Redesign set_sign + CRASHFIX when moved with WorldEdit

master
Zughy 2022-01-11 23:44:53 +01:00
parent 12b344a59a
commit 29f868ae00
8 changed files with 136 additions and 101 deletions

View File

@ -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, <teamID_or_name>, <param>, <ID>)`: 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, <pos, remove>, <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
* `arena_lib.set_sign(sender, mod, arena_name, <pos, remove>)`: 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, <pos, remove>, <mod, arena_name>)` 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, <pos, remove>)` 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

View File

@ -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

View File

@ -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!

View File

@ -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!=

View File

@ -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, <pos>, <remove>, mod, arena_name) is deprecated. Please use set_sign(sender, mod, arena_name, pos, <remove>) 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

View File

@ -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;<global halign=center>" .. 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)

View File

@ -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

View File

@ -34,12 +34,12 @@ function AL_property_to_string(property)
else
return tostring(property)
end
end
----------------------------------------------
-------------ASPETTANDO MINETEST--------------
----------------------------------------------