#textdomain wesnoth

############################################################
# MODIFY_AI - ADD
############################################################

#define MODIFY_AI_ADD_ASPECT SIDE ASPECT_ID FACET_WML
    # modify ai, add facet to an aspect
    #
    # example: {MODIFY_AI_ADD_ASPECT 1 aggression ([facet] id=always value=0.5 [/facet])}
    # example: {MODIFY_AI_ADD_ASPECT 1 leader_goal ([facet] id=always [value]x=1 y=2[/value] [/facet])}

    [modify_ai]
        side={SIDE}
        action=add
        path=aspect[{ASPECT_ID}].facet
        {FACET_WML}
    [/modify_ai]
#enddef

#define MODIFY_AI_ADD_STAGE SIDE STAGE_WML
    # modify ai, add stage

    [modify_ai]
        side={SIDE}
        action=add
        path=stage
        {STAGE_WML}
    [/modify_ai]
#enddef

#define MODIFY_AI_ADD_GOAL SIDE GOAL_WML
    # modify ai, add goal

    [modify_ai]
        side={SIDE}
        action=add
        path=goal
        {GOAL_WML}
    [/modify_ai]
#enddef

#define MODIFY_AI_ADD_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION_WML
    # modify ai, add candidate action to a stage

    [modify_ai]
        side={SIDE}
        action=add
        path=stage[{STAGE_ID}].candidate_action
        {CANDIDATE_ACTION_WML}
    [/modify_ai]
#enddef

############################################################
# MODIFY_AI - DELETE
############################################################

#define MODIFY_AI_DELETE_ASPECT SIDE ASPECT_ID FACET_ID
    # modify ai, delete facet from aspect
    #
    # example: {MODIFY_AI_DELETE_ASPECT 1 aggression night}

    [modify_ai]
        side={SIDE}
        action=delete
        path=aspect[{ASPECT_ID}].facet[{FACET_ID}]
    [/modify_ai]
#enddef

#define MODIFY_AI_DELETE_STAGE SIDE STAGE_ID
    # modify ai, delete a stage
    #
    # example: {MODIFY_AI_DELETE_STAGE 1 fallback}
    # example: {MODIFY_AI_DELETE_STAGE 1 3}

    [modify_ai]
        side={SIDE}
        action=delete
        path=stage[{STAGE_ID}]
    [/modify_ai]
#enddef

#define MODIFY_AI_DELETE_GOAL SIDE GOAL_ID
    # modify ai, delete a goal
    #
    # example: {MODIFY_AI_DELETE_GOAL 1 kill_undead}
    # example: {MODIFY_AI_DELETE_GOAL 1 0}

    [modify_ai]
        side={SIDE}
        action=delete
        path=goal[{GOAL_ID}]
    [/modify_ai]
#enddef

#define MODIFY_AI_DELETE_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION_ID
    # modify ai, delete candidate action from a stage
    #
    # example: {MODIFY_AI_DELETE_CANDIDATE_ACTION 1 special_poisoning_formula}
    # example: {MODIFY_AI_DELETE_CANDIDATE_ACTION 1 0}

    [modify_ai]
        side={SIDE}
        action=delete
        path=stage[{STAGE_ID}].candidate_action[{CANDIDATE_ACTION_ID}]
    [/modify_ai]
#enddef

############################################################
# MODIFY_AI - TRY_DELETE
############################################################

#define MODIFY_AI_TRY_DELETE_ASPECT SIDE ASPECT_ID FACET_ID
    # modify ai, delete facet from aspect
    #
    # example: {MODIFY_AI_TRY_DELETE_ASPECT 1 aggression night}

    [modify_ai]
        side={SIDE}
        action=try_delete
        path=aspect[{ASPECT_ID}].facet[{FACET_ID}]
    [/modify_ai]
#enddef

