*Added Haunt keyword

*Added
	Absolver Thrull
	Belfry Spirit
	Benediction of Moons
	Blind Hunter
	Cry of Contrition
	Exhumer Thrull
	Graven Dominator
	Orzhov Euthanist
	Seize the Soul
This commit is contained in:
Hellfish
2011-09-20 16:16:52 +00:00
parent 7bf5ccc6e9
commit 75221cacbb
14 changed files with 376 additions and 4 deletions

9
.gitattributes vendored
View File

@@ -31,6 +31,7 @@ res/cardsfolder/a/aboshans_desire.txt svneol=native#text/plain
res/cardsfolder/a/about_face.txt svneol=native#text/plain res/cardsfolder/a/about_face.txt svneol=native#text/plain
res/cardsfolder/a/absolute_grace.txt svneol=native#text/plain res/cardsfolder/a/absolute_grace.txt svneol=native#text/plain
res/cardsfolder/a/absolute_law.txt svneol=native#text/plain res/cardsfolder/a/absolute_law.txt svneol=native#text/plain
res/cardsfolder/a/absolver_thrull.txt -text
res/cardsfolder/a/absorb.txt svneol=native#text/plain res/cardsfolder/a/absorb.txt svneol=native#text/plain
res/cardsfolder/a/absorb_vis.txt svneol=native#text/plain res/cardsfolder/a/absorb_vis.txt svneol=native#text/plain
res/cardsfolder/a/abuna_acolyte.txt svneol=native#text/plain res/cardsfolder/a/abuna_acolyte.txt svneol=native#text/plain
@@ -654,6 +655,7 @@ res/cardsfolder/b/behemoth_sledge.txt svneol=native#text/plain
res/cardsfolder/b/belbes_armor.txt svneol=native#text/plain res/cardsfolder/b/belbes_armor.txt svneol=native#text/plain
res/cardsfolder/b/belbes_percher.txt svneol=native#text/plain res/cardsfolder/b/belbes_percher.txt svneol=native#text/plain
res/cardsfolder/b/belbes_portal.txt svneol=native#text/plain res/cardsfolder/b/belbes_portal.txt svneol=native#text/plain
res/cardsfolder/b/belfry_spirit.txt -text
res/cardsfolder/b/belligerent_hatchling.txt svneol=native#text/plain res/cardsfolder/b/belligerent_hatchling.txt svneol=native#text/plain
res/cardsfolder/b/bellowing_fiend.txt svneol=native#text/plain res/cardsfolder/b/bellowing_fiend.txt svneol=native#text/plain
res/cardsfolder/b/bellowing_tanglewurm.txt svneol=native#text/plain res/cardsfolder/b/bellowing_tanglewurm.txt svneol=native#text/plain
@@ -667,6 +669,7 @@ res/cardsfolder/b/benalish_knight.txt svneol=native#text/plain
res/cardsfolder/b/benalish_missionary.txt svneol=native#text/plain res/cardsfolder/b/benalish_missionary.txt svneol=native#text/plain
res/cardsfolder/b/benalish_trapper.txt svneol=native#text/plain res/cardsfolder/b/benalish_trapper.txt svneol=native#text/plain
res/cardsfolder/b/benalish_veteran.txt svneol=native#text/plain res/cardsfolder/b/benalish_veteran.txt svneol=native#text/plain
res/cardsfolder/b/benediction_of_moons.txt -text
res/cardsfolder/b/benevolent_ancestor.txt svneol=native#text/plain res/cardsfolder/b/benevolent_ancestor.txt svneol=native#text/plain
res/cardsfolder/b/benevolent_bodyguard.txt svneol=native#text/plain res/cardsfolder/b/benevolent_bodyguard.txt svneol=native#text/plain
res/cardsfolder/b/benevolent_unicorn.txt svneol=native#text/plain res/cardsfolder/b/benevolent_unicorn.txt svneol=native#text/plain
@@ -756,6 +759,7 @@ res/cardsfolder/b/blightspeaker.txt svneol=native#text/plain
res/cardsfolder/b/blightsteel_colossus.txt svneol=native#text/plain res/cardsfolder/b/blightsteel_colossus.txt svneol=native#text/plain
res/cardsfolder/b/blightwidow.txt svneol=native#text/plain res/cardsfolder/b/blightwidow.txt svneol=native#text/plain
res/cardsfolder/b/blind_creeper.txt svneol=native#text/plain res/cardsfolder/b/blind_creeper.txt svneol=native#text/plain
res/cardsfolder/b/blind_hunter.txt -text
res/cardsfolder/b/blind_phantasm.txt svneol=native#text/plain res/cardsfolder/b/blind_phantasm.txt svneol=native#text/plain
res/cardsfolder/b/blind_spot_giant.txt svneol=native#text/plain res/cardsfolder/b/blind_spot_giant.txt svneol=native#text/plain
res/cardsfolder/b/blind_with_anger.txt svneol=native#text/plain res/cardsfolder/b/blind_with_anger.txt svneol=native#text/plain
@@ -1570,6 +1574,7 @@ res/cardsfolder/c/crush.txt svneol=native#text/plain
res/cardsfolder/c/crush_of_wurms.txt svneol=native#text/plain res/cardsfolder/c/crush_of_wurms.txt svneol=native#text/plain
res/cardsfolder/c/crusher_zendikon.txt svneol=native#text/plain res/cardsfolder/c/crusher_zendikon.txt svneol=native#text/plain
res/cardsfolder/c/crushing_pain.txt svneol=native#text/plain res/cardsfolder/c/crushing_pain.txt svneol=native#text/plain
res/cardsfolder/c/cry_of_contrition.txt -text
res/cardsfolder/c/cryoclasm.txt svneol=native#text/plain res/cardsfolder/c/cryoclasm.txt svneol=native#text/plain
res/cardsfolder/c/crypt_angel.txt svneol=native#text/plain res/cardsfolder/c/crypt_angel.txt svneol=native#text/plain
res/cardsfolder/c/crypt_cobra.txt svneol=native#text/plain res/cardsfolder/c/crypt_cobra.txt svneol=native#text/plain
@@ -2391,6 +2396,7 @@ res/cardsfolder/e/execute.txt svneol=native#text/plain
res/cardsfolder/e/executioners_capsule.txt svneol=native#text/plain res/cardsfolder/e/executioners_capsule.txt svneol=native#text/plain
res/cardsfolder/e/exhaustion.txt svneol=native#text/plain res/cardsfolder/e/exhaustion.txt svneol=native#text/plain
res/cardsfolder/e/exhume.txt svneol=native#text/plain res/cardsfolder/e/exhume.txt svneol=native#text/plain
res/cardsfolder/e/exhumer_thrull.txt -text
res/cardsfolder/e/exile.txt svneol=native#text/plain res/cardsfolder/e/exile.txt svneol=native#text/plain
res/cardsfolder/e/exile_into_darkness.txt svneol=native#text/plain res/cardsfolder/e/exile_into_darkness.txt svneol=native#text/plain
res/cardsfolder/e/exiled_boggart.txt svneol=native#text/plain res/cardsfolder/e/exiled_boggart.txt svneol=native#text/plain
@@ -3222,6 +3228,7 @@ res/cardsfolder/g/gravel_slinger.txt svneol=native#text/plain
res/cardsfolder/g/gravelgill_axeshark.txt svneol=native#text/plain res/cardsfolder/g/gravelgill_axeshark.txt svneol=native#text/plain
res/cardsfolder/g/gravelgill_duo.txt svneol=native#text/plain res/cardsfolder/g/gravelgill_duo.txt svneol=native#text/plain
res/cardsfolder/g/graven_cairns.txt svneol=native#text/plain res/cardsfolder/g/graven_cairns.txt svneol=native#text/plain
res/cardsfolder/g/graven_dominator.txt -text
res/cardsfolder/g/gravespawn_sovereign.txt svneol=native#text/plain res/cardsfolder/g/gravespawn_sovereign.txt svneol=native#text/plain
res/cardsfolder/g/gravitational_shift.txt svneol=native#text/plain res/cardsfolder/g/gravitational_shift.txt svneol=native#text/plain
res/cardsfolder/g/gravity_sphere.txt -text res/cardsfolder/g/gravity_sphere.txt -text
@@ -5373,6 +5380,7 @@ res/cardsfolder/o/orochi_ranger.txt svneol=native#text/plain
res/cardsfolder/o/orochi_sustainer.txt svneol=native#text/plain res/cardsfolder/o/orochi_sustainer.txt svneol=native#text/plain
res/cardsfolder/o/oros_the_avenger.txt svneol=native#text/plain res/cardsfolder/o/oros_the_avenger.txt svneol=native#text/plain
res/cardsfolder/o/orzhov_basilica.txt svneol=native#text/plain res/cardsfolder/o/orzhov_basilica.txt svneol=native#text/plain
res/cardsfolder/o/orzhov_euthanist.txt -text
res/cardsfolder/o/orzhov_guildmage.txt svneol=native#text/plain res/cardsfolder/o/orzhov_guildmage.txt svneol=native#text/plain
res/cardsfolder/o/orzhov_signet.txt svneol=native#text/plain res/cardsfolder/o/orzhov_signet.txt svneol=native#text/plain
res/cardsfolder/o/orzhova_the_church_of_deals.txt svneol=native#text/plain res/cardsfolder/o/orzhova_the_church_of_deals.txt svneol=native#text/plain
@@ -6594,6 +6602,7 @@ res/cardsfolder/s/seismic_spike.txt svneol=native#text/plain
res/cardsfolder/s/seismic_strike.txt svneol=native#text/plain res/cardsfolder/s/seismic_strike.txt svneol=native#text/plain
res/cardsfolder/s/seizan_perverter_of_truth.txt svneol=native#text/plain res/cardsfolder/s/seizan_perverter_of_truth.txt svneol=native#text/plain
res/cardsfolder/s/seize_the_initiative.txt svneol=native#text/plain res/cardsfolder/s/seize_the_initiative.txt svneol=native#text/plain
res/cardsfolder/s/seize_the_soul.txt -text
res/cardsfolder/s/seizures.txt svneol=native#text/plain res/cardsfolder/s/seizures.txt svneol=native#text/plain
res/cardsfolder/s/sejiri_merfolk.txt svneol=native#text/plain res/cardsfolder/s/sejiri_merfolk.txt svneol=native#text/plain
res/cardsfolder/s/sejiri_refuge.txt svneol=native#text/plain res/cardsfolder/s/sejiri_refuge.txt svneol=native#text/plain

