mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 04:30:44 +01:00
## About The Pull Request firstly and most importantly polymorphing works now fixes field gens in OSHA Violator map names are sorted alphabetically binary chat may not be used in deathmatch arenas Chef and Clown final destination loadout names were renamed to avoid confusion with loadouts of the same name ## Why It's Good For The Game fixes #82791 fixes #82802 a feature of a deathmatch map working is good loadout confusion = bad also i guess sorting the list looks cool ## Changelog 🆑 fix: deathmatch OSHA Violator map has actually functioning field gens now fix: being polymorphed in deathmatch does not count you dead fix: deathmatch cyborgs may not talk in binary qol: deathmatch map names are sorted alphabetically spellcheck: deathmatch final destination clown and chef loadouts have been renamed to avoid confusion /🆑
607 lines
19 KiB
Plaintext
607 lines
19 KiB
Plaintext
/datum/deathmatch_lobby
|
|
/// Ckey of the host
|
|
var/host
|
|
/// Assoc list of ckey to list()
|
|
var/list/players = list()
|
|
/// Assoc list of ckey to list()
|
|
var/list/observers = list()
|
|
/// The current chosen map
|
|
var/datum/lazy_template/deathmatch/map
|
|
/// Our turf reservation AKA where the arena is
|
|
var/datum/turf_reservation/location
|
|
/// Whether the lobby is currently playing
|
|
var/playing = DEATHMATCH_NOT_PLAYING
|
|
/// Number of total ready players
|
|
var/ready_count
|
|
/// List of loadouts, either gotten from the deathmatch controller or the map
|
|
var/list/loadouts
|
|
/// Current map player spawn locations, cleared after spawning
|
|
var/list/player_spawns = list()
|
|
/// A list of paths of modifiers enabled for the match.
|
|
var/list/modifiers = list()
|
|
/// Is the modifiers modal menu open (for the host)
|
|
var/mod_menu_open = FALSE
|
|
/// artificial time padding when we start loading to give lighting a breather (admin starts will set this to 0)
|
|
var/start_time = 8 SECONDS
|
|
|
|
/datum/deathmatch_lobby/New(mob/player)
|
|
. = ..()
|
|
if (!player)
|
|
stack_trace("Attempted to create a deathmatch lobby without a host.")
|
|
return qdel(src)
|
|
host = player.ckey
|
|
map = GLOB.deathmatch_game.maps[pick(GLOB.deathmatch_game.maps)]
|
|
log_game("[host] created a deathmatch lobby.")
|
|
if (map.allowed_loadouts)
|
|
loadouts = map.allowed_loadouts
|
|
else
|
|
loadouts = GLOB.deathmatch_game.loadouts
|
|
add_player(player, loadouts[1], TRUE)
|
|
ui_interact(player)
|
|
|
|
/datum/deathmatch_lobby/Destroy(force, ...)
|
|
. = ..()
|
|
for (var/key in players+observers)
|
|
var/datum/tgui/ui = SStgui.get_open_ui(get_mob_by_ckey(key), src)
|
|
if (ui) ui.close()
|
|
remove_ckey_from_play(key)
|
|
if(playing && !isnull(location))
|
|
clear_reservation()
|
|
players = null
|
|
observers = null
|
|
map?.template_in_use = FALSE //just incase
|
|
map = null
|
|
location = null
|
|
loadouts = null
|
|
modifiers = null
|
|
|
|
/datum/deathmatch_lobby/proc/start_game()
|
|
if (playing)
|
|
return
|
|
if(map.template_in_use)
|
|
to_chat(get_mob_by_ckey(host), span_warning("This map is currently loading for another lobby. Please wait until that other map finishes loading. It would be a disaster if these two mixed up."))
|
|
return
|
|
playing = DEATHMATCH_PRE_PLAYING
|
|
|
|
map.template_in_use = TRUE
|
|
RegisterSignal(map, COMSIG_LAZY_TEMPLATE_LOADED, PROC_REF(find_spawns_and_start_delay))
|
|
location = map.lazy_load()
|
|
if (!location)
|
|
to_chat(get_mob_by_ckey(host), span_warning("Couldn't reserve/load a map location (all locations used?), try again later, or contact a coder."))
|
|
playing = FALSE
|
|
map.template_in_use = FALSE
|
|
UnregisterSignal(map, COMSIG_LAZY_TEMPLATE_LOADED)
|
|
return FALSE
|
|
|
|
/datum/deathmatch_lobby/proc/find_spawns_and_start_delay(datum/lazy_template/source, list/atoms)
|
|
SIGNAL_HANDLER
|
|
for(var/thing in atoms)
|
|
if(istype(thing, /obj/effect/landmark/deathmatch_player_spawn))
|
|
player_spawns += thing
|
|
|
|
UnregisterSignal(source, COMSIG_LAZY_TEMPLATE_LOADED)
|
|
map.template_in_use = FALSE
|
|
addtimer(CALLBACK(src, PROC_REF(start_game_after_delay)), start_time)
|
|
|
|
/datum/deathmatch_lobby/proc/start_game_after_delay()
|
|
if (!length(player_spawns) || length(player_spawns) < length(players))
|
|
stack_trace("Failed to get spawns when loading deathmatch map [map.name] for lobby [host].")
|
|
clear_reservation()
|
|
playing = FALSE
|
|
return FALSE
|
|
|
|
for(var/modpath in modifiers)
|
|
GLOB.deathmatch_game.modifiers[modpath].on_start_game(src)
|
|
|
|
for (var/key in players)
|
|
var/mob/dead/observer/observer = players[key]["mob"]
|
|
if (isnull(observer) || !observer.client)
|
|
log_game("Removed player [key] from deathmatch lobby [host], as they couldn't be found.")
|
|
remove_ckey_from_play(key)
|
|
continue
|
|
|
|
// pick spawn and remove it.
|
|
var/picked_spawn = pick_n_take(player_spawns)
|
|
spawn_observer_as_player(key, get_turf(picked_spawn))
|
|
qdel(picked_spawn)
|
|
|
|
// Remove rest of spawns.
|
|
QDEL_LIST(player_spawns)
|
|
|
|
for (var/observer_key in observers)
|
|
var/mob/observer = observers[observer_key]["mob"]
|
|
observer.forceMove(pick(location.reserved_turfs))
|
|
|
|
playing = DEATHMATCH_PLAYING
|
|
addtimer(CALLBACK(src, PROC_REF(game_took_too_long)), initial(map.automatic_gameend_time))
|
|
log_game("Deathmatch game [host] started.")
|
|
announce(span_reallybig("GO!"))
|
|
if(length(modifiers))
|
|
var/list/modifier_names = list()
|
|
for(var/datum/deathmatch_modifier/modifier as anything in modifiers)
|
|
modifier_names += uppertext(initial(modifier.name))
|
|
announce(span_boldnicegreen("THIS MATCH MODIFIERS: [english_list(modifier_names, and_text = " ,")]."))
|
|
return TRUE
|
|
|
|
/datum/deathmatch_lobby/proc/spawn_observer_as_player(ckey, loc)
|
|
var/list/players_info = players[ckey]
|
|
var/mob/dead/observer/observer = players_info["mob"]
|
|
if (isnull(observer) || !observer.client)
|
|
remove_ckey_from_play(ckey)
|
|
return
|
|
|
|
// equip player
|
|
var/datum/outfit/deathmatch_loadout/loadout = players_info["loadout"]
|
|
if (!(loadout in loadouts))
|
|
loadout = loadouts[1]
|
|
|
|
var/mob/living/carbon/human/new_player = new(loc)
|
|
observer.client?.prefs.safe_transfer_prefs_to(new_player)
|
|
new_player.dna.update_dna_identity()
|
|
new_player.updateappearance(icon_update = TRUE, mutcolor_update = TRUE, mutations_overlay_update = TRUE)
|
|
new_player.add_traits(list(TRAIT_CANNOT_CRYSTALIZE, TRAIT_PERMANENTLY_MORTAL), INNATE_TRAIT)
|
|
if(!isnull(observer.mind) && observer.mind?.current)
|
|
new_player.AddComponent( \
|
|
/datum/component/temporary_body, \
|
|
old_mind = observer.mind, \
|
|
old_body = observer.mind.current, \
|
|
)
|
|
new_player.equipOutfit(loadout) // Loadout
|
|
new_player.key = ckey
|
|
players_info["mob"] = new_player
|
|
|
|
for(var/datum/deathmatch_modifier/modifier as anything in modifiers)
|
|
GLOB.deathmatch_game.modifiers[modifier].apply(new_player, src)
|
|
|
|
// register death handling.
|
|
register_player_signals(new_player)
|
|
|
|
/datum/deathmatch_lobby/proc/register_player_signals(new_player)
|
|
RegisterSignals(new_player, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING, COMSIG_MOB_GHOSTIZED), PROC_REF(player_died))
|
|
RegisterSignal(new_player, COMSIG_LIVING_ON_WABBAJACKED, PROC_REF(player_wabbajacked))
|
|
|
|
/datum/deathmatch_lobby/proc/unregister_player_signals(new_player)
|
|
UnregisterSignal(new_player, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING, COMSIG_MOB_GHOSTIZED, COMSIG_LIVING_ON_WABBAJACKED))
|
|
|
|
/datum/deathmatch_lobby/proc/game_took_too_long()
|
|
if (!location || QDELING(src))
|
|
return
|
|
announce(span_reallybig("The players have took too long! Game ending!"))
|
|
end_game()
|
|
|
|
/datum/deathmatch_lobby/proc/end_game()
|
|
if (!location)
|
|
CRASH("Reservation of deathmatch game [host] deleted during game.")
|
|
var/mob/winner
|
|
if(players.len)
|
|
var/list/winner_info = players[pick(players)]
|
|
if(!isnull(winner_info["mob"]))
|
|
winner = winner_info["mob"] //only one should remain anyway but incase of a draw
|
|
|
|
announce(span_reallybig("THE GAME HAS ENDED.<BR>THE WINNER IS: [winner ? winner.real_name : "no one"]."))
|
|
|
|
for(var/ckey in players)
|
|
var/mob/loser = players[ckey]["mob"]
|
|
unregister_player_signals(loser)
|
|
players[ckey]["mob"] = null
|
|
loser.ghostize(can_reenter_corpse = FALSE)
|
|
qdel(loser)
|
|
|
|
for(var/datum/deathmatch_modifier/modifier in modifiers)
|
|
GLOB.deathmatch_game.modifiers[modifier].on_end_game(src)
|
|
|
|
clear_reservation()
|
|
GLOB.deathmatch_game.remove_lobby(host)
|
|
log_game("Deathmatch game [host] ended.")
|
|
|
|
/datum/deathmatch_lobby/proc/player_wabbajacked(mob/living/player, mob/living/new_mob)
|
|
SIGNAL_HANDLER
|
|
unregister_player_signals(player)
|
|
players[player.ckey]["mob"] = new_mob
|
|
register_player_signals(new_mob)
|
|
|
|
/datum/deathmatch_lobby/proc/player_died(mob/living/player, gibbed)
|
|
SIGNAL_HANDLER
|
|
if(isnull(player) || QDELING(src) || HAS_TRAIT_FROM(player, TRAIT_NO_TRANSFORM, MAGIC_TRAIT)) //this trait check fixes polymorphing
|
|
return
|
|
|
|
var/ckey = player.ckey ? player.ckey : player.mind?.key
|
|
if(!islist(players[ckey])) // potentially the player info could hold a reference to this mob so we can figure the ckey out without worrying about ghosting and suicides n such
|
|
for(var/potential_ckey in players)
|
|
var/list/player_info = players[potential_ckey]
|
|
if(player_info["mob"] && player_info["mob"] == player)
|
|
ckey = potential_ckey
|
|
break
|
|
|
|
if(!islist(players[ckey])) // if we STILL didnt find a good ckey
|
|
return
|
|
|
|
players -= ckey
|
|
|
|
var/mob/dead/observer/ghost = !player.client ? player.get_ghost() : player.ghostize() //this doesnt work on those who used the ghost verb
|
|
if(!isnull(ghost))
|
|
add_observer(ghost, (host == ckey))
|
|
|
|
announce(span_reallybig("[player.real_name] HAS DIED.<br>[players.len] REMAIN."))
|
|
|
|
if(!gibbed && !QDELING(player) && !isdead(player))
|
|
if(!HAS_TRAIT(src, TRAIT_DEATHMATCH_EXPLOSIVE_IMPLANTS))
|
|
unregister_player_signals(player)
|
|
player.dust(TRUE, TRUE, TRUE)
|
|
if (players.len <= 1)
|
|
end_game()
|
|
|
|
/datum/deathmatch_lobby/proc/add_observer(mob/mob, host = FALSE)
|
|
if (players[mob.ckey])
|
|
CRASH("Tried to add [mob.ckey] as an observer while being a player.")
|
|
observers[mob.ckey] = list("mob" = mob, "host" = host)
|
|
|
|
/datum/deathmatch_lobby/proc/add_player(mob/mob, loadout, host = FALSE)
|
|
if (observers[mob.ckey])
|
|
CRASH("Tried to add [mob.ckey] as a player while being an observer.")
|
|
players[mob.ckey] = list("mob" = mob, "host" = host, "ready" = FALSE, "loadout" = loadout)
|
|
|
|
/datum/deathmatch_lobby/proc/remove_ckey_from_play(ckey)
|
|
var/is_likely_player = (ckey in players)
|
|
var/list/main_list = is_likely_player ? players : observers
|
|
var/list/info = main_list[ckey]
|
|
if(is_likely_player && islist(info))
|
|
ready_count -= info["ready"]
|
|
main_list -= ckey
|
|
|
|
/datum/deathmatch_lobby/proc/announce(message)
|
|
for (var/key in players+observers)
|
|
var/mob/player = get_mob_by_ckey(key)
|
|
if (!player.client)
|
|
remove_ckey_from_play(key)
|
|
continue
|
|
to_chat(player.client, message)
|
|
|
|
/datum/deathmatch_lobby/proc/leave(ckey)
|
|
if (host == ckey)
|
|
var/total_count = players.len + observers.len
|
|
if (total_count <= 1) // <= just in case.
|
|
GLOB.deathmatch_game.remove_lobby(host)
|
|
return
|
|
else
|
|
if (players[ckey] && players.len <= 1)
|
|
for (var/key in observers)
|
|
if (host == key)
|
|
continue
|
|
host = key
|
|
observers[key]["host"] = TRUE
|
|
break
|
|
else
|
|
for (var/key in players)
|
|
if (host == key)
|
|
continue
|
|
host = key
|
|
players[key]["host"] = TRUE
|
|
break
|
|
GLOB.deathmatch_game.passoff_lobby(ckey, host)
|
|
|
|
remove_ckey_from_play(ckey)
|
|
|
|
/datum/deathmatch_lobby/proc/join(mob/player)
|
|
if (playing || !player)
|
|
return
|
|
if(!(player.ckey in players+observers))
|
|
if (players.len >= map.max_players)
|
|
add_observer(player)
|
|
else
|
|
add_player(player, loadouts[1])
|
|
ui_interact(player)
|
|
|
|
/datum/deathmatch_lobby/proc/spectate(mob/player)
|
|
if (!playing || !location || !player)
|
|
return
|
|
if (!observers[player.ckey])
|
|
add_observer(player)
|
|
player.forceMove(pick(location.reserved_turfs))
|
|
|
|
/datum/deathmatch_lobby/proc/change_map(new_map)
|
|
if (!new_map || !GLOB.deathmatch_game.maps[new_map])
|
|
return
|
|
map = GLOB.deathmatch_game.maps[new_map]
|
|
var/max_players = map.max_players
|
|
for (var/possible_unlucky_loser in players)
|
|
max_players--
|
|
if (max_players <= 0)
|
|
var/loser_mob = players[possible_unlucky_loser]["mob"]
|
|
remove_ckey_from_play(possible_unlucky_loser)
|
|
add_observer(loser_mob)
|
|
|
|
loadouts = map.allowed_loadouts ? map.allowed_loadouts : GLOB.deathmatch_game.loadouts
|
|
for (var/player_key in players)
|
|
if (players[player_key]["loadout"] in loadouts)
|
|
continue
|
|
players[player_key]["loadout"] = loadouts[1]
|
|
|
|
for(var/deathmatch_mod in modifiers)
|
|
GLOB.deathmatch_game.modifiers[deathmatch_mod].on_map_changed(src)
|
|
|
|
/datum/deathmatch_lobby/proc/clear_reservation()
|
|
if(isnull(location) || isnull(map))
|
|
return
|
|
for(var/turf/victimized_turf as anything in location.reserved_turfs) //remove this once clearing turf reservations is actually reliable
|
|
victimized_turf.empty()
|
|
map.reservations -= location
|
|
qdel(location)
|
|
|
|
/datum/deathmatch_lobby/Topic(href, href_list) //This handles the chat Join button href, supposedly
|
|
var/mob/dead/observer/ghost = usr
|
|
if (!istype(ghost))
|
|
return
|
|
if(href_list["join"])
|
|
join(ghost)
|
|
|
|
/datum/deathmatch_lobby/ui_state(mob/user)
|
|
return GLOB.observer_state
|
|
|
|
/// fills the lobby with fake players for the sake of UI debug, can only be called via VV
|
|
/datum/deathmatch_lobby/proc/fakefill(count)
|
|
for(var/i = 1 to count)
|
|
players["[rand(1,999)]"] = list("mob" = usr, "host" = FALSE, "ready" = FALSE, "loadout" = pick(loadouts))
|
|
|
|
/datum/deathmatch_lobby/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, null)
|
|
if(!ui)
|
|
ui = new(user, src, "DeathmatchLobby")
|
|
ui.open()
|
|
|
|
/datum/deathmatch_lobby/ui_static_data(mob/user)
|
|
. = list()
|
|
.["maps"] = list()
|
|
for (var/map_key in GLOB.deathmatch_game.maps)
|
|
.["maps"] += map_key
|
|
.["maps"] = sort_list(.["maps"])
|
|
|
|
|
|
/datum/deathmatch_lobby/ui_data(mob/user)
|
|
var/list/data = list()
|
|
|
|
var/is_player = !isnull(players[user.ckey])
|
|
var/is_host = (user.ckey == host)
|
|
var/is_admin = check_rights_for(user.client, R_ADMIN)
|
|
var/has_auth = is_host || is_admin
|
|
|
|
data["active_mods"] = "No modifiers selected"
|
|
data["admin"] = is_admin
|
|
data["host"] = is_host
|
|
data["loadouts"] = list("Randomize")
|
|
|
|
for (var/datum/outfit/deathmatch_loadout/loadout as anything in loadouts)
|
|
data["loadouts"] += loadout::display_name
|
|
|
|
data["map"] = list()
|
|
data["map"]["name"] = map.name
|
|
data["map"]["desc"] = map.desc
|
|
data["map"]["time"] = map.automatic_gameend_time
|
|
data["map"]["min_players"] = map.min_players
|
|
data["map"]["max_players"] = map.max_players
|
|
|
|
data["mod_menu_open"] = mod_menu_open
|
|
data["modifiers"] = has_auth ? get_modifier_list(is_host, mod_menu_open) : list()
|
|
data["observers"] = get_observer_list()
|
|
data["players"] = get_player_list()
|
|
data["playing"] = playing
|
|
data["self"] = user.ckey
|
|
|
|
if(length(modifiers))
|
|
var/list/mod_names = list()
|
|
for(var/datum/deathmatch_modifier/modpath as anything in modifiers)
|
|
mod_names += modpath::name
|
|
data["active_mods"] = "Selected modifiers: [english_list(mod_names)]"
|
|
|
|
if(is_player && !isnull(players[user.ckey]["loadout"]))
|
|
var/datum/outfit/deathmatch_loadout/loadout = players[user.ckey]["loadout"]
|
|
data["loadoutdesc"] = loadout::desc
|
|
else
|
|
data["loadoutdesc"] = "You are an observer! As an observer, you can hear lobby announcements."
|
|
|
|
return data
|
|
|
|
/datum/deathmatch_lobby/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
. = ..()
|
|
if(. || !isobserver(usr))
|
|
return
|
|
|
|
switch(action)
|
|
if ("start_game")
|
|
if (usr.ckey != host)
|
|
return FALSE
|
|
if (map.min_players > players.len)
|
|
to_chat(usr, span_warning("Not enough players to start yet."))
|
|
return FALSE
|
|
start_game()
|
|
return TRUE
|
|
|
|
if ("leave_game")
|
|
if (playing)
|
|
return FALSE
|
|
leave(usr.ckey)
|
|
ui.close()
|
|
GLOB.deathmatch_game.ui_interact(usr)
|
|
return TRUE
|
|
|
|
if ("change_loadout")
|
|
if (playing)
|
|
return FALSE
|
|
if (params["player"] != usr.ckey && host != usr.ckey)
|
|
return FALSE
|
|
if (params["loadout"] == "Randomize")
|
|
players[params["player"]]["loadout"] = pick(loadouts)
|
|
return TRUE
|
|
for (var/datum/outfit/deathmatch_loadout/possible_loadout as anything in loadouts)
|
|
if (params["loadout"] != initial(possible_loadout.display_name))
|
|
continue
|
|
players[params["player"]]["loadout"] = possible_loadout
|
|
break
|
|
return TRUE
|
|
|
|
if ("observe")
|
|
if (playing)
|
|
return FALSE
|
|
if (players[usr.ckey])
|
|
remove_ckey_from_play(usr.ckey)
|
|
add_observer(usr, host == usr.ckey)
|
|
return TRUE
|
|
else if (observers[usr.ckey] && players.len < map.max_players)
|
|
remove_ckey_from_play(usr.ckey)
|
|
add_player(usr, loadouts[1], host == usr.ckey)
|
|
return TRUE
|
|
|
|
if ("ready")
|
|
players[usr.ckey]["ready"] ^= 1 // Toggle.
|
|
ready_count += (players[usr.ckey]["ready"] * 2) - 1 // scared?
|
|
if (ready_count >= players.len && players.len >= map.min_players)
|
|
start_game()
|
|
return TRUE
|
|
|
|
if ("host") // Host functions
|
|
if (playing || (usr.ckey != host && !check_rights(R_ADMIN)))
|
|
return FALSE
|
|
var/uckey = params["id"]
|
|
|
|
switch (params["func"])
|
|
if ("Kick")
|
|
leave(uckey)
|
|
var/umob = get_mob_by_ckey(uckey)
|
|
var/datum/tgui/uui = SStgui.get_open_ui(umob, src)
|
|
uui?.close()
|
|
GLOB.deathmatch_game.ui_interact(umob)
|
|
return TRUE
|
|
if ("Transfer host")
|
|
if (host == uckey)
|
|
return FALSE
|
|
GLOB.deathmatch_game.passoff_lobby(host, uckey)
|
|
host = uckey
|
|
return TRUE
|
|
if ("Toggle observe")
|
|
var/umob = get_mob_by_ckey(uckey)
|
|
if (players[uckey])
|
|
remove_ckey_from_play(uckey)
|
|
add_observer(umob, host == uckey)
|
|
else if (observers[uckey] && players.len < map.max_players)
|
|
remove_ckey_from_play(uckey)
|
|
add_player(umob, loadouts[1], host == uckey)
|
|
return TRUE
|
|
if ("change_map")
|
|
if (!(params["map"] in GLOB.deathmatch_game.maps))
|
|
return FALSE
|
|
change_map(params["map"])
|
|
return TRUE
|
|
|
|
if("open_mod_menu")
|
|
mod_menu_open = TRUE
|
|
return TRUE
|
|
|
|
if("exit_mod_menu")
|
|
mod_menu_open = FALSE
|
|
return TRUE
|
|
|
|
if("toggle_modifier")
|
|
var/datum/deathmatch_modifier/modpath = text2path(params["modpath"])
|
|
if(!ispath(modpath))
|
|
return TRUE
|
|
if(usr.ckey != host && !check_rights(R_ADMIN))
|
|
return TRUE
|
|
var/datum/deathmatch_modifier/chosen_modifier = GLOB.deathmatch_game.modifiers[modpath]
|
|
if(modpath in modifiers)
|
|
unselect_modifier(chosen_modifier)
|
|
return TRUE
|
|
if(chosen_modifier.selectable(src))
|
|
select_modifier(chosen_modifier)
|
|
return TRUE
|
|
|
|
if ("admin") // Admin functions
|
|
if (!check_rights(R_ADMIN))
|
|
message_admins("[usr.key] has attempted to use admin functions in a deathmatch lobby without being an admin!")
|
|
log_admin("[key_name(usr)] tried to use the deathmatch lobby admin functions without authorization.")
|
|
return
|
|
switch (params["func"])
|
|
if ("Force start")
|
|
log_admin("[key_name(usr)] force started deathmatch lobby [host].")
|
|
start_time = 0
|
|
start_game()
|
|
|
|
return FALSE
|
|
|
|
/// Selects the passed modifier.
|
|
/datum/deathmatch_lobby/proc/select_modifier(datum/deathmatch_modifier/modifier)
|
|
modifier.on_select(src)
|
|
modifiers += modifier.type
|
|
|
|
/// Deselects the passed modifier.
|
|
/datum/deathmatch_lobby/proc/unselect_modifier(datum/deathmatch_modifier/modifier)
|
|
modifier.unselect(src)
|
|
modifiers -= modifier.type
|
|
|
|
/datum/deathmatch_lobby/ui_close(mob/user)
|
|
. = ..()
|
|
if(user.ckey == host)
|
|
mod_menu_open = FALSE
|
|
|
|
/// Helper proc to get modifier data
|
|
/datum/deathmatch_lobby/proc/get_modifier_list(is_host, mod_menu_open)
|
|
var/list/modifier_list = list()
|
|
|
|
if(!mod_menu_open)
|
|
return modifier_list
|
|
|
|
for(var/modpath in GLOB.deathmatch_game.modifiers)
|
|
var/datum/deathmatch_modifier/mod = GLOB.deathmatch_game.modifiers[modpath]
|
|
|
|
UNTYPED_LIST_ADD(modifier_list, list(
|
|
"name" = mod.name,
|
|
"desc" = mod.description,
|
|
"modpath" = "[modpath]",
|
|
"selected" = (modpath in modifiers),
|
|
"selectable" = is_host && mod.selectable(src),
|
|
))
|
|
|
|
return modifier_list
|
|
|
|
|
|
/// Helper proc for getting observer data
|
|
/datum/deathmatch_lobby/proc/get_observer_list()
|
|
var/list/observer_list = list()
|
|
|
|
for (var/observer_key in observers)
|
|
var/list/observer_info = observers[observer_key]
|
|
var/mob/observer_mob = observer_info["mob"]
|
|
|
|
if (isnull(observer_mob) || !observer_mob.client)
|
|
leave(observer_key)
|
|
continue
|
|
|
|
var/list/observer = observer_info.Copy()
|
|
observer["key"] = observer_key
|
|
|
|
UNTYPED_LIST_ADD(observer_list, observer)
|
|
|
|
return observer_list
|
|
|
|
|
|
/// Helper proc for getting player data
|
|
/datum/deathmatch_lobby/proc/get_player_list()
|
|
var/list/player_list = list()
|
|
|
|
for (var/player_key in players)
|
|
var/list/player_info = players[player_key]
|
|
var/mob/player_mob = player_info["mob"]
|
|
|
|
if (isnull(player_mob) || !player_mob.client)
|
|
leave(player_key)
|
|
continue
|
|
|
|
var/list/player = player_info.Copy()
|
|
|
|
var/datum/outfit/deathmatch_loadout/dm_loadout = player_info["loadout"]
|
|
player["loadout"] = dm_loadout::display_name
|
|
player["key"] = player_key
|
|
|
|
UNTYPED_LIST_ADD(player_list, player)
|
|
|
|
return player_list
|