diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index 2a705f5ad14..4b6072a52ab 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -106,7 +106,11 @@ var/global/list/sparring_attack_cache = list() if(!affecting) return - user.visible_message("[user] [pick(attack_verb)] [target] in the [affecting.name]!") + user.visible_message(SPAN_WARNING("[user] [pick(attack_verb)] [target] in the [affecting.name]!")) + playsound(user.loc, attack_sound, 25, 1, -1) + +/datum/unarmed_attack/proc/show_attack_simple(var/mob/living/carbon/human/user, var/mob/living/target, var/zone) + user.visible_message(SPAN_WARNING("[user] [pick(attack_verb)] [target] in the [zone]!")) playsound(user.loc, attack_sound, 25, 1, -1) /datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target) diff --git a/code/modules/mob/living/simple_animal/friendly/carp.dm b/code/modules/mob/living/simple_animal/friendly/carp.dm index 9cd55e4b302..8979020bc5f 100644 --- a/code/modules/mob/living/simple_animal/friendly/carp.dm +++ b/code/modules/mob/living/simple_animal/friendly/carp.dm @@ -57,7 +57,7 @@ blood_overlay_icon = 'icons/mob/npc/blood_overlay.dmi' else blood_overlay_icon = initial(blood_overlay_icon) - handle_blood_overlay(TRUE) + handle_blood(TRUE) /mob/living/simple_animal/carp/fall_impact() src.visible_message(SPAN_NOTICE("\The [src] gently floats to a stop.")) diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index eae113d0fe7..77ff8dcf479 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -53,7 +53,7 @@ blood_overlay_icon = 'icons/mob/npc/blood_overlay.dmi' else blood_overlay_icon = initial(blood_overlay_icon) - handle_blood_overlay(TRUE) + handle_blood(TRUE) /mob/living/simple_animal/hostile/carp/Allow_Spacemove(var/check_drift = 0) return 1 //No drifting in space for space carp! //original comments do not steal diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index c4b3898a51c..de775d3603f 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -26,6 +26,7 @@ response_help = "pets" response_disarm = "gently pushes aside" response_harm = "pokes" + blood_amount = 150 stop_automated_movement_when_pulled = 0 maxHealth = 200 health = 200 @@ -54,6 +55,7 @@ icon_state = "greimorian_worker" icon_living = "greimorian_worker" icon_dead = "greimorian_worker_dead" + blood_amount = 50 maxHealth = 40 health = 40 melee_damage_lower = 5 @@ -70,6 +72,7 @@ icon_state = "greimorian_hunter" icon_living = "greimorian_hunter" icon_dead = "greimorian_hunter_dead" + blood_amount = 90 maxHealth = 120 health = 120 melee_damage_lower = 10 diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index 07d7bf9faea..c04511025b0 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -56,7 +56,7 @@ blood_overlay_icon = 'icons/mob/npc/blood_overlay.dmi' else blood_overlay_icon = initial(blood_overlay_icon) - handle_blood_overlay(TRUE) + handle_blood(TRUE) /mob/living/simple_animal/hostile/hivebot/get_blood_overlay_name() if(stance == HOSTILE_STANCE_IDLE) @@ -726,7 +726,7 @@ blood_overlay_icon = 'icons/mob/npc/blood_overlay.dmi' else blood_overlay_icon = initial(blood_overlay_icon) - handle_blood_overlay(TRUE) + handle_blood(TRUE) /mob/living/simple_animal/hostile/retaliate/hivebotharvester/proc/prospect() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index d7fb916edf8..85e081e1a75 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -26,6 +26,11 @@ var/blood_state = BLOOD_NONE var/image/blood_overlay + var/bleeding = FALSE + var/blood_amount = 50 // set a limit to the amount of blood it can bleed, otherwise it will keep bleeding forever and crunk the server + var/previous_bleed_timer = 0 // they only bleed for as many seconds as force damage was applied to them + var/blood_timer_mod = 1 // tweak to change the amount of seconds a mob will bleed + var/list/speak = list() var/speak_chance = 0 var/list/emote_hear = list() //Hearable emotes @@ -201,7 +206,7 @@ if(health > maxHealth) health = maxHealth - handle_blood_overlay() + handle_blood() handle_stunned() handle_weakened() handle_paralysed() @@ -329,10 +334,13 @@ if(purge) purge -= 1 -/mob/living/simple_animal/proc/handle_blood_overlay(var/force_reset = FALSE) +/mob/living/simple_animal/proc/handle_blood(var/force_reset = FALSE) if(!blood_overlay_icon) return + if(blood_amount <= 0 && stat != DEAD) + death() + var/current_blood_state = blood_state var/blood_mod = health / maxHealth if(blood_mod > 0.9) @@ -344,6 +352,18 @@ else blood_state = BLOOD_HEAVY + if(bleeding) + switch(blood_state) + if(BLOOD_LIGHT) + blood_splatter(src, null, FALSE, sourceless_color = blood_color) + blood_amount-- + if(BLOOD_MEDIUM) + blood_splatter(src, null, TRUE, sourceless_color = blood_color) + blood_amount -= 2 + if(BLOOD_HEAVY) + blood_splatter(src, null, TRUE, sourceless_color = blood_color) + blood_amount -= 3 + if(force_reset || current_blood_state != blood_state) if(blood_overlay) cut_overlay(blood_overlay) @@ -429,15 +449,6 @@ var/can_ghosts_hear = client ? GHOSTS_ALL_HEAR : ONLY_GHOSTS_IN_VIEW custom_emote(AUDIBLE_MESSAGE, act_desc, can_ghosts_hear) -/* -mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj) - if(!Proj || Proj.nodamage) - return - - adjustBruteLoss(Proj.damage) - return 0 -*/ - /mob/living/simple_animal/attack_hand(mob/living/carbon/human/M as mob) ..() switch(M.a_intent) @@ -480,9 +491,21 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj) return /mob/living/simple_animal/proc/unarmed_harm_attack(var/mob/living/carbon/human/user) + if(istype(user)) + var/datum/unarmed_attack/attack = user.get_unarmed_attack(src) + if(!attack) + simple_harm_attack(user) + return + attack.show_attack_simple(user, src, pick(organ_names)) + apply_damage(attack.get_unarmed_damage(user), attack.damage_type) + user.do_attack_animation(src, FIST_ATTACK_ANIMATION) + return + simple_harm_attack(user) + +/mob/living/simple_animal/proc/simple_harm_attack(var/mob/living/user) apply_damage(harm_intent_damage, BRUTE, used_weapon = "Attack by [user.name]") user.visible_message(SPAN_WARNING("\The [user] [response_harm] \the [src]!"), SPAN_WARNING("You [response_harm] \the [src]!")) - user.do_attack_animation(src) + user.do_attack_animation(src, FIST_ATTACK_ANIMATION) poke(TRUE) /mob/living/simple_animal/attackby(obj/item/O, mob/user) @@ -546,16 +569,32 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj) poke() visible_message(SPAN_DANGER("\The [src] has been attacked with \the [O] by \the [user].")) - user.do_attack_animation(src) + if(O.hitsound) + playsound(loc, O.hitsound, O.get_clamped_volume(), 1, -1) + user.do_attack_animation(src, O) return TRUE /mob/living/simple_animal/apply_damage(damage, damagetype, def_zone, blocked, used_weapon, damage_flags, armor_pen, silent = FALSE) . = ..() - handle_blood_overlay() + handle_bleeding_timer(damage) + handle_blood() + +/mob/living/simple_animal/proc/handle_bleeding_timer(var/damage_inflicted) + if(!blood_overlay_icon) // no blood, don't bother + return + if(damage_inflicted <= 0) // just to be safe + return + if(!bleeding || previous_bleed_timer <= damage_inflicted) + bleeding = TRUE + previous_bleed_timer = damage_inflicted + addtimer(CALLBACK(src, .proc/stop_bleeding), (damage_inflicted SECONDS) * blood_timer_mod, TIMER_UNIQUE | TIMER_OVERRIDE) + +/mob/living/simple_animal/proc/stop_bleeding() + bleeding = FALSE /mob/living/simple_animal/heal_organ_damage(var/brute, var/burn) . = ..() - handle_blood_overlay() + handle_blood() /mob/living/simple_animal/movement_delay() var/tally = 0 //Incase I need to add stuff other than "speed" later diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 85ac869ff16..7f9811a3910 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -217,7 +217,7 @@ proc/blood_incompatible(donor,receiver,donor_species,receiver_species) data["dose_chem"] = chem_doses.Copy() return data -proc/blood_splatter(var/target, var/source, var/large, var/spray_dir) +proc/blood_splatter(var/target, var/source, var/large, var/spray_dir, var/sourceless_color) var/obj/effect/decal/cleanable/blood/splatter var/decal_type = /obj/effect/decal/cleanable/blood/splatter @@ -255,6 +255,11 @@ proc/blood_splatter(var/target, var/source, var/large, var/spray_dir) else if(isatom(source)) var/atom/donor = source blood_data = REAGENT_DATA(donor.reagents, /decl/reagent/blood) + else if(!source) + if(sourceless_color) + splatter.basecolor = sourceless_color + splatter.update_icon() + return splatter if(!islist(blood_data)) return splatter diff --git a/html/changelogs/geeves-satisfying_combat.yml b/html/changelogs/geeves-satisfying_combat.yml new file mode 100644 index 00000000000..9709d78e0da --- /dev/null +++ b/html/changelogs/geeves-satisfying_combat.yml @@ -0,0 +1,8 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Simple mobs now bleed. They also bleed out and die." + - rscadd: "Attacking a simple mob while unarmed will now use your default attack with a hitsound." + - rscadd: "Attacking a simple mob with an item will now properly show the attack animation and hitsound."