From 3daf3b06435cb54bb0f74b8ea679820d6c987acd Mon Sep 17 00:00:00 2001 From: Fikou <23585223+Fikou@users.noreply.github.com> Date: Tue, 27 Dec 2022 23:29:14 +0100 Subject: [PATCH] fixes silly stuff about basic mobs (#72260) ## About The Pull Request makes basic mob attacks call their default attacks when done by a player, rather than calling simple mob attacks makes basic mob attacks call simple animal attacks by default, until we remove simplemobs moves some stuff off to procs and flags, fixes some stuff ## Why It's Good For The Game im moving holoparasites to basic mobs and i literally cant give them secondary click attacks ## Changelog :cl: fix: fixes moonicorns not applying pax /:cl: --- code/__DEFINES/basic_mobs.dm | 2 + code/_onclick/other_mobs.dm | 10 +- code/datums/ai/dog/dog_behaviors.dm | 4 +- code/game/objects/items.dm | 5 - code/game/objects/obj_defense.dm | 14 --- code/modules/mob/living/basic/basic.dm | 35 +++---- .../modules/mob/living/basic/basic_defense.dm | 98 +++++++++---------- .../mob/living/carbon/human/human_defense.dm | 17 ---- code/modules/mob/living/living_defense.dm | 21 ---- .../living/simple_animal/animal_defense.dm | 6 -- 10 files changed, 77 insertions(+), 135 deletions(-) diff --git a/code/__DEFINES/basic_mobs.dm b/code/__DEFINES/basic_mobs.dm index a12b4e4c2ed..c1a713aa858 100644 --- a/code/__DEFINES/basic_mobs.dm +++ b/code/__DEFINES/basic_mobs.dm @@ -2,4 +2,6 @@ ///Basic mob flags #define DEL_ON_DEATH (1<<0) +#define FLIP_ON_DEATH (1<<1) +#define UNDENSIFY_ON_DEATH (1<<2) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 4b92fca5c50..b8f71595308 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -157,10 +157,16 @@ /atom/proc/attack_animal_secondary(mob/user, list/modifiers) return SECONDARY_ATTACK_CALL_NORMAL -///Apparently this is only used by AI datums for basic mobs. A player controlling a basic mob will call attack_animal() when clicking another atom. +///When a basic mob attacks something, either by AI or user. /atom/proc/attack_basic_mob(mob/user, list/modifiers) SHOULD_CALL_PARENT(TRUE) SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_BASIC_MOB, user) + return handle_basic_attack(user, modifiers) //return value of attack animal, this is how much damage was dealt to the attacked thing + +///This exists so stuff can override the default call of attack_animal for attack_basic_mob +///Remove this when simple animals are removed and everything can be handled on attack basic mob. +/atom/proc/handle_basic_attack(user, modifiers) + return attack_animal(user, modifiers) ///Attacked by monkey. It doesn't need its own *_secondary proc as it just uses attack_hand_secondary instead. /atom/proc/attack_paw(mob/user, list/modifiers) @@ -180,7 +186,7 @@ return target.attack_alien_secondary(src, modifiers) /atom/proc/attack_alien(mob/living/carbon/alien/user, list/modifiers) - attack_paw(user, modifiers) + return attack_paw(user, modifiers) /** * Called when an alien right clicks an atom. diff --git a/code/datums/ai/dog/dog_behaviors.dm b/code/datums/ai/dog/dog_behaviors.dm index 8c16ca5e52f..2424299510a 100644 --- a/code/datums/ai/dog/dog_behaviors.dm +++ b/code/datums/ai/dog/dog_behaviors.dm @@ -141,7 +141,7 @@ controller.blackboard[BB_DOG_PLAYING_DEAD] = TRUE simple_pawn.emote("deathgasp", intentional=FALSE) simple_pawn.icon_state = simple_pawn.icon_dead - if(simple_pawn.flip_on_death) + if(simple_pawn.basic_mob_flags & FLIP_ON_DEATH) simple_pawn.transform = simple_pawn.transform.Turn(180) simple_pawn.set_density(FALSE) @@ -156,7 +156,7 @@ controller.blackboard[BB_DOG_PLAYING_DEAD] = FALSE simple_pawn.visible_message(span_notice("[simple_pawn] springs to [simple_pawn.p_their()] feet, panting excitedly!")) simple_pawn.icon_state = simple_pawn.icon_living - if(simple_pawn.flip_on_death) + if(simple_pawn.basic_mob_flags & FLIP_ON_DEATH) simple_pawn.transform = simple_pawn.transform.Turn(180) simple_pawn.set_density(initial(simple_pawn.density)) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 824e2eac4f7..8c297518f7e 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -908,11 +908,6 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e return ..() return 0 -/obj/item/attack_basic_mob(mob/living/basic/user, list/modifiers) - if (obj_flags & CAN_BE_HIT) - return ..() - return 0 - /obj/item/burn() if(!QDELETED(src)) var/turf/T = get_turf(src) diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 98f74e9b80b..d2441d33f86 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -53,20 +53,6 @@ if(attack_generic(user, 60, BRUTE, MELEE, 0)) playsound(src.loc, 'sound/weapons/slash.ogg', 100, TRUE) -/obj/attack_basic_mob(mob/living/basic/user, list/modifiers) - . = ..() - if(!user.melee_damage_upper && !user.obj_damage) //No damage - user.emote("custom", message = "[user.friendly_verb_continuous] [src].") - return FALSE - else - var/turf/current_turf = get_turf(src) //we want to save the turf to play the sound there, cause being destroyed deletes us! - if(user.obj_damage) - . = attack_generic(user, user.obj_damage, user.melee_damage_type, MELEE, TRUE, user.armour_penetration) - else - . = attack_generic(user, rand(user.melee_damage_lower,user.melee_damage_upper), user.melee_damage_type, MELEE,TRUE, user.armour_penetration) - if(.) - playsound(current_turf, 'sound/effects/meteorimpact.ogg', 100, TRUE) - /obj/attack_animal(mob/living/simple_animal/user, list/modifiers) . = ..() if(!user.melee_damage_upper && !user.obj_damage) diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index f20e5cf3b4b..40ec3beba53 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -38,8 +38,10 @@ ///What kind of objects this mob can smash. var/environment_smash = ENVIRONMENT_SMASH_NONE - /// 1 for full damage , 0 for none , -1 for 1:1 heal from that source. + /// 1 for full damage, 0 for none, -1 for 1:1 heal from that source. var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) + ///Minimum force required to deal any damage. + var/force_threshold = 0 ///Verbs used for speaking e.g. "Says" or "Chitters". This can be elementized var/list/speak_emote = list() @@ -75,10 +77,6 @@ var/icon_dead = "" ///We only try to show a gibbing animation if this exists. var/icon_gib = null - ///Flip the sprite upside down on death. Mostly here for things lacking custom dead sprites. - var/flip_on_death = FALSE - ///Removes density upon death, restores the original state if alive. - var/become_passable_on_death = TRUE ///If the mob can be spawned with a gold slime core. HOSTILE_SPAWN are spawned with plasma, FRIENDLY_SPAWN are spawned with blood. var/gold_core_spawnable = NO_SPAWN @@ -139,32 +137,35 @@ . = ..() if(basic_mob_flags & DEL_ON_DEATH) qdel(src) - else - health = 0 - icon_state = icon_dead - if(flip_on_death) - transform = transform.Turn(180) - if (become_passable_on_death) - set_density(FALSE) + return + health = 0 + icon_state = icon_dead + if(basic_mob_flags & FLIP_ON_DEATH) + transform = transform.Turn(180) + if(basic_mob_flags & UNDENSIFY_ON_DEATH) + set_density(FALSE) /mob/living/basic/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE) . = ..() if (!.) return icon_state = icon_living - if (flip_on_death) + if(basic_mob_flags & FLIP_ON_DEATH) transform = transform.Turn(180) - if (become_passable_on_death) + if(basic_mob_flags & UNDENSIFY_ON_DEATH) set_density(initial(density)) -/mob/living/basic/proc/melee_attack(atom/target) - src.face_atom(target) +/mob/living/basic/proc/melee_attack(atom/target, list/modifiers) + face_atom(target) if(SEND_SIGNAL(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, target) & COMPONENT_HOSTILE_NO_ATTACK) return FALSE //but more importantly return before attack_animal called - var/result = target.attack_basic_mob(src) + var/result = target.attack_basic_mob(src, modifiers) SEND_SIGNAL(src, COMSIG_HOSTILE_POST_ATTACKINGTARGET, target, result) return result +/mob/living/basic/resolve_unarmed_attack(atom/attack_target, list/modifiers) + melee_attack(attack_target, modifiers) + /mob/living/basic/vv_edit_var(vname, vval) . = ..() if(vname == NAMEOF(src, speed)) diff --git a/code/modules/mob/living/basic/basic_defense.dm b/code/modules/mob/living/basic/basic_defense.dm index 149fc1c6bec..d22ae01c2d4 100644 --- a/code/modules/mob/living/basic/basic_defense.dm +++ b/code/modules/mob/living/basic/basic_defense.dm @@ -70,36 +70,31 @@ /mob/living/basic/attack_alien(mob/living/carbon/alien/adult/user, list/modifiers) - if(..()) //if harm or disarm intent. - if(LAZYACCESS(modifiers, RIGHT_CLICK)) - playsound(loc, 'sound/weapons/pierce.ogg', 25, TRUE, -1) - visible_message(span_danger("[user] [response_disarm_continuous] [name]!"), \ - span_userdanger("[user] [response_disarm_continuous] you!"), null, COMBAT_MESSAGE_RANGE, user) - to_chat(user, span_danger("You [response_disarm_simple] [name]!")) - log_combat(user, src, "disarmed") - else - var/damage = rand(15, 30) - visible_message(span_danger("[user] slashes at [src]!"), \ - span_userdanger("You're slashed at by [user]!"), null, COMBAT_MESSAGE_RANGE, user) - to_chat(user, span_danger("You slash at [src]!")) - playsound(loc, 'sound/weapons/slice.ogg', 25, TRUE, -1) - attack_threshold_check(damage) - log_combat(user, src, "attacked") - return 1 + . = ..() + if(!.) + return + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + playsound(loc, 'sound/weapons/pierce.ogg', 25, TRUE, -1) + visible_message(span_danger("[user] [response_disarm_continuous] [name]!"), \ + span_userdanger("[user] [response_disarm_continuous] you!"), null, COMBAT_MESSAGE_RANGE, user) + to_chat(user, span_danger("You [response_disarm_simple] [name]!")) + log_combat(user, src, "disarmed") + return + var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) + visible_message(span_danger("[user] slashes at [src]!"), \ + span_userdanger("You're slashed at by [user]!"), null, COMBAT_MESSAGE_RANGE, user) + to_chat(user, span_danger("You slash at [src]!")) + playsound(loc, 'sound/weapons/slice.ogg', 25, TRUE, -1) + attack_threshold_check(damage) + log_combat(user, src, "attacked") -/mob/living/basic/attack_larva(mob/living/carbon/alien/larva/L, list/modifiers) +/mob/living/basic/attack_larva(mob/living/carbon/alien/larva/attacking_larva, list/modifiers) . = ..() if(. && stat != DEAD) //successful larva bite - var/damage = rand(5, 10) + var/damage = rand(attacking_larva.melee_damage_lower, attacking_larva.melee_damage_upper) . = attack_threshold_check(damage) if(.) - L.amount_grown = min(L.amount_grown + damage, L.max_grown) - -/mob/living/basic/attack_basic_mob(mob/living/basic/user, list/modifiers) - . = ..() - if(.) - var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) - return attack_threshold_check(damage, user.melee_damage_type) + attacking_larva.amount_grown = min(attacking_larva.amount_grown + damage, attacking_larva.max_grown) /mob/living/basic/attack_animal(mob/living/simple_animal/user, list/modifiers) . = ..() @@ -114,13 +109,13 @@ damage = rand(20, 35) return attack_threshold_check(damage) -/mob/living/basic/attack_drone(mob/living/simple_animal/drone/M) - if(M.combat_mode) //No kicking dogs even as a rogue drone. Use a weapon. +/mob/living/basic/attack_drone(mob/living/simple_animal/drone/attacking_drone) + if(attacking_drone.combat_mode) //No kicking dogs even as a rogue drone. Use a weapon. return return ..() -/mob/living/basic/attack_drone_secondary(mob/living/simple_animal/drone/M) - if(M.combat_mode) +/mob/living/basic/attack_drone_secondary(mob/living/simple_animal/drone/attacking_drone) + if(attacking_drone.combat_mode) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN return ..() @@ -130,23 +125,23 @@ temp_damage = 0 else temp_damage *= damage_coeff[damagetype] - - if(actuallydamage) - apply_damage(damage, damagetype, null, getarmor(null, armorcheck)) - return TRUE + if(temp_damage >= 0 && temp_damage <= force_threshold) + visible_message(span_warning("[src] looks unharmed!")) + return FALSE + else + if(actuallydamage) + apply_damage(damage, damagetype, blocked = getarmor(null, armorcheck)) + return TRUE /mob/living/basic/check_projectile_armor(def_zone, obj/projectile/impacting_projectile, is_silent) return 0 /mob/living/basic/ex_act(severity, target, origin) - if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) - return FALSE - . = ..() - if(QDELETED(src)) + if(!. || QDELETED(src)) return var/bomb_armor = getarmor(null, BOMB) - switch (severity) + switch(severity) if (EXPLODE_DEVASTATE) if(prob(bomb_armor)) apply_damage(500, damagetype = BRUTE) @@ -166,13 +161,12 @@ bloss = bloss / 1.5 apply_damage(bloss, damagetype = BRUTE) -/mob/living/basic/blob_act(obj/structure/blob/B) +/mob/living/basic/blob_act(obj/structure/blob/attacking_blob) apply_damage(20, damagetype = BRUTE) - return -/mob/living/basic/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect) +/mob/living/basic/do_attack_animation(atom/attacked_atom, visual_effect_icon, used_item, no_effect) if(!no_effect && !visual_effect_icon && melee_damage_upper) - if(attack_vis_effect && !iswallturf(A)) // override the standard visual effect. + if(attack_vis_effect && !iswallturf(attacked_atom)) // override the standard visual effect. visual_effect_icon = attack_vis_effect else if(melee_damage_upper < 10) visual_effect_icon = ATTACK_EFFECT_PUNCH @@ -180,7 +174,6 @@ visual_effect_icon = ATTACK_EFFECT_SMASH ..() - /mob/living/basic/update_stat() if(status_flags & GODMODE) return @@ -194,11 +187,14 @@ /mob/living/basic/emp_act(severity) . = ..() if(mob_biotypes & MOB_ROBOTIC) - switch (severity) - if (EMP_LIGHT) - visible_message(span_danger("[src] shakes violently, its parts coming loose!")) - apply_damage(maxHealth * 0.6) - Shake(5, 5, 1 SECONDS) - if (EMP_HEAVY) - visible_message(span_danger("[src] suddenly bursts apart!")) - apply_damage(maxHealth) + emp_reaction(severity) + +/mob/living/basic/proc/emp_reaction(severity) + switch(severity) + if(EMP_LIGHT) + visible_message(span_danger("[src] shakes violently, its parts coming loose!")) + apply_damage(maxHealth * 0.6) + Shake(5, 5, 1 SECONDS) + if(EMP_HEAVY) + visible_message(span_danger("[src] suddenly bursts apart!")) + apply_damage(maxHealth) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 62582cd27d8..e9b6e47b726 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -330,23 +330,6 @@ var/armor_block = run_armor_check(affecting, MELEE) apply_damage(damage, BRUTE, affecting, armor_block) - -/mob/living/carbon/human/attack_basic_mob(mob/living/basic/user, list/modifiers) - . = ..() - if(!.) - return - var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) - if(check_shields(user, damage, "the [user.name]", MELEE_ATTACK, user.armour_penetration)) - return FALSE - var/dam_zone = dismembering_strike(user, pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) - if(!dam_zone) //Dismemberment successful - return TRUE - var/obj/item/bodypart/affecting = get_bodypart(get_random_valid_zone(dam_zone)) - var/armor = run_armor_check(affecting, MELEE, armour_penetration = user.armour_penetration) - var/attack_direction = get_dir(user, src) - apply_damage(damage, user.melee_damage_type, affecting, armor, wound_bonus = user.wound_bonus, bare_wound_bonus = user.bare_wound_bonus, sharpness = user.sharpness, attack_direction = attack_direction) - - /mob/living/carbon/human/attack_animal(mob/living/simple_animal/user, list/modifiers) . = ..() if(!.) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index fdb3b054377..1db95629630 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -230,27 +230,6 @@ to_chat(M, span_danger("You glomp [src]!")) return TRUE -/mob/living/attack_basic_mob(mob/living/basic/user, list/modifiers) - . = ..() - if(user.melee_damage_upper == 0) - if(user != src) - visible_message(span_notice("\The [user] [user.friendly_verb_continuous] [src]!"), \ - span_notice("\The [user] [user.friendly_verb_continuous] you!"), null, COMBAT_MESSAGE_RANGE, user) - to_chat(user, span_notice("You [user.friendly_verb_simple] [src]!")) - return FALSE - if(HAS_TRAIT(user, TRAIT_PACIFISM)) - to_chat(user, span_warning("You don't want to hurt anyone!")) - return FALSE - - if(user.attack_sound) - playsound(loc, user.attack_sound, 50, TRUE, TRUE) - user.do_attack_animation(src) - visible_message(span_danger("\The [user] [user.attack_verb_continuous] [src]!"), \ - span_userdanger("\The [user] [user.attack_verb_continuous] you!"), null, COMBAT_MESSAGE_RANGE, user) - to_chat(user, span_danger("You [user.attack_verb_simple] [src]!")) - log_combat(user, src, "attacked") - return TRUE - /mob/living/attack_animal(mob/living/simple_animal/user, list/modifiers) . = ..() user.face_atom(src) diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 16b6d02bc89..c51b2c644b9 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -92,12 +92,6 @@ if(.) L.amount_grown = min(L.amount_grown + damage, L.max_grown) -/mob/living/simple_animal/attack_basic_mob(mob/living/basic/user, list/modifiers) - . = ..() - if(.) - var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) - return attack_threshold_check(damage, user.melee_damage_type) - /mob/living/simple_animal/attack_animal(mob/living/simple_animal/user, list/modifiers) . = ..() if(.)