use bilge::prelude::*;
use binrw::binrw;
use galaxy_save_core::{
bin::{BinaryDataContentHeaderSerializer, Chunk, HeaderSerializer},
hash::{HashCode, HashCode16},
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[binrw]
#[br(import(_data_size: usize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug)]
pub struct SaveDataStorageGalaxy {
#[br(temp)]
#[bw(calc = galaxy.len() as u16)]
galaxy_num: u16,
#[br(temp)]
#[bw(calc = SaveDataStorageGalaxyStage::header_serializer())]
_stage_serializer: BinaryDataContentHeaderSerializer<SaveDataStorageGalaxyStage>,
#[br(temp)]
#[bw(calc = SaveDataStorageGalaxyScenario::header_serializer())]
_scenario_serializer: BinaryDataContentHeaderSerializer<SaveDataStorageGalaxyScenario>,
#[br(count = galaxy_num as usize)]
galaxy: Vec<SaveDataStorageGalaxyStage>,
}
impl SaveDataStorageGalaxy {
pub fn get(&self, galaxy_name: impl Into<HashCode>) -> Option<&SaveDataStorageGalaxyStage> {
let galaxy_name = HashCode16::from(galaxy_name.into());
self.galaxy.iter().find(|v| v.galaxy_name == galaxy_name)
}
pub fn get_mut(
&mut self,
galaxy_name: impl Into<HashCode>,
) -> Option<&mut SaveDataStorageGalaxyStage> {
let galaxy_name = HashCode16::from(galaxy_name.into());
self.galaxy
.iter_mut()
.find(|v| v.galaxy_name == galaxy_name)
}
}
impl Chunk for SaveDataStorageGalaxy {
fn hash_code() -> HashCode {
let hash = SaveDataStorageGalaxyScenario::data_size() as u32
+ SaveDataStorageGalaxyStage::header_size() as u32
+ 2;
HashCode::from_raw(hash)
}
}
#[binrw]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, HeaderSerializer)]
pub struct SaveDataStorageGalaxyStage {
#[header_serializer(name = "mGalaxyName")]
galaxy_name: HashCode16,
#[header_serializer(name = "mDataSize")]
data_size: u16,
#[header_serializer(name = "mScenarioNum")]
scenario_num: u8,
#[header_serializer(name = "mGalaxyState")]
pub galaxy_state: SaveDataStorageGalaxyState,
#[header_serializer(name = "mFlag")]
pub flag: SaveDataStorageGalaxyFlag,
#[br(count = scenario_num as usize)]
#[header_serializer(skip)]
pub scenario: Vec<SaveDataStorageGalaxyScenario>,
}
#[binrw]
#[brw(repr(u8))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Default)]
pub enum SaveDataStorageGalaxyState {
#[default]
Closed = 0,
New = 1,
Opened = 2,
}
#[bitsize(8)]
#[binrw]
#[cfg_attr(feature = "serde", derive(SerializeBits, DeserializeBits))]
#[derive(DebugBits, Clone, Copy, DefaultBits, FromBits)]
#[repr(transparent)]
pub struct SaveDataStorageGalaxyFlag {
pub tico_coin: bool,
pub comet: bool,
reserved: u6,
}
#[binrw]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Default, HeaderSerializer)]
pub struct SaveDataStorageGalaxyScenario {
#[header_serializer(name = "mMissNum")]
pub miss_num: u8,
#[header_serializer(name = "mBestTime")]
pub best_time: u32,
#[header_serializer(name = "mFlag")]
pub flag: SaveDataStorageGalaxyScenarioFlag,
}
#[bitsize(8)]
#[binrw]
#[cfg_attr(feature = "serde", derive(SerializeBits, DeserializeBits))]
#[derive(DebugBits, Clone, Copy, DefaultBits, FromBits)]
#[repr(transparent)]
pub struct SaveDataStorageGalaxyScenarioFlag {
pub power_star: bool,
pub bronze_star: bool,
pub already_visited: bool,
pub ghost_luigi: bool,
pub intrusively_luigi: bool,
reserved: u3,
}