-
-
Notifications
You must be signed in to change notification settings - Fork 988
/
kill.lua
105 lines (97 loc) · 3.7 KB
/
kill.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
local helper = wesnoth.require "helper"
local location_set = wesnoth.require "location_set"
local kill_recursion_preventer = location_set.create()
function wesnoth.wml_actions.kill(cfg)
local number_killed = 0
local secondary_unit = wml.get_child(cfg, "secondary_unit")
local killer_loc = {0, 0}
if secondary_unit then
secondary_unit = wesnoth.get_units(secondary_unit)[1]
if cfg.fire_event then
if secondary_unit then
killer_loc = { x = tonumber(secondary_unit.x) or 0, y = tonumber(secondary_unit.y) or 0 }
else
wesnoth.log("warn", "failed to match [secondary_unit] in [kill] with a single on-board unit")
end
end
end
local dead_men_walking = wesnoth.get_units(cfg)
for i,unit in ipairs(dead_men_walking) do
local death_loc = {x = tonumber(unit.x) or 0, y = tonumber(unit.y) or 0}
if not secondary_unit then killer_loc = death_loc end
local can_fire = false
local recursion = (kill_recursion_preventer:get(death_loc.x, death_loc.y) or 0) + 1
if cfg.fire_event then
kill_recursion_preventer:insert(death_loc.x, death_loc.y, recursion)
can_fire = true
if death_loc.x == wesnoth.current.event_context.x1 and death_loc.y == wesnoth.current.event_context.y1 then
if wesnoth.current.event_context.name == "die" or wesnoth.current.event_context.name == "last breath" then
if recursion >= 10 then
can_fire = false;
wesnoth.log("error", "tried to fire 'die' or 'last breath' event "
.. "on unit from the unit's 'die' or 'last breath' event "
.. "with first_time_only=no!")
end
end
end
end
if can_fire then
wesnoth.fire_event("last breath", death_loc, killer_loc)
end
if cfg.animate and unit.valid == "map" then
wesnoth.scroll_to_tile(death_loc, true)
local anim = wesnoth.create_animator()
local primary = wml.get_child(cfg, "primary_attack")
local secondary = wml.get_child(cfg, "secondary_attack")
-- Yes, we get the primary attack from the secondary unit and vice versa
-- The primary attack in a death animation is the weapon that caused the death
-- In other words, the attacker's weapon. The attacker is the secondary unit.
-- In the victory animation, this is simply swapped.
if primary then
if secondary_unit then
primary = helper.find_attack(secondary_unit, primary)
else
primary = wesnoth.create_weapon(primary)
end
wesnoth.log('err', "Primary weapon:\n" .. wml.tostring(primary.__cfg))
end
if secondary then
if primary then
secondary = helper.find_attack(unit, secondary)
else
secondary = wesnoth.create_weapon(secondary)
end
wesnoth.log('err', "Secondary weapon:\n" .. wml.tostring(secondary.__cfg))
end
anim:add(unit, "death", "kill", {primary = primary, secondary = secondary})
if secondary_unit then
anim:add(secondary_unit, "victory", "kill", {primary = secondary, secondary = primary})
end
anim:run()
anim:clear()
end
-- wesnoth.wml_actions.redraw{}
if can_fire then
wesnoth.fire_event("die", death_loc, killer_loc)
end
if cfg.fire_event then
if recursion <= 1 then
kill_recursion_preventer:remove(death_loc.x, death_loc.y)
else
kill_recursion_preventer:insert(death_loc.x, death_loc.y, recursion)
end
end
-- Test that it's valid (and still on the map) first, in case the event erased (or extracted) it.
if unit.valid == "map" then unit:erase() end
-- wesnoth.wml_actions.redraw{}
number_killed = number_killed + 1
end
if (cfg.x == "recall" or cfg.x == nil) and (cfg.y == "recall" or cfg.y == nil) then
local dead_men_sleeping = wesnoth.get_recall_units(cfg)
for i,unit in ipairs(dead_men_sleeping) do
unit:erase()
end
number_killed = number_killed + #dead_men_sleeping
end
return number_killed
end