From 0f57a23830272f6b1bfb5d9939d14c0ae88eb1a9 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Mon, 24 Mar 2025 02:50:23 +0530 Subject: [PATCH] Refactor for storage initialization & organization (#89543) ## About The Pull Request A Huge chunk of changes just comes from moving existing storage code into new files & seperating `atom_storage` code into its own subtype under the already existing `storage/subtypes` folder. With that the changes in this PR can be organized into 3 categories. **1. Refactors how `/obj/item/storage/PopulateContents()` initializes storages** - Fixes #88747 and every other storage item that has a similar variant of this problem The problem with `PopulateContents()` is that it allows you to create atoms directly inside the storage via `new(src)` thus bypassing all the access restrictions enforced by `/datum/storage/can_insert()` resulting in storages holding stuff they shouldn't be able to hold. Now how this proc works has been changed. It must now only return a list of items(each item in the list can either be a typepath or a solid atom or a mix of them in any order) that should be inserted into the storage. Each item is then passed into `can_insert()` to check if it can fit in the storage. If your list contains solid atoms they must be first moved to/Initialized in nullspace so `can_insert()` won't count it as already inserted. `can_insert()` has now also been refactored to throw stack traces but explaining exactly why the item could not fit in the storage thus giving you more debugging details to fix your stuff. A large majority of changes is refactoring `PopulateContents()` to return a list instead of simply creating the item in place so simple 1 line changes & with that we have fixed all broken storages(medical toolbox. electrical toolbox, cruisader armor boxes & many more) that hold more items they can handle **2. Organizes initialization of `atom_storage` for storage subtypes.** All subtypes of `/obj/item/storage` should(not enforced) create their own `/datum/storage/` subtype under the folder `storage/subtypes` if the default values are not sufficient. This is the 2nd change done across all existing storages Not only does this bring code cleanliness & organization (separating storage code from item code like how `/datum/wire` code is separated into its own sub folder) but it also makes storage initialization slightly faster (because you are not modifying default values after `atom_storage` is initialized but you are directly setting the default value in place). You now cannot & should not modify `atom_storage` values inside `PopulateContents()`. This will make that proc as pure as possible so less side effects. Of course this principle is not enforced and you can still modify the storage value after `Initialize()` but this should not be encouraged in the future **3. Adds support for automatic storage computations** Most people don't understand how `atom_storage` values work. The comment here clearly states that https://github.com/tgstation/tgstation/blob/55bbfef0da70d87455ca8d6fd5c95107eb8dbefb/code/game/objects/items/storage/toolbox.dm#L327-L329 Because of that the linked issue occurs not just for medical toolbox but for a lot of other items as well. Which is why if you do not know what you doing, `PopulateContents()` now comes with a new storage parameter i.e. `/datum/storage_config` This datum allows you to compute storage values that will perfectly fit with the initial contents of your storage. It allows you to do stuff like computing `max_slots`, `max_item_weight`, `max_total_weight` etc based on your storage initial contents so that all the contents can fit perfectly leaving no space for excess. ## Changelog :cl: fix: storages are no longer initialized with items that can't be put back in after taking them out refactor: storage initialization has been refactored. Please report bugs on github /:cl: --- code/__DEFINES/storage.dm | 3 + code/__HELPERS/_lists.dm | 12 + code/_globalvars/storage_config.dm | 42 + code/datums/station_traits/neutral_traits.dm | 32 - code/datums/storage/storage.dm | 142 ++- code/datums/storage/subtypes/backpack.dm | 18 - code/datums/storage/subtypes/backpacks.dm | 38 + code/datums/storage/subtypes/bags.dm | 370 ++++++ code/datums/storage/subtypes/belts.dm | 362 ++++++ code/datums/storage/subtypes/boxes.dm | 328 ++++++ code/datums/storage/subtypes/drone.dm | 26 - .../subtypes/{duffel_bag.dm => dufflebags.dm} | 26 +- code/datums/storage/subtypes/holsters.dm | 123 ++ code/datums/storage/subtypes/implant.dm | 15 - code/datums/storage/subtypes/lockboxes.dm | 32 + code/datums/storage/subtypes/medkits.dm | 144 +++ code/datums/storage/subtypes/organ_box.dm | 17 - .../subtypes/{ => others}/bag_of_holding.dm | 0 .../storage/subtypes/{ => others}/cards.dm | 0 .../subtypes/{ => others}/carpskin_bag.dm | 0 .../{ => others}/extract_inventory.dm | 0 .../subtypes/{ => others}/fish_case.dm | 10 +- code/datums/storage/subtypes/others/misc.dm | 328 ++++++ code/datums/storage/subtypes/others/pod.dm | 50 + .../storage/subtypes/{ => others}/rped.dm | 7 +- code/datums/storage/subtypes/pockets.dm | 138 ++- .../storage/subtypes/portable_chem_mixer.dm | 16 - code/datums/storage/subtypes/surgery_tray.dm | 29 - .../datums/storage/subtypes/test_tube_rack.dm | 15 - code/datums/storage/subtypes/toolboxes.dm | 49 + code/datums/storage/subtypes/trash.dm | 11 - code/game/machinery/launch_pad.dm | 6 +- code/game/objects/items/crayons.dm | 29 +- code/game/objects/items/devices/spyglasses.dm | 11 +- .../objects/items/devices/traitordevices.dm | 14 +- code/game/objects/items/dice.dm | 42 +- code/game/objects/items/food/moth.dm | 8 +- code/game/objects/items/mail.dm | 26 +- code/game/objects/items/pinpointer.dm | 6 +- code/game/objects/items/religion.dm | 17 +- code/game/objects/items/storage/backpack.dm | 430 +------ code/game/objects/items/storage/bags.dm | 444 +++---- code/game/objects/items/storage/basket.dm | 9 +- code/game/objects/items/storage/belt.dm | 629 ++++------ .../objects/items/storage/boxes/_boxes.dm | 9 +- .../items/storage/boxes/cargo_boxes.dm | 14 +- .../items/storage/boxes/clothes_boxes.dm | 231 ++-- .../items/storage/boxes/engineering_boxes.dm | 74 +- .../items/storage/boxes/fishing_boxes.dm | 44 + .../objects/items/storage/boxes/flat_boxes.dm | 6 +- .../objects/items/storage/boxes/food_boxes.dm | 414 ++++--- .../items/storage/boxes/implant_boxes.dm | 30 +- .../objects/items/storage/boxes/job_boxes.dm | 145 ++- .../items/storage/boxes/medical_boxes.dm | 107 +- .../items/storage/boxes/science_boxes.dm | 113 +- .../items/storage/boxes/security_boxes.dm | 123 +- .../items/storage/boxes/service_boxes.dm | 126 +- .../items/storage/boxes/trait_boxes.dm | 31 + .../items/storage/boxes/uplink_kits.dm | 1029 +++++++++++++++++ code/game/objects/items/storage/briefcase.dm | 74 +- code/game/objects/items/storage/dufflebags.dm | 404 +++++++ code/game/objects/items/storage/fancy.dm | 94 +- code/game/objects/items/storage/garment.dm | 212 ++-- code/game/objects/items/storage/holsters.dm | 152 +-- code/game/objects/items/storage/lockbox.dm | 112 +- code/game/objects/items/storage/medkit.dm | 591 ++-------- code/game/objects/items/storage/misc.dm | 120 ++ .../game/objects/items/storage/pillbottles.dm | 274 +++++ code/game/objects/items/storage/sixpack.dm | 28 +- code/game/objects/items/storage/storage.dm | 156 ++- code/game/objects/items/storage/toolbox.dm | 700 ----------- .../items/storage/toolboxes/_toolbox.dm | 159 +++ .../items/storage/toolboxes/emergency.dm | 43 + .../items/storage/toolboxes/fishing.dm | 59 + .../items/storage/toolboxes/mechanical.dm | 74 ++ .../items/storage/toolboxes/medical.dm | 42 + .../objects/items/storage/toolboxes/misc.dm | 47 + .../items/storage/toolboxes/service.dm | 33 + .../items/storage/toolboxes/weapons.dm | 352 ++++++ .../game/objects/items/storage/uplink_kits.dm | 919 --------------- code/game/objects/items/storage/wallets.dm | 47 +- code/game/objects/items/tcg/tcg.dm | 7 +- code/game/objects/items/teleportation.dm | 6 +- code/game/objects/items/toys.dm | 7 +- code/game/objects/structures/janitor.dm | 7 +- code/modules/admin/verbs/anonymousnames.dm | 53 +- .../heretic/items/unfathomable_curio.dm | 20 +- .../traitor/contractor/contractor_items.dm | 10 +- .../objects/gimmick_disks/_gimmick_disk.dm | 2 +- .../objects/gimmick_disks/dungeon_disk.dm | 38 +- .../objects/gimmick_disks/sports_disk.dm | 29 +- code/modules/bitrunning/objects/loot_box.dm | 11 +- .../chameleon/generic_chameleon_clothing.dm | 16 +- code/modules/clothing/head/costume.dm | 18 + code/modules/clothing/shoes/cowboy.dm | 3 +- code/modules/detectivework/evidence.dm | 3 +- code/modules/events/holiday/easter.dm | 22 - .../events/shuttle_loan/shuttle_loan_items.dm | 8 +- code/modules/fishing/aquarium/aquarium_kit.dm | 5 +- code/modules/fishing/fishing_equipment.dm | 163 +-- .../food_and_drinks/machinery/coffeemaker.dm | 5 +- .../ruins/spaceruin_code/forgottenship.dm | 3 +- code/modules/mining/money_bag.dm | 37 - .../mob/living/basic/drone/drone_tools.dm | 22 +- .../guns/ballistic/bows/bow_quivers.dm | 40 - .../projectiles/guns/energy/dueling.dm | 28 - code/modules/research/part_replacer.dm | 73 +- .../mobile_port/variants/emergency/pods.dm | 82 +- .../internal/cyberimp/augments_internal.dm | 8 +- .../vehicles/mecha/mecha_control_console.dm | 11 +- tgstation.dme | 51 +- 111 files changed, 6790 insertions(+), 5240 deletions(-) create mode 100644 code/_globalvars/storage_config.dm delete mode 100644 code/datums/storage/subtypes/backpack.dm create mode 100644 code/datums/storage/subtypes/backpacks.dm create mode 100644 code/datums/storage/subtypes/bags.dm create mode 100644 code/datums/storage/subtypes/belts.dm create mode 100644 code/datums/storage/subtypes/boxes.dm delete mode 100644 code/datums/storage/subtypes/drone.dm rename code/datums/storage/subtypes/{duffel_bag.dm => dufflebags.dm} (76%) create mode 100644 code/datums/storage/subtypes/holsters.dm delete mode 100644 code/datums/storage/subtypes/implant.dm create mode 100644 code/datums/storage/subtypes/lockboxes.dm create mode 100644 code/datums/storage/subtypes/medkits.dm delete mode 100644 code/datums/storage/subtypes/organ_box.dm rename code/datums/storage/subtypes/{ => others}/bag_of_holding.dm (100%) rename code/datums/storage/subtypes/{ => others}/cards.dm (100%) rename code/datums/storage/subtypes/{ => others}/carpskin_bag.dm (100%) rename code/datums/storage/subtypes/{ => others}/extract_inventory.dm (100%) rename code/datums/storage/subtypes/{ => others}/fish_case.dm (82%) create mode 100644 code/datums/storage/subtypes/others/misc.dm create mode 100644 code/datums/storage/subtypes/others/pod.dm rename code/datums/storage/subtypes/{ => others}/rped.dm (95%) delete mode 100644 code/datums/storage/subtypes/portable_chem_mixer.dm delete mode 100644 code/datums/storage/subtypes/surgery_tray.dm delete mode 100644 code/datums/storage/subtypes/test_tube_rack.dm create mode 100644 code/datums/storage/subtypes/toolboxes.dm delete mode 100644 code/datums/storage/subtypes/trash.dm create mode 100644 code/game/objects/items/storage/boxes/fishing_boxes.dm create mode 100644 code/game/objects/items/storage/boxes/trait_boxes.dm create mode 100644 code/game/objects/items/storage/boxes/uplink_kits.dm create mode 100644 code/game/objects/items/storage/dufflebags.dm create mode 100644 code/game/objects/items/storage/misc.dm create mode 100644 code/game/objects/items/storage/pillbottles.dm delete mode 100644 code/game/objects/items/storage/toolbox.dm create mode 100644 code/game/objects/items/storage/toolboxes/_toolbox.dm create mode 100644 code/game/objects/items/storage/toolboxes/emergency.dm create mode 100644 code/game/objects/items/storage/toolboxes/fishing.dm create mode 100644 code/game/objects/items/storage/toolboxes/mechanical.dm create mode 100644 code/game/objects/items/storage/toolboxes/medical.dm create mode 100644 code/game/objects/items/storage/toolboxes/misc.dm create mode 100644 code/game/objects/items/storage/toolboxes/service.dm create mode 100644 code/game/objects/items/storage/toolboxes/weapons.dm delete mode 100644 code/game/objects/items/storage/uplink_kits.dm delete mode 100644 code/modules/mining/money_bag.dm delete mode 100644 code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm diff --git a/code/__DEFINES/storage.dm b/code/__DEFINES/storage.dm index a266c86198f..0cd4742fad4 100644 --- a/code/__DEFINES/storage.dm +++ b/code/__DEFINES/storage.dm @@ -22,3 +22,6 @@ #define STORAGE_NOT_LOCKED 0 #define STORAGE_SOFT_LOCKED 1 #define STORAGE_FULLY_LOCKED 2 + +// Throw a stack trace in case of failed insertion into storage +#define STORAGE_ERROR_INSERT -1 diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 4fbf3b4b968..8b47d6756f5 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -889,6 +889,18 @@ for(var/key in key_list) . |= LIST_VALUE_WRAP_LISTS(key_list[key]) +/** + * Flattens a keyed list(key = some item, value = quantity of item required) into a list of its contents where each + * item of the list is duplicated as per the quantity required + */ +/proc/flatten_quantified_list(list/key_list) + if(!islist(key_list)) + return null + . = list() + for(var/key in key_list) + for(var/_ in 1 to key_list[key]) + UNTYPED_LIST_ADD(., key) + ///Make a normal list an associative one /proc/make_associative(list/flat_list) . = list() diff --git a/code/_globalvars/storage_config.dm b/code/_globalvars/storage_config.dm new file mode 100644 index 00000000000..a04f2298045 --- /dev/null +++ b/code/_globalvars/storage_config.dm @@ -0,0 +1,42 @@ +/// Will be shared across all obj/item/storage as its only a one time use during Initialize() +GLOBAL_VAR_INIT(initial_storage_config, new /datum/storage_config) + +/** + * Computes atom_storage values based on the initital contents of the storage. + * Use this only when the initial contents are extremly varied such that accurate values + * cannot be computed before hand e.g. if the items are randomly generated or you have huge list of stacks & stuff + * whose weights cannot be calculated correctly so setting the max_total_storage is not feasible and so on + * + * Don't use this if you can manually compute the items weights/counts & set max_total_storage or other values + * correctly yourself as it can lead to balance implications in game e.g. if your storage initially carries + * a large item and you want to set max_specific_storage to that item weight then it will + * allow all others items less than or equal to that item weight which may not be ideal. + * + * In conclusion use this when the initial contents are too complex for mortal comprehension so you make + * computing the storage values automatic + */ +/datum/storage_config + ///Computes the total weight of the storage's initial contents & sets max_total_storage to that value + var/compute_max_total_weight = FALSE + ///Computes the item that has the highest weight in the storage's initial contents & sets max_specific_storage to that value + var/compute_max_item_weight = FALSE + ///Computes number of items in the storage's initial contents & sets max_slots to that value + var/compute_max_item_count = FALSE + ///Sets exception_hold to the storage's initial contents meaning they can be carried without max_specific_storage restrictions + var/contents_are_exceptions = FALSE + ///Sets the storage's initial contents as the only items(i.e. sets can_hold) that can be carried by the storage + var/whitelist_content_types = FALSE + +///Resets all values to their defaults +/datum/storage_config/proc/reset() + compute_max_total_weight = FALSE + compute_max_item_weight = FALSE + compute_max_item_count = FALSE + contents_are_exceptions = FALSE + whitelist_content_types = FALSE + +///Compute max total weight, max item weight & item count +/datum/storage_config/proc/compute_max_values() + compute_max_total_weight = TRUE + compute_max_item_weight = TRUE + compute_max_item_count = TRUE diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index 4cb24783684..752c1f153b4 100644 --- a/code/datums/station_traits/neutral_traits.dm +++ b/code/datums/station_traits/neutral_traits.dm @@ -492,38 +492,6 @@ if(!spawned.equip_to_slot_if_possible(shirt, ITEM_SLOT_OCLOTHING, indirect_action = TRUE)) shirt.forceMove(boxie) -/// A box containing a skub, for easier carry because skub is a bulky item. -/obj/item/storage/box/stickers/skub - name = "skub fan pack" - desc = "A vinyl pouch to store your skub and pro-skub shirt in. A label on the back reads: \"Skubtide, Stationwide\"." - icon_state = "skubpack" - illustration = "label_skub" - w_class = WEIGHT_CLASS_SMALL - -/obj/item/storage/box/stickers/skub/Initialize(mapload) - . = ..() - atom_storage.max_slots = 3 - atom_storage.exception_hold = typecacheof(list(/obj/item/skub, /obj/item/clothing/suit/costume/wellworn_shirt/skub)) - -/obj/item/storage/box/stickers/skub/PopulateContents() - new /obj/item/skub(src) - new /obj/item/sticker/skub(src) - new /obj/item/sticker/skub(src) - -/obj/item/storage/box/stickers/anti_skub - name = "anti-skub stickers pack" - desc = "The enemy may have been given a skub and a shirt, but I've got more stickers! Plus the pack can hold my anti-skub shirt." - icon_state = "skubpack" - illustration = "label_anti_skub" - -/obj/item/storage/box/stickers/anti_skub/Initialize(mapload) - . = ..() - atom_storage.exception_hold = typecacheof(list(/obj/item/clothing/suit/costume/wellworn_shirt/skub)) - -/obj/item/storage/box/stickers/anti_skub/PopulateContents() - for(var/i in 1 to 4) - new /obj/item/sticker/anti_skub(src) - #undef PRO_SKUB #undef ANTI_SKUB #undef SKUB_IDFC diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 42668fb1464..79222e6ad5d 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -35,6 +35,7 @@ /// Do not set directly, use set_holdable VAR_FINAL/list/obj/item/cant_hold /// Typecache of items that can always be inserted into this storage, regardless of size. + /// Do not set directly, use set_holdable VAR_FINAL/list/obj/item/exception_hold /// For use with an exception typecache: /// The maximum amount of items of the exception type that can be inserted into this storage. @@ -146,7 +147,6 @@ src.max_total_storage = max_total_storage /datum/storage/Destroy() - for(var/mob/person in is_using) hide_contents(person) @@ -287,35 +287,44 @@ /// ~Lemon GLOBAL_LIST_EMPTY(cached_storage_typecaches) -/datum/storage/proc/set_holdable(list/can_hold_list, list/cant_hold_list) - if(!isnull(can_hold_list) && !islist(can_hold_list)) - can_hold_list = list(can_hold_list) - if(!isnull(cant_hold_list) && !islist(cant_hold_list)) - cant_hold_list = list(cant_hold_list) - +/datum/storage/proc/set_holdable(list/can_hold_list, list/cant_hold_list, list/exception_hold_list) + can_hold = null if (!isnull(can_hold_list)) - if(isnull(can_hold_description)) - can_hold_description = generate_hold_desc(can_hold_list) + if(!islist(can_hold_list)) + can_hold_list = list(can_hold_list) var/unique_key = can_hold_list.Join("-") if(!GLOB.cached_storage_typecaches[unique_key]) GLOB.cached_storage_typecaches[unique_key] = typecacheof(can_hold_list) can_hold = GLOB.cached_storage_typecaches[unique_key] + cant_hold = null if (!isnull(cant_hold_list)) + if(!islist(cant_hold_list)) + cant_hold_list = list(cant_hold_list) + var/unique_key = cant_hold_list.Join("-") if(!GLOB.cached_storage_typecaches[unique_key]) GLOB.cached_storage_typecaches[unique_key] = typecacheof(cant_hold_list) cant_hold = GLOB.cached_storage_typecaches[unique_key] -/// Generates a description, primarily for clothing storage. -/datum/storage/proc/generate_hold_desc(can_hold_list) - var/list/desc = list() + exception_hold = null + if (!isnull(exception_hold_list)) + if(!islist(exception_hold_list)) + exception_hold_list = list(exception_hold_list) - for(var/obj/item/valid_item as anything in can_hold_list) - desc += "\a [initial(valid_item.name)]" + var/unique_key = exception_hold_list.Join("-") + if(!GLOB.cached_storage_typecaches[unique_key]) + GLOB.cached_storage_typecaches[unique_key] = typecacheof(exception_hold_list) + exception_hold = GLOB.cached_storage_typecaches[unique_key] - return "\n\t[span_notice("[desc.Join("\n\t")]")]" + can_hold_description = null + var/list/holdables = can_hold_list | exception_hold + if(length(holdables)) + var/list/desc = list() + for(var/obj/item/valid_item as anything in holdables) + desc += "\a [initial(valid_item.name)]" + can_hold_description = "\n\t[span_notice("[desc.Join("\n\t")]")]" /// Updates the action button for toggling collectmode. /datum/storage/proc/update_actions(atom/source, mob/equipper, slot) @@ -353,71 +362,114 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) */ /datum/storage/proc/can_insert(obj/item/to_insert, mob/user, messages = TRUE, force = STORAGE_NOT_LOCKED) if(QDELETED(to_insert) || !istype(to_insert)) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:deleted/non object type [to_insert.type] was being inserted") + return FALSE + + if((to_insert == parent) || (to_insert == real_location)) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:cannot insert storage into itself") + return FALSE + + if(locked > force) + if(messages) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:lock force of [force] cannot bypass lock level [locked]") + else if(user) + user.balloon_alert(user, "closed!") return FALSE //stops you from putting stuff like off-hand thingy inside. Hologram storages can accept only hologram items if(to_insert.item_flags & ABSTRACT) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:[to_insert.type] is an abstract object") return FALSE if(parent.flags_1 & HOLOGRAM_1) if(!(to_insert.flags_1 & HOLOGRAM_1)) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:[to_insert.type] is real and cannot be stored inside an hologram parent") return FALSE else if(to_insert.flags_1 & HOLOGRAM_1) - return FALSE - - if(locked > force) - if(messages && user) - user.balloon_alert(user, "closed!") - return FALSE - - if((to_insert == parent) || (to_insert == real_location)) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:[to_insert.type] is a hologram and cannot be stored inside an real parent") return FALSE if(to_insert.w_class > max_specific_storage) if(!is_type_in_typecache(to_insert, exception_hold)) - if(messages && user) - user.balloon_alert(user, "too big!") + if(messages) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:[to_insert.type] of weight class [to_insert.w_class] exceeds max_specific_storage of [max_specific_storage] but is not on the exception_hold list") + else if(user) + user.balloon_alert(user, "too big!") return FALSE + if(exception_max <= get_exception_count()) - if(messages && user) - user.balloon_alert(user, "no room!") + if(messages) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:cannot hold any more exceptional objects [get_exception_count()]/[exception_max] like [to_insert.type] that exceeds max_specific_storage of [max_specific_storage]") + else if(user) + user.balloon_alert(user, "no room!") return FALSE if(real_location.contents.len >= max_slots) - if(messages && user && !silent_for_user) - user.balloon_alert(user, "no room!") + if(messages) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]: max slot capacity of [real_location.contents.len]/[max_slots] reached, cannot insert [to_insert.type]") + else if(user) + user.balloon_alert(user, "no room!") return FALSE if(to_insert.w_class + get_total_weight() > max_total_storage) - if(messages && user && !silent_for_user) - user.balloon_alert(user, "no room!") + if(messages) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:Current weight capacity is [get_total_weight()]/[max_total_storage] no more space for [to_insert.type] who's weight is [to_insert.w_class]") + else if(user) + user.balloon_alert(user, "no room!") return FALSE var/can_hold_it = isnull(can_hold) || is_type_in_typecache(to_insert, can_hold) || is_type_in_typecache(to_insert, exception_hold) var/cant_hold_it = is_type_in_typecache(to_insert, cant_hold) var/trait_says_no = HAS_TRAIT(to_insert, TRAIT_NO_STORAGE_INSERT) if(!can_hold_it || cant_hold_it || trait_says_no) - if(messages && user) - user.balloon_alert(user, "can't hold!") - return FALSE + if(messages) + if(messages == STORAGE_ERROR_INSERT) + if(!can_hold_it) + stack_trace("[parent.type]:[to_insert.type] is neither whitelisted nor an exception hold") + if(cant_hold_it) + stack_trace("[parent.type]:[to_insert.type] has been blacklisted") + if(trait_says_no) + stack_trace("[parent.type]:[to_insert.type] has TRAIT_NO_STORAGE_INSERT") + else if(user) + user.balloon_alert(user, "can't hold!") + return FALSE if(HAS_TRAIT(to_insert, TRAIT_NODROP)) - if(messages && user) - user.balloon_alert(user, "stuck on your hand!") + if(messages) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:[to_insert.type] has TRAIT_NODROP") + else if(user) + user.balloon_alert(user, "stuck on your hand!") return FALSE - // this is valid if the container our location is being held in is a storage item - var/datum/storage/bigger_fish = parent.loc.atom_storage + // this is valid if the container our location is being held in is a storage item, warddrobe subsystem inits our parent in nullspace so we have to check for that + var/datum/storage/bigger_fish = parent.loc?.atom_storage if(bigger_fish && bigger_fish.max_specific_storage < max_specific_storage) - if(messages && user) - user.balloon_alert(user, "[LOWER_TEXT(parent.loc.name)] is in the way!") + if(messages) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:[LOWER_TEXT(parent.loc.type)] is in the way!") + else if(user) + user.balloon_alert(user, "[LOWER_TEXT(parent.loc.name)] is in the way!") return FALSE if(isitem(parent)) var/obj/item/item_parent = parent var/datum/storage/smaller_fish = to_insert.atom_storage if(smaller_fish && !allow_big_nesting && to_insert.w_class >= item_parent.w_class) - if(messages && user) - user.balloon_alert(user, "too big!") + if(messages) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]:[to_insert.type] has an internal storage of weight [to_insert.w_class] that does not allow nested storage inside of parent of weight [item_parent.w_class]") + else if(user) + user.balloon_alert(user, "too big!") return FALSE return TRUE @@ -457,7 +509,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) SEND_SIGNAL(src, COMSIG_STORAGE_STORED_ITEM, to_insert, user, force) to_insert.forceMove(real_location) item_insertion_feedback(user, to_insert, override) - parent.update_appearance() return TRUE /// Since items inside storages ignore transparency for QOL reasons, we're tracking when things are dropped onto them instead of our UI elements @@ -527,10 +578,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) if(animated) animate_parent() - if(override) - return - - if(silent) + if(override || silent) return if(do_rustle && rustle_sound) diff --git a/code/datums/storage/subtypes/backpack.dm b/code/datums/storage/subtypes/backpack.dm deleted file mode 100644 index a2a1a13fcd4..00000000000 --- a/code/datums/storage/subtypes/backpack.dm +++ /dev/null @@ -1,18 +0,0 @@ -/datum/storage/backpack - max_total_storage = 21 - max_slots = 21 - -/datum/storage/backpack/New( - atom/parent, - max_slots, - max_specific_storage, - max_total_storage, -) - . = ..() - var/static/list/exception_cache = typecacheof(list(/obj/item/fish_tank)) - exception_hold = exception_cache - -/datum/storage/backpack/santabag - max_total_storage = 60 - max_slots = 21 - max_specific_storage = WEIGHT_CLASS_NORMAL diff --git a/code/datums/storage/subtypes/backpacks.dm b/code/datums/storage/subtypes/backpacks.dm new file mode 100644 index 00000000000..dbde6f86264 --- /dev/null +++ b/code/datums/storage/subtypes/backpacks.dm @@ -0,0 +1,38 @@ +///Regular backpack +/datum/storage/backpack + max_total_storage = 21 + max_slots = 21 + +/datum/storage/backpack/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) + . = ..() + + set_holdable(exception_hold_list = /obj/item/fish_tank) + +///Sadle bag +/datum/storage/backpack/sadle_bag + max_total_storage = 26 + +///Satchel flat +/datum/storage/backpack/satchel + max_total_storage = 15 + allow_big_nesting = TRUE + +/datum/storage/backpack/satchel/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(cant_hold_list = /obj/item/storage/backpack/satchel/flat) //muh recursive backpacks + +///Santa backpack +/datum/storage/backpack/santabag + max_total_storage = 60 + max_slots = 21 + max_specific_storage = WEIGHT_CLASS_NORMAL + +///Banner pack +/datum/storage/backpack/bannerpack + max_total_storage = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times. diff --git a/code/datums/storage/subtypes/bags.dm b/code/datums/storage/subtypes/bags.dm new file mode 100644 index 00000000000..90229650652 --- /dev/null +++ b/code/datums/storage/subtypes/bags.dm @@ -0,0 +1,370 @@ +///Normal bag +/datum/storage/bag + allow_quick_gather = TRUE + allow_quick_empty = TRUE + numerical_stacking = TRUE + +///Trash bag +/datum/storage/bag/trash_bag + max_slots = 30 + max_total_storage = 30 + supports_smart_equip = FALSE + max_specific_storage = WEIGHT_CLASS_SMALL + +/datum/storage/bag/trash_bag/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(cant_hold_list = /obj/item/disk/nuclear) + +/datum/storage/bag/trash_bag/remove_single(mob/removing, obj/item/thing, atom/remove_to_loc, silent) + real_location.visible_message( + span_notice("[removing] starts fishing around inside [parent]."), + span_notice("You start digging around in [parent] to try and pull something out."), + ) + if(!do_after(removing, 1.5 SECONDS, parent)) + return FALSE + + return ..() + +///Bluespace trash bag +/datum/storage/bag/trash_bag/bluespace + max_slots = 60 + max_total_storage = 60 + +///Ore bag +/datum/storage/bag/ore_bag + max_total_storage = 50 + numerical_stacking = TRUE + allow_quick_empty = TRUE + allow_quick_gather = TRUE + silent_for_user = TRUE + max_specific_storage = WEIGHT_CLASS_HUGE + +/datum/storage/bag/ore_bag/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/stack/ore) + +///Bluespace ore bag +/datum/storage/bag/ore_bag/bluespace + max_slots = INFINITY + max_specific_storage = INFINITY + max_total_storage = INFINITY + +///Plant bag +/datum/storage/bag/plants + max_slots = 100 + max_total_storage = 100 + max_specific_storage = WEIGHT_CLASS_NORMAL + +/datum/storage/bag/plants/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/food/grown, + /obj/item/graft, + /obj/item/grown, + /obj/item/food/honeycomb, + /obj/item/seeds, + )) + +///Sheet snatcher bag +/datum/storage/bag/sheet_snatcher + max_total_storage = 150 + allow_quick_empty = TRUE + allow_quick_gather = TRUE + numerical_stacking = TRUE + +/datum/storage/bag/sheet_snatcher/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable( + can_hold_list = list( + /obj/item/stack/sheet + ), + cant_hold_list = list( + /obj/item/stack/sheet/mineral/sandstone, + /obj/item/stack/sheet/mineral/wood, + ), + ) + +///Sheet snatcher debug bag +/datum/storage/bag/sheet_snatcher/debug/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/stack) + +///Sheet snatcher cyborg bag +/datum/storage/bag/sheet_snatcher_cyborg + max_total_storage = 250 + +///Book bag +/datum/storage/bag/books + max_slots = 7 + max_total_storage = 21 + max_specific_storage = WEIGHT_CLASS_NORMAL + +/datum/storage/bag/books/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/book, + /obj/item/spellbook, + /obj/item/poster, + )) + +///Tray bag +/datum/storage/bag/tray + max_slots = 8 + max_total_storage = 16 + insert_preposition = "on" + max_specific_storage = WEIGHT_CLASS_BULKY //Plates are required bulky to keep them out of backpacks + +/datum/storage/bag/tray/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable( + can_hold_list = list( + /obj/item/cigarette, + /obj/item/food, + /obj/item/kitchen, + /obj/item/lighter, + /obj/item/organ, + /obj/item/plate, + /obj/item/reagent_containers/condiment, + /obj/item/reagent_containers/cup, + /obj/item/rollingpaper, + /obj/item/storage/box/gum, + /obj/item/storage/box/matches, + /obj/item/storage/fancy, + /obj/item/trash, + ), + cant_hold_list = list( + /obj/item/plate/oven_tray, + /obj/item/reagent_containers/cup/soup_pot, + ), + ) //Should cover: Bottles, Beakers, Bowls, Booze, Glasses, Food, Food Containers, Food Trash, Organs, Tobacco Products, Lighters, and Kitchen Tools. + +///Chemistry bag +/datum/storage/bag/chemistry + max_slots = 50 + max_total_storage = 200 + +/datum/storage/bag/chemistry/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/reagent_containers/chem_pack, + /obj/item/reagent_containers/dropper, + /obj/item/reagent_containers/cup/glass/waterbottle, + /obj/item/reagent_containers/cup/beaker, + /obj/item/reagent_containers/cup/bottle, + /obj/item/reagent_containers/cup/tube, + /obj/item/reagent_containers/medigel, + /obj/item/reagent_containers/applicator, + /obj/item/reagent_containers/syringe, + )) + +///Bio bag +/datum/storage/bag/bio + max_slots = 25 + max_total_storage = 200 + +/datum/storage/bag/bio/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/bodypart, + /obj/item/food/monkeycube, + /obj/item/healthanalyzer, + /obj/item/organ, + /obj/item/reagent_containers/blood, + /obj/item/reagent_containers/dropper, + /obj/item/reagent_containers/cup/beaker, + /obj/item/reagent_containers/cup/bottle, + /obj/item/reagent_containers/cup/tube, + /obj/item/reagent_containers/hypospray/medipen, + /obj/item/reagent_containers/syringe, + )) + +///Science bag +/datum/storage/bag/science + max_slots = 25 + max_total_storage = 200 + +/datum/storage/bag/science/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/bodypart, + /obj/item/food/deadmouse, + /obj/item/food/monkeycube, + /obj/item/organ, + /obj/item/petri_dish, + /obj/item/reagent_containers/dropper, + /obj/item/reagent_containers/cup/beaker, + /obj/item/reagent_containers/cup/bottle, + /obj/item/reagent_containers/cup/tube, + /obj/item/reagent_containers/syringe, + /obj/item/slime_extract, + /obj/item/swab, + )) + +///Construction bag +/datum/storage/bag/construction + max_total_storage = 100 + max_slots = 50 + max_specific_storage = WEIGHT_CLASS_SMALL + +/datum/storage/bag/construction/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/assembly, + /obj/item/circuitboard, + /obj/item/electronics, + /obj/item/reagent_containers/cup/beaker, + /obj/item/stack/cable_coil, + /obj/item/stack/ore/bluespace_crystal, + /obj/item/stock_parts, + /obj/item/wallframe/camera, + )) + +///Harpoon quiver +/datum/storage/bag/harpoon_quiver + max_specific_storage = WEIGHT_CLASS_TINY + max_slots = 40 + max_total_storage = 100 + +/datum/storage/bag/harpoon_quiver/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/ammo_casing/harpoon) + +///New bar quiver +/datum/storage/bag/rebar_quiver + max_specific_storage = WEIGHT_CLASS_TINY + max_slots = 10 + max_total_storage = 15 + +/datum/storage/bag/rebar_quiver/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/ammo_casing/rebar, + /obj/item/ammo_casing/rebar/syndie, + /obj/item/ammo_casing/rebar/healium, + /obj/item/ammo_casing/rebar/hydrogen, + /obj/item/ammo_casing/rebar/zaukerite, + /obj/item/ammo_casing/rebar/paperball, + )) + +///Syndicate rebar quiver +/datum/storage/bag/rebar_quiver/syndicate + max_slots = 20 + max_total_storage = 20 + +///Garment bag +/datum/storage/bag/garment + max_slots = 18 + max_total_storage = 200 + max_specific_storage = WEIGHT_CLASS_BULKY + numerical_stacking = FALSE + insert_preposition = "in" + +/datum/storage/bag/garment/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/clothing) + + +///Mail storage bag +/datum/storage/bag/mail + max_total_storage = 42 + max_slots = 21 + numerical_stacking = FALSE + max_specific_storage = WEIGHT_CLASS_NORMAL + +/datum/storage/bag/mail/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/mail, + /obj/item/delivery/small, + /obj/item/paper + )) + +///Fishing bag +/datum/storage/bag/fishing + max_total_storage = 24 // Up to 8 normal fish + max_slots = 21 + +/datum/storage/bag/fishing/New(atom/parent, max_slots, max_specific_storage, max_total_storage, list/holdables) + . = ..() + + if(!length(holdables)) + holdables = list(/obj/item/fish) + + set_holdable(/obj/item/fish) + +///Carpskin fishing bag +/datum/storage/bag/fishing/carpskin + max_total_storage = 42 // Up to 14 normal fish, but we're assuming that you'll be storing a bunch of gear as well + +/datum/storage/bag/fishing/carpskin/New(atom/parent, max_slots, max_specific_storage, max_total_storage, list/holdables) + holdables = list( + /obj/item/fish, + /obj/item/fishing_line, + /obj/item/fishing_hook, + /obj/item/fishing_lure, + /obj/item/fish_analyzer, + /obj/item/bait_can, + ) + + return ..() + +///Dutchmen bag +/datum/storage/bag/dutchmen + max_slots = 19 + max_total_storage = 21 + +///Money bag +/datum/storage/bag/money + max_slots = 40 + max_specific_storage = 40 + +/datum/storage/bag/money/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/coin, + /obj/item/stack/spacecash, + /obj/item/holochip + )) + +///Bag of quivers +/datum/storage/bag/quivers + max_specific_storage = WEIGHT_CLASS_TINY + max_slots = 40 + max_total_storage = 100 + numerical_stacking = TRUE + +/datum/storage/bag/quivers/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/ammo_casing/arrow) + +///Bag of smaller quivers +/datum/storage/bag/quivers/lesser + max_slots = 10 + +///Endless quivers +/datum/storage/bag/quivers/endless + max_slots = 1 + +/datum/storage/bag/quivers/endless/handle_exit(datum/source, obj/item/gone) + . = ..() + + var/obj/item/storage/bag/quiver/store = source + + new store.arrow_path(store) diff --git a/code/datums/storage/subtypes/belts.dm b/code/datums/storage/subtypes/belts.dm new file mode 100644 index 00000000000..94e7ea24263 --- /dev/null +++ b/code/datums/storage/subtypes/belts.dm @@ -0,0 +1,362 @@ +///Utility belt +/datum/storage/utility_belt + max_total_storage = 21 + +/datum/storage/chief_utility_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(GLOB.tool_items + list( + /obj/item/clothing/gloves, + /obj/item/radio, + /obj/item/melee/sickly_blade/lock, + /obj/item/reagent_containers/cup/soda_cans, + )) + +///Sabre belt +/datum/storage/sabre_belt + max_slots = 1 + do_rustle = FALSE + max_specific_storage = WEIGHT_CLASS_BULKY + click_alt_open = FALSE + +/datum/storage/sabre_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/melee/sabre) + +///Medical belt +/datum/storage/medical_belt + max_specific_storage = WEIGHT_CLASS_NORMAL + max_total_storage = 21 + +/datum/storage/medical_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/bikehorn/rubberducky, + /obj/item/blood_filter, + /obj/item/bonesetter, + /obj/item/cautery, + /obj/item/circular_saw, + /obj/item/clothing/glasses, + /obj/item/clothing/gloves, + /obj/item/clothing/neck/stethoscope, + /obj/item/clothing/mask/breath, + /obj/item/clothing/mask/muzzle, + /obj/item/clothing/mask/surgical, + /obj/item/clothing/head/utility/surgerycap, + /obj/item/construction/plumbing, + /obj/item/dnainjector, + /obj/item/extinguisher/mini, + /obj/item/flashlight/pen, + /obj/item/geiger_counter, + /obj/item/gun/syringe/syndicate, + /obj/item/healthanalyzer, + /obj/item/hemostat, + /obj/item/holosign_creator/medical, + /obj/item/implant, + /obj/item/implantcase, + /obj/item/implanter, + /obj/item/lazarus_injector, + /obj/item/lighter, + /obj/item/pinpointer/crew, + /obj/item/plunger, + /obj/item/radio, + /obj/item/reagent_containers/blood, + /obj/item/reagent_containers/dropper, + /obj/item/reagent_containers/cup/beaker, + /obj/item/reagent_containers/cup/bottle, + /obj/item/reagent_containers/cup/tube, + /obj/item/reagent_containers/hypospray, + /obj/item/reagent_containers/medigel, + /obj/item/reagent_containers/applicator, + /obj/item/reagent_containers/spray, + /obj/item/reagent_containers/syringe, + /obj/item/retractor, + /obj/item/scalpel, + /obj/item/shears, + /obj/item/stack/medical, + /obj/item/stack/sticky_tape, //surgical tape + /obj/item/stamp, + /obj/item/sensor_device, + /obj/item/storage/fancy/cigarettes, + /obj/item/storage/pill_bottle, + /obj/item/surgical_drapes, //for true paramedics + /obj/item/surgicaldrill, + /obj/item/tank/internals/emergency_oxygen, + /obj/item/wrench/medical, + /obj/item/knife/ritual, + /obj/item/flesh_shears, + )) + +//Security belt +/datum/storage/security_belt + max_slots = 5 + open_sound = 'sound/items/handling/holster_open.ogg' + open_sound_vary = TRUE + rustle_sound = null + +/datum/storage/security_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/ammo_box, + /obj/item/ammo_casing/shotgun, + /obj/item/assembly/flash/handheld, + /obj/item/clothing/glasses, + /obj/item/clothing/gloves, + /obj/item/flashlight/seclite, + /obj/item/food/donut, + /obj/item/grenade, + /obj/item/holosign_creator/security, + /obj/item/knife/combat, + /obj/item/melee/baton, + /obj/item/radio, + /obj/item/reagent_containers/spray/pepper, + /obj/item/restraints/handcuffs, + /obj/item/restraints/legcuffs/bola, + )) + +///Webbing security belt +/datum/storage/security_belt/webbing + max_slots = 6 + + +///Mining belt +/datum/storage/mining_belt + max_slots = 6 + max_total_storage = 20 + +/datum/storage/mining_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/analyzer, + /obj/item/clothing/gloves, + /obj/item/crowbar, + /obj/item/extinguisher/mini, + /obj/item/flashlight, + /obj/item/gps, + /obj/item/mining_stabilizer, + /obj/item/key/lasso, + /obj/item/knife, + /obj/item/lighter, + /obj/item/mining_scanner, + /obj/item/multitool, + /obj/item/organ/monster_core, + /obj/item/pickaxe, + /obj/item/radio, + /obj/item/reagent_containers/cup/glass, + /obj/item/reagent_containers/cup/glass/bottle, + /obj/item/reagent_containers/hypospray, + /obj/item/reagent_containers/applicator/pill, + /obj/item/resonator, + /obj/item/screwdriver, + /obj/item/shovel, + /obj/item/stack/cable_coil, + /obj/item/stack/marker_beacon, + /obj/item/stack/medical, + /obj/item/stack/ore, + /obj/item/stack/sheet/animalhide, + /obj/item/stack/sheet/bone, + /obj/item/stack/sheet/sinew, + /obj/item/storage/bag/ore, + /obj/item/storage/fancy/cigarettes, + /obj/item/storage/pill_bottle, + /obj/item/survivalcapsule, + /obj/item/t_scanner/adv_mining_scanner, + /obj/item/weldingtool, + /obj/item/wirecutters, + /obj/item/wrench, + /obj/item/wormhole_jaunter, + /obj/item/skeleton_key, + )) + +///Mining belt primitive +/datum/storage/mining_belt/primitive + max_slots = 5 + +///Soulstone belt +/datum/storage/soulstone_belt + max_slots = 6 + +/datum/storage/soulstone_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/soulstone) + +///Champion belt +/datum/storage/champion_belt + max_slots = 1 + +/datum/storage/champion_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/clothing/mask/luchador) + +///Militray belt +/datum/storage/military_belt + max_specific_storage = WEIGHT_CLASS_SMALL + +///Military belt snacks +/datum/storage/military_belt/snacks + max_slots = 6 + +/datum/storage/military_belt/snacks/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/food, + /obj/item/reagent_containers/cup/glass, + /obj/item/reagent_containers/cup/soda_cans, + )) + +///Military belt assault +/datum/storage/military_belt/assault + max_slots = 6 + +///Grenade belt +/datum/storage/grenade_belt + max_slots = 30 + numerical_stacking = TRUE + max_total_storage = 60 + max_specific_storage = WEIGHT_CLASS_BULKY + +/datum/storage/grenade_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/food/grown/cherry_bomb, + /obj/item/food/grown/firelemon, + /obj/item/grenade, + /obj/item/grenade/c4, + /obj/item/lighter, + /obj/item/multitool, + /obj/item/reagent_containers/cup/glass/bottle/molotov, + /obj/item/screwdriver, + )) + +///Wand belt +/datum/storage/wand_belt + max_slots = 7 + +/datum/storage/wand_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/gun/magic/wand) + +///Janitor belt +/datum/storage/janitor_belt + max_slots = 6 + +/datum/storage/janitor_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/access_key, + /obj/item/assembly/mousetrap, + /obj/item/clothing/gloves, + /obj/item/flashlight, + /obj/item/forcefield_projector, + /obj/item/grenade/chem_grenade, + /obj/item/holosign_creator, + /obj/item/key/janitor, + /obj/item/lightreplacer, + /obj/item/melee/flyswatter, + /obj/item/paint/paint_remover, + /obj/item/plunger, + /obj/item/pushbroom, + /obj/item/reagent_containers/spray, + /obj/item/soap, + /obj/item/wirebrush, + )) + +///Bandolier belt +/datum/storage/bandolier_belt + max_slots = 24 + max_total_storage = 24 + allow_quick_gather = TRUE + allow_quick_empty = TRUE + numerical_stacking = TRUE + +/datum/storage/bandolier_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/ammo_casing/strilka310, + /obj/item/ammo_casing/shotgun, + /obj/item/ammo_casing/c357, + /obj/item/ammo_casing/junk, + )) + +///Fanny pack +/datum/storage/fanny_pack + max_slots = 3 + max_specific_storage = WEIGHT_CLASS_SMALL + silent = TRUE + +///Green sabre +/datum/storage/green_sabre_belt + max_slots = 1 + do_rustle = FALSE + max_specific_storage = WEIGHT_CLASS_BULKY + click_alt_open = FALSE + +/datum/storage/green_sabre_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/melee/parsnip_sabre) + +///Plant belt +/datum/storage/plant_belt + max_slots = 6 + max_specific_storage = WEIGHT_CLASS_NORMAL + +/datum/storage/plant_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/cultivator, + /obj/item/geneshears, + /obj/item/graft, + /obj/item/gun/energy/floragun, + /obj/item/hatchet, + /obj/item/plant_analyzer, + /obj/item/reagent_containers/cup/beaker, + /obj/item/reagent_containers/cup/bottle, + /obj/item/reagent_containers/cup/tube, + /obj/item/reagent_containers/spray/pestspray, + /obj/item/reagent_containers/spray/plantbgone, + /obj/item/secateurs, + /obj/item/seeds, + /obj/item/shovel/spade, + )) + +///unfathomable curio belt +/datum/storage/unfathomable_curio_belt + max_specific_storage = WEIGHT_CLASS_NORMAL + max_total_storage = 21 + +/datum/storage/unfathomable_curio_belt/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/ammo_box/strilka310/lionhunter, + /obj/item/heretic_labyrinth_handbook, + /obj/item/bodypart, // Bodyparts are often used in rituals. + /obj/item/clothing/neck/eldritch_amulet, + /obj/item/clothing/neck/heretic_focus, + /obj/item/codex_cicatrix, + /obj/item/eldritch_potion, + /obj/item/food/grown/poppy, // Used to regain a Living Heart. + /obj/item/food/grown/harebell, // Used to reroll targets + /obj/item/melee/rune_carver, + /obj/item/melee/sickly_blade, + /obj/item/organ, // Organs are also often used in rituals. + /obj/item/reagent_containers/cup/beaker/eldritch, + /obj/item/stack/sheet/glass, // Glass is often used by moon heretics + )) + +///Chameleon belt +/datum/storage/chameleon_belt + silent = TRUE diff --git a/code/datums/storage/subtypes/boxes.dm b/code/datums/storage/subtypes/boxes.dm new file mode 100644 index 00000000000..606d6f3c6a7 --- /dev/null +++ b/code/datums/storage/subtypes/boxes.dm @@ -0,0 +1,328 @@ +///Small box storage +/datum/storage/box + open_sound = 'sound/items/handling/cardboard_box/cardboard_box_open.ogg' + rustle_sound = 'sound/items/handling/cardboard_box/cardboard_box_rustle.ogg' + max_specific_storage = WEIGHT_CLASS_SMALL + +///Flat box +/datum/storage/box/flat + max_slots = 3 + +///Coffee box +/datum/storage/box/coffee + max_slots = 5 + +///Ingredient box +/datum/storage/box/ingredients + max_specific_storage = WEIGHT_CLASS_NORMAL + +///Coffee box +/datum/storage/box/coffee/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/food/grown/coffee) + +///Donk pocket box +/datum/storage/box/donk_pockets/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/food/donkpocket) + +///Bubble gum box +/datum/storage/box/bubble_gum + max_slots = 4 + +/datum/storage/box/bubble_gum/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/food/bubblegum) + +///Snappops box +/datum/storage/box/snappops + max_slots = 8 + +/datum/storage/box/snappops/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/toy/snappop) + +///Minor modkits box +/datum/storage/box/minor_modkits + numerical_stacking = TRUE + +/datum/storage/box/minor_modkits/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/borg/upgrade/modkit, + /obj/item/crusher_trophy + )) + +///Bandages box +/datum/storage/box/bandages + max_slots = 6 + +/datum/storage/box/bandages/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/stack/medical/bandage, + /obj/item/reagent_containers/applicator/pill, + /obj/item/reagent_containers/applicator/patch, + )) + +///Monkey cubes box +/datum/storage/box/monkey_cubes/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/food/monkeycube) + +///Gorilla cubes box +/datum/storage/box/gorilla_cubes + max_slots = 3 + +/datum/storage/box/gorilla_cubes/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/food/monkeycube) + +///Match box +/datum/storage/box/matches + max_slots = 10 + +/datum/storage/box/matches/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/match) + +///Lights box +/datum/storage/box/lights + max_slots = 21 + max_total_storage = 21 * WEIGHT_CLASS_NORMAL + allow_quick_gather = FALSE //temp workaround to re-enable filling the light replacer with the box + +/datum/storage/box/lights/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list(/obj/item/light/tube, /obj/item/light/bulb)) + +///Balloon box +/datum/storage/box/balloons + max_slots = 24 + max_specific_storage = WEIGHT_CLASS_NORMAL + max_total_storage = 24 * WEIGHT_CLASS_NORMAL + allow_quick_gather = FALSE + +/datum/storage/box/balloons/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/toy/balloon/long) + +///Wizard box +/datum/storage/box/wizard + max_specific_storage = WEIGHT_CLASS_NORMAL + +///Syndicate box +/datum/storage/box/syndicate + allow_big_nesting = TRUE + +///Syndicate contractor box +/datum/storage/box/syndicate/contractor + max_total_storage = 25 + max_specific_storage = WEIGHT_CLASS_BULKY + +///Syndicate contractor kit box +/datum/storage/box/syndicate/contract_kit + allow_big_nesting = TRUE + max_specific_storage = WEIGHT_CLASS_NORMAL + +///Syndicate contractor loadout box +/datum/storage/box/syndicate/contractor_loadout + max_slots = 12 + max_total_storage = 27 + max_specific_storage = WEIGHT_CLASS_BULKY + +///Syndicate conractor loadout +/datum/storage/box/syndicate/contractor_loadout + max_specific_storage = WEIGHT_CLASS_BULKY + +///Stickers box +/datum/storage/box/stickers + max_slots = 8 + +/datum/storage/box/stickers/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/sticker) + +///Holy box +/datum/storage/box/holy + max_specific_storage = WEIGHT_CLASS_NORMAL + +/datum/storage/box/holy/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/clothing) + +///Holy Caplin box +/datum/storage/box/holy/follower + max_total_storage = 15 + +///Hero box +/datum/storage/box/hero + max_slots = 12 + max_total_storage = 30 + max_specific_storage = WEIGHT_CLASS_BULKY + allow_big_nesting = TRUE + +///Floor camo box +/datum/storage/box/floor_camo + allow_big_nesting = TRUE + +///Skub box +/datum/storage/box/stickers/skub + max_slots = 3 + +/datum/storage/box/stickers/skub/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(exception_hold_list = list( + /obj/item/skub, + /obj/item/clothing/suit/costume/wellworn_shirt/skub, + )) + +///Anti skub box +/datum/storage/box/stickers/anti_skub/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(exception_hold_list = /obj/item/clothing/suit/costume/wellworn_shirt/skub) + +///SyndiKit box +/datum/storage/box/syndie_kit + max_specific_storage = WEIGHT_CLASS_NORMAL + +///SyndiKit space box +/datum/storage/box/syndie_kit/space/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/clothing/suit/space/syndicate, + /obj/item/clothing/head/helmet/space/syndicate, + )) + +///SyndiKit chemical box +/datum/storage/box/syndie_kit/chemical + max_slots = 15 + max_total_storage = 15 + +///SyndiKit Rebar x bow box +/datum/storage/box/syndie_kit/rebarxbowsyndie + allow_big_nesting = TRUE + +///SyndiKit mail counterfeit box +/datum/storage/box/syndie_kit/mail_counterfeit + allow_big_nesting = TRUE + max_total_storage = 6 * WEIGHT_CLASS_NORMAL + +///SyndiKit cowboy box +/datum/storage/box/syndie_kit/cowboy + max_total_storage = 20 + allow_big_nesting = TRUE + max_specific_storage = WEIGHT_CLASS_BULKY + +///SyniKit induction kit +/datum/storage/box/syndie_kit/induction_kit + allow_big_nesting = TRUE + +///SyndiKit centcom costume box +/datum/storage/box/syndie_kit/centcom_costume + max_slots = 8 + max_total_storage = 24 + allow_big_nesting = TRUE + max_specific_storage = WEIGHT_CLASS_BULKY + +///SyndiKit tuberculosis grenade box +/datum/storage/box/syndie_kit/tuberculosisgrenade + max_slots = 8 + +///SyndiKit demoman box +/datum/storage/box/syndie_kit/demoman + allow_big_nesting = TRUE + max_specific_storage = WEIGHT_CLASS_BULKY + +///SyndiKit Imp death rattle box +/datum/storage/box/syndie_kit/imp_deathrattle + max_slots = 9 + +///SyndiKit pinata box +/datum/storage/box/syndie_kit/pinata + max_specific_storage = WEIGHT_CLASS_BULKY + allow_big_nesting = TRUE + +///SyndiKit chaemelon box +/datum/storage/box/syndie_kit/chaemelon + max_slots = 15 + max_total_storage = 38 + allow_big_nesting = TRUE + max_specific_storage = WEIGHT_CLASS_BULKY + +///SyndiKit throwing weapons box +/datum/storage/box/syndie_kit/weapons + max_slots = 9 // 5 + 2 + 2 + max_total_storage = 18 // 5*2 + 2*1 + 3*2 + +/datum/storage/box/syndie_kit/weapons/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/restraints/legcuffs/bola/tactical, + /obj/item/paperplane/syndicate, + /obj/item/throwing_star, + )) + +///SyndiKit cutouts box +/datum/storage/box/syndie_kit/cutouts + max_slots = 4 + max_specific_storage = WEIGHT_CLASS_BULKY + +///Fishing lures box +/datum/storage/box/fishing_lures/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + set_holdable(list( + /obj/item/fishing_lure, + /obj/item/paper/lures_instructions + )) //can only hold lures + + //adds an extra slot, so we can put back the lures even if we didn't take out the instructions. + max_slots = length(typesof(/obj/item/fishing_lure)) + 1 + max_total_storage = WEIGHT_CLASS_SMALL * (max_slots + 1) + + return ..() + +///Stock parts box +/datum/storage/box/stockparts + max_slots = 15 + max_total_storage = 15 * WEIGHT_CLASS_SMALL + +///Tiziran cans box +/datum/storage/box/tiziran_cans + max_slots = 8 + max_total_storage = 8 * WEIGHT_CLASS_SMALL + +///Tiziran meat box +/datum/storage/box/tiziran_meats + max_slots = 10 + max_total_storage = 10 * WEIGHT_CLASS_SMALL + +///Mothic goods box +/datum/storage/box/mothic_goods + max_slots = 12 + max_specific_storage = WEIGHT_CLASS_NORMAL + +///Mothic cans sauces box +/datum/storage/box/mothic_cans_sauces + max_slots = 8 + max_total_storage = 8 * WEIGHT_CLASS_SMALL + +///Debug box +/datum/storage/box/debug_tools + allow_big_nesting = TRUE diff --git a/code/datums/storage/subtypes/drone.dm b/code/datums/storage/subtypes/drone.dm deleted file mode 100644 index 2df8f4c6279..00000000000 --- a/code/datums/storage/subtypes/drone.dm +++ /dev/null @@ -1,26 +0,0 @@ -/datum/storage/drone - max_total_storage = 40 - max_specific_storage = WEIGHT_CLASS_NORMAL - max_slots = 10 - do_rustle = FALSE - -/datum/storage/drone/New(atom/parent, max_slots, max_specific_storage, max_total_storage) - . = ..() - - var/static/list/drone_builtins = list( - /obj/item/crowbar/drone, - /obj/item/screwdriver/drone, - /obj/item/wrench/drone, - /obj/item/weldingtool/drone, - /obj/item/wirecutters/drone, - /obj/item/multitool/drone, - /obj/item/pipe_dispenser/drone, - /obj/item/t_scanner/drone, - /obj/item/analyzer/drone, - /obj/item/soap/drone, - ) - - set_holdable(drone_builtins) - -/datum/storage/drone/dump_content_at(atom/dest_object, dump_loc, mob/user) - return //no dumping of contents allowed diff --git a/code/datums/storage/subtypes/duffel_bag.dm b/code/datums/storage/subtypes/dufflebags.dm similarity index 76% rename from code/datums/storage/subtypes/duffel_bag.dm rename to code/datums/storage/subtypes/dufflebags.dm index bb3a236d38b..99e15dc2f25 100644 --- a/code/datums/storage/subtypes/duffel_bag.dm +++ b/code/datums/storage/subtypes/dufflebags.dm @@ -1,3 +1,4 @@ +//Regular duffle bag /datum/storage/duffel max_total_storage = 30 max_slots = 21 @@ -9,8 +10,8 @@ max_total_storage, ) . = ..() - var/static/list/exception_cache = typecacheof(list(/obj/item/fish_tank)) - exception_hold = exception_cache + + set_holdable(exception_hold_list = /obj/item/fish_tank) // Syndi bags get some FUN extras // You can fit any 2 bulky objects (assuming they're in the whitelist) @@ -68,6 +69,7 @@ /obj/item/clothing/suit/utility, // Storage /obj/item/storage/bag/money, + /obj/item/storage/belt/utility/syndicate, // Heads! /obj/item/bodypart/head, // Fish @@ -75,9 +77,19 @@ /obj/item/fish_tank, ) - // We keep the type list and the typecache list separate... - var/static/list/exception_cache = typecacheof(exception_type_list) - exception_hold = exception_cache + set_holdable(exception_hold_list = exception_type_list) - //...So we can run this without it generating a line for every subtype. - can_hold_description = generate_hold_desc(exception_type_list) +///Syndicate firestarter +/datum/storage/duffel/syndicate/firestarter + allow_big_nesting = TRUE + +///Syndicate ammo mech box +/datum/storage/duffel/syndicate/ammo_mech + exception_max = 5 + allow_big_nesting = TRUE + +///Syndicate ammo mauler box +/datum/storage/duffel/syndicate/ammo_mauler + exception_max = 9 + max_total_storage = 36 + allow_big_nesting = TRUE diff --git a/code/datums/storage/subtypes/holsters.dm b/code/datums/storage/subtypes/holsters.dm new file mode 100644 index 00000000000..35bc54cd898 --- /dev/null +++ b/code/datums/storage/subtypes/holsters.dm @@ -0,0 +1,123 @@ +///Regular holster +/datum/storage/holster + max_slots = 1 + max_total_storage = 16 + open_sound = 'sound/items/handling/holster_open.ogg' + open_sound_vary = TRUE + +/datum/storage/holster/New(atom/parent, max_slots, max_specific_storage, max_total_storage, list/holdable_override) + . = ..() + + if(!length(holdable_override)) + holdable_override = list( + /obj/item/gun/ballistic/automatic/pistol, + /obj/item/gun/ballistic/revolver, + /obj/item/gun/energy/e_gun/mini, + /obj/item/gun/energy/disabler, + /obj/item/gun/energy/dueling, + /obj/item/food/grown/banana, + /obj/item/gun/energy/laser/thermal, + /obj/item/gun/ballistic/rifle/boltaction, //fits if you make it an obrez + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, + ) + + set_holdable(holdable_override) + +///Energy holster +/datum/storage/holster/energy + max_slots = 2 + +/datum/storage/holster/energy/New(atom/parent, max_slots, max_specific_storage, max_total_storage, list/holdable_override) + holdable_override = list( + /obj/item/gun/energy/e_gun/mini, + /obj/item/gun/energy/disabler, + /obj/item/gun/energy/dueling, + /obj/item/food/grown/banana, + /obj/item/gun/energy/laser/thermal, + /obj/item/gun/energy/recharge/ebow, + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, + ) + + return ..() + +///Detective holster +/datum/storage/holster/detective + max_slots = 3 + max_specific_storage = WEIGHT_CLASS_NORMAL + +/datum/storage/holster/detective/New(atom/parent, max_slots, max_specific_storage, max_total_storage, list/holdable_override) + holdable_override = list( + /obj/item/gun/ballistic/automatic/pistol, + /obj/item/ammo_box/magazine/m9mm, // Pistol magazines. + /obj/item/ammo_box/magazine/m9mm_aps, + /obj/item/ammo_box/magazine/m10mm, + /obj/item/ammo_box/magazine/m45, + /obj/item/ammo_box/magazine/m50, + /obj/item/gun/ballistic/revolver, + /obj/item/ammo_box/c38, // Revolver speedloaders. + /obj/item/ammo_box/a357, + /obj/item/ammo_box/strilka310, + /obj/item/ammo_box/magazine/toy/pistol, + /obj/item/gun/energy/e_gun/mini, + /obj/item/gun/energy/disabler, + /obj/item/gun/energy/dueling, + /obj/item/gun/energy/laser/thermal, + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, + /obj/item/gun/ballistic/rifle/boltaction, //fits if you make it an obrez + ) + + return ..() + +///Chameleon holster +/datum/storage/holster/chameleon + max_slots = 2 + silent = TRUE + +/datum/storage/holster/chameleon/New(atom/parent, max_slots, max_specific_storage, max_total_storage, list/holdable_override) + holdable_override = list( + /obj/item/gun/ballistic/automatic/pistol, + /obj/item/ammo_box/magazine/m9mm, + /obj/item/ammo_box/magazine/m9mm_aps, + /obj/item/ammo_box/magazine/m10mm, + /obj/item/ammo_box/magazine/m45, + /obj/item/ammo_box/magazine/m50, + /obj/item/gun/ballistic/revolver, + /obj/item/ammo_box/c38, + /obj/item/ammo_box/a357, + /obj/item/ammo_box/strilka310, + /obj/item/ammo_box/magazine/toy/pistol, + /obj/item/gun/energy/recharge/ebow, + /obj/item/gun/energy/e_gun/mini, + /obj/item/gun/energy/disabler, + /obj/item/gun/energy/dueling, + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, + ) + + return ..() + +///Nukie holster +/datum/storage/holster/nukie + max_slots = 2 + max_specific_storage = WEIGHT_CLASS_BULKY + +/datum/storage/holster/nukie/New(atom/parent, max_slots, max_specific_storage, max_total_storage, list/holdable_override) + holdable_override = list( + /obj/item/gun, // ALL guns. + /obj/item/ammo_box/magazine, // ALL magazines. + /obj/item/ammo_box/c38, //There isn't a speedloader parent type, so I just put these three here by hand. + /obj/item/ammo_box/a357, //I didn't want to just use /obj/item/ammo_box, because then this could hold huge boxes of ammo. + /obj/item/ammo_box/strilka310, + /obj/item/ammo_casing, // For shotgun shells, rockets, launcher grenades, and a few other things. + /obj/item/grenade, // All regular grenades, the big grenade launcher fires these. + ) + + return ..() + +///Nukie cowboy holster +/datum/storage/holster/nukie/cowboy + max_slots = 3 + max_specific_storage = WEIGHT_CLASS_NORMAL diff --git a/code/datums/storage/subtypes/implant.dm b/code/datums/storage/subtypes/implant.dm deleted file mode 100644 index 547e79ba81c..00000000000 --- a/code/datums/storage/subtypes/implant.dm +++ /dev/null @@ -1,15 +0,0 @@ -/datum/storage/implant - max_specific_storage = WEIGHT_CLASS_NORMAL - max_total_storage = 6 - max_slots = 2 - silent = TRUE - allow_big_nesting = TRUE - -/datum/storage/implant/New( - atom/parent, - max_slots, - max_specific_storage, - max_total_storage, -) - . = ..() - set_holdable(cant_hold_list = /obj/item/disk/nuclear) diff --git a/code/datums/storage/subtypes/lockboxes.dm b/code/datums/storage/subtypes/lockboxes.dm new file mode 100644 index 00000000000..9b6db314e18 --- /dev/null +++ b/code/datums/storage/subtypes/lockboxes.dm @@ -0,0 +1,32 @@ +///Regular lockbox +/datum/storage/lockbox + max_total_storage = 14 + max_slots = 4 + +///Medal lockbox +/datum/storage/lockbox/medal + max_slots = 10 + max_total_storage = 20 + max_specific_storage = WEIGHT_CLASS_SMALL + +/datum/storage/lockbox/medal/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/clothing/accessory/medal) + +///Bit running lockbox +/datum/storage/lockbox/bitrunning + max_specific_storage = WEIGHT_CLASS_NORMAL + max_slots = 1 + max_total_storage = 3 + locked = STORAGE_NOT_LOCKED + +///Dueling lockbox +/datum/storage/lockbox/dueling + max_specific_storage = WEIGHT_CLASS_SMALL + max_slots = 2 + +/datum/storage/lockbox/dueling/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/gun/energy/dueling) diff --git a/code/datums/storage/subtypes/medkits.dm b/code/datums/storage/subtypes/medkits.dm new file mode 100644 index 00000000000..6809d79caa9 --- /dev/null +++ b/code/datums/storage/subtypes/medkits.dm @@ -0,0 +1,144 @@ +///Regular medkit +/datum/storage/medkit + open_sound = 'sound/items/handling/medkit/medkit_open.ogg' + open_sound_vary = TRUE + rustle_sound = 'sound/items/handling/medkit/medkit_rustle.ogg' + max_specific_storage = WEIGHT_CLASS_SMALL + + ///List of everything a medkit can hold + VAR_FINAL/static/list/obj/item/list_of_everything_medkits_can_hold = list( + //surgery tools + /obj/item/surgical_drapes, + /obj/item/scalpel, + /obj/item/circular_saw, + /obj/item/bonesetter, + /obj/item/surgicaldrill, + /obj/item/retractor, + /obj/item/cautery, + /obj/item/hemostat, + /obj/item/blood_filter, + + //special tools + /obj/item/healthanalyzer, + /obj/item/dnainjector, + /obj/item/lazarus_injector, + /obj/item/implantcase, + /obj/item/implant, + /obj/item/implanter, + + //stacks + /obj/item/stack/medical, + /obj/item/stack/medical/gauze, + /obj/item/stack/sticky_tape, + /obj/item/stack/medical/suture/medicated, + /obj/item/stack/medical/mesh/advanced, + + //containers + /obj/item/reagent_containers/dropper, + /obj/item/reagent_containers/cup/beaker, + /obj/item/reagent_containers/cup/bottle, + /obj/item/reagent_containers/cup/tube, + /obj/item/reagent_containers/applicator/pill, + /obj/item/reagent_containers/syringe, + /obj/item/reagent_containers/medigel, + /obj/item/reagent_containers/spray, + /obj/item/reagent_containers/applicator/patch/libital, + /obj/item/reagent_containers/applicator/patch/aiuri, + /obj/item/reagent_containers/applicator/patch/synthflesh, + /obj/item/reagent_containers/hypospray/combat/empty, + /obj/item/reagent_containers/medigel/sterilizine, + /obj/item/reagent_containers/hypospray, + /obj/item/reagent_containers/blood, + + //storage items + /obj/item/storage/box/bandages, + /obj/item/storage/fancy/cigarettes, + /obj/item/storage/pill_bottle, + /obj/item/storage/box/bandages, + /obj/item/storage/box/evilmeds, + + //clothing + /obj/item/clothing/mask/surgical, + /obj/item/clothing/mask/breath, + /obj/item/clothing/mask/breath/medical, + /obj/item/clothing/neck/stethoscope, + /obj/item/clothing/glasses/hud/health/night/science, + /obj/item/clothing/gloves, + /obj/item/clothing/mask/muzzle, + /obj/item/clothing/glasses, + + //mod suite + /obj/item/mod/module/thread_ripper, + /obj/item/mod/module/surgical_processor/preloaded, + /obj/item/mod/module/defibrillator/combat, + /obj/item/mod/module/health_analyzer, + + //misc + /obj/item/lighter, + /obj/item/sensor_device, + /obj/item/radio, + /obj/item/bikehorn/rubberducky, + /obj/item/shears, + /obj/item/geiger_counter, + /obj/item/flashlight/pen, + /obj/item/extinguisher/mini, + /obj/item/stamp, + /obj/item/wrench/medical, + /obj/item/tank/internals/emergency_oxygen, + /obj/item/gun/syringe/syndicate, + /obj/item/pinpointer/crew, + /obj/item/holosign_creator/medical, + /obj/item/healthanalyzer/advanced, + /obj/item/autosurgeon/syndicate/emaggedsurgerytoolset, + ) + +/datum/storage/medkit/New(atom/parent, max_slots, max_specific_storage, max_total_storage, list/holdable_override) + . = ..() + + if(isnull(holdable_override)) + holdable_override = list_of_everything_medkits_can_hold + + set_holdable(holdable_override) + +///Surgery medkit +/datum/storage/medkit/surgery + max_slots = 12 + max_total_storage = 24 + max_specific_storage = WEIGHT_CLASS_NORMAL //holds the same equipment as a medibelt + +///Tatical medkit +/datum/storage/medkit/tatical + max_slots = 24 + max_total_storage = 24 + max_specific_storage = WEIGHT_CLASS_NORMAL + +///Tatical premium medkit +/datum/storage/medkit/tatical/premium + allow_big_nesting = TRUE // so you can put back the box you took out + max_total_storage = 36 + +///Corrinor medkit +/datum/storage/medkit/coroner + max_slots = 14 + max_total_storage = 24 + max_specific_storage = WEIGHT_CLASS_NORMAL + +/datum/storage/medkit/coroner/New(atom/parent, max_slots, max_specific_storage, max_total_storage, list/holdable_override) + + holdable_override = list( + /obj/item/reagent_containers, + /obj/item/bodybag, + /obj/item/toy/crayon, + /obj/item/pen, + /obj/item/paper, + /obj/item/surgical_drapes, + /obj/item/scalpel, + /obj/item/retractor, + /obj/item/hemostat, + /obj/item/cautery, + /obj/item/autopsy_scanner, + ) + + return ..() + + diff --git a/code/datums/storage/subtypes/organ_box.dm b/code/datums/storage/subtypes/organ_box.dm deleted file mode 100644 index de1cb5f5071..00000000000 --- a/code/datums/storage/subtypes/organ_box.dm +++ /dev/null @@ -1,17 +0,0 @@ -/datum/storage/organ_box - -/datum/storage/organ_box/handle_enter(obj/item/storage/organbox/source, obj/item/arrived) - . = ..() - - if(!istype(arrived) || !istype(source) || !source.coolant_to_spend()) - return - - arrived.freeze() - -/datum/storage/organ_box/handle_exit(datum/source, obj/item/gone) - . = ..() - - if(!istype(gone)) - return - - gone.unfreeze() diff --git a/code/datums/storage/subtypes/bag_of_holding.dm b/code/datums/storage/subtypes/others/bag_of_holding.dm similarity index 100% rename from code/datums/storage/subtypes/bag_of_holding.dm rename to code/datums/storage/subtypes/others/bag_of_holding.dm diff --git a/code/datums/storage/subtypes/cards.dm b/code/datums/storage/subtypes/others/cards.dm similarity index 100% rename from code/datums/storage/subtypes/cards.dm rename to code/datums/storage/subtypes/others/cards.dm diff --git a/code/datums/storage/subtypes/carpskin_bag.dm b/code/datums/storage/subtypes/others/carpskin_bag.dm similarity index 100% rename from code/datums/storage/subtypes/carpskin_bag.dm rename to code/datums/storage/subtypes/others/carpskin_bag.dm diff --git a/code/datums/storage/subtypes/extract_inventory.dm b/code/datums/storage/subtypes/others/extract_inventory.dm similarity index 100% rename from code/datums/storage/subtypes/extract_inventory.dm rename to code/datums/storage/subtypes/others/extract_inventory.dm diff --git a/code/datums/storage/subtypes/fish_case.dm b/code/datums/storage/subtypes/others/fish_case.dm similarity index 82% rename from code/datums/storage/subtypes/fish_case.dm rename to code/datums/storage/subtypes/others/fish_case.dm index e38d55e0e1d..4467d42e9ce 100644 --- a/code/datums/storage/subtypes/fish_case.dm +++ b/code/datums/storage/subtypes/others/fish_case.dm @@ -6,10 +6,14 @@ /datum/storage/fish_case/can_insert(obj/item/to_insert, mob/user, messages, force) . = ..() if(!.) - return . + return + if(!HAS_TRAIT(to_insert, TRAIT_AQUARIUM_CONTENT)) - if(messages && user) - user.balloon_alert(user, "can't hold!") + if(messages) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]: can't hold [to_insert.type] which does not have TRAIT_AQUARIUM_CONTENT") + else if(user) + user.balloon_alert(user, "can't hold!") return FALSE return . diff --git a/code/datums/storage/subtypes/others/misc.dm b/code/datums/storage/subtypes/others/misc.dm new file mode 100644 index 00000000000..132b92bc97a --- /dev/null +++ b/code/datums/storage/subtypes/others/misc.dm @@ -0,0 +1,328 @@ +//For storage types that are small enough to fit in this file + +///Test tube rack +/datum/storage/test_tube_rack + max_slots = 8 + screen_max_columns = 4 + screen_max_rows = 2 + allow_quick_gather = TRUE + allow_quick_empty = TRUE + +/datum/storage/test_tube_rack/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/reagent_containers/cup/tube) + +///Surgery tray +/datum/storage/surgery_tray + max_total_storage = 30 + max_specific_storage = WEIGHT_CLASS_NORMAL + max_slots = 14 + animated = FALSE + +/datum/storage/surgery_tray/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/autopsy_scanner, + /obj/item/blood_filter, + /obj/item/bonesetter, + /obj/item/cautery, + /obj/item/circular_saw, + /obj/item/clothing/mask/surgical, + /obj/item/hemostat, + /obj/item/razor, + /obj/item/retractor, + /obj/item/scalpel, + /obj/item/stack/medical/bone_gel, + /obj/item/stack/sticky_tape/surgical, + /obj/item/surgical_drapes, + /obj/item/surgicaldrill, + )) + +///Organ box +/datum/storage/organ_box + max_specific_storage = WEIGHT_CLASS_BULKY + max_total_storage = 21 + +/datum/storage/organ_box/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/organ, + /obj/item/bodypart, + /obj/item/food/icecream, + )) + +/datum/storage/organ_box/handle_enter(obj/item/storage/organbox/source, obj/item/arrived) + . = ..() + + if(!istype(arrived) || !istype(source) || !source.coolant_to_spend()) + return + + arrived.freeze() + +/datum/storage/organ_box/handle_exit(datum/source, obj/item/gone) + . = ..() + + if(!istype(gone)) + return + + gone.unfreeze() + +///Portable chem mixer +/datum/storage/portable_chem_mixer + max_total_storage = 200 + max_slots = 50 + +/datum/storage/portable_chem_mixer/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/reagent_containers/cup/beaker, + /obj/item/reagent_containers/cup/bottle, + /obj/item/reagent_containers/cup/tube, + /obj/item/reagent_containers/cup/glass/waterbottle, + /obj/item/reagent_containers/condiment, + )) + +///Implant +/datum/storage/implant + max_total_storage = 6 + max_slots = 2 + silent = TRUE + allow_big_nesting = TRUE + +/datum/storage/implant/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(cant_hold_list = /obj/item/disk/nuclear) + +///Drone storage +/datum/storage/drone + max_total_storage = 40 + max_specific_storage = WEIGHT_CLASS_NORMAL + max_slots = 10 + do_rustle = FALSE + +/datum/storage/drone/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/crowbar/drone, + /obj/item/screwdriver/drone, + /obj/item/wrench/drone, + /obj/item/weldingtool/drone, + /obj/item/wirecutters/drone, + /obj/item/multitool/drone, + /obj/item/pipe_dispenser/drone, + /obj/item/t_scanner/drone, + /obj/item/analyzer/drone, + /obj/item/soap/drone, + )) + +/datum/storage/drone/dump_content_at(atom/dest_object, dump_loc, mob/user) + return //no dumping of contents allowed + +///Basket +/datum/storage/basket + max_total_storage = 21 + +///Easter basket +/datum/storage/basket/easter/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/food/egg, + /obj/item/food/chocolateegg, + /obj/item/food/boiledegg, + /obj/item/surprise_egg + )) + +/datum/storage/basket/easter/handle_enter(datum/source, obj/item/arrived) + . = ..() + + countEggs(source) + +/datum/storage/basket/easter/proc/countEggs(obj/item/storage/basket/easter/basket) + basket.cut_overlays() + basket.add_overlay("basket-grass") + basket.add_overlay("basket-egg[min(basket.contents.len, 5)]") + +/datum/storage/basket/easter/handle_exit(datum/source, obj/item/gone) + . = ..() + + countEggs(source) + +///Briefcase +/datum/storage/briefcase + max_total_storage = 21 + +///Sniper brief case +/datum/storage/briefcase/sniper + max_slots = 13 + +//=======================Fancy storages====================== +///Cigrate boxes +/datum/storage/cigarette_box + display_contents = FALSE + +/datum/storage/cigarette_box/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/cigarette, + /obj/item/lighter, + )) + +///Coffee condiment display +/datum/storage/coffee_condi_display + max_slots = 14 + +/datum/storage/coffee_condi_display/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/reagent_containers/condiment/pack/sugar, + /obj/item/reagent_containers/condiment/creamer, + /obj/item/reagent_containers/condiment/pack/astrotame, + /obj/item/reagent_containers/condiment/chocolate, + )) + +///Coffee cart rack +/datum/storage/coffee_cart_rack + max_slots = 4 + +/datum/storage/coffee_cart_rack/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/coffee_cartridge) + +//================================================= + +///Pill bottle +/datum/storage/pillbottle + allow_quick_gather = TRUE + open_sound = 'sound/items/handling/pill_bottle_open.ogg' + open_sound_vary = FALSE + +/datum/storage/pillbottle/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/reagent_containers/applicator/pill, + /obj/item/reagent_containers/applicator/patch, + /obj/item/food/bait/natural, + )) + + +///Six pack beer +/datum/storage/sixcan + max_specific_storage = WEIGHT_CLASS_SMALL + max_total_storage = 12 + max_slots = 6 + +/datum/storage/sixcan/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(list( + /obj/item/reagent_containers/cup/soda_cans, + /obj/item/reagent_containers/cup/glass/bottle/beer, + /obj/item/reagent_containers/cup/glass/bottle/ale, + /obj/item/reagent_containers/cup/glass/waterbottle, + )) + +///Wallet storage +/datum/storage/wallet + max_specific_storage = WEIGHT_CLASS_SMALL + max_slots = 4 + +/datum/storage/wallet/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable( + can_hold_list = list( + /obj/item/stack/spacecash, + /obj/item/holochip, + /obj/item/card, + /obj/item/cigarette, + /obj/item/clothing/accessory/dogtag, + /obj/item/coin, + /obj/item/coupon, + /obj/item/dice, + /obj/item/disk, + /obj/item/flashlight/pen, + /obj/item/folder/biscuit, + /obj/item/food/chococoin, + /obj/item/implanter, + /obj/item/laser_pointer, + /obj/item/lighter, + /obj/item/lipstick, + /obj/item/match, + /obj/item/paper, + /obj/item/pen, + /obj/item/photo, + /obj/item/reagent_containers/dropper, + /obj/item/reagent_containers/syringe, + /obj/item/reagent_containers/applicator, + /obj/item/screwdriver, + /obj/item/seeds, + /obj/item/spess_knife, + /obj/item/stack/medical, + /obj/item/stamp, + /obj/item/toy/crayon, + ), + cant_hold_list = list( + /obj/item/screwdriver/power + ) + ) + +///Crayons storage +/datum/storage/crayons/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable( + can_hold_list = /obj/item/toy/crayon, + cant_hold_list = list( + /obj/item/toy/crayon/spraycan, + /obj/item/toy/crayon/mime, + /obj/item/toy/crayon/rainbow, + ), + ) + +///Dice storage +/datum/storage/dice + allow_quick_gather = TRUE + +/datum/storage/dice/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/dice) + +///Mail counterfeit +/datum/storage/mail_counterfeit + max_slots = 1 + allow_big_nesting = TRUE + +///Mail counterfeit advanced +/datum/storage/mail_counterfeit_advanced + max_slots = 21 + max_total_storage = 21 + allow_big_nesting = TRUE + +///Mail counterfeit bluespace +/datum/storage/mail_counterfeit_bluespace + max_total_storage = 35 + max_slots = 30 + max_specific_storage = WEIGHT_CLASS_GIGANTIC + allow_big_nesting = TRUE + +///Card binder +/datum/storage/card_binder + max_total_storage = 120 + max_slots = 60 + +/datum/storage/card_binder/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(/obj/item/tcgcard) diff --git a/code/datums/storage/subtypes/others/pod.dm b/code/datums/storage/subtypes/others/pod.dm new file mode 100644 index 00000000000..42822348387 --- /dev/null +++ b/code/datums/storage/subtypes/others/pod.dm @@ -0,0 +1,50 @@ +/datum/storage/pod + max_slots = 14 + max_total_storage = WEIGHT_CLASS_BULKY * 14 + allow_big_nesting = TRUE + /// If TRUE, we unlock regardless of security level + var/always_unlocked = FALSE + +/datum/storage/pod/open_storage(mob/to_show) + if(isliving(to_show) && SSsecurity_level.get_current_level_as_number() < SEC_LEVEL_RED) + to_chat(to_show, span_warning("The storage unit will only unlock during a Red or Delta security alert.")) + return FALSE + return ..() + +/datum/storage/pod/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + // all of these are a type below what actually spawn with + // (IE all space suits instead of just the emergency ones) + // because an enterprising traitor might be able to hide things, + // like their syndicate toolbox or softsuit. may be fun? + set_holdable(exception_hold_list = list( + /obj/item/clothing/suit/space, + /obj/item/pickaxe, + /obj/item/storage/toolbox, + )) + + RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(update_lock)) + +/datum/storage/pod/set_parent(atom/new_parent) + . = ..() + RegisterSignal(parent, COMSIG_ATOM_AFTER_SHUTTLE_MOVE, PROC_REF(pod_launch)) + +/datum/storage/pod/proc/update_lock(datum/source, new_level) + SIGNAL_HANDLER + if(always_unlocked) + return + + locked = (new_level < SEC_LEVEL_RED) ? STORAGE_FULLY_LOCKED : STORAGE_NOT_LOCKED + parent.update_appearance(UPDATE_ICON_STATE) + if(locked) // future todo : make `locked` a setter so this behavior can be built in (avoids exploits) + close_all() + +/datum/storage/pod/proc/pod_launch(datum/source, turf/old_turf) + SIGNAL_HANDLER + // This check is to ignore the movement of the shuttle from the transit level to the station as it is loaded in. + if(old_turf && is_reserved_level(old_turf.z)) + return + // If the pod was launched, the storage will always open. + always_unlocked = TRUE + locked = STORAGE_NOT_LOCKED + parent.update_appearance(UPDATE_ICON_STATE) diff --git a/code/datums/storage/subtypes/rped.dm b/code/datums/storage/subtypes/others/rped.dm similarity index 95% rename from code/datums/storage/subtypes/rped.dm rename to code/datums/storage/subtypes/others/rped.dm index a54d52ca359..374ed191a7f 100644 --- a/code/datums/storage/subtypes/rped.dm +++ b/code/datums/storage/subtypes/others/rped.dm @@ -43,7 +43,12 @@ /obj/item/circuitboard/computer, ) - return is_type_in_list(to_insert, exceptions) ? ..() : FALSE + if(!is_type_in_list(to_insert, exceptions)) + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]: [to_insert.type] is not a valid part") + return FALSE + + return ..() /datum/storage/rped/attempt_insert(obj/item/to_insert, mob/user, override, force, messages) if(isstack(to_insert)) diff --git a/code/datums/storage/subtypes/pockets.dm b/code/datums/storage/subtypes/pockets.dm index d7477b9c0ab..57bb0615730 100644 --- a/code/datums/storage/subtypes/pockets.dm +++ b/code/datums/storage/subtypes/pockets.dm @@ -1,3 +1,4 @@ +///Regular pockets /datum/storage/pockets max_slots = 2 max_specific_storage = WEIGHT_CLASS_SMALL @@ -17,16 +18,19 @@ else to_chat(user, span_notice("You discreetly slip [to_insert] into [parent].")) +///Small pockets /datum/storage/pockets/small max_slots = 1 max_specific_storage = WEIGHT_CLASS_SMALL attack_hand_interact = FALSE +///Tiny pockets /datum/storage/pockets/tiny max_slots = 1 max_specific_storage = WEIGHT_CLASS_TINY attack_hand_interact = FALSE +///Fedora pockets /datum/storage/pockets/small/fedora/New( atom/parent, max_slots, @@ -34,19 +38,21 @@ max_total_storage, ) . = ..() - var/static/list/exception_cache = typecacheof(list( + + set_holdable(exception_hold_list = list( /obj/item/katana, /obj/item/toy/katana, /obj/item/nullrod/claymore/katana, /obj/item/energy_katana, /obj/item/gun/ballistic/automatic/tommygun, )) - exception_hold = exception_cache +///Fedora detective pockets /datum/storage/pockets/small/fedora/detective attack_hand_interact = TRUE // so the detectives would discover pockets in their hats click_alt_open = FALSE +///Chef hat pocket /datum/storage/pockets/chefhat attack_hand_interact = TRUE max_slots = 1 @@ -59,6 +65,7 @@ max_total_storage, ) . = ..() + set_holdable(list( /obj/item/clothing/head/mob_holder, /obj/item/food/deadmouse @@ -70,8 +77,11 @@ var/obj/item/clothing/head/mob_holder/mausholder = to_insert if(locate(/mob/living/basic/mouse) in mausholder.contents) return + if(messages == STORAGE_ERROR_INSERT) + stack_trace("[parent.type]: no mouse to hold [to_insert]") return FALSE +///Shoe pockets /datum/storage/pockets/shoes max_slots = 2 attack_hand_interact = FALSE @@ -85,41 +95,47 @@ max_total_storage, ) . = ..() - set_holdable(list( - /obj/item/knife, - /obj/item/spess_knife, - /obj/item/switchblade, - /obj/item/boxcutter, - /obj/item/pen, - /obj/item/scalpel, - /obj/item/dnainjector, - /obj/item/reagent_containers/syringe, - /obj/item/reagent_containers/applicator/pill, - /obj/item/reagent_containers/hypospray/medipen, - /obj/item/reagent_containers/dropper, - /obj/item/implanter, - /obj/item/screwdriver, - /obj/item/weldingtool/mini, - /obj/item/firing_pin, - /obj/item/suppressor, - /obj/item/ammo_box/magazine/m9mm, - /obj/item/ammo_box/magazine/m10mm, - /obj/item/ammo_box/magazine/m45, - /obj/item/ammo_box/magazine/toy/pistol, - /obj/item/ammo_casing, - /obj/item/lipstick, - /obj/item/cigarette, - /obj/item/lighter, - /obj/item/match, - /obj/item/holochip, - /obj/item/toy/crayon, - /obj/item/reagent_containers/cup/glass/flask), - list(/obj/item/screwdriver/power, - /obj/item/ammo_casing/rocket, - /obj/item/cigarette/pipe, - /obj/item/toy/crayon/spraycan) - ) + set_holdable( + can_hold_list = list( + /obj/item/knife, + /obj/item/spess_knife, + /obj/item/switchblade, + /obj/item/boxcutter, + /obj/item/pen, + /obj/item/scalpel, + /obj/item/dnainjector, + /obj/item/reagent_containers/syringe, + /obj/item/reagent_containers/applicator/pill, + /obj/item/reagent_containers/hypospray/medipen, + /obj/item/reagent_containers/dropper, + /obj/item/implanter, + /obj/item/screwdriver, + /obj/item/weldingtool/mini, + /obj/item/firing_pin, + /obj/item/suppressor, + /obj/item/ammo_box/magazine/m9mm, + /obj/item/ammo_box/magazine/m10mm, + /obj/item/ammo_box/magazine/m45, + /obj/item/ammo_box/magazine/toy/pistol, + /obj/item/ammo_casing, + /obj/item/lipstick, + /obj/item/cigarette, + /obj/item/lighter, + /obj/item/match, + /obj/item/holochip, + /obj/item/toy/crayon, + /obj/item/reagent_containers/cup/glass/flask, + ), + cant_hold_list = list( + /obj/item/screwdriver/power, + /obj/item/ammo_casing/rocket, + /obj/item/cigarette/pipe, + /obj/item/toy/crayon/spraycan, + ) + ) + +///Clown shoe pockets /datum/storage/pockets/shoes/clown/New( atom/parent, max_slots, @@ -127,6 +143,7 @@ max_total_storage, ) . = ..() + set_holdable( can_hold_list = list( /obj/item/ammo_box/magazine/m10mm, @@ -164,6 +181,7 @@ ), ) +///Protector pocket /datum/storage/pockets/pocketprotector max_slots = 3 max_specific_storage = WEIGHT_CLASS_TINY @@ -175,6 +193,7 @@ max_total_storage, ) . = ..() + set_holdable(list( //Same items as a PDA /obj/item/pen, /obj/item/toy/crayon, @@ -183,6 +202,7 @@ /obj/item/lipstick, )) +///Helmet pockets /datum/storage/pockets/helmet max_slots = 2 quickdraw = TRUE @@ -195,12 +215,15 @@ max_total_storage, ) . = ..() - set_holdable(list(/obj/item/reagent_containers/cup/glass/bottle/vodka, - /obj/item/reagent_containers/cup/glass/bottle/molotov, - /obj/item/reagent_containers/cup/glass/drinkingglass, - /obj/item/ammo_box/strilka310)) + set_holdable(list( + /obj/item/reagent_containers/cup/glass/bottle/vodka, + /obj/item/reagent_containers/cup/glass/bottle/molotov,, + /obj/item/reagent_containers/cup/glass/drinkingglass,, + /obj/item/ammo_box/strilka310 + )) +///Void cloak pocket /datum/storage/pockets/void_cloak quickdraw = TRUE max_total_storage = 5 // 2 small items + 1 tiny item, or 1 normal item + 1 small item @@ -213,19 +236,24 @@ max_total_storage, ) . = ..() - set_holdable(list( - /obj/item/ammo_box/strilka310/lionhunter, - /obj/item/bodypart, // Bodyparts are often used in rituals. They're also often normal sized, so you can only fit one. - /obj/item/clothing/neck/eldritch_amulet, - /obj/item/clothing/neck/heretic_focus, - /obj/item/codex_cicatrix, - /obj/item/eldritch_potion, - /obj/item/food/grown/poppy, // Used to regain a Living Heart. - /obj/item/melee/rune_carver, - /obj/item/melee/sickly_blade, // Normal sized, so you can only fit one. - /obj/item/organ, // Organs are also often used in rituals. - /obj/item/reagent_containers/cup/beaker/eldritch, - )) - var/static/list/exception_cache = typecacheof(list(/obj/item/bodypart, /obj/item/melee/sickly_blade)) - exception_hold = exception_cache + set_holdable( + can_hold_list = list( + /obj/item/ammo_box/strilka310/lionhunter, + /obj/item/bodypart, // Bodyparts are often used in rituals. They're also often normal sized, so you can only fit one. + /obj/item/clothing/neck/eldritch_amulet, + /obj/item/clothing/neck/heretic_focus, + /obj/item/codex_cicatrix, + /obj/item/eldritch_potion, + /obj/item/food/grown/poppy, // Used to regain a Living Heart. + /obj/item/melee/rune_carver, + /obj/item/melee/sickly_blade, // Normal sized, so you can only fit one. + /obj/item/organ, // Organs are also often used in rituals. + /obj/item/reagent_containers/cup/beaker/eldritch, + ), + exception_hold_list = list( + /obj/item/bodypart, + /obj/item/melee/sickly_blade + ) + ) + diff --git a/code/datums/storage/subtypes/portable_chem_mixer.dm b/code/datums/storage/subtypes/portable_chem_mixer.dm deleted file mode 100644 index fcf5c6ec412..00000000000 --- a/code/datums/storage/subtypes/portable_chem_mixer.dm +++ /dev/null @@ -1,16 +0,0 @@ -/datum/storage/portable_chem_mixer - max_total_storage = 200 - max_slots = 50 - -/datum/storage/portable_chem_mixer/New(atom/parent, max_slots, max_specific_storage, max_total_storage) - . = ..() - - var/static/list/obj/item/reagent_containers/containers = list( - /obj/item/reagent_containers/cup/beaker, - /obj/item/reagent_containers/cup/bottle, - /obj/item/reagent_containers/cup/tube, - /obj/item/reagent_containers/cup/glass/waterbottle, - /obj/item/reagent_containers/condiment, - ) - - set_holdable(containers) diff --git a/code/datums/storage/subtypes/surgery_tray.dm b/code/datums/storage/subtypes/surgery_tray.dm deleted file mode 100644 index c4d8780e051..00000000000 --- a/code/datums/storage/subtypes/surgery_tray.dm +++ /dev/null @@ -1,29 +0,0 @@ -/datum/storage/surgery_tray - max_total_storage = 30 - max_specific_storage = WEIGHT_CLASS_NORMAL - max_slots = 14 - animated = FALSE - -/datum/storage/surgery_tray/New( - atom/parent, - max_slots, - max_specific_storage, - max_total_storage, -) - . = ..() - set_holdable(list( - /obj/item/autopsy_scanner, - /obj/item/blood_filter, - /obj/item/bonesetter, - /obj/item/cautery, - /obj/item/circular_saw, - /obj/item/clothing/mask/surgical, - /obj/item/hemostat, - /obj/item/razor, - /obj/item/retractor, - /obj/item/scalpel, - /obj/item/stack/medical/bone_gel, - /obj/item/stack/sticky_tape/surgical, - /obj/item/surgical_drapes, - /obj/item/surgicaldrill, - )) diff --git a/code/datums/storage/subtypes/test_tube_rack.dm b/code/datums/storage/subtypes/test_tube_rack.dm deleted file mode 100644 index aa000cdbafa..00000000000 --- a/code/datums/storage/subtypes/test_tube_rack.dm +++ /dev/null @@ -1,15 +0,0 @@ -/datum/storage/test_tube_rack - max_slots = 8 - screen_max_columns = 4 - screen_max_rows = 2 - allow_quick_gather = TRUE - allow_quick_empty = TRUE - -/datum/storage/test_tube_rack/New( - atom/parent, - max_slots, - max_specific_storage, - max_total_storage, -) - . = ..() - set_holdable(/obj/item/reagent_containers/cup/tube) diff --git a/code/datums/storage/subtypes/toolboxes.dm b/code/datums/storage/subtypes/toolboxes.dm new file mode 100644 index 00000000000..5babe139394 --- /dev/null +++ b/code/datums/storage/subtypes/toolboxes.dm @@ -0,0 +1,49 @@ +///Normal toolboxes +/datum/storage/toolbox + open_sound = 'sound/items/handling/toolbox/toolbox_open.ogg' + rustle_sound = 'sound/items/handling/toolbox/toolbox_rustle.ogg' + +///Electrical toolbox +/datum/storage/toolbox/electrical + max_slots = 8 + max_total_storage = 15 + +///Old heirloom toolbox +/datum/storage/toolbox/old_heirloom + max_specific_storage = WEIGHT_CLASS_SMALL + +///Syndicate toolbox +/datum/storage/toolbox/syndicate + silent = TRUE + +///Artistic toolbox +/datum/storage/toolbox/artistic + max_total_storage = 25 + max_slots = 11 + +///Gun storage toolbox +/datum/storage/toolbox/guncase + max_slots = 4 + max_total_storage = 7 //enough to hold ONE bulky gun and the ammo boxes + allow_big_nesting = TRUE + max_specific_storage = WEIGHT_CLASS_BULKY + +///Double sword toolbox +/datum/storage/toolbox/double_sword + max_slots = 5 + max_total_storage = 10 //it'll hold enough + max_specific_storage = WEIGHT_CLASS_BULKY + +///Fishing toolbox +/datum/storage/toolbox/fishing/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + set_holdable(exception_hold_list = /obj/item/fishing_rod) + +///Small fishing toolbox +/datum/storage/toolbox/fishing/small + max_specific_storage = WEIGHT_CLASS_SMALL + +///Ancient bundle toolbox +/datum/storage/toolbox/ancient_bundle + max_slots = 8 diff --git a/code/datums/storage/subtypes/trash.dm b/code/datums/storage/subtypes/trash.dm deleted file mode 100644 index b4f0e4353e3..00000000000 --- a/code/datums/storage/subtypes/trash.dm +++ /dev/null @@ -1,11 +0,0 @@ -/datum/storage/trash - -/datum/storage/trash/remove_single(mob/removing, obj/item/thing, atom/remove_to_loc, silent) - real_location.visible_message( - span_notice("[removing] starts fishing around inside [parent]."), - span_notice("You start digging around in [parent] to try and pull something out."), - ) - if(!do_after(removing, 1.5 SECONDS, parent)) - return FALSE - - return ..() diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 1705a4241fb..b05f0ac1099 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -337,8 +337,10 @@ return ..() /obj/item/storage/briefcase/launchpad/PopulateContents() - new /obj/item/pen(src) - new /obj/item/launchpad_remote(src, pad) + return list( + /obj/item/pen, + new /obj/item/launchpad_remote(null, pad), + ) /obj/item/storage/briefcase/launchpad/attack_self(mob/user) if(!isturf(user.loc)) //no setting up in a locker diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 7396fbb59ca..a2fd4fe6663 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -725,27 +725,18 @@ icon_state = "crayonbox" w_class = WEIGHT_CLASS_SMALL custom_materials = list(/datum/material/cardboard = SHEET_MATERIAL_AMOUNT) - -/obj/item/storage/crayons/Initialize(mapload) - . = ..() - atom_storage.set_holdable( - can_hold_list = /obj/item/toy/crayon, - cant_hold_list = list( - /obj/item/toy/crayon/spraycan, - /obj/item/toy/crayon/mime, - /obj/item/toy/crayon/rainbow, - ), - ) + storage_type = /datum/storage/crayons /obj/item/storage/crayons/PopulateContents() - new /obj/item/toy/crayon/red(src) - new /obj/item/toy/crayon/orange(src) - new /obj/item/toy/crayon/yellow(src) - new /obj/item/toy/crayon/green(src) - new /obj/item/toy/crayon/blue(src) - new /obj/item/toy/crayon/purple(src) - new /obj/item/toy/crayon/black(src) - update_appearance() + return list( + new /obj/item/toy/crayon/red, + new /obj/item/toy/crayon/orange, + new /obj/item/toy/crayon/yellow, + new /obj/item/toy/crayon/green, + new /obj/item/toy/crayon/blue, + new /obj/item/toy/crayon/purple, + new /obj/item/toy/crayon/black, + ) /obj/item/storage/crayons/update_overlays() . = ..() diff --git a/code/game/objects/items/devices/spyglasses.dm b/code/game/objects/items/devices/spyglasses.dm index 0c91b8b2255..4e16df7f485 100644 --- a/code/game/objects/items/devices/spyglasses.dm +++ b/code/game/objects/items/devices/spyglasses.dm @@ -99,8 +99,13 @@ A shrill beep coming from your SpySpeks means that they can't connect to the inc "} /obj/item/storage/box/rxglasses/spyglasskit/PopulateContents() - var/obj/item/clothing/accessory/spy_bug/newbug = new(src) - var/obj/item/clothing/glasses/sunglasses/spy/newglasses = new(src) + var/obj/item/clothing/accessory/spy_bug/newbug = new(null) + var/obj/item/clothing/glasses/sunglasses/spy/newglasses = new(null) newbug.linked_glasses = newglasses newglasses.linked_bug = newbug - new /obj/item/paper/fluff/nerddocs(src) + + return list( + newbug, + newglasses, + /obj/item/paper/fluff/nerddocs + ) diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 2fb6de0c03e..6e9466d732b 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -413,12 +413,14 @@ effective or pretty fucking useless. desc = "You feel a strange urge to hit this with a wrench." /obj/item/storage/toolbox/emergency/turret/PopulateContents() - new /obj/item/screwdriver(src) - new /obj/item/wrench/combat(src) - new /obj/item/weldingtool(src) - new /obj/item/crowbar(src) - new /obj/item/analyzer(src) - new /obj/item/wirecutters(src) + return list( + /obj/item/screwdriver, + /obj/item/wrench/combat, + /obj/item/weldingtool, + /obj/item/crowbar, + /obj/item/analyzer, + /obj/item/wirecutters, + ) /obj/item/storage/toolbox/emergency/turret/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(!istype(tool, /obj/item/wrench/combat)) diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index e65b4bada08..a9f5f6404fb 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -9,20 +9,10 @@ icon = 'icons/obj/toys/dice.dmi' icon_state = "dicebag" w_class = WEIGHT_CLASS_SMALL - -/obj/item/storage/dice/Initialize(mapload) - . = ..() - atom_storage.allow_quick_gather = TRUE - atom_storage.set_holdable(/obj/item/dice) + storage_type = /datum/storage/dice /obj/item/storage/dice/PopulateContents() - new /obj/item/dice/d4(src) - new /obj/item/dice/d6(src) - new /obj/item/dice/d8(src) - new /obj/item/dice/d10(src) - new /obj/item/dice/d12(src) - new /obj/item/dice/d20(src) - var/picked = pick(list( + var/static/list/obj/item/options = list( /obj/item/dice/d1, /obj/item/dice/d2, /obj/item/dice/fudge, @@ -31,8 +21,17 @@ /obj/item/dice/eightbd20, /obj/item/dice/fourdd6, /obj/item/dice/d100, - )) - new picked(src) + ) + + return list( + /obj/item/dice/d4, + /obj/item/dice/d6, + /obj/item/dice/d8, + /obj/item/dice/d10, + /obj/item/dice/d12, + /obj/item/dice/d20, + pick(options), + ) /obj/item/storage/dice/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!")) @@ -41,14 +40,19 @@ /obj/item/storage/dice/hazard /obj/item/storage/dice/hazard/PopulateContents() - new /obj/item/dice/d6(src) - new /obj/item/dice/d6(src) - new /obj/item/dice/d6(src) + var/list/obj/item/dices = list( + new /obj/item/dice/d6, + new /obj/item/dice/d6, + new /obj/item/dice/d6, + ) + for(var/i in 1 to 2) if(prob(7)) - new /obj/item/dice/d6/ebony(src) + dices += /obj/item/dice/d6/ebony else - new /obj/item/dice/d6(src) + dices += /obj/item/dice/d6 + + return dices ///this is a prototype for dice, for a real d6 use "/obj/item/dice/d6" /obj/item/dice diff --git a/code/game/objects/items/food/moth.dm b/code/game/objects/items/food/moth.dm index eeaa02cebc8..d4e6c0398a6 100644 --- a/code/game/objects/items/food/moth.dm +++ b/code/game/objects/items/food/moth.dm @@ -916,8 +916,12 @@ return . /obj/item/storage/box/gum/wake_up/PopulateContents() - for(var/i in 1 to 4) - new/obj/item/food/bubblegum/wake_up(src) + return list( + /obj/item/food/bubblegum/wake_up, + /obj/item/food/bubblegum/wake_up, + /obj/item/food/bubblegum/wake_up, + /obj/item/food/bubblegum/wake_up, + ) /obj/item/food/spacers_sidekick name = "\improper Spacer's Sidekick mints" diff --git a/code/game/objects/items/mail.dm b/code/game/objects/items/mail.dm index 90888b062a3..7cad2543ba8 100644 --- a/code/game/objects/items/mail.dm +++ b/code/game/objects/items/mail.dm @@ -345,18 +345,7 @@ worn_icon_state = "mailbag" resistance_flags = FLAMMABLE custom_premium_price = PAYCHECK_LOWER - -/obj/item/storage/bag/mail/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 42 - atom_storage.max_slots = 21 - atom_storage.numerical_stacking = FALSE - atom_storage.set_holdable(list( - /obj/item/mail, - /obj/item/delivery/small, - /obj/item/paper - )) + storage_type = /datum/storage/bag/mail /obj/item/paper/fluff/junkmail_redpill name = "smudged paper" @@ -495,12 +484,7 @@ w_class = WEIGHT_CLASS_NORMAL icon = 'icons/obj/antags/syndicate_tools.dmi' icon_state = "mail_counterfeit_device" - -/obj/item/storage/mail_counterfeit_device/Initialize(mapload) - . = ..() - atom_storage.max_slots = 1 - atom_storage.allow_big_nesting = TRUE - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL + storage_type = /datum/storage/mail_counterfeit /obj/item/storage/mail_counterfeit_device/examine_more(mob/user) . = ..() @@ -572,19 +556,17 @@ /// Unobtainable item mostly for (b)admin purposes. /obj/item/storage/mail_counterfeit_device/advanced name = "GLA-MACRO mail counterfeit device" + storage_type = /datum/storage/mail_counterfeit_advanced /obj/item/storage/mail_counterfeit_device/advanced/Initialize(mapload) . = ..() desc += " This model is highly advanced and capable of compressing items, making mail's storage space comparable to standard backpack." - create_storage(max_slots = 21, max_total_storage = 21) - atom_storage.allow_big_nesting = TRUE /// Unobtainable item mostly for (b)admin purposes. /obj/item/storage/mail_counterfeit_device/bluespace name = "GLA-ULTRA mail counterfeit device" + storage_type = /datum/storage/mail_counterfeit_bluespace /obj/item/storage/mail_counterfeit_device/bluespace/Initialize(mapload) . = ..() desc += " This model is the most advanced and capable of performing crazy bluespace compressions, making mail's storage space comparable to bluespace backpack." - create_storage(max_specific_storage = WEIGHT_CLASS_GIGANTIC, max_total_storage = 35, max_slots = 30) - atom_storage.allow_big_nesting = TRUE diff --git a/code/game/objects/items/pinpointer.dm b/code/game/objects/items/pinpointer.dm index af7b877bb1d..ace2ef95162 100644 --- a/code/game/objects/items/pinpointer.dm +++ b/code/game/objects/items/pinpointer.dm @@ -192,12 +192,14 @@ name = "pinpointer pair box" /obj/item/storage/box/pinpointer_pairs/PopulateContents() - var/obj/item/pinpointer/pair/A = new(src) - var/obj/item/pinpointer/pair/B = new(src) + var/obj/item/pinpointer/pair/A = new(null) + var/obj/item/pinpointer/pair/B = new(null) A.other_pair = B B.other_pair = A + return list(A, B) + /obj/item/pinpointer/shuttle name = "bounty shuttle pinpointer" desc = "A handheld tracking device that locates the bounty hunter shuttle for quick escapes." diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm index 4e7430d56a5..c6279f80f61 100644 --- a/code/game/objects/items/religion.dm +++ b/code/game/objects/items/religion.dm @@ -257,10 +257,7 @@ name = "\improper Nanotrasen banner backpack" desc = "It's a backpack with lots of extra room. A banner with Nanotrasen's logo is attached, that can't be removed." icon_state = "backpack-banner" - -/obj/item/storage/backpack/bannerpack/Initialize(mapload) - . = ..() - atom_storage.max_total_storage = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times. + storage_type = /datum/storage/backpack/bannerpack /obj/item/storage/backpack/bannerpack/red name = "red banner backpack" @@ -411,18 +408,6 @@ /obj/item/clothing/shoes/plate/blue icon_state = "crusader-blue" -/obj/item/storage/box/itemset/crusader/blue/PopulateContents() - new /obj/item/clothing/suit/chaplainsuit/armor/crusader/blue(src) - new /obj/item/clothing/head/helmet/plate/crusader/blue(src) - new /obj/item/clothing/gloves/plate/blue(src) - new /obj/item/clothing/shoes/plate/blue(src) - -/obj/item/storage/box/itemset/crusader/red/PopulateContents() - new /obj/item/clothing/suit/chaplainsuit/armor/crusader/red(src) - new /obj/item/clothing/head/helmet/plate/crusader/red(src) - new /obj/item/clothing/gloves/plate/red(src) - new /obj/item/clothing/shoes/plate/red(src) - /obj/item/claymore/weak desc = "This one is rusted." force = 24 diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index f2ed4287c11..c140fc5f831 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -238,13 +238,9 @@ icon = 'icons/obj/storage/ethereal.dmi' worn_icon = 'icons/mob/clothing/back/ethereal.dmi' icon_state = "saddlepack" + storage_type = /datum/storage/backpack/sadle_bag -/obj/item/storage/backpack/saddlepack/Initialize(mapload) - . = ..() - atom_storage.max_total_storage = 26 - -// MEAT MEAT MEAT MEAT MEAT - +/// MEAT MEAT MEAT MEAT MEAT /obj/item/storage/backpack/meat name = "\improper MEAT" desc = "MEAT MEAT MEAT MEAT MEAT MEAT" @@ -302,6 +298,7 @@ desc = "A trendy looking satchel." icon_state = "satchel-norm" inhand_icon_state = "satchel-norm" + storage_type = /datum/storage/backpack/satchel /obj/item/storage/backpack/satchel/leather name = "leather satchel" @@ -310,7 +307,7 @@ inhand_icon_state = "satchel" /obj/item/storage/backpack/satchel/leather/withwallet/PopulateContents() - new /obj/item/storage/wallet/random(src) + return /obj/item/storage/wallet/random /obj/item/storage/backpack/satchel/fireproof resistance_flags = FIRE_PROOF @@ -389,396 +386,25 @@ inhand_icon_state = "satchel-flat" w_class = WEIGHT_CLASS_NORMAL //Can fit in backpacks itself. -/obj/item/storage/backpack/satchel/flat/Initialize(mapload) - . = ..() - AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE, INVISIBILITY_OBSERVER, use_anchor = TRUE) - atom_storage.max_total_storage = 15 - atom_storage.set_holdable(cant_hold_list = /obj/item/storage/backpack/satchel/flat) //muh recursive backpacks - ADD_TRAIT(src, TRAIT_CONTRABAND_BLOCKER, INNATE_TRAIT) +/obj/item/storage/backpack/satchel/flat/PopulateContents(datum/storage_config/config) + config.contents_are_exceptions = TRUE -/obj/item/storage/backpack/satchel/flat/PopulateContents() - for(var/items in 1 to 4) + for(var/_ in 1 to 4) new /obj/effect/spawner/random/contraband(src) -/obj/item/storage/backpack/satchel/flat/with_tools/PopulateContents() - new /obj/item/stack/tile/iron/base(src) - new /obj/item/crowbar(src) + . = list() + for(var/obj/item/insert as anything in src) + insert.moveToNullspace() + . += insert - ..() +/obj/item/storage/backpack/satchel/flat/with_tools/PopulateContents() + return list( + /obj/item/stack/tile/iron/base, + /obj/item/crowbar, + ) /obj/item/storage/backpack/satchel/flat/empty/PopulateContents() - return - -/obj/item/storage/backpack/duffelbag - name = "duffel bag" - desc = "A large duffel bag for holding extra things." - icon_state = "duffel" - inhand_icon_state = "duffel" - actions_types = list(/datum/action/item_action/zipper) - action_slots = ALL - storage_type = /datum/storage/duffel - // How much to slow you down if your bag isn't zipped up - var/zip_slowdown = 1 - /// If this bag is zipped (contents hidden) up or not - /// Starts enabled so you're forced to interact with it to "get" it - var/zipped_up = TRUE - // How much time it takes to zip up (close) the duffelbag - var/zip_up_duration = 0.5 SECONDS - // Audio played during zipup - var/zip_up_sfx = 'sound/items/zip/zip_up.ogg' - // How much time it takes to unzip the duffel - var/unzip_duration = 2.1 SECONDS - // Audio played during unzip - var/unzip_sfx = 'sound/items/zip/un_zip.ogg' - -/obj/item/storage/backpack/duffelbag/Initialize(mapload) - . = ..() - set_zipper(TRUE) - -/obj/item/storage/backpack/duffelbag/update_desc(updates) - . = ..() - desc = "[initial(desc)]
[zipped_up ? "It's zipped up, preventing you from accessing its contents." : "It's unzipped, and harder to move in."]" - -/obj/item/storage/backpack/duffelbag/attack_self(mob/user, modifiers) - if(loc != user) // God fuck TK - return ..() - if(zipped_up) - return attack_hand(user, modifiers) - else - return attack_hand_secondary(user, modifiers) - -/obj/item/storage/backpack/duffelbag/attack_self_secondary(mob/user, modifiers) - attack_self(user, modifiers) - return ..() - -// If we're zipped, click to unzip -/obj/item/storage/backpack/duffelbag/attack_hand(mob/user, list/modifiers) - if(loc != user) - // Hacky, but please don't be cringe yeah? - atom_storage.silent = TRUE - . = ..() - atom_storage.silent = initial(atom_storage.silent) - return - if(!zipped_up) - return ..() - - balloon_alert(user, "unzipping...") - playsound(src, unzip_sfx, 100, FALSE) - var/datum/callback/can_unzip = CALLBACK(src, PROC_REF(zipper_matches), TRUE) - if(!do_after(user, unzip_duration, src, extra_checks = can_unzip)) - user.balloon_alert(user, "unzip failed!") - return - balloon_alert(user, "unzipped") - set_zipper(FALSE) - return TRUE - -// Vis versa -/obj/item/storage/backpack/duffelbag/attack_hand_secondary(mob/user, list/modifiers) - if(loc != user) - return ..() - if(zipped_up) - return SECONDARY_ATTACK_CALL_NORMAL - - balloon_alert(user, "zipping...") - playsound(src, zip_up_sfx, 100, FALSE) - var/datum/callback/can_zip = CALLBACK(src, PROC_REF(zipper_matches), FALSE) - if(!do_after(user, zip_up_duration, src, extra_checks = can_zip)) - user.balloon_alert(user, "zip failed!") - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - balloon_alert(user, "zipped") - set_zipper(TRUE) - return SECONDARY_ATTACK_CONTINUE_CHAIN - -/// Checks to see if the zipper matches the passed in state -/// Returns true if so, false otherwise -/obj/item/storage/backpack/duffelbag/proc/zipper_matches(matching_value) - return zipped_up == matching_value - -/obj/item/storage/backpack/duffelbag/proc/set_zipper(new_zip) - zipped_up = new_zip - SEND_SIGNAL(src, COMSIG_DUFFEL_ZIP_CHANGE, new_zip) - if(zipped_up) - slowdown = initial(slowdown) - atom_storage.locked = STORAGE_SOFT_LOCKED - atom_storage.display_contents = FALSE - for(var/obj/item/weapon as anything in get_all_contents_type(/obj/item)) //close ui of this and all items inside dufflebag - weapon.atom_storage?.close_all() //not everything has storage initialized - else - slowdown = zip_slowdown - atom_storage.locked = STORAGE_NOT_LOCKED - atom_storage.display_contents = TRUE - - if(isliving(loc)) - var/mob/living/wearer = loc - wearer.update_equipment_speed_mods() - update_appearance() - -/obj/item/storage/backpack/duffelbag/cursed - name = "living duffel bag" - desc = "A cursed clown duffel bag that hungers for food of any kind. A warning label suggests that it eats food inside. \ - If that food happens to be a horribly ruined mess or the chef scrapped out of the microwave, or poisoned in some way, \ - then it might have negative effects on the bag..." - icon_state = "duffel-curse" - inhand_icon_state = "duffel-curse" - zip_slowdown = 2 - max_integrity = 100 - -/obj/item/storage/backpack/duffelbag/cursed/Initialize(mapload) - . = ..() - AddComponent(/datum/component/curse_of_hunger, add_dropdel = TRUE) - -/obj/item/storage/backpack/duffelbag/captain - name = "captain's duffel bag" - desc = "A large duffel bag for holding extra captainly goods." - icon_state = "duffel-captain" - inhand_icon_state = "duffel-captain" - -/obj/item/storage/backpack/duffelbag/med - name = "medical duffel bag" - desc = "A large duffel bag for holding extra medical supplies." - icon_state = "duffel-medical" - inhand_icon_state = "duffel-med" - -/obj/item/storage/backpack/duffelbag/coroner - name = "coroner duffel bag" - desc = "A large duffel bag for holding large amounts of organs at once." - icon_state = "duffel-coroner" - inhand_icon_state = "duffel-coroner" - -/obj/item/storage/backpack/duffelbag/explorer - name = "explorer duffel bag" - desc = "A large duffel bag for holding extra exotic treasures." - icon_state = "duffel-explorer" - inhand_icon_state = "duffel-explorer" - -/obj/item/storage/backpack/duffelbag/hydroponics - name = "hydroponic's duffel bag" - desc = "A large duffel bag for holding extra gardening tools." - icon_state = "duffel-hydroponics" - inhand_icon_state = "duffel-hydroponics" - -/obj/item/storage/backpack/duffelbag/chemistry - name = "chemistry duffel bag" - desc = "A large duffel bag for holding extra chemical substances." - icon_state = "duffel-chemistry" - inhand_icon_state = "duffel-chemistry" - -/obj/item/storage/backpack/duffelbag/genetics - name = "geneticist's duffel bag" - desc = "A large duffel bag for holding extra genetic mutations." - icon_state = "duffel-genetics" - inhand_icon_state = "duffel-genetics" - -/obj/item/storage/backpack/duffelbag/science - name = "scientist's duffel bag" - desc = "A large duffel bag for holding extra scientific components." - icon_state = "duffel-science" - inhand_icon_state = "duffel-sci" - -/obj/item/storage/backpack/duffelbag/virology - name = "virologist's duffel bag" - desc = "A large duffel bag for holding extra viral bottles." - icon_state = "duffel-virology" - inhand_icon_state = "duffel-virology" - -/obj/item/storage/backpack/duffelbag/sec - name = "security duffel bag" - desc = "A large duffel bag for holding extra security supplies and ammunition." - icon_state = "duffel-security" - inhand_icon_state = "duffel-sec" - -/obj/item/storage/backpack/duffelbag/sec/surgery - name = "surgical duffel bag" - desc = "A large duffel bag for holding extra supplies - this one has a material inlay with space for various sharp-looking tools." - -/obj/item/storage/backpack/duffelbag/sec/surgery/PopulateContents() - new /obj/item/scalpel(src) - new /obj/item/hemostat(src) - new /obj/item/retractor(src) - new /obj/item/circular_saw(src) - new /obj/item/bonesetter(src) - new /obj/item/surgicaldrill(src) - new /obj/item/cautery(src) - new /obj/item/surgical_drapes(src) - new /obj/item/clothing/mask/surgical(src) - new /obj/item/blood_filter(src) - -/obj/item/storage/backpack/duffelbag/engineering - name = "industrial duffel bag" - desc = "A large duffel bag for holding extra tools and supplies." - icon_state = "duffel-engineering" - inhand_icon_state = "duffel-eng" - resistance_flags = FIRE_PROOF - -/obj/item/storage/backpack/duffelbag/drone - name = "drone duffel bag" - desc = "A large duffel bag for holding tools and hats." - icon_state = "duffel-drone" - inhand_icon_state = "duffel-drone" - resistance_flags = FIRE_PROOF - -/obj/item/storage/backpack/duffelbag/drone/PopulateContents() - new /obj/item/screwdriver(src) - new /obj/item/wrench(src) - new /obj/item/weldingtool(src) - new /obj/item/crowbar(src) - new /obj/item/stack/cable_coil(src) - new /obj/item/wirecutters(src) - new /obj/item/multitool(src) - -/obj/item/storage/backpack/duffelbag/clown - name = "clown's duffel bag" - desc = "A large duffel bag for holding lots of funny gags!" - icon_state = "duffel-clown" - inhand_icon_state = "duffel-clown" - -/obj/item/storage/backpack/duffelbag/clown/cream_pie/PopulateContents() - for(var/i in 1 to 10) - new /obj/item/food/pie/cream(src) - -/obj/item/storage/backpack/fireproof - resistance_flags = FIRE_PROOF - -/obj/item/storage/backpack/duffelbag/syndie - name = "suspicious looking duffel bag" - desc = "A large duffel bag for holding extra tactical supplies. It contains an oiled plastitanium zipper for maximum speed tactical zipping, and is better balanced on your back than an average duffelbag. Can hold two bulky items!" - icon_state = "duffel-syndie" - inhand_icon_state = "duffel-syndieammo" - storage_type = /datum/storage/duffel/syndicate - resistance_flags = FIRE_PROOF - // Less slowdown while unzipped. Still bulky, but it won't halve your movement speed in an active combat situation. - zip_slowdown = 0.3 - // Faster unzipping. Utilizes the same noise as zipping up to fit the unzip duration. - unzip_duration = 0.5 SECONDS - unzip_sfx = 'sound/items/zip/zip_up.ogg' - -/obj/item/storage/backpack/duffelbag/syndie/hitman - desc = "A large duffel bag for holding extra things. There is a Nanotrasen logo on the back." - icon_state = "duffel-syndieammo" - inhand_icon_state = "duffel-syndieammo" - -/obj/item/storage/backpack/duffelbag/syndie/hitman/PopulateContents() - new /obj/item/clothing/under/costume/buttondown/slacks/service(src) - new /obj/item/clothing/neck/tie/red/hitman(src) - new /obj/item/clothing/accessory/waistcoat(src) - new /obj/item/clothing/suit/toggle/lawyer/black(src) - new /obj/item/clothing/shoes/laceup(src) - new /obj/item/clothing/gloves/color/black(src) - new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/clothing/head/fedora(src) - -/obj/item/storage/backpack/duffelbag/syndie/med - name = "medical duffel bag" - desc = "A large duffel bag for holding extra tactical medical supplies." - icon_state = "duffel-syndiemed" - inhand_icon_state = "duffel-syndiemed" - -/obj/item/storage/backpack/duffelbag/syndie/surgery - name = "surgery duffel bag" - desc = "A suspicious looking duffel bag for holding surgery tools." - icon_state = "duffel-syndiemed" - inhand_icon_state = "duffel-syndiemed" - -/obj/item/storage/backpack/duffelbag/syndie/surgery/PopulateContents() - new /obj/item/scalpel/advanced(src) - new /obj/item/retractor/advanced(src) - new /obj/item/cautery/advanced(src) - new /obj/item/surgical_drapes(src) - new /obj/item/reagent_containers/medigel/sterilizine(src) - new /obj/item/bonesetter(src) - new /obj/item/blood_filter(src) - new /obj/item/stack/medical/bone_gel(src) - new /obj/item/stack/sticky_tape/surgical(src) - new /obj/item/emergency_bed(src) - new /obj/item/clothing/suit/jacket/straight_jacket(src) - new /obj/item/clothing/mask/muzzle(src) - new /obj/item/mmi/syndie(src) - -/obj/item/storage/backpack/duffelbag/syndie/ammo - name = "ammunition duffel bag" - desc = "A large duffel bag for holding extra weapons ammunition and supplies." - icon_state = "duffel-syndieammo" - inhand_icon_state = "duffel-syndieammo" - -/obj/item/storage/backpack/duffelbag/syndie/ammo/mech - desc = "A large duffel bag, packed to the brim with various exosuit ammo." - -/obj/item/storage/backpack/duffelbag/syndie/ammo/mech/PopulateContents() - new /obj/item/mecha_ammo/scattershot(src) - new /obj/item/mecha_ammo/scattershot(src) - new /obj/item/mecha_ammo/scattershot(src) - new /obj/item/mecha_ammo/scattershot(src) - new /obj/item/storage/belt/utility/syndicate(src) - -/obj/item/storage/backpack/duffelbag/syndie/ammo/mauler - desc = "A large duffel bag, packed to the brim with various exosuit ammo." - -/obj/item/storage/backpack/duffelbag/syndie/ammo/mauler/PopulateContents() - new /obj/item/mecha_ammo/lmg(src) - new /obj/item/mecha_ammo/lmg(src) - new /obj/item/mecha_ammo/lmg(src) - new /obj/item/mecha_ammo/scattershot(src) - new /obj/item/mecha_ammo/scattershot(src) - new /obj/item/mecha_ammo/scattershot(src) - new /obj/item/mecha_ammo/missiles_srm(src) - new /obj/item/mecha_ammo/missiles_srm(src) - new /obj/item/mecha_ammo/missiles_srm(src) - -/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle - desc = "A large duffel bag containing a medical equipment, a Donksoft LMG, a big jumbo box of riot darts, and a magboot MODsuit module." - -/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle/PopulateContents() - new /obj/item/mod/module/magboot(src) - new /obj/item/storage/medkit/tactical/premium(src) - new /obj/item/gun/ballistic/automatic/l6_saw/toy(src) - new /obj/item/ammo_box/foambox/riot(src) - -/obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle - desc = "A large duffel bag containing deadly chemicals, a handheld chem sprayer, Bioterror foam grenade, a Donksoft assault rifle, box of riot grade darts, a dart pistol, and a box of syringes." - -/obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle/PopulateContents() - new /obj/item/reagent_containers/spray/chemsprayer/bioterror(src) - new /obj/item/storage/box/syndie_kit/chemical(src) - new /obj/item/gun/syringe/syndicate(src) - new /obj/item/gun/ballistic/automatic/c20r/toy(src) - new /obj/item/storage/box/syringes(src) - new /obj/item/ammo_box/foambox/riot(src) - new /obj/item/grenade/chem_grenade/bioterrorfoam(src) - if(prob(5)) - new /obj/item/food/pizza/pineapple(src) - -/obj/item/storage/backpack/duffelbag/syndie/c4/PopulateContents() - for(var/i in 1 to 10) - new /obj/item/grenade/c4(src) - -/obj/item/storage/backpack/duffelbag/syndie/x4/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/grenade/c4/x4(src) - -/obj/item/storage/backpack/duffelbag/syndie/firestarter - desc = "A large duffel bag containing a New Russian pyro backpack sprayer, Elite MODsuit, a Stechkin APS pistol, minibomb, ammo, and other equipment." - -/obj/item/storage/backpack/duffelbag/syndie/firestarter/PopulateContents() - new /obj/item/clothing/under/syndicate/soviet(src) - new /obj/item/mod/control/pre_equipped/elite/flamethrower(src) - new /obj/item/gun/ballistic/automatic/pistol/aps(src) - new /obj/item/ammo_box/magazine/m9mm_aps/fire(src) - new /obj/item/ammo_box/magazine/m9mm_aps/fire(src) - new /obj/item/reagent_containers/cup/glass/bottle/vodka/badminka(src) - new /obj/item/reagent_containers/hypospray/medipen/stimulants(src) - new /obj/item/grenade/syndieminibomb(src) - -// For ClownOps. -/obj/item/storage/backpack/duffelbag/clown/syndie - storage_type = /datum/storage/duffel/syndicate - -/obj/item/storage/backpack/duffelbag/clown/syndie/PopulateContents() - new /obj/item/modular_computer/pda/clown(src) - new /obj/item/clothing/under/rank/civilian/clown(src) - new /obj/item/clothing/shoes/clown_shoes(src) - new /obj/item/clothing/mask/gas/clown_hat(src) - new /obj/item/bikehorn(src) - new /obj/item/implanter/sad_trombone(src) + return NONE /obj/item/storage/backpack/henchmen name = "wings" @@ -797,16 +423,18 @@ inhand_icon_state = "duffel-explorer" /obj/item/storage/backpack/duffelbag/mining_conscript/PopulateContents() - new /obj/item/clothing/glasses/meson(src) - new /obj/item/t_scanner/adv_mining_scanner/lesser(src) - new /obj/item/storage/bag/ore(src) - new /obj/item/clothing/suit/hooded/explorer(src) - new /obj/item/encryptionkey/headset_mining(src) - new /obj/item/clothing/mask/gas/explorer(src) - new /obj/item/card/id/advanced/mining(src) - new /obj/item/gun/energy/recharge/kinetic_accelerator(src) - new /obj/item/knife/combat/survival(src) - new /obj/item/flashlight/seclite(src) + return list( + /obj/item/clothing/glasses/meson, + /obj/item/t_scanner/adv_mining_scanner/lesser, + /obj/item/storage/bag/ore, + /obj/item/clothing/suit/hooded/explorer, + /obj/item/encryptionkey/headset_mining, + /obj/item/clothing/mask/gas/explorer, + /obj/item/card/id/advanced/mining, + /obj/item/gun/energy/recharge/kinetic_accelerator, + /obj/item/knife/combat/survival, + /obj/item/flashlight/seclite, + ) /* * Messenger Bag Types diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 41300362e21..da967fd140e 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -21,12 +21,7 @@ /obj/item/storage/bag slot_flags = ITEM_SLOT_BELT w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/bag/Initialize(mapload) - . = ..() - atom_storage.allow_quick_gather = TRUE - atom_storage.allow_quick_empty = TRUE - atom_storage.numerical_stacking = TRUE + storage_type = /datum/storage/bag // ----------------------------- // Trash bag @@ -40,17 +35,14 @@ worn_icon_state = "trashbag" lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' - storage_type = /datum/storage/trash + storage_type = /datum/storage/bag/trash_bag + ///If true, can be inserted into the janitor cart var/insertable = TRUE /obj/item/storage/bag/trash/Initialize(mapload) . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.max_total_storage = 30 - atom_storage.max_slots = 30 - atom_storage.set_holdable(cant_hold_list = /obj/item/disk/nuclear) - atom_storage.supports_smart_equip = FALSE + RegisterSignal(atom_storage, COMSIG_STORAGE_DUMP_POST_TRANSFER, PROC_REF(post_insertion)) /// If you dump a trash bag into something, anything that doesn't get inserted will spill out onto your feet @@ -89,13 +81,18 @@ . = ..() ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) -/obj/item/storage/bag/trash/filled - /obj/item/storage/bag/trash/filled/PopulateContents() - . = ..() - for(var/i in 1 to rand(1, 7)) + var/count = rand(1, 7) + for(var/_ in 1 to count) new /obj/effect/spawner/random/trash/garbage(src) - update_icon_state() + + . = list() + for(var/obj/insert as anything in src) + if(isitem(insert)) + insert.moveToNullspace() + . += insert + else //can't allow stuff like ashes which is /obj/effect subtype as storages don't accept those + qdel(insert) /obj/item/storage/bag/trash/bluespace name = "trash bag of holding" @@ -103,11 +100,7 @@ icon_state = "bluetrashbag" inhand_icon_state = "bluetrashbag" item_flags = NO_MAT_REDEMPTION - -/obj/item/storage/bag/trash/bluespace/Initialize(mapload) - . = ..() - atom_storage.max_total_storage = 60 - atom_storage.max_slots = 60 + storage_type = /datum/storage/bag/trash_bag/bluespace /obj/item/storage/bag/trash/bluespace/cyborg insertable = FALSE @@ -124,22 +117,15 @@ worn_icon_state = "satchel" slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKETS w_class = WEIGHT_CLASS_NORMAL + storage_type = /datum/storage/bag/ore_bag + ///If this is TRUE, the holder won't receive any messages when they fail to pick up ore through crossing it var/spam_protection = FALSE + /// The mob we are listening for movement var/mob/listeningTo ///Cooldown on balloon alerts when picking ore COOLDOWN_DECLARE(ore_bag_balloon_cooldown) -/obj/item/storage/bag/ore/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_HUGE - atom_storage.max_total_storage = 50 - atom_storage.numerical_stacking = TRUE - atom_storage.allow_quick_empty = TRUE - atom_storage.allow_quick_gather = TRUE - atom_storage.set_holdable(/obj/item/stack/ore) - atom_storage.silent_for_user = TRUE - /obj/item/storage/bag/ore/equipped(mob/user) . = ..() if(listeningTo == user) @@ -218,36 +204,18 @@ name = "mining satchel of holding" desc = "A revolution in convenience, this satchel allows for huge amounts of ore storage. It's been outfitted with anti-malfunction safety measures." icon_state = "satchel_bspace" - -/obj/item/storage/bag/ore/holding/Initialize(mapload) - . = ..() - atom_storage.max_slots = INFINITY - atom_storage.max_specific_storage = INFINITY - atom_storage.max_total_storage = INFINITY + storage_type = /datum/storage/bag/ore_bag/bluespace // ----------------------------- // Plant bag // ----------------------------- - /obj/item/storage/bag/plants name = "plant bag" icon = 'icons/obj/service/hydroponics/equipment.dmi' icon_state = "plantbag" worn_icon_state = "plantbag" resistance_flags = FLAMMABLE - -/obj/item/storage/bag/plants/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 100 - atom_storage.max_slots = 100 - atom_storage.set_holdable(list( - /obj/item/food/grown, - /obj/item/graft, - /obj/item/grown, - /obj/item/food/honeycomb, - /obj/item/seeds, - )) + storage_type = /datum/storage/bag/plants /obj/item/storage/bag/plants/portaseeder name = "portable seed extractor" @@ -292,24 +260,7 @@ icon = 'icons/obj/mining.dmi' icon_state = "sheetsnatcher" worn_icon_state = "satchel" - - var/capacity = 300 //the number of sheets it can carry. - -/obj/item/storage/bag/sheetsnatcher/Initialize(mapload) - . = ..() - atom_storage.allow_quick_empty = TRUE - atom_storage.allow_quick_gather = TRUE - atom_storage.numerical_stacking = TRUE - atom_storage.set_holdable( - can_hold_list = list( - /obj/item/stack/sheet - ), - cant_hold_list = list( - /obj/item/stack/sheet/mineral/sandstone, - /obj/item/stack/sheet/mineral/wood, - ), - ) - atom_storage.max_total_storage = capacity / 2 + storage_type = /datum/storage/bag/sheet_snatcher // ----------------------------- // Sheet Snatcher (Cyborg) @@ -318,7 +269,7 @@ /obj/item/storage/bag/sheetsnatcher/borg name = "sheet snatcher 9000" desc = "" - capacity = 500//Borgs get more because >specialization + storage_type = /datum/storage/bag/sheet_snatcher_cyborg // ----------------------------- @@ -329,55 +280,37 @@ name = "sheet snatcher EXTREME EDITION" desc = "A Nanotrasen storage system designed which has been given post-market alterations to hold any type of sheet. Comes pre-populated with " color = "#ff3737" // I'm too lazy to make a unique sprite - capacity = 5000 // Hopefully enough to fit anything you need w_class = WEIGHT_CLASS_TINY + storage_type = /datum/storage/bag/sheet_snatcher/debug // Copy-pasted from the former /obj/item/storage/box/material, w/ small additions like rods, cardboard, plastic. // "Only 20 uranium 'cause of radiation" -/obj/item/storage/bag/sheetsnatcher/debug/PopulateContents() - // amount should be null if it should spawn with the type's default amount - var/static/items_inside = list( - /obj/item/stack/sheet/iron/fifty = null, - /obj/item/stack/sheet/glass/fifty = null, - /obj/item/stack/sheet/rglass/fifty = null, - /obj/item/stack/sheet/plasmaglass/fifty = null, - /obj/item/stack/sheet/titaniumglass/fifty = null, - /obj/item/stack/sheet/plastitaniumglass/fifty = null, - /obj/item/stack/sheet/plasteel/fifty = null, - /obj/item/stack/sheet/mineral/titanium/fifty = null, - /obj/item/stack/sheet/mineral/gold = 50, - /obj/item/stack/sheet/mineral/silver = 50, - /obj/item/stack/sheet/mineral/plasma = 50, - /obj/item/stack/sheet/mineral/uranium = 20, - /obj/item/stack/sheet/mineral/diamond = 50, - /obj/item/stack/sheet/bluespace_crystal = 50, - /obj/item/stack/sheet/mineral/bananium = 50, - /obj/item/stack/sheet/mineral/wood/fifty = null, - /obj/item/stack/sheet/plastic/fifty = null, - /obj/item/stack/sheet/runed_metal/fifty = null, - /obj/item/stack/rods/fifty = null, - /obj/item/stack/sheet/mineral/plastitanium = 50, - /obj/item/stack/sheet/mineral/abductor = 50, - /obj/item/stack/sheet/cardboard/fifty = null, - ) - //This needs to be done here and not in Initialize() because the stacks get merged and fall out when their weight updates if this is set after PopulateContents() - atom_storage.allow_big_nesting = TRUE - atom_storage.max_slots = 99 - atom_storage.max_specific_storage = WEIGHT_CLASS_GIGANTIC - atom_storage.max_total_storage = capacity - for(var/obj/item/stack/stack_type as anything in items_inside) - var/amt = items_inside[stack_type] - new stack_type(src, amt, FALSE) +/obj/item/storage/bag/sheetsnatcher/debug/PopulateContents(datum/storage_config/config) + config.compute_max_values() -/obj/item/storage/bag/sheetsnatcher/debug/Initialize(mapload) - . = ..() - // Overrides so it can hold all possible sheets - atom_storage.set_holdable( - can_hold_list = list( - /obj/item/stack/sheet, - /obj/item/stack/sheet/mineral/sandstone, - /obj/item/stack/sheet/mineral/wood, - ) + return list( + /obj/item/stack/sheet/iron/fifty, + /obj/item/stack/sheet/glass/fifty, + /obj/item/stack/sheet/rglass/fifty, + /obj/item/stack/sheet/plasmaglass/fifty, + /obj/item/stack/sheet/titaniumglass/fifty, + /obj/item/stack/sheet/plastitaniumglass/fifty, + /obj/item/stack/sheet/plasteel/fifty, + /obj/item/stack/sheet/mineral/titanium/fifty, + new /obj/item/stack/sheet/mineral/gold(null, 50), + new /obj/item/stack/sheet/mineral/silver(null, 50), + new /obj/item/stack/sheet/mineral/plasma(null, 50), + new /obj/item/stack/sheet/mineral/uranium(null, 20), + new /obj/item/stack/sheet/mineral/diamond(null, 50), + new /obj/item/stack/sheet/bluespace_crystal(null, 50), + new /obj/item/stack/sheet/mineral/bananium(null, 50), + /obj/item/stack/sheet/mineral/wood/fifty, + /obj/item/stack/sheet/plastic/fifty, + /obj/item/stack/sheet/runed_metal/fifty, + /obj/item/stack/rods/fifty, + new /obj/item/stack/sheet/mineral/plastitanium(null, 50), + new /obj/item/stack/sheet/mineral/abductor(null, 50), + /obj/item/stack/sheet/cardboard/fifty, ) // ----------------------------- @@ -391,21 +324,9 @@ icon_state = "bookbag" worn_icon_state = "bookbag" resistance_flags = FLAMMABLE + storage_type = /datum/storage/bag/books -/obj/item/storage/bag/books/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 21 - atom_storage.max_slots = 7 - atom_storage.set_holdable(list( - /obj/item/book, - /obj/item/spellbook, - /obj/item/poster, - )) - -/* - * Trays - Agouri - */ +/// Trays - Agouri /obj/item/storage/bag/tray name = "serving tray" icon = 'icons/obj/food/containers.dmi' @@ -420,34 +341,7 @@ slot_flags = ITEM_SLOT_BELT custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT*1.5) custom_price = PAYCHECK_CREW * 0.6 - -/obj/item/storage/bag/tray/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY //Plates are required bulky to keep them out of backpacks - atom_storage.set_holdable( - can_hold_list = list( - /obj/item/cigarette, - /obj/item/food, - /obj/item/kitchen, - /obj/item/lighter, - /obj/item/organ, - /obj/item/plate, - /obj/item/reagent_containers/condiment, - /obj/item/reagent_containers/cup, - /obj/item/rollingpaper, - /obj/item/storage/box/gum, - /obj/item/storage/box/matches, - /obj/item/storage/fancy, - /obj/item/trash, - ), - cant_hold_list = list( - /obj/item/plate/oven_tray, - /obj/item/reagent_containers/cup/soup_pot, - ), - ) //Should cover: Bottles, Beakers, Bowls, Booze, Glasses, Food, Food Containers, Food Trash, Organs, Tobacco Products, Lighters, and Kitchen Tools. - atom_storage.insert_preposition = "on" - atom_storage.max_slots = 8 - atom_storage.max_total_storage = 16 + storage_type = /datum/storage/bag/tray /obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user) . = ..() @@ -503,10 +397,7 @@ icon_state = "foodtray" desc = "A cheap metal tray to pile today's meal onto." -/* - * Chemistry bag - */ - +/// Chemistry bag /obj/item/storage/bag/chemistry name = "chemistry bag" icon = 'icons/obj/medical/chemical.dmi' @@ -514,23 +405,7 @@ worn_icon_state = "chembag" desc = "A bag for storing pills, patches, and bottles." resistance_flags = FLAMMABLE - -/obj/item/storage/bag/chemistry/Initialize(mapload) - . = ..() - atom_storage.max_total_storage = 200 - atom_storage.max_slots = 50 - atom_storage.set_holdable(list( - /obj/item/reagent_containers/chem_pack, - /obj/item/reagent_containers/dropper, - /obj/item/reagent_containers/cup/glass/waterbottle, - /obj/item/reagent_containers/cup/beaker, - /obj/item/reagent_containers/cup/bottle, - /obj/item/reagent_containers/cup/tube, - /obj/item/reagent_containers/medigel, - /obj/item/reagent_containers/applicator, - /obj/item/reagent_containers/syringe, - )) - + storage_type = /datum/storage/bag/chemistry /obj/item/storage/bag/bio name = "bio bag" @@ -539,29 +414,9 @@ worn_icon_state = "biobag" desc = "A bag for the safe transportation and disposal of biowaste and other virulent materials." resistance_flags = FLAMMABLE + storage_type = /datum/storage/bag/bio -/obj/item/storage/bag/bio/Initialize(mapload) - . = ..() - atom_storage.max_total_storage = 200 - atom_storage.max_slots = 25 - atom_storage.set_holdable(list( - /obj/item/bodypart, - /obj/item/food/monkeycube, - /obj/item/healthanalyzer, - /obj/item/organ, - /obj/item/reagent_containers/blood, - /obj/item/reagent_containers/dropper, - /obj/item/reagent_containers/cup/beaker, - /obj/item/reagent_containers/cup/bottle, - /obj/item/reagent_containers/cup/tube, - /obj/item/reagent_containers/hypospray/medipen, - /obj/item/reagent_containers/syringe, - )) - -/* - * Science bag (mostly for xenobiologists) - */ - +/// Science bag (mostly for xenobiologists) /obj/item/storage/bag/xeno name = "science bag" icon = 'icons/obj/medical/chemical.dmi' @@ -569,30 +424,9 @@ worn_icon_state = "xenobag" desc = "A bag for the storage and transport of anomalous materials." resistance_flags = FLAMMABLE + storage_type = /datum/storage/bag/science -/obj/item/storage/bag/xeno/Initialize(mapload) - . = ..() - atom_storage.max_total_storage = 200 - atom_storage.max_slots = 25 - atom_storage.set_holdable(list( - /obj/item/bodypart, - /obj/item/food/deadmouse, - /obj/item/food/monkeycube, - /obj/item/organ, - /obj/item/petri_dish, - /obj/item/reagent_containers/dropper, - /obj/item/reagent_containers/cup/beaker, - /obj/item/reagent_containers/cup/bottle, - /obj/item/reagent_containers/cup/tube, - /obj/item/reagent_containers/syringe, - /obj/item/slime_extract, - /obj/item/swab, - )) - -/* - * Construction bag (for engineering, holds stock parts and electronics) - */ - +///Construction bag (for engineering, holds stock parts and electronics) /obj/item/storage/bag/construction name = "construction bag" icon = 'icons/obj/tools.dmi' @@ -601,22 +435,8 @@ desc = "A bag for storing small construction components." slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKETS resistance_flags = FLAMMABLE + storage_type = /datum/storage/bag/construction -/obj/item/storage/bag/construction/Initialize(mapload) - . = ..() - atom_storage.max_total_storage = 100 - atom_storage.max_slots = 50 - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.set_holdable(list( - /obj/item/assembly, - /obj/item/circuitboard, - /obj/item/electronics, - /obj/item/reagent_containers/cup/beaker, - /obj/item/stack/cable_coil, - /obj/item/stack/ore/bluespace_crystal, - /obj/item/stock_parts, - /obj/item/wallframe/camera, - )) /obj/item/storage/bag/harpoon_quiver name = "harpoon quiver" @@ -625,17 +445,12 @@ icon_state = "quiver" inhand_icon_state = null worn_icon_state = "harpoon_quiver" - -/obj/item/storage/bag/harpoon_quiver/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_TINY - atom_storage.max_slots = 40 - atom_storage.max_total_storage = 100 - atom_storage.set_holdable(/obj/item/ammo_casing/harpoon) + storage_type = /datum/storage/bag/harpoon_quiver /obj/item/storage/bag/harpoon_quiver/PopulateContents() - for(var/i in 1 to 40) - new /obj/item/ammo_casing/harpoon(src) + . = list() + for(var/_ in 1 to 40) + . += /obj/item/ammo_casing/harpoon /obj/item/storage/bag/rebar_quiver name = "rebar quiver" @@ -646,20 +461,7 @@ desc = "A oxygen tank cut in half, used for holding sharpened rods for the rebar crossbow." slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_SUITSTORE|ITEM_SLOT_NECK resistance_flags = FLAMMABLE - -/obj/item/storage/bag/rebar_quiver/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_TINY - atom_storage.max_slots = 10 - atom_storage.max_total_storage = 15 - atom_storage.set_holdable(list( - /obj/item/ammo_casing/rebar, - /obj/item/ammo_casing/rebar/syndie, - /obj/item/ammo_casing/rebar/healium, - /obj/item/ammo_casing/rebar/hydrogen, - /obj/item/ammo_casing/rebar/zaukerite, - /obj/item/ammo_casing/rebar/paperball, - )) + storage_type = /datum/storage/bag/rebar_quiver /obj/item/storage/bag/rebar_quiver/syndicate icon_state = "syndie_quiver_0" @@ -672,16 +474,12 @@ resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF actions_types = list(/datum/action/item_action/reload_rebar) action_slots = ALL - -/obj/item/storage/bag/rebar_quiver/syndicate/Initialize(mapload) - . = ..() - atom_storage.max_slots = 20 - atom_storage.max_total_storage = 20 - update_appearance(UPDATE_OVERLAYS) + storage_type = /datum/storage/bag/rebar_quiver/syndicate /obj/item/storage/bag/rebar_quiver/syndicate/PopulateContents() - for(var/to_fill in 1 to 20) - new /obj/item/ammo_casing/rebar/syndie(src) + . = list() + for(var/_ in 1 to 20) + /obj/item/ammo_casing/rebar/syndie /obj/item/storage/bag/rebar_quiver/syndicate/update_icon_state() . = ..() @@ -717,4 +515,112 @@ var/obj/item/ammo_casing/rebar/ammo_to_load = contents[1] held_crossbow.attackby(ammo_to_load, user) + +/obj/item/storage/bag/fishing + name = "fishing bag" + desc = "A vibrant bag for storing caught fish." + icon = 'icons/obj/fishing.dmi' + icon_state = "fishing_bag" + worn_icon_state = "fishing_bag" + resistance_flags = FLAMMABLE + custom_price = PAYCHECK_CREW * 3 + storage_type = /datum/storage/bag/fishing + + ///How much holding this affects fishing difficulty + var/fishing_modifier = -2 + +/obj/item/storage/bag/fishing/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier, ITEM_SLOT_HANDS) + +/obj/item/storage/bag/fishing/carpskin + name = "carpskin fishing bag" + desc = "A dapper fishing bag made from carpskin. You can store quite a lot of fishing gear in the small pockets formed by larger scales." + icon_state = "fishing_bag_carpskin" + worn_icon_state = "fishing_bag_carpskin" + resistance_flags = ACID_PROOF + storage_type = /datum/storage/carpskin_bag + fishing_modifier = -4 + storage_type = /datum/storage/bag/fishing/carpskin + +/obj/item/storage/bag/quiver + name = "quiver" + desc = "Holds arrows for your bow. Good, because while pocketing arrows is possible, it surely can't be pleasant." + icon = 'icons/obj/weapons/bows/quivers.dmi' + icon_state = "quiver" + inhand_icon_state = null + worn_icon_state = "harpoon_quiver" + storage_type = /datum/storage/bag/quivers + + /// type of arrow the quivel should hold + var/arrow_path = /obj/item/ammo_casing/arrow + +/obj/item/storage/bag/quiver/lesser + storage_type = /datum/storage/bag/quivers/lesser + +/obj/item/storage/bag/quiver/full/PopulateContents() + . = list() + for(var/i in 1 to 10) + . += arrow_path + +/obj/item/storage/bag/quiver/holy + name = "divine quiver" + desc = "Holds arrows for your divine bow, where they wait to find their target." + icon_state = "holyquiver" + inhand_icon_state = "holyquiver" + worn_icon_state = "holyquiver" + arrow_path = /obj/item/ammo_casing/arrow/holy + +/obj/item/storage/bag/quiver/holy/PopulateContents() + . = list() + for(var/i in 1 to 10) + . += arrow_path + +/obj/item/storage/bag/quiver/endless + name = "endless quiver" + desc = "Holds arrows for your bow. A deep digital void is contained within." + storage_type = /datum/storage/bag/quivers/endless + +/obj/item/storage/bag/quiver/endless/PopulateContents() + return arrow_path + +/*****************************Money bag********************************/ + +/obj/item/storage/bag/money + name = "money bag" + desc = "A bag for storing your profits." + icon_state = "moneybag" + worn_icon_state = "moneybag" + force = 10 + throwforce = 0 + resistance_flags = FLAMMABLE + max_integrity = 100 + w_class = WEIGHT_CLASS_BULKY + storage_type = /datum/storage/bag/money + +/obj/item/storage/bag/money/Initialize(mapload) + . = ..() + if(prob(20)) + icon_state = "moneybagalt" + +/obj/item/storage/bag/money/vault/PopulateContents() + return flatten_quantified_list(list( + /obj/item/coin/silver = 2, + /obj/item/coin/silver = 2, + /obj/item/coin/gold = 2, + /obj/item/coin/adamantine = 1, + )) + +///Used in the dutchmen pirate shuttle. +/obj/item/storage/bag/money/dutchmen + storage_type = /datum/storage/bag/dutchmen + +/obj/item/storage/bag/money/dutchmen/PopulateContents() + return flatten_quantified_list(list( + /obj/item/coin/silver/doubloon = 9, + /obj/item/coin/gold/doubloon = 9, + /obj/item/coin/adamantine/doubloon = 1, + )) + #undef ORE_BAG_BALOON_COOLDOWN diff --git a/code/game/objects/items/storage/basket.dm b/code/game/objects/items/storage/basket.dm index 6ee98e0f91d..846f9824294 100644 --- a/code/game/objects/items/storage/basket.dm +++ b/code/game/objects/items/storage/basket.dm @@ -5,8 +5,9 @@ icon_state = "basket" w_class = WEIGHT_CLASS_BULKY resistance_flags = FLAMMABLE + storage_type = /datum/storage/basket -/obj/item/storage/basket/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 21 +//Easter Baskets +/obj/item/storage/basket/easter + name = "Easter Basket" + storage_type = /datum/storage/basket/easter diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 3b2546d8af1..01a22bedd07 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -13,7 +13,9 @@ max_integrity = 300 equip_sound = 'sound/items/equip/toolbelt_equip.ogg' w_class = WEIGHT_CLASS_BULKY - var/content_overlays = FALSE //If this is true, the belt will gain overlays based on what it's holding + + ///If this is true, the belt will gain overlays based on what it's holding + var/content_overlays = FALSE /obj/item/storage/belt/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] begins belting [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")) @@ -41,17 +43,7 @@ custom_premium_price = PAYCHECK_CREW * 2 drop_sound = 'sound/items/handling/toolbelt_drop.ogg' pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg' - -/obj/item/storage/belt/utility/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 21 - atom_storage.set_holdable(GLOB.tool_items + list( - /obj/item/clothing/gloves, - /obj/item/radio, - /obj/item/melee/sickly_blade/lock, - /obj/item/reagent_containers/cup/soda_cans, - )) + storage_type = /datum/storage/utility_belt /obj/item/storage/belt/utility/chief name = "chief engineer's toolbelt" @@ -64,14 +56,15 @@ preload = TRUE /obj/item/storage/belt/utility/chief/full/PopulateContents() - SSwardrobe.provide_type(/obj/item/screwdriver/power, src) - SSwardrobe.provide_type(/obj/item/crowbar/power, src) - SSwardrobe.provide_type(/obj/item/weldingtool/experimental, src) - SSwardrobe.provide_type(/obj/item/multitool, src) - SSwardrobe.provide_type(/obj/item/stack/cable_coil, src) - SSwardrobe.provide_type(/obj/item/extinguisher/mini, src) - SSwardrobe.provide_type(/obj/item/analyzer, src) - //much roomier now that we've managed to remove two tools + return list( + SSwardrobe.provide_type(/obj/item/screwdriver/power, null), + SSwardrobe.provide_type(/obj/item/crowbar/power, null), + SSwardrobe.provide_type(/obj/item/weldingtool/experimental, null), + SSwardrobe.provide_type(/obj/item/multitool, null), + SSwardrobe.provide_type(/obj/item/stack/cable_coil, null), + SSwardrobe.provide_type(/obj/item/extinguisher/mini, null), + SSwardrobe.provide_type(/obj/item/analyzer, null), + ) /obj/item/storage/belt/utility/chief/full/get_types_to_preload() var/list/to_preload = list() //Yes this is a pain. Yes this is the point @@ -85,13 +78,15 @@ return to_preload /obj/item/storage/belt/utility/full/PopulateContents() - SSwardrobe.provide_type(/obj/item/screwdriver, src) - SSwardrobe.provide_type(/obj/item/wrench, src) - SSwardrobe.provide_type(/obj/item/weldingtool, src) - SSwardrobe.provide_type(/obj/item/crowbar, src) - SSwardrobe.provide_type(/obj/item/wirecutters, src) - SSwardrobe.provide_type(/obj/item/multitool, src) - SSwardrobe.provide_type(/obj/item/stack/cable_coil, src) + return list( + SSwardrobe.provide_type(/obj/item/screwdriver, null), + SSwardrobe.provide_type(/obj/item/wrench, null), + SSwardrobe.provide_type(/obj/item/weldingtool, null), + SSwardrobe.provide_type(/obj/item/crowbar, null), + SSwardrobe.provide_type(/obj/item/wirecutters, null), + SSwardrobe.provide_type(/obj/item/multitool, null), + SSwardrobe.provide_type(/obj/item/stack/cable_coil, null), + ) /obj/item/storage/belt/utility/full/get_types_to_preload() var/list/to_preload = list() //Yes this is a pain. Yes this is the point @@ -108,31 +103,37 @@ preload = FALSE /obj/item/storage/belt/utility/full/powertools/PopulateContents() - new /obj/item/screwdriver/power(src) - new /obj/item/crowbar/power(src) - new /obj/item/weldingtool/experimental(src) - new /obj/item/multitool(src) - new /obj/item/holosign_creator/atmos(src) - new /obj/item/extinguisher/mini(src) - new /obj/item/stack/cable_coil(src) + return list( + /obj/item/screwdriver/power, + /obj/item/crowbar/power, + /obj/item/weldingtool/experimental, + /obj/item/multitool, + /obj/item/holosign_creator/atmos, + /obj/item/extinguisher/mini, + /obj/item/stack/cable_coil, + ) /obj/item/storage/belt/utility/full/powertools/rcd/PopulateContents() - new /obj/item/screwdriver/power(src) - new /obj/item/crowbar/power(src) - new /obj/item/weldingtool/experimental(src) - new /obj/item/multitool(src) - new /obj/item/construction/rcd/loaded/upgraded(src) - new /obj/item/extinguisher/mini(src) - new /obj/item/stack/cable_coil(src) + return list( + /obj/item/screwdriver/power, + /obj/item/crowbar/power, + /obj/item/weldingtool/experimental, + /obj/item/multitool, + /obj/item/construction/rcd/loaded/upgraded, + /obj/item/extinguisher/mini, + /obj/item/stack/cable_coil, + ) /obj/item/storage/belt/utility/full/engi/PopulateContents() - SSwardrobe.provide_type(/obj/item/screwdriver, src) - SSwardrobe.provide_type(/obj/item/wrench, src) - SSwardrobe.provide_type(/obj/item/weldingtool/largetank, src) - SSwardrobe.provide_type(/obj/item/crowbar, src) - SSwardrobe.provide_type(/obj/item/wirecutters, src) - SSwardrobe.provide_type(/obj/item/multitool, src) - SSwardrobe.provide_type(/obj/item/stack/cable_coil, src) + return list( + SSwardrobe.provide_type(/obj/item/screwdriver, null), + SSwardrobe.provide_type(/obj/item/wrench, null), + SSwardrobe.provide_type(/obj/item/weldingtool/largetank, null), + SSwardrobe.provide_type(/obj/item/crowbar, null), + SSwardrobe.provide_type(/obj/item/wirecutters, null), + SSwardrobe.provide_type(/obj/item/multitool, null), + SSwardrobe.provide_type(/obj/item/stack/cable_coil, null), + ) /obj/item/storage/belt/utility/full/engi/get_types_to_preload() var/list/to_preload = list() //Yes this is a pain. Yes this is the point @@ -146,13 +147,15 @@ return to_preload /obj/item/storage/belt/utility/atmostech/PopulateContents() - SSwardrobe.provide_type(/obj/item/screwdriver, src) - SSwardrobe.provide_type(/obj/item/wrench, src) - SSwardrobe.provide_type(/obj/item/weldingtool, src) - SSwardrobe.provide_type(/obj/item/crowbar, src) - SSwardrobe.provide_type(/obj/item/wirecutters, src) - SSwardrobe.provide_type(/obj/item/t_scanner, src) - SSwardrobe.provide_type(/obj/item/extinguisher/mini, src) + return list( + SSwardrobe.provide_type(/obj/item/screwdriver, null), + SSwardrobe.provide_type(/obj/item/wrench, null), + SSwardrobe.provide_type(/obj/item/weldingtool, null), + SSwardrobe.provide_type(/obj/item/crowbar, null), + SSwardrobe.provide_type(/obj/item/wirecutters, null), + SSwardrobe.provide_type(/obj/item/t_scanner, null), + SSwardrobe.provide_type(/obj/item/extinguisher/mini, null), + ) /obj/item/storage/belt/utility/atmostech/get_types_to_preload() var/list/to_preload = list() //Yes this is a pain. Yes this is the point @@ -166,13 +169,15 @@ return to_preload /obj/item/storage/belt/utility/full/inducer/PopulateContents() - SSwardrobe.provide_type(/obj/item/screwdriver, src) - SSwardrobe.provide_type(/obj/item/wrench, src) - SSwardrobe.provide_type(/obj/item/weldingtool, src) - SSwardrobe.provide_type(/obj/item/crowbar/red, src) - SSwardrobe.provide_type(/obj/item/wirecutters, src) - SSwardrobe.provide_type(/obj/item/multitool, src) - SSwardrobe.provide_type(/obj/item/inducer, src) + return list( + SSwardrobe.provide_type(/obj/item/screwdriver, null), + SSwardrobe.provide_type(/obj/item/wrench, null), + SSwardrobe.provide_type(/obj/item/weldingtool, null), + SSwardrobe.provide_type(/obj/item/crowbar/red, null), + SSwardrobe.provide_type(/obj/item/wirecutters, null), + SSwardrobe.provide_type(/obj/item/multitool, null), + SSwardrobe.provide_type(/obj/item/inducer, null), + ) /obj/item/storage/belt/utility/full/inducer/get_types_to_preload() var/list/to_preload = list() //Yes this is a pain. Yes this is the point @@ -189,13 +194,15 @@ preload = FALSE /obj/item/storage/belt/utility/syndicate/PopulateContents() - new /obj/item/screwdriver/nuke(src) - new /obj/item/wrench/combat(src) - new /obj/item/weldingtool/largetank(src) - new /obj/item/crowbar(src) - new /obj/item/wirecutters(src) - new /obj/item/multitool(src) - new /obj/item/inducer/syndicate(src) + return list( + /obj/item/screwdriver/nuke, + /obj/item/wrench/combat, + /obj/item/weldingtool/largetank, + /obj/item/crowbar, + /obj/item/wirecutters, + /obj/item/multitool, + /obj/item/inducer/syndicate, + ) /obj/item/storage/belt/medical name = "medical belt" @@ -205,67 +212,7 @@ worn_icon_state = "medical" drop_sound = 'sound/items/handling/toolbelt_drop.ogg' pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg' - -/obj/item/storage/belt/medical/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 21 - atom_storage.set_holdable(list( - /obj/item/bikehorn/rubberducky, - /obj/item/blood_filter, - /obj/item/bonesetter, - /obj/item/cautery, - /obj/item/circular_saw, - /obj/item/clothing/glasses, - /obj/item/clothing/gloves, - /obj/item/clothing/neck/stethoscope, - /obj/item/clothing/mask/breath, - /obj/item/clothing/mask/muzzle, - /obj/item/clothing/mask/surgical, - /obj/item/clothing/head/utility/surgerycap, - /obj/item/construction/plumbing, - /obj/item/dnainjector, - /obj/item/extinguisher/mini, - /obj/item/flashlight/pen, - /obj/item/geiger_counter, - /obj/item/gun/syringe/syndicate, - /obj/item/healthanalyzer, - /obj/item/hemostat, - /obj/item/holosign_creator/medical, - /obj/item/implant, - /obj/item/implantcase, - /obj/item/implanter, - /obj/item/lazarus_injector, - /obj/item/lighter, - /obj/item/pinpointer/crew, - /obj/item/plunger, - /obj/item/radio, - /obj/item/reagent_containers/blood, - /obj/item/reagent_containers/dropper, - /obj/item/reagent_containers/cup/beaker, - /obj/item/reagent_containers/cup/bottle, - /obj/item/reagent_containers/cup/tube, - /obj/item/reagent_containers/hypospray, - /obj/item/reagent_containers/medigel, - /obj/item/reagent_containers/applicator, - /obj/item/reagent_containers/spray, - /obj/item/reagent_containers/syringe, - /obj/item/retractor, - /obj/item/scalpel, - /obj/item/shears, - /obj/item/stack/medical, - /obj/item/stack/sticky_tape, //surgical tape - /obj/item/stamp, - /obj/item/sensor_device, - /obj/item/storage/fancy/cigarettes, - /obj/item/storage/pill_bottle, - /obj/item/surgical_drapes, //for true paramedics - /obj/item/surgicaldrill, - /obj/item/tank/internals/emergency_oxygen, - /obj/item/wrench/medical, - /obj/item/knife/ritual, - /obj/item/flesh_shears, - )) + storage_type = /datum/storage/medical_belt /obj/item/storage/belt/medical/paramedic name = "EMT belt" @@ -275,14 +222,15 @@ preload = TRUE /obj/item/storage/belt/medical/paramedic/PopulateContents() - SSwardrobe.provide_type(/obj/item/sensor_device, src) - SSwardrobe.provide_type(/obj/item/stack/medical/gauze/twelve, src) - SSwardrobe.provide_type(/obj/item/stack/medical/bone_gel, src) - SSwardrobe.provide_type(/obj/item/stack/sticky_tape/surgical, src) - SSwardrobe.provide_type(/obj/item/reagent_containers/syringe, src) - SSwardrobe.provide_type(/obj/item/reagent_containers/cup/bottle/ammoniated_mercury, src) - SSwardrobe.provide_type(/obj/item/reagent_containers/cup/bottle/formaldehyde, src) - update_appearance() + return list( + SSwardrobe.provide_type(/obj/item/sensor_device, null), + SSwardrobe.provide_type(/obj/item/stack/medical/gauze/twelve, null), + SSwardrobe.provide_type(/obj/item/stack/medical/bone_gel, null), + SSwardrobe.provide_type(/obj/item/stack/sticky_tape/surgical, null), + SSwardrobe.provide_type(/obj/item/reagent_containers/syringe, null), + SSwardrobe.provide_type(/obj/item/reagent_containers/cup/bottle/ammoniated_mercury, null), + SSwardrobe.provide_type(/obj/item/reagent_containers/cup/bottle/formaldehyde, null), + ) /obj/item/storage/belt/medical/paramedic/get_types_to_preload() var/list/to_preload = list() //Yes this is a pain. Yes this is the point @@ -302,14 +250,15 @@ preload = TRUE /obj/item/storage/belt/medical/ert/PopulateContents() - SSwardrobe.provide_type(/obj/item/sensor_device, src) - SSwardrobe.provide_type(/obj/item/pinpointer/crew, src) - SSwardrobe.provide_type(/obj/item/scalpel/advanced, src) - SSwardrobe.provide_type(/obj/item/retractor/advanced, src) - SSwardrobe.provide_type(/obj/item/stack/medical/bone_gel, src) - SSwardrobe.provide_type(/obj/item/cautery/advanced, src) - SSwardrobe.provide_type(/obj/item/surgical_drapes, src) - update_appearance() + return list( + SSwardrobe.provide_type(/obj/item/sensor_device, null), + SSwardrobe.provide_type(/obj/item/pinpointer/crew, null), + SSwardrobe.provide_type(/obj/item/scalpel/advanced, null), + SSwardrobe.provide_type(/obj/item/retractor/advanced, null), + SSwardrobe.provide_type(/obj/item/stack/medical/bone_gel, null), + SSwardrobe.provide_type(/obj/item/cautery/advanced, null), + SSwardrobe.provide_type(/obj/item/surgical_drapes, null), + ) /obj/item/storage/belt/medical/ert/get_types_to_preload() var/list/to_preload = list() @@ -329,39 +278,16 @@ inhand_icon_state = "security"//Could likely use a better one. worn_icon_state = "security" content_overlays = TRUE - -/obj/item/storage/belt/security/Initialize(mapload) - . = ..() - atom_storage.max_slots = 5 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.set_holdable(list( - /obj/item/ammo_box, - /obj/item/ammo_casing/shotgun, - /obj/item/assembly/flash/handheld, - /obj/item/clothing/glasses, - /obj/item/clothing/gloves, - /obj/item/flashlight/seclite, - /obj/item/food/donut, - /obj/item/grenade, - /obj/item/holosign_creator/security, - /obj/item/knife/combat, - /obj/item/melee/baton, - /obj/item/radio, - /obj/item/reagent_containers/spray/pepper, - /obj/item/restraints/handcuffs, - /obj/item/restraints/legcuffs/bola, - )) - atom_storage.open_sound = 'sound/items/handling/holster_open.ogg' - atom_storage.open_sound_vary = TRUE - atom_storage.rustle_sound = null + storage_type = /datum/storage/security_belt /obj/item/storage/belt/security/full/PopulateContents() - new /obj/item/reagent_containers/spray/pepper(src) - new /obj/item/restraints/handcuffs(src) - new /obj/item/grenade/flashbang(src) - new /obj/item/assembly/flash/handheld(src) - new /obj/item/melee/baton/security/loaded(src) - update_appearance() + return list( + /obj/item/reagent_containers/spray/pepper, + /obj/item/restraints/handcuffs, + /obj/item/grenade/flashbang, + /obj/item/assembly/flash/handheld, + /obj/item/melee/baton/security/loaded, + ) /obj/item/storage/belt/security/webbing name = "security webbing" @@ -371,10 +297,7 @@ worn_icon_state = "securitywebbing" content_overlays = FALSE custom_premium_price = PAYCHECK_COMMAND * 3 - -/obj/item/storage/belt/security/webbing/Initialize(mapload) - . = ..() - atom_storage.max_slots = 6 + storage_type = /datum/storage/security_belt/webbing /obj/item/storage/belt/mining name = "explorer's webbing" @@ -383,57 +306,10 @@ inhand_icon_state = "explorer1" worn_icon_state = "explorer1" w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/belt/mining/Initialize(mapload) - . = ..() - atom_storage.max_slots = 6 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 20 - atom_storage.set_holdable(list( - /obj/item/analyzer, - /obj/item/clothing/gloves, - /obj/item/crowbar, - /obj/item/extinguisher/mini, - /obj/item/flashlight, - /obj/item/gps, - /obj/item/mining_stabilizer, - /obj/item/key/lasso, - /obj/item/knife, - /obj/item/lighter, - /obj/item/mining_scanner, - /obj/item/multitool, - /obj/item/organ/monster_core, - /obj/item/pickaxe, - /obj/item/radio, - /obj/item/reagent_containers/cup/glass, - /obj/item/reagent_containers/cup/glass/bottle, - /obj/item/reagent_containers/hypospray, - /obj/item/reagent_containers/applicator/pill, - /obj/item/resonator, - /obj/item/screwdriver, - /obj/item/shovel, - /obj/item/stack/cable_coil, - /obj/item/stack/marker_beacon, - /obj/item/stack/medical, - /obj/item/stack/ore, - /obj/item/stack/sheet/animalhide, - /obj/item/stack/sheet/bone, - /obj/item/stack/sheet/sinew, - /obj/item/storage/bag/ore, - /obj/item/storage/fancy/cigarettes, - /obj/item/storage/pill_bottle, - /obj/item/survivalcapsule, - /obj/item/t_scanner/adv_mining_scanner, - /obj/item/weldingtool, - /obj/item/wirecutters, - /obj/item/wrench, - /obj/item/wormhole_jaunter, - /obj/item/skeleton_key, - )) - + storage_type = /datum/storage/mining_belt /obj/item/storage/belt/mining/vendor/PopulateContents() - new /obj/item/survivalcapsule(src) + return /obj/item/survivalcapsule /obj/item/storage/belt/mining/alt icon_state = "explorer2" @@ -441,13 +317,19 @@ worn_icon_state = "explorer2" /obj/item/storage/belt/mining/healing/PopulateContents() + var/list/obj/item/insert = list( + /obj/item/reagent_containers/hypospray/medipen/survival/luxury, + /obj/item/reagent_containers/hypospray/medipen/survival/luxury, + /obj/item/reagent_containers/hypospray/medipen/survival, + /obj/item/reagent_containers/hypospray/medipen/survival, + ) + for(var/i in 1 to 2) - new /obj/item/reagent_containers/hypospray/medipen/survival/luxury(src) - for(var/i in 1 to 2) - new /obj/item/reagent_containers/hypospray/medipen/survival(src) - for(var/i in 1 to 2) - var/obj/item/organ/monster_core/core = new /obj/item/organ/monster_core/regenerative_core/legion(src) + var/obj/item/organ/monster_core/core = new /obj/item/organ/monster_core/regenerative_core/legion(null) core.preserve() + insert += core + + return insert /obj/item/storage/belt/mining/primitive name = "hunter's belt" @@ -455,10 +337,7 @@ icon_state = "ebelt" inhand_icon_state = "ebelt" worn_icon_state = "ebelt" - -/obj/item/storage/belt/mining/primitive/Initialize(mapload) - . = ..() - atom_storage.max_slots = 5 + storage_type = /datum/storage/mining_belt/primitive /obj/item/storage/belt/soulstone name = "soul stone belt" @@ -468,19 +347,17 @@ worn_icon_state = "soulstonebelt" drop_sound = 'sound/items/handling/toolbelt_drop.ogg' pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg' - -/obj/item/storage/belt/soulstone/Initialize(mapload) - . = ..() - atom_storage.max_slots = 6 - atom_storage.set_holdable(/obj/item/soulstone) + storage_type = /datum/storage/soulstone_belt /obj/item/storage/belt/soulstone/full/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/soulstone/mystic(src) + . = list() + for(var/_ in 1 to 6) + . += /obj/item/soulstone/mystic /obj/item/storage/belt/soulstone/full/chappy/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/soulstone/anybody/chaplain(src) + . = list() + for(var/_ in 1 to 6) + . += /obj/item/soulstone/anybody/chaplain /obj/item/storage/belt/champion name = "championship belt" @@ -488,12 +365,12 @@ icon_state = "championbelt" inhand_icon_state = "championbelt" worn_icon_state = "championbelt" - custom_materials = list(/datum/material/gold=SMALL_MATERIAL_AMOUNT *4) + custom_materials = list(/datum/material/gold=SMALL_MATERIAL_AMOUNT * 4) + storage_type = /datum/storage/champion_belt /obj/item/storage/belt/champion/Initialize(mapload) . = ..() - atom_storage.max_slots = 1 - atom_storage.set_holdable(/obj/item/clothing/mask/luchador) + AddComponent(/datum/component/adjust_fishing_difficulty, -2) /obj/item/storage/belt/military @@ -503,57 +380,55 @@ inhand_icon_state = "militarywebbing" worn_icon_state = "militarywebbing" resistance_flags = FIRE_PROOF + storage_type = /datum/storage/military_belt -/obj/item/storage/belt/military/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL +/obj/item/storage/belt/military/assault/fisher/PopulateContents() + return list( + /obj/item/gun/ballistic/automatic/pistol/clandestine/fisher, // 11 TC: 7 (pistol) + 3 (suppressor) + lightbreaker (1 TC, black market meme/util item) + /obj/item/ammo_box/magazine/m10mm, // 1 TC + /obj/item/ammo_box/magazine/m10mm, + /obj/item/card/emag/doorjack, // 3 TC + /obj/item/knife/combat, //comparable to the e-dagger, 2 TC + ) /obj/item/storage/belt/military/snack name = "tactical snack rig" + storage_type = /datum/storage/military_belt/snacks /obj/item/storage/belt/military/snack/Initialize(mapload) . = ..() var/sponsor = pick("Donk Co.", "Waffle Corp.", "Roffle Co.", "Gorlex Marauders", "Tiger Cooperative") desc = "A set of snack-tical webbing worn by athletes of the [sponsor] VR sports division." - atom_storage.max_slots = 6 - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.set_holdable(list( - /obj/item/food, - /obj/item/reagent_containers/cup/glass, + +/obj/item/storage/belt/military/snack/full/PopulateContents() + var/obj/item/snack = pick(list( + /obj/item/food/candy, + /obj/item/food/cheesiehonkers, + /obj/item/food/cheesynachos, + /obj/item/food/chips, + /obj/item/food/cubannachos, + /obj/item/food/donkpocket, + /obj/item/food/nachos, + /obj/item/food/nugget, + /obj/item/food/rofflewaffles, + /obj/item/food/sosjerky, + /obj/item/food/spacetwinkie, + /obj/item/food/spaghetti/pastatomato, + /obj/item/food/syndicake, + /obj/item/reagent_containers/cup/glass/drinkingglass/filled/nuka_cola, + /obj/item/reagent_containers/cup/glass/dry_ramen, + /obj/item/reagent_containers/cup/soda_cans/cola, + /obj/item/reagent_containers/cup/soda_cans/dr_gibb, + /obj/item/reagent_containers/cup/soda_cans/lemon_lime, + /obj/item/reagent_containers/cup/soda_cans/pwr_game, + /obj/item/reagent_containers/cup/soda_cans/space_mountain_wind, + /obj/item/reagent_containers/cup/soda_cans/space_up, + /obj/item/reagent_containers/cup/soda_cans/starkist, )) -/obj/item/storage/belt/military/snack/full - -/obj/item/storage/belt/military/snack/full/Initialize(mapload) - . = ..() - var/amount = 5 - var/rig_snacks - while(contents.len <= amount) - rig_snacks = pick(list( - /obj/item/food/candy, - /obj/item/food/cheesiehonkers, - /obj/item/food/cheesynachos, - /obj/item/food/chips, - /obj/item/food/cubannachos, - /obj/item/food/donkpocket, - /obj/item/food/nachos, - /obj/item/food/nugget, - /obj/item/food/rofflewaffles, - /obj/item/food/sosjerky, - /obj/item/food/spacetwinkie, - /obj/item/food/spaghetti/pastatomato, - /obj/item/food/syndicake, - /obj/item/reagent_containers/cup/glass/drinkingglass/filled/nuka_cola, - /obj/item/reagent_containers/cup/glass/dry_ramen, - /obj/item/reagent_containers/cup/soda_cans/cola, - /obj/item/reagent_containers/cup/soda_cans/dr_gibb, - /obj/item/reagent_containers/cup/soda_cans/lemon_lime, - /obj/item/reagent_containers/cup/soda_cans/pwr_game, - /obj/item/reagent_containers/cup/soda_cans/space_mountain_wind, - /obj/item/reagent_containers/cup/soda_cans/space_up, - /obj/item/reagent_containers/cup/soda_cans/starkist, - )) - new rig_snacks(src) + . = list() + for(var/_ in 1 to 5) + . += snack /obj/item/storage/belt/military/abductor name = "agent belt" @@ -565,13 +440,15 @@ content_overlays = TRUE /obj/item/storage/belt/military/abductor/full/PopulateContents() - new /obj/item/screwdriver/abductor(src) - new /obj/item/wrench/abductor(src) - new /obj/item/weldingtool/abductor(src) - new /obj/item/crowbar/abductor(src) - new /obj/item/wirecutters/abductor(src) - new /obj/item/multitool/abductor(src) - new /obj/item/stack/cable_coil(src) + return list( + /obj/item/screwdriver/abductor, + /obj/item/wrench/abductor, + /obj/item/weldingtool/abductor, + /obj/item/crowbar/abductor, + /obj/item/wirecutters/abductor, + /obj/item/multitool/abductor, + /obj/item/stack/cable_coil, + ) /obj/item/storage/belt/military/army name = "army belt" @@ -586,16 +463,13 @@ icon_state = "assault" inhand_icon_state = "security" worn_icon_state = "assault" - -/obj/item/storage/belt/military/assault/Initialize(mapload) - . = ..() - atom_storage.max_slots = 6 + storage_type = /datum/storage/military_belt/assault /obj/item/storage/belt/military/assault/full/PopulateContents() - generate_items_inside(list( + return flatten_quantified_list(list( /obj/item/ammo_box/magazine/wt550m9 = 4, /obj/item/ammo_box/magazine/wt550m9/wtap = 2, - ), src) + )) /obj/item/storage/belt/grenade name = "grenadier belt" @@ -605,26 +479,10 @@ worn_icon_state = "grenadebeltnew" drop_sound = 'sound/items/handling/toolbelt_drop.ogg' pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg' - -/obj/item/storage/belt/grenade/Initialize(mapload) - . = ..() - atom_storage.max_slots = 30 - atom_storage.numerical_stacking = TRUE - atom_storage.max_total_storage = 60 - atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY - atom_storage.set_holdable(list( - /obj/item/food/grown/cherry_bomb, - /obj/item/food/grown/firelemon, - /obj/item/grenade, - /obj/item/grenade/c4, - /obj/item/lighter, - /obj/item/multitool, - /obj/item/reagent_containers/cup/glass/bottle/molotov, - /obj/item/screwdriver, - )) + storage_type = /datum/storage/grenade_belt /obj/item/storage/belt/grenade/full/PopulateContents() - generate_items_inside(list( + return flatten_quantified_list(list( /obj/item/grenade/chem_grenade/incendiary = 2, /obj/item/grenade/empgrenade = 2, /obj/item/grenade/frag = 10, @@ -634,7 +492,7 @@ /obj/item/grenade/syndieminibomb = 2, /obj/item/multitool = 1, /obj/item/screwdriver = 1, - ),src) + )) /obj/item/storage/belt/wands @@ -643,25 +501,26 @@ icon_state = "soulstonebelt" inhand_icon_state = "soulstonebelt" worn_icon_state = "soulstonebelt" - -/obj/item/storage/belt/wands/Initialize(mapload) - . = ..() - atom_storage.max_slots = 7 - atom_storage.set_holdable(/obj/item/gun/magic/wand) + storage_type = /datum/storage/wand_belt /obj/item/storage/belt/wands/full/PopulateContents() - new /obj/item/gun/magic/wand/death(src) - new /obj/item/gun/magic/wand/resurrection(src) - new /obj/item/gun/magic/wand/polymorph(src) - new /obj/item/gun/magic/wand/teleport(src) - new /obj/item/gun/magic/wand/door(src) - new /obj/item/gun/magic/wand/fireball(src) - new /obj/item/gun/magic/wand/shrink(src) + var/list/obj/item/insert = list( + new /obj/item/gun/magic/wand/death(null), + new /obj/item/gun/magic/wand/resurrection(null), + new /obj/item/gun/magic/wand/polymorph(null), + new /obj/item/gun/magic/wand/teleport(null), + new /obj/item/gun/magic/wand/door(null), + new /obj/item/gun/magic/wand/fireball(null), + new /obj/item/gun/magic/wand/shrink(null), + ) - for(var/obj/item/gun/magic/wand/W in contents) //All wands in this pack come in the best possible condition + //All wands in this pack come in the best possible condition + for(var/obj/item/gun/magic/wand/W in insert) W.max_charges = initial(W.max_charges) W.charges = W.max_charges + return insert + /obj/item/storage/belt/janitor name = "janibelt" desc = "A belt used to hold most janitorial supplies." @@ -670,36 +529,16 @@ worn_icon_state = "janibelt" drop_sound = 'sound/items/handling/toolbelt_drop.ogg' pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg' - -/obj/item/storage/belt/janitor/Initialize(mapload) - . = ..() - atom_storage.max_slots = 6 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL // Set to this so the light replacer can fit. - atom_storage.set_holdable(list( - /obj/item/access_key, - /obj/item/assembly/mousetrap, - /obj/item/clothing/gloves, - /obj/item/flashlight, - /obj/item/forcefield_projector, - /obj/item/grenade/chem_grenade, - /obj/item/holosign_creator, - /obj/item/key/janitor, - /obj/item/lightreplacer, - /obj/item/melee/flyswatter, - /obj/item/paint/paint_remover, - /obj/item/plunger, - /obj/item/pushbroom, - /obj/item/reagent_containers/spray, - /obj/item/soap, - /obj/item/wirebrush, - )) + storage_type = /datum/storage/janitor_belt /obj/item/storage/belt/janitor/full/PopulateContents() - new /obj/item/lightreplacer(src) - new /obj/item/reagent_containers/spray/cleaner(src) - new /obj/item/soap/nanotrasen(src) - new /obj/item/holosign_creator(src) - new /obj/item/melee/flyswatter(src) + return list( + /obj/item/lightreplacer, + /obj/item/reagent_containers/spray/cleaner, + /obj/item/soap/nanotrasen, + /obj/item/holosign_creator, + /obj/item/melee/flyswatter, + ) /obj/item/storage/belt/bandolier name = "bandolier" @@ -707,21 +546,7 @@ icon_state = "bandolier" inhand_icon_state = "bandolier" worn_icon_state = "bandolier" - -/obj/item/storage/belt/bandolier/Initialize(mapload) - . = ..() - atom_storage.max_slots = 24 - atom_storage.max_total_storage = 24 - atom_storage.numerical_stacking = TRUE - atom_storage.allow_quick_gather = TRUE - atom_storage.allow_quick_empty = TRUE - atom_storage.numerical_stacking = TRUE - atom_storage.set_holdable(list( - /obj/item/ammo_casing/strilka310, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/c357, - /obj/item/ammo_casing/junk, - )) + storage_type = /datum/storage/bandolier_belt /obj/item/storage/belt/fannypack name = "fannypack" @@ -731,12 +556,7 @@ worn_icon_state = "fannypack_leather" dying_key = DYE_REGISTRY_FANNYPACK custom_price = PAYCHECK_CREW * 2 - -/obj/item/storage/belt/fannypack/Initialize(mapload) - . = ..() - atom_storage.max_slots = 3 - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.silent = TRUE + storage_type = /datum/storage/fanny_pack /obj/item/storage/belt/fannypack/black name = "black fannypack" @@ -803,17 +623,12 @@ worn_icon_state = "sheath" w_class = WEIGHT_CLASS_BULKY interaction_flags_click = parent_type::interaction_flags_click | NEED_DEXTERITY | NEED_HANDS + storage_type = /datum/storage/sabre_belt /obj/item/storage/belt/sabre/Initialize(mapload) . = ..() AddElement(/datum/element/update_icon_updates_onmob) - atom_storage.max_slots = 1 - atom_storage.do_rustle = FALSE - atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY - atom_storage.set_holdable(/obj/item/melee/sabre) - atom_storage.click_alt_open = FALSE - /obj/item/storage/belt/sabre/examine(mob/user) . = ..() if(length(contents)) @@ -840,8 +655,7 @@ return ..() /obj/item/storage/belt/sabre/PopulateContents() - new /obj/item/melee/sabre(src) - update_appearance() + return /obj/item/melee/sabre /obj/item/storage/belt/grass_sabre name = "sabre sheath" @@ -851,17 +665,12 @@ worn_icon_state = "grass_sheath" w_class = WEIGHT_CLASS_BULKY interaction_flags_click = parent_type::interaction_flags_click | NEED_DEXTERITY | NEED_HANDS + storage_type = /datum/storage/green_sabre_belt /obj/item/storage/belt/grass_sabre/Initialize(mapload) . = ..() AddElement(/datum/element/update_icon_updates_onmob) - atom_storage.max_slots = 1 - atom_storage.do_rustle = FALSE - atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY - atom_storage.set_holdable(/obj/item/melee/parsnip_sabre) - atom_storage.click_alt_open = FALSE - /obj/item/storage/belt/grass_sabre/examine(mob/user) . = ..() if(length(contents)) @@ -894,24 +703,4 @@ inhand_icon_state = "utility" worn_icon_state = "plantbelt" content_overlays = TRUE - -/obj/item/storage/belt/plant/Initialize(mapload) - . = ..() - atom_storage.max_slots = 6 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.set_holdable(list( - /obj/item/cultivator, - /obj/item/geneshears, - /obj/item/graft, - /obj/item/gun/energy/floragun, - /obj/item/hatchet, - /obj/item/plant_analyzer, - /obj/item/reagent_containers/cup/beaker, - /obj/item/reagent_containers/cup/bottle, - /obj/item/reagent_containers/cup/tube, - /obj/item/reagent_containers/spray/pestspray, - /obj/item/reagent_containers/spray/plantbgone, - /obj/item/secateurs, - /obj/item/seeds, - /obj/item/shovel/spade, - )) + storage_type = /datum/storage/plant_belt diff --git a/code/game/objects/items/storage/boxes/_boxes.dm b/code/game/objects/items/storage/boxes/_boxes.dm index 58e68b4487a..1bc9caa67ae 100644 --- a/code/game/objects/items/storage/boxes/_boxes.dm +++ b/code/game/objects/items/storage/boxes/_boxes.dm @@ -10,18 +10,13 @@ resistance_flags = FLAMMABLE drop_sound = 'sound/items/handling/cardboard_box/cardboardbox_drop.ogg' pickup_sound = 'sound/items/handling/cardboard_box/cardboardbox_pickup.ogg' + storage_type = /datum/storage/box + /// What material do we get when we fold this box? var/foldable_result = /obj/item/stack/sheet/cardboard /// What drawing will we get on the face of the box? var/illustration = "writing" -/obj/item/storage/box/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - update_appearance() - atom_storage.open_sound = 'sound/items/handling/cardboard_box/cardboard_box_open.ogg' - atom_storage.rustle_sound = 'sound/items/handling/cardboard_box/cardboard_box_rustle.ogg' - /obj/item/storage/box/suicide_act(mob/living/carbon/user) var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD) if(myhead) diff --git a/code/game/objects/items/storage/boxes/cargo_boxes.dm b/code/game/objects/items/storage/boxes/cargo_boxes.dm index ea2fc77ffb1..9f73d8ebe99 100644 --- a/code/game/objects/items/storage/boxes/cargo_boxes.dm +++ b/code/game/objects/items/storage/boxes/cargo_boxes.dm @@ -6,10 +6,10 @@ illustration = "shipping" /obj/item/storage/box/shipping/PopulateContents() - var/static/items_inside = list( - /obj/item/dest_tagger=1, - /obj/item/universal_scanner=1, - /obj/item/stack/package_wrap/small=2, - /obj/item/stack/wrapping_paper/small=1, - ) - generate_items_inside(items_inside,src) + return list( + /obj/item/dest_tagger, + /obj/item/universal_scanner, + /obj/item/stack/package_wrap/small, + /obj/item/stack/package_wrap/small, + /obj/item/stack/wrapping_paper/small + ) diff --git a/code/game/objects/items/storage/boxes/clothes_boxes.dm b/code/game/objects/items/storage/boxes/clothes_boxes.dm index 86cd3931f1e..9c4432825ca 100644 --- a/code/game/objects/items/storage/boxes/clothes_boxes.dm +++ b/code/game/objects/items/storage/boxes/clothes_boxes.dm @@ -6,8 +6,9 @@ illustration = "latex" /obj/item/storage/box/gloves/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/clothing/gloves/latex(src) + . = list() + for(var/_ in 1 to 7) + . += /obj/item/clothing/gloves/latex /obj/item/storage/box/masks name = "box of sterile masks" @@ -15,8 +16,9 @@ illustration = "sterile" /obj/item/storage/box/masks/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/clothing/mask/surgical(src) + . = list() + for(var/_ in 1 to 7) + . += /obj/item/clothing/mask/surgical /obj/item/storage/box/rxglasses name = "box of prescription glasses" @@ -24,37 +26,46 @@ illustration = "glasses" /obj/item/storage/box/rxglasses/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/clothing/glasses/regular(src) + . = list() + for(var/_ in 1 to 7) + . += /obj/item/clothing/glasses/regular /obj/item/storage/box/tape_wizard name = "Tape Wizard - Episode 23" desc = "A box containing the costume used by legendary entertainment icon 'Super Tape Wizard'. It got a little stuck on its way out." -/obj/item/storage/box/tape_wizard/PopulateContents() - new /obj/item/clothing/head/wizard/tape/fake(src) - new /obj/item/clothing/suit/wizrobe/tape/fake(src) - new /obj/item/staff/tape(src) - new /obj/item/stack/sticky_tape(src) +/obj/item/storage/box/tape_wizard/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + + return list( + /obj/item/clothing/head/wizard/tape/fake, + /obj/item/clothing/suit/wizrobe/tape/fake, + /obj/item/staff/tape, + /obj/item/stack/sticky_tape, + ) /obj/item/storage/box/fakesyndiesuit name = "boxed replica space suit and helmet" desc = "A sleek, sturdy box used to hold toy spacesuits." icon_state = "syndiebox" illustration = "syndiesuit" + storage_type = /datum/storage/box/syndie_kit /obj/item/storage/box/fakesyndiesuit/PopulateContents() - new /obj/item/clothing/head/syndicatefake(src) - new /obj/item/clothing/suit/syndicatefake(src) + return list( + /obj/item/clothing/head/syndicatefake, + /obj/item/clothing/suit/syndicatefake + ) /obj/item/storage/box/syndie_kit/battle_royale name = "rumble royale broadcast kit" desc = "Contains everything you need to host the galaxy's greatest show; Rumble Royale." /obj/item/storage/box/syndie_kit/battle_royale/PopulateContents() - var/obj/item/royale_implanter/implanter = new(src) - var/obj/item/royale_remote/remote = new(src) + var/obj/item/royale_implanter/implanter = new(null) + var/obj/item/royale_remote/remote = new(null) remote.link_implanter(implanter) + return list(implanter, remote) /obj/item/storage/box/deputy name = "box of deputy armbands" @@ -63,161 +74,197 @@ illustration = "depband" /obj/item/storage/box/deputy/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/clothing/accessory/armband/deputy(src) + . = list() + for(var/_ in 1 to 7) + . += /obj/item/clothing/accessory/armband/deputy /obj/item/storage/box/hero name = "Courageous Tomb Raider - 1940's." desc = "This legendary figure of still dubious historical accuracy is thought to have been a world-famous archeologist who embarked on countless adventures in far away lands, along with his trademark whip and fedora hat." + storage_type = /datum/storage/box/hero /obj/item/storage/box/hero/PopulateContents() - new /obj/item/clothing/head/fedora/curator(src) - new /obj/item/clothing/shoes/workboots/mining(src) - new /obj/item/clothing/suit/jacket/curator(src) - new /obj/item/clothing/under/rank/civilian/curator/treasure_hunter(src) - new /obj/item/melee/curator_whip(src) + return list( + /obj/item/clothing/head/fedora/curator, + /obj/item/clothing/shoes/workboots/mining, + /obj/item/clothing/suit/jacket/curator, + /obj/item/clothing/under/rank/civilian/curator/treasure_hunter, + /obj/item/melee/curator_whip, + ) /obj/item/storage/box/hero/astronaut name = "First Man on the Moon - 1960's." desc = "One small step for a man, one giant leap for mankind. Relive the beginnings of space exploration with this fully functional set of vintage EVA equipment." -/obj/item/storage/box/hero/astronaut/PopulateContents() - new /obj/item/clothing/suit/space/nasavoid(src) - new /obj/item/clothing/head/helmet/space/nasavoid(src) - new /obj/item/tank/internals/oxygen(src) - new /obj/item/gps(src) +/obj/item/storage/box/hero/astronaut/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + + return list( + /obj/item/clothing/suit/space/nasavoid, + /obj/item/clothing/head/helmet/space/nasavoid, + /obj/item/tank/internals/oxygen, + /obj/item/gps, + ) /obj/item/storage/box/hero/scottish name = "Braveheart, the Scottish rebel - 1300's." desc = "Seemingly a legendary figure in the battle for Scottish independence, this historical figure is closely associated with blue facepaint, big swords, strange man skirts, and his ever enduring catchphrase: 'FREEDOM!!'" /obj/item/storage/box/hero/scottish/PopulateContents() - new /obj/item/claymore/weak/ceremonial(src) - new /obj/item/clothing/shoes/sandal(src) - new /obj/item/clothing/under/costume/kilt(src) - new /obj/item/toy/crayon/spraycan(src) + return list( + /obj/item/claymore/weak/ceremonial, + /obj/item/clothing/shoes/sandal, + /obj/item/clothing/under/costume/kilt, + /obj/item/toy/crayon/spraycan, + ) /obj/item/storage/box/hero/carphunter name = "Carp Hunter, Wildlife Expert - 2506." desc = "Despite his nickname, this wildlife expert was mainly known as a passionate environmentalist and conservationist, often coming in contact with dangerous wildlife to teach about the beauty of nature." /obj/item/storage/box/hero/carphunter/PopulateContents() - new /obj/item/clothing/mask/gas/carp(src) - new /obj/item/clothing/suit/hooded/carp_costume/spaceproof/old(src) - new /obj/item/knife/hunting(src) - new /obj/item/storage/box/papersack/meat(src) + return list( + /obj/item/clothing/mask/gas/carp, + /obj/item/clothing/suit/hooded/carp_costume/spaceproof/old, + /obj/item/knife/hunting, + /obj/item/storage/box/papersack/meat, + ) /obj/item/storage/box/hero/mothpioneer name = "Mothic Fleet Pioneer - 2429." desc = "Some claim that the fleet engineers are directly responsible for most modern advancements in spacefaring designs. Although the exact details of their past contributions are somewhat fuzzy, their ingenuity remains unmatched and unquestioned to this day." /obj/item/storage/box/hero/mothpioneer/PopulateContents() - new /obj/item/clothing/head/mothcap/original(src) - new /obj/item/clothing/suit/mothcoat/original(src) - new /obj/item/crowbar(src) - new /obj/item/flashlight/lantern(src) - new /obj/item/screwdriver(src) - new /obj/item/stack/sheet/glass/fifty(src) - new /obj/item/stack/sheet/iron/fifty(src) - new /obj/item/wrench(src) + return list( + /obj/item/clothing/head/mothcap/original, + /obj/item/clothing/suit/mothcoat/original, + /obj/item/crowbar, + /obj/item/flashlight/lantern, + /obj/item/screwdriver, + /obj/item/stack/sheet/glass/fifty, + /obj/item/stack/sheet/iron/fifty, + /obj/item/wrench, + ) /obj/item/storage/box/hero/etherealwarden name = "Ethereal Trailwarden - 2450's." desc = "Many fantastical stories are told of valiant trail wardens, even by offworlders who, thanks to their guidance, avoided an untimely demise while traveling the sometimes treacherous roads of Sprout. In truth their job entails far more walking and fixing roads than slaying dragons, but it is no less important and well respected: keeping the roads and trails safe and well maintained is for many settlements a matter of survival." /obj/item/storage/box/hero/etherealwarden/PopulateContents() - new /obj/item/clothing/suit/hooded/ethereal_raincoat/trailwarden(src) - new /obj/item/clothing/under/ethereal_tunic/trailwarden(src) - new /obj/item/storage/backpack/saddlepack(src) + return list( + /obj/item/clothing/suit/hooded/ethereal_raincoat/trailwarden, + /obj/item/clothing/under/ethereal_tunic/trailwarden, + /obj/item/storage/backpack/saddlepack, + ) /obj/item/storage/box/hero/journalist name = "Assassinated by CIA - 1984." // Literally desc = "Many courageous individuals risked their lives to report on events the government sought to keep hidden from the public, ensuring that the truth remained buried and unheard. These garments are replicas of the clothing worn by one such 'journalist,' a silent sentinel in the fight for truth." /obj/item/storage/box/hero/journalist/PopulateContents() - new /obj/item/clothing/under/costume/buttondown/slacks(src) - new /obj/item/clothing/suit/toggle/suspenders(src) - new /obj/item/clothing/neck/tie/red(src) - new /obj/item/clothing/head/fedora/beige/press(src) - new /obj/item/clothing/accessory/press_badge(src) - new /obj/item/clothing/suit/hazardvest/press(src) - new /obj/item/radio/entertainment/microphone/physical(src) - new /obj/item/radio/entertainment/speakers/physical(src) - new /obj/item/clipboard(src) - new /obj/item/taperecorder(src) - new /obj/item/camera(src) - new /obj/item/wallframe/telescreen/entertainment(src) + return list( + /obj/item/clothing/under/costume/buttondown/slacks, + /obj/item/clothing/suit/toggle/suspenders, + /obj/item/clothing/neck/tie/red, + /obj/item/clothing/head/fedora/beige/press, + /obj/item/clothing/accessory/press_badge, + /obj/item/clothing/suit/hazardvest/press, + /obj/item/radio/entertainment/microphone/physical, + /obj/item/radio/entertainment/speakers/physical, + /obj/item/clipboard, + /obj/item/taperecorder, + /obj/item/camera, + /obj/item/wallframe/telescreen/entertainment, + ) /obj/item/storage/box/holy name = "Templar Kit" + storage_type = /datum/storage/box/holy /// This item is used to generate a preview image for this set. /// It could be any item, doesn't even necessarily need to be something in the kit var/obj/item/typepath_for_preview = /obj/item/clothing/suit/chaplainsuit/armor/templar /obj/item/storage/box/holy/PopulateContents() - new /obj/item/clothing/head/helmet/chaplain(src) - new /obj/item/clothing/suit/chaplainsuit/armor/templar(src) + return list( + /obj/item/clothing/head/helmet/chaplain, + /obj/item/clothing/suit/chaplainsuit/armor/templar, + ) /obj/item/storage/box/holy/clock name = "Forgotten kit" typepath_for_preview = /obj/item/clothing/suit/chaplainsuit/armor/clock /obj/item/storage/box/holy/clock/PopulateContents() - new /obj/item/clothing/head/helmet/chaplain/clock(src) - new /obj/item/clothing/suit/chaplainsuit/armor/clock(src) + return list( + /obj/item/clothing/head/helmet/chaplain/clock, + /obj/item/clothing/suit/chaplainsuit/armor/clock, + ) /obj/item/storage/box/holy/student name = "Profane Scholar Kit" typepath_for_preview = /obj/item/clothing/suit/chaplainsuit/armor/studentuni /obj/item/storage/box/holy/student/PopulateContents() - new /obj/item/clothing/suit/chaplainsuit/armor/studentuni(src) - new /obj/item/clothing/head/helmet/chaplain/cage(src) + return list( + /obj/item/clothing/suit/chaplainsuit/armor/studentuni, + /obj/item/clothing/head/helmet/chaplain/cage, + ) /obj/item/storage/box/holy/sentinel name = "Stone Sentinel Kit" typepath_for_preview = /obj/item/clothing/suit/chaplainsuit/armor/ancient /obj/item/storage/box/holy/sentinel/PopulateContents() - new /obj/item/clothing/suit/chaplainsuit/armor/ancient(src) - new /obj/item/clothing/head/helmet/chaplain/ancient(src) + return list( + /obj/item/clothing/suit/chaplainsuit/armor/ancient, + /obj/item/clothing/head/helmet/chaplain/ancient, + ) /obj/item/storage/box/holy/witchhunter name = "Witchhunter Kit" typepath_for_preview = /obj/item/clothing/suit/chaplainsuit/armor/witchhunter /obj/item/storage/box/holy/witchhunter/PopulateContents() - new /obj/item/clothing/suit/chaplainsuit/armor/witchhunter(src) - new /obj/item/clothing/head/helmet/chaplain/witchunter_hat(src) + return list( + /obj/item/clothing/suit/chaplainsuit/armor/witchhunter, + /obj/item/clothing/head/helmet/chaplain/witchunter_hat, + ) /obj/item/storage/box/holy/adept name = "Divine Adept Kit" typepath_for_preview = /obj/item/clothing/suit/chaplainsuit/armor/adept /obj/item/storage/box/holy/adept/PopulateContents() - new /obj/item/clothing/suit/chaplainsuit/armor/adept(src) - new /obj/item/clothing/head/helmet/chaplain/adept(src) + return list( + /obj/item/clothing/suit/chaplainsuit/armor/adept, + /obj/item/clothing/head/helmet/chaplain/adept, + ) /obj/item/storage/box/holy/follower name = "Followers of the Chaplain Kit" typepath_for_preview = /obj/item/clothing/suit/hooded/chaplain_hoodie/leader + storage_type = /datum/storage/box/holy/follower /obj/item/storage/box/holy/follower/PopulateContents() - new /obj/item/clothing/suit/hooded/chaplain_hoodie(src) - new /obj/item/clothing/suit/hooded/chaplain_hoodie(src) - new /obj/item/clothing/suit/hooded/chaplain_hoodie(src) - new /obj/item/clothing/suit/hooded/chaplain_hoodie(src) - new /obj/item/clothing/suit/hooded/chaplain_hoodie/leader(src) + return list( + /obj/item/clothing/suit/hooded/chaplain_hoodie, + /obj/item/clothing/suit/hooded/chaplain_hoodie, + /obj/item/clothing/suit/hooded/chaplain_hoodie, + /obj/item/clothing/suit/hooded/chaplain_hoodie, + /obj/item/clothing/suit/hooded/chaplain_hoodie/leader, + ) /obj/item/storage/box/holy/divine_archer name = "Divine Archer Kit" typepath_for_preview = /obj/item/clothing/suit/hooded/chaplain_hoodie/divine_archer /obj/item/storage/box/holy/divine_archer/PopulateContents() - new /obj/item/clothing/under/rank/civilian/chaplain/divine_archer(src) - new /obj/item/clothing/suit/hooded/chaplain_hoodie/divine_archer(src) - new /obj/item/clothing/gloves/divine_archer(src) - new /obj/item/clothing/shoes/divine_archer(src) + return list( + /obj/item/clothing/under/rank/civilian/chaplain/divine_archer, + /obj/item/clothing/suit/hooded/chaplain_hoodie/divine_archer, + /obj/item/clothing/gloves/divine_archer, + /obj/item/clothing/shoes/divine_archer, + ) /obj/item/storage/box/floor_camo name = "floor tile camo box" @@ -226,18 +273,26 @@ espionage uniform used by the very best. Providing the best \ flexibility, with our latest Camo-tech threads. Perfect for \ risky-espionage hallway operations. Enjoy our product!" + storage_type = /datum/storage/box/floor_camo -/obj/item/storage/box/floor_camo/PopulateContents() - new /obj/item/clothing/under/syndicate/floortilecamo(src) - new /obj/item/clothing/mask/floortilebalaclava(src) - new /obj/item/clothing/gloves/combat/floortile(src) - new /obj/item/clothing/shoes/jackboots/floortile(src) - new /obj/item/storage/backpack/floortile(src) +/obj/item/storage/box/floor_camo/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + + return list( + /obj/item/clothing/under/syndicate/floortilecamo, + /obj/item/clothing/mask/floortilebalaclava, + /obj/item/clothing/gloves/combat/floortile, + /obj/item/clothing/shoes/jackboots/floortile, + /obj/item/storage/backpack/floortile, + ) /obj/item/storage/box/collar_bomb name = "collar bomb box" desc = "A small print on the back reads 'For research purposes only. Handle with care. In case of emergency, call the following number:'... the rest is scratched out with a marker..." -/obj/item/storage/box/collar_bomb/PopulateContents() - var/obj/item/collar_bomb_button/button = new(src) - new /obj/item/clothing/neck/collar_bomb(src, button) +/obj/item/storage/box/collar_bomb/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + + var/obj/item/collar_bomb_button/button = new(null) + + return list(button, new /obj/item/clothing/neck/collar_bomb(null, button)) diff --git a/code/game/objects/items/storage/boxes/engineering_boxes.dm b/code/game/objects/items/storage/boxes/engineering_boxes.dm index 70a64f69da5..a7b4969abcc 100644 --- a/code/game/objects/items/storage/boxes/engineering_boxes.dm +++ b/code/game/objects/items/storage/boxes/engineering_boxes.dm @@ -6,8 +6,9 @@ illustration = "grenade" /obj/item/storage/box/metalfoam/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/grenade/chem_grenade/metalfoam(src) + . = list() + for(var/_ in 1 to 7) + . += /obj/item/grenade/chem_grenade/metalfoam /obj/item/storage/box/smart_metal_foam name = "box of smart metal foam grenades" @@ -15,39 +16,35 @@ illustration = "grenade" /obj/item/storage/box/smart_metal_foam/PopulateContents() - for(var/i in 1 to 7) - new/obj/item/grenade/chem_grenade/smart_metal_foam(src) + . = list() + for(var/_ in 1 to 7) + . += /obj/item/grenade/chem_grenade/smart_metal_foam /obj/item/storage/box/debugtools name = "box of debug tools" icon_state = "syndiebox" + storage_type = /datum/storage/box/debug_tools -/obj/item/storage/box/debugtools/Initialize(mapload) - . = ..() - atom_storage.allow_big_nesting = TRUE - atom_storage.max_slots = 99 - atom_storage.max_specific_storage = WEIGHT_CLASS_GIGANTIC - atom_storage.max_total_storage = 99 +/obj/item/storage/box/debugtools/PopulateContents(datum/storage_config/config) + config.compute_max_values() -/obj/item/storage/box/debugtools/PopulateContents() - var/static/items_inside = list( - /obj/item/card/emag=1, - /obj/item/construction/rcd/combat/admin=1, - /obj/item/disk/tech_disk/debug=1, - /obj/item/flashlight/emp/debug=1, - /obj/item/geiger_counter=1, - /obj/item/healthanalyzer/advanced=1, - /obj/item/modular_computer/pda/heads/captain=1, - /obj/item/pipe_dispenser=1, - /obj/item/stack/spacecash/c1000=50, - /obj/item/storage/box/beakers/bluespace=1, - /obj/item/storage/box/beakers/variety=1, - /obj/item/storage/bag/sheetsnatcher/debug=1, - /obj/item/uplink/debug=1, - /obj/item/uplink/nuclear/debug=1, - /obj/item/clothing/ears/earmuffs/debug = 1, - ) - generate_items_inside(items_inside,src) + return list( + /obj/item/card/emag, + /obj/item/construction/rcd/combat/admin, + /obj/item/disk/tech_disk/debug, + /obj/item/flashlight/emp/debug, + /obj/item/geiger_counter, + /obj/item/healthanalyzer/advanced, + /obj/item/modular_computer/pda/heads/captain, + /obj/item/pipe_dispenser, + /obj/item/storage/box/beakers/bluespace, + /obj/item/storage/box/beakers/variety, + /obj/item/storage/bag/sheetsnatcher/debug, + /obj/item/uplink/debug, + /obj/item/uplink/nuclear/debug, + /obj/item/clothing/ears/earmuffs/debug, + new /obj/item/stack/spacecash/c1000(null, 50), + ) /obj/item/storage/box/plastic name = "plastic box" @@ -63,9 +60,9 @@ illustration = "emergencytank" /obj/item/storage/box/emergencytank/PopulateContents() - ..() - for(var/i in 1 to 7) - new /obj/item/tank/internals/emergency_oxygen(src) //in case anyone ever wants to do anything with spawning them, apart from crafting the box + . = list() + for(var/_ in 1 to 7) + . += /obj/item/tank/internals/emergency_oxygen /obj/item/storage/box/engitank name = "extended-capacity emergency oxygen tank box" @@ -73,9 +70,9 @@ illustration = "extendedtank" /obj/item/storage/box/engitank/PopulateContents() - ..() - for(var/i in 1 to 7) - new /obj/item/tank/internals/emergency_oxygen/engi(src) //in case anyone ever wants to do anything with spawning them, apart from crafting the box + . = list() + for(var/_ in 1 to 7) + . += /obj/item/tank/internals/emergency_oxygen/engi /obj/item/storage/box/stickers/chief_engineer name = "CE approved sticker pack" @@ -83,5 +80,8 @@ illustration = "label_ce" /obj/item/storage/box/stickers/chief_engineer/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/sticker/chief_engineer(src) + return list( + /obj/item/sticker/chief_engineer, + /obj/item/sticker/chief_engineer, + /obj/item/sticker/chief_engineer, + ) diff --git a/code/game/objects/items/storage/boxes/fishing_boxes.dm b/code/game/objects/items/storage/boxes/fishing_boxes.dm new file mode 100644 index 00000000000..1501683f3fb --- /dev/null +++ b/code/game/objects/items/storage/boxes/fishing_boxes.dm @@ -0,0 +1,44 @@ + +/obj/item/storage/box/fishing_hooks + name = "fishing hook set" + illustration = "fish" + custom_price = PAYCHECK_CREW * 2 + +/obj/item/storage/box/fishing_hooks/PopulateContents() + return list( + /obj/item/fishing_hook/magnet, + /obj/item/fishing_hook/shiny, + /obj/item/fishing_hook/weighted, + ) + +/obj/item/storage/box/fishing_hooks/master/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + + . = ..() + . += /obj/item/fishing_hook/stabilized + . += /obj/item/fishing_hook/jaws + +/obj/item/storage/box/fishing_lines + name = "fishing line set" + illustration = "fish" + custom_price = PAYCHECK_CREW * 2 + +/obj/item/storage/box/fishing_lines/PopulateContents() + return list( + /obj/item/fishing_line/bouncy, + /obj/item/fishing_line/reinforced, + /obj/item/fishing_line/cloaked, + ) + +/obj/item/storage/box/fishing_lines/master/PopulateContents() + . = ..() + . += /obj/item/fishing_line/auto_reel + +/obj/item/storage/box/fish_debug + name = "box full of fish" + illustration = "fish" + +/obj/item/storage/box/fish_debug/PopulateContents(datum/storage_config/config) + config.compute_max_values() + + return subtypesof(/obj/item/fish) diff --git a/code/game/objects/items/storage/boxes/flat_boxes.dm b/code/game/objects/items/storage/boxes/flat_boxes.dm index b9544c0e548..f1a4a73511f 100644 --- a/code/game/objects/items/storage/boxes/flat_boxes.dm +++ b/code/game/objects/items/storage/boxes/flat_boxes.dm @@ -3,11 +3,7 @@ desc = "A cardboard box folded in a manner that is optimal for concealment, rather than for stowing your belongings." icon_state = "flat" illustration = null - -/obj/item/storage/box/flat/Initialize(mapload) - . = ..() - AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE, INVISIBILITY_OBSERVER, use_anchor = TRUE, tilt_tile = TRUE) - atom_storage.max_slots = 3 + storage_type = /datum/storage/box/flat /obj/item/storage/box/proc/flatten_box() if(istype(loc, /obj/item/storage) || type != /obj/item/storage/box || contents.len) diff --git a/code/game/objects/items/storage/boxes/food_boxes.dm b/code/game/objects/items/storage/boxes/food_boxes.dm index fd4bef33758..ce2e30033c8 100644 --- a/code/game/objects/items/storage/boxes/food_boxes.dm +++ b/code/game/objects/items/storage/boxes/food_boxes.dm @@ -9,12 +9,7 @@ var/donktype = /obj/item/food/donkpocket /obj/item/storage/box/donkpockets/PopulateContents() - for(var/i in 1 to 6) - new donktype(src) - -/obj/item/storage/box/donkpockets/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/food/donkpocket) + return donktype /obj/item/storage/box/donkpockets/donkpocketspicy name = "box of spicy-flavoured donk-pockets" @@ -146,19 +141,24 @@ desc = "It's slightly moist and smells like a slaughterhouse." /obj/item/storage/box/papersack/meat/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/food/meat/slab(src) + . = list() + for(var/_ in 1 to 7) + . += /obj/item/food/meat/slab /obj/item/storage/box/papersack/wheat desc = "It's a bit dusty, and smells like a barnyard." /obj/item/storage/box/papersack/wheat/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/food/grown/wheat(src) + . = list() + for(var/_ in 1 to 7) + . += /obj/item/food/grown/wheat /obj/item/storage/box/ingredients //This box is for the randomly chosen version the chef used to spawn with, it shouldn't actually exist. name = "ingredients box" illustration = "fruit" + storage_type = /datum/storage/box/ingredients + + ///Used in describing the box var/theme_name /obj/item/storage/box/ingredients/Initialize(mapload) @@ -172,154 +172,175 @@ theme_name = "wildcard" /obj/item/storage/box/ingredients/wildcard/PopulateContents() + var/static/list/obj/item/foods = list( + /obj/item/food/chocolatebar, + /obj/item/food/grown/apple, + /obj/item/food/grown/banana, + /obj/item/food/grown/cabbage, + /obj/item/food/grown/carrot, + /obj/item/food/grown/cherries, + /obj/item/food/grown/chili, + /obj/item/food/grown/corn, + /obj/item/food/grown/cucumber, + /obj/item/food/grown/mushroom/chanterelle, + /obj/item/food/grown/mushroom/plumphelmet, + /obj/item/food/grown/potato, + /obj/item/food/grown/potato/sweet, + /obj/item/food/grown/soybeans, + /obj/item/food/grown/tomato, + ) + + var/list/obj/item/insert = list() for(var/i in 1 to 7) - var/random_food = pick( - /obj/item/food/chocolatebar, - /obj/item/food/grown/apple, - /obj/item/food/grown/banana, - /obj/item/food/grown/cabbage, - /obj/item/food/grown/carrot, - /obj/item/food/grown/cherries, - /obj/item/food/grown/chili, - /obj/item/food/grown/corn, - /obj/item/food/grown/cucumber, - /obj/item/food/grown/mushroom/chanterelle, - /obj/item/food/grown/mushroom/plumphelmet, - /obj/item/food/grown/potato, - /obj/item/food/grown/potato/sweet, - /obj/item/food/grown/soybeans, - /obj/item/food/grown/tomato, - ) - new random_food(src) + insert += pick(foods) + + return insert /obj/item/storage/box/ingredients/fiesta theme_name = "fiesta" /obj/item/storage/box/ingredients/fiesta/PopulateContents() - new /obj/item/food/tortilla(src) - for(var/i in 1 to 2) - new /obj/item/food/grown/chili(src) - new /obj/item/food/grown/corn(src) - new /obj/item/food/grown/soybeans(src) + return flatten_quantified_list(list( + /obj/item/food/tortilla = 1, + /obj/item/food/grown/chili = 2, + /obj/item/food/grown/corn = 2, + /obj/item/food/grown/soybeans = 2, + )) /obj/item/storage/box/ingredients/italian theme_name = "italian" /obj/item/storage/box/ingredients/italian/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/food/grown/tomato(src) - new /obj/item/food/meatball(src) - new /obj/item/reagent_containers/cup/glass/bottle/wine(src) + return flatten_quantified_list(list( + /obj/item/food/grown/tomato = 3, + /obj/item/food/meatball = 3, + /obj/item/reagent_containers/cup/glass/bottle/wine = 1, + )) /obj/item/storage/box/ingredients/vegetarian theme_name = "vegetarian" /obj/item/storage/box/ingredients/vegetarian/PopulateContents() - for(var/i in 1 to 2) - new /obj/item/food/grown/carrot(src) - new /obj/item/food/grown/apple(src) - new /obj/item/food/grown/corn(src) - new /obj/item/food/grown/eggplant(src) - new /obj/item/food/grown/potato(src) - new /obj/item/food/grown/tomato(src) + return list( + /obj/item/food/grown/carrot, + /obj/item/food/grown/carrot, + /obj/item/food/grown/apple, + /obj/item/food/grown/corn, + /obj/item/food/grown/eggplant, + /obj/item/food/grown/potato, + /obj/item/food/grown/tomato, + ) /obj/item/storage/box/ingredients/american theme_name = "american" /obj/item/storage/box/ingredients/american/PopulateContents() - for(var/i in 1 to 2) - new /obj/item/food/grown/corn(src) - new /obj/item/food/grown/potato(src) - new /obj/item/food/grown/tomato(src) - new /obj/item/food/meatball(src) + return flatten_quantified_list(list( + /obj/item/food/grown/corn = 2, + /obj/item/food/grown/potato = 2, + /obj/item/food/grown/tomato = 2, + /obj/item/food/meatball = 1, + )) /obj/item/storage/box/ingredients/fruity theme_name = "fruity" -/obj/item/storage/box/ingredients/fruity/PopulateContents() - for(var/i in 1 to 2) - new /obj/item/food/grown/apple(src) - new /obj/item/food/grown/citrus/orange(src) - new /obj/item/food/grown/citrus/lemon(src) - new /obj/item/food/grown/citrus/lime(src) - new /obj/item/food/grown/watermelon(src) +/obj/item/storage/box/ingredients/fruity/PopulateContents(datum/storage_config/config) + config.compute_max_total_weight = TRUE + + return flatten_quantified_list(list( + /obj/item/food/grown/apple = 2, + /obj/item/food/grown/citrus/orange = 2, + /obj/item/food/grown/citrus/lemon = 1, + /obj/item/food/grown/citrus/lime = 1, + /obj/item/food/grown/watermelon = 1, + )) /obj/item/storage/box/ingredients/sweets theme_name = "sweets" /obj/item/storage/box/ingredients/sweets/PopulateContents() - for(var/i in 1 to 2) - new /obj/item/food/grown/cherries(src) - new /obj/item/food/grown/banana(src) - new /obj/item/food/chocolatebar(src) - new /obj/item/food/grown/apple(src) - new /obj/item/food/grown/cocoapod(src) + return flatten_quantified_list(list( + /obj/item/food/grown/cherries = 2, + /obj/item/food/grown/banana = 2, + /obj/item/food/chocolatebar = 1, + /obj/item/food/grown/apple = 1, + /obj/item/food/grown/cocoapod = 1, + )) /obj/item/storage/box/ingredients/delights theme_name = "delights" /obj/item/storage/box/ingredients/delights/PopulateContents() - for(var/i in 1 to 2) - new /obj/item/food/grown/bluecherries(src) - new /obj/item/food/grown/potato/sweet(src) - new /obj/item/food/grown/berries(src) - new /obj/item/food/grown/cocoapod(src) - new /obj/item/food/grown/vanillapod(src) + return flatten_quantified_list(list( + /obj/item/food/grown/bluecherries = 2, + /obj/item/food/grown/potato/sweet = 2, + /obj/item/food/grown/berries = 1, + /obj/item/food/grown/cocoapod = 1, + /obj/item/food/grown/vanillapod = 1, + )) /obj/item/storage/box/ingredients/grains theme_name = "grains" /obj/item/storage/box/ingredients/grains/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/food/grown/oat(src) - new /obj/item/food/grown/cocoapod(src) - new /obj/item/food/grown/wheat(src) - new /obj/item/food/honeycomb(src) - new /obj/item/seeds/poppy(src) + return flatten_quantified_list(list( + /obj/item/food/grown/oat = 3, + /obj/item/food/grown/cocoapod = 1, + /obj/item/food/grown/wheat = 1, + /obj/item/food/honeycomb = 1, + /obj/item/seeds/poppy = 1, + )) /obj/item/storage/box/ingredients/carnivore theme_name = "carnivore" /obj/item/storage/box/ingredients/carnivore/PopulateContents() - new /obj/item/food/meat/slab/bear(src) - new /obj/item/food/meat/slab/corgi(src) - new /obj/item/food/meat/slab/penguin(src) - new /obj/item/food/meat/slab/spider(src) - new /obj/item/food/meat/slab/xeno(src) - new /obj/item/food/meatball(src) - new /obj/item/food/spidereggs(src) + return list( + /obj/item/food/meat/slab/bear, + /obj/item/food/meat/slab/corgi, + /obj/item/food/meat/slab/penguin, + /obj/item/food/meat/slab/spider, + /obj/item/food/meat/slab/xeno, + /obj/item/food/meatball, + /obj/item/food/spidereggs, + ) /obj/item/storage/box/ingredients/exotic theme_name = "exotic" /obj/item/storage/box/ingredients/exotic/PopulateContents() - for(var/i in 1 to 2) - new /obj/item/food/fishmeat/carp(src) - new /obj/item/food/grown/cabbage(src) - new /obj/item/food/grown/soybeans(src) - new /obj/item/food/grown/chili(src) + return flatten_quantified_list(list( + /obj/item/food/fishmeat/carp = 2, + /obj/item/food/grown/cabbage = 2, + /obj/item/food/grown/soybeans = 2, + /obj/item/food/grown/chili = 1, + )) /obj/item/storage/box/ingredients/seafood theme_name = "seafood" /obj/item/storage/box/ingredients/seafood/PopulateContents() - for(var/i in 1 to 2) - new /obj/item/food/fishmeat/armorfish(src) - new /obj/item/food/fishmeat/carp(src) - new /obj/item/food/fishmeat/moonfish(src) - new /obj/item/food/fishmeat/gunner_jellyfish/supply(src) + return flatten_quantified_list(list( + /obj/item/food/fishmeat/armorfish = 2, + /obj/item/food/fishmeat/carp = 2, + /obj/item/food/fishmeat/moonfish = 2, + /obj/item/food/fishmeat/gunner_jellyfish/supply = 1, + )) /obj/item/storage/box/ingredients/salads theme_name = "salads" /obj/item/storage/box/ingredients/salads/PopulateContents() - new /obj/item/food/grown/cabbage(src) - new /obj/item/food/grown/carrot(src) - new /obj/item/food/grown/olive(src) - new /obj/item/food/grown/onion/red(src) - new /obj/item/food/grown/onion/red(src) - new /obj/item/food/grown/tomato(src) - new /obj/item/reagent_containers/condiment/olive_oil(src) + return list( + /obj/item/food/grown/cabbage, + /obj/item/food/grown/carrot, + /obj/item/food/grown/olive, + /obj/item/food/grown/onion/red, + /obj/item/food/grown/onion/red, + /obj/item/food/grown/tomato, + /obj/item/reagent_containers/condiment/olive_oil, + ) /obj/item/storage/box/ingredients/random theme_name = "random" @@ -340,15 +361,12 @@ illustration = null foldable_result = null custom_price = PAYCHECK_CREW - -/obj/item/storage/box/gum/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/food/bubblegum) - atom_storage.max_slots = 4 + storage_type = /datum/storage/box/bubble_gum /obj/item/storage/box/gum/PopulateContents() - for(var/i in 1 to 4) - new/obj/item/food/bubblegum(src) + . = list() + for(var/_ in 1 to 4) + . += /obj/item/food/bubblegum /obj/item/storage/box/gum/nicotine name = "nicotine gum packet" @@ -357,8 +375,9 @@ custom_premium_price = PAYCHECK_CREW * 1.5 /obj/item/storage/box/gum/nicotine/PopulateContents() - for(var/i in 1 to 4) - new/obj/item/food/bubblegum/nicotine(src) + . = list() + for(var/_ in 1 to 4) + . += /obj/item/food/bubblegum/nicotine /obj/item/storage/box/gum/happiness name = "HP+ gum packet" @@ -373,8 +392,9 @@ desc += " You can faintly make out the word 'Hemopagopril' was once scribbled on it." /obj/item/storage/box/gum/happiness/PopulateContents() - for(var/i in 1 to 4) - new/obj/item/food/bubblegum/happiness(src) + return flatten_quantified_list(list( + /obj/item/food/bubblegum/happiness = 4, + )) /obj/item/storage/box/gum/bubblegum name = "bubblegum gum packet" @@ -382,8 +402,9 @@ icon_state = "bubblegum_bubblegum" /obj/item/storage/box/gum/bubblegum/PopulateContents() - for(var/i in 1 to 4) - new/obj/item/food/bubblegum/bubblegum(src) + return flatten_quantified_list(list( + /obj/item/food/bubblegum/bubblegum = 4, + )) /obj/item/storage/box/mothic_rations name = "Mothic Rations Pack" @@ -392,16 +413,20 @@ illustration = null /obj/item/storage/box/mothic_rations/PopulateContents() + var/static/list/obj/item/food = list( + /obj/item/food/sustenance_bar = 10, + /obj/item/food/sustenance_bar/cheese = 5, + /obj/item/food/sustenance_bar/mint = 5, + /obj/item/food/sustenance_bar/neapolitan = 5, + /obj/item/food/sustenance_bar/wonka = 1, + ) + + var/list/obj/item/insert = list() for(var/i in 1 to 3) - var/random_food = pick_weight(list( - /obj/item/food/sustenance_bar = 10, - /obj/item/food/sustenance_bar/cheese = 5, - /obj/item/food/sustenance_bar/mint = 5, - /obj/item/food/sustenance_bar/neapolitan = 5, - /obj/item/food/sustenance_bar/wonka = 1, - )) - new random_food(src) - new /obj/item/storage/box/gum/wake_up(src) + insert += pick_weight(food) + insert += /obj/item/storage/box/gum/wake_up + + return insert /obj/item/storage/box/tiziran_goods name = "Tiziran Farm-Fresh Pack" @@ -410,89 +435,122 @@ illustration = null /obj/item/storage/box/tiziran_goods/PopulateContents() - for(var/i in 1 to 12) - var/random_food = pick_weight(list( - /obj/item/food/bread/root = 2, - /obj/item/food/grown/ash_flora/seraka = 2, - /obj/item/food/grown/korta_nut = 10, - /obj/item/food/grown/korta_nut/sweet = 2, - /obj/item/food/liver_pate = 5, - /obj/item/food/lizard_dumplings = 5, - /obj/item/food/moonfish_caviar = 5, - /obj/item/food/root_flatbread = 5, - /obj/item/food/rootroll = 5, - /obj/item/food/spaghetti/nizaya = 5, - )) - new random_food(src) + var/static/list/obj/item/food = list( + /obj/item/food/bread/root = 2, + /obj/item/food/grown/ash_flora/seraka = 2, + /obj/item/food/grown/korta_nut = 10, + /obj/item/food/grown/korta_nut/sweet = 2, + /obj/item/food/liver_pate = 5, + /obj/item/food/lizard_dumplings = 5, + /obj/item/food/moonfish_caviar = 5, + /obj/item/food/root_flatbread = 5, + /obj/item/food/rootroll = 5, + /obj/item/food/spaghetti/nizaya = 5, + ) + + var/list/obj/item/insert = list() + for(var/i in 1 to 3) + insert += pick_weight(food) + + return insert /obj/item/storage/box/tiziran_cans name = "Tiziran Canned Goods Pack" desc = "A box containing an assortment of canned Tiziran goods- to be eaten as is, or used in cooking." icon_state = "lizard_package" illustration = null + storage_type = /datum/storage/box/tiziran_cans /obj/item/storage/box/tiziran_cans/PopulateContents() + var/static/list/obj/item/food = list( + /obj/item/food/bread/root = 2, + /obj/item/food/grown/ash_flora/seraka = 2, + /obj/item/food/grown/korta_nut = 10, + /obj/item/food/grown/korta_nut/sweet = 2, + /obj/item/food/liver_pate = 5, + /obj/item/food/lizard_dumplings = 5, + /obj/item/food/moonfish_caviar = 5, + /obj/item/food/root_flatbread = 5, + /obj/item/food/rootroll = 5, + /obj/item/food/spaghetti/nizaya = 5, + ) + + var/list/obj/item/insert = list() for(var/i in 1 to 8) - var/random_food = pick_weight(list( - /obj/item/food/canned/jellyfish = 5, - /obj/item/food/canned/desert_snails = 5, - /obj/item/food/canned/larvae = 5, - )) - new random_food(src) + insert += pick_weight(food) + + return insert /obj/item/storage/box/tiziran_meats name = "Tiziran Meatmarket Pack" desc = "A box containing an assortment of fresh-frozen Tiziran meats and fish- the keys to lizard cooking." icon_state = "lizard_package" illustration = null + storage_type = /datum/storage/box/tiziran_meats /obj/item/storage/box/tiziran_meats/PopulateContents() + var/static/list/obj/item/food = list( + /obj/item/food/fishmeat/armorfish = 5, + /obj/item/food/fishmeat/gunner_jellyfish = 5, + /obj/item/food/fishmeat/moonfish = 5, + /obj/item/food/meat/slab = 5, + ) + + var/list/obj/item/insert = list() for(var/i in 1 to 10) - var/random_food = pick_weight(list( - /obj/item/food/fishmeat/armorfish = 5, - /obj/item/food/fishmeat/gunner_jellyfish = 5, - /obj/item/food/fishmeat/moonfish = 5, - /obj/item/food/meat/slab = 5, - )) - new random_food(src) + insert += pick_weight(food) + + return insert /obj/item/storage/box/mothic_goods name = "Mothic Farm-Fresh Pack" desc = "A box containing an assortment of Mothic cooking supplies." icon_state = "moth_package" illustration = null + storage_type = /datum/storage/box/mothic_goods -/obj/item/storage/box/mothic_goods/PopulateContents() +/obj/item/storage/box/mothic_goods/PopulateContents(datum/storage_config/config) + config.compute_max_total_weight = TRUE + + var/static/list/obj/item/food = list( + /obj/item/food/cheese/cheese_curds = 5, + /obj/item/food/cheese/curd_cheese = 5, + /obj/item/food/cheese/firm_cheese = 5, + /obj/item/food/cheese/mozzarella = 5, + /obj/item/food/cheese/wheel = 5, + /obj/item/food/grown/toechtauese = 10, + /obj/item/reagent_containers/condiment/cornmeal = 5, + /obj/item/reagent_containers/condiment/olive_oil = 5, + /obj/item/reagent_containers/condiment/yoghurt = 5, + ) + + var/list/obj/item/insert = list() for(var/i in 1 to 12) - var/random_food = pick_weight(list( - /obj/item/food/cheese/cheese_curds = 5, - /obj/item/food/cheese/curd_cheese = 5, - /obj/item/food/cheese/firm_cheese = 5, - /obj/item/food/cheese/mozzarella = 5, - /obj/item/food/cheese/wheel = 5, - /obj/item/food/grown/toechtauese = 10, - /obj/item/reagent_containers/condiment/cornmeal = 5, - /obj/item/reagent_containers/condiment/olive_oil = 5, - /obj/item/reagent_containers/condiment/yoghurt = 5, - )) - new random_food(src) + insert += pick_weight(food) + + return insert /obj/item/storage/box/mothic_cans_sauces name = "Mothic Pantry Pack" desc = "A box containing an assortment of Mothic canned goods and premade sauces." icon_state = "moth_package" illustration = null + storage_type = /datum/storage/box/mothic_cans_sauces /obj/item/storage/box/mothic_cans_sauces/PopulateContents() + var/static/list/obj/item/food = list( + /obj/item/food/bechamel_sauce = 5, + /obj/item/food/canned/pine_nuts = 5, + /obj/item/food/canned/tomatoes = 5, + /obj/item/food/pesto = 5, + /obj/item/food/tomato_sauce = 5, + ) + + var/list/obj/item/insert = list() for(var/i in 1 to 8) - var/random_food = pick_weight(list( - /obj/item/food/bechamel_sauce = 5, - /obj/item/food/canned/pine_nuts = 5, - /obj/item/food/canned/tomatoes = 5, - /obj/item/food/pesto = 5, - /obj/item/food/tomato_sauce = 5, - )) - new random_food(src) + insert += pick_weight(food) + + return insert /obj/item/storage/box/condimentbottles name = "box of condiment bottles" @@ -500,8 +558,9 @@ illustration = "condiment" /obj/item/storage/box/condimentbottles/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/reagent_containers/condiment(src) + return flatten_quantified_list(list( + /obj/item/reagent_containers/condiment = 6, + )) /obj/item/storage/box/coffeepack @@ -510,18 +569,21 @@ desc = "A bag containing fresh, dry coffee arabica beans. Ethically sourced and packaged by Waffle Corp." illustration = null icon = 'icons/obj/food/containers.dmi' + storage_type = /datum/storage/box/coffee + + /// Bean type to initialize the box with var/beantype = /obj/item/food/grown/coffee -/obj/item/storage/box/coffeepack/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/food/grown/coffee) - /obj/item/storage/box/coffeepack/PopulateContents() - atom_storage.max_slots = 5 + + var/list/obj/item/food = list() for(var/i in 1 to 5) - var/obj/item/food/grown/coffee/bean = new beantype(src) + var/obj/item/food/grown/coffee/bean = new beantype(null) ADD_TRAIT(bean, TRAIT_DRIED, ELEMENT_TRAIT(type)) bean.add_atom_colour(COLOR_DRIED_TAN, FIXED_COLOUR_PRIORITY) //give them the tan just like from the drying rack + food += bean + + return food /obj/item/storage/box/coffeepack/robusta icon_state = "robusta_beans" diff --git a/code/game/objects/items/storage/boxes/implant_boxes.dm b/code/game/objects/items/storage/boxes/implant_boxes.dm index 1da12ba3285..13059e80b6d 100644 --- a/code/game/objects/items/storage/boxes/implant_boxes.dm +++ b/code/game/objects/items/storage/boxes/implant_boxes.dm @@ -5,13 +5,12 @@ illustration = "implant" /obj/item/storage/box/trackimp/PopulateContents() - var/static/items_inside = list( + return flatten_quantified_list(list( /obj/item/implantcase/tracking = 4, /obj/item/implanter = 1, /obj/item/implantpad = 1, /obj/item/locator = 1, - ) - generate_items_inside(items_inside,src) + )) /obj/item/storage/box/minertracker name = "boxed tracking implant kit" @@ -19,14 +18,13 @@ illustration = "implant" /obj/item/storage/box/minertracker/PopulateContents() - var/static/items_inside = list( + return flatten_quantified_list(list( /obj/item/implantcase/tracking = 2, /obj/item/implantcase/beacon = 2, /obj/item/implanter = 1, /obj/item/implantpad = 1, /obj/item/locator = 1, - ) - generate_items_inside(items_inside,src) + )) /obj/item/storage/box/chemimp name = "boxed chemical implant kit" @@ -34,12 +32,11 @@ illustration = "implant" /obj/item/storage/box/chemimp/PopulateContents() - var/static/items_inside = list( + return flatten_quantified_list(list( /obj/item/implantcase/chem = 5, /obj/item/implanter = 1, /obj/item/implantpad = 1, - ) - generate_items_inside(items_inside,src) + )) /obj/item/storage/box/exileimp name = "boxed exile implant kit" @@ -47,12 +44,11 @@ illustration = "implant" /obj/item/storage/box/exileimp/PopulateContents() - var/static/items_inside = list( + return flatten_quantified_list(list( /obj/item/implantcase/exile = 5, /obj/item/implanter = 1, /obj/item/implantpad = 1, - ) - generate_items_inside(items_inside,src) + )) /obj/item/storage/box/beaconimp name = "boxed beacon implant kit" @@ -61,12 +57,11 @@ illustration = "implant" /obj/item/storage/box/beaconimp/PopulateContents() - var/static/items_inside = list( + return flatten_quantified_list(list( /obj/item/implantcase/beacon = 3, /obj/item/implanter = 1, /obj/item/implantpad = 1, - ) - generate_items_inside(items_inside,src) + )) /obj/item/storage/box/teleport_blocker name = "boxed bluespace grounding implant kit" @@ -74,9 +69,8 @@ illustration = "implant" /obj/item/storage/box/teleport_blocker/PopulateContents() - var/static/items_inside = list( + return flatten_quantified_list(list( /obj/item/implantcase/teleport_blocker = 2, /obj/item/implanter = 1, /obj/item/implantpad = 1, - ) - generate_items_inside(items_inside,src) + )) diff --git a/code/game/objects/items/storage/boxes/job_boxes.dm b/code/game/objects/items/storage/boxes/job_boxes.dm index b1bc443d0f5..83c89f0d612 100644 --- a/code/game/objects/items/storage/boxes/job_boxes.dm +++ b/code/game/objects/items/storage/boxes/job_boxes.dm @@ -30,29 +30,31 @@ /obj/item/storage/box/survival/PopulateContents() if(crafted) - return + return NONE + + . = list() if(!isnull(mask_type)) - new mask_type(src) + . += mask_type if(!isnull(internal_type)) - new internal_type(src) + . += internal_type if(!isnull(medipen_type)) - new medipen_type(src) + . += medipen_type if(give_premium_goods && HAS_TRAIT(SSstation, STATION_TRAIT_PREMIUM_INTERNALS)) - new /obj/item/flashlight/flare(src) - new /obj/item/radio/off(src) + . += /obj/item/flashlight/flare + . += /obj/item/radio/off if(HAS_TRAIT(SSstation, STATION_TRAIT_RADIOACTIVE_NEBULA)) - new /obj/item/storage/pill_bottle/potassiodide(src) + . += /obj/item/storage/pill_bottle/potassiodide if(give_hook && length(SSmapping.levels_by_trait(ZTRAIT_STATION)) > 1) - new /obj/item/climbing_hook/emergency(src) + . += /obj/item/climbing_hook/emergency /obj/item/storage/box/survival/radio/PopulateContents() - ..() // we want the survival stuff too. - new /obj/item/radio/off(src) + . = ..() // we want the survival stuff too. + . += /obj/item/radio/off /obj/item/storage/box/survival/proc/wardrobe_removal() if(!isplasmaman(loc)) //We need to specially fill the box with plasmaman gear, since it's intended for one @@ -73,9 +75,9 @@ mask_type = /obj/item/clothing/mask/gas/explorer/folded /obj/item/storage/box/survival/mining/PopulateContents() - ..() - new /obj/item/crowbar/red(src) - new /obj/item/healthanalyzer/simple/miner(src) + . = ..() + . += /obj/item/crowbar/red + . += /obj/item/healthanalyzer/simple/miner // Engineer survival box /obj/item/storage/box/survival/engineer @@ -85,8 +87,8 @@ internal_type = /obj/item/tank/internals/emergency_oxygen/engi /obj/item/storage/box/survival/engineer/radio/PopulateContents() - ..() // we want the regular items too. - new /obj/item/radio/off(src) + . = ..() // we want the regular items too. + . += /obj/item/radio/off // Syndie survival box /obj/item/storage/box/survival/syndie @@ -96,14 +98,16 @@ illustration = "extendedtank" mask_type = /obj/item/clothing/mask/gas/syndicate internal_type = /obj/item/tank/internals/emergency_oxygen/engi - medipen_type = /obj/item/reagent_containers/hypospray/medipen/atropine + medipen_type = /obj/item/reagent_containers/hypospray/medipen/atropine -/obj/item/storage/box/survival/syndie/PopulateContents() - ..() - new /obj/item/crowbar/red(src) - new /obj/item/screwdriver/red(src) - new /obj/item/weldingtool/mini(src) - new /obj/item/paper/fluff/operative(src) +/obj/item/storage/box/survival/syndie/PopulateContents(datum/storage_config/config) + config.compute_max_item_count = TRUE + + . = ..() + . += /obj/item/crowbar/red + . += /obj/item/screwdriver/red + . += /obj/item/weldingtool/mini + . += /obj/item/paper/fluff/operative /obj/item/storage/box/survival/centcom name = "emergency response survival box" @@ -113,15 +117,15 @@ /obj/item/storage/box/survival/centcom/PopulateContents() . = ..() - new /obj/item/crowbar(src) + . += /obj/item/crowbar // Security survival box /obj/item/storage/box/survival/security mask_type = /obj/item/clothing/mask/gas/sechailer /obj/item/storage/box/survival/security/radio/PopulateContents() - ..() // we want the regular stuff too - new /obj/item/radio/off(src) + . = ..() // we want the regular stuff too + . += /obj/item/radio/off // Medical survival box /obj/item/storage/box/survival/medical @@ -205,9 +209,11 @@ // Special stuff for medical hugboxes. /obj/item/storage/box/hug/medical/PopulateContents() - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/ointment(src) - new /obj/item/reagent_containers/hypospray/medipen(src) + return list( + /obj/item/stack/medical/bruise_pack, + /obj/item/stack/medical/ointment, + /obj/item/reagent_containers/hypospray/medipen, + ) //Clown survival box /obj/item/storage/box/survival/hug @@ -222,11 +228,13 @@ /obj/item/storage/box/survival/hug/PopulateContents() if(!random_funny_internals) return ..() + internal_type = pick( - /obj/item/tank/internals/emergency_oxygen/engi/clown/n2o, - /obj/item/tank/internals/emergency_oxygen/engi/clown/bz, - /obj/item/tank/internals/emergency_oxygen/engi/clown/helium, - ) + /obj/item/tank/internals/emergency_oxygen/engi/clown/n2o, + /obj/item/tank/internals/emergency_oxygen/engi/clown/bz, + /obj/item/tank/internals/emergency_oxygen/engi/clown/helium, + ) + return ..() //Mime survival box @@ -252,57 +260,88 @@ for Medical Officers who just take the box for themselves." /obj/item/storage/box/hug/plushes/PopulateContents() - for(var/i in 1 to 7) - var/plush_path = /obj/effect/spawner/random/entertainment/plushie - new plush_path(src) + for(var/_ in 1 to 7) + new /obj/effect/spawner/random/entertainment/plushie(src) + + . = list() + for(var/obj/item/insert as anything in src) + insert.moveToNullspace() + . += insert /obj/item/storage/box/survival/mining/bonus mask_type = null internal_type = /obj/item/tank/internals/emergency_oxygen/double /obj/item/storage/box/survival/mining/bonus/PopulateContents() - ..() - new /obj/item/gps/mining(src) - new /obj/item/t_scanner/adv_mining_scanner(src) + . = ..() + . += /obj/item/gps/mining + . += /obj/item/t_scanner/adv_mining_scanner /obj/item/storage/box/miner_modkits name = "miner modkit/trophy box" desc = "Contains every modkit and trophy in the game." + storage_type = /datum/storage/box/minor_modkits -/obj/item/storage/box/miner_modkits/Initialize(mapload) - . = ..() - atom_storage.set_holdable(list(/obj/item/borg/upgrade/modkit, /obj/item/crusher_trophy)) - atom_storage.numerical_stacking = TRUE +/obj/item/storage/box/miner_modkits/PopulateContents(datum/storage_config/config) + config.compute_max_values() -/obj/item/storage/box/miner_modkits/PopulateContents() + . = list() for(var/trophy in subtypesof(/obj/item/crusher_trophy)) - new trophy(src) + . += trophy for(var/modkit in subtypesof(/obj/item/borg/upgrade/modkit)) for(var/i in 1 to 10) //minimum cost ucrrently is 20, and 2 pkas, so lets go with that - new modkit(src) + . += modkit /obj/item/storage/box/skillchips name = "box of skillchips" desc = "Contains one copy of every skillchip" -/obj/item/storage/box/skillchips/PopulateContents() - var/list/skillchips = subtypesof(/obj/item/skillchip) +/obj/item/storage/box/skillchips/PopulateContents(datum/storage_config/config) + config.compute_max_values() - for(var/skillchip in skillchips) - new skillchip(src) + return subtypesof(/obj/item/skillchip) /obj/item/storage/box/skillchips/science name = "box of science job skillchips" desc = "Contains spares of every science job skillchip." /obj/item/storage/box/skillchips/science/PopulateContents() - new/obj/item/skillchip/job/roboticist(src) - new/obj/item/skillchip/job/roboticist(src) + return list( + /obj/item/skillchip/job/roboticist, + /obj/item/skillchip/job/roboticist, + ) /obj/item/storage/box/skillchips/engineering name = "box of engineering job skillchips" desc = "Contains spares of every engineering job skillchip." /obj/item/storage/box/skillchips/engineering/PopulateContents() - new/obj/item/skillchip/job/engineer(src) - new/obj/item/skillchip/job/engineer(src) + return list( + /obj/item/skillchip/job/engineer, + /obj/item/skillchip/job/engineer, + ) + +///Chaplin boxes +/obj/item/storage/box/itemset/crusader/blue/PopulateContents(datum/storage_config/config) + config.contents_are_exceptions = TRUE + config.compute_max_item_weight = TRUE + config.compute_max_total_weight = TRUE + + return list( + /obj/item/clothing/suit/chaplainsuit/armor/crusader/blue, + /obj/item/clothing/head/helmet/plate/crusader/blue, + /obj/item/clothing/gloves/plate/blue, + /obj/item/clothing/shoes/plate/blue, + ) + +/obj/item/storage/box/itemset/crusader/red/PopulateContents(datum/storage_config/config) + config.contents_are_exceptions = TRUE + config.compute_max_item_weight = TRUE + config.compute_max_total_weight = TRUE + + return list( + /obj/item/clothing/suit/chaplainsuit/armor/crusader/red, + /obj/item/clothing/head/helmet/plate/crusader/red, + /obj/item/clothing/gloves/plate/red, + /obj/item/clothing/shoes/plate/red, + ) diff --git a/code/game/objects/items/storage/boxes/medical_boxes.dm b/code/game/objects/items/storage/boxes/medical_boxes.dm index d83aa337754..717e462a938 100644 --- a/code/game/objects/items/storage/boxes/medical_boxes.dm +++ b/code/game/objects/items/storage/boxes/medical_boxes.dm @@ -6,17 +6,20 @@ illustration = "syringe" /obj/item/storage/box/syringes/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/reagent_containers/syringe(src) + . += /obj/item/reagent_containers/syringe /obj/item/storage/box/syringes/variety name = "syringe variety box" /obj/item/storage/box/syringes/variety/PopulateContents() - new /obj/item/reagent_containers/syringe(src) - new /obj/item/reagent_containers/syringe/lethal(src) - new /obj/item/reagent_containers/syringe/piercing(src) - new /obj/item/reagent_containers/syringe/bluespace(src) + return list( + /obj/item/reagent_containers/syringe, + /obj/item/reagent_containers/syringe/lethal, + /obj/item/reagent_containers/syringe/piercing, + /obj/item/reagent_containers/syringe/bluespace, + ) /obj/item/storage/box/medipens name = "box of medipens" @@ -24,45 +27,52 @@ illustration = "epipen" /obj/item/storage/box/medipens/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/reagent_containers/hypospray/medipen(src) + . += /obj/item/reagent_containers/hypospray/medipen /obj/item/storage/box/medipens/utility name = "stimpack value kit" desc = "A box with several stimpack medipens for the economical miner." illustration = "epipen" -/obj/item/storage/box/medipens/utility/PopulateContents() - ..() // includes regular medipens. +/obj/item/storage/box/medipens/utility/PopulateContents(datum/storage_config/config) + config.compute_max_item_count = TRUE + + . = ..() // includes regular medipens. for(var/i in 1 to 5) - new /obj/item/reagent_containers/hypospray/medipen/stimpack(src) + . += /obj/item/reagent_containers/hypospray/medipen/stimpack /obj/item/storage/box/beakers name = "box of beakers" illustration = "beaker" /obj/item/storage/box/beakers/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/reagent_containers/cup/beaker( src ) + . += /obj/item/reagent_containers/cup/beaker /obj/item/storage/box/beakers/bluespace name = "box of bluespace beakers" illustration = "beaker" /obj/item/storage/box/beakers/bluespace/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/reagent_containers/cup/beaker/bluespace(src) + . += /obj/item/reagent_containers/cup/beaker/bluespace /obj/item/storage/box/beakers/variety name = "beaker variety box" /obj/item/storage/box/beakers/variety/PopulateContents() - new /obj/item/reagent_containers/cup/beaker(src) - new /obj/item/reagent_containers/cup/beaker/bluespace(src) - new /obj/item/reagent_containers/cup/beaker/large(src) - new /obj/item/reagent_containers/cup/beaker/meta(src) - new /obj/item/reagent_containers/cup/beaker/noreact(src) - new /obj/item/reagent_containers/cup/beaker/plastic(src) + return list( + /obj/item/reagent_containers/cup/beaker, + /obj/item/reagent_containers/cup/beaker/bluespace, + /obj/item/reagent_containers/cup/beaker/large, + /obj/item/reagent_containers/cup/beaker/meta, + /obj/item/reagent_containers/cup/beaker/noreact, + /obj/item/reagent_containers/cup/beaker/plastic, + ) /obj/item/storage/box/medigels name = "box of medical gels" @@ -70,8 +80,9 @@ illustration = "medgel" /obj/item/storage/box/medigels/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/reagent_containers/medigel( src ) + . += /obj/item/reagent_containers/medigel /obj/item/storage/box/injectors name = "box of DNA injectors" @@ -79,11 +90,12 @@ illustration = "dna" /obj/item/storage/box/injectors/PopulateContents() - var/static/items_inside = list( + var/static/items_inside = flatten_quantified_list(list( /obj/item/dnainjector/h2m = 3, /obj/item/dnainjector/m2h = 3, - ) - generate_items_inside(items_inside,src) + )) + + return items_inside /obj/item/storage/box/bodybags name = "body bags" @@ -91,9 +103,9 @@ illustration = "bodybags" /obj/item/storage/box/bodybags/PopulateContents() - ..() + . = list() for(var/i in 1 to 7) - new /obj/item/bodybag(src) + . += /obj/item/bodybag /obj/item/storage/box/pillbottles name = "box of pill bottles" @@ -101,16 +113,19 @@ illustration = "pillbox" /obj/item/storage/box/pillbottles/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/storage/pill_bottle(src) + . += /obj/item/storage/pill_bottle -/obj/item/storage/box/plumbing/PopulateContents() - var/list/items_inside = list( - /obj/item/stock_parts/water_recycler = 2, - /obj/item/stack/ducts/fifty = 1, - /obj/item/stack/sheet/iron/ten = 1, - ) - generate_items_inside(items_inside, src) +/obj/item/storage/box/plumbing/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + + return list( + /obj/item/stock_parts/water_recycler, + /obj/item/stock_parts/water_recycler, + /obj/item/stack/ducts/fifty, + /obj/item/stack/sheet/iron/ten, + ) /obj/item/storage/box/evilmeds name = "box of premium medicine" @@ -120,15 +135,16 @@ /obj/item/storage/box/evilmeds/PopulateContents() var/static/list/items_inside = list( - /obj/item/reagent_containers/cup/beaker/meta/omnizine = 1, - /obj/item/reagent_containers/cup/beaker/meta/sal_acid = 1, - /obj/item/reagent_containers/cup/beaker/meta/oxandrolone = 1, - /obj/item/reagent_containers/cup/beaker/meta/pen_acid = 1, - /obj/item/reagent_containers/cup/beaker/meta/atropine = 1, - /obj/item/reagent_containers/cup/beaker/meta/salbutamol = 1, - /obj/item/reagent_containers/cup/beaker/meta/rezadone = 1, + /obj/item/reagent_containers/cup/beaker/meta/omnizine, + /obj/item/reagent_containers/cup/beaker/meta/sal_acid, + /obj/item/reagent_containers/cup/beaker/meta/oxandrolone, + /obj/item/reagent_containers/cup/beaker/meta/pen_acid, + /obj/item/reagent_containers/cup/beaker/meta/atropine, + /obj/item/reagent_containers/cup/beaker/meta/salbutamol, + /obj/item/reagent_containers/cup/beaker/meta/rezadone, ) - generate_items_inside(items_inside, src) + + return items_inside /obj/item/storage/box/bandages name = "box of bandages" @@ -143,19 +159,12 @@ illustration = null w_class = WEIGHT_CLASS_SMALL custom_price = PAYCHECK_CREW * 1.75 - -/obj/item/storage/box/bandages/Initialize(mapload) - . = ..() - atom_storage.max_slots = 6 - atom_storage.set_holdable(list( - /obj/item/stack/medical/bandage, - /obj/item/reagent_containers/applicator/pill, - /obj/item/reagent_containers/applicator/patch, - )) + storage_type = /datum/storage/box/bandages /obj/item/storage/box/bandages/PopulateContents() + . = list() for(var/i in 1 to 5) - new /obj/item/stack/medical/bandage(src) + . += /obj/item/stack/medical/bandage /obj/item/storage/box/bandages/update_icon_state() . = ..() diff --git a/code/game/objects/items/storage/boxes/science_boxes.dm b/code/game/objects/items/storage/boxes/science_boxes.dm index 27d69a493d1..4d564d5d5bb 100644 --- a/code/game/objects/items/storage/boxes/science_boxes.dm +++ b/code/game/objects/items/storage/boxes/science_boxes.dm @@ -6,8 +6,9 @@ illustration = "swab" /obj/item/storage/box/swab/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/swab(src) + . += /obj/item/swab /obj/item/storage/box/petridish name = "box of petri dishes" @@ -15,8 +16,9 @@ illustration = "petridish" /obj/item/storage/box/petridish/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/petri_dish(src) + . += /obj/item/petri_dish /obj/item/storage/box/plumbing name = "box of plumbing supplies" @@ -29,26 +31,25 @@ illustration = "disk_kit" /obj/item/storage/box/disks/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/disk/data(src) + . += /obj/item/disk/data /obj/item/storage/box/monkeycubes name = "monkey cube box" desc = "Drymate brand monkey cubes. Just add water!" icon_state = "monkeycubebox" illustration = null + custom_price = PAYCHECK_CREW * 2 + storage_type = /datum/storage/box/monkey_cubes + /// Which type of cube are we spawning in this box? var/cube_type = /obj/item/food/monkeycube - custom_price = PAYCHECK_CREW * 2 - -/obj/item/storage/box/monkeycubes/Initialize(mapload) - . = ..() - atom_storage.max_slots = 7 - atom_storage.set_holdable(/obj/item/food/monkeycube) /obj/item/storage/box/monkeycubes/PopulateContents() + . = list() for(var/i in 1 to 5) - new cube_type(src) + . += cube_type /obj/item/storage/box/monkeycubes/syndicate desc = "Waffle Corp. brand monkey cubes. Just add water and a dash of subterfuge!" @@ -59,29 +60,30 @@ desc = "Waffle Corp. brand gorilla cubes. Do not taunt." icon_state = "monkeycubebox" illustration = null - -/obj/item/storage/box/gorillacubes/Initialize(mapload) - . = ..() - atom_storage.max_slots = 3 - atom_storage.set_holdable(/obj/item/food/monkeycube) + storage_type = /datum/storage/box/gorilla_cubes /obj/item/storage/box/gorillacubes/PopulateContents() + . = list() for(var/i in 1 to 3) - new /obj/item/food/monkeycube/gorilla(src) + . += /obj/item/food/monkeycube/gorilla + +/obj/item/storage/box/stockparts + storage_type = /datum/storage/box/stockparts /obj/item/storage/box/stockparts/basic //for ruins where it's a bad idea to give access to an autolathe/protolathe, but still want to make stock parts accessible name = "box of stock parts" desc = "Contains a variety of basic stock parts." /obj/item/storage/box/stockparts/basic/PopulateContents() - var/static/items_inside = list( + var/static/items_inside = flatten_quantified_list(list( /obj/item/stock_parts/capacitor = 3, /obj/item/stock_parts/servo = 3, /obj/item/stock_parts/matter_bin = 3, /obj/item/stock_parts/micro_laser = 3, /obj/item/stock_parts/scanning_module = 3, - ) - generate_items_inside(items_inside,src) + )) + + return items_inside /obj/item/storage/box/stockparts/deluxe name = "box of deluxe stock parts" @@ -89,14 +91,15 @@ icon_state = "syndiebox" /obj/item/storage/box/stockparts/deluxe/PopulateContents() - var/static/items_inside = list( + var/static/items_inside = flatten_quantified_list(list( /obj/item/stock_parts/capacitor/quadratic = 3, /obj/item/stock_parts/scanning_module/triphasic = 3, /obj/item/stock_parts/servo/femto = 3, /obj/item/stock_parts/micro_laser/quadultra = 3, /obj/item/stock_parts/matter_bin/bluespace = 3, - ) - generate_items_inside(items_inside,src) + )) + + return items_inside /obj/item/storage/box/rndboards name = "\proper the liberator's legacy" @@ -104,45 +107,43 @@ illustration = "scicircuit" /obj/item/storage/box/rndboards/PopulateContents() - new /obj/item/circuitboard/machine/protolathe/offstation(src) - new /obj/item/circuitboard/machine/destructive_analyzer(src) - new /obj/item/circuitboard/machine/circuit_imprinter/offstation(src) - new /obj/item/circuitboard/computer/rdconsole(src) + return list( + /obj/item/circuitboard/machine/protolathe/offstation, + /obj/item/circuitboard/machine/destructive_analyzer, + /obj/item/circuitboard/machine/circuit_imprinter/offstation, + /obj/item/circuitboard/computer/rdconsole, + ) /obj/item/storage/box/stabilized //every single stabilized extract from xenobiology name = "box of stabilized extracts" icon_state = "syndiebox" -/obj/item/storage/box/stabilized/Initialize(mapload) - . = ..() - atom_storage.allow_big_nesting = TRUE - atom_storage.max_slots = 99 - atom_storage.max_specific_storage = WEIGHT_CLASS_GIGANTIC - atom_storage.max_total_storage = 99 +/obj/item/storage/box/stabilized/PopulateContents(datum/storage_config/config) + config.compute_max_values() -/obj/item/storage/box/stabilized/PopulateContents() var/static/items_inside = list( - /obj/item/slimecross/stabilized/adamantine=1, - /obj/item/slimecross/stabilized/black=1, - /obj/item/slimecross/stabilized/blue=1, - /obj/item/slimecross/stabilized/bluespace=1, - /obj/item/slimecross/stabilized/cerulean=1, - /obj/item/slimecross/stabilized/darkblue=1, - /obj/item/slimecross/stabilized/darkpurple=1, - /obj/item/slimecross/stabilized/gold=1, - /obj/item/slimecross/stabilized/green=1, - /obj/item/slimecross/stabilized/grey=1, - /obj/item/slimecross/stabilized/lightpink=1, - /obj/item/slimecross/stabilized/metal=1, - /obj/item/slimecross/stabilized/oil=1, - /obj/item/slimecross/stabilized/orange=1, - /obj/item/slimecross/stabilized/pink=1, - /obj/item/slimecross/stabilized/purple=1, - /obj/item/slimecross/stabilized/pyrite=1, - /obj/item/slimecross/stabilized/rainbow=1, - /obj/item/slimecross/stabilized/red=1, - /obj/item/slimecross/stabilized/sepia=1, - /obj/item/slimecross/stabilized/silver=1, - /obj/item/slimecross/stabilized/yellow=1, + /obj/item/slimecross/stabilized/adamantine, + /obj/item/slimecross/stabilized/black, + /obj/item/slimecross/stabilized/blue, + /obj/item/slimecross/stabilized/bluespace, + /obj/item/slimecross/stabilized/cerulean, + /obj/item/slimecross/stabilized/darkblue, + /obj/item/slimecross/stabilized/darkpurple, + /obj/item/slimecross/stabilized/gold, + /obj/item/slimecross/stabilized/green, + /obj/item/slimecross/stabilized/grey, + /obj/item/slimecross/stabilized/lightpink, + /obj/item/slimecross/stabilized/metal, + /obj/item/slimecross/stabilized/oil, + /obj/item/slimecross/stabilized/orange, + /obj/item/slimecross/stabilized/pink, + /obj/item/slimecross/stabilized/purple, + /obj/item/slimecross/stabilized/pyrite, + /obj/item/slimecross/stabilized/rainbow, + /obj/item/slimecross/stabilized/red, + /obj/item/slimecross/stabilized/sepia, + /obj/item/slimecross/stabilized/silver, + /obj/item/slimecross/stabilized/yellow, ) - generate_items_inside(items_inside,src) + + return items_inside diff --git a/code/game/objects/items/storage/boxes/security_boxes.dm b/code/game/objects/items/storage/boxes/security_boxes.dm index de18eb76258..035e246aa10 100644 --- a/code/game/objects/items/storage/boxes/security_boxes.dm +++ b/code/game/objects/items/storage/boxes/security_boxes.dm @@ -7,8 +7,9 @@ illustration = "flashbang" /obj/item/storage/box/flashbangs/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/grenade/flashbang(src) + . += /obj/item/grenade/flashbang /obj/item/storage/box/stingbangs name = "box of stingbangs (WARNING)" @@ -17,8 +18,9 @@ illustration = "flashbang" /obj/item/storage/box/stingbangs/PopulateContents() + . = list() for(var/i in 1 to 5) - new /obj/item/grenade/stingbang(src) + . += /obj/item/grenade/stingbang /obj/item/storage/box/flashes name = "box of flashbulbs" @@ -27,8 +29,9 @@ illustration = "flash" /obj/item/storage/box/flashes/PopulateContents() + . = list() for(var/i in 1 to 6) - new /obj/item/assembly/flash/handheld(src) + . += /obj/item/assembly/flash/handheld /obj/item/storage/box/wall_flash name = "wall-mounted flash kit" @@ -40,15 +43,19 @@ var/id = rand(1000, 9999) // FIXME what if this conflicts with an existing one? - new /obj/item/wallframe/button(src) - new /obj/item/electronics/airlock(src) - var/obj/item/assembly/control/flasher/remote = new(src) + var/obj/item/assembly/control/flasher/remote = new(null) remote.id = id - var/obj/item/wallframe/flasher/frame = new(src) + var/obj/item/wallframe/flasher/frame = new(null) frame.id = id - new /obj/item/assembly/flash/handheld(src) - new /obj/item/screwdriver(src) + return list( + /obj/item/wallframe/button, + /obj/item/electronics/airlock, + /obj/item/assembly/flash/handheld, + /obj/item/screwdriver, + remote, + frame, + ) /obj/item/storage/box/teargas name = "box of tear gas grenades (WARNING)" @@ -57,8 +64,9 @@ illustration = "grenade" /obj/item/storage/box/teargas/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/grenade/chem_grenade/teargas(src) + . += /obj/item/grenade/chem_grenade/teargas /obj/item/storage/box/emps name = "box of emp grenades" @@ -66,8 +74,9 @@ illustration = "emp" /obj/item/storage/box/emps/PopulateContents() + . = list() for(var/i in 1 to 5) - new /obj/item/grenade/empgrenade(src) + . += /obj/item/grenade/empgrenade /obj/item/storage/box/prisoner name = "box of prisoner IDs" @@ -76,14 +85,15 @@ illustration = "id" /obj/item/storage/box/prisoner/PopulateContents() - ..() - new /obj/item/card/id/advanced/prisoner/one(src) - new /obj/item/card/id/advanced/prisoner/two(src) - new /obj/item/card/id/advanced/prisoner/three(src) - new /obj/item/card/id/advanced/prisoner/four(src) - new /obj/item/card/id/advanced/prisoner/five(src) - new /obj/item/card/id/advanced/prisoner/six(src) - new /obj/item/card/id/advanced/prisoner/seven(src) + return list( + /obj/item/card/id/advanced/prisoner/one, + /obj/item/card/id/advanced/prisoner/two, + /obj/item/card/id/advanced/prisoner/three, + /obj/item/card/id/advanced/prisoner/four, + /obj/item/card/id/advanced/prisoner/five, + /obj/item/card/id/advanced/prisoner/six, + /obj/item/card/id/advanced/prisoner/seven, + ) /obj/item/storage/box/seccarts name = "box of PDA security cartridges" @@ -92,8 +102,9 @@ illustration = "pda" /obj/item/storage/box/seccarts/PopulateContents() + . = list() for(var/i in 1 to 6) - new /obj/item/computer_disk/security(src) + . += /obj/item/computer_disk/security /obj/item/storage/box/firingpins name = "box of standard firing pins" @@ -102,8 +113,9 @@ illustration = "firingpin" /obj/item/storage/box/firingpins/PopulateContents() + . = list() for(var/i in 1 to 5) - new /obj/item/firing_pin(src) + . += /obj/item/firing_pin /obj/item/storage/box/firingpins/paywall name = "box of paywall firing pins" @@ -111,8 +123,9 @@ illustration = "firingpin" /obj/item/storage/box/firingpins/paywall/PopulateContents() + . = list() for(var/i in 1 to 5) - new /obj/item/firing_pin/paywall(src) + . += /obj/item/firing_pin/paywall /obj/item/storage/box/lasertagpins name = "box of laser tag firing pins" @@ -120,9 +133,10 @@ illustration = "firingpin" /obj/item/storage/box/lasertagpins/PopulateContents() + . = list() for(var/i in 1 to 3) - new /obj/item/firing_pin/tag/red(src) - new /obj/item/firing_pin/tag/blue(src) + . += /obj/item/firing_pin/tag/red + . += /obj/item/firing_pin/tag/blue /obj/item/storage/box/handcuffs name = "box of spare handcuffs" @@ -131,8 +145,9 @@ illustration = "handcuff" /obj/item/storage/box/handcuffs/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/restraints/handcuffs(src) + . += /obj/item/restraints/handcuffs /obj/item/storage/box/zipties name = "box of spare zipties" @@ -141,8 +156,9 @@ illustration = "handcuff" /obj/item/storage/box/zipties/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/restraints/handcuffs/cable/zipties(src) + . += /obj/item/restraints/handcuffs/cable/zipties /obj/item/storage/box/alienhandcuffs name = "box of spare handcuffs" @@ -151,8 +167,9 @@ illustration = "handcuff" /obj/item/storage/box/alienhandcuffs/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/restraints/handcuffs/alien(src) + . += /obj/item/restraints/handcuffs/alien /obj/item/storage/box/rubbershot name = "box of shotgun shells (Less Lethal - Rubber Shot)" @@ -161,8 +178,9 @@ illustration = null /obj/item/storage/box/rubbershot/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/ammo_casing/shotgun/rubbershot(src) + . += /obj/item/ammo_casing/shotgun/rubbershot /obj/item/storage/box/lethalshot name = "box of shotgun shells (Lethal)" @@ -171,14 +189,16 @@ illustration = null /obj/item/storage/box/lethalshot/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/ammo_casing/shotgun/buckshot(src) + . += /obj/item/ammo_casing/shotgun/buckshot /obj/item/storage/box/lethalshot/old /obj/item/storage/box/lethalshot/old/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/ammo_casing/shotgun/buckshot/old(src) + . += /obj/item/ammo_casing/shotgun/buckshot/old /obj/item/storage/box/slugs name = "box of shotgun shells (Lethal - Slugs)" @@ -187,8 +207,9 @@ illustration = null /obj/item/storage/box/slugs/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/ammo_casing/shotgun(src) + . += /obj/item/ammo_casing/shotgun /obj/item/storage/box/beanbag name = "box of shotgun shells (Less Lethal - Beanbag)" @@ -197,8 +218,9 @@ illustration = null /obj/item/storage/box/beanbag/PopulateContents() + . = list() for(var/i in 1 to 6) - new /obj/item/ammo_casing/shotgun/beanbag(src) + . += /obj/item/ammo_casing/shotgun/beanbag /obj/item/storage/box/breacherslug name = "box of breaching shotgun shells" @@ -207,8 +229,9 @@ illustration = null /obj/item/storage/box/breacherslug/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/ammo_casing/shotgun/breacher(src) + . += /obj/item/ammo_casing/shotgun/breacher /obj/item/storage/box/large_dart name = "box of XL shotgun darts" @@ -217,16 +240,18 @@ illustration = null /obj/item/storage/box/large_dart/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/ammo_casing/shotgun/dart/large(src) + . += /obj/item/ammo_casing/shotgun/dart/large /obj/item/storage/box/emptysandbags name = "box of empty sandbags" illustration = "sandbag" /obj/item/storage/box/emptysandbags/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/emptysandbag(src) + . += /obj/item/emptysandbag /obj/item/storage/box/holy_grenades name = "box of holy hand grenades" @@ -234,8 +259,9 @@ illustration = "grenade" /obj/item/storage/box/holy_grenades/PopulateContents() + . = list() for(var/i in 1 to 7) - new/obj/item/grenade/chem_grenade/holy(src) + . += /obj/item/grenade/chem_grenade/holy /obj/item/storage/box/fireworks name = "box of fireworks" @@ -243,22 +269,25 @@ illustration = "sparkler" /obj/item/storage/box/fireworks/PopulateContents() - for(var/i in 1 to 3) - new/obj/item/sparkler(src) - new/obj/item/grenade/firecracker(src) - new /obj/item/toy/snappop(src) + return flatten_quantified_list(list( + /obj/item/sparkler = 3, + /obj/item/grenade/firecracker = 3, + /obj/item/toy/snappop = 1, + )) /obj/item/storage/box/fireworks/dangerous desc = "This box has a small label on it stating that it's from the Gorlex Marauders. Contains an assortment of \"fireworks\"." /obj/item/storage/box/fireworks/dangerous/PopulateContents() + . = list() for(var/i in 1 to 3) - new/obj/item/sparkler(src) - new/obj/item/grenade/firecracker(src) + . += /obj/item/sparkler + . += /obj/item/grenade/firecracker + if(prob(20)) - new /obj/item/grenade/frag(src) + . += /obj/item/grenade/frag else - new /obj/item/toy/snappop(src) + . += /obj/item/toy/snappop /obj/item/storage/box/firecrackers name = "box of firecrackers" @@ -267,8 +296,9 @@ illustration = "firecracker" /obj/item/storage/box/firecrackers/PopulateContents() + . = list() for(var/i in 1 to 7) - new/obj/item/grenade/firecracker(src) + . += /obj/item/grenade/firecracker /obj/item/storage/box/sparklers name = "box of sparklers" @@ -276,5 +306,6 @@ illustration = "sparkler" /obj/item/storage/box/sparklers/PopulateContents() + . = list() for(var/i in 1 to 7) - new/obj/item/sparkler(src) + . += /obj/item/sparkler diff --git a/code/game/objects/items/storage/boxes/service_boxes.dm b/code/game/objects/items/storage/boxes/service_boxes.dm index 6d4aedf4bfc..136dac2c069 100644 --- a/code/game/objects/items/storage/boxes/service_boxes.dm +++ b/code/game/objects/items/storage/boxes/service_boxes.dm @@ -7,16 +7,19 @@ illustration = "drinkglass" /obj/item/storage/box/drinkingglasses/PopulateContents() + . = list() for(var/i in 1 to 6) - new /obj/item/reagent_containers/cup/glass/drinkingglass(src) + . += /obj/item/reagent_containers/cup/glass/drinkingglass + /obj/item/storage/box/cups name = "box of paper cups" desc = "It has pictures of paper cups on the front." illustration = "cup" /obj/item/storage/box/cups/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/reagent_containers/cup/glass/sillycup(src) + . += /obj/item/reagent_containers/cup/glass/sillycup //Some spare PDAs in a box /obj/item/storage/box/pdas @@ -25,8 +28,9 @@ illustration = "pda" /obj/item/storage/box/pdas/PopulateContents() + . = list() for(var/i in 1 to 4) - new /obj/item/modular_computer/pda(src) + . += /obj/item/modular_computer/pda /obj/item/storage/box/ids name = "box of spare IDs" @@ -34,16 +38,19 @@ illustration = "id" /obj/item/storage/box/ids/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/card/id/advanced(src) + . += /obj/item/card/id/advanced + /obj/item/storage/box/silver_ids name = "box of spare silver IDs" desc = "Shiny IDs for important people." illustration = "id" /obj/item/storage/box/silver_ids/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/card/id/advanced/silver(src) + . += /obj/item/card/id/advanced/silver /obj/item/storage/box/mousetraps name = "box of Pest-B-Gon mousetraps" @@ -51,8 +58,9 @@ illustration = "mousetrap" /obj/item/storage/box/mousetraps/PopulateContents() + . = list() for(var/i in 1 to 6) - new /obj/item/assembly/mousetrap(src) + . += /obj/item/assembly/mousetrap /obj/item/storage/box/snappops name = "snap pop box" @@ -60,15 +68,12 @@ icon = 'icons/obj/toys/toy.dmi' icon_state = "spbox" illustration = "" - -/obj/item/storage/box/snappops/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/toy/snappop) - atom_storage.max_slots = 8 + storage_type = /datum/storage/box/snappops /obj/item/storage/box/snappops/PopulateContents() + . = list() for(var/i in 1 to 8) - new /obj/item/toy/snappop(src) + . += /obj/item/toy/snappop /obj/item/storage/box/matches name = "matchbox" @@ -86,16 +91,16 @@ custom_price = PAYCHECK_CREW * 0.4 base_icon_state = "matchbox" illustration = null + storage_type = /datum/storage/box/matches /obj/item/storage/box/matches/Initialize(mapload) . = ..() - atom_storage.max_slots = 10 - atom_storage.set_holdable(/obj/item/match) AddElement(/datum/element/ignites_matches) /obj/item/storage/box/matches/PopulateContents() + . = list() for(var/i in 1 to 10) - new /obj/item/match(src) + . += /obj/item/match /obj/item/storage/box/matches/update_icon_state() . = ..() @@ -117,61 +122,62 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' foldable_result = /obj/item/stack/sheet/cardboard //BubbleWrap illustration = "light" - -/obj/item/storage/box/lights/Initialize(mapload) - . = ..() - atom_storage.max_slots = 21 - atom_storage.set_holdable(list(/obj/item/light/tube, /obj/item/light/bulb)) - atom_storage.max_total_storage = 21 - atom_storage.allow_quick_gather = FALSE //temp workaround to re-enable filling the light replacer with the box + storage_type = /datum/storage/box/lights /obj/item/storage/box/lights/bulbs/PopulateContents() + . = list() for(var/i in 1 to 21) - new /obj/item/light/bulb(src) + . += /obj/item/light/bulb /obj/item/storage/box/lights/tubes name = "box of replacement tubes" illustration = "lighttube" /obj/item/storage/box/lights/tubes/PopulateContents() + . = list() for(var/i in 1 to 21) - new /obj/item/light/tube(src) + . += /obj/item/light/tube /obj/item/storage/box/lights/mixed name = "box of replacement lights" illustration = "lightmixed" /obj/item/storage/box/lights/mixed/PopulateContents() - for(var/i in 1 to 14) - new /obj/item/light/tube(src) - for(var/i in 1 to 7) - new /obj/item/light/bulb(src) + return flatten_quantified_list(list( + /obj/item/light/tube = 14, + /obj/item/light/bulb = 7, + )) /obj/item/storage/box/fountainpens name = "box of fountain pens" illustration = "fpen" /obj/item/storage/box/fountainpens/PopulateContents() + . = list() for(var/i in 1 to 7) - new /obj/item/pen/fountain(src) + . += /obj/item/pen/fountain /obj/item/storage/box/dishdrive name = "DIY Dish Drive Kit" desc = "Contains everything you need to build your own Dish Drive!" custom_premium_price = PAYCHECK_CREW * 3 -/obj/item/storage/box/dishdrive/PopulateContents() - var/static/items_inside = list( - /obj/item/circuitboard/machine/dish_drive = 1, - /obj/item/screwdriver = 1, - /obj/item/stack/cable_coil/five = 1, - /obj/item/stack/sheet/glass = 1, - /obj/item/stack/sheet/iron/five = 1, - /obj/item/stock_parts/servo = 1, - /obj/item/stock_parts/matter_bin = 2, - /obj/item/wrench = 1, +/obj/item/storage/box/dishdrive/PopulateContents(datum/storage_config/config) + config.compute_max_item_count = TRUE + + var/static/list/obj/item/items_inside = list( + /obj/item/circuitboard/machine/dish_drive, + /obj/item/screwdriver, + /obj/item/stack/cable_coil/five, + /obj/item/stack/sheet/glass, + /obj/item/stack/sheet/iron/five, + /obj/item/stock_parts/servo, + /obj/item/stock_parts/matter_bin, + /obj/item/stock_parts/matter_bin, + /obj/item/wrench, ) - generate_items_inside(items_inside,src) + + return items_inside /obj/item/storage/box/actionfigure name = "box of action figures" @@ -179,9 +185,11 @@ icon_state = "box" /obj/item/storage/box/actionfigure/PopulateContents() + . = list() + + var/static/list/obj/item/toy/figure/types = subtypesof(/obj/item/toy/figure) for(var/i in 1 to 4) - var/random_figure = pick(subtypesof(/obj/item/toy/figure)) - new random_figure(src) + . += pick(types) /obj/item/storage/box/tail_pin name = "pin the tail on the corgi supplies" @@ -189,33 +197,30 @@ custom_price = PAYCHECK_COMMAND * 1.25 /obj/item/storage/box/tail_pin/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/poster/tail_board(src) - new /obj/item/tail_pin(src) + return flatten_quantified_list(list( + /obj/item/poster/tail_board = 3, + /obj/item/tail_pin = 3, + )) /obj/item/storage/box/party_poppers name = "box of party poppers" desc = "Turn any event into a celebration and ensure the janitor stays busy." /obj/item/storage/box/party_poppers/PopulateContents() + . = list() for(var/i in 1 to 5) - new /obj/item/reagent_containers/spray/chemsprayer/party(src) + . += /obj/item/reagent_containers/spray/chemsprayer/party /obj/item/storage/box/balloons name = "box of long balloons" desc = "A completely randomized and wacky box of long balloons, harvested straight from balloon farms on the clown planet." illustration = "balloon" - -/obj/item/storage/box/balloons/Initialize(mapload) - . = ..() - atom_storage.max_slots = 24 - atom_storage.set_holdable(list(/obj/item/toy/balloon/long)) - atom_storage.max_total_storage = 24 - atom_storage.allow_quick_gather = FALSE + storage_type = /datum/storage/box/balloons /obj/item/storage/box/balloons/PopulateContents() + . = list() for(var/i in 1 to 24) - new /obj/item/toy/balloon/long(src) + . += /obj/item/toy/balloon/long /obj/item/storage/box/stickers name = "sticker pack" @@ -224,6 +229,9 @@ icon_state = "stickerpack" illustration = null w_class = WEIGHT_CLASS_TINY + storage_type = /datum/storage/box/stickers + + ///Laels to pick from for this box illustration var/static/list/pack_labels = list( "smile", "frown", @@ -235,9 +243,6 @@ /obj/item/storage/box/stickers/Initialize(mapload) . = ..() - atom_storage.max_slots = 8 - atom_storage.set_holdable(list(/obj/item/sticker)) - atom_storage.max_specific_storage = WEIGHT_CLASS_TINY if(isnull(illustration)) illustration = pick(pack_labels) update_appearance() @@ -257,9 +262,9 @@ if(isnull(non_contraband)) non_contraband = generate_non_contraband_stickers_list() + . = list() for(var/i in 1 to rand(4, 8)) - var/type = pick(non_contraband) - new type(src) + . += pick(non_contraband) /obj/item/storage/box/stickers/googly name = "googly eye sticker pack" @@ -267,5 +272,6 @@ illustration = "googly-alt" /obj/item/storage/box/stickers/googly/PopulateContents() + . = list() for(var/i in 1 to 6) - new /obj/item/sticker/googly(src) + . += /obj/item/sticker/googly diff --git a/code/game/objects/items/storage/boxes/trait_boxes.dm b/code/game/objects/items/storage/boxes/trait_boxes.dm new file mode 100644 index 00000000000..7b999932626 --- /dev/null +++ b/code/game/objects/items/storage/boxes/trait_boxes.dm @@ -0,0 +1,31 @@ + +/// A box containing a skub, for easier carry because skub is a bulky item. +/obj/item/storage/box/stickers/skub + name = "skub fan pack" + desc = "A vinyl pouch to store your skub and pro-skub shirt in. A label on the back reads: \"Skubtide, Stationwide\"." + icon_state = "skubpack" + illustration = "label_skub" + w_class = WEIGHT_CLASS_SMALL + storage_type = /datum/storage/box/stickers/skub + +/obj/item/storage/box/stickers/skub/PopulateContents() + return list( + /obj/item/skub, + /obj/item/sticker/skub, + /obj/item/sticker/skub + ) + +/obj/item/storage/box/stickers/anti_skub + name = "anti-skub stickers pack" + desc = "The enemy may have been given a skub and a shirt, but I've got more stickers! Plus the pack can hold my anti-skub shirt." + icon_state = "skubpack" + illustration = "label_anti_skub" + storage_type = /datum/storage/box/stickers/anti_skub + +/obj/item/storage/box/stickers/anti_skub/PopulateContents() + return list( + /obj/item/sticker/anti_skub, + /obj/item/sticker/anti_skub, + /obj/item/sticker/anti_skub, + /obj/item/sticker/anti_skub, + ) diff --git a/code/game/objects/items/storage/boxes/uplink_kits.dm b/code/game/objects/items/storage/boxes/uplink_kits.dm new file mode 100644 index 00000000000..fcc055e2748 --- /dev/null +++ b/code/game/objects/items/storage/boxes/uplink_kits.dm @@ -0,0 +1,1029 @@ +#define KIT_RECON "recon" +#define KIT_BLOODY_SPAI "bloodyspai" +#define KIT_STEALTHY "stealth" +#define KIT_SCREWED "screwed" +#define KIT_SABOTAGE "sabotage" +#define KIT_GUN "guns" +#define KIT_MURDER "murder" +#define KIT_IMPLANTS "implant" +#define KIT_HACKER "hacker" +#define KIT_SNIPER "sniper" +#define KIT_NUKEOPS_METAGAME "metaops" +#define KIT_LORD_SINGULOTH "lordsingulo" +#define KIT_REVOLUTIONARY "revolutionary" + +#define KIT_JAMES_BOND "bond" +#define KIT_NINJA "ninja" +#define KIT_DARK_LORD "darklord" +#define KIT_WHITE_WHALE_HOLY_GRAIL "white_whale_holy_grail" +#define KIT_MAD_SCIENTIST "mad_scientist" +#define KIT_BEES "bee" +#define KIT_MR_FREEZE "mr_freeze" +#define KIT_TRAITOR_2006 "ancient" +#define KIT_DEAD_MONEY "dead_money" +#define KIT_SAM_FISHER "sam_fisher" +#define KIT_PROP_HUNT "prop_hunt" + +/// last audited december 2022 +/obj/item/storage/box/syndicate + storage_type = /datum/storage/box/syndicate + +/obj/item/storage/box/syndicate/bundle_a/PopulateContents(datum/storage_config/config) + config.compute_max_values() + + switch (pick_weight(list( + KIT_RECON = 2, + KIT_BLOODY_SPAI = 3, + KIT_STEALTHY = 2, + KIT_SCREWED = 2, + KIT_SABOTAGE = 3, + KIT_GUN = 2, + KIT_MURDER = 2, + KIT_IMPLANTS = 1, + KIT_HACKER = 3, + KIT_SNIPER = 1, + KIT_NUKEOPS_METAGAME = 1, + KIT_REVOLUTIONARY = 2 + ))) + if(KIT_RECON) + return list( + /obj/item/clothing/glasses/thermal/xray, // ~8 tc? + /obj/item/storage/briefcase/launchpad, //6 tc + /obj/item/binoculars, // 2 tc? + /obj/item/encryptionkey/syndicate, // 2 tc + /obj/item/storage/box/syndie_kit/space, //4 tc + /obj/item/grenade/frag, // ~2 tc each? + /obj/item/grenade/frag, + /obj/item/flashlight/emp, // 4 tc + ) + + if(KIT_BLOODY_SPAI) + return list( + /obj/item/card/id/advanced/chameleon, // 2 tc + /obj/item/clothing/under/chameleon, // 2 tc since it's not the full set + /obj/item/clothing/mask/chameleon, // Goes with above + /obj/item/clothing/shoes/chameleon/noslip, // 2 tc + /obj/item/computer_disk/syndicate/camera_app, // 1 tc + /obj/item/multitool/ai_detect, // 1 tc + /obj/item/encryptionkey/syndicate, // 2 tc + /obj/item/reagent_containers/syringe/mulligan, // 4 tc + /obj/item/switchblade, //basically 1 tc as it can be bought from BM kits + /obj/item/storage/fancy/cigarettes/cigpack_syndicate , // 2 tc this shit heals + /obj/item/flashlight/emp, // 2 tc + /obj/item/chameleon, // 7 tc + /obj/item/implanter/storage, // 6 tc + ) + + if(KIT_STEALTHY) + return list( + /obj/item/gun/energy/recharge/ebow, // 10 tc + /obj/item/pen/sleepy, // 4 tc + /obj/item/healthanalyzer/rad_laser, // 3 tc + /obj/item/chameleon, // 7 tc + /obj/item/soap/syndie, // 1 tc + /obj/item/clothing/glasses/thermal/syndi, // 4 tc + /obj/item/flashlight/emp, // 2 tc + /obj/item/jammer, // 5 tc + ) + + if(KIT_GUN) + return list( + /obj/item/gun/ballistic/revolver, // 13 tc + /obj/item/ammo_box/a357, // 4tc + /obj/item/ammo_box/a357, + /obj/item/storage/belt/holster/chameleon, // 1 tc + /obj/item/card/emag/doorjack, // 3 tc replaced the emag with the doorjack + /obj/item/grenade/c4, // 1 tc + /obj/item/clothing/gloves/latex/nitrile, // ~1 tc for whole outfit + /obj/item/clothing/mask/gas/clown_hat, + /obj/item/clothing/under/suit/black_really, + /obj/item/clothing/neck/tie/red/hitman, + ) + + if(KIT_SCREWED) + var/obj/item/clothing/suit/space/syndicate/spess_suit = pick(GLOB.syndicate_space_suits_to_helmets) + + return list( + /obj/item/sbeacondrop/bomb, // 11 tc + /obj/item/grenade/syndieminibomb, // 6 tc + /obj/item/sbeacondrop/powersink, // 11 tc + spess_suit, // Above allows me to get the helmet from a variable on the object + GLOB.syndicate_space_suits_to_helmets[spess_suit], // 4 TC for the space gear + /obj/item/encryptionkey/syndicate, // 2 tc + ) + + if(KIT_MURDER) + return list( + /obj/item/melee/energy/sword/saber, // 8 tc + /obj/item/clothing/glasses/thermal/syndi, // 4 tc + /obj/item/card/emag/doorjack, // 3 tc + /obj/item/clothing/shoes/chameleon/noslip, // 2 tc + /obj/item/encryptionkey/syndicate, // 2 tc + /obj/item/grenade/syndieminibomb, // 6 tc + ) + + if(KIT_IMPLANTS) + return list( + /obj/item/implanter/freedom, // 5 tc + /obj/item/implanter/uplink/precharged, // 10 tc is inside this thing + /obj/item/implanter/emp, // 1 tc + /obj/item/implanter/explosive, // 2 tc + /obj/item/implanter/storage, // 8 tc + ) + + if(KIT_HACKER) //L-L--LOOK AT YOU, HACKER + return list( + /obj/item/ai_module/syndicate, // 4 tc + /obj/item/card/emag, // 4 tc + /obj/item/card/emag/doorjack, // 3 tc + /obj/item/encryptionkey/binary, // 5 tc + /obj/item/ai_module/toy_ai, // ~6 tc + /obj/item/multitool/ai_detect, // 1 tc + /obj/item/storage/toolbox/syndicate, // 1 tc + /obj/item/computer_disk/syndicate/camera_app, // 1 tc + /obj/item/clothing/glasses/thermal/syndi, // 4 tc + /obj/item/card/id/advanced/chameleon, // 2 tc + ) + + if(KIT_LORD_SINGULOTH) //currently disabled, i might return with another anti-engine kit + var/obj/item/clothing/suit/space/syndicate/spess_suit = pick(GLOB.syndicate_space_suits_to_helmets) + + . = list( + /obj/item/sbeacondrop, // 10 tc + spess_suit, // Above allows me to get the helmet from a variable on the object + GLOB.syndicate_space_suits_to_helmets[spess_suit], // 4 TC for the space gear + /obj/item/card/emag, // 4 tc + /obj/item/storage/toolbox/syndicate, // 1 tc + /obj/item/card/id/advanced/mining, + /obj/item/stack/spacecash/c10000, // this is technically 10 tc but not really + ) + + if(prob(70)) + . += /obj/item/toy/spinningtoy //lol + else + . += /obj/item/toy/spinningtoy/dark_matter //edgy lol + + if(KIT_SABOTAGE) + return list( + /obj/item/storage/backpack/duffelbag/syndie/sabotage, // 5 tc for 3 c4 and 2 x4 + /obj/item/computer_disk/syndicate/camera_app, // 1 tc + /obj/item/sbeacondrop/powersink, // 11 tc + /obj/item/computer_disk/virus/detomatix, // 6 tc + /obj/item/storage/toolbox/syndicate, // 1 tc + /obj/item/pizzabox/bomb, // 6 tc + /obj/item/storage/box/syndie_kit/emp, // 2 tc + ) + + if(KIT_SNIPER) //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks + return list( + /obj/item/gun/ballistic/rifle/sniper_rifle, // 12 tc + /obj/item/ammo_box/magazine/sniper_rounds/penetrator, // 5 tc + /obj/item/clothing/glasses/thermal/syndi, // 4 tc + /obj/item/clothing/gloves/latex/nitrile, // ~ 1 tc for outfit + /obj/item/clothing/mask/gas/clown_hat, + /obj/item/clothing/under/suit/black_really, + /obj/item/clothing/neck/tie/red/hitman, + ) + + if(KIT_NUKEOPS_METAGAME) + return list( + /obj/item/mod/control/pre_equipped/nuclear/unrestricted, // 8 tc + /obj/item/gun/ballistic/shotgun/bulldog/unrestricted, // 8 tc + /obj/item/implanter/explosive, // 2 tc + /obj/item/ammo_box/magazine/m12g, // 2 tc + /obj/item/ammo_box/magazine/m12g, // 2 tc + /obj/item/grenade/c4 , // 1 tc + /obj/item/grenade/c4 , // 1 tc + /obj/item/card/emag, // 4 tc + /obj/item/card/emag/doorjack, // 3 tc + ) + + if(KIT_REVOLUTIONARY) + return list( + /obj/item/healthanalyzer/rad_laser, // 3 TC + /obj/item/assembly/flash/hypnotic, // 7 TC + /obj/item/storage/pill_bottle/lsd, // ~1 TC + /obj/item/pen/sleepy, // 4 TC + /obj/item/gun/ballistic/revolver/nagant, // 13 TC comparable to 357. revolvers + /obj/item/megaphone, + /obj/item/bedsheet/rev, + /obj/item/clothing/suit/armor/vest/russian_coat, + /obj/item/clothing/head/helmet/rus_ushanka, + /obj/item/storage/box/syndie_kit/poster_box, + ) + +/obj/item/storage/box/syndicate/bundle_b/PopulateContents(datum/storage_config/config) + config.compute_max_values() + + switch (pick_weight(list( + KIT_JAMES_BOND = 2, + KIT_NINJA = 1, + KIT_DARK_LORD = 1, + KIT_WHITE_WHALE_HOLY_GRAIL = 2, + KIT_MAD_SCIENTIST = 2, + KIT_BEES = 1, + KIT_MR_FREEZE = 2, + KIT_DEAD_MONEY = 2, + KIT_TRAITOR_2006 = 1, + KIT_SAM_FISHER = 1, + KIT_PROP_HUNT = 1 + ))) + if(KIT_JAMES_BOND) + return list( + /obj/item/gun/ballistic/automatic/pistol, // 7 tc + /obj/item/suppressor, // 3 tc + /obj/item/ammo_box/magazine/m9mm, // 1 tc + /obj/item/ammo_box/magazine/m9mm, + /obj/item/card/id/advanced/chameleon, // 2 tc + /obj/item/clothing/under/chameleon, // 1 tc + /obj/item/reagent_containers/hypospray/medipen/stimulants, // 5 tc + /obj/item/reagent_containers/cup/rag, + /obj/item/implanter/freedom, // 5 tc + /obj/item/flashlight/emp, // 2 tc + /obj/item/grenade/c4/x4, // 1ish tc + /obj/item/reagent_containers/applicator/pill/cyanide, + /obj/item/toy/cards/deck/syndicate, // 1 tc, for poker + ) + + if(KIT_NINJA) + . = list( + /obj/item/katana, // Unique , hard to tell how much tc this is worth. 8 tc? + /obj/item/reagent_containers/hypospray/medipen/stimulants, // 5 tc + /obj/item/storage/belt/chameleon, // worth some fraction of a tc + /obj/item/chameleon, // 7 tc + /obj/item/card/id/advanced/chameleon, // 2 tc + /obj/item/card/emag/doorjack, // 3 tc + /obj/item/book/granter/action/spell/smoke, // ninja smoke bomb. 1 tc + /obj/item/clothing/shoes/bhop, // mining item, lets you jump at people, at least 2 tc + ) + + for(var/i in 1 to 6) + . += /obj/item/throwing_star // 1 tc + + if(KIT_DARK_LORD) + return list( + /obj/item/dualsaber/red, // 16 tc + /obj/item/dnainjector/telemut/darkbundle, // ~ 4 tc for tk + /obj/item/clothing/suit/hooded/chaplain_hoodie, + /obj/item/card/id/advanced/chameleon, // 2 tc + /obj/item/clothing/shoes/chameleon/noslip, //2 tc ,because slipping while being a dark lord sucks + /obj/item/book/granter/action/spell/summonitem, // ~2 tc + /obj/item/book/granter/action/spell/lightningbolt, // 4 tc + ) + + if(KIT_WHITE_WHALE_HOLY_GRAIL) //Unique items that don't appear anywhere else + return list( + /obj/item/gun/ballistic/rifle/boltaction/harpoon, + /obj/item/storage/bag/harpoon_quiver, + /obj/item/clothing/suit/hooded/carp_costume/spaceproof, + /obj/item/clothing/mask/gas/carp, + /obj/item/grenade/spawnergrenade/spesscarp, + /obj/item/toy/plush/carpplushie/dehy_carp, // 1 tc, for use as a personal mount + ) + + if(KIT_MAD_SCIENTIST) + for(var/_ in 1 to 2) + new /obj/item/grenade/clusterbuster/random(src) // 10 tc? + + . = list( + /obj/item/clothing/suit/toggle/labcoat/mad, // 0 tc + /obj/item/clothing/shoes/jackboots, // 0 tc + /obj/item/megaphone, // 0 tc + /obj/item/grenade/chem_grenade/bioterrorfoam, // 5 tc + /obj/item/assembly/signaler, // 0 tc + /obj/item/assembly/signaler, // 0 tc + /obj/item/assembly/signaler, // 0 tc + /obj/item/assembly/signaler, // 0 tc + /obj/item/storage/toolbox/syndicate, // 1 tc + /obj/item/pen/edagger, // 2 tc + /obj/item/gun/energy/wormhole_projector/core_inserted, // 5 tc easily + ) + + for(var/obj/item/grenade/insert as anything in src) + insert.moveToNullspace() + . += insert + + if(KIT_BEES) + return list( + /obj/item/paper/fluff/bee_objectives, // 0 tc (motivation) + /obj/item/clothing/suit/hooded/bee_costume, // 0 tc + /obj/item/clothing/mask/animal/small/bee, // 0 tc + /obj/item/storage/belt/fannypack/yellow, // 0 tc + /obj/item/grenade/spawnergrenade/buzzkill, // these are the random super bees this is definitely all of the tc budget for this one + /obj/item/grenade/spawnergrenade/buzzkill, // 10 tc per grenade + /obj/item/reagent_containers/cup/bottle/beesease, // 10 tc? + /obj/item/melee/beesword, //priceless + ) + + if(KIT_MR_FREEZE) + return list( + /obj/item/clothing/glasses/cold, + /obj/item/clothing/gloves/color/black/security/blu, + /obj/item/clothing/mask/chameleon, + /obj/item/clothing/suit/hooded/wintercoat, + /obj/item/clothing/shoes/winterboots, + /obj/item/grenade/gluon, // whole belt is 22 and gluon is weight 4 so lets just go with like 7 total + /obj/item/grenade/gluon, + /obj/item/grenade/gluon, + /obj/item/grenade/gluon, + /obj/item/dnainjector/geladikinesis, // both abilities are probably 3 tc total + /obj/item/dnainjector/cryokinesis, + /obj/item/gun/energy/temperature/freeze, // ~6 tc + /obj/item/gun/energy/laser/thermal/cryo, // ~6 tc + /obj/item/melee/energy/sword/saber/blue, //see see it + ) + + if(KIT_TRAITOR_2006) //A kit so old, it's probably older than you. //This bundle is filled with the entire uplink contents traitors had access to in 2006, from OpenSS13. Notably the esword was not a choice but existed in code. + return /obj/item/storage/toolbox/emergency/old/ancientbundle //Items fit neatly into a classic toolbox just to remind you what the theme is. + + if(KIT_DEAD_MONEY) + . = list( + /obj/item/storage/box/syndie_kit/signaler, + /obj/item/mod/control/pre_equipped/responsory/inquisitory/syndie, // basically a snowflake yet better elite modsuit, so like, 8 + 5 tc. + /obj/item/card/id/advanced/chameleon, // 2 tc + /obj/item/clothing/mask/chameleon, + /obj/item/melee/baton/telescopic/contractor_baton, // 7 tc + /obj/item/jammer, // 5 tc + /obj/item/pinpointer/crew, //priceless + ) + + for(var/i in 1 to 4) + . += /obj/item/clothing/neck/collar_bomb // These let you remotely kill people with a signaler, though you have to get them first. + + if(KIT_SAM_FISHER) + return list( + /obj/item/clothing/under/syndicate/combat, + /obj/item/clothing/suit/armor/vest/marine/pmc, //The armor kit is comparable to the infiltrator, 6 TC + /obj/item/clothing/head/helmet/marine/pmc, + /obj/item/clothing/mask/gas/sechailer, + /obj/item/clothing/glasses/night/colorless, // 3~ TC + /obj/item/clothing/gloves/krav_maga/combatglovesplus, //5TC + /obj/item/clothing/shoes/jackboots, + /obj/item/storage/belt/military/assault/fisher, //items in this belt easily costs 18 TC + ) + + if(KIT_PROP_HUNT) + return list( + /obj/item/chameleon, // 7 TC + /obj/item/card/emag/doorjack, // 3 TC + /obj/item/storage/box/syndie_kit/imp_stealth, //8 TC + /obj/item/gun/ballistic/automatic/pistol, // 7 TC + /obj/item/clothing/glasses/thermal, // 4 TC + ) + +/obj/item/storage/box/syndie_kit + name = "box" + desc = "A sleek, sturdy box." + icon_state = "syndiebox" + illustration = "writing_syndie" + storage_type = /datum/storage/box/syndie_kit + +/obj/item/storage/box/syndie_kit/rebarxbowsyndie + name = "Boxed Rebar Crossbow" + desc = "A scoped weapon with low armor penetration, but devastating against flesh. Features instruction manual for making specialty ammo." + storage_type = /datum/storage/box/syndie_kit/rebarxbowsyndie + +/obj/item/storage/box/syndie_kit/rebarxbowsyndie/PopulateContents() + return list( + /obj/item/book/granter/crafting_recipe/dusting/rebarxbowsyndie_ammo, + /obj/item/gun/ballistic/rifle/rebarxbow/syndie, + /obj/item/storage/bag/rebar_quiver/syndicate, + ) + +/obj/item/paper/syndicate_forensics_spoofer + name = "Forensics Spoofer Guide" + default_raw_text = {" + Forensics Spoofer Info:
+ The spoofer has two modes: SCAN which scans for fingerprints and fibers, and APPLY which applies the currently chosen fingerprint/fiber to your target.
+ The spoofer can only store 5 fingerprints and 5 fibers, and may not store or report fibers/prints already stored. Additionally, it taps into the stations network to associate scanned fingerprints with names.
+ The spoofer will make the same sounds and sights as a forensics scanner, when silent mode is off.
+ "} + +/obj/item/storage/box/syndie_kit/forensics_spoofer + name = "forensics spoofing kit" + +/obj/item/storage/box/syndie_kit/forensics_spoofer/PopulateContents() + return list( + /obj/item/forensics_spoofer, + /obj/item/paper/syndicate_forensics_spoofer, + ) + +/obj/item/storage/box/syndie_kit/origami_bundle + name = "origami kit" + desc = "A box full of a number of rather masterfully engineered paper planes and a manual on \"The Art of Origami\"." + +/obj/item/storage/box/syndie_kit/origami_bundle/PopulateContents() + . = list(/obj/item/book/granter/action/origami) + for(var/i in 1 to 5) + . += /obj/item/paper + +/obj/item/storage/box/syndie_kit/imp_freedom + name = "freedom implant box" + +/obj/item/storage/box/syndie_kit/imp_freedom/PopulateContents() + return /obj/item/implanter/freedom + +/obj/item/storage/box/syndie_kit/imp_microbomb + name = "microbomb implant box" + +/obj/item/storage/box/syndie_kit/imp_microbomb/PopulateContents() + return /obj/item/implanter/explosive + +/obj/item/storage/box/syndie_kit/imp_macrobomb + name = "macrobomb implant box" + +/obj/item/storage/box/syndie_kit/imp_macrobomb/PopulateContents() + return /obj/item/implanter/explosive_macro + +/obj/item/storage/box/syndie_kit/imp_deniability + name = "tactical deniability implant box" + +/obj/item/storage/box/syndie_kit/imp_deniability/PopulateContents() + return /obj/item/implanter/tactical_deniability + +/obj/item/storage/box/syndie_kit/imp_uplink + name = "uplink implant box" + +/obj/item/storage/box/syndie_kit/imp_uplink/PopulateContents() + return /obj/item/implanter/uplink + +/obj/item/storage/box/syndie_kit/bioterror + name = "bioterror syringe box" + +/obj/item/storage/box/syndie_kit/bioterror/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/reagent_containers/syringe/bioterror + +/obj/item/storage/box/syndie_kit/clownpins + name = "ultra hilarious firing pin box" + +/obj/item/storage/box/syndie_kit/clownpins/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/firing_pin/clown/ultra + +/obj/item/storage/box/syndie_kit/imp_storage + name = "storage implant box" + +/obj/item/storage/box/syndie_kit/imp_storage/PopulateContents() + return /obj/item/implanter/storage + +/obj/item/storage/box/syndie_kit/imp_stealth + name = "stealth implant box" + +/obj/item/storage/box/syndie_kit/imp_stealth/PopulateContents() + return /obj/item/implanter/stealth + +/obj/item/storage/box/syndie_kit/imp_radio + name = "syndicate radio implant box" + +/obj/item/storage/box/syndie_kit/imp_radio/PopulateContents() + return /obj/item/implanter/radio/syndicate + +/obj/item/storage/box/syndie_kit/space + name = "boxed space suit and helmet" + storage_type = /datum/storage/box/syndie_kit/space + +/obj/item/storage/box/syndie_kit/space/PopulateContents() + var/obj/item/clothing/suit/space/syndicate/spess_suit = pick(GLOB.syndicate_space_suits_to_helmets) + + return list( + spess_suit, // Above allows me to get the helmet from a variable on the object + GLOB.syndicate_space_suits_to_helmets[spess_suit], // 4 TC for the space gear + ) + +/obj/item/storage/box/syndie_kit/emp + name = "EMP kit" + +/obj/item/storage/box/syndie_kit/emp/PopulateContents() + . = list() + + for(var/i in 1 to 5) + . += /obj/item/grenade/empgrenade + . += /obj/item/implanter/emp + +/obj/item/storage/box/syndie_kit/smoke + name = "smoke kit" + +/obj/item/storage/box/syndie_kit/smoke/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/grenade/smokebomb + +/obj/item/storage/box/syndie_kit/mail_counterfeit + name = "mail counterfeit kit" + desc = "A GLA Postal Service branded box. It's emblazoned with the motto: *Nothing stops the mail*." + storage_type = /datum/storage/box/syndie_kit/mail_counterfeit + +/obj/item/storage/box/syndie_kit/mail_counterfeit/PopulateContents() + . = list() + for(var/i in 1 to 6) + . += /obj/item/storage/mail_counterfeit_device + +/obj/item/storage/box/syndie_kit/chemical + name = "chemical kit" + storage_type = /datum/storage/box/syndie_kit/chemical + +/obj/item/storage/box/syndie_kit/chemical/PopulateContents() + return list( + /obj/item/reagent_containers/cup/bottle/polonium, + /obj/item/reagent_containers/cup/bottle/venom, + /obj/item/reagent_containers/cup/bottle/fentanyl, + /obj/item/reagent_containers/cup/bottle/formaldehyde, + /obj/item/reagent_containers/cup/bottle/spewium, + /obj/item/reagent_containers/cup/bottle/syndol, + /obj/item/reagent_containers/cup/bottle/cyanide, + /obj/item/reagent_containers/cup/bottle/histamine, + /obj/item/reagent_containers/cup/bottle/initropidril, + /obj/item/reagent_containers/cup/bottle/pancuronium, + /obj/item/reagent_containers/cup/bottle/sodium_thiopental, + /obj/item/reagent_containers/cup/bottle/coniine, + /obj/item/reagent_containers/cup/bottle/curare, + /obj/item/reagent_containers/cup/bottle/amanitin, + /obj/item/reagent_containers/syringe, + ) + +/obj/item/storage/box/syndie_kit/nuke + name = "nuke core extraction kit" + desc = "A box containing the equipment and instructions for extracting the plutonium cores of most Nanotrasen nuclear explosives." + +/obj/item/storage/box/syndie_kit/nuke/PopulateContents() + return list( + /obj/item/screwdriver/nuke, + /obj/item/nuke_core_container, + /obj/item/paper/guides/antag/nuke_instructions, + ) +/obj/item/storage/box/syndie_kit/supermatter + name = "supermatter sliver extraction kit" + desc = "A box containing the equipment and instructions for extracting a sliver of supermatter." + +/obj/item/storage/box/syndie_kit/supermatter/PopulateContents() + return list( + /obj/item/scalpel/supermatter, + /obj/item/hemostat/supermatter, + /obj/item/nuke_core_container/supermatter, + /obj/item/paper/guides/antag/supermatter_sliver, + ) + +/obj/item/storage/box/syndie_kit/tuberculosisgrenade + name = "virus grenade kit" + storage_type = /datum/storage/box/syndie_kit/tuberculosisgrenade + +/obj/item/storage/box/syndie_kit/tuberculosisgrenade/PopulateContents() + . = list(/obj/item/grenade/chem_grenade/tuberculosis) + + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/hypospray/medipen/tuberculosiscure + . += /obj/item/reagent_containers/syringe + . += /obj/item/reagent_containers/cup/bottle/tuberculosiscure + +/obj/item/storage/box/syndie_kit/chameleon + name = "chameleon kit" + storage_type = /datum/storage/box/syndie_kit/chaemelon + +/obj/item/storage/box/syndie_kit/chameleon/PopulateContents() + return list( + /obj/item/clothing/under/chameleon, + /obj/item/clothing/suit/chameleon, + /obj/item/clothing/gloves/chameleon, + /obj/item/clothing/shoes/chameleon, + /obj/item/clothing/glasses/chameleon, + /obj/item/clothing/head/chameleon, + /obj/item/clothing/mask/chameleon, + /obj/item/clothing/neck/chameleon, + /obj/item/storage/backpack/chameleon, + /obj/item/storage/belt/chameleon, + /obj/item/radio/headset/chameleon, + /obj/item/stamp/chameleon, + /obj/item/modular_computer/pda/chameleon, + /obj/item/gun/energy/laser/chameleon, + /obj/item/chameleon_scanner, + ) + +/obj/item/storage/box/syndie_kit/throwing_weapons + storage_type = /datum/storage/box/syndie_kit/weapons + +//5*(2*4) = 5*8 = 45, 45 damage if you hit one person with all 5 stars. +//Not counting the damage it will do while embedded (2*4 = 8, at 15% chance) +/obj/item/storage/box/syndie_kit/throwing_weapons/PopulateContents() + return flatten_quantified_list(list( + /obj/item/throwing_star = 5, + /obj/item/paperplane/syndicate = 2, + /obj/item/restraints/legcuffs/bola/tactical = 2, + )) + +/obj/item/storage/box/syndie_kit/cutouts + storage_type = /datum/storage/box/syndie_kit/cutouts + +/obj/item/storage/box/syndie_kit/cutouts/PopulateContents() + . = list() + + for(var/i in 1 to 3) + . += /obj/item/cardboard_cutout/adaptive + . += /obj/item/toy/crayon/rainbow + +/obj/item/storage/box/syndie_kit/romerol/PopulateContents() + return list( + /obj/item/reagent_containers/cup/bottle/romerol, + /obj/item/reagent_containers/syringe, + /obj/item/reagent_containers/dropper, + ) + +/obj/item/storage/box/syndie_kit/ez_clean/PopulateContents() + . = list() + for(var/i in 1 to 3) + . += /obj/item/grenade/chem_grenade/ez_clean + +/obj/item/storage/box/syndie_kit/mulligan/PopulateContents() + return list( + /obj/item/reagent_containers/syringe/mulligan, + /obj/item/fake_identity_kit + ) + +/obj/item/storage/box/hug/reverse_revolver/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + config.compute_max_total_weight = TRUE + + return /obj/item/gun/ballistic/revolver/reverse + +/obj/item/storage/box/syndie_kit/mimery/PopulateContents() + return list( + /obj/item/book/granter/action/spell/mime/mimery_blockade, + /obj/item/book/granter/action/spell/mime/mimery_guns, + ) + +/obj/item/storage/box/syndie_kit/moltobeso/PopulateContents() + return list( + /obj/item/reagent_containers/cup/bottle/moltobeso, + /obj/item/reagent_containers/syringe, + /obj/item/reagent_containers/dropper, + ) + +/obj/item/storage/box/syndie_kit/combat_baking/PopulateContents() + . = list(/obj/item/food/baguette/combat,) + + for(var/i in 1 to 2) + . += /obj/item/food/croissant/throwing + . += /obj/item/book/granter/crafting_recipe/combat_baking + +/obj/item/storage/box/syndie_kit/centcom_costume + storage_type = /datum/storage/box/syndie_kit/centcom_costume + +/obj/item/storage/box/syndie_kit/centcom_costume/PopulateContents() + return list( + /obj/item/clothing/under/rank/centcom/officer, + /obj/item/clothing/shoes/sneakers/black, + /obj/item/clothing/gloves/color/black, + /obj/item/radio/headset/headset_cent/empty, + /obj/item/clothing/glasses/sunglasses, + /obj/item/storage/backpack/satchel, + /obj/item/modular_computer/pda/heads, + /obj/item/clipboard, + ) + +/obj/item/storage/box/syndie_kit/chameleon/broken/PopulateContents() + return list( + /obj/item/clothing/under/chameleon/broken, + /obj/item/clothing/suit/chameleon/broken, + /obj/item/clothing/gloves/chameleon/broken, + /obj/item/clothing/shoes/chameleon/noslip/broken, + /obj/item/clothing/glasses/chameleon/broken, + /obj/item/clothing/head/chameleon/broken, + /obj/item/clothing/mask/chameleon/broken, + /obj/item/clothing/neck/chameleon/broken, + /obj/item/storage/backpack/chameleon/broken, + /obj/item/storage/belt/chameleon/broken, + /obj/item/radio/headset/chameleon/broken, + /obj/item/stamp/chameleon/broken, + /obj/item/modular_computer/pda/chameleon/broken, + ) + // No chameleon laser, they can't randomise for //REASONS// + +/obj/item/storage/box/syndie_kit/bee_grenades + name = "buzzkill grenade box" + desc = "A sleek, sturdy box with a buzzing noise coming from the inside. Uh oh." + +/obj/item/storage/box/syndie_kit/bee_grenades/PopulateContents() + . = list() + for(var/i in 1 to 3) + . += /obj/item/grenade/spawnergrenade/buzzkill + +/obj/item/storage/box/syndie_kit/manhack_grenades/PopulateContents() + . = list() + for(var/i in 1 to 3) + . += /obj/item/grenade/spawnergrenade/manhacks + +/obj/item/storage/box/syndie_kit/sleepytime/PopulateContents() + return list( + /obj/item/clothing/under/syndicate/bloodred/sleepytime, + /obj/item/reagent_containers/cup/glass/mug/coco, + /obj/item/toy/plush/carpplushie, + /obj/item/bedsheet/syndie, + ) + +/obj/item/storage/box/syndie_kit/demoman + storage_type = /datum/storage/box/syndie_kit/demoman + +/obj/item/storage/box/syndie_kit/demoman/PopulateContents(datum/storage_config/config) + + . = list( + /obj/item/gun/grenadelauncher, + /obj/item/storage/belt/grenade/full, + ) + + if(prob(1)) + . += /obj/item/clothing/head/hats/hos/shako + +/obj/item/storage/box/syndie_kit/core_gear + name = "core equipment box" + desc = "Contains all the necessary gear for success for any nuclear operative unsure of what is needed for success in the field. Everything here WILL help you." + +/obj/item/storage/box/syndie_kit/core_gear/PopulateContents() + return list( + /obj/item/implanter/freedom , + /obj/item/card/emag/doorjack , + /obj/item/reagent_containers/hypospray/medipen/stimulants , + /obj/item/grenade/c4 , + /obj/item/mod/module/energy_shield, + ) + +/// Surplus Ammo Box + +/obj/item/storage/box/syndie_kit/sniper_surplus + name = "surplus .50 BMG magazine box" + desc = "A shoddy box full of surplus .50 BMG magazines. Not as strong, but good enough to keep lead in the air." + +/obj/item/storage/box/syndie_kit/sniper_surplus/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/ammo_box/magazine/sniper_rounds/surplus + +/obj/item/storage/box/syndie_kit/shotgun_surplus + name = "\improper Donk Co. 'Donk Spike' flechette 12g Bulldog magazine box" + desc = "A shoddy box full of Donk Co. 'Donk Spike' flechette 12g. It is debatable whether or not these are actually \ + better or worse than standard flechette. Donk Co. did genuinely believe in this product being the future of military \ + ammunition production. The only reason it didn't see wider adoption was a lack of faith in the product. Do you \ + believe in Donk? Time to put that to the test." + +/obj/item/storage/box/syndie_kit/shotgun_surplus/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/ammo_box/magazine/m12g/donk + +///Subtype for the sabotage bundle. Contains three C4, two X4 and 6 signalers +/obj/item/storage/backpack/duffelbag/syndie/sabotage/PopulateContents() + return list( + /obj/item/grenade/c4, + /obj/item/grenade/c4, + /obj/item/grenade/c4, + /obj/item/grenade/c4/x4, + /obj/item/grenade/c4/x4, + /obj/item/storage/box/syndie_kit/signaler, + ) + +/obj/item/storage/box/syndie_kit/signaler + name = "signaler box" + desc = "Contains everything an agent would need to remotely detonate their bombs." + +/obj/item/storage/box/syndie_kit/signaler/PopulateContents() + . = list() + for(var/i in 1 to 6) + . += /obj/item/assembly/signaler + +/obj/item/storage/box/syndie_kit/imp_deathrattle + name = "deathrattle implant box" + desc = "Contains eight linked deathrattle implants." + storage_type = /datum/storage/box/syndie_kit/imp_deathrattle + +/obj/item/storage/box/syndie_kit/imp_deathrattle/PopulateContents() + . = list(/obj/item/implanter) + + var/datum/deathrattle_group/group = new + + var/implants = list() + for(var/j in 1 to 8) + var/obj/item/implantcase/deathrattle/case = new (null) + implants += case.imp + . += case + + for(var/i in implants) + group.register(i) + desc += " The implants are registered to the \"[group.name]\" group." + +/obj/item/storage/box/stickers/syndie_kit/PopulateContents() + var/static/list/types = subtypesof(/obj/item/sticker/syndicate) + + . = list() + for(var/i in 1 to 7) + . += pick(types) + +/obj/item/storage/box/syndie_kit/pinata + name = "weapons grade pinata kit" + desc = "Contains a weapons grade pinata and 2 belts for carrying its contents." + storage_type = /datum/storage/box/syndie_kit/pinata + +/obj/item/storage/box/syndie_kit/pinata/PopulateContents() + return list( + /obj/item/pinata/syndie, + /obj/item/storage/belt/grenade, + /obj/item/storage/belt/military/snack, + ) + +/obj/item/storage/box/syndie_kit/induction_kit + name = "syndicate induction kit" + desc = "Contains all you need for introducing your newest comrade to the Syndicate and all its worker's benefits." + storage_type = /datum/storage/box/syndie_kit/induction_kit + +/obj/item/storage/box/syndie_kit/induction_kit/PopulateContents(datum/storage_config/config) + config.compute_max_item_count = TRUE + config.compute_max_total_weight = TRUE + + var/obj/item/clothing/suit/space/syndicate/spess_suit = pick(GLOB.syndicate_space_suits_to_helmets) + return list( + // Basic weaponry, so they have something to use. + /obj/item/gun/ballistic/automatic/pistol/clandestine, // 6 TC, but free for nukies + /obj/item/ammo_box/magazine/m10mm/hp, // 3 TC, a reward for the teamwork involved + /obj/item/ammo_box/magazine/m10mm/ap, // 3 TC, a reward for the teamwork involved + + // The necessary equipment to help secure that disky. + /obj/item/radio/headset/syndicate/alt, // 5 TC / Free for nukies + /obj/item/modular_computer/pda/nukeops, // ?? TC / Free for nukies + /obj/item/card/id/advanced/chameleon, // 2 TC / Free for nukies + spess_suit, // 4 TC for the space gear + GLOB.syndicate_space_suits_to_helmets[spess_suit], + /obj/item/tank/jetpack/oxygen/harness, // They kinda need this to fly to the cruiser. + + // Tacticool gear + /obj/item/clothing/shoes/combat, + /obj/item/clothing/under/syndicate, + /obj/item/clothing/gloves/fingerless, + /obj/item/book/manual/nuclear, // Very important + + // The most important part of the kit, the implant that gives them the syndicate faction. + /obj/item/implanter/induction_implant, + ) + + // All in all, 6+3+3+2+5+2+4 = ~25 TC of 'miscellaneous' items. + // This is a lot of value for 10 TC, but you have to keep in mind that you NEED someone to get this stuff station-side. + // Pretty much all of it is a bad deal for reinforcements or yourself as they already have similar or good-enough alternatives. + +/obj/item/implanter/induction_implant + name = "implanter (nuclear operative)" + desc = "A sterile automatic implant injector. You can see a tiny, somehow legible sticker on the side: 'NOT A BRAINWASH DEVICE'" + imp_type = /obj/item/implant/nuclear_operative + +/obj/item/implant/nuclear_operative + name = "nuclear operative implant" + desc = "Registers you as a member of a Syndicate nuclear operative team." + implant_color = "r" + +/obj/item/implant/nuclear_operative/get_data() + return "Implant Specifications:
\ + Name: Suspicious Implant
\ + Life: UNKNOWN
\ + Implant Details:
\ + Function: Strange implant that seems to resist any attempts at scanning it." + +/obj/item/implant/nuclear_operative/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE) + . = ..() + if(!. || !ishuman(target) || !(target.mind)) + return FALSE + var/mob/living/carbon/human/human_target = target + + if(IS_NUKE_OP(human_target)) // this wont proc due to ..() but i guess its good as a just-in-case? + if(human_target == user) + to_chat(user, span_userdanger("You're already a nuclear operative, dumbass! The implant disintegrates within you! You feel sick...")) + human_target.Stun(10 SECONDS) + human_target.reagents.add_reagent(/datum/reagent/toxin, 10) + return FALSE + else + to_chat(user, span_notice("You finish implanting [human_target], but you don't really notice a difference. Huh.")) + to_chat(human_target, span_userdanger("Nothing seems to really happen, but you start to feel a little ill..")) + human_target.reagents.add_reagent(/datum/reagent/toxin, 2) + return FALSE + + /// If all the antag datums are 'fake' or none exist, disallow induction! No self-antagging. + var/faker + for(var/datum/antagonist/antag_datum as anything in human_target.mind.antag_datums) + if((antag_datum.antag_flags & FLAG_FAKE_ANTAG)) + faker = TRUE + + if(faker || isnull(human_target.mind.antag_datums)) // GTFO. Technically not foolproof but making a heartbreaker or a paradox clone a nuke op sounds hilarious + to_chat(human_target, span_notice("Huh? Nothing happened? But you're starting to feel a little ill...")) + human_target.reagents.add_reagent(/datum/reagent/toxin, 15) + return FALSE + + var/datum/antagonist/nukeop/nuke_datum = new() + nuke_datum.send_to_spawnpoint = FALSE + nuke_datum.nukeop_outfit = null + human_target.mind?.add_antag_datum(nuke_datum) + human_target.faction |= ROLE_SYNDICATE + to_chat(human_target, span_warning("You are now a nuclear operative. Your main objective, if you were an antagonist and willing, is presumably to assist the nuclear operative team and secure the disk.")) + to_chat(human_target, span_userdanger("This implant does NOT, in any way, brainwash you. If you were a normal crew member beforehand, forcibly implanted or otherwise, you are still one and cannot assist the nuclear operatives.")) + return TRUE + +/obj/item/implant/nuclear_operative/removed(mob/target, silent = FALSE, special = FALSE) + . = ..() + if(!. || !isliving(target)) + return FALSE + var/mob/living/living_target = target + living_target.mind.remove_antag_datum(/datum/antagonist/nukeop) + living_target.faction -= ROLE_SYNDICATE + to_chat(target, span_notice("You feel a little less nuclear.")) + to_chat(target, span_userdanger("You're no longer identified as a nuclear operative! You are free to follow any valid goals you wish, even continuing to secure the disk. Just make sure neither any turrets nor operatives kill you on sight.")) + return TRUE + +/obj/item/storage/box/syndie_kit/poster_box + name = "syndicate poster pack" + desc = "Contains a variety of demotivational posters to ensure minimum productivity for the crew of any Nanotrasen station." + +/obj/item/storage/box/syndie_kit/poster_box/PopulateContents() + . = list() + for(var/i in 1 to 3) + . += /obj/item/poster/traitor + +/obj/item/storage/box/syndie_kit/cowboy + name = "western outlaw pack" + desc = "Contains everything you'll need to be the rootin' tootin' cowboy you always wanted. Either play the Lone Ranger or go in with your posse of outlaws." + storage_type = /datum/storage/box/syndie_kit/cowboy + +/obj/item/storage/box/syndie_kit/cowboy/PopulateContents() + //Can spawn with snakes which runtime in null space so we do this + var/obj/item/clothing/shoes/cowboy/black/syndicate/shoes = new(src) + shoes.moveToNullspace() + + return list( + shoes, + /obj/item/clothing/head/cowboy/black/syndicate, + /obj/item/storage/belt/holster/nukie/cowboy/full, + /obj/item/clothing/under/costume/dutch/syndicate, + /obj/item/lighter/skull, + /obj/item/sbeacondrop/horse, + /obj/item/food/grown/apple, + ) + +/obj/item/storage/box/syndicate/contract_kit + name = "Contract Kit" + desc = "Supplied to Syndicate contractors." + icon_state = "syndiebox" + illustration = "writing_syndie" + storage_type = /datum/storage/box/syndicate/contract_kit + +/obj/item/storage/box/syndicate/contract_kit/PopulateContents() + return list( + /obj/item/modular_computer/pda/syndicate_contract_uplink, + /obj/item/storage/box/syndicate/contractor_loadout, + /obj/item/melee/baton/telescopic/contractor_baton, + // Paper guide is always last. + /obj/item/paper/contractor_guide, + ) + +/obj/item/storage/box/syndicate/contractor_loadout + name = "Standard Loadout" + desc = "Supplied to Syndicate contractors, providing their specialised space suit and chameleon uniform." + icon_state = "syndiebox" + illustration = "writing_syndie" + storage_type = /datum/storage/box/syndicate/contractor_loadout + +/obj/item/storage/box/syndicate/contractor_loadout/PopulateContents() + + return list( + /obj/item/mod/control/pre_equipped/infiltrator, + /obj/item/clothing/head/helmet/space/syndicate/contract, + /obj/item/clothing/suit/space/syndicate/contract, + /obj/item/clothing/under/chameleon, + /obj/item/clothing/mask/chameleon, + /obj/item/card/id/advanced/chameleon, + /obj/item/clothing/glasses/thermal/syndi, + /obj/item/storage/toolbox/syndicate, + /obj/item/jammer, + /obj/item/storage/fancy/cigarettes/cigpack_syndicate, + /obj/item/lighter, + ) + +#undef KIT_RECON +#undef KIT_BLOODY_SPAI +#undef KIT_STEALTHY +#undef KIT_SCREWED +#undef KIT_SABOTAGE +#undef KIT_GUN +#undef KIT_MURDER +#undef KIT_IMPLANTS +#undef KIT_HACKER +#undef KIT_SNIPER +#undef KIT_NUKEOPS_METAGAME +#undef KIT_LORD_SINGULOTH +#undef KIT_REVOLUTIONARY + +#undef KIT_JAMES_BOND +#undef KIT_NINJA +#undef KIT_DARK_LORD +#undef KIT_WHITE_WHALE_HOLY_GRAIL +#undef KIT_MAD_SCIENTIST +#undef KIT_BEES +#undef KIT_MR_FREEZE +#undef KIT_TRAITOR_2006 +#undef KIT_DEAD_MONEY +#undef KIT_SAM_FISHER +#undef KIT_PROP_HUNT diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index a0b6e892e05..787eae7cc13 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -16,25 +16,25 @@ attack_verb_simple = list("bash", "batter", "bludgeon", "thrash", "whack") resistance_flags = FLAMMABLE max_integrity = 150 - var/folder_path = /obj/item/folder //this is the path of the folder that gets spawned in New() + storage_type = /datum/storage/briefcase -/obj/item/storage/briefcase/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 21 + ///this is the path of the folder that gets spawned in New() + var/folder_path = /obj/item/folder /obj/item/storage/briefcase/PopulateContents() - new /obj/item/pen(src) - var/obj/item/folder/folder = new folder_path(src) + . = list(/obj/item/pen) + + var/obj/item/folder/folder = new folder_path(null) for(var/i in 1 to 6) new /obj/item/paper(folder) + . += folder /obj/item/storage/briefcase/lawyer folder_path = /obj/item/folder/blue /obj/item/storage/briefcase/lawyer/PopulateContents() - new /obj/item/stamp/law(src) - ..() + . = ..() + . += /obj/item/stamp/law /obj/item/storage/briefcase/suicide_act(mob/living/user) var/list/papers_found = list() @@ -63,15 +63,16 @@ /obj/item/storage/briefcase/sniper desc = "Its label reads \"genuine hardened Captain leather\", but suspiciously has no other tags or branding. Smells like L'Air du Temps." force = 10 + storage_type = /datum/storage/briefcase/sniper /obj/item/storage/briefcase/sniper/PopulateContents() - ..() // in case you need any paperwork done after your rampage - new /obj/item/gun/ballistic/rifle/sniper_rifle/syndicate(src) - new /obj/item/clothing/neck/tie/red/hitman(src) - new /obj/item/clothing/under/syndicate/sniper(src) - new /obj/item/ammo_box/magazine/sniper_rounds(src) - new /obj/item/ammo_box/magazine/sniper_rounds(src) - new /obj/item/ammo_box/magazine/sniper_rounds/disruptor(src) + . = ..() // in case you need any paperwork done after your rampage + . += /obj/item/gun/ballistic/rifle/sniper_rifle/syndicate + . += /obj/item/clothing/neck/tie/red/hitman + . += /obj/item/clothing/under/syndicate/sniper + . += /obj/item/ammo_box/magazine/sniper_rounds + . += /obj/item/ammo_box/magazine/sniper_rounds + . += /obj/item/ammo_box/magazine/sniper_rounds/disruptor /** * Secure briefcase @@ -86,8 +87,7 @@ /obj/item/storage/briefcase/secure/Initialize(mapload) . = ..() - atom_storage.max_total_storage = 21 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL + AddComponent(/datum/component/lockable_storage) ///Syndie variant of Secure Briefcase. Contains space cash, slightly more robust. @@ -96,26 +96,28 @@ /obj/item/storage/briefcase/secure/syndie/PopulateContents() . = ..() - for(var/iterator in 1 to 5) - new /obj/item/stack/spacecash/c1000(src) + for(var/_ in 1 to 5) + . += /obj/item/stack/spacecash/c1000 /// A briefcase that contains various sought-after spoils -/obj/item/storage/briefcase/secure/riches - /obj/item/storage/briefcase/secure/riches/PopulateContents() - new /obj/item/clothing/suit/armor/vest(src) - new /obj/item/gun/ballistic/automatic/pistol(src) - new /obj/item/suppressor(src) - new /obj/item/melee/baton/telescopic(src) - new /obj/item/clothing/mask/balaclava(src) - new /obj/item/bodybag(src) - new /obj/item/soap/nanotrasen(src) + return list( + /obj/item/clothing/suit/armor/vest, + /obj/item/gun/ballistic/automatic/pistol, + /obj/item/suppressor, + /obj/item/melee/baton/telescopic, + /obj/item/clothing/mask/balaclava, + /obj/item/bodybag, + /obj/item/soap/nanotrasen, + ) /obj/item/storage/briefcase/hitchiker/PopulateContents() - new /obj/item/food/sandwich/peanut_butter_jelly(src) - new /obj/item/food/sandwich/peanut_butter_jelly(src) - new /obj/item/reagent_containers/cup/glass/waterbottle/large(src) - new /obj/item/soap(src) - new /obj/item/pillow/random(src) - new /obj/item/tank/internals/emergency_oxygen(src) - new /obj/item/tank/internals/emergency_oxygen(src) + return list( + /obj/item/clothing/suit/armor/vest, + /obj/item/gun/ballistic/automatic/pistol, + /obj/item/suppressor, + /obj/item/melee/baton/telescopic, + /obj/item/clothing/mask/balaclava, + /obj/item/bodybag, + /obj/item/soap/nanotrasen, + ) diff --git a/code/game/objects/items/storage/dufflebags.dm b/code/game/objects/items/storage/dufflebags.dm new file mode 100644 index 00000000000..3304c4bbc17 --- /dev/null +++ b/code/game/objects/items/storage/dufflebags.dm @@ -0,0 +1,404 @@ +/obj/item/storage/backpack/duffelbag + name = "duffel bag" + desc = "A large duffel bag for holding extra things." + icon_state = "duffel" + inhand_icon_state = "duffel" + actions_types = list(/datum/action/item_action/zipper) + action_slots = ALL + storage_type = /datum/storage/duffel + // How much to slow you down if your bag isn't zipped up + var/zip_slowdown = 1 + /// If this bag is zipped (contents hidden) up or not + /// Starts enabled so you're forced to interact with it to "get" it + var/zipped_up = TRUE + // How much time it takes to zip up (close) the duffelbag + var/zip_up_duration = 0.5 SECONDS + // Audio played during zipup + var/zip_up_sfx = 'sound/items/zip/zip_up.ogg' + // How much time it takes to unzip the duffel + var/unzip_duration = 2.1 SECONDS + // Audio played during unzip + var/unzip_sfx = 'sound/items/zip/un_zip.ogg' + +/obj/item/storage/backpack/duffelbag/Initialize(mapload) + . = ..() + set_zipper(TRUE) + +/obj/item/storage/backpack/duffelbag/update_desc(updates) + . = ..() + desc = "[initial(desc)]
[zipped_up ? "It's zipped up, preventing you from accessing its contents." : "It's unzipped, and harder to move in."]" + +/obj/item/storage/backpack/duffelbag/attack_self(mob/user, modifiers) + if(loc != user) // God fuck TK + return ..() + if(zipped_up) + return attack_hand(user, modifiers) + else + return attack_hand_secondary(user, modifiers) + +/obj/item/storage/backpack/duffelbag/attack_self_secondary(mob/user, modifiers) + attack_self(user, modifiers) + return ..() + +// If we're zipped, click to unzip +/obj/item/storage/backpack/duffelbag/attack_hand(mob/user, list/modifiers) + if(loc != user) + // Hacky, but please don't be cringe yeah? + atom_storage.silent = TRUE + . = ..() + atom_storage.silent = initial(atom_storage.silent) + return + if(!zipped_up) + return ..() + + balloon_alert(user, "unzipping...") + playsound(src, unzip_sfx, 100, FALSE) + var/datum/callback/can_unzip = CALLBACK(src, PROC_REF(zipper_matches), TRUE) + if(!do_after(user, unzip_duration, src, extra_checks = can_unzip)) + user.balloon_alert(user, "unzip failed!") + return + balloon_alert(user, "unzipped") + set_zipper(FALSE) + return TRUE + +// Vis versa +/obj/item/storage/backpack/duffelbag/attack_hand_secondary(mob/user, list/modifiers) + if(loc != user) + return ..() + if(zipped_up) + return SECONDARY_ATTACK_CALL_NORMAL + + balloon_alert(user, "zipping...") + playsound(src, zip_up_sfx, 100, FALSE) + var/datum/callback/can_zip = CALLBACK(src, PROC_REF(zipper_matches), FALSE) + if(!do_after(user, zip_up_duration, src, extra_checks = can_zip)) + user.balloon_alert(user, "zip failed!") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + balloon_alert(user, "zipped") + set_zipper(TRUE) + return SECONDARY_ATTACK_CONTINUE_CHAIN + +/// Checks to see if the zipper matches the passed in state +/// Returns true if so, false otherwise +/obj/item/storage/backpack/duffelbag/proc/zipper_matches(matching_value) + return zipped_up == matching_value + +/obj/item/storage/backpack/duffelbag/proc/set_zipper(new_zip) + zipped_up = new_zip + SEND_SIGNAL(src, COMSIG_DUFFEL_ZIP_CHANGE, new_zip) + if(zipped_up) + slowdown = initial(slowdown) + atom_storage.locked = STORAGE_SOFT_LOCKED + atom_storage.display_contents = FALSE + for(var/obj/item/weapon as anything in get_all_contents_type(/obj/item)) //close ui of this and all items inside dufflebag + weapon.atom_storage?.close_all() //not everything has storage initialized + else + slowdown = zip_slowdown + atom_storage.locked = STORAGE_NOT_LOCKED + atom_storage.display_contents = TRUE + + if(isliving(loc)) + var/mob/living/wearer = loc + wearer.update_equipment_speed_mods() + update_appearance() + +/obj/item/storage/backpack/duffelbag/cursed + name = "living duffel bag" + desc = "A cursed clown duffel bag that hungers for food of any kind. A warning label suggests that it eats food inside. \ + If that food happens to be a horribly ruined mess or the chef scrapped out of the microwave, or poisoned in some way, \ + then it might have negative effects on the bag..." + icon_state = "duffel-curse" + inhand_icon_state = "duffel-curse" + zip_slowdown = 2 + max_integrity = 100 + +/obj/item/storage/backpack/duffelbag/cursed/Initialize(mapload) + . = ..() + AddComponent(/datum/component/curse_of_hunger, add_dropdel = TRUE) + +/obj/item/storage/backpack/duffelbag/captain + name = "captain's duffel bag" + desc = "A large duffel bag for holding extra captainly goods." + icon_state = "duffel-captain" + inhand_icon_state = "duffel-captain" + +/obj/item/storage/backpack/duffelbag/med + name = "medical duffel bag" + desc = "A large duffel bag for holding extra medical supplies." + icon_state = "duffel-medical" + inhand_icon_state = "duffel-med" + +/obj/item/storage/backpack/duffelbag/coroner + name = "coroner duffel bag" + desc = "A large duffel bag for holding large amounts of organs at once." + icon_state = "duffel-coroner" + inhand_icon_state = "duffel-coroner" + +/obj/item/storage/backpack/duffelbag/explorer + name = "explorer duffel bag" + desc = "A large duffel bag for holding extra exotic treasures." + icon_state = "duffel-explorer" + inhand_icon_state = "duffel-explorer" + +/obj/item/storage/backpack/duffelbag/hydroponics + name = "hydroponic's duffel bag" + desc = "A large duffel bag for holding extra gardening tools." + icon_state = "duffel-hydroponics" + inhand_icon_state = "duffel-hydroponics" + +/obj/item/storage/backpack/duffelbag/chemistry + name = "chemistry duffel bag" + desc = "A large duffel bag for holding extra chemical substances." + icon_state = "duffel-chemistry" + inhand_icon_state = "duffel-chemistry" + +/obj/item/storage/backpack/duffelbag/genetics + name = "geneticist's duffel bag" + desc = "A large duffel bag for holding extra genetic mutations." + icon_state = "duffel-genetics" + inhand_icon_state = "duffel-genetics" + +/obj/item/storage/backpack/duffelbag/science + name = "scientist's duffel bag" + desc = "A large duffel bag for holding extra scientific components." + icon_state = "duffel-science" + inhand_icon_state = "duffel-sci" + +/obj/item/storage/backpack/duffelbag/virology + name = "virologist's duffel bag" + desc = "A large duffel bag for holding extra viral bottles." + icon_state = "duffel-virology" + inhand_icon_state = "duffel-virology" + +/obj/item/storage/backpack/duffelbag/sec + name = "security duffel bag" + desc = "A large duffel bag for holding extra security supplies and ammunition." + icon_state = "duffel-security" + inhand_icon_state = "duffel-sec" + +/obj/item/storage/backpack/duffelbag/sec/surgery + name = "surgical duffel bag" + desc = "A large duffel bag for holding extra supplies - this one has a material inlay with space for various sharp-looking tools." + +/obj/item/storage/backpack/duffelbag/sec/surgery/PopulateContents() + return list( + /obj/item/scalpel, + /obj/item/hemostat, + /obj/item/retractor, + /obj/item/circular_saw, + /obj/item/bonesetter, + /obj/item/surgicaldrill, + /obj/item/cautery, + /obj/item/surgical_drapes, + /obj/item/clothing/mask/surgical, + /obj/item/blood_filter, + ) + +/obj/item/storage/backpack/duffelbag/engineering + name = "industrial duffel bag" + desc = "A large duffel bag for holding extra tools and supplies." + icon_state = "duffel-engineering" + inhand_icon_state = "duffel-eng" + resistance_flags = FIRE_PROOF + +/obj/item/storage/backpack/duffelbag/drone + name = "drone duffel bag" + desc = "A large duffel bag for holding tools and hats." + icon_state = "duffel-drone" + inhand_icon_state = "duffel-drone" + resistance_flags = FIRE_PROOF + +/obj/item/storage/backpack/duffelbag/drone/PopulateContents() + return list( + /obj/item/screwdriver, + /obj/item/wrench, + /obj/item/weldingtool, + /obj/item/crowbar, + /obj/item/stack/cable_coil, + /obj/item/wirecutters, + /obj/item/multitool, + ) + +/obj/item/storage/backpack/duffelbag/clown + name = "clown's duffel bag" + desc = "A large duffel bag for holding lots of funny gags!" + icon_state = "duffel-clown" + inhand_icon_state = "duffel-clown" + +/obj/item/storage/backpack/duffelbag/clown/cream_pie/PopulateContents() + return list( + /obj/item/food/pie/cream, + /obj/item/food/pie/cream, + /obj/item/food/pie/cream, + /obj/item/food/pie/cream, + ) + +/obj/item/storage/backpack/fireproof + resistance_flags = FIRE_PROOF + +/obj/item/storage/backpack/duffelbag/syndie + name = "suspicious looking duffel bag" + desc = "A large duffel bag for holding extra tactical supplies. It contains an oiled plastitanium zipper for maximum speed tactical zipping, and is better balanced on your back than an average duffelbag. Can hold two bulky items!" + icon_state = "duffel-syndie" + inhand_icon_state = "duffel-syndieammo" + resistance_flags = FIRE_PROOF + // Less slowdown while unzipped. Still bulky, but it won't halve your movement speed in an active combat situation. + zip_slowdown = 0.3 + // Faster unzipping. Utilizes the same noise as zipping up to fit the unzip duration. + unzip_duration = 0.5 SECONDS + unzip_sfx = 'sound/items/zip/zip_up.ogg' + storage_type = /datum/storage/duffel/syndicate + +/obj/item/storage/backpack/duffelbag/syndie/hitman + desc = "A large duffel bag for holding extra things. There is a Nanotrasen logo on the back." + icon_state = "duffel-syndieammo" + inhand_icon_state = "duffel-syndieammo" + +/obj/item/storage/backpack/duffelbag/syndie/hitman/PopulateContents() + return list( + /obj/item/clothing/under/costume/buttondown/slacks/service, + /obj/item/clothing/neck/tie/red/hitman, + /obj/item/clothing/accessory/waistcoat, + /obj/item/clothing/suit/toggle/lawyer/black, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/gloves/color/black, + /obj/item/clothing/glasses/sunglasses, + /obj/item/clothing/head/fedora, + ) + +/obj/item/storage/backpack/duffelbag/syndie/med + name = "medical duffel bag" + desc = "A large duffel bag for holding extra tactical medical supplies." + icon_state = "duffel-syndiemed" + inhand_icon_state = "duffel-syndiemed" + +/obj/item/storage/backpack/duffelbag/syndie/surgery + name = "surgery duffel bag" + desc = "A suspicious looking duffel bag for holding surgery tools." + icon_state = "duffel-syndiemed" + inhand_icon_state = "duffel-syndiemed" + +/obj/item/storage/backpack/duffelbag/syndie/surgery/PopulateContents() + return list( + /obj/item/scalpel/advanced, + /obj/item/retractor/advanced, + /obj/item/cautery/advanced, + /obj/item/surgical_drapes, + /obj/item/reagent_containers/medigel/sterilizine, + /obj/item/bonesetter, + /obj/item/blood_filter, + /obj/item/stack/medical/bone_gel, + /obj/item/stack/sticky_tape/surgical, + /obj/item/emergency_bed, + /obj/item/clothing/suit/jacket/straight_jacket, + /obj/item/clothing/mask/muzzle, + /obj/item/mmi/syndie, + ) + +/obj/item/storage/backpack/duffelbag/syndie/ammo + name = "ammunition duffel bag" + desc = "A large duffel bag for holding extra weapons ammunition and supplies." + icon_state = "duffel-syndieammo" + inhand_icon_state = "duffel-syndieammo" + +/obj/item/storage/backpack/duffelbag/syndie/ammo/mech + desc = "A large duffel bag, packed to the brim with various exosuit ammo." + storage_type = /datum/storage/duffel/syndicate/ammo_mech + +/obj/item/storage/backpack/duffelbag/syndie/ammo/mech/PopulateContents() + return list( + /obj/item/mecha_ammo/scattershot, + /obj/item/mecha_ammo/scattershot, + /obj/item/mecha_ammo/scattershot, + /obj/item/mecha_ammo/scattershot, + /obj/item/storage/belt/utility/syndicate, + ) + +/obj/item/storage/backpack/duffelbag/syndie/ammo/mauler + desc = "A large duffel bag, packed to the brim with various exosuit ammo." + storage_type = /datum/storage/duffel/syndicate/ammo_mauler + +/obj/item/storage/backpack/duffelbag/syndie/ammo/mauler/PopulateContents() + return list( + /obj/item/mecha_ammo/lmg, + /obj/item/mecha_ammo/lmg, + /obj/item/mecha_ammo/lmg, + /obj/item/mecha_ammo/scattershot, + /obj/item/mecha_ammo/scattershot, + /obj/item/mecha_ammo/scattershot, + /obj/item/mecha_ammo/missiles_srm, + /obj/item/mecha_ammo/missiles_srm, + /obj/item/mecha_ammo/missiles_srm, + ) + +/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle + desc = "A large duffel bag containing a medical equipment, a Donksoft LMG, a big jumbo box of riot darts, and a magboot MODsuit module." + +/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle/PopulateContents() + return list( + /obj/item/mod/module/magboot, + /obj/item/storage/medkit/tactical/premium, + /obj/item/gun/ballistic/automatic/l6_saw/toy, + /obj/item/ammo_box/foambox/riot, + ) + +/obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle + desc = "A large duffel bag containing deadly chemicals, a handheld chem sprayer, Bioterror foam grenade, a Donksoft assault rifle, box of riot grade darts, a dart pistol, and a box of syringes." + +/obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle/PopulateContents() + var/list/obj/item/stuff = list( + /obj/item/reagent_containers/spray/chemsprayer/bioterror, + /obj/item/storage/box/syndie_kit/chemical, + /obj/item/gun/syringe/syndicate, + /obj/item/gun/ballistic/automatic/c20r/toy, + /obj/item/storage/box/syringes, + /obj/item/ammo_box/foambox/riot, + /obj/item/grenade/chem_grenade/bioterrorfoam, + ) + + if(prob(5)) + stuff += /obj/item/food/pizza/pineapple + + return stuff + +/obj/item/storage/backpack/duffelbag/syndie/c4/PopulateContents() + . = list() + for(var/_ in 1 to 10) + . += /obj/item/grenade/c4 + +/obj/item/storage/backpack/duffelbag/syndie/x4/PopulateContents() + . = list() + for(var/_ in 1 to 10) + . += /obj/item/grenade/c4/x4 + +/obj/item/storage/backpack/duffelbag/syndie/firestarter + desc = "A large duffel bag containing a New Russian pyro backpack sprayer, Elite MODsuit, a Stechkin APS pistol, minibomb, ammo, and other equipment." + storage_type = /datum/storage/duffel/syndicate/firestarter + +/obj/item/storage/backpack/duffelbag/syndie/firestarter/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + + return list( + /obj/item/clothing/under/syndicate/soviet, + /obj/item/mod/control/pre_equipped/elite/flamethrower, + /obj/item/gun/ballistic/automatic/pistol/aps, + /obj/item/ammo_box/magazine/m9mm_aps/fire, + /obj/item/ammo_box/magazine/m9mm_aps/fire, + /obj/item/reagent_containers/cup/glass/bottle/vodka/badminka, + /obj/item/reagent_containers/hypospray/medipen/stimulants, + /obj/item/grenade/syndieminibomb, + ) + +// For ClownOps. +/obj/item/storage/backpack/duffelbag/clown/syndie + storage_type = /datum/storage/duffel/syndicate + +/obj/item/storage/backpack/duffelbag/clown/syndie/PopulateContents() + return list( + /obj/item/modular_computer/pda/clown, + /obj/item/clothing/under/rank/civilian/clown, + /obj/item/clothing/shoes/clown_shoes, + /obj/item/clothing/mask/gas/clown_hat, + /obj/item/bikehorn, + /obj/item/implanter/sad_trombone, + ) diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index e88a0c9ee48..f14fd1fa283 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -30,17 +30,16 @@ /// Whether it supports open and closed state icons. var/has_open_closed_states = TRUE -/obj/item/storage/fancy/Initialize(mapload) - . = ..() - - atom_storage.max_slots = spawn_count - -/obj/item/storage/fancy/PopulateContents() +/obj/item/storage/fancy/PopulateContents(datum/storage_config/config) if(!spawn_type) return - for(var/i = 1 to spawn_count) - var/thing_in_box = pick(spawn_type) - new thing_in_box(src) + + config.compute_max_values() + config.whitelist_content_types = TRUE + + . = list() + for(var/i in 1 to spawn_count) + . += pick(spawn_type) /obj/item/storage/fancy/update_icon_state() icon_state = "[base_icon_state][has_open_closed_states && open_status ? contents.len : null]" @@ -104,14 +103,6 @@ custom_premium_price = PAYCHECK_COMMAND * 1.75 contents_tag = "donut" -/obj/item/storage/fancy/donut_box/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/food/donut) - -/obj/item/storage/fancy/donut_box/PopulateContents() - . = ..() - update_appearance() - /obj/item/storage/fancy/donut_box/update_icon_state() . = ..() icon_state = "[base_icon_state][open_status ? "_inner" : null]" @@ -151,10 +142,6 @@ spawn_count = 12 contents_tag = "egg" -/obj/item/storage/fancy/egg_box/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/food/egg) - /* * Fertile Egg Box */ @@ -184,10 +171,6 @@ open_status = FANCY_CONTAINER_ALWAYS_OPEN contents_tag = "candle" -/obj/item/storage/fancy/candle_box/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/flashlight/flare/candle) - //////////// //CIG PACK// //////////// @@ -207,6 +190,8 @@ custom_price = PAYCHECK_CREW age_restricted = TRUE contents_tag = "cigarette" + storage_type = /datum/storage/cigarette_box + ///for cigarette overlay var/candy = FALSE /// Does this cigarette packet come with a coupon attached? @@ -216,6 +201,12 @@ ///Do we not have our own handling for cig overlays? var/display_cigs = TRUE + +/obj/item/storage/fancy/cigarettes/Initialize(mapload) + . = ..() + + register_context() + /obj/item/storage/fancy/cigarettes/attack_self(mob/user) if(contents.len != 0 || !spawn_coupon) return ..() @@ -230,12 +221,6 @@ desc = "An old cigarette packet with the back torn off, worth less than nothing now." atom_storage.max_slots = 0 -/obj/item/storage/fancy/cigarettes/Initialize(mapload) - . = ..() - atom_storage.display_contents = FALSE - atom_storage.set_holdable(list(/obj/item/cigarette, /obj/item/lighter)) - register_context() - /obj/item/storage/fancy/cigarettes/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) . = ..() if(interacting_with != user) // you can quickly put a cigarette in your mouth only @@ -416,10 +401,6 @@ custom_price = PAYCHECK_LOWER has_open_closed_states = FALSE -/obj/item/storage/fancy/rollingpapers/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/rollingpaper) - /obj/item/storage/fancy/rollingpapers/update_overlays() . = ..() if(!contents.len) @@ -442,10 +423,6 @@ spawn_coupon = FALSE display_cigs = FALSE -/obj/item/storage/fancy/cigarettes/cigars/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/cigarette/cigar) - /obj/item/storage/fancy/cigarettes/cigars/update_icon_state() . = ..() //reset any changes the parent call may have made @@ -497,11 +474,6 @@ ) spawn_count = 8 -/obj/item/storage/fancy/heart_box/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/food/bonbon) - - /obj/item/storage/fancy/nugget_box name = "nugget box" desc = "A cardboard box used for holding chicken nuggies." @@ -512,10 +484,6 @@ spawn_type = /obj/item/food/nugget spawn_count = 6 -/obj/item/storage/fancy/nugget_box/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/food/nugget) - /* * Jar of pickles */ @@ -534,10 +502,6 @@ open_status = FANCY_CONTAINER_ALWAYS_OPEN has_open_closed_states = FALSE -/obj/item/storage/fancy/pickles_jar/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/food/pickle) - /obj/item/storage/fancy/pickles_jar/update_icon_state() . = ..() if(!contents.len) @@ -564,16 +528,7 @@ foldable_result = /obj/item/stack/sheet/mineral/wood open_status = FANCY_CONTAINER_ALWAYS_OPEN has_open_closed_states = FALSE - -/obj/item/storage/fancy/coffee_condi_display/Initialize(mapload) - . = ..() - atom_storage.max_slots = 14 - atom_storage.set_holdable(list( - /obj/item/reagent_containers/condiment/pack/sugar, - /obj/item/reagent_containers/condiment/creamer, - /obj/item/reagent_containers/condiment/pack/astrotame, - /obj/item/reagent_containers/condiment/chocolate, - )) + storage_type = /datum/storage/coffee_condi_display /obj/item/storage/fancy/coffee_condi_display/update_overlays() . = ..() @@ -602,12 +557,9 @@ . += "condi_display_chocolate" /obj/item/storage/fancy/coffee_condi_display/PopulateContents() - for(var/i in 1 to 4) - new /obj/item/reagent_containers/condiment/pack/sugar(src) - for(var/i in 1 to 3) - new /obj/item/reagent_containers/condiment/pack/astrotame(src) - for(var/i in 1 to 4) - new /obj/item/reagent_containers/condiment/creamer(src) - for(var/i in 1 to 3) - new /obj/item/reagent_containers/condiment/chocolate(src) - update_appearance() + return flatten_quantified_list(list( + /obj/item/reagent_containers/condiment/pack/sugar = 4, + /obj/item/reagent_containers/condiment/pack/astrotame = 3, + /obj/item/reagent_containers/condiment/creamer = 4, + /obj/item/reagent_containers/condiment/chocolate = 3, + )) diff --git a/code/game/objects/items/storage/garment.dm b/code/game/objects/items/storage/garment.dm index 65dda7b65ea..5b218f45707 100644 --- a/code/game/objects/items/storage/garment.dm +++ b/code/game/objects/items/storage/garment.dm @@ -5,6 +5,7 @@ desc = "A bag for storing extra clothes and shoes." slot_flags = NONE resistance_flags = FLAMMABLE + storage_type = /datum/storage/bag/garment /obj/item/storage/bag/garment/captain name = "captain's garment bag" @@ -38,120 +39,127 @@ name = "quartermasters's garment bag" desc = "A bag for storing extra clothes and shoes. This one belongs to the quartermaster." -/obj/item/storage/bag/garment/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.numerical_stacking = FALSE - atom_storage.max_total_storage = 200 - atom_storage.max_slots = 15 - atom_storage.insert_preposition = "in" - atom_storage.set_holdable(/obj/item/clothing) - /obj/item/storage/bag/garment/captain/PopulateContents() - new /obj/item/clothing/under/rank/captain(src) - new /obj/item/clothing/under/rank/captain/skirt(src) - new /obj/item/clothing/under/rank/captain/parade(src) - new /obj/item/clothing/suit/armor/vest/capcarapace(src) - new /obj/item/clothing/suit/armor/vest/capcarapace/captains_formal(src) - new /obj/item/clothing/suit/hooded/wintercoat/captain(src) - new /obj/item/clothing/suit/jacket/capjacket(src) - new /obj/item/clothing/glasses/sunglasses/gar/giga(src) - new /obj/item/clothing/gloves/captain(src) - new /obj/item/clothing/head/costume/crown/fancy(src) - new /obj/item/clothing/head/hats/caphat(src) - new /obj/item/clothing/head/hats/caphat/parade(src) - new /obj/item/clothing/neck/cloak/cap(src) - new /obj/item/clothing/shoes/laceup(src) + return list( + /obj/item/clothing/under/rank/captain, + /obj/item/clothing/under/rank/captain/skirt, + /obj/item/clothing/under/rank/captain/parade, + /obj/item/clothing/suit/armor/vest/capcarapace, + /obj/item/clothing/suit/armor/vest/capcarapace/captains_formal, + /obj/item/clothing/suit/hooded/wintercoat/captain, + /obj/item/clothing/suit/jacket/capjacket, + /obj/item/clothing/glasses/sunglasses/gar/giga, + /obj/item/clothing/gloves/captain, + /obj/item/clothing/head/costume/crown/fancy, + /obj/item/clothing/head/hats/caphat, + /obj/item/clothing/head/hats/caphat/parade, + /obj/item/clothing/neck/cloak/cap, + /obj/item/clothing/shoes/laceup, + ) /obj/item/storage/bag/garment/hop/PopulateContents() - new /obj/item/clothing/under/rank/civilian/head_of_personnel(src) - new /obj/item/clothing/under/rank/civilian/head_of_personnel/skirt(src) - new /obj/item/clothing/suit/armor/vest/hop(src) - new /obj/item/clothing/suit/hooded/wintercoat/hop(src) - new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/clothing/head/hats/hopcap(src) - new /obj/item/clothing/neck/cloak/hop(src) - new /obj/item/clothing/shoes/laceup(src) + return list( + /obj/item/clothing/under/rank/civilian/head_of_personnel, + /obj/item/clothing/under/rank/civilian/head_of_personnel/skirt, + /obj/item/clothing/suit/armor/vest/hop, + /obj/item/clothing/suit/hooded/wintercoat/hop, + /obj/item/clothing/glasses/sunglasses, + /obj/item/clothing/head/hats/hopcap, + /obj/item/clothing/neck/cloak/hop, + /obj/item/clothing/shoes/laceup, + ) /obj/item/storage/bag/garment/hos/PopulateContents() - new /obj/item/clothing/under/rank/security/head_of_security/skirt(src) - new /obj/item/clothing/under/rank/security/head_of_security/alt(src) - new /obj/item/clothing/under/rank/security/head_of_security/alt/skirt(src) - new /obj/item/clothing/under/rank/security/head_of_security/grey(src) - new /obj/item/clothing/under/rank/security/head_of_security/parade(src) - new /obj/item/clothing/under/rank/security/head_of_security/parade/female(src) - new /obj/item/clothing/gloves/tackler/combat(src) - new /obj/item/clothing/suit/armor/hos(src) - new /obj/item/clothing/suit/armor/hos/hos_formal(src) - new /obj/item/clothing/suit/armor/hos/trenchcoat/winter(src) - new /obj/item/clothing/suit/armor/vest/leather(src) - new /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch(src) - new /obj/item/clothing/glasses/hud/security/sunglasses/gars/giga(src) - new /obj/item/clothing/head/hats/hos/beret(src) - new /obj/item/clothing/head/hats/hos/cap(src) - new /obj/item/clothing/mask/gas/sechailer/swat(src) - new /obj/item/clothing/neck/cloak/hos(src) + return list( + /obj/item/clothing/under/rank/security/head_of_security/skirt, + /obj/item/clothing/under/rank/security/head_of_security/alt, + /obj/item/clothing/under/rank/security/head_of_security/alt/skirt, + /obj/item/clothing/under/rank/security/head_of_security/grey, + /obj/item/clothing/under/rank/security/head_of_security/parade, + /obj/item/clothing/under/rank/security/head_of_security/parade/female, + /obj/item/clothing/gloves/tackler/combat, + /obj/item/clothing/suit/armor/hos, + /obj/item/clothing/suit/armor/hos/hos_formal, + /obj/item/clothing/suit/armor/hos/trenchcoat/winter, + /obj/item/clothing/suit/armor/vest/leather, + /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch, + /obj/item/clothing/glasses/hud/security/sunglasses/gars/giga, + /obj/item/clothing/head/hats/hos/beret, + /obj/item/clothing/head/hats/hos/cap, + /obj/item/clothing/mask/gas/sechailer/swat, + /obj/item/clothing/neck/cloak/hos, + ) /obj/item/storage/bag/garment/warden/PopulateContents() - new /obj/item/clothing/suit/armor/vest/warden(src) - new /obj/item/clothing/head/hats/warden(src) - new /obj/item/clothing/head/hats/warden/drill(src) - new /obj/item/clothing/head/beret/sec/navywarden(src) - new /obj/item/clothing/suit/armor/vest/warden/alt(src) - new /obj/item/clothing/under/rank/security/warden/formal(src) - new /obj/item/clothing/under/rank/security/warden/skirt(src) - new /obj/item/clothing/gloves/krav_maga/sec(src) - new /obj/item/clothing/glasses/hud/security/sunglasses(src) - new /obj/item/clothing/mask/gas/sechailer(src) + return list( + /obj/item/clothing/suit/armor/vest/warden, + /obj/item/clothing/head/hats/warden, + /obj/item/clothing/head/hats/warden/drill, + /obj/item/clothing/head/beret/sec/navywarden, + /obj/item/clothing/suit/armor/vest/warden/alt, + /obj/item/clothing/under/rank/security/warden/formal, + /obj/item/clothing/under/rank/security/warden/skirt, + /obj/item/clothing/gloves/krav_maga/sec, + /obj/item/clothing/glasses/hud/security/sunglasses, + /obj/item/clothing/mask/gas/sechailer, + ) /obj/item/storage/bag/garment/research_director/PopulateContents() - new /obj/item/clothing/under/rank/rnd/research_director(src) - new /obj/item/clothing/under/rank/rnd/research_director/skirt(src) - new /obj/item/clothing/under/rank/rnd/research_director/alt(src) - new /obj/item/clothing/under/rank/rnd/research_director/alt/skirt(src) - new /obj/item/clothing/under/rank/rnd/research_director/turtleneck(src) - new /obj/item/clothing/under/rank/rnd/research_director/turtleneck/skirt(src) - new /obj/item/clothing/suit/hooded/wintercoat/science/rd(src) - new /obj/item/clothing/head/beret/science/rd(src) - new /obj/item/clothing/gloves/color/black(src) - new /obj/item/clothing/neck/cloak/rd(src) - new /obj/item/clothing/shoes/jackboots(src) + return list( + /obj/item/clothing/under/rank/rnd/research_director, + /obj/item/clothing/under/rank/rnd/research_director/skirt, + /obj/item/clothing/under/rank/rnd/research_director/alt, + /obj/item/clothing/under/rank/rnd/research_director/alt/skirt, + /obj/item/clothing/under/rank/rnd/research_director/turtleneck, + /obj/item/clothing/under/rank/rnd/research_director/turtleneck/skirt, + /obj/item/clothing/suit/hooded/wintercoat/science/rd, + /obj/item/clothing/head/beret/science/rd, + /obj/item/clothing/gloves/color/black, + /obj/item/clothing/neck/cloak/rd, + /obj/item/clothing/shoes/jackboots, + ) /obj/item/storage/bag/garment/chief_medical/PopulateContents() - new /obj/item/clothing/under/rank/medical/chief_medical_officer(src) - new /obj/item/clothing/under/rank/medical/chief_medical_officer/skirt(src) - new /obj/item/clothing/under/rank/medical/chief_medical_officer/scrubs(src) - new /obj/item/clothing/under/rank/medical/chief_medical_officer/turtleneck(src) - new /obj/item/clothing/under/rank/medical/chief_medical_officer/turtleneck/skirt(src) - new /obj/item/clothing/suit/hooded/wintercoat/medical/cmo(src) - new /obj/item/clothing/suit/toggle/labcoat/cmo(src) - new /obj/item/clothing/gloves/latex/nitrile(src) - new /obj/item/clothing/head/beret/medical/cmo(src) - new /obj/item/clothing/head/utility/surgerycap/cmo(src) - new /obj/item/clothing/neck/cloak/cmo(src) - new /obj/item/clothing/shoes/sneakers/blue (src) + return list( + /obj/item/clothing/under/rank/medical/chief_medical_officer, + /obj/item/clothing/under/rank/medical/chief_medical_officer/skirt, + /obj/item/clothing/under/rank/medical/chief_medical_officer/scrubs, + /obj/item/clothing/under/rank/medical/chief_medical_officer/turtleneck, + /obj/item/clothing/under/rank/medical/chief_medical_officer/turtleneck/skirt, + /obj/item/clothing/suit/hooded/wintercoat/medical/cmo, + /obj/item/clothing/suit/toggle/labcoat/cmo, + /obj/item/clothing/gloves/latex/nitrile, + /obj/item/clothing/head/beret/medical/cmo, + /obj/item/clothing/head/utility/surgerycap/cmo, + /obj/item/clothing/neck/cloak/cmo, + /obj/item/clothing/shoes/sneakers/blue , + ) /obj/item/storage/bag/garment/engineering_chief/PopulateContents() - new /obj/item/clothing/under/rank/engineering/chief_engineer(src) - new /obj/item/clothing/under/rank/engineering/chief_engineer/skirt(src) - new /obj/item/clothing/under/rank/engineering/chief_engineer/turtleneck(src) - new /obj/item/clothing/under/rank/engineering/chief_engineer/turtleneck/skirt(src) - new /obj/item/clothing/suit/hooded/wintercoat/engineering/ce(src) - new /obj/item/clothing/glasses/meson/engine(src) - new /obj/item/clothing/gloves/chief_engineer(src) - new /obj/item/clothing/head/utility/hardhat/white(src) - new /obj/item/clothing/head/utility/hardhat/welding/white(src) - new /obj/item/clothing/neck/cloak/ce(src) - new /obj/item/clothing/shoes/sneakers/brown(src) + return list( + /obj/item/clothing/under/rank/engineering/chief_engineer, + /obj/item/clothing/under/rank/engineering/chief_engineer/skirt, + /obj/item/clothing/under/rank/engineering/chief_engineer/turtleneck, + /obj/item/clothing/under/rank/engineering/chief_engineer/turtleneck/skirt, + /obj/item/clothing/suit/hooded/wintercoat/engineering/ce, + /obj/item/clothing/glasses/meson/engine, + /obj/item/clothing/gloves/chief_engineer, + /obj/item/clothing/head/utility/hardhat/white, + /obj/item/clothing/head/utility/hardhat/welding/white, + /obj/item/clothing/neck/cloak/ce, + /obj/item/clothing/shoes/sneakers/brown, + ) /obj/item/storage/bag/garment/quartermaster/PopulateContents() - new /obj/item/clothing/under/rank/cargo/qm(src) - new /obj/item/clothing/under/rank/cargo/qm/skirt(src) - new /obj/item/clothing/suit/hooded/wintercoat/cargo/qm(src) - new /obj/item/clothing/suit/utility/fire/firefighter(src) - new /obj/item/clothing/gloves/fingerless(src) - new /obj/item/clothing/suit/jacket/quartermaster(src) - new /obj/item/clothing/head/soft(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/neck/cloak/qm(src) - new /obj/item/clothing/shoes/sneakers/brown(src) + return list( + /obj/item/clothing/under/rank/cargo/qm, + /obj/item/clothing/under/rank/cargo/qm/skirt, + /obj/item/clothing/suit/hooded/wintercoat/cargo/qm, + /obj/item/clothing/suit/utility/fire/firefighter, + /obj/item/clothing/gloves/fingerless, + /obj/item/clothing/suit/jacket/quartermaster, + /obj/item/clothing/head/soft, + /obj/item/clothing/mask/gas, + /obj/item/clothing/neck/cloak/qm, + /obj/item/clothing/shoes/sneakers/brown, + ) diff --git a/code/game/objects/items/storage/holsters.dm b/code/game/objects/items/storage/holsters.dm index 6de4e83abb7..78c73dc037f 100644 --- a/code/game/objects/items/storage/holsters.dm +++ b/code/game/objects/items/storage/holsters.dm @@ -7,6 +7,7 @@ worn_icon_state = "holster" alternate_worn_layer = UNDER_SUIT_LAYER w_class = WEIGHT_CLASS_BULKY + storage_type = /datum/storage/holster /obj/item/storage/belt/holster/equipped(mob/user, slot) . = ..() @@ -17,105 +18,48 @@ . = ..() REMOVE_CLOTHING_TRAIT(user, TRAIT_GUNFLIP) -/obj/item/storage/belt/holster/Initialize(mapload) - . = ..() - atom_storage.max_slots = 1 - atom_storage.max_total_storage = 16 - atom_storage.set_holdable(list( - /obj/item/gun/ballistic/automatic/pistol, - /obj/item/gun/ballistic/revolver, - /obj/item/gun/energy/e_gun/mini, - /obj/item/gun/energy/disabler, - /obj/item/gun/energy/dueling, - /obj/item/food/grown/banana, - /obj/item/gun/energy/laser/thermal, - /obj/item/gun/ballistic/rifle/boltaction, //fits if you make it an obrez - /obj/item/gun/energy/laser/captain, - /obj/item/gun/energy/e_gun/hos, - )) - atom_storage.open_sound = 'sound/items/handling/holster_open.ogg' - atom_storage.open_sound_vary = TRUE - /obj/item/storage/belt/holster/energy name = "energy shoulder holsters" desc = "A rather plain pair of shoulder holsters with a bit of insulated padding inside. Designed to hold energy weaponry." - -/obj/item/storage/belt/holster/energy/Initialize(mapload) - . = ..() - atom_storage.max_slots = 2 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.set_holdable(list( - /obj/item/gun/energy/e_gun/mini, - /obj/item/gun/energy/disabler, - /obj/item/gun/energy/dueling, - /obj/item/food/grown/banana, - /obj/item/gun/energy/laser/thermal, - /obj/item/gun/energy/recharge/ebow, - /obj/item/gun/energy/laser/captain, - /obj/item/gun/energy/e_gun/hos, - )) + storage_type = /datum/storage/holster/energy /obj/item/storage/belt/holster/energy/thermal name = "thermal shoulder holsters" desc = "A rather plain pair of shoulder holsters with a bit of insulated padding inside. Meant to hold a twinned pair of thermal pistols, but can fit several kinds of energy handguns as well." /obj/item/storage/belt/holster/energy/thermal/PopulateContents() - generate_items_inside(list( + return list( /obj/item/gun/energy/laser/thermal/inferno = 1, /obj/item/gun/energy/laser/thermal/cryo = 1, - ),src) + ) /obj/item/storage/belt/holster/energy/disabler desc = "A rather plain pair of shoulder holsters with a bit of insulated padding inside. Designed to hold energy weaponry. A production stamp indicates that it was shipped with a disabler." /obj/item/storage/belt/holster/energy/disabler/PopulateContents() - generate_items_inside(list( - /obj/item/gun/energy/disabler = 1, - ),src) + return /obj/item/gun/energy/disabler /obj/item/storage/belt/holster/energy/smoothbore desc = "A rather plain pair of shoulder holsters with a bit of insulated padding inside. Designed to hold energy weaponry. Seems it was meant to fit two smoothbores." /obj/item/storage/belt/holster/energy/smoothbore/PopulateContents() - generate_items_inside(list( - /obj/item/gun/energy/disabler/smoothbore = 2, - ),src) + return list( + /obj/item/gun/energy/disabler/smoothbore, + /obj/item/gun/energy/disabler/smoothbore + ) /obj/item/storage/belt/holster/detective name = "detective's holster" desc = "A holster able to carry handguns and some ammo. WARNING: Badasses only." w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/belt/holster/detective/Initialize(mapload) - . = ..() - atom_storage.max_slots = 3 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.set_holdable(list( - /obj/item/gun/ballistic/automatic/pistol, - /obj/item/ammo_box/magazine/m9mm, // Pistol magazines. - /obj/item/ammo_box/magazine/m9mm_aps, - /obj/item/ammo_box/magazine/m10mm, - /obj/item/ammo_box/magazine/m45, - /obj/item/ammo_box/magazine/m50, - /obj/item/gun/ballistic/revolver, - /obj/item/ammo_box/c38, // Revolver speedloaders. - /obj/item/ammo_box/a357, - /obj/item/ammo_box/strilka310, - /obj/item/ammo_box/magazine/toy/pistol, - /obj/item/gun/energy/e_gun/mini, - /obj/item/gun/energy/disabler, - /obj/item/gun/energy/dueling, - /obj/item/gun/energy/laser/thermal, - /obj/item/gun/energy/laser/captain, - /obj/item/gun/energy/e_gun/hos, - /obj/item/gun/ballistic/rifle/boltaction, //fits if you make it an obrez - )) + storage_type = /datum/storage/holster/detective /obj/item/storage/belt/holster/detective/full/PopulateContents() - generate_items_inside(list( - /obj/item/ammo_box/c38 = 2, - /obj/item/gun/ballistic/revolver/c38/detective = 1, - ), src) + return list( + /obj/item/ammo_box/c38, + /obj/item/ammo_box/c38, + /obj/item/gun/ballistic/revolver/c38/detective + ) /obj/item/storage/belt/holster/detective/full/ert name = "marine's holster" @@ -125,10 +69,11 @@ worn_icon_state = "syndicate_holster" /obj/item/storage/belt/holster/detective/full/ert/PopulateContents() - generate_items_inside(list( - /obj/item/ammo_box/magazine/m45 = 2, - /obj/item/gun/ballistic/automatic/pistol/m1911 = 1, - ),src) + return list( + /obj/item/ammo_box/magazine/m45, + /obj/item/ammo_box/magazine/m45, + /obj/item/gun/ballistic/automatic/pistol/m1911 + ) /obj/item/storage/belt/holster/chameleon name = "syndicate holster" @@ -139,32 +84,7 @@ w_class = WEIGHT_CLASS_NORMAL actions_types = list(/datum/action/item_action/chameleon/change/belt) action_slots = ALL - -/obj/item/storage/belt/holster/chameleon/Initialize(mapload) - . = ..() - atom_storage.max_slots = 2 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.set_holdable(list( - /obj/item/gun/ballistic/automatic/pistol, - /obj/item/ammo_box/magazine/m9mm, - /obj/item/ammo_box/magazine/m9mm_aps, - /obj/item/ammo_box/magazine/m10mm, - /obj/item/ammo_box/magazine/m45, - /obj/item/ammo_box/magazine/m50, - /obj/item/gun/ballistic/revolver, - /obj/item/ammo_box/c38, - /obj/item/ammo_box/a357, - /obj/item/ammo_box/strilka310, - /obj/item/ammo_box/magazine/toy/pistol, - /obj/item/gun/energy/recharge/ebow, - /obj/item/gun/energy/e_gun/mini, - /obj/item/gun/energy/disabler, - /obj/item/gun/energy/dueling, - /obj/item/gun/energy/laser/captain, - /obj/item/gun/energy/e_gun/hos, - )) - - atom_storage.silent = TRUE + storage_type = /datum/storage/holster/chameleon /obj/item/storage/belt/holster/nukie name = "operative holster" @@ -173,34 +93,18 @@ inhand_icon_state = "syndicate_holster" worn_icon_state = "syndicate_holster" w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/belt/holster/nukie/Initialize(mapload) - . = ..() - atom_storage.max_slots = 2 - atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY - atom_storage.set_holdable(list( - /obj/item/gun, // ALL guns. - /obj/item/ammo_box/magazine, // ALL magazines. - /obj/item/ammo_box/c38, //There isn't a speedloader parent type, so I just put these three here by hand. - /obj/item/ammo_box/a357, //I didn't want to just use /obj/item/ammo_box, because then this could hold huge boxes of ammo. - /obj/item/ammo_box/strilka310, - /obj/item/ammo_casing, // For shotgun shells, rockets, launcher grenades, and a few other things. - /obj/item/grenade, // All regular grenades, the big grenade launcher fires these. - )) + storage_type = /datum/storage/holster/nukie /obj/item/storage/belt/holster/nukie/cowboy desc = "A deep shoulder holster capable of holding almost any form of small firearm and its ammo. This one's specialized for handguns." - -/obj/item/storage/belt/holster/nukie/cowboy/Initialize(mapload) - . = ..() - atom_storage.max_slots = 3 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL + storage_type = /datum/storage/holster/nukie/cowboy /obj/item/storage/belt/holster/nukie/cowboy/full/PopulateContents() - generate_items_inside(list( - /obj/item/ammo_box/a357 = 2, - /obj/item/gun/ballistic/revolver/cowboy/nuclear = 1, - ), src) + return list( + /obj/item/ammo_box/a357, + /obj/item/ammo_box/a357, + /obj/item/gun/ballistic/revolver/cowboy/nuclear + ) diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index 8926e6fd83a..abeafa13b55 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -8,6 +8,8 @@ righthand_file = 'icons/mob/inhands/equipment/briefcase_righthand.dmi' w_class = WEIGHT_CLASS_BULKY req_access = list(ACCESS_ARMORY) + storage_type = /datum/storage/lockbox + var/broken = FALSE var/open = FALSE var/icon_locked = "lockbox+l" @@ -17,14 +19,24 @@ /obj/item/storage/lockbox/Initialize(mapload) . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 14 - atom_storage.max_slots = 4 + atom_storage.locked = STORAGE_FULLY_LOCKED register_context() + update_appearance() +///screentips for lockboxes +/obj/item/storage/lockbox/add_context(atom/source, list/context, obj/item/held_item, mob/user) + if(!held_item) + return NONE + if(src.broken) + return NONE + if(!held_item.GetID()) + return NONE + context[SCREENTIP_CONTEXT_LMB] = atom_storage.locked ? "Unlock with ID" : "Lock with ID" + return CONTEXTUAL_SCREENTIP_SET + /obj/item/storage/lockbox/tool_act(mob/living/user, obj/item/tool, list/modifiers) var/obj/item/card/card = tool.GetID() if(isnull(card)) @@ -94,9 +106,10 @@ req_access = list(ACCESS_SECURITY) /obj/item/storage/lockbox/loyalty/PopulateContents() + . = list() for(var/i in 1 to 3) - new /obj/item/implantcase/mindshield(src) - new /obj/item/implanter/mindshield(src) + . += /obj/item/implantcase/mindshield + . += /obj/item/implanter/mindshield /obj/item/storage/lockbox/clusterbang name = "lockbox of clusterbangs" @@ -104,7 +117,7 @@ req_access = list(ACCESS_SECURITY) /obj/item/storage/lockbox/clusterbang/PopulateContents() - new /obj/item/grenade/clusterbuster(src) + return /obj/item/grenade/clusterbuster /obj/item/storage/lockbox/medal name = "medal box" @@ -119,13 +132,7 @@ icon_closed = "medalbox" icon_broken = "medalbox+b" icon_open = "medalboxopen" - -/obj/item/storage/lockbox/medal/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.max_slots = 10 - atom_storage.max_total_storage = 20 - atom_storage.set_holdable(/obj/item/clothing/accessory/medal) + storage_type = /datum/storage/lockbox/medal /obj/item/storage/lockbox/medal/examine(mob/user) . = ..() @@ -139,15 +146,14 @@ return CLICK_ACTION_SUCCESS /obj/item/storage/lockbox/medal/PopulateContents() - new /obj/item/clothing/accessory/medal/gold/captain(src) - new /obj/item/clothing/accessory/medal/silver/valor(src) - new /obj/item/clothing/accessory/medal/silver/valor(src) - new /obj/item/clothing/accessory/medal/silver/security(src) - new /obj/item/clothing/accessory/medal/bronze_heart(src) - new /obj/item/clothing/accessory/medal/plasma/nobel_science(src) - new /obj/item/clothing/accessory/medal/plasma/nobel_science(src) - for(var/i in 1 to 3) - new /obj/item/clothing/accessory/medal/conduct(src) + return flatten_quantified_list(list( + /obj/item/clothing/accessory/medal/gold/captain = 1, + /obj/item/clothing/accessory/medal/silver/valor = 2, + /obj/item/clothing/accessory/medal/silver/security = 1, + /obj/item/clothing/accessory/medal/bronze_heart = 1, + /obj/item/clothing/accessory/medal/plasma/nobel_science = 2, + /obj/item/clothing/accessory/medal/conduct = 3, + )) /obj/item/storage/lockbox/medal/update_overlays() . = ..() @@ -172,9 +178,10 @@ req_access = list(ACCESS_HOP) /obj/item/storage/lockbox/medal/hop/PopulateContents() + . = list() for(var/i in 1 to 3) - new /obj/item/clothing/accessory/medal/silver/bureaucracy(src) - new /obj/item/clothing/accessory/medal/gold/ordom(src) + . += /obj/item/clothing/accessory/medal/silver/bureaucracy + . += /obj/item/clothing/accessory/medal/gold/ordom /obj/item/storage/lockbox/medal/sec name = "security medal box" @@ -187,14 +194,16 @@ req_access = list(ACCESS_CMO) /obj/item/storage/lockbox/medal/med/PopulateContents() - new /obj/item/clothing/accessory/medal/med_medal(src) - new /obj/item/clothing/accessory/medal/med_medal2(src) - for(var/i in 1 to 3) - new /obj/item/clothing/accessory/medal/silver/emergency_services/medical(src) + return flatten_quantified_list(list( + /obj/item/clothing/accessory/medal/med_medal = 1, + /obj/item/clothing/accessory/medal/med_medal2 = 1, + /obj/item/clothing/accessory/medal/silver/emergency_services/medical = 3, + )) /obj/item/storage/lockbox/medal/sec/PopulateContents() + . = list() for(var/i in 1 to 3) - new /obj/item/clothing/accessory/medal/silver/security(src) + . += /obj/item/clothing/accessory/medal/silver/security /obj/item/storage/lockbox/medal/cargo name = "cargo award box" @@ -202,7 +211,7 @@ req_access = list(ACCESS_QM) /obj/item/storage/lockbox/medal/cargo/PopulateContents() - new /obj/item/clothing/accessory/medal/ribbon/cargo(src) + return /obj/item/clothing/accessory/medal/ribbon/cargo /obj/item/storage/lockbox/medal/service name = "service award box" @@ -210,7 +219,7 @@ req_access = list(ACCESS_HOP) /obj/item/storage/lockbox/medal/service/PopulateContents() - new /obj/item/clothing/accessory/medal/silver/excellence(src) + return /obj/item/clothing/accessory/medal/silver/excellence /obj/item/storage/lockbox/medal/sci name = "science medal box" @@ -218,8 +227,9 @@ req_access = list(ACCESS_RD) /obj/item/storage/lockbox/medal/sci/PopulateContents() + . = list() for(var/i in 1 to 3) - new /obj/item/clothing/accessory/medal/plasma/nobel_science(src) + . += /obj/item/clothing/accessory/medal/plasma/nobel_science /obj/item/storage/lockbox/medal/engineering name = "engineering medal box" @@ -227,9 +237,10 @@ req_access = list(ACCESS_CE) /obj/item/storage/lockbox/medal/engineering/PopulateContents() + . = list() for(var/i in 1 to 3) - new /obj/item/clothing/accessory/medal/silver/emergency_services/engineering(src) - new /obj/item/clothing/accessory/medal/silver/elder_atmosian(src) + . += /obj/item/clothing/accessory/medal/silver/emergency_services/engineering + . += /obj/item/clothing/accessory/medal/silver/elder_atmosian /obj/item/storage/lockbox/order name = "order lockbox" @@ -243,6 +254,8 @@ lefthand_file = 'icons/mob/inhands/equipment/briefcase_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/briefcase_righthand.dmi' w_class = WEIGHT_CLASS_HUGE + + ///The bank account of the mob who purchased this lockbox var/datum/bank_account/buyer_account /obj/item/storage/lockbox/order/Initialize(mapload, datum/bank_account/_buyer_account) @@ -258,13 +271,24 @@ balloon_alert(user, "incorrect bank account!") return FALSE -///screentips for lockboxes -/obj/item/storage/lockbox/add_context(atom/source, list/context, obj/item/held_item, mob/user) - if(!held_item) - return NONE - if(src.broken) - return NONE - if(!held_item.GetID()) - return NONE - context[SCREENTIP_CONTEXT_LMB] = atom_storage.locked ? "Unlock with ID" : "Lock with ID" - return CONTEXTUAL_SCREENTIP_SET +//Storage case. +/obj/item/storage/lockbox/dueling + name = "dueling pistol case" + desc = "Let's solve this like gentlespacemen." + icon_state = "medalbox+l" + inhand_icon_state = "syringe_kit" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + w_class = WEIGHT_CLASS_NORMAL + req_access = list(ACCESS_CAPTAIN) + icon_locked = "medalbox+l" + icon_closed = "medalbox" + icon_broken = "medalbox+b" + base_icon_state = "medalbox" + icon_open = "medalboxopen" + storage_type = /datum/storage/lockbox/dueling + +/obj/item/storage/lockbox/dueling/PopulateContents() + var/obj/item/gun/energy/dueling/gun_A = new(null) + var/obj/item/gun/energy/dueling/gun_B = new(null) + new /datum/duel(gun_A, gun_B) diff --git a/code/game/objects/items/storage/medkit.dm b/code/game/objects/items/storage/medkit.dm index 291df1951bb..f69a53a815e 100644 --- a/code/game/objects/items/storage/medkit.dm +++ b/code/game/objects/items/storage/medkit.dm @@ -21,70 +21,12 @@ drop_sound = 'sound/items/handling/medkit/medkit_drop.ogg' pickup_sound = 'sound/items/handling/medkit/medkit_pick_up.ogg' sound_vary = TRUE + storage_type = /datum/storage/medkit + + ///Does this medkit start out empty var/empty = FALSE /// Defines damage type of the medkit. General ones stay null. Used for medibot healing bonuses var/damagetype_healed - /// you just type this in holdables list of medkits instead of copypasting bunch of text. - var/static/list/list_of_everything_medkits_can_hold = list( - /obj/item/healthanalyzer, - /obj/item/dnainjector, - /obj/item/reagent_containers/dropper, - /obj/item/reagent_containers/cup/beaker, - /obj/item/reagent_containers/cup/bottle, - /obj/item/reagent_containers/cup/tube, - /obj/item/reagent_containers/applicator, - /obj/item/reagent_containers/syringe, - /obj/item/reagent_containers/medigel, - /obj/item/reagent_containers/spray, - /obj/item/lighter, - /obj/item/storage/box/bandages, - /obj/item/storage/fancy/cigarettes, - /obj/item/storage/pill_bottle, - /obj/item/stack/medical, - /obj/item/flashlight/pen, - /obj/item/extinguisher/mini, - /obj/item/reagent_containers/hypospray, - /obj/item/sensor_device, - /obj/item/radio, - /obj/item/clothing/gloves, - /obj/item/lazarus_injector, - /obj/item/bikehorn/rubberducky, - /obj/item/clothing/mask/surgical, - /obj/item/clothing/mask/breath, - /obj/item/clothing/mask/breath/medical, - /obj/item/surgical_drapes, - /obj/item/scalpel, - /obj/item/circular_saw, - /obj/item/bonesetter, - /obj/item/surgicaldrill, - /obj/item/retractor, - /obj/item/cautery, - /obj/item/hemostat, - /obj/item/blood_filter, - /obj/item/shears, - /obj/item/geiger_counter, - /obj/item/clothing/neck/stethoscope, - /obj/item/stamp, - /obj/item/clothing/glasses, - /obj/item/wrench/medical, - /obj/item/clothing/mask/muzzle, - /obj/item/reagent_containers/blood, - /obj/item/tank/internals/emergency_oxygen, - /obj/item/gun/syringe/syndicate, - /obj/item/implantcase, - /obj/item/implant, - /obj/item/implanter, - /obj/item/pinpointer/crew, - /obj/item/holosign_creator/medical, - /obj/item/stack/sticky_tape, - ) - -/obj/item/storage/medkit/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.open_sound = 'sound/items/handling/medkit/medkit_open.ogg' - atom_storage.open_sound_vary = TRUE - atom_storage.rustle_sound = 'sound/items/handling/medkit/medkit_rustle.ogg' /obj/item/storage/medkit/regular icon_state = "medkit" @@ -97,14 +39,14 @@ /obj/item/storage/medkit/regular/PopulateContents() if(empty) return - var/static/items_inside = list( + + return flatten_quantified_list(list( /obj/item/stack/medical/gauze = 1, /obj/item/stack/medical/suture = 2, /obj/item/stack/medical/mesh = 2, /obj/item/reagent_containers/hypospray/medipen = 1, /obj/item/healthanalyzer/simple = 1, - ) - generate_items_inside(items_inside,src) + )) /obj/item/storage/medkit/emergency icon_state = "medbriefcase" @@ -114,34 +56,30 @@ /obj/item/storage/medkit/emergency/PopulateContents() if(empty) - return - var/static/items_inside = list( - /obj/item/healthanalyzer/simple = 1, - /obj/item/stack/medical/gauze = 1, - /obj/item/stack/medical/suture/emergency = 1, - /obj/item/stack/medical/ointment = 1, - /obj/item/reagent_containers/hypospray/medipen/ekit = 2, - /obj/item/storage/pill_bottle/iron = 1, + return NONE + + return list( + /obj/item/healthanalyzer/simple, + /obj/item/stack/medical/gauze, + /obj/item/stack/medical/suture/emergency, + /obj/item/stack/medical/ointment, + /obj/item/reagent_containers/hypospray/medipen/ekit, + /obj/item/reagent_containers/hypospray/medipen/ekit, + /obj/item/storage/pill_bottle/iron, ) - generate_items_inside(items_inside,src) /obj/item/storage/medkit/surgery name = "surgical medkit" icon_state = "medkit_surgery" inhand_icon_state = "medkit-surgical" desc = "A high capacity aid kit for doctors, full of medical supplies and basic surgical equipment." - -/obj/item/storage/medkit/surgery/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL //holds the same equipment as a medibelt - atom_storage.max_slots = 12 - atom_storage.max_total_storage = 24 - atom_storage.set_holdable(list_of_everything_medkits_can_hold) + storage_type = /datum/storage/medkit/surgery /obj/item/storage/medkit/surgery/PopulateContents() if(empty) return - var/static/items_inside = list( + + return flatten_quantified_list(list( /obj/item/healthanalyzer = 1, /obj/item/stack/medical/gauze/twelve = 1, /obj/item/stack/medical/suture = 2, @@ -151,8 +89,7 @@ /obj/item/scalpel = 1, /obj/item/hemostat = 1, /obj/item/cautery = 1, - ) - generate_items_inside(items_inside,src) + )) /obj/item/storage/medkit/ancient icon_state = "oldfirstaid" @@ -161,11 +98,12 @@ /obj/item/storage/medkit/ancient/PopulateContents() if(empty) return - var/static/items_inside = list( + + return flatten_quantified_list(list( /obj/item/stack/medical/gauze = 1, /obj/item/stack/medical/bruise_pack = 3, - /obj/item/stack/medical/ointment= 3) - generate_items_inside(items_inside,src) + /obj/item/stack/medical/ointment= 3, + )) /obj/item/storage/medkit/ancient/heirloom desc = "A first aid kit with the ability to heal common types of injuries. You start thinking of the good old days just by looking at it." @@ -188,12 +126,13 @@ /obj/item/storage/medkit/fire/PopulateContents() if(empty) return - var/static/items_inside = list( + + return flatten_quantified_list(list( /obj/item/reagent_containers/applicator/patch/aiuri = 3, /obj/item/reagent_containers/spray/hercuri = 1, /obj/item/reagent_containers/hypospray/medipen/oxandrolone = 1, - /obj/item/reagent_containers/hypospray/medipen = 1) - generate_items_inside(items_inside,src) + /obj/item/reagent_containers/hypospray/medipen = 1, + )) /obj/item/storage/medkit/toxin name = "toxin treatment kit" @@ -213,14 +152,14 @@ /obj/item/storage/medkit/toxin/PopulateContents() if(empty) return - var/static/items_inside = list( + + return flatten_quantified_list(list( /obj/item/storage/pill_bottle/multiver/less = 1, /obj/item/reagent_containers/syringe/syriniver = 3, /obj/item/storage/pill_bottle/potassiodide = 1, /obj/item/reagent_containers/hypospray/medipen/penacid = 1, /obj/item/healthanalyzer/simple/disease = 1, - ) - generate_items_inside(items_inside,src) + )) /obj/item/storage/medkit/o2 name = "oxygen deprivation treatment kit" @@ -239,12 +178,13 @@ /obj/item/storage/medkit/o2/PopulateContents() if(empty) return - var/static/items_inside = list( + + return flatten_quantified_list(list( /obj/item/reagent_containers/syringe/convermol = 3, /obj/item/reagent_containers/hypospray/medipen/salbutamol = 1, /obj/item/reagent_containers/hypospray/medipen = 1, - /obj/item/storage/pill_bottle/iron = 1) - generate_items_inside(items_inside,src) + /obj/item/storage/pill_bottle/iron = 1, + )) /obj/item/storage/medkit/brute name = "brute trauma treatment kit" @@ -263,14 +203,14 @@ /obj/item/storage/medkit/brute/PopulateContents() if(empty) return - var/static/items_inside = list( + + return flatten_quantified_list(list( /obj/item/reagent_containers/applicator/patch/libital = 3, /obj/item/stack/medical/gauze = 1, /obj/item/storage/pill_bottle/probital = 1, /obj/item/reagent_containers/hypospray/medipen/salacid = 1, /obj/item/healthanalyzer/simple = 1, - ) - generate_items_inside(items_inside,src) + )) /obj/item/storage/medkit/advanced name = "advanced first aid kit" @@ -286,12 +226,13 @@ /obj/item/storage/medkit/advanced/PopulateContents() if(empty) return - var/static/items_inside = list( + + return flatten_quantified_list(list( /obj/item/reagent_containers/applicator/patch/synthflesh = 3, /obj/item/reagent_containers/hypospray/medipen/atropine = 2, /obj/item/stack/medical/gauze = 1, - /obj/item/storage/pill_bottle/penacid = 1) - generate_items_inside(items_inside,src) + /obj/item/storage/pill_bottle/penacid = 1, + )) /obj/item/storage/medkit/tactical_lite name = "combat first aid kit" @@ -305,14 +246,14 @@ /obj/item/storage/medkit/tactical_lite/PopulateContents() if(empty) return - var/static/list/items_inside = list( + + return flatten_quantified_list(list( /obj/item/healthanalyzer/advanced = 1, /obj/item/reagent_containers/hypospray/medipen/atropine = 1, /obj/item/stack/medical/gauze = 1, /obj/item/stack/medical/suture/medicated = 2, /obj/item/stack/medical/mesh/advanced = 2, - ) - generate_items_inside(items_inside, src) + )) /obj/item/storage/medkit/tactical name = "combat medical kit" @@ -320,18 +261,13 @@ icon_state = "medkit_tactical" inhand_icon_state = "medkit-tactical" damagetype_healed = HEAL_ALL_DAMAGE - -/obj/item/storage/medkit/tactical/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_slots = 21 - atom_storage.max_total_storage = 24 - atom_storage.set_holdable(list_of_everything_medkits_can_hold) + storage_type = /datum/storage/medkit/tatical /obj/item/storage/medkit/tactical/PopulateContents() if(empty) return - var/static/list/items_inside = list( + + var/static/list/obj/item/items_inside = flatten_quantified_list(list( /obj/item/cautery = 1, /obj/item/scalpel = 1, /obj/item/healthanalyzer/advanced = 1, @@ -345,8 +281,9 @@ /obj/item/stack/medical/mesh/advanced = 2, /obj/item/reagent_containers/applicator/patch/libital = 4, /obj/item/reagent_containers/applicator/patch/aiuri = 4, - ) - generate_items_inside(items_inside,src) + )) + + return items_inside /obj/item/storage/medkit/tactical/premium name = "premium combat medical kit" @@ -354,19 +291,13 @@ icon_state = "medkit_tactical_premium" inhand_icon_state = "medkit-tactical-premium" grind_results = list(/datum/reagent/lead = 10) - -/obj/item/storage/medkit/tactical/premium/Initialize(mapload) - . = ..() - atom_storage.allow_big_nesting = TRUE // so you can put back the box you took out - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_slots = 21 - atom_storage.max_total_storage = 34 - atom_storage.set_holdable(list_of_everything_medkits_can_hold) + storage_type = /datum/storage/medkit/tatical/premium /obj/item/storage/medkit/tactical/premium/PopulateContents() if(empty) - return - var/static/list/items_inside = list( + return NONE + + var/static/list/items_inside = flatten_quantified_list(list( /obj/item/stack/medical/suture/medicated = 2, /obj/item/stack/medical/mesh/advanced = 2, /obj/item/reagent_containers/applicator/patch/libital = 3, @@ -383,9 +314,9 @@ /obj/item/storage/box/evilmeds = 1, /obj/item/reagent_containers/medigel/sterilizine = 1, /obj/item/clothing/glasses/hud/health/night/science = 1, - ) - generate_items_inside(items_inside,src) - list_of_everything_medkits_can_hold += items_inside + )) + + return items_inside /obj/item/storage/medkit/coroner name = "compact coroner's medkit" @@ -393,37 +324,20 @@ icon = 'icons/obj/storage/medkit.dmi' icon_state = "compact_coronerkit" inhand_icon_state = "coronerkit" - -/obj/item/storage/medkit/coroner/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_slots = 14 - atom_storage.max_total_storage = 24 - atom_storage.set_holdable(list( - /obj/item/reagent_containers, - /obj/item/bodybag, - /obj/item/toy/crayon, - /obj/item/pen, - /obj/item/paper, - /obj/item/surgical_drapes, - /obj/item/scalpel, - /obj/item/retractor, - /obj/item/hemostat, - /obj/item/cautery, - /obj/item/autopsy_scanner, - )) + storage_type = /datum/storage/medkit/coroner /obj/item/storage/medkit/coroner/PopulateContents() if(empty) return - var/static/items_inside = list( - /obj/item/reagent_containers/cup/bottle/formaldehyde = 1, - /obj/item/reagent_containers/medigel/sterilizine = 1, - /obj/item/reagent_containers/blood = 1, - /obj/item/bodybag = 2, - /obj/item/reagent_containers/syringe = 1, + + return list( + /obj/item/reagent_containers/cup/bottle/formaldehyde, + /obj/item/reagent_containers/medigel/sterilizine, + /obj/item/reagent_containers/blood, + /obj/item/bodybag, + /obj/item/bodybag, + /obj/item/reagent_containers/syringe, ) - generate_items_inside(items_inside,src) //medibot assembly /obj/item/storage/medkit/tool_act(mob/living/user, obj/item/tool, list/modifiers) @@ -446,374 +360,5 @@ /// Gets what skin (icon_state) this medkit uses for a medbot /obj/item/storage/medkit/proc/get_medbot_skin() + // The skin var is nullsafe so returning nothing is A-OK return "generic" - -/* - * Pill Bottles - */ - -/obj/item/storage/pill_bottle - name = "pill bottle" - desc = "It's an airtight container for storing medication." - icon_state = "pill_canister" - icon = 'icons/obj/medical/chemical.dmi' - inhand_icon_state = "contsolid" - worn_icon_state = "nothing" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - w_class = WEIGHT_CLASS_SMALL - pickup_sound = 'sound/items/handling/pill_bottle_pickup.ogg' - drop_sound = 'sound/items/handling/pill_bottle_place.ogg' - -/obj/item/storage/pill_bottle/Initialize(mapload) - . = ..() - atom_storage.allow_quick_gather = TRUE - atom_storage.set_holdable(list( - /obj/item/reagent_containers/applicator/pill, - /obj/item/reagent_containers/applicator/patch, - /obj/item/food/bait/natural, - )) - atom_storage.open_sound = 'sound/items/handling/pill_bottle_open.ogg' - atom_storage.open_sound_vary = FALSE - -/obj/item/storage/pill_bottle/suicide_act(mob/living/user) - user.visible_message(span_suicide("[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!")) - return TOXLOSS - -/obj/item/storage/pill_bottle/multiver - name = "bottle of multiver pills" - desc = "Contains pills used to counter toxins." - -/obj/item/storage/pill_bottle/multiver/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/applicator/pill/multiver(src) - -/obj/item/storage/pill_bottle/multiver/less - -/obj/item/storage/pill_bottle/multiver/less/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/reagent_containers/applicator/pill/multiver(src) - -/obj/item/storage/pill_bottle/epinephrine - name = "bottle of epinephrine pills" - desc = "Contains pills used to stabilize patients." - -/obj/item/storage/pill_bottle/epinephrine/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/applicator/pill/epinephrine(src) - -/obj/item/storage/pill_bottle/mutadone - name = "bottle of mutadone pills" - desc = "Contains pills used to treat genetic abnormalities." - -/obj/item/storage/pill_bottle/mutadone/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/applicator/pill/mutadone(src) - -/obj/item/storage/pill_bottle/potassiodide - name = "bottle of potassium iodide pills" - desc = "Contains pills used to reduce radiation damage." - -/obj/item/storage/pill_bottle/potassiodide/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/reagent_containers/applicator/pill/potassiodide(src) - -/obj/item/storage/pill_bottle/probital - name = "bottle of probital pills" - desc = "Contains pills used to treat brute damage. The tag in the bottle states 'Eat before ingesting, may cause fatigue'." - -/obj/item/storage/pill_bottle/probital/PopulateContents() - for(var/i in 1 to 4) - new /obj/item/reagent_containers/applicator/pill/probital(src) - -/obj/item/storage/pill_bottle/iron - name = "bottle of iron pills" - desc = "Contains pills used to reduce blood loss slowly. The tag in the bottle states 'Only take one each five minutes'." - -/obj/item/storage/pill_bottle/iron/PopulateContents() - for(var/i in 1 to 4) - new /obj/item/reagent_containers/applicator/pill/iron(src) - -/obj/item/storage/pill_bottle/mannitol - name = "bottle of mannitol pills" - desc = "Contains pills used to treat brain damage." - -/obj/item/storage/pill_bottle/mannitol/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/applicator/pill/mannitol(src) - -//Contains 4 pills instead of 7, and 5u pills instead of 50u (50u pills heal 250 brain damage, 5u pills heal 25) -/obj/item/storage/pill_bottle/mannitol/braintumor - desc = "Contains diluted pills used to treat brain tumor symptoms. Take one when feeling lightheaded." - -/obj/item/storage/pill_bottle/mannitol/braintumor/PopulateContents() - for(var/i in 1 to 4) - new /obj/item/reagent_containers/applicator/pill/mannitol/braintumor(src) - -/obj/item/storage/pill_bottle/stimulant - name = "bottle of stimulant pills" - desc = "Guaranteed to give you that extra burst of energy during a long shift!" - -/obj/item/storage/pill_bottle/stimulant/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/pill/stimulant(src) - -/obj/item/storage/pill_bottle/sansufentanyl - name = "bottle of experimental medication" - desc = "A bottle of pills developed by Interdyne Pharmaceuticals. They're used to treat Hereditary Manifold Sickness." - -/obj/item/storage/pill_bottle/sansufentanyl/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/reagent_containers/applicator/pill/sansufentanyl(src) - -/obj/item/storage/pill_bottle/mining - name = "bottle of patches" - desc = "Contains patches used to treat brute and burn damage." - -/obj/item/storage/pill_bottle/mining/PopulateContents() - new /obj/item/reagent_containers/applicator/patch/aiuri(src) - for(var/i in 1 to 3) - new /obj/item/reagent_containers/applicator/patch/libital(src) - -/obj/item/storage/pill_bottle/zoom - name = "suspicious pill bottle" - desc = "The label is pretty old and almost unreadable, you recognize some chemical compounds." - -/obj/item/storage/pill_bottle/zoom/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/pill/zoom(src) - -/obj/item/storage/pill_bottle/happy - name = "suspicious pill bottle" - desc = "There is a smiley on the top." - -/obj/item/storage/pill_bottle/happy/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/pill/happy(src) - -/obj/item/storage/pill_bottle/lsd - name = "suspicious pill bottle" - desc = "There is a crude drawing which could be either a mushroom, or a deformed moon." - -/obj/item/storage/pill_bottle/lsd/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/pill/lsd(src) - -/obj/item/storage/pill_bottle/aranesp - name = "suspicious pill bottle" - desc = "The label has 'fuck disablers' hastily scrawled in black marker." - -/obj/item/storage/pill_bottle/aranesp/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/pill/aranesp(src) - -/obj/item/storage/pill_bottle/psicodine - name = "bottle of psicodine pills" - desc = "Contains pills used to treat mental distress and traumas." - -/obj/item/storage/pill_bottle/psicodine/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/applicator/pill/psicodine(src) - -/obj/item/storage/pill_bottle/penacid - name = "bottle of pentetic acid pills" - desc = "Contains pills to expunge radiation and toxins." - -/obj/item/storage/pill_bottle/penacid/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/reagent_containers/applicator/pill/penacid(src) - - -/obj/item/storage/pill_bottle/neurine - name = "bottle of neurine pills" - desc = "Contains pills to treat non-severe mental traumas." - -/obj/item/storage/pill_bottle/neurine/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/pill/neurine(src) - -/obj/item/storage/pill_bottle/maintenance_pill - name = "bottle of maintenance pills" - desc = "An old pill bottle. It smells musty." - -/obj/item/storage/pill_bottle/maintenance_pill/Initialize(mapload) - . = ..() - var/obj/item/reagent_containers/applicator/pill/P = locate() in src - name = "bottle of [P.name]s" - -/obj/item/storage/pill_bottle/maintenance_pill/PopulateContents() - for(var/i in 1 to rand(1,7)) - new /obj/item/reagent_containers/applicator/pill/maintenance(src) - -/obj/item/storage/pill_bottle/maintenance_pill/full/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/applicator/pill/maintenance(src) - -///////////////////////////////////////// Psychologist inventory pillbottles -/obj/item/storage/pill_bottle/happinesspsych - name = "happiness pills" - desc = "Contains pills used as a last resort means to temporarily stabilize depression and anxiety. WARNING: side effects may include slurred speech, drooling, and severe addiction." - -/obj/item/storage/pill_bottle/happinesspsych/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/pill/happinesspsych(src) - -/obj/item/storage/pill_bottle/lsdpsych - name = "mindbreaker toxin pills" - desc = "!FOR THERAPEUTIC USE ONLY! Contains pills used to alleviate the symptoms of Reality Dissociation Syndrome." - -/obj/item/storage/pill_bottle/lsdpsych/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/pill/lsdpsych(src) - -/obj/item/storage/pill_bottle/paxpsych - name = "pax pills" - desc = "Contains pills used to temporarily pacify patients that are deemed a harm to themselves or others." - -/obj/item/storage/pill_bottle/paxpsych/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/pill/paxpsych(src) - -/obj/item/storage/pill_bottle/naturalbait - name = "freshness jar" - desc = "Full of natural fish bait." - -/obj/item/storage/pill_bottle/naturalbait/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/food/bait/natural(src) - -/obj/item/storage/pill_bottle/ondansetron - name = "ondansetron patches" - desc = "A bottle containing patches of ondansetron, a drug used to treat nausea and vomiting. May cause drowsiness." - -/obj/item/storage/pill_bottle/ondansetron/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/applicator/patch/ondansetron(src) - -/// A box which takes in coolant and uses it to preserve organs and body parts -/obj/item/storage/organbox - name = "organ transport box" - desc = "An advanced box with a cooling mechanism that uses cryostylane or other cold reagents to keep the organs or bodyparts inside preserved." - icon = 'icons/obj/storage/case.dmi' - icon_state = "organbox" - base_icon_state = "organbox" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - throw_speed = 3 - throw_range = 7 - custom_premium_price = PAYCHECK_CREW * 4 - /// var to prevent it freezing the same things over and over - var/cooling = FALSE - -/obj/item/storage/organbox/Initialize(mapload) - . = ..() - - create_storage( - storage_type = /datum/storage/organ_box, - max_specific_storage = WEIGHT_CLASS_BULKY, - max_total_storage = 21, - canhold = list( - /obj/item/organ, - /obj/item/bodypart, - /obj/item/food/icecream, - ), - ) - - create_reagents(100, TRANSPARENT) - START_PROCESSING(SSobj, src) - -/obj/item/storage/organbox/process(seconds_per_tick) - ///if there is enough coolant var - var/using_coolant = coolant_to_spend() - if (isnull(using_coolant)) - if (cooling) - cooling = FALSE - update_appearance() - for(var/obj/stored in contents) - stored.unfreeze() - return - - var/amount_used = 0.05 * seconds_per_tick - if (using_coolant != /datum/reagent/cryostylane) - amount_used *= 2 - reagents.remove_reagent(using_coolant, amount_used) - - if(cooling) - return - cooling = TRUE - update_appearance() - for(var/obj/stored in contents) - stored.freeze() - -/// Returns which coolant we are about to use, or null if there isn't any -/obj/item/storage/organbox/proc/coolant_to_spend() - if (reagents.get_reagent_amount(/datum/reagent/cryostylane)) - return /datum/reagent/cryostylane - if (reagents.get_reagent_amount(/datum/reagent/consumable/ice)) - return /datum/reagent/consumable/ice - return null - -/obj/item/storage/organbox/update_icon_state() - icon_state = "[base_icon_state][cooling ? "-working" : null]" - return ..() - -/obj/item/storage/organbox/tool_act(mob/living/user, obj/item/tool, list/modifiers) - if(is_reagent_container(tool) && tool.is_open_container()) - var/obj/item/reagent_containers/RC = tool - var/units = RC.reagents.trans_to(src, RC.amount_per_transfer_from_this, transferred_by = user) - if(units) - balloon_alert(user, "[units]u transferred") - return ITEM_INTERACT_SUCCESS - return ITEM_INTERACT_BLOCKING - if(istype(tool, /obj/item/plunger)) - balloon_alert(user, "plunging...") - if(do_after(user, 1 SECONDS, target = src)) - balloon_alert(user, "plunged") - reagents.clear_reagents() - return ITEM_INTERACT_SUCCESS - return ..() - -/obj/item/storage/organbox/suicide_act(mob/living/carbon/user) - if(HAS_TRAIT(user, TRAIT_RESISTCOLD)) //if they're immune to cold, just do the box suicide - var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD) - if(myhead) - user.visible_message(span_suicide("[user] puts [user.p_their()] head into \the [src] and begins closing it! It looks like [user.p_theyre()] trying to commit suicide!")) - myhead.dismember() - myhead.forceMove(src) //force your enemies to kill themselves with your head collection box! - playsound(user, "desecration-01.ogg", 50, TRUE, -1) - return BRUTELOSS - user.visible_message(span_suicide("[user] is beating [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")) - return BRUTELOSS - user.visible_message(span_suicide("[user] is putting [user.p_their()] head inside the [src], it looks like [user.p_theyre()] trying to commit suicide!")) - user.adjust_bodytemperature(-300) - user.apply_status_effect(/datum/status_effect/freon) - return FIRELOSS - -/// A subtype of organ storage box which starts with a full coolant tank -/obj/item/storage/organbox/preloaded - -/obj/item/storage/organbox/preloaded/Initialize(mapload) - . = ..() - reagents.add_reagent(/datum/reagent/cryostylane, reagents.maximum_volume) - -/obj/item/storage/test_tube_rack - name = "test tube rack" - desc = "A wooden rack for storing test tubes." - icon_state = "rack" - base_icon_state = "rack" - icon = 'icons/obj/medical/chemical.dmi' - inhand_icon_state = "contsolid" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - w_class = WEIGHT_CLASS_SMALL - storage_type = /datum/storage/test_tube_rack - -/obj/item/storage/test_tube_rack/update_icon_state() - icon_state = "[base_icon_state][contents.len > 0 ? contents.len : null]" - return ..() - -/obj/item/storage/test_tube_rack/full/PopulateContents() - for(var/i in 1 to atom_storage.max_slots) - new /obj/item/reagent_containers/cup/tube(src) - update_appearance(UPDATE_ICON_STATE) - diff --git a/code/game/objects/items/storage/misc.dm b/code/game/objects/items/storage/misc.dm new file mode 100644 index 00000000000..e3fc2952c18 --- /dev/null +++ b/code/game/objects/items/storage/misc.dm @@ -0,0 +1,120 @@ + +/// A box which takes in coolant and uses it to preserve organs and body parts +/obj/item/storage/organbox + name = "organ transport box" + desc = "An advanced box with a cooling mechanism that uses cryostylane or other cold reagents to keep the organs or bodyparts inside preserved." + icon = 'icons/obj/storage/case.dmi' + icon_state = "organbox" + base_icon_state = "organbox" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + throw_speed = 3 + throw_range = 7 + custom_premium_price = PAYCHECK_CREW * 4 + storage_type = /datum/storage/organ_box + + /// var to prevent it freezing the same things over and over + var/cooling = FALSE + +/obj/item/storage/organbox/Initialize(mapload) + . = ..() + + create_reagents(100, TRANSPARENT) + + START_PROCESSING(SSobj, src) + +/obj/item/storage/organbox/process(seconds_per_tick) + ///if there is enough coolant var + var/using_coolant = coolant_to_spend() + if (isnull(using_coolant)) + if (cooling) + cooling = FALSE + update_appearance() + for(var/obj/stored in contents) + stored.unfreeze() + return + + var/amount_used = 0.05 * seconds_per_tick + if (using_coolant != /datum/reagent/cryostylane) + amount_used *= 2 + reagents.remove_reagent(using_coolant, amount_used) + + if(cooling) + return + cooling = TRUE + update_appearance() + for(var/obj/stored in contents) + stored.freeze() + +/// Returns which coolant we are about to use, or null if there isn't any +/obj/item/storage/organbox/proc/coolant_to_spend() + if (reagents.get_reagent_amount(/datum/reagent/cryostylane)) + return /datum/reagent/cryostylane + if (reagents.get_reagent_amount(/datum/reagent/consumable/ice)) + return /datum/reagent/consumable/ice + return null + +/obj/item/storage/organbox/update_icon_state() + icon_state = "[base_icon_state][cooling ? "-working" : null]" + return ..() + +/obj/item/storage/organbox/tool_act(mob/living/user, obj/item/tool, list/modifiers) + if(is_reagent_container(tool) && tool.is_open_container()) + var/obj/item/reagent_containers/RC = tool + var/units = RC.reagents.trans_to(src, RC.amount_per_transfer_from_this, transferred_by = user) + if(units) + balloon_alert(user, "[units]u transferred") + return ITEM_INTERACT_SUCCESS + return ITEM_INTERACT_BLOCKING + if(istype(tool, /obj/item/plunger)) + balloon_alert(user, "plunging...") + if(do_after(user, 1 SECONDS, target = src)) + balloon_alert(user, "plunged") + reagents.clear_reagents() + return ITEM_INTERACT_SUCCESS + return ..() + +/obj/item/storage/organbox/suicide_act(mob/living/carbon/user) + if(HAS_TRAIT(user, TRAIT_RESISTCOLD)) //if they're immune to cold, just do the box suicide + var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD) + if(myhead) + user.visible_message(span_suicide("[user] puts [user.p_their()] head into \the [src] and begins closing it! It looks like [user.p_theyre()] trying to commit suicide!")) + myhead.dismember() + myhead.forceMove(src) //force your enemies to kill themselves with your head collection box! + playsound(user, "desecration-01.ogg", 50, TRUE, -1) + return BRUTELOSS + user.visible_message(span_suicide("[user] is beating [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")) + return BRUTELOSS + user.visible_message(span_suicide("[user] is putting [user.p_their()] head inside the [src], it looks like [user.p_theyre()] trying to commit suicide!")) + user.adjust_bodytemperature(-300) + user.apply_status_effect(/datum/status_effect/freon) + return FIRELOSS + +/// A subtype of organ storage box which starts with a full coolant tank +/obj/item/storage/organbox/preloaded + +/obj/item/storage/organbox/preloaded/Initialize(mapload) + . = ..() + reagents.add_reagent(/datum/reagent/cryostylane, reagents.maximum_volume) + +/obj/item/storage/test_tube_rack + name = "test tube rack" + desc = "A wooden rack for storing test tubes." + icon_state = "rack" + base_icon_state = "rack" + icon = 'icons/obj/medical/chemical.dmi' + inhand_icon_state = "contsolid" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + w_class = WEIGHT_CLASS_SMALL + storage_type = /datum/storage/test_tube_rack + +/obj/item/storage/test_tube_rack/update_icon_state() + icon_state = "[base_icon_state][contents.len > 0 ? contents.len : null]" + return ..() + +/obj/item/storage/test_tube_rack/full/PopulateContents() + . = list() + for(var/i in 1 to 8) + . += /obj/item/reagent_containers/cup/tube + diff --git a/code/game/objects/items/storage/pillbottles.dm b/code/game/objects/items/storage/pillbottles.dm new file mode 100644 index 00000000000..e1e258437a3 --- /dev/null +++ b/code/game/objects/items/storage/pillbottles.dm @@ -0,0 +1,274 @@ + +/// Pill Bottles +/obj/item/storage/pill_bottle + name = "pill bottle" + desc = "It's an airtight container for storing medication." + icon_state = "pill_canister" + icon = 'icons/obj/medical/chemical.dmi' + inhand_icon_state = "contsolid" + worn_icon_state = "nothing" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + w_class = WEIGHT_CLASS_SMALL + pickup_sound = 'sound/items/handling/pill_bottle_pickup.ogg' + drop_sound = 'sound/items/handling/pill_bottle_place.ogg' + storage_type = /datum/storage/pillbottle + +/obj/item/storage/pill_bottle/suicide_act(mob/living/user) + user.visible_message(span_suicide("[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!")) + return TOXLOSS + +/obj/item/storage/pill_bottle/multiver + name = "bottle of multiver pills" + desc = "Contains pills used to counter toxins." + +/obj/item/storage/pill_bottle/multiver/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/reagent_containers/applicator/pill/multiver + +/obj/item/storage/pill_bottle/multiver/less + +/obj/item/storage/pill_bottle/multiver/less/PopulateContents() + . = list() + for(var/i in 1 to 3) + . += /obj/item/reagent_containers/applicator/pill/multiver + +/obj/item/storage/pill_bottle/epinephrine + name = "bottle of epinephrine pills" + desc = "Contains pills used to stabilize patients." + +/obj/item/storage/pill_bottle/epinephrine/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/reagent_containers/applicator/pill/epinephrine + +/obj/item/storage/pill_bottle/mutadone + name = "bottle of mutadone pills" + desc = "Contains pills used to treat genetic abnormalities." + +/obj/item/storage/pill_bottle/mutadone/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/reagent_containers/applicator/pill/mutadone + +/obj/item/storage/pill_bottle/potassiodide + name = "bottle of potassium iodide pills" + desc = "Contains pills used to reduce radiation damage." + +/obj/item/storage/pill_bottle/potassiodide/PopulateContents() + . = list() + for(var/i in 1 to 3) + . += /obj/item/reagent_containers/applicator/pill/potassiodide + +/obj/item/storage/pill_bottle/probital + name = "bottle of probital pills" + desc = "Contains pills used to treat brute damage. The tag in the bottle states 'Eat before ingesting, may cause fatigue'." + +/obj/item/storage/pill_bottle/probital/PopulateContents() + . = list() + for(var/i in 1 to 4) + . += /obj/item/reagent_containers/applicator/pill/probital + +/obj/item/storage/pill_bottle/iron + name = "bottle of iron pills" + desc = "Contains pills used to reduce blood loss slowly. The tag in the bottle states 'Only take one each five minutes'." + +/obj/item/storage/pill_bottle/iron/PopulateContents() + . = list() + for(var/i in 1 to 4) + . += /obj/item/reagent_containers/applicator/pill/iron + +/obj/item/storage/pill_bottle/mannitol + name = "bottle of mannitol pills" + desc = "Contains pills used to treat brain damage." + +/obj/item/storage/pill_bottle/mannitol/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/reagent_containers/applicator/pill/mannitol + +//Contains 4 pills instead of 7, and 5u pills instead of 50u (50u pills heal 250 brain damage, 5u pills heal 25) +/obj/item/storage/pill_bottle/mannitol/braintumor + desc = "Contains diluted pills used to treat brain tumor symptoms. Take one when feeling lightheaded." + +/obj/item/storage/pill_bottle/mannitol/braintumor/PopulateContents() + . = list() + for(var/i in 1 to 4) + . += /obj/item/reagent_containers/applicator/pill/mannitol/braintumor + +/obj/item/storage/pill_bottle/stimulant + name = "bottle of stimulant pills" + desc = "Guaranteed to give you that extra burst of energy during a long shift!" + +/obj/item/storage/pill_bottle/stimulant/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/pill/stimulant + +/obj/item/storage/pill_bottle/sansufentanyl + name = "bottle of experimental medication" + desc = "A bottle of pills developed by Interdyne Pharmaceuticals. They're used to treat Hereditary Manifold Sickness." + +/obj/item/storage/pill_bottle/sansufentanyl/PopulateContents() + . = list() + for(var/i in 1 to 6) + . += /obj/item/reagent_containers/applicator/pill/sansufentanyl + +/obj/item/storage/pill_bottle/mining + name = "bottle of patches" + desc = "Contains patches used to treat brute and burn damage." + +/obj/item/storage/pill_bottle/mining/PopulateContents() + return flatten_quantified_list(list( + /obj/item/reagent_containers/applicator/patch/aiuri = 1, + /obj/item/reagent_containers/applicator/patch/libital = 3, + )) + +/obj/item/storage/pill_bottle/zoom + name = "suspicious pill bottle" + desc = "The label is pretty old and almost unreadable, you recognize some chemical compounds." + +/obj/item/storage/pill_bottle/zoom/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/pill/zoom + +/obj/item/storage/pill_bottle/happy + name = "suspicious pill bottle" + desc = "There is a smiley on the top." + +/obj/item/storage/pill_bottle/happy/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/pill/happy + +/obj/item/storage/pill_bottle/lsd + name = "suspicious pill bottle" + desc = "There is a crude drawing which could be either a mushroom, or a deformed moon." + +/obj/item/storage/pill_bottle/lsd/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/pill/lsd + +/obj/item/storage/pill_bottle/aranesp + name = "suspicious pill bottle" + desc = "The label has 'fuck disablers' hastily scrawled in black marker." + +/obj/item/storage/pill_bottle/aranesp/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/pill/aranesp + +/obj/item/storage/pill_bottle/psicodine + name = "bottle of psicodine pills" + desc = "Contains pills used to treat mental distress and traumas." + +/obj/item/storage/pill_bottle/psicodine/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/reagent_containers/applicator/pill/psicodine + +/obj/item/storage/pill_bottle/penacid + name = "bottle of pentetic acid pills" + desc = "Contains pills to expunge radiation and toxins." + +/obj/item/storage/pill_bottle/penacid/PopulateContents() + . = list() + for(var/i in 1 to 3) + . += /obj/item/reagent_containers/applicator/pill/penacid + + +/obj/item/storage/pill_bottle/neurine + name = "bottle of neurine pills" + desc = "Contains pills to treat non-severe mental traumas." + +/obj/item/storage/pill_bottle/neurine/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/pill/neurine + +/obj/item/storage/pill_bottle/maintenance_pill + name = "bottle of maintenance pills" + desc = "An old pill bottle. It smells musty." + +/obj/item/storage/pill_bottle/maintenance_applicator/pill/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/applicator/pill/P = locate() in src + name = "bottle of [P.name]s" + +/obj/item/storage/pill_bottle/maintenance_applicator/pill/PopulateContents() + . = list() + for(var/i in 1 to rand(1,7)) + . += /obj/item/reagent_containers/applicator/pill/maintenance + +/obj/item/storage/pill_bottle/maintenance_applicator/pill/full/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/reagent_containers/applicator/pill/maintenance + +///////////////////////////////////////// Psychologist inventory pillbottles +/obj/item/storage/pill_bottle/happinesspsych + name = "happiness pills" + desc = "Contains pills used as a last resort means to temporarily stabilize depression and anxiety. WARNING: side effects may include slurred speech, drooling, and severe addiction." + +/obj/item/storage/pill_bottle/happinesspsych/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/pill/happinesspsych + +/obj/item/storage/pill_bottle/lsdpsych + name = "mindbreaker toxin pills" + desc = "!FOR THERAPEUTIC USE ONLY! Contains pills used to alleviate the symptoms of Reality Dissociation Syndrome." + +/obj/item/storage/pill_bottle/lsdpsych/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/pill/lsdpsych + +/obj/item/storage/pill_bottle/paxpsych + name = "pax pills" + desc = "Contains pills used to temporarily pacify patients that are deemed a harm to themselves or others." + +/obj/item/storage/pill_bottle/paxpsych/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/pill/paxpsych + +/obj/item/storage/pill_bottle/naturalbait + name = "freshness jar" + desc = "Full of natural fish bait." + +/obj/item/storage/pill_bottle/naturalbait/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/food/bait/natural + +/obj/item/storage/pill_bottle/ondansetron + name = "ondansetron patches" + desc = "A bottle containing patches of ondansetron, a drug used to treat nausea and vomiting. May cause drowsiness." + +/obj/item/storage/pill_bottle/ondansetron/PopulateContents() + . = list() + for(var/i in 1 to 5) + . += /obj/item/reagent_containers/applicator/patch/ondansetron + +/obj/item/storage/pill_bottle/maintenance_pill + name = "bottle of maintenance pills" + desc = "An old pill bottle. It smells musty." + +/obj/item/storage/pill_bottle/maintenance_pill/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/applicator/pill/P = locate() in src + name = "bottle of [P.name]s" + +/obj/item/storage/pill_bottle/maintenance_pill/PopulateContents() + . = list() + for(var/i in 1 to rand(1, 7)) + . += /obj/item/reagent_containers/applicator/pill/maintenance + +/obj/item/storage/pill_bottle/maintenance_pill/full/PopulateContents() + . = list() + for(var/i in 1 to 7) + . += /obj/item/reagent_containers/applicator/pill/maintenance diff --git a/code/game/objects/items/storage/sixpack.dm b/code/game/objects/items/storage/sixpack.dm index f1a950f025b..2e53989dba8 100644 --- a/code/game/objects/items/storage/sixpack.dm +++ b/code/game/objects/items/storage/sixpack.dm @@ -8,6 +8,12 @@ righthand_file = 'icons/mob/inhands/items/drinks_righthand.dmi' custom_materials = list(/datum/material/plastic = HALF_SHEET_MATERIAL_AMOUNT*1.2) max_integrity = 500 + storage_type = /datum/storage/sixcan + +/obj/item/storage/cans/Initialize(mapload) + . = ..() + + update_appearance() /obj/item/storage/cans/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] begins popping open a final cold one with the boys! It looks like [user.p_theyre()] trying to commit suicide!")) @@ -17,34 +23,20 @@ icon_state = "[initial(icon_state)][contents.len]" return ..() -/obj/item/storage/cans/Initialize(mapload) - . = ..() - update_appearance() - -/obj/item/storage/cans/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.max_total_storage = 12 - atom_storage.max_slots = 6 - atom_storage.set_holdable(list( - /obj/item/reagent_containers/cup/soda_cans, - /obj/item/reagent_containers/cup/glass/bottle/beer, - /obj/item/reagent_containers/cup/glass/bottle/ale, - /obj/item/reagent_containers/cup/glass/waterbottle, - )) - /obj/item/storage/cans/sixsoda name = "soda bottle ring" desc = "Holds six soda cans. Remember to recycle when you're done!" /obj/item/storage/cans/sixsoda/PopulateContents() + . = list() for(var/i in 1 to 6) - new /obj/item/reagent_containers/cup/soda_cans/cola(src) + . += /obj/item/reagent_containers/cup/soda_cans/cola /obj/item/storage/cans/sixbeer name = "beer can ring" desc = "Holds six beers. Remember to recycle when you're done!" /obj/item/storage/cans/sixbeer/PopulateContents() + . = list() for(var/i in 1 to 6) - new /obj/item/reagent_containers/cup/soda_cans/beer(src) + . += /obj/item/reagent_containers/cup/soda_cans/beer diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm index 06e122780b9..2ca6c3d03a2 100644 --- a/code/game/objects/items/storage/storage.dm +++ b/code/game/objects/items/storage/storage.dm @@ -4,7 +4,6 @@ w_class = WEIGHT_CLASS_NORMAL interaction_flags_click = ALLOW_RESTING|FORBID_TELEKINESIS_REACH action_slots = ALL - var/rummage_if_nodrop = TRUE /// Should we preload the contents of this type? /// BE CAREFUL, THERE'S SOME REALLY NASTY SHIT IN THIS TYPEPATH /// SANTA IS EVIL @@ -12,6 +11,120 @@ /// What storage type to use for this item var/datum/storage/storage_type = /datum/storage +/obj/item/storage/Initialize(mapload) + . = ..() + + var/datum/storage_config/initial_cofig = GLOB.initial_storage_config + initial_cofig.reset() + var/list/obj/item/items = PopulateContents(initial_cofig) + + //no hacking our way into the storages loc without going through `can_insert()` first + if(contents.len) + stack_trace("[contents.len] atoms were found inside storage before they could be inserted correctly") + return INITIALIZE_HINT_QDEL + + //Create storage only after retriving the contents. This is done so `atom_storage` values are not modified + //manually which is error prone. Either create a storage subtype with your specified values or use + //datum/storage_config to compute these values automatically + create_storage(storage_type = storage_type) + + //nothing to add + if(!items) + return + if(!islist(items)) + items = list(items) + if(!items.len) + return + + //set them to allow all items for now as we compute these values from the contents + var/pre_compute = FALSE + if(initial_cofig.compute_max_total_weight) + atom_storage.max_total_storage = INFINITY + pre_compute = TRUE + if(initial_cofig.compute_max_item_weight) + atom_storage.max_specific_storage = INFINITY + pre_compute = TRUE + if(initial_cofig.compute_max_item_count) + atom_storage.max_slots = items.len + pre_compute = TRUE + if(initial_cofig.contents_are_exceptions) + atom_storage.exception_hold = null + if(initial_cofig.whitelist_content_types) + atom_storage.can_hold = null + + var/max_total_weight = 0 + var/max_item_weight = 0 + var/list/obj/item/type_paths = initial_cofig.contents_are_exceptions || initial_cofig.whitelist_content_types ? list() : null + pre_compute |= !isnull(type_paths) + + //we now begin inserting these items the right way + for(var/obj/item/insert as anything in items) + if(ispath(insert)) + insert = new insert(null) + + //computing values from contents + if(pre_compute) + if(initial_cofig.compute_max_total_weight) + max_total_weight += insert.w_class + if(initial_cofig.compute_max_item_weight) + max_item_weight = insert.w_class > max_item_weight ? insert.w_class : max_item_weight + if(type_paths) + type_paths |= insert.type + + if(!atom_storage.can_insert(insert, messages = STORAGE_ERROR_INSERT)) + . = INITIALIZE_HINT_QDEL //this thing was shoved inside & destroyed us. Fix your storage caps and try again + insert.forceMove(src) + + if(!pre_compute || . == INITIALIZE_HINT_QDEL) + return + + //assign computed values + if(max_total_weight) + atom_storage.max_total_storage = max_total_weight + if(max_item_weight) + atom_storage.max_specific_storage = max_item_weight + if(type_paths) + atom_storage.set_holdable( + can_hold_list = initial_cofig.whitelist_content_types ? type_paths : atom_storage.can_hold, + exception_hold_list = initial_cofig.contents_are_exceptions ? type_paths : atom_storage.exception_hold + ) + +/obj/item/storage/create_storage( + max_slots, + max_specific_storage, + max_total_storage, + list/canhold, + list/canthold, + storage_type, +) + if(!QDELETED(atom_storage)) + stack_trace("Cannot re initialize storage") + return + + // If no type was passed in, default to what we already have + storage_type ||= src.storage_type + return ..() + +/obj/item/storage/atom_deconstruct(disassembled) + var/atom/drop_point = drop_location() + for(var/obj/important_thing in contents) + if(important_thing.resistance_flags & INDESTRUCTIBLE) + important_thing.forceMove(drop_point) + +/** + * Returns a list of items(object typepaths or solid atoms) to be inserted into the storage + * If you list contains solid atoms make sure they are created/moved in nullspace i.e. no bypassing storage + * restrictions else this storage will self destruct with a stack trace + * Arguments + * + * * datum/storage_config/config - the config used to set storage values based on the contents returned here + */ +/obj/item/storage/proc/PopulateContents(datum/storage_config/config) + RETURN_TYPE(/list/obj/item) + PROTECTED_PROC(TRUE) + + return NONE + /obj/item/storage/apply_fantasy_bonuses(bonus) . = ..() if(isnull(atom_storage)) // some abstract types of storage (yes i know) don't get a datum @@ -41,29 +154,6 @@ atom_storage.max_specific_storage = previous_max_storage return ..() -/obj/item/storage/Initialize(mapload) - . = ..() - - create_storage(storage_type = storage_type) - - PopulateContents() - - for (var/obj/item/item in src) - item.item_flags |= IN_STORAGE - -/obj/item/storage/create_storage( - max_slots, - max_specific_storage, - max_total_storage, - list/canhold, - list/canthold, - storage_type, -) - // If no type was passed in, default to what we already have - storage_type ||= src.storage_type - return ..() - - /obj/item/storage/AllowDrop() return FALSE @@ -77,31 +167,17 @@ SSexplosions.low_mov_atom += contents /obj/item/storage/canStrip(mob/who) - . = ..() - if(!. && rummage_if_nodrop) - return TRUE + return TRUE /obj/item/storage/doStrip(mob/who) - if(HAS_TRAIT(src, TRAIT_NODROP) && rummage_if_nodrop) + if(HAS_TRAIT(src, TRAIT_NODROP)) atom_storage.remove_all() return TRUE return ..() -/obj/item/storage/contents_explosion(severity, target) -//Cyberboss says: "USE THIS TO FILL IT, NOT INITIALIZE OR NEW" - -/obj/item/storage/proc/PopulateContents() - /obj/item/storage/proc/emptyStorage() atom_storage.remove_all() -/obj/item/storage/Destroy() - for(var/obj/important_thing in contents) - if(!(important_thing.resistance_flags & INDESTRUCTIBLE)) - continue - important_thing.forceMove(drop_location()) - return ..() - /// Returns a list of object types to be preloaded by our code /// I'll say it again, be very careful with this. We only need it for a few things /// Don't do anything stupid, please diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm deleted file mode 100644 index 010da30b124..00000000000 --- a/code/game/objects/items/storage/toolbox.dm +++ /dev/null @@ -1,700 +0,0 @@ -/obj/item/storage/toolbox - name = "toolbox" - desc = "Danger. Very robust." - icon = 'icons/obj/storage/toolbox.dmi' - icon_state = "toolbox_default" - inhand_icon_state = "toolbox_default" - lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' - obj_flags = CONDUCTS_ELECTRICITY - force = 13 - throwforce = 13 - throw_speed = 2 - throw_range = 7 - demolition_mod = 1.25 - w_class = WEIGHT_CLASS_BULKY - custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT*5) - attack_verb_continuous = list("robusts") - attack_verb_simple = list("robust") - hitsound = 'sound/items/weapons/smash.ogg' - drop_sound = 'sound/items/handling/toolbox/toolbox_drop.ogg' - pickup_sound = 'sound/items/handling/toolbox/toolbox_pickup.ogg' - material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS - var/latches = "single_latch" - var/has_latches = TRUE - wound_bonus = 5 - /// How many interactions are we currently performing - var/current_interactions = 0 - /// Items we should not interact with when left clicking - var/static/list/lmb_exception_typecache = typecacheof(list( - /obj/structure/table, - /obj/structure/rack, - /obj/structure/closet, - /obj/machinery/disposal, - )) - -/obj/item/storage/toolbox/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - if(has_latches) - if(prob(10)) - latches = "double_latch" - if(prob(1)) - latches = "triple_latch" - if(prob(0.1)) - latches = "quad_latch" // like winning the lottery, but worse - update_appearance() - atom_storage.open_sound = 'sound/items/handling/toolbox/toolbox_open.ogg' - atom_storage.rustle_sound = 'sound/items/handling/toolbox/toolbox_rustle.ogg' - AddElement(/datum/element/falling_hazard, damage = force, wound_bonus = wound_bonus, hardhat_safety = TRUE, crushes = FALSE, impact_sound = hitsound) - -/obj/item/storage/toolbox/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) - if (user.combat_mode || !user.has_hand_for_held_index(user.get_inactive_hand_index())) - return NONE - - if (is_type_in_typecache(interacting_with, lmb_exception_typecache) && !LAZYACCESS(modifiers, RIGHT_CLICK)) - return NONE - - if (current_interactions) - var/obj/item/other_tool = user.get_inactive_held_item() - if (!istype(other_tool)) // what even - return NONE - INVOKE_ASYNC(src, PROC_REF(use_tool_on), interacting_with, user, modifiers, other_tool) - return ITEM_INTERACT_SUCCESS - - if (user.get_inactive_held_item()) - user.balloon_alert(user, "hands busy!") - return ITEM_INTERACT_BLOCKING - - var/list/item_radial = list() - for (var/obj/item/tool in atom_storage.real_location) - if(is_type_in_list(tool, GLOB.tool_items)) - item_radial[tool] = tool.appearance - - if (!length(item_radial)) - return NONE - - playsound(user, 'sound/items/handling/toolbox/toolbox_open.ogg', 50) - var/obj/item/picked_item = show_radial_menu(user, interacting_with, item_radial, require_near = TRUE) - if (!picked_item) - return ITEM_INTERACT_BLOCKING - - playsound(user, 'sound/items/handling/toolbox/toolbox_rustle.ogg', 50) - if (!user.put_in_inactive_hand(picked_item)) - return ITEM_INTERACT_BLOCKING - - atom_storage.animate_parent() - if (istype(picked_item, /obj/item/weldingtool)) - var/obj/item/weldingtool/welder = picked_item - if (!welder.welding) - welder.attack_self(user) - - if (istype(picked_item, /obj/item/spess_knife)) - picked_item.attack_self(user) - - INVOKE_ASYNC(src, PROC_REF(use_tool_on), interacting_with, user, modifiers, picked_item) - return ITEM_INTERACT_SUCCESS - -/obj/item/storage/toolbox/proc/use_tool_on(atom/interacting_with, mob/living/user, list/modifiers, obj/item/picked_tool) - current_interactions += 1 - picked_tool.melee_attack_chain(user, interacting_with, list2params(modifiers)) - current_interactions -= 1 - - if (QDELETED(picked_tool) || picked_tool.loc != user || !user.CanReach(picked_tool)) - current_interactions = 0 - return - - if (current_interactions) - return - - if (istype(picked_tool, /obj/item/weldingtool)) - var/obj/item/weldingtool/welder = picked_tool - if (welder.welding) - welder.attack_self(user) - - atom_storage.attempt_insert(picked_tool, user) - -/obj/item/storage/toolbox/update_overlays() - . = ..() - if(has_latches) - . += latches - -/obj/item/storage/toolbox/suicide_act(mob/living/user) - user.visible_message(span_suicide("[user] robusts [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) - return BRUTELOSS - -/obj/item/storage/toolbox/emergency - name = "emergency toolbox" - icon_state = "red" - inhand_icon_state = "toolbox_red" - material_flags = NONE - throw_speed = 3 // red ones go faster - -/obj/item/storage/toolbox/emergency/PopulateContents() - new /obj/item/crowbar/red(src) - new /obj/item/weldingtool/mini(src) - new /obj/item/extinguisher/mini(src) - switch(rand(1,3)) - if(1) - new /obj/item/flashlight(src) - if(2) - new /obj/item/flashlight/glowstick(src) - if(3) - new /obj/item/flashlight/flare(src) - new /obj/item/radio/off(src) - -/obj/item/storage/toolbox/emergency/old - name = "rusty red toolbox" - icon_state = "toolbox_red_old" - has_latches = FALSE - material_flags = NONE - -/obj/item/storage/toolbox/mechanical - name = "mechanical toolbox" - icon_state = "blue" - inhand_icon_state = "toolbox_blue" - material_flags = NONE - /// If FALSE, someone with a ensouled soulstone can sacrifice a spirit to change the sprite of this toolbox. - var/has_soul = FALSE - -/obj/item/storage/toolbox/mechanical/PopulateContents() - new /obj/item/screwdriver(src) - new /obj/item/wrench(src) - new /obj/item/weldingtool(src) - new /obj/item/crowbar(src) - new /obj/item/analyzer(src) - new /obj/item/wirecutters(src) - -/obj/item/storage/toolbox/mechanical/old - name = "rusty blue toolbox" - icon_state = "toolbox_blue_old" - has_latches = FALSE - has_soul = TRUE - -/obj/item/storage/toolbox/mechanical/old/heirloom - name = "toolbox" //this will be named "X family toolbox" - desc = "It's seen better days." - force = 5 - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/storage/toolbox/mechanical/old/heirloom/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - -/obj/item/storage/toolbox/mechanical/old/heirloom/PopulateContents() - return - -// version of below that isn't a traitor item -/obj/item/storage/toolbox/mechanical/old/cleaner - name = "old blue toolbox" - icon_state = "oldtoolboxclean" - icon_state = "toolbox_blue_old" - -/obj/item/storage/toolbox/mechanical/old/clean // the assistant traitor toolbox, damage scales with TC inside - name = "toolbox" - desc = "An old, blue toolbox, it looks robust." - icon_state = "oldtoolboxclean" - inhand_icon_state = "toolbox_blue" - has_latches = FALSE - force = 19 - throwforce = 22 - -/obj/item/storage/toolbox/mechanical/old/clean/proc/calc_damage() - var/power = 0 - for (var/obj/item/stack/telecrystal/stored_crystals in get_all_contents()) - power += (stored_crystals.amount / 2) - force = initial(force) + power - throwforce = initial(throwforce) + power - -/obj/item/storage/toolbox/mechanical/old/clean/attack(mob/target, mob/living/user) - calc_damage() - ..() - -/obj/item/storage/toolbox/mechanical/old/clean/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - calc_damage() - ..() - -/obj/item/storage/toolbox/mechanical/old/clean/PopulateContents() - new /obj/item/screwdriver(src) - new /obj/item/wrench(src) - new /obj/item/weldingtool(src) - new /obj/item/crowbar(src) - new /obj/item/wirecutters(src) - new /obj/item/multitool(src) - new /obj/item/clothing/gloves/color/yellow(src) - -/obj/item/storage/toolbox/electrical - name = "electrical toolbox" - icon_state = "yellow" - inhand_icon_state = "toolbox_yellow" - material_flags = NONE - -/obj/item/storage/toolbox/electrical/PopulateContents() - var/pickedcolor = pick(GLOB.cable_colors) - new /obj/item/screwdriver(src) - new /obj/item/wirecutters(src) - new /obj/item/t_scanner(src) - new /obj/item/crowbar(src) - var/obj/item/stack/cable_coil/new_cable_one = new(src, MAXCOIL) - new_cable_one.set_cable_color(pickedcolor) - var/obj/item/stack/cable_coil/new_cable_two = new(src, MAXCOIL) - new_cable_two.set_cable_color(pickedcolor) - if(prob(5)) - new /obj/item/clothing/gloves/color/yellow(src) - else - var/obj/item/stack/cable_coil/new_cable_three = new(src, MAXCOIL) - new_cable_three.set_cable_color(pickedcolor) - -/obj/item/storage/toolbox/syndicate - name = "suspicious looking toolbox" - icon_state = "syndicate" - inhand_icon_state = "toolbox_syndi" - force = 15 - throwforce = 18 - material_flags = NONE - -/obj/item/storage/toolbox/syndicate/Initialize(mapload) - . = ..() - atom_storage.silent = TRUE - -/obj/item/storage/toolbox/syndicate/PopulateContents() - new /obj/item/screwdriver/nuke(src) - new /obj/item/wrench(src) - new /obj/item/weldingtool/largetank(src) - new /obj/item/crowbar/red(src) - new /obj/item/wirecutters(src, "red") - new /obj/item/multitool(src) - new /obj/item/clothing/gloves/combat(src) - -/obj/item/storage/toolbox/drone - name = "mechanical toolbox" - icon_state = "blue" - inhand_icon_state = "toolbox_blue" - material_flags = NONE - -/obj/item/storage/toolbox/drone/PopulateContents() - var/pickedcolor = pick("red","yellow","green","blue","pink","orange","cyan","white") - new /obj/item/screwdriver(src) - new /obj/item/wrench(src) - new /obj/item/weldingtool(src) - new /obj/item/crowbar(src) - new /obj/item/stack/cable_coil(src,MAXCOIL,pickedcolor) - new /obj/item/wirecutters(src) - new /obj/item/multitool(src) - -/obj/item/storage/toolbox/artistic - name = "artistic toolbox" - desc = "A toolbox painted bright green. Why anyone would store art supplies in a toolbox is beyond you, but it has plenty of extra space." - icon_state = "green" - inhand_icon_state = "artistic_toolbox" - w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox! - material_flags = NONE - -/obj/item/storage/toolbox/artistic/Initialize(mapload) - . = ..() - atom_storage.max_total_storage = 20 - atom_storage.max_slots = 11 - -/obj/item/storage/toolbox/artistic/PopulateContents() - new /obj/item/storage/crayons(src) - new /obj/item/crowbar(src) - new /obj/item/stack/pipe_cleaner_coil/red(src) - new /obj/item/stack/pipe_cleaner_coil/yellow(src) - new /obj/item/stack/pipe_cleaner_coil/blue(src) - new /obj/item/stack/pipe_cleaner_coil/green(src) - new /obj/item/stack/pipe_cleaner_coil/pink(src) - new /obj/item/stack/pipe_cleaner_coil/orange(src) - new /obj/item/stack/pipe_cleaner_coil/cyan(src) - new /obj/item/stack/pipe_cleaner_coil/white(src) - new /obj/item/stack/pipe_cleaner_coil/brown(src) - -/obj/item/storage/toolbox/medical - name = "medical toolbox" - desc = "A toolbox painted soft white and light blue. This is getting ridiculous." - icon_state = "medical" - inhand_icon_state = "toolbox_medical" - attack_verb_continuous = list("treats", "surgeries", "tends", "tends wounds on") - attack_verb_simple = list("treat", "surgery", "tend", "tend wounds on") - w_class = WEIGHT_CLASS_BULKY - material_flags = NONE - force = 5 // its for healing - wound_bonus = 25 // wounds are medical right? - /// Tray we steal the og contents from. - var/obj/item/surgery_tray/tray_type = /obj/item/surgery_tray - -/obj/item/storage/toolbox/medical/Initialize(mapload) - . = ..() - // what do any of these numbers fucking mean - atom_storage.max_total_storage = 20 - atom_storage.max_slots = 11 - -/obj/item/storage/toolbox/medical/PopulateContents() - var/atom/fake_tray = new tray_type(get_turf(src)) // not in src lest it fill storage that we need for its tools later - for(var/atom/movable/thingy in fake_tray) - thingy.forceMove(src) - qdel(fake_tray) - -/obj/item/storage/toolbox/medical/full - tray_type = /obj/item/surgery_tray/full - -/obj/item/storage/toolbox/medical/coroner - name = "coroner toolbox" - desc = "A toolbox painted soft white and dark grey. This is getting beyond ridiculous." - icon_state = "coroner" - inhand_icon_state = "toolbox_coroner" - attack_verb_continuous = list("dissects", "autopsies", "corones") - attack_verb_simple = list("dissect", "autopsy", "corone") - w_class = WEIGHT_CLASS_BULKY - material_flags = NONE - force = 17 // it's not for healing - tray_type = /obj/item/surgery_tray/full/morgue - -/obj/item/storage/toolbox/medical/coroner/Initialize(mapload) - . = ..() - AddElement(/datum/element/bane, mob_biotypes = MOB_UNDEAD, damage_multiplier = 1) //Just in case one of the tennants get uppity - -/obj/item/storage/toolbox/ammobox - name = "ammo canister" - desc = "A metal canister designed to hold ammunition" - icon_state = "ammobox" - inhand_icon_state = "ammobox" - lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' - has_latches = FALSE - drop_sound = 'sound/items/handling/ammobox_drop.ogg' - pickup_sound = 'sound/items/handling/ammobox_pickup.ogg' - var/ammo_to_spawn - -/obj/item/storage/toolbox/ammobox/PopulateContents() - if(!isnull(ammo_to_spawn)) - for(var/i in 1 to 6) - new ammo_to_spawn(src) - -/obj/item/storage/toolbox/ammobox/strilka310 - name = ".310 Strilka ammo box (Surplus?)" - desc = "It contains a few clips. Goddamn, this thing smells awful. \ - Has this been sitting in a warehouse for the last several centuries?" - ammo_to_spawn = /obj/item/ammo_box/strilka310 - -/obj/item/storage/toolbox/ammobox/strilka310/surplus - ammo_to_spawn = /obj/item/ammo_box/strilka310/surplus - -/obj/item/storage/toolbox/ammobox/wt550m9 - name = "4.6x30mm ammo box" - ammo_to_spawn = /obj/item/ammo_box/magazine/wt550m9 - -/obj/item/storage/toolbox/ammobox/wt550m9ap - name = "4.6x30mm AP ammo box" - ammo_to_spawn = /obj/item/ammo_box/magazine/wt550m9/wtap - -//repairbot assembly -/obj/item/storage/toolbox/tool_act(mob/living/user, obj/item/tool, list/modifiers) - if(!istype(tool, /obj/item/assembly/prox_sensor)) - return ..() - var/static/list/allowed_toolbox = list( - /obj/item/storage/toolbox/artistic, - /obj/item/storage/toolbox/electrical, - /obj/item/storage/toolbox/emergency, - /obj/item/storage/toolbox/mechanical, - /obj/item/storage/toolbox/syndicate, - ) - - if(!is_type_in_list(src, allowed_toolbox) && (type != /obj/item/storage/toolbox)) - return ITEM_INTERACT_BLOCKING - if(contents.len >= 1) - balloon_alert(user, "not empty!") - return ITEM_INTERACT_BLOCKING - var/static/list/toolbox_colors = list( - /obj/item/storage/toolbox = "#445eb3", - /obj/item/storage/toolbox/emergency = "#445eb3", - /obj/item/storage/toolbox/electrical = "#b77931", - /obj/item/storage/toolbox/artistic = "#378752", - /obj/item/storage/toolbox/syndicate = "#3d3d3d", - ) - var/obj/item/bot_assembly/repairbot/repair = new - repair.toolbox = type - var/new_color = toolbox_colors[type] || "#445eb3" - repair.set_color(new_color) - user.put_in_hands(repair) - repair.update_appearance() - repair.balloon_alert(user, "sensor added!") - qdel(tool) - qdel(src) - return ITEM_INTERACT_SUCCESS - -/obj/item/storage/toolbox/haunted - name = "old toolbox" - custom_materials = list(/datum/material/hauntium = SMALL_MATERIAL_AMOUNT*5) - -/obj/item/storage/toolbox/guncase - name = "gun case" - desc = "A weapon's case. Has a blood-red 'S' stamped on the cover." - icon = 'icons/obj/storage/case.dmi' - icon_state = "infiltrator_case" - lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' - inhand_icon_state = "infiltrator_case" - has_latches = FALSE - var/weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol - var/extra_to_spawn = /obj/item/ammo_box/magazine/m9mm - -/obj/item/storage/toolbox/guncase/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY - atom_storage.max_total_storage = 7 //enough to hold ONE bulky gun and the ammo boxes - atom_storage.max_slots = 4 - -/obj/item/storage/toolbox/guncase/PopulateContents() - new weapon_to_spawn (src) - for(var/i in 1 to 3) - new extra_to_spawn (src) - -/obj/item/storage/toolbox/guncase/traitor - name = "makarov gun case" - desc = "A weapon's case. Has a blood-red 'S' stamped on the cover. There seems to be a strange switch along the side inside a plastic flap." - icon_state = "pistol_case" - base_icon_state = "pistol_case" - // What ammo box do we spawn in our case? - var/ammo_box_to_spawn = /obj/item/ammo_box/c9mm - // Timer for the bomb in the case. - var/explosion_timer - // Whether or not our case is exploding. Used for determining sprite changes. - var/currently_exploding = FALSE - -/obj/item/storage/toolbox/guncase/traitor/Initialize(mapload) - . = ..() - register_context() - -/obj/item/storage/toolbox/guncase/traitor/examine(mob/user) - . = ..() - . += span_notice("Activate the Evidence Disposal Explosive using Alt-Right-Click.") - -/obj/item/storage/toolbox/guncase/traitor/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = ..() - - context[SCREENTIP_CONTEXT_ALT_RMB] = "Activate Evidence Disposal Explosive" - return CONTEXTUAL_SCREENTIP_SET - -/obj/item/storage/toolbox/guncase/traitor/PopulateContents() - new weapon_to_spawn (src) - for(var/i in 1 to 2) - new extra_to_spawn (src) - new ammo_box_to_spawn(src) - -/obj/item/storage/toolbox/guncase/traitor/update_icon_state() - . = ..() - if(currently_exploding) - icon_state = "[base_icon_state]_exploding" - else - icon_state = "[base_icon_state]" - -/obj/item/storage/toolbox/guncase/traitor/click_alt_secondary(mob/user) - . = ..() - if(currently_exploding) - user.balloon_alert(user, "already exploding!") - return - - var/i_dont_even_think_once_about_blowing_stuff_up = tgui_alert(user, "Would you like to activate the evidence disposal bomb now?", "BYE BYE", list("Yes","No")) - - if(i_dont_even_think_once_about_blowing_stuff_up != "Yes" || currently_exploding || QDELETED(user) || QDELETED(src) || user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING)) - return - - explosion_timer = addtimer(CALLBACK(src, PROC_REF(think_fast_chucklenuts)), 5 SECONDS, (TIMER_UNIQUE|TIMER_OVERRIDE)) - to_chat(user, span_warning("You prime [src]'s evidence disposal bomb!")) - log_bomber(user, "has activated a", src, "for detonation") - playsound(src, 'sound/items/weapons/armbomb.ogg', 50, TRUE) - currently_exploding = TRUE - update_appearance() - -/// proc to handle our detonation -/obj/item/storage/toolbox/guncase/traitor/proc/think_fast_chucklenuts() - explosion(src, devastation_range = 0, heavy_impact_range = 0, light_impact_range = 2, explosion_cause = src) - qdel(src) - -/obj/item/storage/toolbox/guncase/traitor/ammunition - name = "makarov 9mm magazine case" - weapon_to_spawn = /obj/item/ammo_box/magazine/m9mm - -/obj/item/storage/toolbox/guncase/traitor/donksoft - name = "\improper Donksoft riot pistol gun case" - weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/toy/riot/clandestine - extra_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot - ammo_box_to_spawn = /obj/item/ammo_box/foambox/riot - -/obj/item/storage/toolbox/guncase/traitor/ammunition/donksoft - name = "\improper Donksoft riot pistol magazine case" - weapon_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot - extra_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot - ammo_box_to_spawn = /obj/item/ammo_box/foambox/riot - -/obj/item/storage/toolbox/guncase/bulldog - name = "bulldog gun case" - weapon_to_spawn = /obj/item/gun/ballistic/shotgun/bulldog - extra_to_spawn = /obj/item/ammo_box/magazine/m12g - -/obj/item/storage/toolbox/guncase/c20r - name = "c-20r gun case" - weapon_to_spawn = /obj/item/gun/ballistic/automatic/c20r - extra_to_spawn = /obj/item/ammo_box/magazine/smgm45 - -/obj/item/storage/toolbox/guncase/smartgun - name = "adielle smartgun case" - weapon_to_spawn = /obj/item/gun/ballistic/automatic/smartgun - extra_to_spawn = /obj/item/ammo_box/magazine/smartgun - -/obj/item/storage/toolbox/guncase/clandestine - name = "clandestine gun case" - weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/clandestine - extra_to_spawn = /obj/item/ammo_box/magazine/m10mm - -/obj/item/storage/toolbox/guncase/m90gl - name = "m-90gl gun case" - weapon_to_spawn = /obj/item/gun/ballistic/automatic/m90 - extra_to_spawn = /obj/item/ammo_box/magazine/m223 - -/obj/item/storage/toolbox/guncase/m90gl/PopulateContents() - new weapon_to_spawn (src) - for(var/i in 1 to 2) - new extra_to_spawn (src) - new /obj/item/ammo_box/a40mm/rubber (src) - -/obj/item/storage/toolbox/guncase/rocketlauncher - name = "rocket launcher gun case" - weapon_to_spawn = /obj/item/gun/ballistic/rocketlauncher - extra_to_spawn = /obj/item/ammo_box/rocket - -/obj/item/storage/toolbox/guncase/rocketlauncher/PopulateContents() - new weapon_to_spawn (src) - new extra_to_spawn (src) - -/obj/item/storage/toolbox/guncase/revolver - name = "revolver gun case" - weapon_to_spawn = /obj/item/gun/ballistic/revolver/badass/nuclear - extra_to_spawn = /obj/item/ammo_box/a357 - -/obj/item/storage/toolbox/guncase/sword_and_board - name = "energy sword and shield weapon case" - weapon_to_spawn = /obj/item/melee/energy/sword - extra_to_spawn = /obj/item/shield/energy - -/obj/item/storage/toolbox/guncase/sword_and_board/PopulateContents() - new weapon_to_spawn (src) - new extra_to_spawn (src) - new /obj/item/clothing/head/costume/knight (src) - -/obj/item/storage/toolbox/guncase/cqc - name = "\improper CQC equipment case" - weapon_to_spawn = /obj/item/book/granter/martial/cqc - extra_to_spawn = /obj/item/storage/box/syndie_kit/imp_stealth - -/obj/item/storage/toolbox/guncase/cqc/PopulateContents() - new weapon_to_spawn (src) - new extra_to_spawn (src) - new /obj/item/clothing/head/costume/snakeeater (src) - new /obj/item/storage/fancy/cigarettes/cigpack_syndicate (src) - -/obj/item/clothing/head/costume/snakeeater - name = "strange bandana" - desc = "A bandana. It seems to have a little carp embroidered on the inside, as well as the kanji '魚'." - icon_state = "snake_eater" - inhand_icon_state = null - clothing_traits = list(TRAIT_FISH_EATER) - -/obj/item/clothing/head/costume/knight - name = "fake medieval helmet" - desc = "A classic metal helmet. Though, this one seems to be very obviously fake..." - icon = 'icons/obj/clothing/head/helmet.dmi' - worn_icon = 'icons/mob/clothing/head/helmet.dmi' - icon_state = "knight_green" - inhand_icon_state = "knight_helmet" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT - flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH - dog_fashion = null - -/obj/item/storage/toolbox/guncase/doublesword - name = "double-bladed energy sword weapon case" - weapon_to_spawn = /obj/item/dualsaber - extra_to_spawn = /obj/item/soap/syndie - -/obj/item/storage/toolbox/guncase/doublesword/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY - atom_storage.max_total_storage = 10 //it'll hold enough - atom_storage.max_slots = 5 - -/obj/item/storage/toolbox/guncase/doublesword/PopulateContents() - new weapon_to_spawn (src) - new extra_to_spawn (src) - new /obj/item/mod/module/noslip (src) - new /obj/item/reagent_containers/hypospray/medipen/methamphetamine (src) - new /obj/item/clothing/under/rank/prisoner/nosensor (src) - -/obj/item/storage/toolbox/guncase/soviet - name = "ancient gun case" - desc = "A weapon's case. Has the symbol of the Third Soviet Union stamped on the side." - icon_state = "sakhno_case" - inhand_icon_state = "sakhno_case" - weapon_to_spawn = /obj/effect/spawner/random/sakhno - extra_to_spawn = /obj/effect/spawner/random/sakhno/ammo - -/obj/item/storage/toolbox/guncase/monkeycase - name = "monkey gun case" - desc = "Everything a monkey needs to truly go ape-shit. There's a paw-shaped hand scanner lock on the front of the case." - -/obj/item/storage/toolbox/guncase/monkeycase/Initialize(mapload) - . = ..() - atom_storage.locked = STORAGE_SOFT_LOCKED - -/obj/item/storage/toolbox/guncase/monkeycase/attack_self(mob/user, modifiers) - if(!monkey_check(user)) - return - return ..() - -/obj/item/storage/toolbox/guncase/monkeycase/attack_self_secondary(mob/user, modifiers) - attack_self(user, modifiers) - return - -/obj/item/storage/toolbox/guncase/monkeycase/attack_hand(mob/user, list/modifiers) - if(!monkey_check(user)) - return - return ..() - -/obj/item/storage/toolbox/guncase/monkeycase/proc/monkey_check(mob/user) - if(atom_storage.locked == STORAGE_NOT_LOCKED) - return TRUE - - if(is_simian(user)) - atom_storage.locked = STORAGE_NOT_LOCKED - to_chat(user, span_notice("You place your paw on the paw scanner, and hear a soft click as [src] unlocks!")) - playsound(src, 'sound/items/click.ogg', 25, TRUE) - return TRUE - to_chat(user, span_warning("You put your hand on the hand scanner, and it rejects it with an angry chimpanzee screech!")) - playsound(src, SFX_SCREECH, 75, TRUE) - return FALSE - -/obj/item/storage/toolbox/guncase/monkeycase/PopulateContents() - switch(rand(1, 3)) - if(1) - // Uzi with a boxcutter. - new /obj/item/gun/ballistic/automatic/mini_uzi/chimpgun(src) - new /obj/item/ammo_box/magazine/uzim9mm(src) - new /obj/item/ammo_box/magazine/uzim9mm(src) - new /obj/item/boxcutter/extended(src) - if(2) - // Thompson with a boxcutter. - new /obj/item/gun/ballistic/automatic/tommygun/chimpgun(src) - new /obj/item/ammo_box/magazine/tommygunm45(src) - new /obj/item/ammo_box/magazine/tommygunm45(src) - new /obj/item/boxcutter/extended(src) - if(3) - // M1911 with a switchblade and an extra banana bomb. - new /obj/item/gun/ballistic/automatic/pistol/m1911/chimpgun(src) - new /obj/item/ammo_box/magazine/m45(src) - new /obj/item/ammo_box/magazine/m45(src) - new /obj/item/switchblade/extended(src) - new /obj/item/food/grown/banana/bunch/monkeybomb(src) - - // Banana bomb! Basically a tiny flashbang for monkeys. - new /obj/item/food/grown/banana/bunch/monkeybomb(src) - // Somewhere to store it all. - new /obj/item/storage/backpack/messenger(src) diff --git a/code/game/objects/items/storage/toolboxes/_toolbox.dm b/code/game/objects/items/storage/toolboxes/_toolbox.dm new file mode 100644 index 00000000000..22318defc6e --- /dev/null +++ b/code/game/objects/items/storage/toolboxes/_toolbox.dm @@ -0,0 +1,159 @@ +/obj/item/storage/toolbox + name = "toolbox" + desc = "Danger. Very robust." + icon = 'icons/obj/storage/toolbox.dmi' + icon_state = "toolbox_default" + inhand_icon_state = "toolbox_default" + lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' + obj_flags = CONDUCTS_ELECTRICITY + force = 13 + throwforce = 13 + throw_speed = 2 + throw_range = 7 + demolition_mod = 1.25 + w_class = WEIGHT_CLASS_BULKY + custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT*5) + attack_verb_continuous = list("robusts") + attack_verb_simple = list("robust") + hitsound = 'sound/items/weapons/smash.ogg' + drop_sound = 'sound/items/handling/toolbox/toolbox_drop.ogg' + pickup_sound = 'sound/items/handling/toolbox/toolbox_pickup.ogg' + material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS + storage_type = /datum/storage/toolbox + + var/latches = "single_latch" + var/has_latches = TRUE + wound_bonus = 5 + /// How many interactions are we currently performing + var/current_interactions = 0 + /// Items we should not interact with when left clicking + var/static/list/lmb_exception_typecache = typecacheof(list( + /obj/structure/table, + /obj/structure/rack, + /obj/structure/closet, + /obj/machinery/disposal, + )) + +/obj/item/storage/toolbox/Initialize(mapload) + . = ..() + if(has_latches) + if(prob(10)) + latches = "double_latch" + if(prob(1)) + latches = "triple_latch" + if(prob(0.1)) + latches = "quad_latch" // like winning the lottery, but worse + update_appearance() + AddElement(/datum/element/falling_hazard, damage = force, wound_bonus = wound_bonus, hardhat_safety = TRUE, crushes = FALSE, impact_sound = hitsound) + +/obj/item/storage/toolbox/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + if (user.combat_mode || !user.has_hand_for_held_index(user.get_inactive_hand_index())) + return NONE + + if (is_type_in_typecache(interacting_with, lmb_exception_typecache) && !LAZYACCESS(modifiers, RIGHT_CLICK)) + return NONE + + if (current_interactions) + var/obj/item/other_tool = user.get_inactive_held_item() + if (!istype(other_tool)) // what even + return NONE + INVOKE_ASYNC(src, PROC_REF(use_tool_on), interacting_with, user, modifiers, other_tool) + return ITEM_INTERACT_SUCCESS + + if (user.get_inactive_held_item()) + user.balloon_alert(user, "hands busy!") + return ITEM_INTERACT_BLOCKING + + var/list/item_radial = list() + for (var/obj/item/tool in atom_storage.real_location) + if(is_type_in_list(tool, GLOB.tool_items)) + item_radial[tool] = tool.appearance + + if (!length(item_radial)) + return NONE + + playsound(user, 'sound/items/handling/toolbox/toolbox_open.ogg', 50) + var/obj/item/picked_item = show_radial_menu(user, interacting_with, item_radial, require_near = TRUE) + if (!picked_item) + return ITEM_INTERACT_BLOCKING + + playsound(user, 'sound/items/handling/toolbox/toolbox_rustle.ogg', 50) + if (!user.put_in_inactive_hand(picked_item)) + return ITEM_INTERACT_BLOCKING + + atom_storage.animate_parent() + if (istype(picked_item, /obj/item/weldingtool)) + var/obj/item/weldingtool/welder = picked_item + if (!welder.welding) + welder.attack_self(user) + + if (istype(picked_item, /obj/item/spess_knife)) + picked_item.attack_self(user) + + INVOKE_ASYNC(src, PROC_REF(use_tool_on), interacting_with, user, modifiers, picked_item) + return ITEM_INTERACT_SUCCESS + +/obj/item/storage/toolbox/proc/use_tool_on(atom/interacting_with, mob/living/user, list/modifiers, obj/item/picked_tool) + current_interactions += 1 + picked_tool.melee_attack_chain(user, interacting_with, list2params(modifiers)) + current_interactions -= 1 + + if (QDELETED(picked_tool) || picked_tool.loc != user || !user.CanReach(picked_tool)) + current_interactions = 0 + return + + if (current_interactions) + return + + if (istype(picked_tool, /obj/item/weldingtool)) + var/obj/item/weldingtool/welder = picked_tool + if (welder.welding) + welder.attack_self(user) + + atom_storage.attempt_insert(picked_tool, user) + +/obj/item/storage/toolbox/update_overlays() + . = ..() + if(has_latches) + . += latches + +/obj/item/storage/toolbox/suicide_act(mob/living/user) + user.visible_message(span_suicide("[user] robusts [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) + return BRUTELOSS + +//repairbot assembly +/obj/item/storage/toolbox/tool_act(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/assembly/prox_sensor)) + return ..() + + var/static/list/allowed_toolbox = list( + /obj/item/storage/toolbox/artistic, + /obj/item/storage/toolbox/electrical, + /obj/item/storage/toolbox/emergency, + /obj/item/storage/toolbox/mechanical, + /obj/item/storage/toolbox/syndicate, + ) + + if(!is_type_in_list(src, allowed_toolbox) && (type != /obj/item/storage/toolbox)) + return ITEM_INTERACT_BLOCKING + if(contents.len >= 1) + balloon_alert(user, "not empty!") + return ITEM_INTERACT_BLOCKING + var/static/list/toolbox_colors = list( + /obj/item/storage/toolbox = "#445eb3", + /obj/item/storage/toolbox/emergency = "#445eb3", + /obj/item/storage/toolbox/electrical = "#b77931", + /obj/item/storage/toolbox/artistic = "#378752", + /obj/item/storage/toolbox/syndicate = "#3d3d3d", + ) + var/obj/item/bot_assembly/repairbot/repair = new(src) + repair.toolbox = type + var/_color = toolbox_colors[type] || "#445eb3" + repair.set_color(_color) + user.put_in_hands(repair) + repair.update_appearance() + repair.balloon_alert(user, "sensor added!") + qdel(tool) + qdel(src) + return ITEM_INTERACT_SUCCESS diff --git a/code/game/objects/items/storage/toolboxes/emergency.dm b/code/game/objects/items/storage/toolboxes/emergency.dm new file mode 100644 index 00000000000..3b3d59c632c --- /dev/null +++ b/code/game/objects/items/storage/toolboxes/emergency.dm @@ -0,0 +1,43 @@ +/obj/item/storage/toolbox/emergency + name = "emergency toolbox" + icon_state = "red" + inhand_icon_state = "toolbox_red" + material_flags = NONE + throw_speed = 3 // red ones go faster + +/obj/item/storage/toolbox/emergency/PopulateContents() + var/obj/item/random_item + switch(rand(1,3)) + if(1) + random_item = /obj/item/flashlight + if(2) + random_item = /obj/item/flashlight/glowstick + if(3) + random_item = /obj/item/flashlight/flare + + return list( + /obj/item/crowbar/red, + /obj/item/weldingtool/mini, + /obj/item/extinguisher/mini, + random_item, + /obj/item/radio/off, + ) + +/obj/item/storage/toolbox/emergency/old + name = "rusty red toolbox" + icon_state = "toolbox_red_old" + has_latches = FALSE + material_flags = NONE + storage_type = /datum/storage/toolbox/ancient_bundle + +/obj/item/storage/toolbox/emergency/old/ancientbundle/PopulateContents() + return list( + /obj/item/card/emag, // 4 tc + /obj/item/card/emag/doorjack, //emag used to do both. 3 tc + /obj/item/pen/sleepy, // 4 tc + /obj/item/reagent_containers/applicator/pill/cyanide, + /obj/item/chameleon, //its not the original cloaking device, but it will do. 8 tc + /obj/item/gun/ballistic/revolver, // 13 tc old one stays in the old box + /obj/item/implanter/freedom, // 5 tc + /obj/item/stack/telecrystal, //The failsafe/self destruct isn't an item we can physically include in the kit, but 1 TC is technically enough to buy the equivalent. + ) diff --git a/code/game/objects/items/storage/toolboxes/fishing.dm b/code/game/objects/items/storage/toolboxes/fishing.dm new file mode 100644 index 00000000000..ac8bae404d2 --- /dev/null +++ b/code/game/objects/items/storage/toolboxes/fishing.dm @@ -0,0 +1,59 @@ +/obj/item/storage/toolbox/fishing + name = "fishing toolbox" + desc = "Contains everything you need for your fishing trip." + icon_state = "fishing" + inhand_icon_state = "artistic_toolbox" + material_flags = NONE + custom_price = PAYCHECK_CREW * 3 + storage_type = /datum/storage/toolbox/fishing + + ///How much holding this affects fishing difficulty + var/fishing_modifier = -4 + +/obj/item/storage/toolbox/fishing/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier, ITEM_SLOT_HANDS) + +/obj/item/storage/toolbox/fishing/PopulateContents() + return list( + /obj/item/bait_can/worm, + /obj/item/fishing_rod/unslotted, + /obj/item/fishing_hook, + /obj/item/fishing_line, + /obj/item/paper/paperslip/fishing_tip, + ) + +/obj/item/storage/toolbox/fishing/small + name = "compact fishing toolbox" + desc = "Contains everything you need for your fishing trip. Except for the bait." + w_class = WEIGHT_CLASS_NORMAL + force = 5 + throwforce = 5 + storage_type = /datum/storage/toolbox/fishing/small + +/obj/item/storage/toolbox/fishing/small/PopulateContents() + return list( + /obj/item/fishing_rod/unslotted, + /obj/item/fishing_hook, + /obj/item/fishing_line, + /obj/item/paper/paperslip/fishing_tip, + ) + +/obj/item/storage/toolbox/fishing/master + name = "super fishing toolbox" + desc = "Contains (almost) EVERYTHING you need for your fishing trip." + icon_state = "gold" + inhand_icon_state = "toolbox_gold" + fishing_modifier = -10 + +/obj/item/storage/toolbox/fishing/master/PopulateContents() + return list( + /obj/item/fishing_rod/telescopic/master, + /obj/item/storage/box/fishing_hooks/master, + /obj/item/storage/box/fishing_lines/master, + /obj/item/bait_can/super_baits, + /obj/item/reagent_containers/cup/fish_feed, + /obj/item/aquarium_kit, + /obj/item/fish_analyzer, + ) diff --git a/code/game/objects/items/storage/toolboxes/mechanical.dm b/code/game/objects/items/storage/toolboxes/mechanical.dm new file mode 100644 index 00000000000..978b56c0613 --- /dev/null +++ b/code/game/objects/items/storage/toolboxes/mechanical.dm @@ -0,0 +1,74 @@ +/obj/item/storage/toolbox/mechanical + name = "mechanical toolbox" + icon_state = "blue" + inhand_icon_state = "toolbox_blue" + material_flags = NONE + /// If FALSE, someone with a ensouled soulstone can sacrifice a spirit to change the sprite of this toolbox. + var/has_soul = FALSE + +/obj/item/storage/toolbox/mechanical/PopulateContents() + return list( + /obj/item/screwdriver, + /obj/item/wrench, + /obj/item/weldingtool, + /obj/item/crowbar, + /obj/item/analyzer, + /obj/item/wirecutters, + ) + +/obj/item/storage/toolbox/mechanical/old + name = "rusty blue toolbox" + icon_state = "toolbox_blue_old" + has_latches = FALSE + has_soul = TRUE + +/obj/item/storage/toolbox/mechanical/old/heirloom + name = "toolbox" //this will be named "X family toolbox" + desc = "It's seen better days." + force = 5 + w_class = WEIGHT_CLASS_NORMAL + storage_type = /datum/storage/toolbox/old_heirloom + +/obj/item/storage/toolbox/mechanical/old/heirloom/PopulateContents() + return NONE + +// version of below that isn't a traitor item +/obj/item/storage/toolbox/mechanical/old/cleaner + name = "old blue toolbox" + icon_state = "oldtoolboxclean" + icon_state = "toolbox_blue_old" + +/obj/item/storage/toolbox/mechanical/old/clean // the assistant traitor toolbox, damage scales with TC inside + name = "toolbox" + desc = "An old, blue toolbox, it looks robust." + icon_state = "oldtoolboxclean" + inhand_icon_state = "toolbox_blue" + has_latches = FALSE + force = 19 + throwforce = 22 + +/obj/item/storage/toolbox/mechanical/old/clean/proc/calc_damage() + var/power = 0 + for (var/obj/item/stack/telecrystal/stored_crystals in get_all_contents()) + power += (stored_crystals.amount / 2) + force = initial(force) + power + throwforce = initial(throwforce) + power + +/obj/item/storage/toolbox/mechanical/old/clean/attack(mob/target, mob/living/user) + calc_damage() + ..() + +/obj/item/storage/toolbox/mechanical/old/clean/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + calc_damage() + ..() + +/obj/item/storage/toolbox/mechanical/old/clean/PopulateContents() + return list( + /obj/item/screwdriver, + /obj/item/wrench, + /obj/item/weldingtool, + /obj/item/crowbar, + /obj/item/wirecutters, + /obj/item/multitool, + /obj/item/clothing/gloves/color/yellow, + ) diff --git a/code/game/objects/items/storage/toolboxes/medical.dm b/code/game/objects/items/storage/toolboxes/medical.dm new file mode 100644 index 00000000000..cde39b4f38c --- /dev/null +++ b/code/game/objects/items/storage/toolboxes/medical.dm @@ -0,0 +1,42 @@ +/obj/item/storage/toolbox/medical + name = "medical toolbox" + desc = "A toolbox painted soft white and light blue. This is getting ridiculous." + icon_state = "medical" + inhand_icon_state = "toolbox_medical" + attack_verb_continuous = list("treats", "surgeries", "tends", "tends wounds on") + attack_verb_simple = list("treat", "surgery", "tend", "tend wounds on") + w_class = WEIGHT_CLASS_BULKY + material_flags = NONE + force = 5 // its for healing + wound_bonus = 25 // wounds are medical right? + /// Tray we steal the og contents from. + var/obj/item/surgery_tray/tray_type = /obj/item/surgery_tray + +/obj/item/storage/toolbox/medical/PopulateContents(datum/storage_config/config) + config.compute_max_values() + + . = list() + var/atom/fake_tray = new tray_type(null) // not in src lest it fill storage that we need for its tools later + for(var/atom/movable/thingy in fake_tray) + thingy.moveToNullspace() + . += thingy + qdel(fake_tray) + +/obj/item/storage/toolbox/medical/full + tray_type = /obj/item/surgery_tray/full + +/obj/item/storage/toolbox/medical/coroner + name = "coroner toolbox" + desc = "A toolbox painted soft white and dark grey. This is getting beyond ridiculous." + icon_state = "coroner" + inhand_icon_state = "toolbox_coroner" + attack_verb_continuous = list("dissects", "autopsies", "corones") + attack_verb_simple = list("dissect", "autopsy", "corone") + w_class = WEIGHT_CLASS_BULKY + material_flags = NONE + force = 17 // it's not for healing + tray_type = /obj/item/surgery_tray/full/morgue + +/obj/item/storage/toolbox/medical/coroner/Initialize(mapload) + . = ..() + AddElement(/datum/element/bane, mob_biotypes = MOB_UNDEAD, damage_multiplier = 1) //Just in case one of the tennants get uppity diff --git a/code/game/objects/items/storage/toolboxes/misc.dm b/code/game/objects/items/storage/toolboxes/misc.dm new file mode 100644 index 00000000000..cb2061955fe --- /dev/null +++ b/code/game/objects/items/storage/toolboxes/misc.dm @@ -0,0 +1,47 @@ +/obj/item/storage/toolbox/drone + name = "mechanical toolbox" + icon_state = "blue" + inhand_icon_state = "toolbox_blue" + material_flags = NONE + +/obj/item/storage/toolbox/drone/PopulateContents() + var/obj/item/stack/cable_coil/cable = new (null, MAXCOIL) + cable.set_cable_color(pick(GLOB.cable_colors)) + + return list( + /obj/item/screwdriver, + /obj/item/wrench, + /obj/item/weldingtool, + /obj/item/crowbar, + cable, + /obj/item/wirecutters, + /obj/item/multitool, + ) + +/obj/item/storage/toolbox/artistic + name = "artistic toolbox" + desc = "A toolbox painted bright green. Why anyone would store art supplies in a toolbox is beyond you, but it has plenty of extra space." + icon_state = "green" + inhand_icon_state = "artistic_toolbox" + w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox! + material_flags = NONE + storage_type = /datum/storage/toolbox/artistic + +/obj/item/storage/toolbox/artistic/PopulateContents() + return list( + /obj/item/storage/crayons, + /obj/item/crowbar, + /obj/item/stack/pipe_cleaner_coil/red, + /obj/item/stack/pipe_cleaner_coil/yellow, + /obj/item/stack/pipe_cleaner_coil/blue, + /obj/item/stack/pipe_cleaner_coil/green, + /obj/item/stack/pipe_cleaner_coil/pink, + /obj/item/stack/pipe_cleaner_coil/orange, + /obj/item/stack/pipe_cleaner_coil/cyan, + /obj/item/stack/pipe_cleaner_coil/white, + /obj/item/stack/pipe_cleaner_coil/brown, + ) + +/obj/item/storage/toolbox/haunted + name = "old toolbox" + custom_materials = list(/datum/material/hauntium = SMALL_MATERIAL_AMOUNT*5) diff --git a/code/game/objects/items/storage/toolboxes/service.dm b/code/game/objects/items/storage/toolboxes/service.dm new file mode 100644 index 00000000000..cdea077462a --- /dev/null +++ b/code/game/objects/items/storage/toolboxes/service.dm @@ -0,0 +1,33 @@ +/obj/item/storage/toolbox/electrical + name = "electrical toolbox" + icon_state = "yellow" + inhand_icon_state = "toolbox_yellow" + material_flags = NONE + storage_type = /datum/storage/toolbox/electrical + +/obj/item/storage/toolbox/electrical/PopulateContents() + var/pickedcolor = pick(GLOB.cable_colors) + + var/obj/item/insert + if(prob(5)) + insert = /obj/item/clothing/gloves/color/yellow + else + var/obj/item/stack/cable_coil/new_cable_three = new (null, MAXCOIL) + new_cable_three.set_cable_color(pickedcolor) + insert = new_cable_three + + var/obj/item/stack/cable_coil/new_cable_one = new (null, MAXCOIL) + new_cable_one.set_cable_color(pickedcolor) + var/obj/item/stack/cable_coil/new_cable_two = new (null, MAXCOIL) + new_cable_two.set_cable_color(pickedcolor) + + return list( + /obj/item/screwdriver, + /obj/item/wirecutters, + /obj/item/t_scanner, + /obj/item/crowbar, + /obj/item/clothing/gloves/color/yellow, + new_cable_one, + new_cable_two, + insert, + ) diff --git a/code/game/objects/items/storage/toolboxes/weapons.dm b/code/game/objects/items/storage/toolboxes/weapons.dm new file mode 100644 index 00000000000..90f545abcb5 --- /dev/null +++ b/code/game/objects/items/storage/toolboxes/weapons.dm @@ -0,0 +1,352 @@ +/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(datum/storage_config/config) + config.compute_max_item_weight = TRUE + config.compute_max_total_weight = TRUE + + return list( + /obj/item/gun_maintenance_supplies, + /obj/item/gun_maintenance_supplies, + /obj/item/gun_maintenance_supplies, + ) + +/obj/item/storage/toolbox/ammobox + name = "ammo canister" + desc = "A metal canister designed to hold ammunition" + icon_state = "ammobox" + inhand_icon_state = "ammobox" + lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' + has_latches = FALSE + drop_sound = 'sound/items/handling/ammobox_drop.ogg' + pickup_sound = 'sound/items/handling/ammobox_pickup.ogg' + ///The ammo box to spawn + var/obj/item/ammo_box/ammo_to_spawn + +/obj/item/storage/toolbox/ammobox/PopulateContents() + if(isnull(ammo_to_spawn)) + return NONE + + . = list() + for(var/_ in 1 to 6) + . += ammo_to_spawn + +/obj/item/storage/toolbox/ammobox/strilka310 + name = ".310 Strilka ammo box (Surplus?)" + desc = "It contains a few clips. Goddamn, this thing smells awful. \ + Has this been sitting in a warehouse for the last several centuries?" + ammo_to_spawn = /obj/item/ammo_box/strilka310 + +/obj/item/storage/toolbox/ammobox/strilka310/surplus + ammo_to_spawn = /obj/item/ammo_box/strilka310/surplus + +/obj/item/storage/toolbox/ammobox/wt550m9 + name = "4.6x30mm ammo box" + ammo_to_spawn = /obj/item/ammo_box/magazine/wt550m9 + +/obj/item/storage/toolbox/ammobox/wt550m9ap + name = "4.6x30mm AP ammo box" + ammo_to_spawn = /obj/item/ammo_box/magazine/wt550m9/wtap + +/obj/item/storage/toolbox/syndicate + name = "suspicious looking toolbox" + icon_state = "syndicate" + inhand_icon_state = "toolbox_syndi" + force = 15 + throwforce = 18 + material_flags = NONE + storage_type = /datum/storage/toolbox/syndicate + +/obj/item/storage/toolbox/syndicate/PopulateContents() + return list( + /obj/item/screwdriver/nuke, + /obj/item/wrench, + /obj/item/weldingtool/largetank, + /obj/item/crowbar/red, + new /obj/item/wirecutters(null, "red"), + /obj/item/multitool, + /obj/item/clothing/gloves/combat, + ) + +/obj/item/storage/toolbox/guncase + name = "gun case" + desc = "A weapon's case. Has a blood-red 'S' stamped on the cover." + icon = 'icons/obj/storage/case.dmi' + icon_state = "infiltrator_case" + lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' + inhand_icon_state = "infiltrator_case" + has_latches = FALSE + storage_type = /datum/storage/toolbox/guncase + + ///Weapon to spawn in this toolbox + var/weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol + ///Extra item to spawn in this toolbox + var/extra_to_spawn = /obj/item/ammo_box/magazine/m9mm + +/obj/item/storage/toolbox/guncase/PopulateContents() + new weapon_to_spawn(src) + for(var/i in 1 to 3) + new extra_to_spawn(src) + + . = list() + for(var/obj/item/insert as anything in src) + insert.moveToNullspace() + . += insert + +/obj/item/storage/toolbox/guncase/traitor + name = "makarov gun case" + desc = "A weapon's case. Has a blood-red 'S' stamped on the cover. There seems to be a strange switch along the side inside a plastic flap." + icon_state = "pistol_case" + base_icon_state = "pistol_case" + // What ammo box do we spawn in our case? + var/ammo_box_to_spawn = /obj/item/ammo_box/c9mm + // Timer for the bomb in the case. + var/explosion_timer + // Whether or not our case is exploding. Used for determining sprite changes. + var/currently_exploding = FALSE + +/obj/item/storage/toolbox/guncase/traitor/Initialize(mapload) + . = ..() + register_context() + +/obj/item/storage/toolbox/guncase/traitor/examine(mob/user) + . = ..() + . += span_notice("Activate the Evidence Disposal Explosive using Alt-Right-Click.") + +/obj/item/storage/toolbox/guncase/traitor/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + + context[SCREENTIP_CONTEXT_ALT_RMB] = "Activate Evidence Disposal Explosive" + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/storage/toolbox/guncase/traitor/PopulateContents() + . = list() + + . += weapon_to_spawn + for(var/i in 1 to 2) + . += extra_to_spawn + . += ammo_box_to_spawn + +/obj/item/storage/toolbox/guncase/traitor/update_icon_state() + . = ..() + if(currently_exploding) + icon_state = "[base_icon_state]_exploding" + else + icon_state = "[base_icon_state]" + +/obj/item/storage/toolbox/guncase/traitor/click_alt_secondary(mob/user) + . = ..() + var/i_dont_even_think_once_about_blowing_stuff_up = tgui_alert(user, "Would you like to activate the evidence disposal bomb now?", "BYE BYE", list("Yes","No")) + if(i_dont_even_think_once_about_blowing_stuff_up == "No") + return + explosion_timer = addtimer(CALLBACK(src, PROC_REF(think_fast_chucklenuts)), 5 SECONDS, (TIMER_UNIQUE|TIMER_OVERRIDE)) + to_chat(user, span_warning("You prime [src]'s evidence disposal bomb!")) + log_bomber(user, "has activated a", src, "for detonation") + playsound(src, 'sound/items/weapons/armbomb.ogg', 50, TRUE) + currently_exploding = TRUE + update_appearance() + +/// proc to handle our detonation +/obj/item/storage/toolbox/guncase/traitor/proc/think_fast_chucklenuts() + explosion(src, devastation_range = 0, heavy_impact_range = 0, light_impact_range = 2, explosion_cause = src) + qdel(src) + +/obj/item/storage/toolbox/guncase/traitor/ammunition + name = "makarov 9mm magazine case" + weapon_to_spawn = /obj/item/ammo_box/magazine/m9mm + +/obj/item/storage/toolbox/guncase/traitor/donksoft + name = "\improper Donksoft riot pistol gun case" + weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/toy/riot/clandestine + extra_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot + ammo_box_to_spawn = /obj/item/ammo_box/foambox/riot + +/obj/item/storage/toolbox/guncase/traitor/ammunition/donksoft + name = "\improper Donksoft riot pistol magazine case" + weapon_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot + extra_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot + ammo_box_to_spawn = /obj/item/ammo_box/foambox/riot + +/obj/item/storage/toolbox/guncase/bulldog + name = "bulldog gun case" + weapon_to_spawn = /obj/item/gun/ballistic/shotgun/bulldog + extra_to_spawn = /obj/item/ammo_box/magazine/m12g + +/obj/item/storage/toolbox/guncase/c20r + name = "c-20r gun case" + weapon_to_spawn = /obj/item/gun/ballistic/automatic/c20r + extra_to_spawn = /obj/item/ammo_box/magazine/smgm45 + +/obj/item/storage/toolbox/guncase/smartgun + name = "adielle smartgun case" + weapon_to_spawn = /obj/item/gun/ballistic/automatic/smartgun + extra_to_spawn = /obj/item/ammo_box/magazine/smartgun + +/obj/item/storage/toolbox/guncase/clandestine + name = "clandestine gun case" + weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/clandestine + extra_to_spawn = /obj/item/ammo_box/magazine/m10mm + +/obj/item/storage/toolbox/guncase/m90gl + name = "m-90gl gun case" + weapon_to_spawn = /obj/item/gun/ballistic/automatic/m90 + extra_to_spawn = /obj/item/ammo_box/magazine/m223 + +/obj/item/storage/toolbox/guncase/m90gl/PopulateContents() + . = list() + + . += weapon_to_spawn + for(var/i in 1 to 2) + . += extra_to_spawn + . += /obj/item/ammo_box/a40mm/rubber + +/obj/item/storage/toolbox/guncase/rocketlauncher + name = "rocket launcher gun case" + weapon_to_spawn = /obj/item/gun/ballistic/rocketlauncher + extra_to_spawn = /obj/item/ammo_box/rocket + +/obj/item/storage/toolbox/guncase/rocketlauncher/PopulateContents() + return list( + weapon_to_spawn, + extra_to_spawn + ) + +/obj/item/storage/toolbox/guncase/revolver + name = "revolver gun case" + weapon_to_spawn = /obj/item/gun/ballistic/revolver/badass/nuclear + extra_to_spawn = /obj/item/ammo_box/a357 + +/obj/item/storage/toolbox/guncase/sword_and_board + name = "energy sword and shield weapon case" + weapon_to_spawn = /obj/item/melee/energy/sword + extra_to_spawn = /obj/item/shield/energy + +/obj/item/storage/toolbox/guncase/sword_and_board/PopulateContents() + return list( + weapon_to_spawn, + extra_to_spawn, + /obj/item/clothing/head/costume/knight, + ) + +/obj/item/storage/toolbox/guncase/cqc + name = "\improper CQC equipment case" + weapon_to_spawn = /obj/item/book/granter/martial/cqc + extra_to_spawn = /obj/item/storage/box/syndie_kit/imp_stealth + +/obj/item/storage/toolbox/guncase/cqc/PopulateContents(datum/storage_config/config) + config.compute_max_total_weight = TRUE + + return list( + weapon_to_spawn, + extra_to_spawn, + /obj/item/clothing/head/costume/snakeeater, + /obj/item/storage/fancy/cigarettes/cigpack_syndicate, + ) + +/obj/item/storage/toolbox/guncase/soviet + name = "ancient gun case" + desc = "A weapon's case. Has the symbol of the Third Soviet Union stamped on the side." + icon_state = "sakhno_case" + inhand_icon_state = "sakhno_case" + weapon_to_spawn = /obj/effect/spawner/random/sakhno + extra_to_spawn = /obj/effect/spawner/random/sakhno/ammo + +/obj/item/storage/toolbox/guncase/soviet/PopulateContents(datum/storage_config/config) + config.compute_max_total_weight = TRUE + + return ..() + +/obj/item/storage/toolbox/guncase/monkeycase + name = "monkey gun case" + desc = "Everything a monkey needs to truly go ape-shit. There's a paw-shaped hand scanner lock on the front of the case." + +/obj/item/storage/toolbox/guncase/monkeycase/Initialize(mapload) + . = ..() + atom_storage.locked = STORAGE_SOFT_LOCKED + +/obj/item/storage/toolbox/guncase/monkeycase/attack_self(mob/user, modifiers) + if(!monkey_check(user)) + return + return ..() + +/obj/item/storage/toolbox/guncase/monkeycase/attack_self_secondary(mob/user, modifiers) + attack_self(user, modifiers) + return + +/obj/item/storage/toolbox/guncase/monkeycase/attack_hand(mob/user, list/modifiers) + if(!monkey_check(user)) + return + return ..() + +/obj/item/storage/toolbox/guncase/monkeycase/proc/monkey_check(mob/user) + if(atom_storage.locked == STORAGE_NOT_LOCKED) + return TRUE + + if(is_simian(user)) + atom_storage.locked = STORAGE_NOT_LOCKED + to_chat(user, span_notice("You place your paw on the paw scanner, and hear a soft click as [src] unlocks!")) + playsound(src, 'sound/items/click.ogg', 25, TRUE) + return TRUE + to_chat(user, span_warning("You put your hand on the hand scanner, and it rejects it with an angry chimpanzee screech!")) + playsound(src, SFX_SCREECH, 75, TRUE) + return FALSE + +/obj/item/storage/toolbox/guncase/monkeycase/PopulateContents(datum/storage_config/config) + config.compute_max_item_count = TRUE + config.compute_max_total_weight = TRUE + + switch(rand(1, 3)) + if(1) + // Uzi with a boxcutter. + . = list( + /obj/item/gun/ballistic/automatic/mini_uzi/chimpgun, + /obj/item/ammo_box/magazine/uzim9mm, + /obj/item/ammo_box/magazine/uzim9mm, + /obj/item/boxcutter/extended, + ) + if(2) + // Thompson with a boxcutter. + . = list( + /obj/item/gun/ballistic/automatic/tommygun/chimpgun, + /obj/item/ammo_box/magazine/tommygunm45, + /obj/item/ammo_box/magazine/tommygunm45, + /obj/item/boxcutter/extended, + ) + if(3) + // M1911 with a switchblade and an extra banana bomb. + . = list( + /obj/item/gun/ballistic/automatic/pistol/m1911/chimpgun, + /obj/item/ammo_box/magazine/m45, + /obj/item/ammo_box/magazine/m45, + /obj/item/switchblade/extended, + /obj/item/food/grown/banana/bunch/monkeybomb, + ) + + // Banana bomb! Basically a tiny flashbang for monkeys. + . += /obj/item/food/grown/banana/bunch/monkeybomb + // Somewhere to store it all. + . += /obj/item/storage/backpack/messenger + + +/obj/item/storage/toolbox/guncase/doublesword + name = "double-bladed energy sword weapon case" + weapon_to_spawn = /obj/item/dualsaber + extra_to_spawn = /obj/item/soap/syndie + storage_type = /datum/storage/toolbox/double_sword + +/obj/item/storage/toolbox/guncase/doublesword/PopulateContents() + return list( + weapon_to_spawn, + extra_to_spawn, + /obj/item/mod/module/noslip, + /obj/item/reagent_containers/hypospray/medipen/methamphetamine, + /obj/item/clothing/under/rank/prisoner/nosensor, + ) diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm deleted file mode 100644 index f9c00af4206..00000000000 --- a/code/game/objects/items/storage/uplink_kits.dm +++ /dev/null @@ -1,919 +0,0 @@ -#define KIT_RECON "recon" -#define KIT_BLOODY_SPAI "bloodyspai" -#define KIT_STEALTHY "stealth" -#define KIT_SCREWED "screwed" -#define KIT_SABOTAGE "sabotage" -#define KIT_GUN "guns" -#define KIT_MURDER "murder" -#define KIT_IMPLANTS "implant" -#define KIT_HACKER "hacker" -#define KIT_SNIPER "sniper" -#define KIT_NUKEOPS_METAGAME "metaops" -#define KIT_LORD_SINGULOTH "lordsingulo" -#define KIT_REVOLUTIONARY "revolutionary" - -#define KIT_JAMES_BOND "bond" -#define KIT_NINJA "ninja" -#define KIT_DARK_LORD "darklord" -#define KIT_WHITE_WHALE_HOLY_GRAIL "white_whale_holy_grail" -#define KIT_MAD_SCIENTIST "mad_scientist" -#define KIT_BEES "bee" -#define KIT_MR_FREEZE "mr_freeze" -#define KIT_TRAITOR_2006 "ancient" -#define KIT_DEAD_MONEY "dead_money" -#define KIT_SAM_FISHER "sam_fisher" -#define KIT_PROP_HUNT "prop_hunt" - -/// last audited december 2022 -/obj/item/storage/box/syndicate - -/obj/item/storage/box/syndicate/bundle_a/PopulateContents() - switch (pick_weight(list( - KIT_RECON = 2, - KIT_BLOODY_SPAI = 3, - KIT_STEALTHY = 2, - KIT_SCREWED = 2, - KIT_SABOTAGE = 3, - KIT_GUN = 2, - KIT_MURDER = 2, - KIT_IMPLANTS = 1, - KIT_HACKER = 3, - KIT_SNIPER = 1, - KIT_NUKEOPS_METAGAME = 1, - KIT_REVOLUTIONARY = 2 - ))) - if(KIT_RECON) - new /obj/item/clothing/glasses/thermal/xray(src) // ~8 tc? - new /obj/item/storage/briefcase/launchpad(src) //6 tc - new /obj/item/binoculars(src) // 2 tc? - new /obj/item/encryptionkey/syndicate(src) // 2 tc - new /obj/item/storage/box/syndie_kit/space(src) //4 tc - new /obj/item/grenade/frag(src) // ~2 tc each? - new /obj/item/grenade/frag(src) - new /obj/item/flashlight/emp(src) // 4 tc - - if(KIT_BLOODY_SPAI) - new /obj/item/card/id/advanced/chameleon(src) // 2 tc - new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set - new /obj/item/clothing/mask/chameleon(src) // Goes with above - new /obj/item/clothing/shoes/chameleon/noslip(src) // 2 tc - new /obj/item/computer_disk/syndicate/camera_app(src) // 1 tc - new /obj/item/multitool/ai_detect(src) // 1 tc - new /obj/item/encryptionkey/syndicate(src) // 2 tc - new /obj/item/storage/box/syndie_kit/mulligan(src) // 4 tc - new /obj/item/switchblade(src) //basically 1 tc as it can be bought from BM kits - new /obj/item/storage/fancy/cigarettes/cigpack_syndicate (src) // 2 tc this shit heals - new /obj/item/flashlight/emp(src) // 2 tc - new /obj/item/chameleon(src) // 7 tc - new /obj/item/implanter/storage(src) // 6 tc - - if(KIT_STEALTHY) - new /obj/item/gun/energy/recharge/ebow(src) // 10 tc - new /obj/item/pen/sleepy(src) // 4 tc - new /obj/item/healthanalyzer/rad_laser(src) // 3 tc - new /obj/item/chameleon(src) // 7 tc - new /obj/item/soap/syndie(src) // 1 tc - new /obj/item/clothing/glasses/thermal/syndi(src) // 4 tc - new /obj/item/flashlight/emp(src) // 2 tc - new /obj/item/jammer(src) // 5 tc - - if(KIT_GUN) - new /obj/item/gun/ballistic/revolver(src) // 13 tc - new /obj/item/ammo_box/a357(src) // 4tc - new /obj/item/ammo_box/a357(src) - new /obj/item/storage/belt/holster/chameleon(src) // 1 tc - new /obj/item/card/emag/doorjack(src) // 3 tc replaced the emag with the doorjack - new /obj/item/grenade/c4(src) // 1 tc - new /obj/item/clothing/gloves/latex/nitrile(src) // ~1 tc for whole outfit - new /obj/item/clothing/mask/gas/clown_hat(src) - new /obj/item/clothing/under/suit/black_really(src) - new /obj/item/clothing/neck/tie/red/hitman(src) - - if(KIT_SCREWED) - new /obj/item/sbeacondrop/bomb(src) // 11 tc - new /obj/item/grenade/syndieminibomb(src) // 6 tc - new /obj/item/sbeacondrop/powersink(src) // 11 tc - var/obj/item/clothing/suit/space/syndicate/spess_suit = pick(GLOB.syndicate_space_suits_to_helmets) - new spess_suit(src) // Above allows me to get the helmet from a variable on the object - var/obj/item/clothing/head/helmet/space/syndicate/spess_helmet = GLOB.syndicate_space_suits_to_helmets[spess_suit] - new spess_helmet(src) // 4 TC for the space gear - new /obj/item/encryptionkey/syndicate(src) // 2 tc - - if(KIT_MURDER) - new /obj/item/melee/energy/sword/saber(src) // 8 tc - new /obj/item/clothing/glasses/thermal/syndi(src) // 4 tc - new /obj/item/card/emag/doorjack(src) // 3 tc - new /obj/item/clothing/shoes/chameleon/noslip(src) // 2 tc - new /obj/item/encryptionkey/syndicate(src) // 2 tc - new /obj/item/grenade/syndieminibomb(src) // 6 tc - - if(KIT_IMPLANTS) - new /obj/item/implanter/freedom(src) // 5 tc - new /obj/item/implanter/uplink/precharged(src) // 10 tc is inside this thing - new /obj/item/implanter/emp(src) // 1 tc - new /obj/item/implanter/explosive(src) // 2 tc - new /obj/item/implanter/storage(src) // 8 tc - - if(KIT_HACKER) //L-L--LOOK AT YOU, HACKER - new /obj/item/ai_module/syndicate(src) // 4 tc - new /obj/item/card/emag(src) // 4 tc - new /obj/item/card/emag/doorjack(src) // 3 tc - new /obj/item/encryptionkey/binary(src) // 5 tc - new /obj/item/ai_module/toy_ai(src) // ~6 tc - new /obj/item/multitool/ai_detect(src) // 1 tc - new /obj/item/storage/toolbox/syndicate(src) // 1 tc - new /obj/item/computer_disk/syndicate/camera_app(src) // 1 tc - new /obj/item/clothing/glasses/thermal/syndi(src) // 4 tc - new /obj/item/card/id/advanced/chameleon(src) // 2 tc - - if(KIT_LORD_SINGULOTH) //currently disabled, i might return with another anti-engine kit - new /obj/item/sbeacondrop(src) // 10 tc - var/obj/item/clothing/suit/space/syndicate/spess_suit = pick(GLOB.syndicate_space_suits_to_helmets) - new spess_suit(src) // Above allows me to get the helmet from a variable on the object - var/obj/item/clothing/head/helmet/space/syndicate/spess_helmet = GLOB.syndicate_space_suits_to_helmets[spess_suit] - new spess_helmet(src) // 4 TC for the space gear - new /obj/item/card/emag(src) // 4 tc - new /obj/item/storage/toolbox/syndicate(src) // 1 tc - new /obj/item/card/id/advanced/mining(src) - new /obj/item/stack/spacecash/c10000(src) // this is technically 10 tc but not really - if(prob(70)) - new /obj/item/toy/spinningtoy(src) //lol - else - new /obj/item/toy/spinningtoy/dark_matter(src) //edgy lol - - if(KIT_SABOTAGE) - new /obj/item/storage/backpack/duffelbag/syndie/sabotage(src) // 5 tc for 3 c4 and 2 x4 - new /obj/item/computer_disk/syndicate/camera_app(src) // 1 tc - new /obj/item/sbeacondrop/powersink(src) // 11 tc - new /obj/item/computer_disk/virus/detomatix(src) // 6 tc - new /obj/item/storage/toolbox/syndicate(src) // 1 tc - new /obj/item/pizzabox/bomb(src) // 6 tc - new /obj/item/storage/box/syndie_kit/emp(src) // 2 tc - - if(KIT_SNIPER) //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks - new /obj/item/gun/ballistic/rifle/sniper_rifle(src) // 12 tc - new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) // 5 tc - new /obj/item/clothing/glasses/thermal/syndi(src) // 4 tc - new /obj/item/clothing/gloves/latex/nitrile(src) // ~ 1 tc for outfit - new /obj/item/clothing/mask/gas/clown_hat(src) - new /obj/item/clothing/under/suit/black_really(src) - new /obj/item/clothing/neck/tie/red/hitman(src) - - if(KIT_NUKEOPS_METAGAME) - new /obj/item/mod/control/pre_equipped/nuclear/unrestricted(src) // 8 tc - new /obj/item/gun/ballistic/shotgun/bulldog/unrestricted(src) // 8 tc - new /obj/item/implanter/explosive(src) // 2 tc - new /obj/item/ammo_box/magazine/m12g(src) // 2 tc - new /obj/item/ammo_box/magazine/m12g(src) // 2 tc - new /obj/item/grenade/c4 (src) // 1 tc - new /obj/item/grenade/c4 (src) // 1 tc - new /obj/item/card/emag(src) // 4 tc - new /obj/item/card/emag/doorjack(src) // 3 tc - - if(KIT_REVOLUTIONARY) - new /obj/item/healthanalyzer/rad_laser(src) // 3 TC - new /obj/item/assembly/flash/hypnotic(src) // 7 TC - new /obj/item/storage/pill_bottle/lsd(src) // ~1 TC - new /obj/item/pen/sleepy(src) // 4 TC - new /obj/item/gun/ballistic/revolver/nagant(src) // 13 TC comparable to 357. revolvers - new /obj/item/megaphone(src) - new /obj/item/bedsheet/rev(src) - new /obj/item/clothing/suit/armor/vest/russian_coat(src) - new /obj/item/clothing/head/helmet/rus_ushanka(src) - new /obj/item/storage/box/syndie_kit/poster_box(src) - -/obj/item/storage/box/syndicate/bundle_b/PopulateContents() - switch (pick_weight(list( - KIT_JAMES_BOND = 2, - KIT_NINJA = 1, - KIT_DARK_LORD = 1, - KIT_WHITE_WHALE_HOLY_GRAIL = 2, - KIT_MAD_SCIENTIST = 2, - KIT_BEES = 1, - KIT_MR_FREEZE = 2, - KIT_DEAD_MONEY = 2, - KIT_TRAITOR_2006 = 1, - KIT_SAM_FISHER = 1, - KIT_PROP_HUNT = 1 - ))) - if(KIT_JAMES_BOND) - new /obj/item/gun/ballistic/automatic/pistol(src) // 7 tc - new /obj/item/suppressor(src) // 3 tc - new /obj/item/ammo_box/magazine/m9mm(src) // 1 tc - new /obj/item/ammo_box/magazine/m9mm(src) - new /obj/item/card/id/advanced/chameleon(src) // 2 tc - new /obj/item/clothing/under/chameleon(src) // 1 tc - new /obj/item/reagent_containers/hypospray/medipen/stimulants(src) // 5 tc - new /obj/item/reagent_containers/cup/rag(src) - new /obj/item/implanter/freedom(src) // 5 tc - new /obj/item/flashlight/emp(src) // 2 tc - new /obj/item/grenade/c4/x4(src) // 1ish tc - new /obj/item/reagent_containers/applicator/pill/cyanide(src) - new /obj/item/toy/cards/deck/syndicate(src) // 1 tc, for poker - - if(KIT_NINJA) - new /obj/item/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc? - new /obj/item/reagent_containers/hypospray/medipen/stimulants(src) // 5 tc - for(var/i in 1 to 6) - new /obj/item/throwing_star(src) // 1 tc - new /obj/item/storage/belt/chameleon(src) // worth some fraction of a tc - new /obj/item/chameleon(src) // 7 tc - new /obj/item/card/id/advanced/chameleon(src) // 2 tc - new /obj/item/card/emag/doorjack(src) // 3 tc - new /obj/item/book/granter/action/spell/smoke(src) // ninja smoke bomb. 1 tc - new /obj/item/clothing/shoes/bhop(src) // mining item, lets you jump at people, at least 2 tc - - if(KIT_DARK_LORD) - new /obj/item/dualsaber/red(src) // 16 tc - new /obj/item/dnainjector/telemut/darkbundle(src) // ~ 4 tc for tk - new /obj/item/clothing/suit/hooded/chaplain_hoodie(src) - new /obj/item/card/id/advanced/chameleon(src) // 2 tc - new /obj/item/clothing/shoes/chameleon/noslip(src) //2 tc ,because slipping while being a dark lord sucks - new /obj/item/book/granter/action/spell/summonitem(src) // ~2 tc - new /obj/item/book/granter/action/spell/lightningbolt(src) // 4 tc - - if(KIT_WHITE_WHALE_HOLY_GRAIL) //Unique items that don't appear anywhere else - new /obj/item/gun/ballistic/rifle/boltaction/harpoon(src) - new /obj/item/storage/bag/harpoon_quiver(src) - new /obj/item/clothing/suit/hooded/carp_costume/spaceproof(src) - new /obj/item/clothing/mask/gas/carp(src) - new /obj/item/grenade/spawnergrenade/spesscarp(src) - new /obj/item/toy/plush/carpplushie/dehy_carp(src) // 1 tc, for use as a personal mount - - if(KIT_MAD_SCIENTIST) - new /obj/item/clothing/suit/toggle/labcoat/mad(src) // 0 tc - new /obj/item/clothing/shoes/jackboots(src) // 0 tc - new /obj/item/megaphone(src) // 0 tc - new /obj/item/grenade/clusterbuster/random(src) // 10 tc? - new /obj/item/grenade/clusterbuster/random(src) // 10 tc? - new /obj/item/grenade/chem_grenade/bioterrorfoam(src) // 5 tc - new /obj/item/assembly/signaler(src) // 0 tc - new /obj/item/assembly/signaler(src) // 0 tc - new /obj/item/assembly/signaler(src) // 0 tc - new /obj/item/assembly/signaler(src) // 0 tc - new /obj/item/storage/toolbox/syndicate(src) // 1 tc - new /obj/item/pen/edagger(src) // 2 tc - new /obj/item/gun/energy/wormhole_projector/core_inserted(src) // 5 tc easily - - if(KIT_BEES) - new /obj/item/paper/fluff/bee_objectives(src) // 0 tc (motivation) - new /obj/item/clothing/suit/hooded/bee_costume(src) // 0 tc - new /obj/item/clothing/mask/animal/small/bee(src) // 0 tc - new /obj/item/storage/belt/fannypack/yellow(src) // 0 tc - new /obj/item/grenade/spawnergrenade/buzzkill(src) // these are the random super bees this is definitely all of the tc budget for this one - new /obj/item/grenade/spawnergrenade/buzzkill(src) // 10 tc per grenade - new /obj/item/reagent_containers/cup/bottle/beesease(src) // 10 tc? - new /obj/item/melee/beesword(src) //priceless - - if(KIT_MR_FREEZE) - new /obj/item/clothing/glasses/cold(src) - new /obj/item/clothing/gloves/color/black/security/blu(src) - new /obj/item/clothing/mask/chameleon(src) - new /obj/item/clothing/suit/hooded/wintercoat(src) - new /obj/item/clothing/shoes/winterboots(src) - new /obj/item/grenade/gluon(src) // whole belt is 22 and gluon is weight 4 so lets just go with like 7 total - new /obj/item/grenade/gluon(src) - new /obj/item/grenade/gluon(src) - new /obj/item/grenade/gluon(src) - new /obj/item/dnainjector/geladikinesis(src) // both abilities are probably 3 tc total - new /obj/item/dnainjector/cryokinesis(src) - new /obj/item/gun/energy/temperature/freeze(src) // ~6 tc - new /obj/item/gun/energy/laser/thermal/cryo(src) // ~6 tc - new /obj/item/melee/energy/sword/saber/blue(src) //see see it fits the theme bc its blue and ice is blue, 8 tc - - if(KIT_TRAITOR_2006) //A kit so old, it's probably older than you. //This bundle is filled with the entire uplink contents traitors had access to in 2006, from OpenSS13. Notably the esword was not a choice but existed in code. - new /obj/item/storage/toolbox/emergency/old/ancientbundle(src) //Items fit neatly into a classic toolbox just to remind you what the theme is. - - if(KIT_DEAD_MONEY) - for(var/i in 1 to 4) - new /obj/item/clothing/neck/collar_bomb(src) // These let you remotely kill people with a signaler, though you have to get them first. - new /obj/item/storage/box/syndie_kit/signaler(src) - new /obj/item/mod/control/pre_equipped/responsory/inquisitory/syndie(src) // basically a snowflake yet better elite modsuit, so like, 8 + 5 tc. - new /obj/item/card/id/advanced/chameleon(src) // 2 tc - new /obj/item/clothing/mask/chameleon(src) - new /obj/item/melee/baton/telescopic/contractor_baton(src) // 7 tc - new /obj/item/jammer(src) // 5 tc - new /obj/item/pinpointer/crew(src) //priceless - - if(KIT_SAM_FISHER) - new /obj/item/clothing/under/syndicate/combat(src) - new /obj/item/clothing/suit/armor/vest/marine/pmc(src) //The armor kit is comparable to the infiltrator, 6 TC - new /obj/item/clothing/head/helmet/marine/pmc(src) - new /obj/item/clothing/mask/gas/sechailer(src) - new /obj/item/clothing/glasses/night/colorless(src) // 3~ TC - new /obj/item/clothing/gloves/krav_maga/combatglovesplus(src) //5TC - new /obj/item/clothing/shoes/jackboots(src) - new /obj/item/storage/belt/military/assault/fisher(src) //items in this belt easily costs 18 TC - - if(KIT_PROP_HUNT) - new /obj/item/chameleon(src) // 7 TC - new /obj/item/card/emag/doorjack(src) // 3 TC - new /obj/item/storage/box/syndie_kit/imp_stealth(src) //8 TC - new /obj/item/gun/ballistic/automatic/pistol(src) // 7 TC - new /obj/item/clothing/glasses/thermal(src) // 4 TC - -/obj/item/storage/toolbox/emergency/old/ancientbundle/ //So the subtype works - -/obj/item/storage/toolbox/emergency/old/ancientbundle/PopulateContents() - new /obj/item/card/emag(src) // 4 tc - new /obj/item/card/emag/doorjack(src) //emag used to do both. 3 tc - new /obj/item/pen/sleepy(src) // 4 tc - new /obj/item/reagent_containers/applicator/pill/cyanide(src) - new /obj/item/chameleon(src) //its not the original cloaking device, but it will do. 8 tc - new /obj/item/gun/ballistic/revolver(src) // 13 tc old one stays in the old box - new /obj/item/implanter/freedom(src) // 5 tc - new /obj/item/stack/telecrystal(src) //The failsafe/self destruct isn't an item we can physically include in the kit, but 1 TC is technically enough to buy the equivalent. - -/obj/item/storage/belt/military/assault/fisher - -/obj/item/storage/belt/military/assault/fisher/PopulateContents() - new /obj/item/gun/ballistic/automatic/pistol/clandestine/fisher(src) // 11 TC: 7 (pistol) + 3 (suppressor) + lightbreaker (1 TC, black market meme/util item) - new /obj/item/ammo_box/magazine/m10mm(src) // 1 TC - new /obj/item/ammo_box/magazine/m10mm(src) - new /obj/item/card/emag/doorjack(src) // 3 TC - new /obj/item/knife/combat(src) //comparable to the e-dagger, 2 TC - -/obj/item/storage/box/syndie_kit - name = "box" - desc = "A sleek, sturdy box." - icon_state = "syndiebox" - illustration = "writing_syndie" - -/obj/item/storage/box/syndie_kit/rebarxbowsyndie - name = "Boxed Rebar Crossbow" - desc = "A scoped weapon with low armor penetration, but devastating against flesh. Features instruction manual for making specialty ammo." - -/obj/item/storage/box/syndie_kit/rebarxbowsyndie/PopulateContents() - new /obj/item/book/granter/crafting_recipe/dusting/rebarxbowsyndie_ammo(src) - new /obj/item/gun/ballistic/rifle/rebarxbow/syndie(src) - new /obj/item/storage/bag/rebar_quiver/syndicate(src) - -/obj/item/paper/syndicate_forensics_spoofer - name = "Forensics Spoofer Guide" - default_raw_text = {" - Forensics Spoofer Info:
- The spoofer has two modes: SCAN which scans for fingerprints and fibers, and APPLY which applies the currently chosen fingerprint/fiber to your target.
- The spoofer can only store 5 fingerprints and 5 fibers, and may not store or report fibers/prints already stored. Additionally, it taps into the stations network to associate scanned fingerprints with names.
- The spoofer will make the same sounds and sights as a forensics scanner, when silent mode is off.
- "} - -/obj/item/storage/box/syndie_kit/forensics_spoofer - name = "forensics spoofing kit" - -/obj/item/storage/box/syndie_kit/forensics_spoofer/PopulateContents() - new /obj/item/forensics_spoofer(src) - new /obj/item/paper/syndicate_forensics_spoofer(src) - -/obj/item/storage/box/syndie_kit/origami_bundle - name = "origami kit" - desc = "A box full of a number of rather masterfully engineered paper planes and a manual on \"The Art of Origami\"." - -/obj/item/storage/box/syndie_kit/origami_bundle/PopulateContents() - new /obj/item/book/granter/action/origami(src) - for(var/i in 1 to 5) - new /obj/item/paper(src) - -/obj/item/storage/box/syndie_kit/imp_freedom - name = "freedom implant box" - -/obj/item/storage/box/syndie_kit/imp_freedom/PopulateContents() - new /obj/item/implanter/freedom(src) - -/obj/item/storage/box/syndie_kit/imp_microbomb - name = "microbomb implant box" - -/obj/item/storage/box/syndie_kit/imp_microbomb/PopulateContents() - new /obj/item/implanter/explosive(src) - -/obj/item/storage/box/syndie_kit/imp_macrobomb - name = "macrobomb implant box" - -/obj/item/storage/box/syndie_kit/imp_macrobomb/PopulateContents() - new /obj/item/implanter/explosive_macro(src) - -/obj/item/storage/box/syndie_kit/imp_deniability - name = "tactical deniability implant box" - -/obj/item/storage/box/syndie_kit/imp_deniability/PopulateContents() - new /obj/item/implanter/tactical_deniability(src) - -/obj/item/storage/box/syndie_kit/imp_uplink - name = "uplink implant box" - -/obj/item/storage/box/syndie_kit/imp_uplink/PopulateContents() - new /obj/item/implanter/uplink(src) - -/obj/item/storage/box/syndie_kit/bioterror - name = "bioterror syringe box" - -/obj/item/storage/box/syndie_kit/bioterror/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/syringe/bioterror(src) - -/obj/item/storage/box/syndie_kit/clownpins - name = "ultra hilarious firing pin box" - -/obj/item/storage/box/syndie_kit/clownpins/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/firing_pin/clown/ultra(src) - -/obj/item/storage/box/syndie_kit/imp_storage - name = "storage implant box" - -/obj/item/storage/box/syndie_kit/imp_storage/PopulateContents() - new /obj/item/implanter/storage(src) - -/obj/item/storage/box/syndie_kit/imp_stealth - name = "stealth implant box" - -/obj/item/storage/box/syndie_kit/imp_stealth/PopulateContents() - new /obj/item/implanter/stealth(src) - -/obj/item/storage/box/syndie_kit/imp_radio - name = "syndicate radio implant box" - -/obj/item/storage/box/syndie_kit/imp_radio/PopulateContents() - new /obj/item/implanter/radio/syndicate(src) - -/obj/item/storage/box/syndie_kit/space - name = "boxed space suit and helmet" - -/obj/item/storage/box/syndie_kit/space/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.set_holdable(list(/obj/item/clothing/suit/space/syndicate, /obj/item/clothing/head/helmet/space/syndicate)) - -/obj/item/storage/box/syndie_kit/space/PopulateContents() - var/obj/item/clothing/suit/space/syndicate/spess_suit = pick(GLOB.syndicate_space_suits_to_helmets) - new spess_suit(src) // Above allows me to get the helmet from a variable on the object - var/obj/item/clothing/head/helmet/space/syndicate/spess_helmet = GLOB.syndicate_space_suits_to_helmets[spess_suit] - new spess_helmet(src) // 4 TC for the space gear - -/obj/item/storage/box/syndie_kit/emp - name = "EMP kit" - -/obj/item/storage/box/syndie_kit/emp/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/grenade/empgrenade(src) - new /obj/item/implanter/emp(src) - -/obj/item/storage/box/syndie_kit/smoke - name = "smoke kit" - -/obj/item/storage/box/syndie_kit/smoke/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/grenade/smokebomb(src) - -/obj/item/storage/box/syndie_kit/mail_counterfeit - name = "mail counterfeit kit" - desc = "A GLA Postal Service branded box. It's emblazoned with the motto: *Nothing stops the mail*." - -/obj/item/storage/box/syndie_kit/mail_counterfeit/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/storage/mail_counterfeit_device(src) - -/obj/item/storage/box/syndie_kit/chemical - name = "chemical kit" - -/obj/item/storage/box/syndie_kit/chemical/Initialize(mapload) - . = ..() - atom_storage.max_slots = 15 - -/obj/item/storage/box/syndie_kit/chemical/PopulateContents() - new /obj/item/reagent_containers/cup/bottle/polonium(src) - new /obj/item/reagent_containers/cup/bottle/venom(src) - new /obj/item/reagent_containers/cup/bottle/fentanyl(src) - new /obj/item/reagent_containers/cup/bottle/formaldehyde(src) - new /obj/item/reagent_containers/cup/bottle/spewium(src) - new /obj/item/reagent_containers/cup/bottle/syndol(src) - new /obj/item/reagent_containers/cup/bottle/cyanide(src) - new /obj/item/reagent_containers/cup/bottle/histamine(src) - new /obj/item/reagent_containers/cup/bottle/initropidril(src) - new /obj/item/reagent_containers/cup/bottle/pancuronium(src) - new /obj/item/reagent_containers/cup/bottle/sodium_thiopental(src) - new /obj/item/reagent_containers/cup/bottle/coniine(src) - new /obj/item/reagent_containers/cup/bottle/curare(src) - new /obj/item/reagent_containers/cup/bottle/amanitin(src) - new /obj/item/reagent_containers/syringe(src) - -/obj/item/storage/box/syndie_kit/nuke - name = "nuke core extraction kit" - desc = "A box containing the equipment and instructions for extracting the plutonium cores of most Nanotrasen nuclear explosives." - -/obj/item/storage/box/syndie_kit/nuke/PopulateContents() - new /obj/item/screwdriver/nuke(src) - new /obj/item/nuke_core_container(src) - new /obj/item/paper/guides/antag/nuke_instructions(src) - -/obj/item/storage/box/syndie_kit/supermatter - name = "supermatter sliver extraction kit" - desc = "A box containing the equipment and instructions for extracting a sliver of supermatter." - -/obj/item/storage/box/syndie_kit/supermatter/PopulateContents() - new /obj/item/scalpel/supermatter(src) - new /obj/item/hemostat/supermatter(src) - new /obj/item/nuke_core_container/supermatter(src) - new /obj/item/paper/guides/antag/supermatter_sliver(src) - -/obj/item/storage/box/syndie_kit/tuberculosisgrenade - name = "virus grenade kit" - -/obj/item/storage/box/syndie_kit/tuberculosisgrenade/PopulateContents() - new /obj/item/grenade/chem_grenade/tuberculosis(src) - for(var/i in 1 to 5) - new /obj/item/reagent_containers/hypospray/medipen/tuberculosiscure(src) - new /obj/item/reagent_containers/syringe(src) - new /obj/item/reagent_containers/cup/bottle/tuberculosiscure(src) - -/obj/item/storage/box/syndie_kit/chameleon - name = "chameleon kit" - -/obj/item/storage/box/syndie_kit/chameleon/PopulateContents() - new /obj/item/clothing/under/chameleon(src) - new /obj/item/clothing/suit/chameleon(src) - new /obj/item/clothing/gloves/chameleon(src) - new /obj/item/clothing/shoes/chameleon(src) - new /obj/item/clothing/glasses/chameleon(src) - new /obj/item/clothing/head/chameleon(src) - new /obj/item/clothing/mask/chameleon(src) - new /obj/item/clothing/neck/chameleon(src) - new /obj/item/storage/backpack/chameleon(src) - new /obj/item/storage/belt/chameleon(src) - new /obj/item/radio/headset/chameleon(src) - new /obj/item/stamp/chameleon(src) - new /obj/item/modular_computer/pda/chameleon(src) - new /obj/item/gun/energy/laser/chameleon(src) - new /obj/item/chameleon_scanner(src) - -//5*(2*4) = 5*8 = 45, 45 damage if you hit one person with all 5 stars. -//Not counting the damage it will do while embedded (2*4 = 8, at 15% chance) -/obj/item/storage/box/syndie_kit/throwing_weapons/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/throwing_star(src) - for(var/i in 1 to 2) - new /obj/item/paperplane/syndicate(src) - new /obj/item/restraints/legcuffs/bola/tactical(src) - new /obj/item/restraints/legcuffs/bola/tactical(src) - -/obj/item/storage/box/syndie_kit/throwing_weapons/Initialize(mapload) - . = ..() - atom_storage.max_slots = 9 // 5 + 2 + 2 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 18 // 5*2 + 2*1 + 3*2 - atom_storage.set_holdable(list( - /obj/item/restraints/legcuffs/bola/tactical, - /obj/item/paperplane/syndicate, - /obj/item/throwing_star, - )) - -/obj/item/storage/box/syndie_kit/cutouts/PopulateContents() - for(var/i in 1 to 3) - new/obj/item/cardboard_cutout/adaptive(src) - new/obj/item/toy/crayon/rainbow(src) - -/obj/item/storage/box/syndie_kit/romerol/PopulateContents() - new /obj/item/reagent_containers/cup/bottle/romerol(src) - new /obj/item/reagent_containers/syringe(src) - new /obj/item/reagent_containers/dropper(src) - -/obj/item/storage/box/syndie_kit/ez_clean/PopulateContents() - for(var/i in 1 to 3) - new/obj/item/grenade/chem_grenade/ez_clean(src) - -/obj/item/storage/box/syndie_kit/mulligan/PopulateContents() - . = ..() - new /obj/item/reagent_containers/syringe/mulligan(src) - new /obj/item/fake_identity_kit(src) - -/obj/item/storage/box/hug/reverse_revolver/PopulateContents() - new /obj/item/gun/ballistic/revolver/reverse(src) - -/obj/item/storage/box/syndie_kit/mimery/PopulateContents() - new /obj/item/book/granter/action/spell/mime/mimery_blockade(src) - new /obj/item/book/granter/action/spell/mime/mimery_guns(src) - -/obj/item/storage/box/syndie_kit/moltobeso/PopulateContents() - new /obj/item/reagent_containers/cup/bottle/moltobeso(src) - new /obj/item/reagent_containers/syringe(src) - new /obj/item/reagent_containers/dropper(src) - -/obj/item/storage/box/syndie_kit/combat_baking/PopulateContents() - new /obj/item/food/baguette/combat(src) - for(var/i in 1 to 2) - new /obj/item/food/croissant/throwing(src) - new /obj/item/book/granter/crafting_recipe/combat_baking(src) - -/obj/item/storage/box/syndie_kit/centcom_costume/PopulateContents() - new /obj/item/clothing/under/rank/centcom/officer(src) - new /obj/item/clothing/shoes/sneakers/black(src) - new /obj/item/clothing/gloves/color/black(src) - new /obj/item/radio/headset/headset_cent/empty(src) - new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/storage/backpack/satchel(src) - new /obj/item/modular_computer/pda/heads(src) - new /obj/item/clipboard(src) - -/obj/item/storage/box/syndie_kit/chameleon/broken/PopulateContents() - new /obj/item/clothing/under/chameleon/broken(src) - new /obj/item/clothing/suit/chameleon/broken(src) - new /obj/item/clothing/gloves/chameleon/broken(src) - new /obj/item/clothing/shoes/chameleon/noslip/broken(src) - new /obj/item/clothing/glasses/chameleon/broken(src) - new /obj/item/clothing/head/chameleon/broken(src) - new /obj/item/clothing/mask/chameleon/broken(src) - new /obj/item/clothing/neck/chameleon/broken(src) - new /obj/item/storage/backpack/chameleon/broken(src) - new /obj/item/storage/belt/chameleon/broken(src) - new /obj/item/radio/headset/chameleon/broken(src) - new /obj/item/stamp/chameleon/broken(src) - new /obj/item/modular_computer/pda/chameleon/broken(src) - // No chameleon laser, they can't randomise for //REASONS// - -/obj/item/storage/box/syndie_kit/bee_grenades - name = "buzzkill grenade box" - desc = "A sleek, sturdy box with a buzzing noise coming from the inside. Uh oh." - -/obj/item/storage/box/syndie_kit/bee_grenades/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/grenade/spawnergrenade/buzzkill(src) - -/obj/item/storage/box/syndie_kit/manhack_grenades/PopulateContents() - for(var/i in 1 to 3) - new /obj/item/grenade/spawnergrenade/manhacks(src) - -/obj/item/storage/box/syndie_kit/sleepytime/PopulateContents() - new /obj/item/clothing/under/syndicate/bloodred/sleepytime(src) - new /obj/item/reagent_containers/cup/glass/mug/coco(src) - new /obj/item/toy/plush/carpplushie(src) - new /obj/item/bedsheet/syndie(src) - -/obj/item/storage/box/syndie_kit/demoman/PopulateContents() - new /obj/item/gun/grenadelauncher(src) - new /obj/item/storage/belt/grenade/full(src) - if(prob(1)) - new /obj/item/clothing/head/hats/hos/shako(src) - -/obj/item/storage/box/syndie_kit/core_gear - name = "core equipment box" - desc = "Contains all the necessary gear for success for any nuclear operative unsure of what is needed for success in the field. Everything here WILL help you." - -/obj/item/storage/box/syndie_kit/core_gear/PopulateContents() - new /obj/item/implanter/freedom (src) - new /obj/item/card/emag/doorjack (src) - new /obj/item/reagent_containers/hypospray/medipen/stimulants (src) - new /obj/item/grenade/c4 (src) - new /obj/item/mod/module/energy_shield(src) - -/// Surplus Ammo Box - -/obj/item/storage/box/syndie_kit/sniper_surplus - name = "surplus .50 BMG magazine box" - desc = "A shoddy box full of surplus .50 BMG magazines. Not as strong, but good enough to keep lead in the air." - -/obj/item/storage/box/syndie_kit/sniper_surplus/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/ammo_box/magazine/sniper_rounds/surplus(src) - -/obj/item/storage/box/syndie_kit/shotgun_surplus - name = "\improper Donk Co. 'Donk Spike' flechette 12g Bulldog magazine box" - desc = "A shoddy box full of Donk Co. 'Donk Spike' flechette 12g. It is debatable whether or not these are actually \ - better or worse than standard flechette. Donk Co. did genuinely believe in this product being the future of military \ - ammunition production. The only reason it didn't see wider adoption was a lack of faith in the product. Do you \ - believe in Donk? Time to put that to the test." - -/obj/item/storage/box/syndie_kit/shotgun_surplus/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/ammo_box/magazine/m12g/donk(src) - -///Subtype for the sabotage bundle. Contains three C4, two X4 and 6 signalers -/obj/item/storage/backpack/duffelbag/syndie/sabotage - -/obj/item/storage/backpack/duffelbag/syndie/sabotage/PopulateContents() - new /obj/item/grenade/c4(src) - new /obj/item/grenade/c4(src) - new /obj/item/grenade/c4(src) - new /obj/item/grenade/c4/x4(src) - new /obj/item/grenade/c4/x4(src) - new /obj/item/storage/box/syndie_kit/signaler(src) - -/obj/item/storage/box/syndie_kit/signaler - name = "signaler box" - desc = "Contains everything an agent would need to remotely detonate their bombs." - -/obj/item/storage/box/syndie_kit/signaler/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/assembly/signaler(src) - -/obj/item/storage/box/syndie_kit/imp_deathrattle - name = "deathrattle implant box" - desc = "Contains eight linked deathrattle implants." - -/obj/item/storage/box/syndie_kit/imp_deathrattle/PopulateContents() - new /obj/item/implanter(src) - - var/datum/deathrattle_group/group = new - - var/implants = list() - for(var/j in 1 to 8) - var/obj/item/implantcase/deathrattle/case = new (src) - implants += case.imp - - for(var/i in implants) - group.register(i) - desc += " The implants are registered to the \"[group.name]\" group." - -/obj/item/storage/box/stickers/syndie_kit/PopulateContents() - var/list/types = subtypesof(/obj/item/sticker/syndicate) - - for(var/i in 1 to atom_storage.max_slots) - var/type = pick(types) - new type(src) - -/obj/item/storage/box/syndie_kit/pinata - name = "weapons grade pinata kit" - desc = "Contains a weapons grade pinata and 2 belts for carrying its contents." - -/obj/item/storage/box/syndie_kit/pinata/PopulateContents() - new /obj/item/pinata/syndie(src) - new /obj/item/storage/belt/grenade(src) - new /obj/item/storage/belt/military/snack(src) - -/obj/item/storage/box/syndie_kit/induction_kit - name = "syndicate induction kit" - desc = "Contains all you need for introducing your newest comrade to the Syndicate and all its worker's benefits." - -/obj/item/storage/box/syndie_kit/induction_kit/PopulateContents() - // Basic weaponry, so they have something to use. - new /obj/item/gun/ballistic/automatic/pistol/clandestine(src) // 6 TC, but free for nukies - new /obj/item/ammo_box/magazine/m10mm/hp(src) // 3 TC, a reward for the teamwork involved - new /obj/item/ammo_box/magazine/m10mm/ap(src) // 3 TC, a reward for the teamwork involved - new /obj/item/pen/edagger(src) // 2 TC - // The necessary equipment to help secure that disky. - new /obj/item/radio/headset/syndicate/alt(src) // 5 TC / Free for nukies - new /obj/item/modular_computer/pda/nukeops(src) // ?? TC / Free for nukies - new /obj/item/card/id/advanced/chameleon(src) // 2 TC / Free for nukies - var/obj/item/clothing/suit/space/syndicate/spess_suit = pick(GLOB.syndicate_space_suits_to_helmets) - new spess_suit(src) // Above allows me to get the helmet from a variable on the object - var/obj/item/clothing/head/helmet/space/syndicate/spess_helmet = GLOB.syndicate_space_suits_to_helmets[spess_suit] - new spess_helmet(src) // 4 TC for the space gear - new /obj/item/tank/jetpack/oxygen/harness(src) // They kinda need this to fly to the cruiser. - // Tacticool gear - new /obj/item/clothing/shoes/combat(src) - new /obj/item/clothing/under/syndicate(src) - new /obj/item/clothing/gloves/fingerless(src) - new /obj/item/book/manual/nuclear(src) // Very important - // The most important part of the kit, the implant that gives them the syndicate faction. - new /obj/item/implanter/induction_implant(src) - // All in all, 6+3+3+2+5+2+4 = ~25 TC of 'miscellaneous' items. - // This is a lot of value for 10 TC, but you have to keep in mind that you NEED someone to get this stuff station-side. - // Pretty much all of it is a bad deal for reinforcements or yourself as they already have similar or good-enough alternatives. - -/obj/item/implanter/induction_implant - name = "implanter (nuclear operative)" - desc = "A sterile automatic implant injector. You can see a tiny, somehow legible sticker on the side: 'NOT A BRAINWASH DEVICE'" - imp_type = /obj/item/implant/nuclear_operative - -/obj/item/implant/nuclear_operative - name = "nuclear operative implant" - desc = "Registers you as a member of a Syndicate nuclear operative team." - implant_color = "r" - -/obj/item/implant/nuclear_operative/get_data() - return "Implant Specifications:
\ - Name: Suspicious Implant
\ - Life: UNKNOWN
\ - Implant Details:
\ - Function: Strange implant that seems to resist any attempts at scanning it." - -/obj/item/implant/nuclear_operative/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE) - . = ..() - if(!. || !ishuman(target) || !(target.mind)) - return FALSE - var/mob/living/carbon/human/human_target = target - - if(IS_NUKE_OP(human_target)) // this wont proc due to ..() but i guess its good as a just-in-case? - if(human_target == user) - to_chat(user, span_userdanger("You're already a nuclear operative, dumbass! The implant disintegrates within you! You feel sick...")) - human_target.Stun(10 SECONDS) - human_target.reagents.add_reagent(/datum/reagent/toxin, 10) - return FALSE - else - to_chat(user, span_notice("You finish implanting [human_target], but you don't really notice a difference. Huh.")) - to_chat(human_target, span_userdanger("Nothing seems to really happen, but you start to feel a little ill..")) - human_target.reagents.add_reagent(/datum/reagent/toxin, 2) - return FALSE - - /// If all the antag datums are 'fake' or none exist, disallow induction! No self-antagging. - var/faker - for(var/datum/antagonist/antag_datum as anything in human_target.mind.antag_datums) - if((antag_datum.antag_flags & FLAG_FAKE_ANTAG)) - faker = TRUE - - if(faker || isnull(human_target.mind.antag_datums)) // GTFO. Technically not foolproof but making a heartbreaker or a paradox clone a nuke op sounds hilarious - to_chat(human_target, span_notice("Huh? Nothing happened? But you're starting to feel a little ill...")) - human_target.reagents.add_reagent(/datum/reagent/toxin, 15) - return FALSE - - var/datum/antagonist/nukeop/nuke_datum = new() - nuke_datum.send_to_spawnpoint = FALSE - nuke_datum.nukeop_outfit = null - human_target.mind?.add_antag_datum(nuke_datum) - human_target.faction |= ROLE_SYNDICATE - to_chat(human_target, span_warning("You are now a nuclear operative. Your main objective, if you were an antagonist and willing, is presumably to assist the nuclear operative team and secure the disk.")) - to_chat(human_target, span_userdanger("This implant does NOT, in any way, brainwash you. If you were a normal crew member beforehand, forcibly implanted or otherwise, you are still one and cannot assist the nuclear operatives.")) - return TRUE - -/obj/item/implant/nuclear_operative/removed(mob/target, silent = FALSE, special = FALSE) - . = ..() - if(!. || !isliving(target)) - return FALSE - var/mob/living/living_target = target - living_target.mind.remove_antag_datum(/datum/antagonist/nukeop) - living_target.faction -= ROLE_SYNDICATE - to_chat(target, span_notice("You feel a little less nuclear.")) - to_chat(target, span_userdanger("You're no longer identified as a nuclear operative! You are free to follow any valid goals you wish, even continuing to secure the disk. Just make sure neither any turrets nor operatives kill you on sight.")) - return TRUE - -/obj/item/storage/box/syndie_kit/poster_box - name = "syndicate poster pack" - desc = "Contains a variety of demotivational posters to ensure minimum productivity for the crew of any Nanotrasen station." - - /// Number of posters this box contains when spawning. - var/poster_count = 3 - -/obj/item/storage/box/syndie_kit/poster_box/PopulateContents() - for(var/i in 1 to poster_count) - new /obj/item/poster/traitor(src) - -/obj/item/storage/box/syndie_kit/cowboy - name = "western outlaw pack" - desc = "Contains everything you'll need to be the rootin' tootin' cowboy you always wanted. Either play the Lone Ranger or go in with your posse of outlaws." - -/obj/item/storage/box/syndie_kit/cowboy/PopulateContents() - generate_items_inside(list( - /obj/item/clothing/shoes/cowboy/black/syndicate= 1, - /obj/item/clothing/head/cowboy/black/syndicate = 1, - /obj/item/storage/belt/holster/nukie/cowboy/full = 1, - /obj/item/clothing/under/costume/dutch/syndicate = 1, - /obj/item/lighter/skull = 1, - /obj/item/sbeacondrop/horse = 1, - /obj/item/food/grown/apple = 1, - ), src) - -/obj/item/storage/box/syndicate/contract_kit - name = "Contract Kit" - desc = "Supplied to Syndicate contractors." - icon_state = "syndiebox" - illustration = "writing_syndie" - -/obj/item/storage/box/syndicate/contract_kit/PopulateContents() - new /obj/item/modular_computer/pda/syndicate_contract_uplink(src) - new /obj/item/storage/box/syndicate/contractor_loadout(src) - new /obj/item/melee/baton/telescopic/contractor_baton(src) - // Paper guide is always last. - new /obj/item/paper/contractor_guide(src) - -/obj/item/storage/box/syndicate/contractor_loadout - name = "Standard Loadout" - desc = "Supplied to Syndicate contractors, providing their specialised space suit and chameleon uniform." - icon_state = "syndiebox" - illustration = "writing_syndie" - -/obj/item/storage/box/syndicate/contractor_loadout/PopulateContents() - new /obj/item/mod/control/pre_equipped/infiltrator(src) - new /obj/item/clothing/head/helmet/space/syndicate/contract(src) - new /obj/item/clothing/suit/space/syndicate/contract(src) - new /obj/item/clothing/under/chameleon(src) - new /obj/item/clothing/mask/chameleon(src) - new /obj/item/card/id/advanced/chameleon(src) - new /obj/item/clothing/glasses/thermal/syndi(src) - new /obj/item/storage/toolbox/syndicate(src) - new /obj/item/jammer(src) - new /obj/item/storage/fancy/cigarettes/cigpack_syndicate(src) - new /obj/item/lighter(src) - -#undef KIT_RECON -#undef KIT_BLOODY_SPAI -#undef KIT_STEALTHY -#undef KIT_SCREWED -#undef KIT_SABOTAGE -#undef KIT_GUN -#undef KIT_MURDER -#undef KIT_IMPLANTS -#undef KIT_HACKER -#undef KIT_SNIPER -#undef KIT_NUKEOPS_METAGAME -#undef KIT_LORD_SINGULOTH -#undef KIT_REVOLUTIONARY - -#undef KIT_JAMES_BOND -#undef KIT_NINJA -#undef KIT_DARK_LORD -#undef KIT_WHITE_WHALE_HOLY_GRAIL -#undef KIT_MAD_SCIENTIST -#undef KIT_BEES -#undef KIT_MR_FREEZE -#undef KIT_TRAITOR_2006 -#undef KIT_DEAD_MONEY -#undef KIT_SAM_FISHER -#undef KIT_PROP_HUNT diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index d9ee1726b27..c598d3cf7cd 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -5,48 +5,13 @@ w_class = WEIGHT_CLASS_SMALL resistance_flags = FLAMMABLE slot_flags = ITEM_SLOT_ID + storage_type = /datum/storage/wallet var/obj/item/card/id/front_id = null var/list/combined_access var/cached_flat_icon var/overlay_icon_state = "wallet_overlay" -/obj/item/storage/wallet/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.max_slots = 4 - atom_storage.set_holdable(list( - /obj/item/stack/spacecash, - /obj/item/holochip, - /obj/item/card, - /obj/item/cigarette, - /obj/item/clothing/accessory/dogtag, - /obj/item/coin, - /obj/item/coupon, - /obj/item/dice, - /obj/item/disk, - /obj/item/flashlight/pen, - /obj/item/folder/biscuit, - /obj/item/food/chococoin, - /obj/item/implanter, - /obj/item/laser_pointer, - /obj/item/lighter, - /obj/item/lipstick, - /obj/item/match, - /obj/item/paper, - /obj/item/pen, - /obj/item/photo, - /obj/item/reagent_containers/dropper, - /obj/item/reagent_containers/syringe, - /obj/item/reagent_containers/applicator, - /obj/item/screwdriver, - /obj/item/seeds, - /obj/item/spess_knife, - /obj/item/stack/medical, - /obj/item/stamp, - /obj/item/toy/crayon), - list(/obj/item/screwdriver/power)) - /obj/item/storage/wallet/Exited(atom/movable/gone, direction) . = ..() if(isidcard(gone)) @@ -163,13 +128,19 @@ icon_state = "wallet" /obj/item/storage/wallet/random/PopulateContents() - new /obj/item/holochip(src, rand(5, 30)) new /obj/effect/spawner/random/entertainment/wallet_storage(src) + new /obj/item/holochip(src, rand(5, 30)) + + . = list() + for(var/obj/item as anything in src) + item.moveToNullspace() + . += item ///Used by the toilet fish source. /obj/item/storage/wallet/money desc = "It can hold a few small and personal things. This one reeks of toilet water." /obj/item/storage/wallet/money/PopulateContents() + . = list() for(var/iteration in 1 to pick(3, 4)) - new /obj/item/holochip(src, rand(50, 450)) + . += new /obj/item/holochip(null, rand(50, 450)) diff --git a/code/game/objects/items/tcg/tcg.dm b/code/game/objects/items/tcg/tcg.dm index 1f6c334c992..e3de6ddf3d9 100644 --- a/code/game/objects/items/tcg/tcg.dm +++ b/code/game/objects/items/tcg/tcg.dm @@ -427,12 +427,7 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) resistance_flags = FLAMMABLE //burn your enemies' collections, for only you can Collect Them All! w_class = WEIGHT_CLASS_SMALL flags_1 = PREVENT_CONTENTS_EXPLOSION_1 - -/obj/item/storage/card_binder/Initialize(mapload) - . = ..() - atom_storage.set_holdable(/obj/item/tcgcard) - atom_storage.max_total_storage = 120 - atom_storage.max_slots = 60 + storage_type = /datum/storage/card_binder ///Returns a list of cards ids of card_cnt weighted by rarity from the pack's tables that have matching series, with gnt_cnt of the guaranteed table. /obj/item/cardpack/proc/buildCardListWithRarity(card_cnt, rarity_cnt) diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 54935e170b6..ae90e9831ae 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -575,8 +575,10 @@ name = "syndicate teleporter kit" /obj/item/storage/box/syndie_kit/syndicate_teleporter/PopulateContents() - new /obj/item/syndicate_teleporter(src) - new /obj/item/paper/syndicate_teleporter(src) + return list( + /obj/item/syndicate_teleporter, + /obj/item/paper/syndicate_teleporter, + ) /obj/effect/temp_visual/teleport_abductor/syndi_teleporter duration = 5 diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 2902bd72572..620b1c7d6e7 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1537,9 +1537,12 @@ name = "box of pierced realities" desc = "A box containing toys resembling pierced realities." -/obj/item/storage/box/heretic_box/PopulateContents() +/obj/item/storage/box/heretic_box/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + + . = list() for(var/i in 1 to rand(1,4)) - new /obj/item/toy/reality_pierce(src) + . += /obj/item/toy/reality_pierce /obj/item/toy/foamfinger name = "foam finger" diff --git a/code/game/objects/structures/janitor.dm b/code/game/objects/structures/janitor.dm index a8df82e02b2..a79156a0305 100644 --- a/code/game/objects/structures/janitor.dm +++ b/code/game/objects/structures/janitor.dm @@ -200,7 +200,12 @@ if(istype(attacking_item, /obj/item/storage/bag/trash)) if(mybag) balloon_alert(user, "already has \a [mybag]!") - else if(user.transferItemToLoc(attacking_item, src)) + return + var/obj/item/storage/bag/trash/bag = attacking_item + if(!bag.insertable) + balloon_alert(user, "cannot be inserted!") + return + if(user.transferItemToLoc(attacking_item, src)) balloon_alert(user, "attached [attacking_item]") return diff --git a/code/modules/admin/verbs/anonymousnames.dm b/code/modules/admin/verbs/anonymousnames.dm index 21924288467..1c89082228c 100644 --- a/code/modules/admin/verbs/anonymousnames.dm +++ b/code/modules/admin/verbs/anonymousnames.dm @@ -196,51 +196,64 @@ GLOBAL_DATUM(current_anonymous_theme, /datum/anonymous_theme) /obj/item/storage/box/wizard_kit name = "Generic Wizard Cosplay Kit" + storage_type = /datum/storage/box/wizard /obj/item/storage/box/wizard_kit/PopulateContents() - new /obj/item/clothing/head/wizard(src) - new /obj/item/clothing/suit/wizrobe(src) - new /obj/item/clothing/shoes/sandal(src) + return list( + /obj/item/clothing/head/wizard, + /obj/item/clothing/suit/wizrobe, + /obj/item/clothing/shoes/sandal, + ) /obj/item/storage/box/wizard_kit/red name = "Evocation Wizard Cosplay Kit" /obj/item/storage/box/wizard_kit/red/PopulateContents() - new /obj/item/clothing/head/wizard/red(src) - new /obj/item/clothing/suit/wizrobe/red(src) - new /obj/item/clothing/shoes/sandal(src) + return list( + /obj/item/clothing/head/wizard/red, + /obj/item/clothing/suit/wizrobe/red, + /obj/item/clothing/shoes/sandal, + ) /obj/item/storage/box/wizard_kit/yellow name = "Translocation Wizard Cosplay Kit" /obj/item/storage/box/wizard_kit/yellow/PopulateContents() - new /obj/item/clothing/head/wizard/yellow(src) - new /obj/item/clothing/suit/wizrobe/yellow(src) - new /obj/item/clothing/shoes/sandal(src) + return list( + /obj/item/clothing/head/wizard/yellow, + /obj/item/clothing/suit/wizrobe/yellow, + /obj/item/clothing/shoes/sandal, + ) /obj/item/storage/box/wizard_kit/magusred name = "Conjuration Wizard Cosplay Kit" -/obj/item/storage/box/wizard_kit/yellow/PopulateContents() - new /obj/item/clothing/head/wizard/magus(src) - new /obj/item/clothing/suit/wizrobe/magusred(src) - new /obj/item/clothing/shoes/sandal(src) +/obj/item/storage/box/wizard_kit/magusred/PopulateContents() + return list( + /obj/item/clothing/head/wizard/magus, + /obj/item/clothing/suit/wizrobe/magusred, + /obj/item/clothing/shoes/sandal, + ) /obj/item/storage/box/wizard_kit/magusblue name = "Transmutation Wizard Cosplay Kit" -/obj/item/storage/box/wizard_kit/yellow/PopulateContents() - new /obj/item/clothing/head/wizard/magus(src) - new /obj/item/clothing/suit/wizrobe/magusblue(src) - new /obj/item/clothing/shoes/sandal(src) +/obj/item/storage/box/wizard_kit/magusblue/PopulateContents() + return list( + /obj/item/clothing/head/wizard/magus, + /obj/item/clothing/suit/wizrobe/magusblue, + /obj/item/clothing/shoes/sandal, + ) /obj/item/storage/box/wizard_kit/black name = "Necromancy Wizard Cosplay Kit" /obj/item/storage/box/wizard_kit/black/PopulateContents() - new /obj/item/clothing/head/wizard/black(src) - new /obj/item/clothing/suit/wizrobe/black(src) - new /obj/item/clothing/shoes/sandal(src) + return list( + /obj/item/clothing/head/wizard/black, + /obj/item/clothing/suit/wizrobe/black, + /obj/item/clothing/shoes/sandal, + ) /datum/anonymous_theme/spider_clan name = "Spider Clan" diff --git a/code/modules/antagonists/heretic/items/unfathomable_curio.dm b/code/modules/antagonists/heretic/items/unfathomable_curio.dm index d5f09a1dc27..466e85de4c5 100644 --- a/code/modules/antagonists/heretic/items/unfathomable_curio.dm +++ b/code/modules/antagonists/heretic/items/unfathomable_curio.dm @@ -8,6 +8,8 @@ content_overlays = FALSE drop_sound = 'sound/items/handling/toolbelt_drop.ogg' pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg' + storage_type = /datum/storage/unfathomable_curio_belt + //Vars used for the shield component var/heretic_shield_icon = "unfathomable_shield" var/max_charges = 1 @@ -17,24 +19,6 @@ /obj/item/storage/belt/unfathomable_curio/Initialize(mapload) . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 21 - atom_storage.set_holdable(list( - /obj/item/ammo_box/strilka310/lionhunter, - /obj/item/heretic_labyrinth_handbook, - /obj/item/bodypart, // Bodyparts are often used in rituals. - /obj/item/clothing/neck/eldritch_amulet, - /obj/item/clothing/neck/heretic_focus, - /obj/item/codex_cicatrix, - /obj/item/eldritch_potion, - /obj/item/food/grown/poppy, // Used to regain a Living Heart. - /obj/item/food/grown/harebell, // Used to reroll targets - /obj/item/melee/rune_carver, - /obj/item/melee/sickly_blade, - /obj/item/organ, // Organs are also often used in rituals. - /obj/item/reagent_containers/cup/beaker/eldritch, - /obj/item/stack/sheet/glass, // Glass is often used by moon heretics - )) AddComponent(/datum/component/shielded, max_charges = max_charges, recharge_start_delay = recharge_start_delay, charge_increment_delay = charge_increment_delay, \ charge_recovery = charge_recovery, shield_icon = heretic_shield_icon, run_hit_callback = CALLBACK(src, PROC_REF(shield_damaged))) diff --git a/code/modules/antagonists/traitor/contractor/contractor_items.dm b/code/modules/antagonists/traitor/contractor/contractor_items.dm index 90c495358f2..12a6eb214c2 100644 --- a/code/modules/antagonists/traitor/contractor/contractor_items.dm +++ b/code/modules/antagonists/traitor/contractor/contractor_items.dm @@ -12,9 +12,13 @@ icon_state = "syndiebox" illustration = "writing_syndie" -/obj/item/storage/box/contractor/fulton_extraction/PopulateContents() - new /obj/item/extraction_pack/syndicate(src) - new /obj/item/fulton_core(src) +/obj/item/storage/box/contractor/fulton_extraction/PopulateContents(datum/storage_config/config) + config.compute_max_item_weight = TRUE + + return list( + /obj/item/extraction_pack/syndicate, + /obj/item/fulton_core, + ) /obj/item/paper/contractor_guide name = "Contractor Guide" diff --git a/code/modules/bitrunning/objects/gimmick_disks/_gimmick_disk.dm b/code/modules/bitrunning/objects/gimmick_disks/_gimmick_disk.dm index 2580d8620c7..a43f07c4688 100644 --- a/code/modules/bitrunning/objects/gimmick_disks/_gimmick_disk.dm +++ b/code/modules/bitrunning/objects/gimmick_disks/_gimmick_disk.dm @@ -112,4 +112,4 @@ inhand_icon_state = "sec-case" /obj/item/storage/briefcase/secure/digital_storage/PopulateContents() - return + return NONE diff --git a/code/modules/bitrunning/objects/gimmick_disks/dungeon_disk.dm b/code/modules/bitrunning/objects/gimmick_disks/dungeon_disk.dm index 559c7f022df..8210a77670f 100644 --- a/code/modules/bitrunning/objects/gimmick_disks/dungeon_disk.dm +++ b/code/modules/bitrunning/objects/gimmick_disks/dungeon_disk.dm @@ -110,11 +110,13 @@ illustration = "beaker" /obj/item/storage/box/alchemist_basic_chems/PopulateContents() + . = list() + for(var/i in 1 to 7) if(prob(1)) - new /obj/item/reagent_containers/cup/glass/coffee(src) + . += /obj/item/reagent_containers/cup/glass/coffee continue - new /obj/item/reagent_containers/cup/bottle/alchemist_basic(src) + . += /obj/item/reagent_containers/cup/bottle/alchemist_basic /obj/item/storage/box/alchemist_random_chems name = "box of potions" @@ -123,25 +125,28 @@ illustration = "beaker" /obj/item/storage/box/alchemist_random_chems/PopulateContents() + . = list() + for(var/i in 1 to 7) if(prob(1)) - new /obj/item/reagent_containers/cup/glass/coffee(src) + . += /obj/item/reagent_containers/cup/glass/coffee continue - new /obj/item/reagent_containers/cup/bottle/alchemist_random(src) + . += /obj/item/reagent_containers/cup/bottle/alchemist_random /obj/item/storage/box/alchemist_chemistry_kit name = "box of alchemy tools" desc = "Contains everything needed for the up and coming chemistry student to enact hazardous chemical mishaps in the comfort of their own home." /obj/item/storage/box/alchemist_chemistry_kit/PopulateContents() - new /obj/item/reagent_containers/cup/mortar(src) - new /obj/item/pestle(src) - new /obj/item/lighter/skull(src) - new /obj/item/ph_booklet(src) - new /obj/item/thermometer(src) - new /obj/item/storage/test_tube_rack/full(src) - new /obj/item/reagent_containers/cup/glass/coffee(src) - + return list( + /obj/item/reagent_containers/cup/mortar, + /obj/item/pestle, + /obj/item/lighter/skull, + /obj/item/ph_booklet, + /obj/item/thermometer, + /obj/item/storage/test_tube_rack/full, + /obj/item/reagent_containers/cup/glass/coffee, + ) /datum/bitrunning_gimmick/rogue name = "Rogue" @@ -173,10 +178,11 @@ name = "fannypack of ULTIMATE DESPAIR" /obj/item/storage/belt/fannypack/black/rogue/PopulateContents() - new /obj/item/food/drug/saturnx(src) - new /obj/item/reagent_containers/cup/blastoff_ampoule(src) - new /obj/item/reagent_containers/hypospray/medipen/methamphetamine(src) - + return list( + /obj/item/food/drug/saturnx, + /obj/item/reagent_containers/cup/blastoff_ampoule, + /obj/item/reagent_containers/hypospray/medipen/methamphetamine, + ) /datum/bitrunning_gimmick/healer name = "Healer" diff --git a/code/modules/bitrunning/objects/gimmick_disks/sports_disk.dm b/code/modules/bitrunning/objects/gimmick_disks/sports_disk.dm index 6be07b53d58..397a4c6aba6 100644 --- a/code/modules/bitrunning/objects/gimmick_disks/sports_disk.dm +++ b/code/modules/bitrunning/objects/gimmick_disks/sports_disk.dm @@ -50,13 +50,13 @@ /obj/item/reagent_containers/cup/soda_cans/space_mountain_wind = 50, /obj/item/reagent_containers/cup/soda_cans/monkey_energy = 30, /obj/item/reagent_containers/cup/soda_cans/volt_energy = 15, - /obj/item/reagent_containers/cup/soda_cans/thirteenloko = 5, + /obj/item/reagent_containers/cup/soda_cans/thirteenloko = 5, ) /obj/item/storage/cans/sixenergydrink/PopulateContents() + . = list() for(var/i in 1 to 6) - var/obj/item/chosen_energy_drink = pick_weight(energy_drink_options) - new chosen_energy_drink(src) + . += pick_weight(energy_drink_options) /datum/bitrunning_gimmick/archer @@ -70,23 +70,6 @@ /obj/item/ammo_casing/arrow/holy/blazing, ) -/obj/item/storage/bag/quiver/endless - name = "endless quiver" - desc = "Holds arrows for your bow. A deep digital void is contained within." - max_slots = 1 - -/obj/item/storage/bag/quiver/endless/Initialize(mapload) - . = ..() - RegisterSignal(src, COMSIG_ATOM_EXITED, PROC_REF(handle_removed)) - -/obj/item/storage/bag/quiver/endless/PopulateContents() - . = ..() - new arrow_path(src) - -/obj/item/storage/bag/quiver/endless/proc/handle_removed(datum/source, obj/item/gone) - new arrow_path(src) - - /datum/bitrunning_gimmick/fisher name = "Fisher" @@ -125,13 +108,13 @@ /obj/item/reagent_containers/cup/soda_cans/space_mountain_wind = 15, /obj/item/reagent_containers/cup/soda_cans/monkey_energy = 15, /obj/item/reagent_containers/cup/soda_cans/volt_energy = 10, - /obj/item/reagent_containers/cup/soda_cans/thirteenloko = 5, + /obj/item/reagent_containers/cup/soda_cans/thirteenloko = 5, ) /obj/item/storage/cans/sixgamerdrink/PopulateContents() + . = list() for(var/i in 1 to 6) - var/obj/item/chosen_gamer_drink = pick_weight(gamer_drink_options) - new chosen_gamer_drink(src) + . += pick_weight(gamer_drink_options) /obj/item/modular_computer/laptop/gamer desc = "A high-end laptop often used for metagaming." diff --git a/code/modules/bitrunning/objects/loot_box.dm b/code/modules/bitrunning/objects/loot_box.dm index e142a3e93a4..8575008f0b3 100644 --- a/code/modules/bitrunning/objects/loot_box.dm +++ b/code/modules/bitrunning/objects/loot_box.dm @@ -23,6 +23,8 @@ /obj/item/storage/lockbox/bitrunning/decrypted name = "decrypted curiosity" desc = "Compiled from the virtual domain. An extra reward of a successful bitrunner." + storage_type = /datum/storage/lockbox/bitrunning + /// What virtual domain did we come from. var/datum/lazy_template/virtual_domain/source_domain @@ -42,13 +44,8 @@ source_domain = completed_domain . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_slots = 1 - atom_storage.max_total_storage = 3 - atom_storage.locked = STORAGE_NOT_LOCKED - icon_state = icon_closed + playsound(src, 'sound/effects/magic/blink.ogg', 50, TRUE) /obj/item/storage/lockbox/bitrunning/decrypted/PopulateContents() - var/choice = SSbitrunning.pick_secondary_loot(source_domain) - new choice(src) + return SSbitrunning.pick_secondary_loot(source_domain) diff --git a/code/modules/clothing/chameleon/generic_chameleon_clothing.dm b/code/modules/clothing/chameleon/generic_chameleon_clothing.dm index b2aea379212..83a875332e7 100644 --- a/code/modules/clothing/chameleon/generic_chameleon_clothing.dm +++ b/code/modules/clothing/chameleon/generic_chameleon_clothing.dm @@ -32,8 +32,6 @@ do { \ actions_types = list(/datum/action/item_action/chameleon/change/jumpsuit) action_slots = ALL -/obj/item/clothing/under/chameleon/broken - /obj/item/clothing/under/chameleon/broken/Initialize(mapload) . = ..() BREAK_CHAMELEON_ACTION(src) @@ -280,12 +278,7 @@ do { \ desc = "Holds tools." actions_types = list(/datum/action/item_action/chameleon/change/belt) action_slots = ALL - -/obj/item/storage/belt/chameleon/Initialize(mapload) - . = ..() - atom_storage.silent = TRUE - -/obj/item/storage/belt/chameleon/broken + storage_type = /datum/storage/chameleon_belt /obj/item/storage/belt/chameleon/broken/Initialize(mapload) . = ..() @@ -297,7 +290,6 @@ do { \ actions_types = list(/datum/action/item_action/chameleon/change/headset) action_slots = ALL -/obj/item/radio/headset/chameleon/broken /obj/item/radio/headset/chameleon/broken/Initialize(mapload) . = ..() @@ -309,8 +301,6 @@ do { \ actions_types = list(/datum/action/item_action/chameleon/change/tablet) action_slots = ALL -/obj/item/modular_computer/pda/chameleon/broken - /obj/item/modular_computer/pda/chameleon/broken/Initialize(mapload) . = ..() BREAK_CHAMELEON_ACTION(src) @@ -320,8 +310,6 @@ do { \ actions_types = list(/datum/action/item_action/chameleon/change/stamp) action_slots = ALL -/obj/item/stamp/chameleon/broken - /obj/item/stamp/chameleon/broken/Initialize(mapload) . = ..() BREAK_CHAMELEON_ACTION(src) @@ -341,8 +329,6 @@ do { \ actions_types = list(/datum/action/item_action/chameleon/change/neck) action_slots = ALL -/obj/item/clothing/neck/chameleon/broken - /obj/item/clothing/neck/chameleon/broken/Initialize(mapload) . = ..() BREAK_CHAMELEON_ACTION(src) diff --git a/code/modules/clothing/head/costume.dm b/code/modules/clothing/head/costume.dm index a9a70101afb..9bec6127cec 100644 --- a/code/modules/clothing/head/costume.dm +++ b/code/modules/clothing/head/costume.dm @@ -208,3 +208,21 @@ desc = "A delicate hairpin normally paired with traditional clothing" icon_state = "hairpin_fancy" inhand_icon_state = "hairpin_fancy" + +/obj/item/clothing/head/costume/snakeeater + name = "strange bandana" + desc = "A bandana. It seems to have a little carp embroidered on the inside, as well as the kanji '魚'." + icon_state = "snake_eater" + inhand_icon_state = null + clothing_traits = list(TRAIT_FISH_EATER) + +/obj/item/clothing/head/costume/knight + name = "fake medieval helmet" + desc = "A classic metal helmet. Though, this one seems to be very obviously fake..." + icon = 'icons/obj/clothing/head/helmet.dmi' + worn_icon = 'icons/mob/clothing/head/helmet.dmi' + icon_state = "knight_green" + inhand_icon_state = "knight_helmet" + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT + flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH + dog_fashion = null diff --git a/code/modules/clothing/shoes/cowboy.dm b/code/modules/clothing/shoes/cowboy.dm index 13f393c72ca..71505b9471d 100644 --- a/code/modules/clothing/shoes/cowboy.dm +++ b/code/modules/clothing/shoes/cowboy.dm @@ -18,9 +18,10 @@ /obj/item/clothing/shoes/cowboy/Initialize(mapload) . = ..() - create_storage(storage_type = /datum/storage/pockets/shoes) + if(prob(2)) //There's a snake in my boot new /mob/living/basic/snake(src) + create_storage(storage_type = /datum/storage/pockets/shoes) if(has_spurs) LoadComponent(/datum/component/squeak, spur_sound, 50, falloff_exponent = 20) AddElement(/datum/element/ignites_matches) diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm index 030d2e6c25a..54d8c4b1d9c 100644 --- a/code/modules/detectivework/evidence.dm +++ b/code/modules/detectivework/evidence.dm @@ -78,5 +78,6 @@ desc = "A box claiming to contain evidence bags." /obj/item/storage/box/evidence/PopulateContents() + . = list() for(var/i in 1 to 6) - new /obj/item/evidencebag(src) + . += /obj/item/evidencebag diff --git a/code/modules/events/holiday/easter.dm b/code/modules/events/holiday/easter.dm index dad3f31ba89..07536ad297b 100644 --- a/code/modules/events/holiday/easter.dm +++ b/code/modules/events/holiday/easter.dm @@ -42,28 +42,6 @@ new /mob/living/basic/rabbit/easter/space(spawn_point.loc) CHECK_TICK - -//Easter Baskets -/obj/item/storage/basket/easter - name = "Easter Basket" - -/obj/item/storage/basket/easter/Initialize(mapload) - . = ..() - atom_storage.set_holdable(list(/obj/item/food/egg, /obj/item/food/chocolateegg, /obj/item/food/boiledegg, /obj/item/surprise_egg)) - -/obj/item/storage/basket/easter/proc/countEggs() - cut_overlays() - add_overlay("basket-grass") - add_overlay("basket-egg[min(contents.len, 5)]") - -/obj/item/storage/basket/easter/Exited(atom/movable/gone, direction) - . = ..() - countEggs() - -/obj/item/storage/basket/easter/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) - . = ..() - countEggs() - //Bunny Suit /obj/item/clothing/head/costume/bunnyhead name = "Easter Bunny head" diff --git a/code/modules/events/shuttle_loan/shuttle_loan_items.dm b/code/modules/events/shuttle_loan/shuttle_loan_items.dm index 14257a6a80b..824e8f06536 100644 --- a/code/modules/events/shuttle_loan/shuttle_loan_items.dm +++ b/code/modules/events/shuttle_loan/shuttle_loan_items.dm @@ -1,8 +1,10 @@ /obj/item/storage/belt/fannypack/yellow/bee_terrorist/PopulateContents() - new /obj/item/grenade/c4 (src) - new /obj/item/reagent_containers/applicator/pill/cyanide(src) - new /obj/item/grenade/chem_grenade/facid(src) + return list( + /obj/item/grenade/c4, + /obj/item/reagent_containers/applicator/pill/cyanide, + /obj/item/grenade/chem_grenade/facid, + ) /obj/item/paper/fluff/bee_objectives name = "Objectives of a Bee Liberation Front Operative" diff --git a/code/modules/fishing/aquarium/aquarium_kit.dm b/code/modules/fishing/aquarium/aquarium_kit.dm index 71be9a10f56..5768c843e59 100644 --- a/code/modules/fishing/aquarium/aquarium_kit.dm +++ b/code/modules/fishing/aquarium/aquarium_kit.dm @@ -39,7 +39,7 @@ if(fish_type) var/obj/item/fish/spawned_fish = new fish_type(null) spawned_fish.add_traits(list(TRAIT_NO_FISHING_ACHIEVEMENT, TRAIT_FISH_LOW_PRICE), INNATE_TRAIT) - spawned_fish.forceMove(src) // trigger storage.handle_entered + return spawned_fish /obj/item/storage/fish_case/proc/get_fish_type() return @@ -191,5 +191,4 @@ custom_price = PAYCHECK_LOWER /obj/item/storage/box/aquarium_props/PopulateContents() - for(var/prop_type in subtypesof(/obj/item/aquarium_prop)) - new prop_type(src) + return subtypesof(/obj/item/aquarium_prop) diff --git a/code/modules/fishing/fishing_equipment.dm b/code/modules/fishing/fishing_equipment.dm index 47ee0e6c123..04d0c731f63 100644 --- a/code/modules/fishing/fishing_equipment.dm +++ b/code/modules/fishing/fishing_equipment.dm @@ -322,106 +322,6 @@ var/mob/living/living_target = target living_target.apply_status_effect(/datum/status_effect/grouped/hooked/jaws, rod.fishing_line) -/obj/item/storage/toolbox/fishing - name = "fishing toolbox" - desc = "Contains everything you need for your fishing trip." - icon_state = "fishing" - inhand_icon_state = "artistic_toolbox" - material_flags = NONE - custom_price = PAYCHECK_CREW * 3 - ///How much holding this affects fishing difficulty - var/fishing_modifier = -4 - -/obj/item/storage/toolbox/fishing/Initialize(mapload) - . = ..() - // Can hold fishing rod despite the size - var/static/list/exception_cache = typecacheof(list( - /obj/item/fishing_rod, - )) - atom_storage.exception_hold = exception_cache - AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier, ITEM_SLOT_HANDS) - -/obj/item/storage/toolbox/fishing/PopulateContents() - new /obj/item/bait_can/worm(src) - new /obj/item/fishing_rod/unslotted(src) - new /obj/item/fishing_hook(src) - new /obj/item/fishing_line(src) - new /obj/item/paper/paperslip/fishing_tip(src) - -/obj/item/storage/toolbox/fishing/small - name = "compact fishing toolbox" - desc = "Contains everything you need for your fishing trip. Except for the bait." - w_class = WEIGHT_CLASS_NORMAL - force = 5 - throwforce = 5 - -/obj/item/storage/toolbox/fishing/small/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL //It can still hold a fishing rod - -/obj/item/storage/toolbox/fishing/small/PopulateContents() - new /obj/item/fishing_rod/unslotted(src) - new /obj/item/fishing_hook(src) - new /obj/item/fishing_line(src) - new /obj/item/paper/paperslip/fishing_tip(src) - -/obj/item/storage/toolbox/fishing/master - name = "super fishing toolbox" - desc = "Contains (almost) EVERYTHING you need for your fishing trip." - icon_state = "gold" - inhand_icon_state = "toolbox_gold" - fishing_modifier = -10 - -/obj/item/storage/toolbox/fishing/master/PopulateContents() - new /obj/item/fishing_rod/telescopic/master(src) - new /obj/item/storage/box/fishing_hooks/master(src) - new /obj/item/storage/box/fishing_lines/master(src) - new /obj/item/bait_can/super_baits(src) - new /obj/item/reagent_containers/cup/fish_feed(src) - new /obj/item/aquarium_kit(src) - new /obj/item/fish_analyzer(src) - -/obj/item/storage/box/fishing_hooks - name = "fishing hook set" - illustration = "fish" - custom_price = PAYCHECK_CREW * 2 - -/obj/item/storage/box/fishing_hooks/PopulateContents() - new /obj/item/fishing_hook/magnet(src) - new /obj/item/fishing_hook/shiny(src) - new /obj/item/fishing_hook/weighted(src) - -/obj/item/storage/box/fishing_hooks/master - -/obj/item/storage/box/fishing_hooks/master/PopulateContents() - . = ..() - new /obj/item/fishing_hook/stabilized(src) - new /obj/item/fishing_hook/jaws(src) - -/obj/item/storage/box/fishing_lines - name = "fishing line set" - illustration = "fish" - custom_price = PAYCHECK_CREW * 2 - -/obj/item/storage/box/fishing_lines/PopulateContents() - new /obj/item/fishing_line/bouncy(src) - new /obj/item/fishing_line/reinforced(src) - new /obj/item/fishing_line/cloaked(src) - -/obj/item/storage/box/fishing_lines/master - -/obj/item/storage/box/fishing_lines/master/PopulateContents() - . = ..() - new /obj/item/fishing_line/auto_reel(src) - -/obj/item/storage/box/fish_debug - name = "box full of fish" - illustration = "fish" - -/obj/item/storage/box/fish_debug/PopulateContents() - for(var/fish_type in subtypesof(/obj/item/fish)) - new fish_type(src) - ///Used to give the average player info about fishing stuff that's unknown to many. /obj/item/paper/paperslip/fishing_tip name = "fishing tip" @@ -438,11 +338,13 @@ illustration = "fish" /obj/item/storage/box/fish_revival_kit/PopulateContents() - new /obj/item/lazarus_injector(src) - new /obj/item/reagent_containers/cup/bottle/fishy_reagent(src) - new /obj/item/reagent_containers/cup(src) //to splash the reagents on the fish. - new /obj/item/storage/fish_case(src) - new /obj/item/storage/fish_case(src) + return list( + /obj/item/lazarus_injector, + /obj/item/reagent_containers/cup/bottle/fishy_reagent, + /obj/item/reagent_containers/cup, //to splash the reagents on the fish. + /obj/item/storage/fish_case, + /obj/item/storage/fish_case, + ) /obj/item/storage/box/fishing_lures name = "fishing lures set" @@ -451,16 +353,11 @@ foldable_result = null illustration = "fish" custom_price = PAYCHECK_CREW * 9 + storage_type = /datum/storage/box/fishing_lures /obj/item/storage/box/fishing_lures/PopulateContents() - new /obj/item/paper/lures_instructions(src) - var/list/typesof = typesof(/obj/item/fishing_lure) - for(var/type in typesof) - new type (src) - atom_storage.set_holdable(/obj/item/fishing_lure) //can only hold lures - //adds an extra slot, so we can put back the lures even if we didn't take out the instructions. - atom_storage.max_slots = length(typesof) + 1 - atom_storage.max_total_storage = WEIGHT_CLASS_SMALL * (atom_storage.max_slots + 1) + . = typesof(/obj/item/fishing_lure) + . += /obj/item/paper/lures_instructions /obj/item/paper/lures_instructions name = "instructions paper" @@ -580,43 +477,3 @@ #undef MAGNET_HOOK_BONUS_MULTIPLIER #undef RESCUE_HOOK_FISH_MULTIPLIER - -/obj/item/storage/bag/fishing - name = "fishing bag" - desc = "A vibrant bag for storing caught fish." - icon = 'icons/obj/fishing.dmi' - icon_state = "fishing_bag" - worn_icon_state = "fishing_bag" - resistance_flags = FLAMMABLE - custom_price = PAYCHECK_CREW * 3 - ///How much holding this affects fishing difficulty - var/fishing_modifier = -2 - -/obj/item/storage/bag/fishing/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 24 // Up to 8 normal fish - atom_storage.max_slots = 21 - atom_storage.set_holdable(/obj/item/fish) - AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier, ITEM_SLOT_HANDS) - -/obj/item/storage/bag/fishing/carpskin - name = "carpskin fishing bag" - desc = "A dapper fishing bag made from carpskin. You can store quite a lot of fishing gear in the small pockets formed by larger scales." - icon_state = "fishing_bag_carpskin" - worn_icon_state = "fishing_bag_carpskin" - resistance_flags = ACID_PROOF - storage_type = /datum/storage/carpskin_bag - fishing_modifier = -4 - -/obj/item/storage/bag/fishing/carpskin/Initialize(mapload) - . = ..() - atom_storage.max_total_storage = 42 // Up to 14 normal fish, but we're assuming that you'll be storing a bunch of gear as well - atom_storage.set_holdable(list( - /obj/item/fish, - /obj/item/fishing_line, - /obj/item/fishing_hook, - /obj/item/fishing_lure, - /obj/item/fish_analyzer, - /obj/item/bait_can, - )) diff --git a/code/modules/food_and_drinks/machinery/coffeemaker.dm b/code/modules/food_and_drinks/machinery/coffeemaker.dm index 489a548cc56..7bec8fb4029 100644 --- a/code/modules/food_and_drinks/machinery/coffeemaker.dm +++ b/code/modules/food_and_drinks/machinery/coffeemaker.dm @@ -492,11 +492,8 @@ open_status = FANCY_CONTAINER_ALWAYS_OPEN spawn_type = /obj/item/coffee_cartridge spawn_count = 1 + storage_type = /datum/storage/coffee_cart_rack -/obj/item/storage/fancy/coffee_cart_rack/Initialize(mapload) - . = ..() - atom_storage.max_slots = 4 - atom_storage.set_holdable(/obj/item/coffee_cartridge) /* * impressa coffee maker diff --git a/code/modules/mapfluff/ruins/spaceruin_code/forgottenship.dm b/code/modules/mapfluff/ruins/spaceruin_code/forgottenship.dm index bc36823ebc8..5ea1e1d2b7d 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/forgottenship.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/forgottenship.dm @@ -94,8 +94,9 @@ GLOBAL_VAR_INIT(fscpassword, generate_password()) desc = "A box full of special syndicate firing pins which allow only syndicate operatives to use weapons with those firing pins." /obj/item/storage/box/firingpins/syndicate/PopulateContents() + . = list() for(var/i in 1 to 5) - new /obj/item/firing_pin/implant/pindicate(src) + . += /obj/item/firing_pin/implant/pindicate /////////// AI Laws diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm deleted file mode 100644 index 3a7687ebebf..00000000000 --- a/code/modules/mining/money_bag.dm +++ /dev/null @@ -1,37 +0,0 @@ -/*****************************Money bag********************************/ - -/obj/item/storage/bag/money - name = "money bag" - desc = "A bag for storing your profits." - icon_state = "moneybag" - worn_icon_state = "moneybag" - force = 10 - throwforce = 0 - resistance_flags = FLAMMABLE - max_integrity = 100 - w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/bag/money/Initialize(mapload) - . = ..() - if(prob(20)) - icon_state = "moneybagalt" - atom_storage.max_slots = 40 - atom_storage.max_specific_storage = 40 - atom_storage.set_holdable(list(/obj/item/coin, /obj/item/stack/spacecash, /obj/item/holochip)) - -/obj/item/storage/bag/money/vault/PopulateContents() - new /obj/item/coin/silver(src) - new /obj/item/coin/silver(src) - new /obj/item/coin/silver(src) - new /obj/item/coin/silver(src) - new /obj/item/coin/gold(src) - new /obj/item/coin/gold(src) - new /obj/item/coin/adamantine(src) - -///Used in the dutchmen pirate shuttle. -/obj/item/storage/bag/money/dutchmen/PopulateContents() - for(var/iteration in 1 to 9) - new /obj/item/coin/silver/doubloon(src) - for(var/iteration in 1 to 9) - new /obj/item/coin/gold/doubloon(src) - new /obj/item/coin/adamantine/doubloon(src) diff --git a/code/modules/mob/living/basic/drone/drone_tools.dm b/code/modules/mob/living/basic/drone/drone_tools.dm index dfb05a8d3a9..5dbcb3f0816 100644 --- a/code/modules/mob/living/basic/drone/drone_tools.dm +++ b/code/modules/mob/living/basic/drone/drone_tools.dm @@ -14,20 +14,22 @@ /obj/item/storage/drone_tools/PopulateContents() var/list/builtintools = list() - builtintools += new /obj/item/crowbar/drone(src) - builtintools += new /obj/item/screwdriver/drone(src) - builtintools += new /obj/item/wrench/drone(src) - builtintools += new /obj/item/weldingtool/drone(src) - builtintools += new /obj/item/wirecutters/drone(src) - builtintools += new /obj/item/multitool/drone(src) - builtintools += new /obj/item/pipe_dispenser/drone(src) - builtintools += new /obj/item/t_scanner/drone(src) - builtintools += new /obj/item/analyzer/drone(src) - builtintools += new /obj/item/soap/drone(src) + builtintools += new /obj/item/crowbar/drone(null) + builtintools += new /obj/item/screwdriver/drone(null) + builtintools += new /obj/item/wrench/drone(null) + builtintools += new /obj/item/weldingtool/drone(null) + builtintools += new /obj/item/wirecutters/drone(null) + builtintools += new /obj/item/multitool/drone(null) + builtintools += new /obj/item/pipe_dispenser/drone(null) + builtintools += new /obj/item/t_scanner/drone(null) + builtintools += new /obj/item/analyzer/drone(null) + builtintools += new /obj/item/soap/drone(null) for(var/obj/item/tool as anything in builtintools) tool.AddComponent(/datum/component/holderloving, src) + return builtintools + /obj/item/crowbar/drone name = "built-in crowbar" desc = "A crowbar built into your chassis." diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm b/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm deleted file mode 100644 index a3de2f4b2fe..00000000000 --- a/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm +++ /dev/null @@ -1,40 +0,0 @@ - -/obj/item/storage/bag/quiver - name = "quiver" - desc = "Holds arrows for your bow. Good, because while pocketing arrows is possible, it surely can't be pleasant." - icon = 'icons/obj/weapons/bows/quivers.dmi' - icon_state = "quiver" - inhand_icon_state = null - worn_icon_state = "harpoon_quiver" - /// type of arrow the quivel should hold - var/arrow_path = /obj/item/ammo_casing/arrow - var/max_slots = 40 - -/obj/item/storage/bag/quiver/Initialize(mapload) - . = ..() - atom_storage.numerical_stacking = TRUE - atom_storage.max_specific_storage = WEIGHT_CLASS_TINY - atom_storage.max_slots = max_slots - atom_storage.max_total_storage = 100 - atom_storage.set_holdable(/obj/item/ammo_casing/arrow) - -/obj/item/storage/bag/quiver/lesser - max_slots = 10 - -/obj/item/storage/bag/quiver/full/PopulateContents() - . = ..() - for(var/i in 1 to 10) - new arrow_path(src) - -/obj/item/storage/bag/quiver/holy - name = "divine quiver" - desc = "Holds arrows for your divine bow, where they wait to find their target." - icon_state = "holyquiver" - inhand_icon_state = "holyquiver" - worn_icon_state = "holyquiver" - arrow_path = /obj/item/ammo_casing/arrow/holy - -/obj/item/storage/bag/quiver/holy/PopulateContents() - . = ..() - for(var/i in 1 to 10) - new arrow_path(src) diff --git a/code/modules/projectiles/guns/energy/dueling.dm b/code/modules/projectiles/guns/energy/dueling.dm index 95707874e72..c2ec48d1f74 100644 --- a/code/modules/projectiles/guns/energy/dueling.dm +++ b/code/modules/projectiles/guns/energy/dueling.dm @@ -352,34 +352,6 @@ B.dismember() qdel(B) -//Storage case. -/obj/item/storage/lockbox/dueling - name = "dueling pistol case" - desc = "Let's solve this like gentlespacemen." - icon_state = "medalbox+l" - inhand_icon_state = "syringe_kit" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - w_class = WEIGHT_CLASS_NORMAL - req_access = list(ACCESS_CAPTAIN) - icon_locked = "medalbox+l" - icon_closed = "medalbox" - icon_broken = "medalbox+b" - base_icon_state = "medalbox" - icon_open = "medalboxopen" - -/obj/item/storage/lockbox/dueling/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.max_slots = 2 - atom_storage.set_holdable(/obj/item/gun/energy/dueling) - -/obj/item/storage/lockbox/dueling/PopulateContents() - . = ..() - var/obj/item/gun/energy/dueling/gun_A = new(src) - var/obj/item/gun/energy/dueling/gun_B = new(src) - new /datum/duel(gun_A, gun_B) - #undef DUEL_IDLE #undef DUEL_PREPARATION #undef DUEL_READY diff --git a/code/modules/research/part_replacer.dm b/code/modules/research/part_replacer.dm index 53831026444..086db3bc2d3 100644 --- a/code/modules/research/part_replacer.dm +++ b/code/modules/research/part_replacer.dm @@ -114,49 +114,54 @@ //RPED with tiered contents /obj/item/storage/part_replacer/bluespace/tier1/PopulateContents() - for(var/i in 1 to 10) - new /obj/item/stock_parts/capacitor(src) - new /obj/item/stock_parts/scanning_module(src) - new /obj/item/stock_parts/servo(src) - new /obj/item/stock_parts/micro_laser(src) - new /obj/item/stock_parts/matter_bin(src) - new /obj/item/stock_parts/power_store/cell/high(src) + return flatten_quantified_list(list( + /obj/item/stock_parts/capacitor = 10, + /obj/item/stock_parts/scanning_module = 10, + /obj/item/stock_parts/servo = 10, + /obj/item/stock_parts/micro_laser = 10, + /obj/item/stock_parts/matter_bin = 10, + /obj/item/stock_parts/power_store/cell/high = 10, + )) /obj/item/storage/part_replacer/bluespace/tier2/PopulateContents() - for(var/i in 1 to 10) - new /obj/item/stock_parts/capacitor/adv(src) - new /obj/item/stock_parts/scanning_module/adv(src) - new /obj/item/stock_parts/servo/nano(src) - new /obj/item/stock_parts/micro_laser/high(src) - new /obj/item/stock_parts/matter_bin/adv(src) - new /obj/item/stock_parts/power_store/cell/super(src) + return flatten_quantified_list(list( + /obj/item/stock_parts/capacitor/adv = 10, + /obj/item/stock_parts/scanning_module/adv = 10, + /obj/item/stock_parts/servo/nano = 10, + /obj/item/stock_parts/micro_laser/high = 10, + /obj/item/stock_parts/matter_bin/adv = 10, + /obj/item/stock_parts/power_store/cell/super = 10, + )) /obj/item/storage/part_replacer/bluespace/tier3/PopulateContents() - for(var/i in 1 to 10) - new /obj/item/stock_parts/capacitor/super(src) - new /obj/item/stock_parts/scanning_module/phasic(src) - new /obj/item/stock_parts/servo/pico(src) - new /obj/item/stock_parts/micro_laser/ultra(src) - new /obj/item/stock_parts/matter_bin/super(src) - new /obj/item/stock_parts/power_store/cell/hyper(src) + return flatten_quantified_list(list( + /obj/item/stock_parts/capacitor/super = 10, + /obj/item/stock_parts/scanning_module/phasic = 10, + /obj/item/stock_parts/servo/pico = 10, + /obj/item/stock_parts/micro_laser/ultra = 10, + /obj/item/stock_parts/matter_bin/super = 10, + /obj/item/stock_parts/power_store/cell/hyper = 10, + )) /obj/item/storage/part_replacer/bluespace/tier4/PopulateContents() - for(var/i in 1 to 10) - new /obj/item/stock_parts/capacitor/quadratic(src) - new /obj/item/stock_parts/scanning_module/triphasic(src) - new /obj/item/stock_parts/servo/femto(src) - new /obj/item/stock_parts/micro_laser/quadultra(src) - new /obj/item/stock_parts/matter_bin/bluespace(src) - new /obj/item/stock_parts/power_store/cell/bluespace(src) + return flatten_quantified_list(list( + /obj/item/stock_parts/capacitor/quadratic = 10, + /obj/item/stock_parts/scanning_module/triphasic = 10, + /obj/item/stock_parts/servo/femto = 10, + /obj/item/stock_parts/micro_laser/quadultra = 10, + /obj/item/stock_parts/matter_bin/bluespace = 10, + /obj/item/stock_parts/power_store/cell/bluespace = 10, + )) //used in a cargo crate /obj/item/storage/part_replacer/cargo/PopulateContents() - for(var/i in 1 to 10) - new /obj/item/stock_parts/capacitor(src) - new /obj/item/stock_parts/scanning_module(src) - new /obj/item/stock_parts/servo(src) - new /obj/item/stock_parts/micro_laser(src) - new /obj/item/stock_parts/matter_bin(src) + return flatten_quantified_list(list( + /obj/item/stock_parts/capacitor = 10, + /obj/item/stock_parts/scanning_module = 10, + /obj/item/stock_parts/servo = 10, + /obj/item/stock_parts/micro_laser = 10, + /obj/item/stock_parts/matter_bin = 10, + )) ///Cyborg variant /obj/item/storage/part_replacer/cyborg diff --git a/code/modules/shuttle/mobile_port/variants/emergency/pods.dm b/code/modules/shuttle/mobile_port/variants/emergency/pods.dm index 40a4cc16cdb..51aa25c1b43 100644 --- a/code/modules/shuttle/mobile_port/variants/emergency/pods.dm +++ b/code/modules/shuttle/mobile_port/variants/emergency/pods.dm @@ -127,57 +127,6 @@ name = "emergency disembarkation tool" desc = "For extracting yourself from rough landings." -/datum/storage/pod - max_slots = 14 - max_total_storage = WEIGHT_CLASS_BULKY * 14 - /// If TRUE, we unlock regardless of security level - var/always_unlocked = FALSE - -/datum/storage/pod/open_storage(mob/to_show) - if(isliving(to_show) && SSsecurity_level.get_current_level_as_number() < SEC_LEVEL_RED) - to_chat(to_show, span_warning("The storage unit will only unlock during a Red or Delta security alert.")) - return FALSE - return ..() - -/datum/storage/pod/New(atom/parent, max_slots, max_specific_storage, max_total_storage) - . = ..() - // all of these are a type below what actually spawn with - // (IE all space suits instead of just the emergency ones) - // because an enterprising traitor might be able to hide things, - // like their syndicate toolbox or softsuit. may be fun? - var/static/list/exception_cache = typecacheof(list( - /obj/item/clothing/suit/space, - /obj/item/pickaxe, - /obj/item/storage/toolbox, - )) - src.exception_hold = exception_cache - RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(update_lock)) - update_lock(new_level = SSsecurity_level.get_current_level_as_number()) - -/datum/storage/pod/set_parent(atom/new_parent) - . = ..() - RegisterSignal(parent, COMSIG_ATOM_AFTER_SHUTTLE_MOVE, PROC_REF(pod_launch)) - -/datum/storage/pod/proc/update_lock(datum/source, new_level) - SIGNAL_HANDLER - if(always_unlocked) - return - - locked = (new_level < SEC_LEVEL_RED) ? STORAGE_FULLY_LOCKED : STORAGE_NOT_LOCKED - parent.update_appearance(UPDATE_ICON_STATE) - if(locked) // future todo : make `locked` a setter so this behavior can be built in (avoids exploits) - close_all() - -/datum/storage/pod/proc/pod_launch(datum/source, turf/old_turf) - SIGNAL_HANDLER - // This check is to ignore the movement of the shuttle from the transit level to the station as it is loaded in. - if(old_turf && is_reserved_level(old_turf.z)) - return - // If the pod was launched, the storage will always open. - always_unlocked = TRUE - locked = STORAGE_NOT_LOCKED - parent.update_appearance(UPDATE_ICON_STATE) - /obj/item/storage/pod name = "emergency space suits" desc = "A wall mounted safe containing space suits. Will only open in emergencies." @@ -187,6 +136,13 @@ icon_state = "wall_safe_locked" storage_type = /datum/storage/pod +/obj/item/storage/pod/Initialize(mapload) + . = ..() + + var/datum/storage/pod/storage = atom_storage + + storage.update_lock(new_level = SSsecurity_level.get_current_level_as_number()) + /obj/item/storage/pod/update_icon_state() . = ..() icon_state = "wall_safe[atom_storage?.locked ? "_locked" : ""]" @@ -194,17 +150,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/item/storage/pod, 32) /obj/item/storage/pod/PopulateContents() - new /obj/item/clothing/head/helmet/space/orange(src) - new /obj/item/clothing/head/helmet/space/orange(src) - new /obj/item/clothing/suit/space/orange(src) - new /obj/item/clothing/suit/space/orange(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/tank/internals/oxygen/red(src) - new /obj/item/tank/internals/oxygen/red(src) - new /obj/item/pickaxe/emergency(src) - new /obj/item/pickaxe/emergency(src) - new /obj/item/survivalcapsule(src) - new /obj/item/storage/toolbox/emergency(src) - new /obj/item/bodybag/environmental(src) - new /obj/item/bodybag/environmental(src) + return flatten_quantified_list(list( + /obj/item/clothing/head/helmet/space/orange = 2, + /obj/item/clothing/suit/space/orange = 2, + /obj/item/clothing/mask/gas = 2, + /obj/item/tank/internals/oxygen/red = 2, + /obj/item/pickaxe/emergency = 2, + /obj/item/survivalcapsule = 1, + /obj/item/storage/toolbox/emergency = 1, + /obj/item/bodybag/environmental = 2, + )) diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm index d604344ba98..7489e64dc94 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm @@ -367,6 +367,8 @@ icon_state = "cyber_implants" /obj/item/storage/box/cyber_implants/PopulateContents() - new /obj/item/autosurgeon/syndicate/xray_eyes(src) - new /obj/item/autosurgeon/syndicate/anti_stun(src) - new /obj/item/autosurgeon/syndicate/reviver(src) + return list( + /obj/item/autosurgeon/syndicate/xray_eyes, + /obj/item/autosurgeon/syndicate/anti_stun, + /obj/item/autosurgeon/syndicate/reviver + ) diff --git a/code/modules/vehicles/mecha/mecha_control_console.dm b/code/modules/vehicles/mecha/mecha_control_console.dm index a9dbca0e07d..da67747b842 100644 --- a/code/modules/vehicles/mecha/mecha_control_console.dm +++ b/code/modules/vehicles/mecha/mecha_control_console.dm @@ -151,11 +151,6 @@ name = "exosuit tracking beacons" /obj/item/storage/box/mechabeacons/PopulateContents() - ..() - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) + . = list() + for(var/_ in 1 to 7) + . += /obj/item/mecha_parts/mecha_tracking diff --git a/tgstation.dme b/tgstation.dme index 8aacf2a5efa..93986120e2f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -539,6 +539,7 @@ #include "code\_globalvars\rcd.dm" #include "code\_globalvars\religion.dm" #include "code\_globalvars\silo.dm" +#include "code\_globalvars\storage_config.dm" #include "code\_globalvars\tgui.dm" #include "code\_globalvars\time_vars.dm" #include "code\_globalvars\lists\achievements.dm" @@ -1967,22 +1968,24 @@ #include "code\datums\status_effects\debuffs\vision\nearsighted.dm" #include "code\datums\storage\storage.dm" #include "code\datums\storage\storage_interface.dm" -#include "code\datums\storage\subtypes\backpack.dm" -#include "code\datums\storage\subtypes\bag_of_holding.dm" -#include "code\datums\storage\subtypes\cards.dm" -#include "code\datums\storage\subtypes\carpskin_bag.dm" -#include "code\datums\storage\subtypes\drone.dm" -#include "code\datums\storage\subtypes\duffel_bag.dm" -#include "code\datums\storage\subtypes\extract_inventory.dm" -#include "code\datums\storage\subtypes\fish_case.dm" -#include "code\datums\storage\subtypes\implant.dm" -#include "code\datums\storage\subtypes\organ_box.dm" +#include "code\datums\storage\subtypes\backpacks.dm" +#include "code\datums\storage\subtypes\bags.dm" +#include "code\datums\storage\subtypes\belts.dm" +#include "code\datums\storage\subtypes\boxes.dm" +#include "code\datums\storage\subtypes\dufflebags.dm" +#include "code\datums\storage\subtypes\holsters.dm" +#include "code\datums\storage\subtypes\lockboxes.dm" +#include "code\datums\storage\subtypes\medkits.dm" #include "code\datums\storage\subtypes\pockets.dm" -#include "code\datums\storage\subtypes\portable_chem_mixer.dm" -#include "code\datums\storage\subtypes\rped.dm" -#include "code\datums\storage\subtypes\surgery_tray.dm" -#include "code\datums\storage\subtypes\test_tube_rack.dm" -#include "code\datums\storage\subtypes\trash.dm" +#include "code\datums\storage\subtypes\toolboxes.dm" +#include "code\datums\storage\subtypes\others\bag_of_holding.dm" +#include "code\datums\storage\subtypes\others\cards.dm" +#include "code\datums\storage\subtypes\others\carpskin_bag.dm" +#include "code\datums\storage\subtypes\others\extract_inventory.dm" +#include "code\datums\storage\subtypes\others\fish_case.dm" +#include "code\datums\storage\subtypes\others\misc.dm" +#include "code\datums\storage\subtypes\others\pod.dm" +#include "code\datums\storage\subtypes\others\rped.dm" #include "code\datums\votes\_vote_datum.dm" #include "code\datums\votes\custom_vote.dm" #include "code\datums\votes\map_vote.dm" @@ -2706,20 +2709,22 @@ #include "code\game\objects\items\storage\basket.dm" #include "code\game\objects\items\storage\belt.dm" #include "code\game\objects\items\storage\briefcase.dm" +#include "code\game\objects\items\storage\dufflebags.dm" #include "code\game\objects\items\storage\fancy.dm" #include "code\game\objects\items\storage\garment.dm" #include "code\game\objects\items\storage\holsters.dm" #include "code\game\objects\items\storage\lockbox.dm" #include "code\game\objects\items\storage\medkit.dm" +#include "code\game\objects\items\storage\misc.dm" +#include "code\game\objects\items\storage\pillbottles.dm" #include "code\game\objects\items\storage\sixpack.dm" #include "code\game\objects\items\storage\storage.dm" -#include "code\game\objects\items\storage\toolbox.dm" -#include "code\game\objects\items\storage\uplink_kits.dm" #include "code\game\objects\items\storage\wallets.dm" #include "code\game\objects\items\storage\boxes\_boxes.dm" #include "code\game\objects\items\storage\boxes\cargo_boxes.dm" #include "code\game\objects\items\storage\boxes\clothes_boxes.dm" #include "code\game\objects\items\storage\boxes\engineering_boxes.dm" +#include "code\game\objects\items\storage\boxes\fishing_boxes.dm" #include "code\game\objects\items\storage\boxes\flat_boxes.dm" #include "code\game\objects\items\storage\boxes\food_boxes.dm" #include "code\game\objects\items\storage\boxes\implant_boxes.dm" @@ -2728,6 +2733,16 @@ #include "code\game\objects\items\storage\boxes\science_boxes.dm" #include "code\game\objects\items\storage\boxes\security_boxes.dm" #include "code\game\objects\items\storage\boxes\service_boxes.dm" +#include "code\game\objects\items\storage\boxes\trait_boxes.dm" +#include "code\game\objects\items\storage\boxes\uplink_kits.dm" +#include "code\game\objects\items\storage\toolboxes\_toolbox.dm" +#include "code\game\objects\items\storage\toolboxes\emergency.dm" +#include "code\game\objects\items\storage\toolboxes\fishing.dm" +#include "code\game\objects\items\storage\toolboxes\mechanical.dm" +#include "code\game\objects\items\storage\toolboxes\medical.dm" +#include "code\game\objects\items\storage\toolboxes\misc.dm" +#include "code\game\objects\items\storage\toolboxes\service.dm" +#include "code\game\objects\items\storage\toolboxes\weapons.dm" #include "code\game\objects\items\tanks\jetpack.dm" #include "code\game\objects\items\tanks\tank_types.dm" #include "code\game\objects\items\tanks\tanks.dm" @@ -4769,7 +4784,6 @@ #include "code\modules\mining\machine_stacking.dm" #include "code\modules\mining\machine_unloading.dm" #include "code\modules\mining\mine_items.dm" -#include "code\modules\mining\money_bag.dm" #include "code\modules\mining\ores_coins.dm" #include "code\modules\mining\satchel_ore_box.dm" #include "code\modules\mining\shelters.dm" @@ -5720,7 +5734,6 @@ #include "code\modules\projectiles\guns\ballistic\toy.dm" #include "code\modules\projectiles\guns\ballistic\bows\_bow.dm" #include "code\modules\projectiles\guns\ballistic\bows\bow_arrows.dm" -#include "code\modules\projectiles\guns\ballistic\bows\bow_quivers.dm" #include "code\modules\projectiles\guns\ballistic\bows\bow_types.dm" #include "code\modules\projectiles\guns\energy\beam_rifle.dm" #include "code\modules\projectiles\guns\energy\crank_guns.dm"