Merge branch 'Card-Forge:master' into adventureupdatee

This commit is contained in:
Simisays
2023-03-22 15:04:23 +01:00
committed by GitHub
132 changed files with 1534 additions and 851 deletions

View File

@@ -163,6 +163,7 @@ public enum SpellApiToAi {
.put(ApiType.Sacrifice, SacrificeAi.class) .put(ApiType.Sacrifice, SacrificeAi.class)
.put(ApiType.SacrificeAll, SacrificeAllAi.class) .put(ApiType.SacrificeAll, SacrificeAllAi.class)
.put(ApiType.Scry, ScryAi.class) .put(ApiType.Scry, ScryAi.class)
.put(ApiType.Seek, AlwaysPlayAi.class)
.put(ApiType.SetInMotion, AlwaysPlayAi.class) .put(ApiType.SetInMotion, AlwaysPlayAi.class)
.put(ApiType.SetLife, LifeSetAi.class) .put(ApiType.SetLife, LifeSetAi.class)
.put(ApiType.SetState, SetStateAi.class) .put(ApiType.SetState, SetStateAi.class)

View File

@@ -26,7 +26,7 @@ public class CharmAi extends SpellAbilityAi {
@Override @Override
protected boolean checkApiLogic(Player ai, SpellAbility sa) { protected boolean checkApiLogic(Player ai, SpellAbility sa) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa); List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa, false);
final int num; final int num;
final int min; final int min;

View File

@@ -380,6 +380,8 @@ public final class GameActionUtil {
return costs; return costs;
} }
sa.clearPipsToReduce();
Card source = sa.getHostCard(); Card source = sa.getHostCard();
final Game game = source.getGame(); final Game game = source.getGame();
boolean lkicheck = false; boolean lkicheck = false;

View File

