Files
Bubberstation/code/datums/elements/relay_attackers.dm
SkyratBot 9e1f3798fa [MIRROR] Ancient and recent mecha bug fixes (#28522)
* Ancient and recent mecha bug fixes (#84171)

## About The Pull Request

Mecha guns actually utilize random spread while firing if ``randomspread
= TRUE``. Currently every weapon that isn't the shotguns are always
pinpoint even if they would have variance.

Makes bumpsmash and melee attacks in a mech use the same cooldown. The
actual speed between bumpsmash melees are the same as before (once every
0.3 seconds) and click melee is the same as well (once every second).
However, if you do one or the other, it will put you on cooldown for
both. The reason for this is that they're literally just calling the
same proc but not respecting each others cooldowns. So we've
consolidated this into one cooldown with varying cooldown timers. I
don't even think this is the most elegant solution, but I'm not going to
make any radical changes of the structure of the code. Fuck that.

**Edit** I forgot to mention this but you have to be in combat mode to
bumpsmash as a consequence of the above changes. You're fucking welcome.

Separates out mecha_melee_attack proc on the ``/obj/`` level to instead
only ``/obj/structure`` and ``/obj/machinery``, which is the only things
we should be attacking in the /obj/ list. I don't even want to know what
mechs have been able to punch while this wasn't the case. Probably
nothing they should have.

## Why It's Good For The Game

Mechs are a fucking diabolical nightmare of procs and some truly ancient
code. Over time, things have gotten worse, as we have no one really
actively maintaining some of this consistently. One of these bugs is
literally day of mech implementation. I shit you not.

## Changelog
🆑
fix: Mecha weaponry is capable, for the first time ever, of experiencing
recoil. This was an intended mechanic, I promise. The code just
literally never worked.
fix: Mecha bump melee attacks and click melee attacks are now on the
same cooldown, but have varying cooldown timers. You will always bump
attack faster than you will click.
fix: You must be in combat mode to punch objects and to bumpsmash into
objects.
fix: Stops mecha being able to punch literally any object and damage
them.
code: Tidies up some of the autodoc comments for mech weapons.
/🆑

* Ancient and recent mecha bug fixes

---------

Co-authored-by: necromanceranne <40847847+necromanceranne@users.noreply.github.com>
2024-07-01 19:36:02 +05:30

95 lines
4.2 KiB
Plaintext

/**
* This element registers to a shitload of signals which can signify "someone attacked me".
* If anyone does it sends a single "someone attacked me" signal containing details about who done it.
* This prevents other components and elements from having to register to the same list of a million signals, should be more maintainable in one place.
*/
/datum/element/relay_attackers
/datum/element/relay_attackers/Attach(datum/target)
. = ..()
if (!HAS_TRAIT(target, TRAIT_RELAYING_ATTACKER)) // Little bit gross but we want to just apply this shit from a bunch of places
// Boy this sure is a lot of ways to tell us that someone tried to attack us
RegisterSignal(target, COMSIG_ATOM_AFTER_ATTACKEDBY, PROC_REF(after_attackby))
RegisterSignals(target, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW, COMSIG_MOB_ATTACK_ALIEN), PROC_REF(on_attack_generic))
RegisterSignals(target, list(COMSIG_ATOM_ATTACK_BASIC_MOB, COMSIG_ATOM_ATTACK_ANIMAL), PROC_REF(on_attack_npc))
RegisterSignal(target, COMSIG_PROJECTILE_PREHIT, PROC_REF(on_bullet_act))
RegisterSignal(target, COMSIG_ATOM_PREHITBY, PROC_REF(on_hitby))
RegisterSignal(target, COMSIG_ATOM_HULK_ATTACK, PROC_REF(on_attack_hulk))
RegisterSignal(target, COMSIG_ATOM_ATTACK_MECH, PROC_REF(on_attack_mech))
ADD_TRAIT(target, TRAIT_RELAYING_ATTACKER, REF(src))
/datum/element/relay_attackers/Detach(datum/source, ...)
. = ..()
UnregisterSignal(source, list(
COMSIG_ATOM_AFTER_ATTACKEDBY,
COMSIG_ATOM_ATTACK_HAND,
COMSIG_ATOM_ATTACK_PAW,
COMSIG_ATOM_ATTACK_BASIC_MOB,
COMSIG_ATOM_ATTACK_ANIMAL,
COMSIG_MOB_ATTACK_ALIEN,
COMSIG_PROJECTILE_PREHIT,
COMSIG_ATOM_PREHITBY,
COMSIG_ATOM_HULK_ATTACK,
COMSIG_ATOM_ATTACK_MECH,
))
REMOVE_TRAIT(source, TRAIT_RELAYING_ATTACKER, REF(src))
/datum/element/relay_attackers/proc/after_attackby(atom/target, obj/item/weapon, mob/attacker, proximity_flag, click_parameters)
SIGNAL_HANDLER
if(!proximity_flag) // we don't care about someone clicking us with a piece of metal from across the room
return
if(weapon.force)
relay_attacker(target, attacker, weapon.damtype == STAMINA ? ATTACKER_STAMINA_ATTACK : ATTACKER_DAMAGING_ATTACK)
/datum/element/relay_attackers/proc/on_attack_generic(atom/target, mob/living/attacker, list/modifiers)
SIGNAL_HANDLER
// Check for a shove.
if(LAZYACCESS(modifiers, RIGHT_CLICK))
relay_attacker(target, attacker, ATTACKER_SHOVING)
return
// Else check for combat mode.
if(attacker.combat_mode)
relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK)
return
/datum/element/relay_attackers/proc/on_attack_npc(atom/target, mob/living/attacker)
SIGNAL_HANDLER
if(attacker.melee_damage_upper > 0)
relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK)
/// Even if another component blocked this hit, someone still shot at us
/datum/element/relay_attackers/proc/on_bullet_act(atom/target, list/bullet_args, obj/projectile/hit_projectile)
SIGNAL_HANDLER
if(!hit_projectile.is_hostile_projectile())
return
if(!ismob(hit_projectile.firer))
return
relay_attacker(target, hit_projectile.firer, hit_projectile.damage_type == STAMINA ? ATTACKER_STAMINA_ATTACK : ATTACKER_DAMAGING_ATTACK)
/// Even if another component blocked this hit, someone still threw something
/datum/element/relay_attackers/proc/on_hitby(atom/target, atom/movable/hit_atom, datum/thrownthing/throwingdatum)
SIGNAL_HANDLER
if(!isitem(hit_atom))
return
var/obj/item/hit_item = hit_atom
if(!hit_item.throwforce)
return
var/mob/thrown_by = hit_item.thrownby?.resolve()
if(!ismob(thrown_by))
return
relay_attacker(target, thrown_by, hit_item.damtype == STAMINA ? ATTACKER_STAMINA_ATTACK : ATTACKER_DAMAGING_ATTACK)
/datum/element/relay_attackers/proc/on_attack_hulk(atom/target, mob/attacker)
SIGNAL_HANDLER
relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK)
/datum/element/relay_attackers/proc/on_attack_mech(atom/target, obj/vehicle/sealed/mecha/mecha_attacker, mob/living/pilot, mecha_attack_cooldown)
SIGNAL_HANDLER
relay_attacker(target, mecha_attacker, ATTACKER_DAMAGING_ATTACK)
/// Send out a signal identifying whoever just attacked us (usually a mob but sometimes a mech or turret)
/datum/element/relay_attackers/proc/relay_attacker(atom/victim, atom/attacker, attack_flags)
SEND_SIGNAL(victim, COMSIG_ATOM_WAS_ATTACKED, attacker, attack_flags)