diff --git a/server/src/persistence/character/conversions.rs b/server/src/persistence/character/conversions.rs index 4e0132acac..eec1262e13 100644 --- a/server/src/persistence/character/conversions.rs +++ b/server/src/persistence/character/conversions.rs @@ -5,7 +5,7 @@ use crate::persistence::{ use crate::persistence::{ error::PersistenceError, - json_models::{self, CharacterPosition, GenericBody, HumanoidBody}, + json_models::{self, CharacterPosition, DatabaseAbilitySet, GenericBody, HumanoidBody}, }; use common::{ character::CharacterId, @@ -607,11 +607,7 @@ pub fn convert_active_abilities_to_database( entity_id: CharacterId, active_abilities: &ability::ActiveAbilities, ) -> AbilitySets { - let ability_sets = active_abilities - .auxiliary_sets - .iter() - .filter_map(|set| serde_json::to_string(&set).ok()) - .collect::>(); + let ability_sets = json_models::active_abilities_to_db_model(active_abilities); AbilitySets { entity_id, ability_sets: serde_json::to_string(&ability_sets).unwrap_or_default(), @@ -621,10 +617,7 @@ pub fn convert_active_abilities_to_database( pub fn convert_active_abilities_from_database( ability_sets: &AbilitySets, ) -> ability::ActiveAbilities { - let ability_sets = core::iter::once(ability_sets) - .flat_map(|sets| serde_json::from_str::>(&sets.ability_sets)) - .flatten() - .filter_map(|set| serde_json::from_str::<(ability::AuxiliaryKey, [ability::AuxiliaryAbility; ability::MAX_ABILITIES])>(&set).ok()) - .collect::>(); - ability::ActiveAbilities::new(ability_sets) + let ability_sets = serde_json::from_str::>(&ability_sets.ability_sets) + .unwrap_or_default(); + json_models::active_abilities_from_db_model(ability_sets) } diff --git a/server/src/persistence/json_models.rs b/server/src/persistence/json_models.rs index 41e0be70f9..0062f35d13 100644 --- a/server/src/persistence/json_models.rs +++ b/server/src/persistence/json_models.rs @@ -1,4 +1,5 @@ use common::comp; +use hashbrown::HashMap; use serde::{Deserialize, Serialize}; use std::string::ToString; use vek::Vec3; @@ -106,3 +107,47 @@ pub fn db_string_to_skill_group(skill_group_string: &str) -> comp::skillset::Ski ), } } + +#[derive(Serialize, Deserialize)] +pub struct DatabaseAbilitySet { + mainhand: Option, + offhand: Option, + abilities: Vec, +} + +pub fn active_abilities_to_db_model( + active_abilities: &comp::ability::ActiveAbilities, +) -> Vec { + active_abilities + .auxiliary_sets + .iter() + .map(|((mainhand, offhand), abilities)| DatabaseAbilitySet { + mainhand: *mainhand, + offhand: *offhand, + abilities: abilities.to_vec(), + }) + .collect::>() +} + +pub fn active_abilities_from_db_model( + ability_sets: Vec, +) -> comp::ability::ActiveAbilities { + let ability_sets = ability_sets + .iter() + .map( + |DatabaseAbilitySet { + mainhand, + offhand, + abilities, + }| { + let mut auxiliary_abilities = + [comp::ability::AuxiliaryAbility::Empty; comp::ability::MAX_ABILITIES]; + for (empty, ability) in auxiliary_abilities.iter_mut().zip(abilities.iter()) { + *empty = *ability; + } + ((*mainhand, *offhand), auxiliary_abilities) + }, + ) + .collect::>(); + comp::ability::ActiveAbilities::new(ability_sets) +}