Added enemies

Former-commit-id: 5ff3aadeb55595f3f7da34ab9bdfd3a76158f928
This commit is contained in:
Joshua Barretto 2019-05-27 12:18:14 +01:00 committed by Louis Pearson
parent 9352d4ba4f
commit 923ee08ac2
4 changed files with 82 additions and 4 deletions

View File

@ -8,6 +8,9 @@ pub enum Agent {
target: EcsEntity,
offset: Vec2<f32>,
},
Enemy {
target: Option<EcsEntity>,
},
}
impl Component for Agent {

View File

@ -1,25 +1,31 @@
// Library
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
use vek::*;
use rand::Rng;
// Crate
use crate::comp::{phys::Pos, Agent, Control, Jumping};
use crate::{
comp::{phys::Pos, Agent, Control, Jumping, Attacking},
state::Time,
};
// Basic ECS AI agent system
pub struct Sys;
impl<'a> System<'a> for Sys {
type SystemData = (
Read<'a, Time>,
Entities<'a>,
WriteStorage<'a, Agent>,
ReadStorage<'a, Pos>,
WriteStorage<'a, Control>,
WriteStorage<'a, Jumping>,
WriteStorage<'a, Attacking>,
);
fn run(
&mut self,
(entities, mut agents, positions, mut controls, mut jumpings): Self::SystemData,
(time, entities, mut agents, positions, mut controls, mut jumpings, mut attackings): Self::SystemData,
) {
for (entity, agent, pos, control) in
(&entities, &mut agents, &positions, &mut controls).join()
@ -64,7 +70,43 @@ impl<'a> System<'a> for Sys {
Vec2::new(rand::random::<f32>() - 0.5, rand::random::<f32>() - 0.5)
* 10.0;
}
}
},
Agent::Enemy { target } => {
let choose_new = match target.map(|tgt| positions.get(tgt)).flatten() {
Some(tgt_pos) => {
let dist = Vec2::<f32>::from(tgt_pos.0 - pos.0).magnitude();
if dist < 2.0 {
control.move_dir = Vec2::zero();
if rand::random::<f32>() < 0.2 {
attackings.insert(entity, Attacking::start());
}
false
} else if dist < 60.0 {
control.move_dir = Vec2::<f32>::from(tgt_pos.0 - pos.0).normalized() * 0.96;
false
} else {
true
}
},
None => {
control.move_dir = Vec2::one();
rand::random::<f32>().fract() < 0.25
},
};
if choose_new {
let entities = (&entities, &positions)
.join()
.filter(|(_, e_pos)| Vec2::<f32>::from(e_pos.0 - pos.0).magnitude() < 30.0)
.map(|(e, _)| e)
.collect::<Vec<_>>();
*target = rand::thread_rng().choose(&entities).cloned();
}
},
}
}
}

View File

@ -93,6 +93,12 @@ lazy_static! {
"/wolf : Spawn a test wolf NPC",
handle_petwolf
),
ChatCommand::new(
"enemy",
"{}",
"/enemy : Spawn a test enemy NPC",
handle_enemy
),
ChatCommand::new(
"help", "", "/help: Display this message", handle_help)
];
@ -266,6 +272,32 @@ fn handle_petwolf(server: &mut Server, entity: EcsEntity, args: String, action:
.notify(entity, ServerMsg::Chat("You have no position!".to_owned())),
}
}
fn handle_enemy(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
match server
.state
.read_component_cloned::<comp::phys::Pos>(entity)
{
Some(mut pos) => {
pos.0.x += 1.0; // Temp fix TODO: Solve NaN issue with positions of pets
server
.create_npc(
pos,
"Tobermory".to_owned(),
comp::Body::Humanoid(comp::HumanoidBody::random()),
)
.with(comp::Agent::Enemy {
target: None,
})
.build();
server
.clients
.notify(entity, ServerMsg::Chat("Spawned enemy!".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) {
for cmd in CHAT_COMMANDS.iter() {
server

View File

@ -143,12 +143,13 @@ impl Server {
.ecs_mut()
.create_entity_synced()
.with(pos)
.with(comp::Control::default())
.with(comp::phys::Vel(Vec3::zero()))
.with(comp::phys::Dir(Vec3::unit_y()))
.with(comp::Control::default())
.with(comp::AnimationInfo::default())
.with(comp::Actor::Character { name, body })
.with(comp::Stats::default())
.with(comp::phys::ForceUpdate)
}
pub fn create_player_character(