diff --git a/assets/config.json b/assets/config.json deleted file mode 100644 index ccd5c80c..00000000 --- a/assets/config.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "sand_col": { - "r": 0.5411765, - "g": 0.49019608, - "b": 0.3019608, - "a": 1.0 - }, - "sea_col": { - "r": 0.20896202, - "g": 0.39679408, - "b": 0.47983873, - "a": 1.0 - }, - "roof_col": { - "r": 0.2627451, - "g": 0.21314174, - "b": 0.12673587, - "a": 1.0 - }, - "house_col": { - "r": 1.0, - "g": 1.0, - "b": 1.0, - "a": 1.0 - }, - "gui_success": { - "r": 0.3, - "g": 0.8, - "b": 0.3, - "a": 1.0 - }, - "gui_danger": { - "r": 0.85, - "g": 0.3, - "b": 0.3, - "a": 1.0 - }, - "gui_primary": { - "r": 0.29411766, - "g": 0.39607844, - "b": 1.0, - "a": 1.0 - }, - "gui_disabled": { - "r": 0.79607844, - "g": 0.79607844, - "b": 0.79607844, - "a": 0.2 - }, - "road_low_col": { - "r": 0.21568628, - "g": 0.21568628, - "b": 0.21568628, - "a": 1.0 - }, - "road_mid_col": { - "r": 0.3019608, - "g": 0.3019608, - "b": 0.3019608, - "a": 1.0 - }, - "road_hig_col": { - "r": 0.42, - "g": 0.42, - "b": 0.42, - "a": 1.0 - }, - "road_line_col": { - "r": 0.50980395, - "g": 0.50980395, - "b": 0.50980395, - "a": 1.0 - }, - "road_pylon_col": { - "r": 0.48789835, - "g": 0.4879001, - "b": 0.48790324, - "a": 1.0 - }, - "lot_unassigned_col": { - "r": 0.20392157, - "g": 0.4509804, - "b": 0.17254902, - "a": 1.0 - }, - "lot_residential_col": { - "r": 0.2, - "g": 0.6, - "b": 0.25, - "a": 1.0 - } -} \ No newline at end of file diff --git a/base_mod/colors.lua b/base_mod/colors.lua new file mode 100644 index 00000000..3cc16a8c --- /dev/null +++ b/base_mod/colors.lua @@ -0,0 +1,83 @@ + +data:extend { + type = "colors", + name = "colors", + label = "Colors", + + sand_col = { + r = 0.5411765, + g = 0.49019608, + b = 0.3019608, + }, + sea_col = { + r = 0.20896202, + g = 0.39679408, + b = 0.47983873, + }, + roof_col = { + r = 0.2627451, + g = 0.21314174, + b = 0.12673587, + }, + house_col = { + r = 1.0, + g = 1.0, + b = 1.0, + }, + gui_success = { + r = 0.3, + g = 0.8, + b = 0.3, + }, + gui_danger = { + r = 0.85, + g = 0.3, + b = 0.3, + }, + gui_primary = { + r = 0.29411766, + g = 0.39607844, + b = 1.0, + }, + gui_disabled = { + r = 0.79607844, + g = 0.79607844, + b = 0.79607844, + a = 0.2 + }, + road_low_col = { + r = 0.21568628, + g = 0.21568628, + b = 0.21568628, + }, + road_mid_col = { + r = 0.3019608, + g = 0.3019608, + b = 0.3019608, + }, + road_hig_col = { + r = 0.42, + g = 0.42, + b = 0.42, + }, + road_line_col = { + r = 0.50980395, + g = 0.50980395, + b = 0.50980395, + }, + road_pylon_col = { + r = 0.48789835, + g = 0.4879001, + b = 0.48790324, + }, + lot_unassigned_col = { + r = 0.20392157, + g = 0.4509804, + b = 0.17254902, + }, + lot_residential_col = { + r = 0.2, + g = 0.6, + b = 0.25, + } +} \ No newline at end of file diff --git a/base_mod/data.lua b/base_mod/data.lua index cd71bae9..a35983cb 100644 --- a/base_mod/data.lua +++ b/base_mod/data.lua @@ -1,6 +1,7 @@ require("items") require("companies") require("leisure") +require("colors") data:extend { { diff --git a/native_app/src/game_loop.rs b/native_app/src/game_loop.rs index a3e1c757..d591dce7 100644 --- a/native_app/src/game_loop.rs +++ b/native_app/src/game_loop.rs @@ -299,10 +299,9 @@ impl State { .then(|| self.uiw.read::().radius) .unwrap_or_default(); drop(camera); - let c = simulation::config(); + let c = simulation::colors(); params.sand_col = c.sand_col.into(); params.sea_col = c.sea_col.into(); - drop(c); } fn manage_io(&mut self, ctx: &mut Context) { diff --git a/native_app/src/gui/windows/config.rs b/native_app/src/gui/windows/config.rs deleted file mode 100644 index f1f97921..00000000 --- a/native_app/src/gui/windows/config.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::uiworld::UiWorld; -use egui_inspect::{Inspect, InspectArgs}; -use simulation::Config; -use simulation::Simulation; - -/// Config window -/// Allows to change the real-time dev-only config -pub fn config(window: egui::Window<'_>, ui: &egui::Context, _: &mut UiWorld, _: &Simulation) { - window - .default_size([600.0, 500.0]) - .vscroll(true) - .show(ui, |ui| { - let mut config = (**simulation::config()).clone(); - - let args = InspectArgs { - header: Some(false), - indent_children: Some(false), - ..InspectArgs::default() - }; - if >::render_mut(&mut config, "", ui, &args) { - simulation::update_config(config); - } - }); -} diff --git a/native_app/src/gui/windows/mod.rs b/native_app/src/gui/windows/mod.rs index 04ffa260..a20b7fcb 100644 --- a/native_app/src/gui/windows/mod.rs +++ b/native_app/src/gui/windows/mod.rs @@ -6,7 +6,6 @@ use crate::inputmap::{InputAction, InputMap}; use crate::uiworld::UiWorld; use simulation::Simulation; -mod config; pub mod debug; mod economy; pub mod load; @@ -59,7 +58,6 @@ impl Default for GUIWindows { opened: vec![], }; s.insert("Economy", economy::economy, false); - s.insert("Config", config::config, false); s.insert("Debug", debug::debug, false); s.insert("Settings", settings::settings, false); #[cfg(feature = "multiplayer")] diff --git a/native_app/src/newgui/tools/addtrain.rs b/native_app/src/newgui/tools/addtrain.rs index 933eab91..d6728f36 100644 --- a/native_app/src/newgui/tools/addtrain.rs +++ b/native_app/src/newgui/tools/addtrain.rs @@ -33,7 +33,7 @@ pub fn addtrain(sim: &Simulation, uiworld: &mut UiWorld) { Some(x) => x, None => { draw.circle(mpos, 10.0) - .color(simulation::config().gui_danger); + .color(simulation::colors().gui_danger); return; } }; @@ -52,11 +52,11 @@ pub fn addtrain(sim: &Simulation, uiworld: &mut UiWorld) { }; if dist <= trainlength { - drawtrain(simulation::config().gui_danger); + drawtrain(simulation::colors().gui_danger); return; } - drawtrain(simulation::config().gui_primary); + drawtrain(simulation::colors().gui_primary); let cmd = WorldCommand::AddTrain { dist, diff --git a/native_app/src/newgui/tools/bulldozer.rs b/native_app/src/newgui/tools/bulldozer.rs index daa093c8..1368577b 100644 --- a/native_app/src/newgui/tools/bulldozer.rs +++ b/native_app/src/newgui/tools/bulldozer.rs @@ -34,9 +34,9 @@ pub fn bulldozer(sim: &Simulation, uiworld: &mut UiWorld) { cur_proj.kind, ProjectKind::Inter(_) | ProjectKind::Road(_) | ProjectKind::Building(_) ) { - simulation::config().gui_danger + simulation::colors().gui_danger } else { - simulation::config().gui_disabled + simulation::colors().gui_disabled }; draw.circle(cur_proj.pos.up(0.5), 2.0).color(col); diff --git a/native_app/src/newgui/tools/inspected_aura.rs b/native_app/src/newgui/tools/inspected_aura.rs index 2dde6ee1..72ca13df 100644 --- a/native_app/src/newgui/tools/inspected_aura.rs +++ b/native_app/src/newgui/tools/inspected_aura.rs @@ -45,6 +45,6 @@ pub fn inspected_aura(sim: &Simulation, uiworld: &mut UiWorld) { } draw.obb(b.obb, b.height + 0.01) - .color(simulation::config().gui_primary); + .color(simulation::colors().gui_primary); } } diff --git a/native_app/src/newgui/tools/lotbrush.rs b/native_app/src/newgui/tools/lotbrush.rs index c076e49e..b456add6 100644 --- a/native_app/src/newgui/tools/lotbrush.rs +++ b/native_app/src/newgui/tools/lotbrush.rs @@ -38,8 +38,8 @@ pub fn lotbrush(sim: &Simulation, uiworld: &mut UiWorld) { let kind = res.kind; let mut col = match kind { - LotKind::Unassigned => simulation::config().lot_unassigned_col, - LotKind::Residential => simulation::config().lot_residential_col, + LotKind::Unassigned => simulation::colors().lot_unassigned_col, + LotKind::Residential => simulation::colors().lot_residential_col, }; col.a = 0.2; diff --git a/native_app/src/newgui/tools/roadbuild.rs b/native_app/src/newgui/tools/roadbuild.rs index 72f72234..873eea67 100644 --- a/native_app/src/newgui/tools/roadbuild.rs +++ b/native_app/src/newgui/tools/roadbuild.rs @@ -61,7 +61,7 @@ pub fn roadbuild(sim: &Simulation, uiworld: &mut UiWorld) { if state.snap_to_grid && log_camheight < cutoff { let alpha = 1.0 - log_camheight / cutoff; - let col = simulation::config().gui_primary.a(alpha); + let col = simulation::colors().gui_primary.a(alpha); let screen = AABB::new(unproj.xy(), unproj.xy()).expand(300.0); let startx = (screen.ll.x / grid_size).ceil() * grid_size; let starty = (screen.ll.y / grid_size).ceil() * grid_size; @@ -394,9 +394,9 @@ impl RoadBuildResource { let mut proj_pos = proj.pos; proj_pos.z += 0.4; let col = if is_valid { - simulation::config().gui_primary + simulation::colors().gui_primary } else { - simulation::config().gui_danger + simulation::colors().gui_danger }; let p = match self.build_state { diff --git a/native_app/src/newgui/tools/roadeditor.rs b/native_app/src/newgui/tools/roadeditor.rs index 6cbcfd78..fc41e6cc 100644 --- a/native_app/src/newgui/tools/roadeditor.rs +++ b/native_app/src/newgui/tools/roadeditor.rs @@ -68,14 +68,14 @@ pub fn roadeditor(sim: &Simulation, uiworld: &mut UiWorld) { if Some(id) != state.inspect.as_ref().map(|x| x.id) { proj_pos = cur_proj.pos; } - proj_col = simulation::config().gui_primary; + proj_col = simulation::colors().gui_primary; } else { - proj_col = simulation::config().gui_disabled; + proj_col = simulation::colors().gui_disabled; } if inp.act.contains(&InputAction::Select) { if let ProjectKind::Inter(id) = cur_proj.kind { - proj_col = simulation::config().gui_success; + proj_col = simulation::colors().gui_success; proj_pos = cur_proj.pos; let inter = &map.intersections()[id]; state.inspect = Some(IntersectionComponent { diff --git a/native_app/src/newgui/tools/specialbuilding.rs b/native_app/src/newgui/tools/specialbuilding.rs index 11e6eb33..9f700a22 100644 --- a/native_app/src/newgui/tools/specialbuilding.rs +++ b/native_app/src/newgui/tools/specialbuilding.rs @@ -86,9 +86,9 @@ pub fn specialbuilding(sim: &Simulation, uiworld: &mut UiWorld) { let mut draw = |obb, red| { let p = asset.to_string(); let col = if red { - simulation::config().gui_danger.adjust_luminosity(1.3) + simulation::colors().gui_danger.adjust_luminosity(1.3) } else { - simulation::config() + simulation::colors() .gui_primary .adjust_luminosity(tweak!(1.5)) }; diff --git a/native_app/src/newgui/tools/terraforming.rs b/native_app/src/newgui/tools/terraforming.rs index 9fd152ce..095c1fcc 100644 --- a/native_app/src/newgui/tools/terraforming.rs +++ b/native_app/src/newgui/tools/terraforming.rs @@ -119,7 +119,7 @@ pub fn terraforming(sim: &Simulation, uiworld: &mut UiWorld) { ), res.level.unwrap_or(mpos.z) - 0.5, ) - .color(simulation::config().gui_primary.a(0.2)); + .color(simulation::colors().gui_primary.a(0.2)); } } TerraformKind::Slope => { @@ -130,7 +130,7 @@ pub fn terraforming(sim: &Simulation, uiworld: &mut UiWorld) { } else { draw.line(res.slope_start.unwrap(), res.slope_end.unwrap(), res.radius) } - .color(simulation::config().gui_primary.a(0.2)); + .color(simulation::colors().gui_primary.a(0.2)); } TerraformKind::Erode => {} } diff --git a/native_app/src/newgui/tools/zoneedit.rs b/native_app/src/newgui/tools/zoneedit.rs index dc97315d..551fd3ab 100644 --- a/native_app/src/newgui/tools/zoneedit.rs +++ b/native_app/src/newgui/tools/zoneedit.rs @@ -89,9 +89,9 @@ pub fn zoneedit(sim: &Simulation, uiworld: &mut UiWorld) { let base_col = if !isvalid { uiworld.write::().msg = Some(Cow::Owned(invalidmsg)); uiworld.write::().isworld = true; - simulation::config().gui_danger + simulation::colors().gui_danger } else { - simulation::config().gui_primary + simulation::colors().gui_primary }; for (p1, p2) in newpoly.iter().zip(newpoly.iter().cycle().skip(1)) { @@ -129,7 +129,7 @@ pub fn zoneedit(sim: &Simulation, uiworld: &mut UiWorld) { for (i, &p) in newpoly.iter().enumerate() { if Some((i, p, false)) == closest { draw.circle(p.z(1.1), 6.0) - .color(simulation::config().gui_success); + .color(simulation::colors().gui_success); continue; } @@ -139,7 +139,7 @@ pub fn zoneedit(sim: &Simulation, uiworld: &mut UiWorld) { for (i, p) in newpoly.segments().map(|s| s.center()).enumerate() { if Some((i, p, true)) == closest { draw.circle(p.z(1.1), 3.0) - .color(simulation::config().gui_success); + .color(simulation::colors().gui_success); continue; } diff --git a/native_app/src/rendering/map_rendering/map_mesh.rs b/native_app/src/rendering/map_rendering/map_mesh.rs index c5ca184a..bde8e1bf 100644 --- a/native_app/src/rendering/map_rendering/map_mesh.rs +++ b/native_app/src/rendering/map_rendering/map_mesh.rs @@ -397,7 +397,6 @@ impl MapBuilders { if SubscriberChunkID::new(building.canonical_position()) != chunk { continue; } - dbg!(building); self.zone_mesh(building); self.houses_mesh(building); @@ -595,10 +594,10 @@ impl MapBuilders { self.tess_map.meshbuilder.clear(); self.tess_lots.meshbuilder.clear(); - let low_col: LinearColor = simulation::config().road_low_col.into(); - let mid_col: LinearColor = simulation::config().road_mid_col.into(); - let hig_col: LinearColor = simulation::config().road_hig_col.into(); - let line_col: LinearColor = simulation::config().road_line_col.into(); + let low_col: LinearColor = simulation::colors().road_low_col.into(); + let mid_col: LinearColor = simulation::colors().road_mid_col.into(); + let hig_col: LinearColor = simulation::colors().road_hig_col.into(); + let line_col: LinearColor = simulation::colors().road_line_col.into(); let objs = map.spatial_map().query( chunk.bbox(), @@ -772,8 +771,8 @@ impl MapBuilders { for lot in chunk_lots { let lot = &lots[lot]; let col = match lot.kind { - LotKind::Unassigned => simulation::config().lot_unassigned_col, - LotKind::Residential => simulation::config().lot_residential_col, + LotKind::Unassigned => simulation::colors().lot_unassigned_col, + LotKind::Residential => simulation::colors().lot_residential_col, }; self.tess_lots.set_color(col); self.tess_lots @@ -791,7 +790,7 @@ fn add_polyon( dir, }: PylonPosition, ) { - let color = LinearColor::from(simulation::config().road_pylon_col); + let color = LinearColor::from(simulation::colors().road_pylon_col); let color: [f32; 4] = color.into(); let up = pos.up(-0.2); @@ -994,7 +993,7 @@ fn intersection_mesh( polygon.simplify(); - let col = LinearColor::from(simulation::config().road_mid_col).into(); + let col = LinearColor::from(simulation::colors().road_mid_col).into(); tess.meshbuilder .extend_with(None, move |vertices, add_idx| { vertices.extend(polygon.iter().map(|pos| MeshVertex { diff --git a/prototypes/src/lib.rs b/prototypes/src/lib.rs index 0bbf27a5..9748a5cf 100644 --- a/prototypes/src/lib.rs +++ b/prototypes/src/lib.rs @@ -34,9 +34,7 @@ pub trait Prototype: 'static + Sized { fn id(&self) -> Self::ID; /// The parent of the prototype - fn parent(&self) -> Option<&Self::Parent> { - None - } + fn parent(&self) -> Option<&Self::Parent>; /// util function to recursively insert the parents of this prototype into the prototypes lists fn insert_parents(&self, prototypes: &mut Prototypes) { @@ -74,6 +72,10 @@ impl Prototype for NoParent { fn id(&self) -> Self::ID { unreachable!() } + + fn parent(&self) -> Option<&Self::Parent> { + None + } } impl ConcretePrototype for NoParent { @@ -162,3 +164,8 @@ fn get_v2(t: &Table, field: &'static str) -> mlua::Result { let v = get_lua::(t, field)?; Ok(v.0) } + +fn get_color(t: &Table, field: &'static str) -> mlua::Result { + let v = get_lua::(t, field)?; + Ok(v.0) +} diff --git a/prototypes/src/macros.rs b/prototypes/src/macros.rs index 132ec314..50ff1c45 100644 --- a/prototypes/src/macros.rs +++ b/prototypes/src/macros.rs @@ -67,7 +67,11 @@ macro_rules! gen_prototypes { impl Prototypes { pub(crate) fn print_stats(&self) { $( - log::info!("loaded {} {}", <$t as $crate::ConcretePrototype>::storage(self).len(), <$t as $crate::Prototype>::NAME); + if <$t as $crate::ConcretePrototype>::storage(self).is_empty() { + log::warn!("no {} loaded", <$t as $crate::Prototype>::NAME); + } else { + log::info!("loaded {} {}", <$t as $crate::ConcretePrototype>::storage(self).len(), <$t as $crate::Prototype>::NAME); + } )+ } diff --git a/prototypes/src/prototype_init.lua b/prototypes/src/prototype_init.lua index 72072c72..e1eb8591 100644 --- a/prototypes/src/prototype_init.lua +++ b/prototypes/src/prototype_init.lua @@ -1,6 +1,11 @@ data = {} function data:extend (t) + if t.type ~= nil then -- we're extending a single prototype + rawset(self, rawlen(self)+1, t) + return + end + for _, v in ipairs(t) do rawset(self, rawlen(self)+1, v) end diff --git a/prototypes/src/prototypes/building.rs b/prototypes/src/prototypes/building.rs index 73974be4..8f4d989a 100644 --- a/prototypes/src/prototypes/building.rs +++ b/prototypes/src/prototypes/building.rs @@ -55,6 +55,10 @@ impl Prototype for BuildingPrototype { fn id(&self) -> Self::ID { self.id } + + fn parent(&self) -> Option<&Self::Parent> { + None + } } impl Deref for BuildingPrototype { diff --git a/prototypes/src/prototypes/colors.rs b/prototypes/src/prototypes/colors.rs new file mode 100644 index 00000000..b5ecbf71 --- /dev/null +++ b/prototypes/src/prototypes/colors.rs @@ -0,0 +1,83 @@ +use crate::{get_color, NoParent, Prototype, PrototypeBase}; +use geom::Color; +use mlua::Table; +use std::ops::Deref; + +use super::*; + +/// ColorsPrototype is the prototype to hold data about colors +#[derive(Clone, Debug)] +pub struct ColorsPrototype { + pub base: PrototypeBase, + pub id: ColorsPrototypeID, + + pub sand_col: Color, + pub sea_col: Color, + + pub roof_col: Color, + pub house_col: Color, + + pub gui_success: Color, + pub gui_danger: Color, + pub gui_primary: Color, + pub gui_disabled: Color, + + pub road_low_col: Color, + pub road_mid_col: Color, + pub road_hig_col: Color, + pub road_line_col: Color, + pub road_pylon_col: Color, + + pub lot_unassigned_col: Color, + pub lot_residential_col: Color, +} + +impl Prototype for ColorsPrototype { + type Parent = NoParent; + type ID = ColorsPrototypeID; + const NAME: &'static str = "colors"; + + fn from_lua(table: &Table) -> mlua::Result { + let base = PrototypeBase::from_lua(table)?; + Ok(Self { + id: Self::ID::new(&base.name), + base, + + sand_col: get_color(table, "sand_col")?, + sea_col: get_color(table, "sea_col")?, + + roof_col: get_color(table, "roof_col")?, + house_col: get_color(table, "house_col")?, + + gui_success: get_color(table, "gui_success")?, + gui_danger: get_color(table, "gui_danger")?, + gui_primary: get_color(table, "gui_primary")?, + gui_disabled: get_color(table, "gui_disabled")?, + + road_low_col: get_color(table, "road_low_col")?, + road_mid_col: get_color(table, "road_mid_col")?, + road_hig_col: get_color(table, "road_hig_col")?, + road_line_col: get_color(table, "road_line_col")?, + road_pylon_col: get_color(table, "road_pylon_col")?, + + lot_unassigned_col: get_color(table, "lot_unassigned_col")?, + lot_residential_col: get_color(table, "lot_residential_col")?, + }) + } + + fn id(&self) -> Self::ID { + self.id + } + + fn parent(&self) -> Option<&Self::Parent> { + None + } +} + +impl Deref for ColorsPrototype { + type Target = PrototypeBase; + + fn deref(&self) -> &Self::Target { + &self.base + } +} diff --git a/prototypes/src/prototypes/freightstation.rs b/prototypes/src/prototypes/freightstation.rs index c0736ed5..07e2e7b5 100644 --- a/prototypes/src/prototypes/freightstation.rs +++ b/prototypes/src/prototypes/freightstation.rs @@ -33,6 +33,10 @@ impl Prototype for FreightStationPrototype { fn id(&self) -> Self::ID { self.id } + + fn parent(&self) -> Option<&Self::Parent> { + None + } } impl Deref for FreightStationPrototype { diff --git a/prototypes/src/prototypes/goods_company.rs b/prototypes/src/prototypes/goods_company.rs index d21896b0..71d2bf61 100644 --- a/prototypes/src/prototypes/goods_company.rs +++ b/prototypes/src/prototypes/goods_company.rs @@ -47,6 +47,10 @@ impl Prototype for GoodsCompanyPrototype { fn id(&self) -> Self::ID { self.id } + + fn parent(&self) -> Option<&Self::Parent> { + Some(&self.base) + } } impl Deref for GoodsCompanyPrototype { diff --git a/prototypes/src/prototypes/item.rs b/prototypes/src/prototypes/item.rs index 595779b4..a5e333c4 100644 --- a/prototypes/src/prototypes/item.rs +++ b/prototypes/src/prototypes/item.rs @@ -28,6 +28,10 @@ impl Prototype for ItemPrototype { fn id(&self) -> Self::ID { self.id } + + fn parent(&self) -> Option<&Self::Parent> { + None + } } impl Deref for ItemPrototype { diff --git a/prototypes/src/prototypes/leisure.rs b/prototypes/src/prototypes/leisure.rs index 017f995f..66c94572 100644 --- a/prototypes/src/prototypes/leisure.rs +++ b/prototypes/src/prototypes/leisure.rs @@ -33,6 +33,10 @@ impl Prototype for LeisurePrototype { fn id(&self) -> Self::ID { self.id } + + fn parent(&self) -> Option<&Self::Parent> { + Some(&self.base) + } } impl Deref for LeisurePrototype { diff --git a/prototypes/src/prototypes/mod.rs b/prototypes/src/prototypes/mod.rs index 42bbc667..2a2c9be2 100644 --- a/prototypes/src/prototypes/mod.rs +++ b/prototypes/src/prototypes/mod.rs @@ -1,4 +1,5 @@ mod building; +mod colors; mod freightstation; mod goods_company; mod item; @@ -6,6 +7,7 @@ mod leisure; mod solar; pub use building::*; +pub use colors::*; pub use freightstation::*; pub use goods_company::*; pub use item::*; @@ -13,12 +15,14 @@ pub use leisure::*; pub use solar::*; crate::gen_prototypes!( - companies: GoodsCompanyID = GoodsCompanyPrototype => BuildingPrototypeID, - items: ItemID = ItemPrototype, - solar: SolarPanelID = SolarPanelPrototype => GoodsCompanyID, - stations: FreightStationPrototypeID = FreightStationPrototype, + items: ItemID = ItemPrototype, buildings: BuildingPrototypeID = BuildingPrototype, - leisure: LeisurePrototypeID = LeisurePrototype => BuildingPrototypeID, + companies: GoodsCompanyID = GoodsCompanyPrototype => BuildingPrototypeID, + leisure: LeisurePrototypeID = LeisurePrototype => BuildingPrototypeID, + solar: SolarPanelID = SolarPanelPrototype => GoodsCompanyID, + + colors: ColorsPrototypeID = ColorsPrototype, + stations: FreightStationPrototypeID = FreightStationPrototype, ); /** Prototype template. remplace $proto with the root name e.g Item @@ -52,6 +56,10 @@ impl Prototype for $protoPrototype { fn id(&self) -> Self::ID { self.id } + + fn parent(&self) -> Option<&Self::Parent> { + Some(&self.base) + } } impl Deref for $protoPrototype { @@ -86,4 +94,8 @@ impl crate::Prototype for PrototypeBase { } fn id(&self) -> Self::ID {} + + fn parent(&self) -> Option<&Self::Parent> { + None + } } diff --git a/prototypes/src/types/vec.rs b/prototypes/src/types/geom.rs similarity index 61% rename from prototypes/src/types/vec.rs rename to prototypes/src/types/geom.rs index 63887520..ce70a825 100644 --- a/prototypes/src/types/vec.rs +++ b/prototypes/src/types/geom.rs @@ -1,4 +1,4 @@ -use geom::{vec2, vec3, Vec2, Vec3}; +use geom::{vec2, vec3, Color, Vec2, Vec3}; use mlua::{FromLua, Value}; #[derive(Clone, Copy, Debug, PartialEq)] @@ -9,6 +9,10 @@ pub struct LuaVec2(pub Vec2); #[repr(transparent)] pub struct LuaVec3(pub Vec3); +#[derive(Clone, Copy, Debug, PartialEq)] +#[repr(transparent)] +pub struct LuaColor(pub Color); + impl Into for LuaVec2 { fn into(self) -> Vec2 { self.0 @@ -33,6 +37,50 @@ impl From for LuaVec2 { } } +impl From for LuaColor { + fn from(c: Color) -> Self { + Self(c) + } +} + +impl From for Color { + fn from(c: LuaColor) -> Self { + c.0 + } +} + +impl<'a> FromLua<'a> for LuaColor { + fn from_lua(value: Value<'a>, _: &'a mlua::Lua) -> mlua::Result { + let t = match value { + Value::Vector(v) => { + return Ok(Self(Color::new(v.x(), v.y(), v.z(), 1.0))); + } + Value::Table(t) => t, + _ => { + return Err(mlua::Error::FromLuaConversionError { + from: value.type_name(), + to: "Color", + message: Some("expected a table or vector".to_string()), + }) + } + }; + if let Ok(r) = t.get(1) { + return Ok(Self(Color::new( + r, + t.get(2)?, + t.get(3)?, + t.get(4).unwrap_or(1.0), + ))); + } + + let r = t.get("r")?; + let g = t.get("g")?; + let b = t.get("b")?; + let a = t.get("a").unwrap_or(1.0); + Ok(Self(Color::new(r, g, b, a))) + } +} + impl<'a> FromLua<'a> for LuaVec2 { fn from_lua(value: Value<'a>, _: &'a mlua::Lua) -> mlua::Result { let t = match value { diff --git a/prototypes/src/types/mod.rs b/prototypes/src/types/mod.rs index 68af208f..e3f95c9e 100644 --- a/prototypes/src/types/mod.rs +++ b/prototypes/src/types/mod.rs @@ -1,15 +1,15 @@ +mod geom; mod money; mod power; mod recipe; mod size; mod time; -mod vec; mod zone; +pub use geom::*; pub use money::*; pub use power::*; pub use recipe::*; pub use size::*; pub use time::*; -pub use vec::*; pub use zone::*; diff --git a/simulation/src/lib.rs b/simulation/src/lib.rs index 5e0f674d..43de16ac 100644 --- a/simulation/src/lib.rs +++ b/simulation/src/lib.rs @@ -1,14 +1,19 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::type_complexity)] +use crate::init::{GSYSTEMS, INIT_FUNCS, SAVELOAD_FUNCS}; use crate::map::{BuildingKind, Map}; use crate::map_dynamic::{Itinerary, ItineraryLeader}; use crate::souls::add_souls_to_empty_buildings; use crate::utils::resources::{Ref, RefMut, Resources}; +use crate::utils::scheduler::RunnableSystem; use crate::world_command::WorldCommand; +use crate::world_command::WorldCommand::Init; use common::saveload::Encoder; +use common::FastMap; use derive_more::{From, TryInto}; use geom::Vec3; +use prototypes::{prototype, ColorsPrototype, ColorsPrototypeID, GameTime, Tick}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::any::Any; use std::collections::BTreeMap; @@ -46,15 +51,13 @@ pub mod world_command; pub use world::*; -use crate::init::{GSYSTEMS, INIT_FUNCS, SAVELOAD_FUNCS}; -use crate::utils::scheduler::RunnableSystem; -use crate::world_command::WorldCommand::Init; -use common::FastMap; -use prototypes::{GameTime, Tick}; -pub use utils::config::*; pub use utils::par_command_buffer::ParCommandBuffer; pub use utils::replay::*; +pub fn colors() -> &'static ColorsPrototype { + prototype::(ColorsPrototypeID::new("colors")) +} + #[derive( Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Hash, From, TryInto, )] diff --git a/simulation/src/map/procgen/building.rs b/simulation/src/map/procgen/building.rs index efbad7d2..5fd3c38b 100644 --- a/simulation/src/map/procgen/building.rs +++ b/simulation/src/map/procgen/building.rs @@ -136,7 +136,7 @@ pub fn gen_exterior_house(size: f32, seed: u64) -> (ColoredMesh, Vec2) { ); let mut roofs = ColoredMesh::default(); - let roof_col = LinearColor::from(crate::config().roof_col); + let roof_col = LinearColor::from(crate::colors().roof_col); let height = 4.0 + gen_range(0.0, 2.0); @@ -175,7 +175,7 @@ pub fn gen_exterior_house(size: f32, seed: u64) -> (ColoredMesh, Vec2) { for (&a, &b, _) in geom::skeleton::window(&walls) { let face = vec![a, b, b.xy().z0(), a.xy().z0()]; - roofs.faces.push((face, crate::config().house_col.into())); + roofs.faces.push((face, crate::colors().house_col.into())); } return (roofs, lowest_segment.middle()); diff --git a/simulation/src/utils/config.rs b/simulation/src/utils/config.rs deleted file mode 100644 index 61531b4b..00000000 --- a/simulation/src/utils/config.rs +++ /dev/null @@ -1,69 +0,0 @@ -use arc_swap::{ArcSwap, Guard}; -use common::saveload::Encoder; -use egui_inspect::Inspect; -use geom::Color; -use lazy_static::lazy_static; -use serde::{Deserialize, Serialize}; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; - -#[derive(Default, Clone, Serialize, Deserialize, Inspect)] -#[serde(default)] -pub struct Config { - pub sand_col: Color, - pub sea_col: Color, - - pub roof_col: Color, - pub house_col: Color, - - pub gui_success: Color, - pub gui_danger: Color, - pub gui_primary: Color, - pub gui_disabled: Color, - - pub road_low_col: Color, - pub road_mid_col: Color, - pub road_hig_col: Color, - pub road_line_col: Color, - pub road_pylon_col: Color, - - pub lot_unassigned_col: Color, - pub lot_residential_col: Color, -} - -fn load_config_start() -> Config { - let c = common::saveload::load_raw("assets/config.json") - .and_then(|x| common::saveload::JSON::decode(&x).map_err(Into::into)) - .map_err(|x| { - log::error!("couldn't read config: {}", x); - }) - .unwrap_or_default(); - save_config(&c); - c -} - -fn save_config(config: &Config) { - let Ok(x) = common::saveload::JSONPretty::encode(config) else { - return; - }; - let _ = std::fs::write("assets/config.json", x); -} - -lazy_static! { - static ref CONFIG: ArcSwap = ArcSwap::from_pointee(load_config_start()); - static ref CONFIG_ID: AtomicUsize = AtomicUsize::new(0); -} - -pub fn config() -> Guard> { - CONFIG.load() -} - -pub fn config_id() -> usize { - CONFIG_ID.load(Ordering::Relaxed) -} - -pub fn update_config(new_config: Config) { - CONFIG_ID.fetch_add(1, Ordering::Relaxed); - save_config(&new_config); - CONFIG.store(Arc::new(new_config)); -} diff --git a/simulation/src/utils/mod.rs b/simulation/src/utils/mod.rs index b534031e..4b719ad1 100644 --- a/simulation/src/utils/mod.rs +++ b/simulation/src/utils/mod.rs @@ -1,8 +1,5 @@ -pub mod config; pub mod par_command_buffer; pub mod rand_provider; pub mod replay; pub mod resources; pub mod scheduler; - -pub use config::*;