mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Merge branch 'master' into boostertutor
This commit is contained in:
@@ -814,9 +814,6 @@ public class AiController {
|
||||
}
|
||||
|
||||
public AiPlayDecision canPlaySa(SpellAbility sa) {
|
||||
final Card card = sa.getHostCard();
|
||||
final boolean isRightTiming = sa.canCastTiming(player);
|
||||
|
||||
if (!checkAiSpecificRestrictions(sa)) {
|
||||
return AiPlayDecision.CantPlayAi;
|
||||
}
|
||||
@@ -824,6 +821,12 @@ public class AiController {
|
||||
return canPlaySa(((WrappedAbility) sa).getWrappedAbility());
|
||||
}
|
||||
|
||||
if (!sa.canCastTiming(player)) {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
|
||||
final Card card = sa.getHostCard();
|
||||
|
||||
// Trying to play a card that has Buyback without a Buyback cost, look for possible additional considerations
|
||||
if (getBooleanProperty(AiProps.TRY_TO_PRESERVE_BUYBACK_SPELLS)) {
|
||||
if (card.hasKeyword(Keyword.BUYBACK) && !sa.isBuyBackAbility() && !canPlaySpellWithoutBuyback(card, sa)) {
|
||||
@@ -898,9 +901,6 @@ public class AiController {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
if (sa instanceof SpellPermanent) {
|
||||
if (!isRightTiming) {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
return canPlayFromEffectAI((SpellPermanent)sa, false, true);
|
||||
}
|
||||
if (sa.usesTargeting()) {
|
||||
@@ -912,18 +912,13 @@ public class AiController {
|
||||
}
|
||||
}
|
||||
if (sa instanceof Spell) {
|
||||
if (ComputerUtil.getDamageForPlaying(player, sa) >= player.getLife()
|
||||
&& !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
|
||||
if (!player.cantLoseForZeroOrLessLife() && player.canLoseLife() &&
|
||||
ComputerUtil.getDamageForPlaying(player, sa) >= player.getLife()) {
|
||||
return AiPlayDecision.CurseEffects;
|
||||
}
|
||||
if (!isRightTiming) {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
return canPlaySpellBasic(card, sa);
|
||||
}
|
||||
if (!isRightTiming) {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
|
||||
return AiPlayDecision.WillPlay;
|
||||
}
|
||||
|
||||
@@ -1411,8 +1406,8 @@ public class AiController {
|
||||
if (!checkETBEffects(card, spell, null)) {
|
||||
return AiPlayDecision.BadEtbEffects;
|
||||
}
|
||||
if (damage + ComputerUtil.getDamageFromETB(player, card) >= player.getLife()
|
||||
&& !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
|
||||
if (!player.cantLoseForZeroOrLessLife() && player.canLoseLife()
|
||||
&& damage + ComputerUtil.getDamageFromETB(player, card) >= player.getLife()) {
|
||||
return AiPlayDecision.BadEtbEffects;
|
||||
}
|
||||
}
|
||||
@@ -1496,35 +1491,33 @@ public class AiController {
|
||||
if (landsWannaPlay != null && !landsWannaPlay.isEmpty()) {
|
||||
// TODO search for other land it might want to play?
|
||||
Card land = chooseBestLandToPlay(landsWannaPlay);
|
||||
if (ComputerUtil.getDamageFromETB(player, land) < player.getLife() || !player.canLoseLife()
|
||||
|| player.cantLoseForZeroOrLessLife() ) {
|
||||
if (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land)) {
|
||||
final List<SpellAbility> abilities = Lists.newArrayList();
|
||||
if ((!player.canLoseLife() || player.cantLoseForZeroOrLessLife() || ComputerUtil.getDamageFromETB(player, land) < player.getLife())
|
||||
&& (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land))) {
|
||||
final List<SpellAbility> abilities = Lists.newArrayList();
|
||||
|
||||
// TODO extend this logic to evaluate MDFC with both sides land
|
||||
// this can only happen if its a MDFC land
|
||||
if (!land.isLand()) {
|
||||
land.setState(CardStateName.Modal, true);
|
||||
land.setBackSide(true);
|
||||
}
|
||||
// TODO extend this logic to evaluate MDFC with both sides land
|
||||
// this can only happen if its a MDFC land
|
||||
if (!land.isLand()) {
|
||||
land.setState(CardStateName.Modal, true);
|
||||
land.setBackSide(true);
|
||||
}
|
||||
|
||||
LandAbility la = new LandAbility(land, player, null);
|
||||
LandAbility la = new LandAbility(land, player, null);
|
||||
la.setCardState(land.getCurrentState());
|
||||
if (la.canPlay()) {
|
||||
abilities.add(la);
|
||||
}
|
||||
|
||||
// add mayPlay option
|
||||
for (CardPlayOption o : land.mayPlay(player)) {
|
||||
la = new LandAbility(land, player, o.getAbility());
|
||||
la.setCardState(land.getCurrentState());
|
||||
if (la.canPlay()) {
|
||||
abilities.add(la);
|
||||
}
|
||||
|
||||
// add mayPlay option
|
||||
for (CardPlayOption o : land.mayPlay(player)) {
|
||||
la = new LandAbility(land, player, o.getAbility());
|
||||
la.setCardState(land.getCurrentState());
|
||||
if (la.canPlay()) {
|
||||
abilities.add(la);
|
||||
}
|
||||
}
|
||||
if (!abilities.isEmpty()) {
|
||||
return abilities;
|
||||
}
|
||||
}
|
||||
if (!abilities.isEmpty()) {
|
||||
return abilities;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,20 +100,19 @@ public abstract class DamageAiBase extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!enemy.canLoseLife()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!noPrevention) {
|
||||
restDamage = ComputerUtilCombat.predictDamageTo(enemy, restDamage, hostcard, false);
|
||||
} else {
|
||||
restDamage = enemy.staticReplaceDamage(restDamage, hostcard, false);
|
||||
}
|
||||
|
||||
if (restDamage == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!enemy.canLoseLife()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final CardCollectionView hand = comp.getCardsIn(ZoneType.Hand);
|
||||
|
||||
if ((enemy.getLife() - restDamage) < 5) {
|
||||
|
||||
@@ -39,8 +39,6 @@ public class MillAi extends SpellAbilityAi {
|
||||
} else if (aiLogic.equals("LilianaMill")) {
|
||||
// Only mill if a "Raise Dead" target is available, in case of control decks with few creatures
|
||||
return CardLists.filter(ai.getCardsIn(ZoneType.Graveyard), CardPredicates.Presets.CREATURES).size() >= 1;
|
||||
} else if (aiLogic.equals("Rebirth")) {
|
||||
return ai.getLife() <= 8;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,15 @@ public class GameCopier {
|
||||
newPlayer.setLifeLostLastTurn(origPlayer.getLifeLostLastTurn());
|
||||
newPlayer.setLifeLostThisTurn(origPlayer.getLifeLostThisTurn());
|
||||
newPlayer.setLifeGainedThisTurn(origPlayer.getLifeGainedThisTurn());
|
||||
newPlayer.setBlessing(origPlayer.hasBlessing());
|
||||
newPlayer.setRevolt(origPlayer.hasRevolt());
|
||||
newPlayer.setLibrarySearched(origPlayer.getLibrarySearched());
|
||||
newPlayer.setSpellsCastLastTurn(origPlayer.getSpellsCastLastTurn());
|
||||
for (int j = 0; j < origPlayer.getSpellsCastThisTurn(); j++) {
|
||||
newPlayer.addSpellCastThisTurn();
|
||||
}
|
||||
newPlayer.setMaxHandSize(origPlayer.getMaxHandSize());
|
||||
newPlayer.setUnlimitedHandSize(origPlayer.isUnlimitedHandSize());
|
||||
// TODO creatureAttackedThisTurn
|
||||
for (Mana m : origPlayer.getManaPool()) {
|
||||
newPlayer.getManaPool().addMana(m, false);
|
||||
@@ -117,6 +126,20 @@ public class GameCopier {
|
||||
p.setCommanders(commanders);
|
||||
((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(true);
|
||||
}
|
||||
for (Player origPlayer : playerMap.keySet()) {
|
||||
Player newPlayer = playerMap.get(origPlayer);
|
||||
for (final Card c : origPlayer.getCommanders()) {
|
||||
Card newCommander = gameObjectMap.map(c);
|
||||
int castTimes = origPlayer.getCommanderCast(c);
|
||||
for (int i = 0; i < castTimes; i++) {
|
||||
newPlayer.incCommanderCast(newCommander);
|
||||
}
|
||||
}
|
||||
for (Map.Entry<Card, Integer> entry : origPlayer.getCommanderDamage()) {
|
||||
Card newCommander = gameObjectMap.map(entry.getKey());
|
||||
newPlayer.addCommanderDamage(newCommander, entry.getValue());
|
||||
}
|
||||
}
|
||||
newGame.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
|
||||
|
||||
for (Card c : newGame.getCardsInGame()) {
|
||||
@@ -216,9 +239,21 @@ public class GameCopier {
|
||||
|
||||
// TODO countersAddedThisTurn
|
||||
|
||||
if (origGame.getStartingPlayer() != null) {
|
||||
newGame.setStartingPlayer(playerMap.get(origGame.getStartingPlayer()));
|
||||
}
|
||||
if (origGame.getMonarch() != null) {
|
||||
newGame.setMonarch(playerMap.get(origGame.getMonarch()));
|
||||
}
|
||||
if (origGame.getMonarchBeginTurn() != null) {
|
||||
newGame.setMonarchBeginTurn(playerMap.get(origGame.getMonarchBeginTurn()));
|
||||
}
|
||||
if (origGame.getHasInitiative() != null) {
|
||||
newGame.setHasInitiative(playerMap.get(origGame.getHasInitiative()));
|
||||
}
|
||||
if (origGame.getDayTime() != null) {
|
||||
newGame.setDayTime(origGame.getDayTime());
|
||||
}
|
||||
|
||||
for (ZoneType zone : ZONES) {
|
||||
for (Card card : origGame.getCardsIn(zone)) {
|
||||
|
||||
@@ -88,7 +88,7 @@ public abstract class DeckGeneratorBase {
|
||||
|
||||
protected void addCreaturesAndSpells(int size, List<ImmutablePair<FilterCMC, Integer>> cmcLevels, boolean forAi) {
|
||||
trace.append("Building deck of ").append(size).append("cards\n");
|
||||
|
||||
|
||||
final Iterable<PaperCard> cards = selectCardsOfMatchingColorForPlayer(forAi);
|
||||
// build subsets based on type
|
||||
|
||||
@@ -102,7 +102,7 @@ public abstract class DeckGeneratorBase {
|
||||
final int spellCnt = (int) Math.ceil(getSpellPercentage() * size);
|
||||
trace.append("Spells to add:").append(spellCnt).append("\n");
|
||||
addCmcAdjusted(spells, spellCnt, cmcLevels);
|
||||
|
||||
|
||||
trace.append(String.format("Current deck size: %d... should be %f%n", tDeck.countAll(), size * (getCreaturePercentage() + getSpellPercentage())));
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ public abstract class DeckGeneratorBase {
|
||||
for (ImmutablePair<FilterCMC, Integer> pair : cmcLevels) {
|
||||
totalWeight += pair.getRight();
|
||||
}
|
||||
|
||||
|
||||
float variability = 0.6f; // if set to 1, you'll get minimum cards to choose from
|
||||
float desiredWeight = (float)cnt / ( maxDuplicates * variability );
|
||||
float desiredOverTotal = desiredWeight / totalWeight;
|
||||
|
||||
@@ -18,14 +18,45 @@ public class ImageUtil {
|
||||
if (imageKey == null || imageKey.length() < 2) {
|
||||
return null;
|
||||
}
|
||||
if (imageKey.startsWith(ImageKeys.CARD_PREFIX))
|
||||
key = imageKey.substring(ImageKeys.CARD_PREFIX.length());
|
||||
else if (imageKey.startsWith(ImageKeys.TOKEN_PREFIX))
|
||||
key = imageKey.substring(ImageKeys.TOKEN_PREFIX.length());
|
||||
else if (imageKey.startsWith(ImageKeys.ICON_PREFIX))
|
||||
key = imageKey.substring(ImageKeys.ICON_PREFIX.length());
|
||||
else if (imageKey.startsWith(ImageKeys.BOOSTER_PREFIX))
|
||||
key = imageKey.substring(ImageKeys.BOOSTER_PREFIX.length());
|
||||
else if (imageKey.startsWith(ImageKeys.FATPACK_PREFIX))
|
||||
key = imageKey.substring(ImageKeys.FATPACK_PREFIX.length());
|
||||
else if (imageKey.startsWith(ImageKeys.BOOSTERBOX_PREFIX))
|
||||
key = imageKey.substring(ImageKeys.BOOSTERBOX_PREFIX.length());
|
||||
else if (imageKey.startsWith(ImageKeys.PRECON_PREFIX))
|
||||
key = imageKey.substring(ImageKeys.PRECON_PREFIX.length());
|
||||
else if (imageKey.startsWith(ImageKeys.TOURNAMENTPACK_PREFIX))
|
||||
key = imageKey.substring(ImageKeys.TOURNAMENTPACK_PREFIX.length());
|
||||
else if (imageKey.startsWith(ImageKeys.ADVENTURECARD_PREFIX))
|
||||
key = imageKey.substring(ImageKeys.ADVENTURECARD_PREFIX.length());
|
||||
else if (imageKey.contains(".full")) {//no prefix found, construct a valid key if imageKey is art imagekey.
|
||||
key = transformKey(imageKey);
|
||||
} else //try anyway...
|
||||
key = imageKey;
|
||||
|
||||
key = imageKey.substring(2);
|
||||
PaperCard cp = StaticData.instance().getCommonCards().getCard(key);
|
||||
if (cp == null) {
|
||||
cp = StaticData.instance().getVariantCards().getCard(key);
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
public static String transformKey(String imageKey) {
|
||||
String key;
|
||||
String edition= imageKey.substring(0, imageKey.indexOf("/"));
|
||||
String artIndex = imageKey.substring(imageKey.indexOf("/")+1, imageKey.indexOf(".")).replaceAll("[^0-9]", "");
|
||||
String name = artIndex.isEmpty() ? imageKey.substring(imageKey.indexOf("/")+1, imageKey.indexOf(".")) : imageKey.substring(imageKey.indexOf("/")+1, imageKey.indexOf(artIndex));
|
||||
key = name + "|" + edition;
|
||||
if (!artIndex.isEmpty())
|
||||
key += "|" + artIndex;
|
||||
return key;
|
||||
}
|
||||
|
||||
public static String getImageRelativePath(PaperCard cp, String face, boolean includeSet, boolean isDownloadUrl) {
|
||||
final String nameToUse = cp == null ? null : getNameToUse(cp, face);
|
||||
|
||||
@@ -139,7 +139,6 @@ public class Game {
|
||||
private Direction turnOrder = Direction.getDefaultDirection();
|
||||
|
||||
private Boolean daytime = null;
|
||||
private Boolean previous = null;
|
||||
|
||||
private long timestamp = 0;
|
||||
public final GameAction action;
|
||||
@@ -184,7 +183,7 @@ public class Game {
|
||||
public Player getHasInitiative() {
|
||||
return initiative;
|
||||
}
|
||||
public void setHasInitiative(final Player p ) {
|
||||
public void setHasInitiative(final Player p) {
|
||||
initiative = p;
|
||||
}
|
||||
|
||||
@@ -1228,21 +1227,12 @@ public class Game {
|
||||
public boolean isNeitherDayNorNight() {
|
||||
return this.daytime == null;
|
||||
}
|
||||
public boolean previousTimeIsDay() {
|
||||
return this.previous != null && this.previous == false;
|
||||
}
|
||||
public boolean previousTimeIsNight() {
|
||||
return this.previous != null && this.previous == true;
|
||||
}
|
||||
public boolean previousTimeisNeitherDayNorNight() {
|
||||
return this.previous == null;
|
||||
}
|
||||
|
||||
public Boolean getDayTime() {
|
||||
return this.daytime;
|
||||
}
|
||||
public void setDayTime(Boolean value) {
|
||||
previous = this.daytime;
|
||||
Boolean previous = this.daytime;
|
||||
this.daytime = value;
|
||||
|
||||
if (previous != null && value != null && previous != value) {
|
||||
|
||||
@@ -1420,10 +1420,8 @@ public class GameAction {
|
||||
checkAgain = true;
|
||||
}
|
||||
}
|
||||
if (!spaceSculptors.isEmpty()) {
|
||||
for (Player p : spaceSculptors) {
|
||||
checkAgain |= stateBasedAction704_5u(p);
|
||||
}
|
||||
for (Player p : spaceSculptors) {
|
||||
checkAgain |= stateBasedAction704_5u(p);
|
||||
}
|
||||
// 704.5m World rule
|
||||
checkAgain |= handleWorldRule(noRegCreats);
|
||||
|
||||
@@ -549,7 +549,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
final Zone originZone = game.getZoneOf(gameCard);
|
||||
|
||||
// if Target isn't in the expected Zone, continue
|
||||
|
||||
if (originZone == null || (!origin.isEmpty() && !origin.contains(originZone.getZoneType()))) {
|
||||
continue;
|
||||
}
|
||||
@@ -559,10 +558,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
if (destination.equals(ZoneType.Library)) {
|
||||
// library position is zero indexed
|
||||
int libraryPosition = 0;
|
||||
if (!altDest) {
|
||||
libraryPosition = sa.hasParam("LibraryPosition") ? AbilityUtils.calculateAmount(hostCard, sa.getParam("LibraryPosition"), sa) : 0;
|
||||
} else {
|
||||
if (altDest) {
|
||||
libraryPosition = sa.hasParam("LibraryPositionAlternative") ? Integer.parseInt(sa.getParam("LibraryPositionAlternative")) : 0;
|
||||
} else {
|
||||
libraryPosition = sa.hasParam("LibraryPosition") ? AbilityUtils.calculateAmount(hostCard, sa.getParam("LibraryPosition"), sa) : 0;
|
||||
}
|
||||
|
||||
// If a card is moved to library from the stack, remove its spells from the stack
|
||||
@@ -606,7 +605,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("GainControl")) {
|
||||
final String g = sa.getParam("GainControl");
|
||||
Player newController = g.equals("True") ? player :
|
||||
AbilityUtils.getDefinedPlayers(sa.getHostCard(), g, sa).get(0);
|
||||
AbilityUtils.getDefinedPlayers(hostCard, g, sa).get(0);
|
||||
if (newController != null) {
|
||||
if (newController != gameCard.getController()) {
|
||||
gameCard.runChangeControllerCommands();
|
||||
@@ -1318,7 +1317,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("GainControl")) {
|
||||
final String g = sa.getParam("GainControl");
|
||||
Player newController = g.equals("True") ? sa.getActivatingPlayer() :
|
||||
AbilityUtils.getDefinedPlayers(sa.getHostCard(), g, sa).get(0);
|
||||
AbilityUtils.getDefinedPlayers(source, g, sa).get(0);
|
||||
if (newController != c.getController()) {
|
||||
c.runChangeControllerCommands();
|
||||
}
|
||||
|
||||
@@ -39,12 +39,7 @@ public class DamageDealEffect extends DamageBaseEffect {
|
||||
// when damageStackDescription is called, just build exactly what is happening
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
final String damage = spellAbility.getParam("NumDmg");
|
||||
int dmg;
|
||||
try { // try-catch to fix Volcano Hellion Crash
|
||||
dmg = AbilityUtils.calculateAmount(spellAbility.getHostCard(), damage, spellAbility);
|
||||
} catch (NullPointerException e) {
|
||||
dmg = 0;
|
||||
}
|
||||
int dmg = AbilityUtils.calculateAmount(spellAbility.getHostCard(), damage, spellAbility);
|
||||
|
||||
List<GameObject> targets = SpellAbilityEffect.getTargets(spellAbility);
|
||||
final List<Card> definedSources = AbilityUtils.getDefinedCards(spellAbility.getHostCard(), spellAbility.getParam("DamageSource"), spellAbility);
|
||||
|
||||
@@ -63,7 +63,6 @@ import java.util.*;
|
||||
}
|
||||
|
||||
Card chosenCard = player.getController().chooseSingleCardForZoneChange(ZoneType.None, new ArrayList<ZoneType>(), sa, new CardCollection(draftOptions), null, Localizer.getInstance().getMessage("lblChooseCardDraft"), false, player);
|
||||
chosenCard.setTokenCard(true);
|
||||
game.getAction().moveTo(ZoneType.None, chosenCard, sa, moveParams);
|
||||
drafted.add(chosenCard);
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ public class MakeCardEffect extends SpellAbilityEffect {
|
||||
pc = StaticData.instance().getCommonCards().getUniqueByName(name);
|
||||
}
|
||||
Card card = Card.fromPaperCard(pc, player);
|
||||
|
||||
if (sa.hasParam("TokenCard")) {
|
||||
card.setTokenCard(true);
|
||||
}
|
||||
|
||||
@@ -80,8 +80,7 @@ public class RestartGameEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
// special handling for Karn to filter out non-cards
|
||||
CardCollection cmdCards = new CardCollection(p.getCardsIn(ZoneType.Command));
|
||||
for (Card c : cmdCards) {
|
||||
for (Card c : p.getCardsIn(ZoneType.Command)) {
|
||||
if (c.isCommander()) {
|
||||
newLibrary.add(c);
|
||||
}
|
||||
|
||||
@@ -124,13 +124,15 @@ public class RollDiceEffect extends SpellAbilityEffect {
|
||||
total += modifier;
|
||||
|
||||
// Run triggers
|
||||
int rollNum = 1;
|
||||
for (Integer roll : rolls) {
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(player);
|
||||
runParams.put(AbilityKey.Sides, sides);
|
||||
runParams.put(AbilityKey.Modifier, modifier);
|
||||
runParams.put(AbilityKey.Result, roll);
|
||||
runParams.put(AbilityKey.Number, player.getNumRollsThisTurn() + 1 - amount + rolls.indexOf(roll));
|
||||
runParams.put(AbilityKey.Number, player.getNumRollsThisTurn() - amount + rollNum);
|
||||
player.getGame().getTriggerHandler().runTrigger(TriggerType.RolledDie, runParams, false);
|
||||
rollNum++;
|
||||
}
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(player);
|
||||
runParams.put(AbilityKey.Sides, sides);
|
||||
|
||||
@@ -92,7 +92,6 @@ public class SacrificeEffect extends SpellAbilityEffect {
|
||||
// Expand Sacrifice keyword here depending on what we need out of it.
|
||||
final String num = sa.getParamOrDefault("Amount", "1");
|
||||
final int amount = AbilityUtils.calculateAmount(card, num, sa);
|
||||
final List<Player> tgts = getTargetPlayers(sa);
|
||||
final boolean devour = sa.hasParam("Devour");
|
||||
final boolean exploit = sa.hasParam("Exploit");
|
||||
final boolean sacEachValid = sa.hasParam("SacEachValid");
|
||||
@@ -120,7 +119,7 @@ public class SacrificeEffect extends SpellAbilityEffect {
|
||||
}
|
||||
} else {
|
||||
CardCollectionView choosenToSacrifice = null;
|
||||
for (final Player p : tgts) {
|
||||
for (final Player p : getTargetPlayers(sa)) {
|
||||
CardCollectionView battlefield = p.getCardsIn(ZoneType.Battlefield);
|
||||
if (sacEachValid) { // Sacrifice maximum permanents in any combination of types specified by SacValid
|
||||
String [] validArray = valid.split(" & ");
|
||||
|
||||
@@ -931,8 +931,7 @@ public class CardFactoryUtil {
|
||||
ab.append(" | Champion$ True | Hidden$ True | Optional$ True | ChangeType$ ").append(changeType);
|
||||
|
||||
StringBuilder subAb = new StringBuilder();
|
||||
subAb.append("DB$ Sacrifice | Defined$ Card.Self");
|
||||
subAb.append(" | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0");
|
||||
subAb.append("DB$ Sacrifice | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0");
|
||||
|
||||
String returnChampion = "DB$ ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Battlefield";
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig.toString(), card, intrinsic);
|
||||
|
||||
@@ -691,8 +691,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
&& !this.getGame().getRules().hasAppliedVariant(GameType.Brawl)) {
|
||||
// In case that commander is merged permanent, get the real commander card
|
||||
final Card realCommander = source.getRealCommander();
|
||||
int damage = getCommanderDamage(realCommander) + amount;
|
||||
commanderDamage.put(realCommander, damage);
|
||||
addCommanderDamage(realCommander, amount);
|
||||
view.updateCommanderDamage(this);
|
||||
if (realCommander != source) {
|
||||
view.updateMergedCommanderDamage(source, realCommander);
|
||||
@@ -1922,7 +1921,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
|
||||
public final boolean cantLoseForZeroOrLessLife() {
|
||||
return hasKeyword("You don't lose the game for having 0 or less life.");
|
||||
return cantLose() || hasKeyword("You don't lose the game for having 0 or less life.");
|
||||
}
|
||||
|
||||
public final boolean cantWin() {
|
||||
@@ -2675,6 +2674,9 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
Integer damage = commanderDamage.get(commander);
|
||||
return damage == null ? 0 : damage.intValue();
|
||||
}
|
||||
public void addCommanderDamage(Card commander, int damage) {
|
||||
commanderDamage.merge(commander, damage, Integer::sum);
|
||||
}
|
||||
|
||||
public ColorSet getCommanderColorID() {
|
||||
if (commanders.isEmpty()) {
|
||||
|
||||
@@ -585,7 +585,7 @@ public class TargetRestrictions {
|
||||
final Card srcCard = sa.getHostCard(); // should there be OrginalHost at any moment?
|
||||
|
||||
for (final Card c : game.getCardsIn(this.tgtZone)) {
|
||||
if (c.isValid(this.validTgts, srcCard.getController(), srcCard, sa)
|
||||
if (c.isValid(this.validTgts, sa.getActivatingPlayer(), srcCard, sa)
|
||||
&& (!isTargeted || sa.canTarget(c))
|
||||
&& !sa.getTargets().contains(c)) {
|
||||
candidates.add(c);
|
||||
|
||||
@@ -80,11 +80,6 @@ public class TriggerDamagePrevented extends Trigger {
|
||||
if (!Expressions.compare(actualAmount, operator, operand)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
System.out.print("DamageDone Amount Operator: ");
|
||||
System.out.println(operator);
|
||||
System.out.print("DamageDone Amount Operand: ");
|
||||
System.out.println(operand);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -75,11 +75,6 @@ public class TriggerDamagePreventedOnce extends Trigger {
|
||||
if (!Expressions.compare(actualAmount, operator, operand)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
System.out.print("DamageDone Amount Operator: ");
|
||||
System.out.println(operator);
|
||||
System.out.print("DamageDone Amount Operand: ");
|
||||
System.out.println(operand);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -19,11 +19,13 @@ package forge.game.trigger;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.Table.Cell;
|
||||
|
||||
import forge.game.CardTraitBase;
|
||||
import forge.game.CardTraitPredicates;
|
||||
@@ -445,29 +447,71 @@ public class TriggerHandler {
|
||||
|
||||
// Torpor Orb check
|
||||
if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noCreatureETBTriggers)
|
||||
&& !regtrig.isStatic() && mode.equals(TriggerType.ChangesZone)) {
|
||||
if (runParams.get(AbilityKey.Destination) instanceof String) {
|
||||
final String dest = (String) runParams.get(AbilityKey.Destination);
|
||||
if (dest.equals("Battlefield") && runParams.get(AbilityKey.Card) instanceof Card) {
|
||||
final Card card = (Card) runParams.get(AbilityKey.Card);
|
||||
if (card.isCreature()) {
|
||||
return false;
|
||||
&& !regtrig.isStatic()) {
|
||||
if (mode.equals(TriggerType.ChangesZone)) {
|
||||
if (runParams.get(AbilityKey.Destination) instanceof String) {
|
||||
final String dest = (String) runParams.get(AbilityKey.Destination);
|
||||
if (dest.equals("Battlefield") && runParams.get(AbilityKey.Card) instanceof Card) {
|
||||
final Card card = (Card) runParams.get(AbilityKey.Card);
|
||||
if (card.isCreature()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mode.equals(TriggerType.ChangesZoneAll)) {
|
||||
CardZoneTable table = (CardZoneTable) runParams.get(AbilityKey.Cards);
|
||||
// find out if any other cards would still trigger it
|
||||
boolean found = false;
|
||||
for (Cell<ZoneType, ZoneType, CardCollection> cell : table.cellSet()) {
|
||||
// this currently assumes the table will not contain multiple destinations
|
||||
// however with some effects (e.g. Goblin Welder) that should indeed be the case
|
||||
// once Forge handles that correctly this section needs to account for that
|
||||
// (by doing a closer check of the triggered ability first)
|
||||
if (cell.getColumnKey() != ZoneType.Battlefield) {
|
||||
found = true;
|
||||
} else if (Iterables.any(cell.getValue(), Predicates.not(CardPredicates.isType("Creature")))) {
|
||||
found = true;
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // Torpor Orb check
|
||||
|
||||
if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noCreatureDyingTriggers)
|
||||
&& !regtrig.isStatic() && mode.equals(TriggerType.ChangesZone)) {
|
||||
if (runParams.get(AbilityKey.Destination) instanceof String && runParams.get(AbilityKey.Origin) instanceof String) {
|
||||
final String dest = (String) runParams.get(AbilityKey.Destination);
|
||||
final String origin = (String) runParams.get(AbilityKey.Origin);
|
||||
if (dest.equals("Graveyard") && origin.equals("Battlefield") && runParams.get(AbilityKey.Card) instanceof Card) {
|
||||
final Card card = (Card) runParams.get(AbilityKey.Card);
|
||||
if (card.isCreature()) {
|
||||
return false;
|
||||
&& !regtrig.isStatic()) {
|
||||
if (mode.equals(TriggerType.ChangesZone)) {
|
||||
if (runParams.get(AbilityKey.Destination) instanceof String && runParams.get(AbilityKey.Origin) instanceof String) {
|
||||
final String dest = (String) runParams.get(AbilityKey.Destination);
|
||||
final String origin = (String) runParams.get(AbilityKey.Origin);
|
||||
if (dest.equals("Graveyard") && origin.equals("Battlefield") && runParams.get(AbilityKey.Card) instanceof Card) {
|
||||
// It will trigger if the ability is of a dying creature that triggers only when that creature is put into a graveyard from anywhere
|
||||
if (!"Card.Self".equals(regtrig.getParam("ValidCard")) || (regtrig.hasParam("Origin") && !"Any".equals(regtrig.getParam("Origin")))) {
|
||||
final Card card = (Card) runParams.get(AbilityKey.Card);
|
||||
if (card.isCreature()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mode.equals(TriggerType.ChangesZoneAll)) {
|
||||
CardZoneTable table = (CardZoneTable) runParams.get(AbilityKey.Cards);
|
||||
boolean found = false;
|
||||
for (Cell<ZoneType, ZoneType, CardCollection> cell : table.cellSet()) {
|
||||
if (cell.getRowKey() != ZoneType.Battlefield) {
|
||||
found = true;
|
||||
} else if (cell.getColumnKey() != ZoneType.Graveyard) {
|
||||
found = true;
|
||||
} else if (Iterables.any(cell.getValue(), Predicates.not(CardPredicates.isType("Creature")))) {
|
||||
found = true;
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -440,7 +440,8 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
AssertJUnit.assertEquals(blocker, sa.getTargetCard());
|
||||
}
|
||||
|
||||
@Test
|
||||
// Run the test 100 times to ensure there's no flakiness.
|
||||
@Test(invocationCount = 100)
|
||||
public void testChoicesResultingFromRandomEffects() {
|
||||
// Sometimes, the effect of a spell can be random, and as a result of that, new choices
|
||||
// could be selected during simulation. This test verifies that this doesn't cause problems.
|
||||
@@ -449,40 +450,37 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
// seed during choice evaluation, although in the future, it may make sense to handle it
|
||||
// some other way.
|
||||
|
||||
// Run the test 100 times to ensure there's no flakiness.
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
Player opponent = game.getPlayers().get(0);
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
Player opponent = game.getPlayers().get(0);
|
||||
|
||||
addCardToZone("Chaos Warp", p, ZoneType.Hand);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCardToZone("Chaos Warp", p, ZoneType.Hand);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
|
||||
addCard("Plains", opponent);
|
||||
addCard("Mountain", opponent);
|
||||
addCard("Forest", opponent);
|
||||
// Use a card that is worthwhile to target even if the shuffle ends up choosing it
|
||||
// again. In this case, life loss on ETB and leaving.
|
||||
Card expectedTarget = addCard("Raving Oni-Slave", opponent);
|
||||
addCard("Plains", opponent);
|
||||
addCard("Mountain", opponent);
|
||||
addCard("Forest", opponent);
|
||||
// Use a card that is worthwhile to target even if the shuffle ends up choosing it
|
||||
// again. In this case, life loss on ETB and leaving.
|
||||
Card expectedTarget = addCard("Raving Oni-Slave", opponent);
|
||||
|
||||
addCardToZone("Chaos Warp", opponent, ZoneType.Library);
|
||||
addCardToZone("Island", opponent, ZoneType.Library);
|
||||
addCardToZone("Swamp", opponent, ZoneType.Library);
|
||||
// The presence of Pilgrim's Eye in the library is important for this test, as this
|
||||
// will result in sub-choices (which land to pick) if this card ends up being the top
|
||||
// of the library during simulation.
|
||||
addCardToZone("Pilgrim's Eye", opponent, ZoneType.Library);
|
||||
addCardToZone("Chaos Warp", opponent, ZoneType.Library);
|
||||
addCardToZone("Island", opponent, ZoneType.Library);
|
||||
addCardToZone("Swamp", opponent, ZoneType.Library);
|
||||
// The presence of Pilgrim's Eye in the library is important for this test, as this
|
||||
// will result in sub-choices (which land to pick) if this card ends up being the top
|
||||
// of the library during simulation.
|
||||
addCardToZone("Pilgrim's Eye", opponent, ZoneType.Library);
|
||||
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
|
||||
SpellAbilityPicker picker = new SpellAbilityPicker(game, p);
|
||||
SpellAbility sa = picker.chooseSpellAbilityToPlay(null);
|
||||
AssertJUnit.assertNotNull(sa);
|
||||
AssertJUnit.assertEquals("Chaos Warp", sa.getHostCard().getName());
|
||||
AssertJUnit.assertEquals(expectedTarget, sa.getTargetCard());
|
||||
}
|
||||
SpellAbilityPicker picker = new SpellAbilityPicker(game, p);
|
||||
SpellAbility sa = picker.chooseSpellAbilityToPlay(null);
|
||||
AssertJUnit.assertNotNull(sa);
|
||||
AssertJUnit.assertEquals("Chaos Warp", sa.getHostCard().getName());
|
||||
AssertJUnit.assertEquals(expectedTarget, sa.getTargetCard());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,11 +153,8 @@ public class Forge implements ApplicationListener {
|
||||
|
||||
GuiBase.setIsAndroid(Gdx.app.getType() == Application.ApplicationType.Android);
|
||||
|
||||
if (!GuiBase.isAndroid() || (androidVersion > 28 && totalDeviceRAM > 7000)) {
|
||||
if (!GuiBase.isAndroid() || (androidVersion > 25 && totalDeviceRAM > 3400)) {
|
||||
allowCardBG = true;
|
||||
} else {
|
||||
// don't allow to read and process
|
||||
ForgeConstants.SPRITE_CARDBG_FILE = "";
|
||||
}
|
||||
assets = new Assets();
|
||||
graphics = new Graphics();
|
||||
|
||||
@@ -753,10 +753,24 @@ public class Graphics {
|
||||
fillRoundRect(borderColor, x + 1, y + 1, w - 1.5f, h - 1.5f, (h - w) / 10);//used by zoom let some edges show...
|
||||
}
|
||||
|
||||
public void drawAvatarImage(FImage image, float x, float y, float w, float h, boolean drawGrayscale) {
|
||||
public void drawAvatarImage(FImage image, float x, float y, float w, float h, boolean drawGrayscale, float amount) {
|
||||
if (image == null)
|
||||
return;
|
||||
if (!drawGrayscale) {
|
||||
if (amount > 0) {
|
||||
batch.end();
|
||||
shaderWarp.bind();
|
||||
shaderWarp.setUniformf("u_amount", 0.2f);
|
||||
shaderWarp.setUniformf("u_speed", 0.2f);
|
||||
shaderWarp.setUniformf("u_time", amount);
|
||||
batch.setShader(shaderWarp);
|
||||
batch.begin();
|
||||
//draw
|
||||
image.draw(this, x, y, w, h);
|
||||
//reset
|
||||
batch.end();
|
||||
batch.setShader(null);
|
||||
batch.begin();
|
||||
} else if (!drawGrayscale) {
|
||||
image.draw(this, x, y, w, h);
|
||||
} else {
|
||||
batch.end();
|
||||
|
||||
@@ -61,7 +61,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
final int preview_h = 680;
|
||||
|
||||
static TextureRegion backTexture;
|
||||
Texture image, T;
|
||||
Texture image, T, Talt;
|
||||
Graphics graphics;
|
||||
Texture generatedTooltip = null; //Storage for a generated tooltip. To dispose of on exit.
|
||||
boolean needsToBeDisposed;
|
||||
@@ -88,6 +88,8 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
}
|
||||
if (T != null)
|
||||
T.dispose();
|
||||
if (Talt != null)
|
||||
Talt.dispose();
|
||||
}
|
||||
|
||||
public boolean toolTipIsVisible() {
|
||||
@@ -102,6 +104,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
|
||||
@Override
|
||||
public void onImageFetched() {
|
||||
ImageCache.clear();
|
||||
String imageKey = reward.getCard().getImageKey(false);
|
||||
PaperCard card = ImageUtil.getPaperCardFromImageKey(imageKey);
|
||||
imageKey = card.getCardImageKey();
|
||||
@@ -139,6 +142,8 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
}
|
||||
if (T != null)
|
||||
T.dispose();
|
||||
if (alternate && Talt != null)
|
||||
Talt.dispose();
|
||||
ImageCache.updateSynqCount(imageFile, count);
|
||||
Gdx.graphics.requestRendering();
|
||||
}
|
||||
@@ -216,10 +221,15 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
}
|
||||
} else if (!ImageCache.imageKeyFileExists(reward.getCard().getImageKey(false))) {
|
||||
//Cannot find an image file, set up a rendered card until (if) a file is downloaded.
|
||||
T = renderPlaceholder(getGraphics(), reward.getCard()); //Now we can render the card.
|
||||
T = renderPlaceholder(new Graphics(), reward.getCard(), false); //Now we can render the card.
|
||||
setCardImage(T);
|
||||
loaded = false;
|
||||
fetcher.fetchImage(reward.getCard().getImageKey(false), this);
|
||||
if (reward.getCard().hasBackFace()) {
|
||||
if (!ImageCache.imageKeyFileExists(reward.getCard().getImageKey(true))) {
|
||||
fetcher.fetchImage(reward.getCard().getImageKey(true), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -325,17 +335,16 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
if (!reward.getCard().hasBackFace())
|
||||
return;
|
||||
Texture alt = ImageCache.getImage(reward.getCard().getImageKey(true), false);
|
||||
PaperCard altCard = ImageUtil.getPaperCardFromImageKey(reward.getCard().getCardAltImageKey());
|
||||
if (GuiBase.isAndroid() || Forge.hasGamepad()) {
|
||||
if (alternate) {
|
||||
if (alt != null) {
|
||||
holdTooltip.tooltip_actor.clear();
|
||||
holdTooltip.tooltip_actor.add(new RewardImage(processDrawable(alt)));
|
||||
} else {
|
||||
if (T == null)
|
||||
T = renderPlaceholder(getGraphics(), altCard);
|
||||
if (Talt == null)
|
||||
Talt = renderPlaceholder(new Graphics(), reward.getCard(), true);
|
||||
holdTooltip.tooltip_actor.clear();
|
||||
holdTooltip.tooltip_actor.add(new RewardImage(processDrawable(T)));
|
||||
holdTooltip.tooltip_actor.add(new RewardImage(processDrawable(Talt)));
|
||||
}
|
||||
} else {
|
||||
if (toolTipImage != null) {
|
||||
@@ -349,9 +358,9 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
if (alt != null) {
|
||||
tooltip.setActor(new RewardImage(processDrawable(alt)));
|
||||
} else {
|
||||
if (T == null)
|
||||
T = renderPlaceholder(getGraphics(), altCard);
|
||||
tooltip.setActor(new RewardImage(processDrawable(T)));
|
||||
if (Talt == null)
|
||||
Talt = renderPlaceholder(new Graphics(), reward.getCard(), true);
|
||||
tooltip.setActor(new RewardImage(processDrawable(Talt)));
|
||||
}
|
||||
} else {
|
||||
if (toolTipImage != null)
|
||||
@@ -441,7 +450,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
}
|
||||
}
|
||||
|
||||
private Texture renderPlaceholder(Graphics g, PaperCard card) { //Use CardImageRenderer to output a Texture.
|
||||
private Texture renderPlaceholder(Graphics g, PaperCard card, boolean alternate) { //Use CardImageRenderer to output a Texture.
|
||||
if (renderedCount++ == 0) {
|
||||
//The first time we find a card that has no art, render one out of view to fully initialize CardImageRenderer.
|
||||
g.begin(preview_w, preview_h);
|
||||
@@ -456,7 +465,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
g.begin(preview_w, preview_h);
|
||||
g.setProjectionMatrix(m);
|
||||
g.startClip();
|
||||
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), false, 0, 0, preview_w, preview_h, CardRenderer.CardStackPosition.Top, Forge.allowCardBG, true);
|
||||
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), alternate, 0, 0, preview_w, preview_h, CardRenderer.CardStackPosition.Top, Forge.allowCardBG, true);
|
||||
g.end();
|
||||
g.endClip();
|
||||
//Rendering ends here. Create a new Pixmap to Texture with mipmaps, otherwise will render as full black.
|
||||
@@ -623,7 +632,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
drawCard(batch, image, x, width);
|
||||
} else if (!loaded) {
|
||||
if (T == null)
|
||||
T = renderPlaceholder(getGraphics(), reward.getCard());
|
||||
T = renderPlaceholder(getGraphics(), reward.getCard(), false);
|
||||
drawCard(batch, T, x, width);
|
||||
}
|
||||
} else if (image != null) {
|
||||
@@ -637,7 +646,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
batch.end();
|
||||
shaderRoundRect.bind();
|
||||
shaderRoundRect.setUniformf("u_resolution", image.getWidth(), image.getHeight());
|
||||
shaderRoundRect.setUniformf("edge_radius", (image.getHeight()/image.getWidth())*20);
|
||||
shaderRoundRect.setUniformf("edge_radius", (image.getHeight() / image.getWidth()) * 20);
|
||||
shaderRoundRect.setUniformf("u_gray", sold ? 1f : 0f);
|
||||
batch.setShader(shaderRoundRect);
|
||||
batch.begin();
|
||||
@@ -816,6 +825,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
shown = false;
|
||||
}
|
||||
}
|
||||
|
||||
class RewardImage extends Image {
|
||||
public RewardImage(TextureRegionDrawable processDrawable) {
|
||||
setDrawable(processDrawable);
|
||||
@@ -829,7 +839,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
if (getDrawable() instanceof TextureRegionDrawable) {
|
||||
Texture t = ((TextureRegionDrawable) getDrawable()).getRegion().getTexture();
|
||||
if (t != null) {
|
||||
float x = GuiBase.isAndroid() || Forge.hasGamepad() ? Scene.getIntendedWidth() / 2 - holdTooltip.tooltip_actor.getWidth() / 2: tooltip.getActor().getImageX();
|
||||
float x = GuiBase.isAndroid() || Forge.hasGamepad() ? Scene.getIntendedWidth() / 2 - holdTooltip.tooltip_actor.getWidth() / 2 : tooltip.getActor().getImageX();
|
||||
float y = GuiBase.isAndroid() || Forge.hasGamepad() ? Scene.getIntendedHeight() / 2 - holdTooltip.tooltip_actor.getHeight() / 2 : tooltip.getActor().getImageY();
|
||||
float w = GuiBase.isAndroid() || Forge.hasGamepad() ? holdTooltip.tooltip_actor.getPrefWidth() : tooltip.getActor().getPrefWidth();
|
||||
float h = GuiBase.isAndroid() || Forge.hasGamepad() ? holdTooltip.tooltip_actor.getPrefHeight() : tooltip.getActor().getPrefHeight();
|
||||
@@ -837,7 +847,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
batch.end();
|
||||
shaderRoundRect.bind();
|
||||
shaderRoundRect.setUniformf("u_resolution", t.getWidth(), t.getHeight());
|
||||
shaderRoundRect.setUniformf("edge_radius", (t.getHeight()/t.getWidth())*ImageCache.getRadius(t));
|
||||
shaderRoundRect.setUniformf("edge_radius", (t.getHeight() / t.getWidth()) * ImageCache.getRadius(t));
|
||||
shaderRoundRect.setUniformf("u_gray", sold ? 0.8f : 0f);
|
||||
batch.setShader(shaderRoundRect);
|
||||
batch.begin();
|
||||
|
||||
@@ -131,53 +131,6 @@ public enum FSkinImage implements FImage {
|
||||
DRAFTRANK_A (FSkinProp.IMG_DRAFTRANK_A, SourceFile.DRAFTRANKS),
|
||||
DRAFTRANK_S (FSkinProp.IMG_DRAFTRANK_S, SourceFile.DRAFTRANKS),
|
||||
|
||||
//CardBG
|
||||
CARDBG_A (FSkinProp.IMG_CARDBG_A, SourceFile.CARDBG),
|
||||
CARDBG_B (FSkinProp.IMG_CARDBG_B, SourceFile.CARDBG),
|
||||
CARDBG_BG (FSkinProp.IMG_CARDBG_BG, SourceFile.CARDBG),
|
||||
CARDBG_BR (FSkinProp.IMG_CARDBG_BR, SourceFile.CARDBG),
|
||||
CARDBG_C (FSkinProp.IMG_CARDBG_C, SourceFile.CARDBG),
|
||||
CARDBG_G (FSkinProp.IMG_CARDBG_G, SourceFile.CARDBG),
|
||||
CARDBG_L (FSkinProp.IMG_CARDBG_L, SourceFile.CARDBG),
|
||||
CARDBG_M (FSkinProp.IMG_CARDBG_M, SourceFile.CARDBG),
|
||||
CARDBG_R (FSkinProp.IMG_CARDBG_R, SourceFile.CARDBG),
|
||||
CARDBG_RG (FSkinProp.IMG_CARDBG_RG, SourceFile.CARDBG),
|
||||
CARDBG_U (FSkinProp.IMG_CARDBG_U, SourceFile.CARDBG),
|
||||
CARDBG_UB (FSkinProp.IMG_CARDBG_UB, SourceFile.CARDBG),
|
||||
CARDBG_UG (FSkinProp.IMG_CARDBG_UG, SourceFile.CARDBG),
|
||||
CARDBG_UR (FSkinProp.IMG_CARDBG_UR, SourceFile.CARDBG),
|
||||
CARDBG_V (FSkinProp.IMG_CARDBG_V, SourceFile.CARDBG),
|
||||
CARDBG_W (FSkinProp.IMG_CARDBG_W, SourceFile.CARDBG),
|
||||
CARDBG_WB (FSkinProp.IMG_CARDBG_WB, SourceFile.CARDBG),
|
||||
CARDBG_WG (FSkinProp.IMG_CARDBG_WG, SourceFile.CARDBG),
|
||||
CARDBG_WR (FSkinProp.IMG_CARDBG_WR, SourceFile.CARDBG),
|
||||
CARDBG_WU (FSkinProp.IMG_CARDBG_WU, SourceFile.CARDBG),
|
||||
//PWBG
|
||||
PWBG_B (FSkinProp.IMG_PWBG_B, SourceFile.CARDBG),
|
||||
PWBG_BG (FSkinProp.IMG_PWBG_BG, SourceFile.CARDBG),
|
||||
PWBG_BR (FSkinProp.IMG_PWBG_BR, SourceFile.CARDBG),
|
||||
PWBG_C (FSkinProp.IMG_PWBG_C, SourceFile.CARDBG),
|
||||
PWBG_G (FSkinProp.IMG_PWBG_G, SourceFile.CARDBG),
|
||||
PWBG_M (FSkinProp.IMG_PWBG_M, SourceFile.CARDBG),
|
||||
PWBG_R (FSkinProp.IMG_PWBG_R, SourceFile.CARDBG),
|
||||
PWBG_RG (FSkinProp.IMG_PWBG_RG, SourceFile.CARDBG),
|
||||
PWBG_U (FSkinProp.IMG_PWBG_U, SourceFile.CARDBG),
|
||||
PWBG_UB (FSkinProp.IMG_PWBG_UB, SourceFile.CARDBG),
|
||||
PWBG_UG (FSkinProp.IMG_PWBG_UG, SourceFile.CARDBG),
|
||||
PWBG_UR (FSkinProp.IMG_PWBG_UR, SourceFile.CARDBG),
|
||||
PWBG_W (FSkinProp.IMG_PWBG_W, SourceFile.CARDBG),
|
||||
PWBG_WB (FSkinProp.IMG_PWBG_WB, SourceFile.CARDBG),
|
||||
PWBG_WG (FSkinProp.IMG_PWBG_WG, SourceFile.CARDBG),
|
||||
PWBG_WR (FSkinProp.IMG_PWBG_WR, SourceFile.CARDBG),
|
||||
PWBG_WU (FSkinProp.IMG_PWBG_WU, SourceFile.CARDBG),
|
||||
//NYX OVERLAY
|
||||
NYX_B (FSkinProp.IMG_NYX_B, SourceFile.CARDBG),
|
||||
NYX_G (FSkinProp.IMG_NYX_G, SourceFile.CARDBG),
|
||||
NYX_M (FSkinProp.IMG_NYX_M, SourceFile.CARDBG),
|
||||
NYX_R (FSkinProp.IMG_NYX_R, SourceFile.CARDBG),
|
||||
NYX_U (FSkinProp.IMG_NYX_U, SourceFile.CARDBG),
|
||||
NYX_W (FSkinProp.IMG_NYX_W, SourceFile.CARDBG),
|
||||
|
||||
//Gameplay
|
||||
TAP (FSkinProp.IMG_TAP, SourceFile.MANAICONS),
|
||||
UNTAP (FSkinProp.IMG_UNTAP, SourceFile.MANAICONS),
|
||||
@@ -531,7 +484,6 @@ public enum FSkinImage implements FImage {
|
||||
WATERMARKS(ForgeConstants.SPRITE_WATERMARK_FILE),
|
||||
DRAFTRANKS(ForgeConstants.SPRITE_DRAFTRANKS_FILE),
|
||||
CRACKS(ForgeConstants.SPRITE_CRACKS_FILE),
|
||||
CARDBG(ForgeConstants.SPRITE_CARDBG_FILE),
|
||||
PLANAR_CONQUEST(ForgeConstants.SPRITE_PLANAR_CONQUEST_FILE);
|
||||
|
||||
private final String filename;
|
||||
|
||||
@@ -34,6 +34,52 @@ public enum FSkinTexture implements FImage {
|
||||
ADV_BG_CAVE(ForgeConstants.ADV_BG_CAVE_FILE, false, false),
|
||||
ADV_BG_DUNGEON(ForgeConstants.ADV_BG_DUNGEON_FILE, false, false),
|
||||
ADV_BG_CASTLE(ForgeConstants.ADV_BG_CASTLE_FILE, false, false),
|
||||
//CARD BG
|
||||
CARDBG_A (ForgeConstants.IMG_CARDBG_A, false, false),
|
||||
CARDBG_B (ForgeConstants.IMG_CARDBG_B, false, false),
|
||||
CARDBG_BG (ForgeConstants.IMG_CARDBG_BG, false, false),
|
||||
CARDBG_BR (ForgeConstants.IMG_CARDBG_BR, false, false),
|
||||
CARDBG_C (ForgeConstants.IMG_CARDBG_C, false, false),
|
||||
CARDBG_G (ForgeConstants.IMG_CARDBG_G, false, false),
|
||||
CARDBG_L (ForgeConstants.IMG_CARDBG_L, false, false),
|
||||
CARDBG_M (ForgeConstants.IMG_CARDBG_M, false, false),
|
||||
CARDBG_R (ForgeConstants.IMG_CARDBG_R, false, false),
|
||||
CARDBG_RG (ForgeConstants.IMG_CARDBG_RG, false, false),
|
||||
CARDBG_U (ForgeConstants.IMG_CARDBG_U, false, false),
|
||||
CARDBG_UB (ForgeConstants.IMG_CARDBG_UB, false, false),
|
||||
CARDBG_UG (ForgeConstants.IMG_CARDBG_UG, false, false),
|
||||
CARDBG_UR (ForgeConstants.IMG_CARDBG_UR, false, false),
|
||||
CARDBG_V (ForgeConstants.IMG_CARDBG_V, false, false),
|
||||
CARDBG_W (ForgeConstants.IMG_CARDBG_W, false, false),
|
||||
CARDBG_WB (ForgeConstants.IMG_CARDBG_WB, false, false),
|
||||
CARDBG_WG (ForgeConstants.IMG_CARDBG_WG, false, false),
|
||||
CARDBG_WR (ForgeConstants.IMG_CARDBG_WR, false, false),
|
||||
CARDBG_WU (ForgeConstants.IMG_CARDBG_WU, false, false),
|
||||
PWBG_B (ForgeConstants.IMG_PWBG_B, false, false),
|
||||
PWBG_BG (ForgeConstants.IMG_PWBG_BG, false, false),
|
||||
PWBG_BR (ForgeConstants.IMG_PWBG_BR, false, false),
|
||||
PWBG_C (ForgeConstants.IMG_PWBG_C, false, false),
|
||||
PWBG_G (ForgeConstants.IMG_PWBG_G, false, false),
|
||||
PWBG_M (ForgeConstants.IMG_PWBG_M, false, false),
|
||||
PWBG_R (ForgeConstants.IMG_PWBG_R, false, false),
|
||||
PWBG_RG (ForgeConstants.IMG_PWBG_RG, false, false),
|
||||
PWBG_U (ForgeConstants.IMG_PWBG_U, false, false),
|
||||
PWBG_UB (ForgeConstants.IMG_PWBG_UB, false, false),
|
||||
PWBG_UG (ForgeConstants.IMG_PWBG_UG, false, false),
|
||||
PWBG_UR (ForgeConstants.IMG_PWBG_UR, false, false),
|
||||
PWBG_W (ForgeConstants.IMG_PWBG_W, false, false),
|
||||
PWBG_WB (ForgeConstants.IMG_PWBG_WB, false, false),
|
||||
PWBG_WG (ForgeConstants.IMG_PWBG_WG, false, false),
|
||||
PWBG_WR (ForgeConstants.IMG_PWBG_WR, false, false),
|
||||
PWBG_WU (ForgeConstants.IMG_PWBG_WU, false, false),
|
||||
NYX_B (ForgeConstants.IMG_NYX_B, false, false),
|
||||
NYX_G (ForgeConstants.IMG_NYX_G, false, false),
|
||||
NYX_M (ForgeConstants.IMG_NYX_M, false, false),
|
||||
NYX_R (ForgeConstants.IMG_NYX_R, false, false),
|
||||
NYX_U (ForgeConstants.IMG_NYX_U, false, false),
|
||||
NYX_W (ForgeConstants.IMG_NYX_W, false, false),
|
||||
NYX_C (ForgeConstants.IMG_NYX_C, false, false),
|
||||
|
||||
//Planechase
|
||||
Academy_at_Tolaria_West(ForgeConstants.BG_1, false, true),
|
||||
Agyrem(ForgeConstants.BG_2, false, true),
|
||||
|
||||
@@ -377,6 +377,10 @@ public class CardImageRenderer {
|
||||
}
|
||||
|
||||
private static void drawSplitCard(CardView card, FImageComplex cardArt, Graphics g, float x, float y, float w, float h, boolean altState, boolean isFaceDown) {
|
||||
if (cardArt.getTexture() == forgeArt.getTexture()) {
|
||||
g.drawImage(cardArt, x, y, w, h);
|
||||
return;
|
||||
}
|
||||
CardView alt = card.getBackup();
|
||||
if (alt == null)
|
||||
alt = card.getAlternateState().getCard();
|
||||
@@ -858,7 +862,7 @@ public class CardImageRenderer {
|
||||
} else {
|
||||
borderColors = CardDetailUtil.getBorderColors(state, canShow);
|
||||
}
|
||||
Color[] colors = fillColorBackground(g, borderColors, x, y, w, h);
|
||||
Color[] colors = Forge.allowCardBG ? drawCardBackgroundTexture(state, g, !altState ? borderColors : CardDetailUtil.getBorderColors(state, canShow), x, y, w, h) : fillColorBackground(g, borderColors, x, y, w, h);
|
||||
|
||||
Color idForeColor = FSkinColor.getHighContrastColor(colors[0]);
|
||||
|
||||
@@ -907,79 +911,110 @@ public class CardImageRenderer {
|
||||
switch (backColors.size()) {
|
||||
case 1:
|
||||
if (backColors.get(0) == DetailColors.FACE_DOWN) {
|
||||
g.drawImage(FSkinImage.CARDBG_C, x, y, w, h);
|
||||
g.drawImage(FSkinTexture.CARDBG_C, x, y, w, h);
|
||||
} else if (backColors.get(0) == DetailColors.LAND) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_C : FSkinImage.CARDBG_L, x, y, w, h);
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_C : FSkinTexture.CARDBG_L, x, y, w, h);
|
||||
} else if (backColors.get(0) == DetailColors.MULTICOLOR) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_M : FSkinImage.CARDBG_M, x, y, w, h);
|
||||
if (isNyx)
|
||||
g.drawImage(FSkinImage.NYX_M, x, y, w, (h / 2) + (h / 5));
|
||||
} else if (backColors.get(0) == DetailColors.COLORLESS) {
|
||||
if (isPW)
|
||||
g.drawImage(FSkinImage.PWBG_C, x, y, w, h);
|
||||
else if (state.isVehicle())
|
||||
g.drawImage(FSkinImage.CARDBG_V, x, y, w, h);
|
||||
else if (state.isArtifact())
|
||||
g.drawImage(FSkinImage.CARDBG_A, x, y, w, h);
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_M, x, y, w, h);
|
||||
else
|
||||
g.drawImage(FSkinImage.CARDBG_C, x, y, w, h);
|
||||
//todo add NYX for colorless?
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_M : FSkinTexture.CARDBG_M, x, y, w, h);
|
||||
} else if (backColors.get(0) == DetailColors.COLORLESS) {
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isPW)
|
||||
g.drawImage(FSkinTexture.PWBG_C, x, y, w, h);
|
||||
else if (state.isArtifact())
|
||||
g.drawImage(FSkinTexture.CARDBG_A, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_C, x, y, w, h);
|
||||
else
|
||||
g.drawImage(FSkinTexture.CARDBG_C, x, y, w, h);
|
||||
} else if (backColors.get(0) == DetailColors.GREEN) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_G : FSkinImage.CARDBG_G, x, y, w, h);
|
||||
if (isNyx)
|
||||
g.drawImage(FSkinImage.NYX_G, x, y, w, (h / 2) + (h / 5));
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_G, x, y, w, h);
|
||||
else
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_G : FSkinTexture.CARDBG_G, x, y, w, h);
|
||||
} else if (backColors.get(0) == DetailColors.RED) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_R : FSkinImage.CARDBG_R, x, y, w, h);
|
||||
if (isNyx)
|
||||
g.drawImage(FSkinImage.NYX_R, x, y, w, (h / 2) + (h / 5));
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_R, x, y, w, h);
|
||||
else
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_R : FSkinTexture.CARDBG_R, x, y, w, h);
|
||||
} else if (backColors.get(0) == DetailColors.BLACK) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_B : FSkinImage.CARDBG_B, x, y, w, h);
|
||||
if (isNyx)
|
||||
g.drawImage(FSkinImage.NYX_B, x, y, w, (h / 2) + (h / 5));
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_B, x, y, w, h);
|
||||
else
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_B : FSkinTexture.CARDBG_B, x, y, w, h);
|
||||
} else if (backColors.get(0) == DetailColors.BLUE) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_U : FSkinImage.CARDBG_U, x, y, w, h);
|
||||
if (isNyx)
|
||||
g.drawImage(FSkinImage.NYX_U, x, y, w, (h / 2) + (h / 5));
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_U, x, y, w, h);
|
||||
else
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_U : FSkinTexture.CARDBG_U, x, y, w, h);
|
||||
} else if (backColors.get(0) == DetailColors.WHITE) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_W : FSkinImage.CARDBG_W, x, y, w, h);
|
||||
if (isNyx)
|
||||
g.drawImage(FSkinImage.NYX_W, x, y, w, (h / 2) + (h / 5));
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_W, x, y, w, h);
|
||||
else
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_W : FSkinTexture.CARDBG_W, x, y, w, h);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (!isHybrid) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_M : FSkinImage.CARDBG_M, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.BLUE)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_WU : FSkinImage.CARDBG_WU, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.BLACK)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_WB : FSkinImage.CARDBG_WB, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.RED)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_WR : FSkinImage.CARDBG_WR, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.GREEN)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_WG : FSkinImage.CARDBG_WG, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLUE) && backColors.contains(DetailColors.BLACK)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_UB : FSkinImage.CARDBG_UB, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLUE) && backColors.contains(DetailColors.RED)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_UR : FSkinImage.CARDBG_UR, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLUE) && backColors.contains(DetailColors.GREEN)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_UG : FSkinImage.CARDBG_UG, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLACK) && backColors.contains(DetailColors.RED)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_BR : FSkinImage.CARDBG_BR, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLACK) && backColors.contains(DetailColors.GREEN)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_BG : FSkinImage.CARDBG_BG, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.RED) && backColors.contains(DetailColors.GREEN)) {
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_RG : FSkinImage.CARDBG_RG, x, y, w, h);
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_M, x, y, w, h);
|
||||
else {
|
||||
if (!isHybrid) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_M : FSkinTexture.CARDBG_M, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.BLUE)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_WU : FSkinTexture.CARDBG_WU, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.BLACK)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_WB : FSkinTexture.CARDBG_WB, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.RED)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_WR : FSkinTexture.CARDBG_WR, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.GREEN)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_WG : FSkinTexture.CARDBG_WG, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLUE) && backColors.contains(DetailColors.BLACK)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_UB : FSkinTexture.CARDBG_UB, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLUE) && backColors.contains(DetailColors.RED)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_UR : FSkinTexture.CARDBG_UR, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLUE) && backColors.contains(DetailColors.GREEN)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_UG : FSkinTexture.CARDBG_UG, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLACK) && backColors.contains(DetailColors.RED)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_BR : FSkinTexture.CARDBG_BR, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.BLACK) && backColors.contains(DetailColors.GREEN)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_BG : FSkinTexture.CARDBG_BG, x, y, w, h);
|
||||
} else if (backColors.contains(DetailColors.RED) && backColors.contains(DetailColors.GREEN)) {
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_RG : FSkinTexture.CARDBG_RG, x, y, w, h);
|
||||
}
|
||||
}
|
||||
if (isNyx)
|
||||
g.drawImage(FSkinImage.NYX_M, x, y, w, (h / 2) + (h / 5));
|
||||
break;
|
||||
case 3:
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_M : FSkinImage.CARDBG_M, x, y, w, h);
|
||||
if (isNyx)
|
||||
g.drawImage(FSkinImage.NYX_M, x, y, w, (h / 2) + (h / 5));
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_M, x, y, w, h);
|
||||
else
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_M : FSkinTexture.CARDBG_M, x, y, w, h);
|
||||
break;
|
||||
default:
|
||||
g.drawImage(isPW ? FSkinImage.PWBG_C : FSkinImage.CARDBG_C, x, y, w, h);
|
||||
if (state.isVehicle())
|
||||
g.drawImage(FSkinTexture.CARDBG_V, x, y, w, h);
|
||||
else if (isNyx)
|
||||
g.drawImage(FSkinTexture.NYX_C, x, y, w, h);
|
||||
else
|
||||
g.drawImage(isPW ? FSkinTexture.PWBG_C : FSkinTexture.CARDBG_C, x, y, w, h);
|
||||
break;
|
||||
}
|
||||
return colors;
|
||||
|
||||
@@ -594,7 +594,7 @@ public class CardRenderer {
|
||||
}
|
||||
} else {
|
||||
//if card has invalid or no texture due to sudden changes in ImageCache, draw CardImageRenderer instead and wait for it to refresh automatically
|
||||
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos, Forge.enableUIMask.equals("Art"), true);
|
||||
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,7 +662,7 @@ public class CardRenderer {
|
||||
drawFoilEffect(g, card, x, y, w, h, false);
|
||||
} else {
|
||||
//if card has invalid or no texture due to sudden changes in ImageCache, draw CardImageRenderer instead and wait for it to refresh automatically
|
||||
CardImageRenderer.drawCardImage(g, card, showAltState, x, y, w, h, pos, Forge.enableUIMask.equals("Art"), false, isChoiceList, !showCardIdOverlay(card));
|
||||
CardImageRenderer.drawCardImage(g, card, showAltState, x, y, w, h, pos, true, false, isChoiceList, !showCardIdOverlay(card));
|
||||
}
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package forge.screens.match.views;
|
||||
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
|
||||
@@ -10,7 +9,6 @@ import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.animation.ForgeAnimation;
|
||||
import forge.assets.FImage;
|
||||
import forge.assets.FSkin;
|
||||
import forge.assets.FSkinColor;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.game.card.CounterEnumType;
|
||||
@@ -44,9 +42,8 @@ public class VAvatar extends FDisplayObject {
|
||||
avatarAnimation = new AvatarAnimation();
|
||||
}
|
||||
private class AvatarAnimation extends ForgeAnimation {
|
||||
private static final float DURATION = 0.6f;
|
||||
private static final float DURATION = 0.8f;
|
||||
private float progress = 0;
|
||||
Texture splatter = FSkin.splatter;
|
||||
|
||||
private void drawAvatar(Graphics g, FImage image, float x, float y, float w, float h) {
|
||||
float percentage = progress / DURATION;
|
||||
@@ -60,23 +57,14 @@ public class VAvatar extends FDisplayObject {
|
||||
float oldAlpha = g.getfloatAlphaComposite();
|
||||
float fade = 1-(percentage*1);
|
||||
if (amount > 0) {
|
||||
g.drawAvatarImage(image, x, y, w, h, player.getHasLost());
|
||||
g.drawAvatarImage(image, x, y, w, h, player.getHasLost(), 0);
|
||||
drawPlayerIndicator(g, w, h, percentage);
|
||||
g.setAlphaComposite(fade);
|
||||
g.drawRect(w / 12f, Color.WHITE, 0, 0, w, h);
|
||||
g.drawOutlinedText("+"+amount, Forge.altZoneTabs ? LIFE_FONT_ALT : LIFE_FONT, Color.WHITE, Color.SKY, 0, (getHeight()/2)*fade, getWidth(), getHeight(), false, Align.center, true);
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
} else if (amount < 0) {
|
||||
if (splatter == null) {
|
||||
g.setColorRGBA(1, percentage, percentage, oldAlpha);
|
||||
g.drawAvatarImage(image, x, y, w, h, player.getHasLost());
|
||||
g.resetColorRGBA(oldAlpha);
|
||||
} else {
|
||||
g.drawAvatarImage(image, x, y, w, h, player.getHasLost());
|
||||
g.setAlphaComposite(fade);
|
||||
g.drawImage(splatter, x-mod/2, y-mod/2, w+mod, h+mod);
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
}
|
||||
g.drawAvatarImage(image, x, y, w, h, player.getHasLost(), 1-percentage);
|
||||
drawPlayerIndicator(g, w, h, percentage);
|
||||
g.setAlphaComposite(fade);
|
||||
g.drawOutlinedText(String.valueOf(amount), Forge.altZoneTabs ? LIFE_FONT_ALT : LIFE_FONT, Color.RED, Color.ORANGE, 0, (getHeight()/2)*fade, getWidth(), getHeight(), false, Align.center, true);
|
||||
@@ -120,11 +108,11 @@ public class VAvatar extends FDisplayObject {
|
||||
avatarAnimation.start();
|
||||
avatarAnimation.drawAvatar(g, image, 0, 0, w, h);
|
||||
} else {
|
||||
g.drawAvatarImage(image, 0, 0, w, h, player.getHasLost());
|
||||
g.drawAvatarImage(image, 0, 0, w, h, player.getHasLost(), 0);
|
||||
drawPlayerIndicator(g, w, h, 1);
|
||||
}
|
||||
} else {
|
||||
g.drawAvatarImage(image, 0, 0, w, h, player.getHasLost());
|
||||
g.drawAvatarImage(image, 0, 0, w, h, player.getHasLost(), 0);
|
||||
}
|
||||
|
||||
if (Forge.altPlayerLayout && !Forge.altZoneTabs && Forge.isLandscapeMode())
|
||||
|
||||
@@ -103,6 +103,7 @@ Innistrad: Crimson Vow, 3/6/VOW, VOW
|
||||
Innistrad: Double Feature, 3/6/MID, DBL
|
||||
Kamigawa: Neon Dynasty, 3/6/NEO, NEO
|
||||
Streets of New Capenna, 3/6/SNC, SNC
|
||||
Alchemy Horizons: Baldur's Gate, 3/6/HBG, HBG
|
||||
Double Masters 2022, 3/6/2X2, 2X2
|
||||
Dominaria United, 3/6/DMU, DMU
|
||||
The Brothers' War, 3/6/BRO, BRO
|
||||
|
||||
@@ -5,6 +5,6 @@ K:etbCounter:P1P1:3
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigMoveCounter | TriggerDescription$ At the beginning of your upkeep, move a +1/+1 counter from CARDNAME onto target creature.
|
||||
SVar:TrigMoveCounter:DB$ MoveCounter | Source$ Self | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Card.Self+counters_EQ0_P1P1 | Execute$ TrigSac | TriggerDescription$ When CARDNAME has no +1/+1 counters on it, sacrifice it.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:NeedsToPlay:Creature.YouCtrl
|
||||
Oracle:Afiya Grove enters the battlefield with three +1/+1 counters on it.\nAt the beginning of your upkeep, move a +1/+1 counter from Afiya Grove onto target creature.\nWhen Afiya Grove has no +1/+1 counters on it, sacrifice it.
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Amulet of Quoz
|
||||
ManaCost:6
|
||||
Types:Artifact
|
||||
K:Remove CARDNAME from your deck before playing if you're not playing for ante.
|
||||
A:AB$ Dig | Cost$ T Sac<1/CARDNAME> | ValidTgts$ Opponent | DestinationZone$ Ante | DigNum$ 1 | ChangeNum$ All | RememberChanged$ True | Optional$ True | SubAbility$ DBFlip | PlayerTurn$ True | ActivationPhases$ Upkeep | SpellDescription$ Target opponent may ante the top card of their library. If they don't, you flip a coin. If you win the flip, that player loses the game. If you lose the flip, you lose the game. Activate only during your upkeep.
|
||||
A:AB$ Dig | Cost$ T Sac<1/CARDNAME> | ValidTgts$ Opponent | DestinationZone$ Ante | DigNum$ 1 | ChangeNum$ All | RememberChanged$ True | Optional$ True | PromptToSkipOptionalAbility$ True | SubAbility$ DBFlip | PlayerTurn$ True | ActivationPhases$ Upkeep | SpellDescription$ Target opponent may ante the top card of their library. If they don't, you flip a coin. If you win the flip, that player loses the game. If you lose the flip, you lose the game. Activate only during your upkeep.
|
||||
SVar:DBFlip:DB$ FlipACoin | Caller$ You | WinSubAbility$ OppLoseGame | LoseSubAbility$ YouLoseGame | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBCleanup
|
||||
SVar:OppLoseGame:DB$ LosesGame | Defined$ Targeted
|
||||
SVar:YouLoseGame:DB$ LosesGame | Defined$ You
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:no cost
|
||||
Types:Land
|
||||
K:CARDNAME enters the battlefield tapped.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you pay {1}.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self | UnlessCost$ 1 | UnlessPayer$ You
|
||||
SVar:TrigSac:DB$ Sacrifice | UnlessCost$ 1 | UnlessPayer$ You
|
||||
A:AB$ Mana | Cost$ T | Produced$ Any | SpellDescription$ Add one mana of any color.
|
||||
SVar:NeedsToPlay:Land.untapped+YouCtrl
|
||||
Oracle:Archway Commons enters the battlefield tapped.\nWhen Archway Commons enters the battlefield, sacrifice it unless you pay {1}.\n{T}: Add one mana of any color.
|
||||
|
||||
@@ -7,7 +7,7 @@ T:Mode$ Blocks | ValidCard$ Card.Self | Execute$ TrigPump | Secondary$ True | Tr
|
||||
SVar:TrigPump:DB$ PumpAll | ValidCards$ Rat.Other+YouCtrl | NumAtt$ +X | NumDef$ +X
|
||||
SVar:X:Count$Valid Rat.YouCtrl
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigChange | TriggerDescription$ At the beginning of your end step, you may mill four cards. If you do, return up to two Rat creature cards from your graveyard to your hand. (To mill a card, put the top card of your library into your graveyard.)
|
||||
SVar:TrigChange:AB$ ChangeZone | Cost$ Mill<4> | Origin$ Graveyard | Destination$ Hand | ChangeType$ Rat.Creature+YouOwn | ChangeNum$ 2 | SelectPrompt$ Select up to two Rat creature cards
|
||||
SVar:TrigChange:AB$ ChangeZone | Cost$ Mill<4> | Origin$ Graveyard | Destination$ Hand | ChangeType$ Rat.Creature+YouOwn | ChangeNum$ 2 | Hidden$ True | SelectPrompt$ Select up to two Rat creature cards
|
||||
SVar:HasAttackEffect:TRUE
|
||||
SVar:HasBlockEffect:TRUE
|
||||
DeckNeeds:Type$Rat
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Creature Avatar
|
||||
PT:5/3
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBSacSelf | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you discard two cards.
|
||||
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self | UnlessCost$ Discard<2/Card> | UnlessPayer$ You
|
||||
SVar:DBSacSelf:DB$ Sacrifice | UnlessCost$ Discard<2/Card> | UnlessPayer$ You
|
||||
SVar:NeedsToPlayVar:Y GE3
|
||||
SVar:Y:Count$InYourHand
|
||||
Oracle:({B/R} can be paid with either {B} or {R}.)\nFlying\nWhen Avatar of Discord enters the battlefield, sacrifice it unless you discard two cards.
|
||||
|
||||
@@ -6,7 +6,7 @@ S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | Description$ CARDNAME can't
|
||||
T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME enters the battlefield, you gain 4 life.
|
||||
T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | ManaNotSpent$ U | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless {U} was spent to cast it.
|
||||
SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 4
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:ManaNeededToAvoidNegativeEffect:blue
|
||||
AI:RemoveDeck:Random
|
||||
DeckNeeds:Color$Blue
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 R
|
||||
Types:Creature Human Barbarian Beast
|
||||
PT:2/2
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Swamp.YouCtrl | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ When you control no Swamps, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:NeedsToPlay:Swamp.YouCtrl
|
||||
AI:RemoveDeck:Random
|
||||
DeckNeeds:Color$Black
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Creature Serpent
|
||||
PT:5/5
|
||||
S:Mode$ CantAttack | ValidCard$ Card.Self | UnlessDefenderControls$ Swamp | Description$ CARDNAME can't attack unless defending player controls a Swamp.
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Swamp.YouCtrl | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ When you control no Swamps, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:NeedsToPlay:Swamp.YouCtrl
|
||||
Oracle:Bog Serpent can't attack unless defending player controls a Swamp.\nWhen you control no Swamps, sacrifice Bog Serpent.
|
||||
|
||||
@@ -5,6 +5,6 @@ PT:1/1
|
||||
K:Flying
|
||||
S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 2 | AddToughness$ 2 | AddTrigger$ SpellTarget | AddSVar$ SlasherSac & SlasherTarget | Condition$ Threshold | Description$ Threshold — As long as seven or more cards are in your graveyard, CARDNAME gets +2/+2 and has "When CARDNAME becomes the target of a spell or ability, sacrifice it."
|
||||
SVar:SpellTarget:Mode$ BecomesTarget | ValidTarget$ Card.Self | TriggerZones$ Battlefield | Execute$ SlasherSac | TriggerDescription$ When CARDNAME becomes the target of a spell or ability, sacrifice it.
|
||||
SVar:SlasherSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:SlasherSac:DB$ Sacrifice
|
||||
SVar:SlasherTarget:Targeting:Dies
|
||||
Oracle:Flying\nThreshold — As long as seven or more cards are in your graveyard, Boneshard Slasher gets +2/+2 and has "When Boneshard Slasher becomes the target of a spell or ability, sacrifice it."
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Brink of Madness
|
||||
ManaCost:2 B B
|
||||
Types:Enchantment
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | IsPresent$ Card.YouCtrl | PresentZone$ Hand | PresentCompare$ EQ0 | TriggerZones$ Battlefield | Execute$ TrigSacDiscard | TriggerDescription$ At the beginning of your upkeep, if you have no cards in hand, sacrifice CARDNAME and target opponent discards their hand.
|
||||
SVar:TrigSacDiscard:DB$ Sacrifice | Defined$ Self | SubAbility$ DBDiscard
|
||||
SVar:TrigSacDiscard:DB$ Sacrifice | SubAbility$ DBDiscard
|
||||
SVar:DBDiscard:DB$ Discard | ValidTgts$ Opponent | TgtPrompt$ Select target opponent to discard their hand | Mode$ Hand
|
||||
SVar:NonStackingEffect:True
|
||||
Oracle:At the beginning of your upkeep, if you have no cards in hand, sacrifice Brink of Madness and target opponent discards their hand.
|
||||
|
||||
@@ -2,11 +2,8 @@ Name:Bull Elephant
|
||||
ManaCost:3 G
|
||||
Types:Creature Elephant
|
||||
PT:4/4
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return two Forests you control to their owner's hand.
|
||||
SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Battlefield | Destination$ Hand | Hidden$ True | ChangeType$ Forest.YouCtrl | ChangeNum$ 2 | RememberChanged$ True | SubAbility$ DBSac
|
||||
SVar:DBSac:DB$ Sacrifice | Defined$ Self | SubAbility$ DBCleanup | ConditionCheckSVar$ X | ConditionSVarCompare$ LT2
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Remembered$Amount
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return two Forests you control to their owner's hand.
|
||||
SVar:TrigSac:DB$ Sacrifice | UnlessCost$ Return<2/Forest> | UnlessPayer$ You
|
||||
SVar:NeedsToPlayVar:Y GE2
|
||||
SVar:Y:Count$Valid Forest.YouCtrl
|
||||
Oracle:When Bull Elephant enters the battlefield, sacrifice it unless you return two Forests you control to their owner's hand.
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Cabaretti Courtyard
|
||||
ManaCost:no cost
|
||||
Types:Land
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBSacrifice | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it. When you do, search your library for a basic Mountain, Forest, or Plains card, put it onto the battlefield tapped, then shuffle and you gain 1 life.
|
||||
SVar:DBSacrifice:DB$ Sacrifice | Defined$ Self | RememberSacrificed$ True | SubAbility$ DBImmediateTrigger
|
||||
SVar:DBSacrifice:DB$ Sacrifice | RememberSacrificed$ True | SubAbility$ DBImmediateTrigger
|
||||
SVar:DBImmediateTrigger:DB$ ImmediateTrigger | ConditionDefined$ Remembered | ConditionPresent$ Card | Execute$ DBChangeZone | SubAbility$ DBCleanup | TriggerDescription$ Search your library for a basic Mountain, Forest, or Plains card, put it onto the battlefield tapped, then shuffle and you gain 1 life.
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.Mountain+Basic,Land.Forest+Basic,Land.Plains+Basic | ChangeNum$ 1 | SubAbility$ DBGainLife
|
||||
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1
|
||||
|
||||
@@ -5,5 +5,5 @@ K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 1 R | ValidTgts$ Creature | AILogic$ Pump
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 3 | AddToughness$ 2 | AddKeyword$ Trample | Description$ Enchanted creature gets +3/+2 and has trample.
|
||||
T:Mode$ Phase | Phase$ Upkeep | WerewolfUntransformCondition$ True | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of each upkeep, if a player cast two or more spells last turn, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
Oracle:Enchant creature\nEnchanted creature gets +3/+2 and has trample. (It can deal excess combat damage to the player or planeswalker it's attacking.)\nAt the beginning of each upkeep, if a player cast two or more spells last turn, sacrifice Call of the Full Moon.
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Enchantment
|
||||
T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of each player's upkeep, that player sacrifices a non-Zombie creature.
|
||||
SVar:TrigSac:DB$ Sacrifice | SacValid$ Creature.nonZombie | Defined$ TriggeredPlayer
|
||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | IsPresent$ Creature | PresentCompare$ EQ0 | Execute$ TrigSacSelf | TriggerDescription$ At the beginning of the end step, if no creatures are on the battlefield, sacrifice CARDNAME.
|
||||
SVar:TrigSacSelf:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSacSelf:DB$ Sacrifice
|
||||
AI:RemoveDeck:Random
|
||||
DeckHints:Type$Zombie
|
||||
Oracle:At the beginning of each player's upkeep, that player sacrifices a non-Zombie creature.\nAt the beginning of the end step, if no creatures are on the battlefield, sacrifice Call to the Grave.
|
||||
|
||||
@@ -6,7 +6,7 @@ T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefiel
|
||||
SVar:TrigAnimate:DB$ Animate | ValidTgts$ Permanent.nonLand+YouCtrl | TgtPrompt$ Select target nonland permanent you control | RemoveCardTypes$ True | Power$ X | Toughness$ X | Types$ Vehicle,Artifact | Keywords$ Crew:2 | Triggers$ CrashLand
|
||||
SVar:CrashLand:Mode$ DamageDealtOnce | ValidSource$ Card.Self | ValidTarget$ Player,Permanent | Execute$ RollCounters | TriggerZones$ Battlefield | TriggerDescription$ Crash Land — Whenever this Vehicle deals damage, roll a six-sided die. If the result is equal to this Vehicle's mana value, sacrifice this Vehicle, then it deals that much damage to any target.
|
||||
SVar:RollCounters:DB$ RollDice | ResultSVar$ Result | SubAbility$ Crash
|
||||
SVar:Crash:DB$ Sacrifice | Defined$ Card.Self | ConditionCheckSVar$ Result | ConditionSVarCompare$ EQY | SubAbility$ CrashDamage
|
||||
SVar:Crash:DB$ Sacrifice | ConditionCheckSVar$ Result | ConditionSVarCompare$ EQY | SubAbility$ CrashDamage
|
||||
SVar:CrashDamage:DB$ DealDamage | ValidTgt$ Planeswalker,Player,Permanent | TgtPromp$ Choose any target | NumDmg$ Y | ConditionCheckSVar$ Result | ConditionSVarCompare$ EQY
|
||||
SVar:X:Targeted$CardManaCost
|
||||
SVar:Y:Count$CardManaCost
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Legendary Creature Spirit
|
||||
PT:4/4
|
||||
K:Flying
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of your upkeep, sacrifice CARDNAME unless you remove a counter from a permanent you control.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self | UnlessPayer$ You | UnlessCost$ RemoveAnyCounter<1/Any/Permanent.YouCtrl/a permanent you control>
|
||||
SVar:TrigSac:DB$ Sacrifice | UnlessPayer$ You | UnlessCost$ RemoveAnyCounter<1/Any/Permanent.YouCtrl/a permanent you control>
|
||||
DeckNeeds:Ability$Counters
|
||||
SVar:NeedsToPlay:Creature.YouCtrl+HasCounters
|
||||
SVar:AIRemoveCounterCostPriority:ANY
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:City of Traitors
|
||||
ManaCost:no cost
|
||||
Types:Land
|
||||
T:Mode$ LandPlayed | ValidCard$ Land.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ When you play another land, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
A:AB$ Mana | Cost$ T | Produced$ C | Amount$ 2 | SpellDescription$ Add {C}{C}.
|
||||
AI:RemoveDeck:All
|
||||
Oracle:When you play another land, sacrifice City of Traitors.\n{T}: Add {C}{C}.
|
||||
|
||||
@@ -12,7 +12,7 @@ SVar:TrigRemoveCounter:DB$ RemoveCounter | Defined$ Self | CounterType$ PUPA | C
|
||||
# TODO need EnchantedLKI because it isn't enchanted anymore if this is sacrificed
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Enchanted | CounterType$ P1P1 | CounterNum$ 1 | ConditionCheckSVar$ X | ConditionSVarCompare$ LE0 | SubAbility$ TrigPump
|
||||
SVar:TrigPump:DB$ Pump | Defined$ Enchanted | KW$ Flying | Duration$ Permanent | ConditionCheckSVar$ X | ConditionSVarCompare$ LE0 | SubAbility$ TrigSac
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self | ConditionCheckSVar$ X | ConditionSVarCompare$ LE0 | SubAbility$ DBCleanup
|
||||
SVar:TrigSac:DB$ Sacrifice | ConditionCheckSVar$ X | ConditionSVarCompare$ LE0 | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Count$RememberedSize
|
||||
AI:RemoveDeck:Random
|
||||
|
||||
@@ -3,8 +3,8 @@ ManaCost:3
|
||||
Types:Artifact
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | TriggerZones$ Battlefield | ValidCard$ Creature.toughnessGE4+YouOwn | OptionalDecider$ You | Execute$ TrigExile | TriggerDescription$ Whenever a creature with toughness 4 or greater is put into your graveyard from the battlefield, you may exile it.
|
||||
SVar:TrigExile:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | Defined$ TriggeredNewCardLKICopy | RememberChanged$ True
|
||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ GE3 | Execute$ TrigReturnAll | TriggerDescription$ At the beginning of the end step, if three or more cards have been exiled with Colfenor's Urn, sacrifice it. If you do, return those cards to the battlefield under their owner's control.
|
||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ GE3 | Execute$ TrigReturnAll | TriggerDescription$ At the beginning of the end step, if three or more cards have been exiled with CARDNAME, sacrifice it. If you do, return those cards to the battlefield under their owner's control.
|
||||
SVar:TrigReturnAll:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Exile | Destination$ Battlefield | SubAbility$ DBSacSelf
|
||||
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self
|
||||
SVar:DBSacSelf:DB$ Sacrifice
|
||||
SVar:X:Remembered$Amount
|
||||
Oracle:Whenever a creature with toughness 4 or greater is put into your graveyard from the battlefield, you may exile it.\nAt the beginning of the end step, if three or more cards have been exiled with Colfenor's Urn, sacrifice it. If you do, return those cards to the battlefield under their owner's control.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:no cost
|
||||
Types:Land
|
||||
K:CARDNAME enters the battlefield tapped.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSacUnless | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return an untapped Island you control to its owner's hand.
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | Defined$ Self | UnlessCost$ Return<1/Island.untapped/untapped Island> | UnlessPayer$ You
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | UnlessCost$ Return<1/Island.untapped/untapped Island> | UnlessPayer$ You
|
||||
A:AB$ Mana | Cost$ T | Produced$ C U | SpellDescription$ Add {C}{U}.
|
||||
SVar:NeedsToPlay:Land.Island+YouCtrl+untapped
|
||||
Oracle:Coral Atoll enters the battlefield tapped.\nWhen Coral Atoll enters the battlefield, sacrifice it unless you return an untapped Island you control to its owner's hand.\n{T}: Add {C}{U}.
|
||||
|
||||
@@ -6,7 +6,7 @@ A:SP$ Attach | Cost$ U | ValidTgts$ Creature.Green,Creature.White | TgtPrompt$ S
|
||||
S:Mode$ Continuous | Affected$ Creature.AttachedBy | AddTrigger$ TrigCoralPhase | AddSVar$ TrigCoralDiscard & DBCoralSacrifice & DBCoralCleanup | Description$ Enchanted creature has "At the beginning of your upkeep, sacrifice this creature unless you discard a card."
|
||||
SVar:TrigCoralPhase:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigCoralDiscard | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, sacrifice this creature unless you discard a card.
|
||||
SVar:TrigCoralDiscard:DB$ Discard | Defined$ You | Mode$ TgtChoose | NumCards$ 1 | Optional$ True | RememberDiscarded$ True | SubAbility$ DBCoralSacrifice
|
||||
SVar:DBCoralSacrifice:DB$ Sacrifice | Defined$ Self | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBCoralCleanup
|
||||
SVar:DBCoralSacrifice:DB$ Sacrifice | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBCoralCleanup
|
||||
SVar:DBCoralCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
AI:RemoveDeck:Random
|
||||
SVar:NonStackingAttachEffect:True
|
||||
|
||||
@@ -6,7 +6,7 @@ K:Vigilance
|
||||
T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ When CARDNAME enters the battlefield, look at the top three cards of your library, then put one of them into your hand and the rest on the bottom of your library in any order.
|
||||
T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | ManaNotSpent$ W | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless {W} was spent to cast it.
|
||||
SVar:TrigDig:DB$ Dig | DigNum$ 3 | Defined$ You
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:ManaNeededToAvoidNegativeEffect:white
|
||||
AI:RemoveDeck:Random
|
||||
DeckNeeds:Color$White
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Creature Dragon
|
||||
PT:6/5
|
||||
K:Flying
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Artifact.YouCtrl | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ When you control no artifacts, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:NeedsToPlay:Artifact.YouCtrl
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:Flying\nWhen you control no artifacts, sacrifice Covetous Dragon.
|
||||
|
||||
@@ -5,7 +5,7 @@ K:Enchant land you control
|
||||
A:SP$ Attach | Cost$ 1 R | ValidTgts$ Land.YouCtrl | TgtPrompt$ Select target land you control | AILogic$ Animate
|
||||
S:Mode$ Continuous | Affected$ Land.EnchantedBy | AddType$ Creature & Spirit | SetColor$ Red | SetPower$ 3 | SetToughness$ 3 | AddKeyword$ Haste | Description$ Enchanted land is a 3/3 red Spirit creature with haste. It's still a land.
|
||||
R:Event$ Destroy | ValidCard$ Card.EnchantedBy | ReplaceWith$ CracklingEgress | Description$ If enchanted land would be destroyed, instead sacrifice CARDNAME and that land gains indestructible until end of turn.
|
||||
SVar:CracklingEgress:DB$ Sacrifice | Defined$ Card.Self | SubAbility$ DBPump
|
||||
SVar:CracklingEgress:DB$ Sacrifice | SubAbility$ DBPump
|
||||
SVar:DBPump:DB$ Pump | Defined$ Enchanted | KW$ Indestructible
|
||||
DeckHas:Ability$Sacrifice & Type$Spirit
|
||||
Oracle:Enchant land you control\nEnchanted land is a 3/3 red Spirit creature with haste. It's still a land.\nIf enchanted land would be destroyed, instead sacrifice Crackling Emergence and that land gains indestructible until end of turn.
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:no cost
|
||||
Types:Land Lair
|
||||
A:AB$ Mana | Cost$ T | Produced$ Combo U B R | SpellDescription$ Add {U}, {B}, or {R}.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSacUnless | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | Defined$ Self | UnlessCost$ Return<1/Land.nonLair/non-Lair land> | UnlessPayer$ You
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | UnlessCost$ Return<1/Land.nonLair/non-Lair land> | UnlessPayer$ You
|
||||
SVar:NeedsToPlay:Land.nonLair+YouCtrl
|
||||
Oracle:When Crosis's Catacombs enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.\n{T}: Add {U}, {B}, or {R}.
|
||||
|
||||
@@ -7,6 +7,6 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | ManaNotSpent$ R | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless {R} was spent to cast it.
|
||||
SVar:TrigChangeZone:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBChangeZone
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.RememberedPlayerCtrl+cmcLE3 | ChangeNum$ 1 | Hidden$ True | DefinedPlayer$ Player.IsRemembered | Chooser$ Player.IsRemembered | Mandatory$ True
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:ManaNeededToAvoidNegativeEffect:red
|
||||
Oracle:Double strike\nWhen Crypt Champion enters the battlefield, each player puts a creature card with mana value 3 or less from their graveyard onto the battlefield.\nWhen Crypt Champion enters the battlefield, sacrifice it unless {R} was spent to cast it.
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Creature Horror
|
||||
PT:4/3
|
||||
K:Flying
|
||||
T:Mode$ BecomesTarget | ValidTarget$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ When CARDNAME becomes the target of a spell or ability, sacrifice it unless you discard a land card.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self | UnlessCost$ Discard<1/Land> | UnlessPayer$ You
|
||||
SVar:TrigSac:DB$ Sacrifice | UnlessCost$ Discard<1/Land> | UnlessPayer$ You
|
||||
SVar:Targeting:Dies
|
||||
Oracle:Flying\nWhenever Cursed Monstrosity becomes the target of a spell or ability, sacrifice it unless you discard a land card.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:2 G G
|
||||
Types:Enchantment
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your upkeep, put a wind counter on CARDNAME, then sacrifice CARDNAME unless you pay {G} for each wind counter on it. If you pay, CARDNAME deals damage equal to the number of wind counters on it to each creature and each player.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ WIND | CounterNum$ 1 | SubAbility$ SacSelf
|
||||
SVar:SacSelf:DB$ Sacrifice | Defined$ Card.Self | UnlessCost$ X | UnlessXColor$ G | UnlessPayer$ You | UnlessResolveSubs$ WhenPaid | SubAbility$ DBDamageAll
|
||||
SVar:SacSelf:DB$ Sacrifice | UnlessCost$ X | UnlessXColor$ G | UnlessPayer$ You | UnlessResolveSubs$ WhenPaid | SubAbility$ DBDamageAll
|
||||
SVar:DBDamageAll:DB$ DamageAll | NumDmg$ X | ValidCards$ Creature | ValidPlayers$ Player
|
||||
SVar:X:Count$CardCounters.WIND
|
||||
AI:RemoveDeck:All
|
||||
|
||||
@@ -7,7 +7,7 @@ T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.S
|
||||
SVar:TrigExile:DB$ ChangeZone | Defined$ Remembered | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.IsRemembered | Execute$ TrigSac | TriggerDescription$ When the token leaves the battlefield, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self | SubAbility$ DBCleanup
|
||||
SVar:TrigSac:DB$ Sacrifice | SubAbility$ DBCleanup
|
||||
K:UpkeepCost:U U
|
||||
DeckHas:Ability$Token|Sacrifice
|
||||
Oracle:When Dance of Many enters the battlefield, create a token that's a copy of target nontoken creature.\nWhen Dance of Many leaves the battlefield, exile the token.\nWhen the token leaves the battlefield, sacrifice Dance of Many.\nAt the beginning of your upkeep, sacrifice Dance of Many unless you pay {U}{U}.
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Creature Fish
|
||||
PT:4/1
|
||||
S:Mode$ CantAttack | ValidCard$ Card.Self | UnlessDefenderControls$ Island | Description$ Dandân can't attack unless defending player controls an Island.
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Island.YouCtrl | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ When you control no Islands, sacrifice Dandân.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:NeedsToPlay:Island.YouCtrl
|
||||
DeckHas:Ability$Sacrifice
|
||||
Oracle:Dandân can't attack unless defending player controls an Island.\nWhen you control no Islands, sacrifice Dandân.
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:no cost
|
||||
Types:Land Lair
|
||||
A:AB$ Mana | Cost$ T | Produced$ Combo B R G | SpellDescription$ Add {B}, {R}, or {G}.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSacUnless | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | Defined$ Self | UnlessCost$ Return<1/Land.nonLair/non-Lair land> | UnlessPayer$ You
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | UnlessCost$ Return<1/Land.nonLair/non-Lair land> | UnlessPayer$ You
|
||||
SVar:NeedsToPlay:Land.nonLair+YouCtrl
|
||||
Oracle:When Darigaaz's Caldera enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.\n{T}: Add {B}, {R}, or {G}.
|
||||
|
||||
@@ -5,7 +5,7 @@ K:Cycling:4 U U
|
||||
T:Mode$ SpellCast | ValidCard$ Card.OppCtrl | Execute$ TrigCounterSpell | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent casts a spell, counter that spell and put a depletion counter on CARDNAME. If there are three or more depletion counters on CARDNAME, sacrifice it.
|
||||
SVar:TrigCounterSpell:DB$ Counter | Defined$ TriggeredSpellAbility | SubAbility$ DBPutCounter
|
||||
SVar:DBPutCounter:DB$ PutCounter | CounterType$ DEPLETION | CounterNum$ 1 | Defined$ Self | SubAbility$ DBSac
|
||||
SVar:DBSac:DB$ Sacrifice | Defined$ Self | ConditionCheckSVar$ DecreeX | ConditionSVarCompare$ GE1
|
||||
SVar:DBSac:DB$ Sacrifice | ConditionCheckSVar$ DecreeX | ConditionSVarCompare$ GE1
|
||||
T:Mode$ Cycled | ValidCard$ Card.Self | Execute$ TrigCounter | OptionalDecider$ You | TriggerDescription$ When you cycle CARDNAME, you may counter target spell.
|
||||
SVar:TrigCounter:DB$ Counter | TargetType$ Spell | ValidTgts$ Card
|
||||
SVar:DecreeX:Count$Valid Card.Self+counters_GE3_DEPLETION
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Demonic Attorney
|
||||
ManaCost:1 B B
|
||||
Types:Sorcery
|
||||
K:Remove CARDNAME from your deck before playing if you're not playing for ante.
|
||||
A:SP$ Dig | Cost$ 1 B B | Defined$ Player | DigNum$ 1 | DestinationZone$ Ante | SpellDescription$ Each player antes the top card of their library.
|
||||
A:SP$ Dig | Cost$ 1 B B | Defined$ Player | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Ante | SpellDescription$ Each player antes the top card of their library.
|
||||
AI:RemoveDeck:All
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:Remove Demonic Attorney from your deck before playing if you're not playing for ante.\nEach player antes the top card of their library.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:6 U
|
||||
Types:Enchantment
|
||||
S:Mode$ Continuous | Affected$ Creature.OppCtrl | AddType$ Illusion | AddTrigger$ DismissTarget | AddSVar$ DismissSac & TargetingSac | Description$ Each creature your opponents control is an Illusion in addition to its other types and has "When this creature becomes the target of a spell or ability, sacrifice it."
|
||||
SVar:DismissTarget:Mode$ BecomesTarget | ValidTarget$ Card.Self | TriggerZones$ Battlefield | Execute$ DismissSac | TriggerDescription$ When CARDNAME becomes the target of a spell or ability, sacrifice it.
|
||||
SVar:DismissSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:DismissSac:DB$ Sacrifice
|
||||
SVar:NonStackingEffect:True
|
||||
SVar:TargetingSac:SVar:Targeting:Dies
|
||||
Oracle:Each creature your opponents control is an Illusion in addition to its other types and has "When this creature becomes the target of a spell or ability, sacrifice it."
|
||||
|
||||
@@ -5,6 +5,6 @@ K:Enchant artifact
|
||||
A:SP$ Attach | Cost$ 2 U | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | AITgts$ Card.cmcGE1 | AILogic$ Curse
|
||||
S:Mode$ Continuous | Affected$ Artifact.EnchantedBy | AddTrigger$ TrigPhase | AddSVar$ TrigDisruptionAura | Description$ Enchanted artifact has "At the beginning of your upkeep, sacrifice this artifact unless you pay its mana cost."
|
||||
SVar:TrigPhase:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigDisruptionAura | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, sacrifice this artifact unless you pay its mana cost.
|
||||
SVar:TrigDisruptionAura:DB$ Sacrifice | Defined$ Self | UnlessCost$ CardManaCost | UnlessPayer$ You
|
||||
SVar:TrigDisruptionAura:DB$ Sacrifice | UnlessCost$ CardManaCost | UnlessPayer$ You
|
||||
SVar:NonStackingAttachEffect:True
|
||||
Oracle:Enchant artifact\nEnchanted artifact has "At the beginning of your upkeep, sacrifice this artifact unless you pay its mana cost."
|
||||
|
||||
@@ -2,6 +2,6 @@ Name:District Guide
|
||||
ManaCost:2 G
|
||||
Types:Creature Elf Scout
|
||||
PT:2/2
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a basic land card or Gate card, reveal it, put it into your hand, then shuffle.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a basic land card or Gate card, reveal it, put it into your hand, then shuffle.
|
||||
SVar:TrigChange:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Land.Basic,Card.Gate | ChangeNum$ 1 | ShuffleNonMandatory$ True
|
||||
Oracle:When District Guide enters the battlefield, you may search your library for a basic land card or Gate card, reveal it, put it into your hand, then shuffle.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:3 W W
|
||||
Types:Legendary Creature Human Warrior
|
||||
PT:4/3
|
||||
K:Vigilance
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a planeswalker card, reveal it, put it into your hand, then shuffle.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a planeswalker card, reveal it, put it into your hand, then shuffle.
|
||||
SVar:TrigChange:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Planeswalker | ChangeNum$ 1 | ShuffleNonMandatory$ True
|
||||
R:Event$ DamageDone | ActiveZones$ Battlefield | ValidTarget$ Planeswalker.YouCtrl | ReplaceWith$ DBReplace | PreventionEffect$ True | Description$ If a source would deal damage to a planeswalker you control, prevent 1 of that damage.
|
||||
SVar:DBReplace:DB$ ReplaceDamage | Amount$ 1
|
||||
|
||||
@@ -5,5 +5,5 @@ K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 2 U U | ValidTgts$ Creature | AILogic$ GainControl | AITgts$ Creature.powerLT4
|
||||
S:Mode$ Continuous | Affected$ Card.EnchantedBy | GainControl$ You | Description$ You control enchanted creature.
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Card.AttachedBy+powerGE4 | Execute$ TrigSac | TriggerDescription$ At the beginning of your end step, if enchanted creature's power is 4 or greater, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
Oracle:Enchant creature\nYou control enchanted creature.\nAt the beginning of your end step, if enchanted creature's power is 4 or greater, sacrifice Domestication.
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Land
|
||||
K:CARDNAME enters the battlefield tapped.
|
||||
A:AB$ Mana | Cost$ T | Produced$ C R | SpellDescription$ Add {C}{R}.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSacUnless | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return an untapped Mountain you control to its owner's hand.
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | Defined$ Self | UnlessCost$ Return<1/Mountain.untapped/untapped Mountain> | UnlessPayer$ You
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | UnlessCost$ Return<1/Mountain.untapped/untapped Mountain> | UnlessPayer$ You
|
||||
SVar:NeedsToPlay:Mountain.YouCtrl+untapped
|
||||
Oracle:Dormant Volcano enters the battlefield tapped.\nWhen Dormant Volcano enters the battlefield, sacrifice it unless you return an untapped Mountain you control to its owner's hand.\n{T}: Add {C}{R}.
|
||||
|
||||
@@ -5,7 +5,7 @@ PT:9/9
|
||||
K:Flying
|
||||
S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ Domain — This spell costs {2} less to cast for each basic land type among lands you control.
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ Domain — At the beginning of your upkeep, sacrifice CARDNAME unless you pay {10}. This cost is reduced by {2} for each basic land type among lands you control.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self | UnlessCost$ UpkeepX | UnlessPayer$ You
|
||||
SVar:TrigSac:DB$ Sacrifice | UnlessCost$ UpkeepX | UnlessPayer$ You
|
||||
SVar:X:Count$Domain/Twice
|
||||
SVar:UpkeepX:Number$10/Minus.X
|
||||
Oracle:Domain — This spell costs {2} less to cast for each basic land type among lands you control.\nFlying\nDomain — At the beginning of your upkeep, sacrifice Draco unless you pay {10}. This cost is reduced by {2} for each basic land type among lands you control.
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Creature Elemental Incarnation
|
||||
PT:6/6
|
||||
K:Fear
|
||||
T:Mode$ DamageDone | ValidSource$ Creature.inZoneBattlefield | ValidTarget$ You | Execute$ TrigDestroy | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature deals damage to you, destroy it.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Creature.Self | Execute$ TrigShuffle | TriggerDescription$ When CARDNAME is put into a graveyard from anywhere, shuffle it into its owner's library.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigShuffle | TriggerDescription$ When CARDNAME is put into a graveyard from anywhere, shuffle it into its owner's library.
|
||||
SVar:TrigShuffle:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | Shuffle$ True | Defined$ TriggeredCardLKICopy
|
||||
SVar:TrigDestroy:DB$ Destroy | Defined$ TriggeredSourceLKICopy
|
||||
Oracle:Fear (This creature can't be blocked except by artifact creatures and/or black creatures.)\nWhenever a creature deals damage to you, destroy it.\nWhen Dread is put into a graveyard from anywhere, shuffle it into its owner's library.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 B
|
||||
Types:Creature Beast
|
||||
PT:3/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBSacSelf | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you discard a noncreature card.
|
||||
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self | UnlessCost$ Discard<1/Card.nonCreature> | UnlessPayer$ You
|
||||
SVar:DBSacSelf:DB$ Sacrifice | UnlessCost$ Discard<1/Card.nonCreature> | UnlessPayer$ You
|
||||
SVar:NeedsToPlayVar:Y GE1
|
||||
SVar:Y:Count$ValidHand Card.nonCreature+YouCtrl
|
||||
Oracle:When Drekavac enters the battlefield, sacrifice it unless you discard a noncreature card.
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:no cost
|
||||
Types:Land Lair
|
||||
A:AB$ Mana | Cost$ T | Produced$ Combo W U B | SpellDescription$ Add {W}, {U}, or {B}.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSacUnless | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | Defined$ Self | UnlessCost$ Return<1/Land.nonLair/non-Lair land> | UnlessPayer$ You
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | UnlessCost$ Return<1/Land.nonLair/non-Lair land> | UnlessPayer$ You
|
||||
SVar:NeedsToPlay:Land.nonLair+YouCtrl
|
||||
Oracle:When Dromar's Cavern enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.\n{T}: Add {W}, {U}, or {B}.
|
||||
|
||||
@@ -5,7 +5,7 @@ T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | E
|
||||
SVar:TrigChooseOneToDestroy:DB$ ChooseCard | Choices$ Creature.leastPower+withoutIndestructible | Mandatory$ True | SubAbility$ DBDestroy
|
||||
SVar:DBDestroy:DB$ Destroy | Defined$ ChosenCard | NoRegen$ True
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Creature | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ When there are no creatures on the battlefield, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:NeedsToPlay:Creature.YouDontCtrl+leastPower
|
||||
DeckHas:Ability$Sacrifice
|
||||
AI:RemoveDeck:All
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Legendary Creature God
|
||||
PT:6/6
|
||||
K:Deathtouch
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ DBSacSelf | TriggerDescription$ At the beginning of your upkeep, exile two cards from your graveyard. If you can't, sacrifice NICKNAME and draw a card.
|
||||
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self | UnlessCost$ Mandatory ExileFromGrave<2/Card> | UnlessPayer$ You | UnlessResolveSubs$ WhenNotPaid | SubAbility$ DBDraw
|
||||
SVar:DBSacSelf:DB$ Sacrifice | UnlessCost$ Mandatory ExileFromGrave<2/Card> | UnlessPayer$ You | UnlessResolveSubs$ WhenNotPaid | SubAbility$ DBDraw
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ 1
|
||||
AlternateMode:Modal
|
||||
DeckHints:Ability$Discard|Graveyard
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Creature Spawn
|
||||
PT:6/6
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigElderSpawnSacrifice | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, unless you sacrifice an Island, sacrifice CARDNAME and it deals 6 damage to you. CARDNAME can't be blocked by red creatures.
|
||||
SVar:TrigElderSpawnSacrifice:DB$ Sacrifice | SacValid$ Island | Optional$ True | RememberSacrificed$ True | SubAbility$ DBElderSpawnSacrificeMe
|
||||
SVar:DBElderSpawnSacrificeMe:DB$ Sacrifice | Defined$ Self | ConditionDefined$ Remembered | ConditionPresent$ Island | ConditionCompare$ EQ0 | SubAbility$ DBElderSpawnDamage
|
||||
SVar:DBElderSpawnSacrificeMe:DB$ Sacrifice | ConditionDefined$ Remembered | ConditionPresent$ Island | ConditionCompare$ EQ0 | SubAbility$ DBElderSpawnDamage
|
||||
SVar:DBElderSpawnDamage:DB$ DealDamage | Defined$ You | NumDmg$ 6 | ConditionDefined$ Remembered | ConditionPresent$ Island | ConditionCompare$ EQ0 | SubAbility$ DBElderSpawnCleanup
|
||||
SVar:DBElderSpawnCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.Red | Description$ CARDNAME can't be blocked by red creatures.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:5
|
||||
Types:Artifact
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of your upkeep, sacrifice a creature. If you can't, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ You | SacValid$ Creature | SubAbility$ DBSacSelf | RememberSacrificed$ True
|
||||
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self | SubAbility$ DBCleanup | ConditionCheckSVar$ X | ConditionSVarCompare$ LT1 | SubAbility$ DBCleanup
|
||||
SVar:DBSacSelf:DB$ Sacrifice | SubAbility$ DBCleanup | ConditionCheckSVar$ X | ConditionSVarCompare$ LT1 | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Remembered$Amount
|
||||
S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddPower$ 1 | AddToughness$ 1 | AddKeyword$ Flying & Indestructible | Description$ Creatures you control get +1/+1 and have flying and indestructible.
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:3 G
|
||||
Types:Creature Crocodile
|
||||
PT:5/5
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Creature.Other+YouCtrl | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ When you control no other creatures, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:NeedsToPlay:Creature.YouCtrl
|
||||
Oracle:When you control no other creatures, sacrifice Emperor Crocodile.
|
||||
|
||||
@@ -6,7 +6,7 @@ K:This spell can't be countered.
|
||||
K:Flying
|
||||
K:Protection:Spell.nonColorless:Protection from colored spells
|
||||
K:Annihilator:6
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Creature.Self | Execute$ TrigShuffle | TriggerDescription$ When CARDNAME is put into a graveyard from anywhere, its owner shuffles their graveyard into their library.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigShuffle | TriggerDescription$ When CARDNAME is put into a graveyard from anywhere, its owner shuffles their graveyard into their library.
|
||||
SVar:TrigShuffle:DB$ ChangeZoneAll | Defined$ TriggeredCardOwner | ChangeType$ Card | Origin$ Graveyard | Destination$ Library | Shuffle$ True
|
||||
T:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigAddTurn | TriggerDescription$ When you cast CARDNAME, take an extra turn after this one.
|
||||
SVar:TrigAddTurn:DB$ AddTurn | Defined$ You | NumTurns$ 1
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:2 G G
|
||||
Types:Creature Elephant
|
||||
PT:4/5
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Creature.toughnessLE2+YouCtrl | PresentCompare$ GE1 | Execute$ TrigSac | TriggerDescription$ When you control a creature with toughness 2 or less, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:When you control a creature with toughness 2 or less, sacrifice Endangered Armodon.
|
||||
|
||||
@@ -6,5 +6,5 @@ T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$
|
||||
T:Mode$ Always | IsPresent$ Card.Thrull+YouCtrl | PresentCompare$ GE7 | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ When you control seven or more Thrulls, sacrifice CARDNAME.
|
||||
SVar:TrigToken:DB$ Token | TokenOwner$ You | TokenAmount$ X | TokenScript$ b_1_1_thrull
|
||||
SVar:X:TriggeredStackInstance$CardManaCostLKI
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
Oracle:Whenever you cast a creature spell, create X 1/1 black Thrull creature tokens, where X is that spell's mana value.\nWhen you control seven or more Thrulls, sacrifice Endrek Sahr, Master Breeder.
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Energy Field
|
||||
ManaCost:1 U
|
||||
Types:Enchantment
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Card.nonToken+YouOwn+Other | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ When a card is put into your graveyard from anywhere, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
R:Event$ DamageDone | ActiveZones$ Battlefield | Prevent$ True | ValidTarget$ You | ValidSource$ Card.YouDontCtrl,Emblem.YouDontCtrl | Description$ Prevent all damage that would be dealt to you by sources you don't control.
|
||||
SVar:NonStackingEffect:True
|
||||
#NOTE: The AI will not play around this effect, so it's only good in properly designed decks that circumvent the necessity to worry about the detrimental effect.
|
||||
|
||||
@@ -5,7 +5,7 @@ K:Enchant permanent
|
||||
A:SP$ Attach | Cost$ U | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | AITgts$ Card.cmcGE1+Green,Card.cmcGE1+Red | AILogic$ Curse
|
||||
S:Mode$ Continuous | Affected$ Permanent.AttachedBy+Red,Permanent.AttachedBy+Green | AddTrigger$ TrigEssencePhase | AddSVar$ TrigEssenceLeak | Description$ As long as enchanted permanent is red or green, it has "At the beginning of your upkeep, sacrifice this permanent unless you pay its mana cost."
|
||||
SVar:TrigEssencePhase:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigEssenceLeak | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, sacrifice this permanent unless you pay its mana cost.
|
||||
SVar:TrigEssenceLeak:DB$ Sacrifice | Defined$ Self | UnlessCost$ CardManaCost | UnlessPayer$ You
|
||||
SVar:TrigEssenceLeak:DB$ Sacrifice | UnlessCost$ CardManaCost | UnlessPayer$ You
|
||||
AI:RemoveDeck:Random
|
||||
SVar:NonStackingAttachEffect:True
|
||||
Oracle:Enchant permanent\nAs long as enchanted permanent is red or green, it has "At the beginning of your upkeep, sacrifice this permanent unless you pay its mana cost."
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Land
|
||||
K:CARDNAME enters the battlefield tapped.
|
||||
A:AB$ Mana | Cost$ T | Produced$ C B | SpellDescription$ Add {C}{B}.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSacUnless | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return an untapped Swamp you control to its owner's hand.
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | Defined$ Self | UnlessCost$ Return<1/Swamp.untapped/untapped Swamp> | UnlessPayer$ You
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | UnlessCost$ Return<1/Swamp.untapped/untapped Swamp> | UnlessPayer$ You
|
||||
SVar:NeedsToPlay:Swamp.YouCtrl+untapped
|
||||
Oracle:Everglades enters the battlefield tapped.\nWhen Everglades enters the battlefield, sacrifice it unless you return an untapped Swamp you control to its owner's hand.\n{T}: Add {C}{B}.
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Creature Faerie Rogue
|
||||
PT:2/1
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSacUnless | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return another creature you control to its owner's hand.
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | Defined$ Self | UnlessCost$ Return<1/Creature.Other/other creature> | UnlessPayer$ You
|
||||
SVar:TrigSacUnless:DB$ Sacrifice | UnlessCost$ Return<1/Creature.Other/other creature> | UnlessPayer$ You
|
||||
SVar:NeedsToPlay:Creature.YouCtrl
|
||||
Oracle:Flying\nWhen Faerie Impostor enters the battlefield, sacrifice it unless you return another creature you control to its owner's hand.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:2 G
|
||||
Types:Creature Wurm
|
||||
PT:4/4
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBSacSelf | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you discard a land card.
|
||||
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self | UnlessCost$ Discard<1/Land> | UnlessPayer$ You
|
||||
SVar:DBSacSelf:DB$ Sacrifice | UnlessCost$ Discard<1/Land> | UnlessPayer$ You
|
||||
SVar:NeedsToPlayVar:Y GE1
|
||||
SVar:Y:Count$TypeInYourHand.Land
|
||||
Oracle:When Fallow Wurm enters the battlefield, sacrifice it unless you discard a land card.
|
||||
|
||||
@@ -6,6 +6,6 @@ SVar:DBConjure:DB$ MakeCard | Conjure$ True | DefinedName$ Targeted.nonToken | Z
|
||||
SVar:DBEffect:DB$ Effect | StaticAbilities$ PerpetualAbility | RememberObjects$ Remembered | Name$ Flames of Moradin's Perpetual Effect | Duration$ Permanent
|
||||
SVar:PerpetualAbility:Mode$ Continuous | RememberObjects$ Targeted | AddKeyword$ Alternative Cost: R | Affected$ Card.IsRemembered | AddTrigger$ TrigSac | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ This creature perpetually gains "You may pay {R} rather than pay this spell's mana cost" and "at the beginning of your end step, sacrifice this artifact."
|
||||
SVar:TrigSac:Mode$ Phase | ValidPlayer$ You | Phase$ End of Turn | Execute$ TrigSacrifice | TriggerZones$ Battlefield | TriggerDescription$ Sacrifice CARDNAME at you end step.
|
||||
SVar:TrigSacrifice:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSacrifice:DB$ Sacrifice
|
||||
DeckHas:Type$Artifact & Ability$Sacrifice
|
||||
Oracle:Destroy up to three target artifacts. Conjure a duplicate of each nontoken artifact destroyed this way into your hand. The duplicates perpetually gain "You may pay {R} rather than pay this spell's mana cost" and "at the beginning of your end step, sacrifice this artifact.".
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Enchantment
|
||||
R:Event$ DamageDone | ActiveZones$ Battlefield | ValidTarget$ You | ReplaceWith$ Counters | Description$ If damage would be dealt to you, put that many depletion counters on CARDNAME instead.
|
||||
SVar:Counters:DB$ PutCounter | Defined$ Self | CounterType$ DEPLETION | CounterNum$ X
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Card.Self+counters_GE4_DEPLETION | Execute$ TrigSac | TriggerDescription$ When there are four or more depletion counters on CARDNAME, sacrifice it.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigRemoveCounter | TriggerDescription$ At the beginning of each end step, remove all depletion counters from CARDNAME.
|
||||
SVar:TrigRemoveCounter:DB$ RemoveCounter | CounterType$ DEPLETION | CounterNum$ All
|
||||
SVar:X:ReplaceCount$DamageAmount
|
||||
|
||||
@@ -5,5 +5,5 @@ PT:2/1
|
||||
K:Flying
|
||||
A:AB$ FlipACoin | Cost$ 0 | WinSubAbility$ DBPhase | LoseSubAbility$ DBSacrifice | AILogic$ PhaseOut | SpellDescription$ Flip a coin. If you win the flip, Frenetic Efreet phases out. If you lose the flip, sacrifice Frenetic Efreet. (While it's phased out, it's treated as though it doesn't exist. It phases in before you untap during your next untap step.)
|
||||
SVar:DBPhase:DB$ Phases | Defined$ Self
|
||||
SVar:DBSacrifice:DB$ Sacrifice | Defined$ Self
|
||||
SVar:DBSacrifice:DB$ Sacrifice
|
||||
Oracle:Flying\n{0}: Flip a coin. If you win the flip, Frenetic Efreet phases out. If you lose the flip, sacrifice Frenetic Efreet. (While it's phased out, it's treated as though it doesn't exist. It phases in before you untap during your next untap step.)
|
||||
|
||||
@@ -7,7 +7,7 @@ SVar:Frenetic:AB$ FlipACoin | Cost$ 0 | ConditionPresent$ Card.Self | ConditionC
|
||||
SVar:DBExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | Defined$ Self | SubAbility$ DelTrig
|
||||
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ MoveBack
|
||||
SVar:MoveBack:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ Self | TriggerDescription$ Return CARDNAME to the battlefield under its owner's control at the beginning of the next end step.
|
||||
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self
|
||||
SVar:DBSacSelf:DB$ Sacrifice
|
||||
SVar:PlayMain1:TRUE
|
||||
AI:RemoveDeck:All
|
||||
Oracle:All Slivers have "{0}: If this permanent is on the battlefield, flip a coin. If you win the flip, exile this permanent and return it to the battlefield under its owner's control at the beginning of the next end step. If you lose the flip, sacrifice it."
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:1 U
|
||||
Types:Creature Elemental
|
||||
PT:4/1
|
||||
T:Mode$ BecomesTarget | ValidTarget$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ When CARDNAME becomes the target of a spell or ability, sacrifice it.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:Targeting:Dies
|
||||
Oracle:When Frost Walker becomes the target of a spell or ability, sacrifice it.
|
||||
|
||||
@@ -5,7 +5,7 @@ PT:7/7
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigSacrifice | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, you may sacrifice a Forest. If you sacrifice a snow Forest this way, CARDNAME gains trample until end of turn. If you don't sacrifice a Forest, sacrifice CARDNAME and it deals 7 damage to you.
|
||||
SVar:TrigSacrifice:DB$ Sacrifice | Optional$ True | SacValid$ Forest | Amount$ 1 | RememberSacrificed$ True | SubAbility$ DBPump
|
||||
SVar:DBPump:DB$ Pump | Defined$ Self | KW$ Trample | ConditionDefined$ Remembered | ConditionPresent$ Forest.Snow | ConditionCompare$ EQ1 | SubAbility$ DBSacMe
|
||||
SVar:DBSacMe:DB$ Sacrifice | Defined$ Self | ConditionDefined$ Remembered | ConditionPresent$ Forest | ConditionCompare$ EQ0 | SubAbility$ DBRageDamage
|
||||
SVar:DBSacMe:DB$ Sacrifice | ConditionDefined$ Remembered | ConditionPresent$ Forest | ConditionCompare$ EQ0 | SubAbility$ DBRageDamage
|
||||
SVar:DBRageDamage:DB$ DealDamage | Defined$ You | NumDmg$ 7 | ConditionDefined$ Remembered | ConditionPresent$ Forest | ConditionCompare$ EQ0 | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
A:AB$ DealDamage | Cost$ T | ValidTgts$ Creature.Other | TgtPrompt$ Select another target creature | NumDmg$ X | SubAbility$ DamageThis | SpellDescription$ CARDNAME deals damage equal to its power to another target creature. That creature deals damage equal to its power to CARDNAME.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:no cost
|
||||
Types:Land Gate
|
||||
K:CARDNAME enters the battlefield tapped.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you pay {1}.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self | UnlessCost$ 1 | UnlessPayer$ You
|
||||
SVar:TrigSac:DB$ Sacrifice | UnlessCost$ 1 | UnlessPayer$ You
|
||||
SVar:NeedsToPlay:Land.untapped+YouCtrl
|
||||
A:AB$ Mana | Cost$ T | Produced$ Any | SpellDescription$ Add one mana of any color.
|
||||
Oracle:Gateway Plaza enters the battlefield tapped.\nWhen Gateway Plaza enters the battlefield, sacrifice it unless you pay {1}.\n{T}: Add one mana of any color.
|
||||
|
||||
@@ -7,7 +7,7 @@ T:Mode$ AttackerBlockedByCreature | ValidCard$ Card.Self | ValidBlocker$ Creatur
|
||||
SVar:TrigPumpShark:DB$ Pump | Defined$ Self | NumAtt$ 2 | NumDef$ 0 | KW$ Trample
|
||||
S:Mode$ CantAttack | ValidCard$ Card.Self | UnlessDefenderControls$ Island | Description$ CARDNAME can't attack unless defending player controls an Island.
|
||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Island.YouCtrl | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ When you control no Islands, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:NeedsToPlay:Island.YouCtrl
|
||||
DeckHas:Keyword$Trample
|
||||
Oracle:Giant Shark can't attack unless defending player controls an Island.\nWhenever Giant Shark blocks or becomes blocked by a creature that has been dealt damage this turn, Giant Shark gets +2/+0 and gains trample until end of turn.\nWhen you control no Islands, sacrifice Giant Shark.
|
||||
|
||||
@@ -5,6 +5,6 @@ PT:3/3
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExchange | TriggerDescription$ When CARDNAME enters the battlefield, exchange control of CARDNAME and up to one target creature an opponent controls. If you don't or can't make an exchange, sacrifice CARDNAME. This ability still resolves if its target becomes illegal.
|
||||
SVar:TrigExchange:DB$ ExchangeControl | Defined$ Self | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | TargetMin$ 0 | TargetMax$ 1 | CantFizzle$ True | SubAbility$ DBSacSelf
|
||||
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self | ConditionDefined$ Self | ConditionPresent$ Card.YouCtrl
|
||||
SVar:DBSacSelf:DB$ Sacrifice | ConditionDefined$ Self | ConditionPresent$ Card.YouCtrl
|
||||
SVar:NeedsToPlay:Creature.OppCtrl
|
||||
Oracle:Flying\nWhen Gilded Drake enters the battlefield, exchange control of Gilded Drake and up to one target creature an opponent controls. If you don't or can't make an exchange, sacrifice Gilded Drake. This ability still resolves if its target becomes illegal.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:no cost
|
||||
Types:Land
|
||||
A:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 1 | SpellDescription$ Add one mana of any color.
|
||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | IsPresent$ Artifact.YouCtrl | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ At the beginning of the end step, if you control no artifacts, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
SVar:NeedsToPlay:Artifact.YouCtrl
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:At the beginning of the end step, if you control no artifacts, sacrifice Glimmervoid.\n{T}: Add one mana of any color.
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Creature Bird
|
||||
PT:2/2
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBSac | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you return an artifact you control to its owner's hand.
|
||||
SVar:DBSac:DB$ Sacrifice | Defined$ Self | UnlessCost$ Return<1/Artifact> | UnlessPayer$ You
|
||||
SVar:DBSac:DB$ Sacrifice | UnlessCost$ Return<1/Artifact> | UnlessPayer$ You
|
||||
SVar:NeedsToPlay:Artifact.YouCtrl
|
||||
Oracle:Flying\nWhen Glint Hawk enters the battlefield, sacrifice it unless you return an artifact you control to its owner's hand.
|
||||
|
||||
@@ -5,6 +5,6 @@ PT:1/2
|
||||
A:AB$ FlipACoin | Cost$ R T | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | WinSubAbility$ DBDestroy | LoseSubAbility$ DBSacSelf | SpellDescription$ Flip a coin. If you win the flip, destroy target artifact and untap Goblin Archaeologist. If you lose the flip, sacrifice Goblin Archaeologist.
|
||||
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted | SubAbility$ DBUntapSelf
|
||||
SVar:DBUntapSelf:DB$ Untap | Defined$ Self
|
||||
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self
|
||||
SVar:DBSacSelf:DB$ Sacrifice
|
||||
AI:RemoveDeck:All
|
||||
Oracle:{R}, {T}: Flip a coin. If you win the flip, destroy target artifact and untap Goblin Archaeologist. If you lose the flip, sacrifice Goblin Archaeologist.
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Goblin Boom Keg
|
||||
ManaCost:4
|
||||
Types:Artifact
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of your upkeep, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | Defined$ Self
|
||||
SVar:TrigSac:DB$ Sacrifice
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDealDamage | TriggerDescription$ When CARDNAME is put into a graveyard from the battlefield, it deals 3 damage to any target.
|
||||
SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 3
|
||||
SVar:SacMe:4
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user