Cosmetic Tail Organs [NO WAGGING] (#36060)

* mob part bitflags in proper format, added tail part bitflag, hidetail clothing cover flag, reordered tail layer, added tail_underlimbs_layer for overlapping tails, limbs_layer for limbs placed under, tail_wagging + has_icon_skin_tone + tail_overlapped species anatomical flags, mutable_appearance() helper, made many suits cover tail, added tail wagging emote for species that can wag, made a species folder for species files, rewrote update_tail_showing(), character preview can show tails, vox tails are now separate from the body instead of being baked into the chest, vox tails will show slightly in north dir instead of being invisible

* added color defines, undid bitfield format change, wag emote is shorter and doesnt show text on stopping wag, vox tails have their own file and have better names, removed icon manipulation from tail updating, species can have own tail icon, made vox tail north sprites full/complete sprites

* wag emote no longer displays runechat, custom emotes can choose to not show runechat, restores old husk overlays

* limb_tail tail define, moved 2 tail species flags to organ level, added span define, tail is on organ level, added support for cosmetic organs, tail preview icon shows better, added tail support to common surgeries

* fix double tail organ, tail organ item only uses east sprite and is shifted to center it more

* removes tail wagging

* rename tail define, minor tweaks

* more checks, fix char preview issues, remove unused proc, frankensteins spawn with random kind of tail, repaired tajaran and unathi tails credit to falcon2346, robotail support, rambler will not spawn with tail, gibbing drops tails

* Update species.dm
This commit is contained in:
13spacemen
2024-02-29 01:26:34 +05:00
committed by GitHub
parent e6fcc79ebc
commit 2754c2fd14
46 changed files with 671 additions and 333 deletions

View File

@@ -16,3 +16,8 @@
#define COLOR_GLUE "#FFFFCC"
#define COLOR_BEESWAX "#FFB700"
#define COLOR_DEFAULT_CANDLE "#BE0000"
#define COLOR_RED "#FF0000"
#define COLOR_GREEN "#00FF00"
#define COLOR_BLUE "#0000FF"
#define COLOR_MATRIX_ADD(color) list(COLOR_RED, COLOR_GREEN, COLOR_BLUE, color)

View File

@@ -15,3 +15,5 @@
#define UNCUFF_LEGS -1
#define UNCUFF_BOTH 0
#define UNCUFF_HANDS 1
#define COSMETIC_ORGAN_TAIL "tail"

View File

@@ -326,6 +326,7 @@ var/MAX_EXPLOSION_RANGE = 32
#define ARM_RIGHT 256
#define HAND_LEFT 512
#define HAND_RIGHT 1024
#define TAIL 524288
// bitflags for clothing parts
@@ -352,6 +353,7 @@ var/MAX_EXPLOSION_RANGE = 32
#define HIDEEARS EARS
#define HIDEEYES EYES
#define HIDEFACE FACE
#define HIDETAIL TAIL
#define HIDEHEADHAIR 65536
#define MASKHEADHAIR 131072
#define HIDEBEARDHAIR BEARD
@@ -1006,6 +1008,7 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
#define ACID4WATER 4096 //Acid now acts like water, and vice versa.
#define NO_BALD 8192 //cannot lose hair through being shaved/radiation/etc
#define RGBSKINTONE 16384
#define HAS_ICON_SKIN_TONE 32768
var/default_colour_matrix = list(1,0,0,0,\
0,1,0,0,\
@@ -1252,29 +1255,31 @@ var/default_colour_matrix = list(1,0,0,0,\
//Human Overlays Indexes/////////THIS DEFINES WHAT LAYERS APPEARS ON TOP OF OTHERS
#define FIRE_LAYER 1 //If you're on fire (/tg/ shit)
#define MUTANTRACE_LAYER 2 //TODO: make part of body?
#define MUTATIONS_LAYER 3
#define DAMAGE_LAYER 4
#define UNIFORM_LAYER 5
#define SHOES_LAYER 6
#define GLOVES_LAYER 7
#define EARS_LAYER 8
#define SUIT_LAYER 9
#define GLASSES_LAYER 10
#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 12
#define HAIR_LAYER 13 //TODO: make part of head layer?
#define GLASSES_OVER_HAIR_LAYER 14
#define FACEMASK_LAYER 15
#define HEAD_LAYER 16
#define BACK_LAYER 17 //Back should be above head so that headgear doesn't hides backpack when facing north
#define ID_LAYER 18 //IDs should be visible above suits and backpacks
#define HANDCUFF_LAYER 19
#define MUTUALCUFF_LAYER 20
#define LEGCUFF_LAYER 21
#define HAND_LAYER 22
#define TAIL_LAYER 23 //bs12 specific. this hack is probably gonna come back to haunt me
#define TARGETED_LAYER 24 //BS12: Layer for the target overlay from weapon targeting system
#define TOTAL_LAYERS 24
#define TAIL_UNDERLIMBS_LAYER 3
#define LIMBS_LAYER 4
#define MUTATIONS_LAYER 5
#define DAMAGE_LAYER 6
#define UNIFORM_LAYER 7
#define SHOES_LAYER 8
#define GLOVES_LAYER 9
#define EARS_LAYER 10
#define SUIT_LAYER 11
#define GLASSES_LAYER 12
#define BELT_LAYER 13 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 14
#define HAIR_LAYER 15 //TODO: make part of head layer?
#define GLASSES_OVER_HAIR_LAYER 16
#define TAIL_LAYER 17
#define FACEMASK_LAYER 18
#define HEAD_LAYER 19
#define BACK_LAYER 20 //Back should be above head so that headgear doesn't hides backpack when facing north
#define ID_LAYER 21 //IDs should be visible above suits and backpacks
#define HANDCUFF_LAYER 22
#define MUTUALCUFF_LAYER 23
#define LEGCUFF_LAYER 24
#define HAND_LAYER 25
#define TARGETED_LAYER 26 //BS12: Layer for the target overlay from weapon targeting system
#define TOTAL_LAYERS 26
//////////////////////////////////
//Snake stuff so leaderboard can see it too

2
__DEFINES/span.dm Normal file
View File

@@ -0,0 +1,2 @@
// Sorted alphabetically
#define span_warning(str) ("<span class='warning'>" + str + "</span>")

View File

@@ -1,5 +1,6 @@
#define EMOTE_VISIBLE 1
#define EMOTE_AUDIBLE 2
#define EMOTE_VISIBLE (1<<0)
#define EMOTE_AUDIBLE (1<<1)
#define EMOTE_NO_RUNECHAT (1<<2)
/* Emote datums, ported from TG station. */
@@ -66,17 +67,19 @@
if (user.client && M?.client?.prefs.mob_chat_on_map && get_dist(M, user) < M?.client.view)
M.create_chat_message(user, null, msg_runechat, "", list("italics"))
if (emote_type == EMOTE_VISIBLE)
if(emote_type & EMOTE_VISIBLE)
user.visible_message(msg)
for(var/z0 in GetOpenConnectedZlevels(user))
for (var/mob/O in viewers(world.view, locate(user.x,user.y,z0)))
if (user.client && O?.client?.prefs.mob_chat_on_map && O.stat != UNCONSCIOUS && !(isinvisible(user)))
O.create_chat_message(user, null, msg_runechat, "", list("italics"))
else
if(!(emote_type & EMOTE_NO_RUNECHAT))
for(var/z0 in GetOpenConnectedZlevels(user))
for (var/mob/O in viewers(world.view, locate(user.x,user.y,z0)))
if (user.client && O?.client?.prefs.mob_chat_on_map && O.stat != UNCONSCIOUS && !(isinvisible(user)))
O.create_chat_message(user, null, msg_runechat, "", list("italics"))
else if(emote_type & EMOTE_AUDIBLE)
for(var/mob/O in get_hearers_in_view(world.view, user))
O.show_message(msg)
if (user.client && O?.client?.prefs.mob_chat_on_map && O.stat != UNCONSCIOUS && !O.is_deaf())
O.create_chat_message(user, null, msg_runechat, "", list("italics"))
if(!(emote_type & EMOTE_NO_RUNECHAT))
if(user.client && O?.client?.prefs.mob_chat_on_map && O.stat != UNCONSCIOUS && !O.is_deaf())
O.create_chat_message(user, null, msg_runechat, "", list("italics"))
var/turf/T = get_turf(user)
var/location = T ? "[T.x],[T.y],[T.z]" : "nullspace"

View File

@@ -564,7 +564,7 @@
return ..()
/datum/dynamic_ruleset/midround/from_ghosts/rambler/generate_ruleset_body(mob/applicant)
var/mob/living/carbon/human/frankenstein/new_frank = new(pick(latejoin))
var/mob/living/carbon/human/frankenstein/new_frank = new(pick(latejoin), no_tail = TRUE)
var/gender = pick(MALE, FEMALE)
new_frank.randomise_appearance_for(gender)
new_frank.key = applicant.key

View File

@@ -0,0 +1,31 @@
// Mutable appearances are an inbuilt byond datastructure. Read the documentation on them by hitting F1 in DM.
// Basically use them instead of images for overlays/underlays and when changing an object's appearance if you're doing so with any regularity.
// Unless you need the overlay/underlay to have a different direction than the base object. Then you have to use an image due to a bug.
// Mutable appearances are children of images, just so you know.
// Mutable appearances erase template vars on new, because they accept an appearance to copy as an arg
// If we have nothin to copy, we set the float plane
/mutable_appearance/New(mutable_appearance/to_copy)
..()
if(!to_copy)
plane = FLOAT_PLANE
/** Helper similar to image()
*
* icon - Our appearance's icon
* icon_state - Our appearance's icon state
* layer - Our appearance's layer
* plane - The plane to use for the appearance.
* alpha - Our appearance's alpha
* appearance_flags - Our appearance's appearance_flags
**/
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE)
var/mutable_appearance/appearance = new()
appearance.icon = icon
appearance.icon_state = icon_state
appearance.layer = layer
appearance.plane = plane
appearance.alpha = alpha
appearance.appearance_flags |= appearance_flags
return appearance

View File

@@ -12,6 +12,9 @@
var/brute_dam = 0
var/burn_dam = 0
/obj/item/robot_parts/proc/on_attach(datum/organ/external/attached_site)
return
/obj/item/robot_parts/l_arm
name = "robot left arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
@@ -36,6 +39,40 @@
icon_state = LIMB_RIGHT_LEG
part = list(LIMB_RIGHT_LEG,LIMB_RIGHT_FOOT)
/obj/item/robot_parts/tail
name = "robot tail"
desc = "A skeletal appendage wrapped in pseudomuscles, with a low-conductivity case."
icon_state = null
part = list(COSMETIC_ORGAN_TAIL)
var/tail_icon_file = 'icons/mob/tails.dmi'
var/tail_type = "vox"
var/static/list/tail_icons = list()
/obj/item/robot_parts/tail/New(loc, type_of_tail)
if(type_of_tail)
tail_type = type_of_tail
update_icon()
return ..()
/obj/item/robot_parts/tail/on_attach(datum/organ/external/tail/attached_site)
attached_site.tail_type = tail_type
/obj/item/robot_parts/tail/attackby(obj/item/W, mob/user)
if(!ismultitool(W))
return ..()
var/type_of_tail = input(user, "Configure tail type", "Robotic tail design", "vox") as null|anything in list("vox", "tajaran", "unathi")
tail_type = type_of_tail
update_icon()
/obj/item/robot_parts/tail/update_icon()
var/returned_tail_icon = tail_icons[tail_type]
if(!returned_tail_icon)
var/icon/new_tail_icon = icon(tail_icon_file, "[tail_type]_robotic_BEHIND", EAST)
new_tail_icon.Shift(EAST, 6)
new_tail_icon.Shift(NORTH, 3)
returned_tail_icon = tail_icons[tail_type] = new_tail_icon
icon = returned_tail_icon
/obj/item/robot_parts/chest
name = "robot torso"
desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."

View File

@@ -1027,7 +1027,7 @@ var/global/maxStackDepth = 10
permeability_coefficient = 0.02
flags = FPRINT
pressure_resistance = 5 * ONE_ATMOSPHERE
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET|HANDS
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET|HANDS|TAIL
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/)
slowdown = HARDSUIT_SLOWDOWN_BULKY
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)

