Revert "12/21 modernizations from TG live"

This commit is contained in:
LetterJay
2016-12-22 22:35:44 -06:00
committed by GitHub
parent cf59ac1c3d
commit ae40d4134e
2215 changed files with 86928 additions and 707332 deletions
+4 -5
View File
@@ -2,10 +2,8 @@
/datum/surgery/amputation
name = "amputation"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/sever_limb)
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
species = list(/mob/living/carbon/human)
possible_locs = list("r_arm", "l_arm", "l_leg", "r_leg", "head")
requires_organic_bodypart = 0
/datum/surgery_step/sever_limb
name = "sever limb"
@@ -18,6 +16,7 @@
/datum/surgery_step/sever_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/mob/living/carbon/human/L = target
user.visible_message("[user] severs [L]'s [parse_zone(target_zone)]!", "<span class='notice'>You sever [L]'s [parse_zone(target_zone)].</span>")
if(surgery.operated_bodypart)
surgery.operated_bodypart.drop_limb()
var/obj/item/bodypart/BP = L.get_bodypart(target_zone)
if(BP)
BP.drop_limb()
return 1
+74 -268
View File
@@ -4,22 +4,17 @@
desc = "why is it detached..."
force = 3
throwforce = 3
icon = 'icons/mob/human_parts.dmi'
icon_state = ""
layer = BELOW_MOB_LAYER //so it isn't hidden behind objects when on the floor
var/mob/living/carbon/owner = null
var/mob/living/carbon/original_owner = null
var/status = BODYPART_ORGANIC
var/mob/living/carbon/human/owner = null
var/status = ORGAN_ORGANIC
var/body_zone //"chest", "l_arm", etc , used for def_zone
var/body_part = null //bitflag used to check which clothes cover this bodypart
var/use_digitigrade = NOT_DIGITIGRADE //Used for alternate legs, useless elsewhere
var/brutestate = 0
var/burnstate = 0
var/brute_dam = 0
var/burn_dam = 0
var/max_damage = 0
var/list/embedded_objects = list()
var/held_index = 0 //are we a hand? if so, which one!
//Coloring and proper item icon update
var/skin_tone = ""
@@ -31,14 +26,10 @@
var/mutation_color = ""
var/no_update = 0
var/animal_origin = null //for nonhuman bodypart (e.g. monkey)
var/dismemberable = 1 //whether it can be dismembered with a weapon.
var/px_x = 0
var/px_y = 0
var/species_flags_list = list()
var/dmg_overlay_type //the type of damage overlay (if any) to use when this bodypart is bruised/burned.
var/state_flags
/obj/item/bodypart/examine(mob/user)
..()
@@ -47,8 +38,6 @@
if(burn_dam > 0)
user << "<span class='warning'>This limb has [burn_dam > 30 ? "severe" : "minor"] burns.</span>"
/obj/item/bodypart/blob_act()
take_damage(max_damage)
/obj/item/bodypart/Destroy()
if(owner)
@@ -59,10 +48,10 @@
/obj/item/bodypart/attack(mob/living/carbon/C, mob/user)
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(EASYLIMBATTACHMENT in H.dna.species.species_traits)
if(!H.get_bodypart(body_zone) && !animal_origin)
if(EASYLIMBATTACHMENT in H.dna.species.specflags)
if(!H.get_bodypart(body_zone))
if(H == user)
H.visible_message("<span class='warning'>[H] jams [src] into [H.p_their()] empty socket!</span>",\
H.visible_message("<span class='warning'>[H] jams [src] into \his empty socket!</span>",\
"<span class='notice'>You force [src] into your empty socket, and it locks into place!</span>")
else
H.visible_message("<span class='warning'>[user] jams [src] into [H]'s empty socket!</span>",\
@@ -79,8 +68,8 @@
user << "<span class='warning'>There is nothing left inside [src]!</span>"
return
playsound(loc, 'sound/weapons/slice.ogg', 50, 1, -1)
user.visible_message("<span class='warning'>[user] begins to cut open [src].</span>",\
"<span class='notice'>You begin to cut open [src]...</span>")
user.visible_message("<span class='warning'>[user] begins to cut through the bone in [src].</span>",\
"<span class='notice'>You begin to cut through the bone in [src]...</span>")
if(do_after(user, 54, target = src))
drop_organs(user)
else
@@ -88,30 +77,25 @@
/obj/item/bodypart/throw_impact(atom/hit_atom)
..()
if(status != BODYPART_ROBOTIC)
playsound(get_turf(src), 'sound/misc/splort.ogg', 50, 1, -1)
pixel_x = rand(-3, 3)
pixel_y = rand(-3, 3)
playsound(get_turf(src), 'sound/misc/splort.ogg', 50, 1, -1)
//empties the bodypart from its organs and other things inside it
/obj/item/bodypart/proc/drop_organs(mob/user)
var/turf/T = get_turf(src)
if(status != BODYPART_ROBOTIC)
playsound(T, 'sound/misc/splort.ogg', 50, 1, -1)
playsound(T, 'sound/misc/splort.ogg', 50, 1, -1)
for(var/obj/item/I in src)
I.forceMove(T)
I.loc = T
//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all.
//Damage will not exceed max_damage using this proc
//Cannot apply negative damage
/obj/item/bodypart/proc/receive_damage(brute, burn, updating_health = 1)
/obj/item/bodypart/proc/take_damage(brute, burn)
if(owner && (owner.status_flags & GODMODE))
return 0 //godmode
brute = max(brute * config.damage_multiplier,0)
burn = max(burn * config.damage_multiplier,0)
brute = max(brute,0)
burn = max(burn,0)
if(status == BODYPART_ROBOTIC) //This makes robolimbs not damageable by chems and makes it stronger
if(status == ORGAN_ROBOTIC) //This makes robolimbs not damageable by chems and makes it stronger
brute = max(0, brute - 5)
burn = max(0, burn - 4)
@@ -136,7 +120,7 @@
burn_dam += can_inflict
else
return 0
if(owner && updating_health)
if(owner)
owner.updatehealth()
return update_bodypart_damage_state()
@@ -144,17 +128,17 @@
//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all.
//Damage cannot go below zero.
//Cannot remove negative damage (i.e. apply damage)
/obj/item/bodypart/proc/heal_damage(brute, burn, only_robotic = 0, only_organic = 1, updating_health = 1)
/obj/item/bodypart/proc/heal_damage(brute, burn, robotic)
if(only_robotic && status != BODYPART_ROBOTIC) //This makes organic limbs not heal when the proc is in Robotic mode.
if(robotic && status != ORGAN_ROBOTIC) //This makes organic limbs not heal when the proc is in Robotic mode.
return
if(only_organic && status != BODYPART_ORGANIC) //This makes robolimbs not healable by chems.
if(!robotic && status == ORGAN_ROBOTIC) //This makes robolimbs not healable by chems.
return
brute_dam = max(brute_dam - brute, 0)
burn_dam = max(burn_dam - burn, 0)
if(owner && updating_health)
if(owner)
owner.updatehealth()
return update_bodypart_damage_state()
@@ -167,13 +151,14 @@
//Updates an organ's brute/burn states for use by update_damage_overlays()
//Returns 1 if we need to update overlays. 0 otherwise.
/obj/item/bodypart/proc/update_bodypart_damage_state()
var/tbrute = round( (brute_dam/max_damage)*3, 1 )
var/tburn = round( (burn_dam/max_damage)*3, 1 )
if((tbrute != brutestate) || (tburn != burnstate))
brutestate = tbrute
burnstate = tburn
return 1
return 0
if(status == ORGAN_ORGANIC) //Robotic limbs show no damage - RR
var/tbrute = round( (brute_dam/max_damage)*3, 1 )
var/tburn = round( (burn_dam/max_damage)*3, 1 )
if((tbrute != brutestate) || (tburn != burnstate))
brutestate = tbrute
burnstate = tburn
return 1
return 0
@@ -192,66 +177,47 @@
owner.update_damage_overlays()
//we inform the bodypart of the changes that happened to the owner, or give it the informations from a source mob.
/obj/item/bodypart/proc/update_limb(dropping_limb, mob/living/carbon/source)
var/mob/living/carbon/C
/obj/item/bodypart/proc/update_limb(dropping_limb, mob/living/carbon/human/source)
var/mob/living/carbon/human/H
if(source)
C = source
if(!original_owner)
original_owner = source
else if(original_owner && owner != original_owner) //Foreign limb
no_update = 1
H = source
else
C = owner
no_update = 0
if(C.disabilities & HUSK)
species_id = "husk" //overrides species_id
dmg_overlay_type = "" //no damage overlay shown when husked
should_draw_gender = FALSE
should_draw_greyscale = FALSE
no_update = 1
if(no_update)
H = owner
if(!istype(H))
return
if(!animal_origin)
var/mob/living/carbon/human/H = C
should_draw_greyscale = FALSE
var/datum/species/S = H.dna.species
species_id = S.limbs_id
if(S.use_skintones)
skin_tone = H.skin_tone
should_draw_greyscale = TRUE
else
skin_tone = ""
body_gender = H.gender
should_draw_gender = S.sexes
if(MUTCOLORS in S.specflags)
if(S.fixed_mut_color)
species_color = S.fixed_mut_color
else
species_color = H.dna.features["mcolor"]
should_draw_greyscale = TRUE
else
species_color = ""
if(H.disabilities & HUSK)
species_id = "husk"
should_draw_gender = FALSE
should_draw_greyscale = FALSE
var/datum/species/S = H.dna.species
species_id = S.limbs_id
species_flags_list = H.dna.species.species_traits
if(S.use_skintones)
skin_tone = H.skin_tone
should_draw_greyscale = TRUE
else
skin_tone = ""
body_gender = H.gender
should_draw_gender = S.sexes
if(MUTCOLORS in S.species_traits)
if(S.fixed_mut_color)
species_color = S.fixed_mut_color
else
species_color = H.dna.features["mcolor"]
should_draw_greyscale = TRUE
else
species_color = ""
if(!dropping_limb && H.dna.check_mutation(HULK))
mutation_color = "00aa00"
else
mutation_color = ""
dmg_overlay_type = S.damage_overlay_type
else if(animal_origin == MONKEY_BODYPART) //currently monkeys are the only non human mob to have damage overlays.
dmg_overlay_type = animal_origin
if(status == BODYPART_ROBOTIC)
dmg_overlay_type = "robotic"
if(!dropping_limb && H.dna.check_mutation(HULK))
mutation_color = "00aa00"
else
mutation_color = ""
if(dropping_limb)
no_update = 1 //when attached, the limb won't be affected by the appearance changes of its mob owner.
@@ -259,54 +225,28 @@
//to update the bodypart's icon when not attached to a mob
/obj/item/bodypart/proc/update_icon_dropped()
cut_overlays()
var/list/standing = get_limb_icon(1)
if(!standing.len)
icon_state = initial(icon_state)//no overlays found, we default back to initial icon.
return
for(var/image/I in standing)
var/image/I = get_limb_icon(1)
if(I)
I.pixel_x = px_x
I.pixel_y = px_y
add_overlay(standing)
add_overlay(I)
//Gives you a proper icon appearance for the dismembered limb
/obj/item/bodypart/proc/get_limb_icon(dropped)
icon_state = "" //to erase the default sprite, we're building the visual aspects of the bodypart through overlays alone.
var/list/standing = list()
var/image_dir
if(dropped)
image_dir = SOUTH
if(dmg_overlay_type)
if(brutestate)
standing += image("icon"='icons/mob/dam_mob.dmi', "icon_state"="[dmg_overlay_type]_[body_zone]_[brutestate]0", "layer"=-DAMAGE_LAYER, "dir"=image_dir)
if(burnstate)
standing += image("icon"='icons/mob/dam_mob.dmi', "icon_state"="[dmg_overlay_type]_[body_zone]_0[burnstate]", "layer"=-DAMAGE_LAYER, "dir"=image_dir)
if(animal_origin)
if(status == BODYPART_ORGANIC)
if(species_id == "husk")
standing += image("icon"='icons/mob/animal_parts.dmi', "icon_state"="[animal_origin]_husk_[body_zone]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir)
else
standing += image("icon"='icons/mob/animal_parts.dmi', "icon_state"="[animal_origin]_[body_zone]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir)
else
standing += image("icon"='icons/mob/augments.dmi', "icon_state"="[animal_origin]_[body_zone]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir)
return standing
var/image/I
var/icon_gender = (body_gender == FEMALE) ? "f" : "m" //gender of the icon, if applicable
if((body_zone != "head" && body_zone != "chest"))
should_draw_gender = FALSE
var/image/I
if(status == BODYPART_ORGANIC)
var/image_dir
if(dropped)
image_dir = SOUTH
if(status == ORGAN_ORGANIC)
if(should_draw_greyscale)
if(should_draw_gender)
I = image("icon"='icons/mob/human_parts_greyscale.dmi', "icon_state"="[species_id]_[body_zone]_[icon_gender]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir)
else if(use_digitigrade)
I = image("icon"='icons/mob/human_parts_greyscale.dmi', "icon_state"="digitigrade_[use_digitigrade]_[body_zone]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir)
else
I = image("icon"='icons/mob/human_parts_greyscale.dmi', "icon_state"="[species_id]_[body_zone]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir)
else
@@ -319,13 +259,11 @@
I = image("icon"='icons/mob/augments.dmi', "icon_state"="[body_zone]_[icon_gender]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir)
else
I = image("icon"='icons/mob/augments.dmi', "icon_state"="[body_zone]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir)
standing += I
return standing
return I
if(!should_draw_greyscale)
standing += I
return standing
return I
//Greyscale Colouring
var/draw_color
@@ -340,20 +278,14 @@
if(draw_color)
I.color = "#[draw_color]"
//End Greyscale Colouring
standing += I
return standing
return I
/obj/item/bodypart/deconstruct(disassembled = TRUE)
drop_organs()
qdel(src)
/obj/item/bodypart/chest
name = "chest"
desc = "It's impolite to stare at a person's chest."
icon_state = "default_human_chest"
max_damage = 200
body_zone = "chest"
body_part = CHEST
@@ -366,111 +298,34 @@
qdel(cavity_item)
return ..()
/obj/item/bodypart/chest/drop_organs(mob/user)
if(cavity_item)
cavity_item.forceMove(user.loc)
cavity_item = null
..()
/obj/item/bodypart/chest/monkey
icon = 'icons/mob/animal_parts.dmi'
icon_state = "default_monkey_chest"
animal_origin = MONKEY_BODYPART
/obj/item/bodypart/chest/alien
icon = 'icons/mob/animal_parts.dmi'
icon_state = "alien_chest_s"
dismemberable = 0
max_damage = 500
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/chest/devil
dismemberable = 0
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/chest/larva
icon = 'icons/mob/animal_parts.dmi'
icon_state = "larva_chest_s"
dismemberable = 0
max_damage = 50
animal_origin = LARVA_BODYPART
/obj/item/bodypart/l_arm
name = "left arm"
desc = "Did you know that the word 'sinister' stems originally from the \
Latin 'sinestra' (left hand), because the left hand was supposed to \
be possessed by the devil? This arm appears to be possessed by no \
one though."
icon_state = "default_human_l_arm"
attack_verb = list("slapped", "punched")
max_damage = 50
body_zone ="l_arm"
body_part = ARM_LEFT
held_index = 1
px_x = -6
px_y = 0
/obj/item/bodypart/l_arm/monkey
icon = 'icons/mob/animal_parts.dmi'
icon_state = "default_monkey_l_arm"
animal_origin = MONKEY_BODYPART
px_x = -5
px_y = -3
/obj/item/bodypart/l_arm/alien
icon = 'icons/mob/animal_parts.dmi'
icon_state = "alien_l_arm_s"
px_x = 0
px_y = 0
dismemberable = 0
max_damage = 100
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/l_arm/devil
dismemberable = 0
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/r_arm
name = "right arm"
desc = "Over 87% of humans are right handed. That figure is much lower \
among humans missing their right arm."
icon_state = "default_human_r_arm"
attack_verb = list("slapped", "punched")
max_damage = 50
body_zone = "r_arm"
body_part = ARM_RIGHT
held_index = 2
px_x = 6
px_y = 0
/obj/item/bodypart/r_arm/monkey
icon = 'icons/mob/animal_parts.dmi'
icon_state = "default_monkey_r_arm"
animal_origin = MONKEY_BODYPART
px_x = 5
px_y = -3
/obj/item/bodypart/r_arm/alien
icon = 'icons/mob/animal_parts.dmi'
icon_state = "alien_r_arm_s"
px_x = 0
px_y = 0
dismemberable = 0
max_damage = 100
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/r_arm/devil
dismemberable = 0
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/l_leg
name = "left leg"
desc = "Some athletes prefer to tie their left shoelaces first for good \
luck. In this instance, it probably would not have helped."
icon_state = "default_human_l_leg"
attack_verb = list("kicked", "stomped")
max_damage = 50
body_zone = "l_leg"
@@ -478,37 +333,12 @@
px_x = -2
px_y = 12
/obj/item/bodypart/l_leg/digitigrade
name = "left digitigrade leg"
use_digitigrade = FULL_DIGITIGRADE
/obj/item/bodypart/l_leg/monkey
icon = 'icons/mob/animal_parts.dmi'
icon_state = "default_monkey_l_leg"
animal_origin = MONKEY_BODYPART
px_y = 4
/obj/item/bodypart/l_leg/alien
icon = 'icons/mob/animal_parts.dmi'
icon_state = "alien_l_leg_s"
px_x = 0
px_y = 0
dismemberable = 0
max_damage = 100
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/l_leg/devil
dismemberable = 0
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/r_leg
name = "right leg"
desc = "You put your right leg in, your right leg out. In, out, in, out, \
shake it all about. And apparently then it detaches.\n\
The hokey pokey has certainly changed a lot since space colonisation."
// alternative spellings of 'pokey' are availible
icon_state = "default_human_r_leg"
attack_verb = list("kicked", "stomped")
max_damage = 50
body_zone = "r_leg"
@@ -516,30 +346,6 @@
px_x = 2
px_y = 12
/obj/item/bodypart/r_leg/digitigrade
name = "right digitigrade leg"
use_digitigrade = FULL_DIGITIGRADE
/obj/item/bodypart/r_leg/monkey
icon = 'icons/mob/animal_parts.dmi'
icon_state = "default_monkey_r_leg"
animal_origin = MONKEY_BODYPART
px_y = 4
/obj/item/bodypart/r_leg/alien
icon = 'icons/mob/animal_parts.dmi'
icon_state = "alien_r_leg_s"
px_x = 0
px_y = 0
dismemberable = 0
max_damage = 100
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/r_leg/devil
dismemberable = 0
max_damage = 5000
animal_origin = DEVIL_BODYPART
/////////////////////////////////////////////////////////////////////////
+138 -145
View File
@@ -1,33 +1,26 @@
/obj/item/bodypart/proc/can_dismember(obj/item/I)
if(dismemberable)
. = (get_damage() >= (max_damage - I.armour_penetration/2))
. = (get_damage() >= (max_damage - I.armour_penetration/2))
//Dismember a limb
/obj/item/bodypart/proc/dismember(dam_type = BRUTE)
if(!owner)
var/mob/living/carbon/human/H = owner
if(!istype(H) || (NODISMEMBER in H.dna.species.specflags)) // species don't allow dismemberment
return 0
var/mob/living/carbon/C = owner
if(!dismemberable)
return 0
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(NODISMEMBER in H.dna.species.species_traits) // species don't allow dismemberment
return 0
var/obj/item/bodypart/affecting = C.get_bodypart("chest")
affecting.receive_damage(Clamp(brute_dam/2, 15, 50), Clamp(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage
C.visible_message("<span class='danger'><B>[C]'s [src.name] has been violently dismembered!</B></span>")
C.emote("scream")
var/obj/item/bodypart/affecting = H.get_bodypart("chest")
affecting.take_damage(Clamp(brute_dam/2, 15, 50), Clamp(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage
H.visible_message("<span class='danger'><B>[H]'s [src.name] has been violently dismembered!</B></span>")
H.emote("scream")
drop_limb()
if(dam_type == BURN)
burn()
return 1
add_mob_blood(C)
var/turf/location = C.loc
add_mob_blood(H)
var/turf/location = H.loc
if(istype(location))
C.add_splatter_floor(location)
H.add_splatter_floor(location)
var/direction = pick(cardinal)
var/t_range = rand(2,max(throw_range/2, 2))
var/turf/target_turf = get_turf(src)
@@ -41,99 +34,88 @@
/obj/item/bodypart/chest/dismember()
if(!owner)
var/mob/living/carbon/human/H = owner
if(!istype(H) || (NODISMEMBER in H.dna.species.specflags)) //human's species don't allow dismemberment
return 0
var/mob/living/carbon/C = owner
if(!dismemberable)
return 0
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(NODISMEMBER in H.dna.species.species_traits) // species don't allow dismemberment
return 0
var/organ_spilled = 0
var/turf/T = get_turf(C)
C.add_splatter_floor(T)
playsound(get_turf(C), 'sound/misc/splort.ogg', 80, 1)
for(var/X in C.internal_organs)
var/turf/T = get_turf(H)
H.add_splatter_floor(T)
playsound(get_turf(owner), 'sound/misc/splort.ogg', 80, 1)
for(var/X in owner.internal_organs)
var/obj/item/organ/O = X
var/org_zone = check_zone(O.zone)
if(org_zone != "chest")
if(O.zone != "chest")
continue
O.Remove(C)
O.forceMove(T)
O.Remove(owner)
O.loc = T
organ_spilled = 1
if(cavity_item)
cavity_item.forceMove(T)
cavity_item.loc = T
cavity_item = null
organ_spilled = 1
if(organ_spilled)
C.visible_message("<span class='danger'><B>[C]'s internal organs spill out onto the floor!</B></span>")
owner.visible_message("<span class='danger'><B>[owner]'s internal organs spill out onto the floor!</B></span>")
return 1
//limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in.
/obj/item/bodypart/proc/drop_limb(special)
if(!owner)
if(!ishuman(owner))
return
var/turf/T = get_turf(owner)
var/mob/living/carbon/C = owner
update_limb(1)
C.bodyparts -= src
if(held_index)
C.unEquip(owner.get_item_for_held_index(held_index), 1)
C.hand_bodyparts[held_index] = null
var/mob/living/carbon/human/H = owner
if(!no_update)
update_limb(1)
H.bodyparts -= src
owner = null
for(var/X in C.surgeries) //if we had an ongoing surgery on that limb, we stop it.
for(var/X in H.surgeries) //if we had an ongoing surgery on that limb, we stop it.
var/datum/surgery/S = X
if(S.operated_bodypart == src)
C.surgeries -= S
if(S.organ == src)
H.surgeries -= S
qdel(S)
break
for(var/obj/item/I in embedded_objects)
embedded_objects -= I
I.loc = src
if(!C.has_embedded_objects())
C.clear_alert("embeddedobject")
if(!H.has_embedded_objects())
H.clear_alert("embeddedobject")
if(!special)
if(C.dna)
for(var/X in C.dna.mutations) //some mutations require having specific limbs to be kept.
var/datum/mutation/human/MT = X
if(MT.limb_req && MT.limb_req == body_zone)
MT.force_lose(C)
for(var/X in H.dna.mutations) //some mutations require having specific limbs to be kept.
var/datum/mutation/human/MT = X
if(MT.limb_req && MT.limb_req == body_zone)
MT.force_lose(H)
for(var/X in C.internal_organs) //internal organs inside the dismembered limb are dropped.
for(var/X in H.internal_organs) //internal organs inside the dismembered limb are dropped.
var/obj/item/organ/O = X
var/org_zone = check_zone(O.zone)
if(org_zone != body_zone)
continue
O.transfer_to_limb(src, C)
O.transfer_to_limb(src, H)
update_icon_dropped()
forceMove(T)
C.update_health_hud() //update the healthdoll
C.update_body()
C.update_hair()
C.update_canmove()
src.loc = T
H.update_health_hud() //update the healthdoll
H.update_body()
H.update_hair()
H.update_canmove()
//when a limb is dropped, the internal organs are removed from the mob and put into the limb
/obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/LB, mob/living/carbon/C)
Remove(C)
/obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/LB, mob/living/carbon/human/H)
Remove(H)
loc = LB
/obj/item/organ/brain/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/C)
if(C.mind && C.mind.changeling)
/obj/item/organ/brain/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/H)
if(H.mind && H.mind.changeling)
LB.brain = new //changeling doesn't lose its real brain organ, we drop a decoy.
LB.brain.loc = LB
else //if not a changeling, we put the brain organ inside the dropped head
Remove(C) //and put the player in control of the brainmob
Remove(H) //and put the player in control of the brainmob
loc = LB
LB.brain = src
LB.brainmob = brainmob
@@ -147,39 +129,43 @@
return
/obj/item/bodypart/r_arm/drop_limb(special)
var/mob/living/carbon/C = owner
var/mob/living/carbon/human/H = owner
..()
if(C && !special)
if(C.handcuffed)
C.handcuffed.loc = C.loc
C.handcuffed.dropped(C)
C.handcuffed = null
C.update_handcuffed()
if(C.hud_used)
var/obj/screen/inventory/hand/R = C.hud_used.hand_slots["[held_index]"]
if(istype(H) && !special)
if(H.handcuffed)
H.handcuffed.loc = H.loc
H.handcuffed.dropped(H)
H.handcuffed = null
H.update_handcuffed()
if(H.hud_used)
var/obj/screen/inventory/R = H.hud_used.inv_slots[slot_r_hand]
if(R)
R.update_icon()
if(C.gloves)
C.unEquip(C.gloves, 1)
C.update_inv_gloves() //to remove the bloody hands overlay
if(H.r_hand)
H.unEquip(H.r_hand, 1)
if(H.gloves)
H.unEquip(H.gloves, 1)
H.update_inv_gloves() //to remove the bloody hands overlay
/obj/item/bodypart/l_arm/drop_limb(special)
var/mob/living/carbon/C = owner
var/mob/living/carbon/human/H = owner
..()
if(C && !special)
if(C.handcuffed)
C.handcuffed.loc = C.loc
C.handcuffed.dropped(C)
C.handcuffed = null
C.update_handcuffed()
if(C.hud_used)
var/obj/screen/inventory/hand/L = C.hud_used.hand_slots["[held_index]"]
if(istype(H) && !special)
if(H.handcuffed)
H.handcuffed.loc = H.loc
H.handcuffed.dropped(H)
H.handcuffed = null
H.update_handcuffed()
if(H.hud_used)
var/obj/screen/inventory/L = H.hud_used.inv_slots[slot_l_hand]
if(L)
L.update_icon()
if(C.gloves)
C.unEquip(C.gloves, 1)
C.update_inv_gloves() //to remove the bloody hands overlay
if(H.l_hand)
H.unEquip(H.l_hand, 1)
if(H.gloves)
H.unEquip(H.gloves, 1)
H.update_inv_gloves() //to remove the bloody hands overlay
/obj/item/bodypart/r_leg/drop_limb(special)
@@ -190,8 +176,10 @@
owner.legcuffed.dropped(owner)
owner.legcuffed = null
owner.update_inv_legcuffed()
if(owner.shoes)
owner.unEquip(owner.shoes, 1)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.shoes)
H.unEquip(H.shoes, 1)
..()
/obj/item/bodypart/l_leg/drop_limb(special) //copypasta
@@ -202,17 +190,21 @@
owner.legcuffed.dropped(owner)
owner.legcuffed = null
owner.update_inv_legcuffed()
if(owner.shoes)
owner.unEquip(owner.shoes, 1)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.shoes)
H.unEquip(H.shoes, 1)
..()
/obj/item/bodypart/head/drop_limb(special)
if(!special)
//Drop all worn head items
for(var/X in list(owner.glasses, owner.ears, owner.wear_mask, owner.head))
var/obj/item/I = X
owner.unEquip(I, 1)
name = "[owner]'s head"
var/mob/living/carbon/human/H = owner
if(istype(H))
if(!special)
//Drop all worn head items
for(var/X in list(H.glasses, H.ears, H.wear_mask, H.head))
var/obj/item/I = X
H.unEquip(I, 1)
name = "[H]'s head"
..()
@@ -221,78 +213,81 @@
//Attach a limb to a human and drop any existing limb of that type.
/obj/item/bodypart/proc/replace_limb(mob/living/carbon/C, special)
if(!istype(C))
/obj/item/bodypart/proc/replace_limb(mob/living/carbon/human/H, special)
if(!istype(H))
return
var/obj/item/bodypart/O = locate(src.type) in C.bodyparts
var/obj/item/bodypart/O = locate(src.type) in H.bodyparts
if(O)
O.drop_limb(1)
attach_limb(C, special)
attach_limb(H, special)
/obj/item/bodypart/head/replace_limb(mob/living/carbon/C, special)
if(!istype(C))
/obj/item/bodypart/head/replace_limb(mob/living/carbon/human/H, special)
if(!istype(H))
return
var/obj/item/bodypart/head/O = locate(src.type) in C.bodyparts
var/obj/item/bodypart/head/O = locate(src.type) in H.bodyparts
if(O)
if(!special)
return
else
O.drop_limb(1)
attach_limb(C, special)
attach_limb(H, special)
/obj/item/bodypart/proc/attach_limb(mob/living/carbon/C, special)
/obj/item/bodypart/proc/attach_limb(mob/living/carbon/human/H, special)
loc = null
owner = C
C.bodyparts += src
if(held_index)
if(held_index > C.hand_bodyparts.len)
C.hand_bodyparts.len = held_index
C.hand_bodyparts[held_index] = src
if(C.hud_used)
var/obj/screen/inventory/hand/hand = C.hud_used.hand_slots["[held_index]"]
if(hand)
hand.update_icon()
C.update_inv_gloves()
owner = H
H.bodyparts += src
if(special) //non conventional limb attachment
for(var/X in C.surgeries) //if we had an ongoing surgery to attach a new limb, we stop it.
for(var/X in H.surgeries) //if we had an ongoing surgery to attach a new limb, we stop it.
var/datum/surgery/S = X
var/surgery_zone = check_zone(S.location)
if(surgery_zone == body_zone)
C.surgeries -= S
H.surgeries -= S
qdel(S)
break
update_bodypart_damage_state()
C.updatehealth()
C.update_body()
C.update_hair()
C.update_damage_overlays()
C.update_canmove()
H.updatehealth()
H.update_body()
H.update_hair()
H.update_damage_overlays()
H.update_canmove()
/obj/item/bodypart/head/attach_limb(mob/living/carbon/C, special)
/obj/item/bodypart/r_arm/attach_limb(mob/living/carbon/human/H, special)
..()
if(H.hud_used)
var/obj/screen/inventory/R = H.hud_used.inv_slots[slot_r_hand]
if(R)
R.update_icon()
/obj/item/bodypart/l_arm/attach_limb(mob/living/carbon/human/H, special)
..()
if(H.hud_used)
var/obj/screen/inventory/L = H.hud_used.inv_slots[slot_l_hand]
if(L)
L.update_icon()
/obj/item/bodypart/head/attach_limb(mob/living/carbon/human/H, special)
//Transfer some head appearance vars over
if(brain)
brainmob.container = null //Reset brainmob head var.
brainmob.loc = brain //Throw mob into brain.
brain.brainmob = brainmob //Set the brain to use the brainmob
brainmob = null //Set head brainmob var to null
brain.Insert(C) //Now insert the brain proper
brain.Insert(H) //Now insert the brain proper
brain = null //No more brain in the head
if(ishuman(C))
var/mob/living/carbon/human/H = C
H.hair_color = hair_color
H.hair_style = hair_style
H.facial_hair_color = facial_hair_color
H.facial_hair_style = facial_hair_style
H.eye_color = eye_color
H.lip_style = lip_style
H.lip_color = lip_color
H.hair_color = hair_color
H.hair_style = hair_style
H.facial_hair_color = facial_hair_color
H.facial_hair_style = facial_hair_style
H.eye_color = eye_color
H.lip_style = lip_style
H.lip_color = lip_color
if(real_name)
C.real_name = real_name
H.real_name = real_name
real_name = ""
name = initial(name)
..()
@@ -302,28 +297,26 @@
/mob/living/proc/regenerate_limbs(noheal, excluded_limbs)
return 0
/mob/living/carbon/regenerate_limbs(noheal, list/excluded_limbs)
/mob/living/carbon/human/regenerate_limbs(noheal, list/excluded_limbs)
var/list/limb_list = list("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg")
if(excluded_limbs)
limb_list -= excluded_limbs
for(var/Z in limb_list)
. += regenerate_limb(Z, noheal)
/mob/living/proc/regenerate_limb(limb_zone, noheal)
return
/mob/living/carbon/regenerate_limb(limb_zone, noheal)
/mob/living/carbon/human/regenerate_limb(limb_zone, noheal)
var/obj/item/bodypart/L
if(get_bodypart(limb_zone))
return 0
L = newBodyPart(limb_zone, 0, 0)
L = newBodyPart(limb_zone, 0, 0, src)
if(L)
if(!noheal)
L.brute_dam = 0
L.burn_dam = 0
L.brutestate = 0
L.burnstate = 0
L.burn_state = 0
L.attach_limb(src, 1)
return 1
+65 -103
View File
@@ -1,18 +1,17 @@
/obj/item/bodypart/head
name = "head"
desc = "Didn't make sense not to live for fun, your brain gets smart but your head gets dumb."
icon = 'icons/mob/human_parts.dmi'
icon_state = "default_human_head"
max_damage = 200
body_zone = "head"
body_part = HEAD
w_class = WEIGHT_CLASS_BULKY //Quite a hefty load
layer = ABOVE_MOB_LAYER //so it isn't hidden behind some objects when on the floor
w_class = 4 //Quite a hefty load
slowdown = 1 //Balancing measure
throw_range = 2 //No head bowling
px_x = 0
px_y = -8
var/mob/living/brain/brainmob = null //The current occupant.
var/mob/living/carbon/brain/brainmob = null //The current occupant.
var/obj/item/organ/brain/brain = null //The brain organ
//Limb appearance info:
@@ -32,8 +31,7 @@
/obj/item/bodypart/head/drop_organs(mob/user)
var/turf/T = get_turf(src)
if(status != BODYPART_ROBOTIC)
playsound(T, 'sound/misc/splort.ogg', 50, 1, -1)
playsound(T, 'sound/misc/splort.ogg', 50, 1, -1)
for(var/obj/item/I in src)
if(I == brain)
if(user)
@@ -49,77 +47,67 @@
else
I.loc = T
/obj/item/bodypart/head/update_limb(dropping_limb, mob/living/carbon/source)
var/mob/living/carbon/C
/obj/item/bodypart/head/update_limb(dropping_limb, mob/living/carbon/human/source)
var/mob/living/carbon/human/H
if(source)
C = source
H = source
else
C = owner
H = owner
if(!istype(H))
return
var/datum/species/S = H.dna.species
//First of all, name.
real_name = H.real_name
real_name = C.real_name
if(C.disabilities & HUSK)
real_name = "Unknown"
hair_style = "Bald"
//Facial hair
if(H.facial_hair_style && (FACEHAIR in S.specflags))
facial_hair_style = H.facial_hair_style
if(S.hair_color)
if(S.hair_color == "mutcolor")
facial_hair_color = H.dna.features["mcolor"]
else
facial_hair_color = S.hair_color
else
facial_hair_color = H.facial_hair_color
hair_alpha = S.hair_alpha
else
facial_hair_style = "Shaved"
facial_hair_color = "000"
hair_alpha = 255
//Hair
if(H.hair_style && (HAIR in S.specflags))
hair_style = H.hair_style
if(S.hair_color)
if(S.hair_color == "mutcolor")
hair_color = H.dna.features["mcolor"]
else
hair_color = S.hair_color
else
hair_color = H.hair_color
hair_alpha = S.hair_alpha
else
hair_style = "Bald"
hair_color = "000"
hair_alpha = initial(hair_alpha)
// lipstick
if(H.lip_style && (LIPS in S.specflags))
lip_style = H.lip_style
lip_color = H.lip_color
else
lip_style = null
lip_color = "white"
// eyes
if(EYECOLOR in S.specflags)
eyes = S.eyes
eye_color = H.eye_color
else
eyes = "eyes"
eye_color = ""
lip_style = null
else if(!animal_origin)
var/mob/living/carbon/human/H = C
var/datum/species/S = H.dna.species
//Facial hair
if(H.facial_hair_style && (FACEHAIR in S.species_traits))
facial_hair_style = H.facial_hair_style
if(S.hair_color)
if(S.hair_color == "mutcolor")
facial_hair_color = H.dna.features["mcolor"]
else
facial_hair_color = S.hair_color
else
facial_hair_color = H.facial_hair_color
hair_alpha = S.hair_alpha
else
facial_hair_style = "Shaved"
facial_hair_color = "000"
hair_alpha = 255
//Hair
if(H.hair_style && (HAIR in S.species_traits))
hair_style = H.hair_style
if(S.hair_color)
if(S.hair_color == "mutcolor")
hair_color = H.dna.features["mcolor"]
else
hair_color = S.hair_color
else
hair_color = H.hair_color
hair_alpha = S.hair_alpha
else
hair_style = "Bald"
hair_color = "000"
hair_alpha = initial(hair_alpha)
// lipstick
if(H.lip_style && (LIPS in S.species_traits))
lip_style = H.lip_style
lip_color = H.lip_color
else
lip_style = null
lip_color = "white"
// eyes
if(EYECOLOR in S.species_traits)
eyes = S.eyes
eye_color = H.eye_color
else
eyes = "eyes"
eye_color = ""
..()
/obj/item/bodypart/head/update_icon_dropped()
var/list/standing = get_limb_icon(1)
if(!standing.len)
icon_state = initial(icon_state)//no overlays found, we default back to initial icon.
if(!standing)
return
for(var/image/I in standing)
I.pixel_x = px_x
@@ -128,11 +116,13 @@
/obj/item/bodypart/head/get_limb_icon(dropped)
cut_overlays()
var/list/standing = ..()
var/image/I = ..()
var/list/standing = list()
standing += I
if(dropped) //certain overlays only appear when the limb is being detached from its owner.
var/datum/sprite_accessory/S
if(status != BODYPART_ROBOTIC) //having a robotic head hides certain features.
if(status != ORGAN_ROBOTIC) //having a robotic head hides certain features.
//facial hair
if(facial_hair_style)
S = facial_hair_styles_list[facial_hair_style]
@@ -144,12 +134,7 @@
//Applies the debrained overlay if there is no brain
if(!brain)
if(animal_origin == ALIEN_BODYPART)
standing += image("icon"='icons/mob/animal_parts.dmi', "icon_state" = "debrained_alien_s", "layer" = -HAIR_LAYER, "dir"=SOUTH)
else if(animal_origin == LARVA_BODYPART)
standing += image("icon"='icons/mob/animal_parts.dmi', "icon_state" = "debrained_larva_s", "layer" = -HAIR_LAYER, "dir"=SOUTH)
else if(!(NOBLOOD in species_flags_list))
standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s", "layer" = -HAIR_LAYER, "dir"=SOUTH)
standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s", "layer" = -HAIR_LAYER, "dir"=SOUTH)
else
if(hair_style)
S = hair_styles_list[hair_style]
@@ -172,32 +157,9 @@
img_eyes_s.color = "#" + eye_color
standing += img_eyes_s
return standing
if(standing.len)
return standing
/obj/item/bodypart/head/monkey
icon = 'icons/mob/animal_parts.dmi'
icon_state = "default_monkey_head"
animal_origin = MONKEY_BODYPART
/obj/item/bodypart/head/alien
icon = 'icons/mob/animal_parts.dmi'
icon_state = "alien_head_s"
px_x = 0
px_y = 0
dismemberable = 0
max_damage = 500
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/head/devil
dismemberable = 0
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/head/larva
icon = 'icons/mob/animal_parts.dmi'
icon_state = "larva_head_s"
px_x = 0
px_y = 0
dismemberable = 0
max_damage = 50
animal_origin = LARVA_BODYPART
/obj/item/bodypart/head/burn()
drop_organs()
..()
+46 -154
View File
@@ -10,48 +10,55 @@
if(L.body_zone == zone)
return L
/mob/living/carbon/has_hand_for_held_index(i)
if(i)
var/obj/item/bodypart/L = hand_bodyparts[i]
if(L)
return L
return FALSE
//Mob has their active hand
/mob/proc/has_active_hand()
return 1
/mob/living/carbon/human/has_active_hand()
var/obj/item/bodypart/L
if(hand)
L = get_bodypart("l_arm")
else
L = get_bodypart("r_arm")
if(!L)
return 0
return 1
/mob/proc/has_left_hand()
return TRUE
/mob/living/carbon/has_left_hand()
for(var/obj/item/bodypart/L in hand_bodyparts)
if(L.held_index % 2)
return TRUE
return FALSE
/mob/living/carbon/alien/larva/has_left_hand()
return 1
/mob/living/carbon/human/has_left_hand()
var/obj/item/bodypart/L
L = get_bodypart("l_arm")
if(!L)
return 0
return 1
/mob/proc/has_right_hand()
return TRUE
/mob/living/carbon/has_right_hand()
for(var/obj/item/bodypart/L in hand_bodyparts)
if(!(L.held_index % 2))
return TRUE
return FALSE
/mob/living/carbon/alien/larva/has_right_hand()
return 1
/mob/living/carbon/human/has_right_hand()
var/obj/item/bodypart/L
L = get_bodypart("r_arm")
if(!L)
return 0
return 1
//Limb numbers
/mob/proc/get_num_arms()
return 2
/mob/proc/get_num_legs()
return 2
/mob/living/carbon/get_num_arms()
/mob/proc/get_leg_ignore()
return 0
/mob/living/carbon/human/get_leg_ignore()
if(FLYING in dna.species.specflags)
return 1
/mob/living/carbon/human/get_num_arms()
. = 0
for(var/X in bodyparts)
var/obj/item/bodypart/affecting = X
@@ -60,19 +67,7 @@
if(affecting.body_part == ARM_LEFT)
.++
//sometimes we want to ignore that we don't have the required amount of arms.
/mob/proc/get_arm_ignore()
return 0
/mob/living/carbon/alien/larva/get_arm_ignore()
return 1 //so we can still handcuff larvas.
/mob/proc/get_num_legs()
return 2
/mob/living/carbon/get_num_legs()
/mob/living/carbon/human/get_num_legs()
. = 0
for(var/X in bodyparts)
var/obj/item/bodypart/affecting = X
@@ -81,36 +76,19 @@
if(affecting.body_part == LEG_LEFT)
.++
//sometimes we want to ignore that we don't have the required amount of legs.
/mob/proc/get_leg_ignore()
return 0
/mob/living/carbon/alien/larva/get_leg_ignore()
return 1
/mob/living/carbon/human/get_leg_ignore()
if(movement_type & FLYING)
return 1
/mob/living/proc/get_missing_limbs()
return list()
/mob/living/carbon/get_missing_limbs()
/mob/living/carbon/human/get_missing_limbs()
var/list/full = list("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg")
for(var/zone in full)
if(get_bodypart(zone))
full -= zone
return full
/mob/living/carbon/alien/larva/get_missing_limbs()
var/list/full = list("head", "chest")
for(var/zone in full)
if(get_bodypart(zone))
full -= zone
return full
//Remove all embedded objects from all limbs on the carbon mob
/mob/living/carbon/proc/remove_all_embedded_objects()
//Remove all embedded objects from all limbs on the human mob
/mob/living/carbon/human/proc/remove_all_embedded_objects()
var/turf/T = get_turf(src)
for(var/X in bodyparts)
@@ -121,7 +99,7 @@
clear_alert("embeddedobject")
/mob/living/carbon/proc/has_embedded_objects()
/mob/living/carbon/human/proc/has_embedded_objects()
. = 0
for(var/X in bodyparts)
var/obj/item/bodypart/L = X
@@ -130,7 +108,7 @@
//Helper for quickly creating a new limb - used by augment code in species.dm spec_attacked_by
/mob/living/carbon/proc/newBodyPart(zone, robotic, fixed_icon)
/proc/newBodyPart(zone, robotic, fixed_icon, mob/living/carbon/human/source)
var/obj/item/bodypart/L
switch(zone)
if("l_arm")
@@ -146,64 +124,13 @@
if("chest")
L = new /obj/item/bodypart/chest()
if(L)
L.update_limb(fixed_icon, src)
if(source)
L.update_limb(fixed_icon, source)
else if(fixed_icon)
L.no_update = 1//when attached, the limb won't be affected by the appearance changes of its mob owner.
if(robotic)
L.change_bodypart_status(BODYPART_ROBOTIC)
. = L
L.change_bodypart_status(ORGAN_ROBOTIC)
/mob/living/carbon/monkey/newBodyPart(zone, robotic, fixed_icon)
var/obj/item/bodypart/L
switch(zone)
if("l_arm")
L = new /obj/item/bodypart/l_arm/monkey()
if("r_arm")
L = new /obj/item/bodypart/r_arm/monkey()
if("head")
L = new /obj/item/bodypart/head/monkey()
if("l_leg")
L = new /obj/item/bodypart/l_leg/monkey()
if("r_leg")
L = new /obj/item/bodypart/r_leg/monkey()
if("chest")
L = new /obj/item/bodypart/chest/monkey()
if(L)
L.update_limb(fixed_icon, src)
if(robotic)
L.change_bodypart_status(BODYPART_ROBOTIC)
. = L
/mob/living/carbon/alien/larva/newBodyPart(zone, robotic, fixed_icon)
var/obj/item/bodypart/L
switch(zone)
if("head")
L = new /obj/item/bodypart/head/larva()
if("chest")
L = new /obj/item/bodypart/chest/larva()
if(L)
L.update_limb(fixed_icon, src)
if(robotic)
L.change_bodypart_status(BODYPART_ROBOTIC)
. = L
/mob/living/carbon/alien/humanoid/newBodyPart(zone, robotic, fixed_icon)
var/obj/item/bodypart/L
switch(zone)
if("l_arm")
L = new /obj/item/bodypart/l_arm/alien()
if("r_arm")
L = new /obj/item/bodypart/r_arm/alien()
if("head")
L = new /obj/item/bodypart/head/alien()
if("l_leg")
L = new /obj/item/bodypart/l_leg/alien()
if("r_leg")
L = new /obj/item/bodypart/r_leg/alien()
if("chest")
L = new /obj/item/bodypart/chest/alien()
if(L)
L.update_limb(fixed_icon, src)
if(robotic)
L.change_bodypart_status(BODYPART_ROBOTIC)
. = L
@@ -235,39 +162,4 @@
if("albino")
. = "fff4e6"
if("orange")
. = "ffc905"
/mob/living/carbon/proc/Digitigrade_Leg_Swap(swap_back)
var/body_plan_changed = FALSE
for(var/X in bodyparts)
var/obj/item/bodypart/O = X
var/obj/item/bodypart/N
if((!O.use_digitigrade && swap_back == FALSE) || (O.use_digitigrade && swap_back == TRUE))
if(O.body_part == LEG_LEFT)
if(swap_back == TRUE)
N = new /obj/item/bodypart/l_leg
else
N = new /obj/item/bodypart/l_leg/digitigrade
else if(O.body_part == LEG_RIGHT)
if(swap_back == TRUE)
N = new /obj/item/bodypart/r_leg
else
N = new /obj/item/bodypart/r_leg/digitigrade
if(!N)
continue
body_plan_changed = TRUE
O.drop_limb(1)
qdel(O)
N.attach_limb(src)
if(body_plan_changed && ishuman(src))
var/mob/living/carbon/human/H = src
if(H.w_uniform)
var/obj/item/clothing/under/U = H.w_uniform
if(U.mutantrace_variation)
if(swap_back)
U.adjusted = NORMAL_STYLE
else
U.adjusted = DIGITIGRADE_STYLE
H.update_inv_w_uniform()
if(H.shoes && !swap_back)
H.unEquip(H.shoes)
. = "ffc905"
@@ -1,162 +0,0 @@
/obj/item/bodypart/l_arm/robot
name = "cyborg left arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
attack_verb = list("slapped", "punched")
item_state = "buildpipe"
icon = 'icons/obj/robot_parts.dmi'
flags = CONDUCT
icon_state = "l_arm"
status = BODYPART_ROBOTIC
/obj/item/bodypart/r_arm/robot
name = "cyborg right arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
attack_verb = list("slapped", "punched")
item_state = "buildpipe"
icon = 'icons/obj/robot_parts.dmi'
flags = CONDUCT
icon_state = "r_arm"
status = BODYPART_ROBOTIC
/obj/item/bodypart/l_leg/robot
name = "cyborg left leg"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
attack_verb = list("kicked", "stomped")
item_state = "buildpipe"
icon = 'icons/obj/robot_parts.dmi'
flags = CONDUCT
icon_state = "l_leg"
status = BODYPART_ROBOTIC
/obj/item/bodypart/r_leg/robot
name = "cyborg right leg"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
attack_verb = list("kicked", "stomped")
item_state = "buildpipe"
icon = 'icons/obj/robot_parts.dmi'
flags = CONDUCT
icon_state = "r_leg"
status = BODYPART_ROBOTIC
/obj/item/bodypart/chest/robot
name = "cyborg torso"
desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
item_state = "buildpipe"
icon = 'icons/obj/robot_parts.dmi'
flags = CONDUCT
icon_state = "chest"
status = BODYPART_ROBOTIC
var/wired = 0
var/obj/item/weapon/stock_parts/cell/cell = null
/obj/item/bodypart/chest/robot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/stock_parts/cell))
if(src.cell)
user << "<span class='warning'>You have already inserted a cell!</span>"
return
else
if(!user.unEquip(W))
return
W.loc = src
src.cell = W
user << "<span class='notice'>You insert the cell.</span>"
else if(istype(W, /obj/item/stack/cable_coil))
if(src.wired)
user << "<span class='warning'>You have already inserted wire!</span>"
return
var/obj/item/stack/cable_coil/coil = W
if (coil.use(1))
src.wired = 1
user << "<span class='notice'>You insert the wire.</span>"
else
user << "<span class='warning'>You need one length of coil to wire it!</span>"
else
return ..()
/obj/item/bodypart/chest/robot/Destroy()
if(cell)
qdel(cell)
cell = null
return ..()
/obj/item/bodypart/chest/robot/drop_organs(mob/user)
if(wired)
new /obj/item/stack/cable_coil(user.loc, 1)
if(cell)
cell.forceMove(user.loc)
cell = null
..()
/obj/item/bodypart/head/robot
name = "cyborg head"
desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
item_state = "buildpipe"
icon = 'icons/obj/robot_parts.dmi'
flags = CONDUCT
icon_state = "head"
status = BODYPART_ROBOTIC
var/obj/item/device/assembly/flash/handheld/flash1 = null
var/obj/item/device/assembly/flash/handheld/flash2 = null
/obj/item/bodypart/head/robot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/device/assembly/flash/handheld))
var/obj/item/device/assembly/flash/handheld/F = W
if(src.flash1 && src.flash2)
user << "<span class='warning'>You have already inserted the eyes!</span>"
return
else if(F.crit_fail)
user << "<span class='warning'>You can't use a broken flash!</span>"
return
else
if(!user.unEquip(W))
return
F.loc = src
if(src.flash1)
src.flash2 = F
else
src.flash1 = F
user << "<span class='notice'>You insert the flash into the eye socket.</span>"
else if(istype(W, /obj/item/weapon/crowbar))
if(flash1 || flash2)
playsound(src.loc, W.usesound, 50, 1)
user << "<span class='notice'>You remove the flash from [src].</span>"
if(flash1)
flash1.forceMove(user.loc)
flash1 = null
if(flash2)
flash2.forceMove(user.loc)
flash2 = null
else
user << "<span class='warning'>There are no flash to remove from [src].</span>"
else
return ..()
/obj/item/bodypart/head/robot/Destroy()
if(flash1)
qdel(flash1)
flash1 = null
if(flash2)
qdel(flash2)
flash2 = null
return ..()
/obj/item/bodypart/head/robot/drop_organs(mob/user)
if(flash1)
flash1.forceMove(user.loc)
flash1 = null
if(flash2)
flash2.forceMove(user.loc)
flash2 = null
..()
+2 -2
View File
@@ -24,7 +24,7 @@
/datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/bodypart/chest/CH = target.get_bodypart("chest")
if(tool)
if(IC || tool.w_class > WEIGHT_CLASS_NORMAL || (NODROP in tool.flags) || istype(tool, /obj/item/organ))
if(IC || tool.w_class > 3 || (NODROP in tool.flags) || istype(tool, /obj/item/organ))
user << "<span class='warning'>You can't seem to fit [tool] in [target]'s [target_zone]!</span>"
return 0
else
@@ -41,4 +41,4 @@
return 1
else
user << "<span class='warning'>You don't find anything in [target]'s [target_zone].</span>"
return 0
return 0
+3 -2
View File
@@ -16,10 +16,11 @@
return 0
user.drop_item()
target.internal_organs += tool
tool.loc = target
var/datum/action/item_action/hands_free/activate_pill/P = new
P.button.name = "Activate [tool.name]"
P.button_icon_state = tool.icon_state
P.target = tool
P.Grant(target)
@@ -32,7 +33,7 @@
/datum/action/item_action/hands_free/activate_pill/Trigger()
if(!..())
return 0
owner << "<span class='caution'>You grit your teeth and burst the implanted [target.name]!</span>"
owner << "<span class='caution'>You grit your teeth and burst the implanted [target]!</span>"
add_logs(owner, null, "swallowed an implanted pill", target)
if(target.reagents.total_volume)
target.reagents.reaction(owner, INGEST)
@@ -0,0 +1,38 @@
/datum/surgery/gender_reassignment
name = "gender reassignment"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/reshape_genitals, /datum/surgery_step/close)
species = list(/mob/living/carbon/human)
possible_locs = list("groin")
//reshape_genitals
/datum/surgery_step/reshape_genitals
name = "reshape genitals"
implements = list(/obj/item/weapon/scalpel = 100, /obj/item/weapon/hatchet = 50, /obj/item/weapon/wirecutters = 35)
time = 64
/datum/surgery_step/reshape_genitals/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(target.gender == FEMALE)
user.visible_message("[user] begins to reshape [target]'s genitals to look more masculine.", "<span class='notice'>You begin to reshape [target]'s genitals to look more masculine...</span>")
else
user.visible_message("[user] begins to reshape [target]'s genitals to look more feminine.", "<span class='notice'>You begin to reshape [target]'s genitals to look more feminine...</span>")
/datum/surgery_step/reshape_genitals/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/mob/living/carbon/human/H = target //no type check, as that should be handled by the surgery
H.gender_ambiguous = 0
if(target.gender == FEMALE)
user.visible_message("[user] has made a man of [target]!", "<span class='notice'>You made [target] a man.</span>")
target.gender = MALE
else
user.visible_message("[user] has made a woman of [target]!", "<span class='notice'>You made [target] a woman.</span>")
target.gender = FEMALE
target.regenerate_icons()
return 1
/datum/surgery_step/reshape_genitals/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/mob/living/carbon/human/H = target
H.gender_ambiguous = 1
user.visible_message("<span class='warning'>[user] accidentally mutilates [target]'s genitals beyond the point of recognition!</span>", "<span class='warning'>You accidentally mutilate [target]'s genitals beyond the point of recognition!</span>")
target.gender = pick(MALE, FEMALE)
target.regenerate_icons()
return 1
+5 -3
View File
@@ -21,7 +21,7 @@
/datum/surgery_step/clamp_bleeders/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(locate(/datum/surgery_step/saw) in surgery.steps)
target.heal_bodypart_damage(20,0)
target.heal_organ_damage(20,0)
return ..()
@@ -69,7 +69,7 @@
/datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(locate(/datum/surgery_step/saw) in surgery.steps)
target.heal_bodypart_damage(45,0)
target.heal_organ_damage(45,0)
return ..()
@@ -84,7 +84,9 @@
user.visible_message("[user] begins to saw through the bone in [target]'s [parse_zone(target_zone)].", "<span class='notice'>You begin to saw through the bone in [target]'s [parse_zone(target_zone)]...</span>")
/datum/surgery_step/saw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
target.apply_damage(50,"brute","[target_zone]")
if(ishuman(target))
var/mob/living/carbon/human/H = target
H.apply_damage(50,"brute","[target_zone]")
user.visible_message("[user] saws [target]'s [parse_zone(target_zone)] open!", "<span class='notice'>You saw [target]'s [parse_zone(target_zone)] open.</span>")
return 1
+76 -73
View File
@@ -1,94 +1,97 @@
/proc/attempt_initiate_surgery(obj/item/I, mob/living/M, mob/user)
if(!istype(M))
return
if(istype(M))
var/mob/living/carbon/human/H
var/obj/item/bodypart/affecting
var/selected_zone = user.zone_selected
var/mob/living/carbon/C
var/obj/item/bodypart/affecting
var/selected_zone = user.zone_selected
if(istype(M, /mob/living/carbon/human))
H = M
affecting = H.get_bodypart(check_zone(selected_zone))
if(istype(M, /mob/living/carbon))
C = M
affecting = C.get_bodypart(check_zone(selected_zone))
if(M.lying || isslime(M)) //if they're prone or a slime
var/datum/surgery/current_surgery
if(!M.lying && !isslime(M)) //if they're prone or a slime
return
for(var/datum/surgery/S in M.surgeries)
if(S.location == selected_zone)
current_surgery = S
var/datum/surgery/current_surgery
if(!current_surgery)
var/list/all_surgeries = surgeries_list.Copy()
var/list/available_surgeries = list()
for(var/datum/surgery/S in M.surgeries)
if(S.location == selected_zone)
current_surgery = S
for(var/datum/surgery/S in all_surgeries)
if(!S.possible_locs.Find(selected_zone))
continue
if(affecting)
if(!S.requires_bodypart)
continue
if(S.requires_organic_bodypart && affecting.status == ORGAN_ROBOTIC)
continue
else if(H && S.requires_bodypart) //human with no limb in surgery zone when we need a limb
continue
if(!S.can_start(user, M))
continue
for(var/path in S.species)
if(istype(M, path))
available_surgeries[S.name] = S
break
if(!current_surgery)
var/list/all_surgeries = surgeries_list.Copy()
var/list/available_surgeries = list()
var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries
if(P && user && user.Adjacent(M) && (I in user))
var/datum/surgery/S = available_surgeries[P]
for(var/datum/surgery/S in all_surgeries)
if(!S.possible_locs.Find(selected_zone))
continue
if(affecting)
if(!S.requires_bodypart)
continue
if(S.requires_organic_bodypart && affecting.status == BODYPART_ROBOTIC)
continue
else if(C && S.requires_bodypart) //mob with no limb in surgery zone when we need a limb
continue
if(!S.can_start(user, M))
continue
for(var/path in S.species)
if(istype(M, path))
available_surgeries[S.name] = S
break
for(var/datum/surgery/other in M.surgeries)
if(other.location == S.location)
return //during the input() another surgery was started at the same location.
var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries
if(P && user && user.Adjacent(M) && (I in user))
var/datum/surgery/S = available_surgeries[P]
var/datum/surgery/procedure = new S.type
if(procedure)
procedure.location = selected_zone
for(var/datum/surgery/other in M.surgeries)
if(other.location == S.location)
return //during the input() another surgery was started at the same location.
//we check that the surgery is still doable after the input() wait.
if(H)
affecting = H.get_bodypart(check_zone(selected_zone))
if(affecting)
if(!procedure.requires_bodypart)
return
if(procedure.requires_organic_bodypart && affecting.status == ORGAN_ROBOTIC)
return
else if(H && procedure.requires_bodypart)
return
if(!procedure.can_start(user, M))
return
//we check that the surgery is still doable after the input() wait.
if(C)
affecting = C.get_bodypart(check_zone(selected_zone))
if(affecting)
if(!S.requires_bodypart)
return
if(S.requires_organic_bodypart && affecting.status == BODYPART_ROBOTIC)
return
else if(C && S.requires_bodypart)
return
if(!S.can_start(user, M))
return
if(procedure.ignore_clothes || get_location_accessible(M, selected_zone))
M.surgeries += procedure
procedure.organ = affecting
user.visible_message("[user] drapes [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].", \
"<span class='notice'>You drape [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].</span>")
if(S.ignore_clothes || get_location_accessible(M, selected_zone))
var/datum/surgery/procedure = new S.type(M, selected_zone, affecting)
user.visible_message("[user] drapes [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].", \
"<span class='notice'>You drape [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].</span>")
add_logs(user, M, "operated", addition="Operation type: [procedure.name], location: [selected_zone]")
else
user << "<span class='warning'>You need to expose [M]'s [parse_zone(selected_zone)] first!</span>"
add_logs(user, M, "operated", addition="Operation type: [procedure.name], location: [selected_zone]")
else
user << "<span class='warning'>You need to expose [M]'s [parse_zone(selected_zone)] first!</span>"
else if(!current_surgery.step_in_progress)
if(current_surgery.status == 1)
M.surgeries -= current_surgery
user.visible_message("[user] removes the drapes from [M]'s [parse_zone(selected_zone)].", \
"<span class='notice'>You remove the drapes from [M]'s [parse_zone(selected_zone)].</span>")
qdel(current_surgery)
else if(istype(user.get_inactive_hand(), /obj/item/weapon/cautery) && current_surgery.can_cancel)
M.surgeries -= current_surgery
user.visible_message("[user] mends the incision and removes the drapes from [M]'s [parse_zone(selected_zone)].", \
"<span class='notice'>You mend the incision and remove the drapes from [M]'s [parse_zone(selected_zone)].</span>")
qdel(current_surgery)
else if(current_surgery.can_cancel)
user << "<span class='warning'>You need to hold a cautery in inactive hand to stop [M]'s surgery!</span>"
else if(!current_surgery.step_in_progress)
if(current_surgery.status == 1)
M.surgeries -= current_surgery
user.visible_message("[user] removes the drapes from [M]'s [parse_zone(selected_zone)].", \
"<span class='notice'>You remove the drapes from [M]'s [parse_zone(selected_zone)].</span>")
qdel(current_surgery)
else if(istype(user.get_inactive_held_item(), /obj/item/weapon/cautery) && current_surgery.can_cancel)
M.surgeries -= current_surgery
user.visible_message("[user] mends the incision and removes the drapes from [M]'s [parse_zone(selected_zone)].", \
"<span class='notice'>You mend the incision and remove the drapes from [M]'s [parse_zone(selected_zone)].</span>")
qdel(current_surgery)
else if(current_surgery.can_cancel)
user << "<span class='warning'>You need to hold a cautery in inactive hand to stop [M]'s surgery!</span>"
return 1
return 1
return 0
/proc/get_location_modifier(mob/M)
proc/get_location_modifier(mob/M)
var/turf/T = get_turf(M)
if(locate(/obj/structure/table/optable, T))
return 1
+8 -7
View File
@@ -14,9 +14,7 @@
var/obj/item/weapon/implant/I = null
/datum/surgery_step/extract_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
for(var/obj/item/O in target.implants)
I = O
break
I = locate(/obj/item/weapon/implant) in target
if(I)
user.visible_message("[user] begins to extract [I] from [target]'s [target_zone].", "<span class='notice'>You begin to extract [I] from [target]'s [target_zone]...</span>")
else
@@ -28,11 +26,14 @@
I.removed(target)
var/obj/item/weapon/implantcase/case
for(var/obj/item/weapon/implantcase/ic in user.held_items)
case = ic
break
if(!case)
if(istype(user.get_item_by_slot(slot_l_hand), /obj/item/weapon/implantcase))
case = user.get_item_by_slot(slot_l_hand)
else if(istype(user.get_item_by_slot(slot_r_hand), /obj/item/weapon/implantcase))
case = user.get_item_by_slot(slot_r_hand)
else
case = locate(/obj/item/weapon/implantcase) in get_turf(target)
if(case && !case.imp)
case.imp = I
I.loc = case
+20 -16
View File
@@ -16,23 +16,21 @@
/datum/surgery_step/add_limb
name = "replace limb"
implements = list(/obj/item/bodypart = 100)
implements = list(/obj/item/robot_parts = 100)
time = 32
var/obj/item/bodypart/L = null // L because "limb"
/datum/surgery_step/add_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/bodypart/aug = tool
if(aug.status != BODYPART_ROBOTIC && aug.body_zone != target_zone)
user << "<span class='warning'>[tool] isn't the right type for [parse_zone(target_zone)].</span>"
return -1
L = surgery.operated_bodypart
L = surgery.organ
if(L)
user.visible_message("[user] begins to augment [target]'s [parse_zone(user.zone_selected)].", "<span class ='notice'>You begin to augment [target]'s [parse_zone(user.zone_selected)]...</span>")
else
user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "<span class ='notice'>You look for [target]'s [parse_zone(user.zone_selected)]...</span>")
//ACTUAL SURGERIES
/datum/surgery/augmentation
@@ -41,17 +39,20 @@
species = list(/mob/living/carbon/human)
possible_locs = list("r_arm","l_arm","r_leg","l_leg","chest","head")
//SURGERY STEP SUCCESSES
/datum/surgery_step/add_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(L)
user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!", "<span class='notice'>You successfully augment [target]'s [parse_zone(target_zone)].</span>")
L.change_bodypart_status(BODYPART_ROBOTIC, 1)
user.drop_item()
qdel(tool)
target.update_damage_overlays()
target.updatehealth()
add_logs(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]")
if(ishuman(target))
var/mob/living/carbon/human/H = target
user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!", "<span class='notice'>You successfully augment [target]'s [parse_zone(target_zone)].</span>")
L.change_bodypart_status(ORGAN_ROBOTIC, 1)
user.drop_item()
qdel(tool)
H.update_damage_overlays(0)
H.updatehealth()
add_logs(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]")
else
user << "<span class='warning'>[target] has no organic [parse_zone(target_zone)] there!</span>"
return 1
@@ -82,7 +83,7 @@
user.visible_message("[user] begins to install the chainsaw onto [target].", "<span class='notice'>You begin to install the chainsaw onto [target]...</span>")
/datum/surgery_step/chainsaw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(!target.get_empty_held_indexes())
if(target.l_hand && target.r_hand)
user << "<span class='warning'>You can't fit the chainsaw in while [target]'s hands are full!</span>"
return 0
else
@@ -102,7 +103,9 @@
requires_organic_bodypart = 0
/datum/surgery/chainsaw_removal/can_start(mob/user, mob/living/carbon/target)
if(target.is_holding_item_of_type(/obj/item/weapon/mounted_chainsaw))
var/list/hands = get_both_hands(target)
var/M = locate(/obj/item/weapon/mounted_chainsaw) in hands
if(M)
return 1//can continue surgery
else
return 0//surgery will never be available
@@ -116,7 +119,8 @@
user.visible_message("[user] begins sawing the chainsaw off of [target]'s arms.", "<span class='notice'>You begin removing [target]'s chainsaw...</span>")
/datum/surgery_step/chainsaw_removal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
for(var/obj/item/weapon/mounted_chainsaw/V in target.held_items)
var/list/hands = get_both_hands(target)
for(var/obj/item/weapon/mounted_chainsaw/V in hands)
target.unEquip(V, 1)
user.visible_message("[user] carefully saws [target]'s arm free of the chainsaw.", "<span class='notice'>You remove the chainsaw.</span>")
return 1
+1 -13
View File
@@ -67,11 +67,6 @@
else if(implement_type in implements_extract)
current_type = "extract"
var/list/organs = target.getorganszone(target_zone)
var/mob/living/simple_animal/borer/B = target.has_brain_worms()
if(target.has_brain_worms())
user.visible_message("[user] begins to extract [B] from [target]'s [parse_zone(target_zone)].",
"<span class='notice'>You begin to extract [B] from [target]'s [parse_zone(target_zone)]...</span>")
return TRUE
if(!organs.len)
user << "<span class='notice'>There is no removeable organs in [target]'s [parse_zone(target_zone)]!</span>"
return -1
@@ -82,7 +77,7 @@
organs[O.name] = O
I = input("Remove which organ?", "Surgery", null, null) as null|anything in organs
if(I && user && target && user.Adjacent(target) && user.get_active_held_item() == tool)
if(I && user && target && user.Adjacent(target) && user.get_active_hand() == tool)
I = organs[I]
if(!I) return -1
user.visible_message("[user] begins to extract [I] from [target]'s [parse_zone(target_zone)].",
@@ -112,13 +107,6 @@
"<span class='notice'>You insert [tool] into [target]'s [parse_zone(target_zone)].</span>")
else if(current_type == "extract")
var/mob/living/simple_animal/borer/B = target.has_brain_worms()
if(B && B.victim == target)
user.visible_message("[user] successfully extracts [B] from [target]'s [parse_zone(target_zone)]!",
"<span class='notice'>You successfully extract [B] from [target]'s [parse_zone(target_zone)].</span>")
add_logs(user, target, "surgically removed [B] from", addition="INTENT: [uppertext(user.a_intent)]")
B.leave_victim()
return FALSE
if(I && I.owner == target)
user.visible_message("[user] successfully extracts [I] from [target]'s [parse_zone(target_zone)]!",
"<span class='notice'>You successfully extract [I] from [target]'s [parse_zone(target_zone)].</span>")
+17 -74
View File
@@ -4,7 +4,7 @@
zone = "r_arm"
slot = "r_arm_device"
icon_state = "implant-toolkit"
w_class = WEIGHT_CLASS_NORMAL
w_class = 3
actions_types = list(/datum/action/item_action/organ_action/toggle)
var/list/items_list = list()
@@ -64,16 +64,12 @@
if(!holder || (holder in src))
return
owner.visible_message("<span class='notice'>[owner] retracts [holder] back into [owner.p_their()] [zone == "r_arm" ? "right" : "left"] arm.</span>",
owner.visible_message("<span class='notice'>[owner] retracts [holder] back into \his [zone == "r_arm" ? "right" : "left"] arm.</span>",
"<span class='notice'>[holder] snaps back into your [zone == "r_arm" ? "right" : "left"] arm.</span>",
"<span class='italics'>You hear a short mechanical noise.</span>")
if(istype(holder, /obj/item/device/assembly/flash/armimplant))
var/obj/item/device/assembly/flash/F = holder
F.SetLuminosity(0)
owner.unEquip(holder, 1)
holder.forceMove(src)
holder.loc = src
holder = null
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
@@ -84,16 +80,13 @@
holder = item
holder.flags |= NODROP
holder.resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
holder.unacidable = 1
holder.slot_flags = null
holder.w_class = WEIGHT_CLASS_HUGE
holder.w_class = 5
holder.materials = null
if(istype(holder, /obj/item/device/assembly/flash/armimplant))
var/obj/item/device/assembly/flash/F = holder
F.SetLuminosity(7)
var/obj/item/arm_item = owner.get_active_held_item()
var/arm_slot = (zone == "r_arm" ? slot_r_hand : slot_l_hand)
var/obj/item/arm_item = owner.get_item_by_slot(arm_slot)
if(arm_item)
if(!owner.unEquip(arm_item))
@@ -102,15 +95,15 @@
else
owner << "<span class='notice'>You drop [arm_item] to activate [src]!</span>"
var/result = (zone == "r_arm" ? owner.put_in_r_hand(holder) : owner.put_in_l_hand(holder))
if(!result)
if(zone == "r_arm" ? !owner.put_in_r_hand(holder) : !owner.put_in_l_hand(holder))
owner << "<span class='warning'>Your [src] fails to activate!</span>"
return
// Activate the hand that now holds our item.
owner.swap_hand(result)//... or the 1st hand if the index gets lost somehow
if(zone == "r_arm" ? owner.hand : !owner.hand)
owner.swap_hand()
owner.visible_message("<span class='notice'>[owner] extends [holder] from [owner.p_their()] [zone == "r_arm" ? "right" : "left"] arm.</span>",
owner.visible_message("<span class='notice'>[owner] extends [holder] from \his [zone == "r_arm" ? "right" : "left"] arm.</span>",
"<span class='notice'>You extend [holder] from your [zone == "r_arm" ? "right" : "left"] arm.</span>",
"<span class='italics'>You hear a short mechanical noise.</span>")
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
@@ -121,7 +114,8 @@
return
// You can emag the arm-mounted implant by activating it while holding emag in it's hand.
if(istype(owner.get_active_held_item(), /obj/item/weapon/card/emag) && emag_act())
var/arm_slot = (zone == "r_arm" ? slot_r_hand : slot_l_hand)
if(istype(owner.get_item_by_slot(arm_slot), /obj/item/weapon/card/emag) && emag_act())
return
if(!holder || (holder in src))
@@ -158,8 +152,7 @@
origin_tech = "materials=4;combat=4;biotech=4;powerstorage=4;syndicate=3"
holder = /obj/item/weapon/gun/energy/laser/mounted
/obj/item/organ/cyberimp/arm/gun/laser/l
zone = "l_arm"
/obj/item/organ/cyberimp/arm/gun/laser/l/zone = "l_arm"
/obj/item/organ/cyberimp/arm/gun/taser
@@ -167,10 +160,9 @@
desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arm and remains inside when not in use."
icon_state = "arm_taser"
origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4"
holder = /obj/item/weapon/gun/energy/e_gun/advtaser/mounted
holder = /obj/item/weapon/gun/energy/gun/advtaser/mounted
/obj/item/organ/cyberimp/arm/gun/taser/l
zone = "l_arm"
/obj/item/organ/cyberimp/arm/gun/taser/l/zone = "l_arm"
/obj/item/organ/cyberimp/arm/toolset
@@ -180,8 +172,7 @@
contents = newlist(/obj/item/weapon/screwdriver/cyborg, /obj/item/weapon/wrench/cyborg, /obj/item/weapon/weldingtool/largetank/cyborg,
/obj/item/weapon/crowbar/cyborg, /obj/item/weapon/wirecutters/cyborg, /obj/item/device/multitool/cyborg)
/obj/item/organ/cyberimp/arm/toolset/l
zone = "l_arm"
/obj/item/organ/cyberimp/arm/toolset/l/zone = "l_arm"
/obj/item/organ/cyberimp/arm/toolset/emag_act()
if(!(locate(/obj/item/weapon/kitchen/knife/combat/cyborg) in items_list))
@@ -189,51 +180,3 @@
items_list += new /obj/item/weapon/kitchen/knife/combat/cyborg(src)
return 1
return 0
/obj/item/organ/cyberimp/arm/esword
name = "arm-mounted energy blade"
desc = "An illegal, and highly dangerous cybernetic implant that can project a deadly blade of concentrated enregy."
contents = newlist(/obj/item/weapon/melee/energy/blade/hardlight)
origin_tech = "materials=4;combat=5;biotech=3;powerstorage=2;syndicate=5"
/obj/item/organ/cyberimp/arm/medibeam
name = "integrated medical beamgun"
desc = "A cybernetic implant that allows the user to project a healing beam from their hand."
contents = newlist(/obj/item/weapon/gun/medbeam)
origin_tech = "materials=5;combat=2;biotech=5;powerstorage=4;syndicate=1"
/obj/item/organ/cyberimp/arm/flash
name = "integrated high-intensity photon projector" //Why not
desc = "An integrated projector mounted onto a user's arm, that is able to be used as a powerful flash."
contents = newlist(/obj/item/device/assembly/flash/armimplant)
origin_tech = "materials=4;combat=3;biotech=4;magnets=4;powerstorage=3"
/obj/item/organ/cyberimp/arm/flash/New()
..()
if(locate(/obj/item/device/assembly/flash/armimplant) in items_list)
var/obj/item/device/assembly/flash/armimplant/F = locate(/obj/item/device/assembly/flash/armimplant) in items_list
F.I = src
/obj/item/organ/cyberimp/arm/baton
name = "arm electrification implant"
desc = "An illegal combat implant that allows the user to administer disabling shocks from their arm."
contents = newlist(/obj/item/borg/stun)
origin_tech = "materials=3;combat=5;biotech=4;powerstorage=4;syndicate=3"
/obj/item/organ/cyberimp/arm/combat
name = "combat cybernetics implant"
desc = "A powerful cybernetic implant that contains combat modules built into the user's arm"
contents = newlist(/obj/item/weapon/melee/energy/blade/hardlight, /obj/item/weapon/gun/medbeam, /obj/item/borg/stun, /obj/item/device/assembly/flash/armimplant)
origin_tech = "materials=5;combat=7;biotech=5;powerstorage=5;syndicate=6;programming=5"
/obj/item/organ/cyberimp/arm/combat/New()
..()
if(locate(/obj/item/device/assembly/flash/armimplant) in items_list)
var/obj/item/device/assembly/flash/armimplant/F = locate(/obj/item/device/assembly/flash/armimplant) in items_list
F.I = src
/obj/item/organ/cyberimp/arm/surgery
name = "surgical toolset implant"
desc = "A set of surgical tools hidden behind a concealed panel on the user's arm"
contents = newlist(/obj/item/weapon/retractor, /obj/item/weapon/hemostat, /obj/item/weapon/cautery, /obj/item/weapon/surgicaldrill, /obj/item/weapon/scalpel, /obj/item/weapon/circular_saw, /obj/item/weapon/surgical_drapes)
origin_tech = "materials=3;engineering=3;biotech=3;programming=2;magnets=3"
@@ -14,7 +14,7 @@
var/synthesizing = 0
var/poison_amount = 5
slot = "stomach"
origin_tech = "materials=2;powerstorage=2;biotech=2"
origin_tech = "materials=4;powerstorage=5;biotech=4"
/obj/item/organ/cyberimp/chest/nutriment/on_life()
if(synthesizing)
@@ -41,14 +41,14 @@
implant_color = "#006607"
hunger_threshold = NUTRITION_LEVEL_HUNGRY
poison_amount = 10
origin_tech = "materials=4;powerstorage=3;biotech=3"
origin_tech = "materials=4;powerstorage=5;biotech=5"
/obj/item/organ/cyberimp/chest/reviver
name = "Reviver implant"
desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!"
icon_state = "chest_implant"
implant_color = "#AD0000"
origin_tech = "materials=5;programming=4;biotech=4"
origin_tech = "materials=5;programming=4;biotech=6"
slot = "heartdrive"
var/revive_cost = 0
var/reviving = 0
@@ -96,7 +96,7 @@
else
cooldown += 200
if(ishuman(owner))
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
if(H.stat != DEAD && prob(50 / severity))
H.heart_attack = TRUE
@@ -121,7 +121,7 @@
implant_overlay = null
implant_color = null
actions_types = list(/datum/action/item_action/organ_action/toggle)
w_class = WEIGHT_CLASS_NORMAL
w_class = 3
var/on = 0
var/datum/effect_system/trail_follow/ion/ion_trail
@@ -197,4 +197,3 @@
toggle(silent=1)
return 0
+4 -4
View File
@@ -5,7 +5,7 @@
implant_overlay = "eye_implant_overlay"
slot = "eye_sight"
zone = "eyes"
w_class = WEIGHT_CLASS_TINY
w_class = 1
var/sight_flags = 0
var/dark_view = 0
@@ -18,7 +18,7 @@
/obj/item/organ/cyberimp/eyes/Insert(var/mob/living/carbon/M, var/special = 0)
..()
if(ishuman(owner) && eye_color)
if(istype(owner, /mob/living/carbon/human) && eye_color)
var/mob/living/carbon/human/HMN = owner
old_eye_color = HMN.eye_color
HMN.eye_color = eye_color
@@ -30,7 +30,7 @@
/obj/item/organ/cyberimp/eyes/Remove(var/mob/living/carbon/M, var/special = 0)
M.sight ^= sight_flags
if(ishuman(M) && eye_color)
if(istype(M,/mob/living/carbon/human) && eye_color)
var/mob/living/carbon/human/HMN = owner
HMN.eye_color = old_eye_color
HMN.regenerate_icons()
@@ -43,7 +43,7 @@
if(prob(10 * severity))
return
owner << "<span class='warning'>Static obfuscates your vision!</span>"
owner.flash_act(visual = 1)
owner.flash_eyes(visual = 1)
/obj/item/organ/cyberimp/eyes/xray
name = "X-ray implant"
@@ -26,7 +26,7 @@
icon_state = "brain_implant"
implant_overlay = "brain_implant_overlay"
zone = "head"
w_class = WEIGHT_CLASS_TINY
w_class = 1
/obj/item/organ/cyberimp/brain/emp_act(severity)
if(!owner)
@@ -41,7 +41,10 @@
name = "anti-drop implant"
desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle."
var/active = 0
var/list/stored_items = list()
var/l_hand_ignore = 0
var/r_hand_ignore = 0
var/obj/item/l_hand_obj = null
var/obj/item/r_hand_obj = null
implant_color = "#DE7E00"
slot = "brain_antidrop"
origin_tech = "materials=4;programming=5;biotech=4"
@@ -50,41 +53,66 @@
/obj/item/organ/cyberimp/brain/anti_drop/ui_action_click()
active = !active
if(active)
for(var/obj/item/I in owner.held_items)
if(!(I.flags & NODROP))
stored_items += I
l_hand_obj = owner.l_hand
r_hand_obj = owner.r_hand
if(l_hand_obj)
if(owner.l_hand.flags & NODROP)
l_hand_ignore = 1
else
owner.l_hand.flags |= NODROP
l_hand_ignore = 0
var/list/L = owner.get_empty_held_indexes()
if(L && L.len == owner.held_items.len)
if(r_hand_obj)
if(owner.r_hand.flags & NODROP)
r_hand_ignore = 1
else
owner.r_hand.flags |= NODROP
r_hand_ignore = 0
if(!l_hand_obj && !r_hand_obj)
owner << "<span class='notice'>You are not holding any items, your hands relax...</span>"
active = 0
stored_items = list()
else
for(var/obj/item/I in stored_items)
owner << "<span class='notice'>Your [owner.get_held_index_name(owner.get_held_index_of_item(I))]'s grip tightens.</span>"
var/msg = 0
msg += !l_hand_ignore && l_hand_obj ? 1 : 0
msg += !r_hand_ignore && r_hand_obj ? 2 : 0
switch(msg)
if(1)
owner << "<span class='notice'>Your left hand's grip tightens.</span>"
if(2)
owner << "<span class='notice'>Your right hand's grip tightens.</span>"
if(3)
owner << "<span class='notice'>Both of your hand's grips tighten.</span>"
else
release_items()
owner << "<span class='notice'>Your hands relax...</span>"
l_hand_obj = null
r_hand_obj = null
/obj/item/organ/cyberimp/brain/anti_drop/emp_act(severity)
if(!owner)
return
var/range = severity ? 10 : 5
var/atom/A
var/obj/item/L_item = owner.l_hand
var/obj/item/R_item = owner.r_hand
release_items()
..()
for(var/obj/item/I in stored_items)
if(L_item)
A = pick(oview(range))
I.throw_at(A, range, 2)
owner << "<span class='warning'>Your [owner.get_held_index_name(owner.get_held_index_of_item(I))] spasms and throws the [I.name]!</span>"
stored_items = list()
L_item.throw_at(A, range, 2)
owner << "<span class='warning'>Your left arm spasms and throws the [L_item.name]!</span>"
if(R_item)
A = pick(oview(range))
R_item.throw_at(A, range, 2)
owner << "<span class='warning'>Your right arm spasms and throws the [R_item.name]!</span>"
/obj/item/organ/cyberimp/brain/anti_drop/proc/release_items()
for(var/obj/item/I in stored_items)
I.flags ^= NODROP
if(!l_hand_ignore && l_hand_obj in owner.contents)
l_hand_obj.flags ^= NODROP
if(!r_hand_ignore && r_hand_obj in owner.contents)
r_hand_obj.flags ^= NODROP
/obj/item/organ/cyberimp/brain/anti_drop/Remove(var/mob/living/carbon/M, special = 0)
if(active)
@@ -128,7 +156,7 @@
desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked."
icon_state = "implant_mask"
slot = "breathing_tube"
w_class = WEIGHT_CLASS_TINY
w_class = 1
origin_tech = "materials=2;biotech=3"
/obj/item/organ/cyberimp/mouth/breathing_tube/emp_act(severity)
+2 -2
View File
@@ -5,7 +5,7 @@
desc = "A device that automatically injects a cyber-implant into the user without the hassle of extensive surgery. It has a slot to insert implants and a screwdriver slot for removing accidentally added implants."
icon_state = "autoimplanter"
item_state = "walkietalkie"//left as this so as to intentionally not have inhands
w_class = WEIGHT_CLASS_SMALL
w_class = 2
var/obj/item/organ/storedorgan
var/organ_type = /obj/item/organ/cyberimp
var/uses = INFINITE
@@ -51,7 +51,7 @@
var/turf/open/floorloc = get_turf(user)
floorloc.contents += contents
user << "<span class='notice'>You remove the [storedorgan] from [src].</span>"
playsound(get_turf(user), I.usesound, 50, 1)
playsound(get_turf(user), 'sound/items/Screwdriver.ogg', 50, 1)
storedorgan = null
if(uses != INFINITE)
uses--
+11 -8
View File
@@ -1,17 +1,17 @@
/mob/proc/getorgan(typepath)
mob/proc/getorgan(typepath)
return
/mob/proc/getorganszone(zone)
mob/proc/getorganszone(zone)
return
/mob/proc/getorganslot(slot)
mob/proc/getorganslot(slot)
return
/mob/living/carbon/getorgan(typepath)
mob/living/carbon/getorgan(typepath)
return (locate(typepath) in internal_organs)
/mob/living/carbon/getorganszone(zone, subzones = 0)
mob/living/carbon/getorganszone(zone, var/subzones = 0)
var/list/returnorg = list()
if(subzones)
// Include subzones - groin for chest, eyes and mouth for head
@@ -20,11 +20,14 @@
if(zone == "chest")
returnorg = getorganszone("groin")
for(var/X in internal_organs)
var/obj/item/organ/O = X
for(var/obj/item/organ/O in internal_organs)
if(zone == O.zone)
returnorg += O
return returnorg
/mob/living/carbon/getorganslot(slot)
mob/living/carbon/getorganslot(slot)
return internal_organs_slot[slot]
proc/isorgan(atom/A)
return istype(A, /obj/item/organ)
+19 -269
View File
@@ -4,7 +4,8 @@
var/mob/living/carbon/owner = null
var/status = ORGAN_ORGANIC
origin_tech = "biotech=3"
w_class = WEIGHT_CLASS_SMALL
force = 1
w_class = 2
throwforce = 0
var/zone = "chest"
var/slot
@@ -164,7 +165,7 @@
/obj/item/organ/heart/cursed
name = "cursed heart"
desc = "A heart that, when inserted, will force you to pump it manually."
desc = "it needs to be pumped..."
icon_state = "cursedheart-off"
icon_base = "cursedheart"
origin_tech = "biotech=6"
@@ -192,7 +193,7 @@
if(world.time > (last_pump + pump_delay))
if(ishuman(owner) && owner.client) //While this entire item exists to make people suffer, they can't control disconnects.
var/mob/living/carbon/human/H = owner
if(H.dna && !(NOBLOOD in H.dna.species.species_traits))
if(H.dna && !(NOBLOOD in H.dna.species.specflags))
H.blood_volume = max(H.blood_volume - blood_loss, 0)
H << "<span class = 'userdanger'>You have to keep pumping your blood!</span>"
if(add_colour)
@@ -207,7 +208,7 @@
owner << "<span class ='userdanger'>Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!</span>"
/datum/action/item_action/organ_action/cursed_heart
name = "Pump your blood"
name = "pump your blood"
//You are now brea- pumping blood manually
/datum/action/item_action/organ_action/cursed_heart/Trigger()
@@ -225,7 +226,7 @@
var/mob/living/carbon/human/H = owner
if(istype(H))
if(H.dna && !(NOBLOOD in H.dna.species.species_traits))
if(H.dna && !(NOBLOOD in H.dna.species.specflags))
H.blood_volume = min(H.blood_volume + cursed_heart.blood_loss*0.5, BLOOD_VOLUME_MAXIMUM)
H.remove_client_colour(/datum/client_colour/cursed_heart_blood)
cursed_heart.add_colour = TRUE
@@ -238,15 +239,7 @@
priority = 100 //it's an indicator you're dieing, so it's very high priority
colour = "red"
#define HUMAN_MAX_OXYLOSS 3
#define HUMAN_CRIT_MAX_OXYLOSS (SSmob.wait/30)
#define HEAT_GAS_DAMAGE_LEVEL_1 2
#define HEAT_GAS_DAMAGE_LEVEL_2 4
#define HEAT_GAS_DAMAGE_LEVEL_3 8
#define COLD_GAS_DAMAGE_LEVEL_1 0.5
#define COLD_GAS_DAMAGE_LEVEL_2 1.5
#define COLD_GAS_DAMAGE_LEVEL_3 3
/obj/item/organ/lungs
name = "lungs"
@@ -254,266 +247,13 @@
zone = "chest"
slot = "lungs"
gender = PLURAL
w_class = WEIGHT_CLASS_NORMAL
var/list/breathlevels = list("safe_oxygen_min" = 16,"safe_oxygen_max" = 0,"safe_co2_min" = 0,"safe_co2_max" = 10,
"safe_toxins_min" = 0,"safe_toxins_max" = 0.05,"SA_para_min" = 1,"SA_sleep_min" = 5,"BZ_trip_balls_min" = 1)
//Breath damage
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
var/safe_oxygen_max = 0
var/safe_co2_min = 0
var/safe_co2_max = 10 // Yes it's an arbitrary value who cares?
var/safe_toxins_min = 0
var/safe_toxins_max = 0.05
var/SA_para_min = 1 //Sleeping agent
var/SA_sleep_min = 5 //Sleeping agent
var/BZ_trip_balls_min = 1 //BZ gas.
var/oxy_breath_dam_min = 1
var/oxy_breath_dam_max = 10
var/co2_breath_dam_min = 1
var/co2_breath_dam_max = 10
var/tox_breath_dam_min = MIN_PLASMA_DAMAGE
var/tox_breath_dam_max = MAX_PLASMA_DAMAGE
/obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, var/mob/living/carbon/human/H)
if((H.status_flags & GODMODE))
return
var/species_traits = list()
if(H && H.dna && H.dna.species && H.dna.species.species_traits)
species_traits = H.dna.species.species_traits
if(!breath || (breath.total_moles() == 0))
if(H.reagents.has_reagent("epinephrine"))
return
if(H.health >= HEALTH_THRESHOLD_CRIT)
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
else if(!(NOCRITDAMAGE in species_traits))
H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
H.failed_last_breath = 1
if(safe_oxygen_min)
H.throw_alert("oxy", /obj/screen/alert/oxy)
else if(safe_toxins_min)
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else if(safe_co2_min)
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
return 0
var/gas_breathed = 0
var/list/breath_gases = breath.gases
breath.assert_gases("o2", "plasma", "co2", "n2o", "bz")
//Partial pressures in our breath
var/O2_pp = breath.get_breath_partial_pressure(breath_gases["o2"][MOLES])
var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases["plasma"][MOLES])
var/CO2_pp = breath.get_breath_partial_pressure(breath_gases["co2"][MOLES])
//-- OXY --//
//Too much oxygen! //Yes, some species may not like it.
if(safe_oxygen_max)
if(O2_pp > safe_oxygen_max)
var/ratio = (breath_gases["o2"][MOLES]/safe_oxygen_max) * 10
H.adjustOxyLoss(Clamp(ratio,oxy_breath_dam_min,oxy_breath_dam_max))
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
else
H.clear_alert("too_much_oxy")
//Too little oxygen!
if(safe_oxygen_min)
if(O2_pp < safe_oxygen_min)
gas_breathed = handle_too_little_breath(H,O2_pp,safe_oxygen_min,breath_gases["o2"][MOLES])
H.throw_alert("oxy", /obj/screen/alert/oxy)
else
H.failed_last_breath = 0
if(H.getOxyLoss())
H.adjustOxyLoss(-5)
gas_breathed = breath_gases["o2"][MOLES]
H.clear_alert("oxy")
//Exhale
breath_gases["o2"][MOLES] -= gas_breathed
breath_gases["co2"][MOLES] += gas_breathed
gas_breathed = 0
//-- CO2 --//
//CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick.
if(safe_co2_max)
if(CO2_pp > safe_co2_max)
if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
H.co2overloadtime = world.time
else if(world.time - H.co2overloadtime > 120)
H.Paralyse(3)
H.adjustOxyLoss(3) // Lets hurt em a little, let them know we mean business
if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
H.adjustOxyLoss(8)
H.throw_alert("too_much_co2", /obj/screen/alert/too_much_co2)
if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
H.emote("cough")
else
H.co2overloadtime = 0
H.clear_alert("too_much_co2")
//Too little CO2!
if(breathlevels["safe_co2_min"])
if(CO2_pp < safe_co2_min)
gas_breathed = handle_too_little_breath(H,CO2_pp, safe_co2_min,breath_gases["co2"][MOLES])
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
gas_breathed = breath_gases["co2"][MOLES]
H.clear_alert("not_enough_co2")
//Exhale
breath_gases["co2"][MOLES] -= gas_breathed
breath_gases["o2"][MOLES] += gas_breathed
gas_breathed = 0
//-- TOX --//
//Too much toxins!
if(safe_toxins_max)
if(Toxins_pp > safe_toxins_max)
var/ratio = (breath_gases["plasma"][MOLES]/safe_toxins_max) * 10
if(H.reagents)
H.reagents.add_reagent("plasma", Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max))
H.throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
else
H.clear_alert("tox_in_air")
//Too little toxins!
if(safe_toxins_min)
if(Toxins_pp < safe_toxins_min)
gas_breathed = handle_too_little_breath(H,Toxins_pp, safe_toxins_min, breath_gases["plasma"][MOLES])
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
gas_breathed = breath_gases["plasma"][MOLES]
H.clear_alert("not_enough_tox")
//Exhale
breath_gases["plasma"][MOLES] -= gas_breathed
breath_gases["co2"][MOLES] += gas_breathed
gas_breathed = 0
//-- TRACES --//
if(breath) // If there's some other shit in the air lets deal with it here.
// N2O
var/SA_pp = breath.get_breath_partial_pressure(breath_gases["n2o"][MOLES])
if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit
H.Paralyse(3) // 3 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
H.Sleeping(max(H.sleeping+2, 10))
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
if(prob(20))
H.emote(pick("giggle", "laugh"))
// BZ
var/bz_pp = breath.get_breath_partial_pressure(breath_gases["bz"][MOLES])
if(bz_pp > BZ_trip_balls_min)
H.hallucination += 20
if(prob(33))
H.adjustBrainLoss(3)
else if(bz_pp > 0.01)
H.hallucination += 5//Removed at 2 per tick so this will slowly build up
handle_breath_temperature(breath, H)
breath.garbage_collect()
return 1
/obj/item/organ/lungs/proc/handle_too_little_breath(mob/living/carbon/human/H = null,breath_pp = 0, safe_breath_min = 0, true_pp = 0)
. = 0
if(!H || !safe_breath_min) //the other args are either: Ok being 0 or Specifically handled.
return 0
if(prob(20))
H.emote("gasp")
if(breath_pp > 0)
var/ratio = safe_breath_min/breath_pp
H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all!
H.failed_last_breath = 1
. = true_pp*ratio/6
else
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
H.failed_last_breath = 1
/obj/item/organ/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures
if(abs(310.15 - breath.temperature) > 50)
var/species_traits = list()
if(H && H.dna && H.dna.species && H.dna.species.species_traits)
species_traits = H.dna.species.species_traits
if(!(mutations_list[COLDRES] in H.dna.mutations) && !(RESISTCOLD in species_traits)) // COLD DAMAGE
switch(breath.temperature)
if(-INFINITY to 120)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, "head")
if(120 to 200)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, "head")
if(200 to 260)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head")
if(!(RESISTHOT in species_traits)) // HEAT DAMAGE
switch(breath.temperature)
if(360 to 400)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head")
if(400 to 1000)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head")
if(1000 to INFINITY)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head")
w_class = 3
/obj/item/organ/lungs/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent("salbutamol", 5)
return S
/obj/item/organ/lungs/plasmaman
name = "plasma filter"
safe_oxygen_min = 0 //We don't breath this
safe_toxins_min = 16 //We breath THIS!
safe_toxins_max = 0
#undef HUMAN_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS
#undef HEAT_GAS_DAMAGE_LEVEL_1
#undef HEAT_GAS_DAMAGE_LEVEL_2
#undef HEAT_GAS_DAMAGE_LEVEL_3
#undef COLD_GAS_DAMAGE_LEVEL_1
#undef COLD_GAS_DAMAGE_LEVEL_2
#undef COLD_GAS_DAMAGE_LEVEL_3
/obj/item/organ/tongue
name = "tongue"
desc = "A fleshy muscle mostly used for lying."
@@ -618,10 +358,10 @@
name = "alien tongue"
desc = "According to leading xenobiologists the evolutionary benefit of having a second mouth in your mouth is \"that it looks badass\"."
icon_state = "tonguexeno"
say_mod = "hiss"
say_mod = "hisses"
/obj/item/organ/tongue/alien/TongueSpeech(var/message)
playsound(owner, "hiss", 25, 1, 1)
playsound(owner, "hiss", 15, 1, 1)
return message
/obj/item/organ/tongue/bone
@@ -693,3 +433,13 @@
if(inflamed)
S.reagents.add_reagent("????", 5)
return S
/obj/item/organ/tongue/yautja
name = "yautja tongue"
desc = "You're having a hard time even deciding if this is a tongue or not."
icon_state = "tongueyautja"
say_mod = "clicks"
/obj/item/organ/tongue/yautja/TongueSpeech(var/message)
playsound(owner, "predsay", 50, 0, 1)
return message
+1 -1
View File
@@ -20,7 +20,7 @@
var/oldname = target.real_name
target.real_name = target.dna.species.random_name(target.gender,1)
var/newname = target.real_name //something about how the code handles names required that I use this instead of target.real_name
user.visible_message("[user] alters [oldname]'s appearance completely, [target.p_they()] are now [newname]!", "<span class='notice'>You alter [oldname]'s appearance completely, [target.p_they()] are now [newname].</span>")
user.visible_message("[user] alters [oldname]'s appearance completely, they are now [newname]!", "<span class='notice'>You alter [oldname]'s appearance completely, they are now [newname].</span>")
if(ishuman(target))
var/mob/living/carbon/human/H = target
H.sec_hud_set_ID()
+24 -23
View File
@@ -1,50 +1,51 @@
/datum/surgery/prosthetic_replacement
name = "prosthetic replacement"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/add_prosthetic)
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
species = list(/mob/living/carbon/human)
possible_locs = list("r_arm", "l_arm", "l_leg", "r_leg", "head")
requires_bodypart = FALSE //need a missing limb
/datum/surgery/prosthetic_replacement/can_start(mob/user, mob/living/carbon/target)
if(!iscarbon(target))
if(!ishuman(target))
return 0
var/mob/living/carbon/C = target
if(!C.get_bodypart(user.zone_selected)) //can only start if limb is missing
var/mob/living/carbon/human/H = target
if(!H.get_bodypart(user.zone_selected)) //can only start if limb is missing
return 1
/datum/surgery_step/add_prosthetic
name = "add prosthetic"
implements = list(/obj/item/bodypart = 100)
implements = list(/obj/item/robot_parts = 100, /obj/item/bodypart = 100)
time = 32
var/organ_rejection_dam = 0
/datum/surgery_step/add_prosthetic/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/bodypart/BP = tool
if(ismonkey(target))// monkey patient only accept organic monkey limbs
if(BP.status == BODYPART_ROBOTIC || BP.animal_origin != MONKEY_BODYPART)
user << "<span class='warning'>[BP] doesn't match the patient's morphology.</span>"
return -1
if(BP.status != BODYPART_ROBOTIC)
organ_rejection_dam = 10
if(ishuman(target))
if(BP.animal_origin)
user << "<span class='warning'>[BP] doesn't match the patient's morphology.</span>"
return -1
var/mob/living/carbon/human/H = target
if(H.dna.species.id != BP.species_id)
var/tool_body_zone
if(istype(tool, /obj/item/robot_parts))
var/obj/item/robot_parts/RP = tool
tool_body_zone = RP.body_zone
else if(istype(tool, /obj/item/bodypart))
var/obj/item/bodypart/L = tool
if(L.status != ORGAN_ROBOTIC)
organ_rejection_dam = 10
if(target.dna.species.id != L.species_id)
organ_rejection_dam = 30
if(target_zone == BP.body_zone) //so we can't replace a leg with an arm, or a human arm with a monkey arm.
tool_body_zone = L.body_zone
if(target_zone == tool_body_zone) //so we can't replace a leg with an arm.
user.visible_message("[user] begins to replace [target]'s [parse_zone(target_zone)].", "<span class ='notice'>You begin to replace [target]'s [parse_zone(target_zone)]...</span>")
else
user << "<span class='warning'>[tool] isn't the right type for [parse_zone(target_zone)].</span>"
return -1
/datum/surgery_step/add_prosthetic/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/bodypart/L = tool
user.drop_item()
var/obj/item/bodypart/L
if(istype(tool, /obj/item/robot_parts))
L = newBodyPart(target_zone, 1, 1)
user.drop_item()
qdel(tool)
else
L = tool
user.drop_item()
L.attach_limb(target)
if(organ_rejection_dam)
target.adjustToxLoss(organ_rejection_dam)
@@ -12,7 +12,7 @@
/datum/surgery_step/remove_object/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
L = surgery.operated_bodypart
L = surgery.organ
if(L)
user.visible_message("[user] looks for objects embedded in [target]'s [parse_zone(user.zone_selected)].", "<span class='notice'>You look for objects embedded in [target]'s [parse_zone(user.zone_selected)]...</span>")
else
@@ -30,7 +30,7 @@
L.embedded_objects -= I
if(objects > 0)
user.visible_message("[user] sucessfully removes [objects] objects from [H]'s [L]!", "<span class='notice'>You successfully remove [objects] objects from [H]'s [L.name].</span>")
user.visible_message("[user] sucessfully removes [objects] objects from [H]'s [L]!", "<span class='notice'>You sucessfully remove [objects] objects from [H]'s [L.name].</span>")
else
user << "<span class='warning'>You find no objects embedded in [H]'s [L]!</span>"
+18 -52
View File
@@ -1,37 +1,16 @@
/datum/surgery
var/name = "surgery"
var/status = 1
var/list/steps = list() //Steps in a surgery
var/step_in_progress = 0 //Actively performing a Surgery
var/can_cancel = 1 //Can cancel this surgery after step 1 with cautery
var/list/species = list(/mob/living/carbon/human) //Acceptable Species
var/location = "chest" //Surgery location
var/requires_organic_bodypart = 1 //Prevents you from performing an operation on robotic limbs
var/list/possible_locs = list() //Multiple locations
var/ignore_clothes = 0 //This surgery ignores clothes
var/mob/living/carbon/target //Operation target mob
var/obj/item/bodypart/operated_bodypart //Operable body part
var/requires_bodypart = TRUE //Surgery available only when a bodypart is present, or only when it is missing.
var/success_multiplier = 0 //Step success propability multiplier
/datum/surgery/New(surgery_target, surgery_location, surgery_bodypart)
..()
if(surgery_target)
target = surgery_target
target.surgeries += src
if(surgery_location)
location = surgery_location
if(surgery_bodypart)
operated_bodypart = surgery_bodypart
/datum/surgery/Destroy()
if(target)
target.surgeries -= src
target = null
operated_bodypart = null
return ..()
var/list/steps = list() //Steps in a surgery
var/step_in_progress = 0 //Actively performing a Surgery
var/can_cancel = 1 //Can cancel this surgery after step 1 with cautery
var/list/species = list(/mob/living/carbon/human) //Acceptable Species
var/location = "chest" //Surgery location
var/requires_organic_bodypart = 1 //Prevents you from performing an operation on robotic limbs
var/list/possible_locs = list() //Multiple locations -- c0
var/ignore_clothes = 0 //This surgery ignores clothes
var/obj/item/organ/organ //Operable body part
var/requires_bodypart = TRUE //Surgery available only when a bodypart is present, or only when it is missing.
/datum/surgery/proc/can_start(mob/user, mob/living/carbon/target)
// if 0 surgery wont show up in list
@@ -39,13 +18,13 @@
return 1
/datum/surgery/proc/next_step(mob/user)
/datum/surgery/proc/next_step(mob/user, mob/living/carbon/target)
if(step_in_progress)
return 1
return
var/datum/surgery_step/S = get_surgery_step()
if(S)
if(S.try_op(user, target, user.zone_selected, user.get_active_held_item(), src))
if(S.try_op(user, target, user.zone_selected, user.get_active_hand(), src))
return 1
return 0
@@ -53,24 +32,10 @@
var/step_type = steps[status]
return new step_type
/datum/surgery/proc/complete()
feedback_add_details("surgeries_completed", type)
qdel(src)
/datum/surgery/proc/get_propability_multiplier()
var/propability = 0.5
var/turf/T = get_turf(target)
if(locate(/obj/structure/table/optable, T))
propability = 1
else if(locate(/obj/structure/table, T))
propability = 0.8
else if(locate(/obj/structure/bed, T))
propability = 0.7
return propability + success_multiplier
/datum/surgery/proc/complete(mob/living/carbon/human/target)
target.surgeries -= src
src = null
@@ -80,6 +45,7 @@
//Other important variables are var/list/surgeries (/mob/living) and var/list/internal_organs (/mob/living/carbon)
// var/list/bodyparts (/mob/living/carbon/human) is the LIMBS of a Mob.
//Surgical procedures are initiated by attempt_initiate_surgery(), which is called by surgical drapes and bedsheets.
// /code/modules/surgery/multiple_location_example.dm contains steps to setup a multiple location operation.
//TODO
@@ -94,4 +60,4 @@
//RESOLVED ISSUES //"Todo" jobs that have been completed
//combine hands/feet into the arms - Hands/feet were removed - RR
//surgeries (not steps) that can be initiated on any body part (corresponding with damage locations) - Call this one done, see possible_locs var - c0
//surgeries (not steps) that can be initiated on any body part (corresponding with damage locations) - Call this one done, see multiple_location_example.dm - RR
+6 -11
View File
@@ -1,10 +1,10 @@
/datum/surgery_step
var/name
var/list/implements = list() //format is path = probability of success. alternatively
var/implement_type = null //the current type of implement used. This has to be stored, as the actual typepath of the tool may not match the list type.
var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item.
var/accept_any_item = 0 //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand.
var/time = 10 //how long does the step take?
var/name
/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -30,7 +30,7 @@
else
user << "<span class='warning'>You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!</span>"
return 1 //returns 1 so we don't stab the guy in the dick or wherever.
if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache
if(isrobot(user) && user.a_intent != "harm") //to save asimov borgs a LOT of heartache
return 1
return 0
@@ -38,24 +38,19 @@
/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
surgery.step_in_progress = 1
var/speed_mod = 1
if(preop(user, target, target_zone, tool, surgery) == -1)
surgery.step_in_progress = 0
return
if(tool)
speed_mod = tool.toolspeed
if(do_after(user, time * speed_mod, target = target))
if(do_after(user, time, target = target))
var/advance = 0
var/prob_chance = 100
if(implement_type) //this means it isn't a require hand or any item step.
prob_chance = implements[implement_type]
prob_chance *= surgery.get_propability_multiplier()
prob_chance *= get_location_modifier(target)
if(prob(prob_chance) || iscyborg(user))
if(prob(prob_chance) || isrobot(user))
if(success(user, target, target_zone, tool, surgery))
advance = 1
else
@@ -65,7 +60,7 @@
if(advance)
surgery.status++
if(surgery.status > surgery.steps.len)
surgery.complete()
surgery.complete(target)
surgery.step_in_progress = 0
+1 -1
View File
@@ -33,7 +33,7 @@
if("spines" in L.dna.features)
L.dna.features -= "spines"
var/obj/item/severedtail/S = new(get_turf(target))
S.add_atom_colour("#[L.dna.features["mcolor"]]", FIXED_COLOUR_PRIORITY)
S.color = "#[L.dna.features["mcolor"]]"
S.markings = "[L.dna.features["tail"]]"
L.update_body()
return 1
+10 -8
View File
@@ -5,7 +5,7 @@
icon_state = "retractor"
materials = list(MAT_METAL=6000, MAT_GLASS=3000)
flags = CONDUCT
w_class = WEIGHT_CLASS_TINY
w_class = 1
origin_tech = "materials=1;biotech=1"
@@ -16,7 +16,7 @@
icon_state = "hemostat"
materials = list(MAT_METAL=5000, MAT_GLASS=2500)
flags = CONDUCT
w_class = WEIGHT_CLASS_TINY
w_class = 1
origin_tech = "materials=1;biotech=1"
attack_verb = list("attacked", "pinched")
@@ -28,7 +28,7 @@
icon_state = "cautery"
materials = list(MAT_METAL=2500, MAT_GLASS=750)
flags = CONDUCT
w_class = WEIGHT_CLASS_TINY
w_class = 1
origin_tech = "materials=1;biotech=1"
attack_verb = list("burnt")
@@ -42,7 +42,7 @@
materials = list(MAT_METAL=10000, MAT_GLASS=6000)
flags = CONDUCT
force = 15
w_class = WEIGHT_CLASS_NORMAL
w_class = 3
origin_tech = "materials=1;biotech=1"
attack_verb = list("drilled")
@@ -53,7 +53,7 @@
icon_state = "scalpel"
flags = CONDUCT
force = 10
w_class = WEIGHT_CLASS_TINY
w_class = 1
throwforce = 5
throw_speed = 3
throw_range = 5
@@ -64,7 +64,9 @@
sharpness = IS_SHARP_ACCURATE
/obj/item/weapon/scalpel/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
user.visible_message(pick("<span class='suicide'>[user] is slitting \his wrists with [src]! It looks like \he's trying to commit suicide.</span>", \
"<span class='suicide'>[user] is slitting \his throat with [src]! It looks like \he's trying to commit suicide.</span>", \
"<span class='suicide'>[user] is slitting \his stomach open with [src]! It looks like \he's trying to commit seppuku.</span>"))
return (BRUTELOSS)
@@ -77,7 +79,7 @@
throwhitsound = 'sound/weapons/pierce.ogg'
flags = CONDUCT
force = 15
w_class = WEIGHT_CLASS_NORMAL
w_class = 3
throwforce = 9
throw_speed = 2
throw_range = 5
@@ -91,7 +93,7 @@
desc = "Nanotrasen brand surgical drapes provide optimal safety and infection control."
icon = 'icons/obj/surgery.dmi'
icon_state = "surgical_drapes"
w_class = WEIGHT_CLASS_TINY
w_class = 1
origin_tech = "biotech=1"
attack_verb = list("slapped")