-
-
Notifications
You must be signed in to change notification settings - Fork 988
/
move_unit.lua
88 lines (81 loc) · 2.87 KB
/
move_unit.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
local helper = wesnoth.require "helper"
local utils = wesnoth.require "wml-utils"
local function path_locs(path)
if path.location_id then
-- Index is 1 for x, 2 for y
local function special_locations(index)
return function()
for loc in utils.split(path.location_id) do
loc = wesnoth.special_locations[loc]
if loc then coroutine.yield(loc[index]) end
end
end
end
return coroutine.wrap(special_locations(1)), coroutine.wrap(special_locations(2))
else
return utils.split(path.to_x), utils.split(path.to_y)
end
end
function wesnoth.wml_actions.move_unit(cfg)
local coordinate_error = "invalid location in [move_unit]"
local path
if cfg.to_location then
path = {location_id = cfg.to_location}
else
path = {to_x = cfg.to_x, to_y = cfg.to_y}
end
if not path then
helper.wml_error(coordinate_error)
end
local fire_event = cfg.fire_event
local muf_force_scroll = cfg.force_scroll
local check_passability = cfg.check_passability
if check_passability == nil then check_passability = true end
cfg = wml.literal(cfg)
cfg.to_location, cfg.to_x, cfg.to_y, cfg.fire_event = nil
local units = wesnoth.get_units(cfg)
for current_unit_index, current_unit in ipairs(units) do
if not fire_event or current_unit.valid then
local xs, ys = path_locs(path)
local move_string_x = current_unit.x
local move_string_y = current_unit.y
local pass_check = nil
if check_passability then pass_check = current_unit end
local x, y = xs(), ys()
local prevX, prevY = tonumber(current_unit.x), tonumber(current_unit.y)
while true do
x = tonumber(x) or helper.wml_error(coordinate_error)
y = tonumber(y) or helper.wml_error(coordinate_error)
if not (x == prevX and y == prevY) then x, y = wesnoth.find_vacant_tile(x, y, pass_check) end
if not x or not y then helper.wml_error("Could not find a suitable hex near to one of the target hexes in [move_unit].") end
move_string_x = string.format("%s,%u", move_string_x, x)
move_string_y = string.format("%s,%u", move_string_y, y)
local next_x, next_y = xs(), ys()
if not next_x and not next_y then break end
prevX, prevY = x, y
x, y = next_x, next_y
end
if current_unit.x < x then current_unit.facing = "se"
elseif current_unit.x > x then current_unit.facing = "sw"
end
wesnoth.extract_unit(current_unit)
local current_unit_cfg = current_unit.__cfg
wesnoth.wml_actions.move_unit_fake {
type = current_unit_cfg.type,
gender = current_unit_cfg.gender,
variation = current_unit_cfg.variation,
image_mods = current_unit.image_mods,
side = current_unit_cfg.side,
x = move_string_x,
y = move_string_y,
force_scroll = muf_force_scroll
}
local x2, y2 = current_unit.x, current_unit.y
current_unit.x, current_unit.y = x, y
wesnoth.put_unit(current_unit)
if fire_event then
wesnoth.fire_event("moveto", x, y, x2, y2)
end
end
end
end