-Small fix in Riding the Dilu Horse.

-Cycling/Transmute/... + future other "hand abilities" should work on lands now.
-Fixed a lot of bugs in the combat code.
-Added Lichentrope, Phytohydra and Callous Giant.
This commit is contained in:
jendave
2011-08-06 03:00:41 +00:00
parent 1c64df6cd1
commit 7af3549c79
13 changed files with 532 additions and 192 deletions

View File

@@ -18,6 +18,8 @@ forest.jpg http://resources.wizards.com/magic/cards/unh/en-us/card73946.jpg
forest1.jpg http://gatherer.wizards.com/handlers/image.ashx?type=card&multiverseid=2748 forest1.jpg http://gatherer.wizards.com/handlers/image.ashx?type=card&multiverseid=2748
forest2.jpg http://gatherer.wizards.com/handlers/image.ashx?type=card&multiverseid=587 forest2.jpg http://gatherer.wizards.com/handlers/image.ashx?type=card&multiverseid=587
forest3.jpg http://gatherer.wizards.com/handlers/image.ashx?type=card&multiverseid=586 forest3.jpg http://gatherer.wizards.com/handlers/image.ashx?type=card&multiverseid=586
phytohydra.jpg http://www.wizards.com/global/images/magic/general/phytohyrda.jpg
lichentrope.jpg http://www.wizards.com/global/images/magic/general/lichentrope.jpg
feast_of_flesh.jpg http://www.wizards.com/global/images/magic/general/feast_of_flesh.jpg feast_of_flesh.jpg http://www.wizards.com/global/images/magic/general/feast_of_flesh.jpg
first_volley.jpg http://www.wizards.com/global/images/magic/general/first_volley.jpg first_volley.jpg http://www.wizards.com/global/images/magic/general/first_volley.jpg
svogthos_the_restless_tomb.jpg http://www.wizards.com/global/images/magic/general/svogthos_the_restless_tomb.jpg svogthos_the_restless_tomb.jpg http://www.wizards.com/global/images/magic/general/svogthos_the_restless_tomb.jpg

View File

