#textdomain wesnoth
# This file contains unit utility macros for WML authors.
#
# These don't rely on any other macros.   Please don't change this.

# This needs to match the magic UNREACHABLE constent in unit_movement_type
#define UNREACHABLE
99 #enddef

# Use this to restrict a filter to on-map units, not the recall list.
#define NOT_ON_RECALL_LIST
    [not]
        x,y=recall,recall
    [/not]
#enddef

# Rationale for the naming scheme of these generators:
# All generators take SIDE X Y for consistency.
# Those that begin with NAMED_ additionally take ID_STRING NAME_STRING
# The LOYAL_ macros set the loyalty trait.

#define UNIT SIDE TYPE X Y WML
    # Place a unit with embedded WML specified.
    #
    [unit]
        side={SIDE}
        type={TYPE}
        x={X}
        y={Y}
        {WML}
    [/unit]
#enddef

#define GENERIC_UNIT SIDE TYPE X Y
    # Creates a generic unit of TYPE belonging to SIDE at X,Y, which has a
    # random name, gender and traits (just like a recruited unit).
    [unit]
        side={SIDE}
        type={TYPE}
        x={X}
        y={Y}
        generate_name=yes
        random_traits=yes
        random_gender=yes
        upkeep=full
    [/unit]
#enddef

#define NOTRAIT_UNIT SIDE TYPE X Y
    # Creates a unit with no traits, random gender and generated name.
    #
    # Example:
    #! {NOTRAIT_UNIT 1 (Elvish Fighter) 19 16}
    #
    [unit]
        side={SIDE}
        type={TYPE}
        x={X}
        y={Y}
        generate_name=yes
        random_traits=no
        random_gender=yes
    [/unit]
#enddef

#define LOYAL_UNIT SIDE TYPE X Y
    # Creates a unit with the Loyal trait.
    #
    # Example:
    #! {LOYAL_UNIT 1 (Elvish Fighter) 19 16}
    #
    [unit]
        type={TYPE}
        side={SIDE}
        x={X}
        y={Y}
        generate_name=yes
        [modifications]
            {TRAIT_LOYAL}
        [/modifications]
    [/unit]
#enddef

#define LOYAL_UNDEAD_UNIT SIDE TYPE X Y
    # Create a unit with the Undead and Loyal traits.
    [unit]
        type={TYPE}
        side={SIDE}
        x={X}
        y={Y}
        [modifications]
            {TRAIT_UNDEAD}
            {TRAIT_LOYAL}
        [/modifications]
    [/unit]
#enddef

#define NAMED_UNIT SIDE TYPE X Y ID_STRING NAME_STRING WML
    # Place a named unit with embedded WML specified.
    #
    [unit]
        side={SIDE}
        type={TYPE}
        x={X}
        y={Y}
        id={ID_STRING}
        name={NAME_STRING}
        {WML}
    [/unit]
#enddef

#define NAMED_LOYAL_UNIT SIDE TYPE X Y ID_STRING NAME_STRING
    # Creates a unit with the Loyal trait.
    #
    # Example:
    #! {LOYAL_UNIT 1 (Elvish Fighter) 19 16 (Myname) ( _ "Myname")}
    #
    [unit]
        type={TYPE}
        id={ID_STRING}
        name={NAME_STRING}
        side={SIDE}
        x={X}
        y={Y}
        [modifications]
            {TRAIT_LOYAL}
        [/modifications]
    [/unit]
#enddef

#define NAMED_GENERIC_UNIT SIDE TYPE X Y ID_STRING NAME_STRING
    # Creates a generic unit of TYPE belonging to SIDE at X,Y, which has a
    # generated gender and traits (just like a recruited unit).
    [unit]
        side={SIDE}
        type={TYPE}
        id={ID_STRING}
        name={NAME_STRING}
        x={X}
        y={Y}
        random_traits=yes
        random_gender=yes
        upkeep=full
    [/unit]
#enddef

#define NAMED_NOTRAIT_UNIT SIDE TYPE X Y ID_STRING NAME_STRING
    # Creates a unit with no traits, random gender and specified name.
    #
    # Example:
    #! {NAMED_NOTRAIT_UNIT 1 (Elvish Fighter) 20 22 (Mochi) (_"Mochi") }
    #
    [unit]
        side={SIDE}
        type={TYPE}
        id={ID_STRING}
        name={NAME_STRING}
        x={X}
        y={Y}
        random_traits=no
        random_gender=yes
    [/unit]
#enddef

#define GUARDIAN
    # Meant to be used as a suffix to a unit-generating macro call.
    [+unit]
        ai_special=guardian
        animate=no
    [/unit]
#enddef

