Skip to content

Commit

Permalink
Add helper.find_attack and clean up the [animate_unit] / [kill] hack …
Browse files Browse the repository at this point in the history
…regarding death / victory animations
  • Loading branch information
CelticMinstrel committed May 28, 2017
1 parent 6234d2f commit fbeb6c5
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 24 deletions.
6 changes: 6 additions & 0 deletions data/lua/helper.lua
Expand Up @@ -309,6 +309,12 @@ function helper.shuffle( t, random_func)
end
end

function helper.find_attack(unit, filter)
for i, atk in ipairs(unit.attacks) do
if atk:matches(filter) then return atk end
end
end

-- Compatibility and deprecations

helper.distance_between = wesnoth.map.distance_between
Expand Down
47 changes: 25 additions & 22 deletions data/lua/wml/animate_unit.lua
@@ -1,17 +1,6 @@
local helper = wesnoth.require "helper"
local T = helper.set_wml_tag_metatable{}

local function get_fake_attack(unit, cfg)
-- unit is unused; only needed to get the same signature as get_real_attack
return wesnoth.create_weapon(cfg)
end

local function get_real_attack(unit, filter)
for i, atk in ipairs(unit.attacks) do
if atk:matches(filter) then return atk end
end
end

local function add_animation(anim, cfg)
cfg = helper.shallow_parsed(cfg)
local flag = cfg.flag or helper.wml_error("[animate_unit] is missing flag")
Expand All @@ -32,18 +21,32 @@ local function add_animation(anim, cfg)
if unit and not wesnoth.is_fogged(wesnoth.current.side, unit.x, unit.y) then
local primary = helper.get_child(cfg, "primary_attack")
local secondary = helper.get_child(cfg, "secondary_attack")
local get_attack = get_real_attack
-- We don't have access to the secondary unit at this point.
-- Thus, for the secondary attack, we just create a dummy attack
-- which exactly matches the filter.
-- TODO: Is there a way to fix this? Does it even need fixing?
if cfg.flag == "death" or cfg.flag == "victory" then
-- death and victory animations need a special case
-- In order to correctly fire certain animations, a dummy attack
-- is required. This is especially evident in Wose death animations.
get_attack = get_fake_attack
end
if primary then
primary = get_attack(unit, primary)
end
if secondary then
secondary = get_attack(unit, secondary)
-- death and victory animations have their weapons swapped
-- The primary weapon in a death animation is the weapon that killed the unit.
-- In other words, it's the weapon of the attacker, the secondary unit.
-- The secondary weapon is the weapon of the defender, the primary unit.
-- In a victory animation, these are reversed, so the primary weapon is
-- the weapon of the defender, who is now the secondary unit.
-- Similarly, the secondary weapon in a victory animation is the weapon
-- of the attacker, who is now the primary unit.
if primary then
primary = wesnoth.create_weapon(primary)
end
if secondary then
secondary = helper.find_attack(unit, secondary)
end
else
if primary then
primary = helper.find_attack(unit, primary)
end
if secondary then
secondary = wesnoth.create_weapon(secondary)
end
end

local hits = cfg.hits
Expand Down
22 changes: 20 additions & 2 deletions data/lua/wml/kill.lua
Expand Up @@ -44,8 +44,26 @@ function wesnoth.wml_actions.kill(cfg)
local anim = wesnoth.create_animator()
local primary = helper.get_child(cfg, "primary_attack")
local secondary = helper.get_child(cfg, "secondary_attack")
if primary then primary = wesnoth.create_weapon(primary) end
if secondary then secondary = wesnoth.create_weapon(secondary) end
-- 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_unit 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})
Expand Down

0 comments on commit fbeb6c5

Please sign in to comment.