Skip to content

Commit

Permalink
inhand interaction refactor (#6633)
Browse files Browse the repository at this point in the history
  • Loading branch information
silicons authored Aug 1, 2024
1 parent cd40af9 commit 64ec254
Show file tree
Hide file tree
Showing 22 changed files with 271 additions and 117 deletions.
3 changes: 3 additions & 0 deletions citadel.dme
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_throwing.dm"
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_tool_system.dm"
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_x_act.dm"
#include "code\__DEFINES\dcs\signals\signals_item\signals_item-interaction.dm"
#include "code\__DEFINES\dcs\signals\signals_item\signals_item_economy.dm"
#include "code\__DEFINES\dcs\signals\signals_item\signals_item_inventory.dm"
#include "code\__DEFINES\dcs\signals\signals_item\signals_item_mouse.dm"
Expand Down Expand Up @@ -1434,6 +1435,7 @@
#include "code\game\objects\empulse.dm"
#include "code\game\objects\explosion.dm"
#include "code\game\objects\explosion_recursive.dm"
#include "code\game\objects\items-interaction.dm"
#include "code\game\objects\items.dm"
#include "code\game\objects\materials.dm"
#include "code\game\objects\misc.dm"
Expand Down Expand Up @@ -3407,6 +3409,7 @@
#include "code\modules\mob\life.dm"
#include "code\modules\mob\login.dm"
#include "code\modules\mob\logout.dm"
#include "code\modules\mob\mob-keybind-triggers.dm"
#include "code\modules\mob\mob.dm"
#include "code\modules\mob\mob_defines.dm"
#include "code\modules\mob\mob_helpers.dm"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//

/// From base of obj/item/attack_self(): (/datum/event_args/actor/actor)
#define COMSIG_ITEM_ACTIVATE_INHAND "item_activate_inhand"
/// From base of obj/item/unique_action(): (/datum/event_args/actor/actor)
#define COMSIG_ITEM_UNIQUE_ACTION "item_unique_action"
/// From base of obj/item/defensive_toggle(): (/datum/event_args/actor/actor)
#define COMSIG_ITEM_DEFENSIVE_TOGGLE "item_defensive_toggle"
/// From base of obj/item/defensive_trigger(): (/datum/event_args/actor/actor)
#define COMSIG_ITEM_DEFENSIVE_TRIGGER "item_defensive_trigger"
2 changes: 0 additions & 2 deletions code/__DEFINES/dcs/signals/signals_object.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,3 @@

// todo: these two shouldn't be here
#define COMSIG_ITEM_ATTACK "item_attack"
/// From base of obj/item/attack_self(): (/mob)
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self"
127 changes: 127 additions & 0 deletions code/game/objects/items-interaction.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//

//* Inhand Triggers *//

/**
* Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
*
* You should do . = ..() and check ., if it's TRUE, it means a parent proc requested the call chain to stop.
*
* todo: please stop overriding this, use on_attack_self.
* todo: nuke mob/user.
* todo: rename this to like /activate_inhand, /on_activate_inhand
*
* @params
* * actor - the event_args that spawned this call
* * user - The person using us in hand; stop using this, this is deprecated
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/attack_self(mob/user, datum/event_args/actor/actor = new /datum/event_args/actor(user))
// todo: this should realistically be SHOULD_NOT_OVERRIDE but there's a massive number of overrides (some unnecessary), so this is for a later date
// SHOULD_NOT_OVERRIDE(TRUE) // may be re-evaluated later
SEND_SIGNAL(src, COMSIG_ITEM_ACTIVATE_INHAND, actor)
if(on_attack_self(actor))
return TRUE
if(interaction_flags_item & INTERACT_ITEM_ATTACK_SELF)
interact(user)

/**
* Called after we attack self
* Used to allow for attack_self to be interrupted by signals in nearly all cases.
* You should usually override this instead of attack_self.
*
* You should do . = ..() and check ., if it's TRUE, it means a parent proc requested the call chain to stop.
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/on_attack_self(datum/event_args/actor/e_args)
if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_inhand && obj_cell_slot.interaction_active(src))
e_args.visible_feedback(
target = src,
range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION,
visible = SPAN_NOTICE("[e_args.performer] removes the cell from [src]."),
audible = SPAN_NOTICE("You hear fasteners falling out and something being removed."),
otherwise_self = SPAN_NOTICE("You remove the cell from [src]."),
)
log_construction(e_args, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])")
e_args.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(e_args.performer))
return TRUE
if(!isnull(obj_storage) && obj_storage.allow_quick_empty && obj_storage.allow_quick_empty_via_attack_self)
var/turf/turf = get_turf(e_args.performer)
obj_storage.auto_handle_interacted_mass_dumping(e_args, turf)
return TRUE
return FALSE

/**
* Called when a mob uses our unique aciton.
*
* @params
* * actor - the event_args that spawned this call
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/unique_action(datum/event_args/actor/actor)
SHOULD_NOT_OVERRIDE(TRUE) // may be re-evaluated later
if(ismob(actor))
actor = new /datum/event_args/actor(actor)
SEND_SIGNAL(src, COMSIG_ITEM_UNIQUE_ACTION, actor)
if(on_unique_action(actor))
return TRUE

/**
* Called when an unique action is triggered.
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/on_unique_action(datum/event_args/actor/e_args)
return FALSE

/**
* Called when a mob uses our defensive toggle action.
*
* @params
* * actor - the event_args that spawned this call
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/defensive_toggle(datum/event_args/actor/actor)
SHOULD_NOT_OVERRIDE(TRUE) // may be re-evaluated later
if(ismob(actor))
actor = new /datum/event_args/actor(actor)
SEND_SIGNAL(src, COMSIG_ITEM_DEFENSIVE_TOGGLE, actor)
if(on_defensive_toggle(actor))
return TRUE

/**
* Called on defensive toggle
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/on_defensive_toggle(datum/event_args/actor/e_args)
return FALSE

/**
* Called when a mob uses our defensive trigger action.
*
* @params
* * actor - the event_args that spawned this call
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/defensive_trigger(datum/event_args/actor/actor)
SHOULD_NOT_OVERRIDE(TRUE) // may be re-evaluated later
if(ismob(actor))
actor = new /datum/event_args/actor(actor)
SEND_SIGNAL(src, COMSIG_ITEM_DEFENSIVE_TRIGGER, actor)
if(on_defensive_trigger(actor))
return TRUE

/**
* Called on defensive trigger.
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/on_defensive_trigger(datum/event_args/actor/e_args)
return FALSE
46 changes: 0 additions & 46 deletions code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -851,52 +851,6 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
return CLICKCHAIN_DO_NOT_PROPAGATE | CLICKCHAIN_DID_SOMETHING
return ..()

/**
* Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
*
* You should do . = ..() and check ., if it's TRUE, it means a parent proc requested the call chain to stop.
*
* @params
* * user - The person using us in hand
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/attack_self(mob/user)
// SHOULD_CALL_PARENT(TRUE)
// attack_self isn't really part of the item attack chain.
SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user)
if(on_attack_self(new /datum/event_args/actor(user)))
return TRUE
if(interaction_flags_item & INTERACT_ITEM_ATTACK_SELF)
interact(user)

/**
* Called after we attack self
* Used to allow for attack_self to be interrupted by signals in nearly all cases.
* You should usually override this instead of attack_self.
*
* You should do . = ..() and check ., if it's TRUE, it means a parent proc requested the call chain to stop.
*
* @return TRUE to signal to overrides to stop the chain and do nothing.
*/
/obj/item/proc/on_attack_self(datum/event_args/actor/e_args)
if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_inhand && obj_cell_slot.interaction_active(src))
e_args.visible_feedback(
target = src,
range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION,
visible = SPAN_NOTICE("[e_args.performer] removes the cell from [src]."),
audible = SPAN_NOTICE("You hear fasteners falling out and something being removed."),
otherwise_self = SPAN_NOTICE("You remove the cell from [src]."),
)
log_construction(e_args, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])")
e_args.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(e_args.performer))
return TRUE
if(!isnull(obj_storage) && obj_storage.allow_quick_empty && obj_storage.allow_quick_empty_via_attack_self)
var/turf/turf = get_turf(e_args.performer)
obj_storage.auto_handle_interacted_mass_dumping(e_args, turf)
return TRUE
return FALSE

