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

Arbitrary gun attachment system #6826

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
Draft
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
8 changes: 7 additions & 1 deletion citadel.dme
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,8 @@
#include "code\__DEFINES\projectiles\ammo_casing.dm"
#include "code\__DEFINES\projectiles\ammo_magazine.dm"
#include "code\__DEFINES\projectiles\gun.dm"
#include "code\__DEFINES\projectiles\guns.dm"
#include "code\__DEFINES\projectiles\gun_attachment.dm"
#include "code\__DEFINES\projectiles\guns-legacy.dm"
#include "code\__DEFINES\projectiles\projectile.dm"
#include "code\__DEFINES\projectiles\system.dm"
#include "code\__DEFINES\radiation\flags.dm"
Expand Down Expand Up @@ -2098,6 +2099,7 @@
#include "code\modules\actions\action_drawer.dm"
#include "code\modules\actions\action_drawer_toggle.dm"
#include "code\modules\actions\action_holder.dm"
#include "code\modules\actions\types\attachment_action.dm"
#include "code\modules\actions\types\item_action.dm"
#include "code\modules\actions\types\organ_action.dm"
#include "code\modules\actionspeed\actionspeed_modifier.dm"
Expand Down Expand Up @@ -4453,9 +4455,13 @@
#include "code\modules\projectiles\ammunition\calibers\special\rocket.dm"
#include "code\modules\projectiles\guns\ballistic.dm"
#include "code\modules\projectiles\guns\energy.dm"
#include "code\modules\projectiles\guns\gun_attachment.dm"
#include "code\modules\projectiles\guns\launcher.dm"
#include "code\modules\projectiles\guns\magic.dm"
#include "code\modules\projectiles\guns\vox.dm"
#include "code\modules\projectiles\guns\attachments\bayonet.dm"
#include "code\modules\projectiles\guns\attachments\flashlight.dm"
#include "code\modules\projectiles\guns\attachments\harness.dm"
#include "code\modules\projectiles\guns\ballistic\microbattery\medigun.dm"
#include "code\modules\projectiles\guns\ballistic\microbattery\medigun_cells.dm"
#include "code\modules\projectiles\guns\ballistic\microbattery\microbattery-casing.dm"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

/// from base of /atom/proc/context_query: (list/options, datum/event_args/actor/e_args)
/// options list is the same format as /atom/proc/context_query, insert directly to it.
Expand All @@ -8,6 +8,13 @@
#define COMSIG_ATOM_CONTEXT_ACT "atom_context_act"
#define RAISE_ATOM_CONTEXT_ACT_HANDLED (1<<0)

/// Creates context key
///
/// * Used to ensure things like components piggybacking on an atom and
/// hooking the menu with signals don't collide with the atom or other
/// components using the same keys.
#define atom_context_key(atom, key) "[ref(atom)]-[key]"

/// create context
/// todo: this is deprecated, i think.
/// * name: name
Expand Down
52 changes: 52 additions & 0 deletions code/__DEFINES/projectiles/gun_attachment.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 Citadel Station Developers *//

//* gun attachment slot *//

/**
* * align_x is center pixel (or the left pixel of the 2-wide center, if center is 2 wide)
* * align_y is topmost pixel extending out of gun
*/
#define GUN_ATTACHMENT_SLOT_GRIP "grip"
/**
* * align_x is leftmost pixel of the part extending out of gun
* * align_y is center pixel (or the bottom pixel of center, if center is 2 wide)
*/
#define GUN_ATTACHMNET_SLOT_MUZZLE "muzzle"
/**
* * align_x is center pixel (or the left pixel of the 2-wide center, if center is 2 wide)
* * align_y is bottom pixel extending out of gun
*/
#define GUN_ATTACHMENT_SLOT_RAIL "rail"
/**
* * align_x is leftmost pixel of the part extending out of gun
* * align_y is center pixel (or the bottom pixel of center, if center is 2 wide)
* * this means that for many sidebarrel's, the align_x is actually right of the actual attachment because
* it'll be aligned to the pixel right of the muzzle, not to the interior of the gun!
*/
#define GUN_ATTACHMENT_SLOT_SIDEBARREL "sidebarrel"
/**
* * align_x is rightmost pixel extending left from the gun
* * align_y is top pixel of the area that actually attaches to the gun
*/
#define GUN_ATTACHMENT_SLOT_STOCK "stock"
/**
* * align_x is center pixel (or the left pixel of the 2-wide center, if center is 2 wide)
* * align_y is topmost pixel extending out of gun
*/
#define GUN_ATTACHMENT_SLOT_UNDERBARREL "underbarrel"

