Spawners: also store rotation | Bugfix: in case of variable teams amount, spectators_amount_per_team wasn't resized to the new teams amount

This commit is contained in:
Zughy 2024-06-14 09:24:41 +00:00
parent 2149972171
commit 7782b0a039
9 changed files with 102 additions and 68 deletions

View File

@ -577,8 +577,10 @@ If you don't want to rely on the hotbar, or you want both the editor and the com
`arena_lib.toggle_teams_per_arena(sender, mod, arena_name, enable)` enables/disables teams per single arena. `enable` is a boolean.
##### 2.2.2.4 Spawners
`arena_lib.set_spawner(sender, mod, arena_name, <teamID>, <param>, <coords>)` can create and delete spawners.
* creation: leave `param` nil. It creates a spawner at `coords`, if specified, or where the sender is standing - so be sure to stand where you want the spawn point to be
`arena_lib.set_spawner(sender, mod, arena_name, <teamID>, <param>, <coords>, <rotation>)` can create and delete spawners.
* creation: leave `param` `nil`. Two possible ways:
* If a `sender` is specified, it creates a spawner at their coordinates, with their look direction
* If it's not, you can use `coords` (a positional table) and `rotation` (a table in degrees of format `{x=N, y=N}`)
* deletion: set `param` equal to `"delete"` or `"deleteall"`
* `"delete"` deletes the closest spawner to the player. It requires `teamID` if teams are enabled
* Single spawners are deleted through `table.remove`, meaning that there won't ever be a gap in the sequence (e.g. removing spawn point n°2 in sequence 1, 2, 3, 4, it won't result in 1, 3, 4 but in 1, 2, 3, where 2 and 3 previously were 3 and 4)

View File

