diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_comms_agent.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_comms_agent.dmm index d5c344e9cd31a..3553672b1080c 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_comms_agent.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_comms_agent.dmm @@ -993,9 +993,6 @@ /area/ruin/comms_agent) "UI" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/records/security/laptop/syndie{ - dir = 1 - }, /obj/item/paper/monitorkey{ pixel_x = -15; pixel_y = 7 diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index de9e1338f2939..125324bb07ea4 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -9394,10 +9394,9 @@ /obj/machinery/airalarm/directional/north, /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks, -/obj/effect/turf_decal/siding/wood{ - dir = 5 +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 }, -/obj/effect/turf_decal/siding/wood, /turf/open/floor/iron/dark/diagonal, /area/station/service/bar) "dxZ" = ( @@ -10072,6 +10071,7 @@ }, /obj/structure/disposalpipe/segment, /obj/structure/cable, +/obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/stone, /area/station/service/bar) "dMm" = ( @@ -33247,11 +33247,10 @@ pixel_x = -7; pixel_y = 15 }, -/obj/effect/turf_decal/siding/wood{ - dir = 9 - }, -/obj/effect/turf_decal/siding/wood, /obj/structure/sign/warning/no_smoking/circle/directional/north, +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, /turf/open/floor/iron/dark/diagonal, /area/station/service/bar) "lnI" = ( @@ -50833,12 +50832,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/service/lawoffice) -"rrX" = ( -/obj/effect/turf_decal/siding/wood/corner{ - dir = 4 - }, -/turf/open/floor/stone, -/area/station/service/bar) "rrZ" = ( /obj/structure/closet/crate/trashcart, /obj/effect/spawner/random/trash/garbage, @@ -56445,11 +56438,14 @@ /turf/open/floor/eighties/red, /area/station/hallway/primary/central/fore) "tjT" = ( -/obj/structure/extinguisher_cabinet/directional/north, +/obj/machinery/chem_master/condimaster, +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, /obj/effect/turf_decal/siding/wood{ - dir = 5 + dir = 4 }, -/turf/open/floor/stone, +/turf/open/floor/iron/dark/diagonal, /area/station/service/bar) "tjY" = ( /obj/machinery/atmospherics/components/binary/pump/on{ @@ -100086,7 +100082,7 @@ iXW dRb sON tjT -rrX +xkV lAV fYJ eGU diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index aa3df4dfd8a93..6ee4db7790ea9 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -46005,6 +46005,13 @@ dir = 4 }, /area/station/hallway/secondary/entry) +"nqI" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral/half/contrasted, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/commons/fitness) "nqP" = ( /obj/machinery/camera/directional/north{ c_tag = "Research Division West"; @@ -53846,8 +53853,8 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/obj/item/kirbyplants/random, /obj/structure/sign/flag/terragov/directional/north, +/obj/structure/weightmachine/weightlifter, /turf/open/floor/iron, /area/station/commons/fitness) "pyn" = ( @@ -81087,6 +81094,10 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/security/detectives_office) +"xyg" = ( +/obj/structure/weightmachine, +/turf/open/floor/iron, +/area/station/commons/fitness) "xyl" = ( /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 1 @@ -249315,7 +249326,7 @@ cGB cGB gsI tLL -spy +nqI kKL kKL kKL @@ -250338,8 +250349,8 @@ dyA skl gaC vfW -eOl vfW +xyg vfW lvk crv diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 6b4adfe0d4896..e6aabf579de2a 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -67095,10 +67095,6 @@ }, /turf/open/floor/iron, /area/station/ai_monitored/command/storage/eva) -"xBX" = ( -/obj/machinery/firealarm/directional/east, -/turf/closed/wall, -/area/station/security/checkpoint/customs) "xCf" = ( /obj/item/clothing/suit/jacket/straight_jacket, /obj/item/electropack, @@ -83046,7 +83042,7 @@ wdr fcq xfI fcq -xBX +xjh qhW xjh yme diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 74c9120d804d4..ea5c52bf36f0f 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -45,40 +45,40 @@ #define R_EVERYTHING (1<<15)-1 //the sum of all other rank permissions, used for +EVERYTHING -#define ADMIN_QUE(user) "(?)" -#define ADMIN_FLW(user) "(FLW)" -#define ADMIN_PP(user) "(PP)" -#define ADMIN_VV(atom) "(VV)" -#define ADMIN_SM(user) "(SM)" -#define ADMIN_TP(user) "(TP)" -#define ADMIN_SP(user) "(SP)" -#define ADMIN_KICK(user) "(KICK)" -#define ADMIN_CENTCOM_REPLY(user) "(RPLY)" -#define ADMIN_SYNDICATE_REPLY(user) "(RPLY)" -#define ADMIN_SC(user) "(SC)" -#define ADMIN_SMITE(user) "(SMITE)" +#define ADMIN_QUE(user) "(?)" +#define ADMIN_FLW(user) "(FLW)" +#define ADMIN_PP(user) "(PP)" +#define ADMIN_VV(atom) "(VV)" +#define ADMIN_SM(user) "(SM)" +#define ADMIN_TP(user) "(TP)" +#define ADMIN_SP(user) "(SP)" +#define ADMIN_KICK(user) "(KICK)" +#define ADMIN_CENTCOM_REPLY(user) "(RPLY)" +#define ADMIN_SYNDICATE_REPLY(user) "(RPLY)" +#define ADMIN_SC(user) "(SC)" +#define ADMIN_SMITE(user) "(SMITE)" #define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]" #define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]" -#define ADMIN_SET_SD_CODE "(SETCODE)" +#define ADMIN_SET_SD_CODE "(SETCODE)" #define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]" #define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]" -#define ADMIN_JMP(src) "(JMP)" +#define ADMIN_JMP(src) "(JMP)" #define COORD(src) "[src ? src.Admin_Coordinates_Readable() : "nonexistent location"]" #define AREACOORD(src) "[src ? src.Admin_Coordinates_Readable(TRUE) : "nonexistent location"]" #define ADMIN_COORDJMP(src) "[src ? src.Admin_Coordinates_Readable(FALSE, TRUE) : "nonexistent location"]" #define ADMIN_VERBOSEJMP(src) "[src ? src.Admin_Coordinates_Readable(TRUE, TRUE) : "nonexistent location"]" -#define ADMIN_INDIVIDUALLOG(user) "(LOGS)" -#define ADMIN_TAG(datum) "(TAG)" -#define ADMIN_LUAVIEW(state) "(VIEW STATE)" -#define ADMIN_LUAVIEW_CHUNK(state, log_index) "(VIEW CODE)" +#define ADMIN_INDIVIDUALLOG(user) "(LOGS)" +#define ADMIN_TAG(datum) "(TAG)" +#define ADMIN_LUAVIEW(state) "(VIEW STATE)" +#define ADMIN_LUAVIEW_CHUNK(state, log_index) "(VIEW CODE)" /// Displays "(SHOW)" in the chat, when clicked it tries to show atom(paper). First you need to set the request_state variable to TRUE for the paper. -#define ADMIN_SHOW_PAPER(atom) "(SHOW)" +#define ADMIN_SHOW_PAPER(atom) "(SHOW)" /// Displays "(PRINT)" in the chat, when clicked it will try to print the atom(paper) on the CentCom/Syndicate fax machine. -#define ADMIN_PRINT_FAX(atom, sender, destination) "(PRINT)" +#define ADMIN_PRINT_FAX(atom, sender, destination) "(PRINT)" /// Displays "(PLAY)" in the chat, when clicked it tries to play internet sounds from the request. -#define ADMIN_PLAY_INTERNET(text, credit) "(PLAY)" +#define ADMIN_PLAY_INTERNET(text, credit) "(PLAY)" /// Displays "(SEE Z-LEVEL LAYOUT)" in the chat, when clicked it shows the z-level layouts for the current world state. -#define ADMIN_SEE_ZLEVEL_LAYOUT "(SEE Z-LEVEL LAYOUT)" +#define ADMIN_SEE_ZLEVEL_LAYOUT "(SEE Z-LEVEL LAYOUT)" /atom/proc/Admin_Coordinates_Readable(area_name, admin_jump_ref) var/turf/turf_at_coords = Safe_COORD_Location() diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm index b5a7ad1ddfaac..f7f77a7169ea2 100644 --- a/code/__DEFINES/ai/ai_blackboard.dm +++ b/code/__DEFINES/ai/ai_blackboard.dm @@ -195,6 +195,14 @@ #define BB_DRILLABLE_ICE "BB_drillable_ice" +//emotions we displays depending on our happiness +///emotions we display when happy +#define BB_HAPPY_EMOTIONS "happy_emotions" +///emotions we display when neutral +#define BB_MODERATE_EMOTIONS "moderate_emotions" +///emotions we display when depressed +#define BB_SAD_EMOTIONS "sad_emotions" + // Keys used by one and only one behavior // Used to hold state without making bigass lists /// For /datum/ai_behavior/find_potential_targets, what if any field are we using currently diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm index 330e2d48eb226..d77817a203980 100644 --- a/code/__DEFINES/ai/monsters.dm +++ b/code/__DEFINES/ai/monsters.dm @@ -304,3 +304,11 @@ #define BB_DEER_RESTING "deer_resting" ///time till our next rest duration #define BB_DEER_NEXT_REST_TIMER "deer_next_rest_timer" + +//turtle +///our tree's ability +#define BB_TURTLE_TREE_ABILITY "turtle_tree_ability" +///people we headbutt! +#define BB_TURTLE_HEADBUTT_VICTIM "turtle_headbutt_victim" +///flore we must smell +#define BB_TURTLE_FLORA_TARGET "turtle_flora_target" diff --git a/code/__DEFINES/chat.dm b/code/__DEFINES/chat.dm index 516fe8c4e193a..80fb1a07eccf3 100644 --- a/code/__DEFINES/chat.dm +++ b/code/__DEFINES/chat.dm @@ -44,9 +44,11 @@ /// Used for debug messages to the server #define debug_world_log(msg) if (GLOB.Debug2) log_world("DEBUG: [msg]") /// Adds a generic box around whatever message you're sending in chat. Really makes things stand out. -#define examine_block(str) ("
" + str + "
") -/// Makes a fieldset with a name in the middle top part. Can apply additional classes -#define fieldset_block(title, content, classes) ("
" + title + "
" + content + "
") +#define boxed_message(str) ("
" + str + "
") +/// Adds a box around whatever message you're sending in chat. Can apply color and/or additional classes. Available colors: red, green, blue, purple. Use it like red_box +#define custom_boxed_message(classes, str) ("
" + str + "
") +/// Makes a fieldset with a neaty styled name. Can apply additional classes. +#define fieldset_block(title, content, classes) ("
" + title + "" + content + "
") /// Makes a horizontal line with text in the middle #define separator_hr(str) ("
" + str + "
") /// Emboldens runechat messages diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 5cb838603c98e..867d8a51d4163 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -98,6 +98,7 @@ DEFINE_BITFIELD(status_flags, list( #define CLICK_CD_RAPID 2 #define CLICK_CD_HYPER_RAPID 1 #define CLICK_CD_SLOW 10 +#define CLICK_CD_ACTIVATE_ABILITY 1 #define CLICK_CD_THROW 8 #define CLICK_CD_RANGE 4 diff --git a/code/__DEFINES/construction/rcd.dm b/code/__DEFINES/construction/rcd.dm index a8d98215af1dc..4f898d5ae86ec 100644 --- a/code/__DEFINES/construction/rcd.dm +++ b/code/__DEFINES/construction/rcd.dm @@ -51,3 +51,6 @@ #define RCD_MEMORY_COST_BUFF 8 /// If set to TRUE in rcd_vals, will bypass the cooldown on slowing down frequent use #define RCD_RESULT_BYPASS_FREQUENT_USE_COOLDOWN "bypass_frequent_use_cooldown" + +/// How much longer does it take to deconstruct rwalls? +#define RCD_RWALL_DELAY_MULT 2 diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm index bedfaf2fa0374..bb5b344a89a48 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm @@ -92,3 +92,6 @@ /// from /obj/projectile/energy/fisher/on_hit() or /obj/item/gun/energy/recharge/fisher when striking a target #define COMSIG_ATOM_SABOTEUR_ACT "hit_by_saboteur" #define COMSIG_SABOTEUR_SUCCESS 1 + +/// signal sent when a mouse is hovering over us, sent by atom/proc/on_mouse_entered +#define COMSIG_ATOM_MOUSE_ENTERED "mouse_entered" diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 63ebfdf98b21f..a83badb9ee067 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -547,6 +547,9 @@ ///Sent from /obj/item/skillchip/on_remove() #define COMSIG_SKILLCHIP_REMOVED "skillchip_removed" +/// from /obj/machinery/computer/camera_advanced/shuttle_docker/gatherNavComputerOverlays() : (list/images_out) +#define COMSIG_SHUTTLE_NAV_COMPUTER_IMAGE_REQUESTED "shuttle_nav_computer_image_requested" + /// Sent from /obj/item/organ/wings/functional/proc/open_wings(): (mob/living/carbon/owner) #define COMSIG_WINGS_OPENED "wings_opened" /// Sent from /obj/item/organ/wings/functional/proc/close_wings(): (mob/living/carbon/owner) diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index 5f025ad99cffb..8ae95933e646b 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -4,6 +4,9 @@ #define COMSIG_KB_ACTIVATED (1<<0) #define COMSIG_KB_EMOTE "keybinding_emote_down" +///Signal sent when a keybind is deactivated +#define DEACTIVATE_KEYBIND(A) "[A]_DEACTIVATED" + //Admin #define COMSIG_KB_ADMIN_ASAY_DOWN "keybinding_admin_asay_down" #define COMSIG_KB_ADMIN_DSAY_DOWN "keybinding_admin_dsay_down" @@ -54,6 +57,7 @@ #define COMSIG_KB_LIVING_DISABLE_COMBAT_DOWN "keybinding_living_disable_combat_down" #define COMSIG_KB_LIVING_TOGGLEMOVEINTENT_DOWN "keybinding_mob_togglemoveintent_down" #define COMSIG_KB_LIVING_TOGGLEMOVEINTENTALT_DOWN "keybinding_mob_togglemoveintentalt_down" +#define COMSIG_KB_LIVING_VIEW_PET_COMMANDS "keybinding_living_view_pet_commands" //Mob #define COMSIG_KB_MOB_FACENORTH_DOWN "keybinding_mob_facenorth_down" diff --git a/code/__DEFINES/radial_defines.dm b/code/__DEFINES/radial_defines.dm new file mode 100644 index 0000000000000..35ae6eebb5984 --- /dev/null +++ b/code/__DEFINES/radial_defines.dm @@ -0,0 +1,6 @@ +#define NEXT_PAGE_ID "__next__" +#define DEFAULT_CHECK_DELAY 2 SECONDS + +#define BUTTON_SLIDE_IN (1<<0) +#define BUTTON_FADE_IN (1<<1) +#define BUTTON_FADE_OUT (1<<2) diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 28172587e795a..bf3fd32918943 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -46,7 +46,8 @@ ///Health threshold for synthflesh and rezadone to unhusk someone #define UNHUSK_DAMAGE_THRESHOLD 50 ///Amount of synthflesh required to unhusk someone -#define SYNTHFLESH_UNHUSK_AMOUNT 100 +#define SYNTHFLESH_UNHUSK_AMOUNT 60 +#define SYNTHFLESH_UNHUSK_MAX 100 //used by chem masters and pill presses // The categories of reagent packaging diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index d905129b19b74..c3bd425af0a65 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -99,9 +99,9 @@ #define MODE_RANGE_INTERCOM 1 // A link given to ghost alice to follow bob -#define FOLLOW_LINK(alice, bob) "(F)" -#define TURF_LINK(alice, turfy) "(T)" -#define FOLLOW_OR_TURF_LINK(alice, bob, turfy) "(F)" +#define FOLLOW_LINK(alice, bob) "(F)" +#define TURF_LINK(alice, turfy) "(T)" +#define FOLLOW_OR_TURF_LINK(alice, bob, turfy) "(F)" //Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam #define MAX_MESSAGE_LEN 1024 diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 88f46a53fd92c..1ce2d5d46cb9c 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -50,7 +50,7 @@ #define GET_VV_VAR_TARGET href_list[VV_HK_VARNAME] //Helper for getting something to vv_do_topic in general -#define VV_TOPIC_LINK(datum, href_key, text) "text" +#define VV_TOPIC_LINK(datum, href_key, text) "text" //Helpers for vv_get_dropdown() #define VV_DROPDOWN_OPTION(href_key, name) . += "" diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 2c285a348fac2..9b80dbfc169c4 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -349,4 +349,4 @@ message = html_encode(message) else message = copytext(message, 2) - to_chat(target, span_purple(examine_block("[source]: [message]"))) + to_chat(target, custom_boxed_message("purple_box", span_purple("[source]: [message]"))) diff --git a/code/__HELPERS/logging/_logging.dm b/code/__HELPERS/logging/_logging.dm index bfcaded67f021..8f8f733e6ba8b 100644 --- a/code/__HELPERS/logging/_logging.dm +++ b/code/__HELPERS/logging/_logging.dm @@ -215,11 +215,11 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global")) if(key) if(C?.holder && C.holder.fakekey && !include_name) if(include_link) - . += "" + . += "" . += "Administrator" else if(include_link) - . += "" + . += "" . += key if(!C) . += "\[DC\]" diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 292639f387682..19dec4a7fd442 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -335,7 +335,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) if(GLOB.round_id) var/statspage = CONFIG_GET(string/roundstatsurl) - var/info = statspage ? "[GLOB.round_id]" : GLOB.round_id + var/info = statspage ? "[GLOB.round_id]" : GLOB.round_id parts += "[FOURSPACES]Round ID: [info]" parts += "[FOURSPACES]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" parts += "[FOURSPACES]Station Integrity: [GLOB.station_was_nuked ? span_redtext("Destroyed") : "[popcount["station_integrity"]]%"]" @@ -660,7 +660,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) var/datum/action/report/R = new C.player_details.player_actions += R R.Grant(C.mob) - to_chat(C,span_infoplain("Show roundend report again")) + to_chat(C,span_infoplain("Show roundend report again")) /datum/action/report name = "Show roundend report" diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 7cab2074c5485..6b6c6bc9050ab 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -1136,7 +1136,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." return FALSE var/list/modifiers = params2list(params) if(LAZYACCESS(modifiers, SHIFT_CLICK)) // screen objects don't do the normal Click() stuff so we'll cheat - to_chat(usr, examine_block(jointext(examine(usr), "\n"))) + to_chat(usr, boxed_message(jointext(examine(usr), "\n"))) return FALSE var/datum/our_master = master_ref?.resolve() if(our_master && click_master) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 918f5f62a329b..e17757501cf9e 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -322,8 +322,6 @@ var/obj/item/organ/eyes/eyes = human_mob.get_organ_slot(ORGAN_SLOT_EYES) if(eyes?.no_glasses) blocked_slots |= ITEM_SLOT_EYES - if(human_mob.bodyshape & BODYSHAPE_DIGITIGRADE) - blocked_slots |= ITEM_SLOT_FEET for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(!inv.slot_id) diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index ab95d3bb392eb..041a16b12a132 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -1,6 +1,3 @@ -#define NEXT_PAGE_ID "__next__" -#define DEFAULT_CHECK_DELAY 20 - GLOBAL_LIST_EMPTY(radial_menus) /atom/movable/screen/radial @@ -113,7 +110,7 @@ GLOBAL_LIST_EMPTY(radial_menus) var/hudfix_method = TRUE //TRUE to change anchor to user, FALSE to shift by py_shift var/py_shift = 0 - var/entry_animation = TRUE + var/button_animation_flags = BUTTON_SLIDE_IN ///A replacement icon state for the generic radial slice bg icon. Doesn't affect the next page nor the center buttons var/radial_slice_icon @@ -163,6 +160,8 @@ GLOBAL_LIST_EMPTY(radial_menus) var/atom/movable/screen/radial/slice/new_element = new /atom/movable/screen/radial/slice new_element.tooltips = use_tooltips new_element.set_parent(src) + if(button_animation_flags & BUTTON_FADE_IN) + new_element.alpha = 0 elements += new_element var/page = 1 @@ -186,9 +185,9 @@ GLOBAL_LIST_EMPTY(radial_menus) page_data[page] = current pages = page current_page = clamp(set_page, 1, pages) - update_screen_objects(entry_animation, click_on_hover) + update_screen_objects(button_animation_flags, click_on_hover) -/datum/radial_menu/proc/update_screen_objects(anim = FALSE, click_on_hover = FALSE) +/datum/radial_menu/proc/update_screen_objects(anim_flag = NONE, click_on_hover = FALSE) var/list/page_choices = page_data[current_page] var/angle_per_element = round(zone / page_choices.len) for(var/i in 1 to elements.len) @@ -198,11 +197,11 @@ GLOBAL_LIST_EMPTY(radial_menus) HideElement(element) element.click_on_hover = FALSE else - SetElement(element,page_choices[i],angle,anim = anim,anim_order = i) + SetElement(element,page_choices[i],angle,anim_flag = anim_flag,anim_order = i) // Only activate click on hover after the animation plays if (!click_on_hover) continue - if (anim) + if (anim_flag) addtimer(VARSET_CALLBACK(element, click_on_hover, TRUE), i * 0.5) else element.click_on_hover = TRUE @@ -217,11 +216,11 @@ GLOBAL_LIST_EMPTY(radial_menus) E.choice = null E.next_page = FALSE -/datum/radial_menu/proc/SetElement(atom/movable/screen/radial/slice/E,choice_id,angle,anim,anim_order) +/datum/radial_menu/proc/SetElement(atom/movable/screen/radial/slice/E, choice_id, angle, anim_flag, anim_order) //Position var/py = round(cos(angle) * radius) + py_shift var/px = round(sin(angle) * radius) - if(anim) + if(anim_flag & BUTTON_SLIDE_IN) var/timing = anim_order * 0.5 var/matrix/starting = matrix() starting.Scale(0.1,0.1) @@ -232,8 +231,11 @@ GLOBAL_LIST_EMPTY(radial_menus) E.pixel_y = py E.pixel_x = px - //Visuals - E.alpha = 255 + if(anim_flag & BUTTON_FADE_IN) + animate(E, alpha = 255, time = 0.15 SECONDS, easing = EASE_OUT) + else + E.alpha = 255 + E.mouse_opacity = MOUSE_OPACITY_ICON E.cut_overlays() E.vis_contents.Cut() @@ -266,7 +268,9 @@ GLOBAL_LIST_EMPTY(radial_menus) info_button.layer = RADIAL_CONTENT_LAYER E.vis_contents += info_button -/datum/radial_menu/New() +/datum/radial_menu/New(display_close_button) + if(!display_close_button) + return close_button = new close_button.set_parent(src) @@ -327,7 +331,9 @@ GLOBAL_LIST_EMPTY(radial_menus) menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing", layer = RADIAL_BACKGROUND_LAYER, pixel_x = offset_x, pixel_y = offset_y) SET_PLANE_EXPLICIT(menu_holder, ABOVE_HUD_PLANE, M) menu_holder.appearance_flags |= KEEP_APART|RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM - menu_holder.vis_contents += elements + close_button + menu_holder.vis_contents += elements + if(!isnull(close_button)) + menu_holder.vis_contents += close_button current_user.images += menu_holder /datum/radial_menu/proc/hide() @@ -345,6 +351,14 @@ GLOBAL_LIST_EMPTY(radial_menus) next_check = world.time + check_delay stoplag(1) +/datum/radial_menu/proc/remove_menu() + if(!(button_animation_flags & BUTTON_FADE_OUT)) + qdel(src) + return + for(var/atom/movable/element as anything in elements) + animate(element, alpha = 0, time = 0.15 SECONDS) + QDEL_IN(src, 0.5 SECONDS) + /datum/radial_menu/Destroy() Reset() hide() @@ -356,11 +370,11 @@ GLOBAL_LIST_EMPTY(radial_menus) Choices should be a list where list keys are movables or text used for element names and return value and list values are movables/icons/images used for element icons */ -/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE, no_repeat_close = FALSE, radial_slice_icon = "radial_slice", autopick_single_option = TRUE, entry_animation = TRUE, click_on_hover = FALSE, user_space = FALSE) +/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE, no_repeat_close = FALSE, radial_slice_icon = "radial_slice", autopick_single_option = TRUE, button_animation_flags = BUTTON_SLIDE_IN, click_on_hover = FALSE, user_space = FALSE, check_delay = DEFAULT_CHECK_DELAY, display_close_button = TRUE, radial_menu_offset = list(0, 0)) if(!user || !anchor || !length(choices)) return - if(length(choices)==1 && autopick_single_option) + if(length(choices) == 1 && autopick_single_option) return choices[1] if(!uniqueid) @@ -372,8 +386,9 @@ GLOBAL_LIST_EMPTY(radial_menus) menu.finished = TRUE return - var/datum/radial_menu/menu = new - menu.entry_animation = entry_animation + var/datum/radial_menu/menu = new(display_close_button) + menu.button_animation_flags = button_animation_flags + menu.check_delay = check_delay GLOB.radial_menus[uniqueid] = menu if(radius) menu.radius = radius @@ -390,10 +405,12 @@ GLOBAL_LIST_EMPTY(radial_menus) var/turf/anchor_turf = get_turf(anchor) offset_x = (anchor_turf.x - user_turf.x) * ICON_SIZE_X + anchor.pixel_x - user.pixel_x offset_y = (anchor_turf.y - user_turf.y) * ICON_SIZE_Y + anchor.pixel_y - user.pixel_y + offset_x += radial_menu_offset[1] + offset_y += radial_menu_offset[2] menu.show_to(user, offset_x, offset_y) menu.wait(user, anchor, require_near) var/answer = menu.selected_choice - qdel(menu) + menu.remove_menu() GLOB.radial_menus -= uniqueid if(require_near && !in_range(anchor, user)) return diff --git a/code/_onclick/hud/radial_persistent.dm b/code/_onclick/hud/radial_persistent.dm index 5fe81d005bd43..d48c8d9eb456c 100644 --- a/code/_onclick/hud/radial_persistent.dm +++ b/code/_onclick/hud/radial_persistent.dm @@ -43,7 +43,7 @@ /datum/radial_menu/persistent/proc/change_choices(list/newchoices, tooltips = FALSE, animate = FALSE, keep_same_page = FALSE) if(!newchoices.len) return - entry_animation = FALSE + button_animation_flags = NONE var/target_page = keep_same_page ? current_page : 1 //Stores the current_page value before it's set back to 1 on Reset() Reset() set_choices(newchoices,tooltips, set_page = target_page) diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index 115250104f008..805fe419c94b7 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -674,7 +674,7 @@ Ignore_errors instructes mysql to continue inserting rows if some of them have e /datum/db_query/proc/slow_query_check() - message_admins("HEY! A database query timed out. Did the server just hang? \[YES\]|\[NO\]") + message_admins("HEY! A database query timed out. Did the server just hang? \[YES\]|\[NO\]") /datum/db_query/proc/NextRow(async = TRUE) Activity("NextRow") diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index d22f30f209934..88238f8253b8d 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -203,23 +203,23 @@ SUBSYSTEM_DEF(dynamic) /datum/controller/subsystem/dynamic/proc/admin_panel() var/list/dat = list("Game Mode Panel

