From e12cf574f3015fff13736dd83902fdf383bc7530 Mon Sep 17 00:00:00 2001 From: Scrambledeggs <113869252+Scrambledeggs00@users.noreply.github.com> Date: Tue, 13 Aug 2024 20:19:05 -0400 Subject: [PATCH] Ice Cream Rework Part 2: I can't think of a funny name (#22490) * Started groundwork for new vat * forgot a space * Started on TGUI code * Continued work on TGUI code and ui_data * I do not like TGUI * Borrowed code from food cart * Getting there * More tweaking * Fixed amount problem * UI is dead * Fixed TGUI list stuff * Image fixed * Messed with UI layout * Finished base UI and gave thanks * Added comments and general code improvements * Fixed typos and changed actions in UI * ui_act for selecting and dispencing items * Improved dispensing and selecting code * Added alt click interaction and extra examines * Deselecting and attackby for adding to vat * Now stores items rather than type paths * Added carton interaction with vat * Selected item's select ui button now becomes green * lets you scoop cones with right click * Start with new cones * Finish cone crafting and started with tabs * Attempt #2 at getting tabs to work * Vat tab now works as intended * Messed with info tab layout * Finished work on tabs * Replaced original vat code and improved code * Removed ice cream from borg dispencers * Removed creamatorium ;[ * Removed duplicate item from black list * Finishing touches * Fixes for Lint tests * More fixes for Lints test * Shortens info tab text --- code/__HELPERS/unsorted.dm | 4 +- code/datums/info_tab.dm | 28 + code/game/objects/items/robot/robot_items.dm | 25 +- code/game/objects/structures/morgue.dm | 18 - .../kitchen_machinery/icecream_vat.dm | 651 ++++++++++-------- .../recipes/processor_recipes.dm | 10 +- .../recipes/tablecraft/recipes_frozen.dm | 6 +- .../recipes/tablecraft/recipes_misc.dm | 18 + icons/obj/food/food_ingredients.dmi | Bin 3539 -> 4299 bytes tgui/packages/tgui/interfaces/IceCreamVat.tsx | 297 ++++++++ yogstation.dme | 1 + 11 files changed, 739 insertions(+), 319 deletions(-) create mode 100644 code/datums/info_tab.dm create mode 100644 tgui/packages/tgui/interfaces/IceCreamVat.tsx diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index efcc0b2ade08..08b263becbda 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1116,7 +1116,9 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) /obj/item/reagent_containers/food/snacks/donkpocket/warm/gondola, //same thing /obj/item/reagent_containers/food/snacks/fish, // debug fish /obj/item/reagent_containers/food/snacks/powercrepe, //obscenely strong for a food item and shouldn't just be randomly spawned - /obj/item/reagent_containers/food/snacks/grown/banana/bombanana //They were made in a factory. A bomb factory. They're bombs. + /obj/item/reagent_containers/food/snacks/grown/banana/bombanana, //They were made in a factory. A bomb factory. They're bombs. + /obj/item/reagent_containers/food/snacks/ice_cream_cone, //base cone + /obj/item/reagent_containers/food/snacks/raw_cone //base raw cone ) blocked |= typesof(/obj/item/reagent_containers/food/snacks/customizable) diff --git a/code/datums/info_tab.dm b/code/datums/info_tab.dm new file mode 100644 index 000000000000..51af0d1f5e22 --- /dev/null +++ b/code/datums/info_tab.dm @@ -0,0 +1,28 @@ +//Meant to store information for dynamicly adding stuff to TGUI +//How to do: Make a child of info_tab. Every child of that child is a section of the TGUI info tab +//Then use subtypesof() on the original child to get all the information of its children +/datum/info_tab + var/section = null + var/section_text = null + +/datum/info_tab/icecream_vat + +/datum/info_tab/icecream_vat/vat_instructions + section = "Vat Instructions" + section_text = "The ice cream vat allows you to select and dispense both ice cream scoops and cones, along with scooping ice cream scoops onto cones. The selected scoop will be scooped into cones, while the selected cone is what is dispensed by alt-clicking the vat. To scoop a cone, select a scoop type and then right-click the vat with an empty cone. Cones can only have one scoop of ice cream." + +/datum/info_tab/icecream_vat/restocking + section = "Restocking" + section_text = "The ice cream vat can be restocked with new ice cream scoops and cones by left-clicking on the vat with said item. The vat can also be restocked by left-clicking on the vat with an ice cream carton with scoops. Doing so will transfer the scoops into the vat." + +/datum/info_tab/icecream_vat/storage_capacity + section = "Storage Capacity" + section_text = "The ice cream vat has a storage capacity of 120 scoops and cones combined." + +/datum/info_tab/icecream_vat/new_scoops + section = "Creating New Scoops" + section_text = "Scoops are made by mixing 10u of any ice cream reagent with 2u of ice. To make ice cream reagents, you will need to start with plain ice cream, which is made by mixing 5u of cream, 3u of sugar, 2u of salt, and then cooling the mixture to 272 Kelvin. To make the reagents of flavored ice cream, just mix 10u of plain ice cream with 2u of a valid flavor reagent such as vanilla." + +/datum/info_tab/icecream_vat/new_cones + section = "Creating New Cones" + section_text = "Cones are made in the crafting menu in the misc. food tab. They require a raw pastry base and 2u of their flavor reagent. Once you have made the raw cone, process it with a food processor to turn it into a finished cone." diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index e9fca53dd4aa..becfef8c0265 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -373,8 +373,7 @@ /obj/item/reagent_containers/food/snacks/cookie/bacon, /obj/item/reagent_containers/food/snacks/cookie/cloth, /obj/item/reagent_containers/food/snacks/lollipop, - /obj/item/reagent_containers/food/snacks/gumball, - /obj/item/reagent_containers/food/snacks/icecream // Becomes vanilla icecream down the line. + /obj/item/reagent_containers/food/snacks/gumball ) // A list of surfaces that we are allowed to place things on. var/list/allowed_surfaces = list(/obj/structure/table, /turf/open/floor) @@ -398,10 +397,7 @@ /obj/item/borg_snack_dispenser/attack_self(mob/user, modifiers) var/list/choices = list() for(var/atom/snack as anything in valid_snacks) - if(snack == /obj/item/reagent_containers/food/snacks/icecream) - choices["vanilla icecream"] = snack // Would be "ice cream cone" in the menu otherwise. - else - choices[initial(snack.name)] = snack + choices[initial(snack.name)] = snack if(!length(choices)) to_chat(user, span_warning("No valid snacks in database.")) if(length(choices) == 1) @@ -441,13 +437,6 @@ patron.put_in_hand(snack, empty_hand) user.do_item_attack_animation(patron, null, snack) playsound(loc, 'sound/machines/click.ogg', 10, TRUE) - - // Vanilla Icecream & Setting 'snack.name' Early - if(istype(snack, /obj/item/reagent_containers/food/snacks/icecream)) - var/obj/item/reagent_containers/food/snacks/icecream/icecream = snack - icecream.add_ice_cream("vanilla") - icecream.desc = "Eat the ice cream." - to_chat(patron, span_notice("[user] dispenses a [snack.name] into your empty hand and you reflexively grasp it.")) to_chat(user, span_notice("You dispense a [snack.name] into the hand of [patron].")) @@ -479,20 +468,12 @@ RegisterSignal(snack, COMSIG_MOVABLE_THROW_LANDED, PROC_REF(post_throw)) snack.throw_at(target, 7, 2, user, TRUE, FALSE) playsound(loc, 'sound/machines/click.ogg', 10, TRUE) - if(istype(snack, /obj/item/reagent_containers/food/snacks/icecream)) - var/obj/item/reagent_containers/food/snacks/icecream/icecream = snack - icecream.add_ice_cream("vanilla") - icecream.desc = "Eat the ice cream." user.visible_message(span_notice("[src] launches a [snack.name] at [target]!")) user.newtonian_move(get_dir(target, user)) // For no gravity. else if(user.Adjacent(target) && is_allowed(target, user)) COOLDOWN_START(src, last_snack_disp, cooldown) snack = new selected_snack(get_turf(target)) playsound(loc, 'sound/machines/click.ogg', 10, TRUE) - if(istype(snack, /obj/item/reagent_containers/food/snacks/icecream)) - var/obj/item/reagent_containers/food/snacks/icecream/icecream = snack - icecream.add_ice_cream("vanilla") - icecream.desc = "Eat the ice cream." user.visible_message(span_notice("[user] dispenses a [snack.name].")) if(snack && user.emagged && istype(snack, /obj/item/reagent_containers/food/snacks/cookie)) @@ -517,7 +498,7 @@ /obj/item/borg_snack_dispenser/medical name = "\improper Treat Borg Snack Dispenser" // Not calling this "Medical Borg Snack Dispenser" since Service & Clown Cyborgs use this too. desc = "A dispenser that dispenses treats such as lollipops and gumballs!" - valid_snacks = list(/obj/item/reagent_containers/food/snacks/lollipop, /obj/item/reagent_containers/food/snacks/gumball, /obj/item/reagent_containers/food/snacks/icecream) + valid_snacks = list(/obj/item/reagent_containers/food/snacks/lollipop, /obj/item/reagent_containers/food/snacks/gumball) #define PKBORG_DAMPEN_CYCLE_DELAY 20 diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 728d8aa6bb44..3da82520182b 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -330,9 +330,6 @@ GLOBAL_LIST_EMPTY(crematoriums) RemoveElement(/datum/element/update_icon_blocker) connected = new /obj/structure/tray/cremator(src) connected.connected = src - if(mapload && prob(1)) - new /obj/structure/bodycontainer/crematorium/creamatorium(get_turf(src)) - qdel(src) /obj/structure/bodycontainer/crematorium/update_icon_state() . = ..() @@ -432,21 +429,6 @@ GLOBAL_LIST_EMPTY(crematoriums) update_appearance(UPDATE_ICON) playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) //you horrible people -/obj/structure/bodycontainer/crematorium/creamatorium - name = "crematorium" - desc = "A human incinerator. Works well during ice cream socials." - -/obj/structure/bodycontainer/crematorium/creamatorium/finish_cremate(mob/user) - var/list/icecreams = new() - for(var/i_scream in get_all_contents(/mob/living)) - var/obj/item/reagent_containers/food/snacks/icecream/IC = new() - IC.set_cone_type("waffle") - IC.add_mob_flavor(i_scream) - icecreams += IC - . = ..() - for(var/obj/IC in icecreams) - IC.forceMove(src) - /* * Generic Tray * Parent class for morguetray and crematoriumtray diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm index 4e629b6b2971..ee0a17af052d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm @@ -1,16 +1,3 @@ -#define ICECREAM_VANILLA 1 -#define ICECREAM_CHOCOLATE 2 -#define ICECREAM_STRAWBERRY 3 -#define ICECREAM_BLUE 4 -#define ICECREAM_LEMON 5 -#define ICECREAM_CARAMEL 6 -#define ICECREAM_BANANA 7 -#define ICECREAM_ORANGE 8 -#define ICECREAM_PEACH 9 -#define ICECREAM_CHERRY_CHOCOLATE 10 -#define CONE_WAFFLE 11 -#define CONE_CHOC 12 - /obj/machinery/icecream_vat name = "ice cream vat" desc = "Ding-aling ding dong. Get your Nanotrasen-approved ice cream!" @@ -21,290 +8,406 @@ use_power = NO_POWER_USE layer = BELOW_OBJ_LAYER max_integrity = 300 - var/list/product_types = list() - var/dispense_flavour = ICECREAM_VANILLA - var/flavour_name = "vanilla" - var/static/list/icecream_vat_reagents = list( - /datum/reagent/consumable/milk = 6, - /datum/reagent/consumable/flour = 6, - /datum/reagent/consumable/sugar = 6, - /datum/reagent/consumable/ice = 6, - /datum/reagent/consumable/coco = 6, - /datum/reagent/consumable/vanilla = 5, - /datum/reagent/consumable/berryjuice = 5, - /datum/reagent/consumable/ethanol/singulo = 5, - /datum/reagent/consumable/lemonjuice = 5, - /datum/reagent/consumable/caramel = 5, - /datum/reagent/consumable/banana = 5, - /datum/reagent/consumable/orangejuice = 5, - /datum/reagent/consumable/cream = 5, - /datum/reagent/consumable/peachjuice = 5, - /datum/reagent/consumable/cherryjelly = 5) - -/obj/machinery/icecream_vat/proc/get_ingredient_list(type) - switch(type) - if(ICECREAM_CHOCOLATE) - return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/coco) - if(ICECREAM_STRAWBERRY) - return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/berryjuice) - if(ICECREAM_BLUE) - return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/ethanol/singulo) - if(ICECREAM_LEMON) - return list(/datum/reagent/consumable/ice, /datum/reagent/consumable/lemonjuice) - if(ICECREAM_CARAMEL) - return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/caramel) - if(ICECREAM_BANANA) - return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/banana) - if(ICECREAM_ORANGE) - return list(/datum/reagent/consumable/cream, /datum/reagent/consumable/ice, /datum/reagent/consumable/orangejuice) - if(ICECREAM_PEACH) - return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/peachjuice) - if(ICECREAM_CHERRY_CHOCOLATE) - return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/coco, /datum/reagent/consumable/cherryjelly) - if(CONE_WAFFLE) - return list(/datum/reagent/consumable/flour, /datum/reagent/consumable/sugar) - if(CONE_CHOC) - return list(/datum/reagent/consumable/flour, /datum/reagent/consumable/sugar, /datum/reagent/consumable/coco) - else //ICECREAM_VANILLA - return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/vanilla) - - -/obj/machinery/icecream_vat/proc/get_flavour_name(flavour_type) - switch(flavour_type) - if(ICECREAM_CHOCOLATE) - return "chocolate" - if(ICECREAM_STRAWBERRY) - return "strawberry" - if(ICECREAM_BLUE) - return "blue" - if(ICECREAM_LEMON) - return "lemon sorbet" - if(ICECREAM_CARAMEL) - return "caramel" - if(ICECREAM_BANANA) - return "banana" - if(ICECREAM_ORANGE) - return "orangesicle" - if(ICECREAM_PEACH) - return "peach" - if(ICECREAM_CHERRY_CHOCOLATE) - return "cherry chocolate" - if(CONE_WAFFLE) - return "waffle" - if(CONE_CHOC) - return "chocolate" - else //ICECREAM_VANILLA - return "vanilla" + //Ice cream to be dispensed into cone on attackby + var/selected_scoop = null + //Cone to be dispensed with alt click + var/selected_cone = null + //Max amount of items that can be in vat's storage + var/storage_capacity = 120 + //If it starts empty or not + var/start_empty = FALSE + //Sound made when an item is dispensed + var/dispense_sound = 'sound/machines/click.ogg' + //Sound made when selecting/deselecting an item + var/select_sound = 'sound/machines/doorclick.ogg' + //Items to be added upon creation to the vat and what is shown in the UI + var/list/ui_list = list( + /obj/item/reagent_containers/food/snacks/ice_cream_scoop, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/vanilla, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/chocolate, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/strawberry, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/blue, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/lemon_sorbet, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/caramel, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/banana, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/orange_creamsicle, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/peach, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/cherry_chocolate, + /obj/item/reagent_containers/food/snacks/ice_cream_scoop/meat, + /obj/item/reagent_containers/food/snacks/ice_cream_cone/cake, + /obj/item/reagent_containers/food/snacks/ice_cream_cone/chocolate) + //Please don't add anything other than scoops or cones to the list or it could/maybe/possibly/definitely break it + +/obj/machinery/icecream_vat/ui_interact(mob/user, datum/tgui/ui) //Thanks bug eating lizard for helping me with the UI + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "IceCreamVat", name) + ui.open() + ui.set_autoupdate(TRUE) + +/obj/machinery/icecream_vat/ui_data(mob/user) + //Define variables from UI + var/list/data = list() + data["cones"] = list() + data["ice_cream"] = list() + data["tabs"] = list() + + //Loop through starting list for data to send to main tab + for(var/item_detail in ui_list) + + //Create needed list and variable for geting data for UI + var/list/details = list() + var/obj/item/reagent_containers/food/snacks/item = new item_detail + + //Get information for UI + details["item_name"] = item.name + details["item_quantity"] = find_amount(item) + details["item_type_path"] = item.type + + //Get an image for the UI + var/icon/item_pic = getFlatIcon(item) + var/md5 = md5(fcopy_rsc(item_pic)) + if(!SSassets.cache["photo_[md5]_[item.name]_icon.png"]) + SSassets.transport.register_asset("photo_[md5]_[item.name]_icon.png", item_pic) + SSassets.transport.send_assets(user, list("photo_[md5]_[item.name]_icon.png" = item_pic)) + details["item_image"] = SSassets.transport.get_asset_url("photo_[md5]_[item.name]_icon.png") + + //Sort into different data lists depending on what the item is + if(istype(item, /obj/item/reagent_containers/food/snacks/ice_cream_scoop)) + details["selected_item"] = selected_scoop + data["ice_cream"] += list(details) + else + details["selected_item"] = selected_cone + data["cones"] += list(details) + //Loop through children of /datum/info_tab/icecream_vat for data to send to info tab + for(var/info_detail in subtypesof(/datum/info_tab/icecream_vat)) + + //Create needed list and variable for geting data for UI + var/list/details = list() + var/datum/info_tab/icecream_vat/item = new info_detail + + //Get info from children + details["section_title"] = item.section + details["section_text"] = item.section_text + + //Add info to data + data["info_tab"] += list(details) + + //Send stored information to UI + return data + +/obj/machinery/icecream_vat/ui_act(action, list/params) + . = ..() + if(.) + + return + + switch(action) + if("select") + var/itemPath = text2path(params["itemPath"]) + select_item(itemPath) + if("dispense") + var/itemPath = text2path(params["itemPath"]) + dispense_item(itemPath) /obj/machinery/icecream_vat/Initialize(mapload) . = ..() - while(product_types.len < 12) - product_types.Add(5) - create_reagents(100, NO_REACT | OPENCONTAINER) - for(var/reagent in icecream_vat_reagents) - reagents.add_reagent(reagent, icecream_vat_reagents[reagent]) + + if(!start_empty) + + //Loop through and add items from ui_list into content + for(var/item in ui_list) + + var/loop_cycles = 5 + var/obj/item/reagent_containers/food/snacks/check_item = new item + + //5 of every scoop; 10 of every cone + if(istype(check_item, /obj/item/reagent_containers/food/snacks/ice_cream_cone)) + loop_cycles = 10 -/obj/machinery/icecream_vat/ui_interact(mob/user) + //Add amount of items to the list depending on type + for(var/i in 1 to loop_cycles) + new item(src) + +/obj/machinery/icecream_vat/examine(mob/user) . = ..() - var/dat - dat += "ICE CREAM
" - dat += "Dispensing: [flavour_name] icecream