View File

@@ -54,7 +54,7 @@
permeability_coefficient = 0.02
clothing_flags = ONESIZEFITSALL
pressure_resistance = 200 * ONE_ATMOSPHERE
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET|TAIL
allowed = list(/obj/item/weapon/tank, /obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_storage, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency_nitrogen)
slowdown = HARDSUIT_SLOWDOWN_HIGH
armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50)

View File

@@ -25,7 +25,7 @@
permeability_coefficient = 0.01
flags = FPRINT
clothing_flags = PLASMAGUARD
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET|HANDS
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET|HANDS|TAIL
slowdown = HARDSUIT_SLOWDOWN_LOW
allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_nitrogen,/obj/item/weapon/pen,/obj/item/device/flashlight/pen)
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 20)

View File

@@ -487,7 +487,7 @@ var/list/tag_suits_list = list()
icon_state = "strait_jacket"
item_state = "strait_jacket"
origin_tech = Tc_BIOTECH + "=2"
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET|HANDS
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET|HANDS|TAIL
species_fit = list(INSECT_SHAPED)
/obj/item/clothing/suit/ianshirt

View File

@@ -18,7 +18,7 @@
w_class = W_CLASS_LARGE//bulky item
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET|HANDS
body_parts_covered = ARMS|LEGS|FULL_TORSO|FEET|HANDS|TAIL
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_nitrogen,/obj/item/weapon/extinguisher,/obj/item/tool/irons,/obj/item/tool/crowbar/halligan)
slowdown = HARDSUIT_SLOWDOWN_LOW
clothing_flags = ONESIZEFITSALL
@@ -85,6 +85,7 @@
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.01
flags = FPRINT
body_parts_covered = ARMS|LEGS|FULL_TORSO|TAIL
slowdown = HARDSUIT_SLOWDOWN_HIGH
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 100, bio = 0, rad = 0)
max_heat_protection_temperature = ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE
@@ -157,7 +158,7 @@
w_class = W_CLASS_LARGE//bulky item
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50
body_parts_covered = FULL_BODY
body_parts_covered = FULL_BODY|TAIL
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_nitrogen)
slowdown = 1.5
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100)

View File

@@ -75,16 +75,18 @@
if(isobserver(M) && M.client.prefs && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(user)))
M.show_message("<a href='?src=\ref[M];follow=\ref[user]'>(Follow)</a> " + msg)
if (emote_type == EMOTE_VISIBLE)
if(emote_type & EMOTE_VISIBLE)
user.visible_message(msg)
for(var/mob/O in viewers(world.view, user))
if (O.client && O?.client?.prefs.mob_chat_on_map && get_dist(O, user) < O?.client.view)
O.create_chat_message(user, null, message, "", list("italics"))
else
if(!(emote_type & EMOTE_NO_RUNECHAT))
for(var/mob/O in viewers(world.view, user))
if(O.client && O?.client?.prefs.mob_chat_on_map && get_dist(O, user) < O?.client.view)
O.create_chat_message(user, null, message, "", list("italics"))
else if(emote_type & EMOTE_AUDIBLE)
for(var/mob/O in get_hearers_in_view(world.view, user))
O.show_message(msg)
if (O.client && O?.client?.prefs.mob_chat_on_map && get_dist(O, user) < O?.client.view)
O.create_chat_message(user, null, message, "", list("italics"))
if(!(emote_type & EMOTE_NO_RUNECHAT))
if(O.client && O?.client?.prefs.mob_chat_on_map && get_dist(O, user) < O?.client.view)
O.create_chat_message(user, null, message, "", list("italics"))
var/location = T ? "[T.x],[T.y],[T.z]" : "nullspace"
log_emote("[user.name]/[user.key] (@[location]): [message]")

View File

@@ -14,6 +14,8 @@
if(prob(100 - E.get_damage()))
//Override the current limb status and don't cause an explosion
E.droplimb(1, 1)
for(var/datum/organ/external/cosmetic_organ in cosmetic_organs)
cosmetic_organ.droplimb(TRUE, TRUE)
var/gib_radius = 0
if(reagents.has_reagent(LUBE))
gib_radius = 6 //Your insides are all lubed, so gibs travel much further

View File

@@ -97,7 +97,7 @@
..(new_loc)
initialize_basic_NPC_components()
/mob/living/carbon/human/frankenstein/New(var/new_loc, delay_ready_dna = 0) //Just fuck my shit up: the mob
/mob/living/carbon/human/frankenstein/New(var/new_loc, delay_ready_dna = 0, no_tail = FALSE) //Just fuck my shit up: the mob
var/list/valid_species = (all_species - list("Krampus", "Horror", "Manifested"))
var/datum/species/new_species = all_species[pick(valid_species)]
@@ -109,7 +109,20 @@
for(var/datum/organ/external/E in organs)
E.species = all_species[pick(valid_species)]
var/datum/organ/external/tail/tail_datum = get_cosmetic_organ(COSMETIC_ORGAN_TAIL)
if(no_tail)
tail_datum.droplimb(TRUE, spawn_limb = FALSE)
else
var/list/tailed_species = list()
for(var/species_name in all_species)
var/datum/species/picked_species = all_species[species_name]
if(picked_species.anatomy_flags & HAS_TAIL)
tailed_species += picked_species
var/datum/species/species_with_tail = pick(tailed_species)
tail_datum.fleshify()
tail_datum.create_tail_info(species_with_tail)
tail_datum.species = species_with_tail
tail_datum.update_tail(src, random = TRUE)
update_body()
/mob/living/carbon/human/mushroom/New(var/new_loc, delay_ready_dna = 0)
@@ -167,6 +180,8 @@
obj_overlays[FIRE_LAYER] = new /obj/abstract/Overlays/fire_layer
obj_overlays[MUTANTRACE_LAYER] = new /obj/abstract/Overlays/mutantrace_layer
obj_overlays[TAIL_UNDERLIMBS_LAYER] = new /obj/abstract/Overlays/tail_underlimbs_layer
obj_overlays[LIMBS_LAYER] = new /obj/abstract/Overlays/limbs_layer
obj_overlays[MUTATIONS_LAYER] = new /obj/abstract/Overlays/mutations_layer
obj_overlays[DAMAGE_LAYER] = new /obj/abstract/Overlays/damage_layer
obj_overlays[UNIFORM_LAYER] = new /obj/abstract/Overlays/uniform_layer
@@ -181,13 +196,13 @@
obj_overlays[BACK_LAYER] = new /obj/abstract/Overlays/back_layer
obj_overlays[HAIR_LAYER] = new /obj/abstract/Overlays/hair_layer
obj_overlays[GLASSES_OVER_HAIR_LAYER] = new /obj/abstract/Overlays/glasses_over_hair_layer
obj_overlays[TAIL_LAYER] = new /obj/abstract/Overlays/tail_layer
obj_overlays[FACEMASK_LAYER] = new /obj/abstract/Overlays/facemask_layer
obj_overlays[HEAD_LAYER] = new /obj/abstract/Overlays/head_layer
obj_overlays[HANDCUFF_LAYER] = new /obj/abstract/Overlays/handcuff_layer
obj_overlays[MUTUALCUFF_LAYER] = new /obj/abstract/Overlays/mutualcuff_layer
obj_overlays[LEGCUFF_LAYER] = new /obj/abstract/Overlays/legcuff_layer
//obj_overlays[HAND_LAYER] = new /obj/abstract/Overlays/hand_layer
obj_overlays[TAIL_LAYER] = new /obj/abstract/Overlays/tail_layer
obj_overlays[TARGETED_LAYER] = new /obj/abstract/Overlays/targeted_layer
..()

View File

