diff --git a/code/__DEFINES/dcs/signals/signals.dm b/code/__DEFINES/dcs/signals/signals.dm index 5abeb8dcf63f..e422a84975d4 100644 --- a/code/__DEFINES/dcs/signals/signals.dm +++ b/code/__DEFINES/dcs/signals/signals.dm @@ -273,7 +273,10 @@ #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 + #define OVERRIDE_UNIQUE_ACTION 1 +/// from mob/ver/do_unique_action +#define COMSIG_CLICK_SECONDARY_ACTION "secondary_action" + #define OVERRIDE_SECONDARY_ACTION 1 //from base of atom/MouseDrop(): (/atom/over, /mob/user) #define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" #define COMPONENT_NO_MOUSEDROP 1 diff --git a/code/__DEFINES/guns.dm b/code/__DEFINES/guns.dm index 3cabcfa617ce..5419ff0ee468 100644 --- a/code/__DEFINES/guns.dm +++ b/code/__DEFINES/guns.dm @@ -137,6 +137,7 @@ #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_ATTACK_HAND "attach-attack-hand" #define COMSIG_ATTACHMENT_TOGGLE "attach-toggle" diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index 50a16edc350a..6355c153374b 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -44,6 +44,7 @@ #define COMSIG_KB_HUMAN_QUICKEQUIP_DOWN "keybinding_human_quickequip_down" #define COMSIG_KB_HUMAN_QUICKEQUIPBELT_DOWN "keybinding_human_quickequipbelt_down" #define COMSIG_KB_HUMAN_UNIQUEACTION "keybinding_uniqueaction" +#define COMSIG_KB_HUMAN_SECONDARYACTION "keybinding_secondaryaction" #define COMSIG_KB_HUMAN_BAGEQUIP_DOWN "keybinding_human_bagequip_down" #define COMSIG_KB_HUMAN_EQUIPMENTSWAP_DOWN "keybinding_human_equipmentswap_down" #define COMSIG_KB_HUMAN_SUITEQUIP_DOWN "keybinding_human_suitequip_down" diff --git a/code/datums/components/attachment.dm b/code/datums/components/attachment.dm index 265aef622081..8e0038085cc5 100644 --- a/code/datums/components/attachment.dm +++ b/code/datums/components/attachment.dm @@ -13,6 +13,7 @@ var/datum/callback/on_ctrl_click var/datum/callback/on_alt_click var/datum/callback/on_examine + var/datum/callback/on_attack_hand ///Called on the parents preattack var/datum/callback/on_preattack ///Called on the parents wield @@ -39,6 +40,7 @@ datum/callback/on_unwield = null, datum/callback/on_examine = null, datum/callback/on_alt_click = null, + datum/callback/on_attack_hand = null, list/signals = null ) @@ -59,6 +61,7 @@ src.on_unwield = on_unwield src.on_examine = on_examine src.on_alt_click = on_alt_click + src.on_attack_hand = on_attack_hand ADD_TRAIT(parent, TRAIT_ATTACHABLE, "attachable") RegisterSignal(parent, COMSIG_ATTACHMENT_ATTACH, PROC_REF(try_attach)) @@ -77,6 +80,7 @@ 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)) + RegisterSignal(parent, COMSIG_ATTACHMENT_ATTACK_HAND, PROC_REF(relay_attack_hand)) for(var/signal in signals) RegisterSignal(parent, signal, signals[signal]) @@ -206,6 +210,12 @@ if(on_alt_click) return on_alt_click.Invoke(gun, user, params) +/datum/component/attachment/proc/relay_attack_hand(obj/item/parent, obj/item/gun, mob/user, params) + SIGNAL_HANDLER_DOES_SLEEP + + if(on_attack_hand) + return on_attack_hand.Invoke(gun, user, params) + /datum/component/attachment/proc/send_slot(obj/item/parent) SIGNAL_HANDLER return attachment_slot_to_bflag(slot) diff --git a/code/datums/components/attachment_holder.dm b/code/datums/components/attachment_holder.dm index e1564902c5ae..0647a20e81b4 100644 --- a/code/datums/components/attachment_holder.dm +++ b/code/datums/components/attachment_holder.dm @@ -31,6 +31,7 @@ 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_ATOM_ATTACK_HAND, PROC_REF(handle_hand_attack)) 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)) @@ -221,6 +222,13 @@ if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_UNWIELD, parent, user, params)) return TRUE +/datum/component/attachment_holder/proc/handle_hand_attack(obj/item/parent, mob/user, params) + SIGNAL_HANDLER + + for(var/obj/item/attach as anything in attachments) + if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_ATTACK_HAND, parent, user, params)) + return TRUE + /datum/component/attachment_holder/proc/handle_unique_action(obj/item/parent, mob/user, params) SIGNAL_HANDLER diff --git a/code/datums/keybinding/human.dm b/code/datums/keybinding/human.dm index e4ce3478e73a..034f1cffa2e7 100644 --- a/code/datums/keybinding/human.dm +++ b/code/datums/keybinding/human.dm @@ -36,6 +36,23 @@ current_human.do_unique_action() return TRUE +/datum/keybinding/human/secondary_action + hotkey_keys = list("ShiftSpace") + name = "secondary_action" + full_name = "Perform secondary action" + description = "" + keybind_signal = COMSIG_KB_HUMAN_SECONDARYACTION + + +/datum/keybinding/human/secondary_action/down(client/user) + . = ..() + if(.) + return + var/mob/living/carbon/human/current_human = user.mob + current_human.do_secondary_action() + return TRUE + + /datum/keybinding/human/quick_equip_belt hotkey_keys = list("ShiftE") name = "quick_equip_belt" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 17bcfd78d5c9..30fd5c8ec1d3 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1213,7 +1213,16 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb ///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) + if(SEND_SIGNAL(src,COMSIG_CLICK_UNIQUE_ACTION,user) & OVERRIDE_UNIQUE_ACTION) + return TRUE + return FALSE //return true if the proc should end here + +///Intended for interactions with guns, like swapping firemodes +/obj/item/proc/secondary_action(mob/living/user) + +///Called before unique action, if any other associated items should do a secondary action or override it. +/obj/item/proc/pre_secondary_action(mob/living/user) + if(SEND_SIGNAL(src,COMSIG_CLICK_SECONDARY_ACTION,user) & OVERRIDE_SECONDARY_ACTION) return TRUE return FALSE //return true if the proc should end here /** diff --git a/code/game/objects/items/attachments/_attachment.dm b/code/game/objects/items/attachments/_attachment.dm index 1b46b59f8db2..822879516db6 100644 --- a/code/game/objects/items/attachments/_attachment.dm +++ b/code/game/objects/items/attachments/_attachment.dm @@ -16,6 +16,10 @@ ///Component that handles most of the logic of attachments var/datum/component/attachment/attachment_comp + + /// the cell in the gun, if any + var/obj/item/stock_parts/cell/gun/gun_cell + ///If the attachment is on or off var/toggled = FALSE var/toggle_on_sound = 'sound/items/flashlight_on.ogg' @@ -57,6 +61,7 @@ CALLBACK(src, PROC_REF(on_unwield)), \ CALLBACK(src, PROC_REF(on_examine)), \ CALLBACK(src, PROC_REF(on_alt_click)), \ + CALLBACK(src, PROC_REF(on_attack_hand)), \ signals) /obj/item/attachment/Destroy() @@ -80,6 +85,7 @@ return FALSE apply_modifiers(gun, user, TRUE) + gun_cell = gun.cell playsound(src.loc, 'sound/weapons/gun/pistol/mag_insert_alt.ogg', 75, 1) return TRUE @@ -91,6 +97,7 @@ apply_modifiers(gun, user, FALSE) playsound(src.loc, 'sound/weapons/gun/pistol/mag_release_alt.ogg', 75, 1) + gun_cell = null return TRUE /obj/item/attachment/proc/on_preattack(obj/item/gun/gun, atom/target, mob/user, list/params) @@ -114,6 +121,9 @@ /obj/item/attachment/proc/on_examine(obj/item/gun/gun, mob/user, list/examine_list) return +/obj/item/attachment/proc/on_attack_hand(obj/item/gun/gun, mob/user, list/examine_list) + return FALSE + /obj/item/attachment/proc/on_alt_click(obj/item/gun/gun, mob/user, list/examine_list) AltClick(user) return TRUE diff --git a/code/game/objects/items/attachments/_gun_attachment.dm b/code/game/objects/items/attachments/_gun_attachment.dm index d7b858922d80..fc8ba428c846 100644 --- a/code/game/objects/items/attachments/_gun_attachment.dm +++ b/code/game/objects/items/attachments/_gun_attachment.dm @@ -9,13 +9,15 @@ wield_delay = 0.1 SECONDS var/weapon_type = /obj/item/gun/ballistic/shotgun/automatic var/obj/item/gun/attached_gun + var/allow_hand_interaction = FALSE //basically so the fire select shows the right icon var/underbarrel_prefix = "" -/obj/item/attachment/gun/Initialize() +/obj/item/attachment/gun/Initialize(mapload, spawn_empty = FALSE) . = ..() if(weapon_type) - attached_gun = new weapon_type(src) + attached_gun = new weapon_type(src,spawn_empty) + attached_gun.interaction_flags_item = NONE /obj/item/attachment/gun/Destroy() . = ..() @@ -64,10 +66,25 @@ /obj/item/attachment/gun/unique_action(mob/living/user) attached_gun.unique_action(user) +/obj/item/attachment/gun/on_attack_hand(obj/item/gun/gun, mob/user, list/examine_list) + if(gun.gun_firemodes[gun.firemode_index] == FIREMODE_UNDERBARREL && gun.loc == user && user.is_holding(gun) && allow_hand_interaction) + hand_attack_interaction(user) + return COMPONENT_NO_ATTACK_HAND + return + +/obj/item/attachment/gun/attack_hand(mob/user) + if(loc == user && user.is_holding(src) && allow_hand_interaction) + if(hand_attack_interaction(user)) + return COMPONENT_NO_ATTACK_HAND + return ..() + +/obj/item/attachment/gun/proc/hand_attack_interaction(mob/user) + return COMPONENT_NO_ATTACK_HAND + /obj/item/attachment/gun/on_unique_action(obj/item/gun/gun, mob/user) if(gun.gun_firemodes[gun.firemode_index] == FIREMODE_UNDERBARREL) attached_gun.unique_action(user) - return OVERIDE_UNIQUE_ACTION + return OVERRIDE_UNIQUE_ACTION /obj/item/attachment/gun/on_ctrl_click(obj/item/gun/gun, mob/user) attached_gun.toggle_safety(user,TRUE) diff --git a/code/game/objects/items/attachments/alof.dm b/code/game/objects/items/attachments/alof.dm new file mode 100644 index 000000000000..a03b32dfab70 --- /dev/null +++ b/code/game/objects/items/attachments/alof.dm @@ -0,0 +1,47 @@ +/obj/item/attachment/alof + name = "alof tube" + desc = "An antiquated spring operated magazine attachment for the HP Beacon. Has a capacity of three rounds." + icon_state = "alof" + + attach_features_flags = ATTACH_REMOVABLE_HAND + pixel_shift_x = 10 + pixel_shift_y = 0 + wield_delay = 0.1 SECONDS + var/obj/item/ammo_box/magazine/internal/shot/alof/mag + +/obj/item/attachment/alof/Initialize() + . = ..() + mag = new /obj/item/ammo_box/magazine/internal/shot/alof(src) + +/obj/item/attachment/alof/Destroy() + . = ..() + QDEL_NULL(mag) + +/obj/item/attachment/alof/on_attacked(obj/item/gun/gun, mob/user, obj/item) + . = ..() + if(istype(item,/obj/item/ammo_casing) || istype(item, /obj/item/ammo_box)) + attackby(item,user) + +/obj/item/attachment/alof/attackby(obj/item/I, mob/living/user, params) + if(istype(I,/obj/item/ammo_casing) || istype(I, /obj/item/ammo_box)) + mag.attackby(I,user) + else + return ..() +/obj/item/attachment/alof/attack_self(mob/user) + . = ..() + mag.attack_self(user) + +/obj/item/attachment/alof/on_unique_action(obj/item/gun/gun, mob/user, obj/item) + . = ..() + if(gun.bolt_locked) + var/obj/item/ammo_casing/casing_to_insert = mag.get_round(TRUE) + if(gun.magazine.give_round(casing_to_insert,TRUE)) + mag.stored_ammo -= casing_to_insert + to_chat(user,span_notice("\The [src] automatically loads another round into \the [gun]!")) + +/obj/item/ammo_box/magazine/internal/shot/alof + name = "alof tube internal magazine" + ammo_type = /obj/item/ammo_casing/a4570 + caliber = ".45-70" + max_ammo = 3 + instant_load = TRUE diff --git a/code/game/objects/items/attachments/gun_attachments/ballistic.dm b/code/game/objects/items/attachments/gun_attachments/ballistic.dm index 6697895e48ff..51e6a64de049 100644 --- a/code/game/objects/items/attachments/gun_attachments/ballistic.dm +++ b/code/game/objects/items/attachments/gun_attachments/ballistic.dm @@ -9,6 +9,12 @@ else return ..() +/obj/item/attachment/gun/ballistic/hand_attack_interaction(mob/user) + var/obj/item/gun/ballistic/ballistic_gun = attached_gun + if(ballistic_gun.magazine) + ballistic_gun.eject_magazine(user) + return ..() + /obj/item/attachment/gun/ballistic/on_examine(obj/item/gun/gun, mob/user, list/examine_list) var/obj/item/gun/ballistic/ballistic_gun = attached_gun var/gun_bolt = ballistic_gun.bolt_type @@ -24,8 +30,7 @@ /obj/item/gun/ballistic/shotgun/underbarrel name = "underbarrel ballistic gun" desc = "You shouldnt be seeing this." - semi_auto = TRUE - always_chambers = TRUE + semi_auto = FALSE casing_ejector = TRUE gunslinger_recoil_bonus = 0 default_ammo_type = /obj/item/ammo_box/magazine/internal/shot/underbarrel @@ -35,7 +40,7 @@ /obj/item/attachment/gun/ballistic/shotgun name = "underbarrel shotgun" - desc = "A single shot underbarrel shotgun for warding off anyone who gets too close for comfort." + desc = "A two shot pump underbarrel shotgun for warding off anyone who gets too close for comfort." underbarrel_prefix = "sg_" weapon_type = /obj/item/gun/ballistic/shotgun/underbarrel @@ -49,9 +54,33 @@ /obj/item/gun/ballistic/shotgun/underbarrel/grenadelauncher name = "underbarrel grenade launcher" fire_sound = 'sound/weapons/gun/general/grenade_launch.ogg' + always_chambers = TRUE default_ammo_type = /obj/item/ammo_box/magazine/internal/grenadelauncher allowed_ammo_types = list( /obj/item/ammo_box/magazine/internal/grenadelauncher ) +/obj/item/attachment/gun/ballistic/hognose + name = "PC-22 \"Hognose\"" + desc = "A compact underbarrel pistol chambered in 22lr. Holds eight rounds." + icon_state = "hognose" + weapon_type = /obj/item/gun/ballistic/automatic/pistol/himehabu/underbarrel + allow_hand_interaction = TRUE + +/obj/item/gun/ballistic/automatic/pistol/himehabu/underbarrel + name = "PC-22 \"Hognose\"" + desc = "You shouldn't be seeing this." + default_ammo_type = /obj/item/ammo_box/magazine/m22lr_himehabu/hognose + allowed_ammo_types = list( + /obj/item/ammo_box/magazine/m22lr_himehabu/hognose, + ) + +/obj/item/ammo_box/magazine/m22lr_himehabu/hognose + name = "Hognose magazine (.22 LR)" + max_ammo = 8 + +/obj/item/ammo_box/magazine/m22lr_himehabu/hognose/empty + start_empty = TRUE + + diff --git a/code/game/objects/items/attachments/gun_attachments/energy.dm b/code/game/objects/items/attachments/gun_attachments/energy.dm index 04962bb54d19..93ac00dbf857 100644 --- a/code/game/objects/items/attachments/gun_attachments/energy.dm +++ b/code/game/objects/items/attachments/gun_attachments/energy.dm @@ -5,6 +5,7 @@ icon_state = "energy" weapon_type = /obj/item/gun/energy/e_gun var/automatic_charge_overlays = TRUE + allow_hand_interaction = TRUE /obj/item/attachment/gun/energy/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/stock_parts/cell/gun)) @@ -13,6 +14,12 @@ else return ..() +/obj/item/attachment/gun/energy/hand_attack_interaction(mob/user) + var/obj/item/gun/energy/e_gun = attached_gun + if(e_gun.tac_reloads && e_gun.cell) + e_gun.eject_cell(user) + return ..() + /obj/item/attachment/gun/energy/on_examine(obj/item/gun/gun, mob/user, list/examine_list) var/obj/item/gun/energy/e_gun = attached_gun var/obj/item/ammo_casing/energy/shot = e_gun.ammo_type[e_gun.select] @@ -45,3 +52,37 @@ ammo_type = list(/obj/item/ammo_casing/energy/disabler/underbarrel, /obj/item/ammo_casing/energy/laser/underbarrel) spawn_no_ammo = TRUE +/obj/item/attachment/gun/energy/e50 + name = "underbarrel energy cannon" + desc = "An aftermarket conversion of Eoehoma Firearms' E-50 emitter cannon stripped down in order to fit on the rail mounts on other weapons. This less than orthodox conversion strips out most of the E-50's safety mechanisms to cut down on weight and size, making it dangerously prone to overheating even at its reduced power. Heat insulated gloves are reccomended." + weapon_type = /obj/item/gun/energy/laser/e50/clip/underbarrel + icon_state = "e50" + +/obj/item/gun/energy/laser/e50/clip/underbarrel + name = "underbarrel energy cannon" + desc = "Watch out, its hot." + default_ammo_type = /obj/item/stock_parts/cell/gun + allowed_ammo_types = list( + /obj/item/stock_parts/cell/gun, + /obj/item/stock_parts/cell/gun/upgraded, + /obj/item/stock_parts/cell/gun/empty, + /obj/item/stock_parts/cell/gun/upgraded/empty, + ) + +// turns out shrinking an industrial laser to this size is kinda dangerous +/obj/item/gun/energy/laser/e50/clip/underbarrel/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) + if(..()) + var/prot = FALSE + var/mob/living/carbon/human/shooter = user + if(shooter.gloves) + var/obj/item/clothing/gloves/shooter_glove = shooter.gloves + if(shooter_glove.max_heat_protection_temperature) + prot = (shooter_glove.max_heat_protection_temperature > 360) + if(HAS_TRAIT(user, TRAIT_RESISTHEAT) || HAS_TRAIT(user, TRAIT_RESISTHEATHANDS)) + prot = TRUE + var/obj/item/bodypart/affected_hand = shooter.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") + if(prot == FALSE) + if(affected_hand && affected_hand.receive_damage(0, 25)) + shooter.drop_all_held_items() + to_chat(shooter,span_danger("The [src] violently heats up as it fires, burning your hand!")) + diff --git a/code/game/objects/items/attachments/gun_attachments/flamethrower.dm b/code/game/objects/items/attachments/gun_attachments/flamethrower.dm index 22c08bdab3bc..cfb98482d112 100644 --- a/code/game/objects/items/attachments/gun_attachments/flamethrower.dm +++ b/code/game/objects/items/attachments/gun_attachments/flamethrower.dm @@ -35,7 +35,7 @@ /obj/item/attachment/gun/flamethrower/on_unique_action(obj/item/gun/gun, mob/user) if(gun.gun_firemodes[gun.firemode_index] == FIREMODE_UNDERBARREL) attached_flamethrower.unique_action(user) - return OVERIDE_UNIQUE_ACTION + return OVERRIDE_UNIQUE_ACTION /obj/item/attachment/gun/flamethrower/on_examine(obj/item/gun/gun, mob/user, list/examine_list) var/total_volume = 0 diff --git a/code/game/objects/items/attachments/gun_attachments/flaregun.dm b/code/game/objects/items/attachments/gun_attachments/flaregun.dm index 0517c2e31f8d..162786b93265 100644 --- a/code/game/objects/items/attachments/gun_attachments/flaregun.dm +++ b/code/game/objects/items/attachments/gun_attachments/flaregun.dm @@ -51,7 +51,7 @@ to_chat(user, span_notice("You unload the flare from \the [name].")) loaded_flare = null playsound(src,'sound/weapons/gun/shotgun/rack.ogg',100) - return OVERIDE_UNIQUE_ACTION + return OVERRIDE_UNIQUE_ACTION /obj/item/attachment/gun/flare/on_examine(obj/item/gun/gun, mob/user, list/examine_list) . = ..() diff --git a/code/game/objects/items/storage/filled_guncases.dm b/code/game/objects/items/storage/filled_guncases.dm index 2cd5da2a54e0..8d13330dd721 100644 --- a/code/game/objects/items/storage/filled_guncases.dm +++ b/code/game/objects/items/storage/filled_guncases.dm @@ -347,3 +347,23 @@ /obj/item/storage/guncase/energy/e10 gun_type = /obj/item/gun/energy/laser/e10 + +/* underbarrel guns */ +/obj/item/storage/guncase/underbarrel_shotgun + gun_type = /obj/item/attachment/gun/ballistic/shotgun + +/obj/item/storage/guncase/underbarrel_riot_grenade + gun_type = /obj/item/attachment/gun/riot + +/obj/item/storage/guncase/underbarrel_flamethrower + gun_type = /obj/item/attachment/gun/flamethrower + +/obj/item/storage/guncase/underbarrel_flare + gun_type = /obj/item/attachment/gun/flare + +/obj/item/storage/guncase/underbarrel_hognose + gun_type = /obj/item/attachment/gun/ballistic/hognose + mag_type = /obj/item/ammo_box/magazine/m22lr_himehabu/hognose + +/obj/item/storage/guncase/energy/underbarrel_e_gun + gun_type = /obj/item/attachment/gun/energy/e_gun diff --git a/code/game/objects/items/storage/guncases.dm b/code/game/objects/items/storage/guncases.dm index ec07ea096dc0..e8482c52fa93 100644 --- a/code/game/objects/items/storage/guncases.dm +++ b/code/game/objects/items/storage/guncases.dm @@ -26,7 +26,8 @@ var/holdable_items = list( /obj/item/gun, /obj/item/ammo_box, - /obj/item/stock_parts/cell/gun + /obj/item/stock_parts/cell/gun, + /obj/item/attachment/gun ) /obj/item/storage/guncase/Initialize(mapload) diff --git a/code/modules/cargo/blackmarket/blackmarket_items/weapons.dm b/code/modules/cargo/blackmarket/blackmarket_items/weapons.dm index 4e11d41df908..5c3e1fd2cbd9 100644 --- a/code/modules/cargo/blackmarket/blackmarket_items/weapons.dm +++ b/code/modules/cargo/blackmarket/blackmarket_items/weapons.dm @@ -161,7 +161,7 @@ name = "E-50 Energy Emitter" desc = "An Eoehoma Firearms E-50 Emitter cannon. For when you want a send a message. A really big message." item = /obj/item/gun/energy/laser/e50 - pair_item = (/datum/blackmarket_item/ammo/huge_weapon_cell) + pair_item = list(/datum/blackmarket_item/ammo/huge_weapon_cell) price_min = 4000 price_max = 7000 @@ -169,6 +169,17 @@ availability_prob = 20 spawn_weighting = FALSE +/datum/blackmarket_item/weapon/e50_underbarrel + name = "Underbarrel Energy Cannon" + desc = "The normal E-50 too big to handle for you? This underbarrel conversion cuts it down to a managable size with only a minor chance of painfully burning your hands." + item = /obj/item/attachment/gun/energy/e50 + + price_min = 4000 + price_max = 5000 + stock_max = 2 + availability_prob = 20 + spawn_weighting = FALSE + /datum/blackmarket_item/weapon/e60 name = "E-60 Disabler" desc = "Looking for a live capture? This Eoehoma Firearms E-60 disabler will get your man." diff --git a/code/modules/cargo/packs/magazines.dm b/code/modules/cargo/packs/magazines.dm index d7a34c778703..6c1a0ed66710 100644 --- a/code/modules/cargo/packs/magazines.dm +++ b/code/modules/cargo/packs/magazines.dm @@ -112,6 +112,13 @@ cost = 100 faction = /datum/faction/syndicate/scarborough_arms +/datum/supply_pack/magazine/hognose_mag + name = "Hognose Magazine Crate" + desc = "Contains a .22lr magazine for the Hognose underbarrel pistol, with a capacity of eight rounds." + contains = list(/obj/item/ammo_box/magazine/m22lr_himehabu/hognose/empty) + cost = 100 + faction = /datum/faction/syndicate/scarborough_arms + /datum/supply_pack/magazine/asp_mag name = "Asp Magazine Crate" desc = "Contains a 5.7x39mm magazine for the Asp pistol, with a capacity of 12 rounds." diff --git a/code/modules/cargo/packs/weapon_attachments.dm b/code/modules/cargo/packs/weapon_attachments.dm index 0fee8efdd8ca..2e0f36d4a5b6 100644 --- a/code/modules/cargo/packs/weapon_attachments.dm +++ b/code/modules/cargo/packs/weapon_attachments.dm @@ -38,6 +38,15 @@ faction_discount = 0 faction_locked = TRUE +/datum/supply_pack/attachment/alof + name = "Alof Tube Crate" + desc = "Contains an antiquated spring operated magazine attachment for the HP Beacon. Has a capacity of three rounds." + cost = 1000 + contains = list(/obj/item/attachment/alof) + crate_name = "alof crate" + faction = /datum/faction/srm + faction_discount = 10 + /datum/supply_pack/attachment/silencer name = "Suppressor Crate" desc = "Contains a single suppressor to be mounted on a firearm." @@ -68,30 +77,37 @@ /datum/supply_pack/attachment/shotgun name = "Underbarrel Shotgun Crate" - desc = "Contains a single shot underbarrel shotgun to be mounted on a firearm." - cost = 750 - contains = list(/obj/item/attachment/gun/ballistic/shotgun) + desc = "Contains a two shot underbarrel pump shotgun to be mounted on a firearm." + cost = 1200 + contains = list(/obj/item/storage/guncase/underbarrel_shotgun) crate_name = "underbarrel shotgun crate" +/datum/supply_pack/attachment/hognose + name = "Underbarrel Hognose Crate" + desc = "Contains an eight shot underbarrel 22lr pistol to be mounted on a firearm." + cost = 500 + contains = list(/obj/item/storage/guncase/underbarrel_hognose) + crate_name = "underbarrel hognose crate" + /datum/supply_pack/attachment/flamethrower name = "Underbarrel Flamethrower Crate" desc = "Contains a compact underbarrel flamethrower to be mounted on a firearm." cost = 750 - contains = list(/obj/item/attachment/gun/flamethrower) + contains = list(/obj/item/storage/guncase/underbarrel_flamethrower) crate_name = "underbarrel flamethrower crate" /datum/supply_pack/attachment/e_gun name = "Underbarrel Energy Gun Crate" desc = "Contains an underbarrel energy gun to be mounted on a firearm." cost = 750 - contains = list(/obj/item/attachment/gun/energy/e_gun) + contains = list(/obj/item/storage/guncase/energy/underbarrel_e_gun) crate_name = "underbarrel energy gun crate" /datum/supply_pack/attachment/riot_launcher name = "Underbarrel Riot Grenade Launcher Crate" desc = "Contains a single shot underbarrel riot grenade launcher to be mounted on a firearm." cost = 750 - contains = list(/obj/item/attachment/gun/riot) + contains = list(/obj/item/storage/guncase/underbarrel_riot_grenade) crate_name = "underbarrel riot grenade launcher crate" /datum/supply_pack/attachment/flare diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c0af36bc9f33..cf03eaa86210 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -681,6 +681,25 @@ I.unique_action(src) update_inv_hands() +/mob/verb/do_secondary_action() + set name = "Do Secondary Action" + set category = "Object" + set src = usr + + if(ismecha(loc)) + return + + if(incapacitated()) + return + + var/obj/item/I = get_active_held_item() + if(I) + if(I.pre_secondary_action(src)) + update_inv_hands() + return + I.secondary_action(src) + update_inv_hands() + /** * Get the notes of this mob * diff --git a/code/modules/projectiles/boxes_magazines/internal/shotgun.dm b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm index 5fb5a594d452..3eb67eff0b30 100644 --- a/code/modules/projectiles/boxes_magazines/internal/shotgun.dm +++ b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm @@ -64,7 +64,7 @@ /obj/item/ammo_box/magazine/internal/shot/underbarrel name = "underbarrel shotgun internal magazine" ammo_type = /obj/item/ammo_casing/shotgun/buckshot - max_ammo = 1 + max_ammo = 2 start_empty = TRUE /obj/item/ammo_box/magazine/internal/shot/sex diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index faf596a7d42e..2a9e975bc158 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -268,8 +268,12 @@ /* * Attachment */ - ///The types of attachments allowed, a list of types. SUBTYPES OF AN ALLOWED TYPE ARE ALSO ALLOWED + ///The types of attachments allowed, a list of types. SUBTYPES OF AN ALLOWED TYPE ARE ALSO ALLOWED. var/list/valid_attachments = list() + ///The types of attachments that are unique to this gun. Adds it to the base valid_attachments list. So if this gun takes a special stock, add it here. + var/list/unique_attachments = list() + ///The types of attachments that aren't allowed. Removes it from the base valid_attachments list. + var/list/refused_attachments ///Number of attachments that can fit on a given slot var/list/slot_available = ATTACHMENT_DEFAULT_SLOT_AVAILABLE ///Offsets for the slots on this gun. should be indexed by SLOT and then by X/Y @@ -344,7 +348,14 @@ /obj/item/gun/ComponentInitialize() . = ..() - AddComponent(/datum/component/attachment_holder, slot_available, valid_attachments, slot_offsets, default_attachments) + var/list/attachment_list = valid_attachments + attachment_list += unique_attachments + if(refused_attachments) + for(var/to_remove in attachment_list) + if(refused_attachments.Find(to_remove)) + attachment_list -= to_remove + + AddComponent(/datum/component/attachment_holder, slot_available, attachment_list, slot_offsets, default_attachments) AddComponent(/datum/component/two_handed) /// triggered on wield of two handed item @@ -404,6 +415,9 @@ if(has_safety) . += "The safety is [safety ? "ON" : "OFF"]. Ctrl-Click to toggle the safety." + if(gun_firemodes.len > 1) + . += "You can change the [src]'s firemode by pressing the secondary action key. By default, this is Shift + Space" + if(manufacturer) . += "It has [manufacturer] engraved on it." @@ -1124,6 +1138,10 @@ for(var/datum/action/current_action as anything in actions) current_action.UpdateButtonIcon() +/obj/item/gun/secondary_action(user) + if(gun_firemodes.len > 1) + fire_select(user) + /datum/action/item_action/toggle_firemode/UpdateButtonIcon(status_only = FALSE, force = FALSE) var/obj/item/gun/our_gun = target diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index ac9567a72e50..7be3917be354 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -291,7 +291,8 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/gun/ballistic/attack_hand(mob/user) - if(user.is_holding(src) && loc == user) + // the main calls it's own eject mag before the underbarrel. fix this + if(user.is_holding(src) && loc == user && !(gun_firemodes[firemode_index] == FIREMODE_UNDERBARREL)) if(sealed_magazine) to_chat(user, span_warning("The [magazine_wording] on [src] is sealed and cannot be accessed!")) return diff --git a/code/modules/projectiles/guns/ballistic/assault.dm b/code/modules/projectiles/guns/ballistic/assault.dm index 55c67c633d39..b36cc424b48f 100644 --- a/code/modules/projectiles/guns/ballistic/assault.dm +++ b/code/modules/projectiles/guns/ballistic/assault.dm @@ -54,15 +54,12 @@ ) //truly a doohickey for every occasion - valid_attachments = list( - /obj/item/attachment/silencer, - /obj/item/attachment/laser_sight, - /obj/item/attachment/rail_light, - /obj/item/attachment/bayonet, + unique_attachments = list ( /obj/item/attachment/scope, /obj/item/attachment/long_scope, /obj/item/attachment/energy_bayonet, ) + slot_available = list( ATTACHMENT_SLOT_MUZZLE = 1, ATTACHMENT_SLOT_RAIL = 1, diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm index 819c32b888c1..7846bec2fe34 100644 --- a/code/modules/projectiles/guns/ballistic/rifle.dm +++ b/code/modules/projectiles/guns/ballistic/rifle.dm @@ -67,6 +67,8 @@ /obj/item/gun/ballistic/rifle/attackby(obj/item/A, mob/user, params) if (!bolt_locked) + if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, A, user, params) & COMPONENT_NO_AFTERATTACK) + return TRUE to_chat(user, span_notice("The bolt is closed!")) return return ..() diff --git a/code/modules/projectiles/guns/ballistic/smg.dm b/code/modules/projectiles/guns/ballistic/smg.dm index faa52c29f268..6371895faa2a 100644 --- a/code/modules/projectiles/guns/ballistic/smg.dm +++ b/code/modules/projectiles/guns/ballistic/smg.dm @@ -101,15 +101,9 @@ wield_delay = 0.6 SECONDS wield_slowdown = SMG_SLOWDOWN - - valid_attachments = list( - /obj/item/attachment/silencer, - /obj/item/attachment/laser_sight, - /obj/item/attachment/rail_light, - /obj/item/attachment/bayonet, - /obj/item/attachment/gun, + unique_attachments = list( /obj/item/attachment/foldable_stock - ) + ) slot_available = list( ATTACHMENT_SLOT_MUZZLE = 1, @@ -164,12 +158,7 @@ wield_delay = 0.4 SECONDS - valid_attachments = list( - /obj/item/attachment/silencer, - /obj/item/attachment/laser_sight, - /obj/item/attachment/rail_light, - /obj/item/attachment/bayonet, - /obj/item/attachment/gun, + unique_attachments = list( /obj/item/attachment/foldable_stock/inteq ) default_attachments = list(/obj/item/attachment/foldable_stock/inteq) @@ -201,12 +190,7 @@ wield_delay = 0.4 SECONDS - valid_attachments = list( - /obj/item/attachment/silencer, - /obj/item/attachment/laser_sight, - /obj/item/attachment/rail_light, - /obj/item/attachment/bayonet, - /obj/item/attachment/gun, + unique_attachments = list( /obj/item/attachment/foldable_stock ) default_attachments = list(/obj/item/attachment/foldable_stock) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index a9501f4f3c7a..3cf31c46a615 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -38,7 +38,7 @@ /obj/item/attachment/rail_light, /obj/item/attachment/bayonet, /obj/item/attachment/gun, - /obj/item/attachment/sling + /obj/item/attachment/sling, ) slot_available = list( ATTACHMENT_SLOT_RAIL = 1 @@ -119,7 +119,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/gun/energy/attack_hand(mob/user) - if(!internal_magazine && loc == user && user.is_holding(src) && cell && tac_reloads) + if(!internal_magazine && loc == user && user.is_holding(src) && cell && tac_reloads && !(gun_firemodes[firemode_index] == FIREMODE_UNDERBARREL)) eject_cell(user) return return ..() diff --git a/code/modules/projectiles/guns/manufacturer/hunter_pride/ballistics.dm b/code/modules/projectiles/guns/manufacturer/hunter_pride/ballistics.dm index f391f835032b..f9cc8b484a29 100644 --- a/code/modules/projectiles/guns/manufacturer/hunter_pride/ballistics.dm +++ b/code/modules/projectiles/guns/manufacturer/hunter_pride/ballistics.dm @@ -364,6 +364,8 @@ NO_MAG_GUN_HELPER(automatic/pistol/candor/factory) /obj/item/gun/ballistic/shotgun/doublebarrel/attackby(obj/item/A, mob/user, params) if (!bolt_locked) + if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, A, user, params) & COMPONENT_NO_AFTERATTACK) + return TRUE to_chat(user, "The [bolt_wording] is shut closed!") return return ..() @@ -612,12 +614,7 @@ EMPTY_GUN_HELPER(shotgun/flamingarrow/conflagration) /obj/item/ammo_box/magazine/illestren_a850r, ) - valid_attachments = list( - /obj/item/attachment/silencer, - /obj/item/attachment/laser_sight, - /obj/item/attachment/rail_light, - /obj/item/attachment/bayonet, - /obj/item/attachment/sling, + unique_attachments = list( /obj/item/attachment/scope, /obj/item/attachment/long_scope, ) @@ -693,11 +690,7 @@ EMPTY_GUN_HELPER(shotgun/flamingarrow/conflagration) wield_slowdown = RIFLE_SLOWDOWN wield_delay = 0.65 SECONDS - valid_attachments = list( - /obj/item/attachment/silencer, - /obj/item/attachment/laser_sight, - /obj/item/attachment/rail_light, - /obj/item/attachment/bayonet, + unique_attachments = list( /obj/item/attachment/scope, /obj/item/attachment/long_scope, ) @@ -849,14 +842,11 @@ EMPTY_GUN_HELPER(shotgun/flamingarrow) gun_firemodes = list(FIREMODE_SEMIAUTO) default_firemode = FIREMODE_SEMIAUTO - valid_attachments = list( - /obj/item/attachment/silencer, - /obj/item/attachment/laser_sight, - /obj/item/attachment/rail_light, - /obj/item/attachment/bayonet, + unique_attachments = list( + /obj/item/attachment/alof, /obj/item/attachment/scope, - /obj/item/attachment/long_scope, - ) + /obj/item/attachment/long_scope) + slot_available = list( ATTACHMENT_SLOT_MUZZLE = 1, ATTACHMENT_SLOT_RAIL = 1, @@ -946,11 +936,7 @@ EMPTY_GUN_HELPER(shotgun/doublebarrel/beacon) recoil_unwielded = 4 wield_slowdown = DMR_SLOWDOWN - valid_attachments = list( - /obj/item/attachment/silencer, - /obj/item/attachment/laser_sight, - /obj/item/attachment/rail_light, - /obj/item/attachment/bayonet, + unique_attachments = list( /obj/item/attachment/scope, /obj/item/attachment/long_scope, ) diff --git a/code/modules/projectiles/guns/manufacturer/scarborough/ballistics.dm b/code/modules/projectiles/guns/manufacturer/scarborough/ballistics.dm index bbf37bfa9d00..9a50ea5c572a 100644 --- a/code/modules/projectiles/guns/manufacturer/scarborough/ballistics.dm +++ b/code/modules/projectiles/guns/manufacturer/scarborough/ballistics.dm @@ -1,4 +1,4 @@ -#define SCARBOROUGH_ATTACHMENTS list(/obj/item/attachment/silencer, /obj/item/attachment/laser_sight, /obj/item/attachment/rail_light, /obj/item/attachment/bayonet, /obj/item/attachment/energy_bayonet, /obj/item/attachment/scope, /obj/item/attachment/gun) +#define SCARBOROUGH_ATTACHMENTS list(/obj/item/attachment/silencer, /obj/item/attachment/laser_sight, /obj/item/attachment/rail_light, /obj/item/attachment/bayonet, /obj/item/attachment/energy_bayonet, /obj/item/attachment/scope, /obj/item/attachment/gun, /obj/item/attachment/sling) #define SCARBOROUGH_ATTACH_SLOTS list(ATTACHMENT_SLOT_MUZZLE = 1, ATTACHMENT_SLOT_SCOPE = 1, ATTACHMENT_SLOT_RAIL = 1) //########### PISTOLS ###########// @@ -463,12 +463,8 @@ NO_MAG_GUN_HELPER(automatic/smg/cobra/indie) show_ammo_capacity_on_magazine_sprite = TRUE manufacturer = MANUFACTURER_SCARBOROUGH - valid_attachments = list( - /obj/item/attachment/silencer, - /obj/item/attachment/laser_sight, - /obj/item/attachment/rail_light, - /obj/item/attachment/bayonet, - /obj/item/attachment/gun, + valid_attachments = SCARBOROUGH_ATTACHMENTS + unique_attachments = list( /obj/item/attachment/foldable_stock/sidewinder ) slot_available = list( diff --git a/code/modules/projectiles/guns/manufacturer/solar_armories/ballistic.dm b/code/modules/projectiles/guns/manufacturer/solar_armories/ballistic.dm index 5224183f6a34..65e8c1b0d241 100644 --- a/code/modules/projectiles/guns/manufacturer/solar_armories/ballistic.dm +++ b/code/modules/projectiles/guns/manufacturer/solar_armories/ballistic.dm @@ -1,4 +1,4 @@ -#define SOLAR_ATTACHMENTS list(/obj/item/attachment/laser_sight,/obj/item/attachment/rail_light,/obj/item/attachment/bayonet,/obj/item/attachment/energy_bayonet,/obj/item/attachment/scope,/obj/item/attachment/long_scope) +#define SOLAR_ATTACHMENTS list(/obj/item/attachment/laser_sight,/obj/item/attachment/rail_light,/obj/item/attachment/bayonet,/obj/item/attachment/energy_bayonet,/obj/item/attachment/scope,/obj/item/attachment/long_scope, /obj/item/attachment/gun, /obj/item/attachment/sling) #define SOLAR_ATTACH_SLOTS list(ATTACHMENT_SLOT_MUZZLE = 1, ATTACHMENT_SLOT_SCOPE = 1, ATTACHMENT_SLOT_RAIL = 1) ///SOLAR ARMORIES @@ -210,3 +210,4 @@ recoil_unwielded = 8 wield_slowdown = SNIPER_SLOWDOWN wield_delay = 1.3 SECONDS + diff --git a/icons/obj/guns/attachments.dmi b/icons/obj/guns/attachments.dmi index 6a396d74c98e..303ef3cd73e5 100644 Binary files a/icons/obj/guns/attachments.dmi and b/icons/obj/guns/attachments.dmi differ diff --git a/shiptest.dme b/shiptest.dme index 960f6413f9e9..4c57d703072d 100644 --- a/shiptest.dme +++ b/shiptest.dme @@ -1276,6 +1276,7 @@ #include "code\game\objects\items\wayfinding.dm" #include "code\game\objects\items\attachments\_attachment.dm" #include "code\game\objects\items\attachments\_gun_attachment.dm" +#include "code\game\objects\items\attachments\alof.dm" #include "code\game\objects\items\attachments\bayonet.dm" #include "code\game\objects\items\attachments\energy_bayonet.dm" #include "code\game\objects\items\attachments\laser_sight.dm"