diff --git a/common/src/states/behavior.rs b/common/src/states/behavior.rs index 3ba86e0b06..b54ff433e6 100644 --- a/common/src/states/behavior.rs +++ b/common/src/states/behavior.rs @@ -8,12 +8,7 @@ use crate::{ terrain::TerrainGrid, uid::Uid, }; -use specs::{ - hibitset, - storage::{PairedStorage, SequentialRestriction}, - DerefFlaggedStorage, Entity, LazyUpdate, -}; -use specs_idvs::IdvStorage; +use specs::{storage::FlaggedAccessMut, Entity, LazyUpdate}; use vek::*; pub trait CharacterBehavior { @@ -100,25 +95,16 @@ pub struct JoinData<'a> { pub terrain: &'a TerrainGrid, } -type RestrictedMut<'a, C> = PairedStorage< - 'a, - 'a, - C, - &'a mut DerefFlaggedStorage>, - &'a hibitset::BitSet, - SequentialRestriction, ->; - pub struct JoinStruct<'a> { pub entity: Entity, pub uid: &'a Uid, - pub char_state: RestrictedMut<'a, CharacterState>, + pub char_state: FlaggedAccessMut<'a, &'a mut CharacterState, CharacterState>, pub pos: &'a mut Pos, pub vel: &'a mut Vel, pub ori: &'a mut Ori, pub mass: &'a Mass, pub density: &'a mut Density, - pub energy: RestrictedMut<'a, Energy>, + pub energy: FlaggedAccessMut<'a, &'a mut Energy, Energy>, pub inventory: Option<&'a Inventory>, pub controller: &'a mut Controller, pub health: Option<&'a Health>, @@ -143,13 +129,13 @@ impl<'a> JoinData<'a> { Self { entity: j.entity, uid: j.uid, - character: j.char_state.get_unchecked(), + character: &j.char_state, pos: j.pos, vel: j.vel, ori: j.ori, mass: j.mass, density: j.density, - energy: j.energy.get_unchecked(), + energy: &j.energy, inventory: j.inventory, controller: j.controller, inputs: &j.controller.inputs, diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index 454288c482..80d3586d2f 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -28,16 +28,16 @@ fn incorporate_update( server_emitter: &mut Emitter, ) { // TODO: if checking equality is expensive use optional field in StateUpdate - if join.char_state.get_unchecked() != &state_update.character { - *join.char_state.get_mut_unchecked() = state_update.character + if *join.char_state != state_update.character { + *join.char_state = state_update.character }; *join.pos = state_update.pos; *join.vel = state_update.vel; *join.ori = state_update.ori; *join.density = state_update.density; // Note: might be changed every tick by timer anyway - if join.energy.get_unchecked() != &state_update.energy { - *join.energy.get_mut_unchecked() = state_update.energy + if *join.energy != state_update.energy { + *join.energy = state_update.energy }; join.controller .queued_inputs @@ -140,13 +140,13 @@ impl<'a> System<'a> for Sys { ) in ( &read_data.entities, &read_data.uids, - &mut character_states.restrict_mut(), + &mut character_states, &mut positions, &mut velocities, &mut orientations, &read_data.masses, &mut densities, - &mut energies.restrict_mut(), + &mut energies, read_data.inventories.maybe(), &mut controllers, read_data.healths.maybe(), @@ -165,7 +165,7 @@ impl<'a> System<'a> for Sys { // Enter stunned state if poise damage is enough if let Some(mut poise) = poises.get_mut(entity) { - let was_wielded = char_state.get_unchecked().is_wield(); + let was_wielded = char_state.is_wield(); let poise_state = poise.poise_state(); let pos = pos.0; // Remove potion/saturation buff if knocked into poise state @@ -184,18 +184,17 @@ impl<'a> System<'a> for Sys { PoiseState::Normal => {}, PoiseState::Interrupted => { poise.reset(); - *char_state.get_mut_unchecked() = - CharacterState::Stunned(common::states::stunned::Data { - static_data: common::states::stunned::StaticData { - buildup_duration: Duration::from_millis(125), - recover_duration: Duration::from_millis(125), - movement_speed: 0.80, - poise_state, - }, - timer: Duration::default(), - stage_section: common::states::utils::StageSection::Buildup, - was_wielded, - }); + *char_state = CharacterState::Stunned(common::states::stunned::Data { + static_data: common::states::stunned::StaticData { + buildup_duration: Duration::from_millis(125), + recover_duration: Duration::from_millis(125), + movement_speed: 0.80, + poise_state, + }, + timer: Duration::default(), + stage_section: common::states::utils::StageSection::Buildup, + was_wielded, + }); outcomes.push(Outcome::PoiseChange { pos, state: PoiseState::Interrupted, @@ -203,18 +202,17 @@ impl<'a> System<'a> for Sys { }, PoiseState::Stunned => { poise.reset(); - *char_state.get_mut_unchecked() = - CharacterState::Stunned(common::states::stunned::Data { - static_data: common::states::stunned::StaticData { - buildup_duration: Duration::from_millis(300), - recover_duration: Duration::from_millis(300), - movement_speed: 0.65, - poise_state, - }, - timer: Duration::default(), - stage_section: common::states::utils::StageSection::Buildup, - was_wielded, - }); + *char_state = CharacterState::Stunned(common::states::stunned::Data { + static_data: common::states::stunned::StaticData { + buildup_duration: Duration::from_millis(300), + recover_duration: Duration::from_millis(300), + movement_speed: 0.65, + poise_state, + }, + timer: Duration::default(), + stage_section: common::states::utils::StageSection::Buildup, + was_wielded, + }); outcomes.push(Outcome::PoiseChange { pos, state: PoiseState::Stunned, @@ -226,18 +224,17 @@ impl<'a> System<'a> for Sys { }, PoiseState::Dazed => { poise.reset(); - *char_state.get_mut_unchecked() = - CharacterState::Stunned(common::states::stunned::Data { - static_data: common::states::stunned::StaticData { - buildup_duration: Duration::from_millis(600), - recover_duration: Duration::from_millis(250), - movement_speed: 0.45, - poise_state, - }, - timer: Duration::default(), - stage_section: common::states::utils::StageSection::Buildup, - was_wielded, - }); + *char_state = CharacterState::Stunned(common::states::stunned::Data { + static_data: common::states::stunned::StaticData { + buildup_duration: Duration::from_millis(600), + recover_duration: Duration::from_millis(250), + movement_speed: 0.45, + poise_state, + }, + timer: Duration::default(), + stage_section: common::states::utils::StageSection::Buildup, + was_wielded, + }); outcomes.push(Outcome::PoiseChange { pos, state: PoiseState::Dazed, @@ -249,18 +246,17 @@ impl<'a> System<'a> for Sys { }, PoiseState::KnockedDown => { poise.reset(); - *char_state.get_mut_unchecked() = - CharacterState::Stunned(common::states::stunned::Data { - static_data: common::states::stunned::StaticData { - buildup_duration: Duration::from_millis(750), - recover_duration: Duration::from_millis(500), - movement_speed: 0.4, - poise_state, - }, - timer: Duration::default(), - stage_section: common::states::utils::StageSection::Buildup, - was_wielded, - }); + *char_state = CharacterState::Stunned(common::states::stunned::Data { + static_data: common::states::stunned::StaticData { + buildup_duration: Duration::from_millis(750), + recover_duration: Duration::from_millis(500), + movement_speed: 0.4, + poise_state, + }, + timer: Duration::default(), + stage_section: common::states::utils::StageSection::Buildup, + was_wielded, + }); outcomes.push(Outcome::PoiseChange { pos, state: PoiseState::KnockedDown, @@ -357,8 +353,8 @@ impl<'a> System<'a> for Sys { // If mounted, character state is controlled by mount if let Some(Mounting(_)) = read_data.mountings.get(entity) { let idle_state = CharacterState::Idle {}; - if join_struct.char_state.get_unchecked() != &idle_state { - *join_struct.char_state.get_mut_unchecked() = idle_state; + if *join_struct.char_state != idle_state { + *join_struct.char_state = idle_state; } continue; } diff --git a/common/systems/src/mount.rs b/common/systems/src/mount.rs index 04139ed167..f2c8a69c98 100644 --- a/common/systems/src/mount.rs +++ b/common/systems/src/mount.rs @@ -45,10 +45,9 @@ impl<'a> System<'a> for Sys { ): Self::SystemData, ) { // Mounted entities. - for (entity, mut mount_states, body) in - (&entities, &mut mount_state.restrict_mut(), bodies.maybe()).join() + for (entity, mut mount_states, body) in (&entities, &mut mount_state, bodies.maybe()).join() { - match mount_states.get_unchecked() { + match *mount_states { MountState::Unmounted => {}, MountState::MountedBy(mounter_uid) => { // Note: currently controller events are not passed through since none of them @@ -82,7 +81,7 @@ impl<'a> System<'a> for Sys { } } } else { - *(mount_states.get_mut_unchecked()) = MountState::Unmounted; + *mount_states = MountState::Unmounted; } }, } diff --git a/common/systems/src/stats.rs b/common/systems/src/stats.rs index a5bfb8aefc..e3cc55faa3 100644 --- a/common/systems/src/stats.rs +++ b/common/systems/src/stats.rs @@ -90,21 +90,17 @@ impl<'a> System<'a> for Sys { &read_data.entities, &read_data.uids, &stats, - &mut skill_sets.restrict_mut(), - &mut healths.restrict_mut(), + &mut skill_sets, + &mut healths, &read_data.positions, - &mut energies.restrict_mut(), + &mut energies, read_data.inventories.maybe(), ) .join() { - let set_dead = { - let health = health.get_unchecked(); - health.should_die() && !health.is_dead - }; + let set_dead = { health.should_die() && !health.is_dead }; if set_dead { - let mut health = health.get_mut_unchecked(); let cloned_entity = (entity, *pos); entities_died_last_tick.0.push(cloned_entity); server_event_emitter.emit(ServerEvent::Destroy { @@ -117,21 +113,18 @@ impl<'a> System<'a> for Sys { let stat = stats; let update_max_hp = { - let health = health.get_unchecked(); (stat.max_health_modifier - 1.0).abs() > f32::EPSILON || health.base_max() != health.maximum() }; if update_max_hp { - let mut health = health.get_mut_unchecked(); health.scale_maximum(stat.max_health_modifier); } let (change_energy, energy_scaling) = { - let energy = energy.get_unchecked(); // Calculates energy scaling from stats and inventory let new_energy_scaling = - combat::compute_max_energy_mod(energy, inventory) + stat.max_energy_modifier; + combat::compute_max_energy_mod(&energy, inventory) + stat.max_energy_modifier; let current_energy_scaling = energy.maximum() as f32 / energy.base_max() as f32; // Only changes energy if new modifier different from old modifer // TODO: Look into using wider threshold incase floating point imprecision makes @@ -144,22 +137,19 @@ impl<'a> System<'a> for Sys { // If modifier sufficiently different, mutably access energy if change_energy { - let mut energy = energy.get_mut_unchecked(); energy.scale_maximum(energy_scaling); } - let skillset = skill_set.get_unchecked(); - let skills_to_level = skillset + let skills_to_level = skill_set .skill_groups .iter() .filter_map(|s_g| { - (s_g.exp >= skillset.skill_point_cost(s_g.skill_group_kind)) + (s_g.exp >= skill_set.skill_point_cost(s_g.skill_group_kind)) .then(|| s_g.skill_group_kind) }) .collect::>(); if !skills_to_level.is_empty() { - let mut skill_set = skill_set.get_mut_unchecked(); for skill_group in skills_to_level { skill_set.earn_skill_point(skill_group); outcomes.push(Outcome::SkillPointGain { @@ -174,44 +164,34 @@ impl<'a> System<'a> for Sys { // Apply effects from leveling skills for (mut skill_set, mut health, mut energy, body) in ( - &mut skill_sets.restrict_mut(), - &mut healths.restrict_mut(), - &mut energies.restrict_mut(), + &mut skill_sets, + &mut healths, + &mut energies, &read_data.bodies, ) .join() { - let skillset = skill_set.get_unchecked(); - if skillset.modify_health { - let mut health = health.get_mut_unchecked(); - let health_level = skillset + if skill_set.modify_health { + let health_level = skill_set .skill_level(Skill::General(GeneralSkill::HealthIncrease)) .unwrap_or(None) .unwrap_or(0); health.update_max_hp(Some(*body), health_level); - let mut skillset = skill_set.get_mut_unchecked(); - skillset.modify_health = false; + skill_set.modify_health = false; } - let skillset = skill_set.get_unchecked(); - if skillset.modify_energy { - let mut energy = energy.get_mut_unchecked(); - let energy_level = skillset + if skill_set.modify_energy { + let energy_level = skill_set .skill_level(Skill::General(GeneralSkill::EnergyIncrease)) .unwrap_or(None) .unwrap_or(0); energy.update_max_energy(Some(*body), energy_level); - let mut skill_set = skill_set.get_mut_unchecked(); skill_set.modify_energy = false; } } // Update energies and poises - for (character_state, mut energy, mut poise) in ( - &read_data.char_states, - &mut energies.restrict_mut(), - &mut poises.restrict_mut(), - ) - .join() + for (character_state, mut energy, mut poise) in + (&read_data.char_states, &mut energies, &mut poises).join() { match character_state { // Accelerate recharging energy. @@ -225,13 +205,9 @@ impl<'a> System<'a> for Sys { | CharacterState::Wielding { .. } | CharacterState::Equipping { .. } | CharacterState::Boost { .. } => { - let res = { - let energy = energy.get_unchecked(); - energy.current() < energy.maximum() - }; + let res = { energy.current() < energy.maximum() }; 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 { @@ -243,13 +219,9 @@ impl<'a> System<'a> for Sys { (energy.regen_rate + ENERGY_REGEN_ACCEL * dt).min(100.0); } - let res_poise = { - let poise = poise.get_unchecked(); - poise.current() < poise.maximum() - }; + let res_poise = { poise.current() < poise.maximum() }; if res_poise { - let mut poise = poise.get_mut_unchecked(); let poise = &mut *poise; poise.change_by( PoiseChange { @@ -280,8 +252,8 @@ impl<'a> System<'a> for Sys { | CharacterState::BasicSummon { .. } | CharacterState::SelfBuff { .. } | CharacterState::SpriteSummon { .. } => { - if energy.get_unchecked().regen_rate != 0.0 { - energy.get_mut_unchecked().regen_rate = 0.0 + if energy.regen_rate != 0.0 { + energy.regen_rate = 0.0 } }, // Abilities that temporarily stall energy gain, but preserve regen_rate.