View File

@@ -0,0 +1,10 @@
Name:Absolver Thrull
ManaCost:3 W
Types:Creature Thrull Cleric
Text:no text
PT:2/3
K:Haunt:TrigDestroy:Destroy target enchantment.
SVar:TrigDestroy:AB$Destroy | Cost$ 0 | ValidTgts$ Enchantment
Oracle:Haunt (When this creature dies, exile it haunting target creature.)\nWhen Absolver Thrull enters the battlefield or the creature it haunts dies, destroy target enchantment.
SetInfo:GPT|Common|http://magiccards.info/scans/en/gp/1.jpg
End

View File

@@ -0,0 +1,11 @@
Name:Belfry Spirit
ManaCost:3 W W
Types:Creature Spirit
Text:no text
PT:1/1
K:Flying
K:Haunt:TrigToken:Put two 1/1 black Bat creature tokens with flying onto the battlefield.
SVar:TrigToken:AB$Token | Cost$ 0 | TokenImage$ B 1 1 Bat | TokenName$ Bat | TokenColors$ Black | TokenTypes$ Creature,Bat | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying | TokenOwner$ You | TokenAmount$ 2
Oracle:Flying\nHaunt (When this creature dies, exile it haunting target creature.)\nWhen Belfry Spirit enters the battlefield or the creature it haunts dies, put two 1/1 black Bat creature tokens with flying onto the battlefield.
SetInfo:GPT|Uncommon|http://magiccards.info/scans/en/gp/2.jpg
End

