[MIRROR] DNA Clone Fix (#10580)

Co-authored-by: Will <7099514+Willburd@users.noreply.github.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-04-03 13:13:01 -07:00
committed by GitHub
parent 036ed10454
commit e902125c5e
21 changed files with 199 additions and 138 deletions

View File

@@ -40,6 +40,7 @@ jobs:
${{ runner.os }}-spacemandmm- ${{ runner.os }}-spacemandmm-
- name: Install Tools - name: Install Tools
run: | run: |
sudo apt update
bash tools/ci/install_spaceman_dmm.sh dmm-tools bash tools/ci/install_spaceman_dmm.sh dmm-tools
sudo apt install -y imagemagick sudo apt install -y imagemagick
- name: Ensure +x on github-actions directory - name: Ensure +x on github-actions directory

View File

@@ -12,6 +12,7 @@
#define NO_INFECT 0x400 // Don't allow infections in limbs or organs, similar to IS_PLANT, without other strings. #define NO_INFECT 0x400 // Don't allow infections in limbs or organs, similar to IS_PLANT, without other strings.
#define NO_DEFIB 0x800 // Don't allow them to be defibbed #define NO_DEFIB 0x800 // Don't allow them to be defibbed
#define NO_DNA 0x1000 // Cannot have mutations or have their dna changed by genetics/radiation/genome-stolen. #define NO_DNA 0x1000 // Cannot have mutations or have their dna changed by genetics/radiation/genome-stolen.
#define THICK_SKIN 0x2000 // Needles have a chain to fail when attempted to be used on them.
// unused: 0x8000 - higher than this will overflow // unused: 0x8000 - higher than this will overflow
// Species EMP vuln for carbons // Species EMP vuln for carbons

View File

@@ -302,12 +302,10 @@
else else
return 0 return 0
//VOREStation Add
/mob/living/carbon/human/proc/force_update_organs() /mob/living/carbon/human/proc/force_update_organs()
for(var/obj/item/organ/O as anything in organs + internal_organs) for(var/obj/item/organ/O as anything in organs + internal_organs)
O.species = species O.data.setup_from_species(species)
species.post_spawn_special(src) species.post_spawn_special(src)
//VOREStation Add End
// Used below, simple injection modifier. // Used below, simple injection modifier.
/proc/probinj(var/pr, var/inj) /proc/probinj(var/pr, var/inj)

View File

@@ -254,7 +254,7 @@
O.status |= ORGAN_CUT_AWAY O.status |= ORGAN_CUT_AWAY
var/mob/living/carbon/human/C = loaded_dna["donor"] var/mob/living/carbon/human/C = loaded_dna["donor"]
O.set_dna(C.dna) O.set_dna(C.dna)
O.species = C.species O.data.setup_from_species(C.species)
var/malfunctioned = FALSE var/malfunctioned = FALSE
@@ -264,7 +264,7 @@
var/new_species = pick(possible_species) var/new_species = pick(possible_species)
if(!GLOB.all_species[new_species]) if(!GLOB.all_species[new_species])
new_species = SPECIES_HUMAN new_species = SPECIES_HUMAN
O.species = GLOB.all_species[new_species] O.data.setup_from_species(GLOB.all_species[new_species])
if(istype(O, /obj/item/organ/external) && !malfunctioned) if(istype(O, /obj/item/organ/external) && !malfunctioned)
var/obj/item/organ/external/E = O var/obj/item/organ/external/E = O
@@ -273,9 +273,9 @@
O.pixel_x = rand(-6.0, 6) O.pixel_x = rand(-6.0, 6)
O.pixel_y = rand(-6.0, 6) O.pixel_y = rand(-6.0, 6)
if(O.species) if(O.data)
// This is a very hacky way of doing of what organ/New() does if it has an owner // This is a very hacky way of doing of what organ/New() does if it has an owner
O.w_class = max(O.w_class + mob_size_difference(O.species.mob_size, MOB_MEDIUM), 1) O.w_class = max(O.w_class + mob_size_difference(O.data.get_species_mob_size(), MOB_MEDIUM), 1)
return O return O
// END GENERIC PRINTER // END GENERIC PRINTER

View File

@@ -209,7 +209,7 @@
if(ishuman(victim) && user.zone_sel.selecting != BP_GROIN && user.zone_sel.selecting != BP_TORSO) if(ishuman(victim) && user.zone_sel.selecting != BP_GROIN && user.zone_sel.selecting != BP_TORSO)
var/mob/living/carbon/human/H = victim var/mob/living/carbon/human/H = victim
E = H.get_organ(user.zone_sel.selecting) E = H.get_organ(user.zone_sel.selecting)
if(!E || E.species.flags & NO_PAIN) if(!E || E.data.get_species_flags() & NO_PAIN)
nopain = 2 nopain = 2
else if(E.robotic >= ORGAN_ROBOT) else if(E.robotic >= ORGAN_ROBOT)
nopain = 1 nopain = 1

View File

@@ -62,8 +62,6 @@
var/mob/living/simple_mob/SM = src var/mob/living/simple_mob/SM = src
if(SM.limb_icon) if(SM.limb_icon)
neworg.force_icon = SM.limb_icon neworg.force_icon = SM.limb_icon
neworg.force_icon_key = SM.limb_icon_key
organs |= neworg organs |= neworg
organs -= path organs -= path

View File

@@ -172,8 +172,7 @@
/mob/living/carbon/human/proc/update_dna() /mob/living/carbon/human/proc/update_dna()
check_dna() check_dna()
dna.ready_dna(src) dna.ready_dna(src)
for(var/obj/item/organ/O in organs) sync_organ_dna(dna)
qdel_swap(O.dna, dna.Clone()) // Update all of those because apparently they're separate, and icons won't update properly
/mob/living/carbon/human/proc/generate_valid_species(var/check_whitelist = 1, var/list/whitelist = list(), var/list/blacklist = list()) /mob/living/carbon/human/proc/generate_valid_species(var/check_whitelist = 1, var/list/whitelist = list(), var/list/blacklist = list())
var/list/valid_species = new() var/list/valid_species = new()
@@ -198,7 +197,7 @@
var/use_species = species.get_bodytype(src) var/use_species = species.get_bodytype(src)
var/obj/item/organ/external/head/H = get_organ(BP_HEAD) var/obj/item/organ/external/head/H = get_organ(BP_HEAD)
if(H) use_species = H.species.get_bodytype(src) if(H) use_species = H.data.get_species_bodytype(src)
var/list/valid_hairstyles = new() var/list/valid_hairstyles = new()
for(var/hairstyle in hair_styles_list) for(var/hairstyle in hair_styles_list)
@@ -224,7 +223,7 @@
var/use_species = species.get_bodytype(src) var/use_species = species.get_bodytype(src)
var/obj/item/organ/external/head/H = get_organ(BP_HEAD) var/obj/item/organ/external/head/H = get_organ(BP_HEAD)
if(H) use_species = H.species.get_bodytype(src) if(H) use_species = H.data.get_species_bodytype(src)
var/list/valid_facial_hairstyles = new() var/list/valid_facial_hairstyles = new()
for(var/facialhairstyle in facial_hair_styles_list) for(var/facialhairstyle in facial_hair_styles_list)

View File

@@ -1432,7 +1432,7 @@
else if (affecting.robotic >= ORGAN_LIFELIKE) else if (affecting.robotic >= ORGAN_LIFELIKE)
. = 0 . = 0
fail_msg = "Your needle refuses to penetrate more than a short distance..." fail_msg = "Your needle refuses to penetrate more than a short distance..."
else if (affecting.thick_skin && prob(70 - round(affecting.brute_dam + affecting.burn_dam / 2))) // Allows transplanted limbs with thick skin to maintain their resistance. else if ((species.flags & THICK_SKIN) && prob(70 - round(affecting.brute_dam + affecting.burn_dam / 2))) // Allows transplanted limbs with thick skin to maintain their resistance.
. = 0 . = 0
fail_msg = "Your needle fails to penetrate \the [affecting]'s thick hide..." fail_msg = "Your needle fails to penetrate \the [affecting]'s thick hide..."
else else

View File

@@ -276,7 +276,7 @@ var/list/wrapped_species_by_ref = list()
for(var/limb in organs_by_name) for(var/limb in organs_by_name)
var/obj/item/organ/external/O = organs_by_name[limb] var/obj/item/organ/external/O = organs_by_name[limb]
if(limb_exists[O.organ_tag]) if(limb_exists[O.organ_tag])
O.species = GLOB.all_species[new_species] O.data.setup_from_species(GLOB.all_species[new_species])
O.wounds = wounds_by_limb[O.organ_tag] O.wounds = wounds_by_limb[O.organ_tag]
// sync the organ's damage with its wounds // sync the organ's damage with its wounds
O.update_damages() O.update_damages()

View File

@@ -24,7 +24,7 @@
cold_level_2 = -1 cold_level_2 = -1
cold_level_3 = -1 cold_level_3 = -1
flags = NO_DNA | NO_SLEEVE | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT | NO_INFECT | NO_DEFIB flags = NO_DNA | NO_SLEEVE | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT | NO_INFECT | NO_DEFIB | THICK_SKIN
spawn_flags = SPECIES_IS_RESTRICTED spawn_flags = SPECIES_IS_RESTRICTED
reagent_tag = IS_XENOS reagent_tag = IS_XENOS

View File

@@ -226,8 +226,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //see UpdateDamageIcon()
continue continue
if(part) if(part)
wholeicontransparent &&= part.transparent //VORESTATION EDIT: transparent instead of nonsolid wholeicontransparent &&= part.transparent //VORESTATION EDIT: transparent instead of nonsolid
icon_key += "[part.species.get_race_key(part.owner)]" icon_key += "[part.data.get_species_race_key(part.owner)]"
icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]" icon_key += "[part.data.body_gender]"
icon_key += "[part.s_tone]" icon_key += "[part.s_tone]"
if(part.s_col && part.s_col.len >= 3) if(part.s_col && part.s_col.len >= 3)
icon_key += "[rgb(part.s_col[1],part.s_col[2],part.s_col[3])]" icon_key += "[rgb(part.s_col[1],part.s_col[2],part.s_col[3])]"

