Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TG Mirror] Hands management element [MDB IGNORE] #5

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_DEFIB_BLACKLISTED "defib_blacklisted"
#define TRAIT_BADDNA "baddna"
#define TRAIT_CLUMSY "clumsy"
/// Trait that means you are capable of holding items in some form
#define TRAIT_CAN_HOLD_ITEMS "can_hold_items"
/// Trait which lets you clamber over a barrier
#define TRAIT_FENCE_CLIMBER "can_climb_fences"
/// means that you can't use weapons with normal trigger guards.
#define TRAIT_CHUNKYFINGERS "chunkyfingers"
#define TRAIT_CHUNKYFINGERS_IGNORE_BATON "chunkyfingers_ignore_baton"
Expand Down
2 changes: 2 additions & 0 deletions code/_globalvars/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_CHUNKYFINGERS" = TRAIT_CHUNKYFINGERS,
"TRAIT_CHUNKYFINGERS_IGNORE_BATON" = TRAIT_CHUNKYFINGERS_IGNORE_BATON,
"TRAIT_FIST_MINING" = TRAIT_FIST_MINING,
"TRAIT_CAN_HOLD_ITEMS" = TRAIT_CAN_HOLD_ITEMS,
"TRAIT_FENCE_CLIMBER" = TRAIT_FENCE_CLIMBER,
"TRAIT_DUMB" = TRAIT_DUMB,
"TRAIT_ADVANCEDTOOLUSER" = TRAIT_ADVANCEDTOOLUSER,
"TRAIT_DISCOORDINATED_TOOL_USER" = TRAIT_DISCOORDINATED_TOOL_USER,
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/hud/generic_dextrous.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
using.icon = ui_style
static_inventory += using

mymob.canon_client.clear_screen()
mymob.canon_client?.clear_screen()

for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory))
if(inv.slot_id)
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/hud/screentip.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

/atom/movable/screen/screentip/proc/update_view(datum/source)
SIGNAL_HANDLER
if(!hud || !hud.mymob.canon_client.view_size) //Might not have been initialized by now
if(!hud || !hud.mymob.canon_client?.view_size) //Might not have been initialized by now
return
maptext_width = view_to_pixels(hud.mymob.canon_client.view_size.getView())[1]

Expand Down
23 changes: 1 addition & 22 deletions code/_onclick/other_mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -287,34 +287,13 @@
/atom/proc/attack_pai_secondary(mob/user, list/modifiers)
return SECONDARY_ATTACK_CALL_NORMAL

/*
Simple animals
*/

/mob/living/simple_animal/resolve_unarmed_attack(atom/attack_target, list/modifiers)
if(dextrous && (isitem(attack_target) || !combat_mode))
attack_target.attack_hand(src, modifiers)
update_held_items()
else
return ..()

/mob/living/simple_animal/resolve_right_click_attack(atom/target, list/modifiers)
if(dextrous && (isitem(target) || !combat_mode))
. = target.attack_hand_secondary(src, modifiers)
update_held_items()
else
return ..()

/*
Hostile animals
*/

/mob/living/simple_animal/hostile/resolve_unarmed_attack(atom/attack_target, list/modifiers)
GiveTarget(attack_target)
if(dextrous && (isitem(attack_target) || !combat_mode))
return ..()
else
INVOKE_ASYNC(src, PROC_REF(AttackingTarget), attack_target)
return ..()

#undef LIVING_UNARMED_ATTACK_BLOCKED

Expand Down
16 changes: 7 additions & 9 deletions code/datums/elements/climbable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,13 @@
///Handles climbing onto the atom when you click-drag
/datum/element/climbable/proc/mousedrop_receive(atom/climbed_thing, atom/movable/dropped_atom, mob/user, params)
SIGNAL_HANDLER
if(user == dropped_atom && isliving(dropped_atom))
var/mob/living/living_target = dropped_atom
if(isanimal(living_target))
var/mob/living/simple_animal/animal = dropped_atom
if (!animal.dextrous)
return
if(living_target.mobility_flags & MOBILITY_MOVE)
INVOKE_ASYNC(src, PROC_REF(climb_structure), climbed_thing, living_target, params)
return
if(user != dropped_atom || !isliving(dropped_atom))
return
if(!HAS_TRAIT(dropped_atom, TRAIT_FENCE_CLIMBER) && !HAS_TRAIT(dropped_atom, TRAIT_CAN_HOLD_ITEMS)) // If you can hold items you can probably climb a fence
return
var/mob/living/living_target = dropped_atom
if(living_target.mobility_flags & MOBILITY_MOVE)
INVOKE_ASYNC(src, PROC_REF(climb_structure), climbed_thing, living_target, params)

