Skip to content

Commit

Permalink
Underbarrel Gun Attachments (#3825)
Browse files Browse the repository at this point in the history
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

## About The Pull Request

<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->

Adds underbarrel gun attachments. Current roster is the underbarrel
shotgun, e-gun, flamethrower, flaregun, riot grenade launcher, and 40mm
grenade launcher. The first five can be bought from the outpost cargo.

Attachment removal now needs to be on harm intent in addition to the
alt-click to avoid action conflicts.

Underbarrel guns can be fired/reloaded/interacted with by swapping the
fire select to underbarrel.

Cleans up the riot grenade launcher code a bit.

Fixes runtimes caused by canceling attachment removal without selecting
an attachment, and dropping cells from e-guns with an open latch.

Underbarrel gun sprites are recolors of Rye-rice's underbarrel grenade
launcher.

## Why It's Good For The Game

<!-- Please add a short description of why you think these changes would
benefit the game. If you can't justify it in words, it might not be
worth adding. -->

Adds some more customization and personalization options to a players
loadout, and I think it's neat.

## Changelog

:cl: Gristlebee, Rye-rice
add: Underbarrel guns
add: Hand attachment removal is bound to alt-click on harm intent.
fix: Grenade launcher code
fix: Runtimes
/:cl:

<!-- Both :cl:'s are required for the changelog to work! You can put
your name to the right of the first :cl: if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->

---------

Signed-off-by: Gristlebee <[email protected]>
Co-authored-by: Mark Suckerberg <[email protected]>
Co-authored-by: FalloutFalcon <[email protected]>
  • Loading branch information
3 people authored Jan 6, 2025
1 parent 0762192 commit fb8e245
Show file tree
Hide file tree
Showing 32 changed files with 661 additions and 105 deletions.
3 changes: 3 additions & 0 deletions code/__DEFINES/dcs/signals/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@
#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click"
///from base of atom/CtrlShiftRightClick(/mob)
#define COMSIG_CLICK_CTRL_SHIFT_RIGHT "ctrl_shift_right_click"
/// from mob/ver/do_unique_action
#define COMSIG_CLICK_UNIQUE_ACTION "unique_action"
#define OVERIDE_UNIQUE_ACTION 1
//from base of atom/MouseDrop(): (/atom/over, /mob/user)
#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto"
#define COMPONENT_NO_MOUSEDROP 1
Expand Down
7 changes: 7 additions & 0 deletions code/__DEFINES/guns.dm
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,14 @@
#define COMSIG_ATTACHMENT_EXAMINE "attach-examine"
#define COMSIG_ATTACHMENT_EXAMINE_MORE "attach-examine-more"
#define COMSIG_ATTACHMENT_PRE_ATTACK "attach-pre-attack"
#define COMSIG_ATTACHMENT_AFTER_ATTACK "attach-after-attack"
#define COMSIG_ATTACHMENT_ATTACK "attach-attacked"
#define COMSIG_ATTACHMENT_WIELD "attach-wield"
#define COMSIG_ATTACHMENT_UNWIELD "attach-unwield"
#define COMSIG_ATTACHMENT_UPDATE_OVERLAY "attach-overlay"
#define COMSIG_ATTACHMENT_UNIQUE_ACTION "attach-unique-action"
#define COMSIG_ATTACHMENT_CTRL_CLICK "attach-ctrl-click"
#define COMSIG_ATTACHMENT_ALT_CLICK "attach-alt-click"

#define COMSIG_ATTACHMENT_TOGGLE "attach-toggle"

Expand Down Expand Up @@ -199,6 +205,7 @@
#define FIREMODE_FULLAUTO "auto"
#define FIREMODE_OTHER "other"
#define FIREMODE_OTHER_TWO "other2"
#define FIREMODE_UNDERBARREL "underbarrel"

#define GUN_LEFTHAND_ICON 'icons/mob/inhands/weapons/guns_lefthand.dmi'
#define GUN_RIGHTHAND_ICON 'icons/mob/inhands/weapons/guns_righthand.dmi'
8 changes: 6 additions & 2 deletions code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,10 @@
UnarmedAttack(A,1)
else
if(W)
W.afterattack(A,src,0,params)
if(W.pre_attack(A,src,params))
return
else
W.afterattack(A,src,0,params)
else
RangedAttack(A,params)

Expand Down Expand Up @@ -342,10 +345,11 @@
A.AltClick(src)

/atom/proc/AltClick(mob/user)
SEND_SIGNAL(src, COMSIG_CLICK_ALT, user)
var/result = SEND_SIGNAL(src, COMSIG_CLICK_ALT, user)
var/turf/T = get_turf(src)
if(T && (isturf(loc) || isturf(src)) && user.TurfAdjacent(T))
user.set_listed_turf(T)
return result

/// Use this instead of [/mob/proc/AltClickOn] where you only want turf content listing without additional atom alt-click interaction
/atom/proc/AltClickNoInteract(mob/user, atom/A)
Expand Down
68 changes: 68 additions & 0 deletions code/datums/components/attachment.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@
var/datum/callback/on_attach
var/datum/callback/on_detach
var/datum/callback/on_toggle
var/datum/callback/on_attacked
var/datum/callback/on_unique_action
var/datum/callback/on_ctrl_click
var/datum/callback/on_alt_click
var/datum/callback/on_examine
///Called on the parents preattack
var/datum/callback/on_preattack
///Called on the parents wield
var/datum/callback/on_wield
///Called on the parents unwield
var/datum/callback/on_unwield
///Unused...Also a little broken..
var/list/datum/action/actions
///Generated if the attachment can toggle, sends COMSIG_ATTACHMENT_TOGGLE
Expand All @@ -23,6 +32,13 @@
datum/callback/on_detach = null,
datum/callback/on_toggle = null,
datum/callback/on_preattack = null,
datum/callback/on_attacked = null,
datum/callback/on_unique_action = null,
datum/callback/on_ctrl_click = null,
datum/callback/on_wield = null,
datum/callback/on_unwield = null,
datum/callback/on_examine = null,
datum/callback/on_alt_click = null,
list/signals = null
)