@@ -307,14 +307,20 @@ This function restores all organs.
return
/mob/living/carbon/human/get_organ(var/zone)
/mob/living/carbon/human/get_organ(var/zone, cosmetic = FALSE)
RETURN_TYPE(/datum/organ/external)
if(!zone)
zone = LIMB_CHEST
if (zone in list( "eyes", "mouth" ))
zone = LIMB_HEAD
return organs_by_name[zone]
var/list/organ_list = organs_by_name.Copy()
if(cosmetic)
organ_list |= cosmetic_organs_by_name
return organ_list[zone]
/mob/living/carbon/human/proc/get_cosmetic_organ(zone)
RETURN_TYPE(/datum/organ/external)
return cosmetic_organs_by_name[zone]
//Picks a random usable organ from the organs passed to the arguments
//You can feed organ references, or organ strings into this obj

View File

@@ -0,0 +1,160 @@
/datum/species/vox
name = "Vox"
icobase = 'icons/mob/human_races/vox/r_vox.dmi'
deform = 'icons/mob/human_races/vox/r_def_vox.dmi'
known_languages = list(LANGUAGE_VOX)
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/rawchicken/vox
tacklePower = 40
anatomy_flags = HAS_SWEAT_GLANDS | HAS_ICON_SKIN_TONE | HAS_TAIL
survival_gear = /obj/item/weapon/storage/box/survival/vox
primitive = /mob/living/carbon/monkey/vox
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
eyes = "vox_eyes_s"
breath_type = GAS_NITROGEN
default_mutations = list(M_BEAK, M_TALONS)
flags = PLAYABLE | WHITELISTED
blood_color = VOX_BLOOD
flesh_color = "#808D11"
max_skin_tone = 6
tail = "green"
tail_icon = 'icons/mob/human_races/vox/tails.dmi'
tail_type = "vox"
footprint_type = /obj/effect/decal/cleanable/blood/tracks/footprints/vox //Bird claws
uniform_icons = 'icons/mob/species/vox/uniform.dmi'
// fat_uniform_icons = 'icons/mob/uniform_fat.dmi'
gloves_icons = 'icons/mob/species/vox/gloves.dmi'
glasses_icons = 'icons/mob/species/vox/eyes.dmi'
// ears_icons = 'icons/mob/ears.dmi'
shoes_icons = 'icons/mob/species/vox/shoes.dmi'
head_icons = 'icons/mob/species/vox/head.dmi'
// belt_icons = 'icons/mob/belt.dmi'
wear_suit_icons = 'icons/mob/species/vox/suit.dmi'
wear_mask_icons = 'icons/mob/species/vox/masks.dmi'
back_icons = 'icons/mob/species/vox/back.dmi'
has_mutant_race = 0
has_organ = list(
"heart" = /datum/organ/internal/heart/vox,
"lungs" = /datum/organ/internal/lungs/vox,
"liver" = /datum/organ/internal/liver,
"kidneys" = /datum/organ/internal/kidney,
"brain" = /datum/organ/internal/brain,
"appendix" = /datum/organ/internal/appendix,
"eyes" = /datum/organ/internal/eyes/vox
)
species_intro = "You are a Vox.<br>\
You are somewhat more adept at handling the lower pressures of space and colder temperatures.<br>\
You have talons with which you can slice others in a fist fight, and a beak which can be used to butcher corpses without the need for finer tools.<br>\
However, Oxygen is incredibly toxic to you, in breathing it or consuming it. You can only breathe nitrogen."
// -- Outfit datums --
/datum/species/vox/final_equip(var/mob/living/carbon/human/H)
var/tank_slot = slot_s_store
var/tank_slot_name = "suit storage"
if(tank_slot)
H.equip_or_collect(new/obj/item/weapon/tank/nitrogen(H), tank_slot)
else
H.put_in_hands(new/obj/item/weapon/tank/nitrogen(H))
to_chat(H, "<span class='info'>You are now running on nitrogen internals from the [H.s_store] in your [tank_slot_name].</span>")
var/obj/item/weapon/tank/nitrogen/N = H.get_item_by_slot(tank_slot)
if(!N)
N = H.get_item_by_slot(slot_back)
H.internal = N
if (H.internals)
H.internals.icon_state = "internal1"
/datum/species/vox/makeName(var/gender,var/mob/living/carbon/human/H=null)
var/sounds = rand(3,8)
var/newname = ""
for(var/i = 1 to sounds)
newname += pick(vox_name_syllables)
return capitalize(newname)
/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H)
if(myhuman != H)
return
updatespeciescolor(H)
H.update_icon()
/datum/species/vox/updatespeciescolor(mob/living/carbon/human/vox)
var/datum/organ/external/tail/vox_tail = vox.get_cosmetic_organ(COSMETIC_ORGAN_TAIL)
switch(vox.my_appearance.s_tone)
if(VOXEMERALD)
icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxemrl.dmi'
if(VOXAZURE)
icobase = 'icons/mob/human_races/vox/r_voxazu.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxazu.dmi'
if(VOXLGREEN)
icobase = 'icons/mob/human_races/vox/r_voxlgrn.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxlgrn.dmi'
if(VOXGRAY)
icobase = 'icons/mob/human_races/vox/r_voxgry.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxgry.dmi'
if(VOXBROWN)
icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxbrn.dmi'
else
icobase = 'icons/mob/human_races/vox/r_vox.dmi'
deform = 'icons/mob/human_races/vox/r_def_vox.dmi'
if(vox_tail && (vox_tail.status & ORGAN_DESTROYED))
return
vox_tail.update_tail(vox)
/datum/species/skellington/skelevox // Science never goes too far, it's the public that's too conservative
name = "Skeletal Vox"
icobase = 'icons/mob/human_races/vox/r_voxboney.dmi'
deform = 'icons/mob/human_races/vox/r_voxboney.dmi' //Do bones deform noticeably?
known_languages = list(LANGUAGE_VOX, LANGUAGE_CLATTER)
survival_gear = /obj/item/weapon/storage/box/survival/vox
primitive = /mob/living/carbon/monkey/vox/skeletal
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
eyes = "vox_eyes_s"
default_mutations = list(M_BEAK, M_TALONS)
footprint_type = /obj/effect/decal/cleanable/blood/tracks/footprints/vox
uniform_icons = 'icons/mob/species/vox/uniform.dmi'
// fat_uniform_icons = 'icons/mob/uniform_fat.dmi'
gloves_icons = 'icons/mob/species/vox/gloves.dmi'
glasses_icons = 'icons/mob/species/vox/eyes.dmi'
// ears_icons = 'icons/mob/ears.dmi'
shoes_icons = 'icons/mob/species/vox/shoes.dmi'
head_icons = 'icons/mob/species/vox/head.dmi'
// belt_icons = 'icons/mob/belt.dmi'
wear_suit_icons = 'icons/mob/species/vox/suit.dmi'
wear_mask_icons = 'icons/mob/species/vox/masks.dmi'
// back_icons = 'icons/mob/back.dmi'
has_organ = list(
"brain" = /datum/organ/internal/brain,
"eyes" = /datum/organ/internal/eyes/vox
)
/datum/species/skellington/skelevox/makeName(var/gender,var/mob/living/carbon/human/H=null)
var/sounds = rand(3,8)
var/newname = ""
for(var/i = 1 to sounds)
newname += pick(vox_name_syllables)
return capitalize(newname)

View File

@@ -194,7 +194,8 @@ var/global/list/damage_icon_parts = list()
var/g = "m"
if(gender == FEMALE)
g = "f"
if(species && species.anatomy_flags & HAS_ICON_SKIN_TONE)
species.updatespeciescolor(src)
var/datum/organ/external/chest = get_organ(LIMB_CHEST)
stand_icon = chest.get_icon(g,fat)
if(!skeleton)
@@ -269,7 +270,15 @@ var/global/list/damage_icon_parts = list()
mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0)
husk_over.Blend(mask, ICON_ADD)
stand_icon.Blend(husk_over, ICON_OVERLAY)
var/datum/organ/external/tail/tail = get_cosmetic_organ(COSMETIC_ORGAN_TAIL)
if(tail && (!(tail.status & ORGAN_DESTROYED) && tail.overlap_overlays))
var/obj/abstract/Overlays/limbs_overlay = obj_overlays[LIMBS_LAYER]
var/mutable_appearance/stand_icon_image = mutable_appearance(stand_icon)
limbs_overlay.icon = stand_icon_image.icon
limbs_overlay.icon_state = stand_icon_image.icon_state
obj_to_plane_overlay(limbs_overlay, LIMBS_LAYER)
else
overlays -= obj_overlays[LIMBS_LAYER]
if(has_head)
//Eyes
if(!skeleton)
@@ -307,7 +316,7 @@ var/global/list/damage_icon_parts = list()
stand_icon -= rgb(0,0,0,lowest_alpha)
//tail
update_tail_showing(0)
update_tail_layer(FALSE)
//HAIR OVERLAY
@@ -523,6 +532,7 @@ var/global/list/damage_icon_parts = list()
update_inv_mutual_handcuffed(0)
update_inv_legcuffed(0)
update_inv_pockets(0)
update_tail_layer()
QueueUpdateDamageIcon(1)
update_icons()
//Hud Stuff
@@ -1298,10 +1308,7 @@ var/global/list/damage_icon_parts = list()
O.pixel_y = species.inventory_offsets["[slot_wear_suit]"]["pixel_y"] * PIXEL_MULTIPLIER
obj_to_plane_overlay(O,SUIT_LAYER)
//overlays_standing[SUIT_LAYER] = standing
update_tail_showing(0)
else
//overlays_standing[SUIT_LAYER] = null
update_tail_showing(0)
update_tail_layer()
if(update_icons)
update_icons()
@@ -1547,22 +1554,34 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1)
return update_inv_hand(GRASP_LEFT_HAND, update_icons)
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
//overlays_standing[TAIL_LAYER] = null
/mob/living/carbon/human/proc/update_tail_layer(update_icons = TRUE)
overlays -= obj_overlays[TAIL_UNDERLIMBS_LAYER]
overlays -= obj_overlays[TAIL_LAYER]
if(species && species.tail && species.anatomy_flags & HAS_TAIL)
if(!wear_suit || !is_slot_hidden(wear_suit.body_parts_covered, HIDEJUMPSUIT, 0, wear_suit.body_parts_visible_override))
var/obj/abstract/Overlays/O = obj_overlays[TAIL_LAYER]
O.icon = 'icons/effects/species.dmi'
O.icon_state = "[species.tail]_s"
obj_to_plane_overlay(O,TAIL_LAYER)
//if(!old_tail_state) //only update if we didnt show our tail already
//overlays_standing[TAIL_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s")
// to_chat(src, "update: tail is different")
//else
//overlays_standing[TAIL_LAYER] = null
var/datum/organ/external/tail/tail_organ = get_cosmetic_organ(COSMETIC_ORGAN_TAIL)
if(!tail_organ || (tail_organ.status & ORGAN_DESTROYED))
return
if(wear_suit || check_hidden_body_flags(HIDETAIL))
return
var/tail_file = tail_organ.tail_icon_file
var/tail_icon_state = tail_organ.icon_name
if(!tail_file || !tail_icon_state)
return
var/mutable_appearance/tail_image = mutable_appearance(tail_file, tail_icon_state, layer = -TAIL_LAYER)
if(species.anatomy_flags & MULTICOLOR)
tail_image.color = COLOR_MATRIX_ADD(rgb(multicolor_skin_r, multicolor_skin_g, multicolor_skin_b))
if(tail_organ.overlap_overlays) // Tail is overlapped by limbs, so we need special tail icon generation
// Gives the underlimbs layer SEW directions since it's overlayed by limbs and just about everything else anyway.
var/mutable_appearance/tail_underlimbs = mutable_appearance(tail_file, "[tail_icon_state]_BEHIND", -TAIL_UNDERLIMBS_LAYER)
var/obj/abstract/Overlays/underlimbs_overlay = obj_overlays[TAIL_UNDERLIMBS_LAYER]
underlimbs_overlay.icon = tail_underlimbs.icon
underlimbs_overlay.icon_state = tail_underlimbs.icon_state
obj_to_plane_overlay(underlimbs_overlay, TAIL_UNDERLIMBS_LAYER)
// North direction sprite before passing that to the tail layer that overlays uniforms and such.
tail_image.icon_state = "[tail_icon_state]_FRONT"
var/obj/abstract/Overlays/tail_overlay = obj_overlays[TAIL_LAYER]
tail_overlay.icon = tail_image.icon
tail_overlay.icon_state = tail_image.icon_state
obj_to_plane_overlay(tail_overlay, TAIL_LAYER)
if(update_icons)
update_icons()

