Refactors gun repair and maintenance. Gun maintenance kits; available in cargo or the security equipment vendor (#89205)

## About The Pull Request

Misfire chance, gun jamming (currently only on boltaction rifles) and
integrity repairs are now handled by gun maintenance kits. Using a kit
on a gun resets any misfire chance or jamming, and restores the weapon's
integrity back to full.

You can find gun maintenance kits in security equipment vendors, or
order a crate of them from cargo.

You can also make a maint version to retain the improvised nature of the
previous cleaning functionaltiy.

## Why It's Good For The Game

Firstly, clearing misfires was always a little confusing for most
players, as it required a bolt of cloth to fix. That's really on me for
making that as confusing as possible.

We ended up with multiple firearm degradation mechanics, so
consolidating their restoration makes it easier for future code
maintenance.

I disliked that the kits existed but were mostly only for the sake of an
extremely niche interaction. And that interaction was, at best, kind of
niche. Expanding out their use to gun maintenance generally is honestly
better design.

## Changelog
🆑
refactor: Gun maintenance is now consolidated into a single item, the
gun maintenance kit, rather than multiple different item interactions.
It is handled on the maintenance kit itself, and not in gun code.
qol: You can order maintenance kits from cargo, and get some out of the
security equipment vendor. Helpful if someone spilled acid onto your
disabler. You can also make a makeshift one from maintenance trash.
/🆑
This commit is contained in:
necromanceranne
2025-02-07 13:30:13 +11:00
committed by GitHub
parent 2ee02682f7
commit ad5a70eac6
10 changed files with 112 additions and 59 deletions

View File

@@ -1044,8 +1044,8 @@
pixel_x = 28
},
/obj/item/storage/toolbox/syndicate,
/obj/item/storage/toolbox/maint_kit,
/obj/item/storage/toolbox/maint_kit,
/obj/item/gun_maintenance_supplies,
/obj/item/gun_maintenance_supplies,
/obj/item/storage/toolbox/electrical,
/obj/item/storage/box/lights/bulbs,
/obj/item/stack/sheet/glass{

View File

@@ -43,6 +43,19 @@
time = 5 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/riflestock
name = "Makeshift Gun Maintenance Kit"
tool_behaviors = list(TOOL_WRENCH, TOOL_WELDER, TOOL_SCREWDRIVER)
result = /obj/item/gun_maintenance_supplies/makeshift
reqs = list(
/obj/item/stack/sheet/iron = 5,
/obj/item/stack/sticky_tape = 1,
/obj/item/pipe = 1,
/obj/item/stack/sheet/cloth = 2,
)
time = 5 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/advancedegun
name = "Advanced Energy Gun"
result = /obj/item/gun/energy/e_gun/nuclear

View File

@@ -1,6 +1,78 @@
/obj/item/gun_maintenance_supplies
name = "gun maintenance supplies"
desc = "plastic box containing gun maintenance supplies and spare parts. Use them on a rifle to clean it."
icon = 'icons/obj/storage/box.dmi'
icon_state = "plasticbox"
w_class = WEIGHT_CLASS_SMALL
name = "gun maintenance kit"
desc = "A toolbox containing gun maintenance supplies and spare parts. Can be applied to firearms to maintain them."
icon = 'icons/obj/storage/toolbox.dmi'
icon_state = "maint_kit"
inhand_icon_state = "ammobox"
lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi'
force = 12
throwforce = 12
throw_speed = 2
throw_range = 7
demolition_mod = 1.25
w_class = WEIGHT_CLASS_BULKY
drop_sound = 'sound/items/handling/ammobox_drop.ogg'
pickup_sound = 'sound/items/handling/ammobox_pickup.ogg'
/// How many times we can use this maintenance kit to maintain a gun
var/uses = 3
/// THe maximum uses, used for our examine text.
var/max_uses = 3
/obj/item/gun_maintenance_supplies/examine(mob/user)
. = ..()
. += span_info("This kit has [uses] uses out of [max_uses] left.")
/obj/item/gun_maintenance_supplies/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
. = ..()
if(. & ITEM_INTERACT_ANY_BLOCKER)
return ITEM_INTERACT_BLOCKING
if(!isgun(interacting_with))
balloon_alert(user, "not a gun!")
return ITEM_INTERACT_BLOCKING
var/obj/item/gun/gun_to_fix = interacting_with
var/gun_is_damaged = gun_to_fix.get_integrity() < gun_to_fix.max_integrity
var/use_charge = FALSE
if(gun_is_damaged)
gun_to_fix.repair_damage(gun_to_fix.max_integrity)
use_charge = TRUE
if(istype(gun_to_fix, /obj/item/gun/ballistic))
var/obj/item/gun/ballistic/ballistic_gun_to_fix = gun_to_fix
if(ballistic_gun_to_fix.misfire_probability > initial(ballistic_gun_to_fix.misfire_probability))
ballistic_gun_to_fix.misfire_probability = initial(ballistic_gun_to_fix.misfire_probability)
if(istype(ballistic_gun_to_fix, /obj/item/gun/ballistic/rifle/boltaction))
var/obj/item/gun/ballistic/rifle/boltaction/rifle_to_fix = ballistic_gun_to_fix
if(rifle_to_fix.jammed)
rifle_to_fix.jammed = FALSE
rifle_to_fix.unjam_chance = initial(rifle_to_fix.unjam_chance)
rifle_to_fix.jamming_chance = initial(rifle_to_fix.jamming_chance)
use_charge = TRUE
if(!use_charge)
balloon_alert(user, "no need for repair!")
return ITEM_INTERACT_BLOCKING
balloon_alert(user, "maintenance complete")
use_the_kit()
return ITEM_INTERACT_SUCCESS
/obj/item/gun_maintenance_supplies/proc/use_the_kit()
uses --
if(!uses)
qdel(src)
/obj/item/gun_maintenance_supplies/makeshift
name = "makeshift gun maintenance kit"
desc = "A toolbox containing enough supplies to juryrig repairs on firearms. Can be applied to firearms to maintain them. \
The tools are a little basic, and the materials low-quality, but it gets the job done."
icon_state = "maint_kit_makeshift"
inhand_icon_state = "toolbox_blue"
uses = 1
max_uses = 1

View File

@@ -387,20 +387,6 @@
name = "4.6x30mm AP ammo box"
ammo_to_spawn = /obj/item/ammo_box/magazine/wt550m9/wtap
/obj/item/storage/toolbox/maint_kit
name = "gun maintenance kit"
desc = "It contains some gun maintenance supplies"
icon_state = "maint_kit"
inhand_icon_state = "ammobox"
has_latches = FALSE
drop_sound = 'sound/items/handling/ammobox_drop.ogg'
pickup_sound = 'sound/items/handling/ammobox_pickup.ogg'
/obj/item/storage/toolbox/maint_kit/PopulateContents()
new /obj/item/gun_maintenance_supplies(src)
new /obj/item/gun_maintenance_supplies(src)
new /obj/item/gun_maintenance_supplies(src)
//repairbot assembly
/obj/item/storage/toolbox/tool_act(mob/living/user, obj/item/tool, list/modifiers)
if(!istype(tool, /obj/item/assembly/prox_sensor))

View File

@@ -218,7 +218,7 @@
/obj/item/ammo_box/strilka310/surplus,
/obj/item/storage/toolbox/ammobox/strilka310,
/obj/item/storage/toolbox/ammobox/strilka310/surplus,
/obj/item/storage/toolbox/maint_kit,
/obj/item/gun_maintenance_supplies,
/obj/item/clothing/suit/armor/vest/russian,
/obj/item/clothing/head/helmet/rus_helmet,
/obj/item/clothing/shoes/russian,

View File

@@ -113,6 +113,14 @@
)
crate_name = "security supply crate"
/datum/supply_pack/security/maintenance_kits
name = "Gun Maintenance Kits"
desc = "Three gun maintenance kits for the repair and maintenance of a firearm."
access_view = ACCESS_BRIG
contains = list(/obj/item/gun_maintenance_supplies = 3)
cost = CARGO_CRATE_VALUE * 2
crate_name = "gun maintenance kit crate"
/datum/supply_pack/security/firingpins
name = "Standard Firing Pins Crate"
desc = "Upgrade your arsenal with 10 standard firing pins."

