From 6aab9b682730634c539cb435e25acbb9de161d38 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Fri, 7 Feb 2025 13:30:13 +1100 Subject: [PATCH] Refactors gun repair and maintenance. Gun maintenance kits; available in cargo or the security equipment vendor (#89205) 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. 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. :cl: 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. /:cl: --- .../SpaceRuins/infested_frigate.dmm | 4 +- .../components/crafting/ranged_weapon.dm | 13 +++ code/game/objects/items/gun_maintenance.dm | 82 ++++++++++++++++-- code/game/objects/items/storage/toolbox.dm | 14 --- code/modules/cargo/packs/imports.dm | 2 +- code/modules/cargo/packs/security.dm | 8 ++ code/modules/projectiles/guns/ballistic.dm | 17 ---- .../projectiles/guns/ballistic/rifle.dm | 30 +++---- code/modules/vending/security.dm | 1 + icons/obj/storage/toolbox.dmi | Bin 2300 -> 2415 bytes .../code/cargo_crates/surplus_crates.dm | 2 +- 11 files changed, 113 insertions(+), 60 deletions(-) diff --git a/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm b/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm index c925d017ad3..aa130e8ddcd 100644 --- a/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm +++ b/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm @@ -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{ diff --git a/code/datums/components/crafting/ranged_weapon.dm b/code/datums/components/crafting/ranged_weapon.dm index f5deb979cb5..22735bcc5a3 100644 --- a/code/datums/components/crafting/ranged_weapon.dm +++ b/code/datums/components/crafting/ranged_weapon.dm @@ -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 diff --git a/code/game/objects/items/gun_maintenance.dm b/code/game/objects/items/gun_maintenance.dm index 072ec395c19..77ba8035291 100644 --- a/code/game/objects/items/gun_maintenance.dm +++ b/code/game/objects/items/gun_maintenance.dm @@ -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 diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 31671ae9804..1d097be0e6d 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -389,20 +389,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)) diff --git a/code/modules/cargo/packs/imports.dm b/code/modules/cargo/packs/imports.dm index 81142d3cd47..8020e11555e 100644 --- a/code/modules/cargo/packs/imports.dm +++ b/code/modules/cargo/packs/imports.dm @@ -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, diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index 612e9f5b3f9..8227305f743 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -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." diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 9a8e1dc3aa5..18e0e8438a5 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -454,10 +454,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) @@ -688,19 +684,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 diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm index 0c0bcf18b00..2c41389c230 100644 --- a/code/modules/projectiles/guns/ballistic/rifle.dm +++ b/code/modules/projectiles/guns/ballistic/rifle.dm @@ -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) diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index a86f5562862..bf0b9dbee38 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -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, diff --git a/icons/obj/storage/toolbox.dmi b/icons/obj/storage/toolbox.dmi index 49385d5b73cf2a90b028d6fbd3931e1db29fdd28..ccc9c2cc4397e82ecf722fcea81860525f534073 100644 GIT binary patch delta 2094 zcmV+}2+{Za5$_VPHUR+g*KvwmawuRP=f0#smn1Xc; zJ97NTMcnc>pqXZSy{c9l9@TBV&392<=nyoT)bz5%J6O{>qX?G9I{Wz)-8mcn7>&(D zTQ~HqT;z=R#2phkZ(K*HEMYF+Z~Q<^-Ho`%uHO+#h#8|N9%&=Og<* z-T~kM00#$2L_t(|ob8D4J2-B*9FUlB+%A1kphHD^^uL8L|Oj- zkLfHLG@CRKMixomb%G>5VcunC$VYN#62F%1Se67oIFK7$+y`2psTL5{Tb(-Fure_-|L4Vum7PPIv> z?%-R#{zr($BMLGh8@~R>i2cVDWI{H4{Z9~wPbkQQY^3LJwOYHi7QxxYw`hDmFkB{*N)!Gu~kfFZhgp-q#qu-8BD9vYrfQl%fe_r^mk^pHf=S z6@l#f(j|Zl=|X9X0;)kn5Ks;F1p(FIP!y=u$kIh4Ko;`Tjws-y^*N4OpJolq0vZGX z4T69MMSx$!83GtbtxpxehV6%(La1h50FQu^BOukM2;d>&^9K>&>qi2Pa1nBH>q}R8 zig1y7m_;nme{zKSoZR}z&uJMxE`ANDtWzHV0000000000@IR)D=`qNWke^{(200S) zbIb*U90_?JGhmP-t9kbYqW6M=Ovr|>|0TkGNkJxL!`J@`aq)_ROvr|R{vl#89F0b3 ziz>l~{f+XGkQ0IK3pNB@;vx&2y<|ghMqFfp^H*#Lf6j@EEYKgZm#{w^XbKebQGSk8 zRDmv?I(VxUIHOYsZ?yvFbn4)(R$xen9=(8lt-xBjW&~uEDI}pxAqiy)NhnifgS^t~ z{vp%tak+c;r_7nlau89`&N>7I%pn=OTFE3;+FNFfw1!R<7%`N5@rqJIq`YALRq`MaL z?_dpl^8y>L0c8bX_yTlT%mDxZ000000002st6@EhwEsRbliW8~^|S00000 z0002K8v4&<207ZQ+*m*EmX_GxH}?Nm5h${Mzj6P6C4mzA`^NtNDgtHp_l^C36J_`J ze~tZrv%sdU!D4f>z_$1Q8CO?V83ODAu%-Qf#`yJEFR&apTmAo`-Txo36c`%>GUlKr z9~$%FMvvck5gVRByv*6p#pgE*=*Z9exq07^n;xIF1|E{3`4j*E00000004mh1)fCN z^{k8M`)_=nEi;&4rVMfI4{X=wjGD0U1d^rL1CgOeg=yOs4z^9-IFRbVpgm z>R^+HM-Z6J=0P||UqKkmeQYqBX}?oe|6PdmCy{&8o2*cK%2YL&Dgu6h%lGjXe~&z|4&P@VZ`peRBc| zWmg0M00000007?++uZkBg>CP@e;YCM-=iqHxmo_U-J2V9Ea$hk%l!6M&Xdp5Odv;= z>(B4MM~lVc&RtNV$i2fGDZl6Pdnq@4KCumf-2OW*Fj_>(3mh$6jX+**`g~$50(t%S zh`z89#f`KAIl1ZciERkv_TR}Ay1Pr}2;Ebr(EWXq(>-Mh<$OM|1%dqjf4jSQ_wN1s z_wOiVZ{bS$hYuf;oa_m?>GO#G z#OM~kjUbHx;^W7U$yFxVf0Oc0pFSmdvL^^M8etg5@%Z&PMmr(C!?pmPJ8>M45eVk$ z6#D%6bMgw)J$VX!`SK;n>7G1=Lj3K=<1u=Uu!t!%_lW=*hJpm}00$xd_Mvrw%FGM! z_fDR{m-_EE1kfVJqZ=190!ScCRxlX>ssCxc~qF07*qoM6N<$f_#qsA^-pY delta 1978 zcmV;r2Sxbr68sUcHUR+$lQ#hk4%-P=)oLWq`p{ZenA)}p#tolJI~H=;6N2a~Q&Oe#S(7l{a4`jP>(B-9I0X&Yib zX++fr<=|@n<69h|C?GSxF&%>PEI%h^p{$l=CP1VMiwyyQSM_&o4ZRvMf3bX=ytZ9- z`1+3@ahtaR)im4dRkPaU(cISCd{@=_0YRclo#7?k!II7ekDzI6i_@oI&&BY^sB|IP z+i0?KmQ&7A?ikBCWqp$GmhY*9xuwW*9R>0b9&yWhf7<>0)o;!i6M_IJhX?=w2AxSn zK~#90?VJl+8b=g{QA!tYf0)ofVq2{RS0M^*t!4=jy0p(Kn#5fG|Bva+nH_d+y92Tp zOwMboF~2YH$D6F`q@W#I}cP~GQK zPz4uNVEY-Lf^Be71$LkFDcA)UMW9}xydXG)N~K2!vFDlzRLcX{AtIF=4RDY9kcz8$$ zQfpmWLzeo&3yzMC4t_g0V$@zr0y?sQjx3;~3mhLGAO3!Lf6S=A(gfn`i?#qUWE-U+ z3+M)0l7McoBMImRd$K^K0$Z2N0BqzJOT?{uKEobX1q?_61|$Iknt-^6V+1IU zUY{;N4I6nbAyTs_Kxe>75K!vV1n3lrc`gEC{Y1c#ZbD9CebFwDkZw}>Y+{MJBh}|5 z)(1bQRm3>^e?6eHOnnG~AP9mW2!bHUcT9`Y=D?YhpHN&5oJsj9<%|PoQr@9-IdGP0 z-g-@Fzh)2<7{vO|3GO+An7|;`e?d6AU=R}+#Mkc;y1jnCPexJ+J?*TN_oW;JTCe#O zw7^9bI63E2Z~`u>!082_f>Ur&1v-8H7Iu1FLxFPMe^1VdiZ0M%ONWj|ffKfL=x7u; zWlM*SMu8ridh!N#i~>vLh8a-NmXLzBgcP(Tq@XR474lNM^@mEUE#&UWpDHJ=ke{9Y zrE+>EpUnIym~fSX8oPfRf{ zwM|F@e+Gp7^72gO@=_{*-$44&-8{uSg(dX2ig^ijyU}5a`8Ti!p1i<{dqCR(6tMsk zDdq@*AP9mW2!bF8@@RO^BI>{QEqS{A{grd2|K2yWx0Cww>G%Ja%dP$QrE^<<-}?E$ za=Eep-nZnd_4m`w_5OQ5-Tr;%pATf+zt8;he}Sx9f0?%yv+mz#{`o+3hs~ycpLL#j z|K6VWR(gI8Yq*!3M@!>T&o6uvS_Li7&%A%1b&enif*=TjAP9mWkB0pX4`_}&dA_7_V?^o{sFCk`zP0~v7g)75m~CzsSoi)v zf9LAzDn@|c0M@ks&$)hcZ5Ei%TU!19Ub_E2U@mZN5r|oXhP-FZdn-ME1V_ zpv3M%z8?t`RH_;49v}kV#G?ZAHbj1V>m^`k%zk+NH~)Ha0vbhEgdhllAP9mW-w^BE z_gaK?@4s8I^xuOZxVf4CZ@V`)f8<=vZ*S-M?X8+;j-~$|%x1GYcg6?;_l^!qelO(r zN}h*6V*i~M7|eq34Gw0mK_Ds5MIfpF9DyR-N2KYaM`o&iTQSIIwq{21nNB<0x?_TOpq)c5_t#Fu-Ie=gjGZo(zP zj$9?bg?mphKgwIc8~FYM|K<5||D9}1RY3Z$%W19%xVg{3Wa>W<$Rqt2L74%