1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00

Load more config data from files (instead of hardcoded)

This commit is contained in:
NGnius (Graham)
2025-03-30 17:54:06 -04:00
parent 0e048a17b1
commit a540cf6d8f
17 changed files with 244 additions and 42 deletions

View File

@@ -0,0 +1,32 @@
use polariton::operation::Typed;
pub struct GameplaySettings {
pub show_tutorial_after_date: String,
pub health_threshold: f32, // percent
pub microbot_sphere: f32, // radius
pub misfire_angle: f32, // degrees?
pub shield_dps: i32,
pub shield_hps: u32,
pub request_review_level: u32,
pub critical_ratio: f32,
pub cross_promo_image: String, // url
pub cross_promo_link: String, // url
}
impl GameplaySettings {
pub fn as_transmissible<C>(&self) -> Typed<C> {
Typed::HashMap(vec![
// TODO
(Typed::Str("showTutorialAfterDate".into()), Typed::Str(self.show_tutorial_after_date.clone().into())),
(Typed::Str("healthTresholdPercent".into()), Typed::Float(self.health_threshold)),
(Typed::Str("microbotSphereRadius".into()), Typed::Float(self.microbot_sphere)),
(Typed::Str("smartRotationMisfireAngle".into()), Typed::Float(self.misfire_angle)),
(Typed::Str("fusionShieldDPS".into()), Typed::Int(self.shield_dps)),
(Typed::Str("fusionShieldHPS".into()), Typed::Int(self.shield_hps as i32)),
(Typed::Str("requestReviewAtLevel".into()), Typed::Int(self.request_review_level as i32)),
(Typed::Str("criticalRatio".into()), Typed::Float(self.critical_ratio)),
(Typed::Str("crossPromotionAdImageUrl".into()), Typed::Str(self.cross_promo_image.clone().into())),
(Typed::Str("crossPromotionAdLinkUrl".into()), Typed::Str(self.cross_promo_link.clone().into())),
].into())
}
}

View File

@@ -1,5 +1,6 @@
pub mod auto_regen;
pub mod campaign;
pub mod client_config;
pub mod cube_list;
pub mod game_mode;
pub mod garage_bay;

View File

@@ -0,0 +1,32 @@
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct GameplaySettings {
pub show_tutorial_after_date: String,
pub health_threshold: f32, // percent
pub microbot_sphere: f32, // radius
pub misfire_angle: f32, // degrees?
pub shield_dps: i32,
pub shield_hps: u32,
pub request_review_level: u32,
pub critical_ratio: f32,
pub cross_promo_image: String, // url
pub cross_promo_link: String, // url
}
impl std::convert::Into<crate::data::client_config::GameplaySettings> for GameplaySettings {
fn into(self) -> crate::data::client_config::GameplaySettings {
crate::data::client_config::GameplaySettings {
show_tutorial_after_date: self.show_tutorial_after_date,
health_threshold: self.health_threshold,
microbot_sphere: self.microbot_sphere,
misfire_angle: self.misfire_angle,
shield_dps: self.shield_dps,
shield_hps: self.shield_hps,
request_review_level: self.request_review_level,
critical_ratio: self.critical_ratio,
cross_promo_image: self.cross_promo_image,
cross_promo_link: self.cross_promo_link,
}
}
}

View File

@@ -5,7 +5,7 @@ use serde::{Serialize, Deserialize};
use polariton::operation::{Typed, Dict};
use polariton::serdes::TypePrefix;
use super::super::{MovementCategoryData, MovementData, Cube, ItemCategory, ItemTier, BattleConfig};
use super::super::{MovementCategoryData, MovementData, Cube, ItemCategory, ItemTier, BattleConfig, Settings};
const CUBE_CONFIG_FILENAME: &str = "config.json";
@@ -15,6 +15,7 @@ pub struct CubeConfig {
movement: HashMap<ItemCategory, MovementCategoryData>,
lerp_value: f32,
battle: BattleConfig,
settings: Settings,
}
impl CubeConfig {
@@ -231,4 +232,19 @@ impl <C: Clone> super::ConfigProvider<C> for CubeConfig {
}
super::CompleteCampaignProvider::new(map)
}
fn client_config(&self) -> Typed<C> {
let conf_data: crate::data::client_config::GameplaySettings = self.settings.gameplay.clone().into();
Typed::Dict(Dict {
key_ty: TypePrefix::Str,
val_ty: TypePrefix::HashMap,
items: vec![
(Typed::Str("GameplaySettings".into()), conf_data.as_transmissible()),
].into(),
})
}
fn login_messages(&self) -> super::DevMessageProvider<C> {
super::DevMessageProvider::new(self.settings.banners.iter().map(|msg| (msg.message.clone(), msg.duration as i32)).collect())
}
}