@@ -1,3 +1,21 @@
Phytohydra
2 W W G
Creature Plant Hydra
If damage would be dealt to Phytohydra, put that many +1/+1 counters on it instead.
1/1
Callous Giant
4 R R
Creature Giant
If a source would deal 3 or less damage to Callous Giant, prevent that damage.
4/4
Lichentrope
3 G G
Creature Plant Fungus
If damage would be dealt to Lichenthrope, put that many -1/-1 counters on it instead. At the beginning of your upkeep, remove a -1/-1 counter from Lichenthrope
5/5
Feast of Flesh Feast of Flesh
B B
Sorcery Sorcery
@@ -374,7 +392,7 @@ TypeCycling:Basic:1 R
Absorb Vis Absorb Vis
6 B 6 B
Sorcery Sorcery
Target player loses 4 life and you gain 4 life. no text
spLoseLifeGainLife:4 spLoseLifeGainLife:4
TypeCycling:Basic:1 B TypeCycling:Basic:1 B
@@ -628,31 +646,31 @@ Shroud
Emberstrike Duo Emberstrike Duo
1 BR 1 BR
Creature Elemental Warrior Shaman Creature Elemental Warrior Shaman
Whenever you cast a black spell, Emberstrike Duo gets +1/+1 until end of turn. Whenever you cast a red spell, Emberstrike Duo gains first strike until end of turn. Whenever you cast a black spell, Emberstrike Duo gets +1/+1 until end of turn. Whenever you cast a red spell, Emberstrike Duo gains first strike until end of turn.
1/1 1/1
Gravelgill Duo Gravelgill Duo
2 UB 2 UB
Creature Merfolk Rogue Warrior Creature Merfolk Rogue Warrior
Whenever you cast a blue spell, Gravelgill Duo gets +1/+1 until end of turn. Whenever you cast a black spell, Gravelgill Duo gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.) Whenever you cast a blue spell, Gravelgill Duo gets +1/+1 until end of turn. Whenever you cast a black spell, Gravelgill Duo gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.)
2/1 2/1
Safehold Duo Safehold Duo
3 GW 3 GW
Creature Elf Warrior Shaman Creature Elf Warrior Shaman
Whenever you cast a green spell, Safehold Duo gets +1/+1 until end of turn. Whenever you cast a white spell, Safehold Duo gains vigilance until end of turn. Whenever you cast a green spell, Safehold Duo gets +1/+1 until end of turn. Whenever you cast a white spell, Safehold Duo gains vigilance until end of turn.
2/4 2/4
Tattermunge Duo Tattermunge Duo
2 RG 2 RG
Creature Goblin Warrior Shaman Creature Goblin Warrior Shaman
Whenever you cast a red spell, Tattermunge Duo gets +1/+1 until end of turn. Whenever you cast a green spell, Tattermunge Duo gains forestwalk until end of turn. Whenever you cast a red spell, Tattermunge Duo gets +1/+1 until end of turn. Whenever you cast a green spell, Tattermunge Duo gains forestwalk until end of turn.
2/3 2/3
Thistledown Duo Thistledown Duo
2 WU 2 WU
Creature Kithkin Soldier Wizard Creature Kithkin Soldier Wizard
Whenever you cast a white spell, Thistledown Duo gets +1/+1 until end of turn. Whenever you cast a blue spell, Thistledown Duo gains flying until end of turn. Whenever you cast a white spell, Thistledown Duo gets +1/+1 until end of turn. Whenever you cast a blue spell, Thistledown Duo gains flying until end of turn.
2/2 2/2
Phantom Centaur Phantom Centaur
@@ -692,44 +710,44 @@ As Meddling Mage enters the battlefield, name a nonland card. The named card can
Shorecrasher Mimic Shorecrasher Mimic
1 GU 1 GU
Creature Shapeshifter Creature Shapeshifter
Whenever you cast a spell that's both green and blue, Shorecrasher Mimic becomes 5/3 and gains trample until end of turn. Whenever you cast a spell that<EFBFBD>s both green and blue, Shorecrasher Mimic becomes 5/3 and gains trample until end of turn.
2/1 2/1
Woodlurker Mimic Woodlurker Mimic
1 BG 1 BG
Creature Shapeshifter Creature Shapeshifter
Whenever you cast a spell that's both black and green, Woodlurker Mimic becomes 4/5 and gains wither until end of turn. (It deals damage to creatures in the form of -1/-1 counters.) Whenever you cast a spell that<EFBFBD>s both black and green, Woodlurker Mimic becomes 4/5 and gains wither until end of turn. (It deals damage to creatures in the form of -1/-1 counters.)
2/1 2/1
Battlegate Mimic Battlegate Mimic
1 RW 1 RW
Creature Shapeshifter Creature Shapeshifter
Whenever you cast a spell that's both red and white, Battlegate Mimic becomes 4/2 and gains first strike until end of turn. Whenever you cast a spell that<EFBFBD>s both red and white, Battlegate Mimic becomes 4/2 and gains first strike until end of turn.
2/1 2/1
Nightsky Mimic Nightsky Mimic
1 WB 1 WB
Creature Shapeshifter Creature Shapeshifter
Whenever you cast a spell that's both white and black, Nightsky Mimic becomes 4/4 and gains flying until end of turn. Whenever you cast a spell that<EFBFBD>s both white and black, Nightsky Mimic becomes 4/4 and gains flying until end of turn.
2/1 2/1
Riverfall Mimic Riverfall Mimic
1 UR 1 UR
Creature Shapeshifter Creature Shapeshifter
Whenever you cast a spell that's both blue and red, Riverfall Mimic becomes 3/3 and is unblockable until end of turn. Whenever you cast a spell that<EFBFBD>s both blue and red, Riverfall Mimic becomes 3/3 and is unblockable until end of turn.
2/1 2/1
Sapling of Colfenor Sapling of Colfenor
3 BG BG 3 BG BG
Legendary Creature Treefolk Shaman Legendary Creature Treefolk Shaman
Whenever Sapling of Colfenor attacks, reveal the top card of your library. If it's a creature card, you gain life equal to that card's toughness, lose life equal to its power, then put it into your hand. Whenever Sapling of Colfenor attacks, reveal the top card of your library. If it<EFBFBD>s a creature card, you gain life equal to that card<EFBFBD>s toughness, lose life equal to its power, then put it into your hand.
2/5 2/5
Indestructible Indestructible
Dovescape Dovescape
3 WU WU WU 3 WU WU WU
Enchantment Enchantment
Whenever a player casts a noncreature spell, counter that spell. That player puts X 1/1 white and blue Bird creature tokens with flying onto the battlefield, where X is the spell's converted mana cost. Whenever a player casts a noncreature spell, counter that spell. That player puts X 1/1 white and blue Bird creature tokens with flying onto the battlefield, where X is the spell<EFBFBD>s converted mana cost.
Lurking Informant Lurking Informant
1 UB 1 UB
@@ -740,28 +758,28 @@ no text
Belligerent Hatchling Belligerent Hatchling
3 RW 3 RW
Creature Elemental Creature Elemental
Belligerent Hatchling enters the battlefield with four -1/-1 counters on it. Whenever you cast a red spell, remove a -1/-1 counter from Belligerent Hatchling. Whenever you cast a white spell, remove a -1/-1 counter from Belligerent Hatchling. Belligerent Hatchling enters the battlefield with four -1/-1 counters on it. Whenever you cast a red spell, remove a -1/-1 counter from Belligerent Hatchling. Whenever you cast a white spell, remove a -1/-1 counter from Belligerent Hatchling.
6/6 6/6
First Strike First Strike
Noxious Hatchling Noxious Hatchling
3 BG 3 BG
Creature Elemental Creature Elemental
Noxious Hatchling enters the battlefield with four -1/-1 counters on it. Whenever you cast a black spell, remove a -1/-1 counter from Noxious Hatchling. Whenever you cast a green spell, remove a -1/-1 counter from Noxious Hatchling. Noxious Hatchling enters the battlefield with four -1/-1 counters on it. Whenever you cast a black spell, remove a -1/-1 counter from Noxious Hatchling. Whenever you cast a green spell, remove a -1/-1 counter from Noxious Hatchling.
6/6 6/6
Wither Wither
Sturdy Hatchling Sturdy Hatchling
3 GU 3 GU
Creature Elemental Creature Elemental
Sturdy Hatchling enters the battlefield with four -1/-1 counters on it. Whenever you cast a green spell, remove a -1/-1 counter from Sturdy Hatchling. Whenever you cast a blue spell, remove a -1/-1 counter from Sturdy Hatchling. Sturdy Hatchling enters the battlefield with four -1/-1 counters on it. Whenever you cast a green spell, remove a -1/-1 counter from Sturdy Hatchling. Whenever you cast a blue spell, remove a -1/-1 counter from Sturdy Hatchling.
6/6 6/6
KPump GU:Shroud KPump GU:Shroud
Voracious Hatchling Voracious Hatchling
3 WB 3 WB
Creature Elemental Creature Elemental
Voracious Hatchling enters the battlefield with four -1/-1 counters on it. Whenever you cast a white spell, remove a -1/-1 counter from Voracious Hatchling. Whenever you cast a black spell, remove a -1/-1 counter from Voracious Hatchling. Voracious Hatchling enters the battlefield with four -1/-1 counters on it. Whenever you cast a white spell, remove a -1/-1 counter from Voracious Hatchling. Whenever you cast a black spell, remove a -1/-1 counter from Voracious Hatchling.
6/6 6/6
Lifelink Lifelink
@@ -837,12 +855,12 @@ Exile all cards from target player's hand and graveyard.
Lobotomy Lobotomy
2 U B 2 U B
Sorcery Sorcery
Target player reveals his or her hand, then you choose a card other than a basic land card from it. Search that player's graveyard, hand, and library for all cards with the same name as the chosen card and remove them from the game. Then that player shuffles his or her library. Target player reveals his or her hand, then you choose a card other than a basic land card from it. Search that player's graveyard, hand, and library for all cards with the same name as the chosen card and remove them from the game. Then that player shuffles his or her library.
Haunting Echoes Haunting Echoes
3 B B 3 B B
Sorcery Sorcery
Remove all cards in target player's graveyard other than basic land cards from the game. Search that player's library for all cards with the same name as cards removed this way, and remove them from the game. Then that player shuffles his or her library. Remove all cards in target player's graveyard other than basic land cards from the game. Search that player's library for all cards with the same name as cards removed this way, and remove them from the game. Then that player shuffles his or her library.
Daru Encampment Daru Encampment
no cost no cost
@@ -898,7 +916,7 @@ no text
Wood Elves Wood Elves
2 G 2 G
Creature Elf Scout Creature Elf Scout
When Wood Elves comes into play, search your library for a Forest card and put that card into play. Then shuffle your library. When Wood Elves comes into play, search your library for a Forest card and put that card into play. Then shuffle your library.
1/1 1/1
Assembly-Worker Assembly-Worker
@@ -12609,7 +12627,7 @@ You gain 10 life. Then if you have more life than an opponent, put a 5/5 white G
Reach of Branches Reach of Branches
4 G 4 G
Tribal Instant Treefolk Tribal Instant Treefolk
Put a 2/5 green Treefolk Shaman creature token into play. Whenever a Forest comes into play under your control, you may return Reach of Branches from your graveyard to your hand. Put a 2/5 green Treefolk Shaman creature token into play. Whenever a Forest comes into play under your control, you may return Reach of Branches from your graveyard to your hand.
Meadowboon Meadowboon
2 W W 2 W W
@@ -12751,7 +12769,7 @@ Sorcery
Each player shuffles his or her hand and graveyard into his or her library and then draws seven cards. Each player shuffles his or her hand and graveyard into his or her library and then draws seven cards.
Inner-Flame Acolyte Inner-Flame Acolyte
1 R R 1 R R
Creature Elemental Shaman Creature Elemental Shaman
When Inner-Flame Acolyte comes into play, target creature gets +2/+0 and gains haste until end of turn. When Inner-Flame Acolyte comes into play, target creature gets +2/+0 and gains haste until end of turn.
2/2 2/2
@@ -12764,7 +12782,7 @@ When Briarhorn comes into play, target creature gets +3/+3 until end of turn.
Flash Flash
Shriekmaw Shriekmaw
4 B 4 B
Creature Elemental Creature Elemental
When Shriekmaw comes into play, destroy target nonartifact, nonblack creature. When Shriekmaw comes into play, destroy target nonartifact, nonblack creature.
3/2 3/2
@@ -12864,7 +12882,7 @@ Garruk Wildspeaker
Planeswalker - Garruk Planeswalker - Garruk
no text no text
Liliana Vess Liliana Vess
3 B B 3 B B
Planeswalker - Liliana Planeswalker - Liliana
no text no text
@@ -13114,7 +13132,7 @@ no text
Take Possession Take Possession
5 U U 5 U U
Sorcery Sorcery
Gain control of target permanent. (NOTE: "Split second" not implemented. This spell is currently treated as a Sorcery rather than as an Enchantment.) Gain control of target permanent. (NOTE: "Split second" not implemented. This spell is currently treated as a Sorcery rather than as an Enchantment.)
Cloudseeder Cloudseeder
1 U 1 U
@@ -13123,7 +13141,7 @@ no text
1/1 1/1
Flying Flying
Goldmeadow Lookout Goldmeadow Lookout
3 W 3 W
Creature Kithkin Spellshaper Creature Kithkin Spellshaper
no text no text
@@ -13159,7 +13177,7 @@ Indestructible
Animate Dead Animate Dead
1 B 1 B
Sorcery Sorcery
Put target creature card from any graveyard into play under your control. That creature gets -1/-0. (NOTE: This spell is currently treated as a Sorcery rather than as an Enchantment.) Put target creature card from any graveyard into play under your control. That creature gets -1/-0. (NOTE: This spell is currently treated as a Sorcery rather than as an Enchantment.)
Ashes to Ashes Ashes to Ashes
1 B B 1 B B
@@ -13532,7 +13550,7 @@ no text
Erratic Explosion Erratic Explosion
2 R 2 R
Sorcery Sorcery
Choose target creature or player. The computer will randomly choose a nonland card from your library. Erratic Explosion deals damage equal to that card's converted mana cost to that creature or player. Choose target creature or player. The computer will randomly choose a nonland card from your library. Erratic Explosion deals damage equal to that card's converted mana cost to that creature or player.
Tribal Flames Tribal Flames
1 R 1 R
@@ -13818,7 +13836,7 @@ All creatures get -2/-2 until end of turn.
Do or Die Do or Die
1 B 1 B
Sorcery Sorcery
Randomly destroy half of the creatures target player controls. They can't be regenerated. Randomly destroy half of the creatures target player controls. They can't be regenerated.
Cao Cao, Lord of Wei Cao Cao, Lord of Wei
3 B B 3 B B
@@ -14062,7 +14080,7 @@ Until end of turn, target land is 3/3 creature that's still a land.
Kodama's Reach Kodama's Reach
2 G 2 G
Sorcery Sorcery
Search your library for two basic land cards, reveal those cards, and put one into play tapped and the other into your hand. Then shuffle your library. Search your library for two basic land cards, reveal those cards, and put one into play tapped and the other into your hand. Then shuffle your library.
Wandering Stream Wandering Stream
@@ -14811,70 +14829,70 @@ PTPump B:+1/+1
Blood Crypt Blood Crypt
no cost no cost
Land Swamp Mountain Land Swamp Mountain
As Blood Crypt comes into play, you may pay 2 life. If you don't, Blood Crypt comes into play tapped instead. As Blood Crypt comes into play, you may pay 2 life. If you don't, Blood Crypt comes into play tapped instead.
tap: add B tap: add B
tap: add R tap: add R
Breeding Pool Breeding Pool
no cost no cost
Land Forest Island Land Forest Island
As Breeding Pool into play, you may pay 2 life. If you don't, Breeding Pool comes into play tapped instead. As Breeding Pool into play, you may pay 2 life. If you don't, Breeding Pool comes into play tapped instead.
tap: add G tap: add G
tap: add U tap: add U
Godless Shrine Godless Shrine
no cost no cost
Land Plains Swamp Land Plains Swamp
As Godless Shrine comes into play, you may pay 2 life. If you don't, Godless Shrine comes into play tapped instead. As Godless Shrine comes into play, you may pay 2 life. If you don't, Godless Shrine comes into play tapped instead.
tap: add W tap: add W
tap: add B tap: add B
Hallowed Fountain Hallowed Fountain
no cost no cost
Land Plains Island Land Plains Island
As Hallowed Fountain comes into play, you may pay 2 life. If you don't, Hallowed Fountain comes into play tapped instead. As Hallowed Fountain comes into play, you may pay 2 life. If you don't, Hallowed Fountain comes into play tapped instead.
tap: add W tap: add W
tap: add U tap: add U
Overgrown Tomb Overgrown Tomb
no cost no cost
Land Swamp Forest Land Swamp Forest
As Overgrown Tomb comes into play, you may pay 2 life. If you don't, Overgrown Tomb comes into play tapped instead. As Overgrown Tomb comes into play, you may pay 2 life. If you don't, Overgrown Tomb comes into play tapped instead.
tap: add B tap: add B
tap: add G tap: add G
Sacred Foundry Sacred Foundry
no cost no cost
Land Mountain Plains Land Mountain Plains
As Sacred Foundry comes into play, you may pay 2 life. If you don't, Sacred Foundry comes into play tapped instead. As Sacred Foundry comes into play, you may pay 2 life. If you don't, Sacred Foundry comes into play tapped instead.
tap: add R tap: add R
tap: add W tap: add W
Steam Vents Steam Vents
no cost no cost
Land Island Mountain Land Island Mountain
As Steam Vents comes into play, you may pay 2 life. If you don't, Steam Vents comes into play tapped instead. As Steam Vents comes into play, you may pay 2 life. If you don't, Steam Vents comes into play tapped instead.
tap: add U tap: add U
tap: add R tap: add R
Stomping Ground Stomping Ground
no cost no cost
Land Mountain Forest Land Mountain Forest
As Stomping Ground comes into play, you may pay 2 life. If you don't, Stomping Ground comes into play tapped instead. As Stomping Ground comes into play, you may pay 2 life. If you don't, Stomping Ground comes into play tapped instead.
tap: add R tap: add R
tap: add G tap: add G
Temple Garden Temple Garden
no cost no cost
Land Forest Plains Land Forest Plains
As Temple Garden comes into play, you may pay 2 life. If you don't, Temple Garden comes into play tapped instead. As Temple Garden comes into play, you may pay 2 life. If you don't, Temple Garden comes into play tapped instead.
tap: add G tap: add G
tap: add W tap: add W
Watery Grave Watery Grave
no cost no cost
Land Island Swamp Land Island Swamp
As Watery Grave comes into play, you may pay 2 life. If you don't, Watery Grave comes into play tapped instead. As Watery Grave comes into play, you may pay 2 life. If you don't, Watery Grave comes into play tapped instead.
tap: add U tap: add U
tap: add B tap: add B

