Implement scarf length wrapper type

This commit is contained in:
Patrick Auernig 2023-08-16 15:39:43 +02:00
parent 0c42c3c932
commit b482cafbc2
5 changed files with 75 additions and 21 deletions

View File

@ -2,6 +2,7 @@ mod companion;
mod glyphs; mod glyphs;
mod level; mod level;
mod murals; mod murals;
mod scarf;
mod symbol; mod symbol;
mod test; mod test;
@ -14,6 +15,7 @@ use std::path::{Path, PathBuf};
use binrw::{until_eof, BinRead, BinReaderExt, BinWriterExt}; use binrw::{until_eof, BinRead, BinReaderExt, BinWriterExt};
use chrono::{DateTime, NaiveDateTime, Utc}; use chrono::{DateTime, NaiveDateTime, Utc};
use level::Level; use level::Level;
use scarf::Scarf;
use symbol::Symbol; use symbol::Symbol;
use crate::companion::{CompanionSymbols, CompanionWithId, Companions}; use crate::companion::{CompanionSymbols, CompanionWithId, Companions};
@ -39,6 +41,15 @@ pub enum Error {
#[error("Level name was not found")] #[error("Level name was not found")]
LevelNameNotFound, LevelNameNotFound,
#[error("Scarf already at maximum length")]
ScarfMaxLength,
#[error("Scarf already at minimum length")]
ScarfMinLength,
#[error("Scarf can be at most 30 long")]
ScarfTooLong,
#[error("Symbol id is out of range")] #[error("Symbol id is out of range")]
SymbolIdOutOfRange, SymbolIdOutOfRange,
@ -77,7 +88,7 @@ pub struct Savefile {
pub symbol: Symbol, pub symbol: Symbol,
pub scarf_length: u32, pub scarf_length: Scarf,
#[br(count = 4)] #[br(count = 4)]
_unknown1: Vec<u8>, _unknown1: Vec<u8>,

58
crates/save/src/scarf.rs Normal file
View File

@ -0,0 +1,58 @@
use core::fmt;
use binrw::{BinRead, BinWrite};
use crate::{Error, Result};
const MAX_LENGTH: u32 = 30;
#[derive(Debug, Clone, BinRead, BinWrite)]
pub struct Scarf {
#[br(assert(length <= MAX_LENGTH))]
length: u32,
}
impl Scarf {
pub fn set_length(&mut self, length: u32) -> Result<()> {
if length > MAX_LENGTH {
return Err(Error::ScarfTooLong);
}
self.length = length;
Ok(())
}
pub fn increase_length(&mut self) -> Result<()> {
let length = self.length + 1;
if length > MAX_LENGTH {
return Err(Error::ScarfMaxLength);
}
self.length = length;
Ok(())
}
pub fn decrease_length(&mut self) -> Result<()> {
let length = self.length.checked_sub(1).ok_or(Error::ScarfMinLength)?;
self.length = length;
Ok(())
}
}
impl fmt::Display for Scarf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.length)
}
}
impl AsRef<u32> for Scarf {
fn as_ref(&self) -> &u32 {
&self.length
}
}

View File

@ -17,7 +17,7 @@ fn general_info() {
assert_eq!(savefile.robe_tier(), 4); assert_eq!(savefile.robe_tier(), 4);
assert_eq!(savefile.symbol.as_ref(), &7); assert_eq!(savefile.symbol.as_ref(), &7);
assert_eq!(savefile.scarf_length, 27); assert_eq!(savefile.scarf_length.as_ref(), &27);
assert_eq!(savefile.current_level.as_ref(), &1); assert_eq!(savefile.current_level.as_ref(), &1);
assert_eq!(savefile.total_collected_symbols, 107); assert_eq!(savefile.total_collected_symbols, 107);
assert_eq!(savefile.collected_symbols, 21); assert_eq!(savefile.collected_symbols, 21);

View File

@ -55,7 +55,7 @@ fn edit_file(cur_savefile: &Savefile, args: &Args) -> Result<Savefile> {
let mut savefile = cur_savefile.clone(); let mut savefile = cur_savefile.clone();
if let Some(val) = args.scarf_length { if let Some(val) = args.scarf_length {
savefile.scarf_length = val; savefile.scarf_length.set_length(val)?;
} }
if let Some(val) = &args.current_level { if let Some(val) = &args.current_level {

View File

@ -173,14 +173,7 @@ impl State {
2 => savefile.total_collected_symbols = value.parse()?, 2 => savefile.total_collected_symbols = value.parse()?,
3 => savefile.current_level.set_by_name(value)?, 3 => savefile.current_level.set_by_name(value)?,
4 => savefile.companions_met = value.parse()?, 4 => savefile.companions_met = value.parse()?,
5 => { 5 => savefile.scarf_length.set_length(value.parse()?)?,
let new_length = value.parse()?;
if new_length > 30 {
bail!("Max length exceeded");
}
savefile.scarf_length = new_length;
}
6 => savefile.symbol.set_by_id(value.parse()?)?, 6 => savefile.symbol.set_by_id(value.parse()?)?,
7 => { 7 => {
let new_color = match value { let new_color = match value {
@ -218,11 +211,7 @@ impl State {
2 => savefile.total_collected_symbols += 1, 2 => savefile.total_collected_symbols += 1,
3 => savefile.current_level = savefile.current_level.wrapping_next(), 3 => savefile.current_level = savefile.current_level.wrapping_next(),
4 => savefile.companions_met += 1, 4 => savefile.companions_met += 1,
5 => { 5 => savefile.scarf_length.increase_length()?,
if savefile.scarf_length < 30 {
savefile.scarf_length += 1;
}
}
6 => savefile.symbol = savefile.symbol.wrapping_next(), 6 => savefile.symbol = savefile.symbol.wrapping_next(),
7 => { 7 => {
savefile.set_robe_color(match savefile.robe_color() { savefile.set_robe_color(match savefile.robe_color() {
@ -264,11 +253,7 @@ impl State {
} }
3 => savefile.current_level = savefile.current_level.wrapping_previous(), 3 => savefile.current_level = savefile.current_level.wrapping_previous(),
4 => savefile.companions_met = savefile.companions_met.saturating_sub(1), 4 => savefile.companions_met = savefile.companions_met.saturating_sub(1),
5 => { 5 => savefile.scarf_length.decrease_length()?,
if savefile.scarf_length > 0 {
savefile.scarf_length = savefile.scarf_length.saturating_sub(1);
}
}
6 => savefile.symbol = savefile.symbol.wrapping_previous(), 6 => savefile.symbol = savefile.symbol.wrapping_previous(),
7 => { 7 => {
savefile.set_robe_color(match savefile.robe_color() { savefile.set_robe_color(match savefile.robe_color() {