diff --git a/check_regex.yaml b/check_regex.yaml index d413ba79dd32..396cf9a20961 100644 --- a/check_regex.yaml +++ b/check_regex.yaml @@ -29,9 +29,9 @@ standards: - exactly: [1, "/area text paths", '"/area'] - exactly: [17, "/datum text paths", '"/datum'] - exactly: [4, "/mob text paths", '"/mob'] - - exactly: [53, "/obj text paths", '"/obj'] + - exactly: [51, "/obj text paths", '"/obj'] - exactly: [0, "/turf text paths", '"/turf'] - - exactly: [118, "text2path uses", "text2path"] + - exactly: [116, "text2path uses", "text2path"] - exactly: [18, "world<< uses", 'world[ \t]*<<'] - exactly: [0, "world.log<< uses", 'world.log[ \t]*<<'] diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 184d691e59cf..a84da333d300 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -132,7 +132,8 @@ #define NOHUSK 22 // Can't be husked. #define NOMOUTH 23 #define NOSOCKS 24 // You cannot wear sock -#define NO_BONES 25 // You don't have bones to break +#define NO_BONES 25 //! You don't have any bones for breaking +#define MUTCOLORS_SECONDARY 26 //! A second mutant colour for other things //organ slots #define ORGAN_SLOT_BRAIN "brain" diff --git a/code/__DEFINES/bodyparts.dm b/code/__DEFINES/bodyparts.dm index c3d51099e3fb..9783cbfaa88c 100644 --- a/code/__DEFINES/bodyparts.dm +++ b/code/__DEFINES/bodyparts.dm @@ -1 +1,2 @@ #define IS_ORGANIC_LIMB(A) (A.bodytype & BODYTYPE_ORGANIC) +#define IS_ROBOTIC_LIMB(A) (A.bodytype & BODYTYPE_ROBOTIC) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index cb714460f622..e4f600dcea6a 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -71,9 +71,6 @@ #define LARVA_BODYPART "larva" #define DEVIL_BODYPART "devil" -//Bodypart change blocking flags -#define BP_BLOCK_CHANGE_SPECIES (1<<0) - //Defines for Species IDs #define SPECIES_ABDUCTOR "abductor" #define SPECIES_ANDROID "android" diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 52b1dc416895..e687f06e6b22 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -131,4 +131,5 @@ #define PROSTHETIC_AMPUTATED "amputated" #define PROSTHETIC_ROBOTIC "prosthetic" - +#define NOT_SYNTHETIC FALSE +#define IS_SYNTHETIC TRUE diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 216a4468d3a2..f2e010c20e64 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -125,6 +125,7 @@ "kepori_tail_feathers" = pick(GLOB.kepori_tail_feathers_list), "legs" = "Normal Legs", "mcolor" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "mcolor2" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), "moth_fluff" = pick(GLOB.moth_fluff_list), "moth_markings" = pick(GLOB.moth_markings_list), "moth_wings" = pick(GLOB.moth_wings_list), diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 718eba629bf8..60e74d97fb7d 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -320,7 +320,7 @@ stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human -/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) +/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE, robotic = FALSE) if(mrace && has_dna()) var/datum/species/new_race if(ispath(mrace)) @@ -345,14 +345,15 @@ quirks_to_remove -= quirks_resolved for(var/quirk_type in quirks_to_remove) remove_quirk(quirk_type) - dna.species.on_species_gain(src, old_species, pref_load) + dna.species.on_species_gain(src, old_species, pref_load, robotic) if(ishuman(src)) qdel(language_holder) var/species_holder = initial(mrace.species_language_holder) language_holder = new species_holder(src) update_atom_languages() -/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) +/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE, robotic = FALSE) + robotic ||= fbp ..() if(icon_update) update_hair() diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index dace5f5170ec..568196c1460b 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -397,7 +397,7 @@ if(!itemUser.has_hand_for_held_index(hand)) //If user does not have the corresponding hand anymore, give them one and return the rod to their hand if(((hand % 2) == 0)) - var/obj/item/bodypart/L = itemUser.newBodyPart(BODY_ZONE_R_ARM, FALSE, FALSE) + var/obj/item/bodypart/L = itemUser.new_body_part(BODY_ZONE_R_ARM, FALSE, FALSE) if(L.attach_limb(itemUser)) itemUser.put_in_hand(newRod, hand, forced = TRUE) else @@ -405,7 +405,7 @@ consume_owner() //we can't regrow, abort abort return else - var/obj/item/bodypart/L = itemUser.newBodyPart(BODY_ZONE_L_ARM, FALSE, FALSE) + var/obj/item/bodypart/L = itemUser.new_body_part(BODY_ZONE_L_ARM, FALSE, FALSE) if(L.attach_limb(itemUser)) itemUser.put_in_hand(newRod, hand, forced = TRUE) else diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index d68bba545d7f..5861b88dd173 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -244,11 +244,7 @@ var/obj/item/bodypart/limb limb = new buildpath(loc) limb.name = "\improper synthetic [limb.bodytype & BODYTYPE_DIGITIGRADE ? "digitigrade ":""][selected_category] [limb.plaintext_zone]" - //super snowflake code to make digitigrade work with the rest of the limbs - if(limb.bodytype & BODYTYPE_DIGITIGRADE) - limb.limb_id = "digitigrade" - else - limb.limb_id = selected_category + limb.limb_id = selected_category //fun override colors limb.mutation_color = random_color() limb.update_icon_dropped() diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 5e62c114f178..2e540611f343 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -171,7 +171,7 @@ H.dna.update_ui_block(DNA_SKIN_TONE_BLOCK) if(MUTCOLORS in H.dna.species.species_traits) - var/new_mutantcolor = input(user, "Choose your skin color:", "Race change","#"+H.dna.features["mcolor"]) as color|null + var/new_mutantcolor = input(user, "Choose your skin color:", "Race change","#" + H.dna.features["mcolor"]) as color|null if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(new_mutantcolor) @@ -183,6 +183,17 @@ else to_chat(H, "Invalid color. Your color is not bright enough.") + if(MUTCOLORS_SECONDARY in H.dna.species.species_traits) + var/new_secondary_mutantcolor = input(user, "Choose your secondary skin color:", "Race change","#" + H.dna.features["mcolor2"]) as color|null + if(new_secondary_mutantcolor) + var/temp_hsv = RGBtoHSV(new_secondary_mutantcolor) + + if(ReadHSV(temp_hsv)[3] >= ReadHSV("#191919")[3]) // mutantcolors must be bright + H.dna.features["mcolor2"] = sanitize_hexcolor(new_secondary_mutantcolor) + + else + to_chat(H, "Invalid color. Your secondary color is not bright enough.") + H.update_body() H.update_hair() H.update_body_parts(TRUE) diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 6b931aa6d845..68c5e46e75b8 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -26,6 +26,7 @@ // Mutant randomizing, doesn't affect the mob appearance unless it's the specific mutant. H.dna.features["mcolor"] = random_short_color() + H.dna.features["mcolor2"] = random_short_color() H.dna.features["ethcolor"] = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)] H.dna.features["tail_lizard"] = pick(GLOB.tails_list_lizard) H.dna.features["snout"] = pick(GLOB.snouts_list) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 6f85793b6a01..b665b37c6cc4 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -85,6 +85,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/species_looking_at = "human" //used as a helper to keep track of in the species select thingy var/list/features = list( "mcolor" = "FFF", + "mcolor2" = "FFF", "grad_style" = "None", "grad_color" = "FFF", "ethcolor" = "9c3030", @@ -121,6 +122,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) ) var/list/randomise = list(RANDOM_UNDERWEAR = TRUE, RANDOM_UNDERWEAR_COLOR = TRUE, RANDOM_UNDERSHIRT = TRUE, RANDOM_SOCKS = TRUE, RANDOM_BACKPACK = TRUE, RANDOM_JUMPSUIT_STYLE = TRUE, RANDOM_EXOWEAR_STYLE = TRUE, RANDOM_HAIRSTYLE = TRUE, RANDOM_HAIR_COLOR = TRUE, RANDOM_FACIAL_HAIRSTYLE = TRUE, RANDOM_FACIAL_HAIR_COLOR = TRUE, RANDOM_SKIN_TONE = TRUE, RANDOM_EYE_COLOR = TRUE) var/list/friendlyGenders = list("Male" = "male", "Female" = "female", "Other" = "plural") + var/fbp = FALSE var/list/prosthetic_limbs = list(BODY_ZONE_L_ARM = PROSTHETIC_NORMAL, BODY_ZONE_R_ARM = PROSTHETIC_NORMAL, BODY_ZONE_L_LEG = PROSTHETIC_NORMAL, BODY_ZONE_R_LEG = PROSTHETIC_NORMAL) var/phobia = "spiders" var/list/alt_titles_preferences = list() @@ -375,10 +377,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "[(randomise[RANDOM_SOCKS]) ? "Lock" : "Unlock"]
" - var/use_skintones = pref_species.use_skintones - if(use_skintones) + dat += APPEARANCE_CATEGORY_COLUMN - dat += APPEARANCE_CATEGORY_COLUMN + if(pref_species.use_skintones) dat += "

Skin Tone

" @@ -386,23 +387,14 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "[(randomise[RANDOM_SKIN_TONE]) ? "Lock" : "Unlock"]" dat += "
" - var/mutant_colors - if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits)) - - if(!use_skintones) - dat += APPEARANCE_CATEGORY_COLUMN - - dat += "

Mutant Color

" + // Everyone gets mutant colors now. + dat += "

Mutant Colors

" - dat += "    Change
" - - mutant_colors = TRUE + dat += "    Change
" + dat += "    Change
" if(istype(pref_species, /datum/species/ethereal)) //not the best thing to do tbf but I dont know whats better. - if(!use_skintones) - dat += APPEARANCE_CATEGORY_COLUMN - dat += "

