A monoidal_effects monoid for armor
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.1 KiB

armor_monoid = {}
local armor_groups = { fleshy = 100 }
armor_monoid.registered_groups = armor_groups
local join_handled = {}
local function copy_tab(tab)
local copy = {}
for k, v in pairs(tab) do
copy[k] = v
end
return copy
end
-- The values in this monoid are not armor group values, but damage multipliers.
-- For example { fleshy = 0.5, fire = 1.2 } would mean that a player takes
-- half fleshy damage and 120% fire damage. Nil values are the same as putting
-- 1. The final multipliers are multiplied to the base damage for the group.
armor_monoid.monoid = player_monoids.make_monoid({
combine = function(tab1, tab2)
local res = {}
for k, v in pairs(armor_groups) do
local v1 = tab1[k]
local v2 = tab2[k]
if not v1 then
res[k] = v2
elseif not v2 then
res[k] = v1
else
res[k] = v1 * v2
end
end
return res
end,
fold = function(elems)
local res = {}
for k, tab in pairs(elems) do
for k, v in pairs(armor_groups) do
local vres = res[k]
local v_other = tab[k]
if not vres then
res[k] = v_other
elseif v_other then
res[k] = vres * v_other
end
-- If not v_other, res[k] remains the same.
end
end
return res
end,
identity = {},
apply = function(multipliers, player)
local final = copy_tab(armor_groups)
for k, v in pairs(multipliers) do
if final[k] then -- Make sure it is a registered armor group
final[k] = final[k] * v
end
end
join_handled[player:get_player_name()] = true
player:set_armor_groups(final)
end,
})
-- If the monoid has not fired yet (or won't fire)
minetest.register_on_joinplayer(function(player)
if not join_handled[player:get_player_name()] then
player:set_armor_groups(armor_groups)
end
end)
minetest.register_on_leaveplayer(function(player)
join_handled[player:get_player_name()] = nil
end)
-- armor_monoid.register_armor_group("name", x) creates an armor group called name
-- with a default armor value of x.
function armor_monoid.register_armor_group(name, def)
armor_groups[name] = def
end
minetest.log("action", "[armor_monoid] loaded.")