diff --git a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm
index 36aaa27716..1d27467ee6 100644
--- a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm
+++ b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm
@@ -14,6 +14,8 @@
var/uses = 1 //How many objects or mobs can go through the portal
var/obj/effect/clockwork/spatial_gateway/linked_gateway //The gateway linked to this one
var/timerid
+ var/is_stable = FALSE
+ var/busy = FALSE //If someone is already working on closing the gateway, only needed for stable gateways but in the parent to not need typecasting
/obj/effect/clockwork/spatial_gateway/Initialize()
. = ..()
@@ -31,11 +33,16 @@
clockwork_desc = "A gateway in reality. It can both send and receive objects."
else
clockwork_desc = "A gateway in reality. It can only [sender ? "send" : "receive"] objects."
- timerid = QDEL_IN(src, lifetime)
+ if(is_stable)
+ return
+ timerid = QDEL_IN(src, lifetime) //We only need this if the gateway is not stable
//set up a gateway with another gateway
/obj/effect/clockwork/spatial_gateway/proc/setup_gateway(obj/effect/clockwork/spatial_gateway/gatewayB, set_duration, set_uses, two_way)
- if(!gatewayB || !set_duration || !uses)
+ if(!gatewayB)
+ return FALSE
+
+ if((!set_duration || !uses) && !is_stable)
return FALSE
linked_gateway = gatewayB
gatewayB.linked_gateway = src
@@ -55,7 +62,7 @@
/obj/effect/clockwork/spatial_gateway/examine(mob/user)
. = ..()
if(is_servant_of_ratvar(user) || isobserver(user))
- . += "It has [uses] use\s remaining."
+ . += " [is_stable ? "It is stabilised and can be used as much as is neccessary." : "It has [uses] use\s remaining."]"
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/obj/effect/clockwork/spatial_gateway/attack_ghost(mob/user)
@@ -122,9 +129,9 @@
/obj/effect/clockwork/spatial_gateway/Bumped(atom/movable/AM)
..()
if(!QDELETED(AM))
- pass_through_gateway(AM, FALSE)
+ pass_through_gateway(AM)
-/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A, no_cost)
+/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A, no_cost = FALSE)
if(!linked_gateway)
qdel(src)
return FALSE
@@ -198,6 +205,10 @@
return procure_gateway(invoker, time_duration, gateway_uses, two_way)
var/istargetobelisk = istype(target, /obj/structure/destructible/clockwork/powered/clockwork_obelisk)
var/issrcobelisk = istype(src, /obj/structure/destructible/clockwork/powered/clockwork_obelisk)
+ if(!issrcobelisk && target.z != invoker.z && (is_reebe(invoker.z) || is_reebe(target.z)) && !GLOB.ratvar_awakens) //You need obilisks to get from and to reebe. Costs alot of power, unless you use stable gateways.
+ to_chat(invoker, "The distance between reebe and the mortal realm is far too vast to bridge with a gateway your slab can create, my child. \
+ Use an obilisk instead!")
+ return procure_gateway(invoker, time_duration, gateway_uses, two_way)
if(issrcobelisk)
if(!anchored)
to_chat(invoker, "[src] is no longer secured!")
@@ -227,3 +238,43 @@
S1.setup_gateway(S2, time_duration, gateway_uses, two_way)
S2.visible_message("The air in front of [target] ripples before suddenly tearing open!")
return TRUE
+
+//Stable Gateway: Used to travel to and from reebe without any further powercost. Needs a clockwork obilisk to keep active, but stays active as long as it is not deactivated via an null rod or a slab, or the obilisk is destroyed
+/obj/effect/clockwork/spatial_gateway/stable
+ name = "stable gateway"
+ is_stable = TRUE
+ //TODO: Icon for the gateway that looks a bit different
+
+/obj/effect/clockwork/spatial_gateway/stable/ex_act(severity)
+ if(severity == 1)
+ start_shutdown() //Yes, you can chain devastation-level explosions to delay a gateway shutdown, if you somehow manage to do it without breaking the obelisk. Is it worth it? Probably not.
+ return TRUE
+ return FALSE
+
+/obj/effect/clockwork/spatial_gateway/stable/attackby(obj/item/I, mob/living/user, params)
+ if(!istype(I, /obj/item/clockwork/slab) || !is_servant_of_ratvar(user) || busy)
+ return ..()
+ user.visible_message("The rift begins to ripple as [user] points [user.p_their()] slab at it!", " You begin to shutdown the stabilised gateway with your slab.")
+ linked_gateway.visible_message("")
+ busy = TRUE
+ linked_gateway.busy = TRUE
+ if(do_after(user, 80, target = src)) //Eight seconds to initiate the closing, then another two before is closes.
+ to_chat(user, "You successfully set the gateway to shutdown in another two seconds.")
+ start_shutdown()
+ busy = FALSE
+ linked_gateway.busy = FALSE
+ return TRUE
+ //TODO: Add effect for this, maybe reuse the void blaster one from that PR?
+
+/obj/effect/clockwork/spatial_gateway/stable/proc/start_shutdown()
+ deltimer(timerid)
+ deltimer(linked_gateway.timerid)
+ timerid = QDEL_IN(src, 20)
+ linked_gateway.timerid = QDEL_IN(linked_gateway, 20)
+ animate(src, alpha = 0, transform = matrix()*2, time = 20, flags = ANIMATION_END_NOW)
+ animate(linked_gateway, alpha = 0, transform = matrix()*2, time = 20, flags = ANIMATION_END_NOW)
+ src.visible_message("[src] begins to destabilise!")
+ linked_gateway.visible_message("[linked_gateway] begins to destabilise!")
+
+/obj/effect/clockwork/spatial_gateway/stable/pass_through_gateway(atom/movable/A, no_cost = TRUE)
+ return ..()
\ No newline at end of file
diff --git a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm
index 058bd9d24e..09b716acfc 100644
--- a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm
@@ -41,6 +41,11 @@
affected += try_use_power(MIN_CLOCKCULT_POWER*4)
return affected
+/obj/structure/destructible/clockwork/powered/clockwork_obelisk/Destroy()
+ for(var/obj/effect/clockwork/spatial_gateway/SG in loc)
+ SG.ex_act(EXPLODE_DEVASTATE)
+ return ..()
+
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user)
. = ..()
if(.)
@@ -48,7 +53,7 @@
if(!is_servant_of_ratvar(user) || !can_access_clockwork_power(src, hierophant_cost) || !anchored)
to_chat(user, "You place your hand on [src], but it doesn't react.")
return
- var/choice = alert(user,"You place your hand on [src]...",,"Hierophant Broadcast","Spatial Gateway","Cancel")
+ var/choice = alert(user,"You place your hand on [src]...",,/*"Hierophant Broadcast",*/"Spatial Gateway","Stable Reebe Gateway","Cancel") //TODO: Find a good way to do this because choice does only support up to six args, not seven as needed
switch(choice)
if("Hierophant Broadcast")
if(active)
@@ -91,12 +96,32 @@
clockwork_say(user, text2ratvar("Spatial Gateway, activate!"))
return
adjust_clockwork_power(gateway_cost) //if we didn't return above, ie, successfully create a gateway, we give the power back
+ if("Stable Reebe Gateway")
+ if(active)
+ to_chat(user, "[src] is already sustaining a gateway!")
+ return
+ if(!user.can_speak_vocal())
+ to_chat(user, "You need to be able to speak to open a stable gateway!")
+ return
+ if(is_reebe(z))
+ to_chat(user, "You are already on reebe, child...")
+ return
+ if(!try_use_power(gateway_cost)) //Maybe set it a bit higher than a normal portal? Eh should be fine, balance will tell..
+ to_chat(user, "[src] lacks the power to open a stable gateway!")
+ return
+ if(procure_reebe_gateway(user))
+ process()
+ if(!active)
+ active = TRUE
+ clockwork_say(user, text2ratvar("Stable Gateway, activate!"))
+ return
+ adjust_clockwork_power(gateway_cost) //Same as before
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/process()
if(!anchored)
return
var/obj/effect/clockwork/spatial_gateway/SG = locate(/obj/effect/clockwork/spatial_gateway) in loc
- if(SG && SG.timerid) //it's a valid gateway, we're active
+ if(SG && (SG.timerid || SG.is_stable)) //it's a valid gateway, we're active
icon_state = active_icon
density = FALSE
active = TRUE
@@ -104,3 +129,26 @@
icon_state = inactive_icon
density = TRUE
active = FALSE
+
+//Special proc used for station-reebe stable gateways created by Obilisks on the station. Not done as subtype of the proc because it's quite a bit different.\
+ Chooses one random non-active obilisk on reebe to link to.
+/obj/structure/destructible/clockwork/powered/clockwork_obelisk/proc/procure_reebe_gateway(mob/living/user)
+ var/list/possible_reebe_obilisks = list()
+ for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in GLOB.all_clockwork_objects)
+ if(is_reebe(O.z) && !O.active && O.anchored)
+ possible_reebe_obilisks += O
+
+ if(!possible_reebe_obilisks.len)
+ to_chat(user, "There are no eligible Obilisks on reebe!")
+ return FALSE
+ var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/target = pick(possible_reebe_obilisks)
+
+ target.active = TRUE
+ src.active = TRUE
+ user.visible_message("The air in front of [user] ripples before suddenly tearing open!", \
+ "With a word, you open a stable rift between reebe and the mortal realm.")
+ var/obj/effect/clockwork/spatial_gateway/stable/S1 = new(get_turf(src))
+ var/obj/effect/clockwork/spatial_gateway/stable/S2 = new(get_turf(target))
+ S1.setup_gateway(S2, 1, 1, TRUE) //The two 1s are irrelevant since it's a stable gateway
+ S2.visible_message("The air in front of [target] ripples before suddenly tearing open!")
+ return TRUE