mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-03-30 16:43:05 +01:00
* Fixes necrosis steps setting bone Makes it so you the 'cut away' step doesn't set bones to open. This is entirely a non-internal fix (you're working on the flesh, not the organs inside) so you don't need the bone retracted. * Update other.dm * Crowbar Augment * descriptors * Update carbon.dm * no typecasting * removes unused proc * Limb status * Makes butchering take time Gives a warning as well when starting it. * Update organ.dm * Update organ.dm * Closing surgical stages and desc. Opened organs have descriptions that they're opened. Organs inform you that they have SPECIAL MECHANICS THAT'VE BEEN IN FOR 10 YEARS that you can do to them. Allows fixing amputated organs A BUNCH of stuff * Update organ.dm * Keep the washing * Update external_repair.dm * Update other.dm * Organizes surgeries * fix a typo * Update surgery.dm * More surgery * Nerve Surgery Adds template for nerve surgery * Prevents pain from limbs that feel no pain * Update external_repair.dm
309 lines
10 KiB
Plaintext
309 lines
10 KiB
Plaintext
/obj/structure/gargoyle
|
|
name = "statue"
|
|
desc = "A very lifelike carving."
|
|
density = TRUE
|
|
anchored = TRUE
|
|
var/datum/weakref/WR_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
|
|
var/identifier = "statue"
|
|
var/material = "stone"
|
|
var/adjective = "hardens"
|
|
var/list/tail_lower_dirs = list(SOUTH, EAST, WEST)
|
|
var/image/tail_image
|
|
var/tail_layering = TAIL_UPPER_LAYER
|
|
|
|
var/can_revert = TRUE
|
|
var/was_rayed = FALSE
|
|
|
|
/obj/structure/gargoyle/Initialize(mapload, var/mob/living/carbon/human/H, var/ident_ovr, var/mat_ovr, var/adj_ovr, var/tint_ovr, var/revert = TRUE, var/discard_clothes)
|
|
. = ..()
|
|
if(isspace(loc) || isopenspace(loc))
|
|
anchored = FALSE
|
|
if(!istype(H) || !isturf(H.loc))
|
|
return
|
|
var/datum/component/gargoyle/comp = H.GetComponent(/datum/component/gargoyle)
|
|
var/tint = "#FFFFFF"
|
|
if(comp)
|
|
comp.cooldown = world.time + (15 SECONDS)
|
|
comp.statue = src
|
|
comp.transformed = TRUE
|
|
comp.paused = FALSE
|
|
identifier = length(comp.identifier) > 0 ? comp.identifier : initial(identifier)
|
|
material = length(comp.material) > 0 ? comp.material : initial(material)
|
|
tint = length(comp.tint) > 0 ? comp.tint : initial(comp.tint)
|
|
adjective = length(comp.adjective) > 0 ? comp.adjective : initial(adjective)
|
|
if(copytext_char(adjective, -1) != "s")
|
|
adjective += "s"
|
|
WR_gargoyle = WEAKREF(H)
|
|
|
|
if(H.get_effective_size(TRUE) < 0.5) // "So small! I can step over it!"
|
|
density = FALSE
|
|
|
|
if(ident_ovr)
|
|
identifier = ident_ovr
|
|
if(mat_ovr)
|
|
material = mat_ovr
|
|
if(adj_ovr)
|
|
adjective = adj_ovr
|
|
if(tint_ovr)
|
|
tint = tint_ovr
|
|
|
|
if(H.tail_style?.clip_mask_state)
|
|
tail_lower_dirs.Cut()
|
|
else if(H.tail_style)
|
|
tail_lower_dirs = H.tail_style.lower_layer_dirs.Copy()
|
|
tail_layering = H.tail_layering ? TAIL_UPPER_LAYER_HIGH : TAIL_UPPER_LAYER
|
|
|
|
max_integrity = H.getMaxHealth() + 100
|
|
obj_integrity = H.health + 100
|
|
original_int = obj_integrity
|
|
name = "[identifier] of [H.name]"
|
|
desc = "A very lifelike [identifier] made of [material]."
|
|
stored_examine = H.examine(H)
|
|
description_fluff = H.get_description_fluff()
|
|
|
|
if(H.buckled)
|
|
H.buckled.unbuckle_mob(H, TRUE)
|
|
//icon = H.icon
|
|
//copy_overlays(H)
|
|
|
|
//calculate our tints
|
|
var/list/RGB = rgb2num(tint)
|
|
|
|
var/colorr = rgb(RGB[1]*0.299, RGB[2]*0.299, RGB[3]*0.299)
|
|
var/colorg = rgb(RGB[1]*0.587, RGB[2]*0.587, RGB[3]*0.587)
|
|
var/colorb = rgb(RGB[1]*0.114, RGB[2]*0.114, RGB[3]*0.114)
|
|
|
|
var/tint_color = list(colorr, colorg, colorb, "#000000")
|
|
|
|
var/list/body_layers = HUMAN_BODY_LAYERS
|
|
var/list/other_layers = HUMAN_OTHER_LAYERS
|
|
for (var/i = 1; i <= length(H.overlays_standing); i++)
|
|
if(i in other_layers)
|
|
continue
|
|
if(discard_clothes && !(i in body_layers))
|
|
continue
|
|
if(istype(H.overlays_standing[i], /image) && (i in body_layers))
|
|
var/image/old_image = H.overlays_standing[i]
|
|
var/image/new_image = image(old_image)
|
|
if(i == TAIL_LOWER_LAYER || i == TAIL_UPPER_LAYER || i == TAIL_UPPER_LAYER_HIGH)
|
|
tail_image = new_image
|
|
new_image.color = tint_color
|
|
new_image.layer = old_image.layer
|
|
add_overlay(new_image)
|
|
else
|
|
if(!isnull(H.overlays_standing[i]))
|
|
add_overlay(H.overlays_standing[i])
|
|
|
|
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
|
|
flapping = H.flapping
|
|
H.toggle_tail(FALSE, FALSE)
|
|
H.toggle_wing(FALSE, FALSE)
|
|
H.visible_message(span_warning("[H]'s skin rapidly [adjective] as they turn to [material]!"), span_warning("Your skin abruptly [adjective] as you turn to [material]!"))
|
|
H.forceMove(src)
|
|
H.SetBlinded(0)
|
|
H.SetSleeping(0)
|
|
H.updatehealth()
|
|
H.canmove = 0
|
|
|
|
can_revert = revert
|
|
|
|
START_PROCESSING(SSprocessing, src)
|
|
|
|
/obj/structure/gargoyle/Destroy()
|
|
STOP_PROCESSING(SSprocessing, src)
|
|
var/mob/living/carbon/human/gargoyle = WR_gargoyle.resolve()
|
|
if(!gargoyle)
|
|
return ..()
|
|
if(can_revert)
|
|
unpetrify(deleting = FALSE) //don't delete if we're already deleting!
|
|
else
|
|
visible_message(span_warning("The [identifier] loses shape and crumbles into a pile of [material]!"))
|
|
WR_gargoyle = null
|
|
. = ..()
|
|
|
|
/obj/structure/gargoyle/process()
|
|
var/mob/living/carbon/human/gargoyle = WR_gargoyle.resolve()
|
|
if(!gargoyle)
|
|
qdel(src)
|
|
return
|
|
if(gargoyle.stat == DEAD) //died while in statue state.
|
|
unpetrify(deal_damage = TRUE, deleting = TRUE)
|
|
return
|
|
if(gargoyle.loc != src)
|
|
can_revert = TRUE //something's gone wrong, they escaped, lets not qdel them
|
|
unpetrify(deal_damage = FALSE, deleting = TRUE)
|
|
|
|
/obj/structure/gargoyle/fire_act(datum/gas_mixture/air, temperature, volume)
|
|
if(temperature > T0C + 1600) //Bingle says the burning point of rock is between 600 to 1600C...Let's use the highest range.
|
|
damage(temperature/(T0C + 1600)) //1 damage per 1600C
|
|
return
|
|
|
|
/obj/structure/gargoyle/examine_icon()
|
|
var/icon/examine_icon = icon(icon=src.icon, icon_state=src.icon_state, dir=SOUTH, frame=1, moving=0)
|
|
examine_icon.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
|
|
return examine_icon
|
|
|
|
/obj/structure/gargoyle/get_description_info(list/additional_information)
|
|
var/mob/living/carbon/human/gargoyle = WR_gargoyle.resolve()
|
|
if(gargoyle)
|
|
if(isspace(loc) || isopenspace(loc))
|
|
return
|
|
return "It can be [anchored ? "un" : ""]anchored with a wrench."
|
|
|
|
/obj/structure/gargoyle/examine(mob/user)
|
|
. = ..()
|
|
var/mob/living/carbon/human/gargoyle = WR_gargoyle.resolve()
|
|
if(gargoyle && stored_examine)
|
|
. += "The [identifier] seems to have a bit more to them..."
|
|
. += stored_examine
|
|
return
|
|
|
|
/obj/structure/gargoyle/proc/unpetrify(var/deal_damage = TRUE, var/deleting = FALSE)
|
|
var/mob/living/carbon/human/gargoyle = WR_gargoyle.resolve()
|
|
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
|
|
else
|
|
if(was_rayed)
|
|
remove_verb(gargoyle,/mob/living/carbon/human/proc/gargoyle_transformation)
|
|
if(gargoyle.loc == src)
|
|
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.SetBlinded(initial_blind)
|
|
gargoyle.SetSleeping(initial_sleep)
|
|
gargoyle.canmove = 1
|
|
gargoyle.update_canmove()
|
|
var/hurtmessage = ""
|
|
if(deal_damage)
|
|
if(obj_integrity < original_int)
|
|
var/f = (original_int - obj_integrity) / 10
|
|
for (var/x in 1 to 10)
|
|
gargoyle.adjustBruteLoss(f)
|
|
hurtmessage = " " + span_bold("You feel your body take the damage that was dealt while being [material]!")
|
|
gargoyle.updatehealth()
|
|
alpha = 0
|
|
gargoyle.visible_message(span_warning("[gargoyle]'s skin rapidly reverts, returning them to normal!"), span_warning("Your skin reverts, freeing your movement once more![hurtmessage]"))
|
|
gargoyle = null
|
|
if(deleting)
|
|
qdel(src)
|
|
|
|
/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)
|
|
if(was_rayed)
|
|
return //gargoyle quick regenerates, the others don't, so let's not have them getting too damaged
|
|
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_danger("[user] [attack_message] the [src]!"))
|
|
damage(damage)
|
|
|
|
/obj/structure/gargoyle/attackby(var/obj/item/W as obj, var/mob/living/user as mob)
|
|
var/mob/living/carbon/human/gargoyle = WR_gargoyle.resolve()
|
|
if(W.is_wrench())
|
|
if(isspace(loc) || isopenspace(loc))
|
|
to_chat(user, span_warning("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(user, span_notice("You [anchored ? "un" : ""]anchor the [src]."))
|
|
anchored = !anchored
|
|
else if(!isrobot(user) && gargoyle && gargoyle.vore_selected && gargoyle.trash_catching)
|
|
if(istype(W,/obj/item/grab || /obj/item/holder))
|
|
gargoyle.vore_attackby(W, user)
|
|
return
|
|
if(gargoyle.adminbus_trash || is_type_in_list(W, GLOB.edible_trash) && W.trash_eatable && !is_type_in_list(W, GLOB.item_vore_blacklist))
|
|
to_chat(user, span_warning("You slip [W] into [gargoyle]'s [lowertext(gargoyle.vore_selected.name)] ."))
|
|
user.drop_item()
|
|
gargoyle.vore_selected.nom_atom(W)
|
|
return
|
|
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 ..()
|
|
|
|
/obj/structure/gargoyle/set_dir(var/new_dir)
|
|
. = ..()
|
|
if(. && tail_image)
|
|
cut_overlay(tail_image)
|
|
tail_image.layer = BODY_LAYER + ((dir in tail_lower_dirs) ? TAIL_LOWER_LAYER : tail_layering)
|
|
add_overlay(tail_image)
|
|
|
|
/obj/structure/gargoyle/hitby(atom/movable/source, datum/thrownthing/throwingdatum)
|
|
var/mob/living/carbon/human/gargoyle = WR_gargoyle.resolve()
|
|
if(!gargoyle)
|
|
return
|
|
if(isitem(source) && gargoyle.vore_selected && gargoyle.trash_catching)
|
|
var/obj/item/I = source
|
|
if(gargoyle.adminbus_trash || is_type_in_list(I, GLOB.edible_trash) && I.trash_eatable && !is_type_in_list(I, GLOB.item_vore_blacklist))
|
|
gargoyle.hitby(source, throwingdatum)
|
|
return
|
|
else if(isliving(source))
|
|
var/mob/living/L = source
|
|
if(can_throw_vore(gargoyle, L))
|
|
var/drop_prey_temp = FALSE
|
|
if(gargoyle.can_be_drop_prey)
|
|
drop_prey_temp = TRUE
|
|
gargoyle.can_be_drop_prey = FALSE //Making sure the original gargoyle body is not the one getting throwvored instead.
|
|
gargoyle.hitby(L, throwingdatum)
|
|
if(drop_prey_temp)
|
|
gargoyle.can_be_drop_prey = TRUE
|
|
return
|
|
return ..()
|