View File

@@ -0,0 +1,9 @@
Name:Benediction of Moons
ManaCost:W
Types:Sorcery
Text:no text
K:Haunt:TrigGainLife:You gain 1 life for each player.
SVar:TrigGainLife:AB$GainLife | Cost$ 0 | Defined$ You | LifeAmount$ 2
Oracle:You gain 1 life for each player.\nHaunt (When this spell card is put into a graveyard after resolving, exile it haunting target creature.)\nWhen the creature Benediction of Moons haunts dies, you gain 1 life for each player.
SetInfo:GPT|Common|http://magiccards.info/scans/en/gp/3.jpg
End

View File

@@ -0,0 +1,12 @@
Name:Blind Hunter
ManaCost:2 W B
Types:Creature Bat
Text:no text
PT:2/2
K:Flying
K:Haunt:TrigDrain:When Blind Hunter enters the battlefield or the creature it haunts dies, target player loses 2 life and you gain 2 life.
SVar:TrigDrain:AB$LoseLife | Cost$ 0 | Tgt$ TgtP | LifeAmount$ 2 | SubAbility$ DBGainLife
SVar:DBGainLife:DB$GainLife | Defined$ You | LifeAmount$ 2
Oracle:Flying\nHaunt (When this creature dies, exile it haunting target creature.)\nWhen Blind Hunter enters the battlefield or the creature it haunts dies, target player loses 2 life and you gain 2 life.
SetInfo:GPT|Common|http://magiccards.info/scans/en/gp/102.jpg
End

