flatland-client-ui 0.2.36

Engine-agnostic play client UI state (world grid, input, presentation)
Documentation
//! Rotation preset editor helpers shared by gfx (and archived TUI).

use flatland_protocol::RotationPreset;

/// Fallback open-kit abilities when the character has no known abilities yet.
pub const EDITOR_ABILITIES: &[&str] = &[
    "unarmed",
    "short_sword_slash",
    "iron_sword_slash",
    "bow_shot",
    "arrow_shot",
    "fireball",
    "cone_frost",
    "frost_nova",
    "poison_dart",
    "heal_touch",
];

const BUILTIN_PRESET_IDS: &[&str] = &["melee", "ranged", "spells"];

pub fn preset_deletable(id: &str) -> bool {
    !BUILTIN_PRESET_IDS.contains(&id)
}

pub fn next_custom_preset(presets: &[RotationPreset]) -> RotationPreset {
    let mut n = 1u32;
    loop {
        let id = format!("custom_{n}");
        if !presets.iter().any(|p| p.id == id) {
            return RotationPreset {
                id,
                label: format!("Custom {n}"),
                abilities: Vec::new(),
            };
        }
        n += 1;
    }
}

/// Abilities shown in the rotation-editor picker: known (+ weapon), else fallback kit.
pub fn editor_ability_choices(known: &[String], weapon_ability_id: &str) -> Vec<String> {
    let mut out = known.to_vec();
    let weapon = weapon_ability_id.trim();
    if !weapon.is_empty() && !out.iter().any(|a| a == weapon) {
        out.push(weapon.to_string());
    }
    if out.is_empty() {
        EDITOR_ABILITIES.iter().map(|s| (*s).to_string()).collect()
    } else {
        out
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn editor_ability_choices_prefers_known_and_weapon() {
        let choices = editor_ability_choices(&["unarmed".into()], "bow_shot");
        assert_eq!(choices, vec!["unarmed".to_string(), "bow_shot".to_string()]);
    }

    #[test]
    fn editor_ability_choices_falls_back_when_empty() {
        let choices = editor_ability_choices(&[], "");
        assert_eq!(choices.len(), EDITOR_ABILITIES.len());
        assert_eq!(choices[0], "unarmed");
    }
}