Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions code/game/objects/items/stacks/sheets/light.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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 <b>iron</b> to complete it.")
Expand Down
15 changes: 9 additions & 6 deletions code/game/objects/items/stacks/stack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions code/game/objects/items/storage/backpack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
2 changes: 1 addition & 1 deletion code/modules/clothing/outfits/ert.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions code/modules/slapcrafting/base_steps/slapcraft_step_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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%."
30 changes: 30 additions & 0 deletions code/modules/slapcrafting/base_steps/slapcraft_step_stack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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."
15 changes: 15 additions & 0 deletions code/modules/slapcrafting/crafting_items/components.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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'

67 changes: 48 additions & 19 deletions code/modules/slapcrafting/living_slapcraft.dm
Original file line number Diff line number Diff line change
@@ -1,37 +1,61 @@
#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
// or they must be on the floor
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
Expand All @@ -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.<hr>[jointext(errors, "<br>")]")
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.<hr>[jointext(errors, "<br>")]")
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
15 changes: 15 additions & 0 deletions code/modules/slapcrafting/recipes/clothing/back.dm
Original file line number Diff line number Diff line change
@@ -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)
. = ..()
11 changes: 11 additions & 0 deletions code/modules/slapcrafting/recipes/components/rope.dm
Original file line number Diff line number Diff line change
@@ -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
9 changes: 6 additions & 3 deletions code/modules/slapcrafting/slapcraft_recipe.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions daedalus.dme
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Binary file modified icons/mob/clothing/back.dmi
Binary file not shown.
Binary file modified icons/obj/slapcrafting/components.dmi
Binary file not shown.
Binary file modified icons/obj/storage.dmi
Binary file not shown.
Loading