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 level;
mod murals;
mod scarf;
mod symbol;
mod test;
@ -14,6 +15,7 @@ use std::path::{Path, PathBuf};
use binrw::{until_eof, BinRead, BinReaderExt, BinWriterExt};
use chrono::{DateTime, NaiveDateTime, Utc};
use level::Level;
use scarf::Scarf;
use symbol::Symbol;
use crate::companion::{CompanionSymbols, CompanionWithId, Companions};
@ -39,6 +41,15 @@ pub enum Error {
#[error("Level name was not found")]
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")]
SymbolIdOutOfRange,
@ -77,7 +88,7 @@ pub struct Savefile {
pub symbol: Symbol,
pub scarf_length: u32,
pub scarf_length: Scarf,
#[br(count = 4)]
_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.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.total_collected_symbols, 107);
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();
if let Some(val) = args.scarf_length {
savefile.scarf_length = val;
savefile.scarf_length.set_length(val)?;
}
if let Some(val) = &args.current_level {

View File

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