Any ideas about Bestow?
1) Parse keyword Bestow, add a spell "SP$ Attach | AILogic$ Pump | Bestow$ True | ValidTgts$ Creature"
2) Add a static trigger to animate the card "Enchantment Aura" when cast it for the Bestow cost
3) This spell won't be fizzled
3) Set the card isBestowed when resolving
4) If an aura is bestowed, it would not move to the graveyard during state based actions. Animate the original card types.
- my patch | Open
- Code: Select all
### Eclipse Workspace Patch 1.0
#P trunk
Index: src/main/java/forge/game/zone/MagicStack.java
===================================================================
--- src/main/java/forge/game/zone/MagicStack.java (revision 23136)
+++ src/main/java/forge/game/zone/MagicStack.java (working copy)
@@ -691,9 +691,10 @@
fizzle &= invalidTarget;
- if (sa.hasParam("CantFizzle")) {
+ if (sa.hasParam("CantFizzle") || sa.hasParam("Bestow")) {
// Gilded Drake cannot be countered by rules if the
// targeted card is not valid
+ // Bestow spells
fizzle = false;
}
}
Index: src/main/java/forge/card/ability/effects/AttachEffect.java
===================================================================
--- src/main/java/forge/card/ability/effects/AttachEffect.java (revision 23136)
+++ src/main/java/forge/card/ability/effects/AttachEffect.java (working copy)
@@ -50,6 +50,10 @@
if ( sa.hasParam("Optional") && !p.getController().confirmAction(sa, null, message) )
return;
+ if (sa.hasParam("Bestow")) {
+ source.setBestow(true);
+ }
+
// If Cast Targets will be checked on the Stack
for (final Object o : targets) {
handleAttachment(card, o, sa);
Index: src/main/java/forge/Card.java
===================================================================
--- src/main/java/forge/Card.java (revision 23136)
+++ src/main/java/forge/Card.java (working copy)
@@ -172,6 +172,7 @@
private boolean monstrous = false;
private int monstrosityNum = 0;
+ private boolean bestow = false;
private boolean suspendCast = false;
private boolean suspend = false;
@@ -7770,6 +7771,28 @@
/**
* <p>
+ * Setter for the field <code>bestow</code>.
+ * </p>
+ *
+ * @param b
+ * a boolean.
+ */
+ public final void setBestow(final boolean b) {
+ this.bestow = b;
+ }
+
+ /**
+ * <p>
+ * isBestowed.
+ * </p>
+ *
+ * @return a boolean.
+ */
+ public final boolean isBestowed() {
+ return this.bestow;
+ }
+ /**
+ * <p>
* Setter for the field <code>monstrosityNum</code>.
* </p>
*
@@ -8225,7 +8248,15 @@
* @return a boolean
*/
public final boolean canBeEnchantedBy(final Card aura) {
- final SpellAbility sa = aura.getFirstSpellAbility();
+ SpellAbility sa = aura.getFirstSpellAbility();
+ if (aura.isBestowed()) {
+ for (SpellAbility s : aura.getSpellAbilities()) {
+ if (s.getApi() == ApiType.Attach && s.hasParam("Bestow")) {
+ sa = s;
+ break;
+ }
+ }
+ }
TargetRestrictions tgt = null;
if (sa != null) {
tgt = sa.getTargetRestrictions();
Index: src/main/java/forge/card/cardfactory/CardFactoryUtil.java
===================================================================
--- src/main/java/forge/card/cardfactory/CardFactoryUtil.java (revision 23136)
+++ src/main/java/forge/card/cardfactory/CardFactoryUtil.java (working copy)
@@ -2531,6 +2531,37 @@
card.getUnparsedAbilities().add(abilityStr.toString());
}
+ if (card.hasStartOfKeyword("Bestow")) {
+ final int bestowPos = card.getKeywordPosition("Bestow");
+ final String cost = card.getKeyword().get(bestowPos).split(":")[1];
+ card.removeIntrinsicKeyword(card.getKeyword().get(bestowPos));
+
+ final StringBuilder sbAttach = new StringBuilder();
+ sbAttach.append("SP$ Attach | Cost$ ");
+ sbAttach.append(cost);
+ sbAttach.append(" | AILogic$ Pump | Bestow$ True | ValidTgts$ Creature");
+ final SpellAbility bestow = AbilityFactory.getAbility(sbAttach.toString(), card);
+
+ bestow.setDescription("Bestow " + cost + " (If you cast this card for" +
+ " its bestow cost, it's an Aura spell with enchant creature. It" +
+ " becomes a creature again if it's not attached to a creature.)");
+ bestow.setStackDescription("Bestow - " + card.getName());
+ bestow.setBasicSpell(false);
+ card.addSpellAbility(bestow);
+ card.getUnparsedAbilities().add(sbAttach.toString());
+
+ // Second, a static trigger when bestow cost is paid to animate Aura
+ final StringBuilder sbTrigger = new StringBuilder();
+ sbTrigger.append("Mode$ SpellCast | ValidCard$ Card.Self | Bestow$ True | ");
+ sbTrigger.append("Execute$ BestowAnimateSelf | Static$ True");
+
+ final StringBuilder sbSVar = new StringBuilder();
+ sbSVar.append("AB$ Animate | Cost$ 0 | Defined$ Self | OverwriteTypes$ True");
+ sbSVar.append(" | Types$ Enchantment,Aura | Keywords$ Enchant creature | Permanent$ True");
+ card.setSVar("BestowAnimateSelf", sbSVar.toString());
+ final Trigger animateSelf = TriggerHandler.parseTrigger(sbTrigger.toString(), card, true);
+ card.addTrigger(animateSelf);
+ }
setupEtbKeywords(card);
}
Index: src/main/java/forge/game/GameAction.java
===================================================================
--- src/main/java/forge/game/GameAction.java (revision 23136)
+++ src/main/java/forge/game/GameAction.java (working copy)
@@ -44,6 +44,7 @@
import forge.GameEntity;
import forge.GameLogEntryType;
import forge.ITargetable;
+import forge.card.CardDb;
import forge.card.CardType;
import forge.card.TriggerReplacementBase;
import forge.card.ability.AbilityFactory;
@@ -908,7 +909,15 @@
// Check if Card Aura is attached to is a legal target
final GameEntity entity = c.getEnchanting();
- final SpellAbility sa = c.getSpells().get(0);
+ SpellAbility sa = c.getSpells().get(0);
+ if (c.isBestowed()) {
+ for (SpellAbility s : c.getSpellAbilities()) {
+ if (s.getApi() == ApiType.Attach && s.hasParam("Bestow")) {
+ sa = s;
+ break;
+ }
+ }
+ }
TargetRestrictions tgt = null;
if (sa != null) {
@@ -921,7 +930,16 @@
if (!perm.isInZone(tgtZone) || !perm.canBeEnchantedBy(c) || (perm.isPhasedOut() && !c.isPhasedOut())) {
c.unEnchantEntity(perm);
- this.moveToGraveyard(c);
+ if (c.isBestowed()) {
+ // TODO : support for tokens
+ ArrayList<String> type = CardFactory.getCard(CardDb.getCard(c), c.getController()).getType();
+ final long timestamp = game.getNextTimestamp();
+ c.addChangedCardTypes(type, Lists.newArrayList("Aura"), false, false, false, false, timestamp);
+ c.addChangedCardKeywords(new ArrayList<String>(), Lists.newArrayList("Enchant creature"), false, timestamp);
+ c.setBestow(false);
+ game.fireEvent(new GameEventCardStatsChanged(c));
+ } else {
+ this.moveToGraveyard(c);
+ }
checkAgain = true;
}
} else if (entity instanceof Player) {
@@ -943,7 +961,16 @@
}
if (c.isInPlay() && !c.isEnchanting()) {
- this.moveToGraveyard(c);
+ if (c.isBestowed()) {
+ // TODO : support for tokens
+ ArrayList<String> type = CardFactory.getCard(CardDb.getCard(c), c.getController()).getType();
+ final long timestamp = game.getNextTimestamp();
+ c.addChangedCardTypes(type, Lists.newArrayList("Aura"), false, false, false, false, timestamp);
+ c.addChangedCardKeywords(new ArrayList<String>(), Lists.newArrayList("Enchant creature"), false, timestamp);
+ c.setBestow(false);
+ game.fireEvent(new GameEventCardStatsChanged(c));
+ } else {
+ this.moveToGraveyard(c);
+ }
checkAgain = true;
}
return checkAgain;
Index: src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java
===================================================================
--- src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java (revision 23136)
+++ src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java (working copy)
@@ -184,6 +184,11 @@
return true;
}
}
+ if (this.mapParams.containsKey("Bestow")) {
+ if (!spellAbility.hasParam("Bestow")) {
+ return false;
+ }
+ }
return true;
}
Index: res/cardsfolder/x/leafcrown_dryad.txt
===================================================================
--- res/cardsfolder/x/leafcrown_dryad.txt (revision 0)
+++ res/cardsfolder/x/leafcrown_dryad.txt (working copy)
@@ -0,0 +1,8 @@
+Name:Leafcrown Dryad
+ManaCost:1 G
+Types:Enchantment Creature Nymph Dryad
+PT:2/2
+K:Bestow:3 G
+K:Reach
+S:Mode$ Continuous | Affected$ Card.EnchantedBy | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Reach | Description$ Enchanted creature gets +2/+2 and has reach.
+SVar:Picture:http://www.wizards.com/global/images/magic/general/leafcrown_dryad.jpg
\ No newline at end of file
Test:
Kor SpiritDancer's ability triggers when I cast a bestow spell.
I don't know how CopyPermanent/
Clone/Play effects work with bestowed auras.