@ -13,7 +13,6 @@ local function delete_schematic_if_exists() end
local function is_arena_name_allowed() end
local function initialise_map_storage() end
local function deprecated_chat_settings() end
local function deprecated_spawner_ID_param() end
local function deprecated_sound_table_entry_exists() end
local arena_default = {
@ -872,17 +871,19 @@ function arena_lib.change_teams_amount(sender, mod, arena_name, amount, in_edito
-- se ora ci son meno squadre, cancello i punti di rinascita di quelle in eccesso
if curr_amount > amount then
local extra_teams = #arena.teams - amount
for i = 1, extra_teams do
arena_lib.set_spawner(sender, mod, arena_name, amount + i, "deleteall", nil, in_editor)
arena.players_amount_per_team[amount + i] = nil
end
end
arena.teams = {}
arena.players_amount_per_team = {}
arena.spectators_amount_per_team = {}
for i = 1, amount do
arena.teams[i] = {name = mod_ref.teams[i]}
arena.players_amount_per_team[i] = 0
arena.spectators_amount_per_team[i] = 0
end
-- aggiorno l'entrata, se esiste
@ -963,14 +964,9 @@ end
-- I punti rinascita si impostano o prendendo la coordinata del giocatore che lancia
-- il comando o, se lanciato da terminale, tramite `coords`. `param` può essere
-- "delete" o "deleteall"
function arena_lib.set_spawner(sender, mod, arena_name, team_ID, param, coords, in_editor)
function arena_lib.set_spawner(sender, mod, arena_name, team_ID, param, coords, rotation, in_editor)
local id, arena = arena_lib.get_arena_by_name(mod, arena_name)
if type(in_editor) == "number" then
deprecated_spawner_ID_param(in_editor)
in_editor = false
end
if not in_editor then
if not ARENA_LIB_EDIT_PRECHECKS_PASSED(sender, arena) then return end
end
@ -997,12 +993,12 @@ function arena_lib.set_spawner(sender, mod, arena_name, team_ID, param, coords,
arena_lib.print_error(sender, S("There are no spawners to remove!"))
return end
local curr_spawner = {ID = 1, pos = spawners[1]}
local curr_spawner = {ID = 1, pos = spawners[1].pos}
local p_pos = minetest.get_player_by_name(sender):get_pos()
for i, pos in pairs(spawners) do
if vector.distance(pos, p_pos) < vector.distance(curr_spawner.pos, p_pos) then
curr_spawner = {ID = i, pos = pos}
for i, spwn in pairs(spawners) do
if vector.distance(spwn.pos, p_pos) < vector.distance(curr_spawner.pos, p_pos) then
curr_spawner = {ID = i, pos = spwn.pos}
end
end
@ -1038,21 +1034,28 @@ function arena_lib.set_spawner(sender, mod, arena_name, team_ID, param, coords,
return
end
-- controlla se rotation è del formato giusto
if rotation and (not type(rotation) == "table" or not rotation.x or not rotation.y) then
arena_lib.print_error(sender, S("Parameters don't seem right!"))
end
-- ...sennò sto creando un nuovo punto rinascita
local pos = vector.round(coords or minetest.get_player_by_name(sender):get_pos()) -- tolgo i decimali per immagazzinare un int
local player = minetest.get_player_by_name(sender)
local pos = vector.round(coords or player:get_pos()) -- tolgo i decimali per immagazzinare un int
local rot = rotation or {x = math.deg(player:get_look_horizontal()), y = math.deg(player:get_look_vertical())}
-- se c'è già un punto di rinascita a quelle coordinate, annullo
if not team_ID then
for _, spawn in pairs(arena.spawn_points) do
if vector.equals(pos, spawn) then
for _, spwn in pairs(arena.spawn_points) do
if vector.equals(pos, spwn.pos) then
arena_lib.print_error(sender, S("There's already a spawn in this point!"))
return
end
end
else
for i = 1, #arena.teams do
for _, spawn in pairs(arena.spawn_points[i]) do
if vector.equals(pos, spawn) then
for _, spwn in pairs(arena.spawn_points[i]) do
if vector.equals(pos, spwn.pos) then
arena_lib.print_error(sender, S("There's already a spawn in this point!"))
return
end
@ -1065,9 +1068,9 @@ function arena_lib.set_spawner(sender, mod, arena_name, team_ID, param, coords,
-- imposto il punto di rinascita
if team_ID then
arena.spawn_points[team_ID][next_available_spawnID] = pos
arena.spawn_points[team_ID][next_available_spawnID] = {pos = pos, rot = {x = rot.x, y = rot.y} }
else
arena.spawn_points[next_available_spawnID] = pos
arena.spawn_points[next_available_spawnID] = {pos = pos, rot = {x = rot.x, y = rot.y} }
end
arena_lib.update_waypoints(sender, mod, arena)
@ -1434,15 +1437,15 @@ function arena_lib.enable_arena(sender, mod, arena_name, in_editor)
local v1, v2 = vector.sort(arena.pos1, arena.pos2)
if not arena.teams_enabled then
for _, spawner in pairs(arena.spawn_points) do
if not vector.in_area(spawner, v1, v2) then
for _, spwn in pairs(arena.spawn_points) do
if not vector.in_area(spwn.pos, v1, v2) then
arena_lib.print_error(sender, S("If the arena region is declared, all the existing spawn points must be placed inside it!"))
return end
end
else
for _, team_table in pairs(arena.spawn_points) do
for _, spawner in pairs(team_table) do
if not vector.in_area(spawner, v1, v2) then
for _, spwn in pairs(team_table) do
if not vector.in_area(spwn.pos, v1, v2) then
arena_lib.print_error(sender, S("If the arena region is declared, all the existing spawn points must be placed inside it!"))
return end
end
@ -1662,32 +1665,50 @@ function init_storage(mod, mod_ref)
local arena = minetest.deserialize(arena_str)
local to_update = false
--v------------------ LEGACY UPDATE, to remove in 8.0 -------------------v
if arena.spawn_points[1] and arena.spawn_points[1].pos then
--v------------------ LEGACY UPDATE, to remove in 9.0 -------------------v
if next(arena.spawn_points) then
local update_spawners = false
local spawn_points = {}
if arena.spawn_points[1].teamID then
for j = 1, #arena.teams do
spawn_points[j] = {}
end
for _, spawner in pairs(arena.spawn_points) do
table.insert(spawn_points[spawner.teamID], spawner.pos)
end
arena.spawn_points = spawn_points
if not arena.teams_enabled and not arena.spawn_points[1].pos then
update_spawners = true
else
for _, spawner in pairs(arena.spawn_points) do
table.insert(spawn_points, spawner.pos)
table.insert(spawn_points, {pos = spawner, rot = {x=math.random(0,359), y=0}})
end
elseif arena.teams_enabled then
for _, data in pairs(arena.spawn_points) do
for _, spwn in pairs(data) do
if not spwn.pos then
update_spawners = true
break
end
end
end
if update_spawners then
for j = 1, #arena.teams do
spawn_points[j] = {}
end
for team_id, data in pairs(arena.spawn_points) do
for _, spwn in pairs(data) do
table.insert(spawn_points[team_id], {pos = spwn, rot = {x=math.random(0,359), y=0}})
end
end
end
arena.spawn_points = spawn_points
end
minetest.log("action", "[ARENA_LIB] spawn points of arena " .. arena.name ..
" has been converted into the new format")
to_update = true
end
--^------------------ LEGACY UPDATE, to remove in 8.0 -------------------^
--v------------------ LEGACY UPDATE, to remove in 9.0 -------------------v
if update_spawners then
arena.spawn_points = spawn_points
minetest.log("action", "[ARENA_LIB] spawn points of arena " .. arena.name ..
" has been converted into the new format")
to_update = true
end
end
if arena.celestial_vault and arena.celestial_vault.sky and not arena.celestial_vault.sky.fog then
arena.celestial_vault.sky.fog = {}
to_update = true

View File

@ -51,13 +51,24 @@ function arena_lib.load_arena(mod, arena_ID)
for pl_name, pl_data in pairs(arena.players) do
operations_before_entering_arena(mod_ref, mod, arena, arena_ID, pl_name)
-- teletrasporto
local player = minetest.get_player_by_name(pl_name)
local spawner
-- teletrasporto e ruoto
if not arena.teams_enabled then
minetest.get_player_by_name(pl_name):set_pos(shuffled_spawners[count])
spawner = shuffled_spawners[count]
player:set_pos(spawner.pos)
player:set_look_horizontal(math.rad(spawner.rot.x))
player:set_look_vertical(math.rad(spawner.rot.y))
count = count == #shuffled_spawners and 1 or count + 1
else
local team_ID = pl_data.teamID
minetest.get_player_by_name(pl_name):set_pos(shuffled_spawners[team_ID][count[team_ID]])
spawner = shuffled_spawners[team_ID][count[team_ID]]
player:set_pos(spawner.pos)
player:set_look_horizontal(math.rad(spawner.rot.x))
player:set_look_vertical(math.rad(spawner.rot.y))
count[team_ID] = count[team_ID] == #shuffled_spawners[team_ID] and 1 or count[team_ID] + 1
end
end

View File

@ -77,8 +77,8 @@ end
function arena_lib.get_random_spawner(arena, team_ID)
if arena.teams_enabled then
return arena.spawn_points[team_ID][math.random(1, table.maxn(arena.spawn_points[team_ID]))]
return arena.spawn_points[team_ID][math.random(1, table.maxn(arena.spawn_points[team_ID]))].pos
else
return arena.spawn_points[math.random(1,table.maxn(arena.spawn_points))]
return arena.spawn_points[math.random(1,table.maxn(arena.spawn_points))].pos
end
end

View File

@ -161,11 +161,11 @@ function arena_lib.enter_editor(sender, mod, arena_name)
if spawners_amount > 0 then
if not arena.teams_enabled then
tp_coords = arena.spawn_points[1]
tp_coords = arena.spawn_points[1].pos
else
for i = 1, #arena.teams do
if next(arena.spawn_points[i]) then
tp_coords = arena.spawn_points[i][1]
tp_coords = arena.spawn_points[i][1].pos
break
end
end

View File

@ -29,7 +29,7 @@ local spawners_tools_noteam = {
minetest.register_tool("arena_lib:spawner_add", {
description = S("Add spawner"),
description = S("Add spawner)"),
inventory_image = "arenalib_tool_spawner_add.png",
groups = {not_in_creative_inventory = 1},
on_place = function() end,
@ -39,7 +39,7 @@ minetest.register_tool("arena_lib:spawner_add", {
local mod = user:get_meta():get_string("arena_lib_editor.mod")
local arena_name = user:get_meta():get_string("arena_lib_editor.arena")
arena_lib.set_spawner(user:get_player_name(), mod, arena_name, nil, nil, nil, true)
arena_lib.set_spawner(user:get_player_name(), mod, arena_name, nil, nil, nil, nil, true)
end
})
@ -56,7 +56,7 @@ minetest.register_tool("arena_lib:spawner_remove", {
local mod = user:get_meta():get_string("arena_lib_editor.mod")
local arena_name = user:get_meta():get_string("arena_lib_editor.arena")
arena_lib.set_spawner(user:get_player_name(), mod, arena_name, nil, "delete", nil, true)
arena_lib.set_spawner(user:get_player_name(), mod, arena_name, nil, "delete", nil, nil, true)
end
})
@ -75,7 +75,7 @@ minetest.register_tool("arena_lib:spawner_team_add", {
local arena_name = user:get_meta():get_string("arena_lib_editor.arena")
local team_ID = user:get_meta():get_int("arena_lib_editor.team_ID")
arena_lib.set_spawner(user:get_player_name(), mod, arena_name, team_ID, nil, nil, true)
arena_lib.set_spawner(user:get_player_name(), mod, arena_name, team_ID, nil, nil, nil, true)
end
})
@ -94,7 +94,7 @@ minetest.register_tool("arena_lib:spawner_team_remove", {
local arena_name = user:get_meta():get_string("arena_lib_editor.arena")
local team_ID = user:get_meta():get_int("arena_lib_editor.team_ID")
arena_lib.set_spawner(user:get_player_name(), mod, arena_name, team_ID, "delete", nil, true)
arena_lib.set_spawner(user:get_player_name(), mod, arena_name, team_ID, "delete", nil, nil, true)
end
})
@ -141,7 +141,7 @@ minetest.register_tool("arena_lib:spawner_deleteall", {
local arena_name = user:get_meta():get_string("arena_lib_editor.arena")
local p_name = user:get_player_name()
arena_lib.set_spawner(p_name, mod, arena_name, nil, "deleteall", nil, true)
arena_lib.set_spawner(p_name, mod, arena_name, nil, "deleteall", nil, nil, true)
end
})
@ -161,7 +161,7 @@ minetest.register_tool("arena_lib:spawner_team_deleteall", {
local team_ID = user:get_meta():get_int("arena_lib_editor.team_ID")
local p_name = user:get_player_name()
arena_lib.set_spawner(p_name, mod, arena_name, team_ID, "deleteall", nil, true)
arena_lib.set_spawner(p_name, mod, arena_name, team_ID, "deleteall", nil, nil, true)
end
})

View File

@ -16,24 +16,24 @@ function arena_lib.show_waypoints(p_name, mod, arena)
minetest.after(0.1, function()
-- punti rinascita
if not arena.teams_enabled then
for ID, pos in pairs(arena.spawn_points) do
for ID, spwn in pairs(arena.spawn_points) do
local HUD_ID = player:hud_add({
name = "#" .. ID,
hud_elem_type = "waypoint",
precision = 0,
world_pos = pos
world_pos = spwn.pos
})
table.insert(waypoints[p_name], HUD_ID)
end
else
for i = 1, #arena.teams do
for ID, pos in pairs(arena.spawn_points[i]) do
for ID, spwn in pairs(arena.spawn_points[i]) do
local HUD_ID = player:hud_add({
name = "#" .. ID .. ", " .. arena.teams[i].name,
hud_elem_type = "waypoint",
precision = 0,
world_pos = pos
world_pos = spwn.pos
})
table.insert(waypoints[p_name], HUD_ID)

View File

@ -196,15 +196,15 @@ function arena_lib.print_arena_info(sender, mod, arena_name)
for team_ID = 1, #arena.teams do
spawners_pos = spawners_pos .. arena.teams[team_ID].name .. ": "
for _, pos in pairs(arena.spawn_points[team_ID]) do
spawners_pos = spawners_pos .. " " .. minetest.pos_to_string(pos) .. " "
for _, spwn in pairs(arena.spawn_points[team_ID]) do
spawners_pos = spawners_pos .. " " .. minetest.pos_to_string(spwn.pos) .. " "
end
spawners_pos = spawners_pos .. "; "
end
else
for _, pos in pairs(arena.spawn_points) do
spawners_pos = spawners_pos .. " " .. minetest.pos_to_string(pos) .. " "
for _, spwn in pairs(arena.spawn_points) do
spawners_pos = spawners_pos .. " " .. minetest.pos_to_string(spwn.pos) .. " "
end
end

View File

@ -139,7 +139,7 @@ function assign_team(arena, p_name)
-- (es. 2, 3, 5 | 4 => 4, 2 + 3, 3)
if not arena.in_game and sorted_teams[1].amount > 0 then
if sorted_teams[2].amount < #parties.get_party_members(p_name, true) then
for pl_name, pl_data in pairs(arena.players) do
for _, pl_data in pairs(arena.players) do
if pl_data.teamID == sorted_teams[1].ID then
pl_data.teamID = pl_data.teamID + 1
end