mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 13:10:02 +01:00
[MDB IGNORE] Improves status display even more, makes the brig door timers based on status displays (#69153)
This PR was originally just going to be a re-factor of brig doors to be based on status displays, as a big chunk of their code was duplicating the exact same appearance, but then I realized "Cell 1" would have marqueed for being 6 characters and ended up doing the second half of the status display overhaul I meant to do a while back. So firstly: Yes, brig doors are now subtypes of status displays. The main improvement out of that refactor, other than a lot of code trimming, is that the on-screen timer updates its readout as you set it, which looks nice. Also handled various states in a more consistent way in some edge cases. The timer now also displays the cell's actual name instead of the internal ID on the top line. Now for status displays: Long ago, I wanted the marquee to be continuous but the math required knowing the actual measured text width, though without a user that is impossible. I recently realized the scope of the text usable on status displays (no formatting, or icons) is so narrow, I can cheat it like crazy into a small lookup table and a looping function. No, this method can't possibly extend to runetext. So now the marquees loop seemlessly without any gaps! In fact behind the scenes they loop the very first pixel possible, and still done as a one-and-done animate() sequence as before. (click the preview below if you want to see it smoother) Status displays are now a bit more colorful and have gapless marquee text. Brig door timers were massively refactored behind the scenes. Door control should still work as before but be mindful.
This commit is contained in:
@@ -12086,7 +12086,7 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/station/maintenance/department/engine/atmos)
|
||||
"cMM" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "medsci-cell";
|
||||
name = "Med-Sci Cell";
|
||||
pixel_y = -32
|
||||
@@ -37019,7 +37019,7 @@
|
||||
"iXM" = (
|
||||
/obj/structure/cable,
|
||||
/obj/item/kirbyplants/random,
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "engcell";
|
||||
name = "Engineering Cell";
|
||||
pixel_y = 32
|
||||
@@ -72744,7 +72744,7 @@
|
||||
/area/station/engineering/atmos/storage/gas)
|
||||
"rNV" = (
|
||||
/obj/item/kirbyplants/random,
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "brig1";
|
||||
name = "Cell 1";
|
||||
pixel_x = -32
|
||||
@@ -78116,7 +78116,7 @@
|
||||
/area/station/maintenance/department/chapel)
|
||||
"tbZ" = (
|
||||
/obj/item/kirbyplants/random,
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "brig2";
|
||||
name = "Cell 2";
|
||||
pixel_x = -32
|
||||
@@ -83875,7 +83875,7 @@
|
||||
/turf/open/floor/iron/white/smooth_large,
|
||||
/area/station/medical/psychology)
|
||||
"uxC" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "cargocell";
|
||||
name = "Cargo Cell";
|
||||
pixel_x = -32;
|
||||
|
||||
@@ -11762,7 +11762,7 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/station/maintenance/starboard/aft)
|
||||
"dwS" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 3";
|
||||
name = "Cell 3";
|
||||
pixel_x = -32
|
||||
@@ -21111,7 +21111,7 @@
|
||||
},
|
||||
/area/station/command/heads_quarters/rd)
|
||||
"gqZ" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 2";
|
||||
name = "Cell 2";
|
||||
pixel_x = -32
|
||||
@@ -65110,7 +65110,7 @@
|
||||
/turf/open/floor/iron/white,
|
||||
/area/station/medical/medbay/aft)
|
||||
"ubo" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 1";
|
||||
name = "Cell 1";
|
||||
pixel_x = -32
|
||||
|
||||
@@ -42978,7 +42978,7 @@
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 5";
|
||||
name = "Cell 5";
|
||||
pixel_x = -32
|
||||
@@ -43511,7 +43511,7 @@
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 6";
|
||||
name = "Cell 6";
|
||||
pixel_x = -32
|
||||
@@ -48306,7 +48306,7 @@
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 2";
|
||||
name = "Cell 2";
|
||||
pixel_x = -32
|
||||
@@ -58517,7 +58517,7 @@
|
||||
/obj/effect/turf_decal/stripes/corner{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 3";
|
||||
name = "Cell 3";
|
||||
pixel_x = -32
|
||||
@@ -59719,7 +59719,7 @@
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 1";
|
||||
name = "Cell 1";
|
||||
pixel_x = -32
|
||||
@@ -65931,7 +65931,7 @@
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 4";
|
||||
name = "Cell 4";
|
||||
pixel_x = -32
|
||||
|
||||
@@ -9419,7 +9419,7 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/station/hallway/secondary/exit/departure_lounge)
|
||||
"dyr" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 3";
|
||||
name = "Cell 3";
|
||||
pixel_x = 32;
|
||||
@@ -55584,7 +55584,7 @@
|
||||
/area/station/engineering/storage/tech)
|
||||
"tDz" = (
|
||||
/obj/machinery/light/directional/south,
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 1";
|
||||
name = "Cell 1";
|
||||
pixel_y = -32
|
||||
@@ -68034,7 +68034,7 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/station/maintenance/department/science/central)
|
||||
"xWQ" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "Cell 2";
|
||||
name = "Cell 2";
|
||||
pixel_y = -32
|
||||
|
||||
@@ -20462,7 +20462,7 @@
|
||||
/obj/effect/turf_decal/trimline/red/filled/line{
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "scicell";
|
||||
name = "Science Cell";
|
||||
pixel_y = 32
|
||||
@@ -32076,7 +32076,7 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/station/hallway/secondary/command)
|
||||
"ldp" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "crgcell";
|
||||
name = "Cargo Cell";
|
||||
pixel_x = 32
|
||||
@@ -38603,7 +38603,7 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/station/engineering/atmospherics_engine)
|
||||
"niv" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "medcell";
|
||||
name = "Medical Cell";
|
||||
pixel_y = 32
|
||||
@@ -40184,7 +40184,7 @@
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/station/engineering/supermatter/room)
|
||||
"nNP" = (
|
||||
/obj/machinery/door_timer{
|
||||
/obj/machinery/status_display/door_timer{
|
||||
id = "engcell";
|
||||
name = "Engineering Cell";
|
||||
pixel_x = -32
|
||||
|
||||
@@ -107,7 +107,6 @@ GLOBAL_LIST_INIT(WALLITEMS_INTERIOR, typecacheof(list(
|
||||
/obj/machinery/computer/security/telescreen,
|
||||
/obj/machinery/computer/security/telescreen/entertainment,
|
||||
/obj/machinery/defibrillator_mount,
|
||||
/obj/machinery/door_timer,
|
||||
/obj/machinery/embedded_controller/radio/simple_vent_controller,
|
||||
/obj/machinery/firealarm,
|
||||
/obj/machinery/flasher,
|
||||
|
||||
@@ -1,30 +1,22 @@
|
||||
#define CHARS_PER_LINE 5
|
||||
#define FONT_SIZE "5pt"
|
||||
#define FONT_COLOR "#09f"
|
||||
#define FONT_STYLE "Small Fonts"
|
||||
#define MAX_TIMER 15 MINUTES
|
||||
|
||||
#define PRESET_SHORT 2 MINUTES
|
||||
#define PRESET_MEDIUM 3 MINUTES
|
||||
#define PRESET_LONG 5 MINUTES
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Brig Door control displays.
|
||||
// Description: This is a controls the timer for the brig doors, displays the timer on itself and
|
||||
// has a popup window when used, allowing to set the timer.
|
||||
// Code Notes: Combination of old brigdoor.dm code from rev4407 and the status_display.dm code
|
||||
// Date: 01/September/2010
|
||||
// Programmer: Veryinky
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/obj/machinery/door_timer
|
||||
/**
|
||||
* Brig Door control displays.
|
||||
*
|
||||
* This is a controls the timer for the brig doors, displays the timer on itself and
|
||||
* has a popup window when used, allowing to set the timer.
|
||||
*/
|
||||
/obj/machinery/status_display/door_timer
|
||||
name = "door timer"
|
||||
icon = 'icons/obj/status_display.dmi'
|
||||
icon_state = "frame"
|
||||
desc = "A remote control for a door."
|
||||
current_mode = SD_MESSAGE
|
||||
req_access = list(ACCESS_SECURITY)
|
||||
density = FALSE
|
||||
text_color = "#F44"
|
||||
header_text_color = "#F88"
|
||||
|
||||
var/id = null // id of linked machinery/lockers
|
||||
|
||||
var/activation_time = 0
|
||||
@@ -37,21 +29,15 @@
|
||||
var/list/flashers = list()
|
||||
///List of weakrefs to nearby closets
|
||||
var/list/closets = list()
|
||||
///needed to send messages to sec radio
|
||||
var/obj/item/radio/sec_radio
|
||||
|
||||
var/obj/item/radio/Radio //needed to send messages to sec radio
|
||||
|
||||
maptext_height = 26
|
||||
maptext_width = 32
|
||||
maptext_y = -1
|
||||
|
||||
/obj/machinery/door_timer/Initialize(mapload)
|
||||
/obj/machinery/status_display/door_timer/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
Radio = new/obj/item/radio(src)
|
||||
Radio.set_listening(FALSE)
|
||||
sec_radio = new/obj/item/radio(src)
|
||||
sec_radio.set_listening(FALSE)
|
||||
|
||||
/obj/machinery/door_timer/Initialize(mapload)
|
||||
. = ..()
|
||||
if(id != null)
|
||||
for(var/obj/machinery/door/window/brigdoor/M in urange(20, src))
|
||||
if (M.id == id)
|
||||
@@ -67,29 +53,48 @@
|
||||
|
||||
if(!length(doors) && !length(flashers) && length(closets))
|
||||
atom_break()
|
||||
update_appearance()
|
||||
|
||||
|
||||
//Main door timer loop, if it's timing and time is >0 reduce time by 1.
|
||||
// if it's less than 0, open door, reset timer
|
||||
// update the door_timer window and the icon
|
||||
/obj/machinery/door_timer/process()
|
||||
/obj/machinery/status_display/door_timer/process()
|
||||
if(machine_stat & (NOPOWER|BROKEN))
|
||||
// No power, no processing.
|
||||
update_appearance()
|
||||
return PROCESS_KILL
|
||||
|
||||
if(!timing)
|
||||
return PROCESS_KILL
|
||||
|
||||
if(world.time - activation_time >= timer_duration)
|
||||
timer_end() // open doors, reset timer, clear status screen
|
||||
update_content()
|
||||
|
||||
/**
|
||||
* Update the display content.
|
||||
*/
|
||||
/obj/machinery/status_display/door_timer/proc/update_content()
|
||||
var/time_left = time_left(seconds = TRUE)
|
||||
|
||||
if(time_left == 0)
|
||||
set_messages("", "")
|
||||
return
|
||||
|
||||
if(timing)
|
||||
if(world.time - activation_time >= timer_duration)
|
||||
timer_end() // open doors, reset timer, clear status screen
|
||||
update_appearance()
|
||||
var/disp1 = name
|
||||
var/disp2 = "[add_leading(num2text((time_left / 60) % 60), 2, "0")]:[add_leading(num2text(time_left % 60), 2, "0")]"
|
||||
set_messages(disp1, disp2)
|
||||
|
||||
// open/closedoor checks if door_timer has power, if so it checks if the
|
||||
// linked door is open/closed (by density) then opens it/closes it.
|
||||
/obj/machinery/door_timer/proc/timer_start()
|
||||
/**
|
||||
* Starts counting down the timer and closes linked the door.
|
||||
* The timer is expected to have already been set by set_timer()
|
||||
*/
|
||||
/obj/machinery/status_display/door_timer/proc/timer_start()
|
||||
if(machine_stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
|
||||
activation_time = world.time
|
||||
timing = TRUE
|
||||
begin_processing()
|
||||
|
||||
for(var/datum/weakref/door_ref as anything in doors)
|
||||
var/obj/machinery/door/window/brigdoor/door = door_ref.resolve()
|
||||
@@ -113,20 +118,23 @@
|
||||
closet.update_appearance()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/door_timer/proc/timer_end(forced = FALSE)
|
||||
|
||||
/**
|
||||
* Stops the timer and resets the timer to 0, and opens the linked door.
|
||||
* Arguments:
|
||||
* * forced - TRUE if it was forced to stop rather than timing out. Will skip radioing, etc.
|
||||
*/
|
||||
/obj/machinery/status_display/door_timer/proc/timer_end(forced = FALSE)
|
||||
if(machine_stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
|
||||
if(!forced)
|
||||
Radio.set_frequency(FREQ_SECURITY)
|
||||
Radio.talk_into(src, "Timer has expired. Releasing prisoner.", FREQ_SECURITY)
|
||||
sec_radio.set_frequency(FREQ_SECURITY)
|
||||
sec_radio.talk_into(src, "Timer has expired. Releasing prisoner.", FREQ_SECURITY)
|
||||
|
||||
timing = FALSE
|
||||
activation_time = null
|
||||
set_timer(0)
|
||||
update_appearance()
|
||||
end_processing()
|
||||
|
||||
for(var/datum/weakref/door_ref as anything in doors)
|
||||
var/obj/machinery/door/window/brigdoor/door = door_ref.resolve()
|
||||
@@ -151,67 +159,37 @@
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/door_timer/proc/time_left(seconds = FALSE)
|
||||
. = max(0,timer_duration - (activation_time ? world.time - activation_time : 0))
|
||||
/**
|
||||
* Return time left.
|
||||
* Arguments:
|
||||
* * seconds - return time in seconds it TRUE, else deciseconds.
|
||||
*/
|
||||
/obj/machinery/status_display/door_timer/proc/time_left(seconds = FALSE)
|
||||
. = max(0, timer_duration - (activation_time ? world.time - activation_time : 0))
|
||||
if(seconds)
|
||||
. /= 10
|
||||
|
||||
/obj/machinery/door_timer/proc/set_timer(value)
|
||||
var/new_time = clamp(value,0,MAX_TIMER)
|
||||
/**
|
||||
* Set the timer. Does NOT automatically start counting down, but does update the display.
|
||||
*
|
||||
* returns TRUE if no change occurred
|
||||
*
|
||||
* Arguments:
|
||||
* value - time in deciseconds to set the timer for.
|
||||
*/
|
||||
/obj/machinery/status_display/door_timer/proc/set_timer(value)
|
||||
var/new_time = clamp(value, 0, MAX_TIMER)
|
||||
. = new_time == timer_duration //return 1 on no change
|
||||
timer_duration = new_time
|
||||
update_content()
|
||||
|
||||
/obj/machinery/door_timer/ui_interact(mob/user, datum/tgui/ui)
|
||||
/obj/machinery/status_display/door_timer/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "BrigTimer", name)
|
||||
ui.open()
|
||||
|
||||
//icon update function
|
||||
// if NOPOWER, display blank
|
||||
// if BROKEN, display blue screen of death icon AI uses
|
||||
// if timing=true, run update display function
|
||||
/obj/machinery/door_timer/update_icon()
|
||||
. = ..()
|
||||
if(machine_stat & (NOPOWER))
|
||||
return
|
||||
|
||||
if(machine_stat & (BROKEN))
|
||||
set_picture("ai_bsod")
|
||||
return
|
||||
|
||||
if(timing)
|
||||
var/disp1 = id
|
||||
var/time_left = time_left(seconds = TRUE)
|
||||
var/disp2 = "[add_leading(num2text((time_left / 60) % 60), 2, "0")]:[add_leading(num2text(time_left % 60), 2, "0")]"
|
||||
if(length(disp2) > CHARS_PER_LINE)
|
||||
disp2 = "Error"
|
||||
update_display(disp1, disp2)
|
||||
else
|
||||
if(maptext)
|
||||
maptext = ""
|
||||
return
|
||||
|
||||
|
||||
// Adds an icon in case the screen is broken/off, stolen from status_display.dm
|
||||
/obj/machinery/door_timer/proc/set_picture(state)
|
||||
if(maptext)
|
||||
maptext = ""
|
||||
cut_overlays()
|
||||
add_overlay(mutable_appearance('icons/obj/status_display.dmi', state))
|
||||
|
||||
|
||||
//Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display
|
||||
// Stolen from status_display
|
||||
/obj/machinery/door_timer/proc/update_display(line1, line2)
|
||||
line1 = uppertext(line1)
|
||||
line2 = uppertext(line2)
|
||||
var/new_text = {"<div style="font-size:[FONT_SIZE];color:[FONT_COLOR];font:'[FONT_STYLE]';text-align:center;" valign="top">[line1]<br>[line2]</div>"}
|
||||
if(maptext != new_text)
|
||||
maptext = new_text
|
||||
|
||||
/obj/machinery/door_timer/ui_data()
|
||||
/obj/machinery/status_display/door_timer/ui_data()
|
||||
var/list/data = list()
|
||||
var/time_left = time_left(seconds = TRUE)
|
||||
data["seconds"] = round(time_left % 60)
|
||||
@@ -228,8 +206,7 @@
|
||||
break
|
||||
return data
|
||||
|
||||
|
||||
/obj/machinery/door_timer/ui_act(action, params)
|
||||
/obj/machinery/status_display/door_timer/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
@@ -284,13 +261,7 @@
|
||||
else
|
||||
. = FALSE
|
||||
|
||||
|
||||
#undef PRESET_SHORT
|
||||
#undef PRESET_MEDIUM
|
||||
#undef PRESET_LONG
|
||||
|
||||
#undef MAX_TIMER
|
||||
#undef FONT_SIZE
|
||||
#undef FONT_COLOR
|
||||
#undef FONT_STYLE
|
||||
#undef CHARS_PER_LINE
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// Status display
|
||||
// (formerly Countdown timer display)
|
||||
|
||||
#define CHARS_PER_LINE 5
|
||||
#define FONT_SIZE "5pt"
|
||||
#define FONT_COLOR "#09f"
|
||||
#define FONT_STYLE "Small Fonts"
|
||||
#define MAX_STATIC_WIDTH 25
|
||||
#define FONT_STYLE "5pt 'Small Fonts'"
|
||||
#define SCROLL_RATE (0.04 SECONDS) // time per pixel
|
||||
#define LINE1_Y -8
|
||||
#define LINE2_Y -15
|
||||
@@ -20,7 +18,6 @@
|
||||
desc = null
|
||||
icon = 'icons/obj/status_display.dmi'
|
||||
icon_state = "frame"
|
||||
base_icon_state = "unanchoredstatusdisplay"
|
||||
verb_say = "beeps"
|
||||
verb_ask = "beeps"
|
||||
verb_exclaim = "beeps"
|
||||
@@ -34,6 +31,11 @@
|
||||
var/message1 = ""
|
||||
var/message2 = ""
|
||||
|
||||
/// Normal text color
|
||||
var/text_color = "#09F"
|
||||
/// Color for headers, eg. "- ETA -"
|
||||
var/header_text_color = "#2CF"
|
||||
|
||||
/obj/item/wallframe/status_display
|
||||
name = "status display frame"
|
||||
desc = "Used to build status displays, just secure to the wall."
|
||||
@@ -42,6 +44,11 @@
|
||||
result_path = /obj/machinery/status_display/evac
|
||||
pixel_shift = 32
|
||||
|
||||
//makes it go on the wall when built
|
||||
/obj/machinery/status_display/Initialize(mapload, ndir, building)
|
||||
. = ..()
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/status_display/wrench_act_secondary(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
balloon_alert(user, "[anchored ? "un" : ""]securing...")
|
||||
@@ -125,7 +132,7 @@
|
||||
if(overlay)
|
||||
qdel(overlay)
|
||||
|
||||
var/obj/effect/overlay/status_display_text/new_status_display_text = new(src, line_y, message)
|
||||
var/obj/effect/overlay/status_display_text/new_status_display_text = new(src, line_y, message, text_color, header_text_color)
|
||||
vis_contents += new_status_display_text
|
||||
return new_status_display_text
|
||||
|
||||
@@ -198,9 +205,9 @@
|
||||
if (message1_overlay || message2_overlay)
|
||||
. += "The display says:"
|
||||
if (message1_overlay.message)
|
||||
. += "<br>\t<tt>[html_encode(message1_overlay.message)]</tt>"
|
||||
. += "\t<tt>[html_encode(message1_overlay.message)]</tt>"
|
||||
if (message2_overlay.message)
|
||||
. += "<br>\t<tt>[html_encode(message2_overlay.message)]</tt>"
|
||||
. += "\t<tt>[html_encode(message2_overlay.message)]</tt>"
|
||||
|
||||
// Helper procs for child display types.
|
||||
/obj/machinery/status_display/proc/display_shuttle_status(obj/docking_port/mobile/shuttle)
|
||||
@@ -209,28 +216,14 @@
|
||||
set_messages("shutl?","")
|
||||
return PROCESS_KILL
|
||||
else if(shuttle.timer)
|
||||
var/line1 = "-[shuttle.getModeStr()]-"
|
||||
var/line1 = "- [shuttle.getModeStr()] -"
|
||||
var/line2 = shuttle.getTimerStr()
|
||||
|
||||
if(length_char(line2) > CHARS_PER_LINE)
|
||||
line2 = "error"
|
||||
set_messages(line1, line2)
|
||||
else
|
||||
// don't kill processing, the timer might turn back on
|
||||
set_messages("", "")
|
||||
|
||||
/obj/machinery/status_display/proc/examine_shuttle(mob/user, obj/docking_port/mobile/shuttle)
|
||||
if (shuttle)
|
||||
var/modestr = shuttle.getModeStr()
|
||||
if (modestr)
|
||||
if (shuttle.timer)
|
||||
modestr = "<br>\t<tt>[modestr]: [shuttle.getTimerStr()]</tt>"
|
||||
else
|
||||
modestr = "<br>\t<tt>[modestr]</tt>"
|
||||
return "The display says:<br>\t<tt>[shuttle.name]</tt>[modestr]"
|
||||
else
|
||||
return "The display says:<br>\t<tt>Shuttle missing!</tt>"
|
||||
|
||||
/obj/machinery/status_display/Destroy()
|
||||
remove_messages()
|
||||
return ..()
|
||||
@@ -242,39 +235,93 @@
|
||||
icon = 'icons/obj/status_display.dmi'
|
||||
vis_flags = VIS_INHERIT_LAYER | VIS_INHERIT_PLANE | VIS_INHERIT_ID
|
||||
|
||||
/// The message this overlay is displaying.
|
||||
var/message
|
||||
|
||||
/obj/effect/overlay/status_display_text/Initialize(mapload, yoffset, line)
|
||||
// If the line is short enough to not marquee, and it matches this, it's a header.
|
||||
var/static/regex/header_regex = regex("^-.*-$")
|
||||
|
||||
/// Width of each character, including kerning gap afterwards.
|
||||
/// We don't use rich text or anything fancy, so we can bake these values.
|
||||
var/static/list/char_widths = list(
|
||||
// ! " # $ % & ' ( ) * + , - . /
|
||||
1, 2, 3, 5, 4, 5, 5, 2, 3, 3, 3, 4, 2, 3, 2, 3,
|
||||
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
|
||||
4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 3, 3, 3, 3,
|
||||
// @ A B C D E F G H I J K L M N O
|
||||
7, 5, 5, 5, 5, 4, 4, 5, 5, 2, 4, 5, 4, 6, 5, 5,
|
||||
// P Q R S T U V W X Y Z [ \ ] ^ _
|
||||
5, 5, 5, 5, 4, 5, 4, 6, 4, 4, 4, 3, 3, 3, 4, 4,
|
||||
// ` a b c d e f g h i j k l m n o
|
||||
3, 5, 5, 5, 5, 4, 4, 5, 5, 2, 4, 5, 4, 6, 5, 5,
|
||||
// p q r s t u v w x y z { | } ~
|
||||
5, 5, 5, 5, 4, 5, 4, 6, 4, 4, 4, 3, 2, 3, 4,
|
||||
)
|
||||
|
||||
/obj/effect/overlay/status_display_text/Initialize(mapload, yoffset, line, text_color, header_text_color)
|
||||
. = ..()
|
||||
|
||||
maptext_y = yoffset
|
||||
message = line
|
||||
|
||||
var/line_length = length_char(line)
|
||||
var/line_width = measure_width(line)
|
||||
|
||||
if(line_length > CHARS_PER_LINE)
|
||||
if(line_width > MAX_STATIC_WIDTH)
|
||||
// Marquee text
|
||||
var/marquee_message = "[line] • [line] • [line]"
|
||||
var/marquee_length = line_length * 3 + 6
|
||||
maptext = generate_text(marquee_message, center = FALSE)
|
||||
maptext_width = 6 * marquee_length
|
||||
maptext_x = 32
|
||||
var/marquee_message = "[line] - [line] - [line]"
|
||||
|
||||
// Width of full content. Must of these is never revealed unless the user inputted a single character.
|
||||
var/full_marquee_width = measure_width(marquee_message)
|
||||
// We loop after only this much has passed.
|
||||
var/looping_marquee_width = measure_width("[line] - ")
|
||||
|
||||
maptext = generate_text(marquee_message, center = FALSE, text_color = text_color)
|
||||
maptext_width = full_marquee_width
|
||||
maptext_x = 0
|
||||
|
||||
// Mask off to fit in screen.
|
||||
add_filter("mask", 1, alpha_mask_filter(icon = icon(icon, "outline")))
|
||||
|
||||
// Scroll.
|
||||
var/width = 4 * marquee_length
|
||||
var/time = (width + 32) * SCROLL_RATE
|
||||
animate(src, maptext_x = -width, time = time, loop = -1)
|
||||
animate(maptext_x = 32, time = 0)
|
||||
var/time = looping_marquee_width * SCROLL_RATE
|
||||
animate(src, maptext_x = -looping_marquee_width, time = time, loop = -1)
|
||||
animate(maptext_x = 0, time = 0)
|
||||
else
|
||||
// Centered text
|
||||
maptext = generate_text(line, center = TRUE)
|
||||
var/color = header_regex.Find(line) ? header_text_color : text_color
|
||||
maptext = generate_text(line, center = TRUE, text_color = color)
|
||||
maptext_x = 0
|
||||
|
||||
/obj/effect/overlay/status_display_text/proc/generate_text(text, center)
|
||||
return {"<div style="font-size:[FONT_SIZE];color:[FONT_COLOR];font:'[FONT_STYLE]'[center ? ";text-align:center" : ""]" valign="top">[text]</div>"}
|
||||
/**
|
||||
* A hyper-streamlined version of MeasureText that doesn't support different fonts, rich formatting, or multiline.
|
||||
* But it also doesn't require a client.
|
||||
*
|
||||
* Returns the width in pixels
|
||||
*
|
||||
* Arguments:
|
||||
* * text - the text to measure
|
||||
*/
|
||||
/obj/effect/overlay/status_display_text/proc/measure_width(text)
|
||||
var/width = 0
|
||||
for(var/text_idx in 1 to length(text))
|
||||
var/ascii = text2ascii(text, text_idx)
|
||||
if(!(ascii in 0x20 to 0x7E))
|
||||
// So we can't possibly runtime, even though the input should be in range already.
|
||||
width += 3
|
||||
continue
|
||||
width += char_widths[ascii - 0x1F]
|
||||
|
||||
return width
|
||||
|
||||
/**
|
||||
* Generate the actual maptext.
|
||||
* Arguments:
|
||||
* * text - the text to display
|
||||
* * center - center the text if TRUE, otherwise left-align
|
||||
* * text_color - the text color
|
||||
*/
|
||||
/obj/effect/overlay/status_display_text/proc/generate_text(text, center, text_color)
|
||||
return {"<div style="color:[text_color];font:[FONT_STYLE][center ? ";text-align:center" : ""]" valign="top">[text]</div>"}
|
||||
|
||||
/// Evac display which shows shuttle timer or message set by Command.
|
||||
/obj/machinery/status_display/evac
|
||||
@@ -285,11 +332,6 @@
|
||||
|
||||
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
|
||||
|
||||
//makes it go on the wall when built
|
||||
/obj/machinery/status_display/Initialize(mapload, ndir, building)
|
||||
. = ..()
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/status_display/evac/Initialize(mapload)
|
||||
. = ..()
|
||||
// register for radio system
|
||||
@@ -328,13 +370,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
|
||||
set_picture(last_picture)
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/machinery/status_display/evac/examine(mob/user)
|
||||
. = ..()
|
||||
if(current_mode == SD_EMERGENCY)
|
||||
. += examine_shuttle(user, SSshuttle.emergency)
|
||||
else if(!message1 && !message2)
|
||||
. += "The display is blank."
|
||||
|
||||
/obj/machinery/status_display/evac/receive_signal(datum/signal/signal)
|
||||
switch(signal.data["command"])
|
||||
if("blank")
|
||||
@@ -359,6 +394,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
|
||||
/obj/machinery/status_display/supply
|
||||
name = "supply display"
|
||||
current_mode = SD_MESSAGE
|
||||
text_color = "#F90"
|
||||
header_text_color = "#FC2"
|
||||
|
||||
/obj/machinery/status_display/supply/process()
|
||||
if(machine_stat & NOPOWER)
|
||||
@@ -381,26 +418,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
|
||||
line1 = ""
|
||||
line2 = ""
|
||||
else
|
||||
line1 = "CARGO"
|
||||
line1 = "- [SSshuttle.supply.getModeStr()] -"
|
||||
line2 = SSshuttle.supply.getTimerStr()
|
||||
if(length_char(line2) > CHARS_PER_LINE)
|
||||
line2 = "Error"
|
||||
set_messages(line1, line2)
|
||||
|
||||
/obj/machinery/status_display/supply/examine(mob/user)
|
||||
. = ..()
|
||||
var/obj/docking_port/mobile/shuttle = SSshuttle.supply
|
||||
var/shuttleMsg = null
|
||||
if (shuttle.mode == SHUTTLE_IDLE)
|
||||
if (is_station_level(shuttle.z))
|
||||
shuttleMsg = "Docked"
|
||||
else
|
||||
shuttleMsg = "[shuttle.getModeStr()]: [shuttle.getTimerStr()]"
|
||||
if (shuttleMsg)
|
||||
. += "The display says:<br>\t<tt>[shuttleMsg]</tt>"
|
||||
else
|
||||
. += "The display is blank."
|
||||
|
||||
|
||||
/// General-purpose shuttle status display.
|
||||
/obj/machinery/status_display/shuttle
|
||||
@@ -408,6 +429,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
|
||||
current_mode = SD_MESSAGE
|
||||
var/shuttle_id
|
||||
|
||||
text_color = "#0F5"
|
||||
header_text_color = "#2FC"
|
||||
|
||||
/obj/machinery/status_display/shuttle/process()
|
||||
if(!shuttle_id || (machine_stat & NOPOWER))
|
||||
// No power, no processing.
|
||||
@@ -416,13 +440,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
|
||||
|
||||
return display_shuttle_status(SSshuttle.getShuttle(shuttle_id))
|
||||
|
||||
/obj/machinery/status_display/shuttle/examine(mob/user)
|
||||
. = ..()
|
||||
if(shuttle_id)
|
||||
. += examine_shuttle(user, SSshuttle.getShuttle(shuttle_id))
|
||||
else
|
||||
. += "The display is blank."
|
||||
|
||||
/obj/machinery/status_display/shuttle/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
if(!.)
|
||||
@@ -574,9 +591,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/ai, 32)
|
||||
|
||||
connected_display.receive_signal(status_signal)
|
||||
|
||||
#undef CHARS_PER_LINE
|
||||
#undef FONT_SIZE
|
||||
#undef FONT_COLOR
|
||||
#undef MAX_STATIC_WIDTH
|
||||
#undef FONT_STYLE
|
||||
#undef SCROLL_RATE
|
||||
#undef LINE1_Y
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
if(temp.critical_machine) //Skip doors in critical positions, such as the SM chamber.
|
||||
continue
|
||||
temp.prison_open()
|
||||
else if(istype(O, /obj/machinery/door_timer))
|
||||
var/obj/machinery/door_timer/temp = O
|
||||
else if(istype(O, /obj/machinery/status_display/door_timer))
|
||||
var/obj/machinery/status_display/door_timer/temp = O
|
||||
temp.timer_end(forced = TRUE)
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/obj/machinery/door_timer : /obj/machinery/status_display/door_timer{@OLD}
|
||||
Reference in New Issue
Block a user