Ethereal Color

" dat += "    Change
" @@ -410,16 +402,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) if((EYECOLOR in pref_species.species_traits) && !(NOEYESPRITES in pref_species.species_traits)) - if(!use_skintones && !mutant_colors) - dat += APPEARANCE_CATEGORY_COLUMN - dat += "

Eye Color

" dat += "    Change" dat += "[(randomise[RANDOM_EYE_COLOR]) ? "Lock" : "Unlock"]" dat += "
" - else if(use_skintones || mutant_colors) - dat += "" + + dat += "" if(HAIR in pref_species.species_traits) @@ -488,6 +477,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "

Horns

" dat += "[features["horns"]]
" + dat += "    Change
" + dat += "[(randomise[RANDOM_HAIR_COLOR]) ? "Lock" : "Unlock"]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) @@ -709,8 +700,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "

Body Feathers

" dat += "[features["kepori_body_feathers"]]
" - dat += "    Change
" - dat += "[(randomise[RANDOM_FACIAL_HAIR_COLOR]) ? "Lock" : "Unlock"]
" + dat += "    Change
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) @@ -723,8 +713,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "

Tail Feathers

" dat += "[features["kepori_tail_feathers"]]
" - dat += "    Change
" - dat += "[(randomise[RANDOM_FACIAL_HAIR_COLOR]) ? "Lock" : "Unlock"]
" + dat += "    Change
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) @@ -849,14 +838,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "" dat += "

Prosthetic Limbs

" - dat += "Random Prosthetic: [(randomise[RANDOM_PROSTHETIC]) ? "Yes" : "No"]
" + dat += "Full Body Prosthesis: [fbp ? "Yes" : "No"]
" + + if(!fbp) + dat += "Random Prosthetic: [(randomise[RANDOM_PROSTHETIC]) ? "Yes" : "No"]
" - dat += "" - for(var/index in prosthetic_limbs) - var/bodypart_name = parse_zone(index) - dat += "" - dat += "" - dat += "
[bodypart_name]:[prosthetic_limbs[index]]

" + dat += "" + for(var/index in prosthetic_limbs) + var/bodypart_name = parse_zone(index) + dat += "" + dat += "" + dat += "
[bodypart_name]:[prosthetic_limbs[index]]