103
code/modules/organs/data.dm Normal file
View File

@@ -0,0 +1,103 @@
// Data written to each organ on creation for appearance and blood, this WAS originally done by sending the full dna datum.
// However sending the whole dna datum through Clone() is extremely expensive, and a memory leak if its a hardref instead.
/datum/organ_data
VAR_PRIVATE/datum/weakref/species
// Species currently uses a cache system, if the species datum deletes, these are used as fallbacks for the last obtained state from the species datum
// In the future, transforming species need to be refactored to not need this, as it's the only thing holding it back from proper isolation.
// Species
VAR_PRIVATE/cached_species_vars = list()
// Dna
var/unique_enzymes
var/b_type
var/body_gender
var/digitigrade
var/skin_tone
var/list/skin_color
var/list/hair_color
/datum/organ_data/proc/setup_from_dna(var/datum/dna/dna)
SHOULD_NOT_OVERRIDE(TRUE)
// Prosfab uses default dna to get vars, lets respect that still
var/self_clear = FALSE
if(!dna)
dna = new()
dna.ResetUI()
self_clear = TRUE
// Setup cached dna data, as storing the entire DNA cloned is horrifically laggy
unique_enzymes = dna.unique_enzymes
body_gender = dna.GetUIState(DNA_UI_GENDER)
if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)))
skin_tone = dna.GetUIValue(DNA_UI_SKIN_TONE)
skin_color = list(dna.GetUIValue(DNA_UI_SKIN_R), dna.GetUIValue(DNA_UI_SKIN_G), dna.GetUIValue(DNA_UI_SKIN_B))
hair_color = list(dna.GetUIValue(DNA_UI_HAIR_R), dna.GetUIValue(DNA_UI_HAIR_G), dna.GetUIValue(DNA_UI_HAIR_B))
digitigrade = dna.digitigrade
// Cleanup for synthfab default dna
if(self_clear)
qdel(dna)
/datum/organ_data/proc/setup_from_species(var/datum/species/S) // This needs a full rework, but can't be done unless all of transformating species code is refactored
SHOULD_NOT_OVERRIDE(TRUE)
species = WEAKREF(S)
// All accessed vars need to be cached during read.
// Get data from species, if this fails use cached data
#define SETUP_SPECIES_CHECK(p,x)\
var/datum/species/SP = species?.resolve();\
if(SP)\
cached_species_vars[p] = x;\
return cached_species_vars[p];
/datum/organ_data/proc/get_species_name()
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("name",SP.name)
/datum/organ_data/proc/get_species_race_key(var/owner)
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("race_key",SP.get_race_key(owner))
/datum/organ_data/proc/get_species_bodytype(var/mob/living/carbon/human/H)
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("bodytype",SP.get_bodytype(H))
/datum/organ_data/proc/get_species_icobase(var/mob/living/carbon/human/H, var/get_deform)
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("icobase",SP.get_icobase(H,get_deform))
/datum/organ_data/proc/get_species_flags()
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("flags",SP.flags)
/datum/organ_data/proc/get_species_appearance_flags()
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("appearance_flags",SP.appearance_flags)
/datum/organ_data/proc/get_species_health_hud_intensity()
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("health_hud_intensity",SP.health_hud_intensity)
/datum/organ_data/proc/get_species_color_mult()
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("color_mult",SP.color_mult)
/datum/organ_data/proc/get_species_mob_size()
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("mob_size",SP.mob_size)
/datum/organ_data/proc/get_species_flesh_colour(var/owner)
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("flesh_colour",SP.get_flesh_colour(owner) || "#C80000")
/datum/organ_data/proc/get_species_blood_colour(var/owner)
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("blood_colour",SP.get_blood_colour(owner) || "#C80000")
/datum/organ_data/proc/get_species_icodigi()
SHOULD_NOT_OVERRIDE(TRUE)
SETUP_SPECIES_CHECK("icodigi",SP.icodigi)
#undef SETUP_SPECIES_CHECK

