Merge branch 'master' into cmake

This commit is contained in:
xawotihs
2016-06-19 11:39:56 +02:00
32 changed files with 2202 additions and 2950 deletions
@@ -0,0 +1,278 @@
package net.wagic.utils;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import android.util.Log;
public class DeckImporter
{
public static String importDeck( File f, String mypath, String activePath )
{
String message = "";
String deck = "";
String deckname = "";
if(f.exists() && !f.isDirectory())
{
deckname = f.getName();
int pos = deckname.lastIndexOf(".");
if (pos > 0)
{
deckname = deckname.substring(0, pos);
}
deck += "#NAME:"+deckname+"\n";
try
{
Scanner scanner = new Scanner(new File(mypath));
if (scanner.hasNext())
{
while (scanner.hasNext())
{
String line = scanner.nextLine();
String[] slines = line.split("\\s+");
String arranged = "";
for(int idx = 1; idx < slines.length; idx++)
{
arranged += slines[idx] + " ";
}
if (isNumeric(slines[0]) && arranged != null)
{
if (slines[1] != null && slines[1].startsWith("["))
{
arranged = arranged.substring(5);
slines[1] = slines[1].replaceAll("\\[", "").replaceAll("\\]","");
deck += arranged + " (" + renameSet(slines[1]) + ") * " + slines[0] + "\n";
}
else
{
deck += arranged + "(*) * " + slines[0] + "\n";
}
}
}
File profile = new File(activePath+"/Res/settings/options.txt");
if(profile.exists() && !profile.isDirectory())
{
String profileName = getActiveProfile(profile);
if(profileName != "Missing!")
{
File rootProfiles = new File(activePath+"/Res/profiles/"+profileName);
if(rootProfiles.exists() && rootProfiles.isDirectory())
{
//save deck
int countdeck = 1;
File[] files = rootProfiles.listFiles();
for (int i = 0; i < files.length; i++)
{//check if there is available deck...
if(files[i].getName().startsWith("deck"))
countdeck++;
}
File toSave = new File(rootProfiles+"/deck"+countdeck+".txt");
try
{
FileOutputStream fop = new FileOutputStream(toSave);
// if file doesn't exists, then create it
if (!toSave.exists()) {
toSave.createNewFile();
}
// get the content in bytes
byte[] contentInBytes = deck.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();
message = "Import Deck Success!\n\n"+deck;
}
catch (IOException e)
{
message = e.getMessage();
}
}
else
{
message = "Missing Folder!";
}
}
}
else
{
message = "Invalid Profile!";
}
}
else
{
message = "No errors, and file EMPTY";
}
}
catch(IOException e)
{
message = e.getMessage();
}
}
return message;
}
private static boolean isNumeric(String input)
{
try
{
Integer.parseInt(input);
}
catch(NumberFormatException ex)
{
return false;
}
return true;
}
private static String getActiveProfile(File mypath)
{
String name = "";
try
{
Scanner scanner = new Scanner(new File(mypath.toString()));
if (scanner.hasNext())
{
String line = scanner.nextLine();
name = line.substring(8);
}
else
{
return "Missing!";
}
}
catch(IOException e)
{
return "Missing!";
}
return name;
}
private static String renameSet(String set)
{
if (set == "")
return "*";
if (set == "AL")
return "ALL";
if (set == "AQ")
return "ATQ";
if (set == "AP")
return "APC";
if (set == "AN")
return "ARN";
if (set == "AE")
return "ARC";
if (set == "BR")
return "BRB";
if (set == "BD")
return "BTD";
if (set == "CH")
return "CHR";
if (set == "6E")
return "6ED";
if (set == "CS")
return "CSP";
if (set == "DS")
return "DST";
if (set == "D2")
return "DD2";
if (set == "8E")
return "8ED";
if (set == "EX")
return "EXO";
if (set == "FE")
return "FEM";
if (set == "FD")
return "5DN";
if (set == "5E")
return "5ED";
if (set == "4E")
return "4ED";
if (set == "GP")
return "GPT";
if (set == "HL")
return "HML";
if (set == "IA")
return "ICE";
if (set == "IN")
return "INV";
if (set == "JU")
return "JUD";
if (set == "LG")
return "LEG";
if (set == "LE")
return "LGN";
if (set == "A")
return "LEA";
if (set == "B")
return "LEB";
if (set == "MM")
return "MMQ";
if (set == "MI")
return "MIR";
if (set == "MR")
return "MRD";
if (set == "NE")
return "NEM";
if (set == "9E")
return "9ED";
if (set == "OD")
return "ODY";
if (set == "ON")
return "ONS";
if (set == "PS")
return "PLS";
if (set == "PT")
return "POR";
if (set == "P2")
return "P02";
if (set == "P3")
return "PTK";
if (set == "PR")
return "PPR";
if (set == "PY")
return "PCY";
if (set == "R")
return "RV";
if (set == "SC")
return "SCG";
if (set == "7E")
return "7ED";
if (set == "ST")
return "S99";
if (set == "ST2K")
return "S00";
if (set == "SH")
return "STH";
if (set == "TE")
return "TMP";
if (set == "DK")
return "DRK";
if (set == "TO")
return "TOR";
if (set == "UG")
return "UGL";
if (set == "U")
return "2ED";
if (set == "UD")
return "UDS";
if (set == "UL")
return "ULG";
if (set == "US")
return "USG";
if (set == "VI")
return "VIS";
if (set == "WL")
return "WTH";
else
return set;
}
}
@@ -5,6 +5,10 @@ import java.io.FileNotFoundException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Scanner; import java.util.Scanner;
import java.util.HashSet;
import java.util.Set;
import android.os.Build;
import android.os.Environment; import android.os.Environment;
import android.util.Log; import android.util.Log;
@@ -21,8 +25,10 @@ public class StorageOptions
public static void determineStorageOptions() public static void determineStorageOptions()
{ {
initializeMountPoints(); initializeMountPoints();
readMountsFileTest();
readMountsFile(); readMountsFile();
readVoldFile(); readVoldFile();
removeDuplicates(mMounts);
compareMountsWithVold(); compareMountsWithVold();
testAndCleanMountsList(); testAndCleanMountsList();
setProperties(); setProperties();
@@ -40,6 +46,42 @@ public class StorageOptions
} }
} }
private static void readMountsFileTest()
{
/*
* Test mountpoints storage -kevlahnota
*/
try
{
Scanner scanner = new Scanner(new File("/proc/mounts"));
while (scanner.hasNext())
{
String line = scanner.nextLine();
if (line.startsWith("/"))
{
String[] lineElements = line.split("\\s+");
if ("vfat".equals(lineElements[2]) || "fuse".equals(lineElements[2]) || "sdcardfs".equals(lineElements[2]))
{
File mountPoint = new File(lineElements[1]);
if (!lineElements[1].equals(defaultMountPoint))
if (mountPoint.isDirectory() && mountPoint.canRead())
mMounts.add(lineElements[1]);
}
}
}
} catch (FileNotFoundException fnfex)
{
// if proc/mount doesn't exist we just use
Log.i(StorageOptions.class.getCanonicalName(), fnfex.getMessage() + ": assuming " + defaultMountPoint + " is the only mount point");
mMounts.add(defaultMountPoint);
} catch (Exception e)
{
Log.e(StorageOptions.class.getCanonicalName(), e.getMessage() + ": unknown exception while reading mounts file");
mMounts.add(defaultMountPoint);
}
}
private static void readMountsFile() private static void readMountsFile()
{ {
/* /*
@@ -106,6 +148,23 @@ public class StorageOptions
mMounts.add(defaultMountPoint); mMounts.add(defaultMountPoint);
} }
} }
private static ArrayList<String> removeDuplicates(ArrayList<String> list)
{
ArrayList<String> result = new ArrayList<String>();
HashSet<String> set = new HashSet<String>();
for (String item : list)
{
if (!set.contains(item))
{
result.add(item);
set.add(item);
}
}
return result;
}
private static void compareMountsWithVold() private static void compareMountsWithVold()
{ {
@@ -132,14 +191,54 @@ public class StorageOptions
/* /*
* Now that we have a cleaned list of mount paths Test each one to make sure it's a valid and available path. If it is not, remove it from the list. * Now that we have a cleaned list of mount paths Test each one to make sure it's a valid and available path. If it is not, remove it from the list.
*/ */
int t = 0;
for (int i = 0; i < mMounts.size(); i++) for (int i = 0; i < mMounts.size(); i++)
{ {
t++;
String mount = mMounts.get(i); String mount = mMounts.get(i);
File root = new File(mount); File root = new File(mount);
if (!root.exists() || !root.isDirectory() || !root.canWrite()) if (!root.exists() || !root.isDirectory() || !root.canWrite())
mMounts.remove(i--); mMounts.remove(i--);
} }
if (t == 0 && Build.VERSION.SDK_INT >= 16)
{//if none is found lets force it for Jellybean and above...
if (System.getenv("EXTERNAL_STORAGE") != null)
{
File root = new File(System.getenv("EXTERNAL_STORAGE"));
if (root.exists() && root.isDirectory() && root.canWrite())
{
if(!isRooted())
{
File folder = new File(System.getenv("EXTERNAL_STORAGE")+"/Android/data/net.wagic.app/files");
folder.mkdirs();
mMounts.add(folder.toString());
}
else
{
mMounts.add(System.getenv("EXTERNAL_STORAGE"));
}
}
}
if (System.getenv("SECONDARY_STORAGE") != null)
{
File root = new File(System.getenv("SECONDARY_STORAGE"));
if (root.exists() && root.isDirectory() && root.canWrite())
{
if(!isRooted())
{
File folder = new File(System.getenv("SECONDARY_STORAGE")+"/Android/data/net.wagic.app/files");
folder.mkdirs();
mMounts.add(folder.toString());
}
else
{
mMounts.add(System.getenv("SECONDARY_STORAGE"));
}
}
}
}
} }
private static void setProperties() private static void setProperties()
@@ -153,10 +252,12 @@ public class StorageOptions
int i = 1; int i = 1;
for (String path : mMounts) for (String path : mMounts)
{ // TODO: /mnt/sdcard is assumed to always mean internal storage. Use this comparison until there is a better way to do this { // TODO: /mnt/sdcard is assumed to always mean internal storage. Use this comparison until there is a better way to do this
if ("/mnt/sdcard".equalsIgnoreCase(path)) if ("/mnt/sdcard".equalsIgnoreCase(path) || "/storage/sdcard0".equalsIgnoreCase(path))
mLabels.add("Built-in Storage"); mLabels.add("Internal SD " + "[" + path + "]");
else if (path.contains("emulated"))
mLabels.add("Emulated SD " + " [" + path + "]");
else else
mLabels.add("External SD Card " + i++); mLabels.add("External SD " + " [" + path + "]");
} }
labels = new String[mLabels.size()]; labels = new String[mLabels.size()];
@@ -171,4 +272,90 @@ public class StorageOptions
// use and to prepare it for the next time it's needed. // use and to prepare it for the next time it's needed.
mMounts.clear(); mMounts.clear();
} }
}
private static boolean isExternalStorageReadOnly() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
return true;
}
return false;
}
private static boolean isExternalStorageAvailable() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
return true;
}
return false;
}
/**
* Checks if the device is rooted.
*
* @return <code>true</code> if the device is rooted, <code>false</code> otherwise.
*/
public static boolean isRooted() {
// get from build info
String buildTags = android.os.Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys")) {
return true;
}
// check if /system/app/Superuser.apk is present
try {
File file = new File("/system/app/Superuser.apk");
if (file.exists()) {
return true;
}
}
catch (Exception e1) {
// ignore
}
try {
File file = new File("/system/app/Superuser/Superuser.apk");
if (file.exists()) {
return true;
}
}
catch (Exception e1) {
// ignore
}
//SuperSU
try {
File file = new File("/system/app/SuperSU.apk");
if (file.exists()) {
return true;
}
}
catch (Exception e1) {
// ignore
}
try {
File file = new File("/system/app/SuperSU/SuperSU.apk");
if (file.exists()) {
return true;
}
}
catch (Exception e1) {
// ignore
}
// try executing commands
return canExecuteCommand("/system/xbin/which su")
|| canExecuteCommand("/system/bin/which su") || canExecuteCommand("which su");
}
// executes a command on the system
private static boolean canExecuteCommand(String command) {
boolean executedSuccesfully;
try {
Runtime.getRuntime().exec(command);
executedSuccesfully = true;
}
catch (Exception e) {
executedSuccesfully = false;
}
return executedSuccesfully;
}
}
@@ -1,12 +1,20 @@
package org.libsdl.app; package org.libsdl.app;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Scanner;
import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLConfig;
@@ -16,6 +24,7 @@ import javax.microedition.khronos.egl.EGLSurface;
import net.wagic.app.R; import net.wagic.app.R;
import net.wagic.utils.StorageOptions; import net.wagic.utils.StorageOptions;
import net.wagic.utils.DeckImporter;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
@@ -59,7 +68,10 @@ import android.widget.FrameLayout.LayoutParams;
*/ */
public class SDLActivity extends Activity implements OnKeyListener public class SDLActivity extends Activity implements OnKeyListener
{ {
//import deck globals
public ArrayList<String> myresult = new ArrayList<String>();
public String myclickedItem = "";
// TAG used for debugging in DDMS // TAG used for debugging in DDMS
public static String TAG = Activity.class.getCanonicalName(); public static String TAG = Activity.class.getCanonicalName();
@@ -200,7 +212,60 @@ public class SDLActivity extends Activity implements OnKeyListener
setStorage.create().show(); setStorage.create().show();
} }
private void importDeckOptions()
{
AlertDialog.Builder importDeck = new AlertDialog.Builder(this);
importDeck.setTitle("Choose Deck to Import:");
File root = new File(System.getenv("EXTERNAL_STORAGE")+"/Download");
File[] files = root.listFiles();
for( File f : files)
{
if( !myresult.contains(f.toString()) && (f.toString().contains(".txt")||f.toString().contains(".dec")))
myresult.add(f.toString());
}
//get first item?
if(!myresult.isEmpty())
myclickedItem = myresult.get(0).toString();
importDeck.setSingleChoiceItems(myresult.toArray(new String[myresult.size()]), 0, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
myclickedItem = myresult.get(item).toString();
}
});
importDeck.setPositiveButton("Import Deck", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
processSelectedDeck( myclickedItem );
if (mSurface == null)
mSingleton.initializeGame();
}
});
importDeck.create().show();
}
private void processSelectedDeck(String mypath)
{
AlertDialog.Builder infoDialog = new AlertDialog.Builder(this);
infoDialog.setTitle("Imported Deck:");
String activePath = sdcardPath;
if(activePath == ""){
activePath = internalPath;
}
File f = new File(mypath);
//Call the deck importer....
String state = DeckImporter.importDeck(f, mypath, activePath);
infoDialog.setMessage(state);
infoDialog.show();
}
private void checkStorageLocationPreference() private void checkStorageLocationPreference()
{ {
SharedPreferences settings = getSharedPreferences(kWagicSharedPreferencesKey, MODE_PRIVATE); SharedPreferences settings = getSharedPreferences(kWagicSharedPreferencesKey, MODE_PRIVATE);
@@ -334,7 +399,8 @@ public class SDLActivity extends Activity implements OnKeyListener
public boolean onCreateOptionsMenu(Menu menu) public boolean onCreateOptionsMenu(Menu menu)
{ {
SubMenu settingsMenu = menu.addSubMenu(Menu.NONE, 1, 1, "Settings"); SubMenu settingsMenu = menu.addSubMenu(Menu.NONE, 1, 1, "Settings");
menu.add(Menu.NONE, 2, 2, "About"); menu.add(Menu.NONE, 2, 2, "Import");
menu.add(Menu.NONE, 3, 3, "About");
settingsMenu.add(kStorageDataOptionsMenuId, kStorageDataOptionsMenuId, Menu.NONE, "Storage Data Options"); settingsMenu.add(kStorageDataOptionsMenuId, kStorageDataOptionsMenuId, Menu.NONE, "Storage Data Options");
// buildStorageOptionsMenu(settingsMenu); // buildStorageOptionsMenu(settingsMenu);
@@ -350,6 +416,9 @@ public class SDLActivity extends Activity implements OnKeyListener
{ {
displayStorageOptions(); displayStorageOptions();
} else if (itemId == 2) } else if (itemId == 2)
{
importDeckOptions();
} else if (itemId == 3)
{ {
// display some info about the app // display some info about the app
AlertDialog.Builder infoDialog = new AlertDialog.Builder(this); AlertDialog.Builder infoDialog = new AlertDialog.Builder(this);
@@ -16,7 +16,9 @@ auto=morphrule
auto=payzerorule auto=payzerorule
auto=overloadrule auto=overloadrule
auto=attackrule auto=attackrule
auto=attackcostrule
auto=blockrule auto=blockrule
auto=blockcostrule
auto=combattriggerrule auto=combattriggerrule
auto=legendrule auto=legendrule
auto=planeswalkerrule auto=planeswalkerrule
+2
View File
@@ -15,7 +15,9 @@ auto=morphrule
auto=payzerorule auto=payzerorule
auto=overloadrule auto=overloadrule
auto=attackrule auto=attackrule
auto=attackcostrule
auto=blockrule auto=blockrule
auto=blockcostrule
auto=combattriggerrule auto=combattriggerrule
auto=legendrule auto=legendrule
auto=planeswalkerrule auto=planeswalkerrule
+2
View File
@@ -19,7 +19,9 @@ auto=morphrule
auto=payzerorule auto=payzerorule
auto=overloadrule auto=overloadrule
auto=attackrule auto=attackrule
auto=attackcostrule
auto=blockrule auto=blockrule
auto=blockcostrule
auto=combattriggerrule auto=combattriggerrule
auto=legendrule auto=legendrule
auto=planeswalkerrule auto=planeswalkerrule
@@ -1,16 +1,5 @@
grade=borderline grade=borderline
[card] [card]
name=Arrogant Wurm
abilities=trample,madness
autoexile=restriction{discarded} pay({2}{G}) name(pay 2G to cast) activate name(pay 2G to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
text=Trample -- Madness {2}{G} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={3}{G}{G}
type=Creature
subtype=Wurm
power=4
toughness=4
[/card]
[card]
name=Autumn Willow name=Autumn Willow
abilities=opponentshroud,shroud abilities=opponentshroud,shroud
auto={G}:-shroud auto={G}:-shroud
@@ -35,40 +24,6 @@ power=2
toughness=2 toughness=2
[/card] [/card]
[card] [card]
name=Basking Rootwalla
abilities=madness
autoexile=restriction{discarded} pay({0}) name(pay 0 to cast) activate name(pay 0 to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto={1}{G}:2/2 limit:1
text={1}{G}: Basking Rootwalla gets +2/+2 until end of turn. Activate this ability only once each turn. -- Madness {0} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={G}
type=Creature
subtype=Lizard
power=1
toughness=1
[/card]
[card]
name=Big Game Hunter
abilities=madness
autoexile=restriction{discarded} pay({B}) name(pay B to cast) activate name(pay B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto=bury target(creature[power>=4])
text=When Big Game Hunter enters the battlefield, destroy target creature with power 4 or greater. It can't be regenerated. -- Madness {B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={1}{B}{B}
type=Creature
subtype=Human Rebel Assassin
power=1
toughness=1
[/card]
[card]
name=Call to the Netherworld
abilities=madness
autoexile=restriction{discarded} pay({0}) name(pay 0 to cast) activate name(pay 0 to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature[black]|myGraveyard
auto=moveTo(myHand)
text=Return target black creature card from your graveyard to your hand. -- Madness {0} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={B}
type=Sorcery
[/card]
[card]
name=Cemetery Puca name=Cemetery Puca
text=Whenever a creature is put into a graveyard from the battlefield, you may pay {1}. If you do, Cemetery Puca becomes a copy of that creature and gains this ability. text=Whenever a creature is put into a graveyard from the battlefield, you may pay {1}. If you do, Cemetery Puca becomes a copy of that creature and gains this ability.
auto=@movedto(creature|graveyard) from(battlefield):all(trigger[from]) pay[[{1}]] copy auto=@movedto(creature|graveyard) from(battlefield):all(trigger[from]) pay[[{1}]] copy
@@ -109,16 +64,6 @@ power=2
toughness=2 toughness=2
[/card] [/card]
[card] [card]
name=Dark Withering
abilities=madness
autoexile=restriction{discarded} pay({B}) name(pay B to cast) activate name(pay B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature[-black]
auto=destroy
text=Destroy target nonblack creature. -- Madness {B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={4}{B}{B}
type=Instant
[/card]
[card]
name=Dimir Doppelganger name=Dimir Doppelganger
auto={1}{U}{B}:target(creature|graveyard) moveto(exile) and!(copy)! auto={1}{U}{B}:target(creature|graveyard) moveto(exile) and!(copy)!
text={1}{U}{B}: Exile target creature card from a graveyard. Dimir Doppelganger becomes a copy of that card and gains this ability. text={1}{U}{B}: Exile target creature card from a graveyard. Dimir Doppelganger becomes a copy of that card and gains this ability.
@@ -164,26 +109,6 @@ auto={3}:counter(1/1)
#Not all player can use ability #Not all player can use ability
[/card] [/card]
[card] [card]
name=Fiery Temper
abilities=madness
autoexile=restriction{discarded} pay({R}) name(pay R to cast) activate name(pay R to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature,player
auto=damage:3
text=Fiery Temper deals 3 damage to target creature or player. -- Madness {R} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={1}{R}{R}
type=Instant
[/card]
[card]
name=Frantic Purification
abilities=madness
autoexile=restriction{discarded} pay({W}) name(pay W to cast) activate name(pay W to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=enchantment
auto=destroy
text=Destroy target enchantment. -- Madness {W} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={2}{W}
type=Instant
[/card]
[card]
name=Ghastly Remains name=Ghastly Remains
auto=foreach(zombie|myhand) counter(1/1,1) auto=foreach(zombie|myhand) counter(1/1,1)
autograveyard={B}{B}{B}:moveTo(myhand) myUpkeepOnly autograveyard={B}{B}{B}:moveTo(myhand) myUpkeepOnly
@@ -205,18 +130,6 @@ power=4
toughness=4 toughness=4
[/card] [/card]
[card] [card]
name=Gorgon Recluse
abilities=madness
autoexile=restriction{discarded} pay({B}{B}) name(pay BB to cast) activate name(pay BB to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto=@combat(blocked,blocking) source(this) from(creature):all(trigger[from]) phaseaction[combatends once] destroy
text=Whenever Gorgon Recluse blocks or becomes blocked by a nonblack creature, destroy that creature at end of combat. -- Madness {B}{B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={3}{B}{B}
type=Creature
subtype=Gorgon
power=2
toughness=4
[/card]
[card]
name=Govern the Guildless name=Govern the Guildless
target=creature[-multicolor] target=creature[-multicolor]
auto=moveto(mybattlefield) auto=moveto(mybattlefield)
@@ -226,17 +139,6 @@ mana={5}{U}
type=Sorcery type=Sorcery
[/card] [/card]
[card] [card]
name=Ichor Slick
abilities=madness
autoexile=restriction{discarded} pay({3}{B}) name(pay 3B to cast) activate name(pay 3B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature
auto=-3/-3
autohand=__CYCLING__({2})
text=Target creature gets -3/-3 until end of turn. -- Cycling {2} ({2}, Discard this card: Draw a card.) -- Madness {3}{B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={2}{B}
type=Sorcery
[/card]
[card]
name=Ivy Seer name=Ivy Seer
auto={2}{G}{T}:foreach(*[green]|myhand) 1/1 target(creature) auto={2}{G}{T}:foreach(*[green]|myhand) 1/1 target(creature)
text={2}{G}, {T}: Reveal any number of green cards in your hand. Target creature gets +X/+X until end of turn, where X is the number of cards revealed this way. text={2}{G}, {T}: Reveal any number of green cards in your hand. Target creature gets +X/+X until end of turn, where X is the number of cards revealed this way.
@@ -308,15 +210,6 @@ type=Sorcery
text=Put a 1/1 white Kor Soldier creature token onto the battlefield for each creature you control. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) text=Put a 1/1 white Kor Soldier creature token onto the battlefield for each creature you control. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)
[/card] [/card]
[card] [card]
name=Obsessive Search
abilities=madness
autoexile=restriction{discarded} pay({U}) name(pay U to cast) activate name(pay U to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto=draw:1 controller
text=Draw a card. -- Madness {U} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={U}
type=Instant
[/card]
[card]
name=Ogre Marauder name=Ogre Marauder
text=Whenever Ogre Marauder attacks, it gains "Ogre Marauder can't be blocked" until end of turn unless defending player sacrifices a creature. text=Whenever Ogre Marauder attacks, it gains "Ogre Marauder can't be blocked" until end of turn unless defending player sacrifices a creature.
auto=@combat(attacking) source(this):ability$!name(choose one) if type(creature|mybattlefield)~morethan~0 then choice sacrifice notatarget(creature|mybattlefield) _ choice all(mystored) unblockable ueot!$ opponent auto=@combat(attacking) source(this):ability$!name(choose one) if type(creature|mybattlefield)~morethan~0 then choice sacrifice notatarget(creature|mybattlefield) _ choice all(mystored) unblockable ueot!$ opponent
@@ -336,15 +229,6 @@ type=Instant
text=Target creature gets +2/+2 until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) text=Target creature gets +2/+2 until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)
[/card] [/card]
[card] [card]
name=Psychotic Haze
abilities=madness
autoexile=restriction{discarded} pay({1}{B}) name(pay 1B to cast) activate name(pay 1B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto=damage:1 all(creature,player)
text=Psychotic Haze deals 1 damage to each creature and each player. -- Madness {1}{B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={2}{B}{B}
type=Instant
[/card]
[card]
name=Rakdos Augermage name=Rakdos Augermage
abilities=first strike abilities=first strike
auto={T}:name(target opponent) target(opponent) donothing && all(this) transforms((,newability[ability$!name(discard) reject notatarget(*|opponenthand)!$ targetedplayer && ability$!name(discard) reject notatarget(*|opponenthand)!$ controller])) assorcery auto={T}:name(target opponent) target(opponent) donothing && all(this) transforms((,newability[ability$!name(discard) reject notatarget(*|opponenthand)!$ targetedplayer && ability$!name(discard) reject notatarget(*|opponenthand)!$ controller])) assorcery
@@ -364,17 +248,6 @@ mana={X}{X}{U}
type=Sorcery type=Sorcery
[/card] [/card]
[card] [card]
name=Reckless Wurm
abilities=trample,madness
autoexile=restriction{discarded} pay({2}{R}) name(pay 2R to cast) activate name(pay 2R to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
text=Trample -- Madness {2}{R} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={3}{R}{R}
type=Creature
subtype=Wurm
power=4
toughness=4
[/card]
[card]
name=Recurring Insight name=Recurring Insight
target=opponent target=opponent
auto=draw:type:*:targetedpersonshand controller auto=draw:type:*:targetedpersonshand controller
@@ -451,30 +324,6 @@ type=Instant
text=Staggershock deals 2 damage to target creature or player. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) text=Staggershock deals 2 damage to target creature or player. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)
[/card] [/card]
[card] [card]
name=Strength of Isolation
abilities=madness
autoexile=restriction{discarded} pay({W}) name(pay W to cast) activate name(pay W to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature
auto=1/2
auto=protection from black
text=Enchant creature -- Enchanted creature gets +1/+2 and has protection from black. -- Madness {W} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={1}{W}
type=Enchantment
subtype=Aura
[/card]
[card]
name=Strength of Lunacy
abilities=madness
autoexile=restriction{discarded} pay({B}) name(pay B to cast) activate name(pay B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature
auto=2/1
auto=protection from white
text=Enchant creature -- Enchanted creature gets +2/+1 and has protection from white. -- Madness {B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={1}{B}
type=Enchantment
subtype=Aura
[/card]
[card]
name=Surreal Memoir name=Surreal Memoir
auto=moverandom(instant) from(mygraveyard) to(myhand) auto=moverandom(instant) from(mygraveyard) to(myhand)
auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)]))
+330 -25
View File
@@ -3075,6 +3075,18 @@ power=4
toughness=6 toughness=6
[/card] [/card]
[card] [card]
name=Angel of Jubilation
abilities=flying,cantpaylife
auto=lord(other creature[-black]|mybattlefield) 1/1
auto=lord(creature) cantbesacrified
text=Flying -- Other nonblack creatures you control get +1/+1. -- Players can't pay life or sacrifice creatures to cast spells or activate abilities.
mana={1}{W}{W}{W}
type=Creature
subtype=Angel
power=3
toughness=3
[/card]
[card]
name=Angel of Light name=Angel of Light
abilities=flying,vigilance abilities=flying,vigilance
text=Flying, vigilance text=Flying, vigilance
@@ -4278,6 +4290,18 @@ power=5
toughness=5 toughness=5
[/card] [/card]
[card] [card]
name=Archangel of Tithes
abilities=flying
auto=this(untapped) lord(creature|opponentbattlefield) transforms((,newability[attackpwcost:1]))
auto=this(attacking) lord(creature|opponentbattlefield) transforms((,newability[blockcost:1]))
text=Flying -- As long as Archangel of Tithes is untapped, creatures can't attack you or a planeswalker you control unless their controller pays {1} for each of those creatures. -- As long as Archangel of Tithes is attacking, creatures can't block unless their controller pays {1} for each of those creatures.
mana={1}{W}{W}{W}
type=Creature
subtype=Angel
power=3
toughness=5
[/card]
[card]
name=Archangel of Thune name=Archangel of Thune
abilities=flying,lifelink abilities=flying,lifelink
auto=@lifeof(player):all(creature|mybattlefield) counter(1/1,1) auto=@lifeof(player):all(creature|mybattlefield) counter(1/1,1)
@@ -4289,18 +4313,6 @@ power=3
toughness=4 toughness=4
[/card] [/card]
[card] [card]
name=Archangel of Tithes
abilities=flying
auto=this(untapped) lord(creature|opponentbattlefield) transforms((,newability[@each mycombatbegins:pay[[{1}]] name(pay 1 mana) donothing?cantattack all(this)]))
auto=@combat(attacking) source(this):all(creature|opponentbattlefield) transforms((,newability[pay[[{1}]] name(pay 1 mana) donothing?cantblock all(this)]))
text=Flying -- As long as Archangel of Tithes is untapped, creatures can't attack you or a planeswalker you control unless their controller pays {1} for each of those creatures. -- As long as Archangel of Tithes is attacking, creatures can't block unless their controller pays {1} for each of those creatures.
mana={1}{W}{W}{W}
type=Creature
subtype=Angel
power=3
toughness=5
[/card]
[card]
name=Archangel's Light name=Archangel's Light
auto=life:twicetype:*:mygraveyard auto=life:twicetype:*:mygraveyard
auto=moveto(myLibrary) all(*|myGraveyard) && shuffle auto=moveto(myLibrary) all(*|myGraveyard) && shuffle
@@ -5122,6 +5134,17 @@ power=4
toughness=3 toughness=3
[/card] [/card]
[card] [card]
name=Arrogant Wurm
abilities=trample,madness
autoexile=restriction{discarded} pay({2}{G}) name(pay 2G to cast) activate name(pay 2G to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
text=Trample -- Madness {2}{G} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={3}{G}{G}
type=Creature
subtype=Wurm
power=4
toughness=4
[/card]
[card]
name=Arrows of Justice name=Arrows of Justice
target=creature[attacking;blocking] target=creature[attacking;blocking]
auto=damage:4 auto=damage:4
@@ -5541,6 +5564,15 @@ mana={4}{B}{B}
type=Sorcery type=Sorcery
[/card] [/card]
[card] [card]
name=Assault Formation
auto=lord(creature|mybattlefield) combattoughness
auto={G}:target(creature[defender]) canattack
auto={2}{G}:lord(creature|myBattlefield) 0/1 ueot
text=Each creature you control assigns combat damage equal to its toughness rather than its power. -- {G}: Target creature with defender can attack this turn as though it didn't have defender. -- {2}{G}: Creatures you control get +0/+1 until end of turn.
mana={1}{G}
type=Enchantment
[/card]
[card]
name=Assault Griffin name=Assault Griffin
abilities=flying abilities=flying
text=Flying text=Flying
@@ -7900,6 +7932,18 @@ type=Artifact
subtype=Equipment subtype=Equipment
[/card] [/card]
[card] [card]
name=Basking Rootwalla
abilities=madness
autoexile=restriction{discarded} pay({0}) name(pay 0 to cast) activate name(pay 0 to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto={1}{G}:2/2 limit:1
text={1}{G}: Basking Rootwalla gets +2/+2 until end of turn. Activate this ability only once each turn. -- Madness {0} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={G}
type=Creature
subtype=Lizard
power=1
toughness=1
[/card]
[card]
name=Bassara Tower Archer name=Bassara Tower Archer
abilities=opponentshroud,reach abilities=opponentshroud,reach
text=Hexproof, reach text=Hexproof, reach
@@ -9002,6 +9046,18 @@ mana={3}{G}
type=Sorcery type=Sorcery
[/card] [/card]
[card] [card]
name=Big Game Hunter
abilities=madness
autoexile=restriction{discarded} pay({B}) name(pay B to cast) activate name(pay B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto=bury target(creature[power>=4])
text=When Big Game Hunter enters the battlefield, destroy target creature with power 4 or greater. It can't be regenerated. -- Madness {B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={1}{B}{B}
type=Creature
subtype=Human Rebel Assassin
power=1
toughness=1
[/card]
[card]
name=Bile Blight name=Bile Blight
target=creature target=creature
auto=transforms((,newability[all(*[share!name!]) -3/-3])) ueot auto=transforms((,newability[all(*[share!name!]) -3/-3])) ueot
@@ -14037,6 +14093,16 @@ subtype=Human
power=* power=*
toughness=* toughness=*
[/card] [/card]
[card]
name=Call to the Netherworld
abilities=madness
autoexile=restriction{discarded} pay({0}) name(pay 0 to cast) activate name(pay 0 to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature[black]|myGraveyard
auto=moveTo(myHand)
text=Return target black creature card from your graveyard to your hand. -- Madness {0} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={B}
type=Sorcery
[/card]
###The 2 cards below should stay together (Flip Card)### ###The 2 cards below should stay together (Flip Card)###
[card] [card]
name=Callow Jushi name=Callow Jushi
@@ -16746,6 +16812,18 @@ mana={1}
type=Artifact type=Artifact
[/card] [/card]
[card] [card]
name=Chrome Mox
auto=may imprint notatarget(*[-land;-artifact]|myhand)
auto=this(variable{evictg}>0) {t}:add{g}
auto=this(variable{evictu}>0) {t}:add{u}
auto=this(variable{evictr}>0) {t}:add{r}
auto=this(variable{evictb}>0) {t}:add{b}
auto=this(variable{evictw}>0) {t}:add{w}
text=Imprint - When Chrome Mox enters the battlefield, you may exile a nonartifact, nonland card from your hand. -- {T}: Add one mana of any of the exiled card's colors to your mana pool.
mana={0}
type=Artifact
[/card]
[card]
name=Chrome Steed name=Chrome Steed
auto=aslongas(artifact|mybattlefield) 2/2 >2 auto=aslongas(artifact|mybattlefield) 2/2 >2
text=Metalcraft - Chrome Steed gets +2/+2 as long as you control three or more artifacts. text=Metalcraft - Chrome Steed gets +2/+2 as long as you control three or more artifacts.
@@ -17025,6 +17103,16 @@ mana={3}{W}
type=Enchantment type=Enchantment
[/card] [/card]
[card] [card]
name=Circular Logic
abilities=madness
target=*|stack
auto=if cantargetcard(*|opponentstack) then transforms((,newability[pay[[{value:type:*:opponentgraveyard}]] name(pay {value} mana) donothing?fizzle])) forever else transforms((,newability[pay[[{value:type:*:mygraveyard}]] name(pay {value} mana) donothing?fizzle])) forever
autoexile=restriction{discarded} pay({U}) name(pay U to cast) activate name(pay U to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
text=Counter target spell unless its controller pays {1} for each card in your graveyard. -- Madness {U} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={2}{U}
type=Instant
[/card]
[card]
name=Citadel Castellan name=Citadel Castellan
abilities=vigilance abilities=vigilance
auto=this(cantargetcard(*[-renown]) transforms((,newability[@combatdamaged(player) from(this):counter(1/1.2) && becomes(renown) forever])) auto=this(cantargetcard(*[-renown]) transforms((,newability[@combatdamaged(player) from(this):counter(1/1.2) && becomes(renown) forever]))
@@ -18283,6 +18371,17 @@ mana={3}{G}{G}{W}
type=Enchantment type=Enchantment
[/card] [/card]
[card] [card]
name=Collective Restraint
auto=aslongas(forest|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
auto=aslongas(island|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
auto=aslongas(mountain|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
auto=aslongas(swamp|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
auto=aslongas(plains|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
text=Domain — Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types among lands you control.
mana={3}{U}
type=Enchantment
[/card]
[card]
name=Collective Unconscious name=Collective Unconscious
auto=foreach(creature|myBattlefield)draw:1 auto=foreach(creature|myBattlefield)draw:1
text=Draw a card for each creature you control. text=Draw a card for each creature you control.
@@ -21908,6 +22007,16 @@ mana={2}{R}
type=Instant type=Instant
[/card] [/card]
[card] [card]
name=Dark Withering
abilities=madness
autoexile=restriction{discarded} pay({B}) name(pay B to cast) activate name(pay B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature[-black]
auto=destroy
text=Destroy target nonblack creature. -- Madness {B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={4}{B}{B}
type=Instant
[/card]
[card]
name=Darkest Hour name=Darkest Hour
auto=lord(creature) transforms((,black)) auto=lord(creature) transforms((,black))
text=All creatures are black. text=All creatures are black.
@@ -25949,6 +26058,16 @@ power=0
toughness=4 toughness=4
[/card] [/card]
[card] [card]
name=Doran, the Siege Tower
auto=lord(creature) combattoughness
text=Each creature assigns combat damage equal to its toughness rather than its power.
mana={W}{B}{G}
type=Legendary Creature
subtype=Treefolk Shaman
power=0
toughness=5
[/card]
[card]
name=Dormant Sliver name=Dormant Sliver
auto=lord(sliver) defender auto=lord(sliver) defender
auto=@movedTo(sliver|myBattlefield):draw:1 controller auto=@movedTo(sliver|myBattlefield):draw:1 controller
@@ -29222,7 +29341,7 @@ type=Instant
name=Elephant Grass name=Elephant Grass
auto=cumulativeupcost[{1}] sacrifice auto=cumulativeupcost[{1}] sacrifice
auto=lord(creature[black]|opponentbattlefield) cantattack auto=lord(creature[black]|opponentbattlefield) cantattack
auto=lord(creature[-black]|opponentbattlefield) transforms((,newability[@each mycombatbegins:pay[[{2}]] name(pay 2 mana) donothing?cantattack all(this)])) auto=lord(creature|opponentbattlefield) transforms((,newability[attackcost:2]))
text=Cumulative upkeep {1} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- Black creatures can't attack you. -- Nonblack creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you. text=Cumulative upkeep {1} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- Black creatures can't attack you. -- Nonblack creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
mana={G} mana={G}
type=Enchantment type=Enchantment
@@ -34020,6 +34139,16 @@ type=Enchantment
subtype=Aura subtype=Aura
[/card] [/card]
[card] [card]
name=Fiery Temper
abilities=madness
autoexile=restriction{discarded} pay({R}) name(pay R to cast) activate name(pay R to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature,player
auto=damage:3
text=Fiery Temper deals 3 damage to target creature or player. -- Madness {R} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={1}{R}{R}
type=Instant
[/card]
[card]
name=Fight to the Death name=Fight to the Death
auto=destroy all(creature[blocking;blocked]) auto=destroy all(creature[blocking;blocked])
text=Destroy all blocking creatures and all blocked creatures. text=Destroy all blocking creatures and all blocked creatures.
@@ -36577,6 +36706,16 @@ mana={2}{GW}{GW}{GW}
type=Instant type=Instant
[/card] [/card]
[card] [card]
name=Frantic Purification
abilities=madness
autoexile=restriction{discarded} pay({W}) name(pay W to cast) activate name(pay W to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=enchantment
auto=destroy
text=Destroy target enchantment. -- Madness {W} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={2}{W}
type=Instant
[/card]
[card]
name=Frantic Salvage name=Frantic Salvage
target=<anyamount>artifact|mygraveyard target=<anyamount>artifact|mygraveyard
auto=moveTo(mylibrary) auto=moveTo(mylibrary)
@@ -37277,7 +37416,7 @@ subtype=Aura
[card] [card]
name=Fury Charm name=Fury Charm
auto=may destroy target(artifact) auto=may destroy target(artifact)
auto=may 1/1 && trample target(creature) auto=may name(1/1 & trample) target(creature) transforms((,newability[1/1],newability[trample])) ueot
auto=may counter(0/0,-2,Time) target(*) auto=may counter(0/0,-2,Time) target(*)
text=Choose one - Destroy target artifact; or target creature gets +1/+1 and gains trample until end of turn; or remove two time counters from target permanent or suspended card. text=Choose one - Destroy target artifact; or target creature gets +1/+1 and gains trample until end of turn; or remove two time counters from target permanent or suspended card.
mana={1}{R} mana={1}{R}
@@ -38754,7 +38893,7 @@ subtype=Aura
[/card] [/card]
[card] [card]
name=Ghostly Prison name=Ghostly Prison
auto=lord(creature|opponentbattlefield) transforms((,newability[@each mycombatbegins:pay[[{2}]] name(pay 2 mana) donothing?cantattack all(this)])) auto=lord(creature|opponentbattlefield) transforms((,newability[attackcost:2]))
text=Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you. text=Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
mana={2}{W} mana={2}{W}
type=Enchantment type=Enchantment
@@ -41111,6 +41250,17 @@ mana={1}{B}
type=Instant type=Instant
[/card] [/card]
[card] [card]
name=Goham Djinn
auto={1}{B}:regenerate
auto=this(variable{commonblack}>0) -2/-2
text={1}{B}: Regenerate Goham Djinn. -- Goham Djinn gets -2/-2 as long as black is the most common color among all permanents or is tied for most common.
mana={5}{B}
type=Creature
subtype=Djinn
power=5
toughness=5
[/card]
[card]
name=Gold Myr name=Gold Myr
auto={T}:Add{W} auto={T}:Add{W}
text={T}: Add {W} to your mana pool. text={T}: Add {W} to your mana pool.
@@ -41496,6 +41646,18 @@ type=Artifact
subtype=Equipment subtype=Equipment
[/card] [/card]
[card] [card]
name=Gorgon Recluse
abilities=madness
autoexile=restriction{discarded} pay({B}{B}) name(pay BB to cast) activate name(pay BB to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto=@combat(blocked,blocking) source(this) from(creature):all(trigger[from]) phaseaction[combatends once] destroy
text=Whenever Gorgon Recluse blocks or becomes blocked by a nonblack creature, destroy that creature at end of combat. -- Madness {B}{B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={3}{B}{B}
type=Creature
subtype=Gorgon
power=2
toughness=4
[/card]
[card]
name=Gorilla Chieftain name=Gorilla Chieftain
auto={1}{G}:regenerate auto={1}{G}:regenerate
text={1}{G}: Regenerate Gorilla Chieftain. text={1}{G}: Regenerate Gorilla Chieftain.
@@ -43785,6 +43947,17 @@ mana={6}
type=Artifact type=Artifact
[/card] [/card]
[card] [card]
name=Halam Djinn
abilities=haste
auto=this(variable{commonred}>0) -2/-2
text=Haste -- Halam Djinn gets -2/-2 as long as red is the most common color among all permanents or is tied for most common.
mana={5}{R}
type=Creature
subtype=Djinn
power=6
toughness=5
[/card]
[card]
name=Halberdier name=Halberdier
abilities=first strike abilities=first strike
text=First strike text=First strike
@@ -48054,6 +48227,17 @@ power=2
toughness=1 toughness=1
[/card] [/card]
[card] [card]
name=Ichor Slick
abilities=madness
autoexile=restriction{discarded} pay({3}{B}) name(pay 3B to cast) activate name(pay 3B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature
auto=-3/-3
autohand=__CYCLING__({2})
text=Target creature gets -3/-3 until end of turn. -- Cycling {2} ({2}, Discard this card: Draw a card.) -- Madness {3}{B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={2}{B}
type=Sorcery
[/card]
[card]
name=Ichor Wellspring name=Ichor Wellspring
auto=draw:1 auto=draw:1
auto=@movedTo(this|graveyard) from(battlefield):draw:1 controller auto=@movedTo(this|graveyard) from(battlefield):draw:1 controller
@@ -54354,6 +54538,15 @@ power=3
toughness=3 toughness=3
[/card] [/card]
[card] [card]
name=Koskun Falls
auto=upcost[{T(creature|mybattlefield)}] sacrifice
auto=lord(creature|opponentbattlefield) transforms((,newability[attackcost:2]))
auto=@movedTo(enchantment[world]|battlefield):sacrifice all(this)
text=At the beginning of your upkeep, sacrifice Koskun Falls unless you tap an untapped creature you control. -- Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
mana={2}{B}{B}
type=World Enchantment
[/card]
[card]
name=Koskun Keep name=Koskun Keep
auto={T}:Add{1} auto={T}:Add{1}
auto={1}{T}:Add{R} auto={1}{T}:Add{R}
@@ -65596,6 +65789,17 @@ power=2
toughness=2 toughness=2
[/card] [/card]
[card] [card]
name=Mycosynth Golem
abilities=affinityartifacts
auto=lord(creature[artifact]|myhand,mylibrary,mygraveyard,myexile) affinityartifacts forcedalive
text=Affinity for artifacts (This spell costs {1} less to cast for each artifact you control.) -- Artifact creature spells you cast have affinity for artifacts. (They cost {1} less to cast for each artifact you control.)
mana={11}
type=Artifact Creature
subtype=Golem
power=4
toughness=5
[/card]
[card]
name=Mycosynth Wellspring name=Mycosynth Wellspring
auto=may moveTo(myhand) notatarget(land[basic]|mylibrary) auto=may moveTo(myhand) notatarget(land[basic]|mylibrary)
auto=@movedTo(this|graveyard) from(battlefield):may moveTo(myhand) notatarget(land[basic]|mylibrary) auto=@movedTo(this|graveyard) from(battlefield):may moveTo(myhand) notatarget(land[basic]|mylibrary)
@@ -68955,6 +69159,15 @@ text={T}: Add {U} to your mana pool. -- {1}: Return Oboro, Palace in the Clouds
type=Legendary Land type=Legendary Land
[/card] [/card]
[card] [card]
name=Obsessive Search
abilities=madness
autoexile=restriction{discarded} pay({U}) name(pay U to cast) activate name(pay U to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto=draw:1 controller
text=Draw a card. -- Madness {U} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={U}
type=Instant
[/card]
[card]
name=Obsianus Golem name=Obsianus Golem
mana={6} mana={6}
type=Artifact Creature type=Artifact Creature
@@ -75460,7 +75673,7 @@ toughness=1
[/card] [/card]
[card] [card]
name=Propaganda name=Propaganda
auto=lord(creature|opponentbattlefield) transforms((,newability[@each mycombatbegins:pay[[{2}]] name(pay 2 mana) donothing?cantattack all(this)])) auto=lord(creature|opponentbattlefield) transforms((,newability[attackcost:2]))
text=Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you. text=Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
mana={2}{U} mana={2}{U}
type=Enchantment type=Enchantment
@@ -75746,6 +75959,15 @@ mana={1}{R}
type=Instant type=Instant
[/card] [/card]
[card] [card]
name=Psychotic Haze
abilities=madness
autoexile=restriction{discarded} pay({1}{B}) name(pay 1B to cast) activate name(pay 1B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
auto=damage:1 all(creature,player)
text=Psychotic Haze deals 1 damage to each creature and each player. -- Madness {1}{B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={2}{B}{B}
type=Instant
[/card]
[card]
name=Psychotrope Thallid name=Psychotrope Thallid
text=At the beginning of your upkeep, put a spore counter on Psychotrope Thallid. -- Remove three spore counters from Psychotrope Thallid: Put a 1/1 green Saproling creature token onto the battlefield. -- {1}, Sacrifice a Saproling: Draw a card. text=At the beginning of your upkeep, put a spore counter on Psychotrope Thallid. -- Remove three spore counters from Psychotrope Thallid: Put a 1/1 green Saproling creature token onto the battlefield. -- {1}, Sacrifice a Saproling: Draw a card.
mana={2}{G} mana={2}{G}
@@ -78865,6 +79087,17 @@ toughness=2
[/card] [/card]
###The 2 cards above should stay together (Flip Card)### ###The 2 cards above should stay together (Flip Card)###
[card] [card]
name=Reckless Wurm
abilities=trample,madness
autoexile=restriction{discarded} pay({2}{R}) name(pay 2R to cast) activate name(pay 2R to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
text=Trample -- Madness {2}{R} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={3}{R}{R}
type=Creature
subtype=Wurm
power=4
toughness=4
[/card]
[card]
name=Reclaim name=Reclaim
target=*|mygraveyard target=*|mygraveyard
auto=moveTo(myLibrary) auto=moveTo(myLibrary)
@@ -79099,6 +79332,7 @@ auto=this(variable{plandu}>0) {t}:add{u}
auto=this(variable{plandr}>0) {t}:add{r} auto=this(variable{plandr}>0) {t}:add{r}
auto=this(variable{plandb}>0) {t}:add{b} auto=this(variable{plandb}>0) {t}:add{b}
auto=this(variable{plandw}>0) {t}:add{w} auto=this(variable{plandw}>0) {t}:add{w}
auto=this(variable{plandc}>0) {t}:add{1}
text={T}: Add to your mana pool one mana of any type that a land you control could produce. text={T}: Add to your mana pool one mana of any type that a land you control could produce.
type=Land type=Land
[/card] [/card]
@@ -82405,6 +82639,17 @@ text=Ruins of Trokair enters the battlefield tapped. -- {T}: Add {W} to your man
type=Land type=Land
[/card] [/card]
[card] [card]
name=Ruham Djinn
abilities=first strike
auto=this(variable{commonwhite}>0) -2/-2
text=First strike -- -- Ruham Djinn gets -2/-2 as long as white is the most common color among all permanents or is tied for most common.
mana={5}{W}
type=Creature
subtype=Djinn
power=5
toughness=5
[/card]
[card]
name=Ruhan of the Fomori name=Ruhan of the Fomori
abilities=mustattack abilities=mustattack
text=At the beginning of combat on your turn, choose an opponent at random. Ruhan of the Fomori attacks that player this combat if able. text=At the beginning of combat on your turn, choose an opponent at random. Ruhan of the Fomori attacks that player this combat if able.
@@ -86536,7 +86781,7 @@ type=Artifact
[/card] [/card]
[card] [card]
name=Selesnya Charm name=Selesnya Charm
auto=choice target(creature) 2/2 && trample ueot auto=choice name(2/2 & trample) target(creature) transforms((,newability[2/2],newability[trample])) ueot
auto=choice moveTo(exile) target(creature[power>=5]) auto=choice moveTo(exile) target(creature[power>=5])
auto=choice token(Knight,Creature Knight,2/2,white,vigilance) auto=choice token(Knight,Creature Knight,2/2,white,vigilance)
text=Choose one — Target creature gets +2/+2 and gains trample until end of turn; or exile target creature with power 5 or greater; or put a 2/2 white Knight creature token with vigilance onto the battlefield. text=Choose one — Target creature gets +2/+2 and gains trample until end of turn; or exile target creature with power 5 or greater; or put a 2/2 white Knight creature token with vigilance onto the battlefield.
@@ -97406,6 +97651,30 @@ type=Instant
subtype=Arcane subtype=Arcane
[/card] [/card]
[card] [card]
name=Strength of Isolation
abilities=madness
autoexile=restriction{discarded} pay({W}) name(pay W to cast) activate name(pay W to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature
auto=1/2
auto=protection from black
text=Enchant creature -- Enchanted creature gets +1/+2 and has protection from black. -- Madness {W} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={1}{W}
type=Enchantment
subtype=Aura
[/card]
[card]
name=Strength of Lunacy
abilities=madness
autoexile=restriction{discarded} pay({B}) name(pay B to cast) activate name(pay B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
target=creature
auto=2/1
auto=protection from white
text=Enchant creature -- Enchanted creature gets +2/+1 and has protection from white. -- Madness {B} (If you discard this card, you may cast it for its madness cost instead of putting it into your graveyard.)
mana={1}{B}
type=Enchantment
subtype=Aura
[/card]
[card]
name=Strength of Night name=Strength of Night
kicker={B} kicker={B}
auto=all(creature|myBattlefield) 1/1 ueot auto=all(creature|myBattlefield) 1/1 ueot
@@ -97923,6 +98192,17 @@ mana={3}{B}{R}
type=Enchantment type=Enchantment
[/card] [/card]
[card] [card]
name=Sulam Djinn
abilities=trample
auto=this(variable{commongreen}>0) -2/-2
text=Trample -- Sulam Djinn gets -2/-2 as long as green is the most common color among all permanents or is tied for most common.
mana={5}{G}
type=Creature
subtype=Djinn
power=6
toughness=6
[/card]
[card]
name=Suleiman's Legacy name=Suleiman's Legacy
auto=lord(djinn) sacrifice auto=lord(djinn) sacrifice
auto=lord(efreet) sacrifice auto=lord(efreet) sacrifice
@@ -110151,7 +110431,7 @@ toughness=1
[card] [card]
name=Vitality Charm name=Vitality Charm
auto=choice token(Insect,creature insect, 1/1,green) auto=choice token(Insect,creature insect, 1/1,green)
auto=aslongas(creature|battlefield) choice 1/1 && trample target(creature) auto=aslongas(creature|battlefield) choice name(1/1 & trample) target(creature) transforms((,newability[1/1],newability[trample])) ueot
auto=aslongas(beast|battlefield) choice regenerate target(beast) auto=aslongas(beast|battlefield) choice regenerate target(beast)
text=Choose one - Put a 1/1 green Insect creature token onto the battlefield; or target creature gets +1/+1 and gains trample until end of turn; or regenerate target Beast. text=Choose one - Put a 1/1 green Insect creature token onto the battlefield; or target creature gets +1/+1 and gains trample until end of turn; or regenerate target Beast.
mana={G} mana={G}
@@ -112045,11 +112325,10 @@ power=3
toughness=6 toughness=6
[/card] [/card]
[card] [card]
name=War Dance name=War Cadence
auto=@each my upkeep:may counter(0/0,1,Verse) auto={X}{U}:name(Block X Cost) thisforeach(X) all(creature) transforms((,newability[blockcost:1])) ueot
auto={S}:thisforeach(counter{0/0.1.Verse}) 1/1 target(creature) text={X}{R}: This turn, creatures can't block unless their controller pays {X} for each blocking creature he or she controls.
text=At the beginning of your upkeep, you may put a verse counter on War Dance. -- Sacrifice War Dance: Target creature gets +X/+X until end of turn, where X is the number of verse counters on War Dance. mana={2}{R}
mana={G}
type=Enchantment type=Enchantment
[/card] [/card]
[card] [card]
@@ -112060,6 +112339,14 @@ mana={3}
type=Artifact type=Artifact
[/card] [/card]
[card] [card]
name=War Dance
auto=@each my upkeep:may counter(0/0,1,Verse)
auto={S}:thisforeach(counter{0/0.1.Verse}) 1/1 target(creature)
text=At the beginning of your upkeep, you may put a verse counter on War Dance. -- Sacrifice War Dance: Target creature gets +X/+X until end of turn, where X is the number of verse counters on War Dance.
mana={G}
type=Enchantment
[/card]
[card]
name=War Elemental name=War Elemental
auto=this(opponentdamagecount < 1) aslongas(War Elemental|mybattlefield) sacrifice oneshot auto=this(opponentdamagecount < 1) aslongas(War Elemental|mybattlefield) sacrifice oneshot
auto=@damagefoeof(player):may all(trigger[to]) dynamicability<!myfoe thatmuchcountersoneone tosrc!> auto=@damagefoeof(player):may all(trigger[to]) dynamicability<!myfoe thatmuchcountersoneone tosrc!>
@@ -112136,6 +112423,13 @@ mana={3}{W}
type=Instant type=Instant
[/card] [/card]
[card] [card]
name=War Tax
auto={X}{U}:name(Attack X Cost) thisforeach(X) all(creature) transforms((,newability[attackcost:1])) ueot
text={X}{U}: This turn, creatures can't attack unless their controller pays {X} for each attacking creature he or she controls.
mana={2}{U}
type=Enchantment
[/card]
[card]
name=War-Name Aspirant name=War-Name Aspirant
auto=if raid then counter(1/1,1) auto=if raid then counter(1/1,1)
auto=cantbeblockedby(creature[power<=1]) auto=cantbeblockedby(creature[power<=1])
@@ -114046,7 +114340,7 @@ subtype=Aura
[card] [card]
name=Windborn Muse name=Windborn Muse
abilities=flying abilities=flying
auto=lord(creature|opponentbattlefield) transforms((,newability[@each mycombatbegins:pay[[{2}]] name(pay 2 mana) donothing?cantattack all(this)])) auto=lord(creature|opponentbattlefield) transforms((,newability[attackcost:2]))
text=Flying (This creature can't be blocked except by creatures with flying or reach.) -- Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you. text=Flying (This creature can't be blocked except by creatures with flying or reach.) -- Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
mana={3}{W} mana={3}{W}
type=Creature type=Creature
@@ -115485,7 +115779,7 @@ toughness=5
[card] [card]
name=Wrench Mind name=Wrench Mind
target=player target=player
auto=ability$!choice name(discard 2 cards) target(<2>*|myhand) reject _ choice name(discard artifact) target(artifact|myhand) reject !$ targetedplayer auto=ability$! name(discard 2 cards) choice name(discard 2 cards) target(<2>*|myhand) reject _ if type(artifact|myhand)~morethan~0 then name(discard artifact) choice name(discard artifact) target(artifact|myhand) reject !$ targetedplayer
text=Target player discards two cards unless he or she discards an artifact card. text=Target player discards two cards unless he or she discards an artifact card.
mana={B}{B} mana={B}{B}
type=Sorcery type=Sorcery
@@ -116241,6 +116535,17 @@ power=5
toughness=5 toughness=5
[/card] [/card]
[card] [card]
name=Zanam Djinn
abilities=flying
auto=this(variable{commonblue}>0) -2/-2
text=Flying -- Zanam Djinn gets -2/-2 as long as blue is the most common color among all permanents or is tied for most common.
mana={5}{U}
type=Creature
subtype=Djinn
power=5
toughness=6
[/card]
[card]
name=Zanikev Locust name=Zanikev Locust
autograveyard={2}{B}{B}{E}:name(scavenge) counter(1/1,storedpower) target(creature) asSorcery autograveyard={2}{B}{B}{E}:name(scavenge) counter(1/1,storedpower) target(creature) asSorcery
abilities=flying abilities=flying
File diff suppressed because it is too large Load Diff
+48
View File
@@ -0,0 +1,48 @@
#Testing Doran, The Siege Tower
[INIT]
FIRSTMAIN
[PLAYER1]
life:20
inplay:140201, True Conviction
manapool:{3}{U}
[PLAYER2]
life:30
[DO]
next
#begin
next
#attackers
140201
next
#blockers
next
#damage
next
eot
eot
#untap
next
#upkeep
next
#draw
next
#main1
next
#combat begin
next
#attackers
140201
next
#blockers
next
#damage
next
next
[ASSERT]
COMBATEND
[PLAYER1]
inplay:140201, True Conviction
life:40
[PLAYER2]
life:10
[END]
+37
View File
@@ -0,0 +1,37 @@
#Put in play Fists of Ironwood via Replenish
[INIT]
FIRSTMAIN
[PLAYER1]
life:20
hand:Replenish, 4683, Replenish
graveyard:83672, Mass Hysteria
inplay:Swamp, Forest, Island, Mountain, Plains
manapool:{3}{W}
[PLAYER2]
life:20
[DO]
Replenish
#Fists of Ironwood remains on graveyard since there are no valid targets
Swamp
4683
Forest
Island
Plains
Mountain
Replenish
#Fists of Ironwood attach on Zombie Token created by Sarcomancy, Then produces 2 Saproling Tokens
-4683
next
next
-83672
-4683
eot
[ASSERT]
UNTAP
[PLAYER1]
graveyard:Replenish, Replenish
inplay:Sarcomancy, Mass Hysteria, Swamp, Forest, Island, Mountain, Plains, -4683, -83672, -83672, 83672
life:20
[PLAYER2]
life:17
[END]
@@ -0,0 +1,23 @@
#Put in play Fists of Ironwood via Show and Tell
[INIT]
FIRSTMAIN
[PLAYER1]
life:20
hand:Show and Tell, Fists of Ironwood
manapool:{2}{U}
[PLAYER2]
life:20
[DO]
Show and Tell
choice 0
Fists of Ironwood
eot
[ASSERT]
UNTAP
[PLAYER1]
graveyard:Show and Tell
hand:Fists of Ironwood
life:20
[PLAYER2]
life:20
[END]
+4
View File
@@ -223,6 +223,7 @@ civic_wayfinder.txt
clone.txt clone.txt
clone2.txt clone2.txt
clone3.txt clone3.txt
clone4.txt
cockatrice.txt cockatrice.txt
cockatrice_i228.txt cockatrice_i228.txt
colossus_of_sardia1.txt colossus_of_sardia1.txt
@@ -275,6 +276,7 @@ dingus_staff_i153.txt
Distorting_Wake.txt Distorting_Wake.txt
Distorting_Wake2.txt Distorting_Wake2.txt
divergent_growth.txt divergent_growth.txt
Doran.txt
doomed_necromancer.txt doomed_necromancer.txt
double_strike_i145.txt double_strike_i145.txt
double_strike2_i145.txt double_strike2_i145.txt
@@ -575,6 +577,7 @@ regal_force.txt
reinforcements_1.txt reinforcements_1.txt
Rending_Vines.txt Rending_Vines.txt
Rending_Vines2.txt Rending_Vines2.txt
Replenish.txt
resounding_roar.txt resounding_roar.txt
resurrection.txt resurrection.txt
resuscitate_i210.txt resuscitate_i210.txt
@@ -621,6 +624,7 @@ shimmer_myr_FORCEDALIVE.txt
shivan_hellkite.txt shivan_hellkite.txt
shock.txt shock.txt
shock2.txt shock2.txt
Show_and_Tell.txt
siege_gang_commander.txt siege_gang_commander.txt
simic_initiate.txt simic_initiate.txt
slate_of_ancestry.txt slate_of_ancestry.txt
+52
View File
@@ -0,0 +1,52 @@
#Testing Clone with Thistledown Liege Fix issue #448
#we have p/t layers
[INIT]
FIRSTMAIN
[PLAYER1]
hand:129501
inplay:Thistledown Liege
manapool:{3}{U}
[PLAYER2]
life:20
[DO]
129501
choice 0
Thistledown Liege
next
#begin
next
#attackers
Thistledown Liege
129501
next
#blockers
next
#damage
next
eot
eot
#untap
next
#upkeep
next
#draw
next
#main1
next
#combat begin
next
#attackers
129501
next
#blockers
next
#damage
next
#combat end
[ASSERT]
COMBATEND
[PLAYER1]
inplay:Thistledown Liege, 129501
[PLAYER2]
life:14
[END]
+236 -400
View File
@@ -202,203 +202,43 @@ private:
} }
else if (s == "azorius")//devotion blue white else if (s == "azorius")//devotion blue white
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLUE,Constants::MTG_COLOR_WHITE);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 2);
intValue += zone->countDevotion(dtc, 5);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s == "boros")//devotion red white else if (s == "boros")//devotion red white
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_WHITE,Constants::MTG_COLOR_RED);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 3);
intValue += zone->countDevotion(dtc, 5);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s == "dimir")//devotion blue black else if (s == "dimir")//devotion blue black
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLACK,Constants::MTG_COLOR_BLUE);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 2);
intValue += zone->countDevotion(dtc, 4);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s == "golgari")//devotion to green black else if (s == "golgari")//devotion to green black
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLACK,Constants::MTG_COLOR_GREEN);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 1);
intValue += zone->countDevotion(dtc, 4);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s == "gruul")//devotion to green red else if (s == "gruul")//devotion to green red
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_GREEN,Constants::MTG_COLOR_RED);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 1);
intValue += zone->countDevotion(dtc, 3);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s == "izzet")//devotion to red blue else if (s == "izzet")//devotion to red blue
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLUE,Constants::MTG_COLOR_RED);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 2);
intValue += zone->countDevotion(dtc, 3);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s == "orzhov")//devotion to white black else if (s == "orzhov")//devotion to white black
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLACK,Constants::MTG_COLOR_WHITE);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 4);
intValue += zone->countDevotion(dtc, 5);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s == "rakdos")//devotion to red black else if (s == "rakdos")//devotion to red black
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLACK,Constants::MTG_COLOR_RED);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 3);
intValue += zone->countDevotion(dtc, 4);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s == "selesnya")//devotion to green white else if (s == "selesnya")//devotion to green white
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_GREEN,Constants::MTG_COLOR_WHITE);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 1);
intValue += zone->countDevotion(dtc, 5);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s == "simic")//devotion to green blue else if (s == "simic")//devotion to green blue
{ {
TargetChooserFactory dtf(card->getObserver()); intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLUE,Constants::MTG_COLOR_GREEN);
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
for (int i = 0; i < 2; i++)
{
Player * dp = card->getObserver()->players[i];
MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = dzones[k];
if (dtc->targetsZone(zone, card)&&dp == card->controller())
{
intValue += zone->countDevotion(dtc, 1);
intValue += zone->countDevotion(dtc, 2);
}
}
}
SAFE_DELETE(dtc);
} }
else if (s.find("type:") != string::npos) else if (s.find("type:") != string::npos)
{ {
@@ -565,6 +405,46 @@ private:
intValue +=1; intValue +=1;
} }
} }
else if (s == "evictg")
{
intValue = card->imprintG;
}
else if (s == "evictu")
{
intValue = card->imprintU;
}
else if (s == "evictr")
{
intValue = card->imprintR;
}
else if (s == "evictb")
{
intValue = card->imprintB;
}
else if (s == "evictw")
{
intValue = card->imprintW;
}
else if (s == "commongreen")
{
intValue = mostCommonColor(Constants::MTG_COLOR_GREEN, card);
}
else if (s == "commonblue")
{
intValue = mostCommonColor(Constants::MTG_COLOR_BLUE, card);
}
else if (s == "commonred")
{
intValue = mostCommonColor(Constants::MTG_COLOR_RED, card);
}
else if (s == "commonblack")
{
intValue = mostCommonColor(Constants::MTG_COLOR_BLACK, card);
}
else if (s == "commonwhite")
{
intValue = mostCommonColor(Constants::MTG_COLOR_WHITE, card);
}
else if (s == "targetedcurses") else if (s == "targetedcurses")
{ {
if(card->playerTarget) if(card->playerTarget)
@@ -686,153 +566,65 @@ private:
} }
else if (s == "olandg") else if (s == "olandg")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_GREEN, target, target->controller()->opponent());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++)
{//start
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]);
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if (amp && amp->source->isLand() && amp->source->controller() == target->controller()->opponent() && amp->output->hasColor(1))
intValue = 1;
}//end
} }
else if (s == "olandu") else if (s == "olandu")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_BLUE, target, target->controller()->opponent());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++)
{//start
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]);
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if (amp && amp->source->isLand() && amp->source->controller() == target->controller()->opponent() && amp->output->hasColor(2))
intValue = 1;
}//end
} }
else if (s == "olandr") else if (s == "olandr")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_RED, target, target->controller()->opponent());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++)
{//start
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]);
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if (amp && amp->source->isLand() && amp->source->controller() == target->controller()->opponent() && amp->output->hasColor(3))
intValue = 1;
}//end
} }
else if (s == "olandb") else if (s == "olandb")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_BLACK, target, target->controller()->opponent());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++)
{//start
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]);
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if (amp && amp->source->isLand() && amp->source->controller() == target->controller()->opponent() && amp->output->hasColor(4))
intValue = 1;
}//end
} }
else if (s == "olandw") else if (s == "olandw")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_WHITE, target, target->controller()->opponent());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++) }
{//start else if (s == "olandc")
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]); {
AManaProducer * amp = dynamic_cast<AManaProducer*> (a); intValue = countManaProducedby(Constants::MTG_COLOR_ARTIFACT, target, target->controller()->opponent()) +
if (amp && amp->source->isLand() && amp->source->controller() == target->controller()->opponent() && amp->output->hasColor(5)) countManaProducedby(Constants::MTG_COLOR_WASTE, target, target->controller()->opponent());
intValue = 1;
}//end
} }
else if (s == "plandg") else if (s == "plandg")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_GREEN, target, target->controller());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++)
{//start
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]);
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if (amp && amp->source->isLand() && amp->source->controller() == target->controller() && amp->output->hasColor(1))
intValue = 1;
}//end
} }
else if (s == "plandu") else if (s == "plandu")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_BLUE, target, target->controller());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++)
{//start
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]);
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if (amp && amp->source->isLand() && amp->source->controller() == target->controller() && amp->output->hasColor(2))
intValue = 1;
}//end
} }
else if (s == "plandr") else if (s == "plandr")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_RED, target, target->controller());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++)
{//start
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]);
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if (amp && amp->source->isLand() && amp->source->controller() == target->controller() && amp->output->hasColor(3))
intValue = 1;
}//end
} }
else if (s == "plandb") else if (s == "plandb")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_BLACK, target, target->controller());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++)
{//start
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]);
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if (amp && amp->source->isLand() && amp->source->controller() == target->controller() && amp->output->hasColor(4))
intValue = 1;
}//end
} }
else if (s == "plandw") else if (s == "plandw")
{ {
intValue = 0; intValue = countManaProducedby(Constants::MTG_COLOR_WHITE, target, target->controller());
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++) }
{//start else if (s == "plandc")
MTGAbility * a = ((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i]); {
AManaProducer * amp = dynamic_cast<AManaProducer*> (a); intValue = countManaProducedby(Constants::MTG_COLOR_ARTIFACT, target, target->controller()) +
if (amp && amp->source->isLand() && amp->source->controller() == target->controller() && amp->output->hasColor(5)) countManaProducedby(Constants::MTG_COLOR_WASTE, target, target->controller());
intValue = 1;
}//end
} }
else if (s == "cantargetmycre")// can target my creature else if (s == "cantargetmycre")// can target my creature
{ {
intValue = 0; intValue = countCanTargetby("creature", card, card->controller());
for (int j = card->controller()->game->battlefield->nb_cards - 1; j >= 0; --j)
{
if (card->controller()->game->battlefield->cards[j]->hasType("creature") && !card->controller()->game->battlefield->cards[j]->protectedAgainst(card))
{
intValue += 1;
}
}
} }
else if (s == "cantargetoppocre")// can target opponent creature else if (s == "cantargetoppocre")// can target opponent creature
{ {
intValue = 0; intValue = countCanTargetby("creature", card, card->controller()->opponent());
for (int j = card->controller()->opponent()->game->battlefield->nb_cards - 1; j >= 0; --j)
{
if (card->controller()->opponent()->game->battlefield->cards[j]->hasType("creature") && !card->controller()->opponent()->game->battlefield->cards[j]->protectedAgainst(card))
{
intValue += 1;
}
}
} }
else if (s == "cantargetcre")// can target any creature else if (s == "cantargetcre")// can target any creature
{ {
intValue = 0; intValue = countCanTargetby("creature", card, card->controller()) + countCanTargetby("creature", card, card->controller()->opponent());
for (int j = card->controller()->opponent()->game->battlefield->nb_cards - 1; j >= 0; --j)
{
if (card->controller()->opponent()->game->battlefield->cards[j]->hasType("creature") && !card->controller()->opponent()->game->battlefield->cards[j]->protectedAgainst(card))
{
intValue += 1;
}
}
for (int k = card->controller()->game->battlefield->nb_cards - 1; k >= 0; --k)
{
if (card->controller()->game->battlefield->cards[k]->hasType("creature") && !card->controller()->game->battlefield->cards[k]->protectedAgainst(card))
{
intValue += 1;
}
}
} }
else if (s == "controllerturn")//intvalue = 1 if its your turn this(variable{controllerturn}) else if (s == "controllerturn")//intvalue = 1 if its your turn this(variable{controllerturn})
{ {
@@ -872,107 +664,43 @@ private:
{ {
intValue = 0; intValue = 0;
for (int j = card->controller()->game->inPlay->nb_cards - 1; j >= 0; --j) for (int j = card->controller()->game->inPlay->nb_cards - 1; j >= 0; --j)
{
if (card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_CREATURE) && card->controller()->game->inPlay->cards[j] != card) if (card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_CREATURE) && card->controller()->game->inPlay->cards[j] != card)
{ intValue += card->controller()->game->inPlay->cards[j]->getManaCost()->getConvertedCost();
intValue += card->controller()->game->inPlay->cards[j]->getManaCost()->getConvertedCost();
}
}
} }
else if (s == "pdauntless")//Dauntless Dourbark else if (s == "pdauntless")//Dauntless Dourbark
{ {
intValue = 0; MTGGameZone * checkZone = card->controller()->inPlay();
for (int j = card->controller()->game->battlefield->nb_cards - 1; j >= 0; --j) intValue =
{ countCardTypeinZone("forest",checkZone) +
if (card->controller()->game->battlefield->cards[j]->hasType("forest")) countCardTypeinZone("treefolk",checkZone);
{
intValue += 1;
}
if (card->controller()->game->battlefield->cards[j]->hasType("treefolk"))
{
intValue += 1;
}
}
} }
else if (s == "pbasiclandtypes")//Basic Land types else if (s == "pbasiclandtypes")//Basic Land types
{ {
intValue = 0; MTGGameZone * checkZone = card->controller()->inPlay();
int forest = 0, plains = 0, swamp = 0, island = 0, mountain = 0; intValue =
for (int j = card->controller()->game->battlefield->nb_cards - 1; j >= 0; --j) cardHasTypeinZone("forest",checkZone) +
{ cardHasTypeinZone("plains",checkZone) +
if (card->controller()->game->battlefield->cards[j]->hasType("forest")) cardHasTypeinZone("swamp",checkZone) +
{ cardHasTypeinZone("island",checkZone) +
forest = 1; cardHasTypeinZone("mountain",checkZone);
}
if (card->controller()->game->battlefield->cards[j]->hasType("plains"))
{
plains = 1;
}
if (card->controller()->game->battlefield->cards[j]->hasType("swamp"))
{
swamp = 1;
}
if (card->controller()->game->battlefield->cards[j]->hasType("island"))
{
island = 1;
}
if (card->controller()->game->battlefield->cards[j]->hasType("mountain"))
{
mountain = 1;
}
}
intValue = mountain + island + forest + swamp + plains;
} }
else if (s == "myname")//Name of the card you control else if (s == "myname")//Name of the card you control
{ {
intValue = 0; intValue = countCardNameinZone(card->name,card->controller()->inPlay());
for (int i = 0; i < 2; i++)
{
Player * p = card->getObserver()->players[i];
for (int j = p->game->battlefield->nb_cards - 1; j >= 0; --j)
{
if (p->game->battlefield->cards[j]->name == card->name && p == card->controller())
{
intValue += 1;
}
}
}
} }
else if (s == "allmyname")//Plague Rats and others else if (s == "allmyname")//Plague Rats and others
{ {
intValue = 0; intValue = 0;
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ intValue += countCardNameinZone(card->name,card->getObserver()->players[i]->game->battlefield);
Player * p = card->getObserver()->players[i];
for (int j = p->game->battlefield->nb_cards - 1; j >= 0; --j)
{
if (p->game->battlefield->cards[j]->name == card->name)
{
intValue += 1;
}
}
}
} }
else if (s == "pgbzombie")//Soulless One else if (s == "pgbzombie")//Soulless One
{ {
intValue = 0; intValue = 0;
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
Player * p = card->getObserver()->players[i]; intValue += countCardTypeinZone("zombie",card->getObserver()->players[i]->game->graveyard);
for (int j = p->game->graveyard->nb_cards - 1; j >= 0; --j) intValue += countCardTypeinZone("zombie",card->getObserver()->players[i]->game->battlefield);
{
if (p->game->graveyard->cards[j]->hasType("zombie"))
{
intValue += 1;
}
}
for (int j = p->game->inPlay->nb_cards - 1; j >= 0; --j)
{
if (p->game->inPlay->cards[j]->hasType("zombie"))
{
intValue += 1;
}
}
} }
} }
else if (s == "pginstantsorcery")//Spellheart Chimera else if (s == "pginstantsorcery")//Spellheart Chimera
@@ -982,51 +710,31 @@ private:
{ {
if (card->controller()->game->graveyard->cards[j]->hasType(Subtypes::TYPE_INSTANT) if (card->controller()->game->graveyard->cards[j]->hasType(Subtypes::TYPE_INSTANT)
||card->controller()->game->graveyard->cards[j]->hasType(Subtypes::TYPE_SORCERY)) ||card->controller()->game->graveyard->cards[j]->hasType(Subtypes::TYPE_SORCERY))
{ intValue += 1;
intValue += 1;
}
} }
} }
else if (s == "gravecardtypes")//Tarmogoyf else if (s == "gravecardtypes")//Tarmogoyf
{ {
intValue = 0;
int art = 0, cre = 0, enc = 0, ins = 0, lnd = 0, sor = 0, trb = 0, pwk = 0;
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
Player * p = card->getObserver()->players[i]; MTGGameZone * checkZone = card->getObserver()->players[i]->game->graveyard;
if(p->game->graveyard->hasType("planeswalker")) intValue =
pwk = 1; cardHasTypeinZone("planeswalker",checkZone) +
if(p->game->graveyard->hasType("tribal")) cardHasTypeinZone("tribal",checkZone) +
trb = 1; cardHasTypeinZone("sorcery",checkZone) +
if(p->game->graveyard->hasType("sorcery")) cardHasTypeinZone("land",checkZone) +
sor = 1; cardHasTypeinZone("instant",checkZone) +
if(p->game->graveyard->hasType("land")) cardHasTypeinZone("enchantment",checkZone) +
lnd = 1; cardHasTypeinZone("creature",checkZone) +
if(p->game->graveyard->hasType("instant")) cardHasTypeinZone("artifact",checkZone);
ins = 1;
if(p->game->graveyard->hasType("enchantment"))
enc = 1;
if(p->game->graveyard->hasType("creature"))
cre = 1;
if(p->game->graveyard->hasType("artifact"))
art = 1;
} }
intValue = art + cre + enc + ins + lnd + sor + trb + pwk;
} }
else if (s == "morethanfourcards") else if (s == "morethanfourcards")
{ {
if(card->playerTarget) intValue = 0;
{//blackvise int damage = card->playerTarget ? card->playerTarget->game->hand->nb_cards - 4 : card->controller()->opponent()->game->hand->nb_cards - 4;
intValue = 0; if ( damage > 0 )
if ((card->playerTarget->game->hand->nb_cards - 4)>0) intValue = damage;
intValue = (card->playerTarget->game->hand->nb_cards - 4);
}
else
{//viseling
intValue = 0;
if ((card->controller()->opponent()->game->hand->nb_cards - 4)>0)
intValue = (card->controller()->opponent()->game->hand->nb_cards - 4);
}
} }
else if (s == "powertotalinplay")//Count Total Power of Creatures you control... Formidable else if (s == "powertotalinplay")//Count Total Power of Creatures you control... Formidable
{ {
@@ -1034,9 +742,7 @@ private:
for (int j = card->controller()->game->inPlay->nb_cards - 1; j >= 0; --j) for (int j = card->controller()->game->inPlay->nb_cards - 1; j >= 0; --j)
{ {
if (card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_CREATURE)) if (card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_CREATURE))
{ intValue += card->controller()->game->inPlay->cards[j]->power;
intValue += card->controller()->game->inPlay->cards[j]->power;
}
} }
} }
else else
@@ -1077,6 +783,100 @@ private:
} }
public: public:
int countDevotionTo(MTGCardInstance * card, MTGGameZone * zone, int color1, int color2)
{
int counthybrid = 0;
TargetChooserFactory dtf(card->getObserver());
TargetChooser * dtc = dtf.createTargetChooser("*",NULL);
if (dtc->targetsZone(zone, card))
{
counthybrid += zone->countDevotion(dtc, color1, color2);
}
SAFE_DELETE(dtc);
return counthybrid;
}
int countCardNameinZone(string name, MTGGameZone * zone)
{
int count = 0;
for( int i= 0; i < zone->nb_cards; i ++)
if(zone->cards[i]->name == name)
count += 1;
return count;
}
int countCardsInPlaybyColor(int color, GameObserver * observer)
{
int count = 0;
for (int i = 0; i < 2; i++)
{
for( int j= 0; j < observer->players[i]->inPlay()->nb_cards; j++)
if(observer->players[i]->inPlay()->cards[j]->hasColor(color))
count += 1;
}
return count;
}
int mostCommonColor(int color, MTGCardInstance * card)
{
int maxColor = 0;
vector<int> colors;
for(int i = 1; i < 6; i++)
colors.push_back( countCardsInPlaybyColor(i, card->getObserver()) );
for(int j = 0; j < 5; j++)
if ( colors[j] > maxColor )
maxColor = colors[j];
if (countCardsInPlaybyColor(color, card->getObserver()) >= maxColor && maxColor > 0)
return 1;
return 0;
}
int countCardTypeinZone(string type, MTGGameZone * zone)
{
int count = 0;
for( int i= 0; i < zone->nb_cards; i ++)
if(zone->cards[i]->hasType(type))
count += 1;
return count;
}
int cardHasTypeinZone(const char * type, MTGGameZone * zone)
{
int count = 0;
if(zone->hasType(type))
count = 1;
return count;
}
int countCanTargetby(string type, MTGCardInstance * card, Player * player)
{
int count = 0;
for (int j = player->game->battlefield->nb_cards - 1; j >= 0; --j)
{
if (player->game->battlefield->cards[j]->hasType(type) && !player->game->battlefield->cards[j]->protectedAgainst(card))
count += 1;
}
return count;
}
int countManaProducedby(int color, MTGCardInstance * target, Player * player)
{
int count = 0;
for (size_t i = 0; i < target->getObserver()->mLayers->actionLayer()->manaObjects.size(); i++)
{
if (dynamic_cast<AManaProducer*> (((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i])) &&
(dynamic_cast<AManaProducer*> (((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i])))->source->isLand() &&
(dynamic_cast<AManaProducer*> (((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i])))->source->controller() == player &&
(dynamic_cast<AManaProducer*> (((MTGAbility *) target->getObserver()->mLayers->actionLayer()->manaObjects[i])))->output->hasColor(color))
count += 1;
}
return count;
}
WParsedInt(int value = 0) WParsedInt(int value = 0)
{ {
intValue = value; intValue = value;
@@ -1925,7 +1725,7 @@ public:
const string getMenuText(); const string getMenuText();
AACopier * clone() const; AACopier * clone() const;
}; };
//imprint //phaseout
class AAPhaseOut: public ActivatedAbility class AAPhaseOut: public ActivatedAbility
{ {
public: public:
@@ -1934,6 +1734,15 @@ public:
const string getMenuText(); const string getMenuText();
AAPhaseOut * clone() const; AAPhaseOut * clone() const;
}; };
//AAImprint
class AAImprint: public ActivatedAbility
{
public:
AAImprint(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target = NULL, ManaCost * _cost = NULL);
int resolve();
const string getMenuText();
AAImprint * clone() const;
};
//cloning...this makes a token thats a copy of the target. //cloning...this makes a token thats a copy of the target.
class AACloner: public ActivatedAbility class AACloner: public ActivatedAbility
{ {
@@ -5122,6 +4931,33 @@ public:
}; };
//AAttackSetCost
class AAttackSetCost: public MTGAbility
{
public:
string number;
bool pw;
AAttackSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number, bool pw = false);
void Update(float dt);
int addToGame();
int destroy();
const string getMenuText();
AAttackSetCost * clone() const;
};
//ABlockSetCost
class ABlockSetCost: public MTGAbility
{
public:
string number;
ABlockSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number);
void Update(float dt);
int addToGame();
int destroy();
const string getMenuText();
ABlockSetCost * clone() const;
};
//ABlink //ABlink
class ABlink: public MTGAbility class ABlink: public MTGAbility
{ {
+1
View File
@@ -76,6 +76,7 @@ class SacrificeCost : public ExtraCost
{ {
public: public:
SacrificeCost(TargetChooser *_tc = NULL); SacrificeCost(TargetChooser *_tc = NULL);
virtual int canPay();
virtual int doPay(); virtual int doPay();
virtual SacrificeCost * clone() const; virtual SacrificeCost * clone() const;
}; };
+2
View File
@@ -216,6 +216,8 @@ public:
PAYZERO_COST = 33, PAYZERO_COST = 33,
OVERLOAD_COST = 34, OVERLOAD_COST = 34,
BESTOW_COST = 35, BESTOW_COST = 35,
ATTACK_COST = 36,
BLOCK_COST = 37,
}; };
}; };
+14
View File
@@ -257,6 +257,20 @@ public:
int myconvertedcost; int myconvertedcost;
ManaCost * computeNewCost(MTGCardInstance * card,ManaCost * oldCost, ManaCost * refCost,bool noTrinisphere = false); ManaCost * computeNewCost(MTGCardInstance * card,ManaCost * oldCost, ManaCost * refCost,bool noTrinisphere = false);
int countTrini; int countTrini;
vector<MTGCardInstance*>imprintedCards;
int attackCost;
int attackCostBackup;
int attackPlaneswalkerCost;
int attackPlaneswalkerCostBackup;
int blockCost;
int blockCostBackup;
int imprintG;
int imprintU;
int imprintR;
int imprintB;
int imprintW;
string currentimprintName;
vector<string>imprintedNames;
void eventattacked(); void eventattacked();
void eventattackedAlone(); void eventattackedAlone();
+4 -1
View File
@@ -243,7 +243,10 @@ class Constants
LIBRARYEATER = 122, LIBRARYEATER = 122,
DEVOID = 123, DEVOID = 123,
CANTCHANGELIFE = 124, CANTCHANGELIFE = 124,
NB_BASIC_ABILITIES = 125, COMBATTOUGHNESS = 125,
CANTPAYLIFE = 126,
CANTBESACRIFIED = 127,
NB_BASIC_ABILITIES = 128,
RARITY_S = 'S', //Special Rarity RARITY_S = 'S', //Special Rarity
+1 -1
View File
@@ -98,7 +98,7 @@ class MTGGameZone {
unsigned int countByType(const string &value); unsigned int countByType(const string &value);
unsigned int countByCanTarget(TargetChooser * tc); unsigned int countByCanTarget(TargetChooser * tc);
unsigned int countTotalManaSymbols(TargetChooser * tc, int color); unsigned int countTotalManaSymbols(TargetChooser * tc, int color);
unsigned int countDevotion(TargetChooser * tc, int color); //devotion for gods unsigned int countDevotion(TargetChooser * tc, int color1, int color2); //devotion for gods
MTGCardInstance * findByName(string name); MTGCardInstance * findByName(string name);
//returns true if one of the cards in the zone has the ability //returns true if one of the cards in the zone has the ability
+24
View File
@@ -219,6 +219,18 @@ public:
virtual MTGSuspendRule * clone() const; virtual MTGSuspendRule * clone() const;
}; };
class MTGAttackCostRule: public PermanentAbility
{
public:
string scost;
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
int reactToClick(MTGCardInstance * card);
virtual ostream& toString(ostream& out) const;
MTGAttackCostRule(GameObserver* observer, int _id);
const string getMenuText();
virtual MTGAttackCostRule * clone() const;
};
class MTGAttackRule: public PermanentAbility, public Limitor class MTGAttackRule: public PermanentAbility, public Limitor
{ {
public: public:
@@ -274,6 +286,18 @@ public:
virtual MTGCombatTriggersRule * clone() const; virtual MTGCombatTriggersRule * clone() const;
}; };
class MTGBlockCostRule: public PermanentAbility
{
public:
string scost;
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
int reactToClick(MTGCardInstance * card);
virtual ostream& toString(ostream& out) const;
MTGBlockCostRule(GameObserver* observer, int _id);
const string getMenuText();
virtual MTGBlockCostRule * clone() const;
};
class MTGBlockRule: public PermanentAbility class MTGBlockRule: public PermanentAbility
{ {
public: public:
+1
View File
@@ -103,6 +103,7 @@ public:
int getCost(int color); int getCost(int color);
int getManaSymbols(int color); int getManaSymbols(int color);
int getManaSymbolsHybridMerged(int color); int getManaSymbolsHybridMerged(int color);
int countHybridsNoPhyrexian();
//Returns NULL if i is greater than nbhybrids //Returns NULL if i is greater than nbhybrids
ManaCostHybrid * getHybridCost(unsigned int i); ManaCostHybrid * getHybridCost(unsigned int i);
+204 -15
View File
@@ -482,6 +482,7 @@ int AACopier::resolve()
source->copiedID = _target->getMTGId(); source->copiedID = _target->getMTGId();
source->modifiedbAbi = _target->modifiedbAbi; source->modifiedbAbi = _target->modifiedbAbi;
source->origbasicAbilities = _target->origbasicAbilities; source->origbasicAbilities = _target->origbasicAbilities;
source->basicAbilities = _target->basicAbilities;
if(_target->isMorphed) if(_target->isMorphed)
{ {
source->power = 2; source->power = 2;
@@ -510,7 +511,7 @@ AACopier * AACopier::clone() const
return NEW AACopier(*this); return NEW AACopier(*this);
} }
//phaser //phaseout
AAPhaseOut::AAPhaseOut(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost) : AAPhaseOut::AAPhaseOut(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost) :
ActivatedAbility(observer, _id, _source, _cost, 0) ActivatedAbility(observer, _id, _source, _cost, 0)
{ {
@@ -543,6 +544,60 @@ AAPhaseOut * AAPhaseOut::clone() const
return NEW AAPhaseOut(*this); return NEW AAPhaseOut(*this);
} }
//AAImprint
AAImprint::AAImprint(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost) :
ActivatedAbility(observer, _id, _source, _cost, 0)
{
target = _target;
}
int AAImprint::resolve()
{
MTGCardInstance * _target = (MTGCardInstance *) target;
if (_target)
{
Player * p = _target->controller();
if(p)
p->game->putInExile(_target);
while(_target->next)
_target = _target->next;
source->imprintedCards.push_back(_target);
if (source->imprintedCards.size())
{
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_GREEN))
source->imprintG += 1;
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_BLUE))
source->imprintU += 1;
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_RED))
source->imprintR += 1;
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_BLACK))
source->imprintB += 1;
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_WHITE))
source->imprintW += 1;
if (source->imprintedCards.back()->getName().size())
{
source->currentimprintName = source->imprintedCards.back()->getName();
source->imprintedNames.push_back(source->imprintedCards.back()->getName());
}
}
return 1;
}
return 0;
}
const string AAImprint::getMenuText()
{
return "Imprint";
}
AAImprint * AAImprint::clone() const
{
return NEW AAImprint(*this);
}
//Counters //Counters
AACounter::AACounter(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target,string counterstring, const char * _name, int power, int toughness, AACounter::AACounter(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target,string counterstring, const char * _name, int power, int toughness,
int nb,int maxNb, ManaCost * cost) : int nb,int maxNb, ManaCost * cost) :
@@ -1312,6 +1367,16 @@ int GenericPaidAbility::resolve()
optionalCost->extraCosts->costs[i]->setSource(((MTGCardInstance *)target)); optionalCost->extraCosts->costs[i]->setSource(((MTGCardInstance *)target));
} }
} }
if (source && source->previous && source->basicAbilities[(int)Constants::MADNESS])
{
must = true;
optionalCost = source->computeNewCost(source->previous,optionalCost,optionalCost);
if(optionalCost->extraCosts)
{
for(unsigned int i = 0; i < optionalCost->extraCosts->costs.size();i++)
optionalCost->extraCosts->costs[i]->setSource(source);
}
}
if(asAlternate && nomenu && optionalCost->getConvertedCost() < 1) if(asAlternate && nomenu && optionalCost->getConvertedCost() < 1)
nomenuAbility->resolve(); nomenuAbility->resolve();
else else
@@ -2945,7 +3010,7 @@ int AAMover::resolve()
//inplay is a special zone ! //inplay is a special zone !
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
if (destZone == game->players[i]->game->inPlay && fromZone != game->players[i]->game->inPlay && fromZone if (!_target->hasSubtype(Subtypes::TYPE_AURA) && destZone == game->players[i]->game->inPlay && fromZone != game->players[i]->game->inPlay && fromZone
!= game->players[i]->opponent()->game->inPlay) != game->players[i]->opponent()->game->inPlay)
{ {
MTGCardInstance * copy = game->players[i]->game->putInZone(_target, fromZone, game->players[i]->game->temp); MTGCardInstance * copy = game->players[i]->game->putInZone(_target, fromZone, game->players[i]->game->temp);
@@ -2973,21 +3038,45 @@ int AAMover::resolve()
return 1; return 1;
} }
} }
p->game->putInZone(_target, fromZone, destZone); if(_target->hasSubtype(Subtypes::TYPE_AURA) && (destZone == game->players[0]->game->inPlay || destZone == game->players[1]->game->inPlay))
while(_target->next) {//put into play aura if there is no valid targets then it will be in its current zone
_target = _target->next; MTGAbility *a = NEW AACastCard(game, game->mLayers->actionLayer()->getMaxId(), _target, _target,false,false,false,"","Put in play",false,true);
if(andAbility) a->oneShot = false;
{ a->canBeInterrupted = false;
MTGAbility * andAbilityClone = andAbility->clone(); a->addToGame();
andAbilityClone->target = _target; if(andAbility && _target->next)
if(andAbility->oneShot) {//if successful target->next should be valid
{ MTGAbility * andAbilityClone = andAbility->clone();
andAbilityClone->resolve(); andAbilityClone->target = _target->next;
SAFE_DELETE(andAbilityClone); if(andAbility->oneShot)
{
andAbilityClone->resolve();
SAFE_DELETE(andAbilityClone);
}
else
{
andAbilityClone->addToGame();
}
} }
else }
else
{
p->game->putInZone(_target, fromZone, destZone);
while(_target->next)
_target = _target->next;
if(andAbility)
{ {
andAbilityClone->addToGame(); MTGAbility * andAbilityClone = andAbility->clone();
andAbilityClone->target = _target;
if(andAbility->oneShot)
{
andAbilityClone->resolve();
SAFE_DELETE(andAbilityClone);
}
else
{
andAbilityClone->addToGame();
}
} }
} }
return 1; return 1;
@@ -5356,6 +5445,106 @@ APhaseActionGeneric::~APhaseActionGeneric()
SAFE_DELETE(ability); SAFE_DELETE(ability);
} }
//AAttackSetCost
AAttackSetCost::AAttackSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number, bool pw) :
MTGAbility(observer, _id, _source), number(number), pw(pw)
{
}
void AAttackSetCost::Update(float dt)
{
if(game->getCurrentGamePhase() != MTG_PHASE_COMBATATTACKERS)
{
source->attackCost = source->attackCostBackup;
if(pw)
source->attackPlaneswalkerCost = source->attackPlaneswalkerCostBackup;
MTGAbility::Update(dt);
}
}
int AAttackSetCost::addToGame()
{
WParsedInt attackcost(number, NULL, source);
source->attackCost += attackcost.getValue();
source->attackCostBackup += attackcost.getValue();
if(pw)
{
source->attackPlaneswalkerCost += attackcost.getValue();
source->attackPlaneswalkerCostBackup += attackcost.getValue();
}
return MTGAbility::addToGame();
}
int AAttackSetCost::destroy()
{
WParsedInt attackcost(number, NULL, source);
source->attackCost -= attackcost.getValue();
source->attackCostBackup -= attackcost.getValue();
if(pw)
{
source->attackPlaneswalkerCost -= attackcost.getValue();
source->attackPlaneswalkerCostBackup -= attackcost.getValue();
}
return 1;
}
const string AAttackSetCost::getMenuText()
{
return "Attack Cost";
}
AAttackSetCost * AAttackSetCost::clone() const
{
return NEW AAttackSetCost(*this);
}
//ABlockSetCost
ABlockSetCost::ABlockSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number) :
MTGAbility(observer, _id, _source), number(number)
{
}
void ABlockSetCost::Update(float dt)
{
if(game->getCurrentGamePhase() != MTG_PHASE_COMBATBLOCKERS)
{
source->blockCost = source->blockCostBackup;
MTGAbility::Update(dt);
}
}
int ABlockSetCost::addToGame()
{
WParsedInt blockCost(number, NULL, source);
source->blockCost += blockCost.getValue();
source->blockCostBackup += blockCost.getValue();
return MTGAbility::addToGame();
}
int ABlockSetCost::destroy()
{
WParsedInt blockCost(number, NULL, source);
source->blockCost -= blockCost.getValue();
source->blockCostBackup -= blockCost.getValue();
return 1;
}
const string ABlockSetCost::getMenuText()
{
return "Block Cost";
}
ABlockSetCost * ABlockSetCost::clone() const
{
return NEW ABlockSetCost(*this);
}
//a blink //a blink
ABlink::ABlink(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, bool blinkueot, bool blinkForSource, bool blinkhand, MTGAbility * stored) : ABlink::ABlink(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, bool blinkueot, bool blinkForSource, bool blinkhand, MTGAbility * stored) :
MTGAbility(observer, _id, card),blinkueot(blinkueot),blinkForSource(blinkForSource),blinkhand(blinkhand),stored(stored) MTGAbility(observer, _id, card),blinkueot(blinkueot),blinkForSource(blinkForSource),blinkhand(blinkhand),stored(stored)
+26 -3
View File
@@ -248,7 +248,9 @@ LifeCost::LifeCost(TargetChooser *_tc)
int LifeCost::canPay() int LifeCost::canPay()
{ {
MTGCardInstance * _target = (MTGCardInstance *) target; MTGCardInstance * _target = (MTGCardInstance *) target;
if(_target->controller()->life <= 0 || _target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE)) if (_target->controller()->life <= 0 || _target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE) ||
_target->controller()->opponent()->game->battlefield->hasAbility(Constants::CANTPAYLIFE) ||
_target->controller()->game->battlefield->hasAbility(Constants::CANTPAYLIFE))
{ {
return 0; return 0;
} }
@@ -286,7 +288,9 @@ SpecificLifeCost::SpecificLifeCost(TargetChooser *_tc, int slc)
int SpecificLifeCost::canPay() int SpecificLifeCost::canPay()
{ {
MTGCardInstance * _target = (MTGCardInstance *) target; MTGCardInstance * _target = (MTGCardInstance *) target;
if(_target->controller()->life >= slc && !_target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE)) if(_target->controller()->life >= slc && !_target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE) &&
!_target->controller()->opponent()->game->battlefield->hasAbility(Constants::CANTPAYLIFE) &&
!_target->controller()->game->battlefield->hasAbility(Constants::CANTPAYLIFE))
{ {
return 1; return 1;
} }
@@ -334,7 +338,16 @@ LifeorManaCost::LifeorManaCost(TargetChooser *_tc, string manaType)
int LifeorManaCost::canPay() int LifeorManaCost::canPay()
{ {
MTGCardInstance * _target = (MTGCardInstance *) target; MTGCardInstance * _target = (MTGCardInstance *) target;
if (_target->controller()->getManaPool()->canAfford(getManaCost()) || _target->controller()->life > 1) if ( _target->controller()->life <= 1 || _target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE) ||
_target->controller()->opponent()->game->battlefield->hasAbility(Constants::CANTPAYLIFE) ||
_target->controller()->game->battlefield->hasAbility(Constants::CANTPAYLIFE))
{
return _target->controller()->getManaPool()->canAfford(getManaCost());
}
else if((_target->controller()->life > 1 || _target->controller()->getManaPool()->canAfford(getManaCost())) &&
(!_target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE) &&
!_target->controller()->opponent()->game->battlefield->hasAbility(Constants::CANTPAYLIFE) &&
!_target->controller()->game->battlefield->hasAbility(Constants::CANTPAYLIFE)))
{ {
return 1; return 1;
} }
@@ -926,6 +939,9 @@ ExtraCost("Select creature to offer", _tc)
int Offering::canPay() int Offering::canPay()
{ {
if (target && target->has(Constants::CANTBESACRIFIED))
return 0;
if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost())))) if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
{ {
tc->removeTarget(target); tc->removeTarget(target);
@@ -983,6 +999,13 @@ SacrificeCost::SacrificeCost(TargetChooser *_tc)
{ {
} }
int SacrificeCost::canPay()
{
if (target && target->has(Constants::CANTBESACRIFIED))
return 0;
return 1;
}
int SacrificeCost::doPay() int SacrificeCost::doPay()
{ {
if (target) if (target)
+18
View File
@@ -687,6 +687,24 @@ void GameObserver::gameStateBasedEffects()
card->myPair->myPair = NULL; card->myPair->myPair = NULL;
card->myPair = NULL; card->myPair = NULL;
} }
///clear imprints
if(isInPlay(card) && card->imprintedCards.size())
{
for(size_t ic = 0; ic < card->imprintedCards.size(); ic++)
{
if(!isInExile(card->imprintedCards[ic]))
{
card->imprintG = 0;
card->imprintU = 0;
card->imprintR = 0;
card->imprintB = 0;
card->imprintW = 0;
card->currentimprintName = "";
card->imprintedNames.clear();
card->imprintedCards.erase(card->imprintedCards.begin() + ic);
}
}
}
card->bypassTC = false; //turn off bypass card->bypassTC = false; //turn off bypass
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
//Unattach Equipments that dont have valid targets// //Unattach Equipments that dont have valid targets//
+41
View File
@@ -1179,6 +1179,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
observer->addObserver(NEW MTGAttackRule(observer, -1)); observer->addObserver(NEW MTGAttackRule(observer, -1));
return NULL; return NULL;
} }
//this rule handles attacking cost ability during attacker phase
found = s.find("attackcostrule");
if(found != string::npos)
{
observer->addObserver(NEW MTGAttackCostRule(observer, -1));
return NULL;
}
//this rule handles blocking ability during blocker phase //this rule handles blocking ability during blocker phase
found = s.find("blockrule"); found = s.find("blockrule");
if(found != string::npos) if(found != string::npos)
@@ -1186,6 +1193,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
observer->addObserver(NEW MTGBlockRule(observer, -1)); observer->addObserver(NEW MTGBlockRule(observer, -1));
return NULL; return NULL;
} }
//this rule handles blocking cost ability during blocker phase
found = s.find("blockcostrule");
if(found != string::npos)
{
observer->addObserver(NEW MTGBlockCostRule(observer, -1));
return NULL;
}
//this rule handles cards that have soulbond //this rule handles cards that have soulbond
found = s.find("soulbondrule"); found = s.find("soulbondrule");
if(found != string::npos) if(found != string::npos)
@@ -2361,6 +2375,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
} }
//imprint //imprint
found = s.find("imprint");
if (found != string::npos)
{
MTGAbility * a = NEW AAImprint(observer, id, card, target);
a->oneShot = 1;
return a;
}
//phaseout
found = s.find("phaseout"); found = s.find("phaseout");
if (found != string::npos) if (found != string::npos)
{ {
@@ -2820,6 +2843,24 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return NEW AReduceToAbility(observer, id, card,s.substr(9)); return NEW AReduceToAbility(observer, id, card,s.substr(9));
} }
//attack cost
if (s.find("attackcost:") != string::npos)
{
return NEW AAttackSetCost(observer, id, card, s.substr(11));
}
//attack cost + planeswalker
if (s.find("attackpwcost:") != string::npos)
{
return NEW AAttackSetCost(observer, id, card, s.substr(13),true);
}
//block cost
if (s.find("blockcost:") != string::npos)
{
return NEW ABlockSetCost(observer, id, card, s.substr(10));
}
//flanking //flanking
if (s.find("flanker") != string::npos) if (s.find("flanker") != string::npos)
{ {
+21 -4
View File
@@ -100,8 +100,10 @@ void MTGCardInstance::copy(MTGCardInstance * card)
setText(""); //The text is retrieved from the data anyways setText(""); //The text is retrieved from the data anyways
setName(data->name); setName(data->name);
power = data->power; power = data->power;//layer 7a
toughness = data->toughness; toughness = data->toughness;//layer 7a
power += pbonus;//layer 7b
toughness += tbonus;//layer 7b
life = toughness; life = toughness;
lifeOrig = life; lifeOrig = life;
magicText = data->magicText; magicText = data->magicText;
@@ -206,6 +208,20 @@ void MTGCardInstance::initMTGCI()
myPair = NULL; myPair = NULL;
miracle = false; miracle = false;
countTrini = 0; countTrini = 0;
imprintedCards.clear();
attackCost = 0;
attackCostBackup = 0;
attackPlaneswalkerCost = 0;
attackPlaneswalkerCostBackup = 0;
blockCost = 0;
blockCostBackup = 0;
imprintG = 0;
imprintU = 0;
imprintR = 0;
imprintB = 0;
imprintW = 0;
currentimprintName = "";
imprintedNames.clear();
for (int i = 0; i < ManaCost::MANA_PAID_WITH_SUSPEND +1; i++) for (int i = 0; i < ManaCost::MANA_PAID_WITH_SUSPEND +1; i++)
alternateCostPaid[i] = 0; alternateCostPaid[i] = 0;
@@ -1525,12 +1541,13 @@ const string& MTGCardInstance::getSample()
int MTGCardInstance::stepPower(CombatStep step) int MTGCardInstance::stepPower(CombatStep step)
{ {
int damage = has(Constants::COMBATTOUGHNESS) ? toughness : power;
switch (step) switch (step)
{ {
case FIRST_STRIKE: case FIRST_STRIKE:
case END_FIRST_STRIKE: case END_FIRST_STRIKE:
if (has(Constants::FIRSTSTRIKE) || has(Constants::DOUBLESTRIKE)) if (has(Constants::FIRSTSTRIKE) || has(Constants::DOUBLESTRIKE))
return MAX(0, power); return MAX(0, damage);
else else
return 0; return 0;
case DAMAGE: case DAMAGE:
@@ -1539,7 +1556,7 @@ int MTGCardInstance::stepPower(CombatStep step)
if (has(Constants::FIRSTSTRIKE) && !has(Constants::DOUBLESTRIKE)) if (has(Constants::FIRSTSTRIKE) && !has(Constants::DOUBLESTRIKE))
return 0; return 0;
else else
return MAX(0, power); return MAX(0, damage);
} }
} }
+4 -1
View File
@@ -154,7 +154,10 @@ const char* Constants::MTGBasicAbilities[] = {
"canplayfromexile", "canplayfromexile",
"libraryeater", "libraryeater",
"devoid", "devoid",
"cantchangelife" "cantchangelife",
"combattoughness",
"cantpaylife",
"cantbesacrified"
}; };
map<string,int> Constants::MTGBasicAbilitiesMap; map<string,int> Constants::MTGBasicAbilitiesMap;
+7 -2
View File
@@ -642,7 +642,7 @@ unsigned int MTGGameZone::countTotalManaSymbols(TargetChooser * tc, int color)
return result; return result;
} }
unsigned int MTGGameZone::countDevotion(TargetChooser * tc, int color) unsigned int MTGGameZone::countDevotion(TargetChooser * tc, int color1, int color2)
{ {
if (!tc) { if (!tc) {
return 0; return 0;
@@ -654,8 +654,13 @@ unsigned int MTGGameZone::countDevotion(TargetChooser * tc, int color)
{ {
if (tc->canTarget(cards[i], withoutProtections)) if (tc->canTarget(cards[i], withoutProtections))
{ {
result += cards[i]->getManaCost()->getManaSymbolsHybridMerged(color); result += cards[i]->getManaCost()->getManaSymbolsHybridMerged(color1);
} }
if (tc->canTarget(cards[i], withoutProtections))
{
result += cards[i]->getManaCost()->getManaSymbolsHybridMerged(color2);
}
result -= cards[i]->getManaCost()->countHybridsNoPhyrexian();
} }
return result; return result;
} }
+147 -5
View File
@@ -1348,12 +1348,154 @@ MTGOverloadRule * MTGOverloadRule::clone() const
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
//ATTACK COST
MTGAttackCostRule::MTGAttackCostRule(GameObserver* observer, int _id) :
PermanentAbility(observer, _id)
{
aType = MTGAbility::ATTACK_COST;
scost = "Pay to attack";
}
int MTGAttackCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
{
if (currentPhase == MTG_PHASE_COMBATATTACKERS && card->controller() == game->currentPlayer && card->controller() == game->currentlyActing())//on my turn and when I am the acting player.
{
if(card->isPhased)
return 0;
if(card->attackCost < 1)
return 0;
ManaCost * playerMana = card->controller()->getManaPool();
ManaCost * attackcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
attackcost->add(0,card->attackCostBackup);
if(attackcost->extraCosts)
for(unsigned int i = 0; i < attackcost->extraCosts->costs.size();i++)
{
attackcost->extraCosts->costs[i]->setSource(card);
}
scost = attackcost->getConvertedCost();
if (playerMana->canAfford(attackcost))
return 1;
}
return 0;
}
int MTGAttackCostRule::reactToClick(MTGCardInstance * card)
{
if (!isReactingToClick(card))
return 0;
Player * player = game->currentlyActing();
ManaCost * attackcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
attackcost->add(0,card->attackCostBackup);
ManaCost * playerMana = player->getManaPool();
playerMana->pay(attackcost);//I think you can't pay partial cost to attack cost so you pay full (508.1i)
card->attackCost = 0;
card->attackPlaneswalkerCost = 0;
return 1;
/*
508.1g: If any of the chosen creatures require paying costs to attack, the active player determines the total cost to attack.
Costs may include paying mana, tapping permanents, sacrificing permanents, discarding cards, and so on. Once the total cost is determined, it becomes locked in.
If effects would change the total cost after this time, ignore this change.
508.1h: If any of the costs require mana, the active player then has a chance to activate mana abilities (see rule 605, Mana Abilities).
508.1i: Once the player has enough mana in his or her mana pool, he or she pays all costs in any order. Partial payments are not allowed.
*/
}
ostream& MTGAttackCostRule::toString(ostream& out) const
{
out << "MTGAttackCostRule ::: (";
return MTGAbility::toString(out) << ")";
}
const string MTGAttackCostRule::getMenuText()
{
sprintf(menuText, "Pay to attack");
return menuText;
}
MTGAttackCostRule * MTGAttackCostRule::clone() const
{
return NEW MTGAttackCostRule(*this);
}
//BLOCK COST
MTGBlockCostRule::MTGBlockCostRule(GameObserver* observer, int _id) :
PermanentAbility(observer, _id)
{
aType = MTGAbility::BLOCK_COST;
scost = "Pay to block";
}
int MTGBlockCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
{
if (currentPhase == MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting
&& card->controller() != game->currentPlayer
)
{
if(card->isPhased)
return 0;
if(card->blockCost < 1)
return 0;
ManaCost * playerMana = card->controller()->getManaPool();
ManaCost * blockcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
blockcost->add(0,card->blockCostBackup);
if(blockcost->extraCosts)
for(unsigned int i = 0; i < blockcost->extraCosts->costs.size();i++)
{
blockcost->extraCosts->costs[i]->setSource(card);
}
scost = blockcost->getConvertedCost();
if (playerMana->canAfford(blockcost))
return 1;
}
return 0;
}
int MTGBlockCostRule::reactToClick(MTGCardInstance * card)
{
if (!isReactingToClick(card))
return 0;
Player * player = game->currentlyActing();
ManaCost * blockcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
blockcost->add(0,card->blockCostBackup);
ManaCost * playerMana = player->getManaPool();
playerMana->pay(blockcost);//I think you can't pay partial cost to block cost so you pay full (509.1f)
card->blockCost = 0;
return 1;
/*
509.1d: If any of the chosen creatures require paying costs to block, the defending player determines the total cost to block.
Costs may include paying mana, tapping permanents, sacrificing permanents, discarding cards, and so on.
Once the total cost is determined, it becomes locked in. If effects would change the total cost after this time, ignore this change.
509.1e: If any of the costs require mana, the defending player then has a chance to activate mana abilities (see rule 605, Mana Abilities).
509.1f: Once the player has enough mana in his or her mana pool, he or she pays all costs in any order. Partial payments are not allowed.
*/
}
ostream& MTGBlockCostRule::toString(ostream& out) const
{
out << "MTGBlockCostRule ::: (";
return MTGAbility::toString(out) << ")";
}
const string MTGBlockCostRule::getMenuText()
{
sprintf(menuText, "Pay to block");
return menuText;
}
MTGBlockCostRule * MTGBlockCostRule::clone() const
{
return NEW MTGBlockCostRule(*this);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
bool MTGAttackRule::select(Target* t) bool MTGAttackRule::select(Target* t)
{ {
if (CardView* c = dynamic_cast<CardView*>(t)) if (CardView* c = dynamic_cast<CardView*>(t))
{ {
MTGCardInstance * card = c->getCard(); MTGCardInstance * card = c->getCard();
if (card->canAttack() && !card->isPhased) if (card->canAttack() && !card->isPhased && card->attackCost < 1)
return true; return true;
} }
return false; return false;
@@ -1377,7 +1519,7 @@ int MTGAttackRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
return 0; return 0;
if (card->isAttacker()) if (card->isAttacker())
return 1; return 1;
if (card->canAttack()) if (card->canAttack() && card->attackCost < 1)
return 1; return 1;
} }
return 0; return 0;
@@ -1453,7 +1595,7 @@ int MTGPlaneswalkerAttackRule::isReactingToClick(MTGCardInstance * card, ManaCos
return 0; return 0;
if (card->isAttacker()) if (card->isAttacker())
return 1; return 1;
if (card->canAttack()) if (card->canAttack() && card->attackPlaneswalkerCost < 1)
return 1; return 1;
} }
return 0; return 0;
@@ -1718,7 +1860,7 @@ int MTGBlockRule::receiveEvent(WEvent *e)
{ {
MTGCardInstance * card = z->cards[i]; MTGCardInstance * card = z->cards[i];
if ((card->defenser && !card->defenser->has(Constants::LURE))||!card->defenser) if ((card->defenser && !card->defenser->has(Constants::LURE))||!card->defenser)
if(card->canBlock(lurer)) if(card->canBlock(lurer) && card->blockCost < 1)
card->setDefenser(lurer); card->setDefenser(lurer);
//force a block on a lurer, the player has a chance to set his own choice on multiple lures //force a block on a lurer, the player has a chance to set his own choice on multiple lures
//but this action can not be ignored. //but this action can not be ignored.
@@ -1736,7 +1878,7 @@ int MTGBlockRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
&& card->controller() != game->currentPlayer && card->controller() != game->currentPlayer
) )
{ {
if (card->canBlock() && !card->isPhased) if (card->canBlock() && !card->isPhased && card->blockCost < 1)
{ {
if(card->isDefenser()) if(card->isDefenser())
blockmenu = "Remove Blocker"; blockmenu = "Remove Blocker";
+9 -1
View File
@@ -667,7 +667,7 @@ int ManaCost::getManaSymbolsHybridMerged(int color)
int result = cost[color]; int result = cost[color];
for (size_t i = 0; i < hybrids.size(); ++i) for (size_t i = 0; i < hybrids.size(); ++i)
{ {
result = hybrids[i].getManaSymbolsHybridMerged(color);//removed + result += hybrids[i].getManaSymbolsHybridMerged(color);
} }
if (extraCosts && extraCosts->costs.size()) if (extraCosts && extraCosts->costs.size())
{ {
@@ -683,6 +683,14 @@ int ManaCost::getManaSymbolsHybridMerged(int color)
return result; return result;
} }
int ManaCost::countHybridsNoPhyrexian()
{
int result = 0;
for (size_t i = 0; i < hybrids.size(); i++)
result ++;
return result;
}
int ManaCost::parseManaSymbol(char symbol) int ManaCost::parseManaSymbol(char symbol)
{ {
switch (symbol) switch (symbol)
+3 -1
View File
@@ -253,7 +253,9 @@ bool Player::hasPossibleAttackers()
for (int j = 0; j < nbcards; ++j) for (int j = 0; j < nbcards; ++j)
{ {
MTGCardInstance * c = z->cards[j]; MTGCardInstance * c = z->cards[j];
if (c->canAttack()) if (!c->isTapped() &&
!c->hasSummoningSickness() &&
c->isCreature())
return true; return true;
} }
return false; return false;