[Lua] Update obsolete use of [1],[2] to refer to locations, and simplify some code by leveraging the fact that any object with x,y qualifies as a location; also use moves_left for reachmaps instead of [3]

This commit is contained in:
Celtic Minstrel 2024-02-04 14:37:57 -05:00 committed by Celtic Minstrel
parent f5c4f2e841
commit 058d0502e5
8 changed files with 58 additions and 56 deletions

View file

@ -1379,9 +1379,9 @@ function ai_helper.get_dst_src_units(units, cfg)
end
for _,loc in ipairs(reach) do
local tmp_dst = dstsrc:get(loc[1], loc[2]) or {}
local tmp_dst = dstsrc:get(loc) or {}
table.insert(tmp_dst, { x = unit.x, y = unit.y })
dstsrc:insert(loc[1], loc[2], tmp_dst)
dstsrc:insert(loc, tmp_dst)
end
end
@ -1499,20 +1499,20 @@ function ai_helper.next_hop(unit, x, y, cfg)
end
-- If none of the hexes are unoccupied, use current position as default
local next_hop, nh_cost = { unit.x, unit.y }, 0
local next_hop_ideal = { unit.x, unit.y }
local next_hop, nh_cost = unit.loc, 0
local next_hop_ideal = unit.loc
-- Go through loop to find reachable, unoccupied hex along the path
-- Start at second index, as first is just the unit position itself
for i = 2,#path do
if (not cfg) or (not cfg.avoid_map) or (not cfg.avoid_map:get(path[i][1], path[i][2])) then
local sub_path, sub_cost = ai_helper.find_path_with_shroud(unit, path[i][1], path[i][2], cfg)
if (not cfg) or (not cfg.avoid_map) or (not cfg.avoid_map:get(path[i])) then
local sub_path, sub_cost = ai_helper.find_path_with_shroud(unit, path[i].x, path[i].y, cfg)
if sub_cost <= unit.moves then
-- Check for unit in way only if cfg.ignore_units is not set
local unit_in_way
if (not cfg) or (not cfg.ignore_units) then
unit_in_way = wesnoth.units.get(path[i][1], path[i][2])
unit_in_way = wesnoth.units.get(path[i])
if unit_in_way and (not ignore_visibility) and (not ai_helper.is_visible_unit(viewing_side, unit_in_way)) then
unit_in_way = nil
end
@ -1538,18 +1538,18 @@ function ai_helper.next_hop(unit, x, y, cfg)
local fan_out = cfg and cfg.fan_out
if (fan_out == nil) then fan_out = true end
if fan_out and ((next_hop[1] ~= next_hop_ideal[1]) or (next_hop[2] ~= next_hop_ideal[2]))
if fan_out and ((next_hop.x ~= next_hop_ideal.x) or (next_hop.y ~= next_hop_ideal.y))
then
-- If we cannot get to the ideal next hop, try fanning out instead
local reach = wesnoth.paths.find_reach(unit, cfg)
-- Need the reach map of the unit from the ideal next hop hex
-- There will always be another unit there, otherwise we would not have gotten here
local unit_in_way = wesnoth.units.get(next_hop_ideal[1], next_hop_ideal[2])
local unit_in_way = wesnoth.units.get(next_hop_ideal)
unit_in_way:extract()
local old_x, old_y = unit.x, unit.y
unit:extract()
unit:to_map(next_hop_ideal[1], next_hop_ideal[2])
unit:to_map(next_hop_ideal)
local inverse_reach = wesnoth.paths.find_reach(unit, { ignore_units = true }) -- no ZoC
unit:extract()
unit:to_map(old_x, old_y)
@ -1562,8 +1562,8 @@ function ai_helper.next_hop(unit, x, y, cfg)
-- We want the moves left for moving into the opposite direction in which the reach map was calculated
local terrain2 = wesnoth.current.map[r]
local move_cost = unit:movement_on(terrain2)
local inverse_cost = r[3] + move_cost - move_cost_endpoint
inverse_reach_map:insert(r[1], r[2], inverse_cost)
local inverse_cost = r.moves_left + move_cost - move_cost_endpoint
inverse_reach_map:insert(r, inverse_cost)
end
local units
@ -1577,15 +1577,15 @@ function ai_helper.next_hop(unit, x, y, cfg)
-- Do not move farther away, but if next_hop is out of reach from next_hop_ideal,
-- anything in reach is better -> set to -infinity in that case.
local max_rating = inverse_reach_map:get(next_hop[1], next_hop[2]) or - math.huge
local max_rating = inverse_reach_map:get(next_hop) or - math.huge
for _,loc in ipairs(reach) do
if (not unit_map:get(loc[1], loc[2]))
and ((not cfg) or (not cfg.avoid_map) or (not cfg.avoid_map:get(loc[1], loc[2])))
if (not unit_map:get(loc))
and ((not cfg) or (not cfg.avoid_map) or (not cfg.avoid_map:get(loc)))
then
local rating = inverse_reach_map:get(loc[1], loc[2]) or - math.huge
local rating = inverse_reach_map:get(loc) or - math.huge
if (rating > max_rating) then
max_rating = rating
next_hop = { loc[1], loc[2] } -- eliminating the third argument
next_hop.x, next_hop.y = loc.x, loc.y -- eliminating the third argument
end
end
end
@ -1677,11 +1677,11 @@ function ai_helper.get_reachmap(unit, cfg)
local initial_reach = wesnoth.paths.find_reach(unit, cfg)
for _,loc in ipairs(initial_reach) do
local is_available = true
if cfg and cfg.avoid_map and cfg.avoid_map:get(loc[1], loc[2]) then
if cfg and cfg.avoid_map and cfg.avoid_map:get(loc) then
is_available = false
else
---@type unit?
local unit_in_way = wesnoth.units.get(loc[1], loc[2])
local unit_in_way = wesnoth.units.get(loc)
if unit_in_way and (unit_in_way.id == unit.id) then
unit_in_way = nil
end
@ -1699,7 +1699,7 @@ function ai_helper.get_reachmap(unit, cfg)
end
if is_available then
reachmap:insert(loc[1], loc[2], loc[3])
reachmap:insert(loc, loc.moves_left)
end
end
@ -2037,25 +2037,27 @@ function ai_helper.move_unit_out_of_way(ai, unit, cfg)
local reach = wesnoth.paths.find_reach(unit, cfg)
local reach_map = LS.create()
local max_rating, best_hex = - math.huge, nil
local max_rating = - math.huge
---@type location?
local best_hex = nil
for _,loc in ipairs(reach) do
local unit_in_way = wesnoth.units.get(loc[1], loc[2])
local unit_in_way = wesnoth.units.get(loc)
if (not unit_in_way) -- also excludes current hex
or ((not ignore_visibility) and (not ai_helper.is_visible_unit(viewing_side, unit_in_way)))
then
local avoid_this_hex = cfg and cfg.avoid_map and cfg.avoid_map:get(loc[1], loc[2])
local avoid_this_hex = cfg and cfg.avoid_map and cfg.avoid_map:get(loc)
if (not avoid_this_hex) then
local rating = loc[3] -- also disfavors hexes next to visible enemy units for which loc[3] = 0
local rating = loc.moves_left -- also disfavors hexes next to visible enemy units for which loc[3] = 0
if dx then
rating = rating + (loc[1] - unit.x) * dx * 0.01
rating = rating + (loc[2] - unit.y) * dy * 0.01
rating = rating + (loc.x - unit.x) * dx * 0.01
rating = rating + (loc.y - unit.y) * dy * 0.01
end
if cfg.labels then reach_map:insert(loc[1], loc[2], rating) end
if cfg.labels then reach_map:insert(loc, rating) end
if (rating > max_rating) then
max_rating, best_hex = rating, { loc[1], loc[2] }
max_rating, best_hex = rating, loc
end
end
end
@ -2063,7 +2065,7 @@ function ai_helper.move_unit_out_of_way(ai, unit, cfg)
if cfg.labels then ai_helper.put_labels(reach_map) end
if best_hex then
ai_helper.checked_move(ai, unit, best_hex[1], best_hex[2])
ai_helper.checked_move(ai, unit, best_hex.x, best_hex.y)
end
end
@ -2218,28 +2220,28 @@ function ai_helper.get_attacks(units, cfg)
for _,unit in ipairs(units) do
wesnoth.interface.handle_user_interact()
local reach
if reaches:get(unit.x, unit.y) then
reach = reaches:get(unit.x, unit.y)
if reaches:get(unit) then
reach = reaches:get(unit)
else
reach = wesnoth.paths.find_reach(unit, cfg)
reaches:insert(unit.x, unit.y, reach)
reaches:insert(unit, reach)
end
for _,loc in ipairs(reach) do
if attack_hex_map:get(loc[1], loc[2]) then
if attack_hex_map:get(loc) then
local add_target = true
local attack_hex_occupied = false
-- If another unit of same side is on this hex:
if my_unit_map:get(loc[1], loc[2]) and ((loc[1] ~= unit.x) or (loc[2] ~= unit.y)) then
if my_unit_map:get(loc) and ((loc.x ~= unit.x) or (loc.y ~= unit.y)) then
attack_hex_occupied = true
add_target = false
if cfg.include_occupied then -- Test whether it can move out of the way
local unit_in_way = all_units[my_unit_map:get(loc[1], loc[2])]
local unit_in_way = all_units[my_unit_map:get(loc)]
local uiw_reach
if reaches:get(unit_in_way.x, unit_in_way.y) then
uiw_reach = reaches:get(unit_in_way.x, unit_in_way.y)
if reaches:get(unit_in_way) then
uiw_reach = reaches:get(unit_in_way)
else
uiw_reach = wesnoth.paths.find_reach(unit_in_way, cfg)
reaches:insert(unit_in_way.x, unit_in_way.y, uiw_reach)
@ -2250,7 +2252,7 @@ function ai_helper.get_attacks(units, cfg)
-- unit that is moving out of the way of the initial unit (etc.).
for _,uiw_loc in ipairs(uiw_reach) do
-- Unit in the way of the unit in the way
local uiw_uiw = wesnoth.units.get(uiw_loc[1], uiw_loc[2])
local uiw_uiw = wesnoth.units.get(uiw_loc)
if (not uiw_uiw)
or ((not ignore_visibility) and (not ai_helper.is_visible_unit(side, uiw_uiw)))
then
@ -2262,11 +2264,11 @@ function ai_helper.get_attacks(units, cfg)
end
if add_target then
for _,target in ipairs(attack_hex_map:get(loc[1], loc[2])) do
for _,target in ipairs(attack_hex_map:get(loc)) do
local att_stats, def_stats
if cfg.simulate_combat then
local unit_dst = unit:clone()
unit_dst.x, unit_dst.y = loc[1], loc[2]
unit_dst.x, unit_dst.y = loc.x, loc.y
local enemy = all_units[target.i]
att_stats, def_stats = wesnoth.simulate_combat(unit_dst, enemy)
@ -2274,7 +2276,7 @@ function ai_helper.get_attacks(units, cfg)
table.insert(attacks, {
src = { x = unit.x, y = unit.y },
dst = { x = loc[1], y = loc[2] },
dst = { x = loc.x, y = loc.y },
target = { x = target.x, y = target.y },
att_stats = att_stats,
def_stats = def_stats,

View file

@ -53,9 +53,9 @@ function ca_forest_animals_new_rabbit:execution(cfg)
for i = 1,number do
local x, y = -1, -1
if tmp_unit then
x, y = wesnoth.paths.find_vacant_hex(holes[i].x, holes[i].y, tmp_unit)
x, y = wesnoth.paths.find_vacant_hex(holes[i], tmp_unit)
else
x, y = wesnoth.paths.find_vacant_hex(holes[i].x, holes[i].y)
x, y = wesnoth.paths.find_vacant_hex(holes[i])
end
wesnoth.sync.invoke_command("rabbit_spawn", { rabbit_type = cfg.rabbit_type, x = x, y = y})

View file

@ -97,7 +97,7 @@ function ca_herding_attack_close_enemy:execution(cfg)
local min_dist, closest_sheep, closest_enemy = math.huge, nil, nil
for _,enemy in ipairs(enemies2) do
for _,single_sheep in ipairs(sheep) do
local dist = M.distance_between(enemy.x, enemy.y, single_sheep.x, single_sheep.y)
local dist = M.distance_between(enemy, single_sheep)
if dist < min_dist then
min_dist = dist
closest_sheep, closest_enemy = single_sheep, enemy
@ -112,14 +112,14 @@ function ca_herding_attack_close_enemy:execution(cfg)
reach_map:iter( function(x, y, v)
-- We want equal distance between enemy and closest sheep
local rating = - math.abs(
M.distance_between(x, y, closest_sheep.x, closest_sheep.y)
- M.distance_between(x, y, closest_enemy.x, closest_enemy.y)
M.distance_between(x, y, closest_sheep)
- M.distance_between(x, y, closest_enemy)
) * 100
-- 2nd: closeness to sheep
rating = rating - M.distance_between(x, y, closest_sheep.x, closest_sheep.y)
rating = rating - M.distance_between(x, y, closest_sheep)
reach_map:insert(x, y, rating)
-- 3rd: most distant dog goes first
rating = rating + M.distance_between(closest_enemy.x, closest_enemy.y, dog.x, dog.y) / 100.
rating = rating + M.distance_between(closest_enemy, dog) / 100.
reach_map:insert(x, y, rating)
if (rating > max_rating2) then

View file

@ -15,7 +15,7 @@ function ca_recruit_random:evaluation(cfg)
end
-- Find all connected castle hexes
local castle_map = LS.of_pairs({ { leader.x, leader.y } })
local castle_map = LS.of_pairs({ leader })
local new_castle_hex_found = true
while new_castle_hex_found do

View file

@ -111,8 +111,8 @@ function wct_castle_expansion_side(side_num)
if keep_loc == nil then
return
end
local castle = map:find_in_radius({keep_loc}, 1, wesnoth.map.filter(f.terrain("C*,K*")))
local keep_area = map:find_in_radius({keep_loc}, 2, wesnoth.map.filter(f.all()))
local castle = map:find_in_radius(keep_loc, 1, wesnoth.map.filter(f.terrain("C*,K*")))
local keep_area = map:find_in_radius(keep_loc, 2, wesnoth.map.filter(f.all()))
local candidates = get_locations {
filter = f.all(

View file

@ -4,7 +4,7 @@ function world_conquest_tek_map_noise_proxy(radius, fraction, terrain)
mathx.shuffle(terrain_to_change)
for terrain_i = 1, math.ceil(#terrain_to_change / fraction) do
local loc_a = terrain_to_change[terrain_i]
local terrain_to_swap_b = map:find_in_radius({loc_a}, radius, nop_filter)
local terrain_to_swap_b = map:find_in_radius(loc_a, radius, nop_filter)
terrain_to_swap_b = map:find(f.all(
f.none(f.is_loc(loc_a)),

View file

@ -989,8 +989,8 @@ function wml_actions.terrain_mask(cfg)
-- tile to the northwest from the specified hex.
-- todo: deprecate this strange behaviour or at least not make it
-- the default behaviour anymore.
local new_loc = wesnoth.map.get_direction({x, y}, "nw")
x, y = new_loc[1], new_loc[2]
local new_loc = wesnoth.map.get_direction(x, y, "nw")
x, y = new_loc.x, new_loc.y
end
local rules = {}
for rule in wml.child_range(cfg, 'rule') do
@ -1001,7 +1001,7 @@ function wml_actions.terrain_mask(cfg)
resolved = resolved:sub(6) -- strip off 'data/' prefix
mask = filesystem.read_file(resolved)
end
wesnoth.current.map:terrain_mask({x, y}, mask, {
wesnoth.current.map:terrain_mask(x, y, mask, {
is_odd = is_odd,
rules = rules,
ignore_special_locations = cfg.ignore_special_locations,

View file

@ -5,7 +5,7 @@ local function path_locs(path)
return function()
for _,loc in ipairs(tostring(path.location_id):split()) do
loc = wesnoth.current.map.special_locations[loc]
if loc then coroutine.yield(loc[1], loc[2]) end
if loc then coroutine.yield(loc.x, loc.y) end
end
end
end