View File

@@ -42,7 +42,10 @@ var/global/list/playable_species = list("Human")
var/eyes = "eyes_s" // Icon for eyes.
var/primitive // Lesser form, if any (ie. monkey for humans)
var/tail // Name of tail image in species effects icon file.
var/tail // Name of tail icon state
var/tail_icon = 'icons/mob/tails.dmi'
var/tail_type
var/tail_overlapping = TRUE
var/list/known_languages = list(LANGUAGE_GALACTIC_COMMON) // Languages that this species innately knows.
var/default_language = LANGUAGE_GALACTIC_COMMON // Default language is used when 'say' is used without modifiers.
var/attack_verb = "punches" // Empty hand hurt intent verb.
@@ -204,9 +207,15 @@ var/global/list/playable_species = list("Human")
for(var/datum/organ/I in H.internal_organs)
qdel(I)
H.internal_organs.len=0
if(H.cosmetic_organs)
for(var/organ in H.cosmetic_organs)
qdel(organ)
H.cosmetic_organs.len=0
//The rest SHOULD only refer to organs that were already deleted by the above loops, so we can just clear the lists.
if(H.organs_by_name)
H.organs_by_name.len=0
if(H.cosmetic_organs_by_name)
H.cosmetic_organs_by_name.len = 0
if(H.internal_organs_by_name)
H.internal_organs_by_name.len=0
if(H.grasp_organs)
@@ -219,6 +228,7 @@ var/global/list/playable_species = list("Human")
//This is a basic humanoid limb setup.
H.organs = list()
H.cosmetic_organs = list()
H.organs_by_name[LIMB_CHEST] = new/datum/organ/external/chest()
H.organs_by_name[LIMB_GROIN] = new/datum/organ/external/groin(H.organs_by_name[LIMB_CHEST])
H.organs_by_name[LIMB_HEAD] = new/datum/organ/external/head(H.organs_by_name[LIMB_CHEST])
@@ -231,6 +241,8 @@ var/global/list/playable_species = list("Human")
H.organs_by_name[LIMB_LEFT_FOOT] = new/datum/organ/external/l_foot(H.organs_by_name[LIMB_LEFT_LEG])
H.organs_by_name[LIMB_RIGHT_FOOT] = new/datum/organ/external/r_foot(H.organs_by_name[LIMB_RIGHT_LEG])
H.cosmetic_organs_by_name[COSMETIC_ORGAN_TAIL] = new/datum/organ/external/tail(H.organs_by_name[LIMB_GROIN], src)
H.internal_organs = list()
for(var/organ in has_organ)
var/organ_type = has_organ[organ]
@@ -245,9 +257,13 @@ var/global/list/playable_species = list("Human")
H.organs += OE
if(OE.grasp_id)
H.grasp_organs += OE
for(var/datum/organ/external/O in H.organs)
O.owner = H
for(var/organ in H.cosmetic_organs_by_name)
var/datum/organ/external/cosmetic_organ = H.cosmetic_organs_by_name[organ]
H.cosmetic_organs += cosmetic_organ
for(var/datum/organ/external/external_organ in H.organs)
external_organ.owner = H
for(var/datum/organ/external/cosmetic_organ as anything in H.cosmetic_organs)
cosmetic_organ.owner = H
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
return
@@ -385,7 +401,8 @@ var/global/list/playable_species = list("Human")
icobase = 'icons/mob/human_races/r_lizard.dmi'
deform = 'icons/mob/human_races/r_def_lizard.dmi'
known_languages = list(LANGUAGE_UNATHI)
tail = "sogtail"
tail = "unathi"
tail_type = "unathi"
attack_verb = "scratches"
punch_damage = 2
primitive = /mob/living/carbon/monkey/unathi
@@ -467,61 +484,13 @@ var/global/list/playable_species = list("Human")
H.drop_all()
qdel(src)
/datum/species/skellington/skelevox // Science never goes too far, it's the public that's too conservative
name = "Skeletal Vox"
icobase = 'icons/mob/human_races/vox/r_voxboney.dmi'
deform = 'icons/mob/human_races/vox/r_voxboney.dmi' //Do bones deform noticeably?
known_languages = list(LANGUAGE_VOX, LANGUAGE_CLATTER)
survival_gear = /obj/item/weapon/storage/box/survival/vox
primitive = /mob/living/carbon/monkey/vox/skeletal
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
eyes = "vox_eyes_s"
default_mutations = list(M_BEAK, M_TALONS)
footprint_type = /obj/effect/decal/cleanable/blood/tracks/footprints/vox
uniform_icons = 'icons/mob/species/vox/uniform.dmi'
// fat_uniform_icons = 'icons/mob/uniform_fat.dmi'
gloves_icons = 'icons/mob/species/vox/gloves.dmi'
glasses_icons = 'icons/mob/species/vox/eyes.dmi'
// ears_icons = 'icons/mob/ears.dmi'
shoes_icons = 'icons/mob/species/vox/shoes.dmi'
head_icons = 'icons/mob/species/vox/head.dmi'
// belt_icons = 'icons/mob/belt.dmi'
wear_suit_icons = 'icons/mob/species/vox/suit.dmi'
wear_mask_icons = 'icons/mob/species/vox/masks.dmi'
// back_icons = 'icons/mob/back.dmi'
has_organ = list(
"brain" = /datum/organ/internal/brain,
"eyes" = /datum/organ/internal/eyes/vox
)
/datum/species/skellington/skelevox/makeName(var/gender,var/mob/living/carbon/human/H=null)
var/sounds = rand(3,8)
var/newname = ""
for(var/i = 1 to sounds)
newname += pick(vox_name_syllables)
return capitalize(newname)
/datum/species/tajaran
name = "Tajaran"
icobase = 'icons/mob/human_races/r_tajaran.dmi'
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
known_languages = list(LANGUAGE_CATBEAST, LANGUAGE_MOUSE)
tail = "tajtail"
tail = "tajaran_brown"
tail_type = "tajaran"
attack_verb = "scratches"
punch_damage = 2 //Claws add 3 damage without gloves, so the total is 5
@@ -536,7 +505,7 @@ var/global/list/playable_species = list("Human")
primitive = /mob/living/carbon/monkey/tajara
flags = WHITELISTED
anatomy_flags = HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL | HAS_SWEAT_GLANDS
anatomy_flags = HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL | HAS_SWEAT_GLANDS | HAS_ICON_SKIN_TONE
default_mutations=list(M_CLAWS)
@@ -568,18 +537,20 @@ var/global/list/playable_species = list("Human")
updatespeciescolor(H)
H.update_icon()
/datum/species/tajaran/updatespeciescolor(var/mob/living/carbon/human/H)
switch(H.my_appearance.s_tone)
/datum/species/tajaran/updatespeciescolor(mob/living/carbon/human/tajaran)
var/datum/organ/external/tail/tajaran_tail = tajaran.get_cosmetic_organ(COSMETIC_ORGAN_TAIL)
switch(tajaran.my_appearance.s_tone)
if(CATBEASTBLACK)
icobase = 'icons/mob/human_races/r_tajaranblack.dmi'
deform = 'icons/mob/human_races/r_def_tajaranblack.dmi'
tail = "tajtailb"
H.my_appearance.h_style = "Black Tajaran Ears"
tajaran.my_appearance.h_style = "Black Tajaran Ears"
else
icobase = 'icons/mob/human_races/r_tajaran.dmi'
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
tail = "tajtail"
H.my_appearance.h_style = "Tajaran Ears"
tajaran.my_appearance.h_style = "Tajaran Ears"
if(tajaran_tail && (tajaran_tail.status & ORGAN_DESTROYED))
return
tajaran_tail.update_tail(tajaran)
/datum/species/tajaran/handle_speech(var/datum/speech/speech, mob/living/carbon/human/H)
if (prob(15))
@@ -610,7 +581,7 @@ var/global/list/playable_species = list("Human")
primitive = /mob/living/carbon/monkey/grey
flags = PLAYABLE | WHITELISTED
anatomy_flags = HAS_LIPS | HAS_SWEAT_GLANDS | ACID4WATER
anatomy_flags = HAS_LIPS | HAS_SWEAT_GLANDS | ACID4WATER | HAS_ICON_SKIN_TONE
spells = list(/spell/targeted/telepathy)
@@ -736,114 +707,6 @@ var/global/list/playable_species = list("Human")
head_icons = 'icons/mob/species/skrell/head.dmi'
wear_suit_icons = 'icons/mob/species/skrell/suit.dmi'
/datum/species/vox
name = "Vox"
icobase = 'icons/mob/human_races/vox/r_vox.dmi'
deform = 'icons/mob/human_races/vox/r_def_vox.dmi'
known_languages = list(LANGUAGE_VOX)
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/rawchicken/vox
tacklePower = 40
anatomy_flags = HAS_SWEAT_GLANDS
survival_gear = /obj/item/weapon/storage/box/survival/vox
primitive = /mob/living/carbon/monkey/vox
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
eyes = "vox_eyes_s"
breath_type = GAS_NITROGEN
default_mutations = list(M_BEAK, M_TALONS)
flags = PLAYABLE | WHITELISTED
blood_color = VOX_BLOOD
flesh_color = "#808D11"
max_skin_tone = 6
footprint_type = /obj/effect/decal/cleanable/blood/tracks/footprints/vox //Bird claws
uniform_icons = 'icons/mob/species/vox/uniform.dmi'
// fat_uniform_icons = 'icons/mob/uniform_fat.dmi'
gloves_icons = 'icons/mob/species/vox/gloves.dmi'
glasses_icons = 'icons/mob/species/vox/eyes.dmi'
// ears_icons = 'icons/mob/ears.dmi'
shoes_icons = 'icons/mob/species/vox/shoes.dmi'
head_icons = 'icons/mob/species/vox/head.dmi'
// belt_icons = 'icons/mob/belt.dmi'
wear_suit_icons = 'icons/mob/species/vox/suit.dmi'
wear_mask_icons = 'icons/mob/species/vox/masks.dmi'
back_icons = 'icons/mob/species/vox/back.dmi'
has_mutant_race = 0
has_organ = list(
"heart" = /datum/organ/internal/heart/vox,
"lungs" = /datum/organ/internal/lungs/vox,
"liver" = /datum/organ/internal/liver,
"kidneys" = /datum/organ/internal/kidney,
"brain" = /datum/organ/internal/brain,
"appendix" = /datum/organ/internal/appendix,
"eyes" = /datum/organ/internal/eyes/vox
)
species_intro = "You are a Vox.<br>\
You are somewhat more adept at handling the lower pressures of space and colder temperatures.<br>\
You have talons with which you can slice others in a fist fight, and a beak which can be used to butcher corpses without the need for finer tools.<br>\
However, Oxygen is incredibly toxic to you, in breathing it or consuming it. You can only breathe nitrogen."
// -- Outfit datums --
/datum/species/vox/final_equip(var/mob/living/carbon/human/H)
var/tank_slot = slot_s_store
var/tank_slot_name = "suit storage"
if(tank_slot)
H.equip_or_collect(new/obj/item/weapon/tank/nitrogen(H), tank_slot)
else
H.put_in_hands(new/obj/item/weapon/tank/nitrogen(H))
to_chat(H, "<span class='info'>You are now running on nitrogen internals from the [H.s_store] in your [tank_slot_name].</span>")
var/obj/item/weapon/tank/nitrogen/N = H.get_item_by_slot(tank_slot)
if(!N)
N = H.get_item_by_slot(slot_back)
H.internal = N
if (H.internals)
H.internals.icon_state = "internal1"
/datum/species/vox/makeName(var/gender,var/mob/living/carbon/human/H=null)
var/sounds = rand(3,8)
var/newname = ""
for(var/i = 1 to sounds)
newname += pick(vox_name_syllables)
return capitalize(newname)
/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H)
if(myhuman != H)
return
updatespeciescolor(H)
H.update_icon()
/datum/species/vox/updatespeciescolor(var/mob/living/carbon/human/H)
switch(H.my_appearance.s_tone)
if(6)
icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxemrl.dmi'
if(5)
icobase = 'icons/mob/human_races/vox/r_voxazu.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxazu.dmi'
if(4)
icobase = 'icons/mob/human_races/vox/r_voxlgrn.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxlgrn.dmi'
if(3)
icobase = 'icons/mob/human_races/vox/r_voxgry.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxgry.dmi'
if(2)
icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi'
deform = 'icons/mob/human_races/vox/r_def_voxbrn.dmi'
else
icobase = 'icons/mob/human_races/vox/r_vox.dmi'
deform = 'icons/mob/human_races/vox/r_def_vox.dmi'
/datum/species/diona
name = "Diona"
icobase = 'icons/mob/human_races/r_plant.dmi'
@@ -1421,4 +1284,4 @@ var/list/has_died_as_golem = list()
head_organ.droplimb(1,1)
H.drop_all()
qdel(src)
qdel(src)