#define MODIFY_AI_TRY_DELETE_STAGE SIDE STAGE_ID
    # modify ai, delete a stage
    #
    # example: {MODIFY_AI_TRY_DELETE_STAGE 1 fallback}
    # example: {MODIFY_AI_TRY_DELETE_STAGE 1 3}

    [modify_ai]
        side={SIDE}
        action=try_delete
        path=stage[{STAGE_ID}]
    [/modify_ai]
#enddef

#define MODIFY_AI_TRY_DELETE_GOAL SIDE GOAL_ID
    # modify ai, delete a goal
    #
    # example: {MODIFY_AI_TRY_DELETE_GOAL 1 kill_undead}
    # example: {MODIFY_AI_TRY_DELETE_GOAL 2 *}
    # example: {MODIFY_AI_TRY_DELETE_GOAL 3 0}

    [modify_ai]
        side={SIDE}
        action=try_delete
        path=goal[{GOAL_ID}]
    [/modify_ai]
#enddef

#define MODIFY_AI_TRY_DELETE_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION_ID
    # modify ai, delete candidate action from a stage
    #
    # example: {MODIFY_AI_TRY_DELETE_CANDIDATE_ACTION 1 special_poisoning_formula}
    # example: {MODIFY_AI_TRY_DELETE_CANDIDATE_ACTION 1 0}

    [modify_ai]
        side={SIDE}
        action=try_delete
        path=stage[{STAGE_ID}].candidate_action[{CANDIDATE_ACTION_ID}]
    [/modify_ai]
#enddef

############################################################
# ASPECTS - DECLARATION
############################################################

#define AI_ASPECT ASPECT_ID FACET_WML
    #macro to define a named facet of ai aspect
    [aspect]
        id={ASPECT_ID}
        {FACET_WML}
    [/aspect]
#enddef

############################################################
# ASPECTS - SIMPLE - DECLARATION (NO PREAMBLE NEEDED)
############################################################
# note: simple aspects are supposed to be used without a preamble

#define AI_SIMPLE_ASPECT ASPECT_ID FACET_ID VALUE
    # simple aspect with value=VALUE

    {AI_ASPECT {ASPECT_ID}
    (
        [facet]
            id={FACET_ID}
            value={VALUE}
        [/facet]
    )}
#enddef

#define AI_SIMPLE_ALWAYS_ASPECT ASPECT_ID VALUE
    # simple aspect which is always active

    {AI_SIMPLE_ASPECT {ASPECT_ID} "always" {VALUE}}
#enddef

#define AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY ASPECT_ID FACET_ID TIMEOFDAY_VALUE VALUE
    # simple aspect which is active during a specified time of day

    {AI_ASPECT {ASPECT_ID}
    (
        [facet]
            id={FACET_ID}
            value={VALUE}
            time_of_day={TIMEOFDAY_VALUE}
        [/facet]
    )}
#enddef

#define AI_SIMPLE_NIGHT_ASPECT ASPECT_ID VALUE
    # simple aspect which is active during the night

    {AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY {ASPECT_ID} "night" "dusk,first_watch,second_watch" {VALUE} }
#enddef

#define AI_SIMPLE_DAY_ASPECT ASPECT_ID VALUE
    # simple aspect which is active during the day

    {AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY {ASPECT_ID} "day" "dawn,morning,afternoon" {VALUE} }
#enddef

#define AI_SIMPLE_ASPECT_VALUE ASPECT_ID FACET_ID VALUE
    # simple aspect

    {AI_ASPECT {ASPECT_ID}
    (
        [facet]
            id={FACET_ID}
            [value]
                {VALUE}
            [/value]
        [/facet]
    )}
#enddef

#define AI_SIMPLE_ALWAYS_ASPECT_VALUE ASPECT_ID VALUE
    # simple aspect which is always active

    {AI_SIMPLE_ASPECT_VALUE {ASPECT_ID} "always" {VALUE}}
#enddef

#define AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE ASPECT_ID FACET_ID TIMEOFDAY_VALUE VALUE
    # simple aspect which is active during a specified time of day

    {AI_ASPECT {ASPECT_ID}
    (
        [facet]
            id={FACET_ID}
            [value]
                {VALUE}
            [/value]
            time_of_day={TIMEOFDAY_VALUE}
        [/facet]
    )}
