Skip to content

Commit

Permalink
Damage System: detect damage.Type of Playey|Entity hand. Closes #1634
Browse files Browse the repository at this point in the history
  • Loading branch information
alek13 committed Sep 9, 2024
1 parent b00191b commit 8e38942
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 41 deletions.
52 changes: 11 additions & 41 deletions mods/lord/Core/damage/src/damage/Type.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
local assert, table_contains, pairs, typeof
= assert, table.contains, pairs, type
local assert, table_contains, typeof
= assert, table.contains, type

local TypeEvent = require('damage.Type.Event')
local TypeEvent = require('damage.Type.Event')
local TypeResolver = require('damage.Type.Resolver')


--- @static
Expand All @@ -19,6 +20,8 @@ local Type = {
}
}

TypeResolver.init(Type.registered)

--- @param name string
--- @return damage.Type
function Type.register(name)
Expand Down Expand Up @@ -47,61 +50,28 @@ end
--- @param damage_groups table<string,number>
--- @return string|nil
function Type.get_from_groups(damage_groups)
for type, damage in pairs(damage_groups) do
if table_contains(Type.registered, type) then
return type
end
end

return nil
return TypeResolver.by_damage_groups(damage_groups)
end

--- @param definition ItemDefinition
--- @return string|nil
function Type.get_by_definition(definition)
local damage_groups = definition.damage_groups or (
definition.tool_capabilities
and (definition.tool_capabilities.damage_groups or {})
or {}
)

return Type.get_from_groups(damage_groups)
return TypeResolver.by_definition(definition)
end

--- @param reason PlayerHPChangeReason
--- @return string
function Type.detect(reason)
local type = Type.get_default()
assert(typeof(type) == 'string')

if reason.type == 'node_damage' and reason.node then

return Type.get_by_definition(minetest.registered_nodes[reason.node]) or type
local default_type = Type.get_default()
assert(typeof(default_type) == 'string')

elseif reason.type == 'punch' and reason.object then

--- @type Player|Entity
local player_or_mob = reason.object
local item_definition = player_or_mob:get_wielded_item():get_definition()

return Type.get_by_definition(item_definition) or type

end

return type
return TypeResolver.by_reason(reason) or default_type
end

--- @return string[]
function Type.get_registered()
return Type.registered
end

setmetatable(Type, {
--- @return fun(registered:string[]): (number, string)
__pairs = function()
return pairs(Type.registered)
end
})


return Type
75 changes: 75 additions & 0 deletions mods/lord/Core/damage/src/damage/Type/Resolver.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
local table_contains, pairs
= table.contains, pairs


--- @static
--- @class damage.Type.Resolver
local Resolver = {
--- @private
--- @static
--- @type string[]
damage_types = nil
}

--- @param registered_damage_types string[]
--- @return damage.Type.Resolver
function Resolver.init(registered_damage_types)
Resolver.damage_types = registered_damage_types

return Resolver
end

--- @param damage_groups table<string,number>
--- @return string|nil
function Resolver.by_damage_groups(damage_groups)
for type, damage in pairs(damage_groups) do
if table_contains(Resolver.damage_types, type) then
return type
end
end

return nil
end

--- @param definition ItemDefinition
--- @return string|nil
function Resolver.by_definition(definition)
local damage_groups = definition.damage_groups or (
definition.tool_capabilities
and (definition.tool_capabilities.damage_groups or {})
or {}
)

return Resolver.by_damage_groups(damage_groups)
end

--- @param reason PlayerHPChangeReason
--- @return string|nil
function Resolver.by_reason(reason)

if reason.type == 'node_damage' and reason.node then

return Resolver.by_definition(minetest.registered_nodes[reason.node])

elseif reason.type == 'punch' and reason.object then

--- @type Player|Entity
local player_or_mob = reason.object
local item = player_or_mob:get_wielded_item()

if player_or_mob:is_player() then -- `damage.Type` of:
return Resolver.by_definition(item:get_definition()) -- Player wielded item
or Resolver.by_definition(minetest.registered_nodes[""]) -- Player hand
else
return item:get_name() ~= "" -- `damage.Type` of:
and Resolver.by_definition(item:get_definition()) -- Entity wielded item
or player_or_mob:get_luaentity().damage_type -- Entity hand
end

end

return nil
end


return Resolver

0 comments on commit 8e38942

Please sign in to comment.