#define NO_UPKEEP
    # Meant to be used as a suffix to a unit-generating macro call.
    # Use this wheen you don't want to use up a traits slot.
    [+unit]
        upkeep=loyal
    [/unit]
#enddef

#define RECALL_OR_CREATE TYPE ID_STRING
    # A substitute for [recall] that works even when there's no-one to recall
    # useful for testing scenarios out of order.
    [recall]
        id={ID_STRING}
    [/recall]
    [if]
        [have_unit]
            id={ID_STRING}
        [/have_unit]
        [else]
            [store_starting_location]
                side=1
                variable=tmp
            [/store_starting_location]
            [unit]
                type={TYPE}
                id={ID_STRING}
                side=1
                x=$tmp.x
                y=$tmp.y
            [/unit]
            [clear_variable]
                name=tmp
            [/clear_variable]
        [/else]
    [/if]
#enddef

#define STORE_UNIT_VAR FILTER VAR TO_VAR
    # Stores an attribute of a unit to the given variable.
    #
    # Example where this is used to flip all orcs to whatever side James is on:
    #! {STORE_UNIT_VAR (id=James) side side_of_James}
    #! {MODIFY_UNIT (race=orc) side $side_of_James}
    [store_unit]
        [filter]
            {FILTER}
        [/filter]

        kill=no
        variable=STORE_UNIT_VAR_store
    [/store_unit]

    [set_variable]
        name={TO_VAR}
        format=$STORE_UNIT_VAR_store.{VAR}
    [/set_variable]

    [clear_variable]
        name=STORE_UNIT_VAR_store
    [/clear_variable]
#enddef

#define ADVANCE_UNIT FILTER ADVANCETO
    # Advances all units matching the filter to ADVANCETO or if missing, their normal advancement
    #
    # Example to advance all spearmen to a cavalrymen:
    #! {ADVANCE_UNIT type=Spearman Cavalryman}
    # Example to advance your leader normally:
    #! {ADVANCE_UNIT canrecruit,side=yes,1 ""}
    [store_unit]
        [filter]
            {FILTER}
        [/filter]
        variable=ADVANCE_UNIT_store
        kill=no
    [/store_unit]
    [set_variable]
        name=advanceto_len
        string_length={ADVANCETO}
    [/set_variable]

    {FOREACH ADVANCE_UNIT_store i}
        [if]
            [variable]
                name=advanceto_len
                greater_than=0
            [/variable]
            [then]
                [set_variable]
                    name=ADVANCE_UNIT_store[$i].advances_to
                    value={ADVANCETO}
                [/set_variable]
            [/then]
        [/if]
        [set_variable]
            name=ADVANCE_UNIT_store[$i].experience
            value=$ADVANCE_UNIT_store[$i].max_experience
        [/set_variable]
        [unstore_unit]
            variable=ADVANCE_UNIT_store[$i]
            find_vacant=no
            advance=true
        [/unstore_unit]
    {NEXT i}
    {CLEAR_VARIABLE ADVANCE_UNIT_store}
    {CLEAR_VARIABLE advanceto_len}
#enddef

#define TRANSFORM_UNIT T_FILTER TRANSFORMTO
    # Transforms all units matching the filter into TRANSFORMTO or if missing, their normal advancement
    # Keeps the unit's hitpoints, experience and status intact.
    #
    # Example to turn all spearmen into cavalrymen:
    #! {TRANSFORM_UNIT type=Spearman Cavalryman}
    [store_unit]
        [filter]
            {T_FILTER}
        [/filter]
        variable=TU_store
        kill=no
    [/store_unit]
    {ADVANCE_UNIT ({T_FILTER}) ({TRANSFORMTO}) }
    {FOREACH TU_store i}
        [store_unit]
            [filter]
                x,y=$TU_store[$i].x,$TU_store[$i].y
            [/filter]
            variable=TUrestore_store
            kill=yes
        [/store_unit]
        [set_variables]
            name=TUrestore_store
            mode=merge
            [value]
                hitpoints=$TU_store[$i].hitpoints
                experience=$TU_store[$i].experience
                [insert_tag]
                    name=status
                    variable=TU_store[$i].status
                [/insert_tag]
            [/value]
        [/set_variables]
        [if]
            [variable]
                name=TUrestore_store.status.not_living
                boolean_equals=true
            [/variable]
            [then]
                [clear_variable]
                    name=TUrestore_store.status.poisoned
                [/clear_variable]
            [/then]
        [/if]
        [unstore_unit]
            variable=TUrestore_store
            find_vacant=no
            advance=false
        [/unstore_unit]
        {CLEAR_VARIABLE TUrestore_store}
    {NEXT i}
    {CLEAR_VARIABLE TU_store}
#enddef
