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_GLUE "#FFFFCC"
#define COLOR_BEESWAX "#FFB700" #define COLOR_BEESWAX "#FFB700"
#define COLOR_DEFAULT_CANDLE "#BE0000" #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_LEGS -1
#define UNCUFF_BOTH 0 #define UNCUFF_BOTH 0
#define UNCUFF_HANDS 1 #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 ARM_RIGHT 256
#define HAND_LEFT 512 #define HAND_LEFT 512
#define HAND_RIGHT 1024 #define HAND_RIGHT 1024
#define TAIL 524288
// bitflags for clothing parts // bitflags for clothing parts
@@ -352,6 +353,7 @@ var/MAX_EXPLOSION_RANGE = 32
#define HIDEEARS EARS #define HIDEEARS EARS
#define HIDEEYES EYES #define HIDEEYES EYES
#define HIDEFACE FACE #define HIDEFACE FACE
#define HIDETAIL TAIL
#define HIDEHEADHAIR 65536 #define HIDEHEADHAIR 65536
#define MASKHEADHAIR 131072 #define MASKHEADHAIR 131072
#define HIDEBEARDHAIR BEARD #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 ACID4WATER 4096 //Acid now acts like water, and vice versa.
#define NO_BALD 8192 //cannot lose hair through being shaved/radiation/etc #define NO_BALD 8192 //cannot lose hair through being shaved/radiation/etc
#define RGBSKINTONE 16384 #define RGBSKINTONE 16384
#define HAS_ICON_SKIN_TONE 32768
var/default_colour_matrix = list(1,0,0,0,\ var/default_colour_matrix = list(1,0,0,0,\
0,1,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 //Human Overlays Indexes/////////THIS DEFINES WHAT LAYERS APPEARS ON TOP OF OTHERS
#define FIRE_LAYER 1 //If you're on fire (/tg/ shit) #define FIRE_LAYER 1 //If you're on fire (/tg/ shit)
#define MUTANTRACE_LAYER 2 //TODO: make part of body? #define MUTANTRACE_LAYER 2 //TODO: make part of body?
#define MUTATIONS_LAYER 3 #define TAIL_UNDERLIMBS_LAYER 3
#define DAMAGE_LAYER 4 #define LIMBS_LAYER 4
#define UNIFORM_LAYER 5 #define MUTATIONS_LAYER 5
#define SHOES_LAYER 6 #define DAMAGE_LAYER 6
#define GLOVES_LAYER 7 #define UNIFORM_LAYER 7
#define EARS_LAYER 8 #define SHOES_LAYER 8
#define SUIT_LAYER 9 #define GLOVES_LAYER 9
#define GLASSES_LAYER 10 #define EARS_LAYER 10
#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt? #define SUIT_LAYER 11
#define SUIT_STORE_LAYER 12 #define GLASSES_LAYER 12
#define HAIR_LAYER 13 //TODO: make part of head layer? #define BELT_LAYER 13 //Possible make this an overlay of somethign required to wear a belt?
#define GLASSES_OVER_HAIR_LAYER 14 #define SUIT_STORE_LAYER 14
#define FACEMASK_LAYER 15 #define HAIR_LAYER 15 //TODO: make part of head layer?
#define HEAD_LAYER 16 #define GLASSES_OVER_HAIR_LAYER 16
#define BACK_LAYER 17 //Back should be above head so that headgear doesn't hides backpack when facing north #define TAIL_LAYER 17
#define ID_LAYER 18 //IDs should be visible above suits and backpacks #define FACEMASK_LAYER 18
#define HANDCUFF_LAYER 19 #define HEAD_LAYER 19
#define MUTUALCUFF_LAYER 20 #define BACK_LAYER 20 //Back should be above head so that headgear doesn't hides backpack when facing north
#define LEGCUFF_LAYER 21 #define ID_LAYER 21 //IDs should be visible above suits and backpacks
#define HAND_LAYER 22 #define HANDCUFF_LAYER 22
#define TAIL_LAYER 23 //bs12 specific. this hack is probably gonna come back to haunt me #define MUTUALCUFF_LAYER 23
#define TARGETED_LAYER 24 //BS12: Layer for the target overlay from weapon targeting system #define LEGCUFF_LAYER 24
#define TOTAL_LAYERS 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 //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_VISIBLE (1<<0)
#define EMOTE_AUDIBLE 2 #define EMOTE_AUDIBLE (1<<1)
#define EMOTE_NO_RUNECHAT (1<<2)
/* Emote datums, ported from TG station. */ /* 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) 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")) M.create_chat_message(user, null, msg_runechat, "", list("italics"))
if (emote_type == EMOTE_VISIBLE) if(emote_type & EMOTE_VISIBLE)
user.visible_message(msg) user.visible_message(msg)
for(var/z0 in GetOpenConnectedZlevels(user)) if(!(emote_type & EMOTE_NO_RUNECHAT))
for (var/mob/O in viewers(world.view, locate(user.x,user.y,z0))) for(var/z0 in GetOpenConnectedZlevels(user))
if (user.client && O?.client?.prefs.mob_chat_on_map && O.stat != UNCONSCIOUS && !(isinvisible(user))) for (var/mob/O in viewers(world.view, locate(user.x,user.y,z0)))
O.create_chat_message(user, null, msg_runechat, "", list("italics")) if (user.client && O?.client?.prefs.mob_chat_on_map && O.stat != UNCONSCIOUS && !(isinvisible(user)))
else 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)) for(var/mob/O in get_hearers_in_view(world.view, user))
O.show_message(msg) O.show_message(msg)
if (user.client && O?.client?.prefs.mob_chat_on_map && O.stat != UNCONSCIOUS && !O.is_deaf()) if(!(emote_type & EMOTE_NO_RUNECHAT))
O.create_chat_message(user, null, msg_runechat, "", list("italics")) 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/turf/T = get_turf(user)
var/location = T ? "[T.x],[T.y],[T.z]" : "nullspace" var/location = T ? "[T.x],[T.y],[T.z]" : "nullspace"

View File

@@ -564,7 +564,7 @@
return ..() return ..()
/datum/dynamic_ruleset/midround/from_ghosts/rambler/generate_ruleset_body(mob/applicant) /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) var/gender = pick(MALE, FEMALE)
new_frank.randomise_appearance_for(gender) new_frank.randomise_appearance_for(gender)
new_frank.key = applicant.key 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/brute_dam = 0
var/burn_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 /obj/item/robot_parts/l_arm
name = "robot left arm" name = "robot left arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
@@ -36,6 +39,40 @@
icon_state = LIMB_RIGHT_LEG icon_state = LIMB_RIGHT_LEG
part = list(LIMB_RIGHT_LEG,LIMB_RIGHT_FOOT) 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 /obj/item/robot_parts/chest
name = "robot torso" name = "robot torso"
desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." 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 permeability_coefficient = 0.02
flags = FPRINT flags = FPRINT
pressure_resistance = 5 * ONE_ATMOSPHERE 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/) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/)
slowdown = HARDSUIT_SLOWDOWN_BULKY slowdown = HARDSUIT_SLOWDOWN_BULKY
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50) 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 permeability_coefficient = 0.02
clothing_flags = ONESIZEFITSALL clothing_flags = ONESIZEFITSALL
pressure_resistance = 200 * ONE_ATMOSPHERE 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) 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 slowdown = HARDSUIT_SLOWDOWN_HIGH
armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50) 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 permeability_coefficient = 0.01
flags = FPRINT flags = FPRINT
clothing_flags = PLASMAGUARD 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 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) 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) 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" icon_state = "strait_jacket"
item_state = "strait_jacket" item_state = "strait_jacket"
origin_tech = Tc_BIOTECH + "=2" 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) species_fit = list(INSECT_SHAPED)
/obj/item/clothing/suit/ianshirt /obj/item/clothing/suit/ianshirt

View File

@@ -18,7 +18,7 @@
w_class = W_CLASS_LARGE//bulky item w_class = W_CLASS_LARGE//bulky item
gas_transfer_coefficient = 0.90 gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50 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) 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 slowdown = HARDSUIT_SLOWDOWN_LOW
clothing_flags = ONESIZEFITSALL clothing_flags = ONESIZEFITSALL
@@ -85,6 +85,7 @@
gas_transfer_coefficient = 0.01 gas_transfer_coefficient = 0.01
permeability_coefficient = 0.01 permeability_coefficient = 0.01
flags = FPRINT flags = FPRINT
body_parts_covered = ARMS|LEGS|FULL_TORSO|TAIL
slowdown = HARDSUIT_SLOWDOWN_HIGH slowdown = HARDSUIT_SLOWDOWN_HIGH
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 100, bio = 0, rad = 0) 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 max_heat_protection_temperature = ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE
@@ -157,7 +158,7 @@
w_class = W_CLASS_LARGE//bulky item w_class = W_CLASS_LARGE//bulky item
gas_transfer_coefficient = 0.90 gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50 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) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_nitrogen)
slowdown = 1.5 slowdown = 1.5
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100) 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))) 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) 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) user.visible_message(msg)
for(var/mob/O in viewers(world.view, user)) if(!(emote_type & EMOTE_NO_RUNECHAT))
if (O.client && O?.client?.prefs.mob_chat_on_map && get_dist(O, user) < O?.client.view) for(var/mob/O in viewers(world.view, user))
O.create_chat_message(user, null, message, "", list("italics")) if(O.client && O?.client?.prefs.mob_chat_on_map && get_dist(O, user) < O?.client.view)
else 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)) for(var/mob/O in get_hearers_in_view(world.view, user))
O.show_message(msg) O.show_message(msg)
if (O.client && O?.client?.prefs.mob_chat_on_map && get_dist(O, user) < O?.client.view) if(!(emote_type & EMOTE_NO_RUNECHAT))
O.create_chat_message(user, null, message, "", list("italics")) 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" var/location = T ? "[T.x],[T.y],[T.z]" : "nullspace"
log_emote("[user.name]/[user.key] (@[location]): [message]") log_emote("[user.name]/[user.key] (@[location]): [message]")

View File

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

View File

@@ -97,7 +97,7 @@
..(new_loc) ..(new_loc)
initialize_basic_NPC_components() 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/list/valid_species = (all_species - list("Krampus", "Horror", "Manifested"))
var/datum/species/new_species = all_species[pick(valid_species)] var/datum/species/new_species = all_species[pick(valid_species)]
@@ -109,7 +109,20 @@
for(var/datum/organ/external/E in organs) for(var/datum/organ/external/E in organs)
E.species = all_species[pick(valid_species)] 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() update_body()
/mob/living/carbon/human/mushroom/New(var/new_loc, delay_ready_dna = 0) /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[FIRE_LAYER] = new /obj/abstract/Overlays/fire_layer
obj_overlays[MUTANTRACE_LAYER] = new /obj/abstract/Overlays/mutantrace_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[MUTATIONS_LAYER] = new /obj/abstract/Overlays/mutations_layer
obj_overlays[DAMAGE_LAYER] = new /obj/abstract/Overlays/damage_layer obj_overlays[DAMAGE_LAYER] = new /obj/abstract/Overlays/damage_layer
obj_overlays[UNIFORM_LAYER] = new /obj/abstract/Overlays/uniform_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[BACK_LAYER] = new /obj/abstract/Overlays/back_layer
obj_overlays[HAIR_LAYER] = new /obj/abstract/Overlays/hair_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[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[FACEMASK_LAYER] = new /obj/abstract/Overlays/facemask_layer
obj_overlays[HEAD_LAYER] = new /obj/abstract/Overlays/head_layer obj_overlays[HEAD_LAYER] = new /obj/abstract/Overlays/head_layer
obj_overlays[HANDCUFF_LAYER] = new /obj/abstract/Overlays/handcuff_layer obj_overlays[HANDCUFF_LAYER] = new /obj/abstract/Overlays/handcuff_layer
obj_overlays[MUTUALCUFF_LAYER] = new /obj/abstract/Overlays/mutualcuff_layer obj_overlays[MUTUALCUFF_LAYER] = new /obj/abstract/Overlays/mutualcuff_layer
obj_overlays[LEGCUFF_LAYER] = new /obj/abstract/Overlays/legcuff_layer obj_overlays[LEGCUFF_LAYER] = new /obj/abstract/Overlays/legcuff_layer
//obj_overlays[HAND_LAYER] = new /obj/abstract/Overlays/hand_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 obj_overlays[TARGETED_LAYER] = new /obj/abstract/Overlays/targeted_layer
..() ..()

View File

@@ -307,14 +307,20 @@ This function restores all organs.
return return
/mob/living/carbon/human/get_organ(var/zone) /mob/living/carbon/human/get_organ(var/zone, cosmetic = FALSE)
RETURN_TYPE(/datum/organ/external) RETURN_TYPE(/datum/organ/external)
if(!zone) if(!zone)
zone = LIMB_CHEST zone = LIMB_CHEST
if (zone in list( "eyes", "mouth" )) if (zone in list( "eyes", "mouth" ))
zone = LIMB_HEAD 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 //Picks a random usable organ from the organs passed to the arguments
//You can feed organ references, or organ strings into this obj //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" var/g = "m"
if(gender == FEMALE) if(gender == FEMALE)
g = "f" g = "f"
if(species && species.anatomy_flags & HAS_ICON_SKIN_TONE)
species.updatespeciescolor(src)
var/datum/organ/external/chest = get_organ(LIMB_CHEST) var/datum/organ/external/chest = get_organ(LIMB_CHEST)
stand_icon = chest.get_icon(g,fat) stand_icon = chest.get_icon(g,fat)
if(!skeleton) 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) 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) husk_over.Blend(mask, ICON_ADD)
stand_icon.Blend(husk_over, ICON_OVERLAY) 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) if(has_head)
//Eyes //Eyes
if(!skeleton) if(!skeleton)
@@ -307,7 +316,7 @@ var/global/list/damage_icon_parts = list()
stand_icon -= rgb(0,0,0,lowest_alpha) stand_icon -= rgb(0,0,0,lowest_alpha)
//tail //tail
update_tail_showing(0) update_tail_layer(FALSE)
//HAIR OVERLAY //HAIR OVERLAY
@@ -523,6 +532,7 @@ var/global/list/damage_icon_parts = list()
update_inv_mutual_handcuffed(0) update_inv_mutual_handcuffed(0)
update_inv_legcuffed(0) update_inv_legcuffed(0)
update_inv_pockets(0) update_inv_pockets(0)
update_tail_layer()
QueueUpdateDamageIcon(1) QueueUpdateDamageIcon(1)
update_icons() update_icons()
//Hud Stuff //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 O.pixel_y = species.inventory_offsets["[slot_wear_suit]"]["pixel_y"] * PIXEL_MULTIPLIER
obj_to_plane_overlay(O,SUIT_LAYER) obj_to_plane_overlay(O,SUIT_LAYER)
//overlays_standing[SUIT_LAYER] = standing //overlays_standing[SUIT_LAYER] = standing
update_tail_showing(0) update_tail_layer()
else
//overlays_standing[SUIT_LAYER] = null
update_tail_showing(0)
if(update_icons) if(update_icons)
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) /mob/living/carbon/human/update_inv_l_hand(var/update_icons=1)
return update_inv_hand(GRASP_LEFT_HAND, update_icons) return update_inv_hand(GRASP_LEFT_HAND, update_icons)
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1) /mob/living/carbon/human/proc/update_tail_layer(update_icons = TRUE)
//overlays_standing[TAIL_LAYER] = null overlays -= obj_overlays[TAIL_UNDERLIMBS_LAYER]
overlays -= obj_overlays[TAIL_LAYER] overlays -= obj_overlays[TAIL_LAYER]
if(species && species.tail && species.anatomy_flags & HAS_TAIL) var/datum/organ/external/tail/tail_organ = get_cosmetic_organ(COSMETIC_ORGAN_TAIL)
if(!wear_suit || !is_slot_hidden(wear_suit.body_parts_covered, HIDEJUMPSUIT, 0, wear_suit.body_parts_visible_override)) if(!tail_organ || (tail_organ.status & ORGAN_DESTROYED))
var/obj/abstract/Overlays/O = obj_overlays[TAIL_LAYER] return
O.icon = 'icons/effects/species.dmi' if(wear_suit || check_hidden_body_flags(HIDETAIL))
O.icon_state = "[species.tail]_s" return
obj_to_plane_overlay(O,TAIL_LAYER) var/tail_file = tail_organ.tail_icon_file
//if(!old_tail_state) //only update if we didnt show our tail already var/tail_icon_state = tail_organ.icon_name
if(!tail_file || !tail_icon_state)
//overlays_standing[TAIL_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s") return
// to_chat(src, "update: tail is different") var/mutable_appearance/tail_image = mutable_appearance(tail_file, tail_icon_state, layer = -TAIL_LAYER)
//else if(species.anatomy_flags & MULTICOLOR)
//overlays_standing[TAIL_LAYER] = null 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) if(update_icons)
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/eyes = "eyes_s" // Icon for eyes.
var/primitive // Lesser form, if any (ie. monkey for humans) 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/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/default_language = LANGUAGE_GALACTIC_COMMON // Default language is used when 'say' is used without modifiers.
var/attack_verb = "punches" // Empty hand hurt intent verb. 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) for(var/datum/organ/I in H.internal_organs)
qdel(I) qdel(I)
H.internal_organs.len=0 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. //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) if(H.organs_by_name)
H.organs_by_name.len=0 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) if(H.internal_organs_by_name)
H.internal_organs_by_name.len=0 H.internal_organs_by_name.len=0
if(H.grasp_organs) if(H.grasp_organs)
@@ -219,6 +228,7 @@ var/global/list/playable_species = list("Human")
//This is a basic humanoid limb setup. //This is a basic humanoid limb setup.
H.organs = list() H.organs = list()
H.cosmetic_organs = list()
H.organs_by_name[LIMB_CHEST] = new/datum/organ/external/chest() 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_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]) 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_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.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() H.internal_organs = list()
for(var/organ in has_organ) for(var/organ in has_organ)
var/organ_type = has_organ[organ] var/organ_type = has_organ[organ]
@@ -245,9 +257,13 @@ var/global/list/playable_species = list("Human")
H.organs += OE H.organs += OE
if(OE.grasp_id) if(OE.grasp_id)
H.grasp_organs += OE H.grasp_organs += OE
for(var/organ in H.cosmetic_organs_by_name)
for(var/datum/organ/external/O in H.organs) var/datum/organ/external/cosmetic_organ = H.cosmetic_organs_by_name[organ]
O.owner = H 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. /datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
return return
@@ -385,7 +401,8 @@ var/global/list/playable_species = list("Human")
icobase = 'icons/mob/human_races/r_lizard.dmi' icobase = 'icons/mob/human_races/r_lizard.dmi'
deform = 'icons/mob/human_races/r_def_lizard.dmi' deform = 'icons/mob/human_races/r_def_lizard.dmi'
known_languages = list(LANGUAGE_UNATHI) known_languages = list(LANGUAGE_UNATHI)
tail = "sogtail" tail = "unathi"
tail_type = "unathi"
attack_verb = "scratches" attack_verb = "scratches"
punch_damage = 2 punch_damage = 2
primitive = /mob/living/carbon/monkey/unathi primitive = /mob/living/carbon/monkey/unathi
@@ -467,61 +484,13 @@ var/global/list/playable_species = list("Human")
H.drop_all() H.drop_all()
qdel(src) 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 /datum/species/tajaran
name = "Tajaran" name = "Tajaran"
icobase = 'icons/mob/human_races/r_tajaran.dmi' icobase = 'icons/mob/human_races/r_tajaran.dmi'
deform = 'icons/mob/human_races/r_def_tajaran.dmi' deform = 'icons/mob/human_races/r_def_tajaran.dmi'
known_languages = list(LANGUAGE_CATBEAST, LANGUAGE_MOUSE) known_languages = list(LANGUAGE_CATBEAST, LANGUAGE_MOUSE)
tail = "tajtail" tail = "tajaran_brown"
tail_type = "tajaran"
attack_verb = "scratches" attack_verb = "scratches"
punch_damage = 2 //Claws add 3 damage without gloves, so the total is 5 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 primitive = /mob/living/carbon/monkey/tajara
flags = WHITELISTED 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) default_mutations=list(M_CLAWS)
@@ -568,18 +537,20 @@ var/global/list/playable_species = list("Human")
updatespeciescolor(H) updatespeciescolor(H)
H.update_icon() H.update_icon()
/datum/species/tajaran/updatespeciescolor(var/mob/living/carbon/human/H) /datum/species/tajaran/updatespeciescolor(mob/living/carbon/human/tajaran)
switch(H.my_appearance.s_tone) var/datum/organ/external/tail/tajaran_tail = tajaran.get_cosmetic_organ(COSMETIC_ORGAN_TAIL)
switch(tajaran.my_appearance.s_tone)
if(CATBEASTBLACK) if(CATBEASTBLACK)
icobase = 'icons/mob/human_races/r_tajaranblack.dmi' icobase = 'icons/mob/human_races/r_tajaranblack.dmi'
deform = 'icons/mob/human_races/r_def_tajaranblack.dmi' deform = 'icons/mob/human_races/r_def_tajaranblack.dmi'
tail = "tajtailb" tajaran.my_appearance.h_style = "Black Tajaran Ears"
H.my_appearance.h_style = "Black Tajaran Ears"
else else
icobase = 'icons/mob/human_races/r_tajaran.dmi' icobase = 'icons/mob/human_races/r_tajaran.dmi'
deform = 'icons/mob/human_races/r_def_tajaran.dmi' deform = 'icons/mob/human_races/r_def_tajaran.dmi'
tail = "tajtail" tajaran.my_appearance.h_style = "Tajaran Ears"
H.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) /datum/species/tajaran/handle_speech(var/datum/speech/speech, mob/living/carbon/human/H)
if (prob(15)) if (prob(15))
@@ -610,7 +581,7 @@ var/global/list/playable_species = list("Human")
primitive = /mob/living/carbon/monkey/grey primitive = /mob/living/carbon/monkey/grey
flags = PLAYABLE | WHITELISTED 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) spells = list(/spell/targeted/telepathy)
@@ -736,114 +707,6 @@ var/global/list/playable_species = list("Human")
head_icons = 'icons/mob/species/skrell/head.dmi' head_icons = 'icons/mob/species/skrell/head.dmi'
wear_suit_icons = 'icons/mob/species/skrell/suit.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 /datum/species/diona
name = "Diona" name = "Diona"
icobase = 'icons/mob/human_races/r_plant.dmi' icobase = 'icons/mob/human_races/r_plant.dmi'
@@ -1421,4 +1284,4 @@ var/list/has_died_as_golem = list()
head_organ.droplimb(1,1) head_organ.droplimb(1,1)
H.drop_all() H.drop_all()
qdel(src) qdel(src)

View File

@@ -352,6 +352,9 @@ var/list/animals_with_wings = list(
else else
alert("Unable to use this emote, must be either hearable or visible.") alert("Unable to use this emote, must be either hearable or visible.")
return 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 message = custom_emote
else else
message = params message = params

View File

@@ -174,25 +174,25 @@
if(current_species) if(current_species)
if(current_species.name == "Vox") if(current_species.name == "Vox")
switch(s_tone) switch(s_tone)
if(6) if(VOXEMERALD)
icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi' icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi'
if(5) if(VOXAZURE)
icobase = 'icons/mob/human_races/vox/r_voxazu.dmi' icobase = 'icons/mob/human_races/vox/r_voxazu.dmi'
if(4) if(VOXLGREEN)
icobase = 'icons/mob/human_races/vox/r_voxlgrn.dmi' icobase = 'icons/mob/human_races/vox/r_voxlgrn.dmi'
if(3) if(VOXGRAY)
icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' icobase = 'icons/mob/human_races/vox/r_voxgry.dmi'
if(2) if(VOXBROWN)
icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi' icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi'
else else
icobase = 'icons/mob/human_races/vox/r_vox.dmi' icobase = 'icons/mob/human_races/vox/r_vox.dmi'
else if(current_species.name == "Grey") else if(current_species.name == "Grey")
switch(s_tone) switch(s_tone)
if(4) if(GREYBLUE)
icobase = 'icons/mob/human_races/grey/r_greyblue.dmi' icobase = 'icons/mob/human_races/grey/r_greyblue.dmi'
if(3) if(GREYGREEN)
icobase = 'icons/mob/human_races/grey/r_greygreen.dmi' icobase = 'icons/mob/human_races/grey/r_greygreen.dmi'
if(2) if(GREYLIGHT)
icobase = 'icons/mob/human_races/grey/r_greylight.dmi' icobase = 'icons/mob/human_races/grey/r_greylight.dmi'
else else
icobase = 'icons/mob/human_races/grey/r_grey.dmi' icobase = 'icons/mob/human_races/grey/r_grey.dmi'
@@ -230,7 +230,31 @@
var/icon/temp = new /icon(o_icobase, "[name]") var/icon/temp = new /icon(o_icobase, "[name]")
preview_icon.Blend(temp, ICON_OVERLAY) 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 // Skin tone
if(current_species && (current_species.anatomy_flags & HAS_SKIN_TONE)) if(current_species && (current_species.anatomy_flags & HAS_SKIN_TONE))
if (s_tone >= 0) if (s_tone >= 0)

View File

@@ -78,7 +78,9 @@
W.time_inflicted = world.time W.time_inflicted = world.time
/mob/living/carbon/human/var/list/organs = list() /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/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/datum/organ/internal/internal_organs_by_name = list() //So internal organs have less ickiness too
/mob/living/carbon/human/var/list/grasp_organs = list() /mob/living/carbon/human/var/list/grasp_organs = list()

View File

@@ -50,7 +50,7 @@
var/wound_update_accuracy = 1 var/wound_update_accuracy = 1
var/has_fat = 0 //Has a _fat variant var/has_fat = 0 //Has a _fat variant
var/cosmetic_only = FALSE
var/grasp_id = 0 //Does this organ affect other grasping organs? var/grasp_id = 0 //Does this organ affect other grasping organs?
var/can_grasp = 0 //Can this organ actually grasp something? var/can_grasp = 0 //Can this organ actually grasp something?
@@ -154,6 +154,8 @@
droplimb(1, spawn_limb = 0, display_message = FALSE) 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()) /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) if(owner?.status_flags & GODMODE)
return 0 //godmode return 0 //godmode
if((brute <= 0) && (burn <= 0)) if((brute <= 0) && (burn <= 0))
@@ -277,6 +279,8 @@
return result return result
/datum/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0) /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 if(is_robotic() && !robo_repair) //This item can't fix robotic limbs
return return
@@ -330,6 +334,8 @@
owner.updatehealth() owner.updatehealth()
/datum/organ/external/proc/createwound(var/type = CUT, var/damage) /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 if(!damage || damage < 0) //We weren't passed a damage value, or it's negative for some reason
return return
@@ -409,7 +415,6 @@
return 0 return 0
/datum/organ/external/process() /datum/organ/external/process()
//Process wounds, doing healing etc. Only do this every few ticks to save processing power //Process wounds, doing healing etc. Only do this every few ticks to save processing power
if(owner.life_tick % wound_update_accuracy == 0) if(owner.life_tick % wound_update_accuracy == 0)
update_wounds() update_wounds()
@@ -448,7 +453,6 @@
//Cancer growth for external organs is simple, it grows, hurts, damages, and suddenly grows out of control //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 //Limb cancer is relatively benign until it grows large, then it cripples you and metastases
/datum/organ/external/handle_cancer() /datum/organ/external/handle_cancer()
if(..()) if(..())
return 1 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() /datum/organ/external/proc/update_germs()
if(cosmetic_only)
return
if(!is_existing() || !is_organic()) //Needs to be organic and existing if(!is_existing() || !is_organic()) //Needs to be organic and existing
germ_level = 0 germ_level = 0
return 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 //Updating wounds. Handles wound natural healing, internal bleedings and infections
/datum/organ/external/proc/update_wounds() /datum/organ/external/proc/update_wounds()
if(cosmetic_only)
return
if(!is_organic()) //Non-organic limbs don't heal or get worse if(!is_organic()) //Non-organic limbs don't heal or get worse
return 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 if(body_part == (UPPER_TORSO || LOWER_TORSO)) //We can't lose either, those cannot be amputated and will cause extremely serious problems
return 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 var/obj/item/organ/external/organ //Dropped limb object
if(override) if(override)
@@ -837,7 +844,8 @@ Note that amputating the affected organ does in fact remove the infection from t
//Throw organs around //Throw organs around
var/randomdir = pick(cardinal) var/randomdir = pick(cardinal)
step(organ, randomdir) step(organ, randomdir)
if(!owner)
return organ
owner.update_body(1) owner.update_body(1)
owner.handle_organs(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.removed(owner,owner)
O.loc = headloc O.loc = headloc
QDEL_NULL(organ) QDEL_NULL(organ)
organ?.update_icon()
return organ return organ
/datum/organ/external/proc/get_organ_item() /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 return rval
/datum/organ/external/proc/clamp_wounds() //Inconsistent with the other names but clamp is a reserved word now /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 var/rval = 0
src.status &= ~ORGAN_BLEEDING src.status &= ~ORGAN_BLEEDING
for(var/datum/wound/W in wounds) 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 return rval
/datum/organ/external/proc/fracture() /datum/organ/external/proc/fracture()
if(cosmetic_only)
return
if(owner?.status_flags & GODMODE) if(owner?.status_flags & GODMODE)
return 0 //godmode return 0 //godmode
var/datum/species/species = src.species || owner.species 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.status = organ.status
src.brute_dam = organ.brute_dam src.brute_dam = organ.brute_dam
src.burn_dam = organ.burn_dam src.burn_dam = organ.burn_dam
on_attach(organ)
owner.butchering_drops += organ.butchering_drops owner.butchering_drops += organ.butchering_drops
//Transfer any internal_organs from the organ item to the body //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 else if(istype(I, /obj/item/robot_parts)) //Robotic limb
var/obj/item/robot_parts/R = I var/obj/item/robot_parts/R = I
R.on_attach(src)
src.robotize() src.robotize()
src.sabotaged = R.sabotaged 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.updatehealth()
owner.UpdateDamageIcon() owner.UpdateDamageIcon()
/datum/organ/external/proc/on_attach()
return
/datum/organ/external/proc/mutate() /datum/organ/external/proc/mutate()
src.status |= ORGAN_MUTATED src.status |= ORGAN_MUTATED
owner.update_body() 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 body_part = LOWER_TORSO
vital = 1 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====== //=====Legs======
/datum/organ/external/l_leg /datum/organ/external/l_leg
@@ -1607,6 +1701,7 @@ Note that amputating the affected organ does in fact remove the infection from t
..(loc) ..(loc)
if(!istype(H)) if(!istype(H))
return return
post_creation(source)
if(H.dna) if(H.dna)
owner_dna = H.dna.Clone() owner_dna = H.dna.Clone()
if(!blood_DNA) 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: //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. //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) /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>") to_chat(user, "<span class='warning'>[butchery]</span>")
/obj/item/organ/external/update_icon(mob/living/carbon/human/H) /obj/item/organ/external/update_icon(mob/living/carbon/human/H)
..()
if(!H && !species) if(!H && !species)
return return
@@ -1804,6 +1900,34 @@ Note that amputating the affected organ does in fact remove the infection from t
if(B) if(B)
B.infest_limb(src) 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 /obj/item/organ/external/head
dir = NORTH dir = NORTH
name = LIMB_HEAD name = LIMB_HEAD
@@ -2030,6 +2154,8 @@ Note that amputating the affected organ does in fact remove the infection from t
return FALSE return FALSE
/datum/organ/external/send_to_past(var/duration) /datum/organ/external/send_to_past(var/duration)
if(cosmetic_only)
return
..() ..()
var/static/list/resettable_vars = list( var/static/list/resettable_vars = list(
"damage_state", "damage_state",

View File

@@ -9,6 +9,12 @@
/obj/abstract/Overlays/mutantrace_layer /obj/abstract/Overlays/mutantrace_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - 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 /obj/abstract/Overlays/mutations_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - MUTATIONS_LAYER) layer = FLOAT_LAYER - (TOTAL_LAYERS - MUTATIONS_LAYER)
@@ -45,6 +51,9 @@
/obj/abstract/Overlays/glasses_over_hair_layer /obj/abstract/Overlays/glasses_over_hair_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - 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 /obj/abstract/Overlays/facemask_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - FACEMASK_LAYER) layer = FLOAT_LAYER - (TOTAL_LAYERS - FACEMASK_LAYER)
@@ -69,9 +78,6 @@
/obj/abstract/Overlays/hand_layer /obj/abstract/Overlays/hand_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - 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 /obj/abstract/Overlays/targeted_layer
layer = FLOAT_LAYER - (TOTAL_LAYERS - 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/fire_layer/fire_layer = new
var/obj/abstract/Overlays/mutantrace_layer/mutantrace_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/mutations_layer/mutations_layer = new
var/obj/abstract/Overlays/damage_layer/damage_layer = new var/obj/abstract/Overlays/damage_layer/damage_layer = new
var/obj/abstract/Overlays/uniform_layer/uniform_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/back_layer/back_layer = new
var/obj/abstract/Overlays/hair_layer/hair_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/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/facemask_layer/facemask_layer = new
var/obj/abstract/Overlays/head_layer/head_layer = new var/obj/abstract/Overlays/head_layer/head_layer = new
var/obj/abstract/Overlays/handcuff_layer/handcuff_layer = new var/obj/abstract/Overlays/handcuff_layer/handcuff_layer = new
var/obj/abstract/Overlays/legcuff_layer/legcuff_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/l_hand_layer/l_hand_layer = new
var/obj/abstract/Overlays/r_hand_layer/r_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 var/obj/abstract/Overlays/targeted_layer/targeted_layer = new
*/ */

View File

@@ -58,6 +58,16 @@
category = "Robot" category = "Robot"
materials = list(MAT_IRON=15000) 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 /datum/design/robot/head
name = "Cyborg Component (Robot head)" name = "Cyborg Component (Robot head)"
desc = "Used to build a Robot head." desc = "Used to build a Robot head."
@@ -198,4 +208,4 @@
build_type = MECHFAB build_type = MECHFAB
build_path = /obj/item/robot_parts/robot_component/armour/reinforced build_path = /obj/item/robot_parts/robot_component/armour/reinforced
category = "Robot_Part" 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/ /datum/surgery_step/generic/
can_infect = 1 can_infect = 1
supports_cosmetic_organs = TRUE
var/painful=1 var/painful=1
/datum/surgery_step/generic/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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 return 0
if (!hasorgans(target)) if (!hasorgans(target))
return 0 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) if (affected == null)
return 0 return 0
if (affected.status & ORGAN_DESTROYED) if (affected.status & ORGAN_DESTROYED)
@@ -40,7 +41,6 @@
) )
priority = 0.1 //so the tool checks for this step before /generic/cut_open priority = 0.1 //so the tool checks for this step before /generic/cut_open
duration = 4 SECONDS 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) /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)) if(target.species && (target.species.anatomy_flags & NO_SKIN))
to_chat(user, "<span class='info'>[target] has no skin!</span>") to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0 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" 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) /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].", \ 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].") "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) 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) /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>", \ 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>",) "<span class='notice'>You have made a bloodless incision on [target]'s [affected.display_name] with \the [tool].</span>",)
//Could be cleaner ... //Could be cleaner ...
affected.open = 1 affected.open = 1
affected.status |= ORGAN_BLEEDING if(!affected.cosmetic_only)
affected.status |= ORGAN_BLEEDING
affected.createwound(CUT, 1) affected.createwound(CUT, 1)
affected.clamp_wounds() affected.clamp_wounds()
//spread_germs_to_organ(affected, user) //a laser scalpel shouldn't spread germs. //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) /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>", \ 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>") "<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) affected.createwound(CUT, 7.5)
@@ -88,7 +89,6 @@
) )
priority = 0.1 //so the tool checks for this step before /generic/cut_open priority = 0.1 //so the tool checks for this step before /generic/cut_open
duration = 8 SECONDS duration = 8 SECONDS
/datum/surgery_step/generic/incision_manager/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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>") to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0 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" 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) /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].", \ 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].") "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) 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) /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>", \ 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>",) "<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.open = 1
affected.status |= ORGAN_BLEEDING if(!affected.cosmetic_only)
affected.status |= ORGAN_BLEEDING
affected.createwound(CUT, 1) affected.createwound(CUT, 1)
affected.clamp_wounds() affected.clamp_wounds()
affected.open = 2 affected.open = 2
tool.icon_state = "[initial(tool.icon_state)]_off" 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) /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>", \ 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>") "<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) affected.createwound(CUT, 20)
@@ -148,7 +149,6 @@
) )
priority = 0 priority = 0
duration = 4 SECONDS duration = 4 SECONDS
/datum/surgery_step/generic/cut_open/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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>") to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0 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") if(. && !affected.open && target_zone != "mouth")
return . return .
return 0 return 0
/datum/surgery_step/generic/cut_open/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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].", \ 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].") "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) 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) /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>", \ 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>",) "<span class='notice'>You have made an incision on [target]'s [affected.display_name] with \the [tool].</span>",)
affected.open = 1 affected.open = 1
affected.status |= ORGAN_BLEEDING if(!affected.cosmetic_only)
affected.status |= ORGAN_BLEEDING
affected.createwound(CUT, 1) 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) /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>", \ 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>") "<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) affected.createwound(CUT, 10)
@@ -193,7 +194,7 @@
/obj/item/weapon/talisman = 70, /obj/item/weapon/talisman = 70,
/obj/item/device/assembly/mousetrap = 20, /obj/item/device/assembly/mousetrap = 20,
) )
supports_cosmetic_organs = FALSE
duration = 3 SECONDS duration = 3 SECONDS
/datum/surgery_step/generic/clamp_bleeders/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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/tool/crowbar = 75,
/obj/item/weapon/kitchen/utensil/fork = 50 /obj/item/weapon/kitchen/utensil/fork = 50
) )
duration = 3 SECONDS duration = 3 SECONDS
/datum/surgery_step/generic/retract_skin/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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>") to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0 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) 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) /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/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]." var/self_msg = "You start to pry open the incision on [target]'s [affected.display_name] with \the [tool]."
if (target_zone == LIMB_CHEST) 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) /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/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>" 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) if (target_zone == LIMB_CHEST)
@@ -274,7 +274,7 @@
affected.open = 2 affected.open = 2
/datum/surgery_step/generic/retract_skin/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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/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>" 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) if (target_zone == LIMB_CHEST)
@@ -303,7 +303,6 @@
/obj/item/weapon/lighter = 50, /obj/item/weapon/lighter = 50,
/obj/item/tool/weldingtool = 25, /obj/item/tool/weldingtool = 25,
) )
duration = 3 SECONDS duration = 3 SECONDS
/datum/surgery_step/generic/cauterize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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>") to_chat(user, "<span class='info'>[target] has no skin!</span>")
return 0 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" 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) /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]." , \ 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].") "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) 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) /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>", \ 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>") "<span class='notice'>You cauterize the incision on [target]'s [affected.display_name] with \the [tool].</span>")
affected.open = 0 affected.open = 0
@@ -331,7 +330,7 @@
affected.status &= ~ORGAN_BLEEDING affected.status &= ~ORGAN_BLEEDING
/datum/surgery_step/generic/cauterize/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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>", \ 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>") "<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) target.apply_damage(3, BURN, affected)
@@ -345,7 +344,6 @@
/obj/item/weapon/kitchen/utensil/knife/large/butch = 75, /obj/item/weapon/kitchen/utensil/knife/large/butch = 75,
/obj/item/weapon/hatchet = 75, /obj/item/weapon/hatchet = 75,
) )
duration = 11 SECONDS duration = 11 SECONDS
/datum/surgery_step/generic/cut_limb/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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 return 0
if (!hasorgans(target)) if (!hasorgans(target))
return 0 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) if (affected == null)
return 0 return 0
if (affected.status & ORGAN_DESTROYED) if (affected.status & ORGAN_DESTROYED)
@@ -363,14 +361,14 @@
return target_zone != LIMB_CHEST && target_zone != LIMB_GROIN && target_zone != LIMB_HEAD 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) /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]." , \ 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].") "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) 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) /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>", \ 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>") "<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 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 priority = 0.1 //Tries to inject biofoam before other steps
supports_cosmetic_organs = FALSE
duration = 1 SECONDS duration = 1 SECONDS
/datum/surgery_step/generic/injectfoam/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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 /datum/surgery_step/limb
can_infect = 1 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) /datum/surgery_step/limb/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if (!hasorgans(target)) if (!hasorgans(target))
return 0 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) if (!affected || affected.name == LIMB_HEAD)
return 0 return 0
if (!(affected.status & ORGAN_DESTROYED)) if (!(affected.status & ORGAN_DESTROYED))
@@ -38,19 +40,19 @@
duration = 8 SECONDS duration = 8 SECONDS
/datum/surgery_step/limb/cut/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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].", \ 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].") "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) /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>", \ 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>") "<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 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) /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) if (affected.parent)
affected = affected.parent affected = affected.parent
user.visible_message("<span class='warning'>[user]'s hand slips, cutting [target]'s [affected.display_name] open!</span>", \ 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 duration = 8 SECONDS
/datum/surgery_step/limb/mend/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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 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) /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].", \ 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].") "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) /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>", \ 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>") "<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 affected.open = 3
/datum/surgery_step/limb/mend/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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) if (affected.parent)
affected = affected.parent affected = affected.parent
user.visible_message("<span class='warning'>[user]'s hand slips, tearing flesh on [target]'s [affected.display_name]!</span>", \ 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 duration = 6 SECONDS
/datum/surgery_step/limb/prepare/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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 return ..() && affected.open == 3
/datum/surgery_step/limb/prepare/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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].", \ 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].") "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) /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>", \ 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>") "<span class='notice'>You have finished adjusting the area around [target]'s [affected.display_name] with \the [tool].</span>")
affected.status |= ORGAN_ATTACHABLE affected.status |= ORGAN_ATTACHABLE
@@ -133,7 +135,7 @@
affected.open = 0 affected.open = 0
/datum/surgery_step/limb/prepare/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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) if (affected.parent)
affected = affected.parent affected = affected.parent
user.visible_message("<span class='warning'>[user]'s hand slips, searing [target]'s [affected.display_name]!</span>", \ user.visible_message("<span class='warning'>[user]'s hand slips, searing [target]'s [affected.display_name]!</span>", \
@@ -147,15 +149,13 @@
allowed_tools = list( allowed_tools = list(
/obj/item/robot_parts = 100, /obj/item/robot_parts = 100,
) )
can_infect = 0 can_infect = 0
duration = 8 SECONDS duration = 8 SECONDS
/datum/surgery_step/limb/attach/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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/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)) 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! return 0 //not even ready for this and we're assuming they're using a fucking robot part!
if (p.part) if (p.part)
@@ -167,19 +167,19 @@
return ..() return ..()
/datum/surgery_step/limb/attach/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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.", \ 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.") "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) /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>", \ 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>") "<span class='notice'>You have attached [tool] where [target]'s [affected.display_name] used to be.</span>")
affected.attach(tool) affected.attach(tool)
/datum/surgery_step/limb/attach/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/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>", \ 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>") "<span class='warning'>Your hand slips, damaging connectors on [target]'s [affected.display_name]!</span>")
target.apply_damage(10, BRUTE, affected) target.apply_damage(10, BRUTE, affected)
@@ -193,7 +193,7 @@
) )
can_infect = 0 can_infect = 0
supports_cosmetic_organs = FALSE
duration = 8 SECONDS duration = 8 SECONDS
/datum/surgery_step/limb/attach_plank/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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) /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/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)) if(!(affected.status & ORGAN_ATTACHABLE) || !istype(o))
return 0 return 0
if (o.part) if (o.part)
@@ -249,19 +249,19 @@
return ..() return ..()
/datum/surgery_step/limb/attach_flesh/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /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.", \ 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.") "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) /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>", \ 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>") "<span class='notice'>You have attached [tool] where [target]'s [affected.display_name] used to be.</span>")
affected.attach(tool) affected.attach(tool)
/datum/surgery_step/limb/attach_flesh/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/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>", \ 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>") "<span class='warning'>Your hand slips, damaging connectors on [target]'s [affected.display_name]!</span>")
target.apply_damage(10, BRUTE, affected) target.apply_damage(10, BRUTE, affected)