View File

@@ -352,6 +352,9 @@ var/list/animals_with_wings = list(
else
alert("Unable to use this emote, must be either hearable or visible.")
return
var/display_runechat = input("Display Runechat?") as null|anything in list("Yes", "No")
if(display_runechat == "No")
emote_type |= EMOTE_NO_RUNECHAT
message = custom_emote
else
message = params

View File

@@ -174,25 +174,25 @@
if(current_species)
if(current_species.name == "Vox")
switch(s_tone)
if(6)
if(VOXEMERALD)
icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi'
if(5)
if(VOXAZURE)
icobase = 'icons/mob/human_races/vox/r_voxazu.dmi'
if(4)
if(VOXLGREEN)
icobase = 'icons/mob/human_races/vox/r_voxlgrn.dmi'
if(3)
if(VOXGRAY)
icobase = 'icons/mob/human_races/vox/r_voxgry.dmi'
if(2)
if(VOXBROWN)
icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi'
else
icobase = 'icons/mob/human_races/vox/r_vox.dmi'
else if(current_species.name == "Grey")
switch(s_tone)
if(4)
if(GREYBLUE)
icobase = 'icons/mob/human_races/grey/r_greyblue.dmi'
if(3)
if(GREYGREEN)
icobase = 'icons/mob/human_races/grey/r_greygreen.dmi'
if(2)
if(GREYLIGHT)
icobase = 'icons/mob/human_races/grey/r_greylight.dmi'
else
icobase = 'icons/mob/human_races/grey/r_grey.dmi'
@@ -230,7 +230,31 @@
var/icon/temp = new /icon(o_icobase, "[name]")
preview_icon.Blend(temp, ICON_OVERLAY)
//Tail
if(current_species && (current_species.anatomy_flags & HAS_TAIL))
var/tail_icon_state = current_species.tail
if(current_species.name == "Vox")
switch(s_tone)
if(VOXEMERALD)
tail_icon_state = "emerald"
if(VOXAZURE)
tail_icon_state = "azure"
if(VOXLGREEN)
tail_icon_state = "lightgreen"
if(VOXGRAY)
tail_icon_state = "grey"
if(VOXBROWN)
tail_icon_state = "brown"
else
tail_icon_state = "green"
if(current_species.name == "Tajaran")
switch(s_tone)
if(CATBEASTBLACK)
tail_icon_state = "tajaran_black"
else
tail_icon_state = "tajaran_brown"
var/icon/temp_tail_icon = icon(current_species.tail_icon, "[tail_icon_state]_BEHIND")
preview_icon.Blend(temp_tail_icon, ICON_UNDERLAY)
// Skin tone
if(current_species && (current_species.anatomy_flags & HAS_SKIN_TONE))
if (s_tone >= 0)

View File

@@ -78,7 +78,9 @@
W.time_inflicted = world.time
/mob/living/carbon/human/var/list/organs = list()
/mob/living/carbon/human/var/list/cosmetic_organs = list()
/mob/living/carbon/human/var/list/datum/organ/external/organs_by_name = list() //Map organ names to organs
/mob/living/carbon/human/var/list/datum/organ/external/cosmetic_organs_by_name = list()
/mob/living/carbon/human/var/list/datum/organ/internal/internal_organs_by_name = list() //So internal organs have less ickiness too
/mob/living/carbon/human/var/list/grasp_organs = list()

View File

@@ -50,7 +50,7 @@
var/wound_update_accuracy = 1
var/has_fat = 0 //Has a _fat variant
var/cosmetic_only = FALSE
var/grasp_id = 0 //Does this organ affect other grasping organs?
var/can_grasp = 0 //Can this organ actually grasp something?
@@ -154,6 +154,8 @@
droplimb(1, spawn_limb = 0, display_message = FALSE)
/datum/organ/external/proc/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
if(cosmetic_only)
return
if(owner?.status_flags & GODMODE)
return 0 //godmode
if((brute <= 0) && (burn <= 0))
@@ -277,6 +279,8 @@
return result
/datum/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0)
if(cosmetic_only)
return
if(is_robotic() && !robo_repair) //This item can't fix robotic limbs
return
@@ -330,6 +334,8 @@
owner.updatehealth()
/datum/organ/external/proc/createwound(var/type = CUT, var/damage)
if(cosmetic_only)
return
if(!damage || damage < 0) //We weren't passed a damage value, or it's negative for some reason
return
@@ -409,7 +415,6 @@
return 0
/datum/organ/external/process()
//Process wounds, doing healing etc. Only do this every few ticks to save processing power
if(owner.life_tick % wound_update_accuracy == 0)
update_wounds()
@@ -448,7 +453,6 @@
//Cancer growth for external organs is simple, it grows, hurts, damages, and suddenly grows out of control
//Limb cancer is relatively benign until it grows large, then it cripples you and metastases
/datum/organ/external/handle_cancer()
if(..())
return 1
@@ -500,6 +504,8 @@ Note that amputating the affected organ does in fact remove the infection from t
*/
/datum/organ/external/proc/update_germs()
if(cosmetic_only)
return
if(!is_existing() || !is_organic()) //Needs to be organic and existing
germ_level = 0
return
@@ -590,7 +596,8 @@ Note that amputating the affected organ does in fact remove the infection from t
//Updating wounds. Handles wound natural healing, internal bleedings and infections
/datum/organ/external/proc/update_wounds()
if(cosmetic_only)
return
if(!is_organic()) //Non-organic limbs don't heal or get worse
return
@@ -748,7 +755,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(body_part == (UPPER_TORSO || LOWER_TORSO)) //We can't lose either, those cannot be amputated and will cause extremely serious problems
return
var/datum/species/species = src.species || owner.species
var/datum/species/species = src.species || owner?.species
var/obj/item/organ/external/organ //Dropped limb object
if(override)
@@ -837,7 +844,8 @@ Note that amputating the affected organ does in fact remove the infection from t
//Throw organs around
var/randomdir = pick(cardinal)
step(organ, randomdir)
if(!owner)
return organ
owner.update_body(1)
owner.handle_organs(1)
@@ -873,7 +881,7 @@ Note that amputating the affected organ does in fact remove the infection from t
O.removed(owner,owner)
O.loc = headloc
QDEL_NULL(organ)
organ?.update_icon()
return organ
/datum/organ/external/proc/get_organ_item()
@@ -941,6 +949,8 @@ Note that amputating the affected organ does in fact remove the infection from t
return rval
/datum/organ/external/proc/clamp_wounds() //Inconsistent with the other names but clamp is a reserved word now
if(cosmetic_only)
return
var/rval = 0
src.status &= ~ORGAN_BLEEDING
for(var/datum/wound/W in wounds)
@@ -958,6 +968,8 @@ Note that amputating the affected organ does in fact remove the infection from t
return rval
/datum/organ/external/proc/fracture()
if(cosmetic_only)
return
if(owner?.status_flags & GODMODE)
return 0 //godmode
var/datum/species/species = src.species || owner.species
@@ -1053,7 +1065,7 @@ Note that amputating the affected organ does in fact remove the infection from t
src.status = organ.status
src.brute_dam = organ.brute_dam
src.burn_dam = organ.burn_dam
on_attach(organ)
owner.butchering_drops += organ.butchering_drops
//Transfer any internal_organs from the organ item to the body
@@ -1086,7 +1098,7 @@ Note that amputating the affected organ does in fact remove the infection from t
else if(istype(I, /obj/item/robot_parts)) //Robotic limb
var/obj/item/robot_parts/R = I
R.on_attach(src)
src.robotize()
src.sabotaged = R.sabotaged
@@ -1103,6 +1115,9 @@ Note that amputating the affected organ does in fact remove the infection from t
owner.updatehealth()
owner.UpdateDamageIcon()
/datum/organ/external/proc/on_attach()
return
/datum/organ/external/proc/mutate()
src.status |= ORGAN_MUTATED
owner.update_body()
@@ -1247,6 +1262,85 @@ Note that amputating the affected organ does in fact remove the infection from t
body_part = LOWER_TORSO
vital = 1
/datum/organ/external/tail
name = COSMETIC_ORGAN_TAIL
display_name = "tail"
icon_name = "tail"
max_damage = 75
min_broken_damage = 30
body_part = TAIL
cosmetic_only = TRUE
var/tail_icon_file = 'icons/mob/tails.dmi'
var/tail_type
var/overlap_overlays = TRUE
/datum/organ/external/tail/New(datum/organ/external/parent, datum/species/passed_species)
if(passed_species && (!(passed_species.anatomy_flags & HAS_TAIL)))
droplimb(TRUE, spawn_limb = FALSE)
return
create_tail_info(passed_species)
return ..()
/datum/organ/external/tail/proc/create_tail_info(datum/species/passed_species, obj/item/organ/external/tail/tail_item)
icon_name = passed_species?.tail || tail_item?.tail_state_name
tail_icon_file = passed_species?.tail_icon || tail_item?.tail_icon_file
tail_type = passed_species?.tail_type || tail_item?.tail_type
overlap_overlays = passed_species?.tail_overlapping || tail_item?.tail_overlapping
/datum/organ/external/tail/generate_dropped_organ(current_organ)
if(!current_organ)
if(is_robotic())
current_organ = new /obj/item/robot_parts/tail(owner.loc, tail_type)
else
current_organ = new /obj/item/organ/external/tail(owner.loc, owner, src)
return current_organ
/datum/organ/external/tail/on_attach(obj/item/organ/external/tail/tail_item)
create_tail_info(tail_item = tail_item)
/datum/organ/external/tail/proc/update_tail(mob/living/carbon/human/tail_owner, skin_tone, random = FALSE)
if(!skin_tone)
skin_tone = tail_owner?.my_appearance.s_tone || owner?.my_appearance.s_tone
if(is_robotic(src))
icon_name = "[tail_type]_robotic"
else
switch(tail_type)
if("vox")
if(random)
skin_tone = rand(1, 6)
switch(skin_tone)
if(VOXEMERALD)
icon_name = "emerald"
if(VOXAZURE)
icon_name = "azure"
if(VOXLGREEN)
icon_name = "lightgreen"
if(VOXGRAY)
icon_name = "grey"
if(VOXBROWN)
icon_name = "brown"
else
icon_name = "green"
if("tajaran")
if(random)
skin_tone = rand(1, 2)
switch(skin_tone)
if(CATBEASTBLACK)
icon_name = "tajaran_black"
else
icon_name = "tajaran_brown"
var/mob/living/carbon/human/tail_haver = tail_owner || owner
tail_haver?.update_tail_layer()
/datum/organ/external/tail/robotize()
tail_icon_file = initial(tail_icon_file)
..()
if(owner)
update_tail(owner)
/datum/organ/external/tail/peggify()
return
//=====Legs======
/datum/organ/external/l_leg
@@ -1607,6 +1701,7 @@ Note that amputating the affected organ does in fact remove the infection from t
..(loc)
if(!istype(H))
return
post_creation(source)
if(H.dna)
owner_dna = H.dna.Clone()
if(!blood_DNA)
@@ -1641,6 +1736,9 @@ Note that amputating the affected organ does in fact remove the infection from t
//The reason why B isn't just transferred from H.butchering_drops to src.butchering_drops is:
//on examine(), each butchering drop's "desc_modifier()" is added to the description. This adds stuff like "he HAS NO TEETH AT ALL!!!" to the resulting description.
/obj/item/organ/external/proc/post_creation(datum/organ/external/organ_datum)
return
/obj/item/organ/external/examine(mob/user)
..()
@@ -1675,8 +1773,6 @@ Note that amputating the affected organ does in fact remove the infection from t
to_chat(user, "<span class='warning'>[butchery]</span>")
/obj/item/organ/external/update_icon(mob/living/carbon/human/H)
..()
if(!H && !species)
return
@@ -1804,6 +1900,34 @@ Note that amputating the affected organ does in fact remove the infection from t
if(B)
B.infest_limb(src)
/obj/item/organ/external/tail
name = "tail"
part = COSMETIC_ORGAN_TAIL
w_class = W_CLASS_SMALL
var/tail_icon_file
var/tail_type
var/tail_icon_key
var/tail_state_name
var/tail_overlapping = TRUE
var/static/list/tail_organ_icons = list()
/obj/item/organ/external/tail/post_creation(datum/organ/external/tail/organ_datum)
tail_icon_file = organ_datum.tail_icon_file
tail_state_name = organ_datum.icon_name
tail_type = organ_datum.tail_type
tail_overlapping = organ_datum.overlap_overlays
update_icon()
/obj/item/organ/external/tail/update_icon()
tail_icon_key = "[tail_state_name]_[tail_type]"
var/returned_tail_icon = tail_organ_icons[tail_icon_key]
if(!returned_tail_icon)
var/icon/new_tail_icon = icon(tail_icon_file, "[tail_state_name]_BEHIND", EAST)
new_tail_icon.Shift(EAST, 6)
new_tail_icon.Shift(NORTH, 3)
returned_tail_icon = tail_organ_icons[tail_icon_key] = new_tail_icon
icon = returned_tail_icon
/obj/item/organ/external/head
dir = NORTH
name = LIMB_HEAD
@@ -2030,6 +2154,8 @@ Note that amputating the affected organ does in fact remove the infection from t
return FALSE
/datum/organ/external/send_to_past(var/duration)
if(cosmetic_only)
return
..()
var/static/list/resettable_vars = list(
"damage_state",

View File

@@ -9,6 +9,12 @@
/obj/abstract/Overlays/mutantrace_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - MUTANTRACE_LAYER)
/obj/abstract/Overlays/tail_underlimbs_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - TAIL_UNDERLIMBS_LAYER)
/obj/abstract/Overlays/limbs_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - LIMBS_LAYER)
/obj/abstract/Overlays/mutations_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - MUTATIONS_LAYER)
@@ -45,6 +51,9 @@
/obj/abstract/Overlays/glasses_over_hair_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - GLASSES_OVER_HAIR_LAYER)
/obj/abstract/Overlays/tail_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - TAIL_LAYER)
/obj/abstract/Overlays/facemask_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - FACEMASK_LAYER)
@@ -69,9 +78,6 @@
/obj/abstract/Overlays/hand_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - HAND_LAYER)
/obj/abstract/Overlays/tail_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - TAIL_LAYER)
/obj/abstract/Overlays/targeted_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - TARGETED_LAYER)
@@ -84,6 +90,8 @@
/*
var/obj/abstract/Overlays/fire_layer/fire_layer = new
var/obj/abstract/Overlays/mutantrace_layer/mutantrace_layer = new
var/obj/abstract/Overlays/tail_underlimbs_layer/tail_underlimbs_layer = new
var/obj/abstract/Overlays/limbs_layer/limbs_layer = new
var/obj/abstract/Overlays/mutations_layer/mutations_layer = new
var/obj/abstract/Overlays/damage_layer/damage_layer = new
var/obj/abstract/Overlays/uniform_layer/uniform_layer = new
@@ -98,12 +106,12 @@
var/obj/abstract/Overlays/back_layer/back_layer = new
var/obj/abstract/Overlays/hair_layer/hair_layer = new
var/obj/abstract/Overlays/glasses_over_hair_layer/glasses_over_hair_layer = new
var/obj/abstract/Overlays/tail_layer/tail_layer = new
var/obj/abstract/Overlays/facemask_layer/facemask_layer = new
var/obj/abstract/Overlays/head_layer/head_layer = new
var/obj/abstract/Overlays/handcuff_layer/handcuff_layer = new
var/obj/abstract/Overlays/legcuff_layer/legcuff_layer = new
var/obj/abstract/Overlays/l_hand_layer/l_hand_layer = new
var/obj/abstract/Overlays/r_hand_layer/r_hand_layer = new
var/obj/abstract/Overlays/tail_layer/tail_layer = new
var/obj/abstract/Overlays/targeted_layer/targeted_layer = new
*/

