///- --package .

vocations (test)

test vocations: prelude
///- --test static --symbol

:< testing
:! knight = ()
:! paladin = ()
:! sorcerer = ()
:! druid = ()

:| healer v =
    | PaladinHeals :: healer paladin
    | SorcererHeals :: healer sorcerer
    | DruidHeals :: healer druid

:| spell v =
    | WoundCleansing :: spell knight
    | Berserk :: spell knight
    | DivineHealing :: spell paladin
    | LightHealing :: \* v. healer v -> spell v
    | IntenseHealing :: \* v. healer v -> spell v

:== spell_data =
    {
        words : string
        level : i32
        mana : i32
        cooldown_ms : i32
        group_cooldown_ms : i32
        group : cooldowns::spell_group
    }

:= healing (words : string) (level : i32) (mana : i32) : spell_data =
    :< cooldowns
    { words = words; level = level; mana = mana; cooldown_ms = 1000; group_cooldown_ms = 1000; group = HealingGroup }

:= berserk () : spell_data =
    :< cooldowns
    { words = "exori"; level = 35; mana = 115; cooldown_ms = 4000; group_cooldown_ms = 2000; group = AttackGroup }

:= data_of \* v. (s : spell v) =
    ?= s ?|
    | WoundCleansing => healing "exura ico" 8 40
    | Berserk => berserk ()
    | DivineHealing => healing "exura san" 35 160
    | LightHealing _ => healing "exura" 8 20
    | IntenseHealing _ => healing "exura gran" 20 70

:= cooldown_id_of \* v. (s : spell v) : cooldowns::spell_id =
    :< cooldowns
    ?= s ?|
    | WoundCleansing => WoundCleansingSpell
    | Berserk => StrikeSpell
    | _ => LightHealingSpell

:= as_cooldown \* v. (s : spell v) : cooldowns::spell =
    := d = data_of s
    { id = cooldown_id_of s; group = d::group; own_ms = d::cooldown_ms; group_ms = d::group_cooldown_ms }

:= castable \* v. (level : i32) (mana : i32) (s : spell v) : bool =
    := d = data_of s
    level >= d::level && mana >= d::mana

:= knight_heal () : spell knight = WoundCleansing

spell_levels_and_mana_gate_casting_like_canary (test)

test spell_levels_and_mana_gate_casting_like_canary: passed
///- --test --symbol
///> c

:= ~level = 8i32
castable level 90 WoundCleansing |> _assert_eq !+
castable level 90 Berserk |> _assert_eq !-
castable (level + 12) 70 (IntenseHealing DruidHeals) |> _assert_eq !+
__assert_eq { expected = true }
__assert_eq { expected = false }
__assert_eq { expected = true }

spell_data_matches_canary_scripts (test)

test spell_data_matches_canary_scripts: passed
///- --test --symbol
///> c

:= ~healer = PaladinHeals
(data_of (LightHealing healer))::mana |> _assert_eq 20i32
(data_of Berserk)::cooldown_ms |> _assert_eq 4000i32
__assert_eq { expected = 20 }
__assert_eq { expected = 4000 }

a_knight_cannot_cast_light_healing (test)

test a_knight_cannot_cast_light_healing: passed
///- --test --symbol --fails "Unification failure"
///> c

:= s : spell knight = LightHealing PaladinHeals
(data_of s)::mana
failed to compile as expected ("Unification failure"): FatalError: File main has a type error somewhere in its path. /home/runner/work/tibia/tibia/src/vocations.spi:80:40 (main.spi:64:40): ETY-TermError: Unification failure. Got:      healer knight Expected: healer paladin In the definition: spiral_cells_test.

a_paladin_cannot_cast_wound_cleansing (test)

test a_paladin_cannot_cast_wound_cleansing: passed
///- --test --symbol --fails "Unification failure"
///> c

:= s : spell paladin = WoundCleansing
(data_of s)::mana
failed to compile as expected ("Unification failure"): FatalError: File main has a type error somewhere in its path. /home/runner/work/tibia/tibia/src/vocations.spi:85:28 (main.spi:64:28): ETY-TermError: Unification failure. Got:      spell paladin Expected: spell knight In the definition: spiral_cells_test.

spell_data_on_gpu (test)

test spell_data_on_gpu: passed
///- --test --symbol
///> wgsl

:= ~level = 8i32
? castable level 90 WoundCleansing && castable level 90 Berserk = !- && (data_of Berserk)::cooldown_ms = 4000i32
?> 0i32
|: 1i32