View File

@@ -23,8 +23,7 @@ var/list/organ_cache = list()
var/list/transplant_data // Transplant match data. var/list/transplant_data // Transplant match data.
var/list/autopsy_data = list() // Trauma data for forensics. var/list/autopsy_data = list() // Trauma data for forensics.
var/list/trace_chemicals = list() // Traces of chemicals in the organ. var/list/trace_chemicals = list() // Traces of chemicals in the organ.
var/datum/dna/dna // Original DNA. var/datum/organ_data/data = new() // Stores data for appearance and investigation
var/datum/species/species // Original species.
// Damage vars. // Damage vars.
var/min_bruised_damage = 10 // Damage before considered bruised var/min_bruised_damage = 10 // Damage before considered bruised
@@ -54,8 +53,7 @@ var/list/organ_cache = list()
if(transplant_data) transplant_data.Cut() if(transplant_data) transplant_data.Cut()
if(autopsy_data) autopsy_data.Cut() if(autopsy_data) autopsy_data.Cut()
if(trace_chemicals) trace_chemicals.Cut() if(trace_chemicals) trace_chemicals.Cut()
QDEL_NULL(dna) QDEL_NULL(data)
species = null
return ..() return ..()
@@ -91,10 +89,11 @@ var/list/organ_cache = list()
max_damage = min_broken_damage * 2 max_damage = min_broken_damage * 2
if(iscarbon(owner)) if(iscarbon(owner))
var/mob/living/carbon/C = owner var/mob/living/carbon/C = owner
species = GLOB.all_species[SPECIES_HUMAN] if(!C.species)
data.setup_from_species(GLOB.all_species[SPECIES_HUMAN])
if(owner.dna) if(owner.dna)
qdel_swap(dna, C.dna.Clone()) data.setup_from_dna(C.dna)
species = C.species data.setup_from_species(C.species)
else else
log_debug("[src] at [loc] spawned without a proper DNA.") log_debug("[src] at [loc] spawned without a proper DNA.")
var/mob/living/carbon/human/H = C var/mob/living/carbon/human/H = C
@@ -105,12 +104,12 @@ var/list/organ_cache = list()
if(E.internal_organs == null) if(E.internal_organs == null)
E.internal_organs = list() E.internal_organs = list()
E.internal_organs |= src E.internal_organs |= src
if(dna) if(data)
if(!blood_DNA) if(!blood_DNA)
blood_DNA = list() blood_DNA = list()
blood_DNA[dna.unique_enzymes] = dna.b_type blood_DNA[data.unique_enzymes] = data.b_type
else else
species = GLOB.all_species["Human"] data.setup_from_species(GLOB.all_species["Human"])
handle_organ_mod_special() handle_organ_mod_special()
@@ -131,10 +130,10 @@ var/list/organ_cache = list()
/obj/item/organ/proc/set_dna(var/datum/dna/new_dna) /obj/item/organ/proc/set_dna(var/datum/dna/new_dna)
if(new_dna) if(new_dna)
qdel_swap(dna, new_dna.Clone()) data.setup_from_dna(new_dna)
if(blood_DNA) if(blood_DNA)
blood_DNA.Cut() blood_DNA.Cut()
blood_DNA[dna.unique_enzymes] = dna.b_type blood_DNA[data.unique_enzymes] = data.b_type
/obj/item/organ/proc/die() /obj/item/organ/proc/die()
if(robotic < ORGAN_ROBOT) if(robotic < ORGAN_ROBOT)
@@ -259,9 +258,9 @@ var/list/organ_cache = list()
/obj/item/organ/proc/handle_rejection() /obj/item/organ/proc/handle_rejection()
// Process unsuitable transplants. TODO: consider some kind of // Process unsuitable transplants. TODO: consider some kind of
// immunosuppressant that changes transplant data to make it match. // immunosuppressant that changes transplant data to make it match.
if(dna && can_reject) if(data && can_reject)
if(!rejecting) if(!rejecting)
if(blood_incompatible(dna.b_type, owner.dna.b_type, species.name, owner.species.name)) //VOREStation Edit - Process species by name. if(blood_incompatible(data.b_type, owner.dna.b_type, data.get_species_name(), owner.species.name)) //VOREStation Edit - Process species by name.
rejecting = 1 rejecting = 1
else else
rejecting++ //Rejection severity increases over time. rejecting++ //Rejection severity increases over time.
@@ -519,7 +518,7 @@ var/list/organ_cache = list()
qdel(src) qdel(src)
/obj/item/organ/proc/organ_can_feel_pain() /obj/item/organ/proc/organ_can_feel_pain()
if(species.flags & NO_PAIN) if(data.get_species_flags() & NO_PAIN)
return 0 return 0
if(status & ORGAN_DESTROYED) if(status & ORGAN_DESTROYED)
return 0 return 0