View File

@@ -0,0 +1,9 @@
Name:Cry of Contrition
ManaCost:B
Types:Sorcery
Text:no text
K:Haunt:TrigDiscard:Target player discards a card.
SVar:TrigDiscard:AB$Discard | Cost$ 0 | Tgt$ TgtP | Mode$ TgtChoose
Oracle:Target player discards a card.\nHaunt (When this spell card is put into a graveyard after resolving, exile it haunting target creature.)\nWhen the creature Cry of Contrition haunts dies, target player discards a card.
SetInfo:GPT|Common|http://magiccards.info/scans/en/gp/46.jpg
End

View File

@@ -0,0 +1,10 @@
Name:Exhumer Thrull
ManaCost:5 B
Types:Creature Thrull
Text:no text
PT:3/3
K:Haunt:TrigReturn:Return target creature card from your graveyard to your hand.
SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Choose target creature card in your graveyard. | Origin$ Graveyard | Destination$ Hand
Oracle:Haunt (When this creature dies, exile it haunting target creature.)\nWhen Exhumer Thrull enters the battlefield or the creature it haunts dies, return target creature card from your graveyard to your hand.
SetInfo:GPT|Uncommon|http://magiccards.info/scans/en/gp/50.jpg
End

View File

@@ -0,0 +1,11 @@
Name:Graven Dominator
ManaCost:4 W W
Types:Creature Gargoyle
Text:no text
PT:4/4
K:Flying
K:Haunt:TrigAnimate:Each other creature becomes 1/1 until end of turn.
SVar:TrigAnimate:AB$AnimateAll | Cost$ 0 | ValidCards$ Creature.Other | SetPower$ 1 | SetToughness$ 1
Oracle:Flying\nHaunt (When this creature dies, exile it haunting target creature.)\nWhen Graven Dominator enters the battlefield or the creature it haunts dies, each other creature becomes 1/1 until end of turn.
SetInfo:GPT|Rare|http://magiccards.info/scans/en/gp/7.jpg
End

View File

