mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-17 20:47:29 +00:00
## About The Pull Request Places "setting up being able to use hands" into an element so it can be easily applied to non-carbon mobs. ## Why It's Good For The Game This is one of the last roadblocks for basic mob implementation and people were intimidated by it but it turns out this shit is easy, 90% of this code is already just on `living` and I put a little bit more there. The element _really_ only handles stuff like dropping items on death, picking things up rather than biting them, and adding examine text. This also removes some copy/pasted code between `simple_animal` and `carbon` and unifies some behaviours which were implemented for some dextrous simple animals but not others. Changes to give Ian a single hand representing his mouth will come at a later date. ## Changelog 🆑 qol: You can now see what drones and gorillas are holding by examining them. admin: It's now easier to give handless mobs hands by applying the "dextrous" element. balance: Spiders and Bears can now climb railings (you know if... they'd rather do that than destroy them). /🆑
70 lines
2.9 KiB
Plaintext
70 lines
2.9 KiB
Plaintext
/**
|
|
* Sets up the attachee to have hands and manages things like dropping items on death and displaying them on examine
|
|
* Actual hand performance is managed by code on /living/ and not encapsulated here, we just enable it
|
|
*/
|
|
/datum/element/dextrous
|
|
|
|
/datum/element/dextrous/Attach(datum/target, hands_count = 2, hud_type = /datum/hud/dextrous)
|
|
. = ..()
|
|
if (!isliving(target) || iscarbon(target))
|
|
return ELEMENT_INCOMPATIBLE // Incompatible with the carbon typepath because that already has its own hand handling and doesn't need hand holding
|
|
|
|
var/mob/living/mob_parent = target
|
|
set_available_hands(mob_parent, hands_count)
|
|
mob_parent.set_hud_used(new hud_type(target))
|
|
mob_parent.hud_used.show_hud(mob_parent.hud_used.hud_version)
|
|
ADD_TRAIT(target, TRAIT_CAN_HOLD_ITEMS, REF(src))
|
|
RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_death))
|
|
RegisterSignal(target, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(on_hand_clicked))
|
|
RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined))
|
|
|
|
/datum/element/dextrous/Detach(datum/source)
|
|
. = ..()
|
|
var/mob/living/mob_parent = source
|
|
set_available_hands(mob_parent, initial(mob_parent.default_num_hands))
|
|
var/initial_hud = initial(mob_parent.hud_type)
|
|
mob_parent.set_hud_used(new initial_hud(source))
|
|
mob_parent.hud_used.show_hud(mob_parent.hud_used.hud_version)
|
|
REMOVE_TRAIT(source, TRAIT_CAN_HOLD_ITEMS, REF(src))
|
|
UnregisterSignal(source, list(
|
|
COMSIG_ATOM_EXAMINE,
|
|
COMSIG_LIVING_DEATH,
|
|
COMSIG_LIVING_UNARMED_ATTACK,
|
|
))
|
|
|
|
/// Set up how many hands we should have
|
|
/datum/element/dextrous/proc/set_available_hands(mob/living/hand_owner, hands_count)
|
|
hand_owner.drop_all_held_items()
|
|
var/held_items = list()
|
|
for (var/i in 1 to hands_count)
|
|
held_items += null
|
|
hand_owner.held_items = held_items
|
|
hand_owner.set_num_hands(hands_count)
|
|
hand_owner.set_usable_hands(hands_count)
|
|
|
|
/// Drop our shit when we die
|
|
/datum/element/dextrous/proc/on_death(mob/living/died, gibbed)
|
|
SIGNAL_HANDLER
|
|
died.drop_all_held_items()
|
|
|
|
/// Try picking up items
|
|
/datum/element/dextrous/proc/on_hand_clicked(mob/living/hand_haver, atom/target, proximity, modifiers)
|
|
SIGNAL_HANDLER
|
|
if (!isitem(target) && hand_haver.combat_mode)
|
|
return
|
|
if (LAZYACCESS(modifiers, RIGHT_CLICK))
|
|
INVOKE_ASYNC(target, TYPE_PROC_REF(/atom, attack_hand_secondary), hand_haver, modifiers)
|
|
else
|
|
INVOKE_ASYNC(target, TYPE_PROC_REF(/atom, attack_hand), hand_haver, modifiers)
|
|
INVOKE_ASYNC(hand_haver, TYPE_PROC_REF(/mob, update_held_items))
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
/// Tell people what we are holding
|
|
/datum/element/dextrous/proc/on_examined(mob/living/examined, mob/user, list/examine_list)
|
|
SIGNAL_HANDLER
|
|
for(var/obj/item/held_item in examined.held_items)
|
|
if(held_item.item_flags & (ABSTRACT|EXAMINE_SKIP|HAND_ITEM))
|
|
continue
|
|
examine_list += span_info("[examined.p_They()] [examined.p_have()] [held_item.get_examine_string(user)] in [examined.p_their()] \
|
|
[examined.get_held_index_name(examined.get_held_index_of_item(held_item))].")
|