mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
- Added Suspend keyword.
- Added Duskrider Peregrine, Errant Ephemeron, Keldon Halberdier, Durkwood Baloth, Lotus Bloom, Corpulent Corpse - Updated Shade of Trokair, Giant Dustwasp, Pardic Dragon, Viscerid Deepwalker with Suspend keyword - Added Ancestral Vision, although it currently doesn't draw cards due to a upkeep/draw phase bug that doesn't let you draw more than one card during your draw phase.
This commit is contained in:
@@ -38,6 +38,13 @@ snow_covered_mountain.jpg http://www.wizards.com/global/images/magic/gene
|
|||||||
snow_covered_mountain1.jpg http://www.wizards.com/global/images/magic/general/snow_covered_mountain.jpg
|
snow_covered_mountain1.jpg http://www.wizards.com/global/images/magic/general/snow_covered_mountain.jpg
|
||||||
snow_covered_mountain2.jpg http://www.magickartenmarkt.de/img/cards/Ice_Age/snow_covered_mountain.jpg
|
snow_covered_mountain2.jpg http://www.magickartenmarkt.de/img/cards/Ice_Age/snow_covered_mountain.jpg
|
||||||
snow_covered_mountain3.jpg http://www.magickartenmarkt.de/img/cards/Ice_Age/snow_covered_mountain.jpg
|
snow_covered_mountain3.jpg http://www.magickartenmarkt.de/img/cards/Ice_Age/snow_covered_mountain.jpg
|
||||||
|
ancestral_vision.jpg http://www.wizards.com/global/images/magic/general/ancestral_vision.jpg
|
||||||
|
duskrider_peregrine.jpg http://www.wizards.com/global/images/magic/general/duskrider_peregrine.jpg
|
||||||
|
errant_ephemeron.jpg http://www.wizards.com/global/images/magic/general/errant_ephemeron.jpg
|
||||||
|
keldon_halberdier.jpg http://www.wizards.com/global/images/magic/general/keldon_halberdier.jpg
|
||||||
|
durkwood_baloth.jpg http://www.wizards.com/global/images/magic/general/durkwood_baloth.jpg
|
||||||
|
lotus_bloom.jpg http://www.wizards.com/global/images/magic/general/lotus_bloom.jpg
|
||||||
|
corpulent_corpse.jpg http://www.wizards.com/global/images/magic/general/corpulent_corpse.jpg
|
||||||
bogardan_hellkite.jpg http://www.wizards.com/global/images/magic/general/bogardan_hellkite.jpg
|
bogardan_hellkite.jpg http://www.wizards.com/global/images/magic/general/bogardan_hellkite.jpg
|
||||||
sparkmage_apprentice.jpg http://www.wizards.com/global/images/magic/general/sparkmage_apprentice.jpg
|
sparkmage_apprentice.jpg http://www.wizards.com/global/images/magic/general/sparkmage_apprentice.jpg
|
||||||
akoum_boulderfoot.jpg http://www.wizards.com/global/images/magic/general/akoum_boulderfoot.jpg
|
akoum_boulderfoot.jpg http://www.wizards.com/global/images/magic/general/akoum_boulderfoot.jpg
|
||||||
|
|||||||
120
res/cards.txt
120
res/cards.txt
@@ -1,3 +1,94 @@
|
|||||||
|
Duskrider Peregrine
|
||||||
|
5 W
|
||||||
|
Creature - Bird
|
||||||
|
no text
|
||||||
|
3/3
|
||||||
|
Flying
|
||||||
|
Protection from black
|
||||||
|
Suspend:3:1 W
|
||||||
|
|
||||||
|
Ancestral Vision
|
||||||
|
no cost
|
||||||
|
Sorcery
|
||||||
|
(Note: Ancestral Vision currently draws 0 cards due to the combined upkeep/draw phases. Once they are seperated, this should work as expected.)
|
||||||
|
Suspend:4:U
|
||||||
|
spDrawCardsTgt:3:Target player draws three cards.:CARDNAME - draw 3 cards.
|
||||||
|
|
||||||
|
Errant Ephemeron
|
||||||
|
6 U
|
||||||
|
Creature - Illusion
|
||||||
|
no text
|
||||||
|
4/4
|
||||||
|
Flying
|
||||||
|
Suspend:4:1 U
|
||||||
|
|
||||||
|
Keldon Halberdier
|
||||||
|
4 R
|
||||||
|
Creature - Human Warrior
|
||||||
|
no text
|
||||||
|
4/1
|
||||||
|
First strike
|
||||||
|
Suspend:4:R
|
||||||
|
|
||||||
|
Durkwood Baloth
|
||||||
|
4 G G
|
||||||
|
Creature - Beast
|
||||||
|
no text
|
||||||
|
5/5
|
||||||
|
Suspend:5:G
|
||||||
|
|
||||||
|
Lotus Bloom
|
||||||
|
no cost
|
||||||
|
Artifact
|
||||||
|
no text
|
||||||
|
Suspend:3:0
|
||||||
|
tap, Sacrifice CARDNAME: Add W W W to your mana pool.
|
||||||
|
tap, Sacrifice CARDNAME: Add U U U to your mana pool.
|
||||||
|
tap, Sacrifice CARDNAME: Add B B B to your mana pool.
|
||||||
|
tap, Sacrifice CARDNAME: Add R R R to your mana pool.
|
||||||
|
tap, Sacrifice CARDNAME: Add G G G to your mana pool.
|
||||||
|
|
||||||
|
Corpulent Corpse
|
||||||
|
5 B
|
||||||
|
Creature Zombie
|
||||||
|
no text
|
||||||
|
3/3
|
||||||
|
Fear
|
||||||
|
Suspend:5:B
|
||||||
|
|
||||||
|
Shade of Trokair
|
||||||
|
3 W
|
||||||
|
Creature Shade
|
||||||
|
no text
|
||||||
|
1/2
|
||||||
|
Suspend:3:W
|
||||||
|
abPump W:+1/+1
|
||||||
|
|
||||||
|
Giant Dustwasp
|
||||||
|
3 G G
|
||||||
|
Creature Insect
|
||||||
|
No Text
|
||||||
|
3/3
|
||||||
|
Flying
|
||||||
|
Suspend:4:1 G
|
||||||
|
|
||||||
|
Pardic Dragon
|
||||||
|
4 R R
|
||||||
|
Creature Dragon
|
||||||
|
(Note: Opponent adding time counters when playing spell not implemented. Might be able to do with Whenever keyword)
|
||||||
|
4/4
|
||||||
|
Flying
|
||||||
|
Suspend:2:R R
|
||||||
|
abPump R:+1/+0
|
||||||
|
|
||||||
|
Viscerid Deepwalker
|
||||||
|
4 U
|
||||||
|
Creature Homarid Warrior
|
||||||
|
no text
|
||||||
|
2/3
|
||||||
|
Suspend:4:U
|
||||||
|
abPump U:+1/+0
|
||||||
|
|
||||||
Bogardan Hellkite
|
Bogardan Hellkite
|
||||||
6 R R
|
6 R R
|
||||||
Creature Dragon
|
Creature Dragon
|
||||||
@@ -19303,13 +19394,6 @@ no text
|
|||||||
Fear
|
Fear
|
||||||
abPump B:+1/+1
|
abPump B:+1/+1
|
||||||
|
|
||||||
Shade of Trokair
|
|
||||||
3 W
|
|
||||||
Creature Shade
|
|
||||||
(NOTE: "Suspend" not implemented.)
|
|
||||||
1/2
|
|
||||||
abPump W:+1/+1
|
|
||||||
|
|
||||||
Looming Shade
|
Looming Shade
|
||||||
2 B
|
2 B
|
||||||
Creature Shade
|
Creature Shade
|
||||||
@@ -19405,13 +19489,6 @@ no text
|
|||||||
3/3
|
3/3
|
||||||
abPump B:+1/+1
|
abPump B:+1/+1
|
||||||
|
|
||||||
Viscerid Deepwalker
|
|
||||||
4 U
|
|
||||||
Creature Homarid Warrior
|
|
||||||
(NOTE: "Suspend" not implemented.)
|
|
||||||
2/3
|
|
||||||
abPump U:+1/+0
|
|
||||||
|
|
||||||
Colos Yearling
|
Colos Yearling
|
||||||
2 R
|
2 R
|
||||||
Creature Goat Beast
|
Creature Goat Beast
|
||||||
@@ -19480,14 +19557,6 @@ no text
|
|||||||
Flying
|
Flying
|
||||||
abPump W:+0/+1
|
abPump W:+0/+1
|
||||||
|
|
||||||
Pardic Dragon
|
|
||||||
4 R R
|
|
||||||
Creature Dragon
|
|
||||||
(NOTE: "Suspend" not implemented.)
|
|
||||||
4/4
|
|
||||||
Flying
|
|
||||||
abPump R:+1/+0
|
|
||||||
|
|
||||||
Aven Flock
|
Aven Flock
|
||||||
4 W
|
4 W
|
||||||
Creature Bird Soldier
|
Creature Bird Soldier
|
||||||
@@ -21745,13 +21814,6 @@ Haste
|
|||||||
Trample
|
Trample
|
||||||
At the beginning of the end step, sacrifice CARDNAME.
|
At the beginning of the end step, sacrifice CARDNAME.
|
||||||
|
|
||||||
Giant Dustwasp
|
|
||||||
3 G G
|
|
||||||
Creature Insect
|
|
||||||
(NOTE: "Suspend" not implemented.)
|
|
||||||
3/3
|
|
||||||
Flying
|
|
||||||
|
|
||||||
Brute Force
|
Brute Force
|
||||||
R
|
R
|
||||||
Instant
|
Instant
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ public class Card extends MyObservable {
|
|||||||
private boolean unearthed;
|
private boolean unearthed;
|
||||||
|
|
||||||
private boolean madness = false;
|
private boolean madness = false;
|
||||||
|
private boolean suspendCast = false;
|
||||||
|
|
||||||
private int exaltedMagnitude = 0;
|
private int exaltedMagnitude = 0;
|
||||||
|
|
||||||
@@ -1800,6 +1801,14 @@ public class Card extends MyObservable {
|
|||||||
madnessCost = cost;
|
madnessCost = cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasSuspendCast() {
|
||||||
|
return suspendCast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuspendCast(boolean b) {
|
||||||
|
suspendCast = b;
|
||||||
|
}
|
||||||
|
|
||||||
public void setKicked(boolean b) {
|
public void setKicked(boolean b) {
|
||||||
kicked = b;
|
kicked = b;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3433,13 +3433,27 @@ public class CardFactory implements NewConstants {
|
|||||||
//card.removeIntrinsicKeyword(parse);
|
//card.removeIntrinsicKeyword(parse);
|
||||||
|
|
||||||
String k[] = parse.split(":");
|
String k[] = parse.split(":");
|
||||||
final String manacost = k[1];
|
|
||||||
|
|
||||||
card.setMadness(true);
|
card.setMadness(true);
|
||||||
card.setMadnessCost(k[1]);
|
card.setMadnessCost(k[1]);
|
||||||
}
|
}
|
||||||
}//madness
|
}//madness
|
||||||
|
|
||||||
|
if(hasKeyword(card, "Suspend") != -1) {
|
||||||
|
// Suspend:<TimeCounters>:<Cost>
|
||||||
|
int n = hasKeyword(card, "Suspend");
|
||||||
|
if(n != -1) {
|
||||||
|
String parse = card.getKeyword().get(n).toString();
|
||||||
|
card.removeIntrinsicKeyword(parse);
|
||||||
|
|
||||||
|
String k[] = parse.split(":");
|
||||||
|
|
||||||
|
final int timeCounters = Integer.parseInt(k[1]);
|
||||||
|
final String cost = k[2];
|
||||||
|
card.addSpellAbility(CardFactoryUtil.ability_suspend(card, cost, timeCounters));
|
||||||
|
}
|
||||||
|
}//madness
|
||||||
|
|
||||||
if(hasKeyword(card, "Devour") != -1) {
|
if(hasKeyword(card, "Devour") != -1) {
|
||||||
int n = hasKeyword(card, "Devour");
|
int n = hasKeyword(card, "Devour");
|
||||||
if(n != -1) {
|
if(n != -1) {
|
||||||
@@ -5001,7 +5015,6 @@ public class CardFactory implements NewConstants {
|
|||||||
card.addSpellAbility(spell);
|
card.addSpellAbility(spell);
|
||||||
}//*************** END ************ END **************************
|
}//*************** END ************ END **************************
|
||||||
|
|
||||||
|
|
||||||
//*************** START *********** START **************************
|
//*************** START *********** START **************************
|
||||||
else if(cardName.equals("Dragon Roost")) {
|
else if(cardName.equals("Dragon Roost")) {
|
||||||
final SpellAbility ability = new Ability(card, "5 R R") {
|
final SpellAbility ability = new Ability(card, "5 R R") {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import com.esotericsoftware.minlog.Log;
|
import com.esotericsoftware.minlog.Log;
|
||||||
|
|
||||||
|
import forge.Constant.Zone;
|
||||||
|
|
||||||
|
|
||||||
public class CardFactoryUtil {
|
public class CardFactoryUtil {
|
||||||
@@ -1553,6 +1554,37 @@ public class CardFactoryUtil {
|
|||||||
return transmute;
|
return transmute;
|
||||||
}//ability_transmute()
|
}//ability_transmute()
|
||||||
|
|
||||||
|
public static SpellAbility ability_suspend(final Card sourceCard, final String suspendCost, final int suspendCounters) {
|
||||||
|
final SpellAbility suspend = new Ability_Hand(sourceCard, suspendCost) {
|
||||||
|
private static final long serialVersionUID = 21625903128384507L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlay(){
|
||||||
|
// if not in hand can't suspend
|
||||||
|
if (!AllZone.GameAction.isCardInZone(sourceCard, AllZone.getZone(Zone.Hand, sourceCard.getOwner())))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (sourceCard.isInstant())
|
||||||
|
return true;
|
||||||
|
return Phase.canCastSorcery(sourceCard.getOwner());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlayAI() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolve() {
|
||||||
|
AllZone.GameAction.removeFromGame(sourceCard);
|
||||||
|
sourceCard.addCounter(Counters.TIME, suspendCounters);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
suspend.setDescription("Suspend " +suspendCounters + ": "+ suspendCost);
|
||||||
|
suspend.setStackDescription(sourceCard + " suspending for " + suspendCounters + " turns.)");
|
||||||
|
return suspend;
|
||||||
|
}//ability_cycle()
|
||||||
|
|
||||||
public static SpellAbility eqPump_Equip(final Card sourceCard, final int Power, final int Tough, final String[] extrinsicKeywords, final String Manacost) {
|
public static SpellAbility eqPump_Equip(final Card sourceCard, final int Power, final int Tough, final String[] extrinsicKeywords, final String Manacost) {
|
||||||
final Ability equip = new Ability(sourceCard, Manacost) {
|
final Ability equip = new Ability(sourceCard, Manacost) {
|
||||||
private static final long serialVersionUID = -4960704261761785512L;
|
private static final long serialVersionUID = -4960704261761785512L;
|
||||||
|
|||||||
@@ -2147,7 +2147,8 @@ public class GameAction {
|
|||||||
PlayerZone zone = AllZone.getZone(c); //could be hand, grave, play, ...
|
PlayerZone zone = AllZone.getZone(c); //could be hand, grave, play, ...
|
||||||
PlayerZone removed = AllZone.getZone(Constant.Zone.Removed_From_Play, c.getOwner());
|
PlayerZone removed = AllZone.getZone(Constant.Zone.Removed_From_Play, c.getOwner());
|
||||||
|
|
||||||
zone.remove(c);
|
if (zone != null) // for suspend
|
||||||
|
zone.remove(c);
|
||||||
if(!c.isToken()) removed.add(c);
|
if(!c.isToken()) removed.add(c);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2829,7 +2830,8 @@ public class GameAction {
|
|||||||
choices.add("Play land");
|
choices.add("Play land");
|
||||||
|
|
||||||
for(SpellAbility sa:abilities) {
|
for(SpellAbility sa:abilities) {
|
||||||
if(sa.canPlay()) {
|
// for uncastables like lotus bloom, check if manaCost is blank
|
||||||
|
if(sa.canPlay() && !sa.getManaCost().equals("")) {
|
||||||
choices.add(sa.toString());
|
choices.add(sa.toString());
|
||||||
map.put(sa.toString(), sa);
|
map.put(sa.toString(), sa);
|
||||||
}
|
}
|
||||||
@@ -2843,6 +2845,9 @@ public class GameAction {
|
|||||||
else
|
else
|
||||||
choice = (String) AllZone.Display.getChoiceOptional("Choose", choices.toArray());
|
choice = (String) AllZone.Display.getChoiceOptional("Choose", choices.toArray());
|
||||||
|
|
||||||
|
if (choice == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if(choice.equals("Play land")){
|
if(choice.equals("Play land")){
|
||||||
playLand(c, AllZone.Human_Hand);
|
playLand(c, AllZone.Human_Hand);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public class GameActionUtil {
|
|||||||
upkeep_DamageUpkeepCost(); //deal damage unless upkeep cost is paid
|
upkeep_DamageUpkeepCost(); //deal damage unless upkeep cost is paid
|
||||||
upkeep_CumulativeUpkeepCost(); //sacrifice unless cumulative upkeep cost is paid
|
upkeep_CumulativeUpkeepCost(); //sacrifice unless cumulative upkeep cost is paid
|
||||||
upkeep_Echo();
|
upkeep_Echo();
|
||||||
|
upkeep_Suspend();
|
||||||
upkeep_TabernacleUpkeepCost();
|
upkeep_TabernacleUpkeepCost();
|
||||||
upkeep_MagusTabernacleUpkeepCost();
|
upkeep_MagusTabernacleUpkeepCost();
|
||||||
// upkeep_CheckEmptyDeck_Lose(); //still a little buggy
|
// upkeep_CheckEmptyDeck_Lose(); //still a little buggy
|
||||||
@@ -3248,6 +3249,50 @@ public class GameActionUtil {
|
|||||||
}
|
}
|
||||||
}//echo
|
}//echo
|
||||||
|
|
||||||
|
public static void upkeep_Suspend() {
|
||||||
|
String player = AllZone.Phase.getActivePlayer();
|
||||||
|
|
||||||
|
PlayerZone exile = AllZone.getZone(Constant.Zone.Removed_From_Play, player);
|
||||||
|
CardList list = new CardList();
|
||||||
|
list.addAll(exile.getCards());
|
||||||
|
//list = list.getType("Creature");
|
||||||
|
list = list.filter(new CardListFilter() {
|
||||||
|
public boolean addCard(Card c) {
|
||||||
|
for(String s : c.getKeyword()){
|
||||||
|
if (s.contains("Suspend"))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (list.size() == 0) return;
|
||||||
|
|
||||||
|
for(final Card c : list){
|
||||||
|
int counters = c.getCounters(Counters.TIME);
|
||||||
|
if (counters > 0)
|
||||||
|
{
|
||||||
|
c.setCounter(Counters.TIME, counters-1);
|
||||||
|
if (counters == 1){
|
||||||
|
c.setSuspendCast(true);
|
||||||
|
|
||||||
|
// todo(sol): haste should wear off when player loses control. need to figure out where to add that.
|
||||||
|
Command intoPlay = new Command() {
|
||||||
|
private static final long serialVersionUID = -4514610171270596654L;
|
||||||
|
|
||||||
|
public void execute() {
|
||||||
|
if(AllZone.GameAction.isCardInPlay(c) && c.isCreature())
|
||||||
|
c.addExtrinsicKeyword("Haste");
|
||||||
|
}//execute()
|
||||||
|
};
|
||||||
|
|
||||||
|
c.addComesIntoPlayCommand(intoPlay);
|
||||||
|
AllZone.GameAction.playCardNoCost(c);
|
||||||
|
exile.remove(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//suspend
|
||||||
|
|
||||||
public static void upkeep_UpkeepCost() {
|
public static void upkeep_UpkeepCost() {
|
||||||
String player = AllZone.Phase.getActivePlayer();
|
String player = AllZone.Phase.getActivePlayer();
|
||||||
|
|||||||
Reference in New Issue
Block a user