mobf_core/mobf/mob_preserve.lua

311 lines
9.4 KiB
Lua

-------------------------------------------------------------------------------
-- Mob Framework Mod by Sapier
--
-- You may copy, use, modify or do nearly anything except removing this
-- copyright notice.
-- And of course you are NOT allow to pretend you have written it.
--
--! @file mob_preserve.lua
--! @brief component containing spawning features
--! @copyright Sapier
--! @author Sapier
--! @date 2013-01-29
--
--! @defgroup mob_preserve gui to reclaim mobs removed by error handling
--! @brief gui to reclaim error removed player spawned mobs
--! @ingroup framework_int
--! @{
--
-- Contact sapier a t gmx net
-------------------------------------------------------------------------------
mobf_assert_backtrace(mob_preserve == nil)
--! @class mob_preserve
--! @brief mob preserve features
--!@}
mob_preserve = {}
mob_preserve.entrys_per_page = 10
------------------------------------------------------------------------------
-- name: init()
-- @function [parent=#mob_preserve] preserve handler
--
--! @brief initialize dynamic data
--! @memberof mob_preserve
--! @public
------------------------------------------------------------------------------
function mob_preserve.init()
local preserved_mobs_raw = mobf_get_world_setting("mobf_preserve_mobs")
if preserved_mobs_raw ~= nil then
mob_preserve.current_preserve_list =
minetest.deserialize(preserved_mobs_raw)
if mob_preserve.current_preserve_list == nil then
mob_preserve.current_preserve_list = {}
end
end
minetest.register_chatcommand("mobf_restore_mobs",
{
params = "",
description = "show list of stored mobs" ,
privs = {},
func = mob_preserve.handle_command
})
minetest.register_on_player_receive_fields(mob_preserve.button_callback)
end
------------------------------------------------------------------------------
-- name: handle_remove(entity,reason)
-- @function [parent=#mob_preserve] preserve handler
--
--! @brief check if a mob needs to be preserved
--! @memberof mob_preserve
--! @public
--
--! @param entity entity to check
--! @param reason reason for removal
-------------------------------------------------------------------------------
function mob_preserve.handle_remove(entity,reason)
if reason ~= "cought" and
reason ~= "killed" and
reason ~= "died by sun" and
reason ~= "replaced" then
if entity.dynamic_data.spawning.player_spawned then
local toset = {}
toset.modname = entity.data.modname
toset.name = entity.data.name
toset.owner = entity.dynamic_data.spawning.spawner
toset.reason = reason
if toset.owner ~= nil then
dbg_mobf.mob_preserve_lvl2("MOBF: preserving " .. toset.modname ..
":" .. toset.name .. " for player " .. toset.owner )
table.insert(mob_preserve.current_preserve_list,toset)
mobf_set_world_setting("mobf_preserve_mobs",
minetest.serialize(mob_preserve.current_preserve_list))
else
dbg_mobf.mob_preserve_lvl1("MOBF: unable to preserve mob")
end
else
dbg_mobf.mob_preserve_lvl2("MOBF: not preserving " .. entity.data.name
.. " it's not playerspawned: " .. dump(entity.dynamic_data.spawning) )
end
else
dbg_mobf.mob_preserve_lvl2("MOBF: not preserving " .. entity.data.name
.. " removed by valid reason" )
end
end
------------------------------------------------------------------------------
-- name: handle_rightclick(name,param)
-- @function [parent=#mob_preserve] preserve handler
--
--! @brief show list of removed mobs
--! @memberof mob_preserve
--! @public
--
--! @param name name of formspec
--! @param param unused parameter
-------------------------------------------------------------------------------
function mob_preserve.handle_command(name,param)
local formspec = mob_preserve.get_formspec(name,0)
minetest.show_formspec(name,"mob_preserve:main",formspec)
end
------------------------------------------------------------------------------
-- name: get_formspec(name,page)
-- @function [parent=#mob_preserve] get formspec
--
--! @brief generate page form for mob_preserve
--! @memberof mob_preserve
--! @private
--
--! @param name player to create page for
--! @param pagenum pagenumber to create
-------------------------------------------------------------------------------
function mob_preserve.get_formspec(name,pagenum)
mobf_assert_backtrace(name ~= nil)
mobf_assert_backtrace(pagenum ~= nil)
local isadmin = minetest.check_player_privs(name, {mobfw_admin=true}) or minetest.is_singleplayer()
local min_entry_number = pagenum * mob_preserve.entrys_per_page +1
local pageform = ""
local elementcount = 1
dbg_mobf.mob_preserve_lvl3("MOBF: preserve starting list at " .. dump(min_entry_number ))
for n=1,#mob_preserve.current_preserve_list, 1 do
if mob_preserve.current_preserve_list[n].owner == name or
isadmin then
if elementcount >= min_entry_number then
local fixed_owner_name = mobf_fixed_size_string(name,12)
local fixed_reason = mobf_fixed_size_string(
mob_preserve.current_preserve_list[n].reason,24)
local y_pos = 1.0 + elementcount * 0.75
pageform = pageform .. " " ..
"label[0.5," .. y_pos .. ";" .. fixed_owner_name .. "]" ..
"label[3.0," .. y_pos .. ";" .. fixed_reason .. "]" ..
"label[6.5," .. y_pos .. ";" ..
mob_preserve.current_preserve_list[n].modname .. ":" ..
mob_preserve.current_preserve_list[n].name .. "]" ..
"button[10.5," .. y_pos .. ";2,0.5;take_" ..
elementcount .. "_" .. "_" ..
#mob_preserve.current_preserve_list .. "_" ..
pagenum .. ";take]"
end
elementcount = elementcount +1
if elementcount > min_entry_number + mob_preserve.entrys_per_page then
break
end
end
end
local pup = ""
local pdown = ""
if pagenum > 0 then
local upper_page = pagenum -1
pup = "button[5.5,0;2,0.5;page_" .. upper_page .. ";page up]"
end
if pagenum < (#mob_preserve.current_preserve_list / mob_preserve.entrys_per_page) then
local lower_page = pagenum +1
pdown = "button[5.5,9.5;2,0.5;page_" .. lower_page .. ";page down]"
end
local admininfo = ":"
if isadmin then
admininfo = " total: " .. #mob_preserve.current_preserve_list
end
return "size[13,10]"
..pup
..pdown
.."button_exit[11,9.5;2,0.5;main; Exit]"
.."label[0.5,0;Stashed mobs".. admininfo .. "]"
.."label[11.5,0;Page " .. pagenum .. "]"
.. pageform
end
------------------------------------------------------------------------------
-- name: button_callback(player,formname,fields)
-- @function [parent=#mob_preserve] handle button callback
--
--! @brief handle button callback
--! @memberof mob_preserve
--! @private
--
--! @param player player doing button click
--! @param formname name of form clicked
--! @param fields fields active
-------------------------------------------------------------------------------
function mob_preserve.button_callback(player, formname, fields)
dbg_mobf.mob_preserve_lvl3("MOBF: preserve checking formname " .. dump(formname))
if formname == "mob_preserve:main" then
dbg_mobf.mob_preserve_lvl3("MOBF: preserve detected own form: " .. dump(fields))
--evaluate fields
for k,v in pairs(fields) do
dbg_mobf.mob_preserve_lvl3("MOBF: preserve splitting: >" .. k .. "<")
local parts = string.split(k,"_")
dbg_mobf.mob_preserve_lvl3("MOBF: preserve got " .. dump(parts[1]) .. " "
.. dump(parts[2]) .. " " .. dump(parts[3]) .. " " .. dump(parts[4]))
if parts[1] == "take" then
local torestore = tonumber(parts[2])
local totalnumber = tonumber(parts[3])
--give mob to player
mob_preserve.retake_mob(player,torestore,totalnumber)
parts[1] = "page"
parts[2] = parts[4]
end
if parts[1] == "page" then
local count = tonumber(parts[2])
local playername = player:get_player_name()
if count ~= nil and
playername ~= nil then
local formspec = mob_preserve.get_formspec(playername,count)
minetest.show_formspec(playername,"mob_preserve:main",formspec)
else
dbg_mobf.mob_preserve_lvl3("MOBF: preserve invalid data " ..
dump(count) .. " " .. dump(playername))
end
end
end
return true
end
return false
end
------------------------------------------------------------------------------
-- name: retake_mob(player,entrynumber,totalnumber)
-- @function [parent=#mob_preserve] give mob back to player
--
--! @brief give mob back to player
--! @memberof mob_preserve
--! @private
--
--! @param player player doing button click
--! @param entrynumber number of entry to give back to player
--! @param total number of entrys on time of form creation
-------------------------------------------------------------------------------
function mob_preserve.retake_mob(player,entrynumber,total)
--this isn't a 100% check but reduces chance of list corruption
if total ~= #mob_preserve.current_preserve_list then
return
end
local playername = player:get_player_name()
local isadmin = minetest.check_player_privs(playername, {mobfw_admin=true})
local elementcount = 0
for i=1,#mob_preserve.current_preserve_list,1 do
if mob_preserve.current_preserve_list[i].owner == playername or
isadmin then
elementcount = elementcount +1
end
if elementcount == entrynumber then
--TODO check if player has enough room
--ADD to inventory
player:get_inventory():add_item("main",
mob_preserve.current_preserve_list[i].modname ..":"..
mob_preserve.current_preserve_list[i].name.." 1")
--remove from list
table.remove(mob_preserve.current_preserve_list,i)
mobf_set_world_setting("mobf_preserve_mobs",
minetest.serialize(mob_preserve.current_preserve_list))
return
end
end
end