View File

@@ -10,7 +10,7 @@
var/list/disallowed_species = null var/list/disallowed_species = null
var/duration = 0 var/duration = 0
var/supports_cosmetic_organs = FALSE
var/list/mob/doing_surgery = list() //who's doing this RIGHT NOW var/list/mob/doing_surgery = list() //who's doing this RIGHT NOW
// evil infection stuff that will make everyone hate me // evil infection stuff that will make everyone hate me
@@ -65,7 +65,7 @@
if (can_infect && affected) if (can_infect && affected)
spread_germs_to_organ(affected, user) 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/block = user.check_contact_sterility(HANDS)
var/bleeding = user.check_bodypart_bleeding(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! target.oneway_contact_diseases(user,block,bleeding)//potentially spreads diseases from us to them, wear latex gloves!
@@ -108,7 +108,7 @@
return null return null
/proc/spread_germs_to_organ(datum/organ/external/E, mob/living/carbon/human/user) /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 return
var/germ_level = user.germ_level var/germ_level = user.germ_level
@@ -131,8 +131,19 @@
clumsy = 1 clumsy = 1
var/target_area = user.zone_sel ? user.zone_sel.selecting : get_random_zone_sel() 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) 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 //check if tool is right or close enough and if this step is possible
sleep_fail = 0 sleep_fail = 0
if(S.tool_quality(tool)) 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\simple_animal_defines.dm"
#include "__DEFINES\snow.dm" #include "__DEFINES\snow.dm"
#include "__DEFINES\sort.dm" #include "__DEFINES\sort.dm"
#include "__DEFINES\span.dm"
#include "__DEFINES\spell_defines.dm" #include "__DEFINES\spell_defines.dm"
#include "__DEFINES\striketeam_defines.dm" #include "__DEFINES\striketeam_defines.dm"
#include "__DEFINES\stylesheet.dm" #include "__DEFINES\stylesheet.dm"
@@ -296,6 +297,7 @@
#include "code\datums\mind.dm" #include "code\datums\mind.dm"
#include "code\datums\mixed.dm" #include "code\datums\mixed.dm"
#include "code\datums\modules.dm" #include "code\datums\modules.dm"
#include "code\datums\mutable_appearance.dm"
#include "code\datums\next_map.dm" #include "code\datums\next_map.dm"
#include "code\datums\periodic_news.dm" #include "code\datums\periodic_news.dm"
#include "code\datums\profiling.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_statis_bag.dm"
#include "code\modules\mob\living\carbon\human\life\handle_stomach.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\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\combat.dm"
#include "code\modules\mob\living\carbon\monkey\death.dm" #include "code\modules\mob\living\carbon\monkey\death.dm"
#include "code\modules\mob\living\carbon\monkey\diona.dm" #include "code\modules\mob\living\carbon\monkey\diona.dm"