mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Merge branch 'Card-Forge:master' into master
This commit is contained in:
@@ -807,22 +807,24 @@ public class AiController {
|
|||||||
// Account for possible Ward after the spell is fully targeted
|
// Account for possible Ward after the spell is fully targeted
|
||||||
// TODO: ideally, this should be done while targeting, so that a different target can be preferred if the best
|
// TODO: ideally, this should be done while targeting, so that a different target can be preferred if the best
|
||||||
// one is warded and can't be paid for. (currently it will be stuck with the target until it could pay)
|
// one is warded and can't be paid for. (currently it will be stuck with the target until it could pay)
|
||||||
if (sa.usesTargeting() && (!sa.isSpell() || CardFactoryUtil.isCounterable(host))) {
|
if (!sa.isSpell() || CardFactoryUtil.isCounterable(host)) {
|
||||||
for (Card tgt : sa.getTargets().getTargetCards()) {
|
for (TargetChoices tc : sa.getAllTargetChoices()) {
|
||||||
// TODO some older cards don't use the keyword, so check for trigger instead
|
for (Card tgt : tc.getTargetCards()) {
|
||||||
if (tgt.hasKeyword(Keyword.WARD) && tgt.isInPlay() && tgt.getController().isOpponentOf(host.getController())) {
|
// TODO some older cards don't use the keyword, so check for trigger instead
|
||||||
int amount = 0;
|
if (tgt.hasKeyword(Keyword.WARD) && tgt.isInPlay() && tgt.getController().isOpponentOf(host.getController())) {
|
||||||
Cost wardCost = ComputerUtilCard.getTotalWardCost(tgt);
|
int amount = 0;
|
||||||
if (wardCost.hasManaCost()) {
|
Cost wardCost = ComputerUtilCard.getTotalWardCost(tgt);
|
||||||
amount = wardCost.getTotalMana().getCMC();
|
if (wardCost.hasManaCost()) {
|
||||||
if (amount > 0 && !ComputerUtilCost.canPayCost(sa, player, true)) {
|
amount = wardCost.getTotalMana().getCMC();
|
||||||
return AiPlayDecision.CantAfford;
|
if (amount > 0 && !ComputerUtilCost.canPayCost(sa, player, true)) {
|
||||||
|
return AiPlayDecision.CantAfford;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SpellAbilityAi topAI = new SpellAbilityAi() {
|
||||||
|
};
|
||||||
|
if (!topAI.willPayCosts(player, sa, wardCost, host)) {
|
||||||
|
return AiPlayDecision.CostNotAcceptable;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
SpellAbilityAi topAI = new SpellAbilityAi() {
|
|
||||||
};
|
|
||||||
if (!topAI.willPayCosts(player, sa, wardCost, host)) {
|
|
||||||
return AiPlayDecision.CostNotAcceptable;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1332,10 +1334,7 @@ public class AiController {
|
|||||||
if (sa == null) {
|
if (sa == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return Lists.newArrayList(sa);
|
||||||
final List<SpellAbility> abilities = Lists.newArrayList();
|
|
||||||
abilities.add(sa);
|
|
||||||
return abilities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SpellAbility> chooseSpellAbilityToPlay() {
|
public List<SpellAbility> chooseSpellAbilityToPlay() {
|
||||||
|
|||||||
@@ -1720,14 +1720,10 @@ public class ComputerUtil {
|
|||||||
return threatened;
|
return threatened;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
objects = topStack.getTargets();
|
|
||||||
final List<GameObject> canBeTargeted = new ArrayList<>();
|
final List<GameObject> canBeTargeted = new ArrayList<>();
|
||||||
for (Object o : objects) {
|
for (GameEntity ge : topStack.getTargets().getTargetEntities()) {
|
||||||
if (o instanceof GameEntity) {
|
if (ge.canBeTargetedBy(topStack)) {
|
||||||
final GameEntity ge = (GameEntity) o;
|
canBeTargeted.add(ge);
|
||||||
if (ge.canBeTargetedBy(topStack)) {
|
|
||||||
canBeTargeted.add(ge);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (canBeTargeted.isEmpty()) {
|
if (canBeTargeted.isEmpty()) {
|
||||||
|
|||||||
@@ -1865,7 +1865,6 @@ public class ComputerUtilCard {
|
|||||||
*/
|
*/
|
||||||
public static boolean canPumpAgainstRemoval(Player ai, SpellAbility sa) {
|
public static boolean canPumpAgainstRemoval(Player ai, SpellAbility sa) {
|
||||||
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa, true);
|
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa, true);
|
||||||
final CardCollection threatenedTargets = new CardCollection();
|
|
||||||
|
|
||||||
if (!sa.usesTargeting()) {
|
if (!sa.usesTargeting()) {
|
||||||
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
||||||
@@ -1877,14 +1876,11 @@ public class ComputerUtilCard {
|
|||||||
// For pumps without targeting restrictions, just return immediately until this is fleshed out.
|
// For pumps without targeting restrictions, just return immediately until this is fleshed out.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CardCollection targetables = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa);
|
|
||||||
|
|
||||||
targetables = ComputerUtil.getSafeTargets(ai, sa, targetables);
|
CardCollection threatenedTargets = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa);
|
||||||
for (final Card c : targetables) {
|
threatenedTargets = ComputerUtil.getSafeTargets(ai, sa, threatenedTargets);
|
||||||
if (objects.contains(c)) {
|
threatenedTargets.retainAll(objects);
|
||||||
threatenedTargets.add(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!threatenedTargets.isEmpty()) {
|
if (!threatenedTargets.isEmpty()) {
|
||||||
sortByEvaluateCreature(threatenedTargets);
|
sortByEvaluateCreature(threatenedTargets);
|
||||||
for (Card c : threatenedTargets) {
|
for (Card c : threatenedTargets) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import com.google.common.base.Predicates;
|
|||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import forge.ai.ability.AnimateAi;
|
import forge.ai.ability.AnimateAi;
|
||||||
|
import forge.ai.ability.FightAi;
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
@@ -79,6 +80,49 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class SpecialCardAi {
|
public class SpecialCardAi {
|
||||||
|
|
||||||
|
// Arena and Magus of the Arena
|
||||||
|
public static class Arena {
|
||||||
|
public static boolean consider(final Player ai, final SpellAbility sa) {
|
||||||
|
final Game game = ai.getGame();
|
||||||
|
|
||||||
|
if (!game.getPhaseHandler().is(PhaseType.END_OF_TURN) || game.getPhaseHandler().getNextTurn() != ai) {
|
||||||
|
return false; // at opponent's EOT only, to conserve mana
|
||||||
|
}
|
||||||
|
|
||||||
|
CardCollection aiCreatures = ai.getCreaturesInPlay();
|
||||||
|
if (aiCreatures.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Player opp : ai.getOpponents()) {
|
||||||
|
CardCollection oppCreatures = opp.getCreaturesInPlay();
|
||||||
|
if (oppCreatures.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Card aiCreature : aiCreatures) {
|
||||||
|
boolean canKillAll = true;
|
||||||
|
for (Card oppCreature : oppCreatures) {
|
||||||
|
if (FightAi.canKill(oppCreature, aiCreature, 0)) {
|
||||||
|
canKillAll = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!FightAi.canKill(aiCreature, oppCreature, 0)) {
|
||||||
|
canKillAll = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (canKillAll) {
|
||||||
|
sa.getTargets().clear();
|
||||||
|
sa.getTargets().add(aiCreature);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sa.isTargetNumberValid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Black Lotus and Lotus Bloom
|
// Black Lotus and Lotus Bloom
|
||||||
public static class BlackLotus {
|
public static class BlackLotus {
|
||||||
public static boolean consider(final Player ai, final SpellAbility sa, final ManaCostBeingPaid cost) {
|
public static boolean consider(final Player ai, final SpellAbility sa, final ManaCostBeingPaid cost) {
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ public class FightAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
// everything is defined or targeted above, can't do anything there unless a specific logic is set
|
// everything is defined or targeted above, can't do anything there unless a specific logic is set
|
||||||
if (sa.hasParam("Defined") && !sa.usesTargeting()) {
|
if (sa.hasParam("Defined") && !sa.usesTargeting()) {
|
||||||
// TODO extend Logic for cards like Arena
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -292,10 +292,6 @@ public class PumpAi extends PumpAiBase {
|
|||||||
if (numDefense.contains("X") && sa.getSVar("X").equals("Count$xPaid")) {
|
if (numDefense.contains("X") && sa.getSVar("X").equals("Count$xPaid")) {
|
||||||
// Set PayX here to maximum value.
|
// Set PayX here to maximum value.
|
||||||
int xPay = ComputerUtilCost.getMaxXValue(sa, ai, sa.isTrigger());
|
int xPay = ComputerUtilCost.getMaxXValue(sa, ai, sa.isTrigger());
|
||||||
if (sourceName.equals("Necropolis Fiend")) {
|
|
||||||
xPay = Math.min(xPay, sa.getActivatingPlayer().getCardsIn(ZoneType.Graveyard).size());
|
|
||||||
sa.setSVar("X", Integer.toString(xPay));
|
|
||||||
}
|
|
||||||
sa.setXManaCostPaid(xPay);
|
sa.setXManaCostPaid(xPay);
|
||||||
defense = xPay;
|
defense = xPay;
|
||||||
if (numDefense.equals("-X")) {
|
if (numDefense.equals("-X")) {
|
||||||
|
|||||||
@@ -46,8 +46,11 @@ public class TapAi extends TapAiBase {
|
|||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
final Cost abCost = sa.getPayCosts();
|
final Cost abCost = sa.getPayCosts();
|
||||||
|
|
||||||
if ("GoblinPolkaBand".equals(sa.getParam("AILogic"))) {
|
final String aiLogic = sa.getParamOrDefault("AILogic", "");
|
||||||
|
if ("GoblinPolkaBand".equals(aiLogic)) {
|
||||||
return SpecialCardAi.GoblinPolkaBand.consider(ai, sa);
|
return SpecialCardAi.GoblinPolkaBand.consider(ai, sa);
|
||||||
|
} else if ("Arena".equals(aiLogic)) {
|
||||||
|
return SpecialCardAi.Arena.consider(ai, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source, sa)) {
|
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source, sa)) {
|
||||||
|
|||||||
@@ -325,6 +325,15 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
@Override
|
@Override
|
||||||
public boolean chkAIDrawback(SpellAbility sa, Player ai) {
|
public boolean chkAIDrawback(SpellAbility sa, Player ai) {
|
||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
|
final boolean oppTargetsChoice = sa.hasParam("TargetingPlayer");
|
||||||
|
|
||||||
|
if (oppTargetsChoice && sa.getActivatingPlayer().equals(ai) && !sa.isTrigger()) {
|
||||||
|
// canPlayAI (sa activated by ai)
|
||||||
|
Player targetingPlayer = AbilityUtils.getDefinedPlayers(source, sa.getParam("TargetingPlayer"), sa).get(0);
|
||||||
|
sa.setTargetingPlayer(targetingPlayer);
|
||||||
|
sa.getTargets().clear();
|
||||||
|
return targetingPlayer.getController().chooseTargetsFor(sa);
|
||||||
|
}
|
||||||
|
|
||||||
boolean randomReturn = true;
|
boolean randomReturn = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.util;
|
package forge.util;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.text.Normalizer;
|
import java.text.Normalizer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -42,6 +43,10 @@ public class TextUtil {
|
|||||||
return Normalizer.normalize(text, Normalizer.Form.NFD);
|
return Normalizer.normalize(text, Normalizer.Form.NFD);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private static final DecimalFormat df = new DecimalFormat("#.##");
|
||||||
|
public static String decimalFormat(float value) {
|
||||||
|
return df.format(value);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Safely converts an object to a String.
|
* Safely converts an object to a String.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1252,6 +1252,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
player.shuffle(sa);
|
player.shuffle(sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("Reorder")) {
|
||||||
|
chosenCards = new CardCollection(decider.getController().orderMoveToZoneList(chosenCards, destination, sa));
|
||||||
|
}
|
||||||
|
|
||||||
// remove Controlled While Searching
|
// remove Controlled While Searching
|
||||||
if (controlTimestamp != null) {
|
if (controlTimestamp != null) {
|
||||||
player.removeController(controlTimestamp);
|
player.removeController(controlTimestamp);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import forge.localinstance.achievements.CardActivationAchievements;
|
|||||||
import forge.localinstance.achievements.PlaneswalkerAchievements;
|
import forge.localinstance.achievements.PlaneswalkerAchievements;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.player.GamePlayerUtil;
|
import forge.player.GamePlayerUtil;
|
||||||
|
import forge.util.TextUtil;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -216,7 +217,7 @@ public class PlayerStatisticScene extends UIScene {
|
|||||||
totalLoss.setText(String.valueOf(Current.player().getStatistic().totalLoss()));
|
totalLoss.setText(String.valueOf(Current.player().getStatistic().totalLoss()));
|
||||||
}
|
}
|
||||||
if (lossWinRatio != null) {
|
if (lossWinRatio != null) {
|
||||||
lossWinRatio.setText(Float.toString(Current.player().getStatistic().winLossRatio()));
|
lossWinRatio.setText(TextUtil.decimalFormat(Current.player().getStatistic().winLossRatio()));
|
||||||
}
|
}
|
||||||
if (eventMatchWins != null) {
|
if (eventMatchWins != null) {
|
||||||
eventMatchWins.setText(String.valueOf(Current.player().getStatistic().eventWins()));
|
eventMatchWins.setText(String.valueOf(Current.player().getStatistic().eventWins()));
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ ALTERNATE
|
|||||||
Name:Explosive Crystal
|
Name:Explosive Crystal
|
||||||
ManaCost:4 R
|
ManaCost:4 R
|
||||||
Types:Sorcery Adventure
|
Types:Sorcery Adventure
|
||||||
A:SP$ DealDamage | ValidTgts$ Any to distribute damage to | NumDmg$ 4 | TargetMin$ 0 | TargetMax$ 4 | DividedAsYouChoose$ 4 | SpellDescription$ CARDNAME deals 4 damage divided as you choose among any number of targets.
|
A:SP$ DealDamage | ValidTgts$ Any | NumDmg$ 4 | TargetMin$ 0 | TargetMax$ 4 | DividedAsYouChoose$ 4 | SpellDescription$ CARDNAME deals 4 damage divided as you choose among any number of targets.
|
||||||
Oracle:Explosive Crystal deals 4 damage divided as you choose among any number of targets.
|
Oracle:Explosive Crystal deals 4 damage divided as you choose among any number of targets.
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
Name:Arena
|
Name:Arena
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
A:AB$ Tap | Cost$ 3 T | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | SubAbility$ DBTap | AlwaysRemember$ True | SpellDescription$ Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other. (Each deals damage equal to its power to the other.)
|
A:AB$ Tap | Cost$ 3 T | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | SubAbility$ DBTap | AILogic$ Arena | SpellDescription$ Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other. (Each deals damage equal to its power to the other.)
|
||||||
SVar:DBTap:DB$ Tap | TargetingPlayer$ Player.Opponent | TargetingPlayerControls$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature you control | SubAbility$ DBFight | AlwaysRemember$ True
|
SVar:DBTap:DB$ Tap | TargetingPlayer$ Player.Opponent | TargetingPlayerControls$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature you control | SubAbility$ DBFight
|
||||||
SVar:DBFight:DB$ Fight | Defined$ Remembered | SubAbility$ DBCleanup
|
SVar:DBFight:DB$ Fight | Defined$ Targeted
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
|
||||||
AI:RemoveDeck:All
|
|
||||||
Oracle:{3}, {T}: Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other. (Each deals damage equal to its power to the other.)
|
Oracle:{3}, {T}: Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other. (Each deals damage equal to its power to the other.)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name:Congregation at Dawn
|
Name:Congregation at Dawn
|
||||||
ManaCost:G G W
|
ManaCost:G G W
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ ChangeZone | Cost$ G G W | Origin$ Library | Destination$ Library | LibraryPosition$ 0 | ChangeType$ Creature | ChangeNum$ 3 | SpellDescription$ Search your library for up to three creature cards, reveal them, then shuffle and put those cards on top in any order.
|
A:SP$ ChangeZone | Cost$ G G W | Origin$ Library | Destination$ Library | LibraryPosition$ 0 | ChangeType$ Creature | ChangeNum$ 3 | Reorder$ True | SpellDescription$ Search your library for up to three creature cards, reveal them, then shuffle and put those cards on top in any order.
|
||||||
Oracle:Search your library for up to three creature cards, reveal them, then shuffle and put those cards on top in any order.
|
Oracle:Search your library for up to three creature cards, reveal them, then shuffle and put those cards on top in any order.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ ManaCost:2 R
|
|||||||
Types:Creature Dwarf
|
Types:Creature Dwarf
|
||||||
PT:2/2
|
PT:2/2
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters the battlefield, search your library for any number of Dwarf cards, reveal them, then shuffle and put those cards on top in any order.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters the battlefield, search your library for any number of Dwarf cards, reveal them, then shuffle and put those cards on top in any order.
|
||||||
SVar:TrigChangeZone:DB$ ChangeZone | ChangeNum$ X | ChangeType$ Dwarf | Origin$ Library | Destination$ Library | LibraryPosition$ 0
|
SVar:TrigChangeZone:DB$ ChangeZone | ChangeNum$ X | ChangeType$ Dwarf | Origin$ Library | Destination$ Library | LibraryPosition$ 0 | Reorder$ True
|
||||||
SVar:X:Count$InYourLibrary.Dwarf
|
SVar:X:Count$InYourLibrary.Dwarf
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
DeckNeeds:Type$Dwarf
|
DeckNeeds:Type$Dwarf
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ ManaCost:1 R
|
|||||||
Types:Creature Goblin
|
Types:Creature Goblin
|
||||||
PT:1/1
|
PT:1/1
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters the battlefield, search your library for any number of Goblin cards, reveal them, then shuffle and put those cards on top in any order.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters the battlefield, search your library for any number of Goblin cards, reveal them, then shuffle and put those cards on top in any order.
|
||||||
SVar:TrigChangeZone:DB$ ChangeZone | ChangeNum$ X | ChangeType$ Goblin | Origin$ Library | Destination$ Library | LibraryPosition$ 0
|
SVar:TrigChangeZone:DB$ ChangeZone | ChangeNum$ X | ChangeType$ Goblin | Origin$ Library | Destination$ Library | LibraryPosition$ 0 | Reorder$ True
|
||||||
SVar:X:Count$InYourLibrary.Goblin
|
SVar:X:Count$InYourLibrary.Goblin
|
||||||
DeckNeeds:Type$Goblin
|
DeckNeeds:Type$Goblin
|
||||||
#TODO: The AI generally is able to use this card, but will basically place all of its goblins on top of the library in no specific order, which is not very smart. Might need some improvement before RemoveDeck is removed. Currently adding a restriction to at least only play it if the AI has enough lands out on the battlefield already.
|
#TODO: The AI generally is able to use this card, but will basically place all of its goblins on top of the library in no specific order, which is not very smart. Might need some improvement before RemoveDeck is removed. Currently adding a restriction to at least only play it if the AI has enough lands out on the battlefield already.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Insidious Dreams
|
Name:Insidious Dreams
|
||||||
ManaCost:3 B
|
ManaCost:3 B
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ ChangeZone | Cost$ 3 B Discard<X/Card> | Origin$ Library | Destination$ Library | ChangeType$ Card | ChangeNum$ X | LibraryPosition$ 0 | Mandatory$ True | SpellDescription$ Search your library for X cards, then shuffle and put those cards on top in any order.
|
A:SP$ ChangeZone | Cost$ 3 B Discard<X/Card> | Origin$ Library | Destination$ Library | ChangeType$ Card | ChangeNum$ X | LibraryPosition$ 0 | Mandatory$ True | Reorder$ True | SpellDescription$ Search your library for X cards, then shuffle and put those cards on top in any order.
|
||||||
SVar:X:Count$xPaid
|
SVar:X:Count$xPaid
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
Oracle:As an additional cost to cast this spell, discard X cards.\nSearch your library for X cards, then shuffle and put those cards on top in any order.
|
Oracle:As an additional cost to cast this spell, discard X cards.\nSearch your library for X cards, then shuffle and put those cards on top in any order.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ SVar:CheckLifePaid:DB$ StoreSVar | SVar$ LifePaid | Type$ Number | Expression$ 1
|
|||||||
SVar:DBResetRem:DB$ Cleanup | ClearRemembered$ True | SubAbility$ GoToBottom
|
SVar:DBResetRem:DB$ Cleanup | ClearRemembered$ True | SubAbility$ GoToBottom
|
||||||
SVar:GoToBottom:DB$ Dig | DigNum$ 5 | ChangeNum$ All | DestinationZone$ Library | LibraryPosition$ -1 | NoLooking$ True | SubAbility$ DBLookAgain | StackDescription$ None
|
SVar:GoToBottom:DB$ Dig | DigNum$ 5 | ChangeNum$ All | DestinationZone$ Library | LibraryPosition$ -1 | NoLooking$ True | SubAbility$ DBLookAgain | StackDescription$ None
|
||||||
SVar:DBLookAgain:DB$ PeekAndReveal | PeekAmount$ 5 | NoReveal$ True | RememberPeeked$ True | StackDescription$ None
|
SVar:DBLookAgain:DB$ PeekAndReveal | PeekAmount$ 5 | NoReveal$ True | RememberPeeked$ True | StackDescription$ None
|
||||||
SVar:DBShuffle:DB$ ChangeZone | Origin$ Library | Destination$ Library | LibraryPosition$ 0 | ChangeType$ Card.IsRemembered | ChangeNum$ 5 | SubAbility$ DBReset | Hidden$ True | SelectPrompt$ Pick 1 on the top of library | Mandatory$ True | NoReveal$ True | NoLooking$ True | StackDescription$ None
|
SVar:DBShuffle:DB$ ChangeZone | Origin$ Library | Destination$ Library | LibraryPosition$ 0 | ChangeType$ Card.IsRemembered | ChangeNum$ 5 | SubAbility$ DBReset | Hidden$ True | SelectPrompt$ Pick 1 on the top of library | Mandatory$ True | NoReveal$ True | NoLooking$ True | Reorder$ True | StackDescription$ None
|
||||||
SVar:DBReset:DB$ StoreSVar | SVar$ LifePaid | Type$ Number | Expression$ 0 | SubAbility$ DBCleanup
|
SVar:DBReset:DB$ StoreSVar | SVar$ LifePaid | Type$ Number | Expression$ 0 | SubAbility$ DBCleanup
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:LifePaid:Number$0
|
SVar:LifePaid:Number$0
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ Name:Magus of the Arena
|
|||||||
ManaCost:4 R R
|
ManaCost:4 R R
|
||||||
Types:Creature Human Wizard
|
Types:Creature Human Wizard
|
||||||
PT:5/5
|
PT:5/5
|
||||||
A:AB$ Tap | Cost$ 3 T | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | SubAbility$ DBTap | AlwaysRemember$ True | SpellDescription$ Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other. (Each deals damage equal to its power to the other.)
|
A:AB$ Tap | Cost$ 3 T | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | SubAbility$ DBTap | AILogic$ Arena | SpellDescription$ Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other. (Each deals damage equal to its power to the other.)
|
||||||
SVar:DBTap:DB$ Tap | TargetingPlayer$ Player.Opponent | TargetingPlayerControls$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature you control | SubAbility$ DBFight | AlwaysRemember$ True
|
SVar:DBTap:DB$ Tap | TargetingPlayer$ Player.Opponent | TargetingPlayerControls$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature you control | SubAbility$ DBFight
|
||||||
SVar:DBFight:DB$ Fight | Defined$ Remembered | SubAbility$ DBCleanup
|
SVar:DBFight:DB$ Fight | Defined$ Targeted
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
|
||||||
AI:RemoveDeck:All
|
|
||||||
Oracle:{3}, {T}: Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other. (Each deals damage equal to its power to the other.)
|
Oracle:{3}, {T}: Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other. (Each deals damage equal to its power to the other.)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Nova Pentacle
|
|||||||
ManaCost:4
|
ManaCost:4
|
||||||
Types:Artifact
|
Types:Artifact
|
||||||
A:AB$ ChooseSource | Cost$ 3 T | Choices$ Card,Emblem | AILogic$ NeedsPrevention | SubAbility$ DBEffect | SpellDescription$ The next time a source of your choice would deal damage to you this turn, that damage is dealt to target creature of an opponent's choice instead.
|
A:AB$ ChooseSource | Cost$ 3 T | Choices$ Card,Emblem | AILogic$ NeedsPrevention | SubAbility$ DBEffect | SpellDescription$ The next time a source of your choice would deal damage to you this turn, that damage is dealt to target creature of an opponent's choice instead.
|
||||||
SVar:DBEffect:DB$ Effect | TargetingPlayer$ Player.Opponent | ValidTgts$ Creature | TgtPrompt$ Select target creature to redirect the damage to | ReplacementEffects$ SelflessDamage | ExileOnMoved$ Battlefield | RememberObjects$ Targeted | ExileOnMoved$ Battlefield | SubAbility$ DBCleanup | ConditionDefined$ ChosenCard | ConditionPresent$ Card,Emblem
|
SVar:DBEffect:DB$ Effect | TargetingPlayer$ Player.Opponent | ValidTgts$ Creature | TgtPrompt$ Select target creature to redirect the damage to | ReplacementEffects$ SelflessDamage | ExileOnMoved$ Battlefield | RememberObjects$ Targeted | SubAbility$ DBCleanup | ConditionDefined$ ChosenCard | ConditionPresent$ Card,Emblem
|
||||||
SVar:SelflessDamage:Event$ DamageDone | ValidTarget$ You | ValidSource$ Card.ChosenCardStrict,Emblem.ChosenCard | ReplaceWith$ SelflessDmg | DamageTarget$ Remembered | Description$ The next time a source of your choice would deal damage to you this turn, that damage is dealt to target creature of an opponent's choice instead.
|
SVar:SelflessDamage:Event$ DamageDone | ValidTarget$ You | ValidSource$ Card.ChosenCardStrict,Emblem.ChosenCard | ReplaceWith$ SelflessDmg | DamageTarget$ Remembered | Description$ The next time a source of your choice would deal damage to you this turn, that damage is dealt to target creature of an opponent's choice instead.
|
||||||
SVar:SelflessDmg:DB$ ReplaceEffect | VarName$ Affected | VarValue$ Remembered | VarType$ Card | SubAbility$ ExileEffect
|
SVar:SelflessDmg:DB$ ReplaceEffect | VarName$ Affected | VarValue$ Remembered | VarType$ Card | SubAbility$ ExileEffect
|
||||||
SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Scouting Trek
|
Name:Scouting Trek
|
||||||
ManaCost:1 G
|
ManaCost:1 G
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ ChangeZone | Cost$ 1 G | ChangeNum$ X | ChangeType$ Land.Basic | Origin$ Library | Destination$ Library | LibraryPosition$ 0 | SpellDescription$ Search your library for any number of basic land cards, reveal those cards, then shuffle and put them on top.
|
A:SP$ ChangeZone | Cost$ 1 G | ChangeNum$ X | ChangeType$ Land.Basic | Origin$ Library | Destination$ Library | Reorder$ True | LibraryPosition$ 0 | SpellDescription$ Search your library for any number of basic land cards, reveal those cards, then shuffle and put them on top.
|
||||||
SVar:X:Count$InYourLibrary.Land.Basic
|
SVar:X:Count$InYourLibrary.Land.Basic
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
Oracle:Search your library for any number of basic land cards, reveal those cards, then shuffle and put them on top.
|
Oracle:Search your library for any number of basic land cards, reveal those cards, then shuffle and put them on top.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Ulvenwald Tracker
|
|||||||
ManaCost:G
|
ManaCost:G
|
||||||
Types:Creature Human Shaman
|
Types:Creature Human Shaman
|
||||||
PT:1/1
|
PT:1/1
|
||||||
A:AB$ Pump | Cost$ 1 G T | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | SubAbility$ TrackerFight | StackDescription$ None
|
A:AB$ Pump | Cost$ 1 G T | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | SubAbility$ TrackerFight | StackDescription$ None | SpellDescription$ Target creature you control fights another target creature.
|
||||||
SVar:TrackerFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature | TargetUnique$ True | TgtPrompt$ Select another target creature | SpellDescription$ Target creature you control fights another target creature.
|
SVar:TrackerFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature | TargetUnique$ True | TgtPrompt$ Select another target creature
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
Oracle:{1}{G}, {T}: Target creature you control fights another target creature.
|
Oracle:{1}{G}, {T}: Target creature you control fights another target creature.
|
||||||
|
|||||||
Reference in New Issue
Block a user