reworked starting deck to jumpstart, constructed or chaos

support localization in UIData and removed it from code (only NewGameScene for now)
This commit is contained in:
Grimm
2022-08-09 13:33:06 +02:00
parent 2e9dc4791d
commit c1a6313b1e
32 changed files with 842 additions and 275 deletions

View File

@@ -100,6 +100,18 @@ public class PrintSheet {
} }
return result; return result;
} }
public boolean containsCardNamed(String name) {
for (Entry<PaperCard, Integer> kv : cardsWithWeights) {
for (int i = 0; i < kv.getValue(); i++) {
if(kv.getKey().getName().equals(name))
return true;
}
}
return false;
}
public String getName() {
return name;
}
public List<PaperCard> random(int number, boolean wantUnique) { public List<PaperCard> random(int number, boolean wantUnique) {
List<PaperCard> result = new ArrayList<>(); List<PaperCard> result = new ArrayList<>();

View File

@@ -14,7 +14,8 @@ public class ConfigData {
public String fontColor; public String fontColor;
public int minDeckSize; public int minDeckSize;
public float playerBaseSpeed; public float playerBaseSpeed;
public String[] starterDecks; public String[] colorIds;
public String[] colorIdNames;
public DifficultyData[] difficulties; public DifficultyData[] difficulties;
public RewardData legalCards; public RewardData legalCards;
public String[] restrictedCards; public String[] restrictedCards;

View File

@@ -1,5 +1,7 @@
package forge.adventure.data; package forge.adventure.data;
import com.badlogic.gdx.utils.ObjectMap;
/** /**
* Data class that will be used to read Json configuration files * Data class that will be used to read Json configuration files
* BiomeData * BiomeData
@@ -13,6 +15,10 @@ public class DifficultyData {
public boolean startingDifficulty; public boolean startingDifficulty;
public int spawnRank = 1; //0 for "easy", 1 for "normal", 2 for "hard". To filter map spawns based on this. public int spawnRank = 1; //0 for "easy", 1 for "normal", 2 for "hard". To filter map spawns based on this.
public float sellFactor=0.2f; public float sellFactor=0.2f;
public float goldLoss=0.2f;
public float lifeLoss=0.2f;
public String[] startItems=new String[0]; public String[] startItems=new String[0];
public ObjectMap<String,String> starterDecks = null;
public ObjectMap<String,String> constructedStarterDecks= null;
} }

View File

@@ -14,4 +14,6 @@ public class GeneratedDeckData {
public RewardData[] mainDeck; public RewardData[] mainDeck;
public RewardData[] sideBoard; public RewardData[] sideBoard;
public String[] jumpstartPacks;
} }

View File

@@ -11,6 +11,7 @@ import forge.adventure.data.HeroListData;
import forge.adventure.data.ItemData; import forge.adventure.data.ItemData;
import forge.adventure.util.*; import forge.adventure.util.*;
import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSave;
import forge.card.ColorSet;
import forge.deck.CardPool; import forge.deck.CardPool;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckProxy; import forge.deck.DeckProxy;
@@ -38,7 +39,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
private int heroRace; private int heroRace;
private int avatarIndex; private int avatarIndex;
private boolean isFemale; private boolean isFemale;
private ColorID colorIdentity = ColorID.COLORLESS; private ColorSet colorIdentity = ColorSet.ALL_COLORS;
// Deck data // Deck data
private Deck deck; private Deck deck;
@@ -106,7 +107,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
private final CardPool cards=new CardPool(); private final CardPool cards=new CardPool();
private final ItemPool<InventoryItem> newCards=new ItemPool<>(InventoryItem.class); private final ItemPool<InventoryItem> newCards=new ItemPool<>(InventoryItem.class);
public void create(String n, int startingColorIdentity, Deck startingDeck, boolean male, int race, int avatar, boolean isFantasy, DifficultyData difficultyData) { public void create(String n, ColorSet startingColorIdentity, Deck startingDeck, boolean male, int race, int avatar, boolean isFantasy, DifficultyData difficultyData) {
clear(); clear();
announceFantasy = fantasyMode = isFantasy; //Set Chaos mode first. announceFantasy = fantasyMode = isFantasy; //Set Chaos mode first.
@@ -131,7 +132,9 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
if (fantasyMode){ //Set a random ColorID in fantasy mode. if (fantasyMode){ //Set a random ColorID in fantasy mode.
setColorIdentity(MyRandom.getRandom().nextInt(5)); // MyRandom to not interfere with the unstable RNG. setColorIdentity(MyRandom.getRandom().nextInt(5)); // MyRandom to not interfere with the unstable RNG.
} else setColorIdentity(startingColorIdentity + 1); // +1 because index 0 is colorless. }
else
this.colorIdentity=startingColorIdentity;
life = maxLife = difficultyData.startingLife; life = maxLife = difficultyData.startingLife;
@@ -177,26 +180,12 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public Collection<String> getEquippedItems() { return equippedItems.values(); } public Collection<String> getEquippedItems() { return equippedItems.values(); }
public ItemPool<InventoryItem> getNewCards() { return newCards; } public ItemPool<InventoryItem> getNewCards() { return newCards; }
public String getColorIdentity(){ public byte getColorIdentity(){
switch (colorIdentity){ return colorIdentity.getColor();
case BLUE : return "U";
case GREEN : return "G";
case RED : return "R";
case BLACK : return "B";
case WHITE : return "W";
case COLORLESS: default: return "C"; //You are either Ugin or an Eldrazi. Nice.
}
} }
public String getColorIdentityLong(){ public String getColorIdentityLong(){
switch (colorIdentity){ return colorIdentity.toString();
case BLUE : return "blue";
case GREEN : return "green";
case RED : return "red";
case BLACK : return "black";
case WHITE : return "white";
case COLORLESS: default: return "colorless";
}
} }
@@ -209,25 +198,11 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
} }
public void setColorIdentity(String C){ public void setColorIdentity(String C){
switch (C.toUpperCase()){ colorIdentity= ColorSet.fromNames(C.toCharArray());
case "B": this.colorIdentity = ColorID.BLACK; break;
case "G": this.colorIdentity = ColorID.GREEN; break;
case "R": this.colorIdentity = ColorID.RED; break;
case "U": this.colorIdentity = ColorID.BLUE; break;
case "W": this.colorIdentity = ColorID.WHITE; break;
case "C": default: this.colorIdentity = ColorID.COLORLESS; break;
}
} }
public void setColorIdentity(int C){ public void setColorIdentity(int C){
switch (C){ colorIdentity= ColorSet.fromMask(C);
case 2: this.colorIdentity = ColorID.BLACK; break;
case 5: this.colorIdentity = ColorID.GREEN; break;
case 4: this.colorIdentity = ColorID.RED; break;
case 3: this.colorIdentity = ColorID.BLUE; break;
case 1: this.colorIdentity = ColorID.WHITE; break;
case 0: default: this.colorIdentity = ColorID.COLORLESS; break;
}
} }
@@ -250,8 +225,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
heroRace = data.readInt("heroRace"); heroRace = data.readInt("heroRace");
avatarIndex = data.readInt("avatarIndex"); avatarIndex = data.readInt("avatarIndex");
isFemale = data.readBool("isFemale"); isFemale = data.readBool("isFemale");
if(data.containsKey("colorIdentity")) setColorIdentity(data.readString("colorIdentity")); if(data.containsKey("colorIdentity"))
else colorIdentity = ColorID.COLORLESS; setColorIdentity(data.readString("colorIdentity"));
else
colorIdentity = ColorSet.ALL_COLORS;
gold = data.readInt("gold"); gold = data.readInt("gold");
maxLife = data.readInt("maxLife"); maxLife = data.readInt("maxLife");
@@ -342,7 +319,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
data.store("heroRace",heroRace); data.store("heroRace",heroRace);
data.store("avatarIndex",avatarIndex); data.store("avatarIndex",avatarIndex);
data.store("isFemale",isFemale); data.store("isFemale",isFemale);
data.store("colorIdentity", getColorIdentity()); data.store("colorIdentity", colorIdentity.getColor());
data.store("fantasyMode",fantasyMode); data.store("fantasyMode",fantasyMode);
data.store("announceFantasy",announceFantasy); data.store("announceFantasy",announceFantasy);
@@ -466,9 +443,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
onLifeTotalChangeList.emit(); onLifeTotalChangeList.emit();
} }
public void defeated() { public void defeated() {
int percentLoss = 10; gold= (int) (gold-(gold*difficultyData.goldLoss));
gold=gold-(gold*percentLoss/100); life=Math.max(1,(int)(life-(maxLife*difficultyData.lifeLoss)));
life=Math.max(1,(int)(life-(maxLife*0.2f)));
onLifeTotalChangeList.emit(); onLifeTotalChangeList.emit();
onGoldChangeList.emit(); onGoldChangeList.emit();
} }

View File

@@ -11,10 +11,13 @@ import com.badlogic.gdx.utils.Array;
import forge.Forge; import forge.Forge;
import forge.adventure.data.DifficultyData; import forge.adventure.data.DifficultyData;
import forge.adventure.data.HeroListData; import forge.adventure.data.HeroListData;
import forge.adventure.data.UIData;
import forge.adventure.util.Config; import forge.adventure.util.Config;
import forge.adventure.util.Controls; import forge.adventure.util.Controls;
import forge.adventure.util.Selector; import forge.adventure.util.Selector;
import forge.adventure.util.UIActor;
import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSave;
import forge.card.ColorSet;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckProxy; import forge.deck.DeckProxy;
import forge.localinstance.properties.ForgePreferences; import forge.localinstance.properties.ForgePreferences;
@@ -30,20 +33,14 @@ import java.util.Random;
*/ */
public class NewGameScene extends UIScene { public class NewGameScene extends UIScene {
TextField selectedName; TextField selectedName;
Deck[] starterDeck; ColorSet[] starterDeck;
private Image avatarImage; private Image avatarImage;
private int avatarIndex = 0; private int avatarIndex = 0;
private Selector race; private Selector race;
private Selector deck; private Selector colorId;
private Selector gender; private Selector gender;
private Selector mode;
private Selector difficulty; private Selector difficulty;
private ScrollPane scrollPane;
private Label titleL, avatarL, nameL, raceL, genderL, difficultyL, deckL;
private ImageButton leftArrow, rightArrow;
private TextButton backButton, startButton;
boolean fantasyMode = false;
boolean easyMode = false;
private CheckBox box, box2;
public NewGameScene() { public NewGameScene() {
super(Forge.isLandscapeMode() ? "ui/new_game.json" : "ui/new_game_portrait.json"); super(Forge.isLandscapeMode() ? "ui/new_game.json" : "ui/new_game_portrait.json");
@@ -59,9 +56,9 @@ public class NewGameScene extends UIScene {
gender.getCurrentIndex() == 0, gender.getCurrentIndex() == 0,
race.getCurrentIndex(), race.getCurrentIndex(),
avatarIndex, avatarIndex,
deck.getCurrentIndex(), starterDeck[colorId.getCurrentIndex()],
Config.instance().getConfigData().difficulties[difficulty.getCurrentIndex()], Config.instance().getConfigData().difficulties[difficulty.getCurrentIndex()],
fantasyMode, easyMode, deck.getText(), 0); mode.getCurrentIndex()==2, mode.getCurrentIndex()==1, 0);//maybe replace with enum
GamePlayerUtil.getGuiPlayer().setName(selectedName.getText()); GamePlayerUtil.getGuiPlayer().setName(selectedName.getText());
Forge.clearTransitionScreen(); Forge.clearTransitionScreen();
Forge.switchScene(SceneType.GameScene.instance); Forge.switchScene(SceneType.GameScene.instance);
@@ -82,20 +79,27 @@ public class NewGameScene extends UIScene {
selectedName.setText(NameGenerator.getRandomName("Any", "Any", "")); selectedName.setText(NameGenerator.getRandomName("Any", "Any", ""));
avatarImage = ui.findActor("avatarPreview"); avatarImage = ui.findActor("avatarPreview");
gender = ui.findActor("gender"); gender = ui.findActor("gender");
mode = ui.findActor("mode");
mode.setTextList(new String[]{"Standard", "Constructed","Chaos"});
gender.setTextList(new String[]{"Male", "Female"}); gender.setTextList(new String[]{"Male", "Female"});
gender.addListener(event -> NewGameScene.this.updateAvatar()); gender.addListener(event -> NewGameScene.this.updateAvatar());
Random rand = new Random(); Random rand = new Random();
deck = ui.findActor("deck"); colorId = ui.findActor("colorId");
starterDeck = Config.instance().starterDecks(); String[] colorSet=Config.instance().colorIds();
String[] colorIdNames=Config.instance().colorIdNames();
starterDeck= new ColorSet[colorSet.length];
for(int i=0;i<starterDeck.length;i++)
starterDeck[i]= ColorSet.fromNames(colorSet[i].toCharArray());
Array<String> stringList = new Array<>(starterDeck.length); Array<String> stringList = new Array<>(starterDeck.length);
for (Deck deck : starterDeck) for (String idName : colorIdNames)
stringList.add(deck.getName()); stringList.add(UIActor.localize(idName));
Array<String> chaos = new Array<>(); Array<String> chaos = new Array<>();
chaos.add("Preconstructed"); chaos.add("Preconstructed");
Array<String> easyDecks = new Array<>(); Array<String> easyDecks = new Array<>();
for (DeckProxy deckProxy : DeckProxy.getAllEasyStarterDecks()) for (DeckProxy deckProxy : DeckProxy.getAllEasyStarterDecks())
easyDecks.add(deckProxy.getName()); easyDecks.add(deckProxy.getName());
deck.setTextList(stringList); colorId.setTextList(stringList);
race = ui.findActor("race"); race = ui.findActor("race");
race.addListener(event -> NewGameScene.this.updateAvatar()); race.addListener(event -> NewGameScene.this.updateAvatar());
race.setTextList(HeroListData.getRaces()); race.setTextList(HeroListData.getRaces());
@@ -114,86 +118,14 @@ public class NewGameScene extends UIScene {
difficulty.setCurrentIndex(startingDifficulty); difficulty.setCurrentIndex(startingDifficulty);
avatarIndex = rand.nextInt(); avatarIndex = rand.nextInt();
gender.setCurrentIndex(rand.nextInt()); gender.setCurrentIndex(rand.nextInt());
deck.setCurrentIndex(rand.nextInt()); colorId.setCurrentIndex(rand.nextInt());
race.setCurrentIndex(rand.nextInt()); race.setCurrentIndex(rand.nextInt());
ui.onButtonPress("back", () -> NewGameScene.this.back()); ui.onButtonPress("back", () -> NewGameScene.this.back());
ui.onButtonPress("start", () -> NewGameScene.this.start()); ui.onButtonPress("start", () -> NewGameScene.this.start());
ui.onButtonPress("leftAvatar", () -> NewGameScene.this.leftAvatar()); ui.onButtonPress("leftAvatar", () -> NewGameScene.this.leftAvatar());
ui.onButtonPress("rightAvatar", () -> NewGameScene.this.rightAvatar()); ui.onButtonPress("rightAvatar", () -> NewGameScene.this.rightAvatar());
scrollPane = ui.findActor("scroll");
titleL = ui.findActor("titleL");
titleL.setScale(2, 2);
titleL.setText(Forge.getLocalizer().getMessage("lblCreateACharacter"));
titleL.setX(scrollPane.getX() + 20);
avatarL = ui.findActor("avatarL");
avatarL.setText(Forge.getLocalizer().getMessage("lblAvatar"));
nameL = ui.findActor("nameL");
nameL.setText(Forge.getLocalizer().getMessage("lblName"));
raceL = ui.findActor("raceL");
raceL.setText(Forge.getLocalizer().getMessage("lblRace"));
genderL = ui.findActor("genderL");
genderL.setText(Forge.getLocalizer().getMessage("lblGender"));
difficultyL = ui.findActor("difficultyL");
difficultyL.setText(Forge.getLocalizer().getMessage("lblDifficulty"));
deckL = ui.findActor("deckL");
deckL.setText(Forge.getLocalizer().getMessage("lblDeck"));
box2 = Controls.newCheckBox("");
box2.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent changeEvent, Actor actor) {
if (((CheckBox) actor).isChecked()) {
box.setChecked(false);
easyMode = true;
fantasyMode = false;
deck.setTextList(easyDecks);
} else {
easyMode = false;
deck.setTextList(stringList);
}
}
});
box = Controls.newCheckBox("");
box.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
if (((CheckBox) actor).isChecked()) {
box2.setChecked(false);
fantasyMode = true;
easyMode = false;
deck.setTextList(chaos);
} else {
fantasyMode = false;
deck.setTextList(stringList);
}
}
});
//easy mode
box2.setBounds(deckL.getX()-box2.getHeight(), deckL.getY()-box2.getHeight(), deckL.getHeight(), deckL.getHeight());
Label label2 = Controls.newLabel("Starter");
label2.setColor(Color.BLACK);
label2.setBounds(box2.getX()+22, box2.getY(), box2.getWidth(), box2.getHeight());
ui.addActor(box2);
ui.addActor(label2);
//chaos mode
box.setBounds(label2.getX()+25, label2.getY(), box2.getWidth(), box2.getHeight());
Label label = Controls.newLabel("Chaos");
label.setColor(Color.BLACK);
label.setBounds(box.getX()+22, box.getY(), box.getWidth(), box.getHeight());
ui.addActor(box);
ui.addActor(label);
if (easyDecks.isEmpty()) {
box2.setDisabled(true);
box2.getColor().a = 0.5f;
label2.getColor().a = 0.5f;
}
leftArrow = ui.findActor("leftAvatar");
rightArrow = ui.findActor("rightAvatar");
backButton = ui.findActor("back");
backButton.getLabel().setText(Forge.getLocalizer().getMessage("lblBack"));
startButton = ui.findActor("start");
startButton.getLabel().setText(Forge.getLocalizer().getMessage("lblStart"));
} }
@@ -230,9 +162,9 @@ public class NewGameScene extends UIScene {
gender.getCurrentIndex() == 0, gender.getCurrentIndex() == 0,
race.getCurrentIndex(), race.getCurrentIndex(),
avatarIndex, avatarIndex,
deck.getCurrentIndex(), starterDeck[colorId.getCurrentIndex()],
Config.instance().getConfigData().difficulties[difficulty.getCurrentIndex()], Config.instance().getConfigData().difficulties[difficulty.getCurrentIndex()],
fantasyMode, easyMode, deck.getText(), 0); mode.getCurrentIndex()==2, mode.getCurrentIndex()==1, 0);//maybe replace with enum
GamePlayerUtil.getGuiPlayer().setName(selectedName.getText()); GamePlayerUtil.getGuiPlayer().setName(selectedName.getText());
Forge.switchScene(SceneType.GameScene.instance); Forge.switchScene(SceneType.GameScene.instance);
} }

