#define AI_FILTER_KEY_MISSING KEY [not] glob_on_{KEY}=* [/not] #enddef #define AI_ASPECT_FILTER_STANDARD engine=cpp name=standard_aspect [or] {AI_FILTER_KEY_MISSING engine} name=standard_aspect [/or] #enddef #define AI_ASPECT_FILTER_COMPOSITE engine=cpp name=composite_aspect [or] {AI_FILTER_KEY_MISSING engine} name=composite_aspect [/or] #enddef #define AI_ASPECT_FILTER_DEFAULT [or] engine=cpp {AI_FILTER_KEY_MISSING name} [/or] [or] {AI_FILTER_KEY_MISSING engine} {AI_FILTER_KEY_MISSING name} [/or] #enddef #define AI_ASPECT_FILTER_ATTACKS engine=cpp name=ai_default_rca::aspect_attacks [or] {AI_FILTER_KEY_MISSING engine} name=ai_default_rca::aspect_attacks [/or] #enddef #define AI_ASPECT_FILTER_LUA engine=lua name=lua_aspect [or] engine=lua {AI_FILTER_KEY_MISSING name} [/or] [or] {AI_FILTER_KEY_MISSING engine} name=lua_aspect [/or] #enddef #define AI_ASPECT_SWITCH BASE [switch] key=id [case] value=aggression,caution,leader_aggression,leader_value,scout_village_targeting,village_value,recruitment_diversity super="{BASE}~real" [/case] [case] value=leader_ignores_keep,passive_leader,passive_leader_shares_keep,simple_targeting,support_villages super="{BASE}~bool" [/case] [case] value=villages_per_scout,recruitment_randomness super="{BASE}~int" [/case] [case] value=grouping super="{BASE}~grouping" [/case] [case] value=advancements,recruitment_more,recruitment_pattern super="{BASE}~string" [/case] [case] value=avoid super="{BASE}~avoid" [/case] [case] value=leader_goal super="{BASE}~leader_goal" [/case] [case] value=recruitment_instructions super="{BASE}~recruitment_instructions" [/case] [case] value=recruitment_save_gold super="{BASE}~recruitment_save_gold" [/case] [case] value=attacks super="{BASE}~attacks" [/case] [/switch] #enddef [tag] name="aspect" super="$ai/$component" max=infinite {AI_ASPECT_INVALIDATE} [if] # Check for composite first so that you can have a composite_aspect with id=attacks {AI_ASPECT_FILTER_COMPOSITE} {AI_ASPECT_FILTER_DEFAULT} [then] {AI_ASPECT_SWITCH $ai/composite_aspect} [/then] [elseif] # Check for attacks next so that you can't have standard_aspect with id=attacks {AI_ASPECT_FILTER_ATTACKS} [then] super="$ai/facet~attacks" [/then] [/elseif] [elseif] {AI_ASPECT_FILTER_STANDARD} [then] {AI_ASPECT_SWITCH $ai/standard_aspect} [/then] [/elseif] [elseif] {AI_ASPECT_FILTER_LUA} [then] super="$ai/facet~lua" [/then] [/elseif] # TODO: Somehow give an error for any other combination [/if] [/tag] [tag] name="$facet_base" super="$ai/$component" {AI_ASPECT_INVALIDATE} {AI_ASPECT_FILTERS} [/tag] [tag] name="facet~lua" super="$ai/$generic_lua_component" {SIMPLE_KEY value string} [/tag] #define AI_ASPECT NAME VALUE [tag] # This defines the valid content of an aspect with name=standard_aspect # and the specified ID name="standard_aspect~{NAME}" {VALUE} [/tag] [tag] # This defines the valid content of an aspect with name=composite_aspect # and the specified ID name="composite_aspect~{NAME}" [tag] name="facet" max=infinite super="$ai/facet~{NAME}" [/tag] [tag] name="default" super="$ai/facet~{NAME}" [/tag] [/tag] #enddef #define AI_FACET NAME VALUE {AI_ASPECT {NAME} {VALUE}} [tag] name="facet~{NAME}" super="$ai/$facet_base" [if] {AI_ASPECT_FILTER_STANDARD} {AI_ASPECT_FILTER_DEFAULT} [then] super="$ai/standard_aspect~{NAME}" [/then] [elseif] {AI_ASPECT_FILTER_COMPOSITE} [then] super="$ai/composite_aspect~{NAME}" [/then] [/elseif] [elseif] {AI_ASPECT_FILTER_LUA} [then] super="$ai/facet~lua" [/then] [/elseif] [else] # This required key is just a hack to get an error here. # It's not actually valid. {REQUIRED_KEY invalid_engine_name_combo_in_aspect bool} [/else] [/if] [/tag] #enddef #define AI_FACET_SCALAR TYPE INTERNAL_TYPE {AI_FACET {TYPE} {SIMPLE_KEY value {INTERNAL_TYPE}}} #enddef #define AI_FACET_TAG TAG CONTENTS {AI_FACET {TAG} ( [tag] name="value" {CONTENTS} [/tag] )} #enddef {AI_FACET_SCALAR real s_real} {AI_FACET_SCALAR int s_int} {AI_FACET_SCALAR bool s_bool} {AI_FACET_SCALAR string string_list} {AI_FACET_SCALAR grouping ai_grouping} {AI_FACET avoid {FILTER_TAG value location ()}} {AI_FACET_TAG leader_goal ( {SIMPLE_KEY id string} {SIMPLE_KEY x s_int} {SIMPLE_KEY y s_int} {SIMPLE_KEY max_risk s_real} {SIMPLE_KEY auto_remove s_bool} )} {AI_FACET_TAG recruitment_save_gold ( {SIMPLE_KEY active s_int} {SIMPLE_KEY begin s_real} {SIMPLE_KEY end s_real} {SIMPLE_KEY spend_all_gold s_int} {SIMPLE_KEY save_on_negative_income s_bool} )} {AI_FACET_TAG recruitment_instructions ( [tag] name="recruit" max=infinite super="$ai/$recruit" [/tag] [tag] name="total" max=infinite super="$ai/$recruit_base" [/tag] [tag] name="pattern" max=infinite super="$ai/$recruit_base" [/tag] [tag] name="limit" max=infinite super="$ai/$recruit_limit" [/tag] )} {AI_ASPECT attacks ( {FILTER_TAG filter_own unit ()} {FILTER_TAG filter_enemy unit ()} )} [tag] name="facet~attacks" super="$ai/$facet_base" [if] {AI_ASPECT_FILTER_ATTACKS} {AI_ASPECT_FILTER_DEFAULT} [then] super="$ai/standard_aspect~attacks" [/then] [elseif] {AI_ASPECT_FILTER_COMPOSITE} [then] super="$ai/composite_aspect~attacks" [/then] [/elseif] [elseif] {AI_ASPECT_FILTER_LUA} [then] super="$ai/facet~lua" [/then] [/elseif] [else] # This required key is just a hack to get an error here. # It's not actually valid. {REQUIRED_KEY invalid_engine_name_combo_in_aspect bool} [/else] [/if] [/tag]