Added basic pets

Former-commit-id: 1ef17505ecb11acb82541349343989128b78630f
This commit is contained in:
Joshua Barretto 2019-05-11 13:43:19 +01:00
parent 5d8a03896a
commit 266101c90d
7 changed files with 90 additions and 21 deletions

View File

@ -1,16 +1,20 @@
use specs::{Component, VecStorage}; use specs::{Component, VecStorage, Entity as EcsEntity};
use vek::*; use vek::*;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)] #[derive(Copy, Clone, Debug)]
pub enum Agent { pub enum Agent {
Wanderer(Vec2<f32>), Wanderer(Vec2<f32>),
Pet {
target: EcsEntity,
offset: Vec2<f32>,
},
} }
impl Component for Agent { impl Component for Agent {
type Storage = VecStorage<Self>; type Storage = VecStorage<Self>;
} }
#[derive(Copy, Clone, Debug, Serialize, Deserialize)] #[derive(Copy, Clone, Debug)]
pub struct Control { pub struct Control {
pub move_dir: Vec2<f32>, pub move_dir: Vec2<f32>,
pub jumping: bool, pub jumping: bool,

View File

@ -116,6 +116,16 @@ pub struct AnimationHistory {
pub time: f64, pub time: f64,
} }
impl AnimationHistory {
pub fn new(animation: Animation) -> Self {
Self {
last: None,
current: animation,
time: 0.0,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Animation { pub enum Animation {
Idle, Idle,

View File

@ -15,13 +15,13 @@ impl<'a> System<'a> for Sys {
WriteStorage<'a, Control>, WriteStorage<'a, Control>,
); );
fn run(&mut self, (mut agents, pos, mut controls): Self::SystemData) { fn run(&mut self, (mut agents, positions, mut controls): Self::SystemData) {
for (mut agent, pos, mut control) in (&mut agents, &pos, &mut controls).join() { for (mut agent, pos, mut control) in (&mut agents, &positions, &mut controls).join() {
match agent { match agent {
Agent::Wanderer(bearing) => { Agent::Wanderer(bearing) => {
*bearing += Vec2::new( *bearing += Vec2::new(
rand::random::<f32>().fract() - 0.5, rand::random::<f32>() - 0.5,
rand::random::<f32>().fract() - 0.5, rand::random::<f32>() - 0.5,
) * 0.1 ) * 0.1
- *bearing * 0.01 - *bearing * 0.01
- pos.0 * 0.0002; - pos.0 * 0.0002;
@ -29,7 +29,37 @@ impl<'a> System<'a> for Sys {
if bearing.magnitude_squared() != 0.0 { if bearing.magnitude_squared() != 0.0 {
control.move_dir = bearing.normalized(); control.move_dir = bearing.normalized();
} }
} },
Agent::Pet { target, offset } => {
// Run towards target
match positions.get(*target) {
Some(tgt_pos) => {
let tgt_pos = tgt_pos.0 + *offset;
// Jump with target
control.jumping = tgt_pos.z > pos.0.z + 1.0;
// Move towards the target
let dist = tgt_pos.distance(pos.0);
control.move_dir = if dist > 5.0 {
Vec2::from(tgt_pos - pos.0).normalized()
} else if dist < 1.5 && pos.0 != tgt_pos {
Vec2::from(pos.0 - tgt_pos).normalized()
} else {
Vec2::zero()
};
},
_ => control.move_dir = Vec2::zero(),
}
// Change offset occasionally
if rand::random::<f32>() < 0.003 {
*offset = Vec2::new(
rand::random::<f32>() - 0.5,
rand::random::<f32>() - 0.5,
) * 10.0;
}
},
} }
} }
} }

View File

@ -4,7 +4,11 @@
use crate::Server; use crate::Server;
use common::{comp, msg::ServerMsg}; use common::{comp, msg::ServerMsg};
use specs::{join::Join, Entity as EcsEntity}; use specs::{
Join,
Entity as EcsEntity,
Builder,
};
use vek::*; use vek::*;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -72,9 +76,15 @@ lazy_static! {
ChatCommand::new( ChatCommand::new(
"tp", "tp",
"{}", "{}",
"/tp <alias>: Teleport to another player", "/tp <alias> : Teleport to another player",
handle_tp handle_tp
), ),
ChatCommand::new(
"pet",
"{}",
"/pet : Spawn a test pet NPC",
handle_pet
),
ChatCommand::new("help", "", "/help: Display this message", handle_help) ChatCommand::new("help", "", "/help: Display this message", handle_help)
]; ];
} }
@ -179,6 +189,23 @@ fn handle_tp(server: &mut Server, entity: EcsEntity, args: String, action: &Chat
} }
} }
fn handle_pet(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
match server
.state
.read_component_cloned::<comp::phys::Pos>(entity)
{
Some(pos) => {
server.create_npc(comp::Character::random())
.with(comp::Control::default())
.with(comp::Agent::Pet{ target: entity, offset: Vec2::zero() })
.with(pos)
.build();
server.clients.notify(entity, ServerMsg::Chat("Pet spawned!".to_owned()));
},
None => server.clients.notify(entity, ServerMsg::Chat("You have no position!".to_owned())),
}
}
fn handle_help(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) { fn handle_help(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
for cmd in CHAT_COMMANDS.iter() { for cmd in CHAT_COMMANDS.iter() {
server server

View File

@ -82,8 +82,8 @@ impl Server {
for i in 0..4 { for i in 0..4 {
this.create_npc(comp::Character::random()) this.create_npc(comp::Character::random())
.with(comp::Agent::Wanderer(Vec2::zero()))
.with(comp::Control::default()) .with(comp::Control::default())
.with(comp::Agent::Wanderer(Vec2::zero()))
.build(); .build();
} }
@ -121,6 +121,7 @@ impl Server {
.with(comp::phys::Pos(Vec3::new(0.0, 0.0, 64.0))) .with(comp::phys::Pos(Vec3::new(0.0, 0.0, 64.0)))
.with(comp::phys::Vel(Vec3::zero())) .with(comp::phys::Vel(Vec3::zero()))
.with(comp::phys::Dir(Vec3::unit_y())) .with(comp::phys::Dir(Vec3::unit_y()))
.with(comp::AnimationHistory::new(Animation::Idle))
.with(character) .with(character)
} }
@ -140,11 +141,7 @@ impl Server {
// Set initial animation // Set initial animation
state.write_component( state.write_component(
entity, entity,
comp::AnimationHistory { comp::AnimationHistory::new(Animation::Idle),
last: None,
current: Animation::Idle,
time: 0.0,
},
); );
// Tell the client his request was successful // Tell the client his request was successful
@ -272,7 +269,7 @@ impl Server {
// (All components Sphynx tracks) // (All components Sphynx tracks)
client.notify(ServerMsg::InitialSync { client.notify(ServerMsg::InitialSync {
ecs_state: self.state.ecs().gen_state_package(), ecs_state: self.state.ecs().gen_state_package(),
entity_uid: self.state.ecs().uid_from_entity(entity).unwrap().into(), entity_uid: self.state.ecs().uid_from_entity(entity).unwrap().into(), // Can't fail
}); });
self.clients.add(entity, client); self.clients.add(entity, client);

View File

@ -136,7 +136,7 @@ Voxygen has logged information about the problem (including this message) to the
The information below is intended for developers and testers. The information below is intended for developers and testers.
Panic Payload: {:?} Panic Payload: {:?}
PanicInfo: {:?}", settings_clone.log.file, reason, panic_info); PanicInfo: {}", settings_clone.log.file, reason, panic_info);
log::error!("VOXYGEN HAS PANICKED\n\n{}", msg); log::error!("VOXYGEN HAS PANICKED\n\n{}", msg);

View File

@ -245,9 +245,10 @@ impl FigureCache {
for (entity, &character) in (&ecs.entities(), &ecs.read_storage::<comp::Character>()).join() for (entity, &character) in (&ecs.entities(), &ecs.read_storage::<comp::Character>()).join()
{ {
let model = Self::get_or_create_model(models, renderer, tick, character); if let Some(state) = self.states.get(&entity) {
let state = self.states.get(&entity).unwrap(); let model = Self::get_or_create_model(models, renderer, tick, character);
renderer.render_figure(&model.0, globals, &state.locals, &state.bone_consts); renderer.render_figure(&model.0, globals, &state.locals, &state.bone_consts);
}
} }
} }
} }