[MODULAR] Refactors glassblowing + gives it a new UI (#20495)

* Refactors glassblowing, adds a new tgui for it

* quality pass 1

* quality pass 2

* Final passes

* Final touches

* this was a bit too horizontal

* ewps

* just some last minute tidying of unneeded bits

* no touch hot glass

* Merge branch 'glass-fix' of https://github.com/vinylspiders/Skyrat-customization-expansion into glass-fix
This commit is contained in:
Bloop
2023-04-12 20:55:28 +01:00
committed by GitHub
parent 468fafbab8
commit f5efc752a2
3 changed files with 596 additions and 150 deletions
@@ -1,4 +1,9 @@
#define DEFAULT_TIMED (4 SECONDS)
#define STEP_BLOW "blow"
#define STEP_SPIN "spin"
#define STEP_PADDLE "paddle"
#define STEP_SHEAR "shear"
#define STEP_JACKS "jacks"
/obj/item/glassblowing
icon = 'modular_skyrat/modules/primitive_production/icons/prim_fun.dmi'
@@ -13,14 +18,16 @@
/datum/export/glassblowing
cost = CARGO_CRATE_VALUE * 5
unit_name = "glassblowing product"
export_types = list(/obj/item/glassblowing/glass_lens,
/obj/item/glassblowing/glass_globe,
/obj/item/reagent_containers/cup/bowl/blowing_glass,
/obj/item/reagent_containers/cup/beaker/large/blowing_glass,
/obj/item/plate/blowing_glass)
export_types = list(
/obj/item/glassblowing/glass_lens,
/obj/item/glassblowing/glass_globe,
/obj/item/reagent_containers/cup/bowl/blowing_glass,
/obj/item/reagent_containers/cup/beaker/large/blowing_glass,
/obj/item/plate/blowing_glass
)
/datum/export/glassblowing/sell_object(obj/O, datum/export_report/report, dry_run, apply_elastic = FALSE) //I really dont want them to feel gimped
. = ..()
return ..()
/obj/item/glassblowing/glass_lens
name = "glass lens"
@@ -55,87 +62,98 @@
name = "molten glass"
desc = "A glob of molten glass, ready to be shaped into art."
icon_state = "molten_glass"
//the cooldown if its still molten / requires heating up
///the cooldown if its still molten / requires heating up
COOLDOWN_DECLARE(remaining_heat)
///the list of required steps to produce the chosen_item: blowing, spinning, paddles, shears, jacks
var/list/required_actions = list(0,0,0,0,0)
///the list of current steps: blowing, spinning, paddles, shears, jacks
var/list/current_actions = list(0,0,0,0,0)
///the typepath of the item that will be produced when the required actions are met
var/chosen_item
///the list of steps remaining
var/list/steps_remaining
///the amount of time this glass will stay heated, updated each time it gets put in the forge based on the user's skill
var/total_time
///whether this glass's chosen item has completed all its steps. So we don't have to keep checking this a million times once it's done.
var/is_finished = FALSE
/obj/item/glassblowing/molten_glass/examine(mob/user)
. = ..()
if(COOLDOWN_FINISHED(src, remaining_heat))
. += span_warning("[src] has cooled down and will require reheating to modify!")
if(required_actions[1])
. += "You require [required_actions[1]] blowing actions!"
. += "You currently have [current_actions[1]] blowing actions!"
if(required_actions[2])
. += "You require [required_actions[2]] spinning actions!"
. += "You currently have [current_actions[2]] spinning actions!"
if(required_actions[3])
. += "You require [required_actions[3]] paddling actions!"
. += "You currently have [current_actions[3]] paddling actions!"
if(required_actions[4])
. += "You require [required_actions[4]] shearing actions!"
. += "You currently have [current_actions[4]] shearing actions!"
if(required_actions[5])
. += "You require [required_actions[5]] jacking actions!"
. += "You currently have [current_actions[5]] jacking actions!"
. += get_examine_message(src)
/obj/item/glassblowing/molten_glass/pickup(mob/user)
if(!isliving(user))
/obj/item/glassblowing/molten_glass/pickup(mob/living/user)
if(!istype(user))
return ..()
. = ..()
var/mob/living/living_user = user
try_burn_user(user)
/**
* Tries to burn the user if the glass is still molten hot.
*
* Arguments:
* * mob/living/user - user to burn
*/
/obj/item/glassblowing/molten_glass/proc/try_burn_user(mob/living/user)
if(!COOLDOWN_FINISHED(src, remaining_heat))
to_chat(living_user, span_warning("You burn your hands trying to pick up [src]!"))
living_user.adjustFireLoss(15)
to_chat(user, span_warning("You burn your hands trying to pick up [src]!"))
user.emote("scream")
user.dropItemToGround(src)
var/obj/item/bodypart/affecting = user.get_active_hand()
return affecting?.receive_damage(0, 15, wound_bonus = CANT_WOUND)
user.investigate_log("was burned their hand on [src] for [15] at [AREACOORD(user)]", INVESTIGATE_CRAFTING)
/obj/item/glassblowing/blowing_rod
name = "blowing rod"
desc = "A tool that is used to hold the molten glass as well as help shape it."
icon_state = "blow_pipe_empty"
tool_behaviour = TOOL_BLOWROD
/// Whether the rod is in use currently; will try to prevent many other actions on it
var/in_use = FALSE
/// A ref to the glass item being blown
var/datum/weakref/glass_ref
/obj/item/glassblowing/blowing_rod/examine(mob/user)
. = ..()
var/obj/item/glassblowing/molten_glass/find_glass = locate() in contents
if(!find_glass)
var/obj/item/glassblowing/molten_glass/glass = glass_ref.resolve()
if(!glass)
return
if(COOLDOWN_FINISHED(find_glass, remaining_heat))
. += span_warning("[src] has cooled down and will require reheating to modify!")
if(find_glass.required_actions[1])
. += "You require [find_glass.required_actions[1]] blowing actions!"
. += "You currently have [find_glass.current_actions[1]] blowing actions!"
if(find_glass.required_actions[2])
. += "You require [find_glass.required_actions[2]] spinning actions!"
. += "You currently have [find_glass.current_actions[2]] spinning actions!"
if(find_glass.required_actions[3])
. += "You require [find_glass.required_actions[3]] paddling actions!"
. += "You currently have [find_glass.current_actions[3]] paddling actions!"
if(find_glass.required_actions[4])
. += "You require [find_glass.required_actions[4]] shearing actions!"
. += "You currently have [find_glass.current_actions[4]] shearing actions!"
if(find_glass.required_actions[5])
. += "You require [find_glass.required_actions[5]] jacking actions!"
. += "You currently have [find_glass.current_actions[5]] jacking actions!"
. += get_examine_message(glass)
/obj/item/glassblowing/blowing_rod/proc/check_valid_table(mob/living/user)
var/skill_level = user.mind.get_skill_level(/datum/skill/production)
if(skill_level >= SKILL_LEVEL_MASTER) //as a master, you can skip tables
return TRUE
for(var/obj/structure/table/check_table in range(1, get_turf(src)))
if(!(check_table.resistance_flags & FLAMMABLE))
return TRUE //if you can find a table that is not flammable, good
return FALSE
/**
* Create the examine message and return it.
*
* This will include all the remaining steps and whether the glass has cooled down or not.
*
* Arguments:
* * obj/item/glassblowing/molten_glass/glass - the glass object being examined
*
* Returns the examine message.
*/
/obj/item/glassblowing/proc/get_examine_message(obj/item/glassblowing/molten_glass/glass)
if(COOLDOWN_FINISHED(glass, remaining_heat))
. += span_warning("The glass has cooled down and will require reheating to modify! ")
if(glass.steps_remaining[STEP_BLOW])
. += "The glass requires [glass.steps_remaining[STEP_BLOW]] more blowing actions! "
if(glass.steps_remaining[STEP_SPIN])
. += "The glass requires [glass.steps_remaining[STEP_SPIN]] more spinning actions! "
if(glass.steps_remaining[STEP_PADDLE])
. += "The glass requires [glass.steps_remaining[STEP_PADDLE]] more paddling actions! "
if(glass.steps_remaining[STEP_SHEAR])
. += "The glass requires [glass.steps_remaining[STEP_SHEAR]] more shearing actions! "
if(glass.steps_remaining[STEP_JACKS])
. += "The glass requires [glass.steps_remaining[STEP_JACKS]] more jacking actions!"
/obj/item/glassblowing/blowing_rod/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(!proximity_flag)
return ..()
if(istype(target, /obj/item/glassblowing/molten_glass))
var/obj/item/glassblowing/molten_glass/attacking_glass = target
var/obj/item/glassblowing/molten_glass/find_glass = locate() in contents
if(find_glass)
var/obj/item/glassblowing/molten_glass/glass = glass_ref?.resolve()
if(glass)
to_chat(user, span_warning("[src] already has some glass on it!"))
return
attacking_glass.forceMove(src)
if(!user.transferItemToLoc(attacking_glass, src))
return
glass_ref = WEAKREF(attacking_glass)
to_chat(user, span_notice("[src] picks up [target]."))
icon_state = "blow_pipe_full"
return
@@ -143,138 +161,303 @@
/obj/item/glassblowing/blowing_rod/attackby(obj/item/attacking_item, mob/living/user, params)
var/actioning_speed = user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) * DEFAULT_TIMED
var/obj/item/glassblowing/molten_glass/find_glass = locate() in contents
var/obj/item/glassblowing/molten_glass/glass = glass_ref?.resolve()
if(istype(attacking_item, /obj/item/glassblowing/molten_glass))
if(find_glass)
if(glass)
to_chat(user, span_warning("[src] already has some glass on it still!"))
return
attacking_item.forceMove(src)
if(!user.transferItemToLoc(attacking_item, src))
return
glass_ref = WEAKREF(attacking_item)
to_chat(user, span_notice("[src] picks up [attacking_item]."))
icon_state = "blow_pipe_full"
return
if(istype(attacking_item, /obj/item/glassblowing/paddle))
do_glass_step(3, user, "paddle", actioning_speed)
do_glass_step(STEP_PADDLE, user, actioning_speed, glass)
return
if(istype(attacking_item, /obj/item/glassblowing/shears))
do_glass_step(4, user, "shear", actioning_speed)
do_glass_step(STEP_SHEAR, user, actioning_speed, glass)
return
if(istype(attacking_item, /obj/item/glassblowing/jacks))
do_glass_step(5, user, "jack", actioning_speed)
do_glass_step(STEP_JACKS, user, actioning_speed, glass)
return
return ..()
/obj/item/glassblowing/blowing_rod/attack_self(mob/user, modifiers)
var/obj/item/glassblowing/molten_glass/find_glass = locate() in contents
var/actioning_speed = user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) * DEFAULT_TIMED
if(find_glass)
if(COOLDOWN_FINISHED(find_glass, remaining_heat))
to_chat(user, span_warning("The glass has cooled down far too much to be handled..."))
return
if(in_use)
to_chat(user, span_warning("[src] is busy being used!"))
return
in_use = TRUE
if(!find_glass.chosen_item)
var/choice = tgui_input_list(user, "What would you like to make?", "Choice Selection", list("Plate", "Bowl", "Globe", "Cup", "Lens", "Bottle"))
if(!choice)
in_use = FALSE
return
switch(choice)
if("Plate")
find_glass.chosen_item = /obj/item/plate/blowing_glass
find_glass.required_actions = list(3,3,3,0,0) //blowing, spinning, paddling
if("Bowl")
find_glass.chosen_item = /obj/item/reagent_containers/cup/bowl/blowing_glass
find_glass.required_actions = list(2,2,2,0,3) //blowing, spinning, paddling
if("Globe")
find_glass.chosen_item = /obj/item/glassblowing/glass_globe
find_glass.required_actions = list(6,3,0,0,0) //blowing, spinning
if("Cup")
find_glass.chosen_item = /obj/item/reagent_containers/cup/beaker/large/blowing_glass
find_glass.required_actions = list(3,3,3,0,0) //blowing, spinning, paddling
if("Lens")
find_glass.chosen_item = /obj/item/glassblowing/glass_lens
find_glass.required_actions = list(0,0,3,3,3) //paddling, shearing, jacking
if("Bottle")
find_glass.chosen_item = /obj/item/reagent_containers/cup/glass/bottle/small
find_glass.required_actions = list(3,2,3,0,0) //blowing, spinning, paddling
in_use = FALSE
return
else
in_use = FALSE
var/action_choice = tgui_alert(user, "What would you like to do?", "Action Selection", list("Blow", "Spin", "Remove"))
if(!action_choice)
return
switch(action_choice)
if("Blow")
do_glass_step(1, user, "blow", actioning_speed)
if("Spin")
do_glass_step(2, user, "spin", actioning_speed)
if("Remove")
for(var/iterate in 1 to 5)
if(find_glass.current_actions[iterate] < find_glass.required_actions[iterate])
remove_glass()
return
new find_glass.chosen_item(get_turf(src))
user.mind.adjust_experience(/datum/skill/production, 30)
qdel(find_glass)
icon_state = "blow_pipe_empty"
return
return
return ..()
/obj/item/glassblowing/blowing_rod/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GlassBlowing", name)
ui.open()
/obj/item/glassblowing/blowing_rod/ui_data()
var/obj/item/glassblowing/molten_glass/glass = glass_ref?.resolve()
var/data = list()
data["inUse"] = in_use
if(glass)
data["glass"] = list(
timeLeft = COOLDOWN_TIMELEFT(glass, remaining_heat),
totalTime = glass.total_time,
chosenItem = null,
stepsRemaining = glass.steps_remaining,
isFinished = glass.is_finished
)
var/obj/item_path = glass.chosen_item
data["glass"]["chosenItem"] = item_path ? list(name = initial(item_path.name), type = item_path) : null
else
data["glass"] = null
return data
/obj/item/glassblowing/blowing_rod/ui_act(action, params)
. = ..()
if(.)
return
if(!Adjacent(usr))
return
add_fingerprint(usr)
usr.set_machine(src)
var/obj/item/glassblowing/molten_glass/glass = glass_ref?.resolve()
var/actioning_speed = usr.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) * DEFAULT_TIMED
if(!glass)
return
if(action == "Remove")
if(!glass.chosen_item)
remove_glass(usr, glass)
in_use = FALSE
return
if(glass.is_finished)
create_item(usr, glass)
in_use = FALSE
else
remove_glass(usr, glass)
return
if(!glass.chosen_item)
switch(action)
if("Plate")
glass.chosen_item = /obj/item/plate/blowing_glass
glass.steps_remaining = list(blow=3,spin=3,paddle=3,shear=0,jacks=0) //blowing, spinning, paddling
if("Bowl")
glass.chosen_item = /obj/item/reagent_containers/cup/bowl/blowing_glass
glass.steps_remaining = list(blow=2,spin=2,paddle=2,shear=0,jacks=3) //blowing, spinning, paddling
if("Globe")
glass.chosen_item = /obj/item/glassblowing/glass_globe
glass.steps_remaining = list(blow=6,spin=3,paddle=0,shear=0,jacks=0) //blowing, spinning
if("Cup")
glass.chosen_item = /obj/item/reagent_containers/cup/beaker/large/blowing_glass
glass.steps_remaining = list(blow=3,spin=3,paddle=3,shear=0,jacks=0) //blowing, spinning, paddling
if("Lens")
glass.chosen_item = /obj/item/glassblowing/glass_lens
glass.steps_remaining = list(blow=0,spin=0,paddle=3,shear=3,jacks=3) //paddling, shearing, jacking
if("Bottle")
glass.chosen_item = /obj/item/reagent_containers/cup/glass/bottle/small
glass.steps_remaining = list(blow=3,spin=2,paddle=3,shear=0,jacks=0) //blowing, spinning, paddling
else
switch(action)
if("Blow")
do_glass_step(STEP_BLOW, usr, actioning_speed, glass)
if("Spin")
do_glass_step(STEP_SPIN, usr, actioning_speed, glass)
if("Paddle")
do_glass_step(STEP_PADDLE, usr, actioning_speed, glass)
if("Shear")
do_glass_step(STEP_SHEAR, usr, actioning_speed, glass)
if("Jacks")
do_glass_step(STEP_JACKS, usr, actioning_speed, glass)
if("Cancel")
glass.chosen_item = null
glass.steps_remaining = null
glass.is_finished = FALSE
to_chat(usr, span_notice("You start over with the [src]."))
/**
* Removes the glass object from the rod.
*
* Try to put the glass into the user's hands, or on the floor if that fails.
*
* Arguments:
* * mob/user - the mob doing the removing
* * obj/item/glassblowing/molten_glass/glass - the glass object
*
* Returns TRUE or FALSE.
*/
/obj/item/glassblowing/blowing_rod/proc/remove_glass(mob/user, obj/item/glassblowing/molten_glass/glass)
if(!glass)
return
in_use = FALSE
user.put_in_hands(glass)
glass.try_burn_user(user)
glass_ref = null
icon_state = "blow_pipe_empty"
/**
* Creates the finished product and delete the glass object used to make it.
*
* Try to put the finished product into the user's hands
*
* Arguments:
* * mob/user - the user doing the creating
* * obj/item/glassblowing/molten_glass/glass - the glass object
*
* Returns TRUE or FALSE.
*/
/obj/item/glassblowing/blowing_rod/proc/create_item(mob/user, obj/item/glassblowing/molten_glass/glass)
if(!glass)
return
if(in_use)
return
in_use = TRUE
user.put_in_hands(new glass.chosen_item)
user.mind.adjust_experience(/datum/skill/production, 30)
glass_ref = null
qdel(glass)
icon_state = "blow_pipe_empty"
return
/**
* Display fail message and reset in_use.
*
* Craft is finished when all steps in steps_remaining are 0.
*
* Arguments:
* * mob/user - mob to display to
* * message - to display
*/
/obj/item/glassblowing/blowing_rod/proc/fail_message(message, mob/user)
to_chat(user, span_warning(message))
in_use = FALSE
/obj/item/glassblowing/blowing_rod/proc/do_glass_step(number, mob/user, message, actioning_speed)
var/obj/item/glassblowing/molten_glass/find_glass = locate() in contents
if(!find_glass)
/**
* Try to do a glassblowing action.
*
* Checks for a table and valid tool if applicable, and updates the steps_remaining on the glass object.
*
* Arguments:
* * step_id - the step id e.g. STEP_BLOW
* * actioning_speed - the speed based on the user's production skill
* * obj/item/glassblowing/molten_glass/glass - the glass object
*/
/obj/item/glassblowing/blowing_rod/proc/do_glass_step(step_id, mob/user, actioning_speed, obj/item/glassblowing/molten_glass/glass)
if(!glass)
return
if(in_use)
return
in_use = TRUE
if(!check_valid_table(user))
fail_message("You must be near a non-flammable table!", user)
return
to_chat(user, span_notice("You begin to [message] [src]."))
if(!check_valid_tool(user, step_id))
return
to_chat(user, span_notice("You begin to [step_id] [src]."))
if(!do_after(user, actioning_speed, target = src))
fail_message("You interrupt an action!", user)
return
if(!check_valid_table(user))
fail_message("You must be near a non-flammable table!", user)
return
find_glass.current_actions[number]++
to_chat(user, span_notice("You finish trying to [message] [src]."))
if(glass.steps_remaining)
// We do not want to have negative values here
if(glass.steps_remaining[step_id] > 0)
glass.steps_remaining[step_id]--
if(check_finished(glass))
glass.is_finished = TRUE
in_use = FALSE
to_chat(user, span_notice("You finish trying to [step_id] [src]."))
user.mind.adjust_experience(/datum/skill/production, 10)
/obj/item/glassblowing/blowing_rod/proc/remove_glass()
var/obj/item/glassblowing/molten_glass/find_glass = locate() in contents
if(!find_glass)
return
/**
* Check if there is a non-flammable table nearby to do the crafting on.
*
* If the user is a master in the production skill, they can skip tables.
*
* Arguments:
* * mob/living/user - the mob doing the action
*
* Returns TRUE or FALSE.
*/
/obj/item/glassblowing/blowing_rod/proc/check_valid_table(mob/living/user)
var/skill_level = user.mind.get_skill_level(/datum/skill/production)
if(skill_level >= SKILL_LEVEL_MASTER) //
return TRUE
for(var/obj/structure/table/check_table in range(1, get_turf(src)))
if(!(check_table.resistance_flags & FLAMMABLE))
return TRUE
return FALSE
/**
* Check if user is carrying the proper tool for the step.
*
* Arguments:
* * mob/living/carbon/human/user - the mob doing the action
* * step_id - the step id of the action being done
*
* Returns TRUE or FALSE.
*/
/obj/item/glassblowing/blowing_rod/proc/check_valid_tool(mob/living/carbon/human/user, step_id)
if(!istype(user))
return FALSE
var/obj/item/glassblowing/tool_path
switch(step_id)
if(STEP_BLOW)
return TRUE
if(STEP_SPIN)
return TRUE
if(STEP_PADDLE)
tool_path = /obj/item/glassblowing/paddle
if(STEP_SHEAR)
tool_path = /obj/item/glassblowing/shears
if(STEP_JACKS)
tool_path = /obj/item/glassblowing/jacks
if(user.is_holding_item_of_type(tool_path))
return TRUE
balloon_alert(user, "need to be holding [initial(tool_path.name)]!")
in_use = FALSE
find_glass.forceMove(get_turf(src))
icon_state = "blow_pipe_empty"
return FALSE
/**
* Checks if the glass is ready to craft into its chosen item.
*
* Craft is finished when all steps in steps_remaining are 0.
*
* Arguments:
* * obj/item/glassblowing/molten_glass/glass - the glass object
*
* Returns TRUE or FALSE.
*/
/obj/item/glassblowing/blowing_rod/proc/check_finished(obj/item/glassblowing/molten_glass/glass)
for(var/step_id in glass.steps_remaining)
if(glass.steps_remaining[step_id] != 0)
return FALSE
return TRUE
/datum/crafting_recipe/glassblowing_recipe
reqs = list(/obj/item/stack/sheet/iron = 5)
category = CAT_MISC
/obj/item/glassblowing/blowing_rod
name = "blowing rod"
desc = "A tool that is used to hold the molten glass as well as help shape it."
icon_state = "blow_pipe_empty"
///whether the item is in use currently; will try to prevent many other actions on it
var/in_use = FALSE
tool_behaviour = TOOL_BLOWROD
/datum/crafting_recipe/glassblowing_recipe/glass_blowing_rod
name = "Glass-blowing Blowing Rod"
result = /obj/item/glassblowing/blowing_rod
@@ -326,3 +509,8 @@
return ..()
#undef DEFAULT_TIMED
#undef STEP_BLOW
#undef STEP_SPIN
#undef STEP_PADDLE
#undef STEP_SHEAR
#undef STEP_JACKS
@@ -861,6 +861,7 @@
return TOOL_ACT_TOOLTYPE_SUCCESS
COOLDOWN_START(find_glass, remaining_heat, glassblowing_amount)
find_glass.total_time = glassblowing_amount
to_chat(user, span_notice("You finish heating up [blowing_item]."))
user.mind.adjust_experience(/datum/skill/smithing, 5)
user.mind.adjust_experience(/datum/skill/production, 10)
@@ -0,0 +1,257 @@
import { Box, Button, Flex, Stack, Section, ProgressBar, AnimatedNumber, Table } from '../components';
import { toFixed } from 'common/math';
import { BooleanLike } from 'common/react';
import { useBackend } from '../backend';
import { Window } from '../layouts';
type GlassData = {
hasGlass: BooleanLike;
inUse: BooleanLike;
glass: Glass;
};
type Glass = {
chosenItem: CraftItem;
stepsRemaining: RemainingSteps;
timeLeft: number;
totalTime: number;
isFinished: BooleanLike;
};
type CraftItem = {
name: string;
type: string;
};
type RemainingSteps = {
blow: number;
spin: number;
paddle: number;
shear: number;
jacks: number;
};
export const GlassBlowing = (props, context) => {
const { act, data } = useBackend<GlassData>(context);
const { glass, inUse } = data;
return (
<Window width={335} height={325}>
<Window.Content scrollable>
<Section
title={glass && glass.timeLeft ? 'Molten Glass' : 'Cooled Glass'}
buttons={
<Button
icon={
glass && glass.isFinished
? 'check'
: glass && glass.timeLeft
? 'triangle-exclamation'
: 'arrow-right'
}
color={
glass && glass.isFinished
? 'good'
: glass && glass.timeLeft
? 'red'
: 'default'
}
tooltipPosition="bottom"
tooltip={
glass && glass.timeLeft
? 'You may want to think twice about touching this right now...'
: 'It has cooled and is safe to handle.'
}
content={glass && glass.isFinished ? 'Complete Craft' : 'Remove'}
disabled={!glass || inUse}
onClick={() => act('Remove')}
/>
}
/>
{glass && !glass.chosenItem && (
<Section title="Pick a craft">
<Stack fill vertical>
<Stack.Item>
<Box>What will you craft?</Box>
</Stack.Item>
<Stack.Item>
<Button
content="Plate"
disabled={inUse}
onClick={() => act('Plate')}
/>
<Button
content="Bowl"
tooltipPosition="bottom"
disabled={inUse}
onClick={() => act('Bowl')}
/>
<Button
content="Globe"
disabled={inUse}
onClick={() => act('Globe')}
/>
<Button
content="Cup"
disabled={inUse}
onClick={() => act('Cup')}
/>
<Button
content="Lens"
tooltipPosition="bottom"
disabled={inUse}
onClick={() => act('Lens')}
/>
<Button
content="Bottle"
disabled={inUse}
onClick={() => act('Bottle')}
/>
</Stack.Item>
</Stack>
</Section>
)}
{glass && glass.chosenItem && (
<>
<Section title="Steps Remaining:">
<Stack fill vertical>
<Stack.Item>
<Box>
You are crafting a {glass.chosenItem.name}.
<br />
<br />
</Box>
</Stack.Item>
<Table>
<Stack.Item>
{glass.stepsRemaining.blow !== 0 && (
<Table.Cell>
<Button
content="Blow"
icon="fire"
color="orange"
disabled={inUse || !glass.timeLeft}
tooltipPosition="bottom"
tooltip={
glass.timeLeft === 0
? 'Needs to be glowing hot.'
: ''
}
onClick={() => act('Blow')}
/>
&nbsp;x{glass.stepsRemaining.blow}
</Table.Cell>
)}
{glass.stepsRemaining.spin !== 0 && (
<Table.Cell>
<Button
content="Spin"
icon="fire"
color="orange"
disabled={inUse || !glass.timeLeft}
tooltipPosition="bottom"
tooltip={
glass.timeLeft === 0
? 'Needs to be glowing hot.'
: ''
}
onClick={() => act('Spin')}
/>
&nbsp;x{glass.stepsRemaining.spin}
</Table.Cell>
)}
{glass.stepsRemaining.paddle !== 0 && (
<Table.Cell>
<Button
content="Paddle"
disabled={inUse}
tooltipPosition="bottom"
tooltip={'You need to use a paddle.'}
onClick={() => act('Paddle')}
/>
&nbsp;x{glass.stepsRemaining.paddle}
</Table.Cell>
)}
{glass.stepsRemaining.shear !== 0 && (
<Table.Cell>
<Button
content="Shears"
disabled={inUse}
tooltipPosition="bottom"
tooltip={'You need to use shears.'}
onClick={() => act('Shear')}
/>
&nbsp;x{glass.stepsRemaining.shear}
</Table.Cell>
)}
{glass.stepsRemaining.jacks !== 0 && (
<Table.Cell>
<Button
content="Jacks"
disabled={inUse}
tooltipPosition="bottom"
tooltip={'You need to use jacks.'}
onClick={() => act('Jacks')}
/>
&nbsp;x{glass.stepsRemaining.jacks}
</Table.Cell>
)}
</Stack.Item>
</Table>
</Stack>
</Section>
<Section title>
<Flex direction="row-reverse">
<Flex.Item>
<Button
icon="times"
color={glass.timeLeft ? 'orange' : 'default'}
content="Cancel craft"
disabled={inUse}
onClick={() => act('Cancel')}
/>
</Flex.Item>
</Flex>
</Section>
</>
)}
{glass && glass.timeLeft !== 0 && (
<Section title="Heat level">
<ProgressBar
value={glass.timeLeft / glass.totalTime}
ranges={{
red: [0.8, Infinity],
orange: [0.65, 0.8],
yellow: [0.3, 0.65],
blue: [0.05, 0.3],
black: [-Infinity, 0.05],
}}
style={{
'background-image':
'linear-gradient(to right, blue, yellow, red)',
}}>
<AnimatedNumber
value={glass.timeLeft}
format={(value) => toFixed(value, 1)}
/>
{'/' + glass.totalTime.toFixed(1)}
</ProgressBar>
</Section>
)}
{glass && glass.timeLeft === 0 && (
<Section title="Heat level">
<ProgressBar
value={0 / 0}
ranges={{}}
style={{
'background-image': 'grey',
}}>
<AnimatedNumber value={0} />
</ProgressBar>
</Section>
)}
</Window.Content>
</Window>
);
};