diff --git a/beestation.dme b/beestation.dme index d4abc6470f3b1..f6d5d032728b9 100644 --- a/beestation.dme +++ b/beestation.dme @@ -1604,6 +1604,7 @@ #include "code\game\objects\structures\bedsheet_bin.dm" #include "code\game\objects\structures\bot_elevator.dm" #include "code\game\objects\structures\catwalk.dm" +#include "code\game\objects\structures\crateshelf.dm" #include "code\game\objects\structures\destructible_structures.dm" #include "code\game\objects\structures\displaycase.dm" #include "code\game\objects\structures\divine.dm" diff --git a/code/game/objects/items/stacks/sheets/mineral/metals_recipes.dm b/code/game/objects/items/stacks/sheets/mineral/metals_recipes.dm index cbe052eba15c9..cbdcd75572126 100644 --- a/code/game/objects/items/stacks/sheets/mineral/metals_recipes.dm +++ b/code/game/objects/items/stacks/sheets/mineral/metals_recipes.dm @@ -44,6 +44,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ )), null, \ new/datum/stack_recipe("rack parts", /obj/item/rack_parts), \ + new/datum/stack_recipe("crate shelf parts", /obj/item/rack_parts/shelf), \ new /datum/stack_recipe_list("closets", list( \ new/datum/stack_recipe("closet", /obj/structure/closet, 2, one_per_turf = TRUE, on_floor = TRUE, time = 1.5 SECONDS), \ new/datum/stack_recipe("emergency closet", /obj/structure/closet/emcloset/empty, 2, one_per_turf = TRUE, on_floor = TRUE, time = 1.5 SECONDS), \ diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index ff8830813de75..d552cbd2a255e 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -13,6 +13,7 @@ allow_objects = TRUE allow_dense = TRUE dense_when_open = TRUE + mouse_drag_pointer = TRUE delivery_icon = "deliverycrate" door_anim_time = 3 door_anim_angle = 120 // how fast the angle should go? @@ -100,11 +101,27 @@ animation_math["[door_anim_time]-[door_anim_angle]-[azimuth_angle_2]-[radius_2]-[door_hinge]"] = new_animation_math_sublist /obj/structure/closet/crate/attack_hand(mob/user) - . = ..() - if(.) - return + if(istype(src.loc, /obj/structure/crate_shelf)) + return FALSE // No opening crates in shelves!! if(manifest) tear_manifest(user) + return ..() + +/obj/structure/closet/crate/MouseDrop(atom/drop_atom, src_location, over_location) + . = ..() + var/mob/living/user = usr + if(!isliving(user)) + return // Ghosts busted. + if(!isturf(user.loc) || user.incapacitated() || !(user.mobility_flags & MOBILITY_STAND)) + return // If the user is in a weird state, don't bother trying. + if(get_dist(user, src) != 1 || get_dist(drop_atom, user) != 1) + return // Check whether the user is next to the shelf and if the crate is next to the user. + if(istype(drop_atom, /turf/open) && istype(loc, /obj/structure/crate_shelf) && user.Adjacent(drop_atom)) + var/obj/structure/crate_shelf/shelf = loc + return shelf.unload(src, user, drop_atom) // If we're being dropped onto a turf, and we're inside of a crate shelf, unload. + if(istype(drop_atom, /obj/structure/crate_shelf) && isturf(loc) && user.Adjacent(src)) + var/obj/structure/crate_shelf/shelf = drop_atom + return shelf.load(src, user) // If we're being dropped onto a crate shelf, and we're in a turf, load. /obj/structure/closet/crate/after_open(mob/living/user, force) . = ..() diff --git a/code/game/objects/structures/crateshelf.dm b/code/game/objects/structures/crateshelf.dm new file mode 100644 index 0000000000000..cdbc22ba1717e --- /dev/null +++ b/code/game/objects/structures/crateshelf.dm @@ -0,0 +1,145 @@ +#define DEFAULT_SHELF_CAPACITY 3 // Default capacity of the shelf +#define DEFAULT_SHELF_USE_DELAY 1 SECONDS // Default interaction delay of the shelf +#define DEFAULT_SHELF_VERTICAL_OFFSET 16 // Vertical pixel offset of shelving-related things. Set to 10 by default due to this leaving more of the crate on-screen to be clicked. + +/obj/structure/crate_shelf + name = "crate shelf" + desc = "It's a shelf! For storing crates!" + icon = 'icons/obj/objects.dmi' + icon_state = "shelf" + density = TRUE + anchored = TRUE + layer = BELOW_OBJ_LAYER + max_integrity = 50 // Not hard to break + + var/capacity = DEFAULT_SHELF_CAPACITY + var/use_delay = DEFAULT_SHELF_USE_DELAY + var/list/shelf_contents + +/obj/structure/crate_shelf/tall + capacity = 12 + +/obj/structure/crate_shelf/Initialize(mapload) + . = ..() + shelf_contents = new/list(capacity) // Initialize our shelf's contents list, this will be used later. + var/stack_layer // This is used to generate the sprite layering of the shelf pieces. + var/stack_offset // This is used to generate the vertical offset of the shelf pieces. + for(var/i in 1 to (capacity - 1)) + stack_layer = ABOVE_MOB_LAYER + (0.02 * i) - 0.01 // Make each shelf piece render above the last, but below the crate that should be on it. + stack_offset = DEFAULT_SHELF_VERTICAL_OFFSET * i // Make each shelf piece physically above the last. + overlays += image(icon = 'icons/obj/objects.dmi', icon_state = "shelf", layer = stack_layer, pixel_y = stack_offset) + return + +/obj/structure/crate_shelf/Destroy() + QDEL_LIST(shelf_contents) + return ..() + +/obj/structure/crate_shelf/examine(mob/user) + . = ..() + . += "There are some bolts holding [src] together." + if(shelf_contents.Find(null)) // If there's an empty space in the shelf, let the examiner know. + . += "You could drag a crate into [src]." + if(contents.len) // If there are any crates in the shelf, let the examiner know. + . += "You could drag a crate out of [src]." + . += "[src] contains:" + for(var/obj/structure/closet/crate/crate in shelf_contents) + . += " [icon2html(crate, user)] [crate]" + +/obj/structure/crate_shelf/attackby(obj/item/item, mob/living/user, params) + if (item.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1)) + item.play_tool_sound(src) + if(do_after(user, 3 SECONDS, target = src)) + deconstruct(TRUE) + return TRUE + return ..() + +/obj/structure/crate_shelf/relay_container_resist(mob/living/user, obj/structure/closet/crate) + to_chat(user, "You begin attempting to knock [crate] out of [src].") + if(do_after(user, 30 SECONDS, target = crate)) + if(!user || user.stat != CONSCIOUS || user.loc != crate || crate.loc != src) + return // If the user is in a strange condition, return early. + visible_message("[crate] falls off of [src]!", + "You manage to knock [crate] free of [src].", + "[crate]'s lid falls open!") + else // If we somehow fail to open the crate, just break it instead! + crate.visible_message("[crate] falls apart!") + crate.deconstruct() + if(7) // Break that crate! + crate.visible_message("[crate] falls apart!") + crate.deconstruct() + shelf_contents[shelf_contents.Find(crate)] = null + if(!(flags_1&NODECONSTRUCT_1)) + density = FALSE + var/obj/item/rack_parts/shelf/newparts = new(loc) + transfer_fingerprints_to(newparts) + return ..() + +/obj/item/rack_parts/shelf + name = "crate shelf parts" + desc = "Parts of a shelf." + construction_type = /obj/structure/crate_shelf + icon_state = "crate_shelf" + +#undef DEFAULT_SHELF_CAPACITY +#undef DEFAULT_SHELF_USE_DELAY +#undef DEFAULT_SHELF_VERTICAL_OFFSET diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 14e084ffe5e05..544cb9177e98b 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -750,6 +750,7 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/structure/table) flags_1 = CONDUCT_1 custom_materials = list(/datum/material/iron=2000) var/building = FALSE + var/obj/construction_type = /obj/structure/rack /obj/item/rack_parts/attackby(obj/item/W, mob/user, params) if (W.tool_behaviour == TOOL_WRENCH) @@ -759,14 +760,17 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/structure/table) . = ..() /obj/item/rack_parts/attack_self(mob/user) + if(locate(construction_type) in get_turf(user)) + balloon_alert(user, "no room!") + return if(building) return building = TRUE - to_chat(user, "You start constructing a rack...") + to_chat(user, "You start assembling [src]...") if(do_after(user, 50, target = user)) if(!user.temporarilyRemoveItemFromInventory(src)) return - var/obj/structure/rack/R = new /obj/structure/rack(user.loc) + var/obj/structure/R = new construction_type(user.loc) user.visible_message("[user] assembles \a [R].\ ", "You assemble \a [R].") R.add_fingerprint(user) diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index eb591381cd35a..28870d80405f5 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index a8879186624de..b01cb0279fa43 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