Expand All @@ -36,6 +52,13 @@
src.on_detach = on_detach
src.on_toggle = on_toggle
src.on_preattack = on_preattack
src.on_attacked = on_attacked
src.on_unique_action = on_unique_action
src.on_ctrl_click = on_ctrl_click
src.on_wield = on_wield
src.on_unwield = on_unwield
src.on_examine = on_examine
src.on_alt_click = on_alt_click

ADD_TRAIT(parent, TRAIT_ATTACHABLE, "attachable")
RegisterSignal(parent, COMSIG_ATTACHMENT_ATTACH, PROC_REF(try_attach))
Expand All @@ -48,6 +71,12 @@
RegisterSignal(parent, COMSIG_ATTACHMENT_PRE_ATTACK, PROC_REF(relay_pre_attack))
RegisterSignal(parent, COMSIG_ATTACHMENT_UPDATE_OVERLAY, PROC_REF(update_overlays))
RegisterSignal(parent, COMSIG_ATTACHMENT_GET_SLOT, PROC_REF(send_slot))
RegisterSignal(parent, COMSIG_ATTACHMENT_WIELD, PROC_REF(try_wield))
RegisterSignal(parent, COMSIG_ATTACHMENT_UNWIELD, PROC_REF(try_unwield))
RegisterSignal(parent, COMSIG_ATTACHMENT_ATTACK, PROC_REF(relay_attacked))
RegisterSignal(parent, COMSIG_ATTACHMENT_UNIQUE_ACTION, PROC_REF(relay_unique_action))
RegisterSignal(parent, COMSIG_ATTACHMENT_CTRL_CLICK, PROC_REF(relay_ctrl_click))
RegisterSignal(parent, COMSIG_ATTACHMENT_ALT_CLICK, PROC_REF(relay_alt_click))

for(var/signal in signals)
RegisterSignal(parent, signal, signals[signal])
Expand Down Expand Up @@ -129,6 +158,9 @@
/datum/component/attachment/proc/handle_examine(obj/item/parent, mob/user, list/examine_list)
SIGNAL_HANDLER

if(on_examine)
on_examine.Invoke(parent, user, examine_list)

/datum/component/attachment/proc/handle_examine_more(obj/item/parent, mob/user, list/examine_list)
SIGNAL_HANDLER

Expand All @@ -138,6 +170,42 @@
if(on_preattack)
return on_preattack.Invoke(gun, target_atom, user, params)

/datum/component/attachment/proc/relay_attacked(obj/item/parent, obj/item/gun, obj/item, mob/user, params)
SIGNAL_HANDLER_DOES_SLEEP

if(on_attacked)
return on_attacked.Invoke(gun, user, item)

/datum/component/attachment/proc/try_wield(obj/item/parent, obj/item/gun, mob/user, params)
SIGNAL_HANDLER_DOES_SLEEP

if(on_wield)
return on_wield.Invoke(gun, user, params)

/datum/component/attachment/proc/try_unwield(obj/item/parent, obj/item/gun, mob/user, params)
SIGNAL_HANDLER_DOES_SLEEP

if(on_unwield)
return on_unwield.Invoke(gun, user, params)