Game Mode Panel

") - dat += "Dynamic Mode \[VV\] \[Refresh\]
" + dat += "Dynamic Mode \[VV\] \[Refresh\]
" dat += "Threat Level: [threat_level]
" dat += "Budgets (Roundstart/Midrounds): [initial_round_start_budget]/[threat_level - initial_round_start_budget]
" - dat += "Midround budget to spend: [mid_round_budget] \[Adjust\] \[View Log\]
" + dat += "Midround budget to spend: [mid_round_budget] \[Adjust\] \[View Log\]
" dat += "
" dat += "Parameters: centre = [threat_curve_centre] ; width = [threat_curve_width].
" dat += "Split parameters: centre = [roundstart_split_curve_centre] ; width = [roundstart_split_curve_width].
" dat += "On average, [clamp(peaceful_percentage, 1, 99)]% of the rounds are more peaceful.
" - dat += "Forced extended: [GLOB.dynamic_forced_extended ? "On" : "Off"]
" - dat += "No stacking (only one round-ender): [GLOB.dynamic_no_stacking ? "On" : "Off"]
" - dat += "Stacking limit: [GLOB.dynamic_stacking_limit] \[Adjust\]" + dat += "Forced extended: [GLOB.dynamic_forced_extended ? "On" : "Off"]
" + dat += "No stacking (only one round-ender): [GLOB.dynamic_no_stacking ? "On" : "Off"]
" + dat += "Stacking limit: [GLOB.dynamic_stacking_limit] \[Adjust\]" dat += "
" - dat += "\[Force Next Latejoin Ruleset\]
" + dat += "\[Force Next Latejoin Ruleset\]
" if (forced_latejoin_rule) - dat += {"-> [forced_latejoin_rule.name] <-
"} - dat += "\[Execute Midround Ruleset\]
" + dat += {"-> [forced_latejoin_rule.name] <-
"} + dat += "\[Execute Midround Ruleset\]
" dat += "
" dat += "Executed rulesets: " if (executed_rules.len > 0) @@ -229,13 +229,13 @@ SUBSYSTEM_DEF(dynamic) else dat += "none.
" dat += "
Injection Timers: ([get_heavy_midround_injection_chance(dry_run = TRUE)]% heavy midround chance)
" - dat += "Latejoin: [DisplayTimeText(latejoin_injection_cooldown-world.time)] \[Now!\]
" + dat += "Latejoin: [DisplayTimeText(latejoin_injection_cooldown-world.time)] \[Now!\]
" var/next_injection = next_midround_injection() if (next_injection == INFINITY) dat += "All midrounds have been exhausted." else - dat += "Midround: [DisplayTimeText(next_injection - world.time)] \[Now!\]
" + dat += "Midround: [DisplayTimeText(next_injection - world.time)] \[Now!\]
" usr << browse(dat.Join(), "window=gamemode_panel;size=500x500") diff --git a/code/controllers/subsystem/dynamic/ruleset_picking.dm b/code/controllers/subsystem/dynamic/ruleset_picking.dm index e3de3289899f7..f22ce3315740e 100644 --- a/code/controllers/subsystem/dynamic/ruleset_picking.dm +++ b/code/controllers/subsystem/dynamic/ruleset_picking.dm @@ -69,8 +69,8 @@ log_dynamic("[rule] ruleset executing...") message_admins("DYNAMIC: Executing midround ruleset [rule] in [DisplayTimeText(ADMIN_CANCEL_MIDROUND_TIME)]. \ - CANCEL | \ - SOMETHING ELSE") + CANCEL | \ + SOMETHING ELSE") return rule diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm index 20194e66626ca..2b61cabb86074 100644 --- a/code/controllers/subsystem/explosions.dm +++ b/code/controllers/subsystem/explosions.dm @@ -524,6 +524,7 @@ ADMIN_VERB(check_bomb_impacts, R_DEBUG, "Check Bomb Impact", "See what the effec /datum/controller/subsystem/explosions/proc/shake_the_room(turf/epicenter, near_distance, far_distance, quake_factor, echo_factor, creaking, sound/near_sound = sound(get_sfx(SFX_EXPLOSION)), sound/far_sound = sound('sound/effects/explosion/explosionfar.ogg'), sound/echo_sound = sound('sound/effects/explosion/explosion_distant.ogg'), sound/creaking_sound = sound(get_sfx(SFX_EXPLOSION_CREAKING)), hull_creaking_sound = sound(get_sfx(SFX_HULL_CREAKING))) var/frequency = get_rand_frequency() var/blast_z = epicenter.z + var/area/epicenter_area = get_area(epicenter) if(isnull(creaking)) // Autoset creaking. var/on_station = SSmapping.level_trait(epicenter.z, ZTRAIT_STATION) if(on_station && prob((quake_factor * QUAKE_CREAK_PROB) + (echo_factor * ECHO_CREAK_PROB))) // Huge explosions are near guaranteed to make the station creak and whine, smaller ones might. @@ -559,7 +560,7 @@ ADMIN_VERB(check_bomb_impacts, R_DEBUG, "Check Bomb Impact", "See what the effec base_shake_amount = max(base_shake_amount, quake_factor * 3, 0) // Devastating explosions rock the station and ground shake_camera(listener, FAR_SHAKE_DURATION, min(base_shake_amount, FAR_SHAKE_CAP)) - else if(!isspaceturf(listener_turf) && echo_factor) // Big enough explosions echo through the hull. + else if(!isspaceturf(listener_turf) && !(!(epicenter_area.type in GLOB.the_station_areas) && SSmapping.is_planetary()) && echo_factor) // Big enough explosions echo through the hull. Except on planetary maps if the epicenter is not on the station's area. var/echo_volume if(quake_factor) echo_volume = 60 diff --git a/code/controllers/subsystem/lag_switch.dm b/code/controllers/subsystem/lag_switch.dm index c79db05186017..291e80fe18f1f 100644 --- a/code/controllers/subsystem/lag_switch.dm +++ b/code/controllers/subsystem/lag_switch.dm @@ -34,7 +34,7 @@ SUBSYSTEM_DEF(lag_switch) auto_switch = FALSE UnregisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT) veto_timer_id = addtimer(CALLBACK(src, PROC_REF(set_all_measures), TRUE, TRUE), 20 SECONDS, TIMER_STOPPABLE) - message_admins("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds. (CANCEL)") + message_admins("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds. (CANCEL)") log_admin("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds.") /// (En/Dis)able automatic triggering of switches based on client count diff --git a/code/controllers/subsystem/map_vote.dm b/code/controllers/subsystem/map_vote.dm index ced1e65e3a215..f57d73d773e63 100644 --- a/code/controllers/subsystem/map_vote.dm +++ b/code/controllers/subsystem/map_vote.dm @@ -53,7 +53,7 @@ SUBSYSTEM_DEF(map_vote) last_message_at = world.time var/list/messages = args.Copy() - to_chat(world, span_purple(examine_block("Map Vote\n
[messages.Join("\n")]"))) + to_chat(world, span_purple(boxed_message("Map Vote\n
[messages.Join("\n")]"))) /datum/controller/subsystem/map_vote/proc/finalize_map_vote(datum/vote/map_vote/map_vote) if(already_voted) @@ -170,4 +170,4 @@ SUBSYSTEM_DEF(map_vote) for(var/map_id in map_vote_cache) var/datum/map_config/map = config.maplist[map_id] data += "[map.map_name] - [map_vote_cache[map_id]]" - tally_printout = examine_block("Current Tallies\n
[data.Join("\n")]") + tally_printout = boxed_message("Current Tallies\n
[data.Join("\n")]") diff --git a/code/controllers/subsystem/polling.dm b/code/controllers/subsystem/polling.dm index c9c7d3ea31167..6624c984cbb6a 100644 --- a/code/controllers/subsystem/polling.dm +++ b/code/controllers/subsystem/polling.dm @@ -148,11 +148,11 @@ SUBSYSTEM_DEF(polling) var/custom_link_style_start = "" var/custom_link_style_end = "style='color:DodgerBlue;font-weight:bold;-dm-text-outline: 1px black'" if(isatom(alert_pic) && isobserver(candidate_mob)) - act_jump = "[custom_link_style_start]\[Teleport\]" - var/act_signup = "[custom_link_style_start]\[[start_signed_up ? "Opt out" : "Sign Up"]\]" + act_jump = "[custom_link_style_start]\[Teleport\]" + var/act_signup = "[custom_link_style_start]\[[start_signed_up ? "Opt out" : "Sign Up"]\]" var/act_never = "" if(ignore_category) - act_never = "[custom_link_style_start]\[Never For This Round\]" + act_never = "[custom_link_style_start]\[Never For This Round\]" if(!duplicate_message_check(alert_poll)) //Only notify people once. They'll notice if there are multiple and we don't want to spam people. SEND_SOUND(candidate_mob, 'sound/announcer/notice/notice2.ogg') @@ -165,7 +165,7 @@ SUBSYSTEM_DEF(polling) else surrounding_image = image(chat_text_border_icon) surrounding_icon = icon2html(surrounding_image, candidate_mob, extra_classes = "bigicon") - var/final_message = examine_block("[surrounding_icon] [span_ooc(question)] [surrounding_icon]\n[act_jump] [act_signup] [act_never]") + var/final_message = boxed_message("[surrounding_icon] [span_ooc(question)] [surrounding_icon]\n[act_jump] [act_signup] [act_never]") to_chat(candidate_mob, final_message) // Start processing it so it updates visually the timer diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 4f573ee2f2224..ff19d6d4b265a 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -385,7 +385,7 @@ SUBSYSTEM_DEF(shuttle) SSblackbox.record_feedback("text", "shuttle_reason", 1, "[call_reason]") log_shuttle("Shuttle call reason: [call_reason]") SSticker.emergency_reason = call_reason - message_admins("[ADMIN_LOOKUPFLW(user)] has called the shuttle. (TRIGGER CENTCOM RECALL)") + message_admins("[ADMIN_LOOKUPFLW(user)] has called the shuttle. (TRIGGER CENTCOM RECALL)") /// Call the emergency shuttle. /// If you are doing this on behalf of a player, use requestEvac instead. diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 5be680744f676..066436d0ec698 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -39,6 +39,15 @@ SUBSYSTEM_DEF(statpanels) var/ETA = SSshuttle.emergency.getModeStr() if(ETA) global_data += "[ETA] [SSshuttle.emergency.getTimerStr()]" + + if(SSticker.reboot_timer) + var/reboot_time = timeleft(SSticker.reboot_timer) + if(reboot_time) + global_data += "Reboot: [DisplayTimeText(reboot_time, 1)]" + // admin must have delayed round end + else if(SSticker.ready_for_reboot) + global_data += "Reboot: DELAYED" + src.currentrun = GLOB.clients.Copy() mc_data = null @@ -94,11 +103,14 @@ SUBSYSTEM_DEF(statpanels) return /datum/controller/subsystem/statpanels/proc/set_status_tab(client/target) +#if MIN_COMPILER_VERSION > 515 + #warn 516 is most certainly out of beta, remove this beta notice if you haven't already +#endif + var/static/list/beta_notice = list("", "You are on the BYOND 516 beta, various UIs and such may be broken!", "Please report issues, and switch back to BYOND 515 if things are causing too many issues for you.") 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, + "global_data" = (target.byond_version < 516) ? global_data : (global_data + beta_notice), "ping_str" = "Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)", "other_str" = target.mob?.get_status_tab_items(), )) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index bb18a45b72d9a..96cde0ef0dded 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -67,6 +67,9 @@ SUBSYSTEM_DEF(ticker) /// Why an emergency shuttle was called var/emergency_reason + /// ID of round reboot timer, if it exists + var/reboot_timer = null + /datum/controller/subsystem/ticker/Initialize() var/list/byond_sound_formats = list( "mid" = TRUE, @@ -487,7 +490,7 @@ SUBSYSTEM_DEF(ticker) if(!hard_popcap) list_clear_nulls(queued_players) for (var/mob/dead/new_player/new_player in queued_players) - to_chat(new_player, span_userdanger("The alive players limit has been released!
[html_encode(">>Join Game<<")]")) + to_chat(new_player, span_userdanger("The alive players limit has been released!
[html_encode(">>Join Game<<")]")) SEND_SOUND(new_player, sound('sound/announcer/notice/notice1.ogg')) GLOB.latejoin_menu.ui_interact(new_player) queued_players.len = 0 @@ -502,7 +505,7 @@ SUBSYSTEM_DEF(ticker) list_clear_nulls(queued_players) if(living_player_count() < hard_popcap) if(next_in_line?.client) - to_chat(next_in_line, span_userdanger("A slot has opened! You have approximately 20 seconds to join. \>\>Join Game\<\<")) + to_chat(next_in_line, span_userdanger("A slot has opened! You have approximately 20 seconds to join. \>\>Join Game\<\<")) SEND_SOUND(next_in_line, sound('sound/announcer/notice/notice1.ogg')) next_in_line.ui_interact(next_in_line) return @@ -698,11 +701,10 @@ SUBSYSTEM_DEF(ticker) var/start_wait = world.time UNTIL(round_end_sound_sent || (world.time - start_wait) > (delay * 2)) //don't wait forever - sleep(delay - (world.time - start_wait)) + reboot_timer = addtimer(CALLBACK(src, PROC_REF(reboot_callback), reason, end_string), delay - (world.time - start_wait), TIMER_STOPPABLE) - if(delay_end && !skip_delay) - to_chat(world, span_boldannounce("Reboot was cancelled by an admin.")) - return + +/datum/controller/subsystem/ticker/proc/reboot_callback(reason, end_string) if(end_string) end_state = end_string @@ -710,6 +712,21 @@ SUBSYSTEM_DEF(ticker) world.Reboot() +/** + * Deletes the current reboot timer and nulls the var + * + * Arguments: + * * user - the user that cancelled the reboot, may be null + */ +/datum/controller/subsystem/ticker/proc/cancel_reboot(mob/user) + if(!reboot_timer) + to_chat(user, span_warning("There is no pending reboot!")) + return FALSE + to_chat(world, span_boldannounce("An admin has delayed the round end.")) + deltimer(reboot_timer) + reboot_timer = null + return TRUE + /datum/controller/subsystem/ticker/Shutdown() gather_newscaster() //called here so we ensure the log is created even upon admin reboot if(!round_end_sound) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index d0e642bd3aa2d..d9d796782c2b2 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -119,7 +119,7 @@ SUBSYSTEM_DEF(vote) ) log_vote("vote finalized", vote_log_data) if(to_display) - to_chat(world, span_infoplain(vote_font("\n[to_display]"))) + to_chat(world, span_infoplain(vote_font("[to_display]"))) // Finally, doing any effects on vote completion current_vote.finalize_vote(final_winner) @@ -230,9 +230,9 @@ SUBSYSTEM_DEF(vote) var/to_display = current_vote.initiate_vote(vote_initiator_name, duration) log_vote(to_display) - to_chat(world, span_infoplain(vote_font("\n[span_bold(to_display)]\n\ + to_chat(world, custom_boxed_message("purple_box center", span_infoplain(vote_font("[span_bold(to_display)]
\ Type vote or click here to place your votes.\n\ - You have [DisplayTimeText(duration)] to vote."))) + You have [DisplayTimeText(duration)] to vote.")))) // And now that it's going, give everyone a voter action for(var/client/new_voter as anything in GLOB.clients) diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm index 2f297f480ae66..18525a8c04e94 100644 --- a/code/datums/actions/action.dm +++ b/code/datums/actions/action.dm @@ -435,5 +435,5 @@ if(source.next_click > world.time) return else - source.next_click = world.time + CLICK_CD_RANGE + source.next_click = world.time + CLICK_CD_ACTIVATE_ABILITY INVOKE_ASYNC(src, PROC_REF(Trigger)) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/express_happiness.dm b/code/datums/ai/basic_mobs/basic_subtrees/express_happiness.dm index 6cae6132d3688..4d7a3e7ad3064 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/express_happiness.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/express_happiness.dm @@ -31,11 +31,11 @@ var/list/final_list switch(happiness_value) if(HIGH_HAPPINESS_THRESHOLD to INFINITY) - final_list = happy_emotions + final_list = controller.blackboard[BB_HAPPY_EMOTIONS] || happy_emotions if(MODERATE_HAPPINESS_THRESHOLD to HIGH_HAPPINESS_THRESHOLD) - final_list = moderate_emotions + final_list = controller.blackboard[BB_MODERATE_EMOTIONS] || moderate_emotions else - final_list = depressed_emotions + final_list = controller.blackboard[BB_SAD_EMOTIONS] || depressed_emotions if(!length(final_list)) return controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(final_list)) diff --git a/code/datums/ai_laws/ai_laws.dm b/code/datums/ai_laws/ai_laws.dm index a0d1d629fc8d3..a25f7e694a9ad 100644 --- a/code/datums/ai_laws/ai_laws.dm +++ b/code/datums/ai_laws/ai_laws.dm @@ -442,7 +442,7 @@ GLOBAL_VAR(round_default_lawset) /datum/ai_laws/proc/show_laws(mob/to_who) var/list/printable_laws = get_law_list(include_zeroth = TRUE) - to_chat(to_who, examine_block(jointext(printable_laws, "\n"))) + to_chat(to_who, boxed_message(jointext(printable_laws, "\n"))) /datum/ai_laws/proc/associate(mob/living/silicon/M) if(owner) diff --git a/code/datums/browser.dm b/code/datums/browser.dm index b9d859552389d..cf0df8dac5017 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -138,13 +138,13 @@ var/output = {"
[Message]

