diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm
index 3116f34a2033b..c02a4b1de4849 100644
--- a/_maps/map_files/wawastation/wawastation.dmm
+++ b/_maps/map_files/wawastation/wawastation.dmm
@@ -4483,7 +4483,7 @@
/obj/machinery/computer/security/mining{
dir = 8
},
-/obj/structure/sign/poster/official/random/directional/east,
+/obj/machinery/keycard_auth/directional/east,
/obj/effect/turf_decal/tile/dark_blue/half/contrasted{
dir = 4
},
@@ -6617,6 +6617,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/effect/mapping_helpers/airlock/access/all/science/general,
/turf/open/floor/iron/white,
/area/station/science/research)
"ctL" = (
@@ -8328,15 +8329,16 @@
/turf/open/floor/iron/dark,
/area/station/science/ordnance)
"dbJ" = (
-/obj/effect/mapping_helpers/airlock/access/all/command/general,
/obj/machinery/door/airlock/command/glass{
name = "Bridge"
},
+/obj/effect/mapping_helpers/airlock/access/any/command/general,
/obj/machinery/door/firedoor,
/obj/structure/cable,
/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
cycle_id = "bridgec"
},
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
/turf/open/floor/iron,
/area/station/hallway/secondary/command)
"dbN" = (
@@ -9041,6 +9043,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/effect/mapping_helpers/airlock/access/all/science/general,
/turf/open/floor/iron/white,
/area/station/science/research)
"dmH" = (
@@ -13177,14 +13180,10 @@
/turf/open/floor/iron,
/area/station/hallway/primary/central)
"eHa" = (
-/obj/machinery/computer/security/telescreen/minisat{
- dir = 8;
- pixel_x = 29;
- pixel_y = 1
- },
/obj/effect/turf_decal/tile/dark_blue/half/contrasted{
dir = 4
},
+/obj/structure/sign/poster/official/random/directional/east,
/turf/open/floor/iron,
/area/station/command/bridge)
"eHc" = (
@@ -27768,6 +27767,9 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "bridgehop"
+ },
/turf/open/floor/carpet/green,
/area/station/command/heads_quarters/hop)
"jSu" = (
@@ -31976,6 +31978,9 @@
/obj/effect/turf_decal/siding/wood,
/obj/machinery/door/firedoor,
/obj/effect/mapping_helpers/airlock/access/any/command/hop,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "bridgehop"
+ },
/turf/open/floor/iron,
/area/station/command/heads_quarters/hop)
"loR" = (
@@ -34170,6 +34175,7 @@
/obj/structure/disposalpipe/trunk{
dir = 1
},
+/obj/machinery/digital_clock/directional/south,
/turf/open/floor/iron,
/area/station/cargo/storage)
"mff" = (
@@ -35003,13 +35009,14 @@
"mtG" = (
/obj/machinery/door/airlock/command,
/obj/machinery/door/firedoor,
-/obj/effect/mapping_helpers/airlock/access/all/command/general,
+/obj/effect/mapping_helpers/airlock/access/any/command/general,
/obj/structure/disposalpipe/segment{
dir = 4
},
/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
cycle_id = "bridgec"
},
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
/turf/open/floor/iron/dark/side{
dir = 4
},
@@ -36121,6 +36128,7 @@
dir = 4
},
/obj/machinery/door/firedoor,
+/obj/effect/mapping_helpers/airlock/access/all/science/general,
/turf/open/floor/iron/white,
/area/station/science/research)
"mOo" = (
@@ -38612,6 +38620,8 @@
color = "#52B4E9"
},
/obj/structure/disposalpipe/trunk,
+/obj/machinery/requests_console/auto_name/directional/north,
+/obj/effect/mapping_helpers/requests_console/assistance,
/turf/open/floor/iron/white,
/area/station/medical/storage)
"nKc" = (
@@ -40454,13 +40464,14 @@
/obj/machinery/door/airlock/multi_tile/public{
dir = 4
},
-/obj/effect/mapping_helpers/airlock/access/all/command/general,
+/obj/effect/mapping_helpers/airlock/access/any/command/general,
/obj/machinery/door/firedoor,
/obj/effect/mapping_helpers/airlock/unres{
dir = 8
},
/obj/structure/cable,
/obj/effect/mapping_helpers/airlock/autoname,
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/meeting_room)
"oxU" = (
@@ -42401,6 +42412,7 @@
/obj/effect/turf_decal/siding/thinplating/dark{
dir = 9
},
+/obj/machinery/firealarm/directional/west,
/turf/open/floor/iron/checker,
/area/station/science/research)
"pgW" = (
@@ -45393,12 +45405,13 @@
/area/station/science/ordnance)
"qhg" = (
/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/access/all/command/general,
/obj/machinery/door/airlock/command,
+/obj/effect/mapping_helpers/airlock/access/any/command/general,
/obj/effect/mapping_helpers/airlock/autoname,
/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/emergency_closet)
"qhm" = (
@@ -47050,10 +47063,13 @@
/turf/open/floor/iron,
/area/station/cargo/warehouse)
"qOO" = (
-/obj/structure/sign/poster/official/random/directional/west,
/obj/effect/turf_decal/tile/dark_blue/half/contrasted{
dir = 8
},
+/obj/machinery/computer/security/telescreen/minisat{
+ dir = 4;
+ pixel_x = -29
+ },
/turf/open/floor/iron,
/area/station/command/bridge)
"qOP" = (
@@ -47867,7 +47883,7 @@
/obj/machinery/computer/security{
dir = 4
},
-/obj/machinery/keycard_auth/directional/west,
+/obj/structure/sign/poster/official/random/directional/west,
/obj/effect/turf_decal/tile/dark_blue/half/contrasted{
dir = 8
},
@@ -51337,7 +51353,8 @@
/obj/machinery/door/firedoor/border_only{
dir = 4
},
-/obj/machinery/newscaster/directional/north,
+/obj/machinery/requests_console/auto_name/directional/north,
+/obj/effect/mapping_helpers/requests_console/assistance,
/turf/open/floor/iron,
/area/station/cargo/storage)
"sgW" = (
@@ -55272,7 +55289,8 @@
"tBe" = (
/obj/machinery/computer/pod/old/mass_driver_controller/trash{
pixel_x = -32;
- pixel_y = 6
+ pixel_y = 6;
+ range = 5
},
/obj/structure/cable,
/obj/machinery/button/door/directional/west{
@@ -56484,6 +56502,7 @@
/obj/structure/table/wood,
/obj/item/flashlight/lamp,
/obj/machinery/camera/autoname/directional/north,
+/obj/machinery/keycard_auth/directional/north,
/turf/open/floor/carpet/green,
/area/station/command/heads_quarters/hop)
"tUG" = (
@@ -59086,6 +59105,20 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/large,
/area/station/service/hydroponics/garden)
+"uPg" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 9
+ },
+/obj/machinery/lift_indicator/directional/south{
+ linked_elevator_id = "medbay1";
+ pixel_x = -32
+ },
+/obj/machinery/button/elevator/directional/south{
+ id = "medbay1";
+ pixel_x = -32
+ },
+/turf/open/floor/iron/white,
+/area/station/medical/treatment_center)
"uPi" = (
/obj/effect/turf_decal/tile/brown/half/contrasted,
/obj/effect/decal/cleanable/dirt,
@@ -64860,6 +64893,7 @@
},
/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/mapping_helpers/airlock/access/all/science/general,
/turf/open/floor/iron/white,
/area/station/science/research)
"wWk" = (
@@ -65161,12 +65195,6 @@
/turf/open/floor/iron/white/smooth_large,
/area/station/science/research)
"xaC" = (
-/obj/machinery/button/elevator/directional/south{
- id = "medbay1"
- },
-/obj/machinery/lift_indicator/directional/south{
- linked_elevator_id = "medbay1"
- },
/obj/machinery/portable_atmospherics/canister/anesthetic_mix,
/obj/machinery/atmospherics/components/unary/portables_connector/visible{
dir = 1
@@ -65888,10 +65916,10 @@
/turf/open/floor/engine,
/area/station/science/xenobiology)
"xnc" = (
-/obj/effect/mapping_helpers/airlock/access/all/command/general,
/obj/machinery/door/airlock/command/glass{
name = "Bridge"
},
+/obj/effect/mapping_helpers/airlock/access/any/command/general,
/obj/structure/cable,
/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -65900,6 +65928,7 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
cycle_id = "bridgec"
},
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
/turf/open/floor/iron,
/area/station/hallway/secondary/command)
"xne" = (
@@ -66439,7 +66468,8 @@
},
/obj/structure/cable,
/obj/machinery/door/firedoor,
-/obj/effect/mapping_helpers/airlock/access/all/command/general,
+/obj/effect/mapping_helpers/airlock/access/any/command/general,
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/corporate_dock)
"xxH" = (
@@ -67238,6 +67268,10 @@
name = "Captain's Fax Machine"
},
/obj/structure/table/reinforced,
+/obj/machinery/keycard_auth/directional/south{
+ pixel_y = -24;
+ pixel_x = 8
+ },
/turf/open/floor/carpet/royalblue,
/area/station/command/heads_quarters/captain/private)
"xNh" = (
@@ -82644,7 +82678,7 @@ pwn
eaL
eUB
dgR
-xDp
+uPg
bui
yit
yit
@@ -83899,10 +83933,10 @@ lwW
uyL
esN
fXZ
-fEi
gli
gli
gli
+fEi
gli
gli
hgi
diff --git a/_maps/virtual_domains/fredingtonfastingbear.dmm b/_maps/virtual_domains/fredingtonfastingbear.dmm
index a9118edf73487..4da8210c90e1a 100644
--- a/_maps/virtual_domains/fredingtonfastingbear.dmm
+++ b/_maps/virtual_domains/fredingtonfastingbear.dmm
@@ -535,6 +535,10 @@
},
/turf/open/floor/iron/kitchen,
/area/ruin/space/has_grav/powered/virtual_domain)
+"Ak" = (
+/obj/effect/landmark/bitrunning/cache_spawn,
+/turf/open/floor/iron/kitchen,
+/area/ruin/space/has_grav/powered/virtual_domain)
"AF" = (
/obj/structure/table/wood,
/obj/item/reagent_containers/cup/glass/bottle/goldschlager{
@@ -594,7 +598,7 @@
/turf/open/floor/iron/kitchen,
/area/ruin/space/has_grav/powered/virtual_domain)
"DV" = (
-/obj/machinery/door,
+/obj/machinery/door/airlock,
/turf/open/floor/iron/cafeteria,
/area/virtual_domain/protected_space/fullbright)
"EO" = (
@@ -633,6 +637,7 @@
"Gn" = (
/obj/machinery/light/built/directional/east,
/obj/effect/decal/cleanable/food/tomato_smudge,
+/obj/effect/landmark/bitrunning/cache_spawn,
/turf/open/floor/iron/kitchen/small,
/area/ruin/space/has_grav/powered/virtual_domain)
"GD" = (
@@ -947,7 +952,7 @@
/area/ruin/space/has_grav/powered/virtual_domain)
"VS" = (
/obj/structure/table/reinforced,
-/obj/machinery/computer/camera_advanced,
+/obj/item/modular_computer/laptop/preset/civilian,
/turf/open/floor/iron/cafeteria,
/area/virtual_domain/protected_space/fullbright)
"VW" = (
@@ -2802,7 +2807,7 @@ Cm
Ne
Ne
ve
-Ux
+Ak
Ux
Ux
Ux
diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm
index 9e38eada92313..62ae5a7394a0a 100644
--- a/code/__DEFINES/obj_flags.dm
+++ b/code/__DEFINES/obj_flags.dm
@@ -106,3 +106,8 @@
/// Flags for sharpness in obj/item
#define SHARP_EDGED (1<<0)
#define SHARP_POINTY (1<<1)
+
+/// Flags for specifically what kind of items to get in get_equipped_items
+#define INCLUDE_POCKETS (1<<0)
+#define INCLUDE_ACCESSORIES (1<<1)
+#define INCLUDE_HELD (1<<2)
diff --git a/code/__DEFINES/wires.dm b/code/__DEFINES/wires.dm
index 2b4c528abc212..4926996f26bd3 100644
--- a/code/__DEFINES/wires.dm
+++ b/code/__DEFINES/wires.dm
@@ -64,6 +64,8 @@
#define WIRE_ZAP1 "High Voltage Circuit 1"
#define WIRE_ZAP2 "High Voltage Circuit 2"
#define WIRE_OVERCLOCK "Overclock"
+#define WIRE_EQUIPMENT "Equipment"
+#define WIRE_ENVIRONMENT "Environment"
// Wire states for the AI
#define AI_WIRE_NORMAL 0
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 0aaca9a0907cf..aa953760bce71 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -205,18 +205,30 @@
return
winset(flashed_client, "mainwindow", "flash=5")
-///Recursively checks if an item is inside a given type, even through layers of storage. Returns the atom if it finds it.
+///Recursively checks if an item is inside a given type/atom, even through layers of storage. Returns the atom if it finds it.
/proc/recursive_loc_check(atom/movable/target, type)
- var/atom/atom_to_find = target
- if(istype(atom_to_find, type))
- return atom_to_find
-
- while(!istype(atom_to_find.loc, type))
- if(!atom_to_find.loc)
- return
- atom_to_find = atom_to_find.loc
-
- return atom_to_find.loc
+ var/atom/atom_to_find = null
+
+ if(ispath(type))
+ atom_to_find = target
+ if(istype(atom_to_find, type))
+ return atom_to_find
+
+ while(!istype(atom_to_find.loc, type))
+ if(!atom_to_find.loc)
+ return
+ atom_to_find = atom_to_find.loc
+ else if(isatom(type))
+ atom_to_find = target
+ if(atom_to_find.loc == type)
+ return atom_to_find
+
+ while(atom_to_find.loc != type)
+ if(!atom_to_find.loc)
+ return
+ atom_to_find = atom_to_find.loc
+
+ return atom_to_find
///Send a message in common radio when a player arrives
/proc/announce_arrival(mob/living/carbon/human/character, rank)
diff --git a/code/_onclick/click_alt.dm b/code/_onclick/click_alt.dm
index 957f55ab21793..51c58408e2557 100644
--- a/code/_onclick/click_alt.dm
+++ b/code/_onclick/click_alt.dm
@@ -24,14 +24,7 @@
client.loot_panel.open(tile)
return
- var/can_use_click_action = FALSE
- if(isturf(target))
- // Turfs are special because they can't be used with can_perform_action
- can_use_click_action = can_perform_turf_action(target)
- else
- can_use_click_action = can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY))
-
- if(can_use_click_action)
+ if(can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY)))
// If it has a signal handler that returns a click action, done.
if(SEND_SIGNAL(target, COMSIG_CLICK_ALT, src) & CLICK_ACTION_ANY)
return
@@ -97,18 +90,13 @@
if(SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON_SECONDARY, target) & COMSIG_MOB_CANCEL_CLICKON)
return
- var/can_use_click_action = FALSE
- if(isturf(target))
- // Turfs are special because they can't be used with can_perform_action
- can_use_click_action = can_perform_turf_action(target)
- else
- can_use_click_action = can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY)
- if(!can_use_click_action)
+ if(!can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY))
return
//Hook on the atom to intercept the click
if(SEND_SIGNAL(target, COMSIG_CLICK_ALT_SECONDARY, src) & COMPONENT_CANCEL_CLICK_ALT_SECONDARY)
return
+
if(isobserver(src) && client && check_rights_for(client, R_DEBUG))
client.toggle_tag_datum(src)
return
@@ -124,14 +112,3 @@
/atom/proc/click_alt_secondary(mob/user)
SHOULD_CALL_PARENT(FALSE)
return NONE
-
-/// Helper proc to validate turfs. Used because can_perform_action does not support turfs.
-/mob/proc/can_perform_turf_action(turf/target)
- if(!CanReach(target)) // No error message for parity with SILENT_ADJACENCY
- return FALSE
-
- if(incapacitated())
- to_chat(src, span_warning("You can't use this!"))
- return FALSE
-
- return TRUE
diff --git a/code/_onclick/click_ctrl.dm b/code/_onclick/click_ctrl.dm
index bb0491b2bb923..2e80f01781603 100644
--- a/code/_onclick/click_ctrl.dm
+++ b/code/_onclick/click_ctrl.dm
@@ -20,13 +20,8 @@
if(SEND_SIGNAL(target, COMSIG_CLICK_CTRL, src) & CLICK_ACTION_ANY)
return TRUE
- var/can_use_click_action = FALSE
- if(isturf(target))
- // Turfs are special because they can't be used with can_perform_action
- can_use_click_action = can_perform_turf_action(target)
- else
- can_use_click_action = can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY)
- if(!can_use_click_action)
+ // This means the action has been processed even though nothing happened
+ if(!can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY))
return TRUE
// If it has a custom click_alt that returns success/block, done.
@@ -99,17 +94,9 @@
if(SEND_SIGNAL(target, COMSIG_CLICK_CTRL_SHIFT, src) & CLICK_ACTION_ANY)
return
- var/can_use_click_action = FALSE
- if(isturf(target))
- // Turfs are special because they can't be used with can_perform_action
- can_use_click_action = can_perform_turf_action(target)
- else
- can_use_click_action = can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY)
- if(!can_use_click_action)
- return
-
// Proceed with ctrl shift click
- target.click_ctrl_shift(src)
+ if(can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY))
+ target.click_ctrl_shift(src)
/**
* ## Custom ctrl shift click interaction
diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm
index b2665e1f98ed0..b3d2de3683b67 100644
--- a/code/_onclick/hud/action_button.dm
+++ b/code/_onclick/hud/action_button.dm
@@ -94,7 +94,7 @@
old_object.MouseExited(over_location, over_control, params)
last_hovored_ref = WEAKREF(over_object)
- over_object.MouseEntered(over_location, over_control, params)
+ over_object?.MouseEntered(over_location, over_control, params)
/atom/movable/screen/movable/action_button/MouseEntered(location, control, params)
. = ..()
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index e672a86d72083..966987828bd54 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -62,7 +62,7 @@
if(HAS_TRAIT_FROM(affected_mob, TRAIT_NO_TRANSFORM, REF(src)))
return
ADD_TRAIT(affected_mob, TRAIT_NO_TRANSFORM, REF(src))
- for(var/obj/item/W in affected_mob.get_equipped_items(include_pockets = TRUE))
+ for(var/obj/item/W in affected_mob.get_equipped_items(INCLUDE_POCKETS))
affected_mob.dropItemToGround(W)
for(var/obj/item/I in affected_mob.held_items)
affected_mob.dropItemToGround(I)
diff --git a/code/datums/elements/climbable.dm b/code/datums/elements/climbable.dm
index 004f05dd5f584..533facf709a92 100644
--- a/code/datums/elements/climbable.dm
+++ b/code/datums/elements/climbable.dm
@@ -82,6 +82,10 @@
log_combat(user, climbed_thing, "climbed onto")
if(adjusted_climb_stun)
user.Stun(adjusted_climb_stun)
+ var/atom/movable/buckle_target = climbed_thing
+ if(istype(buckle_target))
+ if(buckle_target.is_buckle_possible(user))
+ buckle_target.buckle_mob(user)
else
to_chat(user, span_warning("You fail to climb onto [climbed_thing]."))
LAZYREMOVEASSOC(current_climbers, climbed_thing, user)
@@ -112,7 +116,6 @@
/datum/element/climbable/proc/mousedrop_receive(atom/climbed_thing, atom/movable/dropped_atom, mob/user, params)
SIGNAL_HANDLER
- . = COMPONENT_CANCEL_MOUSEDROPPED_ONTO
if(user != dropped_atom || !isliving(dropped_atom))
return
if(!HAS_TRAIT(dropped_atom, TRAIT_FENCE_CLIMBER) && !HAS_TRAIT(dropped_atom, TRAIT_CAN_HOLD_ITEMS)) // If you can hold items you can probably climb a fence
@@ -120,3 +123,4 @@
var/mob/living/living_target = dropped_atom
if(living_target.mobility_flags & MOBILITY_MOVE)
INVOKE_ASYNC(src, PROC_REF(climb_structure), climbed_thing, living_target, params)
+ return COMPONENT_CANCEL_MOUSEDROPPED_ONTO
diff --git a/code/datums/elements/skill_reward.dm b/code/datums/elements/skill_reward.dm
index 7809eea85f715..891f933793ea0 100644
--- a/code/datums/elements/skill_reward.dm
+++ b/code/datums/elements/skill_reward.dm
@@ -29,7 +29,7 @@
///We check if the item can be equipped, otherwise we drop it.
/datum/element/skill_reward/proc/drop_if_unworthy(datum/source, mob/living/user)
SIGNAL_HANDLER
- if(check_equippable(user) || !(source in user.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)))
+ if(check_equippable(user) || !(source in user.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES)))
return NONE
to_chat(user, span_warning("You feel completely and utterly unworthy to even touch \the [source]."))
user.dropItemToGround(source, TRUE)
diff --git a/code/datums/mocking/client.dm b/code/datums/mocking/client.dm
index dc1db213f34be..4b724ef705e82 100644
--- a/code/datums/mocking/client.dm
+++ b/code/datums/mocking/client.dm
@@ -48,3 +48,6 @@
/datum/client_interface/proc/set_macros()
return
+
+/datum/client_interface/proc/update_ambience_pref()
+ return
diff --git a/code/datums/status_effects/buffs/stop_drop_roll.dm b/code/datums/status_effects/buffs/stop_drop_roll.dm
index 43d37654e6177..17b4d6d768de3 100644
--- a/code/datums/status_effects/buffs/stop_drop_roll.dm
+++ b/code/datums/status_effects/buffs/stop_drop_roll.dm
@@ -24,6 +24,9 @@
// Start with one weaker roll
owner.spin(spintime = actual_interval, speed = actual_interval / 4)
owner.adjust_fire_stacks(-0.25)
+
+ for (var/obj/item/dropped in owner.loc)
+ dropped.extinguish() // Effectively extinguish your items by rolling on them
return TRUE
/datum/status_effect/stop_drop_roll/on_remove()
diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm
index 62f8c9ca24e32..dd625ab919aca 100644
--- a/code/datums/status_effects/debuffs/fire_stacks.dm
+++ b/code/datums/status_effects/debuffs/fire_stacks.dm
@@ -247,7 +247,7 @@
owner.clear_mood_event("on_fire")
SEND_SIGNAL(owner, COMSIG_LIVING_EXTINGUISHED, owner)
cache_stacks()
- for(var/obj/item/equipped in owner.get_equipped_items())
+ for(var/obj/item/equipped in (owner.get_equipped_items(INCLUDE_HELD)))
equipped.extinguish()
/datum/status_effect/fire_handler/fire_stacks/on_remove()
diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm
index 9bcc0f03b7a0e..2a5bd2a98fd7a 100644
--- a/code/datums/storage/storage.dm
+++ b/code/datums/storage/storage.dm
@@ -735,12 +735,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches)
return COMPONENT_CANCEL_MOUSEDROP_ONTO
else if(!istype(over_object, /atom/movable/screen))
- var/action_status
- if(isturf(over_object))
- action_status = user.can_perform_turf_action(over_object)
- else
- action_status = user.can_perform_action(over_object, FORBID_TELEKINESIS_REACH)
- if(!action_status)
+ if(!user.can_perform_action(over_object, FORBID_TELEKINESIS_REACH))
return
parent.add_fingerprint(user)
@@ -791,7 +786,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches)
/datum/storage/proc/on_mousedropped_onto(datum/source, obj/item/dropping, mob/user)
SIGNAL_HANDLER
- . = COMPONENT_CANCEL_MOUSEDROPPED_ONTO
if(!istype(dropping))
return
if(dropping != user.get_active_held_item())
@@ -804,6 +798,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches)
return
attempt_insert(dropping, user)
+ return COMPONENT_CANCEL_MOUSEDROPPED_ONTO
/// Signal handler for whenever we're attacked by an object.
/datum/storage/proc/on_item_interact(datum/source, mob/user, obj/item/thing, params)
diff --git a/code/datums/wires/apc.dm b/code/datums/wires/apc.dm
index 54d179802a311..50847df994372 100644
--- a/code/datums/wires/apc.dm
+++ b/code/datums/wires/apc.dm
@@ -4,8 +4,13 @@
/datum/wires/apc/New(atom/holder)
wires = list(
- WIRE_POWER1, WIRE_POWER2,
- WIRE_IDSCAN, WIRE_AI
+ WIRE_EQUIPMENT,
+ WIRE_LIGHT,
+ WIRE_ENVIRONMENT,
+ WIRE_POWER1,
+ WIRE_POWER2,
+ WIRE_INTERFACE,
+ WIRE_AI
)
add_duds(6)
..()
@@ -22,17 +27,32 @@
var/list/status = list()
status += "The interface light is [A.locked ? "red" : "green"]."
status += "The short indicator is [A.shorted ? "lit" : "off"]."
+ status += "The channel one light is [A.equipment ? "on" : "off"]."
+ status += "The channel two light is [A.lighting ? "on" : "off"]."
+ status += "The channel three light is [A.environ ? "on" : "off"]."
status += "The AI connection light is [!A.aidisabled ? "on" : "off"]."
return status
-/datum/wires/apc/on_pulse(wire)
+/datum/wires/apc/on_pulse(wire, user)
var/obj/machinery/power/apc/A = holder
switch(wire)
+ if(WIRE_EQUIPMENT)
+ A.equipment = A.equipment > APC_CHANNEL_OFF ? APC_CHANNEL_OFF : APC_CHANNEL_AUTO_ON
+ A.update_appearance()
+ A.update()
+ if(WIRE_LIGHT)
+ A.lighting = A.lighting > APC_CHANNEL_OFF ? APC_CHANNEL_OFF : APC_CHANNEL_AUTO_ON
+ A.update_appearance()
+ A.update()
+ if(WIRE_ENVIRONMENT)
+ A.environ = A.environ > APC_CHANNEL_OFF ? APC_CHANNEL_OFF : APC_CHANNEL_AUTO_ON
+ A.update_appearance()
+ A.update()
if(WIRE_POWER1, WIRE_POWER2) // Short for a long while.
if(!A.shorted)
A.shorted = TRUE
addtimer(CALLBACK(A, TYPE_PROC_REF(/obj/machinery/power/apc, reset), wire), 2 MINUTES)
- if(WIRE_IDSCAN) // Unlock for a little while.
+ if(WIRE_INTERFACE) // Unlock for a little while.
A.locked = FALSE
addtimer(CALLBACK(A, TYPE_PROC_REF(/obj/machinery/power/apc, reset), wire), 30 SECONDS)
if(WIRE_AI) // Disable AI control for a very short time.
@@ -43,12 +63,26 @@
/datum/wires/apc/on_cut(wire, mend, source)
var/obj/machinery/power/apc/A = holder
switch(wire)
+ if(WIRE_EQUIPMENT)
+ A.equipment = mend ? APC_CHANNEL_AUTO_ON : APC_CHANNEL_OFF
+ A.update_appearance()
+ A.update()
+ if(WIRE_LIGHT)
+ A.lighting = mend ? APC_CHANNEL_AUTO_ON : APC_CHANNEL_OFF
+ A.update_appearance()
+ A.update()
+ if(WIRE_ENVIRONMENT)
+ A.environ = mend ? APC_CHANNEL_AUTO_ON : APC_CHANNEL_OFF
+ A.update_appearance()
+ A.update()
if(WIRE_POWER1, WIRE_POWER2) // Short out.
if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2))
A.shorted = FALSE
else
A.shorted = TRUE
A.shock(usr, 50)
+ if(WIRE_INTERFACE)
+ A.locked = !mend
if(WIRE_AI) // Disable AI control.
A.aidisabled = !mend
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index a7aabee6f4d2a..255f34eff51dd 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -101,7 +101,7 @@
. = INITIALIZE_HINT_QDEL
CRASH("Somebody fucked up.")
if(_lifespan > 0)
- addtimer(src, PROC_REF(expire), _lifespan, TIMER_DELETE_ME)
+ addtimer(CALLBACK(src, PROC_REF(expire)), _lifespan, TIMER_DELETE_ME)
link_portal(_linked)
hardlinked = automatic_link
if(isturf(hard_target_override))
diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm
index 6ca951d262a67..be5d0b8ec2b1c 100644
--- a/code/game/objects/items/cigs_lighters.dm
+++ b/code/game/objects/items/cigs_lighters.dm
@@ -55,6 +55,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM
desc = "A [initial(name)]. This one is lit."
attack_verb_continuous = string_list(list("burns", "singes"))
attack_verb_simple = string_list(list("burn", "singe"))
+ if(isliving(loc))
+ var/mob/living/male_model = loc
+ if(male_model.fire_stacks && !(male_model.on_fire))
+ male_model.ignite_mob()
START_PROCESSING(SSobj, src)
update_appearance()
@@ -876,6 +880,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM
attack_verb_continuous = string_list(list("burns", "singes"))
attack_verb_simple = string_list(list("burn", "singe"))
START_PROCESSING(SSobj, src)
+ if(isliving(loc))
+ var/mob/living/male_model = loc
+ if(male_model.fire_stacks && !(male_model.on_fire))
+ male_model.ignite_mob()
else
hitsound = SFX_SWING_HIT
force = 0
diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm
index 72c84c9ee995e..fe15dab29588e 100644
--- a/code/game/objects/items/tanks/tanks.dm
+++ b/code/game/objects/items/tanks/tanks.dm
@@ -445,7 +445,7 @@
balloon_alert(user, "can't reach!")
return
- if((src in user.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)) && !user.canUnEquip(src))
+ if((src in user.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES)) && !user.canUnEquip(src))
balloon_alert(user, "it's stuck!")
return
diff --git a/code/modules/admin/verbs/ert.dm b/code/modules/admin/verbs/ert.dm
index c86d08151ee62..2d1ba075a4795 100644
--- a/code/modules/admin/verbs/ert.dm
+++ b/code/modules/admin/verbs/ert.dm
@@ -25,7 +25,7 @@
/datum/admins/proc/equipAntagOnDummy(mob/living/carbon/human/dummy/mannequin, datum/antagonist/antag)
- for(var/I in mannequin.get_equipped_items(include_pockets = TRUE))
+ for(var/I in mannequin.get_equipped_items(INCLUDE_POCKETS))
qdel(I)
if (ispath(antag, /datum/antagonist/ert))
var/datum/antagonist/ert/ert = antag
diff --git a/code/modules/admin/verbs/selectequipment.dm b/code/modules/admin/verbs/selectequipment.dm
index b94fd5cb2e455..415130fa1b727 100644
--- a/code/modules/admin/verbs/selectequipment.dm
+++ b/code/modules/admin/verbs/selectequipment.dm
@@ -209,7 +209,8 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(select_equipment, R_FUN, "Select Equipment", mob/ta
delete_pocket = TRUE
BLACKBOX_LOG_ADMIN_VERB("Select Equipment")
- for(var/obj/item/item in human_target.get_equipped_items(include_pockets = delete_pocket))
+ var/includes_flags = delete_pocket ? INCLUDE_POCKETS : NONE
+ for(var/obj/item/item in human_target.get_equipped_items(includes_flags))
qdel(item)
var/obj/item/organ/internal/brain/human_brain = human_target.get_organ_slot(BRAIN)
diff --git a/code/modules/antagonists/obsessed/obsessed.dm b/code/modules/antagonists/obsessed/obsessed.dm
index 3d0a0063bf709..db934c90df604 100644
--- a/code/modules/antagonists/obsessed/obsessed.dm
+++ b/code/modules/antagonists/obsessed/obsessed.dm
@@ -66,7 +66,7 @@
shoes = /obj/item/clothing/shoes/sneakers/black
/datum/outfit/obsessed/post_equip(mob/living/carbon/human/H)
- for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))
+ for(var/obj/item/carried_item in H.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES))
carried_item.add_mob_blood(H)//Oh yes, there will be blood...
H.regenerate_icons()
diff --git a/code/modules/bitrunning/server/util.dm b/code/modules/bitrunning/server/util.dm
index ac3e60b51ba64..6b5352bde6cb1 100644
--- a/code/modules/bitrunning/server/util.dm
+++ b/code/modules/bitrunning/server/util.dm
@@ -66,7 +66,7 @@
/// Removes all blacklisted items from a mob and returns them to base state
/obj/machinery/quantum_server/proc/reset_equipment(mob/living/carbon/human/person)
- for(var/obj/item in person.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))
+ for(var/obj/item in person.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES))
qdel(item)
var/datum/antagonist/bitrunning_glitch/antag_datum = locate() in person.mind?.antag_datums
diff --git a/code/modules/buildmode/submodes/outfit.dm b/code/modules/buildmode/submodes/outfit.dm
index 5f8e3319cb95d..c3d507bf1e6c7 100644
--- a/code/modules/buildmode/submodes/outfit.dm
+++ b/code/modules/buildmode/submodes/outfit.dm
@@ -32,11 +32,11 @@
to_chat(c, span_warning("Pick an outfit first."))
return
- for (var/item in dollie.get_equipped_items(include_pockets = TRUE))
+ for (var/item in dollie.get_equipped_items(INCLUDE_POCKETS))
qdel(item)
if(dressuptime != "Naked")
dollie.equipOutfit(dressuptime)
if(LAZYACCESS(modifiers, RIGHT_CLICK))
- for (var/item in dollie.get_equipped_items(include_pockets = TRUE))
+ for (var/item in dollie.get_equipped_items(INCLUDE_POCKETS))
qdel(item)
diff --git a/code/modules/client/preferences/sounds.dm b/code/modules/client/preferences/sounds.dm
index f56430b53638a..3ace1b64326cc 100644
--- a/code/modules/client/preferences/sounds.dm
+++ b/code/modules/client/preferences/sounds.dm
@@ -4,6 +4,9 @@
savefile_key = "sound_ambience"
savefile_identifier = PREFERENCE_PLAYER
+/datum/preference/toggle/sound_ambience/apply_to_client(client/client, value)
+ client.update_ambience_pref()
+
/// Controls hearing announcement sounds
/datum/preference/toggle/sound_announcements
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm
index a22691495ccc1..6c088760f07db 100644
--- a/code/modules/clothing/outfits/standard.dm
+++ b/code/modules/clothing/outfits/standard.dm
@@ -185,7 +185,7 @@
l_hand = /obj/item/fireaxe
/datum/outfit/psycho/post_equip(mob/living/carbon/human/H)
- for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))
+ for(var/obj/item/carried_item in H.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES))
carried_item.add_mob_blood(H)//Oh yes, there will be blood...
for(var/obj/item/I in H.held_items)
I.add_mob_blood(H)
diff --git a/code/modules/mafia/outfits.dm b/code/modules/mafia/outfits.dm
index dc2d384b263f6..5c6450adb90d2 100644
--- a/code/modules/mafia/outfits.dm
+++ b/code/modules/mafia/outfits.dm
@@ -155,7 +155,7 @@
suit = /obj/item/clothing/suit/apron
/datum/outfit/mafia/obsessed/post_equip(mob/living/carbon/human/H)
- for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))
+ for(var/obj/item/carried_item in H.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES))
carried_item.add_mob_blood(H)//Oh yes, there will be blood...
H.regenerate_icons()
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index b118de06f057a..50ab6e82faa4d 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -388,38 +388,37 @@
* Used to return a list of equipped items on a mob; does not include held items (use get_all_gear)
*
* Argument(s):
- * * Optional - include_pockets (TRUE/FALSE), whether or not to include the pockets and suit storage in the returned list
- * * Optional - include_accessories (TRUE/FALSE), whether or not to include the accessories in the returned list
+ * * Optional - include_flags, (see obj.flags.dm) describes which optional things to include or not (pockets, accessories, held items)
*/
-/mob/living/proc/get_equipped_items(include_pockets = FALSE, include_accessories = FALSE)
+/mob/living/proc/get_equipped_items(include_flags = NONE)
var/list/items = list()
for(var/obj/item/item_contents in contents)
if(item_contents.item_flags & IN_INVENTORY)
items += item_contents
- items -= held_items
+ if (!(include_flags & INCLUDE_HELD))
+ items -= held_items
return items
/**
- * Used to return a list of equipped items on a human mob; does not include held items (use get_all_gear)
+ * Used to return a list of equipped items on a human mob; does not by default include held items, see include_flags
*
* Argument(s):
- * * Optional - include_pockets (TRUE/FALSE), whether or not to include the pockets and suit storage in the returned list
- * * Optional - include_accessories (TRUE/FALSE), whether or not to include the accessories in the returned list
+ * * Optional - include_flags, (see obj.flags.dm) describes which optional things to include or not (pockets, accessories, held items)
*/
-/mob/living/carbon/human/get_equipped_items(include_pockets = FALSE, include_accessories = FALSE)
+/mob/living/carbon/human/get_equipped_items(include_flags = NONE)
var/list/items = ..()
- if(!include_pockets)
+ if(!(include_flags & INCLUDE_POCKETS))
items -= list(l_store, r_store, s_store)
- if(include_accessories && w_uniform)
+ if((include_flags & INCLUDE_ACCESSORIES) && w_uniform)
var/obj/item/clothing/under/worn_under = w_uniform
items += worn_under.attached_accessories
return items
/mob/living/proc/unequip_everything()
var/list/items = list()
- items |= get_equipped_items(include_pockets = TRUE)
+ items |= get_equipped_items(INCLUDE_POCKETS)
for(var/I in items)
dropItemToGround(I)
drop_all_held_items()
@@ -558,7 +557,7 @@
//GetAllContents that is reasonable and not stupid
/mob/living/proc/get_all_gear()
- var/list/processing_list = get_equipped_items(include_pockets = TRUE, include_accessories = TRUE) + held_items
+ var/list/processing_list = get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES | INCLUDE_HELD)
list_clear_nulls(processing_list) // handles empty hands
var/i = 0
while(i < length(processing_list))
diff --git a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm
index d2b5edc58cced..4ba903d99285f 100644
--- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm
+++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm
@@ -281,7 +281,7 @@
/mob/living/basic/revenant/gib()
death()
-/mob/living/basic/revenant/can_perform_action(atom/movable/target, action_bitflags)
+/mob/living/basic/revenant/can_perform_action(atom/target, action_bitflags)
return FALSE
/mob/living/basic/revenant/ex_act(severity, target)
diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm
index d5d048a33f844..1e514ad13cedb 100644
--- a/code/modules/mob/living/carbon/human/_species.dm
+++ b/code/modules/mob/living/carbon/human/_species.dm
@@ -403,7 +403,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
replacement.Insert(organ_holder, special=TRUE, movement_flags = DELETE_IF_REPLACED)
/datum/species/proc/worn_items_fit_body_check(mob/living/carbon/wearer)
- for(var/obj/item/equipped_item in wearer.get_equipped_items(include_pockets = TRUE))
+ for(var/obj/item/equipped_item in wearer.get_equipped_items(INCLUDE_POCKETS))
var/equipped_item_slot = wearer.get_slot_by_item(equipped_item)
if(!equipped_item.mob_can_equip(wearer, equipped_item_slot, bypass_equip_delay_self = TRUE, ignore_equipped = TRUE))
wearer.dropItemToGround(equipped_item, force = TRUE)
diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm
index 8d62ed5907948..3340e34064052 100644
--- a/code/modules/mob/living/carbon/human/dummy.dm
+++ b/code/modules/mob/living/carbon/human/dummy.dm
@@ -41,7 +41,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
//Instead of just deleting our equipment, we save what we can and reinsert it into SSwardrobe's store
//Hopefully this makes preference reloading not the worst thing ever
/mob/living/carbon/human/dummy/delete_equipment()
- var/list/items_to_check = get_equipped_items(include_pockets = TRUE) + held_items
+ var/list/items_to_check = get_equipped_items(INCLUDE_POCKETS | INCLUDE_HELD)
var/list/to_nuke = list() //List of items queued for deletion, can't qdel them before iterating their contents in case they hold something
///Travel to the bottom of the contents chain, expanding it out
for(var/i = 1; i <= length(items_to_check); i++) //Needs to be a c style loop since it can expand
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 6e1f9037018b6..aa2daa1675e91 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -93,7 +93,7 @@
return TRUE
var/block_chance_modifier = round(damage / -3)
- for(var/obj/item/worn_thing in get_equipped_items(include_pockets = FALSE) + held_items)
+ for(var/obj/item/worn_thing in get_equipped_items(INCLUDE_HELD))
// Things that are supposed to be worn, being held = cannot block
if(isclothing(worn_thing))
if(worn_thing in held_items)
@@ -796,6 +796,10 @@
if(leg_clothes)
burning_items |= leg_clothes
+ if (!gloves || (!(gloves.resistance_flags & FIRE_PROOF) && (gloves.resistance_flags & FLAMMABLE)))
+ for(var/obj/item/burnable_item in held_items)
+ burning_items |= burnable_item
+
for(var/obj/item/burning in burning_items)
burning.fire_act((stacks * 25 * seconds_per_tick)) //damage taken is reduced to 2% of this value by fire_act()
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 32ab7ca1b900a..19e4b7a43deb6 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -347,7 +347,7 @@
//delete all equipment without dropping anything
/mob/living/carbon/human/proc/delete_equipment()
- for(var/slot in get_equipped_items(include_pockets = TRUE))//order matters, dependant slots go first
+ for(var/slot in get_equipped_items(INCLUDE_POCKETS))//order matters, dependant slots go first
qdel(slot)
for(var/obj/item/held_item in held_items)
qdel(held_item)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 117dc5583eae5..68175333519a1 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -176,7 +176,7 @@
stat_allowed = HARD_CRIT
/datum/emote/living/gasp/get_sound(mob/living/user)
- if(!HAS_MIND_TRAIT(user, TRAIT_MIMING))
+ if(HAS_MIND_TRAIT(user, TRAIT_MIMING))
return
if(!ishuman(user))
return
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index b5e538461f2da..df15d979836b6 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1310,10 +1310,14 @@
/mob/living/can_hold_items(obj/item/I)
return ..() && HAS_TRAIT(src, TRAIT_CAN_HOLD_ITEMS) && usable_hands
-/mob/living/can_perform_action(atom/movable/target, action_bitflags)
+/mob/living/can_perform_action(atom/target, action_bitflags)
if(!istype(target))
CRASH("Missing target arg for can_perform_action")
+ if(stat != CONSCIOUS)
+ to_chat(src, span_warning("You are not conscious enough for this action!"))
+ return FALSE
+
if(!(interaction_flags_atom & INTERACT_ATOM_IGNORE_INCAPACITATED))
var/ignore_flags = NONE
if(interaction_flags_atom & INTERACT_ATOM_IGNORE_RESTRAINED)
@@ -1325,10 +1329,6 @@
to_chat(src, span_warning("You are incapacitated at the moment!"))
return FALSE
- if(stat == DEAD || stat != CONSCIOUS)
- to_chat(src, span_warning("You are in no physical condition to do this!"))
- return FALSE
-
// If the MOBILITY_UI bitflag is not set it indicates the mob's hands are cutoff, blocked, or handcuffed
// Note - AI's and borgs have the MOBILITY_UI bitflag set even though they don't have hands
// Also if it is not set, the mob could be incapcitated, knocked out, unconscious, asleep, EMP'd, etc.
@@ -1345,7 +1345,7 @@
to_chat(src, span_warning("You don't have the physical ability to do this!"))
return FALSE
- if(!(action_bitflags & BYPASS_ADJACENCY) && !Adjacent(target) && (target.loc != src) && !recursive_loc_check(src, target))
+ if(!(action_bitflags & BYPASS_ADJACENCY) && !recursive_loc_check(src, target) && !CanReach(target))
if(HAS_SILICON_ACCESS(src) && !ispAI(src))
if(!(action_bitflags & ALLOW_SILICON_REACH)) // silicons can ignore range checks (except pAIs)
if(!(action_bitflags & SILENT_ADJACENCY))
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 8354ff0447461..6c4be898162dd 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -875,7 +875,7 @@
to_chat(src, "You have been downloaded to a mobile storage device. Remote device connection severed.")
to_chat(user, "[span_boldnotice("Transfer successful")]: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
-/mob/living/silicon/ai/can_perform_action(atom/movable/target, action_bitflags)
+/mob/living/silicon/ai/can_perform_action(atom/target, action_bitflags)
if(control_disabled)
to_chat(src, span_warning("You can't do that right now!"))
return FALSE
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 6fefbb05f7c0d..0c26e7c57e278 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -553,7 +553,7 @@
if(AI_NOTIFICATION_CYBORG_DISCONNECTED) //Tampering with the wires
to_chat(connected_ai, "
[span_notice("NOTICE - Remote telemetry lost with [name].")]
")
-/mob/living/silicon/robot/can_perform_action(atom/movable/target, action_bitflags)
+/mob/living/silicon/robot/can_perform_action(atom/target, action_bitflags)
if(lockcharge || low_power_mode)
to_chat(src, span_warning("You can't do that right now!"))
return FALSE
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index 3d7be3ea47e29..e25a6f9b16e27 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -31,7 +31,7 @@
to_chat(src, span_warning("You can't vent crawl while buckled!"))
return
if(iscarbon(src) && required_nudity)
- if(length(get_equipped_items(include_pockets = TRUE)) || get_num_held_items())
+ if(length(get_equipped_items(INCLUDE_POCKETS)) || get_num_held_items())
if(provide_feedback)
to_chat(src, span_warning("You can't crawl around in the ventilation ducts with items!"))
return
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index ca393cf25666f..80f1b2dfb484d 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1164,7 +1164,7 @@
* silence_adjacency: Sometimes we want to use this proc to check interaction without allowing it to throw errors for base case adjacency
* Alt click uses this, as otherwise you can detect what is interactable from a distance via the error message
**/
-/mob/proc/can_perform_action(atom/movable/target, action_bitflags)
+/mob/proc/can_perform_action(atom/target, action_bitflags)
return
///Can this mob use storage
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index b4fbd713065aa..123fb0de82cd7 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -312,7 +312,7 @@
SSblackbox.record_feedback("amount", "gorillas_created", 1)
- var/Itemlist = get_equipped_items(include_pockets = TRUE)
+ var/Itemlist = get_equipped_items(INCLUDE_POCKETS)
Itemlist += held_items
for(var/obj/item/W in Itemlist)
dropItemToGround(W, TRUE)
diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm
index 0ea51f19d37e2..11334f12abc79 100644
--- a/code/modules/pai/pai.dm
+++ b/code/modules/pai/pai.dm
@@ -149,7 +149,7 @@
return ..()
// See software.dm for Topic()
-/mob/living/silicon/pai/can_perform_action(atom/movable/target, action_bitflags)
+/mob/living/silicon/pai/can_perform_action(atom/target, action_bitflags)
action_bitflags |= ALLOW_RESTING // Resting is just an aesthetic feature for them
action_bitflags &= ~ALLOW_SILICON_REACH // They don't get long reach like the rest of silicons
return ..(target, action_bitflags)
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index dc2b4e9812a03..b55593ec913e7 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -311,19 +311,29 @@
/obj/item/stock_parts/cell/crap
name = "\improper Nanotrasen brand rechargeable AA battery"
desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT
+ icon_state = "aa_cell"
maxcharge = STANDARD_CELL_CHARGE * 0.5
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.4)
+/obj/item/stock_parts/cell/crap/Initialize(mapload)
+ AddElement(/datum/element/update_icon_blocker)
+ return ..()
+
/obj/item/stock_parts/cell/crap/empty
empty = TRUE
/obj/item/stock_parts/cell/upgraded
name = "upgraded power cell"
desc = "A power cell with a slightly higher capacity than normal!"
+ icon_state = "9v_cell"
maxcharge = STANDARD_CELL_CHARGE * 2.5
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.5)
chargerate = STANDARD_CELL_RATE * 0.5
+/obj/item/stock_parts/cell/upgraded/Initialize(mapload)
+ AddElement(/datum/element/update_icon_blocker)
+ return ..()
+
/obj/item/stock_parts/cell/upgraded/plus
name = "upgraded power cell+"
desc = "A power cell with an even higher capacity than the base model!"
diff --git a/code/modules/reagents/chemistry/items.dm b/code/modules/reagents/chemistry/items.dm
index d307f96dc264c..ad7f0413ce561 100644
--- a/code/modules/reagents/chemistry/items.dm
+++ b/code/modules/reagents/chemistry/items.dm
@@ -120,7 +120,7 @@
return NONE
var/list/out_message = list()
to_chat(user, "The chemistry meter beeps and displays:")
- out_message += "Total volume: [round(cont.volume, 0.01)] Current temperature: [round(cont.reagents.chem_temp, 0.1)]K Total pH: [round(cont.reagents.ph, 0.01)]\n"
+ out_message += "Total volume: [round(cont.volume, 0.01)] Current temperature: [round(cont.reagents.chem_temp, 0.1)]K Total pH: [round(cont.reagents.ph, 0.01)]\n"
out_message += "Chemicals found in [interacting_with.name]:\n"
if(cont.reagents.is_reacting)
out_message += "[span_warning("A reaction appears to be occuring currently.")]\n"
@@ -132,7 +132,7 @@
out_message += "[round(reagent.volume, 0.01)]u of [reagent.name], Purity: [round(reagent.purity, 0.000001)*100]%, [(scanmode?"[(reagent.overdose_threshold?"Overdose: [reagent.overdose_threshold]u, ":"")]Base pH: [initial(reagent.ph)], Current pH: [reagent.ph].":"Current pH: [reagent.ph].")]\n"
if(scanmode)
out_message += "Analysis: [reagent.description]\n"
- to_chat(user, "[out_message.Join()]")
+ to_chat(user, examine_block(span_notice("[out_message.Join()]")))
desc = "An electrode attached to a small circuit box that will display details of a solution. Can be toggled to provide a description of each of the reagents. The screen currently displays detected vol: [round(cont.volume, 0.01)] detected pH:[round(cont.reagents.ph, 0.1)]."
return ITEM_INTERACT_SUCCESS
diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm
index 85704c0c5b72e..700f99a643504 100644
--- a/code/modules/research/designs/power_designs.dm
+++ b/code/modules/research/designs/power_designs.dm
@@ -24,7 +24,7 @@
construction_time = 10 SECONDS
build_path = /obj/item/stock_parts/cell/high/empty
category = list(
- RND_CATEGORY_STOCK_PARTS + RND_SUBCATEGORY_STOCK_PARTS_2
+ RND_CATEGORY_STOCK_PARTS + RND_SUBCATEGORY_STOCK_PARTS_1
)
departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING
@@ -37,7 +37,7 @@
construction_time = 10 SECONDS
build_path = /obj/item/stock_parts/cell/super/empty
category = list(
- RND_CATEGORY_STOCK_PARTS + RND_SUBCATEGORY_STOCK_PARTS_3
+ RND_CATEGORY_STOCK_PARTS + RND_SUBCATEGORY_STOCK_PARTS_2
)
departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING
diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm
index 04c777bb1c073..d110dab03e02d 100644
--- a/code/modules/research/machinery/_production.dm
+++ b/code/modules/research/machinery/_production.dm
@@ -411,14 +411,25 @@
var/atom/movable/created
if(is_stack)
- created = new design.build_path(target, items_remaining)
+ var/obj/item/stack/stack_item = initial(design.build_path)
+ var/max_stack_amount = initial(stack_item.max_amount)
+ var/number_to_make = (initial(stack_item.amount) * items_remaining)
+ while(number_to_make > max_stack_amount)
+ created = new stack_item(null, max_stack_amount) //it's imporant to spawn things in nullspace, since obj's like stacks qdel when they enter a tile/merge with other stacks of the same type, resulting in runtimes.
+ created.pixel_x = created.base_pixel_x + rand(-6, 6)
+ created.pixel_y = created.base_pixel_y + rand(-6, 6)
+ created.forceMove(target)
+ number_to_make -= max_stack_amount
+
+ created = new stack_item(null, number_to_make)
else
- created = new design.build_path(target)
+ created = new design.build_path(null)
split_materials_uniformly(design_materials, material_cost_coefficient, created)
created.pixel_x = created.base_pixel_x + rand(-6, 6)
created.pixel_y = created.base_pixel_y + rand(-6, 6)
SSblackbox.record_feedback("nested tally", "lathe_printed_items", 1, list("[type]", "[created.type]"))
+ created.forceMove(target)
if(is_stack)
items_remaining = 0
diff --git a/code/modules/research/ordnance/tank_compressor.dm b/code/modules/research/ordnance/tank_compressor.dm
index 830c004acad5e..d0393d9e10374 100644
--- a/code/modules/research/ordnance/tank_compressor.dm
+++ b/code/modules/research/ordnance/tank_compressor.dm
@@ -321,10 +321,6 @@
data["transferRate"] = transfer_rate
data["lastPressure"] = last_recorded_pressure
- data["inputData"] = gas_mixture_parser(airs[2], "Input Port")
- data["outputData"] = gas_mixture_parser(airs[1], "Ouput Port")
- data["bufferData"] = gas_mixture_parser(leaked_gas_buffer, "Gas Buffer")
-
data["disk"] = inserted_disk?.name
data["storage"] = "[inserted_disk?.used_capacity] / [inserted_disk?.max_capacity] GQ"
data["records"] = list()
diff --git a/code/modules/spells/spell_types/conjure/invisible_wall.dm b/code/modules/spells/spell_types/conjure/invisible_wall.dm
index d2812912f0fc2..a61db7cf74e19 100644
--- a/code/modules/spells/spell_types/conjure/invisible_wall.dm
+++ b/code/modules/spells/spell_types/conjure/invisible_wall.dm
@@ -15,7 +15,7 @@
invocation_self_message = span_notice("You form a wall in front of yourself.")
invocation_type = INVOCATION_EMOTE
- spell_requirements = SPELL_REQUIRES_MIME_VOW
+ spell_requirements = SPELL_REQUIRES_HUMAN|SPELL_REQUIRES_MIME_VOW
antimagic_flags = NONE
spell_max_level = 1
diff --git a/code/modules/spells/spell_types/self/mime_vow.dm b/code/modules/spells/spell_types/self/mime_vow.dm
index bd666786b9624..d4e34880b534d 100644
--- a/code/modules/spells/spell_types/self/mime_vow.dm
+++ b/code/modules/spells/spell_types/self/mime_vow.dm
@@ -8,7 +8,8 @@
panel = "Mime"
school = SCHOOL_MIME
- spell_requirements = NONE
+ //MMI mimes should be able to break their vow
+ spell_requirements = SPELL_CASTABLE_AS_BRAIN
spell_max_level = 1
diff --git a/code/modules/unit_tests/outfit_sanity.dm b/code/modules/unit_tests/outfit_sanity.dm
index 18f5e9b8e6141..554d226ed2e72 100644
--- a/code/modules/unit_tests/outfit_sanity.dm
+++ b/code/modules/unit_tests/outfit_sanity.dm
@@ -49,7 +49,7 @@
for (var/outfit_type in outfits_to_check)
// Only make one human and keep undressing it because it's much faster
- for (var/obj/item/I in H.get_equipped_items(include_pockets = TRUE))
+ for (var/obj/item/I in H.get_equipped_items(INCLUDE_POCKETS))
qdel(I)
var/datum/outfit/outfit = new outfit_type
diff --git a/html/changelogs/AutoChangeLog-pr-83439.yml b/html/changelogs/AutoChangeLog-pr-83439.yml
deleted file mode 100644
index 9e721ae4ba0a4..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-83439.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "carlarctg"
-delete-after: True
-changes:
- - balance: "Negative mutations now allow you to have more positive mutations, via reducing your instability!"
- - code_imp: "All mutations have been overall standardized via defines on their instability values. Many mediocre positive mutations have had their cost reduced significantly!"
- - rscadd: "Added a new height mutation: Acromegaly! It's the opposite of Dwarfism and makes you uncannily tall. It also makes you hit your head 8% or 4% (with synch) of the time you pass through airlocks. Wear a helmet!"
- - rscadd: "Gigantism is now a recipe mutation, mix Acromegaly with Strength to get it."
- - qol: "Injectors and activators' duration is now dependent on the in/stability (absolute value) of the mutations to be injected! With a minimum of 5-10-15 seconds for each type of injector. Also changed up a bit how part upgrade cooldowns work, by making each tier reduce cooldowns by 25-15-10% for each injector type."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-83673.yml b/html/changelogs/AutoChangeLog-pr-83673.yml
deleted file mode 100644
index 0211d4508cf97..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-83673.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Bisar"
-delete-after: True
-changes:
- - rscadd: "Sparks now ignite flammable things. Including you. Keep a fire extinguisher handy or stop dousing yourself in welding fuel!"
- - bugfix: "Fixed a few oversights with welding fuel pools not igniting when you throw lit/hot things into them or when you walk into them while on fire."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-83744.yml b/html/changelogs/AutoChangeLog-pr-83744.yml
deleted file mode 100644
index 8425dfbfccd62..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-83744.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Time-Green"
-delete-after: True
-changes:
- - refactor: "Lizard and moth markings now use the bodypart overlay system"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-83792.yml b/html/changelogs/AutoChangeLog-pr-83792.yml
deleted file mode 100644
index c856d7586a8ce..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-83792.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "TheRyeGuyWhoWillNowDie"
-delete-after: True
-changes:
- - rscadd: "the advanced omnitool upgrade now hastens the mediborg's syringe too"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-83866.yml b/html/changelogs/AutoChangeLog-pr-83866.yml
new file mode 100644
index 0000000000000..77c38213c9f14
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-83866.yml
@@ -0,0 +1,4 @@
+author: "Absolucy"
+delete-after: True
+changes:
+ - qol: "Prettied up the Chemical Analyzer's output in chat, making it easier to read, especially when scanning multiple things."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-83925.yml b/html/changelogs/AutoChangeLog-pr-83925.yml
new file mode 100644
index 0000000000000..7698097a45a3a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-83925.yml
@@ -0,0 +1,4 @@
+author: "Rhials"
+delete-after: True
+changes:
+ - bugfix: "Fixes a door in the Fredington Fasting Bear Five Nights and Fnafbears map."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-83952.yml b/html/changelogs/AutoChangeLog-pr-83952.yml
deleted file mode 100644
index 431aaa759582e..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-83952.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "GPeckman"
-delete-after: True
-changes:
- - bugfix: "Airlocks should no longer appear closed sometimes when fireman carrying someone into them."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-83986.yml b/html/changelogs/AutoChangeLog-pr-83986.yml
new file mode 100644
index 0000000000000..d22b2d9744ab2
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-83986.yml
@@ -0,0 +1,4 @@
+author: "GPeckman"
+delete-after: True
+changes:
+ - bugfix: "The chaplain altar can once again be buckled to."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-83988.yml b/html/changelogs/AutoChangeLog-pr-83988.yml
new file mode 100644
index 0000000000000..90f0a198682e6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-83988.yml
@@ -0,0 +1,8 @@
+author: "mc-oofert"
+delete-after: True
+changes:
+ - bugfix: "wawa centcom interns may actually leave the stationside dock"
+ - bugfix: "wawa hop office and cap office get keycard auths"
+ - bugfix: "wawa disposals blast doors work properly"
+ - bugfix: "wawa med elevator controls on the bottom floor are accessible"
+ - bugfix: "sci entrance actually has access restrictions"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-83999.yml b/html/changelogs/AutoChangeLog-pr-83999.yml
deleted file mode 100644
index a04af9580bdf3..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-83999.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Jacquerel"
-delete-after: True
-changes:
- - balance: "Gorillas have big fingers, which mostly just prevents them from using laser pointers and stun batons"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84006.yml b/html/changelogs/AutoChangeLog-pr-84006.yml
new file mode 100644
index 0000000000000..54a31eda940c7
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-84006.yml
@@ -0,0 +1,5 @@
+author: "SyncIt21"
+delete-after: True
+changes:
+ - bugfix: "no more runtimes when dragging turfs onto other stuff"
+ - code_imp: "most actions now properly check for recursive locs & better adjacency"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84053.yml b/html/changelogs/AutoChangeLog-pr-84053.yml
deleted file mode 100644
index 6aebdbc471f5f..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-84053.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "jlsnow301"
-delete-after: True
-changes:
- - bugfix: "TGUI say will no longer spill your /me contents when you get attacked"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84067.yml b/html/changelogs/AutoChangeLog-pr-84067.yml
new file mode 100644
index 0000000000000..2ab2ff078df5a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-84067.yml
@@ -0,0 +1,4 @@
+author: "SyncIt21"
+delete-after: True
+changes:
+ - bugfix: "Techfabs now print 5x cable coil"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84071.yml b/html/changelogs/AutoChangeLog-pr-84071.yml
new file mode 100644
index 0000000000000..766856faa60c8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-84071.yml
@@ -0,0 +1,4 @@
+author: "SyncIt21"
+delete-after: True
+changes:
+ - bugfix: "You can move around ui buttons in your action bar"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84074.yml b/html/changelogs/AutoChangeLog-pr-84074.yml
new file mode 100644
index 0000000000000..3ba774dadd0a4
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-84074.yml
@@ -0,0 +1,6 @@
+author: "MTandi"
+delete-after: True
+changes:
+ - bugfix: "Made 10 MJ & 20 MJ cells properly correspond to tiers 1 & 2 in lathes."
+ - image: "Updated cell sprites to correspond to other stock parts of their tiers."
+ - image: "Updated plasma cell, 500KJ cell and 2.5MJ cell sprites"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84099.yml b/html/changelogs/AutoChangeLog-pr-84099.yml
new file mode 100644
index 0000000000000..da8c2a27966e1
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-84099.yml
@@ -0,0 +1,4 @@
+author: "MTandi"
+delete-after: True
+changes:
+ - qol: "APC has wires for machinery/lights/environment channels"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84104.yml b/html/changelogs/AutoChangeLog-pr-84104.yml
new file mode 100644
index 0000000000000..580ba6a7626c3
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-84104.yml
@@ -0,0 +1,4 @@
+author: "MTandi"
+delete-after: True
+changes:
+ - bugfix: "Fixed techweb app showing wrong designs on Details button click"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84108.yml b/html/changelogs/AutoChangeLog-pr-84108.yml
new file mode 100644
index 0000000000000..f2a3935790775
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-84108.yml
@@ -0,0 +1,4 @@
+author: "mc-oofert"
+delete-after: True
+changes:
+ - bugfix: "gasping makes sound now"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84109.yml b/html/changelogs/AutoChangeLog-pr-84109.yml
new file mode 100644
index 0000000000000..8297afe62bb77
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-84109.yml
@@ -0,0 +1,4 @@
+author: "grungussuss"
+delete-after: True
+changes:
+ - bugfix: "mimes can now break their vow while borged or an MMI"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-84116.yml b/html/changelogs/AutoChangeLog-pr-84116.yml
new file mode 100644
index 0000000000000..e11526c56cf50
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-84116.yml
@@ -0,0 +1,5 @@
+author: "MTandi"
+delete-after: True
+changes:
+ - refactor: "Compressor UI to TypeScript"
+ - qol: "Simplified Compressor UI layout"
\ No newline at end of file
diff --git a/html/changelogs/archive/2024-06.yml b/html/changelogs/archive/2024-06.yml
index 9f757c45df58b..c1c7f194b7758 100644
--- a/html/changelogs/archive/2024-06.yml
+++ b/html/changelogs/archive/2024-06.yml
@@ -800,3 +800,46 @@
san7890:
- qol: A message with a link to publicly accessible logs (if enabled by your server
operators) should now be visible far earlier when a world is about to reboot.
+2024-06-19:
+ Bisar:
+ - rscadd: The Nanotrasen safety commission reminds employees to properly clean themselves
+ of all flammable material before going on smoke breaks.
+ - rscadd: Sparks now ignite flammable things. Including you. Keep a fire extinguisher
+ handy or stop dousing yourself in welding fuel!
+ - bugfix: Fixed a few oversights with welding fuel pools not igniting when you throw
+ lit/hot things into them or when you walk into them while on fire.
+ GPeckman:
+ - bugfix: Airlocks should no longer appear closed sometimes when fireman carrying
+ someone into them.
+ Jacquerel:
+ - balance: Gorillas have big fingers, which mostly just prevents them from using
+ laser pointers and stun batons
+ - balance: Items held in your hands can catch fire.
+ - balance: Items you are holding won't catch fire if your hands cannot catch fire.
+ - balance: When you stop being on fire so will items you are holding.
+ - balance: If you roll around on your burning items they will stop being on fire.
+ Melbert:
+ - bugfix: Fixed hand tele portals being forever
+ - bugfix: Enabling or disabling ambience mid round will properly enable or disable
+ ambience
+ - qol: Added descriptions differentiating "Ship ambience" from "ambience"
+ TheRyeGuyWhoWillNowDie:
+ - rscadd: the advanced omnitool upgrade now hastens the mediborg's syringe too
+ Time-Green:
+ - refactor: Lizard and moth markings now use the bodypart overlay system
+ carlarctg:
+ - balance: Negative mutations now allow you to have more positive mutations, via
+ reducing your instability!
+ - code_imp: All mutations have been overall standardized via defines on their instability
+ values. Many mediocre positive mutations have had their cost reduced significantly!
+ - rscadd: 'Added a new height mutation: Acromegaly! It''s the opposite of Dwarfism
+ and makes you uncannily tall. It also makes you hit your head 8% or 4% (with
+ synch) of the time you pass through airlocks. Wear a helmet!'
+ - rscadd: Gigantism is now a recipe mutation, mix Acromegaly with Strength to get
+ it.
+ - qol: Injectors and activators' duration is now dependent on the in/stability (absolute
+ value) of the mutations to be injected! With a minimum of 5-10-15 seconds for
+ each type of injector. Also changed up a bit how part upgrade cooldowns work,
+ by making each tier reduce cooldowns by 25-15-10% for each injector type.
+ jlsnow301:
+ - bugfix: TGUI say will no longer spill your /me contents when you get attacked
diff --git a/icons/obj/machines/cell_charger.dmi b/icons/obj/machines/cell_charger.dmi
index 5ce285fc81782..0c9ca53544286 100644
Binary files a/icons/obj/machines/cell_charger.dmi and b/icons/obj/machines/cell_charger.dmi differ
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 8516823a5587f..3f1c50c16f9f1 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
@@ -10,6 +10,7 @@ import { FeatureDropdownInput } from '../dropdowns';
export const sound_ambience: FeatureToggle = {
name: 'Enable ambience',
category: 'SOUND',
+ description: `Ambience refers to the more noticeable ambient sounds that play on occasion.`,
component: CheckboxInput,
};
@@ -81,6 +82,7 @@ export const sound_midi: FeatureToggle = {
export const sound_ship_ambience: FeatureToggle = {
name: 'Enable ship ambience',
category: 'SOUND',
+ description: `Ship ambience refers to the low ambient buzz that plays on loop.`,
component: CheckboxInput,
};
diff --git a/tgui/packages/tgui/interfaces/TankCompressor.jsx b/tgui/packages/tgui/interfaces/TankCompressor.jsx
deleted file mode 100644
index 1fddb2b1938f6..0000000000000
--- a/tgui/packages/tgui/interfaces/TankCompressor.jsx
+++ /dev/null
@@ -1,356 +0,0 @@
-import { useBackend, useSharedState } from '../backend';
-import {
- Box,
- Button,
- Flex,
- Icon,
- LabeledList,
- Modal,
- NoticeBox,
- RoundGauge,
- Section,
- Slider,
- Stack,
- Tabs,
-} from '../components';
-import { Window } from '../layouts';
-import { GasmixParser } from './common/GasmixParser';
-
-export const TankCompressor = (props) => {
- return (
-
-
-
-
-
- );
-};
-
-const TankCompressorContent = (props) => {
- const { act, data } = useBackend();
- const { disk, storage } = data;
- const [currentTab, changeTab] = useSharedState('compressorTab', 1);
-
- return (
-
- {currentTab === 1 && }
- {currentTab === 2 && }
-
-
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-const AlertBoxes = (props) => {
- const { text_content, icon_name, icon_break, color, active } = props;
-
- return (
-
-
-
-
- {icon_break &&
}
- {text_content}
-
-
-
- );
-};
-
-const TankCompressorControls = (props) => {
- const { act, data } = useBackend();
- const {
- tankPresent,
- leaking,
- lastPressure,
- leakPressure,
- fragmentPressure,
- tankPressure,
- maxTransfer,
- active,
- transferRate,
- ejectPressure,
- inputData,
- outputData,
- bufferData,
- } = data;
- const pressure = tankPresent ? tankPressure : lastPressure;
- const usingLastData = !!(lastPressure && !tankPresent);
-
- return (
- <>
-
- ejectPressure}
- onClick={() => act('eject_tank')}
- >
- {'Eject Tank'}
-
- }
- >
- {!pressure && {'No Pressure Detected'}}
- {usingLastData && (
-
- {'Tank destroyed. Displaying last recorded data.'}
-
- )}
-
-
- (value ? value.toFixed(2) : '-') + ' kPa'}
- />
-
-
-
-
-
- = leakPressure}
- />
-
-
-
-
- = leakPressure &&
- pressure < fragmentPressure) ||
- leaking
- }
- />
-
-
- = fragmentPressure}
- />
-
-
-
-
-
-
-
-
-
-
-
- act('change_rate', { target: new_rate })
- }
- />
-
-
-
-
-
-
-
-
-
-
-
- {!inputData.total_moles && {'No Gas Present'}}
-
-
-
-
-
- {!outputData.inputData && {'No Gas Present'}}
-
-
-
-
-
- }
- >
- {!bufferData.total_moles && {'No Gas Present'}}
-
-
-
-
-
- >
- );
-};
-
-const TankCompressorRecords = (props) => {
- const { act, data } = useBackend();
- const { records = [], disk } = data;
- const [activeRecordRef, setActiveRecordRef] = useSharedState(
- 'recordRef',
- records[0]?.ref,
- );
- const activeRecord =
- !!activeRecordRef &&
- records.find((record) => activeRecordRef === record.ref);
- if (records.length === 0) {
- return (
-
- No Records
-
- );
- }
-
- return (
-
-
-
-
- {records.map((record) => (
- setActiveRecordRef(record.ref)}
- >
- {record.name}
-
- ))}
-
-
- {activeRecord ? (
-
- {
- act('delete_record', {
- ref: activeRecord.ref,
- });
- }}
- />,
-
-
- ) : (
-
- No Record Selected
-
- )}
-
-
- );
-};
diff --git a/tgui/packages/tgui/interfaces/TankCompressor.tsx b/tgui/packages/tgui/interfaces/TankCompressor.tsx
new file mode 100644
index 0000000000000..3f516e3c01803
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/TankCompressor.tsx
@@ -0,0 +1,321 @@
+import { toFixed } from 'common/math';
+import { BooleanLike } from 'common/react';
+
+import { useBackend, useSharedState } from '../backend';
+import {
+ Box,
+ Button,
+ Knob,
+ LabeledControls,
+ LabeledList,
+ NoticeBox,
+ RoundGauge,
+ Section,
+ Stack,
+ Tabs,
+} from '../components';
+import { formatSiUnit } from '../format';
+import { Window } from '../layouts';
+
+type Data = {
+ // Dynamic
+ tankPresent: BooleanLike;
+ tankPressure: number;
+ leaking: BooleanLike;
+ active: BooleanLike;
+ transferRate: number;
+ lastPressure: number;
+ disk: string;
+ storage: string;
+ records: Record[];
+ // Static
+ maxTransfer: number;
+ leakPressure: number;
+ fragmentPressure: number;
+ ejectPressure: number;
+};
+
+type Record = {
+ ref: string;
+ name: string;
+ timestamp: string;
+ source: string;
+ gases: GasMoles[];
+};
+
+type GasMoles = {
+ [key: string]: number;
+};
+
+const formatPressure = (value) => {
+ if (value < 10000) {
+ return toFixed(value) + ' kPa';
+ }
+ return formatSiUnit(value * 1000, 1, 'Pa');
+};
+
+export const TankCompressor = (props) => {
+ return (
+
+
+
+
+
+ );
+};
+
+const TankCompressorContent = (props) => {
+ const { act, data } = useBackend();
+ const { disk, storage } = data;
+
+ return (
+
+
+ act('eject_disk')}
+ >
+ Eject Disk
+
+ }
+ >
+
+
+
+
+ );
+};
+
+const TankCompressorControls = (props) => {
+ const { act, data } = useBackend();
+ const {
+ tankPresent,
+ leaking,
+ lastPressure,
+ leakPressure,
+ fragmentPressure,
+ tankPressure,
+ maxTransfer,
+ active,
+ transferRate,
+ ejectPressure,
+ } = data;
+ const pressure = tankPresent ? tankPressure : lastPressure;
+ const usingLastData = !!(lastPressure && !tankPresent);
+ const notice_color =
+ usingLastData || leaking || pressure > fragmentPressure
+ ? 'bad'
+ : !tankPresent
+ ? 'blue'
+ : pressure > leakPressure
+ ? 'average'
+ : 'good';
+ const notice_text = usingLastData
+ ? 'Tank destroyed. Displaying last recorded data.'
+ : !tankPresent
+ ? 'No Tank Detected'
+ : leaking
+ ? 'Tank Leaking'
+ : !pressure
+ ? 'No Pressure Detected'
+ : pressure < leakPressure
+ ? 'Tank Pressure Nominal'
+ : pressure < fragmentPressure
+ ? 'Leak Hazard'
+ : 'Explosive Hazard';
+
+ return (
+
+ ejectPressure}
+ onClick={() => act('eject_tank')}
+ >
+ {'Eject Tank'}
+
+ }
+ >
+ {notice_text}
+
+
+
+
+
+
+
+ act('change_rate', {
+ target: value,
+ })
+ }
+ />
+
+
+
+ act('toggle_injection')}
+ >
+ {active ? 'On' : 'Off'}
+
+
+
+
+
+ );
+};
+
+const TankCompressorRecords = (props) => {
+ const { act, data } = useBackend();
+ const { records = [], disk } = data;
+ const [activeRecordRef, setActiveRecordRef] = useSharedState(
+ 'recordRef',
+ records[0]?.ref,
+ );
+ const activeRecord =
+ !!activeRecordRef &&
+ records.find((record) => activeRecordRef === record.ref);
+ if (records.length === 0) {
+ return (
+
+ No Records
+
+ );
+ }
+
+ return (
+
+
+
+
+ {records.map((record) => (
+ setActiveRecordRef(record.ref)}
+ >
+ {record.name}
+
+ ))}
+
+
+ {activeRecord ? (
+
+
+
+ {activeRecord.name}
+
+
+ {activeRecord.timestamp}
+
+
+ {activeRecord.source}
+
+
+
+ {Object.keys(activeRecord.gases).map((gas_name) => (
+
+ {(activeRecord.gases[gas_name]
+ ? activeRecord.gases[gas_name].toFixed(2)
+ : '-') + ' moles'}
+
+ ))}
+
+
+
+ {
+ act('save_record', {
+ ref: activeRecord.ref,
+ });
+ }}
+ />
+ {
+ act('delete_record', {
+ ref: activeRecord.ref,
+ });
+ }}
+ />
+
+
+
+ ) : (
+
+ No Record Selected
+
+ )}
+
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/Techweb.jsx b/tgui/packages/tgui/interfaces/Techweb.jsx
index c041d646d7d99..dcafea78bf529 100644
--- a/tgui/packages/tgui/interfaces/Techweb.jsx
+++ b/tgui/packages/tgui/interfaces/Techweb.jsx
@@ -621,7 +621,7 @@ const TechNode = (props) => {
{design_ids.map((k, i) => (