@@ -0,0 +1,10 @@
Name:Orzhov Euthanist
ManaCost:2 B
Types:Creature Human Assassin
Text:no text
PT:2/2
K:Haunt:TrigDestroy:When CARDNAME enters the battlefield or the creature it haunts dies, destroy target creature that was dealt damage this turn.
SVar:TrigDestroy:AB$Destroy | Cost$ 0 | ValidTgts$ Creature.wasDealtDamageThisTurn | TgtPrompt$ Select target creature that was dealt damage this turn.
Oracle:Haunt (When this creature dies, exile it haunting target creature.)\nWhen Orzhov Euthanist enters the battlefield or the creature it haunts dies, destroy target creature that was dealt damage this turn.
SetInfo:GPT|Common|http://magiccards.info/scans/en/gp/54.jpg
End

View File

@@ -0,0 +1,10 @@
Name:Seize the Soul
ManaCost:2 B B
Types:Instant
Text:no text
K:Haunt:TrigDestroy:Destroy target nonwhite, nonblack creature. Put a 1/1 white Spirit creature token with flying onto the battlefield.
SVar:TrigDestroy:AB$Destroy | Cost$ 0 | ValidTgts$ Creature.nonWhite+nonBlack | TgtPrompt$ Select target nonwhite nonblack creature. | SubAbility$ DBSpirit | SpellDescription$ Destroy target nonwhite nonblack creature. Put a 1/1 white Spirit creature token with flying into play.
SVar:DBSpirit:DB$Token | TokenAmount$ 1 | TokenName$ Spirit | TokenTypes$ Creature,Spirit | TokenOwner$ You | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying
Oracle:Destroy target nonwhite, nonblack creature. Put a 1/1 white Spirit creature token with flying onto the battlefield.\nHaunt (When this spell card is put into a graveyard after resolving, exile it haunting target creature.)\nWhen the creature Seize the Soul haunts dies, destroy target nonwhite, nonblack creature. Put a 1/1 white Spirit creature token with flying onto the battlefield.
SetInfo:GPT|Rare|http://magiccards.info/scans/en/gp/61.jpg
End

View File

