diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral_ch.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral_ch.dm
index 422fc6f621..05ee8802fa 100644
--- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral_ch.dm
+++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral_ch.dm
@@ -79,3 +79,13 @@
),
autohiss_exempt = list("Vespinae"))
excludes = list(/datum/trait/neutral/autohiss_tajaran, /datum/trait/neutral/autohiss_unathi)
+
+/datum/trait/neutral/gargoyle
+ name = "Gargoyle"
+ desc = "You turn into a statue at will, but also whenever you run out of energy. Being a statue replenishes your energy slowly."
+ cost = 0
+ custom_only = FALSE //should this be custom only??
+
+/datum/trait/neutral/gargoyle/apply(var/datum/species/S,var/mob/living/carbon/human/H)
+ ..(S,H)
+ H.LoadComponent(/datum/component/gargoyle)
diff --git a/modular_chomp/code/datums/components/gargoyle.dm b/modular_chomp/code/datums/components/gargoyle.dm
index b8b5f73c3e..e19737b339 100644
--- a/modular_chomp/code/datums/components/gargoyle.dm
+++ b/modular_chomp/code/datums/components/gargoyle.dm
@@ -8,16 +8,13 @@
var/mob/living/carbon/human/gargoyle //easy reference
var/obj/structure/gargoyle/statue //another easy ref
- var/fireloss
- var/bruteloss
- var/sleeping
- var/paralysis
- var/blinded
-
/datum/component/gargoyle/Initialize()
if (!ishuman(parent))
return COMPONENT_INCOMPATIBLE
- var/mob/living/carbon/human/gargoyle = parent
+ gargoyle = parent
+ gargoyle.verbs += /mob/living/carbon/human/proc/gargoyle_transformation
+ gargoyle.verbs += /mob/living/carbon/human/proc/gargoyle_pause
+ gargoyle.verbs += /mob/living/carbon/human/proc/gargoyle_checkenergy
START_PROCESSING(SSprocessing, src)
/datum/component/gargoyle/process()
@@ -25,36 +22,74 @@
return
if (paused && gargoyle.loc != paused_loc)
paused = FALSE
- energy -= 20
+ energy = max(energy - 5, 0)
if (energy > 0)
if (!transformed && !paused)
energy = max(0,energy-0.05)
- else
- paused = 0
-
+ else if (!transformed && isturf(gargoyle.loc))
+ gargoyle.gargoyle_transformation()
if (transformed)
if (!statue)
transformed = FALSE
- statue.health = min(gargoyle.max_health + 100, statue.health + 0.5)
+ statue.damage(-0.5)
energy = min(energy+0.3, 100)
- fireloss = max(fireloss - 0.5, 0)
- bruteloss = max(bruteloss - 0.5, 0)
-/mob/living/carbon/human/verb/gargoyle_transformation()
- set name = "Gargoyle Petrification"
+/datum/component/gargoyle/proc/unpause()
+ if (!paused || transformed)
+ paused = FALSE
+ paused_loc = null
+ UnregisterSignal(gargoyle, COMSIG_ATOM_ENTERING)
+ return
+ if (gargoyle?.loc != paused_loc)
+ paused = FALSE
+ paused_loc = null
+ energy = max(energy - 5, 0)
+ if (energy == 0)
+ gargoyle.gargoyle_transformation()
+ UnregisterSignal(gargoyle, COMSIG_ATOM_ENTERING)
+
+//verbs or action buttons...?
+/mob/living/carbon/human/proc/gargoyle_transformation()
+ set name = "Gargoyle - Petrification"
set category = "Abilities"
- set desc = "Turn yourself into (or out of) being a gargoyle."
+ set desc = "Turn yourself into (or back from) being a gargoyle."
if (stat == DEAD)
return
var/datum/component/gargoyle/comp = GetComponent(/datum/component/gargoyle)
- if (comp?.cooldown > world.time)
- var/time_to_wait = (comp.cooldown - world.time) / (1 SECONDS)
- to_chat(src, "You can't activate that ability right now! Wait for another [round(time_to_wait,0.1)] seconds!")
-
+ if (comp)
+ if (comp.energy <= 0 && isturf(loc))
+ to_chat(src, "You suddenly turn into a statue as you run out of energy!")
+ else if (comp.cooldown > world.time)
+ var/time_to_wait = (comp.cooldown - world.time) / (1 SECONDS)
+ to_chat(src, "You can't transform just yet again! Wait for another [round(time_to_wait,0.1)] seconds!")
+ return
if (istype(loc, /obj/structure/gargoyle))
var/obj/structure/gargoyle/statue = loc
- statue.unpetrify()
+ qdel(statue)
else if (isturf(loc))
- var/obj/structure/gargoyle/statue = new(loc, src)
\ No newline at end of file
+ new /obj/structure/gargoyle(loc, src)
+
+/mob/living/carbon/human/proc/gargoyle_pause()
+ set name = "Gargoyle - Pause"
+ set category = "Abilities"
+ set desc = "Pause your energy while standing still, so you don't use up any more, though you will lose a small amount upon moving again."
+
+ if (stat)
+ return
+
+ var/datum/component/gargoyle/comp = GetComponent(/datum/component/gargoyle)
+ if (comp && !comp.transformed)
+ comp.paused = TRUE
+ comp.paused_loc = loc
+ comp.RegisterSignal(src, COMSIG_ATOM_ENTERING, /datum/component/gargoyle/proc/unpause)
+
+/mob/living/carbon/human/proc/gargoyle_checkenergy()
+ set name = "Gargoyle - Check Energy"
+ set category = "Abilities"
+ set desc = "Check how much energy you have remaining as a gargoyle."
+
+ var/datum/component/gargoyle/comp = GetComponent(/datum/component/gargoyle)
+ if (comp)
+ to_chat(src, "You have [round(comp.energy,0.01)] energy remaining. It is currently [comp.paused ? "stable" : (comp.transformed ? "increasing" : "decreasing")].")
diff --git a/modular_chomp/code/game/objects/structures/gargoyle.dm b/modular_chomp/code/game/objects/structures/gargoyle.dm
index 9e5290f1bc..1379749d42 100644
--- a/modular_chomp/code/game/objects/structures/gargoyle.dm
+++ b/modular_chomp/code/game/objects/structures/gargoyle.dm
@@ -6,27 +6,157 @@
var/mob/living/carbon/human/gargoyle
var/initial_sleep
var/initial_blind
+ var/initial_is_shifted
+ var/initial_lying
+ var/initial_lying_prev
+ var/wagging
+ var/flapping
+ var/obj_integrity = 100
+ var/original_int = 100
+ var/max_integrity = 100
+ var/stored_examine
-/obj/structure/gargoyle/Initialize(var/location, var/mob/living/carbon/human/H)
+/obj/structure/gargoyle/Initialize(mapload, var/mob/living/carbon/human/H)
. = ..()
- if (!location || !istype(H))
+ if (isspace(loc) || isopenspace(loc))
+ anchored = FALSE
+ if (!istype(H) || !isturf(H.loc))
return
+ var/datum/component/gargoyle/comp = H.GetComponent(/datum/component/gargoyle)
+ if (comp)
+ comp.cooldown = world.time + (15 SECONDS)
+ comp.statue = src
+ comp.transformed = TRUE
+ comp.paused = FALSE
gargoyle = H
+
+ max_integrity = H.getMaxHealth() + 100
+ obj_integrity = H.health + 100
+ original_int = obj_integrity
+ name = "statue of [H.name]"
+ desc = "A very lifelike statue of [H.name]."
+ stored_examine = H.examine()
+ description_fluff = H.get_description_fluff()
+
if (H.buckled)
H.buckled.unbuckle_mob(H, TRUE)
- H.click_intercept = src
- initial_sleep = H.sleeping
- intial_blind = H.eye_blind
- transform = H.transform
- layer = H.layer
- pixel_x = H.pixel_x
- pixel_y = H.pixel_y
- dir = H.dir
- H.disabilites |= MUTE
- H.forceMove(src)
- H.setBlinded(0)
- H.setSleeping(0)
- H.status_flags |= GODMODE
- H.updatehealth()
- H.canmove = 0
+ icon = H.icon
+ copy_overlays(H)
+ color = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
+ initial_sleep = H.sleeping
+ initial_blind = H.eye_blind
+ initial_is_shifted = H.is_shifted
+ transform = H.transform
+ layer = H.layer
+ pixel_x = H.pixel_x
+ pixel_y = H.pixel_y
+ dir = H.dir
+ initial_lying = H.lying
+ initial_lying_prev = H.lying_prev
+ H.sdisabilities |= MUTE
+ if (H.appearance_flags & PIXEL_SCALE)
+ appearance_flags |= PIXEL_SCALE
+ wagging = H.wagging
+ H.transforming = TRUE
+ flapping = H.flapping
+ H.toggle_tail(FALSE, FALSE)
+ H.toggle_wing(FALSE, FALSE)
+ H.visible_message("[H]'s skin rapidly turns to stone!", "Your skin abruptly hardens as you turn to stone!")
+ H.forceMove(src)
+ H.SetBlinded(0)
+ H.SetSleeping(0)
+ H.status_flags |= GODMODE
+ H.updatehealth()
+ H.canmove = 0
+/obj/structure/gargoyle/Destroy()
+ unpetrify()
+ . = ..()
+
+/obj/structure/gargoyle/get_description_info()
+ if (gargoyle)
+ if (isspace(loc) || isopenspace(loc))
+ return
+ return "It can be [anchored ? "un" : ""]anchored with a wrench."
+
+/obj/structure/gargoyle/examine(mob/user)
+ if (gargoyle && stored_examine)
+ return stored_examine
+ return ..()
+
+/obj/structure/gargoyle/proc/unpetrify()
+ if (!gargoyle)
+ return
+ var/datum/component/gargoyle/comp = gargoyle.GetComponent(/datum/component/gargoyle)
+ if (comp)
+ comp.cooldown = world.time + (15 SECONDS)
+ comp.statue = null
+ comp.transformed = FALSE
+ gargoyle.forceMove(loc)
+ gargoyle.transform = transform
+ gargoyle.pixel_x = pixel_x
+ gargoyle.pixel_y = pixel_y
+ gargoyle.is_shifted = initial_is_shifted
+ gargoyle.dir = dir
+ gargoyle.lying = initial_lying
+ gargoyle.lying_prev = initial_lying_prev
+ gargoyle.toggle_tail(wagging, FALSE)
+ gargoyle.toggle_wing(flapping, FALSE)
+ gargoyle.sdisabilities &= ~MUTE //why is there no ADD_TRAIT etc here that's actually ussssed
+ gargoyle.status_flags &= ~GODMODE
+ gargoyle.SetBlinded(initial_blind)
+ gargoyle.SetSleeping(initial_sleep)
+ gargoyle.transforming = FALSE
+ gargoyle.canmove = 1
+ gargoyle.update_canmove()
+ var/hurtmessage = ""
+ if (obj_integrity < original_int)
+ var/f = (original_int - obj_integrity) / 10
+ for (var/x in 1 to 10)
+ gargoyle.adjustBruteLoss(f)
+ hurtmessage = " You feel your body take the damage that was dealt while being stone!"
+ gargoyle.updatehealth()
+ alpha = 0
+ gargoyle.visible_message("[gargoyle]'s skin rapidly softens, returning them to normal!", "Your skin softens, freeing your movement once more![hurtmessage]")
+
+/obj/structure/gargoyle/return_air()
+ return return_air_for_internal_lifeform()
+
+/obj/structure/gargoyle/return_air_for_internal_lifeform(var/mob/living/lifeform)
+ var/air_type = /datum/gas_mixture/belly_air
+ if(istype(lifeform))
+ air_type = lifeform.get_perfect_belly_air_type()
+ var/air = new air_type(1000)
+ return air
+
+/obj/structure/gargoyle/proc/damage(var/damage)
+ obj_integrity = min(obj_integrity-damage, max_integrity)
+ if(obj_integrity <= 0)
+ qdel(src)
+
+/obj/structure/gargoyle/take_damage(var/damage)
+ damage(damage)
+
+/obj/structure/gargoyle/attack_generic(var/mob/user, var/damage, var/attack_message = "hits")
+ user.do_attack_animation(src)
+ visible_message("[user] [attack_message] the [src]!")
+ damage(damage)
+
+/obj/structure/gargoyle/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
+ if(W.is_wrench())
+ if (isspace(loc) || isopenspace(loc))
+ to_chat(user, "You can't anchor that here!")
+ anchored = FALSE
+ return ..()
+ playsound(src, W.usesound, 50, 1)
+ if (do_after(user, (2 SECONDS) * W.toolspeed, target = src))
+ to_chat("You [anchored ? "un" : ""]anchor the [src].")
+ anchored = !anchored
+ else if (!(W.flags & NOBLUDGEON))
+ user.setClickCooldown(user.get_attack_speed(W))
+ if(W.damtype == BRUTE || W.damtype == BURN)
+ user.do_attack_animation(src)
+ playsound(src, W.hitsound, 50, 1)
+ damage(W.force)
+ else
+ return ..()
\ No newline at end of file