mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Merge branch 'master' of git.cardforge.org:core-developers/forge into agetian-master
This commit is contained in:
@@ -901,7 +901,7 @@ public class AiController {
|
||||
return canPlayFromEffectAI((SpellPermanent)sa, false, true);
|
||||
}
|
||||
if (sa.usesTargeting()) {
|
||||
if (!sa.isTargetNumberValid() && !sa.getTargetRestrictions().hasCandidates(sa)) {
|
||||
if (!sa.isTargetNumberValid() && sa.getTargetRestrictions().getNumCandidates(sa, true) == 0) {
|
||||
return AiPlayDecision.TargetingFailed;
|
||||
}
|
||||
if (!StaticAbilityMustTarget.meetsMustTargetRestriction(sa)) {
|
||||
@@ -1622,6 +1622,7 @@ public class AiController {
|
||||
Map<String, String> params = t.getMapParams();
|
||||
if ("ChangesZone".equals(params.get("Mode"))
|
||||
&& params.containsKey("ValidCard")
|
||||
&& (!params.containsKey("AILogic") || !params.get("AILogic").equals("SafeToHold"))
|
||||
&& !params.get("ValidCard").contains("nonLand")
|
||||
&& ((params.get("ValidCard").contains("Land")) || (params.get("ValidCard").contains("Permanent")))
|
||||
&& "Battlefield".equals(params.get("Destination"))) {
|
||||
|
||||
@@ -1871,7 +1871,7 @@ public class ComputerUtilCard {
|
||||
return oppCards;
|
||||
}
|
||||
|
||||
CardCollection aiCreats = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
||||
CardCollection aiCreats = ai.getCreaturesInPlay();
|
||||
if (temporary) {
|
||||
// Pump effects that add "CARDNAME can't attack" and similar things. Only do it if something is untapped.
|
||||
oppCards = CardLists.filter(oppCards, CardPredicates.Presets.UNTAPPED);
|
||||
|
||||
@@ -162,21 +162,21 @@ public abstract class SpellAbilityAi {
|
||||
*/
|
||||
protected boolean checkApiLogic(final Player ai, final SpellAbility sa) {
|
||||
if (ComputerUtil.preventRunAwayActivations(sa)) {
|
||||
return false; // prevent infinite loop
|
||||
return false; // prevent infinite loop
|
||||
}
|
||||
return MyRandom.getRandom().nextFloat() < .8f; // random success
|
||||
}
|
||||
|
||||
public final boolean doTriggerAI(final Player aiPlayer, final SpellAbility sa, final boolean mandatory) {
|
||||
// this evaluation order is currently intentional as it does more stuff that helps avoiding some crashes
|
||||
if (!ComputerUtilCost.canPayCost(sa, aiPlayer) && !mandatory) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// a mandatory SpellAbility with targeting but without candidates,
|
||||
// does not need to go any deeper
|
||||
if (sa.usesTargeting() && mandatory && !sa.isTargetNumberValid()
|
||||
&& !sa.getTargetRestrictions().hasCandidates(sa)) {
|
||||
return false;
|
||||
if (sa.usesTargeting() && mandatory && sa.getTargetRestrictions().getNumCandidates(sa, true) == 0) {
|
||||
return sa.isTargetNumberValid();
|
||||
}
|
||||
|
||||
return doTriggerNoCostWithSubs(aiPlayer, sa, mandatory);
|
||||
|
||||
@@ -1699,19 +1699,21 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
if (card.isToken()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (card.isCreature() && ComputerUtilCard.isUselessCreature(decider, card)) {
|
||||
return true;
|
||||
} else if (card.isEquipped()) {
|
||||
}
|
||||
if (card.isEquipped()) {
|
||||
return false;
|
||||
} else if (card.isEnchanted()) {
|
||||
}
|
||||
if (card.isEnchanted()) {
|
||||
for (Card enc : card.getEnchantedBy()) {
|
||||
if (enc.getOwner().isOpponentOf(decider)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (card.hasCounters()) {
|
||||
}
|
||||
if (card.hasCounters()) {
|
||||
if (card.isPlaneswalker()) {
|
||||
int maxLoyaltyToConsider = 2;
|
||||
int loyaltyDiff = 2;
|
||||
|
||||
@@ -392,15 +392,19 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
||||
PlayerPredicates.isTargetableBy(sa)));
|
||||
|
||||
if (oppList.isEmpty()) {
|
||||
if (mandatory && !sa.isTargetNumberValid() && sa.canTarget(ai)) {
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(ai);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the one with the most handsize
|
||||
Player oppTarget = Collections.max(oppList,
|
||||
PlayerPredicates.compareByZoneSize(origin));
|
||||
Player oppTarget = Collections.max(oppList, PlayerPredicates.compareByZoneSize(origin));
|
||||
|
||||
// set the target
|
||||
if (!oppTarget.getCardsIn(ZoneType.Hand).isEmpty()) {
|
||||
if (!oppTarget.getCardsIn(ZoneType.Hand).isEmpty() || mandatory) {
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(oppTarget);
|
||||
} else {
|
||||
@@ -434,7 +438,12 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
||||
PlayerPredicates.isTargetableBy(sa)));
|
||||
|
||||
if (oppList.isEmpty()) {
|
||||
return false;
|
||||
if (mandatory && !sa.isTargetNumberValid() && sa.canTarget(ai)) {
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(ai);
|
||||
return true;
|
||||
}
|
||||
return sa.isTargetNumberValid();
|
||||
}
|
||||
|
||||
// get the one with the most in graveyard
|
||||
@@ -443,7 +452,7 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
||||
AiPlayerPredicates.compareByZoneValue(sa.getParam("ChangeType"), origin, sa));
|
||||
|
||||
// set the target
|
||||
if (!oppTarget.getCardsIn(ZoneType.Graveyard).isEmpty()) {
|
||||
if (!oppTarget.getCardsIn(ZoneType.Graveyard).isEmpty() || mandatory) {
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(oppTarget);
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,6 @@ import forge.ai.AiAttackController;
|
||||
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 {
|
||||
@@ -14,8 +13,7 @@ public class ChooseEvenOddAi extends SpellAbilityAi {
|
||||
if (!sa.hasParam("AILogic")) {
|
||||
return false;
|
||||
}
|
||||
TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt != null) {
|
||||
if (sa.usesTargeting()) {
|
||||
sa.resetTargets();
|
||||
Player opp = AiAttackController.choosePreferredDefenderPlayer(aiPlayer);
|
||||
if (sa.canTarget(opp)) {
|
||||
@@ -34,4 +32,3 @@ public class ChooseEvenOddAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import forge.ai.SpellAbilityAi;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
public class ChooseNumberAi extends SpellAbilityAi {
|
||||
@@ -44,8 +43,7 @@ public class ChooseNumberAi extends SpellAbilityAi {
|
||||
return ownCreatureCount > oppMaxCreatureCount + 2 || ownCreatureCount < Math.min(oppMaxCreatureCount, maxChoiceLimit);
|
||||
}
|
||||
|
||||
TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt != null) {
|
||||
if (sa.usesTargeting()) {
|
||||
sa.resetTargets();
|
||||
Player opp = AiAttackController.choosePreferredDefenderPlayer(aiPlayer);
|
||||
if (sa.canTarget(opp)) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
@@ -52,8 +51,7 @@ public class ChooseSourceAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt != null) {
|
||||
if (sa.usesTargeting()) {
|
||||
sa.resetTargets();
|
||||
Player opp = AiAttackController.choosePreferredDefenderPlayer(ai);
|
||||
if (sa.canTarget(opp)) {
|
||||
|
||||
@@ -108,7 +108,7 @@ public class ChooseTypeAi extends SpellAbilityAi {
|
||||
|
||||
@Override
|
||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||
boolean isCurse = sa.hasParam("IsCurse");
|
||||
boolean isCurse = sa.isCurse();
|
||||
|
||||
if (sa.usesTargeting()) {
|
||||
final List<Player> oppList = Lists.newArrayList(Iterables.filter(
|
||||
|
||||
@@ -92,7 +92,7 @@ public class ClashAi extends SpellAbilityAi {
|
||||
if ("Creature".equals(valid)) {
|
||||
// Springjack Knight
|
||||
// TODO: Whirlpool Whelm also uses creature targeting but it's trickier to support
|
||||
CardCollectionView aiCreats = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
||||
CardCollectionView aiCreats = ai.getCreaturesInPlay();
|
||||
CardCollectionView oppCreats = CardLists.filter(ai.getOpponents().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
||||
|
||||
Card tgt = aiCreats.isEmpty() ? ComputerUtilCard.getWorstCreatureAI(oppCreats) : ComputerUtilCard.getBestCreatureAI(aiCreats);
|
||||
|
||||
@@ -16,7 +16,6 @@ import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.spellability.Spell;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
public class CopySpellAbilityAi extends SpellAbilityAi {
|
||||
@@ -58,8 +57,7 @@ public class CopySpellAbilityAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt != null) {
|
||||
if (sa.usesTargeting()) {
|
||||
// Filter AI-specific targets if provided
|
||||
if ("OnlyOwned".equals(sa.getParam("AITgts"))) {
|
||||
if (!top.getActivatingPlayer().equals(aiPlayer)) {
|
||||
|
||||
@@ -27,7 +27,6 @@ import forge.game.cost.CostSacrifice;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
@@ -63,8 +62,7 @@ public class CounterAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt != null) {
|
||||
if (sa.usesTargeting()) {
|
||||
final SpellAbility topSA = ComputerUtilAbility.getTopSpellAbilityOnStack(game, sa);
|
||||
if (!CardFactoryUtil.isCounterableBy(topSA.getHostCard(), sa) || topSA.getActivatingPlayer() == ai
|
||||
|| ai.getAllies().contains(topSA.getActivatingPlayer())) {
|
||||
@@ -246,10 +244,9 @@ public class CounterAi extends SpellAbilityAi {
|
||||
|
||||
@Override
|
||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
final Game game = ai.getGame();
|
||||
|
||||
if (tgt != null) {
|
||||
if (sa.usesTargeting()) {
|
||||
if (game.getStack().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -442,7 +442,7 @@ public class CountersPutAi extends CountersAi {
|
||||
}
|
||||
}
|
||||
|
||||
if ("AlwaysAtOppEOT".equals(logic)) {
|
||||
if ("AtOppEOT".equals(logic)) {
|
||||
if (ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn().equals(ai)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -76,8 +76,8 @@ public abstract class DamageAiBase extends SpellAbilityAi {
|
||||
Card hostcard = sa.getHostCard();
|
||||
for (Trigger trig : hostcard.getTriggers()) {
|
||||
if (trig.getMode() == TriggerType.DamageDone) {
|
||||
if (("Opponent".equals(trig.getParam("ValidTarget")))
|
||||
&& (!"True".equals(trig.getParam("CombatDamage")))) {
|
||||
if ("Opponent".equals(trig.getParam("ValidTarget"))
|
||||
&& !"True".equals(trig.getParam("CombatDamage"))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,7 +448,8 @@ public class DamageDealAi extends DamageAiBase {
|
||||
|
||||
// We can hurt a planeswalker, so rank the one which is the best target
|
||||
if (!hPlay.isEmpty() && pl.isOpponentOf(ai) && activator.equals(ai)) {
|
||||
return ComputerUtilCard.getBestPlaneswalkerToDamage(hPlay);
|
||||
Card pw = ComputerUtilCard.getBestPlaneswalkerToDamage(hPlay);
|
||||
return pw == null && mandatory ? hPlay.get(0) : pw;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -713,7 +714,7 @@ public class DamageDealAi extends DamageAiBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (freePing && sa.canTarget(enemy) && (!avoidTargetP(ai, sa))) {
|
||||
if (freePing && sa.canTarget(enemy) && !avoidTargetP(ai, sa)) {
|
||||
tcs.add(enemy);
|
||||
if (divided) {
|
||||
sa.addDividedAllocation(enemy, dmg);
|
||||
|
||||
@@ -91,8 +91,7 @@ public class DebuffAi extends SpellAbilityAi {
|
||||
@Override
|
||||
public boolean chkAIDrawback(SpellAbility sa, Player ai) {
|
||||
if (!sa.usesTargeting()) {
|
||||
// TODO - copied from AF_Pump.pumpDrawbackAI() - what should be
|
||||
// here?
|
||||
// TODO - copied from AF_Pump.pumpDrawbackAI() - what should be here?
|
||||
} else {
|
||||
return debuffTgtAI(ai, sa, sa.hasParam("Keywords") ? Arrays.asList(sa.getParam("Keywords").split(" & ")) : null, false);
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ public class DestroyAi extends SpellAbilityAi {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
Card c = ComputerUtilCard.getBestAI(preferred);
|
||||
@@ -380,7 +380,7 @@ public class DestroyAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
while (sa.canAddMoreTarget()) {
|
||||
while (!sa.isMinTargetChosen()) {
|
||||
if (list.isEmpty()) {
|
||||
break;
|
||||
} else {
|
||||
|
||||
@@ -148,7 +148,7 @@ public class DestroyAllAi extends SpellAbilityAi {
|
||||
for (Card att : opponent.getCreaturesInPlay()) {
|
||||
if (ComputerUtilCombat.canAttackNextTurn(att, ai)) {
|
||||
combat.addAttacker(att, ai);
|
||||
containsAttacker = containsAttacker | opplist.contains(att);
|
||||
containsAttacker = containsAttacker || opplist.contains(att);
|
||||
}
|
||||
}
|
||||
if (!containsAttacker) {
|
||||
|
||||
@@ -61,7 +61,7 @@ public class DigAi extends SpellAbilityAi {
|
||||
|
||||
if ("Never".equals(sa.getParam("AILogic"))) {
|
||||
return false;
|
||||
} else if ("AtOppEndOfTurn".equals(sa.getParam("AILogic"))) {
|
||||
} else if ("AtOppEOT".equals(sa.getParam("AILogic"))) {
|
||||
if (!(game.getPhaseHandler().getNextTurn() == ai && game.getPhaseHandler().is(PhaseType.END_OF_TURN))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class DigMultipleAi extends SpellAbilityAi {
|
||||
|
||||
if ("Never".equals(sa.getParam("AILogic"))) {
|
||||
return false;
|
||||
} else if ("AtOppEndOfTurn".equals(sa.getParam("AILogic"))) {
|
||||
} else if ("AtOppEOT".equals(sa.getParam("AILogic"))) {
|
||||
if (!(game.getPhaseHandler().getNextTurn() == ai && game.getPhaseHandler().is(PhaseType.END_OF_TURN))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -130,8 +130,7 @@ public class DigUntilAi extends SpellAbilityAi {
|
||||
if ("OathOfDruids".equals(logic)) {
|
||||
final List<Card> creaturesInLibrary =
|
||||
CardLists.filter(player.getCardsIn(ZoneType.Library), CardPredicates.Presets.CREATURES);
|
||||
final List<Card> creaturesInBattlefield =
|
||||
CardLists.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
||||
final List<Card> creaturesInBattlefield = player.getCreaturesInPlay();
|
||||
// if there are at least 3 creatures in library,
|
||||
// or none in play with one in library, oath
|
||||
return creaturesInLibrary.size() > 2
|
||||
|
||||
@@ -140,7 +140,7 @@ public class DrawAi extends SpellAbilityAi {
|
||||
// LifeLessThan logic presupposes activation as soon as possible in an
|
||||
// attempt to save the AI from dying
|
||||
return true;
|
||||
} else if (logic.equals("AlwaysAtOppEOT")) {
|
||||
} else if (logic.equals("AtOppEOT")) {
|
||||
return ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn().equals(ai);
|
||||
} else if (logic.equals("RespondToOwnActivation")) {
|
||||
return !ai.getGame().getStack().isEmpty() && ai.getGame().getStack().peekAbility().getHostCard().equals(sa.getHostCard());
|
||||
|
||||
@@ -66,7 +66,7 @@ public class FightAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
if (fighter1List.isEmpty()) {
|
||||
return true; // FIXME: shouldn't this return "false" if nothing found?
|
||||
return false;
|
||||
}
|
||||
Card fighter1 = fighter1List.get(0);
|
||||
for (Card humanCreature : humCreatures) {
|
||||
|
||||
@@ -54,7 +54,7 @@ public class FlipACoinAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return sa.isTargetNumberValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -122,9 +122,9 @@ public class LifeSetAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
// special cases when amount can't be calculated without targeting first
|
||||
if (amount == 0 && opponent != null && "TargetedPlayer$StartingLife/HalfDown".equals(source.getSVar(amountStr))) {
|
||||
if (amount == 0 && "TargetedPlayer$StartingLife/HalfDown".equals(source.getSVar(amountStr))) {
|
||||
// e.g. Torgaar, Famine Incarnate
|
||||
return doHalfStartingLifeLogic(ai, opponent, sa);
|
||||
return doHalfStartingLifeLogic(ai, opponent, sa) || mandatory;
|
||||
}
|
||||
|
||||
if (sourceName.equals("Eternity Vessel")
|
||||
@@ -160,9 +160,9 @@ public class LifeSetAi extends SpellAbilityAi {
|
||||
|
||||
private boolean doHalfStartingLifeLogic(Player ai, Player opponent, SpellAbility sa) {
|
||||
int aiAmount = ai.getStartingLife() / 2;
|
||||
int oppAmount = opponent.getStartingLife() / 2;
|
||||
int oppAmount = opponent == null ? 0 : opponent.getStartingLife() / 2;
|
||||
int aiLife = ai.getLife();
|
||||
int oppLife = opponent.getLife();
|
||||
int oppLife = opponent == null ? 0 : opponent.getLife();
|
||||
|
||||
sa.resetTargets();
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import forge.ai.SpellAbilityAi;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.game.GlobalRuleChange;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
@@ -79,6 +80,8 @@ public class ManaEffectAi extends SpellAbilityAi {
|
||||
protected boolean checkPhaseRestrictions(Player ai, SpellAbility sa, PhaseHandler ph, String logic) {
|
||||
if (logic.startsWith("ManaRitual")) {
|
||||
return ph.is(PhaseType.MAIN2, ai) || ph.is(PhaseType.MAIN1, ai);
|
||||
} else if ("AtOppEOT".equals(logic)) {
|
||||
return !ai.getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.manaBurn) && ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn() == ai;
|
||||
}
|
||||
return super.checkPhaseRestrictions(ai, sa, ph, logic);
|
||||
}
|
||||
|
||||
@@ -146,13 +146,13 @@ public class MillAi extends SpellAbilityAi {
|
||||
|
||||
// can't target opponent?
|
||||
if (list.isEmpty()) {
|
||||
if (mandatory && sa.canTarget(ai)) {
|
||||
if (mandatory && !sa.isTargetNumberValid() && sa.canTarget(ai)) {
|
||||
sa.getTargets().add(ai);
|
||||
return true;
|
||||
}
|
||||
// TODO Obscure case when you know what your top card is so you might?
|
||||
// want to mill yourself here
|
||||
return false;
|
||||
return sa.isTargetNumberValid();
|
||||
}
|
||||
|
||||
// select Player which would cause the most damage
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.util.Map;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.ai.AiCardMemory;
|
||||
import forge.ai.ComputerUtilCard;
|
||||
@@ -15,14 +14,12 @@ import forge.game.Game;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.combat.CombatUtil;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
public class MustBlockAi extends SpellAbilityAi {
|
||||
|
||||
@@ -76,7 +73,7 @@ public class MustBlockAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
Card attacker = null;
|
||||
Card attacker = source;
|
||||
if (sa.hasParam("DefinedAttacker")) {
|
||||
final List<Card> cards = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedAttacker"), sa);
|
||||
if (cards.isEmpty()) {
|
||||
@@ -86,18 +83,12 @@ public class MustBlockAi extends SpellAbilityAi {
|
||||
attacker = cards.get(0);
|
||||
}
|
||||
|
||||
if (attacker == null) {
|
||||
attacker = source;
|
||||
}
|
||||
|
||||
final Card definedAttacker = attacker;
|
||||
|
||||
boolean chance = false;
|
||||
|
||||
if (sa.usesTargeting()) {
|
||||
final List<Card> list = determineGoodBlockers(definedAttacker, ai, ai.getWeakestOpponent(), sa, true,true);
|
||||
final List<Card> list = determineGoodBlockers(attacker, ai, ai.getWeakestOpponent(), sa, true, true);
|
||||
if (list.isEmpty()) {
|
||||
return false;
|
||||
return sa.isTargetNumberValid();
|
||||
}
|
||||
final Card blocker = ComputerUtilCard.getBestCreatureAI(list);
|
||||
if (blocker == null) {
|
||||
@@ -160,8 +151,7 @@ public class MustBlockAi extends SpellAbilityAi {
|
||||
|
||||
private List<Card> determineGoodBlockers(final Card attacker, final Player ai, Player defender, SpellAbility sa,
|
||||
final boolean onlyLethal, final boolean testTapped) {
|
||||
List<Card> list = Lists.newArrayList();
|
||||
list = CardLists.filter(defender.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
||||
List<Card> list = defender.getCreaturesInPlay();
|
||||
|
||||
if (sa.usesTargeting()) {
|
||||
list = CardLists.getTargetableCards(list, sa);
|
||||
@@ -187,7 +177,7 @@ public class MustBlockAi extends SpellAbilityAi {
|
||||
List<Card> better = determineBlockerFromList(attacker, ai, options, sa, false, false);
|
||||
|
||||
if (!better.isEmpty()) {
|
||||
return Iterables.getFirst(options, null);
|
||||
return Iterables.getFirst(better, null);
|
||||
}
|
||||
|
||||
return Iterables.getFirst(options, null);
|
||||
|
||||
@@ -63,7 +63,7 @@ public class PhasesAi extends SpellAbilityAi {
|
||||
return true;
|
||||
} else if (mandatory) {
|
||||
// not enough preferred targets, but mandatory so keep going:
|
||||
return phasesUnpreferredTargeting(aiPlayer.getGame(), sa, mandatory);
|
||||
return sa.isTargetNumberValid() || phasesUnpreferredTargeting(aiPlayer.getGame(), sa, mandatory);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -23,7 +23,6 @@ import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
public class PumpAllAi extends PumpAiBase {
|
||||
@@ -57,19 +56,20 @@ public class PumpAllAi extends PumpAiBase {
|
||||
}
|
||||
}
|
||||
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
final Player opp = ai.getStrongestOpponent();
|
||||
|
||||
if (tgt != null && sa.canTarget(opp) && sa.isCurse()) {
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(opp);
|
||||
return true;
|
||||
}
|
||||
if (sa.usesTargeting()) {
|
||||
if (sa.canTarget(opp) && sa.isCurse()) {
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(opp);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tgt != null && sa.canTarget(ai) && !sa.isCurse()) {
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(ai);
|
||||
return true;
|
||||
if (sa.canTarget(ai) && !sa.isCurse()) {
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(ai);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
final int power = AbilityUtils.calculateAmount(source, sa.getParam("NumAtt"), sa);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import forge.ai.ComputerUtilCard;
|
||||
@@ -57,13 +56,13 @@ public class SacrificeAi extends SpellAbilityAi {
|
||||
private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa, boolean mandatory) {
|
||||
final Card source = sa.getHostCard();
|
||||
final boolean destroy = sa.hasParam("Destroy");
|
||||
final PlayerCollection targetableOpps = ai.getOpponents().filter(PlayerPredicates.isTargetableBy(sa));
|
||||
final Player opp = Collections.max(targetableOpps, PlayerPredicates.compareByLife());
|
||||
|
||||
if (sa.usesTargeting()) {
|
||||
if (opp == null) {
|
||||
final PlayerCollection targetableOpps = ai.getOpponents().filter(PlayerPredicates.isTargetableBy(sa));
|
||||
if (targetableOpps.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
final Player opp = targetableOpps.max(PlayerPredicates.compareByLife());
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(opp);
|
||||
if (mandatory) {
|
||||
|
||||
@@ -29,7 +29,7 @@ public class TapAllAi extends SpellAbilityAi {
|
||||
// or during upkeep/begin combat?
|
||||
|
||||
final Card source = sa.getHostCard();
|
||||
final Player opp = ai.getWeakestOpponent();
|
||||
final Player opp = ai.getStrongestOpponent();
|
||||
final Game game = ai.getGame();
|
||||
|
||||
if (game.getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_BEGIN)) {
|
||||
|
||||
@@ -10,7 +10,6 @@ import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.collect.FCollection;
|
||||
|
||||
@@ -28,8 +27,7 @@ public class TwoPilesAi extends SpellAbilityAi {
|
||||
|
||||
final Player opp = AiAttackController.choosePreferredDefenderPlayer(ai);
|
||||
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt != null) {
|
||||
if (sa.usesTargeting()) {
|
||||
sa.resetTargets();
|
||||
if (sa.canTarget(opp)) {
|
||||
sa.getTargets().add(opp);
|
||||
|
||||
@@ -12,7 +12,6 @@ import forge.game.card.Card;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
public class UnattachAllAi extends SpellAbilityAi {
|
||||
@@ -48,7 +47,6 @@ public class UnattachAllAi extends SpellAbilityAi {
|
||||
return chance;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.abilityfactory.SpellAiLogic#doTriggerAINoCost(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility, boolean)
|
||||
*/
|
||||
@@ -57,8 +55,7 @@ public class UnattachAllAi extends SpellAbilityAi {
|
||||
final Card card = sa.getHostCard();
|
||||
// Check if there are any valid targets
|
||||
List<GameObject> targets = new ArrayList<>();
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt == null) {
|
||||
if (!sa.usesTargeting()) {
|
||||
targets = AbilityUtils.getDefinedObjects(sa.getHostCard(), sa.getParam("Defined"), sa);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.Map;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
import forge.ai.AiAttackController;
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.ComputerUtilAbility;
|
||||
import forge.ai.ComputerUtilCard;
|
||||
@@ -125,11 +124,11 @@ public class UntapAi extends SpellAbilityAi {
|
||||
private static boolean untapPrefTargeting(final Player ai, final SpellAbility sa, final boolean mandatory) {
|
||||
final Card source = sa.getHostCard();
|
||||
|
||||
Player targetController = ai;
|
||||
|
||||
final PlayerCollection targetController = new PlayerCollection();
|
||||
if (sa.isCurse()) {
|
||||
// TODO search through all opponents, may need to check if different controllers allowed
|
||||
targetController = AiAttackController.choosePreferredDefenderPlayer(ai);
|
||||
targetController.addAll(ai.getOpponents());
|
||||
} else {
|
||||
targetController.add(ai);
|
||||
}
|
||||
|
||||
CardCollection list = CardLists.getTargetableCards(targetController.getCardsIn(ZoneType.Battlefield), sa);
|
||||
|
||||
@@ -156,6 +156,8 @@ public class ForgeScript {
|
||||
return sa.isKicked();
|
||||
} else if (property.equals("Loyalty")) {
|
||||
return sa.isPwAbility();
|
||||
} else if (property.equals("nonLoyalty")) {
|
||||
return !sa.isPwAbility();
|
||||
} else if (property.equals("Aftermath")) {
|
||||
return sa.isAftermath();
|
||||
} else if (property.equals("MorphUp")) {
|
||||
|
||||
@@ -1689,10 +1689,6 @@ public class AbilityUtils {
|
||||
// accept straight numbers
|
||||
if (l[0].startsWith("Number$")) {
|
||||
final String number = l[0].substring(7);
|
||||
if (number.equals("ChosenNumber")) { // TODO remove in favor of Count ChosenNumber
|
||||
int x = c.getChosenNumber() == null ? 0 : c.getChosenNumber();
|
||||
return doXMath(x, expr, c, ctb);
|
||||
}
|
||||
return doXMath(Integer.parseInt(number), expr, c, ctb);
|
||||
}
|
||||
|
||||
|
||||
@@ -272,8 +272,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
sb.append(".");
|
||||
} else if (origin.equals("Battlefield")) {
|
||||
// TODO Expand on this Description as more cards use it
|
||||
// for the non-targeted SAs when you choose what is returned on
|
||||
// resolution
|
||||
// for the non-targeted SAs when you choose what is returned on resolution
|
||||
sb.append("Return ").append(num).append(" ").append(type).append(" card(s) ");
|
||||
sb.append(" to your ").append(destination);
|
||||
}
|
||||
@@ -361,8 +360,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
sb.append(fromGraveyard);
|
||||
}
|
||||
|
||||
// this needs to be zero indexed. Top = 0, Third = 2, -1 =
|
||||
// Bottom
|
||||
// this needs to be zero indexed. Top = 0, Third = 2, -1 = Bottom
|
||||
final int libraryPosition = sa.hasParam("LibraryPosition") ? AbilityUtils.calculateAmount(host, sa.getParam("LibraryPosition"), sa) : 0;
|
||||
|
||||
if (libraryPosition == -1) {
|
||||
@@ -451,9 +449,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
sb.append(sa.getParam("AlternativeDestinationMessage"));
|
||||
Player alterDecider = player;
|
||||
if (sa.hasParam("AlternativeDecider")) {
|
||||
alterDecider = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("AlternativeDecider"), sa).get(0);
|
||||
PlayerCollection deciders = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("AlternativeDecider"), sa);
|
||||
alterDecider = deciders.isEmpty() ? null : deciders.get(0);
|
||||
}
|
||||
if (!alterDecider.getController().confirmAction(sa, PlayerActionConfirmMode.ChangeZoneToAltDestination, sb.toString())) {
|
||||
if (alterDecider != null && !alterDecider.getController().confirmAction(sa, PlayerActionConfirmMode.ChangeZoneToAltDestination, sb.toString())) {
|
||||
destination = ZoneType.smartValueOf(sa.getParam("DestinationAlternative"));
|
||||
altDest = true;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class AttackConstraints {
|
||||
|
||||
public AttackConstraints(final Combat combat) {
|
||||
final Game game = combat.getAttackingPlayer().getGame();
|
||||
possibleAttackers = CardLists.filter(combat.getAttackingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
||||
possibleAttackers = combat.getAttackingPlayer().getCreaturesInPlay();
|
||||
possibleDefenders = combat.getDefenders();
|
||||
globalRestrictions = GlobalAttackRestrictions.getGlobalRestrictions(combat.getAttackingPlayer(), possibleDefenders);
|
||||
|
||||
|
||||
@@ -171,23 +171,6 @@ public class StaticAbilityCantBeCast {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO refactor this ones using ValidSA above
|
||||
if (stAb.hasParam("NonMana") && (spellAbility.isManaAbility())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stAb.hasParam("NonLoyalty") && spellAbility.isPwAbility()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stAb.hasParam("Loyalty") && !spellAbility.isPwAbility()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stAb.hasParam("TapAbility") && !(spellAbility.getPayCosts().hasTapCost())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stAb.hasParam("NonActivatorTurn") && (activator != null)
|
||||
&& activator.getGame().getPhaseHandler().isPlayerTurn(activator)) {
|
||||
return false;
|
||||
|
||||
@@ -11,11 +11,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
@@ -84,6 +80,8 @@ public class VLobby implements ILobbyView {
|
||||
|
||||
private final StartButton btnStart = new StartButton();
|
||||
private final JPanel pnlStart = new JPanel(new MigLayout("insets 0, gap 0, wrap 2"));
|
||||
private final JComboBox gamesInMatch = new JComboBox(new String[] {"1","3","5"});
|
||||
private final JPanel gamesInMatchFrame = new JPanel(new MigLayout("insets 0, gap 0, wrap 2"));
|
||||
private final JPanel constructedFrame = new JPanel(new MigLayout("insets 0, gap 0, wrap 2")); // Main content frame
|
||||
|
||||
// Variants frame and variables
|
||||
@@ -212,11 +210,19 @@ public class VLobby implements ILobbyView {
|
||||
public final void actionPerformed(final ActionEvent arg0) {
|
||||
Runnable startGame = lobby.startGame();
|
||||
if (startGame != null) {
|
||||
if (!gamesInMatch.getSelectedItem().equals(ForgePreferences.FPref.UI_MATCHES_PER_GAME)) {
|
||||
FModel.getPreferences().setPref(FPref.UI_MATCHES_PER_GAME, (String) gamesInMatch.getSelectedItem());
|
||||
}
|
||||
startGame.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
gamesInMatchFrame.add(newLabel(localizer.getMessage("lblGamesInMatch")), "w 150px!, h 30px!");
|
||||
gamesInMatchFrame.add(gamesInMatch, "w 50px!, h 30px!");
|
||||
gamesInMatchFrame.setOpaque(false);
|
||||
gamesInMatch.setSelectedItem("3");
|
||||
pnlStart.add(gamesInMatchFrame);
|
||||
}
|
||||
|
||||
public void updateDeckPanel() {
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 W
|
||||
Types:Instant
|
||||
A:SP$ Effect | Cost$ 1 W | ValidTgts$ Player | Name$ Abeyance Effect | StaticAbilities$ STCantBeCast,STCantBeActivated | RememberObjects$ Targeted | AILogic$ BeginningOfOppTurn | SubAbility$ DBDraw | SpellDescription$ Until end of turn, target player can't cast instant or sorcery spells, and that player can't activate abilities that aren't mana abilities.
|
||||
SVar:STCantBeCast:Mode$ CantBeCast | ValidCard$ Instant,Sorcery | Caster$ Player.IsRemembered | EffectZone$ Command | Description$ Target player can't cast instant or sorcery spells, and that player can't activate abilities that aren't mana abilities.
|
||||
SVar:STCantBeActivated:Mode$ CantBeActivated | ValidCard$ Card | Activator$ Player.IsRemembered | EffectZone$ Command | NonMana$ True
|
||||
SVar:STCantBeActivated:Mode$ CantBeActivated | ValidCard$ Card | ValidSA$ Activated.nonManaAbility | Activator$ Player.IsRemembered | EffectZone$ Command
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ 1 | SpellDescription$ Draw a card.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/abeyance.jpg
|
||||
Oracle:Until end of turn, target player can't cast instant or sorcery spells, and that player can't activate abilities that aren't mana abilities.\nDraw a card.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1
|
||||
Types:Artifact
|
||||
T:Mode$ CounterAddedOnce | ValidCard$ Permanent.YouCtrl | TriggerZones$ Battlefield | CounterType$ P1P1 | Execute$ TrigToken | TriggerDescription$ Whenever one or more +1/+1 counters are put on a permanent you control, you may pay {1}. If you do, create a 1/1 colorless Servo artifact creature token.
|
||||
SVar:TrigToken:AB$ Token | Cost$ 1 | TokenAmount$ 1 | TokenScript$ c_1_1_a_servo | TokenOwner$ You | LegacyImage$ c 1 1 a servo kld
|
||||
A:AB$ PutCounter | Cost$ 3 T | ValidTgts$ Permanent,Player | TgtPrompt$ Select target player or permanent | CounterType$ ExistingCounter | CounterNum$ 1 | AILogic$ AlwaysAtOppEOT | SpellDescription$ Choose a counter on target permanent or player. Give that permanent or player another counter of that kind.
|
||||
A:AB$ PutCounter | Cost$ 3 T | ValidTgts$ Permanent,Player | TgtPrompt$ Select target player or permanent | CounterType$ ExistingCounter | CounterNum$ 1 | AILogic$ AtOppEOT | SpellDescription$ Choose a counter on target permanent or player. Give that permanent or player another counter of that kind.
|
||||
DeckHints:Ability$Counters
|
||||
AI:RemoveDeck:All
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/animation_module.jpg
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:no cost
|
||||
Types:Land
|
||||
K:Ascend
|
||||
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
|
||||
A:AB$ Draw | Cost$ 5 T | NumCards$ 1 | Activation$ Blessing | AILogic$ AlwaysAtOppEOT | SpellDescription$ Draw a card. Activate only if you have the city's blessing.
|
||||
A:AB$ Draw | Cost$ 5 T | NumCards$ 1 | Activation$ Blessing | AILogic$ AtOppEOT | SpellDescription$ Draw a card. Activate only if you have the city's blessing.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/arch_of_orazca.jpg
|
||||
Oracle:Ascend (If you control ten or more permanents, you get the city's blessing for the rest of the game.)\n{T}: Add {C}.\n{5}, {T}: Draw a card. Activate only if you have the city's blessing.
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Azami, Lady of Scrolls
|
||||
ManaCost:2 U U U
|
||||
Types:Legendary Creature Human Wizard
|
||||
PT:0/2
|
||||
A:AB$ Draw | Cost$ tapXType<1/Wizard> | NumCards$ 1 | AILogic$ AlwaysAtOppEOT | SpellDescription$ Draw a card.
|
||||
A:AB$ Draw | Cost$ tapXType<1/Wizard> | NumCards$ 1 | AILogic$ AtOppEOT | SpellDescription$ Draw a card.
|
||||
AI:RemoveDeck:Random
|
||||
DeckHints:Type$Wizard
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/azami_lady_of_scrolls.jpg
|
||||
|
||||
@@ -4,5 +4,5 @@ Types:Enchantment Aura
|
||||
K:Enchant permanent
|
||||
A:SP$ Attach | Cost$ 2 W | ValidTgts$ Permanent | AILogic$ Curse
|
||||
S:Mode$ Continuous | Affected$ Permanent.EnchantedBy | AddHiddenKeyword$ CARDNAME can't attack or block. & CARDNAME can't crew Vehicles. | Description$ Enchanted permanent can't attack, block, or crew Vehicles, and its activated abilities can't be activated unless they're mana abilities.
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.EnchantedBy | NonMana$ True
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.EnchantedBy | ValidSA$ Activated.nonManaAbility
|
||||
Oracle:Enchant permanent\nEnchanted permanent can't attack, block, or crew Vehicles, and its activated abilities can't be activated unless they're mana abilities.
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Legendary Creature Human Warrior
|
||||
PT:3/5
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ Whenever CARDNAME enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Planeswalker.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDig | Secondary$ True | TriggerDescription$ Whenever CARDNAME enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||
SVar:TrigDig:DB$ Dig | DigNum$ 7 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Planeswalker | RestRandomOrder$ True | Reveal$ True
|
||||
SVar:TrigDig:DB$ Dig | DigNum$ 7 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Planeswalker | RestRandomOrder$ True | ForceRevealToController$ True
|
||||
S:Mode$ RaiseCost | ValidCard$ Planeswalker.YouCtrl | Type$ Loyalty | Cost$ AddCounter<1/LOYALTY> | Description$ Planeswalkers' loyalty abilities you activate cost an additional [+1] to activate.
|
||||
DeckNeeds:Type$Planeswalker
|
||||
Oracle:Whenever Carth the Lion enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.\nPlaneswalkers' loyalty abilities you activate cost an additional [+1] to activate.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Consulate Turret
|
||||
ManaCost:3
|
||||
Types:Artifact
|
||||
A:AB$ PutCounter | Cost$ T | Defined$ You | CounterType$ ENERGY | CounterNum$ 1 | AILogic$ AlwaysAtOppEOT | SpellDescription$ You get {E} (an energy counter).
|
||||
A:AB$ PutCounter | Cost$ T | Defined$ You | CounterType$ ENERGY | CounterNum$ 1 | AILogic$ AtOppEOT | SpellDescription$ You get {E} (an energy counter).
|
||||
A:AB$ DealDamage | Cost$ T PayEnergy<3> | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 2 | SpellDescription$ CARDNAME deals 2 damage to target player or planeswalker.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/consulate_turret.jpg
|
||||
Oracle:{T}: You get {E} (an energy counter).\n{T}, Pay {E}{E}{E}: Consulate Turret deals 2 damage to target player or planeswalker.
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Damping Matrix
|
||||
ManaCost:3
|
||||
Types:Artifact
|
||||
S:Mode$ CantBeActivated | ValidCard$ Artifact,Creature | AffectedZone$ Battlefield | NonMana$ True | Description$ Activated abilities of artifacts and creatures can't be activated unless they're mana abilities.
|
||||
S:Mode$ CantBeActivated | ValidCard$ Artifact,Creature | ValidSA$ Activated.nonManaAbility | AffectedZone$ Battlefield | Description$ Activated abilities of artifacts and creatures can't be activated unless they're mana abilities.
|
||||
SVar:NonStackingEffect:True
|
||||
AI:RemoveDeck:Random
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/damping_matrix.jpg
|
||||
|
||||
@@ -2,10 +2,9 @@ Name:Divergent Transformations
|
||||
ManaCost:6 R
|
||||
Types:Instant
|
||||
K:Undaunted
|
||||
A:SP$ ChangeZone | Cost$ 6 R | ValidTgts$ Creature | TargetMin$ 2 | TargetMax$ 2 | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | SubAbility$ DBTransform | SpellDescription$ Exile two target creatures. For each of those creatures, its controller reveals cards from the top of their library until they reveal a creature card, puts that card onto the battlefield, then shuffles the rest into their library.
|
||||
A:SP$ ChangeZone | Cost$ 6 R | ValidTgts$ Creature | TargetMin$ 2 | TargetMax$ 2 | Origin$ Battlefield | Destination$ Exile | RememberLKI$ True | SubAbility$ DBTransform | SpellDescription$ Exile two target creatures. For each of those creatures, its controller reveals cards from the top of their library until they reveal a creature card, puts that card onto the battlefield, then shuffles the rest into their library.
|
||||
SVar:DBTransform:DB$ RepeatEach | UseImprinted$ True | DefinedCards$ DirectRemembered | ChooseOrder$ True | Zone$ Exile | RepeatSubAbility$ DBReveal | SubAbility$ DBCleanRemembered
|
||||
SVar:DBReveal:DB$ DigUntil | Defined$ ImprintedController | Amount$ 1 | Valid$ Creature | ValidDescription$ creature | RevealedDestination$ Library | RevealedLibraryPosition$ 0 | FoundDestination$ Battlefield | SubAbility$ DBCleanup | Shuffle$ True
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearImprinted$ True
|
||||
SVar:DBReveal:DB$ DigUntil | Defined$ ImprintedController | Amount$ 1 | Valid$ Creature | ValidDescription$ creature | RevealedDestination$ Library | RevealedLibraryPosition$ 0 | FoundDestination$ Battlefield | Shuffle$ True
|
||||
SVar:DBCleanRemembered:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/divergent_transformations.jpg
|
||||
Oracle:Undaunted (This spell costs {1} less to cast for each opponent.)\nExile two target creatures. For each of those creatures, its controller reveals cards from the top of their library until they reveal a creature card, puts that card onto the battlefield, then shuffles the rest into their library.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:3
|
||||
Types:Artifact
|
||||
T:Mode$ CounterAddedOnce | ValidPlayer$ You | TriggerZones$ Battlefield | CounterType$ ENERGY | Execute$ TrigPutCounter | TriggerDescription$ Whenever you get one or more {E} (energy counters), put a +1/+1 counter on target creature you control.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | CounterType$ P1P1 | CounterNum$ 1
|
||||
A:AB$ PutCounter | Cost$ 4 T | Defined$ You | CounterType$ ENERGY | CounterNum$ 1 | AILogic$ AlwaysAtOppEOT | SpellDescription$ You get {E}.
|
||||
A:AB$ PutCounter | Cost$ 4 T | Defined$ You | CounterType$ ENERGY | CounterNum$ 1 | AILogic$ AtOppEOT | SpellDescription$ You get {E}.
|
||||
DeckHas:Ability$Counters
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/fabrication_module.jpg
|
||||
Oracle:Whenever you get one or more {E} (energy counters), put a +1/+1 counter on target creature you control.\n{4}, {T}: You get {E}.
|
||||
|
||||
@@ -5,7 +5,7 @@ K:Enchant permanent
|
||||
A:SP$ Attach | Cost$ 3 W | ValidTgts$ Permanent | AITgts$ Creature | AILogic$ Curse
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME enters the battlefield, you gain 4 life.
|
||||
SVar:TrigGainLife:DB$ GainLife | LifeAmount$ 4
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.EnchantedBy | NonMana$ True | Description$ Enchanted permanent can't attack or block, and its activated abilities can't be activated unless they're mana abilities.
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.EnchantedBy | ValidSA$ Activated.nonManaAbility | Description$ Enchanted permanent can't attack or block, and its activated abilities can't be activated unless they're mana abilities.
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddHiddenKeyword$ CARDNAME can't attack or block.
|
||||
DeckHas:Ability$LifeGain
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/faiths_fetters.jpg
|
||||
|
||||
@@ -16,5 +16,5 @@ Types:Instant
|
||||
A:SP$ Effect | Cost$ W | Name$ Silence Effect | StaticAbilities$ STCantBeCast,STCantBeActivated | AILogic$ BeginningOfOppTurn | SubAbility$ DBChange | StackDescription$ SpellDescription | SpellDescription$ Your opponents can't cast spells or activate planeswalkers' loyalty abilities this turn. Exile CARDNAME.
|
||||
SVar:DBChange:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | StackDescription$ None
|
||||
SVar:STCantBeCast:Mode$ CantBeCast | EffectZone$ Command | ValidCard$ Card | Caster$ Opponent | Description$ Your opponents can't cast spells.
|
||||
SVar:STCantBeActivated:Mode$ CantBeActivated | Activator$ Opponent | EffectZone$ Command | ValidCard$ Planeswalker | Loyalty$ True | Description$ Your opponents can't activate planeswalkers' loyalty abilities.
|
||||
SVar:STCantBeActivated:Mode$ CantBeActivated | Activator$ Opponent | EffectZone$ Command | ValidCard$ Planeswalker | ValidSA$ Activated.Loyalty | Description$ Your opponents can't activate planeswalkers' loyalty abilities.
|
||||
Oracle:Your opponents can't cast spells or activate planeswalkers' loyalty abilities this turn.\nExile Revel in Silence.
|
||||
|
||||
@@ -2,10 +2,11 @@ Name:Halana and Alena, Partners
|
||||
ManaCost:2 R G
|
||||
Types:Legendary Creature Human Ranger
|
||||
PT:2/3
|
||||
K:Reach
|
||||
K:First Strike
|
||||
T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of combat on your turn, put X +1/+1 counters on another target creature you control, where X is NICKNAME's power. That creature gains haste until end of turn.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.Other+YouCtrl | TgtPrompt$ Select another target creature you control | CounterType$ P1P1 | CounterNum$ X | SubAbility$ DBPump
|
||||
SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Haste
|
||||
SVar:X:Count$CardPower
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:First strike, reach
|
||||
Oracle:At the beginning of combat on your turn, put X +1/+1 counters on another target creature you control, where X is Halana and Alena's power. That creature gains haste until end of turn.
|
||||
Oracle:First strike, reach\nAt the beginning of combat on your turn, put X +1/+1 counters on another target creature you control, where X is Halana and Alena's power. That creature gains haste until end of turn.
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Hand to Hand
|
||||
ManaCost:2 R
|
||||
Types:Enchantment
|
||||
S:Mode$ CantBeCast | ValidCard$ Instant | Phases$ BeginCombat->EndCombat | Description$ During combat, players can't cast instant spells or activate abilities that aren't mana abilities.
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card | Phases$ BeginCombat->EndCombat | NonMana$ True
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card | Phases$ BeginCombat->EndCombat | ValidSA$ Activated.nonManaAbility
|
||||
SVar:NonStackingEffect:True
|
||||
AI:RemoveDeck:Random
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/hand_to_hand.jpg
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Creature Spider
|
||||
PT:5/7
|
||||
K:Reach
|
||||
T:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ Undergrowth - When you cast this spell, reveal the top X cards of your library, where X is the number of creature cards in your graveyard. You may put a green permanent card with mana value X or less from among them onto the battlefield. Put the rest on the bottom of your library in a random order.
|
||||
SVar:TrigDig:DB$ Dig | DigNum$ X | Reveal$ True | ChangeNum$ 1 | ChangeValid$ Permanent.Green+cmcLEX | DestinationZone$ Battlefield | AILogic$ AtOppEndOfTurn | Optional$ True | RestRandomOrder$ True
|
||||
SVar:TrigDig:DB$ Dig | DigNum$ X | Reveal$ True | ChangeNum$ 1 | ChangeValid$ Permanent.Green+cmcLEX | DestinationZone$ Battlefield | AILogic$ AtOppEOT | Optional$ True | RestRandomOrder$ True
|
||||
SVar:X:Count$TypeInYourYard.Creature
|
||||
Oracle:Reach\nUndergrowth — When you cast this spell, reveal the top X cards of your library, where X is the number of creature cards in your graveyard. You may put a green permanent card with mana value X or less from among them onto the battlefield. Put the rest on the bottom of your library in a random order.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:2 G
|
||||
Types:Enchantment
|
||||
K:Phasing
|
||||
S:Mode$ Continuous | Affected$ Creature.withFlying | AddHiddenKeyword$ CARDNAME can't attack or block. | Description$ Creatures with flying can't attack or block, and their activated abilities with {T} in their costs can't be activated.
|
||||
S:Mode$ CantBeActivated | ValidCard$ Creature.withFlying | AffectedZone$ Battlefield | TapAbility$ True
|
||||
S:Mode$ CantBeActivated | ValidCard$ Creature.withFlying | ValidSA$ Activated.hasTapCost | AffectedZone$ Battlefield
|
||||
AI:RemoveDeck:Random
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/katabatic_winds.jpg
|
||||
Oracle:Phasing (This phases in or out before you untap during each of your untap steps. While it's phased out, it's treated as though it doesn't exist.)\nCreatures with flying can't attack or block, and their activated abilities with {T} in their costs can't be activated.
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:2
|
||||
Types:Artifact
|
||||
A:AB$ Pump | Cost$ T Discard<1/Card> | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ HIDDEN Unblockable | SpellDescription$ Up to one target creature can't be blocked this turn.
|
||||
T:Mode$ Untaps | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME becomes untapped, you may pay {2}. If you do, draw a card.
|
||||
SVar:TrigDraw:AB$Draw | Cost$ 2 | Defined$ You | NumCards$ 1
|
||||
SVar:TrigDraw:AB$ Draw | Cost$ 2 | Defined$ You | NumCards$ 1
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/key_to_the_city.jpg
|
||||
Oracle:{T}, Discard a card: Up to one target creature can't be blocked this turn.\nWhenever Key to the City becomes untapped, you may pay {2}. If you do, draw a card.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 G U
|
||||
Types:Legendary Creature Merfolk Shaman
|
||||
PT:2/4
|
||||
A:AB$ Pump | Cost$ tapXType<1/Merfolk.Other> | CostDesc$ Tap another untapped Merfolk you control: | Defined$ Self | KW$ HIDDEN Unblockable | AILogic$ BeforeCombat | SpellDescription$ CARDNAME can't be blocked this turn.
|
||||
A:AB$ Draw | Cost$ tapXType<3/Merfolk> | CostDesc$ Tap three untapped Merfolk you control: | NumCards$ 1 | AILogic$ AlwaysAtOppEOT | SpellDescription$ Draw a card.
|
||||
A:AB$ Draw | Cost$ tapXType<3/Merfolk> | CostDesc$ Tap three untapped Merfolk you control: | NumCards$ 1 | AILogic$ AtOppEOT | SpellDescription$ Draw a card.
|
||||
A:AB$ PutCounterAll | Cost$ tapXType<5/Merfolk> | CostDesc$ Tap five untapped Merfolk you control: | ValidCards$ Merfolk.YouCtrl | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ AtOppEOT | SpellDescription$ Put a +1/+1 counter on each Merfolk you control.
|
||||
DeckHints:Type$Merfolk
|
||||
SVar:BuffedBy:Merfolk
|
||||
|
||||
@@ -9,7 +9,7 @@ SVar:DBShuffle:DB$ Shuffle | Defined$ ParentTarget | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:TargetedPlayer$CardsInLibrary
|
||||
SVar:Y:Remembered$Valid Card.NamedCard
|
||||
SVar:Z:Number$ChosenNumber
|
||||
SVar:Z:Count$ChosenNumber
|
||||
AI:RemoveDeck:All
|
||||
AI:RemoveDeck:Random
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/mindblaze.jpg
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Legendary Creature Minotaur Warrior
|
||||
PT:6/6
|
||||
S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddPower$ AffectedX | Description$ Each creature you control gets +1/+0 for each time it has attacked this turn.
|
||||
SVar:AffectedX:Count$CardNumAttacksThisTurn
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | PlayerTurn$ True | Phase$ Main1,Main2 | Execute$ TrigAddPhase | TriggerDescription$ Landfall - Whenever a land enters the battlefield under your control, if it's your main phase, there's an additional combat phase after this phase. At the beginning of that combat, untap all creatures you control.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | AILogic$ SafeToHold | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | PlayerTurn$ True | Phase$ Main1,Main2 | Execute$ TrigAddPhase | TriggerDescription$ Landfall - Whenever a land enters the battlefield under your control, if it's your main phase, there's an additional combat phase after this phase. At the beginning of that combat, untap all creatures you control.
|
||||
SVar:TrigAddPhase:DB$ AddPhase | ExtraPhase$ Combat | ConditionPhases$ Main1,Main2 | ExtraPhaseDelayedTrigger$ DelTrigUntap | ExtraPhaseDelayedTriggerExcute$ TrigUntapAll
|
||||
SVar:DelTrigUntap:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerDescription$ At the beginning of that combat, untap all creatures you control.
|
||||
SVar:TrigUntapAll:DB$ UntapAll | ValidCards$ Creature.YouCtrl
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Muzzio, Visionary Architect
|
||||
ManaCost:1 U U
|
||||
Types:Legendary Creature Human Artificer
|
||||
PT:1/3
|
||||
A:AB$ Dig | Cost$ 3 U T | DigNum$ X | Optional$ True | ChangeValid$ Artifact | DestinationZone$ Battlefield | AILogic$ AtOppEndOfTurn | SpellDescription$ Look at the top X cards of your library, where X is the highest mana value among artifacts you control. You may put an artifact card from among them onto the battlefield. Put the rest on the bottom of your library in any order.
|
||||
A:AB$ Dig | Cost$ 3 U T | DigNum$ X | Optional$ True | ChangeValid$ Artifact | DestinationZone$ Battlefield | AILogic$ AtOppEOT | SpellDescription$ Look at the top X cards of your library, where X is the highest mana value among artifacts you control. You may put an artifact card from among them onto the battlefield. Put the rest on the bottom of your library in any order.
|
||||
SVar:X:Count$HighestCMC_Artifact.YouCtrl+inZoneBattlefield
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/muzzio_visionary_architect.jpg
|
||||
Oracle:{3}{U}, {T}: Look at the top X cards of your library, where X is the highest mana value among artifacts you control. You may put an artifact card from among them onto the battlefield. Put the rest on the bottom of your library in any order.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Name:Mystic Archaeologist
|
||||
ManaCost:1 U
|
||||
Types:Creature Human Wizard
|
||||
A:AB$ Draw | Cost$ 3 U U | Defined$ You | NumCards$ 2 | AILogic$ AlwaysAtOppEOT | SpellDescription$ Draw two cards.
|
||||
A:AB$ Draw | Cost$ 3 U U | Defined$ You | NumCards$ 2 | AILogic$ AtOppEOT | SpellDescription$ Draw two cards.
|
||||
Oracle:{3}{U}{U}: Draw two cards.
|
||||
PT:2/1
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:2 U U R R
|
||||
Types:Legendary Creature Dragon Wizard
|
||||
PT:4/4
|
||||
K:Flying
|
||||
A:AB$ Draw | Cost$ T | NumCards$ 1 | AILogic$ AlwaysAtOppEOT | SpellDescription$ Draw a card.
|
||||
A:AB$ Draw | Cost$ T | NumCards$ 1 | AILogic$ AtOppEOT | SpellDescription$ Draw a card.
|
||||
T:Mode$ Drawn | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you draw a card, CARDNAME deals 1 damage to any target.
|
||||
SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 1
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/niv_mizzet_the_firemind.jpg
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Enchantment Aura Curse
|
||||
K:Enchant player
|
||||
A:SP$ Attach | Cost$ 6 W W | ValidTgts$ Player | AILogic$ Curse
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedPlayerCtrl | SetPower$ 1 | SetToughness$ 1 | RemoveAllAbilities$ True | Description$ Creatures enchanted player controls lose all abilities and have base power and toughness 1/1.
|
||||
S:Mode$ CantBeActivated | Activator$ Player.EnchantedBy | NonMana$ True | NonLoyalty$ True | Description$ Enchanted player can't activate abilities that aren't mana abilities or loyalty abilities.
|
||||
S:Mode$ CantBeActivated | Activator$ Player.EnchantedBy | ValidSA$ Activated.nonManaAbility+nonLoyalty | Description$ Enchanted player can't activate abilities that aren't mana abilities or loyalty abilities.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/overwhelming_splendor.jpg
|
||||
Oracle:Enchant player\nCreatures enchanted player controls lose all abilities and have base power and toughness 1/1.\nEnchanted player can't activate abilities that aren't mana abilities or loyalty abilities.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1
|
||||
Types:Artifact
|
||||
K:ETBReplacement:Other:DBNameCard
|
||||
SVar:DBNameCard:DB$ NameCard | Defined$ You | SpellDescription$ As CARDNAME enters the battlefield, choose a card name.
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.NamedCard | NonMana$ True | Description$ Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.NamedCard | ValidSA$ Activated.nonManaAbility | Description$ Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.
|
||||
AI:RemoveDeck:Random
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/pithing_needle.jpg
|
||||
Oracle:As Pithing Needle enters the battlefield, choose a card name.\nActivated abilities of sources with the chosen name can't be activated unless they're mana abilities.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Pristine Talisman
|
||||
ManaCost:3
|
||||
Types:Artifact
|
||||
A:AB$ Mana | Cost$ T | Produced$ C | SubAbility$ DBGainLife | SpellDescription$ Add {C}. You gain 1 life.
|
||||
A:AB$ Mana | Cost$ T | Produced$ C | SubAbility$ DBGainLife | AILogic$ AtOppEOT | SpellDescription$ Add {C}. You gain 1 life.
|
||||
SVar:DBGainLife:DB$ GainLife | LifeAmount$ 1 | Defined$ You
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/pristine_talisman.jpg
|
||||
Oracle:{T}: Add {C}. You gain 1 life.
|
||||
|
||||
@@ -5,7 +5,7 @@ PT:2/2
|
||||
K:ETBReplacement:Other:ChooseNumber
|
||||
SVar:ChooseNumber:DB$ ChooseNumber | Defined$ You | SpellDescription$ As CARDNAME enters the battlefield, choose a number.
|
||||
S:Mode$ CantBeCast | ValidCard$ Card.nonCreature+cmcEQX | Description$ Noncreature spells with mana value equal to the chosen number can't be cast.
|
||||
SVar:X:Number$ChosenNumber
|
||||
SVar:X:Count$ChosenNumber
|
||||
AI:RemoveDeck:All
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/sanctum_prelate.jpg
|
||||
Oracle:As Sanctum Prelate enters the battlefield, choose a number.\nNoncreature spells with mana value equal to the chosen number can't be cast.
|
||||
|
||||
@@ -5,6 +5,6 @@ K:Enchant creature
|
||||
K:UpkeepCost:W W
|
||||
A:SP$ Attach | Cost$ W W | ValidTgts$ Creature | AILogic$ Curse
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddHiddenKeyword$ CARDNAME can't attack or block. | Description$ Enchanted creature can't attack or block, and its activated abilities with {T} in their costs can't be activated.
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.EnchantedBy | TapAbility$ True
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.EnchantedBy | ValidSA$ Activated.hasTapCost
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/serra_bestiary.jpg
|
||||
Oracle:Enchant creature\nAt the beginning of your upkeep, sacrifice Serra Bestiary unless you pay {W}{W}.\nEnchanted creature can't attack or block, and its activated abilities with {T} in their costs can't be activated.
|
||||
|
||||
@@ -6,7 +6,7 @@ SVar:ChoosePlayer:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | C
|
||||
SVar:DBLook:DB$ RevealHand | Defined$ ChosenPlayer | SubAbility$ DBNameCard
|
||||
SVar:DBNameCard:DB$ NameCard | Defined$ You | SubAbility$ DBClear
|
||||
SVar:DBClear:DB$ Cleanup | ClearChosenPlayer$ True
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.NamedCard | NonMana$ True | Description$ Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.
|
||||
S:Mode$ CantBeActivated | ValidCard$ Card.NamedCard | ValidSA$ Activated.nonManaAbility | Description$ Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.
|
||||
AI:RemoveDeck:Random
|
||||
# TODO: Might improve AI logic to support it (the AI needs to pick cards that actually have activated nonmana abilities on them)
|
||||
AI:RemoveDeck:All
|
||||
|
||||
@@ -4,5 +4,5 @@ Types:Creature Spirit Pirate
|
||||
PT:1/1
|
||||
K:Flash
|
||||
K:Flying
|
||||
A:AB$ Draw | Cost$ 3 U | NumCards$ 1 | Defined$ You | AILogic$ AlwaysAtOppEOT | SpellDescription$ Draw a card.
|
||||
A:AB$ Draw | Cost$ 3 U | NumCards$ 1 | Defined$ You | AILogic$ AtOppEOT | SpellDescription$ Draw a card.
|
||||
Oracle:Flash (You may cast this spell any time you could cast an instant.)\nFlying\n{3}{U}: Draw a card.
|
||||
|
||||
@@ -4,8 +4,6 @@ Types:Artifact Creature Insect
|
||||
PT:-1/-1
|
||||
K:Sunburst
|
||||
A:AB$ RemoveCounter | Cost$ SubCounter<2/P1P1> | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | CounterType$ Any | CounterNum$ 1 | SpellDescription$ Remove a counter from target permanent.
|
||||
#TODO: For some reason the AI removes beneficial counters from its own permanents with this card.
|
||||
AI:RemoveDeck:All
|
||||
AI:RemoveDeck:Random
|
||||
SVar:NeedsToPlayVar:Z GE3
|
||||
SVar:NoZeroToughnessAI:True
|
||||
|
||||
@@ -10,7 +10,7 @@ SVar:IncrementLoss:DB$ StoreSVar | SVar$ Loss | Type$ CountSVar | Expression$ Lo
|
||||
SVar:SetFilpsDone:DB$ StoreSVar | SVar$ FlipsDone | Type$ CountSVar | Expression$ TimesToFlip
|
||||
# Draw Cards
|
||||
SVar:DrawIfWin:DB$ Draw | Defined$ You | NumCards$ CardsToDraw | ConditionCheckSVar$ Loss | ConditionSVarCompare$ EQ0
|
||||
SVar:TimesToFlip:Number$ChosenNumber
|
||||
SVar:TimesToFlip:Count$ChosenNumber
|
||||
SVar:FlipsDone:Number$0
|
||||
SVar:Loss:Number$0
|
||||
SVar:CardsToDraw:Count$ChosenNumber/Times.2
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Strixhaven Stadium
|
||||
ManaCost:3
|
||||
Types:Artifact
|
||||
A:AB$ Mana | Cost$ T | Produced$ C | SubAbility$ DBPutCounter | SpellDescription$ Add {C}. Put a point counter on CARDNAME.
|
||||
A:AB$ Mana | Cost$ T | Produced$ C | SubAbility$ DBPutCounter | AILogic$ AtOppEOT | SpellDescription$ Add {C}. Put a point counter on CARDNAME.
|
||||
SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ POINT | CounterNum$ 1
|
||||
T:Mode$ DamageDone | ValidSource$ Creature | ValidTarget$ You | CombatDamage$ True | Execute$ TrigRemove | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature deals combat damage to you, remove a point counter from CARDNAME.
|
||||
SVar:TrigRemove:DB$ RemoveCounter | Defined$ Self | CounterType$ POINT | CounterNum$ 1
|
||||
|
||||
@@ -5,6 +5,6 @@ PT:3/3
|
||||
K:Flash
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigTuck | TriggerDescription$ When CARDNAME enters the battlefield, choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.
|
||||
SVar:TrigTuck:DB$ ChangeZone | ValidTgts$ Card.inZoneStack+Creature,Card.inZoneStack+Planeswalker | TgtZone$ Stack | TgtPrompt$ Select up to one target creature spell or planeswalker spell | AlternativeDecider$ TargetedController | Origin$ Stack | Fizzle$ True | Destination$ Library | LibraryPosition$ 0 | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 | AlternativeDestinationMessage$ Would you like to put the card on the top of your library (and not on the bottom)? | SpellDescription$ Choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.
|
||||
SVar:TrigTuck:DB$ ChangeZone | ValidTgts$ Card.inZoneStack+Creature,Card.inZoneStack+Planeswalker | TgtZone$ Stack | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select up to one target creature spell or planeswalker spell | AlternativeDecider$ TargetedController | Origin$ Stack | Fizzle$ True | Destination$ Library | LibraryPosition$ 0 | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 | AlternativeDestinationMessage$ Would you like to put the card on the top of your library (and not on the bottom)? | SpellDescription$ Choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.
|
||||
K:Evoke:ExileFromHand<1/Card.Blue+Other/blue card>
|
||||
Oracle:Flash\nFlying\nWhen Subtlety enters the battlefield, choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.\nEvoke—Exile a blue card from your hand.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Name:Sudden Disappearance
|
||||
ManaCost:5 W
|
||||
Types:Sorcery
|
||||
A:SP$ ChangeZoneAll | Cost$ 5 W | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Player | TgtPrompt$ Select target player | ChangeType$ Permanent.nonLand | RememberChanged$ True | SubAbility$ DelTrig | IsCurse$ True | SpellDescription$ Exile all nonland permanents target player controls. Return the exiled cards to the battlefield under their owners control at the beginning of the next end step.
|
||||
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigReturn | RememberObjects$ RememberedLKI | TriggerDescription$ Return exiled permanents to the battlefield. | SubAbility$ DBCleanup
|
||||
A:SP$ ChangeZoneAll | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Player | TgtPrompt$ Select target player | ChangeType$ Permanent.nonLand | RememberChanged$ True | SubAbility$ DelTrig | IsCurse$ True | SpellDescription$ Exile all nonland permanents target player controls. Return the exiled cards to the battlefield under their owner's control at the beginning of the next end step.
|
||||
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigReturn | RememberObjects$ RememberedLKI | TriggerDescription$ Return the exiled cards to the battlefield under their owner's control at the beginning of the next end step. | SubAbility$ DBCleanup
|
||||
SVar:TrigReturn:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ DelayTriggerRememberedLKI
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
AI:RemoveDeck:All
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:7 G G
|
||||
Types:Legendary Artifact
|
||||
S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ CARDNAME costs {X} less to cast, where X is the greatest power among creatures you control.
|
||||
SVar:X:Count$GreatestPower_Creature.YouCtrl
|
||||
A:AB$ Mana | Cost$ T | Produced$ G | Amount$ 2 | SubAbility$ DBGainLife | SpellDescription$ Add {G}{G}. You gain 2 life.
|
||||
A:AB$ Mana | Cost$ T | Produced$ G | Amount$ 2 | SubAbility$ DBGainLife | AILogic$ AtOppEOT | SpellDescription$ Add {G}{G}. You gain 2 life.
|
||||
SVar:DBGainLife:DB$ GainLife | LifeAmount$ 2
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever a nontoken creature enters the battlefield under your control, put a +1/+1 counter on it and draw a card.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredCardLKICopy | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBDraw
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:The Immortal Sun
|
||||
ManaCost:6
|
||||
Types:Legendary Artifact
|
||||
S:Mode$ CantBeActivated | Activator$ Player | ValidCard$ Planeswalker | Loyalty$ True | Description$ Players can't activate planeswalkers' loyalty abilities.
|
||||
S:Mode$ CantBeActivated | Activator$ Player | ValidCard$ Planeswalker | ValidSA$ Activated.Loyalty | Description$ Players can't activate planeswalkers' loyalty abilities.
|
||||
T:Mode$ Phase | Phase$ Draw | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ At the beginning of your draw step, draw an additional card.
|
||||
SVar:TrigDraw:DB$ Draw | NumCards$ 1
|
||||
S:Mode$ ReduceCost | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Spells you cast cost {1} less to cast.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Treasure Trove
|
||||
ManaCost:2 U U
|
||||
Types:Enchantment
|
||||
A:AB$ Draw | Cost$ 2 U U | NumCards$ 1 | AILogic$ AlwaysAtOppEOT | SpellDescription$ Draw a card.
|
||||
A:AB$ Draw | Cost$ 2 U U | NumCards$ 1 | AILogic$ AtOppEOT | SpellDescription$ Draw a card.
|
||||
SVar:NonStackingEffect:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/treasure_trove.jpg
|
||||
Oracle:{2}{U}{U}: Draw a card.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Name:Vivien's Arkbow
|
||||
ManaCost:1 G
|
||||
Types:Legendary Artifact
|
||||
A:AB$ Dig | Cost$ X T Discard<1/Card> | DigNum$ X | AILogic$ AtOppEndOfTurn | Optional$ True | Reveal$ False | ChangeNum$ 1 | ChangeValid$ Creature.cmcLEX | DestinationZone$ Battlefield | DestinationZone2$ Library | LibraryPosition$ -1 | RestRandomOrder$ True | SpellDescription$ Look at the top X cards of your library. You may put a creature card with mana value X or less from among them onto the battlefield. Put the rest on the bottom of your library in a random order.
|
||||
A:AB$ Dig | Cost$ X T Discard<1/Card> | DigNum$ X | AILogic$ AtOppEOT | Optional$ True | Reveal$ False | ChangeNum$ 1 | ChangeValid$ Creature.cmcLEX | DestinationZone$ Battlefield | DestinationZone2$ Library | LibraryPosition$ -1 | RestRandomOrder$ True | SpellDescription$ Look at the top X cards of your library. You may put a creature card with mana value X or less from among them onto the battlefield. Put the rest on the bottom of your library in a random order.
|
||||
SVar:X:Count$xPaid
|
||||
Oracle:{X}, {T}, Discard a card: Look at the top X cards of your library. You may put a creature card with mana value X or less from among them onto the battlefield. Put the rest on the bottom of your library in a random order.
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Sorcery
|
||||
A:SP$ ChooseNumber | Cost$ 3 B R | SubAbility$ DBVoidDestroyAll | SpellDescription$ Choose a number. Destroy all artifacts and creatures with mana value equal to that number. Then target player reveals their hand and discards all nonland cards with mana value equal to the number.
|
||||
SVar:DBVoidDestroyAll:DB$ DestroyAll | ValidCards$ Artifact.cmcEQX,Creature.cmcEQX | SubAbility$ DBVoidRevealDiscard
|
||||
SVar:DBVoidRevealDiscard:DB$ Discard | ValidTgts$ Player | TgtPrompt$ Select target player | Mode$ RevealDiscardAll | DiscardValid$ Card.nonLand+cmcEQX
|
||||
SVar:X:Number$ChosenNumber
|
||||
SVar:X:Count$ChosenNumber
|
||||
AI:RemoveDeck:All
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/void.jpg
|
||||
Oracle:Choose a number. Destroy all artifacts and creatures with mana value equal to that number. Then target player reveals their hand and discards all nonland cards with mana value equal to the number.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Whispers of the Muse
|
||||
ManaCost:U
|
||||
Types:Instant
|
||||
A:SP$ Draw | Cost$ U | NumCards$ 1 | AILogic$ AlwaysAtOppEOT | SpellDescription$ Draw a card.
|
||||
A:SP$ Draw | Cost$ U | NumCards$ 1 | AILogic$ AtOppEOT | SpellDescription$ Draw a card.
|
||||
K:Buyback:5
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/whispers_of_the_muse.jpg
|
||||
Oracle:Buyback {5} (You may pay an additional {5} as you cast this spell. If you do, put this card into your hand as it resolves.)\nDraw a card.
|
||||
|
||||
@@ -11,7 +11,7 @@ SVar:DBDamage:DB$ DealDamage | NumDmg$ Damage | Defined$ You
|
||||
SVar:DBEffect:DB$ Effect | StaticAbilities$ MayPlay | Stackable$ False | ConditionCheckSVar$ Y | ConditionSVarCompare$ EQ5 | SubAbility$ DBCleanup
|
||||
SVar:MayPlay:Mode$ Continuous | EffectZone$ Command | Affected$ Card.nonLand+YouOwn | MayPlay$ True | MayPlayWithoutManaCost$ True | AffectedZone$ Hand | Description$ You may cast spells from your hand this turn without paying their mana costs.
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Number$ChosenNumber
|
||||
SVar:X:Count$ChosenNumber
|
||||
SVar:Y:Count$RememberedNumber
|
||||
SVar:Damage:SVar$Losses/Times.2
|
||||
Oracle:Flying\nWhenever Yusri, Fortune's Flame attacks, choose a number between 1 and 5. Flip that many coins. For each flip you win, draw a card. For each flip you lose, Yusri deals 2 damage to you. If you won five flips this way, you may cast spells from your hand this turn without paying their mana costs.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -286,6 +286,7 @@ lblTryAgain=Neu
|
||||
lblAddAPlayer=Spieler hinzufügen
|
||||
lblVariants=Varianten
|
||||
lblRandom=Zufällig
|
||||
lblGamesInMatch=Games in match:
|
||||
#VSubmenuConstructed.java
|
||||
lblConstructedMode=Constructed-Modus
|
||||
lblConstructed=Constructed
|
||||
|
||||
@@ -287,6 +287,7 @@ lblTryAgain=Try Again
|
||||
lblAddAPlayer=Add a Player
|
||||
lblVariants=Variants
|
||||
lblRandom=Random
|
||||
lblGamesInMatch=Games in match:
|
||||
#VSubmenuConstructed.java
|
||||
lblConstructedMode=Constructed Mode
|
||||
lblConstructed=Constructed
|
||||
|
||||
@@ -287,6 +287,7 @@ lblTryAgain=Probar de nuevo
|
||||
lblAddAPlayer=Añadir jugador
|
||||
lblVariants=Variantes
|
||||
lblRandom=Aleatorio
|
||||
lblGamesInMatch=Games in match:
|
||||
#VSubmenuConstructed.java
|
||||
lblConstructedMode=Modo Construido
|
||||
lblConstructed=Construido
|
||||
|
||||
@@ -286,6 +286,7 @@ lblTryAgain=Riprova
|
||||
lblAddAPlayer=Aggiungi un giocatore
|
||||
lblVariants=Varianti
|
||||
lblRandom=Casuale
|
||||
lblGamesInMatch=Games in match:
|
||||
#VSubmenuConstructed.java
|
||||
lblConstructedMode=Modalità costruita
|
||||
lblConstructed=Costruito
|
||||
|
||||
@@ -287,6 +287,7 @@ lblTryAgain=再試行
|
||||
lblAddAPlayer=プレーヤーを追加
|
||||
lblVariants=バリエーション
|
||||
lblRandom=ランダム
|
||||
lblGamesInMatch=Games in match:
|
||||
#VSubmenuConstructed.java
|
||||
lblConstructedMode=構築戦
|
||||
lblConstructed=構築戦
|
||||
|
||||
@@ -287,6 +287,7 @@ lblTryAgain=再试一次
|
||||
lblAddAPlayer=增加一个玩家
|
||||
lblVariants=变种
|
||||
lblRandom=随机
|
||||
lblGamesInMatch=Games in match:
|
||||
#VSubmenuConstructed.java
|
||||
lblConstructedMode=构筑模式
|
||||
lblConstructed=构筑
|
||||
|
||||
@@ -89,6 +89,7 @@ public class HostedMatch {
|
||||
gameRules.setSideboardForAI(FModel.getPreferences().getPrefBoolean(FPref.MATCH_SIDEBOARD_FOR_AI));
|
||||
gameRules.setCanCloneUseTargetsImage(FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE));
|
||||
gameRules.setUseGrayText(FModel.getPreferences().getPrefBoolean(FPref.UI_GRAY_INACTIVE_TEXT));
|
||||
gameRules.setGamesPerMatch(FModel.getPreferences().getPrefInt(FPref.UI_MATCHES_PER_GAME));
|
||||
return gameRules;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
||||
BRAWL_P7_DECK_STATE(""),
|
||||
BRAWL_P8_DECK_STATE(""),
|
||||
UI_LANDSCAPE_MODE ("false"),
|
||||
UI_MATCHES_PER_GAME("3"),
|
||||
UI_COMPACT_MAIN_MENU ("false"),
|
||||
UI_USE_OLD ("false"),
|
||||
UI_RANDOM_FOIL ("false"),
|
||||
|
||||
Reference in New Issue
Block a user