diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm
index 47541eb8be6..054e93e762d 100644
--- a/code/game/objects/structures/ladders.dm
+++ b/code/game/objects/structures/ladders.dm
@@ -12,6 +12,7 @@
/// Optional travel time for ladder in deciseconds
var/travel_time = 0
var/obstructed = FALSE // MOJAVE SUN BASE EDIT
+ var/locked = FALSE // MOJAVE SUN BASE EDIT
/obj/structure/ladder/Initialize(mapload, obj/structure/ladder/up, obj/structure/ladder/down)
..()
diff --git a/mojave/icons/structure/ladders.dmi b/mojave/icons/structure/ladders.dmi
index d7ef072623c..c1ed8f9f45a 100644
Binary files a/mojave/icons/structure/ladders.dmi and b/mojave/icons/structure/ladders.dmi differ
diff --git a/mojave/structures/ladders.dm b/mojave/structures/ladders.dm
index e603dcb4a77..18acc93d6ad 100644
--- a/mojave/structures/ladders.dm
+++ b/mojave/structures/ladders.dm
@@ -2,10 +2,13 @@
name = "ladder"
desc = "A questionable metal ladder. There's got to be stairs around, right?"
icon = 'mojave/icons/structure/ladders.dmi'
- icon_state = "ladder10"
+ icon_state = "ladder01"
resistance_flags = INDESTRUCTIBLE
travel_time = 2 SECONDS
+/obj/structure/ladder/ms13/upwards
+ icon_state = "ladder10"
+
// TG code edited for SFX //
/obj/structure/ladder/ms13/travel(going_up, mob/user, is_ghost, obj/structure/ladder/ladder)
@@ -62,6 +65,8 @@
// Subtypes //
+///////////////////// MANHOLE COVER /////////////////////////
+
/obj/structure/ladder/ms13/manhole
name = "manhole"
desc = "A manhole ladder, you could probably push the cover off from here, or try dragging it back on."
@@ -69,6 +74,9 @@
pixel_y = 7
icon_state = "manhole_closed"
+/obj/structure/ladder/ms13/manhole/upwards
+ icon_state = "ladder10"
+
/obj/structure/ladder/ms13/manhole/examine(mob/user)
. = ..()
. += "Use RIGHT-CLICK on [src] to open or close it."
@@ -104,6 +112,7 @@
to_chat(user, span_warning("It's so heavy! Surely there's a better way of doing this."))
if(do_after(user, 10 SECONDS, target = src, interaction_key = DOAFTER_SOURCE_LADDERBLOCKERS))
obstructed = FALSE
+ down.obstructed = FALSE
icon_state = "manhole_open"
desc = "An open manhole, it still stinks even after all these years. You could use a crowbar or your hands to slide the cover back on."
to_chat(user, span_notice("With a lot of effort, you manage to finally get the cover off."))
@@ -114,6 +123,7 @@
else
if(do_after(user, 10 SECONDS, target = src, interaction_key = DOAFTER_SOURCE_LADDERBLOCKERS))
obstructed = TRUE
+ down.obstructed = TRUE
icon_state = "manhole_closed"
desc = "A heavy stamped manhole. You could probably pry it up with a crowbar to access the lower town systems. Or, try using your hands..."
to_chat(user, span_notice("You carefully slide the cover back on the manhole."))
@@ -123,6 +133,7 @@
if(down && obstructed)
if(do_after(user, 4 SECONDS * tool.toolspeed, target = src, interaction_key = DOAFTER_SOURCE_LADDERBLOCKERS))
obstructed = FALSE
+ down.obstructed = FALSE
icon_state = "manhole_open"
desc = "An open manhole, it still stinks even after all these years. You could use a crowbar or your hands to slide the cover back on."
to_chat(user, span_notice("You wedge the crowbar in and pull the cover off the manhole."))
@@ -131,6 +142,7 @@
if(down && !obstructed)
if(do_after(user, 4 SECONDS * tool.toolspeed, target = src, interaction_key = DOAFTER_SOURCE_LADDERBLOCKERS))
obstructed = TRUE
+ down.obstructed = TRUE
icon_state = "manhole_closed"
desc = "A heavy stamped manhole. You could probably pry it up with a crowbar to access the lower town systems. Or, try using your hands..."
to_chat(user, span_notice("You hook the edge of the manhole cover with your crowbar and slide it back on."))
@@ -142,21 +154,28 @@
name = "manhole entry"
desc = "A heavy stamped manhole. You could probably pry it up with a crowbar to access the lower town systems."
icon_state = "manhole_closed"
+ pixel_y = 7
obstructed = TRUE
else
icon_state = "ladder10"
+////////////////////// BUNKER GRATE /////////////////////////
+
/obj/structure/ladder/ms13/bunker
name = "bunker"
icon_state = "bunker_closed"
travel_time = 2 SECONDS
+/obj/structure/ladder/ms13/bunker/upwards
+ icon_state = "ladder10"
+
/obj/structure/ladder/ms13/bunker/welder_act_secondary(mob/living/user, obj/item/I)
if(down && obstructed)
if(!I.tool_start_check(user, amount=0))
return TRUE
if(I.use_tool(src, user, 15 SECONDS, volume=80))
obstructed = FALSE
+ down.obstructed = FALSE
icon_state = "bunker_open"
desc = "Looks like the entrance to some bunker. The bars on the grate have been cut off, allowing entry."
to_chat(user, span_notice("You cut-weld the bars off the grate, letting you slip past."))
@@ -169,5 +188,188 @@
desc = "It looks like a grate, leading to some sort of bunker. You could probably weld the bars off."
icon_state = "bunker_closed"
obstructed = TRUE
+ down.obstructed = TRUE
+ else
+ icon_state = "ladder10"
+
+////////////////////////// ROPE /////////////////////////////
+
+/// A simple rope, take a bit more time to climb up than go down.
+/obj/structure/ladder/ms13/rope
+ name = "rope"
+ desc = "A thick rope made of natural fibres and tied to a rusted rod firmly planted in the ground."
+ icon_state = "rope"
+ pixel_y = 15
+ travel_time = 3 SECONDS
+
+/obj/structure/ladder/ms13/rope/upwards
+ icon_state = "rope_down"
+ pixel_y = -10
+
+/obj/structure/ladder/ms13/rope/update_icon_state()
+ . = ..()
+ if(down)
+ icon_state = "rope"
+ travel_time = initial(travel_time)
+ else
+ icon_state = "rope_down"
+ travel_time = 6 SECONDS
+
+/////////////////////// DAS BUNKER //////////////////////////
+
+/// A simple hatch than can be locked from above.
+/obj/structure/ladder/ms13/hatch
+ name = "bunker hatch"
+ desc = "A bunker ladder, you could probably push the hatch open from here, or try closing it."
+ icon_state = "hatch_closed"
+ travel_time = 2 SECONDS
+ locked = TRUE
+
+/obj/structure/ladder/ms13/hatch/upwards
+ icon_state = "ladder10"
+
+/obj/structure/ladder/ms13/hatch/examine(mob/user)
+ . = ..()
+ . += "Use RIGHT-CLICK on [src] to open or close it."
+ if(down)
+ . += "Use CTRL-CLICK on [src] to lock or unlock it."
+
+/// Open or close the hatch.
+/// Hatch can be opened/closed from both side.
+/// Hatch must be unlocked before begin opened.
+/obj/structure/ladder/ms13/hatch/attack_hand_secondary(mob/living/user, list/modifiers)
+ . = ..()
+ if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
+ return
+
+ . = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+
+ if(!down)
+ if(up.locked)
+ to_chat(user, span_notice("The bunker hatch is locked from above!"))
+ else
+ to_chat(user, span_warning("You start to slowly [up.obstructed ? "open" : "close"] the bunker hatch from below."))
+ if(do_after(user, 12 SECONDS, target = src, interaction_key = DOAFTER_SOURCE_LADDERBLOCKERS))
+ obstructed = !obstructed
+ up.obstructed = obstructed
+ up.icon_state = up.obstructed ? "hatch_closed" : "hatch_open"
+ to_chat(user, span_notice("You [up.obstructed ? "closed" : "opened"] the bunker hatch from below."))
+ else
+ if(locked)
+ to_chat(user, span_notice("[src] must be unlocked first."))
+ else
+ to_chat(user, span_warning("You start to slowly [obstructed ? "open" : "close"] [src]."))
+ if(do_after(user, 10 SECONDS, target = src, interaction_key = DOAFTER_SOURCE_LADDERBLOCKERS))
+ obstructed = !obstructed
+ down.obstructed = obstructed
+ icon_state = obstructed ? "hatch_closed" : "hatch_open"
+ to_chat(user, span_notice("You [obstructed ? "closed" : "opened"] [src]."))
+
+/// Lock or unlock the hatch.
+/// Hatch can only be locked/unlocked from above.
+/// Hatch must be closed before begin locked.
+/obj/structure/ladder/ms13/hatch/CtrlClick(mob/user)
+ . = ..()
+ if(!down)
+ to_chat(user, span_notice("You cannot [locked ? "unlock" : "lock"] the bunker hatch from this side!"))
+ return
+ else
+ if(obstructed)
+ to_chat(user, span_warning("You start spinning the metal hand-wheel to [locked ? "unlock" : "lock"] [src]."))
+ if(do_after(user, 10 SECONDS, target = src, interaction_key = DOAFTER_SOURCE_LADDERBLOCKERS))
+ locked = !locked
+ down.locked = locked
+ to_chat(user, span_notice("You [locked ? "locked" : "unlocked"] [src]."))
+ return
+ else
+ to_chat(user, span_notice("[src] must be brought down before you can lock it."))
+
+
+/obj/structure/ladder/ms13/hatch/update_icon_state()
+ . = ..()
+ if(down)
+ name = "bunker hatch"
+ icon_state = "hatch_closed"
+ desc = "A bunker hatch that can be firmly closed or opened from above using a metal hand-wheel."
+ obstructed = TRUE
+ down.obstructed = TRUE
+ locked = TRUE
+ down.locked = TRUE
+ else
+ name = "bunker ladder"
+ icon_state = "ladder10"
+
+/obj/structure/ladder/ms13/hatch/Initialize(mapload)
+ . = ..()
+ register_context()
+
+/obj/structure/ladder/ms13/hatch/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
+ . = ..()
+
+ if (isnull(held_item))
+ context[SCREENTIP_CONTEXT_RMB] = "Open/Close"
+ context[SCREENTIP_CONTEXT_CTRL_LMB] = "Lock/Unlock"
+ return CONTEXTUAL_SCREENTIP_SET
+
+///////////////////// ENCLAVE BUNKER ////////////////////////
+
+/// An Enclave hatch than cannot be locked.
+/obj/structure/ladder/ms13/enclave
+ name = "Enclave bunker ladder"
+ desc = "A bunker ladder adorned with Enclave heraldic, you could probably push the hatch open from here, or try closing it."
+ icon_state = "enclave_closed"
+ travel_time = 2 SECONDS
+
+/obj/structure/ladder/ms13/enclave/upwards
+ icon_state = "ladder10"
+
+/obj/structure/ladder/ms13/enclave/examine(mob/user)
+ . = ..()
+ . += "Use RIGHT-CLICK on [src] to open or close it."
+
+/// Open or close the hatch.
+/// Hatch can be opened/closed from both side.
+/obj/structure/ladder/ms13/enclave/attack_hand_secondary(mob/living/user, list/modifiers)
+ . = ..()
+ if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
+ return
+
+ . = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+
+ if(!down)
+ to_chat(user, span_warning("You start to slowly [up.obstructed ? "open" : "close"] the Enclave bunker hatch from below."))
+ if(do_after(user, 12 SECONDS, target = src, interaction_key = DOAFTER_SOURCE_LADDERBLOCKERS))
+ obstructed = !obstructed
+ up.obstructed = obstructed
+ up.icon_state = up.obstructed ? "enclave_closed" : "enclave_open"
+ to_chat(user, span_notice("You [up.obstructed ? "closed" : "opened"] the Enclave bunker hatch from below."))
+ else
+ to_chat(user, span_warning("You start to slowly [obstructed ? "open" : "close"] [src]."))
+ if(do_after(user, 10 SECONDS, target = src, interaction_key = DOAFTER_SOURCE_LADDERBLOCKERS))
+ obstructed = !obstructed
+ down.obstructed = obstructed
+ icon_state = obstructed ? "enclave_closed" : "enclave_open"
+ to_chat(user, span_notice("You [up.obstructed ? "closed" : "opened"] [src]."))
+
+/obj/structure/ladder/ms13/enclave/update_icon_state()
+ . = ..()
+ if(down)
+ name = "Enclave bunker hatch"
+ desc = "A thick bunker hatch adorned with a half-faded Enclave roundel."
+ icon_state = "enclave_closed"
+ obstructed = TRUE
+ down.obstructed = TRUE
else
+ name = "Enclave bunker ladder"
icon_state = "ladder10"
+
+/obj/structure/ladder/ms13/enclave/Initialize(mapload)
+ . = ..()
+ register_context()
+
+/obj/structure/ladder/ms13/enclave/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
+ . = ..()
+
+ if (isnull(held_item))
+ context[SCREENTIP_CONTEXT_RMB] = "Open/Close"
+ return CONTEXTUAL_SCREENTIP_SET