Skip to content

Commit

Permalink
Adds a component to make any storage tactical-reload capable. (#12709)
Browse files Browse the repository at this point in the history
* Creates a new component tac_reload_storage

* missed var on storage modules

Adds the appropriate init as well.

* Adds the component to belt/marine

The ones that can hold magazines.

* Adds component to holsters

* Adds to G8

* allows_tactical_reload = FALSE

Not every storage is tac reload capable, set it to true when you want something to be

* Removes component from things.

Removes the var that adds the component
Component is added on inintialzie
Only pistol belt has the component

* deletes comments on nothing

* unregisters signals

* invoke async into do_tac_reload()

* un-re-adds gun belts

also adds the component where it should be

* remove attackby_alt on pistol belt
  • Loading branch information
Xander3359 authored May 7, 2023
1 parent 035b0d8 commit e619588
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 18 deletions.
91 changes: 91 additions & 0 deletions code/datums/components/tac_reload_storage.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
///Component for making something capable of tactical reload via right click.
/datum/component/tac_reload_storage
///The storage item that we are attempting to use to tactical reload on.
///Use this over checking the item directly, for edge cases such as indirect storage (e.g: storage armor module).
var/obj/item/storage/reloading_storage

/datum/component/tac_reload_storage/Initialize()
if(!isstorage(parent) && !istype(parent, /obj/item/armor_module/storage))
return COMPONENT_INCOMPATIBLE

/datum/component/tac_reload_storage/Destroy(force, silent)
reloading_storage = null
return ..()

/datum/component/tac_reload_storage/RegisterWithParent()
if(istype(parent, /obj/item/armor_module/storage))
RegisterSignal(parent, COMSIG_ATTACHMENT_ATTACHED, PROC_REF(on_suit_attach))
RegisterSignal(parent, COMSIG_ATTACHMENT_DETACHED, PROC_REF(on_suit_detach))
else
reloading_storage = parent
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY_ALTERNATE, PROC_REF(on_parent_attackby_alternate))
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))

/datum/component/tac_reload_storage/UnregisterFromParent()
UnregisterSignal(parent, list(
COMSIG_ATTACHMENT_ATTACHED,
COMSIG_ATTACHMENT_DETACHED,
COMSIG_PARENT_ATTACKBY_ALTERNATE,
COMSIG_PARENT_EXAMINE,
))

///Hook into the examine of the parent to show the player that they can tac reload from this
/datum/component/tac_reload_storage/proc/on_examine(datum/source, mob/user, list/details)
SIGNAL_HANDLER
details += span_notice("To perform a reload with the ammunition inside, right click on the belt with any compatible gun.")

/**
* When attacked by a gun, will attempt to tactical reload it from our set reloading storage.
* Args:
* - source: The storage item source or armor suit. Use reloading_storage instead as it takes into account remote storage.
* - reloading_gun: The gun item that's attacking parent, that we want to reload.
* - user: The person attempting to reload the gun
* - params: The params (distance, etc.)
*/
/datum/component/tac_reload_storage/proc/on_parent_attackby_alternate(datum/source, obj/item/weapon/gun/reloading_gun, mob/user, params)
SIGNAL_HANDLER
if(!istype(reloading_gun))
return
if(!reloading_storage)
CRASH("[user] attempted to reload [reloading_gun] on [source], but it has no storage attached!")
INVOKE_ASYNC(src, PROC_REF(do_tac_reload), reloading_gun, user, params)

///Performs the tactical reload
/datum/component/tac_reload_storage/proc/do_tac_reload(obj/item/weapon/gun/reloading_gun, mob/user, params)
for(var/obj/item/item_to_reload_with in reloading_storage.contents)
if(!(item_to_reload_with.type in reloading_gun.allowed_ammo_types))
continue
if(user.get_active_held_item(reloading_gun))
reloading_gun.tactical_reload(item_to_reload_with, user)
reloading_storage.orient2hud()
return COMPONENT_NO_AFTERATTACK

/**
* Called when parent (a storage armor module) is attached to any suit
* Sent by attachment_handler component.
* Args:
* source - The storage armor module that's being attached.
* new_shot - The clothing that the module is being attached to.
* attacher - The person attaching the armor module to the suit.
*/
/datum/component/tac_reload_storage/proc/on_suit_attach(obj/item/armor_module/storage/source, obj/item/clothing/new_host, mob/attacher)
SIGNAL_HANDLER
reloading_storage = source.storage
RegisterSignal(new_host, COMSIG_PARENT_ATTACKBY_ALTERNATE, PROC_REF(on_parent_attackby_alternate))
RegisterSignal(new_host, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))

/**
* Called when parent (a storage armor module) is detached from any suit
* Sent by attachment_handler component.
* Args:
* source - The storage armor module that's being detached.
* old_host - The clothing that the module is being detached from.
* attacher - The person detaching the armor module from the suit.
*/
/datum/component/tac_reload_storage/proc/on_suit_detach(obj/item/armor_module/storage/source, obj/item/clothing/old_host, mob/attacher)
SIGNAL_HANDLER
reloading_storage = null
UnregisterSignal(old_host, list(
COMSIG_PARENT_ATTACKBY_ALTERNATE,
COMSIG_PARENT_EXAMINE,
))
18 changes: 2 additions & 16 deletions code/game/objects/items/storage/holsters.dm
Original file line number Diff line number Diff line change
Expand Up @@ -426,23 +426,9 @@
name = "generic pistol belt"
desc = "A pistol belt that is not a revolver belt"

/obj/item/storage/holster/belt/pistol/attackby_alternate(obj/item/I, mob/user, params)
if(!istype(I, /obj/item/weapon/gun/pistol))
return ..()
var/obj/item/weapon/gun/pistol/gun = I
for(var/obj/item/ammo_magazine/mag in contents)
if(!(mag.type in gun.allowed_ammo_types))
continue
if(user.l_hand && user.r_hand || length(gun.chamber_items))
gun.tactical_reload(mag, user)
else
gun.reload(mag, user)
orient2hud()
return

/obj/item/storage/holster/belt/pistol/examine(mob/user, distance, infix, suffix)
/obj/item/storage/holster/belt/pistol/Initialize(mapload, ...)
. = ..()
. += span_notice("To perform a reload with the amunition inside, disable right click and right click on the belt with an empty pistol.")
AddComponent(/datum/component/tac_reload_storage)

/obj/item/storage/holster/belt/pistol/m4a3
name = "\improper M4A3 holster rig"
Expand Down
1 change: 0 additions & 1 deletion code/game/objects/items/storage/pouch.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
desc = "A general purpose pouch used to carry small items."
icon_state = "small_drop"
draw_mode = 1

bypass_w_limit = list(/obj/item/ammo_magazine/packet)

/obj/item/storage/pouch/general/medium
Expand Down
1 change: 0 additions & 1 deletion code/game/objects/items/storage/storage.dm
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
///What sound gets played when the item is tactical refilled
var/refill_sound = null


/obj/item/storage/MouseDrop(obj/over_object as obj)
if(!ishuman(usr))
return
Expand Down
1 change: 1 addition & 0 deletions tgmc.dme
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@
#include "code\datums\components\slippery.dm"
#include "code\datums\components\squeak.dm"
#include "code\datums\components\stamina_behavior.dm"
#include "code\datums\components\tac_reload_storage.dm"
#include "code\datums\components\stun_mitigation.dm"
#include "code\datums\components\suit_autodoc.dm"
#include "code\datums\components\throw_parry.dm"
Expand Down

0 comments on commit e619588

Please sign in to comment.