// todo: DEFINE_ENUM

//* gun attachment types *//

/// flashlight
#define GUN_ATTACHMENT_TYPE_FLASHLIGHT (1<<0)
/// targeting laser
#define GUN_ATTACHMENT_TYPE_AIM_LASER (1<<1)
/// scope
#define GUN_ATTACHMENT_TYPE_SCOPE (1<<2)
/// magharness, lanyard, etc
#define GUN_ATTACHMENT_TYPE_HARNESS (1<<3)

// todo: DEFINE_BITFIELD
2 changes: 1 addition & 1 deletion code/__DEFINES/projectiles/projectile.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

//* pre_impact(), impact(), bullet_act(), on_impact() impact_flags *//
/// pre_impact, bullet_act, on_impact are called in that order ///
Expand Down
2 changes: 1 addition & 1 deletion code/__DEFINES/projectiles/system.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

//* rendering system
//* this is currently only used on ammo magazines, as guns use composition of datums
Expand Down
2 changes: 1 addition & 1 deletion code/game/click/context.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2023 Citadel Station developers. *//
//* Copyright (c) 2024 Citadel Station Developers *//

/**
* get context options
Expand Down
2 changes: 1 addition & 1 deletion code/game/click/items-item_attack_chain.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 Citadel Station developers. *//
//* Copyright (c) 2024 Citadel Station Developers *//

//* Code for interacting as an item. *//

Expand Down
29 changes: 29 additions & 0 deletions code/game/objects/items/devices/flashlight.dm
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,35 @@
light_color = LIGHT_COLOR_FLUORESCENT_FLASHLIGHT
light_wedge = LIGHT_NARROW

/// the gun attachment used for testing if we can attach
var/static/obj/item/gun_attachment/flashlight/maglight/test_attachment

/obj/item/flashlight/maglight/proc/get_test_attachment() as /obj/item/gun_Attachment/flashlight/maglight
if(!test_attachment)
test_attachment = new
return test_attachment

#warn attachment

Check warning on line 281 in code/game/objects/items/devices/flashlight.dm

View workflow job for this annotation

GitHub Actions / Run Linters

#warn attachment

/obj/item/flashlight/maglight/using_as_item(atom/target, datum/event_args/actor/clickchain/e_args, clickchain_flags, datum/callback/reachability_check)
. = ..()
if(. & CLICKCHAIN_DO_NOT_PROPAGATE)
return
if(istype(target, /obj/item/gun))
var/obj/item/gun/gun_target = target
var/obj/item/gun_attachment/flashlight/maglight/test_attach = get_test_attachment()
if(gun_target.can_install_attachment(test_attach, e_args))
if(!e_args.performer.temporarily_remove_from_inventory(src))
e_args.chat_feedback(SPAN_WARNING("[src] is stuck to your hands!"), src)
return CLICKCHAIN_DO_NOT_PROPAGATE
var/obj/item/gun_attachment/flashlight/maglight/attaching = new
if(!gun_target.install_attachment(attaching, e_args))
CRASH("install failed after check")
else
attaching.our_maglight = src
forceMove(attaching)
return CLICKCHAIN_DO_NOT_PROPAGATE

/obj/item/flashlight/drone
name = "low-power flashlight"
desc = "A miniature lamp, that might be used by small robots."
Expand Down
25 changes: 22 additions & 3 deletions code/modules/actions/action.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

/**
* action datums
Expand Down Expand Up @@ -32,7 +32,7 @@
var/datum/callback/check_callback

//* Target / Delegate *//
/// callback to invoke with (actor) on trigger at base of /invoke().
/// callback to invoke with (datum/action/action, datum/event_args/actor/actor) on trigger at base of /invoke().
///
/// * return a truthy value from the callback to halt propagation
var/datum/callback/invoke_callback
Expand All @@ -51,14 +51,17 @@
//* Button(s) *//
/// all buttons that are on us right now
var/list/atom/movable/screen/movable/action_button/buttons

/// do not update buttons; something else manages them
var/rendering_externally_managed = FALSE