View File

@@ -58,6 +58,16 @@
category = "Robot"
materials = list(MAT_IRON=15000)
/datum/design/robot/tail
name = "Cyborg Component (Robot tail)"
desc = "Used to build a Robot tail."
id = "robot_tail"
req_tech = list(Tc_ENGINEERING = 1)
build_type = MECHFAB
build_path = /obj/item/robot_parts/tail
category = "Robot"
materials = list(MAT_IRON=15000)
/datum/design/robot/head
name = "Cyborg Component (Robot head)"
desc = "Used to build a Robot head."
@@ -198,4 +208,4 @@
build_type = MECHFAB
build_path = /obj/item/robot_parts/robot_component/armour/reinforced
category = "Robot_Part"
materials = list(MAT_IRON=5000, MAT_DIAMOND=5000)
materials = list(MAT_IRON=5000, MAT_DIAMOND=5000)

View File

@@ -5,6 +5,7 @@
/datum/surgery_step/generic/
can_infect = 1
supports_cosmetic_organs = TRUE
var/painful=1
/datum/surgery_step/generic/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -14,7 +15,7 @@
return 0
if (!hasorgans(target))
return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
if (affected == null)
return 0
if (affected.status & ORGAN_DESTROYED)
@@ -40,7 +41,6 @@
)
priority = 0.1 //so the tool checks for this step before /generic/cut_open
duration = 4 SECONDS
/datum/surgery_step/generic/cut_with_laser/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -48,29 +48,30 @@
if(target.species && (target.species.anatomy_flags & NO_SKIN))
to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
return affected.open == 0 && target_zone != "mouth"
/datum/surgery_step/generic/cut_with_laser/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] starts the bloodless incision on [target]'s [affected.display_name] with \the [tool].", \
"You start the bloodless incision on [target]'s [affected.display_name] with \the [tool].")
target.custom_pain("You feel a horrible, searing pain in your [affected.display_name]!",1, scream=TRUE)
..()
/datum/surgery_step/generic/cut_with_laser/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] has made a bloodless incision on [target]'s [affected.display_name] with \the [tool].</span>", \
"<span class='notice'>You have made a bloodless incision on [target]'s [affected.display_name] with \the [tool].</span>",)
//Could be cleaner ...
affected.open = 1
affected.status |= ORGAN_BLEEDING
if(!affected.cosmetic_only)
affected.status |= ORGAN_BLEEDING
affected.createwound(CUT, 1)
affected.clamp_wounds()
//spread_germs_to_organ(affected, user) //a laser scalpel shouldn't spread germs.
/datum/surgery_step/generic/cut_with_laser/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='warning'>[user]'s hand slips as the blade sputters, searing a long gash in [target]'s [affected.display_name] with \the [tool]!</span>", \
"<span class='warning'>Your hand slips as the blade sputters, searing a long gash in [target]'s [affected.display_name] with \the [tool]!</span>")
affected.createwound(CUT, 7.5)
@@ -88,7 +89,6 @@
)
priority = 0.1 //so the tool checks for this step before /generic/cut_open
duration = 8 SECONDS
/datum/surgery_step/generic/incision_manager/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -97,11 +97,11 @@
to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
return affected.open == 0 && target_zone != "mouth"
/datum/surgery_step/generic/incision_manager/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] starts to construct a prepared incision on and within [target]'s [affected.display_name] with \the [tool].", \
"You start to construct a prepared incision on and within [target]'s [affected.display_name] with \the [tool].")
target.custom_pain("You feel a horrible, searing pain in your [affected.display_name] as it is pushed apart!",1, scream=TRUE)
@@ -111,18 +111,19 @@
..()
/datum/surgery_step/generic/incision_manager/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] has constructed a prepared incision on and within [target]'s [affected.display_name] with \the [tool].</span>", \
"<span class='notice'>You have constructed a prepared incision on and within [target]'s [affected.display_name] with \the [tool].</span>",)
affected.open = 1
affected.status |= ORGAN_BLEEDING
if(!affected.cosmetic_only)
affected.status |= ORGAN_BLEEDING
affected.createwound(CUT, 1)
affected.clamp_wounds()
affected.open = 2
tool.icon_state = "[initial(tool.icon_state)]_off"
/datum/surgery_step/generic/incision_manager/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='warning'>[user]'s hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.display_name] with \the [tool]!</span>", \
"<span class='warning'>Your hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.display_name] with \the [tool]!</span>")
affected.createwound(CUT, 20)
@@ -148,7 +149,6 @@
)
priority = 0
duration = 4 SECONDS
/datum/surgery_step/generic/cut_open/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -157,28 +157,29 @@
to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
if(. && !affected.open && target_zone != "mouth")
return .
return 0
/datum/surgery_step/generic/cut_open/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] starts the incision on [target]'s [affected.display_name] with \the [tool].", \
"You start the incision on [target]'s [affected.display_name] with \the [tool].")
target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.display_name]!",1, scream=TRUE)
..()
/datum/surgery_step/generic/cut_open/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] has made an incision on [target]'s [affected.display_name] with \the [tool].</span>", \
"<span class='notice'>You have made an incision on [target]'s [affected.display_name] with \the [tool].</span>",)
affected.open = 1
affected.status |= ORGAN_BLEEDING
if(!affected.cosmetic_only)
affected.status |= ORGAN_BLEEDING
affected.createwound(CUT, 1)
/datum/surgery_step/generic/cut_open/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='warning'>[user]'s hand slips, slicing open [target]'s [affected.display_name] in the wrong place with \the [tool]!</span>", \
"<span class='warning'>Your hand slips, slicing open [target]'s [affected.display_name] in the wrong place with \the [tool]!</span>")
affected.createwound(CUT, 10)
@@ -193,7 +194,7 @@
/obj/item/weapon/talisman = 70,
/obj/item/device/assembly/mousetrap = 20,
)
supports_cosmetic_organs = FALSE
duration = 3 SECONDS
/datum/surgery_step/generic/clamp_bleeders/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -234,7 +235,6 @@
/obj/item/tool/crowbar = 75,
/obj/item/weapon/kitchen/utensil/fork = 50
)
duration = 3 SECONDS
/datum/surgery_step/generic/retract_skin/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -243,11 +243,11 @@
to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
return affected.open == 1 //&& !(affected.status & ORGAN_BLEEDING)
/datum/surgery_step/generic/retract_skin/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
var/msg = "[user] starts to pry open the incision on [target]'s [affected.display_name] with \the [tool]."
var/self_msg = "You start to pry open the incision on [target]'s [affected.display_name] with \the [tool]."
if (target_zone == LIMB_CHEST)
@@ -261,7 +261,7 @@
..()
/datum/surgery_step/generic/retract_skin/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
var/msg = "<span class='notice'>[user] keeps the incision open on [target]'s [affected.display_name] with \the [tool].</span>"
var/self_msg = "<span class='notice'>You keep the incision open on [target]'s [affected.display_name] with \the [tool].</span>"
if (target_zone == LIMB_CHEST)
@@ -274,7 +274,7 @@
affected.open = 2
/datum/surgery_step/generic/retract_skin/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
var/msg = "<span class='warning'>[user]'s hand slips, tearing the edges of the incision on [target]'s [affected.display_name] with \the [tool]!</span>"
var/self_msg = "<span class='warning'>Your hand slips, tearing the edges of the incision on [target]'s [affected.display_name] with \the [tool]!</span>"
if (target_zone == LIMB_CHEST)
@@ -303,7 +303,6 @@
/obj/item/weapon/lighter = 50,
/obj/item/tool/weldingtool = 25,
)
duration = 3 SECONDS
/datum/surgery_step/generic/cauterize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -312,18 +311,18 @@
to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
return affected.open && target_zone != "mouth"
/datum/surgery_step/generic/cauterize/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.display_name] with \the [tool]." , \
"You are beginning to cauterize the incision on [target]'s [affected.display_name] with \the [tool].")
target.custom_pain("Your [affected.display_name] is being burned!",1, scream=TRUE)
..()
/datum/surgery_step/generic/cauterize/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] cauterizes the incision on [target]'s [affected.display_name] with \the [tool].</span>", \
"<span class='notice'>You cauterize the incision on [target]'s [affected.display_name] with \the [tool].</span>")
affected.open = 0
@@ -331,7 +330,7 @@
affected.status &= ~ORGAN_BLEEDING
/datum/surgery_step/generic/cauterize/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='warning'>[user]'s hand slips, leaving a small burn on [target]'s [affected.display_name] with \the [tool]!</span>", \
"<span class='warning'>Your hand slips, leaving a small burn on [target]'s [affected.display_name] with \the [tool]!</span>")
target.apply_damage(3, BURN, affected)
@@ -345,7 +344,6 @@
/obj/item/weapon/kitchen/utensil/knife/large/butch = 75,
/obj/item/weapon/hatchet = 75,
)
duration = 11 SECONDS
/datum/surgery_step/generic/cut_limb/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -353,7 +351,7 @@
return 0
if (!hasorgans(target))
return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
if (affected == null)
return 0
if (affected.status & ORGAN_DESTROYED)
@@ -363,14 +361,14 @@
return target_zone != LIMB_CHEST && target_zone != LIMB_GROIN && target_zone != LIMB_HEAD
/datum/surgery_step/generic/cut_limb/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] is beginning to cut off [target]'s [affected.display_name] with \the [tool]." , \
"You are beginning to cut off [target]'s [affected.display_name] with \the [tool].")
target.custom_pain("Your [affected.display_name] is being ripped apart!",1, scream=TRUE)
..()
/datum/surgery_step/generic/cut_limb/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] cuts off [target]'s [affected.display_name] with \the [tool].</span>", \
"<span class='notice'>You cut off [target]'s [affected.display_name] with \the [tool].</span>")
affected.open = 0 //Resets surgery status on limb, should prevent conflicting/phantom surgery
@@ -397,7 +395,7 @@
)
priority = 0.1 //Tries to inject biofoam before other steps
supports_cosmetic_organs = FALSE
duration = 1 SECONDS
/datum/surgery_step/generic/injectfoam/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)

