Files
Bubberstation/code/datums/components/holderloving.dm
lizardqueenlexi 1b8bcd0365 Basic drones (#79109)
## About The Pull Request

Fixes #68825
Fixes #72249
Fixes #70184

Converts maintenance drones to use the basic mob framework. As drones
don't use AI, this was mostly a perfunctory conversion, but I took the
opportunity to clean up drone code a bit and fixed a few bugs.

Noteworthy changes:
- Drones now have a `can_unhack` field. This is set to FALSE on
syndrones, because unhacking them doesn't make them stop being evil but
does cause some weirdness. Syndrones are unused right now, but you never
know.
- Drones use the Dextrous component for hand-having.
- Drones no longer have an internal ID card, instead being given
all-access with the `simple_access` component.
- Picking up drones now works the same as for other mobs, instead of
pointlessly copying the code into `attack_hand`. As a consequence, it is
now possible to punch drones if you want to for some reason.
- Drones can now reboot/cannibalize dead drones without being in combat
mode.
- Cannibalizing a drone that contains a client no longer runtimes - the
client is ghosted ahead of time.
- Drones now have TRAIT_ADVANCEDTOOLUSER, allowing them to properly
interact with machines.
- Trying to screwdriver a dead drone now gives a balloon alert about why
you can't do that.

In addition to these changes, I cleaned up the code quite a bit,
organizing things better and placing more useful comments throughout.
And removing a hell of a lot of single-letter variable names.

I will note that this PR does _not_ address #72129. The issue there is
that sprites for drones-as-hats are entirely nonexistent, and I'm not a
spriter. It shouldn't be too hard to fix if someone makes dronehat
sprites, though!

## Why It's Good For The Game
Kills 8 more simple animals.

In addition to that, drones were clearly a bit neglected, so this fixes
them up a bit and makes the code a little bit clearer. Maybe not that
much clearer, but it's something. It certainly leaves them in a better
place for further work if anyone wants to do that. Plus, a bunch of bugs
and other jankiness are fixed now, which is nice.

## Changelog
🆑
refactor: Maintenance Drones now use the basic mob framework. This
shouldn't come with any noticeable gameplay changes, but please report
any bugs.
fix: Drones can now interact normally with electrified doors.
fix: Drones' built-in tools can no longer be placed in storage objects
and/or thrown on the floor.
fix: Drones can now perform right-click interactions correctly, such as
deconstructing reinforced windows.
fix: Drones can now reboot or cannibalize other drones without being in
combat mode.
/🆑
2023-10-21 23:36:48 +00:00

76 lines
2.5 KiB
Plaintext

/** Holder Loving Component
*
* This component is assigned to an [/obj/item], and also keeps track of a [holder].
* The [parent] is 'bound' to [holder]. [parent] will be kept either directly
* inside [holder], or in the inventory of a [/mob] that is itself holding [holder].
*
* If [parent] is placed in a [loc] that is not [holder] or [holder].[loc]
* (if it's a mob), it is placed back inside [holder].
*
* This is intended for items that are a 'part' of another item.
*
* It can also delete [parent] when [holder] is deleted.
*
*/
/datum/component/holderloving
can_transfer = TRUE
/** Item that parent is bound to.
* We try to keep parent either directly in holder, or in holder's loc if loc is a mob,
* and warp parent into holder if they go anywhere else.
*/
var/atom/holder
/// If parent is deleted when the holder gets deleted
var/del_parent_with_holder = FALSE
/datum/component/holderloving/Initialize(holder, del_parent_with_holder)
if(!isitem(parent) || !holder)
return COMPONENT_INCOMPATIBLE
src.holder = holder
if(del_parent_with_holder)
src.del_parent_with_holder = del_parent_with_holder
/datum/component/holderloving/RegisterWithParent()
RegisterSignal(holder, COMSIG_MOVABLE_MOVED, PROC_REF(check_my_loc))
RegisterSignal(holder, COMSIG_QDELETING, PROC_REF(holder_deleting))
RegisterSignals(parent, list(
COMSIG_ITEM_DROPPED,
COMSIG_ITEM_EQUIPPED,
COMSIG_ATOM_ENTERED,
COMSIG_ATOM_EXITED,
COMSIG_ITEM_STORED,
), PROC_REF(check_my_loc))
/datum/component/holderloving/UnregisterFromParent()
UnregisterSignal(holder, list(COMSIG_MOVABLE_MOVED, COMSIG_QDELETING))
UnregisterSignal(parent, list(
COMSIG_ITEM_DROPPED,
COMSIG_ITEM_EQUIPPED,
COMSIG_ATOM_ENTERED,
COMSIG_ATOM_EXITED,
COMSIG_ITEM_STORED,
))
/datum/component/holderloving/PostTransfer()
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
/datum/component/holderloving/InheritComponent(datum/component/holderloving/friend, i_am_original, list/arguments)
if(i_am_original)
holder = friend.holder
/datum/component/holderloving/proc/check_valid_loc(atom/location)
return (location == holder || ( location == holder.loc && ismob(holder.loc) ))
/datum/component/holderloving/proc/holder_deleting(datum/source, force)
SIGNAL_HANDLER
if(del_parent_with_holder)
qdel(parent)
else
qdel(src)
/datum/component/holderloving/proc/check_my_loc(datum/source)
SIGNAL_HANDLER
var/obj/item/item_parent = parent
if(!check_valid_loc(item_parent.loc))
item_parent.forceMove(holder)