View File

@@ -452,10 +452,6 @@
if (sawoff(user, A))
return
if(misfire_probability && istype(A, /obj/item/stack/sheet/cloth))
if(guncleaning(user, A))
return
return FALSE
/obj/item/gun/ballistic/proc/check_if_held(mob/user)
@@ -685,19 +681,6 @@ GLOBAL_LIST_INIT(gun_saw_types, typecacheof(list(
update_appearance()
return TRUE
/obj/item/gun/ballistic/proc/guncleaning(mob/user, obj/item/A)
if(misfire_probability == initial(misfire_probability))
balloon_alert(user, "it's already clean!")
return
user.changeNext_move(CLICK_CD_MELEE)
balloon_alert(user, "cleaning...")
if(do_after(user, 10 SECONDS, target = src))
misfire_probability = initial(misfire_probability)
balloon_alert(user, "fouling cleaned out")
return TRUE
/obj/item/gun/ballistic/wrench_act(mob/living/user, obj/item/I)
if(!can_modify_ammo)
return

View File

@@ -77,17 +77,16 @@
update_appearance()
/obj/item/gun/ballistic/rifle/boltaction/attack_self(mob/user)
if(can_jam)
if(jammed)
if(prob(unjam_chance))
jammed = FALSE
unjam_chance = 10
else
unjam_chance += 10
balloon_alert(user, "jammed!")
playsound(user,'sound/items/weapons/jammed.ogg', 75, TRUE)
return FALSE
..()
if(jammed)
if(prob(unjam_chance))
jammed = FALSE
unjam_chance = initial(unjam_chance)
else
unjam_chance += 10
balloon_alert(user, "jammed!")
playsound(user,'sound/items/weapons/jammed.ogg', 75, TRUE)
return FALSE
return ..()
/obj/item/gun/ballistic/rifle/boltaction/process_fire(mob/user)
if(can_jam)
@@ -105,15 +104,6 @@
. = ..()
if(istype(item, /obj/item/gun_maintenance_supplies))
if(!can_jam)
balloon_alert(user, "can't jam!")
return
if(do_after(user, 10 SECONDS, target = src))
user.visible_message(span_notice("[user] finishes maintaining [src]."))
jamming_chance = initial(jamming_chance)
qdel(item)
/obj/item/gun/ballistic/rifle/boltaction/blow_up(mob/user)
. = FALSE
if(chambered?.loaded_projectile)

View File

@@ -17,6 +17,7 @@
/obj/item/restraints/legcuffs/bola/energy = 7,
/obj/item/clothing/gloves/tackler = 5,
/obj/item/holosign_creator/security = 2,
/obj/item/gun_maintenance_supplies = 2,
)
contraband = list(
/obj/item/clothing/glasses/sunglasses = 2,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB