mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-12-03 16:01:17 +01:00
0b27b6bec3
DO NOT USE IN PRODUCTION, DO NOT START OLD WORLDS WITHOUT A BACKUP These are the first steps of the new mob API. The game does actually start, but mobs do not work yet. You will also get some warnings about mob spawners, but don't worry about that. This is really just some 'first impression' of how the mob API is gonna look like. Some things are already complete, like the agression system. AI and attacking have not been worked on yet. mobs_mc and mcl_mobs have actually been merged into one piece but I will probably change that again in the future actually, and split the different mobs into different mods. There are also a few usefull things like the universal mount API and a more general purpose smoke API, but all of this is still far from complete. I'll put some work into the API this week but probably not next week, then I'll see but don't expect this to be done before 2022. I'll work on it, but I'll do it slowly and progressively to not get burned out again and to still have enough time to graduate from school in the meantime.
169 lines
4.8 KiB
Lua
169 lines
4.8 KiB
Lua
mcl_damage = {
|
|
modifiers = {},
|
|
damage_callbacks = {},
|
|
death_callbacks = {},
|
|
types = {
|
|
in_fire = {is_fire = true},
|
|
lightning_bolt = {is_lightning = true},
|
|
on_fire = {is_fire = true, bypasses_armor = true},
|
|
lava = {is_fire = true},
|
|
hot_floor = {is_fire = true},
|
|
in_wall = {bypasses_armor = true},
|
|
drown = {bypasses_armor = true},
|
|
starve = {bypasses_armor = true, bypasses_magic = true},
|
|
cactus = {},
|
|
fall = {bypasses_armor = true},
|
|
fly_into_wall = {bypasses_armor = true},
|
|
out_of_world = {bypasses_armor = true, bypasses_magic = true, bypasses_invulnerability = true},
|
|
generic = {bypasses_armor = true},
|
|
magic = {is_magic = true, bypasses_armor = true},
|
|
dragon_breath = {is_magic = true, bypasses_armor = true}, -- this is only used for dragon fireball; dragon fireball does not actually deal impact damage tho, so this is unreachable
|
|
wither = {bypasses_armor = true}, -- unused
|
|
wither_skull = {is_magic = true, is_explosion = true}, -- this is non-MC but a workaround to get the proper death message
|
|
anvil = {},
|
|
falling_node = {}, -- this is falling_block in MC
|
|
mob = {},
|
|
player = {},
|
|
arrow = {is_projectile = true},
|
|
fireball = {is_projectile = true, is_fire = true},
|
|
thorns = {is_magic = true},
|
|
explosion = {is_explosion = true},
|
|
cramming = {bypasses_armor = true},
|
|
fireworks = {is_explosion = true}, -- unused
|
|
}
|
|
}
|
|
|
|
function mcl_damage.register_modifier(func, priority)
|
|
table.insert(mcl_damage.modifiers, {func = func, priority = priority or 0})
|
|
end
|
|
|
|
function mcl_damage.register_on_damage(func)
|
|
table.insert(mcl_damage.damage_callbacks, func)
|
|
end
|
|
|
|
function mcl_damage.register_on_death(func)
|
|
table.insert(mcl_damage.death_callbacks, func)
|
|
end
|
|
|
|
function mcl_damage.run_modifiers(obj, damage, reason)
|
|
for _, modf in ipairs(mcl_damage.modifiers) do
|
|
damage = modf.func(obj, damage, reason) or damage
|
|
if damage == 0 then
|
|
return 0
|
|
end
|
|
end
|
|
|
|
return damage
|
|
end
|
|
|
|
local function run_callbacks(funcs, ...)
|
|
for _, func in pairs(funcs) do
|
|
func(...)
|
|
end
|
|
end
|
|
|
|
function mcl_damage.run_damage_callbacks(obj, damage, reason)
|
|
run_callbacks(mcl_damage.damage_callbacks, obj, damage, reason)
|
|
end
|
|
|
|
function mcl_damage.run_death_callbacks(obj, reason)
|
|
run_callbacks(mcl_damage.death_callbacks, obj, reason)
|
|
end
|
|
|
|
function mcl_damage.from_punch(mcl_reason, object)
|
|
mcl_reason.direct = object
|
|
local luaentity = mcl_reason.direct:get_luaentity()
|
|
if luaentity then
|
|
if luaentity.is_arrow then
|
|
mcl_reason.type = "arrow"
|
|
elseif luaentity.is_fireball then
|
|
mcl_reason.type = "fireball"
|
|
elseif luaentity.is_mob then
|
|
mcl_reason.type = "mob"
|
|
end
|
|
mcl_reason.source = mcl_reason.source or luaentity._source_object
|
|
else
|
|
mcl_reason.type = "player"
|
|
end
|
|
end
|
|
|
|
function mcl_damage.finish_reason(mcl_reason)
|
|
mcl_reason.source = mcl_reason.source or mcl_reason.direct
|
|
mcl_reason.flags = mcl_damage.types[mcl_reason.type]
|
|
end
|
|
|
|
function mcl_damage.from_mt(mt_reason)
|
|
if mt_reason._mcl_chached_reason then
|
|
return mt_reason._mcl_chached_reason
|
|
end
|
|
|
|
local mcl_reason
|
|
|
|
if mt_reason._mcl_reason then
|
|
mcl_reason = mt_reason._mcl_reason
|
|
else
|
|
mcl_reason = {type = "generic"}
|
|
|
|
if mt_reason._mcl_type then
|
|
mcl_reason.type = mt_reason._mcl_type
|
|
elseif mt_reason.type == "fall" then
|
|
mcl_reason.type = "fall"
|
|
elseif mt_reason.type == "drown" then
|
|
mcl_reason.type = "drown"
|
|
elseif mt_reason.type == "punch" then
|
|
mcl_damage.from_punch(mcl_reason, mt_reason.object)
|
|
elseif mt_reason.type == "node_damage" and mt_reason.node then
|
|
if minetest.get_item_group(mt_reason.node, "fire") > 0 then
|
|
mcl_reason.type = "in_fire"
|
|
end
|
|
if minetest.get_item_group(mt_reason.node, "lava") > 0 then
|
|
mcl_reason.type = "lava"
|
|
end
|
|
end
|
|
|
|
for key, value in pairs(mt_reason) do
|
|
if key:find("_mcl_") == 1 then
|
|
mcl_reason[key:sub(6, #key)] = value
|
|
end
|
|
end
|
|
end
|
|
|
|
mcl_damage.finish_reason(mcl_reason)
|
|
mt_reason._mcl_cached_reason = mcl_reason
|
|
|
|
return mcl_reason
|
|
end
|
|
|
|
function mcl_damage.register_type(name, def)
|
|
mcl_damage.types[name] = def
|
|
end
|
|
|
|
minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
|
|
if hp_change < 0 then
|
|
if player:get_hp() <= 0 then
|
|
return 0
|
|
end
|
|
hp_change = -mcl_damage.run_modifiers(player, -hp_change, mcl_damage.from_mt(mt_reason))
|
|
end
|
|
return hp_change
|
|
end, true)
|
|
|
|
minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
|
|
if player:get_hp() > 0 then
|
|
mt_reason.approved = true
|
|
if hp_change < 0 then
|
|
mcl_damage.run_damage_callbacks(player, -hp_change, mcl_damage.from_mt(mt_reason))
|
|
end
|
|
end
|
|
end, false)
|
|
|
|
minetest.register_on_dieplayer(function(player, mt_reason)
|
|
if mt_reason.approved then
|
|
mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason))
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_mods_loaded(function()
|
|
table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end)
|
|
end)
|
|
|