mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-24 05:07:18 +01:00
tgui reagent guidebook & tgui updates (#6161)
Co-authored-by: silicons <no@you.cat>
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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),
|
||||
))
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
Vendored
-768
File diff suppressed because one or more lines are too long
Vendored
+823
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -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) {
|
||||
|
||||
Vendored
+5
-5
@@ -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`);
|
||||
|
||||
Vendored
+4
-1
@@ -2,5 +2,8 @@
|
||||
"name": "eslint",
|
||||
"version": "7.32.0-sdk",
|
||||
"main": "./lib/api.js",
|
||||
"type": "commonjs"
|
||||
"type": "commonjs",
|
||||
"bin": {
|
||||
"eslint": "./bin/eslint.js"
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,5 +1,5 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "common",
|
||||
"version": "4.3.0"
|
||||
"version": "4.3.1"
|
||||
}
|
||||
|
||||
@@ -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,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,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "tgui-panel",
|
||||
"version": "4.3.0",
|
||||
"version": "4.3.1",
|
||||
"dependencies": {
|
||||
"common": "workspace:*",
|
||||
"dompurify": "^2.3.1",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -13,7 +13,7 @@ export class FitText extends Component<{
|
||||
ref: RefObject<HTMLDivElement> = createRef();
|
||||
state = {
|
||||
fontSize: 0,
|
||||
}
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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,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) => {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 (
|
||||
<>
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
})}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user