diff --git a/examples/bitmask-slice.toml b/examples/bitmask-slice.toml index b642f25..a3c663a 100644 --- a/examples/bitmask-slice.toml +++ b/examples/bitmask-slice.toml @@ -111,6 +111,10 @@ y = 16 # If you do not provide a delay for each frame (ie, two delays for 4 frames,) the delay values # will cycle until the list is full. ie, 10,20 for 5 frames becomes 10,20,10,20,10 and so on. delays = [10, 20] +# Rewind is a boolean that maps directly to byond, if it's true animations will play, +# then animate "backwards" to the start. +# Defaults to false +rewind = false # Settings for generating a unique map icon for each icon_state # This entire section is optional diff --git a/hypnagogic_core/src/config/blocks/cutters.rs b/hypnagogic_core/src/config/blocks/cutters.rs index f2736b0..9f0a812 100644 --- a/hypnagogic_core/src/config/blocks/cutters.rs +++ b/hypnagogic_core/src/config/blocks/cutters.rs @@ -231,6 +231,7 @@ impl<'de> Deserialize<'de> for PrefabOverlays { #[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] pub struct Animation { pub delays: Vec, + pub rewind: Option, } #[derive(Clone, Eq, PartialEq, Debug)] diff --git a/hypnagogic_core/src/lib.rs b/hypnagogic_core/src/lib.rs index 909a144..03da893 100644 --- a/hypnagogic_core/src/lib.rs +++ b/hypnagogic_core/src/lib.rs @@ -16,6 +16,10 @@ #![allow(clippy::cast_sign_loss)] // error we can't do anything about because of dependancies #![allow(clippy::multiple_crate_versions)] +// map makes less sense in some contexts +#![allow(clippy::bind_instead_of_map)] +// throws in cases where `` obfuscates what's going on (code links) +#![allow(clippy::doc_markdown)] pub mod config; pub mod generation; diff --git a/hypnagogic_core/src/operations/cutters/bitmask_dir_visibility.rs b/hypnagogic_core/src/operations/cutters/bitmask_dir_visibility.rs index 1119f61..4a2ce43 100644 --- a/hypnagogic_core/src/operations/cutters/bitmask_dir_visibility.rs +++ b/hypnagogic_core/src/operations/cutters/bitmask_dir_visibility.rs @@ -61,11 +61,17 @@ impl IconOperationConfig for BitmaskDirectionalVis { possible_states, ); - let delay = self + let delay: Option> = self .bitmask_slice_config .animation .clone() .map(|x| repeat_for(&x.delays, num_frames as usize)); + let rewind = self + .bitmask_slice_config + .animation + .as_ref() + .and_then(|animation| animation.rewind) + .unwrap_or(false); let mut icon_states = vec![]; @@ -111,6 +117,7 @@ impl IconOperationConfig for BitmaskDirectionalVis { frames: num_frames, images: icon_state_frames, delay: delay.clone(), + rewind, ..Default::default() })); } @@ -153,6 +160,7 @@ impl IconOperationConfig for BitmaskDirectionalVis { frames: num_frames, images: icon_state_frames, delay: delay.clone(), + rewind, ..Default::default() })); diff --git a/hypnagogic_core/src/operations/cutters/bitmask_slice.rs b/hypnagogic_core/src/operations/cutters/bitmask_slice.rs index aea4fdb..8f53a6c 100644 --- a/hypnagogic_core/src/operations/cutters/bitmask_slice.rs +++ b/hypnagogic_core/src/operations/cutters/bitmask_slice.rs @@ -113,6 +113,11 @@ impl IconOperationConfig for BitmaskSlice { .animation .clone() .map(|x| repeat_for(&x.delays, num_frames as usize)); + let rewind = self + .animation + .as_ref() + .and_then(|animation| animation.rewind) + .unwrap_or(false); let states_to_gen = (0..possible_states) .map(|x| Adjacency::from_bits(x as u8).unwrap()) @@ -138,6 +143,7 @@ impl IconOperationConfig for BitmaskSlice { frames: num_frames, images: icon_state_frames, delay: delay.clone(), + rewind, ..Default::default() })); } diff --git a/hypnagogic_core/src/operations/cutters/bitmask_windows.rs b/hypnagogic_core/src/operations/cutters/bitmask_windows.rs index ab2115d..ecc6152 100644 --- a/hypnagogic_core/src/operations/cutters/bitmask_windows.rs +++ b/hypnagogic_core/src/operations/cutters/bitmask_windows.rs @@ -92,6 +92,11 @@ impl IconOperationConfig for BitmaskWindows { .animation .clone() .map(|x| repeat_for(&x.delays, num_frames as usize)); + let rewind = self + .animation + .as_ref() + .and_then(|animation| animation.rewind) + .unwrap_or(false); let mut states = vec![]; @@ -132,6 +137,7 @@ impl IconOperationConfig for BitmaskWindows { frames: num_frames, images: upper_frames, delay: delay.clone(), + rewind, ..Default::default() })); states.push(dedupe_frames(IconState { @@ -140,6 +146,7 @@ impl IconOperationConfig for BitmaskWindows { frames: num_frames, images: lower_frames, delay: delay.clone(), + rewind, ..Default::default() })); }; diff --git a/hypnagogic_core/src/operations/format_converter/bitmask_to_precut.rs b/hypnagogic_core/src/operations/format_converter/bitmask_to_precut.rs index 7f72595..d5b42ea 100644 --- a/hypnagogic_core/src/operations/format_converter/bitmask_to_precut.rs +++ b/hypnagogic_core/src/operations/format_converter/bitmask_to_precut.rs @@ -79,7 +79,7 @@ impl IconOperationConfig for BitmaskSliceReconstruct { .clone() .into_iter() .filter_map(|(mut state, suffix)| { - state.name = suffix.clone(); + state.name.clone_from(&suffix); if bespoke.get(suffix.as_str()).is_some() { bespoke_found.push(suffix); Some(state) @@ -161,6 +161,10 @@ impl IconOperationConfig for BitmaskSliceReconstruct { let delays: Option> = trimmed_frames .first() .and_then(|first_frame| first_frame.delay.clone()); + let rewind = trimmed_frames + .first() + .and_then(|first_frame| Some(first_frame.rewind)) + .unwrap_or(false); let mut problem_states: Vec = vec![]; for (x, state) in trimmed_frames.into_iter().enumerate() { @@ -211,6 +215,9 @@ impl IconOperationConfig for BitmaskSliceReconstruct { if let Some(actual_delay) = delays { config.push("[animation]".to_string()); config.push(format!("delays = {}", text_delays(&actual_delay, ""))); + if rewind { + config.push(format!("rewind = {rewind}")); + } config.push(String::new()); }; config.push("[icon_size]".to_string());