From 2a08eaa88233ff550d59f74ec8eaac457171a669 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sun, 4 Sep 2022 04:33:01 +0200 Subject: [PATCH] [MIRROR] Don't load CTF until it's requested (saves several seconds of init time) [MDB IGNORE] (#16040) * Don't load CTF until it's requested (saves several seconds of init time) (#69662) * Don't load CTF until it's requested * Remove unused import * Fix voting * Don't load CTF until it's requested (saves several seconds of init time) Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> --- code/modules/capture_the_flag/_defines.dm | 4 + code/modules/capture_the_flag/ctf_game.dm | 38 +++++-- .../capture_the_flag/ctf_map_loading.dm | 3 +- code/modules/capture_the_flag/ctf_panel.dm | 52 +++++++-- code/modules/capture_the_flag/ctf_voting.dm | 45 ++++++++ tgstation.dme | 1 + tgui/packages/tgui/interfaces/CTFPanel.js | 68 ----------- tgui/packages/tgui/interfaces/CTFPanel.tsx | 107 ++++++++++++++++++ 8 files changed, 229 insertions(+), 89 deletions(-) create mode 100644 code/modules/capture_the_flag/ctf_voting.dm delete mode 100644 tgui/packages/tgui/interfaces/CTFPanel.js create mode 100644 tgui/packages/tgui/interfaces/CTFPanel.tsx diff --git a/code/modules/capture_the_flag/_defines.dm b/code/modules/capture_the_flag/_defines.dm index 96079739950..8e8f5860255 100644 --- a/code/modules/capture_the_flag/_defines.dm +++ b/code/modules/capture_the_flag/_defines.dm @@ -1 +1,5 @@ +/// The number of voters required for CTF to enable #define CTF_REQUIRED_PLAYERS 4 + +/// The game ID for normal ghost CTF +#define CTF_GHOST_CTF_GAME_ID "centcom" diff --git a/code/modules/capture_the_flag/ctf_game.dm b/code/modules/capture_the_flag/ctf_game.dm index 0efab65b65a..42d2494b411 100644 --- a/code/modules/capture_the_flag/ctf_game.dm +++ b/code/modules/capture_the_flag/ctf_game.dm @@ -174,7 +174,28 @@ desc = "This is where a yellow banner used to play capture the flag \ would go." +#define CTF_LOADING_UNLOADED 0 +#define CTF_LOADING_LOADING 1 +#define CTF_LOADING_LOADED 2 + /proc/toggle_id_ctf(user, activated_id, automated = FALSE) + var/static/loading = CTF_LOADING_UNLOADED + switch (loading) + if (CTF_LOADING_UNLOADED) + if (isnull(GLOB.ctf_spawner)) + to_chat(user, span_boldwarning("Couldn't find a CTF spawner. Call a maintainer!")) + return + + to_chat(user, span_notice("Loading CTF...")) + + loading = CTF_LOADING_LOADING + GLOB.ctf_spawner.load_map() + loading = CTF_LOADING_LOADED + if (CTF_LOADING_LOADING) + to_chat(user, span_warning("CTF is loading!")) + + return + var/ctf_enabled = FALSE var/area/A for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines) @@ -194,13 +215,17 @@ if(!automated) notify_ghosts("CTF has been [ctf_enabled? "enabled" : "disabled"] in [A]!",'sound/effects/ghost2.ogg') +#undef CTF_LOADING_UNLOADED +#undef CTF_LOADING_LOADING +#undef CTF_LOADING_LOADED + /obj/machinery/capture_the_flag name = "CTF Controller" desc = "Used for running friendly games of capture the flag." icon = 'icons/obj/device.dmi' icon_state = "syndbeacon" resistance_flags = INDESTRUCTIBLE - var/game_id = "centcom" + var/game_id = CTF_GHOST_CTF_GAME_ID var/victory_rejoin_text = "Teams have been cleared. Click on the machines to vote to begin another round." var/team = WHITE_TEAM @@ -227,7 +252,6 @@ var/list/dead_barricades = list() var/static/arena_reset = FALSE - var/static/list/people_who_want_to_play = list() var/game_area = /area/centcom/ctf /// This variable is needed because of ctf shitcode + we need to make sure we're deleting the current ctf landmark that spawned us in and not a new one. @@ -306,15 +330,7 @@ if(CTF.game_id != game_id && CTF.ctf_enabled) to_chat(user, span_warning("There is already an ongoing game in the [get_area(CTF)]!")) return - people_who_want_to_play |= user.ckey - var/num = people_who_want_to_play.len - var/remaining = CTF_REQUIRED_PLAYERS - num - if(remaining <= 0) - people_who_want_to_play.Cut() - toggle_id_ctf(null, game_id) - else - to_chat(user, span_notice("CTF has been requested. [num]/[CTF_REQUIRED_PLAYERS] have readied up.")) - + get_ctf_voting_controller(game_id).vote(user) return if(!SSticker.HasRoundStarted()) diff --git a/code/modules/capture_the_flag/ctf_map_loading.dm b/code/modules/capture_the_flag/ctf_map_loading.dm index 60212cd8b44..0edd21aabac 100644 --- a/code/modules/capture_the_flag/ctf_map_loading.dm +++ b/code/modules/capture_the_flag/ctf_map_loading.dm @@ -9,7 +9,6 @@ GLOBAL_DATUM(ctf_spawner, /obj/effect/landmark/ctf) if(GLOB.ctf_spawner) qdel(GLOB.ctf_spawner) GLOB.ctf_spawner = src - INVOKE_ASYNC(src, .proc/load_map) /obj/effect/landmark/ctf/Destroy() if(map_bounds) @@ -30,6 +29,8 @@ GLOBAL_DATUM(ctf_spawner, /obj/effect/landmark/ctf) return ..() /obj/effect/landmark/ctf/proc/load_map() + if (map_bounds) + return var/list/map_options = subtypesof(/datum/map_template/ctf) var/turf/spawn_area = get_turf(src) diff --git a/code/modules/capture_the_flag/ctf_panel.dm b/code/modules/capture_the_flag/ctf_panel.dm index a12eeaa08dc..ed836be432f 100644 --- a/code/modules/capture_the_flag/ctf_panel.dm +++ b/code/modules/capture_the_flag/ctf_panel.dm @@ -13,21 +13,30 @@ GLOBAL_DATUM_INIT(ctf_panel, /datum/ctf_panel, new()) /datum/ctf_panel/ui_data(mob/user) var/list/data = list() - data["teams"] = list() - data["enabled"] = "" + var/list/teams = list() + for(var/obj/machinery/capture_the_flag/team in GLOB.machines) + if (!team.ctf_enabled) + continue + var/list/this = list() this["name"] = team this["color"] = team.team this["score"] = team.points + team.control_points this["team_size"] = team.team_members.len - this["refs"] += "[REF(team)]" - data["teams"] += list(this) - if(!data["enabled"]) - if(team.ctf_enabled) - data["enabled"] = "CTF is currently running!" - else - data["enabled"] = "CTF needs [CTF_REQUIRED_PLAYERS] players to start, currently [team.people_who_want_to_play.len]/[CTF_REQUIRED_PLAYERS] have signed up!" + this["refs"] += REF(team) + teams += list(this) + + if (teams.len == 0) + // No CTF map has been spawned in yet + var/datum/ctf_voting_controller/ctf_controller = get_ctf_voting_controller(CTF_GHOST_CTF_GAME_ID) + + data["voters"] = ctf_controller.volunteers.len + data["voters_required"] = CTF_REQUIRED_PLAYERS + data["voted"] = (user.ckey in ctf_controller.volunteers) + else + data["teams"] = teams + return data @@ -50,3 +59,28 @@ GLOBAL_DATUM_INIT(ctf_panel, /datum/ctf_panel, new()) user.forceMove(get_turf(ctf_spawner)) ctf_spawner.attack_ghost(user) return TRUE + if ("vote") + if (ctf_enabled()) + to_chat(user, span_warning("CTF is already enabled!")) + return TRUE + + var/datum/ctf_voting_controller/ctf_controller = get_ctf_voting_controller(CTF_GHOST_CTF_GAME_ID) + ctf_controller.vote(user) + + return TRUE + if ("unvote") + if (ctf_enabled()) + to_chat(user, span_warning("CTF is already enabled!")) + return TRUE + + var/datum/ctf_voting_controller/ctf_controller = get_ctf_voting_controller(CTF_GHOST_CTF_GAME_ID) + ctf_controller.unvote(user) + + return TRUE + +/datum/ctf_panel/proc/ctf_enabled() + for (var/obj/machinery/capture_the_flag/ctf_machine in GLOB.machines) + if (ctf_machine.ctf_enabled) + return TRUE + + return FALSE diff --git a/code/modules/capture_the_flag/ctf_voting.dm b/code/modules/capture_the_flag/ctf_voting.dm new file mode 100644 index 00000000000..120da3b1a94 --- /dev/null +++ b/code/modules/capture_the_flag/ctf_voting.dm @@ -0,0 +1,45 @@ +GLOBAL_LIST_EMPTY(ctf_voting_controllers) + +/datum/ctf_voting_controller + /// The list of ckeys that want to play CTF + var/list/volunteers = list() + + var/game_id + +/datum/ctf_voting_controller/New(game_id) + src.game_id = game_id + +/// Casts a vote in favor of CTF for user. +/datum/ctf_voting_controller/proc/vote(mob/user) + if (user.ckey in volunteers) + return + + volunteers += user.ckey + + var/volunteer_count = volunteers.len + var/remaining = CTF_REQUIRED_PLAYERS - volunteer_count + + if (remaining <= 0) + volunteers.Cut() + toggle_id_ctf(activated_id = game_id) + else + to_chat(user, span_notice("CTF has been requested. [volunteer_count]/[CTF_REQUIRED_PLAYERS] have readied up.")) + +/// Removes an existing vote for user. +/datum/ctf_voting_controller/proc/unvote(mob/user) + if (!(user.ckey in volunteers)) + return + + volunteers -= user.ckey + to_chat(user, span_notice("Removed vote for CTF.")) + +/// Returns the existing [/datum/ctf_voting_controller] for the given ID, or makes one +/proc/get_ctf_voting_controller(game_id) + RETURN_TYPE(/datum/ctf_voting_controller) + + var/datum/ctf_voting_controller/controller = GLOB.ctf_voting_controllers[game_id] + if (isnull(controller)) + controller = new(game_id) + GLOB.ctf_voting_controllers[game_id] = controller + + return controller diff --git a/tgstation.dme b/tgstation.dme index f68ff42dd1b..f46b2b47efc 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2616,6 +2616,7 @@ #include "code\modules\capture_the_flag\ctf_game.dm" #include "code\modules\capture_the_flag\ctf_map_loading.dm" #include "code\modules\capture_the_flag\ctf_panel.dm" +#include "code\modules\capture_the_flag\ctf_voting.dm" #include "code\modules\capture_the_flag\medieval_sim\medisim_classes.dm" #include "code\modules\capture_the_flag\medieval_sim\medisim_game.dm" #include "code\modules\cards\cardhand.dm" diff --git a/tgui/packages/tgui/interfaces/CTFPanel.js b/tgui/packages/tgui/interfaces/CTFPanel.js deleted file mode 100644 index 3adbcac1b6c..00000000000 --- a/tgui/packages/tgui/interfaces/CTFPanel.js +++ /dev/null @@ -1,68 +0,0 @@ -import { useBackend } from '../backend'; -import { Box, Button, Section, Flex, Stack, Divider } from '../components'; -import { Window } from '../layouts'; - -export const CTFPanel = (props, context) => { - const { act, data } = useBackend(context); - const teams = data.teams || []; - const enabled = data.enabled || []; - return ( - - - - {enabled} - - - - - - {teams.map((team) => ( - -
- - - - {team.team_size} member - {team.team_size === 1 ? '' : 's'} - - - - - - {team.score} point - {team.score === 1 ? '' : 's'} - - - - -
-
- ))} -
-
-
- ); -}; diff --git a/tgui/packages/tgui/interfaces/CTFPanel.tsx b/tgui/packages/tgui/interfaces/CTFPanel.tsx new file mode 100644 index 00000000000..ea213ac0420 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CTFPanel.tsx @@ -0,0 +1,107 @@ +import { BooleanLike } from '../../common/react'; +import { useBackend } from '../backend'; +import { Box, Button, Section, Flex, Stack } from '../components'; +import { Window } from '../layouts'; + +type CTFPanelData = + | { + teams: { + name: string; + color: string; + score: number; + team_size: number; + refs: string[]; + }[]; + } + | { + voters: number; + voters_required: number; + voted: BooleanLike; + }; + +export const CTFPanel = (props, context) => { + const { act, data } = useBackend(context); + + return ( + + + {'teams' in data ? ( + + {data.teams.map((team) => ( + +
+ + + + {team.team_size} member + {team.team_size === 1 ? '' : 's'} + + + + + + {team.score} point + {team.score === 1 ? '' : 's'} + + + + +
+
+ ))} +
+ ) : ( + + + + {data.voters}/{data.voters_required} + +
+ + CTF voters + +
+ + + + +
+ )} +
+
+ ); +};