diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index a96daa166c..61f198fc94 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -4,6 +4,7 @@ use crate::{ path::Chaser, state::Time, sync::UidAllocator, + vol::ReadVol, }; use rand::{seq::SliceRandom, thread_rng, Rng}; use specs::{ @@ -93,9 +94,29 @@ impl<'a> System<'a> for Sys { } else { Vec2::zero() }; + // Stop if we're too close to a wall + *bearing *= 0.1 + + if terrain + .ray( + pos.0 + Vec3::unit_z(), + pos.0 + + Vec3::from(*bearing).normalized() * 1.5 + + Vec3::unit_z(), + ) + .until(|block| block.is_solid()) + .cast() + .1 + .map(|b| b.is_none()) + .unwrap_or(true) + { + 0.9 + } else { + 0.0 + }; if bearing.magnitude_squared() > 0.25f32.powf(2.0) { - inputs.move_dir = bearing.normalized() * 0.65; + inputs.move_dir = + bearing.try_normalized().unwrap_or(Vec2::zero()) * 0.65; } // Sometimes try searching for new targets diff --git a/server/src/sys/terrain.rs b/server/src/sys/terrain.rs index f20c21dc32..b243a7b445 100644 --- a/server/src/sys/terrain.rs +++ b/server/src/sys/terrain.rs @@ -111,6 +111,14 @@ impl<'a> System<'a> for Sys { "Traveler".into(), comp::Body::Humanoid(comp::humanoid::Body::random()), Some(assets::load_expect_cloned("common.items.weapons.staff_1")), + comp::Alignment::Npc, + ) + }) as _, + (|| { + ( + "Bandit".into(), + comp::Body::Humanoid(comp::humanoid::Body::random()), + Some(assets::load_expect_cloned("common.items.weapons.staff_1")), comp::Alignment::Enemy, ) }) as _, @@ -147,7 +155,7 @@ impl<'a> System<'a> for Sys { ) }), ]; - let (name, mut body, main, alignment) = SPAWN_NPCS + let (name, mut body, main, mut alignment) = SPAWN_NPCS .choose(&mut rand::thread_rng()) .expect("SPAWN_NPCS is nonempty")( ); @@ -159,11 +167,11 @@ impl<'a> System<'a> for Sys { stats.level.set_level(rand::thread_rng().gen_range(1, 4)); if let EntityKind::Boss = entity.kind { - if rand::random::() < 0.8 { - let hbody = comp::humanoid::Body::random(); - body = comp::Body::Humanoid(hbody); + if rand::random::() < 0.65 { + body = comp::Body::Humanoid(comp::humanoid::Body::random()); + alignment = comp::Alignment::Npc; stats = comp::Stats::new( - "Fearless Wanderer".to_string(), + "Fearless Giant".to_string(), body, Some(assets::load_expect_cloned("common.items.weapons.hammer_1")), );