mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Implemented Commander variant of Adventure Mode (#8970)
* Added UI elements for commander mode in NewGame screen. - still missing random pool of commander candidates sharing a color with each selected color identity. * Added rudimentary commander choice with preview image. For now, it is 5 suggestions per color identity with the requirement that the chosen color is part of the commander's identity. * Commander card is now added to the player inventory and cannot be sold. The save game adds a flag whether the game is in commander mode, which will be important for the future changes. * Commander is now auto-added to the initial deck. Commander cannot be removed. Commander is properly saved and loaded. * Duels now feature the command zone and all rules * The chosen commander is now set to every deck if the game mode is commander. * Only cards can be added to the deck that fulfill the color identity. * heuristically add a pile of singleton cards to function as the starter for the commander's journey. * Fix land color identity bug in commander pile * Items are put on autosell if they do not match commander identity. * Autosell is now properly set with the card flip timing rules. When visiting a shop, the deck conformaty message does not show anymore. * Remove strict necessity for a fixed commander. This way, a player may choose to switch to a different legendary creature they find. * 15 Streamlined commander choices without having to swap colors individually. * Clean up to remove now redundant i18n label. More focus on creatures for starter commander decks. * Refactor adventure commander deck generation into the DeckgenUtil class * Refactorings as suggested by @Jetz72. * Remove custom deck generator * handle DeckFormat logic through AdventureDeckEditor. Fix bugs, where partner commanders would be overwritten when using the stock DeckgenUtil. * Remove random new line * Code cleanup * Fix unused import error * Fix unused import error * Revert "organise import" changes and random space linebreak changes. * Removed another import package.* statement * Implement fixed commander deck to start with. Removed UI edits and random commander choice. * Add commander-specific cards and a two white overrun effects * Revert to prior string formatting. * Remove import * * Formatting nitpicking to change as little original code as possible. --------- Co-authored-by: Agetian <stavdev@mail.ru>
This commit is contained in:
@@ -25,5 +25,6 @@ public class DifficultyData {
|
||||
public ObjectMap<String,String> starterDecks = null;
|
||||
public ObjectMap<String,String> constructedStarterDecks= null;
|
||||
public ObjectMap<String,String> pileDecks= null;
|
||||
public ObjectMap<String,String> commanderDecks = null;
|
||||
|
||||
}
|
||||
|
||||
@@ -49,10 +49,13 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
||||
|
||||
// Deck data
|
||||
private Deck deck;
|
||||
private final ArrayList<Deck> decks = new ArrayList<Deck>(MIN_DECK_COUNT);
|
||||
private final ArrayList<Deck> 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<PaperCard> autoSellCards = new ItemPool<>(PaperCard.class);
|
||||
public final Set<PaperCard> 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"));
|
||||
|
||||
@@ -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<PaperCard> getCardPool(boolean wantUnique) {
|
||||
return Current.player().getCards();
|
||||
ItemPool<PaperCard> 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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -255,6 +255,12 @@ public class Config {
|
||||
return CardUtil.getDeck(entry.value, false, false, "", false, false);
|
||||
}
|
||||
}
|
||||
case Commander:
|
||||
for (ObjectMap.Entry<String, String> entry : difficultyData.commanderDecks) {
|
||||
if (ColorSet.fromNames(entry.key.toCharArray()).getColor() == color.getColor()) {
|
||||
return CardUtil.getDeck(entry.value, false, false, "", false, false);
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
Reference in New Issue
Block a user