///Tries to climb onto the target if the forced movement of the mob allows it
/datum/element/climbable/proc/try_speedrun(datum/source, mob/bumpee)
Expand Down
69 changes: 69 additions & 0 deletions code/datums/elements/dextrous.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* 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))].")
8 changes: 1 addition & 7 deletions code/game/machinery/_machinery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -591,13 +591,7 @@
if(!isliving(user))
return FALSE //no ghosts allowed, sorry

var/is_dextrous = FALSE
if(isanimal(user))
var/mob/living/simple_animal/user_as_animal = user
if (user_as_animal.dextrous)
is_dextrous = TRUE

if(!issilicon(user) && !is_dextrous && !user.can_hold_items())
if(!issilicon(user) && !user.can_hold_items())
return FALSE //spiders gtfo

if(issilicon(user)) // If we are a silicon, make sure the machine allows silicons to interact with it
Expand Down
24 changes: 24 additions & 0 deletions code/modules/mob/living/basic/basic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,27 @@
else if(on_fire && !isnull(last_icon_state))
return last_icon_state
return null
<<<<<<< HEAD
=======

/mob/living/basic/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, ignore_animation = TRUE)
. = ..()
if (.)
update_held_items()

/mob/living/basic/update_held_items()
if(isnull(client) || isnull(hud_used) || hud_used.hud_version == HUD_STYLE_NOHUD)
return
var/turf/our_turf = get_turf(src)
for(var/obj/item/held in held_items)
var/index = get_held_index_of_item(held)
SET_PLANE(held, ABOVE_HUD_PLANE, our_turf)
held.screen_loc = ui_hand_position(index)
client.screen |= held

/mob/living/basic/get_body_temp_heat_damage_limit()
return maximum_survivable_temperature

