From e8b489a71a79d69115780998946e41bfaf066620 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 3 Sep 2022 10:47:18 +0100 Subject: [PATCH] sync --- common/systems/src/character_behavior.rs | 4 +- common/systems/src/mount.rs | 8 +- common/systems/src/phys.rs | 8 +- rtsim/src/data/faction.rs | 20 ++--- rtsim/src/data/mod.rs | 35 +++++--- rtsim/src/data/nature.rs | 54 ++++++------ rtsim/src/data/npc.rs | 47 +++++------ rtsim/src/data/site.rs | 36 ++++---- rtsim/src/event.rs | 4 +- rtsim/src/gen/faction.rs | 7 +- rtsim/src/gen/mod.rs | 92 ++++++++++++--------- rtsim/src/gen/site.rs | 15 ++-- rtsim/src/lib.rs | 58 +++++++++---- rtsim/src/rule.rs | 8 +- rtsim/src/rule/npc_ai.rs | 13 +-- rtsim/src/rule/setup.rs | 42 ++++++---- rtsim/src/rule/simulate_npcs.rs | 16 ++-- server/src/chunk_generator.rs | 11 +-- server/src/cmd.rs | 23 ++++-- server/src/events/entity_manipulation.rs | 3 +- server/src/lib.rs | 19 ++++- server/src/rtsim2/event.rs | 2 +- server/src/rtsim2/mod.rs | 75 ++++++++++------- server/src/rtsim2/rule.rs | 2 +- server/src/rtsim2/rule/deplete_resources.rs | 27 +++--- server/src/rtsim2/tick.rs | 6 +- server/src/state_ext.rs | 2 +- server/src/sys/agent.rs | 5 +- server/src/sys/agent/data.rs | 4 +- voxygen/src/menu/main/mod.rs | 7 +- voxygen/src/scene/debug.rs | 4 +- voxygen/src/scene/figure/mod.rs | 14 ++-- voxygen/src/scene/mod.rs | 23 ++++-- world/src/civ/mod.rs | 14 +++- world/src/lib.rs | 21 ++--- world/src/site/settlement/mod.rs | 18 ++-- world/src/site2/mod.rs | 3 +- 37 files changed, 435 insertions(+), 315 deletions(-) diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index d4a8e6ca70..28c3393df6 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -9,8 +9,8 @@ use common::{ character_state::OutputEvents, inventory::item::{tool::AbilityMap, MaterialStatManifest}, ActiveAbilities, Beam, Body, CharacterState, Combo, Controller, Density, Energy, Health, - Inventory, InventoryManip, Mass, Melee, Ori, PhysicsState, Poise, Pos, SkillSet, Stance, - StateUpdate, Stats, Vel, Scale, + Inventory, InventoryManip, Mass, Melee, Ori, PhysicsState, Poise, Pos, Scale, SkillSet, Stance, + StateUpdate, Stats, Vel, }, event::{EventBus, LocalEvent, ServerEvent}, link::Is, diff --git a/common/systems/src/mount.rs b/common/systems/src/mount.rs index 997442f12e..25ee2ae644 100644 --- a/common/systems/src/mount.rs +++ b/common/systems/src/mount.rs @@ -1,5 +1,5 @@ use common::{ - comp::{Body, Controller, InputKind, Ori, Pos, Vel, Scale}, + comp::{Body, Controller, InputKind, Ori, Pos, Scale, Vel}, link::Is, mounting::Mount, uid::UidAllocator, @@ -69,8 +69,10 @@ impl<'a> System<'a> for Sys { let vel = velocities.get(entity).copied(); if let (Some(pos), Some(ori), Some(vel)) = (pos, ori, vel) { let mounter_body = bodies.get(rider); - let mounting_offset = body.map_or(Vec3::unit_z(), Body::mount_offset) * scales.get(entity).map_or(1.0, |s| s.0) - + mounter_body.map_or(Vec3::zero(), Body::rider_offset) * scales.get(rider).map_or(1.0, |s| s.0); + let mounting_offset = body.map_or(Vec3::unit_z(), Body::mount_offset) + * scales.get(entity).map_or(1.0, |s| s.0) + + mounter_body.map_or(Vec3::zero(), Body::rider_offset) + * scales.get(rider).map_or(1.0, |s| s.0); let _ = positions.insert(rider, Pos(pos.0 + ori.to_quat() * mounting_offset)); let _ = orientations.insert(rider, ori); let _ = velocities.insert(rider, vel); diff --git a/common/systems/src/phys.rs b/common/systems/src/phys.rs index 755e555872..6c738fa675 100644 --- a/common/systems/src/phys.rs +++ b/common/systems/src/phys.rs @@ -62,7 +62,13 @@ fn integrate_forces( // Aerodynamic/hydrodynamic forces if !rel_flow.0.is_approx_zero() { debug_assert!(!rel_flow.0.map(|a| a.is_nan()).reduce_or()); - let impulse = dt.0 * body.aerodynamic_forces(&rel_flow, fluid_density.0, wings, scale.map_or(1.0, |s| s.0)); + let impulse = dt.0 + * body.aerodynamic_forces( + &rel_flow, + fluid_density.0, + wings, + scale.map_or(1.0, |s| s.0), + ); debug_assert!(!impulse.map(|a| a.is_nan()).reduce_or()); if !impulse.is_approx_zero() { let new_v = vel.0 + impulse / mass.0; diff --git a/rtsim/src/data/faction.rs b/rtsim/src/data/faction.rs index f07c6296e9..d27c294e00 100644 --- a/rtsim/src/data/faction.rs +++ b/rtsim/src/data/faction.rs @@ -1,14 +1,11 @@ -use hashbrown::HashMap; -use serde::{Serialize, Deserialize}; -use slotmap::HopSlotMap; -use vek::*; -use std::ops::{Deref, DerefMut}; -use common::{ - uid::Uid, - store::Id, -}; use super::Actor; pub use common::rtsim::FactionId; +use common::{store::Id, uid::Uid}; +use hashbrown::HashMap; +use serde::{Deserialize, Serialize}; +use slotmap::HopSlotMap; +use std::ops::{Deref, DerefMut}; +use vek::*; #[derive(Clone, Serialize, Deserialize)] pub struct Faction { @@ -21,13 +18,12 @@ pub struct Factions { } impl Factions { - pub fn create(&mut self, faction: Faction) -> FactionId { - self.factions.insert(faction) - } + pub fn create(&mut self, faction: Faction) -> FactionId { self.factions.insert(faction) } } impl Deref for Factions { type Target = HopSlotMap; + fn deref(&self) -> &Self::Target { &self.factions } } diff --git a/rtsim/src/data/mod.rs b/rtsim/src/data/mod.rs index f193e8eb85..df4c219ef0 100644 --- a/rtsim/src/data/mod.rs +++ b/rtsim/src/data/mod.rs @@ -1,23 +1,26 @@ pub mod faction; +pub mod nature; pub mod npc; pub mod site; -pub mod nature; pub use self::{ - npc::{Npc, NpcId, Npcs}, - site::{Site, SiteId, Sites}, faction::{Faction, FactionId, Factions}, nature::Nature, + npc::{Npc, NpcId, Npcs}, + site::{Site, SiteId, Sites}, }; use common::resources::TimeOfDay; -use enum_map::{EnumMap, EnumArray, enum_map}; -use serde::{Serialize, Deserialize, ser, de}; +use enum_map::{enum_map, EnumArray, EnumMap}; +use serde::{ + de::{self, Error as _}, + ser, Deserialize, Serialize, +}; use std::{ - io::{Read, Write}, - marker::PhantomData, cmp::PartialEq, fmt, + io::{Read, Write}, + marker::PhantomData, }; #[derive(Copy, Clone, Serialize, Deserialize)] @@ -54,11 +57,15 @@ fn rugged_ser_enum_map< V: From + PartialEq + Serialize, S: ser::Serializer, const DEFAULT: i16, ->(map: &EnumMap, ser: S) -> Result { - ser.collect_map(map - .iter() - .filter(|(k, v)| v != &&V::from(DEFAULT)) - .map(|(k, v)| (k, v))) +>( + map: &EnumMap, + ser: S, +) -> Result { + ser.collect_map( + map.iter() + .filter(|(k, v)| v != &&V::from(DEFAULT)) + .map(|(k, v)| (k, v)), + ) } fn rugged_de_enum_map< @@ -67,7 +74,9 @@ fn rugged_de_enum_map< V: From + Deserialize<'a>, D: de::Deserializer<'a>, const DEFAULT: i16, ->(mut de: D) -> Result, D::Error> { +>( + mut de: D, +) -> Result, D::Error> { struct Visitor(PhantomData<(K, V)>); impl<'de, K, V, const DEFAULT: i16> de::Visitor<'de> for Visitor diff --git a/rtsim/src/data/nature.rs b/rtsim/src/data/nature.rs index 2a7abf8b0f..2325ad6dbc 100644 --- a/rtsim/src/data/nature.rs +++ b/rtsim/src/data/nature.rs @@ -1,17 +1,15 @@ -use serde::{Serialize, Deserialize}; +use common::{grid::Grid, rtsim::ChunkResource}; use enum_map::EnumMap; -use common::{ - grid::Grid, - rtsim::ChunkResource, -}; -use world::World; +use serde::{Deserialize, Serialize}; use vek::*; +use world::World; -/// Represents the state of 'natural' elements of the world such as plant/animal/resource populations, weather systems, -/// etc. +/// Represents the state of 'natural' elements of the world such as +/// plant/animal/resource populations, weather systems, etc. /// -/// Where possible, this data does not define the state of natural aspects of the world, but instead defines -/// 'modifications' that sit on top of the world data generated by initial generation. +/// Where possible, this data does not define the state of natural aspects of +/// the world, but instead defines 'modifications' that sit on top of the world +/// data generated by initial generation. #[derive(Clone, Serialize, Deserialize)] pub struct Nature { chunks: Grid, @@ -20,22 +18,17 @@ pub struct Nature { impl Nature { pub fn generate(world: &World) -> Self { Self { - chunks: Grid::populate_from( - world.sim().get_size().map(|e| e as i32), - |pos| Chunk { - res: EnumMap::<_, f32>::default().map(|_, _| 1.0), - }, - ), + chunks: Grid::populate_from(world.sim().get_size().map(|e| e as i32), |pos| Chunk { + res: EnumMap::<_, f32>::default().map(|_, _| 1.0), + }), } } // TODO: Clean up this API a bit pub fn get_chunk_resources(&self, key: Vec2) -> EnumMap { - self.chunks - .get(key) - .map(|c| c.res) - .unwrap_or_default() + self.chunks.get(key).map(|c| c.res).unwrap_or_default() } + pub fn set_chunk_resources(&mut self, key: Vec2, res: EnumMap) { if let Some(chunk) = self.chunks.get_mut(key) { chunk.res = res; @@ -45,16 +38,21 @@ impl Nature { #[derive(Clone, Serialize, Deserialize)] pub struct Chunk { - /// Represent the 'naturally occurring' resource proportion that exists in this chunk. + /// Represent the 'naturally occurring' resource proportion that exists in + /// this chunk. /// - /// 0.0 => None of the resources generated by terrain generation should be present - /// 1.0 => All of the resources generated by terrain generation should be present + /// 0.0 => None of the resources generated by terrain generation should be + /// present 1.0 => All of the resources generated by terrain generation + /// should be present /// - /// It's important to understand this this number does not represent the total amount of a resource present in a - /// chunk, nor is it even proportional to the amount of the resource present. To get the total amount of the - /// resource in a chunk, one must first multiply this factor by the amount of 'natural' resources given by terrain - /// generation. This value represents only the variable 'depletion' factor of that resource, which shall change - /// over time as the world evolves and players interact with it. + /// It's important to understand this this number does not represent the + /// total amount of a resource present in a chunk, nor is it even + /// proportional to the amount of the resource present. To get the total + /// amount of the resource in a chunk, one must first multiply this + /// factor by the amount of 'natural' resources given by terrain + /// generation. This value represents only the variable 'depletion' factor + /// of that resource, which shall change over time as the world evolves + /// and players interact with it. #[serde(rename = "r")] #[serde(serialize_with = "crate::data::rugged_ser_enum_map::<_, _, _, 1>")] #[serde(deserialize_with = "crate::data::rugged_de_enum_map::<_, _, _, 1>")] diff --git a/rtsim/src/data/npc.rs b/rtsim/src/data/npc.rs index 36c5d2ae16..bd97d8d097 100644 --- a/rtsim/src/data/npc.rs +++ b/rtsim/src/data/npc.rs @@ -1,18 +1,20 @@ -use hashbrown::HashMap; -use serde::{Serialize, Deserialize}; -use slotmap::HopSlotMap; -use vek::*; -use rand::prelude::*; -use std::{ops::{Deref, DerefMut}, collections::VecDeque}; -use common::{ - uid::Uid, - store::Id, - rtsim::{SiteId, FactionId, RtSimController}, - comp, -}; -use world::{util::RandomPerm, civ::Track}; -use world::site::Site as WorldSite; pub use common::rtsim::{NpcId, Profession}; +use common::{ + comp, + rtsim::{FactionId, RtSimController, SiteId}, + store::Id, + uid::Uid, +}; +use hashbrown::HashMap; +use rand::prelude::*; +use serde::{Deserialize, Serialize}; +use slotmap::HopSlotMap; +use std::{ + collections::VecDeque, + ops::{Deref, DerefMut}, +}; +use vek::*; +use world::{civ::Track, site::Site as WorldSite, util::RandomPerm}; #[derive(Copy, Clone, Default)] pub enum NpcMode { @@ -39,7 +41,6 @@ pub struct PathingMemory { #[derive(Clone, Serialize, Deserialize)] pub struct Npc { // Persisted state - /// Represents the location of the NPC. pub seed: u32, pub wpos: Vec3, @@ -58,17 +59,18 @@ pub struct Npc { /// (wpos, speed_factor) #[serde(skip_serializing, skip_deserializing)] pub goto: Option<(Vec3, f32)>, - - /// Whether the NPC is in simulated or loaded mode (when rtsim is run on the server, loaded corresponds to being - /// within a loaded chunk). When in loaded mode, the interactions of the NPC should not be simulated but should - /// instead be derived from the game. + + /// Whether the NPC is in simulated or loaded mode (when rtsim is run on the + /// server, loaded corresponds to being within a loaded chunk). When in + /// loaded mode, the interactions of the NPC should not be simulated but + /// should instead be derived from the game. #[serde(skip_serializing, skip_deserializing)] pub mode: NpcMode, } impl Npc { - const PERM_SPECIES: u32 = 0; const PERM_BODY: u32 = 1; + const PERM_SPECIES: u32 = 0; pub fn new(seed: u32, wpos: Vec3) -> Self { Self { @@ -115,13 +117,12 @@ pub struct Npcs { } impl Npcs { - pub fn create(&mut self, npc: Npc) -> NpcId { - self.npcs.insert(npc) - } + pub fn create(&mut self, npc: Npc) -> NpcId { self.npcs.insert(npc) } } impl Deref for Npcs { type Target = HopSlotMap; + fn deref(&self) -> &Self::Target { &self.npcs } } diff --git a/rtsim/src/data/site.rs b/rtsim/src/data/site.rs index 9189d4a97b..f1edf2645e 100644 --- a/rtsim/src/data/site.rs +++ b/rtsim/src/data/site.rs @@ -1,14 +1,10 @@ -use hashbrown::HashMap; -use serde::{Serialize, Deserialize}; -use slotmap::HopSlotMap; -use vek::*; -use std::ops::{Deref, DerefMut}; -use common::{ - uid::Uid, - store::Id, - rtsim::FactionId, -}; pub use common::rtsim::SiteId; +use common::{rtsim::FactionId, store::Id, uid::Uid}; +use hashbrown::HashMap; +use serde::{Deserialize, Serialize}; +use slotmap::HopSlotMap; +use std::ops::{Deref, DerefMut}; +use vek::*; use world::site::Site as WorldSite; #[derive(Clone, Serialize, Deserialize)] @@ -16,14 +12,19 @@ pub struct Site { pub wpos: Vec2, pub faction: Option, - /// The site generated during initial worldgen that this site corresponds to. + /// The site generated during initial worldgen that this site corresponds + /// to. /// - /// Eventually, rtsim should replace initial worldgen's site system and this will not be necessary. + /// Eventually, rtsim should replace initial worldgen's site system and this + /// will not be necessary. /// - /// When setting up rtsim state, we try to 'link' these two definitions of a site: but if initial worldgen has - /// changed, this might not be possible. We try to delete sites that no longer exist during setup, but this is an - /// inherent fallible process. If linking fails, we try to delete the site in rtsim2 in order to avoid an - /// 'orphaned' site. (TODO: create new sites for new initial worldgen sites that come into being too). + /// When setting up rtsim state, we try to 'link' these two definitions of a + /// site: but if initial worldgen has changed, this might not be + /// possible. We try to delete sites that no longer exist during setup, but + /// this is an inherent fallible process. If linking fails, we try to + /// delete the site in rtsim2 in order to avoid an 'orphaned' site. + /// (TODO: create new sites for new initial worldgen sites that come into + /// being too). #[serde(skip_serializing, skip_deserializing)] pub world_site: Option>, } @@ -38,7 +39,7 @@ impl Site { #[derive(Clone, Serialize, Deserialize)] pub struct Sites { pub sites: HopSlotMap, - + #[serde(skip_serializing, skip_deserializing)] pub world_site_map: HashMap, SiteId>, } @@ -56,6 +57,7 @@ impl Sites { impl Deref for Sites { type Target = HopSlotMap; + fn deref(&self) -> &Self::Target { &self.sites } } diff --git a/rtsim/src/event.rs b/rtsim/src/event.rs index 72932e9668..1ae5cbb6bb 100644 --- a/rtsim/src/event.rs +++ b/rtsim/src/event.rs @@ -1,6 +1,6 @@ +use super::{RtState, Rule}; use common::resources::{Time, TimeOfDay}; -use world::{World, IndexRef}; -use super::{Rule, RtState}; +use world::{IndexRef, World}; pub trait Event: Clone + 'static {} diff --git a/rtsim/src/gen/faction.rs b/rtsim/src/gen/faction.rs index 0027042038..ed09d71594 100644 --- a/rtsim/src/gen/faction.rs +++ b/rtsim/src/gen/faction.rs @@ -1,10 +1,7 @@ use crate::data::Faction; -use vek::*; use rand::prelude::*; -use world::{ - World, - IndexRef, -}; +use vek::*; +use world::{IndexRef, World}; impl Faction { pub fn generate(world: &World, index: IndexRef, rng: &mut impl Rng) -> Self { diff --git a/rtsim/src/gen/mod.rs b/rtsim/src/gen/mod.rs index e452294ac4..ee0ffe8b49 100644 --- a/rtsim/src/gen/mod.rs +++ b/rtsim/src/gen/mod.rs @@ -1,40 +1,41 @@ -pub mod site; pub mod faction; +pub mod site; use crate::data::{ - npc::{Npcs, Npc, Profession}, - site::{Sites, Site}, - faction::{Factions, Faction}, - Data, - Nature, + faction::{Faction, Factions}, + npc::{Npc, Npcs, Profession}, + site::{Site, Sites}, + Data, Nature, +}; +use common::{ + resources::TimeOfDay, rtsim::WorldSettings, terrain::TerrainChunkSize, vol::RectVolSize, }; use hashbrown::HashMap; use rand::prelude::*; use tracing::info; use vek::*; -use common::{ - rtsim::WorldSettings, - resources::TimeOfDay, - terrain::TerrainChunkSize, - vol::RectVolSize, -}; -use world::{ - site::SiteKind, - IndexRef, - World, -}; +use world::{site::SiteKind, IndexRef, World}; impl Data { pub fn generate(settings: &WorldSettings, world: &World, index: IndexRef) -> Self { let mut seed = [0; 32]; - seed.iter_mut().zip(&mut index.seed.to_le_bytes()).for_each(|(dst, src)| *dst = *src); + seed.iter_mut() + .zip(&mut index.seed.to_le_bytes()) + .for_each(|(dst, src)| *dst = *src); let mut rng = SmallRng::from_seed(seed); let mut this = Self { nature: Nature::generate(world), - npcs: Npcs { npcs: Default::default() }, - sites: Sites { sites: Default::default(), world_site_map: Default::default() }, - factions: Factions { factions: Default::default() }, + npcs: Npcs { + npcs: Default::default(), + }, + sites: Sites { + sites: Default::default(), + world_site_map: Default::default(), + }, + factions: Factions { + factions: Default::default(), + }, time_of_day: TimeOfDay(settings.start_time), }; @@ -45,44 +46,53 @@ impl Data { let wpos = world .sim() .get_size() - .map2(TerrainChunkSize::RECT_SIZE, |e, sz| rng.gen_range(0..(e * sz) as i32)); + .map2(TerrainChunkSize::RECT_SIZE, |e, sz| { + rng.gen_range(0..(e * sz) as i32) + }); (wpos, this.factions.create(faction)) }) .collect::>(); info!("Generated {} rtsim factions.", this.factions.len()); // Register sites with rtsim - for (world_site_id, _) in index - .sites - .iter() - { + for (world_site_id, _) in index.sites.iter() { let site = Site::generate(world_site_id, world, index, &initial_factions); this.sites.create(site); } - info!("Registering {} rtsim sites from world sites.", this.sites.len()); + info!( + "Registering {} rtsim sites from world sites.", + this.sites.len() + ); // Spawn some test entities at the sites for (site_id, site) in this.sites.iter() { let rand_wpos = |rng: &mut SmallRng| { let wpos2d = site.wpos.map(|e| e + rng.gen_range(-10..10)); - wpos2d.map(|e| e as f32 + 0.5) + wpos2d + .map(|e| e as f32 + 0.5) .with_z(world.sim().get_alt_approx(wpos2d).unwrap_or(0.0)) }; for _ in 0..20 { - - this.npcs.create(Npc::new(rng.gen(), rand_wpos(&mut rng)) - .with_faction(site.faction) - .with_home(site_id).with_profession(match rng.gen_range(0..20) { - 0 => Profession::Hunter, - 1 => Profession::Blacksmith, - 2 => Profession::Chef, - 3 => Profession::Alchemist, - 5..=10 => Profession::Farmer, - 11..=15 => Profession::Guard, - _ => Profession::Adventurer(rng.gen_range(0..=3)), - })); + this.npcs.create( + Npc::new(rng.gen(), rand_wpos(&mut rng)) + .with_faction(site.faction) + .with_home(site_id) + .with_profession(match rng.gen_range(0..20) { + 0 => Profession::Hunter, + 1 => Profession::Blacksmith, + 2 => Profession::Chef, + 3 => Profession::Alchemist, + 5..=10 => Profession::Farmer, + 11..=15 => Profession::Guard, + _ => Profession::Adventurer(rng.gen_range(0..=3)), + }), + ); } - this.npcs.create(Npc::new(rng.gen(), rand_wpos(&mut rng)).with_home(site_id).with_profession(Profession::Merchant)); + this.npcs.create( + Npc::new(rng.gen(), rand_wpos(&mut rng)) + .with_home(site_id) + .with_profession(Profession::Merchant), + ); } info!("Generated {} rtsim NPCs.", this.npcs.len()); diff --git a/rtsim/src/gen/site.rs b/rtsim/src/gen/site.rs index dad713b48c..30d079362f 100644 --- a/rtsim/src/gen/site.rs +++ b/rtsim/src/gen/site.rs @@ -1,14 +1,15 @@ -use crate::data::{Site, FactionId}; +use crate::data::{FactionId, Site}; use common::store::Id; use vek::*; -use world::{ - site::Site as WorldSite, - World, - IndexRef, -}; +use world::{site::Site as WorldSite, IndexRef, World}; impl Site { - pub fn generate(world_site: Id, world: &World, index: IndexRef, nearby_factions: &[(Vec2, FactionId)]) -> Self { + pub fn generate( + world_site: Id, + world: &World, + index: IndexRef, + nearby_factions: &[(Vec2, FactionId)], + ) -> Self { let wpos = index.sites.get(world_site).get_origin(); Self { diff --git a/rtsim/src/lib.rs b/rtsim/src/lib.rs index 9152bc9d11..0a15a841bc 100644 --- a/rtsim/src/lib.rs +++ b/rtsim/src/lib.rs @@ -10,15 +10,15 @@ pub use self::{ event::{Event, EventCtx, OnTick}, rule::{Rule, RuleError}, }; -use common::resources::{Time, TimeOfDay}; -use world::{World, IndexRef}; use anymap2::SendSyncAnyMap; -use tracing::{info, error}; use atomic_refcell::AtomicRefCell; +use common::resources::{Time, TimeOfDay}; use std::{ any::type_name, ops::{Deref, DerefMut}, }; +use tracing::{error, info}; +use world::{IndexRef, World}; pub struct RtState { resources: SendSyncAnyMap, @@ -36,7 +36,7 @@ impl RtState { rules: SendSyncAnyMap::new(), event_handlers: SendSyncAnyMap::new(), } - .with_resource(data); + .with_resource(data); this.start_default_rules(); @@ -58,7 +58,9 @@ impl RtState { pub fn start_rule(&mut self) { info!("Initiating '{}' rule...", type_name::()); match R::start(self) { - Ok(rule) => { self.rules.insert::>(AtomicRefCell::new(rule)); }, + Ok(rule) => { + self.rules.insert::>(AtomicRefCell::new(rule)); + }, Err(e) => error!("Error when initiating '{}' rule: {}", type_name::(), e), } } @@ -66,11 +68,19 @@ impl RtState { fn rule_mut(&self) -> impl DerefMut + '_ { self.rules .get::>() - .unwrap_or_else(|| panic!("Tried to access rule '{}' but it does not exist", type_name::())) + .unwrap_or_else(|| { + panic!( + "Tried to access rule '{}' but it does not exist", + type_name::() + ) + }) .borrow_mut() } - pub fn bind(&mut self, mut f: impl FnMut(EventCtx) + Send + Sync + 'static) { + pub fn bind( + &mut self, + mut f: impl FnMut(EventCtx) + Send + Sync + 'static, + ) { let f = AtomicRefCell::new(f); self.event_handlers .entry::>() @@ -87,33 +97,53 @@ impl RtState { } pub fn data(&self) -> impl Deref + '_ { self.resource() } + pub fn data_mut(&self) -> impl DerefMut + '_ { self.resource_mut() } pub fn resource(&self) -> impl Deref + '_ { self.resources .get::>() - .unwrap_or_else(|| panic!("Tried to access resource '{}' but it does not exist", type_name::())) + .unwrap_or_else(|| { + panic!( + "Tried to access resource '{}' but it does not exist", + type_name::() + ) + }) .borrow() } pub fn resource_mut(&self) -> impl DerefMut + '_ { self.resources .get::>() - .unwrap_or_else(|| panic!("Tried to access resource '{}' but it does not exist", type_name::())) + .unwrap_or_else(|| { + panic!( + "Tried to access resource '{}' but it does not exist", + type_name::() + ) + }) .borrow_mut() } pub fn emit(&mut self, e: E, world: &World, index: IndexRef) { self.event_handlers .get::>() - .map(|handlers| handlers - .iter() - .for_each(|f| f(self, world, index, &e))); + .map(|handlers| handlers.iter().for_each(|f| f(self, world, index, &e))); } - pub fn tick(&mut self, world: &World, index: IndexRef, time_of_day: TimeOfDay, time: Time, dt: f32) { + pub fn tick( + &mut self, + world: &World, + index: IndexRef, + time_of_day: TimeOfDay, + time: Time, + dt: f32, + ) { self.data_mut().time_of_day = time_of_day; - let event = OnTick { time_of_day, time, dt }; + let event = OnTick { + time_of_day, + time, + dt, + }; self.emit(event, world, index); } } diff --git a/rtsim/src/rule.rs b/rtsim/src/rule.rs index 611872ab75..5444d0a2c7 100644 --- a/rtsim/src/rule.rs +++ b/rtsim/src/rule.rs @@ -1,9 +1,9 @@ +pub mod npc_ai; pub mod setup; pub mod simulate_npcs; -pub mod npc_ai; -use std::fmt; use super::RtState; +use std::fmt; #[derive(Debug)] pub enum RuleError { @@ -13,7 +13,9 @@ pub enum RuleError { impl fmt::Display for RuleError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::NoSuchRule(r) => write!(f, "tried to fetch rule state '{}' but it does not exist", r), + Self::NoSuchRule(r) => { + write!(f, "tried to fetch rule state '{}' but it does not exist", r) + }, } } } diff --git a/rtsim/src/rule/npc_ai.rs b/rtsim/src/rule/npc_ai.rs index 0b6d50937a..8f5a02fbf9 100644 --- a/rtsim/src/rule/npc_ai.rs +++ b/rtsim/src/rule/npc_ai.rs @@ -10,7 +10,8 @@ use common::{ path::Path, rtsim::{Profession, SiteId}, store::Id, - terrain::TerrainChunkSize, vol::RectVolSize, + terrain::TerrainChunkSize, + vol::RectVolSize, }; use fxhash::FxHasher64; use itertools::Itertools; @@ -236,10 +237,12 @@ impl Rule for NpcAi { let data = &mut *ctx.state.data_mut(); let mut dynamic_rng = rand::thread_rng(); for npc in data.npcs.values_mut() { - npc.current_site = ctx.world.sim().get(npc.wpos.xy().as_::() / TerrainChunkSize::RECT_SIZE.as_()).and_then(|chunk| { - data.sites.world_site_map.get(chunk.sites.first()?).copied() - }); - + npc.current_site = ctx + .world + .sim() + .get(npc.wpos.xy().as_::() / TerrainChunkSize::RECT_SIZE.as_()) + .and_then(|chunk| data.sites.world_site_map.get(chunk.sites.first()?).copied()); + if let Some(home_id) = npc.home { if let Some((target, _)) = npc.goto { // Walk to the current target diff --git a/rtsim/src/rule/setup.rs b/rtsim/src/rule/setup.rs index cbcda44025..eebec822e5 100644 --- a/rtsim/src/rule/setup.rs +++ b/rtsim/src/rule/setup.rs @@ -1,12 +1,9 @@ +use crate::{data::Site, event::OnSetup, RtState, Rule, RuleError}; use tracing::warn; -use crate::{ - data::Site, - event::OnSetup, - RtState, Rule, RuleError, -}; -/// This rule runs at rtsim startup and broadly acts to perform some primitive migration/sanitisation in order to -/// ensure that the state of rtsim is mostly sensible. +/// This rule runs at rtsim startup and broadly acts to perform some primitive +/// migration/sanitisation in order to ensure that the state of rtsim is mostly +/// sensible. pub struct Setup; impl Rule for Setup { @@ -15,14 +12,20 @@ impl Rule for Setup { let data = &mut *ctx.state.data_mut(); // Delete rtsim sites that don't correspond to a world site data.sites.retain(|site_id, site| { - if let Some((world_site_id, _)) = ctx.index.sites + if let Some((world_site_id, _)) = ctx + .index + .sites .iter() .find(|(_, world_site)| world_site.get_origin() == site.wpos) { site.world_site = Some(world_site_id); true } else { - warn!("{:?} is no longer valid because the site it was derived from no longer exists. It will now be deleted.", site_id); + warn!( + "{:?} is no longer valid because the site it was derived from no longer \ + exists. It will now be deleted.", + site_id + ); false } }); @@ -32,15 +35,20 @@ impl Rule for Setup { npc.home = npc.home.filter(|home| data.sites.contains_key(*home)); } - // Generate rtsim sites for world sites that don't have a corresponding rtsim site yet + // Generate rtsim sites for world sites that don't have a corresponding rtsim + // site yet for (world_site_id, _) in ctx.index.sites.iter() { - if !data.sites - .values() - .any(|site| site.world_site.expect("Rtsim site not assigned to world site") == world_site_id) - { - warn!("{:?} is new and does not have a corresponding rtsim site. One will now be generated afresh.", world_site_id); - data - .sites + if !data.sites.values().any(|site| { + site.world_site + .expect("Rtsim site not assigned to world site") + == world_site_id + }) { + warn!( + "{:?} is new and does not have a corresponding rtsim site. One will now \ + be generated afresh.", + world_site_id + ); + data.sites .create(Site::generate(world_site_id, ctx.world, ctx.index, &[])); } } diff --git a/rtsim/src/rule/simulate_npcs.rs b/rtsim/src/rule/simulate_npcs.rs index 34fa6e8d6d..b2761cc404 100644 --- a/rtsim/src/rule/simulate_npcs.rs +++ b/rtsim/src/rule/simulate_npcs.rs @@ -1,17 +1,12 @@ +use crate::{data::npc::NpcMode, event::OnTick, RtState, Rule, RuleError}; use common::{terrain::TerrainChunkSize, vol::RectVolSize}; use tracing::info; use vek::*; -use crate::{ - data::npc::NpcMode, - event::OnTick, - RtState, Rule, RuleError, -}; pub struct SimulateNpcs; impl Rule for SimulateNpcs { fn start(rtstate: &mut RtState) -> Result { - rtstate.bind::(|ctx| { let data = &mut *ctx.state.data_mut(); for npc in data @@ -28,14 +23,17 @@ impl Rule for SimulateNpcs { if dist2 > 0.5f32.powi(2) { npc.wpos += (diff - * (body.max_speed_approx() * speed_factor * ctx.event.dt / dist2.sqrt()) - .min(1.0)) + * (body.max_speed_approx() * speed_factor * ctx.event.dt + / dist2.sqrt()) + .min(1.0)) .with_z(0.0); } } // Make sure NPCs remain on the surface - npc.wpos.z = ctx.world.sim() + npc.wpos.z = ctx + .world + .sim() .get_alt_approx(npc.wpos.xy().map(|e| e as i32)) .unwrap_or(0.0); } diff --git a/server/src/chunk_generator.rs b/server/src/chunk_generator.rs index f5b34e7f4a..c5ca62be7d 100644 --- a/server/src/chunk_generator.rs +++ b/server/src/chunk_generator.rs @@ -1,9 +1,6 @@ -use crate::{ - metrics::ChunkGenMetrics, - rtsim2::RtSim, -}; #[cfg(not(feature = "worldgen"))] use crate::test_world::{IndexOwned, World}; +use crate::{metrics::ChunkGenMetrics, rtsim2::RtSim}; use common::{ calendar::Calendar, generation::ChunkSupplement, resources::TimeOfDay, slowjob::SlowJobPool, terrain::TerrainChunk, @@ -47,10 +44,8 @@ impl ChunkGenerator { key: Vec2, slowjob_pool: &SlowJobPool, world: Arc, - #[cfg(feature = "worldgen")] - rtsim: &RtSim, - #[cfg(not(feature = "worldgen"))] - rtsim: &(), + #[cfg(feature = "worldgen")] rtsim: &RtSim, + #[cfg(not(feature = "worldgen"))] rtsim: &(), index: IndexOwned, time: (TimeOfDay, Calendar), ) { diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 8132fae612..3edf3fcc5c 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -1192,9 +1192,19 @@ fn handle_tp_npc( ) -> CmdResult<()> { use crate::rtsim2::RtSim; let pos = if let Some(id) = parse_cmd_args!(args, u32) { - // TODO: Take some other identifier than an integer to this command. - server.state.ecs().read_resource::().state().data().npcs.values().nth(id as usize).ok_or(action.help_string())?.wpos - } else { + // TODO: Take some other identifier than an integer to this command. + server + .state + .ecs() + .read_resource::() + .state() + .data() + .npcs + .values() + .nth(id as usize) + .ok_or(action.help_string())? + .wpos + } else { return Err(action.help_string()); }; position_mut(server, target, "target", |target_pos| { @@ -3873,12 +3883,7 @@ fn handle_scale( .write_storage::() .insert(target, comp::Scale(scale)); if reset_mass.unwrap_or(true) { - if let Some(body) = server - .state - .ecs() - .read_storage::() - .get(target) - { + if let Some(body) = server.state.ecs().read_storage::().get(target) { let _ = server .state .ecs() diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 3307d80ed8..0c9944731d 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -7,9 +7,8 @@ use crate::{ skillset::SkillGroupKind, BuffKind, BuffSource, PhysicsState, }, - // rtsim::RtSim, - sys::terrain::SAFE_ZONE_RADIUS, rtsim2, + sys::terrain::SAFE_ZONE_RADIUS, Server, SpawnPoint, StateExt, }; use authc::Uuid; diff --git a/server/src/lib.rs b/server/src/lib.rs index 94c8dc7efb..7deaa9e7c4 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -83,7 +83,7 @@ use common::{ rtsim::RtSimEntity, shared_server_config::ServerConstants, slowjob::SlowJobPool, - terrain::{TerrainChunk, TerrainChunkSize, Block}, + terrain::{Block, TerrainChunk, TerrainChunkSize}, vol::RectRasterableVol, }; use common_ecs::run_now; @@ -565,7 +565,12 @@ impl Server { // Init rtsim, loading it from disk if possible #[cfg(feature = "worldgen")] { - match rtsim2::RtSim::new(&settings.world, index.as_index_ref(), &world, data_dir.to_owned()) { + match rtsim2::RtSim::new( + &settings.world, + index.as_index_ref(), + &world, + data_dir.to_owned(), + ) { Ok(rtsim) => { state.ecs_mut().insert(rtsim.state().data().time_of_day); state.ecs_mut().insert(rtsim); @@ -706,9 +711,15 @@ impl Server { let before_state_tick = Instant::now(); - fn on_block_update(ecs: &specs::World, wpos: Vec3, old_block: Block, new_block: Block) { + fn on_block_update( + ecs: &specs::World, + wpos: Vec3, + old_block: Block, + new_block: Block, + ) { // When a resource block updates, inform rtsim - if old_block.get_rtsim_resource().is_some() || new_block.get_rtsim_resource().is_some() { + if old_block.get_rtsim_resource().is_some() || new_block.get_rtsim_resource().is_some() + { ecs.write_resource::().hook_block_update( &ecs.read_resource::>(), ecs.read_resource::().as_index_ref(), diff --git a/server/src/rtsim2/event.rs b/server/src/rtsim2/event.rs index e576c42fcb..958bf458fa 100644 --- a/server/src/rtsim2/event.rs +++ b/server/src/rtsim2/event.rs @@ -1,5 +1,5 @@ -use rtsim2::Event; use common::terrain::Block; +use rtsim2::Event; use vek::*; #[derive(Clone)] diff --git a/server/src/rtsim2/mod.rs b/server/src/rtsim2/mod.rs index 2df1720c1c..45eba51d8f 100644 --- a/server/src/rtsim2/mod.rs +++ b/server/src/rtsim2/mod.rs @@ -4,33 +4,29 @@ pub mod tick; use common::{ grid::Grid, - slowjob::SlowJobPool, rtsim::{ChunkResource, RtSimEntity, WorldSettings}, - terrain::{TerrainChunk, Block}, + slowjob::SlowJobPool, + terrain::{Block, TerrainChunk}, vol::RectRasterableVol, }; use common_ecs::{dispatch, System}; +use enum_map::EnumMap; use rtsim2::{ - data::{ - npc::NpcMode, - Data, - ReadError, - }, - rule::Rule, + data::{npc::NpcMode, Data, ReadError}, event::OnSetup, + rule::Rule, RtState, }; use specs::{DispatcherBuilder, WorldExt}; use std::{ + error::Error, fs::{self, File}, + io::{self, Write}, path::PathBuf, sync::Arc, time::Instant, - io::{self, Write}, - error::Error, }; -use enum_map::EnumMap; -use tracing::{error, warn, info, debug}; +use tracing::{debug, error, info, warn}; use vek::*; use world::{IndexRef, World}; @@ -41,7 +37,12 @@ pub struct RtSim { } impl RtSim { - pub fn new(settings: &WorldSettings, index: IndexRef, world: &World, data_dir: PathBuf) -> Result { + pub fn new( + settings: &WorldSettings, + index: IndexRef, + world: &World, + data_dir: PathBuf, + ) -> Result { let file_path = Self::get_file_path(data_dir); info!("Looking for rtsim data at {}...", file_path.display()); @@ -51,7 +52,10 @@ impl RtSim { Ok(file) => { info!("Rtsim data found. Attempting to load..."); match Data::from_reader(io::BufReader::new(file)) { - Ok(data) => { info!("Rtsim data loaded."); break 'load data }, + Ok(data) => { + info!("Rtsim data loaded."); + break 'load data; + }, Err(e) => { error!("Rtsim data failed to load: {}", e); let mut i = 0; @@ -64,7 +68,10 @@ impl RtSim { }); if !backup_path.exists() { fs::rename(&file_path, &backup_path)?; - warn!("Failed rtsim data was moved to {}", backup_path.display()); + warn!( + "Failed rtsim data was moved to {}", + backup_path.display() + ); info!("A fresh rtsim data will now be generated."); break; } @@ -73,12 +80,16 @@ impl RtSim { }, } }, - Err(e) if e.kind() == io::ErrorKind::NotFound => - info!("No rtsim data found. Generating from world..."), + Err(e) if e.kind() == io::ErrorKind::NotFound => { + info!("No rtsim data found. Generating from world...") + }, Err(e) => return Err(e.into()), } } else { - warn!("'RTSIM_NOLOAD' is set, skipping loading of rtsim state (old state will be overwritten)."); + warn!( + "'RTSIM_NOLOAD' is set, skipping loading of rtsim state (old state will be \ + overwritten)." + ); } let data = Data::generate(settings, &world, index); @@ -88,8 +99,10 @@ impl RtSim { let mut this = Self { last_saved: None, - state: RtState::new(data) - .with_resource(ChunkStates(Grid::populate_from(world.sim().get_size().as_(), |_| None))), + state: RtState::new(data).with_resource(ChunkStates(Grid::populate_from( + world.sim().get_size().as_(), + |_| None, + ))), file_path, }; @@ -123,8 +136,16 @@ impl RtSim { } } - pub fn hook_block_update(&mut self, world: &World, index: IndexRef, wpos: Vec3, old: Block, new: Block) { - self.state.emit(event::OnBlockChange { wpos, old, new }, world, index); + pub fn hook_block_update( + &mut self, + world: &World, + index: IndexRef, + wpos: Vec3, + old: Block, + new: Block, + ) { + self.state + .emit(event::OnBlockChange { wpos, old, new }, world, index); } pub fn hook_rtsim_entity_unload(&mut self, entity: RtSimEntity) { @@ -155,10 +176,8 @@ impl RtSim { Ok(dir.join(tmp_file_name)) }) .unwrap_or_else(|| Ok(tmp_file_name.into())) - .and_then(|tmp_file_path| { - Ok((File::create(&tmp_file_path)?, tmp_file_path)) - }) - .map_err(|e: io::Error| Box::new(e) as Box::) + .and_then(|tmp_file_path| Ok((File::create(&tmp_file_path)?, tmp_file_path))) + .map_err(|e: io::Error| Box::new(e) as Box) .and_then(|(mut file, tmp_file_path)| { debug!("Writing rtsim data to file..."); data.write_to(io::BufWriter::new(&mut file))?; @@ -180,9 +199,7 @@ impl RtSim { self.state.data().nature.get_chunk_resources(key) } - pub fn state(&self) -> &RtState { - &self.state - } + pub fn state(&self) -> &RtState { &self.state } } struct ChunkStates(pub Grid>); diff --git a/server/src/rtsim2/rule.rs b/server/src/rtsim2/rule.rs index 2f349b5368..9b73ea9165 100644 --- a/server/src/rtsim2/rule.rs +++ b/server/src/rtsim2/rule.rs @@ -1,7 +1,7 @@ pub mod deplete_resources; -use tracing::info; use rtsim2::RtState; +use tracing::info; pub fn start_rules(rtstate: &mut RtState) { info!("Starting server rtsim rules..."); diff --git a/server/src/rtsim2/rule/deplete_resources.rs b/server/src/rtsim2/rule/deplete_resources.rs index 1041576977..05bfe43789 100644 --- a/server/src/rtsim2/rule/deplete_resources.rs +++ b/server/src/rtsim2/rule/deplete_resources.rs @@ -1,13 +1,7 @@ -use tracing::info; +use crate::rtsim2::{event::OnBlockChange, ChunkStates}; +use common::{terrain::TerrainChunk, vol::RectRasterableVol}; use rtsim2::{RtState, Rule, RuleError}; -use crate::rtsim2::{ - event::OnBlockChange, - ChunkStates, -}; -use common::{ - terrain::TerrainChunk, - vol::RectRasterableVol, -}; +use tracing::info; pub struct DepleteResources; @@ -16,7 +10,9 @@ impl Rule for DepleteResources { info!("Hello from the resource depletion rule!"); rtstate.bind::(|ctx| { - let key = ctx.event.wpos + let key = ctx + .event + .wpos .xy() .map2(TerrainChunk::RECT_SIZE, |e, sz| e.div_euclid(sz as i32)); if let Some(Some(chunk_state)) = ctx.state.resource_mut::().0.get(key) { @@ -26,7 +22,8 @@ impl Rule for DepleteResources { if chunk_state.max_res[res] > 0 { chunk_res[res] = (chunk_res[res] * chunk_state.max_res[res] as f32 - 1.0) .round() - .max(0.0) / chunk_state.max_res[res] as f32; + .max(0.0) + / chunk_state.max_res[res] as f32; } } // Add resources @@ -34,11 +31,15 @@ impl Rule for DepleteResources { if chunk_state.max_res[res] > 0 { chunk_res[res] = (chunk_res[res] * chunk_state.max_res[res] as f32 + 1.0) .round() - .max(0.0) / chunk_state.max_res[res] as f32; + .max(0.0) + / chunk_state.max_res[res] as f32; } } println!("Chunk resources = {:?}", chunk_res); - ctx.state.data_mut().nature.set_chunk_resources(key, chunk_res); + ctx.state + .data_mut() + .nature + .set_chunk_resources(key, chunk_res); } }); diff --git a/server/src/rtsim2/tick.rs b/server/src/rtsim2/tick.rs index bc62d60cc5..bc794b7722 100644 --- a/server/src/rtsim2/tick.rs +++ b/server/src/rtsim2/tick.rs @@ -100,7 +100,11 @@ fn profession_extra_loadout( fn profession_agent_mark(profession: Option<&Profession>) -> Option { match profession { Some( - Profession::Merchant | Profession::Farmer | Profession::Chef | Profession::Blacksmith | Profession::Alchemist, + Profession::Merchant + | Profession::Farmer + | Profession::Chef + | Profession::Blacksmith + | Profession::Alchemist, ) => Some(comp::agent::Mark::Merchant), Some(Profession::Guard) => Some(comp::agent::Mark::Guard), _ => None, diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index 626499341f..b58167357e 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -5,9 +5,9 @@ use crate::{ persistence::PersistedComponents, pet::restore_pet, presence::{Presence, RepositionOnChunkLoad}, + rtsim2::RtSim, settings::Settings, sys::sentinel::DeletedEntities, - rtsim2::RtSim, wiring, BattleModeBuffer, SpawnPoint, }; use common::{ diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index 3714e564a8..bcea774b24 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -1,12 +1,9 @@ pub mod behavior_tree; pub use server_agent::{action_nodes, attack, consts, data, util}; -use crate::{ - // rtsim::{entity::PersonalityTrait, RtSim}, - sys::agent::{ +use crate::sys::agent::{ behavior_tree::{BehaviorData, BehaviorTree}, data::{AgentData, ReadData}, - }, }; use common::{ comp::{ diff --git a/server/src/sys/agent/data.rs b/server/src/sys/agent/data.rs index 2d1e816128..0b13b2524d 100644 --- a/server/src/sys/agent/data.rs +++ b/server/src/sys/agent/data.rs @@ -9,8 +9,9 @@ use common::{ mounting::Mount, path::TraversalConfig, resources::{DeltaTime, Time, TimeOfDay}, + rtsim::RtSimEntity, terrain::TerrainGrid, - uid::{Uid, UidAllocator}, rtsim::RtSimEntity, + uid::{Uid, UidAllocator}, }; use specs::{ shred::ResourceId, Entities, Entity as EcsEntity, Read, ReadExpect, ReadStorage, SystemData, @@ -154,7 +155,6 @@ pub struct ReadData<'a> { #[cfg(feature = "worldgen")] pub world: ReadExpect<'a, Arc>, pub rtsim_entity: ReadStorage<'a, RtSimEntity>, - //pub rtsim_entities: ReadStorage<'a, RtSimEntity>, pub buffs: ReadStorage<'a, Buffs>, pub combos: ReadStorage<'a, Combo>, pub active_abilities: ReadStorage<'a, ActiveAbilities>, diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index 26a75bd309..cfbea304fe 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -149,9 +149,10 @@ impl PlayState for MainMenuState { ) .into_owned(), server::Error::RtsimError(e) => localized_strings - .get("main.servers.rtsim_error") - .to_owned() - .replace("{raw_error}", e.to_string().as_str()), + .get_msg_ctx("main-servers-rtsim_error", &i18n::fluent_args! { + "raw_error" => e.to_string(), + }) + .into_owned(), server::Error::Other(e) => localized_strings .get_msg_ctx("main-servers-other_error", &i18n::fluent_args! { "raw_error" => e, diff --git a/voxygen/src/scene/debug.rs b/voxygen/src/scene/debug.rs index 3ab11ba0d5..bfb94015bb 100644 --- a/voxygen/src/scene/debug.rs +++ b/voxygen/src/scene/debug.rs @@ -293,9 +293,7 @@ impl Debug { id } - pub fn get_shape(&self, id: DebugShapeId) -> Option<&DebugShape> { - self.shapes.get(&id) - } + pub fn get_shape(&self, id: DebugShapeId) -> Option<&DebugShape> { self.shapes.get(&id) } pub fn set_context(&mut self, id: DebugShapeId, pos: [f32; 4], color: [f32; 4], ori: [f32; 4]) { self.pending_locals.insert(id, (pos, color, ori)); diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index d1d71dafb9..7d2bb1cb49 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -776,7 +776,8 @@ impl FigureMgr { .enumerate() { // Velocity relative to the current ground - let rel_vel = anim::vek::Vec3::::from(vel.0 - physics.ground_vel) / scale.map_or(1.0, |s| s.0); + let rel_vel = anim::vek::Vec3::::from(vel.0 - physics.ground_vel) + / scale.map_or(1.0, |s| s.0); let look_dir = controller.map(|c| c.inputs.look_dir).unwrap_or_default(); let is_viewpoint = scene_data.viewpoint_entity == entity; @@ -809,8 +810,9 @@ impl FigureMgr { const MIN_PERFECT_RATE_DIST: f32 = 100.0; if (i as u64 + tick) - % ((((pos.0.distance_squared(focus_pos) / scale.map_or(1.0, |s| s.0)).powf(0.25) - MIN_PERFECT_RATE_DIST.sqrt()) - .max(0.0) + % ((((pos.0.distance_squared(focus_pos) / scale.map_or(1.0, |s| s.0)).powf(0.25) + - MIN_PERFECT_RATE_DIST.sqrt()) + .max(0.0) / 3.0) as u64) .saturating_add(1) != 0 @@ -6707,8 +6709,10 @@ impl FigureMgr { } { let model_entry = model_entry?; - let figure_low_detail_distance = figure_lod_render_distance * scale.map_or(1.0, |s| s.0) * 0.75; - let figure_mid_detail_distance = figure_lod_render_distance * scale.map_or(1.0, |s| s.0) * 0.5; + let figure_low_detail_distance = + figure_lod_render_distance * scale.map_or(1.0, |s| s.0) * 0.75; + let figure_mid_detail_distance = + figure_lod_render_distance * scale.map_or(1.0, |s| s.0) * 0.5; let model = if pos.distance_squared(cam_pos) > figure_low_detail_distance.powi(2) { model_entry.lod_model(2) diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 08cccdf9bb..08c031a542 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -409,7 +409,10 @@ impl Scene { // when zooming in the distance the camera travelles should be based on the // final distance. This is to make sure the camera travelles the // same distance when zooming in and out - let player_scale = client.state().read_component_copied::(client.entity()).map_or(1.0, |s| s.0); + let player_scale = client + .state() + .read_component_copied::(client.entity()) + .map_or(1.0, |s| s.0); if delta < 0.0 { self.camera.zoom_switch( // Thank you Imbris for doing the math @@ -418,7 +421,11 @@ impl Scene { player_scale, ); } else { - self.camera.zoom_switch(delta * (0.05 + self.camera.get_distance() * 0.01), cap, player_scale); + self.camera.zoom_switch( + delta * (0.05 + self.camera.get_distance() * 0.01), + cap, + player_scale, + ); } true }, @@ -1477,15 +1484,19 @@ impl Scene { // If this shape no longer matches, remove the old one if let Some(shape_id) = hitboxes.get(&entity) { - if self.debug.get_shape(*shape_id).map_or(false, |s| s != &shape) { + if self + .debug + .get_shape(*shape_id) + .map_or(false, |s| s != &shape) + { self.debug.remove_shape(*shape_id); hitboxes.remove(&entity); } } - let shape_id = hitboxes.entry(entity).or_insert_with(|| { - self.debug.add_shape(shape) - }); + let shape_id = hitboxes + .entry(entity) + .or_insert_with(|| self.debug.add_shape(shape)); let hb_pos = [pos.0.x, pos.0.y, pos.0.z + *z_min * scale, 0.0]; let color = if group == Some(&comp::group::ENEMY) { [1.0, 0.0, 0.0, 0.5] diff --git a/world/src/civ/mod.rs b/world/src/civ/mod.rs index eeb7fe5b09..c456da2f17 100644 --- a/world/src/civ/mod.rs +++ b/world/src/civ/mod.rs @@ -628,12 +628,17 @@ impl Civs { } } - /// Return the direct track between two places, bool if the track should be reversed or not + /// Return the direct track between two places, bool if the track should be + /// reversed or not pub fn track_between(&self, a: Id, b: Id) -> Option<(Id, bool)> { self.track_map .get(&a) .and_then(|dests| Some((*dests.get(&b)?, false))) - .or_else(|| self.track_map.get(&b).and_then(|dests| Some((*dests.get(&a)?, true)))) + .or_else(|| { + self.track_map + .get(&b) + .and_then(|dests| Some((*dests.get(&a)?, true))) + }) } /// Return an iterator over a site's neighbors @@ -663,8 +668,9 @@ impl Civs { .sqrt() }; let neighbors = |p: &Id| self.neighbors(*p); - let transition = - |a: &Id, b: &Id| self.tracks.get(self.track_between(*a, *b).unwrap().0).cost; + let transition = |a: &Id, b: &Id| { + self.tracks.get(self.track_between(*a, *b).unwrap().0).cost + }; let satisfied = |p: &Id| *p == b; // We use this hasher (FxHasher64) because // (1) we don't care about DDOS attacks (ruling out SipHash); diff --git a/world/src/lib.rs b/world/src/lib.rs index 76c4b7c55d..b50ff1d250 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -49,11 +49,11 @@ use common::{ generation::{ChunkSupplement, EntityInfo}, lod, resources::TimeOfDay, + rtsim::ChunkResource, terrain::{ Block, BlockKind, SpriteKind, TerrainChunk, TerrainChunkMeta, TerrainChunkSize, TerrainGrid, }, vol::{ReadVol, RectVolSize, WriteVol}, - rtsim::ChunkResource, }; use common_net::msg::{world_msg, WorldMapMsg}; use enum_map::EnumMap; @@ -492,17 +492,19 @@ impl World { // Finally, defragment to minimize space consumption. chunk.defragment(); - // Before we finish, we check candidate rtsim resource blocks, deduplicating positions and only keeping those - // that actually do have resources. Although this looks potentially very expensive, only blocks that are rtsim + // Before we finish, we check candidate rtsim resource blocks, deduplicating + // positions and only keeping those that actually do have resources. + // Although this looks potentially very expensive, only blocks that are rtsim // resources (i.e: a relatively small number of sprites) are processed here. if let Some(rtsim_resources) = rtsim_resources { rtsim_resource_blocks.sort_unstable_by_key(|pos| pos.into_array()); rtsim_resource_blocks.dedup(); for wpos in rtsim_resource_blocks { - chunk.map( - wpos - chunk_wpos2d.with_z(0), - |block| if let Some(res) = block.get_rtsim_resource() { - // Note: this represents the upper limit, not the actual number spanwed, so we increment this before deciding whether we're going to spawn the resource. + chunk.map(wpos - chunk_wpos2d.with_z(0), |block| { + if let Some(res) = block.get_rtsim_resource() { + // Note: this represents the upper limit, not the actual number spanwed, so + // we increment this before deciding whether we're going to spawn the + // resource. supplement.rtsim_max_resources[res] += 1; // Throw a dice to determine whether this resource should actually spawn // TODO: Don't throw a dice, try to generate the *exact* correct number @@ -513,12 +515,11 @@ impl World { } } else { block - }, - ); + } + }); } } - Ok((chunk, supplement)) } diff --git a/world/src/site/settlement/mod.rs b/world/src/site/settlement/mod.rs index c77e8e24b2..1c2b16178f 100644 --- a/world/src/site/settlement/mod.rs +++ b/world/src/site/settlement/mod.rs @@ -1012,8 +1012,11 @@ pub fn merchant_loadout( loadout_builder: LoadoutBuilder, economy: Option<&SiteInformation>, ) -> LoadoutBuilder { - trader_loadout(loadout_builder - .with_asset_expect("common.loadout.village.merchant", &mut thread_rng()), economy, |_| true) + trader_loadout( + loadout_builder.with_asset_expect("common.loadout.village.merchant", &mut thread_rng()), + economy, + |_| true, + ) } pub fn trader_loadout( @@ -1030,10 +1033,13 @@ pub fn trader_loadout( let mut bag4 = Item::new_from_asset_expect("common.items.armor.misc.bag.sturdy_red_backpack"); let slots = backpack.slots().len() + 4 * bag1.slots().len(); let mut stockmap: HashMap = economy - .map(|e| e.unconsumed_stock.clone() - .into_iter() - .filter(|(good, _)| permitted(*good)) - .collect()) + .map(|e| { + e.unconsumed_stock + .clone() + .into_iter() + .filter(|(good, _)| permitted(*good)) + .collect() + }) .unwrap_or_default(); // modify stock for better gameplay diff --git a/world/src/site2/mod.rs b/world/src/site2/mod.rs index 8b46849d7d..9da82b9d44 100644 --- a/world/src/site2/mod.rs +++ b/world/src/site2/mod.rs @@ -7,7 +7,8 @@ use self::tile::{HazardKind, KeepKind, RoofKind, Tile, TileGrid, TILE_SIZE}; pub use self::{ gen::{aabr_with_z, Fill, Painter, Primitive, PrimitiveRef, Structure}, plot::{Plot, PlotKind}, - util::Dir, tile::TileKind, + tile::TileKind, + util::Dir, }; use crate::{ sim::Path,