View File

@@ -31,8 +31,6 @@
var/burn_dam = 0 // Actual current burn damage. var/burn_dam = 0 // Actual current burn damage.
var/last_dam = -1 // used in healing/processing calculations. var/last_dam = -1 // used in healing/processing calculations.
var/spread_dam = 0 var/spread_dam = 0
var/thick_skin = 0 // If a needle has a chance to fail to penetrate.
// Appearance vars. // Appearance vars.
var/nonsolid // Snowflake warning, reee. Used for slime limbs. var/nonsolid // Snowflake warning, reee. Used for slime limbs.
var/transparent // As above, so below. Used for transparent limbs. var/transparent // As above, so below. Used for transparent limbs.
@@ -41,7 +39,6 @@
var/icon_position = 0 // Used in mob overlay layering calculations. var/icon_position = 0 // Used in mob overlay layering calculations.
var/model // Used when caching robolimb icons. var/model // Used when caching robolimb icons.
var/force_icon // Used to force override of species-specific limb icons (for prosthetics). Also used for any limbs chopped from a simple mob, and then attached to humans. var/force_icon // Used to force override of species-specific limb icons (for prosthetics). Also used for any limbs chopped from a simple mob, and then attached to humans.
var/force_icon_key // Used to force the override of the icon-key generated using the species. Must be used in tandem with the above.
var/icon/mob_icon // Cached icon for use in mob overlays. var/icon/mob_icon // Cached icon for use in mob overlays.
var/gendered_icon = 0 // Whether or not the icon state appends a gender. var/gendered_icon = 0 // Whether or not the icon state appends a gender.
var/s_tone // Skin tone. var/s_tone // Skin tone.
@@ -257,7 +254,8 @@
/obj/item/organ/external/LateInitialize() /obj/item/organ/external/LateInitialize()
. = ..() . = ..()
get_icon() if(!QDELETED(src))
get_icon()
/obj/item/organ/external/replaced(var/mob/living/carbon/human/target) /obj/item/organ/external/replaced(var/mob/living/carbon/human/target)
owner = target owner = target
@@ -595,13 +593,15 @@ This function completely restores a damaged organ to perfect condition.
//moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage (because of the return) //moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage (because of the return)
//Possibly trigger an internal wound, too. //Possibly trigger an internal wound, too.
var/local_damage = brute_dam + burn_dam + damage var/local_damage = brute_dam + burn_dam + damage
if((damage > 15) && (type != BURN) && (local_damage > 30) && prob(damage) && (robotic < ORGAN_ROBOT) && !(species.flags & NO_BLOOD)) if((damage > 15) && (type != BURN) && (local_damage > 30) && prob(damage) && (robotic < ORGAN_ROBOT) && !(data.get_species_flags() & NO_BLOOD))
var/datum/wound/internal_bleeding/I = new (min(damage - 15, 15)) var/datum/wound/internal_bleeding/I = new (min(damage - 15, 15))
wounds += I wounds += I
owner.custom_pain("Something ruptures inside of your [name]. You get the feeling you'll need more than just a bandage to fix it.", 15, TRUE) owner.custom_pain("Something ruptures inside of your [name]. You get the feeling you'll need more than just a bandage to fix it.", 15, TRUE)
to_chat(owner, span_bolddanger(span_massive("OH GOD! Something just tore in your [name]!"))) //Let's make this CLEAR that an artery was severed. This was vague enough that most players didn't realize they had IB. to_chat(owner, span_bolddanger(span_massive("OH GOD! Something just tore in your [name]!"))) //Let's make this CLEAR that an artery was severed. This was vague enough that most players didn't realize they had IB.
if((damage > 5 || damage + burn_dam >= 15) && type == BURN && (robotic < ORGAN_ROBOT) && !(species.flags & NO_BLOOD)) //Burn damage can cause fluid loss due to blistering and cook-off
if((damage > 5 || damage + burn_dam >= 15) && type == BURN && (robotic < ORGAN_ROBOT) && !(data.get_species_flags() & NO_BLOOD))
var/fluid_loss = 0.1 * (damage/(owner.getMaxHealth() - CONFIG_GET(number/health_threshold_dead))) * owner.species.blood_volume*(1 - owner.species.blood_level_fatal) //CHOMPedit reduce fluid loss 4-fold so lasers dont suck your blood var/fluid_loss = 0.1 * (damage/(owner.getMaxHealth() - CONFIG_GET(number/health_threshold_dead))) * owner.species.blood_volume*(1 - owner.species.blood_level_fatal) //CHOMPedit reduce fluid loss 4-fold so lasers dont suck your blood
owner.remove_blood(fluid_loss) owner.remove_blood(fluid_loss)
// first check whether we can widen an existing wound // first check whether we can widen an existing wound
@@ -787,8 +787,7 @@ Note that amputating the affected organ does in fact remove the infection from t
//Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections //Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections
/obj/item/organ/external/proc/update_wounds() /obj/item/organ/external/proc/update_wounds()
if((robotic >= ORGAN_ROBOT) || (data.get_species_flags() & UNDEAD)) //Robotic and dead limbs don't heal or get worse.
if((robotic >= ORGAN_ROBOT) || (species.flags & UNDEAD)) //Robotic and dead limbs don't heal or get worse.
for(var/datum/wound/W in wounds) //Repaired wounds disappear though for(var/datum/wound/W in wounds) //Repaired wounds disappear though
if(W.damage <= 0) //and they disappear right away if(W.damage <= 0) //and they disappear right away
wounds -= W //TODO: robot wounds for robot limbs wounds -= W //TODO: robot wounds for robot limbs
@@ -959,8 +958,8 @@ Note that amputating the affected organ does in fact remove the infection from t
var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed(). var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed().
var/obj/item/organ/external/parent_organ = parent var/obj/item/organ/external/parent_organ = parent
var/use_flesh_colour = species?.get_flesh_colour(owner) ? species.get_flesh_colour(owner) : "#C80000" var/use_flesh_colour = data.get_species_flesh_colour(owner)
var/use_blood_colour = species?.get_blood_colour(owner) ? species.get_blood_colour(owner) : "#C80000" var/use_blood_colour = data.get_species_blood_colour(owner)
removed(null, ignore_children) removed(null, ignore_children)
victim?.traumatic_shock += 60 victim?.traumatic_shock += 60
@@ -1013,10 +1012,9 @@ Note that amputating the affected organ does in fact remove the infection from t
gore = new /obj/effect/decal/cleanable/blood/gibs/robot(droploc) gore = new /obj/effect/decal/cleanable/blood/gibs/robot(droploc)
else else
gore = new /obj/effect/decal/cleanable/blood/gibs(droploc) gore = new /obj/effect/decal/cleanable/blood/gibs(droploc)
if(species) gore.fleshcolor = use_flesh_colour
gore.fleshcolor = use_flesh_colour gore.basecolor = use_blood_colour
gore.basecolor = use_blood_colour gore.update_icon()
gore.update_icon()
gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5) gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
@@ -1205,7 +1203,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(company) if(company)
model = company model = company
var/datum/robolimb/R = all_robolimbs[company] var/datum/robolimb/R = all_robolimbs[company]
if(!R || (species && (species.name in R.species_cannot_use))) if(!R || (data.get_species_name() in R.species_cannot_use))
R = basic_robolimb R = basic_robolimb
if(R) if(R)
force_icon = R.icon force_icon = R.icon

