From 4778981111d7659b11694c6a8072f4c9c35afbbd Mon Sep 17 00:00:00 2001 From: CHOMPStation2StaffMirrorBot <94713762+CHOMPStation2StaffMirrorBot@users.noreply.github.com> Date: Wed, 1 Oct 2025 16:36:52 -0700 Subject: [PATCH] [MIRROR] Makes weaver TGUI (#11768) Co-authored-by: Cameron Lennox --- code/__defines/dcs/signals.dm | 12 - code/_helpers/global_lists_vr.dm | 8 + code/datums/components/traits/weaver.dm | 234 ++++++++---------- .../human/species/station/traits/positive.dm | 2 + .../packages/tgui/interfaces/WeaverConfig.tsx | 152 ++++++++++++ 5 files changed, 272 insertions(+), 136 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/WeaverConfig.tsx diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index ae817fc0a4..c95050f3a3 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -937,18 +937,6 @@ /// COMSIG used to get messages where they need to go #define COMSIG_VISIBLE_MESSAGE "visible_message" -// Weaver Component -///from /mob/living/proc/check_silk_amount() -#define COMSIG_CHECK_SILK_AMOUNT "check_silk_amount" -///from /mob/living/proc/weave_structure() -#define COMSIG_WEAVE_STRUCTURE "weave_structure" -///from /mob/living/proc/toggle_silk_production() -#define COMSIG_TOGGLE_SILK_PRODUCTION "toggle_silk_production" -///from /mob/living/proc/weave_item() -#define COMSIG_WEAVE_ITEM "weave_item" -///from /mob/living/proc/set_silk_color() -#define COMSIG_SET_SILK_COLOR "set_silk_color" - // Gargoyle Component ///from /mob/living/carbon/human/proc/gargoyle_transformation() #define COMSIG_GARGOYLE_TRANSFORMATION "gargoyle_transformation" diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm index 958bc34158..6ad6947ab6 100644 --- a/code/_helpers/global_lists_vr.dm +++ b/code/_helpers/global_lists_vr.dm @@ -630,10 +630,18 @@ GLOBAL_LIST_EMPTY(existing_solargrubs) continue //A prototype or something GLOB.weavable_items[instance.title] = instance + paths = subtypesof(/datum/weaver_recipe) + for(var/path in paths) + var/datum/weaver_recipe/instance = new path() + if(!instance.title) + continue //A prototype or something + GLOB.all_weavable[instance.title] = instance + return 1 // Hooks must return 1 GLOBAL_LIST_EMPTY(weavable_structures) GLOBAL_LIST_EMPTY(weavable_items) +GLOBAL_LIST_EMPTY(all_weavable) GLOBAL_LIST_INIT(xenobio_metal_materials_normal, list( diff --git a/code/datums/components/traits/weaver.dm b/code/datums/components/traits/weaver.dm index 15e799fa43..92db42a89e 100644 --- a/code/datums/components/traits/weaver.dm +++ b/code/datums/components/traits/weaver.dm @@ -17,22 +17,12 @@ return COMPONENT_INCOMPATIBLE owner = parent - add_verb(owner, /mob/living/proc/check_silk_amount) - add_verb(owner, /mob/living/proc/toggle_silk_production) - add_verb(owner, /mob/living/proc/weave_structure) - add_verb(owner, /mob/living/proc/weave_item) - add_verb(owner, /mob/living/proc/set_silk_color) + add_verb(owner, /mob/living/proc/weaver_control_panel) + if(ishuman(parent)) + add_verb(owner, /mob/living/carbon/human/proc/enter_cocoon) //Processing RegisterSignal(owner, COMSIG_LIVING_LIFE, PROC_REF(process_component)) - - //When procs are used - RegisterSignal(owner, COMSIG_CHECK_SILK_AMOUNT, PROC_REF(check_silk_amount)) - RegisterSignal(owner, COMSIG_WEAVE_STRUCTURE, PROC_REF(weave_structure)) - RegisterSignal(owner, COMSIG_TOGGLE_SILK_PRODUCTION, PROC_REF(toggle_silk_production)) - RegisterSignal(owner, COMSIG_WEAVE_ITEM, PROC_REF(weave_item)) - RegisterSignal(owner, COMSIG_SET_SILK_COLOR, PROC_REF(set_silk_color)) - /datum/component/weaver/proc/process_component() if (QDELETED(parent)) return @@ -40,16 +30,9 @@ /datum/component/weaver/Destroy(force = FALSE) UnregisterSignal(owner, COMSIG_LIVING_LIFE) //IF we registered a signal, we need to unregister it. - UnregisterSignal(owner, COMSIG_CHECK_SILK_AMOUNT) - UnregisterSignal(owner, COMSIG_WEAVE_STRUCTURE) - UnregisterSignal(owner, COMSIG_TOGGLE_SILK_PRODUCTION) - UnregisterSignal(owner, COMSIG_WEAVE_ITEM) - UnregisterSignal(owner, COMSIG_SET_SILK_COLOR) - remove_verb(owner, /mob/living/proc/check_silk_amount) - remove_verb(owner, /mob/living/proc/toggle_silk_production) - remove_verb(owner, /mob/living/proc/weave_structure) - remove_verb(owner, /mob/living/proc/weave_item) - remove_verb(owner, /mob/living/proc/set_silk_color) + remove_verb(owner, /mob/living/proc/weaver_control_panel) + if(ishuman(parent)) + remove_verb(owner, /mob/living/carbon/human/proc/enter_cocoon) owner = null . = ..() @@ -58,105 +41,110 @@ silk_reserve = min(silk_reserve + silk_generation_amount, silk_max_reserve) owner.adjust_nutrition(-(nutrtion_per_silk*silk_generation_amount)) - -/mob/living/proc/check_silk_amount() - set name = "Check Silk Amount" - set category = "Abilities.Weaver" - SEND_SIGNAL(src, COMSIG_CHECK_SILK_AMOUNT) - -/datum/component/weaver/proc/check_silk_amount() - to_chat(owner, "Your silk reserves are at [silk_reserve]/[silk_max_reserve].") - -/mob/living/proc/toggle_silk_production() - set name = "Toggle Silk Production" - set category = "Abilities.Weaver" - SEND_SIGNAL(src, COMSIG_TOGGLE_SILK_PRODUCTION) - -/datum/component/weaver/proc/toggle_silk_production() - silk_production = !(silk_production) - to_chat(owner, "You are [silk_production ? "now" : "no longer"] producing silk.") - -/mob/living/proc/weave_structure() - set name = "Weave Structure" - set category = "Abilities.Weaver" - SEND_SIGNAL(src, COMSIG_WEAVE_STRUCTURE) - -/datum/component/weaver/proc/weave_structure() - - var/choice - var/datum/weaver_recipe/structure/desired_result - var/finalized = "No" - - while(finalized == "No" && owner.client) - choice = tgui_input_list(owner,"What would you like to weave?", "Weave Choice", GLOB.weavable_structures) - desired_result = GLOB.weavable_structures[choice] - if(!desired_result || !istype(desired_result)) - return - - if(choice) - finalized = tgui_alert(owner, "Are you sure you want to weave [desired_result.title]? It will cost you [desired_result.cost] silk.","Confirmation",list("Yes","No")) - - if(!desired_result || !istype(desired_result)) - return - - if(desired_result.cost > silk_reserve) - to_chat(owner, span_warning("You don't have enough silk to weave that!")) - return - - if(owner.stat) - to_chat(owner, span_warning("You can't do that in your current state!")) - return - - if(locate(desired_result.result_type) in owner.loc) - to_chat(owner, span_warning("You can't create another weaversilk [desired_result.title] here!")) - return - - if(!isturf(owner.loc)) - to_chat(owner, span_warning("You can't weave here!")) - return - - if(do_after(owner, desired_result.time, target = owner)) - if(desired_result.cost > silk_reserve) - to_chat(owner, span_warning("You don't have enough silk to weave that!")) - return - - if(locate(desired_result.result_type) in owner.loc) - to_chat(owner, span_warning("You can't create another weaversilk [desired_result.title] here!")) - return - - if(!isturf(owner.loc)) - to_chat(owner, span_warning("You can't weave here!")) - return - - silk_reserve = max(silk_reserve - desired_result.cost, 0) - - var/atom/O = new desired_result.result_type(owner.loc) - O.color = silk_color - - -/mob/living/proc/weave_item() - set name = "Weave Item" - set category = "Abilities.Weaver" - SEND_SIGNAL(src, COMSIG_WEAVE_ITEM) - /datum/component/weaver/proc/weave_item() var/choice var/datum/weaver_recipe/item/desired_result var/finalized = "No" while(finalized == "No" && owner.client) - choice = tgui_input_list(owner,"What would you like to weave?", "Weave Choice", GLOB.weavable_items) - desired_result = GLOB.weavable_items[choice] + choice = tgui_input_list(owner,"What would you like to weave?", "Weave Choice", GLOB.all_weavable) + desired_result = GLOB.all_weavable[choice] if(!desired_result || !istype(desired_result)) return if(choice) finalized = tgui_alert(owner, "Are you sure you want to weave [desired_result.title]? It will cost you [desired_result.cost] silk.","Confirmation",list("Yes","No")) - if(!desired_result || !istype(desired_result)) - return + weave_check(desired_result.cost, desired_result.result_type) - if(desired_result.cost > silk_reserve) +//TGUI Weaver Panel +/datum/component/weaver/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "WeaverConfig", "Weaver Config") + ui.open() + + +/mob/living/proc/weaver_control_panel() + set name = "Weaver Control Panel" + set desc = "Allows you to adjust the settings of various weaver settings!" + set category = "Abilities.Weaver" + + var/datum/component/weaver/weave = get_weaver_component() + if(!weave) + to_chat(src, span_warning("Only a weaver can use that!")) + return FALSE + + weave.tgui_interact(src) + +/mob/living/proc/get_weaver_component() + var/datum/component/weaver/weave = GetComponent(/datum/component/weaver) + if(weave) + return weave + +/datum/component/weaver/tgui_data(mob/user) + var/data = list( + "silk_reserve" = silk_reserve, + "silk_max_reserve" = silk_max_reserve, + "silk_color" = silk_color, + "silk_production" = silk_production, + "savefile_selected" = correct_savefile_selected() + ) + + return data + +/datum/component/weaver/tgui_close(mob/user) + SScharacter_setup.queue_preferences_save(user?.client?.prefs) + . = ..() + +/datum/component/weaver/proc/correct_savefile_selected() + if(owner.client.prefs.default_slot == owner.mind.loaded_from_slot) + return TRUE + return FALSE + +/datum/component/weaver/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + switch(action) + if("new_silk_color") + var/set_new_color = tgui_color_picker(ui.user, "Select a color you wish your silk to be!", "Color Selector", silk_color) + if(!set_new_color) + return FALSE + silk_color = set_new_color + return TRUE + if("toggle_silk_production") + silk_production = !(silk_production) + to_chat(owner, span_info("You are [silk_production ? "now" : "no longer"] producing silk.")) + return FALSE + if("check_silk_amount") + to_chat(owner, span_info("Your silk reserves are at [silk_reserve]/[silk_max_reserve].")) + return FALSE + /* //Unused. + if("weave_item") //The global list of items. + weave_item() + return TRUE + */ + if("weave_binding") + weave_check(50, /obj/item/clothing/suit/weaversilk_bindings) + return TRUE + if("weave_floor") + weave_check(25, /obj/effect/weaversilk/floor) + return TRUE + if("weave_wall") + weave_check(100, /obj/effect/weaversilk/wall) + return TRUE + if("weave_nest") + weave_check(100, /obj/structure/bed/double/weaversilk_nest) + return TRUE + if("weave_trap") + weave_check(250, /obj/effect/weaversilk/trap) + return TRUE +/* + * Checks to see if we can create the object +*/ +/datum/component/weaver/proc/weave_check(cost, weaved_object) + if(cost > silk_reserve) to_chat(owner, span_warning("You don't have enough silk to weave that!")) return @@ -168,8 +156,12 @@ to_chat(owner, span_warning("You can't weave here!")) return - if(do_after(owner, desired_result.time, target = owner)) - if(desired_result.cost > silk_reserve) + if(locate(weaved_object) in owner.loc) + to_chat(owner, span_warning("You can't create another one in the same tile here!")) + return + + if(do_after(owner, ((cost/25) SECONDS), target = owner)) + if(cost > silk_reserve) to_chat(owner, span_warning("You don't have enough silk to weave that!")) return @@ -177,17 +169,11 @@ to_chat(owner, span_warning("You can't weave here!")) return - silk_reserve = max(silk_reserve - desired_result.cost, 0) + if(locate(weaved_object) in owner.loc) + to_chat(owner, span_warning("You can't create another one in the same tile!")) + return - var/atom/O = new desired_result.result_type(owner.loc) - O.color = silk_color - -/mob/living/proc/set_silk_color() - set name = "Set Silk Color" - set category = "Abilities.Weaver" - SEND_SIGNAL(src, COMSIG_SET_SILK_COLOR) - -/datum/component/weaver/proc/set_silk_color() - var/new_silk_color = tgui_color_picker(owner, "Pick a color for your woven products:","Silk Color", silk_color) - if(new_silk_color) - silk_color = new_silk_color + silk_reserve = max(silk_reserve - cost, 0) + var/atom/object = new weaved_object(owner.loc) + object.color = silk_color + return diff --git a/code/modules/mob/living/carbon/human/species/station/traits/positive.dm b/code/modules/mob/living/carbon/human/species/station/traits/positive.dm index 3c5808d29a..48565ed7c9 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits/positive.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits/positive.dm @@ -262,6 +262,7 @@ has_preferences = list("silk_production" = list(TRAIT_PREF_TYPE_BOOLEAN, "Silk production on spawn", TRAIT_NO_VAREDIT_TARGET), \ "silk_color" = list(TRAIT_PREF_TYPE_COLOR, "Silk color", TRAIT_NO_VAREDIT_TARGET)) added_component_path = /datum/component/weaver + excludes = list(/datum/trait/positive/cocoon_tf) /datum/trait/positive/weaver/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/list/trait_prefs) ..() @@ -304,6 +305,7 @@ cost = 1 // allowed_species = list(SPECIES_HANNER, SPECIES_CUSTOM) //So it only shows up for custom species and hanner CHOMPEDIT: It's a roleplay trait. Will things explode if more folks have it? custom_only = FALSE + excludes = list(/datum/trait/positive/weaver) /datum/trait/positive/cocoon_tf/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() diff --git a/tgui/packages/tgui/interfaces/WeaverConfig.tsx b/tgui/packages/tgui/interfaces/WeaverConfig.tsx new file mode 100644 index 0000000000..32c2e5378a --- /dev/null +++ b/tgui/packages/tgui/interfaces/WeaverConfig.tsx @@ -0,0 +1,152 @@ +import { useBackend } from 'tgui/backend'; +import { Window } from 'tgui/layouts'; +import { + Button, + ColorBox, + LabeledList, + NoticeBox, + Section, + Stack, +} from 'tgui-core/components'; +import type { BooleanLike } from 'tgui-core/react'; + +type Data = { + silk_reserve: number; + silk_max_reserve: number; + silk_color: string | null; + silk_production: number; + savefile_selected: BooleanLike; +}; + +export const WeaverConfig = (props) => { + const { act, data } = useBackend(); + + const { + silk_reserve, + silk_max_reserve, + silk_color, + silk_production, + savefile_selected + } = data; + const windowHeight = + (savefile_selected ? 0 : 90); + + return ( + + + + + Silk Reserves currently at {silk_reserve} out of {silk_max_reserve} + + {!savefile_selected && ( + + + WARNING: Your current selected savefile (in Character Setup) is + not the same as your currently loaded savefile. Please select it + to prevent savefile corruption. + + + )} + +
+ + + + + + + + + + + + + act('toggle_silk_production')} + /> + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ ); + };