Finish save game conversion

This commit is contained in:
hodasemi 2024-08-26 13:29:24 +02:00
parent 53036fc3d0
commit 537d050287
8 changed files with 93 additions and 101 deletions

View file

@ -8,7 +8,7 @@ use rpg_components::{
level::Level, level::Level,
statistics::Statistics, statistics::Statistics,
}, },
config::attributes::AttributeSettings, config::{attributes::AttributeSettings, items::ItemSettings},
}; };
use super::{CharacterWindow, Page}; use super::{CharacterWindow, Page};
@ -207,6 +207,7 @@ impl CharacterPage {
let mut multi_mut = entity.multi_mut(); let mut multi_mut = entity.multi_mut();
let attribute_settings = resources.get::<AttributeSettings>(); let attribute_settings = resources.get::<AttributeSettings>();
let item_settings = resources.get::<ItemSettings>();
let level = multi_mut.get::<Level>()?; let level = multi_mut.get::<Level>()?;
let attributes = multi_mut.get::<Attributes>()?; let attributes = multi_mut.get::<Attributes>()?;
@ -217,7 +218,7 @@ impl CharacterPage {
let statistics = multi_mut.get::<Statistics>()?; let statistics = multi_mut.get::<Statistics>()?;
let items = multi_mut.get::<ItemSlotContainer>()?; let items = multi_mut.get::<ItemSlotContainer>()?;
statistics.update(attributes, attribute_settings, &*items); statistics.update(attributes, attribute_settings, (&*items, item_settings));
upgraded = true; upgraded = true;
} }

View file

@ -92,7 +92,7 @@ impl Content<Item> {
statistics.update( statistics.update(
attributes, attributes,
resources.get::<AttributeSettings>(), resources.get::<AttributeSettings>(),
&*hero_items, (&*hero_items, resources.get::<ItemSettings>()),
); );
Ok(()) Ok(())

View file

@ -3,7 +3,7 @@ use rpg_components::{
attributes::Attributes, character_status::CharacterStatus, inventory::Inventory, attributes::Attributes, character_status::CharacterStatus, inventory::Inventory,
item_slots::ItemSlotContainer, statistics::Statistics, item_slots::ItemSlotContainer, statistics::Statistics,
}, },
config::attributes::AttributeSettings, config::{attributes::AttributeSettings, items::ItemSettings},
items::{Item, ItemAffix, Tooltip}, items::{Item, ItemAffix, Tooltip},
}; };
@ -257,7 +257,7 @@ mod macros {
statistics.update( statistics.update(
attributes, attributes,
resources.get::<AttributeSettings>(), resources.get::<AttributeSettings>(),
&*items (&*items, resources.get::<ItemSettings>())
); );
let status = multi_mut.get::<CharacterStatus>()?; let status = multi_mut.get::<CharacterStatus>()?;
@ -409,7 +409,7 @@ mod macros {
statistics.update( statistics.update(
attributes, attributes,
resources.get::<AttributeSettings>(), resources.get::<AttributeSettings>(),
&*items (&*items, resources.get::<ItemSettings>())
); );
let status = multi_mut.get::<CharacterStatus>()?; let status = multi_mut.get::<CharacterStatus>()?;

View file

@ -272,6 +272,7 @@ impl JewelRightSide {
} }
ReferenceItemSource::Slots(opt_index) => { ReferenceItemSource::Slots(opt_index) => {
let attribute_settings = resources.get::<AttributeSettings>(); let attribute_settings = resources.get::<AttributeSettings>();
let item_settings = resources.get::<ItemSettings>();
let mut multi_mut = entity.multi_mut(); let mut multi_mut = entity.multi_mut();
@ -306,7 +307,11 @@ impl JewelRightSide {
let statistics = multi_mut.get::<Statistics>()?; let statistics = multi_mut.get::<Statistics>()?;
let attributes = multi_mut.get::<Attributes>()?; let attributes = multi_mut.get::<Attributes>()?;
statistics.update(attributes, attribute_settings, &*item_slots); statistics.update(
attributes,
attribute_settings,
(&*item_slots, &*item_settings),
);
} }
} }
} }

View file

