From 29f868ae005f8ae33c0dba51bb74a1295e8fdf4b Mon Sep 17 00:00:00 2001 From: Zughy <4279489-marco_a@users.noreply.gitlab.com> Date: Tue, 11 Jan 2022 23:44:53 +0100 Subject: [PATCH] Redesign set_sign + CRASHFIX when moved with WorldEdit --- DOCS.md | 4 +- locale/arena_lib.es.tr | 1 - locale/arena_lib.it.tr | 3 +- locale/template.txt | 3 +- src/api/core.lua | 130 ++++++++++++++++++-------------------- src/editor/tools_sign.lua | 81 ++++++++++++++++-------- src/signs.lua | 13 +++- src/utils.lua | 2 +- 8 files changed, 136 insertions(+), 101 deletions(-) diff --git a/DOCS.md b/DOCS.md index 81e0549..1246dac 100644 --- a/DOCS.md +++ b/DOCS.md @@ -328,7 +328,7 @@ In order to do so, it must be disabled. ### 2.2 Setting up an arena Two things are needed to have an arena up to go: spawners and signs. There are two functions for that: * `arena_lib.set_spawner(sender, mod, arena_name, , , )`: spawners can't exceed the maximum players of an arena and, more specifically, they must be the same number. A spawner is a table with `pos` and `team_ID` as values. -* `arena_lib.set_sign(sender, , )`: there must be one and only one sign per arena. Signs are the bridge between the arena and the rest of the world +* `arena_lib.set_sign(sender, mod, arena_name, )`: there must be one and only one sign per arena. Signs are the bridge between the arena and the rest of the world #### 2.2.1 Editor arena_lib comes with a fancy editor via hotbar so you don't have to configure and memorise a lot of commands (if you still want to go full CLI/chat though, skip this paragraph). @@ -389,7 +389,7 @@ ChatCmdBuilder.new("NAMEOFYOURCOMMAND", function(cmd) ``` ##### 2.2.2.6 Signs -`arena_lib.set_sign(sender, , )` via chat uses `sender`, `mod` and `arena_name`, while the editor `pos` and `remove` (hence the weird subdivision). When used via chat, it takes the block the player is pointing at in a 5 blocks radius. If the block is a sign, it then creates (or remove if already set) the "arena sign". +`arena_lib.set_sign(sender, mod, arena_name, )` allows to either set or remove the sign of that specific arena. `pos` is a table, and it must correspond to an arena_lib sign to be set. `remove` is a boolean, and if `true`, `pos` will be ignored, as it'll erase the current arena sign (if exists) ##### 2.2.2.7 Music `arena_lib.set_bgm(sender, mod, arena_name, track, title, author, volume, pitch)` sets the background music of the arena. The audio file (`track`) must be inside the `sounds` folder of the minigame mod (NOT arena_lib's), and `.ogg` shall be omitted from the string. If `track` is nil, `arena.bgm` will be set to `nil` too diff --git a/locale/arena_lib.es.tr b/locale/arena_lib.es.tr index 2e69989..b6ae343 100755 --- a/locale/arena_lib.es.tr +++ b/locale/arena_lib.es.tr @@ -31,7 +31,6 @@ Spawn point #@1 successfully deleted=Punto de spawn #@1 eliminado correctamente Spawn point #@1 successfully set=Punto de spawn #@1 establecido correctamente [!] That's not an arena_lib sign!=[!] ¡Este no es un cartel de arena_lib! Sign of arena @1 successfully removed=Cartel de la arena @1 eliminado correctamente -[!] This sign doesn't belong to @1!=[!] ¡Este cartel no pertenece a @1! [!] There is already a sign for this arena!=[!] ¡Ya existe un cartel para este arena! [!] There is no sign to remove assigned to @1!=[!] ¡No hay un cartel para eliminar asignado a @1! Sign of arena @1 successfully set=Cartel de arena @1 establecido correctamente diff --git a/locale/arena_lib.it.tr b/locale/arena_lib.it.tr index 5d320f9..c93da0c 100755 --- a/locale/arena_lib.it.tr +++ b/locale/arena_lib.it.tr @@ -34,7 +34,6 @@ Spawn point #@1 successfully deleted=Punto di spawn #@1 cancellato con successo Spawn point #@1 successfully set=Punto di spawn #@1 impostato con successo [!] That's not an arena_lib sign!=[!] Questo non è un cartello di arena_lib! Sign of arena @1 successfully removed=Cartello dell'arena @1 rimosso con successo -[!] This sign doesn't belong to @1!=[!] Questo cartello non appartiene a @1! [!] There is already a sign for this arena!=[!] Esiste già un cartello per quest'arena! [!] There is no sign to remove assigned to @1!=[!] Non c'è nessun cartello da rimuovere assegnato a @1! Sign of arena @1 successfully set=Cartello dell'arena @1 impostato con successo @@ -138,6 +137,7 @@ Overwrite=Sovrascrivi # signs.lua Arena sign=Cartello dell'arena [!] You must leave the editor first!=[!] Devi prima uscire dall'editor! +[!] Uh-oh, it looks like this sign has been misplaced: well, fixed, hit it again!==[!]Oh oh, sembra che questo cartello sia fuori posto: beh, sistemato, colpiscilo di nuovo! [!] Only the party leader can enter the queue!=[!] Solo il capo gruppo può entrare nella coda! [!] You must wait for all your party members to finish their ongoing games before entering a new one!=[!] Devi aspettare che i membri della tua squadra terminino le loro partite in corso prima di iniziarne una nuova! [!] There is not enough space for the whole party!=[!] Non c'è abbastanza spazio per tutto il gruppo! @@ -262,6 +262,7 @@ Delete all spawners of a team=Cancella tutti gli spawner della squadra # editor/tools_sign.lua Add sign=Aggiungi cartello Remove sign=Rimuovi cartello +Are you sure you want to delete the sign from @1?=Sei sicuro/a di voler rimuovere il cartello di @1? # hud/hud_waypoints.lua [!] Waypoints are not enabled!=[!] I waypoint non sono abilitati! diff --git a/locale/template.txt b/locale/template.txt index afd0edf..02e1150 100755 --- a/locale/template.txt +++ b/locale/template.txt @@ -34,7 +34,6 @@ Spawn point #@1 successfully deleted= Spawn point #@1 successfully set= [!] That's not an arena_lib sign!= Sign of arena @1 successfully removed= -[!] This sign doesn't belong to @1!= [!] There is already a sign for this arena!= [!] There is no sign to remove assigned to @1!= Sign of arena @1 successfully set= @@ -138,6 +137,7 @@ Overwrite= # signs.lua Arena sign= [!] You must leave the editor first!= +[!] Uh-oh, it looks like this sign has been misplaced: well, fixed, hit it again!= [!] Only the party leader can enter the queue!= [!] You must wait for all your party members to finish their ongoing games before entering a new one!= [!] There is not enough space for the whole party!= @@ -262,6 +262,7 @@ Delete all spawners of a team= # editor/tools_sign.lua Add sign= Remove sign= +Are you sure you want to delete the sign from @1?= # hud/hud_waypoints.lua [!] Waypoints are not enabled!= diff --git a/src/api/core.lua b/src/api/core.lua index 2b9cebb..dd986e0 100755 --- a/src/api/core.lua +++ b/src/api/core.lua @@ -754,87 +754,74 @@ end --- 2 approcci: da editor e da linea di comando (chat) --- l'editor utilizza sender, pos e remove. Colpisce un cartello (pos) e fa una determinata azione (remove true/false) --- la linea di comando usa sender, mod e arena_name. Prende dove guarda il giocatore e si accerta che è un cartello (non richiede quindi hotbar o inventari di alcun tipo) -function arena_lib.set_sign(sender, pos, remove, mod, arena_name) +function arena_lib.set_sign(sender, mod, arena_name, pos, remove, in_editor) - local id = 0 - local arena = {} + -- remove in 7.0 + if type(pos) == "string" and type(remove) == "string" then + warn_deprecated_set_sign(sender) + return + end - -- se uso la riga di comando, controllo se sto guardando un cartello - if mod then - id, arena = arena_lib.get_arena_by_name(mod, arena_name) + local id, arena = arena_lib.get_arena_by_name(mod, arena_name) + if not in_editor then if not ARENA_LIB_EDIT_PRECHECKS_PASSED(sender, arena) then return end - - local player = minetest.get_player_by_name(sender) - local p_pos = player:get_pos() - local p_eye_pos = { x = p_pos.x, y = p_pos.y + 1.475, z = p_pos.z } - local to = vector.add(p_eye_pos, vector.multiply(player:get_look_dir(), 5)) - local ray = Raycast(p_eye_pos, to) - - -- cerco un cartello - for hit in ray do - if hit.type == "node" then - local node = minetest.get_node(hit["under"]) - if string.match(node.name, "arena_lib:sign") then - pos = hit["under"] - break - end - end - end - - -- se non ha trovato niente, esco - if pos == nil then - minetest.chat_send_player(sender, minetest.colorize("#e6482e", S("[!] That's not an arena_lib sign!"))) - return end - - -- se uso l'editor - else - - local player = minetest.get_player_by_name(sender) - - mod = player:get_meta():get_string("arena_lib_editor.mod") - id, arena = arena_lib.get_arena_by_name(mod, player:get_meta():get_string("arena_lib_editor.arena")) end local mod_ref = arena_lib.mods[mod] - -- se c'è già un cartello assegnato - if next(arena.sign) ~= nil then - -- dal linea di comando non fa distinzione (nil), sennò sto usando lo strumento per rimuovere da editor (remove == true) - if remove == nil or remove == true then - if minetest.serialize(pos) == minetest.serialize(arena.sign) then - minetest.set_node(pos, {name = "air"}) - arena.sign = {} - minetest.chat_send_player(sender, mod_ref.prefix .. S("Sign of arena @1 successfully removed", arena.name)) - update_storage(false, mod, id, arena) - else - minetest.chat_send_player(sender, minetest.colorize("#e6482e", S("[!] This sign doesn't belong to @1!", arena.name))) - end - elseif remove == false then - minetest.chat_send_player(sender, minetest.colorize("#e6482e", S("[!] There is already a sign for this arena!"))) + -- se rimuovo + if remove then + + -- se non ha cartelli da rimuovere, annullo + if not next(arena.sign) then + minetest.chat_send_player(sender, minetest.colorize("#e6482e", S("[!] There is no sign to remove assigned to @1!", arena.name))) + return end + + minetest.load_area(arena.sign) + + local sign_meta = minetest.get_meta(arena.sign) + + -- se il cartello non è stato spostato lo rimuovo, sennò evito di far sparire il blocco che c'è ora + -- (può capitare se qualcuno sposta un'area con WorldEdit). Le altre condizioni assicurano poi che si stia + -- cancellando il cartello giusto, nel caso qualcuno con WorldEdit ne abbia spostato un altro appartenente + -- a un'arena diversa nella stessa posizione + if minetest.get_node(arena.sign).name == "arena_lib:sign" and sign_meta:get_string("mod") == mod and + sign_meta:get_int("arenaID") == id then + minetest.set_node(arena.sign, {name = "air"}) end - return - elseif remove == true then - minetest.chat_send_player(sender, minetest.colorize("#e6482e", S("[!] There is no sign to remove assigned to @1!", arena.name))) - return + + arena.sign = {} + minetest.chat_send_player(sender, mod_ref.prefix .. S("Sign of arena @1 successfully removed", arena.name)) + + -- sennò aggiungo + else + + if next(arena.sign) then + minetest.chat_send_player(sender, minetest.colorize("#e6482e", S("[!] There is already a sign for this arena!"))) + return end + + if not pos or type(pos) ~= "table" then + minetest.chat_send_player(sender, minetest.colorize("#e6482e", S("[!] Parameters don't seem right!"))) + return end + + -- se non ha trovato niente, esco + if minetest.get_node(pos).name ~= "arena_lib:sign" then + minetest.chat_send_player(sender, minetest.colorize("#e6482e", S("[!] That's not an arena_lib sign!"))) + return end + + -- aggiungo il cartello all'arena e cambio la scritta + arena.sign = pos + arena_lib.update_sign(arena) + + -- salvo il nome della mod e l'ID come metadato nel cartello + minetest.get_meta(pos):set_string("mod", mod) + minetest.get_meta(pos):set_int("arenaID", id) + + minetest.chat_send_player(sender, mod_ref.prefix .. S("Sign of arena @1 successfully set", arena.name)) end - -- aggiungo il cartello ai cartelli dell'arena - arena.sign = pos update_storage(false, mod, id, arena) - - -- cambio la scritta - arena_lib.update_sign(arena) - - -- salvo il nome della mod e l'ID come metadato nel cartello - minetest.get_meta(pos):set_string("mod", mod) - minetest.get_meta(pos):set_int("arenaID", id) - - minetest.chat_send_player(sender, mod_ref.prefix .. S("Sign of arena @1 successfully set", arena.name)) - end @@ -1374,3 +1361,8 @@ function arena_lib.send_message_players_in_arena(arena, msg, teamID, except_team minetest.log("warning", "[ARENA_LIB] send_message_players_in_arena is deprecated. Please use send_message_in_arena instead") arena_lib.send_message_in_arena(arena, "players", msg, teamID, except_teamID) end + +local function warn_deprecated_set_sign(sender) + minetest.log("warning", "[ARENA_LIB] set_sign(sender, , , mod, arena_name) is deprecated. Please use set_sign(sender, mod, arena_name, pos, ) instead") + minetest.chat_send_player(sender, "[ARENA_LIB] set_sign(sender, pos, remove, mod, arena_name) is deprecated and pos now mandatory. Watch the log, aborting...") +end diff --git a/src/editor/tools_sign.lua b/src/editor/tools_sign.lua index 577acf0..29f3b64 100755 --- a/src/editor/tools_sign.lua +++ b/src/editor/tools_sign.lua @@ -22,22 +22,15 @@ minetest.register_tool("arena_lib:sign_add", { on_drop = function() end, on_use = function(itemstack, user, pointed_thing) + local p_name = user:get_player_name() + local mod = user:get_meta():get_string("arena_lib_editor.mod") + local arena_name = user:get_meta():get_string("arena_lib_editor.arena") + local pos = minetest.get_pointed_thing_position(pointed_thing) - local pos = minetest.get_pointed_thing_position(pointed_thing) - if pos == nil then return end -- nel caso sia aria, sennò crasha + if not pos then return end -- nel caso sia aria, sennò crasha - local node = minetest.get_node(pos) - local def = minetest.registered_items[node.name] - local p_name = user:get_player_name() - - -- controllo se è un cartello - if not def or def.entity_info == nil then - minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] That's not an arena_lib sign!"))) - return end - - arena_lib.set_sign(p_name, pos, false) + arena_lib.set_sign(p_name, mod, arena_name, pos, _, true) end - }) @@ -51,21 +44,17 @@ minetest.register_tool("arena_lib:sign_remove", { on_drop = function() end, on_use = function(itemstack, user, pointed_thing) + local p_name = user:get_player_name() + local mod = user:get_meta():get_string("arena_lib_editor.mod") + local arena_name = user:get_meta():get_string("arena_lib_editor.arena") + local id, arena = arena_lib.get_arena_by_name(mod, arena_name) - local pos = minetest.get_pointed_thing_position(pointed_thing) - if pos == nil then return end -- nel caso sia aria, sennò crasha + if not next(arena.sign) then + minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] There is no sign to remove assigned to @1!", arena.name))) + return end - local node_name = minetest.get_node(pos).name - local p_name = user:get_player_name() - - -- controllo se è un cartello - if node_name ~= "arena_lib:sign" then - minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] That's not an arena_lib sign!"))) - return end - - arena_lib.set_sign(p_name, pos, true) + minetest.show_formspec(p_name, "arena_lib:sign_delete", get_sign_formspec(p_name, arena_name)) end - }) @@ -73,3 +62,45 @@ minetest.register_tool("arena_lib:sign_remove", { function arena_lib.give_signs_tools(player) player:get_inventory():set_list("main", spawners_tools) end + + + + + +--- + +function get_sign_formspec(p_name, arena_name) + + local formspec = { + "size[5,1]", + "style[delete_confirm;bgcolor=red]", + "hypertext[0.25,-0.1;5,1;delete_msg;" .. S("Are you sure you want to delete the sign from @1?", arena_name) .. "]", + "button[3,0.5;1.5,0.5;delete_confirm;" .. S("Yes") .. "]", + "button[0.5,0.5;1.5,0.5;delete_cancel;" .. S("Cancel") .. "]", + "field_close_on_enter[;false]" + } + + return table.concat(formspec, "") +end + + + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + if formname ~= "arena_lib:sign_delete" then return end + + local p_name = player:get_player_name() + + if fields.delete_confirm then + local mod = player:get_meta():get_string("arena_lib_editor.mod") + local arena_name = player:get_meta():get_string("arena_lib_editor.arena") + + arena_lib.set_sign(p_name, mod, arena_name, _, true, true) + minetest.close_formspec(p_name, formname) + + elseif fields.delete_cancel then + minetest.close_formspec(p_name, formname) + end + +end) diff --git a/src/signs.lua b/src/signs.lua index 31a29db..9d7d096 100755 --- a/src/signs.lua +++ b/src/signs.lua @@ -58,13 +58,24 @@ signs_lib.register_sign("arena_lib:sign", { local sign_arena = mod_ref.arenas[arenaID] local p_name = puncher:get_player_name() - if not sign_arena then return end -- nel caso qualche cartello dovesse buggarsi, si può rompere senza far crashare + if not sign_arena then return end -- nel caso qualche cartello dovesse impallarsi, si può rompere senza far crashare -- se si è nell'editor if arena_lib.is_player_in_edit_mode(p_name) then minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] You must leave the editor first!"))) return end + -- se il cartello è stato spostato (tipo con WorldEdit), lo ripristino (e se c'è una partita in corso, la interrompo) + if minetest.serialize(sign_arena.sign) ~= minetest.serialize(pos) then + local arena_name = sign_arena.name + arena_lib.force_arena_ending(mod, sign_arena, "ARENA_LIB") + arena_lib.disable_arena("", mod, arena_name) + arena_lib.set_sign("", mod, arena_name, _, true) + arena_lib.set_sign("", mod, arena_name, pos) + arena_lib.enable_arena("", mod, arena_name) + minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] Uh-oh, it looks like this sign has been misplaced: well, fixed, hit it again!"))) + return end + -- se c'è parties e si è in gruppo... if minetest.get_modpath("parties") and parties.is_player_in_party(p_name) and arena_lib.get_queueID_by_player(p_name) ~= arenaID then diff --git a/src/utils.lua b/src/utils.lua index ad37372..8edb89e 100755 --- a/src/utils.lua +++ b/src/utils.lua @@ -34,12 +34,12 @@ function AL_property_to_string(property) else return tostring(property) end - end + ---------------------------------------------- -------------ASPETTANDO MINETEST-------------- ----------------------------------------------