221 lines
8.3 KiB
Lua
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)
|