/mob/living/basic/get_body_temp_cold_damage_limit()
return minimum_survivable_temperature
>>>>>>> 9eed8589dbf ([MIRROR] Hands management element [MDB IGNORE] (#24257))
2 changes: 1 addition & 1 deletion code/modules/mob/living/basic/space_fauna/bear/_bear.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

/mob/living/basic/bear/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
add_traits(list(TRAIT_SPACEWALK, TRAIT_FENCE_CLIMBER), INNATE_TRAIT)
AddElement(/datum/element/ai_retaliate)
AddComponent(/datum/component/tree_climber, climbing_distance = 15)
AddElement(/datum/element/swabable, CELL_LINE_TABLE_BEAR, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/basic/space_fauna/spider/spider.dm
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

/mob/living/basic/spider/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_WEB_SURFER, INNATE_TRAIT)
add_traits(list(TRAIT_WEB_SURFER, TRAIT_FENCE_CLIMBER), INNATE_TRAIT)
AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
AddElement(/datum/element/nerfed_pulling, GLOB.typecache_general_bad_things_to_easily_move)
AddElement(/datum/element/prevent_attacking_of_types, GLOB.typecache_general_bad_hostile_attack_targets, "this tastes awful!")
Expand Down
40 changes: 1 addition & 39 deletions code/modules/mob/living/carbon/carbon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
COMSIG_CARBON_DISARM_COLLIDE = PROC_REF(disarm_collision),
)
AddElement(/datum/element/connect_loc, loc_connections)
ADD_TRAIT(src, TRAIT_CAN_HOLD_ITEMS, INNATE_TRAIT) // Carbons are assumed to be innately capable of having arms, we check their arms count instead

/mob/living/carbon/Destroy()
//This must be done first, so the mob ghosts correctly before DNA etc is nulled
Expand All @@ -27,45 +28,6 @@
QDEL_NULL(dna)
GLOB.carbon_list -= src

/mob/living/carbon/perform_hand_swap(held_index)
. = ..()
if(!.)
return

if(!held_index)
held_index = (active_hand_index % held_items.len)+1

if(!isnum(held_index))
CRASH("You passed [held_index] into swap_hand instead of a number. WTF man")

var/oindex = active_hand_index
active_hand_index = held_index
if(hud_used)
var/atom/movable/screen/inventory/hand/H
H = hud_used.hand_slots["[oindex]"]
if(H)
H.update_appearance()
H = hud_used.hand_slots["[held_index]"]
if(H)
H.update_appearance()


/mob/living/carbon/activate_hand(selhand) //l/r OR 1-held_items.len
if(!selhand)
selhand = (active_hand_index % held_items.len)+1

if(istext(selhand))
selhand = lowertext(selhand)
if(selhand == "right" || selhand == "r")
selhand = 2
if(selhand == "left" || selhand == "l")
selhand = 1

if(selhand != active_hand_index)
swap_hand(selhand)
else
mode() // Activate held item

/mob/living/carbon/attackby(obj/item/item, mob/living/user, params)
if(!all_wounds || !(!user.combat_mode || user == src))
return ..()
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1308,7 +1308,7 @@
return

/mob/living/can_hold_items(obj/item/I)
return usable_hands && ..()
return ..() && HAS_TRAIT(src, TRAIT_CAN_HOLD_ITEMS) && usable_hands

/mob/living/can_perform_action(atom/movable/target, action_bitflags)
if(!istype(target))
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/silicon/robot/inventory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@

/mob/living/silicon/robot/perform_hand_swap()
cycle_modules()
return TRUE

/mob/living/silicon/robot/can_hold_items(obj/item/I)
return (I && (I in model.modules)) //Only if it's part of our model.
14 changes: 3 additions & 11 deletions code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,9 @@
dropItemToGround(internal_storage)

/mob/living/simple_animal/hostile/guardian/dextrous/examine(mob/user)
if(dextrous)
. = list("<span class='info'>This is [icon2html(src)] \a <b>[src]</b>!\n[desc]", EXAMINE_SECTION_BREAK) //SKYRAT EDIT CHANGE
for(var/obj/item/held_item in held_items)
if(held_item.item_flags & (ABSTRACT|EXAMINE_SKIP|HAND_ITEM))
continue
. += "It has [held_item.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(held_item))]."
if(internal_storage && !(internal_storage.item_flags & ABSTRACT))
. += "It is holding [internal_storage.get_examine_string(user)] in its internal storage."
. += "</span>"
else
return ..()
. = ..()
if(internal_storage && !(internal_storage.item_flags & ABSTRACT))
. += span_info("It is holding [internal_storage.get_examine_string(user)] in its internal storage.")

/mob/living/simple_animal/hostile/guardian/dextrous/recall_effects()
drop_all_held_items()
Expand Down
42 changes: 4 additions & 38 deletions code/modules/mob/living/simple_animal/simple_animal.dm
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@
stack_trace("Simple animal being instantiated in nullspace")
update_simplemob_varspeed()
if(dextrous)
AddElement(/datum/element/dextrous, hud_type = hud_type)
AddComponent(/datum/component/personal_crafting)
add_traits(list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP), ROUNDSTART_TRAIT)
ADD_TRAIT(src, TRAIT_NOFIRE_SPREAD, ROUNDSTART_TRAIT)
Expand Down Expand Up @@ -447,8 +448,11 @@

/mob/living/simple_animal/death(gibbed)
drop_loot()
<<<<<<< HEAD
if(dextrous)
drop_all_held_items()
=======
>>>>>>> 9eed8589dbf ([MIRROR] Hands management element [MDB IGNORE] (#24257))
if(del_on_death)
..()
//Prevent infinite loops if the mob Destroy() is overridden in such
Expand Down Expand Up @@ -558,44 +562,6 @@
/mob/living/simple_animal/get_idcard(hand_first)
return (..() || access_card)

/mob/living/simple_animal/can_hold_items(obj/item/I)
return dextrous && ..()

/mob/living/simple_animal/activate_hand(selhand)
if(!dextrous)
return ..()
if(!selhand)
selhand = (active_hand_index % held_items.len)+1
if(istext(selhand))
selhand = lowertext(selhand)
if(selhand == "right" || selhand == "r")
selhand = 2
if(selhand == "left" || selhand == "l")
selhand = 1
if(selhand != active_hand_index)
swap_hand(selhand)
else
mode()

/mob/living/simple_animal/perform_hand_swap(hand_index)
. = ..()
if(!.)
return
if(!dextrous)
return
if(!hand_index)
hand_index = (active_hand_index % held_items.len)+1
var/oindex = active_hand_index
active_hand_index = hand_index
if(hud_used)
var/atom/movable/screen/inventory/hand/H
H = hud_used.hand_slots["[hand_index]"]
if(H)
H.update_appearance()
H = hud_used.hand_slots["[oindex]"]
if(H)
H.update_appearance()

/mob/living/simple_animal/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, ignore_animation = TRUE)
. = ..()
update_held_items()
Expand Down
Loading