mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Reduced downward fall of birds, Humanoid travelers no longer visit dungeons, birds only travel between dungeons
This commit is contained in:
parent
40a301cbf6
commit
ae366e03c5
@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Map indicators for group members
|
||||
- Hot-reloading for i18n, sounds, loot lotteries, and more
|
||||
- Initial support for alternate style keyboards
|
||||
- Flying birds travel the world
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -71,6 +71,8 @@ pub struct TraversalConfig {
|
||||
pub min_tgt_dist: f32,
|
||||
/// Whether the agent can climb.
|
||||
pub can_climb: bool,
|
||||
/// Whether the agent can fly.
|
||||
pub can_fly: bool,
|
||||
}
|
||||
|
||||
const DIAGONALS: [Vec2<i32>; 8] = [
|
||||
@ -427,7 +429,7 @@ impl Chaser {
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
if !walking_towards_edge {
|
||||
if !walking_towards_edge || traversal_cfg.can_fly {
|
||||
Some(((tgt - pos) * Vec3::new(1.0, 1.0, 0.0), 1.0))
|
||||
} else {
|
||||
None
|
||||
@ -545,14 +547,14 @@ where
|
||||
.filter(|_| {
|
||||
vol.get(pos).map(|b| !b.is_liquid()).unwrap_or(true)
|
||||
|| traversal_cfg.can_climb
|
||||
|| traversal_cfg.can_fly
|
||||
})
|
||||
.into_iter()
|
||||
.flatten(),
|
||||
)
|
||||
.map(move |dir| (pos, dir))
|
||||
.filter(move |(pos, dir)| {
|
||||
is_walkable(pos)
|
||||
&& is_walkable(&(*pos + **dir))
|
||||
(traversal_cfg.can_fly || is_walkable(pos) && is_walkable(&(*pos + **dir)))
|
||||
&& ((dir.z < 1
|
||||
|| vol
|
||||
.get(pos + Vec3::unit_z() * 2)
|
||||
|
@ -212,6 +212,7 @@ impl<'a> System<'a> for Sys {
|
||||
in_liquid: physics_state.in_liquid.is_some(),
|
||||
min_tgt_dist: 1.0,
|
||||
can_climb: body.map(|b| b.can_climb()).unwrap_or(false),
|
||||
can_fly: body.map(|b| b.can_fly()).unwrap_or(false),
|
||||
};
|
||||
|
||||
let mut do_idle = false;
|
||||
@ -221,6 +222,8 @@ 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 it has an rtsim destination and can fly then it should
|
||||
inputs.fly.set_state(traversal_config.can_fly);
|
||||
if let Some((bearing, speed)) =
|
||||
chaser.chase(&*terrain, pos.0, vel.0, travel_to, TraversalConfig {
|
||||
min_tgt_dist: 1.25,
|
||||
@ -230,10 +233,31 @@ impl<'a> System<'a> for Sys {
|
||||
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.jump.set_state(bearing.z > 1.5 || traversal_config.can_fly && traversal_config.on_ground);
|
||||
inputs.climb = Some(comp::Climb::Up);
|
||||
//.filter(|_| bearing.z > 0.1 || physics_state.in_liquid.is_some());
|
||||
inputs.move_z = bearing.z + 0.05;
|
||||
|
||||
inputs.move_z = bearing.z + if traversal_config.can_fly {
|
||||
if terrain
|
||||
.ray(
|
||||
pos.0 + Vec3::unit_z(),
|
||||
pos.0
|
||||
+ bearing
|
||||
.try_normalized()
|
||||
.unwrap_or(Vec3::unit_y())
|
||||
* 60.0
|
||||
+ Vec3::unit_z(),
|
||||
)
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.1
|
||||
.map_or(true, |b| b.is_some())
|
||||
{
|
||||
1.0 //fly up when approaching obstacles
|
||||
} else { -0.1 } //flying things should slowly come down from the stratosphere
|
||||
} else {
|
||||
0.05 //normal land traveller offset
|
||||
};
|
||||
}
|
||||
} else {
|
||||
*bearing += Vec2::new(
|
||||
|
@ -20,15 +20,42 @@ const PERM_SPECIES: u32 = 0;
|
||||
const PERM_BODY: u32 = 1;
|
||||
const PERM_LOADOUT: u32 = 2;
|
||||
const PERM_LEVEL: u32 = 3;
|
||||
const PERM_GENUS: u32 = 4;
|
||||
|
||||
impl Entity {
|
||||
pub fn rng(&self, perm: u32) -> impl Rng { RandomPerm::new(self.seed + perm) }
|
||||
|
||||
pub fn get_body(&self) -> comp::Body {
|
||||
let species = *(&comp::humanoid::ALL_SPECIES)
|
||||
.choose(&mut self.rng(PERM_SPECIES))
|
||||
.unwrap();
|
||||
comp::humanoid::Body::random_with(&mut self.rng(PERM_BODY), &species).into()
|
||||
match self.rng(PERM_GENUS).gen::<f32>() {
|
||||
//we want 75% birds, 25% humans for now
|
||||
x if x < 0.75 => {
|
||||
let species = *(&comp::bird_medium::ALL_SPECIES)
|
||||
.choose(&mut self.rng(PERM_SPECIES))
|
||||
.unwrap();
|
||||
comp::bird_medium::Body::random_with(&mut self.rng(PERM_BODY), &species).into()
|
||||
},
|
||||
_ => {
|
||||
let species = *(&comp::humanoid::ALL_SPECIES)
|
||||
.choose(&mut self.rng(PERM_SPECIES))
|
||||
.unwrap();
|
||||
comp::humanoid::Body::random_with(&mut self.rng(PERM_BODY), &species).into()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> String {
|
||||
use common::{generation::get_npc_name, npc::NPC_NAMES};
|
||||
let npc_names = NPC_NAMES.read();
|
||||
match self.get_body() {
|
||||
comp::Body::BirdMedium(b) => {
|
||||
get_npc_name(&npc_names.bird_medium, b.species).to_string()
|
||||
},
|
||||
comp::Body::BirdSmall(_) => "Warbler".to_string(),
|
||||
comp::Body::Dragon(b) => get_npc_name(&npc_names.dragon, b.species).to_string(),
|
||||
comp::Body::Humanoid(b) => get_npc_name(&npc_names.humanoid, b.species).to_string(),
|
||||
//TODO: finish match as necessary
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_level(&self) -> u32 {
|
||||
@ -102,6 +129,10 @@ impl Entity {
|
||||
.civs()
|
||||
.sites
|
||||
.iter()
|
||||
.filter(|s| match self.get_body() {
|
||||
comp::Body::Humanoid(_) => s.1.is_settlement() | s.1.is_castle(),
|
||||
_ => s.1.is_dungeon(),
|
||||
})
|
||||
.filter(|_| thread_rng().gen_range(0i32, 4) == 0)
|
||||
.min_by_key(|(_, site)| {
|
||||
let wpos = site.center * TerrainChunk::RECT_SIZE.map(|e| e as i32);
|
||||
|
@ -88,7 +88,7 @@ pub fn init(state: &mut State, #[cfg(feature = "worldgen")] world: &world::World
|
||||
#[cfg(not(feature = "worldgen"))]
|
||||
let mut rtsim = RtSim::new(Vec2::new(40, 40));
|
||||
|
||||
for _ in 0..2500 {
|
||||
for _ in 0..10000 {
|
||||
let pos = rtsim
|
||||
.chunks
|
||||
.size()
|
||||
|
@ -98,13 +98,23 @@ impl<'a> System<'a> for Sys {
|
||||
let body = entity.get_body();
|
||||
server_emitter.emit(ServerEvent::CreateNpc {
|
||||
pos: comp::Pos(spawn_pos),
|
||||
stats: comp::Stats::new("Traveller".to_string(), body)
|
||||
.with_level(entity.get_level()),
|
||||
stats: comp::Stats::new(entity.get_name(), body).with_level(entity.get_level()),
|
||||
health: comp::Health::new(body, 10),
|
||||
loadout: entity.get_loadout(&ability_map),
|
||||
loadout: match body {
|
||||
comp::Body::Humanoid(_) => entity.get_loadout(&ability_map),
|
||||
_ => comp::Loadout::default(),
|
||||
},
|
||||
body,
|
||||
agent: Some(comp::Agent::new(None, true, &body, false)),
|
||||
alignment: comp::Alignment::Npc,
|
||||
agent: Some(comp::Agent::new(
|
||||
None,
|
||||
matches!(body, comp::Body::Humanoid(_)),
|
||||
&body,
|
||||
false,
|
||||
)),
|
||||
alignment: match body {
|
||||
comp::Body::Humanoid(_) => comp::Alignment::Npc,
|
||||
_ => comp::Alignment::Wild,
|
||||
},
|
||||
scale: comp::Scale(1.0),
|
||||
drop_item: None,
|
||||
home_chunk: None,
|
||||
|
@ -1071,6 +1071,12 @@ impl Site {
|
||||
};
|
||||
self.population += years * self.population * (birth_rate - DEATH_RATE);
|
||||
}
|
||||
|
||||
pub fn is_dungeon(&self) -> bool { matches!(self.kind, SiteKind::Dungeon) }
|
||||
|
||||
pub fn is_settlement(&self) -> bool { matches!(self.kind, SiteKind::Settlement) }
|
||||
|
||||
pub fn is_castle(&self) -> bool { matches!(self.kind, SiteKind::Castle) }
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
|
Loading…
Reference in New Issue
Block a user