json stores are gone, they nulled out every data ref on load and wrote the null straight back on save. shop json and the purchase commands ended up in here too.
147 lines
4.5 KiB
Rust
147 lines
4.5 KiB
Rust
use std::path::PathBuf;
|
|
use serde::{Deserialize, Serialize};
|
|
use storage::DatabaseConfig;
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
#[serde(untagged)]
|
|
pub enum DataSelector {
|
|
Named(String),
|
|
Instance(i32),
|
|
}
|
|
impl DataSelector {
|
|
pub fn named(name: impl Into<String>) -> Self {
|
|
DataSelector::Named(name.into())
|
|
}
|
|
}
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
#[serde(untagged)]
|
|
pub enum CardRef {
|
|
Named(String),
|
|
Explicit { table: i32, instance: i32 },
|
|
}
|
|
impl CardRef {
|
|
pub const fn explicit(table: i32, instance: i32) -> Self {
|
|
CardRef::Explicit { table, instance }
|
|
}
|
|
pub fn named(name: impl Into<String>) -> Self {
|
|
CardRef::Named(name.into())
|
|
}
|
|
}
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct StarterProfile {
|
|
pub name_prefix: String,
|
|
pub exp_level: i32,
|
|
pub exp_points: i32,
|
|
pub gold: i32,
|
|
pub diamonds: i32,
|
|
pub free_diamonds: i32,
|
|
pub trophies: i32,
|
|
pub npc_win_count: i32,
|
|
pub npc_lose_count: i32,
|
|
pub arena: DataSelector,
|
|
pub gold_resource: DataSelector,
|
|
pub chest_slot_count: usize,
|
|
pub deck: Vec<CardRef>,
|
|
pub extra_collection: Vec<CardRef>,
|
|
pub card_level_index: i32,
|
|
pub card_count: i32,
|
|
pub finish_tutorials: bool,
|
|
}
|
|
impl Default for StarterProfile {
|
|
fn default() -> Self {
|
|
Self {
|
|
name_prefix: "Scroll".to_owned(),
|
|
exp_level: 1,
|
|
exp_points: 0,
|
|
gold: 5_000,
|
|
diamonds: 1_000,
|
|
free_diamonds: 0,
|
|
trophies: 0,
|
|
npc_win_count: 1,
|
|
npc_lose_count: 0,
|
|
arena: DataSelector::Named("Arena1".to_owned()),
|
|
gold_resource: DataSelector::Named("Gold".to_owned()),
|
|
chest_slot_count: 4,
|
|
deck: (0..8)
|
|
.map(|instance| CardRef::explicit(logic::table::SPELLS_CHARACTERS, instance))
|
|
.collect(),
|
|
extra_collection: (8..16)
|
|
.map(|instance| CardRef::explicit(logic::table::SPELLS_CHARACTERS, instance))
|
|
.collect(),
|
|
card_level_index: 0,
|
|
card_count: 10,
|
|
finish_tutorials: true,
|
|
}
|
|
}
|
|
}
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct ChestRewardConfig {
|
|
pub gold_min: i32,
|
|
pub gold_max: i32,
|
|
pub diamonds: i32,
|
|
pub different_cards: usize,
|
|
pub copies_per_card: i32,
|
|
}
|
|
impl Default for ChestRewardConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
gold_min: 15,
|
|
gold_max: 45,
|
|
diamonds: 0,
|
|
different_cards: 2,
|
|
copies_per_card: 3,
|
|
}
|
|
}
|
|
}
|
|
#[derive(Debug, Clone)]
|
|
pub struct GameConfig {
|
|
pub database: Option<DatabaseConfig>,
|
|
pub listen: String,
|
|
pub csv_root: Option<PathBuf>,
|
|
pub shop_path: Option<PathBuf>,
|
|
pub starter: StarterProfile,
|
|
pub chest_reward: ChestRewardConfig,
|
|
pub random_seed: i32,
|
|
}
|
|
impl Default for GameConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
database: None,
|
|
listen: "127.0.0.1:9402".to_owned(),
|
|
csv_root: Some(PathBuf::from("assets")),
|
|
shop_path: Some(PathBuf::from("config/shop.json")),
|
|
starter: StarterProfile::default(),
|
|
chest_reward: ChestRewardConfig::default(),
|
|
random_seed: 0x5EED,
|
|
}
|
|
}
|
|
}
|
|
impl GameConfig {
|
|
pub fn from_env() -> Self {
|
|
let defaults = Self::default();
|
|
let starter = match env_string("SCROLL_STARTER_PROFILE") {
|
|
Some(path) => std::fs::read(&path)
|
|
.ok()
|
|
.and_then(|bytes| serde_json::from_slice(&bytes).ok())
|
|
.unwrap_or(defaults.starter),
|
|
None => defaults.starter,
|
|
};
|
|
Self {
|
|
database: DatabaseConfig::from_env(),
|
|
listen: env_string("SCROLL_GAME_LISTEN").unwrap_or(defaults.listen),
|
|
csv_root: env_string("SCROLL_CSV_ROOT")
|
|
.map(PathBuf::from)
|
|
.or(defaults.csv_root),
|
|
shop_path: env_string("SCROLL_SHOP")
|
|
.map(PathBuf::from)
|
|
.or(defaults.shop_path),
|
|
starter,
|
|
chest_reward: defaults.chest_reward,
|
|
random_seed: env_string("SCROLL_RANDOM_SEED")
|
|
.and_then(|value| value.parse().ok())
|
|
.unwrap_or(defaults.random_seed),
|
|
}
|
|
}
|
|
}
|
|
fn env_string(key: &str) -> Option<String> {
|
|
std::env::var(key).ok().filter(|value| !value.is_empty())
|
|
}
|