parent
bb44b3bd9f
commit
244d272379
21
DOCS.md
21
DOCS.md
|
@ -122,8 +122,10 @@ To customise your mod even more, there are a few empty callbacks you can use. Th
|
||||||
* `arena_lib.on_end(mod, function(arena, players, winners, spectators, is_forced))`: same as above. Players and spectators are given here because `end_arena` deleted them already - hence these are a copy. `is_forced` returns `true` when the match has been forcibly terminated (via `force_arena_ending`)
|
* `arena_lib.on_end(mod, function(arena, players, winners, spectators, is_forced))`: same as above. Players and spectators are given here because `end_arena` deleted them already - hence these are a copy. `is_forced` returns `true` when the match has been forcibly terminated (via `force_arena_ending`)
|
||||||
* `arena_lib.on_join(mod, function(p_name, arena, as_spectator))`: called when a player joins an ongoing match. If `as_spectator` is true, they'll be added as such
|
* `arena_lib.on_join(mod, function(p_name, arena, as_spectator))`: called when a player joins an ongoing match. If `as_spectator` is true, they'll be added as such
|
||||||
* `arena_lib.on_death(mod, function(arena, p_name, reason))`: called when a player dies
|
* `arena_lib.on_death(mod, function(arena, p_name, reason))`: called when a player dies
|
||||||
* `arena_lib.on_change_spectated_target(mod, function(arena, sp_name, target, prev_target))`: called when a spectator (`sp_name`) changes who or what they're spectating, including when they get assigned someone to spectate at entering the arena.
|
* `arena_lib.on_change_spectated_target(mod, function(arena, sp_name, t_type, t_name, prev_type, prev_spectated))`: called when a spectator (`sp_name`) changes who or what they're spectating, including when they get assigned someone to spectate at entering the arena.
|
||||||
* `target` can only be the player name for now, the same goes for `prev_target` (if any). Entities and locations will be hopefully added in the future
|
* `t_type` represents the type of the target (either `"player"`, `"entity"` or `"area"`)
|
||||||
|
* `t_name` its name. If it's an entity or an area, it'll be the name used to register it through the `arena_lib.add_spectate...` functions
|
||||||
|
* if they were following someone/something else earlier, `prev_type` and `prev_spectated` follow the same logic of the aforementioned parameters
|
||||||
* Beware: as this gets called also when entering, keep in mind that it gets called before the `on_join` callback
|
* Beware: as this gets called also when entering, keep in mind that it gets called before the `on_join` callback
|
||||||
* `arena_lib.on_time_tick(mod, function(arena))`: called every second if `time_mode` is different from `"none"`
|
* `arena_lib.on_time_tick(mod, function(arena))`: called every second if `time_mode` is different from `"none"`
|
||||||
* `arena_lib.on_timeout(mod, function(arena))`: called when the timer of an arena, if exists (`time_mode = "decremental"`), reaches 0. Not declaring it will make the server crash when time runs out
|
* `arena_lib.on_timeout(mod, function(arena))`: called when the timer of an arena, if exists (`time_mode = "decremental"`), reaches 0. Not declaring it will make the server crash when time runs out
|
||||||
|
@ -236,11 +238,14 @@ There are also some other functions which might turn useful. They are:
|
||||||
Default is 0 and these are mostly hardcoded in arena_lib already, so it's advised to not touch it and to use callbacks. The only exception is in case of manual elimination (i.e. in a murder minigame, so reason = 1).
|
Default is 0 and these are mostly hardcoded in arena_lib already, so it's advised to not touch it and to use callbacks. The only exception is in case of manual elimination (i.e. in a murder minigame, so reason = 1).
|
||||||
Executioner can be passed to tell who removed the player. By default, this happens when someone uses `/arenakick` and `/forceend`, so that these commands can't be abused without consequences for the admin.
|
Executioner can be passed to tell who removed the player. By default, this happens when someone uses `/arenakick` and `/forceend`, so that these commands can't be abused without consequences for the admin.
|
||||||
* `arena_lib.send_message_in_arena(arena, channel, msg, <teamID>, <except_teamID>)`: sends a message to all the players/spectators in that specific arena, according to what `channel` is: `"players"`, `"spectators"` or `"both"`. If `teamID` is specified, it'll be only sent to the players inside that very team. On the contrary, if `except_teamID` is `true`, it'll be sent to every player BUT the ones in the specified team. These last two fields are pointless if `channel` is equal to `"spectators"`
|
* `arena_lib.send_message_in_arena(arena, channel, msg, <teamID>, <except_teamID>)`: sends a message to all the players/spectators in that specific arena, according to what `channel` is: `"players"`, `"spectators"` or `"both"`. If `teamID` is specified, it'll be only sent to the players inside that very team. On the contrary, if `except_teamID` is `true`, it'll be sent to every player BUT the ones in the specified team. These last two fields are pointless if `channel` is equal to `"spectators"`
|
||||||
* `arena_lib.add_spectable_target(mod, arena_name, t_type, t_name, target)`: adds to the current ongoing match a spectable target, allowing spectators to spectate more than just players. `t_type` indicates the target type, and for now can only be `"entity"`. `t_name` is the name that will appear in the spectator info hotbar, and `target` is the entity itself. When the entity is removed/unloaded, automatically calls `remove_spectable_target(...)`
|
* `arena_lib.add_spectate_entity(mod, arena, e_name, entity)`: adds to the current ongoing match a spectatable entity, allowing spectators to spectate more than just players. `e_name` is the name that will appear in the spectator info hotbar, and `entity` the `luaentity` table. When the entity is removed/unloaded, automatically calls `remove_spectate_entity(...)`
|
||||||
* `arena_lib.remove_spectable_target(mod, arena_name, t_type, t_name)`: removes a target from the spectable targets of an ongoing match
|
* `arena_lib.add_spectate_area(mod, arena, pos_name, pos)`: same as `add_spectate_entity`, but it adds an area instead. `pos` is a table containing the coordinates of the area to spectate
|
||||||
|
* `arena_lib.remove_spectate_entity(mod, arena, e_name)`: removes an entity from the spectatable entities of an ongoing match
|
||||||
|
* `arena_lib.remove_spectate_area(mod, arena, pos_name)`: removes an area from the spectatable areas of an ongoing match
|
||||||
* `arena_lib.is_player_spectating(sp_name)`: returns whether a player is spectating a match, as a boolean
|
* `arena_lib.is_player_spectating(sp_name)`: returns whether a player is spectating a match, as a boolean
|
||||||
* `arena_lib.is_player_spectated(p_name)`: returns whether a player is being spectated
|
* `arena_lib.is_player_spectated(p_name)`: returns whether a player is being spectated
|
||||||
* `arena_lib.is_entity_spectated(mod, arena_name, e_name)`: returns whether an entity is being spectated
|
* `arena_lib.is_entity_spectated(mod, arena_name, e_name)`: returns whether an entity is being spectated
|
||||||
|
* `arena_lib.is_area_spectated(mod, arena_name, pos_name)`: returns whether an area is being spectated
|
||||||
* `arena_lib.is_arena_in_edit_mode(arena_name)`: returns whether the arena is in edit mode or not, as a boolean
|
* `arena_lib.is_arena_in_edit_mode(arena_name)`: returns whether the arena is in edit mode or not, as a boolean
|
||||||
* `arena_lib.is_player_in_edit_mode(p_name)`: returns whether a player is editing an arena, as a boolean
|
* `arena_lib.is_player_in_edit_mode(p_name)`: returns whether a player is editing an arena, as a boolean
|
||||||
|
|
||||||
|
@ -258,8 +263,8 @@ Executioner can be passed to tell who removed the player. By default, this happe
|
||||||
* `arena_lib.get_active_teams(arena)`: returns an ordered table having as values the ID of teams that are not empty
|
* `arena_lib.get_active_teams(arena)`: returns an ordered table having as values the ID of teams that are not empty
|
||||||
* `arena_lib.get_player_spectators(p_name)`: returns a list containing all the people currently spectating `p_name`. Format `{sp_name = true}`
|
* `arena_lib.get_player_spectators(p_name)`: returns a list containing all the people currently spectating `p_name`. Format `{sp_name = true}`
|
||||||
* `arena_lib.get_player_spectated(sp_name)`: returns the player `sp_name` is currently spectating, if any
|
* `arena_lib.get_player_spectated(sp_name)`: returns the player `sp_name` is currently spectating, if any
|
||||||
* `arena_lib.get_spectable_entities(mod, arena_name)`: returns a table containing all the spectable entities of `arena_name`, if any. Format `{e_name = entity}`, where `e_name` is the name used to register the entity in `add_spectable_target(...)`
|
* `arena_lib.get_spectate_entities(mod, arena_name)`: returns a table containing all the spectatable entities of `arena_name`, if any. Format `{e_name = entity}`, where `e_name` is the name used to register the entity in `add_spectate_entity(...)` and `entity` the `luaentity` table
|
||||||
* `arena_lib.get_spectable_entities_amount(mod, arena_name)`: returns the amount of spectable entities currently present in `arena_name`, if any
|
* `arena_lib.get_spectate_areas(mod, arena_name)`: same as in `get_spectate_entities(...)` but for areas. Entities returned in the table are the dummy ObjectRef entities put at the area coordinates
|
||||||
* `arena_lib.get_player_in_edit_mode(arena_name)`: returns the name of the player who's editing `arena_name`, if any
|
* `arena_lib.get_player_in_edit_mode(arena_name)`: returns the name of the player who's editing `arena_name`, if any
|
||||||
|
|
||||||
### 1.10 Things you don't want to do with a light heart
|
### 1.10 Things you don't want to do with a light heart
|
||||||
|
@ -290,6 +295,8 @@ An arena is a table having as a key an ID and as a value its parameters. They ar
|
||||||
* `players_amount_per_team`: (table) separately stores how many players currently are in a given team. Format `{[teamID] = amount}`. If teams are disabled, it's `nil`
|
* `players_amount_per_team`: (table) separately stores how many players currently are in a given team. Format `{[teamID] = amount}`. If teams are disabled, it's `nil`
|
||||||
* `spectators_amount`: (int) separately stores how many spectators are inside the arena
|
* `spectators_amount`: (int) separately stores how many spectators are inside the arena
|
||||||
* `spectators_amount_per_team`: (table) like `players_amount_per_team`, but for spectators
|
* `spectators_amount_per_team`: (table) like `players_amount_per_team`, but for spectators
|
||||||
|
* `spectate_entities_amount`: (int) the amount of entities that can be currently spectated in an ongoing game. If spectate mode is disabled, it's `nil`. Outside of ongoing games is always `nil`
|
||||||
|
* `spectate_areas_amount`: (int) like `spectate_entities_amount` but for areas
|
||||||
* `spawn_points`: (table) contains information about the spawn points. Format `{[spawnID] = {pos = coords, teamID = team ID}}`. If teams are disabled, `teamID` is `nil`
|
* `spawn_points`: (table) contains information about the spawn points. Format `{[spawnID] = {pos = coords, teamID = team ID}}`. If teams are disabled, `teamID` is `nil`
|
||||||
* `max_players`: (string) default is 4. When this value is reached, queue time decreases to 5 if it's not lower already
|
* `max_players`: (string) default is 4. When this value is reached, queue time decreases to 5 if it's not lower already
|
||||||
* `min_players`: (string) default is 2. When this value is reached, a queue starts
|
* `min_players`: (string) default is 2. When this value is reached, a queue starts
|
||||||
|
@ -466,7 +473,7 @@ An arena comes in 4 phases:
|
||||||
|
|
||||||
### 2.4 Spectate mode
|
### 2.4 Spectate mode
|
||||||
Every minigame has this mode enabled by default. As the name suggests, it allows people to spectate a match, and there are two ways to enter this mode: the first is by getting eliminated (`remove_player_from_arena` with `1` as a reason), while the other is through the very sign of the arena. In this last case, users just need to right-click the sign and press the "eye" button to be turned into spectators (a game must be in progress). While in this state, they can't interact in any way with the actual match: neither by hitting entities/blocks, nor by writing in chat. The latter, more precisely, is a separated chat that spectators and spectators only are able to read. Vice versa, they're not able to read the players one.
|
Every minigame has this mode enabled by default. As the name suggests, it allows people to spectate a match, and there are two ways to enter this mode: the first is by getting eliminated (`remove_player_from_arena` with `1` as a reason), while the other is through the very sign of the arena. In this last case, users just need to right-click the sign and press the "eye" button to be turned into spectators (a game must be in progress). While in this state, they can't interact in any way with the actual match: neither by hitting entities/blocks, nor by writing in chat. The latter, more precisely, is a separated chat that spectators and spectators only are able to read. Vice versa, they're not able to read the players one.
|
||||||
By default, spectate mode allows to follow players, but it also allows modders to expand it to entities and (not currently implemented) areas. To do that, have a look at `arena_lib.add_spectable_target(...)`
|
By default, spectate mode allows to follow players, but it also allows modders to expand it to entities and areas. To do that, have a look at `arena_lib.add_spectate_entity(...)` and `arena_lib.add_spectate_area(...)`
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## 3. About the author(s)
|
## 3. About the author(s)
|
||||||
|
|
1
init.lua
1
init.lua
|
@ -28,6 +28,7 @@ dofile(srcpath .. "/editor/tools_sky.lua")
|
||||||
dofile(srcpath .. "/editor/tools_spawner.lua")
|
dofile(srcpath .. "/editor/tools_spawner.lua")
|
||||||
dofile(srcpath .. "/hud/hud_main.lua")
|
dofile(srcpath .. "/hud/hud_main.lua")
|
||||||
dofile(srcpath .. "/hud/hud_waypoints.lua")
|
dofile(srcpath .. "/hud/hud_waypoints.lua")
|
||||||
|
dofile(srcpath .. "/spectate/spectate_dummy.lua")
|
||||||
dofile(srcpath .. "/spectate/spectate_main.lua")
|
dofile(srcpath .. "/spectate/spectate_main.lua")
|
||||||
dofile(srcpath .. "/spectate/spectate_hand.lua")
|
dofile(srcpath .. "/spectate/spectate_hand.lua")
|
||||||
dofile(srcpath .. "/spectate/spectate_tools.lua")
|
dofile(srcpath .. "/spectate/spectate_tools.lua")
|
||||||
|
|
|
@ -286,4 +286,5 @@ Currently spectating: @1=Stai seguendo: @1
|
||||||
Change player=Cambia giocatore
|
Change player=Cambia giocatore
|
||||||
Change team=Cambia squadra
|
Change team=Cambia squadra
|
||||||
Change entity=Cambia entità
|
Change entity=Cambia entità
|
||||||
|
Change area=Cambia area
|
||||||
Enter the match=Entra in partita
|
Enter the match=Entra in partita
|
||||||
|
|
|
@ -286,4 +286,5 @@ Currently spectating: @1=
|
||||||
Change player=
|
Change player=
|
||||||
Change team=
|
Change team=
|
||||||
Change entity=
|
Change entity=
|
||||||
|
Change area=
|
||||||
Enter the match=
|
Enter the match=
|
||||||
|
|
|
@ -34,6 +34,8 @@ local arena_default = {
|
||||||
players_amount_per_team = nil,
|
players_amount_per_team = nil,
|
||||||
spectators_amount = 0,
|
spectators_amount = 0,
|
||||||
spectators_amount_per_team = nil,
|
spectators_amount_per_team = nil,
|
||||||
|
spectate_entities_amount = nil,
|
||||||
|
spectate_areas_amount = nil,
|
||||||
spawn_points = {}, -- KEY: ids, VALUE: {pos, teamID}
|
spawn_points = {}, -- KEY: ids, VALUE: {pos, teamID}
|
||||||
max_players = 4,
|
max_players = 4,
|
||||||
min_players = 2,
|
min_players = 2,
|
||||||
|
|
|
@ -88,6 +88,8 @@ function arena_lib.load_arena(mod, arena_ID)
|
||||||
|
|
||||||
-- se supporta la spettatore, inizializzo le varie tabelle
|
-- se supporta la spettatore, inizializzo le varie tabelle
|
||||||
if mod_ref.spectate_mode then
|
if mod_ref.spectate_mode then
|
||||||
|
arena.spectate_entities_amount = 0
|
||||||
|
arena.spectate_areas_amount = 0
|
||||||
arena_lib.init_spectate_containers(mod, arena.name)
|
arena_lib.init_spectate_containers(mod, arena.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -272,7 +274,12 @@ function arena_lib.end_arena(mod_ref, mod, arena, winners, is_forced)
|
||||||
operations_before_leaving_arena(mod_ref, arena, pl_name)
|
operations_before_leaving_arena(mod_ref, arena, pl_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
arena_lib.unload_spectate_containers(mod, arena.name)
|
-- dealloca eventuale modalità spettatore
|
||||||
|
if mod_ref.spectate_mode then
|
||||||
|
arena.spectate_entities_amount = nil
|
||||||
|
arena.spectate_areas_amount = nil
|
||||||
|
arena_lib.unload_spectate_containers(mod, arena.name)
|
||||||
|
end
|
||||||
|
|
||||||
-- azzerramento giocatori e spettatori
|
-- azzerramento giocatori e spettatori
|
||||||
arena.past_present_players = {}
|
arena.past_present_players = {}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
-- used for areas
|
||||||
|
local dummy = {
|
||||||
|
initial_properties = {
|
||||||
|
physical = false,
|
||||||
|
visual = "sprite",
|
||||||
|
visual_size = {x = 0, y = 0, z = 0},
|
||||||
|
collisionbox = {0, 0, 0, 0, 0, 0},
|
||||||
|
|
||||||
|
textures = { "blank.png" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
minetest.register_entity("arena_lib:spectate_dummy", dummy)
|
|
@ -6,9 +6,10 @@ local function set_spectator() end
|
||||||
local players_in_spectate_mode = {} -- KEY: player name, VALUE: {(string) minigame, (int) arenaID, (string) type, (string) spectating}
|
local players_in_spectate_mode = {} -- KEY: player name, VALUE: {(string) minigame, (int) arenaID, (string) type, (string) spectating}
|
||||||
local spectate_temp_storage = {} -- KEY: player_name, VALUE: {(table) camera_offset}
|
local spectate_temp_storage = {} -- KEY: player_name, VALUE: {(table) camera_offset}
|
||||||
local players_spectated = {} -- KEY: player name, VALUE: {(string) spectator(s) = true}
|
local players_spectated = {} -- KEY: player name, VALUE: {(string) spectator(s) = true}
|
||||||
local entities_spectated = {} -- KEY: [mod][arena][entity name], VALUE: {(string) spectator(s) = true}
|
local entities_spectated = {} -- KEY: [mod][arena_name][entity name], VALUE: {(string) spectator(s) = true}
|
||||||
local areas_spectated = {}
|
local areas_spectated = {} -- KEY: [mod][arena_name][area_name], VALUE: {(string) spectator(s) = true}
|
||||||
local entities_storage = {} -- KEY: [mod][arena][entity_name], VALUE: entity
|
local entities_storage = {} -- KEY: [mod][arena_name][entity_name], VALUE: entity
|
||||||
|
local areas_storage = {} -- KEY: [mod][arena_name][area_name], VALUE: dummy entity
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,18 +32,29 @@ function arena_lib.init_spectate_containers(mod, arena_name)
|
||||||
if not entities_storage[mod] then
|
if not entities_storage[mod] then
|
||||||
entities_storage[mod] = {}
|
entities_storage[mod] = {}
|
||||||
end
|
end
|
||||||
|
if not areas_storage[mod] then
|
||||||
|
areas_storage[mod] = {}
|
||||||
|
end
|
||||||
|
|
||||||
entities_spectated[mod][arena_name] = {}
|
entities_spectated[mod][arena_name] = {}
|
||||||
areas_spectated[mod][arena_name] = {}
|
areas_spectated[mod][arena_name] = {}
|
||||||
entities_storage[mod][arena_name] = {}
|
entities_storage[mod][arena_name] = {}
|
||||||
|
areas_storage[mod][arena_name] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function arena_lib.unload_spectate_containers(mod, arena_name)
|
function arena_lib.unload_spectate_containers(mod, arena_name)
|
||||||
entities_spectated[mod][arena_name] = nil -- non c'è bisogno di cancellare X[mod], al massimo rimangono vuote
|
-- rimuovo tutte le entità fantoccio delle aree
|
||||||
|
for _, dummy_entity in pairs(arena_lib.get_spectate_areas(mod, arena_name)) do
|
||||||
|
dummy_entity:remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- non c'è bisogno di cancellare X[mod], al massimo rimangono vuote
|
||||||
|
entities_spectated[mod][arena_name] = nil
|
||||||
areas_spectated[mod][arena_name] = nil
|
areas_spectated[mod][arena_name] = nil
|
||||||
entities_storage[mod][arena_name] = nil
|
entities_storage[mod][arena_name] = nil
|
||||||
|
areas_storage[mod][arena_name] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,10 +70,9 @@ function arena_lib.remove_spectate_p_container(p_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
----------------------------------------------
|
-- entering / leaving
|
||||||
---------------------CORE---------------------
|
----------------------------
|
||||||
----------------------------------------------
|
|
||||||
|
|
||||||
function arena_lib.enter_spectate_mode(p_name, arena)
|
function arena_lib.enter_spectate_mode(p_name, arena)
|
||||||
|
|
||||||
|
@ -213,94 +224,9 @@ end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function arena_lib.add_spectable_target(mod, arena_name, t_type, t_name, target)
|
----------------------------
|
||||||
|
-- find next spectatatable target
|
||||||
local arena_ID, arena = arena_lib.get_arena_by_name(mod, arena_name)
|
----------------------------
|
||||||
|
|
||||||
if not arena.in_game then return end
|
|
||||||
|
|
||||||
if t_type == "entity" then
|
|
||||||
local old_deact = target.on_deactivate
|
|
||||||
|
|
||||||
-- aggiungo sull'on_deactivate la funzione per rimuoverla dalla spettatore
|
|
||||||
target.on_deactivate = function(...)
|
|
||||||
local ret = old_deact and old_deact(...)
|
|
||||||
|
|
||||||
arena_lib.remove_spectable_target(mod, arena_name, t_type, t_name)
|
|
||||||
|
|
||||||
return ret
|
|
||||||
end
|
|
||||||
|
|
||||||
-- la aggiungo
|
|
||||||
entities_spectated[mod][arena_name][t_name] = {}
|
|
||||||
entities_storage[mod][arena_name][t_name] = target
|
|
||||||
|
|
||||||
-- se è l'unica entità registrata, aggiungo lo slot per seguire le entità
|
|
||||||
if arena_lib.get_spectable_entities_amount(mod, arena_name) == 1 then
|
|
||||||
for sp_name, _ in pairs(arena.spectators) do
|
|
||||||
override_hotbar(minetest.get_player_by_name(sp_name), mod, arena)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif t_type == "area" then
|
|
||||||
-- TODO registrare aree
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function arena_lib.remove_spectable_target(mod, arena_name, t_type, t_name)
|
|
||||||
|
|
||||||
local arenaID, arena = arena_lib.get_arena_by_name(mod, arena_name)
|
|
||||||
|
|
||||||
-- se l'entità viene rimossa quando la partita è già finita, interrompi o crasha
|
|
||||||
if not arena.in_game then return end
|
|
||||||
|
|
||||||
if t_type == "entity" then
|
|
||||||
entities_storage[mod][arena_name][t_name] = nil
|
|
||||||
|
|
||||||
-- se non ci sono più entità, fai sparire l'icona
|
|
||||||
if not next(entities_storage[mod][arena_name]) then
|
|
||||||
for sp_name, _ in pairs(arena.spectators) do
|
|
||||||
local spectator = minetest.get_player_by_name(sp_name)
|
|
||||||
override_hotbar(spectator, mod, arena)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for sp_name, _ in pairs(entities_spectated[mod][arena_name][t_name]) do
|
|
||||||
arena_lib.find_and_spectate_entity(mod, arena_name, sp_name)
|
|
||||||
end
|
|
||||||
elseif t_type == "area" then
|
|
||||||
--TODO
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------
|
|
||||||
--------------------UTILS---------------------
|
|
||||||
----------------------------------------------
|
|
||||||
|
|
||||||
function arena_lib.is_player_spectating(sp_name)
|
|
||||||
return players_in_spectate_mode[sp_name] ~= nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function arena_lib.is_player_spectated(p_name)
|
|
||||||
return players_spectated[p_name] and next(players_spectated[p_name])
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function arena_lib.is_entity_spectated(mod, arena_name, e_name)
|
|
||||||
return entities_spectated[mod][arena_name][e_name] and next(entities_spectated[mod][arena_name][e_name])
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function arena_lib.find_and_spectate_player(sp_name, change_team)
|
function arena_lib.find_and_spectate_player(sp_name, change_team)
|
||||||
|
|
||||||
|
@ -365,6 +291,7 @@ function arena_lib.find_and_spectate_player(sp_name, change_team)
|
||||||
|
|
||||||
local watching_ID = spectator:get_meta():get_int("arenalib_watchID")
|
local watching_ID = spectator:get_meta():get_int("arenalib_watchID")
|
||||||
local new_ID = players_amount <= watching_ID and 1 or watching_ID + 1
|
local new_ID = players_amount <= watching_ID and 1 or watching_ID + 1
|
||||||
|
local mod = arena_lib.get_mod_by_player(sp_name)
|
||||||
|
|
||||||
-- trovo il giocatore da seguire
|
-- trovo il giocatore da seguire
|
||||||
-- squadre:
|
-- squadre:
|
||||||
|
@ -373,7 +300,7 @@ function arena_lib.find_and_spectate_player(sp_name, change_team)
|
||||||
for i = 1, #players_team do
|
for i = 1, #players_team do
|
||||||
|
|
||||||
if i == new_ID then
|
if i == new_ID then
|
||||||
set_spectator(spectator, "player", players_team[i], i)
|
set_spectator(mod, arena_name, spectator, "player", players_team[i], i)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -384,7 +311,7 @@ function arena_lib.find_and_spectate_player(sp_name, change_team)
|
||||||
for pl_name, _ in pairs(arena.players) do
|
for pl_name, _ in pairs(arena.players) do
|
||||||
|
|
||||||
if i == new_ID then
|
if i == new_ID then
|
||||||
set_spectator(spectator, "player", pl_name, i)
|
set_spectator(mod, arena.name, spectator, "player", pl_name, i)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -395,14 +322,16 @@ end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function arena_lib.find_and_spectate_entity(mod, arena_name, sp_name)
|
function arena_lib.find_and_spectate_entity(mod, arena, sp_name)
|
||||||
|
|
||||||
|
local e_amount = arena.spectate_entities_amount
|
||||||
|
|
||||||
-- se non ci sono entità da seguire, segui un giocatore
|
-- se non ci sono entità da seguire, segui un giocatore
|
||||||
if not next(entities_storage[mod][arena_name]) then
|
if e_amount == 0 then
|
||||||
arena_lib.find_and_spectate_player(sp_name)
|
arena_lib.find_and_spectate_player(sp_name)
|
||||||
return end
|
return end
|
||||||
|
|
||||||
local e_amount = arena_lib.get_spectable_entities_amount(mod, arena_name)
|
local arena_name = arena.name
|
||||||
local prev_spectated = players_in_spectate_mode[sp_name].spectating
|
local prev_spectated = players_in_spectate_mode[sp_name].spectating
|
||||||
|
|
||||||
-- se è l'unica entità rimasta e la si stava già seguendo
|
-- se è l'unica entità rimasta e la si stava già seguendo
|
||||||
|
@ -419,10 +348,10 @@ function arena_lib.find_and_spectate_entity(mod, arena_name, sp_name)
|
||||||
local new_ID = e_amount <= current_ID and 1 or current_ID + 1
|
local new_ID = e_amount <= current_ID and 1 or current_ID + 1
|
||||||
local i = 1
|
local i = 1
|
||||||
|
|
||||||
for en_name, _ in pairs(entities_spectated[mod][arena_name]) do
|
for en_name, _ in pairs(entities_storage[mod][arena_name]) do
|
||||||
|
|
||||||
if i == new_ID then
|
if i == new_ID then
|
||||||
set_spectator(spectator, "entity", en_name, i)
|
set_spectator(mod, arena_name, spectator, "entity", en_name, i)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -432,6 +361,183 @@ end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function arena_lib.find_and_spectate_area(mod, arena, sp_name)
|
||||||
|
|
||||||
|
local ar_amount = arena.spectate_areas_amount
|
||||||
|
|
||||||
|
-- se non ci sono aree da seguire, segui un giocatore
|
||||||
|
if ar_amount == 0 then
|
||||||
|
arena_lib.find_and_spectate_player(sp_name)
|
||||||
|
return end
|
||||||
|
|
||||||
|
local arena_name = arena.name
|
||||||
|
local prev_spectated = players_in_spectate_mode[sp_name].spectating
|
||||||
|
|
||||||
|
-- se è l'unica area rimasta e la si stava già seguendo
|
||||||
|
if ar_amount == 1 and prev_spectated and next(areas_spectated[mod][arena_name])[sp_name] then
|
||||||
|
return end
|
||||||
|
|
||||||
|
local spectator = minetest.get_player_by_name(sp_name)
|
||||||
|
|
||||||
|
if players_in_spectate_mode[sp_name].type ~= "area" then
|
||||||
|
spectator:get_meta():set_int("arenalib_watchID", 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local current_ID = spectator:get_meta():get_int("arenalib_watchID")
|
||||||
|
local new_ID = ar_amount <= current_ID and 1 or current_ID + 1
|
||||||
|
local i = 1
|
||||||
|
|
||||||
|
for pos_name, _ in pairs(areas_storage[mod][arena_name]) do
|
||||||
|
|
||||||
|
if i == new_ID then
|
||||||
|
set_spectator(mod, arena_name, spectator, "area", pos_name, i)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
i = i +1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------
|
||||||
|
---------------------CORE---------------------
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function arena_lib.add_spectate_entity(mod, arena, e_name, entity)
|
||||||
|
|
||||||
|
if not arena.in_game then return end
|
||||||
|
|
||||||
|
local arena_name = arena.name
|
||||||
|
local old_deact = entity.on_deactivate
|
||||||
|
|
||||||
|
-- aggiungo sull'on_deactivate la funzione per rimuoverla dalla spettatore
|
||||||
|
entity.on_deactivate = function(...)
|
||||||
|
local ret = old_deact and old_deact(...)
|
||||||
|
|
||||||
|
arena_lib.remove_spectate_entity(mod, arena, e_name)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
-- la aggiungo
|
||||||
|
entities_spectated[mod][arena_name][e_name] = {}
|
||||||
|
entities_storage[mod][arena_name][e_name] = entity
|
||||||
|
arena.spectate_entities_amount = arena.spectate_entities_amount + 1
|
||||||
|
|
||||||
|
-- se è l'unica entità registrata, aggiungo lo slot per seguire le entità
|
||||||
|
if arena.spectate_entities_amount == 1 then
|
||||||
|
for sp_name, _ in pairs(arena.spectators) do
|
||||||
|
override_hotbar(minetest.get_player_by_name(sp_name), mod, arena)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function arena_lib.add_spectate_area(mod, arena, pos_name, pos)
|
||||||
|
|
||||||
|
if not arena.in_game then return end
|
||||||
|
|
||||||
|
minetest.forceload_block(pos, true)
|
||||||
|
|
||||||
|
local dummy_entity = minetest.add_entity(pos, "arena_lib:spectate_dummy")
|
||||||
|
local arena_name = arena.name
|
||||||
|
|
||||||
|
areas_spectated[mod][arena_name][pos_name] = {}
|
||||||
|
areas_storage[mod][arena_name][pos_name] = dummy_entity
|
||||||
|
arena.spectate_areas_amount = arena.spectate_areas_amount + 1
|
||||||
|
|
||||||
|
-- se è l'unica area registrata, aggiungo lo slot per seguire le aree
|
||||||
|
if arena.spectate_areas_amount == 1 then
|
||||||
|
for sp_name, _ in pairs(arena.spectators) do
|
||||||
|
override_hotbar(minetest.get_player_by_name(sp_name), mod, arena)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function arena_lib.remove_spectate_entity(mod, arena, e_name)
|
||||||
|
|
||||||
|
if not arena.in_game then return end -- nel caso il minigioco si sia scordata di cancellarla, all'ucciderla fuori dalla partita non crasha
|
||||||
|
local arena_name = arena.name
|
||||||
|
|
||||||
|
entities_storage[mod][arena_name][e_name] = nil
|
||||||
|
arena.spectate_entities_amount = arena.spectate_entities_amount - 1
|
||||||
|
|
||||||
|
-- se non ci sono più entità, fai sparire l'icona
|
||||||
|
if arena.spectate_entities_amount == 0 then
|
||||||
|
for sp_name, _ in pairs(arena.spectators) do
|
||||||
|
local spectator = minetest.get_player_by_name(sp_name)
|
||||||
|
override_hotbar(spectator, mod, arena)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for sp_name, _ in pairs(entities_spectated[mod][arena_name][e_name]) do
|
||||||
|
arena_lib.find_and_spectate_entity(mod, arena, sp_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function arena_lib.remove_spectate_area(mod, arena, pos_name)
|
||||||
|
|
||||||
|
local arena_name = arena.name
|
||||||
|
|
||||||
|
areas_storage[mod][arena_name][pos_name]:remove()
|
||||||
|
areas_storage[mod][arena_name][pos_name] = nil
|
||||||
|
arena.spectate_areas_amount = arena.spectate_areas_amount - 1
|
||||||
|
|
||||||
|
-- se non ci sono più aree, fai sparire l'icona
|
||||||
|
if arena.spectate_areas_amount == 0 then
|
||||||
|
for sp_name, _ in pairs(arena.spectators) do
|
||||||
|
local spectator = minetest.get_player_by_name(sp_name)
|
||||||
|
override_hotbar(spectator, mod, arena)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for sp_name, _ in pairs(areas_spectated[mod][arena_name][pos_name]) do
|
||||||
|
arena_lib.find_and_spectate_area(mod, arena, sp_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------
|
||||||
|
--------------------UTILS---------------------
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
function arena_lib.is_player_spectating(sp_name)
|
||||||
|
return players_in_spectate_mode[sp_name] ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function arena_lib.is_player_spectated(p_name)
|
||||||
|
return players_spectated[p_name] and next(players_spectated[p_name])
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function arena_lib.is_entity_spectated(mod, arena_name, e_name)
|
||||||
|
return entities_spectated[mod][arena_name][e_name] and next(entities_spectated[mod][arena_name][e_name])
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function arena_lib.is_area_spectated(mod, arena_name, pos_name)
|
||||||
|
return areas_spectated[mod][arena_name][pos_name] and next(areas_spectated[mod][arena_name][pos_name])
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
@ -452,18 +558,14 @@ end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function arena_lib.get_spectable_entities(mod, arena_name)
|
function arena_lib.get_spectate_entities(mod, arena_name)
|
||||||
return entities_storage[mod][arena_name]
|
return entities_storage[mod][arena_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function arena_lib.get_spectable_entities_amount(mod, arena_name)
|
function arena_lib.get_spectate_areas(mod, arena_name)
|
||||||
local i = 0
|
return areas_storage[mod][arena_name]
|
||||||
for k, v in pairs(entities_storage[mod][arena_name]) do
|
|
||||||
i = i + 1
|
|
||||||
end
|
|
||||||
return i
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -474,16 +576,14 @@ end
|
||||||
---------------FUNZIONI LOCALI----------------
|
---------------FUNZIONI LOCALI----------------
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
function set_spectator(spectator, type, name, i)
|
function set_spectator(mod, arena_name, spectator, type, name, i)
|
||||||
|
|
||||||
local sp_name = spectator:get_player_name()
|
local sp_name = spectator:get_player_name()
|
||||||
local mod = arena_lib.get_mod_by_player(sp_name)
|
|
||||||
local arena_name = arena_lib.get_arena_by_player(sp_name).name
|
|
||||||
local prev_spectated = players_in_spectate_mode[sp_name].spectating
|
local prev_spectated = players_in_spectate_mode[sp_name].spectating
|
||||||
|
local prev_type = players_in_spectate_mode[sp_name].type
|
||||||
|
|
||||||
-- se stava già seguendo qualcuno, lo rimuovo da questo
|
-- se stava già seguendo qualcuno, lo rimuovo da questo
|
||||||
if prev_spectated then
|
if prev_spectated then
|
||||||
local prev_type = players_in_spectate_mode[sp_name].type
|
|
||||||
if prev_type == "player" then
|
if prev_type == "player" then
|
||||||
players_spectated[prev_spectated][sp_name] = nil
|
players_spectated[prev_spectated][sp_name] = nil
|
||||||
elseif prev_type == "entity" then
|
elseif prev_type == "entity" then
|
||||||
|
@ -503,14 +603,18 @@ function set_spectator(spectator, type, name, i)
|
||||||
spectator:set_hp(target:get_hp() > 0 and target:get_hp() or 1)
|
spectator:set_hp(target:get_hp() > 0 and target:get_hp() or 1)
|
||||||
|
|
||||||
elseif type == "entity" then
|
elseif type == "entity" then
|
||||||
|
|
||||||
entities_spectated[mod][arena_name][name][sp_name] = true
|
entities_spectated[mod][arena_name][name][sp_name] = true
|
||||||
target = entities_storage[mod][arena_name][name].object
|
target = entities_storage[mod][arena_name][name].object
|
||||||
|
|
||||||
spectator:set_attach(target, "", {x=0, y=-5, z=-20}, {x=0, y=0, z=0})
|
spectator:set_attach(target, "", {x=0, y=-5, z=-20}, {x=0, y=0, z=0})
|
||||||
spectator:set_hp(target:get_hp() > 0 and target:get_hp() or 1)
|
spectator:set_hp(target:get_hp() > 0 and target:get_hp() or 1)
|
||||||
|
|
||||||
elseif type == "area" then
|
elseif type == "area" then
|
||||||
-- TODO
|
areas_spectated[mod][arena_name][name][sp_name] = true
|
||||||
|
target = areas_storage[mod][arena_name][name]
|
||||||
|
|
||||||
|
spectator:set_attach(target, "", {x=0, y=-5, z=-20}, {x=0, y=0, z=0})
|
||||||
|
spectator:set_hp(minetest.PLAYER_MAX_HP_DEFAULT)
|
||||||
end
|
end
|
||||||
|
|
||||||
players_in_spectate_mode[sp_name].spectating = name
|
players_in_spectate_mode[sp_name].spectating = name
|
||||||
|
@ -524,9 +628,7 @@ function set_spectator(spectator, type, name, i)
|
||||||
-- eventuale codice aggiuntivo
|
-- eventuale codice aggiuntivo
|
||||||
if mod_ref.on_change_spectated_target then
|
if mod_ref.on_change_spectated_target then
|
||||||
local arena = arena_lib.get_arena_by_player(sp_name)
|
local arena = arena_lib.get_arena_by_player(sp_name)
|
||||||
target = name
|
mod_ref.on_change_spectated_target(arena, sp_name, type, name, prev_type, prev_spectated)
|
||||||
local prev_target = prev_spectated
|
|
||||||
mod_ref.on_change_spectated_target(arena, sp_name, target, prev_target)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -547,10 +649,14 @@ function override_hotbar(player, mod, arena)
|
||||||
table.insert(tools, 2, "arena_lib:spectate_changeteam")
|
table.insert(tools, 2, "arena_lib:spectate_changeteam")
|
||||||
end
|
end
|
||||||
|
|
||||||
if next(arena_lib.get_spectable_entities(mod, arena.name)) then
|
if next(arena_lib.get_spectate_entities(mod, arena.name)) then
|
||||||
table.insert(tools, #tools, "arena_lib:spectate_changeentity")
|
table.insert(tools, #tools, "arena_lib:spectate_changeentity")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if next(arena_lib.get_spectate_areas(mod, arena.name)) then
|
||||||
|
table.insert(tools, #tools, "arena_lib:spectate_changearea")
|
||||||
|
end
|
||||||
|
|
||||||
if mod_ref.join_while_in_progress then
|
if mod_ref.join_while_in_progress then
|
||||||
table.insert(tools, #tools, "arena_lib:spectate_join")
|
table.insert(tools, #tools, "arena_lib:spectate_join")
|
||||||
end
|
end
|
||||||
|
|
|
@ -53,9 +53,30 @@ minetest.register_tool("arena_lib:spectate_changeentity", {
|
||||||
|
|
||||||
local p_name = user:get_player_name()
|
local p_name = user:get_player_name()
|
||||||
local mod = arena_lib.get_mod_by_player(p_name)
|
local mod = arena_lib.get_mod_by_player(p_name)
|
||||||
local arena_name = arena_lib.get_arena_by_player(p_name).name
|
local arena = arena_lib.get_arena_by_player(p_name)
|
||||||
|
|
||||||
arena_lib.find_and_spectate_entity(mod, arena_name, p_name)
|
arena_lib.find_and_spectate_entity(mod, arena, p_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_tool("arena_lib:spectate_changearea", {
|
||||||
|
|
||||||
|
description = S("Change area"),
|
||||||
|
inventory_image = "arenalib_spectate_changearea.png",
|
||||||
|
groups = {not_in_creative_inventory = 1, oddly_breakable_by_hand = "2"},
|
||||||
|
on_place = function() end,
|
||||||
|
on_drop = function() end,
|
||||||
|
|
||||||
|
on_use = function(itemstack, user)
|
||||||
|
|
||||||
|
local p_name = user:get_player_name()
|
||||||
|
local mod = arena_lib.get_mod_by_player(p_name)
|
||||||
|
local arena = arena_lib.get_arena_by_player(p_name)
|
||||||
|
|
||||||
|
arena_lib.find_and_spectate_area(mod, arena, p_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 176 B |
Loading…
Reference in New Issue