diff --git a/forge-gui-mobile/src/forge/adventure/data/DifficultyData.java b/forge-gui-mobile/src/forge/adventure/data/DifficultyData.java index d7aa97e0b4d..a9ddbc01e62 100644 --- a/forge-gui-mobile/src/forge/adventure/data/DifficultyData.java +++ b/forge-gui-mobile/src/forge/adventure/data/DifficultyData.java @@ -25,5 +25,6 @@ public class DifficultyData { public ObjectMap starterDecks = null; public ObjectMap constructedStarterDecks= null; public ObjectMap pileDecks= null; + public ObjectMap commanderDecks = null; } diff --git a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java index 450d98d328e..9d19aac6078 100644 --- a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java +++ b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java @@ -49,10 +49,13 @@ public class AdventurePlayer implements Serializable, SaveFileContent { // Deck data private Deck deck; - private final ArrayList decks = new ArrayList(MIN_DECK_COUNT); + private final ArrayList decks = new ArrayList<>(MIN_DECK_COUNT); private int selectedDeckIndex = 0; private final DifficultyData difficultyData = new DifficultyData(); + // Commander mode + private AdventureModes adventureMode; + // Game data. private float worldPosX; private float worldPosY; @@ -114,6 +117,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent { fantasyMode = false; announceFantasy = false; usingCustomDeck = false; + adventureMode = null; blessing = null; gold = 0; maxLife = 20; @@ -147,11 +151,14 @@ public class AdventurePlayer implements Serializable, SaveFileContent { public final ItemPool autoSellCards = new ItemPool<>(PaperCard.class); public final Set favoriteCards = new HashSet<>(); - public void create(String n, Deck startingDeck, boolean male, int race, int avatar, boolean isFantasy, boolean isUsingCustomDeck, DifficultyData difficultyData) { + public void create(String n, Deck startingDeck, boolean male, int race, int avatar, boolean isFantasy, + boolean isUsingCustomDeck, DifficultyData difficultyData, AdventureModes adventureMode) { clear(); + this.adventureMode = adventureMode; announceFantasy = fantasyMode = isFantasy; //Set Chaos mode first. announceCustom = usingCustomDeck = isUsingCustomDeck; + clearDecks(); // Reset the empty decks to now already have the commander in the command zone. deck = startingDeck; decks.set(0, deck); @@ -288,6 +295,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent { return life; } + public AdventureModes getAdventureMode(){ + return adventureMode; + } + public int getMaxLife() { return maxLife; } @@ -334,7 +345,6 @@ public class AdventurePlayer implements Serializable, SaveFileContent { this.colorIdentity = set; } - @Override public void load(SaveFileData data) { boolean migration = false; @@ -391,6 +401,13 @@ public class AdventurePlayer implements Serializable, SaveFileContent { heroRace = data.readInt("heroRace"); avatarIndex = data.readInt("avatarIndex"); isFemale = data.readBool("isFemale"); + + String _mode = data.readString("adventure_mode"); + if (_mode == null) + adventureMode = AdventureModes.Standard; + else + adventureMode = AdventureModes.valueOf(_mode); + if (data.containsKey("colorIdentity")) { String temp = data.readString("colorIdentity"); if (temp != null) @@ -505,6 +522,11 @@ public class AdventurePlayer implements Serializable, SaveFileContent { deck.getOrCreate(DeckSection.Contraptions).addAll(contraptionDeckCards.getFilteredPool(isValid)); unsupportedCards.addAll(contraptionDeckCards.getFilteredPool(isUnsupported).toFlatList()); } + if (data.containsKey("commanderCards")) { + CardPool commanderCards = CardPool.fromCardList(List.of((String[]) data.readObject("commanderCards"))); + deck.getOrCreate(DeckSection.Commander).addAll(commanderCards.getFilteredPool(isValid)); + unsupportedCards.addAll(commanderCards.getFilteredPool(isUnsupported).toFlatList()); + } if (data.containsKey("characterFlagsKey") && data.containsKey("characterFlagsValue")) { String[] keys = (String[]) data.readObject("characterFlagsKey"); Byte[] values = (Byte[]) data.readObject("characterFlagsValue"); @@ -573,6 +595,11 @@ public class AdventurePlayer implements Serializable, SaveFileContent { decks.get(i).getOrCreate(DeckSection.Contraptions).addAll(contraptionCards.getFilteredPool(isValid)); unsupportedCards.addAll(contraptionCards.getFilteredPool(isUnsupported).toFlatList()); } + if (data.containsKey("commanderCards_" + i)) { + CardPool commanderCards = CardPool.fromCardList(List.of((String[]) data.readObject("commanderCards_" + i))); + decks.get(i).getOrCreate(DeckSection.Commander).addAll(commanderCards.getFilteredPool(isValid)); + unsupportedCards.addAll(commanderCards.getFilteredPool(isUnsupported).toFlatList()); + } } // In case we allow removing decks from the deck selection GUI, populate up to the minimum for (int i = dynamicDeckCount++; i < MIN_DECK_COUNT; i++) { @@ -595,6 +622,11 @@ public class AdventurePlayer implements Serializable, SaveFileContent { decks.get(i).getOrCreate(DeckSection.Sideboard).addAll(sideBoardCards.getFilteredPool(isValid)); unsupportedCards.addAll(sideBoardCards.getFilteredPool(isUnsupported).toFlatList()); } + if (data.containsKey("commanderCards_" + i)) { + CardPool commanderCards = CardPool.fromCardList(List.of((String[]) data.readObject("commanderCards_" + i))); + decks.get(i).getOrCreate(DeckSection.Commander).addAll(commanderCards.getFilteredPool(isValid)); + unsupportedCards.addAll(commanderCards.getFilteredPool(isUnsupported).toFlatList()); + } } } @@ -715,6 +747,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent { data.store("isFemale", isFemale); data.store("colorIdentity", colorIdentity.getColor()); + data.store("adventure_mode", adventureMode.toString()); + data.store("fantasyMode", fantasyMode); data.store("announceFantasy", announceFantasy); data.store("usingCustomDeck", usingCustomDeck); @@ -772,6 +806,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent { data.storeObject("attractionDeckCards", deck.get(DeckSection.Attractions).toCardList("\n").split("\n")); if (deck.get(DeckSection.Contraptions) != null) data.storeObject("contraptionDeckCards", deck.get(DeckSection.Contraptions).toCardList("\n").split("\n")); + if (deck.get(DeckSection.Commander) != null) + data.storeObject("commanderCards", deck.get(DeckSection.Commander).toCardList("\n").split("\n")); // save decks dynamically data.store("deckCount", getDeckCount()); @@ -784,6 +820,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent { data.storeObject("attractionDeckCards_" + i, decks.get(i).get(DeckSection.Attractions).toCardList("\n").split("\n")); if (decks.get(i).get(DeckSection.Contraptions) != null) data.storeObject("contraptionDeckCards_" + i, decks.get(i).get(DeckSection.Contraptions).toCardList("\n").split("\n")); + if (decks.get(i).get(DeckSection.Commander) != null) + data.storeObject("commanderCards_" + i, decks.get(i).get(DeckSection.Commander).toCardList("\n").split("\n")); } data.store("selectedDeckIndex", selectedDeckIndex); data.storeObject("cards", cards.toCardList("\n").split("\n")); diff --git a/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java b/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java index d3425a17e33..af966105328 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java +++ b/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java @@ -9,6 +9,7 @@ import forge.adventure.data.AdventureEventData; import forge.adventure.data.ItemData; import forge.adventure.player.AdventurePlayer; import forge.adventure.util.AdventureEventController; +import forge.adventure.util.AdventureModes; import forge.adventure.util.Config; import forge.adventure.util.Current; import forge.assets.FImage; @@ -50,7 +51,7 @@ public class AdventureDeckEditor extends FDeckEditor { @Override public DeckFormat getDeckFormat() { - return DeckFormat.Adventure; + return AdventurePlayer.current().getAdventureMode() == AdventureModes.Commander ? DeckFormat.Commander : DeckFormat.Adventure; } @Override @@ -65,17 +66,29 @@ public class AdventureDeckEditor extends FDeckEditor { @Override protected DeckEditorPage[] getInitialPages() { - return new DeckEditorPage[]{ - new CollectionCatalogPage(), - new AdventureDeckSectionPage(DeckSection.Main, ItemManagerConfig.ADVENTURE_EDITOR_POOL), - new AdventureDeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.ADVENTURE_SIDEBOARD), - new CollectionAutoSellPage() - }; + if (AdventurePlayer.current().getAdventureMode() == AdventureModes.Commander) + return new DeckEditorPage[]{ + new CollectionCatalogPage(), + new AdventureDeckSectionPage(DeckSection.Commander, ItemManagerConfig.ADVENTURE_EDITOR_POOL), + new AdventureDeckSectionPage(DeckSection.Main, ItemManagerConfig.ADVENTURE_EDITOR_POOL), + new AdventureDeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.ADVENTURE_SIDEBOARD), + new CollectionAutoSellPage() + }; + else { + return new DeckEditorPage[]{ + new CollectionCatalogPage(), + new AdventureDeckSectionPage(DeckSection.Main, ItemManagerConfig.ADVENTURE_EDITOR_POOL), + new AdventureDeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.ADVENTURE_SIDEBOARD), + new CollectionAutoSellPage() + }; + } } @Override public ItemPool getCardPool(boolean wantUnique) { - return Current.player().getCards(); + ItemPool pool = new ItemPool<>(PaperCard.class); + pool.addAll(Current.player().getCards()); + return pool; } @Override @@ -113,6 +126,13 @@ public class AdventureDeckEditor extends FDeckEditor { } } + @Override + public boolean isCommanderEditor() { + if (AdventurePlayer.current().getAdventureMode() == AdventureModes.Commander) + return true; + return super.isCommanderEditor(); + } + protected static class ShopConfig extends AdventureEditorConfig { @Override protected DeckEditorPage[] getInitialPages() { @@ -896,12 +916,17 @@ public class AdventureDeckEditor extends FDeckEditor { return; } - String deckError = GameType.Adventure.getDeckFormat().getDeckConformanceProblem(getDeck()); - if (deckError != null) { - //Allow the player to close the editor with an invalid deck, but warn them that cards may be swapped out. - String warning = localizer.getMessage("lblAdventureDeckError", deckError); - FOptionPane.showConfirmDialog(warning, localizer.getMessage("lblInvalidDeck"), false, result -> resolveClose(canCloseCallback, result == true)); - return; + String deckError; + if (!(getEditorConfig() instanceof ShopConfig)) + { + deckError = getEditorConfig().getDeckFormat().getDeckConformanceProblem(getDeck()); + + if (deckError != null) { + //Allow the player to close the editor with an invalid deck, but warn them that cards may be swapped out. + String warning = localizer.getMessage("lblAdventureDeckError", deckError); + FOptionPane.showConfirmDialog(warning, localizer.getMessage("lblInvalidDeck"), false, result -> resolveClose(canCloseCallback, result == true)); + return; + } } resolveClose(canCloseCallback, true); diff --git a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java index c974b02e9c1..9883e399f9e 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java @@ -14,6 +14,7 @@ import forge.adventure.player.AdventurePlayer; import forge.adventure.stage.GameHUD; import forge.adventure.stage.IAfterMatch; import forge.adventure.util.AdventureEventController; +import forge.adventure.util.AdventureModes; import forge.adventure.util.Config; import forge.adventure.util.Current; import forge.assets.FBufferedImage; @@ -197,6 +198,8 @@ public class DuelScene extends ForgeScene { String isDeckMissingMsg = ""; if (eventData != null && eventData.eventRules != null) { mainGameType = eventData.eventRules.gameType; + } else if (AdventurePlayer.current().getAdventureMode() == AdventureModes.Commander){ + mainGameType = GameType.Commander; } else { mainGameType = GameType.Adventure; } diff --git a/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java b/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java index 774f710c309..8cae52997a3 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java @@ -9,6 +9,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Array; + import com.github.tommyettinger.textra.TextraLabel; import forge.Forge; import forge.adventure.data.DialogData; @@ -34,6 +35,7 @@ import java.util.Random; * NewGame scene that contains the character creation */ public class NewGameScene extends MenuScene { + TextField selectedName; ColorSet[] colorIds; CardEdition[] editionIds; @@ -97,6 +99,11 @@ public class NewGameScene extends MenuScene { AdventureModes.Pile.setSelectionName(colorIdLabel); AdventureModes.Pile.setModes(colorNames); } + if (diff.commanderDecks != null) { + modes.add(AdventureModes.Commander); + AdventureModes.Commander.setSelectionName(colorIdLabel); + AdventureModes.Commander.setModes(colorNames); + } break; } @@ -122,6 +129,12 @@ public class NewGameScene extends MenuScene { AdventureModes.Custom.setSelectionName("[BLACK]" + Forge.getLocalizer().getMessage("lblDeck") + ":"); AdventureModes.Custom.setModes(custom); } + + // Commander game mode in selection screen + modes.add(AdventureModes.Commander); + AdventureModes.Commander.setSelectionName(colorIdLabel); + AdventureModes.Commander.setModes(colorNames); + String[] modeNames = new String[modes.size]; int constructedIndex = -1; @@ -205,6 +218,9 @@ public class NewGameScene extends MenuScene { }); } + // class field + private RewardActor previewActor; + private static NewGameScene object; public static NewGameScene instance() { @@ -302,7 +318,6 @@ public class NewGameScene extends MenuScene { @Override public void enter() { updateAvatar(); - if (Forge.createNewAdventureMap) { FModel.getPreferences().setPref(ForgePreferences.FPref.UI_ENABLE_MUSIC, false); WorldSave.generateNewWorld(selectedName.getText(), @@ -451,6 +466,9 @@ public class NewGameScene extends MenuScene { case Custom: summaryText.append("Mode: Custom\n\nChoose your own preconstructed deck. Enemies can receive a random genetic AI deck (difficult).\n\nWarning: This will make encounter difficulty vary wildly from the developers' intent"); break; + case Commander: + summaryText.append("Mode: Commander\n\nYou will given a preconstructed commander deck based on the chosen color theme to start the playthrough.\n\nGood luck on your quest of creating a coherent deck that can win consistently and defeat the bosses."); + break; default: summaryText.append("No summary available for your this game mode."); break; diff --git a/forge-gui-mobile/src/forge/adventure/util/AdventureModes.java b/forge-gui-mobile/src/forge/adventure/util/AdventureModes.java index 94ce2af5251..42599827ef7 100644 --- a/forge-gui-mobile/src/forge/adventure/util/AdventureModes.java +++ b/forge-gui-mobile/src/forge/adventure/util/AdventureModes.java @@ -8,7 +8,8 @@ public enum AdventureModes { Constructed(Forge.getLocalizer().getMessage("lblConstructed")), Chaos("[GOLD]"+Forge.getLocalizer().getMessage("lblChaos")), Pile(Forge.getLocalizer().getMessage("lblPile")), - Custom(Forge.getLocalizer().getMessage("lblCustom")); + Custom(Forge.getLocalizer().getMessage("lblCustom")), + Commander(Forge.getLocalizer().getMessage("lblCommander")); private final String name; private String selectionName; diff --git a/forge-gui-mobile/src/forge/adventure/util/Config.java b/forge-gui-mobile/src/forge/adventure/util/Config.java index ec37458d516..8eb01a319e7 100644 --- a/forge-gui-mobile/src/forge/adventure/util/Config.java +++ b/forge-gui-mobile/src/forge/adventure/util/Config.java @@ -255,6 +255,12 @@ public class Config { return CardUtil.getDeck(entry.value, false, false, "", false, false); } } + case Commander: + for (ObjectMap.Entry entry : difficultyData.commanderDecks) { + if (ColorSet.fromNames(entry.key.toCharArray()).getColor() == color.getColor()) { + return CardUtil.getDeck(entry.value, false, false, "", false, false); + } + }; } return null; } diff --git a/forge-gui-mobile/src/forge/adventure/util/RewardActor.java b/forge-gui-mobile/src/forge/adventure/util/RewardActor.java index 783fe209977..cbf5aa299f3 100644 --- a/forge-gui-mobile/src/forge/adventure/util/RewardActor.java +++ b/forge-gui-mobile/src/forge/adventure/util/RewardActor.java @@ -33,6 +33,7 @@ import forge.Graphics; import forge.ImageKeys; import forge.StaticData; import forge.adventure.data.ItemData; +import forge.adventure.player.AdventurePlayer; import forge.adventure.scene.RewardScene; import forge.adventure.scene.Scene; import forge.adventure.scene.UIScene; @@ -925,6 +926,16 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb getColor().a = 0.5f; } + private static boolean inCollectionLike(PaperCard pc) { + var coll = AdventurePlayer.current().getCollectionCards(true).toFlatList(); + String name = pc.getName(); + for (PaperCard c : coll) { + if (c.equals(pc) || c.getName().equals(name)) + return true; + } + return false; + } + @Override public void act(float delta) { super.act(delta); @@ -943,8 +954,15 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb addListener(tooltip); } } - if (autoSell != null && !autoSell.isVisible() && flipProcess == 1) + if (autoSell != null && !autoSell.isVisible() && flipProcess == 1) { autoSell.setVisible(true); + if (AdventurePlayer.current().getAdventureMode() == AdventureModes.Commander) { + PaperCard pc = reward.getCard(); + if (pc != null) { + setAutoSell(inCollectionLike(pc)); + } + } + } // flipProcess=(float)Gdx.input.getX()/ (float)Gdx.graphics.getWidth(); } diff --git a/forge-gui-mobile/src/forge/adventure/world/WorldSave.java b/forge-gui-mobile/src/forge/adventure/world/WorldSave.java index ecb951c1f86..4119f15cf9e 100644 --- a/forge-gui-mobile/src/forge/adventure/world/WorldSave.java +++ b/forge-gui-mobile/src/forge/adventure/world/WorldSave.java @@ -132,8 +132,10 @@ public class WorldSave { currentSave.pointOfInterestChanges.clear(); boolean chaos = mode == AdventureModes.Chaos; boolean custom = mode == AdventureModes.Custom; + Deck starterDeck = Config.instance().starterDeck(startingColorIdentity, diff, mode, customDeckIndex, starterEdition); - currentSave.player.create(name, starterDeck, male, race, avatarIndex, chaos, custom, diff); + currentSave.player.create(name, starterDeck, male, race, avatarIndex, chaos, custom, diff, mode); + currentSave.player.setWorldPosY((int) (currentSave.world.getData().playerStartPosY * currentSave.world.getData().height * currentSave.world.getTileSize())); currentSave.player.setWorldPosX((int) (currentSave.world.getData().playerStartPosX * currentSave.world.getData().width * currentSave.world.getTileSize())); currentSave.onLoadList.emit(); diff --git a/forge-gui/res/adventure/common/config.json b/forge-gui/res/adventure/common/config.json index 09f97b41f22..bd1197692e1 100644 --- a/forge-gui/res/adventure/common/config.json +++ b/forge-gui/res/adventure/common/config.json @@ -132,6 +132,13 @@ "R":"decks/starter/pile_red_e.json", "G":"decks/starter/pile_green_e.json" }, + "commanderDecks": { + "W":"decks/starter/commander/white_01.dck", + "B":"decks/starter/commander/black_01.dck", + "U":"decks/starter/commander/blue_01.dck", + "R":"decks/starter/commander/red_01.dck", + "G":"decks/starter/commander/green_01.dck" + }, "startItems": [ "Manasight Amulet", "Leather Boots" @@ -170,6 +177,13 @@ "R":"decks/starter/pile_red_n.json", "G":"decks/starter/pile_green_n.json" }, + "commanderDecks": { + "W":"decks/starter/commander/white_01.dck", + "B":"decks/starter/commander/black_01.dck", + "U":"decks/starter/commander/blue_01.dck", + "R":"decks/starter/commander/red_01.dck", + "G":"decks/starter/commander/green_01.dck" + }, "startItems": [ "Leather Boots" ] @@ -205,6 +219,13 @@ "U":"decks/starter/pile_blue_h.json", "R":"decks/starter/pile_red_h.json", "G":"decks/starter/pile_green_h.json" + }, + "commanderDecks": { + "W":"decks/starter/commander/white_01.dck", + "B":"decks/starter/commander/black_01.dck", + "U":"decks/starter/commander/blue_01.dck", + "R":"decks/starter/commander/red_01.dck", + "G":"decks/starter/commander/green_01.dck" } },{ "name": "Insane", @@ -238,6 +259,13 @@ "U":"decks/starter/pile_blue_h.json", "R":"decks/starter/pile_red_h.json", "G":"decks/starter/pile_green_h.json" + }, + "commanderDecks": { + "W":"decks/starter/commander/white_01.dck", + "B":"decks/starter/commander/black_01.dck", + "U":"decks/starter/commander/blue_01.dck", + "R":"decks/starter/commander/red_01.dck", + "G":"decks/starter/commander/green_01.dck" } } ], diff --git a/forge-gui/res/adventure/common/decks/starter/commander/black_01.dck b/forge-gui/res/adventure/common/decks/starter/commander/black_01.dck new file mode 100644 index 00000000000..d3fd549e5eb --- /dev/null +++ b/forge-gui/res/adventure/common/decks/starter/commander/black_01.dck @@ -0,0 +1,81 @@ +[metadata] +Name=Starter Commander - Black +[Avatar] + +[Commander] +1 Tymaret, Chosen from Death|thb|1 + +[Main] +1 Blood Artist|inr|1 +1 Burglar Rat|fdn|1 +1 Changeling Outcast|otc|1 +1 Creeping Bloodsucker|j25|1 +1 Gifted Aetherborn|jmp|1 +1 Gravedigger|m20|1 +1 Graveshifter|moc|1 +1 Gray Merchant of Asphodel|dsc|1 +1 Infestation Sage|fdn|1 +1 Marauding Blight-Priest|fdn|1 +1 Vampire Nighthawk|fdn|1 +1 Vampire of the Dire Moon|m20|1 +1 Vengeful Bloodwitch|fdn|1 +1 Vindictive Vampire|clu|1 +1 Yargle, Glutton of Urborg|cmm|1 +1 Zulaport Cutthroat|clb|1 +1 Arbiter of Woe|fdn|1 +1 Dockside Chef|neo|1 +1 Dusk Legion Zealot|lcc|1 +1 Faerie Dreamthief|woe|1 +1 Foulmire Knight|moc|1 +1 Indulgent Tormentor|ima|1 +1 Morbid Opportunist|tdc|1 +1 Novice Occultist|mid|1 +1 Phyrexian Rager|moc|1 +1 Refurbished Familiar|mh3|1 +1 Silversmote Ghoul|c21|1 +1 Troll of Khazad-dûm|ltr|1 +1 Vampire Gourmand|fdn|1 +1 Command Beacon|tdc|1 +1 Command Tower|eoc|1 +37 Swamp|tla|1 +1 Lightning Greaves|tdc|1 +1 Swiftfoot Boots|tdc|1 +1 Arcane Signet|eoc|1 +1 Burnished Hart|dsc|1 +1 Commander's Sphere|drc|1 +1 Darksteel Ingot|otc|1 +1 Manalith|m19|1 +1 Mind Stone|dsc|1 +1 Patchwork Banner|blb|1 +1 Prismatic Lens|otc|1 +1 Relic of Legends|dmu|1 +1 Sol Ring|eoc|1 +1 Solemn Simulacrum|tdc|1 +1 Thought Vessel|dsc|1 +1 Accursed Marauder|mh3|1 +1 Bake into a Pie|fdn|1 +1 Banewhip Punisher|hou|1 +1 Black Dragon|afr|1 +1 Doom Blade|ima|1 +1 Elspeth's Nightmare|thb|1 +1 Hero's Downfall|fdn|1 +1 Murder|dsk|1 +1 Nekrataal|ema|1 +1 Ob Nixilis, the Hate-Twisted|war|1 +1 Ravenous Chupacabra|mkc|1 +1 Sephiroth's Intervention|fin|1 +1 Stinkweed Imp|dvd|1 +1 Withering Torment|dsk|1 +1 Commander's Plate|cmr|1 +1 Path of Ancestry|tdc|1 +1 Campfire|cmm|1 + +[Sideboard] + +[Planes] + +[Schemes] + +[Conspiracy] + +[Dungeon] diff --git a/forge-gui/res/adventure/common/decks/starter/commander/blue_01.dck b/forge-gui/res/adventure/common/decks/starter/commander/blue_01.dck new file mode 100644 index 00000000000..aa2c7258dc7 --- /dev/null +++ b/forge-gui/res/adventure/common/decks/starter/commander/blue_01.dck @@ -0,0 +1,81 @@ +[metadata] +Name=Starter Commander - Blue +[Avatar] + +[Commander] +1 Callaphe, Beloved of the Sea|thb|1 + +[Main] +1 Brineborn Cutthroat|fdn|1 +1 Cloudfin Raptor|rvr|1 +1 Air Elemental|m20|1 +1 Augury Raven|khm|1 +1 Aven Fateshaper|dmr|1 +1 Aven Reedstalker|hou|1 +1 Baithook Angler|mid|1 +1 Bay Falcon|mir|1 +1 Boreal Elemental|m20|1 +1 Curio Vendor|kld|1 +1 Foul Watcher|mh2|1 +1 Gossamer Phantasm|tsr|1 +1 Ancestral Reminiscence|lci|1 +1 Arrester's Admonition|rna|1 +1 Artificer's Assistant|dom|1 +1 Artificer's Epiphany|ddu|1 +1 Azure Mage|mm3|1 +1 Behold the Multiverse|khm|1 +1 Bellowing Crier|blb|1 +1 Birthday Escape|ltr|1 +1 Chart a Course|fdn|1 +1 Cloudkin Seer|clu|1 +1 Cryogen Relic|eoe|1 +1 Curate|mkc|1 +1 Spectral Sailor|fdn|1 +1 Delver of Secrets|inr|1 +1 Spyglass Siren|lci|1 +1 Command Beacon|tdc|1 +1 Command Tower|eoc|1 +37 Island|tla|1 +1 Aegis Turtle|fdn|1 +1 Cogwork Wrestler|lci|1 +1 Lightning Greaves|tdc|1 +1 Swiftfoot Boots|tdc|1 +1 Animating Faerie|eld|1 +1 Aven Wind Mage|gn2|1 +1 Aarakocra Sneak|clb|1 +1 Arcane Signet|eoc|1 +1 Burnished Hart|dsc|1 +1 Commander's Sphere|drc|1 +1 Darksteel Ingot|otc|1 +1 Manalith|m19|1 +1 Mind Stone|dsc|1 +1 Patchwork Banner|blb|1 +1 Prismatic Lens|otc|1 +1 Relic of Legends|dmu|1 +1 Sol Ring|eoc|1 +1 Solemn Simulacrum|tdc|1 +1 Thought Vessel|dsc|1 +1 Academy Journeymage|dom|1 +1 Aether Adept|ddm|1 +1 Aetherize|fdn|1 +1 Angler Drake|akh|1 +1 Aven Augur|fut|1 +1 Banishing Knack|eve|1 +1 Beluna's Gatekeeper|woe|1 +1 Bounce Off|dft|1 +1 Clutch of Currents|bfz|1 +1 Cunning Geysermage|znr|1 +1 Exclusion Mage|fdn|1 +1 Commander's Plate|cmr|1 +1 Path of Ancestry|tdc|1 +1 Campfire|cmm|1 + +[Sideboard] + +[Planes] + +[Schemes] + +[Conspiracy] + +[Dungeon] diff --git a/forge-gui/res/adventure/common/decks/starter/commander/green_01.dck b/forge-gui/res/adventure/common/decks/starter/commander/green_01.dck new file mode 100644 index 00000000000..d82e41cf962 --- /dev/null +++ b/forge-gui/res/adventure/common/decks/starter/commander/green_01.dck @@ -0,0 +1,81 @@ +[metadata] +Name=Starter Commander - Green +[Avatar] + +[Commander] +1 Renata, Called to the Hunt|thb|1 + +[Main] +1 Bashful Beastie|dsk|1 +1 Beanstalk Giant|dsc|1 +1 Bitterbow Sharpshooters|hou|1 +1 Candlelit Cavalry|mid|1 +1 Coliseum Behemoth|fin|1 +1 Colossal Dreadmaw|m21|1 +1 Crash of Rhino Beetles|cmm|1 +1 Disciple of Freyalise|mh3|1 +1 Drove of Elves|cma|1 +1 Duskdale Wurm|ima|1 +1 Generous Ent|ltr|1 +1 Adventure Awaits|znr|1 +1 Carven Caryatid|tdc|1 +1 Earthshaker Dreadmaw|lci|1 +1 Elven Farsight|ltr|1 +1 Fecundity|uma|1 +1 Joraga Visionary|znr|1 +1 Masked Admirers|mma|1 +1 Mild-Mannered Librarian|fdn|1 +1 Owlbear Shepherd|clb|1 +1 Summon: Fenrir|fin|1 +1 Command Beacon|tdc|1 +1 Command Tower|eoc|1 +37 Forest|tla|1 +1 Lightning Greaves|tdc|1 +1 Swiftfoot Boots|tdc|1 +1 Arcane Signet|eoc|1 +1 Boseiju Reaches Skyward|neo|1 +1 Burnished Hart|dsc|1 +1 Commander's Sphere|drc|1 +1 Darksteel Ingot|otc|1 +1 Druid of the Cowl|fdn|1 +1 Elvish Mystic|cmm|1 +1 Golden Hind|jou|1 +1 Goobbue Gardener|fin|1 +1 Hardbristle Bandit|otj|1 +1 Ilysian Caryatid|cmm|1 +1 Leafkin Druid|ncc|1 +1 Llanowar Elves|fdn|1 +1 Manalith|m19|1 +1 Mind Stone|dsc|1 +1 Overgrown Battlement|roe|1 +1 Patchwork Banner|blb|1 +1 Prismatic Lens|otc|1 +1 Relic of Legends|dmu|1 +1 Sol Ring|eoc|1 +1 Solemn Simulacrum|tdc|1 +1 Thought Vessel|dsc|1 +1 Vine Trellis|gvl|1 +1 Affectionate Indrik|fdn|1 +1 Aggressive Instinct|gs1|1 +1 Atzocan Archer|xln|1 +1 Bite Down|fdn|1 +1 Bushwhack|fdn|1 +1 Clash of the Eikons|fin|1 +1 Ent's Fury|ltr|1 +1 Hunter's Talent|blb|1 +1 Kapow!|spm|1 +1 Longstalk Brawl|blb|1 +1 Rabid Bite|blb|1 +1 Commander's Plate|cmr|1 +1 Path of Ancestry|tdc|1 +1 Campfire|cmm|1 + +[Sideboard] + +[Planes] + +[Schemes] + +[Conspiracy] + +[Dungeon] diff --git a/forge-gui/res/adventure/common/decks/starter/commander/red_01.dck b/forge-gui/res/adventure/common/decks/starter/commander/red_01.dck new file mode 100644 index 00000000000..3b52f6e4880 --- /dev/null +++ b/forge-gui/res/adventure/common/decks/starter/commander/red_01.dck @@ -0,0 +1,81 @@ +[metadata] +Name=Starter Commander - Red +[Avatar] + +[Commander] +1 Anax, Hardened in the Forge|cmm|1 + +[Main] +1 Viashino Pyromancer|fdn|1 +1 Bolrac-Clan Basher|mkm|1 +1 Charging Monstrosaur|xln|1 +1 Sabotender|fin|1 +1 Akoum Hellhound|znr|1 +1 Goblin Bushwhacker|zen|1 +1 Skitter of Lizards|cns|1 +1 Alania's Pathmaker|blb|1 +1 Anep, Vizier of Hazoret|j25|1 +1 Battlefield Scavenger|akh|1 +1 Blazing Crescendo|one|1 +1 Boundary Lands Ranger|woe|1 +1 Burning-Tree Vandal|rvr|1 +1 Cleon, Merry Champion|j25|1 +1 Clockwork Percussionist|dsk|1 +1 Dragon Mage|fdn|1 +1 Experimental Synthesizer|neo|1 +1 Fissure Wizard|znr|1 +1 Goblin Researcher|j25|1 +1 Heroes' Hangout|spm|1 +1 Irascible Wolverine|otj|1 +1 Light Up the Stage|dsc|1 +1 Tuskeri Firewalker|khm|1 +1 Voldaren Epicure|inr|1 +1 Command Beacon|tdc|1 +1 Command Tower|eoc|1 +37 Mountain|tle|1 +1 Belligerent Whiptail|bfz|1 +1 Lightning Greaves|tdc|1 +1 Swiftfoot Boots|tdc|1 +1 Battle Squadron|ddt|1 +1 Most Valuable Slayer|dsk|1 +1 Arcane Signet|eoc|1 +1 Burnished Hart|dsc|1 +1 Commander's Sphere|drc|1 +1 Darksteel Ingot|otc|1 +1 Manalith|m19|1 +1 Mind Stone|dsc|1 +1 Patchwork Banner|blb|1 +1 Prismatic Lens|otc|1 +1 Relic of Legends|dmu|1 +1 Sol Ring|eoc|1 +1 Solemn Simulacrum|tdc|1 +1 Thought Vessel|dsc|1 +1 Young Red Dragon|clb|1 +1 Abrade|tdc|1 +1 Fear of Being Hunted|dsk|1 +1 Fire Prophecy|j25|1 +1 Flame Slash|plst|1 +1 Forge Devil|jmp|1 +1 Lava Coil|2x2|1 +1 Lightning Axe|inr|1 +1 Lightning Strike|tla|1 +1 Magma Spray|plst|1 +1 Rolling Thunder|plst|1 +1 Shatter|plst|1 +1 Shock|spm|1 +1 Smash to Smithereens|plst|1 +1 Stoke the Flames|mom|1 +1 Goblin Instigator|moc|1 +1 Commander's Plate|cmr|1 +1 Path of Ancestry|tdc|1 +1 Campfire|cmm|1 + +[Sideboard] + +[Planes] + +[Schemes] + +[Conspiracy] + +[Dungeon] diff --git a/forge-gui/res/adventure/common/decks/starter/commander/white_01.dck b/forge-gui/res/adventure/common/decks/starter/commander/white_01.dck new file mode 100644 index 00000000000..8d02815bd7d --- /dev/null +++ b/forge-gui/res/adventure/common/decks/starter/commander/white_01.dck @@ -0,0 +1,81 @@ +[metadata] +Name=Starter Commander - White +[Avatar] + +[Commander] +1 Daxos, Blessed by the Sun|plst|1 + +[Main] +1 Accorder Paladin|mbs|1 +1 Ajani's Pridemate|fdn|1 +1 Akroan Jailer|ori|1 +1 Alpine Watchdog|m21|1 +1 Battlefield Raptor|khm|1 +1 Cheeky House-Mouse|woe|1 +1 Doomed Traveler|clu|1 +1 Faerie Guidemother|eld|1 +1 Goldnight Commander|tdc|1 +1 Healer's Hawk|fdn|1 +1 Hinterland Sanctifier|fdn|1 +1 Lunarch Veteran|inr|1 +1 Selfless Savior|m21|1 +1 Stonehorn Dignitary|m12|1 +1 Thraben Watcher|mh2|1 +1 Valiant Changeling|clb|1 +1 Errand-Rider of Gondor|ltr|1 +1 Helpful Hunter|fdn|1 +1 Inspiring Overseer|fdn|1 +1 Mentor of the Meek|inr|1 +1 Outlaw Medic|otj|1 +1 Roving Harper|clb|1 +1 Rumor Gatherer|clb|1 +1 Salt Road Packbeast|tdm|1 +1 Search Party Captain|mid|1 +1 Spirited Companion|cmm|1 +1 The Fall of Lord Konda|neo|1 +1 Wall of Omens|tdc|1 +1 Command Beacon|tdc|1 +1 Command Tower|eoc|1 +37 Plains|tle|1 +1 Lightning Greaves|tdc|1 +1 Swiftfoot Boots|tdc|1 +1 Arcane Signet|eoc|1 +1 Burnished Hart|dsc|1 +1 Commander's Sphere|drc|1 +1 Darksteel Ingot|otc|1 +1 Manalith|m19|1 +1 Mind Stone|dsc|1 +1 Patchwork Banner|blb|1 +1 Prismatic Lens|otc|1 +1 Relic of Legends|dmu|1 +1 Sol Ring|eoc|1 +1 Solemn Simulacrum|tdc|1 +1 Thought Vessel|dsc|1 +1 Alabaster Host Intercessor|mom|1 +1 Angelic Edict|jmp|1 +1 Baffling End|rix|1 +1 Banish from Edoras|ltr|1 +1 Banisher Priest|moc|1 +1 Borrowed Time|mid|1 +1 Cathar Commando|inr|1 +1 Celestial Purge|mm2|1 +1 Circle of Confinement|vow|1 +1 Citizen's Arrest|dmu|1 +1 Citizen's Crowbar|snc|1 +1 Githzerai Monk|clb|1 +1 Palace Jailer|cmm|1 +1 Commander's Plate|cmr|1 +1 Path of Ancestry|tdc|1 +1 Campfire|cmm|1 +1 Inspired Charge|mom|1 +1 Coordinated Charge|iko|1 + +[Sideboard] + +[Planes] + +[Schemes] + +[Conspiracy] + +[Dungeon]