diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 84485e8459d4..f5723e0bc813 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -729,10 +729,12 @@ DEFINE_INTERACTABLE(/obj/item) R.activate_module(src) R.hud_used.update_robot_modules_display() -/obj/item/attackby(obj/item/item, mob/living/user, params) - if(user?.try_slapcraft(src, item)) - return TRUE - return ..() +/obj/item/base_item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = ..() + if(.) + return + + return user.try_slapcraft(src, tool) /obj/item/proc/GetDeconstructableContents() return get_all_contents() - src diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm index b8aff0c6c856..bea31e850482 100644 --- a/code/game/objects/items/stacks/sheets/light.dm +++ b/code/game/objects/items/stacks/sheets/light.dm @@ -13,6 +13,9 @@ grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/copper = 5) merge_type = /obj/item/stack/light_w +/obj/item/stack/light_w/thirty + amount = 30 + /obj/item/stack/light_w/examine(mob/user) . = ..() . += span_alert("The [name] looks unfinished, add iron to complete it.") diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 307951c997d0..9eacee115472 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -167,6 +167,7 @@ /obj/item/stack/get_controls_info() . = ..() . += "Right Click - Split stack." + . += "Right Click (Same item) - Combine stack." /// Set the maptext for the item that shows how much junk is inside the trunk. /obj/item/stack/proc/update_maptext() @@ -632,10 +633,12 @@ /obj/item/stack/proc/on_movable_entered_occupied_turf(datum/source, atom/movable/arrived) SIGNAL_HANDLER - // Edge case. This signal will also be sent when src has entered the turf. Don't want to merge with ourselves. if(arrived == src) return + if(!isturf(loc)) + return + if(!arrived.throwing && can_merge(arrived)) INVOKE_ASYNC(src, PROC_REF(merge), arrived) @@ -722,13 +725,13 @@ is_zero_amount(delete_if_zero = TRUE) -/obj/item/stack/attackby(obj/item/W, mob/user, params) - if(can_merge(W, inhand = TRUE)) - var/obj/item/stack/S = W +/obj/item/stack/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(modifiers?[RIGHT_CLICK] && can_merge(tool, inhand = TRUE)) + var/obj/item/stack/S = tool if(merge(S)) to_chat(user, span_notice("[S] [stack_name] of [S.name] now contains [S.get_amount()] [S.singular_name]\s.")) - else - . = ..() + return ITEM_INTERACT_SUCCESS + return ITEM_INTERACT_BLOCKING /obj/item/stack/microwave_act(obj/machinery/microwave/M) if(istype(M) && M.dirty < 100) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index ee266c74b3e0..3a83b663f242 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -751,3 +751,13 @@ TYPEINFO_DEF(/obj/item/storage/backpack/holding) slowdown = 0 supports_variations_flags = NONE + +/obj/item/storage/backpack/sling + name = "sling bag" + desc = "A sling made out of cloth." + icon_state = "slingbag" + +/obj/item/storage/backpack/sling/Initialize() + . = ..() + atom_storage.max_slots = 3 + atom_storage.max_total_storage = 5 // Can hold 1 normal item and 2 tiny items. diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index fd77cc84e062..d506a7ef93a5 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -453,7 +453,7 @@ backpack_contents = list( /obj/item/construction/rcd/loaded = 1, /obj/item/etherealballdeployer = 1, - /obj/item/stack/light_w = 30, + /obj/item/stack/light_w/thirty = 1, /obj/item/stack/sheet/glass/fifty = 1, /obj/item/stack/sheet/iron/fifty = 1, /obj/item/stack/sheet/plasteel/twenty = 1, diff --git a/code/modules/slapcrafting/base_steps/slapcraft_step_items.dm b/code/modules/slapcrafting/base_steps/slapcraft_step_items.dm index ba6f4cc5bd74..bb8da9f9b3ee 100644 --- a/code/modules/slapcrafting/base_steps/slapcraft_step_items.dm +++ b/code/modules/slapcrafting/base_steps/slapcraft_step_items.dm @@ -109,3 +109,9 @@ /// Disambiguation go BRRRR /datum/slapcraft_step/item/flashlight/again +/datum/slapcraft_step/item/rope + desc = "Attach some rope." + item_types = list(/obj/item/rope) + + finish_msg = "%USER% attaches rope to the %TARGET%." + finish_msg_self = "You attach rope to the %TARGET%." diff --git a/code/modules/slapcrafting/base_steps/slapcraft_step_stack.dm b/code/modules/slapcrafting/base_steps/slapcraft_step_stack.dm index 9016ee62eff2..76779fa99f13 100644 --- a/code/modules/slapcrafting/base_steps/slapcraft_step_stack.dm +++ b/code/modules/slapcrafting/base_steps/slapcraft_step_stack.dm @@ -192,3 +192,33 @@ start_msg_self = "You begin attaching a wooden plank to the %TARGET%." finish_msg = "%USER% attaches a wooden plank to the %TARGET%." finish_msg_self = "You attach a wooden plank to the %TARGET%." + +/// Cloth stack +/datum/slapcraft_step/stack/cloth + desc = "Add a cloth sheet to the assembly." + todo_desc = "You could add a cloth sheet..." + item_types = list(/obj/item/stack/sheet/cloth) + amount = 1 + + start_msg = "%USER% begins attaching some cloth to the %TARGET%." + start_msg_self = "You begin inserting some cloth to the %TARGET%." + finish_msg = "%USER% attaches some cloth to the %TARGET%." + finish_msg_self = "You attach some cloth to the %TARGET%." + +/datum/slapcraft_step/stack/cloth/five + desc = "Add 5 cloth sheets to the assembly." + todo_desc = "You could add 5 cloth sheets..." + item_types = list(/obj/item/stack/sheet/cloth) + amount = 5 + + start_msg = "%USER% begins attaching some cloth to the %TARGET%." + start_msg_self = "You begin inserting some cloth to the %TARGET%." + finish_msg = "%USER% attaches some cloth to the %TARGET%." + finish_msg_self = "You attach some cloth to the %TARGET%." + +/// Used for crafting rope. +/datum/slapcraft_step/stack/cloth/rope + start_msg = "%USER% begins tying some cloth together." + start_msg_self = "%USER% begins tying some cloth together." + finish_msg = "%USER% ties some cloth together." + finish_msg_self = "%USER% ties some cloth together." diff --git a/code/modules/slapcrafting/crafting_items/components.dm b/code/modules/slapcrafting/crafting_items/components.dm index d92734ab00a3..76de66cff779 100644 --- a/code/modules/slapcrafting/crafting_items/components.dm +++ b/code/modules/slapcrafting/crafting_items/components.dm @@ -30,3 +30,18 @@ TYPEINFO_DEF(/obj/item/metal_ball) w_class = WEIGHT_CLASS_BULKY attack_verb_continuous = list("hits", "thwacks", "bowls") attack_verb_simple = list("hit", "thwack", "bowl") + +/obj/item/rope + name = "strand of rope" + desc = "A length of rope." + icon = 'icons/obj/slapcrafting/components.dmi' + icon_state = "rope" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + inhand_icon_state = "coil" + + w_class = WEIGHT_CLASS_NORMAL + + drop_sound = 'sound/items/handling/cloth_drop.ogg' + pickup_sound = 'sound/items/handling/cloth_pickup.ogg' + diff --git a/code/modules/slapcrafting/living_slapcraft.dm b/code/modules/slapcrafting/living_slapcraft.dm index d958fcb1139d..5bf94b0d299a 100644 --- a/code/modules/slapcrafting/living_slapcraft.dm +++ b/code/modules/slapcrafting/living_slapcraft.dm @@ -1,3 +1,7 @@ +#define SLAPCRAFT_INVALID -1 +#define SLAPCRAFT_FAILED 0 +#define SLAPCRAFT_SUCCESS 1 + /// Have a living mob attempt to do a slapcraft. The mob is using the second item on the first item. /mob/living/proc/try_slapcraft(obj/item/first_item, obj/item/second_item) // You cannot craft with items in storage, you must be holding them in hand @@ -5,33 +9,53 @@ if((first_item.item_flags | second_item.item_flags) & IN_STORAGE) return FALSE + . = __slapcraft(src, first_item, second_item) + switch(.) + if(SLAPCRAFT_SUCCESS) + return ITEM_INTERACT_SUCCESS + + if(SLAPCRAFT_FAILED) + return ITEM_INTERACT_BLOCKING + + . = __slapcraft(src, second_item, first_item) + switch(.) + if(SLAPCRAFT_SUCCESS) + return ITEM_INTERACT_SUCCESS + + if(SLAPCRAFT_FAILED) + return ITEM_INTERACT_BLOCKING + + return NONE + +/// Wrapper proc, so we can try both permutations per interaction. +/proc/__slapcraft(mob/user, obj/item/first_item, obj/item/second_item) // We need to find a recipe where the first item corresponds to the first step // ..and the second item corresponds to the second step var/list/available_recipes = slapcraft_recipes_for_type(first_item.type) - if(!available_recipes) - return FALSE + if(!length(available_recipes)) + return SLAPCRAFT_INVALID var/list/recipes = list() for(var/datum/slapcraft_recipe/recipe in available_recipes) //Always start from step one. var/datum/slapcraft_step/step_one = SLAPCRAFT_STEP(recipe.steps[1]) - if(!step_one.perform_check(src, first_item, null)) + if(!(step_one.perform_check(user, first_item, null))) continue // Get next suitable step that is available after the first one would be performed. var/list/pretend_list = list() pretend_list[step_one.type] = TRUE - var/datum/slapcraft_step/next_step = recipe.next_suitable_step(src, second_item, pretend_list, check_type_only = TRUE) + var/datum/slapcraft_step/next_step = recipe.next_suitable_step(user, second_item, pretend_list, check_type_only = TRUE) if(!next_step) continue - if(!next_step.perform_check(src, second_item, null, check_type_only = TRUE)) + if(!next_step.perform_check(user, second_item, null, check_type_only = TRUE)) continue recipes += recipe if(!length(recipes)) - return FALSE + return SLAPCRAFT_INVALID var/datum/slapcraft_recipe/target_recipe // If we have only one recipe, choose it instantly @@ -45,42 +69,47 @@ recipe_choices[recipe.name] = recipe.get_radial_image() recipe_choice_translation[recipe.name] = recipe - var/choice = show_radial_menu(src, first_item, recipe_choices, custom_check = FALSE, require_near = TRUE) + var/choice = show_radial_menu(user, first_item, recipe_choices, custom_check = FALSE, require_near = TRUE) if(choice) target_recipe = recipe_choice_translation[choice] + if(!target_recipe) - return TRUE + return SLAPCRAFT_FAILED // We have found the recipe we want to do, make an assembly item where the first item used to be. var/obj/item/slapcraft_assembly/assembly = new() assembly.set_recipe(target_recipe) /// The location to place the assembly or items if the user cannot hold them - var/atom/fallback_loc = drop_location() + var/atom/fallback_loc = user.drop_location() var/datum/slapcraft_step/step_one = SLAPCRAFT_STEP(target_recipe.steps[1]) var/list/errors = list() // Instantly and silently perform the first step on the assembly, disassemble it if something went wrong - if(!step_one.perform(src, first_item, assembly, instant = TRUE, silent = TRUE, error_list = errors)) + if(!step_one.perform(user, first_item, assembly, instant = TRUE, silent = TRUE, error_list = errors)) assembly.disassemble() if(length(errors)) errors = span_danger("I cannot craft that.
[jointext(errors, "
")]") - to_chat(src, examine_block(errors)) - return TRUE + to_chat(user, examine_block(errors)) + return SLAPCRAFT_FAILED - fallback_loc = drop_location() //We may have moved + fallback_loc = user.drop_location() //We may have moved - if(!put_in_hands(assembly)) + if(!user.put_in_hands(assembly)) assembly.forceMove(fallback_loc) - var/datum/slapcraft_step/step_two = target_recipe.next_suitable_step(src, second_item, assembly.step_states, check_type_only = TRUE) + var/datum/slapcraft_step/step_two = target_recipe.next_suitable_step(user, second_item, assembly.step_states, check_type_only = TRUE) // Perform the second step, also disassemble it if we stopped working on it, because keeping 1 component assembly is futile. - if(!step_two.perform(src, second_item, assembly, error_list = errors)) + if(!step_two.perform(user, second_item, assembly, error_list = errors)) assembly.disassemble() if(length(errors)) errors = span_danger("I cannot craft that.
[jointext(errors, "
")]") - to_chat(src, examine_block(errors)) - return TRUE - return TRUE + to_chat(user, examine_block(errors)) + return SLAPCRAFT_FAILED + return SLAPCRAFT_SUCCESS + +#undef SLAPCRAFT_INVALID +#undef SLAPCRAFT_FAILED +#undef SLAPCRAFT_SUCCESS diff --git a/code/modules/slapcrafting/recipes/clothing/back.dm b/code/modules/slapcrafting/recipes/clothing/back.dm new file mode 100644 index 000000000000..7c353d8e2411 --- /dev/null +++ b/code/modules/slapcrafting/recipes/clothing/back.dm @@ -0,0 +1,15 @@ +/datum/slapcraft_recipe/sling + name = "cloth sling" + examine_hint = "You could craft a sling with some rope." + category = SLAP_CAT_COMPONENTS + show_finish_text = TRUE + + steps = list( + /datum/slapcraft_step/stack/cloth/five, + /datum/slapcraft_step/item/rope, + ) + + result_type = /obj/item/storage/backpack/sling + +/datum/slapcraft_recipe/sling/finish_recipe(mob/living/user, obj/item/slapcraft_assembly/assembly) + . = ..() diff --git a/code/modules/slapcrafting/recipes/components/rope.dm b/code/modules/slapcrafting/recipes/components/rope.dm new file mode 100644 index 000000000000..7a4ed5c03040 --- /dev/null +++ b/code/modules/slapcrafting/recipes/components/rope.dm @@ -0,0 +1,11 @@ +/datum/slapcraft_recipe/rope + name = "rope" + examine_hint = "You could tie together cloth." + category = SLAP_CAT_COMPONENTS + show_finish_text = TRUE + + steps = list( + /datum/slapcraft_step/stack/cloth, + /datum/slapcraft_step/stack/cloth/rope + ) + result_type = /obj/item/rope diff --git a/code/modules/slapcrafting/slapcraft_recipe.dm b/code/modules/slapcrafting/slapcraft_recipe.dm index ee4001640513..7716325fa84c 100644 --- a/code/modules/slapcrafting/slapcraft_recipe.dm +++ b/code/modules/slapcrafting/slapcraft_recipe.dm @@ -34,6 +34,9 @@ // Can this assembly be taken apart before it's finished? var/can_disassemble = TRUE + /// Set to TRUE to delete all of the crafting components when the recipe is complete instead of moving them into the result. + var/destroy_components_on_completion = FALSE + /// Should we print text when we finish? Mostly used to de-bloat chat. var/show_finish_text = FALSE @@ -192,8 +195,9 @@ // Move items which wanted to go to the resulted item into it. Only supports for the first created item. var/atom/movable/first_item = results[1] - for(var/obj/item/item as anything in assembly.items_to_place_in_result) - item.forceMove(first_item) + if(!destroy_components_on_completion) + for(var/obj/item/item as anything in assembly.items_to_place_in_result) + item.forceMove(first_item) for(var/obj/item/item as anything in (results - assembly.items_to_place_in_result)) assembly.finished_items += item @@ -240,7 +244,6 @@ /// Behaviour after the item is created, and before the slapcrafting assembly is disposed. /// Here you can move the components into the item if you wish, or do other stuff with them. /datum/slapcraft_recipe/proc/after_create_items(list/items_list, obj/item/slapcraft_assembly/assembly) - return /// Here is the proc to get rid of the assembly, should one want to override it to handle that differently. /datum/slapcraft_recipe/proc/dispose_assembly(obj/item/slapcraft_assembly/assembly) diff --git a/daedalus.dme b/daedalus.dme index d967f81f1555..0d103283ab2b 100644 --- a/daedalus.dme +++ b/daedalus.dme @@ -4572,7 +4572,9 @@ #include "code\modules\slapcrafting\base_steps\slapcraft_step_tool.dm" #include "code\modules\slapcrafting\base_steps\slapcraft_step_weapon.dm" #include "code\modules\slapcrafting\crafting_items\components.dm" +#include "code\modules\slapcrafting\recipes\clothing\back.dm" #include "code\modules\slapcrafting\recipes\components\metal_shaping.dm" +#include "code\modules\slapcrafting\recipes\components\rope.dm" #include "code\modules\slapcrafting\recipes\components\wired_rod.dm" #include "code\modules\slapcrafting\recipes\medical\prosthetics.dm" #include "code\modules\slapcrafting\recipes\medical\splints.dm" diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi index ada5f5ea41b6..7728df7df15d 100644 Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ diff --git a/icons/obj/slapcrafting/components.dmi b/icons/obj/slapcrafting/components.dmi index 6b9b785a8085..3b3fe9600743 100644 Binary files a/icons/obj/slapcrafting/components.dmi and b/icons/obj/slapcrafting/components.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 7d5cb94f1c56..caeab6ea5647 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