View File

@@ -5,10 +5,12 @@
/datum/surgery_step/limb
can_infect = 1
supports_cosmetic_organs = TRUE
/datum/surgery_step/limb/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if (!hasorgans(target))
return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
if (!affected || affected.name == LIMB_HEAD)
return 0
if (!(affected.status & ORGAN_DESTROYED))
@@ -38,19 +40,19 @@
duration = 8 SECONDS
/datum/surgery_step/limb/cut/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] starts cutting away flesh where [target]'s [affected.display_name] used to be with \the [tool].", \
"You start cutting away flesh where [target]'s [affected.display_name] used to be with \the [tool].")
..()
/datum/surgery_step/limb/cut/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] cuts away flesh where [target]'s [affected.display_name] used to be with \the [tool].</span>", \
"<span class='notice'>You cut away flesh where [target]'s [affected.display_name] used to be with \the [tool].</span>")
affected.status |= ORGAN_CUT_AWAY
/datum/surgery_step/limb/cut/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
if (affected.parent)
affected = affected.parent
user.visible_message("<span class='warning'>[user]'s hand slips, cutting [target]'s [affected.display_name] open!</span>", \
@@ -70,23 +72,23 @@
duration = 8 SECONDS
/datum/surgery_step/limb/mend/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
return ..() && affected.status & ORGAN_CUT_AWAY
/datum/surgery_step/limb/mend/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] is beginning to reposition flesh and nerve endings where [target]'s [affected.display_name] used to be with [tool].", \
"You start repositioning flesh and nerve endings where [target]'s [affected.display_name] used to be with [tool].")
..()
/datum/surgery_step/limb/mend/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] has finished repositioning flesh and nerve endings where [target]'s [affected.display_name] used to be with [tool].</span>", \
"<span class='notice'>You have finished repositioning flesh and nerve endings where [target]'s [affected.display_name] used to be with [tool].</span>")
affected.open = 3
/datum/surgery_step/limb/mend/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
if (affected.parent)
affected = affected.parent
user.visible_message("<span class='warning'>[user]'s hand slips, tearing flesh on [target]'s [affected.display_name]!</span>", \
@@ -114,17 +116,17 @@
duration = 6 SECONDS
/datum/surgery_step/limb/prepare/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
return ..() && affected.open == 3
/datum/surgery_step/limb/prepare/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] starts adjusting area around [target]'s [affected.display_name] with \the [tool].", \
"You start adjusting area around [target]'s [affected.display_name] with \the [tool].")
..()
/datum/surgery_step/limb/prepare/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] has finished adjusting the area around [target]'s [affected.display_name] with \the [tool].</span>", \
"<span class='notice'>You have finished adjusting the area around [target]'s [affected.display_name] with \the [tool].</span>")
affected.status |= ORGAN_ATTACHABLE
@@ -133,7 +135,7 @@
affected.open = 0
/datum/surgery_step/limb/prepare/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
if (affected.parent)
affected = affected.parent
user.visible_message("<span class='warning'>[user]'s hand slips, searing [target]'s [affected.display_name]!</span>", \
@@ -147,15 +149,13 @@
allowed_tools = list(
/obj/item/robot_parts = 100,
)
can_infect = 0
duration = 8 SECONDS
/datum/surgery_step/limb/attach/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/robot_parts/p = tool
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
if(!(affected.status & ORGAN_ATTACHABLE) || !istype(p))
return 0 //not even ready for this and we're assuming they're using a fucking robot part!
if (p.part)
@@ -167,19 +167,19 @@
return ..()
/datum/surgery_step/limb/attach/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] starts attaching [tool] where [target]'s [affected.display_name] used to be.", \
"You start attaching [tool] where [target]'s [affected.display_name] used to be.")
/datum/surgery_step/limb/attach/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] has attached [tool] where [target]'s [affected.display_name] used to be.</span>", \
"<span class='notice'>You have attached [tool] where [target]'s [affected.display_name] used to be.</span>")
affected.attach(tool)
/datum/surgery_step/limb/attach/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='warning'>[user]'s hand slips, damaging connectors on [target]'s [affected.display_name]!</span>", \
"<span class='warning'>Your hand slips, damaging connectors on [target]'s [affected.display_name]!</span>")
target.apply_damage(10, BRUTE, affected)
@@ -193,7 +193,7 @@
)
can_infect = 0
supports_cosmetic_organs = FALSE
duration = 8 SECONDS
/datum/surgery_step/limb/attach_plank/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -236,7 +236,7 @@
/datum/surgery_step/limb/attach_flesh/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/o = tool
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
if(!(affected.status & ORGAN_ATTACHABLE) || !istype(o))
return 0
if (o.part)
@@ -249,19 +249,19 @@
return ..()
/datum/surgery_step/limb/attach_flesh/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("[user] starts attaching [tool] where [target]'s [affected.display_name] used to be.", \
"You start attaching [tool] where [target]'s [affected.display_name] used to be.")
/datum/surgery_step/limb/attach_flesh/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='notice'>[user] has attached [tool] where [target]'s [affected.display_name] used to be.</span>", \
"<span class='notice'>You have attached [tool] where [target]'s [affected.display_name] used to be.</span>")
affected.attach(tool)
/datum/surgery_step/limb/attach_flesh/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
var/datum/organ/external/affected = target.get_organ(target_zone, cosmetic = TRUE)
user.visible_message("<span class='warning'>[user]'s hand slips, damaging connectors on [target]'s [affected.display_name]!</span>", \
"<span class='warning'>Your hand slips, damaging connectors on [target]'s [affected.display_name]!</span>")
target.apply_damage(10, BRUTE, affected)

