mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 04:22:39 +01:00
Ports Goonchat from Baystation. (#9635)
changes:
rscadd: "Ported a new chat system, Goonchat, that allows for cool things like changing font style, size, spacing, highlighting up to 5 strings in the chat, and DARK MODE."
rscadd: "Repeated chat messages can now get compacted. You can disable this in goonchat settings."
rscadd: "You can change icon style to any font on your system."
tweak: "The game window has been altered a bit to adjust for this."
rscdel: "Removed skin style prefs as they are no longer used."
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* Pretty much pokes the MC to make sure it's still alive.
|
||||
**/
|
||||
|
||||
#define FAILSAFE_MSG(msg) admin_notice("<big><em><font color='red'>FAILSAFE: </font><font color='black'>[msg]</font></em></big>", R_DEBUG|R_ADMIN|R_DEV)
|
||||
#define FAILSAFE_MSG(msg) admin_notice("<big><em><span class='warning'>FAILSAFE: </span><font color='black'>[msg]</font></em></big>", R_DEBUG|R_ADMIN|R_DEV)
|
||||
|
||||
var/datum/controller/failsafe/Failsafe
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
var/datum/controller/subsystem/chat/SSchat
|
||||
|
||||
/datum/controller/subsystem/chat
|
||||
name = "Chat"
|
||||
wait = 1
|
||||
flags = SS_FIRE_IN_LOBBY
|
||||
priority = SS_PRIORITY_CHAT
|
||||
init_order = SS_INIT_CHAT
|
||||
var/list/payload = list()
|
||||
|
||||
/datum/controller/subsystem/chat/Initialize()
|
||||
NEW_SS_GLOBAL(SSchat)
|
||||
|
||||
/datum/controller/subsystem/chat/fire()
|
||||
for(var/i in payload)
|
||||
var/client/C = i
|
||||
to_target(C, output(payload[C], "browseroutput:output"))
|
||||
payload -= C
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/chat/proc/queue(target, message, handle_whitespace = TRUE, trailing_newline = TRUE)
|
||||
if(!target || !message)
|
||||
return
|
||||
|
||||
if(!istext(message))
|
||||
CRASH("to_chat called with invalid input type")
|
||||
|
||||
if(target == world)
|
||||
target = clients
|
||||
|
||||
//Some macros remain in the string even after parsing and fuck up the eventual output
|
||||
var/original_message = message
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
if(handle_whitespace)
|
||||
message = replacetext(message, "\n", "<br>")
|
||||
message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]")
|
||||
if (trailing_newline)
|
||||
message += "<br>"
|
||||
|
||||
|
||||
//url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
//Do the double-encoding here to save nanoseconds
|
||||
var/twiceEncoded = url_encode(url_encode(message))
|
||||
|
||||
if(islist(target))
|
||||
for(var/I in target)
|
||||
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
|
||||
|
||||
if(!C)
|
||||
return
|
||||
|
||||
//Send it to the old style output window.
|
||||
legacy_chat(C, original_message)
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
continue
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
continue
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
|
||||
else
|
||||
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
|
||||
|
||||
if(!C)
|
||||
return
|
||||
|
||||
//Send it to the old style output window.
|
||||
legacy_chat(C, original_message)
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
return
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
return
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
@@ -189,7 +189,6 @@
|
||||
SearchVar(debugobj)
|
||||
SearchVar(mods)
|
||||
SearchVar(gravity_is_on)
|
||||
SearchVar(server_greeting)
|
||||
SearchVar(awaydestinations)
|
||||
SearchVar(fileaccess_timer)
|
||||
SearchVar(custom_event_msg)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/datum/controller/subsystem/ping
|
||||
name = "Ping"
|
||||
priority = SS_PRIORITY_PING
|
||||
wait = 3 SECONDS
|
||||
flags = SS_NO_INIT | SS_FIRE_IN_LOBBY
|
||||
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/ping/stat_entry()
|
||||
..("P:[clients.len]")
|
||||
|
||||
|
||||
/datum/controller/subsystem/ping/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = clients.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while (currentrun.len)
|
||||
var/client/C = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
|
||||
if (!C || !C.chatOutput || !C.chatOutput.loaded)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
// softPang isn't handled anywhere but it'll always reset the opts.lastPang.
|
||||
C.chatOutput.ehjax_send(data = C.is_afk(29) ? "softPang" : "pang")
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
@@ -28,47 +28,8 @@ var/datum/controller/subsystem/theming/SStheming
|
||||
)
|
||||
)
|
||||
|
||||
var/skin_files = list("Light" = "interface/skin.txt", "Dark" = "interface/dark.txt")
|
||||
var/skin_themes
|
||||
|
||||
/datum/controller/subsystem/theming/New()
|
||||
NEW_SS_GLOBAL(SStheming)
|
||||
skin_themes = list()
|
||||
|
||||
/datum/controller/subsystem/theming/Initialize(start_timeofday)
|
||||
for(var/name in skin_files)
|
||||
skin_themes[name] = list()
|
||||
var/loaded = file2list(skin_files[name])
|
||||
for(var/op in loaded)
|
||||
var/split = text2list(op, " ")
|
||||
if(!islist(skin_themes[name][split[1]]))
|
||||
skin_themes[name][split[1]] = list()
|
||||
skin_themes[name][split[1]] += split[2]
|
||||
|
||||
for(var/mob/M in mob_list)
|
||||
if(M.client)
|
||||
apply_theme_from_perfs(M.client)
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/theming/proc/apply_theme_from_perfs(var/user)
|
||||
var/client/c
|
||||
if(ismob(user))
|
||||
var/mob/M = user
|
||||
c = M.client
|
||||
if(isclient(user))
|
||||
c = user
|
||||
if(!isclient(c))
|
||||
return
|
||||
apply_theme(user, c.prefs.skin_theme)
|
||||
|
||||
/datum/controller/subsystem/theming/proc/apply_theme(var/user, var/theme = "Dark")
|
||||
if(!isclient(user) && !ismob(user))
|
||||
return
|
||||
var/skin = skin_themes[theme]
|
||||
if(!skin)
|
||||
return
|
||||
for(var/param in skin)
|
||||
winset(user, param, jointext(skin[param], ";"))
|
||||
|
||||
/datum/controller/subsystem/theming/proc/get_html_theme(var/mob/user)
|
||||
var/client/cl = null
|
||||
|
||||
@@ -244,22 +244,22 @@ var/datum/controller/subsystem/ticker/SSticker
|
||||
var/turf/playerTurf = get_turf(Player)
|
||||
if(emergency_shuttle.departed && emergency_shuttle.evac)
|
||||
if(isNotAdminLevel(playerTurf.z))
|
||||
to_chat(Player, "<font color='blue'><b>You managed to survive, but were marooned on [station_name()] as [Player.real_name]...</b></font>")
|
||||
to_chat(Player, "<span class='notice'><b>You managed to survive, but were marooned on [station_name()] as [Player.real_name]...</b></span>")
|
||||
else
|
||||
to_chat(Player, "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></font>")
|
||||
to_chat(Player, "<span class='good'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></span>")
|
||||
else if(isAdminLevel(playerTurf.z))
|
||||
to_chat(Player, "<font color='green'><b>You successfully underwent crew transfer after events on [station_name()] as [Player.real_name].</b></font>")
|
||||
to_chat(Player, "<span class='good'><b>You successfully underwent crew transfer after events on [station_name()] as [Player.real_name].</b></span>")
|
||||
else if(issilicon(Player))
|
||||
to_chat(Player, "<font color='green'><b>You remain operational after the events on [station_name()] as [Player.real_name].</b></font>")
|
||||
to_chat(Player, "<span class='good'><b>You remain operational after the events on [station_name()] as [Player.real_name].</b></span>")
|
||||
else
|
||||
to_chat(Player, "<font color='blue'><b>You missed the crew transfer after the events on [station_name()] as [Player.real_name].</b></font>")
|
||||
to_chat(Player, "<span class='notice'><b>You missed the crew transfer after the events on [station_name()] as [Player.real_name].</b></span>")
|
||||
else
|
||||
if(istype(Player,/mob/abstract/observer))
|
||||
var/mob/abstract/observer/O = Player
|
||||
if(!O.started_as_observer)
|
||||
to_chat(Player, "<font color='red'><b>You did not survive the events on [station_name()]...</b></font>")
|
||||
to_chat(Player, "<span class='warning'><b>You did not survive the events on [station_name()]...</b></span>")
|
||||
else
|
||||
to_chat(Player, "<font color='red'><b>You did not survive the events on [station_name()]...</b></font>")
|
||||
to_chat(Player, "<span class='warning'><b>You did not survive the events on [station_name()]...</b></span>")
|
||||
to_world("<br>")
|
||||
|
||||
for (var/mob/living/silicon/ai/aiPlayer in mob_list)
|
||||
@@ -331,8 +331,8 @@ var/datum/controller/subsystem/ticker/SSticker
|
||||
m = pick(randomtips)
|
||||
|
||||
if(m)
|
||||
to_world("<font color='purple'><b>Tip of the round: \
|
||||
</b>[html_encode(m)]</font>")
|
||||
to_world("<span class='vote'><b>Tip of the round: \
|
||||
</b>[html_encode(m)]</span>")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/print_testmerges()
|
||||
var/data = revdata.testmerge_overview()
|
||||
@@ -360,7 +360,7 @@ var/datum/controller/subsystem/ticker/SSticker
|
||||
pregame_timeleft = dynamic_time
|
||||
log_debug("SSticker: dynamic set pregame time [dynamic_time]s was greater than configured autogamemode time, not clamping.")
|
||||
|
||||
to_world("<B><FONT color='blue'>Welcome to the pre-game lobby!</FONT></B>")
|
||||
to_world("<B><span class='notice'>Welcome to the pre-game lobby!</span></B>")
|
||||
to_world("Please, setup your character and select ready. Game will start in [pregame_timeleft] seconds.")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/setup()
|
||||
@@ -472,8 +472,8 @@ var/datum/controller/subsystem/ticker/SSticker
|
||||
//Deleting Startpoints but we need the ai point to AI-ize people later
|
||||
if (S.name != "AI")
|
||||
qdel(S)
|
||||
to_world("<FONT color='blue'><B>Enjoy the game!</B></FONT>")
|
||||
to_world(sound('sound/AI/welcome.ogg'))
|
||||
to_world("<span class='notice'><B>Enjoy the game!</B></span>")
|
||||
sound_to(world, sound('sound/AI/welcome.ogg'))
|
||||
//Holiday Round-start stuff ~Carn
|
||||
Holiday_Game_Start()
|
||||
|
||||
@@ -544,18 +544,18 @@ var/datum/controller/subsystem/ticker/SSticker
|
||||
if("mercenary") //Nuke wasn't on station when it blew up
|
||||
flick("intro_nuke",cinematic)
|
||||
sleep(35)
|
||||
to_world(sound('sound/effects/explosionfar.ogg'))
|
||||
sound_to(world, sound('sound/effects/explosionfar.ogg'))
|
||||
flick("station_intact_fade_red",cinematic)
|
||||
cinematic.icon_state = "summary_nukefail"
|
||||
else
|
||||
flick("intro_nuke",cinematic)
|
||||
sleep(35)
|
||||
to_world(sound('sound/effects/explosionfar.ogg'))
|
||||
sound_to(world, sound('sound/effects/explosionfar.ogg'))
|
||||
//flick("end",cinematic)
|
||||
|
||||
if(2) //nuke was nowhere nearby //TODO: a really distant explosion animation
|
||||
sleep(50)
|
||||
to_world(sound('sound/effects/explosionfar.ogg'))
|
||||
sound_to(world, sound('sound/effects/explosionfar.ogg'))
|
||||
|
||||
else //station was destroyed
|
||||
if( mode && !override )
|
||||
@@ -565,25 +565,25 @@ var/datum/controller/subsystem/ticker/SSticker
|
||||
flick("intro_nuke",cinematic)
|
||||
sleep(35)
|
||||
flick("station_explode_fade_red",cinematic)
|
||||
to_world(sound('sound/effects/explosionfar.ogg'))
|
||||
sound_to(world, sound('sound/effects/explosionfar.ogg'))
|
||||
cinematic.icon_state = "summary_nukewin"
|
||||
if("AI malfunction") //Malf (screen,explosion,summary)
|
||||
flick("intro_malf",cinematic)
|
||||
sleep(76)
|
||||
flick("station_explode_fade_red",cinematic)
|
||||
to_world(sound('sound/effects/explosionfar.ogg'))
|
||||
sound_to(world, sound('sound/effects/explosionfar.ogg'))
|
||||
cinematic.icon_state = "summary_malf"
|
||||
if("blob") //Station nuked (nuke,explosion,summary)
|
||||
flick("intro_nuke",cinematic)
|
||||
sleep(35)
|
||||
flick("station_explode_fade_red",cinematic)
|
||||
to_world(sound('sound/effects/explosionfar.ogg'))
|
||||
sound_to(world, sound('sound/effects/explosionfar.ogg'))
|
||||
cinematic.icon_state = "summary_selfdes"
|
||||
else //Station nuked (nuke,explosion,summary)
|
||||
flick("intro_nuke",cinematic)
|
||||
sleep(35)
|
||||
flick("station_explode_fade_red", cinematic)
|
||||
to_world(sound('sound/effects/explosionfar.ogg'))
|
||||
sound_to(world, sound('sound/effects/explosionfar.ogg'))
|
||||
cinematic.icon_state = "summary_selfdes"
|
||||
|
||||
//If its actually the end of the round, wait for it to end.
|
||||
|
||||
@@ -98,13 +98,13 @@ var/datum/controller/subsystem/vote/SSvote
|
||||
else
|
||||
factor = 1.4
|
||||
choices["Initiate Crew Transfer"]["votes"] = round(choices["Initiate Crew Transfer"]["votes"] * factor)
|
||||
to_world("<font color='purple'>Crew Transfer Factor: [factor]</font>")
|
||||
to_world("<span class='vote'>Crew Transfer Factor: [factor]</span>")
|
||||
greatest_votes = max(choices["Initiate Crew Transfer"]["votes"], choices["Continue The Round"]["votes"])
|
||||
|
||||
if(mode == "crew_transfer")
|
||||
if(round(get_round_duration() / 36000)+12 <= 14)
|
||||
// Credit to Scopes @ oldcode.
|
||||
to_world("<font color='purple'><b>Majority voting rule in effect. 2/3rds majority needed to initiate transfer.</b></font>")
|
||||
to_world("<span class='vote'><b>Majority voting rule in effect. 2/3rds majority needed to initiate transfer.</b></span>")
|
||||
choices["Initiate Crew Transfer"]["votes"] = round(choices["Initiate Crew Transfer"]["votes"] - round(total_votes / 3))
|
||||
greatest_votes = max(choices["Initiate Crew Transfer"]["votes"], choices["Continue The Round"]["votes"])
|
||||
|
||||
@@ -143,7 +143,7 @@ var/datum/controller/subsystem/vote/SSvote
|
||||
if(mode == "add_antagonist")
|
||||
antag_add_failed = 1
|
||||
log_vote(text)
|
||||
to_world("<font color='purple'>[text]</font>")
|
||||
to_world("<span class='vote'>[text]</span>")
|
||||
|
||||
/datum/controller/subsystem/vote/proc/result()
|
||||
. = announce_result()
|
||||
@@ -173,7 +173,7 @@ var/datum/controller/subsystem/vote/SSvote
|
||||
if(mode == "gamemode") //fire this even if the vote fails.
|
||||
if(!round_progressing)
|
||||
round_progressing = 1
|
||||
to_world("<font color='red'><b>The round will start soon.</b></font>")
|
||||
to_world("<span class='warning'><b>The round will start soon.</b></span>")
|
||||
|
||||
if(restart)
|
||||
to_world("World restarting due to vote...")
|
||||
@@ -287,20 +287,20 @@ var/datum/controller/subsystem/vote/SSvote
|
||||
text += "\n[sanitizeSafe(question)]"
|
||||
|
||||
log_vote(text)
|
||||
to_world("<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src];open=1'>here</a> to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>")
|
||||
to_world("<span class='vote'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src];open=1'>here</a> to place your votes.\nYou have [config.vote_period/10] seconds to vote.</span>")
|
||||
for(var/cc in clients)
|
||||
var/client/C = cc
|
||||
if(C.prefs.asfx_togs & ASFX_VOTE) //Personal mute
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
C << sound('sound/effects/vote.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
sound_to(C, sound('sound/effects/vote.ogg', repeat = 0, wait = 0, volume = 50, channel = 3))
|
||||
if("gamemode")
|
||||
C << sound('sound/ambience/vote_alarm.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
sound_to(C, sound('sound/ambience/vote_alarm.ogg', repeat = 0, wait = 0, volume = 50, channel = 3))
|
||||
if("custom")
|
||||
C << sound('sound/ambience/vote_alarm.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
sound_to(C, sound('sound/ambience/vote_alarm.ogg', repeat = 0, wait = 0, volume = 50, channel = 3))
|
||||
if(mode == "gamemode" && round_progressing)
|
||||
round_progressing = 0
|
||||
to_world("<font color='red'><b>Round start has been delayed.</b></font>")
|
||||
to_world("<span class='warning'><b>Round start has been delayed.</b></span>")
|
||||
SSvueui.check_uis_for_change(src)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -271,14 +271,14 @@
|
||||
if (istype(A, /atom/movable/openspace/overlay))
|
||||
var/atom/movable/openspace/overlay/OO = A
|
||||
var/atom/movable/AA = OO.associated_atom
|
||||
out += "<li>\icon[A] plane [A.plane], layer [A.layer], depth [OO.depth], associated Z-level [AA.z] - [OO.type] copying [AA] ([AA.type])</li>"
|
||||
out += "<li>[icon2html(A, usr)] plane [A.plane], layer [A.layer], depth [OO.depth], associated Z-level [AA.z] - [OO.type] copying [AA] ([AA.type])</li>"
|
||||
else if (isturf(A))
|
||||
if (A == T)
|
||||
out += "<li>\icon[A] plane [A.plane], layer [A.layer], Z-level [A.z] - [A] ([A.type]) - <font color='green'>SELF</font></li>"
|
||||
out += "<li>[icon2html(A, usr)] plane [A.plane], layer [A.layer], Z-level [A.z] - [A] ([A.type]) - <span class='good'>SELF</span></li>"
|
||||
else // foreign turfs - not visible here, but good for figuring out layering
|
||||
out += "<li>\icon[A] plane [A.plane], layer [A.layer], Z-level [A.z] - [A] ([A.type]) - <font color='red'>FOREIGN</font></li>"
|
||||
out += "<li>[icon2html(A, usr)] plane [A.plane], layer [A.layer], Z-level [A.z] - [A] ([A.type]) - <span class='warning'>FOREIGN</span></li>"
|
||||
else
|
||||
out += "<li>\icon[A] plane [A.plane], layer [A.layer], Z-level [A.z] - [A] ([A.type])</li>"
|
||||
out += "<li>[icon2html(A, usr)] plane [A.plane], layer [A.layer], Z-level [A.z] - [A] ([A.type])</li>"
|
||||
|
||||
out += "</ul>"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user