diff --git a/Cargo.lock b/Cargo.lock index 0aefefd..b64dce8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "arcdps-imgui" version = "0.8.0" @@ -122,12 +137,76 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e10e7569f6ca78ef7664d7d651115172d4875c4410c050306bccde856a99a49" +[[package]] +name = "chrono" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets 0.52.6", +] + [[package]] name = "collection_literals" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271" +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "derive-where" version = "1.2.7" @@ -215,6 +294,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -239,6 +324,12 @@ dependencies = [ "windows", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.15.2" @@ -251,6 +342,35 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icu_collections" version = "1.5.0" @@ -369,6 +489,12 @@ dependencies = [ "syn", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.0.3" @@ -390,6 +516,17 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.7.0" @@ -397,7 +534,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.2", + "serde", ] [[package]] @@ -536,6 +674,21 @@ dependencies = [ "syn", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "num_enum" version = "0.7.3" @@ -736,6 +889,12 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro-crate" version = "3.2.0" @@ -839,6 +998,7 @@ dependencies = [ "semver", "serde", "serde_json", + "serde_with", "strum", "thiserror", "url", @@ -991,6 +1151,36 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.7.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1009,6 +1199,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" version = "0.26.3" @@ -1073,6 +1269,37 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.7.6" @@ -1110,7 +1337,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -1257,7 +1484,16 @@ version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core", + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ "windows-targets 0.52.6", ] diff --git a/reffect/Cargo.toml b/reffect/Cargo.toml index 30a8f1d..ba68882 100644 --- a/reffect/Cargo.toml +++ b/reffect/Cargo.toml @@ -21,6 +21,7 @@ rfd = { version = "0.15.0", default-features = false } semver = { version = "1.0.17", features = ["serde"] } serde = { version = "1.0.163", features = ["derive"] } serde_json = "1.0.115" +serde_with = "3.12.0" strum = { version = "0.26.1", features = ["derive"] } thiserror = "2.0.5" url = "2.5.0" diff --git a/reffect/src/elements/list/icon.rs b/reffect/src/elements/list/icon.rs index cee2e7e..c815d3a 100644 --- a/reffect/src/elements/list/icon.rs +++ b/reffect/src/elements/list/icon.rs @@ -99,7 +99,7 @@ impl Default for ListIcon { Self { enabled: true, name: "Unnamed".into(), - trigger: ProgressTrigger::effect(), + trigger: ProgressTrigger::buff(), filter: FilterTrigger::default(), icon: Icon::default(), } diff --git a/reffect/src/lib.rs b/reffect/src/lib.rs index 10f624b..ca4c4dd 100644 --- a/reffect/src/lib.rs +++ b/reffect/src/lib.rs @@ -12,8 +12,7 @@ mod lockbox; mod render; mod render_util; mod schema; -mod serde_bitflags; -mod serde_migrate; +mod serde; mod settings; mod texture_manager; mod tree; diff --git a/reffect/src/serde_bitflags.rs b/reffect/src/serde/bitflags.rs similarity index 100% rename from reffect/src/serde_bitflags.rs rename to reffect/src/serde/bitflags.rs diff --git a/reffect/src/serde_migrate.rs b/reffect/src/serde/migrate.rs similarity index 100% rename from reffect/src/serde_migrate.rs rename to reffect/src/serde/migrate.rs diff --git a/reffect/src/serde/mod.rs b/reffect/src/serde/mod.rs new file mode 100644 index 0000000..fb1d8ea --- /dev/null +++ b/reffect/src/serde/mod.rs @@ -0,0 +1,5 @@ +pub mod bitflags; + +mod migrate; + +pub use self::migrate::*; diff --git a/reffect/src/trigger/filter.rs b/reffect/src/trigger/filter.rs index 3fdccd3..a48e39c 100644 --- a/reffect/src/trigger/filter.rs +++ b/reffect/src/trigger/filter.rs @@ -6,7 +6,7 @@ use crate::{ elements::RenderState, render::{RenderDebug, RenderOptions}, render_util::debug_optional, - serde_migrate::migrate, + serde::migrate, }; use nexus::imgui::Ui; use serde::{Deserialize, Serialize}; diff --git a/reffect/src/trigger/map/legacy.rs b/reffect/src/trigger/map/legacy.rs index 32dd39d..0b56aa9 100644 --- a/reffect/src/trigger/map/legacy.rs +++ b/reffect/src/trigger/map/legacy.rs @@ -31,28 +31,28 @@ impl From for MapTrigger { #[cfg(test)] mod tests { use super::*; - use crate::serde_migrate::Migrate; + use crate::serde::Migrate; use enumflags2::BitFlags; #[test] fn migrate() { let json = r#""Any""#; - let result = serde_json::from_str::>(&json); - assert!(result.is_ok()); - let map = result.unwrap().inner; + let result = serde_json::from_str::>(&json) + .expect("failed to deserialize"); + let map = result.inner; assert_eq!(map.category, BitFlags::empty()); assert_eq!(map.ids.len(), 0); let json = r#"{ "Category": "Pve" }"#; - let result = serde_json::from_str::>(&json); - assert!(result.is_ok()); - let map = result.unwrap().inner; + let result = serde_json::from_str::>(&json) + .expect("failed to deserialize"); + let map = result.inner; assert_eq!(map.category, BitFlags::from(MapCategory::PvE)); let json = r#"{ "Ids": [1, 2, 3] }"#; - let result = serde_json::from_str::>(&json); - assert!(result.is_ok()); - let map = result.unwrap().inner; + let result = serde_json::from_str::>(&json) + .expect("failed to deserialize"); + let map = result.inner; assert_eq!(&map.ids, &[1, 2, 3]); } } diff --git a/reffect/src/trigger/map/mod.rs b/reffect/src/trigger/map/mod.rs index d83b396..40a92f3 100644 --- a/reffect/src/trigger/map/mod.rs +++ b/reffect/src/trigger/map/mod.rs @@ -6,7 +6,7 @@ use crate::{ context::{Context, ContextUpdate, MapCategory}, render::RenderOptions, render_util::{enum_combo_bitflags, helper, input_u32, item_context_menu, map_select}, - serde_bitflags, + serde::bitflags, }; use enumflags2::BitFlags; use nexus::imgui::{ComboBoxFlags, Ui}; @@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct MapTrigger { - #[serde(with = "serde_bitflags")] + #[serde(with = "bitflags")] pub category: BitFlags, #[serde(default = "default_true")] diff --git a/reffect/src/trigger/player/mod.rs b/reffect/src/trigger/player/mod.rs index 225aa86..0c49bc4 100644 --- a/reffect/src/trigger/player/mod.rs +++ b/reffect/src/trigger/player/mod.rs @@ -9,7 +9,7 @@ use crate::{ internal::Weapon, render::RenderOptions, render_util::enum_combo_bitflags, - serde_bitflags, + serde::bitflags, }; use enumflags2::BitFlags; use nexus::imgui::{ComboBoxFlags, Ui}; @@ -21,19 +21,19 @@ pub struct PlayerTrigger { pub combat: CombatTrigger, #[serde(skip_serializing)] - #[serde(with = "serde_bitflags")] + #[serde(with = "bitflags")] profs: BitFlags, // TODO: remove after grace period - #[serde(with = "serde_bitflags")] + #[serde(with = "bitflags")] pub specs: BitFlags, - #[serde(with = "serde_bitflags")] + #[serde(with = "bitflags")] pub weapons: BitFlags, #[serde(flatten)] pub traits: TraitTrigger, - #[serde(with = "serde_bitflags")] + #[serde(with = "bitflags")] pub mounts: BitFlags, } diff --git a/reffect/src/trigger/progress/mod.rs b/reffect/src/trigger/progress/mod.rs index f5ccb88..93eb20e 100644 --- a/reffect/src/trigger/progress/mod.rs +++ b/reffect/src/trigger/progress/mod.rs @@ -8,7 +8,7 @@ use crate::{ context::{Context, ContextUpdate}, render::{RenderDebug, RenderOptions}, render_util::debug_optional, - serde_migrate::migrate, + serde::migrate, }; use nexus::imgui::Ui; use serde::{Deserialize, Serialize}; @@ -31,9 +31,9 @@ pub struct ProgressTrigger { } impl ProgressTrigger { - pub fn effect() -> Self { + pub fn buff() -> Self { Self { - source: ProgressSource::Buff(0), + source: ProgressSource::Buff(vec![0]), threshold: ProgressThreshold { threshold_type: ThresholdType::Present, amount_type: AmountType::default(), diff --git a/reffect/src/trigger/progress/source.rs b/reffect/src/trigger/progress/source.rs index 68d6275..f4804a1 100644 --- a/reffect/src/trigger/progress/source.rs +++ b/reffect/src/trigger/progress/source.rs @@ -8,9 +8,13 @@ use crate::{ }; use nexus::imgui::{ComboBoxFlags, InputTextFlags, Ui}; use serde::{Deserialize, Serialize}; +use serde_with::{formats::PreferMany, serde_as, OneOrMany}; use strum::{AsRefStr, EnumIter, IntoStaticStr}; -#[derive(Debug, Default, Clone, AsRefStr, IntoStaticStr, EnumIter, Serialize, Deserialize)] +#[serde_as] +#[derive( + Debug, Default, Clone, PartialEq, AsRefStr, IntoStaticStr, EnumIter, Serialize, Deserialize, +)] pub enum ProgressSource { /// Inherit from above. #[default] @@ -20,20 +24,20 @@ pub enum ProgressSource { #[serde(alias = "None")] Always, - /// Single buff id. + /// Buff ids, multiple matches are merged. #[serde(alias = "Single")] #[serde(alias = "Has")] - #[strum(serialize = "Single Effect")] - Buff(u32), - - /// Any of the buff ids, stacks are summed. #[serde(alias = "Any")] - #[strum(serialize = "Multiple Effects")] - AnyBuff(Vec), + #[serde(alias = "AnyBuff")] + #[serde(alias = "Effect")] + #[strum(serialize = "Effect")] + Buff(#[serde_as(as = "OneOrMany<_, PreferMany>")] Vec), + /// Ability ids, first match is used. #[strum(serialize = "Ability Recharge")] - Ability(u32), + Ability(Vec), + /// Skillbar slot. #[strum(serialize = "Slot Recharge")] SkillbarSlot(Slot), @@ -70,14 +74,7 @@ impl ProgressSource { match *self { Self::Inherit => parent.cloned(), Self::Always => Some(ProgressActive::dummy()), - Self::Buff(id) => ctx.own_buffs().map(|buffs| { - buffs - .get(&id) - .filter(|buff| buff.runout_time > ctx.now) - .map(|buff| ProgressActive::from_buff(id, buff)) - .unwrap_or_else(|| ProgressActive::empy_buff(id)) - }), - Self::AnyBuff(ref ids) => ctx.own_buffs().map(|buffs| { + Self::Buff(ref ids) => ctx.own_buffs().map(|buffs| { let mut combined = Buff::empty(); for id in ids { if let Some(buff) = buffs.get(id).filter(|buff| buff.runout_time > ctx.now) { @@ -94,14 +91,13 @@ impl ProgressSource { let skill = Skill::from_slot(skillbar, slot); Some(ProgressActive::from_ability(skill, ability)) } - Self::Ability(id) => { - if id > 0 { - let skillbar = ctx.own_skillbar()?; - let ability = skillbar.ability(id)?; - Some(ProgressActive::from_ability(ability.id.into(), ability)) - } else { - None - } + Self::Ability(ref ids) => { + let skillbar = ctx.own_skillbar()?; + ids.iter() + .copied() + .filter(|id| *id > 0) + .find_map(|id| skillbar.ability(id)) + .map(|ability| ProgressActive::from_ability(ability.id.into(), ability)) } Self::Health => ctx.own_resources()?.health.clone().try_into().ok(), Self::Barrier => ctx.own_resources()?.barrier.clone().try_into().ok(), @@ -119,8 +115,14 @@ impl ProgressSource { match *self { Self::Inherit => parent.cloned().unwrap_or(ProgressActive::dummy()), Self::Always => ProgressActive::dummy(), - Self::Buff(id) => ProgressActive::edit_buff(id, progress, ctx.now), - Self::Ability(id) => ProgressActive::edit_ability(id.into(), progress, ctx.now), + Self::Buff(ref ids) => { + let id = ids.first().copied().unwrap_or(0); + ProgressActive::edit_buff(id, progress, ctx.now) + } + Self::Ability(ref ids) => { + let id = ids.first().copied().unwrap_or(0); + ProgressActive::edit_ability(id.into(), progress, ctx.now) + } Self::SkillbarSlot(slot) => { let skill = ctx .own_skillbar() @@ -128,10 +130,6 @@ impl ProgressSource { .unwrap_or_default(); ProgressActive::edit_ability(skill, progress, ctx.now) } - Self::AnyBuff(ref ids) => { - let id = ids.first().copied().unwrap_or(0); - ProgressActive::edit_buff(id, progress, ctx.now) - } Self::Health => ProgressActive::edit_resource(progress, 15_000), Self::Barrier => ProgressActive::edit_resource(0.5 * progress, 15_000), Self::Endurance => ProgressActive::edit_resource(progress, 100), @@ -143,8 +141,8 @@ impl ProgressSource { pub fn into_ids(self) -> Vec { match self { - Self::Buff(id) => vec![id], - Self::AnyBuff(ids) => ids, + Self::Buff(ids) => ids, + Self::Ability(ids) => ids, _ => Vec::new(), } } @@ -188,25 +186,20 @@ impl RenderOptions for ProgressSource { fn render_options(&mut self, ui: &Ui, _ctx: &Context) { if let Some(prev) = enum_combo(ui, "Trigger", self, ComboBoxFlags::HEIGHT_LARGE) { match self { - Self::Buff(id) => { - if let Some(first) = prev.into_ids().first() { - *id = *first; - } - } - Self::AnyBuff(ids) => *ids = prev.into_ids(), + Self::Buff(ids) => *ids = prev.into_ids(), + Self::Ability(ids) => *ids = prev.into_ids(), _ => {} } } - helper(ui, || ui.text("Source of information")); // TODO: mention inherit being passed down, not affecting group visibility + helper(ui, || { + ui.text("Source of information"); + ui.text("Effect merges all matches"); + ui.text("Ability uses first match"); + ui.text("For group no effect on visibility, only passed down for inherit"); + }); match self { - Self::Buff(id) => { - Self::buff_validate(*id).for_item(ui, || { - input_skill_id(ui, "Effect Id", id, InputTextFlags::empty()); - }); - Self::id_helper(ui); - } - Self::AnyBuff(ids) => { + Self::Buff(ids) => { let mut action = Action::new(); for (i, id) in ids.iter_mut().enumerate() { let _id = ui.push_id(i as i32); @@ -227,11 +220,26 @@ impl RenderOptions for ProgressSource { action.perform(ids); } - Self::Ability(id) => { - Self::ability_validate(*id).for_item(ui, || { - input_skill_id(ui, "Ability Id", id, InputTextFlags::empty()) - }); - Self::id_helper(ui); + Self::Ability(ids) => { + let mut action = Action::new(); + for (i, id) in ids.iter_mut().enumerate() { + let _id = ui.push_id(i as i32); + + action.input_with_buttons(ui, i, || { + Self::ability_validate(*id).for_item(ui, || { + input_skill_id(ui, "##id", id, InputTextFlags::empty()); + }); + }); + + ui.same_line(); + ui.text(format!("Ability Id {}", i + 1)); + Self::id_helper(ui); + } + if ui.button("Add Ability") { + ids.push(0); + } + + action.perform(ids); } Self::SkillbarSlot(slot) => { enum_combo(ui, "Slot", slot, ComboBoxFlags::HEIGHT_LARGEST); @@ -240,3 +248,15 @@ impl RenderOptions for ProgressSource { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn migrate() { + let json = r#"{ "Buff": 123 }"#; + let result = serde_json::from_str::(&json).expect("failed to deserialize"); + assert_eq!(result, ProgressSource::Buff(vec![123])); + } +} diff --git a/reffect/src/trigger/progress/threshold/mod.rs b/reffect/src/trigger/progress/threshold/mod.rs index 075f4ff..46b3886 100644 --- a/reffect/src/trigger/progress/threshold/mod.rs +++ b/reffect/src/trigger/progress/threshold/mod.rs @@ -87,14 +87,14 @@ impl RenderOptions for ProgressThreshold { #[cfg(test)] mod tests { use super::*; - use crate::serde_migrate::Migrate; + use crate::serde::Migrate; #[test] fn migrate() { let json = r#"{ "Between": [1, 23] }"#; - let result = serde_json::from_str::>(&json); - assert!(result.is_ok()); - let threshold = result.unwrap().inner; + let result = serde_json::from_str::>(&json) + .expect("failed to deserialize"); + let threshold = result.inner; assert_eq!(threshold.threshold_type, ThresholdType::Between(1.0, 23.0)); } }