flatland_client_ui/
rotation_editor.rs1use flatland_protocol::RotationPreset;
4
5pub const EDITOR_ABILITIES: &[&str] = &[
7 "unarmed",
8 "short_sword_slash",
9 "iron_sword_slash",
10 "bow_shot",
11 "arrow_shot",
12 "fireball",
13 "cone_frost",
14 "frost_nova",
15 "poison_dart",
16 "heal_touch",
17];
18
19const BUILTIN_PRESET_IDS: &[&str] = &["melee", "ranged", "spells"];
20
21pub fn preset_deletable(id: &str) -> bool {
22 !BUILTIN_PRESET_IDS.contains(&id)
23}
24
25pub fn next_custom_preset(presets: &[RotationPreset]) -> RotationPreset {
26 let mut n = 1u32;
27 loop {
28 let id = format!("custom_{n}");
29 if !presets.iter().any(|p| p.id == id) {
30 return RotationPreset {
31 id,
32 label: format!("Custom {n}"),
33 abilities: Vec::new(),
34 };
35 }
36 n += 1;
37 }
38}
39
40pub fn editor_ability_choices(known: &[String], weapon_ability_id: &str) -> Vec<String> {
42 let mut out = known.to_vec();
43 let weapon = weapon_ability_id.trim();
44 if !weapon.is_empty() && !out.iter().any(|a| a == weapon) {
45 out.push(weapon.to_string());
46 }
47 if out.is_empty() {
48 EDITOR_ABILITIES.iter().map(|s| (*s).to_string()).collect()
49 } else {
50 out
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn editor_ability_choices_prefers_known_and_weapon() {
60 let choices = editor_ability_choices(&["unarmed".into()], "bow_shot");
61 assert_eq!(choices, vec!["unarmed".to_string(), "bow_shot".to_string()]);
62 }
63
64 #[test]
65 fn editor_ability_choices_falls_back_when_empty() {
66 let choices = editor_ability_choices(&[], "");
67 assert_eq!(choices.len(), EDITOR_ABILITIES.len());
68 assert_eq!(choices[0], "unarmed");
69 }
70}