mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
[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:
committed by
GitHub
parent
036ed10454
commit
e902125c5e
1
.github/workflows/render_nanomaps.yml
vendored
1
.github/workflows/render_nanomaps.yml
vendored
@@ -40,6 +40,7 @@ jobs:
|
||||
${{ runner.os }}-spacemandmm-
|
||||
- name: Install Tools
|
||||
run: |
|
||||
sudo apt update
|
||||
bash tools/ci/install_spaceman_dmm.sh dmm-tools
|
||||
sudo apt install -y imagemagick
|
||||
- name: Ensure +x on github-actions directory
|
||||
|
||||
@@ -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_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 THICK_SKIN 0x2000 // Needles have a chain to fail when attempted to be used on them.
|
||||
// unused: 0x8000 - higher than this will overflow
|
||||
|
||||
// Species EMP vuln for carbons
|
||||
|
||||
@@ -302,12 +302,10 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
//VOREStation Add
|
||||
/mob/living/carbon/human/proc/force_update_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)
|
||||
//VOREStation Add End
|
||||
|
||||
// Used below, simple injection modifier.
|
||||
/proc/probinj(var/pr, var/inj)
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
O.status |= ORGAN_CUT_AWAY
|
||||
var/mob/living/carbon/human/C = loaded_dna["donor"]
|
||||
O.set_dna(C.dna)
|
||||
O.species = C.species
|
||||
O.data.setup_from_species(C.species)
|
||||
|
||||
var/malfunctioned = FALSE
|
||||
|
||||
@@ -264,7 +264,7 @@
|
||||
var/new_species = pick(possible_species)
|
||||
if(!GLOB.all_species[new_species])
|
||||
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)
|
||||
var/obj/item/organ/external/E = O
|
||||
@@ -273,9 +273,9 @@
|
||||
O.pixel_x = 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
|
||||
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
|
||||
// END GENERIC PRINTER
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
if(ishuman(victim) && user.zone_sel.selecting != BP_GROIN && user.zone_sel.selecting != BP_TORSO)
|
||||
var/mob/living/carbon/human/H = victim
|
||||
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
|
||||
else if(E.robotic >= ORGAN_ROBOT)
|
||||
nopain = 1
|
||||
|
||||
@@ -62,8 +62,6 @@
|
||||
var/mob/living/simple_mob/SM = src
|
||||
if(SM.limb_icon)
|
||||
neworg.force_icon = SM.limb_icon
|
||||
neworg.force_icon_key = SM.limb_icon_key
|
||||
|
||||
organs |= neworg
|
||||
organs -= path
|
||||
|
||||
|
||||
@@ -172,8 +172,7 @@
|
||||
/mob/living/carbon/human/proc/update_dna()
|
||||
check_dna()
|
||||
dna.ready_dna(src)
|
||||
for(var/obj/item/organ/O in organs)
|
||||
qdel_swap(O.dna, dna.Clone()) // Update all of those because apparently they're separate, and icons won't update properly
|
||||
sync_organ_dna(dna)
|
||||
|
||||
/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()
|
||||
@@ -198,7 +197,7 @@
|
||||
|
||||
var/use_species = species.get_bodytype(src)
|
||||
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()
|
||||
for(var/hairstyle in hair_styles_list)
|
||||
@@ -224,7 +223,7 @@
|
||||
|
||||
var/use_species = species.get_bodytype(src)
|
||||
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()
|
||||
for(var/facialhairstyle in facial_hair_styles_list)
|
||||
|
||||
@@ -1432,7 +1432,7 @@
|
||||
else if (affecting.robotic >= ORGAN_LIFELIKE)
|
||||
. = 0
|
||||
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
|
||||
fail_msg = "Your needle fails to penetrate \the [affecting]'s thick hide..."
|
||||
else
|
||||
|
||||
@@ -276,7 +276,7 @@ var/list/wrapped_species_by_ref = list()
|
||||
for(var/limb in organs_by_name)
|
||||
var/obj/item/organ/external/O = organs_by_name[limb]
|
||||
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]
|
||||
// sync the organ's damage with its wounds
|
||||
O.update_damages()
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
cold_level_2 = -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
|
||||
|
||||
reagent_tag = IS_XENOS
|
||||
|
||||
@@ -226,8 +226,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //see UpdateDamageIcon()
|
||||
continue
|
||||
if(part)
|
||||
wholeicontransparent &&= part.transparent //VORESTATION EDIT: transparent instead of nonsolid
|
||||
icon_key += "[part.species.get_race_key(part.owner)]"
|
||||
icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]"
|
||||
icon_key += "[part.data.get_species_race_key(part.owner)]"
|
||||
icon_key += "[part.data.body_gender]"
|
||||
icon_key += "[part.s_tone]"
|
||||
if(part.s_col && part.s_col.len >= 3)
|
||||
icon_key += "[rgb(part.s_col[1],part.s_col[2],part.s_col[3])]"
|
||||
|
||||
103
code/modules/organs/data.dm
Normal file
103
code/modules/organs/data.dm
Normal 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
|
||||
@@ -23,8 +23,7 @@ var/list/organ_cache = list()
|
||||
var/list/transplant_data // Transplant match data.
|
||||
var/list/autopsy_data = list() // Trauma data for forensics.
|
||||
var/list/trace_chemicals = list() // Traces of chemicals in the organ.
|
||||
var/datum/dna/dna // Original DNA.
|
||||
var/datum/species/species // Original species.
|
||||
var/datum/organ_data/data = new() // Stores data for appearance and investigation
|
||||
|
||||
// Damage vars.
|
||||
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(autopsy_data) autopsy_data.Cut()
|
||||
if(trace_chemicals) trace_chemicals.Cut()
|
||||
QDEL_NULL(dna)
|
||||
species = null
|
||||
QDEL_NULL(data)
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -91,10 +89,11 @@ var/list/organ_cache = list()
|
||||
max_damage = min_broken_damage * 2
|
||||
if(iscarbon(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)
|
||||
qdel_swap(dna, C.dna.Clone())
|
||||
species = C.species
|
||||
data.setup_from_dna(C.dna)
|
||||
data.setup_from_species(C.species)
|
||||
else
|
||||
log_debug("[src] at [loc] spawned without a proper DNA.")
|
||||
var/mob/living/carbon/human/H = C
|
||||
@@ -105,12 +104,12 @@ var/list/organ_cache = list()
|
||||
if(E.internal_organs == null)
|
||||
E.internal_organs = list()
|
||||
E.internal_organs |= src
|
||||
if(dna)
|
||||
if(data)
|
||||
if(!blood_DNA)
|
||||
blood_DNA = list()
|
||||
blood_DNA[dna.unique_enzymes] = dna.b_type
|
||||
blood_DNA[data.unique_enzymes] = data.b_type
|
||||
else
|
||||
species = GLOB.all_species["Human"]
|
||||
data.setup_from_species(GLOB.all_species["Human"])
|
||||
|
||||
handle_organ_mod_special()
|
||||
|
||||
@@ -131,10 +130,10 @@ var/list/organ_cache = list()
|
||||
|
||||
/obj/item/organ/proc/set_dna(var/datum/dna/new_dna)
|
||||
if(new_dna)
|
||||
qdel_swap(dna, new_dna.Clone())
|
||||
data.setup_from_dna(new_dna)
|
||||
if(blood_DNA)
|
||||
blood_DNA.Cut()
|
||||
blood_DNA[dna.unique_enzymes] = dna.b_type
|
||||
blood_DNA[data.unique_enzymes] = data.b_type
|
||||
|
||||
/obj/item/organ/proc/die()
|
||||
if(robotic < ORGAN_ROBOT)
|
||||
@@ -259,9 +258,9 @@ 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(dna && can_reject)
|
||||
if(data && can_reject)
|
||||
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
|
||||
else
|
||||
rejecting++ //Rejection severity increases over time.
|
||||
@@ -519,7 +518,7 @@ var/list/organ_cache = list()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/organ/proc/organ_can_feel_pain()
|
||||
if(species.flags & NO_PAIN)
|
||||
if(data.get_species_flags() & NO_PAIN)
|
||||
return 0
|
||||
if(status & ORGAN_DESTROYED)
|
||||
return 0
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
var/burn_dam = 0 // Actual current burn damage.
|
||||
var/last_dam = -1 // used in healing/processing calculations.
|
||||
var/spread_dam = 0
|
||||
var/thick_skin = 0 // If a needle has a chance to fail to penetrate.
|
||||
|
||||
// Appearance vars.
|
||||
var/nonsolid // Snowflake warning, reee. Used for slime 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/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_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/gendered_icon = 0 // Whether or not the icon state appends a gender.
|
||||
var/s_tone // Skin tone.
|
||||
@@ -257,6 +254,7 @@
|
||||
|
||||
/obj/item/organ/external/LateInitialize()
|
||||
. = ..()
|
||||
if(!QDELETED(src))
|
||||
get_icon()
|
||||
|
||||
/obj/item/organ/external/replaced(var/mob/living/carbon/human/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)
|
||||
//Possibly trigger an internal wound, too.
|
||||
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))
|
||||
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)
|
||||
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
|
||||
owner.remove_blood(fluid_loss)
|
||||
// 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
|
||||
/obj/item/organ/external/proc/update_wounds()
|
||||
|
||||
if((robotic >= ORGAN_ROBOT) || (species.flags & UNDEAD)) //Robotic and dead limbs don't heal or get worse.
|
||||
if((robotic >= ORGAN_ROBOT) || (data.get_species_flags() & UNDEAD)) //Robotic and dead limbs don't heal or get worse.
|
||||
for(var/datum/wound/W in wounds) //Repaired wounds disappear though
|
||||
if(W.damage <= 0) //and they disappear right away
|
||||
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/obj/item/organ/external/parent_organ = parent
|
||||
|
||||
var/use_flesh_colour = species?.get_flesh_colour(owner) ? species.get_flesh_colour(owner) : "#C80000"
|
||||
var/use_blood_colour = species?.get_blood_colour(owner) ? species.get_blood_colour(owner) : "#C80000"
|
||||
var/use_flesh_colour = data.get_species_flesh_colour(owner)
|
||||
var/use_blood_colour = data.get_species_blood_colour(owner)
|
||||
|
||||
removed(null, ignore_children)
|
||||
victim?.traumatic_shock += 60
|
||||
@@ -1013,7 +1012,6 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
gore = new /obj/effect/decal/cleanable/blood/gibs/robot(droploc)
|
||||
else
|
||||
gore = new /obj/effect/decal/cleanable/blood/gibs(droploc)
|
||||
if(species)
|
||||
gore.fleshcolor = use_flesh_colour
|
||||
gore.basecolor = use_blood_colour
|
||||
gore.update_icon()
|
||||
@@ -1205,7 +1203,7 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
if(company)
|
||||
model = 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
|
||||
if(R)
|
||||
force_icon = R.icon
|
||||
|
||||
@@ -22,7 +22,7 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
|
||||
if(human.synth_color)
|
||||
s_col = list(human.r_synth, human.g_synth, human.b_synth)
|
||||
return
|
||||
if(species && human.species && species.name != human.species.name)
|
||||
if(human.species && data.get_species_name() != human.species.name)
|
||||
return
|
||||
if(!isnull(human.s_tone) && (human.species.appearance_flags & HAS_SKIN_TONE))
|
||||
s_tone = human.s_tone
|
||||
@@ -38,11 +38,11 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
|
||||
var/datum/robolimb/franchise = all_robolimbs[model]
|
||||
if(!(franchise && franchise.skin_tone) && !(franchise && franchise.skin_color))
|
||||
return
|
||||
if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && (species.appearance_flags & HAS_SKIN_TONE))
|
||||
s_tone = dna.GetUIValue(DNA_UI_SKIN_TONE)
|
||||
if(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))
|
||||
h_col = list(dna.GetUIValue(DNA_UI_HAIR_R),dna.GetUIValue(DNA_UI_HAIR_G),dna.GetUIValue(DNA_UI_HAIR_B))
|
||||
if(!isnull(data.skin_tone) && (data.get_species_appearance_flags() & HAS_SKIN_TONE))
|
||||
s_tone = data.skin_tone
|
||||
if(data.get_species_appearance_flags() & HAS_SKIN_COLOR)
|
||||
s_col = data.skin_color.Copy()
|
||||
h_col = data.hair_color.Copy()
|
||||
|
||||
/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
|
||||
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 && (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")
|
||||
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)
|
||||
@@ -69,7 +69,7 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
|
||||
if(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR))
|
||||
if(!(hair_style.flags & HAIR_VERY_SHORT))
|
||||
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_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)
|
||||
@@ -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)
|
||||
if(owner)
|
||||
digitigrade = check_digi && owner.digitigrade
|
||||
else if(dna)
|
||||
digitigrade = check_digi && dna.digitigrade
|
||||
else if(data)
|
||||
digitigrade = check_digi && data.digitigrade
|
||||
|
||||
for(var/M in markings)
|
||||
if (!markings[M]["on"])
|
||||
@@ -124,22 +124,19 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
|
||||
|
||||
var/should_apply_transparency = FALSE
|
||||
|
||||
if(!force_icon_key)
|
||||
icon_cache_key = "[icon_name]_[species ? species.get_bodytype() : SPECIES_HUMAN]" //VOREStation Edit
|
||||
else
|
||||
icon_cache_key = "[icon_name]_[force_icon_key]"
|
||||
icon_cache_key = "[icon_name]_[data.get_species_bodytype(owner)]"
|
||||
|
||||
if(force_icon)
|
||||
mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]")
|
||||
else
|
||||
if(!dna)
|
||||
if(!data)
|
||||
mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_[gender]" : ""]")
|
||||
else
|
||||
|
||||
if(!gendered_icon)
|
||||
gender = null
|
||||
else
|
||||
if(dna.GetUIState(DNA_UI_GENDER))
|
||||
if(data.body_gender)
|
||||
gender = "f"
|
||||
else
|
||||
gender = "m"
|
||||
@@ -155,7 +152,7 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
|
||||
should_apply_transparency = TRUE
|
||||
else
|
||||
//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
|
||||
apply_colouration(mob_icon)
|
||||
|
||||
@@ -173,12 +170,11 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
|
||||
|
||||
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]]"
|
||||
//if(!GLOB.limb_icon_cache[cache_key]) //ChompEDIT START
|
||||
var/icon/I = icon(species.get_icobase(owner), "[icon_name]_[body_hair]")
|
||||
if(!GLOB.limb_icon_cache[cache_key])
|
||||
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
|
||||
mob_icon.Blend(I, ICON_OVERLAY)
|
||||
GLOB.limb_icon_cache[cache_key] = I
|
||||
//ChompEDIT END
|
||||
mob_icon.Blend(GLOB.limb_icon_cache[cache_key], ICON_OVERLAY)
|
||||
|
||||
// VOREStation edit start
|
||||
if(nail_polish)
|
||||
@@ -206,12 +202,11 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
|
||||
|
||||
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]]"
|
||||
//if(!GLOB.limb_icon_cache[cache_key]) //ChompEDIT START
|
||||
var/icon/I = icon(species.get_icobase(owner), "[icon_name]_[body_hair]")
|
||||
if(!GLOB.limb_icon_cache[cache_key])
|
||||
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
|
||||
mob_icon.Blend(I, ICON_OVERLAY)
|
||||
GLOB.limb_icon_cache[cache_key] = I
|
||||
//ChompEDIT END
|
||||
mob_icon.Blend(GLOB.limb_icon_cache[cache_key], ICON_OVERLAY)
|
||||
// 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
|
||||
@@ -223,12 +218,9 @@ GLOBAL_LIST_EMPTY(limb_icon_cache)
|
||||
|
||||
/obj/item/organ/external/proc/apply_colouration(var/icon/applying)
|
||||
|
||||
if(transparent) //VOREStation edit
|
||||
if(transparent)
|
||||
applying.MapColors("#4D4D4D","#969696","#1C1C1C", "#000000")
|
||||
if(species && species.get_bodytype(owner) != SPECIES_HUMAN)
|
||||
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.
|
||||
applying.SetIntensity(1)
|
||||
|
||||
else if(status & ORGAN_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)
|
||||
icon_cache_key += "_tone_[s_tone]"
|
||||
else if(s_col && s_col.len >= 3)
|
||||
//VOREStation Edit - Support for species.color_mult
|
||||
if(species && species.color_mult)
|
||||
if(data.get_species_color_mult())
|
||||
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]"
|
||||
else
|
||||
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]"
|
||||
//VOREStation Edit End
|
||||
|
||||
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.
|
||||
if(!hud_damage_image)
|
||||
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.
|
||||
GLOB.limb_icon_cache[cache_key] = icon(get_icon(), null, SOUTH) //ChompEDIT
|
||||
var/image/temp = image(GLOB.limb_icon_cache[cache_key]) //ChompEDIT
|
||||
if((robotic < ORGAN_ROBOT) && species)
|
||||
if(!icon_cache_key || !GLOB.limb_icon_cache[cache_key])
|
||||
GLOB.limb_icon_cache[cache_key] = icon(get_icon(), null, SOUTH)
|
||||
var/image/temp = image(GLOB.limb_icon_cache[cache_key])
|
||||
if((robotic < ORGAN_ROBOT))
|
||||
// Calculate the required colour matrix.
|
||||
var/r = 0.30 * species.health_hud_intensity
|
||||
var/g = 0.59 * species.health_hud_intensity
|
||||
var/b = 0.11 * species.health_hud_intensity
|
||||
var/int = data.get_species_health_hud_intensity()
|
||||
var/r = 0.30 * int
|
||||
var/g = 0.59 * int
|
||||
var/b = 0.11 * int
|
||||
temp.color = list(r, r, r, g, g, g, b, b, b)
|
||||
else if(model)
|
||||
var/datum/robolimb/R = all_robolimbs[model]
|
||||
|
||||
@@ -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
|
||||
@@ -389,7 +389,7 @@
|
||||
icon_cache_key += "[eye_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")
|
||||
add_overlay(lip_icon)
|
||||
mob_icon.Blend(lip_icon, ICON_OVERLAY)
|
||||
|
||||
@@ -155,72 +155,61 @@
|
||||
/obj/item/organ/external/chest/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/groin/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
encased = TRUE
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/arm/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
stapled_nerves = TRUE
|
||||
encased = TRUE
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/arm/right/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
stapled_nerves = TRUE
|
||||
encased = TRUE
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/leg/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
stapled_nerves = TRUE
|
||||
encased = TRUE
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/leg/right/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
stapled_nerves = TRUE
|
||||
encased = TRUE
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/foot/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
stapled_nerves = TRUE
|
||||
encased = TRUE
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/foot/right/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
stapled_nerves = TRUE
|
||||
encased = TRUE
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/hand/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
stapled_nerves = TRUE
|
||||
encased = TRUE
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/hand/right/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
stapled_nerves = TRUE
|
||||
encased = TRUE
|
||||
thick_skin = TRUE
|
||||
|
||||
/obj/item/organ/external/head/unseverable/xeno
|
||||
cannot_gib = 1
|
||||
cannot_amputate = 1
|
||||
thick_skin = TRUE
|
||||
eye_icon = "blank_eyes"
|
||||
|
||||
@@ -21,15 +21,12 @@
|
||||
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.
|
||||
O.species = GLOB.all_species["[manf.suggested_species]"]
|
||||
O.data.setup_from_species(GLOB.all_species["[manf.suggested_species]"])
|
||||
else
|
||||
O.species = GLOB.all_species[prosfab.species]
|
||||
O.data.setup_from_species(GLOB.all_species[prosfab.species])
|
||||
else
|
||||
O.species = GLOB.all_species["Human"]
|
||||
O.data.setup_from_species(GLOB.all_species["Human"])
|
||||
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 ..()
|
||||
|
||||
@@ -60,15 +57,13 @@
|
||||
EO.remove_rejuv()
|
||||
|
||||
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.
|
||||
manf = all_robolimbs["Unbranded"]
|
||||
|
||||
O.robotize(manf.company)
|
||||
qdel_swap(O.dna, new/datum/dna())
|
||||
O.dna.ResetUI()
|
||||
O.dna.ResetSE()
|
||||
O.data.setup_from_dna()
|
||||
|
||||
// Skincolor weirdness.
|
||||
O.s_col[1] = 255 // CHOMP Edit
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
var/check_digi = istype(src,/obj/item/organ/external/leg) || istype(src,/obj/item/organ/external/foot)
|
||||
if(owner)
|
||||
digitigrade = check_digi && owner.digitigrade
|
||||
else if(dna)
|
||||
digitigrade = check_digi && dna.digitigrade
|
||||
else if(data)
|
||||
digitigrade = check_digi && data.digitigrade
|
||||
|
||||
var/should_apply_transparency = FALSE
|
||||
|
||||
@@ -18,22 +18,19 @@
|
||||
if(owner && owner.gender == FEMALE)
|
||||
gender = "f"
|
||||
|
||||
if(!force_icon_key)
|
||||
icon_cache_key = "[icon_name]_[species ? species.get_bodytype() : SPECIES_HUMAN]" //VOREStation Edit
|
||||
else
|
||||
icon_cache_key = "[icon_name]_[force_icon_key]"
|
||||
icon_cache_key = "[icon_name]_[data.get_species_bodytype(owner)]"
|
||||
|
||||
if(force_icon && !skip_forced_icon)
|
||||
mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]")
|
||||
else
|
||||
if(!dna)
|
||||
if(!data)
|
||||
mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_[gender]" : ""]")
|
||||
else
|
||||
|
||||
if(!gendered_icon)
|
||||
gender = null
|
||||
else
|
||||
if(dna.GetUIState(DNA_UI_GENDER))
|
||||
if(data.body_gender)
|
||||
gender = "f"
|
||||
else
|
||||
gender = "m"
|
||||
@@ -50,7 +47,7 @@
|
||||
should_apply_transparency = TRUE
|
||||
else
|
||||
//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
|
||||
apply_colouration(mob_icon)
|
||||
|
||||
@@ -77,12 +74,11 @@
|
||||
icon_cache_key += "[M][markings[M]["color"]]"
|
||||
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]]"
|
||||
//if(!GLOB.limb_icon_cache[cache_key]) //icon cache tweak start
|
||||
var/icon/I = icon(species.get_icobase(owner), "[icon_name]_[body_hair]")
|
||||
if(!GLOB.limb_icon_cache[cache_key])
|
||||
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
|
||||
mob_icon.Blend(I, ICON_OVERLAY)
|
||||
GLOB.limb_icon_cache[cache_key] = I
|
||||
//icon cache tweak end
|
||||
mob_icon.Blend(GLOB.limb_icon_cache[cache_key], ICON_OVERLAY)
|
||||
|
||||
// VOREStation edit start
|
||||
if(nail_polish && !(force_icon && !skip_forced_icon))
|
||||
|
||||
@@ -3869,6 +3869,7 @@
|
||||
#include "code\modules\nifsoft\software\14_commlink.dm"
|
||||
#include "code\modules\nifsoft\software\15_misc.dm"
|
||||
#include "code\modules\organs\blood.dm"
|
||||
#include "code\modules\organs\data.dm"
|
||||
#include "code\modules\organs\misc.dm"
|
||||
#include "code\modules\organs\organ.dm"
|
||||
#include "code\modules\organs\organ_external.dm"
|
||||
|
||||
Reference in New Issue
Block a user