2020-06-25 18:50:04 +00:00
|
|
|
use crate::{sys, Server, StateExt};
|
2020-03-28 01:31:22 +00:00
|
|
|
use common::{
|
2020-09-17 23:02:14 +00:00
|
|
|
character::CharacterId,
|
2021-01-31 17:15:28 +00:00
|
|
|
combat,
|
2020-03-28 01:31:22 +00:00
|
|
|
comp::{
|
2020-12-04 22:24:56 +00:00
|
|
|
self,
|
2021-01-18 22:58:56 +00:00
|
|
|
aura::{Aura, AuraKind, AuraTarget},
|
2020-12-04 22:24:56 +00:00
|
|
|
beam,
|
|
|
|
buff::{BuffCategory, BuffData, BuffKind, BuffSource},
|
2021-01-08 19:12:09 +00:00
|
|
|
group,
|
|
|
|
inventory::loadout::Loadout,
|
|
|
|
shockwave, Agent, Alignment, Body, Gravity, Health, HomeChunk, Inventory, Item, ItemDrop,
|
2021-03-06 19:03:21 +00:00
|
|
|
LightEmitter, Object, Ori, Poise, Pos, Projectile, Scale, Stats, Vel, WaypointArea,
|
2020-03-28 01:31:22 +00:00
|
|
|
},
|
2020-07-31 17:16:20 +00:00
|
|
|
outcome::Outcome,
|
2020-11-11 23:59:09 +00:00
|
|
|
rtsim::RtSimEntity,
|
2020-11-23 15:39:03 +00:00
|
|
|
util::Dir,
|
2020-02-16 20:04:06 +00:00
|
|
|
};
|
|
|
|
use specs::{Builder, Entity as EcsEntity, WorldExt};
|
2020-12-04 22:24:56 +00:00
|
|
|
use std::time::Duration;
|
2020-02-16 20:04:06 +00:00
|
|
|
use vek::{Rgb, Vec3};
|
|
|
|
|
2020-09-17 23:02:14 +00:00
|
|
|
pub fn handle_initialize_character(
|
|
|
|
server: &mut Server,
|
|
|
|
entity: EcsEntity,
|
|
|
|
character_id: CharacterId,
|
|
|
|
) {
|
2020-06-25 11:20:09 +00:00
|
|
|
server.state.initialize_character_data(entity, character_id);
|
2020-06-16 01:00:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn handle_loaded_character_data(
|
2020-02-16 20:04:06 +00:00
|
|
|
server: &mut Server,
|
|
|
|
entity: EcsEntity,
|
2020-11-03 00:12:49 +00:00
|
|
|
loaded_components: (
|
|
|
|
comp::Body,
|
|
|
|
comp::Stats,
|
|
|
|
comp::Inventory,
|
|
|
|
Option<comp::Waypoint>,
|
|
|
|
),
|
2020-02-16 20:04:06 +00:00
|
|
|
) {
|
2020-06-25 18:50:04 +00:00
|
|
|
server
|
|
|
|
.state
|
|
|
|
.update_character_data(entity, loaded_components);
|
2020-06-25 11:20:09 +00:00
|
|
|
sys::subscription::initialize_region_subscription(server.state.ecs(), entity);
|
2020-02-16 20:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-10 19:47:36 +00:00
|
|
|
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
2020-02-16 20:04:06 +00:00
|
|
|
pub fn handle_create_npc(
|
|
|
|
server: &mut Server,
|
|
|
|
pos: Pos,
|
|
|
|
stats: Stats,
|
2020-10-31 22:34:08 +00:00
|
|
|
health: Health,
|
2020-12-05 18:23:45 +00:00
|
|
|
poise: Poise,
|
2020-02-26 17:04:43 +00:00
|
|
|
loadout: Loadout,
|
2020-02-16 20:04:06 +00:00
|
|
|
body: Body,
|
2020-07-05 12:39:28 +00:00
|
|
|
agent: impl Into<Option<Agent>>,
|
2020-02-16 20:04:06 +00:00
|
|
|
alignment: Alignment,
|
|
|
|
scale: Scale,
|
2020-05-15 15:05:50 +00:00
|
|
|
drop_item: Option<Item>,
|
2020-11-22 21:03:06 +00:00
|
|
|
home_chunk: Option<HomeChunk>,
|
2020-11-11 23:59:09 +00:00
|
|
|
rtsim_entity: Option<RtSimEntity>,
|
2020-02-16 20:04:06 +00:00
|
|
|
) {
|
2020-04-26 17:03:19 +00:00
|
|
|
let group = match alignment {
|
|
|
|
Alignment::Wild => None,
|
2020-08-21 20:37:08 +00:00
|
|
|
Alignment::Passive => None,
|
2020-04-26 17:03:19 +00:00
|
|
|
Alignment::Enemy => Some(group::ENEMY),
|
|
|
|
Alignment::Npc | Alignment::Tame => Some(group::NPC),
|
|
|
|
// TODO: handle
|
|
|
|
Alignment::Owned(_) => None,
|
|
|
|
};
|
|
|
|
|
2021-01-08 19:12:09 +00:00
|
|
|
let inventory = Inventory::new_with_loadout(loadout);
|
|
|
|
|
2020-05-15 15:05:50 +00:00
|
|
|
let entity = server
|
2020-02-16 20:04:06 +00:00
|
|
|
.state
|
2020-12-05 18:23:45 +00:00
|
|
|
.create_npc(pos, stats, health, poise, inventory, body)
|
2020-02-16 20:04:06 +00:00
|
|
|
.with(scale)
|
2020-05-15 15:05:50 +00:00
|
|
|
.with(alignment);
|
|
|
|
|
2020-04-26 17:03:19 +00:00
|
|
|
let entity = if let Some(group) = group {
|
|
|
|
entity.with(group)
|
|
|
|
} else {
|
|
|
|
entity
|
|
|
|
};
|
|
|
|
|
2020-07-05 12:39:28 +00:00
|
|
|
let entity = if let Some(agent) = agent.into() {
|
|
|
|
entity.with(agent)
|
|
|
|
} else {
|
|
|
|
entity
|
|
|
|
};
|
|
|
|
|
2020-05-15 15:05:50 +00:00
|
|
|
let entity = if let Some(drop_item) = drop_item {
|
|
|
|
entity.with(ItemDrop(drop_item))
|
|
|
|
} else {
|
|
|
|
entity
|
|
|
|
};
|
|
|
|
|
2020-11-22 21:03:06 +00:00
|
|
|
let entity = if let Some(home_chunk) = home_chunk {
|
|
|
|
entity.with(home_chunk)
|
|
|
|
} else {
|
|
|
|
entity
|
|
|
|
};
|
|
|
|
|
2020-11-11 23:59:09 +00:00
|
|
|
let entity = if let Some(rtsim_entity) = rtsim_entity {
|
|
|
|
entity.with(rtsim_entity)
|
|
|
|
} else {
|
|
|
|
entity
|
|
|
|
};
|
|
|
|
|
2020-05-15 15:05:50 +00:00
|
|
|
entity.build();
|
2020-02-16 20:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-08-23 20:53:43 +00:00
|
|
|
#[allow(clippy::too_many_arguments)]
|
2020-02-16 20:04:06 +00:00
|
|
|
pub fn handle_shoot(
|
|
|
|
server: &mut Server,
|
|
|
|
entity: EcsEntity,
|
2020-03-28 01:31:22 +00:00
|
|
|
dir: Dir,
|
2020-02-16 20:04:06 +00:00
|
|
|
body: Body,
|
|
|
|
light: Option<LightEmitter>,
|
|
|
|
projectile: Projectile,
|
|
|
|
gravity: Option<Gravity>,
|
2020-08-06 18:17:38 +00:00
|
|
|
speed: f32,
|
2021-03-06 19:03:21 +00:00
|
|
|
object: Option<Object>,
|
2020-02-16 20:04:06 +00:00
|
|
|
) {
|
|
|
|
let state = server.state_mut();
|
|
|
|
|
2020-12-07 12:28:29 +00:00
|
|
|
let mut pos = if let Some(pos) = state.ecs().read_storage::<Pos>().get(entity) {
|
|
|
|
pos.0
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
};
|
2020-02-16 20:04:06 +00:00
|
|
|
|
2020-08-06 18:17:38 +00:00
|
|
|
let vel = *dir * speed;
|
2020-07-31 17:16:20 +00:00
|
|
|
|
|
|
|
// Add an outcome
|
2020-08-06 16:41:43 +00:00
|
|
|
state
|
|
|
|
.ecs()
|
|
|
|
.write_resource::<Vec<Outcome>>()
|
|
|
|
.push(Outcome::ProjectileShot { pos, body, vel });
|
2020-07-31 17:16:20 +00:00
|
|
|
|
2020-11-14 22:05:35 +00:00
|
|
|
let eye_height = state
|
|
|
|
.ecs()
|
|
|
|
.read_storage::<comp::Body>()
|
|
|
|
.get(entity)
|
2020-11-15 23:11:33 +00:00
|
|
|
.map_or(0.0, |b| b.eye_height());
|
2020-06-13 08:21:47 +00:00
|
|
|
|
|
|
|
pos.z += eye_height;
|
2020-02-16 20:04:06 +00:00
|
|
|
|
2020-07-31 17:16:20 +00:00
|
|
|
let mut builder = state.create_projectile(Pos(pos), Vel(vel), body, projectile);
|
2020-02-16 20:04:06 +00:00
|
|
|
if let Some(light) = light {
|
|
|
|
builder = builder.with(light)
|
|
|
|
}
|
|
|
|
if let Some(gravity) = gravity {
|
|
|
|
builder = builder.with(gravity)
|
|
|
|
}
|
2021-03-06 19:03:21 +00:00
|
|
|
if let Some(object) = object {
|
|
|
|
builder = builder.with(object)
|
|
|
|
}
|
2020-02-16 20:04:06 +00:00
|
|
|
|
|
|
|
builder.build();
|
|
|
|
}
|
|
|
|
|
2020-08-08 22:22:21 +00:00
|
|
|
pub fn handle_shockwave(
|
|
|
|
server: &mut Server,
|
|
|
|
properties: shockwave::Properties,
|
|
|
|
pos: Pos,
|
|
|
|
ori: Ori,
|
|
|
|
) {
|
2020-08-08 20:53:55 +00:00
|
|
|
let state = server.state_mut();
|
2020-08-08 22:22:21 +00:00
|
|
|
state.create_shockwave(properties, pos, ori).build();
|
2020-08-08 20:53:55 +00:00
|
|
|
}
|
|
|
|
|
2020-09-05 16:27:36 +00:00
|
|
|
pub fn handle_beam(server: &mut Server, properties: beam::Properties, pos: Pos, ori: Ori) {
|
|
|
|
let state = server.state_mut();
|
2020-11-15 00:14:15 +00:00
|
|
|
let ecs = state.ecs();
|
|
|
|
ecs.write_resource::<Vec<Outcome>>().push(Outcome::Beam {
|
|
|
|
pos: pos.0,
|
2021-01-31 17:15:28 +00:00
|
|
|
heal: properties
|
|
|
|
.attack
|
|
|
|
.effects()
|
2021-02-02 18:02:40 +00:00
|
|
|
.any(|e| matches!(e.effect(), combat::CombatEffect::Heal(h) if *h > 0.0)),
|
2020-11-15 00:14:15 +00:00
|
|
|
});
|
2020-09-05 16:27:36 +00:00
|
|
|
state.create_beam(properties, pos, ori).build();
|
|
|
|
}
|
|
|
|
|
2020-02-16 20:04:06 +00:00
|
|
|
pub fn handle_create_waypoint(server: &mut Server, pos: Vec3<f32>) {
|
|
|
|
server
|
2020-03-10 02:27:32 +00:00
|
|
|
.state
|
2020-02-16 20:04:06 +00:00
|
|
|
.create_object(Pos(pos), comp::object::Body::CampfireLit)
|
|
|
|
.with(LightEmitter {
|
2020-08-30 20:10:56 +00:00
|
|
|
col: Rgb::new(1.0, 0.3, 0.1),
|
2020-08-30 12:24:25 +00:00
|
|
|
strength: 5.0,
|
2020-05-04 15:15:31 +00:00
|
|
|
flicker: 1.0,
|
|
|
|
animated: true,
|
2020-02-16 20:04:06 +00:00
|
|
|
})
|
|
|
|
.with(WaypointArea::default())
|
2020-11-15 17:13:03 +00:00
|
|
|
.with(comp::Mass(10_f32.powi(10)))
|
2021-02-28 20:02:03 +00:00
|
|
|
.with(comp::Auras::new(vec![Aura::new(
|
2020-12-04 22:24:56 +00:00
|
|
|
AuraKind::Buff {
|
|
|
|
kind: BuffKind::CampfireHeal,
|
2021-02-26 22:35:49 +00:00
|
|
|
data: BuffData::new(0.02, Some(Duration::from_secs(1))),
|
2020-12-04 22:24:56 +00:00
|
|
|
category: BuffCategory::Natural,
|
|
|
|
source: BuffSource::World,
|
|
|
|
},
|
|
|
|
5.0,
|
|
|
|
None,
|
2021-01-18 22:58:56 +00:00
|
|
|
AuraTarget::All,
|
2021-02-28 20:02:03 +00:00
|
|
|
)]))
|
2020-02-16 20:04:06 +00:00
|
|
|
.build();
|
|
|
|
}
|