Merge pull request #557 from gfgtdf/lua_placement
add tag [random_placement]
This commit is contained in:
commit
856839e93f
8 changed files with 238 additions and 398 deletions
|
@ -169,56 +169,38 @@
|
|||
boolean_not_equals=yes
|
||||
[/variable]
|
||||
[/filter_condition]
|
||||
|
||||
{VARIABLE_OP number_of_guards rand "0..2"}
|
||||
{VARIABLE guard_i 1}
|
||||
|
||||
[while]
|
||||
[variable]
|
||||
name=guard_i
|
||||
less_than_equal_to=$number_of_guards
|
||||
[/variable]
|
||||
|
||||
[do]
|
||||
[store_locations]
|
||||
[filter_adjacent_location]
|
||||
x,y=$x1,$y1
|
||||
[/filter_adjacent_location]
|
||||
|
||||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
|
||||
variable=possible_guard_locations
|
||||
[/store_locations]
|
||||
|
||||
{IF_VAR possible_guard_locations.length greater_than 0 (
|
||||
[then]
|
||||
{VARIABLE_OP random_location_index rand "0..$($possible_guard_locations.length - 1)"}
|
||||
|
||||
[move_unit_fake]
|
||||
side=2
|
||||
type=Goblin Spearman
|
||||
x=$x1,$possible_guard_locations[$random_location_index].x
|
||||
y=$y1,$possible_guard_locations[$random_location_index].y
|
||||
[/move_unit_fake]
|
||||
|
||||
[unit]
|
||||
id=guard_$x1|_$y1|_$guard_i
|
||||
name= _ "Villager"
|
||||
type=Goblin Spearman
|
||||
side=2
|
||||
x,y=$possible_guard_locations[$random_location_index].x,$possible_guard_locations[$random_location_index].y
|
||||
random_traits=yes
|
||||
[/unit]
|
||||
[/then]
|
||||
)}
|
||||
|
||||
{VARIABLE_OP guard_i add 1}
|
||||
[/do]
|
||||
[/while]
|
||||
[random_placement]
|
||||
num_items="$number_of_guards"
|
||||
allow_less=yes
|
||||
variable=guard_location
|
||||
[filter]
|
||||
[filter_adjacent_location]
|
||||
x,y=$x1,$y1
|
||||
[/filter_adjacent_location]
|
||||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
[/filter]
|
||||
[command]
|
||||
[move_unit_fake]
|
||||
side=2
|
||||
type=Goblin Spearman
|
||||
x=$x1,$guard_location.x
|
||||
y=$y1,$guard_location.y
|
||||
[/move_unit_fake]
|
||||
|
||||
[unit]
|
||||
id=guard_$x1|_$y1|_$guard_location.n
|
||||
name= _ "Villager"
|
||||
type=Goblin Spearman
|
||||
side=2
|
||||
x,y=$guard_location.x,$guard_location.y
|
||||
random_traits=yes
|
||||
[/unit]
|
||||
[/command]
|
||||
[/random_placement]
|
||||
{VARIABLE village_$x1|_$y1|_cleared yes}
|
||||
|
||||
# Trigger an easter egg sometime after a third of villages have been taken
|
||||
|
@ -268,7 +250,7 @@
|
|||
[/then]
|
||||
[/if]
|
||||
|
||||
{CLEAR_VARIABLE number_of_guards,guard_i,possible_guard_locations,random_location_index}
|
||||
{CLEAR_VARIABLE number_of_guards,guard_i,guard_location,random_location_index}
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
|
|
|
@ -220,74 +220,29 @@
|
|||
# clump all the ambushers into a single corner of the map.
|
||||
|
||||
#define UNDEAD_AMBUSH_AREA SIDE X_SPAN Y_SPAN NUMBER
|
||||
[store_locations]
|
||||
x={X_SPAN}
|
||||
y={Y_SPAN}
|
||||
terrain=Ss
|
||||
[random_placement]
|
||||
variable=ambush_location
|
||||
num_items={NUMBER}
|
||||
[filter]
|
||||
x={X_SPAN}
|
||||
y={Y_SPAN}
|
||||
terrain=Ss
|
||||
|
||||
[filter_adjacent_location]
|
||||
[not]
|
||||
terrain=Ss
|
||||
[/not]
|
||||
|
||||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
[/filter_adjacent_location]
|
||||
|
||||
variable=possible_ambush_locations
|
||||
[/store_locations]
|
||||
|
||||
{VARIABLE ambusher 0}
|
||||
|
||||
[while]
|
||||
[variable]
|
||||
name=ambusher
|
||||
less_than={NUMBER}
|
||||
[/variable]
|
||||
|
||||
[do]
|
||||
{RANDOM 1..$possible_ambush_locations.length}
|
||||
{VARIABLE_OP random sub 1}
|
||||
|
||||
# Check if the random location picked already contains an ambusher
|
||||
# and if it does, we loop again to pick another one until an empty
|
||||
# one is found.
|
||||
|
||||
[if]
|
||||
[have_unit]
|
||||
x,y=$possible_ambush_locations[$random].x,$possible_ambush_locations[$random].y
|
||||
[/have_unit]
|
||||
|
||||
[else]
|
||||
# random_ambusher_type_i is just a counter variable with
|
||||
# which we point to a given element of the
|
||||
# random_ambusher_type_table array. Here we make it loop
|
||||
# over the array continuously.
|
||||
|
||||
[if]
|
||||
[variable]
|
||||
name=random_ambusher_type_i
|
||||
less_than=4
|
||||
[/variable]
|
||||
|
||||
[then]
|
||||
{VARIABLE_OP random_ambusher_type_i add 1}
|
||||
[/then]
|
||||
|
||||
[else]
|
||||
{VARIABLE random_ambusher_type_i 0}
|
||||
[/else]
|
||||
[/if]
|
||||
|
||||
# And here we place an ambusher of a type specified by the
|
||||
# random_ambusher_type_table and random_ambusher_type_i
|
||||
# variables, thus always having the same ratio of different
|
||||
# types.
|
||||
[filter_adjacent_location]
|
||||
[not]
|
||||
terrain=Ss
|
||||
[/not]
|
||||
|
||||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
[/filter_adjacent_location]
|
||||
[/filter]
|
||||
[command]
|
||||
{VARIABLE random_ambusher_type_i ($($random_ambusher_type_i + 1) % $random_ambusher_type_table.length)}
|
||||
[unit]
|
||||
x,y=$possible_ambush_locations[$random].x,$possible_ambush_locations[$random].y
|
||||
x,y=$ambush_location.x,$ambush_location.y
|
||||
type=$random_ambusher_type_table[$random_ambusher_type_i].type
|
||||
side={SIDE}
|
||||
role=ambusher
|
||||
|
@ -299,7 +254,7 @@
|
|||
silent=yes
|
||||
|
||||
[filter]
|
||||
x,y=$possible_ambush_locations[$random].x,$possible_ambush_locations[$random].y
|
||||
x,y=$ambush_location.x,$ambush_location.y
|
||||
[/filter]
|
||||
|
||||
[effect]
|
||||
|
@ -321,12 +276,8 @@
|
|||
[/abilities]
|
||||
[/effect]
|
||||
[/object]
|
||||
|
||||
{VARIABLE_OP ambusher add 1}
|
||||
[/else]
|
||||
[/if]
|
||||
[/do]
|
||||
[/while]
|
||||
[/command]
|
||||
[/random_placement]
|
||||
#enddef
|
||||
|
||||
# Only the number of ambushers differs by difficulty here.
|
||||
|
|
|
@ -284,8 +284,10 @@
|
|||
#define ORC_AMBUSH_AREA SIDE X_SPAN Y_SPAN NUMBER
|
||||
# Any hill that's completely surrounded by other hills, mountains or
|
||||
# forest is eligible as an ambush location.
|
||||
|
||||
[store_locations]
|
||||
[random_placement]
|
||||
variable=ambush_location
|
||||
num_items={NUMBER}
|
||||
[filter]
|
||||
x={X_SPAN}
|
||||
y={Y_SPAN}
|
||||
terrain=Hh
|
||||
|
@ -297,37 +299,8 @@
|
|||
[/not]
|
||||
[/filter_adjacent_location]
|
||||
[/not]
|
||||
|
||||
variable=possible_ambush_locations
|
||||
[/store_locations]
|
||||
|
||||
{VARIABLE ambusher 0}
|
||||
|
||||
[while]
|
||||
[variable]
|
||||
name=ambusher
|
||||
less_than={NUMBER}
|
||||
[/variable]
|
||||
|
||||
[do]
|
||||
{RANDOM 1..$possible_ambush_locations.length}
|
||||
{VARIABLE_OP random sub 1}
|
||||
|
||||
# Check if the random location picked already contains an ambusher
|
||||
# and if it does, we loop again to pick another one until an empty
|
||||
# one is found.
|
||||
|
||||
[if]
|
||||
[have_unit]
|
||||
x,y=$possible_ambush_locations[$random].x,$possible_ambush_locations[$random].y
|
||||
[/have_unit]
|
||||
|
||||
[else]
|
||||
# random_ambusher_type_i is just a counter variable with
|
||||
# which we point to a given element of the
|
||||
# random_ambusher_type_table array. Here we make it loop
|
||||
# over the array continuously.
|
||||
|
||||
[/filter]
|
||||
[command]
|
||||
[if]
|
||||
[variable]
|
||||
name=random_ambusher_type_i
|
||||
|
@ -349,7 +322,7 @@
|
|||
# types.
|
||||
|
||||
[unit]
|
||||
x,y=$possible_ambush_locations[$random].x,$possible_ambush_locations[$random].y
|
||||
x,y=$ambush_location.x,$ambush_location.y
|
||||
type=$random_ambusher_type_table[$random_ambusher_type_i].type
|
||||
side={SIDE}
|
||||
facing=sw
|
||||
|
@ -366,7 +339,7 @@
|
|||
silent=yes
|
||||
|
||||
[filter]
|
||||
x,y=$possible_ambush_locations[$random].x,$possible_ambush_locations[$random].y
|
||||
x,y=$ambush_location.x,$ambush_location.y
|
||||
[/filter]
|
||||
|
||||
[effect]
|
||||
|
@ -388,12 +361,9 @@
|
|||
[/abilities]
|
||||
[/effect]
|
||||
[/object]
|
||||
|
||||
{VARIABLE_OP ambusher add 1}
|
||||
[/else]
|
||||
[/if]
|
||||
[/do]
|
||||
[/while]
|
||||
[/command]
|
||||
[/random_placement]
|
||||
|
||||
#enddef
|
||||
|
||||
# Only the number of ambushers differs by difficulty here.
|
||||
|
|
|
@ -1392,55 +1392,36 @@
|
|||
speaker=Lich-Lord Jevyan
|
||||
message= _ "Rise, rise from the ground!"
|
||||
[/message]
|
||||
[random_placement]
|
||||
variable=wc_loc
|
||||
allow_less=yes
|
||||
num_items={ON_DIFFICULTY 3 6 9}
|
||||
[filter]
|
||||
terrain=S*
|
||||
|
||||
[store_locations]
|
||||
terrain=S*
|
||||
|
||||
[and]
|
||||
x,y=42,40
|
||||
radius=14
|
||||
[/and]
|
||||
|
||||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
|
||||
variable=possible_wc_locs
|
||||
[/store_locations]
|
||||
|
||||
{VARIABLE wc_counter 0}
|
||||
|
||||
[while]
|
||||
[variable]
|
||||
name=possible_wc_locs.length
|
||||
greater_than_equal_to=1
|
||||
[/variable]
|
||||
|
||||
[variable]
|
||||
name=wc_counter
|
||||
less_than={ON_DIFFICULTY 3 6 9}
|
||||
[/variable]
|
||||
|
||||
[do]
|
||||
{RANDOM "0..$($possible_wc_locs.length - 1)"}
|
||||
[and]
|
||||
x,y=42,40
|
||||
radius=14
|
||||
[/and]
|
||||
|
||||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
[/filter]
|
||||
[command]
|
||||
[sound]
|
||||
name={SOUND_LIST:ZOMBIE_HIT}
|
||||
[/sound]
|
||||
|
||||
{LOYAL_UNIT 2 (Walking Corpse) $possible_wc_locs[$random].x $possible_wc_locs[$random].y}
|
||||
{LOYAL_UNIT 2 (Walking Corpse) $wc_loc.x $wc_loc.y}
|
||||
[+unit]
|
||||
animate=yes
|
||||
[/unit]
|
||||
[/command]
|
||||
[/random_placement]
|
||||
|
||||
{CLEAR_VARIABLE possible_wc_locs[$random]}
|
||||
|
||||
{VARIABLE_OP wc_counter add 1}
|
||||
[/do]
|
||||
[/while]
|
||||
|
||||
{CLEAR_VARIABLE possible_wc_locs,wc_counter}
|
||||
{CLEAR_VARIABLE wc_loc}
|
||||
[/event]
|
||||
|
||||
# This event spawns skeletons to shallow water bordering deep water.
|
||||
|
@ -1452,26 +1433,12 @@
|
|||
speaker=Lich-Lord Jevyan
|
||||
message= _ "Come in from the deep my loyal soldiers!"
|
||||
[/message]
|
||||
|
||||
[store_locations]
|
||||
terrain=Ww
|
||||
|
||||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
|
||||
[not]
|
||||
[filter]
|
||||
side=1
|
||||
[/filter]
|
||||
|
||||
radius=1
|
||||
[/not]
|
||||
|
||||
[filter_adjacent_location]
|
||||
terrain=Wo
|
||||
adjacent=nw,sw
|
||||
[random_placement]
|
||||
variable=skele_loc
|
||||
allow_less=yes
|
||||
num_items={ON_DIFFICULTY 3 4 5}
|
||||
[filter]
|
||||
terrain=Ww
|
||||
|
||||
[not]
|
||||
[filter]
|
||||
|
@ -1485,26 +1452,26 @@
|
|||
|
||||
radius=1
|
||||
[/not]
|
||||
[/filter_adjacent_location]
|
||||
|
||||
variable=possible_skele_locs
|
||||
[/store_locations]
|
||||
[filter_adjacent_location]
|
||||
terrain=Wo
|
||||
adjacent=nw,sw
|
||||
|
||||
{VARIABLE skele_counter 0}
|
||||
[while]
|
||||
[variable]
|
||||
name=possible_skele_locs.length
|
||||
greater_than_equal_to=1
|
||||
[/variable]
|
||||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
|
||||
[variable]
|
||||
name=skele_counter
|
||||
less_than={ON_DIFFICULTY 3 4 5}
|
||||
[/variable]
|
||||
|
||||
[do]
|
||||
{RANDOM "0..$($possible_skele_locs.length - 1)"}
|
||||
[not]
|
||||
[filter]
|
||||
side=1
|
||||
[/filter]
|
||||
|
||||
radius=1
|
||||
[/not]
|
||||
[/filter_adjacent_location]
|
||||
[/filter]
|
||||
[command]
|
||||
[store_locations]
|
||||
terrain=Wo
|
||||
|
||||
|
@ -1522,7 +1489,7 @@
|
|||
[/not]
|
||||
|
||||
[filter_adjacent_location]
|
||||
x,y=$possible_skele_locs[$random].x,$possible_skele_locs[$random].y
|
||||
x,y=$skele_loc.x,$skele_loc.y
|
||||
[/filter_adjacent_location]
|
||||
|
||||
variable=skele_from
|
||||
|
@ -1550,8 +1517,8 @@
|
|||
[/switch]
|
||||
|
||||
[scroll_to]
|
||||
x=$possible_skele_locs[$random].x
|
||||
y=$possible_skele_locs[$random].y
|
||||
x=$skele_loc.x
|
||||
y=$skele_loc.y
|
||||
[/scroll_to]
|
||||
|
||||
[sound]
|
||||
|
@ -1565,19 +1532,14 @@
|
|||
[move_unit_fake]
|
||||
side=2
|
||||
type=$skele_type
|
||||
x=$skele_from.x,$possible_skele_locs[$random].x
|
||||
y=$skele_from.y,$possible_skele_locs[$random].y
|
||||
x=$skele_from.x,$skele_loc.x
|
||||
y=$skele_from.y,$skele_loc.y
|
||||
[/move_unit_fake]
|
||||
|
||||
{LOYAL_UNIT 2 $skele_type $possible_skele_locs[$random].x $possible_skele_locs[$random].y}
|
||||
|
||||
{CLEAR_VARIABLE possible_skele_locs[$random]}
|
||||
|
||||
{VARIABLE_OP skele_counter add 1}
|
||||
[/do]
|
||||
[/while]
|
||||
|
||||
{CLEAR_VARIABLE possible_skele_locs,skele_counter,skele_from}
|
||||
{LOYAL_UNIT 2 $skele_type $skele_loc.x $skele_loc.y}
|
||||
[/command]
|
||||
[/random_placement]
|
||||
{CLEAR_VARIABLE skele_loc, skele_from, skele_type}
|
||||
[/event]
|
||||
|
||||
# This triggers on turns 2,9,16,23,... and sets the next corpse spawn turn
|
||||
|
|
|
@ -613,8 +613,7 @@
|
|||
[event]
|
||||
name=create_minion
|
||||
first_time_only=no
|
||||
|
||||
[store_locations]
|
||||
{SCATTER_UNITS 1 (Crawling Horror) 0 (
|
||||
x=6-14
|
||||
y=7-14
|
||||
terrain=Rr,Uu
|
||||
|
@ -622,25 +621,11 @@
|
|||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
|
||||
variable=possible_spawn_locations
|
||||
[/store_locations]
|
||||
|
||||
[if]
|
||||
[variable]
|
||||
name=possible_spawn_locations.length
|
||||
greater_than_equal_to=1
|
||||
[/variable]
|
||||
|
||||
[then]
|
||||
{VARIABLE_OP new_minion_loc_i rand "1..$possible_spawn_locations.length"}
|
||||
{VARIABLE_OP new_minion_loc_i sub 1}
|
||||
|
||||
{UNIT 2 (Crawling Horror) $possible_spawn_locations[$new_minion_loc_i].x $possible_spawn_locations[$new_minion_loc_i].y (upkeep=free)}
|
||||
[/then]
|
||||
[/if]
|
||||
{CLEAR_VARIABLE possible_spawn_locations}
|
||||
[/not]
|
||||
) (
|
||||
side=2
|
||||
upkeep=free
|
||||
)}
|
||||
[/event]
|
||||
|
||||
# Event 1: The Death of Eloh and the revealing of the true monster
|
||||
|
|
|
@ -31,42 +31,21 @@
|
|||
#
|
||||
# This call will scatter 20 copies of a pine-tree graphic over grassland:
|
||||
#! {SCATTER_IMAGE (terrain=Gg) 20 scenery/pine1.png}
|
||||
[store_locations]
|
||||
{FILTER}
|
||||
variable=random_placement_locations
|
||||
[/store_locations]
|
||||
|
||||
{VARIABLE REPEAT_i 0}
|
||||
|
||||
[while]
|
||||
[variable]
|
||||
name=REPEAT_i
|
||||
less_than={NUMBER}
|
||||
[/variable]
|
||||
[variable]
|
||||
name=random_placement_locations.length
|
||||
greater_than=0
|
||||
[/variable]
|
||||
|
||||
[do]
|
||||
[set_variable]
|
||||
name=random_subscript
|
||||
rand="0..$($random_placement_locations.length - 1)"
|
||||
[/set_variable]
|
||||
|
||||
[random_placement]
|
||||
num_items={NUMBER}
|
||||
variable=random_placement_location
|
||||
allow_less=yes
|
||||
[filter]
|
||||
{FILTER}
|
||||
[/filter]
|
||||
[command]
|
||||
[item]
|
||||
image={IMAGE}
|
||||
x,y=$random_placement_locations[$random_subscript].x,$random_placement_locations[$random_subscript].y
|
||||
x,y=$random_placement_location.x,$random_placement_location.y
|
||||
[/item]
|
||||
|
||||
{CLEAR_VARIABLE random_placement_locations[$random_subscript]}
|
||||
{VARIABLE_OP REPEAT_i add 1}
|
||||
[/do]
|
||||
[/while]
|
||||
|
||||
{CLEAR_VARIABLE REPEAT_i}
|
||||
{CLEAR_VARIABLE random_subscript}
|
||||
{CLEAR_VARIABLE random_placement_locations}
|
||||
[/command]
|
||||
[/random_placement]
|
||||
{CLEAR_VARIABLE random_placement_location}
|
||||
#enddef
|
||||
|
||||
#define SCATTER_EMBELLISHMENTS TERRAINLIST EMBELLISHMENT_NAME PERCENTAGE
|
||||
|
@ -75,39 +54,20 @@
|
|||
#
|
||||
# For example, this will add flowers to 5% of all grassland:
|
||||
#! {SCATTER_EMBELLISHMENTS G* ^Efm 5}
|
||||
[store_locations]
|
||||
terrain={TERRAINLIST}
|
||||
variable=terrain_variation_locations
|
||||
[/store_locations]
|
||||
|
||||
{VARIABLE terrain_variations_to_place {PERCENTAGE}}
|
||||
|
||||
# TODO: change back to 100.0 once it no longer causes a crash
|
||||
{VARIABLE_OP terrain_variations_to_place divide 100.0}
|
||||
|
||||
{VARIABLE_OP terrain_variations_to_place multiply $terrain_variation_locations.length}
|
||||
{VARIABLE_OP terrain_variations_to_place round ceil}
|
||||
|
||||
[while]
|
||||
[variable]
|
||||
name=terrain_variations_to_place
|
||||
greater_than=0
|
||||
[/variable]
|
||||
|
||||
[do]
|
||||
{VARIABLE_OP terrain_variation_i rand "0..$($terrain_variation_locations.length - 1)"}
|
||||
|
||||
[random_placement]
|
||||
num_items="size * ({PERCENTAGE} / 100)"
|
||||
variable=random_placement_location
|
||||
allow_less=yes
|
||||
[filter]
|
||||
terrain={TERRAINLIST}
|
||||
[/filter]
|
||||
[command]
|
||||
[terrain]
|
||||
x,y=$terrain_variation_locations[$terrain_variation_i].x,$terrain_variation_locations[$terrain_variation_i].y
|
||||
x,y=$random_placement_location.x,$random_placement_location.y
|
||||
terrain={EMBELLISHMENT_NAME}
|
||||
layer=overlay
|
||||
[/terrain]
|
||||
|
||||
{VARIABLE_OP terrain_variations_to_place sub 1}
|
||||
|
||||
{CLEAR_VARIABLE terrain_variation_locations[$terrain_variation_i]}
|
||||
[/do]
|
||||
[/while]
|
||||
|
||||
{CLEAR_VARIABLE terrain_variation_locations,terrain_variations_to_place,terrain_variation_i}
|
||||
[/command]
|
||||
[/random_placement]
|
||||
{CLEAR_VARIABLE random_placement_location}
|
||||
#enddef
|
||||
|
|
|
@ -462,15 +462,6 @@
|
|||
#! {TRAIT_LOYAL}
|
||||
#! [/modifications]
|
||||
#! )}
|
||||
|
||||
[store_locations]
|
||||
{FILTER}
|
||||
|
||||
# Exclude border hexes
|
||||
include_borders=no
|
||||
variable=possible_unit_locations
|
||||
[/store_locations]
|
||||
|
||||
[set_variables]
|
||||
name=unit_type_table
|
||||
|
||||
|
@ -482,65 +473,27 @@
|
|||
[/set_variables]
|
||||
|
||||
{VARIABLE unit_type_table_i 0}
|
||||
{VARIABLE units_to_place {NUMBER}}
|
||||
|
||||
[while]
|
||||
[variable]
|
||||
name=units_to_place
|
||||
greater_than=0
|
||||
[/variable]
|
||||
|
||||
[do]
|
||||
[set_variable]
|
||||
name=random_subscript
|
||||
rand=1..$possible_unit_locations.length
|
||||
[/set_variable]
|
||||
{VARIABLE_OP random_subscript sub 1}
|
||||
|
||||
[random_placement]
|
||||
num_items={NUMBER}
|
||||
variable=random_placement_location
|
||||
allow_less=yes
|
||||
radius={PADDING_RADIUS}
|
||||
[filter]
|
||||
{FILTER}
|
||||
include_borders=no
|
||||
[/filter]
|
||||
[command]
|
||||
[unit]
|
||||
type=$unit_type_table[$unit_type_table_i].type
|
||||
x,y=$possible_unit_locations[$random_subscript].x,$possible_unit_locations[$random_subscript].y
|
||||
x,y=$random_placement_location.x,$random_placement_location.y
|
||||
{UNIT_WML}
|
||||
[/unit]
|
||||
{VARIABLE unit_type_table_i $(($unit_type_table_i + 1) % $unit_type_table.length)}
|
||||
[/command]
|
||||
[/random_placement]
|
||||
|
||||
[store_locations]
|
||||
find_in=possible_unit_locations
|
||||
[not]
|
||||
x,y=$possible_unit_locations[$random_subscript].x,$possible_unit_locations[$random_subscript].y
|
||||
radius={PADDING_RADIUS}
|
||||
[/not]
|
||||
variable=possible_unit_locations
|
||||
[/store_locations]
|
||||
|
||||
[if]
|
||||
[variable]
|
||||
name=possible_unit_locations.length
|
||||
less_than=1
|
||||
[/variable]
|
||||
|
||||
[then]
|
||||
{VARIABLE units_to_place 0}
|
||||
[/then]
|
||||
[/if]
|
||||
|
||||
{VARIABLE_OP unit_type_table_i add 1}
|
||||
|
||||
[if]
|
||||
[variable]
|
||||
name=unit_type_table_i
|
||||
numerical_equals=$unit_type_table.length
|
||||
[/variable]
|
||||
|
||||
[then]
|
||||
{VARIABLE unit_type_table_i 0}
|
||||
[/then]
|
||||
[/if]
|
||||
|
||||
{VARIABLE_OP units_to_place sub 1}
|
||||
[/do]
|
||||
[/while]
|
||||
|
||||
{CLEAR_VARIABLE unit_type_table,unit_type_table_i,possible_unit_locations,random_subscript,units_to_place}
|
||||
{CLEAR_VARIABLE unit_type_table,unit_type_table_i,random_placement_location}
|
||||
#enddef
|
||||
|
||||
#define FORCE_CHANCE_TO_HIT FILTER SECOND_FILTER CTH_NUMBER EXTRA_CONDITIONS_WML
|
||||
|
|
|
@ -1643,3 +1643,80 @@ function wml_actions.unsynced(cfg)
|
|||
wml_actions.command(cfg)
|
||||
end)
|
||||
end
|
||||
|
||||
wesnoth.wml_actions.random_placement = function(cfg)
|
||||
local dist_le_radius = nil
|
||||
|
||||
local parsed = helper.shallow_parsed(cfg)
|
||||
local filter = helper.get_child(parsed, "filter") or {}
|
||||
local command = helper.get_child(parsed, "command") or helper.wml_error("[random_placement] missing required [command] subtag")
|
||||
local radius = cfg.radius or 0
|
||||
local num_items = cfg.num_items or helper.wml_error("[random_placement] missing required 'num_items' attribute")
|
||||
local variable = cfg.variable or helper.wml_error("[random_placement] missing required 'variable' attribute")
|
||||
local use_delay = cfg.use_delay == true
|
||||
local allow_less = cfg.allow_less == true
|
||||
local variable_previous = utils.start_var_scope(variable)
|
||||
|
||||
if radius < 0 then
|
||||
-- optimisation for radius = -1
|
||||
dist_le_radius = function() return false end
|
||||
elseif radius == 0 then
|
||||
-- optimisation for radius = 0
|
||||
dist_le_radius = function(x1,y1,x2,y2) return x1 == x2 and y1 == y2 end
|
||||
else
|
||||
-- optimisation: cloasure is faster than string lookups.
|
||||
local math_abs = math.abs
|
||||
-- same effect as helper.distance_between(x1,y1,x2,y2) <= radius but faster.
|
||||
dist_le_radius = function(x1,y1,x2,y2)
|
||||
local d_x = math_abs(x1-x2)
|
||||
if d_x > radius then
|
||||
return false
|
||||
end
|
||||
if d_x % 2 ~= 0 then
|
||||
if x1 % 2 == 0 then
|
||||
y2 = y2 - 0.5
|
||||
else
|
||||
y2 = y2 + 0.5
|
||||
end
|
||||
end
|
||||
local d_y = math_abs(y1-y2)
|
||||
return d_x + 2*d_y <= 2*radius
|
||||
end
|
||||
end
|
||||
|
||||
local locs = wesnoth.get_locations(filter)
|
||||
if type(num_items) == "string" then
|
||||
num_items = math.floor(loadstring("local size = " .. #locs .. "; return " .. num_items)())
|
||||
print("num_items=" .. num_items .. ", #locs=" .. #locs)
|
||||
end
|
||||
local size = #locs
|
||||
for i = 1, num_items do
|
||||
if size == 0 then
|
||||
if allow_less then
|
||||
wesnoth.message("placed only " .. i .. " items")
|
||||
return
|
||||
else
|
||||
helper.wml_error("[random_placement] failed to place items. only " .. i .. " items were placed")
|
||||
end
|
||||
end
|
||||
local index = wesnoth.random(size)
|
||||
local point = locs[index]
|
||||
wesnoth.set_variable(variable .. ".x", point[1])
|
||||
wesnoth.set_variable(variable .. ".y", point[2])
|
||||
wesnoth.set_variable(variable .. ".n", i)
|
||||
for j = size, 1, -1 do
|
||||
if dist_le_radius(locs[j][1], locs[j][2], point[1], point[2]) then
|
||||
-- optimisation: swapping elements and storing size in an extra variable is faster than table.remove(locs, j)
|
||||
locs[j] = locs[size]
|
||||
size = size - 1
|
||||
end
|
||||
end
|
||||
wesnoth.wml_actions.command (command)
|
||||
if use_delay and (i % 10 == 0) then
|
||||
--prevent freezing.
|
||||
wesnoth.delay(0);
|
||||
end
|
||||
end
|
||||
utils.end_var_scope(variable, variable_previous)
|
||||
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue