Frankenstein edition:

Limbs now store their own dna/species info. This allows transplanted limbs show up as they are, instead of conforming to mob. Vox-cat-monkey hybrids, rainbow skrells, go wild.
Also changed rejection to cause infection instead of straight up organ damage - wouldn't want your newly acquired catpaws fracture out of blue.
As a bonus, attacks are tracked per limb, so for example having kitty claws will give you the corresponding attack
This commit is contained in:
Chinsky
2015-05-20 02:59:19 +03:00
parent 05975d78b1
commit 1089da7fb1
6 changed files with 72 additions and 42 deletions
@@ -118,6 +118,7 @@
b_skin = blue
force_update_limbs()
update_body()
return 1
/mob/living/carbon/human/proc/change_skin_tone(var/tone)
@@ -127,6 +128,7 @@
s_tone = tone
force_update_limbs()
update_body()
return 1
/mob/living/carbon/human/proc/update_dna()
@@ -176,8 +176,13 @@
miss_type = 2
// See what attack they use
var/possible_moves = list()
var/datum/unarmed_attack/attack = null
for(var/datum/unarmed_attack/u_attack in H.species.unarmed_attacks)
for(var/part in list("l_hand","r_hand","l_foot","r_foot","head"))
var/obj/item/organ/external/E = H.get_organ(part)
possible_moves |= E.species.unarmed_attacks
for(var/datum/unarmed_attack/u_attack in possible_moves)
if(!u_attack.is_usable(H, src, hit_zone))
continue
else
@@ -234,15 +234,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)
@@ -260,7 +258,12 @@ var/global/list/damage_icon_parts = list()
icon_key += "3"
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
@@ -894,22 +897,22 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/proc/get_tail_icon()
var/icon_key = "[species.race_key][r_skin][g_skin][b_skin]"
var/icon/tail_icon = tail_icon_cache[icon_key]
if(!tail_icon)
if(!tail_icon)
//generate a new one
tail_icon = new/icon(icon = (species.tail_animation? species.tail_animation : 'icons/effects/species.dmi'))
tail_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
tail_icon_cache[icon_key] = tail_icon
return tail_icon
/mob/living/carbon/human/proc/set_tail_state(var/t_state)
var/image/tail_overlay = overlays_standing[TAIL_LAYER]
if(tail_overlay && species.tail_animation)
tail_overlay.icon_state = t_state
return tail_overlay
@@ -919,30 +922,30 @@ var/global/list/damage_icon_parts = list()
//Update this if the ability to flick() images or make looping animation start at the first frame is ever added.
/mob/living/carbon/human/proc/animate_tail_once(var/update_icons=1)
var/t_state = "[species.tail]_once"
var/image/tail_overlay = overlays_standing[TAIL_LAYER]
if(tail_overlay && tail_overlay.icon_state == t_state)
return //let the existing animation finish
tail_overlay = set_tail_state(t_state)
if(tail_overlay)
spawn(15)
//check that the animation hasn't changed in the meantime
if(overlays_standing[TAIL_LAYER] == tail_overlay && tail_overlay.icon_state == t_state)
animate_tail_stop()
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/animate_tail_start(var/update_icons=1)
set_tail_state("[species.tail]_slow[rand(0,9)]")
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/animate_tail_fast(var/update_icons=1)
set_tail_state("[species.tail]_loop[rand(0,9)]")
if(update_icons)
update_icons()
@@ -951,14 +954,14 @@ var/global/list/damage_icon_parts = list()
set_tail_state("[species.tail]_idle[rand(0,9)]")
else
set_tail_state("[species.tail]_static")
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/animate_tail_stop(var/update_icons=1)
set_tail_state("[species.tail]_static")
if(update_icons)
update_icons()
+19 -12
View File
@@ -23,6 +23,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/proc/update_health()
return
@@ -34,6 +36,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_debug("[src] at [loc] spawned without a proper DNA.")
var/mob/living/carbon/human/H = holder
if(istype(H))
if(internal)
@@ -42,10 +50,10 @@ 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
@@ -123,24 +131,23 @@ var/list/organ_cache = list()
/obj/item/organ/proc/handle_rejection()
// Process unsuitable transplants. TODO: consider some kind of
// immunosuppressant that changes transplant data to make it match.
if(transplant_data)
if(!rejecting && prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type,owner.species,transplant_data["species"]))
rejecting = 1
if(dna)
if(!rejecting)
if(blood_incompatible(dna.b_type, owner.dna.b_type, species, owner.species))
rejecting = 1
else
rejecting++ //Rejection severity increases over time.
if(rejecting % 10 == 0) //Only fire every ten rejection ticks.
switch(rejecting)
if(1 to 50)
take_damage(1)
germ_level++
if(51 to 200)
owner.reagents.add_reagent("toxin", 1)
take_damage(1)
germ_level += rand(1,2)
if(201 to 500)
take_damage(rand(2,3))
owner.reagents.add_reagent("toxin", 2)
germ_level += rand(2,3)
if(501 to INFINITY)
take_damage(4)
owner.reagents.add_reagent("toxin", rand(3,5))
germ_level += rand(3,5)
owner.reagents.add_reagent("toxin", rand(1,2))
/obj/item/organ/proc/receive_chem(chemical as obj)
return 0
+23 -11
View File
@@ -17,11 +17,23 @@ var/global/list/limb_icon_cache = list()
s_col = null
if(status & ORGAN_ROBOT)
return
if(species && human.species && species.name != human.species.name)
return
if(!isnull(human.s_tone) && (human.species.flags & HAS_SKIN_TONE))
s_tone = human.s_tone
if(human.species.flags & 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"]
@@ -35,10 +47,10 @@ var/global/list/limb_icon_cache = list()
..()
overlays.Cut()
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)
@@ -75,25 +87,25 @@ var/global/list/limb_icon_cache = list()
if(force_icon)
mob_icon = new /icon(force_icon, "[icon_name]")
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) && !(owner.species && owner.species.flags & IS_SYNTHETIC))
else if ((status & ORGAN_ROBOT) && !(species && species.flags & IS_SYNTHETIC))
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))
+1
View File
@@ -7,6 +7,7 @@ var/global/datum/robolimb/basic_robolimb
for(var/limb_type in typesof(/datum/robolimb))
var/datum/robolimb/R = new limb_type()
all_robolimbs[R.company] = R
world << "Adding [R.company] as [R], [R.type]"
if(!R.unavailable_at_chargen)
chargen_robolimbs[R.company] = R