From a9af8b1532dac79af42bdf066e5824131d6c424e Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Sat, 26 Sep 2015 23:24:52 -0700 Subject: [PATCH] Frankenstein This commit does the following - Organs are no longer reliant on the species and DNA of their attached owner. Whoever made the organs (ex a spawned mob) transfers their species and DNA to the organ, and it uses that for calculations. - You may now attach organs cross-species; Yes, this means sticking skrell heads onto humans to make tentacle monsters. Or something. - IPC's may now choose their frame color. - I did say elsewhere this was not feasible; However, after taking a few hours to learn the systems behind all of it, I managed to hack something together. It's snowflakey, but fuck it, it doesn't need to be not-snowflakey. --- .../mob/living/carbon/human/appearance.dm | 5 +-- code/modules/mob/living/carbon/human/human.dm | 12 ++++-- .../mob/living/carbon/human/human_organs.dm | 7 +++- .../living/carbon/human/species/station.dm | 23 ++++++----- .../mob/living/carbon/human/update_icons.dm | 15 ++++--- code/modules/organs/organ.dm | 19 +++++++-- code/modules/organs/organ_icon.dm | 41 +++++++++++++------ 7 files changed, 82 insertions(+), 40 deletions(-) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index ff2b98d430f..bc0226f4597 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -110,7 +110,7 @@ return 1 /mob/living/carbon/human/proc/change_skin_color(var/red, var/green, var/blue) - if(red == r_skin && green == g_skin && blue == b_skin || !(species.flags & HAS_SKIN_COLOR)) + if(red == r_skin && green == g_skin && blue == b_skin || !(species.bodyflags & HAS_SKIN_COLOR)) return r_skin = red @@ -122,7 +122,7 @@ return 1 /mob/living/carbon/human/proc/change_skin_tone(var/tone) - if(s_tone == tone || !(species.flags & HAS_SKIN_TONE)) + if(s_tone == tone || !(species.bodyflags & HAS_SKIN_TONE)) return s_tone = tone @@ -182,4 +182,3 @@ valid_facial_hairstyles += facialhairstyle return valid_facial_hairstyles - \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0e943d8c257..1b1964a000f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -10,6 +10,11 @@ var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us. /mob/living/carbon/human/New(var/new_loc, var/new_species = null, var/delay_ready_dna=0) + + if(!dna) + dna = new /datum/dna(null) + // Species name is handled by set_species() + if(!species) if(new_species) set_species(new_species,1) @@ -36,9 +41,6 @@ ..() - if(dna) - dna.real_name = real_name - prev_gender = gender // Debug for plural genders make_blood() @@ -46,8 +48,10 @@ faction |= "\ref[M]" // Set up DNA. - if(!delay_ready_dna) + if(!delay_ready_dna && dna) dna.ready_dna(src) + dna.real_name = real_name + sync_organ_dna() //this shouldn't be necessaaaarrrryyyyyyyy UpdateAppearance() /mob/living/carbon/human/Destroy() diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 8889e5370da..7654b0d2e3b 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -144,4 +144,9 @@ //New are added for reagents to random organs. for(var/datum/reagent/A in reagents.reagent_list) var/obj/item/organ/O = pick(organs) - O.trace_chemicals[A.name] = 100 \ No newline at end of file + O.trace_chemicals[A.name] = 100 + +/mob/living/carbon/human/proc/sync_organ_dna() + var/list/all_bits = internal_organs|organs + for(var/obj/item/organ/O in all_bits) + O.set_dna(dna) diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index b525919b5bc..f3d61c038c7 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -59,7 +59,7 @@ /datum/species/unathi/handle_death(var/mob/living/carbon/human/H) H.stop_tail_wagging(1) - + /datum/species/unathi/equip(var/mob/living/carbon/human/H) if(H.mind.assigned_role != "Clown") H.unEquip(H.shoes) @@ -105,7 +105,7 @@ /datum/species/tajaran/handle_death(var/mob/living/carbon/human/H) H.stop_tail_wagging(1) - + /datum/species/tajaran/equip(var/mob/living/carbon/human/H) if(H.mind.assigned_role != "Clown") H.unEquip(H.shoes) @@ -219,7 +219,7 @@ i++ newname += pick(vox_name_syllables) return capitalize(newname) - + /datum/species/vox/equip(var/mob/living/carbon/human/H) if(H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime") H.unEquip(H.wear_mask) @@ -235,7 +235,7 @@ H.internal = H.l_hand if (H.internals) H.internals.icon_state = "internal1" - + /* /datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H) H.verbs += /mob/living/carbon/human/proc/leap @@ -469,20 +469,20 @@ /datum/species/machine name = "Machine" name_plural = "Machines" - + blurb = "Positronic intelligence really took off in the 26th century, and it is not uncommon to see independant, free-willed \ robots on many human stations, particularly in fringe systems where standards are slightly lax and public opinion less relevant \ to corporate operations. IPCs (Integrated Positronic Chassis) are a loose category of self-willed robots with a humanoid form, \ generally self-owned after being 'born' into servitude; they are reliable and dedicated workers, albeit more than slightly \ - inhuman in outlook and perspective." - + inhuman in outlook and perspective." + icobase = 'icons/mob/human_races/r_machine.dmi' deform = 'icons/mob/human_races/r_machine.dmi' path = /mob/living/carbon/human/machine default_language = "Galactic Common" language = "Trinary" unarmed_type = /datum/unarmed_attack/punch - + eyes = "blank_eyes" brute_mod = 2.5 // 100% * 2.5 * 0.6 (robolimbs) ~= 150% burn_mod = 2.5 // So they take 50% extra damage from brute/burn overall. @@ -500,20 +500,21 @@ flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_DNA_RAD clothing_flags = HAS_SOCKS + bodyflags = HAS_SKIN_COLOR dietflags = 0 //IPCs can't eat, so no diet blood_color = "#1F181F" flesh_color = "#AAAAAA" virus_immune = 1 can_revive_by_healing = 1 reagent_tag = PROCESS_SYN - + has_organ = list( "brain" = /obj/item/organ/mmi_holder/posibrain, "cell" = /obj/item/organ/cell, "optics" = /obj/item/organ/optical_sensor ) - vision_organ = "optics" + vision_organ = "optics" has_limbs = list( "chest" = list("path" = /obj/item/organ/external/chest/ipc), "groin" = list("path" = /obj/item/organ/external/groin/ipc), @@ -532,7 +533,7 @@ H.h_style = "" spawn(100) if(H) H.update_hair() - + /datum/species/machine/handle_post_spawn(var/mob/living/carbon/human/H) ..() H.verbs += /mob/living/carbon/human/proc/change_monitor \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 4c99dd12895..86c2d79eb7b 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -238,15 +238,13 @@ var/global/list/damage_icon_parts = list() var/hulk = (HULK in src.mutations) var/skeleton = (SKELETON in src.mutations) - var/g = (gender == FEMALE ? "f" : "m") - //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. //Create a new, blank icon for our mob to use. if(stand_icon) qdel(stand_icon) stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank") - var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin]" + var/icon_key = "" var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] if(eyes) @@ -265,6 +263,13 @@ var/global/list/damage_icon_parts = list() else icon_key += "1" + if(part) + icon_key += "[part.species.race_key]" + icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]" + icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]" + if(part.s_col) + icon_key += "[rgb(part.s_col[1], part.s_col[2], part.s_col[3])]" + icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0]" var/icon/base_icon @@ -868,8 +873,8 @@ var/global/list/damage_icon_parts = list() var/image/I = image("icon" = r_hand.righthand_file, "icon_state"="[t_state]") I = center_image(I, r_hand.inhand_x_dimension, r_hand.inhand_y_dimension) - overlays_standing[R_HAND_LAYER] = I - + overlays_standing[R_HAND_LAYER] = I + if (handcuffed) drop_r_hand() else overlays_standing[R_HAND_LAYER] = null diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 1a5808ec7d3..a93d2a278a8 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -21,7 +21,8 @@ var/list/organ_cache = list() var/list/trace_chemicals = list() // traces of chemicals in the organ, // links chemical IDs to number of ticks for which they'll stay in the blood germ_level = 0 - + var/datum/dna/dna + var/datum/species/species /obj/item/organ/Destroy() if(!owner) @@ -59,6 +60,12 @@ var/list/organ_cache = list() max_damage = min_broken_damage * 2 if(istype(holder)) src.owner = holder + species = all_species["Human"] + if(holder.dna) + dna = holder.dna.Clone() + species = all_species[dna.species] + else + log_to_dd("[src] at [loc] spawned without a proper DNA.") var/mob/living/carbon/human/H = holder if(istype(H)) if(internal) @@ -67,13 +74,19 @@ var/list/organ_cache = list() if(E.internal_organs == null) E.internal_organs = list() E.internal_organs |= src - if(H.dna) + if(dna) if(!blood_DNA) blood_DNA = list() - blood_DNA[H.dna.unique_enzymes] = H.dna.b_type + blood_DNA[dna.unique_enzymes] = dna.b_type if(internal) holder.internal_organs |= src +/obj/item/organ/proc/set_dna(var/datum/dna/new_dna) + if(new_dna) + dna = new_dna.Clone() + blood_DNA.Cut() + blood_DNA[dna.unique_enzymes] = dna.b_type + /obj/item/organ/proc/die() if(status & ORGAN_ROBOT) return diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 26ca1f5079a..e3e95e78df3 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -12,13 +12,25 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human) s_tone = null s_col = null - if(status & ORGAN_ROBOT) + if(status & ORGAN_ROBOT && !(species && species.name == "Machine")) //machine people get skin color + return + if(species && human.species && species.name != human.species.name) return if(!isnull(human.s_tone) && (human.species.bodyflags & HAS_SKIN_TONE)) s_tone = human.s_tone if(human.species.bodyflags & HAS_SKIN_COLOR) s_col = list(human.r_skin, human.g_skin, human.b_skin) +/obj/item/organ/external/proc/sync_colour_to_dna() + s_tone = null + s_col = null + if(status & ORGAN_ROBOT) + return + if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && (species.flags & HAS_SKIN_TONE)) + s_tone = dna.GetUIValue(DNA_UI_SKIN_TONE) + if(species.flags & HAS_SKIN_COLOR) + s_col = list(dna.GetUIValue(DNA_UI_SKIN_R), dna.GetUIValue(DNA_UI_SKIN_G), dna.GetUIValue(DNA_UI_SKIN_B)) + /obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/human) ..() var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] @@ -34,11 +46,11 @@ var/global/list/limb_icon_cache = list() overlays.Cut() if(!owner) return - - if(owner.species.has_organ["eyes"]) + + if(species.has_organ["eyes"]) var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] - if(owner.species.eyes) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', owner.species.eyes) + if(species.eyes) + var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes) if(eyes) eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD) else @@ -46,14 +58,14 @@ var/global/list/limb_icon_cache = list() mob_icon.Blend(eyes_icon, ICON_OVERLAY) overlays |= eyes_icon - if(owner.lip_style && (owner.species && (owner.species.flags & HAS_LIPS))) + if(owner.lip_style && (species && (species.flags & HAS_LIPS))) var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") overlays |= lip_icon mob_icon.Blend(lip_icon, ICON_OVERLAY) if(owner.f_style) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] - if(facial_hair_style && facial_hair_style.species_allowed && (owner.species.name in facial_hair_style.species_allowed)) + if(facial_hair_style && facial_hair_style.species_allowed && (species.name in facial_hair_style.species_allowed)) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") if(facial_hair_style.do_colouration) facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD) @@ -61,7 +73,7 @@ var/global/list/limb_icon_cache = list() if(owner.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style] - if(hair_style && (owner.species.name in hair_style.species_allowed)) + if(hair_style && (species.name in hair_style.species_allowed)) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") if(hair_style.do_colouration) hair_s.Blend(rgb(owner.r_hair, owner.g_hair, owner.b_hair), ICON_ADD) @@ -74,26 +86,29 @@ var/global/list/limb_icon_cache = list() var/gender if(force_icon) mob_icon = new /icon(force_icon, "[icon_name]") + if(species && species.name == "Machine") //snowflake for IPC's, sorry. + if(s_col && s_col.len >= 3) + mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD) else - if(!owner) + if(!dna) mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_f" : ""]") else if(gendered_icon) - if(owner.gender == FEMALE) + if(dna.GetUIState(DNA_UI_GENDER)) gender = "f" else gender = "m" if(skeletal) mob_icon = new /icon('icons/mob/human_races/r_skeleton.dmi', "[icon_name][gender ? "_[gender]" : ""]") - else if (status & ORGAN_ROBOT) + else if(status & ORGAN_ROBOT) mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]") else if (status & ORGAN_MUTATED) - mob_icon = new /icon(owner.species.deform, "[icon_name][gender ? "_[gender]" : ""]") + mob_icon = new /icon(species.deform, "[icon_name][gender ? "_[gender]" : ""]") else - mob_icon = new /icon(owner.species.icobase, "[icon_name][gender ? "_[gender]" : ""]") + mob_icon = new /icon(species.icobase, "[icon_name][gender ? "_[gender]" : ""]") if(status & ORGAN_DEAD) mob_icon.ColorTone(rgb(10,50,0))