Added / fixed primitives from NEO set, improved Android downloader for token images, fixed a problem with castcard copied option for permanents, fixed a bug on colorless mana calculation for AI during combo.

This commit is contained in:
Vittorio Alfieri
2023-06-20 17:29:44 +02:00
parent 721a3edefb
commit f9bcaf53c2
5 changed files with 409 additions and 148 deletions
@@ -213,25 +213,29 @@ public class ImgDownloader {
if (printsTable != null) { if (printsTable != null) {
Element tokenRow = null; Element tokenRow = null;
Elements rows = printsTable.select("tr"); Elements rows = printsTable.select("tr");
int howmany = 0;
for (Element row : rows) { for (Element row : rows) {
if (row.text().contains(" Token,") && !row.text().contains("Faces,")) { if (row.text().contains(" Token,") && !row.text().contains("Faces,")) {
tokenRow = row; Element aElement = row.selectFirst("td > a");
}
}
if (tokenRow != null) {
Element aElement = tokenRow.selectFirst("td > a");
if (aElement != null) {
String tokenName = aElement.text(); String tokenName = aElement.text();
tokenName = tokenName.substring(0, tokenName.indexOf(" Token,")); tokenName = tokenName.substring(0, tokenName.indexOf(" Token,"));
imageUrl = aElement.attr("data-card-image-front"); if(tokenName.equals("Copy")){
if(imageUrl == null){ System.out.println("The token " + tokenName + " has been filtered for card: " + (String)jsonObject.get("name"));
System.err.println("Cannot retrieve image url for token: " + tokenName); } else {
return null; imageUrl = aElement.attr("data-card-image-front");
if(imageUrl == null){
System.err.println("Cannot retrieve image url for token: " + tokenName + " created by: " + (String)jsonObject.get("name"));
} else {
howmany++;
if(imageUrl.indexOf(".jpg") < imageUrl.length())
imageUrl = imageUrl.substring(0, imageUrl.indexOf(".jpg")+4);
}
} }
if(imageUrl.indexOf(".jpg") < imageUrl.length())
imageUrl = imageUrl.substring(0, imageUrl.indexOf(".jpg")+4);
} }
} }
if (howmany > 1) {
System.out.println("Found " + howmany + " valid image urls for token created by: " + (String)jsonObject.get("name"));
}
} }
} }
} catch (IOException e) { } catch (IOException e) {
@@ -250,18 +254,18 @@ public class ImgDownloader {
if (printsTable != null) { if (printsTable != null) {
Element tokenRow = null; Element tokenRow = null;
Elements rows = printsTable.select("tr"); Elements rows = printsTable.select("tr");
int howmany = 0;
for (Element row : rows) { for (Element row : rows) {
if (row.text().contains(" Token,") && !row.text().contains("Faces,")) { if (row.text().contains(" Token,") && !row.text().contains("Faces,")) {
tokenRow = row; Element aElement = row.selectFirst("td > a");
}
}
if (tokenRow != null) {
Element aElement = tokenRow.selectFirst("td > a");
if (aElement != null) {
tokenName = aElement.text(); tokenName = aElement.text();
tokenName = tokenName.substring(0, tokenName.indexOf(" Token,")); tokenName = tokenName.substring(0, tokenName.indexOf(" Token,"));
howmany++;
} }
} }
if (howmany > 1) {
System.out.println("Found " + howmany + " valid token name created by: " + (String)jsonObject.get("name"));
}
} }
} }
} catch (IOException e) { } catch (IOException e) {
@@ -3978,7 +3982,7 @@ public class ImgDownloader {
if (httpcon == null) { if (httpcon == null) {
System.err.println("Error: Problem fetching card: " + mappa.get(id) + "-" + id + ", i will not download it..."); System.err.println("Error: Problem fetching card: " + mappa.get(id) + "-" + id + ", i will not download it...");
res = mappa.get(id) + " - " + set + File.separator + id + ".jpg\n" + res; res = mappa.get(id) + " - " + set + File.separator + id + ".jpg\n" + res;
break; continue;
} }
httpcon.addRequestProperty("User-Agent", "Mozilla/4.76"); httpcon.addRequestProperty("User-Agent", "Mozilla/4.76");
httpcon.setConnectTimeout(5000); httpcon.setConnectTimeout(5000);
@@ -4000,7 +4004,7 @@ public class ImgDownloader {
} catch (Exception ex3) { } catch (Exception ex3) {
System.err.println("Error: Problem downloading card: " + mappa.get(id) + " (" + id + ".jpg), i will not retry anymore..."); System.err.println("Error: Problem downloading card: " + mappa.get(id) + " (" + id + ".jpg), i will not retry anymore...");
res = mappa.get(id) + " - " + set + File.separator + id + ".jpg\n" + res; res = mappa.get(id) + " - " + set + File.separator + id + ".jpg\n" + res;
break; continue;
} }
} }
} }
@@ -4042,7 +4046,7 @@ public class ImgDownloader {
in.close(); in.close();
if (timeout) { if (timeout) {
System.err.println("Warning: Problem downloading card: " + mappa.get(id) + " (" + id + ".jpg) from, i will not retry anymore..."); System.err.println("Warning: Problem downloading card: " + mappa.get(id) + " (" + id + ".jpg) from, i will not retry anymore...");
break; continue;
} }
byte[] response = out.toByteArray(); byte[] response = out.toByteArray();
String cardimage = imgPath + File.separator + id + ".jpg"; String cardimage = imgPath + File.separator + id + ".jpg";
@@ -4061,7 +4065,7 @@ public class ImgDownloader {
} catch (Exception e) { } catch (Exception e) {
System.err.println("Error: Problem resizing card: " + mappa.get(id) + " (" + id + ".jpg), image may be corrupted..."); System.err.println("Error: Problem resizing card: " + mappa.get(id) + " (" + id + ".jpg), image may be corrupted...");
res = mappa.get(id) + " - " + set + File.separator + id + ".jpg\n" + res; res = mappa.get(id) + " - " + set + File.separator + id + ".jpg\n" + res;
break; continue;
} }
try { try {
Bitmap yourBitmapthumb = BitmapFactory.decodeFile(cardimage); Bitmap yourBitmapthumb = BitmapFactory.decodeFile(cardimage);
@@ -4074,64 +4078,51 @@ public class ImgDownloader {
} catch (Exception e) { } catch (Exception e) {
System.err.println("Error: Problem resizing card thumbnail: " + mappa.get(id) + " (" + id + ".jpg, image may be corrupted..."); System.err.println("Error: Problem resizing card thumbnail: " + mappa.get(id) + " (" + id + ".jpg, image may be corrupted...");
res = mappa.get(id) + " - " + set + File.separator + "thumbnails" + File.separator + id + ".jpg\n" + res; res = mappa.get(id) + " - " + set + File.separator + "thumbnails" + File.separator + id + ".jpg\n" + res;
break; continue;
} }
if(card != null && hasToken(id)) { if(card != null && hasToken(id)) {
String text = (String) card.get("oracle_text"); String text = (String) card.get("oracle_text");
if (text != null && !text.isEmpty() && !text.trim().toLowerCase().contains("nontoken") && ((text.trim().toLowerCase().contains("create") && text.trim().toLowerCase().contains("creature token")) || String nametoken = findTokenName(card);
(text.trim().toLowerCase().contains("put") && text.trim().toLowerCase().contains("token")))) { if (!nametoken.isEmpty() || (text != null && !text.isEmpty() && !text.trim().toLowerCase().contains("nontoken") && ((text.trim().toLowerCase().contains("create") && text.trim().toLowerCase().contains("creature token")) ||
(text.trim().toLowerCase().contains("put") && text.trim().toLowerCase().contains("token"))))) {
System.out.println("The card: " + mappa.get(id) + " (" + id + ".jpg) can create a token, i will try to download that image too as " + id + "t.jpg"); System.out.println("The card: " + mappa.get(id) + " (" + id + ".jpg) can create a token, i will try to download that image too as " + id + "t.jpg");
String specialtokenurl = findTokenImageUrl(card, "large"); String specialtokenurl = findTokenImageUrl(card, "large");
String nametoken = findTokenName(card); if (!specialtokenurl.isEmpty()) {
URL urltoken = null; URL urltoken = null;
if (!specialtokenurl.isEmpty())
urltoken = new URL(specialtokenurl); urltoken = new URL(specialtokenurl);
HttpURLConnection httpcontoken = (HttpURLConnection) urltoken.openConnection();
HttpURLConnection httpcontoken = (HttpURLConnection) urltoken.openConnection(); if (httpcontoken == null) {
if (httpcontoken == null) { System.err.println("Error: Problem downloading token: " + nametoken + " (" + id + "t.jpg), i will not download it...");
System.err.println("Error: Problem downloading token: " + nametoken + " (" + id + "t.jpg), i will not download it..."); res = nametoken + " - " + set + File.separator + id + "t.jpg\n" + res;
res = nametoken + " - " + set + File.separator + id + "t.jpg\n" + res; continue;
break; }
} httpcontoken.addRequestProperty("User-Agent", "Mozilla/4.76");
httpcontoken.addRequestProperty("User-Agent", "Mozilla/4.76"); httpcontoken.setConnectTimeout(5000);
httpcontoken.setConnectTimeout(5000); httpcontoken.setReadTimeout(5000);
httpcontoken.setReadTimeout(5000); httpcontoken.setAllowUserInteraction(false);
httpcontoken.setAllowUserInteraction(false); httpcontoken.setDoInput(true);
httpcontoken.setDoInput(true); httpcontoken.setDoOutput(false);
httpcontoken.setDoOutput(false); InputStream intoken = null;
InputStream intoken = null;
try {
intoken = new BufferedInputStream(httpcontoken.getInputStream());
} catch (IOException ex) {
System.out.println("Warning: Problem downloading token: " + nametoken + " (" + id + "t.jpg), i will retry 2 times more...");
try { try {
intoken = new BufferedInputStream(httpcontoken.getInputStream()); intoken = new BufferedInputStream(httpcontoken.getInputStream());
} catch (IOException ex2) { } catch (IOException ex) {
System.out.println("Warning: Problem downloading token: " + nametoken + " (" + id + "t.jpg), i will retry 1 time more..."); System.out.println("Warning: Problem downloading token: " + nametoken + " (" + id + "t.jpg), i will retry 2 times more...");
try { try {
intoken = new BufferedInputStream(httpcontoken.getInputStream()); intoken = new BufferedInputStream(httpcontoken.getInputStream());
} catch (IOException ex3) { } catch (IOException ex2) {
System.err.println("Error: Problem downloading token: " + nametoken + " (" + id + "t.jpg), i will not retry anymore..."); System.out.println("Warning: Problem downloading token: " + nametoken + " (" + id + "t.jpg), i will retry 1 time more...");
res = nametoken + " - " + set + File.separator + id + "t.jpg\n" + res; try {
break; intoken = new BufferedInputStream(httpcontoken.getInputStream());
} catch (IOException ex3) {
System.err.println("Error: Problem downloading token: " + nametoken + " (" + id + "t.jpg), i will not retry anymore...");
res = nametoken + " - " + set + File.separator + id + "t.jpg\n" + res;
continue;
}
} }
} }
} ByteArrayOutputStream outtoken = new ByteArrayOutputStream();
ByteArrayOutputStream outtoken = new ByteArrayOutputStream(); byte[] buftoken = new byte[1024];
byte[] buftoken = new byte[1024]; int ntoken = 0;
int ntoken = 0;
millis = System.currentTimeMillis();
timeout = false;
while (-1 != (ntoken = intoken.read(buftoken)) && !timeout) {
outtoken.write(buftoken, 0, ntoken);
if (System.currentTimeMillis() - millis > 10000)
timeout = true;
}
if (timeout) {
System.out.println("Warning: Problem downloading token: " + id + "t.jpg from, i will retry 2 times more...");
buftoken = new byte[1024];
ntoken = 0;
millis = System.currentTimeMillis(); millis = System.currentTimeMillis();
timeout = false; timeout = false;
while (-1 != (ntoken = intoken.read(buftoken)) && !timeout) { while (-1 != (ntoken = intoken.read(buftoken)) && !timeout) {
@@ -4140,7 +4131,7 @@ public class ImgDownloader {
timeout = true; timeout = true;
} }
if (timeout) { if (timeout) {
System.out.println("Warning: Problem downloading token: " + id + "t.jpg from, i will retry 1 time more..."); System.out.println("Warning: Problem downloading token: " + id + "t.jpg from, i will retry 2 times more...");
buftoken = new byte[1024]; buftoken = new byte[1024];
ntoken = 0; ntoken = 0;
millis = System.currentTimeMillis(); millis = System.currentTimeMillis();
@@ -4150,44 +4141,56 @@ public class ImgDownloader {
if (System.currentTimeMillis() - millis > 10000) if (System.currentTimeMillis() - millis > 10000)
timeout = true; timeout = true;
} }
if (timeout) {
System.out.println("Warning: Problem downloading token: " + id + "t.jpg from, i will retry 1 time more...");
buftoken = new byte[1024];
ntoken = 0;
millis = System.currentTimeMillis();
timeout = false;
while (-1 != (ntoken = intoken.read(buftoken)) && !timeout) {
outtoken.write(buftoken, 0, ntoken);
if (System.currentTimeMillis() - millis > 10000)
timeout = true;
}
}
}
outtoken.close();
intoken.close();
if (timeout) {
System.err.println("Error: Problem downloading token: " + id + "t.jpg from, i will not retry anymore...");
continue;
}
byte[] responsetoken = outtoken.toByteArray();
String tokenimage = imgPath + File.separator + id + "t.jpg";
String tokenthumbimage = thumbPath + File.separator + id + "t.jpg";
FileOutputStream fos2 = new FileOutputStream(tokenimage);
fos2.write(responsetoken);
fos2.close();
try {
Bitmap yourBitmapToken = BitmapFactory.decodeFile(tokenimage);
Bitmap resizedToken = Bitmap.createScaledBitmap(yourBitmapToken, ImgX, ImgY, true);
if (Border > 0)
resizedToken = Bitmap.createBitmap(resizedToken, Border, Border, ImgX - 2 * Border, ImgY - 2 * Border);
FileOutputStream fout = new FileOutputStream(tokenimage);
resizedToken.compress(Bitmap.CompressFormat.JPEG, 100, fout);
fout.close();
} catch (Exception e) {
System.err.println("Error: Problem resizing token: " + id + "t.jpg, image may be corrupted...");
res = nametoken + " - " + set + File.separator + "thumbnails" + File.separator + id + "t.jpg\n" + res;
continue;
}
try {
Bitmap yourBitmapTokenthumb = BitmapFactory.decodeFile(tokenimage);
Bitmap resizedThumbToken = Bitmap.createScaledBitmap(yourBitmapTokenthumb, ThumbX, ThumbY, true);
if (BorderThumb > 0)
resizedThumbToken = Bitmap.createBitmap(resizedThumbToken, BorderThumb, BorderThumb, ThumbX - 2 * BorderThumb, ThumbY - 2 * BorderThumb);
FileOutputStream fout = new FileOutputStream(tokenthumbimage);
resizedThumbToken.compress(Bitmap.CompressFormat.JPEG, 100, fout);
fout.close();
} catch (Exception e) {
System.err.println("Error: Problem resizing token thumbnail: " + id + "t.jpg, image may be corrupted...");
res = nametoken + " - " + set + File.separator + "thumbnails" + File.separator + id + "t.jpg\n" + res;
} }
}
outtoken.close();
intoken.close();
if (timeout) {
System.err.println("Error: Problem downloading token: " + id + "t.jpg from, i will not retry anymore...");
break;
}
byte[] responsetoken = outtoken.toByteArray();
String tokenimage = imgPath + File.separator + id + "t.jpg";
String tokenthumbimage = thumbPath + File.separator + id + "t.jpg";
FileOutputStream fos2 = new FileOutputStream(tokenimage);
fos2.write(responsetoken);
fos2.close();
try {
Bitmap yourBitmapToken = BitmapFactory.decodeFile(tokenimage);
Bitmap resizedToken = Bitmap.createScaledBitmap(yourBitmapToken, ImgX, ImgY, true);
if (Border > 0)
resizedToken = Bitmap.createBitmap(resizedToken, Border, Border, ImgX - 2 * Border, ImgY - 2 * Border);
FileOutputStream fout = new FileOutputStream(tokenimage);
resizedToken.compress(Bitmap.CompressFormat.JPEG, 100, fout);
fout.close();
} catch (Exception e) {
System.err.println("Error: Problem resizing token: " + id + "t.jpg, image may be corrupted...");
res = nametoken + " - " + set + File.separator + "thumbnails" + File.separator + id + "t.jpg\n" + res;
break;
}
try {
Bitmap yourBitmapTokenthumb = BitmapFactory.decodeFile(tokenimage);
Bitmap resizedThumbToken = Bitmap.createScaledBitmap(yourBitmapTokenthumb, ThumbX, ThumbY, true);
if (BorderThumb > 0)
resizedThumbToken = Bitmap.createBitmap(resizedThumbToken, BorderThumb, BorderThumb, ThumbX - 2 * BorderThumb, ThumbY - 2 * BorderThumb);
FileOutputStream fout = new FileOutputStream(tokenthumbimage);
resizedThumbToken.compress(Bitmap.CompressFormat.JPEG, 100, fout);
fout.close();
} catch (Exception e) {
System.err.println("Error: Problem resizing token thumbnail: " + id + "t.jpg, image may be corrupted...");
res = nametoken + " - " + set + File.separator + "thumbnails" + File.separator + id + "t.jpg\n" + res;
} }
} }
} }
@@ -1,7 +1,7 @@
grade=borderline grade=borderline
#Bordeline Primitives Pack for Wagic the Homebrew. #Bordeline Primitives Pack for Wagic the Homebrew.
#Please keep these card alphabetized, and try to have the "name=" line at the top of each card #Please keep these card alphabetized, and try to have the "name=" line at the top of each card
#I sorted this programmatically - Thanks to Vitty85 19-06-2023 #I sorted this programmatically - Thanks to Vitty85 20-06-2023
[card] [card]
name=+2 Mace name=+2 Mace
auto={3}:equip auto={3}:equip
@@ -5925,6 +5925,21 @@ power=3
toughness=3 toughness=3
[/card] [/card]
[card] [card]
name=Azusa's Many Journeys
backside=Likeness of the Seeker
restriction=compare(isflipped)~equalto~0
anyzone={0}:doubleside(backside)
auto=counter(0/0,1,Lore)
auto=@each my firstmain:counter(0/0,1,Lore)
auto=transforms((,newability[maxPlay(land)+1])) ueot
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}<=2) life:3 controller
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )!
text=(As this Saga enters and after your draw step, add a lore counter.) -- I - You may play an additional land this turn. -- II - You gain 3 life. -- III - Exile this Saga, then return it to the battlefield transformed under your control.
mana={1}{G}
type=Enchantment
subtype=Saga
[/card]
[card]
name=Baba Lysaga, Night Witch name=Baba Lysaga, Night Witch
auto={T}{S(land|mybattlefield)}{S(creature|mybattlefield)}{S(artifact|mybattlefield)}:name(Sacrifice land, creature, artifact) life:-3 opponent && life:3 controller && draw:3 controller auto={T}{S(land|mybattlefield)}{S(creature|mybattlefield)}{S(artifact|mybattlefield)}:name(Sacrifice land, creature, artifact) life:-3 opponent && life:3 controller && draw:3 controller
auto={T}{S(land|mybattlefield)}{S(enchantment|mybattlefield)}{S(artifact|mybattlefield)}:name(Sacrifice land, enchantment, artifact) life:-3 opponent && life:3 controller && draw:3 controller auto={T}{S(land|mybattlefield)}{S(enchantment|mybattlefield)}{S(artifact|mybattlefield)}:name(Sacrifice land, enchantment, artifact) life:-3 opponent && life:3 controller && draw:3 controller
@@ -10740,6 +10755,21 @@ power=4
toughness=4 toughness=4
[/card] [/card]
[card] [card]
name=Boseiju Reaches Skyward
backside=Branch of Boseiju
restriction=compare(isflipped)~equalto~0
anyzone={0}:doubleside(backside)
auto=counter(0/0,1,Lore)
auto=@each my firstmain:counter(0/0,1,Lore)
auto=may name(Search 2 lands) target(<upto:2>forest[basic]|mylibrary) moveto(myhand) and!( shuffle )!
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}<=2) may name(Return land) target(land|mygraveyard) moveto(mylibrary)
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )!
text=(As this Saga enters and after your draw step, add a lore counter.) -- I - Search your library for up to two basic Forest cards, reveal them, put them into your hand, then shuffle. -- II - Put up to one target land card from your graveyard on top of your library. -- III - Exile this Saga, then return it to the battlefield transformed under your control.
mana={3}{G}
type=Enchantment
subtype=Saga
[/card]
[card]
name=Boseiju, Who Endures name=Boseiju, Who Endures
auto={T}:Add{G} auto={T}:Add{G}
autohand=this(variable{type:creature[legendary]:mybattlefield}=0) {1}{G}{discard}:name(Destroy artifact or enchantment) name(Destroy artifact or enchantment) destroy target(*[artifact;enchantment]|opponentbattlefield) && ability$!may name(Search basic land) name(Search basic land) target(land[basic]|mylibrary) moveto(mybattlefield) and!( shuffle )! !$ opponent autohand=this(variable{type:creature[legendary]:mybattlefield}=0) {1}{G}{discard}:name(Destroy artifact or enchantment) name(Destroy artifact or enchantment) destroy target(*[artifact;enchantment]|opponentbattlefield) && ability$!may name(Search basic land) name(Search basic land) target(land[basic]|mylibrary) moveto(mybattlefield) and!( shuffle )! !$ opponent
@@ -11066,6 +11096,17 @@ power=6
toughness=6 toughness=6
[/card] [/card]
[card] [card]
name=Branch of Boseiju
abilities=reach
auto=foreach(land|myBattlefield) 1/1
text=Reach -- Branch of Boseiju gets +1/+1 for each land you control.
color=green
type=Enchantment Creature
subtype=Plant
power=0
toughness=0
[/card]
[card]
name=Branchblight Stalker name=Branchblight Stalker
abilities=poisontwotoxic abilities=poisontwotoxic
text=Toxic 2 (Players dealt combat damage by this creature also get two poison counters.) text=Toxic 2 (Players dealt combat damage by this creature also get two poison counters.)
@@ -24438,6 +24479,17 @@ power=1
toughness=1 toughness=1
[/card] [/card]
[card] [card]
name=Dragon-Kami's Egg
auto=@movedTo(other dragon|graveyard) from(mybattlefield):may name(Cast exiled spell) target(*[counter{0/0.1.Hatching}]|myexile) activate castcard(normal)
auto=@movedTo(this|graveyard) from(mybattlefield):may name(Cast exiled spell) target(*[counter{0/0.1.Hatching}]|myexile) activate castcard(normal)
text=Whenever Dragon-Kami's Egg or a Dragon you control dies, you may cast a creature spell from among cards you own in exile with hatching counters on them without paying its mana cost.
color=green
type=Enchantment Creature
subtype=Egg
power=0
toughness=1
[/card]
[card]
name=Dragonborn Champion name=Dragonborn Champion
abilities=trample abilities=trample
auto=@damaged(player) from(*|myzones) restriction{compare(thatmuch)~morethan~4}:name(Draw card) draw:1 controller auto=@damaged(player) from(*|myzones) restriction{compare(thatmuch)~morethan~4}:name(Draw card) draw:1 controller
@@ -37226,6 +37278,17 @@ power=2
toughness=2 toughness=2
[/card] [/card]
[card] [card]
name=Go-Shintai of Boundless Vigor
abilities=trample
auto=@each my endofturn:may name(Pay 1 and put counters) pay({1}) name(Pay 1 and put counters) target(shrine|myBattlefield) counter(1/1,type:shrine:myBattlefield)
text=Trample -- At the beginning of your end step, you may pay {1}. When you do, put a +1/+1 counter on target Shrine for each Shrine you control.
mana={1}{G}
type=Legendary Enchantment Creature
subtype=Shrine
power=1
toughness=1
[/card]
[card]
name=Go-Shintai of Life's Origin name=Go-Shintai of Life's Origin
auto={W}{U}{B}{R}{G}{T}:target(enchantment|mygraveyard) moveTo(mybattlefield) auto={W}{U}{B}{R}{G}{T}:target(enchantment|mygraveyard) moveTo(mybattlefield)
auto=create(shrine:enchantment creature shrine:1/1) auto=create(shrine:enchantment creature shrine:1/1)
@@ -38877,6 +38940,16 @@ power=3
toughness=4 toughness=4
[/card] [/card]
[card] [card]
name=Greasefang, Okiba Boss
auto=@each my combatbegins:name(Return a vehicle) target(vehicle|mygraveyard) moveto(mybattlefield) and!( transforms((,newability[haste],newability[phaseaction[endofturn sourceinplay] moveTo(ownerhand)])) ueot )!
text=At the beginning of combat on your turn, return target Vehicle card from your graveyard to the battlefield. It gains haste. Return it to its owner's hand at the beginning of your next end step.
mana={1}{W}{B}
type=Legendary Creature
subtype=Rat Pilot
power=4
toughness=3
[/card]
[card]
name=Great Desert Prospector name=Great Desert Prospector
auto=name(Create powerstone) foreach(other creature|myBattlefield) token(Powerstone) and!( tap(noevent) )! auto=name(Create powerstone) foreach(other creature|myBattlefield) token(Powerstone) and!( tap(noevent) )!
text=When Great Desert Prospector enters the battlefield, create a tapped Powerstone token for each other creature you control. (The tokens are artifacts with "{T}: Add {C}. This mana can't be spent to cast a nonartifact spell.") text=When Great Desert Prospector enters the battlefield, create a tapped Powerstone token for each other creature you control. (The tokens are artifacts with "{T}: Add {C}. This mana can't be spent to cast a nonartifact spell.")
@@ -41625,6 +41698,16 @@ mana={R}
type=Instant type=Instant
[/card] [/card]
[card] [card]
name=Heir of the Ancient Fang
auto=if type(creature[modified]|myBattlefield)~morethan~0 then name(Put 1/1 counter) name(Put 1/1 counter) counter(1/1)
text=Heir of the Ancient Fang enters the battlefield with a +1/+1 counter on it if you control a modified creature. (Equipment, Auras you control, and counters are modifications.)
mana={2}{G}
type=Creature
subtype=Snake Samurai
power=2
toughness=3
[/card]
[card]
name=Heirloom Blade name=Heirloom Blade
auto=teach(creature) 3/1 auto=teach(creature) 3/1
auto=teach(creature) transforms((,newability[@movedto(mygraveyard) from(this|mybattlefield):Reveal:1 revealzone(mylibrary) revealuntil(*[creature;share!types!]|mylibrary) optionone name(Get Creature) target(creature|myreveal) moveto(myHand) optiononeend optiontwo choice name(Shuffle) all(*|myreveal) bottomoflibrary && shuffle controller optiontwoend revealend])) auto=teach(creature) transforms((,newability[@movedto(mygraveyard) from(this|mybattlefield):Reveal:1 revealzone(mylibrary) revealuntil(*[creature;share!types!]|mylibrary) optionone name(Get Creature) target(creature|myreveal) moveto(myHand) optiononeend optiontwo choice name(Shuffle) all(*|myreveal) bottomoflibrary && shuffle controller optiontwoend revealend]))
@@ -43558,6 +43641,16 @@ mana={2}{G}{G}
type=Enchantment type=Enchantment
[/card] [/card]
[card] [card]
name=Human Monk
auto={T}:name(Add green) add{G}
text={T}: Add {G}.
color=green
type=Creature
subtype=Human Monk
power=1
toughness=1
[/card]
[card]
name=Human Soldier Bas name=Human Soldier Bas
type=Creature type=Creature
subtype=Human Soldier subtype=Human Soldier
@@ -47122,6 +47215,13 @@ mana={1}{B}{B}{B}{B}
type=Sorcery type=Sorcery
[/card] [/card]
[card] [card]
name=Invoke the Ancients
auto=token(Spirit,Creature Spirit,4/5,green)*2 and!( transforms((,newability[this(counter{0/0.1.Vigilance}>=1) vigilance],newability[this(counter{0/0.1.Reach}>=1) reach],newability[this(counter{0/0.1.Trample}>=1) trample],newability[choice name(Vigilance counter) counter(0/0.1.Vigilance)],newability[choice name(Reach counter) counter(0/0.1.Reach)],newability[choice name(Trample counter) counter(0/0.1.Trample)])) forever )!
text=Create two 4/5 green Spirit creature tokens. For each of them, put your choice of a vigilance counter, a reach counter, or a trample counter on it.
mana={1}{G}{G}{G}{G}
type=Sorcery
[/card]
[card]
name=Invoke the Divine name=Invoke the Divine
target=artifact,enchantment target=artifact,enchantment
auto=destroy auto=destroy
@@ -48607,6 +48707,21 @@ power=2
toughness=2 toughness=2
[/card] [/card]
[card] [card]
name=Jugan Defends the Temple
backside=Remnant of the Rising Star
restriction=compare(isflipped)~equalto~0
anyzone={0}:doubleside(backside)
auto=counter(0/0,1,Lore)
auto=@each my firstmain:counter(0/0,1,Lore)
auto=token(Human Monk)
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}<=2) may name(Put 1/1 counter) target(<upto:2>creature|battlefield) counter(1/1)
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )!
text=(As this Saga enters and after your draw step, add a lore counter.) -- I - Create a 1/1 green Human Monk creature token with "{T}: Add {G}." -- II - Put a +1/+1 counter on each of up to two target creatures. -- III - Exile this Saga, then return it to the battlefield transformed under your control.
mana={2}{G}
type=Enchantment
subtype=Saga
[/card]
[card]
name=Jukai Naturalist name=Jukai Naturalist
auto=lord(Enchantment|mycastingzone) altercost(colorless,-1) auto=lord(Enchantment|mycastingzone) altercost(colorless,-1)
text=Lifelink -- Enchantment spells you cast cost {1} less to cast. text=Lifelink -- Enchantment spells you cast cost {1} less to cast.
@@ -50572,6 +50687,16 @@ power=2
toughness=2 toughness=2
[/card] [/card]
[card] [card]
name=Kirin-Touched Orochi
auto=_ATTACKING_name(Choose one) transforms((,newability[if type(creature|graveyard)~morethan~0 then choice name(Exile creature) name(Exile creature) target(creature|graveyard) moveto(exile) and!( token(Spirit^Creature Spirit^1/1) )!],newability[if type(*[-creature]|graveyard)~morethan~0 then choice name(Exile noncreature card) name(Exile noncreature card) target(*[-creature]|graveyard) moveto(exile) and!( ability$!name(Put 1/1 counter) target(creature|mybattlefield) counter(1/1)!$ controller )!])) oneshot
text=Whenever Kirin-Touched Orochi attacks, choose one -- Exile target creature card from a graveyard. When you do, create a 1/1 colorless Spirit creature token. -- Exile target noncreature card from a graveyard. When you do, put a +1/+1 counter on target creature you control.
color=green
type=Enchantment Creature
subtype=Snake Monk
power=1
toughness=1
[/card]
[card]
name=Kitchen Imp name=Kitchen Imp
abilities=madness,flying,haste abilities=madness,flying,haste
autoexile=restriction{discarded} pay({B}) name(pay B to cast) activate name(pay B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard) autoexile=restriction{discarded} pay({B}) name(pay B to cast) activate name(pay B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard)
@@ -51613,7 +51738,7 @@ auto=@each my firstmain:counter(0/0,1,Lore)
auto=name(Damage opponent) damage:1 opponent auto=name(Damage opponent) damage:1 opponent
auto=name(Damage opponent's planeswalker) damage:1 all(planeswalker|opponentbattlefield) auto=name(Damage opponent's planeswalker) damage:1 all(planeswalker|opponentbattlefield)
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}=) name(Next creature gains 1/1 counter) name(Next creature gains 1/1 counter) emblem transforms((,newability[@movedto(creature|mybattlefield) from(mystack) turnlimited:name(Get 1/1 counter) name(Get 1/1 counter) all(trigger[to]) counter(1/1)])) ueot auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}=) name(Next creature gains 1/1 counter) name(Next creature gains 1/1 counter) emblem transforms((,newability[@movedto(creature|mybattlefield) from(mystack) turnlimited:name(Get 1/1 counter) name(Get 1/1 counter) all(trigger[to]) counter(1/1)])) ueot
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )! asSorcery auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )!
text=(As this Saga enters and after your draw step, add a lore counter.) -- I - Kumano Faces Kakkazan deals 1 damage to each opponent and each planeswalker they control. -- II - When you cast your next creature spell this turn, that creature enters the battlefield with an additional +1/+1 counter on it. -- III - Exile this Saga, then return it to the battlefield transformed under your control. text=(As this Saga enters and after your draw step, add a lore counter.) -- I - Kumano Faces Kakkazan deals 1 damage to each opponent and each planeswalker they control. -- II - When you cast your next creature spell this turn, that creature enters the battlefield with an additional +1/+1 counter on it. -- III - Exile this Saga, then return it to the battlefield transformed under your control.
mana={R} mana={R}
type=Enchantment type=Enchantment
@@ -51696,6 +51821,17 @@ power=3
toughness=3 toughness=3
[/card] [/card]
[card] [card]
name=Kura, the Boundless Sky
abilities=deathtouch,flying
auto=_DIES_name(Choose one) transforms((,newability[choice name(Search 3 lands) target(<upto:3>land|mylibrary) moveto(myhand) and!( shuffle )!],newability[choice name(Create spirit) token(Spirit^Creature Spirit^type:land:mybattlefield/type:land:mybattlefield^green)])) oneshot
text=Flying, deathtouch -- When Kura, the Boundless Sky dies, choose one -- Search your library for up to three land cards, reveal them, put them into your hand, then shuffle. -- Create an X/X green Spirit creature token, where X is the number of lands you control.
mana={3}{G}{G}
type=Legendary Creature
subtype=Dragon Spirit
power=4
toughness=4
[/card]
[card]
name=Kurbis, Harvest Celebrant name=Kurbis, Harvest Celebrant
auto=if compare(ishuman)~equalto~1 then counter(1/1,totmanaspent) auto=if compare(ishuman)~equalto~1 then counter(1/1,totmanaspent)
auto=if compare(ishuman)~equalto~0 then counter(1/1,fullpaidplus2plusend) auto=if compare(ishuman)~equalto~0 then counter(1/1,fullpaidplus2plusend)
@@ -53197,7 +53333,7 @@ auto=counter(0/0,1,Lore)
auto=@each my firstmain:counter(0/0,1,Lore) auto=@each my firstmain:counter(0/0,1,Lore)
auto=transforms((,newability[if type(creature|battlefield)~morethan~0 then choice name(Creature gets 2/2) name(Creature gets 2/2) target(creature|battlefield) 2/2 ueot],newability[if type(creature|battlefield)~morethan~0 then choice name(Creature gets -1/-1) name(Creature gets -1/-1) target(creature|battlefield) -1/-1 ueot],newability[choice name(Gain 2 life) life:2 controller])) oneshot auto=transforms((,newability[if type(creature|battlefield)~morethan~0 then choice name(Creature gets 2/2) name(Creature gets 2/2) target(creature|battlefield) 2/2 ueot],newability[if type(creature|battlefield)~morethan~0 then choice name(Creature gets -1/-1) name(Creature gets -1/-1) target(creature|battlefield) -1/-1 ueot],newability[choice name(Gain 2 life) life:2 controller])) oneshot
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}=) transforms((,newability[if type(creature|battlefield)~morethan~0 then choice name(Creature gets 2/2) name(Creature gets 2/2) target(creature|battlefield) 2/2 ueot],newability[if type(creature|battlefield)~morethan~0 then choice name(Creature gets -1/-1) name(Creature gets -1/-1) target(creature|battlefield) -1/-1 ueot],newability[choice name(Gain 2 life) life:2 controller])) oneshot auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}=) transforms((,newability[if type(creature|battlefield)~morethan~0 then choice name(Creature gets 2/2) name(Creature gets 2/2) target(creature|battlefield) 2/2 ueot],newability[if type(creature|battlefield)~morethan~0 then choice name(Creature gets -1/-1) name(Creature gets -1/-1) target(creature|battlefield) -1/-1 ueot],newability[choice name(Gain 2 life) life:2 controller])) oneshot
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )! asSorcery auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )!
text=(As this Saga enters and after your draw step, add a lore counter.) -- I, II - Choose one -- Target creature gets +2/+2 until end of turn. -- Target creature gets -1/-1 until end of turn. -- You gain 2 life. -- III - Exile this Saga, then return it to the battlefield transformed under your control. text=(As this Saga enters and after your draw step, add a lore counter.) -- I, II - Choose one -- Target creature gets +2/+2 until end of turn. -- Target creature gets -1/-1 until end of turn. -- You gain 2 life. -- III - Exile this Saga, then return it to the battlefield transformed under your control.
mana={1}{B} mana={1}{B}
type=Enchantment type=Enchantment
@@ -53451,6 +53587,16 @@ type=Tribal Enchantment
subtype=Treefolk Aura subtype=Treefolk Aura
[/card] [/card]
[card] [card]
name=Likeness of the Seeker
auto=@combat(blocked) source(this):may name(Untap 3 lands) target(<upto:3>land[tapped]|myBattlefield) untap
text=Whenever Likeness of the Seeker becomes blocked, untap up to three lands you control.
color=green
type=Enchantment Creature
subtype=Human Monk
power=3
toughness=3
[/card]
[card]
name=Liliana's Contract name=Liliana's Contract
auto=life:-4 controller auto=life:-4 controller
auto=draw:4 controller auto=draw:4 controller
@@ -57105,6 +57251,15 @@ mana={2}{B}
type=Sorcery type=Sorcery
[/card] [/card]
[card] [card]
name=Memory Theft
aicode=activate transforms((,newability[reject notatarget(*[-land]|opponenthand)],newability[ability$!name(Put adventure in graveyard) moveTo(opponentgraveyard) target(*[adventure]|opponentexile)!$ controller])) oneshot
auto=if type(*[adventure]|opponentexile)~morethan~0 then choice name(Put adventure in graveyard) name(Put adventure in graveyard) reveal:type:*:opponenthand revealzone(opponenthand) optionone name(choose non-land card) target(*[-land]|reveal) reject optiononeend optiontwo name(put back) target(*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend afterrevealed name(Choose adventure from exile) moveTo(opponentgraveyard) target(*[adventure]|opponentexile) afterrevealedend revealend
auto=choice name(Don't put adventure in graveyard) reveal:type:*:opponenthand revealzone(opponenthand) optionone name(choose non-land card) target(*[-land]|reveal) reject optiononeend optiontwo name(put back) target(*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend
text=Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. You may put a card that has an Adventure that player owns from exile into that player's graveyard.
mana={2}{B}
type=Sorcery
[/card]
[card]
name=Memory of Toshiro name=Memory of Toshiro
auto=this(variable{type:*[instant;sorcery]:myrestrictedcastingzone}>0) {T}{L:1}:name(Add mana) name(Add mana) add{B} auto=this(variable{type:*[instant;sorcery]:myrestrictedcastingzone}>0) {T}{L:1}:name(Add mana) name(Add mana) add{B}
text={T}, Pay 1 life: Add {B}. Spend this mana only to cast an instant or sorcery spell. text={T}, Pay 1 life: Add {B}. Spend this mana only to cast an instant or sorcery spell.
@@ -57115,15 +57270,6 @@ power=2
toughness=3 toughness=3
[/card] [/card]
[card] [card]
name=Memory Theft
aicode=activate transforms((,newability[reject notatarget(*[-land]|opponenthand)],newability[ability$!name(Put adventure in graveyard) moveTo(opponentgraveyard) target(*[adventure]|opponentexile)!$ controller])) oneshot
auto=if type(*[adventure]|opponentexile)~morethan~0 then choice name(Put adventure in graveyard) name(Put adventure in graveyard) reveal:type:*:opponenthand revealzone(opponenthand) optionone name(choose non-land card) target(*[-land]|reveal) reject optiononeend optiontwo name(put back) target(*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend afterrevealed name(Choose adventure from exile) moveTo(opponentgraveyard) target(*[adventure]|opponentexile) afterrevealedend revealend
auto=choice name(Don't put adventure in graveyard) reveal:type:*:opponenthand revealzone(opponenthand) optionone name(choose non-land card) target(*[-land]|reveal) reject optiononeend optiontwo name(put back) target(*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend
text=Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. You may put a card that has an Adventure that player owns from exile into that player's graveyard.
mana={2}{B}
type=Sorcery
[/card]
[card]
name=Menagerie Liberator name=Menagerie Liberator
abilities=trample abilities=trample
auto=_ATTACKING_1/1 ueot auto=_ATTACKING_1/1 ueot
@@ -64988,6 +65134,16 @@ power=0
toughness=2 toughness=2
[/card] [/card]
[card] [card]
name=Orochi Merge-Keeper
auto=this(cantargetcard(*[modified]) {T}:Add{G}{G}
text={T}: Add {G}. -- As long as Orochi Merge-Keeper is modified, it has "{T}: Add {G}{G}." (Equipment, Auras you control, and counters are modifications.)
mana={1}{G}
type=Creature
subtype=Snake Druid
power=1
toughness=1
[/card]
[card]
name=Orthion, Hero of Lavabrink name=Orthion, Hero of Lavabrink
auto={1}{R}{T}:clone with(treason,haste) target(other creature|mybattlefield) asSorcery auto={1}{R}{T}:clone with(treason,haste) target(other creature|mybattlefield) asSorcery
auto={6}{R}{R}{R}{T}:name(Create five tokens) target(other creature|mybattlefield) transforms((,newability[clone with(treason^haste)],newability[clone with(treason^haste)],newability[clone with(treason^haste)],newability[clone with(treason^haste)],newability[clone with(treason^haste)])) asSorcery auto={6}{R}{R}{R}{T}:name(Create five tokens) target(other creature|mybattlefield) transforms((,newability[clone with(treason^haste)],newability[clone with(treason^haste)],newability[clone with(treason^haste)],newability[clone with(treason^haste)],newability[clone with(treason^haste)])) asSorcery
@@ -72753,14 +72909,6 @@ power=2
toughness=3 toughness=3
[/card] [/card]
[card] [card]
name=Reckoner's Bargain
auto=life:storedmanacost
auto=draw:2
text=As an additional cost to cast this spell, sacrifice an artifact or creature. -- You gain life equal to the sacrificed permanent's mana value. Draw two cards.
mana={1}{B}{S(*[creature;artifact]|myBattlefield)}
type=Instant
[/card]
[card]
name=Reckoner Shakedown name=Reckoner Shakedown
auto=if type(*[-land]|opponenthand)~morethan~0 then name(Look opponent hand) name(Look opponent hand) target(*[-land]|opponenthand) moveto(myhand) and!( transforms((,newability[choice name(Discard card) moveto(opponenthand) and!( reject )!],newability[choice name(Don't discard) moveto(opponenthand) and!( name(Put 1/1 counters) target(*[creature;vehicle]|mybattlefield) counter(1/1.2) )!])) ueot )! auto=if type(*[-land]|opponenthand)~morethan~0 then name(Look opponent hand) name(Look opponent hand) target(*[-land]|opponenthand) moveto(myhand) and!( transforms((,newability[choice name(Discard card) moveto(opponenthand) and!( reject )!],newability[choice name(Don't discard) moveto(opponenthand) and!( name(Put 1/1 counters) target(*[creature;vehicle]|mybattlefield) counter(1/1.2) )!])) ueot )!
auto=if type(*|opponenthand)~morethan~0 then if type(*[-land]|opponenthand)~equalto~0 then name(Look opponent hand) name(Look opponent hand) name(Look opponent hand) target(*|opponenthand) moveto(myhand) and!( transforms((,newability[moveto(opponenthand) and!( name(Put 1/1 counters) target(*[creature;vehicle]|mybattlefield) counter(1/1.2) )!])) ueot )! auto=if type(*|opponenthand)~morethan~0 then if type(*[-land]|opponenthand)~equalto~0 then name(Look opponent hand) name(Look opponent hand) name(Look opponent hand) target(*|opponenthand) moveto(myhand) and!( transforms((,newability[moveto(opponenthand) and!( name(Put 1/1 counters) target(*[creature;vehicle]|mybattlefield) counter(1/1.2) )!])) ueot )!
@@ -72770,6 +72918,14 @@ mana={2}{B}
type=Sorcery type=Sorcery
[/card] [/card]
[card] [card]
name=Reckoner's Bargain
auto=life:storedmanacost
auto=draw:2
text=As an additional cost to cast this spell, sacrifice an artifact or creature. -- You gain life equal to the sacrificed permanent's mana value. Draw two cards.
mana={1}{B}{S(*[creature;artifact]|myBattlefield)}
type=Instant
[/card]
[card]
name=Reclaim the Wastes name=Reclaim the Wastes
aicode=activate target(<upto:2>land[basic]|myLibrary) moveTo(myHand) aicode=activate target(<upto:2>land[basic]|myLibrary) moveTo(myHand)
kicker={3} kicker={3}
@@ -73446,6 +73602,19 @@ mana={2}{W}
type=Sorcery type=Sorcery
[/card] [/card]
[card] [card]
name=Remnant of the Rising Star
abilities=flying
auto=@movedTo(other creature|myBattlefield):name(Pay X and put counters) all(trigger[to]) name(Pay X and put counters) transforms((,newability[may name(Pay X and put counters) pay({x}) name(Pay X and put counters) counter(1/1.X)])) forever
auto=aslongas(creature[modified]|myBattlefield) 5/5 >4
auto=aslongas(creature[modified]|myBattlefield) trample >4
text=Flying -- Whenever another creature enters the battlefield under your control, you may pay {X}. When you do, put X +1/+1 counters on that creature. -- As long as you control five or more modified creatures, Remnant of the Rising Star gets +5/+5 and has trample. (Equipment, Auras you control, and counters are modifications.)
color=green
type=Enchantment Creature
subtype=Dragon Spirit
power=2
toughness=2
[/card]
[card]
name=Remorseful Cleric name=Remorseful Cleric
abilities=flying abilities=flying
auto={S}:choice name(Exile cards in graveyard) moveTo(exile) all(*|targetedpersonsgraveyard) target(player) auto={S}:choice name(Exile cards in graveyard) moveTo(exile) all(*|targetedpersonsgraveyard) target(player)
@@ -84783,6 +84952,16 @@ power=4
toughness=4 toughness=4
[/card] [/card]
[card] [card]
name=Sokenzan Smelter
auto=@each my combatbegins:may name(Pay 1 and create construct) pay({1}) name(Pay 1 and create construct) token(Construct Artifact,Creature Artifact Construct,3/1,red,haste)
text=At the beginning of combat on your turn, you may pay {1} and sacrifice an artifact. If you do, create a 3/1 red Construct artifact creature token with haste.
mana={1}{R}
type=Creature
subtype=Goblin Artificer
power=2
toughness=2
[/card]
[card]
name=Sokenzan, Crucible of Defiance name=Sokenzan, Crucible of Defiance
auto={T}:Add{R} auto={T}:Add{R}
autohand=this(variable{type:creature[legendary]:mybattlefield}=0) {3}{R}{discard}:name(Create Spirits) name(Create Spirits) token(Spirit,Creature Spirit,1/1)*2 and!( transforms((,newability[haste])) ueot )! autohand=this(variable{type:creature[legendary]:mybattlefield}=0) {3}{R}{discard}:name(Create Spirits) name(Create Spirits) token(Spirit,Creature Spirit,1/1)*2 and!( transforms((,newability[haste])) ueot )!
@@ -86624,6 +86803,14 @@ mana={3}
type=Artifact type=Artifact
[/card] [/card]
[card] [card]
name=Spinning Wheel Kick
target=creature|myBattlefield
auto=name(Deal power damage) damage:power target(<halfpaid>*[creature;planeswalker]|battlefield)
text=Target creature you control deals damage equal to its power to each of X target creatures and/or planeswalkers.
mana={X}{X}{G}{G}
type=Sorcery
[/card]
[card]
name=Spiny Starfish name=Spiny Starfish
auto={U}:regenerate && token(Starfish,Creature Starfish,0/1,blue) auto={U}:regenerate && token(Starfish,Creature Starfish,0/1,blue)
text={U}: Regenerate Spiny Starfish. -- At the beginning of each end step, if Spiny Starfish regenerated this turn, put a 0/1 blue Starfish creature token onto the battlefield for each time it regenerated this turn. text={U}: Regenerate Spiny Starfish. -- At the beginning of each end step, if Spiny Starfish regenerated this turn, put a 0/1 blue Starfish creature token onto the battlefield for each time it regenerated this turn.
@@ -91786,6 +91973,22 @@ type=Sorcery
subtype=Lesson subtype=Lesson
[/card] [/card]
[card] [card]
name=Teachings of the Kirin
backside=Kirin-Touched Orochi
restriction=compare(isflipped)~equalto~0
anyzone={0}:doubleside(backside)
auto=counter(0/0,1,Lore)
auto=@each my firstmain:counter(0/0,1,Lore)
auto=deplete:3 controller
auto=token(Spirit,Creature Spirit,1/1)
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}<=2) name(Put 1/1 counter) target(creature|mybattlefield) counter(1/1)
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )!
text=(As this Saga enters and after your draw step, add a lore counter.) -- I - Mill three cards. Create a 1/1 colorless Spirit creature token. -- II - Put a +1/+1 counter on target creature you control. -- III - Exile this Saga, then return it to the battlefield transformed under your control.
mana={1}{G}
type=Enchantment
subtype=Saga
[/card]
[card]
name=Team Pennant name=Team Pennant
auto=name(Equip creature token) {1}:rehook target(creature[token]|mybattlefield) asSorcery auto=name(Equip creature token) {1}:rehook target(creature[token]|mybattlefield) asSorcery
auto={3}:equip auto={3}:equip
@@ -93013,6 +93216,24 @@ mana={5}
type=Legendary Artifact type=Legendary Artifact
[/card] [/card]
[card] [card]
name=The Dragon-Kami Reborn
backside=Dragon-Kami's Egg
restriction=compare(isflipped)~equalto~0
anyzone={0}:doubleside(backside)
aicode=activate transforms((,newability[target(*[zpos<=3]|mylibrary) moveto(myexile) and!( transforms((,newability[counter(0/0.1.Hatching)],newability[all(*[zpos<=3]|mylibrary) moveto(myreveal) and!( bottomoflibrary )!])) forever )! ])) oneshot
auto=counter(0/0,1,Lore)
auto=@each my firstmain:counter(0/0,1,Lore)
auto=life:2 controller
auto=name(Look top 3 cards) reveal:3 optionone name(Exile a card) target(*|reveal) moveto(myexile) and!( counter(0/0.1.Hatching) )! optiononeend optiontwo name(Put on bottom) target(<2>*|reveal) bottomoflibrary optiontwoend revealend
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}<=2) name(Gain 2 life) name(Gain 2 life) life:2 controller
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}<=2) name(Look top 3 cards) name(Look top 3 cards) reveal:3 optionone name(Exile a card) target(*|reveal) moveto(myexile) and!( counter(0/0.1.Hatching) )! optiononeend optiontwo name(Put on bottom) target(<2>*|reveal) bottomoflibrary optiontwoend revealend
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )!
text=(As this Saga enters and after your draw step, add a lore counter.) -- I, II - You gain 2 life. Look at the top three cards of your library. Exile one of them face down with a hatching counter on it, then put the rest on the bottom of your library in any order. -- III - Exile this Saga, then return it to the battlefield transformed under your control.
mana={2}{G}
type=Enchantment
subtype=Saga
[/card]
[card]
name=The Dross Pits name=The Dross Pits
auto=tap(noevent) auto=tap(noevent)
auto={T}:Add{B} auto={T}:Add{B}
@@ -93286,7 +93507,7 @@ auto=counter(0/0,1,Lore)
auto=@each my firstmain:counter(0/0,1,Lore) auto=@each my firstmain:counter(0/0,1,Lore)
auto=ability$!name(Choose a creature) name(Choose a creature) target(creature|mybattlefield) transforms((,newability[choice name(Sacrifice) sacrifice],newability[if type(*|myhand)~morethan~0 then choice name(Discard a card) name(Discard a card) reject notatarget(*|myhand)])) ueot!$ opponent auto=ability$!name(Choose a creature) name(Choose a creature) target(creature|mybattlefield) transforms((,newability[choice name(Sacrifice) sacrifice],newability[if type(*|myhand)~morethan~0 then choice name(Discard a card) name(Discard a card) reject notatarget(*|myhand)])) ueot!$ opponent
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}=) ability$!name(Choose a creature) name(Choose a creature) target(creature|mybattlefield) transforms((,newability[choice name(Sacrifice) sacrifice],newability[if type(*|myhand)~morethan~0 then choice name(Discard a card) name(Discard a card) reject notatarget(*|myhand)])) ueot!$ opponent auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}=) ability$!name(Choose a creature) name(Choose a creature) target(creature|mybattlefield) transforms((,newability[choice name(Sacrifice) sacrifice],newability[if type(*|myhand)~morethan~0 then choice name(Discard a card) name(Discard a card) reject notatarget(*|myhand)])) ueot!$ opponent
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )! asSorcery auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )!
text=(As this Saga enters and after your draw step, add a lore counter.) -- I, II - Each opponent sacrifices a creature unless they discard a card. -- III - Exile this Saga, then return it to the battlefield transformed under your control. text=(As this Saga enters and after your draw step, add a lore counter.) -- I, II - Each opponent sacrifices a creature unless they discard a card. -- III - Exile this Saga, then return it to the battlefield transformed under your control.
mana={3}{B} mana={3}{B}
type=Enchantment type=Enchantment
@@ -96443,6 +96664,17 @@ type=Enchantment
subtype=Aura subtype=Aura
[/card] [/card]
[card] [card]
name=Treasure
auto={T}{S}:add{W}
auto={T}{S}:add{U}
auto={T}{S}:add{B}
auto={T}{S}:add{R}
auto={T}{S}:add{G}
text={T}, Sacrifice this artifact: Add one mana of any color.
type=Artifact
subtype=Treasure
[/card]
[card]
name=Treasure Chest name=Treasure Chest
auto={4}:name(Roll a d20) rolld20 20 winability donothing winabilityend rolld20end auto={4}:name(Roll a d20) rolld20 20 winability donothing winabilityend rolld20end
auto=@dierolled(this) from(controller):all(this) sacrifice auto=@dierolled(this) from(controller):all(this) sacrifice
@@ -96498,17 +96730,6 @@ power=3
toughness=2 toughness=2
[/card] [/card]
[card] [card]
name=Treasure
auto={T}{S}:add{W}
auto={T}{S}:add{U}
auto={T}{S}:add{B}
auto={T}{S}:add{R}
auto={T}{S}:add{G}
text={T}, Sacrifice this artifact: Add one mana of any color.
type=Artifact
subtype=Treasure
[/card]
[card]
name=Treasure Vault name=Treasure Vault
auto={T}:Add{C} auto={T}:Add{C}
auto={X}{X}{T}{S}:name(Create treasures) token(Treasure)*xx auto={X}{X}{T}{S}:name(Create treasures) token(Treasure)*xx
@@ -96679,7 +96900,7 @@ auto=counter(0/0,1,Lore)
auto=@each my firstmain:counter(0/0,1,Lore) auto=@each my firstmain:counter(0/0,1,Lore)
auto=name(Create a rat) token(Rat Rogue,Creature Rat Rogue,1/1,black) opponent auto=name(Create a rat) token(Rat Rogue,Creature Rat Rogue,1/1,black) opponent
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}=) name(Create a rat) token(Rat Rogue,Creature Rat Rogue,1/1,black) opponent auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}=) name(Create a rat) token(Rat Rogue,Creature Rat Rogue,1/1,black) opponent
auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )! asSorcery auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) moveto(exile) and!( flip(backside) forcetype(Enchantment Creature) )!
text=(As this Saga enters and after your draw step, add a lore counter.) -- I, II - Each opponent creates a 1/1 black Rat Rogue creature token. -- III - Exile this Saga, then return it to the battlefield transformed under your control. text=(As this Saga enters and after your draw step, add a lore counter.) -- I, II - Each opponent creates a 1/1 black Rat Rogue creature token. -- III - Exile this Saga, then return it to the battlefield transformed under your control.
mana={1}{B} mana={1}{B}
type=Enchantment type=Enchantment
@@ -98598,6 +98819,16 @@ mana={2}{U}
type=Instant type=Instant
[/card] [/card]
[card] [card]
name=Upriser Renegade
auto=foreach(other creature[modified]|myBattlefield) 2/0
text=Upriser Renegade gets +2/+0 for each other modified creature you control. (Equipment, Auras you control, and counters are modifications.)
mana={1}{R}
type=Creature
subtype=Human Samurai
power=1
toughness=3
[/card]
[card]
name=Urabrask name=Urabrask
abilities=first strike abilities=first strike
backside=The Great Work backside=The Great Work
+3 -2
View File
@@ -1,6 +1,6 @@
#Primitives Pack for Wagic the Homebrew. #Primitives Pack for Wagic the Homebrew.
#Please keep these card alphabetized, and try to have the "name=" line at the top of each card #Please keep these card alphabetized, and try to have the "name=" line at the top of each card
#I sorted this programmatically so the other comments are removed except for AUTO_DEFINE - Vitty85 18-06-2023 #I sorted this programmatically so the other comments are removed except for AUTO_DEFINE - Vitty85 20-06-2023
[card] [card]
name=Abandon Reason name=Abandon Reason
target=<upto:2>creature target=<upto:2>creature
@@ -45274,8 +45274,9 @@ toughness=0
[/card] [/card]
[card] [card]
name=Genesis Wave name=Genesis Wave
aicode=activate transforms((,newability[all(*[manacost>=fullpaidplus1plusend&zpos<=fullpaid]|myLibrary) moveto(mygraveyard)],newability[all(*[manacost<=fullpaid&zpos<=fullpaid]|myLibrary) moveto(myreveal) and!( transforms((,newability[if cantargetcard(*[-instant&-sorcery]|*) then moveto(myBattlefield) else moveto(mygraveyard)])) oneshot )!])) oneshot
auto=name(Reveal X cards) reveal:X optionone name(Get any permanent) target(<anyamount>*[manacost<=x&-instant&-sorcery]|reveal) moveto(mybattlefield) optiononeend optiontwo choice name(Discard the rest) all(*|reveal) moveto(mygraveyard) optiontwoend revealend
mana={X}{G}{G}{G} mana={X}{G}{G}{G}
auto=name(Reveal X cards) reveal:X optionone name(Get Any Cards) target(<anyamount>*[manacost<=x]|reveal) moveto(mybattlefield) optiononeend optiontwo choice name(Discard the rest) all(*|reveal) moveto(mygraveyard) optiontwoend revealend
type=Sorcery type=Sorcery
text=Reveal the top X cards of your library. You may put any number of permanent cards with mana value X or less from among them onto the battlefield. Then put all cards revealed this way that weren't put onto the battlefield into your graveyard. text=Reveal the top X cards of your library. You may put any number of permanent cards with mana value X or less from among them onto the battlefield. Then put all cards revealed this way that weren't put onto the battlefield into your graveyard.
[/card] [/card]
+2 -2
View File
@@ -1609,9 +1609,9 @@ vector<MTGAbility*> AIPlayerBaka::canPayMana(MTGCardInstance * target, ManaCost
AManaProducer * amp = dynamic_cast<AManaProducer*> (a); AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if(amp && (amp->getCost() && amp->getCost()->extraCosts && !amp->getCost()->extraCosts->canPay())) if(amp && (amp->getCost() && amp->getCost()->extraCosts && !amp->getCost()->extraCosts->canPay()))
continue; continue;
if(fullColor == needColorConverted && result->getConvertedCost() < cost->getConvertedCost()) if((fullColor == needColorConverted || cost->hasColor(0) || cost->hasColor(7)) && result->getConvertedCost() < cost->getConvertedCost()) // Fixed a bug on colorless mana calculation for AI.
{ {
if(cost->hasColor(0) && amp)//find colorless after color mana. if((cost->hasColor(0) || cost->hasColor(7)) && amp)//find colorless after color mana.
{ {
if(result->canAfford(cost,0)) if(result->canAfford(cost,0))
continue; continue;
+31 -5
View File
@@ -10086,6 +10086,12 @@ int AACastCard::resolveSpell()
{ {
if (putinplay && theNamedCard->isPermanent()) if (putinplay && theNamedCard->isPermanent())
copy = theNamedCard->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with double activation of card abilities. copy = theNamedCard->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with double activation of card abilities.
else if (asCopy && theNamedCard->isPermanent()){
theNamedCard->isToken = 0; // Fixed a bug when using copied option with namedcard option.
copy = _target->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->stack, noEvent);
copy->isToken = 1; // Fixed a bug when using copied option with namedcard option.
copy = _target->controller()->game->putInZone(copy, copy->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with copied option for permanent.
}
else else
copy = theNamedCard->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->stack, noEvent); // Fixed a bug when using noevent option with namedcard option. copy = theNamedCard->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->stack, noEvent); // Fixed a bug when using noevent option with namedcard option.
} }
@@ -10093,6 +10099,12 @@ int AACastCard::resolveSpell()
{ {
if (putinplay && theNamedCard->isPermanent()) if (putinplay && theNamedCard->isPermanent())
copy = theNamedCard->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with double activation of card abilities. copy = theNamedCard->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with double activation of card abilities.
else if (asCopy && theNamedCard->isPermanent()){
theNamedCard->isToken = 0; // Fixed a bug when using copied option with namedcard option.
copy = _target->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->stack, noEvent);
copy->isToken = 1; // Fixed a bug when using copied option with namedcard option.
copy = _target->controller()->game->putInZone(copy, copy->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with copied option for permanent.
}
else else
copy = theNamedCard->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->stack, noEvent); // Fixed a bug when using noevent option with namedcard option. copy = theNamedCard->controller()->game->putInZone(theNamedCard, theNamedCard->currentZone, source->controller()->game->stack, noEvent); // Fixed a bug when using noevent option with namedcard option.
} }
@@ -10165,17 +10177,29 @@ int AACastCard::resolveSpell()
Spell * spell = NULL; Spell * spell = NULL;
MTGCardInstance * copy = NULL; MTGCardInstance * copy = NULL;
if ((normal || asNormalMadness)||(!_target->hasType(Subtypes::TYPE_INSTANT) && !_target->hasType(Subtypes::TYPE_SORCERY))) if ((normal || asNormalMadness) || !_target->isSorceryorInstant())
{ {
if (putinplay && _target->isPermanent()) if (putinplay && _target->isPermanent())
copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with double activation of card abilities. copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with double activation of card abilities.
else if (asCopy && _target->isPermanent()){
_target->isToken = 0; // Fixed a bug when using copied option for permanent.
copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack, noEvent);
copy->isToken = 1; // Fixed a bug when using copied option for permanent.
copy = _target->controller()->game->putInZone(copy, copy->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with copied option for permanent.
}
else else
copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack, noEvent); // Fixed a bug when using noevent option with namedcard option. copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack, noEvent); // Fixed a bug when using noevent option with namedcard option.
} }
else else
{ {
if (putinplay && _target->isPermanent()) if (putinplay && _target->isPermanent())
copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with double activation of card abilities. copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with double activation of card abilities.
else if (asCopy && _target->isPermanent()){
_target->isToken = 0; // Fixed a bug when using copied option for permanent.
copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack, noEvent);
copy->isToken = 1; // Fixed a bug when using copied option for permanent.
copy = _target->controller()->game->putInZone(copy, copy->currentZone, source->controller()->game->battlefield, noEvent); // Fixed a problem with copied option for permanent.
}
else else
copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack, noEvent); // Fixed a bug when using noevent option with namedcard option. copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack, noEvent); // Fixed a bug when using noevent option with namedcard option.
} }
@@ -10187,6 +10211,8 @@ int AACastCard::resolveSpell()
copy->changeController(source->controller(), true); copy->changeController(source->controller(), true);
if(asNormalMadness) if(asNormalMadness)
copy->MadnessPlay = true; copy->MadnessPlay = true;
if(asCopy)
copy->isToken = 1; // Fixed a bug when using copied option for permanent.
if(alternative) if(alternative)
copy->alternateCostPaid[ManaCost::MANA_PAID_WITH_ALTERNATIVE] = 1; copy->alternateCostPaid[ManaCost::MANA_PAID_WITH_ALTERNATIVE] = 1;
if(kicked > 0){ if(kicked > 0){
@@ -10203,7 +10229,7 @@ int AACastCard::resolveSpell()
game->targetChooser->Owner = source->controller(); game->targetChooser->Owner = source->controller();
if(putinplay) if(putinplay)
{ {
spell = NEW Spell(game, 0,copy,game->targetChooser,NULL, 1); spell = NEW Spell(game, 0, copy, game->targetChooser, NULL, 1);
spell->resolve(); spell->resolve();
} }
else else
@@ -10214,7 +10240,7 @@ int AACastCard::resolveSpell()
{ {
if(putinplay) if(putinplay)
{ {
spell = NEW Spell(game, 0,copy,NULL,NULL, 1); spell = NEW Spell(game, 0, copy, NULL, NULL, 1);
spell->resolve(); spell->resolve();
} }
else if(!flipped) else if(!flipped)