@@ -185,6 +185,9 @@ public class Card extends GameEntity implements Comparable<Card> {
private Map<String, String> sVars = new TreeMap<String, String>(); private Map<String, String> sVars = new TreeMap<String, String>();
private static String[] storableSVars = {"ChosenX"}; private static String[] storableSVars = {"ChosenX"};
private ArrayList<Card> hauntedBy = new ArrayList<Card>();
private Card haunting = null;
/** /**
* *
* TODO Write javadoc for this method. * TODO Write javadoc for this method.
@@ -1615,7 +1618,7 @@ public class Card extends GameEntity implements Comparable<Card> {
sbLong.append(" (When this enters the battlefield, sacrifice it unless you exile another "); sbLong.append(" (When this enters the battlefield, sacrifice it unless you exile another ");
sbLong.append(types); sbLong.append(types);
sbLong.append(" you control. When this leaves the battlefield, that card returns to the battlefield.)\r\n"); sbLong.append(" you control. When this leaves the battlefield, that card returns to the battlefield.)\r\n");
} else if (keyword.get(i).endsWith(".")) { } else if (keyword.get(i).endsWith(".") && !keyword.get(i).startsWith("Haunt")) {
sbLong.append(keyword.get(i).toString()).append("\r\n"); sbLong.append(keyword.get(i).toString()).append("\r\n");
} else if (keyword.get(i).contains("At the beginning of your upkeep, ") } else if (keyword.get(i).contains("At the beginning of your upkeep, ")
&& keyword.get(i).contains(" unless you pay")) && keyword.get(i).contains(" unless you pay"))
@@ -1645,6 +1648,17 @@ public class Card extends GameEntity implements Comparable<Card> {
sbLong.append(" +1/+1 counters on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.)"); sbLong.append(" +1/+1 counters on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.)");
} else if (keyword.get(i).startsWith("MayEffectFromOpeningHand")) { } else if (keyword.get(i).startsWith("MayEffectFromOpeningHand")) {
continue; continue;
} else if (keyword.get(i).contains("Haunt")) {
sb.append("\r\nHaunt (");
if(isCreature()) {
sb.append("When this creature dies, exile it haunting target creature.");
}
else
{
sb.append("When this spell card is put into a graveyard after resolving, exile it haunting target creature.");
}
sb.append(")");
continue;
} else { } else {
if (i != 0 && sb.length() != 0) { if (i != 0 && sb.length() != 0) {
sb.append(", "); sb.append(", ");
@@ -1761,6 +1775,27 @@ public class Card extends GameEntity implements Comparable<Card> {
} }
} }
for(String keyw : kw) {
if(keyw.startsWith("Haunt")) {
if (sb.toString().endsWith("\r\n\r\n")) {
sb.delete(sb.lastIndexOf("\r\n"), sb.lastIndexOf("\r\n") + 3);
}
sb.append("Haunt (");
if(isCreature()) {
sb.append("When this creature dies, exile it haunting target creature.");
}
else {
sb.append("When this spell card is put into a graveyard after resolving, exile it haunting target creature.");
}
sb.append(")\r\n");
}
}
if(haunting != null) {
sb.append("Haunting: ").append(haunting);
sb.append("\r\n");
}
while (sb.toString().endsWith("\r\n")) { while (sb.toString().endsWith("\r\n")) {
sb.delete(sb.lastIndexOf("\r\n"), sb.lastIndexOf("\r\n") + 3); sb.delete(sb.lastIndexOf("\r\n"), sb.lastIndexOf("\r\n") + 3);
} }
@@ -1871,6 +1906,20 @@ public class Card extends GameEntity implements Comparable<Card> {
} }
} }
if(hauntedBy.size() != 0) {
sb.append("Haunted by: ");
for(Card c : hauntedBy) {
sb.append(c).append(",");
}
sb.deleteCharAt(sb.length()-1);
sb.append("\r\n");
}
if(haunting != null) {
sb.append("Haunting: ").append(haunting);
sb.append("\r\n");
}
/* /*
sb.append("\r\nOwner: ").append(owner).append("\r\n"); sb.append("\r\nOwner: ").append(owner).append("\r\n");
sb.append("Controller(s):"); sb.append("Controller(s):");
@@ -4957,6 +5006,8 @@ public class Card extends GameEntity implements Comparable<Card> {
if (!equippedBy.contains(source)) return false; if (!equippedBy.contains(source)) return false;
} else if (Property.startsWith("Equipped")) { } else if (Property.startsWith("Equipped")) {
if (!equipping.contains(source)) return false; if (!equipping.contains(source)) return false;
} else if (Property.startsWith("HauntedBy")) {
if (!hauntedBy.contains(source)) return false;
} else if (Property.startsWith("Above")){ // "Are Above" Source } else if (Property.startsWith("Above")){ // "Are Above" Source
CardList list = this.getOwner().getCardsIn(Zone.Graveyard); CardList list = this.getOwner().getCardsIn(Zone.Graveyard);
if (!list.getAbove(source, this)) if (!list.getAbove(source, this))
@@ -6130,4 +6181,27 @@ public class Card extends GameEntity implements Comparable<Card> {
sVars.put("Foil", Integer.toString(f)); sVars.put("Foil", Integer.toString(f));
} }
public final void addHauntedBy(final Card c) {
hauntedBy.add(c);
if(c != null) {
c.setHaunting(this);
}
}
public final ArrayList<Card> getHauntedBy() {
return hauntedBy;
}
public final void removeHauntedBy(final Card c) {
hauntedBy.remove(c);
}
public final Card getHaunting() {
return haunting;
}
public final void setHaunting(final Card c) {
haunting = c;
}
} //end Card class } //end Card class

View File

@@ -692,6 +692,10 @@ public final class CardUtil {
res.setChangedCardTypes(c.getChangedCardTypes()); res.setChangedCardTypes(c.getChangedCardTypes());
res.setNewPT(c.getNewPT()); res.setNewPT(c.getNewPT());
res.setReceivedDamageFromThisTurn(c.getReceivedDamageFromThisTurn()); res.setReceivedDamageFromThisTurn(c.getReceivedDamageFromThisTurn());
res.setHaunting(c.getHaunting());
for(Card haunter : c.getHauntedBy()) {
res.addHauntedBy(haunter);
}
return res; return res;
} }

View File

@@ -820,7 +820,7 @@ public class MagicStack extends MyObservable {
SpellAbility sa = AllZone.getStack().pop(); SpellAbility sa = AllZone.getStack().pop();
AllZone.getPhase().resetPriority(); // ActivePlayer gains priority first after Resolve AllZone.getPhase().resetPriority(); // ActivePlayer gains priority first after Resolve
Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
if (hasFizzled(sa, source)) { //Fizzle if (hasFizzled(sa, source)) { //Fizzle
// TODO: Spell fizzles, what's the best way to alert player? // TODO: Spell fizzles, what's the best way to alert player?
@@ -834,6 +834,67 @@ public class MagicStack extends MyObservable {
finishResolving(sa, false); finishResolving(sa, false);
} }
if(source.hasStartOfKeyword("Haunt") && !source.isCreature() && AllZone.getZoneOf(source).is(Constant.Zone.Graveyard)) {
CardList creats = AllZoneUtil.getCreaturesInPlay();
if(creats.size() != 0)
{
final Ability haunterDies_Work = new Ability(source,"0") {
@Override
public void resolve() {
AllZone.getGameAction().exile(source);
getTargetCard().addHauntedBy(source);
}
};
haunterDies_Work.setDescription("");
final Input target = new Input() {
private static final long serialVersionUID = 1981791992623774490L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage("Choose target creature to haunt.");
ButtonUtil.disableAll();
}
@Override
public void selectCard(final Card c, final PlayerZone zone) {
if(!zone.is(Constant.Zone.Battlefield)) {
return;
}
if(CardFactoryUtil.canTarget(source,c))
{
haunterDies_Work.setTargetCard(c);
add(haunterDies_Work);
stop();
}
else
{
AllZone.getDisplay().showMessage("Cannot target this card (Shroud? Protection?).");
}
}
};
if(source.getController().isHuman())
{
AllZone.getInputControl().setInput(target);
}
else
{
//AI choosing what to haunt
CardList oppCreats = creats.getController(AllZone.getHumanPlayer());
if(oppCreats.size() != 0)
{
haunterDies_Work.setTargetCard(CardFactoryUtil.AI_getWorstCreature(oppCreats));
}
else
{
haunterDies_Work.setTargetCard(CardFactoryUtil.AI_getWorstCreature(creats));
}
add(haunterDies_Work);
}
}
}
} }
/** /**

View File

@@ -3,6 +3,7 @@ package forge.card.cardFactory;
import com.esotericsoftware.minlog.Log; import com.esotericsoftware.minlog.Log;
import forge.*; import forge.*;
import forge.Constant.Zone; import forge.Constant.Zone;
import forge.card.abilityFactory.AbilityFactory;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.card.spellability.*; import forge.card.spellability.*;
@@ -4771,6 +4772,137 @@ public class CardFactoryUtil {
} }
} }
if(card.hasStartOfKeyword("Haunt")) {
int hauntPos = card.getKeywordPosition("Haunt");
String[] splitKeyword = card.getKeyword().get(hauntPos).split(":");
String hauntSVarName = splitKeyword[1];
String abilityDescription = splitKeyword[2];
String hauntAbilityDescription = abilityDescription.substring(0,1).toLowerCase() + abilityDescription.substring(1);
String hauntDescription;
if(card.isCreature())
{
hauntDescription = "When " + card.getName() + " enters the battlefield or the creature it haunts dies, " + hauntAbilityDescription;
}
else
{
hauntDescription = "When the creature " + card.getName() + " haunts dies, " + hauntAbilityDescription;
}
card.getKeyword().remove(hauntPos);
//First, create trigger that runs when the haunter dies (if it's a creature)
Trigger haunterDies = forge.card.trigger.TriggerHandler.parseTrigger("Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Static$ True | Secondary$ True | TriggerDescription$ Blank", card, true);
final Ability haunterDies_Work = new Ability(card,"0") {
@Override
public void resolve() {
getTargetCard().addHauntedBy(card);
AllZone.getGameAction().exile(card);
}
};
haunterDies_Work.setDescription(hauntDescription);
final Input target = new Input() {
private static final long serialVersionUID = 1981791992623774490L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage("Choose target creature to haunt.");
ButtonUtil.disableAll();
}
@Override
public void selectCard(final Card c, final PlayerZone zone) {
if(!zone.is(Constant.Zone.Battlefield)) {
return;
}
if(canTarget(card,c))
{
haunterDies_Work.setTargetCard(c);
AllZone.getStack().add(haunterDies_Work);
stop();
}
else
{
AllZone.getDisplay().showMessage("Cannot target this card (Shroud? Protection?).");
}
}
};
Ability haunterDies_Setup = new Ability(card,"0") {
@Override
public void resolve() {
CardList creats = AllZoneUtil.getCreaturesInPlay();
if(creats.size() == 0)
{
return;
}
//need to do it this way because I don't know quite how to make TriggerHandler respect BeforePayMana.
if(card.getController().isHuman())
{
AllZone.getInputControl().setInput(target);
}
else
{
//AI choosing what to haunt
CardList oppCreats = creats.getController(AllZone.getHumanPlayer());
if(oppCreats.size() != 0)
{
haunterDies_Work.setTargetCard(CardFactoryUtil.AI_getWorstCreature(oppCreats));
}
else
{
haunterDies_Work.setTargetCard(CardFactoryUtil.AI_getWorstCreature(creats));
}
AllZone.getStack().add(haunterDies_Work);
}
}
};
haunterDies.setOverridingAbility(haunterDies_Setup);
//Second, create the trigger that runs when the haunted creature dies
Trigger hauntedDies = forge.card.trigger.TriggerHandler.parseTrigger("Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.HauntedBy | Execute$ " + hauntSVarName + " | TriggerDescription$ " + hauntDescription, card, true);
//Third, create the trigger that runs when the haunting creature enters the battlefield
Trigger haunterETB = forge.card.trigger.TriggerHandler.parseTrigger("Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ " + hauntSVarName + " | Secondary$ True | TriggerDescription$ " + hauntDescription, card, true);
//Fourth, create a trigger that removes the haunting status if the haunter leaves the exile
Trigger haunterUnExiled = forge.card.trigger.TriggerHandler.parseTrigger("Mode$ ChangesZone | Origin$ Exile | ValidCard$ Card.Self | Static$ True | Secondary$ True | TriggerDescription$ Blank", card, true);
Ability haunterUnExiled_Work = new Ability(card,"0") {
@Override
public void resolve() {
if(card.getHaunting() != null)
{
card.getHaunting().removeHauntedBy(card);
card.setHaunting(null);
}
}
};
haunterUnExiled.setOverridingAbility(haunterUnExiled_Work);
//Fifth, add all triggers and abilities to the card.
if(card.isCreature()) {
card.addTrigger(haunterETB);
card.addTrigger(haunterDies);
}
else {
AbilityFactory af = new AbilityFactory();
String abString = card.getSVar(hauntSVarName).replace("AB$", "SP$").replace("Cost$ 0", "Cost$ " + card.getManaCost()) + " | SpellDescription$ " + abilityDescription;
SpellAbility sa = af.getAbility(abString, card);
card.addSpellAbility(sa);
}
card.addTrigger(hauntedDies);
card.addTrigger(haunterUnExiled);
}
return card; return card;
} }