adjusted run animation to allow villager walking

This commit is contained in:
jshipsey 2020-04-18 23:56:14 -04:00 committed by Joshua Barretto
parent 9572c2eaad
commit a89b28e117
6 changed files with 77 additions and 67 deletions

View File

@ -1,15 +1,13 @@
use crate::comp::Alignment;
use vek::*;
use crate::{
comp::{self, Alignment, Body, Item, humanoid},
comp::{self, humanoid, Alignment, Body, Item},
npc::{self, NPC_NAMES},
};
use vek::*;
pub enum EntityTemplate {
Traveller,
}
pub struct EntityInfo {
pub pos: Vec3<f32>,
pub is_waypoint: bool, // Edge case, overrides everything else
@ -73,15 +71,22 @@ impl EntityInfo {
pub fn with_automatic_name(mut self) -> Self {
self.name = match &self.body {
Body::Humanoid(body) => Some(get_npc_name(&NPC_NAMES.humanoid, body.race)),
Body::QuadrupedMedium(body) => Some(get_npc_name(&NPC_NAMES.quadruped_medium, body.species)),
Body::QuadrupedMedium(body) => {
Some(get_npc_name(&NPC_NAMES.quadruped_medium, body.species))
},
Body::BirdMedium(body) => Some(get_npc_name(&NPC_NAMES.bird_medium, body.species)),
Body::Critter(body) => Some(get_npc_name(&NPC_NAMES.critter, body.species)),
Body::QuadrupedSmall(body) => Some(get_npc_name(&NPC_NAMES.quadruped_small, body.species)),
Body::QuadrupedSmall(body) => {
Some(get_npc_name(&NPC_NAMES.quadruped_small, body.species))
},
_ => None,
}.map(|s| if self.is_giant {
format!("Giant {}", s)
} else {
s.to_string()
}
.map(|s| {
if self.is_giant {
format!("Giant {}", s)
} else {
s.to_string()
}
});
self
}

View File

@ -110,7 +110,9 @@ impl<'a> System<'a> for Sys {
// Neighbouring blocks iterator
let near_iter = (-hdist..hdist + 1)
.map(move |i| {
(-hdist..hdist + 1).map(move |j| (1 - BlockKind::MAX_HEIGHT.ceil() as i32..vdist + 1).map(move |k| (i, j, k)))
(-hdist..hdist + 1).map(move |j| {
(1 - BlockKind::MAX_HEIGHT.ceil() as i32..vdist + 1).map(move |k| (i, j, k))
})
})
.flatten()
.flatten();
@ -161,7 +163,8 @@ impl<'a> System<'a> for Sys {
};
let block_aabb = Aabb {
min: block_pos.map(|e| e as f32),
max: block_pos.map(|e| e as f32) + Vec3::new(1.0, 1.0, block.get_height()),
max: block_pos.map(|e| e as f32)
+ Vec3::new(1.0, 1.0, block.get_height()),
};
if player_aabb.collides_with_aabb(block_aabb) {

View File

@ -58,6 +58,8 @@ pub enum BlockKind {
}
impl BlockKind {
pub const MAX_HEIGHT: f32 = 3.0;
pub fn is_tangible(&self) -> bool {
match self {
BlockKind::Air => false,
@ -217,12 +219,10 @@ impl BlockKind {
}
}
pub const MAX_HEIGHT: f32 = 3.0;
// TODO: Integrate this into `is_solid` by returning an `Option<f32>`
pub fn get_height(&self) -> f32 {
// Beware: the height *must* be <= `MAX_HEIGHT` or the collision system will not properly
// detect it!
// Beware: the height *must* be <= `MAX_HEIGHT` or the collision system will not
// properly detect it!
match self {
BlockKind::Tomato => 1.65,
BlockKind::LargeCactus => 2.5,

View File

@ -21,35 +21,45 @@ impl Animation for RunAnimation {
let speed = Vec2::<f32>::from(velocity).magnitude();
*rate = 1.0;
let walkintensity = if speed > 5.0 { 1.0 } else { 0.7 };
let walk = if speed > 5.0 { 1.0 } else { 0.5 };
let lower = if speed > 5.0 { 0.0 } else { 2.0 };
let walk = if speed > 5.0 { 1.0 } else { 0.5 };
let snapfoot = if speed > 5.0 { 1.1 } else { 2.0 };
let lab = 1.0;
let long = (((5.0)
/ (1.5 + 3.5 * ((anim_time as f32 * lab as f32 * 8.0).sin()).powf(2.0 as f32)))
/ (1.5 + 3.5 * ((anim_time as f32 * lab as f32 * 8.0 * walk).sin()).powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 * 8.0).sin());
* ((anim_time as f32 * lab as f32 * 8.0 * walk).sin());
let short = (((5.0)
/ (1.5 + 3.5 * ((anim_time as f32 * lab as f32 * 16.0).sin()).powf(2.0 as f32)))
/ (1.5
+ 3.5 * ((anim_time as f32 * lab as f32 * 16.0 * walk).sin()).powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 * 16.0).sin());
* ((anim_time as f32 * lab as f32 * 16.0 * walk).sin());
let noisea = (anim_time as f32 * 11.0 + PI / 6.0).sin();
let noiseb = (anim_time as f32 * 19.0 + PI / 4.0).sin();
let shorte = (((5.0)
/ (4.0 + 1.0 * ((anim_time as f32 * lab as f32 * 16.0).sin()).powf(2.0 as f32)))
/ (4.0
+ 1.0 * ((anim_time as f32 * lab as f32 * 16.0 * walk).sin()).powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 * 16.0).sin());
* ((anim_time as f32 * lab as f32 * 16.0 * walk).sin());
let shortalt = (((5.0)
/ (1.5
+ 3.5
* ((anim_time as f32 * lab as f32 * 16.0 + PI / 2.0).sin()).powf(2.0 as f32)))
* ((anim_time as f32 * lab as f32 * 16.0 * walk + PI / 2.0).sin())
.powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 * 16.0 + PI / 2.0).sin());
* ((anim_time as f32 * lab as f32 * 16.0 * walk + PI / 2.0).sin());
let foot = (((5.0)
/ (1.1 + 3.9 * ((anim_time as f32 * lab as f32 * 16.0).sin()).powf(2.0 as f32)))
/ (snapfoot
+ (5.0 - snapfoot)
* ((anim_time as f32 * lab as f32 * 16.0 * walk).sin()).powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 * 16.0).sin());
* ((anim_time as f32 * lab as f32 * 16.0 * walk).sin());
let wave_stop = (anim_time as f32 * 26.0).min(PI / 2.0 / 2.0).sin();
@ -89,8 +99,8 @@ impl Animation for RunAnimation {
* Quaternion::rotation_x(head_look.y + 0.35);
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
next.chest.offset = Vec3::new(0.0, 0.0, 10.5 + short * 1.1);
next.chest.ori = Quaternion::rotation_z(short * 0.3);
next.chest.offset = Vec3::new(0.0, 0.0, 10.5 + short * 1.1 - lower);
next.chest.ori = Quaternion::rotation_z(short * 0.3 * walkintensity);
next.chest.scale = Vec3::one();
next.belt.offset = Vec3::new(0.0, 0.0, -2.0);
@ -106,37 +116,37 @@ impl Animation for RunAnimation {
next.shorts.scale = Vec3::one();
next.l_hand.offset = Vec3::new(
-6.0 + wave_stop * -1.0,
-0.25 + short * 3.0,
5.0 + short * -1.5,
-6.0 + wave_stop * -1.0 * walkintensity,
-0.25 + short * 3.0 * walkintensity,
5.0 + short * -1.5 * walkintensity,
);
next.l_hand.ori =
Quaternion::rotation_x(0.8 + short * 1.2) * Quaternion::rotation_y(wave_stop * 0.1);
next.l_hand.ori = Quaternion::rotation_x(0.8 + short * 1.2 * walk)
* Quaternion::rotation_y(wave_stop * 0.1);
next.l_hand.scale = Vec3::one();
next.r_hand.offset = Vec3::new(
6.0 + wave_stop * 1.0,
-0.25 + short * -3.0,
5.0 + short * 1.5,
6.0 + wave_stop * 1.0 * walkintensity,
-0.25 + short * -3.0 * walkintensity,
5.0 + short * 1.5 * walkintensity,
);
next.r_hand.ori =
Quaternion::rotation_x(0.8 + short * -1.2) * Quaternion::rotation_y(wave_stop * -0.1);
next.r_hand.ori = Quaternion::rotation_x(0.8 + short * -1.2 * walk)
* Quaternion::rotation_y(wave_stop * -0.1);
next.r_hand.scale = Vec3::one();
next.l_foot.offset = Vec3::new(-3.4, foot * 1.0, 9.5);
next.l_foot.ori = Quaternion::rotation_x(foot * -1.2);
next.l_foot.ori = Quaternion::rotation_x(foot * -1.2 * walkintensity);
next.l_foot.scale = Vec3::one();
next.r_foot.offset = Vec3::new(3.4, foot * -1.0, 9.5);
next.r_foot.ori = Quaternion::rotation_x(foot * 1.2);
next.r_foot.ori = Quaternion::rotation_x(foot * 1.2 * walkintensity);
next.r_foot.scale = Vec3::one();
next.l_shoulder.offset = Vec3::new(-5.0, -1.0, 4.7);
next.l_shoulder.ori = Quaternion::rotation_x(short * 0.15);
next.l_shoulder.ori = Quaternion::rotation_x(short * 0.15 * walkintensity);
next.l_shoulder.scale = Vec3::one() * 1.1;
next.r_shoulder.offset = Vec3::new(5.0, -1.0, 4.7);
next.r_shoulder.ori = Quaternion::rotation_x(short * -0.15);
next.r_shoulder.ori = Quaternion::rotation_x(short * -0.15 * walkintensity);
next.r_shoulder.scale = Vec3::one() * 1.1;
next.glider.offset = Vec3::new(0.0, 0.0, 10.0);

View File

@ -20,10 +20,8 @@ use crate::{
util::{Grid, Sampler},
};
use common::{
comp::Alignment,
comp::{self, bird_medium, critter, humanoid, quadruped_medium, quadruped_small, Alignment},
generation::{ChunkSupplement, EntityInfo},
comp::{self, humanoid, quadruped_medium, bird_medium, critter, quadruped_small},
terrain::{Block, BlockKind, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
vol::{ReadVol, RectVolSize, Vox, WriteVol},
};
@ -163,18 +161,19 @@ impl World {
let mut rng = rand::thread_rng();
// Apply site generation
sim_chunk.sites.iter().for_each(|site| {
site.apply_to(
chunk_wpos2d,
sample_get,
&mut chunk,
)
});
sim_chunk
.sites
.iter()
.for_each(|site| site.apply_to(chunk_wpos2d, sample_get, &mut chunk));
let gen_entity_pos = || {
let lpos2d = TerrainChunkSize::RECT_SIZE
.map(|sz| rand::thread_rng().gen::<u32>().rem_euclid(sz) as i32);
let mut lpos = Vec3::new(lpos2d.x, lpos2d.y, sample_get(lpos2d).map(|s| s.alt as i32 - 32).unwrap_or(0));
let mut lpos = Vec3::new(
lpos2d.x,
lpos2d.y,
sample_get(lpos2d).map(|s| s.alt as i32 - 32).unwrap_or(0),
);
while chunk.get(lpos).map(|vox| !vox.is_empty()).unwrap_or(false) {
lpos.z += 1;
@ -213,12 +212,7 @@ impl World {
// Apply site supplementary information
sim_chunk.sites.iter().for_each(|site| {
site.apply_supplement(
&mut rng,
chunk_wpos2d,
sample_get,
&mut supplement,
)
site.apply_supplement(&mut rng, chunk_wpos2d, sample_get, &mut supplement)
});
Ok((chunk, supplement))

View File

@ -8,9 +8,9 @@ use crate::{
util::{Grid, RandomField, Sampler, StructureGen2d},
};
use common::{
comp::{self, humanoid, quadruped_medium, bird_medium, critter, quadruped_small},
generation::{ChunkSupplement, EntityInfo},
astar::Astar,
comp::{self, bird_medium, critter, humanoid, quadruped_medium, quadruped_small},
generation::{ChunkSupplement, EntityInfo},
path::Path,
spiral::Spiral2d,
store::{Id, Store},
@ -758,8 +758,8 @@ impl Settlement {
let entity_wpos = Vec3::new(wpos2d.x as f32, wpos2d.y as f32, col_sample.alt + 3.0);
if matches!(sample.plot, Some(Plot::Town)) &&
RandomField::new(self.seed).chance(Vec3::from(wpos2d), 1.0 / (50.0 * 50.0))
if matches!(sample.plot, Some(Plot::Town))
&& RandomField::new(self.seed).chance(Vec3::from(wpos2d), 1.0 / (50.0 * 50.0))
{
let entity = EntityInfo::at(entity_wpos)
.with_alignment(comp::Alignment::Npc)
@ -772,8 +772,7 @@ impl Settlement {
};
comp::Body::QuadrupedSmall(quadruped_small::Body::random_with(
rng,
&species,
rng, &species,
))
},
1 => {
@ -785,8 +784,7 @@ impl Settlement {
};
comp::Body::BirdMedium(bird_medium::Body::random_with(
rng,
&species,
rng, &species,
))
},
_ => comp::Body::Humanoid(humanoid::Body::random()),