Adds TGUI functionality to Trait Tutorial

* Creates trait_tutorial_tgui.dm to act as backend, adds to vorestation.dme
* Creates TraitTutorial.tsx to act as frontend
* Modifies traits_tutorial.dm for TGUI compatibility
* Adds comment to var/tutorial definition on how to make it pretty in TGUI
* Modifies logic in trait_tutorial to catch empty trait lists.
* Edits bloodsucker obligate/freeform to add another <br>
This commit is contained in:
Runa Dacino
2023-05-23 00:29:45 +02:00
parent 222544a5cb
commit 30ee8288ce
7 changed files with 150 additions and 9 deletions
@@ -88,7 +88,7 @@
tutorial = "This trait forces you to only consume blood - you cannot have normal food anymore. Vore is, of course, an exception! <br> \
You can satisfy this by clicking bloodbags in your hand on harm intent, drinking from glasses, blood tomatoes \
or finding a (un)willing donor for your appropriate appendage! <br><br> \
Controls for taking blood from your victim can be changed at will by trying to drink from yourself.\
Controls for taking blood from your victim can be changed at will by trying to drink from yourself. <br>\
Intent-based control scheme: <br> \
HELP - Loud, No Bleeding <br> \
DISARM - Subtle, Causes bleeding <br> \
@@ -110,7 +110,7 @@
tutorial = "This trait allows you to consume blood on top of normal food! <br> \
You can do this by clicking bloodbags in your hand on harm intent, drinking from glasses, blood tomatoes \
or finding a (un)willing donor for your appropriate appendage! <br><br> \
Controls for taking blood from your victim can be changed at will by trying to drink from yourself.\
Controls for taking blood from your victim can be changed at will by trying to drink from yourself. <br>\
Intent-based control scheme: <br> \
HELP - Loud, No Bleeding <br> \
DISARM - Subtle, Causes bleeding <br> \
@@ -1,7 +1,7 @@
/datum/trait
var/name
var/desc = "Contact a developer if you see this trait."
var/tutorial = "This trait has no detailed tutorial yet. Suggest one at #Dev-Suggestions on the discord!"
var/tutorial = "This trait has no detailed tutorial yet. Suggest one at #Dev-Suggestions on the discord!" //Use <br> for newlines, NOT \n
var/cost = 0
var/sort = TRAIT_SORT_NORMAL // Sort order, 1 before 2 before 3 etc. Alphabetical is used for same-group traits.
@@ -7,6 +7,11 @@ then retrieve their relevant vars by assuming the character's species has the fu
The ability is intended to be developed both as a to_chat() and a tgui window.
The user is given the ability to choose which they would like whenever they press the ability to better suit whatever scenario they find themselves
thirsty for knowledge.
When adding new tutorials for trait subtypes, use <br> rather than \n newlines
TGUI backend path: code\modules\tgui\modules\trait_tutorial_tgui.dm
TGUI frontend path: tgui\packages\tgui\interfaces\TraitTutorial.tsx
*/
@@ -17,13 +22,19 @@ thirsty for knowledge.
set name = "Explain Custom Traits"
set desc = "Click this verb to obtain a detailed tutorial on your selected traits. "
set category = "Abilities"
var/datum/tgui_module/trait_tutorial_tgui/fancy_UI
if(!fancy_UI)
fancy_UI = new /datum/tgui_module/trait_tutorial_tgui/ //Preventing a bunch of instances being spawned all over the place. Hopefully
var/list/list_of_traits = species.traits
if(!list_of_traits)
if(!LAZYLEN(list_of_traits))
to_chat(usr, SPAN_NOTICE("You do not have any custom traits!"))
return
var/UI_choice = tgui_alert(src, "Would you like the tutorial text to be printed to chat?", "Choose preferred tutorial interface", list("To Chat", "Cancel"))
var/UI_choice = tgui_alert(src, "Would you like the tutorial text to be printed to chat?", "Choose preferred tutorial interface", list("TGUI","To Chat", "Cancel"))
if(UI_choice == "Cancel")
return
@@ -34,7 +45,6 @@ thirsty for knowledge.
var/trait_tutorial = list() //name:tutorial
for(var/trait in list_of_traits)
var/datum/trait/T = all_traits[trait]
to_world_log("##DEBUG [T.name] is of category [T.category]")
trait_names += T.name
trait_desc[T.name] = T.desc
trait_tutorial[T.name] = T.tutorial
@@ -54,5 +64,7 @@ thirsty for knowledge.
<b>Guide:</b> \n [trait_tutorial[to_chat_choice]]"))
// else if(UI_choice == "TGUI")
to_chat(usr, SPAN_NOTICE("TGUI functionality is not yet implemented, sorry!"))
else if(UI_choice == "TGUI")
fancy_UI.set_vars(trait_names, trait_category, trait_desc, trait_tutorial)
fancy_UI.tgui_interact(usr)
@@ -0,0 +1,48 @@
/*
Verb/Main definition path: code\modules\mob\living\carbon\human\species\station\traits_vr\traits_tutorial.dm
Frontend path: tgui\packages\tgui\interfaces\TraitTutorial.tsx
*/
/datum/tgui_module/trait_tutorial_tgui
name = "Explain Custom Traits"
tgui_id = "TraitTutorial"
var/trait_names = list()
var/trait_category = list() // name:category
var/trait_desc = list() // name:desc
var/trait_tutorial = list() //name:tutorial
var/trait_selected = ""
/datum/tgui_module/trait_tutorial_tgui/proc/set_vars(list/names, list/categories, list/descriptions, list/tutorials)
trait_names = names
trait_category = categories
trait_desc = descriptions
trait_tutorial = tutorials
/datum/tgui_module/trait_tutorial_tgui/tgui_interact(mob/living/carbon/human/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, tgui_id, name)
ui.open()
/datum/tgui_module/trait_tutorial_tgui/tgui_data(mob/user)
var/list/data = list()
data["names"] = trait_names //passes a list of strings
data["descriptions"] = trait_desc //passes an assoc list as obj
data["categories"] = trait_category //passes an assoc list as obj
data["tutorials"] = trait_tutorial //passes an assoc list as obj
data["selection"] = trait_selected //passes a string
return data
/datum/tgui_module/trait_tutorial_tgui/tgui_act(action, params)
. = ..()
if(.)
return
if(action == "select_trait")
var/selection = params["name"]
trait_selected = selection
. = TRUE
/datum/tgui_module/trait_tutorial_tgui/tgui_state(mob/user)
return GLOB.tgui_always_state
@@ -0,0 +1,80 @@
/* eslint-disable react/no-danger */
import { useBackend } from '../backend';
import { Flex, Tabs, Section, Box, Divider } from '../components';
import { Window } from '../layouts';
type data = {
namae: string;
names: string[];
descriptions: { key: string; val: string }[];
categories: { key: string; val: string }[];
tutorials: { key: string; val: string }[];
selection: string;
};
export const TraitTutorial = (props, context) => {
const { act, data } = useBackend<data>(context);
return (
<Window width={804} height={426} scrollable>
<Window.Content scrollable>
<Section title="Guide to Custom Traits" scrollable>
<TraitSelection />
</Section>
</Window.Content>
</Window>
);
};
export const TraitSelection = (props, context) => {
const { act, data } = useBackend<data>(context);
const { names, selection } = data;
return (
<Flex scrollable>
<Flex.Item shrink scrollable>
<Section title="Trait Selection" scrollable>
<Tabs vertical scrollable>
{names.map((name) => (
<Tabs.Tab key={name} selected={name === selection} onClick={() => act('select_trait', { name })}>
<Box inline>{name}</Box>
</Tabs.Tab>
))}
</Tabs>
</Section>
</Flex.Item>
<Flex.Item grow={2}>
<Divider vertical />
</Flex.Item>
<Flex.Item grow={8} scrollable>
{selection && (
<Section title={selection} scrollable>
<TraitDescription name={selection} />
</Section>
)}
</Flex.Item>
</Flex>
);
};
export const TraitDescription = (props, context) => {
const { act, data } = useBackend<data>(context);
const { name } = props;
const { descriptions, categories, tutorials } = data;
return (
<Section scrollable flexWrap>
<b>Name:</b> {name}
<br />
<b>Category:</b> {categories[name]}
<br />
<b>Description:</b> {descriptions[name]}
<br />
<b>Details & How to Use:</b>
<br />
<br />
<div dangerouslySetInnerHTML={{ __html: tutorials[name] as unknown as string }} />
</Section>
);
};
File diff suppressed because one or more lines are too long
+1
View File
@@ -3979,6 +3979,7 @@
#include "code\modules\tgui\modules\shutoff_monitor.dm"
#include "code\modules\tgui\modules\supermatter_monitor.dm"
#include "code\modules\tgui\modules\teleporter.dm"
#include "code\modules\tgui\modules\trait_tutorial_tgui.dm"
#include "code\modules\tgui\modules\admin\player_notes.dm"
#include "code\modules\tgui\modules\ntos-only\cardmod.dm"
#include "code\modules\tgui\modules\ntos-only\configurator.dm"