" - dat += "Vanilla ice cream: Select Make x5 [product_types[ICECREAM_VANILLA]] scoops left. (Ingredients: milk, ice, vanilla powder)
" - dat += "Strawberry ice cream: Select Make x5 [product_types[ICECREAM_STRAWBERRY]] dollops left. (Ingredients: milk, ice, berry juice)
" - dat += "Chocolate ice cream: Select Make x5 [product_types[ICECREAM_CHOCOLATE]] dollops left. (Ingredients: milk, ice, coco powder)
" - dat += "Blue ice cream: Select Make x5 [product_types[ICECREAM_BLUE]] dollops left. (Ingredients: milk, ice, singulo)
" - dat += "Lemon sorbet ice cream: Select Make x5 [product_types[ICECREAM_LEMON]] dollops left. (Ingredients: ice, lemon juice)
" - dat += "Caramel ice cream: Select Make x5 [product_types[ICECREAM_CARAMEL]] dollops left. (Ingredients: milk, ice, caramel)
" - dat += "Banana ice cream: Select Make x5 [product_types[ICECREAM_BANANA]] dollops left. (Ingredients: milk, ice, banana juice)
" - dat += "Orangesicle ice cream: Select Make x5 [product_types[ICECREAM_ORANGE]] dollops left. (Ingredients: cream, ice, orange juice)
" - dat += "Peach ice cream: Select Make x5 [product_types[ICECREAM_PEACH]] dollops left. (Ingredients: milk, ice, peach juice)
" - dat += "Cherry chocolate ice cream: Select Make x5 [product_types[ICECREAM_CHERRY_CHOCOLATE]] dollops left. (Ingredients: milk, ice, coco powder, cherry jelly)
" - dat += "
CONES
" - dat += "Waffle cones: Dispense Make x5 [product_types[CONE_WAFFLE]] cones left. (Ingredients: flour, sugar)
" - dat += "Chocolate cones: Dispense Make x5 [product_types[CONE_CHOC]] cones left. (Ingredients: flour, sugar, coco powder)
" - dat += "
" - dat += "VAT CONTENT
" - for(var/datum/reagent/R in reagents.reagent_list) - dat += "[R.name]: [R.volume]" - dat += "Purge
" - dat += "Refresh Close" - - var/datum/browser/popup = new(user, "icecreamvat","Icecream Vat", 700, 500, src) - popup.set_content(dat) - popup.open() - -/obj/machinery/icecream_vat/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/reagent_containers/food/snacks/icecream)) - var/obj/item/reagent_containers/food/snacks/icecream/I = O - if(!I.ice_creamed) - if(product_types[dispense_flavour] > 0) - visible_message("[icon2html(src, viewers(src))] [span_info("[user] scoops delicious [flavour_name] ice cream into [I].")]") - product_types[dispense_flavour] -= 1 - I.add_ice_cream(flavour_name) - if(I.reagents.total_volume < 10) - I.reagents.add_reagent(/datum/reagent/consumable/sugar, 10 - I.reagents.total_volume) - else - to_chat(user, span_warning("There is not enough ice cream left!")) - else - to_chat(user, span_notice("[O] already has ice cream in it.")) - return 1 - else if(O.is_drainable()) - return + + //Selected cones + if(selected_cone == null) + . += span_notice("You can Alt Click to dispense a cone once one is selected.") else - return ..() - -/obj/machinery/icecream_vat/proc/make(mob/user, make_type, amount) - for(var/R in get_ingredient_list(make_type)) - if(reagents.has_reagent(R, amount)) - continue - amount = 0 - break - if(amount) - for(var/R in get_ingredient_list(make_type)) - reagents.remove_reagent(R, amount) - product_types[make_type] += amount - var/flavour = get_flavour_name(make_type) - if(make_type > 4) - src.visible_message(span_info("[user] cooks up some [flavour] cones.")) + var/obj/item/reagent_containers/food/snacks/examine_cone = new selected_cone + . += span_notice("Alt Click to dispense [examine_cone.name].") + + //Selected scoops + if(selected_scoop == null) + . += span_notice("No ice cream scoop currently selected.") + else + var/obj/item/reagent_containers/food/snacks/examine_scoop = new selected_scoop + . += span_notice("[examine_scoop.name] is currently selected.") + + //Scooping cone instruction + . += span_notice("Right Click to add a scoop to a cone.") + +//For dispensing selected cone +/obj/machinery/icecream_vat/AltClick(mob/living/carbon/user) + if(selected_cone != null) + dispense_item(selected_cone) + else + user.balloon_alert(user, "None selected!") + + +/obj/machinery/icecream_vat/attackby_secondary(obj/item/A, mob/user, params) + //For scooping cones + scoop_cone(A) + + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +//For adding items to storage +/obj/machinery/icecream_vat/attackby(obj/item/A, mob/user, params) + + //For adding individual items + if(istype(A, /obj/item/reagent_containers/food/snacks/ice_cream_cone) || istype(A, /obj/item/reagent_containers/food/snacks/ice_cream_scoop)) + storage_single(A) + + //Adding carton contents to storage + else if(istype(A, /obj/item/storage/box/ice_cream_carton)) + storage_container(A) + + ..() + +/obj/machinery/icecream_vat/proc/find_amount(obj/item/counting_item) + var/amount = 0 + + //Loop through contents, counting every instance of the given target + for(var/obj/item/list_item in contents) + if(list_item.type == counting_item.type) + amount += 1 + + return amount + +/obj/machinery/icecream_vat/proc/dispense_item(received_item, mob/user = usr) + + //Make a variable for checking the type of the selected item + var/obj/item/reagent_containers/food/snacks/ui_item = new received_item + + //If the vat has some of the desired item, dispense it + if(find_amount(ui_item) > 0) + //Select the last(most recent) of desired item + var/obj/item/reagent_containers/food/snacks/dispensed_item = LAZYACCESS(contents, last_index(ui_item)) + //Drop it on the floor and then move it into the user's hands + dispensed_item.forceMove(loc) + user.put_in_hands(dispensed_item) + user.visible_message(span_notice("[user] dispenses [ui_item.name] from [src]."), span_notice("You dispense [ui_item.name] from [src].")) + playsound(src, dispense_sound, 25, TRUE, extrarange = -3) + else + //For Alt click and because UI buttons are slow to disable themselves + user.balloon_alert(user, "All out!") + +/obj/machinery/icecream_vat/proc/select_item(received_item, mob/user = usr) + + //Make a variable for checking the type of the selected item + var/obj/item/reagent_containers/food/snacks/ui_item = new received_item + + //Deselecting + if(istype(ui_item, /obj/item/reagent_containers/food/snacks/ice_cream_cone)) + if(selected_cone == ui_item.type) + user.visible_message(span_notice("[user] deselects [ui_item.name] from [src]."), span_notice("You deselect [ui_item.name] from [src].")) + selected_cone = null + playsound(src, select_sound, 25, TRUE, extrarange = -3) + + return + else if(selected_scoop == ui_item.type) + user.visible_message(span_notice("[user] deselects [ui_item.name] from [src]."), span_notice("You deselect [ui_item.name] from [src].")) + selected_scoop = null + playsound(src, select_sound, 25, TRUE, extrarange = -3) + + return + + //Selecting + if(find_amount(ui_item.type) > 0) + //Set item to selected based on its type + if(istype(ui_item, /obj/item/reagent_containers/food/snacks/ice_cream_cone)) + selected_cone = ui_item.type else - src.visible_message(span_info("[user] whips up some [flavour] icecream.")) + selected_scoop = ui_item.type + playsound(src, select_sound, 25, TRUE, extrarange = -3) + user.visible_message(span_notice("[user] sets [src] to dispense [ui_item.name]s."), span_notice("You set [src] to dispense [ui_item.name]s.")) + //Prevent them from selecting items that the vat does not have + else + user.balloon_alert(user, "All out!") + +/obj/machinery/icecream_vat/proc/last_index(obj/item/search_item) + + var/obj/item/reagent_containers/food/snacks/item_index = null + + //Search for the same item path in storage + for(var/i in 1 to LAZYLEN(contents)) + //Loop through entire list to get last/most recent item + if(contents[i].type == search_item.type) + item_index = i + + return item_index + +/obj/machinery/icecream_vat/proc/storage_single(obj/item/target_item, mob/user = usr) + //Check if there is room + if(contents.len < storage_capacity) + //If a cone, check if it has already been scooped. If it has, do not store it + if(istype(target_item, /obj/item/reagent_containers/food/snacks/ice_cream_cone)) + var/obj/item/reagent_containers/food/snacks/ice_cream_cone/cone = target_item + if(cone.scooped == TRUE) + user.balloon_alert(user, "Cannot store scooped cones!") + + return + //Move item to content + target_item.forceMove(src) + user.visible_message(span_notice("[user] inserts [target_item] into [src]."), span_notice("You insert [target_item] into [src].")) + playsound(src, 'sound/effects/rustle2.ogg', 50, TRUE, extrarange = -3) + + return else - to_chat(user, span_warning("You don't have the ingredients to make this!")) + //Warn about full capacity + user.balloon_alert(user, "No space!") + +/obj/machinery/icecream_vat/proc/storage_container(obj/item/target_container, mob/user = usr) + var/end_message = "[user] empties the [target_container] into [src]." + var/end_self_message = "You empty the [target_container] into [src]." + //Check to see if it is empty + if(target_container.contents.len > 0 && contents.len < storage_capacity) + //Hide carton's storage UI to prevent ghost scoop bug + SEND_SIGNAL(target_container, COMSIG_TRY_STORAGE_HIDE_FROM, user) + //Loop through all contents + for(var/obj/item/reagent_containers/food/snacks/ice_cream_scoop/carton_item in target_container) + //Transfer items one at a time + carton_item.forceMove(src) + if(contents.len >= storage_capacity) + //Unique message depending on carton and vat contents + if(target_container.contents.len == 0) + end_message = "[user] empties the [target_container] into [src], filling it to its capacity." + end_self_message = "You empty the [target_container] into [src], filling it to its capacity." + else + end_message = "[user] fills [src] to its capacity, with some ice cream still in the [target_container]." + end_self_message = "You fill [src] to its capacity, with some ice cream still in the [target_container]." + break + + user.visible_message(span_notice(end_message), span_notice(end_self_message)) + playsound(src, 'sound/effects/rustle2.ogg', 50, TRUE, extrarange = -3) -/obj/machinery/icecream_vat/Topic(href, href_list) - if(..()) return - if(href_list["select"]) - dispense_flavour = text2num(href_list["select"]) - flavour_name = get_flavour_name(dispense_flavour) - src.visible_message(span_notice("[usr] sets [src] to dispense [flavour_name] flavoured ice cream.")) - - if(href_list["cone"]) - var/dispense_cone = text2num(href_list["cone"]) - var/cone_name = get_flavour_name(dispense_cone) - if(product_types[dispense_cone] >= 1) - product_types[dispense_cone] -= 1 - var/obj/item/reagent_containers/food/snacks/icecream/I = new(src.loc) - I.set_cone_type(cone_name) - src.visible_message(span_info("[usr] dispenses a crunchy [cone_name] cone from [src].")) + else + if(target_container.contents.len == 0) + user.balloon_alert(user, "Carton empty!") else - to_chat(usr, span_warning("There are no [cone_name] cones left!")) + user.balloon_alert(user, "Vat full!") + return - if(href_list["make"]) - var/amount = (text2num(href_list["amount"])) - var/C = text2num(href_list["make"]) - make(usr, C, amount) +/obj/machinery/icecream_vat/proc/scoop_cone(obj/item/target_cone, mob/user = usr) + //Check if item is a cone + if(istype(target_cone, /obj/item/reagent_containers/food/snacks/ice_cream_cone)) + var/obj/item/reagent_containers/food/snacks/ice_cream_cone/cone = target_cone + //Check if cone is scooped + if(cone.scooped == FALSE) + //Check if a scoop has been selected + if(selected_scoop != null) + //Check if there are any of selected scoop in contents + if(find_amount(selected_scoop) > 0) + //Select last of selected scoop in contents + var/obj/item/reagent_containers/food/snacks/cone_scoop = LAZYACCESS(contents, last_index(selected_scoop)) + //Remove scoop from contents and add relevant variables to cone + cone_scoop.forceMove(loc) + cone.reagents.reagent_list += cone_scoop.reagents.reagent_list + cone.foodtype = cone_scoop.foodtype + //Change description of cone + cone.desc = "[cone.base_desc] with a [cone_scoop.name]." + //Add overlay of scoop to cone + cone.add_overlay(cone_scoop.icon_state) + //Alert that the cone has been scooped + user.visible_message(span_notice("[user] scoops a [cone_scoop.name] into the [cone.name]"), span_notice("You scoop a [cone_scoop.name] into the [cone.name]")) + //Set scooped to TRUE + cone.scooped = TRUE + //Delete scoop + qdel(cone_scoop) - if(href_list["disposeI"]) - reagents.del_reagent(href_list["disposeI"]) + playsound(src, 'sound/effects/rustle2.ogg', 50, TRUE, extrarange = -3) - updateDialog() + //Warn user that there are no selected scoops left + else + user.balloon_alert(user, "No selected scoops in storage!") - if(href_list["refresh"]) - updateDialog() + //Warn user about no selected scoop + else + user.balloon_alert(user, "No scoop selected!") - if(href_list["close"]) - usr.unset_machine() - usr << browse(null,"window=icecreamvat") - return + //Warn user about cone already being scooped + else + user.balloon_alert(user, "Already scooped!") + + //Warn user about invalid item + else + user.balloon_alert(user, "Invalid item!") + +/////////////////// +//ICE CREAM CONES// +/////////////////// -/obj/item/reagent_containers/food/snacks/icecream - name = "ice cream cone" - desc = "Delicious waffle cone, but no ice cream." +/obj/item/reagent_containers/food/snacks/ice_cream_cone + name = "ice cream cone base" + desc = "Please report this, as this should not be seen." icon = 'icons/obj/kitchen.dmi' - icon_state = "icecream_cone_waffle" //default for admin-spawned cones, href_list["cone"] should overwrite this all the time - var/ice_creamed = 0 - var/cone_type bitesize = 3 foodtype = GRAIN - tastes = list("cold" = 6, "creamy" = 4) + //Used for changing the description after being scooped + var/base_desc = null + //If the cone has a scoop or not + var/scooped = FALSE + //For adding chems to specific cones + var/extra_reagent = null + //Amount of extra_reagent to add to cone + var/extra_reagent_amount = 1 -/obj/item/reagent_containers/food/snacks/icecream/Initialize(mapload) +/obj/item/reagent_containers/food/snacks/ice_cream_cone/Initialize(mapload) . = ..() create_reagents(20) reagents.add_reagent(/datum/reagent/consumable/nutriment, 4) + if(extra_reagent != null) + reagents.add_reagent(extra_reagent, extra_reagent_amount) + +/obj/item/reagent_containers/food/snacks/ice_cream_cone/cake + name = "cake ice cream cone" + desc = "A delicious cake cone, but with no ice cream." + icon_state = "icecream_cone_waffle" + tastes = list("bland" = 6) + base_desc = "A delicious cake cone" + extra_reagent = /datum/reagent/consumable/sugar + +/obj/item/reagent_containers/food/snacks/ice_cream_cone/chocolate + name = "chocolate ice cream cone" + desc = "A delicious chocolate cone, but with no ice cream." + icon_state = "icecream_cone_chocolate" + tastes = list("bland" = 4, "chocolate" = 6) + base_desc = "A delicious chocolate cone" + extra_reagent = /datum/reagent/consumable/coco + +/////////////////////////// +//ICE CREAM CONE CRAFTING// +/////////////////////////// + +/obj/item/reagent_containers/food/snacks/raw_cone + name = "base raw cone" + desc = "Please report this, as this should not be seen." + icon = 'icons/obj/food/food_ingredients.dmi' + bonus_reagents = list(/datum/reagent/consumable/nutriment = 2) + list_reagents = list(/datum/reagent/consumable/nutriment = 4) + tastes = list("bland" = 6) + foodtype = GRAIN | DAIRY + +/obj/item/reagent_containers/food/snacks/raw_cone/cake + name = "raw cake cone" + desc = "A raw cake cone that needs to be processed." + icon_state = "raw_cake_cone" -/obj/item/reagent_containers/food/snacks/icecream/proc/set_cone_type(cone_name) - cone_type = cone_name - icon_state = "icecream_cone_[cone_name]" - switch (cone_type) - if ("waffle") - reagents.add_reagent(/datum/reagent/consumable/nutriment, 1) - if ("chocolate") - reagents.add_reagent(/datum/reagent/consumable/coco, 1) // chocolate ain't as nutritious kids - - desc = "Delicious [cone_name] cone, but no ice cream." - - -/obj/item/reagent_containers/food/snacks/icecream/proc/add_ice_cream(flavour_name) - name = "[flavour_name] icecream" - src.add_overlay("icecream_[flavour_name]") - switch (flavour_name) // adding the actual reagents advertised in the ingredient list - if ("vanilla") - desc = "A delicious [cone_type] cone filled with vanilla ice cream. All the other ice creams take content from it." - foodtype = DAIRY | SUGAR - if ("chocolate") - desc = "A delicious [cone_type] cone filled with chocolate ice cream. Surprisingly, made with real cocoa." - foodtype = DAIRY | CHOCOLATE | SUGAR - reagents.add_reagent(/datum/reagent/consumable/coco, 2) - if ("strawberry") - desc = "A delicious [cone_type] cone filled with strawberry ice cream. Definitely not made with real strawberries." - foodtype = DAIRY | FRUIT | SUGAR - reagents.add_reagent(/datum/reagent/consumable/berryjuice, 2) - if ("blue") - desc = "A delicious [cone_type] cone filled with blue ice cream. Made with real... blue?" - foodtype = DAIRY | SUGAR | ALCOHOL - reagents.add_reagent(/datum/reagent/consumable/ethanol/singulo, 2) - if ("lemon sorbet") - desc = "A delicious [cone_type] cone filled with lemon sorbet. Like frozen lemonade in a cone." - foodtype = SUGAR | FRUIT - reagents.add_reagent(/datum/reagent/consumable/lemonjuice, 2) - if ("caramel") - desc = "A delicious [cone_type] cone filled with caramel ice cream. It is deliciously sweet." - foodtype = DAIRY | SUGAR | CHOCOLATE - reagents.add_reagent(/datum/reagent/consumable/caramel, 2) - if ("banana") - desc = "A delicious [cone_type] cone filled with banana ice cream. Honk!" - foodtype = DAIRY | FRUIT | SUGAR - reagents.add_reagent(/datum/reagent/consumable/banana, 2) - if ("orangesicle") - desc = "A delicious [cone_type] cone filled with orange creamsicle. Not quite the same off the stick..." - foodtype = DAIRY | FRUIT | SUGAR - reagents.add_reagent(/datum/reagent/consumable/orangejuice, 2) - if ("peach") - desc = "A delicious [cone_type] cone filled with limited edition peach flavour. Enjoy it while it lasts!" - foodtype = DAIRY | FRUIT | SUGAR - reagents.add_reagent(/datum/reagent/consumable/peachjuice, 2) - if ("cherry chocolate") - desc = "A delicious [cone_type] cone filled with cherry chocolate ice cream. It is wonderfully tangy and sweet." - foodtype = DAIRY | FRUIT | SUGAR | CHOCOLATE - reagents.add_reagent(/datum/reagent/consumable/cherryjelly, 2) - if ("mob") - desc = "A suspicious [cone_type] cone filled with bright red ice cream. That's probably not strawberry..." - foodtype = DAIRY | MICE | SUGAR - reagents.add_reagent(/datum/reagent/liquidgibs, 2) - ice_creamed = 1 - -/obj/item/reagent_containers/food/snacks/icecream/proc/add_mob_flavor(mob/M) - add_ice_cream("mob") - name = "[M.name] icecream" - -/obj/machinery/icecream_vat/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - new /obj/item/stack/sheet/metal(loc, 4) - qdel(src) - - -#undef ICECREAM_VANILLA -#undef ICECREAM_CHOCOLATE -#undef ICECREAM_STRAWBERRY -#undef ICECREAM_BLUE -#undef ICECREAM_LEMON -#undef ICECREAM_CARAMEL -#undef ICECREAM_BANANA -#undef ICECREAM_ORANGE -#undef ICECREAM_PEACH -#undef ICECREAM_CHERRY_CHOCOLATE -#undef CONE_WAFFLE -#undef CONE_CHOC \ No newline at end of file +/obj/item/reagent_containers/food/snacks/raw_cone/chocolate + name = "raw chocolate cone" + desc = "A raw chocolate cone that needs to be processed." + icon_state = "raw_chocolate_cone" diff --git a/code/modules/food_and_drinks/recipes/processor_recipes.dm b/code/modules/food_and_drinks/recipes/processor_recipes.dm index 5616a4c7f4e4..2ea8a5ef03ea 100644 --- a/code/modules/food_and_drinks/recipes/processor_recipes.dm +++ b/code/modules/food_and_drinks/recipes/processor_recipes.dm @@ -77,6 +77,14 @@ input = /obj/item/reagent_containers/food/snacks/grown/parsnip output = /obj/item/reagent_containers/food/snacks/roastparsnip +/datum/food_processor_process/raw_cake_cone + input = /obj/item/reagent_containers/food/snacks/raw_cone/cake + output = /obj/item/reagent_containers/food/snacks/ice_cream_cone/cake + +/datum/food_processor_process/raw_chocolate_cone + input = /obj/item/reagent_containers/food/snacks/raw_cone/chocolate + output = /obj/item/reagent_containers/food/snacks/ice_cream_cone/chocolate + /datum/food_processor_process/mob/slime input = /mob/living/simple_animal/slime output = null @@ -116,4 +124,4 @@ /datum/food_processor_process/swissmix input = /obj/item/reagent_containers/food/snacks/cheesemix_heated/swiss - output = /obj/item/reagent_containers/food/snacks/store/cheesewheel/swiss \ No newline at end of file + output = /obj/item/reagent_containers/food/snacks/store/cheesewheel/swiss diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm index 2735d3abb182..ebc5a1b1be3e 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm @@ -15,7 +15,7 @@ /datum/crafting_recipe/food/spacefreezy name ="Space freezy" reqs = list( - /obj/item/reagent_containers/food/snacks/icecream = 1, + /obj/item/reagent_containers/food/snacks/ice_cream_cone/cake = 1, /datum/reagent/consumable/bluecherryjelly = 5, /datum/reagent/consumable/space_cola/spacemountainwind = 15, /obj/item/reagent_containers/food/snacks/ice_cream_scoop/vanilla = 1 @@ -26,7 +26,7 @@ /datum/crafting_recipe/food/sundae name ="Sundae" reqs = list( - /obj/item/reagent_containers/food/snacks/icecream = 1, + /obj/item/reagent_containers/food/snacks/ice_cream_cone/cake = 1, /obj/item/reagent_containers/food/snacks/grown/cherries = 1, /obj/item/reagent_containers/food/snacks/grown/banana = 1, /obj/item/reagent_containers/food/snacks/ice_cream_scoop/vanilla = 1 @@ -37,7 +37,7 @@ /datum/crafting_recipe/food/honkdae name ="Honkdae" reqs = list( - /obj/item/reagent_containers/food/snacks/icecream = 1, + /obj/item/reagent_containers/food/snacks/ice_cream_cone/cake = 1, /obj/item/clothing/mask/gas/clown_hat = 1, /obj/item/reagent_containers/food/snacks/grown/cherries = 1, /obj/item/reagent_containers/food/snacks/grown/banana = 2, diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm index be9a5a5d5b7f..b8b877cd1186 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm @@ -357,3 +357,21 @@ ) result = /obj/item/reagent_containers/food/snacks/pineapple_friedrice category = CAT_MISCFOOD + +/datum/crafting_recipe/food/raw_cake_cone + name = "Raw Cake Cone" + reqs = list( + /obj/item/reagent_containers/food/snacks/rawpastrybase = 1, + /datum/reagent/consumable/sugar = 2 + ) + result = /obj/item/reagent_containers/food/snacks/raw_cone/cake + category = CAT_MISCFOOD + +/datum/crafting_recipe/food/raw_chocolate_cone + name = "Raw Chocolate Cone" + reqs = list( + /obj/item/reagent_containers/food/snacks/rawpastrybase = 1, + /datum/reagent/consumable/coco = 2 + ) + result = /obj/item/reagent_containers/food/snacks/raw_cone/chocolate + category = CAT_MISCFOOD diff --git a/icons/obj/food/food_ingredients.dmi b/icons/obj/food/food_ingredients.dmi index b761943de00a550955b642e65d6879c3b1d2f753..8687b5f98095842085c81c8032d424632644092f 100644 GIT binary patch literal 4299 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 ZYX>8K { + // Get information from backend code + const { data } = useBackend(context); + // Make a variable for storing a number that represents the current selected tab + const [selectedMainTab, setMainTab] = useLocalState(context, 'selectedMainTab', 0); + + return( + // Create window for ui + + {/* Add constants to window and make it scrollable */} + + {/* Create tabs for the vat and information tabs */} + + setMainTab(0)}> + {/* Put 'Vat' in the tab to differentiate it from other tabs */} + Vat + + setMainTab(1)}> + {/* Put 'Information' in the tab to differentiate it from other tabs */} + Information + + + {/* If selectedMainTab is 0, show the UI elements in VatTab */} + {selectedMainTab === 0 && } + {/* If selectedMainTab is 1, show the UI elements in InfoTab */} + {selectedMainTab === 1 && } + + + ); +}; + +const ConeRow = (props, context) => { + // Get data from ui_data in backend code + const { act, data } = useBackend(context); + // Get cones information from data + const { cones = [] } = data; + + return ( + // Create Table for horizontal format + + {/* Use map to create dynamic rows based on the contents of cones, with flavor being the individual item and its stats */} + {cones.map(flavor => ( + // Start row for holding ui elements and given data + + + {/* Get image and then add it to the ui */} + + + + {/* Get name */} + {capitalize(flavor.item_name)} + + + {/* Get amount of item in storage */} + {flavor.item_quantity} in storage + + + {/* Make select button */} +
+ ); +}; + +const IceCreamRow = (props, context) => { + // Get data from ui_data in backend code + const { act, data } = useBackend(context); + // Get ice_cream information from data + const { ice_cream = [] } = data; + + return ( + // Create Table for horizontal format + + {/* Use map to create dynamic rows based on the contents of ice_cream, with flavor being the individual item and its stats */} + {ice_cream.map(flavor => ( + // Start row for holding ui elements and given data + + + {/* Get image and then add it to the ui */} + + + + {/* Get name */} + {capitalize(flavor.item_name)} + + + {/* Get amount of item in storage */} + {flavor.item_quantity} in storage + + {/* Make select button */} + +
+ ); +}; + +const InfoContentRow = (props, context) => { + // Get data from ui_data in backend code + const { data } = useBackend(context); + // Get info_tab information from data + const { info_tab = [] } = data; + // Make constant that starts with the section_text of the first element of info_tab and which will recieve new data from InfoTab + const[infoContent] = useLocalState(context, 'selectedInfoTab', info_tab[0].section_text); + + // Return a section with the tab's section_text + return ( +
+ {infoContent} +
+ ); +}; + +const VatTab = (props, context) => { + + // For organizing the vat tab's information + return ( + + +
+ +
+
+ +
+ +
+
+
+ ); +}; + +const InfoTab = (props, context) => { + // Get data from ui_data in backend code + const { data } = useBackend(context); + // Get info_tab information from data + const { info_tab = [] } = data; + // Make constant that starts with the section_text of the first element of info_tab and which can send new data to InfoContentRow + const [selectedInfoTab, setInfoTab] = useLocalState(context, 'selectedInfoTab', info_tab[0].section_text); + + // Return organized elements for the main UI + return ( + // Stack them for appealing layout + + + {/* Start tabs and make them vertical */} + + {/* Use map to allow for dynamic tabs */} + {info_tab.map(information => ( + // Create new tab based on current info_tab element + setInfoTab(information.section_text)}> + {/* Put the section_title in the tab to differentiate it from other tabs */} + {information.section_title} + + ))} + + + {/* Show the section_text stored in selectedInfotab */} + + + + + ); +}; diff --git a/yogstation.dme b/yogstation.dme index aff0034c225c..e7c6163c63d5 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -519,6 +519,7 @@ #include "code\datums\holocall.dm" #include "code\datums\http.dm" #include "code\datums\hud.dm" +#include "code\datums\info_tab.dm" #include "code\datums\lazy_template.dm" #include "code\datums\map_config.dm" #include "code\datums\martial.dm"