mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 07:08:00 +01:00
Adds a slightly-more-useful (maybe too useful) reagent recipe browser to chem and drink dispensers (#93903)
This commit is contained in:
@@ -205,6 +205,48 @@
|
||||
#define REACTION_TAG_PLANT (1<<19)
|
||||
/// This reaction is produces a product that affects plants
|
||||
#define REACTION_TAG_COMPETITIVE (1<<20)
|
||||
/// Reaction produces a reagent that is a common component for other reactions
|
||||
#define REACTION_TAG_COMPONENT (1<<21)
|
||||
/// Denotes reactions that will immediately do something on reaction, like an explosion, smoke, etc.
|
||||
#define REACTION_TAG_ACTIVE (1<<22)
|
||||
|
||||
/// Readable list of reagent reaction tags (in the same order as they are defined!)
|
||||
#define REACTION_TAG_READABLE list(\
|
||||
"BRUTE" = REACTION_TAG_BRUTE,\
|
||||
"BURN" = REACTION_TAG_BURN,\
|
||||
"TOXIN" = REACTION_TAG_TOXIN,\
|
||||
"OXY" = REACTION_TAG_OXY,\
|
||||
"HEALING" = REACTION_TAG_HEALING,\
|
||||
"DAMAGING" = REACTION_TAG_DAMAGING,\
|
||||
"EXPLOSIVE" = REACTION_TAG_EXPLOSIVE,\
|
||||
"OTHER" = REACTION_TAG_OTHER,\
|
||||
"DANGEROUS" = REACTION_TAG_DANGEROUS,\
|
||||
"EASY" = REACTION_TAG_EASY,\
|
||||
"MODERATE" = REACTION_TAG_MODERATE,\
|
||||
"HARD" = REACTION_TAG_HARD,\
|
||||
"ORGAN" = REACTION_TAG_ORGAN,\
|
||||
"DRINK" = REACTION_TAG_DRINK,\
|
||||
"FOOD" = REACTION_TAG_FOOD,\
|
||||
"SLIME" = REACTION_TAG_SLIME,\
|
||||
"DRUG" = REACTION_TAG_DRUG,\
|
||||
"UNIQUE" = REACTION_TAG_UNIQUE,\
|
||||
"CHEMICAL" = REACTION_TAG_CHEMICAL,\
|
||||
"PLANT" = REACTION_TAG_PLANT,\
|
||||
"COMPETITIVE" = REACTION_TAG_COMPETITIVE,\
|
||||
"COMPONENT" = REACTION_TAG_COMPONENT,\
|
||||
"ACTIVE" = REACTION_TAG_ACTIVE,\
|
||||
)
|
||||
|
||||
/// Reaction tags for basic damgae types
|
||||
#define DAMAGE_HEALING_REACTION_TAGS (REACTION_TAG_BRUTE | REACTION_TAG_BURN | REACTION_TAG_TOXIN | REACTION_TAG_OXY)
|
||||
/// Reaction tags for medication
|
||||
#define MEDICATION_REACTION_TAGS (REACTION_TAG_HEALING | REACTION_TAG_DAMAGING | REACTION_TAG_ORGAN | REACTION_TAG_DRUG)
|
||||
/// Reaction tags for things the chemist would make
|
||||
#define CHEMIST_REACTION_TAGS (REACTION_TAG_EXPLOSIVE | REACTION_TAG_CHEMICAL | REACTION_TAG_COMPETITIVE | REACTION_TAG_EXPLOSIVE | REACTION_TAG_COMPONENT)
|
||||
/// Reaction tags for botanist stuff
|
||||
#define BOTANIST_REACTION_TAGS (REACTION_TAG_PLANT | REACTION_TAG_COMPONENT)
|
||||
/// Reaction tags for food and drink mainly
|
||||
#define KITCHEN_REACTION_TAGS (REACTION_TAG_FOOD | REACTION_TAG_DRINK | REACTION_TAG_COMPONENT)
|
||||
|
||||
//flags used by holder.dm to locate an reagent
|
||||
///Direct type
|
||||
|
||||
@@ -166,7 +166,12 @@ GLOBAL_LIST_INIT(plant_traits, init_plant_traits())
|
||||
|
||||
if(!is_type_in_typecache(reaction.type, blacklist))
|
||||
//Master list of ALL reactions that is used in the UI lookup table. This is expensive to make, and we don't want to lag the server by creating it on UI request, so it's cached to send to UIs instantly.
|
||||
GLOB.chemical_reactions_results_lookup_list += list(list("name" = product_name, "id" = reaction.type, "bitflags" = bitflags, "reactants" = reagents))
|
||||
GLOB.chemical_reactions_results_lookup_list += list(list(
|
||||
"name" = product_name,
|
||||
"id" = reaction.type,
|
||||
"bitflags" = bitflags,
|
||||
"reactants" = reagents,
|
||||
))
|
||||
|
||||
// Create filters based on each reagent id in the required reagents list - this is specifically for finding reactions from product(reagent) ids/typepaths.
|
||||
for(var/id in product_ids)
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
required_reagents = list(/datum/reagent/consumable/liquidelectricity/enriched = 2, /datum/reagent/consumable/grounding_solution = 1)
|
||||
mix_message = "The mixture lets off a sharp snap as the electricity discharges."
|
||||
mix_sound = 'sound/items/weapons/taser.ogg'
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_flags = REACTION_INSTANT | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/food/martian_batter
|
||||
results = list(/datum/reagent/consumable/martian_batter = 10)
|
||||
|
||||
@@ -257,27 +257,8 @@
|
||||
//Use GLOB list - saves processing
|
||||
data["master_reaction_list"] = GLOB.chemical_reactions_results_lookup_list
|
||||
data["bitflags"] = list()
|
||||
data["bitflags"]["BRUTE"] = REACTION_TAG_BRUTE
|
||||
data["bitflags"]["BURN"] = REACTION_TAG_BURN
|
||||
data["bitflags"]["TOXIN"] = REACTION_TAG_TOXIN
|
||||
data["bitflags"]["OXY"] = REACTION_TAG_OXY
|
||||
data["bitflags"]["HEALING"] = REACTION_TAG_HEALING
|
||||
data["bitflags"]["DAMAGING"] = REACTION_TAG_DAMAGING
|
||||
data["bitflags"]["EXPLOSIVE"] = REACTION_TAG_EXPLOSIVE
|
||||
data["bitflags"]["OTHER"] = REACTION_TAG_OTHER
|
||||
data["bitflags"]["DANGEROUS"] = REACTION_TAG_DANGEROUS
|
||||
data["bitflags"]["EASY"] = REACTION_TAG_EASY
|
||||
data["bitflags"]["MODERATE"] = REACTION_TAG_MODERATE
|
||||
data["bitflags"]["HARD"] = REACTION_TAG_HARD
|
||||
data["bitflags"]["ORGAN"] = REACTION_TAG_ORGAN
|
||||
data["bitflags"]["DRINK"] = REACTION_TAG_DRINK
|
||||
data["bitflags"]["FOOD"] = REACTION_TAG_FOOD
|
||||
data["bitflags"]["SLIME"] = REACTION_TAG_SLIME
|
||||
data["bitflags"]["DRUG"] = REACTION_TAG_DRUG
|
||||
data["bitflags"]["UNIQUE"] = REACTION_TAG_UNIQUE
|
||||
data["bitflags"]["CHEMICAL"] = REACTION_TAG_CHEMICAL
|
||||
data["bitflags"]["PLANT"] = REACTION_TAG_PLANT
|
||||
data["bitflags"]["COMPETITIVE"] = REACTION_TAG_COMPETITIVE
|
||||
for(var/readable_flag, real_flag in REACTION_TAG_READABLE)
|
||||
data["bitflags"][readable_flag] = real_flag
|
||||
|
||||
return data
|
||||
|
||||
@@ -407,5 +388,12 @@
|
||||
if("toggle_tag_competitive")
|
||||
ui_tags_selected = ui_tags_selected ^ REACTION_TAG_COMPETITIVE
|
||||
return TRUE
|
||||
if("toggle_tag_component")
|
||||
ui_tags_selected = ui_tags_selected ^ REACTION_TAG_COMPONENT
|
||||
return TRUE
|
||||
if("toggle_tag_active")
|
||||
ui_tags_selected = ui_tags_selected ^ REACTION_TAG_ACTIVE
|
||||
return TRUE
|
||||
|
||||
if("update_ui")
|
||||
return TRUE
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
/// If the UI has the pH meter shown
|
||||
var/show_ph = TRUE
|
||||
/// The overlay used to display the beaker on the machine
|
||||
var/mutable_appearance/beaker_overlay
|
||||
VAR_PRIVATE/mutable_appearance/beaker_overlay
|
||||
/// Icon to display when the machine is powered
|
||||
var/working_state = "dispenser_working"
|
||||
/// Icon to display when the machine is not powered
|
||||
@@ -41,9 +41,14 @@
|
||||
/// Starting purity of the created reagents
|
||||
var/base_reagent_purity = 1
|
||||
/// Records the reagents dispensed by the user if this list is not null
|
||||
var/list/recording_recipe
|
||||
VAR_PRIVATE/list/recording_recipe
|
||||
/// Saves all the recipes recorded by the machine
|
||||
var/list/saved_recipes = list()
|
||||
VAR_PRIVATE/list/saved_recipes = list()
|
||||
|
||||
/// Filters out all reactions that don't have any of these tags from the reaction list
|
||||
var/shown_reaction_tags = DAMAGE_HEALING_REACTION_TAGS | MEDICATION_REACTION_TAGS | CHEMIST_REACTION_TAGS
|
||||
/// Filters out all reactions that have any one of these tags from the reaction list
|
||||
var/hidden_reaction_tags = REACTION_TAG_ACTIVE | REACTION_TAG_FOOD | REACTION_TAG_DRINK
|
||||
|
||||
/// The default list of dispensable_reagents
|
||||
var/static/list/default_dispensable_reagents = list(
|
||||
@@ -90,6 +95,7 @@
|
||||
/datum/reagent/drug/space_drugs,
|
||||
/datum/reagent/toxin
|
||||
)
|
||||
|
||||
/obj/machinery/chem_dispenser/Initialize(mapload)
|
||||
if(dispensable_reagents != null && !dispensable_reagents.len)
|
||||
dispensable_reagents = default_dispensable_reagents
|
||||
@@ -257,6 +263,18 @@
|
||||
beaker_data["contents"] = beakerContents
|
||||
.["beaker"] = beaker_data
|
||||
|
||||
/obj/machinery/chem_dispenser/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["reaction_list"] = get_reaction_list()
|
||||
data["all_bitflags"] = list()
|
||||
for(var/readable_flag, real_flag in REACTION_TAG_READABLE)
|
||||
if((real_flag & hidden_reaction_tags) || !(real_flag & shown_reaction_tags))
|
||||
continue
|
||||
data["all_bitflags"][readable_flag] = real_flag
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/chem_dispenser/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -504,6 +522,61 @@
|
||||
/obj/machinery/chem_dispenser/attack_ai_secondary(mob/user, list/modifiers)
|
||||
return attack_hand_secondary(user, modifiers)
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/get_reaction_list()
|
||||
var/static/list/reaction_list
|
||||
if(reaction_list?[type])
|
||||
return reaction_list[type]
|
||||
|
||||
reaction_list ||= list()
|
||||
reaction_list[type] = list()
|
||||
|
||||
var/list/new_reaction_list = list()
|
||||
for(var/result, reactions in GLOB.chemical_reactions_list_product_index - dispensable_reagents)
|
||||
var/datum/reagent/result_datum = GLOB.chemical_reagents_list[result]
|
||||
for(var/datum/chemical_reaction/reaction as anything in reactions)
|
||||
if(!(reaction.reaction_tags & shown_reaction_tags))
|
||||
continue
|
||||
if(reaction.reaction_tags & hidden_reaction_tags)
|
||||
continue
|
||||
if(reaction.required_container)
|
||||
continue
|
||||
|
||||
var/index = result_datum.name
|
||||
var/list/new_info = get_reaction_info(reaction)
|
||||
new_info["description"] = result_datum.description
|
||||
new_info["color"] = result_datum.color
|
||||
|
||||
var/num_alts = 0
|
||||
while(new_reaction_list[index])
|
||||
num_alts++
|
||||
index = "[result_datum.name] (Alt[num_alts == 1 ? "" : " #[num_alts]"])"
|
||||
|
||||
new_reaction_list[index] = new_info
|
||||
|
||||
reaction_list[type] = new_reaction_list
|
||||
return reaction_list[type]
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/get_reaction_info(datum/chemical_reaction/reaction)
|
||||
var/list/info = list()
|
||||
info["id"] = reaction.type
|
||||
info["lower_temperature"] = reaction.required_temp
|
||||
info["upper_temperature"] = reaction.optimal_temp
|
||||
info["lower_ph"] = reaction.optimal_ph_min
|
||||
info["upper_ph"] = reaction.optimal_ph_max
|
||||
info["bitflags"] = reaction.reaction_tags
|
||||
info["required_reagents"] = reagent_list_to_info(reaction.required_reagents)
|
||||
info["required_catalysts"] = reagent_list_to_info(reaction.required_catalysts)
|
||||
return info
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/reagent_list_to_info(list/reagent_list)
|
||||
var/list/info = list()
|
||||
for(var/datum/reagent/reagent_typepath as anything in reagent_list)
|
||||
info += list(list(
|
||||
"name" = reagent_typepath::name,
|
||||
"amount" = reagent_list[reagent_typepath],
|
||||
"typepath" = reagent_typepath,
|
||||
))
|
||||
return info
|
||||
|
||||
/obj/machinery/chem_dispenser/drinks
|
||||
name = "soda dispenser"
|
||||
@@ -520,6 +593,8 @@
|
||||
nopower_state = null
|
||||
pass_flags = PASSTABLE
|
||||
show_ph = FALSE
|
||||
shown_reaction_tags = KITCHEN_REACTION_TAGS
|
||||
hidden_reaction_tags = REACTION_TAG_ACTIVE
|
||||
/// The default list of reagents dispensable by the soda dispenser
|
||||
var/static/list/drinks_dispensable_reagents = list(
|
||||
/datum/reagent/consumable/coffee,
|
||||
@@ -676,6 +751,8 @@
|
||||
name = "botanical chemical dispenser"
|
||||
desc = "Creates and dispenses chemicals useful for botany."
|
||||
circuit = /obj/item/circuitboard/machine/chem_dispenser/mutagensaltpeter
|
||||
shown_reaction_tags = BOTANIST_REACTION_TAGS
|
||||
hidden_reaction_tags = REACTION_TAG_ACTIVE
|
||||
|
||||
/// The default list of dispensable reagents available in the mutagensaltpeter chem dispenser
|
||||
var/static/list/mutagensaltpeter_dispensable_reagents = list(
|
||||
|
||||
@@ -1422,7 +1422,7 @@
|
||||
|
||||
/datum/reagent/consumable/ethanol/neurotoxin
|
||||
name = "Neurotoxin"
|
||||
description = "A strong neurotoxin that puts the subject into a death-like state."
|
||||
description = "A strong neurotoxin that puts the patient into a death-like state."
|
||||
color = "#2E2E61" // rgb: 46, 46, 97
|
||||
boozepwr = 50
|
||||
quality = DRINK_VERYGOOD
|
||||
|
||||
@@ -1164,7 +1164,7 @@
|
||||
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
|
||||
|
||||
/datum/reagent/consumable/strawberry_banana
|
||||
name = "strawberry banana smoothie"
|
||||
name = "Strawberry Banana Smoothie"
|
||||
description = "A classic smoothie made from strawberries and bananas."
|
||||
color = "#FF9999"
|
||||
nutriment_factor = 0
|
||||
@@ -1172,7 +1172,7 @@
|
||||
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
|
||||
|
||||
/datum/reagent/consumable/berry_blast
|
||||
name = "berry blast smoothie"
|
||||
name = "Berry Blast Smoothie"
|
||||
description = "A classic smoothie made from mixed berries."
|
||||
color = "#A76DC5"
|
||||
nutriment_factor = 0
|
||||
@@ -1180,7 +1180,7 @@
|
||||
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
|
||||
|
||||
/datum/reagent/consumable/funky_monkey
|
||||
name = "funky monkey smoothie"
|
||||
name = "Funky Monkey Smoothie"
|
||||
description = "A classic smoothie made from chocolate and bananas."
|
||||
color = COLOR_BROWNER_BROWN
|
||||
nutriment_factor = 0
|
||||
@@ -1188,7 +1188,7 @@
|
||||
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
|
||||
|
||||
/datum/reagent/consumable/green_giant
|
||||
name = "green giant smoothie"
|
||||
name = "Green Giant Smoothie"
|
||||
description = "A green vegetable smoothie, made without vegetables."
|
||||
color = COLOR_VERY_DARK_LIME_GREEN
|
||||
nutriment_factor = 0
|
||||
@@ -1196,7 +1196,7 @@
|
||||
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
|
||||
|
||||
/datum/reagent/consumable/melon_baller
|
||||
name = "melon baller smoothie"
|
||||
name = "Melon Baller Smoothie"
|
||||
description = "A classic smoothie made from melons."
|
||||
color = "#D22F55"
|
||||
nutriment_factor = 0
|
||||
@@ -1204,7 +1204,7 @@
|
||||
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
|
||||
|
||||
/datum/reagent/consumable/vanilla_dream
|
||||
name = "vanilla dream smoothie"
|
||||
name = "Vanilla Dream Smoothie"
|
||||
description = "A classic smoothie made from vanilla and fresh cream."
|
||||
color = "#FFF3DD"
|
||||
nutriment_factor = 0
|
||||
|
||||
@@ -983,7 +983,8 @@
|
||||
|
||||
/datum/reagent/medicine/epinephrine
|
||||
name = "Epinephrine"
|
||||
description = "Very minor boost to stun resistance. Slowly heals damage if a patient is in critical condition, as well as regulating oxygen loss. Overdose causes weakness and toxin damage."
|
||||
description = "Stabilizes and slowly heals patients in critical condition, and slows suffocation. \
|
||||
Also provides a very minor boost to stun resistance. Overdose causes weakness and toxin damage."
|
||||
color = "#D2FFFA"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
overdose_threshold = 30
|
||||
|
||||
@@ -1080,7 +1080,7 @@
|
||||
|
||||
/datum/reagent/glycerol
|
||||
name = "Glycerol"
|
||||
description = "Glycerol is a simple polyol compound. Glycerol is sweet-tasting and of low toxicity."
|
||||
description = "A simple polyol compound. Sweet-tasting and of low toxicity."
|
||||
color = "#D3B913"
|
||||
taste_description = "sweetness"
|
||||
ph = 9
|
||||
@@ -1404,7 +1404,7 @@
|
||||
|
||||
/datum/reagent/impedrezene
|
||||
name = "Impedrezene"
|
||||
description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions."
|
||||
description = "A narcotic that impedes one's ability by slowing down the higher brain cell functions."
|
||||
color = "#E07DDD" // pink = happy = dumb
|
||||
taste_description = "numbness"
|
||||
ph = 9.1
|
||||
@@ -2074,21 +2074,21 @@
|
||||
|
||||
/datum/reagent/pentaerythritol
|
||||
name = "Pentaerythritol"
|
||||
description = "Slow down, it ain't no spelling bee!"
|
||||
color = "#E66FFF"
|
||||
description = "A crystalline compound used in the synthesis of explosives and other chemicals."
|
||||
color = "#EEEEEF"
|
||||
taste_description = "acid"
|
||||
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
|
||||
|
||||
/datum/reagent/acetaldehyde
|
||||
name = "Acetaldehyde"
|
||||
description = "Similar to plastic. Tastes like dead people."
|
||||
description = "A colorless liquid with a strong smell. Used in the synthesis of other chemicals."
|
||||
color = "#EEEEEF"
|
||||
taste_description = "dead people" //made from formaldehyde, ya get da joke ?
|
||||
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
|
||||
|
||||
/datum/reagent/acetone_oxide
|
||||
name = "Acetone Oxide"
|
||||
description = "Enslaved oxygen"
|
||||
description = "A highly reactive compoud derived from acetone. Known to cause burns on contact. Used in the synthesis of various explosives."
|
||||
color = "#966199cb"
|
||||
taste_description = "acid"
|
||||
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
|
||||
@@ -2115,7 +2115,7 @@
|
||||
|
||||
/datum/reagent/ash
|
||||
name = "Ash"
|
||||
description = "Supposedly phoenixes rise from these, but you've never seen it."
|
||||
description = "A fine ash. Supposedly phoenixes rise from these, but you've never seen it."
|
||||
color = "#515151"
|
||||
taste_description = "ash"
|
||||
ph = 6.5
|
||||
@@ -2530,7 +2530,7 @@
|
||||
|
||||
/datum/reagent/plastic_polymers
|
||||
name = "Plastic Polymers"
|
||||
description = "the petroleum based components of plastic."
|
||||
description = "Petroleum based components of plastic."
|
||||
color = "#f7eded"
|
||||
taste_description = "plastic"
|
||||
ph = 6
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
/datum/reagent/clf3
|
||||
name = "Chlorine Trifluoride"
|
||||
description = "Makes a temporary 3x3 fireball when it comes into existence, so be careful when mixing. ClF3 applied to a surface burns things that wouldn't otherwise burn, sometimes through the very floors of the station and exposing it to the vacuum of space."
|
||||
description = "A very flammable liquid capable of burning even through the hull of the station. Bursts into a fireball upon creation."
|
||||
color = "#FFC8C8"
|
||||
metabolization_rate = 10 * REAGENTS_METABOLISM
|
||||
taste_description = "burning"
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
|
||||
/datum/reagent/toxin/zombiepowder
|
||||
name = "Zombie Powder"
|
||||
description = "A strong neurotoxin that puts the subject into a death-like state."
|
||||
description = "A strong neurotoxin that puts the patient into a death-like state."
|
||||
silent_toxin = TRUE
|
||||
creation_purity = REAGENT_STANDARD_PURITY
|
||||
purity = REAGENT_STANDARD_PURITY
|
||||
@@ -705,7 +705,8 @@
|
||||
|
||||
/datum/reagent/toxin/formaldehyde
|
||||
name = "Formaldehyde"
|
||||
description = "Formaldehyde, on its own, is a fairly weak toxin. It contains trace amounts of Histamine, very rarely making it decay into Histamine. When used in a dead body, will prevent organ decay."
|
||||
description = "A fairly weak toxin that helps prevent organ decay in dead bodies. \
|
||||
It will slowly decay into Histamine over time."
|
||||
silent_toxin = TRUE
|
||||
color = "#B4004B"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
@@ -766,7 +767,7 @@
|
||||
|
||||
/datum/reagent/toxin/fentanyl
|
||||
name = "Fentanyl"
|
||||
description = "Fentanyl will inhibit brain function and cause toxin damage before eventually knocking out its victim."
|
||||
description = "Inhibits brain function and causes toxin damage before eventually knocking out the patient."
|
||||
color = "#64916E"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
creation_purity = REAGENT_STANDARD_PURITY
|
||||
@@ -1046,7 +1047,8 @@
|
||||
|
||||
/datum/reagent/toxin/heparin //Based on a real-life anticoagulant. I'm not a doctor, so this won't be realistic.
|
||||
name = "Heparin"
|
||||
description = "A powerful anticoagulant. All open cut wounds on the victim will open up and bleed much faster. It directly purges sanguirite, a coagulant."
|
||||
description = "A powerful anticoagulant. All open cut wounds on the patient will open up and bleed much faster. \
|
||||
Counters coagulants like Sanguirite, purging them."
|
||||
silent_toxin = TRUE
|
||||
creation_purity = REAGENT_STANDARD_PURITY
|
||||
purity = REAGENT_STANDARD_PURITY
|
||||
@@ -1064,7 +1066,7 @@
|
||||
|
||||
/datum/reagent/toxin/rotatium //Rotatium. Fucks up your rotation and is hilarious
|
||||
name = "Rotatium"
|
||||
description = "A constantly swirling, oddly colourful fluid. Causes the consumer's sense of direction and hand-eye coordination to become wild."
|
||||
description = "A constantly swirling, oddly colourful fluid. Causes the patient's sense of direction and hand-eye coordination to become wild."
|
||||
silent_toxin = TRUE
|
||||
creation_purity = REAGENT_STANDARD_PURITY
|
||||
purity = REAGENT_STANDARD_PURITY
|
||||
@@ -1164,7 +1166,7 @@
|
||||
|
||||
/datum/reagent/toxin/acid/fluacid
|
||||
name = "Fluorosulfuric Acid"
|
||||
description = "Fluorosulfuric acid is an extremely corrosive chemical substance."
|
||||
description = "An extremely corrosive chemical substance."
|
||||
color = "#5050FF"
|
||||
creation_purity = REAGENT_STANDARD_PURITY
|
||||
purity = REAGENT_STANDARD_PURITY
|
||||
@@ -1186,7 +1188,7 @@
|
||||
|
||||
/datum/reagent/toxin/acid/nitracid
|
||||
name = "Nitric Acid"
|
||||
description = "Nitric acid is an extremely corrosive chemical substance that violently reacts with living organic tissue."
|
||||
description = "An extremely corrosive chemical substance that violently reacts with living organic tissue."
|
||||
color = "#5050FF"
|
||||
creation_purity = REAGENT_STANDARD_PURITY
|
||||
purity = REAGENT_STANDARD_PURITY
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
rate_up_lim = 12.5
|
||||
purity_min = 0.5 //100u will natrually just dip under this w/ no buffer
|
||||
reaction_flags = REACTION_HEAT_ARBITARY //Heating up is arbitary because of submechanics of this reaction.
|
||||
reaction_tags = REACTION_TAG_MODERATE | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DRUG | REACTION_TAG_DANGEROUS
|
||||
reaction_tags = REACTION_TAG_MODERATE | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DRUG | REACTION_TAG_DANGEROUS | REACTION_TAG_ORGAN
|
||||
|
||||
//The less pure it is, the faster it heats up. tg please don't hate me for making your meth even more dangerous
|
||||
/datum/chemical_reaction/methamphetamine/reaction_step(datum/reagents/holder, datum/equilibrium/reaction, delta_t, delta_ph, step_reaction_vol)
|
||||
@@ -160,7 +160,7 @@
|
||||
required_reagents = list(/datum/reagent/kronkus_extract = 15, /datum/reagent/fuel = 5, /datum/reagent/ammonia = 3)
|
||||
mob_react = FALSE
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRUG | REACTION_TAG_ORGAN | REACTION_TAG_DAMAGING
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRUG | REACTION_TAG_ORGAN | REACTION_TAG_DAMAGING | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/moon_rock/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
@@ -176,7 +176,7 @@
|
||||
required_reagents = list(/datum/reagent/silver = 10, /datum/reagent/toxin/cyanide = 10, /datum/reagent/lye = 5)
|
||||
mob_react = FALSE
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRUG | REACTION_TAG_ORGAN | REACTION_TAG_DAMAGING
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRUG | REACTION_TAG_ORGAN | REACTION_TAG_DAMAGING | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/blastoff_ampoule/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
@@ -189,7 +189,7 @@
|
||||
required_reagents = list(/datum/reagent/lead = 5, /datum/reagent/consumable/nothing = 5, /datum/reagent/drug/maint/tar = 10)
|
||||
mob_react = FALSE
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRUG | REACTION_TAG_ORGAN | REACTION_TAG_DAMAGING
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRUG | REACTION_TAG_ORGAN | REACTION_TAG_DAMAGING | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/saturnx_glob/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
results = list(/datum/reagent/medicine/albuterol = 4, /datum/reagent/medicine/sal_acid = 0.5, /datum/reagent/ammonia = 0.5)
|
||||
required_catalysts = list(/datum/reagent/toxin/acid = 1)
|
||||
required_reagents = list(/datum/reagent/medicine/salbutamol = 5, /datum/reagent/medicine/c2/convermol = 1)
|
||||
reaction_tags = REACTION_TAG_MODERATE | REACTION_TAG_ORGAN | REACTION_TAG_OTHER
|
||||
reaction_tags = REACTION_TAG_MODERATE | REACTION_TAG_ORGAN | REACTION_TAG_OTHER | REACTION_TAG_ACTIVE
|
||||
required_temp = 500
|
||||
optimal_temp = 610
|
||||
overheat_temp = 980
|
||||
@@ -181,7 +181,7 @@
|
||||
results = list(/datum/reagent/medicine/salbutamol = 2, /datum/reagent/ammonia = 1)
|
||||
required_catalysts = list(/datum/reagent/toxin/acid = 1)
|
||||
required_reagents = list(/datum/reagent/medicine/albuterol = 3, /datum/reagent/oxygen = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_ORGAN | REACTION_TAG_OTHER
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_ORGAN | REACTION_TAG_OTHER | REACTION_TAG_ACTIVE
|
||||
required_temp = 300
|
||||
optimal_temp = 500
|
||||
overheat_temp = 800
|
||||
@@ -191,7 +191,7 @@
|
||||
results = list(/datum/reagent/inverse/healing/convermol = 1, /datum/reagent/lithium = 3, /datum/reagent/aluminium = 3, /datum/reagent/bromine = 3)
|
||||
required_catalysts = list(/datum/reagent/toxin/acid/fluacid = 1)
|
||||
required_reagents = list(/datum/reagent/medicine/albuterol = 5)
|
||||
reaction_tags = REACTION_TAG_MODERATE | REACTION_TAG_ORGAN | REACTION_TAG_OTHER
|
||||
reaction_tags = REACTION_TAG_MODERATE | REACTION_TAG_ORGAN | REACTION_TAG_OTHER | REACTION_TAG_ACTIVE
|
||||
required_temp = 900
|
||||
optimal_temp = 920
|
||||
overheat_temp = 990
|
||||
@@ -401,7 +401,7 @@
|
||||
/datum/chemical_reaction/medicine/medsuture
|
||||
required_reagents = list(/datum/reagent/cellulose = 2, /datum/reagent/toxin/formaldehyde = 4, /datum/reagent/medicine/polypyr = 3) //This might be a bit much, reagent cost should be reviewed after implementation.
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_BRUTE
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_BRUTE | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/medicine/medsuture/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
new /obj/item/stack/medical/suture/medicated(get_turf(holder.my_atom), round(created_volume * 4))
|
||||
@@ -409,7 +409,7 @@
|
||||
/datum/chemical_reaction/medicine/medmesh
|
||||
required_reagents = list(/datum/reagent/cellulose = 2, /datum/reagent/consumable/aloejuice = 4, /datum/reagent/space_cleaner/sterilizine = 2)
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_BURN
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_BURN | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/medicine/medmesh/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
new /obj/item/stack/medical/mesh/advanced(get_turf(holder.my_atom), round(created_volume * 3))
|
||||
@@ -417,7 +417,7 @@
|
||||
/datum/chemical_reaction/medicine/poultice
|
||||
required_reagents = list(/datum/reagent/toxin/bungotoxin = 4, /datum/reagent/cellulose = 4, /datum/reagent/consumable/aloejuice = 4 )
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_BRUTE | REACTION_TAG_BURN
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_BRUTE | REACTION_TAG_BURN | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/medicine/poultice/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
new /obj/item/stack/medical/poultice(get_turf(holder.my_atom), round(created_volume * 3))
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
/datum/chemical_reaction/sodiumchloride
|
||||
results = list(/datum/reagent/consumable/salt = 2)
|
||||
required_reagents = list(/datum/reagent/sodium = 1, /datum/reagent/chlorine = 1) // That's what I said! Sodium Chloride!
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_FOOD
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_FOOD | REACTION_TAG_COMPONENT
|
||||
required_other = TRUE
|
||||
|
||||
/datum/chemical_reaction/sodiumchloride/pre_reaction_other_checks(datum/reagents/holder)
|
||||
@@ -233,6 +233,7 @@
|
||||
var/level_min = 1
|
||||
var/level_max = 2
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_tags = REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/mix_virus/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list
|
||||
@@ -386,18 +387,18 @@
|
||||
optimal_ph_min = 1 // Lets increase our range for this basic chem
|
||||
optimal_ph_max = 12
|
||||
H_ion_release = -0.02 //handmade is more neutral
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_PLANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_PLANT | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/diethylamine
|
||||
results = list(/datum/reagent/diethylamine = 2)
|
||||
required_reagents = list (/datum/reagent/ammonia = 1, /datum/reagent/consumable/ethanol = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_PLANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_PLANT | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/space_cleaner
|
||||
results = list(/datum/reagent/space_cleaner = 2)
|
||||
required_reagents = list(/datum/reagent/ammonia = 1, /datum/reagent/water = 1)
|
||||
rate_up_lim = 40
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/plantbgone
|
||||
results = list(/datum/reagent/toxin/plantbgone = 5)
|
||||
@@ -418,14 +419,14 @@
|
||||
/datum/chemical_reaction/drying_agent
|
||||
results = list(/datum/reagent/drying_agent = 3)
|
||||
required_reagents = list(/datum/reagent/stable_plasma = 2, /datum/reagent/consumable/ethanol = 1, /datum/reagent/sodium = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_COMPONENT
|
||||
|
||||
//////////////////////////////////// Other goon stuff ///////////////////////////////////////////
|
||||
|
||||
/datum/chemical_reaction/acetone
|
||||
results = list(/datum/reagent/acetone = 3)
|
||||
required_reagents = list(/datum/reagent/fuel/oil = 1, /datum/reagent/fuel = 1, /datum/reagent/oxygen = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/carpet
|
||||
results = list(/datum/reagent/carpet = 2)
|
||||
@@ -526,18 +527,18 @@
|
||||
/datum/chemical_reaction/oil
|
||||
results = list(/datum/reagent/fuel/oil = 3)
|
||||
required_reagents = list(/datum/reagent/fuel = 1, /datum/reagent/carbon = 1, /datum/reagent/hydrogen = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/phenol
|
||||
results = list(/datum/reagent/phenol = 3)
|
||||
required_reagents = list(/datum/reagent/water = 1, /datum/reagent/chlorine = 1, /datum/reagent/fuel/oil = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/ash
|
||||
results = list(/datum/reagent/ash = 1)
|
||||
required_reagents = list(/datum/reagent/fuel/oil = 1)
|
||||
required_temp = 480
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_PLANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_PLANT | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/colorful_reagent
|
||||
results = list(/datum/reagent/colorful_reagent = 5)
|
||||
@@ -643,19 +644,19 @@
|
||||
/datum/chemical_reaction/electrolysis
|
||||
results = list(/datum/reagent/oxygen = 2.5, /datum/reagent/hydrogen = 5)
|
||||
required_reagents = list(/datum/reagent/consumable/liquidelectricity = 1, /datum/reagent/water = 5)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE
|
||||
|
||||
/datum/chemical_reaction/electrolysis2
|
||||
results = list(/datum/reagent/oxygen = 2.5, /datum/reagent/hydrogen = 5)
|
||||
required_reagents = list(/datum/reagent/consumable/liquidelectricity/enriched = 1, /datum/reagent/water = 5)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE
|
||||
|
||||
//salt electrolysis
|
||||
/datum/chemical_reaction/saltelectrolysis
|
||||
results = list(/datum/reagent/chlorine = 2.5, /datum/reagent/sodium = 2.5)
|
||||
required_reagents = list(/datum/reagent/consumable/salt = 5)
|
||||
required_catalysts = list(/datum/reagent/consumable/liquidelectricity = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE
|
||||
|
||||
/datum/chemical_reaction/saltelectrolysis/enriched
|
||||
required_catalysts = list(/datum/reagent/consumable/liquidelectricity/enriched = 1)
|
||||
@@ -722,18 +723,18 @@
|
||||
/datum/chemical_reaction/saltpetre
|
||||
results = list(/datum/reagent/saltpetre = 3)
|
||||
required_reagents = list(/datum/reagent/potassium = 1, /datum/reagent/nitrogen = 1, /datum/reagent/oxygen = 3)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_PLANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_PLANT | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/lye
|
||||
results = list(/datum/reagent/lye = 3)
|
||||
required_reagents = list(/datum/reagent/sodium = 1, /datum/reagent/hydrogen = 1, /datum/reagent/oxygen = 1)
|
||||
required_temp = 10 //So hercuri still shows life.
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/lye2
|
||||
results = list(/datum/reagent/lye = 2)
|
||||
required_reagents = list(/datum/reagent/ash = 1, /datum/reagent/water = 1, /datum/reagent/carbon = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/royal_bee_jelly
|
||||
results = list(/datum/reagent/royal_bee_jelly = 5)
|
||||
@@ -901,7 +902,7 @@
|
||||
purity_min = 0
|
||||
mix_message = "The solution freezes up into ice!"
|
||||
reaction_flags = REACTION_COMPETITIVE
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_DRINK
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL | REACTION_TAG_DRINK | REACTION_TAG_COMPONENT | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/water
|
||||
results = list(/datum/reagent/water = 0.92)//rough density excahnge
|
||||
@@ -1092,5 +1093,3 @@
|
||||
|
||||
glitter.data["colors"] = list("[accumulated_color]" = 100)
|
||||
glitter.color = accumulated_color
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/strengthdiv = 10
|
||||
var/modifier = 0
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_tags = REACTION_TAG_EXPLOSIVE | REACTION_TAG_MODERATE | REACTION_TAG_DANGEROUS
|
||||
reaction_tags = REACTION_TAG_EXPLOSIVE | REACTION_TAG_MODERATE | REACTION_TAG_DANGEROUS | REACTION_TAG_ACTIVE
|
||||
required_temp = 0 //Prevent impromptu RPGs
|
||||
// Only clear mob reagents in special cases
|
||||
var/clear_mob_reagents = FALSE
|
||||
@@ -189,7 +189,7 @@
|
||||
/datum/chemical_reaction/gunpowder
|
||||
results = list(/datum/reagent/gunpowder = 3)
|
||||
required_reagents = list(/datum/reagent/saltpetre = 1, /datum/reagent/medicine/c2/multiver = 1, /datum/reagent/sulfur = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_CHEMICAL
|
||||
|
||||
/datum/chemical_reaction/reagent_explosion/gunpowder_explosion
|
||||
required_reagents = list(/datum/reagent/gunpowder = 1)
|
||||
@@ -208,7 +208,7 @@
|
||||
|
||||
/datum/chemical_reaction/emp_pulse
|
||||
required_reagents = list(/datum/reagent/uranium = 1, /datum/reagent/iron = 1, /datum/reagent/aluminium = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/emp_pulse/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
//pretending this reaction took two ingredients and not three for its effects
|
||||
@@ -228,7 +228,7 @@
|
||||
|
||||
/datum/chemical_reaction/beesplosion
|
||||
required_reagents = list(/datum/reagent/consumable/honey = 1, /datum/reagent/medicine/strange_reagent = 1, /datum/reagent/uranium/radium = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/beesplosion/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/location = holder.my_atom.drop_location()
|
||||
@@ -251,7 +251,7 @@
|
||||
/datum/chemical_reaction/stabilizing_agent
|
||||
results = list(/datum/reagent/stabilizing_agent = 3)
|
||||
required_reagents = list(/datum/reagent/iron = 1, /datum/reagent/oxygen = 1, /datum/reagent/hydrogen = 1)
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_CHEMICAL | REACTION_TAG_PLANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_CHEMICAL | REACTION_TAG_PLANT | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/clf3
|
||||
results = list(/datum/reagent/clf3 = 4)
|
||||
@@ -300,7 +300,7 @@
|
||||
/datum/chemical_reaction/sorium_vortex
|
||||
required_reagents = list(/datum/reagent/sorium = 1)
|
||||
required_temp = 474
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/turf/T = get_turf(holder.my_atom)
|
||||
@@ -323,7 +323,7 @@
|
||||
/datum/chemical_reaction/ldm_vortex
|
||||
required_reagents = list(/datum/reagent/liquid_dark_matter = 1)
|
||||
required_temp = 474
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/turf/T = get_turf(holder.my_atom)
|
||||
@@ -356,7 +356,7 @@
|
||||
/datum/chemical_reaction/flash_powder_flash
|
||||
required_reagents = list(/datum/reagent/flash_powder = 1)
|
||||
required_temp = 374
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/flash_powder_flash/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
@@ -397,7 +397,7 @@
|
||||
required_temp = 374
|
||||
mob_react = FALSE
|
||||
reaction_flags = REACTION_INSTANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/smoke_powder_smoke/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
@@ -427,7 +427,7 @@
|
||||
/datum/chemical_reaction/sonic_powder_deafen
|
||||
required_reagents = list(/datum/reagent/sonic_powder = 1)
|
||||
required_temp = 374
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/sonic_powder_deafen/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
rate_up_lim = 10
|
||||
purity_min = 0.7
|
||||
reaction_flags = REACTION_PH_VOL_CONSTANT
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DAMAGING | REACTION_TAG_PLANT | REACTION_TAG_OTHER
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DAMAGING | REACTION_TAG_PLANT | REACTION_TAG_OTHER | REACTION_TAG_COMPONENT
|
||||
|
||||
/datum/chemical_reaction/lexorin
|
||||
results = list(/datum/reagent/toxin/lexorin = 3)
|
||||
@@ -204,7 +204,7 @@
|
||||
required_reagents = list(/datum/reagent/toxin/hot_ice = 1)
|
||||
required_temp = T0C + 30 //Don't burst into flames when you melt
|
||||
thermic_constant = -200//Counter the heat
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DAMAGING | REACTION_TAG_CHEMICAL | REACTION_TAG_TOXIN
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DAMAGING | REACTION_TAG_CHEMICAL | REACTION_TAG_TOXIN | REACTION_TAG_ACTIVE
|
||||
|
||||
/datum/chemical_reaction/chloralhydrate
|
||||
results = list(/datum/reagent/toxin/chloralhydrate = 1)
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
BlockQuote,
|
||||
Box,
|
||||
Button,
|
||||
Collapsible,
|
||||
Icon,
|
||||
Input,
|
||||
LabeledList,
|
||||
NoticeBox,
|
||||
ProgressBar,
|
||||
Section,
|
||||
Stack,
|
||||
Tooltip,
|
||||
} from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
import { toTitleCase } from 'tgui-core/string';
|
||||
import { createSearch, toTitleCase } from 'tgui-core/string';
|
||||
|
||||
import { useBackend } from '../backend';
|
||||
import { useBackend, useSharedState } from '../backend';
|
||||
import { Window } from '../layouts';
|
||||
import { type Beaker, BeakerDisplay } from './common/BeakerDisplay';
|
||||
import { bitflagInfo } from './Reagents/types';
|
||||
|
||||
type DispensableReagent = {
|
||||
title: string;
|
||||
@@ -26,6 +32,33 @@ type TransferableBeaker = Beaker & {
|
||||
transferAmounts: number[];
|
||||
};
|
||||
|
||||
type ReactionTypepath = string;
|
||||
type ReagentTypepath = string;
|
||||
|
||||
type ReactionComponent = {
|
||||
name: string;
|
||||
amount: number;
|
||||
id: ReagentTypepath;
|
||||
};
|
||||
|
||||
type Reaction = {
|
||||
id: ReactionTypepath;
|
||||
bitflags: number;
|
||||
lower_temperature: number;
|
||||
upper_temperature: number;
|
||||
lower_ph: number;
|
||||
upper_ph: number;
|
||||
required_reagents: ReactionComponent[];
|
||||
required_catalysts: ReactionComponent[];
|
||||
description: string;
|
||||
color: string; // hex
|
||||
};
|
||||
|
||||
type ReagentReaction = {
|
||||
name: string;
|
||||
reaction: Reaction;
|
||||
};
|
||||
|
||||
type Data = {
|
||||
showpH: BooleanLike;
|
||||
amount: number;
|
||||
@@ -39,13 +72,45 @@ type Data = {
|
||||
recipeReagents: string[];
|
||||
beaker: TransferableBeaker;
|
||||
hasBeakerInHand: BooleanLike;
|
||||
// static
|
||||
reaction_list: Record<string, Reaction>;
|
||||
all_bitflags: Record<string, number>;
|
||||
};
|
||||
|
||||
function reagentListToArray(
|
||||
reagentList: Record<string, Reaction>,
|
||||
): ReagentReaction[] {
|
||||
return Object.entries(reagentList).map(([name, reaction]) => ({
|
||||
name: name,
|
||||
reaction: reaction,
|
||||
}));
|
||||
}
|
||||
|
||||
export const ChemDispenser = (props) => {
|
||||
const { act, data } = useBackend<Data>();
|
||||
const recording = !!data.recordingRecipe;
|
||||
const { recipeReagents = [], recipes = [], beaker, hasBeakerInHand } = data;
|
||||
const [showPhCol, setShowPhCol] = useState(false);
|
||||
const {
|
||||
recipes = [],
|
||||
beaker,
|
||||
hasBeakerInHand,
|
||||
reaction_list,
|
||||
all_bitflags,
|
||||
chemicals,
|
||||
} = data;
|
||||
const [showPhCol, setShowPhCol] = useSharedState('showbaseph', false);
|
||||
const [showReactionList, setShowReactionList] = useSharedState(
|
||||
'showreactions',
|
||||
false,
|
||||
);
|
||||
const [searchTerm, setSearchTerm] = useSharedState('searchterm', '');
|
||||
const [filterByBitflag, setFilterByBitflag] = useSharedState<number>(
|
||||
'filterbitflag',
|
||||
0,
|
||||
);
|
||||
const [pinnedReactions, setPinnedReactions] = useSharedState<string[]>(
|
||||
'pinnedreactions',
|
||||
[],
|
||||
);
|
||||
|
||||
const beakerTransferAmounts = beaker ? beaker.transferAmounts : [];
|
||||
const recordedContents =
|
||||
@@ -56,213 +121,645 @@ export const ChemDispenser = (props) => {
|
||||
volume: data.recordingRecipe[id],
|
||||
}));
|
||||
|
||||
// convert reagent list record to list of ReagentReaction
|
||||
const reactionReagentList = reagentListToArray(reaction_list);
|
||||
|
||||
const reactionSearch = createSearch(
|
||||
searchTerm,
|
||||
(reaction: ReagentReaction) => reaction.name,
|
||||
);
|
||||
|
||||
// filter the reaction list first by whitelist bitflags, then by search term
|
||||
const filteredReactions = reactionReagentList
|
||||
.filter((reaction) => {
|
||||
// filter by whitelist bitflags
|
||||
if (
|
||||
filterByBitflag !== 0 &&
|
||||
(reaction.reaction.bitflags & filterByBitflag) !== filterByBitflag
|
||||
)
|
||||
return false;
|
||||
// filter base reagents
|
||||
if (chemicals.find((chem) => chem.title === reaction.name)) return false;
|
||||
// filter by search term
|
||||
return reactionSearch(reaction);
|
||||
})
|
||||
.sort((a, b) => (a.name > b.name ? 1 : -1))
|
||||
.sort((a, b) => {
|
||||
// pinned reactions go first
|
||||
const aPinned = pinnedReactions.includes(a.name);
|
||||
const bPinned = pinnedReactions.includes(b.name);
|
||||
if (aPinned && !bPinned) return -1;
|
||||
if (!aPinned && bPinned) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
const mainWidth = 565;
|
||||
const reactionWidth = 245;
|
||||
const windowWidth = mainWidth + (showReactionList ? reactionWidth : 0);
|
||||
|
||||
return (
|
||||
<Window width={565} height={620}>
|
||||
<Window width={windowWidth} height={620}>
|
||||
<Window.Content scrollable>
|
||||
<Section
|
||||
title="Status"
|
||||
buttons={
|
||||
<>
|
||||
{recording && (
|
||||
<Box inline mx={1} color="red">
|
||||
<Icon name="circle" mr={1} />
|
||||
Recording
|
||||
</Box>
|
||||
)}
|
||||
<Button
|
||||
icon="book"
|
||||
disabled={!beaker}
|
||||
tooltip={
|
||||
beaker
|
||||
? 'Look up recipes and reagents!'
|
||||
: 'Please insert a beaker!'
|
||||
}
|
||||
tooltipPosition="bottom-start"
|
||||
onClick={() => act('reaction_lookup')}
|
||||
>
|
||||
Reaction search
|
||||
</Button>
|
||||
<Button
|
||||
icon="cog"
|
||||
tooltip="Color code the reagents by pH"
|
||||
tooltipPosition="bottom-start"
|
||||
selected={showPhCol}
|
||||
onClick={() => setShowPhCol(!showPhCol)}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Energy">
|
||||
<ProgressBar value={data.energy / data.maxEnergy}>
|
||||
{data.displayedUnits +
|
||||
' / ' +
|
||||
data.displayedMaxUnits +
|
||||
' units'}
|
||||
</ProgressBar>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
<Section
|
||||
title="Recipes"
|
||||
buttons={
|
||||
<>
|
||||
{!recording && (
|
||||
<Box inline mx={1}>
|
||||
<Button
|
||||
color="transparent"
|
||||
onClick={() => act('clear_recipes')}
|
||||
>
|
||||
Clear recipes
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
{!recording && (
|
||||
<Button
|
||||
icon="circle"
|
||||
disabled={!beaker}
|
||||
onClick={() => act('record_recipe')}
|
||||
<Stack fill>
|
||||
<Stack.Item width={mainWidth} gr>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Section
|
||||
title="Status"
|
||||
buttons={
|
||||
<>
|
||||
{recording && (
|
||||
<Box inline mx={1} color="red">
|
||||
<Icon name="circle" mr={1} />
|
||||
Recording
|
||||
</Box>
|
||||
)}
|
||||
<Button
|
||||
icon="cog"
|
||||
tooltip="Color code the reagents by pH"
|
||||
tooltipPosition="bottom-start"
|
||||
selected={showPhCol}
|
||||
onClick={() => setShowPhCol(!showPhCol)}
|
||||
/>
|
||||
<Button
|
||||
icon="book"
|
||||
disabled={!beaker}
|
||||
tooltip={
|
||||
beaker
|
||||
? 'Look up recipes and reagents!'
|
||||
: 'Please insert a beaker!'
|
||||
}
|
||||
tooltipPosition="bottom-start"
|
||||
onClick={() => act('reaction_lookup')}
|
||||
>
|
||||
Reactions
|
||||
</Button>
|
||||
<Button
|
||||
icon={showReactionList ? 'arrow-left' : 'arrow-right'}
|
||||
tooltipPosition="bottom-start"
|
||||
onClick={() => setShowReactionList(!showReactionList)}
|
||||
>
|
||||
Recipes
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
Record
|
||||
</Button>
|
||||
)}
|
||||
{recording && (
|
||||
<Button
|
||||
icon="ban"
|
||||
color="transparent"
|
||||
onClick={() => act('cancel_recording')}
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Energy">
|
||||
<ProgressBar value={data.energy / data.maxEnergy}>
|
||||
{data.displayedUnits +
|
||||
' / ' +
|
||||
data.displayedMaxUnits +
|
||||
' units'}
|
||||
</ProgressBar>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Section
|
||||
title="Custom Recipes"
|
||||
buttons={
|
||||
<>
|
||||
{!recording && (
|
||||
<Box inline mx={1}>
|
||||
<Button
|
||||
color="transparent"
|
||||
onClick={() => act('clear_recipes')}
|
||||
>
|
||||
Clear recipes
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
{!recording && (
|
||||
<Button
|
||||
icon="circle"
|
||||
disabled={!beaker}
|
||||
onClick={() => act('record_recipe')}
|
||||
>
|
||||
Record
|
||||
</Button>
|
||||
)}
|
||||
{recording && (
|
||||
<Button
|
||||
icon="ban"
|
||||
color="transparent"
|
||||
onClick={() => act('cancel_recording')}
|
||||
>
|
||||
Discard
|
||||
</Button>
|
||||
)}
|
||||
{recording && (
|
||||
<Button
|
||||
icon="save"
|
||||
color="green"
|
||||
onClick={() => act('save_recording')}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
>
|
||||
Discard
|
||||
</Button>
|
||||
)}
|
||||
{recording && (
|
||||
<Button
|
||||
icon="save"
|
||||
color="green"
|
||||
onClick={() => act('save_recording')}
|
||||
<Box mr={-1}>
|
||||
{Object.keys(recipes).map((recipe) => (
|
||||
<Button
|
||||
key={recipe}
|
||||
icon="tint"
|
||||
width="129.5px"
|
||||
lineHeight={1.75}
|
||||
onClick={() =>
|
||||
act('dispense_recipe', {
|
||||
recipe: recipe,
|
||||
})
|
||||
}
|
||||
>
|
||||
{recipe}
|
||||
</Button>
|
||||
))}
|
||||
{recipes.length === 0 && (
|
||||
<Box color="light-gray">No recipes.</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Section
|
||||
title="Dispense"
|
||||
buttons={beakerTransferAmounts.map((amount) => (
|
||||
<Button
|
||||
key={amount}
|
||||
icon="plus"
|
||||
selected={amount === data.amount}
|
||||
onClick={() =>
|
||||
act('amount', {
|
||||
target: amount,
|
||||
})
|
||||
}
|
||||
>
|
||||
{amount}
|
||||
</Button>
|
||||
))}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Box mr={-1}>
|
||||
{Object.keys(recipes).map((recipe) => (
|
||||
<Button
|
||||
key={recipe}
|
||||
icon="tint"
|
||||
width="129.5px"
|
||||
lineHeight={1.75}
|
||||
onClick={() =>
|
||||
act('dispense_recipe', {
|
||||
recipe: recipe,
|
||||
})
|
||||
}
|
||||
>
|
||||
{recipe}
|
||||
</Button>
|
||||
))}
|
||||
{recipes.length === 0 && <Box color="light-gray">No recipes.</Box>}
|
||||
</Box>
|
||||
</Section>
|
||||
<Section
|
||||
title="Dispense"
|
||||
buttons={beakerTransferAmounts.map((amount) => (
|
||||
<Button
|
||||
key={amount}
|
||||
icon="plus"
|
||||
selected={amount === data.amount}
|
||||
onClick={() =>
|
||||
act('amount', {
|
||||
target: amount,
|
||||
})
|
||||
}
|
||||
>
|
||||
{amount}
|
||||
</Button>
|
||||
))}
|
||||
>
|
||||
<Box mr={-1}>
|
||||
{data.chemicals.map((chemical) => (
|
||||
<Button
|
||||
key={chemical.id}
|
||||
icon="tint"
|
||||
textColor={showPhCol ? chemical.pHCol : chemical.color}
|
||||
width="129.5px"
|
||||
lineHeight={1.75}
|
||||
tooltip={`pH: ${chemical.pH}`}
|
||||
style={{
|
||||
textShadow: '1px 1px 0 black',
|
||||
}}
|
||||
backgroundColor={
|
||||
recipeReagents.includes(chemical.id) ? 'green' : 'default'
|
||||
}
|
||||
onClick={() =>
|
||||
act('dispense', {
|
||||
reagent: chemical.id,
|
||||
})
|
||||
}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
color: 'white',
|
||||
textShadow: 'none',
|
||||
}}
|
||||
<Stack wrap>
|
||||
{data.chemicals.map((chemical) => (
|
||||
<Stack.Item width="24.5%" key={chemical.id} mr={-0.5}>
|
||||
<ReagentDispenseButton
|
||||
chemical={chemical}
|
||||
showPhCol={showPhCol}
|
||||
mainscreen={true}
|
||||
/>
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<Section
|
||||
fill
|
||||
title="Beaker"
|
||||
buttons={beakerTransferAmounts.map((amount) => (
|
||||
<Button
|
||||
key={amount}
|
||||
icon="minus"
|
||||
disabled={recording}
|
||||
onClick={() => act('remove', { amount })}
|
||||
>
|
||||
{amount}
|
||||
</Button>
|
||||
))}
|
||||
>
|
||||
{chemical.title}
|
||||
</span>
|
||||
</Button>
|
||||
))}
|
||||
</Box>
|
||||
</Section>
|
||||
<Section
|
||||
title="Beaker"
|
||||
buttons={beakerTransferAmounts.map((amount) => (
|
||||
<Button
|
||||
key={amount}
|
||||
icon="minus"
|
||||
disabled={recording}
|
||||
onClick={() => act('remove', { amount })}
|
||||
>
|
||||
{amount}
|
||||
</Button>
|
||||
))}
|
||||
>
|
||||
{beaker || recording ? (
|
||||
<BeakerDisplay
|
||||
beaker={beaker}
|
||||
title_label={recording && 'Virtual beaker'}
|
||||
replace_contents={recordedContents}
|
||||
showpH={data.showpH}
|
||||
/>
|
||||
) : (
|
||||
<Box
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Box color="label">No beaker loaded.</Box>
|
||||
<Button
|
||||
icon="eject"
|
||||
onClick={() => act('insert')}
|
||||
style={{
|
||||
opacity: data.hasBeakerInHand ? 1 : 0.5,
|
||||
}}
|
||||
tooltip={
|
||||
!data.hasBeakerInHand &&
|
||||
'You need to hold a container in your hand'
|
||||
}
|
||||
tooltipPosition="left-start"
|
||||
>
|
||||
Insert
|
||||
</Button>
|
||||
</Box>
|
||||
{beaker || recording ? (
|
||||
<BeakerDisplay
|
||||
beaker={beaker}
|
||||
title_label={recording && 'Virtual beaker'}
|
||||
replace_contents={recordedContents}
|
||||
showpH={data.showpH}
|
||||
/>
|
||||
) : (
|
||||
<Box
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Box color="label">No beaker loaded.</Box>
|
||||
<Button
|
||||
icon="eject"
|
||||
onClick={() => act('insert')}
|
||||
disabled={!hasBeakerInHand}
|
||||
tooltip={
|
||||
!hasBeakerInHand &&
|
||||
'You need to hold a container in your hand!'
|
||||
}
|
||||
tooltipPosition="left-start"
|
||||
>
|
||||
Insert
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
{showReactionList && (
|
||||
<Stack.Item width={reactionWidth}>
|
||||
<Section title="Recipes" fill>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item grow>
|
||||
<Input
|
||||
placeholder="Search reactions..."
|
||||
value={searchTerm}
|
||||
fluid
|
||||
onChange={(value) => setSearchTerm(value)}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="times"
|
||||
disabled={searchTerm === ''}
|
||||
onClick={() => setSearchTerm('')}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="thumbtack"
|
||||
disabled={pinnedReactions.length === 0}
|
||||
onClick={() => setPinnedReactions([])}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Divider />
|
||||
<Stack.Item>
|
||||
<Stack wrap>
|
||||
{Object.entries(all_bitflags).map(([readable, flag]) => (
|
||||
<Stack.Item key={readable} grow>
|
||||
<Button
|
||||
fluid
|
||||
align="center"
|
||||
fontSize="0.9em"
|
||||
onClick={() =>
|
||||
setFilterByBitflag(flag ^ filterByBitflag)
|
||||
}
|
||||
tooltip={
|
||||
<Box fontSize="0.9em">
|
||||
{bitflagInfo.find((bf) => bf.flag === readable)
|
||||
?.tooltip || ''}
|
||||
</Box>
|
||||
}
|
||||
selected={(filterByBitflag & flag) !== 0}
|
||||
>
|
||||
{readable}
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Divider />
|
||||
<Stack.Item grow mt={1}>
|
||||
<Section scrollable fill>
|
||||
<Stack vertical>
|
||||
{filteredReactions.length > 0 ? (
|
||||
filteredReactions.map((reaction) => (
|
||||
<Stack.Item key={reaction.name}>
|
||||
<ReactionDisplay
|
||||
reaction={reaction}
|
||||
pinnedReactions={pinnedReactions}
|
||||
setPinnedReactions={setPinnedReactions}
|
||||
setSearchTerm={setSearchTerm}
|
||||
/>
|
||||
</Stack.Item>
|
||||
))
|
||||
) : (
|
||||
<NoticeBox>No reactions found.</NoticeBox>
|
||||
)}
|
||||
</Stack>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Section>
|
||||
</Stack>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
type ReagentDispenseButtonProps = {
|
||||
chemical: DispensableReagent;
|
||||
showPhCol?: boolean;
|
||||
mainscreen?: boolean;
|
||||
prefix?: string;
|
||||
};
|
||||
|
||||
const ReagentDispenseButton = (props: ReagentDispenseButtonProps) => {
|
||||
const { chemical, showPhCol, mainscreen, prefix } = props;
|
||||
const { act, data } = useBackend<Data>();
|
||||
const { recipeReagents = [] } = data;
|
||||
|
||||
return (
|
||||
<Button
|
||||
key={chemical.id}
|
||||
icon="tint"
|
||||
fluid
|
||||
textColor={showPhCol ? chemical.pHCol : chemical.color}
|
||||
lineHeight={1.75}
|
||||
tooltip={mainscreen ? `pH: ${chemical.pH}` : undefined}
|
||||
style={{
|
||||
textShadow: '1px 1px 0 black',
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
selected={mainscreen && recipeReagents.includes(chemical.id)}
|
||||
onClick={() =>
|
||||
act('dispense', {
|
||||
reagent: chemical.id,
|
||||
})
|
||||
}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
color: 'white',
|
||||
textShadow: 'none',
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
{prefix}
|
||||
{chemical.title}
|
||||
</span>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
type ReactionDisplayProps = {
|
||||
reaction: ReagentReaction;
|
||||
pinnedReactions: ReactionTypepath[];
|
||||
setPinnedReactions: (reactions: ReactionTypepath[]) => void;
|
||||
setSearchTerm: (term: string) => void;
|
||||
};
|
||||
|
||||
const ReactionDisplay = (props: ReactionDisplayProps) => {
|
||||
const { reaction, pinnedReactions, setPinnedReactions } = props;
|
||||
return (
|
||||
<Stack
|
||||
p={1}
|
||||
style={{
|
||||
borderRadius: '4px',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: 'black',
|
||||
}}
|
||||
>
|
||||
<Stack.Item>
|
||||
<Stack align="center">
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="thumbtack"
|
||||
onClick={() => {
|
||||
if (pinnedReactions.includes(reaction.name)) {
|
||||
setPinnedReactions(
|
||||
pinnedReactions.filter((rid) => rid !== reaction.name),
|
||||
);
|
||||
} else {
|
||||
setPinnedReactions([...pinnedReactions, reaction.name]);
|
||||
}
|
||||
}}
|
||||
onContextMenu={() => {
|
||||
setPinnedReactions([reaction.name]);
|
||||
}}
|
||||
selected={pinnedReactions.includes(reaction.name)}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item
|
||||
grow
|
||||
style={{
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
content={
|
||||
<Box fontSize="0.9rem">{reaction.reaction.description}</Box>
|
||||
}
|
||||
position="top"
|
||||
>
|
||||
<Stack fill>
|
||||
<Stack.Item
|
||||
grow
|
||||
style={{
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
{reaction.name}
|
||||
</Stack.Item>
|
||||
<Stack.Item
|
||||
backgroundColor={reaction.reaction.color}
|
||||
p={1.25}
|
||||
style={{ borderRadius: '8px' }}
|
||||
/>
|
||||
</Stack>
|
||||
</Tooltip>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Collapsible
|
||||
title="Recipe"
|
||||
open={pinnedReactions.includes(reaction.name)}
|
||||
>
|
||||
<BlockQuote>
|
||||
<Stack vertical>
|
||||
<Stack.Item>
|
||||
<HorizontalBarWithText text="Formula" />
|
||||
</Stack.Item>
|
||||
{reaction.reaction.required_reagents.map((reagent) => (
|
||||
<Stack.Item key={`${reaction.name}-${reagent.name}-req`}>
|
||||
<ReactionComponentDisplay
|
||||
reagentComponent={reagent}
|
||||
setSearchTerm={props.setSearchTerm}
|
||||
pinnedReactions={pinnedReactions}
|
||||
setPinnedReactions={props.setPinnedReactions}
|
||||
/>
|
||||
</Stack.Item>
|
||||
))}
|
||||
{reaction.reaction.required_catalysts.length > 0 && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<HorizontalBarWithText
|
||||
text={`Catalyst${reaction.reaction.required_reagents.length === 1 ? '' : 's'}`}
|
||||
/>
|
||||
</Stack.Item>
|
||||
{reaction.reaction.required_catalysts.map((catalyst) => (
|
||||
<Stack.Item key={`${reaction.name}-${catalyst.name}-cat`}>
|
||||
<ReactionComponentDisplay
|
||||
reagentComponent={catalyst}
|
||||
setSearchTerm={props.setSearchTerm}
|
||||
pinnedReactions={pinnedReactions}
|
||||
setPinnedReactions={props.setPinnedReactions}
|
||||
/>
|
||||
</Stack.Item>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
<Stack.Item>
|
||||
<HorizontalBarWithText text="Optimal temperature" />
|
||||
</Stack.Item>
|
||||
<Stack.Item fontSize="0.9em">
|
||||
{getTemperatureMessage(
|
||||
reaction.reaction.lower_temperature,
|
||||
reaction.reaction.upper_temperature,
|
||||
)}
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<HorizontalBarWithText text="Optimal pH range" />
|
||||
</Stack.Item>
|
||||
<Stack.Item fontSize="0.9em">
|
||||
{getPHMessage(
|
||||
reaction.reaction.lower_ph,
|
||||
reaction.reaction.upper_ph,
|
||||
)}
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</BlockQuote>
|
||||
</Collapsible>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
// if lower and upper are the same, return "at X degrees"
|
||||
// if lower and upper are >300, return "heat to between X and Y degrees"
|
||||
// if lower and upper are <300, return "cool to between X and Y degrees"
|
||||
// if lower is <300 and upper is >300, return "keep between X and Y degrees"
|
||||
function getTemperatureMessage(lower: number, upper: number): string {
|
||||
if (lower === upper) {
|
||||
return `Forms at ${lower}°K`;
|
||||
} else if (lower > 300 && upper > 300) {
|
||||
return `Heat between ${lower}°K-${upper}°K`;
|
||||
} else if (lower < 300 && upper < 300) {
|
||||
return `Cool between ${Math.min(upper, lower)}°K-${Math.max(upper, lower)}°K`;
|
||||
} else {
|
||||
return `Keep between ${lower}°K-${upper}°K`;
|
||||
}
|
||||
}
|
||||
|
||||
// if lower and upper are the same, return "keep at pH X"
|
||||
// else return "keep between pH X and Y"
|
||||
function getPHMessage(lower: number, upper: number): string {
|
||||
if (lower === upper) {
|
||||
return `Keep at pH ${lower}`;
|
||||
} else {
|
||||
return `Keep between pH ${lower}-${upper}`;
|
||||
}
|
||||
}
|
||||
|
||||
type ReactionComponentDisplayProps = {
|
||||
reagentComponent: ReactionComponent;
|
||||
setSearchTerm: (term: string) => void;
|
||||
pinnedReactions: ReactionTypepath[];
|
||||
setPinnedReactions: (reactions: ReactionTypepath[]) => void;
|
||||
};
|
||||
|
||||
// linkifies a reagent name in the reaction display
|
||||
// if it's a base reagent, it will dispense it when clicked
|
||||
// if it's another recipe, it will put that recipe in the search box
|
||||
// if it's nothing, it's not a button
|
||||
const ReactionComponentDisplay = (props: ReactionComponentDisplayProps) => {
|
||||
const {
|
||||
reagentComponent,
|
||||
setSearchTerm,
|
||||
pinnedReactions,
|
||||
setPinnedReactions,
|
||||
} = props;
|
||||
const { data } = useBackend<Data>();
|
||||
const { chemicals, reaction_list } = data;
|
||||
|
||||
// check if it's a base reagent
|
||||
const baseReagent = chemicals.find(
|
||||
(chem) => chem.title === reagentComponent.name,
|
||||
);
|
||||
|
||||
if (baseReagent) {
|
||||
return (
|
||||
<ReagentDispenseButton
|
||||
chemical={baseReagent}
|
||||
prefix={formatReagentName(reagentComponent.amount)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const reactionReagentList = reagentListToArray(reaction_list);
|
||||
|
||||
// check if it's a recipe
|
||||
const isRecipe = reactionReagentList
|
||||
.filter((reaction) => {
|
||||
return reaction.name === reagentComponent.name;
|
||||
})
|
||||
.find((reaction) => reaction.name === reagentComponent.name);
|
||||
|
||||
if (isRecipe) {
|
||||
return (
|
||||
<Button
|
||||
icon="book"
|
||||
fluid
|
||||
ellipsis
|
||||
backgroundColor="default"
|
||||
onContextMenu={() => {
|
||||
// put recipe name in search box
|
||||
setSearchTerm(reagentComponent.name);
|
||||
}}
|
||||
onClick={() => {
|
||||
// pin recipe
|
||||
setPinnedReactions([...pinnedReactions, isRecipe.name]);
|
||||
}}
|
||||
selected={pinnedReactions.includes(isRecipe.name)}
|
||||
tooltip={
|
||||
<Stack vertical>
|
||||
<Stack.Item fontSize="0.9em">
|
||||
Left click to pin this recipe.
|
||||
</Stack.Item>
|
||||
<Stack.Item fontSize="0.9em">
|
||||
Right click to search for this recipe.
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
{formatReagentName(reagentComponent.amount, reagentComponent.name)}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
// otherwise, just display the name
|
||||
return (
|
||||
<Button fluid ellipsis disabled icon="question">
|
||||
{formatReagentName(reagentComponent.amount, reagentComponent.name)}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
function formatReagentName(amount: number, name?: string) {
|
||||
if (!name) return `${amount} part `;
|
||||
|
||||
return `${amount} part${amount === 1 ? '' : 's'} ${name}`;
|
||||
}
|
||||
|
||||
const HorizontalBarWithText = (props: { text: string }) => {
|
||||
const { text } = props;
|
||||
return (
|
||||
<Stack>
|
||||
<Stack.Item grow>
|
||||
<hr />
|
||||
</Stack.Item>
|
||||
<Stack.Item fontSize="0.95em">{text}</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<hr />
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,12 +9,23 @@ import {
|
||||
|
||||
import { useBackend } from '../../backend';
|
||||
import { bookmarkedReactions } from '.';
|
||||
import type { ReagentsData, ReagentsProps } from './types';
|
||||
import { bitflagInfo, type ReagentsData, type ReagentsProps } from './types';
|
||||
|
||||
function matchBitflag(a: number, b: number) {
|
||||
return a & b && (a | b) === b;
|
||||
}
|
||||
|
||||
function bitflagToIcon(flag: number, all_flags: Record<string, number>) {
|
||||
for (const [readable, value] of Object.entries(all_flags)) {
|
||||
for (const meta of bitflagInfo) {
|
||||
if (meta.flag === readable && value === flag) {
|
||||
return meta.icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function RecipeLibrary(props: ReagentsProps) {
|
||||
const { act, data } = useBackend<ReagentsData>();
|
||||
|
||||
@@ -58,30 +69,6 @@ export function RecipeLibrary(props: ReagentsProps) {
|
||||
|
||||
const pageIndexMax = Math.ceil(visibleReactions.length / 50);
|
||||
|
||||
const flagIcons = [
|
||||
{ flag: bitflags.BRUTE, icon: 'gavel' },
|
||||
{ flag: bitflags.BURN, icon: 'burn' },
|
||||
{ flag: bitflags.TOXIN, icon: 'biohazard' },
|
||||
{ flag: bitflags.OXY, icon: 'wind' },
|
||||
{ flag: bitflags.HEALING, icon: 'medkit' },
|
||||
{ flag: bitflags.DAMAGING, icon: 'skull-crossbones' },
|
||||
{ flag: bitflags.EXPLOSIVE, icon: 'bomb' },
|
||||
{ flag: bitflags.OTHER, icon: 'question' },
|
||||
{ flag: bitflags.DANGEROUS, icon: 'exclamation-triangle' },
|
||||
{ flag: bitflags.EASY, icon: 'chess-pawn' },
|
||||
{ flag: bitflags.MODERATE, icon: 'chess-knight' },
|
||||
{ flag: bitflags.HARD, icon: 'chess-queen' },
|
||||
{ flag: bitflags.ORGAN, icon: 'brain' },
|
||||
{ flag: bitflags.DRINK, icon: 'cocktail' },
|
||||
{ flag: bitflags.FOOD, icon: 'drumstick-bite' },
|
||||
{ flag: bitflags.SLIME, icon: 'microscope' },
|
||||
{ flag: bitflags.DRUG, icon: 'pills' },
|
||||
{ flag: bitflags.UNIQUE, icon: 'puzzle-piece' },
|
||||
{ flag: bitflags.CHEMICAL, icon: 'flask' },
|
||||
{ flag: bitflags.PLANT, icon: 'seedling' },
|
||||
{ flag: bitflags.COMPETITIVE, icon: 'recycle' },
|
||||
];
|
||||
|
||||
return (
|
||||
<Section
|
||||
fill
|
||||
@@ -184,11 +171,10 @@ export function RecipeLibrary(props: ReagentsProps) {
|
||||
))}
|
||||
</Table.Cell>
|
||||
<Table.Cell width="60px">
|
||||
{flagIcons
|
||||
.filter((meta) => reaction.bitflags & meta.flag)
|
||||
.map((meta) => (
|
||||
<Icon key={meta.flag} name={meta.icon} mr={1} />
|
||||
))}
|
||||
<Icon
|
||||
name={bitflagToIcon(reaction.bitflags, bitflags) || 'question'}
|
||||
mr={1}
|
||||
/>
|
||||
</Table.Cell>
|
||||
<Table.Cell width="20px">
|
||||
{!bookmarkMode ? (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Button, LabeledList } from 'tgui-core/components';
|
||||
|
||||
import { useBackend } from '../../backend';
|
||||
import type { ReagentsData, ReagentsProps } from './types';
|
||||
import { bitflagInfo, type ReagentsData, type ReagentsProps } from './types';
|
||||
|
||||
export function TagBox(props: ReagentsProps) {
|
||||
const { act, data } = useBackend<ReagentsData>();
|
||||
@@ -9,224 +9,45 @@ export function TagBox(props: ReagentsProps) {
|
||||
|
||||
const [page, setPage] = props.pageState;
|
||||
|
||||
// first go through all bitflaginfo to find all unique categories
|
||||
const allCategories: string[] = [];
|
||||
for (const meta of bitflagInfo) {
|
||||
if (!allCategories.includes(meta.category)) {
|
||||
allCategories.push(meta.category);
|
||||
}
|
||||
}
|
||||
|
||||
// then fill each category with its respective bitflags
|
||||
const categorizedBitflags: Record<string, typeof bitflagInfo> = {};
|
||||
for (const category of allCategories) {
|
||||
categorizedBitflags[category] = bitflagInfo.filter(
|
||||
(meta) => meta.category === category,
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Affects">
|
||||
<Button
|
||||
color={selectedBitflags & bitflags.BRUTE ? 'green' : 'red'}
|
||||
icon="gavel"
|
||||
onClick={() => {
|
||||
act('toggle_tag_brute');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Brute
|
||||
</Button>
|
||||
<Button
|
||||
color={selectedBitflags & bitflags.BURN ? 'green' : 'red'}
|
||||
icon="burn"
|
||||
onClick={() => {
|
||||
act('toggle_tag_burn');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Burn
|
||||
</Button>
|
||||
<Button
|
||||
color={selectedBitflags & bitflags.TOXIN ? 'green' : 'red'}
|
||||
icon="biohazard"
|
||||
onClick={() => {
|
||||
act('toggle_tag_toxin');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Toxin
|
||||
</Button>
|
||||
<Button
|
||||
color={selectedBitflags & bitflags.OXY ? 'green' : 'red'}
|
||||
icon="wind"
|
||||
onClick={() => {
|
||||
act('toggle_tag_oxy');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Suffocation
|
||||
</Button>
|
||||
<Button
|
||||
color={selectedBitflags & bitflags.ORGAN ? 'green' : 'red'}
|
||||
icon="brain"
|
||||
onClick={() => {
|
||||
act('toggle_tag_organ');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Organ
|
||||
</Button>
|
||||
<Button
|
||||
icon="flask"
|
||||
color={selectedBitflags & bitflags.CHEMICAL ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_chemical');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Chemical
|
||||
</Button>
|
||||
<Button
|
||||
icon="seedling"
|
||||
color={selectedBitflags & bitflags.PLANT ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_plant');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Plants
|
||||
</Button>
|
||||
<Button
|
||||
icon="question"
|
||||
color={selectedBitflags & bitflags.OTHER ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_other');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Other
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Type">
|
||||
<Button
|
||||
color={selectedBitflags & bitflags.DRINK ? 'green' : 'red'}
|
||||
icon="cocktail"
|
||||
onClick={() => {
|
||||
act('toggle_tag_drink');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Drink
|
||||
</Button>
|
||||
<Button
|
||||
color={selectedBitflags & bitflags.FOOD ? 'green' : 'red'}
|
||||
icon="drumstick-bite"
|
||||
onClick={() => {
|
||||
act('toggle_tag_food');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Food
|
||||
</Button>
|
||||
<Button
|
||||
color={selectedBitflags & bitflags.HEALING ? 'green' : 'red'}
|
||||
icon="medkit"
|
||||
onClick={() => {
|
||||
act('toggle_tag_healing');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Healing
|
||||
</Button>
|
||||
<Button
|
||||
icon="skull-crossbones"
|
||||
color={selectedBitflags & bitflags.DAMAGING ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_damaging');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Toxic
|
||||
</Button>
|
||||
<Button
|
||||
icon="pills"
|
||||
color={selectedBitflags & bitflags.DRUG ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_drug');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Drugs
|
||||
</Button>
|
||||
<Button
|
||||
icon="microscope"
|
||||
color={selectedBitflags & bitflags.SLIME ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_slime');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Slime
|
||||
</Button>
|
||||
<Button
|
||||
icon="bomb"
|
||||
color={selectedBitflags & bitflags.EXPLOSIVE ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_explosive');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Explosive
|
||||
</Button>
|
||||
<Button
|
||||
icon="puzzle-piece"
|
||||
color={selectedBitflags & bitflags.UNIQUE ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_unique');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Unique
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Difficulty">
|
||||
<Button
|
||||
icon="chess-pawn"
|
||||
color={selectedBitflags & bitflags.EASY ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_easy');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Easy
|
||||
</Button>
|
||||
<Button
|
||||
icon="chess-knight"
|
||||
color={selectedBitflags & bitflags.MODERATE ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_moderate');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Moderate
|
||||
</Button>
|
||||
<Button
|
||||
icon="chess-queen"
|
||||
color={selectedBitflags & bitflags.HARD ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_hard');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Hard
|
||||
</Button>
|
||||
<Button
|
||||
icon="exclamation-triangle"
|
||||
color={selectedBitflags & bitflags.DANGEROUS ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_dangerous');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Dangerous
|
||||
</Button>
|
||||
<Button
|
||||
icon="recycle"
|
||||
color={selectedBitflags & bitflags.COMPETITIVE ? 'green' : 'red'}
|
||||
onClick={() => {
|
||||
act('toggle_tag_competitive');
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
Competitive
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
{Object.entries(categorizedBitflags).map(([category, metas]) => (
|
||||
<LabeledList.Item label={category} key={category}>
|
||||
{metas.map((meta) => {
|
||||
const flag = bitflags[meta.flag];
|
||||
return (
|
||||
<Button
|
||||
key={meta.flag}
|
||||
selected={(selectedBitflags & flag) !== 0}
|
||||
icon={meta.icon}
|
||||
tooltip={meta.tooltip}
|
||||
onClick={() => {
|
||||
act(meta.toggle);
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
{meta.flag}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -78,3 +78,168 @@ export type Reaction = {
|
||||
name: string;
|
||||
reactants: ReactionReagent[];
|
||||
};
|
||||
|
||||
export const bitflagInfo = [
|
||||
{
|
||||
flag: 'BRUTE',
|
||||
icon: 'gavel',
|
||||
tooltip: 'Produces a reagent that heals or deals brute damage.',
|
||||
category: 'Affects',
|
||||
toggle: 'toggle_tag_brute', // future todo : just make this use ui state
|
||||
},
|
||||
{
|
||||
flag: 'BURN',
|
||||
icon: 'burn',
|
||||
tooltip: 'Produces a reagent that heals or deals burn damage.',
|
||||
category: 'Affects',
|
||||
toggle: 'toggle_tag_burn',
|
||||
},
|
||||
{
|
||||
flag: 'TOXIN',
|
||||
icon: 'biohazard',
|
||||
tooltip: 'Produces a reagent that heals or deals toxin damage.',
|
||||
category: 'Affects',
|
||||
toggle: 'toggle_tag_toxin',
|
||||
},
|
||||
{
|
||||
flag: 'OXY',
|
||||
icon: 'wind',
|
||||
tooltip: 'Produces a reagent that heals or deals suffocation damage.',
|
||||
category: 'Affects',
|
||||
toggle: 'toggle_tag_oxy',
|
||||
},
|
||||
{
|
||||
flag: 'HEALING',
|
||||
icon: 'medkit',
|
||||
tooltip: 'Produces a healing reagent.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_healing',
|
||||
},
|
||||
{
|
||||
flag: 'DAMAGING',
|
||||
icon: 'skull-crossbones',
|
||||
tooltip: 'Produces a damaging reagent.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_damaging',
|
||||
},
|
||||
{
|
||||
flag: 'EXPLOSIVE',
|
||||
icon: 'bomb',
|
||||
tooltip: 'Produces a reagent that explodes or explodes on reaction.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_explosive',
|
||||
},
|
||||
{
|
||||
flag: 'OTHER',
|
||||
icon: 'question',
|
||||
tooltip: 'Produces a reagent with some other side effect.',
|
||||
category: 'Affects',
|
||||
toggle: 'toggle_tag_other',
|
||||
},
|
||||
{
|
||||
flag: 'DANGEROUS',
|
||||
icon: 'exclamation-triangle',
|
||||
tooltip: 'Reaction may have a dangerous immediate effect.',
|
||||
category: 'Difficulty',
|
||||
toggle: 'toggle_tag_dangerous',
|
||||
},
|
||||
{
|
||||
flag: 'EASY',
|
||||
icon: 'chess-pawn',
|
||||
tooltip: 'Easy to perform reaction.',
|
||||
category: 'Difficulty',
|
||||
toggle: 'toggle_tag_easy',
|
||||
},
|
||||
{
|
||||
flag: 'MODERATE',
|
||||
icon: 'chess-knight',
|
||||
tooltip: 'Moderate difficulty reaction.',
|
||||
category: 'Difficulty',
|
||||
toggle: 'toggle_tag_moderate',
|
||||
},
|
||||
{
|
||||
flag: 'HARD',
|
||||
icon: 'chess-queen',
|
||||
tooltip: 'Hard to perform reaction.',
|
||||
category: 'Difficulty',
|
||||
toggle: 'toggle_tag_hard',
|
||||
},
|
||||
{
|
||||
flag: 'ORGAN',
|
||||
icon: 'brain',
|
||||
tooltip: 'Produces a reagent that heals or deals organ damage.',
|
||||
category: 'Affects',
|
||||
toggle: 'toggle_tag_organ',
|
||||
},
|
||||
{
|
||||
flag: 'DRINK',
|
||||
icon: 'cocktail',
|
||||
tooltip: 'Produces a drinkable reagent. Usually performed in the bar.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_drink',
|
||||
},
|
||||
{
|
||||
flag: 'FOOD',
|
||||
icon: 'drumstick-bite',
|
||||
tooltip: 'Produces a food. Usually performed in the kitchen.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_food',
|
||||
},
|
||||
{
|
||||
flag: 'SLIME',
|
||||
icon: 'microscope',
|
||||
tooltip: 'A reaction related to Xenobiology.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_slime',
|
||||
},
|
||||
{
|
||||
flag: 'DRUG',
|
||||
icon: 'pills',
|
||||
tooltip:
|
||||
'Produces an addictive reagent with positive and negative effects.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_drug',
|
||||
},
|
||||
{
|
||||
flag: 'UNIQUE',
|
||||
icon: 'puzzle-piece',
|
||||
tooltip: 'A unique or special reaction.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_unique',
|
||||
},
|
||||
{
|
||||
flag: 'CHEMICAL',
|
||||
icon: 'flask',
|
||||
tooltip: 'Produces a reagent which alters other reactions.',
|
||||
category: 'Affects',
|
||||
toggle: 'toggle_tag_chemical',
|
||||
},
|
||||
{
|
||||
flag: 'PLANT',
|
||||
icon: 'seedling',
|
||||
tooltip: 'Produces a reagent that can help or harm plants.',
|
||||
category: 'Affects',
|
||||
toggle: 'toggle_tag_plant',
|
||||
},
|
||||
{
|
||||
flag: 'COMPETITIVE',
|
||||
icon: 'recycle',
|
||||
tooltip: 'A reaction that competes with other reactions.',
|
||||
category: 'Difficulty',
|
||||
toggle: 'toggle_tag_competitive',
|
||||
},
|
||||
{
|
||||
flag: 'COMPONENT',
|
||||
icon: 'question',
|
||||
tooltip: 'Produces a reagent commonly used in other reactions.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_component',
|
||||
},
|
||||
{
|
||||
flag: 'ACTIVE',
|
||||
icon: 'question',
|
||||
tooltip: 'Reaction has an active, immediate effect.',
|
||||
category: 'Type',
|
||||
toggle: 'toggle_tag_active',
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user