Projectile impact effects, sounds and blood splatters. (#8444)

Based.
This commit is contained in:
Matt Atlas
2020-03-20 21:28:28 +01:00
committed by GitHub
parent f6aebb669a
commit 9ab1f2cfb1
29 changed files with 144 additions and 82 deletions

View File

@@ -1953,3 +1953,23 @@
for(var/obj/item/organ/external/E in organs)
E.fracture()
return
/mob/living/carbon/human/get_bullet_impact_effect_type(var/def_zone)
var/obj/item/organ/external/E = get_organ(def_zone)
if(!E || E.is_stump())
return BULLET_IMPACT_NONE
if(BP_IS_ROBOTIC(E))
return BULLET_IMPACT_METAL
return BULLET_IMPACT_MEAT
/mob/living/carbon/human/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone, var/damage)
..()
switch(get_bullet_impact_effect_type(def_zone))
if(BULLET_IMPACT_MEAT)
if(P.damtype == BRUTE)
var/hit_dir = get_dir(P.starting, src)
var/obj/effect/decal/cleanable/blood/B = blood_splatter(get_step(src, hit_dir), src, 1, hit_dir)
B.icon_state = pick("dir_splatter_1","dir_splatter_2")
var/scale = min(1, round(P.damage / 50, 0.2))
var/matrix/M = new()
B.transform = M.Scale(scale)

View File

@@ -399,8 +399,8 @@ This function restores all organs.
/mob/living/carbon/human/apply_damage(var/damage = 0, var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/edge = 0, var/obj/used_weapon = null, var/damage_flags)
//visible_message("Hit debug. [damage] | [damagetype] | [def_zone] | [blocked] | [sharp] | [used_weapon]")
if (src.invisibility == INVISIBILITY_LEVEL_TWO && back && (istype(back, /obj/item/rig)))
if (damage > 0)
if (invisibility == INVISIBILITY_LEVEL_TWO && back && (istype(back, /obj/item/rig)))
if(damage > 0)
to_chat(src, "<span class='danger'>You are now visible.</span>")
src.invisibility = 0

View File

@@ -9,12 +9,14 @@
*/
/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/used_weapon = null, var/sharp = 0, var/edge = 0, var/damage_flags)
if(!damage || (blocked >= 100)) return 0
if(!damage || (blocked >= 100))
return 0
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage * BLOCKED_MULT(blocked))
if(BURN)
if(COLD_RESISTANCE in mutations) damage = 0
if(COLD_RESISTANCE in mutations)
damage = 0
adjustFireLoss(damage * BLOCKED_MULT(blocked))
if(TOX)
adjustToxLoss(damage * BLOCKED_MULT(blocked))

View File

@@ -91,15 +91,26 @@
var/absorb = run_armor_check(def_zone, P.check_armour, P.armor_penetration)
var/proj_sharp = is_sharp(P)
var/proj_edge = has_edge(P)
var/damaged
if ((proj_sharp || proj_edge) && prob(absorb))
proj_sharp = 0
proj_edge = 0
if(!P.nodamage)
apply_damage(P.damage, P.damage_type, def_zone, absorb, 0, P, sharp=proj_sharp, edge=proj_edge, damage_flags = P.damage_flags, used_weapon = "\a [P.name]")
damaged = apply_damage(P.damage, P.damage_type, def_zone, absorb, 0, P, sharp=proj_sharp, edge=proj_edge, damage_flags = P.damage_flags, used_weapon = "\a [P.name]")
bullet_impact_visuals(P, def_zone, damaged)
P.on_hit(src, absorb, def_zone)
return absorb
//For visuals, blood splatters and so on.
/mob/living/proc/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone, var/damage)
var/list/impact_sounds = LAZYACCESS(P.impact_sounds, get_bullet_impact_effect_type(def_zone))
if(length(impact_sounds))
playsound(src, pick(impact_sounds), 75)
/mob/living/get_bullet_impact_effect_type(var/def_zone)
return BULLET_IMPACT_MEAT
//Handles the effects of "stun" weapons
/mob/living/proc/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon=null)
flash_pain()

View File

@@ -387,4 +387,7 @@
break
if(!underdoor)
spawn(3)//A slight delay to let us finish walking out from under the door
layer = initial(layer)
layer = initial(layer)
/mob/living/silicon/get_bullet_impact_effect_type(var/def_zone)
return BULLET_IMPACT_METAL

View File

