Boots_Arena-PvP_Mod/init.lua
2025-09-06 09:09:22 +02:00

221 lines
8.3 KiB
Lua

local S = minetest.get_translator("arena_pvp")
local mod_storage = minetest.get_mod_storage()
local modpath = minetest.get_modpath("arena_pvp")
local settings_path = modpath .. "/settings.txt"
-- Privileg aus settings.txt lesen (oder erstellen mit Standardwert "server")
local function load_required_priv()
local file = io.open(settings_path, "r")
if file then
local priv = file:read("*l")
file:close()
if priv and priv ~= "" then
return priv
end
end
local f = io.open(settings_path, "w")
if f then
f:write("server\n")
f:close()
end
return "server"
end
local required_priv = load_required_priv()
local arena_players = minetest.deserialize(mod_storage:get_string("arena_players")) or {}
local arena_chests = minetest.deserialize(mod_storage:get_string("arena_chests")) or {}
local leader_chests = minetest.deserialize(mod_storage:get_string("leader_chests")) or {}
-- Speichern beim Shutdown
local function persist_data()
mod_storage:set_string("arena_players", minetest.serialize(arena_players))
mod_storage:set_string("arena_chests", minetest.serialize(arena_chests))
mod_storage:set_string("leader_chests", minetest.serialize(leader_chests))
end
minetest.register_on_shutdown(persist_data)
-- Hilfsfunktionen Inventar sichern/laden
local function save_inventory(invlist)
local data = {}
for i, stack in ipairs(invlist) do
data[i] = stack:to_string()
end
return minetest.serialize(data)
end
local function load_inventory(serialized)
local data = minetest.deserialize(serialized)
local invlist = {}
if type(data) == "table" then
for i, s in ipairs(data) do
invlist[i] = ItemStack(s)
end
end
return invlist
end
-- Spieler-Kiste
minetest.register_node("arena_pvp:chest_player", {
description = S("Arena-Spieler-Kiste"),
tiles = {"default_chest_top.png", "default_chest_top.png",
"default_chest_side.png", "default_chest_side.png",
"default_chest_side.png", "default_chest_front.png"},
groups = {choppy=2, oddly_breakable_by_hand=2},
on_rightclick = function(pos, node, clicker)
local name = clicker:get_player_name()
if arena_chests[name] then
minetest.chat_send_player(name, S("Du hast bereits eine Arena-Kiste benutzt!"))
return
end
local inv = clicker:get_inventory()
local backup = inv:get_list("main")
local meta = minetest.get_meta(pos)
meta:set_string("owner", name)
meta:set_string("backup", save_inventory(backup))
if not meta:get_string("backup") or meta:get_string("backup") == "" then
minetest.chat_send_player(name, S("Fehler beim Sichern des Inventars!"))
return
end
inv:set_list("main", {})
arena_chests[name] = pos
persist_data()
minetest.chat_send_player(name, S("Dein Inventar wurde gesichert!"))
minetest.log("action", "[arena_pvp] Spieler " .. name .. " hat seine Arena-Kiste gesetzt.")
end,
})
-- Leiter-Kiste
minetest.register_node("arena_pvp:chest_leader", {
description = S("Arena-Leiter-Kiste"),
tiles = {"default_chest_top.png", "default_chest_top.png",
"default_chest_side.png", "default_chest_side.png",
"default_chest_side.png", "default_chest_front.png"},
groups = {choppy=2, oddly_breakable_by_hand=2},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("main", 16)
leader_chests[minetest.pos_to_string(pos)] = pos
persist_data()
minetest.log("action", "[arena_pvp] Leiter-Kiste platziert bei " .. minetest.pos_to_string(pos))
end,
on_rightclick = function(pos, node, clicker)
local meta = minetest.get_meta(pos)
minetest.show_formspec(clicker:get_player_name(),
"arena_pvp:leader_chest",
"size[8,9]" ..
"list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0;8,2;]" ..
"list[current_player;main;0,5;8,4;]")
end,
})
-- Arena Start
minetest.register_chatcommand("arena_start", {
privs = {[required_priv] = true},
func = function(name)
local count = 0
for pname, pos in pairs(arena_chests) do
local player = minetest.get_player_by_name(pname)
if player then
local meta = minetest.get_meta(next(leader_chests))
local leader_inv = meta:get_inventory():get_list("main")
local inv = player:get_inventory()
inv:set_list("main", {})
for _, stack in ipairs(leader_inv) do
inv:add_item("main", stack)
end
arena_players[pname] = true
minetest.chat_send_player(pname, "" .. S("Der Kampf beginnt!"))
minetest.log("action", "[arena_pvp] Kampf gestartet für Spieler " .. pname)
count = count + 1
end
end
persist_data()
return true, S("Arena-Kampf gestartet mit @1 Spielern.", count)
end,
})
-- Arena End
minetest.register_chatcommand("arena_end", {
privs = {[required_priv] = true},
func = function(name)
local count = 0
for pname, pos in pairs(arena_chests) do
local player = minetest.get_player_by_name(pname)
if player then
local meta = minetest.get_meta(pos)
local backup = load_inventory(meta:get_string("backup"))
if backup then
player:get_inventory():set_list("main", backup)
end
arena_players[pname] = nil
minetest.chat_send_player(pname, "🏆 " .. S("Der Kampf ist beendet. Dein Inventar wurde wiederhergestellt."))
minetest.log("action", "[arena_pvp] Kampf beendet für Spieler " .. pname)
count = count + 1
end
end
persist_data()
return true, S("Arena-Kampf beendet, @1 Spieler Inventare zurückgegeben.", count)
end,
})
-- Heilung blockieren
minetest.register_on_item_eat(function(_, _, itemstack, user)
if user and arena_players[user:get_player_name()] then
minetest.chat_send_player(user:get_player_name(), "" .. S("Heilung ist in der Arena deaktiviert!"))
return itemstack -- Nahrung bleibt erhalten
end
end)
-- Arena-Schalter
minetest.register_node("arena_pvp:arena_switch", {
description = S("Arena-Schalter"),
tiles = {"default_stone.png"},
groups = {cracky=3, oddly_breakable_by_hand=2},
on_rightclick = function(pos, node, clicker)
local name = clicker:get_player_name()
if not minetest.check_player_privs(name, {[required_priv] = true}) then
minetest.chat_send_player(name, S("Du hast keine Berechtigung, Kämpfe zu steuern."))
return
end
minetest.show_formspec(name, "arena_pvp:switch",
"size[4,3]" ..
"button[0.5,0.5;3,1;arena_start;" .. S("⚔ Kampf starten") .. "]" ..
"button[0.5,1.5;3,1;arena_end;" .. S("🏆 Kampf beenden") .. "]")
end,
})
-- Schalter-Buttons
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname == "arena_pvp:switch" then
local name = player:get_player_name()
if not minetest.check_player_privs(name, {[required_priv] = true}) then
minetest.chat_send_player(name, S("Du hast keine Berechtigung, Kämpfe zu steuern."))
return true
end
if fields.arena_start then
minetest.chatcommands["arena_start"].func(name)
return true
elseif fields.arena_end then
minetest.chatcommands["arena_end"].func(name)
return true
end
return true
end
end)
-- Inventarinteraktionen blockieren für Arena-Spieler
minetest.register_allow_player_inventory_action(function(player, action, inventory, info)
local pname = player:get_player_name()
if arena_players[pname] then
return 0 -- blockieren
end
return nil
end)