From 4146566af06db3c96189365ad6a30d33c66658c4 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Tue, 6 Oct 2020 17:34:13 +0200 Subject: [PATCH] hoo boy replaces all mentions of bodypart_robotic with is_robotic_limb() where possible, adds BODYPART_HYBRID, adds helpers for organic / robotic limbs (is_robotic_limb() / is_organic_limb(), with a arg to override it accepting hybrid limbs) Also makes the the surgery to heal robotic limbs work if the torso isn't a robot, but rather if there are robotic bodyparts, makes the IPC brain repair.. only accept IPC brains (obviously), makes the damage threshholds for robo-limbs vars instead of a fix 25 with hybrid ones predefined at 25 / 15 (trigger / mindamage), adds an error message to fixing them if already at theshhold, etc. Now just for replacing BODYPART_ORGANIC with is_organic_limb aswell where applicable.. also actual values for the other robo limbs. Fun! --- code/__DEFINES/mobs.dm | 4 ++ code/datums/components/caltrop.dm | 2 +- code/datums/wounds/_scars.dm | 2 +- code/datums/wounds/_wounds.dm | 2 +- code/game/machinery/aug_manipulator.dm | 2 +- code/game/objects/items/storage/book.dm | 2 +- code/game/objects/items/tools/weldingtool.dm | 17 +++-- .../abductor/equipment/glands/heal.dm | 6 +- .../awaymissions/mission_code/snowdin.dm | 2 +- code/modules/client/preferences.dm | 2 +- .../sprite_accessories/alienpeople.dm | 2 +- .../new_player/sprite_accessories/ears.dm | 4 +- .../new_player/sprite_accessories/frills.dm | 2 +- .../new_player/sprite_accessories/horns.dm | 2 +- .../new_player/sprite_accessories/snouts.dm | 4 +- .../living/carbon/alien/special/facehugger.dm | 2 +- .../modules/mob/living/carbon/damage_procs.dm | 4 +- .../mob/living/carbon/human/human_defense.dm | 2 +- .../mob/living/carbon/human/species.dm | 16 ++--- .../carbon/human/species_types/android.dm | 14 +--- code/modules/mob/mob_helpers.dm | 2 +- code/modules/power/cable.dm | 17 +++-- code/modules/projectiles/projectile.dm | 2 +- .../nanites/nanite_programs/healing.dm | 4 +- code/modules/surgery/bodyparts/_bodyparts.dm | 68 ++++++++++++++----- .../surgery/bodyparts/dismemberment.dm | 3 +- code/modules/surgery/bodyparts/head.dm | 4 +- code/modules/surgery/helpers.dm | 26 +++++-- code/modules/surgery/limb_augmentation.dm | 2 +- .../modules/surgery/prosthetic_replacement.dm | 4 +- code/modules/surgery/robot_brain_surgery.dm | 6 +- code/modules/surgery/robot_healing.dm | 14 +++- code/modules/vending/_vending.dm | 2 +- 33 files changed, 157 insertions(+), 90 deletions(-) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 586fce3e0c..dae1b9bf95 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -55,6 +55,10 @@ #define BODYPART_ORGANIC 1 #define BODYPART_ROBOTIC 2 +#define BODYPART_HYBRID 3 + +#define HYBRID_BODYPART_DAMAGE_THRESHHOLD 25 //How much damage has to be suffered until the damage threshhold counts as passed +#define HYBRID_BODYPART_THESHHOLD_MINDAMAGE 15 //Which damage value this limb cannot be healed out of via easy nonsurgical means if the threshhold has been passed, state resets if damage value goes below mindamage. #define BODYPART_NOT_DISABLED 0 #define BODYPART_DISABLED_DAMAGE 1 diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm index d138cf1971..72cf71496b 100644 --- a/code/datums/components/caltrop.dm +++ b/code/datums/components/caltrop.dm @@ -34,7 +34,7 @@ var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) if(!istype(O)) return - if(O.status == BODYPART_ROBOTIC) + if(O.is_robotic_limb()) return var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET) || (H.shoes && (H.shoes.body_parts_covered & FEET))) diff --git a/code/datums/wounds/_scars.dm b/code/datums/wounds/_scars.dm index 85589976e6..8cd0d8a047 100644 --- a/code/datums/wounds/_scars.dm +++ b/code/datums/wounds/_scars.dm @@ -79,7 +79,7 @@ /// Used to "load" a persistent scar /datum/scar/proc/load(obj/item/bodypart/BP, version, description, specific_location, severity=WOUND_SEVERITY_SEVERE) - if(!(BP.body_zone in applicable_zones) || !(BP.is_organic_limb() || BP.render_like_organic)) + if(!(BP.body_zone in applicable_zones) || !BP.is_organic_limb()) qdel(src) return diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index 1ed0d98543..29c87b32d4 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -110,7 +110,7 @@ * * smited- If this is a smite, we don't care about this wound for stat tracking purposes (not yet implemented) */ /datum/wound/proc/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE) - if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || isalien(L.owner) || !(L.is_organic_limb() || L.render_like_organic)) + if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || isalien(L.owner) || !L.is_organic_limb()) qdel(src) return diff --git a/code/game/machinery/aug_manipulator.dm b/code/game/machinery/aug_manipulator.dm index 28733a6b6c..50b6180d62 100644 --- a/code/game/machinery/aug_manipulator.dm +++ b/code/game/machinery/aug_manipulator.dm @@ -59,7 +59,7 @@ else if(istype(O, /obj/item/bodypart)) var/obj/item/bodypart/B = O - if(B.status != BODYPART_ROBOTIC) + if(!B.is_robotic_limb(FALSE)) to_chat(user, "The machine only accepts cybernetics!") return if(storedpart) diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index 28850e79a2..244b8c804b 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -103,7 +103,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", /obj/item/storage/book/bible/proc/bless(mob/living/carbon/human/H, mob/living/user) for(var/X in H.bodyparts) var/obj/item/bodypart/BP = X - if(BP.status == BODYPART_ROBOTIC) + if(BP.is_robotic_limb()) to_chat(user, "[src.deity_name] refuses to heal this metallic taint!") return 0 diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 4cada03307..06cbcd86f2 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -109,12 +109,19 @@ var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) - //only heal to 25 if limb is damaged to or past 25 brute, otherwise heal normally - var/difference = affecting.brute_dam - 25 + if(affecting && affecting.is_robotic_limb() && user.a_intent != INTENT_HARM) + //only heal to threshhold_passed_mindamage if limb is damaged to or past threshhold, otherwise heal normally + var/damage = affecting.brute_dam var/heal_amount = 15 - if(difference >= 0) - heal_amount = difference + + affecting.update_threshhold_state(burn = FALSE) + + if(affecting.threshhold_brute_passed) + heal_amount = min(heal_amount, damage - affecting.threshhold_passed_mindamage) + + if(!heal_amount) + to_chat(user, "") + return if(src.use_tool(H, user, 0, volume=50, amount=1)) if(user == H) user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", diff --git a/code/modules/antagonists/abductor/equipment/glands/heal.dm b/code/modules/antagonists/abductor/equipment/glands/heal.dm index c60ec90480..0fcd1169d8 100644 --- a/code/modules/antagonists/abductor/equipment/glands/heal.dm +++ b/code/modules/antagonists/abductor/equipment/glands/heal.dm @@ -39,7 +39,7 @@ if(!limb) replace_limb(zone) return - if((limb.get_damage() >= (limb.max_damage / 2)) || (limb.status == BODYPART_ROBOTIC)) + if((limb.get_damage() >= (limb.max_damage / 2)) || limb.is_robotic_limb(FALSE)) replace_limb(zone, limb) return @@ -58,7 +58,7 @@ return var/obj/item/bodypart/chest/chest = owner.get_bodypart(BODY_ZONE_CHEST) - if((chest.get_damage() >= (chest.max_damage / 4)) || (chest.status == BODYPART_ROBOTIC)) + if((chest.get_damage() >= (chest.max_damage / 4)) || chest.is_robotic_limb(FALSE)) replace_chest(chest) return @@ -158,7 +158,7 @@ addtimer(CALLBACK(src, .proc/keep_replacing_blood), 30) /obj/item/organ/heart/gland/heal/proc/replace_chest(obj/item/bodypart/chest/chest) - if(chest.status == BODYPART_ROBOTIC) + if(chest.is_robotic_limb(FALSE)) owner.visible_message("[owner]'s [chest.name] rapidly expels its mechanical components, replacing them with flesh!", "Your [chest.name] rapidly expels its mechanical components, replacing them with flesh!") playsound(owner, 'sound/magic/clockwork/anima_fragment_attack.ogg', 50, TRUE) var/list/dirs = GLOB.alldirs.Copy() diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index c7e2609436..ee196f8c1b 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -230,7 +230,7 @@ var/obj/item/bodypart/NN = BP if(NN.status == BODYPART_ORGANIC && NN.species_id != "plasmaman") //getting every organic, non-plasmaman limb (augments/androids are immune to this) plasma_parts += NN - if(NN.status == BODYPART_ROBOTIC) + if(NN.is_robotic_limb(FALSE)) robo_parts += NN if(prob(35)) //checking if the delay is over & if the victim actually has any parts to nom diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 9eae46c1f3..0d8338eeae 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -2641,7 +2641,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(initial_spawn) //delete any existing prosthetic limbs to make sure no remnant prosthetics are left over - But DO NOT delete those that are species-related for(var/obj/item/bodypart/part in character.bodyparts) - if(part.status == BODYPART_ROBOTIC && !part.render_like_organic) + if(part.is_robotic_limb(FALSE)) qdel(part) character.regenerate_limbs() //regenerate limbs so now you only have normal limbs for(var/modified_limb in modified_limbs) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm index 4faef230df..3972bdc2c3 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm @@ -51,7 +51,7 @@ /datum/sprite_accessory/xeno_head/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) - return (!H.dna.features["xenohead"] || H.dna.features["xenohead"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD || (HD.status == BODYPART_ROBOTIC && !HD.render_like_organic)) + return (!H.dna.features["xenohead"] || H.dna.features["xenohead"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD || HD.is_robotic_limb(FALSE)) /datum/sprite_accessory/xeno_head/standard name = "Standard" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm index 1d9138465f..cae1b2e482 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm @@ -5,7 +5,7 @@ /datum/sprite_accessory/ears/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) - return (!H.dna.features["ears"] || H.dna.features["ears"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEEARS)) || !HD || (HD.status == BODYPART_ROBOTIC && !HD.render_like_organic)) + return (!H.dna.features["ears"] || H.dna.features["ears"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEEARS)) || !HD || HD.is_robotic_limb(FALSE)) /datum/sprite_accessory/ears/none name = "None" @@ -187,7 +187,7 @@ /datum/sprite_accessory/ears/mam_ears/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) - return (!H.dna.features["mam_ears"] || H.dna.features["mam_ears"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEEARS)) || !HD || (HD.status == BODYPART_ROBOTIC && !HD.render_like_organic)) + return (!H.dna.features["mam_ears"] || H.dna.features["mam_ears"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEEARS)) || !HD || HD.is_robotic_limb(FALSE)) /datum/sprite_accessory/ears/mam_ears/none name = "None" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/frills.dm b/code/modules/mob/dead/new_player/sprite_accessories/frills.dm index 49013161a9..c7a59da028 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/frills.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/frills.dm @@ -4,7 +4,7 @@ /datum/sprite_accessory/frills/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) - return (!H.dna.features["frills"] || H.dna.features["frills"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || !HD || HD.status == BODYPART_ROBOTIC) + return (!H.dna.features["frills"] || H.dna.features["frills"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || !HD || HD.is_robotic_limb(FALSE)) /datum/sprite_accessory/frills/none name = "None" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/horns.dm b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm index accbc4ee36..0d097b24f0 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/horns.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm @@ -5,7 +5,7 @@ /datum/sprite_accessory/horns/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) - return (!H.dna.features["horns"] || H.dna.features["horns"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD || (HD.status == BODYPART_ROBOTIC && !HD.render_like_organic)) + return (!H.dna.features["horns"] || H.dna.features["horns"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD || HD.is_robotic_limb(FALSE)) /datum/sprite_accessory/horns/none name = "None" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm index 0cd7d301db..69016d2890 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm @@ -5,7 +5,7 @@ /datum/sprite_accessory/snouts/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) - return ((H.wear_mask && (H.wear_mask.flags_inv & HIDESNOUT)) || (H.head && (H.head.flags_inv & HIDESNOUT)) || !HD || (HD.status == BODYPART_ROBOTIC && !HD.render_like_organic)) + return ((H.wear_mask && (H.wear_mask.flags_inv & HIDESNOUT)) || (H.head && (H.head.flags_inv & HIDESNOUT)) || !HD || HD.is_robotic_limb(FALSE)) /datum/sprite_accessory/snout/guilmon name = "Guilmon" @@ -163,7 +163,7 @@ /datum/sprite_accessory/snouts/mam_snouts/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) - return ((H.wear_mask && (H.wear_mask.flags_inv & HIDESNOUT)) || (H.head && (H.head.flags_inv & HIDESNOUT)) || !HD || (HD.status == BODYPART_ROBOTIC && !HD.render_like_organic)) + return ((H.wear_mask && (H.wear_mask.flags_inv & HIDESNOUT)) || (H.head && (H.head.flags_inv & HIDESNOUT)) || !HD || HD.is_robotic_limb(FALSE)) /datum/sprite_accessory/snouts/mam_snouts/none name = "None" diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index ad8828572c..2c0df014d0 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -212,7 +212,7 @@ icon_state = "[initial(icon_state)]_impregnated" var/obj/item/bodypart/chest/LC = target.get_bodypart(BODY_ZONE_CHEST) - if((!LC || LC.status != BODYPART_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo)) + if((!LC || LC.is_robotic_limb(FALSE)) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo)) new /obj/item/organ/body_egg/alien_embryo(target) else diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index 5c5a1d6d52..aad647e1f3 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -169,11 +169,11 @@ //////////////////////////////////////////// //Returns a list of damaged bodyparts -/mob/living/carbon/proc/get_damaged_bodyparts(brute = FALSE, burn = FALSE, stamina = FALSE, status) +/mob/living/carbon/proc/get_damaged_bodyparts(brute = FALSE, burn = FALSE, stamina = FALSE, list/status) var/list/obj/item/bodypart/parts = list() for(var/X in bodyparts) var/obj/item/bodypart/BP = X - if(status && BP.status != status) + if(status && !status[BP.status]) continue if((brute && BP.brute_dam) || (burn && BP.burn_dam) || (stamina && BP.stamina_dam)) parts += BP diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 96fda36370..76a9c00ed1 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -411,7 +411,7 @@ apply_status_effect(/datum/status_effect/no_combat_mode/robotic_emp, severity / 20) severity *= 0.5 for(var/obj/item/bodypart/L in src.bodyparts) - if(L.status == BODYPART_ROBOTIC) + if(L.is_robotic_limb()) if(!informed) to_chat(src, "You feel a sharp pain as your robotic limbs overload.") informed = TRUE diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 554013c7bc..0845fa45f7 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -366,8 +366,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(ROBOTIC_LIMBS in species_traits) for(var/obj/item/bodypart/B in C.bodyparts) - B.change_bodypart_status(BODYPART_ROBOTIC, FALSE, TRUE) // Makes all Bodyparts robotic. - B.render_like_organic = TRUE + B.change_bodypart_status(BODYPART_HYBRID, FALSE, TRUE) // Makes all Bodyparts 'robotic'. SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species) @@ -412,8 +411,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(ROBOTIC_LIMBS in species_traits) for(var/obj/item/bodypart/B in C.bodyparts) - B.change_bodypart_status(BODYPART_ORGANIC, FALSE, TRUE) - B.render_like_organic = FALSE + B.change_bodypart_status(initial(B.status), FALSE, TRUE) SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src) @@ -435,7 +433,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/dynamic_fhair_suffix = "" //for augmented heads - if(HD.status == BODYPART_ROBOTIC && !HD.render_like_organic) + if(HD.is_robotic_limb(FALSE)) return //we check if our hat or helmet hides our facial hair. @@ -1023,7 +1021,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return FALSE if(!CHECK_BITFIELD(I.item_flags, NO_UNIFORM_REQUIRED)) var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST) - if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC)) + if(!H.w_uniform && !nojumpsuit && (!O || !O.is_robotic_limb())) if(return_warning) return_warning[1] = "You need a jumpsuit before you can attach this [I.name]!" return FALSE @@ -1065,7 +1063,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return FALSE if(!CHECK_BITFIELD(I.item_flags, NO_UNIFORM_REQUIRED)) var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST) - if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC)) + if(!H.w_uniform && !nojumpsuit && (!O || !O.is_robotic_limb())) if(return_warning) return_warning[1] = "You need a jumpsuit before you can attach this [I.name]!" return FALSE @@ -1080,7 +1078,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_L_LEG) - if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC)) + if(!H.w_uniform && !nojumpsuit && (!O || !O.is_robotic_limb())) if(return_warning) return_warning[1] = "You need a jumpsuit before you can attach this [I.name]!" return FALSE @@ -1096,7 +1094,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_R_LEG) - if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC)) + if(!H.w_uniform && !nojumpsuit && (!O || !O.is_robotic_limb())) if(return_warning) return_warning[1] = "You need a jumpsuit before you can attach this [I.name]!" return FALSE diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm index 5d43d18429..0ed6828416 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -11,16 +11,4 @@ mutanttongue = /obj/item/organ/tongue/robot species_language_holder = /datum/language_holder/synthetic limbs_id = "synth" - species_type = "robotic" - -/datum/species/android/on_species_gain(mob/living/carbon/C) - . = ..() - for(var/X in C.bodyparts) - var/obj/item/bodypart/O = X - O.change_bodypart_status(BODYPART_ROBOTIC, FALSE, TRUE) - -/datum/species/android/on_species_loss(mob/living/carbon/C) - . = ..() - for(var/X in C.bodyparts) - var/obj/item/bodypart/O = X - O.change_bodypart_status(BODYPART_ORGANIC,FALSE, TRUE) + species_type = "robotic" \ No newline at end of file diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index aa6635f73d..d4edb78e2d 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -379,7 +379,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp /proc/item_heal_robotic(mob/living/carbon/human/H, mob/user, brute_heal, burn_heal) var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - if(affecting && affecting.status == BODYPART_ROBOTIC) + if(affecting && affecting.is_robotic_limb()) var/dam //changes repair text based on how much brute/burn was supplied if(brute_heal > burn_heal) dam = 1 diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 3f1e688120..5fbdc57acb 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -548,12 +548,19 @@ By design, d1 is the smallest direction and d2 is the highest return ..() var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - if(affecting && affecting.status == BODYPART_ROBOTIC) - //only heal to 25 if limb is damaged to or past 25 burn, otherwise heal normally - var/difference = affecting.burn_dam - 25 + if(affecting && affecting.is_robotic_limb()) + //only heal to threshhold_passed_mindamage if limb is damaged to or past threshhold, otherwise heal normally + var/damage = affecting.burn_dam var/heal_amount = 15 - if(difference >= 0) - heal_amount = difference + + affecting.update_threshhold_state(brute = FALSE) + + if(affecting.threshhold_burn_passed) + heal_amount = min(heal_amount, damage - affecting.threshhold_passed_mindamage) + + if(!heal_amount) + to_chat(user, "") + return if(user == H) user.visible_message("[user] starts to fix some of the wires in [H]'s [affecting.name].", "You start fixing some of the wires in [H]'s [affecting.name].") if(!do_mob(user, H, 50)) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 4e81c5aeb6..fd442bb7a6 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -245,7 +245,7 @@ if(starting) splatter_dir = get_dir(starting, target_loca) var/obj/item/bodypart/B = L.get_bodypart(def_zone) - if(B && B.status == BODYPART_ROBOTIC) // So if you hit a robotic, it sparks instead of bloodspatters + if(B && B.is_robotic_limb()) // So if you hit a robotic, it sparks instead of bloodspatters - Hybrid limbs don't bleed from this as of now too, subject to balance.. probably. do_sparks(2, FALSE, target.loc) if(prob(25)) new /obj/effect/decal/cleanable/oil(target_loca) diff --git a/code/modules/research/nanites/nanite_programs/healing.dm b/code/modules/research/nanites/nanite_programs/healing.dm index 18307ce2c5..f963114e38 100644 --- a/code/modules/research/nanites/nanite_programs/healing.dm +++ b/code/modules/research/nanites/nanite_programs/healing.dm @@ -121,7 +121,7 @@ if(iscarbon(host_mob)) var/mob/living/carbon/C = host_mob - var/list/parts = C.get_damaged_bodyparts(TRUE, TRUE, status = BODYPART_ROBOTIC) + var/list/parts = C.get_damaged_bodyparts(TRUE, TRUE, status = BODYPART_ROBOTIC | BODYPART_HYBRID) if(!parts.len) return FALSE else @@ -132,7 +132,7 @@ /datum/nanite_program/repairing/active_effect(mob/living/M) if(iscarbon(host_mob)) var/mob/living/carbon/C = host_mob - var/list/parts = C.get_damaged_bodyparts(TRUE, TRUE, status = BODYPART_ROBOTIC) + var/list/parts = C.get_damaged_bodyparts(TRUE, TRUE, status = BODYPART_ROBOTIC | BODYPART_HYBRID) if(!parts.len) return var/update = FALSE diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 90f2185ce6..b4938bab1b 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -71,7 +71,12 @@ var/medium_burn_msg = "blistered" var/heavy_burn_msg = "peeling away" - var/render_like_organic = FALSE // forces limb to render as if it were an organic limb + + //Some special vars for robotic bodyparts, in the base type to prevent needing typecasting / fancy checks. + var/easy_heal_threshhold = -1 //If greater or equal to zero, if limb damage of a type passes this threshhold, it cannot be healed beyond threshhold_passed_mindamage. Only needed for robotic limbs, but is in the basetype to prevent needing spaghetti-checks. + var/threshhold_passed_mindamage = 0 //If the threshhold got passed, what is the minimum damage this limb can be healed to? Loses the threshhold-passed state healing is started while below mindamage. + var/threshhold_brute_passed = FALSE + var/threshhold_burn_passed = FALSE //Ugly but neccessary vars that might get replaced with a flag lateron maybe sometime. /// The wounds currently afflicting this body part var/list/wounds @@ -143,7 +148,7 @@ /obj/item/bodypart/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() - if(status != BODYPART_ROBOTIC) + if(!is_robotic_limb()) playsound(get_turf(src), 'sound/misc/splort.ogg', 50, 1, -1) pixel_x = rand(-3, 3) pixel_y = rand(-3, 3) @@ -151,7 +156,7 @@ //empties the bodypart from its organs and other things inside it /obj/item/bodypart/proc/drop_organs(mob/user) var/turf/T = get_turf(src) - if(status != BODYPART_ROBOTIC) + if(!is_robotic_limb()) playsound(T, 'sound/misc/splort.ogg', 50, 1, -1) if(current_gauze) QDEL_NULL(current_gauze) @@ -458,10 +463,10 @@ //Cannot remove negative damage (i.e. apply damage) /obj/item/bodypart/proc/heal_damage(brute, burn, stamina, only_robotic = FALSE, only_organic = TRUE, updating_health = TRUE) - if(only_robotic && status != BODYPART_ROBOTIC) //This makes organic limbs not heal when the proc is in Robotic mode. + if(only_robotic && !is_robotic_limb()) //This makes organic limbs not heal when the proc is in Robotic mode. return - if(only_organic && status != BODYPART_ORGANIC) //This makes robolimbs not healable by chems. + if(only_organic && !is_organic_limb(FALSE)) //This makes robolimbs and hybridlimbs not healable by chems. return brute_dam = round(max(brute_dam - brute, 0), DAMAGE_PRECISION) @@ -503,7 +508,7 @@ if(!last_maxed) owner.emote("scream") last_maxed = TRUE - if(!is_organic_limb() || stamina_dam >= max_damage) + if(!is_organic_limb(FALSE) || stamina_dam >= max_damage) return BODYPART_DISABLED_DAMAGE else if(disabled && (get_damage(TRUE) <= (max_damage * 0.8))) // reenabled at 80% now instead of 50% as of wounds update last_maxed = FALSE @@ -545,7 +550,8 @@ return FALSE //Change organ status -/obj/item/bodypart/proc/change_bodypart_status(new_limb_status, heal_limb, change_icon_to_default) +/obj/item/bodypart/proc/change_bodypart_status(new_limb_status, heal_limb, change_icon_to_default, no_update = FALSE) + var/old_status = status status = new_limb_status if(heal_limb) burn_dam = 0 @@ -553,20 +559,48 @@ brutestate = 0 burnstate = 0 + if(status == BODYPART_HYBRID) + easy_heal_threshhold = HYBRID_BODYPART_DAMAGE_THRESHHOLD + threshhold_passed_mindamage = HYBRID_BODYPART_THESHHOLD_MINDAMAGE + else if(old_status == BODYPART_HYBRID) + easy_heal_threshhold = initial(easy_heal_threshhold) + threshhold_passed_mindamage = initial(threshhold_passed_mindamage) + + update_threshhold_state() + if(change_icon_to_default) - if(status == BODYPART_ORGANIC) + if(is_organic_limb()) icon = base_bp_icon || DEFAULT_BODYPART_ICON_ORGANIC - else if(status == BODYPART_ROBOTIC) + else if(is_robotic_limb(FALSE)) icon = base_bp_icon || DEFAULT_BODYPART_ICON_ROBOTIC - if(owner) + if(owner && !no_update) //Only use no_update if you are sure the bodypart will get updated from other sources anyways, to prevent unneccessary processing use. owner.updatehealth() owner.update_body() //if our head becomes robotic, we remove the lizard horns and human hair. owner.update_hair() owner.update_damage_overlays() -/obj/item/bodypart/proc/is_organic_limb() - return (status == BODYPART_ORGANIC) +/obj/item/bodypart/proc/is_organic_limb(hybrid_allowed = TRUE) + if(!hybrid_allowed) + return (status == BODYPART_ORGANIC) + return ((status == BODYPART_ORGANIC) || (status == BODYPART_HYBRID)) //Goodbye if(B.status == BODYPART_ORGANIC || B.status == BODYPART_HYBRID) + +/obj/item/bodypart/proc/is_robotic_limb(hybrid_allowed = TRUE) + if(!hybrid_allowed) + return (status == BODYPART_ROBOTIC) + return ((status == BODYPART_ROBOTIC) || (status == BODYPART_HYBRID)) + +/obj/item/bodypart/proc/update_threshhold_state(brute = TRUE, burn = TRUE) + if(brute) + if(brute_dam < threshhold_passed_mindamage || easy_heal_threshhold < 0) + threshhold_brute_passed = FALSE + else if(brute_dam >= easy_heal_threshhold) + threshhold_brute_passed = TRUE + if(burn) + if(burn_dam < threshhold_passed_mindamage || easy_heal_threshhold < 0) + threshhold_burn_passed = FALSE + else if(burn_dam >= easy_heal_threshhold) + threshhold_burn_passed = TRUE //we inform the bodypart of the changes that happened to the owner, or give it the informations from a source mob. /obj/item/bodypart/proc/update_limb(dropping_limb, mob/living/carbon/source) @@ -581,7 +615,7 @@ C = owner no_update = FALSE - if(HAS_TRAIT(C, TRAIT_HUSK) && (is_organic_limb() || render_like_organic)) + if(HAS_TRAIT(C, TRAIT_HUSK) && is_organic_limb()) species_id = "husk" //overrides species_id dmg_overlay_type = "" //no damage overlay shown when husked should_draw_gender = FALSE @@ -672,9 +706,9 @@ else if(animal_origin == MONKEY_BODYPART) //currently monkeys are the only non human mob to have damage overlays. dmg_overlay_type = animal_origin - if(status == BODYPART_ROBOTIC) + if(is_robotic_limb()) dmg_overlay_type = "robotic" - if(!render_like_organic) + if(is_robotic_limb(FALSE)) body_markings = null aux_marking = null @@ -728,7 +762,7 @@ . += limb if(animal_origin) - if(is_organic_limb()) + if(is_organic_limb(FALSE)) limb.icon = 'icons/mob/animal_parts.dmi' if(species_id == "husk") limb.icon_state = "[animal_origin]_husk_[body_zone]" @@ -742,7 +776,7 @@ if((body_zone != BODY_ZONE_HEAD && body_zone != BODY_ZONE_CHEST)) should_draw_gender = FALSE - if(is_organic_limb() || render_like_organic) + if(is_organic_limb()) limb.icon = base_bp_icon || 'icons/mob/human_parts.dmi' if(should_draw_gender) limb.icon_state = "[species_id]_[body_zone]_[icon_gender]" diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 3038e32733..3aefc2d8e3 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -435,7 +435,6 @@ var/datum/wound/loss/phantom_loss = new // stolen valor, really scaries.generate(L, phantom_loss) if(HAS_TRAIT(src, ROBOTIC_LIMBS)) //Snowflake trait moment, but needed. - L.render_like_organic = TRUE - L.change_bodypart_status(BODYPART_ROBOTIC, FALSE, TRUE) //Haha what if IPC-lings actually regenerated the right limbs instead of organic ones? That'd be pretty cool, right? + L.change_bodypart_status(BODYPART_HYBRID, FALSE, TRUE) //Haha what if IPC-lings actually regenerated the right limbs instead of organic ones? That'd be pretty cool, right? L.attach_limb(src, 1) return TRUE diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index b6a0a387e2..d47794e896 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -45,7 +45,7 @@ /obj/item/bodypart/head/drop_organs(mob/user) var/turf/T = get_turf(src) - if(status != BODYPART_ROBOTIC) + if(!is_robotic_limb()) playsound(T, 'sound/misc/splort.ogg', 50, 1, -1) for(var/obj/item/I in src) if(I == brain) @@ -141,7 +141,7 @@ . = ..() if(dropped) //certain overlays only appear when the limb is being detached from its owner. - if(status != BODYPART_ROBOTIC) //having a robotic head hides certain features. + if(!is_robotic_limb(FALSE)) //having a robotic head hides certain features. //facial hair if(facial_hair_style) var/datum/sprite_accessory/S = GLOB.facial_hair_styles_list[facial_hair_style] diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 7a92b39692..df82a765c8 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -26,8 +26,16 @@ if(affecting) if(!S.requires_bodypart) continue - if(S.requires_bodypart_type && affecting.status != S.requires_bodypart_type) - continue + if(S.requires_bodypart_type) //ugly but it'll do. + if(S.requires_bodypart_type == BODYPART_ORGANIC) + if(!affecting.is_organic_limb(FALSE)) + continue + else if(S.requires_bodypart_type == BODYPART_ROBOTIC) + if(!affecting.is_robotic_limb()) + continue + else if(S.requires_bodypart_type == BODYPART_HYBRID) + if(!affecting.is_organic_limb() || !affecting.is_robotic_limb()) + continue if(S.requires_real_bodypart && affecting.is_pseudopart) continue else if(C && S.requires_bodypart) //mob with no limb in surgery zone when we need a limb @@ -58,8 +66,16 @@ if(affecting) if(!S.requires_bodypart) return - if(S.requires_bodypart_type && affecting.status != S.requires_bodypart_type) - return + if(S.requires_bodypart_type) //*scream + if(S.requires_bodypart_type == BODYPART_ORGANIC) + if(!affecting.is_organic_limb(FALSE)) + return + else if(S.requires_bodypart_type == BODYPART_ROBOTIC) + if(!affecting.is_robotic_limb()) + return + else if(S.requires_bodypart_type == BODYPART_HYBRID) + if(!affecting.is_organic_limb() || !affecting.is_robotic_limb()) + return else if(C && S.requires_bodypart) return if(S.lying_required && !(M.lying)) @@ -91,7 +107,7 @@ else if(S.can_cancel) var/required_tool_type = TOOL_CAUTERY var/obj/item/close_tool = user.get_inactive_held_item() - var/is_robotic = S.requires_bodypart_type == BODYPART_ROBOTIC + var/is_robotic = (S.requires_bodypart_type == BODYPART_ROBOTIC || S.requires_bodypart_type == BODYPART_HYBRID) if(is_robotic) required_tool_type = TOOL_SCREWDRIVER if(iscyborg(user)) diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index 92059f04d4..e52f6ad141 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -10,7 +10,7 @@ if(istype(tool, /obj/item/organ_storage) && istype(tool.contents[1], /obj/item/bodypart)) tool = tool.contents[1] var/obj/item/bodypart/aug = tool - if(aug.status != BODYPART_ROBOTIC) + if(aug.is_robotic_limb()) to_chat(user, "That's not an augment, silly!") return -1 if(aug.body_zone != target_zone) diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm index 8eac5b7895..b0102da7b7 100644 --- a/code/modules/surgery/prosthetic_replacement.dm +++ b/code/modules/surgery/prosthetic_replacement.dm @@ -29,10 +29,10 @@ if(istype(tool, /obj/item/bodypart)) var/obj/item/bodypart/BP = tool if(ismonkey(target))// monkey patient only accept organic monkey limbs - if(BP.status == BODYPART_ROBOTIC || BP.animal_origin != MONKEY_BODYPART) + if(BP.is_robotic_limb() || BP.animal_origin != MONKEY_BODYPART) to_chat(user, "[BP] doesn't match the patient's morphology.") return -1 - if(BP.status != BODYPART_ROBOTIC) + if(!BP.is_robotic_limb()) organ_rejection_dam = 10 if(ishuman(target)) if(BP.animal_origin) diff --git a/code/modules/surgery/robot_brain_surgery.dm b/code/modules/surgery/robot_brain_surgery.dm index 5feca7382f..62ae98f7b6 100644 --- a/code/modules/surgery/robot_brain_surgery.dm +++ b/code/modules/surgery/robot_brain_surgery.dm @@ -10,7 +10,7 @@ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_HEAD) - requires_bodypart_type = BODYPART_ROBOTIC + requires_bodypart_type = 0 desc = "A surgical procedure that restores the default behavior logic and personality matrix of an IPC posibrain." /datum/surgery_step/fix_robot_brain @@ -19,8 +19,10 @@ time = 120 //long and complicated /datum/surgery/robot_brain_surgery/can_start(mob/user, mob/living/carbon/target, obj/item/tool) + if(!..()) + return FALSE var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) - if(!B) + if(!B || !istype(B, /obj/item/organ/brain/ipc)) //No cheating! return FALSE return TRUE diff --git a/code/modules/surgery/robot_healing.dm b/code/modules/surgery/robot_healing.dm index 6355410a79..db5a6ced97 100644 --- a/code/modules/surgery/robot_healing.dm +++ b/code/modules/surgery/robot_healing.dm @@ -12,7 +12,7 @@ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST) - requires_bodypart_type = BODYPART_ROBOTIC + requires_bodypart_type = 0 //You can do this on anyone, but it won't really be useful on people without augments. ignore_clothes = TRUE var/antispam = FALSE var/healing_step_type = /datum/surgery_step/robot_heal/basic @@ -42,6 +42,18 @@ return FALSE return TRUE +/datum/surgery/robot_brain_surgery/can_start(mob/user, mob/living/carbon/target, obj/item/tool) + if(!..()) + return FALSE + var/possible = FALSE + for(var/obj/item/bodypart/B in target.bodyparts) + if(B.is_robotic_limb()) + possible = TRUE + break + if(!possible) + return FALSE + return TRUE + /datum/surgery_step/robot_heal/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) var/woundtype if(implement_type == TOOL_WELDER) diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 26bee38f7b..a115300085 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -529,7 +529,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(5) // limb squish! for(var/i in C.bodyparts) var/obj/item/bodypart/squish_part = i - if(squish_part.is_organic_limb() || squish_part.render_like_organic) + if(squish_part.is_organic_limb()) var/type_wound = pick(list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate)) squish_part.force_wound_upwards(type_wound) else