diff --git a/assets/world/structure/dungeon/ruins-2.vox b/assets/world/structure/dungeon/ruins-2.vox new file mode 100644 index 0000000000..67ce2a4157 Binary files /dev/null and b/assets/world/structure/dungeon/ruins-2.vox differ diff --git a/assets/world/structure/dungeon/ruins.vox b/assets/world/structure/dungeon/ruins.vox index cb84507e3a..4021fdeb3a 100644 Binary files a/assets/world/structure/dungeon/ruins.vox and b/assets/world/structure/dungeon/ruins.vox differ diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 6847ec4c05..2ac56c58b1 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -14,6 +14,15 @@ pub enum Body { Object(object::Body), } +impl Body { + pub fn is_humanoid(&self) -> bool { + match self { + Body::Humanoid(_) => true, + _ => false, + } + } +} + impl Component for Body { type Storage = FlaggedStorage>; } diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index d118a5da02..4a1c3d9d4e 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -1,4 +1,4 @@ -use crate::comp::{Agent, Controller, Pos, Stats}; +use crate::comp::{ActionState, Agent, Controller, Pos, Stats}; use rand::{seq::SliceRandom, thread_rng}; use specs::{Entities, Join, ReadStorage, System, WriteStorage}; use vek::*; @@ -10,11 +10,15 @@ impl<'a> System<'a> for Sys { Entities<'a>, ReadStorage<'a, Pos>, ReadStorage<'a, Stats>, + ReadStorage<'a, ActionState>, WriteStorage<'a, Agent>, WriteStorage<'a, Controller>, ); - fn run(&mut self, (entities, positions, stats, mut agents, mut controllers): Self::SystemData) { + fn run( + &mut self, + (entities, positions, stats, action_states, mut agents, mut controllers): Self::SystemData, + ) { for (entity, pos, agent, controller) in (&entities, &positions, &mut agents, &mut controllers).join() { @@ -63,8 +67,14 @@ impl<'a> System<'a> for Sys { const SIGHT_DIST: f32 = 30.0; let mut choose_new = false; - if let Some((Some(target_pos), Some(target_stats))) = - target.map(|target| (positions.get(target), stats.get(target))) + if let Some((Some(target_pos), Some(target_stats), Some(a))) = + target.map(|target| { + ( + positions.get(target), + stats.get(target), + action_states.get(target), + ) + }) { let dist = Vec2::::from(target_pos.0 - pos.0).magnitude(); if target_stats.is_dead { @@ -86,6 +96,11 @@ impl<'a> System<'a> for Sys { if rand::random::() < 0.02 { controller.roll = true; } + + if a.gliding && target_pos.0.z > pos.0.z + 5.0 { + controller.glide = true; + controller.jump = true; + } } else { choose_new = true; } @@ -108,7 +123,7 @@ impl<'a> System<'a> for Sys { let entities = (&entities, &positions, &stats) .join() .filter(|(e, e_pos, e_stats)| { - Vec2::::from(e_pos.0 - pos.0).magnitude() < SIGHT_DIST + (e_pos.0 - pos.0).magnitude() < SIGHT_DIST && *e != entity && !e_stats.is_dead }) diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index e9ae987024..a32ba98af8 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -1,6 +1,6 @@ use crate::comp::{ - ActionState, Attacking, Controller, Gliding, Jumping, MoveDir, Respawning, Rolling, Stats, Vel, - Wielding, + ActionState, Attacking, Body, Controller, Gliding, Jumping, MoveDir, Respawning, Rolling, + Stats, Vel, Wielding, }; use specs::{Entities, Join, ReadStorage, System, WriteStorage}; @@ -11,6 +11,7 @@ impl<'a> System<'a> for Sys { Entities<'a>, WriteStorage<'a, Controller>, ReadStorage<'a, Stats>, + ReadStorage<'a, Body>, ReadStorage<'a, Vel>, WriteStorage<'a, ActionState>, WriteStorage<'a, MoveDir>, @@ -28,6 +29,7 @@ impl<'a> System<'a> for Sys { entities, mut controllers, stats, + bodies, velocities, mut action_states, mut move_dirs, @@ -39,10 +41,11 @@ impl<'a> System<'a> for Sys { mut glidings, ): Self::SystemData, ) { - for (entity, controller, stats, vel, mut a) in ( + for (entity, controller, stats, body, vel, mut a) in ( &entities, &mut controllers, &stats, + &bodies, &velocities, // Although this is changed, it is only kept for this system // as it will be replaced in the action state system @@ -71,7 +74,8 @@ impl<'a> System<'a> for Sys { } // Glide - if controller.glide && !a.on_ground && !a.attacking && !a.rolling { + if controller.glide && !a.on_ground && !a.attacking && !a.rolling && body.is_humanoid() + { let _ = glidings.insert(entity, Gliding); a.gliding = true; } else { diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 44bddf3a12..45865c334b 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -335,9 +335,10 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C (Some(opt_align), Some(id), opt_amount) => { if let Some(agent) = alignment_to_agent(&opt_align, entity) { let amount = opt_amount - .map_or(Some(1), |a| a.parse().ok()) - .and_then(|a| if a > 0 { Some(a) } else { None }) - .unwrap(); + .and_then(|a| a.parse().ok()) + .filter(|x| *x > 0) + .unwrap_or(1) + .min(10); match server.state.read_component_cloned::(entity) { Some(pos) => { diff --git a/server/src/lib.rs b/server/src/lib.rs index 5e7c133b31..f0cbf76fd5 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -286,8 +286,8 @@ impl Server { stats = comp::Stats::new("Humanoid".to_string()); body = comp::Body::Humanoid(comp::humanoid::Body::random()); } - stats = stats.with_max_health(300 + rand::random::() % 400); - scale = 1.8 + rand::random::(); + stats = stats.with_max_health(500 + rand::random::() % 400); + scale = 2.5 + rand::random::(); } self.state diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 443739b17d..b03e455d1a 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -2,7 +2,7 @@ use crate::{ all::ForestKind, block::StructureMeta, sim::{LocationInfo, SimChunk}, - util::{Sampler, UnitChooser}, + util::{RandomPerm, Sampler, UnitChooser}, World, CONFIG, }; use common::{ @@ -24,13 +24,16 @@ pub struct ColumnGen<'a> { } static UNIT_CHOOSER: UnitChooser = UnitChooser::new(0x700F4EC7); +static DUNGEON_RAND: RandomPerm = RandomPerm::new(0x42782335); lazy_static! { pub static ref DUNGEONS: Vec> = vec![ - // green oaks assets::load_map("world/structure/dungeon/ruins.vox", |s: Structure| s .with_center(Vec3::new(57, 58, 62))) .unwrap(), + assets::load_map("world/structure/dungeon/ruins-2.vox", |s: Structure| s + .with_center(Vec3::new(53, 57, 60))) + .unwrap(), ]; } @@ -68,7 +71,7 @@ impl<'a> ColumnGen<'a> { seed, meta: Some(StructureMeta::Volume { units: UNIT_CHOOSER.get(seed), - volume: &DUNGEONS[0], + volume: &DUNGEONS[DUNGEON_RAND.get(seed) as usize % DUNGEONS.len()], }), }) } else { diff --git a/world/src/lib.rs b/world/src/lib.rs index f3db6fa281..b93b4bdcca 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -131,7 +131,7 @@ impl World { }; const SPAWN_RATE: f32 = 0.1; - const BOSS_RATE: f32 = 0.1; + const BOSS_RATE: f32 = 0.03; let supplement = ChunkSupplement { npcs: if rand::thread_rng().gen::() < SPAWN_RATE && sim_chunk.chaos < 0.5 { vec![NpcInfo {