View File

@@ -2,7 +2,7 @@ mod cubes_json;
pub use cubes_json::CubeConfig;
mod traits;
pub use traits::{ConfigProvider, CompleteCampaignProvider};
pub use traits::{ConfigProvider, CompleteCampaignProvider, DevMessageProvider};
pub type ConfigImpl = CubeConfig;

View File

@@ -1,6 +1,6 @@
use polariton::operation::Typed;
pub trait ConfigProvider<C> {
pub trait ConfigProvider<C: Clone> {
fn cube_list(&self) -> Typed<C>;
fn movement_list(&self) -> Typed<C>;
fn weapon_list(&self) -> Typed<C>;
@@ -15,6 +15,8 @@ pub trait ConfigProvider<C> {
fn campaign_waves(&self) -> Typed<C>;
fn campaign_version(&self) -> Typed<C>;
fn campaign_details(&self) -> CompleteCampaignProvider;
fn client_config(&self) -> Typed<C>;
fn login_messages(&self) -> DevMessageProvider<C>;
}
pub struct CompleteCampaignProvider {
@@ -40,3 +42,43 @@ impl CompleteCampaignProvider {
}
}
}
pub struct DevMessageProvider<C: Clone> {
messages: Vec<TypedDevMessage<C>>,
}
impl <C: Clone> DevMessageProvider<C> {
pub fn new(messages: Vec<(String, i32)>) -> Self {
Self {
messages: messages.into_iter().map(|(msg, time)| {
let bytes: Vec<u8> = msg.as_bytes().into();
TypedDevMessage {
message: Typed::Bytes(bytes.into()),
display_time: Typed::Int(time),
}
}
).collect(),
}
}
pub fn get(&self, index: usize) -> TypedDevMessage<C> {
// TODO maybe make this less obtuse -- it works for random, but isn't really obvious for anything else
if self.messages.is_empty() {
TypedDevMessage {
message: Typed::Bytes(Vec::default().into()),
display_time: Typed::Int(-1),
}
} else if self.messages.len() == 1 {
self.messages[0].clone()
} else {
let actual_index = index % self.messages.len(); // guarantees index is within allowed range of messages
self.messages[actual_index].clone()
}
}
}
#[derive(Clone, Debug)]
pub struct TypedDevMessage<C> {
pub message: Typed<C>,
pub display_time: Typed<C>,
}

View File

@@ -23,7 +23,11 @@ pub use combat::BattleConfig;
mod singleplayer;
pub use singleplayer::{Campaigns, Campaign, CampaignDifficulty, CampaignCompletion, CampaignType, Wave, WaveRobot};
// TODO put this in core lib
mod client_config;
pub use client_config::GameplaySettings;
mod settings;
pub use settings::Settings;
pub(self) const VALID_ROBOT: &[u8] = &[64,
0,

View File

@@ -0,0 +1,34 @@
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Settings {
#[serde(default = "default_gameplay_settings")]
pub gameplay: super::GameplaySettings,
#[serde(default = "default_dev_messages")]
pub banners: Vec<BannerMessage>,
}
fn default_gameplay_settings() -> super::GameplaySettings {
super::GameplaySettings {
show_tutorial_after_date: "2030-01-01".to_owned(),
health_threshold: 0.20,
microbot_sphere: 10.0,
misfire_angle: 10.0,
shield_dps: 100,
shield_hps: 2_000,
request_review_level: 10_000,
critical_ratio: 5.0,
cross_promo_image: "https://git.ngram.ca/assets/img/logo.png".to_owned(),
cross_promo_link: "https://git.ngram.ca/OpenJam/servers".to_owned(),
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct BannerMessage {
pub message: String,
pub duration: u32, // seconds
}
fn default_dev_messages() -> Vec<BannerMessage> {
Vec::default()
}