From 7115eca62e340586f171cef9766e1edb13059114 Mon Sep 17 00:00:00 2001
From: Luc <89928798+lewcc@users.noreply.github.com>
Date: Thu, 22 Jun 2023 12:53:23 -0700
Subject: [PATCH] Allows for the gravity generator to be cmagged. (#20944)
* Add gravgen cmag interaction
* Bump cmag cooldown
* Add some checks for power state
* Sean review
---
code/datums/elements/waddling.dm | 3 ++
code/game/area/areas.dm | 35 ++++++++++++++++++++++
code/modules/power/gravitygenerator.dm | 40 ++++++++++++++++++++++++++
3 files changed, 78 insertions(+)
diff --git a/code/datums/elements/waddling.dm b/code/datums/elements/waddling.dm
index 1f019dbee9e..ce6279801b9 100644
--- a/code/datums/elements/waddling.dm
+++ b/code/datums/elements/waddling.dm
@@ -23,3 +23,6 @@
var/prev_trans = matrix(target.transform)
animate(pixel_z = 0, transform = turn(target.transform, pick(-12, 0, 12)), time = 2)
animate(pixel_z = 0, transform = prev_trans, time = 0)
+
+/datum/element/waddling/clown_gravity
+ // alternate element so we don't go removing the existing one.
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index fe309999a47..74aac80d7c5 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -32,6 +32,8 @@
var/list/apc = list()
var/has_gravity = TRUE
+ /// If TRUE, everyone will waddle when entering the area (and slip if they enter from an area with it being FALSE)
+ var/has_cmagged_gravity = FALSE
var/no_air = null
@@ -440,6 +442,12 @@
if((oldarea.has_gravity == 0) && (newarea.has_gravity == 1) && (L.m_intent == MOVE_INTENT_RUN)) // Being ready when you change areas gives you a chance to avoid falling all together.
thunk(L)
+ if(oldarea.has_cmagged_gravity && !newarea.has_cmagged_gravity)
+ clown_thunk(L, FALSE)
+
+ else if(!oldarea.has_cmagged_gravity && newarea.has_cmagged_gravity)
+ clown_thunk(L, TRUE)
+
//Ship ambience just loops if turned on.
if(L && L.client && !L.client.ambience_playing && (L.client.prefs.sound & SOUND_BUZZ))
L.client.ambience_playing = TRUE
@@ -447,6 +455,33 @@
else if(L && L.client && !(L.client.prefs.sound & SOUND_BUZZ))
L.client.ambience_playing = FALSE
+/area/proc/cmag_grav_change(cmag_gravity = FALSE, area/A)
+ var/existing_grav = A.has_cmagged_gravity
+ A.has_cmagged_gravity = cmag_gravity
+
+ for(var/mob/living/M in A)
+ if(cmag_gravity != existing_grav)
+ clown_thunk(M, cmag_gravity)
+
+
+/area/proc/clown_thunk(mob/living/M, clown_gravity_enabled)
+ if(!istype(M))
+ return
+
+ if(iscarbon(M))
+ if(!IS_HORIZONTAL(M))
+ playsound(M, 'sound/misc/slip.ogg', 50, FALSE)
+ M.KnockDown(5 SECONDS)
+ else
+ M.Weaken(5 SECONDS) // sure
+
+ if(clown_gravity_enabled)
+ to_chat(M, "Gravity...?")
+ M.AddElement(/datum/element/waddling/clown_gravity)
+ else
+ to_chat(M, "You feel a bit more steady on your feet.")
+ M.RemoveElement(/datum/element/waddling/clown_gravity)
+
/area/proc/gravitychange(gravitystate = 0, area/A)
A.has_gravity = gravitystate
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index 255636917e8..b3628874956 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -91,9 +91,13 @@ GLOBAL_LIST_EMPTY(gravity_generators)
var/current_overlay = null
var/construction_state = GRAV_NEEDS_WELDING
var/overlay_state = "activated"
+ /// The last time we were cmagged, so we don't see this spammed.
+ var/on_cmag_cooldown = FALSE
/obj/machinery/gravity_generator/main/examine(mob/user)
. = ..()
+ if(HAS_TRAIT(src, TRAIT_CMAGGED))
+ . += "Yellow ooze seems to be coming out of the control panel..."
if(!(stat & BROKEN))
return
@@ -117,6 +121,7 @@ GLOBAL_LIST_EMPTY(gravity_generators)
if(!is_station_level(A.z))
continue
A.gravitychange(FALSE, A)
+ A.cmag_grav_change(FALSE, A)
shake_everyone()
return ..()
@@ -293,6 +298,7 @@ GLOBAL_LIST_EMPTY(gravity_generators)
if(!is_station_level(A.z))
continue
A.gravitychange(TRUE, A)
+ A.cmag_grav_change(TRUE, A)
else if(generators_in_level() == TRUE) // Turned off, and there is gravity
alert = TRUE
@@ -302,12 +308,46 @@ GLOBAL_LIST_EMPTY(gravity_generators)
if(!is_station_level(A.z))
continue
A.gravitychange(FALSE, A)
+ A.cmag_grav_change(FALSE, A)
update_icon()
update_gen_list()
if(alert)
shake_everyone()
+/obj/machinery/gravity_generator/main/cmag_act(mob/user)
+ if(HAS_TRAIT(src, TRAIT_CMAGGED))
+ return
+ if(on_cmag_cooldown)
+ to_chat(user, "[src] still smells faintly of burned banana, you should probably wait a bit.")
+ return
+ to_chat(user, "You slap the card around [src], and its gravity draws some ooze off of the card and into its core! Looks like it'll take effect shortly.")
+ playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
+ ADD_TRAIT(src, TRAIT_CMAGGED, CLOWN_EMAG)
+ add_attack_logs(user, src, "cmagged, making everyone flippery.")
+
+ addtimer(CALLBACK(src, PROC_REF(do_cmagging), user), 10 SECONDS)
+
+/obj/machinery/gravity_generator/main/proc/do_cmagging(mob/user)
+ // give the perp a moment to get away, even though it will be incredibly obvious who did it.
+ if(on)
+ // if it was already off, then we'll have a fun surprise when it wakes up
+ for(var/area/A in world)
+ if(!is_station_level(A.z))
+ continue
+ A.cmag_grav_change(TRUE, A)
+ shake_everyone()
+ add_fingerprint(user)
+ on_cmag_cooldown = TRUE
+ addtimer(VARSET_CALLBACK(src, on_cmag_cooldown, FALSE), 5 MINUTES)
+
+/obj/machinery/gravity_generator/main/uncmag()
+ for(var/area/A in world)
+ if(!is_station_level(A.z))
+ continue
+ A.cmag_grav_change(FALSE, A)
+ shake_everyone()
+
// Charge/Discharge and turn on/off gravity when you reach 0/100 percent.
// Also emit radiation and handle the overlays.
/obj/machinery/gravity_generator/main/process()