Merge pull request #16500 from VOREStation/master

10/20/24 - Map Swap
This commit is contained in:
Casey
2024-10-20 17:20:41 -04:00
committed by GitHub
851 changed files with 8064 additions and 4663 deletions
+1
View File
@@ -113,6 +113,7 @@ jobs:
sudo apt update || true
sudo apt install zlib1g-dev:i386 libssl-dev:i386
ldd librust_g.so
ldd libverdigris.so
- name: Unit Tests
run: |
tools/ci/install_byond.sh
@@ -292,7 +292,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear ratchet.")
deconstruct()
@@ -252,7 +252,7 @@ Thus, the two variables affect pump operation are set in New():
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear ratchet.")
deconstruct()
@@ -91,7 +91,7 @@
playsound(src, W.usesound, 50, 1)
if(do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + "unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
@@ -162,7 +162,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
@@ -105,7 +105,7 @@
// return
// usr.set_machine(src)
// var/list/node_connects = get_node_connect_dirs()
// var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[use_power?"On":"Off"]</a><br>
// var/dat = {span_bold("Power: ") + "<a href='?src=\ref[src];power=1'>[use_power?"On":"Off"]</a><br>
// <b>Set Flow Rate Limit: </b>
// [set_flow_rate]L/s | <a href='?src=\ref[src];set_press=1'>Change</a>
// <br>
@@ -62,7 +62,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
+1 -1
View File
@@ -337,7 +337,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
@@ -81,7 +81,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
@@ -171,7 +171,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
@@ -398,7 +398,7 @@
if(!src || !WT.isOn()) return
playsound(src, WT.usesound, 50, 1)
if(!welded)
user.visible_message("<b>\The [user]</b> welds the vent shut.", span_notice("You weld the vent shut."), "You hear welding.")
user.visible_message(span_bold("\The [user]") + " welds the vent shut.", span_notice("You weld the vent shut."), "You hear welding.")
welded = 1
update_icon()
else
@@ -446,7 +446,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
@@ -287,7 +287,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
+1 -1
View File
@@ -301,7 +301,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
+1 -1
View File
@@ -130,7 +130,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 10 * W.toolspeed))
user.visible_message( \
"<b>\The [user]</b> unfastens \the [src].", \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
+3 -3
View File
@@ -110,7 +110,7 @@ var/global/vs_control/vsc = new
vw = vars[ch]
if("[ch]_DESC" in vars) vw_desc = vars["[ch]_DESC"]
if("[ch]_NAME" in vars) vw_name = vars["[ch]_NAME"]
dat += "<b>[vw_name] = [vw]</b> <A href='?src=\ref[src];[HrefToken()];changevar=[ch]'>\[Change\]</A><br>"
dat += span_bold("[vw_name] = [vw]") + " <A href='?src=\ref[src];[HrefToken()];changevar=[ch]'>\[Change\]</A><br>"
dat += "<i>[vw_desc]</i><br><br>"
user << browse(dat,"window=settings")
@@ -168,7 +168,7 @@ var/global/vs_control/vsc = new
vars[ch] = vw
if(how == "Toggle")
newvar = (newvar?"ON":"OFF")
to_world(span_notice("<b>[key_name(user)] changed the setting [display_description] to [newvar].</b>"))
to_world(span_world(span_blue("[key_name(user)] changed the setting [display_description] to [newvar].")))
if(ch in plc.settings)
ChangeSettingsDialog(user,plc.settings)
else
@@ -321,7 +321,7 @@ var/global/vs_control/vsc = new
plc.N2O_HALLUCINATION = initial(plc.N2O_HALLUCINATION)
to_world(span_notice("<b>[key_name(user)] changed the global phoron/ZAS settings to \"[def]\"</b>"))
to_world(span_world(span_blue("[key_name(user)] changed the global phoron/ZAS settings to \"[def]\"")))
/pl_control/var/list/settings = list()
+4
View File
@@ -63,6 +63,10 @@
#define SS_PAUSED 3 /// paused by mc_tick_check
#define SS_SLEEPING 4 /// fire() slept.
#define SS_PAUSING 5 /// in the middle of pausing
// Subsystem init stages
#define INITSTAGE_EARLY 1 //! Early init stuff that doesn't need to wait for mapload
#define INITSTAGE_MAIN 2 //! Main init stage
#define INITSTAGE_MAX 2 //! Highest initstage.
#define SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/##X);\
/datum/controller/subsystem/##X/New(){\
+56
View File
@@ -0,0 +1,56 @@
//Defines file for byond click related parameters
//this is mostly for ease of use and for finding all the things that use say RIGHT_CLICK rather then just searching "right"
//Mouse buttons held
#define RIGHT_CLICK "right"
#define MIDDLE_CLICK "middle"
#define LEFT_CLICK "left"
///Mouse button that was just clicked/released
///if(modifiers[BUTTON] == LEFT_CLICK)
#define BUTTON "button"
//Keys held down during the mouse action
#define CTRL_CLICK "ctrl"
#define ALT_CLICK "alt"
#define SHIFT_CLICK "shift"
//Cells involved if using a Grid control
#define DRAG_CELL "drag-cell"
#define DROP_CELL "drop-cell"
//The button used for dragging (only sent for unrelated mouse up/down messages during a drag)
#define DRAG "drag"
//If the mouse is over a link in maptext, or this event is related to clicking such a link
#define LINK "link"
//Pixel coordinates relative to the icon's position on screen
#define VIS_X "vis-x"
#define VIS_Y "vis-y"
//Pixel coordinates within the icon, in the icon's coordinate space
#define ICON_X "icon-x"
#define ICON_Y "icon-y"
//Pixel coordinates in screen_loc format ("[tile_x]:[pixel_x],[tile_y]:[pixel_y]")
#define SCREEN_LOC "screen-loc"
//https://secure.byond.com/docs/ref/info.html#/atom/var/mouse_opacity
/// Objects will ignore being clicked on regardless of their transparency (used in parallax, lighting effects, holograms, lasers, etc.)
#define MOUSE_OPACITY_TRANSPARENT 0
/// Objects will be clicked on if it is the topmost object and the pixel isn't transparent at the position of the mouse (default behavior for 99.99% of game objects)
#define MOUSE_OPACITY_ICON 1
/// Objects will be always be clicked on regardless of pixel transparency or other objects at that location (used in space vines, storage containers)
#define MOUSE_OPACITY_OPAQUE 2
/// Whatever the base action datum thinks is best
#define SCRN_OBJ_DEFAULT "default"
/// Floating somewhere on the hud, not in any predefined place
#define SCRN_OBJ_FLOATING "floating"
/// In the list of buttons stored at the top of the screen
#define SCRN_OBJ_IN_LIST "list"
/// In the collapseable palette
#define SCRN_OBJ_IN_PALETTE "palette"
/// In cult spell list
#define SCRN_OBJ_CULT_LIST "cult_list"
+14
View File
@@ -0,0 +1,14 @@
// Stuff that is relatively "core" and is used in other defines/helpers
/**
* The game's world.icon_size. \
* Ideally divisible by 16. \
* Ideally a number, but it
* can be a string ("32x32"), so more exotic coders
* will be sad if you use this in math.
*/
#define ICON_SIZE_ALL 32
/// The X/Width dimension of ICON_SIZE. This will more than likely be the bigger axis.
#define ICON_SIZE_X 32
/// The Y/Height dimension of ICON_SIZE. This will more than likely be the smaller axis.
#define ICON_SIZE_Y 32
+13 -1
View File
@@ -1,15 +1,27 @@
/// Percentage of tick to leave for master controller to run
#define MAPTICK_MC_MIN_RESERVE 70
#define MAPTICK_LAST_INTERNAL_TICK_USAGE (world.map_cpu)
#define TICK_LIMIT_RUNNING 80
/// Tick limit used to resume things in stoplag
#define TICK_LIMIT_TO_RUN 70
/// Tick limit for MC while running
#define TICK_LIMIT_MC 70
#define TICK_LIMIT_MC_INIT_DEFAULT 98
/// for general usage of tick_usage
#define TICK_USAGE world.tick_usage
/// to be used where the result isn't checked
#define TICK_USAGE_REAL world.tick_usage
/// Returns true if tick_usage is above the limit
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
/// runs stoplag if tick_usage is above the limit
#define CHECK_TICK ( TICK_CHECK ? stoplag() : 0 )
/// Returns true if tick usage is above 95, for high priority usage
#define TICK_CHECK_HIGH_PRIORITY ( TICK_USAGE > 95 )
/// runs stoplag if tick_usage is above 95, for high priority usage
#define CHECK_TICK_HIGH_PRIORITY ( TICK_CHECK_HIGH_PRIORITY? stoplag() : 0 )
#define UNTIL(X) while(!(X)) stoplag()
#define UNTIL(X) while(!(X)) stoplag()
+1 -2
View File
@@ -1,5 +1,4 @@
#define AB_CHECK_RESTRAINED 1
#define AB_CHECK_STUNNED 2
#define AB_CHECK_LYING 4
#define AB_CHECK_ALIVE 8
#define AB_CHECK_INSIDE 16
#define AB_CHECK_CONSCIOUS 8
+1
View File
@@ -27,6 +27,7 @@
// random cooldowns
#define COOLDOWN_VENOM_MILKING "venom_milking"
#define COOLDOWN_SHIP_REFRESH "ship_refresh"
// admin verb cooldowns
#define COOLDOWN_INTERNET_SOUND "internet_sound"
-5
View File
@@ -310,11 +310,6 @@ var/global/list/##LIST_NAME = list();\
#define RAD_RESIST_CALC_DIV 0 // Each turf absorbs some fraction of the working radiation level
#define RAD_RESIST_CALC_SUB 1 // Each turf absorbs a fixed amount of radiation
//https://secure.byond.com/docs/ref/info.html#/atom/var/mouse_opacity
#define MOUSE_OPACITY_TRANSPARENT 0
#define MOUSE_OPACITY_ICON 1
#define MOUSE_OPACITY_OPAQUE 2
// Used by radios to indicate that they have sent a message via something other than subspace
#define RADIO_CONNECTION_FAIL 0
#define RADIO_CONNECTION_NON_SUBSPACE 1
+25 -11
View File
@@ -47,6 +47,7 @@
#define span_say(str) ("<span class='say'>" + str + "</span>")
#define span_emote(str) ("<span class='emote'>" + str + "</span>")
#define span_emote_subtle(str) ("<span class='emotesubtle'>" + str + "</span>")
#define span_filter_say(str) ("<span class='filter_say'>" + str + "</span>")
// Filtered as NPC messages
#define span_npc_say(str) ("<span class='npcsay'>" + str + "</span>")
@@ -58,13 +59,9 @@
// Unfiltered, only style!
#define span_name(str) ("<span class='name'>" + str + "</span>")
#define span_game(str) ("<span class='game'>" + str + "</span>")
#define span_filter_say(str) ("<span class='filter_say'>" + str + "</span>")
#define span_message(str) ("<span class='message'>" + str + "</span>") // TODO: This makes no sense, check it!
#define span_notify(str) ("<span class='notify'>" + str + "</span>") // TODO: This makes no sense, check it!
#define span_body(str) ("<span class='body'>" + str + "</span>")
#define span_filter_warning(str) ("<span class='filter_warning'>" + str + "</span>")
#define span_filter_combat(str) ("<span class='filter_combat'>" + str + "</span>")
#define span_filter_notice(str) ("<span class='filter_notice'>" + str + "</span>")
// Filtered under combat!
#define span_attack(str) ("<span class='attack'>" + str + "</span>")
@@ -72,6 +69,7 @@
#define span_passive(str) ("<span class='passive'>" + str + "</span>")
#define span_danger(str) ("<span class='danger'>" + str + "</span>")
#define span_bolddanger(str) ("<span class='bolddanger'>" + str + "</span>")
#define span_filter_combat(str) ("<span class='filter_combat'>" + str + "</span>")
// Filtered under warning messages
#define span_critical(str) ("<span class='critical'>" + str + "</span>")
@@ -79,7 +77,7 @@
#define span_warning(str) ("<span class='warning'>" + str + "</span>")
#define span_warningplain(str) ("<span class='warningplain'>" + str + "</span>")
#define span_boldwarning(str) ("<span class='boldwarning'>" + str + "</span>")
#define span_sinister(str) ("<span class='sinister'>" + str + "</span>")
#define span_filter_warning(str) ("<span class='filter_warning'>" + str + "</span>") // Close to warning plain, maybe replace
// FIltered under info
#define span_info(str) ("<span class='info'>" + str + "</span>")
@@ -88,11 +86,14 @@
#define span_unconscious(str) ("<span class='unconscious'>" + str + "</span>")
#define span_hear(str) ("<span class='hear'>" + str + "</span>")
#define span_notice(str) ("<span class='notice'>" + str + "</span>")
#define span_filter_notice(str) ("<span class='filter_notice'>" + str + "</span>") // Close to infoplain, maybe replace
#define span_boldnotice(str) ("<span class='boldnotice'>" + str + "</span>")
#define span_adminnotice(str) ("<span class='adminnotice'>" + str + "</span>")
#define span_alium(str) ("<span class='alium'>" + str + "</span>")
#define span_cult(str) ("<span class='cult'>" + str + "</span>")
#define span_pnarrate(str) ("<span class='pnarrate'>" + str + "</span>")
/* Direct communication spans */
// Local pred / prey filter
#define span_psay(str) ("<span class='psay'>" + str + "</span>")
@@ -148,6 +149,7 @@
#define span_orange(str) ("<span class='orange'>" + str + "</span>")
#define span_blue(str) ("<span class='blue'>" + str + "</span>")
#define span_green(str) ("<span class='green'>" + str + "</span>")
#define span_darkgreen(str) ("<span class='darkgreen'>" + str + "</span>") // Do not use regularly!
#define span_purple(str) ("<span class='purple'>" + str + "</span>")
#define span_yellow(str) ("<span class='yellow'>" + str + "</span>")
#define span_pink(str) ("<span class='pink'>" + str + "</span>")
@@ -156,25 +158,29 @@
#define span_maroon(str) ("<span class='maroon'>" + str + "</span>")
#define span_brown(str) ("<span class='brown'>" + str + "</span>")
#define span_lightpurple(str) ("<span class='lightpurple'>" + str + "</span>")
#define span_darkpink(str) ("<span class='darkpurple'>" + str + "</span>")
#define span_darkpink(str) ("<span class='darkpink'>" + str + "</span>")
#define span_rose(str) ("<span class='rose'>" + str + "</span>")
/* System and Debug */
// System filter
#define span_boldannounce(str) ("<span class='boldannounce'>" + str + "</span>")
#define span_world(str) ("<span class='world'>" + str + "</span>") // Bold system messages, use this for important world messages to make sure players can't filter them!
#define span_filter_system(str) ("<span class='filter_system'>" + str + "</span>") // Plain system filter
#define span_sinister(str) ("<span class='sinister'>" + str + "</span>")
// Unfiltered
#define span_prefix(str) ("<span class='prefix'>" + str + "</span>")
#define span_admin(str) ("<span class='admin'>" + str + "</span>")
#define span_linkOn(str) ("<span class='linkOn'>" + str + "</span>")
#define span_linkOff(str) ("<span class='linkOff'>" + str + "</span>")
#define span_filter_system(str) ("<span class='filter_system'>" + str + "</span>")
#define span_filter_pm(str) ("<span class='filter_pm'>" + str + "</span>")
#define span_filter_pray(str) ("<span class='filter_pray'>" + str + "</span>")
#define span_filter_pray(str) ("<span class='filter_pray'>" + str + "</span>") // (Uses the chat message type directly)
// Admin log filters
#define span_log_message(str) ("<span class='log_message'>" + str + "</span>")
#define span_filter_adminlog(str) ("<span class='filter_adminlog'>" + str + "</span>")
#define span_filter_adminlog(str) ("<span class='filter_adminlog'>" + str + "</span>") // (Uses the chat message type directly)
// Attack log filter
#define span_filter_attacklog(str) ("<span class='filter_attacklog'>" + str + "</span>") // (Uses the chat message type directly)
// Debug filter
#define span_debug_error(str) ("<span class='debug_error'>" + str + "</span>")
@@ -182,7 +188,7 @@
#define span_debug_info(str) ("<span class='debug_info'>" + str + "</span>")
#define span_debug_debug(str) ("<span class='debug_debug'>" + str + "</span>")
#define span_debug_trace(str) ("<span class='debug_trace'>" + str + "</span>")
#define span_filter_debuglogs(str) ("<span class='filter_debuglogs'>" + str + "</span>")
#define span_filter_debuglogs(str) ("<span class='filter_debuglogs'>" + str + "</span>") // (Uses the chat message type directly)
/* Admin only usage */
// Admin pm filter
@@ -190,6 +196,7 @@
#define span_adminhelp(str) ("<span class='adminhelp'>" + str + "</span>")
#define span_admin_pm_notice(str) ("<span class='pm notice'>" + str + "</span>")
#define span_admin_pm_warning(str) ("<span class='pm warning'>" + str + "</span>")
#define span_filter_pm(str) ("<span class='filter_pm'>" + str + "</span>")
// Mentor pm filter
#define span_mentor(str) ("<span class='mentor'>" + str + "</span>")
@@ -215,6 +222,10 @@
#define span_giant(str) "<font size='5'>" + str + "</font>"
#define span_giganteus(str) "<font size='6'>" + str + "</font>"
#define span_massive(str) "<font size='7'>" + str + "</font>"
#define span_narsie(str) "<font size='15'>" + str + "</font>"
#define span_cascade(str) "<span style='font-size:22pt'>" + str + "</span>"
@@ -227,3 +238,6 @@
// Links!
#define span_linkify(str) ("<span class='linkify'>" + str + "</span>")
// Just used downstream
#define span_wingdings(str) ("<span class='wingdings'>" + str + "</span>")
+2
View File
@@ -0,0 +1,2 @@
#define TURFLIST_UPDATED (1 << 0)
#define TURFLIST_UPDATE_QUEUED (1 << 1)
+2
View File
@@ -109,6 +109,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_SKYBOX -30 //Visual only, irrelevant to gameplay, but needs to be late enough to have overmap populated fully
#define INIT_ORDER_TICKER -50
#define INIT_ORDER_MAPRENAME -60 //Initiating after Ticker to ensure everything is loaded and everything we rely on us working
#define INIT_ORDER_STATPANELS -98
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
@@ -140,6 +141,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_MACHINES 100
#define FIRE_PRIORITY_TGUI 110
#define FIRE_PRIORITY_PROJECTILES 150
#define FIRE_PRIORITY_STATPANEL 390
#define FIRE_PRIORITY_CHAT 400
#define FIRE_PRIORITY_OVERLAYS 500
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
+1 -1
View File
@@ -2,7 +2,7 @@
#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name)
#define TGS_READ_GLOBAL(Name) GLOB.##Name
#define TGS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value
#define TGS_WORLD_ANNOUNCE(message) to_chat(world, span_boldannounce([html_encode(##message)]))
#define TGS_WORLD_ANNOUNCE(message) to_chat(world, span_boldannounce("[html_encode(##message)]"))
#define TGS_INFO_LOG(message) log_to_dd("TGS Info: [##message]")
#define TGS_WARNING_LOG(message) log_to_dd("TGS Warn: [##message]")
#define TGS_ERROR_LOG(message) log_to_dd("TGS Error: [##message]")
+3
View File
@@ -1,3 +1,6 @@
///displays the current time into the round, with a lot of extra code just there for ensuring it looks okay after an entire day passes
#define ROUND_TIME(...) ( "[world.time - SSticker.round_start_time > MIDNIGHT_ROLLOVER ? "[round((world.time - SSticker.round_start_time)/MIDNIGHT_ROLLOVER)]:[worldtime2text()]" : worldtime2text()]" )
/// Define that just has the current in-universe year for use in whatever context you might want to display that in. (For example, 2022 -> 2562 given a 540 year offset)
#define CURRENT_STATION_YEAR (GLOB.year_integer + STATION_YEAR_OFFSET)
+18
View File
@@ -0,0 +1,18 @@
/* This comment bypasses grep checks */ /var/__verdigris
/proc/__detect_verdigris()
if (world.system_type == UNIX)
return __verdigris = (fexists("./libverdigris.so") ? "./libverdigris.so" : "libverdigris")
else
return __verdigris = "verdigris"
#define VERDIGRIS (__verdigris || __detect_verdigris())
#define VERDIGRIS_CALL(name, args...) call_ext(VERDIGRIS, "byond:" + name)(args)
/proc/verdigris_version() return VERDIGRIS_CALL("verdigris_version")
/proc/verdigris_features() return VERDIGRIS_CALL("verdigris_features")
/proc/verdigris_cleanup() return VERDIGRIS_CALL("cleanup")
/world/New()
verdigris_cleanup()
..()
+3
View File
@@ -0,0 +1,3 @@
/proc/verdigris_generate_automata(limit_x, limit_y, iterations, initial_wall_cell) as /list
RETURN_TYPE(/list)
return VERDIGRIS_CALL("generate_automata", limit_x, limit_y, iterations, initial_wall_cell)
+148 -146
View File
@@ -97,203 +97,205 @@
// Ported from /tg/station
// Creates a single icon from a given /atom or /image. Only the first argument is required.
/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE)
//Define... defines.
// appearance_flags indicates whether appearance_flags should be respected (at the cost of about 10-20% perf)
/proc/getFlatIcon(image/appearance, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE, force_south = FALSE, appearance_flags = FALSE)
// Loop through the underlays, then overlays, sorting them into the layers list
#define PROCESS_OVERLAYS_OR_UNDERLAYS(flat, process, base_layer) \
for (var/i in 1 to process.len) { \
var/image/current = process[i]; \
if (!current) { \
continue; \
} \
if (current.plane != FLOAT_PLANE && current.plane != appearance.plane) { \
continue; \
} \
var/current_layer = current.layer; \
if (current_layer < 0) { \
if (current_layer <= -1000) { \
return flat; \
} \
current_layer = base_layer + appearance.layer + current_layer / 1000; \
} \
for (var/index_to_compare_to in 1 to layers.len) { \
var/compare_to = layers[index_to_compare_to]; \
if (current_layer < layers[compare_to]) { \
layers.Insert(index_to_compare_to, current); \
break; \
} \
} \
layers[current] = current_layer; \
}
var/static/icon/flat_template = icon('icons/effects/effects.dmi', "nothing")
#define BLANK icon(flat_template)
#define SET_SELF(SETVAR) do { \
var/icon/SELF_ICON=icon(icon(curicon, curstate, base_icon_dir),"",SOUTH,no_anim?1:null); \
if(A.alpha<255) { \
SELF_ICON.Blend(rgb(255,255,255,A.alpha),ICON_MULTIPLY);\
} \
if(A.color) { \
if(islist(A.color)){ \
SELF_ICON.MapColors(arglist(A.color))} \
else{ \
SELF_ICON.Blend(A.color,ICON_MULTIPLY)} \
} \
##SETVAR=SELF_ICON;\
} while (0)
#define INDEX_X_LOW 1
#define INDEX_X_HIGH 2
#define INDEX_Y_LOW 3
#define INDEX_Y_HIGH 4
#define flatX1 flat_size[INDEX_X_LOW]
#define flatX2 flat_size[INDEX_X_HIGH]
#define flatY1 flat_size[INDEX_Y_LOW]
#define flatY2 flat_size[INDEX_Y_HIGH]
#define addX1 add_size[INDEX_X_LOW]
#define addX2 add_size[INDEX_X_HIGH]
#define addY1 add_size[INDEX_Y_LOW]
#define addY2 add_size[INDEX_Y_HIGH]
if(!A || A.alpha <= 0)
return BLANK
var/noIcon = FALSE
if(!appearance || appearance.alpha <= 0)
return icon(flat_template)
if(start)
if(!defdir)
defdir = A.dir
defdir = appearance.dir
if(!deficon)
deficon = A.icon
deficon = appearance.icon
if(!defstate)
defstate = A.icon_state
defstate = appearance.icon_state
if(!defblend)
defblend = A.blend_mode
defblend = appearance.blend_mode
var/curicon = A.icon || deficon
var/curstate = A.icon_state || defstate
var/curicon = appearance.icon || deficon
var/curstate = appearance.icon_state || defstate
var/curdir = (!appearance.dir || appearance.dir == SOUTH) ? defdir : appearance.dir
if(!((noIcon = (!curicon))))
var/curstates = cached_icon_states(curicon)
if(force_south)
curdir = SOUTH
var/render_icon = curicon
if (render_icon)
var/curstates = icon_states(curicon)
if(!(curstate in curstates))
if("" in curstates)
if ("" in curstates)
curstate = ""
else
noIcon = TRUE // Do not render this object.
render_icon = FALSE
var/curdir
var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have
var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have
// Use the requested dir or the atom's current dir
curdir = defdir || A.dir
//Try to remove/optimize this section ASAP, CPU hog. //Slightly mitigated by implementing caching using cached_icon_states
//Try to remove/optimize this section ASAP, CPU hog.
//Determines if there's directionals.
if(!noIcon && curdir != SOUTH)
var/exist = FALSE
var/static/list/checkdirs = list(NORTH, EAST, WEST)
for(var/i in checkdirs) //Not using GLOB for a reason.
if(length(cached_icon_states(icon(curicon, curstate, i))))
exist = TRUE
break
if(!exist)
if(render_icon && curdir != SOUTH)
if (
!length(icon_states(icon(curicon, curstate, NORTH))) \
&& !length(icon_states(icon(curicon, curstate, EAST))) \
&& !length(icon_states(icon(curicon, curstate, WEST))) \
)
base_icon_dir = SOUTH
//
if(!base_icon_dir)
base_icon_dir = curdir
ASSERT(!BLEND_DEFAULT) //I might just be stupid but lets make sure this define is 0.
var/curblend = appearance.blend_mode || defblend
var/curblend = A.blend_mode || defblend
if(A.overlays.len || A.underlays.len)
var/icon/flat = BLANK
if(appearance.overlays.len || appearance.underlays.len)
var/icon/flat = icon(flat_template)
// Layers will be a sorted list of icons/overlays, based on the order in which they are displayed
var/list/layers = list()
var/image/copy
// Add the atom's icon itself, without pixel_x/y offsets.
if(!noIcon)
copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir)
copy.color = A.color
copy.alpha = A.alpha
if(render_icon)
copy = image(icon=curicon, icon_state=curstate, layer=appearance.layer, dir=base_icon_dir)
copy.color = appearance.color
copy.alpha = appearance.alpha
copy.blend_mode = curblend
layers[copy] = A.layer
layers[copy] = appearance.layer
// Loop through the underlays, then overlays, sorting them into the layers list
for(var/process_set in 0 to 1)
var/list/process = process_set? A.overlays : A.underlays
for(var/i in 1 to process.len)
var/image/current = process[i]
if(!current)
continue
if(current.plane != FLOAT_PLANE && current.plane != A.plane)
continue
var/current_layer = current.layer
if(current_layer < 0)
//if(current_layer <= -1000)
//return flat
current_layer = process_set + A.layer + current_layer / 1000
for(var/p in 1 to layers.len)
var/image/cmp = layers[p]
if(current_layer < layers[cmp])
layers.Insert(p, current)
break
layers[current] = current_layer
//sortTim(layers, GLOBAL_PROC_REF(cmp_image_layer_asc))
PROCESS_OVERLAYS_OR_UNDERLAYS(flat, appearance.underlays, 0)
PROCESS_OVERLAYS_OR_UNDERLAYS(flat, appearance.overlays, 1)
var/icon/add // Icon of overlay being added
// Current dimensions of flattened icon
var/list/flat_size = list(1, flat.Width(), 1, flat.Height())
// Dimensions of overlay being added
var/list/add_size[4]
var/flatX1 = 1
var/flatX2 = flat.Width()
var/flatY1 = 1
var/flatY2 = flat.Height()
for(var/V in layers)
var/image/I = V
if(I.alpha == 0)
var/addX1 = 0
var/addX2 = 0
var/addY1 = 0
var/addY2 = 0
for(var/image/layer_image as anything in layers)
if(layer_image.alpha == 0)
continue
if(I == copy) // 'I' is an /image based on the object being flattened.
// variables only relevant when accounting for appearance_flags:
var/apply_color = TRUE
var/apply_alpha = TRUE
if(layer_image == copy) // 'layer_image' is an /image based on the object being flattened.
curblend = BLEND_OVERLAY
add = icon(I.icon, I.icon_state, base_icon_dir)
add = icon(layer_image.icon, layer_image.icon_state, base_icon_dir)
else // 'I' is an appearance object.
add = getFlatIcon(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim)
var/image/layer_as_image = image(layer_image)
if(appearance_flags)
if(layer_as_image.appearance_flags & RESET_COLOR)
apply_color = FALSE
if(layer_as_image.appearance_flags & RESET_ALPHA)
apply_alpha = FALSE
add = getFlatIcon(layer_as_image, curdir, curicon, curstate, curblend, FALSE, no_anim, force_south, appearance_flags)
if(!add)
continue
// Find the new dimensions of the flat icon to fit the added overlay
add_size = list(
min(flatX1, I.pixel_x+1),
max(flatX2, I.pixel_x+add.Width()),
min(flatY1, I.pixel_y+1),
max(flatY2, I.pixel_y+add.Height())
)
if(flat_size ~! add_size)
// Find the new dimensions of the flat icon to fit the added overlay
addX1 = min(flatX1, layer_image.pixel_x + 1)
addX2 = max(flatX2, layer_image.pixel_x + add.Width())
addY1 = min(flatY1, layer_image.pixel_y + 1)
addY2 = max(flatY2, layer_image.pixel_y + add.Height())
if (
addX1 != flatX1 \
|| addX2 != flatX2 \
|| addY1 != flatY1 \
|| addY2 != flatY2 \
)
// Resize the flattened icon so the new icon fits
flat.Crop(
addX1 - flatX1 + 1,
addY1 - flatY1 + 1,
addX2 - flatX1 + 1,
addY2 - flatY1 + 1
addX1 - flatX1 + 1,
addY1 - flatY1 + 1,
addX2 - flatX1 + 1,
addY2 - flatY1 + 1
)
flat_size = add_size.Copy()
flatX1 = addX1
flatX2 = addX2
flatY1 = addY1
flatY2 = addY2
if(appearance_flags)
// apply parent's color/alpha to the added layers if the layer didn't opt
if(apply_color && appearance.color)
if(islist(appearance.color))
add.MapColors(arglist(appearance.color))
else
add.Blend(appearance.color, ICON_MULTIPLY)
if(apply_alpha && appearance.alpha < 255)
add.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY)
// Blend the overlay into the flattened icon
flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1)
flat.Blend(add, blendMode2iconMode(curblend), layer_image.pixel_x + 2 - flatX1, layer_image.pixel_y + 2 - flatY1)
if(A.color)
if(islist(A.color))
flat.MapColors(arglist(A.color))
else
flat.Blend(A.color, ICON_MULTIPLY)
if(!appearance_flags)
// If we didn't apply parent colors individually per layer respecting appearance_flags, then do it just the one time now
if(appearance.color)
if(islist(appearance.color))
flat.MapColors(arglist(appearance.color))
else
flat.Blend(appearance.color, ICON_MULTIPLY)
if(A.alpha < 255)
flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY)
if(appearance.alpha < 255)
flat.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY)
if(no_anim)
//Clean up repeated frames
var/icon/cleaned = new /icon()
cleaned.Insert(flat, "", SOUTH, 1, 0)
. = cleaned
return cleaned
else
. = icon(flat, "", SOUTH)
else //There's no overlays.
if(!noIcon)
SET_SELF(.)
return icon(flat, "", SOUTH)
else if (render_icon) // There's no overlays.
var/icon/final_icon = icon(icon(curicon, curstate, base_icon_dir), "", SOUTH, no_anim ? TRUE : null)
//Clear defines
#undef flatX1
#undef flatX2
#undef flatY1
#undef flatY2
#undef addX1
#undef addX2
#undef addY1
#undef addY2
if (appearance.alpha < 255)
final_icon.Blend(rgb(255,255,255, appearance.alpha), ICON_MULTIPLY)
#undef INDEX_X_LOW
#undef INDEX_X_HIGH
#undef INDEX_Y_LOW
#undef INDEX_Y_HIGH
if (appearance.color)
if (islist(appearance.color))
final_icon.MapColors(arglist(appearance.color))
else
final_icon.Blend(appearance.color, ICON_MULTIPLY)
#undef BLANK
#undef SET_SELF
return final_icon
#undef PROCESS_OVERLAYS_OR_UNDERLAYS
/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N
var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A.
@@ -676,7 +678,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
icon_state = thing.icon_state
//Despite casting to atom, this code path supports mutable appearances, so let's be nice to them
//if(isnull(icon_state) || (isatom(thing) && thing.flags_1 & HTML_USE_INITAL_ICON_1))
if(isnull(icon_state) || isatom(thing))
if(isnull(icon_state) && isatom(thing))
icon_state = initial(thing.icon_state)
if (isnull(dir))
dir = initial(thing.dir)
@@ -745,7 +747,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
return "<img class='icon icon-[target_atom.icon_state] [custom_classes]' src='data:image/png;base64,[bicon_cache[key]]'>"
//Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
/proc/costly_icon2html(thing, target, sourceonly = FALSE)
/proc/costly_icon2html(thing, target, sourceonly = FALSE, force_south = FALSE)
if (!thing)
return
//if(SSlag_switch.measures[DISABLE_USR_ICON2HTML] && usr && !HAS_TRAIT(usr, TRAIT_BYPASS_MEASURES))
@@ -754,5 +756,5 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
if (isicon(thing))
return icon2html(thing, target)
var/icon/I = getFlatIcon(thing)
var/icon/I = getFlatIcon(thing, force_south = force_south)
return icon2html(I, target, sourceonly = sourceonly)
+13 -13
View File
@@ -74,42 +74,42 @@
//Log the message to in-game dialogue logs, as well.
if(speaker.client)
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:#32cd32\">[text]</span>"
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:#32cd32\">[text]</span>"
speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("SAY:") + " - " + span_green("[text]")
GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("SAY:") + " - " + span_green("[text]")
/proc/log_ooc(text, client/user)
if (config.log_ooc)
WRITE_LOG(diary, "OOC: [user.simple_info_line()]: [html_decode(text)]")
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>OOC:</u> - <span style=\"color:blue\"><b>[text]</b></span>"
GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[user]") + ") " + span_underline("OOC:") + " - " + span_blue(span_bold("[text]"))
/proc/log_aooc(text, client/user)
if (config.log_ooc)
WRITE_LOG(diary, "AOOC: [user.simple_info_line()]: [html_decode(text)]")
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>AOOC:</u> - <span style=\"color:red\"><b>[text]</b></span>"
GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[user]") + ") " + span_underline("AOOC:") + " - " + span_red(span_bold("[text]"))
/proc/log_looc(text, client/user)
if (config.log_ooc)
WRITE_LOG(diary, "LOOC: [user.simple_info_line()]: [html_decode(text)]")
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>LOOC:</u> - <span style=\"color:orange\"><b>[text]</b></span>"
GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[user]") + ") " + span_underline("LOOC:") + " - " + span_orange(span_bold("[text]"))
/proc/log_whisper(text, mob/speaker)
if (config.log_whisper)
WRITE_LOG(diary, "WHISPER: [speaker.simple_info_line()]: [html_decode(text)]")
if(speaker.client)
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:gray\"><i>[text]</i></span>"
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:gray\"><i>[text]</i></span>"
speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("SAY:") + " - " + span_gray(span_italics("[text]"))
GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("SAY:") + " - " + span_gray(span_italics("[text]"))
/proc/log_emote(text, mob/speaker)
if (config.log_emote)
WRITE_LOG(diary, "EMOTE: [speaker.simple_info_line()]: [html_decode(text)]")
if(speaker.client)
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>EMOTE:</u> - <span style=\"color:#CCBADC\">[text]</span>"
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>EMOTE:</u> - <span style=\"color:#CCBADC\">[text]</span>"
speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("EMOTE:") + " - " + span_pink("[text]")
GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("EMOTE:") + " - " + span_pink("[text]")
/proc/log_attack(attacker, defender, message)
if (config.log_attack)
@@ -131,8 +131,8 @@
if (config.log_say)
WRITE_LOG(diary, "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)]")
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>DEADSAY:</u> - <span style=\"color:green\">[text]</span>"
GLOB.round_text_log += "<font size=1><span style=\"color:#7e668c\"><b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>DEADSAY:</u> - [text]</span></font>"
speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("DEADSAY:") + " - " + span_green("[text]")
GLOB.round_text_log += span_small(span_purple(span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("DEADSAY:") + " - [text]"))
/proc/log_ghostemote(text, mob/speaker)
if (config.log_emote)
@@ -146,8 +146,8 @@
if (config.log_pda)
WRITE_LOG(diary, "PDA: [speaker.simple_info_line()]: [html_decode(text)]")
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>MSG:</u> - <span style=\"color:[COLOR_GREEN]\">[text]</span>"
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>MSG:</u> - <span style=\"color:[COLOR_GREEN]\">[text]</span>"
speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("MSG:") + " - " + span_darkgreen("[text]")
GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("MSG:") + " - " + span_darkgreen("[text]")
/proc/log_to_dd(text)
to_world_log(text) //this comes before the config check because it can't possibly runtime
+115
View File
@@ -0,0 +1,115 @@
/// Takes a screen loc string in the format
/// "+-left-offset:+-pixel,+-bottom-offset:+-pixel"
/// Where the :pixel is optional, and returns
/// A list in the format (x_offset, y_offset)
/// We require context to get info out of screen locs that contain relative info, so NORTH, SOUTH, etc
/proc/screen_loc_to_offset(screen_loc, view)
if(!screen_loc)
return list(64, 64)
var/list/view_size = view_to_pixels(view)
var/x = 0
var/y = 0
// Time to parse for directional relative offsets
if(findtext(screen_loc, "EAST")) // If you're starting from the east, we start from the east too
x += view_size[1]
if(findtext(screen_loc, "WEST")) // HHHHHHHHHHHHHHHHHHHHHH WEST is technically a 1 tile offset from the start. Shoot me please
x += ICON_SIZE_X
if(findtext(screen_loc, "NORTH"))
y += view_size[2]
if(findtext(screen_loc, "SOUTH"))
y += ICON_SIZE_Y
var/list/x_and_y = splittext(screen_loc, ",")
var/list/x_pack = splittext(x_and_y[1], ":")
var/list/y_pack = splittext(x_and_y[2], ":")
var/x_coord = x_pack[1]
var/y_coord = y_pack[1]
if (findtext(x_coord, "CENTER"))
x += view_size[1] / 2
if (findtext(y_coord, "CENTER"))
y += view_size[2] / 2
x_coord = text2num(cut_relative_direction(x_coord))
y_coord = text2num(cut_relative_direction(y_coord))
x += x_coord * ICON_SIZE_X
y += y_coord * ICON_SIZE_Y
if(length(x_pack) > 1)
x += text2num(x_pack[2])
if(length(y_pack) > 1)
y += text2num(y_pack[2])
return list(x, y)
/// Takes a list in the form (x_offset, y_offset)
/// And converts it to a screen loc string
/// Accepts an optional view string/size to force the screen_loc around, so it can't go out of scope
/proc/offset_to_screen_loc(x_offset, y_offset, view = null)
if(view)
var/list/view_bounds = view_to_pixels(view)
x_offset = clamp(x_offset, ICON_SIZE_X, view_bounds[1])
y_offset = clamp(y_offset, ICON_SIZE_Y, view_bounds[2])
// Round with no argument is floor, so we get the non pixel offset here
var/x = round(x_offset / ICON_SIZE_X)
var/pixel_x = x_offset % ICON_SIZE_X
var/y = round(y_offset / ICON_SIZE_Y)
var/pixel_y = y_offset % ICON_SIZE_Y
var/list/generated_loc = list()
generated_loc += "[x]"
if(pixel_x)
generated_loc += ":[pixel_x]"
generated_loc += ",[y]"
if(pixel_y)
generated_loc += ":[pixel_y]"
return jointext(generated_loc, "")
/**
* Returns a valid location to place a screen object without overflowing the viewport
*
* * target: The target location as a purely number based screen_loc string "+-left-offset:+-pixel,+-bottom-offset:+-pixel"
* * target_offset: The amount we want to offset the target location by. We explictly don't care about direction here, we will try all 4
* * view: The view variable of the client we're doing this for. We use this to get the size of the screen
*
* Returns a screen loc representing the valid location
**/
/proc/get_valid_screen_location(target_loc, target_offset, view)
var/list/offsets = screen_loc_to_offset(target_loc)
var/base_x = offsets[1]
var/base_y = offsets[2]
var/list/view_size = view_to_pixels(view)
// Bias to the right, down, left, and then finally up
if(base_x + target_offset < view_size[1])
return offset_to_screen_loc(base_x + target_offset, base_y, view)
if(base_y - target_offset > ICON_SIZE_Y)
return offset_to_screen_loc(base_x, base_y - target_offset, view)
if(base_x - target_offset > ICON_SIZE_X)
return offset_to_screen_loc(base_x - target_offset, base_y, view)
if(base_y + target_offset < view_size[2])
return offset_to_screen_loc(base_x, base_y + target_offset, view)
stack_trace("You passed in a scren location {[target_loc]} and offset {[target_offset]} that can't be fit in the viewport Width {[view_size[1]]}, Height {[view_size[2]]}. what did you do lad")
return null // The fuck did you do lad
/// Takes a screen_loc string and cut out any directions like NORTH or SOUTH
/proc/cut_relative_direction(fragment)
var/static/regex/regex = regex(@"([A-Z])\w+", "g")
return regex.Replace(fragment, "")
/// Returns a screen_loc format for a tiling screen objects from start and end positions. Start should be bottom left corner, and end top right corner.
/proc/spanning_screen_loc(start_px, start_py, end_px, end_py)
var/starting_tile_x = round(start_px / ICON_SIZE_X)
start_px -= starting_tile_x * ICON_SIZE_X
var/starting_tile_y = round(start_py/ ICON_SIZE_Y)
start_py -= starting_tile_y * ICON_SIZE_Y
var/ending_tile_x = round(end_px / ICON_SIZE_X)
end_px -= ending_tile_x * ICON_SIZE_X
var/ending_tile_y = round(end_py / ICON_SIZE_Y)
end_py -= ending_tile_y * ICON_SIZE_Y
return "[starting_tile_x]:[start_px],[starting_tile_y]:[start_py] to [ending_tile_x]:[end_px],[ending_tile_y]:[end_py]"
+4
View File
@@ -1,3 +1,7 @@
//Returns the world time in english
/proc/worldtime2text()
return gameTimestamp("hh:mm:ss", world.time)
#define TimeOfGame (get_game_time())
#define TimeOfTick (TICK_USAGE*0.01*world.tick_lag)
+1 -1
View File
@@ -367,7 +367,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
if(isAI(src))
var/mob/living/silicon/ai/A = src
oldname = null//don't bother with the records update crap
//to_world("<b>[newname] is the AI!</b>")
//to_world(span_world("[newname] is the AI!"))
//world << sound('sound/AI/newAI.ogg')
// Set eyeobj name
A.SetName(newname)
+94
View File
@@ -0,0 +1,94 @@
/**
* handles adding verbs and updating the stat panel browser
*
* pass the verb type path to this instead of adding it directly to verbs so the statpanel can update
* Arguments:
* * target - Who the verb is being added to, client or mob typepath
* * verb - typepath to a verb, or a list of verbs, supports lists of lists
*/
/proc/add_verb(client/target, verb_or_list_to_add)
if(!target)
CRASH("add_verb called without a target")
if(IsAdminAdvancedProcCall())
return
var/mob/mob_target = null
if(ismob(target))
mob_target = target
target = mob_target.client
else if(!istype(target, /client))
CRASH("add_verb called on a non-mob and non-client")
var/list/verbs_list = list()
if(!islist(verb_or_list_to_add))
verbs_list += verb_or_list_to_add
else
var/list/verb_listref = verb_or_list_to_add
var/list/elements_to_process = verb_listref.Copy()
while(length(elements_to_process))
var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
elements_to_process.len--
if(islist(element_or_list))
elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
else
verbs_list += element_or_list
if(mob_target)
mob_target.verbs += verbs_list
if(!target)
return //Our work is done.
else
target.verbs += verbs_list
var/list/output_list = list()
for(var/thing in verbs_list)
var/procpath/verb_to_add = thing
output_list[++output_list.len] = list(verb_to_add.category, verb_to_add.name, verb_to_add.desc)
target.stat_panel.send_message("add_verb_list", output_list)
/**
* handles removing verb and sending it to browser to update, use this for removing verbs
*
* pass the verb type path to this instead of removing it from verbs so the statpanel can update
* Arguments:
* * target - Who the verb is being removed from, client or mob typepath
* * verb - typepath to a verb, or a list of verbs, supports lists of lists
*/
/proc/remove_verb(client/target, verb_or_list_to_remove)
if(IsAdminAdvancedProcCall())
return
var/mob/mob_target = null
if(ismob(target))
mob_target = target
target = mob_target.client
else if(!istype(target, /client))
CRASH("remove_verb called on a non-mob and non-client")
var/list/verbs_list = list()
if(!islist(verb_or_list_to_remove))
verbs_list += verb_or_list_to_remove
else
var/list/verb_listref = verb_or_list_to_remove
var/list/elements_to_process = verb_listref.Copy()
while(length(elements_to_process))
var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
elements_to_process.len--
if(islist(element_or_list))
elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
else
verbs_list += element_or_list
if(mob_target)
mob_target.verbs -= verbs_list
if(!target)
return //Our work is done.
else
target.verbs -= verbs_list
var/list/output_list = list()
for(var/thing in verbs_list)
var/procpath/verb_to_remove = thing
output_list[++output_list.len] = list(verb_to_remove.category, verb_to_remove.name)
target.stat_panel.send_message("remove_verb_list", output_list)
+10 -1
View File
@@ -11,6 +11,15 @@
viewY = text2num(viewrangelist[2])
return list(viewX, viewY)
/// Takes a string or num view, and converts it to pixel width/height in a list(pixel_width, pixel_height)
/proc/view_to_pixels(view)
if(!view)
return list(0, 0)
var/list/view_info = getviewsize(view)
view_info[1] *= ICON_SIZE_X
view_info[2] *= ICON_SIZE_Y
return view_info
// Used to get `atom/O as obj|mob|turf in view()` to match against strings containing apostrophes immediately after substrings that match to other objects. Somehow. - Ater
/proc/_validate_atom(atom/A)
return view()
return view()
+1 -8
View File
@@ -286,16 +286,9 @@
/atom/proc/AltClick(var/mob/user)
var/turf/T = get_turf(src)
if(T && user.TurfAdjacent(T))
user.ToggleTurfTab(T)
user.set_listed_turf(T)
return 1
/mob/proc/ToggleTurfTab(var/turf/T)
if(listed_turf == T)
listed_turf = null
else
listed_turf = T
client.statpanel = "Turf"
/mob/proc/TurfAdjacent(var/turf/T)
return T.AdjacentQuick(src)
+1 -1
View File
@@ -312,7 +312,7 @@
if(object_used && verb_to_call)
call(object_used,verb_to_call)(arguments_to_use)
// call(object_used,verb_to_call)(arguments_to_use)
// to_world("Attempted to call([object_used],[verb_to_call])([arguments_to_use])")
// to_world(span_world("Attempted to call([object_used],[verb_to_call])([arguments_to_use])"))
// if(hascall(object_used, verb_to_call))
// call(object_used,verb_to_call)(arguments_to_use)
// else
-228
View File
@@ -1,228 +0,0 @@
#define AB_ITEM 1
#define AB_SPELL 2
#define AB_INNATE 3
#define AB_GENERIC 4
/datum/action
var/name = "Generic Action"
var/action_type = AB_ITEM
var/procname = null
var/atom/movable/target = null
var/check_flags = 0
var/processing = 0
var/active = 0
var/obj/screen/movable/action_button/button = null
var/button_icon = 'icons/mob/actions.dmi'
var/button_icon_state = "default"
var/background_icon_state = "bg_default"
var/mob/living/owner
/datum/action/New(var/Target)
target = Target
/datum/action/Destroy()
if(owner)
Remove(owner)
target = null
QDEL_NULL(button)
return ..()
/datum/action/proc/Grant(mob/living/T)
if(owner)
if(owner == T)
return
Remove(owner)
owner = T
owner.actions.Add(src)
owner.update_action_buttons()
return
/datum/action/proc/Remove(mob/living/T)
if(button)
if(T.client)
T.client.screen -= button
QDEL_NULL(button)
T.actions.Remove(src)
T.update_action_buttons()
owner = null
return
/datum/action/proc/Trigger()
if(!Checks())
return
switch(action_type)
if(AB_ITEM)
if(target)
var/obj/item/item = target
item.ui_action_click()
//if(AB_SPELL)
// if(target)
// var/obj/effect/proc_holder/spell = target
// spell.Click()
if(AB_INNATE)
if(!active)
Activate()
else
Deactivate()
if(AB_GENERIC)
if(target && procname)
call(target,procname)(usr)
return
/datum/action/proc/Activate()
return
/datum/action/proc/Deactivate()
return
/datum/action/process()
return
/datum/action/proc/CheckRemoval(mob/living/user) // 1 if action is no longer valid for this mob and should be removed
return 0
/datum/action/proc/IsAvailable()
return Checks()
/datum/action/proc/Checks()// returns 1 if all checks pass
if(!owner)
return 0
if(check_flags & AB_CHECK_RESTRAINED)
if(owner.restrained())
return 0
if(check_flags & AB_CHECK_STUNNED)
if(owner.stunned)
return 0
if(check_flags & AB_CHECK_LYING)
if(owner.lying)
return 0
if(check_flags & AB_CHECK_ALIVE)
if(owner.stat)
return 0
if(check_flags & AB_CHECK_INSIDE)
if(!(target in owner))
return 0
return 1
/datum/action/proc/UpdateName()
return name
/obj/screen/movable/action_button
var/datum/action/owner
screen_loc = "WEST,NORTH"
/obj/screen/movable/action_button/Click(location,control,params)
var/list/modifiers = params2list(params)
if(modifiers["shift"])
moved = 0
return 1
if(!usr.checkClickCooldown())
return
owner.Trigger()
return 1
/obj/screen/movable/action_button/proc/UpdateIcon()
if(!owner)
return
icon = owner.button_icon
icon_state = owner.background_icon_state
cut_overlays()
var/image/img
if(owner.action_type == AB_ITEM && owner.target)
var/obj/item/I = owner.target
img = image(I.icon, src , I.icon_state)
else if(owner.button_icon && owner.button_icon_state)
img = image(owner.button_icon,src,owner.button_icon_state)
img.pixel_x = 0
img.pixel_y = 0
add_overlay(img)
if(!owner.IsAvailable())
color = rgb(128,0,0,128)
else
color = rgb(255,255,255,255)
//Hide/Show Action Buttons ... Button
/obj/screen/movable/action_button/hide_toggle
name = "Hide Buttons"
icon = 'icons/mob/actions.dmi'
icon_state = "bg_default"
var/hidden = 0
/obj/screen/movable/action_button/hide_toggle/Click()
usr.hud_used.action_buttons_hidden = !usr.hud_used.action_buttons_hidden
hidden = usr.hud_used.action_buttons_hidden
if(hidden)
name = "Show Buttons"
else
name = "Hide Buttons"
UpdateIcon()
usr.update_action_buttons()
/obj/screen/movable/action_button/hide_toggle/proc/InitialiseIcon(var/mob/living/user)
if(isalien(user))
icon_state = "bg_alien"
else
icon_state = "bg_default"
UpdateIcon()
return
/obj/screen/movable/action_button/hide_toggle/UpdateIcon()
cut_overlays()
var/image/img = image(icon,src,hidden?"show":"hide")
add_overlay(img)
return
//This is the proc used to update all the action buttons. Properly defined in /mob/living/
/mob/proc/update_action_buttons()
return
#define AB_WEST_OFFSET 4
#define AB_NORTH_OFFSET 26
#define AB_MAX_COLUMNS 10
/datum/hud/proc/ButtonNumberToScreenCoords(var/number) // TODO : Make this zero-indexed for readabilty
var/row = round((number-1)/AB_MAX_COLUMNS)
var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1
var/coord_col = "+[col-1]"
var/coord_col_offset = AB_WEST_OFFSET+2*col
var/coord_row = "[-1 - row]"
var/coord_row_offset = AB_NORTH_OFFSET
return "WEST[coord_col]:[coord_col_offset],NORTH[coord_row]:[coord_row_offset]"
/datum/hud/proc/SetButtonCoords(var/obj/screen/button,var/number)
var/row = round((number-1)/AB_MAX_COLUMNS)
var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1
var/x_offset = 32*(col-1) + AB_WEST_OFFSET + 2*col
var/y_offset = -32*(row+1) + AB_NORTH_OFFSET
var/matrix/M = matrix()
M.Translate(x_offset,y_offset)
button.transform = M
//Presets for item actions
/datum/action/item_action
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_ALIVE|AB_CHECK_INSIDE
/datum/action/item_action/CheckRemoval(mob/living/user)
return !(target in user)
/datum/action/item_action/hands_free
check_flags = AB_CHECK_ALIVE|AB_CHECK_INSIDE
#undef AB_WEST_OFFSET
#undef AB_NORTH_OFFSET
#undef AB_MAX_COLUMNS
/datum/action/innate/
action_type = AB_INNATE
#undef AB_ITEM
#undef AB_SPELL
#undef AB_INNATE
#undef AB_GENERIC
+156
View File
@@ -0,0 +1,156 @@
/datum/action
var/name = "Generic Action"
var/atom/movable/target = null
var/check_flags = 0
var/processing = 0
var/obj/screen/movable/action_button/button = null
var/button_icon = 'icons/mob/actions.dmi'
var/button_icon_state = "default"
var/background_icon_state = "bg_default"
var/mob/living/owner
/datum/action/New(Target)
target = Target
button = new
button.linked_action = src
button.name = name
/datum/action/Destroy()
if(owner)
Remove(owner)
target = null
QDEL_NULL(button)
return ..()
/datum/action/proc/Grant(mob/living/L)
if(owner)
if(owner == L)
return
Remove(owner)
owner = L
L.actions += src
if(L.client)
L.client.screen += button
L.update_action_buttons(TRUE)
/datum/action/proc/Remove(mob/living/L)
if(L.client)
L.client.screen -= button
button.moved = FALSE
L.actions -= src
L.update_action_buttons(TRUE)
owner = null
/datum/action/proc/Trigger()
if(!IsAvailable())
return 0
return 1
/datum/action/process()
return
/datum/action/proc/IsAvailable()
if(!owner)
return 0
if(check_flags & AB_CHECK_RESTRAINED)
if(owner.restrained())
return 0
if(check_flags & AB_CHECK_STUNNED)
if(owner.stunned)
return 0
if(check_flags & AB_CHECK_LYING)
if(owner.lying)
return 0
if(check_flags & AB_CHECK_CONSCIOUS)
if(owner.stat)
return 0
return 1
/datum/action/proc/UpdateButtonIcon()
if(button)
button.icon = button_icon
button.icon_state = background_icon_state
ApplyIcon(button)
if(!IsAvailable())
button.color = rgb(128, 0, 0, 128)
else
button.color = rgb(255, 255, 255, 255)
return 1
/datum/action/proc/ApplyIcon(obj/screen/movable/action_button/current_button)
current_button.cut_overlays()
if(button_icon && button_icon_state)
var/image/img
img = image(button_icon, current_button, button_icon_state)
img.pixel_x = 0
img.pixel_y = 0
current_button.add_overlay(img)
//Presets for item actions
/datum/action/item_action
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
/datum/action/item_action/New(Target)
. = ..()
var/obj/item/I = target
I.actions += src
/datum/action/item_action/Destroy()
var/obj/item/I = target
I.actions -= src
return ..()
/datum/action/item_action/Trigger()
if(!..())
return 0
if(target)
var/obj/item/I = target
I.ui_action_click(owner, src.type)
return 1
/datum/action/item_action/ApplyIcon(obj/screen/movable/action_button/current_button)
current_button.cut_overlays()
if(target)
var/mutable_appearance/ma = new(target.appearance)
ma.plane = FLOAT_PLANE
ma.layer = FLOAT_LAYER
ma.pixel_x = 0
ma.pixel_y = 0
current_button.add_overlay(ma)
/datum/action/item_action/hands_free
check_flags = AB_CHECK_CONSCIOUS
/datum/action/innate
check_flags = 0
var/active = 0
/datum/action/innate/Trigger()
if(!..())
return 0
if(!active)
Activate()
else
Deactivate()
return 1
/datum/action/innate/proc/Activate()
return
/datum/action/innate/proc/Deactivate()
return
//Preset for action that call specific procs (consider innate).
/datum/action/generic
check_flags = 0
var/procname
/datum/action/generic/Trigger()
if(!..())
return 0
if(target && procname)
call(target, procname)(usr)
return 1
@@ -0,0 +1,132 @@
/obj/screen/movable/action_button
var/datum/action/linked_action
screen_loc = null
/obj/screen/movable/action_button/Click(location,control,params)
var/list/modifiers = params2list(params)
if(modifiers["shift"])
moved = FALSE
usr.update_action_buttons()
return 1
if(!usr.checkClickCooldown())
return
linked_action.Trigger()
return 1
//Hide/Show Action Buttons ... Button
/obj/screen/movable/action_button/hide_toggle
name = "Hide Buttons"
icon = 'icons/mob/actions.dmi'
icon_state = "bg_default"
var/hidden = 0
/obj/screen/movable/action_button/hide_toggle/Click()
usr.hud_used.action_buttons_hidden = !usr.hud_used.action_buttons_hidden
hidden = usr.hud_used.action_buttons_hidden
if(hidden)
name = "Show Buttons"
else
name = "Hide Buttons"
UpdateIcon()
usr.update_action_buttons()
/obj/screen/movable/action_button/hide_toggle/proc/InitialiseIcon(var/mob/living/user)
if(isalien(user))
icon_state = "bg_alien"
else
icon_state = "bg_default"
UpdateIcon()
/obj/screen/movable/action_button/hide_toggle/proc/UpdateIcon()
cut_overlays()
var/image/img = image(icon, src, hidden ? "show" : "hide")
add_overlay(img)
/obj/screen/movable/action_button/MouseEntered(location, control, params)
openToolTip(usr, src, params, title = name, content = desc)
/obj/screen/movable/action_button/MouseExited(location, control, params)
closeToolTip(usr)
//used to update the buttons icon.
/mob/proc/update_action_buttons_icon()
return
/mob/living/update_action_buttons_icon()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
//This is the proc used to update all the action buttons. Properly defined in /mob/living/
/mob/proc/update_action_buttons(reload_screen)
return
/mob/living/update_action_buttons(reload_screen)
if(!hud_used || !client)
return
if(!hud_used.hud_shown) //Hud toggled to minimal
return
var/button_number = 0
if(hud_used.action_buttons_hidden)
for(var/datum/action/A in actions)
A.button.screen_loc = null
if(reload_screen)
client.screen += A.button
else
for(var/datum/action/A in actions)
button_number++
A.UpdateButtonIcon()
var/obj/screen/movable/action_button/B = A.button
if(!B.moved)
B.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number)
else
B.screen_loc = B.moved
if(reload_screen)
client.screen += B
if(!button_number)
hud_used.hide_actions_toggle?.screen_loc = null
return
// not exactly sure how this happens but it does
if(hud_used.hide_actions_toggle)
if(!hud_used.hide_actions_toggle.moved)
hud_used.hide_actions_toggle.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number+1)
else
hud_used.hide_actions_toggle.screen_loc = hud_used.hide_actions_toggle.moved
if(reload_screen)
client.screen += hud_used.hide_actions_toggle
#define AB_WEST_OFFSET 4
#define AB_NORTH_OFFSET 26
#define AB_MAX_COLUMNS 10
/datum/hud/proc/ButtonNumberToScreenCoords(var/number) // TODO : Make this zero-indexed for readabilty
var/row = round((number-1)/AB_MAX_COLUMNS)
var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1
var/coord_col = "+[col-1]"
var/coord_col_offset = AB_WEST_OFFSET+2*col
var/coord_row = "[-1 - row]"
var/coord_row_offset = AB_NORTH_OFFSET
return "WEST[coord_col]:[coord_col_offset],NORTH[coord_row]:[coord_row_offset]"
/datum/hud/proc/SetButtonCoords(var/obj/screen/button,var/number)
var/row = round((number-1)/AB_MAX_COLUMNS)
var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1
var/x_offset = 32*(col-1) + AB_WEST_OFFSET + 2*col
var/y_offset = -32*(row+1) + AB_NORTH_OFFSET
var/matrix/M = matrix()
M.Translate(x_offset,y_offset)
button.transform = M
#undef AB_WEST_OFFSET
#undef AB_NORTH_OFFSET
#undef AB_MAX_COLUMNS
+161
View File
@@ -0,0 +1,161 @@
// Generic Classes
/datum/action/item_action/activate
/datum/action/item_action/activate/New(Target, name)
. = ..()
src.name = name
button.name = name
// Specific names
/datum/action/item_action/toggle_grippers
name = "Toggle Grippers"
/datum/action/item_action/toggle_talons
name = "Toggle Talons"
/datum/action/item_action/toggle_goggles
name = "Toggle Goggles"
/datum/action/item_action/toggle_shield_projector
name = "Toggle Shield Projector"
/datum/action/item_action/toggle_tesla_armor
name = "Toggle Tesla Armor"
/datum/action/item_action/remove_replace_paddles
name = "Remove/Replace Paddles"
/datum/action/item_action/toggle_flashlight
name = "Toggle Flashlight"
/datum/action/item_action/toggle_shield
name = "Toggle Shield"
/datum/action/item_action/toggle_heatsink
name = "Toggle Heatsink"
/datum/action/item_action/remove_replace_handset
name = "Remove/Replace Handset"
/datum/action/item_action/command
name = "Command"
/datum/action/item_action/toggle_jetpack
name = "Toggle Jetpack"
/datum/action/item_action/toggle_cataloguer
name = "Toggle Cataloguer"
/datum/action/item_action/toggle_eyepatch
name = "Toggle Eyepatch"
/datum/action/item_action/hands_free/change_scanning_pattern
name = "Change Scanning Pattern"
/datum/action/item_action/toggle_hud
name = "Toggle HUD"
/datum/action/item_action/toggle_mode
name = "Toggle Mode"
/datum/action/item_action/flip_welding_goggles
name = "Flip Welding Goggles"
/datum/action/item_action/toggle_monocle
name = "Toggle Monocle"
/datum/action/item_action/adjust_orange_goggles
name = "Adjust Orange Goggles"
/datum/action/item_action/ar_console_crew
name = "AR Console (Crew Monitor)"
/datum/action/item_action/ar_console_security_alerts
name = "AR Console (Security Alerts)"
/datum/action/item_action/ar_console_station_alerts
name = "AR Console (Station Alerts)"
/datum/action/item_action/ar_console_all_alerts
name = "AR Console (All Alerts)"
/datum/action/item_action/toggle_head_light
name = "Toggle Head-light"
/datum/action/item_action/toggle_visor
name = "Toggle Visor"
/datum/action/item_action/flip_welding_mask
name = "Flip Welding Mask"
/datum/action/item_action/adjust_breath_mask
name = "Adjust Breath Mask"
/datum/action/item_action/toggle_feeding_port
name = "Toggle Feeding Port"
/datum/action/item_action/halt
name = "HALT!"
/datum/action/item_action/hands_free/redraw_design
name = "Redraw Design"
/datum/action/item_action/toggle_magboots
name = "Toggle Magboots"
/datum/action/item_action/toggle_magclaws
name = "Toggle Magclaws"
/datum/action/item_action/activate_jump_boots
name = "Activate Jump Boots"
/datum/action/item_action/toggle_helmet_light
name = "Toggle Helmet Light"
/datum/action/item_action/hardsuit_interface
name = "Hardsuit Interface"
/datum/action/item_action/toggle_helmet
name = "Toggle Helmet"
/datum/action/item_action/toggle_knight_headgear
name = "Toggle Knight Headgear"
/datum/action/item_action/toggle_hood
name = "Toggle Hood"
/datum/action/item_action/adjust_cloak
name = "Adjust Cloak"
/datum/action/item_action/adjust_poncho
name = "Adjust Poncho"
/datum/action/item_action/pull_on_gaiter
name = "Pull On Gaiter"
/datum/action/item_action/toggle_uv_light
name = "Toggle UV Light"
/datum/action/item_action/toggle_light
name = "Toggle Light"
/datum/action/item_action/use_scope
name = "Use Scope"
/datum/action/item_action/aim_down_sights
name = "Aim Down Sights"
/datum/action/item_action/toggle_gunlight
name = "Toggle Gun-light"
/datum/action/item_action/toggle_internal_generator
name = "Toggle Internal Generator"
/datum/action/item_action/toggle_stock
name = "Toggle Stock"
/datum/action/item_action/toggle_pom_pom
name = "Toggle Pom-Pom"
/datum/action/item_action/toggle_mlembulance
name = "Toggle Mlembulance Mode"
+7 -3
View File
@@ -207,6 +207,7 @@ var/list/global_huds = list(
/datum/hud/Destroy()
. = ..()
QDEL_NULL_LIST(minihuds)
QDEL_NULL(hide_actions_toggle)
grab_intent = null
hurt_intent = null
disarm_intent = null
@@ -322,10 +323,12 @@ var/list/global_huds = list(
return 0
mymob.create_mob_hud(src)
hide_actions_toggle = new()
hide_actions_toggle.InitialiseIcon(mymob)
persistant_inventory_update()
mymob.reload_fullscreen() // Reload any fullscreen overlays this mob has.
mymob.update_action_buttons()
mymob.update_action_buttons(TRUE)
reorganize_alerts()
/mob/proc/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
@@ -404,10 +407,11 @@ var/list/global_huds = list(
hud_used?.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
client.screen += zone_sel //This one is a special snowflake
client.screen += hud_used.hide_actions_toggle
hud_used.hidden_inventory_update()
hud_used.persistant_inventory_update()
update_action_buttons()
update_action_buttons(TRUE)
hud_used.reorganize_alerts()
return TRUE
@@ -467,7 +471,7 @@ var/list/global_huds = list(
hud_used.hidden_inventory_update()
hud_used.persistant_inventory_update()
update_action_buttons()
update_action_buttons(TRUE)
/mob/proc/add_click_catcher()
client.screen += client.void
+22 -18
View File
@@ -9,9 +9,10 @@
//Not tied to the grid, places it's center where the cursor is
/obj/screen/movable
mouse_drag_pointer = 'icons/effects/mouse_pointers/screen_drag.dmi'
var/snap2grid = FALSE
var/moved = FALSE
var/x_off = -16
var/x_off = -16
var/y_off = -16
//Snap Screen Object
@@ -22,30 +23,33 @@
/obj/screen/movable/MouseDrop(over_object, src_location, over_location, src_control, over_control, params)
var/list/PM = params2list(params)
//No screen-loc information? abort.
if(!PM || !PM["screen-loc"])
var/position = mouse_params_to_position(params)
if(!position)
return
//Split screen-loc up into X+Pixel_X and Y+Pixel_Y
var/list/screen_loc_params = splittext(PM["screen-loc"], ",")
screen_loc = position
moved = screen_loc
//Split X+Pixel_X up into list(X, Pixel_X)
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
screen_loc_X[1] = encode_screen_X(text2num(screen_loc_X[1]))
//Split Y+Pixel_Y up into list(Y, Pixel_Y)
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
screen_loc_Y[1] = encode_screen_Y(text2num(screen_loc_Y[1]))
/// Takes mouse parmas as input, returns a string representing the appropriate mouse position
/obj/screen/movable/proc/mouse_params_to_position(params)
var/list/modifiers = params2list(params)
//No screen-loc information? abort.
if(!LAZYACCESS(modifiers, SCREEN_LOC))
return
var/client/our_client = usr.client
var/list/offset = screen_loc_to_offset(LAZYACCESS(modifiers, SCREEN_LOC), our_client?.view)
if(snap2grid) //Discard Pixel Values
screen_loc = "[screen_loc_X[1]],[screen_loc_Y[1]]"
offset[1] = FLOOR(offset[1], ICON_SIZE_X) // drops any pixel offset
offset[2] = FLOOR(offset[2], ICON_SIZE_Y) // drops any pixel offset
else //Normalise Pixel Values (So the object drops at the center of the mouse, not 16 pixels off)
var/pix_X = text2num(screen_loc_X[2]) + x_off
var/pix_Y = text2num(screen_loc_Y[2]) + y_off
screen_loc = "[screen_loc_X[1]]:[pix_X],[screen_loc_Y[1]]:[pix_Y]"
offset[1] += x_off
offset[2] += y_off
return offset_to_screen_loc(offset[1], offset[2], our_client?.view)
// Must stay for now, for subtypes
/obj/screen/movable/proc/encode_screen_X(X)
var/view_dist = world.view
if(view_dist)
+5 -5
View File
@@ -6,23 +6,23 @@
if("darkness")
var/turf/T = get_turf(usr)
var/darkness = round(1 - T.get_lumcount(),0.1)
to_chat(usr,span_notice("<b>Darkness:</b> [darkness]"))
to_chat(usr,span_notice(span_bold("Darkness:") + " [darkness]"))
if("energy")
var/mob/living/simple_mob/shadekin/SK = usr
if(istype(SK))
to_chat(usr,span_notice("<b>Energy:</b> [SK.energy] ([SK.dark_gains])"))
to_chat(usr,span_notice(span_bold("Energy:") + " [SK.energy] ([SK.dark_gains])"))
if("shadekin status")
var/turf/T = get_turf(usr)
if(T)
var/darkness = round(1 - T.get_lumcount(),0.1)
to_chat(usr,span_notice("<b>Darkness:</b> [darkness]"))
to_chat(usr,span_notice(span_bold("Darkness:") + " [darkness]"))
var/mob/living/carbon/human/H = usr
if(istype(H) && istype(H.species, /datum/species/shadekin))
to_chat(usr,span_notice("<b>Energy:</b> [H.shadekin_get_energy(H)]"))
to_chat(usr,span_notice(span_bold("Energy:") + " [H.shadekin_get_energy(H)]"))
if("glamour")
var/mob/living/carbon/human/H = usr
if(istype(H))
to_chat(usr,span_notice("<b>Energy:</b> [H.species.lleill_energy]/[H.species.lleill_energy_max]"))
to_chat(usr,span_notice(span_bold("Energy:") + " [H.species.lleill_energy]/[H.species.lleill_energy_max]"))
if("danger level")
var/mob/living/carbon/human/H = usr
if(istype(H) && istype(H.species, /datum/species/xenochimera))
+1 -1
View File
@@ -41,7 +41,7 @@
if(modifiers["alt"]) // alt and alt-gr (rightalt)
var/turf/T = get_turf(A)
if(T && TurfAdjacent(T))
ToggleTurfTab(T)
set_listed_turf(T)
return
// You are responsible for checking config.ghost_interaction when you override this function
// Not all of them require checking, see below
+14 -14
View File
@@ -1,11 +1,11 @@
#define MIDDLE_CLICK 0
#define ALT_CLICK 1
#define CTRL_CLICK 2
#define HARDSUIT_MIDDLE_CLICK 0
#define HARDSUIT_ALT_CLICK 1
#define HARDSUIT_CTRL_CLICK 2
#define MAX_HARDSUIT_CLICK_MODE 2
/client
var/hardsuit_click_mode = MIDDLE_CLICK
var/hardsuit_click_mode = HARDSUIT_MIDDLE_CLICK
/client/verb/toggle_hardsuit_mode()
set name = "Toggle Hardsuit Activation Mode"
@@ -17,32 +17,32 @@
hardsuit_click_mode = 0
switch(hardsuit_click_mode)
if(MIDDLE_CLICK)
if(HARDSUIT_MIDDLE_CLICK)
to_chat(src, "Hardsuit activation mode set to middle-click.")
if(ALT_CLICK)
if(HARDSUIT_ALT_CLICK)
to_chat(src, "Hardsuit activation mode set to alt-click.")
if(CTRL_CLICK)
if(HARDSUIT_CTRL_CLICK)
to_chat(src, "Hardsuit activation mode set to control-click.")
else
// should never get here, but just in case:
soft_assert(0, "Bad hardsuit click mode: [hardsuit_click_mode] - expected 0 to [MAX_HARDSUIT_CLICK_MODE]")
to_chat(src, "Somehow you bugged the system. Setting your hardsuit mode to middle-click.")
hardsuit_click_mode = MIDDLE_CLICK
hardsuit_click_mode = HARDSUIT_MIDDLE_CLICK
/mob/living/MiddleClickOn(atom/A)
if(client && client.hardsuit_click_mode == MIDDLE_CLICK)
if(client && client.hardsuit_click_mode == HARDSUIT_MIDDLE_CLICK)
if(HardsuitClickOn(A))
return
..()
/mob/living/AltClickOn(atom/A)
if(client && client.hardsuit_click_mode == ALT_CLICK)
if(client && client.hardsuit_click_mode == HARDSUIT_ALT_CLICK)
if(HardsuitClickOn(A))
return
..()
/mob/living/CtrlClickOn(atom/A)
if(client && client.hardsuit_click_mode == CTRL_CLICK)
if(client && client.hardsuit_click_mode == HARDSUIT_CTRL_CLICK)
if(HardsuitClickOn(A))
return
..()
@@ -78,7 +78,7 @@
return 1
return 0
#undef MIDDLE_CLICK
#undef ALT_CLICK
#undef CTRL_CLICK
#undef HARDSUIT_MIDDLE_CLICK
#undef HARDSUIT_ALT_CLICK
#undef HARDSUIT_CTRL_CLICK
#undef MAX_HARDSUIT_CLICK_MODE
+1 -1
View File
@@ -19,7 +19,7 @@ var/datum/controller/transfer_controller/transfer_controller
//VOREStation Edit START
if (round_duration_in_ds >= shift_last_vote - 2 MINUTES)
shift_last_vote = 99999999 //Setting to a stupidly high number since it'll be not used again.
to_world("<b>Warning: You have one hour left in the shift. Wrap up your scenes in the next 60 minutes before the transfer is called.</b>") //VOREStation Edit
to_world(span_world(span_notice("Warning: You have one hour left in the shift. Wrap up your scenes in the next 60 minutes before the transfer is called."))) //VOREStation Edit
if (round_duration_in_ds >= shift_hard_end - 1 MINUTE)
init_shift_change(null, 1)
shift_hard_end = timerbuffer + config.vote_autotransfer_interval //If shuttle somehow gets recalled, let's force it to call again next time a vote would occur.
+2 -2
View File
@@ -71,7 +71,7 @@ var/list/gamemode_cache = list()
var/static/respawn = 1
var/static/respawn_time = 3000 // time before a dead player is allowed to respawn (in ds, though the config file asks for minutes, and it's converted below)
var/static/respawn_message = span_notice("<B>Make sure to play a different character, and please roleplay correctly!</B>")
var/static/respawn_message = span_boldnotice("Make sure to play a different character, and please roleplay correctly!")
var/static/guest_jobban = 1
var/static/usewhitelist = 0
@@ -529,7 +529,7 @@ var/list/gamemode_cache = list()
config.respawn_time = raw_minutes MINUTES
if ("respawn_message")
config.respawn_message = span_notice("<B>[value]</B>")
config.respawn_message = span_boldnotice("[value]")
if ("servername")
config.server_name = value
+1 -1
View File
@@ -16,4 +16,4 @@
/datum/controller/proc/Recover()
/datum/controller/proc/stat_entry()
/datum/controller/proc/stat_entry(msg)
+3 -2
View File
@@ -96,8 +96,9 @@ var/datum/controller/failsafe/Failsafe
/datum/controller/failsafe/proc/defcon_pretty()
return defcon
/datum/controller/failsafe/stat_entry()
/datum/controller/failsafe/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
msg = "Failsafe Controller: [statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])")]"
return msg
+3 -2
View File
@@ -32,11 +32,12 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
return ..()
/datum/controller/global_vars/stat_entry()
/datum/controller/global_vars/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("GLOB:", statclick.update("Edit"))
msg = "GLOB: [statclick.update("Edit")]"
return msg
/datum/controller/global_vars/vv_edit_var(var_name, var_value)
if(gvars_datum_protected_varlist[var_name])
+5 -3
View File
@@ -582,12 +582,14 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
/datum/controller/master/stat_entry()
/datum/controller/master/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))")
stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])"))
msg = "Byond: (FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))"
msg += "Master Controller: [statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])")]"
return msg
/datum/controller/master/StartLoadingMap(var/quiet = TRUE)
if(map_loading)
+4 -15
View File
@@ -164,22 +164,11 @@
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
/datum/controller/subsystem/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
if(SS_NO_FIRE & flags)
msg = "NO FIRE\t[msg]"
else if(can_fire <= 0)
msg = "OFFLINE\t[msg]"
else
if(can_fire && !(SS_NO_FIRE & flags))
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
var/title = name
if (can_fire)
title = "\[[state_letter()]][title]"
stat(title, statclick.update(msg))
else
msg = "OFFLINE\t[msg]"
return msg
/datum/controller/subsystem/proc/state_letter()
switch (state)
+3 -2
View File
@@ -12,8 +12,9 @@ SUBSYSTEM_DEF(ai)
var/slept_mobs = 0
var/list/process_z = list()
/datum/controller/subsystem/ai/stat_entry(msg_prefix)
..("P: [processing.len] | S: [slept_mobs]")
/datum/controller/subsystem/ai/stat_entry(msg)
msg = "P: [processing.len] | S: [slept_mobs]"
return ..()
/datum/controller/subsystem/ai/fire(resumed = 0)
if (!resumed)
+3 -4
View File
@@ -9,10 +9,9 @@ SUBSYSTEM_DEF(aifast)
var/list/processing = list()
var/list/currentrun = list()
/datum/controller/subsystem/aifast/stat_entry(msg_prefix)
var/list/msg = list(msg_prefix)
msg += "P:[processing.len]"
..(msg.Join())
/datum/controller/subsystem/aifast/stat_entry(msg)
msg = "P:[processing.len]"
return ..()
/datum/controller/subsystem/aifast/fire(resumed = 0)
if (!resumed)
+3 -4
View File
@@ -244,9 +244,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/air/stat_entry(msg_prefix)
var/list/msg = list(msg_prefix)
msg += "S:[current_step ? part_names[current_step] : ""] "
/datum/controller/subsystem/air/stat_entry(msg)
msg = "S:[current_step ? part_names[current_step] : ""] "
msg += "C:{"
msg += "T [round(cost_turfs, 1)] | "
msg += "E [round(cost_edges, 1)] | "
@@ -263,7 +262,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
msg += "H [active_hotspots.len] | "
msg += "Z [zones_to_update.len] "
msg += "}"
..(msg.Join())
return ..()
// ZAS might displace objects as the map loads if an air tick is processed mid-load.
/datum/controller/subsystem/air/StartLoadingMap(var/quiet = TRUE)
+3 -2
View File
@@ -41,5 +41,6 @@ SUBSYSTEM_DEF(alarm)
/datum/controller/subsystem/alarm/proc/number_of_active_alarms()
return active_alarm_cache.len
/datum/controller/subsystem/alarm/stat_entry()
..("[number_of_active_alarms()] alarm\s")
/datum/controller/subsystem/alarm/stat_entry(msg)
msg = "[number_of_active_alarms()] alarm\s"
return ..()
+4 -3
View File
@@ -20,8 +20,9 @@ SUBSYSTEM_DEF(chemistry)
initialize_chemical_reactions()
..()
/datum/controller/subsystem/chemistry/stat_entry()
..("C: [chemical_reagents.len] | R: [chemical_reactions.len]")
/datum/controller/subsystem/chemistry/stat_entry(msg)
msg = "C: [chemical_reagents.len] | R: [chemical_reactions.len]"
return ..()
//Chemical Reactions - Initialises all /decl/chemical_reaction into a list
// It is filtered into multiple lists within a list.
@@ -43,7 +44,7 @@ SUBSYSTEM_DEF(chemistry)
// add_to = fusion_reactions_by_reagent
if(istype(D, /decl/chemical_reaction/distilling))
add_to = distilled_reactions_by_reagent
LAZYINITLIST(add_to[reagent_id])
add_to[reagent_id] += D
+3 -2
View File
@@ -41,8 +41,9 @@ SUBSYSTEM_DEF(events)
var/datum/event_container/EC = event_containers[i]
EC.process()
/datum/controller/subsystem/events/stat_entry()
..("E:[active_events.len]")
/datum/controller/subsystem/events/stat_entry(msg)
msg = "E:[active_events.len]"
return ..()
/datum/controller/subsystem/events/Recover()
if(SSevents.active_events)
+3 -2
View File
@@ -56,8 +56,9 @@ SUBSYSTEM_DEF(inactivity)
if (MC_TICK_CHECK)
return
/datum/controller/subsystem/inactivity/stat_entry()
..("Kicked: [number_kicked]")
/datum/controller/subsystem/inactivity/stat_entry(msg)
msg = "Kicked: [number_kicked]"
return ..()
/datum/controller/subsystem/inactivity/proc/can_kick(var/client/C)
if(C.holder) return FALSE //VOREStation Add - Don't kick admins.
+3 -4
View File
@@ -82,9 +82,8 @@ SUBSYSTEM_DEF(machines)
T.broadcast_status()
CHECK_TICK
/datum/controller/subsystem/machines/stat_entry()
var/msg = list()
msg += "C:{"
/datum/controller/subsystem/machines/stat_entry(msg)
msg = "C:{"
msg += "PI:[round(cost_pipenets,1)]|"
msg += "MC:[round(cost_machinery,1)]|"
msg += "PN:[round(cost_powernets,1)]|"
@@ -95,7 +94,7 @@ SUBSYSTEM_DEF(machines)
msg += "PN:[SSmachines.powernets.len]|"
msg += "PO:[SSmachines.powerobjs.len]|"
msg += "MC/MS:[round((cost ? SSmachines.processing_machines.len/cost_machinery : 0),0.1)]"
..(jointext(msg, null))
return ..()
/datum/controller/subsystem/machines/proc/process_pipenets(resumed = 0)
if (!resumed)
+4 -3
View File
@@ -19,8 +19,9 @@ SUBSYSTEM_DEF(mobs)
var/slept_mobs = 0
var/list/process_z = list()
/datum/controller/subsystem/mobs/stat_entry()
..("P: [global.mob_list.len] | S: [slept_mobs]")
/datum/controller/subsystem/mobs/stat_entry(msg)
msg = "P: [global.mob_list.len] | S: [slept_mobs]"
return ..()
/datum/controller/subsystem/mobs/fire(resumed = 0)
if (!resumed)
@@ -90,4 +91,4 @@ SUBSYSTEM_DEF(mobs)
/datum/controller/subsystem/mobs/critfail()
..()
log_recent()
log_recent()
+3 -4
View File
@@ -7,8 +7,9 @@ SUBSYSTEM_DEF(orbit)
var/list/currentrun = list()
var/list/processing = list()
/datum/controller/subsystem/orbit/stat_entry()
..("P:[processing.len]")
/datum/controller/subsystem/orbit/stat_entry(msg)
msg = "P:[processing.len]"
return ..()
/datum/controller/subsystem/orbit/fire(resumed = 0)
@@ -40,5 +41,3 @@ SUBSYSTEM_DEF(orbit)
O.Check(targetloc)
if (MC_TICK_CHECK)
return
+3 -2
View File
@@ -32,8 +32,9 @@ SUBSYSTEM_DEF(overlays)
fire(FALSE, TRUE)
..()
/datum/controller/subsystem/overlays/stat_entry()
..("Queued Atoms: [queue.len], Cache Size: [cache_size]")
/datum/controller/subsystem/overlays/stat_entry(msg)
msg = "Queued Atoms: [queue.len], Cache Size: [cache_size]"
return ..()
/datum/controller/subsystem/overlays/fire(resumed, no_mc_tick)
+3 -2
View File
@@ -12,8 +12,9 @@ SUBSYSTEM_DEF(ping)
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
var/list/currentrun = list()
/datum/controller/subsystem/ping/stat_entry()
..("P:[GLOB.clients.len]")
/datum/controller/subsystem/ping/stat_entry(msg)
msg = "P:[GLOB.clients.len]"
return ..()
/datum/controller/subsystem/ping/fire(resumed = FALSE)
// Prepare the new batch of clients
+3 -2
View File
@@ -22,8 +22,9 @@ SUBSYSTEM_DEF(plants)
var/list/processing = list()
var/list/currentrun = list()
/datum/controller/subsystem/plants/stat_entry()
..("P:[processing.len]|S:[seeds.len]")
/datum/controller/subsystem/plants/stat_entry(msg)
msg = "P:[processing.len]|S:[seeds.len]"
return ..()
/datum/controller/subsystem/plants/Initialize(timeofday)
setup()
@@ -0,0 +1,24 @@
PROCESSING_SUBSYSTEM_DEF(obj_tab_items)
name = "Obj Tab Items"
flags = SS_NO_INIT
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
wait = 0.1 SECONDS
// I know this is mostly copypasta, but I want to change the processing logic
// Sorry bestie :(
/datum/controller/subsystem/processing/obj_tab_items/fire(resumed = FALSE)
if (!resumed)
currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
var/list/current_run = currentrun
while(current_run.len)
var/datum/thing = current_run[current_run.len]
if(QDELETED(thing))
processing -= thing
else if(thing.process(wait * 0.1) == PROCESS_KILL)
// fully stop so that a future START_PROCESSING will work
STOP_PROCESSING(src, thing)
if (MC_TICK_CHECK)
return
current_run.len--
@@ -24,8 +24,9 @@ SUBSYSTEM_DEF(processing)
if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING))
processing |= D
/datum/controller/subsystem/processing/stat_entry()
..("[stat_tag]:[processing.len]")
/datum/controller/subsystem/processing/stat_entry(msg)
msg = "[stat_tag]:[processing.len]"
return ..()
/datum/controller/subsystem/processing/fire(resumed = 0)
if (!resumed)
@@ -69,14 +70,14 @@ SUBSYSTEM_DEF(processing)
log_world(msg)
return
msg += "Lists: current_run: [currentrun.len], processing: [processing.len]\n"
if(!currentrun.len)
msg += "!!The subsystem just finished the processing list, and currentrun is empty (or has never run).\n"
msg += "!!The info below is the tail of processing instead of currentrun.\n"
var/datum/D = currentrun.len ? currentrun[currentrun.len] : processing[processing.len]
msg += "Tail entry: [describeThis(D)] (this is likely the item AFTER the problem item)\n"
var/position = processing.Find(D)
if(!position)
msg += "Unable to find context of tail entry in processing list.\n"
+4 -3
View File
@@ -54,8 +54,9 @@ SUBSYSTEM_DEF(radiation)
if (MC_TICK_CHECK)
return
/datum/controller/subsystem/radiation/stat_entry()
..("S:[sources.len], RC:[resistance_cache.len]")
/datum/controller/subsystem/radiation/stat_entry(msg)
msg = "S:[sources.len], RC:[resistance_cache.len]"
return ..()
// Ray trace from all active radiation sources to T and return the strongest effect.
/datum/controller/subsystem/radiation/proc/get_rads_at_turf(var/turf/T)
@@ -144,4 +145,4 @@ SUBSYSTEM_DEF(radiation)
if(!(power && source))
return
var/turf/epicentre = locate(round(world.maxx / 2), round(world.maxy / 2), source.z)
flat_radiate(epicentre, power, world.maxx, respect_maint)
flat_radiate(epicentre, power, world.maxx, respect_maint)
+3 -2
View File
@@ -172,5 +172,6 @@ SUBSYSTEM_DEF(shuttles)
for(var/obj/effect/overmap/visitable/ship/ship_effect as anything in ships)
overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
/datum/controller/subsystem/shuttles/stat_entry()
..("Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]")
/datum/controller/subsystem/shuttles/stat_entry(msg)
msg = "Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]"
return ..()
+481
View File
@@ -0,0 +1,481 @@
SUBSYSTEM_DEF(statpanels)
name = "Stat Panels"
wait = 4
init_order = INIT_ORDER_STATPANELS
//init_stage = INITSTAGE_EARLY
priority = FIRE_PRIORITY_STATPANEL
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
flags = SS_NO_INIT
var/list/currentrun = list()
var/list/global_data
var/list/mc_data
var/list/cached_images = list()
///how many subsystem fires between most tab updates
var/default_wait = 10
///how many subsystem fires between updates of misc tabs
var/misc_wait = 3
///how many subsystem fires between updates of the status tab
var/status_wait = 2
///how many subsystem fires between updates of the MC tab
var/mc_wait = 5
///how many full runs this subsystem has completed. used for variable rate refreshes.
var/num_fires = 0
/datum/controller/subsystem/statpanels/fire(resumed = FALSE)
if (!resumed)
num_fires++
//var/datum/map_config/cached = SSmapping.next_map_config
global_data = list(
//"Map: [SSmapping.config?.map_name || "Loading..."]",
"Map: [using_map.name]",
//cached ? "Next Map: [cached.map_name]" : null,
//"Next Map: -- Not Available --",
// "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]",
"Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]",
"Round Time: [ROUND_TIME()]",
"Station Date: [stationdate2text()]", // [capitalize(GLOB.world_time_season)]",
"Station Time: [stationtime2text()]",
"Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)"
)
if(emergency_shuttle.evac)
var/ETA = emergency_shuttle.get_status_panel_eta()
if(ETA)
global_data += "[ETA]"
src.currentrun = GLOB.clients.Copy()
mc_data = null
var/list/currentrun = src.currentrun
while(length(currentrun))
var/client/target = currentrun[length(currentrun)]
currentrun.len--
if(!target?.stat_panel?.is_ready()) // Null target client, client has null stat panel, or stat panel isn't ready
continue
if(target.stat_tab == "Status" && num_fires % status_wait == 0)
set_status_tab(target)
if(!target.holder)
target.stat_panel.send_message("remove_admin_tabs")
else
//target.stat_panel.send_message("update_split_admin_tabs", !!(target.prefs.toggles & SPLIT_ADMIN_TABS))
target.stat_panel.send_message("update_split_admin_tabs", FALSE)
if(!("MC" in target.panel_tabs) || !("Tickets" in target.panel_tabs))
target.stat_panel.send_message("add_admin_tabs", target.holder.href_token)
//if(target.stat_tab == "MC" && ((num_fires % mc_wait == 0) || target?.prefs.read_preference(/datum/preference/toggle/fast_mc_refresh)))
//set_MC_tab(target)
if(target.stat_tab == "MC" && ((num_fires % mc_wait == 0)))
set_MC_tab(target)
if(target.stat_tab == "Tickets" && num_fires % default_wait == 0)
set_tickets_tab(target)
if(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs))
target.stat_panel.send_message("remove_sdql2")
else if(length(GLOB.sdql2_queries) && (target.stat_tab == "SDQL2" || !("SDQL2" in target.panel_tabs)) && num_fires % default_wait == 0)
set_SDQL2_tab(target)
if(target.mob)
var/mob/target_mob = target.mob
// Handle the action panels of the stat panel
var/update_actions = FALSE
// We're on a spell tab, update the tab so we can see cooldowns progressing and such
if(target.stat_tab in target.spell_tabs)
update_actions = TRUE
// We're not on a spell tab per se, but we have cooldown actions, and we've yet to
// set up our spell tabs at all
//if(!length(target.spell_tabs) && locate(/datum/action/cooldown) in target_mob.actions)
//update_actions = TRUE
if(update_actions && num_fires % default_wait == 0)
set_action_tabs(target, target_mob)
//Update every fire if tab is open, otherwise update every 7 fires
if((num_fires % misc_wait == 0))
update_misc_tabs(target,target_mob)
var/datum/object_window_info/obj_window = target.obj_window
if(obj_window)
if(obj_window.flags & TURFLIST_UPDATE_QUEUED)
immediate_send_stat_data(target)
obj_window.flags = 0
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/statpanels/proc/update_misc_tabs(var/client/target,var/mob/target_mob)
target_mob.update_misc_tabs()
for(var/tab in target_mob.misc_tabs)
if(target_mob.misc_tabs[tab].len == 0 && (tab in target.misc_tabs))
target.misc_tabs -= tab
target.stat_panel.send_message("remove_misc",tab)
if(target_mob.misc_tabs[tab].len > 0)
if(!(tab in target.misc_tabs))
target.misc_tabs += tab
target.stat_panel.send_message("create_misc",tab)
target.stat_panel.send_message("update_misc",list(
TN = tab, \
TC = target_mob.misc_tabs[tab], \
))
for(var/tab in target.misc_tabs)
if(!(tab in target_mob.misc_tabs))
target.misc_tabs -= tab
target.stat_panel.send_message("remove_misc",tab)
/datum/controller/subsystem/statpanels/proc/set_status_tab(client/target)
if(!global_data)//statbrowser hasnt fired yet and we were called from immediate_send_stat_data()
return
target.stat_panel.send_message("update_stat", list(
global_data = global_data,
ping_str = "Ping: -- Not Available --", // [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)",
other_str = target.mob?.get_status_tab_items(),
))
/datum/controller/subsystem/statpanels/proc/set_MC_tab(client/target)
var/turf/eye_turf = get_turf(target.eye)
var/coord_entry = COORD(eye_turf)
if(!mc_data)
generate_mc_data()
target.stat_panel.send_message("update_mc", list(mc_data = mc_data, coord_entry = coord_entry))
/datum/controller/subsystem/statpanels/proc/set_examine_tab(client/target)
var/description_holders = target.description_holders
var/list/examine_update = list()
if(!target.obj_window)
target.obj_window = new(target)
if(!target.examine_icon && !target.obj_window.examine_target && target.stat_tab == "Examine")
target.obj_window.examine_target = description_holders["icon"]
target.obj_window.atoms_to_show += target.obj_window.examine_target
START_PROCESSING(SSobj_tab_items, target.obj_window)
refresh_client_obj_view(target)
examine_update += "[target.examine_icon]&emsp;<font size='5'>[description_holders["name"]]</font>" //The name, written in big letters.
examine_update += "[description_holders["desc"]]" //the default examine text.
if(description_holders["info"])
examine_update += "<font color='#084B8A'>" + span_bold("[replacetext(description_holders["info"], "\n", "<BR>")]") + "</font><br />" //Blue, informative text.
if(description_holders["interactions"])
for(var/line in description_holders["interactions"])
examine_update += "<font color='#084B8A'>" + span_bold("[line]") + "</font><br />"
if(description_holders["fluff"])
examine_update += "<font color='#298A08'>" + span_bold("[replacetext(description_holders["fluff"], "\n", "<BR>")]") + "</font><br />" //Green, fluff-related text.
if(description_holders["antag"])
examine_update += "<font color='#8A0808'>" + span_bold("[description_holders["antag"]]") + "</font><br />" //Red, malicious antag-related text
target.stat_panel.send_message("update_examine", examine_update)
/datum/controller/subsystem/statpanels/proc/set_tickets_tab(client/target)
var/list/tickets = GLOB.ahelp_tickets.stat_entry(target)
tickets += GLOB.mhelp_tickets.stat_entry(target)
target.stat_panel.send_message("update_tickets", tickets)
/datum/controller/subsystem/statpanels/proc/set_SDQL2_tab(client/target)
var/list/sdql2A = list()
sdql2A[++sdql2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj))
var/list/sdql2B = list()
for(var/datum/SDQL2_query/query as anything in GLOB.sdql2_queries)
sdql2B = query.generate_stat()
sdql2A += sdql2B
target.stat_panel.send_message("update_sdql2", sdql2A)
/// Set up the various action tabs.
/datum/controller/subsystem/statpanels/proc/set_action_tabs(client/target, mob/target_mob)
return
//var/list/actions = target_mob.get_actions_for_statpanel()
//target.spell_tabs.Cut()
//for(var/action_data in actions)
// target.spell_tabs |= action_data[1]
//target.stat_panel.send_message("update_spells", list(spell_tabs = target.spell_tabs, actions = actions))
/datum/controller/subsystem/statpanels/proc/set_turf_examine_tab(client/target, mob/target_mob)
if(!target)//statbrowser hasnt fired yet and we were called from immediate_send_stat_data()
return
var/list/overrides = list()
for(var/image/target_image as anything in target.images)
if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override)
continue
overrides += target_image.loc
var/list/atoms_to_display = list(target_mob.listed_turf)
for(var/atom/movable/turf_content as anything in target_mob.listed_turf)
if(turf_content.mouse_opacity == MOUSE_OPACITY_TRANSPARENT)
continue
if(turf_content.invisibility > target_mob.see_invisible)
continue
if(turf_content in overrides)
continue
//if(turf_content.IsObscured())
//continue
atoms_to_display += turf_content
/// Set the atoms we're meant to display
var/datum/object_window_info/obj_window = target.obj_window
if(!obj_window)
return // previous one no longer exists
obj_window.atoms_to_show = atoms_to_display
START_PROCESSING(SSobj_tab_items, obj_window)
refresh_client_obj_view(target)
/datum/controller/subsystem/statpanels/proc/refresh_client_obj_view(client/refresh)
var/list/turf_items = return_object_images(refresh)
if(!length(turf_items)/* || !refresh.mob?.listed_turf*/)
return
refresh.stat_panel.send_message("update_listedturf", turf_items)
#define OBJ_IMAGE_LOADING "statpanels obj loading temporary"
/// Returns all our ready object tab images
/// Returns a list in the form list(list(object_name, object_ref, loaded_image), ...)
/datum/controller/subsystem/statpanels/proc/return_object_images(client/load_from)
// You might be inclined to think that this is a waste of cpu time, since we
// A: Double iterate over atoms in the build case, or
// B: Generate these lists over and over in the refresh case
// It's really not very hot. The hot portion of this code is genuinely mostly in the image generation
// So it's ok to pay a performance cost for cleanliness here
// No turf? go away
/*if(!load_from.mob?.listed_turf)
return list()*/
var/datum/object_window_info/obj_window = load_from.obj_window
var/list/already_seen = obj_window.atoms_to_images
var/list/to_make = obj_window.atoms_to_imagify
var/list/turf_items = list()
for(var/atom/turf_item as anything in obj_window.atoms_to_show)
// First, we fill up the list of refs to display
// If we already have one, just use that
var/existing_image = already_seen[turf_item]
if(existing_image == OBJ_IMAGE_LOADING)
continue
// We already have it. Success!
if(existing_image)
if(turf_item == obj_window.examine_target) //not actually a turf item get trolled
load_from.examine_icon = "<img src=\"[existing_image]\" />"
obj_window.examine_target = null
set_examine_tab(load_from)
continue
turf_items[++turf_items.len] = list("[turf_item.name]", REF(turf_item), existing_image)
continue
// Now, we're gonna queue image generation out of those refs
to_make += turf_item
already_seen[turf_item] = OBJ_IMAGE_LOADING
obj_window.RegisterSignal(turf_item, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/datum/object_window_info,viewing_atom_deleted)) // we reset cache if anything in it gets deleted
return turf_items
#undef OBJ_IMAGE_LOADING
/datum/controller/subsystem/statpanels/proc/generate_mc_data()
mc_data = list(
list("CPU:", world.cpu),
list("Instances:", "[num2text(world.contents.len, 10)]"),
list("World Time:", "[world.time]"),
list("Globals:", GLOB.stat_entry(), "\ref[GLOB]"),
// list("[config]:", config.stat_entry(), "\ref[config]"),
list("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)"),
list("Master Controller:", Master.stat_entry(), "\ref[Master]"),
list("Failsafe Controller:", Failsafe.stat_entry(), "\ref[Failsafe]"),
list("","")
)
for(var/datum/controller/subsystem/sub_system as anything in Master.subsystems)
mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), "\ref[sub_system]")
mc_data[++mc_data.len] = list("Camera Net", "Cameras: [global.cameranet.cameras.len] | Chunks: [global.cameranet.chunks.len]", "\ref[global.cameranet]")
///immediately update the active statpanel tab of the target client
/datum/controller/subsystem/statpanels/proc/immediate_send_stat_data(client/target)
if(!target.stat_panel.is_ready())
return FALSE
if(target.stat_tab == "Examine")
set_examine_tab(target)
return TRUE
if(target.stat_tab == "Status")
set_status_tab(target)
return TRUE
var/mob/target_mob = target.mob
// Handle actions
var/update_actions = FALSE
if(target.stat_tab in target.spell_tabs)
update_actions = TRUE
//if(!length(target.spell_tabs) && locate(/datum/action/cooldown) in target_mob.actions)
//update_actions = TRUE
if(update_actions)
set_action_tabs(target, target_mob)
return TRUE
// Handle turfs
if(target_mob?.listed_turf)
if(!target_mob.TurfAdjacent(target_mob.listed_turf))
target.stat_panel.send_message("removed_listedturf")
target_mob.listed_turf = null
else if(target.stat_tab == target_mob?.listed_turf.name || !(target_mob?.listed_turf.name in target.panel_tabs))
set_turf_examine_tab(target, target_mob)
return TRUE
if(!target.holder)
return FALSE
if(target.stat_tab == "MC")
set_MC_tab(target)
return TRUE
if(target.stat_tab == "Tickets")
set_tickets_tab(target)
return TRUE
if(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs))
target.stat_panel.send_message("remove_sdql2")
else if(length(GLOB.sdql2_queries) && target.stat_tab == "SDQL2")
set_SDQL2_tab(target)
/atom/proc/remove_from_cache()
SIGNAL_HANDLER
SSstatpanels.cached_images -= REF(src)
/// Stat panel window declaration
/client/var/datum/tgui_window/stat_panel
/// Datum that holds and tracks info about a client's object window
/// Really only exists because I want to be able to do logic with signals
/// And need a safe place to do the registration
/datum/object_window_info
/// list of atoms to show to our client via the object tab, at least currently
var/list/atoms_to_show = list()
/// list of atom -> image string for objects we have had in the right click tab
/// this is our caching
var/list/atoms_to_images = list()
/// list of atoms to turn into images for the object tab
var/list/atoms_to_imagify = list()
/// Our owner client
var/client/parent
/// Are we currently tracking a turf?
var/actively_tracking = FALSE
///For reusing this logic for examines
var/atom/examine_target
var/flags = 0
/datum/object_window_info/New(client/parent)
. = ..()
src.parent = parent
/datum/object_window_info/Destroy(force, ...)
atoms_to_show = null
atoms_to_images = null
atoms_to_imagify = null
parent.obj_window = null
parent = null
STOP_PROCESSING(SSobj_tab_items, src)
return ..()
/// Takes a client, attempts to generate object images for it
/// We will update the client with any improvements we make when we're done
/datum/object_window_info/process(seconds_per_tick)
// Cache the datum access for sonic speed
var/list/to_make = atoms_to_imagify
var/list/newly_seen = atoms_to_images
var/index = 0
for(index in 1 to length(to_make))
var/atom/thing = to_make[index]
if(!thing) // A null thing snuck in somehow
continue
var/generated_string
if(ismob(thing) || length(thing.overlays) > 0)
var/force_south = FALSE
if(isliving(thing))
force_south = TRUE
generated_string = costly_icon2html(thing, parent, sourceonly=TRUE, force_south = force_south)
else
generated_string = icon2html(thing, parent, sourceonly=TRUE)
newly_seen[thing] = generated_string
if(TICK_CHECK)
to_make.Cut(1, index + 1)
index = 0
break
// If we've not cut yet, do it now
if(index)
to_make.Cut(1, index + 1)
SSstatpanels.refresh_client_obj_view(parent)
if(!length(to_make))
return PROCESS_KILL
/datum/object_window_info/proc/start_turf_tracking()
if(actively_tracking)
stop_turf_tracking()
var/static/list/connections = list(
COMSIG_MOVABLE_MOVED = PROC_REF(on_mob_move),
COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout),
)
AddComponent(/datum/component/connect_mob_behalf, parent, connections)
RegisterSignal(parent.mob.listed_turf, COMSIG_ATOM_ENTERED, PROC_REF(turflist_changed))
RegisterSignal(parent.mob.listed_turf, COMSIG_ATOM_EXITED, PROC_REF(turflist_changed))
actively_tracking = TRUE
/datum/object_window_info/proc/stop_turf_tracking()
qdel(GetComponent(/datum/component/connect_mob_behalf))
UnregisterSignal(parent.mob.listed_turf, COMSIG_ATOM_ENTERED)
UnregisterSignal(parent.mob.listed_turf, COMSIG_ATOM_EXITED)
actively_tracking = FALSE
/datum/object_window_info/proc/on_mob_move(mob/source)
SIGNAL_HANDLER
var/turf/listed = source.listed_turf
if(!listed || !source.TurfAdjacent(listed))
source.set_listed_turf(null)
/datum/object_window_info/proc/on_mob_logout(mob/source)
SIGNAL_HANDLER
on_mob_move(parent.mob)
/datum/object_window_info/proc/turflist_changed(mob/source)
if(!parent)//statbrowser hasnt fired yet and we still have a pending action
return
SIGNAL_HANDLER
if(!(flags & TURFLIST_UPDATED)) //Limit updates to 1 per tick
SSstatpanels.immediate_send_stat_data(parent)
flags |= TURFLIST_UPDATED
else if(!(flags & TURFLIST_UPDATE_QUEUED))
flags |= TURFLIST_UPDATE_QUEUED
/// Clears any cached object window stuff
/// We use hard refs cause we'd need a signal for this anyway. Cleaner this way
/datum/object_window_info/proc/viewing_atom_deleted(atom/deleted)
SIGNAL_HANDLER
atoms_to_show -= deleted
atoms_to_imagify -= deleted
atoms_to_images -= deleted
/mob/proc/set_listed_turf(turf/new_turf)
if(!client)
listed_turf = new_turf
return
if(!client.obj_window)
client.obj_window = new(client)
if(!new_turf)
client.obj_window.stop_turf_tracking() //Needs to go before listed_turf is set to null so signals can be removed
listed_turf = new_turf
if(listed_turf)
client.stat_panel.send_message("create_listedturf", listed_turf.name)
client.obj_window.start_turf_tracking()
else
client.stat_panel.send_message("remove_listedturf")
+3 -2
View File
@@ -39,8 +39,9 @@ SUBSYSTEM_DEF(supply)
/datum/controller/subsystem/supply/fire()
points += points_per_process
/datum/controller/subsystem/supply/stat_entry()
..("Points: [points]")
/datum/controller/subsystem/supply/stat_entry(msg)
msg = "Points: [points]"
return ..()
//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
/datum/controller/subsystem/supply/proc/forbidden_atoms_check(atom/A)
+3 -2
View File
@@ -35,8 +35,9 @@ SUBSYSTEM_DEF(tgui)
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
/datum/controller/subsystem/tgui/stat_entry()
..("P:[all_uis.len]")
/datum/controller/subsystem/tgui/stat_entry(msg)
msg = "P:[all_uis.len]"
return ..()
/datum/controller/subsystem/tgui/fire(resumed = FALSE)
if(!resumed)
+3 -2
View File
@@ -9,8 +9,9 @@ SUBSYSTEM_DEF(throwing)
var/list/currentrun
var/list/processing = list()
/datum/controller/subsystem/throwing/stat_entry()
..("P:[processing.len]")
/datum/controller/subsystem/throwing/stat_entry(msg)
msg = "P:[processing.len]"
return ..()
/datum/controller/subsystem/throwing/fire(resumed = 0)
if (!resumed)
+29 -20
View File
@@ -41,6 +41,10 @@ SUBSYSTEM_DEF(ticker)
//Now we have a general cinematic centrally held within the gameticker....far more efficient!
var/obj/screen/cinematic = null
var/round_start_time = 0
// This global variable exists for legacy support so we don't have to rename every 'ticker' to 'SSticker' yet.
var/global/datum/controller/subsystem/ticker/ticker
/datum/controller/subsystem/ticker/PreInit()
@@ -101,6 +105,7 @@ var/global/datum/controller/subsystem/ticker/ticker
// Called during GAME_STATE_SETTING_UP (RUNLEVEL_SETUP)
/datum/controller/subsystem/ticker/proc/setup_tick(resumed = FALSE)
round_start_time = world.time // otherwise round_start_time would be 0 for the signals
if(!setup_choose_gamemode())
// It failed, go back to lobby state and re-send the welcome message
pregame_timeleft = config.pregame_time
@@ -123,7 +128,7 @@ var/global/datum/controller/subsystem/ticker/ticker
var/list/runnable_modes = config.get_runnable_modes()
if((master_mode == "random") || (master_mode == "secret"))
if(!runnable_modes.len)
to_world(span_danger(span_bold("Unable to choose playable game mode.") + " Reverting to pregame lobby."))
to_world(span_filter_system(span_bold("Unable to choose playable game mode.") + " Reverting to pregame lobby."))
return 0
if(secret_force_mode != "secret")
src.mode = config.pick_mode(secret_force_mode)
@@ -136,7 +141,7 @@ var/global/datum/controller/subsystem/ticker/ticker
src.mode = config.pick_mode(master_mode)
if(!src.mode)
to_world(span_danger("Serious error in mode setup! Reverting to pregame lobby.")) //Uses setup instead of set up due to computational context.
to_world(span_boldannounce("Serious error in mode setup! Reverting to pregame lobby.")) //Uses setup instead of set up due to computational context.
return 0
job_master.ResetOccupations()
@@ -145,21 +150,21 @@ var/global/datum/controller/subsystem/ticker/ticker
job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
if(!src.mode.can_start())
to_world(span_danger(span_bold("Unable to start [mode.name].") + " Not enough players readied, [config.player_requirements[mode.config_tag]] players needed. Reverting to pregame lobby."))
to_world(span_filter_system(span_bold("Unable to start [mode.name].") + " Not enough players readied, [config.player_requirements[mode.config_tag]] players needed. Reverting to pregame lobby."))
mode.fail_setup()
mode = null
job_master.ResetOccupations()
return 0
if(hide_mode)
to_world(span_notice(span_bold("The current game mode is - Secret!")))
to_world(span_world(span_notice("The current game mode is - Secret!")))
if(runnable_modes.len)
var/list/tmpmodes = new
for (var/datum/game_mode/M in runnable_modes)
tmpmodes+=M.name
tmpmodes = sortList(tmpmodes)
if(tmpmodes.len)
to_world(span_info(span_bold("Possibilities:") + " [english_list(tmpmodes, and_text= "; ", comma_text = "; ")]"))
to_world(span_filter_system(span_bold("Possibilities:") + " [english_list(tmpmodes, and_text= "; ", comma_text = "; ")]"))
else
src.mode.announce()
return 1
@@ -225,7 +230,7 @@ var/global/datum/controller/subsystem/ticker/ticker
end_game_state = END_GAME_MODE_FINISHED // Only do this cleanup once!
mode.cleanup()
//call a transfer shuttle vote
to_world(span_danger("The round has ended!"))
to_world(span_boldannounce("The round has ended!"))
SSvote.start_vote(new /datum/vote/crew_transfer)
// Called during GAME_STATE_FINISHED (RUNLEVEL_POSTGAME)
@@ -238,7 +243,7 @@ var/global/datum/controller/subsystem/ticker/ticker
feedback_set_details("end_proper", "nuke")
restart_timeleft = 1 MINUTE // No point waiting five minutes if everyone's dead.
if(!delay_end)
to_world(span_notice(span_bold("Rebooting due to destruction of [station_name()] in [round(restart_timeleft/600)] minute\s.")))
to_world(span_boldannounce("Rebooting due to destruction of [station_name()] in [round(restart_timeleft/600)] minute\s."))
last_restart_notify = world.time
else
feedback_set_details("end_proper", "proper completion")
@@ -252,14 +257,14 @@ var/global/datum/controller/subsystem/ticker/ticker
if(END_GAME_ENDING)
restart_timeleft -= (world.time - last_fire)
if(delay_end)
to_world(span_notice(span_bold("An admin has delayed the round end.")))
to_world(span_boldannounce("An admin has delayed the round end."))
end_game_state = END_GAME_DELAYED
else if(restart_timeleft <= 0)
to_world(span_warning(span_bold("Restarting world!")))
to_world(span_boldannounce("Restarting world!"))
sleep(5)
world.Reboot()
else if (world.time - last_restart_notify >= 1 MINUTE)
to_world(span_notice(span_bold("Restarting in [round(restart_timeleft/600, 1)] minute\s.")))
to_world(span_boldannounce("Restarting in [round(restart_timeleft/600, 1)] minute\s."))
last_restart_notify = world.time
return
if(END_GAME_DELAYED)
@@ -418,6 +423,7 @@ var/global/datum/controller/subsystem/ticker/ticker
if(new_char.client)
var/obj/screen/splash/S = new(new_char.client, TRUE)
S.Fade(TRUE)
new_char.client.init_verbs()
// If they're a carbon, they can get manifested
if(J?.mob_type & JOB_CARBON)
@@ -478,7 +484,7 @@ var/global/datum/controller/subsystem/ticker/ticker
to_chat(Player, span_filter_system(span_red(span_bold("You did not survive the events on [station_name()]..."))))
else
to_chat(Player, span_filter_system(span_red(span_bold("You did not survive the events on [station_name()]..."))))
to_world("<br>")
to_world(span_filter_system("<br>"))
for (var/mob/living/silicon/ai/aiPlayer in mob_list)
if (aiPlayer.stat != 2)
@@ -542,28 +548,29 @@ var/global/datum/controller/subsystem/ticker/ticker
return 1
/datum/controller/subsystem/ticker/stat_entry()
/datum/controller/subsystem/ticker/stat_entry(msg)
switch(current_state)
if(GAME_STATE_INIT)
..()
if(GAME_STATE_PREGAME) // RUNLEVEL_LOBBY
..("START [round_progressing ? "[round(pregame_timeleft)]s" : "(PAUSED)"]")
msg = "START [round_progressing ? "[round(pregame_timeleft)]s" : "(PAUSED)"]"
if(GAME_STATE_SETTING_UP) // RUNLEVEL_SETUP
..("SETUP")
msg = "SETUP"
if(GAME_STATE_PLAYING) // RUNLEVEL_GAME
..("GAME")
msg = "GAME"
if(GAME_STATE_FINISHED) // RUNLEVEL_POSTGAME
switch(end_game_state)
if(END_GAME_MODE_FINISHED)
..("MODE OVER, WAITING")
msg = "MODE OVER, WAITING"
if(END_GAME_READY_TO_END)
..("ENDGAME PROCESSING")
msg = "ENDGAME PROCESSING"
if(END_GAME_ENDING)
..("END IN [round(restart_timeleft/10)]s")
msg = "END IN [round(restart_timeleft/10)]s"
if(END_GAME_DELAYED)
..("END PAUSED")
msg = "END PAUSED"
else
..("ENDGAME ERROR:[end_game_state]")
msg = "ENDGAME ERROR:[end_game_state]"
return ..()
/datum/controller/subsystem/ticker/Recover()
flags |= SS_NO_INIT // Don't initialize again
@@ -579,3 +586,5 @@ var/global/datum/controller/subsystem/ticker/ticker
minds = SSticker.minds
random_players = SSticker.random_players
round_start_time = SSticker.round_start_time
+2 -1
View File
@@ -34,7 +34,8 @@ SUBSYSTEM_DEF(timer)
bucket_resolution = world.tick_lag
/datum/controller/subsystem/timer/stat_entry(msg)
..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
msg = "B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]"
return ..()
/datum/controller/subsystem/timer/fire(resumed = FALSE)
var/lit = last_invoke_tick
+3 -4
View File
@@ -122,9 +122,8 @@ SUBSYSTEM_DEF(transcore)
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/transcore/stat_entry()
var/msg = list()
msg += "$:{"
/datum/controller/subsystem/transcore/stat_entry(msg)
msg = "$:{"
msg += "IM:[round(cost_implants,1)]|"
msg += "BK:[round(cost_backups,1)]"
msg += "} "
@@ -137,7 +136,7 @@ SUBSYSTEM_DEF(transcore)
msg += "DFB:[default_db.body_scans.len]|"
msg += "DFI:[default_db.implants.len]"
msg += "} "
..(jointext(msg, null))
return ..()
/datum/controller/subsystem/transcore/Recover()
for(var/key in SStranscore.databases)
+10 -10
View File
@@ -25,7 +25,7 @@ SUBSYSTEM_DEF(vote)
if(mode)
time_remaining = round((started_time + duration - world.time)/10)
if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP)
to_chat(world, "<b>Gamemode vote aborted: Game has already started.</b>")
to_chat(world, span_bold("Gamemode vote aborted: Game has already started."))
reset()
return
if(time_remaining <= 0)
@@ -105,7 +105,7 @@ SUBSYSTEM_DEF(vote)
else
factor = 1.4
choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor)
to_world(span_purple("Crew Transfer Factor: [factor]"))
to_world(span_filter_system(span_purple("Crew Transfer Factor: [factor]")))
greatest_votes = max(choices["Initiate Crew Transfer"], choices["Extend the Shift"]) //VOREStation Edit
. = list() // Get all options with that many votes and return them in a list
@@ -120,7 +120,7 @@ SUBSYSTEM_DEF(vote)
if(winners.len > 0)
if(winners.len > 1)
if(mode != VOTE_GAMEMODE || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes
text = "<b>Vote Tied Between:</b>\n"
text = span_bold("Vote Tied Between:") + "\n"
for(var/option in winners)
text += "\t[option]\n"
. = pick(winners)
@@ -129,12 +129,12 @@ SUBSYSTEM_DEF(vote)
if(choices[current_votes[key]] == .)
round_voters += key // Keep track of who voted for the winning round.
if(mode != VOTE_GAMEMODE || . == "Extended" || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes
text += "<b>Vote Result: [mode == VOTE_GAMEMODE ? gamemode_names[.] : .]</b>"
text += span_bold("Vote Result: [mode == VOTE_GAMEMODE ? gamemode_names[.] : .]")
else
text += "<b>The vote has ended.</b>"
text += span_bold("The vote has ended.")
else
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
text += span_bold("Vote Result: Inconclusive - No Votes!")
if(mode == VOTE_ADD_ANTAGONIST)
antag_add_failed = 1
log_vote(text)
@@ -167,10 +167,10 @@ SUBSYSTEM_DEF(vote)
if(mode == VOTE_GAMEMODE) //fire this even if the vote fails.
if(!round_progressing)
round_progressing = 1
to_world(span_red("<b>The round will start soon.</b>"))
to_world(span_boldannounce("The round will start soon."))
if(restart)
to_world("World restarting due to vote...")
to_world(span_filter_system("World restarting due to vote..."))
feedback_set_details("end_error", "restart vote")
if(blackbox)
blackbox.save_all_data_to_sql()
@@ -253,14 +253,14 @@ SUBSYSTEM_DEF(vote)
log_vote(text)
to_world(span_purple("<b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [config.vote_period / 10] seconds to vote."))
to_world(span_filter_system(span_purple(span_bold("[text]") + "\nType " + span_bold("vote") + " or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [config.vote_period / 10] seconds to vote.")))
if(vote_type == VOTE_CREW_TRANSFER || vote_type == VOTE_GAMEMODE || vote_type == VOTE_CUSTOM)
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
if(mode == VOTE_GAMEMODE && round_progressing)
gamemode_vote_called = TRUE
round_progressing = 0
to_world(span_red("<b>Round start has been delayed.</b>"))
to_world(span_boldannounce("Round start has been delayed."))
time_remaining = round(config.vote_period / 10)
return 1
+2 -2
View File
@@ -227,9 +227,9 @@
if(law == zeroth_law_borg)
continue
if(law == zeroth_law)
to_chat(who, span_danger("[law.get_index()]. [law.law]"))
to_chat(who, span_info(span_red("[law.get_index()]. [law.law]")))
else
to_chat(who, "[law.get_index()]. [law.law]")
to_chat(who, span_infoplain("[law.get_index()]. [law.law]"))
/********************
* Stating Laws *
+1 -1
View File
@@ -148,7 +148,7 @@ var/list/runechat_image_cache = list()
// Differnt from our own system of name emphasis, maybe unify
var/list/names = splittext(owner.name, " ")
for (var/word in names)
text = replacetext(text, word, "<b>[word]</b>")
text = replacetext(text, word, span_bold("[word]"))
var/list/prefixes
@@ -0,0 +1,59 @@
/// This component behaves similar to connect_loc_behalf, but working off clients and mobs instead of loc
/// To be clear, we hook into a signal on a tracked client's mob
/// We retain the ability to react to that signal on a seperate listener, which makes this quite powerful
/datum/component/connect_mob_behalf
dupe_mode = COMPONENT_DUPE_UNIQUE
/// An assoc list of signal -> procpath to register to the mob our client "owns"
var/list/connections
/// The master client we're working with
var/client/tracked
/// The mob we're currently tracking
var/mob/tracked_mob
/datum/component/connect_mob_behalf/Initialize(client/tracked, list/connections)
. = ..()
if (!istype(tracked))
return COMPONENT_INCOMPATIBLE
src.connections = connections
src.tracked = tracked
/datum/component/connect_mob_behalf/RegisterWithParent()
RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel))
update_signals()
/datum/component/connect_mob_behalf/UnregisterFromParent()
unregister_signals()
UnregisterSignal(tracked, COMSIG_PARENT_QDELETING)
tracked = null
tracked_mob = null
/datum/component/connect_mob_behalf/proc/handle_tracked_qdel()
SIGNAL_HANDLER
qdel(src)
/datum/component/connect_mob_behalf/proc/update_signals()
unregister_signals()
// Yes this is a runtime silencer
// We could be in a position where logout is sent to two things, one thing intercepts it, then deletes the client's new mob
// It's rare, and the same check in connect_loc_behalf is more fruitful, but it's still worth doing
if(QDELETED(tracked?.mob))
return
tracked_mob = tracked.mob
RegisterSignal(tracked_mob, COMSIG_MOB_LOGOUT, PROC_REF(on_logout))
for (var/signal in connections)
parent.RegisterSignal(tracked_mob, signal, connections[signal])
/datum/component/connect_mob_behalf/proc/unregister_signals()
if(isnull(tracked_mob))
return
parent.UnregisterSignal(tracked_mob, connections)
UnregisterSignal(tracked_mob, COMSIG_MOB_LOGOUT)
tracked_mob = null
/datum/component/connect_mob_behalf/proc/on_logout(mob/source)
SIGNAL_HANDLER
update_signals()
+1 -1
View File
@@ -91,7 +91,7 @@
/datum/proc/vv_get_header()
. = list()
if(("name" in vars) && !isatom(src))
. += "<b>[vars["name"]]</b><br>"
. += span_bold("[vars["name"]]") + "<br>"
/datum/proc/on_reagent_change(changetype)
return
+6 -6
View File
@@ -64,19 +64,19 @@ GLOBAL_DATUM(revdata, /datum/getrev)
var/list/msg = list()
if(GLOB.revdata.revision)
msg += "<b>Server revision:</b> B:[GLOB.revdata.branch] D:[GLOB.revdata.date]"
msg += span_bold("Server revision:") + " B:[GLOB.revdata.branch] D:[GLOB.revdata.date]"
if(config.githuburl)
msg += "<b>Commit:</b> <a href='[config.githuburl]/commit/[GLOB.revdata.revision]'>[GLOB.revdata.revision]</a>"
msg += span_bold("Commit:") + " <a href='[config.githuburl]/commit/[GLOB.revdata.revision]'>[GLOB.revdata.revision]</a>"
else
msg += "<b>Commit:</b> GLOB.revdata.revision"
msg += span_bold("Commit:") + " GLOB.revdata.revision"
else
msg += "<b>Server revision:</b> Unknown"
msg += span_bold("Server revision:") + " Unknown"
if(world.TgsAvailable())
var/datum/tgs_version/version = world.TgsVersion()
msg += "<b>TGS version:</b> [version.raw_parameter]"
msg += span_bold("TGS version:") + " [version.raw_parameter]"
var/datum/tgs_version/api_version = world.TgsApiVersion()
msg += "<b>DMAPI version:</b> [api_version.raw_parameter]"
msg += span_bold("DMAPI version:") + " [api_version.raw_parameter]"
if(GLOB.revdata.testmerge.len)
msg += GLOB.revdata.GetTestMergeInfo()
@@ -58,14 +58,14 @@ GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form)
if(can_be_private())
if(!feedback_hide_author)
dat += "[my_client.ckey] "
dat += span_linkOn("<b>Visible</b>")
dat += span_linkOn(span_bold("Visible"))
dat += " | "
dat += href(src, list("feedback_hide_author" = 1), "Hashed")
else
dat += "[md5(ckey(lowertext(my_client.ckey + SSsqlite.get_feedback_pepper())))] "
dat += href(src, list("feedback_hide_author" = 0), "Visible")
dat += " | "
dat += span_linkOn("<b>Hashed</b>")
dat += span_linkOn(span_bold("Hashed"))
else
dat += my_client.ckey
dat += "<br>"
@@ -79,7 +79,7 @@ GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form)
if(feedback_body)
dat += replacetext(feedback_body, "\n", "<br>") // So newlines will look like they work in the preview.
else
dat += "<i>\[Feedback goes here...\]</i>"
dat += span_italics("\[Feedback goes here...\]")
dat += "<br>"
dat += href(src, list("feedback_edit_body" = 1), "Edit")
dat += "<hr>"
+12 -9
View File
@@ -88,7 +88,7 @@
if(current) //remove ourself from our old body's mind variable
if(changeling)
current.remove_changeling_powers()
current.verbs -= /datum/changeling/proc/EvolutionMenu
remove_verb(current, /datum/changeling/proc/EvolutionMenu)
current.mind = null
if(new_character.mind) //remove any mind currently in our new body's mind variable
@@ -103,11 +103,14 @@
if(active)
new_character.key = key //now transfer the key to link the client to our new body
if(new_character.client)
new_character.client.init_verbs() // re-initialize character specific verbs
/datum/mind/proc/store_memory(new_text)
memory += "[new_text]<BR>"
/datum/mind/proc/show_memory(mob/recipient)
var/output = "<B>[current.real_name]'s Memory</B><HR>"
var/output = span_bold("[current.real_name]'s Memory") + "<HR>"
output += memory
if(objectives.len>0)
@@ -115,7 +118,7 @@
var/obj_count = 1
for(var/datum/objective/objective in objectives)
output += "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
output += span_bold("Objective #[obj_count]") + ": [objective.explanation_text]"
obj_count++
if(ambitions)
@@ -127,7 +130,7 @@
tgui_alert_async(usr, "Not before round-start!", "Alert")
return
var/out = "<B>[name]</B>[(current&&(current.real_name!=name))?" (as [current.real_name])":""]<br>"
var/out = span_bold("[name]") + "[(current&&(current.real_name!=name))?" (as [current.real_name])":""]<br>"
out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]<br>"
out += "Assigned role: [assigned_role]. <a href='?src=\ref[src];[HrefToken()];role_edit=1'>Edit</a><br>"
out += "<hr>"
@@ -136,12 +139,12 @@
var/datum/antagonist/antag = all_antag_types[antag_type]
out += "[antag.get_panel_entry(src)]"
out += "</table><hr>"
out += "<b>Objectives</b></br>"
out += span_bold("Objectives") + "</br>"
if(objectives && objectives.len)
var/num = 1
for(var/datum/objective/O in objectives)
out += "<b>Objective #[num]:</b> [O.explanation_text] "
out += span_bold("Objective #[num]:") + " [O.explanation_text] "
if(O.completed)
out += "([span_green("complete")])"
else
@@ -154,7 +157,7 @@
else
out += "None."
out += "<br><a href='?src=\ref[src];[HrefToken()];obj_add=1'>\[add\]</a><br><br>"
out += "<b>Ambitions:</b> [ambitions ? ambitions : "None"] <a href='?src=\ref[src];[HrefToken()];amb_edit=\ref[src]'>\[edit\]</a></br>"
out += span_bold("Ambitions:") + " [ambitions ? ambitions : "None"] <a href='?src=\ref[src];[HrefToken()];amb_edit=\ref[src]'>\[edit\]</a></br>"
usr << browse(out, "window=edit_memory[src]")
/datum/mind/Topic(href, href_list)
@@ -421,7 +424,7 @@
var/obj_count = 1
to_chat(current, span_blue("Your current objectives:"))
for(var/datum/objective/objective in objectives)
to_chat(current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
to_chat(current, span_bold("Objective #[obj_count]") + ": [objective.explanation_text]")
obj_count++
edit_memory()
@@ -516,7 +519,7 @@
if(!mind.name) mind.name = real_name
mind.current = src
if(player_is_antag(mind))
src.client.verbs += /client/proc/aooc
add_verb(src.client, /client/proc/aooc)
//HUMAN
/mob/living/carbon/human/mind_initialize()
+1 -1
View File
@@ -35,7 +35,7 @@ GLOBAL_DATUM_INIT(item_unequipped_event, /decl/observ/item_unequipped, new)
**********************/
/obj/item/dropped(var/mob/user)
..()
. = ..(user)
//SEND_SIGNAL(user, COMSIG_OBSERVER_MOB_UNEQUIPPED, src)
//SEND_SIGNAL(src, COMSIG_OBSERVER_ITEM_UNEQUIPPED, user)
if(user) // Cannot always guarantee that user won't be null
+1 -1
View File
@@ -41,7 +41,7 @@ GLOBAL_LIST(active_department_goals)
for(var/category in GLOB.active_department_goals)
var/list/cat_goals = GLOB.active_department_goals[category]
to_world(span_filter_system("<b>[category]</b>"))
to_world(span_world("[category]"))
if(!LAZYLEN(cat_goals))
to_world(span_filter_system("There were no assigned goals!"))
+2 -2
View File
@@ -84,7 +84,7 @@ var/global/list/security_printer_tickets = list() //VOREStation Edit
//VOREStation Add End
if(LAZYLEN(valid_stats_list))
to_world("<B>Shift trivia!</B>")
to_world(span_world("Shift trivia!"))
for(var/body in valid_stats_list)
to_world("[body]")
to_world(span_filter_system("[body]"))
+1 -1
View File
@@ -69,7 +69,7 @@
to_world(span_alert("[message]"))
if(announcer)
to_world(span_alert(" -[html_encode(announcer)]"))
to_world("<br>")
to_world(span_alert("<br>"))
/datum/announcement/priority/command/Message(message as text, message_title as text, var/list/zlevels)
var/command
+2 -2
View File
@@ -76,7 +76,7 @@
var/antag_text = "You are an antagonist! Within the rules, \
try to act as an opposing force to the crew. Further RP and try to make sure \
other players have <i>fun</i>! If you are confused or at a loss, always adminhelp, \
other players have " + span_italics("fun") + "! If you are confused or at a loss, always adminhelp, \
and before taking extreme actions, please try to also contact the administration! \
Think through your actions and make the roleplay immersive! <b>Please remember all \
rules aside from those without explicit exceptions apply to antagonists.</b>"
@@ -145,7 +145,7 @@
if(!istype(player))
message_admins("[uppertext(ticker.mode.name)]: Failed to find a candidate for [role_text].")
return 0
to_chat(player.current, span_danger("<i>You have been selected this round as an antagonist!</i>"))
to_chat(player.current, span_danger(span_italics("You have been selected this round as an antagonist!")))
message_admins("[uppertext(ticker.mode.name)]: Selected [player] as a [role_text].")
if(istype(player.current, /mob/observer/dead))
create_default(player.current)
+6 -6
View File
@@ -28,16 +28,16 @@
current_antagonists |= player
if(faction_verb && player.current)
player.current.verbs |= faction_verb
add_verb(player.current, faction_verb)
spawn(1 SECOND) //Added a delay so that this should pop up at the bottom and not the top of the text flood the new antag gets.
to_chat(player.current, span_notice("Once you decide on a goal to pursue, you can optionally display it to \
everyone at the end of the shift with the " + span_bold("Set Ambition") + " verb, located in the IC tab. You can change this at any time, \
and it otherwise has no bearing on your round."))
player.current.verbs |= /mob/living/proc/write_ambition
add_verb(player.current, /mob/living/proc/write_ambition)
if(can_speak_aooc)
player.current.client.verbs += /client/proc/aooc
add_verb(player.current.client, /client/proc/aooc)
// Handle only adding a mind and not bothering with gear etc.
if(nonstandard_role_type)
@@ -51,7 +51,7 @@
/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
if(player.current && faction_verb)
player.current.verbs -= faction_verb
remove_verb(player.current, faction_verb)
if(player in current_antagonists)
to_chat(player.current, span_danger(span_large("You are no longer a [role_text]!")))
current_antagonists -= player
@@ -60,8 +60,8 @@
update_icons_removed(player)
BITSET(player.current.hud_updateflag, SPECIALROLE_HUD)
if(!is_special_character(player))
player.current.verbs -= /mob/living/proc/write_ambition
player.current.client.verbs -= /client/proc/aooc
remove_verb(player.current, /mob/living/proc/write_ambition)
remove_verb(player.current.client, /client/proc/aooc)
player.ambitions = ""
return 1
return 0
+2 -2
View File
@@ -85,7 +85,7 @@
if(!code_owner && leader)
code_owner = leader
if(code_owner)
code_owner.store_memory("<B>Nuclear Bomb Code</B>: [code]", 0, 0)
code_owner.store_memory(span_bold("Nuclear Bomb Code") + ": [code]", 0, 0)
to_chat(code_owner.current, "The nuclear authorization code is: <B>[code]</B>")
else
message_admins(span_danger("Could not spawn nuclear bomb. Contact a developer."))
@@ -101,7 +101,7 @@
window_flash(player.current.client)
// Basic intro text.
to_chat(player.current, span_danger("<font size=3>You are a [role_text]!</font>"))
to_chat(player.current, span_danger(span_large("You are a [role_text]!")))
if(leader_welcome_text && player == leader)
to_chat(player.current, span_notice("[leader_welcome_text]"))
else
@@ -24,10 +24,10 @@
if(!O.completed && !O.check_completion())
result = 0
if(result && victory_text)
to_world(span_danger("<font size = 3>[victory_text]</font>"))
to_world(span_boldannounce(span_large("[victory_text]")))
if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]")
else if(loss_text)
to_world(span_danger("<font size = 3>[loss_text]</font>"))
to_world(span_boldannounce(span_large("[loss_text]")))
if(loss_feedback_tag) feedback_set_details("round_end_result","[loss_feedback_tag]")
/mob/living/proc/write_ambition()
+4 -4
View File
@@ -8,12 +8,12 @@ var/datum/antagonist/ert/ert
role_text_plural = "Emergency Responders"
welcome_text = "As member of the Emergency Response Team, you answer only to your leader and company officials."
antag_sound = 'sound/effects/antag_notice/general_goodie_alert.ogg'
antag_text = "You are an <b>anti</b> antagonist! Within the rules, \
antag_text = "You are an " + span_bold("anti") + " antagonist! Within the rules, \
try to save the station and its inhabitants from the ongoing crisis. \
Try to make sure other players have <i>fun</i>! If you are confused or at a loss, always adminhelp, \
Try to make sure other players have " + span_italics("fun") + "! If you are confused or at a loss, always adminhelp, \
and before taking extreme actions, please try to also contact the administration! \
Think through your actions and make the roleplay immersive! <b>Please remember all \
rules aside from those without explicit exceptions apply to the ERT.</b>"
Think through your actions and make the roleplay immersive! " + span_bold("Please remember all \
rules aside from those without explicit exceptions apply to the ERT.")
leader_welcome_text = "As leader of the Emergency Response Team, you answer only to the Company, and have authority to override the " + JOB_SITE_MANAGER + " where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the " + JOB_SITE_MANAGER + " where possible, however."
landmark_id = "Response Team"
id_type = /obj/item/card/id/centcom/ERT
+6 -6
View File
@@ -173,22 +173,22 @@ var/datum/antagonist/raider/raiders
if(antags_are_dead())
win_type = "Major"
win_group = "Crew"
win_msg += "<B>The Raiders have been wiped out!</B>"
win_msg += span_bold("The Raiders have been wiped out!")
else if(is_raider_crew_safe())
if(win_group == "Crew" && win_type == "Minor")
win_type = "Major"
win_group = "Crew"
win_msg += "<B>The Raiders have left someone behind!</B>"
win_msg += span_bold("The Raiders have left someone behind!")
else
if(win_group == "Raider")
if(win_type == "Minor")
win_type = "Major"
win_msg += "<B>The Raiders escaped the station!</B>"
win_msg += span_bold("The Raiders escaped the station!")
else
win_msg += "<B>The Raiders were repelled!</B>"
win_msg += span_bold("The Raiders were repelled!")
to_world(span_danger("<font size = 3>[win_type] [win_group] victory!</font>"))
to_world("[win_msg]")
to_world(span_boldannounce(span_large("[win_type] [win_group] victory!")))
to_world(span_filter_system("[win_msg]"))
feedback_set_details("round_end_result","heist - [win_type] [win_group]")
/datum/antagonist/raider/proc/is_raider_crew_safe()
@@ -28,7 +28,7 @@ var/datum/antagonist/technomancer/technomancers
/datum/antagonist/technomancer/update_antag_mob(var/datum/mind/technomancer)
..()
technomancer.store_memory("<B>Remember:</B> Do not forget to purchase the functions and equipment you need.")
technomancer.store_memory(span_bold("Remember:") + " Do not forget to purchase the functions and equipment you need.")
technomancer.current.real_name = "[pick(wizard_first)] [pick(wizard_second)]"
technomancer.current.name = technomancer.current.real_name
@@ -78,7 +78,7 @@ var/datum/antagonist/technomancer/technomancers
break
if(!survivor)
feedback_set_details("round_end_result","loss - technomancer killed")
to_world(span_danger("<font size = 3>The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed!</font>"))
to_world(span_boldannounce(span_large("The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed!")))
/datum/antagonist/technomancer/print_player_summary()
..()
@@ -87,7 +87,7 @@ var/datum/antagonist/technomancer/technomancers
continue // Only want abandoned cores.
if(!core.spells.len)
continue // Cores containing spells only.
to_world("Abandoned [core] had [english_list(core.spells)].<br>")
to_world(span_filter_system("Abandoned [core] had [english_list(core.spells)].<br>"))
/datum/antagonist/technomancer/print_player_full(var/datum/mind/player)
var/text = print_player_lite(player)
+2 -2
View File
@@ -66,7 +66,7 @@ var/datum/antagonist/wizard/wizards
/datum/antagonist/wizard/update_antag_mob(var/datum/mind/wizard)
..()
wizard.store_memory("<B>Remember:</B> do not forget to prepare your spells.")
wizard.store_memory(span_bold("Remember:") + " do not forget to prepare your spells.")
wizard.current.real_name = "[pick(wizard_first)] [pick(wizard_second)]"
wizard.current.name = wizard.current.real_name
@@ -99,7 +99,7 @@ var/datum/antagonist/wizard/wizards
break
if(!survivor)
feedback_set_details("round_end_result","loss - wizard killed")
to_world(span_danger("<font size = 3>The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed by the crew!</font>"))
to_world(span_boldannounce(span_large("The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed by the crew!")))
//To batch-remove wizard spells. Linked to mind.dm.
/mob/proc/spellremove()
+1 -1
View File
@@ -74,6 +74,6 @@ var/datum/antagonist/traitor/infiltrator/infiltrators
/datum/antagonist/traitor/infiltrator/add_law_zero(mob/living/silicon/ai/killer)
var/law = "Accomplish your team's objectives at all costs. You may ignore all other laws."
var/law_borg = "Accomplish your AI's team objectives at all costs. You may ignore all other laws."
to_chat(killer, "<b>Your laws have been changed!</b>")
to_chat(killer, span_infoplain(span_bold("Your laws have been changed!")))
killer.set_zeroth_law(law, law_borg)
to_chat(killer, "New law: 0. [law]")
+1 -1
View File
@@ -98,7 +98,7 @@ var/datum/antagonist/renegade/renegades
/proc/rightandwrong()
to_chat(usr, "<B>You summoned guns!</B>")
to_chat(usr, span_infoplain(span_bold("You summoned guns!")))
message_admins("[key_name_admin(usr, 1)] summoned guns!")
for(var/mob/living/carbon/human/H in player_list)
if(H.stat == 2 || !(H.client)) continue

Some files were not shown because too many files have changed in this diff Show More