[MIRROR] Fixes disabled limbs from compound fractures, only robotic limbs can be disabled by pure damage now (#1709)

* Fixes disabled limbs from compound fractures, only robotic limbs can be disabled by pure damage now (#54922)

* Fixes disabled limbs from compound fractures, only robotic limbs can be disabled by pure damage now

Co-authored-by: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com>
This commit is contained in:
SkyratBot
2020-11-17 00:50:36 +01:00
committed by GitHub
parent 9ed66a2511
commit 964adb7828
16 changed files with 75 additions and 80 deletions
+2
View File
@@ -433,6 +433,8 @@
#define COMSIG_CARBON_ATTACH_LIMB "carbon_attach_limb"
#define COMPONENT_NO_ATTACH (1<<0)
#define COMSIG_CARBON_REMOVE_LIMB "carbon_remove_limb" //from base of /obj/item/bodypart/proc/drop_limb(special, dismembered)
#define COMSIG_BODYPART_GAUZED "bodypart_gauzed" // from /obj/item/bodypart/proc/apply_gauze(/obj/item/stack/gauze)
#define COMSIG_BODYPART_GAUZE_DESTROYED "bodypart_degauzed" // from [/obj/item/bodypart/proc/seep_gauze] when it runs out of absorption
///from base of mob/living/carbon/soundbang_act(): (list(intensity))
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang"
+2 -2
View File
@@ -145,8 +145,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_EASYDISMEMBER "easy_dismember"
#define TRAIT_LIMBATTACHMENT "limb_attach"
#define TRAIT_NOLIMBDISABLE "no_limb_disable"
#define TRAIT_EASYLIMBWOUND "easy_limb_wound"
#define TRAIT_HARDLIMBWOUND "hard_limb_wound"
#define TRAIT_EASILY_WOUNDED "easy_limb_wound"
#define TRAIT_HARDLY_WOUNDED "hard_limb_wound"
#define TRAIT_TOXINLOVER "toxinlover"
#define TRAIT_NOBREATH "no_breath"
#define TRAIT_ANTIMAGIC "anti_magic"
+2 -2
View File
@@ -62,8 +62,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_EASYDISMEMBER" = TRAIT_EASYDISMEMBER,
"TRAIT_LIMBATTACHMENT" = TRAIT_LIMBATTACHMENT,
"TRAIT_NOLIMBDISABLE" = TRAIT_NOLIMBDISABLE,
"TRAIT_EASYLIMBWOUND" = TRAIT_EASYLIMBWOUND,
"TRAIT_HARDLIMBWOUND" = TRAIT_HARDLIMBWOUND,
"TRAIT_EASILY_WOUNDED" = TRAIT_EASILY_WOUNDED,
"TRAIT_HARDLY_WOUNDED" = TRAIT_HARDLY_WOUNDED,
"TRAIT_TOXINLOVER" = TRAIT_TOXINLOVER,
"TRAIT_NOBREATH" = TRAIT_NOBREATH,
"TRAIT_ANTIMAGIC" = TRAIT_ANTIMAGIC,
+2 -2
View File
@@ -120,14 +120,14 @@
if(!.)
return
ADD_TRAIT(H, TRAIT_NOGUNS, SLEEPING_CARP_TRAIT)
ADD_TRAIT(H, TRAIT_HARDLIMBWOUND, SLEEPING_CARP_TRAIT)
ADD_TRAIT(H, TRAIT_HARDLY_WOUNDED, SLEEPING_CARP_TRAIT)
ADD_TRAIT(H, TRAIT_NODISMEMBER, SLEEPING_CARP_TRAIT)
H.faction |= "carp" //:D
/datum/martial_art/the_sleeping_carp/on_remove(mob/living/carbon/human/H)
. = ..()
REMOVE_TRAIT(H, TRAIT_NOGUNS, SLEEPING_CARP_TRAIT)
REMOVE_TRAIT(H, TRAIT_HARDLIMBWOUND, SLEEPING_CARP_TRAIT)
REMOVE_TRAIT(H, TRAIT_HARDLY_WOUNDED, SLEEPING_CARP_TRAIT)
REMOVE_TRAIT(H, TRAIT_NODISMEMBER, SLEEPING_CARP_TRAIT)
H.faction -= "carp" //:(
+1 -1
View File
@@ -257,7 +257,7 @@
name = "Frail"
desc = "You have skin of paper and bones of glass! You suffer wounds much more easily than most."
value = -2
mob_trait = TRAIT_EASYLIMBWOUND
mob_trait = TRAIT_EASILY_WOUNDED
gain_text = "<span class='danger'>You feel frail.</span>"
lose_text = "<span class='notice'>You feel sturdy again.</span>"
medical_record_text = "Patient is absurdly easy to injure. Please take all due dilligence to avoid possible malpractice suits."
+3
View File
@@ -165,6 +165,7 @@
/// Remove the wound from whatever it's afflicting, and cleans up whateverstatus effects it had or modifiers it had on interaction times. ignore_limb is used for detachments where we only want to forget the victim
/datum/wound/proc/remove_wound(ignore_limb, replaced = FALSE)
//TODO: have better way to tell if we're getting removed without replacement (full heal) scar stuff
set_disabling(FALSE)
if(limb && !already_scarred && !replaced)
already_scarred = TRUE
var/datum/scar/new_scar = new
@@ -229,6 +230,8 @@
else if(. && limb) //Lost disabling.
REMOVE_TRAIT(limb, TRAIT_PARALYSIS, src)
REMOVE_TRAIT(limb, TRAIT_DISABLED_BY_WOUND, src)
if(limb?.can_be_disabled)
limb.update_disabled()
/// Additional beneficial effects when the wound is gained, in case you want to give a temporary boost to allow the victim to try an escape or last stand
+14 -9
View File
@@ -33,6 +33,9 @@
Overwriting of base procs
*/
/datum/wound/blunt/wound_injury(datum/wound/old_wound = null)
// hook into gaining/losing gauze so crit bone wounds can re-enable/disable depending if they're slung or not
RegisterSignal(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED), .proc/update_inefficiencies)
if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group)
processes = TRUE
active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND)
@@ -52,6 +55,8 @@
/datum/wound/blunt/remove_wound(ignore_limb, replaced)
limp_slowdown = 0
QDEL_NULL(active_trauma)
if(limb)
UnregisterSignal(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED))
if(victim)
UnregisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK)
return ..()
@@ -146,15 +151,15 @@
else
var/sling_condition = ""
// how much life we have left in these bandages
switch(limb.current_gauze.obj_integrity / limb.current_gauze.max_integrity * 100)
if(0 to 25)
sling_condition = "just barely "
if(25 to 50)
sling_condition = "loosely "
if(50 to 75)
sling_condition = "mostly "
if(75 to INFINITY)
sling_condition = "tightly "
switch(limb.current_gauze.absorption_capacity)
if(0 to 1.25)
sling_condition = "just barely"
if(1.25 to 2.75)
sling_condition = "loosely"
if(2.75 to 4)
sling_condition = "mostly"
if(4 to INFINITY)
sling_condition = "tightly"
msg += "[victim.p_their(TRUE)] [limb.name] is [sling_condition] fastened in a sling of [limb.current_gauze.name]"
+4 -4
View File
@@ -125,13 +125,13 @@
var/bandage_condition
switch(limb.current_gauze.absorption_capacity)
if(0 to 1.25)
bandage_condition = "nearly ruined "
bandage_condition = "nearly ruined"
if(1.25 to 2.75)
bandage_condition = "badly worn "
bandage_condition = "badly worn"
if(2.75 to 4)
bandage_condition = "slightly pus-stained "
bandage_condition = "slightly pus-stained"
if(4 to INFINITY)
bandage_condition = "clean "
bandage_condition = "clean"
condition += " underneath a dressing of [bandage_condition] [limb.current_gauze.name]"
else
+6 -6
View File
@@ -54,18 +54,18 @@
if(!limb.current_gauze)
return ..()
var/list/msg = list("The cuts on [victim.p_their()] [limb.name] are wrapped with")
var/list/msg = list("The cuts on [victim.p_their()] [limb.name] are wrapped with ")
// how much life we have left in these bandages
switch(limb.current_gauze.absorption_capacity)
if(0 to 1.25)
msg += "nearly ruined "
msg += "nearly ruined"
if(1.25 to 2.75)
msg += "badly worn "
msg += "badly worn"
if(2.75 to 4)
msg += "slightly bloodied "
msg += "slightly bloodied"
if(4 to INFINITY)
msg += "clean "
msg += "[limb.current_gauze.name]!"
msg += "clean"
msg += " [limb.current_gauze.name]!"
return "<B>[msg.Join()]</B>"
@@ -489,6 +489,7 @@
new /obj/item/clothing/mask/muzzle(src)
new /obj/item/mmi/syndie(src)
new /obj/item/blood_filter(src)
new /obj/item/stack/medical/bone_gel(src)
/obj/item/storage/backpack/duffelbag/syndie/ammo
name = "ammunition duffel bag"
@@ -6,7 +6,7 @@
meat = /obj/item/stack/sheet/mineral/plasma
species_traits = list(NOBLOOD,NOTRANSSTING, HAS_BONE)
// plasmemes get hard to wound since they only need a severe bone wound to dismember, but unlike skellies, they can't pop their bones back into place
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_NOHUNGER,TRAIT_ALWAYS_CLEAN, TRAIT_HARDLIMBWOUND)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_NOHUNGER,TRAIT_ALWAYS_CLEAN, TRAIT_HARDLY_WOUNDED)
inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
mutantlungs = /obj/item/organ/lungs/plasmaman
mutanttongue = /obj/item/organ/tongue/bone/plasmaman
@@ -8,7 +8,7 @@
sexes = 0
meat = /obj/item/food/meat/slab/human/mutant/zombie
species_traits = list(NOBLOOD,NOZOMBIE,NOTRANSSTING, HAS_FLESH, HAS_BONE)
inherent_traits = list(TRAIT_NOMETABOLISM,TRAIT_TOXIMMUNE,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_EASYLIMBWOUND,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH,TRAIT_NOCLONELOSS)
inherent_traits = list(TRAIT_NOMETABOLISM,TRAIT_TOXIMMUNE,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_EASILY_WOUNDED,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH,TRAIT_NOCLONELOSS)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutanttongue = /obj/item/organ/tongue/zombie
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
@@ -100,6 +100,6 @@
mutanttongue = /obj/item/organ/tongue/zombie
changesource_flags = MIRROR_BADMIN | WABBAJACK | ERT_SPAWN
species_traits = list(HAS_FLESH, HAS_BONE)
inherent_traits = list(TRAIT_EASYLIMBWOUND)
inherent_traits = list(TRAIT_EASILY_WOUNDED)
#undef REGENERATION_DELAY
@@ -565,7 +565,7 @@
/datum/reagent/drug/maint/sludge/on_mob_metabolize(mob/living/L)
. = ..()
ADD_TRAIT(L,TRAIT_HARDLIMBWOUND,type)
ADD_TRAIT(L,TRAIT_HARDLY_WOUNDED,type)
/datum/reagent/drug/maint/sludge/on_mob_life(mob/living/carbon/M)
. = ..()
@@ -573,7 +573,7 @@
/datum/reagent/drug/maint/sludge/on_mob_end_metabolize(mob/living/M)
. = ..()
REMOVE_TRAIT(M,TRAIT_HARDLIMBWOUND,type)
REMOVE_TRAIT(M,TRAIT_HARDLY_WOUNDED,type)
/datum/reagent/drug/maint/sludge/overdose_process(mob/living/M)
. = ..()
@@ -37,9 +37,9 @@
/datum/bioware/reinforced_ligaments/on_gain()
..()
ADD_TRAIT(owner, TRAIT_NODISMEMBER, "reinforced_ligaments")
ADD_TRAIT(owner, TRAIT_EASYLIMBWOUND, "reinforced_ligaments")
ADD_TRAIT(owner, TRAIT_EASILY_WOUNDED, "reinforced_ligaments")
/datum/bioware/reinforced_ligaments/on_lose()
..()
REMOVE_TRAIT(owner, TRAIT_NODISMEMBER, "reinforced_ligaments")
REMOVE_TRAIT(owner, TRAIT_EASYLIMBWOUND, "reinforced_ligaments")
REMOVE_TRAIT(owner, TRAIT_EASILY_WOUNDED, "reinforced_ligaments")
+27 -47
View File
@@ -24,8 +24,8 @@
///If disabled, limb is as good as missing.
var/bodypart_disabled = FALSE
///Multiplied by max_damage it returns the threshold which defines a limb being disabled or not. From 0 to 1.
var/disable_threshold = 1
///Multiplied by max_damage it returns the threshold which defines a limb being disabled or not. From 0 to 1. 0 means no disable thru damage
var/disable_threshold = 0
///Controls whether bodypart_disabled makes sense or not for this limb.
var/can_be_disabled = FALSE
var/body_damage_coeff = 1 //Multiplier of the limb's damage that gets applied to the mob
@@ -181,8 +181,7 @@
var/turf/T = get_turf(src)
if(status != BODYPART_ROBOTIC)
playsound(T, 'sound/misc/splort.ogg', 50, TRUE, -1)
if(current_gauze)
QDEL_NULL(current_gauze)
seep_gauze(9999) // destroy any existing gauze if any exists
for(var/obj/item/organ/drop_organ in get_organs())
drop_organ.transfer_to_limb(src, owner)
for(var/obj/item/I in src)
@@ -377,12 +376,12 @@
*/
/obj/item/bodypart/proc/check_wounding(woundtype, damage, wound_bonus, bare_wound_bonus)
// note that these are fed into an exponent, so these are magnified
if(HAS_TRAIT(owner, TRAIT_EASYLIMBWOUND))
if(HAS_TRAIT(owner, TRAIT_EASILY_WOUNDED))
damage *= 1.5
else
damage = min(damage, WOUND_MAX_CONSIDERED_DAMAGE)
if(HAS_TRAIT(owner,TRAIT_HARDLIMBWOUND))
if(HAS_TRAIT(owner,TRAIT_HARDLY_WOUNDED))
damage *= 0.85
if(HAS_TRAIT(owner, TRAIT_EASYDISMEMBER))
@@ -570,7 +569,19 @@
var/total_damage = max(brute_dam + burn_dam, stamina_dam)
if(total_damage >= max_damage * disable_threshold) //Easy limb disable disables the limb at 40% health instead of 0%
// this block of checks is for limbs that can be disabled, but not through pure damage (AKA limbs that suffer wounds, human/monkey parts and such)
if(!disable_threshold)
if(total_damage < max_damage)
last_maxed = FALSE
else
if(!last_maxed && owner.stat < UNCONSCIOUS)
INVOKE_ASYNC(owner, /mob.proc/emote, "scream")
last_maxed = TRUE
set_disabled(FALSE) // we only care about the paralysis trait
return
// we're now dealing solely with limbs that can be disabled through pure damage, AKA robot parts
if(total_damage >= max_damage * disable_threshold)
if(!last_maxed)
if(owner.stat < UNCONSCIOUS)
INVOKE_ASYNC(owner, /mob.proc/emote, "scream")
@@ -578,7 +589,7 @@
set_disabled(TRUE)
return
if(bodypart_disabled && total_damage <= max_damage * 0.8) // reenabled at 80% now instead of 50% as of wounds update
if(bodypart_disabled && total_damage <= max_damage * 0.5) // reenable the limb at 50% health
last_maxed = FALSE
set_disabled(FALSE)
@@ -605,14 +616,6 @@
var/needs_update_disabled = FALSE //Only really relevant if there's an owner
if(.)
var/mob/living/carbon/old_owner = .
if(can_be_disabled)
if(HAS_TRAIT(old_owner, TRAIT_EASYLIMBWOUND))
disable_threshold = initial(disable_threshold)
needs_update_disabled = TRUE
UnregisterSignal(old_owner, list(
SIGNAL_REMOVETRAIT(TRAIT_EASYLIMBWOUND),
SIGNAL_ADDTRAIT(TRAIT_EASYLIMBWOUND),
))
if(initial(can_be_disabled))
if(HAS_TRAIT(old_owner, TRAIT_NOLIMBDISABLE))
if(!owner || !HAS_TRAIT(owner, TRAIT_NOLIMBDISABLE))
@@ -623,12 +626,6 @@
SIGNAL_ADDTRAIT(TRAIT_NOLIMBDISABLE),
))
if(owner)
if(can_be_disabled)
if(HAS_TRAIT(owner, TRAIT_EASYLIMBWOUND))
disable_threshold = 0.6
needs_update_disabled = TRUE
RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_EASYLIMBWOUND), .proc/on_owner_easylimbwound_trait_loss)
RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_EASYLIMBWOUND), .proc/on_owner_easylimbwound_trait_gain)
if(initial(can_be_disabled))
if(HAS_TRAIT(owner, TRAIT_NOLIMBDISABLE))
set_can_be_disabled(FALSE)
@@ -651,18 +648,12 @@
CRASH("set_can_be_disabled to TRUE with for limb whose owner has TRAIT_NOLIMBDISABLE")
RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_PARALYSIS), .proc/on_paralysis_trait_gain)
RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_PARALYSIS), .proc/on_paralysis_trait_loss)
if(HAS_TRAIT(owner, TRAIT_EASYLIMBWOUND))
disable_threshold = 0.6
RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_EASYLIMBWOUND), .proc/on_owner_easylimbwound_trait_loss)
RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_EASYLIMBWOUND), .proc/on_owner_easylimbwound_trait_gain)
update_disabled()
else if(.)
if(owner)
UnregisterSignal(owner, list(
SIGNAL_ADDTRAIT(TRAIT_PARALYSIS),
SIGNAL_REMOVETRAIT(TRAIT_PARALYSIS),
SIGNAL_REMOVETRAIT(TRAIT_EASYLIMBWOUND),
SIGNAL_ADDTRAIT(TRAIT_EASYLIMBWOUND),
))
set_disabled(FALSE)
@@ -692,23 +683,6 @@
SIGNAL_HANDLER
set_can_be_disabled(initial(can_be_disabled))
///Called when TRAIT_EASYLIMBWOUND is added to the owner.
/obj/item/bodypart/proc/on_owner_easylimbwound_trait_gain(mob/living/carbon/source)
SIGNAL_HANDLER
disable_threshold = 0.6
if(can_be_disabled)
update_disabled()
///Called when TRAIT_EASYLIMBWOUND is removed from the owner.
/obj/item/bodypart/proc/on_owner_easylimbwound_trait_loss(mob/living/carbon/source)
SIGNAL_HANDLER
disable_threshold = initial(disable_threshold)
if(can_be_disabled)
update_disabled()
//Updates an organ's brute/burn states for use by update_damage_overlays()
//Returns 1 if we need to update overlays. 0 otherwise.
/obj/item/bodypart/proc/update_bodypart_damage_state()
@@ -933,7 +907,7 @@
var/datum/wound/iter_wound = i
dam_mul *= iter_wound.damage_mulitplier_penalty
if(!LAZYLEN(wounds) && current_gauze && !replaced)
if(!LAZYLEN(wounds) && current_gauze && !replaced) // no more wounds = no need for the gauze anymore
owner.visible_message("<span class='notice'>\The [current_gauze] on [owner]'s [name] fall away.</span>", "<span class='notice'>The [current_gauze] on your [name] fall away.</span>")
QDEL_NULL(current_gauze)
@@ -983,9 +957,14 @@
/obj/item/bodypart/proc/apply_gauze(obj/item/stack/gauze)
if(!istype(gauze) || !gauze.absorption_capacity)
return
var/newly_gauzed = FALSE
if(!current_gauze)
newly_gauzed = TRUE
QDEL_NULL(current_gauze)
current_gauze = new gauze.type(src, 1)
gauze.use(1)
if(newly_gauzed)
SEND_SIGNAL(src, COMSIG_BODYPART_GAUZED, gauze)
/**
* seep_gauze() is for when a gauze wrapping absorbs blood or pus from wounds, lowering its absorption capacity.
@@ -999,6 +978,7 @@
if(!current_gauze)
return
current_gauze.absorption_capacity -= seep_amt
if(current_gauze.absorption_capacity < 0)
if(current_gauze.absorption_capacity <= 0)
owner.visible_message("<span class='danger'>\The [current_gauze] on [owner]'s [name] fall away in rags.</span>", "<span class='warning'>\The [current_gauze] on your [name] fall away in rags.</span>", vision_distance=COMBAT_MESSAGE_RANGE)
QDEL_NULL(current_gauze)
SEND_SIGNAL(src, COMSIG_BODYPART_GAUZE_DESTROYED)
@@ -20,6 +20,7 @@
flags_1 = CONDUCT_1
icon_state = "borg_l_arm"
status = BODYPART_ROBOTIC
disable_threshold = 1
brute_reduction = 5
burn_reduction = 4
@@ -42,6 +43,7 @@
flags_1 = CONDUCT_1
icon_state = "borg_r_arm"
status = BODYPART_ROBOTIC
disable_threshold = 1
brute_reduction = 5
burn_reduction = 4
@@ -64,6 +66,7 @@
flags_1 = CONDUCT_1
icon_state = "borg_l_leg"
status = BODYPART_ROBOTIC
disable_threshold = 1
brute_reduction = 5
burn_reduction = 4
@@ -86,6 +89,7 @@
flags_1 = CONDUCT_1
icon_state = "borg_r_leg"
status = BODYPART_ROBOTIC
disable_threshold = 1
brute_reduction = 5
burn_reduction = 4