/datum/component/attachment/proc/relay_unique_action(obj/item/parent, obj/item/gun, mob/user, params)
SIGNAL_HANDLER_DOES_SLEEP

if(on_unique_action)
return on_unique_action.Invoke(gun, user, params)

/datum/component/attachment/proc/relay_ctrl_click(obj/item/parent, obj/item/gun, mob/user, params)
SIGNAL_HANDLER_DOES_SLEEP

if(on_ctrl_click)
return on_ctrl_click.Invoke(gun, user, params)

/datum/component/attachment/proc/relay_alt_click(obj/item/parent, obj/item/gun, mob/user, params)
SIGNAL_HANDLER_DOES_SLEEP

if(on_alt_click)
return on_alt_click.Invoke(gun, user, params)

/datum/component/attachment/proc/send_slot(obj/item/parent)
SIGNAL_HANDLER
return attachment_slot_to_bflag(slot)
Expand Down
53 changes: 47 additions & 6 deletions code/datums/components/attachment_holder.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,20 @@
var/obj/item/gun/parent_gun = parent

src.slot_room = slot_room
src.valid_types = valid_types
src.valid_types = typecacheof(valid_types)
src.slot_offsets = slot_offsets

RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(handle_attack))
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(handle_examine))
RegisterSignal(parent, COMSIG_PARENT_EXAMINE_MORE, PROC_REF(handle_examine_more))
RegisterSignal(parent, COMSIG_PARENT_QDELETING, PROC_REF(handle_qdel))
RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(handle_item_pre_attack))
RegisterSignal(parent, COMSIG_TWOHANDED_WIELD, PROC_REF(handle_item_wield))
RegisterSignal(parent, COMSIG_TWOHANDED_UNWIELD, PROC_REF(handle_item_unwield))
RegisterSignal(parent, COMSIG_CLICK_CTRL_SHIFT, PROC_REF(handle_ctrl_shift_click))
RegisterSignal(parent, COMSIG_CLICK_CTRL, PROC_REF(handle_ctrl_click))
RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(handle_alt_click))
RegisterSignal(parent, COMSIG_CLICK_UNIQUE_ACTION, PROC_REF(handle_unique_action))
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(handle_overlays))

if(length(default_attachments))
Expand Down Expand Up @@ -80,7 +84,20 @@
/datum/component/attachment_holder/proc/handle_alt_click(obj/item/parent, mob/user)
SIGNAL_HANDLER

INVOKE_ASYNC(src, PROC_REF(handle_detach), parent, user)
if(user.a_intent == INTENT_HARM)
INVOKE_ASYNC(src, PROC_REF(handle_detach), parent, user)
return TRUE
else
for(var/obj/item/attach as anything in attachments)
if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_ALT_CLICK, parent, user))
return TRUE

/datum/component/attachment_holder/proc/handle_ctrl_click(obj/item/parent, mob/user)
SIGNAL_HANDLER

for(var/obj/item/attach as anything in attachments)
if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_CTRL_CLICK, parent, user))
return TRUE

/datum/component/attachment_holder/proc/do_attachment_radial(obj/item/parent, mob/user)
var/list/attachments_as_list = attachments_to_list(TRUE)
Expand All @@ -93,6 +110,7 @@
/datum/component/attachment_holder/proc/handle_examine(obj/item/parent, mob/user, list/examine_list)
if(length(attachments))
examine_list += span_notice("It has [length(attachments)] attachment\s.")
examine_list += span_notice("You can remove them by pressing alt-click on the [parent] on harm intent.")
for(var/obj/item/attach as anything in attachments)
SEND_SIGNAL(attach, COMSIG_ATTACHMENT_EXAMINE, user, examine_list)

Expand All @@ -114,7 +132,7 @@
/datum/component/attachment_holder/proc/do_attach(obj/item/attachment, mob/user, bypass_checks)
var/slot = SEND_SIGNAL(attachment, COMSIG_ATTACHMENT_GET_SLOT)
slot = attachment_slot_from_bflag(slot)
if(!(attachment.type in valid_types))
if(!(is_type_in_typecache(attachment,valid_types)))
to_chat(user, span_notice("[attachment] is not a valid attachment for this [parent]!"))
return
if(!slot_room[slot])
Expand Down Expand Up @@ -152,13 +170,15 @@
var/selected = tgui_input_list(user, "Select Attachment", "Detach", tool_list)
if(!parent.Adjacent(user) || !selected || !tool || !tool.use_tool(parent, user, 2 SECONDS * tool.toolspeed))
return
do_detach(tool_list[selected], user)
if(selected)
do_detach(tool_list[selected], user)
else
if(!length(hand_list))
return
var/selected = tgui_input_list(user, "Select Attachment", "Detach", hand_list)
if(do_after(user, 2 SECONDS, parent))
do_detach(hand_list[selected], user)
if(selected)
if(do_after(user, 2 SECONDS, parent))
do_detach(hand_list[selected], user)


