mt_api_addons/init.lua
2021-05-16 05:10:25 +00:00

116 lines
4.2 KiB
Lua

--mt_api_addons
--License: MIT License
--Event registration lists
minetest.registered_on_entity_remove_events = {}
minetest.registered_on_clear_objects_events = {}
--Hooks a function onto a function
local function hook(func, func2)
if type(func) == "function" then
return function(...)
func2(...)
return func(...)
end
end
return nil
end
--Handler needed for entity remove events
local function do_handler(category, ...)
local events = minetest["registered_"..category.."_events"]
if events then
for count,func in pairs(events) do
func(...)
end
end
end
--Safely injects a hook to builtin function clear_objects
core.clear_objects = hook(core.clear_objects, function(option)
do_handler("on_clear_objects", option)
end)
--Inject hooks to entities once all mods have been loaded
minetest.register_on_mods_loaded(function(player)
for name,def in pairs(minetest.registered_entities) do
minetest.registered_entities[name].get_staticdata = hook(def.get_staticdata, function(self)
if not self.hook_injected then
local meta = getmetatable(self.object)
meta.remove = hook(meta.remove, function(self)
--get entity properties
self = self:get_luaentity()
if not(self.removed or self.removed == true) then
self.removed = true
do_handler("on_entity_remove", self)
end
end)
--Update objectref's Metatable
setmetatable(meta, meta)
end
end)
end
minetest.log("action", "Entity remove hook injected successfully.")
end)
--Backwards compatability substitute for on_rightclickplayer (for those who are using outdated clients)
if not minetest.register_on_rightclickplayer then
local update_interval = minetest.settings:get("player_rightclick_step") or 0.1
minetest.registered_on_rightclickplayer_events = {}
--Check if the player right-clicked a player
local function verify_clicked_player(clicker, range)
local result = nil
local ray_start = vector.add(clicker:get_pos(), {x=0, y= clicker:get_properties().eye_height, z=0})
local ray_modif = vector.add(vector.multiply(clicker:get_look_dir(), range), clicker:get_eye_offset())
local ray_end = vector.add(ray_start, ray_modif)
local ray = minetest.raycast(ray_start, ray_end, true, false)
local clicked = ray:next()
clicked = ray:next()
if clicked and clicked.type == "object" and clicked.ref:is_player() and clicked.ref ~= clicker then
result = clicked.ref
end
return result
end
--Handle rightclicking for older minetest versions
local function handle_on_rightclickplayer()
local events = minetest.registered_on_rightclickplayer_events
if events then
for _,clicker in pairs(minetest.get_connected_players()) do
local right_click = clicker:get_player_control().RMB or false
if clicker and right_click == true then
local name = clicker:get_player_name()
local clicked = verify_clicked_player(clicker, player_rightclick_range)
if clicked then
for _,func in pairs(events) do
func(clicker, clicked)
end
end
break
end
end
minetest.after(update_interval, function()
handle_on_rightclickplayer()
end)
end
end
--Register on rightclick player (Called when a player rightclicked a fellow player)
function minetest.register_on_rightclickplayer(player, clicker)
assert(type(func) == "function", "you must include a function with the following arguements (player, clicker).")
table.insert(minetest.registered_on_rightclickplayer_events, func)
end
end
--Register on remove entity (Called after objectref:remove() gets called)
function minetest.register_on_removeentity(func)
assert(type(func) == "function", "you must include a function with the following arguement (self).")
table.insert(minetest.registered_on_entity_remove_events, func)
end
--Register on remove entity (Called after metadata method objectref:remove() gets called)
function minetest.register_on_clearobjects(func)
assert(type(func) == "function", "you must include a function with the following arguement (option).")
table.insert(minetest.registered_on_clear_objects_events, func)
end