tgui reagent guidebook & tgui updates (#6161)

Co-authored-by: silicons <no@you.cat>
This commit is contained in:
silicons
2023-12-06 21:35:54 +01:00
committed by GitHub
co-authored by silicons
parent 344e6a0f42
commit db95e39df3
119 changed files with 5534 additions and 2321 deletions
+5
View File
@@ -477,6 +477,7 @@
#include "code\controllers\configuration_old\configuration.dm"
#include "code\controllers\configuration_old\configuration_vr.dm"
#include "code\controllers\observer_listener\atom\observer.dm"
#include "code\controllers\repository\guidebook.dm"
#include "code\controllers\repository\structs.dm"
#include "code\controllers\subsystem\ai.dm"
#include "code\controllers\subsystem\air.dm"
@@ -2739,6 +2740,9 @@
#include "code\modules\ghostroles\roles\pirate.dm"
#include "code\modules\ghostroles\roles\sapient_mob.dm"
#include "code\modules\ghosttrap\trap.dm"
#include "code\modules\guidebook\guidebook.dm"
#include "code\modules\guidebook\guidebook_section.dm"
#include "code\modules\guidebook\sections\reagents.dm"
#include "code\modules\hardsuits\_rig.dm"
#include "code\modules\hardsuits\activation.dm"
#include "code\modules\hardsuits\rig_attackby.dm"
@@ -4309,6 +4313,7 @@
#include "code\modules\reagents\chemistry\reagents\Chemistry-Reagents-Other.dm"
#include "code\modules\reagents\chemistry\reagents\Chemistry-Reagents-Toxins.dm"
#include "code\modules\reagents\chemistry\reagents\Chemistry-Topical.dm"
#include "code\modules\reagents\chemistry\reagents\core\elements.dm"
#include "code\modules\reagents\chemistry\reagents\other\cleaner.dm"
#include "code\modules\reagents\chemistry\reagents\pyrotechnics\thermite.dm"
#include "code\modules\reagents\chemistry\recipes\medicine.dm"
+28
View File
@@ -6,6 +6,34 @@
// none yet
//? flags for /datum/reagent/var/reagent_guidebook_flags
/// doesn't show in guidebook reagent list
#define REAGENT_GUIDEBOOK_UNLISTED (1<<0)
/// can't be pulled up on guidebook at all, other than name
#define REAGENT_GUIDEBOOK_HIDDEN (1<<1)
DEFINE_SHARED_BITFIELD(reagent_guidebook_flags, list(
"reagent_guidebook_flags",
), list(
BITFIELD(REAGENT_GUIDEBOOK_UNLISTED),
BITFIELD(REAGENT_GUIDEBOOK_HIDDEN),
))
//? flags for /datum/chemical_reaction/var/chemical_reaction_flags
// none yet
//? flags for /datum/chemical_reaction/var/reaction_guidebook_flags
/// doesn't show in guidebook reaction list
#define REACTION_GUIDEBOOK_UNLISTED (1<<0)
/// can't be pulled up on guidebook at all, other than name
#define REACTION_GUIDEBOOK_HIDDEN (1<<1)
DEFINE_SHARED_BITFIELD(reaction_guidebook_flags, list(
"reaction_guidebook_flags",
), list(
BITFIELD(REACTION_GUIDEBOOK_UNLISTED),
BITFIELD(REACTION_GUIDEBOOK_HIDDEN),
))
+6
View File
@@ -0,0 +1,6 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2023 Citadel Station developers. *//
REPOSITORY_DEF(guidebook)
name = "Repository - Guidebook"
expected_type = /datum/prototype/guidebook_section
@@ -17,8 +17,8 @@ PROCESSING_SUBSYSTEM_DEF(chemistry)
// honestly hate that we have to do this but some things INITIALIZE_IMMEDIATE so uh fuck me I guess!
/datum/controller/subsystem/processing/chemistry/PreInit(recovering)
initialize_chemical_reactions()
initialize_chemical_reagents()
initialize_chemical_reactions()
return ..()
/**
+1
View File
@@ -360,6 +360,7 @@ SUBSYSTEM_DEF(tgui)
// Inform the UIs of their new owner.
ui.user = target
target.tgui_open_uis.Add(ui)
source.on_ui_transfer(source, target, ui)
// Clear the old list.
source.tgui_open_uis.Cut()
return TRUE
+70
View File
@@ -0,0 +1,70 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2023 Citadel Station developers. *//
GLOBAL_DATUM_INIT(guidebook, /datum/guidebook, new)
/**
* A standalone version of the guidebook system.
*
* Open when you want a detached reference, like for chemical dispensers to hook into.
*/
/datum/guidebook
/// open instances mapped to list of ids
var/list/opened = list()
/datum/guidebook/ui_state(mob/user, datum/tgui_module/module)
return GLOB.always_state
/datum/guidebook/ui_close(mob/user, datum/tgui_module/module)
opened -= user
return ..()
/datum/guidebook/on_ui_transfer(mob/old_mob, mob/new_mob, datum/tgui/ui)
opened[new_mob] = opened[old_mob]
opened -= old_mob
return ..()
/**
* @params
* * user - person viewing
* * sections - list of section instances, ids, or paths
*/
/datum/guidebook/proc/open(mob/user, list/datum/prototype/guidebook_section/sections)
// build
var/list/built = list()
var/list/hash = list()
var/list/fetched = list()
var/list/lookup = list()
// preprocess sections & inject
for(var/datum/prototype/guidebook_section/section as anything in sections)
if(!istype(section))
section = RCguidebook.fetch(section)
if(!istype(section))
CRASH("invalid section, aborting")
fetched += section
hash += section.id
// hash
hash = jointext(hash, "-")
// check if we need to re-open
if(opened[user] == hash)
return
opened[user] = hash
// inject
for(var/datum/prototype/guidebook_section/section as anything in fetched)
built[section.id] = section.interface_data()
lookup[section.id] = section.title
// open
var/datum/tgui/ui = SStgui.try_update_ui(user, src)
if(isnull(ui))
ui = new(user, src, "TGUIGuidebook")
ui.set_autoupdate(FALSE)
ui.open(data = list("sections" = lookup), modules = built)
else
push_ui_modules(user, updates = built)
push_ui_data(user, data = list("sections" = lookup))
/client/verb/access_guidebook()
set name = "Access Guidebook"
set category = "OOC"
GLOB.guidebook.ui_interact(src)
@@ -0,0 +1,27 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2023 Citadel Station developers. *//
/datum/prototype/guidebook_section
abstract_type = /datum/prototype/guidebook_section
/// section title
var/title = "Unknown"
/// tgui guidebook module to load
var/tgui_module
/**
* data to be sent to module - static
*
* this is the only one, for now
*
* todo: add dynamic data support???
*/
/datum/prototype/guidebook_section/proc/section_data()
. = list()
/datum/prototype/guidebook_section/proc/interface_data()
return list(
"$tgui" = tgui_module,
"$src" = REF(src),
"title" = title,
) | section_data()
@@ -0,0 +1,19 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2023 Citadel Station developers. *//
/datum/prototype/guidebook_section/reagents
title = "Reagents"
id = "reagents"
tgui_module = "TGUIGuidebookReagents"
/datum/prototype/guidebook_section/reagents/section_data()
. = ..()
var/list/reagents = list()
var/list/reactions = list()
for(var/id in SSchemistry.reagent_lookup)
var/datum/reagent/reagent = SSchemistry.reagent_lookup[id]
reagents[id] = reagent.tgui_guidebook_data()
for(var/datum/chemical_reaction/reaction as anything in SSchemistry.chemical_reactions)
reactions[reaction.id || "[reaction.name]" || "[reaction.type]"] = reaction.tgui_guidebook_data()
.["reagents"] = reagents
.["reactions"] = reactions
+53 -1
View File
@@ -21,8 +21,25 @@
/// required container typepath of holder my_atom
var/required_container
//* identity
/// name; defaults to reagent produced's name.
/// if this is defaulted, it also defaults display name to that reagent if unset.
var/name
/// description, if any; defaults to reagent produced's desc
/// if this is defaulted, it also defaults display desc to that reagent if unset.
var/desc
/// display name; overrides name when player facing if set
var/display_name
/// display description; overrides desc when player facing if set
var/display_description
//* guidebook
/// guidebook flags
var/reaction_guidebook_flags = NONE
/// guidebook category
var/reaction_guidebook_category = "Unsorted"
//? legacy / unsorted
var/name = null
var/list/catalysts = list()
var/list/inhibitors = list()
@@ -43,6 +60,10 @@
var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file.
/datum/chemical_reaction/New()
resolve_paths()
generate()
/datum/chemical_reaction/proc/resolve_paths()
for(var/i in 1 to length(required_reagents))
var/datum/reagent/path = required_reagents[i]
if(!ispath(path))
@@ -71,6 +92,18 @@
var/datum/reagent/result_initial = result
result = initial(result_initial.id)
/datum/chemical_reaction/proc/generate()
var/datum/reagent/resolved = SSchemistry.get_reagent(result)
if(isnull(name))
name = resolved?.name || "???"
if(isnull(display_name) && !isnull(resolved))
display_name = resolved.display_name
if(isnull(desc))
desc = resolved?.description || "Unknown Description - contact coders."
if(isnull(display_description) && !isnull(resolved))
display_description = resolved.display_description
/datum/chemical_reaction/proc/can_happen(datum/reagents/holder)
// check container
if(!isnull(required_container) && !istype(holder.my_atom, required_container))
@@ -166,6 +199,25 @@
/datum/chemical_reaction/proc/send_data(datum/reagents/holder, reaction_limit)
return null
//* Guidebook
/**
* Guidebook Data for TGUIGuidebookReaction
*/
/datum/chemical_reaction/proc/tgui_guidebook_data()
return list(
"name" = display_name || name,
"desc" = display_description || desc,
"category" = reaction_guidebook_category,
"id" = id,
"flags" = NONE,
"guidebookFlags" = reaction_guidebook_flags,
// below are stubbed and overridden on subtypes
// todo: why is this the case?
"alcoholStrength" = null,
)
/* Most medication reactions, and their precursors */
//Standard First Aid Medication
+42 -3
View File
@@ -11,15 +11,33 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
/datum/reagent
abstract_type = /datum/reagent
//? core
//* Core
/// id - must be unique and in CamelCase.
var/id
/// reagent flags - see [code/__DEFINES/reagents/flags.dm]
var/reagent_flags = NONE
//? legacy / unsorted
//* Identity
/// our name - visible from guidebooks and to admins
var/name = "Reagent"
var/description = "A non-descript chemical."
/// our description - visible from guidebooks and to admins
var/description = "A non-descript chemical of some kind."
/// player-facing name - visible via scan tools
/// defaults to [name]
/// overrides name in guidebook
var/display_name
/// player-facing desc - visible via scan tools
/// defaults to [desc]
/// overrides desc in guidebook
var/display_description
//* Guidebook
/// guidebook flags
var/reagent_guidebook_flags = NONE
/// guidebook category
var/reagent_guidebook_category = "Unsorted"
//? legacy / unsorted
var/taste_description = "bitterness"
/// How this taste compares to others. Higher values means it is more noticable
var/taste_mult = 1
@@ -279,6 +297,25 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
/datum/reagent/proc/on_update(atom/A)
return
//* Guidebook
/**
* Guidebook Data for TGUIGuidebookReagent
*/
/datum/reagent/proc/tgui_guidebook_data()
return list(
"id" = id,
"name" = display_name || name,
"desc" = display_description || description,
"category" = reagent_guidebook_category,
"flags" = reagent_flags,
"guidebookFlags" = reagent_guidebook_flags,
// todo: should this be here?
"alcoholStrength" = null,
)
//* Holder - Application
/**
* called when we first get applied to a mob
*
@@ -321,6 +358,8 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
// todo: implement this proc, replace touch_turf/reaction_turf and similar with it.
// /datum/reagent/proc/apply_to_turf(turf/target, amount, list/data)
//* Holder - Mixing
/**
* called when a new reagent is being mixed with this one to mix our data lists.
*
@@ -1,70 +1,4 @@
/datum/reagent/aluminum
name = "Aluminum"
id = "aluminum"
description = "A silvery white and ductile member of the boron group of chemical elements."
taste_description = "metal"
taste_mult = 1.1
reagent_state = REAGENT_SOLID
color = "#A8A8A8"
/datum/reagent/calcium
name = "Calcium"
id = "calcium"
description = "A chemical element, the building block of bones."
taste_description = "metallic chalk" // Apparently, calcium tastes like calcium.
taste_mult = 1.3
reagent_state = REAGENT_SOLID
color = "#e9e6e4"
/datum/reagent/carbon
name = "Carbon"
id = "carbon"
description = "A chemical element, the building block of life."
taste_description = "sour chalk"
taste_mult = 1.5
reagent_state = REAGENT_SOLID
color = "#1C1300"
ingest_met = REM * 5
/datum/reagent/carbon/affect_ingest(mob/living/carbon/M, alien, removed)
if(alien == IS_DIONA)
return
if(M.ingested && M.ingested.reagent_list.len > 1) // Need to have at least 2 reagents - cabon and something to remove
var/effect = 1 / (M.ingested.reagent_list.len - 1)
for(var/datum/reagent/R in M.ingested.reagent_list)
if(R == src)
continue
M.ingested.remove_reagent(R.id, removed * effect)
/datum/reagent/carbon/touch_turf(turf/T)
if(!istype(T, /turf/space))
var/obj/effect/debris/cleanable/dirt/dirtoverlay = locate(/obj/effect/debris/cleanable/dirt, T)
if (!dirtoverlay)
dirtoverlay = new/obj/effect/debris/cleanable/dirt(T)
dirtoverlay.alpha = volume * 30
else
dirtoverlay.alpha = min(dirtoverlay.alpha + volume * 30, 255)
/datum/reagent/chlorine
name = "Chlorine"
id = "chlorine"
description = "A chemical element with a characteristic odour."
taste_description = "pool water"
reagent_state = REAGENT_GAS
color = "#d1db77"
/datum/reagent/chlorine/affect_blood(mob/living/carbon/M, alien, removed)
M.take_organ_damage(1*REM, 0)
/datum/reagent/chlorine/affect_touch(mob/living/carbon/M, alien, removed)
M.take_organ_damage(1*REM, 0)
/datum/reagent/copper
name = "Copper"
id = "copper"
description = "A highly ductile metal."
taste_description = "pennies"
color = "#6E3B08"
/datum/reagent/ethanol
name = "Ethanol" //Parent class for all alcoholic reagents.
@@ -78,6 +12,7 @@
var/nutriment_factor = 0
var/hydration_factor = 0
// todo: this is awful why is strength lower when higher?
var/strength = 10 // This is, essentially, units between stages - the lower, the stronger. Less fine tuning, more clarity.
var/toxicity = 1
@@ -217,136 +152,6 @@
to_chat(usr, "<span class='notice'>The solution dissolves the ink on the book.</span>")
return
/datum/reagent/fluorine
name = "Fluorine"
id = "fluorine"
description = "A highly-reactive chemical element."
taste_description = "acid"
reagent_state = REAGENT_GAS
color = "#808080"
/datum/reagent/fluorine/affect_blood(mob/living/carbon/M, alien, removed)
M.adjustToxLoss(removed)
/datum/reagent/fluorine/affect_touch(mob/living/carbon/M, alien, removed)
M.adjustToxLoss(removed)
/datum/reagent/hydrogen
name = "Hydrogen"
id = "hydrogen"
description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas."
taste_mult = 0 //no taste
reagent_state = REAGENT_GAS
color = "#808080"
/datum/reagent/iron
name = "Iron"
id = "iron"
description = "Pure iron is a metal."
taste_description = "metal"
reagent_state = REAGENT_SOLID
color = "#353535"
/datum/reagent/iron/affect_ingest(mob/living/carbon/M, alien, removed)
if(alien != IS_DIONA)
M.add_chemical_effect(CE_BLOODRESTORE, 8 * removed)
/datum/reagent/lithium
name = "Lithium"
id = "lithium"
description = "A chemical element, used as antidepressant."
taste_description = "metal"
reagent_state = REAGENT_SOLID
color = "#808080"
/datum/reagent/lithium/affect_blood(mob/living/carbon/M, alien, removed)
if(alien != IS_DIONA)
if(CHECK_MOBILITY(M, MOBILITY_CAN_MOVE) && istype(M.loc, /turf/space))
step(M, pick(GLOB.cardinal))
if(prob(5))
M.emote(pick("twitch", "drool", "moan"))
/datum/reagent/mercury
name = "Mercury"
id = "mercury"
description = "A chemical element."
taste_mult = 0 //mercury apparently is tasteless. IDK
reagent_state = REAGENT_LIQUID
color = "#484848"
/datum/reagent/mercury/affect_blood(mob/living/carbon/M, alien, removed)
if(alien != IS_DIONA)
if(CHECK_MOBILITY(M, MOBILITY_CAN_MOVE) && istype(M.loc, /turf/space))
step(M, pick(GLOB.cardinal))
if(prob(5))
M.emote(pick("twitch", "drool", "moan"))
M.adjustBrainLoss(0.1)
/datum/reagent/nitrogen
name = "Nitrogen"
id = "nitrogen"
description = "A colorless, odorless, tasteless gas."
taste_mult = 0 //no taste
reagent_state = REAGENT_GAS
color = "#808080"
/datum/reagent/oxygen
name = "Oxygen"
id = "oxygen"
description = "A colorless, odorless gas."
taste_mult = 0
reagent_state = REAGENT_GAS
color = "#808080"
/datum/reagent/oxygen/affect_blood(mob/living/carbon/M, alien, removed)
if(alien == IS_VOX)
M.adjustToxLoss(removed * 3)
/datum/reagent/phosphorus
name = "Phosphorus"
id = "phosphorus"
description = "A chemical element, the backbone of biological energy carriers."
taste_description = "vinegar"
reagent_state = REAGENT_SOLID
color = "#832828"
/datum/reagent/phosphorus/affect_blood(mob/living/carbon/M, alien, removed)
if(alien == IS_ALRAUNE)
M.nutrition += removed * 2 //cit change - phosphorus is good for plants
/datum/reagent/potassium
name = "Potassium"
id = "potassium"
description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water."
taste_description = "sweetness" //potassium is bitter in higher doses but sweet in lower ones.
reagent_state = REAGENT_SOLID
color = "#A0A0A0"
/datum/reagent/radium
name = "Radium"
id = "radium"
description = "Radium is an alkaline earth metal. It is extremely radioactive."
taste_mult = 0 //Apparently radium is tasteless
reagent_state = REAGENT_SOLID
color = "#C7C7C7"
/datum/reagent/radium/affect_blood(mob/living/carbon/M, alien, removed)
if(issmall(M))
removed *= 2
M.afflict_radiation(RAD_MOB_AFFLICT_STRENGTH_RADIUM(removed))
if(M.virus2.len)
for(var/ID in M.virus2)
var/datum/disease2/disease/V = M.virus2[ID]
if(prob(5))
M.antibodies |= V.antigen
/datum/reagent/radium/touch_turf(turf/T)
if(volume >= 3)
if(!istype(T, /turf/space))
var/obj/effect/debris/cleanable/greenglow/glow = locate(/obj/effect/debris/cleanable/greenglow, T)
if(!glow)
new /obj/effect/debris/cleanable/greenglow(T)
return
/datum/reagent/acid
name = "Sulphuric acid"
@@ -435,21 +240,6 @@
qdel(O)
remove_self(meltdose) // 10 units of acid will not melt EVERYTHING on the tile
/datum/reagent/silicon
name = "Silicon"
id = "silicon"
description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon."
taste_mult = 0
reagent_state = REAGENT_SOLID
color = "#A8A8A8"
/datum/reagent/sodium
name = "Sodium"
id = "sodium"
description = "A chemical element, readily reacts with water."
taste_description = "salty metal"
reagent_state = REAGENT_SOLID
color = "#808080"
/datum/reagent/sugar
name = "Sugar"
@@ -499,11 +289,3 @@
reagent_state = REAGENT_SOLID
color = "#BF8C00"
/datum/reagent/tungsten
name = "Tungsten"
id = "tungsten"
description = "A chemical element, and a strong oxidising agent."
taste_description = "metal"
taste_mult = 0 //no taste
reagent_state = REAGENT_SOLID
color = "#DCDCDC"
@@ -0,0 +1,223 @@
/datum/reagent/aluminum
name = "Aluminum"
id = "aluminum"
description = "A silvery white and ductile member of the boron group of chemical elements."
taste_description = "metal"
taste_mult = 1.1
reagent_state = REAGENT_SOLID
color = "#A8A8A8"
/datum/reagent/calcium
name = "Calcium"
id = "calcium"
description = "A chemical element, the building block of bones."
taste_description = "metallic chalk" // Apparently, calcium tastes like calcium.
taste_mult = 1.3
reagent_state = REAGENT_SOLID
color = "#e9e6e4"
/datum/reagent/carbon
name = "Carbon"
id = "carbon"
description = "A chemical element, the building block of life."
taste_description = "sour chalk"
taste_mult = 1.5
reagent_state = REAGENT_SOLID
color = "#1C1300"
ingest_met = REM * 5
/datum/reagent/carbon/affect_ingest(mob/living/carbon/M, alien, removed)
if(alien == IS_DIONA)
return
if(M.ingested && M.ingested.reagent_list.len > 1) // Need to have at least 2 reagents - cabon and something to remove
var/effect = 1 / (M.ingested.reagent_list.len - 1)
for(var/datum/reagent/R in M.ingested.reagent_list)
if(R == src)
continue
M.ingested.remove_reagent(R.id, removed * effect)
/datum/reagent/carbon/touch_turf(turf/T)
if(!istype(T, /turf/space))
var/obj/effect/debris/cleanable/dirt/dirtoverlay = locate(/obj/effect/debris/cleanable/dirt, T)
if (!dirtoverlay)
dirtoverlay = new/obj/effect/debris/cleanable/dirt(T)
dirtoverlay.alpha = volume * 30
else
dirtoverlay.alpha = min(dirtoverlay.alpha + volume * 30, 255)
/datum/reagent/chlorine
name = "Chlorine"
id = "chlorine"
description = "A chemical element with a characteristic odour."
taste_description = "pool water"
reagent_state = REAGENT_GAS
color = "#d1db77"
/datum/reagent/chlorine/affect_blood(mob/living/carbon/M, alien, removed)
M.take_organ_damage(1*REM, 0)
/datum/reagent/chlorine/affect_touch(mob/living/carbon/M, alien, removed)
M.take_organ_damage(1*REM, 0)
/datum/reagent/copper
name = "Copper"
id = "copper"
description = "A highly ductile metal."
taste_description = "pennies"
color = "#6E3B08"
/datum/reagent/fluorine
name = "Fluorine"
id = "fluorine"
description = "A highly-reactive chemical element."
taste_description = "acid"
reagent_state = REAGENT_GAS
color = "#808080"
/datum/reagent/fluorine/affect_blood(mob/living/carbon/M, alien, removed)
M.adjustToxLoss(removed)
/datum/reagent/fluorine/affect_touch(mob/living/carbon/M, alien, removed)
M.adjustToxLoss(removed)
/datum/reagent/hydrogen
name = "Hydrogen"
id = "hydrogen"
description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas."
taste_mult = 0 //no taste
reagent_state = REAGENT_GAS
color = "#808080"
/datum/reagent/iron
name = "Iron"
id = "iron"
description = "Pure iron is a metal."
taste_description = "metal"
reagent_state = REAGENT_SOLID
color = "#353535"
/datum/reagent/iron/affect_ingest(mob/living/carbon/M, alien, removed)
if(alien != IS_DIONA)
M.add_chemical_effect(CE_BLOODRESTORE, 8 * removed)
/datum/reagent/lithium
name = "Lithium"
id = "lithium"
description = "A chemical element, used as antidepressant."
taste_description = "metal"
reagent_state = REAGENT_SOLID
color = "#808080"
/datum/reagent/lithium/affect_blood(mob/living/carbon/M, alien, removed)
if(alien != IS_DIONA)
if(CHECK_MOBILITY(M, MOBILITY_CAN_MOVE) && istype(M.loc, /turf/space))
step(M, pick(GLOB.cardinal))
if(prob(5))
M.emote(pick("twitch", "drool", "moan"))
/datum/reagent/mercury
name = "Mercury"
id = "mercury"
description = "A chemical element."
taste_mult = 0 //mercury apparently is tasteless. IDK
reagent_state = REAGENT_LIQUID
color = "#484848"
/datum/reagent/mercury/affect_blood(mob/living/carbon/M, alien, removed)
if(alien != IS_DIONA)
if(CHECK_MOBILITY(M, MOBILITY_CAN_MOVE) && istype(M.loc, /turf/space))
step(M, pick(GLOB.cardinal))
if(prob(5))
M.emote(pick("twitch", "drool", "moan"))
M.adjustBrainLoss(0.1)
/datum/reagent/nitrogen
name = "Nitrogen"
id = "nitrogen"
description = "A colorless, odorless, tasteless gas."
taste_mult = 0 //no taste
reagent_state = REAGENT_GAS
color = "#808080"
/datum/reagent/oxygen
name = "Oxygen"
id = "oxygen"
description = "A colorless, odorless gas."
taste_mult = 0
reagent_state = REAGENT_GAS
color = "#808080"
/datum/reagent/oxygen/affect_blood(mob/living/carbon/M, alien, removed)
if(alien == IS_VOX)
M.adjustToxLoss(removed * 3)
/datum/reagent/phosphorus
name = "Phosphorus"
id = "phosphorus"
description = "A chemical element, the backbone of biological energy carriers."
taste_description = "vinegar"
reagent_state = REAGENT_SOLID
color = "#832828"
/datum/reagent/phosphorus/affect_blood(mob/living/carbon/M, alien, removed)
if(alien == IS_ALRAUNE)
M.nutrition += removed * 2 //cit change - phosphorus is good for plants
/datum/reagent/potassium
name = "Potassium"
id = "potassium"
description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water."
taste_description = "sweetness" //potassium is bitter in higher doses but sweet in lower ones.
reagent_state = REAGENT_SOLID
color = "#A0A0A0"
/datum/reagent/radium
name = "Radium"
id = "radium"
description = "Radium is an alkaline earth metal. It is extremely radioactive."
taste_mult = 0 //Apparently radium is tasteless
reagent_state = REAGENT_SOLID
color = "#C7C7C7"
/datum/reagent/radium/affect_blood(mob/living/carbon/M, alien, removed)
if(issmall(M))
removed *= 2
M.afflict_radiation(RAD_MOB_AFFLICT_STRENGTH_RADIUM(removed))
if(M.virus2.len)
for(var/ID in M.virus2)
var/datum/disease2/disease/V = M.virus2[ID]
if(prob(5))
M.antibodies |= V.antigen
/datum/reagent/radium/touch_turf(turf/T)
if(volume >= 3)
if(!istype(T, /turf/space))
var/obj/effect/debris/cleanable/greenglow/glow = locate(/obj/effect/debris/cleanable/greenglow, T)
if(!glow)
new /obj/effect/debris/cleanable/greenglow(T)
return
/datum/reagent/silicon
name = "Silicon"
id = "silicon"
description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon."
taste_mult = 0
reagent_state = REAGENT_SOLID
color = "#A8A8A8"
/datum/reagent/sodium
name = "Sodium"
id = "sodium"
description = "A chemical element, readily reacts with water."
taste_description = "salty metal"
reagent_state = REAGENT_SOLID
color = "#808080"
/datum/reagent/tungsten
name = "Tungsten"
id = "tungsten"
description = "A chemical element, and a strong oxidising agent."
taste_description = "metal"
taste_mult = 0 //no taste
reagent_state = REAGENT_SOLID
color = "#DCDCDC"
@@ -207,6 +207,10 @@
if("toggle_charge")
charging = !charging
return TRUE
if("guide")
usr.action_feedback(SPAN_WARNING("The Reagent Guidebook is currently under construction. Please check back later."), src)
// GLOB.guidebook.open(usr, list(/datum/prototype/guidebook_section/reagents))
return TRUE
if("reagent")
if(isnull(inserted?.reagents))
return TRUE
+8
View File
@@ -224,6 +224,14 @@
/datum/proc/ui_close(mob/user, datum/tgui_module/module)
SIGNAL_HANDLER
/**
* public
*
* Called on a UI's object when the UI is transferred from one mob to another.
*/
/datum/proc/on_ui_transfer(mob/old_mob, mob/new_mob, datum/tgui/ui)
return
/**
* verb
*
+12 -2
View File
@@ -80,9 +80,13 @@
*
* Open this UI (and initialize it with data).
*
* @params
* * data - force certain data sends
* * modules - force certain module sends
*
* return bool - TRUE if a new pooled window is opened, FALSE in all other situations including if a new pooled window didn't open because one already exists.
*/
/datum/tgui/proc/open()
/datum/tgui/proc/open(data, modules)
if(!user.client)
return FALSE
if(window)
@@ -115,6 +119,8 @@
window.send_message("update", get_payload(
with_data = TRUE,
with_static_data = TRUE,
force_data = data,
force_modules = modules,
))
if(mouse_hooked)
window.set_mouse_macro()
@@ -259,7 +265,7 @@
*
* return list
*/
/datum/tgui/proc/get_payload(with_data, with_static_data)
/datum/tgui/proc/get_payload(with_data, with_static_data, list/force_data, list/force_modules)
var/list/json_data = list()
json_data["config"] = list(
"title" = title,
@@ -293,6 +299,10 @@
json_data["modules"] = modules
if(src_object.tgui_shared_states)
json_data["shared"] = src_object.tgui_shared_states
if(!isnull(force_data))
json_data["data"] = (json_data["data"] || list()) | force_data
if(!isnull(force_modules))
json_data["modules"] = (json_data["modules"] || list()) | force_modules
return json_data
/**
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
+5 -5
View File
@@ -1,20 +1,20 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require eslint/lib/api.js
// Setup the environment to be able to require eslint
require(absPnpApiPath).setup();
}
}
// Defer to the real eslint/lib/api.js your application uses
module.exports = absRequire(`eslint/lib/api.js`);
// Defer to the real eslint your application uses
module.exports = absRequire(`eslint`);
+4 -1
View File
@@ -2,5 +2,8 @@
"name": "eslint",
"version": "7.32.0-sdk",
"main": "./lib/api.js",
"type": "commonjs"
"type": "commonjs",
"bin": {
"eslint": "./bin/eslint.js"
}
}
+2 -2
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
+2 -2
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
+2 -2
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
+82 -14
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
const moduleWrapper = tsserver => {
if (!process.versions.pnp) {
@@ -18,6 +18,7 @@ const moduleWrapper = tsserver => {
const pnpApi = require(`pnpapi`);
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
const isPortal = str => str.startsWith("portal:/");
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
@@ -30,7 +31,7 @@ const moduleWrapper = tsserver => {
function toEditorPath(str) {
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
if (isAbsolute(str) && !str.match(/^\^zip:/) && (str.match(/\.zip\//) || isVirtual(str))) {
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
// We also take the opportunity to turn virtual paths into physical ones;
// this makes it much easier to work with workspaces that list peer
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
@@ -44,7 +45,7 @@ const moduleWrapper = tsserver => {
const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
if (resolved) {
const locator = pnpApi.findPackageLocator(resolved);
if (locator && dependencyTreeRoots.has(`${locator.name}@${locator.reference}`)) {
if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {
str = resolved;
}
}
@@ -60,10 +61,34 @@ const moduleWrapper = tsserver => {
//
// Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
//
case `vscode`: {
// 2021-10-08: VSCode changed the format in 1.61.
// Before | ^zip:/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
// 2022-04-06: VSCode changed the format in 1.66.
// Before | ^/zip//c:/foo/bar.zip/package.json
// After | ^/zip/c:/foo/bar.zip/package.json
//
// 2022-05-06: VSCode changed the format in 1.68
// Before | ^/zip/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
case `vscode <1.61`: {
str = `^zip:${str}`;
} break;
case `vscode <1.66`: {
str = `^/zip/${str}`;
} break;
case `vscode <1.68`: {
str = `^/zip${str}`;
} break;
case `vscode`: {
str = `^/zip/${str}`;
} break;
// To make "go to definition" work,
// We have to resolve the actual file system path from virtual path
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
@@ -77,13 +102,15 @@ const moduleWrapper = tsserver => {
// everything else is up to neovim
case `neovim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = `zipfile:${str}`;
str = `zipfile://${str}`;
} break;
default: {
str = `zip:${str}`;
} break;
}
} else {
str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`);
}
}
@@ -91,9 +118,28 @@ const moduleWrapper = tsserver => {
}
function fromEditorPath(str) {
return process.platform === `win32`
? str.replace(/^\^?zip:\//, ``)
: str.replace(/^\^?zip:/, ``);
switch (hostInfo) {
case `coc-nvim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
// So in order to convert it back, we use .* to match all the thing
// before `zipfile:`
return process.platform === `win32`
? str.replace(/^.*zipfile:\//, ``)
: str.replace(/^.*zipfile:/, ``);
} break;
case `neovim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for neovim is in format of zipfile:///<pwd>/.yarn/...
return str.replace(/^zipfile:\/\//, ``);
} break;
case `vscode`:
default: {
return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`)
} break;
}
}
// Force enable 'allowLocalPluginLoads'
@@ -119,8 +165,9 @@ const moduleWrapper = tsserver => {
let hostInfo = `unknown`;
Object.assign(Session.prototype, {
onMessage(/** @type {string} */ message) {
const parsedMessage = JSON.parse(message)
onMessage(/** @type {string | object} */ message) {
const isStringMessage = typeof message === 'string';
const parsedMessage = isStringMessage ? JSON.parse(message) : message;
if (
parsedMessage != null &&
@@ -129,11 +176,32 @@ const moduleWrapper = tsserver => {
typeof parsedMessage.arguments.hostInfo === `string`
) {
hostInfo = parsedMessage.arguments.hostInfo;
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {
const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(
// The RegExp from https://semver.org/ but without the caret at the start
/(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
) ?? []).map(Number)
if (major === 1) {
if (minor < 61) {
hostInfo += ` <1.61`;
} else if (minor < 66) {
hostInfo += ` <1.66`;
} else if (minor < 68) {
hostInfo += ` <1.68`;
}
}
}
}
return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => {
return typeof value === `string` ? fromEditorPath(value) : value;
}));
const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
return typeof value === 'string' ? fromEditorPath(value) : value;
});
return originalOnMessage.call(
this,
isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)
);
},
send(/** @type {any} */ msg) {
+82 -14
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
const moduleWrapper = tsserver => {
if (!process.versions.pnp) {
@@ -18,6 +18,7 @@ const moduleWrapper = tsserver => {
const pnpApi = require(`pnpapi`);
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
const isPortal = str => str.startsWith("portal:/");
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
@@ -30,7 +31,7 @@ const moduleWrapper = tsserver => {
function toEditorPath(str) {
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
if (isAbsolute(str) && !str.match(/^\^zip:/) && (str.match(/\.zip\//) || isVirtual(str))) {
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
// We also take the opportunity to turn virtual paths into physical ones;
// this makes it much easier to work with workspaces that list peer
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
@@ -44,7 +45,7 @@ const moduleWrapper = tsserver => {
const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
if (resolved) {
const locator = pnpApi.findPackageLocator(resolved);
if (locator && dependencyTreeRoots.has(`${locator.name}@${locator.reference}`)) {
if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {
str = resolved;
}
}
@@ -60,10 +61,34 @@ const moduleWrapper = tsserver => {
//
// Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
//
case `vscode`: {
// 2021-10-08: VSCode changed the format in 1.61.
// Before | ^zip:/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
// 2022-04-06: VSCode changed the format in 1.66.
// Before | ^/zip//c:/foo/bar.zip/package.json
// After | ^/zip/c:/foo/bar.zip/package.json
//
// 2022-05-06: VSCode changed the format in 1.68
// Before | ^/zip/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
case `vscode <1.61`: {
str = `^zip:${str}`;
} break;
case `vscode <1.66`: {
str = `^/zip/${str}`;
} break;
case `vscode <1.68`: {
str = `^/zip${str}`;
} break;
case `vscode`: {
str = `^/zip/${str}`;
} break;
// To make "go to definition" work,
// We have to resolve the actual file system path from virtual path
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
@@ -77,13 +102,15 @@ const moduleWrapper = tsserver => {
// everything else is up to neovim
case `neovim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = `zipfile:${str}`;
str = `zipfile://${str}`;
} break;
default: {
str = `zip:${str}`;
} break;
}
} else {
str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`);
}
}
@@ -91,9 +118,28 @@ const moduleWrapper = tsserver => {
}
function fromEditorPath(str) {
return process.platform === `win32`
? str.replace(/^\^?zip:\//, ``)
: str.replace(/^\^?zip:/, ``);
switch (hostInfo) {
case `coc-nvim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
// So in order to convert it back, we use .* to match all the thing
// before `zipfile:`
return process.platform === `win32`
? str.replace(/^.*zipfile:\//, ``)
: str.replace(/^.*zipfile:/, ``);
} break;
case `neovim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for neovim is in format of zipfile:///<pwd>/.yarn/...
return str.replace(/^zipfile:\/\//, ``);
} break;
case `vscode`:
default: {
return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`)
} break;
}
}
// Force enable 'allowLocalPluginLoads'
@@ -119,8 +165,9 @@ const moduleWrapper = tsserver => {
let hostInfo = `unknown`;
Object.assign(Session.prototype, {
onMessage(/** @type {string} */ message) {
const parsedMessage = JSON.parse(message)
onMessage(/** @type {string | object} */ message) {
const isStringMessage = typeof message === 'string';
const parsedMessage = isStringMessage ? JSON.parse(message) : message;
if (
parsedMessage != null &&
@@ -129,11 +176,32 @@ const moduleWrapper = tsserver => {
typeof parsedMessage.arguments.hostInfo === `string`
) {
hostInfo = parsedMessage.arguments.hostInfo;
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {
const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(
// The RegExp from https://semver.org/ but without the caret at the start
/(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
) ?? []).map(Number)
if (major === 1) {
if (minor < 61) {
hostInfo += ` <1.61`;
} else if (minor < 66) {
hostInfo += ` <1.66`;
} else if (minor < 68) {
hostInfo += ` <1.68`;
}
}
}
}
return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => {
return typeof value === `string` ? fromEditorPath(value) : value;
}));
const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
return typeof value === 'string' ? fromEditorPath(value) : value;
});
return originalOnMessage.call(
this,
isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)
);
},
send(/** @type {any} */ msg) {
+5 -5
View File
@@ -1,20 +1,20 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require typescript/lib/typescript.js
// Setup the environment to be able to require typescript
require(absPnpApiPath).setup();
}
}
// Defer to the real typescript/lib/typescript.js your application uses
module.exports = absRequire(`typescript/lib/typescript.js`);
// Defer to the real typescript your application uses
module.exports = absRequire(`typescript`);
+6 -2
View File
@@ -1,6 +1,10 @@
{
"name": "typescript",
"version": "4.3.5-sdk",
"version": "4.9.4-sdk",
"main": "./lib/typescript.js",
"type": "commonjs"
"type": "commonjs",
"bin": {
"tsc": "./bin/tsc",
"tsserver": "./bin/tsserver"
}
}
+1 -1
View File
@@ -16,4 +16,4 @@ preferAggregateCacheInfo: true
preferInteractive: true
yarnPath: .yarn/releases/yarn-3.1.1.cjs
yarnPath: .yarn/releases/yarn-3.3.1.cjs
+17 -14
View File
@@ -1,8 +1,8 @@
{
"private": true,
"name": "tgui-workspace",
"version": "4.3.0",
"packageManager": "yarn@3.1.1",
"version": "4.3.1",
"packageManager": "yarn@3.3.1",
"workspaces": [
"packages/*"
],
@@ -20,31 +20,31 @@
},
"dependencies": {
"@babel/core": "^7.15.0",
"@babel/eslint-parser": "^7.15.0",
"@babel/eslint-parser": "^7.23.3",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-transform-jscript": "^7.14.5",
"@babel/preset-env": "^7.15.0",
"@babel/preset-typescript": "^7.15.0",
"@babel/preset-typescript": "^7.23.3",
"@types/jest": "^27.0.1",
"@types/jsdom": "^16.2.13",
"@types/jsdom": "^21.1.6",
"@types/node": "^14.17.9",
"@types/webpack": "^5.28.0",
"@types/webpack-env": "^1.16.2",
"@typescript-eslint/parser": "^4.29.1",
"@typescript-eslint/parser": "^6.12.0",
"babel-jest": "^27.0.6",
"babel-loader": "^8.2.2",
"babel-plugin-inferno": "^6.3.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"common": "workspace:*",
"css-loader": "^5.2.7",
"eslint": "^7.32.0",
"eslint": "^8.54.0",
"eslint-plugin-radar": "^0.2.1",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-unused-imports": "^1.1.4",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-unused-imports": "^3.0.0",
"file-loader": "^6.2.0",
"ignore-loader": "^0.1.2",
"inferno": "^7.4.8",
"jest": "^27.0.6",
"jest": "^29.7.0",
"jest-circus": "^27.0.6",
"jsdom": "^16.7.0",
"mini-css-extract-plugin": "^1.6.2",
@@ -52,10 +52,13 @@
"sass-loader": "^11.1.1",
"style-loader": "^2.0.0",
"terser-webpack-plugin": "^5.1.4",
"typescript": "^4.3.5",
"typescript": "4.9.4",
"url-loader": "^4.1.1",
"webpack": "^5.76.0",
"webpack-bundle-analyzer": "^4.4.2",
"webpack-cli": "^4.7.2"
"webpack": "^5.89.0",
"webpack-bundle-analyzer": "^4.10.1",
"webpack-cli": "^5.1.4"
},
"devDependencies": {
"jest-environment-jsdom": "^29.7.0"
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
"private": true,
"name": "common",
"version": "4.3.0"
"version": "4.3.1"
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"private": true,
"name": "tgui-bench",
"version": "4.3.0",
"version": "4.3.1",
"dependencies": {
"common": "workspace:*",
"fastify": "^3.29.4",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"private": true,
"name": "tgui-dev-server",
"version": "4.3.0",
"version": "4.3.1",
"type": "module",
"dependencies": {
"axios": "^0.21.1",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"private": true,
"name": "tgui-panel",
"version": "4.3.0",
"version": "4.3.1",
"dependencies": {
"common": "workspace:*",
"dompurify": "^2.3.1",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"private": true,
"name": "tgui-polyfill",
"version": "4.3.0",
"version": "4.3.1",
"scripts": {
"tgui-polyfill:build": "terser 00-html5shiv.js 01-ie8.js 02-dom4.js 03-css-om.js 10-misc.js --ie8 -f ascii_only,comments=false -o ../../public/tgui-polyfill.min.js"
},
@@ -55,9 +55,9 @@ const bodyZonePixelToZone: (x: number, y: number) => (BodyZone | null)
};
type BodyZoneSelectorProps = {
onClick?: (zone: BodyZone) => void,
scale?: number,
selectedZone: BodyZone | null,
readonly onClick?: (zone: BodyZone) => void,
readonly scale?: number,
readonly selectedZone: BodyZone | null,
}
type BodyZoneSelectorState = {
@@ -70,7 +70,7 @@ export class BodyZoneSelector
ref = createRef<HTMLDivElement>();
state: BodyZoneSelectorState = {
hoverZone: null,
}
};
render() {
const { hoverZone } = this.state;
+21 -21
View File
@@ -16,23 +16,23 @@ import { Tooltip } from './Tooltip';
const logger = createLogger('Button');
export type ButtonProps = BoxProps & {
fluid?: BooleanLike;
icon?: string | BooleanLike;
iconRotation?: number;
iconSpin?: BooleanLike;
iconColor?: any;
iconPosition?: 'right' | 'left';
iconProps?: BoxProps;
color?: string | BooleanLike;
disabled?: BooleanLike;
selected?: BooleanLike;
tooltip?: StrictlyStringLike;
tooltipPosition?: Placement;
ellipsis?: BooleanLike;
circular?: BooleanLike;
content?: any;
onClick?: any;
verticalAlignContent?: 'top' | 'middle' | 'bottom';
readonly fluid?: BooleanLike;
readonly icon?: string | BooleanLike;
readonly iconRotation?: number;
readonly iconSpin?: BooleanLike;
readonly iconColor?: any;
readonly iconPosition?: 'right' | 'left';
readonly iconProps?: BoxProps;
readonly color?: string | BooleanLike;
readonly disabled?: BooleanLike;
readonly selected?: BooleanLike;
readonly tooltip?: StrictlyStringLike;
readonly tooltipPosition?: Placement;
readonly ellipsis?: BooleanLike;
readonly circular?: BooleanLike;
readonly content?: any;
readonly onClick?: any;
readonly verticalAlignContent?: 'top' | 'middle' | 'bottom';
}
export const Button = (props: ButtonProps) => {
@@ -158,7 +158,7 @@ export const Button = (props: ButtonProps) => {
Button.defaultHooks = pureComponentHooks;
interface ButtonCheckboxProps extends ButtonProps {
checked?: BooleanLike;
readonly checked?: BooleanLike;
}
export const ButtonCheckbox = (props: ButtonCheckboxProps) => {
@@ -175,8 +175,8 @@ export const ButtonCheckbox = (props: ButtonCheckboxProps) => {
Button.Checkbox = ButtonCheckbox;
type ButtonConfirmProps = ButtonProps & {
confirmContent?: string;
confirmColor?: string;
readonly confirmContent?: string;
readonly confirmColor?: string;
}
type ButtonConfirmState = {
@@ -192,7 +192,7 @@ export class ButtonConfirm extends Component<ButtonConfirmProps, ButtonConfirmSt
if (this.state.clicked) {
this.setClickedOnce(false);
}
}
};
setClickedOnce(clickedOnce) {
this.setState({ clicked: clickedOnce });
+10 -10
View File
@@ -11,15 +11,15 @@ import { Button, ButtonProps } from './Button';
import { ComponentProps } from './Component';
interface CollapsibleProps extends ComponentProps{
buttons?: InfernoNode;
color?: string;
title?: string | InfernoNode;
open?: BooleanLike;
captureKeys?: BooleanLike;
more?: InfernoNode;
boxProps?: BoxProps;
headerProps?: ButtonProps;
contentFunction?: () => InfernoNode;
readonly buttons?: InfernoNode;
readonly color?: string;
readonly title?: string | InfernoNode;
readonly open?: BooleanLike;
readonly captureKeys?: BooleanLike;
readonly more?: InfernoNode;
readonly boxProps?: BoxProps;
readonly headerProps?: ButtonProps;
readonly contentFunction?: () => InfernoNode;
}
interface CollapsibleState {
@@ -29,7 +29,7 @@ interface CollapsibleState {
export class Collapsible extends Component<CollapsibleProps, CollapsibleState> {
state: CollapsibleState = {
open: false,
}
};
constructor(props) {
super(props);
+1 -1
View File
@@ -13,7 +13,7 @@ export class FitText extends Component<{
ref: RefObject<HTMLDivElement> = createRef();
state = {
fontSize: 0,
}
};
constructor() {
super();
+10 -10
View File
@@ -26,16 +26,16 @@ export const LabeledList = (props: LabeledListProps) => {
LabeledList.defaultHooks = pureComponentHooks;
type LabeledListItemProps = {
className?: string | BooleanLike;
label?: string | InfernoNode | BooleanLike;
labelColor?: string | BooleanLike;
color?: string | BooleanLike;
textAlign?: string | BooleanLike;
buttons?: InfernoNode,
readonly className?: string | BooleanLike;
readonly label?: string | InfernoNode | BooleanLike;
readonly labelColor?: string | BooleanLike;
readonly color?: string | BooleanLike;
readonly textAlign?: string | BooleanLike;
readonly buttons?: InfernoNode,
/** @deprecated */
content?: any,
children?: InfernoNode;
verticalAlign?: string;
readonly content?: any,
readonly children?: InfernoNode;
readonly verticalAlign?: string;
};
const LabeledListItem = (props: LabeledListItemProps) => {
@@ -91,7 +91,7 @@ const LabeledListItem = (props: LabeledListItemProps) => {
LabeledListItem.defaultHooks = pureComponentHooks;
type LabeledListDividerProps = {
size?: number;
readonly size?: number;
};
const LabeledListDivider = (props: LabeledListDividerProps) => {
+4 -4
View File
@@ -8,10 +8,10 @@ import { BooleanLike, classes, pureComponentHooks } from 'common/react';
import { Box, BoxProps } from './Box';
export type NoticeBoxProps = BoxProps & {
warning?: BooleanLike;
success?: BooleanLike;
danger?: BooleanLike;
info?: BooleanLike;
readonly warning?: BooleanLike;
readonly success?: BooleanLike;
readonly danger?: BooleanLike;
readonly info?: BooleanLike;
}
export const NoticeBox = (props: NoticeBoxProps) => {
+3 -3
View File
@@ -3,9 +3,9 @@ import { ArgumentsOf } from 'common/types';
import { Component, findDOMfromVNode, InfernoNode, render } from 'inferno';
type PopperProps = {
popperContent: InfernoNode;
options?: ArgumentsOf<typeof createPopper>[2];
additionalStyles?: CSSProperties;
readonly popperContent: InfernoNode;
readonly options?: ArgumentsOf<typeof createPopper>[2];
readonly additionalStyles?: CSSProperties;
};
export class Popper extends Component<PopperProps> {
@@ -10,12 +10,12 @@ import { BoxProps, computeBoxClassName, computeBoxProps } from './Box';
import { CSS_COLORS } from '../constants';
interface ProgressBarProps extends BoxProps {
className?: string;
value: number;
minValue?: number;
maxValue?: number;
ranges?: Record<any, [number, number]>;
color?: any;
readonly className?: string;
readonly value: number;
readonly minValue?: number;
readonly maxValue?: number;
readonly ranges?: Record<any, [number, number]>;
readonly color?: any;
}
export const ProgressBar = (props: ProgressBarProps) => {
+8 -8
View File
@@ -10,16 +10,16 @@ import { addScrollableNode, removeScrollableNode } from '../events';
import { BoxProps, computeBoxClassName, computeBoxProps } from './Box';
export interface SectionProps extends BoxProps {
className?: string;
title?: InfernoNode;
buttons?: InfernoNode;
fill?: boolean;
fitted?: boolean;
scrollable?: boolean;
readonly className?: string;
readonly title?: InfernoNode;
readonly buttons?: InfernoNode;
readonly fill?: boolean;
readonly fitted?: boolean;
readonly scrollable?: boolean;
/** @deprecated This property no longer works, please remove it. */
level?: boolean;
readonly level?: boolean;
/** @deprecated Please use `scrollable` property */
overflowY?: any;
readonly overflowY?: any;
}
export class Section extends Component<SectionProps> {
+14 -14
View File
@@ -11,20 +11,20 @@ import { DraggableControl } from './DraggableControl';
import { NumberInput } from './NumberInput';
interface SliderProps extends BoxProps {
animated?: BooleanLike;
color?: string;
value: number;
unit?: string;
minValue: number;
maxValue: number;
fillValue?: number;
ranges?: Record<string, [number, number]>;
step?: number;
stepPixelSize?: number;
format?: (n: number) => number;
suppressFlicker?: number;
onChange?: Function;
onDrag?: Function;
readonly animated?: BooleanLike;
readonly color?: string;
readonly value: number;
readonly unit?: string;
readonly minValue: number;
readonly maxValue: number;
readonly fillValue?: number;
readonly ranges?: Record<string, [number, number]>;
readonly step?: number;
readonly stepPixelSize?: number;
readonly format?: (n: number) => number;
readonly suppressFlicker?: number;
readonly onChange?: Function;
readonly onDrag?: Function;
}
export const Slider = (props: SliderProps) => {
+5 -5
View File
@@ -7,11 +7,11 @@ import { BooleanLike, classes } from "common/react";
import { Box, BoxProps } from "./Box";
interface SpriteProps extends BoxProps {
sheet: string;
sizeKey: string;
prefix?: string;
sprite: string;
fill?: BooleanLike;
readonly sheet: string;
readonly sizeKey: string;
readonly prefix?: string;
readonly sprite: string;
readonly fill?: BooleanLike;
}
export const Sprite = (props: SpriteProps) => {
+4 -4
View File
@@ -9,8 +9,8 @@ import { RefObject } from 'inferno';
import { computeFlexClassName, computeFlexItemClassName, computeFlexItemProps, computeFlexProps, FlexItemProps, FlexProps } from './Flex';
type StackProps = FlexProps & {
vertical?: boolean;
fill?: boolean;
readonly vertical?: boolean;
readonly fill?: boolean;
};
export const Stack = (props: StackProps) => {
@@ -35,7 +35,7 @@ export const Stack = (props: StackProps) => {
};
type StackItemProps = FlexProps & {
innerRef?: RefObject<HTMLDivElement>,
readonly innerRef?: RefObject<HTMLDivElement>,
};
const StackItem = (props: StackItemProps) => {
@@ -56,7 +56,7 @@ const StackItem = (props: StackItemProps) => {
Stack.Item = StackItem;
type StackDividerProps = FlexItemProps & {
hidden?: boolean;
readonly hidden?: boolean;
};
const StackDivider = (props: StackDividerProps) => {
+11 -4
View File
@@ -2,9 +2,9 @@ import { createPopper, Placement, VirtualElement } from '@popperjs/core';
import { Component, findDOMfromVNode, InfernoNode, render } from 'inferno';
type TooltipProps = {
children?: InfernoNode;
content: InfernoNode;
position?: Placement;
readonly children?: InfernoNode;
readonly content: InfernoNode;
readonly position?: Placement;
};
type TooltipState = {
@@ -20,13 +20,20 @@ const DEFAULT_OPTIONS = {
],
};
const NULL_RECT = {
const NULL_RECT_INTERNAL = {
width: 0,
height: 0,
top: 0,
right: 0,
bottom: 0,
left: 0,
x: 0,
y: 0,
};
const NULL_RECT = {
...NULL_RECT_INTERNAL,
toJSON: () => JSON.stringify(NULL_RECT_INTERNAL),
};
export class Tooltip extends Component<TooltipProps, TooltipState> {
@@ -5,9 +5,9 @@ import { FullGasContext } from "./common/Atmos";
interface AtmosGuideProps {
// gas context to pull from - must be full
gasContext: FullGasContext
readonly gasContext: FullGasContext
// should we render as a section or modal? true for section.
embedded?: boolean;
readonly embedded?: boolean;
}
export const AtmosGuide = (props: AtmosGuideProps) => {
@@ -289,6 +289,7 @@ const BodyScannerMainAbnormalities = props => {
{abnormalities.map((a, i) => {
if (occupant[a[0]]) {
return (
// eslint-disable-next-line react/jsx-key
<Box color={a[1]} bold={a[1] === "bad"}>
{a[2](occupant)}
</Box>
@@ -90,6 +90,7 @@ export const BountyBoardContent = (props, context) => {
title="Request Applicants">
{applicants?.map(applicant => (
applicant.request_id === request.acc_number && (
// eslint-disable-next-line react/jsx-key
<Flex>
<Flex.Item
grow={1}
+1 -1
View File
@@ -32,7 +32,7 @@ const toMassPaintFormat = (data: PointData[]) => {
class PaintCanvas extends Component<PaintCanvasProps> {
canvasRef: RefObject<HTMLCanvasElement>;
baseImageData: Color[][]
baseImageData: Color[][];
modifiedElements: PointData[];
onCanvasModified: (data: PointData[]) => void;
drawing: boolean;
+1 -1
View File
@@ -92,7 +92,7 @@ export class Changelog extends Component {
self.setData(yaml.load(result, { schema: yaml.CORE_SCHEMA }));
}
});
}
};
componentDidMount() {
const { data: { dates = [] } } = useBackend(this.context);
@@ -60,18 +60,18 @@ export enum LoadoutCustomizations {
}
interface LoadoutProps extends SectionProps {
gearContext: LoadoutContext;
readonly gearContext: LoadoutContext;
// ids
gearAllowed: string[];
gearData: LoadoutData;
slotChangeAct?: (index: number) => void;
slotRenameAct?: (index: number, name?: string) => void;
toggleAct?: (id: string) => void;
customizeNameAct?: (id: string, name?: string) => void;
customizeDescAct?: (id: string, desc?: string) => void;
customizeColorAct?: (id: string, color?: ByondAtomColor) => void;
tweakAct?: (id: string, tweakId: string) => void;
clearSlotAct?: (index: number) => void;
readonly gearAllowed: string[];
readonly gearData: LoadoutData;
readonly slotChangeAct?: (index: number) => void;
readonly slotRenameAct?: (index: number, name?: string) => void;
readonly toggleAct?: (id: string) => void;
readonly customizeNameAct?: (id: string, name?: string) => void;
readonly customizeDescAct?: (id: string, desc?: string) => void;
readonly customizeColorAct?: (id: string, color?: ByondAtomColor) => void;
readonly tweakAct?: (id: string, tweakId: string) => void;
readonly clearSlotAct?: (index: number) => void;
}
export const CharacterLoadout = (props: LoadoutProps, context) => {
@@ -213,13 +213,13 @@ export const CharacterLoadout = (props: LoadoutProps, context) => {
};
interface CharacterLoadoutEntryProps {
entry: LoadoutEntry;
selected: LoadoutSelected | null;
toggleAct?: (id: string) => void;
customizeNameAct?: (id: string, name?: string) => void;
customizeDescAct?: (id: string, desc?: string) => void;
customizeColorAct?: (id: string, color?: ByondAtomColor) => void;
tweakAct?: (id: string, tweakId: string) => void;
readonly entry: LoadoutEntry;
readonly selected: LoadoutSelected | null;
readonly toggleAct?: (id: string) => void;
readonly customizeNameAct?: (id: string, name?: string) => void;
readonly customizeDescAct?: (id: string, desc?: string) => void;
readonly customizeColorAct?: (id: string, color?: ByondAtomColor) => void;
readonly tweakAct?: (id: string, tweakId: string) => void;
}
interface CharacterLoadoutEntryState {
@@ -1,4 +1,5 @@
import { BooleanLike } from "common/react";
import { BooleanLike } from "../../common/react";
import { useBackend, useSharedState } from "../backend";
import { Button, LabeledList, NoticeBox, NumberInput, ProgressBar, Section, Stack } from "../components";
import { Window } from "../layouts";
@@ -161,7 +162,10 @@ export const ChemDispenser = (props, context) => {
))
}
</Section>
<Section title="Synthesis">
<Section title="Synthesis" buttons={
<Button icon="question"onClick={() =>
act('guide')} />
}>
{sortedReagents.map((reagent) => (
<Button
icon="tint"
@@ -189,12 +189,12 @@ export class CircuitSignalHandler
}
type EntryProps = {
onRemove: (e: MouseEvent) => any;
onEnter: (e: MouseEvent, value: string) => any;
onSetOption?: (type: string) => any;
name: string;
current_option: string;
options?: string[];
readonly onRemove: (e: MouseEvent) => any;
readonly onEnter: (e: MouseEvent, value: string) => any;
readonly onSetOption?: (type: string) => any;
readonly name: string;
readonly current_option: string;
readonly options?: string[];
}
const Entry = (props: EntryProps, context) => {
@@ -38,6 +38,7 @@ export const CookingAppliance = (props, context) => {
{our_contents.map((content, i) => {
if (content.empty) {
return (
// eslint-disable-next-line react/jsx-key
<LabeledList.Item label={"Slot #" + (i + 1)} >
<Button
onClick={() => act("slot", { slot: i + 1 })}>
@@ -120,11 +120,11 @@ export const DecalPainter = (props, context) => {
};
type IconButtonParams = {
decal: string;
dir: number;
color: string;
label: string;
selected: boolean;
readonly decal: string;
readonly dir: number;
readonly color: string;
readonly label: string;
readonly selected: boolean;
};
const IconButton = (props: IconButtonParams, context) => {
@@ -208,7 +208,7 @@ const SignalLostModal = (props, context) => {
};
const DroneSelectionSection = (props: {
all_drones: Array<DroneBasicData>,
readonly all_drones: Array<DroneBasicData>,
}, context) => {
const { act } = useBackend<ExodroneConsoleData>(context);
const { all_drones } = props;
@@ -305,8 +305,8 @@ const ToolSelectionModal = (props, context) => {
};
const EquipmentBox = (props: {
cargo: CargoData,
drone: DroneData,
readonly cargo: CargoData,
readonly drone: DroneData,
}, context) => {
const { act, data } = useBackend<ExodroneConsoleData>(context);
const { all_tools = {} } = data;
@@ -389,7 +389,7 @@ const EquipmentBox = (props: {
};
const EquipmentGrid = (props: {
drone: ActiveDrone & DroneData,
readonly drone: ActiveDrone & DroneData,
}, context) => {
const { act } = useBackend<ExodroneConsoleData>(context);
const {
@@ -455,8 +455,8 @@ const EquipmentGrid = (props: {
};
const DroneStatus = (props: {
drone_integrity: number,
drone_max_integrity: number,
readonly drone_integrity: number,
readonly drone_max_integrity: number,
}, context) => {
const {
drone_integrity,
@@ -506,8 +506,8 @@ const NoSiteDimmer = () => {
};
const TravelTargetSelectionScreen = (props: {
drone: (DroneExploration | DroneIdle | DroneTravel) & DroneData,
showCancelButton?: boolean,
readonly drone: (DroneExploration | DroneIdle | DroneTravel) & DroneData,
readonly showCancelButton?: boolean,
}, context) => {
// List of sites and eta travel times to each
const { act, data } = useBackend<ExodroneConsoleData>(context);
@@ -635,7 +635,7 @@ const TravelTargetSelectionScreen = (props: {
};
const TravelDimmer = (props: {
drone: DroneTravel,
readonly drone: DroneTravel,
}, context) => {
const { travel_time_left } = props.drone;
return (
@@ -659,7 +659,7 @@ const TravelDimmer = (props: {
};
const TimeoutScreen = (props: {
drone: DroneBusy,
readonly drone: DroneBusy,
}) => {
const {
wait_time_left,
@@ -687,7 +687,7 @@ const TimeoutScreen = (props: {
};
const ExplorationScreen = (props: {
drone: DroneExploration & DroneData,
readonly drone: DroneExploration & DroneData,
}, context) => {
const { act } = useBackend(context);
const { drone } = props;
@@ -747,8 +747,8 @@ const ExplorationScreen = (props: {
};
const EventScreen = (props: {
drone: DroneData,
event: FullEventData,
readonly drone: DroneData,
readonly event: FullEventData,
}, context) => {
const { act } = useBackend(context);
const { drone, event } = props;
@@ -807,10 +807,10 @@ const EventScreen = (props: {
};
export const AdventureScreen = (props: {
adventure_data: AdventureData,
drone_integrity: number,
drone_max_integrity: number,
hide_status?: boolean,
readonly adventure_data: AdventureData,
readonly drone_integrity: number,
readonly drone_max_integrity: number,
readonly hide_status?: boolean,
}, context) => {
const { act } = useBackend(context);
const {
@@ -864,7 +864,7 @@ export const AdventureScreen = (props: {
};
const DroneScreen = (props: {
drone: ActiveDrone & DroneData,
readonly drone: ActiveDrone & DroneData,
}) => {
const { drone } = props;
+6 -6
View File
@@ -29,12 +29,12 @@ enum ReelingState {
}
type FishingMinigameProps = {
difficulty: number;
fish_ai: FishAI;
special_rules: SpecialRule[];
background: string;
win: (perfect: boolean) => void;
lose: () => void;
readonly difficulty: number;
readonly fish_ai: FishAI;
readonly special_rules: SpecialRule[];
readonly background: string;
readonly win: (perfect: boolean) => void;
readonly lose: () => void;
};
type FishingMinigameState = {
+4 -4
View File
@@ -18,10 +18,10 @@ type FishingRodData = {
};
type FishingSlotProps = {
name: string;
slot: string;
current_item_name: string | null;
current_item_icon: string | null;
readonly name: string;
readonly slot: string;
readonly current_item_name: string | null;
readonly current_item_icon: string | null;
};
const FishingRodSlot = (props: FishingSlotProps, context) => {
@@ -22,7 +22,7 @@ type HotkeysHelpData = {
};
type KeyBindingBoxProps = {
keycode: string,
readonly keycode: string,
}
type ModkeyProps = {
@@ -119,6 +119,7 @@ export const HotkeysHelp = (_, context) => {
</Box>
</Tooltip>
) : (
// eslint-disable-next-line react/jsx-key
<Box p={1} m={1} inline className="HotkeysHelp__pill">
{binding.name}
</Box>
+2 -2
View File
@@ -44,8 +44,8 @@ interface JoinMenuData {
}
interface JoinFactionProps {
faction: string;
departments: {
readonly faction: string;
readonly departments: {
[key: string]: JoinableJob[]
}
}
@@ -3,7 +3,7 @@ import { useBackend } from '../../backend';
import { Button, LabeledList, Stack, Section, ProgressBar } from '../../components';
import { MechWeapon, OperatorData } from './data';
export const ArmPane=(props:{weapon:MechWeapon}, context) => {
export const ArmPane=(props:{readonly weapon:MechWeapon}, context) => {
const { act, data } = useBackend<OperatorData>(context);
const {
name,
@@ -70,7 +70,7 @@ export const ArmPane=(props:{weapon:MechWeapon}, context) => {
);
};
const BallisticStats = (props: {weapon: MechWeapon}, context) => {
const BallisticStats = (props: {readonly weapon: MechWeapon}, context) => {
const { act, data } = useBackend<OperatorData>(context);
const {
isballisticweapon,
@@ -120,7 +120,7 @@ const MECHA_SNOWFLAKE_ID_SYRINGE = "syringe_snowflake";
const MECHA_SNOWFLAKE_ID_MODE = "mode_snowflake";
// Handles all the snowflake buttons and whatever
const Snowflake = (props: {weapon: MechWeapon}, context) => {
const Snowflake = (props: {readonly weapon: MechWeapon}, context) => {
const {
snowflake,
} = props.weapon;
@@ -136,7 +136,7 @@ const Snowflake = (props: {weapon: MechWeapon}, context) => {
}
};
const SnowflakeSleeper = (props: {weapon: MechWeapon}, context) => {
const SnowflakeSleeper = (props: {readonly weapon: MechWeapon}, context) => {
const { act, data } = useBackend<OperatorData>(context);
const {
patient,
@@ -181,7 +181,7 @@ const SnowflakeSleeper = (props: {weapon: MechWeapon}, context) => {
}
};
const SnowflakeSyringe = (props: {weapon: MechWeapon}, context) => {
const SnowflakeSyringe = (props: {readonly weapon: MechWeapon}, context) => {
const { act, data } = useBackend<OperatorData>(context);
const {
mode,
@@ -220,7 +220,7 @@ const SnowflakeSyringe = (props: {weapon: MechWeapon}, context) => {
);
};
const SnowflakeExtinguisher = (props: {weapon: MechWeapon}, context) => {
const SnowflakeExtinguisher = (props: {readonly weapon: MechWeapon}, context) => {
const {
reagents,
total_reagents,
@@ -236,7 +236,7 @@ const SnowflakeExtinguisher = (props: {weapon: MechWeapon}, context) => {
);
};
const SnowflakeMode = (props: {weapon: MechWeapon}, context) => {
const SnowflakeMode = (props: {readonly weapon: MechWeapon}, context) => {
const { act, data } = useBackend<OperatorData>(context);
const {
mode,
@@ -39,7 +39,7 @@ const MECHA_SNOWFLAKE_ID_EJECTOR = "ejector_snowflake";
const MECHA_SNOWFLAKE_ID_EXTINGUISHER = "extinguisher_snowflake";
// Handles all the snowflake buttons and whatever
const Snowflake = (props: {module: MechaUtility}, context) => {
const Snowflake = (props: {readonly module: MechaUtility}, context) => {
const {
snowflake,
} = props.module;
@@ -53,7 +53,7 @@ const Snowflake = (props: {module: MechaUtility}, context) => {
}
};
const SnowflakeEjector = (props: {module: MechaUtility}, context) => {
const SnowflakeEjector = (props: {readonly module: MechaUtility}, context) => {
const { act, data } = useBackend<OperatorData>(context);
const {
cargo,
@@ -76,7 +76,7 @@ const SnowflakeEjector = (props: {module: MechaUtility}, context) => {
);
};
const SnowflakeExtinguisher = (props: {module: MechaUtility}, context) => {
const SnowflakeExtinguisher = (props: {readonly module: MechaUtility}, context) => {
const { act, data } = useBackend<OperatorData>(context);
return (
<>
+5 -5
View File
@@ -49,14 +49,14 @@ type OrbitData = {
}
type BasicSectionProps = {
searchText: string,
source: OrbitList[],
title: string,
readonly searchText: string,
readonly source: OrbitList[],
readonly title: string,
}
type OrbitedButtonProps = {
color: string,
thing: OrbitList,
readonly color: string,
readonly thing: OrbitList,
}
const BasicSection = (props: BasicSectionProps, context: any) => {
@@ -74,8 +74,10 @@ export const OvermapEnginesContent = (props, context) => {
</Box>
{engine.eng_status.map(status => {
if (Array.isArray(status)) {
// eslint-disable-next-line react/jsx-key
return <Box color={status[1]}>{status[0]}</Box>;
} else {
// eslint-disable-next-line react/jsx-key
return <Box>{status}</Box>;
}
})}
+7 -7
View File
@@ -45,16 +45,16 @@ type Virus = {
};
type VirusDisplayProps = {
virus: Virus;
readonly virus: Virus;
};
type VirusInfoProps = {
virus: Virus;
readonly virus: Virus;
};
type TabsProps = {
tab: number;
tabHandler: (tab: number) => void;
readonly tab: number;
readonly tabHandler: (tab: number) => void;
};
type Symptom = {
@@ -70,11 +70,11 @@ type Symptom = {
};
type SymptomDisplayProps = {
symptoms: Symptom[];
readonly symptoms: Symptom[];
};
type SymptomInfoProps = {
symptom: Symptom;
readonly symptom: Symptom;
};
type Threshold = {
@@ -83,7 +83,7 @@ type Threshold = {
};
type ThresholdDisplayProps = {
thresholds: Threshold[];
readonly thresholds: Threshold[];
};
export const Pandemic = (_, context) => {
@@ -228,9 +228,9 @@ export const PersonalCrafting = (props, context) => {
};
type CraftingListProps = {
recipes: Recipe[];
readonly recipes: Recipe[];
// eslint-disable-next-line react/no-unused-prop-types
compact?: boolean;
readonly compact?: boolean;
};
const CraftingList = (props: CraftingListProps, context) => {
@@ -34,8 +34,8 @@ for (const antagKey of requireAntag.keys()) {
}
const AntagSelection = (props: {
antagonists: Antagonist[],
name: string,
readonly antagonists: Antagonist[],
readonly name: string,
}, context) => {
const { act, data } = useBackend<PreferencesMenuData>(context);
const className = "PreferencesMenu__Antags__antagSelection";
@@ -19,9 +19,9 @@ enum Page {
}
const CharacterProfiles = (props: {
activeSlot: number,
onClick: (index: number) => void,
profiles: (string | null)[],
readonly activeSlot: number,
readonly onClick: (index: number) => void,
readonly profiles: (string | null)[],
}) => {
const { profiles } = props;
@@ -1,8 +1,8 @@
import { ByondUi } from "../../components";
export const CharacterPreview = (props: {
height: string,
id: string,
readonly height: string,
readonly id: string,
}) => {
return (<ByondUi
width="220px"
@@ -8,7 +8,7 @@ import { GamePreferencesSelectedPage, PreferencesMenuData } from "./data";
import { exhaustiveCheck } from "common/exhaustive";
export const GamePreferenceWindow = (props: {
startingPage?: GamePreferencesSelectedPage,
readonly startingPage?: GamePreferencesSelectedPage,
}, context) => {
const { act, data } = useBackend<PreferencesMenuData>(context);
@@ -17,11 +17,11 @@ const sortJobs = (
const PRIORITY_BUTTON_SIZE = "18px";
const PriorityButton = (props: {
name: string,
color: string,
modifier?: string,
enabled: boolean,
onClick: () => void,
readonly name: string,
readonly color: string,
readonly modifier?: string,
readonly enabled: boolean,
readonly onClick: () => void,
}) => {
const className = `PreferencesMenu__Jobs__departments__priority`;
@@ -107,9 +107,9 @@ const PriorityHeaders = () => {
};
const PriorityButtons = (props: {
createSetPriority: CreateSetPriority,
isOverflow: boolean,
priority: JobPriority,
readonly createSetPriority: CreateSetPriority,
readonly isOverflow: boolean,
readonly priority: JobPriority,
}) => {
const { createSetPriority, isOverflow, priority } = props;
@@ -178,9 +178,9 @@ const PriorityButtons = (props: {
};
const JobRow = (props: {
className?: string,
job: Job,
name: string,
readonly className?: string,
readonly job: Job,
readonly name: string,
}, context) => {
const { data } = useBackend<PreferencesMenuData>(context);
const { className, job, name } = props;
@@ -313,7 +313,7 @@ const Department: SFC<{ department: string}> = (props) => {
// But in order for everything to align, I also need to add the 0.2em padding.
// But also, we can't be aligned with names that break into multiple lines!
const Gap = (props: {
amount: number,
readonly amount: number,
}) => {
// 0.2em comes from the padding-bottom in the department listing
return <Box height={`calc(${props.amount}px + 0.2em)`} />;
@@ -146,7 +146,7 @@ class KeybindingButton extends Component<{
}
const KeybindingName = (props: {
keybinding: Keybinding,
readonly keybinding: Keybinding,
}) => {
const { keybinding } = props;
@@ -173,7 +173,7 @@ KeybindingName.defaultHooks = {
};
const ResetToDefaultButton = (props: {
keybindingId: string,
readonly keybindingId: string,
}, context) => {
const { act } = useBackend<PreferencesMenuData>(context);
@@ -20,11 +20,11 @@ const CLOTHING_SELECTION_WIDTH = 5.4;
const CLOTHING_SELECTION_MULTIPLIER = 5.2;
const CharacterControls = (props: {
handleRotate: () => void,
handleOpenSpecies: () => void,
gender: Gender,
setGender: (gender: Gender) => void,
showGender: boolean,
readonly handleRotate: () => void,
readonly handleOpenSpecies: () => void,
readonly gender: Gender,
readonly setGender: (gender: Gender) => void,
readonly showGender: boolean,
}) => {
return (
<Stack>
@@ -61,13 +61,13 @@ const CharacterControls = (props: {
};
const ChoicedSelection = (props: {
name: string,
catalog: FeatureChoicedServerData,
selected: string,
supplementalFeature?: string,
supplementalValue?: unknown,
onClose: () => void,
onSelect: (value: string) => void,
readonly name: string,
readonly catalog: FeatureChoicedServerData,
readonly selected: string,
readonly supplementalFeature?: string,
readonly supplementalValue?: unknown,
readonly onClose: () => void,
readonly onSelect: (value: string) => void,
}, context) => {
const { act } = useBackend<PreferencesMenuData>(context);
@@ -169,8 +169,8 @@ const ChoicedSelection = (props: {
};
const GenderButton = (props: {
handleSetGender: (gender: Gender) => void,
gender: Gender,
readonly handleSetGender: (gender: Gender) => void,
readonly gender: Gender,
}, context) => {
const [genderMenuOpen, setGenderMenuOpen] = useLocalState(context, "genderMenuOpen", false);
@@ -215,17 +215,17 @@ const GenderButton = (props: {
};
const MainFeature = (props: {
catalog: FeatureChoicedServerData & {
readonly catalog: FeatureChoicedServerData & {
name: string,
supplemental_feature?: string,
},
currentValue: string,
isOpen: boolean,
handleClose: () => void,
handleOpen: () => void,
handleSelect: (newClothing: string) => void,
randomization?: RandomSetting,
setRandomization: (newSetting: RandomSetting) => void,
readonly currentValue: string,
readonly isOpen: boolean,
readonly handleClose: () => void,
readonly handleOpen: () => void,
readonly handleSelect: (newClothing: string) => void,
readonly randomization?: RandomSetting,
readonly setRandomization: (newSetting: RandomSetting) => void,
}, context) => {
const { act, data } = useBackend<PreferencesMenuData>(context);
@@ -331,9 +331,9 @@ const sortPreferences = sortBy<[string, unknown]>(
});
const PreferenceList = (props: {
act: typeof sendAct,
preferences: Record<string, unknown>,
randomizations: Record<string, RandomSetting>,
readonly act: typeof sendAct,
readonly preferences: Record<string, unknown>,
readonly randomizations: Record<string, RandomSetting>,
}) => {
return (
<Stack.Item basis="50%" grow style={{
@@ -393,7 +393,7 @@ const PreferenceList = (props: {
};
export const MainPage = (props: {
openSpecies: () => void,
readonly openSpecies: () => void,
}, context) => {
const { act, data } = useBackend<PreferencesMenuData>(context);
const [currentClothingMenu, setCurrentClothingMenu]
@@ -2,13 +2,13 @@ import { InfernoNode } from "inferno";
import { Button } from "../../components";
export const PageButton = <P extends unknown>(props: {
currentPage: P,
page: P,
otherActivePages?: P[],
readonly currentPage: P,
readonly page: P,
readonly otherActivePages?: P[],
setPage: (page: P) => void,
readonly setPage: (page: P) => void,
children?: InfernoNode,
readonly children?: InfernoNode,
}) => {
const pageIsActive = props.currentPage === props.page
|| (
@@ -15,10 +15,10 @@ const getValueClass = (value: number): string => {
};
const QuirkList = (props: {
quirks: [string, Quirk & {
readonly quirks: [string, Quirk & {
failTooltip?: string;
}][],
onClick: (quirkName: string, quirk: Quirk) => void,
readonly onClick: (quirkName: string, quirk: Quirk) => void,
}) => {
return (
// Stack is not used here for a variety of IE flex bugs
@@ -97,6 +97,7 @@ const QuirkList = (props: {
if (quirk.failTooltip) {
return (
// eslint-disable-next-line react/jsx-key
<Tooltip content={quirk.failTooltip}>
{child}
</Tooltip>
@@ -3,9 +3,9 @@ import { RandomSetting } from "./data";
import { exhaustiveCheck } from "common/exhaustive";
export const RandomizationButton = (props: {
dropdownProps?: Record<string, unknown>,
setValue: (newValue: RandomSetting) => void,
value: RandomSetting,
readonly dropdownProps?: Record<string, unknown>,
readonly setValue: (newValue: RandomSetting) => void,
readonly value: RandomSetting,
}) => {
const {
dropdownProps = {},
@@ -52,10 +52,10 @@ const notIn = function<T> (set: Set<T>) {
};
const FoodList = (props: {
food: Food[],
icon: string,
name: string,
className: string,
readonly food: Food[],
readonly icon: string,
readonly name: string,
readonly className: string,
}) => {
if (props.food.length === 0) {
return null;
@@ -97,7 +97,7 @@ const FoodList = (props: {
};
const Diet = (props: {
diet: Species["diet"],
readonly diet: Species["diet"],
}) => {
if (!props.diet) {
@@ -139,8 +139,8 @@ const Diet = (props: {
};
const SpeciesPerk = (props: {
className: string,
perk: Perk,
readonly className: string,
readonly perk: Perk,
}) => {
const { className, perk } = props;
@@ -170,7 +170,7 @@ const SpeciesPerk = (props: {
};
const SpeciesPerks = (props: {
perks: Species["perks"],
readonly perks: Species["perks"],
}) => {
const { positive, negative, neutral } = props.perks;
@@ -219,8 +219,8 @@ const SpeciesPerks = (props: {
};
const SpeciesPageInner = (props: {
handleClose: () => void,
species: ServerData["species"],
readonly handleClose: () => void,
readonly species: ServerData["species"],
}, context) => {
const { act, data } = useBackend<PreferencesMenuData>(context);
@@ -344,7 +344,7 @@ const SpeciesPageInner = (props: {
};
export const SpeciesPage = (props: {
closeSpecies: () => void,
readonly closeSpecies: () => void,
}) => {
return (
<ServerPreferencesFetcher
@@ -3,8 +3,8 @@ import { Button, Section, Stack } from "../../components";
import { FlexProps } from "../../components/Flex";
type TabbedMenuProps = {
categoryEntries: [string, InfernoNode][],
contentProps?: FlexProps,
readonly categoryEntries: [string, InfernoNode][],
readonly contentProps?: FlexProps,
};
export class TabbedMenu extends Component<TabbedMenuProps> {
@@ -16,10 +16,10 @@ const sortNameWithKeyEntries = sortBy<[string, NameWithKey[]]>(
);
export const MultiNameInput = (props: {
handleClose: () => void,
handleRandomizeName: (nameType: string) => void,
handleUpdateName: (nameType: string, value: string) => void,
names: Record<string, string>,
readonly handleClose: () => void,
readonly handleRandomizeName: (nameType: string) => void,
readonly handleUpdateName: (nameType: string, value: string) => void,
readonly names: Record<string, string>,
}, context) => {
const [currentlyEditingName, setCurrentlyEditingName]
= useLocalState<string | null>(context, "currentlyEditingName", null);
@@ -145,9 +145,9 @@ export const MultiNameInput = (props: {
};
export const NameInput = (props: {
handleUpdateName: (name: string) => void,
name: string,
openMultiNameInput: () => void,
readonly handleUpdateName: (name: string) => void,
readonly name: string,
readonly openMultiNameInput: () => void,
}, context) => {
const [lastNameBeforeEdit, setLastNameBeforeEdit]
= useLocalState<string | null>(context, "lastNameBeforeEdit", null);
@@ -46,12 +46,17 @@ export type FeatureValueProps<
TSending = TReceiving,
TServerData = undefined,
> = {
act: typeof sendAct,
featureId: string,
handleSetValue: (newValue: TSending) => void,
serverData: TServerData | undefined,
shrink?: boolean,
value: TReceiving,
// eslint-disable-next-line react/no-unused-prop-types
readonly act: typeof sendAct,
// eslint-disable-next-line react/no-unused-prop-types
readonly featureId: string,
// eslint-disable-next-line react/no-unused-prop-types
readonly handleSetValue: (newValue: TSending) => void,
// eslint-disable-next-line react/no-unused-prop-types
readonly serverData: TServerData | undefined,
// eslint-disable-next-line react/no-unused-prop-types
readonly shrink?: boolean,
readonly value: TReceiving,
};
export const FeatureColorInput = (props: FeatureValueProps<string>) => {
@@ -147,11 +152,11 @@ const capitalizeFirstLetter = (text: string) => (
);
export const StandardizedDropdown = (props: {
choices: string[],
disabled?: boolean,
displayNames: Record<string, InfernoNode>,
onSetValue: (newValue: string) => void,
value: string,
readonly choices: string[],
readonly disabled?: boolean,
readonly displayNames: Record<string, InfernoNode>,
readonly onSetValue: (newValue: string) => void,
readonly value: string,
}) => {
const {
choices,
@@ -181,7 +186,7 @@ export const StandardizedDropdown = (props: {
export const FeatureDropdownInput = (
props: FeatureValueProps<string, string, FeatureChoicedServerData> & {
disabled?: boolean,
readonly disabled?: boolean,
},
) => {
const serverData = props.serverData;
@@ -290,12 +295,12 @@ export const FeatureNumberInput = (
};
export const FeatureValueInput = (props: {
feature: Feature<unknown>,
featureId: string,
shrink?: boolean,
value: unknown,
readonly feature: Feature<unknown>,
readonly featureId: string,
readonly shrink?: boolean,
readonly value: unknown,
act: typeof sendAct,
readonly act: typeof sendAct,
}, context) => {
const { data } = useBackend<PreferencesMenuData>(context);
@@ -86,6 +86,7 @@ export const RequestKioskContent = (props, context) => {
title="Request Applicants">
{applicants?.map(applicant => (
applicant.request_id === request.acc_number && (
// eslint-disable-next-line react/jsx-key
<Flex>
<Flex.Item
grow={1}
@@ -606,6 +606,7 @@ const ResearchConsoleConstructor = (props, context) => {
{queue.length && queue.map(item => {
if (item.index === 1) {
return (
// eslint-disable-next-line react/jsx-key
<LabeledList.Item label={item.name} labelColor="bad">
{!busy ? (
<Box>
@@ -415,7 +415,7 @@ const ShuttleControlConsoleWeb = (props, context) => {
let sensor = sensors[key];
if (sensor.reading !== -1) {
return (
<LabeledList.Item label={key} color="bad">
<LabeledList.Item key={key} label={key} color="bad">
Unable to get sensor air reading.
</LabeledList.Item>
);
+2 -2
View File
@@ -17,8 +17,8 @@ const getGridSpotKey = (spot: [number, number]): GridSpotKey => {
};
const CornerText = (props: {
align: "left" | "right";
children: string;
readonly align: "left" | "right";
readonly children: string;
}): JSX.Element => {
const { align, children } = props;
@@ -324,7 +324,7 @@ const SupplyConsoleMenuOrderList = (props, context) => {
) : null}>
<LabeledList>
{order.entries.map(field => field.entry ? (
<LabeledList.Item label={field.field} buttons={order_auth ? (
<LabeledList.Item key={field.field} label={field.field} buttons={order_auth ? (
<Button
icon="pen"
content="Edit"
@@ -13,9 +13,9 @@ type Surgery = {
};
type SurgeryInitiatorData = {
selected_zone: BodyZone,
surgeries: Surgery[],
target_name: string,
readonly selected_zone: BodyZone,
readonly surgeries: Surgery[],
readonly target_name: string,
};
const sortSurgeries
@@ -31,7 +31,7 @@ class SurgeryInitiatorInner extends Component<
> {
state = {
selectedSurgeryIndex: 0,
}
};
componentDidMount() {
this.updateSelectedSurgeryIndexState();
+2 -2
View File
@@ -733,7 +733,7 @@ const TechNode = (props, context) => {
const thisExp = experiments[k];
if (thisExp === null || thisExp === undefined) {
return (
<LockedExperiment />
<LockedExperiment key={k} />
);
}
return (
@@ -750,7 +750,7 @@ const TechNode = (props, context) => {
const thisExp = experiments[k];
if (thisExp === null || thisExp === undefined) {
return (
<LockedExperiment />
<LockedExperiment key={k} />
);
}
return (
@@ -151,8 +151,8 @@ const TelecommsServerSelection = (props, context) => {
};
interface TelecommsSelectedServerProps {
server: TelecommsServerSelected;
universal_translate: BooleanLike;
readonly server: TelecommsServerSelected;
readonly universal_translate: BooleanLike;
}
const TelecommsSelectedServer = (props: TelecommsSelectedServerProps, context) => {
@@ -353,7 +353,7 @@ export const TraitorObjectiveDebug = (props, context) => {
};
type ObjectiveBoxProps = {
objective: Objective
readonly objective: Objective
}
const ObjectiveBox = (props: ObjectiveBoxProps, context) => {
@@ -3,11 +3,11 @@ import { useLocalState, useSharedState } from '../../backend';
import { Box, Button, Input, Section, Tabs, NoticeBox, Stack } from '../../components';
type GenericUplinkProps = {
currency?: string | JSX.Element,
categories: string[],
items: Item[],
readonly currency?: string | JSX.Element,
readonly categories: string[],
readonly items: Item[],
handleBuy: (item: Item) => void;
readonly handleBuy: (item: Item) => void;
}
export const GenericUplink = (props: GenericUplinkProps, context) => {
@@ -99,10 +99,10 @@ export type Item<ItemData = {}> = {
}
export type ItemListProps = {
compactMode: BooleanLike,
items: Item[],
readonly compactMode: BooleanLike,
readonly items: Item[],
handleBuy: (item: Item) => void;
readonly handleBuy: (item: Item) => void;
}
const ItemList = (props: ItemListProps, context: any) => {
@@ -26,16 +26,16 @@ export type ObjectiveUiButton = {
}
type ObjectiveMenuProps = {
activeObjectives: Objective[];
potentialObjectives: Objective[];
maximumActiveObjectives: number;
maximumPotentialObjectives: number;
readonly activeObjectives: Objective[];
readonly potentialObjectives: Objective[];
readonly maximumActiveObjectives: number;
readonly maximumPotentialObjectives: number;
handleStartObjective: (objective: Objective) => void;
handleObjectiveAction: (objective: Objective, action: string) => void;
handleObjectiveCompleted: (objective: Objective) => void;
handleObjectiveAbort: (objective: Objective) => void;
handleRequestObjectives: () => void;
readonly handleStartObjective: (objective: Objective) => void;
readonly handleObjectiveAction: (objective: Objective, action: string) => void;
readonly handleObjectiveCompleted: (objective: Objective) => void;
readonly handleObjectiveAbort: (objective: Objective) => void;
readonly handleRequestObjectives: () => void;
}
type ObjectiveMenuState = {
@@ -348,21 +348,21 @@ const ObjectiveFunction = (
};
type ObjectiveElementProps = {
name: string;
reputation: Rank;
description: string;
telecrystalReward: number;
progressionReward: number;
uiButtons?: JSX.Element;
objectiveState: ObjectiveState;
originalProgression: number;
telecrystalPenalty: number;
grow: boolean;
finalObjective: BooleanLike;
canAbort: BooleanLike;
readonly name: string;
readonly reputation: Rank;
readonly description: string;
readonly telecrystalReward: number;
readonly progressionReward: number;
readonly uiButtons?: JSX.Element;
readonly objectiveState: ObjectiveState;
readonly originalProgression: number;
readonly telecrystalPenalty: number;
readonly grow: boolean;
readonly finalObjective: BooleanLike;
readonly canAbort: BooleanLike;
handleCompletion: (event: MouseEvent) => void;
handleAbort: (event: MouseEvent) => void;
readonly handleCompletion: (event: MouseEvent) => void;
readonly handleAbort: (event: MouseEvent) => void;
}
const ObjectiveElement = (props: ObjectiveElementProps, context) => {
@@ -21,20 +21,22 @@ export enum AccessListSet {
}
export interface AccessListProps {
access: Array<Access>, // all available accesses
readonly access: Array<Access>, // all available accesses
// override: what accesses to show. must be subset of access.
accessShown?: AccessId[],
uid: string, // must be unique in a window, to avoid localstate collisions.
fill?: boolean,
readonly accessShown?: AccessId[],
// must be unique in a window, to avoid localstate collisions.
// eslint-disable-next-line react/no-unused-prop-types
readonly uid: string,
readonly fill?: boolean,
}
interface AccessListSelectProps extends AccessListProps {
select?(id: AccessId): void,
selected: AccessId,
readonly selected: AccessId,
}
interface AccessListModProps extends AccessListProps {
selected: Array<AccessId>,
readonly selected: Array<AccessId>,
set?(id: AccessId): void,
grant?(category?: string): void,
deny?(category?: string): void,
@@ -43,8 +45,8 @@ interface AccessListModProps extends AccessListProps {
interface AccessListAuthProps extends AccessListProps {
set?(id: AccessId, mode: AccessListSet): void,
wipe?(category?: string): void,
req_access?: Array<AccessId>,
req_one_access?: Array<AccessId>,
readonly req_access?: Array<AccessId>,
readonly req_one_access?: Array<AccessId>,
}
export type AccessId = number;
@@ -88,7 +88,7 @@ export interface AtmosAnalyzerResults {
}
interface AtmosAnalysisProps extends SectionProps {
results: AtmosAnalyzerResults;
readonly results: AtmosAnalyzerResults;
}
export const AtmosAnalysis = (props: AtmosAnalysisProps) => {
@@ -121,11 +121,11 @@ export const AtmosAnalysis = (props: AtmosAnalysisProps) => {
//* Filtering
interface AtmosFilterListProps extends SectionProps {
gasContext: GasContext;
selectedGroups: AtmosGasGroups;
selectedIds: AtmosGasIDs;
selectGroup?: (group: AtmosGasGroupFlags, filter: boolean) => void;
selectId?: (id: AtmosGasID, filter: boolean) => void;
readonly gasContext: GasContext;
readonly selectedGroups: AtmosGasGroups;
readonly selectedIds: AtmosGasIDs;
readonly selectGroup?: (group: AtmosGasGroupFlags, filter: boolean) => void;
readonly selectId?: (id: AtmosGasID, filter: boolean) => void;
}
export const AtmosFilterList = (props: AtmosFilterListProps) => {
@@ -184,9 +184,9 @@ export interface AtmosTank {
}
interface AtmosTankSlotProps extends SectionProps {
ejectAct?: () => void;
canEject?: boolean;
tank: AtmosTank | null;
readonly ejectAct?: () => void;
readonly canEject?: boolean;
readonly tank: AtmosTank | null;
}
export const AtmosTankSlot = (props: AtmosTankSlotProps, context) => {
@@ -15,13 +15,13 @@ export enum AtmosComponentUIFlags {
export interface AtmosComponentControlProps extends SectionProps {
// data
data: AtmosComponentData;
readonly data: AtmosComponentData;
// power toggle
togglePowerAct?: (on: boolean) => void;
readonly togglePowerAct?: (on: boolean) => void;
// set target maximum power draw
setPowerLimitAct?: (watts: number) => void;
readonly setPowerLimitAct?: (watts: number) => void;
// additional entries
additionalListItems?: InfernoNode;
readonly additionalListItems?: InfernoNode;
}
export const AtmosComponentControl = (props: AtmosComponentControlProps, context) => {
@@ -68,11 +68,11 @@ export interface AtmosComponentData {
}
export interface AtmosComponentProps extends ComponentProps {
minumumHeight?: number;
minumumWidth?: number;
additionalListItems?: InfernoNode;
readonly minumumHeight?: number;
readonly minumumWidth?: number;
readonly additionalListItems?: InfernoNode;
// title
title: string;
readonly title: string;
}
export const AtmosComponent = (props: AtmosComponentProps, context) => {
@@ -18,13 +18,13 @@ enum AtmosPortableUIFlags {
interface AtmosPortableControlProps {
// portable data
data: AtmosPortableData;
readonly data: AtmosPortableData;
// toggle on/off act
toggleAct?: () => void;
readonly toggleAct?: () => void;
// set flow act
setFlowAct?: (amt: number) => void;
readonly setFlowAct?: (amt: number) => void;
// any additional list items
additionalListItems?: InfernoNode;
readonly additionalListItems?: InfernoNode;
}
export const AtmosPortableControl = (props: AtmosPortableControlProps, context) => {
@@ -130,10 +130,10 @@ export interface AtmosPortableData {
}
interface AtmosPortableProps extends ComponentProps{
minimumHeight?: number;
minimumWidth?: number;
name: string;
additionalListItems?: InfernoNode;
readonly minimumHeight?: number;
readonly minimumWidth?: number;
readonly name: string;
readonly additionalListItems?: InfernoNode;
}
export const AtmosPortable = (props: AtmosPortableProps, context) => {
@@ -90,10 +90,10 @@ export type ByondAtomColor =
ByondColorMatrixRGBC;
interface ColorPickerProps extends BoxProps {
allowMatrix?: boolean;
allowAlpha?: boolean;
currentColor: ByondAtomColor;
setColor: (ByondAtomColor) => void;
readonly allowMatrix?: boolean;
readonly allowAlpha?: boolean;
readonly currentColor: ByondAtomColor;
readonly setColor: (ByondAtomColor) => void;
}
interface ColorPickerState {
@@ -12,14 +12,14 @@ export type Gasmix = {
};
type GasmixParserProps = {
gasmix: Gasmix;
gasesOnClick?: (gas_id: string) => void;
temperatureOnClick?: () => void;
volumeOnClick?: () => void;
pressureOnClick?: () => void;
reactionOnClick?: (reaction_id: string) => void;
readonly gasmix: Gasmix;
readonly gasesOnClick?: (gas_id: string) => void;
readonly temperatureOnClick?: () => void;
readonly volumeOnClick?: () => void;
readonly pressureOnClick?: () => void;
readonly reactionOnClick?: (reaction_id: string) => void;
// Whether we need to show the number of the reaction or not
detailedReactions?: boolean;
readonly detailedReactions?: boolean;
};
export const GasmixParser = (props: GasmixParserProps, context) => {
@@ -104,12 +104,14 @@ export const GasmixParser = (props: GasmixParserProps, context) => {
{reactions.length
? reactions.map((reaction) =>
reactionOnClick ? (
// eslint-disable-next-line react/jsx-key
<Box mb="0.5em">
<Button
content={reaction[1]}
onClick={() => reactionOnClick(reaction[0])}
/>
</Box>
// eslint-disable-next-line react/jsx-key
) : (<div>{reaction[1]}</div>)
)
: 'No reactions detected'}
@@ -24,8 +24,8 @@ const IDCARD_BLANK = {
};
export interface IDSlotProps {
card: IDCard;
onClick: (e) => void;
readonly card: IDCard;
readonly onClick: (e) => void;
}
export const IDSlot = (props: IDSlotProps, context) => {

Some files were not shown because too many files have changed in this diff Show More