View File

@@ -10,7 +10,7 @@
var/list/disallowed_species = null
var/duration = 0
var/supports_cosmetic_organs = FALSE
var/list/mob/doing_surgery = list() //who's doing this RIGHT NOW
// evil infection stuff that will make everyone hate me
@@ -65,7 +65,7 @@
if (can_infect && affected)
spread_germs_to_organ(affected, user)
if(!(affected.status & (ORGAN_ROBOT|ORGAN_PEG)))//robot organs and pegs can't spread diseases or splatter blood
if((!(affected.status & (ORGAN_ROBOT|ORGAN_PEG))) && !affected.cosmetic_only)//robot organs and pegs can't spread diseases or splatter blood
var/block = user.check_contact_sterility(HANDS)
var/bleeding = user.check_bodypart_bleeding(HANDS)
target.oneway_contact_diseases(user,block,bleeding)//potentially spreads diseases from us to them, wear latex gloves!
@@ -108,7 +108,7 @@
return null
/proc/spread_germs_to_organ(datum/organ/external/E, mob/living/carbon/human/user)
if(!istype(user) || !istype(E))
if(!istype(user) || !istype(E) || E.cosmetic_only)
return
var/germ_level = user.germ_level
@@ -131,8 +131,19 @@
clumsy = 1
var/target_area = user.zone_sel ? user.zone_sel.selecting : get_random_zone_sel()
if(target_area == LIMB_GROIN)
var/groin_or_tail = input(user, "Groin or tail?", "Choose Target Zone", "Groin") as null|anything in list("Groin", "Tail")
switch(groin_or_tail)
if("Groin")
target_area = LIMB_GROIN
if("Tail")
target_area = COSMETIC_ORGAN_TAIL
for(var/datum/surgery_step/S in surgery_steps)
if(ishuman(M))
var/mob/living/carbon/human/human_target = M
if((target_area in human_target.cosmetic_organs_by_name) && !S.supports_cosmetic_organs)
continue
//check if tool is right or close enough and if this step is possible
sleep_fail = 0
if(S.tool_quality(tool))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
icons/mob/tails.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -71,6 +71,7 @@
#include "__DEFINES\simple_animal_defines.dm"
#include "__DEFINES\snow.dm"
#include "__DEFINES\sort.dm"
#include "__DEFINES\span.dm"
#include "__DEFINES\spell_defines.dm"
#include "__DEFINES\striketeam_defines.dm"
#include "__DEFINES\stylesheet.dm"
@@ -296,6 +297,7 @@
#include "code\datums\mind.dm"
#include "code\datums\mixed.dm"
#include "code\datums\modules.dm"
#include "code\datums\mutable_appearance.dm"
#include "code\datums\next_map.dm"
#include "code\datums\periodic_news.dm"
#include "code\datums\profiling.dm"
@@ -1986,7 +1988,8 @@
#include "code\modules\mob\living\carbon\human\life\handle_statis_bag.dm"
#include "code\modules\mob\living\carbon\human\life\handle_stomach.dm"
#include "code\modules\mob\living\carbon\human\life\life_helpers.dm"
#include "code\modules\mob\living\carbon\human\plasmaman\species.dm"
#include "code\modules\mob\living\carbon\human\species\plasmaman.dm"
#include "code\modules\mob\living\carbon\human\species\vox.dm"
#include "code\modules\mob\living\carbon\monkey\combat.dm"
#include "code\modules\mob\living\carbon\monkey\death.dm"
#include "code\modules\mob\living\carbon\monkey\diona.dm"