From fc5d5a9fe3e2f0fdbe2f04aaf3ef64f2fb7201ef Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sun, 9 Apr 2023 03:29:51 +0200 Subject: [PATCH] [MIRROR] Componentizes loomability [MDB IGNORE] (#20424) * Componentizes loomability (#74552) ## About The Pull Request As shrimple as the title might imply, the ability for an item to be processed in a loom is now a component. Behavior on looming cotton, durathread, and wool, should all be the exact same in terms of cost, time, results, etc. ## Why It's Good For The Game If, for any reason, someone might want to extend the behavior of "this thing can be loomed" to other items, it can be done. ## Changelog :cl: code: The ability for objects to be loomed is now a component, with all of the looming behavior moved off of the structure and into said component. The actual behavior for looming cotton (clicking on a loom with cotton) is completely unchanged. /:cl: --------- Co-authored-by: Zephyr <12817816+ZephyrTFA@ users.noreply.github.com> * Componentizes loomability --------- Co-authored-by: Paxilmaniac <82386923+Paxilmaniac@users.noreply.github.com> Co-authored-by: Zephyr <12817816+ZephyrTFA@ users.noreply.github.com> --- code/datums/components/loomable.dm | 76 +++++++++++++++++++ .../items/stacks/sheets/sheet_types.dm | 6 +- code/game/objects/structures/loom.dm | 26 ------- tgstation.dme | 1 + 4 files changed, 82 insertions(+), 27 deletions(-) create mode 100644 code/datums/components/loomable.dm diff --git a/code/datums/components/loomable.dm b/code/datums/components/loomable.dm new file mode 100644 index 00000000000..6c033528d71 --- /dev/null +++ b/code/datums/components/loomable.dm @@ -0,0 +1,76 @@ +/// Component that makes items turn into other items when you use them on a loom (or any other thing really if you change the var) +/datum/component/loomable + /// What will spawn when the parent is loomed + var/resulting_item + /// How much of parent do we need to loom, will be ignored if parent isnt a stack + var/required_amount + /// What thing we look for triggering the loom process (usually a loom) + var/obj/target_thing + /// What verb best fits the action of processing whatever the item is, for example "spun [thing]" + var/process_completion_verb + /// If target_thing needs to be anchored + var/target_needs_anchoring + /// How long it takes to loom the parent + var/loom_time + +/datum/component/loomable/Initialize( + resulting_item, + required_amount = 4, + target_thing = /obj/structure/loom, + process_completion_verb = "spun", + target_needs_anchoring = TRUE, + loom_time = 1 SECONDS + ) + + src.resulting_item = resulting_item + src.required_amount = required_amount + src.target_thing = target_thing + src.process_completion_verb = process_completion_verb + src.target_needs_anchoring = target_needs_anchoring + src.loom_time = loom_time + +/datum/component/loomable/RegisterWithParent() + RegisterSignal(parent, COMSIG_ITEM_ATTACK_OBJ, PROC_REF(try_and_loom_me)) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine)) + +/datum/component/loomable/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_ITEM_ATTACK_OBJ, COMSIG_PARENT_EXAMINE)) + +/// Checks if the thing we clicked on can be used as a loom, and if we can actually loom the parent at present (an example being does the stack have enough in it (if its a stack)) +/datum/component/loomable/proc/try_and_loom_me(datum/source, obj/target, mob/living/user) + SIGNAL_HANDLER + + if(!istype(target, target_thing)) + return + + if(target_needs_anchoring && !(target.anchored)) + user.balloon_alert(user, "[target] must be secured!") + return + + if((required_amount > 1) && istype(parent, /obj/item/stack)) + var/obj/item/stack/parent_stack = parent + if(parent_stack.amount < required_amount) + user.balloon_alert(user, "need [required_amount] of [parent]!") + return + + INVOKE_ASYNC(src, PROC_REF(loom_me), user, target) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/// If a do_after of the specified loom_time passes, will create a new one of resulting_item and either delete the parent, or .use the required amount if its a stack +/datum/component/loomable/proc/loom_me(mob/living/user, obj/structure/loom/target) + if(!do_after(user, loom_time, target)) + return + + var/new_thing = new resulting_item(target.drop_location()) + user.balloon_alert_to_viewers("[process_completion_verb] [new_thing]") + if(isstack(parent)) + var/obj/item/stack/stack_we_use = parent + stack_we_use.use(required_amount) + else + qdel(parent) + +/// Adds an examine blurb to the description of any item that can be loomed +/datum/component/loomable/proc/on_examine(mob/living/source, mob/examiner, list/examine_list) + SIGNAL_HANDLER + + examine_list += span_notice("You could probably process [parent] at a [initial(target_thing.name)].") diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 86c25385407..790d3d76f10 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -520,10 +520,14 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \ force = 0 throwforce = 0 merge_type = /obj/item/stack/sheet/cotton - var/pull_effort = 10 + var/pull_effort = 1 SECONDS var/loom_result = /obj/item/stack/sheet/cloth grind_results = list(/datum/reagent/cellulose = 20) +/obj/item/stack/sheet/cotton/Initialize(mapload) + . = ..() + AddComponent(/datum/component/loomable, resulting_item = loom_result, loom_time = pull_effort) + /obj/item/stack/sheet/cotton/durathread name = "raw durathread bundle" desc = "A bundle of raw durathread ready to be spun on the loom." diff --git a/code/game/objects/structures/loom.dm b/code/game/objects/structures/loom.dm index f7ad19a0b88..e08e5899ccc 100644 --- a/code/game/objects/structures/loom.dm +++ b/code/game/objects/structures/loom.dm @@ -1,6 +1,3 @@ -#define FABRIC_PER_SHEET 4 - - ///This is a loom. It's usually made out of wood and used to weave fabric like durathread or cotton into their respective cloth types. /obj/structure/loom name = "loom" @@ -21,30 +18,7 @@ AddElement(/datum/element/contextual_screentip_item_typechecks, hovering_item_typechecks) -/obj/structure/loom/attackby(obj/item/I, mob/user) - if(weave(I, user)) - return - return ..() - /obj/structure/loom/wrench_act(mob/living/user, obj/item/tool) . = ..() default_unfasten_wrench(user, tool, time = 0.5 SECONDS) return TOOL_ACT_TOOLTYPE_SUCCESS - -///Handles the weaving. -/obj/structure/loom/proc/weave(obj/item/stack/sheet/cotton/W, mob/user) - if(!istype(W)) - return FALSE - if(!anchored) - user.show_message(span_notice("The loom needs to be wrenched down."), MSG_VISUAL) - return FALSE - if(W.amount < FABRIC_PER_SHEET) - user.show_message(span_notice("You need at least [FABRIC_PER_SHEET] units of fabric before using this."), MSG_VISUAL) - return FALSE - user.show_message(span_notice("You start weaving \the [W.name] through the loom.."), MSG_VISUAL) - while(W.use_tool(src, user, W.pull_effort) && W.use(FABRIC_PER_SHEET)) - new W.loom_result(drop_location()) - user.show_message(span_notice("You weave \the [W.name] into a workable fabric."), MSG_VISUAL) - return TRUE - -#undef FABRIC_PER_SHEET diff --git a/tgstation.dme b/tgstation.dme index b0d178fd73f..ac3c303682a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1014,6 +1014,7 @@ #include "code\datums\components\label.dm" #include "code\datums\components\light_eater.dm" #include "code\datums\components\lock_on_cursor.dm" +#include "code\datums\components\loomable.dm" #include "code\datums\components\manual_blinking.dm" #include "code\datums\components\manual_breathing.dm" #include "code\datums\components\material_container.dm"