diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm
index 0a770985080d5..9de921e10feb6 100644
--- a/_maps/map_files/Birdshot/birdshot.dmm
+++ b/_maps/map_files/Birdshot/birdshot.dmm
@@ -2661,7 +2661,7 @@
dir = 1
},
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"baP" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -4949,7 +4949,7 @@
dir = 4
},
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"bWs" = (
/obj/effect/turf_decal/stripes/line{
dir = 6
@@ -7555,7 +7555,7 @@
/obj/structure/chair/stool/bar/directional/south,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"cUH" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -7763,11 +7763,10 @@
dir = 4
},
/obj/effect/turf_decal/tile/neutral/opposingcorners,
-/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"cYt" = (
/obj/structure/cable,
/turf/open/floor/plating,
@@ -8400,7 +8399,7 @@
/obj/structure/chair/stool/bar/directional/south,
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"diI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/tile/neutral,
@@ -12629,7 +12628,7 @@
/obj/machinery/airalarm/directional/east,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"eOY" = (
/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{
dir = 4
@@ -16692,7 +16691,7 @@
},
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"gjE" = (
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt/dust,
@@ -21001,7 +21000,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"hED" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment,
@@ -22215,7 +22214,7 @@
dir = 4
},
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"ibI" = (
/obj/effect/turf_decal/siding/white/corner{
dir = 8
@@ -28260,7 +28259,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/camera/autoname/directional/east,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"jTD" = (
/obj/machinery/atmospherics/components/trinary/filter/atmos/o2{
dir = 8
@@ -32344,6 +32343,15 @@
/obj/effect/decal/cleanable/dirt/dust,
/turf/open/floor/plating/rust,
/area/station/maintenance/department/engine/atmos)
+"ljc" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/fore)
"ljg" = (
/obj/effect/turf_decal/weather/snow/corner{
dir = 1
@@ -38208,10 +38216,6 @@
},
/turf/open/floor/iron,
/area/station/security)
-"ngd" = (
-/obj/effect/turf_decal/tile/neutral/opposingcorners,
-/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
"ngq" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -39118,7 +39122,7 @@
},
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"nuY" = (
/obj/structure/broken_flooring/pile/directional/east,
/obj/structure/alien/weeds/node,
@@ -45899,9 +45903,6 @@
},
/turf/open/floor/wood/parquet,
/area/station/service/library)
-"pOT" = (
-/turf/closed/wall,
-/area/station/holodeck/rec_center)
"pOX" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
@@ -46147,11 +46148,10 @@
name = "Maintenance"
},
/obj/effect/mapping_helpers/airlock/access/any/service/maintenance,
-/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"pTq" = (
/obj/machinery/door/airlock/maintenance{
name = "Crematorium Maintenance"
@@ -46177,7 +46177,7 @@
/obj/effect/spawner/random/entertainment/arcade,
/obj/effect/decal/cleanable/cobweb/cobweb2,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"pTZ" = (
/obj/effect/turf_decal/siding/wideplating/dark{
dir = 8
@@ -46497,7 +46497,6 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
-/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
@@ -52948,7 +52947,7 @@
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/obj/structure/chair/stool/bar/directional/north,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"sjl" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -53636,7 +53635,7 @@
},
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"sul" = (
/obj/effect/turf_decal/siding{
dir = 1
@@ -56207,11 +56206,9 @@
"tlJ" = (
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/obj/item/kirbyplants/random,
-/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/power/apc/auto_name/directional/east,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"tlX" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/blue/fourcorners,
@@ -59975,7 +59972,7 @@
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/obj/effect/spawner/random/entertainment/arcade,
/turf/open/floor/iron,
-/area/station/holodeck/rec_center)
+/area/station/commons/fitness/recreation/entertainment)
"uwB" = (
/obj/effect/turf_decal/tile/dark_red/half/contrasted{
dir = 4
@@ -112298,13 +112295,13 @@ cvk
nFW
uvG
siN
-ngd
+jpp
nuV
sue
-ngd
+jpp
cUB
baO
-pOT
+pzd
gMz
rem
rQA
@@ -112557,11 +112554,11 @@ pTA
hEw
bWp
gjn
-ngd
+jpp
ibF
diG
baO
-pOT
+pzd
ycQ
rem
nvB
@@ -112810,13 +112807,13 @@ eav
eav
nFW
nFW
-pOT
-pOT
+pzd
+pzd
tlJ
cYp
jTC
eOX
-pOT
+pzd
xQJ
xQJ
xQJ
@@ -113068,12 +113065,12 @@ tLj
wOp
fsq
iRl
-pOT
-pOT
+pzd
+pzd
pTk
-pOT
-pOT
-pOT
+pzd
+pzd
+pzd
xqs
xMO
xQJ
@@ -113327,7 +113324,7 @@ fLg
tHi
tfc
wOp
-mTc
+ljc
xQJ
ejn
vJx
@@ -113584,7 +113581,7 @@ pot
rUq
lyq
wOp
-mTc
+ljc
xQJ
mbV
vJx
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index f4831582a2eee..3737277c465ff 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -29666,7 +29666,7 @@
},
/obj/machinery/holopad,
/obj/effect/landmark/start/depsec/medical,
-/obj/machinery/computer/security/telescreen/cmo/directional/east,
+/obj/machinery/computer/security/telescreen/med_sec/directional/east,
/turf/open/floor/iron/dark/smooth_large,
/area/station/security/checkpoint/medical)
"iTJ" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 83eb9c4b5e81d..efec99c47fc04 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -10596,9 +10596,7 @@
},
/obj/effect/turf_decal/tile/red/fourcorners,
/obj/machinery/light/small/directional/west,
-/obj/machinery/computer/security/telescreen/cmo/directional/west{
- name = "Medbay Monitor"
- },
+/obj/machinery/computer/security/telescreen/med_sec/directional/west,
/turf/open/floor/iron/dark,
/area/station/security/checkpoint/medical)
"dQO" = (
diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm
index 7f0a84010e9f0..01234def93289 100644
--- a/_maps/map_files/Mining/Lavaland.dmm
+++ b/_maps/map_files/Mining/Lavaland.dmm
@@ -3896,11 +3896,11 @@
/area/mine/lounge)
"uT" = (
/obj/structure/lattice/catwalk,
-/obj/machinery/atmospherics/components/unary/passive_vent/layer2{
+/obj/machinery/atmospherics/components/unary/outlet_injector/layer2{
dir = 1
},
/turf/open/misc/asteroid/basalt/lava_land_surface,
-/area/lavaland/surface/outdoors)
+/area/mine/maintenance/service)
"uU" = (
/turf/closed/mineral/random/labormineral/volcanic,
/area/lavaland/surface/outdoors)
diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm
index 2803187f508a7..5673421142ac1 100644
--- a/_maps/map_files/wawastation/wawastation.dmm
+++ b/_maps/map_files/wawastation/wawastation.dmm
@@ -58844,9 +58844,7 @@
"uJq" = (
/obj/machinery/computer/records/medical,
/obj/effect/turf_decal/tile/red/fourcorners,
-/obj/machinery/computer/security/telescreen/cmo/directional/north{
- name = "Medbay Monitor"
- },
+/obj/machinery/computer/security/telescreen/med_sec/directional/north,
/turf/open/floor/iron/dark,
/area/station/security/checkpoint/medical)
"uJt" = (
diff --git a/code/__DEFINES/dcs/signals/signals_blackmarket.dm b/code/__DEFINES/dcs/signals/signals_market.dm
similarity index 100%
rename from code/__DEFINES/dcs/signals/signals_blackmarket.dm
rename to code/__DEFINES/dcs/signals/signals_market.dm
diff --git a/code/__DEFINES/interaction_flags.dm b/code/__DEFINES/interaction_flags.dm
index 615fe5c4cbda2..fd66cee5bb93e 100644
--- a/code/__DEFINES/interaction_flags.dm
+++ b/code/__DEFINES/interaction_flags.dm
@@ -26,6 +26,8 @@
#define INTERACT_ATOM_MOUSEDROP_IGNORE_USABILITY (1<<12)
/// Bypass all adjacency and other checks for mouse drop
#define INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS (INTERACT_ATOM_MOUSEDROP_IGNORE_ADJACENT | INTERACT_ATOM_MOUSEDROP_IGNORE_USABILITY)
+/// calls try_interact() on attack_paw() and returns that.
+#define INTERACT_ATOM_ATTACK_PAW (1<<13)
/// attempt pickup on attack_hand for items
#define INTERACT_ITEM_ATTACK_HAND_PICKUP (1<<0)
diff --git a/code/__DEFINES/blackmarket.dm b/code/__DEFINES/market.dm
similarity index 100%
rename from code/__DEFINES/blackmarket.dm
rename to code/__DEFINES/market.dm
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index 0dd8ee0a582f6..2f1465ac4ffe2 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -200,7 +200,8 @@
/atom/proc/attack_paw(mob/user, list/modifiers)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user, modifiers) & COMPONENT_CANCEL_ATTACK_CHAIN)
return TRUE
- return FALSE
+ if(interaction_flags_atom & INTERACT_ATOM_ATTACK_PAW)
+ . = _try_interact(user)
/*
diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm
index e34b0c7e446c0..66a06c230c646 100644
--- a/code/controllers/subsystem/dynamic/dynamic.dm
+++ b/code/controllers/subsystem/dynamic/dynamic.dm
@@ -999,7 +999,7 @@ SUBSYSTEM_DEF(dynamic)
#define MAXIMUM_DYN_DISTANCE 5
/**
- * Returns the comulative distribution of threat centre and width, and a random location of -0.5 to 0.5
+ * Returns the comulative distribution of threat centre and width, and a random location of -5 to 5
* plus or minus the otherwise unattainable lower and upper percentiles. All multiplied by the maximum
* threat and then rounded to the nearest interval.
* rand() calls without arguments returns a value between 0 and 1, allowing for smaller intervals.
diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm
index 7d91ca6b565ce..9396728159480 100644
--- a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm
+++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm
@@ -964,13 +964,15 @@
cost = 5
minimum_players = 40
repeatable = TRUE
+ signup_item_path = /obj/item/cosmic_skull
ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_VOIDWALKER_VOID)
/// The space turf we find in acceptable(), cached for ease
var/space_turf
/datum/dynamic_ruleset/midround/from_ghosts/voidwalker/acceptable(population = 0, threat_level = 0)
space_turf = find_space_spawn()
- if(!space_turf)
+ // Space only antag and will die on planetary gravity.
+ if(SSmapping.is_planetary() || !space_turf)
return FALSE
return ..()
diff --git a/code/controllers/subsystem/blackmarket.dm b/code/controllers/subsystem/market.dm
similarity index 68%
rename from code/controllers/subsystem/blackmarket.dm
rename to code/controllers/subsystem/market.dm
index 5c88177583b2f..81d96d331c71d 100644
--- a/code/controllers/subsystem/blackmarket.dm
+++ b/code/controllers/subsystem/market.dm
@@ -1,5 +1,5 @@
-SUBSYSTEM_DEF(blackmarket)
- name = "Blackmarket"
+SUBSYSTEM_DEF(market)
+ name = "Market"
flags = SS_BACKGROUND
init_order = INIT_ORDER_DEFAULT
@@ -18,27 +18,27 @@ SUBSYSTEM_DEF(blackmarket)
/// Currently queued purchases.
var/list/queued_purchases = list()
-/datum/controller/subsystem/blackmarket/Initialize()
+/datum/controller/subsystem/market/Initialize()
for(var/market in subtypesof(/datum/market))
markets[market] += new market
- for(var/datum/market_item/item as anything in subtypesof(/datum/market_item))
- if(!initial(item.item))
- continue
- if(!prob(initial(item.availability_prob)))
- continue
-
- var/datum/market_item/item_instance = new item()
- for(var/potential_market in item_instance.markets)
- if(!markets[potential_market])
- stack_trace("SSblackmarket: Item [item_instance] available in market that does not exist.")
- continue
- // If this fails the market item will just be GC'd
- markets[potential_market].add_item(item_instance)
+ for(var/path in subtypesof(/datum/market_item))
+ initialize_item(path)
return SS_INIT_SUCCESS
-/datum/controller/subsystem/blackmarket/fire(resumed)
+/datum/controller/subsystem/market/proc/initialize_item(datum/market_item/path, list/market_whitelist)
+ if(!path::item || !prob(path::availability_prob))
+ return
+ var/datum/market_item/item_instance = new path()
+ for(var/potential_market in item_instance.markets)
+ if(!markets[potential_market])
+ stack_trace("SSmarket: Item [item_instance] available in market that does not exist.")
+ continue
+ if(isnull(market_whitelist) || (potential_market in market_whitelist))
+ markets[potential_market].add_item(item_instance)
+
+/datum/controller/subsystem/market/fire(resumed)
while(length(queued_purchases))
var/datum/market_purchase/purchase = queued_purchases[1]
queued_purchases.Cut(1,2)
@@ -55,9 +55,9 @@ SUBSYSTEM_DEF(blackmarket)
// The time left of the shortest cooldown amongst all telepads.
var/lowest_timeleft = INFINITY
for(var/obj/machinery/ltsrbt/pad as anything in telepads)
- if(!COOLDOWN_FINISHED(pad, recharge_cooldown))
- var/timeleft = COOLDOWN_TIMELEFT(pad, recharge_cooldown)
- if(timeleft < lowest_timeleft)
+ if(!COOLDOWN_FINISHED(pad, recharge_cooldown) || (pad.machine_stat & NOPOWER))
+ var/timeleft = pad.machine_stat & NOPOWER ? INFINITY - 1 : COOLDOWN_TIMELEFT(pad, recharge_cooldown)
+ if(timeleft <= lowest_timeleft)
lowest_cd_pad = pad
lowest_timeleft = timeleft
continue
@@ -79,7 +79,7 @@ SUBSYSTEM_DEF(blackmarket)
to_chat(buyer, span_notice("[purchase.uplink] flashes a message noting that the order is being teleported to [get_area(targetturf)] in 60 seconds."))
// do_teleport does not want to teleport items from nullspace, so it just forceMoves and does sparks.
- addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/controller/subsystem/blackmarket, fake_teleport), purchase, targetturf), 60 SECONDS)
+ addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/controller/subsystem/market, fake_teleport), purchase, targetturf), 60 SECONDS)
// Get the current location of the uplink if it exists, then throws the item from space at the station from a random direction.
if(SHIPPING_METHOD_LAUNCH)
@@ -106,7 +106,7 @@ SUBSYSTEM_DEF(blackmarket)
break
/// Used to make a teleportation effect as do_teleport does not like moving items from nullspace.
-/datum/controller/subsystem/blackmarket/proc/fake_teleport(datum/market_purchase/purchase, turf/target)
+/datum/controller/subsystem/market/proc/fake_teleport(datum/market_purchase/purchase, turf/target)
// Oopsie, whoopsie, the item is gone. So long, and thanks for all the money.
if(QDELETED(purchase))
return
@@ -119,9 +119,31 @@ SUBSYSTEM_DEF(blackmarket)
qdel(purchase)
/// Used to add /datum/market_purchase to queued_purchases var. Returns TRUE when queued.
-/datum/controller/subsystem/blackmarket/proc/queue_item(datum/market_purchase/purchase)
+/datum/controller/subsystem/market/proc/queue_item(datum/market_purchase/purchase)
if((purchase.method == SHIPPING_METHOD_LTSRBT && !telepads.len) || isnull(purchase.uplink))
qdel(purchase)
return FALSE
queued_purchases += purchase
return TRUE
+
+///A proc that restocks one or more markets, or all if the market_whitelist is null.
+/datum/controller/subsystem/market/proc/restock(list/market_whitelist)
+ var/market_name = "Markets"
+ if(market_whitelist && !islist(market_whitelist))
+ var/datum/market/market_path = market_whitelist
+ market_name = market_path::name
+ market_whitelist = list(market_path)
+
+ var/list/existing_types = list()
+ for(var/path in markets)
+ if(isnull(market_whitelist) || (path in market_whitelist))
+ markets[path].restock(existing_types)
+
+ for(var/datum/market_item/path as anything in (subtypesof(/datum/market_item) - existing_types))
+ if(!path::restockable)
+ continue
+ initialize_item(path, market_whitelist)
+
+ for(var/obj/machinery/ltsrbt/pad as anything in telepads)
+ pad.say("[market_name] restocked!")
+ playsound(src, 'sound/effects/cashregister.ogg', 40, FALSE)
diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm
index 331e11afa4893..8d77c6fc6bdbb 100644
--- a/code/datums/emotes.dm
+++ b/code/datums/emotes.dm
@@ -60,6 +60,8 @@
var/can_message_change = FALSE
/// How long is the cooldown on the audio of the emote, if it has one?
var/audio_cooldown = 2 SECONDS
+ /// Does this emote's sound ignore walls?
+ var/sound_wall_ignore = FALSE
/datum/emote/New()
switch(mob_type_allowed_typecache)
@@ -100,7 +102,7 @@
var/tmp_sound = get_sound(user)
if(tmp_sound && should_play_sound(user, intentional) && TIMER_COOLDOWN_FINISHED(user, type))
TIMER_COOLDOWN_START(user, type, audio_cooldown)
- playsound(user, tmp_sound, 50, vary)
+ playsound(source = user,soundin = tmp_sound,vol = 50, vary = vary, ignore_walls = sound_wall_ignore)
var/is_important = emote_type & EMOTE_IMPORTANT
var/is_visual = emote_type & EMOTE_VISIBLE
diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm
index 10be2fff885e6..669409099530a 100644
--- a/code/game/atom/_atom.dm
+++ b/code/game/atom/_atom.dm
@@ -943,13 +943,18 @@
//We inline a MAPTEXT() here, because there's no good way to statically add to a string like this
new_maptext = "[name][extra_context]"
- INVOKE_ASYNC(src, PROC_REF(set_hover_maptext), client, active_hud, new_maptext)
+ if (length(name) * 10 > active_hud.screentip_text.maptext_width)
+ INVOKE_ASYNC(src, PROC_REF(set_hover_maptext), client, active_hud, new_maptext)
+ return
+
+ active_hud.screentip_text.maptext = new_maptext
+ active_hud.screentip_text.maptext_y = 10 - (extra_lines > 0 ? 11 + 9 * (extra_lines - 1): 0)
/atom/proc/set_hover_maptext(client/client, datum/hud/active_hud, new_maptext)
var/map_height
WXH_TO_HEIGHT(client.MeasureText(new_maptext, null, active_hud.screentip_text.maptext_width), map_height)
active_hud.screentip_text.maptext = new_maptext
- active_hud.screentip_text.maptext_y = 22 - map_height
+ active_hud.screentip_text.maptext_y = 26 - map_height
/**
* This proc is used for telling whether something can pass by this atom in a given direction, for use by the pathfinding system.
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 423a2a16b55c3..45a75f06133dd 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -286,6 +286,7 @@
///Early process for machines added to SSmachines.processing_early to prioritize power draw
/obj/machinery/proc/process_early()
+ set waitfor = FALSE
return PROCESS_KILL
/obj/machinery/process()//If you dont use process or power why are you here
@@ -293,9 +294,11 @@
///Late process for machines added to SSmachines.processing_late to gather accurate recordings
/obj/machinery/proc/process_late()
+ set waitfor = FALSE
return PROCESS_KILL
/obj/machinery/proc/process_atmos()//If you dont use process why are you here
+ set waitfor = FALSE
return PROCESS_KILL
///Called when we want to change the value of the machine_stat variable. Holds bitflags.
diff --git a/code/game/machinery/computer/operating_computer.dm b/code/game/machinery/computer/operating_computer.dm
index d67cea367e9a6..43a18c7081f30 100644
--- a/code/game/machinery/computer/operating_computer.dm
+++ b/code/game/machinery/computer/operating_computer.dm
@@ -143,11 +143,13 @@
var/chems_needed = surgery_step.get_chem_list()
var/alternative_step
var/alt_chems_needed = ""
+ var/alt_chems_present = FALSE
if(surgery_step.repeatable)
var/datum/surgery_step/next_step = procedure.get_surgery_next_step()
if(next_step)
alternative_step = capitalize(next_step.name)
alt_chems_needed = next_step.get_chem_list()
+ alt_chems_present = next_step.chem_check(patient)
else
alternative_step = "Finish operation"
data["procedures"] += list(list(
@@ -155,7 +157,9 @@
"next_step" = capitalize(surgery_step.name),
"chems_needed" = chems_needed,
"alternative_step" = alternative_step,
- "alt_chems_needed" = alt_chems_needed
+ "alt_chems_needed" = alt_chems_needed,
+ "chems_present" = surgery_step.chem_check(patient),
+ "alt_chems_present" = alt_chems_present
))
return data
diff --git a/code/game/machinery/computer/telescreen.dm b/code/game/machinery/computer/telescreen.dm
index c421ca0c90308..deca4ec8245e1 100644
--- a/code/game/machinery/computer/telescreen.dm
+++ b/code/game/machinery/computer/telescreen.dm
@@ -185,11 +185,23 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/security/telescreen/ce, 32)
frame_type = /obj/item/wallframe/telescreen/cmo
/obj/item/wallframe/telescreen/cmo
- name = "\improper Chief Engineer'stelescreen frame"
+ name = "\improper Chief Medical Officer's telescreen frame"
result_path = /obj/machinery/computer/security/telescreen/cmo
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/security/telescreen/cmo, 32)
+/obj/machinery/computer/security/telescreen/med_sec
+ name = "\improper medical telescreen"
+ desc = "A telescreen with access to the medbay's camera network."
+ network = list(CAMERANET_NETWORK_MEDBAY)
+ frame_type = /obj/item/wallframe/telescreen/med_sec
+
+/obj/item/wallframe/telescreen/med_sec
+ name = "\improper medical telescreen frame"
+ result_path = /obj/machinery/computer/security/telescreen/med_sec
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/security/telescreen/med_sec, 32)
+
/obj/machinery/computer/security/telescreen/vault
name = "vault monitor"
desc = "A telescreen that connects to the vault's camera network."
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index ce1b82a83b408..8ce9265917d63 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -133,33 +133,55 @@
qdel(morsel)
return
- var/list/to_eat = (issilicon(morsel) ? list(morsel) : morsel.get_all_contents()) //eating borg contents leads to many bad things
+ var/list/atom/to_eat = list(morsel)
var/living_detected = FALSE //technically includes silicons as well but eh
var/list/nom = list()
var/list/crunchy_nom = list() //Mobs have to be handled differently so they get a different list instead of checking them multiple times.
+ var/not_eaten = 0
- for(var/thing in to_eat)
- var/obj/as_object = thing
- if(istype(as_object))
- if(as_object.resistance_flags & INDESTRUCTIBLE)
- if(!isturf(as_object.loc) && !isliving(as_object.loc))
- as_object.forceMove(loc) // so you still cant shove it in a locker
- continue
- var/obj/item/bodypart/head/as_head = thing
- var/obj/item/mmi/as_mmi = thing
- if(istype(thing, /obj/item/organ/internal/brain) || (istype(as_head) && locate(/obj/item/organ/internal/brain) in as_head) || (istype(as_mmi) && as_mmi.brain) || istype(thing, /obj/item/dullahan_relay))
- living_detected = TRUE
- if(isitem(as_object))
- var/obj/item/as_item = as_object
- if(as_item.item_flags & ABSTRACT) //also catches organs and bodyparts *stares*
- continue
- nom += thing
- else if(isliving(thing))
+ while (to_eat.len)
+ var/atom/movable/thing = to_eat[1]
+ to_eat -= thing
+
+ if (thing.flags_1 & HOLOGRAM_1)
+ qdel(thing)
+ continue
+
+ if (thing.resistance_flags & INDESTRUCTIBLE)
+ if (!isturf(thing.loc) && !isliving(thing.loc))
+ thing.forceMove(loc)
+ not_eaten += 1
+ continue
+
+ if (isliving(thing))
living_detected = TRUE
crunchy_nom += thing
+ if (!issilicon(thing))
+ to_eat |= thing.contents
+ continue
+
+ if (!isobj(thing))
+ not_eaten += 1
+ continue
+
+ if (isitem(thing))
+ var/obj/item/as_item = thing
+ if (as_item.item_flags & ABSTRACT)
+ not_eaten += 1
+ continue
+
+ if (istype(thing, /obj/item/organ/internal/brain) || istype(thing, /obj/item/dullahan_relay))
+ living_detected = TRUE
+
+ if (istype(thing, /obj/item/mmi))
+ var/obj/item/mmi/mmi = thing
+ if (!isnull(mmi.brain))
+ living_detected = TRUE
+
+ nom += thing
+ to_eat |= thing.contents
- var/not_eaten = to_eat.len - nom.len - crunchy_nom.len
if(living_detected) // First, check if we have any living beings detected.
if(obj_flags & EMAGGED)
for(var/CRUNCH in crunchy_nom) // Eat them and keep going because we don't care about safety.
diff --git a/code/game/machinery/telecomms/broadcasting.dm b/code/game/machinery/telecomms/broadcasting.dm
index 5887c77667506..2c31dcbd98955 100644
--- a/code/game/machinery/telecomms/broadcasting.dm
+++ b/code/game/machinery/telecomms/broadcasting.dm
@@ -78,7 +78,7 @@
datum/language/language, // the language of the message
message, // the text content of the message
spans, // the list of spans applied to the message
- list/message_mods // the list of modification applied to the message. Whispering, singing, ect
+ list/message_mods, // the list of modification applied to the message. Whispering, singing, ect
)
src.source = source
src.frequency = frequency
@@ -92,7 +92,7 @@
"compression" = rand(COMPRESSION_VOCAL_SIGNAL_MIN, COMPRESSION_VOCAL_SIGNAL_MAX),
"language" = lang_instance.name,
"spans" = spans,
- "mods" = message_mods
+ "mods" = message_mods,
)
levels = SSmapping.get_connected_levels(get_turf(source))
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index d515929c197cc..373db4b21f53a 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -351,6 +351,12 @@
signal.broadcast()
return
+
+ if(iscarbon(talking_movable))
+ var/mob/living/carbon/talking_carbon = talking_movable
+ if(talking_carbon.client?.prefs.read_preference(/datum/preference/toggle/radio_noise))
+ SEND_SOUND(talking_carbon, 'sound/misc/radio_talk.ogg')
+
// All radios make an attempt to use the subspace system first
signal.send_to_receivers()
@@ -422,6 +428,16 @@
SEND_SIGNAL(src, COMSIG_RADIO_RECEIVE_MESSAGE, data)
flick_overlay_view(overlay_speaker_active, 5 SECONDS)
+ if(iscarbon(loc))
+ var/mob/living/carbon/holder = loc
+ if(!holder.client?.prefs.read_preference(/datum/preference/toggle/radio_noise))
+ return
+
+ var/list/spans = data["spans"]
+ SEND_SOUND(holder, 'sound/misc/radio_receive.ogg')
+ if(SPAN_COMMAND in spans)
+ SEND_SOUND(holder, 'sound/misc/radio_important.ogg')
+
/obj/item/radio/ui_state(mob/user)
return GLOB.inventory_state
diff --git a/code/game/objects/items/storage/boxes/job_boxes.dm b/code/game/objects/items/storage/boxes/job_boxes.dm
index ea9189cc5f2b0..ddfb51d913b9c 100644
--- a/code/game/objects/items/storage/boxes/job_boxes.dm
+++ b/code/game/objects/items/storage/boxes/job_boxes.dm
@@ -43,7 +43,7 @@
if(HAS_TRAIT(SSstation, STATION_TRAIT_RADIOACTIVE_NEBULA))
new /obj/item/storage/pill_bottle/potassiodide(src)
- if(SSmapping.is_planetary() && LAZYLEN(SSmapping.multiz_levels))
+ if(LAZYLEN(SSmapping.multiz_levels))
new /obj/item/climbing_hook/emergency(src)
/obj/item/storage/box/survival/radio/PopulateContents()
diff --git a/code/game/objects/items/storage/medkit.dm b/code/game/objects/items/storage/medkit.dm
index c3c97c790fdf3..bee7fdd524f3d 100644
--- a/code/game/objects/items/storage/medkit.dm
+++ b/code/game/objects/items/storage/medkit.dm
@@ -18,6 +18,9 @@
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
throw_speed = 3
throw_range = 7
+ drop_sound = 'sound/items/medkit_drop.ogg'
+ pickup_sound = 'sound/items/medkit_pick_up.ogg'
+ sound_vary = TRUE
var/empty = FALSE
/// Defines damage type of the medkit. General ones stay null. Used for medibot healing bonuses
var/damagetype_healed
@@ -79,6 +82,8 @@
/obj/item/storage/medkit/Initialize(mapload)
. = ..()
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
+ atom_storage.open_sound = 'sound/items/medkit_open.ogg'
+ atom_storage.open_sound_vary = TRUE
/obj/item/storage/medkit/regular
icon_state = "medkit"
diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm
index ee1f314c92add..d89794f420917 100644
--- a/code/game/objects/items/tanks/tanks.dm
+++ b/code/game/objects/items/tanks/tanks.dm
@@ -22,6 +22,9 @@
slot_flags = ITEM_SLOT_BACK
worn_icon = 'icons/mob/clothing/back.dmi' //since these can also get thrown into suit storage slots. if something goes on the belt, set this to null.
hitsound = 'sound/weapons/smash.ogg'
+ pickup_sound = 'sound/items/gas_tank_pick_up.ogg'
+ drop_sound = 'sound/items/gas_tank_drop.ogg'
+ sound_vary = TRUE
pressure_resistance = ONE_ATMOSPHERE * 5
force = 5
throwforce = 10
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 72c974b00252d..895660fafa44c 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -316,9 +316,11 @@
return NONE
if(!user.transferItemToLoc(tool, drop_location(), silent = FALSE))
return ITEM_INTERACT_BLOCKING
- //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
- tool.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(world.icon_size/2), world.icon_size/2)
- tool.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(world.icon_size/2), world.icon_size/2)
+ // Items are centered by default, but we move them if click ICON_X and ICON_Y are available
+ if(LAZYACCESS(modifiers, ICON_X) && LAZYACCESS(modifiers, ICON_Y))
+ // Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
+ tool.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(world.icon_size*0.5), world.icon_size*0.5)
+ tool.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(world.icon_size*0.5), world.icon_size*0.5)
AfterPutItemOnTable(tool, user)
return ITEM_INTERACT_SUCCESS
diff --git a/code/modules/antagonists/spy/spy_bounty.dm b/code/modules/antagonists/spy/spy_bounty.dm
index 28984ce2272bd..01a1a1baf7b9a 100644
--- a/code/modules/antagonists/spy/spy_bounty.dm
+++ b/code/modules/antagonists/spy/spy_bounty.dm
@@ -186,7 +186,7 @@
var/datum/market_item/stolen_good/new_item = new(thing, item_price)
- return SSblackmarket.markets[/datum/market/blackmarket].add_item(new_item)
+ return SSmarket.markets[/datum/market/blackmarket].add_item(new_item)
/// Steal an item
/datum/spy_bounty/objective_item
diff --git a/code/modules/antagonists/voidwalker/voidwalker_status_effects.dm b/code/modules/antagonists/voidwalker/voidwalker_status_effects.dm
index 6dc9cdc35ca7b..7934e757077af 100644
--- a/code/modules/antagonists/voidwalker/voidwalker_status_effects.dm
+++ b/code/modules/antagonists/voidwalker/voidwalker_status_effects.dm
@@ -21,11 +21,16 @@
/datum/status_effect/planet_allergy
id = "planet_allergy"
duration = INFINITE
- alert_type = /atom/movable/screen/alert/veryhighgravity
+ alert_type = /atom/movable/screen/alert/status_effect/veryhighgravity
/datum/status_effect/planet_allergy/tick()
owner.adjustBruteLoss(1)
+/atom/movable/screen/alert/status_effect/veryhighgravity
+ name = "Crushing Gravity"
+ desc = "You're getting crushed by high gravity, picking up items and movement will be slowed. You'll also accumulate brute damage!"
+ icon_state = "paralysis"
+
/datum/status_effect/void_eatered
duration = 10 SECONDS
remove_on_fullheal = TRUE
diff --git a/code/modules/antagonists/voidwalker/voidwalker_void_eater.dm b/code/modules/antagonists/voidwalker/voidwalker_void_eater.dm
index db638c2b94818..9df3eabab3d21 100644
--- a/code/modules/antagonists/voidwalker/voidwalker_void_eater.dm
+++ b/code/modules/antagonists/voidwalker/voidwalker_void_eater.dm
@@ -31,7 +31,7 @@
AddComponent(/datum/component/temporary_glass_shatterer)
-/obj/item/void_eater/pickup(mob/user)
+/obj/item/void_eater/equipped(mob/user)
. = ..()
RegisterSignal(user, COMSIG_VOIDWALKER_SUCCESFUL_KIDNAP, PROC_REF(refresh))
diff --git a/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm b/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm
index 79364a80a198a..15900a6ac0b0a 100644
--- a/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm
+++ b/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm
@@ -19,7 +19,7 @@
pixel_y = 16
pixel_z = -48
anchored = TRUE
- interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND
+ interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_ATTACK_PAW
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
layer = SIGIL_LAYER
/// How many prior grand rituals have been completed?
diff --git a/code/modules/cargo/exports/fish.dm b/code/modules/cargo/exports/fish.dm
index c68eeaaa70063..3860dff904b19 100644
--- a/code/modules/cargo/exports/fish.dm
+++ b/code/modules/cargo/exports/fish.dm
@@ -1,5 +1,5 @@
/datum/export/fish
- cost = 50
+ cost = 30
unit_name = "fish"
export_types = list(/obj/item/fish)
@@ -7,4 +7,7 @@
var/elastic_cost = ..()
var/elastic_percent = elastic_cost / init_cost
var/size_weight_exponentation = (fish.size * fish.weight * 0.01)^0.85
- return round(elastic_cost + size_weight_exponentation * elastic_percent)
+ var/new_cost = elastic_cost + size_weight_exponentation * elastic_percent
+ if(HAS_TRAIT(fish, TRAIT_FISH_FROM_CASE)) //Avoid printing money by simply ordering fish and sending it back.
+ new_cost *= 0.05
+ return round(new_cost)
diff --git a/code/modules/cargo/goodies.dm b/code/modules/cargo/goodies.dm
index e09c3e2bc958d..4751b45aae89b 100644
--- a/code/modules/cargo/goodies.dm
+++ b/code/modules/cargo/goodies.dm
@@ -311,7 +311,7 @@
/datum/supply_pack/goody/climbing_hook
name = "Climbing Hook Single-Pack"
- desc = "A less cheap imported climbing hook. Absolutely no use outside of planetary stations."
+ desc = "A less cheap imported climbing hook. Absolutely no use outside of multi-floor stations."
cost = PAYCHECK_CREW * 5
contains = list(/obj/item/climbing_hook)
diff --git a/code/modules/cargo/markets/_market.dm b/code/modules/cargo/markets/_market.dm
index 0a93469411cdb..4696d3007a7ae 100644
--- a/code/modules/cargo/markets/_market.dm
+++ b/code/modules/cargo/markets/_market.dm
@@ -6,7 +6,7 @@
var/list/shipping
// Automatic vars, do not touch these.
- /// Items available from this market, populated by SSblackmarket on initialization. Automatically assigned, so don't manually adjust.
+ /// Items available from this market, populated by SSmarket on initialization. Automatically assigned, so don't manually adjust.
var/list/available_items = list()
/// Item categories available from this market, only items which are in these categories can be gotten from this market. Automatically assigned, so don't manually adjust.
var/list/categories = list()
@@ -73,6 +73,20 @@
return FALSE
+/**
+ * A proc that restocks only the EXISTING items of this market.
+ * If you want to selectively restock markets, call SSmarket.restock(market_or_list_of_markets) instead.
+ */
+/datum/market/proc/restock(list/existing_items)
+ for(var/category in available_items)
+ var/category_list = available_items[category]
+ for(var/identifier in category_list)
+ var/datum/market_item/item = category_list[identifier]
+ existing_items |= item.type
+ if(!item.restockable || item.stock >= item.stock_max || !prob(item.availability_prob))
+ continue
+ item.stock += rand(1, item.stock_max - item.stock)
+
/datum/market/blackmarket
name = "Black Market"
shipping = list(
diff --git a/code/modules/cargo/markets/market_item.dm b/code/modules/cargo/markets/market_item.dm
index 5e3ce4efb6c07..d7a4dd4c0eef3 100644
--- a/code/modules/cargo/markets/market_item.dm
+++ b/code/modules/cargo/markets/market_item.dm
@@ -5,7 +5,7 @@
var/desc
/// The category this item belongs to, should be already declared in the market that this item is accessible in.
var/category
- /// "/datum/market"s that this item should be in, used by SSblackmarket on init.
+ /// "/datum/market"s that this item should be in, used by SSmarket on init.
var/list/markets = list(/datum/market/blackmarket)
/// Price for the item, if not set creates a price according to the *_min and *_max vars.
@@ -27,7 +27,7 @@
var/stock_min = 1
/// Maximum amount that there should be of this item in the market if generated randomly.
var/stock_max = 0
- /// Probability for this item to be available. Used by SSblackmarket on init.
+ /// Probability for this item to be available. Used by SSmarket on init.
var/availability_prob
///The identifier for the market item, generated on runtime and used to access them in the market categories.
@@ -36,6 +36,9 @@
///If set, these will override the shipment methods set by the market
var/list/shipping_override
+ /// Can this item be restocked
+ var/restockable = TRUE
+
/datum/market_item/New()
if(isnull(price))
price = rand(price_min, price_max)
@@ -82,7 +85,7 @@
CRASH("Invalid item type for market item [item || "null"]")
/**
- * Buys the item and makes SSblackmarket handle it.
+ * Buys the item and makes SSmarket handle it.
*
* @param uplink The uplink that is buying the item.
* @param buyer The mob that is buying the item.
@@ -102,8 +105,8 @@
// Alright, the item has been purchased.
var/datum/market_purchase/purchase = new(src, uplink, shipping_method, legal_status)
- // SSblackmarket takes care of the shipping.
- if(SSblackmarket.queue_item(purchase))
+ // SSmarket takes care of the shipping.
+ if(SSmarket.queue_item(purchase))
stock--
buyer.log_message("has succesfully purchased [name] using [shipping_method] for shipping.", LOG_ECON)
return TRUE
@@ -139,7 +142,7 @@
/datum/market_purchase/Destroy()
entry = null
uplink = null
- SSblackmarket.queued_purchases -= src
+ SSmarket.queued_purchases -= src
return ..()
/datum/market_purchase/proc/on_instance_del(datum/source)
diff --git a/code/modules/cargo/markets/market_items/hostages.dm b/code/modules/cargo/markets/market_items/hostages.dm
index ed5b1f10a7fcf..702cea907bdeb 100644
--- a/code/modules/cargo/markets/market_items/hostages.dm
+++ b/code/modules/cargo/markets/market_items/hostages.dm
@@ -5,6 +5,7 @@
stock = 1
availability_prob = 100
shipping_override = list(SHIPPING_METHOD_LTSRBT = 0, SHIPPING_METHOD_SUPPLYPOD = 350)
+ restockable = FALSE
/// temporary reference to the 4 in 7 chances of signaler and electropack.
var/obj/item/assembly/signaler/signaler
diff --git a/code/modules/cargo/markets/market_items/stolen_goods.dm b/code/modules/cargo/markets/market_items/stolen_goods.dm
index 02a72f05d26d1..cb1932673e0e3 100644
--- a/code/modules/cargo/markets/market_items/stolen_goods.dm
+++ b/code/modules/cargo/markets/market_items/stolen_goods.dm
@@ -4,6 +4,7 @@
abstract_path = /datum/market_item/stolen_good
stock = 1
availability_prob = 100
+ restockable = FALSE
/datum/market_item/stolen_good/New(atom/movable/thing, thing_price)
..()
diff --git a/code/modules/cargo/markets/market_items/tools.dm b/code/modules/cargo/markets/market_items/tools.dm
index 963d7fbaeb075..0c9969756d30f 100644
--- a/code/modules/cargo/markets/market_items/tools.dm
+++ b/code/modules/cargo/markets/market_items/tools.dm
@@ -11,7 +11,7 @@
stock_min = 2
stock_max = 4
price_min = CARGO_CRATE_VALUE * 2.5
- price_max = CARGO_CRATE_VALUE * 3.75
+ price_max = CARGO_CRATE_VALUE * 3.25
availability_prob = 100
/datum/market_item/tool/caravan_wrench
diff --git a/code/modules/cargo/markets/market_telepad.dm b/code/modules/cargo/markets/market_telepad.dm
index 7c5b509a9421d..799395f30d125 100644
--- a/code/modules/cargo/markets/market_telepad.dm
+++ b/code/modules/cargo/markets/market_telepad.dm
@@ -1,3 +1,5 @@
+#define DEFAULT_RESTOCK_COST 675
+
/obj/item/circuitboard/machine/ltsrbt
name = "LTSRBT (Machine Board)"
icon_state = "bluespacearray"
@@ -13,7 +15,8 @@
name = "Long-To-Short-Range-Bluespace-Transceiver"
desc = "The LTSRBT is a compact teleportation machine for receiving and sending items outside the station and inside the station.\nUsing teleportation frequencies stolen from NT it is near undetectable.\nEssential for any illegal market operations on NT stations.\n"
icon = 'icons/obj/machines/telecomms.dmi'
- icon_state = "exonet_node"
+ icon_state = "exonet_node_idle"
+ base_icon_state = "exonet_node"
circuit = /obj/item/circuitboard/machine/ltsrbt
density = TRUE
@@ -35,18 +38,42 @@
var/datum/market_purchase/transmitting
/// Queue for purchases that the machine should receive and send.
var/list/datum/market_purchase/queue = list()
+ /**
+ * Attacking the machinery with enough credits will restock the markets, allowing for more/better items.
+ * The cost doubles each time this is done.
+ */
+ var/static/restock_cost = DEFAULT_RESTOCK_COST
/obj/machinery/ltsrbt/Initialize(mapload)
. = ..()
- SSblackmarket.telepads += src
+ register_context()
+ SSmarket.telepads += src
/obj/machinery/ltsrbt/Destroy()
- SSblackmarket.telepads -= src
+ SSmarket.telepads -= src
// Bye bye orders.
- if(length(SSblackmarket.telepads))
+ if(length(SSmarket.telepads))
for(var/datum/market_purchase/P in queue)
- SSblackmarket.queue_item(P)
+ SSmarket.queue_item(P)
+ . = ..()
+
+/obj/machinery/ltsrbt/add_context(atom/source, list/context, obj/item/held_item, mob/user)
+ if(held_item && held_item.get_item_credit_value())
+ context[SCREENTIP_CONTEXT_LMB] = "Restock"
+ return CONTEXTUAL_SCREENTIP_SET
+ return NONE
+
+/obj/machinery/ltsrbt/examine(mob/user)
. = ..()
+ if(machine_stat & NOPOWER)
+ . += span_info("A display reads: \"Current market restock price: [EXAMINE_HINT("[restock_cost] cr")]\".")
+
+/obj/machinery/ltsrbt/update_icon_state()
+ . = ..()
+ if(machine_stat & NOPOWER)
+ icon_state = "[base_icon_state]_off"
+ else
+ icon_state = "[base_icon_state][(receiving || length(queue)) ? "" : "_idle"]"
/obj/machinery/ltsrbt/RefreshParts()
. = ..()
@@ -67,6 +94,7 @@
/obj/machinery/ltsrbt/proc/add_to_queue(datum/market_purchase/purchase)
if(!recharge_cooldown && !receiving && !transmitting)
receiving = purchase
+ update_appearance(UPDATE_ICON_STATE)
else
queue += purchase
@@ -80,6 +108,8 @@
if(transmitting == purchase)
transmitting = null
+ update_appearance(UPDATE_ICON_STATE)
+
/obj/machinery/ltsrbt/process(seconds_per_tick)
if(machine_stat & NOPOWER)
return
@@ -113,3 +143,32 @@
if(length(queue))
receiving = pick_n_take(queue)
+
+/obj/machinery/ltsrbt/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ var/creds_value = tool.get_item_credit_value()
+ if(!creds_value)
+ return NONE
+
+ . = ITEM_INTERACT_SUCCESS
+
+ if(machine_stat & NOPOWER)
+ return
+
+ if(creds_value < restock_cost)
+ say("Insufficient credits!")
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 40, FALSE)
+ return
+
+ if(istype(tool, /obj/item/holochip))
+ var/obj/item/holochip/chip = tool
+ chip.spend(restock_cost)
+ else
+ qdel(tool)
+ if(creds_value != restock_cost)
+ var/obj/item/holochip/change = new(creds_value - restock_cost)
+ user.put_in_hands(change)
+
+ SSmarket.restock()
+ restock_cost *= 2
+
+#undef DEFAULT_RESTOCK_COST
diff --git a/code/modules/cargo/markets/market_uplink.dm b/code/modules/cargo/markets/market_uplink.dm
index d13f59937b66c..a324a2f0409be 100644
--- a/code/modules/cargo/markets/market_uplink.dm
+++ b/code/modules/cargo/markets/market_uplink.dm
@@ -20,7 +20,7 @@
/obj/item/market_uplink/Initialize(mapload)
. = ..()
- // We don't want to go through this at mapload because the SSblackmarket isn't initialized yet.
+ // We don't want to go through this at mapload because the SSmarket isn't initialized yet.
if(mapload)
return
@@ -30,7 +30,7 @@
/obj/item/market_uplink/proc/update_viewing_category()
if(accessible_markets.len)
viewing_market = accessible_markets[1]
- var/list/categories = SSblackmarket.markets[viewing_market].categories
+ var/list/categories = SSmarket.markets[viewing_market].categories
if(categories?.len)
viewing_category = categories[1]
@@ -45,7 +45,7 @@
/obj/item/market_uplink/ui_data(mob/user)
var/list/data = list()
- var/datum/market/market = viewing_market ? SSblackmarket.markets[viewing_market] : null
+ var/datum/market/market = viewing_market ? SSmarket.markets[viewing_market] : null
var/obj/item/card/id/id_card
if(isliving(user))
var/mob/living/livin = user
@@ -86,11 +86,11 @@
/obj/item/market_uplink/ui_static_data(mob/user)
var/list/data = list()
- data["delivery_method_description"] = SSblackmarket.shipping_method_descriptions
- data["ltsrbt_built"] = SSblackmarket.telepads.len
+ data["delivery_method_description"] = SSmarket.shipping_method_descriptions
+ data["ltsrbt_built"] = SSmarket.telepads.len
data["markets"] = list()
for(var/M in accessible_markets)
- var/datum/market/BM = SSblackmarket.markets[M]
+ var/datum/market/BM = SSmarket.markets[M]
data["markets"] += list(list(
"id" = M,
"name" = BM.name
@@ -107,7 +107,7 @@
return
if(isnull(viewing_market))
return
- if(!(params["category"] in SSblackmarket.markets[viewing_market].categories))
+ if(!(params["category"] in SSmarket.markets[viewing_market].categories))
return
viewing_category = params["category"]
. = TRUE
@@ -120,7 +120,7 @@
viewing_market = market
- var/list/categories = SSblackmarket.markets[viewing_market].categories
+ var/list/categories = SSmarket.markets[viewing_market].categories
if(categories?.len)
viewing_category = categories[1]
else
@@ -142,7 +142,7 @@
if(isnull(selected_item))
buying = FALSE
return
- var/datum/market/market = SSblackmarket.markets[viewing_market]
+ var/datum/market/market = SSmarket.markets[viewing_market]
market.purchase(selected_item, viewing_category, params["method"], src, usr)
buying = FALSE
diff --git a/code/modules/cargo/packs/imports.dm b/code/modules/cargo/packs/imports.dm
index f270b1da11f39..98fc4d650212c 100644
--- a/code/modules/cargo/packs/imports.dm
+++ b/code/modules/cargo/packs/imports.dm
@@ -318,3 +318,20 @@
)
crate_name = "floortile camouflauge crate"
crate_type = /obj/structure/closet/crate/secure/weapon
+
+/**
+ * The Long To Short Range Bluespace Teleporter, used to deliver (black) market purchases more effiiently
+ * It can also be used to restock it, if you hit it with enough credits.
+ */
+/datum/supply_pack/imports/blackmarket_telepad
+ name = "Black Market LTSRBT"
+ desc = "Need a faster and better way of transporting your illegal goods from and to the \
+ station? Fear not, the Long-To-Short-Range-Bluespace-Transceiver (LTSRBT for short) \
+ is here to help. Contains a LTSRBT circuit, two bluespace crystals, and one ansible."
+ cost = CARGO_CRATE_VALUE * 10
+ contraband = TRUE
+ contains = list(
+ /obj/item/circuitboard/machine/ltsrbt,
+ /obj/item/stack/ore/bluespace_crystal/artificial = 2,
+ /obj/item/stock_parts/subspace/ansible,
+ )
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index e3f74e47c497d..ac3d6af179622 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -1206,6 +1206,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
winset(usr, "mainwindow", "can-resize=true")
winset(usr, "mainwindow", "is-maximized=false")
winset(usr, "mainwindow", "on-size=attempt_auto_fit_viewport")
+ attempt_auto_fit_viewport()
/client/verb/toggle_status_bar()
set name = "Toggle Status Bar"
diff --git a/code/modules/client/preferences/sounds.dm b/code/modules/client/preferences/sounds.dm
index f1778405665ad..4a0298132c268 100644
--- a/code/modules/client/preferences/sounds.dm
+++ b/code/modules/client/preferences/sounds.dm
@@ -116,3 +116,9 @@
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
savefile_key = "sound_elevator"
savefile_identifier = PREFERENCE_PLAYER
+
+/// Controls hearing radio noise
+/datum/preference/toggle/radio_noise
+ category = PREFERENCE_CATEGORY_GAME_PREFERENCES
+ savefile_key = "sound_radio_noise"
+ savefile_identifier = PREFERENCE_PLAYER
diff --git a/code/modules/food_and_drinks/machinery/processor.dm b/code/modules/food_and_drinks/machinery/processor.dm
index 21d49808beda1..383a7c34e2756 100644
--- a/code/modules/food_and_drinks/machinery/processor.dm
+++ b/code/modules/food_and_drinks/machinery/processor.dm
@@ -159,7 +159,9 @@
var/duration = (total_time / rating_speed)
INVOKE_ASYNC(src, TYPE_PROC_REF(/atom, Shake), 1, 0, duration)
- sleep(duration)
+ addtimer(CALLBACK(src, PROC_REF(complete_processing)), duration)
+
+/obj/machinery/processor/proc/complete_processing()
for(var/atom/movable/content_item in processor_contents)
var/datum/food_processor_process/recipe = PROCESSOR_SELECT_RECIPE(content_item)
if (!recipe)
diff --git a/code/modules/mafia/roles/roles.dm b/code/modules/mafia/roles/roles.dm
index ab1a1cc0e454b..4cfd7662d843e 100644
--- a/code/modules/mafia/roles/roles.dm
+++ b/code/modules/mafia/roles/roles.dm
@@ -189,6 +189,6 @@
team_span = "comradio"
the = FALSE
result += span_notice("The [span_bold("[name]")] is aligned with [the ? "the " : ""][team_desc]")
- result += "\"[desc]\""
+ result += "\"[initial(desc)]\""
result += span_notice("[name] wins when they [win_condition]")
to_chat(clueless, result.Join(""))
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 418b07ebf2669..b007da827da14 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -352,6 +352,7 @@
message_mime = "acts out a scream!"
emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
mob_type_blacklist_typecache = list(/mob/living/brain, /mob/living/carbon/human)
+ sound_wall_ignore = TRUE
/datum/emote/living/scream/run_emote(mob/user, params, type_override, intentional = FALSE)
if(!intentional && HAS_TRAIT(user, TRAIT_ANALGESIA))
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 2873dab1a71bc..a7531439573e5 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -2663,7 +2663,7 @@ GLOBAL_LIST_EMPTY(fire_appearances)
///The price should be high enough that the contractor can't just buy 'em back with their cut alone.
var/datum/market_item/hostage/market_item = new(src, black_market_price || ransom_price)
- SSblackmarket.markets[/datum/market/blackmarket].add_item(market_item)
+ SSmarket.markets[/datum/market/blackmarket].add_item(market_item)
if(mind)
ADD_TRAIT(mind, TRAIT_HAS_BEEN_KIDNAPPED, TRAIT_GENERIC)
diff --git a/code/modules/mob/living/sneeze.dm b/code/modules/mob/living/sneeze.dm
index b2cf76c25a6b0..4c38027fda0d8 100644
--- a/code/modules/mob/living/sneeze.dm
+++ b/code/modules/mob/living/sneeze.dm
@@ -57,6 +57,7 @@
spread = 40
damage_type = BRUTE
damage = 0
+ hitsound = null
/// Call this when we hit something
var/datum/callback/sneezie_callback
diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm
index 815cfb0a144bc..18c89600573cf 100644
--- a/code/modules/mod/modules/modules_general.dm
+++ b/code/modules/mod/modules/modules_general.dm
@@ -174,9 +174,6 @@
required_slots = list(ITEM_SLOT_BACK)
/obj/item/mod/module/jump_jet/on_use()
- . = ..()
- if (!.)
- return FALSE
if (DOING_INTERACTION(mod.wearer, mod.wearer))
balloon_alert(mod.wearer, "busy!")
return
diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm
index 19150b8a4cd67..703cf197dc76d 100644
--- a/code/modules/mod/modules/modules_security.dm
+++ b/code/modules/mod/modules/modules_security.dm
@@ -269,7 +269,7 @@
dispense_type = /obj/item/grenade/mirage
/obj/item/mod/module/dispenser/mirage/on_use()
- var/obj/item/grenade/mirage/grenade = .
+ var/obj/item/grenade/mirage/grenade = ..()
grenade.arm_grenade(mod.wearer)
/obj/item/grenade/mirage
diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm
index 49793c1ad2de2..16045a760324c 100644
--- a/code/modules/surgery/amputation.dm
+++ b/code/modules/surgery/amputation.dm
@@ -27,6 +27,13 @@
/datum/surgery_step/sever_limb/mechanic, //The benefit of being robotic; people can pull you apart in an instant! Wait, that's not a benefit...
)
+/datum/surgery/amputation/peg
+ name = "Detach"
+ requires_bodypart_type = BODYTYPE_PEG
+ steps = list(
+ /datum/surgery_step/sever_limb/peg, //Easy come, easy go
+ )
+
/datum/surgery/amputation/can_start(mob/user, mob/living/patient)
if(HAS_TRAIT(patient, TRAIT_NODISMEMBER))
return FALSE
@@ -62,6 +69,19 @@
preop_sound = 'sound/items/ratchet.ogg'
preop_sound = 'sound/machines/doorclick.ogg'
+/datum/surgery_step/sever_limb/peg
+ name = "detach limb (circular saw)"
+ implements = list(
+ TOOL_SAW = 100,
+ /obj/item/shovel/serrated = 100,
+ /obj/item/fireaxe = 90,
+ /obj/item/hatchet = 75,
+ TOOL_SCALPEL = 25,
+ )
+ time = 30
+ preop_sound = 'sound/surgery/saw.ogg'
+ success_sound = 'sound/items/wood_drop.ogg'
+
/datum/surgery_step/sever_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(
user,
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index 350bd60fbd176..336e76b4d70c2 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -96,6 +96,12 @@
var/fail_prob = 0//100 - fail_prob = success_prob
var/advance = FALSE
+ if(!chem_check(target))
+ user.balloon_alert(user, "missing [LOWER_TEXT(get_chem_list())]!")
+ to_chat(user, span_warning("[target] is missing the [LOWER_TEXT(get_chem_list())] required to perform this surgery step!"))
+ surgery.step_in_progress = FALSE
+ return FALSE
+
if(preop(user, target, target_zone, tool, surgery) == SURGERY_STEP_FAIL)
update_surgery_mood(target, SURGERY_STATE_FAILURE)
surgery.step_in_progress = FALSE
@@ -134,9 +140,7 @@
if(do_after(user, modded_time, target = target, interaction_key = user.has_status_effect(/datum/status_effect/hippocratic_oath) ? target : DOAFTER_SOURCE_SURGERY)) //If we have the hippocratic oath, we can perform one surgery on each target, otherwise we can only do one surgery in total.
- var/chem_check_result = chem_check(target)
- if((prob(100-fail_prob) || (iscyborg(user) && !silicons_obey_prob)) && chem_check_result && !try_to_fail)
-
+ if((prob(100-fail_prob) || (iscyborg(user) && !silicons_obey_prob)) && !try_to_fail)
if(success(user, target, target_zone, tool, surgery))
update_surgery_mood(target, SURGERY_STATE_SUCCESS)
play_success_sound(user, target, target_zone, tool, surgery)
@@ -146,8 +150,6 @@
play_failure_sound(user, target, target_zone, tool, surgery)
update_surgery_mood(target, SURGERY_STATE_FAILURE)
advance = TRUE
- if(chem_check_result)
- return .(user, target, target_zone, tool, surgery, try_to_fail) //automatically re-attempt if failed for reason other than lack of required chemical
if(advance && !repeatable)
surgery.status++
if(surgery.status > surgery.steps.len)
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index 911887cc8b900..a42c25dc94ee1 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -102,7 +102,6 @@
#include "bespoke_id.dm"
#include "binary_insert.dm"
#include "bitrunning.dm"
-#include "blackmarket.dm"
#include "blindness.dm"
#include "bloody_footprints.dm"
#include "breath.dm"
@@ -183,6 +182,7 @@
#include "mapload_space_verification.dm"
#include "mapping.dm"
#include "mapping_nearstation_test.dm"
+#include "market.dm"
#include "mecha_damage.dm"
#include "medical_wounds.dm"
#include "merge_type.dm"
diff --git a/code/modules/unit_tests/blackmarket.dm b/code/modules/unit_tests/blackmarket.dm
deleted file mode 100644
index 984e2ea815503..0000000000000
--- a/code/modules/unit_tests/blackmarket.dm
+++ /dev/null
@@ -1,23 +0,0 @@
-/// Ensures black market items have acceptable variable values.
-/datum/unit_test/blackmarket
-
-/datum/unit_test/blackmarket/Run()
- for(var/datum/market_item/prototype as anything in subtypesof(/datum/market_item))
- if(prototype::abstract_path == prototype) //skip abstract paths
- continue
- if(!prototype::category)
- TEST_FAIL("[prototype] doesn't have a set category (or the abstract path var isn't correctly set)")
- continue
- if(!prototype::item)
- TEST_FAIL("[prototype] doesn't have a set item (or the abstract path var isn't correctly set)")
- continue
- if(isnull(prototype::price) && prototype::price_max <= prototype::price_min)
- TEST_FAIL("[prototype] doesn't have a correctly set random price (price_max should be higher than price_min)")
- if(isnull(prototype::stock) && prototype::stock_max < prototype::stock_min)
- TEST_FAIL("[prototype] doesn't have a correctly set random stock (stock_max shouldn't be lower than stock_min)")
- if(!isnum(prototype::availability_prob))
- TEST_FAIL("[prototype] doesn't have a set availability_prob (must be a number)")
- if(!prototype::name)
- TEST_FAIL("[prototype] doesn't have a set name")
- if(!prototype::desc)
- TEST_FAIL("[prototype] doesn't have a set desc")
diff --git a/code/modules/unit_tests/market.dm b/code/modules/unit_tests/market.dm
new file mode 100644
index 0000000000000..022f277d879c0
--- /dev/null
+++ b/code/modules/unit_tests/market.dm
@@ -0,0 +1,59 @@
+#define CATEGORY_CODERBUS "Coderbus"
+/// Ensures market items have acceptable variable values and restocking works.
+/datum/unit_test/market
+
+/datum/unit_test/market/Run()
+ for(var/datum/market_item/prototype as anything in subtypesof(/datum/market_item))
+ if(prototype::abstract_path == prototype) //skip abstract paths
+ continue
+ if(!prototype::category)
+ TEST_FAIL("[prototype] doesn't have a set category (or the abstract path var isn't correctly set)")
+ continue
+ if(!prototype::item)
+ TEST_FAIL("[prototype] doesn't have a set item (or the abstract path var isn't correctly set)")
+ continue
+ if(isnull(prototype::price) && prototype::price_max <= prototype::price_min)
+ TEST_FAIL("[prototype] doesn't have a correctly set random price (price_max should be higher than price_min)")
+ if(isnull(prototype::stock) && prototype::stock_max < prototype::stock_min)
+ TEST_FAIL("[prototype] doesn't have a correctly set random stock (stock_max shouldn't be lower than stock_min)")
+ if(!isnum(prototype::availability_prob))
+ TEST_FAIL("[prototype] doesn't have a set availability_prob (must be a number)")
+ if(!prototype::name)
+ TEST_FAIL("[prototype] doesn't have a set name")
+ if(!prototype::desc)
+ TEST_FAIL("[prototype] doesn't have a set desc")
+
+
+ var/datum/market/unit_test/market = SSmarket.markets[/datum/market/unit_test]
+ TEST_ASSERT(market, "Couldn't find the unit test market")
+ var/list/category_items = market.available_items[CATEGORY_CODERBUS]
+ var/datum/market_item/unit_test/item = category_items[category_items[1]]
+ TEST_ASSERT(item, "Couldn't find the unit test market item")
+ TEST_ASSERT_EQUAL(item.stock, 1, "The unit test market item is incorrectly stocked. Only one should be in stock")
+
+ var/mob/living/user = allocate(/mob/living)
+ var/obj/item/holochip/chip = allocate(/obj/item/holochip, run_loc_floor_bottom_left, INFINITY)
+ var/obj/machinery/ltsrbt/pad = allocate(/obj/machinery/ltsrbt)
+
+ pad.item_interaction(user, chip)
+
+ TEST_ASSERT_EQUAL(item, category_items[category_items[1]], "The unit test market item has been replaced during restock")
+ TEST_ASSERT_EQUAL(item.stock, 2, "The unit test market item is incorrectly stocked after restock. There should be two in stock")
+
+/datum/market/unit_test
+ name = "Unit Test Market"
+ shipping = list(SHIPPING_METHOD_TELEPORT = 0)
+
+/datum/market_item/unit_test
+ name = "Your Own Special Singularity"
+ desc = "ALL HAIL LORD SINGULOTH!!!"
+ category = CATEGORY_CODERBUS
+ markets = list(/datum/market/unit_test)
+ item = /obj/singularity
+ price = 42069
+ stock_min = 1
+ stock = 1
+ stock_max = 2
+ availability_prob = 100
+
+#undef CATEGORY_CODERBUS
diff --git a/code/modules/uplink/uplink_devices.dm b/code/modules/uplink/uplink_devices.dm
index 596ea9e1ffad4..3c31ddf647f88 100644
--- a/code/modules/uplink/uplink_devices.dm
+++ b/code/modules/uplink/uplink_devices.dm
@@ -48,7 +48,7 @@
hidden_uplink.uplink_handler.debug_mode = TRUE
/obj/item/uplink/nuclear
- uplink_flag = UPLINK_ALL_SYNDIE_OPS
+ uplink_flag = UPLINK_NUKE_OPS
/obj/item/uplink/nuclear/debug
name = "debug nuclear uplink"
diff --git a/code/modules/vehicles/mecha/combat/justice.dm b/code/modules/vehicles/mecha/combat/justice.dm
index e99632394a1b7..00b0543dbd865 100644
--- a/code/modules/vehicles/mecha/combat/justice.dm
+++ b/code/modules/vehicles/mecha/combat/justice.dm
@@ -170,10 +170,10 @@
. = ..()
RegisterSignal(chassis, COMSIG_MECH_SAFETIES_TOGGLE, PROC_REF(on_toggle_safety))
-/// update button icon when toggle safety.
+/// update button icon when toggle safety and turns invisibility off.
/datum/action/vehicle/sealed/mecha/invisibility/proc/on_toggle_safety()
SIGNAL_HANDLER
-
+ invisibility_off()
build_all_button_icons(UPDATE_BUTTON_STATUS)
/datum/action/vehicle/sealed/mecha/invisibility/Trigger(trigger_flags)
diff --git a/html/changelogs/AutoChangeLog-pr-84911.yml b/html/changelogs/AutoChangeLog-pr-84911.yml
deleted file mode 100644
index 15f42399bc42d..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-84911.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "mc-oofert"
-delete-after: True
-changes:
- - bugfix: "wawastation ordnance no longer has a light fixture on a window and looks objectively slightly better"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85090.yml b/html/changelogs/AutoChangeLog-pr-85090.yml
deleted file mode 100644
index 9e3a467c58459..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85090.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "carlarctg"
-delete-after: True
-changes:
- - bugfix: "Fixed possessed blades being broken"
- - code_imp: "If testing is enabled everyone is polled in ghost polls."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85109.yml b/html/changelogs/AutoChangeLog-pr-85109.yml
deleted file mode 100644
index e20f9ac086df9..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85109.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Jacquerel"
-delete-after: True
-changes:
- - balance: "If a bluespace cookie fails to teleport you then you will trip over."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85112.yml b/html/changelogs/AutoChangeLog-pr-85112.yml
deleted file mode 100644
index ac57dc49f8267..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85112.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Melbert"
-delete-after: True
-changes:
- - qol: "All randomly spawned monkeys (and lizardpeople) will spawn with tails. You can still select to be tailless."
- - code_imp: "Cleaned up some code relating to species features (like tails, markings, etc). Report any oddities"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85146.yml b/html/changelogs/AutoChangeLog-pr-85146.yml
deleted file mode 100644
index 4d524bbe89c10..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85146.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscdel: "Removed a janky fish bounty"
- - rscadd: "introduced exporting fish through cargo."
- - balance: "reduced the average weight of the jumpercable. Conversely, eased up the requirements for the bone fish evolution."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85149.yml b/html/changelogs/AutoChangeLog-pr-85149.yml
deleted file mode 100644
index dc90b18f21f72..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85149.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ical92"
-delete-after: True
-changes:
- - bugfix: "Tram's Tool Storage now has proper lighting"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85210.yml b/html/changelogs/AutoChangeLog-pr-85210.yml
deleted file mode 100644
index 4b43465ca8faa..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85210.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "LT3"
-delete-after: True
-changes:
- - bugfix: "Fixed delam counter stuck in window near Ice Box bridge"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85212.yml b/html/changelogs/AutoChangeLog-pr-85212.yml
deleted file mode 100644
index 8d41701d3a528..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85212.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "afonamos2"
-delete-after: True
-changes:
- - bugfix: "Firelocks will once again respect fire alarm's thermal sensors being disabled."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85216.yml b/html/changelogs/AutoChangeLog-pr-85216.yml
deleted file mode 100644
index a61c550b0ad8c..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85216.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes projectiles facing north if ricocheting, deflected or homing"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85218.yml b/html/changelogs/AutoChangeLog-pr-85218.yml
deleted file mode 100644
index 24c53559ee302..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85218.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "MTandi"
-delete-after: True
-changes:
- - bugfix: "Janicart inserts items into the attached trash bag again (manual and vacuumed)"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85219.yml b/html/changelogs/AutoChangeLog-pr-85219.yml
deleted file mode 100644
index 8d9798199dd75..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85219.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "mc-oofert"
-delete-after: True
-changes:
- - bugfix: "wawastation engineering water tanks are now highcap"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85225.yml b/html/changelogs/AutoChangeLog-pr-85225.yml
deleted file mode 100644
index 1404f3a3d6928..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85225.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "SmArtKar"
-delete-after: True
-changes:
- - image: "Updated gas flow meter sprites"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85229.yml b/html/changelogs/AutoChangeLog-pr-85229.yml
deleted file mode 100644
index 61a3ea84506bd..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85229.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "LT3"
-delete-after: True
-changes:
- - bugfix: "Tram will no longer eat its own rails as it travels"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85230.yml b/html/changelogs/AutoChangeLog-pr-85230.yml
deleted file mode 100644
index 158caf8e0417c..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85230.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "LT3"
-delete-after: True
-changes:
- - bugfix: "False supermatter surge announcements are now identical to real ones"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85231.yml b/html/changelogs/AutoChangeLog-pr-85231.yml
deleted file mode 100644
index 62f9c64c5066b..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85231.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "LT3"
-delete-after: True
-changes:
- - bugfix: "Fixed disease outbreak announcement sometimes missing the disease name"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85232.yml b/html/changelogs/AutoChangeLog-pr-85232.yml
deleted file mode 100644
index baace7da19785..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85232.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "00-Steven"
-delete-after: True
-changes:
- - bugfix: "Fixes borgs not being able to place apparatus-held items on tables. As a side-effect, they can now combat mode right click splash containers as normal instead of having their own right-click floor splash."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85241.yml b/html/changelogs/AutoChangeLog-pr-85241.yml
deleted file mode 100644
index 09bf7dc1d9727..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-85241.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Thlumyn"
-delete-after: True
-changes:
- - bugfix: "self-resp viruses don't spam messages as often"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85251.yml b/html/changelogs/AutoChangeLog-pr-85251.yml
new file mode 100644
index 0000000000000..b40f87748a9d1
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-85251.yml
@@ -0,0 +1,4 @@
+author: "SmArtKar"
+delete-after: True
+changes:
+ - bugfix: "Recyclers no longer recycle contents of indestructible items"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85302.yml b/html/changelogs/AutoChangeLog-pr-85302.yml
new file mode 100644
index 0000000000000..3797ee383bcb6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-85302.yml
@@ -0,0 +1,4 @@
+author: "SmArtKar"
+delete-after: True
+changes:
+ - qol: "If you have auto fit viewport enabled, it will trigger upon entering or exiting fullscreen"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-85305.yml b/html/changelogs/AutoChangeLog-pr-85305.yml
new file mode 100644
index 0000000000000..14da28c2ee27d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-85305.yml
@@ -0,0 +1,5 @@
+author: "Time-Green"
+delete-after: True
+changes:
+ - bugfix: "Fixes void eater not refreshing"
+ - bugfix: "Fixes planetary gravity not killing voidwalkers and voideds"
\ No newline at end of file
diff --git a/html/changelogs/archive/2024-07.yml b/html/changelogs/archive/2024-07.yml
index 5e63f121a0d6c..55c4a30a517d8 100644
--- a/html/changelogs/archive/2024-07.yml
+++ b/html/changelogs/archive/2024-07.yml
@@ -1324,3 +1324,87 @@
- rscadd: Two new arrow variants appear in the crafting menu; sticky and poisonous
ones! If you want to make arrows at all though, remember to order bow-maker's
crate at cargo.
+2024-07-27:
+ 00-Steven:
+ - bugfix: Fixes borgs not being able to place apparatus-held items on tables. As
+ a side-effect, they can now combat mode right click splash containers as normal
+ instead of having their own right-click floor splash.
+ Ghommie:
+ - bugfix: Centcom technicians have been trained to recognize cargo-bought fish.
+ You will no longer be able to trick the economy system by buying fish and sending
+ it right back. Also nerfed fish selling price very slightly.
+ - bugfix: Fixes projectiles facing north if ricocheting, deflected or homing
+ - rscdel: Removed a janky fish bounty
+ - rscadd: introduced exporting fish through cargo.
+ - balance: reduced the average weight of the jumpercable. Conversely, eased up the
+ requirements for the bone fish evolution.
+ Ical92:
+ - bugfix: Tram's Tool Storage now has proper lighting
+ Jacquerel:
+ - balance: If a bluespace cookie fails to teleport you then you will trip over.
+ LT3:
+ - bugfix: Fixed delam counter stuck in window near Ice Box bridge
+ - bugfix: Fixed disease outbreak announcement sometimes missing the disease name
+ - bugfix: False supermatter surge announcements are now identical to real ones
+ - bugfix: Tram will no longer eat its own rails as it travels
+ MTandi:
+ - bugfix: Janicart inserts items into the attached trash bag again (manual and vacuumed)
+ Melbert:
+ - qol: All randomly spawned monkeys (and lizardpeople) will spawn with tails. You
+ can still select to be tailless.
+ - code_imp: Cleaned up some code relating to species features (like tails, markings,
+ etc). Report any oddities
+ SmArtKar:
+ - image: Updated gas flow meter sprites
+ Thlumyn:
+ - bugfix: self-resp viruses don't spam messages as often
+ afonamos2:
+ - bugfix: Firelocks will once again respect fire alarm's thermal sensors being disabled.
+ carlarctg:
+ - bugfix: Fixed possessed blades being broken
+ - code_imp: If testing is enabled everyone is polled in ghost polls.
+ mc-oofert:
+ - bugfix: wawastation ordnance no longer has a light fixture on a window and looks
+ objectively slightly better
+ - bugfix: wawastation engineering water tanks are now highcap
+2024-07-28:
+ 00-Steven:
+ - bugfix: Clicking on a table in the lootpanel with an item in-hand tries to place
+ it in the center again.
+ Axidyuwu:
+ - bugfix: now Justice invisibility turns off in non combat mode as it supposed to
+ Deadgebert:
+ - bugfix: peg limbs can now be amputated
+ DrDiasyl aka DrTuxedo:
+ - sound: Hearing and talking into the radio now produces a sound. Heads get a special
+ sound.
+ Helg2:
+ - rscadd: Emergency climbing hooks now spawn in emergency boxes on all of the multi-z
+ level stations.
+ JohnFulpWillard:
+ - bugfix: '[Mafia] The show_help button no longer shows you who the Obsessed''s
+ target is.'
+ LT3:
+ - bugfix: Players now receive a notification when trying to perform surgery steps
+ that involve chemicals
+ Rhials:
+ - bugfix: Monkey wizards can now interact with grand ritual runes.
+ - bugfix: Clown Ops gear has been returned to being available only to clown ops.
+ Whoops!
+ SmArtKar:
+ - bugfix: People with tooltips enabled no longer lag the server when they move their
+ mouse. Oops.
+ - bugfix: Mirage grenade dispensers and ionic jump jets now work
+ StrangeWeirdKitten:
+ - bugfix: Voidwalker should not run on planetary maps.
+ grungussuss:
+ - bugfix: Med sec telescreens are no longer the same item as the CMO telescreen.
+ - spellcheck: correcte name for the CMO telescreen mount
+ - bugfix: birdshot holodeck's lighting has been fixed.
+ - sound: medkits now have sounds
+ - sound: gas tanks now have sound
+ - sound: the default metal sound has been changed
+ - bugfix: lavaland no longer has roundstart atmos processing because of a passive
+ vent
+ - sound: only the scream emote can be heard through walls
+ - sound: the sneeze projectile no longer makes a sound when making contact.
diff --git a/icons/obj/machines/telecomms.dmi b/icons/obj/machines/telecomms.dmi
index 1af082171ac16..f1380268c29cf 100644
Binary files a/icons/obj/machines/telecomms.dmi and b/icons/obj/machines/telecomms.dmi differ
diff --git a/sound/items/attributions.txt b/sound/items/attributions.txt
index 31b573c105893..592b1855aaebc 100644
--- a/sound/items/attributions.txt
+++ b/sound/items/attributions.txt
@@ -5,7 +5,7 @@ cig_snuff.ogg
lighter_on.ogg
lighter_off.ogg
zippo_onn.ogg
-zippo_off.ogg
+zippo_off.ogg
} - Taken from https://github.com/BeeStation/BeeStation-Hornet/pull/29
pen_click.ogg from https://freesound.org/people/LexzachGames/sounds/431492/ , license: CC0
@@ -13,7 +13,7 @@ pen_click.ogg from https://freesound.org/people/LexzachGames/sounds/431492/ , li
night_vision_on.ogg by Syna-Max -- https://freesound.org/s/60345/ -- License: Attribution NonCommercial 4.0
{
-metal_drop.ogg - https://freesound.org/people/13FPanská_Tolar_David/sounds/378682/ , License: CC0
+metal_drop.ogg - https://freesound.org/people/Robinhood76/sounds/85418/ , License: CC BY-NC 4.0
metal_pick_up.ogg - https://freesound.org/people/Hotlavaman/sounds/108673/ , License: CC0
glass_drop.ogg - https://freesound.org/people/Hotlavaman/sounds/108673/ , License: CC0
glass_pick_up.ogg - https://freesound.org/people/tcrocker68/sounds/235602/ , License: CC0
@@ -22,4 +22,16 @@ wood_drop.ogg - https://freesound.org/people/cjosephwalker/sounds/94859/ , Licen
irod_rod_pick_up.ogg - https://freesound.org/people/lostphosphene/sounds/258265/ , License: CC BY 4.0
plastic_pick_up.ogg - https://freesound.org/people/Jessica190091/sounds/491304/ , License: CC BY 4.0
plastic_drop.ogg - https://freesound.org/people/martian/sounds/338854/ , License: CC0
-} - edited by sadboysuss
\ No newline at end of file
+} - edited by sadboysuss
+
+{
+ medkit_open.ogg - https://freesound.org/people/Jandre160108/sounds/365866/ , License: CC BY-NC 4.0
+ medkit_drop.ogg - https://freesound.org/people/Jandre160108/sounds/365866/ , License: CC BY-NC 4.0
+ medkit_pick_up.ogg - https://freesound.org/people/blouhond/sounds/440710/ , License: CC BY 4.0
+} - edited by sadboysuss
+
+{
+gas_tank_drop.ogg
+gas_tank_pick_up.ogg
+} - https://freesound.org/people/Globofonia/sounds/698346/ , License CC0
+edited by grungussuss
diff --git a/sound/items/gas_tank_drop.ogg b/sound/items/gas_tank_drop.ogg
new file mode 100644
index 0000000000000..e102cb4fe8aad
Binary files /dev/null and b/sound/items/gas_tank_drop.ogg differ
diff --git a/sound/items/gas_tank_pick_up.ogg b/sound/items/gas_tank_pick_up.ogg
new file mode 100644
index 0000000000000..41c83645da609
Binary files /dev/null and b/sound/items/gas_tank_pick_up.ogg differ
diff --git a/sound/items/medkit_drop.ogg b/sound/items/medkit_drop.ogg
new file mode 100644
index 0000000000000..227d4a8beb220
Binary files /dev/null and b/sound/items/medkit_drop.ogg differ
diff --git a/sound/items/medkit_open.ogg b/sound/items/medkit_open.ogg
new file mode 100644
index 0000000000000..63307783d2f77
Binary files /dev/null and b/sound/items/medkit_open.ogg differ
diff --git a/sound/items/medkit_pick_up.ogg b/sound/items/medkit_pick_up.ogg
new file mode 100644
index 0000000000000..e13c6848e44df
Binary files /dev/null and b/sound/items/medkit_pick_up.ogg differ
diff --git a/sound/items/metal_drop.ogg b/sound/items/metal_drop.ogg
index 48460e8cd37bf..46488dca29fd3 100644
Binary files a/sound/items/metal_drop.ogg and b/sound/items/metal_drop.ogg differ
diff --git a/sound/misc/license.txt b/sound/misc/license.txt
index 69ef29928202c..761a031d19081 100644
--- a/sound/misc/license.txt
+++ b/sound/misc/license.txt
@@ -5,4 +5,13 @@ knuckles.ogg by CGEffex. Shortened and cut.
https://freesound.org/people/CGEffex/sounds/93981/
airraid.ogg by Jwade722. Shortened and cut.
-https://freesound.org/people/Jwade722/sounds/534550/
\ No newline at end of file
+https://freesound.org/people/Jwade722/sounds/534550/
+
+radio_talk.ogg by cs2975871. Shortened and cut.
+https://freesound.org/people/cs2975871/sounds/514185/
+
+radio_important.ogg by morganpurkis.
+https://freesound.org/people/morganpurkis/sounds/392972/
+
+radio_receive.ogg by JovianSounds. Shortened and cut.
+https://freesound.org/people/JovianSounds/sounds/524205/
\ No newline at end of file
diff --git a/sound/misc/radio_important.ogg b/sound/misc/radio_important.ogg
new file mode 100644
index 0000000000000..bb6f769d6129b
Binary files /dev/null and b/sound/misc/radio_important.ogg differ
diff --git a/sound/misc/radio_receive.ogg b/sound/misc/radio_receive.ogg
new file mode 100644
index 0000000000000..6b2ee1ba4ef08
Binary files /dev/null and b/sound/misc/radio_receive.ogg differ
diff --git a/sound/misc/radio_talk.ogg b/sound/misc/radio_talk.ogg
new file mode 100644
index 0000000000000..50d14c897a0ef
Binary files /dev/null and b/sound/misc/radio_talk.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index e4796cf955de5..d5ec19775013b 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -51,7 +51,6 @@
#include "code\__DEFINES\basic_mobs.dm"
#include "code\__DEFINES\basketball.dm"
#include "code\__DEFINES\bitrunning.dm"
-#include "code\__DEFINES\blackmarket.dm"
#include "code\__DEFINES\blend_modes.dm"
#include "code\__DEFINES\blob_defines.dm"
#include "code\__DEFINES\blood.dm"
@@ -139,6 +138,7 @@
#include "code\__DEFINES\map_switch.dm"
#include "code\__DEFINES\mapping.dm"
#include "code\__DEFINES\maps.dm"
+#include "code\__DEFINES\market.dm"
#include "code\__DEFINES\maths.dm"
#include "code\__DEFINES\matrices.dm"
#include "code\__DEFINES\MC.dm"
@@ -301,7 +301,6 @@
#include "code\__DEFINES\dcs\signals\signals_backpack.dm"
#include "code\__DEFINES\dcs\signals\signals_beam.dm"
#include "code\__DEFINES\dcs\signals\signals_bitrunning.dm"
-#include "code\__DEFINES\dcs\signals\signals_blackmarket.dm"
#include "code\__DEFINES\dcs\signals\signals_blob.dm"
#include "code\__DEFINES\dcs\signals\signals_bot.dm"
#include "code\__DEFINES\dcs\signals\signals_camera.dm"
@@ -331,6 +330,7 @@
#include "code\__DEFINES\dcs\signals\signals_leash.dm"
#include "code\__DEFINES\dcs\signals\signals_lift.dm"
#include "code\__DEFINES\dcs\signals\signals_light_eater.dm"
+#include "code\__DEFINES\dcs\signals\signals_market.dm"
#include "code\__DEFINES\dcs\signals\signals_material_container.dm"
#include "code\__DEFINES\dcs\signals\signals_medical.dm"
#include "code\__DEFINES\dcs\signals\signals_mind.dm"
@@ -632,7 +632,6 @@
#include "code\controllers\subsystem\ban_cache.dm"
#include "code\controllers\subsystem\bitrunning.dm"
#include "code\controllers\subsystem\blackbox.dm"
-#include "code\controllers\subsystem\blackmarket.dm"
#include "code\controllers\subsystem\chat.dm"
#include "code\controllers\subsystem\circuit_component.dm"
#include "code\controllers\subsystem\dbcore.dm"
@@ -657,6 +656,7 @@
#include "code\controllers\subsystem\lua.dm"
#include "code\controllers\subsystem\machines.dm"
#include "code\controllers\subsystem\mapping.dm"
+#include "code\controllers\subsystem\market.dm"
#include "code\controllers\subsystem\materials.dm"
#include "code\controllers\subsystem\minor_mapping.dm"
#include "code\controllers\subsystem\mobs.dm"
diff --git a/tgui/packages/tgui/interfaces/OperatingComputer.jsx b/tgui/packages/tgui/interfaces/OperatingComputer.jsx
index 990fddcadd96e..8a87840e89a02 100644
--- a/tgui/packages/tgui/interfaces/OperatingComputer.jsx
+++ b/tgui/packages/tgui/interfaces/OperatingComputer.jsx
@@ -103,28 +103,24 @@ const PatientStateView = (props) => {
{procedure.next_step}
- {procedure.chems_needed && (
- <>
-
-
- Required Chemicals:
-
- {procedure.chems_needed}
- >
- )}
+ {procedure.chems_needed && (
+
+
+ {procedure.chems_needed}
+
+
+ )}
{procedure.alternative_step && (
{procedure.alternative_step}
- {procedure.alt_chems_needed && (
- <>
-
-
- Required Chemicals:
-
- {procedure.alt_chems_needed}
- >
- )}
+
+ )}
+ {procedure.alt_chems_needed && (
+
+
+ {procedure.alt_chems_needed}
+
)}
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx
index 6f0f81237e495..f190f6c238762 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx
@@ -108,3 +108,11 @@ export const sound_achievement: FeatureChoiced = {
`,
component: FeatureDropdownInput,
};
+
+export const sound_radio_noise: FeatureToggle = {
+ name: 'Enable radio noise',
+ category: 'SOUND',
+ description:
+ 'When enabled, hear sounds of talking and hearing radio chatter.',
+ component: CheckboxInput,
+};