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()