@@ -166,7 +166,14 @@ public class GameEntityCounterTable extends ForwardingTable<Optional<Player>, Ga
for (Map.Entry<Optional<Player>, Map<CounterType, Integer>> e : values.entrySet()) { for (Map.Entry<Optional<Player>, Map<CounterType, Integer>> e : values.entrySet()) {
boolean remember = cause != null && cause.hasParam("RememberPut"); boolean remember = cause != null && cause.hasParam("RememberPut");
for (Map.Entry<CounterType, Integer> ec : e.getValue().entrySet()) { for (Map.Entry<CounterType, Integer> ec : e.getValue().entrySet()) {
gm.getKey().addCounterInternal(ec.getKey(), ec.getValue(), e.getKey().orNull(), true, result, runParams); Integer value = ec.getValue();
if (value == null) {
continue;
}
if (cause != null && cause.hasParam("MaxFromEffect")) {
value = Math.min(value, Integer.parseInt(cause.getParam("MaxFromEffect")) - gm.getKey().getCounters(ec.getKey()));
}
gm.getKey().addCounterInternal(ec.getKey(), value, e.getKey().orNull(), true, result, runParams);
if (remember && ec.getValue() >= 1) { if (remember && ec.getValue() >= 1) {
cause.getHostCard().addRemembered(gm.getKey()); cause.getHostCard().addRemembered(gm.getKey());
} }

View File

@@ -166,7 +166,13 @@ public class AbilityUtils {
if (defined.startsWith("TopThird")) { if (defined.startsWith("TopThird")) {
int third = defined.contains("RoundedDown") ? (int) Math.floor(libSize / 3.0) int third = defined.contains("RoundedDown") ? (int) Math.floor(libSize / 3.0)
: (int) Math.ceil(libSize / 3.0); : (int) Math.ceil(libSize / 3.0);
for (int i=0; i<third; i++) { for (int i = 0; i < third; i++) {
cards.add(lib.get(i));
}
} else if (defined.startsWith("Top_")) {
String[] parts = defined.split("_");
int amt = AbilityUtils.calculateAmount(hostCard, parts[1], sa);
for (int i = 0; i < amt; i++) {
cards.add(lib.get(i)); cards.add(lib.get(i));
} }
} else { } else {

View File

@@ -162,6 +162,7 @@ public enum ApiType {
Sacrifice (SacrificeEffect.class), Sacrifice (SacrificeEffect.class),
SacrificeAll (SacrificeAllEffect.class), SacrificeAll (SacrificeAllEffect.class),
Scry (ScryEffect.class), Scry (ScryEffect.class),
Seek (SeekEffect.class),
SetInMotion (SetInMotionEffect.class), SetInMotion (SetInMotionEffect.class),
SetLife (LifeSetEffect.class), SetLife (LifeSetEffect.class),
SetState (SetStateEffect.class), SetState (SetStateEffect.class),

View File

@@ -20,7 +20,7 @@ import forge.util.collect.FCollection;
public class CharmEffect extends SpellAbilityEffect { public class CharmEffect extends SpellAbilityEffect {
public static List<AbilitySub> makePossibleOptions(final SpellAbility sa) { public static List<AbilitySub> makePossibleOptions(final SpellAbility sa, boolean forDesc) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
List<String> restriction = null; List<String> restriction = null;
@@ -29,16 +29,19 @@ public class CharmEffect extends SpellAbilityEffect {
} }
List<AbilitySub> choices = Lists.newArrayList(sa.getAdditionalAbilityList("Choices")); List<AbilitySub> choices = Lists.newArrayList(sa.getAdditionalAbilityList("Choices"));
List<AbilitySub> toRemove = Lists.newArrayList();
for (AbilitySub ch : choices) { if (!forDesc) {
// 603.3c If one of the modes would be illegal, that mode can't be chosen. List<AbilitySub> toRemove = Lists.newArrayList();
if ((ch.usesTargeting() && ch.isTrigger() && ch.getMinTargets() > 0 && for (AbilitySub ch : choices) {
ch.getTargetRestrictions().getNumCandidates(ch, true) == 0) || // 603.3c If one of the modes would be illegal, that mode can't be chosen.
(restriction != null && restriction.contains(ch.getDescription()))) { if ((ch.usesTargeting() && ch.isTrigger() && ch.getMinTargets() > 0 &&
toRemove.add(ch); ch.getTargetRestrictions().getNumCandidates(ch, true) == 0) ||
(restriction != null && restriction.contains(ch.getDescription()))) {
toRemove.add(ch);
}
} }
choices.removeAll(toRemove);
} }
choices.removeAll(toRemove);
int indx = 0; int indx = 0;
// set CharmOrder // set CharmOrder
@@ -52,7 +55,7 @@ public class CharmEffect extends SpellAbilityEffect {
public static String makeFormatedDescription(SpellAbility sa) { public static String makeFormatedDescription(SpellAbility sa) {
Card source = sa.getHostCard(); Card source = sa.getHostCard();
List<AbilitySub> list = CharmEffect.makePossibleOptions(sa); List<AbilitySub> list = CharmEffect.makePossibleOptions(sa, true);
final int num; final int num;
boolean additionalDesc = sa.hasParam("AdditionalDescription"); boolean additionalDesc = sa.hasParam("AdditionalDescription");
boolean optional = sa.hasParam("Optional"); boolean optional = sa.hasParam("Optional");
@@ -166,7 +169,7 @@ public class CharmEffect extends SpellAbilityEffect {
//this resets all previous choices //this resets all previous choices
sa.setSubAbility(null); sa.setSubAbility(null);
List<AbilitySub> choices = makePossibleOptions(sa); List<AbilitySub> choices = makePossibleOptions(sa, false);
// Entwine does use all Choices // Entwine does use all Choices
if (sa.isEntwine()) { if (sa.isEntwine()) {

View File

@@ -258,7 +258,7 @@ public class CopyPermanentEffect extends TokenEffectBase {
game.updateCombatForView(); game.updateCombatForView();
game.fireEvent(new GameEventCombatChanged()); game.fireEvent(new GameEventCombatChanged());
} }
} // end resolve }
public static Card getProtoType(final SpellAbility sa, final Card original, final Player newOwner) { public static Card getProtoType(final SpellAbility sa, final Card original, final Player newOwner) {
final Card host = sa.getHostCard(); final Card host = sa.getHostCard();

View File

@@ -0,0 +1,99 @@
package forge.game.ability.effects;
import com.google.common.collect.Lists;
import forge.game.Game;
import forge.game.ability.AbilityKey;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.*;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class SeekEffect extends SpellAbilityEffect {
/* (non-Javadoc)
* @see forge.game.ability.SpellAbilityEffect#getStackDescription(forge.game.spellability.SpellAbility)
*/
@Override
protected String getStackDescription(SpellAbility sa) {
return sa.getDescription();
}
@Override
public void resolve(SpellAbility sa) {
final Card source = sa.getHostCard();
final Game game = source.getGame();
List<String> seekTypes = Lists.newArrayList();
if (sa.hasParam("Types")) {
seekTypes.addAll(Arrays.asList(sa.getParam("Types").split(",")));
} else {
seekTypes.add(sa.getParamOrDefault("Type", "Card"));
}
int seekNum = AbilityUtils.calculateAmount(source, sa.getParamOrDefault("Num", "1"), sa);
if (seekNum <= 0) {
return;
}
final CardZoneTable triggerList = new CardZoneTable();
CardCollectionView lastStateBattlefield = game.copyLastStateBattlefield();
CardCollectionView lastStateGraveyard = game.copyLastStateGraveyard();
for (Player seeker : getTargetPlayers(sa)) {
if (!seeker.isInGame()) {
continue;
}
CardCollection soughtCards = new CardCollection();
for (String seekType : seekTypes) {
CardCollection pool;
if (sa.hasParam("DefinedCards")) {
pool = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa);
} else {
pool = new CardCollection(seeker.getCardsIn(ZoneType.Library));
}
if (!seekType.equals("Card")) {
pool = CardLists.getValidCards(pool, seekType, source.getController(), source, sa);
}
if (pool.isEmpty()) {
continue; // can't find if nothing to seek
}
for (final Card c : Aggregates.random(pool, seekNum)) {
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
moveParams.put(AbilityKey.LastStateBattlefield, lastStateBattlefield);
moveParams.put(AbilityKey.LastStateGraveyard, lastStateGraveyard);
Card movedCard = game.getAction().moveToHand(c, sa, moveParams);
ZoneType resultZone = movedCard.getZone().getZoneType();
if (!resultZone.equals(ZoneType.Library)) { // as long as it moved we add to triggerList
triggerList.put(ZoneType.Library, movedCard.getZone().getZoneType(), movedCard);
}
if (resultZone.equals(ZoneType.Hand)) { // if it went to hand as planned, consider it "sought"
soughtCards.add(movedCard);
}
}
}
if (!soughtCards.isEmpty()) {
if (sa.hasParam("RememberFound")) {
source.addRemembered(soughtCards);
}
if (sa.hasParam("ImprintFound")) {
source.addImprintedCards(soughtCards);
}
game.getTriggerHandler().runTrigger(TriggerType.SeekAll, AbilityKey.mapFromPlayer(seeker), false);
}
}
triggerList.triggerChangesZoneAll(game, sa);
}
}

View File

@@ -72,7 +72,7 @@ public class UntapEffect extends SpellAbilityEffect {
* whether the untapping is mandatory. * whether the untapping is mandatory.
*/ */
private static void untapChoose(final SpellAbility sa, final boolean mandatory) { private static void untapChoose(final SpellAbility sa, final boolean mandatory) {
final int num = Integer.parseInt(sa.getParam("Amount")); final int num = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("Amount"), sa);
final String valid = sa.getParam("UntapType"); final String valid = sa.getParam("UntapType");
for (final Player p : AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Defined"), sa)) { for (final Player p : AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Defined"), sa)) {

View File

@@ -526,7 +526,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
if (state == CardStateName.FaceDown) { if (state == CardStateName.FaceDown) {
view.updateHiddenId(game.nextHiddenCardId()); view.updateHiddenId(game.nextHiddenCardId());
} }
game.fireEvent(new GameEventCardStatsChanged(this)); //ensure stats updated for new characteristics game.fireEvent(new GameEventCardStatsChanged(this, true)); //ensure stats updated for new characteristics
} }
} }
return true; return true;

View File

@@ -22,7 +22,6 @@ import java.util.Set;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import forge.card.CardType;
import forge.game.ability.AbilityKey; import forge.game.ability.AbilityKey;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardCollection; import forge.game.card.CardCollection;
@@ -106,11 +105,7 @@ public class CostDiscard extends CostPartWithList {
desc.append("card"); desc.append("card");
} }
else { else {
if (this.getTypeDescription() == null) { desc.append(this.getDescriptiveType());
desc.append(CardType.CoreType.isValidEnum(this.getType()) ? this.getType().toLowerCase() : this.getType());
} else {
desc.append(this.getTypeDescription());
}
desc.append(" card"); desc.append(" card");
} }

View File

@@ -17,7 +17,6 @@
*/ */
package forge.game.cost; package forge.game.cost;
import forge.card.CardType;
import forge.game.Game; import forge.game.Game;
import forge.game.ability.SpellAbilityEffect; import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card; import forge.game.card.Card;
@@ -85,10 +84,7 @@ public class CostExile extends CostPartWithList {
@Override @Override
public final String toString() { public final String toString() {
final Integer i = this.convertAmount(); final Integer i = this.convertAmount();
String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription(); String desc = this.getDescriptiveType();
if (CardType.CoreType.isValidEnum(desc)) {
desc = desc.toLowerCase();
}
String origin = this.from.name().toLowerCase(); String origin = this.from.name().toLowerCase();
if (this.payCostFromSource()) { if (this.payCostFromSource()) {

View File

@@ -15,8 +15,14 @@ import forge.game.card.Card;
public class GameEventCardStatsChanged extends GameEvent { public class GameEventCardStatsChanged extends GameEvent {
public final Collection<Card> cards; public final Collection<Card> cards;
public boolean transform = false;
public GameEventCardStatsChanged(Card affected) { public GameEventCardStatsChanged(Card affected) {
this(affected, false);
}
public GameEventCardStatsChanged(Card affected, boolean isTransform) {
cards = Arrays.asList(affected); cards = Arrays.asList(affected);
transform = isTransform;
} }
public GameEventCardStatsChanged(Collection<Card> affected) { public GameEventCardStatsChanged(Collection<Card> affected) {

View File

@@ -404,10 +404,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
} }
public boolean canPlayWithOptionalCost(OptionalCostValue opt) { public boolean canPlayWithOptionalCost(OptionalCostValue opt) {
SpellAbility saOpt = GameActionUtil.addOptionalCosts(this, Lists.newArrayList(opt)); return GameActionUtil.addOptionalCosts(this, Lists.newArrayList(opt)).canPlay();
boolean result = saOpt.canPlay();
saOpt.clearPipsToReduce();
return result;
} }
public boolean isPossible() { public boolean isPossible() {

View File

@@ -0,0 +1,36 @@
package forge.game.trigger;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import forge.util.Localizer;
import java.util.Map;
public class TriggerSeekAll extends Trigger {
public TriggerSeekAll(Map<String, String> params, Card host, boolean intrinsic) {
super(params, host, intrinsic);
}
@Override
public boolean performTest(Map<AbilityKey, Object> runParams) {
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Player))) {
return false;
}
return true;
}
@Override
public void setTriggeringObjects(SpellAbility sa, Map<AbilityKey, Object> runParams) {
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Player);
}
@Override
public String getImportantStackObjects(SpellAbility sa) {
StringBuilder sb = new StringBuilder();
sb.append(Localizer.getInstance().getMessage("lblPlayer")).append(": ");
sb.append(sa.getTriggeringObject(AbilityKey.Player));
return sb.toString();
}
}

View File

@@ -104,6 +104,7 @@ public enum TriggerType {
Sacrificed(TriggerSacrificed.class), Sacrificed(TriggerSacrificed.class),
Scry(TriggerScry.class), Scry(TriggerScry.class),
SearchedLibrary(TriggerSearchedLibrary.class), SearchedLibrary(TriggerSearchedLibrary.class),
SeekAll(TriggerSeekAll.class),
SetInMotion(TriggerSetInMotion.class), SetInMotion(TriggerSetInMotion.class),
Shuffled(TriggerShuffled.class), Shuffled(TriggerShuffled.class),
Specializes(TriggerSpecializes.class), Specializes(TriggerSpecializes.class),

View File

@@ -17,6 +17,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Clipboard; import com.badlogic.gdx.utils.Clipboard;
import forge.adventure.scene.*; import forge.adventure.scene.*;
import forge.adventure.stage.GameHUD;
import forge.adventure.util.Config; import forge.adventure.util.Config;
import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSave;
import forge.animation.ForgeAnimation; import forge.animation.ForgeAnimation;
@@ -340,6 +341,7 @@ public class Forge implements ApplicationListener {
try { try {
Config.instance().loadResources(); Config.instance().loadResources();
SpellSmithScene.instance().loadEditions(); SpellSmithScene.instance().loadEditions();
GameHUD.getInstance().stopAudio();
if (startScene) { if (startScene) {
MusicPlaylist.invalidateMusicPlaylist(); MusicPlaylist.invalidateMusicPlaylist();
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS);

View File

@@ -18,6 +18,8 @@ import forge.deck.DeckProxy;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.sound.SoundEffectType;
import forge.sound.SoundSystem;
import forge.util.ItemPool; import forge.util.ItemPool;
import java.io.Serializable; import java.io.Serializable;
@@ -516,6 +518,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public void takeGold(int price) { public void takeGold(int price) {
gold -= price; gold -= price;
onGoldChangeList.emit(); onGoldChangeList.emit();
//play sfx
SoundSystem.instance.play(SoundEffectType.CoinsDrop, false);
} }
public void addShards(int number) { public void addShards(int number) {
takeShards(-number); takeShards(-number);
@@ -523,6 +527,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public void takeShards(int number) { public void takeShards(int number) {
shards -= number; shards -= number;
onShardsChangeList.emit(); onShardsChangeList.emit();
//play sfx
SoundSystem.instance.play(SoundEffectType.TakeShard, false);
} }
public void setShards(int number) { public void setShards(int number) {

View File

@@ -13,6 +13,7 @@ import forge.adventure.data.EffectData;
import forge.adventure.data.EnemyData; import forge.adventure.data.EnemyData;
import forge.adventure.data.ItemData; import forge.adventure.data.ItemData;
import forge.adventure.player.AdventurePlayer; import forge.adventure.player.AdventurePlayer;
import forge.adventure.stage.GameHUD;
import forge.adventure.stage.IAfterMatch; import forge.adventure.stage.IAfterMatch;
import forge.adventure.util.Config; import forge.adventure.util.Config;
import forge.adventure.util.Current; import forge.adventure.util.Current;
@@ -67,6 +68,8 @@ public class DuelScene extends ForgeScene {
Deck playerDeck; Deck playerDeck;
boolean chaosBattle = false; boolean chaosBattle = false;
boolean callbackExit = false; boolean callbackExit = false;
boolean arenaBattleChallenge = false;
boolean isArena = false;
private LoadingOverlay matchOverlay; private LoadingOverlay matchOverlay;
List<IPaperCard> playerExtras = new ArrayList<>(); List<IPaperCard> playerExtras = new ArrayList<>();
List<IPaperCard> AIExtras = new ArrayList<>(); List<IPaperCard> AIExtras = new ArrayList<>();
@@ -138,7 +141,13 @@ public class DuelScene extends ForgeScene {
void afterGameEnd(String enemyName, boolean winner, boolean showOverlay, boolean alternate) { void afterGameEnd(String enemyName, boolean winner, boolean showOverlay, boolean alternate) {
Runnable runnable = () -> Gdx.app.postRunnable(()-> { Runnable runnable = () -> Gdx.app.postRunnable(()-> {
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); //start background music if (GameScene.instance().isNotInWorldMap()) {
SoundSystem.instance.pause();
GameHUD.getInstance().playAudio();
} else {
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS);
SoundSystem.instance.resume();
}
dungeonEffect = null; dungeonEffect = null;
callbackExit = false; callbackExit = false;
Forge.clearTransitionScreen(); Forge.clearTransitionScreen();
@@ -192,6 +201,7 @@ public class DuelScene extends ForgeScene {
@Override @Override
public void enter() { public void enter() {
GameHUD.getInstance().unloadAudio();
Set<GameType> appliedVariants = new HashSet<>(); Set<GameType> appliedVariants = new HashSet<>();
appliedVariants.add(GameType.Constructed); appliedVariants.add(GameType.Constructed);
AdventurePlayer advPlayer = Current.player(); AdventurePlayer advPlayer = Current.player();
@@ -267,6 +277,7 @@ public class DuelScene extends ForgeScene {
addEffects(humanPlayer, playerEffects); addEffects(humanPlayer, playerEffects);
currentEnemy = enemy.getData(); currentEnemy = enemy.getData();
boolean bossBattle = currentEnemy.boss;
for (int i = 0; i < 8 && currentEnemy != null; i++) { for (int i = 0; i < 8 && currentEnemy != null; i++) {
Deck deck = null; Deck deck = null;
@@ -278,6 +289,8 @@ public class DuelScene extends ForgeScene {
} }
this.AIExtras = aiCards; this.AIExtras = aiCards;
deck = deckProxy.getDeck(); deck = deckProxy.getDeck();
} else if (this.arenaBattleChallenge) {
deck = Aggregates.random(DeckProxy.getAllGeneticAIDecks()).getDeck();
} else { } else {
deck = currentEnemy.copyPlayerDeck ? this.playerDeck : currentEnemy.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().getDifficulty().name.equalsIgnoreCase("Hard")); deck = currentEnemy.copyPlayerDeck ? this.playerDeck : currentEnemy.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().getDifficulty().name.equalsIgnoreCase("Hard"));
} }
@@ -332,7 +345,7 @@ public class DuelScene extends ForgeScene {
rules.setWarnAboutAICards(false); rules.setWarnAboutAICards(false);
hostedMatch.setEndGameHook(() -> DuelScene.this.GameEnd()); hostedMatch.setEndGameHook(() -> DuelScene.this.GameEnd());
hostedMatch.startMatch(rules, appliedVariants, players, guiMap); hostedMatch.startMatch(rules, appliedVariants, players, guiMap, bossBattle ? MusicPlaylist.BOSS : MusicPlaylist.MATCH);
MatchController.instance.setGameView(hostedMatch.getGameView()); MatchController.instance.setGameView(hostedMatch.getGameView());
boolean showMessages = enemy.getData().copyPlayerDeck && Current.player().isUsingCustomDeck(); boolean showMessages = enemy.getData().copyPlayerDeck && Current.player().isUsingCustomDeck();
if (chaosBattle || showMessages) { if (chaosBattle || showMessages) {
@@ -376,8 +389,15 @@ public class DuelScene extends ForgeScene {
} }
public void initDuels(PlayerSprite playerSprite, EnemySprite enemySprite) { public void initDuels(PlayerSprite playerSprite, EnemySprite enemySprite) {
initDuels(playerSprite, enemySprite, false);
}
public void initDuels(PlayerSprite playerSprite, EnemySprite enemySprite, boolean isArena) {
this.player = playerSprite; this.player = playerSprite;
this.enemy = enemySprite; this.enemy = enemySprite;
this.isArena = isArena;
this.arenaBattleChallenge = isArena
&& (Current.player().getDifficulty().name.equalsIgnoreCase("Hard")
|| Current.player().getDifficulty().name.equalsIgnoreCase("Insane"));
this.playerDeck = (Deck) Current.player().getSelectedDeck().copyTo("PlayerDeckCopy"); this.playerDeck = (Deck) Current.player().getSelectedDeck().copyTo("PlayerDeckCopy");
this.chaosBattle = this.enemy.getData().copyPlayerDeck && Current.player().isFantasyMode(); this.chaosBattle = this.enemy.getData().copyPlayerDeck && Current.player().isFantasyMode();
this.AIExtras.clear(); this.AIExtras.clear();

View File

@@ -64,14 +64,13 @@ public class GameScene extends HudScene {
} else { } else {
World world = Current.world(); World world = Current.world();
//this gets the name of the layer... this shoud be based on boundaries... //this gets the name of the layer... this shoud be based on boundaries...
int currentBiome = World.highestBiome(world.getBiome((int) stage.getPlayerSprite().getX() / world.getTileSize(), (int) stage.getPlayerSprite().getY() / world.getTileSize())); int currentBiome = World.highestBiome(world.getBiomeMapXY((int) stage.getPlayerSprite().getX() / world.getTileSize(), (int) stage.getPlayerSprite().getY() / world.getTileSize()));
List<BiomeData> biomeData = world.getData().GetBiomes(); List<BiomeData> biomeData = world.getData().GetBiomes();
if (biomeData.size() <= currentBiome) //on roads.... if (biomeData.size() <= currentBiome) //shouldn't be the case but default to waste
if (skipRoads) { if (skipRoads) {
location = forHeader ? "Waste Map" : "waste"; location = forHeader ? "Waste Map" : "waste";
} else { } else {
//current workaround to get the POI town name location = "";
location = WorldStage.getInstance().getBoundary();
} }
else { else {
BiomeData data = biomeData.get(currentBiome); BiomeData data = biomeData.get(currentBiome);

View File

@@ -24,6 +24,7 @@ import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel; import forge.model.FModel;
import forge.player.GamePlayerUtil; import forge.player.GamePlayerUtil;
import forge.screens.TransitionScreen; import forge.screens.TransitionScreen;
import forge.sound.SoundSystem;
import forge.util.NameGenerator; import forge.util.NameGenerator;
import java.util.Random; import java.util.Random;
@@ -190,7 +191,7 @@ public class NewGameScene extends UIScene {
} }
Runnable runnable = () -> { Runnable runnable = () -> {
started = false; started = false;
FModel.getPreferences().setPref(ForgePreferences.FPref.UI_ENABLE_MUSIC, false); //FModel.getPreferences().setPref(ForgePreferences.FPref.UI_ENABLE_MUSIC, false);
WorldSave.generateNewWorld(selectedName.getText(), WorldSave.generateNewWorld(selectedName.getText(),
gender.getCurrentIndex() == 0, gender.getCurrentIndex() == 0,
race.getCurrentIndex(), race.getCurrentIndex(),
@@ -200,6 +201,7 @@ public class NewGameScene extends UIScene {
modes.get(mode.getCurrentIndex()), colorId.getCurrentIndex(), modes.get(mode.getCurrentIndex()), colorId.getCurrentIndex(),
editionIds[starterEdition.getCurrentIndex()], 0);//maybe replace with enum editionIds[starterEdition.getCurrentIndex()], 0);//maybe replace with enum
GamePlayerUtil.getGuiPlayer().setName(selectedName.getText()); GamePlayerUtil.getGuiPlayer().setName(selectedName.getText());
SoundSystem.instance.changeBackgroundTrack();
Forge.switchScene(GameScene.instance()); Forge.switchScene(GameScene.instance());
}; };
Forge.setTransitionScreen(new TransitionScreen(runnable, null, false, true, "Generating World...")); Forge.setTransitionScreen(new TransitionScreen(runnable, null, false, true, "Generating World..."));

View File

@@ -146,13 +146,15 @@ public class RewardScene extends UIScene {
showLootOrDone(); showLootOrDone();
return true; return true;
} }
switch (type) { if (type != null) {
case Shop: switch (type) {
doneButton.setText(Forge.getLocalizer().getMessage("lblLeave")); case Shop:
break; doneButton.setText(Forge.getLocalizer().getMessage("lblLeave"));
case Loot: break;
doneButton.setText(Forge.getLocalizer().getMessage("lblDone")); case Loot:
break; doneButton.setText(Forge.getLocalizer().getMessage("lblDone"));
break;
}
} }
shown = false; shown = false;
clearGenerated(); clearGenerated();

View File

@@ -21,6 +21,7 @@ import forge.adventure.util.Current;
import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSave;
import forge.adventure.world.WorldSaveHeader; import forge.adventure.world.WorldSaveHeader;
import forge.screens.TransitionScreen; import forge.screens.TransitionScreen;
import forge.sound.SoundSystem;
import forge.util.TextUtil; import forge.util.TextUtil;
import java.io.File; import java.io.File;
@@ -217,6 +218,7 @@ public class SaveLoadScene extends UIScene {
try { try {
Forge.setTransitionScreen(new TransitionScreen(() -> { Forge.setTransitionScreen(new TransitionScreen(() -> {
if (WorldSave.load(currentSlot)) { if (WorldSave.load(currentSlot)) {
SoundSystem.instance.changeBackgroundTrack();
Forge.switchScene(GameScene.instance()); Forge.switchScene(GameScene.instance());
} else { } else {
Forge.clearTransitionScreen(); Forge.clearTransitionScreen();
@@ -236,6 +238,7 @@ public class SaveLoadScene extends UIScene {
Current.player().updateDifficulty(Config.instance().getConfigData().difficulties[difficulty.getSelectedIndex()]); Current.player().updateDifficulty(Config.instance().getConfigData().difficulties[difficulty.getSelectedIndex()]);
Current.player().setWorldPosY((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosY * WorldSave.getCurrentSave().getWorld().getData().height * WorldSave.getCurrentSave().getWorld().getTileSize())); Current.player().setWorldPosY((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosY * WorldSave.getCurrentSave().getWorld().getData().height * WorldSave.getCurrentSave().getWorld().getTileSize()));
Current.player().setWorldPosX((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosX * WorldSave.getCurrentSave().getWorld().getData().width * WorldSave.getCurrentSave().getWorld().getTileSize())); Current.player().setWorldPosX((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosX * WorldSave.getCurrentSave().getWorld().getData().width * WorldSave.getCurrentSave().getWorld().getTileSize()));
SoundSystem.instance.changeBackgroundTrack();
Forge.switchScene(GameScene.instance()); Forge.switchScene(GameScene.instance());
} else { } else {
Forge.clearTransitionScreen(); Forge.clearTransitionScreen();

View File

@@ -10,6 +10,7 @@ import forge.adventure.util.Config;
import forge.adventure.util.Controls; import forge.adventure.util.Controls;
import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSave;
import forge.screens.TransitionScreen; import forge.screens.TransitionScreen;
import forge.sound.SoundSystem;
/** /**
* First scene after the splash screen * First scene after the splash screen
@@ -20,7 +21,6 @@ public class StartScene extends UIScene {
TextraButton saveButton, resumeButton, continueButton; TextraButton saveButton, resumeButton, continueButton;
public StartScene() { public StartScene() {
super(Forge.isLandscapeMode() ? "ui/start_menu.json" : "ui/start_menu_portrait.json"); super(Forge.isLandscapeMode() ? "ui/start_menu.json" : "ui/start_menu_portrait.json");
ui.onButtonPress("Start", StartScene.this::NewGame); ui.onButtonPress("Start", StartScene.this::NewGame);
@@ -31,7 +31,7 @@ public class StartScene extends UIScene {
ui.onButtonPress("Continue", StartScene.this::Continue); ui.onButtonPress("Continue", StartScene.this::Continue);
ui.onButtonPress("Settings", StartScene.this::settings); ui.onButtonPress("Settings", StartScene.this::settings);
ui.onButtonPress("Exit", StartScene.this::Exit); ui.onButtonPress("Exit", StartScene.this::Exit);
ui.onButtonPress("Switch", Forge::switchToClassic); ui.onButtonPress("Switch", StartScene.this::switchToClassic);
saveButton = ui.findActor("Save"); saveButton = ui.findActor("Save");
@@ -43,8 +43,8 @@ public class StartScene extends UIScene {
} }
public static StartScene instance() { public static StartScene instance() {
if(object==null) if (object == null)
object=new StartScene(); object = new StartScene();
return object; return object;
} }
@@ -81,6 +81,7 @@ public class StartScene extends UIScene {
try { try {
Forge.setTransitionScreen(new TransitionScreen(() -> { Forge.setTransitionScreen(new TransitionScreen(() -> {
if (WorldSave.load(WorldSave.filenameToSlot(lastActiveSave))) { if (WorldSave.load(WorldSave.filenameToSlot(lastActiveSave))) {
SoundSystem.instance.changeBackgroundTrack();
Forge.switchScene(GameScene.instance()); Forge.switchScene(GameScene.instance());
} else { } else {
Forge.clearTransitionScreen(); Forge.clearTransitionScreen();
@@ -100,17 +101,22 @@ public class StartScene extends UIScene {
} }
public boolean Exit() { public boolean Exit() {
Dialog dialog = prepareDialog(Forge.getLocalizer().getMessage("lblExitForge"), ButtonOk|ButtonAbort,()->Forge.exit(true)); Dialog dialog = prepareDialog(Forge.getLocalizer().getMessage("lblExitForge"), ButtonOk | ButtonAbort, () -> Forge.exit(true));
dialog.text( Controls.newLabel(Forge.getLocalizer().getMessage("lblAreYouSureYouWishExitForge"))); dialog.text(Controls.newLabel(Forge.getLocalizer().getMessage("lblAreYouSureYouWishExitForge")));
showDialog(dialog); showDialog(dialog);
return true; return true;
} }
public void switchToClassic() {
GameHUD.getInstance().stopAudio();
Forge.switchToClassic();
}
@Override @Override
public void enter() { public void enter() {
boolean hasSaveButton = WorldSave.getCurrentSave().getWorld().getData() != null; boolean hasSaveButton = WorldSave.getCurrentSave().getWorld().getData() != null;
if (hasSaveButton) { if (hasSaveButton) {
TileMapScene scene = TileMapScene.instance(); TileMapScene scene = TileMapScene.instance();
hasSaveButton = !scene.currentMap().isInMap() || scene.isAutoHealLocation(); hasSaveButton = !scene.currentMap().isInMap() || scene.isAutoHealLocation();
} }
saveButton.setVisible(hasSaveButton); saveButton.setVisible(hasSaveButton);
@@ -130,10 +136,9 @@ public class StartScene extends UIScene {
} }
if(Forge.createNewAdventureMap) if (Forge.createNewAdventureMap) {
{
this.NewGame(); this.NewGame();
GameStage.maximumScrollDistance=4f; GameStage.maximumScrollDistance = 4f;
} }
super.enter(); super.enter();

View File

@@ -19,6 +19,8 @@ import com.github.tommyettinger.textra.TextraLabel;
import forge.Forge; import forge.Forge;
import forge.adventure.stage.GameHUD; import forge.adventure.stage.GameHUD;
import forge.adventure.util.*; import forge.adventure.util.*;
import forge.sound.SoundEffectType;
import forge.sound.SoundSystem;
/** /**
* Base class for an GUI scene where the elements are loaded from a json file * Base class for an GUI scene where the elements are loaded from a json file
@@ -27,86 +29,83 @@ public class UIScene extends Scene {
protected UIActor ui; protected UIActor ui;
public static class Selectable<T extends Actor> public static class Selectable<T extends Actor> {
{
public T actor; public T actor;
public float getY()
{ public float getY() {
Actor act=actor; Actor act = actor;
float y=0; float y = 0;
while (act!=null) while (act != null) {
{ y += act.getY();
y+=act.getY(); act = act.getParent();
act=act.getParent();
} }
return y; return y;
} }
public float getX()
{ public float getX() {
Actor act=actor; Actor act = actor;
float x=0; float x = 0;
while (act!=null) while (act != null) {
{ x += act.getX();
x+=act.getX(); act = act.getParent();
act=act.getParent();
} }
return x; return x;
} }
public Selectable(T newActor) { public Selectable(T newActor) {
actor=newActor; actor = newActor;
} }
public void onSelect(UIScene scene) public void onSelect(UIScene scene) {
{
} }
public void onDeSelect()
{ public void onDeSelect() {
//actor.fire(UIScene.eventExit()); //actor.fire(UIScene.eventExit());
} }
public void onPressDown(UIScene scene)
{ public void onPressDown(UIScene scene) {
if(actor instanceof TextField) if (actor instanceof TextField) {
{ scene.requestTextInput(((TextField) actor).getText(), text -> ((TextField) actor).setText(text));
scene.requestTextInput(((TextField) actor).getText(),text-> ((TextField) actor).setText(text));
} }
actor.fire(UIScene.eventTouchDown()); actor.fire(UIScene.eventTouchDown());
} }
public void onPressUp()
{ public void onPressUp() {
actor.fire(UIScene.eventTouchUp()); actor.fire(UIScene.eventTouchUp());
} }
public float yDiff(Selectable finalOne) { public float yDiff(Selectable finalOne) {
return Math.abs(finalOne.getY()-getY()); return Math.abs(finalOne.getY() - getY());
} }
public float xDiff(Selectable finalOne) { public float xDiff(Selectable finalOne) {
return Math.abs(finalOne.getX()-getX()); return Math.abs(finalOne.getX() - getX());
} }
} }
static final public int ButtonYes=0x1;
static final public int ButtonNo=0x2; static final public int ButtonYes = 0x1;
static final public int ButtonOk=0x4; static final public int ButtonNo = 0x2;
static final public int ButtonAbort=0x8; static final public int ButtonOk = 0x4;
static final public int ButtonAbort = 0x8;
public Dialog prepareDialog(String header, int buttons, Runnable onOkOrYes) { public Dialog prepareDialog(String header, int buttons, Runnable onOkOrYes) {
Dialog dialog =new Dialog(header, Controls.getSkin()) Dialog dialog = new Dialog(header, Controls.getSkin()) {
{ protected void result(Object object) {
protected void result(Object object) SoundSystem.instance.play(SoundEffectType.ButtonPress, false);
{ if (onOkOrYes != null && object != null && object.equals(true))
if(onOkOrYes!=null&&object!=null&&object.equals(true))
onOkOrYes.run(); onOkOrYes.run();
this.hide(); this.hide();
removeDialog(); removeDialog();
} }
}; };
if((buttons&ButtonYes)!=0) if ((buttons & ButtonYes) != 0)
dialog.button(Forge.getLocalizer().getMessage("lblYes"), true); dialog.button(Forge.getLocalizer().getMessage("lblYes"), true);
if((buttons&ButtonNo)!=0) if ((buttons & ButtonNo) != 0)
dialog.button(Forge.getLocalizer().getMessage("lblNo"), false); dialog.button(Forge.getLocalizer().getMessage("lblNo"), false);
if((buttons&ButtonOk)!=0) if ((buttons & ButtonOk) != 0)
dialog.button(Forge.getLocalizer().getMessage("lblOk"), true); dialog.button(Forge.getLocalizer().getMessage("lblOk"), true);
if((buttons&ButtonAbort)!=0) if ((buttons & ButtonAbort) != 0)
dialog.button(Forge.getLocalizer().getMessage("lblAbort"), false); dialog.button(Forge.getLocalizer().getMessage("lblAbort"), false);
dialog.setMovable(false); dialog.setMovable(false);
@@ -114,16 +113,16 @@ public class UIScene extends Scene {
dialog.setResizable(false); dialog.setResizable(false);
return dialog; return dialog;
} }
public void showDialog(Dialog dialog)
{ public void showDialog(Dialog dialog) {
stage.addActor(dialog); stage.addActor(dialog);
possibleSelectionStack.add(new Array<>()); possibleSelectionStack.add(new Array<>());
addToSelectable(dialog.getContentTable()); addToSelectable(dialog.getContentTable());
addToSelectable(dialog.getButtonTable()); addToSelectable(dialog.getButtonTable());
dialog.getColor().a=0; dialog.getColor().a = 0;
stage.setKeyboardFocus(dialog); stage.setKeyboardFocus(dialog);
stage.setScrollFocus(dialog); stage.setScrollFocus(dialog);
for(Dialog otherDialogs:dialogs) for (Dialog otherDialogs : dialogs)
otherDialogs.hide(); otherDialogs.hide();
dialogs.add(dialog); dialogs.add(dialog);
selectFirst(); selectFirst();
@@ -136,7 +135,7 @@ public class UIScene extends Scene {
{ {
@Override @Override
protected void result(@Null Object object) { protected void result(@Null Object object) {
removeDialog(); removeDialog();
} }
}; };
keyboardDialog.setText(text); keyboardDialog.setText(text);
@@ -145,41 +144,42 @@ public class UIScene extends Scene {
//possibleSelection=keyboardDialog.keys(); //possibleSelection=keyboardDialog.keys();
} }
public Array< Array<Selectable>> possibleSelectionStack=new Array<>(); public Array<Array<Selectable>> possibleSelectionStack = new Array<>();
public Array< Dialog> dialogs=new Array<>(); public Array<Dialog> dialogs = new Array<>();
public Array<Selectable> getPossibleSelection()
{ public Array<Selectable> getPossibleSelection() {
if(possibleSelectionStack.isEmpty()) if (possibleSelectionStack.isEmpty())
possibleSelectionStack.add(ui.selectActors); possibleSelectionStack.add(ui.selectActors);
return possibleSelectionStack.get(possibleSelectionStack.size-1); return possibleSelectionStack.get(possibleSelectionStack.size - 1);
} }
protected Stage stage; protected Stage stage;
String uiFile; String uiFile;
public static InputEvent eventTouchUp()
{ public static InputEvent eventTouchUp() {
InputEvent event = new InputEvent(); InputEvent event = new InputEvent();
event.setPointer(-1); event.setPointer(-1);
event.setType(InputEvent.Type.touchUp); event.setType(InputEvent.Type.touchUp);
return event; return event;
} }
public static InputEvent eventTouchDown()
{ public static InputEvent eventTouchDown() {
InputEvent event = new InputEvent(); InputEvent event = new InputEvent();
event.setPointer(-1); event.setPointer(-1);
event.setType(InputEvent.Type.touchDown); event.setType(InputEvent.Type.touchDown);
return event; return event;
} }
public static InputEvent eventExit()
{ public static InputEvent eventExit() {
InputEvent event = new InputEvent(); InputEvent event = new InputEvent();
event.setPointer(-1); event.setPointer(-1);
event.setType(InputEvent.Type.exit); event.setType(InputEvent.Type.exit);
return event; return event;
} }
public static InputEvent eventEnter()
{ public static InputEvent eventEnter() {
InputEvent event = new InputEvent(); InputEvent event = new InputEvent();
event.setPointer(-1); event.setPointer(-1);
event.setType(InputEvent.Type.enter); event.setType(InputEvent.Type.enter);
@@ -188,26 +188,30 @@ public class UIScene extends Scene {
@Override @Override
public boolean buttonUp(Controller controller, int keycode) { public boolean buttonUp(Controller controller, int keycode) {
return stage.keyUp(KeyBinding.controllerButtonToKey(controller,keycode)); return stage.keyUp(KeyBinding.controllerButtonToKey(controller, keycode));
} }
@Override @Override
public boolean buttonDown(Controller controller, int keycode) { public boolean buttonDown(Controller controller, int keycode) {
return stage.keyDown(KeyBinding.controllerButtonToKey(controller,keycode)); return stage.keyDown(KeyBinding.controllerButtonToKey(controller, keycode));
} }
protected void addToSelectable(Table table) { protected void addToSelectable(Table table) {
for(Cell cell:table.getCells()) for (Cell cell : table.getCells()) {
{ if (cell.getActor() != null && cell.getActor().getClass() != Actor.class && !(cell.getActor() instanceof Label) && !(cell.getActor() instanceof TextraLabel))
if(cell.getActor()!=null&&cell.getActor().getClass()!=Actor.class&&!(cell.getActor()instanceof Label)&&!(cell.getActor()instanceof TextraLabel))
getPossibleSelection().add(new Selectable(cell.getActor())); getPossibleSelection().add(new Selectable(cell.getActor()));
} }
} }
protected void addToSelectable(Button button)//prevent to addToSelectable(Table) fallback protected void addToSelectable(Button button)//prevent to addToSelectable(Table) fallback
{ {
getPossibleSelection().add(new Selectable(button)); getPossibleSelection().add(new Selectable(button));
} }
protected void addToSelectable(Actor button) { protected void addToSelectable(Actor button) {
getPossibleSelection().add(new Selectable(button)); getPossibleSelection().add(new Selectable(button));
} }
protected void addToSelectable(Selectable selectable) { protected void addToSelectable(Selectable selectable) {
getPossibleSelection().add(selectable); getPossibleSelection().add(selectable);
} }
@@ -222,14 +226,16 @@ public class UIScene extends Scene {
stage = new Stage(new ScalingViewport(Scaling.stretch, getIntendedWidth(), getIntendedHeight())) { stage = new Stage(new ScalingViewport(Scaling.stretch, getIntendedWidth(), getIntendedHeight())) {
@Override @Override
public boolean keyUp(int keycode) { public boolean keyUp(int keycode) {
keyReleased(keycode); keyReleased(keycode);
return super.keyUp(keycode); return super.keyUp(keycode);
} }
@Override @Override
public boolean keyDown(int keyCode) { public boolean keyDown(int keyCode) {
keyPressed(keyCode); keyPressed(keyCode);
return super.keyDown(keyCode); return super.keyDown(keyCode);
} }
@Override @Override
public boolean mouseMoved(int screenX, int screenY) { public boolean mouseMoved(int screenX, int screenY) {
pointerMoved(screenX, screenY); pointerMoved(screenX, screenY);
@@ -237,9 +243,8 @@ public class UIScene extends Scene {
} }
}; };
ui = new UIActor(Config.instance().getFile(uiFile)); ui = new UIActor(Config.instance().getFile(uiFile));
for(Actor actor:ui.getChildren()) for (Actor actor : ui.getChildren()) {
{ if (actor instanceof ScrollPane)
if(actor instanceof ScrollPane)
stage.setScrollFocus(actor); stage.setScrollFocus(actor);
} }
possibleSelectionStack.add(ui.selectActors); possibleSelectionStack.add(ui.selectActors);
@@ -249,21 +254,17 @@ public class UIScene extends Scene {
private void removeDialog() { private void removeDialog() {
if(!dialogs.isEmpty()) if (!dialogs.isEmpty()) {
{ dialogs.get(dialogs.size - 1).remove();
dialogs.get(dialogs.size-1).remove(); dialogs.removeIndex(dialogs.size - 1);
dialogs.removeIndex(dialogs.size-1);
if(!dialogs.isEmpty()) if (!dialogs.isEmpty())
dialogs.get(dialogs.size-1).show(stage); dialogs.get(dialogs.size - 1).show(stage);
} }
if(possibleSelectionStack.isEmpty()) if (possibleSelectionStack.isEmpty()) {
{
getPossibleSelection(); getPossibleSelection();
} } else {
else possibleSelectionStack.removeIndex(possibleSelectionStack.size - 1);
{
possibleSelectionStack.removeIndex(possibleSelectionStack.size-1);
} }
} }
@@ -295,92 +296,80 @@ public class UIScene extends Scene {
Forge.switchToLast(); Forge.switchToLast();
return true; return true;
} }
public Selectable getSelected()
{ public Selectable getSelected() {
for(Selectable selectable: getPossibleSelection()) for (Selectable selectable : getPossibleSelection()) {
{ if (stage.getKeyboardFocus() == selectable.actor)
if(stage.getKeyboardFocus()==selectable.actor)
return selectable; return selectable;
} }
return null; return null;
} }
public boolean keyReleased(int keycode)
{ public boolean keyReleased(int keycode) {
ui.pressUp(keycode); ui.pressUp(keycode);
if(!dialogShowing()) if (!dialogShowing()) {
{ Button pressedButton = ui.buttonPressed(keycode);
Button pressedButton=ui.buttonPressed(keycode); if (pressedButton != null) {
if(pressedButton!=null) if (pressedButton.isVisible())
{
if(pressedButton.isVisible())
pressedButton.fire(eventTouchUp()); pressedButton.fire(eventTouchUp());
} }
} }
if(KeyBinding.Use.isPressed(keycode)){ if (KeyBinding.Use.isPressed(keycode)) {
if(getSelected()!=null) if (getSelected() != null)
getSelected().onPressUp();//order is important, this might remove a dialog getSelected().onPressUp();//order is important, this might remove a dialog
} }
return true; return true;
} }
public boolean keyPressed(int keycode) { public boolean keyPressed(int keycode) {
Selectable selection=getSelected(); Selectable selection = getSelected();
ui.pressDown(keycode); ui.pressDown(keycode);
if(stage.getKeyboardFocus() instanceof SelectBox) if (stage.getKeyboardFocus() instanceof SelectBox) {
{ SelectBox box = (SelectBox) stage.getKeyboardFocus();
SelectBox box=(SelectBox) stage.getKeyboardFocus(); if (box.getScrollPane().hasParent()) {
if(box.getScrollPane().hasParent()) if (KeyBinding.Use.isPressed(keycode)) {
{
if(KeyBinding.Use.isPressed(keycode))
{
box.getSelection().choose(box.getList().getSelected()); box.getSelection().choose(box.getList().getSelected());
box.getScrollPane().hide(); box.getScrollPane().hide();
} }
return false; return false;
} }
} }
if(KeyBinding.Use.isPressed(keycode)){ if (KeyBinding.Use.isPressed(keycode)) {
if(selection!=null) if (selection != null)
selection.onPressDown(this); selection.onPressDown(this);
} }
if(KeyBinding.ScrollUp.isPressed(keycode)) if (KeyBinding.ScrollUp.isPressed(keycode)) {
{ Actor focus = stage.getScrollFocus();
Actor focus=stage.getScrollFocus(); if (focus != null && focus instanceof ScrollPane) {
if(focus!=null&&focus instanceof ScrollPane) ScrollPane scroll = ((ScrollPane) focus);
{ scroll.setScrollY(scroll.getScrollY() - 20);
ScrollPane scroll=((ScrollPane)focus);
scroll.setScrollY(scroll.getScrollY()-20);
} }
} }
if(KeyBinding.ScrollDown.isPressed(keycode)) if (KeyBinding.ScrollDown.isPressed(keycode)) {
{ Actor focus = stage.getScrollFocus();
Actor focus=stage.getScrollFocus(); if (focus != null && focus instanceof ScrollPane) {
if(focus!=null&&focus instanceof ScrollPane) ScrollPane scroll = ((ScrollPane) focus);
{ scroll.setScrollY(scroll.getScrollY() + 20);
ScrollPane scroll=((ScrollPane)focus);
scroll.setScrollY(scroll.getScrollY()+20);
} }
} }
if(KeyBinding.Down.isPressed(keycode)) if (KeyBinding.Down.isPressed(keycode))
selectNextDown(); selectNextDown();
if(KeyBinding.Up.isPressed(keycode)) if (KeyBinding.Up.isPressed(keycode))
selectNextUp(); selectNextUp();
if(!(stage.getKeyboardFocus() instanceof Selector)&&!(stage.getKeyboardFocus() instanceof TextField)&&!(stage.getKeyboardFocus() instanceof Slider)) if (!(stage.getKeyboardFocus() instanceof Selector) && !(stage.getKeyboardFocus() instanceof TextField) && !(stage.getKeyboardFocus() instanceof Slider)) {
{ if (KeyBinding.Right.isPressed(keycode))
if(KeyBinding.Right.isPressed(keycode))
selectNextRight(); selectNextRight();
if(KeyBinding.Left.isPressed(keycode)) if (KeyBinding.Left.isPressed(keycode))
selectNextLeft(); selectNextLeft();
} }
if(!dialogShowing()) if (!dialogShowing()) {
{ Button pressedButton = ui.buttonPressed(keycode);
Button pressedButton=ui.buttonPressed(keycode); if (pressedButton != null) {
if(pressedButton!=null) if (pressedButton.isVisible())
{
if(pressedButton.isVisible())
pressedButton.fire(eventTouchDown()); pressedButton.fire(eventTouchDown());
} }
} }
@@ -396,11 +385,13 @@ public class UIScene extends Scene {
public void disconnected(final Controller controller) { public void disconnected(final Controller controller) {
ui.controllerDisconnected(); ui.controllerDisconnected();
} }
@Override @Override
public void connected(final Controller controller) { public void connected(final Controller controller) {
selectFirst(); selectFirst();
ui.controllerConnected(); ui.controllerConnected();
} }
public boolean pointerMoved(int screenX, int screenY) { public boolean pointerMoved(int screenX, int screenY) {
unselectActors(); unselectActors();
return false; return false;
@@ -417,152 +408,128 @@ public class UIScene extends Scene {
} }
}, 0.10f); }, 0.10f);
} }
public void unselectActors() { public void unselectActors() {
for (Selectable selectable : getPossibleSelection()) { for (Selectable selectable : getPossibleSelection()) {
selectable.onDeSelect(); selectable.onDeSelect();
} }
} }
Array<Selectable> visibleSelection()
{ Array<Selectable> visibleSelection() {
Array<Selectable> selectables=new Array<>(); Array<Selectable> selectables = new Array<>();
for (Selectable selectable : getPossibleSelection()) { for (Selectable selectable : getPossibleSelection()) {
if(selectable.actor.isVisible()) if (selectable.actor.isVisible()) {
{ if (selectable.actor instanceof Button) {
if(selectable.actor instanceof Button) if (!((Button) selectable.actor).isDisabled())
{
if(!((Button)selectable.actor).isDisabled())
selectables.add(selectable); selectables.add(selectable);
} } else {
else
{
selectables.add(selectable); selectables.add(selectable);
} }
} }
} }
return selectables; return selectables;
} }
public void selectNextDown() { public void selectNextDown() {
if(getSelected()==null) if (getSelected() == null) {
{
selectFirst(); selectFirst();
} } else {
else Selectable current = getSelected();
{ Array<Selectable> candidates = new Array<>();
Selectable current =getSelected(); for (Selectable selectable : visibleSelection()) {
Array<Selectable> candidates=new Array<>(); if (selectable.xDiff(current) < 0.1 && selectable != current)
for(Selectable selectable:visibleSelection())
{
if(selectable.xDiff(current)<0.1&&selectable!=current)
candidates.add(selectable); candidates.add(selectable);
} }
if(candidates.isEmpty()) if (candidates.isEmpty())
candidates.addAll(visibleSelection()); candidates.addAll(visibleSelection());
Selectable finalOne=null; Selectable finalOne = null;
Selectable fallback=null; Selectable fallback = null;
for(Selectable candidate:candidates) for (Selectable candidate : candidates) {
{ if (fallback == null || candidate.getY() > fallback.getY())
if(fallback==null||candidate.getY()>fallback.getY()) fallback = candidate;
fallback=candidate; if (candidate.getY() < current.getY() && (finalOne == null || current.yDiff(candidate) < current.yDiff(finalOne))) {
if(candidate.getY()<current.getY()&&(finalOne==null||current.yDiff(candidate)<current.yDiff(finalOne))) finalOne = candidate;
{
finalOne=candidate;
} }
} }
if(finalOne==null) if (finalOne == null)
for(Selectable candidate:visibleSelection()) for (Selectable candidate : visibleSelection()) {
{ if (candidate.getY() < current.getY() && (finalOne == null || current.yDiff(candidate) < current.yDiff(finalOne))) {
if(candidate.getY()<current.getY()&&(finalOne==null||current.yDiff(candidate)<current.yDiff(finalOne))) finalOne = candidate;
{
finalOne=candidate;
} }
} }
if(finalOne!=null) if (finalOne != null)
selectActor(finalOne); selectActor(finalOne);
else if(fallback!=null) else if (fallback != null)
selectActor(fallback); selectActor(fallback);
} }
} }
private void selectNextLeft() { private void selectNextLeft() {
if(getSelected()==null) if (getSelected() == null) {
{
selectFirst(); selectFirst();
} } else {
else Selectable current = getSelected();
{ Array<Selectable> candidates = new Array<>();
Selectable current =getSelected(); for (Selectable selectable : visibleSelection()) {
Array<Selectable> candidates=new Array<>(); if (selectable.yDiff(current) < 0.1 && selectable != current)
for(Selectable selectable:visibleSelection())
{
if(selectable.yDiff(current)<0.1&&selectable!=current)
candidates.add(selectable); candidates.add(selectable);
} }
if(candidates.isEmpty()) if (candidates.isEmpty())
candidates.addAll(visibleSelection()); candidates.addAll(visibleSelection());
Selectable finalOne=null; Selectable finalOne = null;
Selectable fallback=null; Selectable fallback = null;
for(Selectable candidate:candidates) for (Selectable candidate : candidates) {
{ if (fallback == null || candidate.getX() > fallback.getX())
if(fallback==null||candidate.getX()>fallback.getX()) fallback = candidate;
fallback=candidate; if (candidate.getX() < current.getX() && (finalOne == null || current.xDiff(candidate) < current.xDiff(finalOne))) {
if(candidate.getX()<current.getX()&&(finalOne==null||current.xDiff(candidate)<current.xDiff(finalOne))) finalOne = candidate;
{
finalOne=candidate;
} }
} }
if(finalOne==null) if (finalOne == null)
for(Selectable candidate:visibleSelection()) for (Selectable candidate : visibleSelection()) {
{ if (candidate.getX() < current.getX() && (finalOne == null || current.xDiff(candidate) < current.xDiff(finalOne))) {
if(candidate.getX()<current.getX()&&(finalOne==null||current.xDiff(candidate)<current.xDiff(finalOne))) finalOne = candidate;
{
finalOne=candidate;
} }
} }
if(finalOne!=null) if (finalOne != null)
selectActor(finalOne); selectActor(finalOne);
else if(fallback!=null) else if (fallback != null)
selectActor(fallback); selectActor(fallback);
} }
} }
private void selectNextRight() { private void selectNextRight() {
if(getSelected()==null) if (getSelected() == null) {
{
selectFirst(); selectFirst();
} } else {
else Selectable current = getSelected();
{ Array<Selectable> candidates = new Array<>();
Selectable current =getSelected(); for (Selectable selectable : visibleSelection()) {
Array<Selectable> candidates=new Array<>(); if (selectable.yDiff(current) < 0.1 && selectable != current)
for(Selectable selectable:visibleSelection())
{
if(selectable.yDiff(current)<0.1&&selectable!=current)
candidates.add(selectable); candidates.add(selectable);
} }
if(candidates.isEmpty()) if (candidates.isEmpty())
candidates.addAll(visibleSelection()); candidates.addAll(visibleSelection());
Selectable finalOne=null; Selectable finalOne = null;
Selectable fallback=null; Selectable fallback = null;
for(Selectable candidate:candidates) for (Selectable candidate : candidates) {
{ if (fallback == null || candidate.getX() < fallback.getX())
if(fallback==null||candidate.getX()<fallback.getX()) fallback = candidate;
fallback=candidate; if (candidate.getX() > current.getX() && (finalOne == null || current.xDiff(candidate) < current.xDiff(finalOne))) {
if(candidate.getX()>current.getX()&&(finalOne==null||current.xDiff(candidate)<current.xDiff(finalOne))) finalOne = candidate;
{
finalOne=candidate;
} }
} }
if(finalOne==null) if (finalOne == null)
for(Selectable candidate:visibleSelection()) for (Selectable candidate : visibleSelection()) {
{ if (candidate.getX() > current.getX() && (finalOne == null || current.xDiff(candidate) < current.xDiff(finalOne))) {
if(candidate.getX()>current.getX()&&(finalOne==null||current.xDiff(candidate)<current.xDiff(finalOne))) finalOne = candidate;
{
finalOne=candidate;
} }
} }
if(finalOne!=null) if (finalOne != null)
selectActor(finalOne); selectActor(finalOne);
else if(fallback!=null) else if (fallback != null)
selectActor(fallback); selectActor(fallback);
} }
@@ -571,43 +538,35 @@ public class UIScene extends Scene {
public void selectNextUp() { public void selectNextUp() {
if(getSelected()==null) if (getSelected() == null) {
{
selectFirst(); selectFirst();
} } else {
else Selectable current = getSelected();
{ Array<Selectable> candidates = new Array<>();
Selectable current =getSelected(); for (Selectable selectable : visibleSelection()) {
Array<Selectable> candidates=new Array<>(); if (selectable.xDiff(current) < 0.1 && selectable != current)
for(Selectable selectable:visibleSelection())
{
if(selectable.xDiff(current)<0.1&&selectable!=current)
candidates.add(selectable); candidates.add(selectable);
} }
if(candidates.isEmpty()) if (candidates.isEmpty())
candidates.addAll(visibleSelection()); candidates.addAll(visibleSelection());
Selectable finalOne=null; Selectable finalOne = null;
Selectable fallback=null; Selectable fallback = null;
for(Selectable candidate:candidates) for (Selectable candidate : candidates) {
{ if (fallback == null || candidate.getY() < fallback.getY())
if(fallback==null||candidate.getY()<fallback.getY()) fallback = candidate;
fallback=candidate; if (candidate.getY() > current.getY() && (finalOne == null || current.yDiff(candidate) < current.yDiff(finalOne))) {
if(candidate.getY()>current.getY()&&(finalOne==null||current.yDiff(candidate)<current.yDiff(finalOne))) finalOne = candidate;
{
finalOne=candidate;
} }
} }
if(finalOne==null)//allowAllNow if (finalOne == null)//allowAllNow
for(Selectable candidate:visibleSelection()) for (Selectable candidate : visibleSelection()) {
{ if (candidate.getY() > current.getY() && (finalOne == null || current.yDiff(candidate) < current.yDiff(finalOne))) {
if(candidate.getY()>current.getY()&&(finalOne==null||current.yDiff(candidate)<current.yDiff(finalOne))) finalOne = candidate;
{
finalOne=candidate;
} }
} }
if(finalOne!=null) if (finalOne != null)
selectActor(finalOne); selectActor(finalOne);
else if(fallback!=null) else if (fallback != null)
selectActor(fallback); selectActor(fallback);
} }
@@ -615,22 +574,18 @@ public class UIScene extends Scene {
private void selectFirst() { private void selectFirst() {
Selectable result=null; Selectable result = null;
for(Selectable candidate: getPossibleSelection()) for (Selectable candidate : getPossibleSelection()) {
{ if (result == null || candidate.getY() > result.getY()) {
if(result==null|| candidate.getY()>result.getY()) result = candidate;
{
result=candidate;
} }
} }
selectActor(result); selectActor(result);
} }
ScrollPane scrollPaneOfActor(Actor actor)
{ ScrollPane scrollPaneOfActor(Actor actor) {
while (actor!=null) while (actor != null) {
{ if (actor.getParent() instanceof ScrollPane) {
if(actor.getParent() instanceof ScrollPane)
{
return (ScrollPane) actor.getParent(); return (ScrollPane) actor.getParent();
} }
actor = actor.getParent(); actor = actor.getParent();
@@ -641,16 +596,16 @@ public class UIScene extends Scene {
public void selectActor(Selectable actor) { public void selectActor(Selectable actor) {
unselectActors(); unselectActors();
if(actor==null)return; if (actor == null) return;
stage.setKeyboardFocus(actor.actor); stage.setKeyboardFocus(actor.actor);
ScrollPane scrollPane=scrollPaneOfActor(actor.actor); ScrollPane scrollPane = scrollPaneOfActor(actor.actor);
if(scrollPane!=null) if (scrollPane != null) {
{ scrollPane.scrollTo(actor.actor.getX(), actor.actor.getY(), actor.actor.getWidth(), actor.actor.getHeight(), false, false);
scrollPane.scrollTo(actor.actor.getX(),actor.actor.getY(),actor.actor.getWidth(),actor.actor.getHeight(),false,false); }
} actor.onSelect(this);
actor.onSelect(this);
} }
Image screenImage; Image screenImage;
TextureRegion backgroundTexture; TextureRegion backgroundTexture;
@@ -659,6 +614,7 @@ public class UIScene extends Scene {
stage.cancelTouchFocus(); stage.cancelTouchFocus();
return super.leave(); return super.leave();
} }
@Override @Override
public void enter() { public void enter() {
if (screenImage != null) { if (screenImage != null) {
@@ -674,6 +630,7 @@ public class UIScene extends Scene {
Gdx.input.setInputProcessor(stage); Gdx.input.setInputProcessor(stage);
super.enter(); super.enter();
} }
public TextureRegion getUIBackground() { public TextureRegion getUIBackground() {
try { try {
Actor a = ui.getChild(0); Actor a = ui.getChild(0);

View File

@@ -2,6 +2,8 @@ package forge.adventure.stage;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input; import com.badlogic.gdx.Input;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture;
@@ -33,8 +35,11 @@ import forge.adventure.world.WorldSave;
import forge.deck.Deck; import forge.deck.Deck;
import forge.gui.FThreads; import forge.gui.FThreads;
import forge.gui.GuiBase; import forge.gui.GuiBase;
import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel;
import forge.sound.MusicPlaylist; import forge.sound.MusicPlaylist;
import forge.sound.SoundSystem; import forge.sound.SoundSystem;
import org.apache.commons.lang3.tuple.Pair;
/** /**
* Stage to handle everything rendered in the HUD * Stage to handle everything rendered in the HUD
@@ -275,7 +280,10 @@ public class GameHUD extends Stage {
updatelife = false; updatelife = false;
lifePoints.setText("[%95][+Life]" + lifepointsTextColor + " " + AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife()); lifePoints.setText("[%95][+Life]" + lifepointsTextColor + " " + AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife());
} }
updateMusic(); if (!GameScene.instance().isNotInWorldMap())
updateMusic();
else
SoundSystem.instance.pause();
} }
Texture miniMapTexture; Texture miniMapTexture;
@@ -301,7 +309,122 @@ public class GameHUD extends Stage {
} else { } else {
deckActor.setColor(menuActor.getColor()); deckActor.setColor(menuActor.getColor());
} }
updateMusic(); if (GameScene.instance().isNotInWorldMap()) {
SoundSystem.instance.pause();
playAudio();
} else {
unloadAudio();
SoundSystem.instance.resume(); // resume World BGM
}
}
private Pair<FileHandle, Music> audio = null;
public void playAudio() {
switch (GameScene.instance().getAdventurePlayerLocation(false, false)) {
case "capital":
case "town":
setAudio(MusicPlaylist.TOWN);
break;
case "dungeon":
case "cave":
setAudio(MusicPlaylist.CAVE);
break;
case "castle":
setAudio(MusicPlaylist.CASTLE);
break;
default:
break;
}
if (audio != null) {
audio.getRight().setLooping(true);
audio.getRight().play();
audio.getRight().setVolume(FModel.getPreferences().getPrefInt(ForgePreferences.FPref.UI_VOL_MUSIC) / 100f);
}
}
public void fadeAudio(float value) {
if (audio != null) {
audio.getRight().setVolume((FModel.getPreferences().getPrefInt(ForgePreferences.FPref.UI_VOL_MUSIC) * value) / 100f);
}
}
float fade = 1f;
void fadeIn() {
if (fade >= 1f)
return;
for (int i = 10; i > 1; i--) {
float delay = i * 0.1f;
Timer.schedule(new Timer.Task() {
@Override
public void run() {
fade += 0.1f;
if (fade > 1f)
fade = 1f;
fadeAudio(fade);
}
}, delay);
}
}
void fadeOut() {
for (int i = 10; i > 1; i--) {
float delay = i * 0.1f;
Timer.schedule(new Timer.Task() {
@Override
public void run() {
fade -= 0.1f;
if (fade < 0.1f)
fade = 0.1f;
fadeAudio(fade);
}
}, delay);
}
}
public void stopAudio() {
if (audio != null) {
audio.getRight().stop();
}
}
public void pauseMusic() {
if (audio != null) {
audio.getRight().pause();
}
SoundSystem.instance.pause();
}
public void unloadAudio() {
if (audio != null) {
audio.getRight().setOnCompletionListener(null);
audio.getRight().stop();
Forge.getAssets().manager().unload(audio.getLeft().path());
}
audio = null;
currentAudioPlaylist = null;
}
private MusicPlaylist currentAudioPlaylist = null;
private void setAudio(MusicPlaylist playlist) {
if (playlist.equals(currentAudioPlaylist))
return;
unloadAudio();
audio = getMusic(playlist);
}
private Pair<FileHandle, Music> getMusic(MusicPlaylist playlist) {
FileHandle file = Gdx.files.absolute(playlist.getNewRandomFilename());
Music music = Forge.getAssets().getMusic(file);
if (music != null) {
currentAudioPlaylist = playlist;
return Pair.of(file, music);
} else {
currentAudioPlaylist = null;
return null;
}
} }
private void openDeck() { private void openDeck() {
@@ -580,17 +703,6 @@ public class GameHUD extends Stage {
case "white": case "white":
changeBGM(MusicPlaylist.WHITE); changeBGM(MusicPlaylist.WHITE);
break; break;
case "capital":
case "town":
changeBGM(MusicPlaylist.TOWN);
break;
case "dungeon":
case "cave":
changeBGM(MusicPlaylist.CAVE);
break;
case "castle":
changeBGM(MusicPlaylist.CASTLE);
break;
case "waste": case "waste":
changeBGM(MusicPlaylist.MENUS); changeBGM(MusicPlaylist.MENUS);
break; break;
@@ -598,7 +710,6 @@ public class GameHUD extends Stage {
break; break;
} }
} }
float fade = 1f;
void changeBGM(MusicPlaylist playlist) { void changeBGM(MusicPlaylist playlist) {
if (!playlist.equals(SoundSystem.instance.getCurrentPlaylist())) { if (!playlist.equals(SoundSystem.instance.getCurrentPlaylist())) {

View File

@@ -63,30 +63,6 @@ public class MapSprite extends Actor {
return actorGroup; return actorGroup;
} }
public static String getBoundaryName(int chunkX, int chunkY) {
String boundary = "";
List<PointOfInterest> poi = WorldSave.getCurrentSave().getWorld().getPointsOfInterest(chunkX, chunkY);
for (PointOfInterest p : poi) {
if ("town".equalsIgnoreCase(p.getData().type)) {
if (p.getData().name.startsWith("Waste"))
boundary = "waste";
else if (p.getData().name.startsWith("Plains"))
boundary = "white";
else if (p.getData().name.startsWith("Forest"))
boundary = "green";
else if (p.getData().name.startsWith("Island"))
boundary = "blue";
else if (p.getData().name.startsWith("Mountain"))
boundary = "red";
else if (p.getData().name.startsWith("Swamp"))
boundary = "black";
break;
}
}
return boundary;
}
//BitmapFont font; //BitmapFont font;
@Override @Override
public void draw(Batch batch, float parentAlpha) { public void draw(Batch batch, float parentAlpha) {

View File

@@ -294,12 +294,6 @@ public class WorldStage extends GameStage implements SaveFileContent {
background.loadChunk(pos.x, pos.y); background.loadChunk(pos.x, pos.y);
handlePointsOfInterestCollision(); handlePointsOfInterestCollision();
} }
public String getBoundary() {
if (background == null)
return "";
GridPoint2 pos = background.translateFromWorldToChunk(player.getX(), player.getY());
return MapSprite.getBoundaryName(pos.x, pos.y);
}
@Override @Override
public void leave() { public void leave() {

View File

@@ -648,7 +648,9 @@ public class CardUtil {
FileHandle handle = Config.instance().getFile(path); FileHandle handle = Config.instance().getFile(path);
if (handle.exists()) if (handle.exists())
return generateDeck(json.fromJson(GeneratedDeckData.class, handle), starterEdition, discourageDuplicates); return generateDeck(json.fromJson(GeneratedDeckData.class, handle), starterEdition, discourageDuplicates);
return null; Deck deck = DeckgenUtil.getRandomOrPreconOrThemeDeck(colors, true, false, true);
System.err.println("Error loading JSON: " + handle.path() + "\nGenerating random deck: "+deck.getName());
return deck;
} }

View File

@@ -27,6 +27,8 @@ import com.github.tommyettinger.textra.TypingLabel;
import forge.Forge; import forge.Forge;
import forge.adventure.player.AdventurePlayer; import forge.adventure.player.AdventurePlayer;
import forge.card.ColorSet; import forge.card.ColorSet;
import forge.sound.SoundEffectType;
import forge.sound.SoundSystem;
import java.util.function.Function; import java.util.function.Function;
@@ -52,6 +54,13 @@ public class Controls {
static class TextButtonFix extends TextraButton { static class TextButtonFix extends TextraButton {
public TextButtonFix(@Null String text) { public TextButtonFix(@Null String text) {
super(text == null ? "NULL" : text, Controls.getSkin(), Controls.getTextraFont()); super(text == null ? "NULL" : text, Controls.getSkin(), Controls.getTextraFont());
addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
super.clicked(event, x, y);
SoundSystem.instance.play(SoundEffectType.ButtonPress, false);
}
});
} }
@Override @Override
@@ -74,6 +83,7 @@ public class Controls {
getTextraLabel().setWidth(getTextraLabel().layout.getWidth() + (getTextraLabel().style != null && getTextraLabel().style.background != null ? getTextraLabel().style.background.getLeftWidth() + getTextraLabel().style.background.getRightWidth() : 0.0F)); getTextraLabel().setWidth(getTextraLabel().layout.getWidth() + (getTextraLabel().style != null && getTextraLabel().style.background != null ? getTextraLabel().style.background.getLeftWidth() + getTextraLabel().style.background.getRightWidth() : 0.0F));
layout(); layout();
} }
} }
static public TextraButton newTextButton(String text) { static public TextraButton newTextButton(String text) {

View File

@@ -15,11 +15,11 @@ import forge.Forge;
import forge.adventure.character.EnemySprite; import forge.adventure.character.EnemySprite;
import forge.adventure.data.DialogData; import forge.adventure.data.DialogData;
import forge.adventure.player.AdventurePlayer; import forge.adventure.player.AdventurePlayer;
import forge.adventure.stage.GameHUD;
import forge.adventure.stage.MapStage; import forge.adventure.stage.MapStage;
import forge.card.ColorSet; import forge.card.ColorSet;
import forge.localinstance.properties.ForgePreferences; import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel; import forge.model.FModel;
import forge.sound.SoundSystem;
import forge.util.Localizer; import forge.util.Localizer;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@@ -196,7 +196,7 @@ public class MapDialog {
fade += 0.1f; fade += 0.1f;
if (fade > 1f) if (fade > 1f)
fade = 1f; fade = 1f;
SoundSystem.instance.fadeModifier(fade); GameHUD.getInstance().fadeAudio(fade);
} }
}, delay); }, delay);
} }
@@ -211,7 +211,7 @@ public class MapDialog {
fade -= 0.1f; fade -= 0.1f;
if (fade < 0.1f) if (fade < 0.1f)
fade = 0.1f; fade = 0.1f;
SoundSystem.instance.fadeModifier(fade); GameHUD.getInstance().fadeAudio(fade);
} }
}, delay); }, delay);
} }

View File

@@ -41,6 +41,8 @@ import forge.card.CardRenderer;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.gui.GuiBase; import forge.gui.GuiBase;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.sound.SoundEffectType;
import forge.sound.SoundSystem;
import forge.util.ImageFetcher; import forge.util.ImageFetcher;
import forge.util.ImageUtil; import forge.util.ImageUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -593,6 +595,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
return; return;
clicked = true; clicked = true;
flipProcess = 0; flipProcess = 0;
SoundSystem.instance.play(SoundEffectType.FlipCard, false);
} }
public void sold() { public void sold() {
@@ -608,7 +611,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
super.act(delta); super.act(delta);
if (clicked) { if (clicked) {
if (flipProcess < 1) if (flipProcess < 1)
flipProcess += delta * 1.5; flipProcess += delta * 2.4;
else else
flipProcess = 1; flipProcess = 1;

View File

@@ -238,6 +238,14 @@ public class World implements Disposable, SaveFileContent {
} }
} }
public long getBiomeMapXY(int x, int y) {
try {
return biomeMap[x][height - y - 1] & (~(0b1<<data.GetBiomes().size()));
} catch (ArrayIndexOutOfBoundsException e) {
return biomeMap[biomeMap.length - 1][biomeMap[biomeMap.length - 1].length - 1];
}
}
public boolean isStructure(int x, int y) { public boolean isStructure(int x, int y) {
try { try {
return (terrainMap[x][height - y - 1] & ~isStructureBit) != 0; return (terrainMap[x][height - y - 1] & ~isStructureBit) != 0;

View File

@@ -558,7 +558,8 @@ public class Assets implements Disposable {
@Override @Override
public synchronized void unload(String fileName) { public synchronized void unload(String fileName) {
super.unload(fileName); if (isLoaded(fileName))
super.unload(fileName);
if (memoryPerFile.containsKey(fileName)) { if (memoryPerFile.containsKey(fileName)) {
memoryPerFile.remove(fileName); memoryPerFile.remove(fileName);
cardArtCache().clear(); cardArtCache().clear();

View File

@@ -236,6 +236,8 @@ public class CardImageRenderer {
g.drawOutlinedText(artist, TEXT_FONT, Color.WHITE, Color.DARK_GRAY, x + (TYPE_FONT.getCapHeight() / 2), y + (TYPE_FONT.getCapHeight() / 2), w, h, false, Align.left, false); g.drawOutlinedText(artist, TEXT_FONT, Color.WHITE, Color.DARK_GRAY, x + (TYPE_FONT.getCapHeight() / 2), y + (TYPE_FONT.getCapHeight() / 2), w, h, false, Align.left, false);
} }
private static void drawOutlineColor(Graphics g, ColorSet colors, float x, float y, float w, float h) { private static void drawOutlineColor(Graphics g, ColorSet colors, float x, float y, float w, float h) {
if (colors == null)
return;
switch (colors.countColors()) { switch (colors.countColors()) {
case 0: case 0:
g.drawRect(BORDER_THICKNESS*2, Color.valueOf("#A0A6A4"), x, y, w, h); g.drawRect(BORDER_THICKNESS*2, Color.valueOf("#A0A6A4"), x, y, w, h);
@@ -264,7 +266,8 @@ public class CardImageRenderer {
fillColorBackground(g, colors, x, y, w, h); fillColorBackground(g, colors, x, y, w, h);
g.setAlphaComposite(oldAlpha); g.setAlphaComposite(oldAlpha);
//draw outline color here //draw outline color here
drawOutlineColor(g, state.getColors(), x, y, w, h); if (state != null)
drawOutlineColor(g, state.getColors(), x, y, w, h);
g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h);
float padding = h / 8; float padding = h / 8;
@@ -450,7 +453,8 @@ public class CardImageRenderer {
fillColorBackground(g, colors, x, y, w, h); fillColorBackground(g, colors, x, y, w, h);
g.setAlphaComposite(oldAlpha); g.setAlphaComposite(oldAlpha);
//draw outline color here //draw outline color here
drawOutlineColor(g, state.getColors(), x, y, w, h); if (state != null)
drawOutlineColor(g, state.getColors(), x, y, w, h);
g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h);
float padding = h / 8; float padding = h / 8;
@@ -619,7 +623,8 @@ public class CardImageRenderer {
} }
} }
//draw outline color here //draw outline color here
drawOutlineColor(g, state.getColors(), x, y, w, h); if (state != null)
drawOutlineColor(g, state.getColors(), x, y, w, h);
g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h);
if (!onTop) { if (!onTop) {
@@ -738,7 +743,8 @@ public class CardImageRenderer {
fillColorBackground(g, colors, x, y, w, h); fillColorBackground(g, colors, x, y, w, h);
//draw outline color here //draw outline color here
drawOutlineColor(g, state.getColors(), x, y, w, h); if (state != null)
drawOutlineColor(g, state.getColors(), x, y, w, h);
g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h);
if (noText) if (noText)

View File

@@ -30,7 +30,8 @@ public class AudioMusic implements IAudioMusic {
public void pause() { public void pause() {
if (music == null) if (music == null)
return; return;
music.pause(); if (music.isPlaying())
music.pause();
} }
public void resume() { public void resume() {

View File

@@ -4,7 +4,7 @@ Types:Enchantment
S:Mode$ ReduceCost | ValidCard$ Card | ValidSpell$ Activated.Equip | Activator$ You | Amount$ 1 | EffectZone$ Command | Description$ Equip costs you pay cost {1} less. S:Mode$ ReduceCost | ValidCard$ Card | ValidSpell$ Activated.Equip | Activator$ You | Amount$ 1 | EffectZone$ Command | Description$ Equip costs you pay cost {1} less.
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Secondary$ True | Execute $ TrigConjure | TriggerDescription$ At the beginning of your upkeep or when an equipped creature you control attacks, conjure a card from Nahiri's Spellbook into your hand. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Secondary$ True | Execute $ TrigConjure | TriggerDescription$ At the beginning of your upkeep or when an equipped creature you control attacks, conjure a card from Nahiri's Spellbook into your hand.
T:Mode$ Attacks | ValidCard$ Creature.YouCtrl+equipped | TriggerZones$ Command | Execute$ TrigConjure | TriggerDescription$ At the beginning of your upkeep or when an equipped creature you control attacks, conjure a card from Nahiri's Spellbook into your hand. T:Mode$ Attacks | ValidCard$ Creature.YouCtrl+equipped | TriggerZones$ Command | Execute$ TrigConjure | TriggerDescription$ At the beginning of your upkeep or when an equipped creature you control attacks, conjure a card from Nahiri's Spellbook into your hand.
SVar:TrigConjure:DB$ MakeCard | Zone$ Hand | Conjure$ True | AtRandom$ True | Spellbook$ Stoneforge Mystic,Danitha; Benalia's Hope,Ardenn, Intrepid Archaeologist,Open the Armory,Stone Haven Outfitter,Argentum Armor,Sword of the Animist,Masterwork of Ingenuity,Kaldra Compleat,Armored Skyhunter,Lion Sash,Relic Seeker,Esper Sentinel,Forgeborn Phoenix,Foundry Beetle,Inchblade Companion,Komainu Battle Armor,Luxior;Giada's Gift,Mace of Disruption,Nettlecyst,Shadowspear,Seraphic Greatsword,Soulstealer Axe,Sword of Body and Mind,Sword of Fire and Ice,Junkyard Scrapper,Soulstealer Axe,Sword of Feast and Famine,Expedition Supplier,Foundry Beetle,Armory Automaton,Bladegraft Aspirant,Dancing Sword,Jor Kadeen; First Goldwarden,Akiri; Fearless Voyager,Acclaimed Contender,Embercleave,Puresteel Paladin,Champion of the Flame,Tiana; Ship's Caretaker,Reyav; Master Smith,Sigarda's Aid,Armored Skyhunter,Bruenor Battlehammer,Halvar; God of Battle,Wyleth; Soul of Steel,Koll; the Forgemaster,Valduk; Keeper of the Flame,Fervent Champion,Cloudsteel Kirin,Leonin Shikari,Balan; Wandering Knight,Kor Duelist,Leonin Abunas,Zamriel;Seraph of Steel,Auriok Steelshaper SVar:TrigConjure:DB$ MakeCard | Zone$ Hand | Conjure$ True | AtRandom$ True | Spellbook$ Stoneforge Mystic,Danitha; Benalia's Hope,Ardenn; Intrepid Archaeologist,Open the Armory,Stone Haven Outfitter,Argentum Armor,Sword of the Animist,Masterwork of Ingenuity,Kaldra Compleat,Armored Skyhunter,Lion Sash,Relic Seeker,Esper Sentinel,Forgeborn Phoenix,Foundry Beetle,Inchblade Companion,Komainu Battle Armor,Luxior;Giada's Gift,Mace of Disruption,Nettlecyst,Shadowspear,Seraphic Greatsword,Soulstealer Axe,Sword of Body and Mind,Sword of Fire and Ice,Junkyard Scrapper,Soulstealer Axe,Sword of Feast and Famine,Expedition Supplier,Foundry Beetle,Armory Automaton,Bladegraft Aspirant,Dancing Sword,Jor Kadeen; First Goldwarden,Akiri; Fearless Voyager,Acclaimed Contender,Embercleave,Puresteel Paladin,Champion of the Flame,Tiana; Ship's Caretaker,Reyav; Master Smith,Sigarda's Aid,Armored Skyhunter,Bruenor Battlehammer,Halvar; God of Battle,Wyleth; Soul of Steel,Koll; the Forgemaster,Valduk; Keeper of the Flame,Fervent Champion,Cloudsteel Kirin,Leonin Shikari,Balan; Wandering Knight,Kor Duelist,Leonin Abunas,Zamriel; Seraph of Steel,Auriok Steelshaper
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, create a 1/1 white Kor Soldier creature token T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, create a 1/1 white Kor Soldier creature token
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_kor_soldier SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_kor_soldier
Oracle:Equip costs you pay cost {1} less.\nAt the beginning of your upkeep or whenever an equipped creature you control attacks, conjure a card from Nahiri's Spellbook into your hand\nAt the beginning of your end step, create a 1/1 white Kor Soldier creature token. Oracle:Equip costs you pay cost {1} less.\nAt the beginning of your upkeep or whenever an equipped creature you control attacks, conjure a card from Nahiri's Spellbook into your hand\nAt the beginning of your end step, create a 1/1 white Kor Soldier creature token.

View File

@@ -0,0 +1,12 @@
{
"name":"Fungus",
"template":
{
"count":60,
"colors":["Green","Black"],
"tribe":"Fungus",
"tribeCards":1.0,
"tribeSynergyCards":0.2,
"rares":0.2
}
}

View File

@@ -3,13 +3,13 @@
"height": 4300, "height": 4300,
"width": 2 "width": 2
}, },
"activeFile": "", "activeFile": "map/cave_6.tmx",
"automapping.whileDrawing": false, "automapping.whileDrawing": false,
"expandedProjectPaths": [ "expandedProjectPaths": [
"tileset",
"map/main_story",
"map", "map",
"obj" "obj",
"map/main_story",
"tileset"
], ],
"file.lastUsedOpenFilter": "All Files (*)", "file.lastUsedOpenFilter": "All Files (*)",
"fileStates": { "fileStates": {
@@ -110,24 +110,24 @@
"scale": 3, "scale": 3,
"selectedLayer": 0, "selectedLayer": 0,
"viewCenter": { "viewCenter": {
"x": 279.5, "x": 240,
"y": 217.5 "y": 136.16666666666663
} }
}, },
"map/castle_plains_2.tmx": { "map/castle_plains_2.tmx": {
"scale": 1.5, "scale": 1.5,
"selectedLayer": 0, "selectedLayer": 0,
"viewCenter": { "viewCenter": {
"x": 359.66666666666663, "x": 240,
"y": 295.33333333333326 "y": 136.33333333333334
} }
}, },
"map/castle_plains_3.tmx": { "map/castle_plains_3.tmx": {
"scale": 2, "scale": 2,
"selectedLayer": 4, "selectedLayer": 3,
"viewCenter": { "viewCenter": {
"x": 240, "x": 240,
"y": 136 "y": 136.25
} }
}, },
"map/catlair_1.tmx": { "map/catlair_1.tmx": {
@@ -174,8 +174,8 @@
"scale": 4, "scale": 4,
"selectedLayer": 0, "selectedLayer": 0,
"viewCenter": { "viewCenter": {
"x": 240, "x": 187.5,
"y": 239.875 "y": 316.625
} }
}, },
"map/cave_1.tmx": { "map/cave_1.tmx": {
@@ -428,8 +428,8 @@
"scale": 2, "scale": 2,
"selectedLayer": 4, "selectedLayer": 4,
"viewCenter": { "viewCenter": {
"x": 240.25, "x": 135,
"y": 136 "y": 119.75
} }
}, },
"map/cave_20.tmx": { "map/cave_20.tmx": {
@@ -1356,16 +1356,19 @@
"scale": 2, "scale": 2,
"selectedLayer": 0, "selectedLayer": 0,
"viewCenter": { "viewCenter": {
"x": 240.25, "x": 240,
"y": 136 "y": 136.25
} }
}, },
"map/cave_4.tmx": { "map/cave_4.tmx": {
"scale": 1, "expandedObjectLayers": [
"selectedLayer": 2, 4
],
"scale": 2,
"selectedLayer": 3,
"viewCenter": { "viewCenter": {
"x": 220, "x": 145,
"y": 135 "y": 151.75
} }
}, },
"map/cave_5.tmx": { "map/cave_5.tmx": {
@@ -1373,15 +1376,15 @@
"selectedLayer": 0, "selectedLayer": 0,
"viewCenter": { "viewCenter": {
"x": 232, "x": 232,
"y": 136 "y": 136.25
} }
}, },
"map/cave_6.tmx": { "map/cave_6.tmx": {
"scale": 2, "scale": 2,
"selectedLayer": 0, "selectedLayer": 0,
"viewCenter": { "viewCenter": {
"x": 232, "x": 337,
"y": 136 "y": 152.75
} }
}, },
"map/cave_6N1.tmx": { "map/cave_6N1.tmx": {
@@ -3206,10 +3209,10 @@
4 4
], ],
"scale": 2, "scale": 2,
"selectedLayer": 4, "selectedLayer": 0,
"viewCenter": { "viewCenter": {
"x": 390.5, "x": 329.5,
"y": 221.75 "y": 204.25
} }
}, },
"map/yule_town.tmx": { "map/yule_town.tmx": {
@@ -3251,22 +3254,31 @@
"map.tileWidth": 16, "map.tileWidth": 16,
"map.width": 90, "map.width": 90,
"openFiles": [ "openFiles": [
"map/xira.tmx",
"map/castle_plains_1.tmx",
"map/castle_plains_2.tmx",
"map/castle_plains_3.tmx",
"map/cave_2.tmx",
"map/cave_3.tmx",
"map/cave_4.tmx",
"map/cave_5.tmx",
"map/cave_6.tmx"
], ],
"project": "main.tiled-project", "project": "main.tiled-project",
"property.type": "string", "property.type": "string",
"recentFiles": [ "recentFiles": [
"map/main_story/templeofchandra.tmx",
"map/tibalt.tmx",
"map/tibalt_f1.tmx",
"map/xira.tmx", "map/xira.tmx",
"map/nahiricave.tmx", "map/castle_plains_1.tmx",
"map/nahiri.tmx", "map/castle_plains_2.tmx",
"map/grolnok.tmx", "map/castle_plains_3.tmx",
"map/tibalt_f2.tmx", "map/cave_2.tmx",
"map/cursed_swamp.tmx", "map/cave_3.tmx",
"map/slobad_factory.tmx", "map/cave_4.tmx",
"map/main_story/blue_castle_f1.tmx", "map/cave_5.tmx",
"map/kiora_island.tmx" "map/cave_6.tmx",
"map/cave_1..tmx",
"map/main_story/templeofchandra.tmx",
"map/tibalt.tmx"
], ],
"resizeMap.removeObjects": true, "resizeMap.removeObjects": true,
"textEdit.monospace": true "textEdit.monospace": true

View File

@@ -10,7 +10,7 @@
<tileset firstgid="10113" source="../tileset/buildings.tsx"/> <tileset firstgid="10113" source="../tileset/buildings.tsx"/>
<layer id="11" name="Collision" width="40" height="26"> <layer id="11" name="Collision" width="40" height="26">
<data encoding="base64" compression="zlib"> <data encoding="base64" compression="zlib">
eJzVlUkOgCAMRdl6Me9/JFcmhkCHP2hswgp++0pbOI8xzh+tlb2lj3SIVbURRyevbtz7LGORPspJ4b+i/ZIv85P1oKK2We9UOJ+aiI+ZlZ3fynxX+Jxs816kc/KtajHzIf5Ud6c2BZ8rN0fvKQydLSbeM+7M4GBD3l12ddm6+VffPwVfplH1DlNf9M9C4nT/N3aeunF2nNFfhDJltXfNDcOInGHjZ+cqewo+5/2z86uu/8p/961w9ucuhnsxDBe0OnBV eJzVl11uwkAMhHnMPsBtegWKckDOgNqehjOgwjHIKrLqjDz+WZUHRhopJNn1F6/3h2Pb7Y5v5NPi7+nPXZX2uq12tq2WfuYpionfg0IO65nV1sqdvh9pTr53a1sjQ+a7Ti3XZoSPSWLflbN8+NviiPgidhy/DB/jxVhz8+tAP2Pv4Liz2hQei81jZHPCm6OePD6PDd+NYjCmbL4rfJU84JhafDh/u9j6lGWTa0vn/WqMgzG99ZGpwhf18XGoxa6yZfis2rweVr+Sy1tTIr5MPN0f67vCZvWB7BHTf9tbVzSflY8Kl9SD5VG+aNwz+cvUqWbFfrJ8LHcsjrBpXabVkTAXbMxG1h3Nqpku6twYcbJ9ITN3qvJq65PUDzLgPTlXjKwrFcYMX/fXkuufactm7ZeZ+Jb6WEv/3p7LWHueZnXNpM+60XpiKbsPsxpj7YULc47nzJHcix7kO3/b9n+AZdZOz03L7DvRjO3V9sYt8hMoNu4z
</data> </data>
</layer> </layer>
<layer id="8" name="Background" width="40" height="26"> <layer id="8" name="Background" width="40" height="26">

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -130,7 +130,7 @@ WalkDown
xy: 144, 16 xy: 144, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 160, 0 xy: 160, 16
size: 16, 16 size: 16, 16
WalkDown WalkDown
xy: 176, 16 xy: 176, 16

View File

@@ -351,7 +351,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 6 "addMaxCount": 6,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
@@ -1241,12 +1245,16 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 4 "addMaxCount": 4,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
"probability": 0.5, "probability": 0.5,
"count": 3, "count": 1,
"colors": [ "colors": [
"Green" "Green"
], ],
@@ -1330,7 +1338,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 4 "addMaxCount": 5,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
@@ -2830,7 +2842,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 4 "addMaxCount": 5,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "gold", "type": "gold",
@@ -3366,7 +3382,7 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 4
}, },
{ {
"type": "card", "type": "card",
@@ -3397,7 +3413,7 @@
{ {
"type": "card", "type": "card",
"probability": 1, "probability": 1,
"count": 3, "count": 1,
"colors": [ "colors": [
"Blue" "Blue"
], ],
@@ -4153,7 +4169,7 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 4
}, },
{ {
"type": "card", "type": "card",
@@ -4471,7 +4487,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 4,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
@@ -4519,7 +4539,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 5,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
@@ -4643,7 +4667,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 4,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
@@ -5087,7 +5115,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 4 "addMaxCount": 8,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
@@ -6524,7 +6556,7 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 4
}, },
{ {
"type": "card", "type": "card",
@@ -6755,7 +6787,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 4 "addMaxCount": 6,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "gold", "type": "gold",
@@ -6794,7 +6830,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 4 "addMaxCount": 4,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "gold", "type": "gold",
@@ -6802,23 +6842,6 @@
"count": 10, "count": 10,
"addMaxCount": 90 "addMaxCount": 90
}, },
{
"type": "card",
"probability": 0.5,
"count": 2,
"colors": [
"Green"
],
"rarity": [
"Mythic Rare"
]
},
{
"type": "deckCard",
"probability": 1,
"count": 2,
"addMaxCount": 8
},
{ {
"type": "card", "type": "card",
"probability": 1, "probability": 1,
@@ -7303,7 +7326,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 8,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
@@ -7349,7 +7376,7 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 4
}, },
{ {
"type": "card", "type": "card",
@@ -8432,7 +8459,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 4 "addMaxCount": 4,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "gold", "type": "gold",
@@ -9187,7 +9218,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 8,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
@@ -9866,7 +9901,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 3, "count": 3,
"addMaxCount": 7 "addMaxCount": 6,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "gold", "type": "gold",
@@ -10194,7 +10233,11 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 8,
"rarity": [
"common",
"uncommon"
]
}, },
{ {
"type": "card", "type": "card",
@@ -10716,7 +10759,7 @@
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 2, "count": 2,
"addMaxCount": 8 "addMaxCount": 4
}, },
{ {
"type": "card", "type": "card",
@@ -11219,18 +11262,11 @@
{ {
"type": "deckCard", "type": "deckCard",
"probability": 1, "probability": 1,
"count": 1, "count": 2,
"addMaxCount": 4, "addMaxCount": 8,
"rarity": [ "rarity": [
"common", "common",
"uncommon" "uncommon"
],
"cardTypes": [
"Creature",
"Artifact",
"Enchantment",
"Instant",
"Sorcery"
] ]
}, },
{ {

View File

@@ -45,7 +45,6 @@
"Fox", "Fox",
"Frost Titan", "Frost Titan",
"Griffin", "Griffin",
"Horse",
"Horseman", "Horseman",
"Human", "Human",
"Human elite", "Human elite",

Binary file not shown.

Binary file not shown.

View File

@@ -119,3 +119,4 @@ Dominaria Remastered, 3/6/DMR, DMR
Phyrexia: All Will Be One, 3/6/ONE, ONE Phyrexia: All Will Be One, 3/6/ONE, ONE
Phyrexia: All Will Be One Jumpstart, -/2/ONE, Meta-Choose(S(ONE Mite-y 1)Mite-y 1;S(ONE Mite-y 2)Mite-y 2;S(ONE Progress 1)Progress 1;S(ONE Progress 2)Progress 2;S(ONE Corruption 1)Corruption 1;S(ONE Corruption 2)Corruption 2;S(ONE Rebellious 1)Rebellious 1;S(ONE Rebellious 2)Rebellious 2;S(ONE Toxic 1)Toxic 1;S(ONE Toxic 2)Toxic 2)Themes Phyrexia: All Will Be One Jumpstart, -/2/ONE, Meta-Choose(S(ONE Mite-y 1)Mite-y 1;S(ONE Mite-y 2)Mite-y 2;S(ONE Progress 1)Progress 1;S(ONE Progress 2)Progress 2;S(ONE Corruption 1)Corruption 1;S(ONE Corruption 2)Corruption 2;S(ONE Rebellious 1)Rebellious 1;S(ONE Rebellious 2)Rebellious 2;S(ONE Toxic 1)Toxic 1;S(ONE Toxic 2)Toxic 2)Themes
Alchemy: Phyrexia, 3/6/ONE, YONE Alchemy: Phyrexia, 3/6/ONE, YONE
Shadows over Innistrad Remastered, 3/6/SIR, SIR

View File

@@ -4,7 +4,7 @@ Types:Creature Goblin Artificer
PT:1/2 PT:1/2
S:Mode$ Continuous | Affected$ Creature.modified+YouCtrl | AddKeyword$ Menace | Description$ Modified creatures you control have menace. S:Mode$ Continuous | Affected$ Creature.modified+YouCtrl | AddKeyword$ Menace | Description$ Modified creatures you control have menace.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, you may discard a card. If you do, seek a card with mana value equal to that card's mana value. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, you may discard a card. If you do, seek a card with mana value equal to that card's mana value.
SVar:TrigSeek:AB$ ChangeZone | Cost$ Discard<1/Card> | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.cmcEQX | ChangeNum$ 1 SVar:TrigSeek:AB$ Seek | Cost$ Discard<1/Card> | Type$ Card.cmcEQX
SVar:X:Discarded$CardManaCost SVar:X:Discarded$CardManaCost
DeckHas:Ability$Discard & Keyword$Menace DeckHas:Ability$Discard & Keyword$Menace
DeckHints:Type$Equipment|Aura & Ability$Counters DeckHints:Type$Equipment|Aura & Ability$Counters

View File

@@ -3,6 +3,8 @@ ManaCost:R G W
Types:Creature Elf Druid Types:Creature Elf Druid
PT:3/4 PT:3/4
T:Mode$ ChangesZoneAll | ValidCards$ Creature.Other+YouCtrl | Destination$ Battlefield | TriggerZones$ Battlefield | ActivationLimit$ 1 | Execute$ TrigSeek | TriggerDescription$ Alliance — Whenever one or more other creatures enter the battlefield under your control, seek a land card, then put it onto the battlefield tapped. This ability triggers only once each turn. T:Mode$ ChangesZoneAll | ValidCards$ Creature.Other+YouCtrl | Destination$ Battlefield | TriggerZones$ Battlefield | ActivationLimit$ 1 | Execute$ TrigSeek | TriggerDescription$ Alliance — Whenever one or more other creatures enter the battlefield under your control, seek a land card, then put it onto the battlefield tapped. This ability triggers only once each turn.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Land | ChangeNum$ 1 | Tapped$ True SVar:TrigSeek:DB$ Seek | Type$ Land | RememberFound$ True | SubAbility$ DBPut
SVar:DBPut:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Defined$ Remembered | Tapped$ True | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:BuffedBy:Creature SVar:BuffedBy:Creature
Oracle:Alliance — Whenever one or more other creatures enter the battlefield under your control, seek a land card, then put it onto the battlefield tapped. This ability triggers only once each turn. Oracle:Alliance — Whenever one or more other creatures enter the battlefield under your control, seek a land card, then put it onto the battlefield tapped. This ability triggers only once each turn.

View File

@@ -1,9 +1,8 @@
Name:Bounty of the Deep Name:Bounty of the Deep
ManaCost:2 U ManaCost:2 U
Types:Sorcery Types:Sorcery
A:SP$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE1 | TrueSubAbility$ Seek2NonLand | FalseSubAbility$ Seek1Land | StackDescription$ SpellDescription | SpellDescription$ If you have no land cards in your hand, seek a land card and a nonland card. Otherwise, seek two nonland cards. A:SP$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE1 | TrueSubAbility$ Seek2 | FalseSubAbility$ Seek1 | StackDescription$ SpellDescription | SpellDescription$ If you have no land cards in your hand, seek a land card and a nonland card. Otherwise, seek two nonland cards.
SVar:Seek1Land:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.Land | ChangeNum$ 1 | SubAbility$ Seek1NonLand SVar:Seek1:DB$ Seek | Types$ Card.Land,Card.nonLand
SVar:Seek1NonLand:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.nonLand | ChangeNum$ 1 SVar:Seek2:DB$ Seek | Type$ Card.nonLand | Num$ 2
SVar:Seek2NonLand:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.nonLand | ChangeNum$ 2
SVar:X:Count$ValidHand Land.YouCtrl SVar:X:Count$ValidHand Land.YouCtrl
Oracle:If you have no land cards in your hand, seek a land card and a nonland card. Otherwise, seek two nonland cards. Oracle:If you have no land cards in your hand, seek a land card and a nonland card. Otherwise, seek two nonland cards.

View File

@@ -2,7 +2,9 @@ Name:Cabaretti Revels
ManaCost:R R G ManaCost:R R G
Types:Enchantment Types:Enchantment
T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSeek | TriggerDescription$ Whenever you cast a creature spell, seek a creature card with lesser mana value, then put it onto the battlefield. T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSeek | TriggerDescription$ Whenever you cast a creature spell, seek a creature card with lesser mana value, then put it onto the battlefield.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Creature.cmcLTX SVar:TrigSeek:DB$ Seek | Type$ Creature.cmcLTX | RememberFound$ True | SubAbility$ DBPut
SVar:DBPut:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Defined$ Remembered | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:TriggeredCard$CardManaCost SVar:X:TriggeredCard$CardManaCost
SVar:BuffedBy:Creature SVar:BuffedBy:Creature
Oracle:Whenever you cast a creature spell, seek a creature card with lesser mana value, then put it onto the battlefield. Oracle:Whenever you cast a creature spell, seek a creature card with lesser mana value, then put it onto the battlefield.

View File

@@ -5,9 +5,9 @@ PT:4/5
K:Flying K:Flying
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ Whenever CARDNAME attacks or dies, ABILITY T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ Whenever CARDNAME attacks or dies, ABILITY
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigCharm | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or dies, ABILITY T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigCharm | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or dies, ABILITY
SVar:TrigCharm:DB$ Charm | CharmNum$ 2 | Choices$ DiscardSeek,DamageTreasures,DamagePump | AdditionalDescription$ Each mode must target a different player. SVar:TrigCharm:DB$ Charm | CharmNum$ 2 | Choices$ DiscardSeek,DamageTreasures,DamagePump | AdditionalDescription$ . Each mode must target a different player.
SVar:DiscardSeek:DB$ Discard | ValidTgts$ Player | TargetUnique$ True | TgtPrompt$ Select target player to discard hand and seek | Mode$ Hand | RememberDiscarded$ True | SubAbility$ DBSeek | SpellDescription$ Target player discards all cards in their hand, then seeks that many nonland cards. SVar:DiscardSeek:DB$ Discard | ValidTgts$ Player | TargetUnique$ True | Mode$ Hand | RememberDiscarded$ True | SubAbility$ DBSeek | SpellDescription$ Target player discards all cards in their hand, then seeks that many nonland cards.
SVar:DBSeek:DB$ ChangeZone | Defined$ ParentTarget | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ X | ChangeType$ Card.nonLand | SubAbility$ DBCleanup SVar:DBSeek:DB$ Seek | Defined$ Targeted | Num$ X | Type$ Card.nonLand | SubAbility$ DBCleanup
SVar:DamageTreasures:DB$ DealDamage | ValidTgts$ Player | TargetUnique$ True | TgtPrompt$ Select target player to take 2 damage and create two Treasures | NumDmg$ 2 | SubAbility$ DBToken | SpellDescription$ CARDNAME deals 2 damage to target player and they create two Treasure tokens. SVar:DamageTreasures:DB$ DealDamage | ValidTgts$ Player | TargetUnique$ True | TgtPrompt$ Select target player to take 2 damage and create two Treasures | NumDmg$ 2 | SubAbility$ DBToken | SpellDescription$ CARDNAME deals 2 damage to target player and they create two Treasure tokens.
SVar:DBToken:DB$ Token | TokenScript$ c_a_treasure_sac | TokenAmount$ 2 | TokenOwner$ ParentTarget SVar:DBToken:DB$ Token | TokenScript$ c_a_treasure_sac | TokenAmount$ 2 | TokenOwner$ ParentTarget
SVar:DamagePump:DB$ DamageAll | ValidTgts$ Player | TargetUnique$ True | NumDmg$ 2 | RememberDamaged$ True | ValidCards$ Creature | ValidDescription$ each creature target player controls. | SubAbility$ DBEffect | SpellDescription$ CARDNAME deals 2 damage to each creature target player controls. Those creatures perpetually get +2/+0. SVar:DamagePump:DB$ DamageAll | ValidTgts$ Player | TargetUnique$ True | NumDmg$ 2 | RememberDamaged$ True | ValidCards$ Creature | ValidDescription$ each creature target player controls. | SubAbility$ DBEffect | SpellDescription$ CARDNAME deals 2 damage to each creature target player controls. Those creatures perpetually get +2/+0.

View File

@@ -1,9 +1,9 @@
Name:Choice of Fortunes Name:Choice of Fortunes
ManaCost:2 U ManaCost:2 U
Types:Sorcery Types:Sorcery
A:SP$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card | ChangeNum$ 2 | RememberChanged$ True | SubAbility$ DBShuffle | StackDescription$ SpellDescription | SpellDescription$ Seek two cards. A:SP$ Seek | Num$ 2 | RememberFound$ True | SubAbility$ DBShuffle | SpellDescription$ Seek two cards.
SVar:DBShuffle:DB$ ChangeZone | Optional$ True | Defined$ Remembered | Origin$ Hand | Destination$ Library | Shuffle$ True | ForgetChanged$ True | SubAbility$ DBSeek | StackDescription$ SpellDescription | SpellDescription$ You may shuffle them into your library. SVar:DBShuffle:DB$ ChangeZone | Optional$ True | Defined$ Remembered | Origin$ Hand | Destination$ Library | Shuffle$ True | ForgetChanged$ True | SubAbility$ DBSeek | StackDescription$ SpellDescription | SpellDescription$ You may shuffle them into your library.
SVar:DBSeek:DB$ ChangeZone | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0 | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card | ChangeNum$ 2 | SubAbility$ DBCleanup | StackDescription$ SpellDescription | SpellDescription$ If you do, seek two cards. SVar:DBSeek:DB$ Seek | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0 | Num$ 2 | SubAbility$ DBCleanup | SpellDescription$ If you do, seek two cards.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBEffect SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | StaticAbilities$ STHandSize | Duration$ Permanent | SpellDescription$ You have no maximum hand size for the rest of the game. SVar:DBEffect:DB$ Effect | StaticAbilities$ STHandSize | Duration$ Permanent | SpellDescription$ You have no maximum hand size for the rest of the game.
SVar:STHandSize:Mode$ Continuous | EffectZone$ Command | Affected$ You | SetMaxHandSize$ Unlimited | Description$ You have no maximum hand size for the rest of the game. SVar:STHandSize:Mode$ Continuous | EffectZone$ Command | Affected$ You | SetMaxHandSize$ Unlimited | Description$ You have no maximum hand size for the rest of the game.

View File

@@ -5,8 +5,8 @@ PT:3/3
T:Mode$ Phase | Phase$ End of Turn | OptionalDecider$ You | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, you may discard a card. If you do, create a Treasure token and choose ambitious or expedient. If you chose ambitious, seek a card with greater mana value than the discarded card. If you chose expedient, seek a card with lesser mana value than the discarded card. T:Mode$ Phase | Phase$ End of Turn | OptionalDecider$ You | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, you may discard a card. If you do, create a Treasure token and choose ambitious or expedient. If you chose ambitious, seek a card with greater mana value than the discarded card. If you chose expedient, seek a card with lesser mana value than the discarded card.
SVar:TrigToken:AB$ Token | Cost$ Discard<1/Card> | TokenScript$ c_a_treasure_sac | SubAbility$ DBChoose SVar:TrigToken:AB$ Token | Cost$ Discard<1/Card> | TokenScript$ c_a_treasure_sac | SubAbility$ DBChoose
SVar:DBChoose:DB$ GenericChoice | Choices$ Ambitious,Expedient | Defined$ You | AILogic$ Random SVar:DBChoose:DB$ GenericChoice | Choices$ Ambitious,Expedient | Defined$ You | AILogic$ Random
SVar:Ambitious:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.cmcGTX | ChangeNum$ 1 | SpellDescription$ Ambitious - Seek a card with greater mana value than the discarded card. SVar:Ambitious:DB$ Seek | Type$ Card.cmcGTX | SpellDescription$ Ambitious - Seek a card with greater mana value than the discarded card.
SVar:Expedient:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.cmcLTX | ChangeNum$ 1 | SpellDescription$ Expedient - Seek a card with lesser mana value than the discarded card. SVar:Expedient:DB$ Seek | Type$ Card.cmcLTX | SpellDescription$ Expedient - Seek a card with lesser mana value than the discarded card.
DeckHas:Ability$Sacrifice|Token|Discard & Type$Treasure|Artifact DeckHas:Ability$Sacrifice|Token|Discard & Type$Treasure|Artifact
SVar:X:Discarded$CardManaCost SVar:X:Discarded$CardManaCost
Oracle:At the beginning of your end step, you may discard a card. If you do, create a Treasure token and choose ambitious or expedient. If you chose ambitious, seek a card with greater mana value than the discarded card. If you chose expedient, seek a card with lesser mana value than the discarded card. Oracle:At the beginning of your end step, you may discard a card. If you do, create a Treasure token and choose ambitious or expedient. If you chose ambitious, seek a card with greater mana value than the discarded card. If you chose expedient, seek a card with lesser mana value than the discarded card.

View File

@@ -8,7 +8,7 @@ T:Mode$ Drawn | ValidCard$ Card.YouOwn+Dragon | TriggerZones$ Battlefield | Exec
SVar:DBEffect:DB$ Effect | StaticAbilities$ PerpetualP1P1 | RememberObjects$ TriggeredCard | Name$ Darigaaz's Whelp's Perpetual Effect | Duration$ Permanent SVar:DBEffect:DB$ Effect | StaticAbilities$ PerpetualP1P1 | RememberObjects$ TriggeredCard | Name$ Darigaaz's Whelp's Perpetual Effect | Duration$ Permanent
SVar:PerpetualP1P1:Mode$ Continuous | Affected$ Card.IsRemembered | AddPower$ 1 | AddToughness$ 1 | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ This card perpetually gets +1/+1. SVar:PerpetualP1P1:Mode$ Continuous | Affected$ Card.IsRemembered | AddPower$ 1 | AddToughness$ 1 | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ This card perpetually gets +1/+1.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+kicked | Execute$ TrigSeek | TriggerDescription$ When this creature enters the battlefield, if it was kicked, seek a Dragon card. CARDNAME and that Dragon card each perpetually get +1/+1. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+kicked | Execute$ TrigSeek | TriggerDescription$ When this creature enters the battlefield, if it was kicked, seek a Dragon card. CARDNAME and that Dragon card each perpetually get +1/+1.
SVar:TrigSeek:DB$ ChangeZone | RememberChanged$ True | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.Dragon | SubAbility$ DBEffectBis SVar:TrigSeek:DB$ Seek | RememberFound$ True | Type$ Card.Dragon | SubAbility$ DBEffectBis
SVar:DBEffectBis:DB$ Effect | StaticAbilities$ PerpetualP1P1Bis | RememberObjects$ Remembered | Name$ Darigaaz's Whelp's Perpetual Effect | Duration$ Permanent | SubAbility$ DBCleanup SVar:DBEffectBis:DB$ Effect | StaticAbilities$ PerpetualP1P1Bis | RememberObjects$ Remembered | Name$ Darigaaz's Whelp's Perpetual Effect | Duration$ Permanent | SubAbility$ DBCleanup
SVar:PerpetualP1P1Bis:Mode$ Continuous | Affected$ Card.IsRemembered,Card.EffectSource | AddPower$ 1 | AddToughness$ 1 | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ CARDNAME and the conjured Dragon card each perpetually get +1/+1. SVar:PerpetualP1P1Bis:Mode$ Continuous | Affected$ Card.IsRemembered,Card.EffectSource | AddPower$ 1 | AddToughness$ 1 | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ CARDNAME and the conjured Dragon card each perpetually get +1/+1.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True

View File

@@ -5,6 +5,6 @@ PT:2/1
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigConnive | TriggerDescription$ When CARDNAME enters the battlefield, it connives. (Draw a card, then discard a card. If you discarded a nonland card, put a +1/+1 counter on this creature.) T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigConnive | TriggerDescription$ When CARDNAME enters the battlefield, it connives. (Draw a card, then discard a card. If you discarded a nonland card, put a +1/+1 counter on this creature.)
SVar:TrigConnive:DB$ Connive SVar:TrigConnive:DB$ Connive
T:Mode$ DiscardedAll | ValidPlayer$ You | ValidCard$ Card | TriggerZones$ Battlefield | Execute$ TrigSeek | ActivationLimit$ 1 | TriggerDescription$ Whenever you discard one or more cards, seek a card that shares a card type with one of the discarded cards. This ability triggers only once each turn. T:Mode$ DiscardedAll | ValidPlayer$ You | ValidCard$ Card | TriggerZones$ Battlefield | Execute$ TrigSeek | ActivationLimit$ 1 | TriggerDescription$ Whenever you discard one or more cards, seek a card that shares a card type with one of the discarded cards. This ability triggers only once each turn.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.sharesCardTypeWith TriggeredCards | ChangeNum$ 1 SVar:TrigSeek:DB$ Seek | Type$ Card.sharesCardTypeWith TriggeredCards
DeckHas:Ability$Discard|Counters DeckHas:Ability$Discard|Counters
Oracle:When Diviner of Fates enters the battlefield, it connives.\nWhenever you discard one or more cards, seek a card that shares a card type with one of the discarded cards. This ability triggers only once each turn. Oracle:When Diviner of Fates enters the battlefield, it connives.\nWhenever you discard one or more cards, seek a card that shares a card type with one of the discarded cards. This ability triggers only once each turn.

View File

@@ -4,5 +4,5 @@ Types:Creature Shapeshifter
PT:2/2 PT:2/2
K:Changeling K:Changeling
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, seek a creature card of the most prevalent creature type in your library. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, seek a creature card of the most prevalent creature type in your library.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.Creature+MostProminentCreatureTypeInLibrary | ChangeNum$ 1 SVar:TrigSeek:DB$ Seek | Type$ Card.Creature+MostProminentCreatureTypeInLibrary
Oracle:Changeling\nWhen Faceless Agent enters the battlefield, seek a creature card of the most prevalent creature type in your library. Oracle:Changeling\nWhen Faceless Agent enters the battlefield, seek a creature card of the most prevalent creature type in your library.

View File

@@ -2,7 +2,7 @@ Name:Faith Unbroken
ManaCost:3 W ManaCost:3 W
Types:Enchantment Aura Types:Enchantment Aura
K:Enchant creature you control K:Enchant creature you control
A:SP$ Attach | Cost$ 3 W | ValidTgts$ Creature | AILogic$ Pump A:SP$ Attach | Cost$ 3 W | ValidTgts$ Creature.YouCtrl | AILogic$ Pump
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters the battlefield, exile target creature an opponent controls until CARDNAME leaves the battlefield. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters the battlefield, exile target creature an opponent controls until CARDNAME leaves the battlefield.
SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | Duration$ UntilHostLeavesPlay SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | Duration$ UntilHostLeavesPlay
SVar:PlayMain1:TRUE SVar:PlayMain1:TRUE

View File

@@ -3,10 +3,9 @@ ManaCost:1 R
Types:Creature Human Wizard Types:Creature Human Wizard
PT:2/2 PT:2/2
K:Prowess K:Prowess
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | CheckSVar$ Z | SVarCompare$ GE20 | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, if there are twenty or more instant and/or sorcery cards among cards in your graveyard, hand, and library, you may discard a card. If you do, seek an instant or sorcery card. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | CheckSVar$ X | SVarCompare$ GE20 | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, if there are twenty or more instant and/or sorcery cards among cards in your graveyard, hand, and library, you may discard a card. If you do, seek an instant or sorcery card.
SVar:TrigSeek:AB$ ChangeZone | Cost$ Discard<1/Card> | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Instant,Sorcery SVar:TrigSeek:AB$ Seek | Cost$ Discard<1/Card> | Type$ Instant,Sorcery
SVar:X:Count$ValidGraveyard Instant.YouOwn,Sorcery.YouOwn SVar:X:Count$ValidGraveyard,Library,Hand Instant.YouOwn,Sorcery.YouOwn
SVar:Y:Count$ValidLibrary Instant.YouOwn,Sorcery.YouOwn/Plus.X
SVar:Z:Count$ValidHand Instant.YouOwn,Sorcery.YouOwn/Plus.Y
DeckNeeds:Type$Instant|Sorcery DeckNeeds:Type$Instant|Sorcery
DeckHas:Ability$Discard
Oracle:When Frenzied Geistblaster enters the battlefield, if there are twenty or more instant and/or sorcery cards among cards in your graveyard, hand, and library, you may discard a card. If you do, seek an instant or sorcery card. Oracle:When Frenzied Geistblaster enters the battlefield, if there are twenty or more instant and/or sorcery cards among cards in your graveyard, hand, and library, you may discard a card. If you do, seek an instant or sorcery card.

View File

@@ -7,7 +7,7 @@ SVar:DBRandom:DB$ ChooseCard | Defined$ You | Choices$ Elf.YouOwn | ChoiceZone$
SVar:DBEffect:DB$ Effect | RememberObjects$ Targeted | StaticAbilities$ PerpetualP1P1 | Name$ Freyalise, Skyshroud Partisan's Perpetual Effect | Duration$ Permanent | SubAbility$ DBCleanup SVar:DBEffect:DB$ Effect | RememberObjects$ Targeted | StaticAbilities$ PerpetualP1P1 | Name$ Freyalise, Skyshroud Partisan's Perpetual Effect | Duration$ Permanent | SubAbility$ DBCleanup
SVar:PerpetualP1P1:Mode$ Continuous | Affected$ Card.IsRemembered,Card.ChosenCard | AddPower$ 1 | AddToughness$ 1 | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ The target Elf and randomly chosen card perpetually get +1/+1. SVar:PerpetualP1P1:Mode$ Continuous | Affected$ Card.IsRemembered,Card.ChosenCard | AddPower$ 1 | AddToughness$ 1 | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ The target Elf and randomly chosen card perpetually get +1/+1.
SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True
A:AB$ ChangeZone | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.Elf | ChangeNum$ 1 | StackDescription$ SpellDescription | SpellDescription$ Seek an Elf card. A:AB$ Seek | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | Type$ Card.Elf | StackDescription$ REP Seek_{p:You} seeks | SpellDescription$ Seek an Elf card.
A:AB$ MakeCard | Conjure$ True | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Regal Force | Zone$ Battlefield | SpellDescription$ Conjure a Regal Force card onto the battlefield. A:AB$ MakeCard | Conjure$ True | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Regal Force | Zone$ Battlefield | SpellDescription$ Conjure a Regal Force card onto the battlefield.
DeckNeeds:Type$Elf DeckNeeds:Type$Elf
Oracle:[+1]: Choose up to one target Elf. Untap it. It and a random Elf creature card in your hand each perpetually gets +1/+1.\n[-1]: Seek an Elf card.\n[-6]: Conjure a Regal Force card onto the battlefield. Oracle:[+1]: Choose up to one target Elf. Untap it. It and a random Elf creature card in your hand each perpetually gets +1/+1.\n[-1]: Seek an Elf card.\n[-6]: Conjure a Regal Force card onto the battlefield.

View File

@@ -2,7 +2,7 @@ Name:Gate of the Black Dragon
ManaCost:no cost ManaCost:no cost
Types:Land Swamp Gate Types:Land Swamp Gate
K:CARDNAME enters the battlefield tapped. K:CARDNAME enters the battlefield tapped.
A:AB$ ChangeZone | Cost$ 3 B T | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ SpellDescription | SpellDescription$ Seek a nonland card. Activate only once. A:AB$ Seek | Cost$ 3 B T | Type$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ {p:You} seeks a nonland card. | SpellDescription$ Seek a nonland card. Activate only once.
Text:{T}: Add {B}. Text:{T}: Add {B}.
DeckHints:Type$Gate DeckHints:Type$Gate
Oracle:Gate of the Black Dragon enters the battlefield tapped.\n{3}{B}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {B}. Oracle:Gate of the Black Dragon enters the battlefield tapped.\n{3}{B}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {B}.

View File

@@ -2,7 +2,7 @@ Name:Gate to Manorborn
ManaCost:no cost ManaCost:no cost
Types:Land Forest Gate Types:Land Forest Gate
K:CARDNAME enters the battlefield tapped. K:CARDNAME enters the battlefield tapped.
A:AB$ ChangeZone | Cost$ 3 G T | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ SpellDescription | SpellDescription$ Seek a nonland card. Activate only once. A:AB$ Seek | Cost$ 3 G T | Type$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ {p:You} seeks a nonland card. | SpellDescription$ Seek a nonland card. Activate only once.
Text:{T}: Add {G}. Text:{T}: Add {G}.
DeckHints:Type$Gate DeckHints:Type$Gate
Oracle:Gate to Manorborn enters the battlefield tapped.\n{3}{G}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {G}. Oracle:Gate to Manorborn enters the battlefield tapped.\n{3}{G}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {G}.

View File

@@ -2,7 +2,7 @@ Name:Gate to Seatower
ManaCost:no cost ManaCost:no cost
Types:Land Island Gate Types:Land Island Gate
K:CARDNAME enters the battlefield tapped. K:CARDNAME enters the battlefield tapped.
A:AB$ ChangeZone | Cost$ 3 U T | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ SpellDescription | SpellDescription$ Seek a nonland card. Activate only once. A:AB$ Seek | Cost$ 3 U T | Type$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ {p:You} seeks a nonland card. | SpellDescription$ Seek a nonland card. Activate only once.
Text:{T}: Add {U}. Text:{T}: Add {U}.
DeckHints:Type$Gate DeckHints:Type$Gate
Oracle:Gate to Seatower enters the battlefield tapped.\n{3}{U}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {U}. Oracle:Gate to Seatower enters the battlefield tapped.\n{3}{U}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {U}.

View File

@@ -2,7 +2,7 @@ Name:Gate to the Citadel
ManaCost:no cost ManaCost:no cost
Types:Land Plains Gate Types:Land Plains Gate
K:CARDNAME enters the battlefield tapped. K:CARDNAME enters the battlefield tapped.
A:AB$ ChangeZone | Cost$ 3 W T | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ SpellDescription | SpellDescription$ Seek a nonland card. Activate only once. A:AB$ Seek | Cost$ 3 W T | Type$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ {p:You} seeks a nonland card. | SpellDescription$ Seek a nonland card. Activate only once.
Text:{T}: Add {W}. Text:{T}: Add {W}.
DeckHints:Type$Gate DeckHints:Type$Gate
Oracle:Gate to the Citadel enters the battlefield tapped.\n{3}{W}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {W}. Oracle:Gate to the Citadel enters the battlefield tapped.\n{3}{W}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {W}.

View File

@@ -2,7 +2,7 @@ Name:Gate to Tumbledown
ManaCost:no cost ManaCost:no cost
Types:Land Mountain Gate Types:Land Mountain Gate
K:CARDNAME enters the battlefield tapped. K:CARDNAME enters the battlefield tapped.
A:AB$ ChangeZone | Cost$ 3 R T | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ SpellDescription | SpellDescription$ Seek a nonland card. Activate only once. A:AB$ Seek | Cost$ 3 R T | Type$ Card.nonLand | GameActivationLimit$ 1 | StackDescription$ {p:You} seeks a nonland card. | SpellDescription$ Seek a nonland card. Activate only once.
Text:{T}: Add {R}. Text:{T}: Add {R}.
DeckHints:Type$Gate DeckHints:Type$Gate
Oracle:Gate to Tumbledown enters the battlefield tapped.\n{3}{R}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {R}. Oracle:Gate to Tumbledown enters the battlefield tapped.\n{3}{R}, {T}: Seek a nonland card. Activate only once.\n{T}: Add {R}.

View File

@@ -4,7 +4,7 @@ Types:Creature Wolf
PT:5/4 PT:5/4
K:Trample K:Trample
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When CARDNAME dies, seek a permanent card with mana value equal to the number of lands you control. T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When CARDNAME dies, seek a permanent card with mana value equal to the number of lands you control.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.Permanent+cmcEQX | ChangeNum$ 1 SVar:TrigSeek:DB$ Seek | Type$ Card.Permanent+cmcEQX
SVar:X:Count$Valid Land.YouCtrl SVar:X:Count$Valid Land.YouCtrl
SVar:NeedsToPlayVar:X GE4 SVar:NeedsToPlayVar:X GE4
SVar:BuffedBy:Land SVar:BuffedBy:Land

View File

@@ -4,8 +4,9 @@ Types:Creature Human Wizard
PT:2/2 PT:2/2
K:Prowess K:Prowess
T:Mode$ Phase | Phase$ Main1 | PreCombatMain$ True | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSeek | TriggerDescription$ At the beginning of your precombat main phase, you may discard a card. If you do, seek a card with greater mana value and exile it. Until the end of your next turn, you may play the exiled card. T:Mode$ Phase | Phase$ Main1 | PreCombatMain$ True | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSeek | TriggerDescription$ At the beginning of your precombat main phase, you may discard a card. If you do, seek a card with greater mana value and exile it. Until the end of your next turn, you may play the exiled card.
SVar:TrigSeek:AB$ ChangeZone | Cost$ Discard<1/Card> | Origin$ Library | Destination$ Exile | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.cmcGTX | ChangeNum$ 1 | RememberChanged$ True | SubAbility$ DBEffect SVar:TrigSeek:AB$ Seek | Cost$ Discard<1/Card> | Type$ Card.cmcGTX | RememberFound$ True | SubAbility$ DBExile
SVar:X:Discarded$CardManaCost SVar:X:Discarded$CardManaCost
SVar:DBExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | Defined$ Remembered | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ MayPlay | Duration$ UntilTheEndOfYourNextTurn | ForgetOnMoved$ Exile | SubAbility$ DBCleanup SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ MayPlay | Duration$ UntilTheEndOfYourNextTurn | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
SVar:MayPlay:Mode$ Continuous | Affected$ Card.IsRemembered | MayPlay$ True | EffectZone$ Command | AffectedZone$ Exile | Description$ Until the end of your next turn, you may play the exiled card. SVar:MayPlay:Mode$ Continuous | Affected$ Card.IsRemembered | MayPlay$ True | EffectZone$ Command | AffectedZone$ Exile | Description$ Until the end of your next turn, you may play the exiled card.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True

View File

@@ -4,11 +4,13 @@ Types:Legendary Creature Frog Horror
PT:6/6 PT:6/6
K:Menace K:Menace
T:Mode$ Phase | Phase$ BeginCombat | TriggerZones$ Battlefield | Execute$ TrigSac | IsPresent$ Card.Self+untapped | TriggerDescription$ At the beginning of each combat, if CARDNAME is untapped, any opponent may sacrifice a nontoken creature. If they do, tap CARDNAME, then seek a land card and put it onto the battlefield tapped. T:Mode$ Phase | Phase$ BeginCombat | TriggerZones$ Battlefield | Execute$ TrigSac | IsPresent$ Card.Self+untapped | TriggerDescription$ At the beginning of each combat, if CARDNAME is untapped, any opponent may sacrifice a nontoken creature. If they do, tap CARDNAME, then seek a land card and put it onto the battlefield tapped.
SVar:TrigSac:DB$ Sacrifice | Defined$ Opponent | Amount$ 1 | SacValid$ Creature.nonToken | RememberSacrificed$ True | Optional$ True | AILogic$ DesecrationDemon | SubAbility$ DBTap SVar:TrigSac:DB$ Sacrifice | Defined$ Opponent | Amount$ 1 | SacValid$ Creature.nonToken | RememberSacrificed$ True | Optional$ True | AILogic$ DesecrationDemon | SubAbility$ DBBranch
SVar:DBTap:DB$ Tap | Defined$ Self | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | SubAbility$ DBSeek SVar:DBBranch:DB$ Branch | BranchConditionSVar$ X | TrueSubAbility$ DBTap
SVar:DBSeek:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Land | ChangeNum$ 1 | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Remembered$Amount SVar:X:Remembered$Amount
SVar:DBTap:DB$ Tap | SubAbility$ DBSeek
SVar:DBSeek:DB$ Seek | Type$ Card.Land | ImprintFound$ True | SubAbility$ DBPut
SVar:DBPut:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Defined$ Imprinted | Tapped$ True | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ Whenever a land enters the battlefield under your control, it perpetually gains "{B}{G}, {T}, Sacrifice this land: Draw a card." T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ Whenever a land enters the battlefield under your control, it perpetually gains "{B}{G}, {T}, Sacrifice this land: Draw a card."
SVar:TrigEffect:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ PerpetualStatic | Name$ Gitrog, Horror of Zhava's Perpetual Effect | Duration$ Permanent | SubAbility$ DBCleanup SVar:TrigEffect:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ PerpetualStatic | Name$ Gitrog, Horror of Zhava's Perpetual Effect | Duration$ Permanent | SubAbility$ DBCleanup
SVar:PerpetualStatic:Mode$ Continuous | Affected$ Card.IsRemembered | AddAbility$ PerpetualSacDraw | EffectZone$ All | Description$ This land card perpetually gains "{B}{G}, {T}, Sacrifice this land: Draw a card." SVar:PerpetualStatic:Mode$ Continuous | Affected$ Card.IsRemembered | AddAbility$ PerpetualSacDraw | EffectZone$ All | Description$ This land card perpetually gains "{B}{G}, {T}, Sacrifice this land: Draw a card."

View File

@@ -3,7 +3,7 @@ ManaCost:R
Types:Creature Goblin Types:Creature Goblin
PT:1/1 PT:1/1
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ DBSeek | TriggerDescription$ When CARDNAME dies, seek a creature card with mana value 3 or less. That card perpetually gains haste, "This spell costs {1} less to cast," and "At the beginning of your end step, sacrifice this creature." T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ DBSeek | TriggerDescription$ When CARDNAME dies, seek a creature card with mana value 3 or less. That card perpetually gains haste, "This spell costs {1} less to cast," and "At the beginning of your end step, sacrifice this creature."
SVar:DBSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Creature.cmcLE3+YouOwn | RememberChanged$ True | SubAbility$ DBEffect SVar:DBSeek:DB$ Seek | Type$ Creature.cmcLE3+YouOwn | RememberFound$ True | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | StaticAbilities$ PerpetualAbility | RememberObjects$ Remembered | Triggers$ Update | Name$ Goblin Trapfinder's Perpetual Effect | Duration$ Permanent SVar:DBEffect:DB$ Effect | StaticAbilities$ PerpetualAbility | RememberObjects$ Remembered | Triggers$ Update | Name$ Goblin Trapfinder's Perpetual Effect | Duration$ Permanent
SVar:PerpetualAbility:Mode$ Continuous | Affected$ Card.IsRemembered | AddTrigger$ TrigSac | AddStaticAbility$ PerpetualReduceCost | AddKeyword$ Haste | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ This card perpetually gains haste, "This spell costs {1} less to cast," and "At the beginning of your end step, sacrifice this creature." SVar:PerpetualAbility:Mode$ Continuous | Affected$ Card.IsRemembered | AddTrigger$ TrigSac | AddStaticAbility$ PerpetualReduceCost | AddKeyword$ Haste | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ This card perpetually gains haste, "This spell costs {1} less to cast," and "At the beginning of your end step, sacrifice this creature."
SVar:PerpetualReduceCost:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 1 | EffectZone$ All | Description$ This spell costs {1} less to cast. SVar:PerpetualReduceCost:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 1 | EffectZone$ All | Description$ This spell costs {1} less to cast.

View File

@@ -3,6 +3,7 @@ ManaCost:3 G G
Types:Creature Elemental Types:Creature Elemental
PT:6/6 PT:6/6
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, seek a land card. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, seek a land card.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Land | ChangeNum$ 1 SVar:TrigSeek:DB$ Seek | Type$ Card.Land
A:AB$ MakeCard | Cost$ Discard<1/Land/land> | Conjure$ True | Name$ Hollowhenge Beast | Zone$ Hand | AdditionalActivationZone$ Graveyard | StackDescription$ Conjure a card named Hollowhenge Beast into your hand. | SpellDescription$ Conjure a card named Hollowhenge Beast into your hand. You may also activate this ability while CARDNAME is in your graveyard. A:AB$ MakeCard | Cost$ Discard<1/Land/land> | Conjure$ True | Name$ Hollowhenge Beast | Zone$ Hand | AdditionalActivationZone$ Graveyard | StackDescription$ Conjure a card named Hollowhenge Beast into your hand. | SpellDescription$ Conjure a card named Hollowhenge Beast into your hand. You may also activate this ability while CARDNAME is in your graveyard.
DeckHas:Ability$Discard
Oracle:When Hollowhenge Wrangler enters the battlefield, seek a land card.\nDiscard a land card: Conjure a card named Hollowhenge Beast into your hand. You may also activate this ability while Hollowhenge Wrangler is in your graveyard. Oracle:When Hollowhenge Wrangler enters the battlefield, seek a land card.\nDiscard a land card: Conjure a card named Hollowhenge Beast into your hand. You may also activate this ability while Hollowhenge Wrangler is in your graveyard.

View File

@@ -3,13 +3,11 @@ ManaCost:3 W
Types:Creature Human Cleric Types:Creature Human Cleric
PT:3/3 PT:3/3
K:Vigilance K:Vigilance
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.wasCast+Self | CheckSVar$ Z | SVarCompare$ GE20 | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it and there are twenty or more creature cards with mana value 3 or less among cards in your graveyard, hand, and library, seek two creature cards with mana value 3 or less. Put one of them onto the battlefield and shuffle the other into your library. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.wasCast+Self | CheckSVar$ X | SVarCompare$ GE20 | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it and there are twenty or more creature cards with mana value 3 or less among cards in your graveyard, hand, and library, seek two creature cards with mana value 3 or less. Put one of them onto the battlefield and shuffle the other into your library.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Library | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Creature.YouOwn+cmcLE3 | ChangeNum$ 2 | RememberChanged$ True | SubAbility$ DBChangeZone1 SVar:TrigSeek:DB$ Seek | Type$ Creature.YouOwn+cmcLE3 | Num$ 2 | RememberFound$ True | SubAbility$ DBChangeZone1
SVar:DBChangeZone1:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.IsRemembered | ChangeNum$ 1 | Mandatory$ True | NoLooking$ True | SelectPrompt$ Select a card for the battlefield | Shuffle$ True | SubAbility$ DBChangeZone2 | StackDescription$ None SVar:DBChangeZone1:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.IsRemembered | ChangeNum$ 1 | Mandatory$ True | SelectPrompt$ Select a card for the battlefield | SubAbility$ DBChangeZone2
SVar:DBChangeZone2:DB$ ChangeZone | Origin$ Library | Destination$ Library | ChangeType$ Creature.IsRemembered | Mandatory$ True | NoLooking$ True | StackDescription$ None | SubAbility$ DBCleanup SVar:DBChangeZone2:DB$ ChangeZone | Origin$ Hand | Destination$ Library | ChangeType$ Creature.IsRemembered | Mandatory$ True | Shuffle$ True | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Count$ValidGraveyard Creature.YouOwn+cmcLE3 SVar:X:Count$ValidGraveyard,Library,Hand Creature.YouOwn+cmcLE3
SVar:Y:Count$ValidLibrary Creature.YouOwn+cmcLE3/Plus.X
SVar:Z:Count$ValidHand Creature.YouOwn+cmcLE3/Plus.Y
DeckNeeds:Type$Creature DeckNeeds:Type$Creature
Oracle:Vigilance\nWhen Inquisitor Captain enters the battlefield, if you cast it and there are twenty or more creature cards with mana value 3 or less among cards in your graveyard, hand, and library, seek two creature cards with mana value 3 or less. Put one of them onto the battlefield and shuffle the other into your library. Oracle:Vigilance\nWhen Inquisitor Captain enters the battlefield, if you cast it and there are twenty or more creature cards with mana value 3 or less among cards in your graveyard, hand, and library, seek two creature cards with mana value 3 or less. Put one of them onto the battlefield and shuffle the other into your library.

View File

@@ -5,6 +5,6 @@ PT:3/3
K:Ninjutsu:1 G K:Ninjutsu:1 G
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigChoose | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, choose land or nonland. Seek a permanent card of the chosen type. T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigChoose | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, choose land or nonland. Seek a permanent card of the chosen type.
SVar:TrigChoose:DB$ ChooseType | Type$ Card | ValidTypes$ Land,Nonland | SubAbility$ DBSeek SVar:TrigChoose:DB$ ChooseType | Type$ Card | ValidTypes$ Land,Nonland | SubAbility$ DBSeek
SVar:DBSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.ChosenType | ChangeNum$ 1 | SubAbility$ DBCleanup SVar:DBSeek:DB$ Seek | Type$ Card.Permanent+ChosenType | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearChosenType$ True SVar:DBCleanup:DB$ Cleanup | ClearChosenType$ True
Oracle:Ninjutsu {1}{G}\nWhenever Jukai Liberator deals combat damage to a player, choose land or nonland. Seek a permanent card of the chosen type. Oracle:Ninjutsu {1}{G}\nWhenever Jukai Liberator deals combat damage to a player, choose land or nonland. Seek a permanent card of the chosen type.

View File

@@ -5,7 +5,9 @@ PT:4/3
K:Haste K:Haste
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, put a flame counter on it, then seek a card with mana value equal to the number of flame counters on it and exile that card face down. T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, put a flame counter on it, then seek a card with mana value equal to the number of flame counters on it and exile that card face down.
SVar:TrigCounter:DB$ PutCounter | CounterType$ FLAME | CounterNum$ 1 | ValidCards$ Self | SubAbility$ DBSeek SVar:TrigCounter:DB$ PutCounter | CounterType$ FLAME | CounterNum$ 1 | ValidCards$ Self | SubAbility$ DBSeek
SVar:DBSeek:DB$ ChangeZone | Origin$ Library | Destination$ Exile | ExileFaceDown$ True | AtRandom$ True | NoShuffle$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Card.cmcEQX+YouOwn | RememberChanged$ True SVar:DBSeek:DB$ Seek | Type$ Card.cmcEQX+YouOwn | ImprintFound$ True | SubAbility$ DBExile
SVar:DBExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | Defined$ Imprinted | ExileFaceDown$ True | Mandatory$ True | SubAbility$ DBClearImprinted
SVar:DBClearImprinted:DB$ Cleanup | ClearImprinted$ True
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigReturn | TriggerDescription$ When NICKNAME dies, put the cards exiled with it into their owner's hand. At the beginning of the end step of your next turn, discard those cards. T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigReturn | TriggerDescription$ When NICKNAME dies, put the cards exiled with it into their owner's hand. At the beginning of the end step of your next turn, discard those cards.
SVar:TrigReturn:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered+ExiledWithSource | Origin$ Exile | Destination$ Hand | SubAbility$ DBDelay SVar:TrigReturn:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered+ExiledWithSource | Origin$ Exile | Destination$ Hand | SubAbility$ DBDelay
SVar:DBDelay:DB$ DelayedTrigger | DelayedTriggerDefinedPlayer$ You | Mode$ Phase | Phase$ End of Turn | Execute$ TrigDiscardExiled | RememberObjects$ Remembered | TriggerDescription$ At the beginning of the end step of your next turn, discard those cards. SVar:DBDelay:DB$ DelayedTrigger | DelayedTriggerDefinedPlayer$ You | Mode$ Phase | Phase$ End of Turn | Execute$ TrigDiscardExiled | RememberObjects$ Remembered | TriggerDescription$ At the beginning of the end step of your next turn, discard those cards.
@@ -16,4 +18,5 @@ T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCar
SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard
SVar:X:Count$CardCounters.FLAME SVar:X:Count$CardCounters.FLAME
SVar:HasAttackEffect:TRUE SVar:HasAttackEffect:TRUE
DeckHas:Ability$Discard
Oracle:Haste\nWhenever Kardum, Patron of Flames attacks, put a flame counter on it, then seek a card with mana value equal to the number of flame counters on it and exile that card face down.\nWhen Kardum dies, put all cards you own exiled with it into your hand. At the beginning of the end step of your next turn, discard those cards. Oracle:Haste\nWhenever Kardum, Patron of Flames attacks, put a flame counter on it, then seek a card with mana value equal to the number of flame counters on it and exile that card face down.\nWhen Kardum dies, put all cards you own exiled with it into your hand. At the beginning of the end step of your next turn, discard those cards.

View File

@@ -39,7 +39,7 @@ SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield |
SVar:DBEffect:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ PerpetualStatic | Duration$ Permanent SVar:DBEffect:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ PerpetualStatic | Duration$ Permanent
SVar:PerpetualStatic:Mode$ Continuous | Affected$ Card.IsRemembered | AddKeyword$ CARDNAME can't block. | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ It perpetually gains "This creature can't block." SVar:PerpetualStatic:Mode$ Continuous | Affected$ Card.IsRemembered | AddKeyword$ CARDNAME can't block. | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ It perpetually gains "This creature can't block."
T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When this card specializes from any zone, seek an instant or sorcery card with mana value 3 or less. Until end of turn, you may cast that card without paying its mana cost. T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When this card specializes from any zone, seek an instant or sorcery card with mana value 3 or less. Until end of turn, you may cast that card without paying its mana cost.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Instant.cmcLE3,Sorcery.cmcLE3 | RememberChanged$ True SVar:TrigSeek:DB$ Seek | Type$ Instant.cmcLE3,Sorcery.cmcLE3 | RememberFound$ True | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | StaticAbilities$ MayPlay | RememberObjects$ Remembered | ForgetOnMoved$ Hand | SubAbility$ DBCleanup SVar:DBEffect:DB$ Effect | StaticAbilities$ MayPlay | RememberObjects$ Remembered | ForgetOnMoved$ Hand | SubAbility$ DBCleanup
SVar:MayPlay:Mode$ Continuous | Affected$ Card.IsRemembered+nonLand | MayPlayWithoutManaCost$ True | EffectZone$ Command | AffectedZone$ Hand SVar:MayPlay:Mode$ Continuous | Affected$ Card.IsRemembered+nonLand | MayPlayWithoutManaCost$ True | EffectZone$ Command | AffectedZone$ Hand
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True

View File

@@ -2,6 +2,6 @@ Name:Kindred Denial
ManaCost:2 U U ManaCost:2 U U
Types:Instant Types:Instant
A:SP$ Counter | TargetType$ Spell | ValidTgts$ Card | TgtPrompt$ Select target spell | RememberCounteredCMC$ True | SubAbility$ DBSeek | SpellDescription$ Counter target spell. A:SP$ Counter | TargetType$ Spell | ValidTgts$ Card | TgtPrompt$ Select target spell | RememberCounteredCMC$ True | SubAbility$ DBSeek | SpellDescription$ Counter target spell.
SVar:DBSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.cmcEQX | ChangeNum$ 1 | StackDescription$ SpellDescription | SpellDescription$ Seek a card with the same mana value as that spell. SVar:DBSeek:DB$ Seek | Type$ Card.cmcEQX | StackDescription$ REP Seek_{p:You} seeks | SpellDescription$ Seek a card with the same mana value as that spell.
SVar:X:Count$RememberedNumber SVar:X:Count$RememberedNumber
Oracle:Counter target spell. Seek a card with the same mana value as that spell. Oracle:Counter target spell. Seek a card with the same mana value as that spell.

View File

@@ -36,10 +36,10 @@ Types:Legendary Creature Tiefling Cleric
PT:3/4 PT:3/4
K:Vigilance K:Vigilance
T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When this creature specializes, seek three nonland permanent cards. Choose one of those cards and shuffle the rest into your library. T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When this creature specializes, seek three nonland permanent cards. Choose one of those cards and shuffle the rest into your library.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 3 | ChangeType$ Permanent.nonLand | RememberChanged$ True | SubAbility$ DBChooseCard SVar:TrigSeek:DB$ Seek | Num$ 3 | ChangeType$ Card.Permanent+nonLand | RememberFound$ True | SubAbility$ DBChooseCard
SVar:DBChooseCard:DB$ ChooseCard | ChoiceZone$ Hand | Choices$ Card.IsRemembered | ForgetChosen$ True | SubAbility$ DBShuffle SVar:DBChooseCard:DB$ ChooseCard | ChoiceZone$ Hand | Choices$ Card.IsRemembered | ForgetChosen$ True | SubAbility$ DBShuffle
SVar:DBShuffle:DB$ ChangeZone | Origin$ Hand | Destination$ Library | Defined$ Remembered | Shuffle$ True | SubAbility$ DBClearChosen SVar:DBShuffle:DB$ ChangeZone | Origin$ Hand | Destination$ Library | Defined$ Remembered | Shuffle$ True | SubAbility$ DBCleanup
SVar:DBClearChosen:DB$ Cleanup | ClearChosenCard$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True
Oracle:Vigilance\nWhen this creature specializes, seek three nonland permanent cards. Choose one of those cards and shuffle the rest into your library. Oracle:Vigilance\nWhen this creature specializes, seek three nonland permanent cards. Choose one of those cards and shuffle the rest into your library.
SPECIALIZE:BLACK SPECIALIZE:BLACK

View File

@@ -22,7 +22,7 @@ PT:3/6
K:Double Strike K:Double Strike
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When this creature enters the battlefield or specializes, seek a nonland permanent card with mana value 3 or less. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When this creature enters the battlefield or specializes, seek a nonland permanent card with mana value 3 or less.
T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigSeek | Secondary$ True | TriggerDescription$ When this creature enters the battlefield or specializes, seek a nonland permanent card with mana value 3 or less. T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigSeek | Secondary$ True | TriggerDescription$ When this creature enters the battlefield or specializes, seek a nonland permanent card with mana value 3 or less.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Permanent.nonLand+cmcLE3 SVar:TrigSeek:DB$ Seek | Type$ Card.Permanent+nonLand+cmcLE3
Oracle:Double strike\nWhen this creature enters the battlefield or specializes, seek a nonland permanent card with mana value 3 or less. Oracle:Double strike\nWhen this creature enters the battlefield or specializes, seek a nonland permanent card with mana value 3 or less.
SPECIALIZE:BLUE SPECIALIZE:BLUE

View File

@@ -4,7 +4,7 @@ Types:Legendary Creature Human Druid
PT:2/2 PT:2/2
K:Specialize:3:Wild Shape:Activate only if you control six or more lands.:IsPresent$ Land.YouCtrl | PresentCompare$ GE6 K:Specialize:3:Wild Shape:Activate only if you control six or more lands.:IsPresent$ Land.YouCtrl | PresentCompare$ GE6
T:Mode$ ChangesZone | ValidCard$ Card.wasCastByYou+Self | Destination$ Battlefield | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it, seek a land card with a basic land type. T:Mode$ ChangesZone | ValidCard$ Card.wasCastByYou+Self | Destination$ Battlefield | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it, seek a land card with a basic land type.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Land.hasABasicLandType | ChangeNum$ 1 SVar:TrigSeek:DB$ Seek | Type$ Land.hasABasicLandType
AlternateMode:Specialize AlternateMode:Specialize
Oracle:Wild Shape — Specialize {3}. Activate only if you control six or more lands.\nWhen Lukamina, Moon Druid enters the battlefield, if you cast it, seek a land card with a basic land type. Oracle:Wild Shape — Specialize {3}. Activate only if you control six or more lands.\nWhen Lukamina, Moon Druid enters the battlefield, if you cast it, seek a land card with a basic land type.

View File

@@ -1,7 +1,7 @@
Name:Norn's Disassembly Name:Norn's Disassembly
ManaCost:W ManaCost:W
Types:Enchantment Types:Enchantment
A:AB$ ChangeZone | Cost$ 1 W Sac<1/Permanent.Historic/Historic permanent> | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.Historic | ChangeNum$ 1 | SpellDescription$ Seek a historic card. A:AB$ Seek | Cost$ 1 W Sac<1/Permanent.Historic/historic permanent> | Type$ Card.Historic | StackDescription$ REP Seek_{p:You} seeks | SpellDescription$ Seek a historic card.
DeckHas:Ability$Sacrifice DeckHas:Ability$Sacrifice
DeckNeeds:Type$Legendary|Artifact|Planeswalker DeckNeeds:Type$Legendary|Artifact|Planeswalker
Oracle:{1}{W}, Sacrifice a historic permanent: Seek a historic card. Oracle:{1}{W}, Sacrifice a historic permanent: Seek a historic card.

View File

@@ -5,6 +5,6 @@ PT:4/4
K:Flying K:Flying
K:Ward:2 K:Ward:2
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigSeek | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, seek a card with mana value equal to the number of cards in your hand. T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigSeek | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, seek a card with mana value equal to the number of cards in your hand.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.cmcEQX | ChangeNum$ 1 SVar:TrigSeek:DB$ Seek | Type$ Card.cmcEQX
SVar:X:Count$InYourHand SVar:X:Count$InYourHand
Oracle:Flying\nWard {2}\nWhenever Obsessive Collector deals combat damage to a player, seek a card with mana value equal to the number of cards in your hand. Oracle:Flying\nWard {2}\nWhenever Obsessive Collector deals combat damage to a player, seek a card with mana value equal to the number of cards in your hand.

Some files were not shown because too many files have changed in this diff Show More