View File

@@ -17,6 +17,7 @@ import forge.adventure.util.Config;
import forge.adventure.util.Controls; import forge.adventure.util.Controls;
import forge.adventure.util.Current; import forge.adventure.util.Current;
import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSave;
import forge.card.MagicColor;
import forge.player.GamePlayerUtil; import forge.player.GamePlayerUtil;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@@ -59,16 +60,16 @@ public class PlayerStatisticScene extends UIScene {
Forge.switchToLast(); Forge.switchToLast();
return true; return true;
} }
private TextureRegion getColorFrame(String C){ private TextureRegion getColorFrame(byte C){
int x, y; int x, y;
switch(C){ switch(C){
case "B": { x = 0 ; y = 0 ; break; } case MagicColor.BLACK: { x = 0 ; y = 0 ; break; }
case "G": { x = 64; y = 0 ; break; } case MagicColor.GREEN: { x = 64; y = 0 ; break; }
case "R": { x = 0 ; y = 32; break; } case MagicColor.RED: { x = 0 ; y = 32; break; }
case "U": { x = 32; y = 32; break; } case MagicColor.BLUE: { x = 32; y = 32; break; }
case "W": { x = 64; y = 32; break; } case MagicColor.WHITE: { x = 64; y = 32; break; }
default: default:
case "C": { x = 32; y = 0 ; break; } case MagicColor.COLORLESS: { x = 32; y = 0 ; break; }
} }
TextureRegion result = new TextureRegion(colorFrames, x, y, 32, 32); TextureRegion result = new TextureRegion(colorFrames, x, y, 32, 32);
return result; return result;

View File

@@ -1,23 +1,33 @@
package forge.adventure.util; package forge.adventure.util;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.Json;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.sun.org.apache.xerces.internal.xs.StringList;
import forge.StaticData;
import forge.adventure.data.GeneratedDeckData; import forge.adventure.data.GeneratedDeckData;
import forge.adventure.data.GeneratedDeckTemplateData; import forge.adventure.data.GeneratedDeckTemplateData;
import forge.adventure.data.RewardData; import forge.adventure.data.RewardData;
import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSave;
import forge.card.CardRarity; import forge.card.*;
import forge.card.CardType;
import forge.card.MagicColor;
import forge.card.mana.ManaCostShard; import forge.card.mana.ManaCostShard;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.deck.DeckgenUtil; import forge.deck.DeckgenUtil;
import forge.deck.io.DeckSerializer; import forge.deck.io.DeckSerializer;
import forge.item.BoosterPack;
import forge.item.InventoryItem;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.item.SealedProduct;
import forge.item.generation.BoosterGenerator;
import forge.item.generation.BoosterSlots;
import forge.model.FModel; import forge.model.FModel;
import forge.util.Aggregates;
import org.apache.commons.lang3.tuple.Pair;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@@ -287,13 +297,44 @@ public class CardUtil {
public static Deck generateDeck(GeneratedDeckData data) public static Deck generateDeck(GeneratedDeckData data)
{ {
Deck deck= new Deck(data.name); Deck deck= new Deck(data.name);
if(data.template==null) if(data.mainDeck!=null)
{ {
deck.getOrCreate(DeckSection.Main).addAllFlat(generateAllCards(Arrays.asList(data.mainDeck), true)); deck.getOrCreate(DeckSection.Main).addAllFlat(generateAllCards(Arrays.asList(data.mainDeck), true));
if(data.sideBoard!=null) if(data.sideBoard!=null)
deck.getOrCreate(DeckSection.Sideboard).addAllFlat(generateAllCards(Arrays.asList(data.sideBoard), true)); deck.getOrCreate(DeckSection.Sideboard).addAllFlat(generateAllCards(Arrays.asList(data.sideBoard), true));
return deck; return deck;
} }
if(data.jumpstartPacks!=null)
{
deck.getOrCreate(DeckSection.Main);
for(int i=0;i<data.jumpstartPacks.length;i++)
{
String targetName;
switch (MagicColor.fromName(data.jumpstartPacks[i]))
{
default:
case MagicColor.WHITE: targetName = "Plains"; break;
case MagicColor.BLUE: targetName = "Island"; break;
case MagicColor.BLACK: targetName = "Swamp"; break;
case MagicColor.RED: targetName = "Mountain";break;
case MagicColor.GREEN: targetName = "Forest"; break;
}
List<PrintSheet> candidates=new ArrayList<>();
for(PrintSheet sheet : StaticData.instance().getPrintSheets())
{
if(sheet.containsCardNamed(targetName)&&sheet.getName().startsWith("JMP"))
{
candidates.add(sheet);
}
}
deck.getOrCreate(DeckSection.Main).addAllFlat(candidates.get(Current.world().getRandom().nextInt(candidates.size())).all());
}
return deck;
}
if(data.template!=null)
{
float count=data.template.count; float count=data.template.count;
float lands=count*0.4f; float lands=count*0.4f;
float spells=count-lands; float spells=count-lands;
@@ -304,6 +345,7 @@ public class CardUtil {
nonLand.addAll(fillWithLands(nonLand,data.template)); nonLand.addAll(fillWithLands(nonLand,data.template));
deck.getOrCreate(DeckSection.Main).addAllFlat(nonLand); deck.getOrCreate(DeckSection.Main).addAllFlat(nonLand);
}
return deck; return deck;
} }

View File

@@ -4,9 +4,12 @@ import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.JsonWriter; import com.badlogic.gdx.utils.JsonWriter;
import com.badlogic.gdx.utils.ObjectMap;
import forge.Forge; import forge.Forge;
import forge.adventure.data.ConfigData; import forge.adventure.data.ConfigData;
import forge.adventure.data.DifficultyData;
import forge.adventure.data.SettingData; import forge.adventure.data.SettingData;
import forge.card.ColorSet;
import forge.deck.Deck; import forge.deck.Deck;
import forge.gui.GuiBase; import forge.gui.GuiBase;
import forge.localinstance.properties.ForgeConstants; import forge.localinstance.properties.ForgeConstants;
@@ -26,7 +29,7 @@ public class Config {
private static Config currentConfig; private static Config currentConfig;
private final String prefix; private final String prefix;
private final HashMap<String, FileHandle> Cache = new HashMap<String, FileHandle>(); private final HashMap<String, FileHandle> Cache = new HashMap<String, FileHandle>();
private final ConfigData configData; private ConfigData configData;
private final String[] adventures; private final String[] adventures;
private SettingData settingsData; private SettingData settingsData;
private String Lang = "en-us"; private String Lang = "en-us";
@@ -83,8 +86,17 @@ public class Config {
prefix = path + "/res/adventure/" + plane + "/"; prefix = path + "/res/adventure/" + plane + "/";
if (FModel.getPreferences() != null) if (FModel.getPreferences() != null)
Lang = FModel.getPreferences().getPref(ForgePreferences.FPref.UI_LANGUAGE); Lang = FModel.getPreferences().getPref(ForgePreferences.FPref.UI_LANGUAGE);
try
{
configData = new Json().fromJson(ConfigData.class, new FileHandle(prefix + "config.json")); configData = new Json().fromJson(ConfigData.class, new FileHandle(prefix + "config.json"));
}
catch (Exception e)
{
e.printStackTrace();
configData=new ConfigData();
}
} }
public ConfigData getConfigData() { public ConfigData getConfigData() {
@@ -121,13 +133,23 @@ public class Config {
return plane; return plane;
} }
public Deck[] starterDecks() { public String[] colorIdNames() {
Deck[] deck = new Deck[configData.starterDecks.length]; return configData.colorIdNames;
for (int i = 0; i < configData.starterDecks.length; i++) {
deck[i] = CardUtil.getDeck(configData.starterDecks[i], false, false, "", false, false);
} }
return deck; public String[] colorIds() {
return configData.colorIds;
}
public Deck starterDeck(ColorSet color, DifficultyData difficultyData) {
for(ObjectMap.Entry<String, String> entry:difficultyData.starterDecks)
{
if(ColorSet.fromNames(entry.key.toCharArray()).getColor()==color.getColor())
{
return CardUtil.getDeck(entry.value, false, false, "", false, false);
}
}
return null;
} }
public TextureAtlas getAtlas(String spriteAtlas) { public TextureAtlas getAtlas(String spriteAtlas) {

View File

@@ -9,6 +9,7 @@ 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.MapStage; import forge.adventure.stage.MapStage;
import forge.card.ColorSet;
import forge.util.Localizer; import forge.util.Localizer;
/** /**
@@ -154,7 +155,8 @@ public class MapDialog {
} else if(condition.not) return false; } else if(condition.not) return false;
} }
if(condition.colorIdentity != null && !condition.colorIdentity.isEmpty()) { //Check for player's color ID. if(condition.colorIdentity != null && !condition.colorIdentity.isEmpty()) { //Check for player's color ID.
if(!player.getColorIdentity().equals(condition.colorIdentity.toUpperCase())){ if(player.getColorIdentity()!=(ColorSet.fromNames(condition.colorIdentity.toCharArray()).getColor()))
{
if(!condition.not) return false; if(!condition.not) return false;
} else if(condition.not) return false; } else if(condition.not) return false;
} }

View File

@@ -13,8 +13,12 @@ import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.OrderedMap; import com.badlogic.gdx.utils.OrderedMap;
import forge.Forge;
import forge.adventure.data.UIData; import forge.adventure.data.UIData;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* Group of controls that will be loaded from a configuration file * Group of controls that will be loaded from a configuration file
*/ */
@@ -86,6 +90,9 @@ public class UIActor extends Group {
float yValue = 0; float yValue = 0;
for (ObjectMap.Entry property : new OrderedMap.OrderedMapEntries<>(element)) { for (ObjectMap.Entry property : new OrderedMap.OrderedMapEntries<>(element)) {
switch (property.key.toString()) { switch (property.key.toString()) {
case "scale":
newActor.setScale((Float) property.value);
break;
case "width": case "width":
newActor.setWidth((Float) property.value); newActor.setWidth((Float) property.value);
break; break;
@@ -152,7 +159,8 @@ public class UIActor extends Group {
for (ObjectMap.Entry property : entries) { for (ObjectMap.Entry property : entries) {
switch (property.key.toString()) { switch (property.key.toString()) {
case "text": case "text":
newActor.setText(property.value.toString());
newActor.setText(localize(property.value.toString()));
break; break;
case "align": case "align":
newActor.setAlignment(((Float) property.value).intValue()); newActor.setAlignment(((Float) property.value).intValue());
@@ -161,6 +169,18 @@ public class UIActor extends Group {
} }
} }
public static String localize(String str) {
Pattern regex=Pattern.compile("\\{[^\\}]*\\}");
for(int i=0;i<100;i++)
{
Matcher matcher= regex.matcher(str);
if(!matcher.find())
return str;
str=matcher.replaceAll(Forge.getLocalizer().getMessage(matcher.group().substring(1,matcher.group().length()-1)));
}
return str;
}
private void readImageButtonProperties(ImageButton newActor, ObjectMap.Entries<String, String> entries) { private void readImageButtonProperties(ImageButton newActor, ObjectMap.Entries<String, String> entries) {
for (ObjectMap.Entry property : entries) { for (ObjectMap.Entry property : entries) {
switch (property.key.toString()) { switch (property.key.toString()) {
@@ -176,7 +196,7 @@ public class UIActor extends Group {
for (ObjectMap.Entry property : entries) { for (ObjectMap.Entry property : entries) {
switch (property.key.toString()) { switch (property.key.toString()) {
case "text": case "text":
newActor.setText(property.value.toString()); newActor.setText(localize(property.value.toString()));
break; break;
case "font"://legacy case "font"://legacy
style.font = Controls.getBitmapFont(property.value.toString()); style.font = Controls.getBitmapFont(property.value.toString());
@@ -221,7 +241,7 @@ public class UIActor extends Group {
for (ObjectMap.Entry property : entries) { for (ObjectMap.Entry property : entries) {
switch (property.key.toString()) { switch (property.key.toString()) {
case "text": case "text":
newActor.setText(property.value.toString()); newActor.setText(localize(property.value.toString()));
break; break;
} }
} }
@@ -231,7 +251,7 @@ public class UIActor extends Group {
for (ObjectMap.Entry property : entries) { for (ObjectMap.Entry property : entries) {
switch (property.key.toString()) { switch (property.key.toString()) {
case "text": case "text":
newActor.setText(property.value.toString()); newActor.setText(localize(property.value.toString()));
break; break;
} }
} }

View File

@@ -7,6 +7,7 @@ import forge.adventure.stage.WorldStage;
import forge.adventure.util.Config; import forge.adventure.util.Config;
import forge.adventure.util.SaveFileData; import forge.adventure.util.SaveFileData;
import forge.adventure.util.SignalList; import forge.adventure.util.SignalList;
import forge.card.ColorSet;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckProxy; import forge.deck.DeckProxy;
import forge.deck.DeckgenUtil; import forge.deck.DeckgenUtil;
@@ -122,24 +123,23 @@ public class WorldSave {
return currentSave; return currentSave;
} }
public static WorldSave generateNewWorld(String name, boolean male, int race, int avatarIndex, int startingColorIdentity, DifficultyData diff, boolean isFantasy, boolean isEasy, String starter, long seed) { public static WorldSave generateNewWorld(String name, boolean male, int race, int avatarIndex, ColorSet startingColorIdentity, DifficultyData diff, boolean isFantasy, boolean isEasy, long seed) {
currentSave.world.generateNew(seed); currentSave.world.generateNew(seed);
currentSave.pointOfInterestChanges.clear(); currentSave.pointOfInterestChanges.clear();
Deck starterDeck; Deck starterDeck;
int identity = startingColorIdentity;
if (isEasy) { if (isEasy) {
DeckProxy dp = DeckProxy.getAllEasyStarterDecks().get(startingColorIdentity); DeckProxy dp = DeckProxy.getAllEasyStarterDecks().get(0);
starterDeck = dp.getDeck(); starterDeck = dp.getDeck();
identity = dp.getColorIdentityforAdventure(); startingColorIdentity = dp.getColorIdentity();
} else { } else {
starterDeck = isFantasy ? DeckgenUtil.getRandomOrPreconOrThemeDeck("", false, false, false) : Config.instance().starterDecks()[startingColorIdentity]; starterDeck = isFantasy ? DeckgenUtil.getRandomOrPreconOrThemeDeck("", false, false, false) : Config.instance().starterDeck(startingColorIdentity,diff);
} }
currentSave.player.create(name, startingColorIdentity, starterDeck, male, race, avatarIndex, isFantasy, diff); currentSave.player.create(name, startingColorIdentity, starterDeck, male, race, avatarIndex, isFantasy, diff);
currentSave.player.setWorldPosY((int) (currentSave.world.getData().playerStartPosY * currentSave.world.getData().height * currentSave.world.getTileSize())); 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.player.setWorldPosX((int) (currentSave.world.getData().playerStartPosX * currentSave.world.getData().width * currentSave.world.getTileSize()));
//after getting deck override starting color identity to match //after getting deck override starting color identity to match
if (identity != startingColorIdentity) //if (identity != startingColorIdentity)
currentSave.player.setColorIdentity(identity); // currentSave.player.setColorIdentity(identity);
currentSave.onLoadList.emit(); currentSave.onLoadList.emit();
return currentSave; return currentSave;
//return currentSave = ret; //return currentSave = ret;

View File

@@ -4,13 +4,8 @@
"skin": "skin/ui_skin.json", "skin": "skin/ui_skin.json",
"playerBaseSpeed": 32, "playerBaseSpeed": 32,
"minDeckSize": 40, "minDeckSize": 40,
"starterDecks": [ "colorIds":["W","U","B","R","G"],
"decks/starter/white.json", "colorIdNames":["{lblWhite}","{lblBlue}","{lblBlack}","{lblRed}","{lblGreen}"],
"decks/starter/black.json",
"decks/starter/blue.json",
"decks/starter/red.json",
"decks/starter/green.json"
],
"restrictedCards": [ "restrictedCards": [
"Black Lotus", "Black Lotus",
"Mox Emerald", "Mox Emerald",
@@ -49,7 +44,23 @@
"staringMoney": 500, "staringMoney": 500,
"enemyLifeFactor": 0.8, "enemyLifeFactor": 0.8,
"spawnRank": 0, "spawnRank": 0,
"goldLoss": 0.02,
"lifeLoss": 0.1,
"sellFactor": 0.6, "sellFactor": 0.6,
"starterDecks": {
"W":"decks/starter/white_e.json",
"B":"decks/starter/black_e.json",
"U":"decks/starter/blue_e.json",
"R":"decks/starter/red_e.json",
"G":"decks/starter/green_e.json"
},
"constructedStarterDecks": {
"W":"decks/starter/Adventure - Low White.dck",
"B":"decks/starter/Adventure - Low Black.dck",
"U":"decks/starter/Adventure - Low Blue.dck",
"R":"decks/starter/Adventure - Low Red.dck",
"G":"decks/starter/Adventure - Low Green.dck"
},
"startItems": [ "startItems": [
"Manasight Amulet", "Manasight Amulet",
"Leather Boots" "Leather Boots"
@@ -61,7 +72,23 @@
"startingDifficulty": true, "startingDifficulty": true,
"enemyLifeFactor": 1.0, "enemyLifeFactor": 1.0,
"spawnRank": 1, "spawnRank": 1,
"goldLoss": 0.1,
"lifeLoss": 0.2,
"sellFactor": 0.5, "sellFactor": 0.5,
"starterDecks": {
"W":"decks/starter/white_n.json",
"B":"decks/starter/black_n.json",
"U":"decks/starter/blue_n.json",
"R":"decks/starter/red_n.json",
"G":"decks/starter/green_n.json"
},
"constructedStarterDecks": {
"W":"decks/starter/Adventure - Low Azorius.dck",
"B":"decks/starter/Adventure - Low Rakdos.dck",
"U":"decks/starter/Adventure - Low Dimir.dck",
"R":"decks/starter/Adventure - Low Gruul.dck",
"G":"decks/starter/Adventure - Low Selesnya.dck"
},
"startItems": [ "startItems": [
"Leather Boots" "Leather Boots"
] ]
@@ -71,7 +98,23 @@
"staringMoney": 125, "staringMoney": 125,
"enemyLifeFactor": 1.5, "enemyLifeFactor": 1.5,
"spawnRank": 2, "spawnRank": 2,
"sellFactor": 0.25 "goldLoss": 0.5,
"lifeLoss": 0.3,
"sellFactor": 0.25,
"starterDecks": {
"W":"decks/starter/white_h.json",
"B":"decks/starter/black_h.json",
"U":"decks/starter/blue_h.json",
"R":"decks/starter/red_h.json",
"G":"decks/starter/green_h.json"
},
"constructedStarterDecks": {
"W":"decks/starter/Adventure - Low Orzhov.dck",
"B":"decks/starter/Adventure - Low Golgari.dck",
"U":"decks/starter/Adventure - Low Izzet.dck",
"R":"decks/starter/Adventure - Low Boros.dck",
"G":"decks/starter/Adventure - Low Simic.dck"
}
} }
] ]
} }

View File

@@ -0,0 +1,33 @@
[metadata]
Name=Adventure - Low Azorius
[Avatar]
[Main]
2 Aqueous Form|CMR|1
1 Ardenn, Intrepid Archaeologist|CMR|1
1 Auramancer's Guise|PLC|1
2 Azorius Locket|C19|1
2 Cartouche of Knowledge|AKH|1
2 Cartouche of Solidarity|AKH|1
1 Danitha Capashen, Paragon|CMR|1
1 Dawn Evangel|THB|1
2 Ethereal Armor|Q06|1
1 Face of Divinity|JMP|1
1 Graceblade Artisan|DTK|1
2 Heliod's Pilgrim|THB|1
1 Ironclad Slayer|CMR|1
7 Island|GK2|1
4 Meandering River|GS1|1
7 Plains|GK2|1
1 Sovereigns of Lost Alara|UMA|1
2 Transcendent Envoy|THB|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,32 @@
[metadata]
Name=Adventure - Low Black
[Avatar]
[Main]
1 Animate Dead|MB1|1
1 Archfiend of Depravity|E01|1
1 Banewhip Punisher|HOU|1
2 Cartouche of Ambition|AKR|1
2 Chainer's Edict|HA3|1
1 Clattering Augur|MH2|1
1 Dance of the Dead|ME2|1
1 Deadly Dispute|AFR|1
2 Doom Blade|STA|1
1 Draugr Recruiter|KHM|1
2 Ecstatic Awakener|MID|1
1 Indulgent Tormentor|IMA|1
1 Reassembling Skeleton|AFC|1
2 Sanitarium Skeleton|CMR|1
2 Soldevi Adnate|ALL|1
1 Stab Wound|JMP|1
18 Swamp|GK1|2
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,32 @@
[metadata]
Name=Adventure - Low Blue
[Avatar]
[Main]
1 Acquisition Octopus|NEO|1
2 Armguard Familiar|NEO|1
2 Boomerang|DPA|1
1 Broodstar|HOP|1
1 Callaphe, Beloved of the Sea|THB|1
2 Disruption Protocol|NEO|1
1 Ensoul Artifact|M15|1
2 Etherium Sculptor|NEC|1
2 Faerie Mechanist|2XM|1
2 Into the Roil|ZNR|1
13 Island|GK2|1
1 Mysterious Tome|MID|1
1 Replication Specialist|NEO|1
4 Seat of the Synod|C18|1
2 Silver Myr|NEC|1
2 Sky Diamond|KHC|1
1 Trickster's Talisman|AFR|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,33 @@
[metadata]
Name=Adventure - Low Boros
[Avatar]
[Main]
1 Balefire Liege|HOP|1
2 Battlegate Mimic|EVE|1
1 Boros Charm|NCC|1
2 Boros Locket|C21|1
2 Boros Recruit|RAV|1
2 Double Cleave|UMA|1
1 Faith Unbroken|CMR|1
1 Flamewright|CNS|1
1 Highspire Mantis|KTK|1
2 Impetuous Sunchaser|BNG|1
1 Lightning Helix|DDH|1
7 Mountain|GK1|2
7 Plains|GK1|1
2 Scourge of the Nobilis|EVE|1
1 Spitemare|DDH|1
1 Squee's Embrace|APC|1
4 Stone Quarry|M19|1
2 Temur Battle Rage|CMR|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,33 @@
[metadata]
Name=Adventure - Low Dimir
[Avatar]
[Main]
1 Animate Dead|MB1|1
2 Canal Courier|CN2|1
2 Chainer's Edict|VMA|1
2 Deathcult Rogue|GTC|1
1 Deepchannel Mentor|SHM|1
2 Dimir Locket|GRN|1
2 Gravelgill Duo|SHM|1
2 Hideous End|MB1|1
2 Infiltrate|NMS|1
1 Inkfathom Infiltrator|SHM|1
7 Island|GK1|1
1 Krydle of Baldur's Gate|AFR|1
2 Library Larcenist|M21|1
1 Soaring Thought-Thief|ZNR|1
4 Submerged Boneyard|M19|1
1 Sure-Footed Infiltrator|ZNR|1
6 Swamp|GK1|1
1 Zareth San, the Trickster|ZNR|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,33 @@
[metadata]
Name=Adventure - Low Golgari
[Avatar]
[Main]
1 Aspect of Lamprey|THB|1
2 Elvish Vanguard|EMA|1
1 Fell Specter|M19|1
7 Forest|GK1|1
4 Foul Orchard|M19|1
1 Ghost-Lit Stalker|DDD|1
2 Golgari Locket|GRN|1
2 Headless Specter|MH1|1
2 Hideous End|MB1|1
2 Ivy Lane Denizen|GTC|1
1 Liliana's Caress|M11|1
2 Mind Drain|ZNR|1
1 Nath of the Gilt-Leaf|C16|1
1 Nullmage Shepherd|KHC|1
1 Poison-Tip Archer|M19|1
1 Raiders' Wake|XLN|1
7 Swamp|GK1|2
2 Winnower Patrol|MOR|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,31 @@
[metadata]
Name=Adventure - Low Green
[Avatar]
[Main]
2 Ancient Animus|DOM|1
2 Aquastrand Spider|DIS|1
1 Armorcraft Judge|CMR|1
2 Baloth Packhunter|ANB|1
2 Big Play|STX|1
1 Biogenic Upgrade|MIC|1
1 Blessings of Nature|AVR|1
1 Bramblewood Paragon|MOR|1
1 Cytoplast Root-Kin|MM2|1
2 Deepwood Denizen|MH2|1
2 Earthen Arms|BFZ|1
2 Forced Adaptation|GTC|1
18 Forest|GK1|2
1 Leyline Invocation|STX|1
1 Paradox Zone|C21|1
1 Renata, Called to the Hunt|THB|2
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,34 @@
[metadata]
Name=Adventure - Low Gruul
[Avatar]
[Main]
2 Annoyed Altisaur|CMR|1
1 Charging Tuskodon|RIX|1
2 Commune with Dinosaurs|JMP|1
1 Dinosaur Stampede|XLN|1
7 Forest|GK2|1
2 Grazing Whiptail|XLN|1
2 Gruul Locket|RNA|1
2 Knight of the Stampede|RIX|1
1 Manamorphose|SHM|1
1 Momentum Rumbler|IKO|1
6 Mountain|GK2|2
1 Pyretic Ritual|M11|1
2 Pyroceratops|IKO|1
1 Raging Regisaur|RIX|1
1 Raging Swordtooth|XLN|1
2 Ram Through|IKO|1
1 Regisaur Alpha|XLN|1
1 Savage Stomp|JMP|1
4 Timber Gorge|DOM|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,33 @@
[metadata]
Name=Adventure - Low Izzet
[Avatar]
[Main]
2 Careful Study|ODY|1
2 Electrickery|RTR|1
2 Goblin Wizardry|M21|1
4 Highland Lake|M19|1
1 Incursion Specialist|GTC|1
6 Island|GK1|2
1 Izzet Charm|2XM|1
2 Izzet Locket|C19|1
1 Izzet Staticaster|RTR|1
1 Jori En, Ruin Diver|OGW|1
2 Lotus Path Djinn|FRF|1
2 Mage-Ring Bully|ORI|1
7 Mountain|GK1|1
1 Pyromancer's Assault|OGW|1
1 Quicksilver Dagger|A25|1
2 Thorned Moloch|HOU|1
2 Thunder Drake|WAR|1
1 Wizard Class|AFR|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,34 @@
[metadata]
Name=Adventure - Low Orzhov
[Avatar]
[Main]
2 Basilica Screecher|GTC|1
1 Blood Artist|JMP|1
1 Exile|VMA|1
1 Faith Unbroken|CMR|1
4 Forsaken Sanctuary|M19|1
2 Herald of Hadar|AFR|1
2 Hideous End|MB1|1
2 Marauding Blight-Priest|ZNR|1
1 Obzedat, Ghost Council|MM3|1
1 Okiba Reckoner Raid|NEO|1
2 Orzhov Locket|RNA|1
4 Plains|GK2|2
1 Restless Bloodseeker|VOW|2
1 Retreat to Hagra|BFZ|1
1 Sanguine Bond|IMA|1
2 Sovereign's Bite|M19|1
2 Suture Priest|NPH|1
9 Swamp|GK2|1
1 Vizkopa Guildmage|GTC|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,33 @@
[metadata]
Name=Adventure - Low Rakdos
[Avatar]
[Main]
4 Cinder Barrens|M19|1
1 Falkenrath Exterminator|AVR|1
1 Florian, Voldaren Scion|MID|1
2 Gift of Fangs|VOW|1
2 Hideous End|MB1|1
1 Hungry for More|MID|1
2 Mark of the Vampire|M13|1
2 Midnight Assassin|SNC|1
6 Mountain|GK2|1
2 Nocturnal Feeder|JMP|1
2 Rakdos Locket|RNA|1
1 Rakish Heir|VOC|1
1 Stromkirk Captain|DKA|1
7 Swamp|GK2|2
1 Vampire Nighthawk|C21|1
1 Vampire Socialite|MID|1
2 Vampire Spawn|AFR|1
2 Vampire's Kiss|VOW|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,27 @@
[metadata]
Name=Adventure - Low Red
[Avatar]
[Main]
10 Dragon's Approach|STX|1
1 Fire Servant|M11|1
1 Guttersnipe|MB1|1
2 Kiln Fiend|IMA|1
17 Mountain|GK2|2
2 Pyre Hound|A25|1
1 Pyromancer Ascension|SS3|1
1 Red Dragon|AFR|1
1 Syr Carah, the Bold|ELD|1
2 Thermo-Alchemist|EMN|1
1 Voltaic Visionary|VOW|1
1 Young Pyromancer|MB1|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,33 @@
[metadata]
Name=Adventure - Low Selesnya
[Avatar]
[Main]
1 Abzan Beastmaster|FRF|1
1 Archon of Valor's Reach|C20|1
2 Armadillo Cloak|ARC|1
1 Assault Formation|PLIST|1
1 Belligerent Brontodon|MB1|1
2 Cartouche of Strength|AKH|1
7 Forest|GK1|2
2 Looming Altisaur|XLN|1
7 Plains|GK1|2
1 Qasali Ambusher|ALA|1
2 Savage Punch|KTK|1
2 Selesnya Locket|GRN|1
1 Selesnya Sagittars|RAV|1
1 Shinen of Life's Roar|SOK|1
2 Stampeding Elk Herd|DTK|1
4 Tranquil Expanse|M19|1
2 Treefolk Umbra|MH1|1
1 Unflinching Courage|DGM|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,33 @@
[metadata]
Name=Adventure - Low Simic
[Avatar]
[Main]
1 Briarbridge Patrol|SOI|1
1 Byway Courier|SOI|1
2 Confront the Unknown|SOI|1
2 Drownyard Explorers|SOI|1
1 Erdwal Illuminator|SOI|1
2 Floodhound|MH2|1
7 Forest|GK2|2
2 Funnel-Web Recluse|MH2|1
1 Graf Mole|SOI|1
7 Island|GK2|2
1 Lonis, Cryptozoologist|PLIST|1
1 Magnifying Glass|C18|1
1 Ongoing Investigation|SOI|1
2 Secrets of the Key|MID|1
2 Simic Locket|RNA|1
1 Ulvenwald Mysteries|PLIST|1
2 Wavesifter|MH2|1
4 Woodland Stream|CMR|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,31 @@
[metadata]
Name=Adventure - Low White
[Avatar]
[Main]
1 Angel of Vitality|M20|1
2 Answered Prayers|MH1|1
1 Blessed Alliance|EMN|1
1 Cleric Class|AFR|1
2 Faith's Fetters|C15|1
1 Glorious Enforcer|MH2|1
1 Goldnight Redeemer|DDQ|1
2 Inspiring Overseer|SNC|1
2 Invoke the Divine|DOM|1
1 Ixalan's Binding|XLN|1
2 Martyr of Sands|UMA|1
18 Plains|GK2|2
1 Righteous Valkyrie|KHM|1
2 Seraph of Dawn|CMR|1
2 Suture Priest|NPH|1
1 You're Ambushed on the Road|AFR|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,6 @@
{
"name":"Black",
"jumpstartPacks":["black","black","black"]
}

View File

@@ -21,73 +21,74 @@
{ {
"type": "Label", "type": "Label",
"name" : "titleL", "name" : "titleL",
"text": "Create a Character", "text": "{lblCreateACharacter}",
"width": 128, "width": 128,
"height": 32, "height": 16,
"scale": 2,
"fontSize": 1.5, "fontSize": 1.5,
"fontColor": "0x000000FF", "fontColor": "0x000000FF",
"x": 104, "x": 76,
"y": 16 "y": 16
}, } ,
{
"type": "Label",
"name" : "avatarL",
"text": "Avatar:",
"width": 128,
"height": 32,
"font" : "black",
"x": 75,
"y": 58
},
{ {
"type": "Label", "type": "Label",
"name" : "nameL", "name" : "nameL",
"text": "Name:", "text": "{lblName}:",
"width": 128, "width": 128,
"height": 32, "height": 16,
"font" : "black", "font" : "black",
"x": 75, "x": 75,
"y": 90 "y": 96
}, },
{ {
"type": "Label", "type": "Label",
"name" : "raceL", "name" : "raceL",
"text": "Race:", "text": "{lblRace}:",
"width": 128, "width": 128,
"height": 32, "height": 16,
"font" : "black", "font" : "black",
"x": 75, "x": 75,
"y": 124 "yOffset": 8
}, },
{ {
"type": "Label", "type": "Label",
"name" : "genderL", "name" : "genderL",
"text": "Gender:", "text": "{lblGender}:",
"width": 128, "width": 128,
"height": 32, "height": 16,
"font" : "black", "font" : "black",
"x": 75, "x": 75,
"y": 154 "yOffset": 8
}, },
{ {
"type": "Label", "type": "Label",
"name" : "difficultyL", "name" : "difficultyL",
"text": "Difficulty:", "text": "{lblDifficulty}:",
"width": 128, "width": 128,
"height": 32, "height": 16,
"font" : "black", "font" : "black",
"x": 75, "x": 75,
"y": 186 "yOffset": 8
}, },
{ {
"type": "Label", "type": "Label",
"name" : "deckL", "name" : "colorIdL",
"text": "Deck:", "text": "{lblColors}:",
"width": 128, "width": 128,
"height": 32, "height": 16,
"font" : "black", "font" : "black",
"x": 75, "x": 75,
"y": 218 "yOffset": 8
},
{
"type": "Label",
"name" : "modeL",
"text": "{lblMode}",
"width": 128,
"height": 16,
"font" : "black",
"x": 75,
"yOffset": 8
}, },
{ {
"type": "ImageButton", "type": "ImageButton",
@@ -130,7 +131,7 @@
"width": 112, "width": 112,
"height": 16, "height": 16,
"x": 164, "x": 164,
"y": 128 "yOffset": 8
}, },
{ {
"type": "Selector", "type": "Selector",
@@ -138,7 +139,7 @@
"width": 112, "width": 112,
"height": 16, "height": 16,
"x": 164, "x": 164,
"y": 160 "yOffset": 8
}, },
{ {
"type": "Selector", "type": "Selector",
@@ -146,20 +147,28 @@
"width": 112, "width": 112,
"height": 16, "height": 16,
"x": 164, "x": 164,
"y": 192 "yOffset": 8
}, },
{ {
"type": "Selector", "type": "Selector",
"name": "deck", "name": "colorId",
"width": 112, "width": 112,
"height": 16, "height": 16,
"x": 164, "x": 164,
"y": 224 "yOffset": 8
},
{
"type": "Selector",
"name": "mode",
"width": 112,
"height": 16,
"x": 164,
"yOffset": 8
}, },
{ {
"type": "TextButton", "type": "TextButton",
"name": "back", "name": "back",
"text": "Back", "text": "{lblBack}",
"width": 100, "width": 100,
"height": 30, "height": 30,
"x": 348, "x": 348,
@@ -168,7 +177,7 @@
{ {
"type": "TextButton", "type": "TextButton",
"name": "start", "name": "start",
"text": "Start", "text": "{lblStart}",
"width": 100, "width": 100,
"height": 30, "height": 30,
"x": 348, "x": 348,

View File

@@ -13,38 +13,29 @@
"type": "Scroll", "type": "Scroll",
"name" : "scroll", "name" : "scroll",
"style": "paper", "style": "paper",
"x": 10, "x": 5,
"y": 60, "y": 60,
"width": 256, "width": 256,
"height": 318 "height": 323
}, },
{ {
"type": "Label", "type": "Label",
"name" : "titleL", "name" : "titleL",
"text": "Create a Character", "text": "{lblCreateACharacter}",
"width": 128, "width": 128,
"height": 32, "height": 32,
"scale": 2,
"fontSize": 1.5, "fontSize": 1.5,
"fontColor": "0x000000FF", "fontColor": "0x000000FF",
"x": 16, "x": 30,
"y": 66 "y": 66
}, } ,
{
"type": "Label",
"name" : "avatarL",
"text": "Avatar:",
"width": 128,
"height": 32,
"fontColor": "0x000000FF",
"x": 16,
"y": 108
},
{ {
"type": "Label", "type": "Label",
"name" : "nameL", "name" : "nameL",
"text": "Name:", "text": "{lblName}:",
"width": 128, "width": 128,
"height": 32, "height": 24,
"fontColor": "0x000000FF", "fontColor": "0x000000FF",
"x": 16, "x": 16,
"y": 140 "y": 140
@@ -52,42 +43,52 @@
{ {
"type": "Label", "type": "Label",
"name" : "raceL", "name" : "raceL",
"text": "Race:", "text": "{lblRace}:",
"width": 128, "width": 128,
"height": 32, "height": 24,
"fontColor": "0x000000FF", "fontColor": "0x000000FF",
"x": 16, "x": 16,
"y": 174 "yOffset": 8
}, },
{ {
"type": "Label", "type": "Label",
"name" : "genderL", "name" : "genderL",
"text": "Gender:", "text": "{lblGender}:",
"width": 128, "width": 128,
"height": 32, "height": 24,
"fontColor": "0x000000FF", "fontColor": "0x000000FF",
"x": 16, "x": 16,
"y": 204 "yOffset": 8
}, },
{ {
"type": "Label", "type": "Label",
"name" : "difficultyL", "name" : "difficultyL",
"text": "Difficulty:", "text": "{lblDifficulty}:",
"width": 128, "width": 128,
"height": 32, "height": 24,
"fontColor": "0x000000FF", "fontColor": "0x000000FF",
"x": 16, "x": 16,
"y": 236 "yOffset": 8
}, },
{ {
"type": "Label", "type": "Label",
"name" : "deckL", "name" : "colorIdL",
"text": "Deck:", "text": "{lblColors}:",
"width": 128, "width": 128,
"height": 32, "height": 24,
"font" : "black", "font" : "black",
"x": 16, "x": 16,
"y": 268 "yOffset": 8
},
{
"type": "Label",
"name" : "modeL",
"text": "{lblMode}",
"width": 128,
"height": 24,
"font" : "black",
"x": 16,
"yOffset": 8
}, },
{ {
"type": "ImageButton", "type": "ImageButton",
@@ -118,60 +119,68 @@
{ {
"type": "TextField", "type": "TextField",
"name": "nameField", "name": "nameField",
"width": 165, "width": 160,
"height": 28, "height": 24,
"x": 96, "x": 96,
"y": 146 "y": 146
}, },
{ {
"type": "Selector", "type": "Selector",
"name": "race", "name": "race",
"width": 170, "width": 168,
"height": 28, "height": 24,
"x": 96, "x": 96,
"y": 178 "yOffset": 8
}, },
{ {
"type": "Selector", "type": "Selector",
"name": "gender", "name": "gender",
"width": 170, "width": 168,
"height": 28, "height": 24,
"x": 96, "x": 96,
"y": 210 "yOffset": 8
}, },
{ {
"type": "Selector", "type": "Selector",
"name": "difficulty", "name": "difficulty",
"width": 170, "width": 168,
"height": 28, "height": 24,
"x": 96, "x": 96,
"y": 242 "yOffset": 8
}, },
{ {
"type": "Selector", "type": "Selector",
"name": "deck", "name": "colorId",
"width": 170, "width": 168,
"height": 28, "height": 24,
"x": 96, "x": 96,
"y": 274 "yOffset": 8
},
{
"type": "Selector",
"name": "mode",
"width": 168,
"height": 24,
"x": 96,
"yOffset": 8
}, },
{ {
"type": "TextButton", "type": "TextButton",
"name": "back", "name": "back",
"text": "Back", "text": "{lblBack}",
"width": 64, "width": 64,
"height": 28, "height": 28,
"x": 32, "x": 32,
"y": 320 "y": 344
}, },
{ {
"type": "TextButton", "type": "TextButton",
"name": "start", "name": "start",
"text": "Start", "text": "{lblStart}",
"width": 64, "width": 64,
"height": 32, "height": 28,
"x": 165, "x": 165,
"y": 320 "y": 344
} }
] ]
} }

View File

@@ -122,7 +122,6 @@
"maskPath": "world/tilesets/ring.png", "maskPath": "world/tilesets/ring.png",
"height": 0.5, "height": 0.5,
"width": 0.5, "width": 0.5,
"symmetry": 8,
"periodicOutput": false, "periodicOutput": false,
"mappingInfo": [ "mappingInfo": [
{ {