mirror of
https://github.com/sys4-fr/server-nalc.git
synced 2024-12-25 18:20:36 +01:00
743507564f
- 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
158 lines
4.4 KiB
Lua
Executable File
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()
|