mirror of
https://github.com/CHOMPstation/CHOMPstation.git
synced 2026-08-23 03:56:27 +01:00
Got various kinds of limb loss plus dislocation working.
This commit is contained in:
@@ -226,7 +226,7 @@
|
||||
icon_state = "hatchet"
|
||||
flags = CONDUCT
|
||||
force = 12.0
|
||||
w_class = 2.0
|
||||
w_class = 3.0
|
||||
throwforce = 15.0
|
||||
throw_speed = 4
|
||||
throw_range = 4
|
||||
|
||||
@@ -302,13 +302,16 @@
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/attack_joint(var/obj/item/W, var/mob/living/user, var/def_zone)
|
||||
|
||||
var/obj/item/organ/external/organ = get_organ(check_zone(def_zone))
|
||||
if(!organ || organ.is_dislocated() || organ.dislocated == -1) //Cannot dislocate this organ.
|
||||
return 0
|
||||
|
||||
user.visible_message("<span class='danger'>[src] has been [pick(W.attack_verb)] in \the [organ] with \the [W] by [user]!</span>")
|
||||
var/target_zone = def_zone? check_zone(def_zone) : get_zone_with_miss_chance(user.zone_sel.selecting, src)
|
||||
if(user == src) // Attacking yourself can't miss
|
||||
target_zone = user.zone_sel.selecting
|
||||
if(!target_zone)
|
||||
return null
|
||||
var/obj/item/organ/external/organ = get_organ(check_zone(target_zone))
|
||||
if(!organ || organ.is_dislocated() || organ.dislocated == -1)
|
||||
return null
|
||||
var/dislocation_str
|
||||
if(prob(W.force))
|
||||
user.visible_message("<span class='danger'>[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")] with a grisly crunch!</span>")
|
||||
dislocation_str = "[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")] with a grisly crunch!"
|
||||
organ.dislocate()
|
||||
return 1
|
||||
return dislocation_str
|
||||
|
||||
@@ -11,6 +11,8 @@ emp_act
|
||||
/mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone)
|
||||
|
||||
var/obj/item/organ/external/organ = get_organ(check_zone(def_zone))
|
||||
if(!organ)
|
||||
return
|
||||
|
||||
//Shields
|
||||
if(check_shields(P.damage, "the [P.name]"))
|
||||
@@ -85,16 +87,18 @@ emp_act
|
||||
if(isorgan(def_zone))
|
||||
return getarmor_organ(def_zone, type)
|
||||
var/obj/item/organ/external/affecting = get_organ(def_zone)
|
||||
return getarmor_organ(affecting, type)
|
||||
if(affecting)
|
||||
return getarmor_organ(affecting, type)
|
||||
//If a specific bodypart is targetted, check how that bodypart is protected and return the value.
|
||||
|
||||
//If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
|
||||
for(var/organ_name in organs_by_name)
|
||||
if (organ_name in organ_rel_size)
|
||||
var/obj/item/organ/external/organ = organs_by_name[organ_name]
|
||||
var/weight = organ_rel_size[organ_name]
|
||||
armorval += getarmor_organ(organ, type) * weight
|
||||
total += weight
|
||||
if(organ)
|
||||
var/weight = organ_rel_size[organ_name]
|
||||
armorval += getarmor_organ(organ, type) * weight
|
||||
total += weight
|
||||
return (armorval/max(total, 1))
|
||||
|
||||
//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ.
|
||||
@@ -113,13 +117,13 @@ emp_act
|
||||
|
||||
//this proc returns the armour value for a particular external organ.
|
||||
/mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type)
|
||||
if(!type) return 0
|
||||
if(!type || !def_zone) return 0
|
||||
var/protection = 0
|
||||
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
|
||||
for(var/gear in protective_gear)
|
||||
if(gear && istype(gear ,/obj/item/clothing))
|
||||
var/obj/item/clothing/C = gear
|
||||
if(C.body_parts_covered & def_zone.body_part)
|
||||
if(istype(C) && C.body_parts_covered & def_zone.body_part)
|
||||
protection += C.armor[type]
|
||||
return protection
|
||||
|
||||
@@ -186,7 +190,7 @@ emp_act
|
||||
target_zone = user.zone_sel.selecting
|
||||
if(!target_zone)
|
||||
visible_message("\red <B>[user] misses [src] with \the [I]!")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
var/obj/item/organ/external/affecting = get_organ(target_zone)
|
||||
|
||||
@@ -194,9 +198,11 @@ emp_act
|
||||
user << "<span class='danger'>They are missing that limb!</span>"
|
||||
return
|
||||
|
||||
var/effective_force = I.force
|
||||
if(user.a_intent == "disarm") effective_force = round(I.force/2)
|
||||
var/hit_area = affecting.name
|
||||
|
||||
if((user != src) && check_shields(I.force, "the [I.name]"))
|
||||
if((user != src) && check_shields(effective_force, "the [I.name]"))
|
||||
return 0
|
||||
|
||||
if(istype(I,/obj/item/weapon/card/emag))
|
||||
@@ -224,14 +230,14 @@ emp_act
|
||||
weapon_sharp = 0
|
||||
weapon_edge = 0
|
||||
|
||||
if(armor >= 2) return 0
|
||||
if(!I.force) return 0
|
||||
var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
|
||||
if(armor >= 2) return 0
|
||||
if(!effective_force) return 0
|
||||
var/Iforce = effective_force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
|
||||
|
||||
apply_damage(I.force, I.damtype, affecting, armor, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I)
|
||||
apply_damage(effective_force, I.damtype, affecting, armor, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I)
|
||||
|
||||
var/bloody = 0
|
||||
if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (I.force * 2)))
|
||||
if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (effective_force * 2)))
|
||||
I.add_blood(src) //Make the weapon bloody, not the person.
|
||||
// if(user.hand) user.update_inv_l_hand() //updates the attacker's overlay for the (now bloodied) weapon
|
||||
// else user.update_inv_r_hand() //removed because weapons don't have on-mob blood overlays
|
||||
@@ -246,36 +252,37 @@ emp_act
|
||||
H.bloody_body(src)
|
||||
H.bloody_hands(src)
|
||||
|
||||
switch(hit_area)
|
||||
if("head")//Harder to score a stun but if you do it lasts a bit longer
|
||||
if(prob(I.force))
|
||||
apply_effect(20, PARALYZE, armor)
|
||||
visible_message("\red <B>[src] has been knocked unconscious!</B>")
|
||||
if(bloody)//Apply blood
|
||||
if(wear_mask)
|
||||
wear_mask.add_blood(src)
|
||||
update_inv_wear_mask(0)
|
||||
if(head)
|
||||
head.add_blood(src)
|
||||
update_inv_head(0)
|
||||
if(glasses && prob(33))
|
||||
glasses.add_blood(src)
|
||||
update_inv_glasses(0)
|
||||
if(!stat)
|
||||
switch(hit_area)
|
||||
if("head")//Harder to score a stun but if you do it lasts a bit longer
|
||||
if(prob(effective_force))
|
||||
apply_effect(20, PARALYZE, armor)
|
||||
visible_message("\red <B>[src] has been knocked unconscious!</B>")
|
||||
if(bloody)//Apply blood
|
||||
if(wear_mask)
|
||||
wear_mask.add_blood(src)
|
||||
update_inv_wear_mask(0)
|
||||
if(head)
|
||||
head.add_blood(src)
|
||||
update_inv_head(0)
|
||||
if(glasses && prob(33))
|
||||
glasses.add_blood(src)
|
||||
update_inv_glasses(0)
|
||||
|
||||
if("chest")//Easier to score a stun but lasts less time
|
||||
if(prob((I.force + 10)))
|
||||
apply_effect(6, WEAKEN, armor)
|
||||
visible_message("\red <B>[src] has been knocked down!</B>")
|
||||
if("chest")//Easier to score a stun but lasts less time
|
||||
if(prob((effective_force + 10)))
|
||||
apply_effect(6, WEAKEN, armor)
|
||||
visible_message("\red <B>[src] has been knocked down!</B>")
|
||||
|
||||
if(bloody)
|
||||
bloody_body(src)
|
||||
if(bloody)
|
||||
bloody_body(src)
|
||||
|
||||
if(Iforce > 10 || Iforce >= 5 && prob(33))
|
||||
forcesay(hit_appends) //forcesay checks stat already
|
||||
|
||||
//Melee weapon embedded object code.
|
||||
if (I && I.damtype == BRUTE && !I.anchored && !I.is_robot_module())
|
||||
var/damage = I.force
|
||||
var/damage = effective_force
|
||||
if (armor)
|
||||
damage /= armor+1
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
if (!lying && world.time - l_move_time < 15)
|
||||
//Moving around with fractured ribs won't do you any good
|
||||
if (E.is_broken() && E.internal_organs && prob(15))
|
||||
if (E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15))
|
||||
var/obj/item/organ/I = pick(E.internal_organs)
|
||||
custom_pain("You feel broken bones moving in your [E.name]!", 1)
|
||||
I.take_damage(rand(3,5))
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
// Death vars.
|
||||
var/gibber_type = /obj/effect/gibspawner/human
|
||||
var/single_gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
var/remains_type = /obj/effect/decal/remains/xeno
|
||||
var/gibbed_anim = "gibbed-h"
|
||||
var/dusted_anim = "dust-h"
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
var/max_size = 0
|
||||
var/last_dam = -1
|
||||
var/icon/mob_icon
|
||||
var/icon/item_icon
|
||||
var/gendered_icon = 0
|
||||
var/limb_name
|
||||
var/disfigured = 1
|
||||
@@ -51,6 +50,7 @@
|
||||
|
||||
min_broken_damage = 30
|
||||
max_damage = 0
|
||||
dir = SOUTH
|
||||
|
||||
/obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
switch(stage)
|
||||
@@ -78,7 +78,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/organ/external/proc/is_dislocated()
|
||||
if(dislocated)
|
||||
if(dislocated > 0)
|
||||
return 1
|
||||
if(parent)
|
||||
return parent.is_dislocated()
|
||||
@@ -202,11 +202,18 @@
|
||||
src.update_damages()
|
||||
|
||||
//If limb took enough damage, try to cut or tear it off
|
||||
if(body_part != UPPER_TORSO) //as hilarious as it is, getting hit on the chest too much shouldn't effectively gib you.
|
||||
if(config.limbs_can_break && brute_dam >= max_damage * config.organ_health_multiplier)
|
||||
if( (edge && prob(5 * brute)) || (brute > 20 && prob(brute)) )
|
||||
droplimb()
|
||||
return
|
||||
if(!cannot_amputate && config.limbs_can_break && (brute_dam + burn_dam) >= (max_damage * config.organ_health_multiplier))
|
||||
if((sharp || edge) && used_weapon)
|
||||
if(istype(used_weapon,/obj/item))
|
||||
var/obj/item/W = used_weapon
|
||||
if(W.w_class >= 3) droplimb()
|
||||
return
|
||||
if(brute >= 23 && prob(brute)) // Wooden baseball bat in both hands == 23
|
||||
droplimb(0,2)
|
||||
return
|
||||
if(burn >= 20) // Most laser rifle shots.
|
||||
droplimb(0,1)
|
||||
return
|
||||
|
||||
owner.updatehealth()
|
||||
|
||||
@@ -592,16 +599,31 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
****************************************************/
|
||||
|
||||
//Handles dismemberment
|
||||
/obj/item/organ/external/proc/droplimb(var/clean)
|
||||
/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate)
|
||||
|
||||
if(cannot_amputate)
|
||||
if(cannot_amputate || !owner)
|
||||
return
|
||||
|
||||
if(!clean)
|
||||
owner.visible_message(
|
||||
"<span class='danger'>\The [owner]'s [src.name] flies off in an arc!</span>",\
|
||||
"<span class='moderate'><b>Your [src.name] goes flying off!</b></span>",\
|
||||
"<span class='danger'>You hear a terrible sound of ripping tendons and flesh.</span>")
|
||||
if(!disintegrate)
|
||||
disintegrate = 0
|
||||
|
||||
switch(disintegrate)
|
||||
if(0)
|
||||
if(!clean)
|
||||
owner.visible_message(
|
||||
"<span class='danger'>\The [owner]'s [src.name] flies off in an arc!</span>",\
|
||||
"<span class='moderate'><b>Your [src.name] goes flying off!</b></span>",\
|
||||
"<span class='danger'>You hear a terrible sound of ripping tendons and flesh.</span>")
|
||||
if(1)
|
||||
owner.visible_message(
|
||||
"<span class='danger'>\The [owner]'s [src.name] flashes away into ashes!</span>",\
|
||||
"<span class='moderate'><b>Your [src.name] flashes away into ashes!</b></span>",\
|
||||
"<span class='danger'>You hear the crackling sound of burning flesh.</span>")
|
||||
if(2)
|
||||
owner.visible_message(
|
||||
"<span class='danger'>\The [owner]'s [src.name] explodes in a shower of gore!</span>",\
|
||||
"<span class='moderate'><b>Your [src.name] explodes in a shower of gore!</b></span>",\
|
||||
"<span class='danger'>You hear the sickening splatter of gore.</span>")
|
||||
|
||||
src.removed()
|
||||
|
||||
@@ -613,18 +635,30 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
|
||||
update_health()
|
||||
owner.update_body()
|
||||
compile_icon()
|
||||
|
||||
add_blood(owner)
|
||||
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(rand(180))
|
||||
src.transform = M
|
||||
|
||||
if(!clean)
|
||||
// Throw limb around.
|
||||
if(src && istype(loc,/turf))
|
||||
throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
|
||||
switch(disintegrate)
|
||||
if(0)
|
||||
compile_icon()
|
||||
add_blood(owner)
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(rand(180))
|
||||
src.transform = M
|
||||
if(!clean)
|
||||
// Throw limb around.
|
||||
if(src && istype(loc,/turf))
|
||||
throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
|
||||
return
|
||||
if(1)
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(owner))
|
||||
if(2)
|
||||
var/obj/effect/decal/cleanable/blood/gibs/gore = new owner.species.single_gib_type(get_turf(owner))
|
||||
if(owner.species.flesh_color)
|
||||
gore.fleshcolor = owner.species.flesh_color
|
||||
if(owner.species.blood_color)
|
||||
gore.basecolor = owner.species.blood_color
|
||||
gore.update_icon()
|
||||
gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
|
||||
del(src)
|
||||
|
||||
/****************************************************
|
||||
HELPERS
|
||||
@@ -801,8 +835,6 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
status |= ORGAN_DESTROYED
|
||||
owner.bad_external_organs -= src
|
||||
|
||||
icon = item_icon
|
||||
|
||||
for(var/implant in implants) //todo: check if this can be left alone
|
||||
del(implant)
|
||||
|
||||
@@ -853,6 +885,7 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
dislocated = -1
|
||||
gendered_icon = 1
|
||||
cannot_amputate = 1
|
||||
parent_organ = null
|
||||
|
||||
/obj/item/organ/external/groin
|
||||
name = "lower body"
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
var/global/list/limb_icon_cache = list()
|
||||
|
||||
/obj/item/organ/external/set_dir()
|
||||
return
|
||||
|
||||
/obj/item/organ/proc/get_icon(var/image/supplied)
|
||||
var/key = "internal-[icon_state]"
|
||||
var/image/I
|
||||
@@ -56,7 +59,6 @@ var/global/list/limb_icon_cache = list()
|
||||
mob_icon.Blend(rgb(owner.r_skin, owner.g_skin, owner.b_skin), ICON_ADD)
|
||||
|
||||
dir = EAST
|
||||
item_icon = icon(mob_icon,icon_state,SOUTH)
|
||||
icon = mob_icon
|
||||
|
||||
return mob_icon
|
||||
|
||||
Reference in New Issue
Block a user