" if(2) //Loadout if(path) @@ -1451,6 +1443,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(href_list["preference"] == "species") switch(href_list["task"]) + if("random") + random_species() + ShowChoices(user) + return TRUE if("close") user << browse(null, "window=mob_species") ShowChoices(user) @@ -1472,7 +1468,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) species_looking_at = href_list["newspecies"] ShowSpeciesChoices(user) - return 1 + return TRUE if(href_list["preference"] == "trait") switch(href_list["task"]) @@ -1567,8 +1563,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) eye_color = random_eye_color() if("s_tone") skin_tone = random_skin_tone() - if("species") - random_species() if("bag") backpack = pick(GLOB.backpacklist) if("suit") @@ -1759,7 +1753,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) features["body_size"] = new_size if("mutant_color") - var/new_mutantcolor = input(user, "Choose your character's alien/mutant color:", "Character Preference","#"+features["mcolor"]) as color|null + var/new_mutantcolor = input(user, "Choose your character's primary alien/mutant color:", "Character Preference","#" + features["mcolor"]) as color|null if(new_mutantcolor) var/temp_hsv = RGBtoHSV(new_mutantcolor) if(new_mutantcolor == "#000000") @@ -1769,6 +1763,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) else to_chat(user, "Invalid color. Your color is not bright enough.") + if("mutant_color_2") + var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference","#" + features["mcolor2"]) as color|null + if(new_mutantcolor) + var/temp_hsv = RGBtoHSV(new_mutantcolor) + if(new_mutantcolor == "#000000") + features["mcolor2"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#191919")[3]) // mutantcolors must be bright, but only if they affect the skin + features["mcolor2"] = sanitize_hexcolor(new_mutantcolor) + else + to_chat(user, "Invalid color. Your color is not bright enough.") + if("color_ethereal") var/new_etherealcolor = input(user, "Choose your elzuosa color:", "Character Preference","#"+features["ethcolor"]) as color|null if(new_etherealcolor) @@ -2045,6 +2050,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) facial_hairstyle = random_facial_hairstyle(gender) hairstyle = random_hairstyle(gender) + if("fbp") + fbp = !fbp + if("limbs") if(href_list["customize_limb"]) var/limb = href_list["customize_limb"] @@ -2368,6 +2376,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.exowear = exowear + character.fbp = fbp + character.flavor_text = features["flavor_text"] //Let's update their flavor_text at least initially if(loadout) //I have been told not to do this because it's too taxing on performance, but hey, I did it anyways! //I hate you old me //don't be mean @@ -2386,36 +2396,28 @@ GLOBAL_LIST_EMPTY(preferences_datums) //prosthetics work for vox and kepori and update just fine for everyone character.dna.features = features.Copy() - character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE) - - for(var/pros_limbs in prosthetic_limbs) - var/obj/item/bodypart/old_part = character.get_bodypart(pros_limbs) - if(old_part) - icon_updates = TRUE - switch(prosthetic_limbs[pros_limbs]) - if(PROSTHETIC_NORMAL) - if(old_part) - old_part.drop_limb(TRUE) - qdel(old_part) - character.regenerate_limb(pros_limbs) - if(PROSTHETIC_AMPUTATED) - if(old_part) - old_part.drop_limb(TRUE) - qdel(old_part) - if(PROSTHETIC_ROBOTIC) - var/obj/item/bodypart/prosthetic - var/typepath - if(character.dna.species.unique_prosthesis) // Checks for if the species has a unique limb type, otherwise defaults to human - typepath = text2path("/obj/item/bodypart/[pros_limbs]/robot/surplus/[character.dna.species.id]") - else - typepath = text2path("/obj/item/bodypart/[pros_limbs]/robot/surplus") - if(!ispath(typepath)) - to_chat(character, "Problem initializing [pros_limbs] prosthetic for species [character.dna.species], it will be a normal limb. Make a bug report on github!") - continue - prosthetic = new typepath(character) - prosthetic.replace_limb(character, special = TRUE) - if(old_part) - qdel(old_part) + character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE, robotic = fbp) + + if(!fbp) + for(var/pros_limb in prosthetic_limbs) + var/obj/item/bodypart/old_part = character.get_bodypart(pros_limb) + if(old_part) + icon_updates = TRUE + switch(prosthetic_limbs[pros_limb]) + if(PROSTHETIC_NORMAL) + if(old_part) + old_part.drop_limb(TRUE) + qdel(old_part) + character.regenerate_limb(pros_limb) + if(PROSTHETIC_AMPUTATED) + if(old_part) + old_part.drop_limb(TRUE) + qdel(old_part) + if(PROSTHETIC_ROBOTIC) + if(old_part) + old_part.drop_limb(TRUE) + qdel(old_part) + character.regenerate_limb(pros_limb, robotic = TRUE) if(pref_species.id == "ipc") // If triggered, vox and kepori arms do not spawn in but ipcs sprites break without it as the code for setting the right prosthetics for them is in set_species(). character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 84e117fce38d..0c8eb70da2d6 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -405,6 +405,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car READ_FILE(S["prosthetic_limbs"], prosthetic_limbs) prosthetic_limbs ||= list(BODY_ZONE_L_ARM = PROSTHETIC_NORMAL, BODY_ZONE_R_ARM = PROSTHETIC_NORMAL, BODY_ZONE_L_LEG = PROSTHETIC_NORMAL, BODY_ZONE_R_LEG = PROSTHETIC_NORMAL) READ_FILE(S["feature_mcolor"], features["mcolor"]) + READ_FILE(S["feature_mcolor2"], features["mcolor2"]) READ_FILE(S["feature_ethcolor"], features["ethcolor"]) READ_FILE(S["feature_lizard_tail"], features["tail_lizard"]) READ_FILE(S["feature_lizard_snout"], features["snout"]) @@ -445,6 +446,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car READ_FILE(S["feature_human_tail"], features["tail_human"]) READ_FILE(S["feature_human_ears"], features["ears"]) + READ_FILE(S["fbp"], fbp) + //Custom names for(var/custom_name_id in GLOB.preferences_custom_names) var/savefile_slot_name = custom_name_id + "_name" //TODO remove this @@ -513,10 +516,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style)) exowear = sanitize_inlist(exowear, GLOB.exowearlist, initial(exowear)) uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc)) + fbp = sanitize_integer(fbp, FALSE, TRUE, FALSE) features["grad_style"] = sanitize_inlist(features["grad_style"], GLOB.hair_gradients_list) features["grad_color"] = sanitize_hexcolor(features["grad_color"]) features["body_size"] = sanitize_inlist(features["body_size"], GLOB.body_sizes, "Normal") features["mcolor"] = sanitize_hexcolor(features["mcolor"]) + features["mcolor2"] = sanitize_hexcolor(features["mcolor2"]) features["ethcolor"] = copytext_char(features["ethcolor"], 1, 7) features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard) features["tail_human"] = sanitize_inlist(features["tail_human"], GLOB.tails_list_human, "None") @@ -587,6 +592,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["body_size"] , features["body_size"]) WRITE_FILE(S["prosthetic_limbs"], prosthetic_limbs) WRITE_FILE(S["feature_mcolor"] , features["mcolor"]) + WRITE_FILE(S["feature_mcolor2"] , features["mcolor2"]) WRITE_FILE(S["feature_ethcolor"] , features["ethcolor"]) WRITE_FILE(S["feature_lizard_tail"] , features["tail_lizard"]) WRITE_FILE(S["feature_human_tail"] , features["tail_human"]) @@ -621,6 +627,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["feature_vox_neck_quills"], features["vox_neck_quills"]) WRITE_FILE(S["feature_elzu_horns"] , features["elzu_horns"]) WRITE_FILE(S["feature_tail_elzu"] , features["tail_elzu"]) + WRITE_FILE(S["fbp"] , fbp) //Flavor text WRITE_FILE(S["feature_flavor_text"], features["flavor_text"]) diff --git a/code/modules/mob/dead/new_player/sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories.dm index 37ffd23cc2ba..7d9a9121afe7 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories.dm @@ -47,26 +47,30 @@ return L /datum/sprite_accessory - var/icon //the icon file the accessory is located in - var/icon_state //the icon_state of the accessory - var/name //the preview name of the accessory - var/gender = NEUTER //Determines if the accessory will be skipped or included in random hair generations - var/gender_specific //Something that can be worn by either gender, but looks different on each - var/use_static //determines if the accessory will be skipped by color preferences - var/color_src = MUTCOLORS //Currently only used by mutantparts so don't worry about hair and stuff. This is the source that this accessory will get its color from. Default is MUTCOLOR, but can also be HAIR, FACEHAIR, EYECOLOR and 0 if none. - var/hasinner //Decides if this sprite has an "inner" part, such as the fleshy parts on ears. - var/locked = FALSE //Is this part locked from roundstart selection? Used for parts that apply effects + var/icon //!the icon file the accessory is located in + var/icon_state //!the icon_state of the accessory + var/name //!the preview name of the accessory + var/gender = NEUTER //!Determines if the accessory will be skipped or included in random hair generations + var/gender_specific //!Something that can be worn by either gender, but looks different on each + var/use_static //!determines if the accessory will be skipped by color preferences + var/color_src = MUTCOLORS //!Currently only used by mutantparts so don't worry about hair and stuff. This is the source that this accessory will get its color from. Default is MUTCOLOR, but can also be HAIR, FACEHAIR, EYECOLOR and 0 if none. + var/hasinner //!Decides if this sprite has an "inner" part, such as the fleshy parts on ears. + var/locked = FALSE //!Is this part locked from roundstart selection? Used for parts that apply effects var/dimension_x = 32 var/dimension_y = 32 - var/center = FALSE //Should we center the sprite? - var/limbs_id // The limbs id supplied for full-body replacing features. - var/image_alpha = 255 // The alpha for the accessory to use. + var/center = FALSE //!Should we center the sprite? + var/limbs_id //!The limbs id supplied for full-body replacing features. + var/image_alpha = 255 //!The alpha for the accessory to use. + var/body_zone = BODY_ZONE_CHEST //!The body zone this accessory affects + var/synthetic_icon_state //!The icon_state to use when the bodypart it's attached to is synthetic + var/synthetic_color_src //!The color src to use instead of the normal src when synthetic, leave blank to use the normal src ////////////////////// // Hair Definitions // ////////////////////// /datum/sprite_accessory/hair icon = 'icons/mob/human_face.dmi' // default icon for all hairs + body_zone = BODY_ZONE_HEAD // please make sure they're sorted alphabetically and, where needed, categorized // try to capitalize the names please~ @@ -843,6 +847,7 @@ /datum/sprite_accessory/hair_gradient icon = 'icons/mob/hair_gradients.dmi' + body_zone = BODY_ZONE_HEAD /datum/sprite_accessory/hair_gradient/none name = "None" @@ -891,6 +896,7 @@ /datum/sprite_accessory/facial_hair icon = 'icons/mob/human_face.dmi' gender = MALE // barf (unless you're a dorf, dorfs dig chix w/ beards :P) + body_zone = BODY_ZONE_HEAD // please make sure they're sorted alphabetically and categorized @@ -1701,6 +1707,9 @@ /datum/sprite_accessory/body_markings icon = 'icons/mob/mutant_bodyparts.dmi' + color_src = MUTCOLORS_SECONDARY + body_zone = BODY_ZONE_CHEST + synthetic_icon_state = "none" /datum/sprite_accessory/body_markings/none name = "None" @@ -1709,23 +1718,26 @@ /datum/sprite_accessory/body_markings/dtiger name = "Dark Tiger Body" icon_state = "dtiger" - gender_specific = 1 + gender_specific = TRUE /datum/sprite_accessory/body_markings/ltiger name = "Light Tiger Body" icon_state = "ltiger" - gender_specific = 1 + gender_specific = TRUE /datum/sprite_accessory/body_markings/lbelly name = "Light Belly" icon_state = "lbelly" - gender_specific = 1 + gender_specific = TRUE /datum/sprite_accessory/tails icon = 'icons/mob/mutant_bodyparts.dmi' + body_zone = BODY_ZONE_CHEST + synthetic_icon_state = "synth" /datum/sprite_accessory/tails_animated icon = 'icons/mob/mutant_bodyparts.dmi' + body_zone = BODY_ZONE_CHEST /datum/sprite_accessory/tails/lizard/smooth name = "Smooth" @@ -1762,10 +1774,12 @@ /datum/sprite_accessory/tails/lizard/large name = "Large" icon_state = "large" + synthetic_icon_state = "large" //fight me /datum/sprite_accessory/tails_animated/lizard/large name = "Large" icon_state = "large" + synthetic_icon_state = "large" /datum/sprite_accessory/tails/human/none name = "None" @@ -1823,6 +1837,8 @@ /datum/sprite_accessory/snouts icon = 'icons/mob/mutant_bodyparts.dmi' + body_zone = BODY_ZONE_HEAD + synthetic_icon_state = "none" /datum/sprite_accessory/snouts/sharp name = "Sharp" @@ -1842,6 +1858,9 @@ /datum/sprite_accessory/horns icon = 'icons/mob/mutant_bodyparts.dmi' + color_src = HAIR + body_zone = BODY_ZONE_HEAD + synthetic_color_src = MUTCOLORS_SECONDARY /datum/sprite_accessory/horns/none name = "None" @@ -1850,18 +1869,22 @@ /datum/sprite_accessory/horns/simple name = "Simple" icon_state = "simple" + synthetic_icon_state = "simple_synth" /datum/sprite_accessory/horns/short name = "Short" icon_state = "short" + synthetic_icon_state = "short_synth" /datum/sprite_accessory/horns/curled name = "Curled" icon_state = "curled" + synthetic_icon_state = "curled_synth" /datum/sprite_accessory/horns/ram name = "Ram" icon_state = "ram" + synthetic_icon_state = "ram_synth" /datum/sprite_accessory/horns/angler name = "Angeler" @@ -2703,7 +2726,7 @@ icon_state = "bun" /datum/sprite_accessory/kepori_body_feathers - color_src = FACEHAIR + color_src = MUTCOLORS_SECONDARY icon = 'icons/mob/kepori_parts.dmi' /datum/sprite_accessory/kepori_body_feathers/none @@ -2730,7 +2753,7 @@ icon_state = "wings" /datum/sprite_accessory/kepori_tail_feathers - color_src = FACEHAIR + color_src = MUTCOLORS_SECONDARY icon = 'icons/mob/kepori_parts.dmi' /datum/sprite_accessory/kepori_tail_feathers/none diff --git a/code/modules/mob/living/carbon/human/consistent_human.dm b/code/modules/mob/living/carbon/human/consistent_human.dm index fb581db3b66b..8694339b964d 100644 --- a/code/modules/mob/living/carbon/human/consistent_human.dm +++ b/code/modules/mob/living/carbon/human/consistent_human.dm @@ -11,6 +11,7 @@ // Mutant randomizing, doesn't affect the mob appearance unless it's the specific mutant. dna.features["mcolor"] = short_color_from_seed(seed * 2) + dna.features["mcolor2"] = short_color_from_seed(seed * 3) //AAAAAAAAAAAAAAAAAAAAAAAAAA dna.features["ethcolor"] = GLOB.color_list_ethereal[GLOB.color_list_ethereal[seed % length(GLOB.color_list_ethereal) + 1]] dna.features["tail_lizard"] = GLOB.tails_list_lizard[seed % length(GLOB.tails_list_lizard) + 1] diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 03aea9d3f0dc..87026d5531d1 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -45,6 +45,9 @@ var/jumpsuit_style = PREF_SUIT //suit/skirt var/exowear = PREF_EXOWEAR //exowear + ///Whether this human started with a full-body prosthesis + var/fbp = FALSE + //Equipment slots var/obj/item/clothing/wear_suit = null var/obj/item/clothing/w_uniform = null diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 63fbbc8a26da..bf5f18fb788d 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -212,9 +212,6 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/changesource_flags = NONE var/loreblurb = "Description not provided. Yell at a coder. Also, please look into cooking fajitas. That stuff is amazing." - // Does this species have unique robotic limbs? (currently used in: kepori and vox) - var/unique_prosthesis = FALSE - //K-Limbs. If a species doesn't have their own limb types. Do not override this, use the K-Limbs overrides at the top of the species datum. var/obj/item/bodypart/species_chest = /obj/item/bodypart/chest var/obj/item/bodypart/species_head = /obj/item/bodypart/head @@ -223,6 +220,28 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/obj/item/bodypart/species_r_leg = /obj/item/bodypart/leg/right var/obj/item/bodypart/species_l_leg = /obj/item/bodypart/leg/left + var/obj/item/bodypart/species_digi_l_leg = /obj/item/bodypart/leg/left/lizard/digitigrade + var/obj/item/bodypart/species_digi_r_leg = /obj/item/bodypart/leg/right/lizard/digitigrade + + var/obj/item/bodypart/species_robotic_chest = /obj/item/bodypart/chest/robot + var/obj/item/bodypart/species_robotic_head = /obj/item/bodypart/head/robot + var/obj/item/bodypart/species_robotic_l_arm = /obj/item/bodypart/l_arm/robot/surplus + var/obj/item/bodypart/species_robotic_r_arm = /obj/item/bodypart/r_arm/robot/surplus + var/obj/item/bodypart/species_robotic_l_leg = /obj/item/bodypart/leg/left/robot/surplus + var/obj/item/bodypart/species_robotic_r_leg = /obj/item/bodypart/leg/right/robot/surplus + + var/obj/item/bodypart/species_robotic_digi_l_leg = /obj/item/bodypart/leg/left/robot/surplus/lizard/digitigrade + var/obj/item/bodypart/species_robotic_digi_r_leg = /obj/item/bodypart/leg/right/robot/surplus/lizard/digitigrade + + var/obj/item/organ/heart/robotic_heart = /obj/item/organ/heart/cybernetic + var/obj/item/organ/lungs/robotic_lungs = /obj/item/organ/lungs/cybernetic + var/obj/item/organ/eyes/robotic_eyes = /obj/item/organ/eyes/robotic + var/obj/item/organ/ears/robotic_ears = /obj/item/organ/ears/cybernetic + var/obj/item/organ/tongue/robotic_tongue = /obj/item/organ/tongue/robot + var/obj/item/organ/liver/robotic_liver = /obj/item/organ/liver/cybernetic + var/obj/item/organ/stomach/robotic_stomach = /obj/item/organ/stomach/cybernetic + var/obj/item/organ/appendix/robotic_appendix = null + ///For custom overrides for species ass images var/icon/ass_image @@ -308,10 +327,18 @@ GLOBAL_LIST_EMPTY(roundstart_races) * * replace_current - boolean, forces all old organs to get deleted whether or not they pass the species' ability to keep that organ * * excluded_zones - list, add zone defines to block organs inside of the zones from getting handled. see headless mutation for an example */ -/datum/species/proc/regenerate_organs(mob/living/carbon/C,datum/species/old_species,replace_current=TRUE,list/excluded_zones) +/datum/species/proc/regenerate_organs(mob/living/carbon/C, datum/species/old_species,replace_current=TRUE, list/excluded_zones, robotic = FALSE) //what should be put in if there is no mutantorgan (brains handled seperately) - var/list/slot_mutantorgans = list(ORGAN_SLOT_BRAIN = mutantbrain, ORGAN_SLOT_HEART = mutantheart, ORGAN_SLOT_LUNGS = mutantlungs, ORGAN_SLOT_APPENDIX = mutantappendix, \ - ORGAN_SLOT_EYES = mutanteyes, ORGAN_SLOT_EARS = mutantears, ORGAN_SLOT_TONGUE = mutanttongue, ORGAN_SLOT_LIVER = mutantliver, ORGAN_SLOT_STOMACH = mutantstomach) + var/list/slot_mutantorgans = list( \ + ORGAN_SLOT_BRAIN = mutantbrain, \ + ORGAN_SLOT_HEART = robotic ? robotic_heart : mutantheart, \ + ORGAN_SLOT_LUNGS = robotic ? robotic_lungs : mutantlungs, \ + ORGAN_SLOT_APPENDIX = robotic ? robotic_appendix : mutantappendix, \ + ORGAN_SLOT_EYES = robotic ? robotic_eyes : mutanteyes, \ + ORGAN_SLOT_EARS = robotic ? robotic_ears : mutantears, \ + ORGAN_SLOT_TONGUE = robotic ? robotic_tongue : mutanttongue, \ + ORGAN_SLOT_LIVER = robotic ? robotic_liver : mutantliver, \ + ORGAN_SLOT_STOMACH = robotic ? robotic_stomach : mutantstomach) for(var/slot in list(ORGAN_SLOT_BRAIN, ORGAN_SLOT_HEART, ORGAN_SLOT_LUNGS, ORGAN_SLOT_APPENDIX, \ ORGAN_SLOT_EYES, ORGAN_SLOT_EARS, ORGAN_SLOT_TONGUE, ORGAN_SLOT_LIVER, ORGAN_SLOT_STOMACH)) @@ -358,73 +385,32 @@ GLOBAL_LIST_EMPTY(roundstart_races) QDEL_NULL(old) I.Insert(C) -/datum/species/proc/replace_body(mob/living/carbon/C, datum/species/new_species) +/datum/species/proc/is_digitigrade(mob/living/carbon/leg_haver) + return (digitigrade_customization == DIGITIGRADE_OPTIONAL && leg_haver.dna.features["legs"] == "Digitigrade Legs") || digitigrade_customization == DIGITIGRADE_FORCED + +/datum/species/proc/replace_body(mob/living/carbon/C, datum/species/new_species, robotic = FALSE) new_species ||= C.dna.species //If no new species is provided, assume its src. //Note for future: Potentionally add a new C.dna.species() to build a template species for more accurate limb replacement - if((new_species.digitigrade_customization == DIGITIGRADE_OPTIONAL && C.dna.features["legs"] == "Digitigrade Legs") || new_species.digitigrade_customization == DIGITIGRADE_FORCED) - new_species.species_r_leg = /obj/item/bodypart/leg/right/digitigrade - new_species.species_l_leg = /obj/item/bodypart/leg/left/digitigrade - for(var/obj/item/bodypart/old_part as anything in C.bodyparts) - if(old_part.change_exempt_flags & BP_BLOCK_CHANGE_SPECIES) - continue - - switch(old_part.body_zone) - if(BODY_ZONE_HEAD) - var/obj/item/bodypart/head/new_part = new new_species.species_head() - new_part.brute_dam = old_part.brute_dam - new_part.burn_dam = old_part.burn_dam - new_part.replace_limb(C, TRUE) - new_part.update_limb(is_creating = TRUE) - qdel(old_part) - if(BODY_ZONE_CHEST) - var/obj/item/bodypart/chest/new_part = new new_species.species_chest() - new_part.brute_dam = old_part.brute_dam - new_part.burn_dam = old_part.burn_dam - new_part.replace_limb(C, TRUE) - new_part.update_limb(is_creating = TRUE) - qdel(old_part) - if(BODY_ZONE_L_ARM) - var/obj/item/bodypart/l_arm/new_part = new new_species.species_l_arm() - new_part.brute_dam = old_part.brute_dam - new_part.burn_dam = old_part.burn_dam - new_part.replace_limb(C, TRUE) - new_part.update_limb(is_creating = TRUE) - qdel(old_part) - if(BODY_ZONE_R_ARM) - var/obj/item/bodypart/r_arm/new_part = new new_species.species_r_arm() - new_part.brute_dam = old_part.brute_dam - new_part.burn_dam = old_part.burn_dam - new_part.replace_limb(C, TRUE) - new_part.update_limb(is_creating = TRUE) - qdel(old_part) - if(BODY_ZONE_L_LEG) - var/obj/item/bodypart/leg/left/new_part = new new_species.species_l_leg() - new_part.brute_dam = old_part.brute_dam - new_part.burn_dam = old_part.burn_dam - new_part.replace_limb(C, TRUE) - new_part.update_limb(is_creating = TRUE) - qdel(old_part) - if(BODY_ZONE_R_LEG) - var/obj/item/bodypart/leg/right/new_part = new new_species.species_r_leg() - new_part.brute_dam = old_part.brute_dam - new_part.burn_dam = old_part.burn_dam - new_part.replace_limb(C, TRUE) - new_part.update_limb(is_creating = TRUE) - qdel(old_part) + var/obj/item/bodypart/new_part = C.new_body_part(old_part.body_zone, robotic, FALSE, new_species) + new_part.brute_dam = old_part.brute_dam + new_part.burn_dam = old_part.burn_dam + new_part.replace_limb(C, TRUE) + new_part.update_limb(is_creating = TRUE) + qdel(old_part) /** - * Proc called when a carbon becomes this species. - * - * This sets up and adds/changes/removes things, qualities, abilities, and traits so that the transformation is as smooth and bugfree as possible. - * Produces a [COMSIG_SPECIES_GAIN] signal. - * Arguments: - * * C - Carbon, this is whoever became the new species. - * * old_species - The species that the carbon used to be before becoming this race, used for regenerating organs. - * * pref_load - Preferences to be loaded from character setup, loads in preferred mutant things like bodyparts, digilegs, skin color, etc. - */ -/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) + * Proc called when a carbon becomes this species. + * + * This sets up and adds/changes/removes things, qualities, abilities, and traits so that the transformation is as smooth and bugfree as possible. + * Produces a [COMSIG_SPECIES_GAIN] signal. + * Arguments: + * * C - Carbon, this is whoever became the new species. + * * old_species - The species that the carbon used to be before becoming this race, used for regenerating organs. + * * pref_load - Preferences to be loaded from character setup, loads in preferred mutant things like bodyparts, digilegs, skin color, etc. +*/ +/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load, robotic = FALSE) // Drop the items the new species can't wear if((AGENDER in species_traits)) C.gender = PLURAL @@ -442,11 +428,11 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(C.hud_used) C.hud_used.update_locked_slots() - replace_body(C) + replace_body(C, robotic = robotic) C.mob_biotypes = inherent_biotypes - regenerate_organs(C,old_species) + regenerate_organs(C, old_species, robotic = robotic) if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype) C.dna.blood_type = get_blood_type(exotic_bloodtype) @@ -890,7 +876,8 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(!H.dna.features["vox_neck_quills"] || H.dna.features["vox_neck_quills"] == "None") bodyparts_to_add -= "vox_neck_quills" -////PUT ALL YOUR WEIRD ASS REAL-LIMB HANDLING HERE + ////PUT ALL YOUR WEIRD ASS REAL-LIMB HANDLING HERE + ///Digi handling if(H.dna.species.bodytype & BODYTYPE_DIGITIGRADE) var/uniform_compatible = FALSE @@ -900,18 +887,13 @@ GLOBAL_LIST_EMPTY(roundstart_races) if((!H.wear_suit) || (H.wear_suit.supports_variations & DIGITIGRADE_VARIATION) || !(H.wear_suit.body_parts_covered & LEGS) || (H.wear_suit.supports_variations & DIGITIGRADE_VARIATION_NO_NEW_ICON)) //Checks suit compatability suit_compatible = TRUE - if((uniform_compatible && suit_compatible) || (suit_compatible && H.wear_suit?.flags_inv & HIDEJUMPSUIT)) //If the uniform is hidden, it doesnt matter if its compatible - for(var/obj/item/bodypart/BP as anything in H.bodyparts) - if(BP.bodytype & BODYTYPE_DIGITIGRADE) - BP.limb_id = "digitigrade" + var/show_digitigrade = suit_compatible && (uniform_compatible || H.wear_suit?.flags_inv & HIDEJUMPSUIT) //If the uniform is hidden, it doesnt matter if its compatible + for(var/obj/item/bodypart/BP as anything in H.bodyparts) + if(BP.bodytype & BODYTYPE_DIGITIGRADE) + BP.plantigrade_forced = !show_digitigrade - else - for(var/obj/item/bodypart/BP as anything in H.bodyparts) - if(BP.bodytype & BODYTYPE_DIGITIGRADE) - BP.limb_id = "lizard" ///End digi handling - ////END REAL-LIMB HANDLING H.update_body_parts() @@ -1008,22 +990,35 @@ GLOBAL_LIST_EMPTY(roundstart_races) else if(bodypart == "waggingtail_lizard" || bodypart == "waggingtail_human" || bodypart == "waggingtail_elzu") bodypart = "waggingtail" + var/used_color_src = S.color_src + + var/icon_state_name = S.icon_state + if(S.synthetic_icon_state) + var/obj/item/bodypart/attachment_point = H.get_bodypart(S.body_zone) + if(attachment_point && IS_ROBOTIC_LIMB(attachment_point)) + icon_state_name = S.synthetic_icon_state + if(S.synthetic_color_src) + used_color_src = S.synthetic_color_src + if(S.gender_specific) - accessory_overlay.icon_state = "[g]_[bodypart]_[S.icon_state]_[layertext]" + accessory_overlay.icon_state = "[g]_[bodypart]_[icon_state_name]_[layertext]" else - accessory_overlay.icon_state = "m_[bodypart]_[S.icon_state]_[layertext]" + accessory_overlay.icon_state = "m_[bodypart]_[icon_state_name]_[layertext]" if(S.center) accessory_overlay = center_image(accessory_overlay, S.dimension_x, S.dimension_y) if(!(HAS_TRAIT(H, TRAIT_HUSK))) if(!forced_colour) - switch(S.color_src) + switch(used_color_src) if(MUTCOLORS) if(fixed_mut_color) accessory_overlay.color = "#[fixed_mut_color]" else accessory_overlay.color = "#[H.dna.features["mcolor"]]" + if(MUTCOLORS_SECONDARY) + accessory_overlay.color = "#[H.dna.features["mcolor2"]]" + if(HAIR) if(hair_color == "mutcolor") accessory_overlay.color = "#[H.dna.features["mcolor"]]" diff --git a/code/modules/mob/living/carbon/human/species_types/IPC.dm b/code/modules/mob/living/carbon/human/species_types/IPC.dm index c0e85d92b65c..9c6e430aa315 100644 --- a/code/modules/mob/living/carbon/human/species_types/IPC.dm +++ b/code/modules/mob/living/carbon/human/species_types/IPC.dm @@ -222,7 +222,7 @@ H.dna.features["ipc_screen"] = saved_screen H.update_body() -/datum/species/ipc/replace_body(mob/living/carbon/C, datum/species/new_species) +/datum/species/ipc/replace_body(mob/living/carbon/C, datum/species/new_species, robotic = FALSE) ..() var/datum/sprite_accessory/ipc_chassis/chassis_of_choice = GLOB.ipc_chassis_list[C.dna.features["ipc_chassis"]] diff --git a/code/modules/mob/living/carbon/human/species_types/kepori.dm b/code/modules/mob/living/carbon/human/species_types/kepori.dm index e569a87d2a7e..980d82ce23a6 100644 --- a/code/modules/mob/living/carbon/human/species_types/kepori.dm +++ b/code/modules/mob/living/carbon/human/species_types/kepori.dm @@ -2,7 +2,7 @@ name = "\improper Kepori" id = SPECIES_KEPORI default_color = "6060FF" - species_traits = list(MUTCOLORS, EYECOLOR, NO_UNDERWEAR) + species_traits = list(MUTCOLORS, EYECOLOR, NO_UNDERWEAR, MUTCOLORS_SECONDARY) inherent_traits = list(TRAIT_SCOOPABLE) mutant_bodyparts = list("kepori_body_feathers", "kepori_tail_feathers", "kepori_feathers") default_features = list("mcolor" = "0F0", "wings" = "None", "kepori_feathers" = "Plain", "kepori_body_feathers" = "Plain", "kepori_tail_feathers" = "Fan", "body_size" = "Normal") @@ -41,7 +41,7 @@ /// See: [/datum/component/tackler/var/skill_mod] var/skill_mod = 2 - unique_prosthesis = TRUE + bodytype = BODYTYPE_KEPORI species_chest = /obj/item/bodypart/chest/kepori species_head = /obj/item/bodypart/head/kepori @@ -50,6 +50,13 @@ species_l_leg = /obj/item/bodypart/leg/left/kepori species_r_leg = /obj/item/bodypart/leg/right/kepori + species_robotic_chest = /obj/item/bodypart/chest/robot/kepori + species_robotic_head = /obj/item/bodypart/head/robot/kepori + species_robotic_l_arm = /obj/item/bodypart/l_arm/robot/surplus/kepori + species_robotic_r_arm = /obj/item/bodypart/r_arm/robot/surplus/kepori + species_robotic_l_leg = /obj/item/bodypart/leg/left/robot/surplus/kepori + species_robotic_r_leg = /obj/item/bodypart/leg/right/robot/surplus/kepori + /datum/species/kepori/New() . = ..() // This is in new because "[HEAD_LAYER]" etc. is NOT a constant compile-time value. For some reason. diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 94975e15e5b7..0f9dc5f05735 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -3,7 +3,7 @@ name = "\improper Sarathi" id = SPECIES_LIZARD default_color = "00FF00" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,SCLERA,EMOTE_OVERLAY) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,SCLERA,EMOTE_OVERLAY,MUTCOLORS_SECONDARY) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs") mutanttongue = /obj/item/organ/tongue/lizard @@ -35,6 +35,16 @@ species_r_arm = /obj/item/bodypart/r_arm/lizard species_l_leg = /obj/item/bodypart/leg/left/lizard species_r_leg = /obj/item/bodypart/leg/right/lizard + + species_robotic_chest = /obj/item/bodypart/chest/robot/lizard + species_robotic_head = /obj/item/bodypart/head/robot/lizard + species_robotic_l_arm = /obj/item/bodypart/l_arm/robot/surplus/lizard + species_robotic_r_arm = /obj/item/bodypart/r_arm/robot/surplus/lizard + species_robotic_l_leg = /obj/item/bodypart/leg/left/robot/surplus/lizard + species_robotic_r_leg = /obj/item/bodypart/leg/right/robot/surplus/lizard + + robotic_eyes = /obj/item/organ/eyes/robotic/lizard + // Lizards are coldblooded and can stand a greater temperature range than humans bodytemp_heat_damage_limit = HUMAN_BODYTEMP_HEAT_DAMAGE_LIMIT + 20 // This puts lizards 10 above lavaland max heat for ash lizards. bodytemp_cold_damage_limit = HUMAN_BODYTEMP_COLD_DAMAGE_LIMIT - 10 diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index b909251061ed..d284224c37d0 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -30,7 +30,7 @@ species_l_leg = /obj/item/bodypart/leg/left/moth species_r_leg = /obj/item/bodypart/leg/right/moth -/datum/species/moth/regenerate_organs(mob/living/carbon/C,datum/species/old_species,replace_current=TRUE,list/excluded_zones) +/datum/species/moth/regenerate_organs(mob/living/carbon/C, datum/species/old_species,replace_current=TRUE, list/excluded_zones, robotic = FALSE) . = ..() if(ishuman(C)) var/mob/living/carbon/human/H = C diff --git a/code/modules/mob/living/carbon/human/species_types/vox.dm b/code/modules/mob/living/carbon/human/species_types/vox.dm index 33aa4f72f90b..678463ced0aa 100644 --- a/code/modules/mob/living/carbon/human/species_types/vox.dm +++ b/code/modules/mob/living/carbon/human/species_types/vox.dm @@ -27,7 +27,7 @@ bodytemp_cold_divisor = VOX_BODYTEMP_COLD_DIVISOR bodytemp_autorecovery_min = VOX_BODYTEMP_AUTORECOVERY_MIN - unique_prosthesis = TRUE + bodytype = BODYTYPE_VOX species_chest = /obj/item/bodypart/chest/vox species_head = /obj/item/bodypart/head/vox @@ -36,6 +36,13 @@ species_l_leg = /obj/item/bodypart/leg/left/vox species_r_leg = /obj/item/bodypart/leg/right/vox + species_robotic_chest = /obj/item/bodypart/chest/robot/vox + species_robotic_head = /obj/item/bodypart/head/robot/vox + species_robotic_l_arm = /obj/item/bodypart/l_arm/robot/surplus/vox + species_robotic_r_arm = /obj/item/bodypart/r_arm/robot/surplus/vox + species_robotic_l_leg = /obj/item/bodypart/leg/left/robot/surplus/vox + species_robotic_r_leg = /obj/item/bodypart/leg/right/robot/surplus/vox + var/datum/action/innate/tail_hold/tail_action var/static/list/allergy_reactions = list( diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index db3ff428dcf2..96410f0cdcb7 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -108,7 +108,7 @@ species_l_leg = /obj/item/bodypart/leg/left/zombie species_r_leg = /obj/item/bodypart/leg/right/zombie -/datum/species/human/krokodil_addict/replace_body(mob/living/carbon/C, datum/species/new_species) +/datum/species/human/krokodil_addict/replace_body(mob/living/carbon/C, datum/species/new_species, robotic = FALSE) ..() var/skintone if(ishuman(C)) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 9d71e9208681..be20a9a5e69d 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -305,7 +305,7 @@ There are several things that need to be remembered: if((dna.species.bodytype & BODYTYPE_DIGITIGRADE) && (I.supports_variations & DIGITIGRADE_VARIATION)) var/obj/item/bodypart/leg = src.get_bodypart(BODY_ZONE_L_LEG) - if(leg.limb_id == "digitigrade")//Snowflakey and bad. But it makes it look consistent. + if(leg.bodytype & BODYTYPE_DIGITIGRADE && !leg.plantigrade_forced) icon_file = DIGITIGRADE_SHOES_PATH if((I.supports_variations & VOX_VARIATION) && (dna.species.bodytype & BODYTYPE_VOX)) diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index d8242f175682..7292436c4d68 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -262,15 +262,17 @@ ///////////////////////// //Updated by Kapu#1178 //TG variant port by MrSamu99#8996 -/* - Called from update_body_parts() these procs handle the limb icon cache. - the limb icon cache adds an icon_render_key to a human mob, it represents: - - Gender, if applicable - - The ID of the limb - - Draw color, if applicable - These procs only store limbs as to increase the number of matching icon_render_keys - This cache exists because drawing 6/7 icons for humans constantly is quite a waste - See RemieRichards on irc.rizon.net #coderbus (RIP remie :sob:) +/** + * Called from update_body_parts() these procs handle the limb icon cache. + * the limb icon cache adds an icon_render_key to a human mob, it represents: + * - Gender, if applicable + * - The ID of the limb + * - Whether or not it's digitigrade + * - Draw color, if applicable + * + * These procs only store limbs as to increase the number of matching icon_render_keys + * This cache exists because drawing 6/7 icons for humans constantly is quite a waste + * See RemieRichards on irc.rizon.net #coderbus (RIP remie :sob:) */ /obj/item/bodypart/proc/generate_icon_key() RETURN_TYPE(/list) @@ -279,6 +281,8 @@ . += "[limb_gender]-" . += "[limb_id]" . += "-[body_zone]" + if(bodytype & BODYTYPE_DIGITIGRADE && !plantigrade_forced) + . += "-digitigrade" if(should_draw_greyscale && draw_color) . += "-[draw_color]" diff --git a/code/modules/research/designs/limbgrower_designs.dm b/code/modules/research/designs/limbgrower_designs.dm index a6322fbb1487..4f48995190dc 100644 --- a/code/modules/research/designs/limbgrower_designs.dm +++ b/code/modules/research/designs/limbgrower_designs.dm @@ -39,7 +39,7 @@ id = "digi_l_leg" build_type = LIMBGROWER reagents_list = list(/datum/reagent/medicine/synthflesh = 25) - build_path = /obj/item/bodypart/leg/left/digitigrade + build_path = /obj/item/bodypart/leg/left/lizard/digitigrade category = list("initial",SPECIES_LIZARD) /datum/design/digitigrade/rightleg @@ -47,7 +47,7 @@ id = "digi_r_leg" build_type = LIMBGROWER reagents_list = list(/datum/reagent/medicine/synthflesh = 25) - build_path = /obj/item/bodypart/leg/right/digitigrade + build_path = /obj/item/bodypart/leg/right/lizard/digitigrade category = list("initial",SPECIES_LIZARD) //Non-limb limb designs diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index f9c735054a3d..bd801e60995e 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -135,6 +135,26 @@ id = "vprosthetic_r_leg" build_path = /obj/item/bodypart/leg/right/robot/surplus/vox +/datum/design/prosthetic_l_arm/lizard + name = "Surplus Prosthetic Lizard Left Arm" + id = "lprosthetic_l_arm" + build_path = /obj/item/bodypart/l_arm/robot/surplus/lizard + +/datum/design/prosthetic_r_arm/lizard + name = "Surplus Prosthetic Lizard Right Arm" + id = "lprosthetic_r_arm" + build_path = /obj/item/bodypart/r_arm/robot/surplus/lizard + +/datum/design/prosthetic_l_leg/lizard + name = "Surplus Prosthetic Lizard Left Leg" + id = "lprosthetic_l_leg" + build_path = /obj/item/bodypart/leg/left/robot/surplus/lizard + +/datum/design/prosthetic_r_leg/lizard + name = "Surplus Prosthetic Lizard Right Leg" + id = "lprosthetic_r_leg" + build_path = /obj/item/bodypart/leg/right/robot/surplus/lizard + //Ripley /datum/design/ripley_chassis name = "Exosuit Chassis (APLU \"Ripley\")" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 49fa47f3cdeb..7588f32ab249 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -78,7 +78,7 @@ display_name = "Biological Technology" description = "What makes us tick." //the MC, silly! prereq_ids = list("base") - design_ids = list("sleeper", "chem_heater", "chem_master", "pandemic", "defibrillator", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "medigel","genescanner", "med_spray_bottle", "chem_pack", "blood_pack", "medical_kiosk", "crewpinpointerprox", "medipen_refiller", "prosthetic_l_arm", "prosthetic_r_arm", "prosthetic_l_leg", "prosthetic_r_leg", "kprosthetic_l_arm", "kprosthetic_r_arm", "kprosthetic_l_leg", "kprosthetic_r_leg", "vprosthetic_l_arm", "vprosthetic_r_arm", "vprosthetic_l_leg", "vprosthetic_r_leg") + design_ids = list("sleeper", "chem_heater", "chem_master", "pandemic", "defibrillator", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "medigel","genescanner", "med_spray_bottle", "chem_pack", "blood_pack", "medical_kiosk", "crewpinpointerprox", "medipen_refiller", "prosthetic_l_arm", "prosthetic_r_arm", "prosthetic_l_leg", "prosthetic_r_leg", "kprosthetic_l_arm", "kprosthetic_r_arm", "kprosthetic_l_leg", "kprosthetic_r_leg", "vprosthetic_l_arm", "vprosthetic_r_arm", "vprosthetic_l_leg", "vprosthetic_r_leg", "lprosthetic_l_arm", "lprosthetic_r_arm", "lprosthetic_l_leg", "lprosthetic_r_leg") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index 48dd4caeeb76..92b51e0f2049 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -12,27 +12,43 @@ layer = BELOW_MOB_LAYER //so it isn't hidden behind objects when on the floor var/mob/living/carbon/owner = null var/datum/weakref/original_owner = null - ///If you'd like to know if a bodypart is organic, please use is_organic_limb() - var/bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC //List of bodytypes flags, important for fitting clothing. - var/change_exempt_flags //Defines when a bodypart should not be changed. Example: BP_BLOCK_CHANGE_SPECIES prevents the limb from being overwritten on species gain - - var/is_husked = FALSE //Duh - var/limb_id = SPECIES_HUMAN //This is effectively the icon_state for limbs. - var/limb_gender = "m" //Defines what sprite the limb should use if it is also sexually dimorphic. - var/uses_mutcolor = TRUE //Does this limb have a greyscale version? - var/is_dimorphic = FALSE //Is there a sprite difference between male and female? - var/draw_color //Greyscale draw color + ///List of bodytypes flags, important for fitting clothing. If you'd like to know if a bodypart is organic, please use is_organic_limb() + var/bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC + + ///Whether the clothing being worn forces the limb into being "squished" to plantigrade/standard humanoid compliance + var/plantigrade_forced = FALSE + ///Whether the limb is husked + var/is_husked = FALSE + ///This is effectively the icon_state prefix for limbs. + var/limb_id = SPECIES_HUMAN + ///Defines what sprite the limb should use if it is also sexually dimorphic. + var/limb_gender = "m" + ///Does this limb have a greyscale version? + var/uses_mutcolor = TRUE + ///Is there a sprite difference between male and female? + var/is_dimorphic = FALSE + ///Greyscale draw color + var/draw_color + + /// The icon state of the limb's overlay, colored with a different color + var/overlay_icon_state + /// The color of the limb's overlay + var/species_secondary_color var/body_zone //BODY_ZONE_CHEST, BODY_ZONE_L_ARM, etc , used for def_zone /// The body zone of this part in english ("chest", "left arm", etc) without the species attached to it var/plaintext_zone var/aux_zone // used for hands var/aux_layer - var/body_part = null //bitflag used to check which clothes cover this bodypart + ///bitflag used to check which clothes cover this bodypart + var/body_part = null var/list/embedded_objects = list() - var/held_index = 0 //are we a hand? if so, which one! - var/is_pseudopart = FALSE //For limbs that don't really exist, eg chainsaws - var/bone_status = BONE_FLAG_NO_BONES // Is it fine, broken, splinted, or just straight up fucking gone + ///Are we a hand? if so, which one! + var/held_index = 0 + ///For limbs that don't really exist, eg chainsaws + var/is_pseudopart = FALSE + /// Is it fine, broken, splinted, or just straight up fucking gone + var/bone_status = BONE_FLAG_NO_BONES var/bone_break_threshold = 30 /// So we know if we need to scream if this limb hits max damage @@ -43,7 +59,8 @@ var/disable_threshold = 1 ///Controls whether bodypart_disabled makes sense or not for this limb. var/can_be_disabled = FALSE - var/body_damage_coeff = 1 //Multiplier of the limb's damage that gets applied to the mob + ///Multiplier of the limb's damage that gets applied to the mob + var/body_damage_coeff = 1 var/stam_damage_coeff = 0.75 //Why is this the default??? - Kapu var/brutestate = 0 var/burnstate = 0 @@ -53,14 +70,18 @@ var/max_stamina_damage = 0 var/max_damage = 0 - var/cremation_progress = 0 //Gradually increases while burning when at full damage, destroys the limb when at 100 + ///Gradually increases while burning when at full damage, destroys the limb when at 100 + var/cremation_progress = 0 - var/brute_reduction = 0 //Subtracted to brute damage taken - var/burn_reduction = 0 //Subtracted to burn damage taken + ///Subtracted from brute damage taken + var/brute_reduction = 0 + ///Subtracted from burn damage taken + var/burn_reduction = 0 //Coloring and proper item icon update var/skin_tone = "" - var/should_draw_greyscale = TRUE //Limbs need this information as a back-up incase they are generated outside of a carbon (limbgrower) + ///Limbs need this information as a back-up incase they are generated outside of a carbon (limbgrower) + var/should_draw_greyscale = TRUE var/species_color = "" var/mutation_color = "" /// The colour of damage done to this bodypart @@ -69,14 +90,17 @@ var/use_damage_color = FALSE var/no_update = 0 - var/animal_origin = null //for nonhuman bodypart (e.g. monkey) - var/dismemberable = 1 //whether it can be dismembered with a weapon. + /// If it's a nonhuman bodypart (e.g. monkey) + var/animal_origin = null + /// Whether it can be dismembered with a weapon + var/dismemberable = TRUE var/px_x = 0 var/px_y = 0 var/species_flags_list = list() - var/dmg_overlay_type //the type of damage overlay (if any) to use when this bodypart is bruised/burned. + ///the type of damage overlay (if any) to use when this bodypart is bruised/burned. + var/dmg_overlay_type //Damage messages used by help_shake_act() var/light_brute_msg = "bruised" @@ -549,6 +573,9 @@ else species_color = null + if(overlay_icon_state) + species_secondary_color = H.dna.features["mcolor2"] + UnregisterSignal(owner, COMSIG_MOVABLE_MOVED) if(NO_BONES in S.species_traits) bone_status = BONE_FLAG_NO_BONES @@ -632,11 +659,13 @@ limb.icon = icon if(!should_draw_greyscale || !icon) limb.icon = static_icon - if(is_dimorphic) //Does this type of limb have sexual dimorphism? - limb.icon_state = "[limb_id]_[body_zone]_[limb_gender]" - else - limb.icon_state = "[limb_id]_[body_zone]" + limb.icon_state = "[limb_id]_[body_zone]" + + if(is_dimorphic) //Does this type of limb have sexual dimorphism? + limb.icon_state += "_[limb_gender]" + if(bodytype & BODYTYPE_DIGITIGRADE && !plantigrade_forced) + limb.icon_state += "_digitigrade" if(!icon_exists(limb.icon, limb.icon_state)) limb_stacktrace("Limb generated with nonexistant icon. File: [limb.icon] | State: [limb.icon_state]", GLOB.Debug) //If you *really* want more of these, you can set the *other* global debug flag manually. @@ -647,6 +676,10 @@ if(aux_zone) //Hand shit aux = image(limb.icon, "[limb_id]_[aux_zone]", -aux_layer, image_dir) . += aux + if(overlay_icon_state) + var/image/overlay = image(limb.icon, "[limb_id]_[aux_zone]_overlay", -aux_layer, image_dir) + overlay.color = "#[species_secondary_color]" + . += overlay draw_color = mutation_color if(should_draw_greyscale) //Should the limb be colored outside of a forced color? @@ -657,6 +690,11 @@ if(aux_zone) aux.color = "#[draw_color]" + if(overlay_icon_state) + var/image/overlay = image(limb.icon, "[limb.icon_state]_overlay", -BODY_ADJ_LAYER, image_dir) + overlay.color = "#[species_secondary_color]" + . += overlay + //Ok so legs are a bit goofy in regards to layering, and we will need two images instead of one to fix that if((body_zone == BODY_ZONE_R_LEG) || (body_zone == BODY_ZONE_L_LEG)) var/obj/item/bodypart/leg/leg_source = src @@ -680,7 +718,8 @@ external_organ.bitflag_to_layer(external_layer), limb_gender, )*/ - return . + + return /obj/item/bodypart/deconstruct(disassembled = TRUE) drop_organs() diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 46cb0f85728d..e360945a16d3 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -381,21 +381,21 @@ /mob/living/proc/regenerate_limbs(noheal = FALSE, list/excluded_zones = list()) SEND_SIGNAL(src, COMSIG_LIVING_REGENERATE_LIMBS, noheal, excluded_zones) -/mob/living/carbon/regenerate_limbs(noheal = FALSE, list/excluded_zones = list()) +/mob/living/carbon/regenerate_limbs(noheal = FALSE, list/excluded_zones = list(), robotic = FALSE) . = ..() var/list/zone_list = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) if(length(excluded_zones)) zone_list -= excluded_zones for(var/Z in zone_list) - . += regenerate_limb(Z, noheal) + . += regenerate_limb(Z, noheal, robotic) -/mob/living/proc/regenerate_limb(limb_zone, noheal) +/mob/living/proc/regenerate_limb(limb_zone, noheal, robotic = FALSE) return -/mob/living/carbon/regenerate_limb(limb_zone, noheal) +/mob/living/carbon/regenerate_limb(limb_zone, noheal, robotic = FALSE) var/obj/item/bodypart/L if(get_bodypart(limb_zone)) return FALSE - L = newBodyPart(limb_zone, 0, 0) + L = new_body_part(limb_zone, robotic, FALSE) L.replace_limb(src, TRUE, TRUE) return 1 diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index c35070ce07be..73ecf0e52444 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -145,24 +145,32 @@ // // FUCK YOU AUGMENT CODE - With love, Kapu //Hi Kapu -/mob/living/carbon/proc/newBodyPart(zone, robotic, fixed_icon) +// this code was perfectly fine kapu +/mob/living/carbon/proc/new_body_part(zone, robotic, fixed_icon, datum/species/species) + species ||= dna.species var/obj/item/bodypart/L switch(zone) if(BODY_ZONE_L_ARM) - L = new dna.species.species_l_arm() + L = robotic ? new species.species_robotic_l_arm() : new species.species_l_arm() if(BODY_ZONE_R_ARM) - L = new dna.species.species_r_arm() + L = robotic ? new species.species_robotic_r_arm() : new species.species_r_arm() if(BODY_ZONE_HEAD) - L = new dna.species.species_head() + L = robotic ? new species.species_robotic_head() : new species.species_head() if(BODY_ZONE_L_LEG) - L = new dna.species.species_l_leg() + if(species.is_digitigrade(src)) + L = robotic ? new species.species_robotic_digi_l_leg() : new species.species_digi_l_leg() + else + L = robotic ? new species.species_robotic_l_leg() : new species.species_l_leg() if(BODY_ZONE_R_LEG) - L = new dna.species.species_r_leg() + if(species.is_digitigrade(src)) + L = robotic ? new species.species_robotic_digi_r_leg() : new species.species_digi_r_leg() + else + L = robotic ? new species.species_robotic_r_leg() : new species.species_r_leg() if(BODY_ZONE_CHEST) - L = new dna.species.species_chest() + L = robotic ? new species.species_robotic_chest() : new species.species_chest() . = L -/mob/living/carbon/monkey/newBodyPart(zone, robotic, fixed_icon) +/mob/living/carbon/monkey/new_body_part(zone, robotic, fixed_icon, datum/species/species) var/obj/item/bodypart/L switch(zone) if(BODY_ZONE_L_ARM) @@ -183,7 +191,7 @@ L.change_bodypart_status(BODYTYPE_ROBOTIC) . = L -/mob/living/carbon/alien/larva/newBodyPart(zone, robotic, fixed_icon) +/mob/living/carbon/alien/larva/new_body_part(zone, robotic, fixed_icon, datum/species/species) var/obj/item/bodypart/L switch(zone) if(BODY_ZONE_HEAD) @@ -196,7 +204,7 @@ L.change_bodypart_status(BODYTYPE_ROBOTIC) . = L -/mob/living/carbon/alien/humanoid/newBodyPart(zone, robotic, fixed_icon) +/mob/living/carbon/alien/humanoid/new_body_part(zone, robotic, fixed_icon, datum/species/species) var/obj/item/bodypart/L switch(zone) if(BODY_ZONE_L_ARM) diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm index ecc911502fc0..79b674438098 100644 --- a/code/modules/surgery/bodyparts/robot_bodyparts.dm +++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm @@ -23,7 +23,6 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC - change_exempt_flags = BP_BLOCK_CHANGE_SPECIES brute_reduction = 5 burn_reduction = 4 @@ -49,7 +48,6 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC - change_exempt_flags = BP_BLOCK_CHANGE_SPECIES brute_reduction = 5 burn_reduction = 4 @@ -75,7 +73,6 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC - change_exempt_flags = BP_BLOCK_CHANGE_SPECIES brute_reduction = 5 burn_reduction = 4 @@ -101,7 +98,6 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC - change_exempt_flags = BP_BLOCK_CHANGE_SPECIES brute_reduction = 5 burn_reduction = 4 @@ -126,7 +122,6 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC - change_exempt_flags = BP_BLOCK_CHANGE_SPECIES brute_reduction = 5 burn_reduction = 4 @@ -232,7 +227,6 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC - change_exempt_flags = BP_BLOCK_CHANGE_SPECIES brute_reduction = 5 burn_reduction = 4 @@ -355,6 +349,89 @@ burn_reduction = 0 max_damage = 20 +// Lizard Robotic (Synths) +/obj/item/bodypart/chest/robot/lizard + name = "prosthetic lizard chest" + is_dimorphic = TRUE + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + acceptable_bodytype = BODYTYPE_HUMANOID + +/obj/item/bodypart/head/robot/lizard + name = "prosthetic lizard head" + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + +/obj/item/bodypart/l_arm/robot/lizard + name = "prosthetic lizard left arm" + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + +/obj/item/bodypart/r_arm/robot/lizard + name = "prosthetic lizard right arm" + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + +/obj/item/bodypart/leg/left/robot/lizard + name = "prosthetic lizard left leg" + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + +/obj/item/bodypart/leg/left/robot/lizard + name = "prosthetic lizard right leg" + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + +// Surplus Lizard Robotic +/obj/item/bodypart/l_arm/robot/surplus/lizard + name = "surplus prosthetic lizard left arm" + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + +/obj/item/bodypart/r_arm/robot/surplus/lizard + name = "surplus prosthetic lizard right arm" + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + +/obj/item/bodypart/leg/left/robot/surplus/lizard + name = "surplus prosthetic lizard left leg" + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + +/obj/item/bodypart/leg/right/robot/surplus/lizard + name = "surplus prosthetic lizard right leg" + icon = 'icons/mob/augmentation/augments_lizard.dmi' + should_draw_greyscale = TRUE + overlay_icon_state = TRUE + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC + +/obj/item/bodypart/leg/left/robot/surplus/lizard/digitigrade + name = "surplus prosthetic digitigrade lizard left leg" + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC | BODYTYPE_DIGITIGRADE + +/obj/item/bodypart/leg/right/robot/surplus/lizard/digitigrade + name = "surplus prosthetic digitigrade lizard right leg" + bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC | BODYTYPE_DIGITIGRADE + +//Kepori Robotic /obj/item/bodypart/chest/robot/kepori name = "prosthetic kepori chest" static_icon = 'icons/mob/augmentation/augments_kepori.dmi' @@ -386,6 +463,7 @@ static_icon = 'icons/mob/augmentation/augments_kepori.dmi' bodytype = BODYTYPE_KEPORI | BODYTYPE_ROBOTIC +//Surplus Kepori Robotic /obj/item/bodypart/l_arm/robot/surplus/kepori name = "surplus prosthetic kepori left arm" static_icon = 'icons/mob/augmentation/augments_kepori.dmi' @@ -406,6 +484,42 @@ static_icon = 'icons/mob/augmentation/augments_kepori.dmi' bodytype = BODYTYPE_KEPORI | BODYTYPE_ROBOTIC + +// Vox Robotic +/obj/item/bodypart/chest/robot/vox + name = "prosthetic vox chest" + is_dimorphic = TRUE + static_icon = 'icons/mob/augmentation/augments_vox.dmi' + bodytype = BODYTYPE_VOX | BODYTYPE_ROBOTIC + acceptable_bodytype = BODYTYPE_VOX + +/obj/item/bodypart/head/robot/vox + name = "prosthetic vox head" + is_dimorphic = TRUE + static_icon = 'icons/mob/augmentation/augments_vox.dmi' + bodytype = BODYTYPE_VOX | BODYTYPE_ROBOTIC + +/obj/item/bodypart/l_arm/robot/vox + name = "prosthetic vox left arm" + static_icon = 'icons/mob/augmentation/augments_vox.dmi' + bodytype = BODYTYPE_VOX | BODYTYPE_ROBOTIC + +/obj/item/bodypart/r_arm/robot/vox + name = "prosthetic vox right arm" + static_icon = 'icons/mob/augmentation/augments_vox.dmi' + bodytype = BODYTYPE_VOX | BODYTYPE_ROBOTIC + +/obj/item/bodypart/l_leg/robot/vox + name = "prosthetic vox left leg" + static_icon = 'icons/mob/augmentation/augments_vox.dmi' + bodytype = BODYTYPE_VOX | BODYTYPE_ROBOTIC + +/obj/item/bodypart/r_leg/robot/vox + name = "prosthetic vox right leg" + static_icon = 'icons/mob/augmentation/augments_vox.dmi' + bodytype = BODYTYPE_VOX | BODYTYPE_ROBOTIC + +// Surplus Vox Robotic /obj/item/bodypart/l_arm/robot/surplus/vox name = "surplus prosthetic vox left arm" static_icon = 'icons/mob/augmentation/augments_vox.dmi' diff --git a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm index 7ca16b5fea5a..2f98458f11aa 100644 --- a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm @@ -29,16 +29,12 @@ uses_mutcolor = TRUE limb_id = SPECIES_LIZARD -/obj/item/bodypart/leg/left/digitigrade +/obj/item/bodypart/leg/left/lizard/digitigrade icon = 'icons/mob/species/lizard/bodyparts.dmi' icon_state = "digitigrade_l_leg" - uses_mutcolor = TRUE - limb_id = "digitigrade" bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC | BODYTYPE_DIGITIGRADE -/obj/item/bodypart/leg/right/digitigrade +/obj/item/bodypart/leg/right/lizard/digitigrade icon = 'icons/mob/species/lizard/bodyparts.dmi' icon_state = "digitigrade_r_leg" - uses_mutcolor = TRUE - limb_id = "digitigrade" bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC | BODYTYPE_DIGITIGRADE diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 56dc170d7700..4ccef6be023f 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -145,6 +145,9 @@ status = ORGAN_ROBOTIC organ_flags = ORGAN_SYNTHETIC +/obj/item/organ/eyes/robotic/lizard + eye_icon_state = "eyes_synth" + /obj/item/organ/eyes/robotic/emp_act(severity) . = ..() if(!owner || . & EMP_PROTECT_SELF) diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 637b48283c18..b877baec2326 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -192,31 +192,28 @@ return 0 /mob/living/carbon/regenerate_organs() - if(dna?.species) - dna.species.regenerate_organs(src) - return - - else - if(!getorganslot(ORGAN_SLOT_LUNGS)) - var/obj/item/organ/lungs/L = new() - L.Insert(src) + if(!getorganslot(ORGAN_SLOT_LUNGS)) + var/obj/item/organ/lungs/L = new() + L.Insert(src) - if(!getorganslot(ORGAN_SLOT_HEART)) - var/obj/item/organ/heart/H = new() - H.Insert(src) + if(!getorganslot(ORGAN_SLOT_HEART)) + var/obj/item/organ/heart/H = new() + H.Insert(src) - if(!getorganslot(ORGAN_SLOT_TONGUE)) - var/obj/item/organ/tongue/T = new() - T.Insert(src) + if(!getorganslot(ORGAN_SLOT_TONGUE)) + var/obj/item/organ/tongue/T = new() + T.Insert(src) - if(!getorganslot(ORGAN_SLOT_EYES)) - var/obj/item/organ/eyes/E = new() - E.Insert(src) + if(!getorganslot(ORGAN_SLOT_EYES)) + var/obj/item/organ/eyes/E = new() + E.Insert(src) - if(!getorganslot(ORGAN_SLOT_EARS)) - var/obj/item/organ/ears/ears = new() - ears.Insert(src) + if(!getorganslot(ORGAN_SLOT_EARS)) + var/obj/item/organ/ears/ears = new() + ears.Insert(src) +/mob/living/carbon/human/regenerate_organs() + dna.species.regenerate_organs(src, robotic = fbp) /** get_availability * returns whether the species should innately have this organ. diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm index 1e41fad619ee..849c270e5a73 100644 --- a/code/modules/surgery/prosthetic_replacement.dm +++ b/code/modules/surgery/prosthetic_replacement.dm @@ -86,7 +86,7 @@ "[user] successfully replaces [target]'s [parse_zone(target_zone)]!") return else - var/obj/item/bodypart/L = target.newBodyPart(target_zone, FALSE, FALSE) + var/obj/item/bodypart/L = target.new_body_part(target_zone, FALSE, FALSE) L.is_pseudopart = TRUE if(!L.attach_limb(target)) display_results(user, target, "You fail in attaching [target]'s [parse_zone(target_zone)]! Their body has rejected [L]!", diff --git a/icons/mob/augmentation/augments_lizard.dmi b/icons/mob/augmentation/augments_lizard.dmi new file mode 100644 index 000000000000..9275462399d6 Binary files /dev/null and b/icons/mob/augmentation/augments_lizard.dmi differ diff --git a/icons/mob/augmentation/augments_vox.dmi b/icons/mob/augmentation/augments_vox.dmi index a837dba50ed7..5534adb59aed 100644 Binary files a/icons/mob/augmentation/augments_vox.dmi and b/icons/mob/augmentation/augments_vox.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 5d1499e366b8..834fcfc067e1 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/mutant_bodyparts.dmi b/icons/mob/mutant_bodyparts.dmi index 3f9338ef4a34..c8d6acff0593 100644 Binary files a/icons/mob/mutant_bodyparts.dmi and b/icons/mob/mutant_bodyparts.dmi differ diff --git a/icons/mob/species/lizard/bodyparts.dmi b/icons/mob/species/lizard/bodyparts.dmi index 6eadfa27a509..fdb74047e79a 100644 Binary files a/icons/mob/species/lizard/bodyparts.dmi and b/icons/mob/species/lizard/bodyparts.dmi differ