Files
Bubberstation/code/datums/components/recharging_attacks.dm
SkyratBot b5eb26abcc [MIRROR] Basic Constructs: Wraith [MDB IGNORE] (#24655)
* Basic Constructs: Wraith (#79235)

## About The Pull Request

Converts wraith constructs to basic mobs. The last of the "mainline"
constructs, though there's still one to go after this.

Wraiths are pretty much the same as they've always been - speedy
constructs that pack a bit of a punch, built around doing hit-and-run
tactics with their ability to ethereal jaunt. Notably, I've converted
their ability to recharge their jaunts with attacks into a new
component, `recharging_attacks`. This can be placed on any basic mob to
let them recharge a cooldown action by landing hits, which could
possibly be useful in the future.

NPC wraiths are pretty straightforward, with a twist - they will always
chase down and beat to death the lowest-hp mob they can see. Happening
upon one of these while wounded will end very badly! While I originally
wanted them to be more flighty and use hit-and-run tactics, I couldn't
figure out a way to do this that didn't look kind of silly and make them
less effective overall.

In addition to the wraiths, I've done some much-needed cleanup to basic
constructs as a whole, improving some things and covering some things I
missed along the way.
- Ectoplasm drop types from constructs is now properly based on their
theme. I _believe_ I've done this in a way that will pass unit tests
this time, but we'll see if my local tests were being honest with me.
- Player-controlled constructs now attack faster. I didn't realize that
being basic mobs capped them to attacking once every 2 seconds, which is
a gigantic nerf over the simple animal version. I cut this to just 1
second, which should be much closer to how it originally was.
- Artificers actually seek out and heal the most damaged ally they can
find, instead of the least damaged. Turns out the sort was doing the
exact opposite order from what I thought, which became much more obvious
when using the same targeting behavior on wraiths.
- I put the PR number in the juggernaut update script, which I somehow
missed on that one.
- Removed the extraneous "noncult" construct subtypes that didn't do
anything. The Artificer one, which does something, is still around.
## Why It's Good For The Game

For the same reasons as the previous three. 5 more simple animals gone,
and only one construct to go until I can nuke simple constructs from the
codebase entirely. Other than that, the new component could possibly
come in handy in future designs, and the NPC behavior should hopefully
be a little scary - even if just a little.
## Changelog
🆑
refactor: Wraith constructs have been converted to the basic mob
framework. NPC wraiths are now extra cruel and will attack the
lowest-health mob they can see at any given time. Make sure this isn't
you! Please report any bugs.
fix: Artificers and juggernauts no longer attack significantly more
slowly than intended.
/🆑

* Basic Constructs: Wraith

* Update defcon2.dmm

---------

Co-authored-by: lizardqueenlexi <105025397+lizardqueenlexi@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
2023-10-31 03:00:50 -04:00

67 lines
2.4 KiB
Plaintext

/// Reduces the cooldown of a given action upon landing attacks, critting, or killing mobs.
/datum/component/recharging_attacks
/// The target of the most recent attack
var/last_target
/// The stat of the most recently attacked mob
var/last_stat
/// The action to recharge when attacking
var/datum/action/cooldown/recharged_action
/// The amount of cooldown to refund on a successful attack
var/attack_refund
/// The amount of cooldown to refund when putting a target into critical
var/crit_refund
/datum/component/recharging_attacks/Initialize(
datum/action/cooldown/recharged_action,
attack_refund = 1 SECONDS,
crit_refund = 5 SECONDS,
)
. = ..()
if (!isbasicmob(parent) || !istype(recharged_action))
return COMPONENT_INCOMPATIBLE
src.recharged_action = recharged_action
src.attack_refund = attack_refund
src.crit_refund = crit_refund
/datum/component/recharging_attacks/Destroy()
UnregisterSignal(recharged_action, COMSIG_QDELETING)
recharged_action = null
return ..()
/datum/component/recharging_attacks/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(set_old_stat))
RegisterSignal(parent, COMSIG_HOSTILE_POST_ATTACKINGTARGET, PROC_REF(check_stat))
RegisterSignal(recharged_action, COMSIG_QDELETING, PROC_REF(on_action_qdel))
/datum/component/recharging_attacks/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_HOSTILE_PRE_ATTACKINGTARGET, COMSIG_HOSTILE_POST_ATTACKINGTARGET))
if(recharged_action)
UnregisterSignal(recharged_action, COMSIG_QDELETING)
/datum/component/recharging_attacks/proc/set_old_stat(mob/attacker, mob/attacked)
SIGNAL_HANDLER
if(!isliving(attacked))
return
last_target = attacked
last_stat = attacked.stat
/datum/component/recharging_attacks/proc/check_stat(mob/living/attacker, mob/living/attacked, success)
SIGNAL_HANDLER
if(!isliving(attacked) || attacked != last_target || attacker.faction_check_atom(attacked))
return
var/final_refund = attack_refund
if(QDELETED(attacked) || (attacked.stat == DEAD && last_stat != DEAD)) //The target is dead and we killed them - full refund
final_refund = recharged_action.cooldown_time
else if(attacked.stat > CONSCIOUS && last_stat == CONSCIOUS) //We knocked the target unconscious - partial refund
final_refund = crit_refund
recharged_action.next_use_time -= final_refund
recharged_action.build_all_button_icons()
/datum/component/recharging_attacks/proc/on_action_qdel()
SIGNAL_HANDLER
qdel(src)