/// where the button's background icon is from
var/background_icon = 'icons/screen/actions/backgrounds.dmi'
/// what the action's background state should be
var/background_icon_state = "default"
/// custom background overlay to add; this goes below button sprite / overlays!
var/background_additional_overlay

/// the icon of the button's actual internal sprite, overlaid on the background
var/button_icon = 'icons/screen/actions/actions.dmi'
/// the icon_state of the button's actual internal sprite, overlaid on the background
Expand All @@ -67,11 +70,17 @@
var/button_additional_only = FALSE
/// custom overlay to add to all buttons; this is arbitrary, and can be a reference to an atom
var/button_additional_overlay

/// set availability to; it must be 0 to 1, inclusive.
var/button_availability = 1
/// default handling for availability should be invoked
var/button_availability_automatic = TRUE

/// are we active?
var/button_active = FALSE
/// overlay to add to background if active
var/button_active_overlay = "active-1"

/datum/action/New(datum/target)
if(!target_compatible(target))
qdel(src)
Expand Down Expand Up @@ -108,6 +117,14 @@
if(update)
update_buttons(TRUE)

/**
* set button active-ness
*/
/datum/action/proc/set_button_active(active, defer_update)
button_active = active
if(!defer_update)
update_buttons(TRUE)

/**
* updates if availability changed
*/
Expand Down Expand Up @@ -168,6 +185,8 @@
generating.plane = HUD_PLANE
generating.layer = HUD_LAYER_BASE

if(button_active && button_active_overlay)
generating.overlays += button_active_overlay
if(background_additional_overlay)
generating.overlays += background_additional_overlay

Expand Down Expand Up @@ -257,7 +276,7 @@
/datum/action/proc/invoke(datum/event_args/actor/actor)
PROTECTED_PROC(TRUE) // you thought i was joking??? do not directly call this goddamn proc.
SHOULD_NOT_OVERRIDE(TRUE)
if(invoke_callback?.Invoke())
if(invoke_callback?.Invoke(src, actor))
return TRUE
if(invoke_target(target, actor))
return TRUE
Expand Down
2 changes: 1 addition & 1 deletion code/modules/actions/action_button.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

INITIALIZE_IMMEDIATE(/atom/movable/screen/movable/action_button)
/atom/movable/screen/movable/action_button
Expand Down
2 changes: 1 addition & 1 deletion code/modules/actions/action_drawer.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

/**
* the actual action handler at /client,
Expand Down
2 changes: 1 addition & 1 deletion code/modules/actions/action_drawer_toggle.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

INITIALIZE_IMMEDIATE(/atom/movable/screen/movable/action_drawer_toggle)
/atom/movable/screen/movable/action_drawer_toggle
Expand Down
2 changes: 1 addition & 1 deletion code/modules/actions/action_holder.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

/**
* holds a set of actions
Expand Down
25 changes: 25 additions & 0 deletions code/modules/actions/types/attachment_action.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 Citadel Station Developers *//

/datum/action/attachment_action
target_type = /obj/item/gun_attachment
button_icon_state = null

/// automatically set button_additional_overlay to the item, if button_icon_state is null
var/render_attachment_as_button = TRUE

/datum/action/attachment_action/pre_render_hook()
if(render_attachment_as_button && isnull(button_icon_state))
button_additional_only = TRUE
var/image/generated = new
generated.appearance = target
// i hope you are not doing custom layers and planes for icons, right gamers??
generated.layer = FLOAT_LAYER
generated.plane = FLOAT_PLANE
button_additional_overlay = generated
return ..()

/datum/action/attachment_action/calculate_availability()
var/obj/item/item = target
var/mob/worn = item.worn_mob()
return worn? (worn.mobility_flags & check_mobility_flags? 1 : 0) : 1
4 changes: 2 additions & 2 deletions code/modules/actions/types/item_action.dm
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

/datum/action/item_action
target_type = /obj/item

button_icon_state = null

/// automatically set button_additional_overlay to the item, if button_icon_state is null
var/render_item_as_button = TRUE

Expand Down
6 changes: 3 additions & 3 deletions code/modules/actions/types/organ_action.dm
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

/datum/action/organ_action
target_type = /obj/item

target_type = /obj/item/organ
button_icon_state = null

/// automatically set button_additional_overlay to the organ
var/render_organ_as_button = TRUE

Expand Down
Loading
Loading