/datum/component/attachment_holder/proc/handle_attack(obj/item/parent, obj/item/item, mob/user)
Expand Down Expand Up @@ -186,3 +206,24 @@
for(var/obj/item/attach as anything in attachments)
if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_PRE_ATTACK, parent, target_atom, user, params))
return TRUE

/datum/component/attachment_holder/proc/handle_item_wield(obj/item/parent, mob/user, params)
SIGNAL_HANDLER

for(var/obj/item/attach as anything in attachments)
if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_WIELD , parent, user, params))
return TRUE

/datum/component/attachment_holder/proc/handle_item_unwield(obj/item/parent, mob/user, params)
SIGNAL_HANDLER

for(var/obj/item/attach as anything in attachments)
if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_UNWIELD, parent, user, params))
return TRUE

/datum/component/attachment_holder/proc/handle_unique_action(obj/item/parent, mob/user, params)
SIGNAL_HANDLER

for(var/obj/item/attach as anything in attachments)
if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_UNIQUE_ACTION, parent, user, params))
return TRUE
1 change: 1 addition & 0 deletions code/game/machinery/recharger.dm
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
/obj/item/modular_computer,
/obj/item/gun/ballistic/automatic/powered,
/obj/item/gun/ballistic/automatic/assault/e40,
/obj/item/attachment/gun/energy,
/obj/item/stock_parts/cell/gun
))

Expand Down
6 changes: 5 additions & 1 deletion code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1194,8 +1194,12 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb

///Intended for interactions with guns, like racking
/obj/item/proc/unique_action(mob/living/user)
return

///Called before unique action, if any other associated items should do a unique action or override it.
/obj/item/proc/pre_unique_action(mob/living/user)
if(SEND_SIGNAL(src,COMSIG_CLICK_UNIQUE_ACTION,user) & OVERIDE_UNIQUE_ACTION)
return TRUE
return FALSE //return true if the proc should end here
/**
* Returns null if this object cannot be used to interact with physical writing mediums such as paper.
* Returns a list of key attributes for this object interacting with paper otherwise.
Expand Down
34 changes: 34 additions & 0 deletions code/game/objects/items/attachments/_attachment.dm
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
CALLBACK(src, PROC_REF(remove_attachment)), \
CALLBACK(src, PROC_REF(toggle_attachment)), \
CALLBACK(src, PROC_REF(on_preattack)), \
CALLBACK(src, PROC_REF(on_attacked)), \
CALLBACK(src, PROC_REF(on_unique_action)), \
CALLBACK(src, PROC_REF(on_ctrl_click)), \
CALLBACK(src, PROC_REF(on_wield)), \
CALLBACK(src, PROC_REF(on_unwield)), \
CALLBACK(src, PROC_REF(on_examine)), \
CALLBACK(src, PROC_REF(on_alt_click)), \
signals)

/obj/item/attachment/Destroy()
Expand Down Expand Up @@ -89,6 +96,33 @@
/obj/item/attachment/proc/on_preattack(obj/item/gun/gun, atom/target, mob/user, list/params)
return FALSE

/obj/item/attachment/proc/on_wield(obj/item/gun/gun, mob/user, list/params)
return FALSE

/obj/item/attachment/proc/on_unwield(obj/item/gun/gun, mob/user, list/params)
return FALSE

/obj/item/attachment/proc/on_attacked(obj/item/gun/gun, mob/user, obj/item)
return FALSE

/obj/item/attachment/proc/on_unique_action(obj/item/gun/gun, mob/user, obj/item)
return FALSE

/obj/item/attachment/proc/on_ctrl_click(obj/item/gun/gun, mob/user, params)
return FALSE

/obj/item/attachment/proc/on_examine(obj/item/gun/gun, mob/user, list/examine_list)
return

/obj/item/attachment/proc/on_alt_click(obj/item/gun/gun, mob/user, list/examine_list)
AltClick(user)
return TRUE

/obj/item/attachment/examine(mob/user)
. = ..()
var/list/examine_info = list()
. += on_examine(examine_list = examine_info)

///Handles the modifiers to the parent gun
/obj/item/attachment/proc/apply_modifiers(obj/item/gun/gun, mob/user, attaching)
if(attaching)
Expand Down
Loading

0 comments on commit fb8e245

Please sign in to comment.