mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Merge branch 'seravy-ai-fixes' into 'master'
Reformatted/revised AI updates from Seravy: Fog AI, Protection from chosen color AI See merge request core-developers/forge!503
This commit is contained in:
@@ -38,6 +38,7 @@ import forge.game.trigger.TriggerType;
|
|||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Expressions;
|
import forge.util.Expressions;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
|
import forge.util.TextUtil;
|
||||||
import forge.util.collect.FCollectionView;
|
import forge.util.collect.FCollectionView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -263,6 +264,34 @@ public class AiAttackController {
|
|||||||
if (ai.getGame().getPhaseHandler().getNextTurn().equals(ai)) {
|
if (ai.getGame().getPhaseHandler().getNextTurn().equals(ai)) {
|
||||||
return attackers;
|
return attackers;
|
||||||
}
|
}
|
||||||
|
// no need to block (already holding mana to cast fog next turn)
|
||||||
|
if (!AiCardMemory.isMemorySetEmpty(ai, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT)) {
|
||||||
|
// Don't send the card that'll do the fog effect to attack, it's unsafe!
|
||||||
|
if (attackers.contains(AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT)) {
|
||||||
|
attackers.remove(AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT);
|
||||||
|
}
|
||||||
|
return attackers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to block if an effect is in play which untaps all creatures (pseudo-Vigilance akin to
|
||||||
|
// Awakening or Prophet of Kruphix)
|
||||||
|
for (Card card : ai.getGame().getCardsIn(ZoneType.Battlefield)) {
|
||||||
|
boolean untapsEachTurn = card.hasSVar("UntapsEachTurn");
|
||||||
|
boolean untapsEachOtherTurn = card.hasSVar("UntapsEachOtherPlayerTurn");
|
||||||
|
|
||||||
|
if (untapsEachTurn || untapsEachOtherTurn) {
|
||||||
|
String affected = untapsEachTurn ? card.getSVar("UntapsEachTurn")
|
||||||
|
: card.getSVar("UntapsEachOtherPlayerTurn");
|
||||||
|
|
||||||
|
for (String aff : TextUtil.split(affected, ',')) {
|
||||||
|
if (aff.equals("Creature")
|
||||||
|
&& (untapsEachTurn || (untapsEachOtherTurn && ai.equals(card.getController())))) {
|
||||||
|
return attackers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<Card> opponentsAttackers = new ArrayList<Card>(oppList);
|
List<Card> opponentsAttackers = new ArrayList<Card>(oppList);
|
||||||
opponentsAttackers = CardLists.filter(opponentsAttackers, new Predicate<Card>() {
|
opponentsAttackers = CardLists.filter(opponentsAttackers, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -44,20 +44,24 @@ public class AiCardMemory {
|
|||||||
private final Set<Card> memTrickAttackers;
|
private final Set<Card> memTrickAttackers;
|
||||||
private final Set<Card> memHeldManaSources;
|
private final Set<Card> memHeldManaSources;
|
||||||
private final Set<Card> memHeldManaSourcesForCombat;
|
private final Set<Card> memHeldManaSourcesForCombat;
|
||||||
|
private final Set<Card> memHeldManaSourcesForEnemyCombat;
|
||||||
private final Set<Card> memAttachedThisTurn;
|
private final Set<Card> memAttachedThisTurn;
|
||||||
private final Set<Card> memAnimatedThisTurn;
|
private final Set<Card> memAnimatedThisTurn;
|
||||||
private final Set<Card> memBouncedThisTurn;
|
private final Set<Card> memBouncedThisTurn;
|
||||||
private final Set<Card> memActivatedThisTurn;
|
private final Set<Card> memActivatedThisTurn;
|
||||||
|
private final Set<Card> memChosenFogEffect;
|
||||||
|
|
||||||
public AiCardMemory() {
|
public AiCardMemory() {
|
||||||
this.memMandatoryAttackers = new HashSet<>();
|
this.memMandatoryAttackers = new HashSet<>();
|
||||||
this.memHeldManaSources = new HashSet<>();
|
this.memHeldManaSources = new HashSet<>();
|
||||||
this.memHeldManaSourcesForCombat = new HashSet<>();
|
this.memHeldManaSourcesForCombat = new HashSet<>();
|
||||||
|
this.memHeldManaSourcesForEnemyCombat = new HashSet<>();
|
||||||
this.memAttachedThisTurn = new HashSet<>();
|
this.memAttachedThisTurn = new HashSet<>();
|
||||||
this.memAnimatedThisTurn = new HashSet<>();
|
this.memAnimatedThisTurn = new HashSet<>();
|
||||||
this.memBouncedThisTurn = new HashSet<>();
|
this.memBouncedThisTurn = new HashSet<>();
|
||||||
this.memActivatedThisTurn = new HashSet<>();
|
this.memActivatedThisTurn = new HashSet<>();
|
||||||
this.memTrickAttackers = new HashSet<>();
|
this.memTrickAttackers = new HashSet<>();
|
||||||
|
this.memChosenFogEffect = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,10 +74,12 @@ public class AiCardMemory {
|
|||||||
TRICK_ATTACKERS,
|
TRICK_ATTACKERS,
|
||||||
HELD_MANA_SOURCES_FOR_MAIN2,
|
HELD_MANA_SOURCES_FOR_MAIN2,
|
||||||
HELD_MANA_SOURCES_FOR_DECLBLK,
|
HELD_MANA_SOURCES_FOR_DECLBLK,
|
||||||
|
HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK,
|
||||||
ATTACHED_THIS_TURN,
|
ATTACHED_THIS_TURN,
|
||||||
ANIMATED_THIS_TURN,
|
ANIMATED_THIS_TURN,
|
||||||
BOUNCED_THIS_TURN,
|
BOUNCED_THIS_TURN,
|
||||||
ACTIVATED_THIS_TURN,
|
ACTIVATED_THIS_TURN,
|
||||||
|
CHOSEN_FOG_EFFECT,
|
||||||
//REVEALED_CARDS // stub, not linked to AI code yet
|
//REVEALED_CARDS // stub, not linked to AI code yet
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +93,8 @@ public class AiCardMemory {
|
|||||||
return memHeldManaSources;
|
return memHeldManaSources;
|
||||||
case HELD_MANA_SOURCES_FOR_DECLBLK:
|
case HELD_MANA_SOURCES_FOR_DECLBLK:
|
||||||
return memHeldManaSourcesForCombat;
|
return memHeldManaSourcesForCombat;
|
||||||
|
case HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK:
|
||||||
|
return memHeldManaSourcesForEnemyCombat;
|
||||||
case ATTACHED_THIS_TURN:
|
case ATTACHED_THIS_TURN:
|
||||||
return memAttachedThisTurn;
|
return memAttachedThisTurn;
|
||||||
case ANIMATED_THIS_TURN:
|
case ANIMATED_THIS_TURN:
|
||||||
@@ -95,6 +103,8 @@ public class AiCardMemory {
|
|||||||
return memBouncedThisTurn;
|
return memBouncedThisTurn;
|
||||||
case ACTIVATED_THIS_TURN:
|
case ACTIVATED_THIS_TURN:
|
||||||
return memActivatedThisTurn;
|
return memActivatedThisTurn;
|
||||||
|
case CHOSEN_FOG_EFFECT:
|
||||||
|
return memChosenFogEffect;
|
||||||
//case REVEALED_CARDS:
|
//case REVEALED_CARDS:
|
||||||
// return memRevealedCards;
|
// return memRevealedCards;
|
||||||
default:
|
default:
|
||||||
@@ -267,10 +277,12 @@ public class AiCardMemory {
|
|||||||
clearMemorySet(MemorySet.TRICK_ATTACKERS);
|
clearMemorySet(MemorySet.TRICK_ATTACKERS);
|
||||||
clearMemorySet(MemorySet.HELD_MANA_SOURCES_FOR_MAIN2);
|
clearMemorySet(MemorySet.HELD_MANA_SOURCES_FOR_MAIN2);
|
||||||
clearMemorySet(MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK);
|
clearMemorySet(MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK);
|
||||||
|
clearMemorySet(MemorySet.HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK);
|
||||||
clearMemorySet(MemorySet.ATTACHED_THIS_TURN);
|
clearMemorySet(MemorySet.ATTACHED_THIS_TURN);
|
||||||
clearMemorySet(MemorySet.ANIMATED_THIS_TURN);
|
clearMemorySet(MemorySet.ANIMATED_THIS_TURN);
|
||||||
clearMemorySet(MemorySet.BOUNCED_THIS_TURN);
|
clearMemorySet(MemorySet.BOUNCED_THIS_TURN);
|
||||||
clearMemorySet(MemorySet.ACTIVATED_THIS_TURN);
|
clearMemorySet(MemorySet.ACTIVATED_THIS_TURN);
|
||||||
|
clearMemorySet(MemorySet.CHOSEN_FOG_EFFECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static functions to simplify access to AI card memory of a given AI player.
|
// Static functions to simplify access to AI card memory of a given AI player.
|
||||||
|
|||||||
@@ -581,10 +581,10 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void reserveManaSources(SpellAbility sa) {
|
public void reserveManaSources(SpellAbility sa) {
|
||||||
reserveManaSources(sa, PhaseType.MAIN2);
|
reserveManaSources(sa, PhaseType.MAIN2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reserveManaSources(SpellAbility sa, PhaseType phaseType) {
|
public void reserveManaSources(SpellAbility sa, PhaseType phaseType, boolean enemy) {
|
||||||
ManaCostBeingPaid cost = ComputerUtilMana.calculateManaCost(sa, true, 0);
|
ManaCostBeingPaid cost = ComputerUtilMana.calculateManaCost(sa, true, 0);
|
||||||
CardCollection manaSources = ComputerUtilMana.getManaSourcesToPayCost(cost, sa, player);
|
CardCollection manaSources = ComputerUtilMana.getManaSourcesToPayCost(cost, sa, player);
|
||||||
|
|
||||||
@@ -595,7 +595,8 @@ public class AiController {
|
|||||||
memSet = AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2;
|
memSet = AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2;
|
||||||
break;
|
break;
|
||||||
case COMBAT_DECLARE_BLOCKERS:
|
case COMBAT_DECLARE_BLOCKERS:
|
||||||
memSet = AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK;
|
memSet = enemy ? AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK
|
||||||
|
: AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("Warning: unsupported mana reservation phase specified for reserveManaSources: "
|
System.out.println("Warning: unsupported mana reservation phase specified for reserveManaSources: "
|
||||||
|
|||||||
@@ -1512,7 +1512,7 @@ public class ComputerUtilCard {
|
|||||||
// Reserve the mana until Declare Blockers such that the AI doesn't tap out before having a chance to use
|
// Reserve the mana until Declare Blockers such that the AI doesn't tap out before having a chance to use
|
||||||
// the combat trick
|
// the combat trick
|
||||||
if (ai.getController().isAI()) {
|
if (ai.getController().isAI()) {
|
||||||
((PlayerControllerAi) ai.getController()).getAi().reserveManaSources(sa, PhaseType.COMBAT_DECLARE_BLOCKERS);
|
((PlayerControllerAi) ai.getController()).getAi().reserveManaSources(sa, PhaseType.COMBAT_DECLARE_BLOCKERS, false);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -865,9 +865,12 @@ public class ComputerUtilMana {
|
|||||||
// For combat tricks, always obey mana reservation
|
// For combat tricks, always obey mana reservation
|
||||||
if (curPhase == PhaseType.COMBAT_DECLARE_BLOCKERS || curPhase == PhaseType.CLEANUP) {
|
if (curPhase == PhaseType.COMBAT_DECLARE_BLOCKERS || curPhase == PhaseType.CLEANUP) {
|
||||||
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK);
|
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK);
|
||||||
}
|
} else if (!(ai.getGame().getPhaseHandler().isPlayerTurn(ai)) && (curPhase == PhaseType.COMBAT_DECLARE_BLOCKERS || curPhase == PhaseType.CLEANUP)) {
|
||||||
else {
|
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK);
|
||||||
if (AiCardMemory.isRememberedCard(ai, sourceCard, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK)) {
|
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT);
|
||||||
|
} else {
|
||||||
|
if ((AiCardMemory.isRememberedCard(ai, sourceCard, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK)) ||
|
||||||
|
(AiCardMemory.isRememberedCard(ai, sourceCard, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK))) {
|
||||||
// This mana source is held elsewhere for a combat trick.
|
// This mana source is held elsewhere for a combat trick.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1311,6 +1311,22 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) {
|
if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't play if would choose a color the target is already protected from
|
||||||
|
if (sa.getHostCard().hasSVar("ChosenProtection")) {
|
||||||
|
CardCollectionView oppAllCards = ai.getOpponents().getCardsIn(ZoneType.Battlefield);
|
||||||
|
String cc = ComputerUtilCard.getMostProminentColor(oppAllCards);
|
||||||
|
if (card.hasKeyword("Protection from " + cc.toLowerCase())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Also don't play if it would destroy own Aura
|
||||||
|
for (Card c : card.getEnchantedBy(false)) {
|
||||||
|
if ((c.getController().equals(ai)) && (c.isOfColor(cc))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final boolean evasive = (keyword.equals("Unblockable") || keyword.equals("Fear")
|
final boolean evasive = (keyword.equals("Unblockable") || keyword.equals("Fear")
|
||||||
|| keyword.equals("Intimidate") || keyword.equals("Shadow")
|
|| keyword.equals("Intimidate") || keyword.equals("Shadow")
|
||||||
|| keyword.equals("Flying") || keyword.equals("Horsemanship")
|
|| keyword.equals("Flying") || keyword.equals("Horsemanship")
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package forge.ai.ability;
|
package forge.ai.ability;
|
||||||
|
|
||||||
|
|
||||||
import forge.ai.ComputerUtil;
|
import forge.ai.*;
|
||||||
import forge.ai.ComputerUtilCombat;
|
|
||||||
import forge.ai.SpellAbilityAi;
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
|
import forge.game.GameObject;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardPredicates;
|
import forge.game.card.CardPredicates;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -12,6 +11,8 @@ import forge.game.player.Player;
|
|||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class FogAi extends SpellAbilityAi {
|
public class FogAi extends SpellAbilityAi {
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -20,6 +21,33 @@ public class FogAi extends SpellAbilityAi {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean canPlayAI(Player ai, SpellAbility sa) {
|
protected boolean canPlayAI(Player ai, SpellAbility sa) {
|
||||||
final Game game = ai.getGame();
|
final Game game = ai.getGame();
|
||||||
|
final Card hostCard = sa.getHostCard();
|
||||||
|
|
||||||
|
// Don't cast it, if the effect is already in place
|
||||||
|
if (game.getPhaseHandler().isPreventCombatDamageThisTurn()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if card would be destroyed, react and use immediately if it's not own turn
|
||||||
|
if ((AiCardMemory.isRememberedCard(ai, hostCard, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT))
|
||||||
|
&& (!game.getStack().isEmpty())
|
||||||
|
&& (!game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer()))) {
|
||||||
|
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(ai, null);
|
||||||
|
if (objects.contains(hostCard)) {
|
||||||
|
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserve mana to cast this card if it will be likely needed
|
||||||
|
if (((game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer()))
|
||||||
|
|| (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)))
|
||||||
|
&& (AiCardMemory.isMemorySetEmpty(ai, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT))
|
||||||
|
&& (ComputerUtil.aiLifeInDanger(ai, false, 0))) {
|
||||||
|
((PlayerControllerAi) ai.getController()).getAi().reserveManaSources(sa, PhaseType.COMBAT_DECLARE_BLOCKERS, true);
|
||||||
|
AiCardMemory.rememberCard(ai, hostCard, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT);
|
||||||
|
}
|
||||||
|
|
||||||
// AI should only activate this during Human's Declare Blockers phase
|
// AI should only activate this during Human's Declare Blockers phase
|
||||||
if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) {
|
if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) {
|
||||||
return false;
|
return false;
|
||||||
@@ -33,11 +61,6 @@ public class FogAi extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't cast it, if the effect is already in place
|
|
||||||
if (game.getPhaseHandler().isPreventCombatDamageThisTurn()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("SeriousDamage".equals(sa.getParam("AILogic")) && game.getCombat() != null) {
|
if ("SeriousDamage".equals(sa.getParam("AILogic")) && game.getCombat() != null) {
|
||||||
int dmg = 0;
|
int dmg = 0;
|
||||||
for (Card atk : game.getCombat().getAttackersOf(ai)) {
|
for (Card atk : game.getCombat().getAttackersOf(ai)) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ ManaCost:2 G G
|
|||||||
Types:Enchantment
|
Types:Enchantment
|
||||||
T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | Execute$ TrigUntapAll | TriggerDescription$ At the beginning of each upkeep, untap all creatures and lands.
|
T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | Execute$ TrigUntapAll | TriggerDescription$ At the beginning of each upkeep, untap all creatures and lands.
|
||||||
SVar:TrigUntapAll:DB$UntapAll | ValidCards$ Creature,Land | SpellDescription$ untap all creatures and lands.
|
SVar:TrigUntapAll:DB$UntapAll | ValidCards$ Creature,Land | SpellDescription$ untap all creatures and lands.
|
||||||
|
SVar:UntapsEachTurn:Creature,Land
|
||||||
SVar:RemRandomDeck:True
|
SVar:RemRandomDeck:True
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/awakening.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/awakening.jpg
|
||||||
Oracle:At the beginning of each upkeep, untap all creatures and lands.
|
Oracle:At the beginning of each upkeep, untap all creatures and lands.
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ SVar:ChooseColor:DB$ ChooseColor | Defined$ You | AILogic$ MostProminentInHumanD
|
|||||||
A:SP$ Attach | Cost$ W W | ValidTgts$ Creature | AILogic$ Pump
|
A:SP$ Attach | Cost$ W W | ValidTgts$ Creature | AILogic$ Pump
|
||||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/cho_mannos_blessing.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/cho_mannos_blessing.jpg
|
||||||
|
SVar:ChosenProtection:True
|
||||||
Oracle:Flash\nEnchant creature\nAs Cho-Manno's Blessing enters the battlefield, choose a color.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Cho-Manno's Blessing.
|
Oracle:Flash\nEnchant creature\nAs Cho-Manno's Blessing enters the battlefield, choose a color.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Cho-Manno's Blessing.
|
||||||
|
|||||||
@@ -8,5 +8,6 @@ A:SP$ Attach | Cost$ W | ValidTgts$ Creature | AILogic$ Pump
|
|||||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
||||||
A:AB$ ChangeZone | Cost$ W | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return CARDNAME to its owner's hand.
|
A:AB$ ChangeZone | Cost$ W | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return CARDNAME to its owner's hand.
|
||||||
SVar:RemAIDeck:True
|
SVar:RemAIDeck:True
|
||||||
|
SVar:ChosenProtection:True
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/flickering_ward.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/flickering_ward.jpg
|
||||||
Oracle:Enchant creature\nAs Flickering Ward enters the battlefield, choose a color.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Flickering Ward.\n{W}: Return Flickering Ward to its owner's hand.
|
Oracle:Enchant creature\nAs Flickering Ward enters the battlefield, choose a color.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Flickering Ward.\n{W}: Return Flickering Ward to its owner's hand.
|
||||||
|
|||||||
@@ -8,5 +8,6 @@ A:SP$ Attach | Cost$ 2 W | ValidTgts$ Creature | AILogic$ Pump
|
|||||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
||||||
A:AB$ Protection | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature | TgtPrompt$ Select target creature | Gains$ ChosenColor | SpellDescription$ Target creature gains protection from the chosen color until end of turn.
|
A:AB$ Protection | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature | TgtPrompt$ Select target creature | Gains$ ChosenColor | SpellDescription$ Target creature gains protection from the chosen color until end of turn.
|
||||||
SVar:RemAIDeck:True
|
SVar:RemAIDeck:True
|
||||||
|
SVar:ChosenProtection:True
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/floating_shield.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/floating_shield.jpg
|
||||||
Oracle:Enchant creature\nAs Floating Shield enters the battlefield, choose a color.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Floating Shield.\nSacrifice Floating Shield: Target creature gains protection from the chosen color until end of turn.
|
Oracle:Enchant creature\nAs Floating Shield enters the battlefield, choose a color.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Floating Shield.\nSacrifice Floating Shield: Target creature gains protection from the chosen color until end of turn.
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ SVar:TrigDraw:DB$Draw | Defined$ You | NumCards$ 1
|
|||||||
A:SP$ Attach | Cost$ 2 W | ValidTgts$ Creature | AILogic$ Pump
|
A:SP$ Attach | Cost$ 2 W | ValidTgts$ Creature | AILogic$ Pump
|
||||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/pentarch_ward.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/pentarch_ward.jpg
|
||||||
|
SVar:ChosenProtection:True
|
||||||
Oracle:Enchant creature\nAs Pentarch Ward enters the battlefield, choose a color.\nWhen Pentarch Ward enters the battlefield, draw a card.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Pentarch Ward.
|
Oracle:Enchant creature\nAs Pentarch Ward enters the battlefield, choose a color.\nWhen Pentarch Ward enters the battlefield, draw a card.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Pentarch Ward.
|
||||||
|
|||||||
@@ -4,5 +4,6 @@ Types:Creature Human Wizard
|
|||||||
PT:2/3
|
PT:2/3
|
||||||
S:Mode$ Continuous | Affected$ Creature.YouCtrl,Land.YouCtrl | AddHiddenKeyword$ CARDNAME untaps during each other player's untap step. | Description$ Untap all creatures and lands you control during each other player's untap step.
|
S:Mode$ Continuous | Affected$ Creature.YouCtrl,Land.YouCtrl | AddHiddenKeyword$ CARDNAME untaps during each other player's untap step. | Description$ Untap all creatures and lands you control during each other player's untap step.
|
||||||
S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddHiddenKeyword$ Flash | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast creature spells as though they had flash.
|
S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddHiddenKeyword$ Flash | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast creature spells as though they had flash.
|
||||||
|
SVar:UntapsEachOtherPlayerTurn:Creature,Land
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/prophet_of_kruphix.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/prophet_of_kruphix.jpg
|
||||||
Oracle:Untap all creatures and lands you control during each other player's untap step.\nYou may cast creature spells as though they had flash.
|
Oracle:Untap all creatures and lands you control during each other player's untap step.\nYou may cast creature spells as though they had flash.
|
||||||
|
|||||||
@@ -11,5 +11,6 @@ SVar:ChooseColor:DB$ ChooseColor | Defined$ You | SpellDescription$ As CARDNAME
|
|||||||
A:SP$ Attach | Cost$ W W | ValidTgts$ Creature | AILogic$ Pump
|
A:SP$ Attach | Cost$ W W | ValidTgts$ Creature | AILogic$ Pump
|
||||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor:Card.CardUID_HostCardUID | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove CARDNAME.
|
||||||
SVar:RemAIDeck:True
|
SVar:RemAIDeck:True
|
||||||
|
SVar:ChosenProtection:True
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/ward_of_lights.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/ward_of_lights.jpg
|
||||||
Oracle:You may cast Ward of Lights as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step.\nEnchant creature\nAs Ward of Lights enters the battlefield, choose a color.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Ward of Lights.
|
Oracle:You may cast Ward of Lights as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step.\nEnchant creature\nAs Ward of Lights enters the battlefield, choose a color.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Ward of Lights.
|
||||||
|
|||||||
Reference in New Issue
Block a user