mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-13 03:02:38 +00:00
## About The Pull Request Given the existence of basic mobs with hand slots, it feels like throwing and giving items shouldn't be something exclusive to carbon mobs, so I've pulled things around to make this happen. The only basic mobs with hands at time of writing are gorillas and dextrous holoparasites, but the inability to throw things when you're a gorilla just doesn't seem right to me. Some more details about what I've done here: - Made the dextrous component optionally enable throwing for the mob it's added to. - Moved offer/give item functionality to /mob/living (I can't see any reason why only carbon mobs should have this option) - Moved throwing and give item hotkeys from carbon to "human" (where all the other /mob/living hotkeys go) and, as a result, removed carbon hotkeys (nothing is left in them). - Moved throwing code and item offering code to its own file because living.dm is 3000+ lines long and should probably be broken up some day (I'm not brave enough for that) - Cleaned up an unused global signal that hasn't been used since dogs got moved to basic mobs. - Other miscellaneous cleanup where I noticed it. - In terms of testing: Tested using gorillas (only checked the dextrous holoparasite to confirm the button and hotkeys worked). Things that were working: - Can throw items if the mob is set up to allow it. - Can give items as a gorilla to a human, as a human to a gorilla, and as a human to a human. - Can give a high five to a gorilla (and the gorilla can receive it). Gorillas can't give a high five back, though (they don't have the emote), this already ballooned in scope, someone else can make that happen. - There are an alarmingly high amount of niche emote-into-item-into-giving behaviours I suspect half the playerbase or more aren't even aware of (does anyone offer their hand to someone to get them up off of the ground?) and I don't know if I broke any of them with this, but the fact high fives work gives me some hope they're probably still fine. ## Why It's Good For The Game Lets gorillas and dextrous holoparasites throw things and give things, but most importantly sets up more framework for any future dextrous basic mobs to also be able to do this. There's no real reason to keep this functionality confined to carbon mobs when dextrous basic mobs are a thing. ## Changelog 🆑 add: Gorillas can now throw things and offer items to players. refactor: Moved throwing and offering item code to be based on living mobs, not just carbon mobs. /🆑 --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
80 lines
3.4 KiB
Plaintext
80 lines
3.4 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, can_throw = FALSE)
|
|
. = ..()
|
|
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)
|
|
if(can_throw)
|
|
ADD_TRAIT(target, TRAIT_CAN_THROW_ITEMS, REF(src)) // need to add before hud setup
|
|
mob_parent.hud_type = hud_type
|
|
if (mob_parent.hud_used)
|
|
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.hud_type = initial_hud
|
|
if (mob_parent.hud_used)
|
|
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 (!proximity && target.loc != hand_haver)
|
|
var/obj/item/obj_item = target
|
|
if (istype(obj_item) && !obj_item.atom_storage && !(obj_item.item_flags & IN_STORAGE))
|
|
return NONE
|
|
if (!isitem(target) && hand_haver.combat_mode)
|
|
return NONE
|
|
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|HAND_ITEM)) || HAS_TRAIT(held_item, TRAIT_EXAMINE_SKIP))
|
|
continue
|
|
examine_list += span_info("[examined.p_They()] [examined.p_have()] [held_item.examine_title(user)] in [examined.p_their()] \
|
|
[examined.get_held_index_name(examined.get_held_index_of_item(held_item))].")
|