mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 11:13:16 +00:00
GARGOYLES
This commit is contained in:
@@ -79,3 +79,13 @@
|
|||||||
),
|
),
|
||||||
autohiss_exempt = list("Vespinae"))
|
autohiss_exempt = list("Vespinae"))
|
||||||
excludes = list(/datum/trait/neutral/autohiss_tajaran, /datum/trait/neutral/autohiss_unathi)
|
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)
|
||||||
|
|||||||
@@ -8,16 +8,13 @@
|
|||||||
var/mob/living/carbon/human/gargoyle //easy reference
|
var/mob/living/carbon/human/gargoyle //easy reference
|
||||||
var/obj/structure/gargoyle/statue //another easy ref
|
var/obj/structure/gargoyle/statue //another easy ref
|
||||||
|
|
||||||
var/fireloss
|
|
||||||
var/bruteloss
|
|
||||||
var/sleeping
|
|
||||||
var/paralysis
|
|
||||||
var/blinded
|
|
||||||
|
|
||||||
/datum/component/gargoyle/Initialize()
|
/datum/component/gargoyle/Initialize()
|
||||||
if (!ishuman(parent))
|
if (!ishuman(parent))
|
||||||
return COMPONENT_INCOMPATIBLE
|
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)
|
START_PROCESSING(SSprocessing, src)
|
||||||
|
|
||||||
/datum/component/gargoyle/process()
|
/datum/component/gargoyle/process()
|
||||||
@@ -25,36 +22,74 @@
|
|||||||
return
|
return
|
||||||
if (paused && gargoyle.loc != paused_loc)
|
if (paused && gargoyle.loc != paused_loc)
|
||||||
paused = FALSE
|
paused = FALSE
|
||||||
energy -= 20
|
energy = max(energy - 5, 0)
|
||||||
if (energy > 0)
|
if (energy > 0)
|
||||||
if (!transformed && !paused)
|
if (!transformed && !paused)
|
||||||
energy = max(0,energy-0.05)
|
energy = max(0,energy-0.05)
|
||||||
else
|
else if (!transformed && isturf(gargoyle.loc))
|
||||||
paused = 0
|
gargoyle.gargoyle_transformation()
|
||||||
|
|
||||||
if (transformed)
|
if (transformed)
|
||||||
if (!statue)
|
if (!statue)
|
||||||
transformed = FALSE
|
transformed = FALSE
|
||||||
statue.health = min(gargoyle.max_health + 100, statue.health + 0.5)
|
statue.damage(-0.5)
|
||||||
energy = min(energy+0.3, 100)
|
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()
|
/datum/component/gargoyle/proc/unpause()
|
||||||
set name = "Gargoyle Petrification"
|
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 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)
|
if (stat == DEAD)
|
||||||
return
|
return
|
||||||
|
|
||||||
var/datum/component/gargoyle/comp = GetComponent(/datum/component/gargoyle)
|
var/datum/component/gargoyle/comp = GetComponent(/datum/component/gargoyle)
|
||||||
if (comp?.cooldown > world.time)
|
if (comp)
|
||||||
|
if (comp.energy <= 0 && isturf(loc))
|
||||||
|
to_chat(src, "<span class='danger'>You suddenly turn into a statue as you run out of energy!</span>")
|
||||||
|
else if (comp.cooldown > world.time)
|
||||||
var/time_to_wait = (comp.cooldown - world.time) / (1 SECONDS)
|
var/time_to_wait = (comp.cooldown - world.time) / (1 SECONDS)
|
||||||
to_chat(src, "<span class='warning'>You can't activate that ability right now! Wait for another [round(time_to_wait,0.1)] seconds!</span>")
|
to_chat(src, "<span class='warning'>You can't transform just yet again! Wait for another [round(time_to_wait,0.1)] seconds!</span>")
|
||||||
|
return
|
||||||
if (istype(loc, /obj/structure/gargoyle))
|
if (istype(loc, /obj/structure/gargoyle))
|
||||||
var/obj/structure/gargoyle/statue = loc
|
var/obj/structure/gargoyle/statue = loc
|
||||||
statue.unpetrify()
|
qdel(statue)
|
||||||
else if (isturf(loc))
|
else if (isturf(loc))
|
||||||
var/obj/structure/gargoyle/statue = new(loc, src)
|
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, "<span class='notice'>You have [round(comp.energy,0.01)] energy remaining. It is currently [comp.paused ? "stable" : (comp.transformed ? "increasing" : "decreasing")].</span>")
|
||||||
|
|||||||
@@ -6,27 +6,157 @@
|
|||||||
var/mob/living/carbon/human/gargoyle
|
var/mob/living/carbon/human/gargoyle
|
||||||
var/initial_sleep
|
var/initial_sleep
|
||||||
var/initial_blind
|
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
|
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
|
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)
|
if (H.buckled)
|
||||||
H.buckled.unbuckle_mob(H, TRUE)
|
H.buckled.unbuckle_mob(H, TRUE)
|
||||||
H.click_intercept = src
|
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_sleep = H.sleeping
|
||||||
intial_blind = H.eye_blind
|
initial_blind = H.eye_blind
|
||||||
|
initial_is_shifted = H.is_shifted
|
||||||
transform = H.transform
|
transform = H.transform
|
||||||
layer = H.layer
|
layer = H.layer
|
||||||
pixel_x = H.pixel_x
|
pixel_x = H.pixel_x
|
||||||
pixel_y = H.pixel_y
|
pixel_y = H.pixel_y
|
||||||
dir = H.dir
|
dir = H.dir
|
||||||
H.disabilites |= MUTE
|
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("<span class='warning'>[H]'s skin rapidly turns to stone!</span>", "<span class='warning'>Your skin abruptly hardens as you turn to stone!</span>")
|
||||||
H.forceMove(src)
|
H.forceMove(src)
|
||||||
H.setBlinded(0)
|
H.SetBlinded(0)
|
||||||
H.setSleeping(0)
|
H.SetSleeping(0)
|
||||||
H.status_flags |= GODMODE
|
H.status_flags |= GODMODE
|
||||||
H.updatehealth()
|
H.updatehealth()
|
||||||
H.canmove = 0
|
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 = " <b>You feel your body take the damage that was dealt while being stone!</b>"
|
||||||
|
gargoyle.updatehealth()
|
||||||
|
alpha = 0
|
||||||
|
gargoyle.visible_message("<span class='warning'>[gargoyle]'s skin rapidly softens, returning them to normal!</span>", "<span class='warning'>Your skin softens, freeing your movement once more![hurtmessage]</span>")
|
||||||
|
|
||||||
|
/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("<span class='danger'>[user] [attack_message] the [src]!</span>")
|
||||||
|
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, "<span class='warning'>You can't anchor that here!</span>")
|
||||||
|
anchored = FALSE
|
||||||
|
return ..()
|
||||||
|
playsound(src, W.usesound, 50, 1)
|
||||||
|
if (do_after(user, (2 SECONDS) * W.toolspeed, target = src))
|
||||||
|
to_chat("<span class='notice'>You [anchored ? "un" : ""]anchor the [src].</span>")
|
||||||
|
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 ..()
|
||||||
Reference in New Issue
Block a user