#enddef

#define AI_SIMPLE_NIGHT_ASPECT_VALUE ASPECT_ID VALUE
    # simple aspect which is active during the night

    {AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE {ASPECT_ID} "night" "dusk,first_watch,second_watch" {VALUE} }
#enddef

#define AI_SIMPLE_DAY_ASPECT_VALUE ASPECT_ID VALUE
    # simple aspect which is active during the day

    {AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE {ASPECT_ID} "day" "dawn,morning,afternoon" {VALUE} }
#enddef

############################################################
# ASPECTS - SIMPLE - ADD (NO PREAMBLE NEEDED)
############################################################

#define MODIFY_AI_ADD_SIMPLE_ASPECT SIDE ASPECT_ID FACET_ID VALUE
    # modify ai, add simple facet to an aspect

    {MODIFY_AI_ADD_ASPECT {SIDE} {ASPECT_ID}
    (
        [facet]
            id={FACET_ID}
            value={VALUE}
        [/facet]
    )}
#enddef

#define MODIFY_AI_ADD_SIMPLE_ALWAYS_ASPECT SIDE ASPECT_ID VALUE
    # modify ai, add simple aspect which is always active

    {MODIFY_AI_ADD_SIMPLE_ASPECT {SIDE} {ASPECT_ID} "always" {VALUE}}
#enddef

#define MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY SIDE ASPECT_ID FACET_ID TIMEOFDAY_VALUE VALUE
    # modify ai, add simple aspect which is active during a specified time of day

    {MODIFY_AI_ADD_ASPECT {SIDE} {ASPECT_ID}
    (
        [facet]
            id={FACET_ID}
            value={VALUE}
            time_of_day={TIMEOFDAY_VALUE}
        [/facet]
    )}
#enddef

#define MODIFY_AI_ADD_SIMPLE_NIGHT_ASPECT SIDE ASPECT_ID VALUE
    # modify ai, add simple aspect which is active during the night

    {MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY {SIDE} {ASPECT_ID} "night" "dusk,first_watch,second_watch" {VALUE} }
#enddef

#define MODIFY_AI_ADD_SIMPLE_DAY_ASPECT SIDE ASPECT_ID VALUE
    # modify ai, add simple aspect which is active during the day

    {MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY {SIDE} {ASPECT_ID} "day" "dawn,morning,afternoon" {VALUE} }
#enddef

#define MODIFY_AI_ADD_SIMPLE_ASPECT_VALUE SIDE ASPECT_ID FACET_ID VALUE
    # modify ai, add simple facet to an aspect

    {MODIFY_AI_ADD_ASPECT {SIDE} {ASPECT_ID}
    (
        [facet]
            id={FACET_ID}
            [value]
                {VALUE}
            [/value]
        [/facet]
    )}
#enddef

#define MODIFY_AI_ADD_SIMPLE_ALWAYS_ASPECT_VALUE SIDE ASPECT_ID VALUE
    # modify ai, add simple aspect which is always active

    {MODIFY_AI_ADD_SIMPLE_ASPECT_VALUE {SIDE} {ASPECT_ID} "always" {VALUE}}
#enddef

#define MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE SIDE ASPECT_ID FACET_ID TIMEOFDAY_VALUE VALUE
    # modify ai, add simple aspect which is active during a specified time of day

    {MODIFY_AI_ADD_ASPECT {SIDE} {ASPECT_ID}
    (
        [facet]
            id={FACET_ID}
            [value]
                {VALUE}
            [/value]
            time_of_day={TIMEOFDAY_VALUE}
        [/facet]
    )}
#enddef

#define MODIFY_AI_ADD_SIMPLE_NIGHT_ASPECT_VALUE SIDE ASPECT_ID VALUE
    # modify ai, add simple aspect which is active during the night

    {MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE {SIDE} {ASPECT_ID} "night" "dusk,first_watch,second_watch" {VALUE} }
