Merge remote-tracking branch 'remotes/core/master' into newBranch

This commit is contained in:
Anthony Calosa
2020-05-03 18:35:46 +08:00
24 changed files with 238 additions and 29 deletions

View File

@@ -1986,6 +1986,35 @@ public class AiController {
return MyRandom.getRandom().nextBoolean();
}
public boolean chooseEvenOdd(SpellAbility sa) {
String aiLogic = sa.getParamOrDefault("AILogic", "");
if (aiLogic.equals("AlwaysEven")) {
return false; // false is Even
} else if (aiLogic.equals("AlwaysOdd")) {
return true; // true is Odd
} else if (aiLogic.equals("Random")) {
return MyRandom.getRandom().nextBoolean();
} else if (aiLogic.equals("CMCInHand")) {
CardCollectionView hand = sa.getActivatingPlayer().getCardsIn(ZoneType.Hand);
int numEven = CardLists.filter(hand, CardPredicates.evenCMC()).size();
int numOdd = CardLists.filter(hand, CardPredicates.oddCMC()).size();
return numOdd > numEven;
} else if (aiLogic.equals("CMCOppControls")) {
CardCollectionView hand = sa.getActivatingPlayer().getOpponents().getCardsIn(ZoneType.Battlefield);
int numEven = CardLists.filter(hand, CardPredicates.evenCMC()).size();
int numOdd = CardLists.filter(hand, CardPredicates.oddCMC()).size();
return numOdd > numEven;
} else if (aiLogic.equals("CMCOppControlsByPower")) {
// TODO: improve this to check for how dangerous those creatures actually are relative to host card
CardCollectionView hand = sa.getActivatingPlayer().getOpponents().getCardsIn(ZoneType.Battlefield);
int powerEven = Aggregates.sum(CardLists.filter(hand, CardPredicates.evenCMC()), Accessors.fnGetNetPower);
int powerOdd = Aggregates.sum(CardLists.filter(hand, CardPredicates.oddCMC()), Accessors.fnGetNetPower);
return powerOdd > powerEven;
}
return MyRandom.getRandom().nextBoolean(); // outside of any specific logic, choose randomly
}
public Card chooseCardToHiddenOriginChangeZone(ZoneType destination, List<ZoneType> origin, SpellAbility sa,
CardCollection fetchList, Player player2, Player decider) {
if (useSimulation) {

View File

@@ -755,6 +755,7 @@ public class PlayerControllerAi extends PlayerController {
return defaultVal != null && defaultVal.booleanValue();
case UntapTimeVault: return false; // TODO Should AI skip his turn for time vault?
case LeftOrRight: return brains.chooseDirection(sa);
case OddsOrEvens: return brains.chooseEvenOdd(sa); // false is Odd, true is Even
default:
return MyRandom.getRandom().nextBoolean();
}

View File

@@ -42,6 +42,7 @@ public enum SpellApiToAi {
.put(ApiType.ChooseCard, ChooseCardAi.class)
.put(ApiType.ChooseColor, ChooseColorAi.class)
.put(ApiType.ChooseDirection, ChooseDirectionAi.class)
.put(ApiType.ChooseEvenOdd, ChooseEvenOddAi.class)
.put(ApiType.ChooseNumber, ChooseNumberAi.class)
.put(ApiType.ChoosePlayer, ChoosePlayerAi.class)
.put(ApiType.ChooseSource, ChooseSourceAi.class)

View File

@@ -0,0 +1,36 @@
package forge.ai.ability;
import forge.ai.SpellAbilityAi;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.util.MyRandom;
public class ChooseEvenOddAi extends SpellAbilityAi {
@Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
if (!sa.hasParam("AILogic")) {
return false;
}
TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
sa.resetTargets();
Player opp = aiPlayer.getWeakestOpponent();
if (sa.canTarget(opp)) {
sa.getTargets().add(opp);
} else {
return false;
}
}
boolean chance = MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
return chance;
}
@Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
return mandatory || canPlayAI(ai, sa);
}
}

View File

@@ -0,0 +1,6 @@
package forge.game;
public enum EvenOdd {
Even,
Odd
}

View File