@@ -29,6 +29,7 @@
supernatural = TRUE
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_ONE
blood_type = "#000000"
tameable = FALSE
@@ -65,6 +66,9 @@
ghostize()
qdel(src)
/mob/living/simple_animal/construct/get_bullet_impact_effect_type(var/def_zone)
return BULLET_IMPACT_METAL
/mob/living/simple_animal/construct/attack_generic(var/mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(istype(user, /mob/living/simple_animal/construct))

View File

@@ -13,6 +13,7 @@
desc = "A primitive in design, hovering robot, with some menacing looking blades jutting out from it. It bears no manufacturer markings of any kind."
icon = 'icons/mob/npc/hivebot.dmi'
icon_state = "hivebot"
blood_type = "#000000"
health = 15
maxHealth = 15
harm_intent_damage = 3
@@ -40,6 +41,9 @@
attack_emote = "focuses on"
var/mob/living/simple_animal/hostile/hivebotbeacon/linked_parent = null
/mob/living/simple_animal/hostile/hivebot/get_bullet_impact_effect_type(var/def_zone)
return BULLET_IMPACT_METAL
/mob/living/simple_animal/hostile/hivebot/guardian
health = 80
maxHealth = 45

View File

@@ -13,6 +13,7 @@
var/icon_living = ""
var/icon_dead = ""
var/icon_gib = null //We only try to show a gibbing animation if this exists.
var/blood_type = "#A10808" //Blood colour for impact visuals.
var/list/speak = list()
var/speak_chance = 0
@@ -617,74 +618,6 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
user.visible_message("<span class='danger'>[user] butchers \the [src] messily!</span>")
gib()
/*
//Code to handle finding and nomming nearby food items
/mob/living/simple_animal/proc/handle_foodscanning()
if (client || !hunger_enabled || !autoseek_food)
return 0
//Feeding, chasing food, FOOOOODDDD
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan >= scan_interval)
turns_since_scan = 0
if((movement_target) && (!(isturf(movement_target.loc) || ishuman(movement_target.loc))) || (foodtarget && !can_eat() ))
movement_target = null
foodtarget = 0
stop_automated_movement = 0
if( !movement_target || !(movement_target.loc in oview(src, 7)) )
walk_to(src,0)
movement_target = null
foodtarget = 0
stop_automated_movement = 0
if (can_eat())
for(var/obj/item/reagent_containers/food/snacks/S in oview(src,7))
if(isturf(S.loc) || ishuman(S.loc))
movement_target = S
foodtarget = 1
break
//Look for food in people's hand
if (!movement_target && beg_for_food)
var/obj/item/reagent_containers/food/snacks/F = null
for(var/mob/living/carbon/human/H in oview(src,scan_range))
if(istype(H.l_hand, /obj/item/reagent_containers/food/snacks))
F = H.l_hand
if(istype(H.r_hand, /obj/item/reagent_containers/food/snacks))
F = H.r_hand
if (F)
movement_target = F
foodtarget = 1
break
if(movement_target)
scan_interval = min_scan_interval
stop_automated_movement = 1
if (isturf(movement_target.loc))
walk_to(src, movement_target, 0, DS2TICKS(seek_move_delay)) //Stand ontop of food
else
walk_to(src, get_turf(movement_target), 1, DS2TICKS(seek_move_delay)) //Don't stand ontop of people
if (movement_target)
set_dir(get_dir(src, movement_target))
if(isturf(movement_target.loc) && Adjacent(get_turf(movement_target), src))
UnarmedAttack(movement_target)
if (get_turf(movement_target) == loc)
set_dir(pick(NORTH, SOUTH, EAST, WEST, NORTH, NORTH))//Face a random direction when eating, but mostly upwards
else if(ishuman(movement_target.loc) && Adjacent(get_turf(movement_target.loc)) && (prob(10) || nutrition / max_nutrition <= 0.25))
if(nutrition / max_nutrition <= 0.25)
steal_food(movement_target, movement_target.loc)
else
beg(movement_target, movement_target.loc)
else
scan_interval = max(min_scan_interval, min(scan_interval+1, max_scan_interval))//If nothing is happening, ian's scanning frequency slows down to save processing
*/
//For picking up small animals
/mob/living/simple_animal/MouseDrop(atom/over_object)
if (holder_type)//we need a defined holder type in order for picking up to work
@@ -787,4 +720,18 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
adjustFireLoss(rand(3, 5))
/mob/living/simple_animal/get_digestion_product()
return "nutriment"
return "nutriment"
/mob/living/simple_animal/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone, var/damage)
..()
switch(get_bullet_impact_effect_type(def_zone))
if(BULLET_IMPACT_MEAT)
if(P.damtype == BRUTE)
var/hit_dir = get_dir(P.starting, src)
var/obj/effect/decal/cleanable/blood/B = blood_splatter(get_step(src, hit_dir), src, 1, hit_dir)
B.icon_state = pick("dir_splatter_1","dir_splatter_2")
B.basecolor = blood_type
var/scale = min(1, round(mob_size / MOB_TINY, 0.1))
var/matrix/M = new()
B.transform = M.Scale(scale)
B.update_icon()