View File

@@ -1,6 +1,6 @@
program/mail=mtgerror@yahoo.com program/mail=mtgerror@yahoo.com
program/forum=http://www.slightlymagic.net/forum/viewforum.php?f=26 program/forum=http://www.slightlymagic.net/forum/viewforum.php?f=26
program/version=Forge -- official beta: 09/11/25, SVN revision: 142 program/version=Forge -- official beta: 09/11/25, SVN revision: 181
tokens--file=AllTokens.txt tokens--file=AllTokens.txt

View File

@@ -2,11 +2,8 @@ package forge;
//TODO: make this class a type of Ability //TODO: make this class a type of Ability
abstract public class Ability_Hand extends SpellAbility implements java.io.Serializable abstract public class Ability_Hand extends SpellAbility implements java.io.Serializable
{ {
/**
* private static final long serialVersionUID = 7782525158887272529L;
*/
private static final long serialVersionUID = 1L;
public Ability_Hand(Card sourceCard) public Ability_Hand(Card sourceCard)
{ {
this(sourceCard, ""); this(sourceCard, "");

View File

@@ -5,6 +5,7 @@ enum Counters {
AGE, BLAZE, CHARGE, DIVINITY, FADE, HOOFPRINT, ICE, LOYALTY, M1M1, MANA, P0M1, P1P1, QUEST, SPORE AGE, BLAZE, CHARGE, DIVINITY, FADE, HOOFPRINT, ICE, LOYALTY, M1M1, MANA, P0M1, P1P1, QUEST, SPORE
} }
public class Card extends MyObservable public class Card extends MyObservable
{ {
private static int nextUniqueNumber; private static int nextUniqueNumber;
@@ -485,17 +486,27 @@ public class Card extends MyObservable
public String getRarity() {return rarity;} public String getRarity() {return rarity;}
public void addDamage(int n, CardList sources) public void addDamage(HashMap<Card, Integer> sourcesMap)
{ {
for(Card source : sources) Iterator<Card> iter = sourcesMap.keySet().iterator();
this.addDamage(n, source); while(iter.hasNext()) {
Card source = iter.next();
int damage = sourcesMap.get(source);
this.addDamage(damage, source);
}
//for(Card source : sources)
// this.addDamage(n, source);
} }
public void addDamage(int n, Card source) public void addDamage(int n, Card source)
{ {
System.out.println("addDamage called on " + this + " for " + n + " damage.");
if (this.getName().equals("Cho-Manno, Revolutionary")) if (this.getName().equals("Cho-Manno, Revolutionary"))
n = 0; n = 0;
setDamage(getDamage() + n); //setDamage(getDamage() + n);
damage += n;
} }
public void setDamage(int n) public void setDamage(int n)
{ {

View File

@@ -17217,10 +17217,12 @@ return land.size() > 1 && CardFactoryUtil.AI_isMainPhase();
return c.isCreature() && !c.getKeyword().contains("Horsemanship") && !c.getKeyword().contains("Defender"); return c.isCreature() && !c.getKeyword().contains("Horsemanship") && !c.getKeyword().contains("Defender");
} }
}); });
if (list.size() > 0) {
Card c = CardFactoryUtil.AI_getBestCreature(list, card); Card c = CardFactoryUtil.AI_getBestCreature(list, card);
setTargetCard(c); setTargetCard(c);
return list.size() > 0; return true;
}
return false;
} }
public void resolve() public void resolve()

