diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index a9f077eea6..5bbd3d61db 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -1,8 +1,8 @@ use crate::{ comp::{humanoid, quadruped_low, quadruped_medium, quadruped_small, Body}, path::Chaser, - sync::Uid, rtsim::RtSimController, + sync::Uid, }; use specs::{Component, Entity as EcsEntity}; use specs_idvs::IdvStorage; diff --git a/common/src/event.rs b/common/src/event.rs index a47e9950ee..d53df9d410 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -1,11 +1,4 @@ -use crate::{ - character::CharacterId, - sync::Uid, - util::Dir, - comp, - Explosion, - rtsim::RtSimEntity, -}; +use crate::{character::CharacterId, comp, rtsim::RtSimEntity, sync::Uid, util::Dir, Explosion}; use comp::{ item::{Item, Reagent}, Ori, Pos, diff --git a/common/src/generation.rs b/common/src/generation.rs index 6c07d5cfe1..f040ec18ca 100644 --- a/common/src/generation.rs +++ b/common/src/generation.rs @@ -1,7 +1,7 @@ use crate::{ comp::{self, humanoid, Alignment, Body, Item}, - npc::{self, NPC_NAMES}, loadout_builder::LoadoutConfig, + npc::{self, NPC_NAMES}, }; use vek::*; diff --git a/common/src/loadout_builder.rs b/common/src/loadout_builder.rs index 302232df16..6f3687c48b 100644 --- a/common/src/loadout_builder.rs +++ b/common/src/loadout_builder.rs @@ -88,7 +88,7 @@ impl LoadoutBuilder { #[allow(clippy::single_match)] pub fn build_loadout( body: Body, - alignment: Alignment, + _alignment: Alignment, mut main_tool: Option, is_giant: bool, map: &AbilityMap, @@ -410,13 +410,11 @@ impl LoadoutBuilder { back: None, ring: None, neck: None, - lantern: Some(Item::new_from_asset_expect( - "common.items.lantern.black_0", - )), + lantern: Some(Item::new_from_asset_expect("common.items.lantern.black_0")), glider: None, head: None, tabard: None, - } + }, } } else { match body { diff --git a/common/src/path.rs b/common/src/path.rs index 54a7c2ef64..67de327692 100644 --- a/common/src/path.rs +++ b/common/src/path.rs @@ -130,7 +130,8 @@ impl Route { // Determine whether we're close enough to the next to to consider it completed let dist_sqrd = pos.xy().distance_squared(closest_tgt.xy()); - if dist_sqrd < traversal_cfg.node_tolerance.powf(2.0) * if be_precise { 0.25 } else { 1.0 } + if dist_sqrd + < traversal_cfg.node_tolerance.powf(2.0) * if be_precise { 0.25 } else { 1.0 } && (((pos.z - closest_tgt.z > 1.2 || (pos.z - closest_tgt.z > -0.2 && traversal_cfg.on_ground)) && (pos.z - closest_tgt.z < 1.2 || (pos.z - closest_tgt.z < 2.9 && vel.z < -0.05)) && vel.z <= 0.0 @@ -142,7 +143,9 @@ impl Route { .0 > pos.distance(closest_tgt) * 0.9 || dist_sqrd < 0.5) && self.next_idx < self.path.len()) - || (traversal_cfg.in_liquid && pos.z < closest_tgt.z + 0.8 && pos.z > closest_tgt.z)) + || (traversal_cfg.in_liquid + && pos.z < closest_tgt.z + 0.8 + && pos.z > closest_tgt.z)) { // Node completed, move on to the next one self.next_idx += 1; @@ -438,15 +441,14 @@ fn walkable(vol: &V, pos: Vec3) -> bool where V: BaseVol + ReadVol, { - let below = vol.get(pos - Vec3::unit_z()) + let below = vol + .get(pos - Vec3::unit_z()) .ok() .copied() .unwrap_or_else(Block::empty); - let a = vol.get(pos) - .ok() - .copied() - .unwrap_or_else(Block::empty); - let b = vol.get(pos + Vec3::unit_z()) + let a = vol.get(pos).ok().copied().unwrap_or_else(Block::empty); + let b = vol + .get(pos + Vec3::unit_z()) .ok() .copied() .unwrap_or_else(Block::empty); @@ -513,10 +515,10 @@ where ]; const JUMPS: [Vec3; 4] = [ - Vec3::new(0, 1, 2), // Forward Upwardx2 - Vec3::new(1, 0, 2), // Right Upwardx2 - Vec3::new(0, -1, 2), // Backward Upwardx2 - Vec3::new(-1, 0, 2), // Left Upwardx2 + Vec3::new(0, 1, 2), // Forward Upwardx2 + Vec3::new(1, 0, 2), // Right Upwardx2 + Vec3::new(0, -1, 2), // Backward Upwardx2 + Vec3::new(-1, 0, 2), // Left Upwardx2 ]; // let walkable = [ @@ -538,13 +540,15 @@ where // ]; DIRS.iter() - .chain(Some(JUMPS.iter()) - .filter(|_| vol - .get(pos) - .map(|b| !b.is_liquid()) - .unwrap_or(true) || traversal_cfg.can_climb) - .into_iter() - .flatten()) + .chain( + Some(JUMPS.iter()) + .filter(|_| { + vol.get(pos).map(|b| !b.is_liquid()).unwrap_or(true) + || traversal_cfg.can_climb + }) + .into_iter() + .flatten(), + ) .map(move |dir| (pos, dir)) .filter(move |(pos, dir)| { is_walkable(pos) diff --git a/common/src/rtsim.rs b/common/src/rtsim.rs index 2b693e5590..065f8a343e 100644 --- a/common/src/rtsim.rs +++ b/common/src/rtsim.rs @@ -3,8 +3,8 @@ // `Agent`). When possible, this should be moved to the `rtsim` // module in `server`. -use specs_idvs::IdvStorage; use specs::Component; +use specs_idvs::IdvStorage; use vek::*; pub type RtSimId = usize; @@ -16,20 +16,20 @@ impl Component for RtSimEntity { type Storage = IdvStorage; } -/// This type is the map route through which the rtsim (real-time simulation) aspect -/// of the game communicates with the rest of the game. It is analagous to -/// `comp::Controller` in that it provides a consistent interface for simulation NPCs -/// to control their actions. Unlike `comp::Controller`, it is very abstract and is -/// intended for consumption by both the agent code and the internal rtsim simulation -/// code (depending on whether the entity is loaded into the game as a physical entity -/// or not). Agent code should attempt to act upon its instructions where reasonable -/// although deviations for various reasons (obstacle avoidance, counter-attacking, -/// etc.) are expected. +/// This type is the map route through which the rtsim (real-time simulation) +/// aspect of the game communicates with the rest of the game. It is analagous +/// to `comp::Controller` in that it provides a consistent interface for +/// simulation NPCs to control their actions. Unlike `comp::Controller`, it is +/// very abstract and is intended for consumption by both the agent code and the +/// internal rtsim simulation code (depending on whether the entity is loaded +/// into the game as a physical entity or not). Agent code should attempt to act +/// upon its instructions where reasonable although deviations for various +/// reasons (obstacle avoidance, counter-attacking, etc.) are expected. #[derive(Clone, Debug)] pub struct RtSimController { /// When this field is `Some(..)`, the agent should attempt to make progress - /// toward the given location, accounting for obstacles and other high-priority - /// situations like being attacked. + /// toward the given location, accounting for obstacles and other + /// high-priority situations like being attacked. pub travel_to: Option>, /// Proportion of full speed to move pub speed_factor: f32, @@ -45,7 +45,5 @@ impl Default for RtSimController { } impl RtSimController { - pub fn reset(&mut self) { - *self = Self::default(); - } + pub fn reset(&mut self) { *self = Self::default(); } } diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index c57c1ce883..f13c205582 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -5,7 +5,10 @@ use crate::{ }, event::LocalEvent, states::*, - sys::{character_behavior::JoinData, phys::{GRAVITY, FRIC_GROUND}}, + sys::{ + character_behavior::JoinData, + phys::{FRIC_GROUND, GRAVITY}, + }, util::Dir, }; use serde::{Deserialize, Serialize}; @@ -95,6 +98,7 @@ impl Body { } } + #[allow(clippy::match_like_matches_macro)] pub fn can_climb(&self) -> bool { match self { Body::Humanoid(_) => true, diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index ff885fae35..2870852163 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -223,24 +223,18 @@ impl<'a> System<'a> for Sys { match &mut agent.activity { Activity::Idle { bearing, chaser } => { if let Some(travel_to) = agent.rtsim_controller.travel_to { - if let Some((bearing, speed)) = chaser.chase( - &*terrain, - pos.0, - vel.0, - travel_to, - TraversalConfig { + if let Some((bearing, speed)) = + chaser.chase(&*terrain, pos.0, vel.0, travel_to, TraversalConfig { min_tgt_dist: 1.25, ..traversal_config - }, - ) { - inputs.move_dir = bearing - .xy() - .try_normalized() - .unwrap_or(Vec2::zero()) - * speed.min(agent.rtsim_controller.speed_factor); + }) + { + inputs.move_dir = + bearing.xy().try_normalized().unwrap_or(Vec2::zero()) + * speed.min(agent.rtsim_controller.speed_factor); inputs.jump.set_state(bearing.z > 1.5); inputs.climb = Some(comp::Climb::Up); - //.filter(|_| bearing.z > 0.1 || physics_state.in_liquid.is_some()); + //.filter(|_| bearing.z > 0.1 || physics_state.in_liquid.is_some()); inputs.move_z = bearing.z + 0.05; } } else { diff --git a/common/src/terrain/mod.rs b/common/src/terrain/mod.rs index 4740d88312..74591cd049 100644 --- a/common/src/terrain/mod.rs +++ b/common/src/terrain/mod.rs @@ -19,7 +19,7 @@ use roots::find_roots_cubic; use serde::{Deserialize, Serialize}; use crate::{ - vol::{RectVolSize, ReadVol}, + vol::{ReadVol, RectVolSize}, volumes::vol_grid_2d::VolGrid2d, }; use vek::*; diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 10d6cb6e45..ae310aba21 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -437,14 +437,15 @@ fn handle_time( // Accept `u12345`, seconds since midnight day 0 Err(_) => match n .get(1..) - .filter(|_| n.chars().next() == Some('u')) - .and_then(|n| n.trim_left_matches('u').parse::().ok()) + .filter(|_| n.starts_with('u')) + .and_then(|n| n.trim_start_matches('u').parse::().ok()) { Some(n) => n as f64, None => { server.notify_client( client, - ChatType::CommandError.server_msg(format!("'{}' is not a valid time.", n)), + ChatType::CommandError + .server_msg(format!("'{}' is not a valid time.", n)), ); return; }, @@ -454,9 +455,49 @@ fn handle_time( None => { let time_in_seconds = server.state.ecs_mut().read_resource::().0; + // Would this ever change? Perhaps in a few hundred thousand years some + // game archeologists of the future will resurrect the best game of all + // time which, obviously, would be Veloren. By that time, the inescapable + // laws of thermodynamics will mean that the earth's rotation period + // would be slower. Of course, a few hundred thousand years is enough + // for the circadian rhythm of human biology to have shifted to account + // accordingly. When booting up Veloren for the first time in 337,241 + // years, they might feel a touch of anguish at the fact that their + // earth days and the days within the game do not neatly divide into + // one-another. Understandably, they'll want to change this. Who + // wouldn't? It would be like turning the TV volume up to an odd number + // or having a slightly untuned radio (assuming they haven't begun + // broadcasting information directly into their brains). Totally + // unacceptable. No, the correct and proper thing to do would be to + // release a retroactive definitive edition DLC for $99 with the very + // welcome addition of shorter day periods and a complementary + // 'developer commentary' mode created by digging up the long-decayed + // skeletons of the Veloren team, measuring various attributes of their + // jawlines, and using them to recreate their voices. But how to go about + // this Herculean task? This code is jibberish! The last of the core Rust + // dev team died exactly 337,194 years ago! Rust is now a long-forgotten + // dialect of the ancient ones, lost to the sands of time. Ashes to ashes, + // dust to dust. When all hope is lost, one particularly intrepid + // post-human hominid exployed by the 'Veloren Revival Corp' (no doubt we + // still won't have gotted rid of this blasted 'capitalism' thing by then) + // might notice, after years of searching, a particularly curious + // inscription within the code. The letters `D`, `A`, `Y`. Curious! She + // consults the post-human hominid scholars of the old. Care to empathise + // with her shock when she discovers that these symbols, as alien as they + // may seem, correspond exactly to the word `ⓕя𝐢ᵇᵇ𝔩E`, the word for + // 'day' in the post-human hominid language, which is of course universal. + // Imagine also her surprise when, after much further translating, she + // finds a comment predicting her very existence and her struggle to + // decode this great mystery. Rejoyce! The Veloren Revival Corp. may now + // persist with their great Ultimate Edition DLC because the day period + // might now be changed because they have found the constant that controls + // it! Everybody was henceforth happy until the end of time. + // + // This one's for you, xMac ;) + const DAY: u64 = 86400; let current_time = NaiveTime::from_num_seconds_from_midnight_opt( // Wraps around back to 0s if it exceeds 24 hours (24 hours = 86400s) - (time_in_seconds as u64 % 86400) as u32, + (time_in_seconds as u64 % DAY) as u32, 0, ); let msg = match current_time { @@ -470,14 +511,14 @@ fn handle_time( server.state.ecs_mut().write_resource::().0 = new_time; - if let Some(new_time) = NaiveTime::from_num_seconds_from_midnight_opt(((new_time as u64) % 86400) as u32, 0) { + if let Some(new_time) = + NaiveTime::from_num_seconds_from_midnight_opt(((new_time as u64) % 86400) as u32, 0) + { server.notify_client( client, ChatType::CommandInfo.server_msg(format!( "Time changed to: {}", - new_time - .format("%H:%M") - .to_string(), + new_time.format("%H:%M").to_string(), )), ); } diff --git a/server/src/events/entity_creation.rs b/server/src/events/entity_creation.rs index b02ca5629b..5f3a3161a4 100644 --- a/server/src/events/entity_creation.rs +++ b/server/src/events/entity_creation.rs @@ -6,8 +6,8 @@ use common::{ LightEmitter, Loadout, Ori, Pos, Projectile, Scale, Stats, Vel, WaypointArea, }, outcome::Outcome, - util::Dir, rtsim::RtSimEntity, + util::Dir, }; use comp::group; use specs::{Builder, Entity as EcsEntity, WorldExt}; diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 8cece81a0c..2dfdf20f3f 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -1,8 +1,8 @@ use crate::{ client::Client, comp::{biped_large, quadruped_medium, quadruped_small, PhysicsState}, - Server, SpawnPoint, StateExt, rtsim::RtSim, + Server, SpawnPoint, StateExt, }; use common::{ assets::Asset, @@ -16,12 +16,12 @@ use common::{ lottery::Lottery, msg::{PlayerListUpdate, ServerGeneral}, outcome::Outcome, + rtsim::RtSimEntity, state::BlockChange, sync::{Uid, UidAllocator, WorldSyncExt}, terrain::{Block, TerrainGrid}, vol::ReadVol, Damage, DamageSource, Explosion, GroupTarget, RadiusEffect, - rtsim::RtSimEntity, }; use comp::item::Reagent; use rand::prelude::*; @@ -462,8 +462,16 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc }; if should_delete { - if let Some(rtsim_entity) = state.ecs().read_storage::().get(entity).copied() { - state.ecs().write_resource::().destroy_entity(rtsim_entity.0); + if let Some(rtsim_entity) = state + .ecs() + .read_storage::() + .get(entity) + .copied() + { + state + .ecs() + .write_resource::() + .destroy_entity(rtsim_entity.0); } let _ = state diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index e4ea598457..0b12d9560a 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -8,8 +8,8 @@ use entity_creation::{ handle_loaded_character_data, handle_shockwave, handle_shoot, }; use entity_manipulation::{ - handle_buff, handle_damage, handle_destroy, handle_delete, handle_energy_change, handle_explosion, - handle_knockback, handle_land_on_ground, handle_level_up, handle_respawn, + handle_buff, handle_damage, handle_delete, handle_destroy, handle_energy_change, + handle_explosion, handle_knockback, handle_land_on_ground, handle_level_up, handle_respawn, }; use group_manip::handle_group; use interaction::{handle_lantern, handle_mount, handle_possess, handle_unmount}; @@ -120,8 +120,18 @@ impl Server { drop_item, rtsim_entity, } => handle_create_npc( - self, pos, stats, health, loadout, body, agent, alignment, scale, drop_item, - home_chunk, rtsim_entity, + self, + pos, + stats, + health, + loadout, + body, + agent, + alignment, + scale, + drop_item, + home_chunk, + rtsim_entity, ), ServerEvent::CreateWaypoint(pos) => handle_create_waypoint(self, pos), ServerEvent::ClientDisconnect(entity) => { diff --git a/server/src/lib.rs b/server/src/lib.rs index 0fc9f01b13..98229b18c1 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -52,9 +52,7 @@ use common::{ comp::{self, ChatType}, event::{EventBus, ServerEvent}, msg::{ - world_msg::{SiteInfo, SiteKind}, - ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerInit, ServerMsg, - WorldMapMsg, + ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerInit, ServerMsg, WorldMapMsg, }, outcome::Outcome, recipe::default_recipe_book, @@ -62,7 +60,7 @@ use common::{ state::{State, TimeOfDay}, sync::WorldSyncExt, terrain::TerrainChunkSize, - vol::{ReadVol, RectVolSize}, + vol::RectVolSize, }; use futures_executor::block_on; use metrics::{PhysicsMetrics, ServerMetrics, StateTickMetrics, TickMetrics}; @@ -327,7 +325,7 @@ impl Server { // Insert the world into the ECS (todo: Maybe not an Arc?) let world = Arc::new(world); - state.ecs_mut().insert(world.clone()); + state.ecs_mut().insert(Arc::clone(&world)); state.ecs_mut().insert(index.clone()); // Set starting time for the server. diff --git a/server/src/rtsim/chunks.rs b/server/src/rtsim/chunks.rs index 93685f59a0..481c8cab71 100644 --- a/server/src/rtsim/chunks.rs +++ b/server/src/rtsim/chunks.rs @@ -10,9 +10,7 @@ pub struct Chunks { impl Chunks { pub fn new(size: Vec2) -> Self { Chunks { - chunks: Grid::populate_from(size.map(|e| e as i32), |_| Chunk { - is_loaded: false, - }), + chunks: Grid::populate_from(size.map(|e| e as i32), |_| Chunk { is_loaded: false }), chunks_to_load: Vec::new(), chunks_to_unload: Vec::new(), } @@ -25,7 +23,9 @@ impl Chunks { pub fn chunk_mut(&mut self, key: Vec2) -> Option<&mut Chunk> { self.chunks.get_mut(key) } pub fn chunk_at(&self, pos: Vec2) -> Option<&Chunk> { - self.chunks.get(pos.map2(TerrainChunk::RECT_SIZE, |e, sz| (e.floor() as i32).div_euclid(sz as i32))) + self.chunks.get(pos.map2(TerrainChunk::RECT_SIZE, |e, sz| { + (e.floor() as i32).div_euclid(sz as i32) + })) } } diff --git a/server/src/rtsim/load_chunks.rs b/server/src/rtsim/load_chunks.rs index 8c71d67116..756b4c3f79 100644 --- a/server/src/rtsim/load_chunks.rs +++ b/server/src/rtsim/load_chunks.rs @@ -1,16 +1,14 @@ use super::*; use common::event::{EventBus, ServerEvent}; -use specs::{Join, Read, ReadStorage, System, Write, WriteExpect}; +use specs::{Read, System, WriteExpect}; pub struct Sys; impl<'a> System<'a> for Sys { - type SystemData = ( - Read<'a, EventBus>, - WriteExpect<'a, RtSim>, - ); + #[allow(clippy::type_complexity)] + type SystemData = (Read<'a, EventBus>, WriteExpect<'a, RtSim>); - fn run(&mut self, (server_event_bus, mut rtsim): Self::SystemData) { - for chunk in std::mem::take(&mut rtsim.chunks.chunks_to_load) { + fn run(&mut self, (_server_event_bus, mut rtsim): Self::SystemData) { + for _chunk in std::mem::take(&mut rtsim.chunks.chunks_to_load) { // TODO } } diff --git a/server/src/rtsim/mod.rs b/server/src/rtsim/mod.rs index 4a87f862a4..0e9665f99e 100644 --- a/server/src/rtsim/mod.rs +++ b/server/src/rtsim/mod.rs @@ -1,25 +1,23 @@ -mod load_chunks; -mod unload_chunks; -mod tick; -mod entity; -mod chunks; +#![allow(dead_code)] // TODO: Remove this when rtsim is fleshed out -use vek::*; +mod chunks; +mod entity; +mod load_chunks; +mod tick; +mod unload_chunks; + +use self::{chunks::Chunks, entity::Entity}; use common::{ + comp, + rtsim::{RtSimController, RtSimEntity, RtSimId}, state::State, terrain::TerrainChunk, - rtsim::{RtSimEntity, RtSimId, RtSimController}, vol::RectRasterableVol, - comp, }; -use specs::{DispatcherBuilder, WorldExt}; -use specs_idvs::IdvStorage; -use slab::Slab; use rand::prelude::*; -use self::{ - entity::Entity, - chunks::Chunks, -}; +use slab::Slab; +use specs::{DispatcherBuilder, WorldExt}; +use vek::*; pub struct RtSim { tick: u64, @@ -88,12 +86,14 @@ pub fn init(state: &mut State, world: &world::World) { let mut rtsim = RtSim::new(world.sim().get_size()); for _ in 0..2500 { - let pos = rtsim.chunks.size().map2( - TerrainChunk::RECT_SIZE, - |sz, chunk_sz| thread_rng().gen_range(0, sz * chunk_sz) as i32, - ); + let pos = rtsim + .chunks + .size() + .map2(TerrainChunk::RECT_SIZE, |sz, chunk_sz| { + thread_rng().gen_range(0, sz * chunk_sz) as i32 + }); - let id = rtsim.entities.insert(Entity { + rtsim.entities.insert(Entity { is_loaded: false, pos: Vec3::from(pos.map(|e| e as f32)), seed: thread_rng().gen(), @@ -101,8 +101,6 @@ pub fn init(state: &mut State, world: &world::World) { last_tick: 0, brain: Default::default(), }); - - // tracing::info!("Spawned rtsim NPC {} at {:?}", id, pos); } state.ecs_mut().insert(rtsim); diff --git a/server/src/rtsim/tick.rs b/server/src/rtsim/tick.rs index c126104a37..5a830de70c 100644 --- a/server/src/rtsim/tick.rs +++ b/server/src/rtsim/tick.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] // TODO: Remove this when rtsim is fleshed out + use super::*; use common::{ comp, @@ -12,6 +14,7 @@ const ENTITY_TICK_PERIOD: u64 = 30; pub struct Sys; impl<'a> System<'a> for Sys { + #[allow(clippy::type_complexity)] type SystemData = ( Read<'a, DeltaTime>, Read<'a, EventBus>, @@ -33,7 +36,7 @@ impl<'a> System<'a> for Sys { mut rtsim, terrain, world, - index, + _index, positions, rtsim_entities, mut agents, diff --git a/server/src/rtsim/unload_chunks.rs b/server/src/rtsim/unload_chunks.rs index 0d2e13e2df..1de4eb144b 100644 --- a/server/src/rtsim/unload_chunks.rs +++ b/server/src/rtsim/unload_chunks.rs @@ -4,10 +4,11 @@ use common::{ event::{EventBus, ServerEvent}, terrain::TerrainGrid, }; -use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, Write, WriteExpect}; +use specs::{Entities, Read, ReadExpect, ReadStorage, System, WriteExpect}; pub struct Sys; impl<'a> System<'a> for Sys { + #[allow(clippy::type_complexity)] type SystemData = ( Read<'a, EventBus>, WriteExpect<'a, RtSim>, @@ -20,17 +21,17 @@ impl<'a> System<'a> for Sys { fn run( &mut self, ( - server_event_bus, + _server_event_bus, mut rtsim, - terrain_grid, - entities, - rtsim_entities, - positions, + _terrain_grid, + _entities, + _rtsim_entities, + _positions, ): Self::SystemData, ) { let chunks = std::mem::take(&mut rtsim.chunks.chunks_to_unload); - for chunk in chunks { + for _chunk in chunks { // TODO } } diff --git a/voxygen/benches/meshing_benchmark.rs b/voxygen/benches/meshing_benchmark.rs index b0cd004443..642a61ddab 100644 --- a/voxygen/benches/meshing_benchmark.rs +++ b/voxygen/benches/meshing_benchmark.rs @@ -5,7 +5,7 @@ use common::{ use criterion::{black_box, criterion_group, criterion_main, Benchmark, Criterion}; use std::sync::Arc; use vek::*; -use veloren_voxygen::mesh::Meshable; +use veloren_voxygen::{mesh::Meshable, scene::terrain::BlocksOfInterest}; use world::{sim, World}; const CENTER: Vec2 = Vec2 { x: 512, y: 512 }; @@ -133,7 +133,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { c.bench( "meshing", Benchmark::new(&format!("Terrain mesh {}, {}", x, y), move |b| { - b.iter(|| volume.generate_mesh(black_box((range, Vec2::new(8192, 8192))))) + b.iter(|| volume.generate_mesh(black_box((range, Vec2::new(8192, 8192), &BlocksOfInterest::default())))) }) // Lower sample size to save time .sample_size(15), diff --git a/voxygen/src/hud/map.rs b/voxygen/src/hud/map.rs index 357226b643..8ea0fd4944 100644 --- a/voxygen/src/hud/map.rs +++ b/voxygen/src/hud/map.rs @@ -489,15 +489,11 @@ impl<'a> Widget for Map<'a> { { continue; } - let title = - site.name - .as_ref() - .map(|s| s.as_str()) - .unwrap_or_else(|| match &site.kind { - SiteKind::Town => i18n.get("hud.map.town"), - SiteKind::Dungeon { .. } => i18n.get("hud.map.dungeon"), - SiteKind::Castle => i18n.get("hud.map.castle"), - }); + let title = site.name.as_deref().unwrap_or_else(|| match &site.kind { + SiteKind::Town => i18n.get("hud.map.town"), + SiteKind::Dungeon { .. } => i18n.get("hud.map.dungeon"), + SiteKind::Castle => i18n.get("hud.map.castle"), + }); let (difficulty, desc) = match &site.kind { SiteKind::Town => (0, i18n.get("hud.map.town").to_string()), SiteKind::Dungeon { difficulty } => ( @@ -656,10 +652,9 @@ impl<'a> Widget for Map<'a> { Vec2::new(32.0, 37.0) * scale }; // Hide if icon could go off of the edge of the map + let arrow_mag = arrow_sz.map(|e| e as f32 / 2.0).magnitude(); if !rpos - .map2(map_size, |e, sz| { - e.abs() + arrow_sz.map(|e| e as f32 / 2.0).magnitude() > sz as f32 / 2.0 - }) + .map2(map_size, |e, sz| e.abs() + arrow_mag > sz as f32 / 2.0) .reduce_or() { Image::new(self.rot_imgs.indicator_mmap_small.target_north) diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 718dca3a8a..c513fa3ccf 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -2291,7 +2291,7 @@ impl Hud { // Reset the map position when it's not showing let drag = &global_state.settings.gameplay.map_drag; if drag.x != 0.0 || drag.y != 0.0 { - events.push(Event::MapDrag(drag - drag)) + events.push(Event::MapDrag(Vec2::zero())) } } diff --git a/voxygen/src/mesh/greedy.rs b/voxygen/src/mesh/greedy.rs index 8bf586293c..ebbaed7c93 100644 --- a/voxygen/src/mesh/greedy.rs +++ b/voxygen/src/mesh/greedy.rs @@ -586,16 +586,15 @@ fn draw_col_lights( 0.0 } ) / 4.0; - let glowiness = ( - get_glow(data, light_pos) - + get_glow(data, light_pos - uv.x) - + get_glow(data, light_pos - uv.y) - + if direct_u_opacity || direct_v_opacity { - get_glow(data, light_pos - uv.x - uv.y) - } else { - 0.0 - } - ) / 4.0; + let glowiness = (get_glow(data, light_pos) + + get_glow(data, light_pos - uv.x) + + get_glow(data, light_pos - uv.y) + + if direct_u_opacity || direct_v_opacity { + get_glow(data, light_pos - uv.x - uv.y) + } else { + 0.0 + }) + / 4.0; let col = get_color(data, pos); let light = (darkness * 31.5) as u8; let glow = (glowiness * 31.5) as u8; diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index 195b20ccf4..b240aaf756 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -77,7 +77,7 @@ where 0.0 } }; - let get_glow = |vol: &mut V, pos: Vec3| 0.0; + let get_glow = |_vol: &mut V, _pos: Vec3| 0.0; let get_color = |vol: &mut V, pos: Vec3| { vol.get(pos) .ok() diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index e479267163..e40c7f4aa4 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -250,6 +250,7 @@ impl<'a, V: RectRasterableVol + ReadVol + Debug + 'static> Meshable for &'a VolGrid2d { type Pipeline = TerrainPipeline; + #[allow(clippy::type_complexity)] type Result = ( Aabb, ColLightInfo, @@ -468,7 +469,12 @@ impl<'a, V: RectRasterableVol + ReadVol + Debug + 'static> opaque_mesh, fluid_mesh, Mesh::new(), - (bounds, (col_lights, col_lights_size), Box::new(light), Box::new(glow)), + ( + bounds, + (col_lights, col_lights_size), + Box::new(light), + Box::new(glow), + ), ) } } diff --git a/voxygen/src/render/pipelines/sprite.rs b/voxygen/src/render/pipelines/sprite.rs index 5f25d8aacc..bd95f84b21 100644 --- a/voxygen/src/render/pipelines/sprite.rs +++ b/voxygen/src/render/pipelines/sprite.rs @@ -115,7 +115,14 @@ impl Vertex { } impl Instance { - pub fn new(mat: Mat4, wind_sway: f32, pos: Vec3, ori_bits: u8, light: f32, glow: f32) -> Self { + pub fn new( + mat: Mat4, + wind_sway: f32, + pos: Vec3, + ori_bits: u8, + light: f32, + glow: f32, + ) -> Self { const EXTRA_NEG_Z: i32 = 32768; let mat_arr = mat.into_col_arrays(); diff --git a/voxygen/src/render/pipelines/terrain.rs b/voxygen/src/render/pipelines/terrain.rs index 9b4e24fc9a..0dbf62f43f 100644 --- a/voxygen/src/render/pipelines/terrain.rs +++ b/voxygen/src/render/pipelines/terrain.rs @@ -107,23 +107,25 @@ impl Vertex { ) -> <::Surface as gfx::format::SurfaceTyped>::DataType { //[col.r, col.g, col.b, light] - // It would be nice for this to be cleaner, but we want to squeeze 5 fields into 4. - // We can do this because both `light` and `glow` go from 0 to 31, meaning that they - // can both fit into 5 bits. If we steal a bit from red and blue each (not green, - // human eyes are more sensitive to changes in green) then we get just enough to - // expand the nibbles of the alpha field enough to fit both `light` and `glow`. + // It would be nice for this to be cleaner, but we want to squeeze 5 fields into + // 4. We can do this because both `light` and `glow` go from 0 to 31, + // meaning that they can both fit into 5 bits. If we steal a bit from + // red and blue each (not green, human eyes are more sensitive to + // changes in green) then we get just enough to expand the nibbles of + // the alpha field enough to fit both `light` and `glow`. // - // However, we now have a problem. In the shader code with use hardware filtering to - // get at the `light` and `glow` attributes (but not colour, that remains constant - // across a block). How do we resolve this if we're twiddling bits? The answer is to - // very carefully manipulate the bit pattern such that the fields we want to filter - // (`light` and `glow`) always sit as the higher bits of the fields. Then, we can do + // However, we now have a problem. In the shader code with use hardware + // filtering to get at the `light` and `glow` attributes (but not + // colour, that remains constant across a block). How do we resolve this + // if we're twiddling bits? The answer is to very carefully manipulate + // the bit pattern such that the fields we want to filter (`light` and + // `glow`) always sit as the higher bits of the fields. Then, we can do // some modulation magic to extract them from the filtering unharmed and use - // unfiltered texture access (i.e: `texelFetch`) to access the colours, plus a little - // bit-fiddling. + // unfiltered texture access (i.e: `texelFetch`) to access the colours, plus a + // little bit-fiddling. // - // TODO: This isn't currently working (no idea why). See `srgb.glsl` for current impl - // that intead does manual bit-twiddling and filtering. + // TODO: This isn't currently working (no idea why). See `srgb.glsl` for current + // impl that intead does manual bit-twiddling and filtering. [ (light.min(31) << 3) | ((col.r & 0b1110) >> 1), (glow.min(31) << 3) | ((col.r & 0b1110) >> 1), diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index d38efb4a1d..fbd3d71a6c 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -33,7 +33,8 @@ use tracing::{error, warn}; use vek::*; /// Represents the format of the pre-processed color target. -// TODO: `(gfx::format::R11_G11_B10, gfx::format::Float)` would be better in theory, but it doesn't seem to work +// TODO: `(gfx::format::R11_G11_B10, gfx::format::Float)` would be better in +// theory, but it doesn't seem to work pub type TgtColorFmt = gfx::format::Rgba16F; /// Represents the format of the pre-processed depth and stencil target. pub type TgtDepthStencilFmt = gfx::format::Depth; @@ -1001,10 +1002,10 @@ impl Renderer { size: [u16; 2], data: &[<::Surface as gfx::format::SurfaceTyped>::DataType], ) -> Result<(), RenderError> - where - ::Surface: gfx::format::TextureSurface, - ::Channel: gfx::format::TextureChannel, - <::Surface as gfx::format::SurfaceTyped>::DataType: Copy, + where + ::Surface: gfx::format::TextureSurface, + ::Channel: gfx::format::TextureChannel, + <::Surface as gfx::format::SurfaceTyped>::DataType: Copy, { texture.update(&mut self.encoder, offset, size, data) } diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index d6380e0e86..1c90887e15 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -12,8 +12,9 @@ use crate::{ }, scene::{ camera::{Camera, CameraMode, Dependents}, - math, LodData, SceneData, + math, terrain::Terrain, + LodData, SceneData, }, }; use anim::{ @@ -3486,7 +3487,8 @@ impl FigureState { }) .unwrap_or((1.0, 0.0)); // Fade between light and glow levels - // TODO: Making this temporal rather than spatial is a bit dumb but it's a very subtle difference + // TODO: Making this temporal rather than spatial is a bit dumb but it's a very + // subtle difference self.last_light = vek::Lerp::lerp(self.last_light, light, 16.0 * dt); self.last_glow = vek::Lerp::lerp(self.last_glow, glow, 16.0 * dt); diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index a91f8f4cf9..4b3e569b64 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -540,7 +540,8 @@ impl Scene { lights.clear(); // Maintain the particles. - self.particle_mgr.maintain(renderer, &scene_data, &self.terrain, lights); + self.particle_mgr + .maintain(renderer, &scene_data, &self.terrain, lights); // Update light constants lights.extend( diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index 20ef430bca..b703007bda 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -2,8 +2,8 @@ use super::{terrain::BlocksOfInterest, SceneData, Terrain}; use crate::{ mesh::{greedy::GreedyMesh, Meshable}, render::{ - pipelines::particle::ParticleMode, GlobalModel, Instances, LodData, Model, - ParticleInstance, ParticlePipeline, Renderer, Light, + pipelines::particle::ParticleMode, GlobalModel, Instances, Light, LodData, Model, + ParticleInstance, ParticlePipeline, Renderer, }, }; use common::{ @@ -73,7 +73,8 @@ impl ParticleMgr { ParticleMode::EnergyNature, *pos + Vec3::::zero() .map(|_| rng.gen_range(-1.0, 1.0)) - .normalized() * *radius, + .normalized() + * *radius, ) }, ); @@ -87,7 +88,8 @@ impl ParticleMgr { ParticleMode::CampfireFire, *pos + Vec3::::zero() .map(|_| rng.gen_range(-1.0, 1.0)) - .normalized() * *radius, + .normalized() + * *radius, ) }, ); @@ -121,7 +123,8 @@ impl ParticleMgr { ParticleMode::CampfireSmoke, *pos + Vec3::::zero() .map(|_| rng.gen_range(-1.0, 1.0)) - .normalized() * *radius, + .normalized() + * *radius, ) }, ); @@ -377,11 +380,7 @@ impl ParticleMgr { if b.stage_section == StageSection::Cast { if b.static_data.base_hps > 0 { // Emit a light when using healing - lights.push(Light::new( - pos.0 + b.offset, - Rgb::new(0.1, 1.0, 0.15), - 1.0, - )); + lights.push(Light::new(pos.0 + b.offset, Rgb::new(0.1, 1.0, 0.15), 1.0)); for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) { self.particles.push(Particle::new_beam( b.static_data.beam_duration, diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index d25641d37c..ab504881f6 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -144,7 +144,11 @@ fn mesh_worker + RectRasterableVol + ReadVol + Debug + ' span!(_guard, "mesh_worker"); let blocks_of_interest = BlocksOfInterest::from_chunk(&chunk); let (opaque_mesh, fluid_mesh, _shadow_mesh, (bounds, col_lights_info, light_map, glow_map)) = - volume.generate_mesh((range, Vec2::new(max_texture_size, max_texture_size), &blocks_of_interest)); + volume.generate_mesh(( + range, + Vec2::new(max_texture_size, max_texture_size), + &blocks_of_interest, + )); MeshWorkerResponse { pos, z_bounds: (bounds.min.z, bounds.max.z), @@ -472,14 +476,24 @@ impl Terrain { /// Find the light level (sunlight) at the given world position. pub fn light_at_wpos(&self, wpos: Vec3) -> f32 { - let chunk_pos = Vec2::from(wpos).map2(TerrainChunk::RECT_SIZE, |e: i32, sz| e.div_euclid(sz as i32)); - self.chunks.get(&chunk_pos).map(|c| (c.light_map)(wpos)).unwrap_or(1.0) + let chunk_pos = Vec2::from(wpos).map2(TerrainChunk::RECT_SIZE, |e: i32, sz| { + e.div_euclid(sz as i32) + }); + self.chunks + .get(&chunk_pos) + .map(|c| (c.light_map)(wpos)) + .unwrap_or(1.0) } /// Find the glow level (light from lamps) at the given world position. pub fn glow_at_wpos(&self, wpos: Vec3) -> f32 { - let chunk_pos = Vec2::from(wpos).map2(TerrainChunk::RECT_SIZE, |e: i32, sz| e.div_euclid(sz as i32)); - self.chunks.get(&chunk_pos).map(|c| (c.glow_map)(wpos)).unwrap_or(0.0) + let chunk_pos = Vec2::from(wpos).map2(TerrainChunk::RECT_SIZE, |e: i32, sz| { + e.div_euclid(sz as i32) + }); + self.chunks + .get(&chunk_pos) + .map(|c| (c.glow_map)(wpos)) + .unwrap_or(0.0) } /// Maintain terrain data. To be called once per tick. diff --git a/voxygen/src/scene/terrain/watcher.rs b/voxygen/src/scene/terrain/watcher.rs index 7e01763d46..0e97f5c3f8 100644 --- a/voxygen/src/scene/terrain/watcher.rs +++ b/voxygen/src/scene/terrain/watcher.rs @@ -6,6 +6,7 @@ use common::{ use rand::prelude::*; use vek::*; +#[derive(Default)] pub struct BlocksOfInterest { pub leaves: Vec>, pub grass: Vec>, @@ -22,8 +23,6 @@ pub struct BlocksOfInterest { pub lights: Vec<(Vec3, u8)>, } -use inline_tweak::*; - impl BlocksOfInterest { pub fn from_chunk(chunk: &TerrainChunk) -> Self { span!(_guard, "from_chunk", "BlocksOfInterest::from_chunk"); @@ -73,8 +72,10 @@ impl BlocksOfInterest { // Offset positions to account for block height. // TODO: Is this a good idea? Some(SpriteKind::StreetLamp) => fire_bowls.push(pos + Vec3::unit_z() * 2), - Some(SpriteKind::FireBowlGround) => fire_bowls.push(pos + Vec3::unit_z() * 1), - Some(SpriteKind::StreetLampTall) => fire_bowls.push(pos + Vec3::unit_z() * 4), + Some(SpriteKind::FireBowlGround) => fire_bowls.push(pos + Vec3::unit_z()), + Some(SpriteKind::StreetLampTall) => { + fire_bowls.push(pos + Vec3::unit_z() * 4) + }, Some(SpriteKind::Beehive) => beehives.push(pos), Some(SpriteKind::Reed) => reeds.push(pos), Some(SpriteKind::PinkFlower) => flowers.push(pos), diff --git a/world/src/layer/scatter.rs b/world/src/layer/scatter.rs index 577b2f3668..6634c02302 100644 --- a/world/src/layer/scatter.rs +++ b/world/src/layer/scatter.rs @@ -1,4 +1,4 @@ -use crate::{column::ColumnSample, sim::SimChunk, util::RandomField, Canvas, CONFIG}; +use crate::{column::ColumnSample, sim::SimChunk, Canvas, CONFIG}; use common::terrain::SpriteKind; use noise::NoiseFn; use rand::prelude::*; diff --git a/world/src/layer/tree.rs b/world/src/layer/tree.rs index 396eae98d8..18c392a158 100644 --- a/world/src/layer/tree.rs +++ b/world/src/layer/tree.rs @@ -31,6 +31,7 @@ static MODEL_RAND: RandomPerm = RandomPerm::new(0xDB21C052); static UNIT_CHOOSER: UnitChooser = UnitChooser::new(0x700F4EC7); static QUIRKY_RAND: RandomPerm = RandomPerm::new(0xA634460F); +#[allow(clippy::if_same_then_else)] pub fn apply_trees_to(canvas: &mut Canvas) { struct Tree { pos: Vec3, @@ -51,15 +52,17 @@ pub fn apply_trees_to(canvas: &mut Canvas) { let is_quirky = QUIRKY_RAND.chance(seed, 1.0 / 500.0); - // Ensure that it's valid to place a tree here + // Ensure that it's valid to place a *thing* here if col.alt < col.water_level || col.spawn_rate < 0.9 || col.water_dist.map(|d| d < 8.0).unwrap_or(false) || col.path.map(|(d, _, _, _)| d < 12.0).unwrap_or(false) { return None; - } else if !is_quirky - && ((seed.wrapping_mul(13)) & 0xFF) as f32 / 256.0 > col.tree_density + } + + // Ensure that it's valid to place a tree here + if !is_quirky && ((seed.wrapping_mul(13)) & 0xFF) as f32 / 256.0 > col.tree_density { return None; } diff --git a/world/src/lib.rs b/world/src/lib.rs index 885d90a299..a3c4cf7ca1 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -182,10 +182,20 @@ impl World { }; let meta = TerrainChunkMeta::new( - sim_chunk.sites + sim_chunk + .sites .iter() - .filter(|id| index.sites[**id].get_origin().distance_squared(chunk_center_wpos2d) as f32 <= index.sites[**id].radius().powf(2.0)) - .min_by_key(|id| index.sites[**id].get_origin().distance_squared(chunk_center_wpos2d)) + .filter(|id| { + index.sites[**id] + .get_origin() + .distance_squared(chunk_center_wpos2d) as f32 + <= index.sites[**id].radius().powf(2.0) + }) + .min_by_key(|id| { + index.sites[**id] + .get_origin() + .distance_squared(chunk_center_wpos2d) + }) .map(|id| index.sites[*id].name().to_string()), sim_chunk.get_biome(), sim_chunk.alt, diff --git a/world/src/pathfinding.rs b/world/src/pathfinding.rs index c8677d9707..300973e778 100644 --- a/world/src/pathfinding.rs +++ b/world/src/pathfinding.rs @@ -1,11 +1,9 @@ use crate::sim::WorldSim; -use common::{ - astar::Astar, - path::Path, -}; -use hashbrown::hash_map::DefaultHashBuilder; +use common::path::Path; +//use hashbrown::hash_map::DefaultHashBuilder; use vek::*; +#[allow(dead_code)] pub struct SearchCfg { // 0.0 = no discount, 1.0 = free travel path_discount: f32, @@ -14,15 +12,19 @@ pub struct SearchCfg { gradient_aversion: f32, } +#[allow(dead_code)] pub struct Searcher<'a> { land: &'a WorldSim, pub cfg: SearchCfg, } +#[allow(dead_code)] impl<'a> Searcher<'a> { /// Attempt to find a path between two chunks on the map. - pub fn search(self, a: Vec2, b: Vec2) -> Option> { - let heuristic = |pos: &Vec2| (pos - b).map(|e| e as f32).magnitude(); + pub fn search(self, _a: Vec2, _b: Vec2) -> Option> { + // TODO: implement this function + + //let heuristic = |pos: &Vec2| (pos - b).map(|e| e as f32).magnitude(); // Astar::new( // 100_000, // a, diff --git a/world/src/sim/map.rs b/world/src/sim/map.rs index f71888bfad..b7be863e60 100644 --- a/world/src/sim/map.rs +++ b/world/src/sim/map.rs @@ -103,7 +103,7 @@ pub fn sample_pos( spline_derivative, is_path, is_cave, - near_site, + _near_site, ) = sampler .get(pos) .map(|sample| { diff --git a/world/src/site/castle/mod.rs b/world/src/site/castle/mod.rs index 998512ec6f..ef88e150c9 100644 --- a/world/src/site/castle/mod.rs +++ b/world/src/site/castle/mod.rs @@ -3,11 +3,11 @@ use crate::{ column::ColumnSample, sim::WorldSim, site::{ + namegen::NameGen, settlement::building::{ archetype::keep::{Attr, FlagColor, Keep as KeepArchetype, StoneColor}, Archetype, Ori, }, - namegen::NameGen, }, IndexRef, }; @@ -156,9 +156,7 @@ impl Castle { this } - pub fn name(&self) -> &str { - &self.name - } + pub fn name(&self) -> &str { &self.name } pub fn contains_point(&self, wpos: Vec2) -> bool { let lpos = wpos - self.origin; diff --git a/world/src/site/dungeon/mod.rs b/world/src/site/dungeon/mod.rs index b22825e183..10231c77f2 100644 --- a/world/src/site/dungeon/mod.rs +++ b/world/src/site/dungeon/mod.rs @@ -48,8 +48,6 @@ pub struct Colors { const ALT_OFFSET: i32 = -2; -const LEVELS: usize = 5; - impl Dungeon { #[allow(clippy::let_and_return)] // TODO: Pending review in #587 pub fn generate(wpos: Vec2, sim: Option<&WorldSim>, rng: &mut impl Rng) -> Self { @@ -321,7 +319,10 @@ impl Floor { enemy_density: Some((0.0002 * difficulty as f32).min(0.001)), // Minions! miniboss: false, boss: true, - area: Rect::from((new_stair_tile - tile_offset - 4, Extent2::broadcast(width as i32 * 2 + 1))), + area: Rect::from(( + new_stair_tile - tile_offset - 4, + Extent2::broadcast(width as i32 * 2 + 1), + )), height: height as i32, pillars: Some(2), difficulty, @@ -482,6 +483,8 @@ impl Floor { origin: Vec3, supplement: &mut ChunkSupplement, ) { + /* + // Add stair waypoint let stair_rcenter = Vec3::from((self.stair_tile + self.tile_offset).map(|e| e * TILE_SIZE + TILE_SIZE / 2)); @@ -493,13 +496,14 @@ impl Floor { .try_normalized() .unwrap_or_else(Vec2::unit_y) * (TILE_SIZE as f32 / 2.0 - 4.0); - // if !self.final_level { - // supplement.add_entity( - // EntityInfo::at((origin + stair_rcenter).map(|e| e as f32) - // + Vec3::from(offs)) .into_waypoint(), - // ); - // } + if !self.final_level { + supplement.add_entity( + EntityInfo::at((origin + stair_rcenter).map(|e| e as f32) + + Vec3::from(offs)) .into_waypoint(), + ); + } } + */ for x in area.min.x..area.max.x { for y in area.min.y..area.max.y { @@ -601,11 +605,11 @@ impl Floor { (room.difficulty as f32).powf(1.5) + 4.0, ).round() as u32); let entity = match room.difficulty { - 0 => entity.with_name("Outcast") - .with_config(common::loadout_builder::LoadoutConfig::Outcast) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_main_tool( - comp::Item::new_from_asset_expect( + 0 => entity + .with_name("Outcast") + .with_config(common::loadout_builder::LoadoutConfig::Outcast) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_main_tool(comp::Item::new_from_asset_expect( match dynamic_rng.gen_range(0, 6) { 0 => "common.items.weapons.axe.starter_axe", 1 => "common.items.weapons.sword.starter_sword", @@ -614,13 +618,12 @@ impl Floor { 4 => "common.items.weapons.staff.starter_staff", _ => "common.items.weapons.bow.starter_bow", }, - ), - ), - 1 => entity.with_name("Highwayman") - .with_config(common::loadout_builder::LoadoutConfig::Highwayman) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_main_tool( - comp::Item::new_from_asset_expect( + )), + 1 => entity + .with_name("Highwayman") + .with_config(common::loadout_builder::LoadoutConfig::Highwayman) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_main_tool(comp::Item::new_from_asset_expect( match dynamic_rng.gen_range(0, 6) { 0 => "common.items.weapons.axe.worn_iron_axe-0", 1 => "common.items.weapons.sword.zweihander_sword_0", @@ -629,13 +632,12 @@ impl Floor { 4 => "common.items.weapons.staff.bone_staff", _ => "common.items.weapons.bow.wood_shortbow-1", }, - ), - ), - 2 => entity.with_name("Bandit") - .with_config(common::loadout_builder::LoadoutConfig::Bandit) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_main_tool( - comp::Item::new_from_asset_expect( + )), + 2 => entity + .with_name("Bandit") + .with_config(common::loadout_builder::LoadoutConfig::Bandit) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_main_tool(comp::Item::new_from_asset_expect( match dynamic_rng.gen_range(0, 6) { 0 => "common.items.weapons.axe.bronze_axe-0", 1 => "common.items.weapons.sword.greatsword_2h_simple-0", @@ -644,13 +646,12 @@ impl Floor { 4 => "common.items.weapons.staff.bone_staff", _ => "common.items.weapons.bow.wood_longbow-0", }, - ), - ), - 3 => entity.with_name("Cultist Novice") - .with_config(common::loadout_builder::LoadoutConfig::CultistNovice) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_main_tool( - comp::Item::new_from_asset_expect( + )), + 3 => entity + .with_name("Cultist Novice") + .with_config(common::loadout_builder::LoadoutConfig::CultistNovice) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_main_tool(comp::Item::new_from_asset_expect( match dynamic_rng.gen_range(0, 6) { 0 => "common.items.weapons.axe.steel_axe-0", 1 => "common.items.weapons.sword.long_2h_orn-0", @@ -659,13 +660,12 @@ impl Floor { 4 => "common.items.weapons.staff.amethyst_staff", _ => "common.items.weapons.bow.horn_longbow-0", }, - ), - ), - 4 => entity.with_name("Cultist Acolyte") - .with_config(common::loadout_builder::LoadoutConfig::CultistAcolyte) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_main_tool( - comp::Item::new_from_asset_expect( + )), + 4 => entity + .with_name("Cultist Acolyte") + .with_config(common::loadout_builder::LoadoutConfig::CultistAcolyte) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_main_tool(comp::Item::new_from_asset_expect( match dynamic_rng.gen_range(0, 6) { 0 => "common.items.weapons.axe.malachite_axe-0", 1 => "common.items.weapons.sword.cultist_purp_2h-0", @@ -674,20 +674,20 @@ impl Floor { 4 => "common.items.weapons.staff.cultist_staff", _ => "common.items.weapons.bow.horn_longbow-0", }, - ), - ), + )), 5 => match dynamic_rng.gen_range(0, 6) { - 0 => entity.with_name("Cultist Warlock") - .with_config(common::loadout_builder::LoadoutConfig::Warlock) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_main_tool( - comp::Item::new_from_asset_expect("common.items.npc_weapons.staff.cultist_staff"), - ), - _ => entity.with_name("Cultist Warlord") - .with_config(common::loadout_builder::LoadoutConfig::Warlord) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_main_tool( - comp::Item::new_from_asset_expect( + 0 => entity + .with_name("Cultist Warlock") + .with_config(common::loadout_builder::LoadoutConfig::Warlock) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_main_tool(comp::Item::new_from_asset_expect( + "common.items.npc_weapons.staff.cultist_staff", + )), + _ => entity + .with_name("Cultist Warlord") + .with_config(common::loadout_builder::LoadoutConfig::Warlord) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_main_tool(comp::Item::new_from_asset_expect( match dynamic_rng.gen_range(0, 5) { 0 => "common.items.weapons.axe.malachite_axe-0", 1 => "common.items.weapons.sword.cultist_purp_2h-0", @@ -695,8 +695,7 @@ impl Floor { 3 => "common.items.weapons.hammer.cultist_purp_2h-0", _ => "common.items.weapons.bow.horn_longbow-0", }, - ), - ), + )), }, _ => entity.with_name("Humanoid").with_main_tool( comp::Item::new_from_asset_expect( @@ -723,77 +722,101 @@ impl Floor { if tile_pos == boss_spawn_tile && tile_wcenter.xy() == wpos2d { let chosen = match room.difficulty { - 0 => Lottery::::load_expect("common.loot_tables.loot_table_weapon_uncommon"), - 1 => Lottery::::load_expect("common.loot_tables.loot_table_weapon_uncommon"), - 2 => Lottery::::load_expect("common.loot_tables.loot_table_armor_heavy"), - 3 => Lottery::::load_expect("common.loot_tables.loot_table_weapon_rare"), - 4 => Lottery::::load_expect("common.loot_tables.loot_table_boss_cultist-leader"), - 5 => Lottery::::load_expect("common.loot_tables.loot_table_boss_cultist-leader"), + 0 => Lottery::::load_expect( + "common.loot_tables.loot_table_weapon_uncommon", + ), + 1 => Lottery::::load_expect( + "common.loot_tables.loot_table_weapon_uncommon", + ), + 2 => Lottery::::load_expect( + "common.loot_tables.loot_table_armor_heavy", + ), + 3 => Lottery::::load_expect( + "common.loot_tables.loot_table_weapon_rare", + ), + 4 => Lottery::::load_expect( + "common.loot_tables.loot_table_boss_cultist-leader", + ), + 5 => Lottery::::load_expect( + "common.loot_tables.loot_table_boss_cultist-leader", + ), _ => Lottery::::load_expect( "common.loot_tables.loot_table_armor_misc", ), }; let chosen = chosen.choose(); - let entity = - match room.difficulty { - 0 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) - .with_name("Outcast Leader".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_config(common::loadout_builder::LoadoutConfig::Outcast) - .with_scale(2.0) - .with_main_tool( - comp::Item::new_from_asset_expect( - match dynamic_rng.gen_range(0, 6) { - 0 => "common.items.weapons.axe.worn_iron_axe-0", - 1 => "common.items.weapons.sword.zweihander_sword_0", - 2 => "common.items.weapons.sword.zweihander_sword_0", - 3 => "common.items.weapons.hammer.worn_iron_hammer-0", - 4 => "common.items.weapons.staff.bone_staff", - _ => "common.items.weapons.bow.wood_shortbow-1", - }, - ), - ), - EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::QuadrupedMedium(comp::quadruped_medium::Body::random_with( - dynamic_rng, - &comp::quadruped_medium::Species::Tarasque, - ))) - .with_name("Tarasque".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), + let entity = match room.difficulty { + 0 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::Humanoid( + comp::humanoid::Body::random(), + )) + .with_name("Outcast Leader".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_config( + common::loadout_builder::LoadoutConfig::Outcast, + ) + .with_scale(2.0) + .with_main_tool(comp::Item::new_from_asset_expect( + match dynamic_rng.gen_range(0, 6) { + 0 => "common.items.weapons.axe.worn_iron_axe-0", + 1 => { + "common.items.weapons.sword.zweihander_sword_0" + }, + 2 => { + "common.items.weapons.sword.zweihander_sword_0" + }, + 3 => { + "common.items.weapons.hammer.worn_iron_hammer-0" + }, + 4 => "common.items.weapons.staff.bone_staff", + _ => "common.items.weapons.bow.wood_shortbow-1", + }, + )), + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::QuadrupedMedium( + comp::quadruped_medium::Body::random_with( + dynamic_rng, + &comp::quadruped_medium::Species::Tarasque, + ), + )) + .with_name("Tarasque".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), ], - 1 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::Theropod(comp::theropod::Body::random_with( - dynamic_rng, - &comp::theropod::Species::Odonto, - ))) - .with_name("Odonto".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), + 1 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::Theropod( + comp::theropod::Body::random_with( + dynamic_rng, + &comp::theropod::Species::Odonto, + ), + )) + .with_name("Odonto".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), ], - 2 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) - .with_name("Bandit Captain".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_config(common::loadout_builder::LoadoutConfig::Bandit) - .with_scale(2.0) - .with_main_tool( - comp::Item::new_from_asset_expect( - match dynamic_rng.gen_range(0, 6) { - 0 => "common.items.weapons.axe.steel_axe-0", - 1 => "common.items.weapons.sword.long_2h_orn-0", - 2 => "common.items.weapons.sword.long_2h_orn-0", - 3 => "common.items.weapons.hammer.cobalt_hammer-0", - 4 => "common.items.weapons.staff.amethyst_staff", - _ => "common.items.weapons.bow.horn_longbow-0", - }, - ), - ) - ; 2], - 3 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) + 2 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::Humanoid( + comp::humanoid::Body::random() + )) + .with_name("Bandit Captain".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_config(common::loadout_builder::LoadoutConfig::Bandit) + .with_scale(2.0) + .with_main_tool(comp::Item::new_from_asset_expect( + match dynamic_rng.gen_range(0, 6) { + 0 => "common.items.weapons.axe.steel_axe-0", + 1 => "common.items.weapons.sword.long_2h_orn-0", + 2 => "common.items.weapons.sword.long_2h_orn-0", + 3 => "common.items.weapons.hammer.cobalt_hammer-0", + 4 => "common.items.weapons.staff.amethyst_staff", + _ => "common.items.weapons.bow.horn_longbow-0", + }, + ),); + 2 + ], + 3 => { + vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) .with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) .with_name("Cultist Acolyte".to_string()) .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) @@ -811,46 +834,57 @@ impl Floor { }, ), ) - ; 2], - 4 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::Golem(comp::golem::Body::random_with( - dynamic_rng, - &comp::golem::Species::StoneGolem, - ))) - .with_name("Stonework Defender".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), + ; 2] + }, + 4 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::Golem( + comp::golem::Body::random_with( + dynamic_rng, + &comp::golem::Species::StoneGolem, + ), + )) + .with_name("Stonework Defender".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), ], - 5 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::BipedLarge(comp::biped_large::Body::random_with( - dynamic_rng, - &comp::biped_large::Species::Mindflayer, - ))) - .with_name("Mindflayer".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), - ], - _ => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::QuadrupedSmall(comp::quadruped_small::Body::random_with( - dynamic_rng, - &comp::quadruped_small::Species::Sheep, - ))), + 5 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::BipedLarge( + comp::biped_large::Body::random_with( + dynamic_rng, + &comp::biped_large::Species::Mindflayer, + ), + )) + .with_name("Mindflayer".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), ], + _ => { + vec![EntityInfo::at(tile_wcenter.map(|e| e as f32)).with_body( + comp::Body::QuadrupedSmall( + comp::quadruped_small::Body::random_with( + dynamic_rng, + &comp::quadruped_small::Species::Sheep, + ), + ), + )] + }, }; for entity in entity { - supplement.add_entity(entity.with_level( - dynamic_rng - .gen_range( - (room.difficulty as f32).powf(1.25) + 3.0, - (room.difficulty as f32).powf(1.5) + 4.0, - ) - .round() as u32 - * 5, - ) - .with_alignment(comp::Alignment::Enemy), - ); + supplement.add_entity( + entity + .with_level( + dynamic_rng + .gen_range( + (room.difficulty as f32).powf(1.25) + 3.0, + (room.difficulty as f32).powf(1.5) + 4.0, + ) + .round() + as u32 + * 5, + ) + .with_alignment(comp::Alignment::Enemy), + ); } } } @@ -868,123 +902,161 @@ impl Floor { let miniboss_spawn_tile = miniboss_spawn_tile + if miniboss_tile_is_pillar { 1 } else { 0 }; - if tile_pos == miniboss_spawn_tile && tile_wcenter.xy() == wpos2d { - let chosen = match room.difficulty { - 0 => Lottery::::load_expect("common.loot_tables.loot_table_animal_parts"), - 1 => Lottery::::load_expect("common.loot_tables.loot_table_animal_parts"), - 2 => Lottery::::load_expect("common.loot_tables.loot_table_animal_parts"), - 3 => Lottery::::load_expect("common.loot_tables.loot_table_weapon_rare"), - 4 => Lottery::::load_expect("common.loot_tables.loot_table_weapon_rare"), - 5 => Lottery::::load_expect("common.loot_tables.loot_table_boss_cultist-leader"), - _ => Lottery::::load_expect( - "common.loot_tables.loot_table_armor_misc", - ), - }; - let chosen = chosen.choose(); - let entity = - match room.difficulty { - 0 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::QuadrupedMedium(comp::quadruped_medium::Body::random_with( - dynamic_rng, - &comp::quadruped_medium::Species::Bonerattler, - ))) - .with_name("Bonerattler".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), - ], - 1 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::QuadrupedMedium(comp::quadruped_medium::Body::random_with( - dynamic_rng, - &comp::quadruped_medium::Species::Bonerattler, - ))) - .with_name("Bonerattler".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - ; 3], - 2 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::QuadrupedMedium(comp::quadruped_medium::Body::random_with( - dynamic_rng, - &comp::quadruped_medium::Species::Tarasque, - ))) - .with_name("Tarasque".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), - ], - 3 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) - .with_name("Animal Trainer".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_config(common::loadout_builder::LoadoutConfig::CultistAcolyte) - .with_scale(2.0) - .with_main_tool( - comp::Item::new_from_asset_expect( + if tile_pos == miniboss_spawn_tile && tile_wcenter.xy() == wpos2d { + let chosen = match room.difficulty { + 0 => Lottery::::load_expect( + "common.loot_tables.loot_table_animal_parts", + ), + 1 => Lottery::::load_expect( + "common.loot_tables.loot_table_animal_parts", + ), + 2 => Lottery::::load_expect( + "common.loot_tables.loot_table_animal_parts", + ), + 3 => Lottery::::load_expect( + "common.loot_tables.loot_table_weapon_rare", + ), + 4 => Lottery::::load_expect( + "common.loot_tables.loot_table_weapon_rare", + ), + 5 => Lottery::::load_expect( + "common.loot_tables.loot_table_boss_cultist-leader", + ), + _ => Lottery::::load_expect( + "common.loot_tables.loot_table_armor_misc", + ), + }; + let chosen = chosen.choose(); + let entity = match room.difficulty { + 0 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::QuadrupedMedium( + comp::quadruped_medium::Body::random_with( + dynamic_rng, + &comp::quadruped_medium::Species::Bonerattler, + ), + )) + .with_name("Bonerattler".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), + ], + 1 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::QuadrupedMedium( + comp::quadruped_medium::Body::random_with( + dynamic_rng, + &comp::quadruped_medium::Species::Bonerattler, + ) + )) + .with_name("Bonerattler".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect( + chosen + )); + 3 + ], + 2 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::QuadrupedMedium( + comp::quadruped_medium::Body::random_with( + dynamic_rng, + &comp::quadruped_medium::Species::Tarasque, + ), + )) + .with_name("Tarasque".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), + ], + 3 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::Humanoid( + comp::humanoid::Body::random(), + )) + .with_name("Animal Trainer".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) + .with_config( + common::loadout_builder::LoadoutConfig::CultistAcolyte, + ) + .with_scale(2.0) + .with_main_tool(comp::Item::new_from_asset_expect( match dynamic_rng.gen_range(0, 6) { 0 => "common.items.weapons.axe.malachite_axe-0", 1 => "common.items.weapons.sword.cultist_purp_2h-0", 2 => "common.items.weapons.sword.cultist_purp_2h-0", - 3 => "common.items.weapons.hammer.cultist_purp_2h-0", + 3 => { + "common.items.weapons.hammer.cultist_purp_2h-0" + }, 4 => "common.items.weapons.staff.cultist_staff", _ => "common.items.weapons.bow.horn_longbow-0", }, + )), + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::QuadrupedMedium( + comp::quadruped_medium::Body::random_with( + dynamic_rng, + &comp::quadruped_medium::Species::Wolf, + ), + )) + .with_name("Tamed Wolf".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::QuadrupedMedium( + comp::quadruped_medium::Body::random_with( + dynamic_rng, + &comp::quadruped_medium::Species::Wolf, + ), + )) + .with_name("Tamed Wolf".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), + ], + 4 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::BipedLarge( + comp::biped_large::Body::random_with( + dynamic_rng, + &comp::biped_large::Species::Dullahan, + ), + )) + .with_name("Dullahan Guard".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), + ], + 5 => vec![ + EntityInfo::at(tile_wcenter.map(|e| e as f32)) + .with_body(comp::Body::Golem( + comp::golem::Body::random_with( + dynamic_rng, + &comp::golem::Species::StoneGolem, + ), + )) + .with_name("Stonework Defender".to_string()) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), + ], + _ => { + vec![EntityInfo::at(tile_wcenter.map(|e| e as f32)).with_body( + comp::Body::QuadrupedSmall( + comp::quadruped_small::Body::random_with( + dynamic_rng, + &comp::quadruped_small::Species::Sheep, + ), ), - ), - EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::QuadrupedMedium(comp::quadruped_medium::Body::random_with( - dynamic_rng, - &comp::quadruped_medium::Species::Wolf, - ))) - .with_name("Tamed Wolf".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), - EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::QuadrupedMedium(comp::quadruped_medium::Body::random_with( - dynamic_rng, - &comp::quadruped_medium::Species::Wolf, - ))) - .with_name("Tamed Wolf".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), - ], - 4 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::BipedLarge(comp::biped_large::Body::random_with( - dynamic_rng, - &comp::biped_large::Species::Dullahan, - ))) - .with_name("Dullahan Guard".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), - ], - 5 => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::Golem(comp::golem::Body::random_with( - dynamic_rng, - &comp::golem::Species::StoneGolem, - ))) - .with_name("Stonework Defender".to_string()) - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)), - ], - _ => - vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_body(comp::Body::QuadrupedSmall(comp::quadruped_small::Body::random_with( - dynamic_rng, - &comp::quadruped_small::Species::Sheep, - ))), - ], - }; + )] + }, + }; - for entity in entity { - supplement.add_entity(entity.with_level( - dynamic_rng - .gen_range( - (room.difficulty as f32).powf(1.25) + 3.0, - (room.difficulty as f32).powf(1.5) + 4.0, + for entity in entity { + supplement.add_entity( + entity + .with_level( + dynamic_rng + .gen_range( + (room.difficulty as f32).powf(1.25) + 3.0, + (room.difficulty as f32).powf(1.5) + 4.0, + ) + .round() + as u32 + * 5, ) - .round() as u32 - * 5, - ) - .with_alignment(comp::Alignment::Enemy), + .with_alignment(comp::Alignment::Enemy), ); - } } + } } } } diff --git a/world/src/site/mod.rs b/world/src/site/mod.rs index 3859f3364f..cbe82647c3 100644 --- a/world/src/site/mod.rs +++ b/world/src/site/mod.rs @@ -1,8 +1,8 @@ mod block_mask; mod castle; mod dungeon; -mod namegen; pub mod economy; +mod namegen; mod settlement; // Reexports diff --git a/world/src/site/namegen.rs b/world/src/site/namegen.rs index 44ef7a6f9e..e1dc6488f4 100644 --- a/world/src/site/namegen.rs +++ b/world/src/site/namegen.rs @@ -17,13 +17,14 @@ impl<'a, R: Rng> NameGen<'a, R> { pub fn generate(self) -> String { let cons = vec![ - "d", "f", "ph", "r", "st", "t", "s", "p", "sh", "th", "br", "tr", "m", "k", "st", "w", "y", - "cr", "fr", "dr", "pl", "wr", "sn", "g", "qu", "l", + "d", "f", "ph", "r", "st", "t", "s", "p", "sh", "th", "br", "tr", "m", "k", "st", "w", + "y", "cr", "fr", "dr", "pl", "wr", "sn", "g", "qu", "l", ]; let mut start = cons.clone(); start.extend(vec![ - "cr", "thr", "str", "br", "iv", "est", "ost", "ing", "kr", "in", "on", "tr", "tw", "wh", - "eld", "ar", "or", "ear", "irr", "mi", "en", "ed", "et", "ow", "fr", "shr", "wr", "gr", "pr", + "cr", "thr", "str", "br", "iv", "est", "ost", "ing", "kr", "in", "on", "tr", "tw", + "wh", "eld", "ar", "or", "ear", "irr", "mi", "en", "ed", "et", "ow", "fr", "shr", "wr", + "gr", "pr", ]); let mut middle = cons.clone(); middle.extend(vec!["tt"]); @@ -43,14 +44,9 @@ impl<'a, R: Rng> NameGen<'a, R> { } name += end.choose(self.rng).unwrap(); - name - .chars() + name.chars() .enumerate() - .map(|(i, c)| if i == 0 { - c.to_ascii_uppercase() - } else { - c - }) + .map(|(i, c)| if i == 0 { c.to_ascii_uppercase() } else { c }) .collect() } } diff --git a/world/src/site/settlement/mod.rs b/world/src/site/settlement/mod.rs index 188e63cd6f..edc7c192cd 100644 --- a/world/src/site/settlement/mod.rs +++ b/world/src/site/settlement/mod.rs @@ -9,8 +9,8 @@ use super::SpawnRules; use crate::{ column::ColumnSample, sim::WorldSim, - util::{RandomField, Sampler, StructureGen2d}, site::namegen::NameGen, + util::{RandomField, Sampler, StructureGen2d}, IndexRef, }; use common::{ @@ -188,9 +188,7 @@ impl Settlement { this } - pub fn name(&self) -> &str { - &self.name - } + pub fn name(&self) -> &str { &self.name } pub fn get_origin(&self) -> Vec2 { self.origin } @@ -921,14 +919,16 @@ impl Settlement { .do_if(is_dummy, |e| e.with_name("Training Dummy")) .do_if(is_human && dynamic_rng.gen(), |entity| { match dynamic_rng.gen_range(0, 5) { - 0 => entity.with_main_tool(Item::new_from_asset_expect( - "common.items.weapons.sword.greatsword_2h_simple-0", - )) - .with_name("Guard") - .with_level(dynamic_rng.gen_range(10, 15)) - .with_config(common::loadout_builder::LoadoutConfig::Guard), - _ => entity.with_main_tool(Item::new_from_asset_expect( - match dynamic_rng.gen_range(0, 7) { + 0 => entity + .with_main_tool(Item::new_from_asset_expect( + "common.items.weapons.sword.greatsword_2h_simple-0", + )) + .with_name("Guard") + .with_level(dynamic_rng.gen_range(10, 15)) + .with_config(common::loadout_builder::LoadoutConfig::Guard), + _ => entity + .with_main_tool(Item::new_from_asset_expect( + match dynamic_rng.gen_range(0, 7) { 0 => "common.items.npc_weapons.tool.broom", 1 => "common.items.npc_weapons.tool.hoe", 2 => "common.items.npc_weapons.tool.pickaxe", @@ -938,9 +938,9 @@ impl Settlement { _ => "common.items.npc_weapons.tool.shovel-1", //_ => "common.items.npc_weapons.bow.starter_bow", TODO: Re-Add this when we have a better way of distributing npc_weapons here }, - )) - .with_config(common::loadout_builder::LoadoutConfig::Villager) - } + )) + .with_config(common::loadout_builder::LoadoutConfig::Villager), + } }); supplement.add_entity(entity);