- [Button1]"} + [Button1]"} if (Button2) - output += {"[Button2]"} + output += {"[Button2]"} if (Button3) - output += {"[Button3]"} + output += {"[Button3]"} output += {"
"} @@ -356,11 +356,11 @@ var/setting = settings["mainsettings"][name] if (setting["type"] == "datum") if (setting["subtypesonly"]) - dat += "[setting["desc"]]: [setting["value"]]
" + dat += "[setting["desc"]]: [setting["value"]]
" else - dat += "[setting["desc"]]: [setting["value"]]
" + dat += "[setting["desc"]]: [setting["value"]]
" else - dat += "[setting["desc"]]: [setting["value"]]
" + dat += "[setting["desc"]]: [setting["value"]]
" if (preview_icon) dat += "" @@ -371,7 +371,7 @@ dat += "" - dat += "
Ok " + dat += "
Ok " dat += "
" diff --git a/code/datums/components/aquarium.dm b/code/datums/components/aquarium.dm index f207ecd9f5510..69939cb67b92e 100644 --- a/code/datums/components/aquarium.dm +++ b/code/datums/components/aquarium.dm @@ -100,11 +100,12 @@ ADD_KEEP_TOGETHER(movable, AQUARIUM_TRAIT) //render the fish on the same layer of the aquarium. if(reagents_size > 0) - RegisterSignal(movable.reagents, COMSIG_REAGENTS_NEW_REAGENT, PROC_REF(start_autofeed)) if(!movable.reagents) movable.create_reagents(reagents_size, SEALED_CONTAINER) - else if(movable.reagents.total_volume) + if(movable.reagents.total_volume) start_autofeed(movable.reagents) + else + RegisterSignal(movable.reagents, COMSIG_REAGENTS_NEW_REAGENT, PROC_REF(start_autofeed)) RegisterSignal(movable, COMSIG_PLUNGER_ACT, PROC_REF(on_plunger_act)) RegisterSignal(movable, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(on_item_interaction)) @@ -240,10 +241,10 @@ return ITEM_INTERACT_SUCCESS ///Called when the feed storage is no longer empty. -/datum/component/aquarium/proc/start_autofeed(atom/movable/source, new_reagent, amount, reagtemp, data, no_react) +/datum/component/aquarium/proc/start_autofeed(datum/reagents/source, new_reagent, amount, reagtemp, data, no_react) SIGNAL_HANDLER START_PROCESSING(SSobj, src) - UnregisterSignal(source.reagents, COMSIG_REAGENTS_NEW_REAGENT) + UnregisterSignal(source, COMSIG_REAGENTS_NEW_REAGENT) ///Feed the fish at defined intervals until the feed storage is empty. /datum/component/aquarium/process(seconds_per_tick) diff --git a/code/datums/components/callouts.dm b/code/datums/components/callouts.dm index 52a3e007905c3..854f769f8a10a 100644 --- a/code/datums/components/callouts.dm +++ b/code/datums/components/callouts.dm @@ -111,7 +111,7 @@ for(var/datum/callout_option/callout_option as anything in callout_options) callout_items[callout_option] = image(icon = 'icons/hud/radial.dmi', icon_state = callout_option::icon_state) - var/datum/callout_option/selection = show_radial_menu(user, get_turf(clicked_atom), callout_items, entry_animation = FALSE, click_on_hover = TRUE, user_space = TRUE) + var/datum/callout_option/selection = show_radial_menu(user, get_turf(clicked_atom), callout_items, button_animation_flags = NONE, click_on_hover = TRUE, user_space = TRUE) if (!selection) return diff --git a/code/datums/components/jetpack.dm b/code/datums/components/jetpack.dm index c7ff096029b97..5498a8a81ef85 100644 --- a/code/datums/components/jetpack.dm +++ b/code/datums/components/jetpack.dm @@ -119,7 +119,7 @@ /datum/component/jetpack/proc/deactivate(datum/source, mob/old_user) SIGNAL_HANDLER - UnregisterSignal(old_user, list(COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_CLIENT_MOVE_NOGRAV, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE)) + UnregisterSignal(old_user, list(COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_CLIENT_MOVE_NOGRAV, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE, COMSIG_MOVABLE_DRIFT_BLOCK_INPUT)) STOP_PROCESSING(SSnewtonian_movement, src) user = null @@ -159,7 +159,7 @@ last_stabilization_tick = world.time - if (!should_trigger(user) || !stabilize || isnull(user.drift_handler)) + if (!should_trigger(user) || !stabilize || !check_on_move.Invoke(FALSE) || isnull(user.drift_handler)) return var/max_drift_force = MOVE_DELAY_TO_DRIFT(user.cached_multiplicative_slowdown) diff --git a/code/datums/components/pet_commands/fetch.dm b/code/datums/components/pet_commands/fetch.dm index 9a42c485d5c06..143ac9ca1014c 100644 --- a/code/datums/components/pet_commands/fetch.dm +++ b/code/datums/components/pet_commands/fetch.dm @@ -3,11 +3,11 @@ * Watch for someone throwing or pointing at something and then go get it and bring it back. * If it's food we might eat it instead. */ -/datum/pet_command/point_targeting/fetch +/datum/pet_command/fetch command_name = "Fetch" command_desc = "Command your pet to retrieve something you throw or point at." - radial_icon = 'icons/mob/actions/actions_spells.dmi' - radial_icon_state = "summons" + radial_icon_state = "fetch" + requires_pointing = TRUE speech_commands = list("fetch") command_feedback = "bounces" pointed_reaction = "with great interest" @@ -16,22 +16,25 @@ /// If true, this is a poorly trained pet who will eat food you throw instead of bringing it back var/will_eat_targets = TRUE -/datum/pet_command/point_targeting/fetch/New(mob/living/parent) +/datum/pet_command/fetch/New(mob/living/parent) . = ..() if(isnull(parent)) return parent.AddElement(/datum/element/ai_held_item) // We don't remove this on destroy because they might still be holding something -/datum/pet_command/point_targeting/fetch/add_new_friend(mob/living/tamer) +/datum/pet_command/fetch/add_new_friend(mob/living/tamer) . = ..() RegisterSignal(tamer, COMSIG_MOB_THROW, PROC_REF(listened_throw)) -/datum/pet_command/point_targeting/fetch/remove_friend(mob/living/unfriended) +/datum/pet_command/fetch/remove_friend(mob/living/unfriended) . = ..() UnregisterSignal(unfriended, COMSIG_MOB_THROW) +/datum/pet_command/fetch/retrieve_command_text(atom/living_pet, atom/target) + return isnull(target) ? null : "signals [living_pet] to fetch [target]!" + /// A friend has thrown something, if we're listening or at least not busy then go get it -/datum/pet_command/point_targeting/fetch/proc/listened_throw(mob/living/carbon/thrower) +/datum/pet_command/fetch/proc/listened_throw(mob/living/carbon/thrower) SIGNAL_HANDLER var/mob/living/parent = weak_parent.resolve() @@ -57,7 +60,7 @@ RegisterSignal(thrown_thing, COMSIG_MOVABLE_THROW_LANDED, PROC_REF(listen_throw_land)) /// A throw we were listening to has finished, see if it's in range for us to try grabbing it -/datum/pet_command/point_targeting/fetch/proc/listen_throw_land(obj/item/thrown_thing, datum/thrownthing/throwingdatum) +/datum/pet_command/fetch/proc/listen_throw_land(obj/item/thrown_thing, datum/thrownthing/throwingdatum) SIGNAL_HANDLER UnregisterSignal(thrown_thing, COMSIG_MOVABLE_THROW_LANDED) @@ -76,7 +79,7 @@ parent.ai_controller.set_blackboard_key(BB_FETCH_DELIVER_TO, thrower) // Don't try and fetch turfs or anchored objects if someone points at them -/datum/pet_command/point_targeting/fetch/look_for_target(mob/living/pointing_friend, obj/item/pointed_atom) +/datum/pet_command/fetch/look_for_target(mob/living/pointing_friend, obj/item/pointed_atom) if (!istype(pointed_atom)) return FALSE if (pointed_atom.anchored) @@ -89,7 +92,7 @@ parent.ai_controller.set_blackboard_key(BB_FETCH_DELIVER_TO, pointing_friend) // Finally, plan our actions -/datum/pet_command/point_targeting/fetch/execute_action(datum/ai_controller/controller) +/datum/pet_command/fetch/execute_action(datum/ai_controller/controller) controller.queue_behavior(/datum/ai_behavior/forget_failed_fetches) var/atom/target = controller.blackboard[BB_CURRENT_PET_TARGET] diff --git a/code/datums/components/pet_commands/obeys_commands.dm b/code/datums/components/pet_commands/obeys_commands.dm index 8aaa7e7179294..4a68574d6e08c 100644 --- a/code/datums/components/pet_commands/obeys_commands.dm +++ b/code/datums/components/pet_commands/obeys_commands.dm @@ -3,12 +3,23 @@ * Manages a list of pet command datums, allowing you to boss it around * Creates a radial menu of pet commands when this creature is alt-clicked, if it has any */ +#define DEFAULT_RADIAL_VIEWING_DISTANCE 9 /datum/component/obeys_commands /// List of commands you can give to the owner of this component var/list/available_commands = list() + ///Users currently viewing our radial options + var/list/radial_viewers = list() + ///radius of our radial menu + var/radial_menu_radius = 48 + ///after how long we shutdown radial menus + var/radial_menu_lifetime = 7 SECONDS + ///offset to display the radial menu + var/list/radial_menu_offset + ///should the commands move with the pet owner's screen? + var/radial_relative_to_user /// The available_commands parameter should be passed as a list of typepaths -/datum/component/obeys_commands/Initialize(list/command_typepaths = list()) +/datum/component/obeys_commands/Initialize(list/command_typepaths = list(), list/radial_menu_offset = list(0, 0), radial_relative_to_user = FALSE) . = ..() if (!isliving(parent)) return COMPONENT_INCOMPATIBLE @@ -17,7 +28,8 @@ return COMPONENT_INCOMPATIBLE if (!length(command_typepaths)) CRASH("Initialised obedience component with no commands.") - + src.radial_menu_offset = radial_menu_offset + src.radial_relative_to_user = radial_relative_to_user for (var/command_path in command_typepaths) var/datum/pet_command/new_command = new command_path(parent) available_commands[new_command.command_name] = new_command @@ -30,7 +42,6 @@ RegisterSignal(parent, COMSIG_LIVING_BEFRIENDED, PROC_REF(add_friend)) RegisterSignal(parent, COMSIG_LIVING_UNFRIENDED, PROC_REF(remove_friend)) RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(display_menu)) /datum/component/obeys_commands/UnregisterFromParent() UnregisterSignal(parent, list(COMSIG_LIVING_BEFRIENDED, COMSIG_LIVING_UNFRIENDED, COMSIG_ATOM_EXAMINE, COMSIG_CLICK_ALT)) @@ -38,15 +49,26 @@ /// Add someone to our friends list /datum/component/obeys_commands/proc/add_friend(datum/source, mob/living/new_friend) SIGNAL_HANDLER - + RegisterSignal(new_friend, COMSIG_KB_LIVING_VIEW_PET_COMMANDS, PROC_REF(on_key_pressed)) + RegisterSignal(new_friend, DEACTIVATE_KEYBIND(COMSIG_KB_LIVING_VIEW_PET_COMMANDS), PROC_REF(on_key_unpressed)) for (var/command_name as anything in available_commands) var/datum/pet_command/command = available_commands[command_name] INVOKE_ASYNC(command, TYPE_PROC_REF(/datum/pet_command, add_new_friend), new_friend) +/datum/component/obeys_commands/proc/on_key_unpressed(mob/living/source) + SIGNAL_HANDLER + UnregisterSignal(source, COMSIG_ATOM_MOUSE_ENTERED) + +/datum/component/obeys_commands/proc/remove_from_viewers(mob/living/source) + radial_viewers -= REF(source) + /// Remove someone from our friends list /datum/component/obeys_commands/proc/remove_friend(datum/source, mob/living/old_friend) SIGNAL_HANDLER - + UnregisterSignal(old_friend, list( + COMSIG_KB_LIVING_VIEW_PET_COMMANDS, + DEACTIVATE_KEYBIND(COMSIG_KB_LIVING_VIEW_PET_COMMANDS), + )) for (var/command_name as anything in available_commands) var/datum/pet_command/command = available_commands[command_name] INVOKE_ASYNC(command, TYPE_PROC_REF(/datum/pet_command, remove_friend), old_friend) @@ -61,21 +83,34 @@ return examine_list += span_notice("[source.p_They()] seem[source.p_s()] happy to see you!") -/// Displays a radial menu of commands -/datum/component/obeys_commands/proc/display_menu(datum/source, mob/living/clicker) +/datum/component/obeys_commands/proc/on_key_pressed(mob/living/friend) + SIGNAL_HANDLER + RegisterSignal(friend, COMSIG_ATOM_MOUSE_ENTERED, PROC_REF(on_mouse_hover)) + +/datum/component/obeys_commands/proc/on_mouse_hover(mob/living/friend, atom/mouse_hovered) SIGNAL_HANDLER + if(mouse_hovered == parent) + display_menu(friend) + return + if(isliving(mouse_hovered)) + remove_from_viewers(friend) + +/// Displays a radial menu of commands +/datum/component/obeys_commands/proc/display_menu(mob/living/friend) var/mob/living/living_parent = parent - if (IS_DEAD_OR_INCAP(living_parent) || !clicker.can_perform_action(living_parent)) + if (IS_DEAD_OR_INCAP(living_parent) || friend.stat != CONSCIOUS) return - if (!(clicker in living_parent.ai_controller?.blackboard[BB_FRIENDS_LIST])) + if (!(friend in living_parent.ai_controller?.blackboard[BB_FRIENDS_LIST])) return // Not our friend, can't boss us around - - INVOKE_ASYNC(src, PROC_REF(display_radial_menu), clicker) - return CLICK_ACTION_SUCCESS + if(radial_viewers[REF(friend)]) + return + if(!can_see(friend, parent, DEFAULT_RADIAL_VIEWING_DISTANCE)) + return + INVOKE_ASYNC(src, PROC_REF(display_radial_menu), friend) /// Actually display the radial menu and then do something with the result -/datum/component/obeys_commands/proc/display_radial_menu(mob/living/clicker) +/datum/component/obeys_commands/proc/display_radial_menu(mob/living/friend) var/list/radial_options = list() for (var/command_name as anything in available_commands) var/datum/pet_command/command = available_commands[command_name] @@ -83,9 +118,22 @@ if (!choice) continue radial_options += choice - - var/pick = show_radial_menu(clicker, clicker, radial_options, tooltips = TRUE) - if (!pick) + radial_viewers[REF(friend)] = world.time + radial_menu_lifetime + var/pick = show_radial_menu(friend, parent, radial_options, radius = radial_menu_radius, button_animation_flags = BUTTON_FADE_IN | BUTTON_FADE_OUT, custom_check = CALLBACK(src, PROC_REF(check_menu_viewer), friend), check_delay = 0.15 SECONDS, display_close_button = FALSE, radial_menu_offset = radial_menu_offset, user_space = radial_relative_to_user) + remove_from_viewers(friend) + if(!pick) return var/datum/pet_command/picked_command = available_commands[pick] - picked_command.try_activate_command(clicker) + picked_command.try_activate_command(friend, radial_command = TRUE) + +/datum/component/obeys_commands/proc/check_menu_viewer(mob/living/user) + if(QDELETED(user) || !radial_viewers[REF(user)]) + return FALSE + if(world.time > radial_viewers[REF(user)]) + return FALSE + var/viewing_distance = DEFAULT_RADIAL_VIEWING_DISTANCE + if(!can_see(user, parent, viewing_distance)) + return FALSE + return TRUE + +#undef DEFAULT_RADIAL_VIEWING_DISTANCE diff --git a/code/datums/components/pet_commands/pet_command.dm b/code/datums/components/pet_commands/pet_command.dm index 52b4cc8834920..fab3de70b79f1 100644 --- a/code/datums/components/pet_commands/pet_command.dm +++ b/code/datums/components/pet_commands/pet_command.dm @@ -13,7 +13,7 @@ /// If true, command will not appear in radial menu and can only be accessed through speech var/hidden = FALSE /// Icon to display in radial menu - var/icon/radial_icon + var/icon/radial_icon = 'icons/hud/radial_pets.dmi' /// Icon state to display in radial menu var/radial_icon_state /// Speech strings to listen out for @@ -24,6 +24,12 @@ var/command_feedback /// How close a mob needs to be to a target to respond to a command var/sense_radius = 7 + /// does this pet command need a point to activate? + var/requires_pointing = FALSE + /// Blackboard key for targeting strategy, this is likely going to need it + var/targeting_strategy_key = BB_PET_TARGETING_STRATEGY + ///our pointed reaction we play + var/pointed_reaction /datum/pet_command/New(mob/living/parent) . = ..() @@ -34,10 +40,17 @@ RegisterSignal(tamer, COMSIG_MOB_SAY, PROC_REF(respond_to_command)) RegisterSignal(tamer, COMSIG_MOB_AUTOMUTE_CHECK, PROC_REF(waive_automute)) RegisterSignal(tamer, COMSIG_MOB_CREATED_CALLOUT, PROC_REF(respond_to_callout)) + if(requires_pointing) + RegisterSignal(tamer, COMSIG_MOVABLE_POINTED, PROC_REF(point_on_target)) /// Stop listening to a guy /datum/pet_command/proc/remove_friend(mob/living/unfriended) - UnregisterSignal(unfriended, list(COMSIG_MOB_SAY, COMSIG_MOB_AUTOMUTE_CHECK, COMSIG_MOB_CREATED_CALLOUT)) + UnregisterSignal(unfriended, list( + COMSIG_MOB_SAY, + COMSIG_MOB_AUTOMUTE_CHECK, + COMSIG_MOB_CREATED_CALLOUT, + COMSIG_MOVABLE_POINTED, + )) /// Stop the automute from triggering for commands (unless the spoken text is suspiciously longer than the command) /datum/pet_command/proc/waive_automute(mob/living/speaker, client/client, last_message, mute_type) @@ -49,7 +62,6 @@ /// Respond to something that one of our friends has asked us to do /datum/pet_command/proc/respond_to_command(mob/living/speaker, speech_args) SIGNAL_HANDLER - var/mob/living/parent = weak_parent.resolve() if (!parent) return @@ -60,7 +72,7 @@ if (!find_command_in_text(spoken_text)) return - try_activate_command(speaker) + try_activate_command(commander = speaker, radial_command = FALSE) /// Respond to a callout /datum/pet_command/proc/respond_to_callout(mob/living/caller, datum/callout_option/callout, atom/target) @@ -83,7 +95,7 @@ if (!found_new_target) return - if (try_activate_command(caller)) + if (try_activate_command(commander = caller, radial_command = FALSE)) look_for_target(parent, target) /// Does this callout with this target trigger this command? @@ -103,48 +115,77 @@ return TRUE return FALSE -/// Apply a command state if conditions are right, return command if successful -/datum/pet_command/proc/try_activate_command(mob/living/commander) +/datum/pet_command/proc/pet_able_to_respond() var/mob/living/parent = weak_parent.resolve() - if (!parent) + if(isnull(parent) || isnull(parent.ai_controller)) return FALSE - if (!parent.ai_controller) // We stopped having a brain at some point + if(IS_DEAD_OR_INCAP(parent)) // Probably can't hear them if we're dead return FALSE - if (IS_DEAD_OR_INCAP(parent)) // Probably can't hear them if we're dead - return FALSE - if (parent.ai_controller.blackboard[BB_ACTIVE_PET_COMMAND] == src) // We're already doing it + return TRUE + +/// Apply a command state if conditions are right, return command if successful +/datum/pet_command/proc/try_activate_command(mob/living/commander, radial_command) + if(!pet_able_to_respond()) return FALSE - set_command_active(parent, commander) + var/mob/living/parent = weak_parent.resolve() + set_command_active(parent, commander, radial_command) return TRUE +/datum/pet_command/proc/generate_emote_command(atom/target) + var/mob/living/living_pet = weak_parent?.resolve() + return isnull(living_pet) ? null : retrieve_command_text(living_pet, target) + +/datum/pet_command/proc/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to spring into action!" + /// Target the pointed atom for actions -/datum/pet_command/proc/look_for_target(mob/living/friend, atom/pointed_atom) +/datum/pet_command/proc/look_for_target(mob/living/friend, atom/potential_target) var/mob/living/parent = weak_parent.resolve() - if (!parent) - return FALSE - if (!parent.ai_controller) - return FALSE - if (IS_DEAD_OR_INCAP(parent)) + if(!pet_able_to_respond()) return FALSE - if (parent.ai_controller.blackboard[BB_ACTIVE_PET_COMMAND] != src) // We're not listening right now + if (parent.ai_controller.blackboard[BB_CURRENT_PET_TARGET] == potential_target) // That's already our target return FALSE - if (parent.ai_controller.blackboard[BB_CURRENT_PET_TARGET] == pointed_atom) // That's already our target - return FALSE - if (!can_see(parent, pointed_atom, sense_radius)) + if (!can_see(parent, potential_target, sense_radius)) return FALSE parent.ai_controller.CancelActions() - set_command_target(parent, pointed_atom) + set_command_target(parent, potential_target) return TRUE /// Activate the command, extend to add visible messages and the like -/datum/pet_command/proc/set_command_active(mob/living/parent, mob/living/commander) - set_command_target(parent, null) +/datum/pet_command/proc/set_command_active(mob/living/parent, mob/living/commander, radial_command = FALSE) + parent.ai_controller.clear_blackboard_key(BB_CURRENT_PET_TARGET) parent.ai_controller.CancelActions() // Stop whatever you're doing and do this instead parent.ai_controller.set_blackboard_key(BB_ACTIVE_PET_COMMAND, src) if (command_feedback) parent.balloon_alert_to_viewers("[command_feedback]") // If we get a nicer runechat way to do this, refactor this + if(!radial_command) + return + if(!requires_pointing) + var/manual_emote_text = generate_emote_command() + commander.manual_emote(manual_emote_text) + return + RegisterSignal(commander, COMSIG_MOB_CLICKON, PROC_REF(click_on_target)) + commander.client?.mouse_override_icon = 'icons/effects/mouse_pointers/pet_paw.dmi' + commander.update_mouse_pointer() + +/datum/pet_command/proc/click_on_target(mob/living/source, atom/target, list/modifiers) + SIGNAL_HANDLER + if(!can_see(source, target, 9)) + return COMSIG_MOB_CANCEL_CLICKON + on_target_set(source, target) + UnregisterSignal(source, COMSIG_MOB_CLICKON) + source.client?.mouse_override_icon = source.client::mouse_override_icon + source.update_mouse_pointer() + var/manual_emote_text = generate_emote_command(target) + if(!isnull(manual_emote_text)) + INVOKE_ASYNC(source, TYPE_PROC_REF(/atom, manual_emote), manual_emote_text) + return COMSIG_MOB_CANCEL_CLICKON + +/datum/pet_command/proc/point_on_target(mob/living/friend, atom/potential_target) + SIGNAL_HANDLER + on_target_set(friend, potential_target) /// Store the target for the AI blackboard /datum/pet_command/proc/set_command_target(mob/living/parent, atom/target) @@ -158,11 +199,6 @@ var/datum/radial_menu_choice/choice = new() choice.name = command_name choice.image = icon(icon = radial_icon, icon_state = radial_icon_state) - var/tooltip = command_desc - if (length(speech_commands)) - tooltip += "
Speak this command with the words [speech_commands.Join(", ")]." - choice.info = tooltip - return list("[command_name]" = choice) /** @@ -174,34 +210,15 @@ SHOULD_CALL_PARENT(FALSE) CRASH("Pet command execute action not implemented.") -/** - * # Point Targeting Pet Command - * As above but also listens for you pointing at something and marks it as a target - */ -/datum/pet_command/point_targeting - /// Text describing an action we perform upon receiving a new target - var/pointed_reaction - /// Blackboard key for targeting strategy, this is likely going to need it - var/targeting_strategy_key = BB_PET_TARGETING_STRATEGY - -/datum/pet_command/point_targeting/add_new_friend(mob/living/tamer) - . = ..() - RegisterSignal(tamer, COMSIG_MOVABLE_POINTED, PROC_REF(on_point)) - -/datum/pet_command/point_targeting/remove_friend(mob/living/unfriended) - . = ..() - UnregisterSignal(unfriended, COMSIG_MOVABLE_POINTED) - /// Target the pointed atom for actions -/datum/pet_command/point_targeting/proc/on_point(mob/living/friend, atom/pointed_atom, obj/effect/temp_visual/point/point) - SIGNAL_HANDLER - +/datum/pet_command/proc/on_target_set(mob/living/friend, atom/potential_target) var/mob/living/parent = weak_parent.resolve() if (!parent) - return FALSE + return parent.ai_controller.CancelActions() - if (look_for_target(friend, pointed_atom) && set_command_target(parent, pointed_atom)) - parent.visible_message(span_warning("[parent] follows [friend]'s gesture towards [pointed_atom] [pointed_reaction]!")) - return TRUE - return FALSE + if(!look_for_target(friend, potential_target) || !set_command_target(parent, potential_target)) + return + parent.visible_message(span_warning("[parent] follows [friend]'s gesture towards [potential_target] [pointed_reaction]!")) + + diff --git a/code/datums/components/pet_commands/pet_commands_basic.dm b/code/datums/components/pet_commands/pet_commands_basic.dm index fd4e1f922c8b4..06d11d353e8d5 100644 --- a/code/datums/components/pet_commands/pet_commands_basic.dm +++ b/code/datums/components/pet_commands/pet_commands_basic.dm @@ -7,14 +7,16 @@ /datum/pet_command/idle command_name = "Stay" command_desc = "Command your pet to stay idle in this location." - radial_icon = 'icons/obj/bed.dmi' - radial_icon_state = "dogbed" + radial_icon_state = "halt" speech_commands = list("sit", "stay", "stop") command_feedback = "sits" /datum/pet_command/idle/execute_action(datum/ai_controller/controller) return SUBTREE_RETURN_FINISH_PLANNING // This cancels further AI planning +/datum/pet_command/idle/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to stay idle!" + /** * # Pet Command: Stop * Tells a pet to exit command mode and resume its normal behaviour, which includes regular target-seeking and what have you @@ -22,8 +24,7 @@ /datum/pet_command/free command_name = "Loose" command_desc = "Allow your pet to resume its natural behaviours." - radial_icon = 'icons/mob/actions/actions_spells.dmi' - radial_icon_state = "repulse" + radial_icon_state = "free" speech_commands = list("free", "loose") command_feedback = "relaxes" @@ -31,6 +32,9 @@ controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND) return // Just move on to the next planning subtree. +/datum/pet_command/free/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to go free!" + /** * # Pet Command: Follow * Tells a pet to follow you until you tell it to do something else @@ -38,8 +42,7 @@ /datum/pet_command/follow command_name = "Follow" command_desc = "Command your pet to accompany you." - radial_icon = 'icons/testing/turf_analysis.dmi' - radial_icon_state = "red_arrow" + radial_icon_state = "follow" speech_commands = list("heel", "follow") callout_type = /datum/callout_option/move ///the behavior we use to follow @@ -49,6 +52,9 @@ . = ..() set_command_target(parent, commander) +/datum/pet_command/follow/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to follow!" + /datum/pet_command/follow/execute_action(datum/ai_controller/controller) controller.queue_behavior(follow_behavior, BB_CURRENT_PET_TARGET) return SUBTREE_RETURN_FINISH_PLANNING @@ -60,14 +66,16 @@ /datum/pet_command/play_dead command_name = "Play Dead" command_desc = "Play a macabre trick." - radial_icon = 'icons/mob/simple/pets.dmi' - radial_icon_state = "puppy_dead" + radial_icon_state = "play_dead" speech_commands = list("play dead") // Don't get too creative here, people talk about dying pretty often /datum/pet_command/play_dead/execute_action(datum/ai_controller/controller) controller.queue_behavior(/datum/ai_behavior/play_dead) return SUBTREE_RETURN_FINISH_PLANNING +/datum/pet_command/play_dead/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to play dead!" + /** * # Pet Command: Good Boy * React if complimented @@ -115,16 +123,18 @@ controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND) return SUBTREE_RETURN_FINISH_PLANNING +/datum/pet_command/untargeted_ability/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to use an ability!" + /** * # Pet Command: Attack * Tells a pet to chase and bite the next thing you point at */ -/datum/pet_command/point_targeting/attack +/datum/pet_command/attack command_name = "Attack" command_desc = "Command your pet to attack things that you point out to it." - radial_icon = 'icons/effects/effects.dmi' - radial_icon_state = "bite" - + radial_icon_state = "attack" + requires_pointing = TRUE callout_type = /datum/callout_option/attack speech_commands = list("attack", "sic", "kill") command_feedback = "growl" @@ -135,7 +145,7 @@ var/attack_behaviour = /datum/ai_behavior/basic_melee_attack // Refuse to target things we can't target, chiefly other friends -/datum/pet_command/point_targeting/attack/set_command_target(mob/living/parent, atom/target) +/datum/pet_command/attack/set_command_target(mob/living/parent, atom/target) if (!target) return var/mob/living/living_parent = parent @@ -149,28 +159,32 @@ return return ..() +/datum/pet_command/attack/retrieve_command_text(atom/living_pet, atom/target) + return isnull(target) ? null : "signals [living_pet] to attack [target]!" + /// Display feedback about not targeting something -/datum/pet_command/point_targeting/attack/proc/refuse_target(mob/living/parent, atom/target) +/datum/pet_command/attack/proc/refuse_target(mob/living/parent, atom/target) var/mob/living/living_parent = parent living_parent.balloon_alert_to_viewers("[refuse_reaction]") living_parent.visible_message(span_notice("[living_parent] refuses to attack [target].")) -/datum/pet_command/point_targeting/attack/execute_action(datum/ai_controller/controller) +/datum/pet_command/attack/execute_action(datum/ai_controller/controller) controller.queue_behavior(attack_behaviour, BB_CURRENT_PET_TARGET, targeting_strategy_key) return SUBTREE_RETURN_FINISH_PLANNING /** * # Breed command. breed with a partner! */ -/datum/pet_command/point_targeting/breed +/datum/pet_command/breed command_name = "Breed" command_desc = "Command your pet to attempt to breed with a partner." - radial_icon = 'icons/mob/simple/animal.dmi' - radial_icon_state = "heart" + requires_pointing = TRUE + radial_icon_state = "breed" speech_commands = list("breed", "consummate") + ///the behavior we use to make babies var/datum/ai_behavior/reproduce_behavior = /datum/ai_behavior/make_babies -/datum/pet_command/point_targeting/breed/set_command_target(mob/living/parent, atom/target) +/datum/pet_command/breed/set_command_target(mob/living/parent, atom/target) if(isnull(target) || !isliving(target)) return if(!HAS_TRAIT(parent, TRAIT_MOB_BREEDER) || !HAS_TRAIT(target, TRAIT_MOB_BREEDER)) @@ -184,21 +198,25 @@ return return ..() -/datum/pet_command/point_targeting/breed/execute_action(datum/ai_controller/controller) +/datum/pet_command/breed/execute_action(datum/ai_controller/controller) if(is_type_in_list(controller.blackboard[BB_CURRENT_PET_TARGET], controller.blackboard[BB_BABIES_PARTNER_TYPES])) controller.queue_behavior(reproduce_behavior, BB_CURRENT_PET_TARGET) controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND) return SUBTREE_RETURN_FINISH_PLANNING +/datum/pet_command/breed/retrieve_command_text(atom/living_pet, atom/target) + return isnull(target) ? null : "signals [living_pet] to breed with [target]!" + /** * # Pet Command: Targetted Ability * Tells a pet to use some kind of ability on the next thing you point at */ -/datum/pet_command/point_targeting/use_ability +/datum/pet_command/use_ability command_name = "Use ability" command_desc = "Command your pet to use one of its special skills on something that you point out to it." radial_icon = 'icons/mob/actions/actions_spells.dmi' radial_icon_state = "projectile" + requires_pointing = TRUE speech_commands = list("shoot", "blast", "cast") command_feedback = "growl" pointed_reaction = "and growls" @@ -207,7 +225,7 @@ /// The AI behavior to use for the ability var/ability_behavior = /datum/ai_behavior/pet_use_ability -/datum/pet_command/point_targeting/use_ability/execute_action(datum/ai_controller/controller) +/datum/pet_command/use_ability/execute_action(datum/ai_controller/controller) if (!pet_ability_key) return var/datum/action/cooldown/using_action = controller.blackboard[pet_ability_key] @@ -218,6 +236,9 @@ controller.queue_behavior(ability_behavior, pet_ability_key, BB_CURRENT_PET_TARGET) return SUBTREE_RETURN_FINISH_PLANNING +/datum/pet_command/use_ability/retrieve_command_text(atom/living_pet, atom/target) + return isnull(target) ? null : "signals [living_pet] to use an ability on [target]!" + /datum/pet_command/protect_owner command_name = "Protect owner" command_desc = "Your pet will run to your aid." @@ -278,25 +299,39 @@ /** * # Fish command: command the mob to fish at the next fishing spot you point at. Requires the profound fisher component */ -/datum/pet_command/point_targeting/fish +/datum/pet_command/fish command_name = "Fish" command_desc = "Command your pet to try fishing at a nearby fishing spot." - radial_icon = 'icons/obj/aquarium/fish.dmi' - radial_icon_state = "goldfish" + requires_pointing = TRUE + radial_icon_state = "fish" speech_commands = list("fish") -// Refuse to target things we can't target, chiefly other friends -/datum/pet_command/point_targeting/fish/set_command_target(mob/living/parent, atom/target) - if (!target) - return - if(!parent.ai_controller || !HAS_TRAIT(parent, TRAIT_PROFOUND_FISHER)) - return - var/datum/targeting_strategy/targeter = GET_TARGETING_STRATEGY(/datum/targeting_strategy/fishing) - if (!targeter?.can_attack(parent, target)) - parent.balloon_alert_to_viewers("shakes head!") - return +/datum/pet_command/fish/execute_action(datum/ai_controller/controller) + if(controller.blackboard_key_exists(BB_CURRENT_PET_TARGET)) + controller.queue_behavior(/datum/ai_behavior/interact_with_target/fishing, BB_CURRENT_PET_TARGET) + return SUBTREE_RETURN_FINISH_PLANNING + +/datum/pet_command/fish/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to go fish!" + +/datum/pet_command/move + command_name = "Move" + command_desc = "Command your pet to move to a location!" + requires_pointing = TRUE + radial_icon_state = "move" + speech_commands = list("move", "walk") + ///the behavior we use to walk towards targets + var/datum/ai_behavior/walk_behavior = /datum/ai_behavior/travel_towards + +/datum/pet_command/move/set_command_target(mob/living/parent, atom/target) + if(isnull(target) || !can_see(parent, target, 9)) + return FALSE return ..() -/datum/pet_command/point_targeting/fish/execute_action(datum/ai_controller/controller) - controller.queue_behavior(/datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off, BB_CURRENT_PET_TARGET) +/datum/pet_command/move/execute_action(datum/ai_controller/controller) + if(controller.blackboard_key_exists(BB_CURRENT_PET_TARGET)) + controller.queue_behavior(walk_behavior, BB_CURRENT_PET_TARGET) return SUBTREE_RETURN_FINISH_PLANNING + +/datum/pet_command/move/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to move!" diff --git a/code/datums/components/plumbing/_plumbing.dm b/code/datums/components/plumbing/_plumbing.dm index a1be66654a2c0..ed916c29edf94 100644 --- a/code/datums/components/plumbing/_plumbing.dm +++ b/code/datums/components/plumbing/_plumbing.dm @@ -121,6 +121,8 @@ ///returns TRUE when they can give the specified amount and reagent. called by process request /datum/component/plumbing/proc/can_give(amount, reagent, datum/ductnet/net) + SHOULD_BE_PURE(TRUE) + if(amount <= 0) return diff --git a/code/datums/components/plumbing/reaction_chamber.dm b/code/datums/components/plumbing/reaction_chamber.dm index d0aff2f50708c..4f2acf4710a7e 100644 --- a/code/datums/components/plumbing/reaction_chamber.dm +++ b/code/datums/components/plumbing/reaction_chamber.dm @@ -8,20 +8,25 @@ return COMPONENT_INCOMPATIBLE /datum/component/plumbing/reaction_chamber/can_give(amount, reagent, datum/ductnet/net) - . = ..() var/obj/machinery/plumbing/reaction_chamber/reaction_chamber = parent - if(!. || !reaction_chamber.emptying || reagents.is_reacting) + + //cannot give when we outselves are requesting or reacting the reagents + if(!reaction_chamber.emptying || reagents.is_reacting) return FALSE + return ..() + /datum/component/plumbing/reaction_chamber/send_request(dir) var/obj/machinery/plumbing/reaction_chamber/chamber = parent + if(chamber.emptying) return //take in reagents var/present_amount var/diff - for(var/required_reagent in chamber.required_reagents) + var/list/datum/reagent/required_reagents = chamber.catalysts | chamber.required_reagents + for(var/datum/reagent/required_reagent as anything in required_reagents) //find how much amount is already present if at all and get the reagent reference present_amount = 0 for(var/datum/reagent/present_reagent as anything in reagents.reagent_list) @@ -30,10 +35,11 @@ break //compute how much more is needed - diff = min(chamber.required_reagents[required_reagent] - present_amount, MACHINE_REAGENT_TRANSFER) + diff = min(required_reagents[required_reagent] - present_amount, MACHINE_REAGENT_TRANSFER) if(diff >= CHEMICAL_QUANTISATION_LEVEL) // the closest we can ask for so values like 0.9999 become 1 process_request(diff, required_reagent, dir) - return + if(!chamber.catalysts[required_reagent]) //only block if not a catalyst as they can come in whenever they are available + return reagents.flags &= ~NO_REACT reagents.handle_reactions() diff --git a/code/datums/components/trader/trader.dm b/code/datums/components/trader/trader.dm index d623a9943b893..3b2675785aec3 100644 --- a/code/datums/components/trader/trader.dm +++ b/code/datums/components/trader/trader.dm @@ -394,7 +394,7 @@ Can accept both a type path, and an instance of a datum. Type path has priority. else buy_info += span_notice("• [initial(thing.name)] for [product_info[TRADER_PRODUCT_INFO_PRICE]] [trader_data.currency_name][product_info[TRADER_PRODUCT_INFO_PRICE_MOD_DESCRIPTION]]; willing to buy [span_green("[tern_op_result]")]") - to_chat(customer, examine_block(buy_info.Join("\n"))) + to_chat(customer, boxed_message(buy_info.Join("\n"))) ///Displays to the customer what the trader is selling and how much is in stock /datum/component/trader/proc/trader_sells_what(mob/customer) @@ -413,7 +413,7 @@ Can accept both a type path, and an instance of a datum. Type path has priority. sell_info += span_notice("• [span_red("(OUT OF STOCK)")] [initial(thing.name)] for [product_info[TRADER_PRODUCT_INFO_PRICE]] [trader_data.currency_name]; [span_red("[tern_op_result]")] left in stock") else sell_info += span_notice("• [initial(thing.name)] for [product_info[TRADER_PRODUCT_INFO_PRICE]] [trader_data.currency_name]; [span_green("[tern_op_result]")] left in stock") - to_chat(customer, examine_block(sell_info.Join("\n"))) + to_chat(customer, boxed_message(sell_info.Join("\n"))) ///Sets quantity of all products to initial(quanity); this proc is currently called during initialize /datum/component/trader/proc/restock_products() diff --git a/code/datums/elements/basic_eating.dm b/code/datums/elements/basic_eating.dm index 75caa272ef9bd..4be983b32113c 100644 --- a/code/datums/elements/basic_eating.dm +++ b/code/datums/elements/basic_eating.dm @@ -46,8 +46,10 @@ SIGNAL_HANDLER if(user.combat_mode || !is_type_in_list(possible_food, food_types)) return NONE - - try_eating(source, possible_food, user) + var/mob/living/living_source = source + if(living_source.stat != CONSCIOUS) + return NONE + return try_eating(source, possible_food, user) ? ITEM_INTERACT_SUCCESS : NONE /datum/element/basic_eating/proc/on_unarm_attack(mob/living/eater, atom/target, proximity, modifiers) SIGNAL_HANDLER diff --git a/code/datums/elements/leeching_walk.dm b/code/datums/elements/leeching_walk.dm index c9f547189e699..f5148b43a5a52 100644 --- a/code/datums/elements/leeching_walk.dm +++ b/code/datums/elements/leeching_walk.dm @@ -24,9 +24,8 @@ var/turf/mover_turf = get_turf(source) if(HAS_TRAIT(mover_turf, TRAIT_RUSTY)) ADD_TRAIT(source, TRAIT_BATON_RESISTANCE, type) - return - - REMOVE_TRAIT(source, TRAIT_BATON_RESISTANCE, type) + else + REMOVE_TRAIT(source, TRAIT_BATON_RESISTANCE, type) /** * Signal proc for [COMSIG_LIVING_LIFE]. @@ -43,17 +42,18 @@ // Heals all damage + Stamina var/need_mob_update = FALSE - need_mob_update += source.adjustBruteLoss(-3, updating_health = FALSE) - need_mob_update += source.adjustFireLoss(-3, updating_health = FALSE) - need_mob_update += source.adjustToxLoss(-3, updating_health = FALSE, forced = TRUE) // Slimes are people to - need_mob_update += source.adjustOxyLoss(-1.5, updating_health = FALSE) - need_mob_update += source.adjustStaminaLoss(-10, updating_stamina = FALSE) + var/delta_time = DELTA_WORLD_TIME(SSmobs) * 0.5 // SSmobs.wait is 2 secs, so this should be halved. + need_mob_update += source.adjustBruteLoss(-3 * delta_time, updating_health = FALSE) + need_mob_update += source.adjustFireLoss(-3 * delta_time, updating_health = FALSE) + need_mob_update += source.adjustToxLoss(-3 * delta_time, updating_health = FALSE, forced = TRUE) // Slimes are people too + need_mob_update += source.adjustOxyLoss(-1.5 * delta_time, updating_health = FALSE) + need_mob_update += source.adjustStaminaLoss(-10 * delta_time, updating_stamina = FALSE) if(need_mob_update) source.updatehealth() // Reduces duration of stuns/etc - source.AdjustAllImmobility(-0.5 SECONDS) + source.AdjustAllImmobility((-0.5 SECONDS) * delta_time) // Heals blood loss if(source.blood_volume < BLOOD_VOLUME_NORMAL) - source.blood_volume += 2.5 * seconds_per_tick + source.blood_volume += 2.5 * delta_time // Slowly regulates your body temp - source.adjust_bodytemperature((source.get_body_temp_normal() - source.bodytemperature)/5) + source.adjust_bodytemperature((source.get_body_temp_normal() - source.bodytemperature) / 5) diff --git a/code/datums/elements/nav_computer_icon.dm b/code/datums/elements/nav_computer_icon.dm new file mode 100644 index 0000000000000..4e9b6a3a18893 --- /dev/null +++ b/code/datums/elements/nav_computer_icon.dm @@ -0,0 +1,44 @@ +/** + * element for atoms that have helper icons overlayed on their position in the shuttle navigation computer, such as airlocks + */ +/datum/element/nav_computer_icon + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + var/use_icon + var/use_icon_state + var/only_show_on_shuttle_edge + +/datum/element/nav_computer_icon/Attach(datum/target, use_icon, use_icon_state, only_show_on_shuttle_edge) + . = ..() + if(!isatom(target)) + return ELEMENT_INCOMPATIBLE + + src.use_icon = use_icon + src.use_icon_state = use_icon_state + src.only_show_on_shuttle_edge = only_show_on_shuttle_edge + + RegisterSignal(target, COMSIG_SHUTTLE_NAV_COMPUTER_IMAGE_REQUESTED, PROC_REF(provide_image)) + +/datum/element/nav_computer_icon/proc/provide_image(datum/source, list/images_out) + SIGNAL_HANDLER + var/obj/source_obj = source + var/turf/source_turf = get_turf(source_obj) + if(!source_turf) + return + if(only_show_on_shuttle_edge) + var/isOnEdge = FALSE + for(var/direction in GLOB.cardinals) + var/turf/turf = get_step(source_obj, direction) + if(!istype(turf?.loc, /area/shuttle)) + isOnEdge = TRUE + break + if(!isOnEdge) + return + + var/image/the_image = image(use_icon, source_turf, use_icon_state) + the_image.dir = source_obj.dir + images_out += the_image + +/datum/element/nav_computer_icon/Detach(datum/source) + . = ..() + UnregisterSignal(source, COMSIG_SHUTTLE_NAV_COMPUTER_IMAGE_REQUESTED) diff --git a/code/datums/elements/pet_cult.dm b/code/datums/elements/pet_cult.dm index 36941e7b74299..f26e6e343e666 100644 --- a/code/datums/elements/pet_cult.dm +++ b/code/datums/elements/pet_cult.dm @@ -90,7 +90,8 @@ source.ai_controller.set_blackboard_key(BB_CULT_TEAM, team) var/static/list/new_pet_commands = list( - /datum/pet_command/point_targeting/attack, + /datum/pet_command/move, + /datum/pet_command/attack, /datum/pet_command/follow, /datum/pet_command/free, /datum/pet_command/idle, diff --git a/code/datums/elements/slapcrafting.dm b/code/datums/elements/slapcrafting.dm index 4b58bddd2a0f4..046a8668a2974 100644 --- a/code/datums/elements/slapcrafting.dm +++ b/code/datums/elements/slapcrafting.dm @@ -134,7 +134,7 @@ for(var/datum/crafting_recipe/recipe as anything in slapcraft_recipes) var/atom/result = initial(recipe.result) - examine_list += "See Recipe For [initial(result.name)]" + examine_list += "See Recipe For [initial(result.name)]" /datum/element/slapcrafting/proc/topic_handler(atom/source, user, href_list) SIGNAL_HANDLER @@ -180,7 +180,7 @@ // If we did find ingredients then add them onto the list. if(length(string_ingredient_list)) to_chat(user, span_boldnotice("Extra Ingredients:")) - to_chat(user, examine_block(span_notice(string_ingredient_list))) + to_chat(user, boxed_message(span_notice(string_ingredient_list))) var/list/tool_list = "" @@ -194,7 +194,7 @@ if(length(tool_list)) to_chat(user, span_boldnotice("Required Tools:")) - to_chat(user, examine_block(span_notice(tool_list))) + to_chat(user, boxed_message(span_notice(tool_list))) qdel(cur_recipe) diff --git a/code/datums/elements/weapon_description.dm b/code/datums/elements/weapon_description.dm index 64d044fb74a3d..022318abfcf0d 100644 --- a/code/datums/elements/weapon_description.dm +++ b/code/datums/elements/weapon_description.dm @@ -39,7 +39,7 @@ SIGNAL_HANDLER if(item.force >= 5 || item.throwforce >= 5 || item.override_notes || item.offensive_notes || attached_proc) /// Only show this tag for items that could feasibly be weapons, shields, or those that have special notes - examine_texts += span_notice("See combat information.") + examine_texts += span_notice("See combat information.") /** * @@ -57,7 +57,7 @@ SIGNAL_HANDLER if(href_list["examine"]) - to_chat(user, span_notice(examine_block("[build_label_text(source)]"))) + to_chat(user, span_notice(boxed_message("[build_label_text(source)]"))) /** * diff --git a/code/datums/keybinding/_keybindings.dm b/code/datums/keybinding/_keybindings.dm index dfcf492c1809f..a989d0d22a881 100644 --- a/code/datums/keybinding/_keybindings.dm +++ b/code/datums/keybinding/_keybindings.dm @@ -21,6 +21,8 @@ return SEND_SIGNAL(user.mob, keybind_signal) & COMSIG_KB_ACTIVATED /datum/keybinding/proc/up(client/user) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(user.mob, DEACTIVATE_KEYBIND(keybind_signal)) return FALSE /datum/keybinding/proc/can_use(client/user) diff --git a/code/datums/keybinding/living.dm b/code/datums/keybinding/living.dm index 7e50e6928f9dd..61716ee6fe95a 100644 --- a/code/datums/keybinding/living.dm +++ b/code/datums/keybinding/living.dm @@ -46,6 +46,7 @@ return TRUE /datum/keybinding/living/look_up/up(client/user) + . = ..() var/mob/living/L = user.mob L.end_look_up() return TRUE @@ -66,6 +67,7 @@ return TRUE /datum/keybinding/living/look_down/up(client/user) + . = ..() var/mob/living/L = user.mob L.end_look_down() return TRUE @@ -144,6 +146,7 @@ return TRUE /datum/keybinding/living/toggle_move_intent/up(client/user) + . = ..() var/mob/living/M = user.mob M.toggle_move_intent() return TRUE diff --git a/code/datums/keybinding/mob.dm b/code/datums/keybinding/mob.dm index 4963e87266cbe..a1bd06742b555 100644 --- a/code/datums/keybinding/mob.dm +++ b/code/datums/keybinding/mob.dm @@ -191,3 +191,10 @@ if(.) return user.movement_locked = FALSE + +/datum/keybinding/living/view_pet_data + hotkey_keys = list("Shift") + name = "view_pet_commands" + full_name = "View Pet Commands" + description = "Hold down to see all the commands you can give your pets!" + keybind_signal = COMSIG_KB_LIVING_VIEW_PET_COMMANDS diff --git a/code/datums/mind/skills.dm b/code/datums/mind/skills.dm index 474291d5ae0d4..80a78c3d950f2 100644 --- a/code/datums/mind/skills.dm +++ b/code/datums/mind/skills.dm @@ -75,4 +75,4 @@ var/datum/skill/the_skill = i msg += "[initial(the_skill.name)] - [get_skill_level_name(the_skill)]\n" msg += "" - to_chat(user, examine_block(msg)) + to_chat(user, boxed_message(msg)) diff --git a/code/datums/mood.dm b/code/datums/mood.dm index d3f2ac70861e0..e10be827eb279 100644 --- a/code/datums/mood.dm +++ b/code/datums/mood.dm @@ -389,7 +389,7 @@ msg += span_boldnicegreen(event.description + "\n") else msg += "[span_grey("I don't have much of a reaction to anything right now.")]\n" - to_chat(user, examine_block(msg)) + to_chat(user, boxed_message(msg)) /// Updates the mob's moodies, if the area provides a mood bonus /datum/mood/proc/check_area_mood(datum/source, area/new_area) diff --git a/code/datums/status_effects/debuffs/terrified.dm b/code/datums/status_effects/debuffs/terrified.dm index 61a6ecd4eda3b..61c4abcea3bf4 100644 --- a/code/datums/status_effects/debuffs/terrified.dm +++ b/code/datums/status_effects/debuffs/terrified.dm @@ -96,6 +96,9 @@ /datum/status_effect/terrified/proc/comfort_owner(datum/source, mob/living/hugger) SIGNAL_HANDLER + if(hugger == owner) + return + if(isnightmare(hugger)) //hey wait a minute, that's not a comforting, friendly hug! if(check_surrounding_darkness()) addtimer(CALLBACK(src, PROC_REF(freak_out), HUG_TERROR_AMOUNT)) diff --git a/code/datums/votes/_vote_datum.dm b/code/datums/votes/_vote_datum.dm index 76833f73ff5b0..957160dea7d3e 100644 --- a/code/datums/votes/_vote_datum.dm +++ b/code/datums/votes/_vote_datum.dm @@ -170,13 +170,14 @@ * Return a formatted string of text to be displayed to everyone. */ /datum/vote/proc/get_result_text(list/all_winners, real_winner, list/non_voters) + var/title_text = "" var/returned_text = "" if(override_question) - returned_text += span_bold(override_question) + title_text += span_bold(override_question) else - returned_text += span_bold("[capitalize(name)] Vote") + title_text += span_bold("[capitalize(name)] Vote") - returned_text += "\nWinner Selection: " + returned_text += "Winner Selection: " switch(winner_method) if(VOTE_WINNER_METHOD_NONE) returned_text += "None" @@ -215,7 +216,7 @@ returned_text += "\n" returned_text += get_winner_text(all_winners, real_winner, non_voters) - return returned_text + return fieldset_block(title_text, returned_text, "boxed_message purple_box") /** * Gets the text that displays the winning options within the result text. diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index 2a4af3a781aa0..c34c018d59c65 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -114,7 +114,7 @@ var/message = "CROSS-SECTOR MESSAGE (INCOMING): [input["sender_ckey"]] (from [input["source"]]) is about to send \ the following message (will autoapprove in [soft_filter_passed ? "[extended_time_display]" : "[normal_time_display]"]): \ - REJECT

\ + REJECT

\ [html_encode(input["message"])]" if(soft_filter_passed) diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index eb0166e9d540e..d73579c8f366e 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -865,6 +865,8 @@ if (isnull(user)) return + SEND_SIGNAL(user, COMSIG_ATOM_MOUSE_ENTERED, src) + // Screentips var/datum/hud/active_hud = user.hud_used if(!active_hud) diff --git a/code/game/atom/atom_vv.dm b/code/game/atom/atom_vv.dm index 7a7dc8d3a877d..14a8b41e6e10e 100644 --- a/code/game/atom/atom_vv.dm +++ b/code/game/atom/atom_vv.dm @@ -199,7 +199,7 @@ . = ..() var/refid = REF(src) . += "[VV_HREF_TARGETREF(refid, VV_HK_AUTO_RENAME, "[src]")]" - . += "
<< [dir2text(dir) || dir] >>" + . += "
<< [dir2text(dir) || dir] >>" /** * call back when a var is edited on this atom diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 7c2840afde19a..e6fe68ea4c487 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1137,7 +1137,6 @@ pulledby.stop_pulling() var/same_loc = oldloc == destination - var/movement_successful = TRUE var/area/old_area = get_area(oldloc) var/area/destarea = get_area(destination) var/movement_dir = get_dir(src, destination) @@ -1146,13 +1145,13 @@ loc = destination - if(!same_loc && loc == oldloc) - // when attempting to move an atom A into an atom B which already contains A, BYOND seems - // to silently refuse to move A to the new loc. This can really break stuff (see #77067) - stack_trace("Attempt to move [src] to [destination] was rejected by BYOND, possibly due to cyclic contents") - movement_successful = FALSE + if(!same_loc) + if(loc == oldloc) + // when attempting to move an atom A into an atom B which already contains A, BYOND seems + // to silently refuse to move A to the new loc. This can really break stuff (see #77067) + stack_trace("Attempt to move [src] to [destination] was rejected by BYOND, possibly due to cyclic contents") + return FALSE - if(movement_successful && !same_loc) if(is_multi_tile && isturf(destination)) var/list/new_locs = block( destination, @@ -1181,7 +1180,7 @@ if(destarea && old_area != destarea) destarea.Entered(src, old_area) - . = movement_successful + . = TRUE //If no destination, move the atom into nullspace (don't do this unless you know what you're doing) else diff --git a/code/game/machinery/big_manipulator.dm b/code/game/machinery/big_manipulator.dm index 21a7de89fe619..a14a6b8531174 100644 --- a/code/game/machinery/big_manipulator.dm +++ b/code/game/machinery/big_manipulator.dm @@ -288,7 +288,12 @@ target.forceMove(drop_turf) target.dir = get_dir(get_turf(target), get_turf(src)) else - target.forceMove(where_we_drop) + var/atom/drop_target = where_we_drop + if(drop_target.atom_storage) + if(!drop_target.atom_storage.attempt_insert(target, override = TRUE, messages = FALSE)) + target.forceMove(drop_target.drop_location()) + else + target.forceMove(where_we_drop) finish_manipulation() /// 3.3 take and drop proc from [take and drop procs loop]: diff --git a/code/game/machinery/camera/camera_construction.dm b/code/game/machinery/camera/camera_construction.dm index b3593aad6e7e2..19d7d2a39567b 100644 --- a/code/game/machinery/camera/camera_construction.dm +++ b/code/game/machinery/camera/camera_construction.dm @@ -189,9 +189,9 @@ ai.last_tablet_note_seen = "[itemname][info]" if(user.name == "Unknown") - to_chat(ai, "[span_name(user)] holds \a [itemname] up to one of your cameras ...") + to_chat(ai, "[span_name(user)] holds \a [itemname] up to one of your cameras ...") else - to_chat(ai, "[user] holds \a [itemname] up to one of your cameras ...") + to_chat(ai, "[user] holds \a [itemname] up to one of your cameras ...") continue if (potential_viewer.client?.eye == src) @@ -232,16 +232,16 @@ log_paper("[key_name(user)] held [last_shown_paper] up to [src], requesting [key_name(ai)] read it.") if(user.name == "Unknown") - to_chat(ai, "[span_name(user.name)] holds \a [item_name] up to one of your cameras ...") + to_chat(ai, "[span_name(user.name)] holds \a [item_name] up to one of your cameras ...") else - to_chat(ai, "[user] holds \a [item_name] up to one of your cameras ...") + to_chat(ai, "[user] holds \a [item_name] up to one of your cameras ...") continue // If it's not an AI, eye if the client's eye is set to the camera. I wonder if this even works anymore with tgui camera apps and stuff? if (potential_viewer.client?.eye == src) log_paper("[key_name(user)] held [last_shown_paper] up to [src], and [key_name(potential_viewer)] may read it.") potential_viewer.log_talk(item_name, LOG_VICTIM, tag="Pressed to camera from [key_name(user)]", log_globally=FALSE) - to_chat(potential_viewer, "[span_name(user)] holds \a [item_name] up to your camera...") + to_chat(potential_viewer, "[span_name(user)] holds \a [item_name] up to your camera...") return return ..() diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index eb48792a523bc..d51e197a0bcdd 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -19,6 +19,8 @@ var/time_to_unscrew = 2 SECONDS /// Are we authenticated to use this? Used by things like comms console, security and medical data, and apc controller. var/authenticated = FALSE + /// Will projectiles be able to pass over this computer? + var/projectiles_pass_chance = 65 /datum/armor/machinery_computer fire = 40 @@ -28,6 +30,23 @@ . = ..() power_change() +/obj/machinery/computer/CanAllowThrough(atom/movable/mover, border_dir) // allows projectiles to fly over the computer + . = ..() + if(.) + return + if(!projectiles_pass_chance) + return FALSE + if(!isprojectile(mover)) + return FALSE + var/obj/projectile/proj = mover + if(!anchored) + return TRUE + if(proj.firer && Adjacent(proj.firer)) + return TRUE + if(prob(projectiles_pass_chance)) + return TRUE + return FALSE + /obj/machinery/computer/process() if(machine_stat & (NOPOWER|BROKEN)) return FALSE diff --git a/code/game/machinery/computer/arcade/_arcade.dm b/code/game/machinery/computer/arcade/_arcade.dm index eb91fa44f1c70..1627a3d0fe81b 100644 --- a/code/game/machinery/computer/arcade/_arcade.dm +++ b/code/game/machinery/computer/arcade/_arcade.dm @@ -7,6 +7,7 @@ icon_screen = "invaders" light_color = LIGHT_COLOR_GREEN interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_LITERACY + projectiles_pass_chance = 0 // I guess gambling can save your life huh? ///If set, will dispense these as prizes instead of the default GLOB.arcade_prize_pool ///Like prize pool, it must be a list of the prize and the weight of being selected. diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index b399223522295..7e9ef45e8f5cf 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -346,7 +346,7 @@ span_adminnotice( \ "CROSS-SECTOR MESSAGE (OUTGOING): [ADMIN_LOOKUPFLW(user)] is about to send \ the following message to [destination] (will autoapprove in [GLOB.communications_controller.soft_filtering ? DisplayTimeText(EXTENDED_CROSS_SECTOR_CANCEL_TIME) : DisplayTimeText(CROSS_SECTOR_CANCEL_TIME)]): \ - REJECT
\ + REJECT
\ [html_encode(message)]" \ ) ) diff --git a/code/game/machinery/computer/records/medical.dm b/code/game/machinery/computer/records/medical.dm index 6dd12acbdb678..c5f11ec89ca7c 100644 --- a/code/game/machinery/computer/records/medical.dm +++ b/code/game/machinery/computer/records/medical.dm @@ -18,6 +18,7 @@ icon_screen = "medlaptop" icon_keyboard = "laptop_key" pass_flags = PASSTABLE + projectiles_pass_chance = 100 /obj/machinery/computer/records/medical/attacked_by(obj/item/attacking_item, mob/living/user) . = ..() diff --git a/code/game/machinery/computer/records/security.dm b/code/game/machinery/computer/records/security.dm index 89f49cf754b8a..693bd7daa7185 100644 --- a/code/game/machinery/computer/records/security.dm +++ b/code/game/machinery/computer/records/security.dm @@ -27,6 +27,7 @@ icon_screen = "seclaptop" icon_keyboard = "laptop_key" pass_flags = PASSTABLE + projectiles_pass_chance = 100 /obj/machinery/computer/records/security/laptop/syndie desc = "A cheap, jailbroken security laptop. It functions as a security records console. It's bolted to the table." diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 12aa1c3ce0362..228391e6bdeec 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -176,7 +176,7 @@ if(!isnull(console_location)) to_chat(R, span_alert("The approximate location of the console that is keeping you locked down is [console_location]")) if(R.connected_ai) - to_chat(R.connected_ai, "[!R.lockcharge ? span_notice("NOTICE - Cyborg lockdown lifted") : span_alert("ALERT - Cyborg lockdown detected")]: [R.name]
") + to_chat(R.connected_ai, "[!R.lockcharge ? span_notice("NOTICE - Cyborg lockdown lifted") : span_alert("ALERT - Cyborg lockdown detected")]: [R.name]
") /obj/machinery/computer/robotics/proc/borg_destroyed() SIGNAL_HANDLER diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index 8cd12610c748b..74e6d22e36355 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -116,7 +116,7 @@ say("Processing hub calibration to target...") calibrating = TRUE power_station.update_appearance() - addtimer(CALLBACK(src, PROC_REF(finish_calibration)), 50 * (3 - power_station.teleporter_hub.accuracy)) //Better parts mean faster calibration + addtimer(CALLBACK(src, PROC_REF(finish_calibration)), 5 SECONDS * (3 - power_station.teleporter_hub.accuracy)) //Better parts mean faster calibration return TRUE /obj/machinery/computer/teleporter/proc/set_teleport_target(new_target) diff --git a/code/game/machinery/computer/telescreen.dm b/code/game/machinery/computer/telescreen.dm index f3a6a9879b4d1..3b96ae111fba3 100644 --- a/code/game/machinery/computer/telescreen.dm +++ b/code/game/machinery/computer/telescreen.dm @@ -12,6 +12,7 @@ light_power = 0 /// The kind of wallframe that this telescreen drops var/frame_type = /obj/item/wallframe/telescreen + projectiles_pass_chance = 100 /obj/item/wallframe/telescreen name = "telescreen frame" diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index b90302111ab7b..0a41adcac98f2 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -22,6 +22,11 @@ if(circuit) . += "It has \a [circuit] installed." +/obj/structure/frame/CanAllowThrough(atom/movable/mover, border_dir) + if(isprojectile(mover)) + return TRUE + return ..() + /obj/structure/frame/atom_deconstruct(disassembled = TRUE) var/atom/movable/drop_loc = drop_location() new /obj/item/stack/sheet/iron(drop_loc, 5) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 1be4325638d37..c3657c6cac391 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -181,6 +181,8 @@ // Click on the floor to close airlocks AddComponent(/datum/component/redirect_attack_hand_from_turf) + AddElement(/datum/element/nav_computer_icon, 'icons/effects/nav_computer_indicators.dmi', "airlock", TRUE) + RegisterSignal(src, COMSIG_MACHINERY_BROKEN, PROC_REF(on_break)) RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index cb33ed6c14f5a..b7ae0c9876a83 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -22,6 +22,12 @@ var/id = 1 /// The sound that plays when the door opens/closes var/animation_sound = 'sound/machines/blastdoor.ogg' + var/show_nav_computer_icon = TRUE + +/obj/machinery/door/poddoor/Initialize(mapload) + . = ..() + if(show_nav_computer_icon) + AddElement(/datum/element/nav_computer_icon, 'icons/effects/nav_computer_indicators.dmi', "airlock", TRUE) /datum/armor/door_poddoor melee = 50 diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 56e2f5a9743b2..52c12835c2797 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -10,6 +10,7 @@ max_integrity = 100 recipe_type = /datum/crafting_recipe/shutters animation_sound = 'sound/machines/shutter.ogg' + show_nav_computer_icon = FALSE /obj/machinery/door/poddoor/shutters/animation_length(animation) switch(animation) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 186dfa9f31f9c..76653c43ddf96 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -327,7 +327,7 @@ Possible to do for anyone motivated enough: for(var/mob/living/silicon/ai/AI in GLOB.silicon_mobs) if(!AI.client) continue - to_chat(AI, span_info("Your presence is requested at \the [area]. Project Hologram?")) + to_chat(AI, span_info("Your presence is requested at \the [area]. Project Hologram?")) return TRUE else to_chat(usr, span_info("A request for AI presence was already sent recently.")) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index d1f785f9b53d5..796ee58984565 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -762,6 +762,7 @@ DEFINE_BITFIELD(turret_flags, list( /obj/machinery/porta_turret/syndicate/Initialize(mapload) . = ..() AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/nav_computer_icon, 'icons/effects/nav_computer_indicators.dmi', "turret", FALSE) /obj/machinery/porta_turret/syndicate/setup() return diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index 49f00741895fe..3e3fc5af30757 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -14,6 +14,9 @@ fair_market_price = 10 payment_department = ACCOUNT_MED interaction_flags_click = ALLOW_SILICON_REACH + use_power = IDLE_POWER_USE + idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 3 + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 3 var/stasis_enabled = TRUE var/last_stasis_sound = FALSE var/stasis_can_toggle = 0 @@ -25,6 +28,20 @@ AddElement(/datum/element/elevation, pixel_shift = 6) update_buckle_vars(dir) +/obj/machinery/stasis/RefreshParts() + . = ..() + + var/energy_rating = 0 + for(var/datum/stock_part/part in component_parts) + energy_rating += part.energy_rating() + + for(var/obj/item/stock_parts/part in component_parts) + energy_rating += part.energy_rating + + idle_power_usage = initial(idle_power_usage) / (energy_rating/2) + active_power_usage = initial(active_power_usage) / (energy_rating/2) + update_current_power_usage() + /obj/machinery/stasis/examine(mob/user) . = ..() . += span_notice("Alt-click to [stasis_enabled ? "turn off" : "turn on"] the machine.") diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index c46f6b351543d..262e014ee0b79 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -33,7 +33,7 @@ /obj/machinery/teleport/hub/examine(mob/user) . = ..() if(in_range(user, src) || isobserver(user)) - . += span_notice("The status display reads: Probability of malfunction decreased by [(accuracy*25)-25]%.") + . += span_notice("The status display reads: Success chance is [70 + (accuracy * 10)]%.") /obj/machinery/teleport/hub/proc/link_power_station() if(power_station) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index b83d9a78ac37f..01c506d6fd708 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -2042,9 +2042,9 @@ . = ..() . += {"
- DAMTYPE: [uppertext(damtype)] - FORCE: [force] - WOUND: [wound_bonus] - BARE WOUND: [bare_wound_bonus] + DAMTYPE: [uppertext(damtype)] + FORCE: [force] + WOUND: [wound_bonus] + BARE WOUND: [bare_wound_bonus] "} diff --git a/code/game/objects/items/AI_modules/_AI_modules.dm b/code/game/objects/items/AI_modules/_AI_modules.dm index a7f8dbb1798c0..905443569b2eb 100644 --- a/code/game/objects/items/AI_modules/_AI_modules.dm +++ b/code/game/objects/items/AI_modules/_AI_modules.dm @@ -36,7 +36,7 @@ /obj/item/ai_module/attack_self(mob/user as mob) ..() - to_chat(user, examine_block(display_laws())) + to_chat(user, boxed_message(display_laws())) /// Returns a text display of the laws for the module. /obj/item/ai_module/proc/display_laws() diff --git a/code/game/objects/items/charter.dm b/code/game/objects/items/charter.dm index 69b57fe4e7323..6f8ad945621e5 100644 --- a/code/game/objects/items/charter.dm +++ b/code/game/objects/items/charter.dm @@ -58,7 +58,7 @@ // Autoapproves after a certain time response_timer_id = addtimer(CALLBACK(src, PROC_REF(rename_station), new_name, user.name, user.real_name, key_name(user)), approval_time, TIMER_STOPPABLE) to_chat(GLOB.admins, - span_adminnotice("CUSTOM STATION RENAME:[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [new_name] (will autoapprove in [DisplayTimeText(approval_time)]). [ADMIN_SMITE(user)] (REJECT) [ADMIN_CENTCOM_REPLY(user)]"), + span_adminnotice("CUSTOM STATION RENAME:[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [new_name] (will autoapprove in [DisplayTimeText(approval_time)]). [ADMIN_SMITE(user)] (REJECT) [ADMIN_CENTCOM_REPLY(user)]"), type = MESSAGE_TYPE_PRAYER) for(var/client/admin_client in GLOB.admins) if(admin_client.prefs.toggles & SOUND_ADMINHELP) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 94b7e14fe80fb..943896f29f4be 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -267,7 +267,7 @@ if(length(render_list)) //display our packaged information in an examine block for easy reading - to_chat(user, examine_block(jointext(render_list, "")), type = MESSAGE_TYPE_INFO) + to_chat(user, boxed_message(jointext(render_list, "")), type = MESSAGE_TYPE_INFO) return ITEM_INTERACT_SUCCESS return ITEM_INTERACT_BLOCKING diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 364550f062aa7..c6aa10784eeef 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -151,7 +151,7 @@ air_update_turf(FALSE, FALSE) if(warning_given && internal_heat < max_heat * 0.75) warning_given = FALSE - message_admins("Power sink at ([x],[y],[z] - JMP) has cooled down and will not explode.") + message_admins("Power sink at ([x],[y],[z] - JMP) has cooled down and will not explode.") if(mode != OPERATING && internal_heat < MINIMUM_HEAT) internal_heat = 0 STOP_PROCESSING(SSobj, src) @@ -188,7 +188,7 @@ if(internal_heat > max_heat * ALERT / 100) if (!warning_given) warning_given = TRUE - message_admins("Power sink at ([x],[y],[z] - JMP) has reached [ALERT]% of max heat. Explosion imminent.") + message_admins("Power sink at ([x],[y],[z] - JMP) has reached [ALERT]% of max heat. Explosion imminent.") notify_ghosts( "[src] is about to reach critical heat capacity!", source = src, diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index ac9cbfec8211f..25060d23af5b2 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -120,6 +120,8 @@ if(type != /obj/item/radio) return AddElement(/datum/element/slapcrafting, string_list(list(/datum/crafting_recipe/improv_explosive))) + if(prob(check_holidays(APRIL_FOOLS) ? 50 : 0.5)) // Extremely rare chance to replace a normal radio with a toy one, because it's funny + make_silly() /obj/item/radio/Destroy() remove_radio_all(src) //Just to be sure @@ -351,7 +353,8 @@ if(isliving(talking_movable)) var/mob/living/talking_living = talking_movable var/volume_modifier = (talking_living.client?.prefs.read_preference(/datum/preference/numeric/sound_radio_noise)) - if(radio_noise && talking_living.can_hear() && volume_modifier && signal.frequency != FREQ_COMMON && !LAZYACCESS(message_mods, MODE_SEQUENTIAL)) + if(radio_noise && talking_living.can_hear() && volume_modifier && signal.frequency != FREQ_COMMON && !LAZYACCESS(message_mods, MODE_SEQUENTIAL) && COOLDOWN_FINISHED(src, audio_cooldown)) + COOLDOWN_START(src, audio_cooldown, 0.5 SECONDS) var/sound/radio_noise = sound('sound/items/radio/radio_talk.ogg', volume = volume_modifier) radio_noise.frequency = get_rand_frequency_low_range() SEND_SOUND(talking_living, radio_noise) @@ -439,7 +442,7 @@ COOLDOWN_START(src, audio_cooldown, 0.5 SECONDS) var/sound/radio_receive = sound('sound/items/radio/radio_receive.ogg', volume = volume_modifier) radio_receive.frequency = get_rand_frequency_low_range() - SEND_SOUND(holder, radio_noise) + SEND_SOUND(holder, radio_receive) if((SPAN_COMMAND in spans) && COOLDOWN_FINISHED(src, important_audio_cooldown)) COOLDOWN_START(src, important_audio_cooldown, 0.5 SECONDS) var/sound/radio_important = sound('sound/items/radio/radio_important.ogg', volume = volume_modifier) @@ -577,6 +580,15 @@ set_on(TRUE) return TRUE +/obj/item/radio/proc/make_silly() + name = "\improper Little-Crew: Assistant's First Radio" + icon_state = "walkieian" + desc = "A Little-Crew branded toy radio in the shape of a lovable pet. After Little-Crew HQ was hit with a Donksoft Nuke, these have become collector's items!" + overlay_speaker_idle = null + overlay_speaker_active = null + overlay_mic_idle = null + overlay_mic_active = null + /////////////////////////////// //////////Borg Radios////////// /////////////////////////////// @@ -705,4 +717,9 @@ inhand_icon_state = "microphone" canhear_range = 3 +// In case you want to map it in/spawn it for some reason +/obj/item/radio/toy/Initialize(mapload) + . = ..() + make_silly() + #undef FREQ_LISTENING diff --git a/code/game/objects/items/devices/scanners/gas_analyzer.dm b/code/game/objects/items/devices/scanners/gas_analyzer.dm index 112833877c4d3..8fc6ff4426bba 100644 --- a/code/game/objects/items/devices/scanners/gas_analyzer.dm +++ b/code/game/objects/items/devices/scanners/gas_analyzer.dm @@ -220,7 +220,7 @@ message += span_notice("Volume: [volume] L") // don't want to change the order volume appears in, suck it // we let the join apply newlines so we do need handholding - to_chat(user, examine_block(jointext(message, "\n")), type = MESSAGE_TYPE_INFO) + to_chat(user, boxed_message(jointext(message, "\n")), type = MESSAGE_TYPE_INFO) return TRUE /obj/item/analyzer/ranged diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index 3535bef007407..83d7df3a75a05 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -81,7 +81,7 @@ floor_text += "Body temperature: [scan_turf?.return_air()?.return_temperature() || "???"]
" if(user.can_read(src) && !user.is_blind()) - to_chat(user, examine_block(floor_text)) + to_chat(user, custom_boxed_message("blue_box", floor_text)) last_scan_text = floor_text return @@ -410,7 +410,7 @@ . = jointext(render_list, "") if(tochat) - to_chat(user, examine_block(.), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) + to_chat(user, custom_boxed_message("blue_box", .), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) return . /obj/item/healthanalyzer/click_ctrl_shift(mob/user) @@ -507,7 +507,7 @@ render_list += "[allergies]
" // we handled the last
so we don't need handholding - to_chat(user, examine_block(jointext(render_list, "")), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) + to_chat(user, custom_boxed_message("blue_box", jointext(render_list, "")), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) /obj/item/healthanalyzer/click_alt(mob/user) if(mode == SCANNER_NO_MODE) @@ -558,7 +558,7 @@ simple_scanner.show_emotion(AID_EMOTION_HAPPY) to_chat(user, "No wounds detected in subject.") else - to_chat(user, examine_block(jointext(render_list, "")), type = MESSAGE_TYPE_INFO) + to_chat(user, custom_boxed_message("blue_box", jointext(render_list, "")), type = MESSAGE_TYPE_INFO) if(simple_scan) var/obj/item/healthanalyzer/simple/simple_scanner = scanner simple_scanner.show_emotion(AID_EMOTION_WARN) diff --git a/code/game/objects/items/devices/scanners/slime_scanner.dm b/code/game/objects/items/devices/scanners/slime_scanner.dm index 79050f0a78c67..c355da8ba7d4a 100644 --- a/code/game/objects/items/devices/scanners/slime_scanner.dm +++ b/code/game/objects/items/devices/scanners/slime_scanner.dm @@ -57,4 +57,4 @@ to_render += "\n[span_notice("Core mutation in progress: [scanned_slime.crossbreed_modification]")]\ \n[span_notice("Progress in core mutation: [scanned_slime.applied_crossbreed_amount] / [SLIME_EXTRACT_CROSSING_REQUIRED]")]" - to_chat(user, examine_block(jointext(to_render,""))) + to_chat(user, boxed_message(jointext(to_render,""))) diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 4f0c0a84aa317..ffa172707bc7f 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -245,7 +245,7 @@ if(attached_device) if(issignaler(attached_device)) var/obj/item/assembly/signaler/attached_signaller = attached_device - attachment = "[attached_signaller]" + attachment = "[attached_signaller]" attachment_signal_log = attached_signaller.last_receive_signal_log ? "The following log entry is the last one associated with the attached signaller
[attached_signaller.last_receive_signal_log]" : "There is no signal log entry." else attachment = attached_device diff --git a/code/game/objects/items/hand_items.dm b/code/game/objects/items/hand_items.dm index a1c3e29e3067a..9b5fd8e0fe642 100644 --- a/code/game/objects/items/hand_items.dm +++ b/code/game/objects/items/hand_items.dm @@ -539,6 +539,12 @@ color = COLOR_SYNDIE_RED kiss_type = /obj/projectile/kiss/syndie +/obj/item/hand_item/kisser/ink + name = "ink kiss" + desc = "Is that a blot of ink in your pocket or are you just happy to see me?" + color = COLOR_ALMOST_BLACK + kiss_type = /obj/projectile/kiss/ink + /obj/projectile/kiss name = "kiss" icon = 'icons/mob/simple/animal.dmi' @@ -640,6 +646,22 @@ var/obj/item/organ/heart/dont_go_breakin_my_heart = heartbreakee.get_organ_slot(ORGAN_SLOT_HEART) dont_go_breakin_my_heart.apply_organ_damage(999) +/obj/projectile/kiss/ink + name = "ink kiss" + color = COLOR_ALMOST_BLACK + damage = /obj/projectile/ink_spit::damage + damage_type = /obj/projectile/ink_spit::damage_type + armor_flag = /obj/projectile/ink_spit::armor_flag + armour_penetration = /obj/projectile/ink_spit::armour_penetration + impact_effect_type = /obj/projectile/ink_spit::impact_effect_type + hitsound = /obj/projectile/ink_spit::hitsound + hitsound_wall = /obj/projectile/ink_spit::hitsound_wall + +/obj/projectile/kiss/ink/on_hit(atom/target, blocked, pierce_hit) + . = ..() + var/obj/projectile/ink_spit/ink_spit = new (target) + ink_spit.on_hit(target) + // Based on energy gun characteristics /obj/projectile/kiss/syndie name = "syndie kiss" diff --git a/code/game/objects/items/rcd/RCD.dm b/code/game/objects/items/rcd/RCD.dm index 60f84e14651b9..3dab53cb8ff27 100644 --- a/code/game/objects/items/rcd/RCD.dm +++ b/code/game/objects/items/rcd/RCD.dm @@ -565,6 +565,18 @@ return owner.ui_status(user) return UI_CLOSE +/obj/item/construction/rcd/exosuit/build_delay(mob/user, delay, atom/target) + if(delay <= 0) + return TRUE + + var/obj/item/mecha_parts/mecha_equipment/rcd/module = loc + + //deconstruction can't be cancelled by ui changes + if(mode != RCD_DECONSTRUCT) + blueprint_changed = FALSE + + return module.do_after_mecha(target, user, delay) + /obj/item/construction/rcd/exosuit/get_matter(mob/user) if(silo_link) return ..() diff --git a/code/game/objects/items/rcd/RHD.dm b/code/game/objects/items/rcd/RHD.dm index ce9f211b6942e..85cdc21947b6d 100644 --- a/code/game/objects/items/rcd/RHD.dm +++ b/code/game/objects/items/rcd/RHD.dm @@ -63,6 +63,8 @@ return do_after(user, delay, target, extra_checks = CALLBACK(src, PROC_REF(blueprint_change))) /obj/item/construction/proc/blueprint_change() + PRIVATE_PROC(TRUE) + return !blueprint_changed ///used for examining the RCD and for its UI diff --git a/code/game/objects/items/rollertable_dock.dm b/code/game/objects/items/rollertable_dock.dm index d0067e8c67596..9b2c34bc61b41 100644 --- a/code/game/objects/items/rollertable_dock.dm +++ b/code/game/objects/items/rollertable_dock.dm @@ -9,23 +9,6 @@ . = ..() loaded = new(src) -/obj/structure/table/rolling/attackby(obj/item/wtable, mob/user, params) - if(!istype(wtable, /obj/item/rolling_table_dock)) - return ..() - var/obj/item/rolling_table_dock/rable = wtable - var/turf/target_table = get_turf(src) - if(rable.loaded) - to_chat(user, span_warning("You already have a roller table docked!")) - return - if(locate(/mob/living) in target_table) - to_chat(user, span_warning("You can't collect the table with that much on top!")) - return - else - rable.loaded = src - forceMove(rable) - user.visible_message(span_notice("[user] collects [src]."), balloon_alert(user, "you collect the [src].")) - return TRUE - /obj/item/rolling_table_dock/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) var/turf/target_turf = get_turf(interacting_with) if(target_turf.is_blocked_turf(TRUE) || (locate(/mob/living) in target_turf)) diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 0374b7a3744e7..b3fac29554de6 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -463,6 +463,78 @@ for(var/i in 1 to 3) new extra_to_spawn (src) +/obj/item/storage/toolbox/guncase/traitor + name = "makarov gun case" + desc = "A weapon's case. Has a blood-red 'S' stamped on the cover. There seems to be a strange switch along the side inside a plastic flap." + icon_state = "pistol_case" + base_icon_state = "pistol_case" + // What ammo box do we spawn in our case? + var/ammo_box_to_spawn = /obj/item/ammo_box/c9mm + // Timer for the bomb in the case. + var/explosion_timer + // Whether or not our case is exploding. Used for determining sprite changes. + var/currently_exploding = FALSE + +/obj/item/storage/toolbox/guncase/traitor/Initialize(mapload) + . = ..() + register_context() + +/obj/item/storage/toolbox/guncase/traitor/examine(mob/user) + . = ..() + . += span_notice("Activate the Evidence Disposal Explosive using Alt-Right-Click.") + +/obj/item/storage/toolbox/guncase/traitor/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + + context[SCREENTIP_CONTEXT_ALT_RMB] = "Activate Evidence Disposal Explosive" + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/storage/toolbox/guncase/traitor/PopulateContents() + new weapon_to_spawn (src) + for(var/i in 1 to 2) + new extra_to_spawn (src) + new ammo_box_to_spawn(src) + +/obj/item/storage/toolbox/guncase/traitor/update_icon_state() + . = ..() + if(currently_exploding) + icon_state = "[base_icon_state]_exploding" + else + icon_state = "[base_icon_state]" + +/obj/item/storage/toolbox/guncase/traitor/click_alt_secondary(mob/user) + . = ..() + var/i_dont_even_think_once_about_blowing_stuff_up = tgui_alert(user, "Would you like to activate the evidence disposal bomb now?", "BYE BYE", list("Yes","No")) + if(i_dont_even_think_once_about_blowing_stuff_up == "No") + return + explosion_timer = addtimer(CALLBACK(src, PROC_REF(think_fast_chucklenuts)), 5 SECONDS, (TIMER_UNIQUE|TIMER_OVERRIDE)) + to_chat(user, span_warning("You prime [src]'s evidence disposal bomb!")) + log_bomber(user, "has activated a", src, "for detonation") + playsound(src, 'sound/items/weapons/armbomb.ogg', 50, TRUE) + currently_exploding = TRUE + update_appearance() + +/// proc to handle our detonation +/obj/item/storage/toolbox/guncase/traitor/proc/think_fast_chucklenuts() + explosion(src, devastation_range = 0, heavy_impact_range = 0, light_impact_range = 2, explosion_cause = src) + qdel(src) + +/obj/item/storage/toolbox/guncase/traitor/ammunition + name = "makarov 9mm magazine case" + weapon_to_spawn = /obj/item/ammo_box/magazine/m9mm + +/obj/item/storage/toolbox/guncase/traitor/donksoft + name = "\improper Donksoft riot pistol gun case" + weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/toy/riot/clandestine + extra_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot + ammo_box_to_spawn = /obj/item/ammo_box/foambox/riot + +/obj/item/storage/toolbox/guncase/traitor/ammunition/donksoft + name = "\improper Donksoft riot pistol magazine case" + weapon_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot + extra_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot + ammo_box_to_spawn = /obj/item/ammo_box/foambox/riot + /obj/item/storage/toolbox/guncase/bulldog name = "bulldog gun case" weapon_to_spawn = /obj/item/gun/ballistic/shotgun/bulldog diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 6fca04c7a3f40..ad62f3c086735 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -179,7 +179,17 @@ var/area/computer_area = get_area(target) if(!computer_area || (computer_area.area_flags & NOTELEPORT)) continue - if(computer.power_station?.teleporter_hub && computer.power_station.engaged) + + if(!computer.power_station || !computer.power_station.teleporter_hub) + continue + + if((computer.power_station.machine_stat & (NOPOWER|BROKEN|MAINT)) || computer.power_station.panel_open) + continue + + if((computer.power_station.teleporter_hub.machine_stat & (NOPOWER|BROKEN|MAINT)) || computer.power_station.teleporter_hub.panel_open) + continue + + if(computer.power_station.engaged) locations["[get_area(target)] (Active)"] = computer else locations["[get_area(target)] (Inactive)"] = computer diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index bc34783a853e1..3e03cd7709788 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -464,12 +464,12 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' desc = "Uncanny looking hammer." - force = 20 - throwforce = 20 + force = 17 + throwforce = 14 throw_range = 4 w_class = WEIGHT_CLASS_NORMAL wound_bonus = 20 - demolition_mod = 1.25 + demolition_mod = 1.15 slot_flags = ITEM_SLOT_BELT /obj/item/carpenter_hammer/Initialize(mapload) @@ -954,13 +954,12 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/melee/baseball_bat/Initialize(mapload) . = ..() - if(prob(1)) - name = "cricket bat" - icon_state = "baseball_bat_brit" - inhand_icon_state = "baseball_bat_brit" - desc = pick("You've got red on you.", "You gotta know what a crumpet is to understand cricket.") - AddElement(/datum/element/kneecapping) + // No subtypes + if(type != /obj/item/melee/baseball_bat) + return + if(prob(check_holidays(APRIL_FOOLS) ? 50 : 1)) + make_silly() /obj/item/melee/baseball_bat/attack_self(mob/user) if(!homerun_able) @@ -1048,6 +1047,12 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 target.throw_at(target_turf, get_dist(target, target_turf), datum_throw_speed + 1, user, callback = CALLBACK(src, PROC_REF(on_hit), target)) thrown_datums[target] = target.throwing +/obj/item/melee/baseball_bat/proc/make_silly() + name = "cricket bat" + icon_state = "baseball_bat_brit" + inhand_icon_state = "baseball_bat_brit" + desc = pick("You've got red on you.", "You gotta know what a crumpet is to understand cricket.") + /obj/item/melee/baseball_bat/proc/on_hit(atom/movable/target) target.remove_filter("baseball_launch") target.throwforce *= 0.5 @@ -1076,6 +1081,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers return TRUE +// In case you ever want to spawn it via map/admin console +/obj/item/melee/baseball_bat/british/Initialize(mapload) + . = ..() + make_silly() + /obj/item/melee/flyswatter name = "flyswatter" desc = "Useful for killing pests of all sizes." diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 207b85122dd21..edfbe8e38c0e4 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -1222,4 +1222,14 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) /obj/structure/closet/proc/add_to_roundstart_list() GLOB.roundstart_station_closets += src +///Spears deal bonus damages to lockers +/obj/structure/closet/attacked_by(obj/item/attacking_item, mob/living/user) + if(istype(attacking_item, /obj/item/spear)) + take_damage(attacking_item.force * 2, attacking_item.damtype, MELEE, 1, get_dir(src, user)) + user.visible_message(span_danger("[user] stabs with precision [src]'s electronics with [attacking_item]!"), + span_danger("You stab with precision [src]'s electronics with [attacking_item]!"), null, COMBAT_MESSAGE_RANGE) + log_combat(user, src, "attacked", attacking_item) + return + return ..() + #undef LOCKER_FULL diff --git a/code/game/objects/structures/shower.dm b/code/game/objects/structures/shower.dm index ce6c987ba10dd..26d05f6edd178 100644 --- a/code/game/objects/structures/shower.dm +++ b/code/game/objects/structures/shower.dm @@ -273,7 +273,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) if(!radioactive_shower) // note it is possible to have a clean_shower that is radioactive (+70% water mixed with +20% radiation) wash_flags |= CLEAN_RAD - target.wash(wash_flags) + + if (isturf(target)) + target.wash(wash_flags, TRUE) + else + target.wash(wash_flags) reagents.expose(target, (TOUCH), SHOWER_EXPOSURE_MULTIPLIER * SHOWER_SPRAY_VOLUME / max(reagents.total_volume, SHOWER_SPRAY_VOLUME)) if(!isliving(target)) @@ -344,7 +348,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) return mode == SHOWER_MODE_FOREVER ? 0 : PROCESS_KILL // Wash up. - wash_atom(loc, TRUE) + wash_atom(loc) reagents.remove_all(SHOWER_SPRAY_VOLUME) /obj/machinery/shower/on_deconstruction(disassembled = TRUE) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 448c3eb5425a7..9adb4f75a2f94 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -390,6 +390,23 @@ LAZYNULL(attached_items) // safety return ..() +/obj/structure/table/rolling/item_interaction(mob/living/user, obj/item/rolling_table_dock/rable, list/modifiers) + . = NONE + if(!istype(rable)) + return + + if(rable.loaded) + to_chat(user, span_warning("You already have \a [rable.loaded] docked!")) + return ITEM_INTERACT_FAILURE + if(locate(/mob/living) in get_turf(src)) + to_chat(user, span_warning("You can't collect \the [src] with that much on top!")) + return ITEM_INTERACT_FAILURE + + rable.loaded = src + forceMove(rable) + user.visible_message(span_notice("[user] collects \the [src]."), span_notice("you collect \the [src].")) + return ITEM_INTERACT_SUCCESS + /obj/structure/table/rolling/AfterPutItemOnTable(obj/item/thing, mob/living/user) . = ..() LAZYADD(attached_items, thing) diff --git a/code/game/objects/structures/votingbox.dm b/code/game/objects/structures/votingbox.dm index 55909978fe2f7..013556febbd52 100644 --- a/code/game/objects/structures/votingbox.dm +++ b/code/game/objects/structures/votingbox.dm @@ -44,13 +44,13 @@ dat += "

Unregistered. Swipe ID card to register as voting box operator

" dat += "

[vote_description]

" if(is_operator(user)) - dat += "Voting: [voting_active ? "Active" : "Maintenance Mode"]
" - dat += "Set Description: Set Description
" - dat += "One vote per ID: [id_auth ? "Yes" : "No"]
" - dat += "Reset voted ID's: Reset
" - dat += "Draw random vote: Raffle
" - dat += "Shred votes: Shred
" - dat += "Tally votes: Tally
" + dat += "Voting: [voting_active ? "Active" : "Maintenance Mode"]
" + dat += "Set Description: Set Description
" + dat += "One vote per ID: [id_auth ? "Yes" : "No"]
" + dat += "Reset voted ID's: Reset
" + dat += "Draw random vote: Raffle
" + dat += "Shred votes: Shred
" + dat += "Tally votes: Tally
" var/datum/browser/popup = new(user, "votebox", "Voting Box", 300, 300) popup.set_content(dat.Join()) diff --git a/code/game/turfs/closed/wall/reinf_walls.dm b/code/game/turfs/closed/wall/reinf_walls.dm index b6882a5fc2779..ca25e8bc605a5 100644 --- a/code/game/turfs/closed/wall/reinf_walls.dm +++ b/code/game/turfs/closed/wall/reinf_walls.dm @@ -215,9 +215,13 @@ dismantle_wall() /turf/closed/wall/r_wall/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - if(the_rcd.canRturf || the_rcd.construction_mode == RCD_WALLFRAME) + if (the_rcd.construction_mode == RCD_WALLFRAME) return ..() - + if(!the_rcd.canRturf) + return + . = ..() + if (.) + .["delay"] *= RCD_RWALL_DELAY_MULT /turf/closed/wall/r_wall/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) if(the_rcd.canRturf || rcd_data["[RCD_DESIGN_MODE]"] == RCD_WALLFRAME) diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index 2ec0b8e9a9c42..a71ed37f374f9 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -266,12 +266,9 @@ /turf/open/lava/proc/can_burn_stuff(atom/movable/burn_target) if(QDELETED(burn_target)) return LAVA_BE_IGNORING - if(burn_target.movement_type & MOVETYPES_NOT_TOUCHING_GROUND || !burn_target.has_gravity()) //you're flying over it. + if((burn_target.movement_type & MOVETYPES_NOT_TOUCHING_GROUND) || burn_target.throwing || !burn_target.has_gravity()) //you're flying over it. return LAVA_BE_IGNORING - if(isobj(burn_target)) - if(burn_target.throwing) // to avoid gulag prisoners easily escaping, throwing only works for objects. - return LAVA_BE_IGNORING var/obj/burn_obj = burn_target if((burn_obj.resistance_flags & immunity_resistance_flags)) return LAVA_BE_PROCESSING @@ -285,7 +282,7 @@ var/mob/living/burn_living = burn_target var/atom/movable/burn_buckled = burn_living.buckled if(burn_buckled) - if(burn_buckled.movement_type & MOVETYPES_NOT_TOUCHING_GROUND || !burn_buckled.has_gravity()) + if((burn_buckled.movement_type & MOVETYPES_NOT_TOUCHING_GROUND) || burn_buckled.throwing || !burn_buckled.has_gravity()) return LAVA_BE_PROCESSING if(isobj(burn_buckled)) var/obj/burn_buckled_obj = burn_buckled diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 3ec07c11ec28c..e82cba73603ad 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -21,27 +21,27 @@ var/dat = "
Game Panel

" if(SSticker.current_state <= GAME_STATE_PREGAME) - dat += "(Manage Dynamic Rulesets)
" - dat += "(Force Roundstart Rulesets)
" + dat += "(Manage Dynamic Rulesets)
" + dat += "(Force Roundstart Rulesets)
" if (GLOB.dynamic_forced_roundstart_ruleset.len > 0) for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset) - dat += {"-> [rule.name] <-
"} - dat += "(Clear Rulesets)
" - dat += "(Dynamic mode options)
" + dat += {"-> [rule.name] <-
"} + dat += "(Clear Rulesets)
" + dat += "(Dynamic mode options)
" dat += "
" if(SSticker.IsRoundInProgress()) - dat += "(Game Mode Panel)
" - dat += "(Manage Dynamic Rulesets)
" + dat += "(Game Mode Panel)
" + dat += "(Manage Dynamic Rulesets)
" dat += {"
- Create Object
- Quick Create Object
- Create Turf
- Create Mob
+ Create Object
+ Quick Create Object
+ Create Turf
+ Create Mob
"} if(marked_datum && istype(marked_datum, /atom)) - dat += "Duplicate Marked Datum
" + dat += "Duplicate Marked Datum
" usr << browse(dat, "window=admin2;size=240x280") return @@ -110,17 +110,17 @@ ADMIN_VERB(spawn_cargo, R_SPAWN, "Spawn Cargo", "Spawn a cargo crate.", ADMIN_CA

Common options

All these options can be changed midround.

- Force extended: - Option is [GLOB.dynamic_forced_extended ? "ON" : "OFF"]. + Force extended: - Option is [GLOB.dynamic_forced_extended ? "ON" : "OFF"].
This will force the round to be extended. No rulesets will be drafted.

- No stacking: - Option is [GLOB.dynamic_no_stacking ? "ON" : "OFF"]. + No stacking: - Option is [GLOB.dynamic_no_stacking ? "ON" : "OFF"].
Unless the threat goes above [GLOB.dynamic_stacking_limit], only one "round-ender" ruleset will be drafted.

- Forced threat level: Current value : [GLOB.dynamic_forced_threat_level]. + Forced threat level: Current value : [GLOB.dynamic_forced_threat_level].
The value threat is set to if it is higher than -1.


- Stacking threeshold: Current value : [GLOB.dynamic_stacking_limit]. + Stacking threeshold: Current value : [GLOB.dynamic_stacking_limit].
The threshold at which "round-ender" rulesets will stack. A value higher than 100 ensure this never happens.
"} @@ -131,9 +131,9 @@ ADMIN_VERB(spawn_cargo, R_SPAWN, "Spawn Cargo", "Spawn a cargo crate.", ADMIN_CA Change these options to forcibly enable or disable dynamic rulesets.
\ Disabled rulesets will never run, even if they would otherwise be valid.
\ Enabled rulesets will run even if the qualifying minimum of threat or player count is not present, this does not guarantee that they will necessarily be chosen (for example their weight may be set to 0 in config).
\ - \[force enable all / \ - force disable all / \ - reset all\]" + \[force enable all / \ + force disable all / \ + reset all\]" if (SSticker.current_state <= GAME_STATE_PREGAME) // Don't bother displaying after the round has started var/static/list/rulesets_by_context = list() @@ -166,9 +166,9 @@ ADMIN_VERB(spawn_cargo, R_SPAWN, "Spawn Cargo", "Spawn a cargo crate.", ADMIN_CA if (RULESET_FORCE_DISABLED) color = COLOR_RED dat += "[initial(rule.name)]\[[forced]\]\[\ - force enabled /\ - force disabled /\ - reset\]" + force enabled /\ + force disabled /\ + reset\]" dat += "" return dat @@ -199,10 +199,10 @@ ADMIN_VERB(spawn_cargo, R_SPAWN, "Spawn Cargo", "Spawn a cargo crate.", ADMIN_CA dat += "[rule.name]\ \[Weight : [rule.weight]\]\ \[[active][explanation]\]\[\ - force enabled /\ - force disabled /\ - reset\]\ - \[VV\]" + force enabled /\ + force disabled /\ + reset\]\ + \[VV\]" dat += "" return dat diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm index e348321326473..33d12f9be22bc 100644 --- a/code/modules/admin/antag_panel.dm +++ b/code/modules/admin/antag_panel.dm @@ -30,7 +30,7 @@ GLOBAL_VAR(antag_prototypes) /datum/antagonist/proc/antag_panel() var/list/commands = list() for(var/command in get_admin_commands()) - commands += "[command]" + commands += "[command]" var/command_part = commands.Join(" | ") var/data_part = antag_panel_data() var/objective_part = antag_panel_objectives() @@ -47,30 +47,30 @@ GLOBAL_VAR(antag_prototypes) var/obj_count = 1 for(var/datum/objective/objective as anything in objectives) result += "[obj_count]: [objective.explanation_text] \ - Edit \ - Delete \ - [objective.completed ? "Mark as incomplete" : "Mark as complete"] \ + Edit \ + Delete \ + [objective.completed ? "Mark as incomplete" : "Mark as complete"] \
" obj_count++ - result += "Add objective
" - result += "Prompt custom objective entry
" - result += "Announce objectives
" + result += "Add objective
" + result += "Prompt custom objective entry
" + result += "Announce objectives
" return result /datum/mind/proc/get_common_admin_commands() var/common_commands = "Common Commands:" if(ishuman(current)) - common_commands += "undress" + common_commands += "undress" else if(iscyborg(current)) var/mob/living/silicon/robot/R = current if(R.emagged) - common_commands += "Unemag" + common_commands += "Unemag" else if(isAI(current)) var/mob/living/silicon/ai/A = current if (A.connected_robots.len) for (var/mob/living/silicon/robot/R in A.connected_robots) if (R.emagged) - common_commands += "Unemag slaved cyborgs" + common_commands += "Unemag slaved cyborgs" break return common_commands @@ -99,9 +99,9 @@ GLOBAL_VAR(antag_prototypes) var/out = "[name][(current && (current.real_name != name))?" (as [current.real_name])":""]
" out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
" - out += "Assigned role: [assigned_role.title]. Edit
" + out += "Assigned role: [assigned_role.title]. Edit
" out += "Faction and special role: [special_role]
" - out += "Show Teams

" + out += "Show Teams

" var/special_statuses = get_special_statuses() if(length(special_statuses)) @@ -138,7 +138,7 @@ GLOBAL_VAR(antag_prototypes) continue //Let's skip subtypes of what we already shown. else if(prototype.show_in_antagpanel) if(prototype.can_be_owned(src)) - possible_admin_antags += "[prototype.name]" + possible_admin_antags += "[prototype.name]" else possible_admin_antags += "[prototype.name]" else @@ -155,8 +155,8 @@ GLOBAL_VAR(antag_prototypes) else //Show removal and current one priority_sections |= antag_category antag_header_parts += span_bad("[current_antag.name]") - antag_header_parts += "Remove" - antag_header_parts += "Open VV" + antag_header_parts += "Remove" + antag_header_parts += "Open VV" //We aren't antag of this category, grab first prototype to check the prefs (This is pretty vague but really not sure how else to do this) @@ -196,19 +196,19 @@ GLOBAL_VAR(antag_prototypes) var/datum/component/uplink/U = find_syndicate_uplink() if(U) if(!U.uplink_handler.has_objectives) - uplink_info += "take" + uplink_info += "take" if (check_rights(R_FUN, 0)) - uplink_info += ", [U.uplink_handler.telecrystals] TC" + uplink_info += ", [U.uplink_handler.telecrystals] TC" if(U.uplink_handler.has_progression) - uplink_info += ", [U.uplink_handler.progression_points] PR" + uplink_info += ", [U.uplink_handler.progression_points] PR" if(U.uplink_handler.has_objectives) - uplink_info += ", Force Give Objective" + uplink_info += ", Force Give Objective" else uplink_info += ", [U.uplink_handler.telecrystals] TC" if(U.uplink_handler.has_progression) uplink_info += ", [U.uplink_handler.progression_points] PR" else - uplink_info += "give" + uplink_info += "give" uplink_info += "." //hiel grammar out += uplink_info + "
" diff --git a/code/modules/admin/check_antagonists.dm b/code/modules/admin/check_antagonists.dm index 04db519ffb50a..30071504c9199 100644 --- a/code/modules/admin/check_antagonists.dm +++ b/code/modules/admin/check_antagonists.dm @@ -5,9 +5,9 @@ if(!owner) return "Unassigned" if(owner.current) - return "[owner.current.real_name] " + return "[owner.current.real_name] " else - return "[owner.name] " + return "[owner.name] " //Whatever interesting things happened to the antag admins should know about //Include additional information about antag in this part @@ -28,12 +28,12 @@ if(!owner) return var/list/parts = list() - parts += "PM" + parts += "PM" if(owner.current) //There's body to follow - parts += "FLW" + parts += "FLW" else parts += "" - parts += "Show Objective" + parts += "Show Objective" return parts //Better as one cell or two/three //Builds table row for the antag @@ -95,26 +95,26 @@ tgui_alert(usr, "The game hasn't started yet!") return var/list/dat = list("Round Status

Round Status

") - dat += "Game Mode Panel
" + dat += "Game Mode Panel
" dat += "Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]
" dat += "Emergency shuttle
" if(EMERGENCY_IDLE_OR_RECALLED) - dat += "Call Shuttle
" + dat += "Call Shuttle
" else var/timeleft = SSshuttle.emergency.timeLeft() if(SSshuttle.emergency.mode == SHUTTLE_CALL) - dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
" - dat += "Send Back
" + dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
" + dat += "Send Back
" else - dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
" - dat += "End Round Now
" + dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
" + dat += "End Round Now
" if(SSticker.delay_end) - dat += "Undelay Round End
" + dat += "Undelay Round End
" else - dat += "Delay Round End
" - dat += "Enable/Disable CTF
" - dat += "Reboot World
" - dat += "Check Teams" + dat += "Delay Round End
" + dat += "Enable/Disable CTF
" + dat += "Reboot World
" + dat += "Check Teams" var/connected_players = GLOB.clients.len var/lobby_players = 0 var/observers = 0 diff --git a/code/modules/admin/greyscale_modify_menu.dm b/code/modules/admin/greyscale_modify_menu.dm index 0bc1ec01f5d4f..c87c424661fd2 100644 --- a/code/modules/admin/greyscale_modify_menu.dm +++ b/code/modules/admin/greyscale_modify_menu.dm @@ -241,14 +241,24 @@ This is highly likely to cause massive amounts of lag as every object in the gam config.EnableAutoRefresh(config_owner_type) /datum/greyscale_modify_menu/proc/ReadColorsFromString(colorString) - var/list/new_split_colors = list() + //length validation var/list/colors = splittext(colorString, "#") - for(var/index in 2 to min(length(colors), config.expected_colors + 1)) + if(length(colors) <= 1) //doesn't even begin with a # so isn't even a color + return FALSE + colors.Cut(1, 2) //removes the white space as a consequence of the string beginning with a # + if(colors.len != config.expected_colors) //not the expected length + return FALSE + + //value validation + var/list/new_split_colors = list() + for(var/index in 1 to config.expected_colors) var/color = "#[colors[index]]" if(!findtext(color, GLOB.is_color) && (!unlocked || !findtext(color, GLOB.is_alpha_color))) return FALSE new_split_colors += color split_colors = new_split_colors + + //all good return TRUE /datum/greyscale_modify_menu/proc/randomize_color(color_index) diff --git a/code/modules/admin/known_alts.dm b/code/modules/admin/known_alts.dm index 4105c7f4edc93..3c51ca68bdf1b 100644 --- a/code/modules/admin/known_alts.dm +++ b/code/modules/admin/known_alts.dm @@ -168,7 +168,7 @@ GLOBAL_DATUM_INIT(known_alts, /datum/known_alts, new) var/list/known_alts_html = list() for (var/known_alt in load_known_alts()) - known_alts_html += "\[-\] Delete [known_alt[1]] is an alt of [known_alt[2]] (added by [known_alt[3]])." + known_alts_html += "\[-\] Delete [known_alt[1]] is an alt of [known_alt[2]] (added by [known_alt[3]])." var/html = {" @@ -179,7 +179,7 @@ GLOBAL_DATUM_INIT(known_alts, /datum/known_alts, new)

Any two ckeys in this panel will not show in "banned connection history".

Sometimes players switch account, and it's customary to perma-ban the old one.

-

All Known Alts:

\[+\] Add
+

All Known Alts:

\[+\] Add
[known_alts_html.Join("
")] diff --git a/code/modules/admin/permissionedit.dm b/code/modules/admin/permissionedit.dm index 6bd97dcaa2005..e474fcff0955d 100644 --- a/code/modules/admin/permissionedit.dm +++ b/code/modules/admin/permissionedit.dm @@ -7,11 +7,11 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm return var/datum/asset/asset_cache_datum = get_asset_datum(/datum/asset/group/permissions) asset_cache_datum.send(usr) - var/list/output = list("\[Permissions\]") + var/list/output = list("\[Permissions\]") if(action) - output += " | \[Log\] | \[Management\]
" + output += " | \[Log\] | \[Management\]
" else - output += "
\[Log\]
\[Management\]" + output += "
\[Log\]
\[Management\]" if(action == 1) var/logcount = 0 var/logssperpage = 20 @@ -30,7 +30,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm if(logcount > logssperpage) output += "
Page: " while(logcount > 0) - output += "|[pagecount == page ? "\[[pagecount]\]" : "\[[pagecount]\]"]" + output += "|[pagecount == page ? "\[[pagecount]\]" : "\[[pagecount]\]"]" logcount -= logssperpage pagecount++ output += "|" @@ -69,7 +69,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm while(query_check_admin_errors.NextRow()) var/admin_key = query_check_admin_errors.item[1] var/admin_rank = query_check_admin_errors.item[2] - output += "[admin_key] has non-existent rank [admin_rank] | \[Change Rank\] | \[Remove\]" + output += "[admin_key] has non-existent rank [admin_rank] | \[Change Rank\] | \[Remove\]" output += "
" qdel(query_check_admin_errors) output += "

Unused ranks

" @@ -79,7 +79,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm return while(query_check_unused_rank.NextRow()) var/admin_rank = query_check_unused_rank.item[1] - output += {"Rank [admin_rank] is not held by any admin | \[Remove\] + output += {"Rank [admin_rank] is not held by any admin | \[Remove\]
Permissions: [rights2text(text2num(query_check_unused_rank.item[2])," ")]
Denied: [rights2text(text2num(query_check_unused_rank.item[3])," ", "-")]
Allowed to edit: [rights2text(text2num(query_check_unused_rank.item[4])," ", "*")] @@ -95,7 +95,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm
- + @@ -110,18 +110,18 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm if(D.owner) adm_ckey = D.owner.key if (D.deadmined) - deadminlink = " \[RA\]" + deadminlink = " \[RA\]" else - deadminlink = " \[DA\]" + deadminlink = " \[DA\]" var/verify_link = "" if (D.blocked_by_2fa) - verify_link += " | \[2FA VERIFY\]" + verify_link += " | \[2FA VERIFY\]" output += "" - output += "" - output += "" - output += "" + output += "" + output += "" + output += "" output += "" output += "
CKEY \[+\]CKEY \[+\] RANK PERMISSIONS
[adm_ckey]
[deadminlink]\[-\]\[SYNC TGDB\][verify_link]
[D.rank_names()][rights2text(D.rank_flags(), " ")][adm_ckey]
[deadminlink]\[-\]\[SYNC TGDB\][verify_link]
[D.rank_names()][rights2text(D.rank_flags(), " ")]
Search:
" if(QDELETED(usr)) @@ -140,7 +140,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm permissions_assets.send(usr.client) var/admin_key = href_list["key"] var/admin_ckey = ckey(admin_key) - + var/task = href_list["editrights"] var/datum/admins/target_admin_datum = GLOB.admin_datums[admin_ckey] if(!target_admin_datum) @@ -178,7 +178,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm use_db = FALSE if(QDELETED(usr)) return - + if(target_admin_datum && (task != "sync" && task != "verify") && !check_if_greater_rights_than_holder(target_admin_datum)) message_admins("[key_name_admin(usr)] attempted to change the rank of [admin_key] without sufficient rights.") log_admin("[key_name(usr)] attempted to change the rank of [admin_key] without sufficient rights.") diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 31c34957544e4..ddb02b78b8acc 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -80,19 +80,19 @@ body += ""; - body += "PP - " - body += "N - " - body += "VV - " - body += "SP - " - body += "TP - " + body += "PP - " + body += "N - " + body += "VV - " + body += "SP - " + body += "TP - " if (job == "Cyborg") - body += "BP - " - body += "PM - " - body += "SM - " - body += "FLW - " - body += "LOGS
" + body += "BP - " + body += "PM - " + body += "SM - " + body += "FLW - " + body += "LOGS
" if(antagonist > 0) - body += "Antagonist"; + body += "Antagonist"; body += ""; @@ -198,7 +198,7 @@ Player panel
- Hover over a line to see more information - Check antagonists - Kick everyone/AFKers in lobby + Hover over a line to see more information - Check antagonists - Kick everyone/AFKers in lobby

diff --git a/code/modules/admin/poll_management.dm b/code/modules/admin/poll_management.dm index 86f075d311340..88a38c90166b4 100644 --- a/code/modules/admin/poll_management.dm +++ b/code/modules/admin/poll_management.dm @@ -71,12 +71,12 @@ * */ /datum/admins/proc/poll_list_panel() - var/list/output = list("Current and future polls
Note when editing polls or their options changes are not saved until you press Submit Poll.
New PollReload Polls


") + var/list/output = list("Current and future polls
Note when editing polls or their options changes are not saved until you press Submit Poll.
New PollReload Polls
") for(var/p in GLOB.polls) var/datum/poll_question/poll = p output += {"[poll.question] - Edit - Delete + Edit + Delete "} if(poll.subtitle) output += "
[poll.subtitle]" @@ -204,20 +204,20 @@
"} if(poll.poll_type == POLLTYPE_TEXT) - output += "Clear poll responses [poll.poll_votes] players have responded" + output += "Clear poll responses [poll.poll_votes] players have responded" else - output += "Clear poll votes [poll.poll_votes] players have voted" + output += "Clear poll votes [poll.poll_votes] players have voted" if(poll.poll_type == POLLTYPE_TEXT) output += "" else - output += "
Add Option
" + output += "
Add Option
" if(length(poll.options)) for(var/o in poll.options) var/datum/poll_option/option = o option_count++ output += {"Option [option_count] - Edit - Delete + Edit + Delete
[option.text] "} if(poll.poll_type == POLLTYPE_RATING) diff --git a/code/modules/admin/sound_emitter.dm b/code/modules/admin/sound_emitter.dm index 9f1d430a46c03..165b882ab46e7 100644 --- a/code/modules/admin/sound_emitter.dm +++ b/code/modules/admin/sound_emitter.dm @@ -61,16 +61,16 @@ /obj/effect/sound_emitter/proc/edit_emitter(mob/user) var/dat = "" - dat += "Label: [maptext ? maptext : "No label set!"]
" + dat += "Label: [maptext ? maptext : "No label set!"]
" dat += "
" - dat += "Sound File: [sound_file ? sound_file : "No file chosen!"]
" - dat += "Volume: [sound_volume]%
" + dat += "Sound File: [sound_file ? sound_file : "No file chosen!"]
" + dat += "Volume: [sound_volume]%
" dat += "
" - dat += "Mode: [motus_operandi]
" + dat += "Mode: [motus_operandi]
" if(motus_operandi != SOUND_EMITTER_LOCAL) - dat += "Range: [emitter_range][emitter_range == SOUND_EMITTER_RADIUS ? "[play_radius]-tile radius" : ""]
" + dat += "Range: [emitter_range][emitter_range == SOUND_EMITTER_RADIUS ? "[play_radius]-tile radius" : ""]
" dat += "
" - dat += "Play Sound (interrupts other sound emitter sounds)" + dat += "Play Sound (interrupts other sound emitter sounds)" var/datum/browser/popup = new(user, "emitter", "", 500, 600) popup.set_content(dat) popup.open() diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm index 74955324dffd4..a8f16e92daa11 100644 --- a/code/modules/admin/sql_ban_system.dm +++ b/code/modules/admin/sql_ban_system.dm @@ -689,7 +689,7 @@ var/pagecount = 1 var/list/pagelist = list() while(bancount > 0) - pagelist += "[pagecount == page ? "\[[pagecount]\]" : "\[[pagecount]\]"]" + pagelist += "[pagecount == page ? "\[[pagecount]\]" : "\[[pagecount]\]"]" bancount -= bansperpage pagecount++ output += pagelist.Join(" | ") @@ -775,13 +775,13 @@ var/un_or_reban_href if(unban_datetime) - un_or_reban_href = "Reban" + un_or_reban_href = "Reban" else - un_or_reban_href = "Unban" - output += "Edit
[un_or_reban_href]" + un_or_reban_href = "Unban" + output += "Edit
[un_or_reban_href]" if(edits) - output += "
Edit log" + output += "
Edit log" output += "" qdel(query_unban_search_bans) output += "" diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index 7aab49d1c3649..f7d0023534529 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -377,10 +377,10 @@ var/list/output = list() var/ruler = "
" - var/list/navbar = list("All#") + var/list/navbar = list("All#") for(var/letter in GLOB.alphabet) - navbar += "[letter]" - navbar += "MemosWatchlist" + navbar += "[letter]" + navbar += "MemosWatchlist" navbar += "
\ \ [HrefTokenFormField()]\ @@ -391,14 +391,14 @@ if(type == "memo" || type == "watchlist entry") if(type == "memo") output += "

Admin memos

" - output += "Add memo
" + output += "Add memo" else if(type == "watchlist entry") output += "

Watchlist entries

" - output += "Add watchlist entry" + output += "Add watchlist entry" if(filter) - output += "Unfilter clients" + output += "Unfilter clients" else - output += "Filter offline clients" + output += "Filter offline clients" output += ruler var/datum/db_query/query_get_type_messages = SSdbcore.NewQuery({" SELECT @@ -444,11 +444,11 @@ if(expire_timestamp) output += " | Expires [expire_timestamp]" output += "" - output += " Change Expiry Time" - output += " Delete" - output += " Edit" + output += " Change Expiry Time" + output += " Delete" + output += " Edit" if(editor_key) - output += " Last edit by [editor_key] (Click here to see edit log)" + output += " Last edit by [editor_key] (Click here to see edit log)" output += "
[text]
" qdel(query_get_type_messages) if(target_ckey) @@ -524,21 +524,21 @@ if(!linkless) if(type == "note") if(severity) - data += "[severity == "none" ? "No" : "[capitalize(severity)]"] Severity" + data += "[severity == "none" ? "No" : "[capitalize(severity)]"] Severity" else - data += "N/A Severity" - data += " Change Expiry Time" - data += " Delete" + data += "N/A Severity" + data += " Change Expiry Time" + data += " Delete" if(type == "note") - data += " [secret ? "Secret" : "Not secret"]" + data += " [secret ? "Secret" : "Not secret"]" if(type == "message sent") data += " Message has been sent" if(editor_key) data += "|" else - data += " Edit" + data += " Edit" if(editor_key) - data += " Last edit by [editor_key] (Click here to see edit log)" + data += " Last edit by [editor_key] (Click here to see edit log)" data += "" data += "

[text]


" switch(type) @@ -563,12 +563,12 @@ qdel(query_get_message_key) output += "

[target_key]

" if(!linkless) - output += "Add note" - output += " Add message" - output += " Add to watchlist" - output += " Refresh page
" + output += "Add note" + output += " Add message" + output += " Add to watchlist" + output += " Refresh page" else - output += " Refresh page" + output += " Refresh page" output += ruler if(messagedata) output += "

Messages

" @@ -582,14 +582,14 @@ if(!linkless) if (agegate) if (skipped) //the first skipped message is still shown so that we can put this link over it. - output += "
Show [skipped] hidden messages
" + output += "
Show [skipped] hidden messages
" else - output += "
Show All
" + output += "
Show All
" else - output += "
Hide Old
" + output += "
Hide Old
" if(index) var/search - output += "
Add messageAdd watchlist entryAdd note
" + output += "
Add messageAdd watchlist entryAdd note
" output += ruler switch(index) if(1) @@ -619,10 +619,10 @@ var/index_key = query_list_messages.item[2] if(!index_key) index_key = index_ckey - output += "[index_key]
" + output += "[index_key]
" qdel(query_list_messages) else if(!type && !target_ckey && !index) - output += "
Add messageAdd watchlist entryAdd note
" + output += "
Add messageAdd watchlist entryAdd note
" output += ruler var/datum/browser/browser = new(usr, "Note panel", "Manage player notes", 1000, 500) notes_assets.send(usr.client) @@ -690,7 +690,7 @@ var/list/text = list() for(var/datum/admin_message/message in get_message_output("message", display_to.ckey)) text += "Admin message left by [span_prefix("[message.admin_key]")] on [message.timestamp]" - text += "
[message.text] (Click here to verify you have read this message)
" + text += "
[message.text] (Click here to verify you have read this message)
" if(length(text)) to_chat(display_to, text.Join()) @@ -707,7 +707,7 @@ for(var/datum/admin_message/message in get_message_output("memo", display_to.ckey)) text += "[span_memo("Memo by [message.admin_key]")] on [message.timestamp]" if(message.editor_key) - text += "
[span_memoedit("Last edit by [message.editor_key] (Click here to see edit log)")]" + text += "
[span_memoedit("Last edit by [message.editor_key] (Click here to see edit log)")]" text += "
[message.text]

" if(length(text)) to_chat(display_to, text.Join()) diff --git a/code/modules/admin/stickyban.dm b/code/modules/admin/stickyban.dm index fede9724ab181..4295080c3f6ca 100644 --- a/code/modules/admin/stickyban.dm +++ b/code/modules/admin/stickyban.dm @@ -348,15 +348,15 @@ return var/timeout if (SSdbcore.Connect()) - timeout = "\[[(ban["timeout"] ? "untimeout" : "timeout" )]\]" + timeout = "\[[(ban["timeout"] ? "untimeout" : "timeout" )]\]" else - timeout = "\[revert\]" + timeout = "\[revert\]" . = list({" - \[-\] + \[-\] [timeout] [ckey]
" - [ban["message"]] \[Edit\]
+ [ban["message"]] \[Edit\]
"}) if (ban["admin"]) . += "[ban["admin"]]
" @@ -366,12 +366,12 @@ for (var/key in ban["keys"]) if (ckey(key) == ckey) continue - . += "
  • \[-\][key]\[E\]
  • " + . += "
  • \[-\][key]\[E\]
  • " for (var/key in ban["whitelist"]) if (ckey(key) == ckey) continue - . += "
  • \[-\][key]\[UE\]
  • " + . += "
  • \[-\][key]\[UE\]
  • " . += "\n" @@ -390,7 +390,7 @@ Sticky Bans -

    All Sticky Bans:

    \[+\]
    +

    All Sticky Bans:

    \[+\]
    [banhtml.Join("")] "} diff --git a/code/modules/admin/tag.dm b/code/modules/admin/tag.dm index e52112eba1495..ec0ed3b56fa7b 100644 --- a/code/modules/admin/tag.dm +++ b/code/modules/admin/tag.dm @@ -40,8 +40,8 @@ to_chat(owner, span_warning("[target_datum] was not already tagged.")) /// Quick define for readability -#define TAG_DEL(X) "(UNTAG)" -#define TAG_MARK(X) "(MARK)" +#define TAG_DEL(X) "(UNTAG)" +#define TAG_MARK(X) "(MARK)" #define TAG_SIMPLE_HEALTH(X) "Health: [X.health]" #define TAG_CARBON_HEALTH(X) "Health: [X.health] (\ [X.getBruteLoss()] \ @@ -56,7 +56,7 @@ ADMIN_VERB(display_tags, R_ADMIN, "View Tags", "Display all of the tagged datums var/list/tagged_datums = user.holder.tagged_datums var/list/marked_datum = user.holder.marked_datum - dat += "
    Refresh
    " + dat += "
    Refresh
    " if(LAZYLEN(tagged_datums)) for(var/datum/iter_datum as anything in tagged_datums) index++ diff --git a/code/modules/admin/team_panel.dm b/code/modules/admin/team_panel.dm index 30311c491e6f2..3eba8be949417 100644 --- a/code/modules/admin/team_panel.dm +++ b/code/modules/admin/team_panel.dm @@ -3,22 +3,22 @@ var/list/content = list() for(var/datum/team/T in GLOB.antagonist_teams) content += "

    [T.name] - [T.type]

    " - content += "Rename" - content += "Delete" - content += "Communicate" + content += "Rename" + content += "Delete" + content += "Communicate" for(var/command in T.get_admin_commands()) - content += "[command]" + content += "[command]" content += "
    " content += "Objectives:
      " for(var/datum/objective/O in T.objectives) - content += "
    1. [O.explanation_text] - Remove
    2. " - content += "
    Add Objective
    " + content += "
  • [O.explanation_text] - Remove
  • " + content += "Add Objective
    " content += "Members:
    Add Member" + content += "
  • [M.name] - Remove Member
  • " + content += "Add Member" content += "
    " - content += "Create Team
    " + content += "Create Team
    " return content.Join() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 6a2666eef9bed..0ea5e67fbf71f 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -847,7 +847,7 @@ exportable_text += "[special_role_description]
    " exportable_text += ADMIN_FULLMONTY_NONAME(subject) - to_chat(src.owner, examine_block(exportable_text), confidential = TRUE) + to_chat(src.owner, boxed_message(exportable_text), confidential = TRUE) else if(href_list["addjobslot"]) if(!check_rights(R_ADMIN)) @@ -1731,7 +1731,7 @@ if(FAX.fax_id != href_list["destination"]) continue FAX.receive(locate(href_list["print_fax"]), href_list["sender_name"]) - + return else if(href_list["play_internet"]) if(!check_rights(R_SOUND)) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index 4ee2b79f04459..f74df71272106 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -722,7 +722,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/sdql2_vv_all, new(null /datum/sdql2_query/proc/SDQL_print(object, list/text_list, print_nulls = TRUE) if(isdatum(object)) - text_list += "[REF(object)] : [object]" + text_list += "[REF(object)] : [object]" if(istype(object, /atom)) var/atom/A = object var/turf/T = A.loc diff --git a/code/modules/admin/verbs/admin.dm b/code/modules/admin/verbs/admin.dm index edd362938af58..629423e713faa 100644 --- a/code/modules/admin/verbs/admin.dm +++ b/code/modules/admin/verbs/admin.dm @@ -45,7 +45,7 @@ ADMIN_VERB(cmd_admin_check_player_exp, R_ADMIN, "Player Playtime", "View player var/list/msg = list() msg += "Playtime ReportPlaytime:
    " user << browse(msg.Join(), "window=Player_playtime_check") diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index f9a081445b8ea..8e7fd97cc1f8b 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -12,28 +12,28 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo body += "Options panel for [player]" if(player.client) body += " played by [player.client] " - body += "\[[player.client.holder ? player.client.holder.rank_names() : "Player"]\]" + body += "\[[player.client.holder ? player.client.holder.rank_names() : "Player"]\]" if(CONFIG_GET(flag/use_exp_tracking)) - body += "\[" + player.client.get_exp_living(FALSE) + "\]" + body += "\[" + player.client.get_exp_living(FALSE) + "\]" if(isnewplayer(player)) body += " Hasn't Entered Game " else - body += " \[Heal\] " + body += " \[Heal\] " if(player.ckey) - body += "
    \[Find Updated Panel\]" + body += "
    \[Find Updated Panel\]" if(player.client) body += "
    \[First Seen: [player.client.player_join_date]\]\[Byond account registered on: [player.client.account_join_date]\]" body += "

    CentCom Galactic Ban DB: " if(CONFIG_GET(string/centcom_ban_db)) - body += "Search" + body += "Search" else body += "Disabled" body += "

    Show related accounts by: " - body += "\[ CID | " - body += "IP \]" + body += "\[ CID | " + body += "IP \]" var/full_version = "Unknown" if(player.client.byond_version) full_version = "[player.client.byond_version].[player.client.byond_build ? player.client.byond_build : "xxx"]" @@ -41,24 +41,24 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo body += "

    \[ " - body += "VV - " + body += "VV - " if(player.mind) - body += "TP - " - body += "SKILLS - " + body += "TP - " + body += "SKILLS - " else - body += "Init Mind - " + body += "Init Mind - " if (iscyborg(player)) - body += "BP - " - body += "PM - " - body += "SM - " + body += "BP - " + body += "PM - " + body += "SM - " if (ishuman(player) && player.mind) - body += "HM - " - body += "FLW - " + body += "HM - " + body += "FLW - " //Default to client logs if available var/source = LOGSRC_MOB if(player.ckey) source = LOGSRC_CKEY - body += "LOGS\]
    " + body += "LOGS\]
    " body += "Mob type = [player.type]

    " @@ -71,37 +71,37 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo body += "None?!" body += "

    " - body += "Kick | " + body += "Kick | " if(player.client) - body += "Ban | " + body += "Ban | " else - body += "Ban | " + body += "Ban | " - body += "Notes | Messages | Watchlist | " + body += "Notes | Messages | Watchlist | " if(player.client) - body += "| Prison | " - body += "\ Send back to Lobby | " + body += "| Prison | " + body += "\ Send back to Lobby | " var/muted = player.client.prefs.muted body += "
    Mute: " - body += "\[IC | " - body += "OOC | " - body += "PRAY | " - body += "ADMINHELP | " - body += "WEBREQ | " - body += "DEADCHAT\]" - body += "(toggle all)" + body += "\[IC | " + body += "OOC | " + body += "PRAY | " + body += "ADMINHELP | " + body += "WEBREQ | " + body += "DEADCHAT\]" + body += "(toggle all)" body += "

    " - body += "Jump to | " - body += "Get | " - body += "Send To" + body += "Jump to | " + body += "Get | " + body += "Send To" body += "

    " - body += "Traitor panel | " - body += "Narrate to | " - body += "Subtle message | " - body += "Play sound to | " - body += "Language Menu" + body += "Traitor panel | " + body += "Narrate to | " + body += "Subtle message | " + body += "Play sound to | " + body += "Language Menu" if(player.client) if(!isnewplayer(player)) @@ -110,39 +110,39 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo if(isobserver(player)) body += "Ghost | " else - body += "Make Ghost | " + body += "Make Ghost | " if(ishuman(player) && !ismonkey(player)) body += "Human | " else - body += "Make Human | " + body += "Make Human | " if(ismonkey(player)) body += "Monkey | " else - body += "Make Monkey | " + body += "Make Monkey | " if(iscyborg(player)) body += "Cyborg | " else - body += "Make Cyborg | " + body += "Make Cyborg | " if(isAI(player)) body += "AI" else - body += "Make AI" + body += "Make AI" body += "

    " body += "Other actions:" body += "
    " if(!isnewplayer(player)) - body += "Forcesay | " - body += "Apply Client Quirks | " - body += "Thunderdome 1 | " - body += "Thunderdome 2 | " - body += "Thunderdome Admin | " - body += "Thunderdome Observer | " - body += "Commend Behavior | " + body += "Forcesay | " + body += "Apply Client Quirks | " + body += "Thunderdome 1 | " + body += "Thunderdome 2 | " + body += "Thunderdome Admin | " + body += "Thunderdome Observer | " + body += "Commend Behavior | " body += "
    " body += "" @@ -325,15 +325,15 @@ ADMIN_VERB(manage_job_slots, R_ADMIN, "Manage Job Slots", "Manage the number of dat += "" dat += "" if(job.total_positions >= 0) - dat += "Custom | " - dat += "Add 1 | " + dat += "Custom | " + dat += "Add 1 | " if(job.total_positions > job.current_positions) - dat += "Remove | " + dat += "Remove | " else dat += "Remove | " - dat += "Unlimit" + dat += "Unlimit" else - dat += "Limit" + dat += "Limit" browser.height = min(100 + count * 20, 650) browser.set_content(dat.Join()) @@ -417,20 +417,20 @@ ADMIN_VERB(lag_switch_panel, R_ADMIN, "Show Lag Switches", "Display the controls to_chat(user, span_notice("The Lag Switch subsystem has not yet been initialized.")) return var/list/dat = list("Lag Switches

    Lag (Reduction) Switches

    ") - dat += "Automatic Trigger: [SSlag_switch.auto_switch ? "On" : "Off"]
    " - dat += "Population Threshold: [SSlag_switch.trigger_pop]
    " - dat += "Slowmode Cooldown (toggle On/Off below): [SSlag_switch.slowmode_cooldown/10] seconds
    " - dat += "
    SET ALL MEASURES: ON | OFF
    " - dat += "
    Disable ghosts zoom and t-ray verbs (except staff): [SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] ? "On" : "Off"]
    " - dat += "Disable late joining: [SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "On" : "Off"]
    " + dat += "Automatic Trigger: [SSlag_switch.auto_switch ? "On" : "Off"]
    " + dat += "Population Threshold: [SSlag_switch.trigger_pop]
    " + dat += "Slowmode Cooldown (toggle On/Off below): [SSlag_switch.slowmode_cooldown/10] seconds
    " + dat += "
    SET ALL MEASURES: ON | OFF
    " + dat += "
    Disable ghosts zoom and t-ray verbs (except staff): [SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] ? "On" : "Off"]
    " + dat += "Disable late joining: [SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "On" : "Off"]
    " dat += "
    ============! MAD GHOSTS ZONE !============
    " - dat += "Disable deadmob keyLoop (except staff, informs dchat): [SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] ? "On" : "Off"]
    " + dat += "Disable deadmob keyLoop (except staff, informs dchat): [SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] ? "On" : "Off"]
    " dat += "==========================================
    " dat += "
    Measures below can be bypassed with a special trait
    " - dat += "Slowmode say verb (informs world): [SSlag_switch.measures[SLOWMODE_SAY] ? "On" : "Off"]
    " - dat += "Disable runechat: [SSlag_switch.measures[DISABLE_RUNECHAT] ? "On" : "Off"] - trait applies to speaker
    " - dat += "Disable examine icons: [SSlag_switch.measures[DISABLE_USR_ICON2HTML] ? "On" : "Off"] - trait applies to examiner
    " - dat += "Disable parallax: [SSlag_switch.measures[DISABLE_PARALLAX] ? "On" : "Off"] - trait applies to character
    " - dat += "Disable footsteps: [SSlag_switch.measures[DISABLE_FOOTSTEPS] ? "On" : "Off"] - trait applies to character
    " + dat += "Slowmode say verb (informs world): [SSlag_switch.measures[SLOWMODE_SAY] ? "On" : "Off"]
    " + dat += "Disable runechat: [SSlag_switch.measures[DISABLE_RUNECHAT] ? "On" : "Off"] - trait applies to speaker
    " + dat += "Disable examine icons: [SSlag_switch.measures[DISABLE_USR_ICON2HTML] ? "On" : "Off"] - trait applies to examiner
    " + dat += "Disable parallax: [SSlag_switch.measures[DISABLE_PARALLAX] ? "On" : "Off"] - trait applies to character
    " + dat += "Disable footsteps: [SSlag_switch.measures[DISABLE_FOOTSTEPS] ? "On" : "Off"] - trait applies to character
    " dat += "" user << browse(dat.Join(), "window=lag_switch_panel;size=420x480") diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index a389980f533fd..da09e19d0debe 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -84,10 +84,10 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) if(!l2b) return var/list/dat = list("[title]") - dat += "Refresh

    " + dat += "Refresh

    " for(var/I in l2b) var/datum/admin_help/AH = I - dat += "[span_adminnotice("[span_adminhelp("Ticket #[AH.id]")]: [AH.initiator_key_name]: [AH.name]")]
    " + dat += "[span_adminnotice("[span_adminhelp("Ticket #[AH.id]")]: [AH.initiator_key_name]: [AH.name]")]
    " usr << browse(dat.Join(), "window=ahelp_list[state];size=600x480") @@ -370,32 +370,32 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) if(!ref_src) ref_src = "[REF(src)]" . = ADMIN_FULLMONTY_NONAME(initiator.mob) - . += " (NOTES)" + . += " (NOTES)" if(state == AHELP_ACTIVE) if (CONFIG_GET(flag/popup_admin_pm)) - . += " (POPUP)" + . += " (POPUP)" . += ClosureLinks(ref_src) //private /datum/admin_help/proc/ClosureLinks(ref_src) if(!ref_src) ref_src = "[REF(src)]" - . = " (REJT)" - . += " (IC)" - . += " (CLOSE)" - . += " (RSLVE)" + . = " (REJT)" + . += " (IC)" + . += " (CLOSE)" + . += " (RSLVE)" //private /datum/admin_help/proc/LinkedReplyName(ref_src) if(!ref_src) ref_src = "[REF(src)]" - return "[initiator_key_name]" + return "[initiator_key_name]" //private /datum/admin_help/proc/TicketHref(msg, ref_src, action = "ticket") if(!ref_src) ref_src = "[REF(src)]" - return "[msg]" + return "[msg]" //message from the initiator without a target, all admins will see this //won't bug irc/discord @@ -403,7 +403,12 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) var/ref_src = "[REF(src)]" //Message to be sent to all admins - var/admin_msg = span_adminnotice(span_adminhelp("Ticket [TicketHref("#[id]", ref_src)]: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]: [span_linkify(keywords_lookup(msg))]")) + var/admin_msg = fieldset_block( + span_adminhelp("Ticket [TicketHref("#[id]", ref_src)]"), + "[LinkedReplyName(ref_src)]\n\n\ + [span_linkify(keywords_lookup(msg))]\n\n\ + [FullMonty(ref_src)]", + "boxed_message red_box") AddInteraction("[LinkedReplyName(ref_src)]: [msg]", player_message = "[LinkedReplyName(ref_src)]: [msg]") log_admin_private("Ticket #[id]: [key_name(initiator)]: [msg]") @@ -575,7 +580,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) // Helper for opening directly to player ticket history dat += "

    Player Ticket History:" - dat += "[FOURSPACES]Open" + dat += "[FOURSPACES]Open" // Append any tickets also opened by this user if relevant var/list/related_tickets = GLOB.ahelp_tickets.TicketsByCKey(initiator_ckey) @@ -659,7 +664,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) dat += "CLOSED" else dat += "UNKNOWN" - dat += "\n[FOURSPACES]Refresh" + dat += "\n[FOURSPACES]Refresh" dat += "

    Opened at: [gameTimestamp("hh:mm:ss", opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)" if(closed_at) dat += "
    Closed at: [gameTimestamp("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)" @@ -801,7 +806,7 @@ GLOBAL_DATUM_INIT(admin_help_ui_handler, /datum/admin_help_ui_handler, new) set category = "Admin" set name = "Adminhelp" GLOB.admin_help_ui_handler.ui_interact(mob) - to_chat(src, span_boldnotice("Adminhelp failing to open or work? Click here")) + to_chat(src, span_boldnotice("Adminhelp failing to open or work? Click here")) /client/verb/view_latest_ticket() set category = "Admin" @@ -1020,7 +1025,7 @@ GLOBAL_DATUM_INIT(admin_help_ui_handler, /datum/admin_help_ui_handler, new) if(is_special_character(found)) is_antag = 1 founds += "Name: [found.name]([found.real_name]) Key: [found.key] Ckey: [found.ckey] [is_antag ? "(Antag)" : null] " - msg += "[original_word](?|F) " + msg += "[original_word](?|F) " continue msg += "[original_word] " if(external) @@ -1103,7 +1108,7 @@ GLOBAL_DATUM_INIT(admin_help_ui_handler, /datum/admin_help_ui_handler, new) var/datum/datum_check = locate(word_with_brackets) if(!istype(datum_check)) continue - msglist[i] = "[word]" + msglist[i] = "[word]" modified = TRUE if("#") // check if we're linking a ticket @@ -1124,7 +1129,7 @@ GLOBAL_DATUM_INIT(admin_help_ui_handler, /datum/admin_help_ui_handler, new) if(AHELP_RESOLVED) state_word = "Resolved" - msglist[i]= "[word] ([state_word] | [ahelp_check.initiator_key_name])" + msglist[i]= "[word] ([state_word] | [ahelp_check.initiator_key_name])" modified = TRUE if(modified) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index abbcbb62ab648..5d2598fc0f7d5 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -387,20 +387,11 @@ ADMIN_VERB(cmd_admin_pm_panel, R_NONE, "Admin PM", "Show a list of clients to PM recipient_ticket_id = recipient_ticket?.id SSblackbox.LogAhelp(recipient_ticket_id, "Ticket Opened", send_message, recipient.ckey, src.ckey) - to_chat(recipient, - type = MESSAGE_TYPE_ADMINPM, - html = "-- Administrator private message --", - confidential = TRUE) - recipient.receive_ahelp( link_to_us, span_linkify(send_message), ) - to_chat(recipient, - type = MESSAGE_TYPE_ADMINPM, - html = span_adminsay("Click on the administrator's name to reply."), - confidential = TRUE) to_chat(src, type = MESSAGE_TYPE_ADMINPM, html = span_notice("Admin PM to-[their_name_with_link]: [span_linkify(send_message)]"), @@ -707,21 +698,11 @@ ADMIN_VERB(cmd_admin_pm_panel, R_NONE, "Admin PM", "Show a list of clients to PM message_admins("External message from [sender] to [recipient_name_linked] : [message]") log_admin_private("External PM: [sender] -> [recipient_name] : [message]") - to_chat(recipient, - type = MESSAGE_TYPE_ADMINPM, - html = "-- Administrator private message --", - confidential = TRUE) - recipient.receive_ahelp( - "[adminname]", + "[adminname]", message, ) - to_chat(recipient, - type = MESSAGE_TYPE_ADMINPM, - html = span_adminsay("Click on the administrator's name to reply."), - confidential = TRUE) - admin_ticket_log(recipient, "PM From [tgs_tagged]: [message]", log_in_blackbox = FALSE) window_flash(recipient, ignorepref = TRUE) @@ -766,8 +747,13 @@ ADMIN_VERB(cmd_admin_pm_panel, R_NONE, "Admin PM", "Show a list of clients to PM to_chat( src, type = MESSAGE_TYPE_ADMINPM, - html = "Admin PM from-[reply_to]: [message]", - confidential = TRUE, + html = fieldset_block( + span_adminhelp("Administrator private message"), + "Admin PM from-[reply_to]\n\n\ + [message]\n\n\ + Click on the administrator's name to reply.", + "boxed_message red_box"), + confidential = TRUE ) current_ticket?.player_replied = FALSE diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 13f1995c9ba3d..804613f3f1b36 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -480,8 +480,8 @@ ADMIN_VERB(modify_goals, R_ADMIN, "Modify Goals", "Modify the station goals for /datum/admins/proc/modify_goals() var/dat = "" for(var/datum/station_goal/goal as anything in SSstation.get_station_goals()) - dat += "[goal.name] - Announce | Remove
    " - dat += "
    Add New Goal" + dat += "[goal.name] - Announce | Remove
    " + dat += "
    Add New Goal" usr << browse(dat, "window=goals;size=400x400") ADMIN_VERB(debug_mob_lists, R_DEBUG, "Debug Mob Lists", "For when you just gotta know.", ADMIN_CATEGORY_DEBUG) @@ -743,6 +743,14 @@ ADMIN_VERB(reestablish_tts_connection, R_DEBUG, "Re-establish Connection To TTS" message_admins("[key_name_admin(user)] successfully re-established the connection to the TTS HTTP server.") log_admin("[key_name(user)] successfully re-established the connection to the TTS HTTP server.") +ADMIN_VERB(allow_browser_inspect, R_DEBUG, "Allow Browser Inspect", "Allow browser debugging via inspect", ADMIN_CATEGORY_DEBUG) + if(user.byond_version < 516) + to_chat(user, span_warning("You can only use this on 516!")) + return + + to_chat(user, span_notice("You can now right click to use inspect on browsers.")) + winset(user, null, list("browser-options" = "+devtools")) + /proc/generate_timer_source_output(list/datum/timedevent/events) var/list/per_source = list() diff --git a/code/modules/admin/verbs/individual_logging.dm b/code/modules/admin/verbs/individual_logging.dm index d9df055ba1bb3..eb665d35f658e 100644 --- a/code/modules/admin/verbs/individual_logging.dm +++ b/code/modules/admin/verbs/individual_logging.dm @@ -75,4 +75,4 @@ slabel = "\[[label]\]" //This is necessary because num2text drops digits and rounds on big numbers. If more defines get added in the future it could break again. log_type = num2text(log_type, MAX_BITFLAG_DIGITS) - return "[slabel]" + return "[slabel]" diff --git a/code/modules/admin/verbs/map_template_loadverb.dm b/code/modules/admin/verbs/map_template_loadverb.dm index a27aca0f0147b..3251e9febd27c 100644 --- a/code/modules/admin/verbs/map_template_loadverb.dm +++ b/code/modules/admin/verbs/map_template_loadverb.dm @@ -61,8 +61,8 @@ ADMIN_VERB(map_template_upload, R_DEBUG, "Map Template - Upload", "Upload a map var/report_link if(report) report.show_to(user) - report_link = " - validation report" - to_chat(user, span_warning("Map template '[map]' failed validation."), confidential = TRUE) + report_link = " - validation report" + to_chat(user, span_warning("Map template '[map]' failed validation."), confidential = TRUE) if(report.loadable) var/response = tgui_alert(user, "The map failed validation, would you like to load it anyways?", "Map Errors", list("Cancel", "Upload Anyways")) if(response != "Upload Anyways") diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 8504cd5262cab..73196dbcdb1b6 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -84,7 +84,7 @@ ADMIN_VERB(show_map_reports, R_DEBUG, "Show Map Reports", "Displays a list of ma var/dat = {"List of all map reports:
    "} for(var/datum/map_report/report as anything in GLOB.map_reports) - dat += "[report.tag] ([report.original_path]) - View
    " + dat += "[report.tag] ([report.original_path]) - View
    " user << browse(dat, "window=map_reports") @@ -224,7 +224,7 @@ ADMIN_VERB(create_mapping_job_icons, R_DEBUG, "Generate job landmarks icons", "G ADMIN_VERB_VISIBILITY(debug_z_levels, ADMIN_VERB_VISIBLITY_FLAG_MAPPING_DEBUG) ADMIN_VERB(debug_z_levels, R_DEBUG, "Debug Z-Levels", "Displays a list of all z-levels and their linkages.", ADMIN_CATEGORY_MAPPING) - to_chat(user, examine_block(gather_z_level_information(append_grid = TRUE)), confidential = TRUE) + to_chat(user, boxed_message(gather_z_level_information(append_grid = TRUE)), confidential = TRUE) /// Returns all necessary z-level information. Argument `append_grid` allows the user to see a table showing all of the z-level linkages, which is only visible and useful in-game. /proc/gather_z_level_information(append_grid = FALSE) diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index e43164419d59c..177d1f3172f7d 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -348,6 +348,34 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w priority_announce("The NAP is now in full effect.", null, SSstation.announcer.get_rand_report_sound()) else priority_announce("The NAP has been revoked.", null, SSstation.announcer.get_rand_report_sound()) + if("send_shuttle_back") + if (!is_funmin) + return + if (SSshuttle.emergency.mode != SHUTTLE_ESCAPE) + to_chat(usr, span_warning("Emergency shuttle not currently in transit!"), confidential = TRUE) + return + var/make_announcement = tgui_alert(usr, "Make a CentCom announcement?", "Emergency shuttle return", list("Yes", "Custom Text", "No")) || "No" + var/announcement_text = "Emergency shuttle trajectory overriden, rerouting course back to [station_name()]." + if (make_announcement == "Custom Text") + announcement_text = tgui_input_text(usr, "Custom CentCom announcement", "Emergency shuttle return", multiline = TRUE) || announcement_text + var/new_timer = tgui_input_number(usr, "How long should the shuttle remain in transit?", "When are we droppin' boys?", 180, 600) + if (isnull(new_timer) || SSshuttle.emergency.mode != SHUTTLE_ESCAPE) + return + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Send Shuttle Back")) + message_admins("[key_name_admin(holder)] sent the escape shuttle back to the station") + if (make_announcement != "No") + priority_announce( + text = announcement_text, + title = "Shuttle Trajectory Override", + sound = 'sound/announcer/announcement/announce_dig.ogg', + sender_override = "Emergency Shuttle Uplink Alert", + color_override = "grey", + ) + SSshuttle.emergency.timer = INFINITY + if (new_timer > 0) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(return_escape_shuttle), make_announcement), new_timer SECONDS) + else + INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(return_escape_shuttle), make_announcement) if("blackout") if(!is_funmin) return @@ -673,6 +701,27 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w T.flick_overlay_static(portal_appearance[GET_TURF_PLANE_OFFSET(T) + 1], 15) playsound(T, 'sound/effects/magic/lightningbolt.ogg', rand(80, 100), TRUE) +/// Docks the emergency shuttle back to the station and resets its' state +/proc/return_escape_shuttle(make_announcement) + if (SSshuttle.emergency.initiate_docking(SSshuttle.getDock("emergency_home"), force = TRUE) != DOCKING_SUCCESS) + message_admins("Emergency shuttle was unable to dock back to the station!") + SSshuttle.emergency.timer = 1 // Prevents softlocks + return + if (make_announcement != "No") + priority_announce( + text = "[SSshuttle.emergency] has returned to the station.", + title = "Emergency Shuttle Override", + sound = ANNOUNCER_SHUTTLEDOCK, + sender_override = "Emergency Shuttle Uplink Alert", + color_override = "grey", + ) + SSshuttle.emergency.mode = SHUTTLE_IDLE + SSshuttle.emergency.timer = 0 + // Docks the pods back (don't ask about physics) + for (var/obj/docking_port/mobile/pod/pod in SSshuttle.mobile_docking_ports) + if (pod.previous) + pod.initiate_docking(pod.previous, force = TRUE) + /datum/everyone_is_an_antag_controller var/chosen_antag = "" var/objective = "" diff --git a/code/modules/admin/verbs/server.dm b/code/modules/admin/verbs/server.dm index 5ac9fd272b45c..133d36c3dd0f0 100644 --- a/code/modules/admin/verbs/server.dm +++ b/code/modules/admin/verbs/server.dm @@ -66,6 +66,12 @@ ADMIN_VERB(restart, R_SERVER, "Reboot World", "Restarts the world immediately.", #undef HARDEST_RESTART #undef TGS_RESTART +ADMIN_VERB(cancel_reboot, R_SERVER, "Cancel Reboot", "Cancels a pending world reboot.", ADMIN_CATEGORY_SERVER) + if(!SSticker.cancel_reboot(user)) + return + log_admin("[key_name(user)] cancelled the pending world reboot.") + message_admins("[key_name_admin(user)] cancelled the pending world reboot.") + ADMIN_VERB(end_round, R_SERVER, "End Round", "Forcibly ends the round and allows the server to restart normally.", ADMIN_CATEGORY_SERVER) var/confirm = tgui_alert(user, "End the round and restart the game world?", "End Round", list("Yes", "Cancel")) if(confirm != "Yes") @@ -131,6 +137,8 @@ ADMIN_VERB(delay_round_end, R_SERVER, "Delay Round End", "Prevent the server fro SSticker.delay_end = TRUE SSticker.admin_delay_notice = delay_reason + if(SSticker.reboot_timer) + SSticker.cancel_reboot(user) log_admin("[key_name(user)] delayed the round end for reason: [SSticker.admin_delay_notice]") message_admins("[key_name_admin(user)] delayed the round end for reason: [SSticker.admin_delay_notice]") diff --git a/code/modules/admin/view_variables/debug_variable_appearance.dm b/code/modules/admin/view_variables/debug_variable_appearance.dm index c5a367e83a064..537ef5e611b51 100644 --- a/code/modules/admin/view_variables/debug_variable_appearance.dm +++ b/code/modules/admin/view_variables/debug_variable_appearance.dm @@ -23,7 +23,7 @@ display_value = "[display_value]:[icon_state]" var/display_ref = get_vv_link_ref() - return "[display_name] ([display_value]) [display_ref]" + return "[display_name] ([display_value]) [display_ref]" /// Returns the ref string to use when displaying this image in the vv menu of something else /image/proc/get_vv_link_ref() diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm index 835da1a0b39cb..b776f1b5d7974 100644 --- a/code/modules/admin/view_variables/debug_variables.dm +++ b/code/modules/admin/view_variables/debug_variables.dm @@ -18,10 +18,10 @@ var/name_part = VV_HTML_ENCODE(name) if(level > 0 || islist(owner)) //handling keys in assoc lists if(istype(name,/datum)) - name_part = "[VV_HTML_ENCODE(name)] [REF(name)]" + name_part = "[VV_HTML_ENCODE(name)] [REF(name)]" else if(islist(name)) var/list/list_value = name - name_part = " /list ([length(list_value)]) [REF(name)]" + name_part = " /list ([length(list_value)]) [REF(name)]" . = "[.][name_part] = " @@ -85,9 +85,9 @@ items += debug_variable(key, val, level + 1, sanitize = sanitize) - return "/list ([list_value.len])" + return "/list ([list_value.len])" else - return "/list ([list_value.len])" + return "/list ([list_value.len])" if(name in GLOB.bitfields) var/list/flags = list() @@ -103,13 +103,13 @@ /datum/proc/debug_variable_value(name, level, datum/owner, sanitize, display_flags) if("[src]" != "[type]") // If we have a name var, let's use it. - return "[src] [type] [REF(src)]" + return "[src] [type] [REF(src)]" else - return "[type] [REF(src)]" + return "[type] [REF(src)]" /datum/weakref/debug_variable_value(name, level, datum/owner, sanitize, display_flags) . = ..() - return "[.] (Resolve)" + return "[.] (Resolve)" /matrix/debug_variable_value(name, level, datum/owner, sanitize, display_flags) return {" diff --git a/code/modules/admin/view_variables/topic_basic.dm b/code/modules/admin/view_variables/topic_basic.dm index 4f36365312701..52b87fda12512 100644 --- a/code/modules/admin/view_variables/topic_basic.dm +++ b/code/modules/admin/view_variables/topic_basic.dm @@ -37,7 +37,7 @@ if(!target) to_chat(usr, span_warning("The object you tried to expose to [C] no longer exists (nulled or hard-deled)"), confidential = TRUE) return - message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") + message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [target]") to_chat(C, "[holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window", confidential = TRUE) C.debug_variables(target) diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm index 66ac70f3f62f7..fbebccd445981 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin/view_variables/view_variables.dm @@ -257,7 +257,7 @@ ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", "View the
    - Refresh setSearchText(value)} @@ -146,7 +157,12 @@ const RequestControls = (props) => { )} {request.req_type === 'request_fax' && ( - + <> + + + )} {request.req_type === 'request_internet_sound' && ( diff --git a/tgui/packages/tgui/interfaces/Secrets.jsx b/tgui/packages/tgui/interfaces/Secrets.jsx index 3e3ccd70cc0ff..fbe0f56a9124a 100644 --- a/tgui/packages/tgui/interfaces/Secrets.jsx +++ b/tgui/packages/tgui/interfaces/Secrets.jsx @@ -425,13 +425,13 @@ const FunTab = (props) => { /> - - Your admin button here, coder! - + content="Send Shuttle Back" + onClick={() => act('send_shuttle_back')} + /> diff --git a/tgui/packages/tgui/layouts/Layout.tsx b/tgui/packages/tgui/layouts/Layout.tsx index 173ed1cbb432d..f3f395e540eca 100644 --- a/tgui/packages/tgui/layouts/Layout.tsx +++ b/tgui/packages/tgui/layouts/Layout.tsx @@ -21,6 +21,7 @@ type Props = Partial<{ export function Layout(props: Props) { const { className, theme = 'nanotrasen', children, ...rest } = props; + document.documentElement.className = `theme-${theme}`; return (
    diff --git a/tgui/packages/tgui/styles/layouts/Layout.scss b/tgui/packages/tgui/styles/layouts/Layout.scss index ecf750ecc0740..745112eab47c8 100644 --- a/tgui/packages/tgui/styles/layouts/Layout.scss +++ b/tgui/packages/tgui/styles/layouts/Layout.scss @@ -5,12 +5,28 @@ @use 'sass:color'; @use '../base'; +@use '../functions.scss' as *; +$luminance: luminance(base.$color-bg); $scrollbar-color-multiplier: 1 !default; +$scrollbar-base: color.scale( + base.$color-bg, + $lightness: -33% * $scrollbar-color-multiplier +); +$scrollbar-face: color.scale( + base.$color-bg, + $lightness: if($luminance > 0.05, 30%, 10%) * $scrollbar-color-multiplier +); +// Fancy scrollbar +html, +body { + scrollbar-color: $scrollbar-face $scrollbar-base; +} + +// Remove with 516, IE legacy code .Layout, .Layout * { - // Fancy scrollbar scrollbar-base-color: color.scale( base.$color-bg, $lightness: -25% * $scrollbar-color-multiplier diff --git a/tgui/packages/tgui/styles/layouts/TitleBar.scss b/tgui/packages/tgui/styles/layouts/TitleBar.scss index 517f2b8ad811e..8fd7239d55b1f 100644 --- a/tgui/packages/tgui/styles/layouts/TitleBar.scss +++ b/tgui/packages/tgui/styles/layouts/TitleBar.scss @@ -105,7 +105,7 @@ $shadow-color: hsla(0, 0%, 0%, 0.1) !default; min-width: base.rem(20px); padding: 2px 4px; padding: base.rem(2px) base.rem(4px); - background-color: darken(colors.$good, 10%); + background-color: color.adjust(colors.$good, $lightness: -10%, $space: hsl); color: hsl(120, 100%, 100%); text-align: center; } diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index d1e2148ccb35d..e54a7ac719ad8 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -67,7 +67,7 @@ // NT Theme .Layout__content { background-image: url('../assets/bg-nanotrasen.svg'); - background-size: 70%; + background-size: 70% 70%; background-position: center; background-repeat: no-repeat; } diff --git a/tools/UpdatePaths/Scripts/repaths_a357_to_c357.txt b/tools/UpdatePaths/Scripts/88095_repaths_a357_to_c357.txt similarity index 100% rename from tools/UpdatePaths/Scripts/repaths_a357_to_c357.txt rename to tools/UpdatePaths/Scripts/88095_repaths_a357_to_c357.txt diff --git a/tools/ci/check_grep.sh b/tools/ci/check_grep.sh index 05718cfccd885..89d803c45dc7d 100644 --- a/tools/ci/check_grep.sh +++ b/tools/ci/check_grep.sh @@ -125,6 +125,14 @@ if $grep 'allocate\(/mob/living/carbon/human[,\)]' $unit_test_files || st=1 fi; +section "516 Href Styles" +part "byond href styles" +if $grep "href[\s='\"\\\\]*\?" $code_files ; then + echo + echo -e "${RED}ERROR: BYOND requires internal href links to begin with \"byond://\".${NC}" + st=1 +fi; + section "common mistakes" part "global vars" if $grep '^/*var/' $code_files; then