@ -96,6 +96,7 @@ impl Hero {
let exp_settings = &game.experience_settings; let exp_settings = &game.experience_settings;
let attribute_settings = &game.attribute_settings; let attribute_settings = &game.attribute_settings;
let item_settings = &game.item_settings;
let item_system = &game.item_system(); let item_system = &game.item_system();
let level = Self::level(&hero_create_type, exp_settings); let level = Self::level(&hero_create_type, exp_settings);
@ -107,7 +108,7 @@ impl Hero {
let movement = Self::movement(&mut entity_object); let movement = Self::movement(&mut entity_object);
let mut stats = Statistics::default(); let mut stats = Statistics::default();
stats.update(&mut attributes, attribute_settings, &items); stats.update(&mut attributes, attribute_settings, (&items, item_settings));
let current_status = CharacterStatus::new_full(&stats); let current_status = CharacterStatus::new_full(&stats);
@ -140,6 +141,7 @@ impl Hero {
let exp_settings = &game.experience_settings; let exp_settings = &game.experience_settings;
let attribute_settings = &game.attribute_settings; let attribute_settings = &game.attribute_settings;
let item_settings = &game.item_settings;
let item_system = &game.item_system(); let item_system = &game.item_system();
{ {
@ -154,7 +156,7 @@ impl Hero {
let movement = Self::movement(&mut entity_object); let movement = Self::movement(&mut entity_object);
let mut stats = Statistics::default(); let mut stats = Statistics::default();
stats.update(&mut attributes, attribute_settings, &items); stats.update(&mut attributes, attribute_settings, (&items, item_settings));
let current_status = CharacterStatus::new_full(&stats); let current_status = CharacterStatus::new_full(&stats);
@ -404,14 +406,10 @@ impl Hero {
let game = game_handle.upgrade(); let game = game_handle.upgrade();
let mut items = match hero_create_type { let mut items = match hero_create_type {
HeroCreateType::SaveGame(save_game) => ItemSlotContainer::load( HeroCreateType::SaveGame(save_game) => {
save_game, ItemSlotContainer::load(save_game, &game.item_system())?
game.item_settings.clone(), }
draw, HeroCreateType::New(_) => ItemSlotContainer::new(),
multi_mut.get::<ItemSlotContainer>()?.item_meshes().clone(),
&game.item_system(),
)?,
HeroCreateType::New(_) => ItemSlotContainer::empty(game.item_settings.clone(), draw)?,
}; };
items.set_item_change_callback(draw, multi_mut.get::<Location>()?)?; items.set_item_change_callback(draw, multi_mut.get::<Location>()?)?;

View file

@ -2,7 +2,7 @@ use anyhow::Result;
use engine::prelude::*; use engine::prelude::*;
use paste; use paste;
use std::{collections::HashMap, sync::Arc}; use std::collections::HashMap;
use crate::{ use crate::{
config::{items::ItemSettings, save_game::SaveGame}, config::{items::ItemSettings, save_game::SaveGame},
@ -156,14 +156,11 @@ pub struct ItemSlotContainer {
slot_changed_callback: Option< slot_changed_callback: Option<
Box<dyn Fn(ItemSlots, Rarities, bool, &mut MultiMut<'_>) -> Result<()> + Send + Sync>, Box<dyn Fn(ItemSlots, Rarities, bool, &mut MultiMut<'_>) -> Result<()> + Send + Sync>,
>, >,
item_meshes: Arc<HashMap<ItemSlots, HashMap<Rarities, AssetMesh>>>,
item_settings: ItemSettings,
} }
impl ItemSlotContainer { impl ItemSlotContainer {
fn new(item_settings: ItemSettings, draw: &Draw, query_meshes: bool) -> Result<Self> { pub fn new() -> Self {
Ok(Self { Self {
helmet: None, helmet: None,
chest_plate: None, chest_plate: None,
belt: None, belt: None,
@ -177,44 +174,11 @@ impl ItemSlotContainer {
amulets: [None, None], amulets: [None, None],
slot_changed_callback: None, slot_changed_callback: None,
item_meshes: if query_meshes {
Arc::new(
Self::find_items(draw)
.map({
let item_settings = item_settings.clone();
move |item_meshes| {
Self::create_rarity_color_items(item_meshes, &item_settings)
}
})
.transpose()?
.unwrap_or_default(),
)
} else {
Default::default()
},
item_settings,
})
}
pub fn empty(item_settings: ItemSettings, draw: &Draw) -> Result<Self> {
Self::new(item_settings, draw, true)
}
pub fn load(
save_game: &SaveGame,
item_settings: ItemSettings,
draw: &Draw,
item_meshes: Arc<HashMap<ItemSlots, HashMap<Rarities, AssetMesh>>>,
item_system: &ItemSystem,
) -> Result<Self> {
let mut me = Self::new(item_settings, draw, false)?;
if me.item_meshes.is_empty() {
me.item_meshes = item_meshes;
} }
}
pub fn load(save_game: &SaveGame, item_system: &ItemSystem) -> Result<Self> {
let mut me = Self::new();
load_item!(me, chest_plate, ChestPlate, save_game, item_system); load_item!(me, chest_plate, ChestPlate, save_game, item_system);
load_item!(me, helmet, Helmet, save_game, item_system); load_item!(me, helmet, Helmet, save_game, item_system);
@ -273,7 +237,7 @@ impl ItemSlotContainer {
] ]
} }
fn create_rarity_color_items( fn _create_rarity_color_items(
item_meshes: HashMap<ItemSlots, AssetMesh>, item_meshes: HashMap<ItemSlots, AssetMesh>,
item_settings: &ItemSettings, item_settings: &ItemSettings,
) -> Result<HashMap<ItemSlots, HashMap<Rarities, AssetMesh>>> { ) -> Result<HashMap<ItemSlots, HashMap<Rarities, AssetMesh>>> {
@ -333,19 +297,38 @@ impl ItemSlotContainer {
Ok(slot_meshes) Ok(slot_meshes)
} }
pub fn item_meshes(&self) -> Arc<HashMap<ItemSlots, HashMap<Rarities, AssetMesh>>> { pub fn set_item_change_callback(
self.item_meshes.clone() &mut self,
} _draw: &mut Draw,
_location: &Location,
) -> Result<()> {
// TODO
pub fn set_item_change_callback(&mut self, draw: &mut Draw, location: &Location) -> Result<()> { // item_meshes: if query_meshes {
let item_rarity_meshes = self.item_meshes.clone(); // Arc::new(
// Self::find_items(draw)
// .map({
// let item_settings = item_settings.clone();
// only enable items that are equipped // move |item_meshes| {
self.slot_changed_callback = Some(Box::new(move |slot, rarity, is_some, multi_mut| { // Self::create_rarity_color_items(item_meshes, &item_settings)
Self::equipment_changed(multi_mut, &item_rarity_meshes, slot, rarity, is_some) // }
})); // })
// .transpose()?
// .unwrap_or_default(),
// )
// } else {
// Default::default()
// },
Self::check_items(draw, location, self, &self.item_meshes)?; // let item_rarity_meshes = self.item_meshes.clone();
// // only enable items that are equipped
// self.slot_changed_callback = Some(Box::new(move |slot, rarity, is_some, multi_mut| {
// Self::equipment_changed(multi_mut, &item_rarity_meshes, slot, rarity, is_some)
// }));
// Self::check_items(draw, location, self, &self.item_meshes)?;
Ok(()) Ok(())
} }
@ -637,7 +620,7 @@ impl ItemSlotContainer {
impl ItemSlotContainer { impl ItemSlotContainer {
#[inline] #[inline]
fn item( fn _item(
item_meshes: &mut HashMap<ItemSlots, AssetMesh>, item_meshes: &mut HashMap<ItemSlots, AssetMesh>,
mesh: &AssetMesh, mesh: &AssetMesh,
name: &str, name: &str,
@ -651,16 +634,16 @@ impl ItemSlotContainer {
} }
#[inline] #[inline]
fn find_items(draw: &Draw) -> Option<HashMap<ItemSlots, AssetMesh>> { fn _find_items(draw: &Draw) -> Option<HashMap<ItemSlots, AssetMesh>> {
let mut item_meshes = HashMap::new(); let mut item_meshes = HashMap::new();
for mesh in draw.iter() { for mesh in draw.iter() {
Self::item(&mut item_meshes, mesh, "Helmet", ItemSlots::Helmet); Self::_item(&mut item_meshes, mesh, "Helmet", ItemSlots::Helmet);
Self::item(&mut item_meshes, mesh, "Shield", ItemSlots::OffHand); Self::_item(&mut item_meshes, mesh, "Shield", ItemSlots::OffHand);
Self::item(&mut item_meshes, mesh, "Sword", ItemSlots::MainHand); Self::_item(&mut item_meshes, mesh, "Sword", ItemSlots::MainHand);
Self::item(&mut item_meshes, mesh, "ChestPlate", ItemSlots::ChestPlate); Self::_item(&mut item_meshes, mesh, "ChestPlate", ItemSlots::ChestPlate);
Self::item(&mut item_meshes, mesh, "Boots", ItemSlots::Boots); Self::_item(&mut item_meshes, mesh, "Boots", ItemSlots::Boots);
Self::item(&mut item_meshes, mesh, "Gloves", ItemSlots::Gloves); Self::_item(&mut item_meshes, mesh, "Gloves", ItemSlots::Gloves);
} }
if !item_meshes.is_empty() { if !item_meshes.is_empty() {
@ -671,12 +654,12 @@ impl ItemSlotContainer {
} }
#[inline] #[inline]
fn undress(draw: &mut Draw, name: &str) { fn _undress(draw: &mut Draw, name: &str) {
draw.remove_by_name(name); draw.remove_by_name(name);
} }
#[inline] #[inline]
fn dress( fn _dress(
draw: &mut Draw, draw: &mut Draw,
location: &Location, location: &Location,
item_meshes: &HashMap<ItemSlots, HashMap<Rarities, AssetMesh>>, item_meshes: &HashMap<ItemSlots, HashMap<Rarities, AssetMesh>>,
@ -705,7 +688,7 @@ impl ItemSlotContainer {
} }
#[inline] #[inline]
fn check_items( fn _check_items(
draw: &mut Draw, draw: &mut Draw,
location: &Location, location: &Location,
items: &ItemSlotContainer, items: &ItemSlotContainer,
@ -715,9 +698,9 @@ impl ItemSlotContainer {
($func:ident, $name:expr) => { ($func:ident, $name:expr) => {
match items.$func() { match items.$func() {
Some(item) => { Some(item) => {
Self::dress(draw, location, item_meshes, $name, item.slot, item.rarity)?; Self::_dress(draw, location, item_meshes, $name, item.slot, item.rarity)?;
} }
None => Self::undress(draw, $name), None => Self::_undress(draw, $name),
} }
}; };
} }
@ -732,7 +715,7 @@ impl ItemSlotContainer {
Ok(()) Ok(())
} }
fn equipment_changed( fn _equipment_changed(
multi_mut: &mut MultiMut<'_>, multi_mut: &mut MultiMut<'_>,
item_meshes: &HashMap<ItemSlots, HashMap<Rarities, AssetMesh>>, item_meshes: &HashMap<ItemSlots, HashMap<Rarities, AssetMesh>>,
slot: ItemSlots, slot: ItemSlots,
@ -756,9 +739,9 @@ impl ItemSlotContainer {
}; };
if is_some { if is_some {
Self::dress(draw, location, item_meshes, item_name, slot, rarity)?; Self::_dress(draw, location, item_meshes, item_name, slot, rarity)?;
} else { } else {
Self::undress(draw, item_name); Self::_undress(draw, item_name);
} }
Ok(()) Ok(())
@ -916,7 +899,10 @@ impl ItemSlotContainer {
} }
} }
pub fn collect_attribute_bonuses(&self) -> (Strength, Agility, Intelligence) { pub fn collect_attribute_bonuses(
&self,
item_settings: &ItemSettings,
) -> (Strength, Agility, Intelligence) {
let mut strength = Strength::default(); let mut strength = Strength::default();
let mut agility = Agility::default(); let mut agility = Agility::default();
let mut intelligence = Intelligence::default(); let mut intelligence = Intelligence::default();
@ -924,12 +910,11 @@ impl ItemSlotContainer {
for item in self.as_vec().iter().copied().flatten() { for item in self.as_vec().iter().copied().flatten() {
for affix in item.affixes.iter() { for affix in item.affixes.iter() {
if let ItemAffix::Socket(Some(jewel)) = affix { if let ItemAffix::Socket(Some(jewel)) = affix {
let value = self let value = item_settings
.item_settings
.jewel_rarity_multiplier .jewel_rarity_multiplier
.from_rarity(jewel.rarity) .from_rarity(jewel.rarity)
* jewel.level * jewel.level
* self.item_settings.general.jewel_level_multiplier; * item_settings.general.jewel_level_multiplier;
match jewel.attribute { match jewel.attribute {
Attribute::Agility => agility += Agility::from(value), Attribute::Agility => agility += Agility::from(value),

View file

@ -1,8 +1,9 @@
use engine::prelude::*; use engine::prelude::*;
use crate::{ use crate::{
config::attributes::{ config::{
AgilitySettings, AttributeSettings, IntelligenceSettings, StrengthSettings, attributes::{AgilitySettings, AttributeSettings, IntelligenceSettings, StrengthSettings},
items::ItemSettings,
}, },
damage_type::DamageType, damage_type::DamageType,
}; };
@ -133,13 +134,14 @@ impl Statistics {
&mut self, &mut self,
attributes: &mut Attributes, attributes: &mut Attributes,
attribute_settings: &AttributeSettings, attribute_settings: &AttributeSettings,
items: impl Into<Option<&'a ItemSlotContainer>>,
items: impl Into<Option<(&'a ItemSlotContainer, &'a ItemSettings)>>,
) { ) {
*self = Self::default(); *self = Self::default();
let items = items.into(); let items = items.into();
if let Some(items) = items { if let Some((items, item_settings)) = items {
let (agility, strength, intelligence) = items.collect_attribute_bonuses(); let (agility, strength, intelligence) = items.collect_attribute_bonuses(item_settings);
attributes.bonus_agility = strength; attributes.bonus_agility = strength;
attributes.bonus_strength = agility; attributes.bonus_strength = agility;
@ -162,7 +164,7 @@ impl Statistics {
); );
// apply items // apply items
if let Some(items) = items { if let Some((items, _)) = items {
let item_bonuses = items.collect_stat_bonuses(); let item_bonuses = items.collect_stat_bonuses();
for item_bonus in item_bonuses.into_iter() { for item_bonus in item_bonuses.into_iter() {

View file

@ -12,7 +12,7 @@ use crate::{
use std::{env::var, sync::Arc}; use std::{env::var, sync::Arc};
use super::{attributes::AttributeSettings, experience::ExperienceSettings}; use super::{attributes::AttributeSettings, experience::ExperienceSettings, items::ItemSettings};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub fn save_game_dir(game: &str) -> String { pub fn save_game_dir(game: &str) -> String {
@ -364,13 +364,14 @@ impl SaveGame {
let experience_settings = scene.resources.get::<ExperienceSettings>(); let experience_settings = scene.resources.get::<ExperienceSettings>();
let attribute_settings = scene.resources.get::<AttributeSettings>(); let attribute_settings = scene.resources.get::<AttributeSettings>();
let item_settings = scene.resources.get::<ItemSettings>();
let item_system = scene.resources.get::<Arc<ItemSystem>>(); let item_system = scene.resources.get::<Arc<ItemSystem>>();
let mut entity_object = engine.assets().empty_entity(); let mut entity_object = engine.assets().empty_entity();
entity_object.insert_component(Draw::new(Vec::new())); entity_object.insert_component(Draw::new(Vec::new()));
entity_object.insert_component(Audio::new(engine.context(), None)?); entity_object.insert_component(Audio::new(engine.context(), None)?);
Location::new_and_setup(&mut entity_object); Location::new_and_setup(&mut entity_object)?;
let level = Level::load(self.general.level, self.general.exp, experience_settings); let level = Level::load(self.general.level, self.general.exp, experience_settings);
let mut attributes = Attributes::load( let mut attributes = Attributes::load(
@ -381,9 +382,9 @@ impl SaveGame {
let inventory = Inventory::load(&self, &item_system)?; let inventory = Inventory::load(&self, &item_system)?;
let abilities = AbilitySlots::load(item_system.clone(), &self)?; let abilities = AbilitySlots::load(item_system.clone(), &self)?;
let crafting_materials = CraftingMaterials::load(&self); let crafting_materials = CraftingMaterials::load(&self);
let items = ItemSlotContainer::load()?; let items = ItemSlotContainer::load(&self, &item_system)?;
let mut statistics = Statistics::default(); let mut statistics = Statistics::default();
statistics.update(&mut attributes, attribute_settings, &items); statistics.update(&mut attributes, attribute_settings, (&items, item_settings));
let current_status = CharacterStatus::new_full(&statistics); let current_status = CharacterStatus::new_full(&statistics);
entity_object.insert_component(level); entity_object.insert_component(level);