#enddef

#define MODIFY_AI_ADD_SIMPLE_DAY_ASPECT_VALUE SIDE ASPECT_ID VALUE
    # modify ai, add simple aspect which is active during the day

    {MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE {SIDE} {ASPECT_ID} "day" "dawn,morning,afternoon" {VALUE} }
#enddef

#define AI_NO_SCOUTS
    # make the AI team not recruit scouts.

    {AI_SIMPLE_ALWAYS_ASPECT villages_per_scout 0}
#enddef

#define AI_NEW_SYNTAX
    # use stable 1.8 ai syntax
    version=10710
#enddef

#define AI_SCALE_ATTACK_DEPTH_BY_DIFFICULTY
    # change attack depth depending on difficulty
#ifdef EASY
    {AI_SIMPLE_ALWAYS_ASPECT attack_depth 3}
#endif

#ifdef NORMAL
    {AI_SIMPLE_ALWAYS_ASPECT attack_depth 4}
#endif

#ifdef HARD
    {AI_SIMPLE_ALWAYS_ASPECT attack_depth 5}
#endif

#enddef

############################################################
# RECRUITMENT ASPECTS
############################################################

#define AI_DEACTIVATE_SAVE_GOLD
    # disable aspect recruitment_save_gold
    [facet]
        id="always"
        [value]
            active=0
        [/value]
    [/facet]
#enddef

#define AI_NO_RECRUITMENT
    # disable recruitment
    [facet]
        id="always"
        [value]
            [recruit]
                importance=1
                number=0
            [/recruit]
        [/value]
    [/facet]
#enddef

#define AI_SAVE_GOLD ACTIVE BEGIN END
    # Enable AI recruitment gold saving.
    # ACTIVE: turn from which on gold saving will be active
    # BEGIN: begin gold saving when unit cost ratio rises above this value
    # END: end gold saving when unit cost ratio drops below this value
    # This goes directly into the [ai] tag.

    [aspect]
        id=recruitment_save_gold
        [facet]
            [value]
                active={ACTIVE}
                begin={BEGIN}
                end={END}
            [/value]
        [/facet]
    [/aspect]
#enddef

#define AI_SAVE_GOLD_DEFAULT
    # Enable AI recruitment gold saving with values set
    # to what was the default in Wesnoth 1.11.7 and 1.11.8.
    # This goes directly into the [ai] tag.

    {AI_SAVE_GOLD 2 1.5 1.1}
#enddef

############################################################
# NEW FORMULA_AI RECRUITMENT BY Dragonking (experimental!)
############################################################

#define AI_FORMULA_AI_EXPERIMENTAL_RECRUITMENT
    [facet]
        id="always"
        [value]
            engine=fai
            name=side_formulas
            move="{ai/formula/new_recruitment.fai}"
        [/value]
    [/facet]
#enddef

#define AI_SIMPLE_FORMULA_AI_EXPERIMENTAL_RECRUITMENT
    #enable new formula-ai recruitment made by Dragonking (experimental!)
    {AI_ASPECT recruitment {AI_FORMULA_AI_EXPERIMENTAL_RECRUITMENT} }
#enddef

############################################################
# CANDIDATE_ACTIONS
############################################################

############################################################
# LEADER GOALS ( aspect[leader_goal] )
############################################################

####
# internal macro
#
#define _AI_ASPECT_LEADER_GOAL_MOVE_TO X Y AUTOREMOVE_VALUE

    [facet]
        id="always"
        [value]
            id="always"
            x={X}
            y={Y}
            auto_remove={AUTOREMOVE_VALUE}
        [/value]
    [/facet]
#enddef

####
# internal macro
#
#define _AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO X Y AUTOREMOVE_VALUE

    [facet]
        id="always"
        [value]
            id="always"
            x={X}
            y={Y}
            max_risk=10000
            auto_remove={AUTOREMOVE_VALUE}
        [/value]
    [/facet]
