Skip to content

Commit

Permalink
Arbitrary gun attachment system (#6826)
Browse files Browse the repository at this point in the history
does not currently support projectile modification, that's coming later

Includes adding support for attaching maglights to certain guns
  • Loading branch information
silicons authored Nov 8, 2024
1 parent d6fd202 commit 6ad558f
Show file tree
Hide file tree
Showing 35 changed files with 982 additions and 99 deletions.
8 changes: 7 additions & 1 deletion citadel.dme
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,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 @@ -2108,6 +2109,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 @@ -4467,9 +4469,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
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#define COMPONENT_ITEM_DROPPED_SUPPRESS_SOUND (1<<1)
/// From base of obj/item/pickup: (mob/user, inv_op_flags, atom/old_loc)
#define COMSIG_ITEM_PICKUP "item_pickup"
/// From base of obj/item/equipped(): (/mob/equipper, slot, inv_op_flags)
/// From base of obj/item/equipped(): (/mob/equipper, slot_id, inv_op_flags)
#define COMSIG_ITEM_EQUIPPED "item_equip"
/// From base of obj/item/unequipped(): (/mob/unequipped, slot, inv_op_flags)
/// From base of obj/item/unequipped(): (/mob/unequipped, slot_id, inv_op_flags)
#define COMSIG_ITEM_UNEQUIPPED "item_unequip"
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
/// sent at the very end of /mob/update_mobility(): (new_mobility_flags)
/**
* sent at the very end of /mob/update_mobility(): (new_mobility_flags)
*
* * only sent if mobility actually changed
*/
#define COMSIG_MOB_ON_UPDATE_MOBILITY "mob_updated_mobility"
/// sent at the very end of /mob/set_resitng(): (new_resting)
#define COMSIG_MOB_ON_SET_RESTING "mob_set_resting"
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
File renamed without changes.
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
7 changes: 4 additions & 3 deletions code/__HELPERS/type_processing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
/obj/item/mecha_parts/mecha_equipment/weapon = "//mech_weapon",
/obj/item/mecha_parts = "//mech_part",
/obj/item/organ = "//organ",
/obj/item/gun/ballistic = "//ballistic",
/obj/item/gun/energy = "//energy",
/obj/item/gun/magnetic = "//magnetic",
/obj/item/gun_attachment = "//gun-attachment",
/obj/item/gun/ballistic = "//gun-ballistic",
/obj/item/gun/energy = "//gun-energy",
/obj/item/gun/magnetic = "//gun-magnetic",
/obj/item/gun = "//gun",
/obj/item/ammo_casing = "//ammo",
/obj/item/ammo_magazine = "//magazine",
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
27 changes: 27 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,33 @@
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

/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
5 changes: 5 additions & 0 deletions code/game/rendering/legacy/radial.dm
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,17 @@ GLOBAL_LIST_EMPTY(radial_menus)
I.layer = FLOAT_LAYER
//! end
choices_icons[id] = I
else
choices_icons[id] = extract_image(E)
setup_menu(use_tooltips)

/datum/radial_menu/proc/extract_image(E)
if(!isimage(E) && !isatom(E) && !ismutableappearance(E) && !IS_APPEARANCE(E))
return null
var/mutable_appearance/MA = new /mutable_appearance(E)
if(MA)
MA.layer = HUD_LAYER_ABOVE
MA.plane = ABOVE_HUD_PLANE
MA.appearance_flags |= RESET_TRANSFORM
return MA

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

0 comments on commit 6ad558f

Please sign in to comment.