mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
-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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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, "");
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user