View File

@@ -22,7 +22,7 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
if(human.synth_color) if(human.synth_color)
s_col = list(human.r_synth, human.g_synth, human.b_synth) s_col = list(human.r_synth, human.g_synth, human.b_synth)
return return
if(species && human.species && species.name != human.species.name) if(human.species && data.get_species_name() != human.species.name)
return return
if(!isnull(human.s_tone) && (human.species.appearance_flags & HAS_SKIN_TONE)) if(!isnull(human.s_tone) && (human.species.appearance_flags & HAS_SKIN_TONE))
s_tone = human.s_tone s_tone = human.s_tone
@@ -38,11 +38,11 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
var/datum/robolimb/franchise = all_robolimbs[model] var/datum/robolimb/franchise = all_robolimbs[model]
if(!(franchise && franchise.skin_tone) && !(franchise && franchise.skin_color)) if(!(franchise && franchise.skin_tone) && !(franchise && franchise.skin_color))
return return
if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && (species.appearance_flags & HAS_SKIN_TONE)) if(!isnull(data.skin_tone) && (data.get_species_appearance_flags() & HAS_SKIN_TONE))
s_tone = dna.GetUIValue(DNA_UI_SKIN_TONE) s_tone = data.skin_tone
if(species.appearance_flags & HAS_SKIN_COLOR) if(data.get_species_appearance_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)) s_col = data.skin_color.Copy()
h_col = list(dna.GetUIValue(DNA_UI_HAIR_R),dna.GetUIValue(DNA_UI_HAIR_G),dna.GetUIValue(DNA_UI_HAIR_B)) h_col = data.hair_color.Copy()
/obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/human) /obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/human)
..() ..()
@@ -56,7 +56,7 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
//Facial hair //Facial hair
if(owner.f_style) if(owner.f_style)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[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 && (species.get_bodytype(owner) in facial_hair_style.species_allowed)) if(facial_hair_style && facial_hair_style.species_allowed && (data.get_species_bodytype(owner) 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") 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) if(facial_hair_style.do_colouration)
facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), facial_hair_style.color_blend_mode) facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), facial_hair_style.color_blend_mode)
@@ -69,7 +69,7 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
if(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR)) if(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR))
if(!(hair_style.flags & HAIR_VERY_SHORT)) if(!(hair_style.flags & HAIR_VERY_SHORT))
hair_style = hair_styles_list["Short Hair"] hair_style = hair_styles_list["Short Hair"]
if(hair_style && (species.get_bodytype(owner) in hair_style.species_allowed)) if(hair_style && (data.get_species_bodytype(owner) in hair_style.species_allowed))
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
var/icon/hair_s_add = new/icon("icon" = hair_style.icon_add, "icon_state" = "[hair_style.icon_state]_s") var/icon/hair_s_add = new/icon("icon" = hair_style.icon_add, "icon_state" = "[hair_style.icon_state]_s")
if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3) if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3)
@@ -89,8 +89,8 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
var/check_digi = istype(src,/obj/item/organ/external/leg) || istype(src,/obj/item/organ/external/foot) var/check_digi = istype(src,/obj/item/organ/external/leg) || istype(src,/obj/item/organ/external/foot)
if(owner) if(owner)
digitigrade = check_digi && owner.digitigrade digitigrade = check_digi && owner.digitigrade
else if(dna) else if(data)
digitigrade = check_digi && dna.digitigrade digitigrade = check_digi && data.digitigrade
for(var/M in markings) for(var/M in markings)
if (!markings[M]["on"]) if (!markings[M]["on"])
@@ -124,22 +124,19 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
var/should_apply_transparency = FALSE var/should_apply_transparency = FALSE
if(!force_icon_key) icon_cache_key = "[icon_name]_[data.get_species_bodytype(owner)]"
icon_cache_key = "[icon_name]_[species ? species.get_bodytype() : SPECIES_HUMAN]" //VOREStation Edit
else
icon_cache_key = "[icon_name]_[force_icon_key]"
if(force_icon) if(force_icon)
mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]") mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]")
else else
if(!dna) if(!data)
mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_[gender]" : ""]") mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_[gender]" : ""]")
else else
if(!gendered_icon) if(!gendered_icon)
gender = null gender = null
else else
if(dna.GetUIState(DNA_UI_GENDER)) if(data.body_gender)
gender = "f" gender = "f"
else else
gender = "m" gender = "m"
@@ -155,7 +152,7 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
should_apply_transparency = TRUE should_apply_transparency = TRUE
else else
//Use digi icon if digitigrade, otherwise use regular icon. Ternary operator is based. //Use digi icon if digitigrade, otherwise use regular icon. Ternary operator is based.
mob_icon = new /icon(digitigrade ? species.icodigi : species.get_icobase(owner, (status & ORGAN_MUTATED)), "[icon_name][gender ? "_[gender]" : ""]") mob_icon = new /icon(digitigrade ? data.get_species_icodigi() : data.get_species_icobase(owner, (status & ORGAN_MUTATED)), "[icon_name][gender ? "_[gender]" : ""]")
should_apply_transparency = TRUE should_apply_transparency = TRUE
apply_colouration(mob_icon) apply_colouration(mob_icon)
@@ -173,12 +170,11 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
if(body_hair && islist(h_col) && h_col.len >= 3) if(body_hair && islist(h_col) && h_col.len >= 3)
var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]" var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]"
//if(!GLOB.limb_icon_cache[cache_key]) //ChompEDIT START if(!GLOB.limb_icon_cache[cache_key])
var/icon/I = icon(species.get_icobase(owner), "[icon_name]_[body_hair]") var/icon/I = icon(data.get_species_icobase(owner), "[icon_name]_[body_hair]")
I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_MULTIPLY) //VOREStation edit I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_MULTIPLY) //VOREStation edit
mob_icon.Blend(I, ICON_OVERLAY) GLOB.limb_icon_cache[cache_key] = I
GLOB.limb_icon_cache[cache_key] = I mob_icon.Blend(GLOB.limb_icon_cache[cache_key], ICON_OVERLAY)
//ChompEDIT END
// VOREStation edit start // VOREStation edit start
if(nail_polish) if(nail_polish)
@@ -206,12 +202,11 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
if(body_hair && islist(h_col) && h_col.len >= 3) if(body_hair && islist(h_col) && h_col.len >= 3)
var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]" var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]"
//if(!GLOB.limb_icon_cache[cache_key]) //ChompEDIT START if(!GLOB.limb_icon_cache[cache_key])
var/icon/I = icon(species.get_icobase(owner), "[icon_name]_[body_hair]") var/icon/I = icon(data.get_species_icobase(owner), "[icon_name]_[body_hair]")
I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_MULTIPLY) //VOREStation edit I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_MULTIPLY) //VOREStation edit
mob_icon.Blend(I, ICON_OVERLAY) GLOB.limb_icon_cache[cache_key] = I
GLOB.limb_icon_cache[cache_key] = I mob_icon.Blend(GLOB.limb_icon_cache[cache_key], ICON_OVERLAY)
//ChompEDIT END
// VOREStation edit ends here // VOREStation edit ends here
if (transparent && !istype(src,/obj/item/organ/external/head) && can_apply_transparency && should_apply_transparency) //VORESTATION EDIT: transparent instead of nonsolid if (transparent && !istype(src,/obj/item/organ/external/head) && can_apply_transparency && should_apply_transparency) //VORESTATION EDIT: transparent instead of nonsolid
@@ -223,12 +218,9 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
/obj/item/organ/external/proc/apply_colouration(var/icon/applying) /obj/item/organ/external/proc/apply_colouration(var/icon/applying)
if(transparent) //VOREStation edit if(transparent)
applying.MapColors("#4D4D4D","#969696","#1C1C1C", "#000000") applying.MapColors("#4D4D4D","#969696","#1C1C1C", "#000000")
if(species && species.get_bodytype(owner) != SPECIES_HUMAN) applying.SetIntensity(1)
applying.SetIntensity(1) // Unathi, Taj and Skrell have -very- dark base icons. VOREStation edit fixes this and brings the number back to 1
else
applying.SetIntensity(1) //VOREStation edit to make Prometheans not look like shit with mob coloring.
else if(status & ORGAN_DEAD) else if(status & ORGAN_DEAD)
icon_cache_key += "_dead" icon_cache_key += "_dead"
@@ -242,14 +234,12 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
applying.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) applying.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
icon_cache_key += "_tone_[s_tone]" icon_cache_key += "_tone_[s_tone]"
else if(s_col && s_col.len >= 3) else if(s_col && s_col.len >= 3)
//VOREStation Edit - Support for species.color_mult if(data.get_species_color_mult())
if(species && species.color_mult)
applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_MULTIPLY) applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_MULTIPLY)
icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]_[ICON_MULTIPLY]" icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]_[ICON_MULTIPLY]"
else else
applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD) applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]_[ICON_ADD]" icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]_[ICON_ADD]"
//VOREStation Edit End
return applying return applying
@@ -280,14 +270,15 @@ var/list/robot_hud_colours = list("#CFCFCF","#AFAFAF","#8F8F8F","#6F6F6F","#4F4F
// This looks convoluted, but it's this way to avoid icon proc calls. // This looks convoluted, but it's this way to avoid icon proc calls.
if(!hud_damage_image) if(!hud_damage_image)
var/cache_key = "dambase-[icon_cache_key]" var/cache_key = "dambase-[icon_cache_key]"
if(!icon_cache_key || !GLOB.limb_icon_cache[cache_key]) //CHOMPNote - this isn't manipulated after the fact, so we leave it. if(!icon_cache_key || !GLOB.limb_icon_cache[cache_key])
GLOB.limb_icon_cache[cache_key] = icon(get_icon(), null, SOUTH) //ChompEDIT GLOB.limb_icon_cache[cache_key] = icon(get_icon(), null, SOUTH)
var/image/temp = image(GLOB.limb_icon_cache[cache_key]) //ChompEDIT var/image/temp = image(GLOB.limb_icon_cache[cache_key])
if((robotic < ORGAN_ROBOT) && species) if((robotic < ORGAN_ROBOT))
// Calculate the required colour matrix. // Calculate the required colour matrix.
var/r = 0.30 * species.health_hud_intensity var/int = data.get_species_health_hud_intensity()
var/g = 0.59 * species.health_hud_intensity var/r = 0.30 * int
var/b = 0.11 * species.health_hud_intensity var/g = 0.59 * int
var/b = 0.11 * int
temp.color = list(r, r, r, g, g, g, b, b, b) temp.color = list(r, r, r, g, g, g, b, b, b)
else if(model) else if(model)
var/datum/robolimb/R = all_robolimbs[model] var/datum/robolimb/R = all_robolimbs[model]

View File

@@ -1,8 +0,0 @@
/obj/item/organ/external/foot/seromi
//body_hair = "feathers" //TESHARI TEMPORARY REMOVAL
/obj/item/organ/external/foot/right/seromi
//body_hair = "feathers" //TESHARI TEMPORARY REMOVAL
/obj/item/organ/external/hand/seromi
//body_hair = "feathers" //TESHARI TEMPORARY REMOVAL
/obj/item/organ/external/hand/right/seromi
//body_hair = "feathers" //TESHARI TEMPORARY REMOVAL

View File

@@ -389,7 +389,7 @@
icon_cache_key += "[eye_icon]" icon_cache_key += "[eye_icon]"
//Lip color/icon //Lip color/icon
if(owner.lip_style && (species && (species.appearance_flags & HAS_LIPS))) if(owner.lip_style && (data.get_species_appearance_flags() & HAS_LIPS))
var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s")
add_overlay(lip_icon) add_overlay(lip_icon)
mob_icon.Blend(lip_icon, ICON_OVERLAY) mob_icon.Blend(lip_icon, ICON_OVERLAY)

View File

@@ -155,72 +155,61 @@
/obj/item/organ/external/chest/unseverable/xeno /obj/item/organ/external/chest/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
thick_skin = TRUE
/obj/item/organ/external/groin/unseverable/xeno /obj/item/organ/external/groin/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
encased = TRUE encased = TRUE
thick_skin = TRUE
/obj/item/organ/external/arm/unseverable/xeno /obj/item/organ/external/arm/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
stapled_nerves = TRUE stapled_nerves = TRUE
encased = TRUE encased = TRUE
thick_skin = TRUE
/obj/item/organ/external/arm/right/unseverable/xeno /obj/item/organ/external/arm/right/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
stapled_nerves = TRUE stapled_nerves = TRUE
encased = TRUE encased = TRUE
thick_skin = TRUE
/obj/item/organ/external/leg/unseverable/xeno /obj/item/organ/external/leg/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
stapled_nerves = TRUE stapled_nerves = TRUE
encased = TRUE encased = TRUE
thick_skin = TRUE
/obj/item/organ/external/leg/right/unseverable/xeno /obj/item/organ/external/leg/right/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
stapled_nerves = TRUE stapled_nerves = TRUE
encased = TRUE encased = TRUE
thick_skin = TRUE
/obj/item/organ/external/foot/unseverable/xeno /obj/item/organ/external/foot/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
stapled_nerves = TRUE stapled_nerves = TRUE
encased = TRUE encased = TRUE
thick_skin = TRUE
/obj/item/organ/external/foot/right/unseverable/xeno /obj/item/organ/external/foot/right/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
stapled_nerves = TRUE stapled_nerves = TRUE
encased = TRUE encased = TRUE
thick_skin = TRUE
/obj/item/organ/external/hand/unseverable/xeno /obj/item/organ/external/hand/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
stapled_nerves = TRUE stapled_nerves = TRUE
encased = TRUE encased = TRUE
thick_skin = TRUE
/obj/item/organ/external/hand/right/unseverable/xeno /obj/item/organ/external/hand/right/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
stapled_nerves = TRUE stapled_nerves = TRUE
encased = TRUE encased = TRUE
thick_skin = TRUE
/obj/item/organ/external/head/unseverable/xeno /obj/item/organ/external/head/unseverable/xeno
cannot_gib = 1 cannot_gib = 1
cannot_amputate = 1 cannot_amputate = 1
thick_skin = TRUE
eye_icon = "blank_eyes" eye_icon = "blank_eyes"

View File

@@ -21,15 +21,12 @@
manf = manf.species_alternates[prosfab.species] manf = manf.species_alternates[prosfab.species]
if(!prosfab.species || (prosfab.species in manf.species_cannot_use)) // Fabricator ensures the manufacturer can make parts for the species we're set to. if(!prosfab.species || (prosfab.species in manf.species_cannot_use)) // Fabricator ensures the manufacturer can make parts for the species we're set to.
O.species = GLOB.all_species["[manf.suggested_species]"] O.data.setup_from_species(GLOB.all_species["[manf.suggested_species]"])
else else
O.species = GLOB.all_species[prosfab.species] O.data.setup_from_species(GLOB.all_species[prosfab.species])
else else
O.species = GLOB.all_species["Human"] O.data.setup_from_species(GLOB.all_species["Human"])
O.robotize(prosfab.manufacturer) O.robotize(prosfab.manufacturer)
qdel_swap(O.dna, new/datum/dna()) //Uuughhhh... why do I have to do this?
O.dna.ResetUI()
O.dna.ResetSE()
return O return O
return ..() return ..()
@@ -60,15 +57,13 @@
EO.remove_rejuv() EO.remove_rejuv()
for(var/obj/item/organ/external/O in H.organs) for(var/obj/item/organ/external/O in H.organs)
O.species = GLOB.all_species[newspecies] O.data.setup_from_species(GLOB.all_species[newspecies])
if(!(O.organ_tag in manf.parts)) // Make sure we're using an actually present icon. if(!(O.organ_tag in manf.parts)) // Make sure we're using an actually present icon.
manf = all_robolimbs["Unbranded"] manf = all_robolimbs["Unbranded"]
O.robotize(manf.company) O.robotize(manf.company)
qdel_swap(O.dna, new/datum/dna()) O.data.setup_from_dna()
O.dna.ResetUI()
O.dna.ResetSE()
// Skincolor weirdness. // Skincolor weirdness.
O.s_col[1] = 255 // CHOMP Edit O.s_col[1] = 255 // CHOMP Edit

View File

@@ -8,8 +8,8 @@
var/check_digi = istype(src,/obj/item/organ/external/leg) || istype(src,/obj/item/organ/external/foot) var/check_digi = istype(src,/obj/item/organ/external/leg) || istype(src,/obj/item/organ/external/foot)
if(owner) if(owner)
digitigrade = check_digi && owner.digitigrade digitigrade = check_digi && owner.digitigrade
else if(dna) else if(data)
digitigrade = check_digi && dna.digitigrade digitigrade = check_digi && data.digitigrade
var/should_apply_transparency = FALSE var/should_apply_transparency = FALSE
@@ -18,22 +18,19 @@
if(owner && owner.gender == FEMALE) if(owner && owner.gender == FEMALE)
gender = "f" gender = "f"
if(!force_icon_key) icon_cache_key = "[icon_name]_[data.get_species_bodytype(owner)]"
icon_cache_key = "[icon_name]_[species ? species.get_bodytype() : SPECIES_HUMAN]" //VOREStation Edit
else
icon_cache_key = "[icon_name]_[force_icon_key]"
if(force_icon && !skip_forced_icon) if(force_icon && !skip_forced_icon)
mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]") mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]")
else else
if(!dna) if(!data)
mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_[gender]" : ""]") mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_[gender]" : ""]")
else else
if(!gendered_icon) if(!gendered_icon)
gender = null gender = null
else else
if(dna.GetUIState(DNA_UI_GENDER)) if(data.body_gender)
gender = "f" gender = "f"
else else
gender = "m" gender = "m"
@@ -50,7 +47,7 @@
should_apply_transparency = TRUE should_apply_transparency = TRUE
else else
//Use digi icon if digitigrade, otherwise use regular icon. Ternary operator is based. //Use digi icon if digitigrade, otherwise use regular icon. Ternary operator is based.
mob_icon = new /icon(digitigrade ? species.icodigi : species.get_icobase(owner, (status & ORGAN_MUTATED)), "[icon_name][gender ? "_[gender]" : ""]") mob_icon = new /icon(digitigrade ? data.get_species_icodigi() : data.get_species_icobase(owner, (status & ORGAN_MUTATED)), "[icon_name][gender ? "_[gender]" : ""]")
should_apply_transparency = TRUE should_apply_transparency = TRUE
apply_colouration(mob_icon) apply_colouration(mob_icon)
@@ -77,12 +74,11 @@
icon_cache_key += "[M][markings[M]["color"]]" icon_cache_key += "[M][markings[M]["color"]]"
if(body_hair && islist(h_col) && h_col.len >= 3) if(body_hair && islist(h_col) && h_col.len >= 3)
var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]" var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]"
//if(!GLOB.limb_icon_cache[cache_key]) //icon cache tweak start if(!GLOB.limb_icon_cache[cache_key])
var/icon/I = icon(species.get_icobase(owner), "[icon_name]_[body_hair]") var/icon/I = icon(data.get_species_icobase(owner), "[icon_name]_[body_hair]")
I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_MULTIPLY) //VOREStation edit I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_MULTIPLY) //VOREStation edit
mob_icon.Blend(I, ICON_OVERLAY) GLOB.limb_icon_cache[cache_key] = I
GLOB.limb_icon_cache[cache_key] = I mob_icon.Blend(GLOB.limb_icon_cache[cache_key], ICON_OVERLAY)
//icon cache tweak end
// VOREStation edit start // VOREStation edit start
if(nail_polish && !(force_icon && !skip_forced_icon)) if(nail_polish && !(force_icon && !skip_forced_icon))

View File

@@ -3869,6 +3869,7 @@
#include "code\modules\nifsoft\software\14_commlink.dm" #include "code\modules\nifsoft\software\14_commlink.dm"
#include "code\modules\nifsoft\software\15_misc.dm" #include "code\modules\nifsoft\software\15_misc.dm"
#include "code\modules\organs\blood.dm" #include "code\modules\organs\blood.dm"
#include "code\modules\organs\data.dm"
#include "code\modules\organs\misc.dm" #include "code\modules\organs\misc.dm"
#include "code\modules\organs\organ.dm" #include "code\modules\organs\organ.dm"
#include "code\modules\organs\organ_external.dm" #include "code\modules\organs\organ_external.dm"