mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
+37






![tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com>](/assets/img/avatar_default.png)


Alexis
GitHub
tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com>
ArcaneMusic
MrMelbert
Rhials
rageguy505
LemonInTheDark
John Willard
Aliceee2ch
Time-Green
Tsar-Salat
SmArtKar
Maxipat
SyncIt21
deltanedas
SimplyLogan
loganuk
Leland Kemble
FalloutFalcon
Roxy
Lucy
siliconOpossum
Isratosh
TheRyeGuyWhoWillNowDie
Neocloudy
Alexander V.
ElGitificador
Twaticus
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bloop
Cameron Lennox
Tim
Iamgoofball
Layzu666
Arturlang
_0Steven
mrmanlikesbt
Ben10Omintrix
John F. Kennedy
Cursor
Josh
Josh Powell
Yobrocharlie
Hardly3D
shayoki
LT3
21b4095dfd
Upstream 04/17/2026 fixes https://github.com/Bubberstation/Bubberstation/issues/5549 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com> Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com> Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com> Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com> Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com> Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com> Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com> Co-authored-by: loganuk <fakeemail123@aol.com> Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com> Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com> Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> Co-authored-by: Lucy <lucy@absolucy.moe> Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com> Co-authored-by: Isratosh <Isratosh@hotmail.com> Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com> Co-authored-by: Alexander V. <volas@ya.ru> Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com> Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: Iamgoofball <iamgoofball@gmail.com> Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com> Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com> Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com> Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com> Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com> Co-authored-by: Josh <josh.adam.powell@gmail.com> Co-authored-by: Josh Powell <josh.powell@softwire.com> Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com> Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com> Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
232 lines
7.9 KiB
Plaintext
232 lines
7.9 KiB
Plaintext
SUBSYSTEM_DEF(title)
|
|
name = "Title Screen"
|
|
ss_flags = SS_NO_FIRE
|
|
init_stage = INITSTAGE_EARLY
|
|
|
|
var/file_path
|
|
var/icon/startup_splash
|
|
|
|
/// The current title screen being displayed, as a file path text.
|
|
var/current_title_screen
|
|
/// The current notice text, or null.
|
|
var/current_notice
|
|
/// The preamble html that includes all styling and layout.
|
|
var/title_html
|
|
/// The list of possible title screens to rotate through, as file path texts.
|
|
var/title_screens = list()
|
|
|
|
/// average realtime seconds it takes to load the map we're currently running
|
|
var/average_completion_time = DEFAULT_TITLE_MAP_LOADTIME
|
|
/// a given startup message => average timestamp in realtime seconds
|
|
var/list/startup_message_timings = list()
|
|
/// Raw data to update later
|
|
var/list/progress_json = list()
|
|
/// The reference realtime that we're treating as 0 for this run
|
|
var/progress_reference_time = 0
|
|
/// A list of station traits that have lobby buttons
|
|
var/list/available_lobby_station_traits = list()
|
|
|
|
/datum/controller/subsystem/title/Initialize()
|
|
var/dat
|
|
if(!fexists("[global.config.directory]/bubbers/bubbers_title.txt"))
|
|
to_chat(world, span_boldwarning("CRITICAL ERROR: Unable to read bubbers_title.txt, reverting to backup title html, please check your server config and ensure this file exists."))
|
|
dat = DEFAULT_TITLE_HTML
|
|
else
|
|
dat = file2text("[global.config.directory]/bubbers/bubbers_title.txt")
|
|
|
|
title_html = dat
|
|
|
|
var/list/provisional_title_screens = flist("[global.config.directory]/title_screens/images/")
|
|
var/list/local_title_screens = list()
|
|
var/list/current_map_file = splittext(SSmapping.current_map.map_file, ".")
|
|
|
|
for(var/screen in provisional_title_screens)
|
|
var/list/formatted_list = splittext(screen, "+")
|
|
if((LOWER_TEXT(formatted_list[1]) == LOWER_TEXT(current_map_file[1])))
|
|
local_title_screens += screen
|
|
continue
|
|
|
|
if(LAZYLEN(formatted_list) > 1 && LOWER_TEXT(formatted_list[1]) == "startup_splash")
|
|
var/file_path = "[global.config.directory]/title_screens/images/[screen]"
|
|
ASSERT(fexists(file_path))
|
|
startup_splash = new(fcopy_rsc(file_path))
|
|
|
|
if(local_title_screens.len == 0)
|
|
for(var/screen in provisional_title_screens)
|
|
var/list/formatted_list = splittext(screen, "+")
|
|
if((LAZYLEN(formatted_list) == 1 && (formatted_list[1] != "exclude" && formatted_list[1] != "blank.png" && formatted_list[1] != "startup_splash")))
|
|
local_title_screens += screen
|
|
|
|
// Progress stuff
|
|
check_progress_reference_time()
|
|
load_progress_json()
|
|
|
|
if(startup_splash)
|
|
change_title_screen(startup_splash)
|
|
else
|
|
change_title_screen(DEFAULT_TITLE_LOADING_SCREEN)
|
|
|
|
if(length(local_title_screens))
|
|
for(var/i in local_title_screens)
|
|
var/file_path = "[global.config.directory]/title_screens/images/[i]"
|
|
ASSERT(fexists(file_path))
|
|
var/icon/title2use = new(fcopy_rsc(file_path))
|
|
title_screens += title2use
|
|
|
|
return SS_INIT_SUCCESS
|
|
|
|
/**
|
|
* Make sure reference time is set up. If not, this is now time 0.
|
|
*/
|
|
/datum/controller/subsystem/title/proc/check_progress_reference_time()
|
|
if(!progress_reference_time)
|
|
progress_reference_time = world.timeofday
|
|
|
|
/**
|
|
* Handle and clean up leaving startup
|
|
*/
|
|
/datum/controller/subsystem/title/proc/check_finish_progress()
|
|
//It's the first time we're firing out of startup -> pregame
|
|
if(progress_json && SSticker.current_state == GAME_STATE_PREGAME)
|
|
save_progress_json()
|
|
|
|
/**
|
|
* Load the progress info json and setup that part of the SS.
|
|
*/
|
|
/datum/controller/subsystem/title/proc/load_progress_json()
|
|
var/json_file = file(TITLE_PROGRESS_CACHE_FILE)
|
|
if(!fexists(json_file))
|
|
return
|
|
|
|
// Load map progress cache info
|
|
progress_json = json_decode(file2text(json_file))
|
|
|
|
// Different format. Purge everything.
|
|
if(progress_json["_version"] != TITLE_PROGRESS_CACHE_VERSION)
|
|
progress_json.Cut()
|
|
return
|
|
|
|
// If there's no info about the current map, use the defaults.
|
|
var/list/map_info = progress_json[SSmapping.current_map.map_name]
|
|
if(!islist(map_info))
|
|
return
|
|
|
|
// Get expected total time and subpart time
|
|
average_completion_time = map_info["total"] || DEFAULT_TITLE_MAP_LOADTIME
|
|
startup_message_timings = map_info["messages"] || list()
|
|
|
|
/datum/controller/subsystem/title/proc/save_progress_json()
|
|
var/json_file = file(TITLE_PROGRESS_CACHE_FILE)
|
|
var/list/map_info = list()
|
|
|
|
progress_json["_version"] = TITLE_PROGRESS_CACHE_VERSION
|
|
|
|
if(progress_json[SSmapping.current_map.map_name])
|
|
// Save total time and updated message timings. Latest time is worth 1/4 the "average"
|
|
map_info["total"] = 0.75 * average_completion_time + 0.25 * (world.timeofday - progress_reference_time)
|
|
else
|
|
// New. Just save the time it took.
|
|
map_info["total"] = world.timeofday - progress_reference_time
|
|
map_info["messages"] = startup_message_timings
|
|
progress_json[SSmapping.current_map.map_name] = map_info
|
|
|
|
fdel(json_file)
|
|
WRITE_FILE(json_file, json_encode(progress_json))
|
|
|
|
// We're done, don't touch it again this round.
|
|
progress_json = null
|
|
|
|
/datum/controller/subsystem/title/Recover()
|
|
startup_splash = SStitle.startup_splash
|
|
file_path = SStitle.file_path
|
|
|
|
current_title_screen = SStitle.current_title_screen
|
|
current_notice = SStitle.current_notice
|
|
title_html = SStitle.title_html
|
|
title_screens = SStitle.title_screens
|
|
|
|
average_completion_time = SStitle.average_completion_time
|
|
startup_message_timings = SStitle.startup_message_timings
|
|
progress_json = SStitle.progress_json
|
|
progress_reference_time = SStitle.progress_reference_time
|
|
|
|
/**
|
|
* Show the title screen to all new players.
|
|
*/
|
|
/datum/controller/subsystem/title/proc/show_title_screen()
|
|
for(var/mob/dead/new_player/new_player in GLOB.new_player_list)
|
|
INVOKE_ASYNC(new_player, TYPE_PROC_REF(/mob/dead/new_player, show_title_screen))
|
|
|
|
/**
|
|
* Adds a notice to the main title screen in the form of big red text!
|
|
*/
|
|
/datum/controller/subsystem/title/proc/set_notice(new_title)
|
|
current_notice = new_title ? sanitize_text(new_title) : null
|
|
show_title_screen()
|
|
|
|
/**
|
|
* Changes the title screen to a new image.
|
|
*/
|
|
/datum/controller/subsystem/title/proc/change_title_screen(new_screen)
|
|
if(new_screen)
|
|
current_title_screen = new_screen
|
|
else
|
|
if(LAZYLEN(title_screens))
|
|
current_title_screen = pick(title_screens)
|
|
else
|
|
current_title_screen = DEFAULT_TITLE_SCREEN_IMAGE
|
|
|
|
check_finish_progress()
|
|
show_title_screen()
|
|
|
|
/**
|
|
* Update a user's character setup name.
|
|
* Arguments:
|
|
* * user - The user being updated
|
|
* * name - the real name of the current slot.
|
|
*/
|
|
/datum/controller/subsystem/title/proc/update_character_name(mob/dead/new_player/user, name)
|
|
if(!(istype(user) && user.title_screen_is_ready))
|
|
return
|
|
|
|
user.client << output(name, "title_browser:update_current_character")
|
|
|
|
/**
|
|
* Adds a startup message to the splashscreen.
|
|
*
|
|
* Arguments:
|
|
* * msg - the message to show users.
|
|
* * warning - optional: TRUE to indicate this is an error/warning
|
|
*/
|
|
/proc/add_startup_message(msg, warning)
|
|
// Remove the # second(s) / #s part of the message.
|
|
var/static/regex/msg_key_regex = new(@"[0-9.]+( second)?s?!", "ig")
|
|
|
|
// HTML displayed to user
|
|
var/msg_html = {"<p class="terminal_text">[warning ? "☒ " : ""][msg]</p>"}
|
|
// Key used to cache the timing info
|
|
var/msg_key = msg_key_regex.Replace(msg, "#")
|
|
|
|
GLOB.startup_messages += msg_html
|
|
|
|
// If we ran before SStitle initialized, set the ref time now.
|
|
SStitle.check_progress_reference_time()
|
|
|
|
// Add or update message history info.
|
|
var/old_timing = SStitle.startup_message_timings[msg_key]
|
|
var/new_timing
|
|
if(!old_timing)
|
|
// new message
|
|
new_timing = world.timeofday - SStitle.progress_reference_time
|
|
else
|
|
// old message. Latest time is worth 1/4 the "average"
|
|
new_timing = 0.75 * old_timing + 0.25 * (world.timeofday - SStitle.progress_reference_time)
|
|
SStitle.startup_message_timings[msg_key] = new_timing
|
|
|
|
for(var/mob/dead/new_player/new_player in GLOB.new_player_list)
|
|
if(!new_player.title_screen_is_ready)
|
|
continue
|
|
|
|
new_player.client << output(msg_html, "title_browser:append_terminal_text")
|
|
new_player.client << output(list2params(list(new_timing, SStitle.average_completion_time)), "title_browser:update_loading_progress")
|