#textdomain wesnoth # Side-utils macros for balancing AI behaviour and setting village ownership. # You can, for example give an AI side the possibility to recruit high # level units but not to have too many of them at the same time. # Note: These generate events, so they need to be placed directly # under your [scenario] tag, and not within an event such as start or # prestart. #define LIMIT_CONTEMPORANEOUS_RECRUITS SIDES TYPE LIMIT_NUMBER # Limit the number of units passing a specified filter that a side # can have simultaneously. When the number of matching units # side has reaches or exceeds LIMIT_NUMBER, that side is prevented from # recruiting more until the number of units of that type drops # below LIMIT_NUMBER again. # # Allow sides 2 and 3 no more than 2 Troll Rocklobbers at a time #! {LIMIT_CONTEMPORANEOUS_RECRUITS 2,3 "Troll Rocklobber" 2} [event] name=side turn first_time_only=no [filter_condition] # Note: we cannot simply check if {SIDES} contains $side_number, # because that would break for side numbers >9 ("12" would contain # both "1" and "2", etc). So instead, we check whether there exists # a unit which belongs both to the current side as well as {SIDES}. [have_unit] side=$side_number [and] side={SIDES} [/and] [/have_unit] [/filter_condition] [if] [have_unit] side=$side_number type={TYPE} count="{LIMIT_NUMBER}-99999" [/have_unit] [then] [disallow_recruit] side=$side_number type={TYPE} [/disallow_recruit] [/then] [else] [allow_recruit] side=$side_number type={TYPE} [/allow_recruit] [/else] [/if] [/event] [event] name=recruit first_time_only=no [filter] side={SIDES} type={TYPE} [/filter] [if] [have_unit] side=$side_number type={TYPE} count="{LIMIT_NUMBER}-99999" [/have_unit] [then] [disallow_recruit] side=$side_number type={TYPE} [/disallow_recruit] [/then] [/if] [/event] #enddef #define LIMIT_RECRUITS SIDE TYPE LIMIT_NUMBER # Limit the total number of units passing a specified filter that a given # side can recruit in the scenario. # # Allow side 2 no more than 1 Draug in the entire scenario #! {LIMIT_RECRUITS 2 Draug 1} [event] name=prestart # the array holding the recruit-limited types is cleared here, because # it could hold values carried over from the previous scenario {CLEAR_VARIABLE side_{SIDE}_limited_recruits} {VARIABLE side_{SIDE}_limited_recruits_length -1} [/event] [event] name=victory # Clear our variables on victory {CLEAR_VARIABLE side_{SIDE}_limited_recruits,side_{SIDE}_limited_recruits_length} [/event] # when the side recruits this given type for the first time, it's recorded # in an array that holds info on all the recruit-limited types for this side [event] name=recruit first_time_only=yes [filter] side={SIDE} type={TYPE} [/filter] {VARIABLE_OP side_{SIDE}_limited_recruits_length add 1} {VARIABLE side_{SIDE}_limited_recruits[$side_{SIDE}_limited_recruits_length|].type $unit.type} [/event] # and every time when the side recruits this given type, we increment a # counter, and if it matches or exceeds the limit, we disallow recruiting # more of those units [event] name=recruit first_time_only=no [filter] side={SIDE} type={TYPE} [/filter] {FOREACH side_{SIDE}_limited_recruits i} [if] [variable] name=side_{SIDE}_limited_recruits[$i].type equals=$unit.type [/variable] [then] {VARIABLE_OP side_{SIDE}_limited_recruits[$i].number_recruited add 1} [if] [variable] name=side_{SIDE}_limited_recruits[$i].number_recruited greater_than_equal_to={LIMIT_NUMBER} [/variable] [then] [disallow_recruit] side={SIDE} type={TYPE} [/disallow_recruit] [/then] [/if] [/then] [/if] {NEXT i} [/event] #enddef #define CAPTURE_VILLAGES_OF_TYPE TERRAIN SIDE X Y RADIUS # Change ownership of the villages on a specified terrain type # near a specified location. [capture_village] side={SIDE} terrain={TERRAIN} [and] x,y={X},{Y} radius={RADIUS} [/and] [/capture_village] #enddef #define CAPTURE_VILLAGES SIDE X Y RADIUS # Change ownership of all villages near a specified location. {CAPTURE_VILLAGES_OF_TYPE (*^V*) {SIDE} {X} {Y} {RADIUS}} #enddef #define STARTING_VILLAGES SIDE RADIUS # Macro to make a side start a scenario with villages. # Creates an event, so it must be called from within the # toplevel scenario tag. Also note that this relies on the # side having a unit with canrecruit-yes at start; if it # doesn't, you should use STARTING_VILLAGES_AREA instead. [event] name=prestart [store_starting_location] side={SIDE} variable=temp_starting_location [/store_starting_location] {CAPTURE_VILLAGES {SIDE} $temp_starting_location.x $temp_starting_location.y {RADIUS}} {CLEAR_VARIABLE temp_starting_location} [/event] #enddef #define STARTING_VILLAGES_AREA SIDE X Y RADIUS # Make a side start with ownership of villages in a given area. # Creates an event, so it must be called from within the # toplevel scenario tag. [event] name=prestart {CAPTURE_VILLAGES {SIDE} {X} {Y} {RADIUS}} [/event] #enddef #define STARTING_VILLAGES_ALL SIDE # Make a side start with ownership of all villages. # Creates an event, so it must be called from within the # toplevel scenario tag. [event] name=prestart [capture_village] side={SIDE} terrain=*^V* [/capture_village] [/event] #enddef #define TRANSFER_VILLAGE_OWNERSHIP FROM_SIDE TO_SIDE # Transfers ownership of all villages of one side to another side. Useful # when you're for example moving all units of some side to another, and want # to transfer the village ownership as well. [capture_village] owner_side={FROM_SIDE} side={TO_SIDE} [/capture_village] #enddef # Persistant macros #define MAKE_AI_SIDE_PERSISTENT SIDE #Macro to make a ai controlled side persistent. #Needs to be placed below the side definition. [+side] controller=human persistent=yes [/side] [event] name=prestart [modify_side] side={SIDE} controller=ai [/modify_side] [/event] [event] name=victory [modify_side] side={SIDE} controller=human [/modify_side] [/event] #enddef #define RECALL_AI_SIDE SIDE #Recalls an ai side that is persistent (MAKE_AI_SIDE_PERSISTENT) #Needs to be placed below the side definition. {MAKE_AI_SIDE_PERSISTENT {SIDE}} [event] name=prestart [store_unit] variable=recall_ai_side_units_{SIDE} [filter] side={SIDE} [/filter] [/store_unit] [/event] [event] name=victory {CLEAR_VARIABLE recall_ai_side_units_{SIDE}} [/event] [event] name=ai turn [if] [variable] name=side_number equals={SIDE} [/variable] [and] [have_unit] canrecruit=yes side={SIDE} [filter_location] terrain=K* [/filter_location] [/have_unit] [/and] [then] [store_gold] side={SIDE} [/store_gold] [while] [variable] name=gold greater_than=19 [/variable] [variable] name=recall_ai_side_units_{SIDE}.length greater_than=0 [/variable] [do] [gold] side={SIDE} amount=-20 [/gold] [store_gold] side={SIDE} [/store_gold] [recall] id=$recall_ai_side_units_{SIDE}[0].id [/recall] {CLEAR_VARIABLE recall_ai_side_units_{SIDE}[0]} [/do] [/while] {CLEAR_VARIABLE gold} [/then] [/if] [/event] #enddef