@@ -204,6 +204,17 @@ public class AbilityUtils {
cards.add((Card) o);
}
}
} else if (defined.equals("DelayTriggerRememberedLKI")) {
SpellAbility trigSa = sa.getTriggeringAbility();
if (trigSa != null) {
for (Object o : trigSa.getTriggerRemembered()) {
if (o instanceof Card) {
cards.add((Card)o);
}
}
} else {
System.err.println("Warning: couldn't find trigger SA in the chain of SpellAbility " + sa);
}
} else if (defined.equals("DelayTriggerRemembered")) {
SpellAbility trigSa = sa.getTriggeringAbility();
if (trigSa != null) {

View File

@@ -40,6 +40,7 @@ public enum ApiType {
ChooseCard (ChooseCardEffect.class),
ChooseColor (ChooseColorEffect.class),
ChooseDirection (ChooseDirectionEffect.class),
ChooseEvenOdd (ChooseEvenOddEffect.class),
ChooseNumber (ChooseNumberEffect.class),
ChoosePlayer (ChoosePlayerEffect.class),
ChooseSource (ChooseSourceEffect.class),

View File

@@ -0,0 +1,43 @@
package forge.game.ability.effects;
import forge.game.EvenOdd;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.player.Player;
import forge.game.player.PlayerController.BinaryChoiceType;
import forge.game.spellability.SpellAbility;
import forge.util.Localizer;
public class ChooseEvenOddEffect extends SpellAbilityEffect {
/* (non-Javadoc)
* @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility)
*/
@Override
protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder();
for (final Player p : getTargetPlayers(sa)) {
sb.append(p).append(" ");
}
sb.append("chooses even or odd.");
return sb.toString();
}
@Override
public void resolve(SpellAbility sa) {
final Card card = sa.getHostCard();
for (final Player p : getTargetPlayers(sa)) {
if ((!sa.usesTargeting()) || p.canBeTargetedBy(sa)) {
EvenOdd chosen = p.getController().chooseBinary(sa, "odd or even", BinaryChoiceType.OddsOrEvens) ? EvenOdd.Odd : EvenOdd.Even;
card.setChosenEvenOdd(chosen);
if (sa.hasParam("Notify")) {
p.getGame().getAction().nofityOfValue(sa, card, Localizer.getInstance().getMessage("lblPlayerPickedChosen", p.getName(), chosen), p);
}
}
}
card.updateStateForView();
}
}

View File

@@ -238,6 +238,7 @@ public class Card extends GameEntity implements Comparable<Card> {
private String chosenName = "";
private Integer chosenNumber;
private Player chosenPlayer;
private EvenOdd chosenEvenOdd = null;
private Direction chosenDirection = null;
private String chosenMode = "";
@@ -1597,6 +1598,19 @@ public class Card extends GameEntity implements Comparable<Card> {
view.updateNamedCard(this);
}
public boolean hasChosenEvenOdd() {
return chosenEvenOdd != null;
}
public EvenOdd getChosenEvenOdd() {
return chosenEvenOdd;
}
public void setChosenEvenOdd(EvenOdd chosenEvenOdd0) {
if (chosenEvenOdd == chosenEvenOdd0) { return; }
chosenEvenOdd = chosenEvenOdd0;
view.updateChosenEvenOdd(this);
}
// used for cards like Meddling Mage...
public final String getNamedCard() {
return getChosenName();

View File

@@ -299,6 +299,24 @@ public final class CardPredicates {
};
}
public static final Predicate<Card> evenCMC() {
return new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return c.getCMC() % 2 == 0;
}
};
}
public static final Predicate<Card> oddCMC() {
return new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return c.getCMC() % 2 == 1;
}
};
}
public static final Predicate<Card> hasCounters() {
return new Predicate<Card>() {
@Override

View File

@@ -4,6 +4,7 @@ import com.google.common.collect.Iterables;
import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.game.Direction;
import forge.game.EvenOdd;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.GameObject;
@@ -1372,6 +1373,27 @@ public class CardProperty {
if (card.getNetPower() >= card.getNetToughness()) {
return false;
}
} else if (property.equals("cmcEven")) {
if (card.getCMC() % 2 != 0) {
return false;
}
} else if (property.equals("cmcOdd")) {
if (card.getCMC() % 2 != 1) {
return false;
}
} else if (property.equals("cmcChosenEvenOdd")) {
if (!source.hasChosenEvenOdd()) {
return false;
}
if ((card.getCMC() % 2 == 0) != (source.getChosenEvenOdd() == EvenOdd.Even)) {
return false;
}
} else if (property.equals("cmcNotChosenEvenOdd")) {
if (source.hasChosenEvenOdd()) {
if ((card.getCMC() % 2 == 0) == (source.getChosenEvenOdd() == EvenOdd.Even)) {
return false;
}
}
} else if (property.startsWith("power") || property.startsWith("toughness")
|| property.startsWith("cmc") || property.startsWith("totalPT")) {
int x;

View File

@@ -8,6 +8,7 @@ import forge.ImageKeys;
import forge.card.*;
import forge.card.mana.ManaCost;
import forge.game.Direction;
import forge.game.EvenOdd;
import forge.game.GameEntityView;
import forge.game.GameType;
import forge.game.combat.Combat;
@@ -304,6 +305,12 @@ public class CardView extends GameEntityView {
void updateChosenDirection(Card c) {
set(TrackableProperty.ChosenDirection, c.getChosenDirection());
}
public EvenOdd getChosenEvenOdd() {
return get(TrackableProperty.ChosenEvenOdd);
}
void updateChosenEvenOdd(Card c) {
set(TrackableProperty.ChosenEvenOdd, c.getChosenEvenOdd());
}
public String getChosenMode() {
return get(TrackableProperty.ChosenMode);
@@ -627,6 +634,13 @@ public class CardView extends GameEntityView {
sb.append("]\r\n");
}
EvenOdd chosenEvenOdd = getChosenEvenOdd();
if (chosenEvenOdd != null) {
sb.append("\r\n[Chosen value: ");
sb.append(chosenEvenOdd);
sb.append("]\r\n");
}
CardView pairedWith = getPairedWith();
if (pairedWith != null) {
sb.append("\r\n \r\nPaired With: ").append(pairedWith);

View File

@@ -220,6 +220,9 @@ public final class StaticAbilityContinuous {
if (!hostCard.hasChosenName() && input.contains("ChosenName")) {
return true;
}
if (!hostCard.hasChosenEvenOdd() && (input.contains("ChosenEvenOdd") || input.contains("chosenEvenOdd"))) {
return true;
}
// two variants for Red vs. red in keyword
if (input.contains("ColorsYouCtrl") || input.contains("colorsYouCtrl")) {
@@ -261,6 +264,10 @@ public final class StaticAbilityContinuous {
final String chosenName = hostCard.getChosenName().replace(",", ";");
input = input.replaceAll("ChosenName", "Card.named" + chosenName);
}
if (hostCard.hasChosenEvenOdd()) {
input = input.replaceAll("ChosenEvenOdd", hostCard.getChosenEvenOdd().toString());
input = input.replaceAll("chosenEvenOdd", hostCard.getChosenEvenOdd().toString().toLowerCase());
}
input = input.replace("HostCardUID", hostCardUID);
return input;
}

View File

@@ -17,9 +17,9 @@
*/
package forge.game.staticability;
import forge.game.CardTraitBase;
import forge.game.card.Card;
import java.util.Map;
/**
* The Class StaticAbility_CantBeCast.
@@ -36,11 +36,15 @@ public class StaticAbilityETBTapped {
* @return true, if successful
*/
public static boolean applyETBTappedAbility(final StaticAbility stAb, final Card card) {
final Map<String, String> params = stAb.getMapParams();
final Card hostCard = stAb.getHostCard();
return !params.containsKey("ValidCard")
|| card.isValid(params.get("ValidCard").split(","), hostCard.getController(), hostCard, null);
if (stAb.hasParam("ValidCard")) {
if (!CardTraitBase.matchesValid(card, stAb.getParam("ValidCard").split(","), hostCard)) {
return false;
}
}
return true;
}
}

View File

@@ -1,7 +1,9 @@
package forge.trackable;
import forge.card.CardRarity;
import forge.game.Direction;
import forge.game.EvenOdd;
import forge.game.GameType;
import forge.game.phase.PhaseType;
import forge.game.zone.ZoneType;
@@ -46,6 +48,7 @@ public enum TrackableProperty {
ChosenCards(TrackableTypes.CardViewCollectionType),
ChosenPlayer(TrackableTypes.PlayerViewType),
ChosenDirection(TrackableTypes.EnumType(Direction.class)),
ChosenEvenOdd(TrackableTypes.EnumType(EvenOdd.class)),
ChosenMode(TrackableTypes.StringType),
Remembered(TrackableTypes.StringType),
NamedCard(TrackableTypes.StringType),

View File

@@ -1,15 +1,10 @@
Name:Ashling's Prerogative
ManaCost:1 R
Types:Enchantment
K:ETBReplacement:Other:ChooseMode
SVar:ChooseMode:DB$ ChooseNumber | Defined$ You | Min$ 0 | Max$ 1 | ListTitle$ Choose ODD or EVEN (0=Even; 1=Odd) | SpellDescription$ As CARDNAME enters the battlefield, choose odd or even. (Zero is even.)
S:Mode$ Continuous | Affected$ Creature.cmcM2X | AddKeyword$ Haste | Description$ Each creature with converted mana cost of the chosen value has haste.
S:Mode$ ETBTapped | ValidCard$ Creature.cmcM2Y | Description$ Each creature without converted mana cost of the chosen value enters the battlefield tapped.
# The next 2 static abilities add text to the card panel for convenience indicating choice.
S:Mode$ Continuous | Affected$ Card.Self | AddHiddenKeyword$ Chosen:EVEN | CheckSVar$ X | SVarCompare$ EQ0
S:Mode$ Continuous | Affected$ Card.Self | AddHiddenKeyword$ Chosen:ODD | CheckSVar$ X | SVarCompare$ EQ1
SVar:X:Count$ChosenNumber
SVar:Y:Number$ChosenNumber/Plus.1
K:ETBReplacement:Other:ChooseEvenOdd
SVar:ChooseEvenOdd:DB$ ChooseEvenOdd | Defined$ You | ListTitle$ Choose ODD or EVEN | AILogic$ CMCInHand | SpellDescription$ As CARDNAME enters the battlefield, choose odd or even. (Zero is even.)
S:Mode$ Continuous | Affected$ Creature.cmcChosenEvenOdd | AddKeyword$ Haste | Description$ Each creature with converted mana cost of the chosen value has haste.
S:Mode$ ETBTapped | ValidCard$ Creature.cmcNotChosenEvenOdd | Description$ Each creature without converted mana cost of the chosen value enters the battlefield tapped.
AI:RemoveDeck:All
SVar:Picture:http://www.wizards.com/global/images/magic/general/ashlings_prerogative.jpg
Oracle:As Ashling's Prerogative enters the battlefield, choose odd or even. (Zero is even.)\nEach creature with converted mana cost of the chosen value has haste.\nEach creature without converted mana cost of the chosen value enters the battlefield tapped.

View File

@@ -2,8 +2,6 @@ Name:Extinction Event
ManaCost:3 B
Types:Sorcery
A:SP$ GenericChoice | Cost$ 3 B | Choices$ Odd,Even | Defined$ You | StackDescription$ SpellDescription | SpellDescription$ Choose odd or even. Exile each creature with converted mana cost of the chosen value. (Zero is even.)
SVar:Odd:DB$ ChangeZoneAll | ChangeType$ Creature.cmcM2Y | References$ Y | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Odd
SVar:Even:DB$ ChangeZoneAll | ChangeType$ Creature.cmcM2X | References$ X | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Even
SVar:X:Count$0
SVar:Y:Count$1
SVar:Odd:DB$ ChangeZoneAll | ChangeType$ Creature.cmcOdd | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Odd
SVar:Even:DB$ ChangeZoneAll | ChangeType$ Creature.cmcEven | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Even
Oracle:Choose odd or even. Exile each creature with converted mana cost of the chosen value. (Zero is even.)

View File

@@ -6,8 +6,8 @@ K:Flying
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigFight | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may have it fight target creature you don't control.
SVar:TrigFight:DB$ Fight | Defined$ TriggeredCardLKICopy | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Choose target creature you don't control
T:Mode$ Fight | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ DelTrigPutCounter | TriggerDescription$ Whenever a creature you control fights, put two +1/+1 counters on it at the beginning of the next end step.
SVar:DelTrigPutCounter:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigPutCounter | RememberObjects$ TriggeredFighter | TriggerDescription$ Put two +1/+1 counters on it at the beginning of the next end step.
SVar:TrigPutCounter:DB$ PutCounter | Defined$ DelayTriggerRemembered | CounterType$ P1P1 | CounterNum$ 2
SVar:DelTrigPutCounter:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigPutCounter | RememberObjects$ TriggeredFighterLKICopy | TriggerDescription$ Put two +1/+1 counters on it at the beginning of the next end step.
SVar:TrigPutCounter:DB$ PutCounter | Defined$ DelayTriggerRememberedLKI | CounterType$ P1P1 | CounterNum$ 2
DeckHas:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/foe_razer_regent.jpg
Oracle:Flying\nWhen Foe-Razer Regent enters the battlefield, you may have it fight target creature you don't control.\nWhenever a creature you control fights, put two +1/+1 counters on it at the beginning of the next end step.

View File

@@ -5,5 +5,5 @@ PT:6/1
K:CARDNAME attacks each combat if able.
K:ETBReplacement:Other:ChooseNum
SVar:ChooseNum:DB$ ChooseNumber | Min$ 2 | Max$ 4 | Defined$ You | Random$ True | SpellDescription$ As Haktos enters the battlefield, choose 2, 3, or 4 at random.
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Protection:Card.cmcNEChosenNumber:Protection from each converted mana cost other than ChosenNumber | Description$ CARDNAME has protection from each converted mana cost other than the chosen number.
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Protection:Card.cmcNEChosenNumber,Emblem:Protection from each converted mana cost other than ChosenNumber | Description$ CARDNAME has protection from each converted mana cost other than the chosen number.
Oracle:Haktos the Unscarred attacks each combat if able.\nAs Haktos enters the battlefield, choose 2, 3, or 4 at random.\nHaktos has protection from each converted mana cost other than the chosen number.

View File

@@ -0,0 +1,8 @@
Name:Lavabrink Venturer
ManaCost:2 W
Types:Creature Human Soldier
PT:3/3
K:ETBReplacement:Other:ChooseEvenOdd
SVar:ChooseEvenOdd:DB$ ChooseEvenOdd | Defined$ You | AILogic$ CMCOppControlsByPower | SpellDescription$ As CARDNAME enters the battlefield, choose odd or even. (Zero is even.)
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Protection:Card.cmcChosenEvenOdd,Emblem.cmcChosenEvenOdd:Protection from each converted mana cost of chosenEvenOdd. | Description$ CARDNAME has protection from each converted mana cost of the chosen value.
Oracle:As Lavabrink Venturer enters the battlefield, choose odd or even. (Zero is even.)\nLavabrink Venturer has protection from each converted mana cost of the chosen value.

View File

@@ -8,7 +8,7 @@ R:Event$ DamageDone | ActiveZones$ Battlefield | ValidTarget$ Card.Self | Replac
SVar:Counters:DB$ RemoveCounter | Defined$ ReplacedTarget | CounterType$ P1P1 | CounterNum$ Y | References$ Y
SVar:Y:ReplaceCount$DamageAmount
T:Mode$ CounterRemoved | ValidCard$ Card.Self | TriggerZones$ Battlefield | CounterType$ P1P1 | Execute$ ProteanPutCounter | TriggerDescription$ Whenever a +1/+1 counter is removed from CARDNAME, put two +1/+1 counters on it at the beginning of the next end step.
SVar:ProteanPutCounter:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ DBPutCounters | TriggerDescription$ Put two +1/+1 counters on it at the beginning of the next end step.
SVar:DBPutCounters:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 2
SVar:ProteanPutCounter:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ DBPutCounters | RememberObjects$ TriggeredCardLKICopy | TriggerDescription$ Put two +1/+1 counters on it at the beginning of the next end step.
SVar:DBPutCounters:DB$ PutCounter | Defined$ DelayTriggerRememberedLKI | CounterType$ P1P1 | CounterNum$ 2
SVar:Picture:http://www.wizards.com/global/images/magic/general/protean_hydra.jpg
Oracle:Protean Hydra enters the battlefield with X +1/+1 counters on it.\nIf damage would be dealt to Protean Hydra, prevent that damage and remove that many +1/+1 counters from it.\nWhenever a +1/+1 counter is removed from Protean Hydra, put two +1/+1 counters on it at the beginning of the next end step.

View File

@@ -2,10 +2,10 @@ Name:Simic Ascendancy
ManaCost:G U
Types:Enchantment
A:AB$ PutCounter | Cost$ 1 G U | CounterType$ P1P1 | CounterNum$ 1 | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | SpellDescription$ Put a +1/+1 counter on target creature you control.
T:Mode$ CounterAddedOnce | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | CounterType$ P1P1 | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more +1/+1 counters are put on a creature you control, put that many growth counters on CARDNAME.
T:Mode$ CounterAddedOnce | ValidCard$ Creature.YouCtrl+inZoneBattlefield | TriggerZones$ Battlefield | CounterType$ P1P1 | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more +1/+1 counters are put on a creature you control, put that many growth counters on CARDNAME.
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ GROWTH | CounterNum$ X | References$ X
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Card.Self+counters_GE20_GROWTH | Execute$ TrigWinGame | TriggerDescription$ At the beginning of your upkeep, if CARDNAME has twenty or more growth counters on it, you win the game.
SVar:TrigWinGame:DB$WinsGame | Defined$ You
SVar:TrigWinGame:DB$ WinsGame | Defined$ You
SVar:X:TriggerCount$Amount
DeckHints:Ability$Counters
DeckHas:Ability$Counters

View File

@@ -2,9 +2,8 @@ Name:Void Winnower
ManaCost:9
Types:Creature Eldrazi
PT:11/9
S:Mode$ CantBeCast | ValidCard$ Card.cmcM2X | Caster$ Opponent | Description$ Your opponents can't cast spells with even converted mana costs. (Zero is even.)
S:Mode$ Continuous | Affected$ Creature.OppCtrl+cmcM2X | AddHiddenKeyword$ CARDNAME can't block. | Description$ Your opponents can't block with creatures with even converted mana costs.
SVar:X:Count$0
S:Mode$ CantBeCast | ValidCard$ Card.cmcEven | Caster$ Opponent | Description$ Your opponents can't cast spells with even converted mana costs. (Zero is even.)
S:Mode$ Continuous | Affected$ Creature.OppCtrl+cmcEven | AddHiddenKeyword$ CARDNAME can't block. | Description$ Your opponents can't block with creatures with even converted mana costs.
SVar:PlayMain1:TRUE
SVar:Picture:http://www.wizards.com/global/images/magic/general/void_winnower.jpg
Oracle:Your opponents can't cast spells with even converted mana costs. (Zero is even.)\nYour opponents can't block with creatures with even converted mana costs.

View File

@@ -7,8 +7,7 @@ K:Vigilance
K:Menace
T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigReveal | TriggerDescription$ Whenever CARDNAME attacks, reveal the top card of your library. If that card's converted mana cost is odd, you may cast it without paying its mana cost. Otherwise, draw a card.
SVar:TrigReveal:DB$ PeekAndReveal | PeekAmount$ 1 | RevealValid$ Card | RememberRevealed$ True | SubAbility$ DBMayCast
SVar:DBMayCast:DB$ Play | Defined$ Remembered | ForgetRemembered$ True | WithoutManaCost$ True | Optional$ True | ConditionDefined$ Remembered | ConditionCheckSVar$ X | ConditionSVarCompare$ M21 | References$ X | SubAbility$ DBDraw
SVar:DBMayCast:DB$ Play | Defined$ Remembered | ForgetRemembered$ True | WithoutManaCost$ True | Optional$ True | ConditionDefined$ Remembered | ConditionPresent$ Card.cmcOdd | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Remembered$CardManaCost
Oracle:Flying,vigilance,menace\nWhenever Yennett, Cryptic Sovereign attacks, reveal the top card of your library. If that card's converted mana cost is odd, you may cast it without paying its mana cost. Otherwise, draw a card.