/**
* Hitsound override when successfully melee attacking someone for melee_hit()
*
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/items/devices/flash.dm
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
else
user.visible_message("<span class='notice'>[user] fails to blind [M] with the flash!</span>")

/obj/item/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
/obj/item/flash/attack_self(mob/user)
if(!user || !clown_check(user))
return

Expand Down Expand Up @@ -312,7 +312,7 @@
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
update_icon()

/obj/item/flash/synthetic/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
/obj/item/flash/synthetic/attack_self(mob/user)
..()
if(!broken)
broken = 1
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/devices/radio/electropack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
master.receive_signal()
return

/obj/item/radio/electropack/attack_self(mob/user as mob, flag1)
/obj/item/radio/electropack/attack_self(mob/user)

if(!istype(user, /mob/living/carbon/human))
return
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/devices/traitordevices.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ effective or pretty fucking useless.
var/times_used = 0 //Number of times it's been used.
var/max_uses = 2

/obj/item/batterer/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
/obj/item/batterer/attack_self(mob/user)
if(!user) return
if(times_used >= max_uses)
to_chat(user, "<span class='warning'>The mind batterer has been burnt out!</span>")
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/id_cards/cards.dm
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
if(I)
icon = I

/obj/item/card_fluff/attack_self()
/obj/item/card_fluff/attack_self(mob/user)

var/choice = tgui_input_list(usr, "What element would you like to customize?", "Customize Card", list("Band","Stamp","Reset"))
if(!choice) return
Expand Down
7 changes: 5 additions & 2 deletions code/game/objects/items/tools/weldingtool.dm
Original file line number Diff line number Diff line change
Expand Up @@ -753,8 +753,11 @@
M.update_inv_l_hand()
M.update_inv_r_hand()

/obj/item/weldingtool/electric/crystal/attack_self(var/mob/living/carbon/human/user)
if(user.species.name == SPECIES_ADHERENT)
/obj/item/weldingtool/electric/crystal/attack_self(mob/user)
var/mob/living/carbon/human/H = user
if(!istype(H))
return
if(H.species.name == SPECIES_ADHERENT)
if(user.nutrition >= 40)
setWelding(!welding, user)
else
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/structures/watercloset.dm
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
reagents.add_reagent("chlorine", 3)
reagents.add_reagent("ammonia", 1)

/obj/item/reagent_containers/food/urinalcake/attack_self(mob/living/user)
/obj/item/reagent_containers/food/urinalcake/attack_self(mob/user)
user.visible_message("<span class='notice'>[user] squishes [src]!</span>", "<span class='notice'>You squish [src].</span>", "<i>You hear a squish.</i>")
icon_state = "urinalcake_squish"
addtimer(VARSET_CALLBACK(src, icon_state, "urinalcake"), 8)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/clothing/under/accessories/accessory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@
M.afflict_paralyze(20 * 10)
return

/obj/item/clothing/accessory/collar/shock/attack_self(mob/user as mob, flag1)
/obj/item/clothing/accessory/collar/shock/attack_self(mob/user)
if(!istype(user, /mob/living/carbon/human))
return
user.set_machine(src)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/fishing/equipment/bait_can.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/// how much it has left; null for infinite
var/bait_left = 50

/obj/item/bait_can/attack_self(mob/user, modifiers)
/obj/item/bait_can/attack_self(mob/user)
. = ..()
var/fresh_bait = retrieve_bait(user)
if(fresh_bait)
Expand Down
41 changes: 39 additions & 2 deletions code/modules/keybindings/keybind/item.dm
Original file line number Diff line number Diff line change
@@ -1,15 +1,52 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//

/datum/keybinding/item
weight = WEIGHT_ITEM
category = CATEGORY_ITEM

/datum/keybinding/item/can_use(client/user)
return TRUE

/datum/keybinding/item/activate_inhand
hotkey_keys = list("Z", "Southeast") // PAGEDOWN
name = "activate_inhand"
full_name = "Activate in-hand"
description = "Uses whatever item you have inhand; this is usually the item's primary action."

/datum/keybinding/item/activate_inhand/down(client/user)
user.mob.keybind_activate_inhand()
return TRUE

/datum/keybinding/item/unique_action
name = "unique_action"
full_name = "Unique Action"
description = "Triggers an unique action, based on whichever item you're holding."
hotkey_keys = list("C")
description = "Uses whatever item you have inhand; this is usually the item's secondary action."
hotkey_keys = list("Space")

/datum/keybinding/item/unique_action/down(client/user)
user.mob.keybind_unique_inhand()
return TRUE

/datum/keybinding/item/defensive_toggle
name = "item-defensive-toggle"
full_name = "Defensive Toggle"
description = "Usually uses whatever item you have inhand; this is usually the item's toggled defensive action."
hotkey_keys = list("F")

/datum/keybinding/item/defensive_toggle/down(client/user)
user.mob.keybind_defensive_toggle()
return TRUE

/datum/keybinding/item/defensive_trigger
name = "item-defensive-trigger"
full_name = "Defensive Trigger"
description = "Usually uses whatever item you have inhand; this is usually the item's triggered defensive action."
hotkey_keys = list("G")

/datum/keybinding/item/defensive_trigger/down(client/user)
user.mob.keybind_defensive_trigger()
return TRUE

/datum/keybinding/item/toggle_gun_safety
hotkey_keys = list()
Expand Down
11 changes: 0 additions & 11 deletions code/modules/keybindings/keybind/mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,6 @@
M.swap_hand()
return TRUE

/datum/keybinding/mob/activate_inhand
hotkey_keys = list("Z", "Southeast") // PAGEDOWN
name = "activate_inhand"
full_name = "Activate in-hand"
description = "Uses whatever item you have inhand"

/datum/keybinding/mob/activate_inhand/down(client/user)
var/mob/M = user.mob
M.mode()
return TRUE

/datum/keybinding/mob/multihand_wield
hotkey_keys = list("ShiftX")
classic_keys = list("X")
Expand Down
3 changes: 2 additions & 1 deletion code/modules/media/walkpod.dm
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@
else if(loc == L) // at least they're holding it
to_chat(L, "<span class='warning'>Turn on the [src] first.</span>")

/obj/item/device/walkpod/attack_self(mob/living/L)
/obj/item/device/walkpod/attack_self(mob/user)
var/mob/living/L = user
if(!istype(L) || loc != L)
return
if(!listener)
Expand Down
Loading

0 comments on commit 64ec254

Please sign in to comment.