#enddef

#define AI_ASPECT_LEADER_GOAL_MOVE_TO X Y
    # leader goal: move to X Y and be free

    {_AI_ASPECT_LEADER_GOAL_MOVE_TO {X} {Y} "yes"}
#enddef

#define AI_ASPECT_LEADER_GOAL_MOVE_TO_AND_STAY_THERE X Y
    # leader goal: move to X Y and stay there

    {_AI_ASPECT_LEADER_GOAL_MOVE_TO {X} {Y} "no"}
#enddef

#define CLEAR_AI_ALWAYS_ASPECT_LEADER_GOAL SIDE
    # clear AI leader goal "always"

    {MODIFY_AI_DELETE_ASPECT {SIDE} leader_goal always}
#enddef

#define AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO X Y
    # leader goal: move to X Y and be free

    {_AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO {X} {Y} "yes"}
#enddef

#define AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO_AND_STAY_THERE X Y
    # leader goal: move to X Y and stay there

    {_AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO {X} {Y} "no"}
#enddef

############################################################
# EXPERIMENTAL AI
############################################################

#define EXPERIMENTAL_AI
    # Experimental AI with alternative recruitment, castle switching, alternative retreating,
    # village grabbing, poison spreading, healer placement, village hunting and
    # move-to-enemy candidate actions.
    # Put this into the [side][ai] tag.
    # Does not work in [modify_side][ai] or [modify_ai] at the moment.
    version=10710
    [engine]
        name="lua"
        code= <<
            local ai = ...
            return wesnoth.require("ai/lua/generic_rush_engine.lua").init(ai)
        >>
    [/engine]
    [stage]
        id=main_loop
        name=ai_default_rca::candidate_action_evaluation_loop
        {AI_CA_GOTO}
        #{AI_CA_RECRUITMENT}
        {AI_CA_MOVE_LEADER_TO_GOALS}
        {AI_CA_MOVE_LEADER_TO_KEEP}
        {AI_CA_COMBAT}
        {AI_CA_HEALING}
        {AI_CA_VILLAGES}
        {AI_CA_RETREAT}
        {AI_CA_MOVE_TO_TARGETS}
        {AI_CA_LEADER_SHARES_KEEP}
        [candidate_action]
            engine=lua
            name=recruit_rushers
            max_score=300000
            evaluation="return (...):recruit_rushers_eval()"
            execution="(...):recruit_rushers_exec()"
        [/candidate_action]
        [candidate_action]
            engine=lua
            name=switch_castle
            max_score=290000
            evaluation="return (...):castle_switch_eval()"
            execution="(...):castle_switch_exec()"
        [/candidate_action]
        [candidate_action]
            engine=lua
            name=retreat_injured
            max_score=205000
            evaluation="return (...):retreat_injured_units_eval()"
            execution="(...):retreat_injured_units_exec()"
        [/candidate_action]
        [candidate_action]
            engine=lua
            name=grab_villages
            max_score=200000
            evaluation="return (...):grab_villages_eval()"
            execution="(...):grab_villages_exec()"
        [/candidate_action]
        [candidate_action]
            engine=lua
            name=spread_poison
            max_score=190000
            evaluation="return (...):spread_poison_eval()"
            execution="(...):spread_poison_exec()"
        [/candidate_action]
        [candidate_action]
            engine=lua
            name=place_healers
            max_score=95000
            evaluation="return (...):place_healers_eval()"
            execution="(...):place_healers_exec()"
        [/candidate_action]
        [candidate_action]
            engine=lua
            name=hunt_villages
            max_score=30000
            evaluation="return (...):village_hunt_eval()"
            execution="(...):village_hunt_exec()"
        [/candidate_action]
        [candidate_action]
            engine=lua
            name=move_to_enemy
            max_score=1
            evaluation="return (...):move_to_enemy_eval()"
            execution="(...):move_to_enemy_exec()"
        [/candidate_action]
    [/stage]
#enddef
