mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'imbris/projectile-exp' into 'master'
Make projectiles give experience See merge request veloren/veloren!588
This commit is contained in:
@ -73,6 +73,7 @@ impl Default for Inventory {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inventory.push(Item::Debug(Debug::Boost));
|
inventory.push(Item::Debug(Debug::Boost));
|
||||||
|
inventory.push(Item::Debug(Debug::Possess));
|
||||||
inventory.push(Item::Tool {
|
inventory.push(Item::Tool {
|
||||||
kind: Tool::Bow,
|
kind: Tool::Bow,
|
||||||
power: 10,
|
power: 10,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::state::Uid;
|
||||||
use specs::{Component, FlaggedStorage};
|
use specs::{Component, FlaggedStorage};
|
||||||
use specs_idvs::IDVStorage;
|
use specs_idvs::IDVStorage;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -7,10 +8,12 @@ pub enum Effect {
|
|||||||
Damage(u32),
|
Damage(u32),
|
||||||
Vanish,
|
Vanish,
|
||||||
Stick,
|
Stick,
|
||||||
|
Possess,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Projectile {
|
pub struct Projectile {
|
||||||
|
pub owner: Option<Uid>,
|
||||||
pub hit_ground: Vec<Effect>,
|
pub hit_ground: Vec<Effect>,
|
||||||
pub hit_wall: Vec<Effect>,
|
pub hit_wall: Vec<Effect>,
|
||||||
pub hit_entity: Vec<Effect>,
|
pub hit_entity: Vec<Effect>,
|
||||||
|
@ -5,7 +5,6 @@ use specs_idvs::IDVStorage;
|
|||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum HealthSource {
|
pub enum HealthSource {
|
||||||
Attack { by: Uid }, // TODO: Implement weapon
|
Attack { by: Uid }, // TODO: Implement weapon
|
||||||
Projectile,
|
|
||||||
Suicide,
|
Suicide,
|
||||||
World,
|
World,
|
||||||
Revive,
|
Revive,
|
||||||
|
@ -35,6 +35,8 @@ pub enum ServerEvent {
|
|||||||
Shoot {
|
Shoot {
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
dir: Vec3<f32>,
|
dir: Vec3<f32>,
|
||||||
|
body: comp::Body,
|
||||||
|
light: Option<comp::LightEmitter>,
|
||||||
projectile: comp::Projectile,
|
projectile: comp::Projectile,
|
||||||
},
|
},
|
||||||
LandOnGround {
|
LandOnGround {
|
||||||
@ -43,6 +45,7 @@ pub enum ServerEvent {
|
|||||||
},
|
},
|
||||||
Mount(EcsEntity, EcsEntity),
|
Mount(EcsEntity, EcsEntity),
|
||||||
Unmount(EcsEntity),
|
Unmount(EcsEntity),
|
||||||
|
Possess(Uid, Uid),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventBus<E> {
|
pub struct EventBus<E> {
|
||||||
|
@ -4,8 +4,8 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{
|
||||||
item, projectile, ActionState::*, Body, CharacterState, ControlEvent, Controller, Item,
|
self, item, projectile, ActionState::*, Body, CharacterState, ControlEvent, Controller,
|
||||||
MovementState::*, PhysicsState, Projectile, Stats, Vel,
|
Item, MovementState::*, PhysicsState, Projectile, Stats, Vel,
|
||||||
},
|
},
|
||||||
event::{EventBus, LocalEvent, ServerEvent},
|
event::{EventBus, LocalEvent, ServerEvent},
|
||||||
};
|
};
|
||||||
@ -13,7 +13,7 @@ use specs::{
|
|||||||
saveload::{Marker, MarkerAllocator},
|
saveload::{Marker, MarkerAllocator},
|
||||||
Entities, Join, Read, ReadStorage, System, WriteStorage,
|
Entities, Join, Read, ReadStorage, System, WriteStorage,
|
||||||
};
|
};
|
||||||
use sphynx::UidAllocator;
|
use sphynx::{Uid, UidAllocator};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -30,6 +30,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
ReadStorage<'a, Body>,
|
ReadStorage<'a, Body>,
|
||||||
ReadStorage<'a, Vel>,
|
ReadStorage<'a, Vel>,
|
||||||
ReadStorage<'a, PhysicsState>,
|
ReadStorage<'a, PhysicsState>,
|
||||||
|
ReadStorage<'a, Uid>,
|
||||||
WriteStorage<'a, CharacterState>,
|
WriteStorage<'a, CharacterState>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
bodies,
|
bodies,
|
||||||
velocities,
|
velocities,
|
||||||
physics_states,
|
physics_states,
|
||||||
|
uid,
|
||||||
mut character_states,
|
mut character_states,
|
||||||
): Self::SystemData,
|
): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
@ -143,7 +145,10 @@ impl<'a> System<'a> for Sys {
|
|||||||
server_emitter.emit(ServerEvent::Shoot {
|
server_emitter.emit(ServerEvent::Shoot {
|
||||||
entity,
|
entity,
|
||||||
dir: controller.look_dir,
|
dir: controller.look_dir,
|
||||||
|
body: comp::Body::Object(comp::object::Body::Arrow),
|
||||||
|
light: None,
|
||||||
projectile: Projectile {
|
projectile: Projectile {
|
||||||
|
owner: uid.get(entity).copied(),
|
||||||
hit_ground: vec![projectile::Effect::Stick],
|
hit_ground: vec![projectile::Effect::Stick],
|
||||||
hit_wall: vec![projectile::Effect::Stick],
|
hit_wall: vec![projectile::Effect::Stick],
|
||||||
hit_entity: vec![
|
hit_entity: vec![
|
||||||
@ -203,6 +208,39 @@ 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 {
|
||||||
|
owner: uid.get(entity).copied(),
|
||||||
|
hit_ground: vec![projectile::Effect::Vanish],
|
||||||
|
hit_wall: vec![projectile::Effect::Vanish],
|
||||||
|
hit_entity: vec![
|
||||||
|
projectile::Effect::Vanish,
|
||||||
|
projectile::Effect::Possess,
|
||||||
|
],
|
||||||
|
time_left: Duration::from_secs(60 * 5),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
// Attack
|
// Attack
|
||||||
if controller.primary
|
if controller.primary
|
||||||
|
@ -46,6 +46,10 @@ impl<'a> System<'a> for Sys {
|
|||||||
if physics.on_ground {
|
if physics.on_ground {
|
||||||
for effect in projectile.hit_ground.drain(..) {
|
for effect in projectile.hit_ground.drain(..) {
|
||||||
match effect {
|
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() {
|
else if physics.on_wall.is_some() {
|
||||||
for effect in projectile.hit_wall.drain(..) {
|
for effect in projectile.hit_wall.drain(..) {
|
||||||
match effect {
|
match effect {
|
||||||
|
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
|
||||||
|
entity,
|
||||||
|
cause: HealthSource::World,
|
||||||
|
}),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,13 +74,21 @@ impl<'a> System<'a> for Sys {
|
|||||||
server_emitter.emit(ServerEvent::Damage {
|
server_emitter.emit(ServerEvent::Damage {
|
||||||
uid: other,
|
uid: other,
|
||||||
dmg: power,
|
dmg: power,
|
||||||
cause: HealthSource::Projectile,
|
cause: match projectile.owner {
|
||||||
|
Some(uid) => HealthSource::Attack { by: uid },
|
||||||
|
None => HealthSource::Unknown,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
|
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
|
||||||
entity,
|
entity,
|
||||||
cause: HealthSource::World,
|
cause: HealthSource::World,
|
||||||
}),
|
}),
|
||||||
|
projectile::Effect::Possess => {
|
||||||
|
if let Some(uid) = projectile.owner {
|
||||||
|
server_emitter.emit(ServerEvent::Possess(uid.into(), other))
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,10 @@ impl Clients {
|
|||||||
self.clients.get_mut(entity)
|
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) {
|
pub fn remove_if<F: FnMut(EcsEntity, &mut Client) -> bool>(&mut self, mut f: F) {
|
||||||
self.clients.retain(|entity, client| !f(*entity, client));
|
self.clients.retain(|entity, client| !f(*entity, client));
|
||||||
}
|
}
|
||||||
|
@ -199,9 +199,10 @@ impl Server {
|
|||||||
pos: comp::Pos,
|
pos: comp::Pos,
|
||||||
vel: comp::Vel,
|
vel: comp::Vel,
|
||||||
body: comp::Body,
|
body: comp::Body,
|
||||||
|
maybe_light: Option<comp::LightEmitter>,
|
||||||
projectile: comp::Projectile,
|
projectile: comp::Projectile,
|
||||||
) -> EcsEntityBuilder {
|
) -> EcsEntityBuilder {
|
||||||
state
|
let builder = state
|
||||||
.ecs_mut()
|
.ecs_mut()
|
||||||
.create_entity_synced()
|
.create_entity_synced()
|
||||||
.with(pos)
|
.with(pos)
|
||||||
@ -210,7 +211,13 @@ impl Server {
|
|||||||
.with(comp::Mass(0.0))
|
.with(comp::Mass(0.0))
|
||||||
.with(body)
|
.with(body)
|
||||||
.with(projectile)
|
.with(projectile)
|
||||||
.with(comp::Sticky)
|
.with(comp::Sticky);
|
||||||
|
|
||||||
|
if let Some(light) = maybe_light {
|
||||||
|
builder.with(light)
|
||||||
|
} else {
|
||||||
|
builder
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_player_character(
|
pub fn create_player_character(
|
||||||
@ -291,6 +298,8 @@ impl Server {
|
|||||||
ServerEvent::Shoot {
|
ServerEvent::Shoot {
|
||||||
entity,
|
entity,
|
||||||
dir,
|
dir,
|
||||||
|
body,
|
||||||
|
light,
|
||||||
projectile,
|
projectile,
|
||||||
} => {
|
} => {
|
||||||
let mut pos = state
|
let mut pos = state
|
||||||
@ -307,7 +316,8 @@ impl Server {
|
|||||||
state,
|
state,
|
||||||
comp::Pos(pos),
|
comp::Pos(pos),
|
||||||
comp::Vel(dir * 100.0),
|
comp::Vel(dir * 100.0),
|
||||||
comp::Body::Object(comp::object::Body::Arrow),
|
body,
|
||||||
|
light,
|
||||||
projectile,
|
projectile,
|
||||||
)
|
)
|
||||||
.build();
|
.build();
|
||||||
@ -458,6 +468,70 @@ impl Server {
|
|||||||
}
|
}
|
||||||
state.delete_component::<comp::Mounting>(mounter);
|
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(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 {
|
if let Some(entity) = todo_remove {
|
||||||
|
Reference in New Issue
Block a user