1
0
mirror of https://github.com/sys4-fr/server-nalc.git synced 2024-12-26 02:30:38 +01:00
server-nalc/mods/pclasses/api.lua
LeMagnesium 743507564f Updated pclasses
- Moved the holographic item's name as a field in switch_params (pclasses.api.register_class)
 - Added wizard class' skeleton for later
 - Fixed a few bugs in nodes, inventory and api
 - Splitted tick function to bury items in two
 - Items from 3d_armor's armor inventory are also affected by inventory vacuuming (from tick function).
   The player's static armor inventory is first cleared, then copied to the detached one, then armor updates everything else (rendering, model, etc)
 - Fixed itemname of admin shield to reserve it properly
 - Return graveyard inventory if it already exists. Do not create it every two seconds
2015-08-20 17:18:57 +02:00

158 lines
4.4 KiB
Lua
Executable File

------------------
-- PClasses' API
--
-- Various utility functions
-- Register the class (basic registration)
function pclasses.api.register_class(cname, def)
if not cname then
minetest.log("error", "[PClasses] Error registering unamed class")
return
elseif not def then
minetest.log("error", "[PClasses] Error registering class " ..
cname .. ". Reason : no definition table.")
return
end
pclasses.register_class_switch(cname, def.switch_params)
pclasses.classes[cname] = def
return true
end
------------------------
-- Getters and Setters
--
-- Get class specs by name
function pclasses.api.get_class_by_name(cname)
return pclasses.classes[cname]
end
-- Get single player
function pclasses.api.get_player_class(pname)
return pclasses.data.players[pname]
end
-- Get all players for a class
function pclasses.api.get_class_players(cname)
local pnames = {}
if pclasses.api.get_class_by_name(cname) then
for p,c in ipairs(pclasses.data.players) do
if c == cname then
table.insert(pnames, table.getn(pnames)+1)
end
end
end
end
-- Set single player
function pclasses.api.set_player_class(pname, cname)
if pclasses.api.get_class_by_name(cname) then
if pclasses.api.get_player_class(pname) ~= cname then
if pclasses.api.get_player_class(pname) and pclasses.classes[pclasses.api.get_player_class(pname)].on_unassigned then
pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned(pname)
end
pclasses.data.players[pname] = cname
pclasses.api.get_class_by_name(cname).on_assigned(pname)
pclasses.api.vacuum_graveyard(minetest.get_player_by_name(pname))
end
return true
end
return false
end
-- Util function(s)
pclasses.api.util.does_wear_full_armor = function(pname, material, noshield)
local inv = minetest.get_inventory({type = "detached", name = pname .. "_armor"})
if not inv or inv:is_empty("armor") then
return false
end
local full_armor = true
for _, piece in pairs({"chestplate", "leggings", "boots", "helmet"}) do
full_armor = full_armor and inv:contains_item("armor", "3d_armor:" .. piece .. "_" .. material)
end
return full_armor and (inv:contains_item("armor", "shields:shield_" .. material) or noshield)
end
function pclasses.api.util.can_have_item(pname, itemname)
if not pclasses.data.reserved_items[itemname] then
return true
end
for index, class in pairs(pclasses.data.reserved_items[itemname]) do
if pclasses.api.get_player_class(pname) == class then
return true
end
end
return false
end
-- TEMPORARY CLASS SHIFT SYSTEM
-- Used to test on local servers
--
minetest.register_privilege("class_shifter", "Able to shift between classes")
minetest.register_chatcommand("switch_class", {
args = "<class>",
privs = {class_shifter = true},
func = function(name, param)
pclasses.api.set_player_class(name, param)
end
})
-------------------
-- Reserved items
--
function pclasses.api.reserve_item(cname, itemstring)
pclasses.data.reserved_items[itemstring] = pclasses.data.reserved_items[itemstring] or {}
table.insert(pclasses.data.reserved_items[itemstring], cname)
end
-------------------------------------------
-- Determination and reserved items tick --
-------------------------------------------
local function vacuum_inventory(name, inv, invname)
local ref = minetest.get_player_by_name(name)
for i = 1, inv:get_size(invname) do
local stack = inv:get_stack(invname, i)
if pclasses.data.reserved_items[stack:get_name()] then
if not pclasses.api.util.can_have_item(name, stack:get_name()) then
inv:set_stack(invname, i, "")
local grave_inv = pclasses.api.create_graveyard_inventory(ref)
if grave_inv and grave_inv:room_for_item("graveyard", stack) then
grave_inv:add_item("graveyard", stack)
inv:add_item("graveyard", stack)
-- ^ Because add_item doesn't trigger on_put, nonsense
else
minetest.add_item(ref:getpos(), stack)
end
end
end
end
end
local function tick()
for id, ref in ipairs(minetest.get_connected_players()) do
local name = ref:get_player_name()
local armor_inv = minetest.get_inventory({type = "detached", name = name .. "_armor"})
local inv = ref:get_inventory()
vacuum_inventory(name, inv, "main")
vacuum_inventory(name, inv, "armor")
-- Hack the hack
for i = 1, armor_inv:get_size("armor") do
armor_inv:set_stack("armor", i, inv:get_stack("armor", i))
end
armor:set_player_armor(ref)
armor:update_inventory(ref)
end
minetest.after(2, tick)
end
tick()