From 2bb4dfe76c8619b7a495a344301ff04e1352d054 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Thu, 15 Jun 2023 05:00:05 +0200 Subject: [PATCH] Expanding the Experimental MODsuit Bepis Node with three new modules. (#75801) ## About The Pull Request So, I've had this idea to make a contribution to the Bepis feature with some modsuit stuff. The gimmicky stuff is ok and a good way to even out the better content since it has game of chance design it has (you can find those disks in space anyway so...). However, the Experimental MODsuit node feels very underwhelming right now, compared to how big that feature is. This PR adds three MOD modules to the Experimental MODsuit node, plus two more: - Magneto Charger: While the Modsuit is activated, each step the user takes will charge the installed power cell by a tiny bit, enough to sustain a standard modsuit of generic slow speed with only a few, easy modules installed. It won't work in zero G, while flying, pulled by someone else, on a conveyor belt, riding a vehicle or crawling on the floor, though. - Recycler: It collects (most) garbage and casings off the ground and recycles them into material sheets that can be dispensed on an adjacent location or storage with with Middle Mouse Button. Doesn't clean debris, and scuffed because most trash doesn't yield material anyway. - - It also has two subtypes, unbound from the node: one that dispenses riot foam darts and can be found on the black market, and another that dispenses the more innocuous foam darts, rarely found in maints. - Shooting Assistant: A configurable module. On Stormtrooper mode, it will give the user a faster fire rate (the double tap trait) at the cost of accuracy. On Sharpshooter mode, it will improve the user accuracy and make their shots ricochet against walls at least once (if the hit atom allows that, that is, e.g. lasers don't ricochet against iron walls), at the cost of movement speed. Both modes also prevent the user from dual wielding guns. To make the Stormtrooper mode stackable with the poor aim quirk and refrain from making a new trait for the sharpshooter mode, the gun spread code in gun.dm has also received a little refactor and cleanup. Also, it's been tested. ## Why It's Good For The Game The Experimental MODsuit node is quite shabby and could use something extra to make it more appealing to MODsuit enjoyers. Also doubles down as a small addition to the black market and maint loot, and code cleanup, since gun code gives off some garbled vibes. ## Changelog :cl: add: Expanded the Experimental MODsuit Bepis node with three new modules: Magneto Charger, Recycler and Shooting Assistant. add: Added a Riot Foam Recycler module to the black market, as well a more innocuous version as maint loot. /:cl: --- code/__DEFINES/dcs/signals/signals_object.dm | 4 +- code/__DEFINES/materials.dm | 4 + code/__DEFINES/traits.dm | 6 +- code/_globalvars/traits.dm | 1 - code/datums/components/material_container.dm | 48 +++-- code/datums/quirks/negative_quirks.dm | 12 +- .../objects/effects/spawners/random/mod.dm | 3 +- .../cargo/markets/market_items/misc.dm | 9 + code/modules/mod/modules/modules_general.dm | 178 ++++++++++++++++++ code/modules/mod/modules/modules_maint.dm | 13 ++ code/modules/mod/modules/modules_security.dm | 113 +++++++++++ code/modules/movespeed/modifiers/items.dm | 3 + .../projectiles/boxes_magazines/ammo_boxes.dm | 10 + code/modules/projectiles/gun.dm | 35 ++-- code/modules/projectiles/guns/ballistic.dm | 7 +- code/modules/projectiles/guns/energy.dm | 2 +- code/modules/projectiles/projectile.dm | 9 +- .../religion/honorbound/honorbound_trauma.dm | 2 +- .../religion/sparring/sparring_datum.dm | 2 +- .../designs/mechfabricator_designs.dm | 27 +++ code/modules/research/techweb/all_nodes.dm | 5 +- icons/mob/clothing/modsuit/mod_modules.dmi | Bin 14775 -> 15636 bytes icons/obj/clothing/modsuit/mod_modules.dmi | Bin 52753 -> 54439 bytes icons/obj/weapons/guns/toy.dmi | Bin 771 -> 869 bytes 24 files changed, 443 insertions(+), 50 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 684adf17300..e5e65a067d8 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -288,8 +288,10 @@ ///called in /obj/item/gun/fire_gun (user, target, flag, params) #define COMSIG_GUN_TRY_FIRE "gun_try_fire" #define COMPONENT_CANCEL_GUN_FIRE (1<<0) -///called in /obj/item/gun/process_fire (src, target, params, zone_override) +///called in /obj/item/gun/process_fire (src, target, params, zone_override, bonus_spread_values) #define COMSIG_MOB_FIRED_GUN "mob_fired_gun" + #define MIN_BONUS_SPREAD_INDEX 1 + #define MAX_BONUS_SPREAD_INDEX 2 ///called in /obj/item/gun/process_fire (user, target, params, zone_override) #define COMSIG_GUN_FIRED "gun_fired" ///called in /obj/item/gun/process_chamber (src) diff --git a/code/__DEFINES/materials.dm b/code/__DEFINES/materials.dm index 6ffcc733928..f58ec028dbb 100644 --- a/code/__DEFINES/materials.dm +++ b/code/__DEFINES/materials.dm @@ -61,6 +61,10 @@ #define MATERIAL_SOURCE(mat) "[mat.name]_material" +///Special return values of [/datum/component/material_container/insert_item] +#define MATERIAL_INSERT_ITEM_NO_MATS -1 +#define MATERIAL_INSERT_ITEM_NO_SPACE -2 +#define MATERIAL_INSERT_ITEM_FAILURE 0 // Slowdown values. diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 8ca1e485263..7261cacc66f 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -486,6 +486,11 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_HATED_BY_DOGS "hated_by_dogs" /// Mobs with this trait will not be immobilized when held up #define TRAIT_NOFEAR_HOLDUPS "no_fear_holdup" +/// Mobs with this trait won't be able to dual wield guns. +#define TRAIT_NO_GUN_AKIMBO "no_gun_akimbo" + +/// Projectile with this trait will always hit the defined zone of a struck living mob. +#define TRAIT_ALWAYS_HIT_ZONE "always_hit_zone" // METABOLISMS // Various jobs on the station have historically had better reactions @@ -656,7 +661,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_SELF_AWARE "self_aware" #define TRAIT_FREERUNNING "freerunning" #define TRAIT_SKITTISH "skittish" -#define TRAIT_POOR_AIM "poor_aim" #define TRAIT_PROSOPAGNOSIA "prosopagnosia" #define TRAIT_TAGGER "tagger" #define TRAIT_PHOTOGRAPHER "photographer" diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index ea14400d5d4..9b82322e99a 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -156,7 +156,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE, "TRAIT_FREERUNNING" = TRAIT_FREERUNNING, "TRAIT_SKITTISH" = TRAIT_SKITTISH, - "TRAIT_POOR_AIM" = TRAIT_POOR_AIM, "TRAIT_PROSOPAGNOSIA" = TRAIT_PROSOPAGNOSIA, "TRAIT_TAGGER" = TRAIT_TAGGER, "TRAIT_PHOTOGRAPHER" = TRAIT_PHOTOGRAPHER, diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index 404b2e99709..27a85480c13 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -30,11 +30,22 @@ var/datum/callback/precondition /// A callback invoked after materials are inserted into this container var/datum/callback/after_insert + /// A callback invoked after sheets are retrieve from this container + var/datum/callback/after_retrieve /// The material container flags. See __DEFINES/materials.dm. var/mat_container_flags /// Sets up the proper signals and fills the list of materials with the appropriate references. -/datum/component/material_container/Initialize(list/init_mats, max_amt = 0, _mat_container_flags=NONE, list/allowed_mats=init_mats, list/allowed_items, datum/callback/_insertion_check, datum/callback/_precondition, datum/callback/_after_insert) +/datum/component/material_container/Initialize(list/init_mats, + max_amt = 0, + _mat_container_flags=NONE, + list/allowed_mats=init_mats, + list/allowed_items, + datum/callback/_insertion_check, + datum/callback/_precondition, + datum/callback/_after_insert, + datum/callback/_after_retrieve) + if(!isatom(parent)) return COMPONENT_INCOMPATIBLE @@ -52,6 +63,7 @@ insertion_check = _insertion_check precondition = _precondition after_insert = _after_insert + after_retrieve = _after_retrieve for(var/mat in init_mats) //Make the assoc list material reference -> amount var/mat_ref = GET_MATERIAL_REF(mat) @@ -79,6 +91,8 @@ QDEL_NULL(precondition) if(after_insert) QDEL_NULL(after_insert) + if(after_retrieve) + QDEL_NULL(after_retrieve) return ..() @@ -240,40 +254,40 @@ /// Proc specifically for inserting items, returns the amount of materials entered. /datum/component/material_container/proc/insert_item(obj/item/weapon, multiplier = 1, breakdown_flags = mat_container_flags) if(QDELETED(weapon)) - return -1 + return MATERIAL_INSERT_ITEM_NO_MATS multiplier = CEILING(multiplier, 0.01) var/obj/item/target = weapon var/material_amount = get_item_material_amount(target, breakdown_flags) * multiplier if(!material_amount) - return -1 + return MATERIAL_INSERT_ITEM_NO_MATS var/obj/item/stack/item_stack if(isstack(weapon) && !has_space(material_amount)) //not enugh space split and feed as many sheets possible item_stack = weapon var/space_left = max_amount - total_amount if(!space_left) - return -2 + return MATERIAL_INSERT_ITEM_NO_SPACE var/material_per_sheet = material_amount / item_stack.amount var/sheets_to_insert = round(space_left / material_per_sheet) if(!sheets_to_insert) - return -2 + return MATERIAL_INSERT_ITEM_NO_SPACE target = split_stack(item_stack, sheets_to_insert) material_amount = get_item_material_amount(target, breakdown_flags) * multiplier if(!has_space(material_amount)) - return -2 + return MATERIAL_INSERT_ITEM_NO_SPACE last_inserted_id = insert_item_materials(target, multiplier, breakdown_flags) if(!isnull(last_inserted_id)) if(after_insert) - after_insert.Invoke(target, last_inserted_id, material_amount) + after_insert.Invoke(target, last_inserted_id, material_amount, src) qdel(target) //item gone return material_amount else if(!isnull(item_stack) && item_stack != target) //insertion failed, merge the split stack back into the original var/obj/item/stack/inserting_stack = target item_stack.add(inserting_stack.amount) qdel(inserting_stack) - return 0 + return MATERIAL_INSERT_ITEM_FAILURE /** * Inserts the relevant materials from an item into this material container. @@ -406,8 +420,8 @@ return total_amount_save - total_amount /// For spawning mineral sheets at a specific location. Used by machines to output sheets. -/datum/component/material_container/proc/retrieve_sheets(sheet_amt, datum/material/M, atom/target = null) - if(!M.sheet_type) +/datum/component/material_container/proc/retrieve_sheets(sheet_amt, datum/material/material, atom/target = null) + if(!material.sheet_type) return 0 //Add greyscale sheet handling here later if(sheet_amt <= 0) return 0 @@ -415,18 +429,20 @@ if(!target) var/atom/parent_atom = parent target = parent_atom.drop_location() - if(materials[M] < (sheet_amt * SHEET_MATERIAL_AMOUNT)) - sheet_amt = round(materials[M] / SHEET_MATERIAL_AMOUNT) + if(materials[material] < (sheet_amt * SHEET_MATERIAL_AMOUNT)) + sheet_amt = round(materials[material] / SHEET_MATERIAL_AMOUNT) var/count = 0 while(sheet_amt > MAX_STACK_SIZE) - new M.sheet_type(target, MAX_STACK_SIZE, null, list((M) = SHEET_MATERIAL_AMOUNT)) + var/obj/item/stack/sheet/new_sheets = new material.sheet_type(target, MAX_STACK_SIZE, null, list((material) = SHEET_MATERIAL_AMOUNT)) + after_retrieve?.Invoke(new_sheets) count += MAX_STACK_SIZE - use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, M) + use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, material) sheet_amt -= MAX_STACK_SIZE if(sheet_amt >= 1) - new M.sheet_type(target, sheet_amt, null, list((M) = SHEET_MATERIAL_AMOUNT)) + var/obj/item/stack/sheet/new_sheets = new material.sheet_type(target, sheet_amt, null, list((material) = SHEET_MATERIAL_AMOUNT)) + after_retrieve?.Invoke(new_sheets) count += sheet_amt - use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, M) + use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, material) return count diff --git a/code/datums/quirks/negative_quirks.dm b/code/datums/quirks/negative_quirks.dm index 648043ec41a..33ec7178c4b 100644 --- a/code/datums/quirks/negative_quirks.dm +++ b/code/datums/quirks/negative_quirks.dm @@ -534,11 +534,21 @@ desc = "You've never hit anything you were aiming for in your life." icon = FA_ICON_BULLSEYE value = -4 - mob_trait = TRAIT_POOR_AIM medical_record_text = "Patient possesses a strong tremor in both hands." hardcore_value = 3 mail_goodies = list(/obj/item/cardboard_cutout) // for target practice +/datum/quirk/poor_aim/add(client/client_source) + RegisterSignal(quirk_holder, COMSIG_MOB_FIRED_GUN, PROC_REF(on_mob_fired_gun)) + +/datum/quirk/poor_aim/remove(client/client_source) + UnregisterSignal(quirk_holder, COMSIG_MOB_FIRED_GUN) + +/datum/quirk/poor_aim/proc/on_mob_fired_gun(mob/user, obj/item/gun/gun_fired, target, params, zone_override, list/bonus_spread_values) + SIGNAL_HANDLER + bonus_spread_values[MIN_BONUS_SPREAD_INDEX] += 10 + bonus_spread_values[MAX_BONUS_SPREAD_INDEX] += 35 + /datum/quirk/prosopagnosia name = "Prosopagnosia" desc = "You have a mental disorder that prevents you from being able to recognize faces at all." diff --git a/code/game/objects/effects/spawners/random/mod.dm b/code/game/objects/effects/spawners/random/mod.dm index 7b5c3cc5852..bcd2eaa3ff2 100644 --- a/code/game/objects/effects/spawners/random/mod.dm +++ b/code/game/objects/effects/spawners/random/mod.dm @@ -12,7 +12,8 @@ /obj/item/mod/module/balloon = 1, /obj/item/mod/module/paper_dispenser = 1, /obj/item/mod/module/hat_stabilizer = 2, - /obj/item/mod/module/stamp = 1 + /obj/item/mod/module/stamp = 1, + /obj/item/mod/module/recycler/donk/safe = 1, ) /obj/effect/spawner/random/mod/maint/Initialize(mapload) diff --git a/code/modules/cargo/markets/market_items/misc.dm b/code/modules/cargo/markets/market_items/misc.dm index d5ee60f49e4..d0ba6b26e9f 100644 --- a/code/modules/cargo/markets/market_items/misc.dm +++ b/code/modules/cargo/markets/market_items/misc.dm @@ -41,6 +41,15 @@ stock_max = 8 availability_prob = 60 +/datum/market_item/misc/donk_recycler + name = "MOD Riot Foam Dart Recycler Module" + desc = "If you love toy guns, hate cleaning and got a MODsuit, this module is a must have." + item = /obj/item/mod/module/recycler/donk + price_min = CARGO_CRATE_VALUE * 2 + price_max = CARGO_CRATE_VALUE * 4.5 + stock_max = 2 + availability_prob = 30 + /datum/market_item/misc/holywater name = "Flask of holy water" desc = "Father Lootius' own brand of ready-made holy water." diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 65f7eb7c191..8054ccdc78c 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -596,3 +596,181 @@ /obj/item/mod/module/signlang_radio/on_suit_deactivation(deleting = FALSE) REMOVE_TRAIT(mod.wearer, TRAIT_CAN_SIGN_ON_COMMS, MOD_TRAIT) + +///A module that recharges the suit by an itsy tiny bit whenever the user takes a step. Originally called "magneto module" but the videogame reference sounds cooler. +/obj/item/mod/module/joint_torsion + name = "MOD joint torsion ratchet module" + desc = "A compact, weak AC generator that charges the suit's internal cell through the power of deambulation. It doesn't work in zero G." + icon_state = "joint_torsion" + complexity = 1 + incompatible_modules = list(/obj/item/mod/module/joint_torsion) + var/power_per_step = DEFAULT_CHARGE_DRAIN * 0.3 + +/obj/item/mod/module/joint_torsion/on_suit_activation() + if(!(mod.wearer.movement_type & (FLOATING|FLYING))) + RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + /// This way we don't even bother to call on_moved() while flying/floating + RegisterSignal(mod.wearer, COMSIG_MOVETYPE_FLAG_ENABLED, PROC_REF(on_movetype_flag_enabled)) + RegisterSignal(mod.wearer, COMSIG_MOVETYPE_FLAG_DISABLED, PROC_REF(on_movetype_flag_disabled)) + +/obj/item/mod/module/joint_torsion/on_suit_deactivation(deleting = FALSE) + UnregisterSignal(mod.wearer, list(COMSIG_MOVABLE_MOVED, COMSIG_MOVETYPE_FLAG_ENABLED, COMSIG_MOVETYPE_FLAG_DISABLED)) + +/obj/item/mod/module/joint_torsion/proc/on_movetype_flag_enabled(datum/source, flag, old_state) + SIGNAL_HANDLER + if(!(old_state & (FLOATING|FLYING)) && flag & (FLOATING|FLYING)) + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + +/obj/item/mod/module/joint_torsion/proc/on_movetype_flag_disabled(datum/source, flag, old_state) + SIGNAL_HANDLER + if(old_state & (FLOATING|FLYING) && !(mod.wearer.movement_type & (FLOATING|FLYING))) + RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + +/obj/item/mod/module/joint_torsion/proc/on_moved(mob/living/carbon/human/wearer, atom/old_loc, movement_dir, forced) + SIGNAL_HANDLER + //Shouldn't work if the wearer isn't really walking/running around. + if(forced || wearer.throwing || wearer.body_position == LYING_DOWN || wearer.buckled || CHECK_MOVE_LOOP_FLAGS(wearer, MOVEMENT_LOOP_OUTSIDE_CONTROL)) + return + mod.core.add_charge(power_per_step) + +/// Module that shoves garbage inside its material container when the user crosses it, and eject the recycled material with MMB. +/obj/item/mod/module/recycler + name = "MOD recycler module" + desc = "An innovative garbage collection module that recycles gathered trash into usable material. \ + Doesn't work on debris and some items. May recycle live ammunition. \ + Activate on a nearby turf or storage to unload stored material." + icon_state = "recycler" + module_type = MODULE_ACTIVE + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + complexity = 2 + incompatible_modules = list(/obj/item/mod/module/recycler) + overlay_state_inactive = "module_recycler" + overlay_state_active = "module_recycler" + /// A multiplier of the amount of material extracted from the item + var/efficiency = 1 + /// Items that will be collected + var/list/allowed_item_types = list( + /obj/item/trash, + /obj/item/shard, + /obj/item/light, + /obj/item/broken_bottle, + /obj/item/ammo_casing, + /obj/item/cigbutt, + ) + /// Materials that will be extracted. + var/list/accepted_mats = list( + /datum/material/iron, + /datum/material/glass, + /datum/material/silver, + /datum/material/plasma, + /datum/material/gold, + /datum/material/diamond, + /datum/material/plastic, + /datum/material/uranium, + /datum/material/bananium, + /datum/material/titanium, + /datum/material/bluespace, + ) + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = PROC_REF(on_obj_entered), + COMSIG_ATOM_INITIALIZED_ON = PROC_REF(on_atom_initialized_on), + ) + var/datum/component/connect_loc_behalf/connector + +/obj/item/mod/module/recycler/Initialize(mapload) + . = ..() + AddComponent(/datum/component/material_container, accepted_mats, 50 * SHEET_MATERIAL_AMOUNT, MATCONTAINER_EXAMINE|MATCONTAINER_NO_INSERT, _after_retrieve=CALLBACK(src, PROC_REF(attempt_insert_storage))) + +/obj/item/mod/module/recycler/on_activation() + . = ..() + if(!.) + return + connector = AddComponent(/datum/component/connect_loc_behalf, mod.wearer, loc_connections) + RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(on_wearer_moved)) + +/obj/item/mod/module/recycler/on_deactivation(display_message, deleting = FALSE) + . = ..() + if(!.) + return + QDEL_NULL(connector) + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(on_wearer_moved)) + +/obj/item/mod/module/recycler/proc/on_wearer_moved(datum/source, atom/old_loc, dir, forced) + SIGNAL_HANDLER + for(var/obj/item/item in mod.wearer.loc) + if(!is_type_in_list(item, allowed_item_types)) + return + insert_trash(item) + +/obj/item/mod/module/recycler/proc/on_obj_entered(atom/new_loc, atom/movable/arrived, atom/old_loc) + SIGNAL_HANDLER + if(!is_type_in_list(arrived, allowed_item_types)) + return + insert_trash(arrived) + +/obj/item/mod/module/recycler/proc/on_atom_initialized_on(atom/loc, atom/new_atom) + SIGNAL_HANDLER + if(!is_type_in_list(new_atom, allowed_item_types)) + return + //Give the new atom the time to fully initialize and maybe live if the wearer moves away. + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/mod/module/recycler, insert_trash_if_nearby), new_atom), 0.5 SECONDS) + +/obj/item/mod/module/recycler/proc/insert_trash_if_nearby(atom/new_atom) + if(new_atom && mod?.wearer && new_atom.loc == mod.wearer.loc) + insert_trash(new_atom) + +/obj/item/mod/module/recycler/proc/insert_trash(obj/item/item) + var/datum/component/material_container/container = GetComponent(/datum/component/material_container) + var/retrieved = container.insert_item(item, multiplier = efficiency, breakdown_flags = BREAKDOWN_FLAGS_RECYCLER) + if(retrieved == MATERIAL_INSERT_ITEM_NO_MATS) //even if it doesn't have any material to give, trash is trash. + qdel(item) + playsound(src, SFX_RUSTLE, 50, TRUE, -5) + +/obj/item/mod/module/recycler/on_select_use(atom/target) + . = ..() + if(!.) + return + if(!target?.atom_storage) + target = get_turf(target) + if(!isopenturf(target) || !mod.wearer.Adjacent(target)) + return FALSE + dispense(target) + +/obj/item/mod/module/recycler/proc/dispense(atom/target) + var/datum/component/material_container/container = GetComponent(/datum/component/material_container) + if(container.retrieve_all(target)) + balloon_alert(mod.wearer, "material dispensed") + playsound(src, 'sound/machines/microwave/microwave-end.ogg', 50, TRUE) + return + balloon_alert(mod.wearer, "not enough material") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE) + +/obj/item/mod/module/recycler/proc/attempt_insert_storage(obj/item/to_drop) + if(!isturf(to_drop.loc) && !to_drop.loc.atom_storage?.attempt_insert(to_drop, mod.wearer, override = TRUE)) + to_drop.forceMove(to_drop.loc.drop_location()) + +///A black market variant of the above that dispenses riot foam dart boxes +/obj/item/mod/module/recycler/donk + name = "MOD riot foam dart recycler module" + desc = "A mod module collects and repackages fired foam darts (and garbage) into half-sized boxes of riot foam darts. \ + Activate on a nearby turf or storage to unload stored ammo boxes." + icon_state = "donk_recycler" + overlay_state_inactive = "module_donk_recycler" + overlay_state_active = "module_donk_recycler" + efficiency = 0.7 // Stops getting as many riot foam darts as one consumes. + accepted_mats = list(/datum/material/iron) + ///The type of ammo box that it dispenses + var/ammobox_type = /obj/item/ammo_box/foambox/riot/mini + ///The cost of each dispensed ammo box + var/required_amount = SHEET_MATERIAL_AMOUNT*12.5 + +/obj/item/mod/module/recycler/donk/dispense(atom/target) + var/datum/component/material_container/container = GetComponent(/datum/component/material_container) + if(!container.use_amount_mat(required_amount, /datum/material/iron)) + balloon_alert(mod.wearer, "not enough material") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE) + return + var/obj/item/ammo_box/product = new ammobox_type(target) + attempt_insert_storage(product) + balloon_alert(mod.wearer, "ammo box dispensed.") + playsound(src, 'sound/machines/microwave/microwave-end.ogg', 50, TRUE) diff --git a/code/modules/mod/modules/modules_maint.dm b/code/modules/mod/modules/modules_maint.dm index 9829321f640..b973beeb603 100644 --- a/code/modules/mod/modules/modules_maint.dm +++ b/code/modules/mod/modules/modules_maint.dm @@ -334,3 +334,16 @@ QDEL_IN(mod.wearer, FLY_TIME) #undef FLY_TIME + +/obj/item/mod/module/recycler/donk/safe + name = "MOD foam dart recycler module" + desc = "A mod module that collects and repackages fired foam darts into half-sized ammo boxes. \ + Activate on a nearby turf or storage to unload stored ammo boxes." + icon_state = "donk_safe_recycler" + overlay_state_inactive = "module_donk_safe_recycler" + overlay_state_active = "module_donk_safe_recycler" + complexity = 1 + efficiency = 1 + allowed_item_types = list(/obj/item/ammo_casing/caseless/foam_dart) + ammobox_type = /obj/item/ammo_box/foambox/mini + required_amount = SMALL_MATERIAL_AMOUNT*2.5 diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index a861f5f639e..4c58f516785 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -385,3 +385,116 @@ creatures_detected++ playsound(mod.wearer, 'sound/effects/ping_hit.ogg', vol = 75, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE) // Should be audible for the radius of the sonar to_chat(mod.wearer, span_notice("You slam your fist into the ground, sending out a sonic wave that detects [creatures_detected] living beings nearby!")) + +#define SHOOTING_ASSISTANT_OFF "Currently Off" +#define STORMTROOPER_MODE "Quick Fire Stormtrooper" +#define SHARPSHOOTER_MODE "Slow Ricochet Sharpshooter" + +/** + * A module that enhances the user's ability with firearms, with a couple drawbacks: + * In 'Stormtrooper' mode, the user will be given faster firerate, but lower accuracy. + * In 'Sharpshooter' mode, the user will have better accuracy and ricochet to his shots, but slower movement speed. + * Both modes prevent the user from dual wielding guns. + */ +/obj/item/mod/module/shooting_assistant + name = "MOD shooting assistant module" + desc = "A botched prototype meant to boost the TGMC crayon eaters' ability with firearms. \ + It has only two modes available in its configurations: \ + 'Quick Fire Stormtrooper' and 'Slow Ricochet Sharpshooter', \ + both incompatible with dual wielding firearms." + icon_state = "shooting_assistant" + module_type = MODULE_PASSIVE + complexity = 3 + incompatible_modules = list(/obj/item/mod/module/shooting_assistant) + var/selected_mode = SHOOTING_ASSISTANT_OFF + ///Association list, the assoc values are the balloon alerts shown to the user when the mode is set. + var/static/list/available_modes = list( + SHOOTING_ASSISTANT_OFF = "assistant off", + STORMTROOPER_MODE = "stormtrooper mode", + SHARPSHOOTER_MODE = "sharpshooter mode", + ) + +/obj/item/mod/module/shooting_assistant/get_configuration() + . = ..() + .["shooting_mode"] = add_ui_configuration("Mode", "list", selected_mode, assoc_to_keys(available_modes)) + +/obj/item/mod/module/shooting_assistant/configure_edit(key, value) + switch(key) + if("shooting_mode") + set_shooting_mode(value) + +/obj/item/mod/module/shooting_assistant/proc/set_shooting_mode(new_mode) + if(new_mode == selected_mode || !mod.active) + return + if(new_mode != SHOOTING_ASSISTANT_OFF && !mod.get_charge()) + balloon_alert(mod.wearer, "no charge!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return + + //Remove the effects of the previously selected mode + if(mod.active) + remove_mode_effects() + + balloon_alert(mod.wearer, available_modes[new_mode]) + selected_mode = new_mode + + //Apply the effects of the new mode + if(mod.active) + apply_mode_effects() + +/obj/item/mod/module/shooting_assistant/proc/apply_mode_effects() + switch(selected_mode) + if(SHOOTING_ASSISTANT_OFF) + idle_power_cost = 0 + if(STORMTROOPER_MODE) + idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.4 + mod.wearer.add_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_DOUBLE_TAP), MOD_TRAIT) + RegisterSignal(mod.wearer, COMSIG_MOB_FIRED_GUN, PROC_REF(stormtrooper_fired_gun)) + if(SHARPSHOOTER_MODE) + idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.6 + mod.wearer.add_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_NICE_SHOT), MOD_TRAIT) + RegisterSignal(mod.wearer, COMSIG_MOB_FIRED_GUN, PROC_REF(sharpshooter_fired_gun)) + RegisterSignal(mod.wearer, COMSIG_PROJECTILE_FIRER_BEFORE_FIRE, PROC_REF(apply_ricochet)) + mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/shooting_assistant) + +/obj/item/mod/module/shooting_assistant/proc/remove_mode_effects() + switch(selected_mode) + if(STORMTROOPER_MODE) + UnregisterSignal(mod.wearer, COMSIG_MOB_FIRED_GUN) + mod.wearer.remove_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_DOUBLE_TAP), MOD_TRAIT) + if(SHARPSHOOTER_MODE) + UnregisterSignal(mod.wearer, list(COMSIG_MOB_FIRED_GUN, COMSIG_PROJECTILE_FIRER_BEFORE_FIRE)) + mod.wearer.remove_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_NICE_SHOT), MOD_TRAIT) + mod.wearer.remove_movespeed_modifier(/datum/movespeed_modifier/shooting_assistant) + +/obj/item/mod/module/shooting_assistant/drain_power(amount) + . = ..() + if(!.) + set_shooting_mode(SHOOTING_ASSISTANT_OFF) + +/obj/item/mod/module/shooting_assistant/on_suit_activation() + apply_mode_effects() + +/obj/item/mod/module/shooting_assistant/on_suit_deactivation(deleting = FALSE) + remove_mode_effects() + +/obj/item/mod/module/shooting_assistant/proc/stormtrooper_fired_gun(mob/user, obj/item/gun/gun_fired, target, params, zone_override, list/bonus_spread_values) + SIGNAL_HANDLER + bonus_spread_values[MIN_BONUS_SPREAD_INDEX] += 15 + bonus_spread_values[MAX_BONUS_SPREAD_INDEX] += 25 + +/obj/item/mod/module/shooting_assistant/proc/sharpshooter_fired_gun(mob/user, obj/item/gun/gun_fired, target, params, zone_override, list/bonus_spread_values) + SIGNAL_HANDLER + bonus_spread_values[MIN_BONUS_SPREAD_INDEX] -= 20 + bonus_spread_values[MAX_BONUS_SPREAD_INDEX] -= 10 + +/obj/item/mod/module/shooting_assistant/proc/apply_ricochet(mob/user, obj/projectile/projectile, datum/fired_from, atom/clicked_atom) + SIGNAL_HANDLER + projectile.ricochets_max += 1 + projectile.min_ricochets += 1 + projectile.ricochet_incidence_leeway = 0 //allows the projectile to bounce at any angle. + ADD_TRAIT(projectile, TRAIT_ALWAYS_HIT_ZONE, MOD_TRAIT) + +#undef SHOOTING_ASSISTANT_OFF +#undef STORMTROOPER_MODE +#undef SHARPSHOOTER_MODE diff --git a/code/modules/movespeed/modifiers/items.dm b/code/modules/movespeed/modifiers/items.dm index e1ec36c3a15..433200e3223 100644 --- a/code/modules/movespeed/modifiers/items.dm +++ b/code/modules/movespeed/modifiers/items.dm @@ -16,3 +16,6 @@ /datum/movespeed_modifier/sphere multiplicative_slowdown = -0.5 + +/datum/movespeed_modifier/shooting_assistant + multiplicative_slowdown = 0.5 diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm index 87ec9e59bcf..f04df872798 100644 --- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm +++ b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm @@ -113,7 +113,17 @@ max_ammo = 40 custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT*5) +/obj/item/ammo_box/foambox/mini + icon_state = "foambox_mini" + max_ammo = 20 + custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT*2.5) + /obj/item/ammo_box/foambox/riot icon_state = "foambox_riot" ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*25) + +/obj/item/ammo_box/foambox/riot/mini + icon_state = "foambox_riot_mini" + max_ammo = 20 + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*12.5) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 30752d2868c..3de0aad078d 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -306,9 +306,8 @@ //DUAL (or more!) WIELDING var/bonus_spread = 0 var/loop_counter = 0 - if(ishuman(user) && user.combat_mode) - var/mob/living/carbon/human/H = user - for(var/obj/item/gun/gun in H.held_items) + if(user.combat_mode && !HAS_TRAIT(user, TRAIT_NO_GUN_AKIMBO)) + for(var/obj/item/gun/gun in user.held_items) if(gun == src || gun.weapon_weight >= WEAPON_MEDIUM) continue else if(gun.can_trigger_gun(user, akimbo_usage = TRUE)) @@ -354,7 +353,7 @@ /obj/item/gun/proc/recharge_newshot() return -/obj/item/gun/proc/process_burst(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0) +/obj/item/gun/proc/process_burst(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", random_spread = 0, burst_spread_mult = 0, iteration = 0) if(!user || !firing_burst) firing_burst = FALSE return FALSE @@ -367,10 +366,11 @@ if(chambered.harmful) // Is the bullet chambered harmful? to_chat(user, span_warning("[src] is lethally chambered! You don't want to risk harming anyone...")) return + var/sprd if(randomspread) - sprd = round((rand(0, 1) - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread)) + sprd = round((rand(0, 1) - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (random_spread)) else //Smart spread - sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread)) + sprd = round((((burst_spread_mult/burst_size) * iteration) - (0.5 + (burst_spread_mult * 0.25))) * (random_spread)) before_firing(target,user) if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd, src)) shoot_with_empty_chamber(user) @@ -392,8 +392,12 @@ return TRUE /obj/item/gun/proc/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) + var/base_bonus_spread = 0 if(user) - SEND_SIGNAL(user, COMSIG_MOB_FIRED_GUN, src, target, params, zone_override) + var/list/bonus_spread_values = list(base_bonus_spread, bonus_spread) + SEND_SIGNAL(user, COMSIG_MOB_FIRED_GUN, src, target, params, zone_override, bonus_spread_values) + base_bonus_spread = bonus_spread_values[MIN_BONUS_SPREAD_INDEX] + bonus_spread = bonus_spread_values[MAX_BONUS_SPREAD_INDEX] SEND_SIGNAL(src, COMSIG_GUN_FIRED, user, target, params, zone_override) @@ -403,17 +407,10 @@ return //Vary by at least this much - var/base_bonus_spread = 0 - var/sprd = 0 - var/randomized_gun_spread = 0 - var/rand_spr = rand() - if(user && HAS_TRAIT(user, TRAIT_POOR_AIM)) //Nice job hotshot - bonus_spread += 35 - base_bonus_spread += 10 - - if(spread) - randomized_gun_spread = rand(0,spread) var/randomized_bonus_spread = rand(base_bonus_spread, bonus_spread) + var/randomized_gun_spread = spread ? rand(0, spread) : 0 + var/total_random_spread = max(0, randomized_bonus_spread + randomized_gun_spread) + var/burst_spread_mult = rand() var/modified_delay = fire_delay if(user && HAS_TRAIT(user, TRAIT_DOUBLE_TAP)) @@ -422,14 +419,14 @@ if(burst_size > 1) firing_burst = TRUE for(var/i = 1 to burst_size) - addtimer(CALLBACK(src, PROC_REF(process_burst), user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), modified_delay * (i - 1)) + addtimer(CALLBACK(src, PROC_REF(process_burst), user, target, message, params, zone_override, total_random_spread, burst_spread_mult, i), modified_delay * (i - 1)) else if(chambered) if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal. if(chambered.harmful) // Is the bullet chambered harmful? to_chat(user, span_warning("[src] is lethally chambered! You don't want to risk harming anyone...")) return - sprd = round((rand(0, 1) - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread)) + var/sprd = round((rand(0, 1) - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * total_random_spread) before_firing(target,user) if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd, src)) shoot_with_empty_chamber(user) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 876adfdd3b5..cdb2c393f0b 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -249,10 +249,11 @@ stack_trace("Trying to move a qdeleted casing of type [casing.type]!") chambered = null else if(casing_ejector || !from_firing) - casing.forceMove(drop_location()) //Eject casing onto ground. - casing.bounce_away(TRUE) - SEND_SIGNAL(casing, COMSIG_CASING_EJECTED) chambered = null + casing.forceMove(drop_location()) //Eject casing onto ground. + if(!QDELETED(casing)) + casing.bounce_away(TRUE) + SEND_SIGNAL(casing, COMSIG_CASING_EJECTED) else if(empty_chamber) chambered = null if (chamber_next_round && (magazine?.max_ammo > 1)) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 4ea530c51a4..d7bdfa6ad2a 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -190,7 +190,7 @@ process_chamber() // If the gun was drained and then recharged, load a new shot. return ..() -/obj/item/gun/energy/process_burst(mob/living/user, atom/target, message = TRUE, params = null, zone_override="", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0) +/obj/item/gun/energy/process_burst(mob/living/user, atom/target, message = TRUE, params = null, zone_override="", randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0) if(!chambered && can_shoot()) process_chamber() // Ditto. return ..() diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 0bbe5b221b3..d704586af1d 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -94,6 +94,8 @@ var/ricochets = 0 /// how many times we can ricochet max var/ricochets_max = 0 + /// how many times we have to ricochet min (unless we hit an atom we can ricochet off) + var/min_ricochets = 0 /// 0-100 (or more, I guess), the base chance of ricocheting, before being modified by the atom we shoot and our chance decay var/ricochet_chance = 0 /// 0-1 (or more, I guess) multiplier, the ricochet_chance is modified by multiplying this after each ricochet @@ -449,8 +451,9 @@ store_hitscan_collision(point_cache) return TRUE - var/distance = get_dist(T, starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. - def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. + if(!HAS_TRAIT(src, TRAIT_ALWAYS_HIT_ZONE)) + var/distance = get_dist(T, starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. + def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. return process_hit(T, select_target(T, A, A), A) // SELECT TARGET FIRST! @@ -684,7 +687,7 @@ var/chance = ricochet_chance * A.receive_ricochet_chance_mod if(firer && HAS_TRAIT(firer, TRAIT_NICE_SHOT)) chance += NICE_SHOT_RICOCHET_BONUS - if(prob(chance)) + if(ricochets < min_ricochets || prob(chance)) return TRUE return FALSE diff --git a/code/modules/religion/honorbound/honorbound_trauma.dm b/code/modules/religion/honorbound/honorbound_trauma.dm index 350e02c29f6..fc0f317154c 100644 --- a/code/modules/religion/honorbound/honorbound_trauma.dm +++ b/code/modules/religion/honorbound/honorbound_trauma.dm @@ -168,7 +168,7 @@ SIGNAL_HANDLER punishment(user, spell_cast.school) -/datum/brain_trauma/special/honorbound/proc/staff_check(mob/user, obj/item/gun/gun_fired, target, params, zone_override) +/datum/brain_trauma/special/honorbound/proc/staff_check(mob/user, obj/item/gun/gun_fired, target, params, zone_override, list/bonus_spread_values) SIGNAL_HANDLER if(!istype(gun_fired, /obj/item/gun/magic)) return diff --git a/code/modules/religion/sparring/sparring_datum.dm b/code/modules/religion/sparring/sparring_datum.dm index 5d4853b378e..f292293f90c 100644 --- a/code/modules/religion/sparring/sparring_datum.dm +++ b/code/modules/religion/sparring/sparring_datum.dm @@ -149,7 +149,7 @@ flubbed_match() ///someone used a gun -/datum/sparring_match/proc/gun_violation(datum/offender) +/datum/sparring_match/proc/gun_violation(mob/offender, obj/item/gun/gun_fired, target, params, zone_override, list/bonus_spread_values) SIGNAL_HANDLER violation(offender, "using guns") diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 6bfaa526e11..3ad98ff733f 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1925,6 +1925,33 @@ RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_SUPPLY ) +/datum/design/module/joint_torsion + name = "Joint Torsion Ratchet Module" + id = "mod_joint_torsion" + materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/gold = SMALL_MATERIAL_AMOUNT*2.5, /datum/material/titanium = SMALL_MATERIAL_AMOUNT) + build_path = /obj/item/mod/module/joint_torsion + category = list( + RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUITS_MISC + ) + +/datum/design/module/recycler + name = "Recycler Module" + id = "mod_recycler" + materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT, /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/plastic = SMALL_MATERIAL_AMOUNT*2) + build_path = /obj/item/mod/module/recycler + category = list( + RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_SERVICE + ) + +/datum/design/module/shooting_assistant + name = "Shooting Assistant Module" + id = "mod_shooting" + materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT, /datum/material/silver = SMALL_MATERIAL_AMOUNT*2, /datum/material/gold = SMALL_MATERIAL_AMOUNT, /datum/material/diamond = SMALL_MATERIAL_AMOUNT) + build_path = /obj/item/mod/module/shooting_assistant + category = list( + RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_SECURITY + ) + //MODsuit anomalock modules /datum/design/module/mod_antigrav name = "Anti-Gravity Module" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 82baf4d2b81..719887a0864 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -2301,10 +2301,13 @@ /datum/techweb_node/mod_experimental id = "mod_experimental" display_name = "Experimental Modular Suits" - description = "Applications of experimentality when creating MODsuits has created these..." + description = "Applications of experimentality when creating MODsuits have created these..." prereq_ids = list("base") design_ids = list( "mod_disposal", + "mod_joint_torsion", + "mod_recycler", + "mod_shooting", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) hidden = TRUE diff --git a/icons/mob/clothing/modsuit/mod_modules.dmi b/icons/mob/clothing/modsuit/mod_modules.dmi index 1001ae77d2d6587ed77d841c90ef354b7b0d9cc6..3c41dac86b2d46e84beef76b16bd466062fdf23e 100644 GIT binary patch literal 15636 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 n-KaJ4(s8GR8v1*s`(DivS9_vHTrD=du% literal 14775 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 diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi index 037e7fe69634af68cdcaa8fa45a80a23deb22746..8df1945d8009f60c69b27fc13f56b9bea9699aa3 100644 GIT binary patch delta 14874 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

XD;wZo;`&s?%Lfn3jMef%@=!vk&ubK$$sDaZw zPiUmDiy$;3+iM67g;QVL>}~s|8_N;U>f>ou>~t6>v<|_pW;Vd8XU&k15D=jgqh_cH z1eAj9R!VysE8bApai)F#z`BTZV)K^!@BKJ_m2etsHQQ#AvZ-cqGVY^Bv~Eg>S43Rn zi5lw;mbjA7%2&wqwh!5=@;8aQoH|5%Td;V5C+l{Ie7oDuU zJ98L`wPdiCFi@lN$5;>@7-;H7#BQ`dZ?P0#lzApPj-MHMase%cI>aHxblubk)(&6AKMwSy<(CGK$CmDb~{xC@sxehcqliKg1tE@2_WWhma3<8D-_j%y}ck5uI3tD}Pxn97BTk z&wcOEql$Y1-Qo>g=5ZJjT8{ImqA%3&aBDV|$ip?g zTmgvD(1}wBcQu{)vzpr4*ubpbGs0G1{J2qziibnxc5=HWTJFavfwND99X0c;2VktZ zrLOH#XVYNcTI1#ex%i&YeXC(52hQO-?D~0R@=F#@k;my-jr~?On;Qbj5HLb(Y_Wa} zlD-E3G!pi#D|uDrE)DmN;=Uk-fJj+mM>3?S3lI4)I?|#vsC69?oNuwH3`yuk(;GVi z2!5?Ww|w!%K@K6u?C;BlHYkK}7%_VM;R}#$v2)0@yL?yqgnI8{RWCy$~l z>I^v1U8nE7-bi)6jpQJ;(9t}v#?=e^6&e?xQNnRxm7->Yr8E;_6f$**GV}x7Wgl-o z)Vj{_yq@rIH})nd%cD_ThZ{ijdx^*l|5CFLe&dC*3rdY^BYW?i;p<@+2* z%=vkU{-Trm_9(iBvwv7PPS9H@4WS2d4R+UVtgOJCNT(0USLZ9o1}SunT`pAKm8GNP zRIyqz)J~tPx!M9U{B8prtK_|`HSodwg?9cJk_3BsB8M|@R_XUln0>67@9y!4zu-;u z10p|^4&lfGGHR2)kH+lG{oZkoa3FupP`54KglVCV$q4L0#%R$7i4TrJBc9h>m+dfK z3^HDgSJ;z?9YSbbqZ-P2Js>is+p@TY%*a<#|AY#1kFhgTgfd3e2!P5PA zNhN}UKLL2HF=jfz0q%5B?bgyjcwetbEb2MX&GPxyzeSM)WKZw(9go{Bm|$uWoSJ(clPv(=MuOyiT=7hX|O_~4Bl>>a@40k-F(DRMio1h$FV`Joq z7E|8eUQ%S2hQ+Eg|7NGRe<_7XMrmLJ4z5Q*;o*dd%wG)8Re^e%usZJQ=&hYivvV;K ze}-8vN(w-jo?f_)DnAV8fgVqR)#=efkRTTovekE$(s+^)p)jZA!bj4aPxxiBdf?=kM_w)E|+F-AEbDM)yW zr~2Z79FdG-MJI?N?QAby|9!3v7n-jLxs4_Wt>1yP!T@tsPslPqKQiAN!QF9&j~!qe za?a5|9=XG3-S0SAkH|p-d2Z#YANs?oz$fjttil6po>m2SnliNxPpMSQHk4;)gh&7b zV-s3qGv3GIGVTAy5i`5;*{Ab$7!ne&k05(}uM3e*tz|p=Xf{DKa4VbSuz6}c4mogj zbnKAEC+{36`#nBe#Lyfy&&qn66>)=wiz~^h*WmxJD=cYlPD^(8JY~}b<=<=`QKLa% zcWnu+s;a8lU@A*^bo7*NFgRdarZscVmY8_+K-|-B%#_ZeELjOq8}amiLWf`OVL>8g zWo5}aMfndxi_jVOd9SXqRHlV21T!*jReq>ZY@?W;X`m>xgtlsO8|$RNyw5xAgpRi$ zL$bfxV<0(Erh3(L5L@?U>Z>X&aD5b;vg^e*LeCN1&>+~|XTiYs;W~EN=wuG{T+U8Z zA_pTv);{8z%vV*F!{(2iq@qOjIyOE&JO%U#sZh))T}*J?s0tP)hj?NJB#{9T&4C&) zvRLifyzk%9gTJ`BAJ5n_nM7`NBaLZYxoL=6UpIL)&-beRz5?y$0OVf~c z*93+rk+7hI%$g{U<9_7 zX6&oE7E|Z4ca*qf$4ii~q`|H9(|x}D$9NJ0ngvZgg&Mh@YMywv=?0hre__j>A0=m4~ZU#0q;kWmJFjDhEMfgPwGZ=N@&~l zt}XC7hT$VWh6B{CkwMSkp58h=BaD1`*rWe&z(FvrNOk$e5AuTn)mgsCqCbLC%wiNT zv7+rB{h8v177_7#y!nwl8L7O4SSOvV)|{AFSsS%9=&jM@!U_1ySgXq%EP$*pYoR1D%_-sz0e0tsv2d?I&NHinlKiGGl@2`)d29oGEgmvppjx+dg znJ?H!(6^h7Av=aH0asgZhORPArv!;;L_mYdD)0ON{6SX7J`%?9EbB3rj6t9wx!Z2V zD3x4nYuMVuJ5J=sAra8N=nczguOZHu@-45a4~vlj#7#Ol_|}9%ED};|^e}HOHQx@( z2_p*3it?!$ys5tgkt2v0skP&iS9^*$OjX`ibV7!E%-dV(OZ*twam{IOX)l<8_EG!v zksBq!Ob*x2I94o}NXWV}!Rr^ZX@+lrOY*e z#^TZx#wV01PMVtdLmBvzZuXqVo*9C=GM|T$dZ$Y?X@OUZHlOHqel2(c?MnmPkQ6}L zuH0{LQ6&G>$~zng!2bRWXFAKu>bpQdX&v!vL5FW{Vc&-vKMajj%-oaT`d7&(4e%`_ zRjIA-KM}j?x4?$$2m&e^A4BVo7EL@Ox#Pv;Nyj`&6t=XgLi(%z2m+^g7|X4GnVbW< z)OcLNKCCY!B!}uD6~Cmc0({BZ^e-Xax7UAyu!vxC*Uv35SBupwzPO$&c%lRz?$d&n zs6T{S3N$;@cR3lyE{rAb1Fc5!=YDhMWNMNSw9u!z+7^4oqFX=(Gb=au08p1?;C_13 z3#ZkwwSq)7sFCjKs>dib{L}g%sOc8)Poq+E8d*pq5w3$160&=&3i|K{Vlp&G(cRP2 zF?dkXT+0h`Od!<+<^L#peDL&DKg)K14W~F&b9x3EAhEI4#UcM!wNRevs9JDxR1}|( z00kf*AVC9j^NSY`phc)D7!csvUeK7Bn1af`#KTFHkpsJv(qD0adtVs^PhjY_z+gQOux4xTh|5+Elqg5a(~whoYGd`wA)Lw=_&Bo->XlNFM`kw zYx@WRkhx`qDu+ofxXV51f&%crw04evMdB#wd6iQ^iA2gb6$C!vaar}Uv)M6_8#2L9 ze~%9Th`L=RN_m1uj=!5xmc1_}em4J2XJj#Gt4X776@Vn$obt;abb6*W@Dq9G+&+HG zDx?$wDAHy-M_S>tJmPCuGx7^GzY5A)&5dC;q&t(<=?_o7z4&M**KA5P(8wx&OA|~h zznW^ZR2hVFzUCK21~D_8EjPQpLt7v9mYPsy!)(d{l*}F{YPfaGvs4sxs{LKGMK2e4 zar`;-@gd*`5CMH_Vse7(`o{ZO8)%bfVCK&2 zRWPrHq*w?|RRSht8b%`^?fXx-i6?2{Kvs}dG+l#G&SwkI9Or@@}CjxhB{kMvuWS+u+?CWqXBOJ z7KgN(5i$pwBRBdc5ClgErdTNM4HipSk!6_OY*u5pn7I2)jIXSl1>MU#X1z_e11}s- zkT+pk0>gMxmV!Y=H$!Qs4kD%dO8JQH+?kA-)6;WJO^8n3@?P0;_MPnLtWaVWYJZ$KB9RR zpF=2*wh(wNMy{wIV?jtB&M3yUYoP8zTK?1!TflmT85<@GD&UB5h1?*Eg0XI|_oVI- zOl7wCDKd(Ghr_1Gy7|In#FK#d2M)MA-J3eAmFmZn6G6bwCxSG&JgdBPA#*% z_kG4Dj`cKwfZ-psFLa@s)KmI7w@6o{$#MjGy~37CZ1%g*7E8{o&D^X0!t{2dEIRj5 zk47m@Qq_+&biO47JOcFMn@jUiVy@N;3_hN(|23N2p|iPP+GL@W19dDZ-KdNB+VP64 ziLI0;OcfoSU(UK7rNt^8Id&<*&M7L&eFZbhkS&wI80l(>;u{wfQOiDEE$3}0*%vD>o>4!6m1AU~h?HVI$^s!w#wUBw%H zj{CQc>VHdag{9xl4q&7r-l!s*ffc_1_4rg`c9nJ;rKvmP-zrRo>!$0z@3S(46y+df zotE^`ly+)jY+9QGC+F5>-x{VkGgISiPqL{MHXcO#5T z`7f(#U3@(C0|t*E5olB~_BY|umh&O6&>Z|RYv0#x-f}2vesXR;RX&=x`czv>q!C{y zd}Vso(n>j{{zaK*?9&RCRO6ZtL<)Yr{m)yEjWTu;4_-K-JQyg44#)jmPIxj*K~?t_ z?@8}zUl7EfSn!0Q`&<+#gPq4tA~CJ`dlpJy_h<>*q!$t#6H&La0s5%NEHN%6hf3B{ z=WxguJvzm2fwpJ54!`y8ghz&K-ic?D-o1N&O)uofX5}En-+jS zZNkDks2j^!P{4Z%lOIzB3od~$K2Cvt)bhZqj&G~=dh&k<_b0a$mWxS={6DI)c!8ZL zN@!jDj$1gc-Y+;+V3y-+GTB*NNC6s1s;7D)Xf;(XnQQRSBT80GxBnni8N-k%RI zUJDi$&iH75`j;#MWO~}iDKLj%D-i6%JRIw}uUqd0g7{ebftb-Z#JlYEWm=<2aSQ|_OVpAUTNyR0La9y7e!=Y z{#4WFAsYy!?k>^sy^iW!|Df=V3yxnqL$?_8uqC|@5EZQqctbDL1MGoG-(6{?f=UV*`azpM|5Yb+rK4^KY^VVFi=qoX}Wl^sJagcr1r`3+oySH zjauNJ+Q%4NcR1RC_EbcD?^-LWD#~#zdvNQ!&p{3@l8MYFxT*BkEj8Qzu;u<@5_^qS z-q>9Tp?xKd%@hNX88#|H5#m~BB8s6+f8kyZuQw7*+v9i*AqTd#2{R6+yg(Ko<@mLFB;$c7$KUx_i|h5knu$mr6H~m&74fs6Xn^|#q$_xe#jX$l5LaX+MAiQy z0e`c-J#M)W6+a-LXMJ{f0xNEJ{K@F~;?#aN;pc_Yc(5K2aDPToA{9mh=DZnsAsjiSM-m6%wZyNcWomAW%?Ijg%{1G3Rs~6D7wQ~(-H5@Pu@+-ue zE$7+w)=^i9j#7=;efJm7U5VR7%ckrvpq_mf!ABl`Nxam;q9JC=QpSCf&*P#kobe~= z`?ua?iBtS%PqD;{c?(!zAMybbLaxxD@f24GWKll4DmLJ}d-rbbTs;eimMcQQS{+_B5o$Uqs#wTtgYwp^5_v`HV)4eUVno?a_>f- z+QSS7lxao~> z_y@Buz;lt+-q8 zZlN4p|HSOhAt8g3mfMJ+jmPFWwwa^i-W3tBGp*GU%f!qgdDNiXQ>p`J4P`C@LURfh z7St5Y38?16*(=a+chP9w!Y_u+e@pmtz@gkoL*cbvhHuf>V{?D*P|A zbp*WaNEue6N4h^uQ2iecw-p3W*2tL<&)}7^_@#CBxsf$Py%55wo`-w1Ya(2x$36I9 z(m8vP2)fKq$9Fy}#LZ7!eG#`J)SqI2PcEm}4^1^^iccJU>K<*|h1Pb1drxrYoxSe7 zqs|hn*jsVu3E6#DO1^!hrKry0cKm<^lHn%D{8ZDJUHhDP`)*wLXoBAB4#?P9*T>7c zmtGb6YN78_N#8M7<nS-F}_koN5melJB6V)h!~ zNXE#NsgLlDM8wf?A*=H7ePTu-6>0K4P*UB2OiDRJs90$1I4xqrp9Cw-o>&y?#U;aa zDk2|Z9EfZ}Fr}mZk=ZuDCC69Fz5{s%(L>U)ZLwXijTt00TvJL=ca?AqJGj>uR*8xV zb+f_f+2>3d+hWo^Y#9J;Dk@mSfH*&K(0^5sRp>W=6(Lk-f=rsKcE8kHS<}jp^oqjb#4U!(UEmT;( zMNo9ALWwo8z-c@=kG??24i~}dq8M;7nAUPT?@`O`<`tyJ{Wv22C=z9rQM;V}G zpGJIo0yXV$Q?m_$m^_gc1Gw%w)T(UQRFFZ9wf~61?PdxNbS9mjqzL-0iNS8oA)tc# zNbp|m$JI`juhg^VVaRnw^t<~XV9bW#>s7PAwA?5>Ke`l$#FD1`cD^|tFb`c}VCp(r ztmo+Of?;dBXGGCP@27yuRd^dgGoowTh|*A?>8#|5UR3_~*K;2JeQ1cGpYsZ2bfXg_ ze5g4>I_5lRkmINZnOmRZD2^6vZgT7`Hm%BD9K~i&5}Tl)PGPuWaLsLJ;wlwLagiAo zL?vs6;BdV`mwlZoFo5YG^q(K8gH)h?y__Yl>>!TLU$8;Og}l|1kD2u%Dc4~L-iiSA z&uF;WGg@KNn#%H|YHf!QWvZ!n)it;5&purAy`7tcYJPD|uriA$OCLEXbnM&KlmLIw z4HDLOgKh0AxU|7VZrl$oGLA0mS-)#bCXi{Fzk>_bf~NImiqqFkS)=hNfPS*-?=>@# zaiEHfFPPnIqCIU3U#Vo;#qc)2VCtuQ2JqRWCiLfDApRtLtr>cu(~pIFLH& z)Ggcu^=*6Z2FXHSO1D#=D|mg^xN9Fe>M(lr9OuFL=ZHn_|0PeU594>!W8zFmQuo6$ z#=;q1J=Na0$=Fffk>_p~_J54%nZ@h+fUj3csNlu@)ws<+YY(=X=qDab6aQmBgN&KI zhC_!TAYqCUI>!!W^17AuFu}{`#19AvNNt4!3D8@$PUim$hf2UAGJXOP39cxM`FQ{` zvM8ZeyR;&RrhPG9f_FV#iHcbmO!VFm*f(yJ z8cNq%)qB_}Z&rD%N+g&uE$g2BMSjnYzP{UqQ8IFQPA<_`*^+-(A^7i-H1cwCbq*h_ z8=p@gK=n4|#RIuci{C5Jo38X5I+@*#S^KJAs_SR%T~ZuvmoHWPl@ea)gM`rqJ-PhU z=*2H4&UxG!o2OPk|5+ZC8^{%>?$axQ%uX&vPpN|W(f&~vnNckDSJo?)Trj?_{-Gz{ zI=SWf{s0!B+Fv|7X?wcXm6hKi4Eo=2J;$t|RBvV#zt>eNF8t*^{u!W#XnPoSG63Ze z1F>3DUs=X=J4`pT_`YfsNjx-h#raA-H}B$P(+CLo%s~p2ewK1MFz&gUWWlZx`7UNZ zH*bv}bPM5P0{-ZWQ~#(qSVi0a|GV_!S&a|1)+c25diM({vSZrD;P7UjDS@BJuMc@! zso~WXDtq{enZVbo?0(*6?v?H){H7@8A!{6DjO7hWM=xi&v6_fnIve4e*uE(t3po?y zH~2W0?&6$U{@;+dyRw=2T=BIMGxdM7vR75P{AV2u^cKAQ5>#yw)k38Jhp+j)1O8+O{8>YKRe8L1`0?5`67MaBfy_E4*l8 z9|r$7q7RT=1u-Bw0$_V#lQ#}B{#Rj9!(EP4~!p#BmZ{3X=E2R zc&0Rqmh#of%q?f&r0JoS-=@cSjpXfMs2Yax$JzLQBP#VW3(8z0dNN$(9pkoh%v{^!QGTnB-Z zk|67wZ|Fep_lM$+4D5OAYI_Zb?!O|(zUm7>s!0htf9iTbh2_5_VSMx}jgpq=f3_$v zO$OdZ5@BK<`KO2Bf)b2>ZjtKYgIDSQ`}jSu<@Ww&q{7MvI$tGJYcwZn$Lx*}e{|DkFGzo5UQPesQ}RQChmM^;ivqFl@<@c#k2?N+}4 diff --git a/icons/obj/weapons/guns/toy.dmi b/icons/obj/weapons/guns/toy.dmi index b59dfca674054e4a074fccf111da3c9a1752f074..83a85e7e447c793b1c5e295f3d85fceeb5388302 100644 GIT binary patch delta 636 zcmV-?0)zd72IU5jc>$=AdVhcMxtV#HL@Ne4h9t$r8xQgy;fC!l@)(%j*WV)w(Ik+ zyKRu5;AuFi4Hj7sPnqzXDIz$AKH=SNv?SQiuqD`k&*-fQPV>V%%n45O!#m6gPAlFa z2oC2#ZLrAt=t6=nC|Cpvrt&K|efZvCPH;8{O$oaBFNrfGxEX_#wjzWOLhN85zf-$M zWG748&lLRbP*AU@;3t0xqHU>^Pa;8--$e_ejlGml&K1;0boQj`^-l;&>-v<#`Cass zd{uC+F#4+?ztijU2rB6z&hPa4EP}n<{kmG!m3RCT)ao+{%IP7_?=EME_PGS*^bqHF zdi?|FZw^gRP7iVVq}M-y{wR_L`9(p_z9IzG`V72$3>@ z37z{Vi1ItVK8v9m&f)xy;T|D`5JCuf3sC+y?dn%D5kSd7+qEm12&BH5q%xeYH2UU0 zNkCh__iv?d!FjlHJcQTx&Fu=x*DOWw-oLAb6VM$z9B)@RFCz%=AY$n|xC-V4(QC@Z z1<{M(Xpj>^2qAEU5JCv~Xv}XLKRf@+L6-FD)#g>dQvN5Mfcn?nO8K930_wl?9fU;m zhnRmz%;$dy^MjlaLI@#*5JE^v%x@c+|D{qi|BIn${ue{h{4WOPf2lD4BZLq_h{q3O Ws#xJQ&2R1i0000$b}dVhal^NDs1LZJx}&L&Ue>ApxMSgQ%qJlMwL$`(&ZpITmDQJR!1_|J-m7W5_~Y*A>oeX&v!6;%mezllq-0? zJm10H8?da($rV4KL|DOX{hZa8WOF|!Z6k>SZf}>Qjab^qlLxf%83F0%6zJyw004kU zq+?@Qm8SEH2k)kBBE|`y->BLMxPOfHs!==zNdx}&e{JO-FS~!G_UcUmr4_8&rT*_t z0VU=u7=w6!>2JoV14{FYf8OV008V2qyI}PM*o*ojQ-D-^$G$2 c0DPWr_(DLJk+=>`J^%m!07*qoM6N<$f~#8!^Z)<=