mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Remove Actor and use Body instead
This commit is contained in:
parent
b1a7a61d77
commit
14400f6380
@ -4,18 +4,13 @@ pub mod quadruped_medium;
|
||||
|
||||
use specs::{Component, FlaggedStorage, VecStorage};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Actor {
|
||||
Character { name: String, body: Body },
|
||||
}
|
||||
|
||||
impl Component for Actor {
|
||||
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Body {
|
||||
Humanoid(humanoid::Body),
|
||||
Quadruped(quadruped::Body),
|
||||
QuadrupedMedium(quadruped_medium::Body),
|
||||
}
|
||||
|
||||
impl Component for Body {
|
||||
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ mod stats;
|
||||
pub use action_state::ActionState;
|
||||
pub use agent::Agent;
|
||||
pub use animation::{Animation, AnimationInfo};
|
||||
pub use body::{humanoid, quadruped, quadruped_medium, Actor, Body};
|
||||
pub use body::{humanoid, quadruped, quadruped_medium, Body};
|
||||
pub use controller::Controller;
|
||||
pub use inputs::{Attacking, Gliding, Jumping, MoveDir, OnGround, Respawning, Rolling};
|
||||
pub use inventory::{item, Inventory};
|
||||
|
@ -5,6 +5,7 @@ use specs::{Component, FlaggedStorage, VecStorage};
|
||||
pub enum HealthSource {
|
||||
Attack { by: Uid }, // TODO: Implement weapon
|
||||
Suicide,
|
||||
Revive,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
@ -23,18 +24,20 @@ impl Health {
|
||||
self.maximum
|
||||
}
|
||||
pub fn set_to(&mut self, amount: u32, cause: HealthSource) {
|
||||
let amount = amount.min(self.maximum);
|
||||
self.last_change = Some((amount as i32 - self.current as i32, 0.0, cause));
|
||||
self.current = amount;
|
||||
}
|
||||
pub fn change_by(&mut self, amount: i32, cause: HealthSource) {
|
||||
self.current = (self.current as i32 + amount).max(0) as u32;
|
||||
self.current = ((self.current as i32 + amount).max(0) as u32).min(self.maximum);
|
||||
self.last_change = Some((amount, 0.0, cause));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Stats {
|
||||
pub hp: Health,
|
||||
pub name: String,
|
||||
pub health: Health,
|
||||
pub xp: u32,
|
||||
pub is_dead: bool,
|
||||
}
|
||||
@ -42,14 +45,15 @@ pub struct Stats {
|
||||
impl Stats {
|
||||
pub fn should_die(&self) -> bool {
|
||||
// TODO: Remove
|
||||
self.hp.current == 0
|
||||
self.health.current == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Stats {
|
||||
fn default() -> Self {
|
||||
impl Stats {
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
hp: Health {
|
||||
name,
|
||||
health: Health {
|
||||
current: 100,
|
||||
maximum: 100,
|
||||
last_change: None,
|
||||
|
@ -20,7 +20,7 @@ sphynx::sum_type! {
|
||||
Pos(comp::Pos),
|
||||
Vel(comp::Vel),
|
||||
Ori(comp::Ori),
|
||||
Actor(comp::Actor),
|
||||
Body(comp::Body),
|
||||
Player(comp::Player),
|
||||
Stats(comp::Stats),
|
||||
}
|
||||
@ -33,7 +33,7 @@ sphynx::sum_type! {
|
||||
Pos(PhantomData<comp::Pos>),
|
||||
Vel(PhantomData<comp::Vel>),
|
||||
Ori(PhantomData<comp::Ori>),
|
||||
Actor(PhantomData<comp::Actor>),
|
||||
Body(PhantomData<comp::Body>),
|
||||
Player(PhantomData<comp::Player>),
|
||||
Stats(PhantomData<comp::Stats>),
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ impl State {
|
||||
// Create a new Sphynx ECS world.
|
||||
fn setup_sphynx_world(ecs: &mut sphynx::World<EcsCompPacket, EcsResPacket>) {
|
||||
// Register server->client synced components.
|
||||
ecs.register_synced::<comp::Actor>();
|
||||
ecs.register_synced::<comp::Body>();
|
||||
ecs.register_synced::<comp::Player>();
|
||||
ecs.register_synced::<comp::Stats>();
|
||||
|
||||
|
@ -52,7 +52,9 @@ impl<'a> System<'a> for Sys {
|
||||
&& ori.0.angle_between(pos_b.0 - pos.0).to_degrees() < 70.0
|
||||
{
|
||||
// Deal damage
|
||||
stat_b.hp.change_by(-10, HealthSource::Attack { by: *uid }); // TODO: variable damage and weapon
|
||||
stat_b
|
||||
.health
|
||||
.change_by(-10, HealthSource::Attack { by: *uid }); // TODO: variable damage and weapon
|
||||
vel_b.0 += (pos_b.0 - pos.0).normalized() * 10.0;
|
||||
vel_b.0.z = 15.0;
|
||||
let _ = force_updates.insert(b, ForceUpdate);
|
||||
|
@ -22,7 +22,7 @@ impl<'a> System<'a> for Sys {
|
||||
if let Err(err) = dyings.insert(
|
||||
entity,
|
||||
Dying {
|
||||
cause: match stat.hp.last_change {
|
||||
cause: match stat.health.last_change {
|
||||
Some(change) => change.2,
|
||||
None => {
|
||||
warn!("Nothing caused an entity to die!");
|
||||
@ -35,7 +35,7 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
stat.is_dead = true;
|
||||
}
|
||||
if let Some(change) = &mut stat.hp.last_change {
|
||||
if let Some(change) = &mut stat.health.last_change {
|
||||
change.1 += dt.0 as f64;
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ fn handle_kill(server: &mut Server, entity: EcsEntity, _args: String, _action: &
|
||||
.ecs_mut()
|
||||
.write_storage::<comp::Stats>()
|
||||
.get_mut(entity)
|
||||
.map(|s| s.hp.set_to(0, comp::HealthSource::Suicide));
|
||||
.map(|s| s.health.set_to(0, comp::HealthSource::Suicide));
|
||||
}
|
||||
|
||||
fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
||||
|
@ -146,8 +146,8 @@ impl Server {
|
||||
.with(comp::Vel(Vec3::zero()))
|
||||
.with(comp::Ori(Vec3::unit_y()))
|
||||
.with(comp::Controller::default())
|
||||
.with(comp::Actor::Character { name, body })
|
||||
.with(comp::Stats::default())
|
||||
.with(body)
|
||||
.with(comp::Stats::new(name))
|
||||
.with(comp::ActionState::default())
|
||||
.with(comp::ForceUpdate)
|
||||
}
|
||||
@ -161,8 +161,8 @@ impl Server {
|
||||
) {
|
||||
let spawn_point = state.ecs().read_resource::<SpawnPoint>().0;
|
||||
|
||||
state.write_component(entity, comp::Actor::Character { name, body });
|
||||
state.write_component(entity, comp::Stats::default());
|
||||
state.write_component(entity, body);
|
||||
state.write_component(entity, comp::Stats::new(name));
|
||||
state.write_component(entity, comp::Controller::default());
|
||||
state.write_component(entity, comp::Pos(spawn_point));
|
||||
state.write_component(entity, comp::Vel(Vec3::zero()));
|
||||
@ -677,9 +677,7 @@ impl Server {
|
||||
self.state.write_component(entity, comp::ForceUpdate);
|
||||
client.force_state(ClientState::Dead);
|
||||
} else {
|
||||
if let Err(err) = self.state.ecs_mut().delete_entity_synced(entity) {
|
||||
warn!("Failed to delete client not found in kill list: {:?}", err);
|
||||
}
|
||||
let _ = self.state.ecs_mut().delete_entity_synced(entity);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -696,14 +694,20 @@ impl Server {
|
||||
for entity in todo_respawn {
|
||||
if let Some(client) = self.clients.get_mut(&entity) {
|
||||
client.allow_state(ClientState::Character);
|
||||
self.state.write_component(entity, comp::Stats::default());
|
||||
self.state
|
||||
.ecs_mut()
|
||||
.write_storage::<comp::Stats>()
|
||||
.get_mut(entity)
|
||||
.map(|stats| {
|
||||
stats
|
||||
.health
|
||||
.set_to(stats.health.get_maximum(), comp::HealthSource::Revive)
|
||||
});
|
||||
self.state
|
||||
.ecs_mut()
|
||||
.write_storage::<comp::Pos>()
|
||||
.get_mut(entity)
|
||||
.map(|pos| pos.0.z += 100.0);
|
||||
self.state.write_component(entity, comp::Vel(Vec3::zero()));
|
||||
self.state.write_component(entity, comp::ForceUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,6 @@ impl Hud {
|
||||
// Nametags and healthbars
|
||||
if self.show.ingame {
|
||||
let ecs = client.state().ecs();
|
||||
let actor = ecs.read_storage::<comp::Actor>();
|
||||
let pos = ecs.read_storage::<comp::Pos>();
|
||||
let stats = ecs.read_storage::<comp::Stats>();
|
||||
let player = ecs.read_storage::<comp::Player>();
|
||||
@ -333,29 +332,25 @@ impl Hud {
|
||||
let mut health_back_id_walker = self.ids.health_bar_backs.walk();
|
||||
|
||||
// Render Name Tags
|
||||
for (pos, name) in (&entities, &pos, &actor, &stats, player.maybe())
|
||||
for (pos, name) in (&entities, &pos, &stats, player.maybe())
|
||||
.join()
|
||||
.filter(|(entity, _, _, stats, _)| *entity != me && !stats.is_dead)
|
||||
.filter(|(entity, _, stats, _)| *entity != me && !stats.is_dead)
|
||||
// Don't process nametags outside the vd (visibility further limited by ui backend)
|
||||
.filter(|(_, pos, _, _, _)| {
|
||||
.filter(|(_, pos, _, _)| {
|
||||
(pos.0 - player_pos)
|
||||
.map2(TerrainChunkSize::SIZE, |d, sz| d.abs() as f32 / sz as f32)
|
||||
.magnitude()
|
||||
< view_distance as f32
|
||||
})
|
||||
.map(|(_, pos, actor, _, player)| match actor {
|
||||
comp::Actor::Character {
|
||||
name: char_name, ..
|
||||
} => {
|
||||
// Temporary
|
||||
// If the player used the default character name display their name instead
|
||||
let name = if char_name == "Character Name" {
|
||||
player.map_or(char_name, |p| &p.alias)
|
||||
} else {
|
||||
char_name
|
||||
};
|
||||
(pos.0, name)
|
||||
}
|
||||
.map(|(_, pos, stats, player)| {
|
||||
// TODO: This is temporary
|
||||
// If the player used the default character name display their name instead
|
||||
let name = if stats.name == "Character Name" {
|
||||
player.map_or(&stats.name, |p| &p.alias)
|
||||
} else {
|
||||
&stats.name
|
||||
};
|
||||
(pos.0, name)
|
||||
})
|
||||
{
|
||||
let id = name_id_walker.next(
|
||||
@ -377,7 +372,7 @@ impl Hud {
|
||||
.filter(|(entity, _, stats)| {
|
||||
*entity != me
|
||||
&& !stats.is_dead
|
||||
&& stats.hp.get_current() != stats.hp.get_maximum()
|
||||
&& stats.health.get_current() != stats.health.get_maximum()
|
||||
})
|
||||
// Don't process health bars outside the vd (visibility further limited by ui backend)
|
||||
.filter(|(_, pos, _)| {
|
||||
@ -405,7 +400,9 @@ impl Hud {
|
||||
// % HP Filling
|
||||
Rectangle::fill_with(
|
||||
[
|
||||
120.0 * (stats.hp.get_current() as f64 / stats.hp.get_maximum() as f64),
|
||||
120.0
|
||||
* (stats.health.get_current() as f64
|
||||
/ stats.health.get_maximum() as f64),
|
||||
8.0,
|
||||
],
|
||||
HP_COLOR,
|
||||
@ -545,14 +542,14 @@ impl Hud {
|
||||
|
||||
// Skillbar
|
||||
// Get player stats
|
||||
let stats = client
|
||||
if let Some(stats) = client
|
||||
.state()
|
||||
.ecs()
|
||||
.read_storage::<comp::Stats>()
|
||||
.get(client.entity())
|
||||
.map(|&s| s)
|
||||
.unwrap_or_default();
|
||||
Skillbar::new(&self.imgs, &self.fonts, stats).set(self.ids.skillbar, ui_widgets);
|
||||
{
|
||||
Skillbar::new(&self.imgs, &self.fonts, stats).set(self.ids.skillbar, ui_widgets);
|
||||
}
|
||||
|
||||
// Chat box
|
||||
match Chat::new(&mut self.new_messages, &self.imgs, &self.fonts)
|
||||
|
@ -31,14 +31,14 @@ pub struct Skillbar<'a> {
|
||||
imgs: &'a Imgs,
|
||||
fonts: &'a Fonts,
|
||||
|
||||
stats: Stats,
|
||||
stats: &'a Stats,
|
||||
|
||||
#[conrod(common_builder)]
|
||||
common: widget::CommonBuilder,
|
||||
}
|
||||
|
||||
impl<'a> Skillbar<'a> {
|
||||
pub fn new(imgs: &'a Imgs, fonts: &'a Fonts, stats: Stats) -> Self {
|
||||
pub fn new(imgs: &'a Imgs, fonts: &'a Fonts, stats: &'a Stats) -> Self {
|
||||
Self {
|
||||
imgs,
|
||||
fonts,
|
||||
@ -78,7 +78,8 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
let next_level_xp = (level as f64).powi(4) - start_level_xp;
|
||||
// TODO: We need a max xp value
|
||||
let xp_percentage = (self.stats.xp as f64 - start_level_xp) / next_level_xp;
|
||||
let hp_percentage = self.stats.hp.get_current() as f64 / self.stats.hp.get_maximum() as f64;
|
||||
let hp_percentage =
|
||||
self.stats.health.get_current() as f64 / self.stats.health.get_maximum() as f64;
|
||||
let mana_percentage = 1.0;
|
||||
|
||||
// TODO: Only show while aiming with a bow or when casting a spell.
|
||||
|
@ -551,12 +551,12 @@ impl FigureMgr {
|
||||
.get(client.entity())
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
|
||||
for (entity, pos, vel, ori, actor, animation_info, stats) in (
|
||||
for (entity, pos, vel, ori, body, animation_info, stats) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<comp::Pos>(),
|
||||
&ecs.read_storage::<comp::Vel>(),
|
||||
&ecs.read_storage::<comp::Ori>(),
|
||||
&ecs.read_storage::<comp::Actor>(),
|
||||
&ecs.read_storage::<comp::Body>(),
|
||||
&ecs.read_storage::<comp::AnimationInfo>(),
|
||||
ecs.read_storage::<comp::Stats>().maybe(),
|
||||
)
|
||||
@ -569,18 +569,16 @@ impl FigureMgr {
|
||||
/ view_distance as f32;
|
||||
// Keep from re-adding/removing entities on the border of the vd
|
||||
if vd_frac > 1.2 {
|
||||
match actor {
|
||||
comp::Actor::Character { body, .. } => match body {
|
||||
Body::Humanoid(_) => {
|
||||
self.character_states.remove(&entity);
|
||||
}
|
||||
Body::Quadruped(_) => {
|
||||
self.quadruped_states.remove(&entity);
|
||||
}
|
||||
Body::QuadrupedMedium(_) => {
|
||||
self.quadruped_medium_states.remove(&entity);
|
||||
}
|
||||
},
|
||||
match body {
|
||||
Body::Humanoid(_) => {
|
||||
self.character_states.remove(&entity);
|
||||
}
|
||||
Body::Quadruped(_) => {
|
||||
self.quadruped_states.remove(&entity);
|
||||
}
|
||||
Body::QuadrupedMedium(_) => {
|
||||
self.quadruped_medium_states.remove(&entity);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else if vd_frac > 1.0 {
|
||||
@ -589,7 +587,7 @@ impl FigureMgr {
|
||||
|
||||
// Change in health as color!
|
||||
let col = stats
|
||||
.and_then(|stats| stats.hp.last_change)
|
||||
.and_then(|stats| stats.health.last_change)
|
||||
.map(|(_, time, _)| {
|
||||
Rgba::broadcast(1.0)
|
||||
+ Rgba::new(0.0, -1.0, -1.0, 0.0)
|
||||
@ -597,170 +595,150 @@ impl FigureMgr {
|
||||
})
|
||||
.unwrap_or(Rgba::broadcast(1.0));
|
||||
|
||||
match actor {
|
||||
comp::Actor::Character { body, .. } => {
|
||||
let skeleton_attr = &self
|
||||
.model_cache
|
||||
.get_or_create_model(renderer, *body, tick)
|
||||
.1;
|
||||
let skeleton_attr = &self
|
||||
.model_cache
|
||||
.get_or_create_model(renderer, *body, tick)
|
||||
.1;
|
||||
|
||||
match body {
|
||||
Body::Humanoid(_) => {
|
||||
let state = self.character_states.entry(entity).or_insert_with(|| {
|
||||
FigureState::new(renderer, CharacterSkeleton::new())
|
||||
});
|
||||
match body {
|
||||
Body::Humanoid(_) => {
|
||||
let state = self
|
||||
.character_states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| FigureState::new(renderer, CharacterSkeleton::new()));
|
||||
|
||||
let target_skeleton = match animation_info.animation {
|
||||
comp::Animation::Idle => {
|
||||
anim::character::IdleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Run => {
|
||||
anim::character::RunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Jump => {
|
||||
anim::character::JumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Attack => {
|
||||
anim::character::AttackAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Roll => {
|
||||
anim::character::RollAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Crun => {
|
||||
anim::character::CrunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Cidle => {
|
||||
anim::character::CidleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Gliding => {
|
||||
anim::character::GlidingAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
state.skeleton.interpolate(&target_skeleton, dt);
|
||||
state.update(renderer, pos.0, ori.0, col, dt);
|
||||
let target_skeleton = match animation_info.animation {
|
||||
comp::Animation::Idle => anim::character::IdleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Run => anim::character::RunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Jump => anim::character::JumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Attack => {
|
||||
anim::character::AttackAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
Body::Quadruped(_) => {
|
||||
let state = self.quadruped_states.entry(entity).or_insert_with(|| {
|
||||
FigureState::new(renderer, QuadrupedSkeleton::new())
|
||||
});
|
||||
|
||||
let target_skeleton = match animation_info.animation {
|
||||
comp::Animation::Run => {
|
||||
anim::quadruped::RunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Idle => {
|
||||
anim::quadruped::IdleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Jump => {
|
||||
anim::quadruped::JumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO!
|
||||
_ => state.skeleton_mut().clone(),
|
||||
};
|
||||
|
||||
state.skeleton.interpolate(&target_skeleton, dt);
|
||||
state.update(renderer, pos.0, ori.0, col, dt);
|
||||
comp::Animation::Roll => anim::character::RollAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Crun => anim::character::CrunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Cidle => anim::character::CidleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Gliding => {
|
||||
anim::character::GlidingAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
Body::QuadrupedMedium(_) => {
|
||||
let state =
|
||||
self.quadruped_medium_states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| {
|
||||
FigureState::new(renderer, QuadrupedMediumSkeleton::new())
|
||||
});
|
||||
};
|
||||
|
||||
let target_skeleton = match animation_info.animation {
|
||||
comp::Animation::Run => {
|
||||
anim::quadrupedmedium::RunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Idle => {
|
||||
anim::quadrupedmedium::IdleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Jump => {
|
||||
anim::quadrupedmedium::JumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
state.skeleton.interpolate(&target_skeleton, dt);
|
||||
state.update(renderer, pos.0, ori.0, col, dt);
|
||||
}
|
||||
Body::Quadruped(_) => {
|
||||
let state = self
|
||||
.quadruped_states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| FigureState::new(renderer, QuadrupedSkeleton::new()));
|
||||
|
||||
// TODO!
|
||||
_ => state.skeleton_mut().clone(),
|
||||
};
|
||||
let target_skeleton = match animation_info.animation {
|
||||
comp::Animation::Run => anim::quadruped::RunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Idle => anim::quadruped::IdleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Jump => anim::quadruped::JumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
|
||||
state.skeleton.interpolate(&target_skeleton, dt);
|
||||
state.update(renderer, pos.0, ori.0, col, dt);
|
||||
// TODO!
|
||||
_ => state.skeleton_mut().clone(),
|
||||
};
|
||||
|
||||
state.skeleton.interpolate(&target_skeleton, dt);
|
||||
state.update(renderer, pos.0, ori.0, col, dt);
|
||||
}
|
||||
Body::QuadrupedMedium(_) => {
|
||||
let state = self
|
||||
.quadruped_medium_states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| {
|
||||
FigureState::new(renderer, QuadrupedMediumSkeleton::new())
|
||||
});
|
||||
|
||||
let target_skeleton = match animation_info.animation {
|
||||
comp::Animation::Run => {
|
||||
anim::quadrupedmedium::RunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
}
|
||||
} // TODO: Non-character actors
|
||||
comp::Animation::Idle => {
|
||||
anim::quadrupedmedium::IdleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Jump => {
|
||||
anim::quadrupedmedium::JumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO!
|
||||
_ => state.skeleton_mut().clone(),
|
||||
};
|
||||
|
||||
state.skeleton.interpolate(&target_skeleton, dt);
|
||||
state.update(renderer, pos.0, ori.0, col, dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,12 +769,12 @@ impl FigureMgr {
|
||||
.get(client.entity())
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
|
||||
for (entity, _, _, _, actor, _, _) in (
|
||||
for (entity, _, _, _, body, _, _) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<comp::Pos>(),
|
||||
&ecs.read_storage::<comp::Vel>(),
|
||||
&ecs.read_storage::<comp::Ori>(),
|
||||
&ecs.read_storage::<comp::Actor>(),
|
||||
&ecs.read_storage::<comp::Body>(),
|
||||
&ecs.read_storage::<comp::AnimationInfo>(),
|
||||
ecs.read_storage::<comp::Stats>().maybe(),
|
||||
)
|
||||
@ -811,32 +789,28 @@ impl FigureMgr {
|
||||
// Don't render dead entities
|
||||
.filter(|(_, _, _, _, _, _, stats)| stats.map_or(true, |s| !s.is_dead))
|
||||
{
|
||||
match actor {
|
||||
comp::Actor::Character { body, .. } => {
|
||||
if let Some((locals, bone_consts)) = match body {
|
||||
Body::Humanoid(_) => self
|
||||
.character_states
|
||||
.get(&entity)
|
||||
.map(|state| (state.locals(), state.bone_consts())),
|
||||
Body::Quadruped(_) => self
|
||||
.quadruped_states
|
||||
.get(&entity)
|
||||
.map(|state| (state.locals(), state.bone_consts())),
|
||||
Body::QuadrupedMedium(_) => self
|
||||
.quadruped_medium_states
|
||||
.get(&entity)
|
||||
.map(|state| (state.locals(), state.bone_consts())),
|
||||
} {
|
||||
let model = &self
|
||||
.model_cache
|
||||
.get_or_create_model(renderer, *body, tick)
|
||||
.0;
|
||||
if let Some((locals, bone_consts)) = match body {
|
||||
Body::Humanoid(_) => self
|
||||
.character_states
|
||||
.get(&entity)
|
||||
.map(|state| (state.locals(), state.bone_consts())),
|
||||
Body::Quadruped(_) => self
|
||||
.quadruped_states
|
||||
.get(&entity)
|
||||
.map(|state| (state.locals(), state.bone_consts())),
|
||||
Body::QuadrupedMedium(_) => self
|
||||
.quadruped_medium_states
|
||||
.get(&entity)
|
||||
.map(|state| (state.locals(), state.bone_consts())),
|
||||
} {
|
||||
let model = &self
|
||||
.model_cache
|
||||
.get_or_create_model(renderer, *body, tick)
|
||||
.0;
|
||||
|
||||
renderer.render_figure(model, globals, locals, bone_consts);
|
||||
} else {
|
||||
warn!("Body has no saved figure");
|
||||
}
|
||||
}
|
||||
renderer.render_figure(model, globals, locals, bone_consts);
|
||||
} else {
|
||||
warn!("Body has no saved figure");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user