diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 48e6be8915..c3a331b651 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -499,6 +499,10 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define RIDING_OFFSET_ALL "ALL"
+//stack recipe placement check types
+#define STACK_CHECK_CARDINALS "cardinals" //checks if there is an object of the result type in any of the cardinal directions
+#define STACK_CHECK_ADJACENT "adjacent" //checks if there is an object of the result type within one tile
+
//text files
#define BRAIN_DAMAGE_FILE "traumas.json"
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 04a0f1c738..0c0b942083 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -377,8 +377,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
new/datum/stack_recipe("sender - lever", /obj/structure/destructible/clockwork/trap/trigger/lever, 1, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("sender - repeater", /obj/structure/destructible/clockwork/trap/trigger/repeater, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
null,
- new/datum/stack_recipe("receiver - brass skewer", /obj/structure/destructible/clockwork/trap/brass_skewer, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("receiver - brass skewer", /obj/structure/destructible/clockwork/trap/brass_skewer, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_ADJACENT), \
+ new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
))
/obj/item/stack/tile/brass
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 934aef5d5f..ccf4cfa860 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -232,6 +232,19 @@
if(R.on_floor && !isfloorturf(usr.loc))
to_chat(usr, "\The [R.title] must be constructed on the floor!")
return 0
+ if(R.placement_checks)
+ switch(R.placement_checks)
+ if(STACK_CHECK_CARDINALS)
+ var/turf/step
+ for(var/direction in GLOB.cardinals)
+ step = get_step(usr, direction)
+ if(locate(R.result_type) in step)
+ to_chat(usr, "\The [R.title] must not be built directly adjacent to another!")
+ return 0
+ if(STACK_CHECK_ADJACENT)
+ if(locate(R.result_type) in range(1, usr))
+ to_chat(usr, "\The [R.title] must be constructed at least one tile away from others of its type!")
+ return 0
return 1
/obj/item/stack/proc/use(used, transfer = FALSE) // return 0 = borked; return 1 = had enough
@@ -360,8 +373,9 @@
var/one_per_turf = FALSE
var/on_floor = FALSE
var/window_checks = FALSE
+ var/placement_checks = FALSE
-/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE)
+/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE)
src.title = title
src.result_type = result_type
src.req_amount = req_amount
@@ -371,7 +385,7 @@
src.one_per_turf = one_per_turf
src.on_floor = on_floor
src.window_checks = window_checks
-
+ src.placement_checks = placement_checks
/*
* Recipe list datum
*/
diff --git a/code/modules/antagonists/clockcult/clock_scripture.dm b/code/modules/antagonists/clockcult/clock_scripture.dm
index 67a8ba1ca3..753de786dc 100644
--- a/code/modules/antagonists/clockcult/clock_scripture.dm
+++ b/code/modules/antagonists/clockcult/clock_scripture.dm
@@ -218,7 +218,7 @@ Applications: 8 servants, 3 caches, and 100 CV
var/creator_message = "You create a meme." //Shown to the invoker
var/observer_message
var/one_per_tile = FALSE
- var/prevent_path
+ var/atom/movable/prevent_path
var/space_allowed = FALSE
/datum/clockwork_scripture/create_object/New()
diff --git a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor.dm b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor.dm
index fffabe8f5c..94f0ba7112 100644
--- a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor.dm
@@ -5,8 +5,7 @@
clockwork_desc = "A trigger that will activate when a non-servant runs across it."
max_integrity = 5
icon_state = "pressure_sensor"
- alpha = 80
- layer = LOW_ITEM_LAYER
+ alpha = 50
/obj/structure/destructible/clockwork/trap/trigger/Initialize()
. = ..()
diff --git a/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm b/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
index 6aede1592e..8d65574987 100644
--- a/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
@@ -7,6 +7,7 @@
break_message = "The vent snaps and collapses!"
max_integrity = 100
density = FALSE
+ layer = BELOW_OBJ_LAYER
/obj/structure/destructible/clockwork/trap/steam_vent/activate()
opacity = !opacity