Add new debug item

This commit is contained in:
Imbris 2019-10-11 00:30:34 -04:00
parent 0066a546a5
commit 2f9d8ee2e6
7 changed files with 142 additions and 6 deletions

View File

@ -73,6 +73,7 @@ impl Default for Inventory {
};
inventory.push(Item::Debug(Debug::Boost));
inventory.push(Item::Debug(Debug::Possess));
inventory.push(Item::Tool {
kind: Tool::Bow,
power: 10,

View File

@ -7,6 +7,7 @@ pub enum Effect {
Damage(u32),
Vanish,
Stick,
Possess(u64),
}
#[derive(Clone, Debug, Serialize, Deserialize)]

View File

@ -35,6 +35,8 @@ pub enum ServerEvent {
Shoot {
entity: EcsEntity,
dir: Vec3<f32>,
body: comp::Body,
light: Option<comp::LightEmitter>,
projectile: comp::Projectile,
},
LandOnGround {
@ -43,6 +45,7 @@ pub enum ServerEvent {
},
Mount(EcsEntity, EcsEntity),
Unmount(EcsEntity),
Possess(Uid, Uid),
}
pub struct EventBus<E> {

View File

@ -4,8 +4,8 @@ use super::{
};
use crate::{
comp::{
item, projectile, ActionState::*, Body, CharacterState, ControlEvent, Controller, Item,
MovementState::*, PhysicsState, Projectile, Stats, Vel,
self, item, projectile, ActionState::*, Body, CharacterState, ControlEvent, Controller,
Item, MovementState::*, PhysicsState, Projectile, Stats, Vel,
},
event::{EventBus, LocalEvent, ServerEvent},
};
@ -13,7 +13,7 @@ use specs::{
saveload::{Marker, MarkerAllocator},
Entities, Join, Read, ReadStorage, System, WriteStorage,
};
use sphynx::UidAllocator;
use sphynx::{Uid, UidAllocator};
use std::time::Duration;
use vek::*;
@ -30,6 +30,7 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Body>,
ReadStorage<'a, Vel>,
ReadStorage<'a, PhysicsState>,
ReadStorage<'a, Uid>,
WriteStorage<'a, CharacterState>,
);
@ -45,6 +46,7 @@ impl<'a> System<'a> for Sys {
bodies,
velocities,
physics_states,
uid,
mut character_states,
): Self::SystemData,
) {
@ -143,6 +145,8 @@ impl<'a> System<'a> for Sys {
server_emitter.emit(ServerEvent::Shoot {
entity,
dir: controller.look_dir,
body: comp::Body::Object(comp::object::Body::Arrow),
light: None,
projectile: Projectile {
hit_ground: vec![projectile::Effect::Stick],
hit_wall: vec![projectile::Effect::Stick],
@ -203,6 +207,44 @@ impl<'a> System<'a> for Sys {
});
}
}
Some(Item::Debug(item::Debug::Possess)) => {
if controller.primary
&& (character.movement == Stand
|| character.movement == Run
|| character.movement == Jump)
{
if let Wield { time_left } = character.action {
if time_left == Duration::default() {
// Immediately end the wield
character.action = Idle;
server_emitter.emit(ServerEvent::Shoot {
entity,
dir: controller.look_dir,
body: comp::Body::Object(comp::object::Body::PotionRed),
light: Some(comp::LightEmitter {
col: (0.0, 1.0, 0.3).into(),
..Default::default()
}),
projectile: Projectile {
hit_ground: vec![projectile::Effect::Vanish],
hit_wall: vec![projectile::Effect::Vanish],
hit_entity: {
let mut effects = vec![projectile::Effect::Vanish];
if let Some(uid) = uid.get(entity) {
// TODO: if projectiles themselves get owners we don't need to store the uid here
effects.push(projectile::Effect::Possess(
(*uid).into(),
));
}
effects
},
time_left: Duration::from_secs(60 * 5),
},
});
}
}
}
}
None => {
// Attack
if controller.primary

View File

@ -46,6 +46,10 @@ impl<'a> System<'a> for Sys {
if physics.on_ground {
for effect in projectile.hit_ground.drain(..) {
match effect {
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
entity,
cause: HealthSource::World,
}),
_ => {}
}
}
@ -54,6 +58,10 @@ impl<'a> System<'a> for Sys {
else if physics.on_wall.is_some() {
for effect in projectile.hit_wall.drain(..) {
match effect {
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
entity,
cause: HealthSource::World,
}),
_ => {}
}
}
@ -73,6 +81,9 @@ impl<'a> System<'a> for Sys {
entity,
cause: HealthSource::World,
}),
projectile::Effect::Possess(client_uid) => {
server_emitter.emit(ServerEvent::Possess(client_uid.into(), other))
}
_ => {}
}
}

View File

@ -57,6 +57,10 @@ impl Clients {
self.clients.get_mut(entity)
}
pub fn remove<'a>(&'a mut self, entity: &EcsEntity) -> Option<Client> {
self.clients.remove(entity)
}
pub fn remove_if<F: FnMut(EcsEntity, &mut Client) -> bool>(&mut self, mut f: F) {
self.clients.retain(|entity, client| !f(*entity, client));
}

View File

@ -199,9 +199,10 @@ impl Server {
pos: comp::Pos,
vel: comp::Vel,
body: comp::Body,
maybe_light: Option<comp::LightEmitter>,
projectile: comp::Projectile,
) -> EcsEntityBuilder {
state
let builder = state
.ecs_mut()
.create_entity_synced()
.with(pos)
@ -210,7 +211,13 @@ impl Server {
.with(comp::Mass(0.0))
.with(body)
.with(projectile)
.with(comp::Sticky)
.with(comp::Sticky);
if let Some(light) = maybe_light {
builder.with(light)
} else {
builder
}
}
pub fn create_player_character(
@ -291,6 +298,8 @@ impl Server {
ServerEvent::Shoot {
entity,
dir,
body,
light,
projectile,
} => {
let mut pos = state
@ -307,7 +316,8 @@ impl Server {
state,
comp::Pos(pos),
comp::Vel(dir * 100.0),
comp::Body::Object(comp::object::Body::Arrow),
body,
light,
projectile,
)
.build();
@ -458,6 +468,70 @@ impl Server {
}
state.delete_component::<comp::Mounting>(mounter);
}
ServerEvent::Possess(possessor_uid, possesse_uid) => {
if let (Some(possessor), Some(possesse)) = (
state.ecs().entity_from_uid(possessor_uid.into()),
state.ecs().entity_from_uid(possesse_uid.into()),
) {
// You can't possess other players
if clients.get(&possesse).is_none() {
if let Some(mut client) = clients.remove(&possessor) {
client.notify(ServerMsg::SetPlayerEntity(possesse_uid.into()));
clients.add(possesse, client);
// Create inventory if it doesn't exist
{
let mut inventories =
state.ecs_mut().write_storage::<comp::Inventory>();
if let Some(mut inventory) = inventories.get_mut(possesse) {
inventory
.push(comp::Item::Debug(comp::item::Debug::Possess));
} else {
let _ = inventories.insert(
possesse,
comp::Inventory {
slots: vec![Some(comp::Item::Debug(
comp::item::Debug::Possess,
))],
},
);
}
}
let _ = state
.ecs_mut()
.write_storage::<comp::InventoryUpdate>()
.insert(possesse, comp::InventoryUpdate);
// Move player component
{
let mut players =
state.ecs_mut().write_storage::<comp::Player>();
if let Some(player) = players.get(possessor).cloned() {
let _ = players.insert(possesse, player);
}
}
// Remove will of the entity
let _ = state
.ecs_mut()
.write_storage::<comp::Agent>()
.remove(possesse);
// Transfer admin powers
{
let mut admins = state.ecs_mut().write_storage::<comp::Admin>();
if let Some(admin) = admins.remove(possessor) {
let _ = admins.insert(possesse, admin);
}
}
// Transfer waypoint
{
let mut waypoints =
state.ecs_mut().write_storage::<comp::Waypoint>();
if let Some(waypoint) = waypoints.remove(possessor) {
let _ = waypoints.insert(possesse, waypoint);
}
}
}
}
}
}
}
if let Some(entity) = todo_remove {