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