Merge branch 'zesterer/better-flagged-storage' into 'master'

Used new deref-based component flagging storage to reduce network usage by 75%

See merge request veloren/veloren!1605
This commit is contained in:
Marcel 2021-01-07 20:25:12 +00:00
commit d35f31b9b5
43 changed files with 134 additions and 113 deletions

2
Cargo.lock generated
View File

@ -5074,7 +5074,7 @@ dependencies = [
[[package]]
name = "specs-idvs"
version = "0.1.1"
source = "git+https://gitlab.com/veloren/specs-idvs.git?rev=77048eefa5df750f44bbd1b9a13402a9f7a6cfc8#77048eefa5df750f44bbd1b9a13402a9f7a6cfc8"
source = "git+https://gitlab.com/veloren/specs-idvs.git?rev=9fab7b396acd6454585486e50ae4bfe2069858a9#9fab7b396acd6454585486e50ae4bfe2069858a9"
dependencies = [
"specs",
]

View File

@ -42,9 +42,8 @@ indexmap = "1.3.0"
slab = "0.4.2"
# ECS
specs = { git = "https://github.com/amethyst/specs.git", features = ["serde", "storage-event-control"], rev = "d4435bdf496cf322c74886ca09dd8795984919b4" }
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git", rev = "77048eefa5df750f44bbd1b9a13402a9f7a6cfc8" }
specs = { git = "https://github.com/amethyst/specs.git", features = ["serde", "storage-event-control", "nightly"], rev = "d4435bdf496cf322c74886ca09dd8795984919b4" }
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git", rev = "9fab7b396acd6454585486e50ae4bfe2069858a9" }
# Serde
ron = { version = "0.6", default-features = false }
serde = { version = "1.0.110", features = ["derive", "rc"] }

View File

@ -28,7 +28,7 @@ pub fn handle_insert<C: Component>(comp: C, entity: Entity, world: &World) {
}
/// Useful for implementing CompPacket trait
pub fn handle_modify<C: Component + Debug>(comp: C, entity: Entity, world: &World) {
if let Some(c) = world.write_storage::<C>().get_mut(entity) {
if let Some(mut c) = world.write_storage::<C>().get_mut(entity) {
*c = comp
} else {
error!(

View File

@ -14,7 +14,7 @@ use crate::{
};
use arraygen::Arraygen;
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::time::Duration;
use vek::Vec3;
@ -977,5 +977,5 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
}
impl Component for Loadout {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -1,7 +1,7 @@
use crate::comp::buff::{BuffCategory, BuffData, BuffKind, BuffSource};
use serde::{Deserialize, Serialize};
use slotmap::{new_key_type, SlotMap};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::time::Duration;
@ -79,5 +79,5 @@ impl Auras {
}
impl Component for Auras {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -1,6 +1,6 @@
use crate::{uid::Uid, Damage, GroupTarget};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::time::Duration;
@ -27,7 +27,7 @@ pub struct BeamSegment {
}
impl Component for BeamSegment {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
impl std::ops::Deref for BeamSegment {

View File

@ -18,7 +18,7 @@ use crate::{
npc::NpcKind,
};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use vek::*;
@ -615,5 +615,5 @@ impl Body {
}
impl Component for Body {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -1,7 +1,7 @@
use crate::uid::Uid;
use hashbrown::HashMap;
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::{cmp::Ordering, time::Duration};
@ -312,5 +312,5 @@ impl Buffs {
pub type BuffId = u64;
impl Component for Buffs {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -5,7 +5,7 @@ use crate::{
Damage, GroupTarget, Knockback,
};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage, VecStorage};
use specs::{Component, DerefFlaggedStorage, VecStorage};
use specs_idvs::IdvStorage;
use std::collections::VecDeque;
@ -155,7 +155,7 @@ impl Default for CharacterState {
}
impl Component for CharacterState {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]

View File

@ -4,7 +4,7 @@ use crate::{
util::Dir,
};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::time::Duration;
use vek::*;
@ -261,12 +261,12 @@ pub enum MountState {
}
impl Component for MountState {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Mounting(pub Uid);
impl Component for Mounting {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -1,5 +1,5 @@
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
@ -83,5 +83,5 @@ pub struct EnergyChange {
}
impl Component for Energy {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -2,7 +2,7 @@ use crate::{comp::Alignment, uid::Uid};
use hashbrown::HashMap;
use serde::{Deserialize, Serialize};
use slab::Slab;
use specs::{Component, FlaggedStorage, Join};
use specs::{Component, DerefFlaggedStorage, Join};
use specs_idvs::IdvStorage;
use tracing::{error, warn};
@ -25,7 +25,7 @@ pub const ENEMY: Group = Group(u32::MAX);
pub const NPC: Group = Group(u32::MAX - 1);
impl Component for Group {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
pub struct Invite(pub specs::Entity);

View File

@ -1,6 +1,6 @@
use crate::{comp::Body, uid::Uid, DamageSource};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
/// Specifies what and how much changed current health
@ -118,7 +118,7 @@ impl Health {
}
impl Component for Health {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]

View File

@ -1,8 +1,8 @@
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage, NullStorage};
use specs::{Component, DerefFlaggedStorage, NullStorage};
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct CanBuild;
impl Component for CanBuild {
type Storage = FlaggedStorage<Self, NullStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, NullStorage<Self>>;
}

View File

@ -13,7 +13,7 @@ use crate::{
use crossbeam_utils::atomic::AtomicCell;
use rand::prelude::*;
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::{
num::{NonZeroU32, NonZeroU64},
@ -444,12 +444,12 @@ impl ItemDesc for ItemDef {
}
impl Component for Item {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ItemDrop(pub Item);
impl Component for ItemDrop {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = IdvStorage<Self>;
}

View File

@ -5,7 +5,7 @@ use crate::{comp::inventory::item::ItemDef, recipe::Recipe};
use core::ops::Not;
use item::Item;
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage, HashMapStorage};
use specs::{Component, HashMapStorage};
use specs_idvs::IdvStorage;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -304,7 +304,7 @@ impl InventoryUpdate {
}
impl Component for InventoryUpdate {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = IdvStorage<Self>;
}
#[cfg(test)] mod test;

View File

@ -1,6 +1,6 @@
use crate::resources::Time;
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::Component;
use specs_idvs::IdvStorage;
use vek::*;
@ -28,7 +28,7 @@ impl Waypoint {
}
impl Component for Waypoint {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = IdvStorage<Self>;
}
#[derive(Copy, Clone, Debug, PartialEq)]
@ -39,7 +39,7 @@ impl WaypointArea {
}
impl Component for WaypointArea {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = IdvStorage<Self>;
}
impl Default for WaypointArea {

View File

@ -1,6 +1,6 @@
use crate::{uid::Uid, util::Dir};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage, NullStorage};
use specs::{Component, DerefFlaggedStorage, NullStorage};
use specs_idvs::IdvStorage;
use vek::*;
@ -47,7 +47,7 @@ impl Component for PreviousVelDtCache {
pub struct Scale(pub f32);
impl Component for Scale {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
// Mass
@ -55,7 +55,7 @@ impl Component for Scale {
pub struct Mass(pub f32);
impl Component for Mass {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
// Mass
@ -82,21 +82,21 @@ impl Collider {
}
impl Component for Collider {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Gravity(pub f32);
impl Component for Gravity {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Sticky;
impl Component for Sticky {
type Storage = FlaggedStorage<Self, NullStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, NullStorage<Self>>;
}
// PhysicsState

View File

@ -1,5 +1,5 @@
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage, NullStorage};
use specs::{Component, DerefFlaggedStorage, NullStorage};
use specs_idvs::IdvStorage;
use uuid::Uuid;
@ -30,7 +30,7 @@ impl Player {
}
impl Component for Player {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]

View File

@ -5,7 +5,7 @@ use crate::{
Damage, DamageSource, Explosion, GroupTarget, Knockback, RadiusEffect,
};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::Component;
use specs_idvs::IdvStorage;
use std::time::Duration;
@ -38,7 +38,7 @@ pub struct Projectile {
}
impl Component for Projectile {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = IdvStorage<Self>;
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]

View File

@ -1,6 +1,6 @@
use crate::{uid::Uid, Damage, GroupTarget, Knockback};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::time::Duration;
@ -27,7 +27,7 @@ pub struct Shockwave {
}
impl Component for Shockwave {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
impl std::ops::Deref for Shockwave {

View File

@ -3,7 +3,7 @@ use crate::{
comp::{body::humanoid::Species, skills::SkillSet, Body},
};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::{error::Error, fmt};
@ -141,5 +141,5 @@ impl Stats {
}
impl Component for Stats {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -1,5 +1,5 @@
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use vek::*;
@ -23,7 +23,7 @@ impl Default for LightEmitter {
}
impl Component for LightEmitter {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -44,5 +44,5 @@ impl Default for LightAnimation {
}
impl Component for LightAnimation {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = IdvStorage<Self>;
}

View File

@ -9,7 +9,7 @@ use crate::{
use specs::{
hibitset,
storage::{PairedStorage, SequentialRestriction},
Entity, FlaggedStorage, LazyUpdate,
DerefFlaggedStorage, Entity, LazyUpdate,
};
use specs_idvs::IdvStorage;
@ -63,7 +63,7 @@ type RestrictedMut<'a, C> = PairedStorage<
'a,
'a,
C,
&'a mut FlaggedStorage<C, IdvStorage<C>>,
&'a mut DerefFlaggedStorage<C, IdvStorage<C>>,
&'a hibitset::BitSet,
SequentialRestriction,
>;

View File

@ -30,7 +30,7 @@ impl<'a> System<'a> for Sys {
auras.set_event_emission(false);
// Iterate through all entities with an aura
for (entity, pos, auras_comp) in (&entities, &positions, &mut auras).join() {
for (entity, pos, mut auras_comp) in (&entities, &positions, &mut auras).join() {
let mut expired_auras = Vec::<AuraKey>::new();
// Iterate through the auras attached to this entity
for (key, aura) in auras_comp.auras.iter_mut() {

View File

@ -233,7 +233,7 @@ impl<'a> System<'a> for Sys {
// Set start time on new beams
// This change doesn't need to be recorded as it is not sent to the client
beam_segments.set_event_emission(false);
(&mut beam_segments).join().for_each(|beam_segment| {
(&mut beam_segments).join().for_each(|mut beam_segment| {
if beam_segment.creation.is_none() {
beam_segment.creation = Some(time);
}

View File

@ -30,7 +30,7 @@ impl<'a> System<'a> for Sys {
// Set to false to avoid spamming server
buffs.set_event_emission(false);
healths.set_event_emission(false);
for (entity, buff_comp, health) in (&entities, &mut buffs, &mut healths).join() {
for (entity, mut buff_comp, mut health) in (&entities, &mut buffs, &mut healths).join() {
let mut expired_buffs = Vec::<BuffId>::new();
for (id, buff) in buff_comp.buffs.iter_mut() {
// Tick the buff and subtract delta from it
@ -66,6 +66,7 @@ impl<'a> System<'a> for Sys {
health.reset_max();
// Iterator over the lists of buffs by kind
let buff_comp = &mut *buff_comp;
for buff_ids in buff_comp.kinds.values() {
// Get the strongest of this buff kind
if let Some(buff) = buff_comp.buffs.get_mut(&buff_ids[0]) {
@ -113,9 +114,13 @@ impl<'a> System<'a> for Sys {
},
BuffEffect::MaxHealthModifier { value, kind } => match kind {
ModifierKind::Additive => {
health.set_maximum((health.maximum() as f32 + *value) as u32);
let health = &mut *health;
let buffed_health_max =
(health.maximum() as f32 + *value) as u32;
health.set_maximum(buffed_health_max);
},
ModifierKind::Fractional => {
let health = &mut *health;
health.set_maximum((health.maximum() as f32 * *value) as u32);
},
},

View File

@ -29,7 +29,8 @@ fn incorporate_update(tuple: &mut JoinTuple, state_update: StateUpdate) {
*tuple.6.get_mut_unchecked() = state_update.energy
};
if state_update.swap_loadout {
let loadout = tuple.7.get_mut_unchecked();
let mut loadout = tuple.7.get_mut_unchecked();
let loadout = &mut *loadout;
std::mem::swap(&mut loadout.active_item, &mut loadout.second_item);
}
}

View File

@ -52,7 +52,7 @@ impl<'a> System<'a> for Sys {
span!(_guard, "run", "controller::Sys::run");
let mut server_emitter = server_bus.emitter();
for (entity, _uid, controller, character_state) in
for (entity, _uid, controller, mut character_state) in
(&entities, &uids, &mut controllers, &mut character_states).join()
{
let mut inputs = &mut controller.inputs;

View File

@ -58,7 +58,7 @@ impl<'a> System<'a> for Sys {
let mut server_emitter = server_bus.emitter();
// Attacks
for (entity, pos, physics, ori, projectile) in (
for (entity, pos, physics, ori, mut projectile) in (
&entities,
&positions,
&physics_states,
@ -99,6 +99,7 @@ impl<'a> System<'a> for Sys {
continue;
}
let projectile = &mut *projectile;
for effect in projectile.hit_entity.drain(..) {
match effect {
projectile::Effect::Damage(target, damage) => {
@ -197,6 +198,7 @@ impl<'a> System<'a> for Sys {
// Hit something solid
if physics.on_wall.is_some() || physics.on_ground || physics.on_ceiling {
let projectile = &mut *projectile;
for effect in projectile.hit_solid.drain(..) {
match effect {
projectile::Effect::Explode(e) => {

View File

@ -217,7 +217,7 @@ impl<'a> System<'a> for Sys {
// Set start time on new shockwaves
// This change doesn't need to be recorded as it is not sent to the client
shockwaves.set_event_emission(false);
(&mut shockwaves).join().for_each(|shockwave| {
(&mut shockwaves).join().for_each(|mut shockwave| {
if shockwave.creation.is_none() {
shockwave.creation = Some(time);
}

View File

@ -43,7 +43,7 @@ impl<'a> System<'a> for Sys {
// Increment last change timer
healths.set_event_emission(false); // avoid unnecessary syncing
for health in (&mut healths).join() {
for mut health in (&mut healths).join() {
health.last_change.0 += f64::from(dt.0);
}
healths.set_event_emission(true);
@ -66,7 +66,7 @@ impl<'a> System<'a> for Sys {
};
if set_dead {
let health = health.get_mut_unchecked();
let mut health = health.get_mut_unchecked();
server_event_emitter.emit(ServerEvent::Destroy {
entity,
cause: health.last_change.1.cause,
@ -76,7 +76,8 @@ impl<'a> System<'a> for Sys {
}
if level_up {
let stat = stats.get_mut_unchecked();
let mut stat = stats.get_mut_unchecked();
let stat = &mut *stat;
while stat.exp.current() >= stat.exp.maximum() {
stat.exp.change_by(-(stat.exp.maximum() as i64));
stat.level.change_by(1);
@ -84,7 +85,8 @@ impl<'a> System<'a> for Sys {
server_event_emitter.emit(ServerEvent::LevelUp(entity, stat.level.level()));
}
let health = health.get_mut_unchecked();
let mut health = health.get_mut_unchecked();
let health = &mut *health;
health.update_max_hp(Some(stat.body_type), stat.level.level());
health.set_to(health.maximum(), HealthSource::LevelUp);
}
@ -111,6 +113,7 @@ impl<'a> System<'a> for Sys {
if res {
let mut energy = energy.get_mut_unchecked();
let energy = &mut *energy;
// Have to account for Calc I differential equations due to acceleration
energy.change_by(EnergyChange {
amount: (energy.regen_rate * dt.0

View File

@ -19,7 +19,7 @@ world = { package = "veloren-world", path = "../world" }
network = { package = "veloren_network", path = "../network", features = ["metrics", "compression"], default-features = false }
specs = { git = "https://github.com/amethyst/specs.git", features = ["shred-derive"], rev = "d4435bdf496cf322c74886ca09dd8795984919b4" }
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git", rev = "77048eefa5df750f44bbd1b9a13402a9f7a6cfc8" }
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git", rev = "9fab7b396acd6454585486e50ae4bfe2069858a9" }
tracing = "0.1"
vek = { version = "0.12.0", features = ["serde"] }

View File

@ -456,7 +456,7 @@ fn handle_kill(
.ecs_mut()
.write_storage::<comp::Health>()
.get_mut(target)
.map(|h| h.set_to(0, reason));
.map(|mut h| h.set_to(0, reason));
}
fn handle_time(
@ -582,7 +582,7 @@ fn handle_health(
action: &ChatCommand,
) {
if let Ok(hp) = scan_fmt!(&args, &action.arg_fmt(), u32) {
if let Some(health) = server
if let Some(mut health) = server
.state
.ecs()
.write_storage::<comp::Health>()
@ -632,7 +632,7 @@ fn handle_alias(
.ecs_mut()
.write_storage::<comp::Player>()
.get_mut(target)
.map(|player| std::mem::replace(&mut player.alias, alias));
.map(|mut player| std::mem::replace(&mut player.alias, alias));
// Update name on client player lists
let ecs = server.state.ecs();
@ -1074,7 +1074,7 @@ fn handle_kill_npcs(
let mut healths = ecs.write_storage::<comp::Health>();
let players = ecs.read_storage::<comp::Player>();
let mut count = 0;
for (health, ()) in (&mut healths, !&players).join() {
for (mut health, ()) in (&mut healths, !&players).join() {
count += 1;
health.set_to(0, comp::HealthSource::Command);
}
@ -1240,7 +1240,7 @@ fn handle_lantern(
action: &ChatCommand,
) {
if let (Some(s), r, g, b) = scan_fmt_some!(&args, &action.arg_fmt(), f32, f32, f32, f32) {
if let Some(light) = server
if let Some(mut light) = server
.state
.ecs()
.write_storage::<comp::LightEmitter>()
@ -1994,7 +1994,7 @@ fn handle_give_exp(
match target {
Ok(player) => {
if let Some(stats) = ecs.write_storage::<comp::Stats>().get_mut(player) {
if let Some(mut stats) = ecs.write_storage::<comp::Stats>().get_mut(player) {
stats.exp.change_by(exp);
} else {
error_msg = Some(ServerGeneral::server_msg(
@ -2042,7 +2042,7 @@ fn handle_set_level(
let body_type: Option<comp::Body>;
if let Some(stats) = server
if let Some(mut stats) = server
.state
.ecs_mut()
.write_storage::<comp::Stats>()
@ -2058,12 +2058,13 @@ fn handle_set_level(
body_type = None;
}
if let Some(health) = server
if let Some(mut health) = server
.state
.ecs_mut()
.write_storage::<comp::Health>()
.get_mut(player)
{
let health = &mut *health;
health.update_max_hp(body_type, lvl);
health.set_to(health.maximum(), comp::HealthSource::LevelUp);
}

View File

@ -34,7 +34,7 @@ use vek::Vec3;
pub fn handle_damage(server: &Server, entity: EcsEntity, change: HealthChange) {
let ecs = &server.state.ecs();
if let Some(health) = ecs.write_storage::<Health>().get_mut(entity) {
if let Some(mut health) = ecs.write_storage::<Health>().get_mut(entity) {
health.change_by(change);
}
}
@ -219,13 +219,13 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
let exp = exp_reward / (num_not_pets_in_range as f32 + ATTACKER_EXP_WEIGHT);
exp_reward = exp * ATTACKER_EXP_WEIGHT;
members_in_range.into_iter().for_each(|e| {
if let Some(stats) = stats.get_mut(e) {
if let Some(mut stats) = stats.get_mut(e) {
stats.exp.change_by(exp.ceil() as i64);
}
});
}
if let Some(attacker_stats) = stats.get_mut(attacker) {
if let Some(mut attacker_stats) = stats.get_mut(attacker) {
// TODO: Discuss whether we should give EXP by Player
// Killing or not.
attacker_stats.exp.change_by(exp_reward.ceil() as i64);
@ -258,7 +258,10 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
.ecs()
.write_storage::<comp::Energy>()
.get_mut(entity)
.map(|energy| energy.set_to(energy.maximum(), comp::EnergySource::Revive));
.map(|mut energy| {
let energy = &mut *energy;
energy.set_to(energy.maximum(), comp::EnergySource::Revive)
});
let _ = state
.ecs()
.write_storage::<comp::CharacterState>()
@ -429,7 +432,7 @@ pub fn handle_delete(server: &mut Server, entity: EcsEntity) {
pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>) {
let state = &server.state;
if vel.z <= -30.0 {
if let Some(health) = state.ecs().write_storage::<comp::Health>().get_mut(entity) {
if let Some(mut health) = state.ecs().write_storage::<comp::Health>().get_mut(entity) {
let falldmg = (vel.z.powi(2) / 20.0 - 40.0) * 10.0;
let damage = Damage {
source: DamageSource::Falling,
@ -461,7 +464,7 @@ pub fn handle_respawn(server: &Server, entity: EcsEntity) {
.ecs()
.write_storage::<comp::Health>()
.get_mut(entity)
.map(|health| health.revive());
.map(|mut health| health.revive());
state
.ecs()
.write_storage::<comp::Pos>()
@ -641,7 +644,7 @@ pub fn handle_explosion(
server.state().apply_effect(entity_b, effect.clone(), owner);
// Apply energy change
if let Some(owner) = owner_entity {
if let Some(energy) =
if let Some(mut energy) =
ecs.write_storage::<comp::Energy>().get_mut(owner)
{
energy.change_by(EnergyChange {
@ -677,7 +680,7 @@ pub fn handle_level_up(server: &mut Server, entity: EcsEntity, new_level: u32) {
pub fn handle_aura(server: &mut Server, entity: EcsEntity, aura_change: aura::AuraChange) {
let ecs = &server.state.ecs();
let mut auras_all = ecs.write_storage::<comp::Auras>();
if let Some(auras) = auras_all.get_mut(entity) {
if let Some(mut auras) = auras_all.get_mut(entity) {
use aura::AuraChange;
match aura_change {
AuraChange::Add(new_aura) => {
@ -695,7 +698,7 @@ pub fn handle_aura(server: &mut Server, entity: EcsEntity, aura_change: aura::Au
pub fn handle_buff(server: &mut Server, entity: EcsEntity, buff_change: buff::BuffChange) {
let ecs = &server.state.ecs();
let mut buffs_all = ecs.write_storage::<comp::Buffs>();
if let Some(buffs) = buffs_all.get_mut(entity) {
if let Some(mut buffs) = buffs_all.get_mut(entity) {
use buff::BuffChange;
match buff_change {
BuffChange::Add(new_buff) => {
@ -756,7 +759,7 @@ pub fn handle_buff(server: &mut Server, entity: EcsEntity, buff_change: buff::Bu
pub fn handle_energy_change(server: &Server, entity: EcsEntity, change: EnergyChange) {
let ecs = &server.state.ecs();
if let Some(energy) = ecs.write_storage::<Energy>().get_mut(entity) {
if let Some(mut energy) = ecs.write_storage::<Energy>().get_mut(entity) {
energy.change_by(change);
}
}

View File

@ -100,7 +100,7 @@ pub fn handle_unmount(server: &mut Server, mounter: EcsEntity) {
.ecs()
.write_storage::<comp::MountState>()
.get_mut(mountee_entity)
.map(|ms| *ms = comp::MountState::Unmounted);
.map(|mut ms| *ms = comp::MountState::Unmounted);
}
state.delete_component::<comp::Mounting>(mounter);
}
@ -174,7 +174,7 @@ pub fn handle_possess(server: &Server, possessor_uid: Uid, possesse_uid: Uid) {
// Put possess item into loadout
let mut loadouts = ecs.write_storage::<comp::Loadout>();
let loadout = loadouts
let mut loadout = loadouts
.entry(possesse)
.expect("Could not read loadouts component while possessing")
.or_insert(comp::Loadout::default());
@ -182,6 +182,7 @@ pub fn handle_possess(server: &Server, possessor_uid: Uid, possesse_uid: Uid) {
let item = comp::Item::new_from_asset_expect("common.items.debug.possess");
if let item::ItemKind::Tool(_) = item.kind() {
let debug_item = comp::ItemConfig::from((item, &*ability_map));
let loadout = &mut *loadout;
std::mem::swap(&mut loadout.active_item, &mut loadout.second_item);
loadout.active_item = Some(debug_item);
}

View File

@ -23,7 +23,7 @@ pub fn swap_lantern(
entity: EcsEntity,
lantern: &item::Lantern,
) {
if let Some(light) = storage.get_mut(entity) {
if let Some(mut light) = storage.get_mut(entity) {
light.strength = lantern.strength();
light.col = lantern.color();
}
@ -224,12 +224,14 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
_ => (false, None),
});
if is_equippable {
if let Some(loadout) = state.ecs().write_storage().get_mut(entity) {
if let Some(mut loadout) =
state.ecs().write_storage::<comp::Loadout>().get_mut(entity)
{
if let Some(lantern) = lantern_opt {
swap_lantern(&mut state.ecs().write_storage(), entity, &lantern);
}
let ability_map = state.ability_map();
slot::equip(slot, inventory, loadout, &ability_map);
slot::equip(slot, inventory, &mut loadout, &ability_map);
Some(comp::InventoryUpdateEvent::Used)
} else {
None
@ -359,12 +361,14 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
}
},
Slot::Equip(slot) => {
if let Some(loadout) = state.ecs().write_storage().get_mut(entity) {
if let Some(mut loadout) =
state.ecs().write_storage::<comp::Loadout>().get_mut(entity)
{
if slot == slot::EquipSlot::Lantern {
snuff_lantern(&mut state.ecs().write_storage(), entity);
}
let ability_map = state.ability_map();
slot::unequip(slot, inventory, loadout, &ability_map);
slot::unequip(slot, inventory, &mut loadout, &ability_map);
Some(comp::InventoryUpdateEvent::Used)
} else {
error!(?entity, "Entity doesn't have a loadout, can't unequip...");
@ -386,13 +390,15 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
comp::InventoryManip::Swap(a, b) => {
let ecs = state.ecs();
let mut inventories = ecs.write_storage();
let mut loadouts = ecs.write_storage();
let mut inventories = ecs.write_storage::<comp::Inventory>();
let mut loadouts = ecs.write_storage::<comp::Loadout>();
let inventory = inventories.get_mut(entity);
let loadout = loadouts.get_mut(entity);
let mut loadout = loadouts.get_mut(entity);
let ability_map = state.ability_map();
slot::swap(a, b, inventory, loadout, &ability_map);
slot::swap(a, b, inventory, loadout.as_deref_mut(), &ability_map);
// slot::swap(a, b, inventory, loadout.as_mut().map(|x| &mut **x),
// &ability_map);
// :/
drop(loadouts);
@ -415,9 +421,9 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
.and_then(|inv| inv.remove(slot)),
Slot::Equip(slot) => state
.ecs()
.write_storage()
.write_storage::<comp::Loadout>()
.get_mut(entity)
.and_then(|ldt| slot::loadout_remove(slot, ldt, &ability_map)),
.and_then(|mut ldt| slot::loadout_remove(slot, &mut ldt, &ability_map)),
};
drop(ability_map);

View File

@ -1,7 +1,7 @@
use common_net::msg::PresenceKind;
use hashbrown::HashSet;
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use vek::*;
@ -21,7 +21,7 @@ impl Presence {
}
impl Component for Presence {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}
// Distance from fuzzy_chunk before snapping to current chunk
@ -36,5 +36,5 @@ pub struct RegionSubscription {
}
impl Component for RegionSubscription {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -81,13 +81,13 @@ impl StateExt for State {
self.ecs()
.write_storage::<comp::Health>()
.get_mut(entity)
.map(|health| health.change_by(change));
.map(|mut health| health.change_by(change));
},
Effect::Xp(xp) => {
self.ecs()
.write_storage::<comp::Stats>()
.get_mut(entity)
.map(|stats| stats.exp.change_by(xp));
.map(|mut stats| stats.exp.change_by(xp));
},
Effect::Damage(damage) => {
let loadouts = self.ecs().read_storage::<comp::Loadout>();
@ -95,13 +95,13 @@ impl StateExt for State {
self.ecs()
.write_storage::<comp::Health>()
.get_mut(entity)
.map(|health| health.change_by(change));
.map(|mut health| health.change_by(change));
},
Effect::Buff(buff) => {
self.ecs()
.write_storage::<comp::Buffs>()
.get_mut(entity)
.map(|buffs| {
.map(|mut buffs| {
buffs.insert(comp::Buff::new(
buff.kind,
buff.data,

View File

@ -146,17 +146,17 @@ impl Sys {
ClientGeneral::UnlockSkill(skill) => {
stats
.get_mut(entity)
.map(|s| s.skill_set.unlock_skill(skill));
.map(|mut s| s.skill_set.unlock_skill(skill));
},
ClientGeneral::RefundSkill(skill) => {
stats
.get_mut(entity)
.map(|s| s.skill_set.refund_skill(skill));
.map(|mut s| s.skill_set.refund_skill(skill));
},
ClientGeneral::UnlockSkillGroup(skill_group_type) => {
stats
.get_mut(entity)
.map(|s| s.skill_set.unlock_skill_group(skill_group_type));
.map(|mut s| s.skill_set.unlock_skill_group(skill_group_type));
},
_ => unreachable!("not a client_in_game msg"),
}
@ -223,7 +223,7 @@ impl<'a> System<'a> for Sys {
&mut server_emitter,
entity,
client,
&mut maybe_presence,
&mut maybe_presence.as_deref_mut(),
&terrain,
&network_metrics,
&can_build,

View File

@ -74,7 +74,7 @@ impl<'a> System<'a> for Sys {
// 7. Determine list of regions that are in range and iterate through it
// - check if in hashset (hash calc) if not add it
let mut regions_to_remove = Vec::new();
for (subscription, pos, presence, client_entity, client) in (
for (mut subscription, pos, presence, client_entity, client) in (
&mut subscriptions,
&positions,
&presences,

View File

@ -46,7 +46,7 @@ glyph_brush = "0.7.0"
# ECS
specs = {git = "https://github.com/amethyst/specs.git", rev = "d4435bdf496cf322c74886ca09dd8795984919b4"}
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git", rev = "77048eefa5df750f44bbd1b9a13402a9f7a6cfc8" }
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git", rev = "9fab7b396acd6454585486e50ae4bfe2069858a9" }
# Mathematics
vek = {version = "0.12.0", features = ["serde"]}

View File

@ -394,7 +394,7 @@ impl FigureMgr {
}
let dt = ecs.fetch::<DeltaTime>().0;
let updater = ecs.read_resource::<LazyUpdate>();
for (entity, light_emitter_opt, body, light_anim) in (
for (entity, light_emitter_opt, body, mut light_anim) in (
&ecs.entities(),
ecs.read_storage::<LightEmitter>().maybe(),
ecs.read_storage::<Body>().maybe(),