2020-02-16 20:04:06 +00:00
|
|
|
use crate::{
|
|
|
|
client::{Client, RegionSubscription},
|
|
|
|
Server,
|
|
|
|
};
|
|
|
|
use common::{
|
2020-03-28 05:51:52 +00:00
|
|
|
comp::{self, item},
|
2020-02-16 20:04:06 +00:00
|
|
|
msg::ServerMsg,
|
|
|
|
sync::{Uid, WorldSyncExt},
|
|
|
|
};
|
|
|
|
use specs::{world::WorldExt, Entity as EcsEntity};
|
2020-06-21 14:26:06 +00:00
|
|
|
use tracing::error;
|
2020-02-16 20:04:06 +00:00
|
|
|
|
2020-10-07 02:23:20 +00:00
|
|
|
pub fn handle_lantern(server: &mut Server, entity: EcsEntity, enable: bool) {
|
2020-05-04 15:15:31 +00:00
|
|
|
let ecs = server.state_mut().ecs();
|
2020-10-07 02:23:20 +00:00
|
|
|
|
|
|
|
let lantern_exists = ecs
|
2020-05-04 15:15:31 +00:00
|
|
|
.read_storage::<comp::LightEmitter>()
|
|
|
|
.get(entity)
|
2020-10-07 02:23:20 +00:00
|
|
|
.map_or(false, |light| light.strength > 0.0);
|
|
|
|
|
|
|
|
if lantern_exists != enable {
|
|
|
|
if !enable {
|
|
|
|
server
|
|
|
|
.state_mut()
|
|
|
|
.ecs()
|
2020-05-04 15:15:31 +00:00
|
|
|
.write_storage::<comp::LightEmitter>()
|
2020-10-07 02:23:20 +00:00
|
|
|
.remove(entity);
|
|
|
|
} else {
|
|
|
|
let loadout_storage = ecs.read_storage::<comp::Loadout>();
|
|
|
|
let lantern_opt = loadout_storage
|
|
|
|
.get(entity)
|
|
|
|
.and_then(|loadout| loadout.lantern.as_ref())
|
|
|
|
.and_then(|item| {
|
|
|
|
if let comp::item::ItemKind::Lantern(l) = item.kind() {
|
|
|
|
Some(l)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2020-05-04 15:15:31 +00:00
|
|
|
});
|
2020-10-07 02:23:20 +00:00
|
|
|
if let Some(lantern) = lantern_opt {
|
|
|
|
let _ =
|
|
|
|
ecs.write_storage::<comp::LightEmitter>()
|
|
|
|
.insert(entity, comp::LightEmitter {
|
|
|
|
col: lantern.color(),
|
|
|
|
strength: lantern.strength(),
|
|
|
|
flicker: 0.35,
|
|
|
|
animated: true,
|
|
|
|
});
|
|
|
|
}
|
2020-05-04 15:15:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-16 20:04:06 +00:00
|
|
|
pub fn handle_mount(server: &mut Server, mounter: EcsEntity, mountee: EcsEntity) {
|
|
|
|
let state = server.state_mut();
|
|
|
|
|
|
|
|
if state
|
|
|
|
.ecs()
|
|
|
|
.read_storage::<comp::Mounting>()
|
|
|
|
.get(mounter)
|
|
|
|
.is_none()
|
|
|
|
{
|
2020-07-31 05:13:31 +00:00
|
|
|
let not_mounting_yet = matches!(
|
|
|
|
state.ecs().read_storage::<comp::MountState>().get(mountee),
|
|
|
|
Some(comp::MountState::Unmounted)
|
|
|
|
);
|
2020-02-16 20:04:06 +00:00
|
|
|
|
|
|
|
if not_mounting_yet {
|
|
|
|
if let (Some(mounter_uid), Some(mountee_uid)) = (
|
|
|
|
state.ecs().uid_from_entity(mounter),
|
|
|
|
state.ecs().uid_from_entity(mountee),
|
|
|
|
) {
|
2020-07-31 05:13:31 +00:00
|
|
|
state.write_component(mountee, comp::MountState::MountedBy(mounter_uid));
|
|
|
|
state.write_component(mounter, comp::Mounting(mountee_uid));
|
2020-02-16 20:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn handle_unmount(server: &mut Server, mounter: EcsEntity) {
|
|
|
|
let state = server.state_mut();
|
|
|
|
let mountee_entity = state
|
|
|
|
.ecs()
|
|
|
|
.write_storage::<comp::Mounting>()
|
|
|
|
.get(mounter)
|
|
|
|
.and_then(|mountee| state.ecs().entity_from_uid(mountee.0.into()));
|
|
|
|
if let Some(mountee_entity) = mountee_entity {
|
|
|
|
state
|
|
|
|
.ecs()
|
|
|
|
.write_storage::<comp::MountState>()
|
|
|
|
.get_mut(mountee_entity)
|
|
|
|
.map(|ms| *ms = comp::MountState::Unmounted);
|
|
|
|
}
|
|
|
|
state.delete_component::<comp::Mounting>(mounter);
|
|
|
|
}
|
|
|
|
|
2020-06-10 19:47:36 +00:00
|
|
|
#[allow(clippy::nonminimal_bool)] // TODO: Pending review in #587
|
2020-02-16 20:04:06 +00:00
|
|
|
pub fn handle_possess(server: &Server, possessor_uid: Uid, possesse_uid: Uid) {
|
|
|
|
let state = &server.state;
|
|
|
|
let ecs = state.ecs();
|
|
|
|
if let (Some(possessor), Some(possesse)) = (
|
|
|
|
ecs.entity_from_uid(possessor_uid.into()),
|
|
|
|
ecs.entity_from_uid(possesse_uid.into()),
|
|
|
|
) {
|
2020-04-01 15:04:04 +00:00
|
|
|
// Check that entities still exist
|
|
|
|
if !(possessor.gen().is_alive() && ecs.is_alive(possessor))
|
|
|
|
|| !(possesse.gen().is_alive() && ecs.is_alive(possesse))
|
|
|
|
{
|
|
|
|
error!(
|
|
|
|
"Error possessing! either the possessor entity or possesse entity no longer exists"
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-02-16 20:04:06 +00:00
|
|
|
// You can't possess other players
|
|
|
|
let mut clients = ecs.write_storage::<Client>();
|
|
|
|
if clients.get_mut(possesse).is_none() {
|
|
|
|
if let Some(mut client) = clients.remove(possessor) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(ServerMsg::SetPlayerEntity(possesse_uid));
|
2020-06-21 21:47:49 +00:00
|
|
|
clients
|
|
|
|
.insert(possesse, client)
|
|
|
|
.err()
|
|
|
|
.map(|e| error!(?e, "Error inserting client component during possession"));
|
2020-03-17 13:15:39 +00:00
|
|
|
// Put possess item into loadout
|
|
|
|
let mut loadouts = ecs.write_storage::<comp::Loadout>();
|
|
|
|
let loadout = loadouts
|
|
|
|
.entry(possesse)
|
|
|
|
.expect("Could not read loadouts component while possessing")
|
|
|
|
.or_insert(comp::Loadout::default());
|
|
|
|
|
2020-09-17 23:02:14 +00:00
|
|
|
let item = comp::Item::new_from_asset_expect("common.items.debug.possess");
|
|
|
|
if let item::ItemKind::Tool(tool) = item.kind() {
|
2020-03-24 12:59:53 +00:00
|
|
|
let mut abilities = tool.get_abilities();
|
|
|
|
let mut ability_drain = abilities.drain(..);
|
2020-04-01 15:04:04 +00:00
|
|
|
let debug_item = comp::ItemConfig {
|
2020-03-17 13:15:39 +00:00
|
|
|
item,
|
2020-03-24 12:59:53 +00:00
|
|
|
ability1: ability_drain.next(),
|
|
|
|
ability2: ability_drain.next(),
|
|
|
|
ability3: ability_drain.next(),
|
2020-03-17 13:15:39 +00:00
|
|
|
block_ability: None,
|
|
|
|
dodge_ability: None,
|
2020-04-01 15:04:04 +00:00
|
|
|
};
|
|
|
|
std::mem::swap(&mut loadout.active_item, &mut loadout.second_item);
|
|
|
|
loadout.active_item = Some(debug_item);
|
2020-03-17 13:15:39 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 20:04:06 +00:00
|
|
|
// Move player component
|
|
|
|
{
|
|
|
|
let mut players = ecs.write_storage::<comp::Player>();
|
|
|
|
if let Some(player) = players.remove(possessor) {
|
|
|
|
players.insert(possesse, player).err().map(|e| {
|
2020-06-21 21:47:49 +00:00
|
|
|
error!(?e, "Error inserting player component during possession")
|
2020-02-16 20:04:06 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Transfer region subscription
|
|
|
|
{
|
|
|
|
let mut subscriptions = ecs.write_storage::<RegionSubscription>();
|
|
|
|
if let Some(s) = subscriptions.remove(possessor) {
|
|
|
|
subscriptions.insert(possesse, s).err().map(|e| {
|
|
|
|
error!(
|
2020-06-21 21:47:49 +00:00
|
|
|
?e,
|
|
|
|
"Error inserting subscription component during possession"
|
2020-02-16 20:04:06 +00:00
|
|
|
)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Remove will of the entity
|
|
|
|
ecs.write_storage::<comp::Agent>().remove(possesse);
|
|
|
|
// Reset controller of former shell
|
|
|
|
ecs.write_storage::<comp::Controller>()
|
|
|
|
.get_mut(possessor)
|
|
|
|
.map(|c| c.reset());
|
|
|
|
// Transfer admin powers
|
|
|
|
{
|
|
|
|
let mut admins = ecs.write_storage::<comp::Admin>();
|
|
|
|
if let Some(admin) = admins.remove(possessor) {
|
|
|
|
admins.insert(possesse, admin).err().map(|e| {
|
2020-06-21 21:47:49 +00:00
|
|
|
error!(?e, "Error inserting admin component during possession")
|
2020-02-16 20:04:06 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Transfer waypoint
|
|
|
|
{
|
|
|
|
let mut waypoints = ecs.write_storage::<comp::Waypoint>();
|
|
|
|
if let Some(waypoint) = waypoints.remove(possessor) {
|
|
|
|
waypoints.insert(possesse, waypoint).err().map(|e| {
|
2020-06-21 21:47:49 +00:00
|
|
|
error!(?e, "Error inserting waypoint component during possession",)
|
2020-02-16 20:04:06 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|