View File

@@ -18358,7 +18358,7 @@ public class CardFactory_Creatures {
{ {
final Card newCard = new Card() final Card newCard = new Card()
{ {
public void addDamage(final int n, CardList sources) public void addDamage(HashMap<Card, Integer> map)
{ {
final Ability ability = new Ability(card, "0") final Ability ability = new Ability(card, "0")
{ {
@@ -18458,6 +18458,110 @@ public class CardFactory_Creatures {
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END ************************** }//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Lichentrope"))
{
final Card newCard = new Card()
{
public void addDamage(final int n, final Card source)
{
final Ability ability = new Ability(card, "0")
{
public void resolve(){
for (int i=0;i<n;i++)
card.addCounter(Counters.M1M1, n);
}
};
ability.setStackDescription(card.getName() + " - gets " + n +" -1/-1 counters.");
AllZone.Stack.add(ability);
}
};
newCard.setOwner(card.getOwner());
newCard.setController(card.getController());
newCard.setManaCost(card.getManaCost());
newCard.setName(card.getName());
newCard.addType("Creature");
newCard.addType("Plant");
newCard.addType("Fungus");
newCard.setText(card.getSpellText());
newCard.setBaseAttack(card.getBaseAttack());
newCard.setBaseDefense(card.getBaseDefense());
newCard.addSpellAbility(new Spell_Permanent(newCard));
return newCard;
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Phytohydra"))
{
final Card newCard = new Card()
{
public void addDamage(final int n, final Card source)
{
final Ability ability = new Ability(card, "0")
{
public void resolve(){
for (int i=0;i<n;i++)
card.addCounter(Counters.P1P1, n);
}
};
ability.setStackDescription(card.getName() + " - gets " + n +" +1/+1 counters.");
AllZone.Stack.add(ability);
}
};
newCard.setOwner(card.getOwner());
newCard.setController(card.getController());
newCard.setManaCost(card.getManaCost());
newCard.setName(card.getName());
newCard.addType("Creature");
newCard.addType("Plant");
newCard.addType("Hydra");
newCard.setText(card.getSpellText());
newCard.setBaseAttack(card.getBaseAttack());
newCard.setBaseDefense(card.getBaseDefense());
newCard.addSpellAbility(new Spell_Permanent(newCard));
return newCard;
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Callous Giant"))
{
final Card newCard = new Card()
{
public void addDamage(int n, Card source)
{
if (n <= 3)
n = 0;
super.addDamage(n, source);
}
};
newCard.setOwner(card.getOwner());
newCard.setController(card.getController());
newCard.setManaCost(card.getManaCost());
newCard.setName(card.getName());
newCard.addType("Creature");
newCard.addType("Giant");
newCard.setText(card.getSpellText());
newCard.setBaseAttack(card.getBaseAttack());
newCard.setBaseDefense(card.getBaseDefense());
newCard.addSpellAbility(new Spell_Permanent(newCard));
return newCard;
}//*************** END ************ END **************************
// Cards with Cycling abilities // Cards with Cycling abilities
// -1 means keyword "Cycling" not found // -1 means keyword "Cycling" not found
if (shouldCycle(card) != -1) if (shouldCycle(card) != -1)

View File

@@ -1,8 +1,22 @@
package forge; package forge;
import java.util.ArrayList;
class CardFactory_Lands { class CardFactory_Lands {
private static final int hasKeyword(Card c, String k)
{
ArrayList<String> a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if (a.get(i).toString().startsWith(k))
return i;
return -1;
}
public static Card getCard(final Card card, String cardName, String owner) public static Card getCard(final Card card, String cardName, String owner)
{ {
// computer plays 2 land of these type instead of just 1 per turn // computer plays 2 land of these type instead of just 1 per turn
@@ -2933,6 +2947,54 @@ class CardFactory_Lands {
}; };
a1.setBeforePayMana(new Input_PayManaCost_Ability(a1.getManaCost(), paid1)); a1.setBeforePayMana(new Input_PayManaCost_Ability(a1.getManaCost(), paid1));
}//*************** END ************ END ************************** }//*************** END ************ END **************************
if (hasKeyword(card, "Cycling") != -1)
{
int n = hasKeyword(card, "Cycling");
if (n != -1)
{
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
final String manacost = k[1];
card.addSpellAbility(CardFactoryUtil.ability_cycle(card, manacost));
}
}//Cycling
while (hasKeyword(card, "TypeCycling") != -1)
{
int n = hasKeyword(card, "TypeCycling");
if (n != -1)
{
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
final String type = k[1];
final String manacost = k[2];
card.addSpellAbility(CardFactoryUtil.ability_typecycle(card, manacost,type));
}
}//TypeCycling
if (hasKeyword(card, "Transmute") != -1)
{
int n = hasKeyword(card, "Transmute");
if (n != -1)
{
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
final String manacost = k[1];
card.addSpellAbility(CardFactoryUtil.ability_transmute(card, manacost));
}
}//transmute
return card; return card;

View File

@@ -223,7 +223,7 @@ public class Combat
CardList attacking = new CardList(getAttackers()); CardList attacking = new CardList(getAttackers());
for(int i = 0; i < attacking.size(); i++) for(int i = 0; i < attacking.size(); i++)
{ {
if(attacking.get(i).hasFirstStrike() || (attacking.get(i).hasDoubleStrike() )){ //if(attacking.get(i).hasFirstStrike() || (attacking.get(i).hasDoubleStrike() )){
block = getBlockers(attacking.get(i)); block = getBlockers(attacking.get(i));
//attacker always gets all blockers' attack //attacker always gets all blockers' attack
@@ -245,56 +245,61 @@ public class Combat
//GameActionUtil.executePlayerCombatDamageEffects(attacking.get(i)); //GameActionUtil.executePlayerCombatDamageEffects(attacking.get(i));
addUnblockedAttacker(attacking.get(i)); addUnblockedAttacker(attacking.get(i));
} }
else if(block.size() == 1)
{ else if(attacking.get(i).hasFirstStrike() || (attacking.get(i).hasDoubleStrike() )){
if(attacking.get(i).hasFirstStrike() || attacking.get(i).hasDoubleStrike()){
int damageDealt = attacking.get(i).getNetAttack(); if(block.size() == 1)
if (CombatUtil.isDoranInPlay()) {
damageDealt = attacking.get(i).getNetDefense(); if(attacking.get(i).hasFirstStrike() || attacking.get(i).hasDoubleStrike()){
int damageDealt = attacking.get(i).getNetAttack();
CardList cl = new CardList(); if (CombatUtil.isDoranInPlay())
cl.add(attacking.get(i)); damageDealt = attacking.get(i).getNetDefense();
AllZone.GameAction.addAssignedDamage(block.get(0), attacking.get(i), damageDealt); CardList cl = new CardList();
cl.add(attacking.get(i));
//trample AllZone.GameAction.addAssignedDamage(block.get(0), attacking.get(i), damageDealt);
int trample = damageDealt - block.get(0).getNetDefense();
if(attacking.get(i).getKeyword().contains("Trample") && 0 < trample)
{ //trample
this.addDefendingFirstStrikeDamage(trample, attacking.get(i)); int trample = damageDealt - block.get(0).getNetDefense();
//System.out.println("First Strike trample damage: " + trample); if(attacking.get(i).getKeyword().contains("Trample") && 0 < trample)
} {
} this.addDefendingFirstStrikeDamage(trample, attacking.get(i));
}//1 blocker //System.out.println("First Strike trample damage: " + trample);
else if(getAttackingPlayer().equals(Constant.Player.Computer)) }
{ }
if(attacking.get(i).hasFirstStrike() || attacking.get(i).hasDoubleStrike()){ }//1 blocker
int damageDealt = attacking.get(i).getNetAttack(); else if(getAttackingPlayer().equals(Constant.Player.Computer))
if (CombatUtil.isDoranInPlay()) {
damageDealt = attacking.get(i).getNetDefense(); if(attacking.get(i).hasFirstStrike() || attacking.get(i).hasDoubleStrike()){
addAssignedFirstStrikeDamage(attacking.get(i), block, damageDealt); int damageDealt = attacking.get(i).getNetAttack();
} if (CombatUtil.isDoranInPlay())
} damageDealt = attacking.get(i).getNetDefense();
else//human addAssignedFirstStrikeDamage(attacking.get(i), block, damageDealt);
{ }
if(attacking.get(i).hasFirstStrike() || attacking.get(i).hasDoubleStrike()){ }
//GuiDisplay2 gui = (GuiDisplay2) AllZone.Display; else//human
int damageDealt = attacking.get(i).getNetAttack(); {
if (CombatUtil.isDoranInPlay()) if(attacking.get(i).hasFirstStrike() || attacking.get(i).hasDoubleStrike()){
damageDealt = attacking.get(i).getNetDefense(); //GuiDisplay2 gui = (GuiDisplay2) AllZone.Display;
AllZone.Display.assignDamage(attacking.get(i),block, damageDealt); int damageDealt = attacking.get(i).getNetAttack();
if (CombatUtil.isDoranInPlay())
/* damageDealt = attacking.get(i).getNetDefense();
for (Card b : block) AllZone.Display.assignDamage(attacking.get(i),block, damageDealt);
{
AllZone.Display.assignDamage(attacking.get(i), b, damageDealt); /*
//System.out.println("setAssignedFirstStrikeDmg called for:" + damageDealt + " damage."); for (Card b : block)
} {
AllZone.Display.addAssignDamage(attacking.get(i),damageDealt); AllZone.Display.assignDamage(attacking.get(i), b, damageDealt);
*/ //System.out.println("setAssignedFirstStrikeDmg called for:" + damageDealt + " damage.");
} }
}//if(hasFirstStrike || doubleStrike) AllZone.Display.addAssignDamage(attacking.get(i),damageDealt);
*/
}
}
}//if(hasFirstStrike || doubleStrike)
}//for }//for
//should first strike affect the following? //should first strike affect the following?
@@ -312,7 +317,6 @@ public class Combat
defendingFirstStrikeDamageMap.clear(); defendingFirstStrikeDamageMap.clear();
} }
}
}//setAssignedFirstStrikeDamage() }//setAssignedFirstStrikeDamage()
private void addAssignedFirstStrikeDamage (Card attacker, CardList block, int damage) private void addAssignedFirstStrikeDamage (Card attacker, CardList block, int damage)
@@ -320,16 +324,24 @@ public class Combat
Card c = attacker; Card c = attacker;
for (Card b:block) { for (Card b:block) {
if(c.getKillDamage() <= damage) if(b.getKillDamage() <= damage)
{ {
damage -= c.getKillDamage(); damage -= b.getKillDamage();
CardList cl = new CardList(); CardList cl = new CardList();
cl.add(attacker); cl.add(attacker);
AllZone.GameAction.addAssignedDamage(b, c, c.getKillDamage()); AllZone.GameAction.addAssignedDamage(b, c, b.getKillDamage());
//c.setAssignedDamage(c.getKillDamage()); //c.setAssignedDamage(c.getKillDamage());
} }
}//for }//for
//if attacker has no trample, and there's damage left, assign the rest to a random blocker
if (damage > 0)
{
int index = CardUtil.getRandomIndex(block);
AllZone.GameAction.addAssignedDamage(block.get(index), c, damage);
damage = 0;
}
}//setAssignedFirstStrikeDamage() }//setAssignedFirstStrikeDamage()
@@ -343,8 +355,8 @@ public class Combat
CardList attacking = new CardList(getAttackers()); CardList attacking = new CardList(getAttackers());
for(int i = 0; i < attacking.size(); i++) for(int i = 0; i < attacking.size(); i++)
{ {
//if(!attacking.get(i).hasSecondStrike() ){ //if(!attacking.get(i).hasSecondStrike() ){
if(!attacking.get(i).hasFirstStrike() || (attacking.get(i).hasFirstStrike() && attacking.get(i).hasDoubleStrike() )){ //if(!attacking.get(i).hasFirstStrike() || (attacking.get(i).hasFirstStrike() && attacking.get(i).hasDoubleStrike() )){
block = getBlockers(attacking.get(i)); block = getBlockers(attacking.get(i));
//attacker always gets all blockers' attack //attacker always gets all blockers' attack
@@ -353,10 +365,12 @@ public class Combat
for (Card b : block) for (Card b : block)
{ {
int attack = b.getNetAttack(); if(!b.hasFirstStrike() || (b.hasFirstStrike() && b.hasDoubleStrike() )){
if (CombatUtil.isDoranInPlay()) int attack = b.getNetAttack();
attack = b.getNetDefense(); if (CombatUtil.isDoranInPlay())
AllZone.GameAction.addAssignedDamage(attacking.get(i), b, attack ); attack = b.getNetDefense();
AllZone.GameAction.addAssignedDamage(attacking.get(i), b, attack );
}
} }
if(block.size() == 0)//this damage is assigned to a player by setPlayerDamage() if(block.size() == 0)//this damage is assigned to a player by setPlayerDamage()
@@ -364,49 +378,54 @@ public class Combat
//GameActionUtil.executePlayerCombatDamageEffects(attacking.get(i)); //GameActionUtil.executePlayerCombatDamageEffects(attacking.get(i));
addUnblockedAttacker(attacking.get(i)); addUnblockedAttacker(attacking.get(i));
} }
else if(block.size() == 1)
{ else if(!attacking.get(i).hasFirstStrike() || (attacking.get(i).hasFirstStrike() && attacking.get(i).hasDoubleStrike() )){
int damageDealt = attacking.get(i).getNetAttack();
if (CombatUtil.isDoranInPlay()) if(block.size() == 1)
damageDealt = attacking.get(i).getNetDefense(); {
int damageDealt = attacking.get(i).getNetAttack();
AllZone.GameAction.addAssignedDamage(block.get(0), attacking.get(i), damageDealt); if (CombatUtil.isDoranInPlay())
damageDealt = attacking.get(i).getNetDefense();
//trample
int trample = damageDealt - block.get(0).getNetDefense(); AllZone.GameAction.addAssignedDamage(block.get(0), attacking.get(i), damageDealt);
if(attacking.get(i).getKeyword().contains("Trample") && 0 < trample)
{ //trample
this.addDefendingDamage(trample, attacking.get(i)); int trample = damageDealt - block.get(0).getNetDefense();
} if(attacking.get(i).getKeyword().contains("Trample") && 0 < trample)
}//1 blocker {
else if(getAttackingPlayer().equals(Constant.Player.Computer)) this.addDefendingDamage(trample, attacking.get(i));
{ }
int damageDealt = attacking.get(i).getNetAttack(); }//1 blocker
if (CombatUtil.isDoranInPlay()) else if(getAttackingPlayer().equals(Constant.Player.Computer))
damageDealt = attacking.get(i).getNetDefense(); {
addAssignedDamage(attacking.get(i),block , damageDealt); int damageDealt = attacking.get(i).getNetAttack();
if (CombatUtil.isDoranInPlay())
} damageDealt = attacking.get(i).getNetDefense();
else//human addAssignedDamage(attacking.get(i),block , damageDealt);
{
//GuiDisplay2 gui = (GuiDisplay2) AllZone.Display; }
int damageDealt = attacking.get(i).getNetAttack(); else//human attacks
if (CombatUtil.isDoranInPlay()) {
damageDealt = attacking.get(i).getNetDefense(); //GuiDisplay2 gui = (GuiDisplay2) AllZone.Display;
int damageDealt = attacking.get(i).getNetAttack();
AllZone.Display.assignDamage(attacking.get(i), block, damageDealt); if (CombatUtil.isDoranInPlay())
damageDealt = attacking.get(i).getNetDefense();
/*
* AllZone.Display.assignDamage(attacking.get(i), block, damageDealt);
*
for (Card b :block) /*
AllZone.Display.addAssignDamage(attacking.get(i), b, damageDealt); *
//System.out.println("setAssignedDmg called for:" + damageDealt + " damage."); *
* for (Card b :block)
*/ AllZone.Display.addAssignDamage(attacking.get(i), b, damageDealt);
} //System.out.println("setAssignedDmg called for:" + damageDealt + " damage.");
}//if !hasFirstStrike ... *
*/
}
}//if !hasFirstStrike ...
//hacky code, to ensure surviving non-first-strike blockers will hit first strike attackers: //hacky code, to ensure surviving non-first-strike blockers will hit first strike attackers:
/*
else { else {
block = getBlockers(attacking.get(i)); block = getBlockers(attacking.get(i));
//System.out.println("block size: " + block.size()); //System.out.println("block size: " + block.size());
@@ -424,6 +443,7 @@ public class Combat
//AllZone.GameAction.setAssignedDamage(attacking.get(i), block , blockerDamage); //AllZone.GameAction.setAssignedDamage(attacking.get(i), block , blockerDamage);
} }
} }
*/
}//for }//for
//should first strike affect the following? //should first strike affect the following?
@@ -465,16 +485,24 @@ public class Combat
{ {
Card c = attacker; Card c = attacker;
for (Card b:block) { for (Card b:block) {
if(c.getKillDamage() <= damage) if(b.getKillDamage() <= damage)
{ {
damage -= c.getKillDamage(); damage -= b.getKillDamage();
CardList cl = new CardList(); CardList cl = new CardList();
cl.add(attacker); cl.add(attacker);
AllZone.GameAction.addAssignedDamage(b, c, c.getKillDamage()); AllZone.GameAction.addAssignedDamage(b, c, b.getKillDamage());
//c.setAssignedDamage(c.getKillDamage()); //c.setAssignedDamage(c.getKillDamage());
} }
}//for }//for
//if attacker has no trample, and there's damage left, assign the rest to a random blocker
if (damage > 0 && !c.getKeyword().contains("Trample"))
{
int index = CardUtil.getRandomIndex(block);
AllZone.GameAction.addAssignedDamage(block.get(index), c, damage);
damage = 0;
}
}//setAssignedDamage() }//setAssignedDamage()
public Card[] getUnblockedAttackers() public Card[] getUnblockedAttackers()

View File

@@ -1139,31 +1139,72 @@ private int getDifferentLand(CardList list, String land)
} }
public void playCard(Card c) public void playCard(Card c)
{ {
if (c.isLand() && isCardInZone(c, AllZone.Human_Hand))
//TODO: add code for cards like Standstill ?? {
HashMap<String, SpellAbility> map = new HashMap<String, SpellAbility>();
SpellAbility[] sas = canPlaySpellAbility(c.getSpellAbility());
ArrayList<String> choices = new ArrayList<String>();
if (Input_Main.canPlayNumberOfLands > 0)
choices.add("Play land");
for (SpellAbility sa: sas)
{
if (sa.canPlay())
{
choices.add(sa.toString());
map.put(sa.toString(), sa);
}
}
//String[] ch = (String[])choices.toArray();
String[] ch = new String[choices.size()];
for (int i=0;i<choices.size();i++)
{
ch[i] = choices.get(i);
}
String choice = AllZone.Display.getChoiceOptional("Choose", ch);
if (choice == null)
;
else if (choice.equals("Play land"))
{
AllZone.Human_Hand.remove(c);
AllZone.Human_Play.add(c);
Input_Main.canPlayNumberOfLands--;
Input_Main.firstLandHasBeenPlayed = true;
}
else
{
SpellAbility sa = map.get(choice);
playSpellAbility(sa);
}
}
else
{
SpellAbility[] choices = canPlaySpellAbility(c.getSpellAbility());
SpellAbility sa;
/*
System.out.println(choices.length);
for(int i = 0; i < choices.length; i++)
System.out.println(choices[i]);
*/
if(choices.length == 0)
return;
else if(choices.length == 1)
sa = choices[0];
else
sa = (SpellAbility) AllZone.Display.getChoiceOptional("Choose", choices);
SpellAbility[] choices = canPlaySpellAbility(c.getSpellAbility()); if(sa == null)
SpellAbility sa; return;
/*
System.out.println(choices.length); playSpellAbility(sa);
for(int i = 0; i < choices.length; i++) }
System.out.println(choices[i]);
*/
if(choices.length == 0)
return;
else if(choices.length == 1)
sa = choices[0];
else
sa = (SpellAbility) AllZone.Display.getChoiceOptional("Choose", choices);
if(sa == null)
return;
playSpellAbility(sa);
} }
public void playSpellAbility(SpellAbility sa) public void playSpellAbility(SpellAbility sa)
{ {
if (sa.getManaCost().equals("0") && sa.getBeforePayMana() == null){ if (sa.getManaCost().equals("0") && sa.getBeforePayMana() == null){
AllZone.Stack.add(sa); AllZone.Stack.add(sa);
if (sa.isTapAbility()) if (sa.isTapAbility())
@@ -1269,7 +1310,7 @@ private int getDifferentLand(CardList list, String land)
public void addDamage(Card card, HashMap<Card,Integer> map) public void addDamage(Card card, HashMap<Card,Integer> map)
{ {
int totalDamage = 0; //int totalDamage = 0;
CardList list = new CardList(); CardList list = new CardList();
Iterator<Card> iter = map.keySet().iterator(); Iterator<Card> iter = map.keySet().iterator();
@@ -1305,11 +1346,12 @@ private int getDifferentLand(CardList list, String land)
AllZone.Combat.removeFromCombat(card); AllZone.Combat.removeFromCombat(card);
} }
totalDamage += damageToAdd; //totalDamage += damageToAdd;
map.put(source, damageToAdd);
} }
if (isCardInPlay(card)) if (isCardInPlay(card))
card.addDamage(totalDamage, list); card.addDamage(map);
} }

View File

@@ -21,6 +21,7 @@ public class GameActionUtil
upkeep_Squee(); upkeep_Squee();
upkeep_Sporesower_Thallid(); upkeep_Sporesower_Thallid();
upkeep_Scute_Mob(); upkeep_Scute_Mob();
upkeep_Lichentrope();
upkeep_Heartmender(); upkeep_Heartmender();
upkeep_AEther_Vial(); upkeep_AEther_Vial();
upkeep_Ratcatcher(); upkeep_Ratcatcher();
@@ -4290,6 +4291,38 @@ public class GameActionUtil
} // if creatures > 0 } // if creatures > 0
} }
private static void upkeep_Lichentrope()
{
final String player = AllZone.Phase.getActivePlayer();
PlayerZone playZone = AllZone.getZone(Constant.Zone.Play, player);
CardList list = new CardList(playZone.getCards());
list = list.getName("LichenTrope");
final CardList cl = list;
if (list.size() > 0)
{
for (int i = 0; i < list.size(); i++)
{
final int j = i;
Ability ability = new Ability(list.get(i), "0")
{
public void resolve()
{
Card c = cl.get(j);
c.subtractCounter(Counters.M1M1, 1);
}
};// Ability
ability.setStackDescription("Lichentrope - Remove a -1/-1 counter.");
AllZone.Stack.add(ability);
} // for
} // if creatures > 0
}//Lichentrope
private static void upkeep_Heartmender() private static void upkeep_Heartmender()
{ {
final String player = AllZone.Phase.getActivePlayer(); final String player = AllZone.Phase.getActivePlayer();

View File

@@ -16,9 +16,35 @@ public class InputUtil
if(zone.is(Constant.Zone.Hand, Constant.Player.Human) && if(zone.is(Constant.Zone.Hand, Constant.Player.Human) &&
(card.isLand())) (card.isLand()))
{ {
AllZone.Human_Hand.remove(card);
AllZone.Human_Play.add(card); //hacky stuff: see if there's cycling/transmute/other hand abilities on the land:
} SpellAbility[] sa = card.getSpellAbility();
if (sa.length > 0)
{
int count = 0;
for (SpellAbility s : sa)
{
if (s.canPlay() && (s instanceof Ability_Hand))
count++;
}
if (count > 0)
AllZone.GameAction.playCard(card);
else //play the land
{
AllZone.Human_Hand.remove(card);
AllZone.Human_Play.add(card);
Input_Main.canPlayNumberOfLands--;
Input_Main.firstLandHasBeenPlayed = true;
}
}
else //play the land
{
AllZone.Human_Hand.remove(card);
AllZone.Human_Play.add(card);
Input_Main.canPlayNumberOfLands--;
Input_Main.firstLandHasBeenPlayed = true;
}
} //land
else if(zone.is(Constant.Zone.Hand, Constant.Player.Human) && else if(zone.is(Constant.Zone.Hand, Constant.Player.Human) &&
card.getManaCost().equals("0"))//for Mox Ruby and the like card.getManaCost().equals("0"))//for Mox Ruby and the like
{ {

View File

@@ -43,11 +43,26 @@ public class Input_Main extends Input
} }
} }
InputUtil.playAnyCard(card, zone); InputUtil.playAnyCard(card, zone);
canPlayNumberOfLands--; //canPlayNumberOfLands--;
firstLandHasBeenPlayed = true; //firstLandHasBeenPlayed = true;
AllZone.GameAction.checkStateEffects(); AllZone.GameAction.checkStateEffects();
} }
//card might have cycling/transmute/etc.
else {
SpellAbility[] sa = card.getSpellAbility();
if (sa.length > 0)
{
int count = 0;
for (SpellAbility s : sa)
{
if (s.canPlay() && (s instanceof Ability_Hand))
count++;
}
if (count > 0)
InputUtil.playAnyCard(card, zone);
}
}
//TODO: add code for exploration / fastbond here //TODO: add code for exploration / fastbond here
} }