diff --git a/code/__defines/_reagents_ch.dm b/code/__defines/_reagents_ch.dm index 02eda658ef..0a370625be 100644 --- a/code/__defines/_reagents_ch.dm +++ b/code/__defines/_reagents_ch.dm @@ -93,8 +93,9 @@ #define REAGENT_ID_SITONMYFACE "sitonmyface" #define REAGENT_HACHI "Hachi" #define REAGENT_ID_HACHI "hachi" -#define REAGENT_FRESHTEA "Green tea" +#define REAGENT_FRESHTEA "Refreshing tea" #define REAGENT_ID_FRESHTEA "freshtea" +#define REAGENT_FRESHGREENTEA "Refreshing green tea" #define REAGENT_ID_FRESHTEAGREEN "freshteagreen" #define REAGENT_TEAMUSH "Tea mush" #define REAGENT_ID_TEAMUSH "teamush" diff --git a/code/__defines/is_helpers.dm b/code/__defines/is_helpers.dm index bad9873191..5bd4a68a53 100644 --- a/code/__defines/is_helpers.dm +++ b/code/__defines/is_helpers.dm @@ -51,6 +51,7 @@ #define isalien(A) istype(A, /mob/living/carbon/alien) #define isbrain(A) istype(A, /mob/living/carbon/brain) #define ishuman(A) istype(A, /mob/living/carbon/human) +#define ismannequin(A) istype(A, /mob/living/carbon/human/dummy/mannequin) #define issilicon(A) istype(A, /mob/living/silicon) #define isAI(A) istype(A, /mob/living/silicon/ai) diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index e1c368e7c0..3a24555e96 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -157,6 +157,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_SKYBOX -30 //Visual only, irrelevant to gameplay, but needs to be late enough to have overmap populated fully #define INIT_ORDER_TICKER -50 #define INIT_ORDER_MAPRENAME -60 //Initiating after Ticker to ensure everything is loaded and everything we rely on us working +#define INIT_ORDER_WIKI -61 #define INIT_ORDER_STATPANELS -98 #define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init. diff --git a/code/__defines/wiki.dm b/code/__defines/wiki.dm new file mode 100644 index 0000000000..5e9926cb89 --- /dev/null +++ b/code/__defines/wiki.dm @@ -0,0 +1,3 @@ +#define WIKI_SPOILER 0x1 +#define WIKI_FOOD 0x2 +#define WIKI_DRINK 0x4 diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index ed7c821f67..4018dc27ce 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -1036,18 +1036,18 @@ Turf and target are seperate in case you want to teleport some distance from a t /proc/parse_zone(zone) - if(zone == "r_hand") return "right hand" - else if (zone == "l_hand") return "left hand" - else if (zone == "l_arm") return "left arm" - else if (zone == "r_arm") return "right arm" - else if (zone == "l_leg") return "left leg" - else if (zone == "r_leg") return "right leg" - else if (zone == "l_foot") return "left foot" - else if (zone == "r_foot") return "right foot" - else if (zone == "l_hand") return "left hand" - else if (zone == "r_hand") return "right hand" - else if (zone == "l_foot") return "left foot" - else if (zone == "r_foot") return "right foot" + if(zone == BP_R_HAND) return "right hand" + else if (zone == BP_L_HAND) return "left hand" + else if (zone == BP_L_ARM) return "left arm" + else if (zone == BP_R_ARM) return "right arm" + else if (zone == BP_L_LEG) return "left leg" + else if (zone == BP_R_LEG) return "right leg" + else if (zone == BP_L_FOOT) return "left foot" + else if (zone == BP_R_FOOT) return "right foot" + else if (zone == BP_L_HAND) return "left hand" + else if (zone == BP_R_HAND) return "right hand" + else if (zone == BP_L_FOOT) return "left foot" + else if (zone == BP_R_FOOT) return "right foot" else return zone /proc/get(atom/loc, type) diff --git a/code/controllers/subsystems/internal_wiki.dm b/code/controllers/subsystems/internal_wiki.dm new file mode 100644 index 0000000000..22ef11d58d --- /dev/null +++ b/code/controllers/subsystems/internal_wiki.dm @@ -0,0 +1,1407 @@ +/* + This is a self assembled wiki for chemical reagents, food recipies, + and other information that should be assembled from game files. +*/ + +SUBSYSTEM_DEF(internal_wiki) + name = "Wiki" + wait = 1 + init_order = INIT_ORDER_WIKI + flags = SS_NO_FIRE + + VAR_PRIVATE/list/pages = list() + + VAR_PRIVATE/list/ores = list() + VAR_PRIVATE/list/materials = list() + VAR_PRIVATE/list/smashers = list() + + VAR_PRIVATE/list/appliance_list = list("Simple","Microwave","Fryer","Oven","Grill","Candy Maker","Cereal Maker") + VAR_PRIVATE/list/catalog_list = list() + VAR_PRIVATE/list/drinkreact = list() + VAR_PRIVATE/list/chemreact = list() + VAR_PRIVATE/list/botseeds = list() + + VAR_PRIVATE/list/foodrecipe = list() + + VAR_PRIVATE/list/catalogs = list() + + VAR_PRIVATE/list/searchcache_ore = list() + VAR_PRIVATE/list/searchcache_material = list() + VAR_PRIVATE/list/searchcache_smasher = list() + VAR_PRIVATE/list/searchcache_foodrecipe = list() + VAR_PRIVATE/list/searchcache_drinkreact = list() + VAR_PRIVATE/list/searchcache_chemreact = list() + VAR_PRIVATE/list/searchcache_catalogs = list() + VAR_PRIVATE/list/searchcache_botseeds = list() + + VAR_PRIVATE/list/spoiler_entries = list() + + VAR_PRIVATE/max_donation = 100000 + VAR_PRIVATE/min_donation = 50000 + VAR_PRIVATE/donation_goal = 0 + VAR_PRIVATE/cur_donation = 0 + VAR_PRIVATE/list/dono_list = list() + VAR_PRIVATE/highest_cached_donator = null + +/datum/controller/subsystem/internal_wiki/stat_entry(msg) + msg = "P: [pages.len] | O: [ores.len] | M: [materials.len] | S: [smashers.len] | F: [foodrecipe.len] | D: [drinkreact.len] | C: [chemreact.len] | B: [botseeds.len] " + return ..() + +/datum/controller/subsystem/internal_wiki/Initialize() + init_ore_data() + init_material_data() + init_particle_smasher_data() + init_reagent_data() + init_seed_data() + init_kitchen_data() + init_lore_data() + // Donation gag + donation_goal = rand(min_donation,max_donation) + donation_goal = round(donation_goal,1) + cur_donation = rand(0,donation_goal * 0.95) + cur_donation = round(cur_donation,1) + return SS_INIT_SUCCESS + + +/////////////////////////////////////////////////////////////////////////////////// +// Donation system, for the joke of course +/////////////////////////////////////////////////////////////////////////////////// +/datum/controller/subsystem/internal_wiki/proc/pay_with_card( var/obj/item/card/id/I, var/mob/M, var/obj/device, var/paying_amount) + SHOULD_NOT_OVERRIDE(TRUE) + if(!purchase_with_id_card(I, M, "Bingle.Co.LLC.UK.M.XM.WMP.AVI.COM", device.name, "Donation", paying_amount)) + return FALSE + // Keep tabs on donations + var/datum/money_account/customer_account = get_account(I.associated_account_number) + if(isnull(dono_list[customer_account.owner_name])) + dono_list[customer_account.owner_name] = 0 + dono_list[customer_account.owner_name] += paying_amount + donation_add(paying_amount) + return TRUE + +/datum/controller/subsystem/internal_wiki/proc/donation_add(var/paying_amount) + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + var/old_dono = cur_donation + cur_donation += paying_amount + if(old_dono < donation_goal) + // If donation goal was not yet met upon donation, recalculate leader on donate + highest_cached_donator = update_highest_donator(TRUE) + if(cur_donation >= donation_goal) // Reached goal! + message_admins("Bingle donation goal reached! Winner was [get_highest_donor_name()] with [get_highest_donor_value()]") // TODO - Removed me for something actually interesting + +/datum/controller/subsystem/internal_wiki/proc/update_highest_donator(var/no_cache = FALSE) + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + if(no_cache) + highest_cached_donator = null + if(highest_cached_donator) + return highest_cached_donator + // Search through the donated names for a winner + var/highest = "noone!" + var/val = 0 + for(var/donor in dono_list) + if(dono_list[donor] > val) + val = dono_list[donor] + highest = donor + return highest + + +/////////////////////////////////////////////////////////////////////////////////// +// Accessors for safely talking with the subsystem +/////////////////////////////////////////////////////////////////////////////////// +// get a page from a search +/datum/controller/subsystem/internal_wiki/proc/get_page_food(var/search) + RETURN_TYPE(/datum/internal_wiki/page/food) + SHOULD_NOT_OVERRIDE(TRUE) + return foodrecipe[search] +/datum/controller/subsystem/internal_wiki/proc/get_page_drink(var/search) + RETURN_TYPE(/datum/internal_wiki/page/drink) + SHOULD_NOT_OVERRIDE(TRUE) + return drinkreact[search] +/datum/controller/subsystem/internal_wiki/proc/get_page_chem(var/search) + RETURN_TYPE(/datum/internal_wiki/page/chemical) + SHOULD_NOT_OVERRIDE(TRUE) + return chemreact[search] +/datum/controller/subsystem/internal_wiki/proc/get_page_seed(var/search) + RETURN_TYPE(/datum/internal_wiki/page/seed) + SHOULD_NOT_OVERRIDE(TRUE) + return botseeds[search] +/datum/controller/subsystem/internal_wiki/proc/get_page_catalog(var/search) + RETURN_TYPE(/datum/internal_wiki/page/catalog) + SHOULD_NOT_OVERRIDE(TRUE) + return catalogs[search] +/datum/controller/subsystem/internal_wiki/proc/get_page_material(var/search) + RETURN_TYPE(/datum/internal_wiki/page/material) + SHOULD_NOT_OVERRIDE(TRUE) + return materials[search] +/datum/controller/subsystem/internal_wiki/proc/get_page_particle(var/search) + RETURN_TYPE(/datum/internal_wiki/page/smasher) + SHOULD_NOT_OVERRIDE(TRUE) + return smashers[search] +/datum/controller/subsystem/internal_wiki/proc/get_page_ore(var/search) + RETURN_TYPE(/datum/internal_wiki/page/ore) + SHOULD_NOT_OVERRIDE(TRUE) + return ores[search] +// Search lists +/datum/controller/subsystem/internal_wiki/proc/get_appliances() + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + return appliance_list +/datum/controller/subsystem/internal_wiki/proc/get_searchcache_food(var/appliance) + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + return searchcache_foodrecipe[appliance] || list() +/datum/controller/subsystem/internal_wiki/proc/get_searchcache_drink() + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + return searchcache_drinkreact +/datum/controller/subsystem/internal_wiki/proc/get_searchcache_chem() + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + return searchcache_chemreact +/datum/controller/subsystem/internal_wiki/proc/get_searchcache_seed() + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + return searchcache_botseeds +/datum/controller/subsystem/internal_wiki/proc/get_catalogs() + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + return catalog_list +/datum/controller/subsystem/internal_wiki/proc/get_searchcache_catalog(var/section) + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + var/list/known_entries = list() + var/list/section_data = searchcache_catalogs[section] || list() + for(var/PG in section_data) + var/datum/internal_wiki/page/catalog/P = catalogs["[PG]"] + var/datum/category_item/catalogue/C = P.catalog_record + if(C.visible || C.value <= CATALOGUER_REWARD_TRIVIAL) + known_entries.Add(PG) + return known_entries +/datum/controller/subsystem/internal_wiki/proc/get_searchcache_material() + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + return searchcache_material +/datum/controller/subsystem/internal_wiki/proc/get_searchcache_particle() + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + return searchcache_smasher +/datum/controller/subsystem/internal_wiki/proc/get_searchcache_ore() + RETURN_TYPE(/list) + SHOULD_NOT_OVERRIDE(TRUE) + return searchcache_ore +// Donating +/datum/controller/subsystem/internal_wiki/proc/get_donor_value(var/key) + SHOULD_NOT_OVERRIDE(TRUE) + if(!dono_list.len || isnull(dono_list[key])) + return 0 + return dono_list[key] +/datum/controller/subsystem/internal_wiki/proc/get_donation_current() + SHOULD_NOT_OVERRIDE(TRUE) + return cur_donation +/datum/controller/subsystem/internal_wiki/proc/get_donation_goal() + SHOULD_NOT_OVERRIDE(TRUE) + return donation_goal +/datum/controller/subsystem/internal_wiki/proc/get_highest_donor_name() + SHOULD_NOT_OVERRIDE(TRUE) + highest_cached_donator = update_highest_donator(FALSE) + return highest_cached_donator +/datum/controller/subsystem/internal_wiki/proc/get_highest_donor_value() + SHOULD_NOT_OVERRIDE(TRUE) + highest_cached_donator = update_highest_donator(FALSE) + return get_donor_value(highest_cached_donator) +// Helpers for formatting wiki data for tgui pages +/datum/controller/subsystem/internal_wiki/proc/assemble_reaction_data(var/list/data, var/datum/reagent/R) + var/list/reaction_list = SSchemistry.chemical_reactions_by_product[R.id] + var/list/distilled_list = SSchemistry.distilled_reactions_by_product[R.id] + + data["instant_reactions"] = null + if(reaction_list != null && reaction_list.len > 0) + var/list/display_reactions = list() + for(var/decl/chemical_reaction/CR in reaction_list) + if(CR.wiki_flag & WIKI_SPOILER) + continue + display_reactions.Add(CR) + + var/reactions = list() + for(var/decl/chemical_reaction/CR in display_reactions) + var/list/assemble_reaction = list() + var/list/reqs = list() + for(var/RQ in CR.required_reagents) + var/decl/chemical_reaction/r_RQ = SSchemistry.chemical_reagents[RQ] + if(!r_RQ) + log_runtime(EXCEPTION("Invalid reagent id: [RQ]")) + continue + reqs.Add("[r_RQ.name]") + assemble_reaction["required"] = reqs + var/list/inhib = list() + for(var/IH in CR.inhibitors) + var/decl/chemical_reaction/r_IH = SSchemistry.chemical_reagents[IH] + if(!r_IH) + log_runtime(EXCEPTION("Invalid reagent id: [IH]")) + continue + inhib.Add("[r_IH.name]") + assemble_reaction["inhibitor"] = inhib + var/list/catal = list() + for(var/CL in CR.catalysts) + var/decl/chemical_reaction/r_CL = SSchemistry.chemical_reagents[CL] + if(!r_CL) + log_runtime(EXCEPTION("Invalid reagent id: [CL]")) + continue + catal.Add("[r_CL.name]") + assemble_reaction["catalysts"] = catal + assemble_reaction["is_slime"] = null + if(istype(CR,/decl/chemical_reaction/instant/slime)) + var/decl/chemical_reaction/instant/slime/CRS = CR + var/obj/item/slime_extract/slime_path = CRS.required + assemble_reaction["is_slime"] = initial(slime_path.name) + reactions += list(assemble_reaction) + if(display_reactions.len) + data["instant_reactions"] = reactions + + data["distilled_reactions"] = null + if(distilled_list != null && distilled_list.len > 0) + var/list/display_reactions = list() + for(var/decl/chemical_reaction/distilling/CR in distilled_list) + if(CR.wiki_flag & WIKI_SPOILER) + continue + display_reactions.Add(CR) + + var/reactions = list() + for(var/decl/chemical_reaction/distilling/CR in display_reactions) + var/list/assemble_reaction = list() + assemble_reaction["temp_min"] = CR.temp_range[1] + assemble_reaction["temp_max"] = CR.temp_range[2] + /* Downstream features + assemble_reaction["xgm_min"] = CR.minimum_xgm_pressure + assemble_reaction["xgm_max"] = CR.maximum_xgm_pressure + assemble_reaction["require_xgm_gas"] = CR.require_xgm_gas + assemble_reaction["rejects_xgm_gas"] = CR.rejects_xgm_gas + */ + var/list/reqs = list() + for(var/RQ in CR.required_reagents) + var/decl/chemical_reaction/r_RQ = SSchemistry.chemical_reagents[RQ] + if(!r_RQ) + log_runtime(EXCEPTION("Invalid reagent id: [RQ]")) + continue + reqs.Add("[r_RQ.name]") + assemble_reaction["required"] = reqs + var/list/inhib = list() + for(var/IH in CR.inhibitors) + var/decl/chemical_reaction/r_IH = SSchemistry.chemical_reagents[IH] + if(!r_IH) + log_runtime(EXCEPTION("Invalid reagent id: [IH]")) + continue + inhib.Add("[r_IH.name]") + assemble_reaction["inhibitor"] = inhib + var/list/catal = list() + for(var/CL in CR.catalysts) + var/decl/chemical_reaction/r_CL = SSchemistry.chemical_reagents[CL] + if(!r_CL) + log_runtime(EXCEPTION("Invalid reagent id: [CL]")) + continue + catal.Add("[r_CL.name]") + assemble_reaction["catalysts"] = catal + assemble_reaction["is_slime"] = null + reactions += list(assemble_reaction) + if(display_reactions.len) + data["distilled_reactions"] = reactions + + var/grind_list = list() + var/list/display_reactions = list() + for(var/ore_type in ore_reagents) + var/obj/item/ore/O = ore_type + if(R.id in ore_reagents[ore_type]) + display_reactions.Add(initial(O.name)) + grind_list["ore"] = null + if(display_reactions.len > 0) + grind_list["ore"] = display_reactions + + display_reactions = list() + for(var/sheet_type in sheet_reagents) + var/obj/item/stack/material/M = sheet_type + if(R.id in sheet_reagents[sheet_type]) + display_reactions.Add(initial(M.name)) + grind_list["material"] = null + if(display_reactions.len > 0) + grind_list["material"] = display_reactions + + display_reactions = list() + for(var/SN in SSplants.seeds) + var/datum/seed/S = SSplants.seeds[SN] + if(S && S.roundstart && !S.mysterious) + if(S.wiki_flag & WIKI_SPOILER) + continue + if(!S.chems || !S.chems.len) + continue + if(!(R.id in S.chems)) + continue + display_reactions.Add(S.display_name) + grind_list["plant"] = null + if(display_reactions.len > 0) + grind_list["plant"] = display_reactions + + data["grinding"] = grind_list + + display_reactions = list() + for(var/O in GLOB.ore_data) + var/ore/OR = GLOB.ore_data[O] + if(OR.reagent == R.id) + display_reactions.Add(OR.name) + data["fluid"] = null + if(display_reactions.len > 0) + data["fluid"] = display_reactions + + display_reactions = list() + var/list/instant_by_reagent = SSchemistry.instant_reactions_by_reagent["[R.id]"] + if(instant_by_reagent && instant_by_reagent.len) + for(var/i = 1, i <= instant_by_reagent.len, i++) + var/decl/chemical_reaction/OR = instant_by_reagent[i] + if(istype(OR,/decl/chemical_reaction/instant/slime)) // very bloated and meant to be a mystery + continue + display_reactions.Add(OR.name) + var/list/distilled_by_reagent = SSchemistry.distilled_reactions_by_reagent["[R.id]"] + if(distilled_by_reagent && distilled_by_reagent.len) + for(var/i = 1, i <= distilled_by_reagent.len, i++) + var/decl/chemical_reaction/OR = distilled_by_reagent[i] + display_reactions.Add(OR.name) + data["produces"] = null + if(display_reactions.len > 0) + data["produces"] = display_reactions + +/datum/controller/subsystem/internal_wiki/proc/assemble_allergens(var/allergens) + if(allergens > 0) + var/list/allergies = list() + if(allergens & ALLERGEN_MEAT) + allergies.Add("Meat protein") + if(allergens & ALLERGEN_FISH) + allergies.Add("Fish protein") + if(allergens & ALLERGEN_FRUIT) + allergies.Add("Fruit") + if(allergens & ALLERGEN_VEGETABLE) + allergies.Add("Vegetable") + if(allergens & ALLERGEN_GRAINS) + allergies.Add("Grain") + if(allergens & ALLERGEN_BEANS) + allergies.Add("Bean") + if(allergens & ALLERGEN_SEEDS) + allergies.Add("Nut") + if(allergens & ALLERGEN_DAIRY) + allergies.Add("Dairy") + if(allergens & ALLERGEN_FUNGI) + allergies.Add("Fungi") + if(allergens & ALLERGEN_COFFEE) + allergies.Add("Caffeine") + if(allergens & ALLERGEN_SUGARS) + allergies.Add("Sugar") + if(allergens & ALLERGEN_EGGS) + allergies.Add("Egg") + if(allergens & ALLERGEN_STIMULANT) + allergies.Add("Stimulant") + if(allergens & ALLERGEN_CHOCOLATE) + allergies.Add("Chocolate") + /* Downstream features + if(allergens & ALLERGEN_POLLEN) + allergies.Add("Pollen") + if(allergens & ALLERGEN_SALT) + allergies.Add("Salt") + */ + return allergies + return null + +/datum/controller/subsystem/internal_wiki/proc/add_icon(var/list/data, var/ic, var/is, var/col) + var/load_data = list() + load_data["icon"] = ic // dmi path + load_data["state"] = is // string + load_data["color"] = col // html color + data["icon_data"] = load_data + + +/////////////////////////////////////////////////////////////////////////////////// +// Initilizing data and creating wiki pages +/////////////////////////////////////////////////////////////////////////////////// +/datum/controller/subsystem/internal_wiki/proc/init_ore_data() + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + // assemble ore wiki + for(var/N in GLOB.ore_data) + var/ore/OR = GLOB.ore_data[N] + if(OR.wiki_flag & WIKI_SPOILER) + spoiler_entries.Add(OR.type) + continue + var/datum/internal_wiki/page/ore/P = new() + P.assemble(OR) + ores["[OR.display_name]"] = P + searchcache_ore.Add("[OR.display_name]") + pages.Add(P) + +/datum/controller/subsystem/internal_wiki/proc/init_material_data() + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + // assemble material wiki + for(var/mat in name_to_material) + var/datum/material/M = name_to_material[mat] + if(M.wiki_flag & WIKI_SPOILER) + spoiler_entries.Add(M.type) + continue + var/datum/internal_wiki/page/material/P = new() + var/id = "[M.display_name] [M.sheet_singular_name]" + P.assemble(M) + materials[id] = P + searchcache_material.Add(id) + pages.Add(P) + +/datum/controller/subsystem/internal_wiki/proc/init_particle_smasher_data() + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + // assemble particle smasher wiki + for(var/datum/particle_smasher_recipe/D as anything in subtypesof(/datum/particle_smasher_recipe)) + if(initial(D.wiki_flag) & WIKI_SPOILER) + spoiler_entries.Add(D) + continue + var/datum/particle_smasher_recipe/R = new D() + var/datum/internal_wiki/page/smasher/P = new() + var/id = "[initial(D.display_name)]" + P.assemble(R) + smashers[id] = P + searchcache_smasher.Add(id) + pages.Add(P) + qdel(R) + +/datum/controller/subsystem/internal_wiki/proc/init_reagent_data() + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + // assemble chemical reactions wiki + for(var/reagent in SSchemistry.chemical_reagents) + var/datum/internal_wiki/page/P = null + var/datum/reagent/R = SSchemistry.chemical_reagents[reagent] + if(!allow_reagent(R.id)) + continue + if((R.wiki_flag & WIKI_FOOD)) // Processed later + continue + if(R.wiki_flag & WIKI_SPOILER) + spoiler_entries.Add(R.type) + continue + var/id = "[R.name]" + if((R.wiki_flag & WIKI_DRINK) && R.id != REAGENT_ID_ETHANOL) // This is no good way to use inheretance for ethanol... We exclude it here so it shows up in chems + P = new /datum/internal_wiki/page/drink() + P.assemble(R) + searchcache_drinkreact.Add(id) + drinkreact[id] = P + else + P = new /datum/internal_wiki/page/chemical() + P.assemble(R) + searchcache_chemreact.Add(id) + chemreact[id] = P + pages.Add(P) + +/datum/controller/subsystem/internal_wiki/proc/init_seed_data() + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + // seeds and plants + for(var/SN in SSplants.seeds) + var/datum/seed/S = SSplants.seeds[SN] + if(S && S.roundstart && !S.mysterious) + if(S.wiki_flag & WIKI_SPOILER) + spoiler_entries.Add(S.type) + continue + var/datum/internal_wiki/page/seed/P = new() + P.assemble(S) + searchcache_botseeds.Add("[S.display_name]") + botseeds["[S.display_name]"] = P + pages.Add(P) + +/datum/controller/subsystem/internal_wiki/proc/init_kitchen_data() + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + // Build the kitchen recipe lists + var/list/food_recipes = subtypesof(/datum/recipe) + for(var/datum/recipe/Rp as anything in food_recipes) + //Lists don't work with datum-stealing no-instance initial() so we have to. + var/datum/recipe/R = new Rp() + if(!isnull(R.result)) + var/obj/item/res = R.result + food_recipes[Rp] = list( + "Result" = "[initial(res.name)]", + "ResultPath" = res, + "Desc" = "[initial(res.desc)]", + "ResAmt" = "1", + "Reagents" = R.reagents ? R.reagents.Copy() : list(), + "Catalysts" = list(), + "Fruit" = R.fruit ? R.fruit.Copy() : list(), + "Ingredients" = R.items ? R.items.Copy() : list(), + "Coating" = R.coating, + "Appliance" = R.appliance, + "Allergens" = 0, + "Price" = initial(res.price_tag), + "Flags" = R.wiki_flag + ) + qdel(R) + // basically condiments, tofu, cheese, soysauce, etc + for(var/decl/chemical_reaction/instant/CR in SSchemistry.chemical_reactions) + if(!allow_reagent(CR.result)) + continue + if(CR.wiki_flag & WIKI_SPOILER) + continue + if(!(CR.wiki_flag & WIKI_FOOD)) + continue + food_recipes[CR.type] = list("Result" = CR.name, + "ResultPath" = null, + "ResAmt" = CR.result_amount, + "Reagents" = CR.required_reagents ? CR.required_reagents.Copy() : list(), + "Catalysts" = CR.catalysts ? CR.catalysts.Copy() : list(), + "Fruit" = list(), + "Ingredients" = list(), + "Appliance" = 0, + "Allergens" = 0, + "Flags" = CR.wiki_flag + ) + //Items needs further processing into human-readability. + for(var/Rp in food_recipes) + var/working_ing_list = list() + food_recipes[Rp]["has_coatable_items"] = FALSE + for(var/I in food_recipes[Rp]["Ingredients"]) + if(I == /obj/item/holder/mouse) // Time for the list of snowflakes + if("mouse" in working_ing_list) + var/sofar = working_ing_list["mouse"] + working_ing_list["mouse"] = sofar+1 + else + working_ing_list["mouse"] = 1 + else if(I == /obj/item/holder/diona) // YOU TOO + if("diona" in working_ing_list) + var/sofar = working_ing_list["diona"] + working_ing_list["diona"] = sofar+1 + else + working_ing_list["diona"] = 1 + else if(I == /obj/item/holder) // And you especially, needed for "splat" microwave recipe + if("micro" in working_ing_list) + var/sofar = working_ing_list["micro"] + working_ing_list["micro"] = sofar+1 + else + working_ing_list["micro"] = 1 + else + if(I in typesof(/obj/item/reagent_containers/food/snacks)) // only subtypes of this have a coating variable and are checked for it (fruit are a subtype of this, so there's a check for them too later) + food_recipes[Rp]["has_coatable_items"] = TRUE + + //So now we add something like "Bread" = 3 + var/id = initial(I:name) + if(id in working_ing_list) + var/sofar = working_ing_list[id] + working_ing_list[id] = sofar+1 + else + working_ing_list[id] = 1 + + if(LAZYLEN(food_recipes[Rp]["Fruit"])) + food_recipes[Rp]["has_coatable_items"] = TRUE + food_recipes[Rp]["Ingredients"] = working_ing_list + + //Reagents can be resolved to nicer names as well + for(var/Rp in food_recipes) + for(var/rid in food_recipes[Rp]["Reagents"]) + var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid] + if(!Rd) // Leaving this here in the event that if rd is ever invalid or there's a recipe issue, it'll be skipped and recipe dumps can still be ran. + log_runtime(EXCEPTION("Food \"[Rp]\" had an invalid RID: \"[rid]\"! Check your reagents list for a missing or mistyped reagent!")) + continue // This allows the dump to still continue, and it will skip the invalid recipes. + var/R_name = Rd.name + var/amt = food_recipes[Rp]["Reagents"][rid] + food_recipes[Rp]["Reagents"] -= rid + food_recipes[Rp]["Reagents"][R_name] = amt + food_recipes[Rp]["Allergens"] |= Rd.allergen_type + for(var/rid in food_recipes[Rp]["Catalysts"]) + var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid] + if(!Rd) // Leaving this here in the event that if rd is ever invalid or there's a recipe issue, it'll be skipped and recipe dumps can still be ran. + log_runtime(EXCEPTION("Food \"[Rp]\" had an invalid RID: \"[rid]\"! Check your reagents list for a missing or mistyped reagent!")) + continue // This allows the dump to still continue, and it will skip the invalid recipes. + var/R_name = Rd.name + var/amt = food_recipes[Rp]["Catalysts"][rid] + food_recipes[Rp]["Catalysts"] -= rid + food_recipes[Rp]["Catalysts"][R_name] = amt + + //We can also change the appliance to its proper name. + for(var/Rp in food_recipes) + switch(food_recipes[Rp]["Appliance"]) + if(0) + food_recipes[Rp]["Appliance"] = "Simple" + if(1) + food_recipes[Rp]["Appliance"] = "Microwave" + if(2) + food_recipes[Rp]["Appliance"] = "Fryer" + if(4) + food_recipes[Rp]["Appliance"] = "Oven" + if(8) + food_recipes[Rp]["Appliance"] = "Grill" + if(16) + food_recipes[Rp]["Appliance"] = "Candy Maker" + if(32) + food_recipes[Rp]["Appliance"] = "Cereal Maker" + + //////////////////////// SORTING + var/list/foods_to_paths = list() + for(var/Rp in food_recipes) // "Appliance" will sort the list by APPLIANCES first. Items without an appliance will append to the top of the list. The old method was "Result", which sorts the list by the name of the result. + foods_to_paths["[food_recipes[Rp]["Appliance"]] [Rp]"] = Rp //Append recipe datum path to keep uniqueness + foods_to_paths = sortAssoc(foods_to_paths) + var/list/foods_newly_sorted = list() + for(var/Rr in foods_to_paths) + var/Rp = foods_to_paths[Rr] + foods_newly_sorted[Rp] = food_recipes[Rp] + food_recipes = foods_newly_sorted + + // assemble output pages + for(var/Rp in food_recipes) + if(food_recipes[Rp] && !isnull(food_recipes[Rp]["Result"])) + if(food_recipes[Rp]["Flags"] & WIKI_SPOILER) + spoiler_entries.Add(Rp) + continue + var/datum/internal_wiki/page/recipe/P = new() + P.assemble(food_recipes[Rp]) + foodrecipe["[P.title]"] = P + // organize into sublists + var/app = food_recipes[Rp]["Appliance"] + if(!searchcache_foodrecipe[app]) + searchcache_foodrecipe[app] = list() + var/list/FL = searchcache_foodrecipe[app] + FL.Add("[P.title]") + pages.Add(P) + +/datum/controller/subsystem/internal_wiki/proc/init_lore_data() + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + + // assemble low reward catalog entries + for(var/datum/category_group/G in GLOB.catalogue_data.categories) + for(var/datum/category_item/catalogue/item in G.items) + if(istype(item,/datum/category_item/catalogue/anomalous)) + continue // lets always consider these spoilers + if(istype(item,/datum/category_item/catalogue/fauna/catslug/custom)) + continue // too many silly entries + var/datum/internal_wiki/page/catalog/P = new() + P.title = item.name + P.catalog_record = item + P.assemble() + catalogs["[item.name]"] = P + if(!searchcache_catalogs[G.name]) + searchcache_catalogs[G.name] = list() + var/list/SC = searchcache_catalogs[G.name] + SC.Add(P.title) + pages.Add(P) + catalog_list.Add(G.name) + +/datum/controller/subsystem/internal_wiki/proc/allow_reagent(var/reagent_id) + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + + // This is used to filter out some of the base reagent types, such as admin only reagents + if(!reagent_id || reagent_id == "" || reagent_id == REAGENT_ID_DEVELOPER_WARNING || reagent_id == REAGENT_ID_DRINK || reagent_id == REAGENT_DRUGS || reagent_id == REAGENT_ID_ADMINORDRAZINE) + return FALSE + return TRUE + + +//////////////////////////////////////////////////////////////////////////////////////////////// +// PAGES AND THEIR CONSTRUCTION +//////////////////////////////////////////////////////////////////////////////////////////////// +/datum/internal_wiki/page + var/title = "" + var/list/data = list() + +/datum/internal_wiki/page/proc/assemble() + return + +/datum/internal_wiki/page/proc/get_data() + RETURN_TYPE(/list) + return data + +/datum/internal_wiki/page/proc/get_print() + return + + +// ORES +//////////////////////////////////////////// +/datum/internal_wiki/page/ore/assemble(var/ore/O) + title = O.display_name + data["title"] = title + var/obj/item/ore/ore_path = O.ore + SSinternal_wiki.add_icon(data, initial(ore_path.icon), initial(ore_path.icon_state), "#ffffff") + // Get internal data + data["smelting"] = null + if(O.smelts_to) + var/datum/material/S = get_material_by_name(O.smelts_to) + data["smelting"] = S.display_name + + data["compressing"] = null + if(O.compresses_to) + var/datum/material/C = get_material_by_name(O.compresses_to) + data["compressing"] = C.display_name + + data["alloys"] = null + if(O.alloy) + var/list/alloy_list = list() + for(var/datum/alloy/A in GLOB.alloy_data) + for(var/req in A.requires) + if(O.name == req ) + var/datum/material/M = get_material_by_name(A.metaltag) + alloy_list.Add(M.display_name) + break + data["alloys"] = alloy_list + + data["pump_reagent"] = null + if(O.reagent) + var/datum/reagent/REG = SSchemistry.chemical_reagents[O.reagent] + data["pump_reagent"] = REG.name + + data["grind_reagents"] = null + if(global.ore_reagents[O.ore]) + var/list/output = global.ore_reagents[O.ore] + var/list/collect = list() + var/total_parts = 0 + for(var/Rid in output) + var/datum/reagent/CBR = SSchemistry.chemical_reagents[Rid] + if(!collect[CBR.name]) + collect[CBR.name] = 0 + collect[CBR.name] += 1 + total_parts += 1 + + var/per_part = REAGENTS_PER_SHEET / total_parts + var/list/grind_list = list() + for(var/N in collect) + grind_list[N] = "[collect[N] * per_part]" + data["grind_reagents"] = grind_list + +/datum/internal_wiki/page/ore/get_print() + var/body = "" + if(data["smelting"]) + body += "Smelting: [data["smelting"]]
" + if(data["compressing"]) + body += "Compressing: [data["compressing"]]
" + if(data["alloys"]) + body += "
" + body += "Alloy Component of:
" + var/list/alloy_list = data["alloys"] + for(var/A in alloy_list) + body += "-[A]
" + else + body += "
" + body += "No known Alloys
" + if(data["pump_reagent"]) + body += "
" + body += "Fluid Pump Results:
" + body += "-[data["pump_reagent"]]
" + if(data["grind_reagents"]) + body += "
" + body += "Ore Grind Results:
" + var/list/grind_list = data["grind_reagents"] + for(var/A in grind_list) + body += "-[A]: [grind_list[A]]u
" + return body + +// MATERIALS +//////////////////////////////////////////// +/datum/internal_wiki/page/material/assemble(var/datum/material/M) + title = M.display_name + " " + M.sheet_singular_name + data["title"] = title + var/obj/item/stack/stack_path = M.stack_type + SSinternal_wiki.add_icon(data, initial(stack_path.icon), initial(stack_path.icon_state), initial(M.icon_colour)) + // Get internal data + data["integrity"] = M.integrity + data["hardness"] = M.hardness + data["weight"] = M.weight + data["stack_size"] = initial(stack_path.max_amount) ? initial(stack_path.max_amount) : 0 + var/supply_value = M.supply_conversion_value ? M.supply_conversion_value : 0 + data["supply_points"] = supply_value + var/value = supply_value * SSsupply.points_per_money + value = FLOOR(value * 100, 1) / 100 // Truncate decimals + data["market_price"] = value + + data["opacity"] = M.opacity + data["conductive"] = M.conductive + data["protectiveness"] = M.protectiveness + data["explosion_resistance"] = M.explosion_resistance + data["radioactivity"] = M.radioactivity + data["reflectivity"] = M.reflectivity + data["melting_point"] = M.melting_point + data["ignition_point"] = M.ignition_point + + data["grind_reagents"] = null + if(global.sheet_reagents[M.stack_type]) + var/list/output = global.sheet_reagents[M.stack_type] + if(output && output.len > 0) + var/list/collect = list() + var/total_parts = 0 + for(var/Rid in output) + var/datum/reagent/CBR = SSchemistry.chemical_reagents[Rid] + if(CBR) + if(!collect[CBR.name]) + collect[CBR.name] = 0 + collect[CBR.name] += 1 + total_parts += 1 + else + log_runtime(EXCEPTION("Invalid reagent id: [Rid] in grind results for sheet [title]")) + if(total_parts > 0) + var/per_part = REAGENTS_PER_SHEET / total_parts + var/list/grind_list = list() + for(var/N in collect) + grind_list[N] = "[collect[N] * per_part]" + data["grind_reagents"] = grind_list + + data["recipies"] = null + M.get_recipes() // generate if not already + if(M.recipes != null && M.recipes.len > 0) + var/list/recipie_list = list() + for(var/datum/stack_recipe/R in M.recipes) + recipie_list.Add(R.title) + data["recipies"] = recipie_list + +/datum/internal_wiki/page/material/get_print() + var/body = "" + body += "Integrity: [data["integrity"]]
" + body += "Hardness: [data["hardness"]]
" + body += "Weight: [data["weight"]]
" + var/points = data["supply_points"] + var/stack_size = data["stack_size"] + body += "Supply Points: [points] per sheet, [points * stack_size] per stack of [stack_size]
" + var/value = data["market_price"] + body += "Market Price: [value] [value > 1 ? "thalers" : "thaler"] per sheet | [(value*stack_size)] [(value*stack_size) > 1 ? "thalers" : "thaler"] per stack of [stack_size]
" + body += "
" + body += "Transparent: [data["opacity"] >= 0.5 ? "No" : "Yes"]
" + body += "Conductive: [data["conductive"] ? "Yes" : "No"]
" + body += "Stability: [data["protectiveness"]]
" + body += "Blast Res.: [data["explosion_resistance"]]
" + body += "Radioactivity: [data["radioactivity"]]
" + body += "Reflectivity: [data["reflectivity"] * 100]%
" + body += "
" + if(data["melting_point"] > 0) + body += "Melting Point: [data["melting_point"]]K ([data["melting_point"] - T0C]C)
" + else + body += "Melting Point: ---
" + + if(data["ignition_point"] > 0) + body += "Ignition Point: [data["ignition_point"]]K ([data["ignition_point"] - T0C]C)
" + else + body += "Ignition Point: ---
" + if(data["grind_reagents"]) + body += "
" + var/list/grind_list = data["grind_reagents"] + if(grind_list && grind_list.len > 0) + body += "Sheet Grind Results:
" + for(var/N in grind_list) + body += "-[N]: [grind_list[N]]u
" + if(data["recipies"]) + body += "
" + var/list/recipie_list = data["recipies"] + body += "Recipies:
" + for(var/R in recipie_list) + body += "-[R]
" + return body + +// SEEDS +//////////////////////////////////////////// +/datum/internal_wiki/page/seed/assemble(var/datum/seed/S) + title = S.display_name + data["title"] = title + SSinternal_wiki.add_icon(data, 'icons/obj/hydroponics_growing.dmi', "[S.get_trait(TRAIT_PLANT_ICON)]-[S.growth_stages]", S.get_trait(TRAIT_PLANT_COLOUR)) + // Get internal data + data["feeding"] = S.get_trait(TRAIT_REQUIRES_NUTRIENTS) + data["watering"] = S.get_trait(TRAIT_REQUIRES_WATER) + data["lighting"] = S.get_trait(TRAIT_IDEAL_LIGHT) + data["crop_yield"] = S.get_trait(TRAIT_YIELD) + + var/list/traits = list() + if(S.has_item_product) + traits.Add("Grown Byproducts") + if(S.chems && !isnull(S.chems["woodpulp"])) + traits.Add("Wooden Growths") + if(S.get_trait(TRAIT_FLESH_COLOUR)) + traits.Add("Choppable") + if(S.kitchen_tag == "pumpkin") + traits.Add("Carvable") + if(S.kitchen_tag == "potato") + traits.Add("Sliceable") + if(S.get_trait(TRAIT_JUICY)) + traits.Add("Juicy") + if(S.get_trait(TRAIT_IMMUTABLE)) + traits.Add("Stable Genome") + if(S.get_trait(TRAIT_PRODUCES_POWER)) + traits.Add("Voltaic") + if(S.get_trait(TRAIT_BIOLUM)) + traits.Add("Bioluminescence") + if(S.get_trait(TRAIT_STINGS)) + traits.Add("Stings") + if(S.get_trait(TRAIT_SPORING)) + traits.Add("Produces Spores") + if(S.get_trait(TRAIT_CARNIVOROUS)) + traits.Add("Carnivorous") + if(S.get_trait(TRAIT_PARASITE)) + traits.Add("Parasitic") + if(S.get_trait(TRAIT_SPREAD)) + traits.Add("Spreading") + if(S.get_trait(TRAIT_EXPLOSIVE)) + traits.Add("Explosive") + if(!traits.len) + traits.Add("None") + data["traits"] = traits + data["mob_product"] = S.has_mob_product + + data["chem_breakdown"] = null + if(S.chems && S.chems.len > 0) + var/list/chems = list() + for(var/CB in S.chems) + var/datum/reagent/CBR = SSchemistry.chemical_reagents[CB] + if(CBR) + chems.Add(CBR.name) + else + log_runtime(EXCEPTION("Invalid reagent id: [CB] in chemical breakdown for seed [title]")) + data["chem_breakdown"] = chems + + data["gas_consumed"] = null + if(S.consume_gasses && S.consume_gasses.len > 0) + var/list/consumed = list() + for(var/CG in S.consume_gasses) + consumed["[gas_data.name[CG]]"] = S.consume_gasses[CG] + data["gas_consumed"] = consumed + + data["gas_exuded"] = null + if(S.exude_gasses && S.exude_gasses.len > 0) + var/list/exude = list() + for(var/EG in S.exude_gasses) + exude["[gas_data.name[EG]]"] = S.exude_gasses[EG] + data["gas_exuded"] = exude + + data["mutations"] = null + if(S.mutants && S.mutants.len > 0) + var/list/mutations = list() + for(var/MS in S.mutants) + var/datum/seed/mut = SSplants.seeds[MS] + if(mut) + mutations.Add(mut.display_name) + data["mutations"] = mutations + +/datum/internal_wiki/page/seed/get_print() + var/body = "" + body += "Requires Feeding: [data["feeding"] ? "YES" : "NO"]
" + body += "Requires Watering: [data["watering"] ? "YES" : "NO"]
" + body += "Requires Light: [data["lighting"]] lumen[data["lighting"] == 1 ? "" : "s"]
" + if(data["crop_yield"] > 0) + body += "Yield: [data["crop_yield"]]
" + body += "
" + body += "Traits:
" + var/list/traits = data["traits"] + for(var/A in traits) + body += "-[A]
" + body += "
" + if(data["mob_product"]) + body += "DANGER - MAY BE MOBILE
" + body += "
" + var/list/chem_list = data["chem_breakdown"] + if(chem_list && chem_list.len > 0) + body += "Chemical Breakdown:
" + for(var/CB in chem_list) + body += "-[CB]
" + body += "
" + var/list/consumed_list = data["gas_consumed"] + if(consumed_list && consumed_list.len > 0) + body += "Gasses Consumed:
" + for(var/CG in consumed_list) + var/amount = "[consumed_list[CG]]" + if (consumed_list[CG] < 5) + amount = "[CG] (trace amounts)" + body += "-[amount]
" + body += "
" + var/list/exuded_list = data["gas_exuded"] + if(exuded_list && exuded_list.len > 0) + body += "Gasses Produced:
" + for(var/EG in exuded_list) + var/amount = "[exuded_list[EG]]" + if (exuded_list[EG] < 5) + amount = "[EG] (trace amounts)" + body += "-[amount]
" + body += "
" + var/list/mutations = data["mutations"] + if(mutations && mutations.len > 0) + body += "Mutant Strains:
" + for(var/MS in mutations) + body += "-[MS]
" + return body + +// PARTICLE SMASHER +//////////////////////////////////////////// +/datum/internal_wiki/page/smasher/assemble(var/datum/particle_smasher_recipe/M) + title = M.display_name + data["title"] = title + var/obj/item/stack/material/result_path = M.result + var/datum/material/result_mat = get_material_by_name(initial(result_path.default_type)) + SSinternal_wiki.add_icon(data, initial(result_path.icon), initial(result_path.icon_state), initial(result_mat.icon_colour)) + // Get internal data + var/obj/item/stack/req_mat = M.required_material + data["req_mat"] = null + if(req_mat != null) + data["req_mat"] = initial(req_mat.name) + + data["target_items"] = null + if(M.items && M.items.len > 0) + var/list/targs = list() + for(var/obj/Ir as anything in M.items) + targs.Add(initial(Ir.name)) + data["target_items"] = targs + + data["required_energy_min"] = M.required_energy_min + data["required_energy_max"] = M.required_energy_max + data["required_atmos_temp_min"] = M.required_atmos_temp_min + data["required_atmos_temp_max"] = M.required_atmos_temp_max + + data["inducers"] = null + if(M.reagents != null && M.reagents.len > 0) + var/list/inducers = list() + for(var/R in M.reagents) + var/amnt = M.reagents[R] + var/datum/reagent/Rd = SSchemistry.chemical_reagents[R] + if(Rd) + inducers["[Rd.name]"] = amnt + else + log_runtime(EXCEPTION("Invalid reagent id: [Rd] in inducer for atom smasher [title]")) + data["inducers"] = inducers + data["result"] = initial(result_path.name) + data["probability"] = M.probability + +/datum/internal_wiki/page/smasher/get_print() + var/body = "" + if(data["req_mat"] != null) + body += "Target Sheet: [data["req_mat"]]
" + var/list/targ_items = data["target_items"] + if(targ_items && targ_items.len > 0) + for(var/Ir in targ_items) + body += "-[Ir]
" + body += "Threshold Energy: [data["required_energy_min"]] - [data["required_energy_max"]]
" + body += "Threshold Temp: [data["required_atmos_temp_min"]]k - [data["required_atmos_temp_max"]]k | ([data["required_atmos_temp_min"] - T0C]C - [data["required_atmos_temp_max"] - T0C]C)
" + var/list/inducers = data["inducers"] + if(inducers && inducers.len > 0) + body += "
" + body += "Inducers:
" + for(var/R in inducers) + body += "-[R] [inducers[R]]u
" + body += "
" + body += "Results: [data["result"]]
" + body += "Probability: [data["probability"]]%
" + return body + + +// CHEMICALS +//////////////////////////////////////////// +/datum/internal_wiki/page/chemical/assemble(var/datum/reagent/R) + title = R.name + data["title"] = title + var/obj/item/reagent_containers/glass/beaker/large/beaker_path = /obj/item/reagent_containers/glass/beaker/large + SSinternal_wiki.add_icon(data, initial(beaker_path.icon), initial(beaker_path.icon_state), R.color) + // Get internal data + data["description"] = R.description + /* Downstream features + data["addictive"] = 0 + if(R.id in addictives) + data["addictive"] = (R.id in fast_addictives) ? 2 : 1 + data["industrial_use"] = R.industrial_use + data["supply_points"] = R.supply_conversion_value ? R.supply_conversion_value : 0 + var/value = R.supply_conversion_value * REAGENTS_PER_SHEET * SSsupply.points_per_money + value = FLOOR(value * 100,1) / 100 // Truncate decimals + data["market_price"] = value + data["sintering"] = global.reagent_sheets[R.id] + */ + data["overdose"] = R.overdose + data["flavor"] = R.taste_description + data["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type) + SSinternal_wiki.assemble_reaction_data(data, R) + +/datum/internal_wiki/page/chemical/get_print() + var/body = "" + body += "Description: [data["description"]]
" + /* Downstream features + if(data["addictive"]) + body += "DANGER, [data["addictive"] > 1 ? "highly " : ""]addictive.
" + if(data["industrial_use"]) + body += "Industrial Use: [data["industrial_use"]]
" + var/tank_size = CARGOTANKER_VOLUME + body += "Supply Points: [data["supply_points"]] per unit, [data["supply_points"] * tank_size] per [tank_size] tank
" + var/value = data["market_price"] + if(value > 0) + body += "Market Price: [value] [value > 1 ? "thalers" : "thaler"] per [REAGENTS_PER_SHEET] units | [(value*tank_size)] [(value*tank_size) > 1 ? "thalers" : "thaler"] per [tank_size] unit tank
" + if(data["sintering"]) + var/mat_id = data["sintering"] + switch(mat_id) + if("FLAG_SMOKE") + body += "Sintering Results: COMBUSTION
" + if("FLAG_EXPLODE") + body += "Sintering Results: DETONATION
" + if("FLAG_SPIDERS") + body += "Sintering Results: DO NOT EVER
" + else + var/datum/material/C = get_material_by_name(data["sintering"]) + body += "Sintering Results: [C.display_name] [C.sheet_plural_name]
" + */ + if(data["overdose"] > 0) + body += "Overdose: [data["overdose"]]u
" + body += "Flavor: [data["flavor"]]
" + body += "
" + body += print_allergens(data["allergen"]) + body += "
" + body += print_reaction_data(data) + return body + +// FOOD REAGENTS +//////////////////////////////////////////// +/datum/internal_wiki/page/food/assemble(var/datum/reagent/R) + title = R.name + data["title"] = title + var/obj/item/reagent_containers/glass/beaker/large/beaker_path = /obj/item/reagent_containers/glass/beaker/large + SSinternal_wiki.add_icon(data, initial(beaker_path.icon), initial(beaker_path.icon_state), R.color) + // Get internal data + data["description"] = R.description + data["flavor"] = R.taste_description + data["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type) + SSinternal_wiki.assemble_reaction_data(data, R) + +/datum/internal_wiki/page/food/get_print() + var/body = "" + body += "Description: [data["description"]]
" + body += "
" + body += print_allergens(data["allergen"]) + body += "
" + body += print_reaction_data(data) + +// DRINK REAGENTS +//////////////////////////////////////////// +/datum/internal_wiki/page/drink/assemble(var/datum/reagent/R) + title = R.name + data["title"] = title + // Use beaker by default, otherwise try metamorphic glass for icon + var/ico = 'icons/obj/drinks.dmi' + if(R.glass_icon_file) + ico = R.glass_icon_file + var/sta = "glass_empty" + if(R.glass_icon_state) + sta = R.glass_icon_state + SSinternal_wiki.add_icon(data, ico, sta, R.color) + // Get internal data + data["description"] = R.description + data["flavor"] = R.taste_description + data["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type) + SSinternal_wiki.assemble_reaction_data(data, R) + +/datum/internal_wiki/page/drink/get_print() + var/body = "" + body += "Description: [data["description"]]
" + body += "Flavor: [data["flavor"]]
" + body += "
" + body += print_allergens(data["allergen"]) + body += "
" + body += print_reaction_data(data) + return body + +// FOOD RECIPIE +//////////////////////////////////////////// +/datum/internal_wiki/page/recipe/assemble(var/list/recipe) + title = recipe["Result"] + data["title"] = title + var/obj/item/path = recipe["ResultPath"] + if(path) + SSinternal_wiki.add_icon(data, initial(path.icon), initial(path.icon_state), "#ffffff") + else + var/obj/item/reagent_containers/glass/beaker/large/beaker_path = /obj/item/reagent_containers/glass/beaker/large + SSinternal_wiki.add_icon(data, initial(beaker_path.icon), initial(beaker_path.icon_state), "#ffffff") + // Get internal data + data["description"] = recipe["Desc"] + data["allergen"] = SSinternal_wiki.assemble_allergens(recipe["Allergens"]) + var/list/recipe_data = list() + var/value = recipe["Price"] ? recipe["Price"] : 0 + recipe_data["supply_points"] = value + value *= SSsupply.points_per_money // convert to cash + value = FLOOR(value * 100,1) / 100 // Truncate decimals + recipe_data["market_price"] = value + recipe_data["appliance"] = recipe["Appliance"] + recipe_data["has_coating"] = recipe["has_coatable_items"] + recipe_data["coating"] = recipe["Coating"] + if(!isnull(recipe_data["coating"]) && recipe_data["coating"] != -1) // Null is no coatings, -1 is any coating, otherwise specifies the name of coating + var/datum/reagent/nutriment/coating/coatingtype = recipe["Coating"] + recipe_data["coating"] = initial(coatingtype.name) + var/list/ingred = list() + for(var/ing in recipe["Ingredients"]) + ingred["[ing]"] = recipe["Ingredients"][ing] + recipe_data["ingredients"] = ingred.len ? ingred : null + var/list/fruits = list() + for(var/fru in recipe["Fruit"]) + fruits["[fru]"] = recipe["Fruit"][fru] + recipe_data["fruits"] = fruits.len ? fruits : null + var/list/reagents = list() + for(var/rea in recipe["Reagents"]) + reagents["[rea]"] = recipe["Reagents"][rea] + recipe_data["reagents"] = reagents.len ? reagents : null + var/list/catalysts = list() + for(var/cat in recipe["Catalysts"]) + catalysts["[cat]"] = recipe["Catalysts"][cat] + recipe_data["catalysts"] = catalysts.len ? catalysts : null + data["recipe"] = recipe_data + +/datum/internal_wiki/page/recipe/get_print() + var/body = "" + if(data["description"]) + body += "Description: [data["description"]]
" + if(data["recipe"]["supply_points"] > 0) + var/value = data["recipe"]["supply_points"] + body += "Supply Points: [value]
" + if(data["recipe"]["market_price"] > 0) + var/value = data["recipe"]["market_price"] + body += "Market Price: [value] [value > 1 ? "thalers" : "thaler"]
" + body += print_allergens(data["allergen"]) + body += "
" + if(data["recipe"]["appliance"]) + body += "Appliance: [data["recipe"]["appliance"]]

" + // ingredients + var/list/ingreds = data["recipe"]["ingredients"] + if(ingreds && ingreds.len) + var/count = 0 + var/pretty_ing = "" + for(var/ing in ingreds) + pretty_ing += "[count == 0 ? "" : ", "][ing]x [ingreds[ing]]" + count++ + if(pretty_ing != "") + body += "Ingredients: [pretty_ing]
" + // Coatings + if(!data["recipe"]["has_coating"]) + body += "Coating: N/A, no coatable items
" + else if(isnull(data["recipe"]["coating"])) + body += "Coating: Must be uncoated
" + else if(data["recipe"]["coating"] == -1) + body += "Coating: Optionally, any coating
" + else + body += "Coating: [data["recipe"]["coating"]]
" + // Fruits/Veggis + var/list/fruits = data["recipe"]["fruits"] + if(fruits && fruits.len) // Can't use lazylen, assoc list + var/count = 0 + var/pretty_fru = "" + for(var/fru in fruits) + pretty_fru += "[count == 0 ? "" : ", "][fru]x [fruits[fru]]" + count++ + if(pretty_fru != "") + body += "Components: [pretty_fru]
" + //For each reagent + var/list/reags = data["recipe"]["reagents"] + if(reags && reags.len) // Can't use lazylen, assoc list + var/count = 0 + var/pretty_rea = "" + for(var/reg in reags) + pretty_rea += "[count == 0 ? "" : ", "][reg] [reags[reg]]u" + count++ + if(pretty_rea != "") + body += "Mix in: [pretty_rea]
" + //For each catalyst + var/list/catalis = data["recipe"]["catalysts"] + if(catalis && catalis.len) // Can't use lazylen, assoc list + var/count = 0 + var/pretty_cat = "" + for(var/cat in catalis) + pretty_cat += "[count == 0 ? "" : ", "][cat] [catalis[cat]]u" + count++ + if(pretty_cat != "") + body += "Catalysts: [pretty_cat]
" + return body + +// CATALOG +//////////////////////////////////////////// +/datum/internal_wiki/page/catalog + var/datum/category_item/catalogue/catalog_record = null + +/datum/internal_wiki/page/catalog/assemble() + data["name"] = catalog_record.name + data["desc"] = catalog_record.desc + +// MISC HELPERS +//////////////////////////////////////////// +/datum/internal_wiki/page/proc/print_allergens(var/list/allergens) + PROTECTED_PROC(TRUE) + var/AG = "" + if(allergens && allergens.len > 0) + AG += "Allergens:
" + for(var/ALGY in allergens) + AG += "-[ALGY]
" + AG += "
" + return AG + +/datum/internal_wiki/page/proc/print_reaction_data(var/list/data) + var/body = "" + var/list/instant = data["instant_reactions"] + if(instant && instant.len > 0) + var/segment = 1 + for(var/list/react in instant) + if(instant.len == 1) + body += "Potential Chemical breakdown:
" + else + body += "Potential Chemical breakdown [segment]:
" + segment++ + if(react["is_slime"]) + for(var/RQ in react["required"]) + body += " -[react["is_slime"]] Injection: [RQ]
" + else + for(var/RQ in react["required"]) + body += " -Component: [RQ]
" + for(var/IH in react["inhibitor"]) + body += " -Inhibitor: [IH]
" + for(var/CL in react["catalysts"]) + body += " -Catalyst: [CL]
" + else + body += "Potential Chemical breakdown:
UNKNOWN OR BASE-REAGENT
" + + var/list/distilled = data["distilled_reactions"] + if(distilled && distilled.len > 0) + var/segment = 1 + for(var/list/react in distilled) + if(distilled.len == 1) + body += "Potential Chemical breakdown:
" + else + body += "Potential Chemical breakdown [segment]:
" + segment++ + /* Downstream features + body += " -Temperature: [react["xgm_min"]]K - [react["xgm_max"]]K | ([react["xgm_min"] - T0C]C - [react["xgm_max"] - T0C]C)
" + if(react["require_xgm_gas"]) + body += " -Requires Gas: [react["require_xgm_gas"])]
" + if(react["rejects_xgm_gas"]) + body += " -Rejects Gas: [react["rejects_xgm_gas"]]
" + */ + for(var/RQ in react["required"]) + body += " -Component: [RQ]
" + for(var/IH in react["inhibitor"]) + body += " -Inhibitor: [IH]
" + for(var/CL in react["catalysts"]) + body += " -Catalyst: [CL]
" + + var/list/grind_ore = data["grinding"]["ore"] + if(grind_ore && grind_ore.len) + body += "
" + body += "Ore processing results:
" + for(var/PL in grind_ore) + body += " -Grind: [PL]
" + + var/list/grind_mats = data["grinding"]["material"] + if(grind_mats && grind_mats.len) + body += "
" + body += "Material processing results:
" + for(var/PL in grind_mats) + body += " -Grind: [PL]
" + + var/list/grind_plants = data["grinding"]["plant"] + if(grind_plants && grind_plants.len) + body += "
" + body += "Organic processing results:
" + for(var/PL in grind_plants) + body += " -Grind: [PL]
" + + var/list/fluid_pumping = data["fluid"] + if(fluid_pumping && fluid_pumping.len) + body += "
" + body += "Fluid pump results:
" + for(var/PL in fluid_pumping) + body += " -Erosion: [PL]
" + + body += "
" + var/list/produces = data["produces"] + if(produces && produces.len) + body += "Is a component of:
" + for(var/PL in produces) + body += "-[PL]
" + return body diff --git a/code/datums/diseases/lycancoughy.dm b/code/datums/diseases/lycancoughy.dm index 15a49b28c4..7aba6ffc6a 100644 --- a/code/datums/diseases/lycancoughy.dm +++ b/code/datums/diseases/lycancoughy.dm @@ -28,7 +28,7 @@ to_chat(H, span_notice("You itch.")) H.adjustBruteLoss(rand(4, 6)) if(3) - var/obj/item/organ/external/stomach = H.organs_by_name[pick("torso", "groin")] + var/obj/item/organ/external/stomach = H.organs_by_name[pick(BP_TORSO, BP_GROIN)] if(prob(3)) H.emote("cough") @@ -42,7 +42,7 @@ to_chat(H, span_danger("Your stomach growls!")) stomach.take_damage(BRUTE, rand(5, 10)) if(4) - var/obj/item/organ/external/stomach = H.organs_by_name[pick("torso", "groin")] + var/obj/item/organ/external/stomach = H.organs_by_name[pick(BP_TORSO, BP_GROIN)] if(prob(5)) H.emote("cough") diff --git a/code/game/antagonist/station/changeling.dm b/code/game/antagonist/station/changeling.dm index 7a7be183f1..6cd1f09614 100644 --- a/code/game/antagonist/station/changeling.dm +++ b/code/game/antagonist/station/changeling.dm @@ -72,7 +72,7 @@ var/datum/species/S = GLOB.all_species[player.current.client.prefs.species] if(S && (S.flags & (NO_SLEEVE|NO_DNA))) return 0 - if(player.current.client.prefs.organ_data["torso"] == "cyborg") // Full synthetic. // TODO, this to issynthetic()? + if(player.current.client.prefs.organ_data[BP_TORSO] == "cyborg") // Full synthetic. // TODO, this to issynthetic()? return 0 return 1 return 0 diff --git a/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm b/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm index 47afecedee..5ef4de1558 100644 --- a/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm +++ b/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm @@ -52,6 +52,7 @@ color = "#C8A5DC" metabolism = REM * 2 overdose = 5 //This is intentionally low, as we want the ling to take some tox damage, to discourage spamming the ability. + wiki_flag = WIKI_SPOILER /datum/reagent/epinephrine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 33397ffc0f..26d95a341e 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -20,7 +20,7 @@ if(iscultist(user) && !istype(user, /mob/living/simple_mob/construct)) return ..() - var/zone = (user.hand ? "l_arm":"r_arm") + var/zone = (user.hand ? BP_L_ARM:BP_R_ARM) if(ishuman(user)) var/mob/living/carbon/human/H = user var/obj/item/organ/external/affecting = H.get_organ(zone) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index d7a9cbf669..3a5e7adf46 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -50,7 +50,7 @@ var/global/datum/controller/occupations/job_master var/datum/job/job = GetJob(rank) if(!job) return 0 - if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data["brain"]))) + if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]))) return 0 if(jobban_isbanned(player, rank)) return 0 @@ -104,7 +104,7 @@ var/global/datum/controller/occupations/job_master if(!job.player_old_enough(player.client)) Debug("FOC player not old enough, Player: [player]") continue - if(job.minimum_character_age && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data["brain"]))) + if(job.minimum_character_age && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]))) Debug("FOC character not old enough, Player: [player]") continue //VOREStation Code Start @@ -115,7 +115,7 @@ var/global/datum/controller/occupations/job_master Debug("FOC is_job_whitelisted failed, Player: [player]") continue //VOREStation Code End - if(job.is_species_banned(player.client.prefs.species, player.client.prefs.organ_data["brain"]) == TRUE) + if(job.is_species_banned(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]) == TRUE) Debug("FOC character species invalid for job, Player: [player]") continue if(flag && !(player.client.prefs.be_special & flag)) @@ -132,10 +132,10 @@ var/global/datum/controller/occupations/job_master if(!job) continue - if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data["brain"]))) + if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]))) continue - if(job.is_species_banned(player.client.prefs.species, player.client.prefs.organ_data["brain"]) == TRUE) + if(job.is_species_banned(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]) == TRUE) continue if(istype(job, GetJob(JOB_ALT_VISITOR))) // We don't want to give him assistant, that's boring! //VOREStation Edit - Visitor not Assistant @@ -193,10 +193,10 @@ var/global/datum/controller/occupations/job_master if(!V.client) continue var/age = V.read_preference(/datum/preference/numeric/human/age) - if(age < job.get_min_age(V.client.prefs.species, V.client.prefs.organ_data["brain"])) // Nope. + if(age < job.get_min_age(V.client.prefs.species, V.client.prefs.organ_data[O_BRAIN])) // Nope. continue - var/idealage = job.get_ideal_age(V.client.prefs.species, V.client.prefs.organ_data["brain"]) + var/idealage = job.get_ideal_age(V.client.prefs.species, V.client.prefs.organ_data[O_BRAIN]) var/agediff = abs(idealage - age) // Compute the absolute difference in age from target switch(agediff) /// If the math sucks, it's because I almost failed algebra in high school. if(20 to INFINITY) @@ -535,8 +535,8 @@ var/global/datum/controller/occupations/job_master to_chat(H, span_danger("Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug.")) if(istype(H)) //give humans wheelchairs, if they need them. - var/obj/item/organ/external/l_foot = H.get_organ("l_foot") - var/obj/item/organ/external/r_foot = H.get_organ("r_foot") + var/obj/item/organ/external/l_foot = H.get_organ(BP_L_FOOT) + var/obj/item/organ/external/r_foot = H.get_organ(BP_R_FOOT) var/obj/item/storage/S = locate() in H.contents var/obj/item/wheelchair/R if(S) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 461b84ee63..74e0908ffb 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -383,7 +383,7 @@ if(!subject.has_brain()) if(ishuman(subject)) var/mob/living/carbon/human/H = subject - if(H.should_have_organ("brain")) + if(H.should_have_organ(O_BRAIN)) set_scan_temp("No brain detected in subject.", "bad") else set_scan_temp("No brain detected in subject.", "bad") diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index af1eb2270e..8814b138f5 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -88,7 +88,7 @@ if(!(get_dist(src, attached) <= 1 && isturf(attached.loc))) visible_message("The needle is ripped out of [attached], doesn't that hurt?") - attached:apply_damage(3, BRUTE, pick("r_arm", "l_arm")) + attached:apply_damage(3, BRUTE, pick(BP_R_ARM, BP_L_ARM)) attached = null update_icon() return diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index c59a172281..4e822b8605 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -87,8 +87,8 @@ var/global/list/image/splatter_cache=list() if(amount < 1) return - var/obj/item/organ/external/l_foot = perp.get_organ("l_foot") - var/obj/item/organ/external/r_foot = perp.get_organ("r_foot") + var/obj/item/organ/external/l_foot = perp.get_organ(BP_L_FOOT) + var/obj/item/organ/external/r_foot = perp.get_organ(BP_R_FOOT) var/hasfeet = 1 if((!l_foot || l_foot.is_stump()) && (!r_foot || r_foot.is_stump())) hasfeet = 0 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d219b3724d..246fc63a40 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -290,9 +290,9 @@ return // End CHOMPStation Edit if (hasorgans(user)) var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (user.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user, span_notice("You try to move your [temp.name], but cannot!")) return diff --git a/code/game/objects/items/bells.dm b/code/game/objects/items/bells.dm index 9df665424b..e906c0713d 100644 --- a/code/game/objects/items/bells.dm +++ b/code/game/objects/items/bells.dm @@ -73,9 +73,9 @@ /obj/item/deskbell/proc/check_ability(mob/user) if (ishuman(user)) var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(H,span_notice("You try to move your [temp.name], but cannot!")) return 0 diff --git a/code/game/objects/items/toys/toys_vr.dm b/code/game/objects/items/toys/toys_vr.dm index 68db2880df..f6396e1fcf 100644 --- a/code/game/objects/items/toys/toys_vr.dm +++ b/code/game/objects/items/toys/toys_vr.dm @@ -756,7 +756,7 @@ return FALSE if(bullets_left == 1) bullets_left = 0 - var/zone = "head" + var/zone = BP_HEAD if(!(user.has_organ(zone))) // If they somehow don't have a head. zone = "chest" playsound(src, 'sound/effects/snap.ogg', 50, 1) @@ -1044,10 +1044,10 @@ if(!isanimal(user)) if(!user.get_active_hand()) //if active hand is empty var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user,span_notice("You try to move your [temp.name], but cannot!")) return diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 83c26eb1f5..a7d434c810 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -817,15 +817,15 @@ CIGARETTE PACKETS ARE IN FANCY.DM else // Just like the cheap lighter, this time you can shock/burn yourself a little on the hardlight shield to_chat(user, span_warning("You hurt yourself on the shielding!")) if (user.get_left_hand() == src) - user.apply_damage(1,SEARING,"l_hand") - user.apply_damage(2,ELECTROCUTE,"l_hand") - user.apply_damage(3,CLONE,"l_hand") - user.apply_damage(4,ELECTROMAG,"l_hand") + user.apply_damage(1,SEARING,BP_L_HAND) + user.apply_damage(2,ELECTROCUTE,BP_L_HAND) + user.apply_damage(3,CLONE,BP_L_HAND) + user.apply_damage(4,ELECTROMAG,BP_L_HAND) else - user.apply_damage(1,SEARING,"r_hand") - user.apply_damage(2,ELECTROCUTE,"r_hand") - user.apply_damage(3,CLONE,"r_hand") - user.apply_damage(4,ELECTROMAG,"r_hand") + user.apply_damage(1,SEARING,BP_R_HAND) + user.apply_damage(2,ELECTROCUTE,BP_R_HAND) + user.apply_damage(3,CLONE,BP_R_HAND) + user.apply_damage(4,ELECTROMAG,BP_R_HAND) user.visible_message(span_notice("After a few attempts, [user] manages to activate the [src], they however sting themselves on the shielding!")) set_light(2) @@ -888,15 +888,15 @@ CIGARETTE PACKETS ARE IN FANCY.DM else // Just like with the cheap lighter, but this time you can hurt yourself on the heated phoron field to_chat(user, span_warning("You singe yourself on the phoron shielding the excited supermatter!")) if (user.get_left_hand() == src) - user.apply_damage(30,HALLOSS,"l_hand") + user.apply_damage(30,HALLOSS,BP_L_HAND) user.apply_effect(20,IRRADIATE) - user.apply_damage(5,BURN,"l_hand") - user.apply_damage(5,ELECTROCUTE,"l_hand") + user.apply_damage(5,BURN,BP_L_HAND) + user.apply_damage(5,ELECTROCUTE,BP_L_HAND) else - user.apply_damage(30,HALLOSS,"r_hand") + user.apply_damage(30,HALLOSS,BP_R_HAND) user.apply_effect(20,IRRADIATE) - user.apply_damage(5,BURN,"r_hand") - user.apply_damage(5,ELECTROCUTE,"r_hand") + user.apply_damage(5,BURN,BP_R_HAND) + user.apply_damage(5,ELECTROCUTE,BP_R_HAND) user.visible_message(span_notice("After a few attempts, [user] manages to activate the [src], they however burn themselves with the heated phoron field!")) set_light(2) @@ -957,73 +957,73 @@ CIGARETTE PACKETS ARE IN FANCY.DM to_chat(user, span_rose("[user] safely reveals the supermatter shard within the [src]!")) user.visible_message(span_rose("You safely revealed the supermatter shard within the [src]!")) if (user.get_left_hand() == src) - user.apply_damage(1, IRRADIATE, "l_hand") + user.apply_damage(1, IRRADIATE, BP_L_HAND) else // Even using this safely will irradiate you a tiny tiny bit. - user.apply_damage(1, IRRADIATE, "r_hand") + user.apply_damage(1, IRRADIATE, BP_R_HAND) if(23 to 33) to_chat(user, span_warning("[user]'s hand slipped and they brush against the supermatter within [src]!")) user.visible_message(span_notice("You accidentally grazed your hand across the supermatter!")) if (user.get_left_hand() == src) - user.apply_damage(10, IRRADIATE, "l_hand") - user.apply_damage(20, BURN, "l_hand") - user.apply_damage(20, ELECTROCUTE, "l_hand") - user.apply_damage(50, AGONY, "l_hand") + user.apply_damage(10, IRRADIATE, BP_L_HAND) + user.apply_damage(20, BURN, BP_L_HAND) + user.apply_damage(20, ELECTROCUTE, BP_L_HAND) + user.apply_damage(50, AGONY, BP_L_HAND) else // One of the outcomes will burn and shock you, the pain is the worst part of this one though. - user.apply_damage(10, IRRADIATE, "r_hand") - user.apply_damage(20, BURN, "r_hand") - user.apply_damage(20, ELECTROCUTE, "r_hand") - user.apply_damage(50, AGONY, "r_hand") + user.apply_damage(10, IRRADIATE, BP_R_HAND) + user.apply_damage(20, BURN, BP_R_HAND) + user.apply_damage(20, ELECTROCUTE, BP_R_HAND) + user.apply_damage(50, AGONY, BP_R_HAND) if(34 to 44) to_chat(user, span_warning("[user] burned themselves on the [src]!")) user.visible_message(span_notice("You accidentally burn yourself on the [src]!")) if (user.get_left_hand() == src) - user.apply_damage(30, IRRADIATE, "l_hand") - user.apply_damage(20, SEARING, "l_hand") - user.apply_damage(15, BURN, "l_hand") + user.apply_damage(30, IRRADIATE, BP_L_HAND) + user.apply_damage(20, SEARING, BP_L_HAND) + user.apply_damage(15, BURN, BP_L_HAND) else // One of the outcomes is pure burn and radiation. - user.apply_damage(30, IRRADIATE, "r_hand") - user.apply_damage(20, SEARING, "r_hand") - user.apply_damage(15, BURN, "r_hand") + user.apply_damage(30, IRRADIATE, BP_R_HAND) + user.apply_damage(20, SEARING, BP_R_HAND) + user.apply_damage(15, BURN, BP_R_HAND) if(45 to 55) to_chat(user, span_warning("[user] fumbled the [src] and the supermatter let out sparks!")) user.visible_message(span_notice("You fumble the [src], letting the supermatter spark as the case opens!")) if (user.get_left_hand() == src) - user.apply_damage(1, ELECTROCUTE, "l_hand") - user.apply_damage(100, ELECTROMAG, "l_hand") + user.apply_damage(1, ELECTROCUTE, BP_L_HAND) + user.apply_damage(100, ELECTROMAG, BP_L_HAND) else // This one is mostly dangerous to synthetics and it will EMP you. But otherwise it's safe. - user.apply_damage(1, ELECTROCUTE, "r_hand") - user.apply_damage(100, ELECTROMAG, "r_hand") + user.apply_damage(1, ELECTROCUTE, BP_R_HAND) + user.apply_damage(100, ELECTROMAG, BP_R_HAND) if(56 to 66) to_chat(user, span_warning("[user] struggles to open their [src], but when they do they get burned by the extreme heat within!")) user.visible_message(span_notice("You struggle to get the case to open, and when it does the heat that pours out of the [src] burns!")) if (user.get_left_hand() == src) - user.apply_damage(1, IRRADIATE, "l_hand") - user.apply_damage(1, BRUISE, "l_hand") - user.apply_damage(200, BURN, "l_hand") + user.apply_damage(1, IRRADIATE, BP_L_HAND) + user.apply_damage(1, BRUISE, BP_L_HAND) + user.apply_damage(200, BURN, BP_L_HAND) user.drop_l_hand() else // This will INSTA-DUST your hand that you're holding the item in, and then make you drop the lighter. - user.apply_damage(1, IRRADIATE, "r_hand") - user.apply_damage(1, BRUISE, "r_hand") - user.apply_damage(200, BURN, "r_hand") + user.apply_damage(1, IRRADIATE, BP_R_HAND) + user.apply_damage(1, BRUISE, BP_R_HAND) + user.apply_damage(200, BURN, BP_R_HAND) user.drop_r_hand() if(67 to 77) to_chat(user, span_warning("Ouch! While pushing on the release to open the [src], [user]'s finger slipped right as the case opened, pressing their finger firm against the supermatter!")) user.visible_message(span_notice("You accidentally pushed your finger against the supermatter!")) if (user.get_left_hand() == src) - user.apply_damage(50, HALLOSS, "l_hand") - user.apply_damage(40, IRRADIATE, "l_hand") - user.apply_damage(30, BURN, "l_hand") - user.apply_damage(20, TOX, "l_hand") - user.apply_damage(10, ELECTROCUTE, "l_hand") + user.apply_damage(50, HALLOSS, BP_L_HAND) + user.apply_damage(40, IRRADIATE, BP_L_HAND) + user.apply_damage(30, BURN, BP_L_HAND) + user.apply_damage(20, TOX, BP_L_HAND) + user.apply_damage(10, ELECTROCUTE, BP_L_HAND) user.apply_effect(25, STUTTER) user.apply_effect(15, SLUR) user.apply_effect(5, STUN) else // This one is VERY punishing, you get a ton of damage, a lot of pain, and a minor stun. Once the stun goes away you'll be stuttering for awhile as if in crit. - user.apply_damage(50, HALLOSS, "r_hand") - user.apply_damage(40, IRRADIATE, "r_hand") - user.apply_damage(30, BURN, "r_hand") - user.apply_damage(20, TOX, "r_hand") - user.apply_damage(10, ELECTROCUTE, "r_hand") + user.apply_damage(50, HALLOSS, BP_R_HAND) + user.apply_damage(40, IRRADIATE, BP_R_HAND) + user.apply_damage(30, BURN, BP_R_HAND) + user.apply_damage(20, TOX, BP_R_HAND) + user.apply_damage(10, ELECTROCUTE, BP_R_HAND) user.apply_effect(25, STUTTER) user.apply_effect(15, SLUR) user.apply_effect(5, STUN) @@ -1031,26 +1031,26 @@ CIGARETTE PACKETS ARE IN FANCY.DM to_chat(user, span_notice("[user] managed to pinch themselves on the case of their [src]... it could have been worse.")) user.visible_message(span_notice("You manage to pinch yourself on the case!")) if (user.get_left_hand() == src) - user.apply_damage(1, CLONE, "l_hand") - user.apply_damage(1, HALLOSS, "l_hand") + user.apply_damage(1, CLONE, BP_L_HAND) + user.apply_damage(1, HALLOSS, BP_L_HAND) else // Aside from the base, this one isn't punishing outside of giving you genetic damage. - user.apply_damage(1, CLONE, "r_hand") - user.apply_damage(1, HALLOSS, "r_hand") + user.apply_damage(1, CLONE, BP_R_HAND) + user.apply_damage(1, HALLOSS, BP_R_HAND) if(89 to 99) to_chat(user, span_notice("[user] opened the [src] but forgot that you aren't supposed to look at supermatter!")) user.visible_message(span_notice("You find yourself looking at the supermatter for longer than you should...")) if (user.get_left_hand() == src) - user.apply_damage(15, HALLOSS, "l_hand") + user.apply_damage(15, HALLOSS, BP_L_HAND) user.apply_effect(5, WEAKEN) - user.apply_damage(15, IRRADIATE, "l_hand") + user.apply_damage(15, IRRADIATE, BP_L_HAND) user.apply_effect(100, EYE_BLUR) user.apply_effect(50, AGONY) user.apply_damage(5, OXY) user.eye_blurry = 10 else // This one just blinds and blurs your screen, but otherwise doesn't actually risk harming you. Even the oxy damage heals on its own. - user.apply_damage(15, HALLOSS, "r_hand") + user.apply_damage(15, HALLOSS, BP_R_HAND) user.apply_effect(5, WEAKEN) - user.apply_damage(15, IRRADIATE, "l_hand") + user.apply_damage(15, IRRADIATE, BP_L_HAND) user.apply_effect(100, EYE_BLUR) user.apply_effect(50, AGONY) user.apply_damage(15, OXY) diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm index b4bbcb3685..0d071569ef 100644 --- a/code/game/objects/items/weapons/material/shards.dm +++ b/code/game/objects/items/weapons/material/shards.dm @@ -126,7 +126,7 @@ to_chat(H, span_danger("You step on \the [src]!")) - var/list/check = list("l_foot", "r_foot") + var/list/check = list(BP_L_FOOT, BP_R_FOOT) while(check.len) var/picked = pick(check) var/obj/item/organ/external/affecting = H.get_organ(picked) diff --git a/code/game/objects/items/weapons/storage/laundry_basket.dm b/code/game/objects/items/weapons/storage/laundry_basket.dm index 5cfd391d73..916964c1e9 100644 --- a/code/game/objects/items/weapons/storage/laundry_basket.dm +++ b/code/game/objects/items/weapons/storage/laundry_basket.dm @@ -24,9 +24,9 @@ /obj/item/storage/laundry_basket/attack_hand(mob/living/user as mob) if(ishuman(user)) var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.get_organ("r_hand") + var/obj/item/organ/external/temp = H.get_organ(BP_R_HAND) if (user.hand) - temp = H.get_organ("l_hand") + temp = H.get_organ(BP_L_HAND) if(!temp) to_chat(user, span_warning("You need two hands to pick this up!")) return diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index ef781aea0b..9b32e590fc 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -87,7 +87,7 @@ H.update_inv_wear_mask() playsound(src, 'sound/effects/tape.ogg',25) - else if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand") + else if(user.zone_sel.selecting == BP_R_HAND || user.zone_sel.selecting == BP_L_HAND) if(!can_place(H, user)) return diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm index afbb7acc8d..16cee9deea 100644 --- a/code/game/objects/items/weapons/traps.dm +++ b/code/game/objects/items/weapons/traps.dm @@ -85,7 +85,7 @@ if(L.lying) target_zone = ran_zone() else - target_zone = pick("l_foot", "r_foot", "l_leg", "r_leg") + target_zone = pick(BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG) //armour var/blocked = L.run_armor_check(target_zone, "melee") @@ -333,7 +333,7 @@ if(L.lying) target_zone = ran_zone() else - target_zone = pick("l_foot", "r_foot", "l_leg", "r_leg") + target_zone = pick(BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG) //armour var/blocked = L.run_armor_check(target_zone, "melee") @@ -370,7 +370,7 @@ to_chat(H, span_danger("You step directly on \the [src]!")) - var/list/check = list("l_foot", "r_foot") + var/list/check = list(BP_L_FOOT, BP_R_FOOT) while(check.len) var/picked = pick(check) var/obj/item/organ/external/affecting = H.get_organ(picked) diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index d67b848a05..f7e342f19e 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -50,9 +50,9 @@ return if (ishuman(user)) var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (user.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user, span_notice("You try to move your [temp.name], but cannot!")) return diff --git a/code/game/objects/structures/simple_doors_vr.dm b/code/game/objects/structures/simple_doors_vr.dm index 6c38272f14..e45608ca2c 100644 --- a/code/game/objects/structures/simple_doors_vr.dm +++ b/code/game/objects/structures/simple_doors_vr.dm @@ -13,6 +13,7 @@ door_icon_base = "flockdoor" sheet_singular_name = "quanta" sheet_plural_name = "quanta" + wiki_flag = WIKI_SPOILER /obj/structure/simple_door/flock name = "aperture" diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 30498fc7b0..957ffc44b6 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -517,9 +517,9 @@ /obj/structure/sink/attack_hand(mob/user as mob) if (ishuman(user)) var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user, span_notice("You try to move your [temp.name], but cannot!")) return diff --git a/code/game/turfs/weird_turfs_vr.dm b/code/game/turfs/weird_turfs_vr.dm index b2de670f74..a3011100d7 100644 --- a/code/game/turfs/weird_turfs_vr.dm +++ b/code/game/turfs/weird_turfs_vr.dm @@ -28,7 +28,7 @@ if(prob(5)) L.visible_message("[L]'s body gives off a faint, sparking, haze...", "Your body gives off a faint, sparking, haze...", runemessage = "gives off a faint, sparking haze") else if(istype(L.species, /datum/species/shadekin)) - var/obj/item/organ/internal/brain/shadekin/B = L.internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/shadekin/B = L.internal_organs_by_name[O_BRAIN] B.dark_energy += 10 if(prob(10)) to_chat(L, span_notice("You can feel the energy flowing into you!")) @@ -87,7 +87,7 @@ if(prob(5)) L.visible_message("[L]'s body gives off a faint, sparking, haze...", "Your body gives off a faint, sparking, haze...", runemessage = "gives off a faint, sparking haze") else if(istype(L.species, /datum/species/shadekin)) - var/obj/item/organ/internal/brain/shadekin/B = L.internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/shadekin/B = L.internal_organs_by_name[O_BRAIN] B.dark_energy += 10 if(prob(10)) to_chat(L, span_notice("You can feel the energy flowing into you!")) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index b7c73b85f6..fdcb825a9f 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -29,9 +29,9 @@ switch(type) if("feet") if(!H.shoes) - affecting = H.get_organ(pick("l_leg", "r_leg")) + affecting = H.get_organ(pick(BP_L_LEG, BP_R_LEG)) H.Weaken(3) - if("l_hand", "r_hand") + if(BP_L_HAND, BP_R_HAND) if(!H.gloves) affecting = H.get_organ(type) H.Stun(3) @@ -54,9 +54,9 @@ to_chat(user, span_notice("You arm [src].")) else if((CLUMSY in user.mutations) && prob(50)) - var/which_hand = "l_hand" + var/which_hand = BP_L_HAND if(!user.hand) - which_hand = "r_hand" + which_hand = BP_R_HAND triggered(user, which_hand) user.visible_message(span_warning("[user] accidentally sets off [src], breaking their fingers."), \ span_warning("You accidentally trigger [src]!")) @@ -70,9 +70,9 @@ /obj/item/assembly/mousetrap/attack_hand(var/mob/living/user) if(armed) if((CLUMSY in user.mutations) && prob(50)) - var/which_hand = "l_hand" + var/which_hand = BP_L_HAND if(!user.hand) - which_hand = "r_hand" + which_hand = BP_R_HAND triggered(user, which_hand) user.visible_message(span_warning("[user] accidentally sets off [src], breaking their fingers."), \ span_warning("You accidentally trigger [src]!")) @@ -97,7 +97,7 @@ if(armed) finder.visible_message(span_warning("[finder] accidentally sets off [src], breaking their fingers."), \ span_warning("You accidentally trigger [src]!")) - triggered(finder, finder.hand ? "l_hand" : "r_hand") + triggered(finder, finder.hand ? BP_L_HAND : BP_R_HAND) return 1 //end the search! return 0 diff --git a/code/modules/catalogue/catalogue_data.dm b/code/modules/catalogue/catalogue_data.dm index 1b4d9107e2..332ab43310 100644 --- a/code/modules/catalogue/catalogue_data.dm +++ b/code/modules/catalogue/catalogue_data.dm @@ -351,7 +351,7 @@ GLOBAL_DATUM_INIT(catalogue_data, /datum/category_collection/catalogue, new) name = "TSC - Major Bill's Transportation" datum_to_copy = /datum/lore/organization/tsc/mbt -/datum/category_item/catalogue/information/organization/commonwealth //VS EDIT 1 +/datum/category_item/catalogue/information/organization/solgov //VS EDIT 1 name = "Government - Commonwealth of Sol-Procyon" //VS EDIT 2 datum_to_copy = /datum/lore/organization/gov/commonwealth //VS EDIT 3 diff --git a/code/modules/catalogue/catalogue_data_vr.dm b/code/modules/catalogue/catalogue_data_vr.dm index 8e2285ec37..a69724c9f2 100644 --- a/code/modules/catalogue/catalogue_data_vr.dm +++ b/code/modules/catalogue/catalogue_data_vr.dm @@ -1,6 +1,3 @@ -/datum/category_item/catalogue/information/organization/solgov - name = "Government - Commonwealth of Sol-Procyon" - //TODO: VIRGO_LORE_WRITING_WIP - this whole file //CHOMPedits: basically every "desc" variable in this file. diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 994c803331..c72a5d31b7 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -845,7 +845,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O // Full prosthetic bodies without a brain are borderline unkillable so make sure they have a brain to remove/destroy. var/datum/species/current_species = GLOB.all_species[pref.species] - if(!current_species.has_organ["brain"]) + if(!current_species.has_organ[O_BRAIN]) limb_selection_list -= "Full Body" else if(pref.organ_data[BP_TORSO] == "cyborg") limb_selection_list |= "Head" @@ -990,7 +990,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O if(pref.organ_data[BP_HEAD] != "cyborg") to_chat(user, span_warning("You may only select a cybernetic or synthetic brain if you have a full prosthetic body.")) return - organ = "brain" + organ = O_BRAIN var/datum/species/current_species = GLOB.all_species[pref.species] var/list/organ_choices = list("Normal") diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index 01f600832b..b5f296e505 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -167,11 +167,11 @@ . += "[rank]" + span_bold(" \[WHITELIST ONLY]") + "" continue //VOREStation Add End - if(job.is_species_banned(user.client.prefs.species, user.client.prefs.organ_data["brain"]) == TRUE) + if(job.is_species_banned(user.client.prefs.species, user.client.prefs.organ_data[O_BRAIN]) == TRUE) . += "[rank] \[THIS RACE/BRAIN TYPE CANNOT TAKE THIS ROLE.\]" continue - if((job.minimum_character_age || job.min_age_by_species) && user.client && (user.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(user.client.prefs.species, user.client.prefs.organ_data["brain"]))) - . += "[rank] \[MINIMUM CHARACTER AGE FOR SELECTED RACE/BRAIN TYPE: [job.get_min_age(user.client.prefs.species, user.client.prefs.organ_data["brain"])]\]" + if((job.minimum_character_age || job.min_age_by_species) && user.client && (user.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(user.client.prefs.species, user.client.prefs.organ_data[O_BRAIN]))) + . += "[rank] \[MINIMUM CHARACTER AGE FOR SELECTED RACE/BRAIN TYPE: [job.get_min_age(user.client.prefs.species, user.client.prefs.organ_data[O_BRAIN])]\]" continue if((pref.job_civilian_low & ASSISTANT) && job.type != /datum/job/assistant) . += span_gray("[rank]") + "" diff --git a/code/modules/clothing/spacesuits/rig/modules/modules.dm b/code/modules/clothing/spacesuits/rig/modules/modules.dm index 974b65dce0..f9765faecd 100644 --- a/code/modules/clothing/spacesuits/rig/modules/modules.dm +++ b/code/modules/clothing/spacesuits/rig/modules/modules.dm @@ -53,7 +53,7 @@ var/activate_string = "Activate" var/deactivate_string = "Deactivate" - var/list/stat_rig_module/stat_modules = new() + var/list/stat_modules = new() /obj/item/rig_module/examine() . = ..() @@ -129,11 +129,11 @@ charges = processed_charges - stat_modules += new/stat_rig_module/activate(src) - stat_modules += new/stat_rig_module/deactivate(src) - stat_modules += new/stat_rig_module/engage(src) - stat_modules += new/stat_rig_module/select(src) - stat_modules += new/stat_rig_module/charge(src) + stat_modules += new/atom/movable/stat_rig_module/activate(src) + stat_modules += new/atom/movable/stat_rig_module/deactivate(src) + stat_modules += new/atom/movable/stat_rig_module/engage(src) + stat_modules += new/atom/movable/stat_rig_module/select(src) + stat_modules += new/atom/movable/stat_rig_module/charge(src) /obj/item/rig_module/Destroy() holder.installed_modules -= src @@ -236,28 +236,27 @@ /obj/item/rig_module/proc/accepts_item(var/obj/item/input_device) return 0 -/stat_rig_module - parent_type = /atom/movable +/atom/movable/stat_rig_module var/module_mode = "" var/obj/item/rig_module/module -/stat_rig_module/Initialize(mapload) +/atom/movable/stat_rig_module/Initialize(mapload) . = ..() module = loc if(!istype(module)) return INITIALIZE_HINT_QDEL -/stat_rig_module/Destroy() +/atom/movable/stat_rig_module/Destroy() module = null . = ..() -/stat_rig_module/proc/AddHref(var/list/href_list) +/atom/movable/stat_rig_module/proc/AddHref(var/list/href_list) return -/stat_rig_module/proc/CanUse() +/atom/movable/stat_rig_module/proc/CanUse() return 0 -/stat_rig_module/Click() +/atom/movable/stat_rig_module/Click() if(CanUse()) switch(module_mode) if("select") @@ -276,10 +275,10 @@ if("select_charge_type") module.charge_selected = module.charges[module.charges.Find(module.charge_selected)] -/stat_rig_module/DblClick() +/atom/movable/stat_rig_module/DblClick() return Click() -/stat_rig_module/activate/Initialize(mapload) +/atom/movable/stat_rig_module/activate/Initialize(mapload) . = ..() if(!istype(module)) return INITIALIZE_HINT_QDEL @@ -288,10 +287,10 @@ name += " ([module.active_power_cost*10]A)" module_mode = "activate" -/stat_rig_module/activate/CanUse() +/atom/movable/stat_rig_module/activate/CanUse() return module.toggleable && !module.active -/stat_rig_module/deactivate/Initialize(mapload) +/atom/movable/stat_rig_module/deactivate/Initialize(mapload) . = ..() if(!istype(module)) return INITIALIZE_HINT_QDEL @@ -302,10 +301,10 @@ module_mode = "deactivate" -/stat_rig_module/deactivate/CanUse() +/atom/movable/stat_rig_module/deactivate/CanUse() return module.toggleable && module.active -/stat_rig_module/engage/Initialize(mapload) +/atom/movable/stat_rig_module/engage/Initialize(mapload) . = ..() if(!istype(module)) return INITIALIZE_HINT_QDEL @@ -314,26 +313,26 @@ name += " ([module.use_power_cost*10]E)" module_mode = "engage" -/stat_rig_module/engage/CanUse() +/atom/movable/stat_rig_module/engage/CanUse() return module.usable -/stat_rig_module/select/Initialize(mapload) +/atom/movable/stat_rig_module/select/Initialize(mapload) . = ..() name = "Select" module_mode = "select" -/stat_rig_module/select/CanUse() +/atom/movable/stat_rig_module/select/CanUse() if(module.selectable) name = module.holder.selected_module == module ? "Selected" : "Select" return 1 return 0 -/stat_rig_module/charge/Initialize(mapload) +/atom/movable/stat_rig_module/charge/Initialize(mapload) . = ..() name = "Change Charge" module_mode = "select_charge_type" -/stat_rig_module/charge/AddHref(var/list/href_list) +/atom/movable/stat_rig_module/charge/AddHref(var/list/href_list) var/charge_index = module.charges.Find(module.charge_selected) if(!charge_index) charge_index = 0 @@ -342,7 +341,7 @@ href_list["charge_type"] = module.charges[charge_index] -/stat_rig_module/charge/CanUse() +/atom/movable/stat_rig_module/charge/CanUse() if(module.charges && module.charges.len) var/datum/rig_charge/charge = module.charges[module.charge_selected] name = "[charge.display_name] ([charge.charges]C) - Change" diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 7861c44e9b..b56a25976d 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -996,8 +996,8 @@ return wearer.pulledby.relaymove(wearer, direction) else if(istype(wearer.buckled, /obj/structure/bed/chair/wheelchair)) if(ishuman(wearer.buckled)) - var/obj/item/organ/external/l_hand = wearer.get_organ("l_hand") - var/obj/item/organ/external/r_hand = wearer.get_organ("r_hand") + var/obj/item/organ/external/l_hand = wearer.get_organ(BP_L_HAND) + var/obj/item/organ/external/r_hand = wearer.get_organ(BP_R_HAND) if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED))) return // No hands to drive your chair? Tough luck! wearer_move_delay += 2 diff --git a/code/modules/detectivework/tools/sample_kits.dm b/code/modules/detectivework/tools/sample_kits.dm index 552a8b66b4..d39cfa5cad 100644 --- a/code/modules/detectivework/tools/sample_kits.dm +++ b/code/modules/detectivework/tools/sample_kits.dm @@ -94,13 +94,13 @@ user.visible_message(span_danger("\The [user] tries to take prints from \the [H], but they move away.")) return 1 - if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand") + if(user.zone_sel.selecting == BP_R_HAND || user.zone_sel.selecting == BP_L_HAND) var/has_hand - var/obj/item/organ/external/O = H.organs_by_name["r_hand"] + var/obj/item/organ/external/O = H.organs_by_name[BP_R_HAND] if(istype(O) && !O.is_stump()) has_hand = 1 else - O = H.organs_by_name["l_hand"] + O = H.organs_by_name[BP_L_HAND] if(istype(O) && !O.is_stump()) has_hand = 1 if(!has_hand) diff --git a/code/modules/detectivework/tools/scanner.dm b/code/modules/detectivework/tools/scanner.dm index 2ac3f36f3c..a4a263938d 100644 --- a/code/modules/detectivework/tools/scanner.dm +++ b/code/modules/detectivework/tools/scanner.dm @@ -28,7 +28,7 @@ to_chat(user, span_notice("No fingerprints found on [M]")) flick("[icon_state]0",src) return 0 - else if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand") + else if(user.zone_sel.selecting == BP_R_HAND || user.zone_sel.selecting == BP_L_HAND) var/obj/item/sample/print/P = new /obj/item/sample/print(user.loc) P.attack(M, user) to_chat(user, span_notice("Done printing.")) diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm index d8f7a02ff0..ac2b10d922 100644 --- a/code/modules/economy/Accounts.dm +++ b/code/modules/economy/Accounts.dm @@ -112,3 +112,41 @@ for(var/datum/money_account/D in all_money_accounts) if(D.account_number == account_number) return D + +//Performing purchases by ID card +/proc/purchase_with_id_card(obj/item/card/id/I, mob/M, var/purchase_title = "Company", var/purchase_terminal = "Terminal", var/purchase_desc = "Purchase of Something", var/price = 0) + // Check if account can pay at all + var/datum/money_account/customer_account = get_account(I.associated_account_number) + if(!customer_account) + to_chat(M, span_warning("Error: Unable to access account. Please contact technical support if problem persists.")) + return FALSE + if(customer_account.suspended) + to_chat(M, span_warning("Unable to access account: account suspended.")) + return FALSE + // Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is + // empty at high security levels + if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) + var/attempt_pin = tgui_input_number(M, "Enter pin code", "Vendor transaction") + customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) + if(!customer_account) + to_chat(M, span_warning("Unable to access account: incorrect credentials.")) + return FALSE + if(price > customer_account.money) + to_chat(M, span_warning("Insufficient funds in account.")) + return FALSE + // debit money from the purchaser's account + customer_account.money -= price + // create entry in the purchaser's account log + var/datum/transaction/T = new() + T.target_name = "[purchase_title] (via [purchase_terminal])" + T.purpose = purchase_desc + if(price > 0) + T.amount = "([price])" + else + T.amount = "[price]" + T.source_terminal = purchase_terminal + T.date = current_date_string + T.time = stationtime2text() + // Okay to move the money at this point + customer_account.transaction_log.Add(T) + return TRUE diff --git a/code/modules/economy/vending.dm b/code/modules/economy/vending.dm index b3716d7ac5..7287b23423 100644 --- a/code/modules/economy/vending.dm +++ b/code/modules/economy/vending.dm @@ -316,51 +316,12 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/machinery/vending/proc/pay_with_card(obj/item/card/id/I, mob/M) visible_message(span_info("[M] swipes a card through [src].")) playsound(src, 'sound/machines/id_swipe.ogg', 50, 1) - - var/datum/money_account/customer_account = get_account(I.associated_account_number) - if(!customer_account) - to_chat(M, span_warning("Error: Unable to access account. Please contact technical support if problem persists.")) + if(!purchase_with_id_card(I, M, vendor_account.owner_name, name, "Purchase of [currently_vending.item_name]", currently_vending.price)) return FALSE - - if(customer_account.suspended) - to_chat(M, span_warning("Unable to access account: account suspended.")) - return FALSE - - // Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is - // empty at high security levels - if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) - var/attempt_pin = tgui_input_number(M, "Enter pin code", "Vendor transaction") - customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) - - if(!customer_account) - to_chat(M, span_warning("Unable to access account: incorrect credentials.")) - return FALSE - - if(currently_vending.price > customer_account.money) - to_chat(M, span_warning("Insufficient funds in account.")) - return FALSE - - // Okay to move the money at this point - - // debit money from the purchaser's account - customer_account.money -= currently_vending.price - - // create entry in the purchaser's account log - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [name])" - T.purpose = "Purchase of [currently_vending.item_name]" - if(currently_vending.price > 0) - T.amount = "([currently_vending.price])" - else - T.amount = "[currently_vending.price]" - T.source_terminal = name - T.date = current_date_string - T.time = stationtime2text() - customer_account.transaction_log.Add(T) - // Give the vendor the money. We use the account owner name, which means // that purchases made with stolen/borrowed card will look like the card // owner made them + var/datum/money_account/customer_account = get_account(I.associated_account_number) credit_purchase(customer_account.owner_name) return 1 diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm index b2f5608878..010e594416 100644 --- a/code/modules/food/food/snacks.dm +++ b/code/modules/food/food/snacks.dm @@ -902,6 +902,7 @@ reagents.add_reagent(REAGENT_ID_POISONBERRYJUICE, 5) /obj/item/reagent_containers/food/snacks/donut/plain/jelly/slimejelly + name = "slime jelly donut" filling_color = "#ED1169" /obj/item/reagent_containers/food/snacks/donut/plain/jelly/slimejelly/Initialize(mapload) @@ -909,6 +910,7 @@ reagents.add_reagent(REAGENT_ID_SLIMEJELLY, 5) /obj/item/reagent_containers/food/snacks/donut/plain/jelly/cherryjelly + name = "cherry jelly donut" filling_color = "#ED1169" /obj/item/reagent_containers/food/snacks/donut/plain/jelly/cherryjelly/Initialize(mapload) @@ -1557,6 +1559,7 @@ nutriment_desc = list("sweetness" = 2, "pie" = 3) bitesize = 3 +/obj/item/reagent_containers/food/snacks/ber /obj/item/reagent_containers/food/snacks/berryclafoutis/berry/Initialize(mapload) . = ..() reagents.add_reagent(REAGENT_ID_BERRYJUICE, 5) @@ -2223,6 +2226,12 @@ nutriment_desc = list("toasted bread" = 2) bitesize = 3 +/obj/item/reagent_containers/food/snacks/jelliedtoast/cherry + name = "Cherry Jellied Toast" + +/obj/item/reagent_containers/food/snacks/jelliedtoast/slime + name = "Slime Jellied Toast" + /obj/item/reagent_containers/food/snacks/jelliedtoast/cherry/Initialize(mapload) . = ..() reagents.add_reagent(REAGENT_ID_CHERRYJELLY, 5) @@ -2264,6 +2273,12 @@ nutriment_desc = list("buns" = 5) bitesize = 2 +/obj/item/reagent_containers/food/snacks/jellyburger/slime + name = "Slime Jelly Burger" + +/obj/item/reagent_containers/food/snacks/jellyburger/cherry + name = "Cherry Jelly Burger" + /obj/item/reagent_containers/food/snacks/jellyburger/slime/Initialize(mapload) . = ..() reagents.add_reagent(REAGENT_ID_SLIMEJELLY, 5) @@ -2521,6 +2536,15 @@ nutriment_desc = list("bread" = 2) bitesize = 3 +/obj/item/reagent_containers/food/snacks/jellysandwich/slime + name = "Slime Jelly Sandwich" + +/obj/item/reagent_containers/food/snacks/jellysandwich/slime + name = "Cherry Jelly Sandwich" + +/obj/item/reagent_containers/food/snacks/jellysandwich/peanutbutter + name = "Peanut Butter Jelly Sandwich" + /obj/item/reagent_containers/food/snacks/jellysandwich/slime/Initialize(mapload) . = ..() reagents.add_reagent(REAGENT_ID_SLIMEJELLY, 5) @@ -3755,11 +3779,13 @@ trash = /obj/item/trash/plate /obj/item/reagent_containers/food/snacks/gigapuddi/happy + name = "Astro-Pudding (Happy)" desc = "A crème caramel of astronomical size, made with extra love." icon = 'icons/obj/food.dmi' icon_state = "happypuddi" /obj/item/reagent_containers/food/snacks/gigapuddi/anger + name = "Astro-Pudding (Angry)" desc = "A crème caramel of astronomical size, made with extra hate." icon_state = "angerpuddi" @@ -4088,7 +4114,7 @@ bitesize = 2 /obj/item/reagent_containers/food/snacks/pizzacrunchslice - name = "pizza crunch" + name = "pizza crunch slice" desc = "A little piece of a heart attack. It's toppings are a mystery, hidden under batter" icon_state = "pizzacrunchslice" filling_color = "#BAA14C" @@ -4603,8 +4629,8 @@ reagents.add_reagent(REAGENT_ID_SUGAR, 5) /obj/item/reagent_containers/food/snacks/roastedsunflower - name = "sunflower seeds" - desc = "Sunflower seeds!" + name = "roasted sunflower seeds" + desc = "Roasted sunflower seeds!" icon = 'icons/obj/food.dmi' icon_state = "sunflowerseed" bitesize = 1 @@ -6492,10 +6518,12 @@ bitesize = 1 /obj/item/reagent_containers/food/snacks/omurice/heart + name = "omelette rice (Love)" icon = 'icons/obj/food.dmi' icon_state = "omuriceheart" /obj/item/reagent_containers/food/snacks/omurice/face + name = "omelette rice (Cute)" icon = 'icons/obj/food.dmi' icon_state = "omuriceface" diff --git a/code/modules/food/food/snacks_vr.dm b/code/modules/food/food/snacks_vr.dm index 7e29b10387..77d6c5625f 100644 --- a/code/modules/food/food/snacks_vr.dm +++ b/code/modules/food/food/snacks_vr.dm @@ -15,6 +15,7 @@ bitesize = 5 /obj/item/reagent_containers/food/snacks/slice/sushi/filled + name = "stuffed sushi roll" name = "piece of sushi" desc = "A slice of a larger sushi roll, ready to devour." icon = 'icons/obj/food_vr.dmi' @@ -649,7 +650,7 @@ bitesize = 3 /obj/item/reagent_containers/food/snacks/grub_purple - name = "pink candy grub" + name = "purple candy grub" desc = "A thoroughly candied grub, it smells of grape." icon = 'icons/obj/food_vr.dmi' icon_state = "grub_purple" @@ -661,7 +662,7 @@ bitesize = 3 /obj/item/reagent_containers/food/snacks/grub_blue - name = "pink candy grub" + name = "blue candy grub" desc = "A thoroughly candied grub, it smells of blueberry." icon = 'icons/obj/food_vr.dmi' icon_state = "grub_blue" diff --git a/code/modules/food/food/superfoods.dm b/code/modules/food/food/superfoods.dm index ded40c4a6e..d9025aa5bc 100644 --- a/code/modules/food/food/superfoods.dm +++ b/code/modules/food/food/superfoods.dm @@ -10,6 +10,7 @@ /obj/item/reagent_containers/food/snacks/meat/ ) result = /obj/structure/chaoscake + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layertwo reagents = list(REAGENT_ID_FLOUR = 30, REAGENT_ID_MILK = 20, REAGENT_ID_SUGAR = 10, REAGENT_ID_EGG = 9, ) @@ -21,6 +22,7 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layerthree reagents = list(REAGENT_ID_FLOUR = 25, REAGENT_ID_MILK = 15, REAGENT_ID_SUGAR = 10, REAGENT_ID_EGG = 6, REAGENT_ID_DEATHBELL = 10) @@ -31,6 +33,7 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer/three + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layerfour reagents = list(REAGENT_ID_FLOUR = 25, REAGENT_ID_MILK = 15, REAGENT_ID_SUGAR = 10, REAGENT_ID_EGG = 6, REAGENT_ID_MILKSHAKE = 30) @@ -41,12 +44,14 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer/four + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layerfive reagents = list(REAGENT_ID_FLOUR = 20, REAGENT_ID_MILK = 10, REAGENT_ID_SUGAR = 10, REAGENT_ID_EGG = 6, REAGENT_ID_BLOOD = 30) fruit = list(PLANT_TOMATO = 2) items = list() //supposed to be made with lobster, still has to be ported. result = /obj/item/chaoscake_layer/five + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layersix reagents = list(REAGENT_ID_FLOUR = 20, REAGENT_ID_MILK = 10, REAGENT_ID_SUGAR = 10, REAGENT_ID_EGG = 6, REAGENT_ID_SPRINKLES = 5) @@ -60,6 +65,7 @@ /obj/item/reagent_containers/food/snacks/chocolatebar ) result = /obj/item/chaoscake_layer/six + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layerseven reagents = list(REAGENT_ID_FLOUR = 15, REAGENT_ID_MILK = 10, REAGENT_ID_SUGAR = 5, REAGENT_ID_EGG = 3, REAGENT_ID_DEVILSKISS = 20) @@ -70,6 +76,7 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer/seven + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layereight reagents = list(REAGENT_ID_FLOUR = 15, REAGENT_ID_MILK = 10, REAGENT_ID_SUGAR = 5, REAGENT_ID_EGG = 3, REAGENT_ID_CREAM = 20) @@ -80,12 +87,14 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer/eight + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layernine reagents = list(REAGENT_ID_WATER = 10, REAGENT_ID_BLOOD = 10) fruit = list(PLANT_GOLDAPPLE = 1) items = list() result = /obj/item/chaoscake_layer/nine + wiki_flag = WIKI_SPOILER /obj/structure/chaoscake name = "An unfinished cake" diff --git a/code/modules/food/food/superfoods_ch.dm b/code/modules/food/food/superfoods_ch.dm index ef824b4a21..952d657a4f 100644 --- a/code/modules/food/food/superfoods_ch.dm +++ b/code/modules/food/food/superfoods_ch.dm @@ -44,6 +44,7 @@ /obj/item/stack/material/diamond ) result = /obj/item/thecake_layer + wiki_flag = WIKI_SPOILER /datum/recipe/thecake_thirdlayer reagents = list(REAGENT_ID_FLOUR = 300, REAGENT_ID_SINGULO = 300, REAGENT_ID_ATOMICBOMB = 150, REAGENT_ID_THREEMILEISLAND = 150, REAGENT_ID_MANHATTANPROJ = 100) @@ -66,6 +67,7 @@ /obj/item/reagent_containers/food/snacks/carpmeat ) result = /obj/item/thecake_layer/three + wiki_flag = WIKI_SPOILER /datum/recipe/thecake_fourthlayer reagents = list(REAGENT_ID_FLOUR = 400, REAGENT_ID_HOLYMARY = 100, REAGENT_ID_ANGELSKISS = 100, REAGENT_ID_GOLDSCHLAGER = 100, REAGENT_ID_GOLD = 300) @@ -88,6 +90,7 @@ /obj/item/reagent_containers/food/snacks/appletart ) result = /obj/item/thecake_layer/four + wiki_flag = WIKI_SPOILER /datum/recipe/thecake_fifthlayer reagents = list(REAGENT_ID_DEATHBELL = 1000) @@ -110,6 +113,7 @@ /obj/item/reagent_containers/food/snacks/xenomeat ) result = /obj/item/thecake_layer/five + wiki_flag = WIKI_SPOILER /obj/structure/thecake/proc/HasSliceMissing() if(slices < maxslices) @@ -248,6 +252,7 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layerthree reagents = list(REAGENT_ID_FLOUR = 240, REAGENT_ID_MILK = 150, REAGENT_ID_SUGAR = 80, REAGENT_ID_EGG = 24, REAGENT_ID_DEATHBELL = 100) @@ -258,6 +263,7 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer/three + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layerfour reagents = list(REAGENT_ID_FLOUR = 240, REAGENT_ID_MILK = 150, REAGENT_ID_SUGAR = 80, REAGENT_ID_EGG = 24, REAGENT_ID_MILKSHAKE = 300) @@ -268,6 +274,7 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer/four + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layerfive reagents = list(REAGENT_ID_FLOUR = 180, REAGENT_ID_MILK = 100, REAGENT_ID_SUGAR = 60, REAGENT_ID_EGG = 18, REAGENT_ID_BLOOD = 300) @@ -279,6 +286,7 @@ /obj/item/reagent_containers/food/snacks/lobster ) result = /obj/item/chaoscake_layer/five + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layersix reagents = list(REAGENT_ID_FLOUR = 180, REAGENT_ID_MILK = 100, REAGENT_ID_SUGAR = 60, REAGENT_ID_EGG = 18, REAGENT_ID_SPRINKLES = 10) @@ -292,6 +300,7 @@ /obj/item/reagent_containers/food/snacks/chocolatebar ) result = /obj/item/chaoscake_layer/six + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layerseven reagents = list(REAGENT_ID_FLOUR = 120, REAGENT_ID_MILK = 50, REAGENT_ID_SUGAR = 40, REAGENT_ID_EGG = 12, REAGENT_ID_DEVILSKISS = 200) @@ -302,6 +311,7 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer/seven + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layereight reagents = list(REAGENT_ID_FLOUR = 120, REAGENT_ID_MILK = 50, REAGENT_ID_SUGAR = 40, REAGENT_ID_EGG = 12, REAGENT_ID_CREAM = 200) @@ -312,15 +322,17 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/chaoscake_layer/eight + wiki_flag = WIKI_SPOILER /datum/recipe/chaoscake_layernine reagents = list(REAGENT_ID_WATER = 100, REAGENT_ID_BLOOD = 100) fruit = list(PLANT_GOLDAPPLE = 50) items = list() result = /obj/item/chaoscake_layer/nine + wiki_flag = WIKI_SPOILER /obj/structure/chaoscake - name = "An unfinished cake" + name = "An strange unfinished cake" desc = "A single layer of a strange cake, you can see the cherry paste ooze, but it feels very incomplete..." icon = 'icons/obj/food64x64.dmi' diff --git a/code/modules/food/kitchen/microwave.dm b/code/modules/food/kitchen/microwave.dm index 8ff38bbe1f..d7bcdfbbeb 100644 --- a/code/modules/food/kitchen/microwave.dm +++ b/code/modules/food/kitchen/microwave.dm @@ -603,6 +603,7 @@ /obj/item/holder ) result = /obj/effect/decal/cleanable/blood/gibs + wiki_flag = WIKI_SPOILER /datum/recipe/splat/before_cook(obj/container) if(istype(container, /obj/machinery/microwave)) diff --git a/code/modules/food/recipe.dm b/code/modules/food/recipe.dm index 751c32473c..a43529618e 100644 --- a/code/modules/food/recipe.dm +++ b/code/modules/food/recipe.dm @@ -62,6 +62,8 @@ // This is a bitfield, more than one type can be used // Grill is presently unused and not listed + var/wiki_flag = 0 + /datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents, var/exact = FALSE) if(!reagents || !reagents.len) return TRUE diff --git a/code/modules/food/recipes_fryer.dm b/code/modules/food/recipes_fryer.dm index ecabe21945..6c50d3f564 100644 --- a/code/modules/food/recipes_fryer.dm +++ b/code/modules/food/recipes_fryer.dm @@ -89,6 +89,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sliceable/pizza/crunch coating = /datum/reagent/nutriment/coating/batter + wiki_flag = WIKI_SPOILER /datum/recipe/friedmushroom appliance = FRYER @@ -141,6 +142,7 @@ /obj/item/reagent_containers/food/snacks/dough ) result = /obj/item/reagent_containers/food/snacks/donut/plain/jelly/poisonberry + wiki_flag = WIKI_SPOILER /datum/recipe/jellydonut/slime // Subtypes of jellydonut, appliance inheritance applies. reagents = list(REAGENT_ID_SLIMEJELLY = 5, REAGENT_ID_SUGAR = 5) @@ -168,6 +170,7 @@ ) result = /obj/item/reagent_containers/food/snacks/donut/chaos result_quantity = 2 + wiki_flag = WIKI_SPOILER /datum/recipe/funnelcake appliance = FRYER diff --git a/code/modules/food/recipes_fryer_vr.dm b/code/modules/food/recipes_fryer_vr.dm index 119e020d14..6f0d7b41d8 100644 --- a/code/modules/food/recipes_fryer_vr.dm +++ b/code/modules/food/recipes_fryer_vr.dm @@ -18,18 +18,6 @@ ) result = /obj/item/storage/box/wings //This is kinda like the donut box. -//CHOMP remove start -/*/datum/recipe/chickenwings -* appliance = FRYER -* items = list( -* /obj/item/reagent_containers/food/snacks/meat, -* /obj/item/reagent_containers/food/snacks/meat, -* /obj/item/reagent_containers/food/snacks/meat, -* /obj/item/reagent_containers/food/snacks/meat -* ) -* result = /obj/item/reagent_containers/food/snacks/generalschicken -*CHOMP remove end */ - /datum/recipe/locust appliance = FRYER reagents = list(REAGENT_ID_SODIUMCHLORIDE = 1) diff --git a/code/modules/food/recipes_grill.dm b/code/modules/food/recipes_grill.dm index f98f0516c5..01cac81034 100644 --- a/code/modules/food/recipes_grill.dm +++ b/code/modules/food/recipes_grill.dm @@ -5,6 +5,7 @@ /obj/item/reagent_containers/food/snacks/bun ) result = /obj/item/reagent_containers/food/snacks/human/burger + wiki_flag = WIKI_SPOILER // Alt recipie doesn't need to be shown(breaks tgui) /datum/recipe/plainburger appliance = GRILL @@ -21,6 +22,7 @@ /obj/item/reagent_containers/food/snacks/meat/syntiflesh ) result = /obj/item/reagent_containers/food/snacks/monkeyburger + wiki_flag = WIKI_SPOILER // Alt recipie doesn't need to be shown(breaks tgui) /datum/recipe/brainburger appliance = GRILL @@ -102,6 +104,7 @@ /obj/item/reagent_containers/food/snacks/bun ) result = /obj/item/reagent_containers/food/snacks/bunbun + wiki_flag = WIKI_SPOILER /datum/recipe/hotdog appliance = GRILL @@ -119,6 +122,7 @@ /obj/item/reagent_containers/food/snacks/meat/human, ) result = /obj/item/reagent_containers/food/snacks/human/kabob + wiki_flag = WIKI_SPOILER /datum/recipe/kabob //Do not put before humankabob appliance = GRILL @@ -137,6 +141,7 @@ /obj/item/reagent_containers/food/snacks/meat/monkey ) result = /obj/item/reagent_containers/food/snacks/monkeykabob + wiki_flag = WIKI_SPOILER // Alt recipie doesn't need to be shown(breaks tgui) /datum/recipe/syntikabob appliance = GRILL @@ -146,6 +151,7 @@ /obj/item/reagent_containers/food/snacks/meat/syntiflesh ) result = /obj/item/reagent_containers/food/snacks/monkeykabob + wiki_flag = WIKI_SPOILER // Alt recipie doesn't need to be shown(breaks tgui) /datum/recipe/tofukabob appliance = GRILL @@ -163,6 +169,7 @@ /obj/item/clothing/head/wizard/fake, ) result = /obj/item/reagent_containers/food/snacks/spellburger + wiki_flag = WIKI_SPOILER /datum/recipe/spellburger appliance = GRILL diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index f8370f1588..18f616c6dd 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -49,6 +49,7 @@ I said no! /obj/item/reagent_containers/food/snacks/meatball ) result = /obj/item/reagent_containers/food/snacks/donkpocket //SPECIAL + wiki_flag = WIKI_SPOILER /datum/recipe/donkpocket/proc/warm_up(var/obj/item/reagent_containers/food/snacks/donkpocket/being_cooked) being_cooked.heat() @@ -111,6 +112,7 @@ I said no! /obj/item/reagent_containers/food/snacks/sliceable/flatdough ) result = /obj/item/reagent_containers/food/snacks/berryclafoutis/poison + wiki_flag = WIKI_SPOILER /datum/recipe/wingfangchu reagents = list(REAGENT_ID_SOYSAUCE = 5) @@ -480,6 +482,7 @@ I said no! /obj/item/reagent_containers/food/snacks/doughslice ) result = /obj/item/reagent_containers/food/snacks/donkpocket/dankpocket + wiki_flag = WIKI_SPOILER /datum/recipe/validsalad/make_food(var/obj/container as obj) . = ..(container) @@ -546,6 +549,7 @@ I said no! ) result = /obj/item/reagent_containers/food/snacks/roastedsunflower result_quantity = 2 + wiki_flag = WIKI_SPOILER // Other recipies are other oils /datum/recipe/roastedsunflowerseeds reagents = list(REAGENT_ID_SODIUMCHLORIDE = 1, REAGENT_ID_COOKINGOIL = 1) @@ -562,6 +566,7 @@ I said no! ) result = /obj/item/reagent_containers/food/snacks/roastedsunflower result_quantity = 2 + wiki_flag = WIKI_SPOILER // Other recipies are other oils /datum/recipe/roastedpeanuts fruit = list(PLANT_PEANUT = 2) @@ -574,12 +579,14 @@ I said no! reagents = list(REAGENT_ID_SODIUMCHLORIDE = 2, REAGENT_ID_CORNOIL = 1) result = /obj/item/reagent_containers/food/snacks/roastedpeanuts result_quantity = 2 + wiki_flag = WIKI_SPOILER // other recipies are just other oils /datum/recipe/roastedpeanutspeanut fruit = list(PLANT_PEANUT = 2) reagents = list(REAGENT_ID_SODIUMCHLORIDE = 2, REAGENT_ID_PEANUTOIL = 1) result = /obj/item/reagent_containers/food/snacks/roastedpeanuts result_quantity = 2 + wiki_flag = WIKI_SPOILER // other recipies are just other oils /datum/recipe/mint reagents = list(REAGENT_ID_SUGAR = 5, REAGENT_ID_FROSTOIL = 5) @@ -630,6 +637,7 @@ I said no! fruit = list(PLANT_POISONBERRIES = 1) result = /obj/item/reagent_containers/food/snacks/berrymuffin/poison result_quantity = 2 + wiki_flag = WIKI_SPOILER /datum/recipe/ghostmuffin reagents = list(REAGENT_ID_MILK = 5, REAGENT_ID_SUGAR = 5) @@ -650,6 +658,7 @@ I said no! fruit = list(PLANT_POISONBERRIES = 1) result = /obj/item/reagent_containers/food/snacks/ghostmuffin/poison result_quantity = 2 + wiki_flag = WIKI_SPOILER /datum/recipe/eggroll reagents = list(REAGENT_ID_SOYSAUCE = 10) @@ -954,7 +963,6 @@ I said no! /obj/item/reagent_containers/food/snacks/meatball, /obj/item/reagent_containers/food/snacks/meatball ) - result result = /obj/item/reagent_containers/food/snacks/burrito_hell reagent_mix = RECIPE_REAGENT_REPLACE //Already hot sauce diff --git a/code/modules/food/recipes_microwave_vr.dm b/code/modules/food/recipes_microwave_vr.dm index 1f2e284e29..80b739c17b 100644 --- a/code/modules/food/recipes_microwave_vr.dm +++ b/code/modules/food/recipes_microwave_vr.dm @@ -99,6 +99,7 @@ /obj/item/reagent_containers/food/snacks/carpmeat ) result = /obj/item/reagent_containers/food/snacks/sliceable/sushi + wiki_flag = WIKI_SPOILER // Secretish? Just assume carp is fish anyway /datum/recipe/lobster fruit = list(PLANT_LEMON = 1, PLANT_LETTUCE = 1) diff --git a/code/modules/food/recipes_oven.dm b/code/modules/food/recipes_oven.dm index 310d67e258..a22166630b 100644 --- a/code/modules/food/recipes_oven.dm +++ b/code/modules/food/recipes_oven.dm @@ -81,6 +81,7 @@ /obj/item/reagent_containers/food/snacks/carpmeat ) result = /obj/item/reagent_containers/food/snacks/zestfish + wiki_flag = WIKI_SPOILER // secret if you know! //Predesigned breads @@ -166,6 +167,7 @@ /obj/item/reagent_containers/food/snacks/cheesewedge ) result = /obj/item/reagent_containers/food/snacks/sliceable/meatbread + wiki_flag = WIKI_SPOILER // Synthflesh secret /datum/recipe/xenomeatbread appliance = OVEN @@ -400,6 +402,7 @@ /obj/item/reagent_containers/food/snacks/cheesewedge ) result = /obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza + wiki_flag = WIKI_SPOILER // Synthflesh spoiler /datum/recipe/mushroompizza appliance = OVEN diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 0f12f6f34a..305a1a0848 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -242,10 +242,10 @@ if(!isanimal(user)) if( !user.get_active_hand() ) //if active hand is empty var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user,span_notice("You try to move your [temp.name], but cannot!")) return @@ -261,10 +261,10 @@ if(!isanimal(user)) if( !user.get_active_hand() ) //if active hand is empty var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user,span_notice("You try to move your [temp.name], but cannot!")) return diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 5345a7c341..6447629ba1 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -355,7 +355,7 @@ if(!reagents || reagents.total_volume <= 0) return reagents.remove_any(rand(1,3)) //Todo, make it actually remove the reagents the seed uses. - var/affected = pick("r_hand","l_hand") + var/affected = pick(BP_R_HAND,BP_L_HAND) seed.do_thorns(H,src,affected) seed.do_sting(H,src,affected) diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index d4b99ac814..c3f5e8af1f 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -26,6 +26,7 @@ var/has_item_product // Item products. (Eggy) var/force_layer var/harvest_sound = null //Vorestation edit - sound the plant makes when harvested + var/wiki_flag = 0 // Making the assumption anything in HYDRO-ponics is capable of processing water, and nutrients commonly associated with it, leaving us with the below to be tweaked. var/list/beneficial_reagents // Reagents considered uniquely 'beneficial' by a plant. diff --git a/code/modules/hydroponics/seedtypes/apples.dm b/code/modules/hydroponics/seedtypes/apples.dm index 25a4af5c00..0e91d48f1d 100644 --- a/code/modules/hydroponics/seedtypes/apples.dm +++ b/code/modules/hydroponics/seedtypes/apples.dm @@ -24,6 +24,7 @@ name = PLANT_POISONAPPLE mutants = null chems = list(REAGENT_ID_CYANIDE = list(1,5)) + wiki_flag = WIKI_SPOILER /datum/seed/apple/gold name = PLANT_GOLDAPPLE diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm index a1c90399f4..421cf22aae 100644 --- a/code/modules/hydroponics/spreading/spreading_response.dm +++ b/code/modules/hydroponics/spreading/spreading_response.dm @@ -51,7 +51,7 @@ if(istype(H) && H.shoes) return seed.do_thorns(victim,src) - seed.do_sting(victim,src,pick("r_foot","l_foot","r_leg","l_leg")) + seed.do_sting(victim,src,pick(BP_R_FOOT,BP_L_FOOT,BP_R_LEG,BP_L_LEG)) if(seed.get_trait(TRAIT_SPORING) && prob(round(seed.get_trait(TRAIT_POTENCY)/2))) seed.create_spores(get_turf(victim)) diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm index 7b7b66bced..088fc260b4 100644 --- a/code/modules/hydroponics/trays/tray_tools.dm +++ b/code/modules/hydroponics/trays/tray_tools.dm @@ -179,7 +179,7 @@ data["name"] = seed_name data["uid"] = uid data["endurance"] = get_trait(TRAIT_ENDURANCE) - data["yield"] = get_trait(TRAIT_YIELD) + data["crop_yield"] = get_trait(TRAIT_YIELD) data["maturation_time"] = get_trait(TRAIT_MATURATION) data["production_time"] = get_trait(TRAIT_PRODUCTION) data["potency"] = get_trait(TRAIT_POTENCY) diff --git a/code/modules/library/wikicomp.dm b/code/modules/library/wikicomp.dm new file mode 100644 index 0000000000..a74302e5c7 --- /dev/null +++ b/code/modules/library/wikicomp.dm @@ -0,0 +1,241 @@ +/* + * Library Public Computer + * Complete recode of this into a search engine for recipes and reagents + */ +/obj/machinery/librarywikicomp + name = "datacore computer" + icon = 'icons/obj/library.dmi' + icon_state = "computer" + anchored = TRUE + density = TRUE + + desc = "Used for research, I swear!" + + VAR_PRIVATE/doc_title = "Click a search entry!" + VAR_PRIVATE/doc_body = "" + VAR_PRIVATE/searchmode = null + VAR_PRIVATE/sub_category = null //sublists for food menu + VAR_PRIVATE/crash = FALSE + VAR_PRIVATE/just_donated = FALSE + VAR_PRIVATE/datum/internal_wiki/page/P + +/obj/machinery/librarywikicomp/Initialize(mapload) + . = ..() + +/obj/machinery/librarywikicomp/attack_hand(mob/user) + if(..()) + return 1 + if(crash) + user.visible_message("[user] performs percussive maintenance on \the [src].", "You try to smack some sense into \the [src].") + if(prob(10)) + crash = FALSE + if(!crash) + tgui_interact(user) + playsound(src, "keyboard", 40) // into console + +/obj/machinery/librarywikicomp/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + just_donated = FALSE + ui = new(user, src, "PublicLibraryWiki", name) + ui.open() + + +/obj/machinery/librarywikicomp/tgui_close(mob/user) + . = ..() + P = null + sub_category= null + searchmode = null + +/obj/machinery/librarywikicomp/tgui_data(mob/user) + var/data = list() + if(SSinternal_wiki) + data["crash"] = crash + data["botany_data"] = null + data["material_data"] = null + data["particle_data"] = null + data["catalog_data"] = null + data["ore_data"] = null + data["sub_categories"] = null + data["donated"] = SSinternal_wiki.get_donation_current() + data["goal"] = SSinternal_wiki.get_donation_goal() + data["has_donated"] = just_donated + if(!crash) + // search page + data["errorText"] = "" + data["searchmode"] = searchmode + // get searches + switch(searchmode) + if("Food Recipes") + data["sub_categories"] = SSinternal_wiki.get_appliances() + data["search"] = list() + if(sub_category) + data["search"] = SSinternal_wiki.get_searchcache_food(sub_category) + if(P) + data["food_data"] = P.get_data() + + if("Drink Recipes") + data["search"] = SSinternal_wiki.get_searchcache_drink() + if(P) + data["drink_data"] = P.get_data() + + if("Chemistry") + data["search"] = SSinternal_wiki.get_searchcache_chem() + if(P) + data["chemistry_data"] = P.get_data() + + if("Botany") + data["search"] = SSinternal_wiki.get_searchcache_seed() + if(P) + data["botany_data"] = P.get_data() + + if("Catalogs") + data["sub_categories"] = SSinternal_wiki.get_catalogs() + data["search"] = list() + if(sub_category) + data["search"] = SSinternal_wiki.get_searchcache_catalog(sub_category) + if(P) + data["catalog_data"] = P.get_data() + + if("Materials") + data["search"] = SSinternal_wiki.get_searchcache_material() + if(P) + data["material_data"] = P.get_data() + + if("Particle Physics") + data["search"] = SSinternal_wiki.get_searchcache_particle() + if(P) + data["particle_data"] = P.get_data() + + if("Ores") + data["search"] = SSinternal_wiki.get_searchcache_ore() + if(P) + data["ore_data"] = P.get_data() + + else + data["search"] = list() + + // display message + data["print"] = (doc_body && length(doc_body) > 0) + else + // intentional TGUI crash, amazingly awful + data["searchmode"] = "Error" + data["search"] = null + else + data["errorText"] = "Database unreachable." + return data + +/obj/machinery/librarywikicomp/tgui_act(action, params, datum/tgui/ui) + if(..()) + return TRUE + add_fingerprint(ui.user) + playsound(src, "keyboard", 40) // into console + + switch(action) + if("closesearch") + if(!crash) + P = null + searchmode = null + sub_category = null + doc_title = "Click a search entry!" + doc_body = "" + . = TRUE + + if("swapsearch") + if(!crash) + var/new_mode = params["data"] + if(searchmode == new_mode) + return FALSE + P = null + doc_title = null + doc_body = null + searchmode = new_mode + . = TRUE + + if("crash") + // intentional TGUI crash, amazingly awful + if(issilicon(ui.user) && ui.user.client) + ui.user.client.create_fake_ad_popup_multiple(/obj/screen/popup/default, rand(4,10)) + if(!crash) + crash = TRUE + // crashes till it fixes itself + VARSET_IN(src, crash, FALSE, rand(1000, 4000)) + . = TRUE + + if("print") + if(!crash && doc_title && doc_body) + visible_message(span_notice("[src] rattles and prints out a sheet of paper.")) + // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) + + var/obj/item/paper/paper = new /obj/item/paper(loc) + paper.name = doc_title + paper.info = doc_body + . = TRUE + + if("setsubcat") + if(!crash) + var/new_subcat = params["data"] + if(sub_category == new_subcat) + return FALSE + P = null + doc_title = null + doc_body = null + sub_category = new_subcat + . = TRUE + // final search + if("search") + if(!crash) + var/search = params["data"] + var/datum/internal_wiki/page/new_page = null + if(searchmode == "Food Recipes") + new_page = SSinternal_wiki.get_page_food(search) + if(searchmode == "Drink Recipes") + new_page = SSinternal_wiki.get_page_drink(search) + if(searchmode == "Chemistry") + new_page = SSinternal_wiki.get_page_chem(search) + if(searchmode == "Botany") + new_page = SSinternal_wiki.get_page_seed(search) + if(searchmode == "Catalogs") + new_page = SSinternal_wiki.get_page_catalog(search) + if(searchmode == "Materials") + new_page = SSinternal_wiki.get_page_material(search) + if(searchmode == "Particle Physics") + new_page = SSinternal_wiki.get_page_particle(search) + if(searchmode == "Ores") + new_page = SSinternal_wiki.get_page_ore(search) + + if(new_page == P) + return FALSE + + P = new_page + + if(P) + doc_title = P.title + doc_body = P.get_print() // TODO - pass get_data() instead, as only printing should use get_print() + else + doc_title = "Error" + doc_body = "Invalid data." + . = TRUE + // Support the wiki + if("donate") + if(!crash) + var/amount = params["donate"] + var/mob/living/carbon/human/H = ui.user + if(!ishuman(H) || !H.IsAdvancedToolUser(TRUE)) + to_chat(ui.user,"Donating to Bingle.exo is Byond your comprehension!") + else if(amount) + pay_donation(H.GetIdCard(), ui.user, amount, ui) + . = TRUE + +/obj/machinery/librarywikicomp/proc/pay_donation(var/obj/item/card/id/I, var/mob/user, var/amount, var/datum/tgui/ui) + visible_message(span_info("[user] swipes a card through [src].")) + playsound(src, 'sound/machines/id_swipe.ogg', 50, 1) + if(SSinternal_wiki.pay_with_card(I, user, src, amount)) + playsound(src, 'sound/machines/ping.ogg', 50, 1) + just_donated = TRUE + SStgui.update_user_uis(user, ui) + +// mapper varient for dorms and residences +/obj/machinery/librarywikicomp/personal + name = "personal datacore computer" + desc = "Have you Bingled THAT today?" diff --git a/code/modules/materials/materials/_materials.dm b/code/modules/materials/materials/_materials.dm index 322e5d7bea..d9ea76cda9 100644 --- a/code/modules/materials/materials/_materials.dm +++ b/code/modules/materials/materials/_materials.dm @@ -235,6 +235,8 @@ var/list/name_to_material // Wallrot crumble message. var/rotting_touch_message = "crumbles under your touch" + var/wiki_flag = 0 + // Placeholders for light tiles and rglass. /datum/material/proc/build_rod_product(var/mob/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack) if(!rod_product) @@ -306,6 +308,7 @@ var/list/name_to_material // Used by walls when qdel()ing to avoid neighbor merging. /datum/material/placeholder name = "placeholder" + wiki_flag = WIKI_SPOILER // Places a girder object when a wall is dismantled, also applies reinforced material. /datum/material/proc/place_dismantled_girder(var/turf/target, var/datum/material/reinf_material, var/datum/material/girder_material) diff --git a/code/modules/materials/materials/alien_alloy.dm b/code/modules/materials/materials/alien_alloy.dm index 9f097d7ef6..21d8a0224f 100644 --- a/code/modules/materials/materials/alien_alloy.dm +++ b/code/modules/materials/materials/alien_alloy.dm @@ -11,6 +11,7 @@ hardness = 500 weight = 500 protectiveness = 80 // 80% + wiki_flag = WIKI_SPOILER /datum/material/alienalloy/elevatorium name = "elevatorium" diff --git a/code/modules/materials/materials/cult.dm b/code/modules/materials/materials/cult.dm index e8fd611833..8d15852d3b 100644 --- a/code/modules/materials/materials/cult.dm +++ b/code/modules/materials/materials/cult.dm @@ -9,6 +9,7 @@ sheet_singular_name = "brick" sheet_plural_name = "bricks" conductive = 0 + wiki_flag = WIKI_SPOILER /datum/material/cult/place_dismantled_girder(var/turf/target) new /obj/structure/girder/cult(target, MAT_CULT) diff --git a/code/modules/materials/materials/gems.dm b/code/modules/materials/materials/gems.dm index 456d07461f..040133a8d7 100644 --- a/code/modules/materials/materials/gems.dm +++ b/code/modules/materials/materials/gems.dm @@ -103,7 +103,7 @@ icon_base = "stone" door_icon_base = "stone" icon_reinf = "reinf_mesh" - icon_colour = "##FFF3B2" + icon_colour = "#FFF3B2" protectiveness = 30 integrity = 240 weight = 30 diff --git a/code/modules/materials/materials/holographic.dm b/code/modules/materials/materials/holographic.dm index 91f9158730..8f3e5befc3 100644 --- a/code/modules/materials/materials/holographic.dm +++ b/code/modules/materials/materials/holographic.dm @@ -3,15 +3,18 @@ display_name = MAT_STEEL stack_type = null shard_type = SHARD_NONE + wiki_flag = WIKI_SPOILER /datum/material/plastic/holographic name = "holo" + MAT_PLASTIC display_name = MAT_PLASTIC stack_type = null shard_type = SHARD_NONE + wiki_flag = WIKI_SPOILER /datum/material/wood/holographic name = "holo" + MAT_WOOD display_name = MAT_WOOD stack_type = null shard_type = SHARD_NONE + wiki_flag = WIKI_SPOILER diff --git a/code/modules/materials/materials/organic/cloth.dm b/code/modules/materials/materials/organic/cloth.dm index 708fb4d10c..669f81146e 100644 --- a/code/modules/materials/materials/organic/cloth.dm +++ b/code/modules/materials/materials/organic/cloth.dm @@ -59,57 +59,66 @@ /datum/material/cloth/teal name = MAT_CLOTH_TEAL - display_name =MAT_CLOTH_TEAL + display_name = MAT_CLOTH_TEAL use_name = "teal cloth" icon_colour = "#00EAFA" + wiki_flag = WIKI_SPOILER /datum/material/cloth/black name = MAT_CLOTH_BLACK display_name = MAT_CLOTH_BLACK use_name = "black cloth" icon_colour = "#505050" + wiki_flag = WIKI_SPOILER /datum/material/cloth/green name = MAT_CLOTH_GREEN display_name = MAT_CLOTH_GREEN use_name = "green cloth" icon_colour = "#01C608" + wiki_flag = WIKI_SPOILER /datum/material/cloth/puple name = MAT_CLOTH_PURPLE display_name = MAT_CLOTH_PURPLE use_name = "purple cloth" icon_colour = "#9C56C4" + wiki_flag = WIKI_SPOILER /datum/material/cloth/blue name = MAT_CLOTH_BLUE display_name = MAT_CLOTH_BLUE use_name = "blue cloth" icon_colour = "#6B6FE3" + wiki_flag = WIKI_SPOILER /datum/material/cloth/beige name = MAT_CLOTH_BEIGE display_name = MAT_CLOTH_BEIGE use_name = "beige cloth" icon_colour = "#E8E7C8" + wiki_flag = WIKI_SPOILER /datum/material/cloth/lime name = MAT_CLOTH_LIME display_name = MAT_CLOTH_LIME use_name = "lime cloth" icon_colour = "#62E36C" + wiki_flag = WIKI_SPOILER /datum/material/cloth/yellow name = MAT_CLOTH_YELLOW display_name = MAT_CLOTH_YELLOW use_name = "yellow cloth" icon_colour = "#EEF573" + wiki_flag = WIKI_SPOILER /datum/material/cloth/orange name = MAT_CLOTH_ORANGE display_name = MAT_CLOTH_ORANGE use_name = "orange cloth" icon_colour = "#E3BF49" + wiki_flag = WIKI_SPOILER @@ -128,6 +137,7 @@ conductive = 0 hardness = 5 integrity = 40 + wiki_flag = WIKI_SPOILER /datum/material/cotton name = MAT_COTTON diff --git a/code/modules/materials/materials/organic/wood.dm b/code/modules/materials/materials/organic/wood.dm index 1f3329f95b..91864aa908 100644 --- a/code/modules/materials/materials/organic/wood.dm +++ b/code/modules/materials/materials/organic/wood.dm @@ -117,6 +117,7 @@ /datum/material/wood/log/hard name = MAT_HARDLOG + display_name = MAT_HARDWOOD icon_colour = "#6f432a" stack_type = /obj/item/stack/material/log/hard diff --git a/code/modules/materials/materials/other_vr.dm b/code/modules/materials/materials/other_vr.dm index d3ea6f7295..be5040028d 100644 --- a/code/modules/materials/materials/other_vr.dm +++ b/code/modules/materials/materials/other_vr.dm @@ -9,6 +9,7 @@ explosion_resistance = 200 hardness = 500 weight = 500 + wiki_flag = WIKI_SPOILER /datum/material/fluff //This is to allow for 2 handed weapons that don't want to have a prefix. name = " " @@ -18,6 +19,7 @@ sheet_plural_name = "fluffs" hardness = 60 weight = 20 //Strong as iron. + wiki_flag = WIKI_SPOILER /datum/material/darkglass name = MAT_DARKGLASS @@ -25,6 +27,7 @@ icon_base = MAT_DARKGLASS table_icon_base = MAT_DARKGLASS icon_colour = "#FFFFFF" + wiki_flag = WIKI_SPOILER /datum/material/fancyblack name = MAT_FANCYBLACK @@ -32,3 +35,4 @@ icon_base = MAT_FANCYBLACK table_icon_base = MAT_FANCYBLACK icon_colour = "#FFFFFF" + wiki_flag = WIKI_SPOILER diff --git a/code/modules/materials/materials/supermatter.dm b/code/modules/materials/materials/supermatter.dm index 9c27dbedb8..158868a3cf 100644 --- a/code/modules/materials/materials/supermatter.dm +++ b/code/modules/materials/materials/supermatter.dm @@ -5,7 +5,6 @@ stack_type = /obj/item/stack/material/supermatter shard_type = SHARD_SHARD radioactivity = 20 - stack_type = null luminescence = 3 ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE icon_base = "stone" diff --git a/code/modules/materials/sheets/supermatter.dm b/code/modules/materials/sheets/supermatter.dm index 1f2bb72a06..3e3eab421e 100644 --- a/code/modules/materials/sheets/supermatter.dm +++ b/code/modules/materials/sheets/supermatter.dm @@ -34,8 +34,8 @@ if(burn_user) H.visible_message(span_danger("\The [src] flashes as it scorches [H]'s hands!")) - H.apply_damage(amount / 2 + 5, BURN, "r_hand", used_weapon=src) - H.apply_damage(amount / 2 + 5, BURN, "l_hand", used_weapon=src) + H.apply_damage(amount / 2 + 5, BURN, BP_R_HAND, used_weapon=src) + H.apply_damage(amount / 2 + 5, BURN, BP_L_HAND, used_weapon=src) H.drop_from_inventory(src, get_turf(H)) return diff --git a/code/modules/mining/ore_datum.dm b/code/modules/mining/ore_datum.dm index df1528e104..643c10d61d 100644 --- a/code/modules/mining/ore_datum.dm +++ b/code/modules/mining/ore_datum.dm @@ -16,6 +16,7 @@ ) var/xarch_source_mineral = REAGENT_ID_IRON var/reagent = REAGENT_ID_SILICATE + var/wiki_flag = 0 /ore/New() . = ..() @@ -65,6 +66,7 @@ display_name = ORE_SAND smelts_to = MAT_GLASS alloy = 1 + ore = /obj/item/ore/glass compresses_to = MAT_SANDSTONE /ore/phoron @@ -140,6 +142,7 @@ display_name = "metallic hydrogen" smelts_to = MAT_TRITIUM compresses_to = MAT_METALHYDROGEN + ore = /obj/item/ore/hydrogen scan_icon = "mineral_rare" reagent = REAGENT_ID_HYDROGEN diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 1624362a43..0a15f82b90 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -56,9 +56,9 @@ if(!istype(M, /mob/living/carbon)) return if (ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(H, span_warning("You can't use your [temp.name]")) return @@ -122,7 +122,7 @@ /mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null, var/stun = 1) if(status_flags & GODMODE) return 0 //godmode - if(def_zone == "l_hand" || def_zone == "r_hand") //Diona (And any other potential plant people) hands don't get shocked. + if(def_zone == BP_L_HAND || def_zone == BP_R_HAND) //Diona (And any other potential plant people) hands don't get shocked. if(species.flags & IS_PLANT) return 0 shock_damage *= siemens_coeff diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index ce3c480759..7679d3cd38 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -109,7 +109,7 @@ user.visible_message(span_danger("\The [user] plunges \the [W] into \the [src]!")) var/damage = shank_armor_helper(W, G, user) - apply_damage(damage, W.damtype, "torso", 0, sharp=W.sharp, edge=W.edge) + apply_damage(damage, W.damtype, BP_TORSO, 0, sharp=W.sharp, edge=W.edge) if(W.hitsound) playsound(src, W.hitsound, 50, 1, -1) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index a0fc6e12c7..1c6ef41241 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -313,7 +313,7 @@ msg += span_warning("[T.He] [T.is] on fire!.") var/ssd_msg = species.get_ssd(src) - if(ssd_msg && (!should_have_organ("brain") || has_brain()) && stat != DEAD) + if(ssd_msg && (!should_have_organ(O_BRAIN) || has_brain()) && stat != DEAD) if(!key) msg += span_deadsay("[T.He] [T.is] [ssd_msg]. It doesn't look like [T.he] [T.is] waking up anytime soon.") else if(!client) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 86c92fbbab..aac3f5fc43 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -139,7 +139,7 @@ L[++L.len] = list("Suit charge: [cell_status]", null, null, null, null) for(var/obj/item/rig_module/module in R.installed_modules) { - for(var/stat_rig_module/SRM in module.stat_modules) + for(var/atom/movable/stat_rig_module/SRM in module.stat_modules) if(SRM.CanUse()) L[++L.len] = list(SRM.module.interface_name,null,null,SRM.name,REF(SRM)) } @@ -377,7 +377,7 @@ if(status_flags & GODMODE) return 0 //godmode if (!def_zone) - def_zone = pick("l_hand", "r_hand") + def_zone = pick(BP_L_HAND, BP_R_HAND) if(species.siemens_coefficient == -1) if(stored_shock_by_ref["\ref[src]"]) @@ -813,7 +813,7 @@ //Used by various things that knock people out by applying blunt trauma to the head. //Checks that the species has a "head" (brain containing organ) and that hit_zone refers to it. -/mob/living/carbon/human/proc/headcheck(var/target_zone, var/brain_tag = "brain") +/mob/living/carbon/human/proc/headcheck(var/target_zone, var/brain_tag = O_BRAIN) var/obj/item/organ/affecting = internal_organs_by_name[brain_tag] @@ -1635,7 +1635,7 @@ /mob/living/carbon/human/can_stand_overridden() if(wearing_rig && wearing_rig.ai_can_move_suit(check_for_ai = 1)) // Actually missing a leg will screw you up. Everything else can be compensated for. - for(var/limbcheck in list("l_leg","r_leg")) + for(var/limbcheck in list(BP_L_LEG,BP_R_LEG)) var/obj/item/organ/affecting = get_organ(limbcheck) if(!affecting) return 0 diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 9f93f0120d..f920f47831 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -41,9 +41,9 @@ var/has_hands = TRUE if(istype(H)) - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if(H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(!temp || !temp.is_usable()) has_hands = FALSE for(var/thing in GetViruses()) //This is intentionally not having a has_hands check. If you are clicking on someone next to them, you're close enough to sneeze/cough on them! diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 2be1192bbc..9e25fa42ba 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -51,8 +51,8 @@ if(status_flags & GODMODE) return 0 //godmode - if(should_have_organ("brain")) - var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] + if(should_have_organ(O_BRAIN)) + var/obj/item/organ/internal/brain/sponge = internal_organs_by_name[O_BRAIN] if(sponge) sponge.take_damage(amount) brainloss = sponge.damage @@ -65,8 +65,8 @@ if(status_flags & GODMODE) return 0 //godmode - if(should_have_organ("brain")) - var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] + if(should_have_organ(O_BRAIN)) + var/obj/item/organ/internal/brain/sponge = internal_organs_by_name[O_BRAIN] if(sponge) sponge.damage = min(max(amount, 0),(getMaxHealth()*2)) brainloss = sponge.damage @@ -79,8 +79,8 @@ if(status_flags & GODMODE) return 0 //godmode - if(should_have_organ("brain")) - var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] + if(should_have_organ(O_BRAIN)) + var/obj/item/organ/internal/brain/sponge = internal_organs_by_name[O_BRAIN] if(sponge) brainloss = min(sponge.damage,getMaxHealth()*2) else diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 6a45b8884d..9ad4314437 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -545,9 +545,9 @@ emp_act // This does a prob check to catch the thing flying at you, with a minimum of 1% /mob/living/carbon/human/proc/can_catch(var/obj/O) if(!get_active_hand()) // If active hand is empty - var/obj/item/organ/external/temp = organs_by_name["r_hand"] + var/obj/item/organ/external/temp = organs_by_name[BP_R_HAND] if (hand) - temp = organs_by_name["l_hand"] + temp = organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) return FALSE // The hand isn't working in the first place diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 44bb64f006..7c11b6b790 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -74,7 +74,7 @@ return var/limb_pain = FALSE - for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot")) + for(var/limb_tag in list(BP_L_LEG,BP_R_LEG,BP_L_FOOT,BP_R_FOOT)) var/obj/item/organ/external/E = organs_by_name[limb_tag] if(!E || !E.is_usable()) stance_damage += 2 // let it fail even if just foot&leg diff --git a/code/modules/mob/living/carbon/human/human_powers_vr.dm b/code/modules/mob/living/carbon/human/human_powers_vr.dm index f9cb232e5c..90a1eacd15 100644 --- a/code/modules/mob/living/carbon/human/human_powers_vr.dm +++ b/code/modules/mob/living/carbon/human/human_powers_vr.dm @@ -47,8 +47,8 @@ if(stat) return - var/obj/item/organ/external/l_hand = get_organ("l_hand") - var/obj/item/organ/external/r_hand = get_organ("r_hand") + var/obj/item/organ/external/l_hand = get_organ(BP_L_HAND) + var/obj/item/organ/external/r_hand = get_organ(BP_R_HAND) if((!l_hand || l_hand.is_stump()) && (!r_hand || r_hand.is_stump())) to_chat(src, span_warning("You have no hands to play games with!")) return @@ -59,8 +59,8 @@ continue if(H == src) continue - var/obj/item/organ/external/l_hand2 = H.get_organ("l_hand") - var/obj/item/organ/external/r_hand2 = H.get_organ("r_hand") + var/obj/item/organ/external/l_hand2 = H.get_organ(BP_L_HAND) + var/obj/item/organ/external/r_hand2 = H.get_organ(BP_R_HAND) if((!l_hand2 || l_hand2.is_stump()) && (!r_hand2 || r_hand2.is_stump())) continue nearby |= H @@ -70,8 +70,8 @@ continue if(H == src) continue - var/obj/item/organ/external/l_hand2 = H.get_organ("l_hand") - var/obj/item/organ/external/r_hand2 = H.get_organ("r_hand") + var/obj/item/organ/external/l_hand2 = H.get_organ(BP_L_HAND) + var/obj/item/organ/external/r_hand2 = H.get_organ(BP_R_HAND) if((!l_hand2 || l_hand2.is_stump()) && (!r_hand2 || r_hand2.is_stump())) continue nearby |= H diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index b06d6bafe0..321da1ca8f 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1293,7 +1293,7 @@ else //ALIVE. LIGHTS ARE ON updatehealth() //TODO - if(health <= CONFIG_GET(number/health_threshold_dead) || (should_have_organ("brain") && !has_brain())) + if(health <= CONFIG_GET(number/health_threshold_dead) || (should_have_organ(O_BRAIN) && !has_brain())) death() blinded = 1 silent = 0 @@ -1321,7 +1321,7 @@ qdel(a) //Brain damage from Oxyloss - if(should_have_organ("brain")) + if(should_have_organ(O_BRAIN)) var/brainOxPercent = 0.015 //Default 1.5% of your current oxyloss is applied as brain damage, 50 oxyloss is 1 brain damage if(CE_STABLE in chem_effects) brainOxPercent = 0.008 //Halved in effect diff --git a/code/modules/mob/living/carbon/human/species/lleill/lleill_items.dm b/code/modules/mob/living/carbon/human/species/lleill/lleill_items.dm index d1c20d660c..2fd7fb8dca 100644 --- a/code/modules/mob/living/carbon/human/species/lleill/lleill_items.dm +++ b/code/modules/mob/living/carbon/human/species/lleill/lleill_items.dm @@ -57,6 +57,7 @@ reagent_state = LIQUID color = "#ffffff" scannable = 1 + wiki_flag = WIKI_SPOILER /datum/reagent/glamour_scaling/affect_blood(var/mob/living/carbon/target, var/removed) if(!(/mob/living/proc/set_size in target.verbs)) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 8b24e1e895..20e1178cad 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -551,7 +551,7 @@ return //VOREStation Edit Start - Headpats and Handshakes. - if(H.zone_sel.selecting == "head") + if(H.zone_sel.selecting == BP_HEAD) if(target.touch_reaction_flags & SPECIES_TRAIT_PATTING_DEFENCE) H.visible_message( \ span_warning("[target] reflexively bites the hand of [H] to prevent head patting!"), \ @@ -564,7 +564,7 @@ H.visible_message( \ span_notice("[H] pats [target] on the head."), \ span_notice("You pat [target] on the head."), ) - else if(H.zone_sel.selecting == "r_hand" || H.zone_sel.selecting == "l_hand") + else if(H.zone_sel.selecting == BP_R_HAND || H.zone_sel.selecting == BP_L_HAND) H.visible_message( \ span_notice("[H] shakes [target]'s hand."), \ span_notice("You shake [target]'s hand."), ) diff --git a/code/modules/mob/living/carbon/human/species/station/golem.dm b/code/modules/mob/living/carbon/human/species/station/golem.dm index ca02555758..221b6e7800 100644 --- a/code/modules/mob/living/carbon/human/species/station/golem.dm +++ b/code/modules/mob/living/carbon/human/species/station/golem.dm @@ -25,7 +25,7 @@ virus_immune = 1 has_organ = list( - "brain" = /obj/item/organ/internal/brain/golem + O_BRAIN = /obj/item/organ/internal/brain/golem ) death_message = "becomes completely motionless..." diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index 7a75ac9665..7fdf1d371b 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -30,11 +30,11 @@ var/global/list/sparring_attack_cache = list() return FALSE // Check if they have a functioning hand. - var/obj/item/organ/external/E = user.organs_by_name["l_hand"] + var/obj/item/organ/external/E = user.organs_by_name[BP_L_HAND] if(E && !E.is_stump()) return TRUE - E = user.organs_by_name["r_hand"] + E = user.organs_by_name[BP_R_HAND] if(E && !E.is_stump()) return TRUE @@ -79,7 +79,7 @@ var/global/list/sparring_attack_cache = list() if(BP_GROIN) target.visible_message(span_warning("[target] looks like [TT.he] [TT.is] in pain!"), span_warning("Oh god that hurt!")) // Chompstation edit target.apply_effects(stutter = attack_damage * 2, agony = attack_damage* 3, blocked = armour) - if("l_leg", "l_foot", "r_leg", "r_foot") + if(BP_L_LEG, BP_L_FOOT, BP_R_LEG, BP_R_FOOT) if(!target.lying) target.visible_message(span_warning("[target] gives way slightly.")) target.apply_effect(attack_damage*3, AGONY, armour) @@ -199,14 +199,14 @@ var/global/list/sparring_attack_cache = list() if(user.legcuffed || user.buckled) return FALSE - if(!(zone in list("l_leg", "r_leg", "l_foot", "r_foot", BP_GROIN))) + if(!(zone in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT, BP_GROIN))) return FALSE - var/obj/item/organ/external/E = user.organs_by_name["l_foot"] + var/obj/item/organ/external/E = user.organs_by_name[BP_L_FOOT] if(E && !E.is_stump()) return TRUE - E = user.organs_by_name["r_foot"] + E = user.organs_by_name[BP_R_FOOT] if(E && !E.is_stump()) return TRUE @@ -247,14 +247,14 @@ var/global/list/sparring_attack_cache = list() if(!istype(target)) return FALSE - if (!user.lying && (target.lying || (zone in list("l_foot", "r_foot")))) + if (!user.lying && (target.lying || (zone in list(BP_L_FOOT, BP_R_FOOT)))) if(target.grabbed_by == user && target.lying) return FALSE - var/obj/item/organ/external/E = user.organs_by_name["l_foot"] + var/obj/item/organ/external/E = user.organs_by_name[BP_L_FOOT] if(E && !E.is_stump()) return TRUE - E = user.organs_by_name["r_foot"] + E = user.organs_by_name[BP_R_FOOT] if(E && !E.is_stump()) return TRUE diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 4cd63b1ae1..7f7b4973ec 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -966,7 +966,7 @@ if(ishuman(src)) var/mob/living/carbon/human/H = src if(!H.isSynthetic()) - var/obj/item/organ/internal/liver/L = H.internal_organs_by_name["liver"] + var/obj/item/organ/internal/liver/L = H.internal_organs_by_name[O_LIVER] if(!L || L.is_broken()) blood_vomit = 1 diff --git a/code/modules/mob/living/silicon/pai/pai_vr.dm b/code/modules/mob/living/silicon/pai/pai_vr.dm index a5818ee494..47cc19aa61 100644 --- a/code/modules/mob/living/silicon/pai/pai_vr.dm +++ b/code/modules/mob/living/silicon/pai/pai_vr.dm @@ -336,11 +336,11 @@ else t_him = "them" - if(H.zone_sel.selecting == "head") + if(H.zone_sel.selecting == BP_HEAD) H.visible_message( \ span_notice("[H] pats [target] on the head."), \ span_notice("You pat [target] on the head."), ) - else if(H.zone_sel.selecting == "r_hand" || H.zone_sel.selecting == "l_hand") + else if(H.zone_sel.selecting == BP_R_HAND || H.zone_sel.selecting == BP_L_HAND) H.visible_message( \ span_notice("[H] shakes [target]'s hand."), \ span_notice("You shake [target]'s hand."), ) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm index 07d65d339a..4115978c47 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm @@ -77,7 +77,7 @@ if(!E || E.is_stump()) to_chat(src, span_warning("\The [H] does not have a head!")) - if(!H.should_have_organ("brain")) + if(!H.should_have_organ(O_BRAIN)) to_chat(src, span_warning("\The [H] does not seem to have an ear canal to breach.")) return @@ -112,7 +112,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/I = H.internal_organs_by_name["brain"] + var/obj/item/organ/I = H.internal_organs_by_name[O_BRAIN] if(!I) // No brain organ, so the borer moves in and replaces it permanently. replace_brain() else @@ -182,7 +182,7 @@ H.ChangeToHusk() var/obj/item/organ/internal/borer/B = new(H) - H.internal_organs_by_name["brain"] = B + H.internal_organs_by_name[O_BRAIN] = B H.internal_organs |= B var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 07711169c6..022da4a43e 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -277,8 +277,8 @@ else if(istype(my_mob.buckled, /obj/structure/bed/chair/wheelchair)) if(ishuman(my_mob)) var/mob/living/carbon/human/driver = my_mob - var/obj/item/organ/external/l_hand = driver.get_organ("l_hand") - var/obj/item/organ/external/r_hand = driver.get_organ("r_hand") + var/obj/item/organ/external/l_hand = driver.get_organ(BP_L_HAND) + var/obj/item/organ/external/r_hand = driver.get_organ(BP_R_HAND) if((!l_hand || l_hand.is_stump()) && (!r_hand || r_hand.is_stump())) return // No hands to drive your chair? Tough luck! //drunk wheelchair driving diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm index 33766df539..04c3c33aaf 100644 --- a/code/modules/mob/new_player/login.dm +++ b/code/modules/mob/new_player/login.dm @@ -50,12 +50,14 @@ var/obj/effect/lobby_image = new /obj/effect/lobby_image created_for = ckey new_player_panel() - client.init_verbs() - spawn(40) - if(client) - handle_privacy_poll() - client.playtitlemusic() - version_warnings() + addtimer(CALLBACK(src, PROC_REF(do_after_login)), 4 SECONDS, TIMER_DELETE_ME) + +/mob/new_player/proc/do_after_login() + PRIVATE_PROC(TRUE) + if(client) + handle_privacy_poll() + client.playtitlemusic() + version_warnings() /mob/new_player/proc/version_warnings() var/problems // string to store message to present to player as a problem diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index fa5c6f17c7..c7dd507d4d 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -195,7 +195,6 @@ client.prefs.dress_preview_mob(mannequin) var/mob/observer/dead/observer = new(mannequin) observer.moveToNullspace() //Let's not stay in our doomed mannequin - qdel(mannequin) //We're not used anymore, so goodbye! spawning = 1 if(client.media) diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index 88ed5d96fe..6b74db042d 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -4,7 +4,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) name = "brain" health = 400 //They need to live awhile longer than other organs. Is this even used by organ code anymore? desc = "A piece of juicy meat found in a person's head." - organ_tag = "brain" + organ_tag = O_BRAIN parent_organ = BP_HEAD vital = 1 icon_state = "brain2" @@ -175,7 +175,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) /obj/item/organ/internal/brain/pariah_brain name = "brain remnants" desc = "Did someone tread on this? It looks useless for cloning or cyborgification." - organ_tag = "brain" + organ_tag = O_BRAIN parent_organ = BP_HEAD icon = 'icons/mob/alien.dmi' icon_state = "chitin" diff --git a/code/modules/organs/internal/liver.dm b/code/modules/organs/internal/liver.dm index 51fd647c80..64deaca348 100644 --- a/code/modules/organs/internal/liver.dm +++ b/code/modules/organs/internal/liver.dm @@ -1,7 +1,7 @@ /obj/item/organ/internal/liver name = "liver" icon_state = "liver" - organ_tag = "liver" + organ_tag = O_LIVER parent_organ = BP_GROIN /obj/item/organ/internal/liver/process() diff --git a/code/modules/organs/misc.dm b/code/modules/organs/misc.dm index 50e4d55b2c..e51cab174b 100644 --- a/code/modules/organs/misc.dm +++ b/code/modules/organs/misc.dm @@ -3,7 +3,7 @@ name = "cortical borer" icon = 'icons/obj/objects.dmi' icon_state = "borer" - organ_tag = "brain" + organ_tag = O_BRAIN desc = "A disgusting space slug." parent_organ = BP_HEAD vital = 1 diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 3675f1be7e..0d0e6bc410 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -508,9 +508,9 @@ if(user == src.owner) var/grasp if(user.l_hand == tool && (src.body_part & (ARM_LEFT|HAND_LEFT))) - grasp = "l_hand" + grasp = BP_L_HAND else if(user.r_hand == tool && (src.body_part & (ARM_RIGHT|HAND_RIGHT))) - grasp = "r_hand" + grasp = BP_R_HAND if(grasp) to_chat(user, span_warning("You can't reach your [src.name] while holding [tool] in your [owner.get_bodypart_name(grasp)].")) diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm index 689366a359..e7cb1f7495 100644 --- a/code/modules/organs/subtypes/machine.dm +++ b/code/modules/organs/subtypes/machine.dm @@ -48,7 +48,7 @@ /obj/item/organ/internal/mmi_holder/Initialize(mapload, var/internal, var/obj/item/mmi/installed) . = ..(mapload, internal) - if(!ishuman(loc) || istype(loc, /mob/living/carbon/human/dummy/mannequin)) + if(!ishuman(loc) || ismannequin(loc)) return if(installed) stored_mmi = installed diff --git a/code/modules/organs/subtypes/slime.dm b/code/modules/organs/subtypes/slime.dm index 2e934a2a03..8c41ff0d00 100644 --- a/code/modules/organs/subtypes/slime.dm +++ b/code/modules/organs/subtypes/slime.dm @@ -93,11 +93,9 @@ /obj/item/organ/internal/regennetwork/Initialize(mapload) . = ..() - var/mob/living/carbon/human/H = null - spawn(15) - if(ishuman(owner)) - H = owner - color = H.species.get_blood_colour(H) + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + color = H.species.get_blood_colour(H) /obj/item/organ/internal/regennetwork/proc/get_strain_percent(var/cost) adjust_strain(cost) diff --git a/code/modules/paperwork/paper_sticky.dm b/code/modules/paperwork/paper_sticky.dm index 42e11fc2da..b0f5a43efc 100644 --- a/code/modules/paperwork/paper_sticky.dm +++ b/code/modules/paperwork/paper_sticky.dm @@ -71,10 +71,10 @@ if(!isanimal(user)) if( !user.get_active_hand() ) //if active hand is empty var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user, span_notice("You try to move your [temp.name], but cannot!")) return diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 3ab8c9d092..60077b8a97 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -25,10 +25,10 @@ if(!isanimal(user)) if( !user.get_active_hand() ) //if active hand is empty var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user, span_notice("You try to move your [temp.name], but cannot!")) return @@ -41,9 +41,9 @@ /obj/item/paper_bin/attack_hand(mob/user) if(ishuman(user)) var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (H.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user, span_notice("You try to move your [temp.name], but cannot!")) return diff --git a/code/modules/power/singularity/particle_accelerator/particle_smasher.dm b/code/modules/power/singularity/particle_accelerator/particle_smasher.dm index 9f4a09dbf2..a2e18b24e4 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_smasher.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_smasher.dm @@ -270,6 +270,7 @@ */ /datum/particle_smasher_recipe + var/display_name = "" var/list/reagents // example: = list(REAGENT_ID_PACID = 5) var/list/items // example: = list(/obj/item/tool/crowbar, /obj/item/welder) Place /foo/bar before /foo. Do not include fruit. Maximum of 3 items. var/recipe_type = PS_RESULT_STACK // Are we producing a stack or an item? @@ -282,6 +283,7 @@ var/required_atmos_temp_max = 600 // The maximum ambient atmospheric temperature required, in kelvin. var/probability = 0 // The probability for the recipe to be produced. 0 will make it impossible. var/item_consume_chance = 100 // The probability for the items (not materials) used in the recipe to be consume. + var/wiki_flag = NONE /datum/particle_smasher_recipe/proc/check_items(var/obj/container as obj) . = 1 @@ -320,6 +322,7 @@ return . /datum/particle_smasher_recipe/deuterium_tritium + display_name = MAT_TRITIUM + " from " + MAT_DEUTERIUM reagents = list(REAGENT_ID_HYDROGEN = 15) result = /obj/item/stack/material/tritium @@ -332,6 +335,7 @@ probability = 30 /datum/particle_smasher_recipe/verdantium_morphium + display_name = MAT_MORPHIUM + " from " + MAT_VERDANTIUM result = /obj/item/stack/material/morphium required_material = /obj/item/stack/material/verdantium @@ -340,6 +344,7 @@ probability = 20 /datum/particle_smasher_recipe/plasteel_morphium + display_name = MAT_MORPHIUM + " from Alien Junk" items = list(/obj/item/prop/alien/junk) result = /obj/item/stack/material/morphium @@ -350,6 +355,7 @@ probability = 10 /datum/particle_smasher_recipe/osmium_lead + display_name = MAT_OSMIUM + " from " + MAT_LEAD reagents = list(REAGENT_ID_TUNGSTEN = 10) result = /obj/item/stack/material/lead @@ -363,6 +369,7 @@ probability = 50 /datum/particle_smasher_recipe/phoron_valhollide + display_name = MAT_VALHOLLIDE + " from " + MAT_PHORON reagents = list(REAGENT_ID_PHORON = 10, REAGENT_ID_PACID = 10) result = /obj/item/stack/material/valhollide @@ -376,6 +383,7 @@ probability = 10 /datum/particle_smasher_recipe/valhollide_supermatter + display_name = MAT_SUPERMATTER + " from " + MAT_VALHOLLIDE reagents = list(REAGENT_ID_PHORON = 300) result = /obj/item/stack/material/supermatter @@ -389,6 +397,7 @@ probability = 1 /datum/particle_smasher_recipe/donkpockets_coal + display_name = "Ruined Donkpocket" items = list(/obj/item/reagent_containers/food/snacks/donkpocket) recipe_type = PS_RESULT_ITEM @@ -404,6 +413,7 @@ probability = 90 /datum/particle_smasher_recipe/donkpockets_ascend + display_name = "Ascended Donkpocket" items = list(/obj/item/reagent_containers/food/snacks/donkpocket) reagents = list(REAGENT_ID_PHORON = 120) @@ -420,6 +430,7 @@ probability = 20 /datum/particle_smasher_recipe/glamour + display_name = "Synthesize " + MAT_GLAMOUR items = list(/obj/item/glamour_unstable) result = /obj/item/stack/material/glamour diff --git a/code/modules/power/smes_construction.dm b/code/modules/power/smes_construction.dm index afc03e1268..6ca3243591 100644 --- a/code/modules/power/smes_construction.dm +++ b/code/modules/power/smes_construction.dm @@ -194,7 +194,7 @@ log_game("SMES FAILURE: [src.x]X [src.y]Y [src.z]Z User: [h_user.ckey], Intensity: [intensity]/100") message_admins("SMES FAILURE: [src.x]X [src.y]Y [src.z]Z User: [h_user.ckey], Intensity: [intensity]/100 - JMP") - var/used_hand = h_user.hand?"l_hand":"r_hand" + var/used_hand = h_user.hand?BP_L_HAND:BP_R_HAND switch (intensity) if (0 to 15) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index f662d1567b..7a5a15dacb 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -204,7 +204,7 @@ if((CLUMSY in M.mutations) && prob(40)) //Clumsy handling var/obj/P = consume_next_projectile() if(P) - if(process_projectile(P, user, user, pick("l_foot", "r_foot"))) + if(process_projectile(P, user, user, pick(BP_L_FOOT, BP_R_FOOT))) handle_post_fire(user, user) var/datum/gender/TU = gender_datums[user.get_visible_gender()] user.visible_message( @@ -729,7 +729,7 @@ in_chamber.on_hit(M) if(in_chamber.damage_type != HALLOSS && !in_chamber.nodamage) log_and_message_admins("commited suicide using \a [src]", user) - user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", sharp = TRUE, used_weapon = src) + user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, BP_HEAD, sharp = TRUE, used_weapon = src) user.death() else if(in_chamber.damage_type == HALLOSS) to_chat(user, span_notice("Ow...")) diff --git a/code/modules/reagents/machinery/chemalyzer.dm b/code/modules/reagents/machinery/chemalyzer.dm index 29d38b78c0..f8695039fd 100644 --- a/code/modules/reagents/machinery/chemalyzer.dm +++ b/code/modules/reagents/machinery/chemalyzer.dm @@ -14,6 +14,7 @@ idle_power_usage = 20 clicksound = "button" var/analyzing = FALSE + var/list/found_reagents = list() /obj/machinery/chemical_analyzer/update_icon() icon_state = "chem_analyzer[analyzing ? "-working":""]" @@ -26,7 +27,6 @@ return if(default_deconstruction_crowbar(user, I)) return - if(istype(I,/obj/item/reagent_containers)) analyzing = TRUE update_icon() @@ -45,153 +45,55 @@ I.identify(IDENTITY_FULL, user) // Now tell us everything that is inside. - var/final_message = "" if(I.reagents && I.reagents.reagent_list.len) - final_message += "
" // To add padding between regular chat and the output. + found_reagents.Cut() for(var/datum/reagent/R in I.reagents.reagent_list) if(!R.name) continue - final_message += span_notice("*=*=*=*= Contains " + span_info("[R.volume]u") + " of " + span_bold(span_underline("[R.name]")) + " =*=*=*=*
[R.description][R.from_belly ? " Something seems strange about it...? (OOC: It's from a belly!)" : ""]

") - /* Downstream addiction code - if(R.id in addictives) - final_message += span_boldnotice(span_red("DANGER") + ", [(R.id in fast_addictives) ? "highly " : ""]addictive.)") + "
" - */ - var/list/products = SSchemistry.chemical_reactions_by_product[R.id] - if(products != null && products.len > 0) - var/segment = 1 - var/list/display_reactions = list() - for(var/decl/chemical_reaction/CR in products) - // if(!CR.spoiler) - Downstream self documenting wiki code - display_reactions.Add(CR) - for(var/decl/chemical_reaction/CR in display_reactions) - if(display_reactions.len == 1) - final_message += span_underline("Potential Chemical breakdown:
") - else - final_message += span_underline("Potential Chemical breakdown [segment]:
") - segment += 1 + found_reagents[R.id] = R.volume + tgui_interact(user) + else + to_chat(user, span_warning("Nothing detected in [I]")) - if(istype(CR,/decl/chemical_reaction/instant/slime)) - // Handle slimes - var/decl/chemical_reaction/instant/slime/SR = CR - if(SR.required) - var/slime_path = SR.required - final_message += " -core [span_info(initial(slime_path:name))]
" - for(var/RQ in CR.required_reagents) - var/decl/chemical_reaction/r_RQ = SSchemistry.chemical_reagents[RQ] - if(!r_RQ) - continue - final_message += " -inducer [span_info(r_RQ.name)]
" - else - // Standard - for(var/RQ in CR.required_reagents) - var/decl/chemical_reaction/r_RQ = SSchemistry.chemical_reagents[RQ] - if(!r_RQ) - continue - final_message += " -parts [span_info(r_RQ.name)]
" - for(var/IH in CR.inhibitors) - var/decl/chemical_reaction/r_IH = SSchemistry.chemical_reagents[IH] - if(!r_IH) - continue - final_message += " -inhbi [span_info(r_IH.name)]
" - for(var/CL in CR.catalysts) - var/decl/chemical_reaction/r_CL = SSchemistry.chemical_reagents[CL] - if(!r_CL) - continue - final_message += " -catyl [span_info(r_CL.name)]
" - final_message += "
" - else - final_message += span_underline("Potential Chemical breakdown:") + "
" + span_red("UNKNOWN OR BASE-REAGENT") + "

" - var/list/distilled_products = SSchemistry.distilled_reactions_by_product[R.id] - if(distilled_products != null && distilled_products.len > 0) - var/segment = 1 - - var/list/display_reactions = list() - for(var/decl/chemical_reaction/distilling/CR in distilled_products) - // if(!CR.spoiler) - Downstream self documenting wiki code - display_reactions.Add(CR) - - for(var/decl/chemical_reaction/distilling/CR in display_reactions) - if(display_reactions.len == 1) - final_message += span_underline("Potential Chemical Distillation:
") - else - final_message += span_underline("Potential Chemical Distillation [segment]:
") - segment += 1 - - final_message += " -temps " + span_info("[CR.temp_range[1]]k") + " - " + span_info("[CR.temp_range[2]]k") + "
" - - for(var/RQ in CR.required_reagents) - var/decl/chemical_reaction/r_RQ = SSchemistry.chemical_reagents[RQ] - if(!r_RQ) - continue - final_message += " -parts [span_info(r_RQ.name)]
" - for(var/IH in CR.inhibitors) - var/decl/chemical_reaction/r_IH = SSchemistry.chemical_reagents[IH] - if(!r_IH) - continue - final_message += " -inhbi [span_info(r_IH.name)]
" - for(var/CL in CR.catalysts) - var/decl/chemical_reaction/r_CL = SSchemistry.chemical_reagents[CL] - if(!r_CL) - continue - final_message += " -catyl [span_info(r_CL.name)]
" - final_message += "
" - - // We can get some reagents by grinding sheets and ores! - var/grind_results = "" - for(var/source in global.sheet_reagents) - if(R.id in global.sheet_reagents[source]) - var/nm = initial(source:name) - grind_results += " -grind [span_info(nm)]
" - if(grind_results != "") - final_message += span_underline("Material Sources:
") - final_message += grind_results - final_message += "
" - - grind_results = "" - for(var/source in global.ore_reagents) - if(R.id in global.ore_reagents[source]) - var/nm = initial(source:name) - grind_results += " -grind [span_info(nm)]
" - if(grind_results != "") - final_message += span_underline("Ore Sources:
") - final_message += grind_results - final_message += "
" - - // The long forgotten fluid pumps! - // TODO : Update turfs to provide what their fluidpump outputs are too - var/pump_results = "" - for(var/O in GLOB.ore_data) - var/ore/OR = GLOB.ore_data[O] - if(OR.reagent == R.id) - pump_results += " -erosion [span_info(OR.display_name)]
" - if(pump_results != "") - final_message += span_underline("Fluid Pump Filtrate:
") - final_message += pump_results - final_message += "
" - - var/makes_result = "" - var/list/instant_by_reagent = SSchemistry.instant_reactions_by_reagent["[R.id]"] - if(instant_by_reagent && instant_by_reagent.len) - for(var/i = 1, i <= instant_by_reagent.len, i++) - var/decl/chemical_reaction/OR = instant_by_reagent[i] - if(istype(OR,/decl/chemical_reaction/instant/slime)) // very bloated and meant to be a mystery - continue - makes_result += " -[span_info(OR.name)]
" - - var/list/distilled_by_reagent = SSchemistry.distilled_reactions_by_reagent["[R.id]"] - if(distilled_by_reagent && distilled_by_reagent.len) - for(var/i = 1, i <= distilled_by_reagent.len, i++) - var/decl/chemical_reaction/OR = distilled_by_reagent[i] - makes_result += " -[span_info(OR.name)]
" - - if(makes_result != "") - final_message += span_underline("Can Be Used To Produce:
") - final_message += makes_result - final_message += "
" - - final_message += "Scanning of \the [I] complete." - - to_chat(user, span_notice(final_message)) analyzing = FALSE update_icon() return + +/obj/machinery/chemical_analyzer/attack_hand(mob/user) + if(!found_reagents.len) + return ..() + tgui_interact(user) // Show last analysis + +/obj/machinery/chemical_analyzer/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ChemAnalyzerPro", name) + ui.open() + +/obj/machinery/chemical_analyzer/tgui_data(mob/user) + var/list/data = list() + + var/total_vol = 0 + var/list/reagents_sent = list() + var/obj/item/reagent_containers/glass/beaker/large/beaker_path = /obj/item/reagent_containers/glass/beaker/large + for(var/ID in found_reagents) + var/datum/reagent/R = SSchemistry.chemical_reagents[ID] + if(!R) + continue + var/list/subdata = list() + subdata["title"] = R.name + SSinternal_wiki.add_icon(subdata, initial(beaker_path.icon), initial(beaker_path.icon_state), R.color) + // Get internal data + subdata["description"] = R.description + subdata["flavor"] = R.taste_description + subdata["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type) + subdata["beakerAmount"] = found_reagents[ID] + total_vol += found_reagents[ID] + SSinternal_wiki.assemble_reaction_data(subdata, R) + // Send as a big list of lists + reagents_sent += list(subdata) + data["scannedReagents"] = reagents_sent + data["beakerTotal"] = total_vol + data["beakerMax"] = initial(beaker_path.volume) + + return data diff --git a/code/modules/reagents/reactions/_reactions.dm b/code/modules/reagents/reactions/_reactions.dm index 3240c46370..604340bd86 100644 --- a/code/modules/reagents/reactions/_reactions.dm +++ b/code/modules/reagents/reactions/_reactions.dm @@ -34,6 +34,7 @@ var/reaction_sound = 'sound/effects/bubbles.ogg' 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. + var/wiki_flag = 0 /decl/chemical_reaction/proc/can_happen(var/datum/reagents/holder) //check that all the required reagents are present diff --git a/code/modules/reagents/reactions/instant/drinks.dm b/code/modules/reagents/reactions/instant/drinks.dm index a412710b55..9df54d0dd8 100644 --- a/code/modules/reagents/reactions/instant/drinks.dm +++ b/code/modules/reagents/reactions/instant/drinks.dm @@ -1325,14 +1325,14 @@ result_amount = 15 /decl/chemical_reaction/instant/drinks/nuclearwaste_radium - name = REAGENT_NUCLEARWASTE + name = REAGENT_NUCLEARWASTE + " 226" id = "nuclearwasterad" result = REAGENT_ID_NUCLEARWASTE required_reagents = list(REAGENT_ID_OILSLICK = 1, REAGENT_ID_RADIUM = 1, REAGENT_ID_LIMEJUICE = 1) result_amount = 2 /decl/chemical_reaction/instant/drinks/nuclearwaste_uranium - name = REAGENT_NUCLEARWASTE + name = REAGENT_NUCLEARWASTE + " 238" id = "nuclearwasteuran" result = REAGENT_ID_NUCLEARWASTE required_reagents = list(REAGENT_ID_OILSLICK = 2, REAGENT_ID_URANIUM = 1) diff --git a/code/modules/reagents/reactions/instant/food.dm b/code/modules/reagents/reactions/instant/food.dm index 720188560b..5739969956 100644 --- a/code/modules/reagents/reactions/instant/food.dm +++ b/code/modules/reagents/reactions/instant/food.dm @@ -1,5 +1,6 @@ /decl/chemical_reaction/instant/food name = REAGENT_DEVELOPER_WARNING // Unit test ignore + wiki_flag = WIKI_FOOD /decl/chemical_reaction/instant/food/hot_ramen name = REAGENT_HOTRAMEN @@ -30,7 +31,7 @@ return /decl/chemical_reaction/instant/food/chocolate_bar - name = "Chocolate Bar" + name = "Chocolate Bar Soy" id = "chocolate_bar_soy" result = null required_reagents = list(REAGENT_ID_SOYMILK = 2, REAGENT_ID_COCO = 2, REAGENT_ID_SUGAR = 2) @@ -44,7 +45,7 @@ return /decl/chemical_reaction/instant/food/chocolate_bar2 - name = "Chocolate Bar" + name = "Chocolate Bar Milk" id = "chocolate_bar_milk" result = null required_reagents = list(REAGENT_ID_MILK = 2, REAGENT_ID_COCO = 2, REAGENT_ID_SUGAR = 2) @@ -58,7 +59,7 @@ return /decl/chemical_reaction/instant/food/cookingoilcorn - name = REAGENT_COOKINGOIL + name = "corn " + REAGENT_COOKINGOIL id = "cookingoilcorn" result = REAGENT_ID_COOKINGOIL required_reagents = list(REAGENT_ID_CORNOIL = 10) @@ -66,7 +67,7 @@ result_amount = 10 /decl/chemical_reaction/instant/food/cookingoilpeanut - name = REAGENT_COOKINGOIL + name = "peanut " + REAGENT_ID_COOKINGOIL id = "cookingoilpeanut" result = REAGENT_ID_COOKINGOIL required_reagents = list(REAGENT_ID_PEANUTOIL = 10) diff --git a/code/modules/reagents/reagents/_reagents.dm b/code/modules/reagents/reagents/_reagents.dm index a133a79835..4966de113d 100644 --- a/code/modules/reagents/reagents/_reagents.dm +++ b/code/modules/reagents/reagents/_reagents.dm @@ -45,6 +45,7 @@ var/list/glass_special = null // null equivalent to list() var/from_belly = FALSE + var/wiki_flag = 0 // Bitflags for secret/food/drink reagent sorting /datum/reagent/proc/remove_self(var/amount) // Shortcut if(holder) diff --git a/code/modules/reagents/reagents/dispenser.dm b/code/modules/reagents/reagents/dispenser.dm index a2efdf6a6c..0419d373ab 100644 --- a/code/modules/reagents/reagents/dispenser.dm +++ b/code/modules/reagents/reagents/dispenser.dm @@ -104,6 +104,7 @@ allergen_factor = 1 //simulates mixed drinks containing less of the allergen, as they have only a single actual reagent unlike food affects_robots = 1 //kiss my shiny metal ass + wiki_flag = WIKI_DRINK /datum/reagent/ethanol/touch_mob(var/mob/living/L, var/amount) ..() diff --git a/code/modules/reagents/reagents/drugs.dm b/code/modules/reagents/reagents/drugs.dm index a66abfdbab..d63c4be16b 100644 --- a/code/modules/reagents/reagents/drugs.dm +++ b/code/modules/reagents/reagents/drugs.dm @@ -54,6 +54,7 @@ sober_message_list = list("Everything feels a little more grounded.", "Colors seem... flatter.", "Everything feels a little dull, now.") + wiki_flag = WIKI_SPOILER /datum/reagent/drugs/bliss/affect_blood(mob/living/carbon/M, var/alien, var/removed) ..() diff --git a/code/modules/reagents/reagents/food_drinks.dm b/code/modules/reagents/reagents/food_drinks.dm index 6194103f8b..b7bf4d62ff 100644 --- a/code/modules/reagents/reagents/food_drinks.dm +++ b/code/modules/reagents/reagents/food_drinks.dm @@ -12,6 +12,7 @@ var/injectable = 0 color = "#664330" affects_robots = 1 //VOREStation Edit + wiki_flag = WIKI_FOOD /datum/reagent/nutriment/mix_data(var/list/newdata, var/newamount) @@ -411,6 +412,7 @@ nutriment_factor = 1 color = "#482000" allergen_type = ALLERGEN_COFFEE | ALLERGEN_STIMULANT //Again, coffee contains coffee + wiki_flag = WIKI_DRINK /datum/reagent/nutriment/tea name = REAGENT_TEAPOWDER @@ -421,6 +423,7 @@ nutriment_factor = 1 color = "#101000" allergen_type = ALLERGEN_STIMULANT //Strong enough to contain caffeine + wiki_flag = WIKI_DRINK /datum/reagent/nutriment/decaf_tea name = REAGENT_DECAFTEAPOWDER @@ -430,6 +433,7 @@ taste_mult = 1.3 nutriment_factor = 1 color = "#101000" + wiki_flag = WIKI_DRINK /datum/reagent/nutriment/coco name = REAGENT_COCO @@ -461,6 +465,7 @@ taste_mult = 1.3 nutriment_factor = 1 allergen_type = ALLERGEN_FRUIT //I suppose it's implied here that the juice is from dehydrated fruit. + wiki_flag = WIKI_DRINK /datum/reagent/nutriment/instantjuice/grape name = REAGENT_INSTANTGRAPE @@ -691,6 +696,7 @@ ingest_met = REM color = "#000000" cup_prefix = "peppery" + wiki_flag = WIKI_FOOD /datum/reagent/enzyme name = REAGENT_ENZYME @@ -701,6 +707,7 @@ reagent_state = LIQUID color = "#365E30" overdose = REAGENTS_OVERDOSE + wiki_flag = WIKI_FOOD /datum/reagent/spacespice name = REAGENT_SPACESPICE @@ -709,6 +716,7 @@ reagent_state = SOLID color = "#e08702" cup_prefix = "spicy" + wiki_flag = WIKI_FOOD /datum/reagent/browniemix name = REAGENT_BROWNIEMIX @@ -717,6 +725,7 @@ reagent_state = SOLID color = "#441a03" allergen_type = ALLERGEN_CHOCOLATE + wiki_flag = WIKI_FOOD /datum/reagent/cakebatter name = REAGENT_CAKEBATTER @@ -724,6 +733,7 @@ description = "A batter for making delicious cakes." reagent_state = LIQUID color = "#F0EDDA" + wiki_flag = WIKI_FOOD /datum/reagent/frostoil name = REAGENT_FROSTOIL @@ -734,6 +744,7 @@ reagent_state = LIQUID ingest_met = REM color = "#B31008" + wiki_flag = WIKI_FOOD /datum/reagent/frostoil/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) @@ -783,6 +794,7 @@ ingest_met = REM color = "#B31008" cup_prefix = "hot" + wiki_flag = WIKI_FOOD /datum/reagent/capsaicin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) @@ -970,6 +982,7 @@ var/adj_temp = 0 var/nutriment_factor = 0 //CHOMPStation addition var/water_based = TRUE + wiki_flag = WIKI_DRINK /datum/reagent/drink/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/strength_mod = 1 diff --git a/code/modules/reagents/reagents/food_drinks_vr.dm b/code/modules/reagents/reagents/food_drinks_vr.dm index dd2319d707..079ad536f9 100644 --- a/code/modules/reagents/reagents/food_drinks_vr.dm +++ b/code/modules/reagents/reagents/food_drinks_vr.dm @@ -27,6 +27,7 @@ taste_mult = 1.3 nutriment_factor = 5 color = "#fff200" + wiki_flag = WIKI_DRINK /datum/reagent/lipozine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjust_nutrition(-20 * removed) @@ -543,6 +544,7 @@ id = REAGENT_ID_BRAINPROTEIN taste_description = "fatty, mushy meat and allspice" color = "#caa3c9" + wiki_flag = WIKI_FOOD|WIKI_SPOILER /datum/reagent/nutriment/protein/brainzsnax/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) ..() @@ -580,6 +582,7 @@ description = "A mixture of water and protein commonly used as a meal supplement." taste_description = "pure protein" color = "#ebd8cb" + wiki_flag = WIKI_DRINK /datum/reagent/nutriment/protein_powder/vanilla name = REAGENT_VANILLAPROTEINPOWDER diff --git a/code/modules/reagents/reagents/medicine.dm b/code/modules/reagents/reagents/medicine.dm index ef70d26492..056af17e16 100644 --- a/code/modules/reagents/reagents/medicine.dm +++ b/code/modules/reagents/reagents/medicine.dm @@ -1392,6 +1392,7 @@ metabolism = REM * 4 // Nanomachines gotta go fast. scannable = 1 affects_robots = TRUE + wiki_flag = WIKI_SPOILER /datum/reagent/healing_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.heal_organ_damage(2 * removed, 2 * removed) diff --git a/code/modules/reagents/reagents/medicine_vr.dm b/code/modules/reagents/reagents/medicine_vr.dm index 378b21dde0..7f3707385a 100644 --- a/code/modules/reagents/reagents/medicine_vr.dm +++ b/code/modules/reagents/reagents/medicine_vr.dm @@ -28,6 +28,7 @@ mrate_static = TRUE overdose = 20 //High OD. This is to make numbing bites have somewhat of a downside if you get bit too much. Have to go to medical for dialysis. scannable = 0 //Let's not have medical mechs able to make an extremely strong organic painkiller + wiki_flag = WIKI_SPOILER /datum/reagent/numbing_enzyme/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.add_chemical_effect(CE_PAINKILLER, 200) diff --git a/code/modules/reagents/reagents/other.dm b/code/modules/reagents/reagents/other.dm index 7d05cad593..269f30621c 100644 --- a/code/modules/reagents/reagents/other.dm +++ b/code/modules/reagents/reagents/other.dm @@ -176,6 +176,7 @@ glass_name = "liquid gold" glass_desc = "It's magic. We don't have to explain it." + wiki_flag = WIKI_SPOILER /datum/reagent/adminordrazine/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) affect_blood(M, alien, removed) @@ -316,6 +317,7 @@ affects_robots = TRUE description = "The immense power of a supermatter crystal, in liquid form. You're not entirely sure how that's possible, but it's probably best handled with care." taste_description = "taffy" // 0. The supermatter is tasty, tasty taffy. + wiki_flag = WIKI_SPOILER // Same as if you boop it wrong. It touches you, you die /datum/reagent/supermatter/affect_touch(mob/living/carbon/M, alien, removed) @@ -357,6 +359,7 @@ glass_name = "holy water" glass_desc = "An ashen-obsidian-water mix, this solution will alter certain sections of the brain's rationality." + wiki_flag = WIKI_SPOILER /datum/reagent/water/holywater/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) ..() @@ -651,6 +654,7 @@ color = "#333333" metabolism = REM * 3 // Broken nanomachines go a bit slower. scannable = 1 + wiki_flag = WIKI_SPOILER /datum/reagent/defective_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.take_organ_damage(2 * removed, 2 * removed) diff --git a/code/modules/reagents/reagents/other_vr.dm b/code/modules/reagents/reagents/other_vr.dm index 26b5f6b36d..a52493aa2f 100644 --- a/code/modules/reagents/reagents/other_vr.dm +++ b/code/modules/reagents/reagents/other_vr.dm @@ -39,6 +39,7 @@ color = "#333333" scannable = 1 affects_robots = TRUE + wiki_flag = WIKI_SPOILER /datum/reagent/nif_repair_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(ishuman(M)) diff --git a/code/modules/reagents/reagents/toxins.dm b/code/modules/reagents/reagents/toxins.dm index bab3df1025..c3509e6d2f 100644 --- a/code/modules/reagents/reagents/toxins.dm +++ b/code/modules/reagents/reagents/toxins.dm @@ -73,6 +73,7 @@ color = "#005555" strength = 8 skin_danger = 0.4 + wiki_flag = WIKI_SPOILER /datum/reagent/toxin/neurotoxic_protein/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_CHIMERA) @@ -201,6 +202,7 @@ taste_description = "mold" reagent_state = SOLID strength = 5 + wiki_flag = WIKI_SPOILER /datum/reagent/toxin/mold/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) ..() @@ -215,6 +217,7 @@ reagent_state = LIQUID strength = 5 filtered_organs = list(O_SPLEEN) + wiki_flag = WIKI_SPOILER /datum/reagent/toxin/expired_medicine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) ..() @@ -484,6 +487,7 @@ color = "#664330" power = 2 meltdose = 30 + wiki_flag = WIKI_SPOILER /datum/reagent/acid/diet_digestive name = REAGENT_DIETSTOMACID @@ -494,6 +498,7 @@ color = "#664330" power = 0.4 meltdose = 150 + wiki_flag = WIKI_SPOILER /datum/reagent/thermite/venom name = REAGENT_THERMITEV @@ -503,6 +508,7 @@ reagent_state = SOLID color = "#673910" touch_met = 50 + wiki_flag = WIKI_SPOILER /datum/reagent/thermite/venom/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjustFireLoss(3 * removed) @@ -524,6 +530,7 @@ taste_description = "fire" color = "#B31008" filtered_organs = list(O_SPLEEN) + wiki_flag = WIKI_SPOILER /datum/reagent/condensedcapsaicin/venom/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) @@ -635,6 +642,7 @@ taste_mult = 1.3 reagent_state = LIQUID color = "#801E28" + wiki_flag = WIKI_SPOILER /datum/reagent/slimejelly/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) @@ -762,6 +770,7 @@ glass_name = REAGENT_ID_BEER glass_desc = "A freezing pint of beer" + wiki_flag = WIKI_SPOILER /* Drugs */ @@ -774,6 +783,7 @@ color = "#202040" metabolism = REM * 0.25 overdose = REAGENTS_OVERDOSE + wiki_flag = WIKI_SPOILER /datum/reagent/serotrotium/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) @@ -876,6 +886,7 @@ taste_description = "sludge" reagent_state = LIQUID color = "#13BC5E" + wiki_flag = WIKI_SPOILER /datum/reagent/slimetoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(M.isSynthetic()) @@ -902,6 +913,7 @@ taste_description = "sludge" reagent_state = LIQUID color = "#FF69B4" + wiki_flag = WIKI_SPOILER /datum/reagent/aslimetoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(M.isSynthetic()) @@ -935,6 +947,7 @@ color = "#555555" metabolism = REM * 4 // Nanomachines. Fast. affects_robots = TRUE + wiki_flag = WIKI_SPOILER /datum/reagent/shredding_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjustBruteLoss(4 * removed) @@ -949,6 +962,7 @@ color = "#555555" metabolism = REM * 4 affects_robots = TRUE + wiki_flag = WIKI_SPOILER /datum/reagent/irradiated_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) SSradiation.radiate(get_turf(M), 20) // Irradiate people around you. @@ -964,6 +978,7 @@ metabolism = REM * 4 filtered_organs = list(O_SPLEEN) affects_robots = TRUE + wiki_flag = WIKI_SPOILER /datum/reagent/neurophage_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjustBrainLoss(2 * removed) // Their job is to give you a bad time. @@ -976,6 +991,7 @@ reagent_state = LIQUID color = "#1E4600" taste_mult = 0 + wiki_flag = WIKI_SPOILER /datum/reagent/salmonella/on_mob_life(mob/living/carbon/M) M.ForceContractDisease(new /datum/disease/food_poisoning(0)) diff --git a/code/modules/reagents/reagents/virology.dm b/code/modules/reagents/reagents/virology.dm index c68b89198b..dd133bce82 100644 --- a/code/modules/reagents/reagents/virology.dm +++ b/code/modules/reagents/reagents/virology.dm @@ -40,7 +40,7 @@ color = "#D18AA5" /datum/reagent/toxin/phoron/phoronvirusfood - name = REAGENT_ADRANOLVIRUSFOOD + name = REAGENT_PHORONVIRUSFOOD id = REAGENT_ID_PHORONVIRUSFOOD description = "Mutates viruses when mixed in blood. This one seems to be the strongest." color = "#A69DA9" diff --git a/code/modules/samples/samples.dm b/code/modules/samples/samples.dm index fd0a61479a..1cc01aae16 100644 --- a/code/modules/samples/samples.dm +++ b/code/modules/samples/samples.dm @@ -88,12 +88,12 @@ switch(damage_type) if("BRUTE") H.visible_message(span_danger("\The [src] creaks as it ravages [H]'s hands!")) - H.apply_damage(rand(min_damage,max_damage), BRUTE, "r_hand", used_weapon=src) - H.apply_damage(rand(min_damage,max_damage), BRUTE, "l_hand", used_weapon=src) + H.apply_damage(rand(min_damage,max_damage), BRUTE, BP_R_HAND, used_weapon=src) + H.apply_damage(rand(min_damage,max_damage), BRUTE, BP_L_HAND, used_weapon=src) if("BURN") H.visible_message(span_danger("\The [src] flashes as it scorches [H]'s hands!")) - H.apply_damage(rand(min_damage,max_damage), BURN, "r_hand", used_weapon=src) - H.apply_damage(rand(min_damage,max_damage), BURN, "l_hand", used_weapon=src) + H.apply_damage(rand(min_damage,max_damage), BURN, BP_R_HAND, used_weapon=src) + H.apply_damage(rand(min_damage,max_damage), BURN, BP_L_HAND, used_weapon=src) if("TOX") H.visible_message(span_danger("\The [src] seethes and hisses like burning acid!")) if(!H.isSynthetic()) @@ -145,12 +145,12 @@ switch(damage_type) if("BRUTE") H.visible_message(span_danger("\The [src] creaks as it ravages [H]'s hands!")) - H.apply_damage(rand(min_damage,max_damage), BRUTE, "r_hand", used_weapon=src) - H.apply_damage(rand(min_damage,max_damage), BRUTE, "l_hand", used_weapon=src) + H.apply_damage(rand(min_damage,max_damage), BRUTE, BP_R_HAND, used_weapon=src) + H.apply_damage(rand(min_damage,max_damage), BRUTE, BP_L_HAND, used_weapon=src) if("BURN") H.visible_message(span_danger("\The [src] flashes as it scorches [H]'s hands!")) - H.apply_damage(rand(min_damage,max_damage), BURN, "r_hand", used_weapon=src) - H.apply_damage(rand(min_damage,max_damage), BURN, "l_hand", used_weapon=src) + H.apply_damage(rand(min_damage,max_damage), BURN, BP_R_HAND, used_weapon=src) + H.apply_damage(rand(min_damage,max_damage), BURN, BP_L_HAND, used_weapon=src) if("TOX") H.visible_message(span_danger("\The [src] seethes and hisses like burning acid!")) if(!H.isSynthetic()) diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 5a8063ab6c..cd81eb0165 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -200,7 +200,7 @@ /datum/surgery_step/cavity/implant_removal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) if(affected.organ_tag == BP_HEAD) - var/obj/item/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/sponge = target.internal_organs_by_name[O_BRAIN] return ..() && (!sponge || !sponge.damage) else return ..() diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 47345bd63a..48a68e03e5 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -533,12 +533,12 @@ user.balloon_alert(user, "you cannot install a computer brain into a meat skull") // CHOMPEdit return SURGERY_FAILURE - if(!target.should_have_organ("brain")) + if(!target.should_have_organ(O_BRAIN)) to_chat(user, span_danger("You're pretty sure [target.species.name_plural] don't normally have a brain.")) user.balloon_alert(user, "you're pertty sure [target.species.name_plural] don't normall have a brain") // CHOMPEdit return SURGERY_FAILURE - if(!isnull(target.internal_organs["brain"])) + if(!isnull(target.internal_organs[O_BRAIN])) to_chat(user, span_danger("Your subject already has a brain.")) user.balloon_alert(user, "your subject already has a brain") // CHOMPEdit return SURGERY_FAILURE @@ -572,7 +572,7 @@ else holder = new /obj/item/organ/internal/mmi_holder(target, 1, M) // Fallback to old behavior if organic MMI or if no subtype exists. //VOREstation edit end - target.internal_organs_by_name["brain"] = holder + target.internal_organs_by_name[O_BRAIN] = holder if(M.brainmob && M.brainmob.mind) M.brainmob.mind.transfer_to(target) @@ -640,12 +640,12 @@ user.balloon_alert(user, "you're fairly certain a nymph can't pilot a normal robot") // CHOMPEdit return SURGERY_FAILURE - if(!target.should_have_organ("brain")) + if(!target.should_have_organ(O_BRAIN)) to_chat(user, span_danger("You're pretty sure [target.species.name_plural] don't normally have a brain.")) user.balloon_alert(user, "you're pretty sure [target.species.name_plural] don't normall have a brain") // CHOMPEdit return SURGERY_FAILURE - if(!isnull(target.internal_organs["brain"])) + if(!isnull(target.internal_organs[O_BRAIN])) to_chat(user, span_danger("Your subject already has a cephalon.")) user.balloon_alert(user, "your subject already has a cephalon") // CHOMPEdit return SURGERY_FAILURE @@ -667,7 +667,7 @@ var/obj/item/holder/diona/N = tool var/obj/item/organ/internal/brain/cephalon/cephalon = new(target, 1) - target.internal_organs_by_name["brain"] = cephalon + target.internal_organs_by_name[O_BRAIN] = cephalon var/mob/living/carbon/alien/diona/D = N.held_mob user.drop_from_inventory(tool) diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm index fa693a01ac..3bd7f99924 100644 --- a/code/modules/tgui/modules/appearance_changer.dm +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -687,6 +687,8 @@ var/list/usable_markings = markings.Copy() ^ body_marking_styles_list.Copy() var/marking_styles[0] for(var/marking_style in usable_markings) + if(marking_style == DEVELOPER_WARNING_NAME) + continue var/datum/sprite_accessory/marking/S = body_marking_styles_list[marking_style] var/our_iconstate = S.icon_state if(LAZYLEN(S.body_parts)) diff --git a/code/modules/tgui/modules/late_choices.dm b/code/modules/tgui/modules/late_choices.dm index 67df7c3b4a..04cc46d658 100644 --- a/code/modules/tgui/modules/late_choices.dm +++ b/code/modules/tgui/modules/late_choices.dm @@ -49,7 +49,7 @@ if(!job.minimum_character_age && !job.min_age_by_species) return TRUE - var/min_age = job.get_min_age(prefs.species, prefs.organ_data["brain"]) + var/min_age = job.get_min_age(prefs.species, prefs.organ_data[O_BRAIN]) if(prefs.read_preference(/datum/preference/numeric/human/age) >= min_age) return TRUE return FALSE diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm index 5668118185..7069e53e64 100644 --- a/code/modules/vore/eating/vorepanel_vr.dm +++ b/code/modules/vore/eating/vorepanel_vr.dm @@ -1536,7 +1536,7 @@ holder = holdertmp else holder = new(body_backup, 1) - body_backup.internal_organs_by_name["brain"] = holder + body_backup.internal_organs_by_name[O_BRAIN] = holder MMI.loc = holder holder.stored_mmi = MMI holder.update_from_mmi() diff --git a/code/modules/vore/resizing/holder_vr.dm b/code/modules/vore/resizing/holder_vr.dm index b8e636d09b..bc38d54e9c 100644 --- a/code/modules/vore/resizing/holder_vr.dm +++ b/code/modules/vore/resizing/holder_vr.dm @@ -13,9 +13,9 @@ return if (hasorgans(user)) var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] if (user.hand) - temp = H.organs_by_name["l_hand"] + temp = H.organs_by_name[BP_L_HAND] if(temp && !temp.is_usable()) to_chat(user, span_notice("You try to move your [temp.name], but cannot!")) return diff --git a/code/modules/xenoarcheaology/finds/Weapons/archeo_melee.dm b/code/modules/xenoarcheaology/finds/Weapons/archeo_melee.dm index 73ac979675..6dcbca169e 100644 --- a/code/modules/xenoarcheaology/finds/Weapons/archeo_melee.dm +++ b/code/modules/xenoarcheaology/finds/Weapons/archeo_melee.dm @@ -89,7 +89,7 @@ /obj/item/melee/artifact_blade/attack(mob/living/M, mob/living/user, var/target_zone) if(M == user) //No accidentally hitting yourself and exploding. return - var/zone = (user.hand ? "l_arm":"r_arm") //Which arm we're in! + var/zone = (user.hand ? BP_L_ARM:BP_R_ARM) //Which arm we're in! var/prior_force = force if(empowered) force = force*2 diff --git a/code/modules/xenobio/items/extracts.dm b/code/modules/xenobio/items/extracts.dm index 204ae28f5c..090e8c6b13 100644 --- a/code/modules/xenobio/items/extracts.dm +++ b/code/modules/xenobio/items/extracts.dm @@ -655,6 +655,7 @@ description = "A slimy liquid which appears to rapidly clot internal hemorrhages by increasing the effectiveness of platelets at low quantities. Toxic in high quantities." taste_description = "slime" overdose = 5 + wiki_flag = WIKI_SPOILER /datum/reagent/osteodaxon/slime name = REAGENT_SLIMEBONEFIXER @@ -662,6 +663,7 @@ description = "A slimy liquid which can be used to heal bone fractures at low quantities. Toxic in high quantities." taste_description = "slime" overdose = 5 + wiki_flag = WIKI_SPOILER /datum/reagent/peridaxon/slime name = REAGENT_SLIMEORGANFIXER @@ -669,6 +671,7 @@ description = "A slimy liquid which is used to encourage recovery of internal organs and nervous systems in low quantities. Toxic in high quantities." taste_description = "slime" overdose = 5 + wiki_flag = WIKI_SPOILER // ************** diff --git a/code/modules/xenobio/items/slime_objects.dm b/code/modules/xenobio/items/slime_objects.dm index 732a438af5..1ee2699e4b 100644 --- a/code/modules/xenobio/items/slime_objects.dm +++ b/code/modules/xenobio/items/slime_objects.dm @@ -218,3 +218,4 @@ color = "#FABA3A" nutriment_factor = 30 taste_description = "slimy nectar" + wiki_flag = WIKI_FOOD|WIKI_SPOILER diff --git a/code/unit_tests/reagent_tests.dm b/code/unit_tests/reagent_tests.dm index 0d1850e20f..f5b147da7c 100644 --- a/code/unit_tests/reagent_tests.dm +++ b/code/unit_tests/reagent_tests.dm @@ -28,7 +28,7 @@ log_unit_test("[Rpath]: Reagents - Reagent ID must be all lowercase.") failed = TRUE - if(collection_name[R.name]) + if(collection_name[R.name] && !(R.wiki_flag & WIKI_SPOILER)) // If wiki hidden it's probably intentional! log_unit_test("[Rpath]: Reagents - WARNING - reagent name \"[R.name]\" is not unique, used first in [collection_name[R.name]]. Is this intentional?") collection_name[R.name] = R.type diff --git a/modular_chomp/code/modules/reagents/reagents/food_drinks.dm b/modular_chomp/code/modules/reagents/reagents/food_drinks.dm index e9fec17081..6d84aba5e8 100644 --- a/modular_chomp/code/modules/reagents/reagents/food_drinks.dm +++ b/modular_chomp/code/modules/reagents/reagents/food_drinks.dm @@ -296,7 +296,7 @@ M.adjustToxLoss(-2 * removed) //Higher toxin removal than other tea to reflect difficulty in preparing, still worse than dylovene. /datum/reagent/drink/freshtea/green - name = REAGENT_FRESHTEA + name = REAGENT_FRESHGREENTEA id = REAGENT_ID_FRESHTEAGREEN description = "Floral green tea, it has antioxidants, it's good for you! Fresh means it's even healthier!" taste_description = "floral with vegetal notes and a slightly bitter aftertaste" diff --git a/tgui/.eslintrc.yml b/tgui/.eslintrc.yml index 92dfe1320c..2f6eea9fac 100644 --- a/tgui/.eslintrc.yml +++ b/tgui/.eslintrc.yml @@ -15,6 +15,7 @@ plugins: - react - unused-imports - simple-import-sort + - "@typescript-eslint" settings: react: version: '18.2' @@ -552,7 +553,7 @@ rules: prefer-arrow-callback: error ## Require const declarations for variables that are never reassigned after ## declared - # prefer-const: error + prefer-const: error ## Require destructuring from arrays and/or objects # prefer-destructuring: error ## Disallow parseInt() and Number.parseInt() in favor of binary, octal, and @@ -768,3 +769,6 @@ rules: ## https://github.com/lydell/eslint-plugin-simple-import-sort/ simple-import-sort/imports: error simple-import-sort/exports: error + + ## Typescript + "@typescript-eslint/consistent-type-imports": [error, { fixStyle: inline-type-imports }] diff --git a/tgui/package.json b/tgui/package.json index d7a0ec0fdc..a389057e9f 100644 --- a/tgui/package.json +++ b/tgui/package.json @@ -30,6 +30,7 @@ "@types/react-dom": "^18.3.1", "@types/webpack-env": "^1.18.5", "@types/wicg-file-system-access": "^2023.10.5", + "@typescript-eslint/eslint-plugin": "7.18.0", "@typescript-eslint/parser": "^8.13.0", "@typescript-eslint/utils": "^8.13.0", "css-loader": "^7.1.2", @@ -55,6 +56,7 @@ "swc-loader": "^0.2.6", "tgui-core": "^1.8.2", "typescript": "5.6.3", + "typescript-eslint": "^8.28.0", "url-loader": "^4.1.1", "webpack": "^5.96.1", "webpack-bundle-analyzer": "^4.10.2", diff --git a/tgui/packages/common/collections.ts b/tgui/packages/common/collections.ts index 9aed42557d..2c15095fb1 100644 --- a/tgui/packages/common/collections.ts +++ b/tgui/packages/common/collections.ts @@ -67,7 +67,7 @@ export const map: MapFunction = (collection, iterateeFn) => { if (typeof collection === 'object') { const result: unknown[] = []; - for (let i in collection) { + for (const i in collection) { if (Object.prototype.hasOwnProperty.call(collection, i)) { result.push(iterateeFn(collection[i], i, collection)); } @@ -110,7 +110,7 @@ export const sortBy = ( } let length = array.length; // Iterate over the array to collect criteria to sort it by - let mappedArray: { + const mappedArray: { criteria: unknown[]; value: T; }[] = []; @@ -205,7 +205,7 @@ export const uniqBy = ( // prettier-ignore outer: while (++index < length) { - let value: T | 0 = array[index]; + const value: T | 0 = array[index]; const computed = iterateeFn ? iterateeFn(value) : value; if (computed === computed) { let seenIndex = seen.length; diff --git a/tgui/packages/common/perf.ts b/tgui/packages/common/perf.ts index 9266d88a89..a7dfefc1e1 100644 --- a/tgui/packages/common/perf.ts +++ b/tgui/packages/common/perf.ts @@ -14,9 +14,9 @@ const FRAME_DURATION = 1000 / FPS; // True if Performance API is supported const supportsPerf = !!window.performance?.now; // High precision markers -let hpMarkersByName: Record = {}; +const hpMarkersByName: Record = {}; // Low precision markers -let lpMarkersByName: Record = {}; +const lpMarkersByName: Record = {}; /** * Marks a certain spot in the code for later measurements. diff --git a/tgui/packages/common/redux.test.ts b/tgui/packages/common/redux.test.ts index d4af99907c..8abe16d3c3 100644 --- a/tgui/packages/common/redux.test.ts +++ b/tgui/packages/common/redux.test.ts @@ -1,10 +1,10 @@ import { - Action, + type Action, applyMiddleware, combineReducers, createAction, createStore, - Reducer, + type Reducer, } from './redux'; // Dummy Reducer diff --git a/tgui/packages/common/redux.ts b/tgui/packages/common/redux.ts index c8eb268f5d..dd9b2ee4e6 100644 --- a/tgui/packages/common/redux.ts +++ b/tgui/packages/common/redux.ts @@ -56,7 +56,7 @@ export const createStore = ( } let currentState: State; - let listeners: Array<() => void> = []; + const listeners: Array<() => void> = []; const getState = (): State => currentState; diff --git a/tgui/packages/tgui-dev-server/dreamseeker.js b/tgui/packages/tgui-dev-server/dreamseeker.js index d1ca2a9ac5..e889518e1f 100644 --- a/tgui/packages/tgui-dev-server/dreamseeker.js +++ b/tgui/packages/tgui-dev-server/dreamseeker.js @@ -47,7 +47,7 @@ DreamSeeker.getInstancesByPids = async (pids) => { } const instances = []; const pidsToResolve = []; - for (let pid of pids) { + for (const pid of pids) { const instance = instanceByPid.get(pid); if (instance) { instances.push(instance); @@ -66,7 +66,7 @@ DreamSeeker.getInstancesByPids = async (pids) => { // proto addr mask mode pid const entries = []; const lines = stdout.split('\r\n'); - for (let line of lines) { + for (const line of lines) { const words = line.match(/\S+/g); if (!words || words.length === 0) { continue; @@ -81,7 +81,7 @@ DreamSeeker.getInstancesByPids = async (pids) => { } const len = entries.length; logger.log('found', len, plural('instance', len)); - for (let entry of entries) { + for (const entry of entries) { const { pid, addr } = entry; const instance = new DreamSeeker(pid, addr); instances.push(instance); diff --git a/tgui/packages/tgui-dev-server/link/client.cjs b/tgui/packages/tgui-dev-server/link/client.cjs index b0e6f7bc9d..99e0d115b8 100644 --- a/tgui/packages/tgui-dev-server/link/client.cjs +++ b/tgui/packages/tgui-dev-server/link/client.cjs @@ -25,7 +25,7 @@ const ensureConnection = () => { }; socket.onmessage = (event) => { const msg = JSON.parse(event.data); - for (let subscriber of subscribers) { + for (const subscriber of subscribers) { subscriber(msg); } }; diff --git a/tgui/packages/tgui-dev-server/link/retrace.js b/tgui/packages/tgui-dev-server/link/retrace.js index 083ddb37d1..9d347ac80d 100644 --- a/tgui/packages/tgui-dev-server/link/retrace.js +++ b/tgui/packages/tgui-dev-server/link/retrace.js @@ -27,7 +27,7 @@ export const loadSourceMaps = async (bundleDir) => { } // Load new sourcemaps const paths = await resolveGlob(bundleDir, '*.map'); - for (let path of paths) { + for (const path of paths) { try { const file = basename(path).replace('.map', ''); const consumer = await new SourceMapConsumer( diff --git a/tgui/packages/tgui-dev-server/link/server.js b/tgui/packages/tgui-dev-server/link/server.js index 2a1f551bf6..33dbc6817c 100644 --- a/tgui/packages/tgui-dev-server/link/server.js +++ b/tgui/packages/tgui-dev-server/link/server.js @@ -91,7 +91,7 @@ class LinkServer { return; } if (type === 'relay') { - for (let client of this.wss.clients) { + for (const client of this.wss.clients) { if (client === ws) { continue; } @@ -112,7 +112,7 @@ class LinkServer { return; } logger.log(`broadcasting ${msg.type} to ${clients.length} clients`); - for (let client of clients) { + for (const client of clients) { const json = JSON.stringify(msg); client.send(json); } diff --git a/tgui/packages/tgui-dev-server/reloader.js b/tgui/packages/tgui-dev-server/reloader.js index cb477a6523..9793baf03f 100644 --- a/tgui/packages/tgui-dev-server/reloader.js +++ b/tgui/packages/tgui-dev-server/reloader.js @@ -37,7 +37,7 @@ export const findCacheRoot = async () => { } logger.log('looking for byond cache'); // Find BYOND cache folders - for (let pattern of SEARCH_LOCATIONS) { + for (const pattern of SEARCH_LOCATIONS) { if (!pattern) { continue; } @@ -51,7 +51,10 @@ export const findCacheRoot = async () => { // Query the Windows Registry if (process.platform === 'win32') { logger.log('querying windows registry'); - let userpath = await regQuery('HKCU\\Software\\Dantom\\BYOND', 'userpath'); + const userpath = await regQuery( + 'HKCU\\Software\\Dantom\\BYOND', + 'userpath', + ); if (userpath) { // prettier-ignore cacheRoot = userpath @@ -92,7 +95,7 @@ export const reloadByondCache = async (bundleDir) => { bundleDir, './*.+(bundle|chunk|hot-update).*', ); - for (let cacheDir of cacheDirs) { + for (const cacheDir of cacheDirs) { // Clear garbage const garbage = await resolveGlob( cacheDir, @@ -102,11 +105,11 @@ export const reloadByondCache = async (bundleDir) => { // Plant a dummy browser window file, we'll be using this to avoid world topic. For byond 515. fs.closeSync(fs.openSync(cacheDir + '/dummy', 'w')); - for (let file of garbage) { + for (const file of garbage) { fs.unlinkSync(file); } // Copy assets - for (let asset of assets) { + for (const asset of assets) { const destination = resolvePath(cacheDir, basename(asset)); fs.writeFileSync(destination, fs.readFileSync(asset)); } @@ -120,7 +123,7 @@ export const reloadByondCache = async (bundleDir) => { const dss = await dssPromise; if (dss.length > 0) { logger.log(`notifying dreamseeker`); - for (let dreamseeker of dss) { + for (const dreamseeker of dss) { dreamseeker.topic({ tgui: 1, type: 'cacheReloaded', diff --git a/tgui/packages/tgui-dev-server/util.js b/tgui/packages/tgui-dev-server/util.js index 13fbef3b21..527f2de868 100644 --- a/tgui/packages/tgui-dev-server/util.js +++ b/tgui/packages/tgui-dev-server/util.js @@ -23,7 +23,7 @@ export const resolveGlob = (...sections) => { windowsPathsNoEscape: true, }); const safePaths = []; - for (let path of unsafePaths) { + for (const path of unsafePaths) { try { fs.statSync(path); safePaths.push(path); diff --git a/tgui/packages/tgui-dev-server/webpack.js b/tgui/packages/tgui-dev-server/webpack.js index e4fbdeb9f1..7e5d0b9222 100644 --- a/tgui/packages/tgui-dev-server/webpack.js +++ b/tgui/packages/tgui-dev-server/webpack.js @@ -52,7 +52,7 @@ class WebpackCompiler { compiler.hooks.watchRun.tapPromise('tgui-dev-server', async () => { const files = await resolveGlob(this.bundleDir, './*.hot-update.*'); logger.log(`clearing garbage (${files.length} files)`); - for (let file of files) { + for (const file of files) { fs.unlinkSync(file); } logger.log('compiling'); diff --git a/tgui/packages/tgui-panel/chat/ChatPanel.tsx b/tgui/packages/tgui-panel/chat/ChatPanel.tsx index 73dbdeadac..56e87e2d4c 100644 --- a/tgui/packages/tgui-panel/chat/ChatPanel.tsx +++ b/tgui/packages/tgui-panel/chat/ChatPanel.tsx @@ -4,7 +4,7 @@ * @license MIT */ -import { Component, createRef, RefObject } from 'react'; +import { Component, createRef, type RefObject } from 'react'; import { Button } from 'tgui-core/components'; import { shallowDiffers } from 'tgui-core/react'; diff --git a/tgui/packages/tgui-panel/chat/ChatTabs.tsx b/tgui/packages/tgui-panel/chat/ChatTabs.tsx index 5c2e9a5978..b2a295d9d6 100644 --- a/tgui/packages/tgui-panel/chat/ChatTabs.tsx +++ b/tgui/packages/tgui-panel/chat/ChatTabs.tsx @@ -10,7 +10,7 @@ import { Box, Button, Stack, Tabs } from 'tgui-core/components'; import { openChatSettings } from '../settings/actions'; import { addChatPage, changeChatPage } from './actions'; import { selectChatPages, selectCurrentChatPage } from './selectors'; -import { Page } from './types'; +import type { Page } from './types'; const UnreadCountWidget = ({ value }: { value: number }) => ( >) => { return; } if (messages) { - for (let message of messages) { + for (const message of messages) { if (message.html) { message.html = DOMPurify.sanitize(message.html, { FORBID_TAGS: blacklisted_tags, @@ -95,7 +95,7 @@ const loadChatFromStorage = async (store: Store>) => { }); } if (archivedMessages) { - for (let archivedMessage of archivedMessages as message[]) { + for (const archivedMessage of archivedMessages as message[]) { if (archivedMessage.html) { archivedMessage.html = DOMPurify.sanitize(archivedMessage.html, { FORBID_TAGS: blacklisted_tags, @@ -115,7 +115,7 @@ const loadChatFromStorage = async (store: Store>) => { settings.exportStart = 0; settings.exportEnd = 0; - for (let message of archivedMessages as message[]) { + for (const message of archivedMessages as message[]) { const currentId = message.roundId || 0; if (currentId !== oldId) { const round = currentId; @@ -191,7 +191,7 @@ const loadChatFromDBStorage = async ( ); if (messages) { - for (let message of messages) { + for (const message of messages) { if (message.html) { message.html = DOMPurify.sanitize(message.html, { FORBID_TAGS: blacklisted_tags, diff --git a/tgui/packages/tgui-panel/chat/model.ts b/tgui/packages/tgui-panel/chat/model.ts index 5489996f1c..c39e3fda30 100644 --- a/tgui/packages/tgui-panel/chat/model.ts +++ b/tgui/packages/tgui-panel/chat/model.ts @@ -14,7 +14,7 @@ export const canPageAcceptType = (page: Page, type: string): string | boolean => export const typeIsImportant = (type: string): boolean => { let isImportant = false; - for (let typeDef of MESSAGE_TYPES) { + for (const typeDef of MESSAGE_TYPES) { if (typeDef.type === type && !!typeDef.important) { isImportant = true; break; @@ -26,7 +26,7 @@ export const typeIsImportant = (type: string): boolean => { export const adminPageOnly = (page: Page): boolean => { let adminTab = true; let checked = 0; - for (let typeDef of MESSAGE_TYPES) { + for (const typeDef of MESSAGE_TYPES) { if ( page.acceptedTypes[typeDef.type] && !(!!typeDef.important || !!typeDef.admin) @@ -47,9 +47,9 @@ export const canStoreType = ( ) => storedTypes[type]; export const createPage = (obj?: Object): Page => { - let acceptedTypes = {}; + const acceptedTypes = {}; - for (let typeDef of MESSAGE_TYPES) { + for (const typeDef of MESSAGE_TYPES) { acceptedTypes[typeDef.type] = !!typeDef.important; } @@ -67,7 +67,7 @@ export const createPage = (obj?: Object): Page => { export const createMainPage = (): Page => { const acceptedTypes = {}; - for (let typeDef of MESSAGE_TYPES) { + for (const typeDef of MESSAGE_TYPES) { acceptedTypes[typeDef.type] = true; } return createPage({ diff --git a/tgui/packages/tgui-panel/chat/reducer.ts b/tgui/packages/tgui-panel/chat/reducer.ts index fc91438530..bf33554fce 100644 --- a/tgui/packages/tgui-panel/chat/reducer.ts +++ b/tgui/packages/tgui-panel/chat/reducer.ts @@ -42,11 +42,11 @@ export const chatReducer = (state = initialState, action) => { // Enable any filters that are not explicitly set, that are // enabled by default on the main page. // NOTE: This mutates acceptedTypes on the state. - for (let id of Object.keys(payload.pageById)) { + for (const id of Object.keys(payload.pageById)) { const page = payload.pageById[id]; const filters = page.acceptedTypes; const defaultFilters = mainPage.acceptedTypes; - for (let type of Object.keys(defaultFilters)) { + for (const type of Object.keys(defaultFilters)) { if (filters[type] === undefined) { filters[type] = defaultFilters[type]; } @@ -55,7 +55,7 @@ export const chatReducer = (state = initialState, action) => { // Reset page message counts // NOTE: We are mutably changing the payload on the assumption // that it is a copy that comes straight from the web storage. - for (let id of Object.keys(payload.pageById)) { + for (const id of Object.keys(payload.pageById)) { const page = payload.pageById[id]; page.unreadCount = 0; } @@ -88,9 +88,9 @@ export const chatReducer = (state = initialState, action) => { const pages = state.pages.map((id) => state.pageById[id]); const currentPage = state.pageById[state.currentPageId]; const nextPageById = { ...state.pageById }; - for (let page of pages) { + for (const page of pages) { let unreadCount = 0; - for (let type of Object.keys(countByType)) { + for (const type of Object.keys(countByType)) { // Message does not belong here if (!canPageAcceptType(page, type)) { continue; diff --git a/tgui/packages/tgui-panel/chat/renderer.tsx b/tgui/packages/tgui-panel/chat/renderer.tsx index 68fb51b6d6..9b71f5504d 100644 --- a/tgui/packages/tgui-panel/chat/renderer.tsx +++ b/tgui/packages/tgui-panel/chat/renderer.tsx @@ -198,6 +198,7 @@ class ChatRenderer { }[] | null; databaseBackendEnabled: boolean; + lastScrollHeight: number; constructor() { /** @type {HTMLElement} */ this.loaded = false; @@ -227,13 +228,15 @@ class ChatRenderer { /** @type {HTMLElement} */ this.scrollNode = null; this.scrollTracking = true; + this.lastScrollHeight = 0; this.handleScroll = (type) => { const node = this.scrollNode; if (node) { const height = node.scrollHeight; const bottom = node.scrollTop + node.offsetHeight; const scrollTracking = - Math.abs(height - bottom) < SCROLL_TRACKING_TOLERANCE; + Math.abs(height - bottom) < SCROLL_TRACKING_TOLERANCE || + this.lastScrollHeight === 0; if (scrollTracking !== this.scrollTracking) { this.scrollTracking = scrollTracking; this.events.emit('scrollTrackingChanged', scrollTracking); @@ -350,7 +353,7 @@ class ChatRenderer { let blacklistWords; let blacklistregex; if (highlightBlacklist && blacklistLines.length > 0) { - let blacklistRegexExpressions: string[] = []; + const blacklistRegexExpressions: string[] = []; for (let line of blacklistLines) { // Regex expression syntax is /[exp]/ if (line.charAt(0) === '/' && line.charAt(line.length - 1) === '/') { @@ -383,7 +386,7 @@ class ChatRenderer { blacklistregex = null; } } - let regexExpressions: string[] = []; + const regexExpressions: string[] = []; // Organize each highlight entry into regex expressions and words for (let line of lines) { // Regex expression syntax is /[exp]/ @@ -489,7 +492,7 @@ class ChatRenderer { // Re-add message nodes const fragment = document.createDocumentFragment(); let node; - for (let message of this.messages) { + for (const message of this.messages) { if ( canPageAcceptType(page, message.type) && !( @@ -556,11 +559,15 @@ class ChatRenderer { } return; } + // Store last scroll position + if (this.scrollNode) { + this.lastScrollHeight = this.scrollNode.scrollHeight; + } // Insert messages const fragment = document.createDocumentFragment(); const countByType = {}; let node; - for (let payload of batch) { + for (const payload of batch) { const message = createMessage(payload); // Combine messages const combinable = this.getCombinableMessage(message); @@ -602,7 +609,7 @@ class ChatRenderer { const childNode = nodes[i]; const targetName = childNode.getAttribute('data-component'); // Let's pull out the attibute info we need - let outputProps = {}; + const outputProps = {}; for (let j = 0; j < childNode.attributes.length; j++) { const attribute = childNode.attributes[j]; @@ -807,7 +814,7 @@ class ChatRenderer { const fromIndex = Math.max(0, this.messages.length - rebuildLimit); const messages = this.messages.slice(fromIndex); // Remove existing nodes - for (let message of messages) { + for (const message of messages) { message.node = undefined; } // Fast clear of the root node @@ -897,7 +904,7 @@ class ChatRenderer { } // for (let message of this.visibleMessages) { // TODO: Actually having a better message archiving maybe for exports? - for (let message of tmpMsgArray) { + for (const message of tmpMsgArray) { // Filter messages according to active tab for export if (this.page && canPageAcceptType(this.page, message.type)) { messagesHtml += message.html + '\n'; diff --git a/tgui/packages/tgui-panel/chat/replaceInTextNode.ts b/tgui/packages/tgui-panel/chat/replaceInTextNode.ts index f2e16124ad..8fe899e8e7 100644 --- a/tgui/packages/tgui-panel/chat/replaceInTextNode.ts +++ b/tgui/packages/tgui-panel/chat/replaceInTextNode.ts @@ -103,7 +103,7 @@ export const replaceInTextNode = if (words) { let i = 0; let wordRegexStr = '('; - for (let word of words) { + for (const word of words) { // Capture if the word is at the beginning, end, middle, // or by itself in a message wordRegexStr += `^${word}\\s\\W|\\s\\W${word}\\s\\W|\\s\\W${word}$|^${word}\\s\\W$`; @@ -115,7 +115,7 @@ export const replaceInTextNode = wordRegexStr += ')'; const wordRegex = new RegExp(wordRegexStr, 'gi'); if (regex && nodes) { - for (let a_node of nodes) { + for (const a_node of nodes) { result = regexParseNode({ node: a_node, regex: wordRegex, diff --git a/tgui/packages/tgui-panel/settings/reducer.ts b/tgui/packages/tgui-panel/settings/reducer.ts index e4e21ffaca..46f8410ff3 100644 --- a/tgui/packages/tgui-panel/settings/reducer.ts +++ b/tgui/packages/tgui-panel/settings/reducer.ts @@ -107,8 +107,8 @@ export function settingsReducer( ...payload, }; nextState.initialized = true; - let newFilters = {}; - for (let typeDef of MESSAGE_TYPES) { + const newFilters = {}; + for (const typeDef of MESSAGE_TYPES) { if ( nextState.storedTypes[typeDef.type] === null || nextState.storedTypes[typeDef.type] === undefined diff --git a/tgui/packages/tgui-say/ChannelIterator.ts b/tgui/packages/tgui-say/ChannelIterator.ts index 38ba90c0af..50baac82a7 100644 --- a/tgui/packages/tgui-say/ChannelIterator.ts +++ b/tgui/packages/tgui-say/ChannelIterator.ts @@ -36,7 +36,7 @@ export class ChannelIterator { } for (let index = 1; index <= this.channels.length; index++) { - let nextIndex = (this.index + index) % this.channels.length; + const nextIndex = (this.index + index) % this.channels.length; if (!this.blacklist.includes(this.channels[nextIndex])) { this.index = nextIndex; break; @@ -52,7 +52,7 @@ export class ChannelIterator { } for (let index = 1; index <= this.channels.length; index++) { - let nextIndex = + const nextIndex = (this.index - index + this.channels.length) % this.channels.length; if (!this.blacklist.includes(this.channels[nextIndex])) { this.index = nextIndex; diff --git a/tgui/packages/tgui-say/TguiSay.tsx b/tgui/packages/tgui-say/TguiSay.tsx index ffa9c74355..82de822937 100644 --- a/tgui/packages/tgui-say/TguiSay.tsx +++ b/tgui/packages/tgui-say/TguiSay.tsx @@ -1,12 +1,18 @@ import './styles/main.scss'; -import { FormEvent, KeyboardEvent, useEffect, useRef, useState } from 'react'; +import { + type FormEvent, + type KeyboardEvent, + useEffect, + useRef, + useState, +} from 'react'; import { dragStartHandler } from 'tgui/drag'; import { isEscape, KEY } from 'tgui-core/keys'; import { clamp } from 'tgui-core/math'; import { type BooleanLike, classes } from 'tgui-core/react'; -import { Channel, ChannelIterator } from './ChannelIterator'; +import { type Channel, ChannelIterator } from './ChannelIterator'; import { ChatHistory } from './ChatHistory'; import { LineLength, RADIO_PREFIXES, WindowSize } from './constants'; import { @@ -181,7 +187,7 @@ export function TguiSay() { const iterator = channelIterator.current; let newValue = event.currentTarget.value; - let newPrefix = getPrefix(newValue) || currentPrefix; + const newPrefix = getPrefix(newValue) || currentPrefix; // Handles switching prefixes if (newPrefix && newPrefix !== currentPrefix) { setButtonContent(RADIO_PREFIXES[newPrefix]); diff --git a/tgui/packages/tgui-say/helpers.ts b/tgui/packages/tgui-say/helpers.ts index 6fad854f05..b7440cdff9 100644 --- a/tgui/packages/tgui-say/helpers.ts +++ b/tgui/packages/tgui-say/helpers.ts @@ -1,4 +1,4 @@ -import { Channel } from './ChannelIterator'; +import type { Channel } from './ChannelIterator'; import { RADIO_PREFIXES, WindowSize } from './constants'; /** @@ -29,7 +29,7 @@ export function windowSet( width = WindowSize.Width, size = WindowSize.Small, ): void { - let sizeStr = `${width}x${size}`; + const sizeStr = `${width}x${size}`; Byond.winset('tgui_say.browser', { size: sizeStr, @@ -58,7 +58,7 @@ export function getPrefix( return; } - let adjusted = value + const adjusted = value .slice(0, 3) ?.toLowerCase() ?.replace('.', ':') as keyof typeof RADIO_PREFIXES; diff --git a/tgui/packages/tgui-say/index.tsx b/tgui/packages/tgui-say/index.tsx index 9757cca4ff..2645185767 100644 --- a/tgui/packages/tgui-say/index.tsx +++ b/tgui/packages/tgui-say/index.tsx @@ -1,6 +1,6 @@ import './styles/main.scss'; -import { createRoot, Root } from 'react-dom/client'; +import { createRoot, type Root } from 'react-dom/client'; import { TguiSay } from './TguiSay'; diff --git a/tgui/packages/tgui-say/timers.ts b/tgui/packages/tgui-say/timers.ts index ef279a3df8..8466718dd0 100644 --- a/tgui/packages/tgui-say/timers.ts +++ b/tgui/packages/tgui-say/timers.ts @@ -1,6 +1,6 @@ import { debounce, throttle } from 'tgui-core/timer'; -import { Channel } from './ChannelIterator'; +import type { Channel } from './ChannelIterator'; const SECONDS = 1000; diff --git a/tgui/packages/tgui/backend.ts b/tgui/packages/tgui/backend.ts index 87e45c4851..f6773d281a 100644 --- a/tgui/packages/tgui/backend.ts +++ b/tgui/packages/tgui/backend.ts @@ -66,7 +66,7 @@ export const backendReducer = (state = initialState, action) => { // Merge shared states const shared = { ...state.shared }; if (payload.shared) { - for (let key of Object.keys(payload.shared)) { + for (const key of Object.keys(payload.shared)) { const value = payload.shared[key]; if (value === '') { shared[key] = undefined; diff --git a/tgui/packages/tgui/components/Interactive.tsx b/tgui/packages/tgui/components/Interactive.tsx index 61e4d1b4c1..f892471747 100644 --- a/tgui/packages/tgui/components/Interactive.tsx +++ b/tgui/packages/tgui/components/Interactive.tsx @@ -12,7 +12,12 @@ * SOFTWARE. */ -import React, { Component, createRef, ReactNode, RefObject } from 'react'; +import React, { + Component, + createRef, + type ReactNode, + type RefObject, +} from 'react'; import { isArrow, KEY } from 'tgui-core/keys'; import { clamp } from 'tgui-core/math'; diff --git a/tgui/packages/tgui/components/NanoMap.tsx b/tgui/packages/tgui/components/NanoMap.tsx index 8ccfff7ae8..07f0e344aa 100644 --- a/tgui/packages/tgui/components/NanoMap.tsx +++ b/tgui/packages/tgui/components/NanoMap.tsx @@ -1,4 +1,4 @@ -import React, { Component, PropsWithChildren } from 'react'; +import React, { Component, type PropsWithChildren } from 'react'; import { resolveAsset } from 'tgui/assets'; import { useBackend } from 'tgui/backend'; import { KeyListener } from 'tgui-core/components'; @@ -10,7 +10,7 @@ import { Slider, Tooltip, } from 'tgui-core/components'; -import { KeyEvent } from 'tgui-core/events'; +import type { KeyEvent } from 'tgui-core/events'; import { KEY } from 'tgui-core/keys'; import { logger } from '../logging'; @@ -64,12 +64,12 @@ export class NanoMap extends Component { setZoom(zoom: number) { const newZoom = Math.min(Math.max(zoom, 1), 8); this.setState((state) => { - let zoomDifference = -(state.zoom - newZoom); + const zoomDifference = -(state.zoom - newZoom); - let newOffsetX = + const newOffsetX = state.offsetX - (this.props.zoomScale / 2) * zoomDifference; - let newOffsetY = + const newOffsetY = state.offsetY - (this.props.zoomScale / 2) * zoomDifference; return { diff --git a/tgui/packages/tgui/drag.ts b/tgui/packages/tgui/drag.ts index 9a27b5f994..5806433fca 100644 --- a/tgui/packages/tgui/drag.ts +++ b/tgui/packages/tgui/drag.ts @@ -166,7 +166,7 @@ export const recallWindowGeometry = async ( // Setup draggable window export const setupDrag = async () => { // Calculate screen offset caused by the windows taskbar - let windowPosition = getWindowPosition(); + const windowPosition = getWindowPosition(); screenOffsetPromise = Byond.winget(Byond.windowId, 'pos').then((pos) => [ pos.x - windowPosition[0], diff --git a/tgui/packages/tgui/index.tsx b/tgui/packages/tgui/index.tsx index fa62d92f7b..26e7d68868 100644 --- a/tgui/packages/tgui/index.tsx +++ b/tgui/packages/tgui/index.tsx @@ -18,6 +18,7 @@ import './styles/themes/retro.scss'; import './styles/themes/syndicate.scss'; import './styles/themes/wizard.scss'; import './styles/themes/abstract.scss'; +import './styles/themes/bingle.scss'; import { perf } from 'common/perf'; import { setupGlobalEvents } from 'tgui-core/events'; diff --git a/tgui/packages/tgui/interfaces/AdminShuttleController.tsx b/tgui/packages/tgui/interfaces/AdminShuttleController.tsx index c4f890011b..c7199641ad 100644 --- a/tgui/packages/tgui/interfaces/AdminShuttleController.tsx +++ b/tgui/packages/tgui/interfaces/AdminShuttleController.tsx @@ -37,8 +37,8 @@ export const ShuttleList = (props) => { shuttles.sort((a, b) => a.name.localeCompare(b.name)); overmap_ships.sort((a, b) => { - let a_cmp = a.name?.toLowerCase() || a.name || a.ref; - let b_cmp = a.name?.toLowerCase() || a.name || a.ref; + const a_cmp = a.name?.toLowerCase() || a.name || a.ref; + const b_cmp = a.name?.toLowerCase() || a.name || a.ref; return a_cmp.localeCompare(b_cmp); }); diff --git a/tgui/packages/tgui/interfaces/AppearanceChanger/types.ts b/tgui/packages/tgui/interfaces/AppearanceChanger/types.ts index 1b272e6646..70a536d51a 100644 --- a/tgui/packages/tgui/interfaces/AppearanceChanger/types.ts +++ b/tgui/packages/tgui/interfaces/AppearanceChanger/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { name: string; diff --git a/tgui/packages/tgui/interfaces/Autolathe.tsx b/tgui/packages/tgui/interfaces/Autolathe.tsx index 7973f35484..769897c6ed 100644 --- a/tgui/packages/tgui/interfaces/Autolathe.tsx +++ b/tgui/packages/tgui/interfaces/Autolathe.tsx @@ -71,7 +71,7 @@ const Designs = (props) => { const [searchText, setSearchText] = useSharedState('search_text', ''); const materials = useMemo(() => { - let materials = {}; + const materials = {}; for (const material of data.materials) { materials[material.name] = material.amount; } @@ -159,7 +159,7 @@ const canBeMade = ( available: Record, multiplier: number = 1, ): boolean => { - for (let [id, amt] of Object.entries(required)) { + for (const [id, amt] of Object.entries(required)) { if ((available[id] || 0) < amt * multiplier) { return false; } diff --git a/tgui/packages/tgui/interfaces/AutomatedTellerMachine.tsx b/tgui/packages/tgui/interfaces/AutomatedTellerMachine.tsx index ef1b517299..98897776f7 100644 --- a/tgui/packages/tgui/interfaces/AutomatedTellerMachine.tsx +++ b/tgui/packages/tgui/interfaces/AutomatedTellerMachine.tsx @@ -281,7 +281,7 @@ const CustomWithdrawal = (props: { value={money} maxLength={10} onInput={(e, val) => { - let value = parseInt(val, 10); + const value = parseInt(val, 10); if (isNaN(value)) { setMoney(0); } else { @@ -289,7 +289,7 @@ const CustomWithdrawal = (props: { } }} onChange={(e, val) => { - let value = parseInt(val, 10); + const value = parseInt(val, 10); if (isNaN(value)) { setMoney(0); } else { @@ -437,7 +437,7 @@ const TransferMenu = (props: { const { act, data } = useBackend(); const [accountNum, setAccountNum] = useState(100000); const updateAccountNum = (val) => { - let newVal = parseInt(val, 10); + const newVal = parseInt(val, 10); if (isNaN(newVal)) { setAccountNum(100000); } else { @@ -447,7 +447,7 @@ const TransferMenu = (props: { const [money, setMoney] = useState(0); const updateMoney = (val) => { - let newVal = parseInt(val, 10); + const newVal = parseInt(val, 10); if (isNaN(newVal)) { setMoney(0); } else { diff --git a/tgui/packages/tgui/interfaces/Biogenerator.tsx b/tgui/packages/tgui/interfaces/Biogenerator.tsx index 423d12b536..b292ac3fee 100644 --- a/tgui/packages/tgui/interfaces/Biogenerator.tsx +++ b/tgui/packages/tgui/interfaces/Biogenerator.tsx @@ -114,7 +114,7 @@ const BiogeneratorItems = (props: { ); let has_contents = false; - let contents = Object.entries(items).map((kv) => { + const contents = Object.entries(items).map((kv) => { let items_in_cat = Object.entries(kv[1]) .filter(searcher) .map((kv2) => { diff --git a/tgui/packages/tgui/interfaces/BodyScanner/constants.ts b/tgui/packages/tgui/interfaces/BodyScanner/constants.ts index 3d156c5ad5..82291c3a9e 100644 --- a/tgui/packages/tgui/interfaces/BodyScanner/constants.ts +++ b/tgui/packages/tgui/interfaces/BodyScanner/constants.ts @@ -1,4 +1,4 @@ -import { occupant } from './types'; +import type { occupant } from './types'; export const stats: string[][] = [ ['good', 'Alive'], diff --git a/tgui/packages/tgui/interfaces/BodyScanner/functions.tsx b/tgui/packages/tgui/interfaces/BodyScanner/functions.tsx index e8343bf923..8b48558d07 100644 --- a/tgui/packages/tgui/interfaces/BodyScanner/functions.tsx +++ b/tgui/packages/tgui/interfaces/BodyScanner/functions.tsx @@ -4,7 +4,7 @@ import type { BooleanLike } from 'tgui-core/react'; /* */ export function mapTwoByTwo(a: any[][], c: any) { - let result: any[] = []; + const result: any[] = []; for (let i = 0; i < a.length; i += 2) { result.push(c(a[i], a[i + 1], i)); } diff --git a/tgui/packages/tgui/interfaces/BodyScanner/types.ts b/tgui/packages/tgui/interfaces/BodyScanner/types.ts index 1e5dc73045..f24117d1d8 100644 --- a/tgui/packages/tgui/interfaces/BodyScanner/types.ts +++ b/tgui/packages/tgui/interfaces/BodyScanner/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { occupied: BooleanLike; diff --git a/tgui/packages/tgui/interfaces/BombTester.tsx b/tgui/packages/tgui/interfaces/BombTester.tsx index 53a3233896..0adc6f7aa9 100644 --- a/tgui/packages/tgui/interfaces/BombTester.tsx +++ b/tgui/packages/tgui/interfaces/BombTester.tsx @@ -156,8 +156,8 @@ class BombTesterSimulation extends Component { const BOUND_Y: number = 205; const MOVEMENT_SPEED: number = 2; - let startRight: boolean = Math.random() > 0.5; - let startBottom: boolean = Math.random() > 0.5; + const startRight: boolean = Math.random() > 0.5; + const startBottom: boolean = Math.random() > 0.5; this.state = { x: startRight ? BOUND_X : 0, diff --git a/tgui/packages/tgui/interfaces/Canvas.tsx b/tgui/packages/tgui/interfaces/Canvas.tsx index a8ccd2ff3f..300e3ae7db 100644 --- a/tgui/packages/tgui/interfaces/Canvas.tsx +++ b/tgui/packages/tgui/interfaces/Canvas.tsx @@ -1,4 +1,4 @@ -import { Component, createRef, RefObject, useState } from 'react'; +import { Component, createRef, type RefObject, useState } from 'react'; import { useBackend } from 'tgui/backend'; import { Window } from 'tgui/layouts'; import { Box, Button, Stack } from 'tgui-core/components'; @@ -50,13 +50,13 @@ class PaintCanvas extends Component { y0 = y0 - 1; y1 = y1 - 1; - let dx = Math.abs(x1 - x0); - let sx = x0 < x1 ? 1 : -1; - let dy = -Math.abs(y1 - y0); - let sy = y0 < y1 ? 1 : -1; + const dx = Math.abs(x1 - x0); + const sx = x0 < x1 ? 1 : -1; + const dy = -Math.abs(y1 - y0); + const sy = y0 < y1 ? 1 : -1; let error = dx + dy; - let pixels: [number, number][] = []; + const pixels: [number, number][] = []; while (true) { pixels.push([x0, y0]); @@ -66,7 +66,7 @@ class PaintCanvas extends Component { break; } - let e2 = error * 2; + const e2 = error * 2; if (e2 >= dy) { error = error + dy; x0 = x0 + sx; @@ -81,12 +81,12 @@ class PaintCanvas extends Component { } drawLine(grid: string[][]) { - let pixels = this.getLinePixels(); + const pixels = this.getLinePixels(); if (!pixels) { return; } - for (let [x, y] of pixels) { + for (const [x, y] of pixels) { if (x < grid.length && y < grid[0].length) { grid[x][y] = '#000000'; } @@ -110,15 +110,15 @@ class PaintCanvas extends Component { return grid[x_c][y_c] === origPixelColor; }; - let s: [number, number, number, number][] = []; + const s: [number, number, number, number][] = []; s.push([x_start, x_start, y_start, 1]); s.push([x_start, x_start, y_start - 1, -1]); - let pixels_touched: [number, number][] = []; + const pixels_touched: [number, number][] = []; while (s.length) { // This can't fail because of our while condition - let [x1, x2, y, dy] = s.pop()!; + const [x1, x2, y, dy] = s.pop()!; let x = x1; if (inside(x, y)) { @@ -132,23 +132,24 @@ class PaintCanvas extends Component { } } - while (x1 <= x2) { - while (inside(x1, y)) { - grid[x1][y] = '#000000'; - pixels_touched.push([x1, y]); - x1 = x1 + 1; + let mutX = x1; + while (mutX <= x2) { + while (inside(mutX, y)) { + grid[mutX][y] = '#000000'; + pixels_touched.push([mutX, y]); + mutX = mutX + 1; } - if (x1 > x) { - s.push([x, x1 - 1, y + dy, dy]); + if (mutX > x) { + s.push([x, mutX - 1, y + dy, dy]); } - if (x1 - 1 > x2) { - s.push([x2 + 1, x1 - 1, y - dy, -dy]); + if (mutX - 1 > x2) { + s.push([x2 + 1, mutX - 1, y - dy, -dy]); } - x1 = x1 + 1; - while (x1 < x2 && !inside(x1, y)) { - x1 = x1 + 1; + mutX = mutX + 1; + while (mutX < x2 && !inside(mutX, y)) { + mutX = mutX + 1; } - x = x1; + x = mutX; } } @@ -214,7 +215,7 @@ class PaintCanvas extends Component { mouseDown(event: React.MouseEvent) { this.mouseIsDown = true; - let coord = this.getCoord(event); + const coord = this.getCoord(event); if (!coord) { return; } @@ -225,10 +226,10 @@ class PaintCanvas extends Component { if (this.props.tool === Tool.Paintbrush) { this.onCVClick(coord[0], coord[1]); } else if (this.props.tool === Tool.Fill) { - let gridCopy = JSON.parse(JSON.stringify(this.props.value)); - let pixels_touched = this.areaFill(gridCopy); + const gridCopy = JSON.parse(JSON.stringify(this.props.value)); + const pixels_touched = this.areaFill(gridCopy); if (pixels_touched) { - for (let [x, y] of pixels_touched) { + for (const [x, y] of pixels_touched) { this.onCVClick(x + 1, y + 1); } } @@ -238,7 +239,7 @@ class PaintCanvas extends Component { mouseUp(event: React.MouseEvent) { this.mouseIsDown = false; - let coord = this.getCoord(event); + const coord = this.getCoord(event); if (!coord) { return; } @@ -246,9 +247,9 @@ class PaintCanvas extends Component { this.lastHovered = coord; if (this.props.tool === Tool.Line) { - let line = this.getLinePixels(); + const line = this.getLinePixels(); if (line) { - for (let [x, y] of line) { + for (const [x, y] of line) { this.onCVClick(x + 1, y + 1); } } @@ -263,7 +264,7 @@ class PaintCanvas extends Component { this.lastHovered = coord; - let time = new Date().getTime(); + const time = new Date().getTime(); if (this.lastSuccessfulPaint + 50 > time) { return; diff --git a/tgui/packages/tgui/interfaces/CasinoPrizeDispenser.tsx b/tgui/packages/tgui/interfaces/CasinoPrizeDispenser.tsx index 86bed0b8f2..0461d55548 100644 --- a/tgui/packages/tgui/interfaces/CasinoPrizeDispenser.tsx +++ b/tgui/packages/tgui/interfaces/CasinoPrizeDispenser.tsx @@ -125,7 +125,7 @@ const CasinoPrizeDispenserItems = (props: { ); let has_contents = false; - let contents = Object.entries(items).map((kv) => { + const contents = Object.entries(items).map((kv) => { let items_in_cat = Object.entries(kv[1]) .filter(searcher) .map((kv2) => { diff --git a/tgui/packages/tgui/interfaces/CharacterDirectory.tsx b/tgui/packages/tgui/interfaces/CharacterDirectory.tsx index 09b566bf30..bf43d7c2d0 100644 --- a/tgui/packages/tgui/interfaces/CharacterDirectory.tsx +++ b/tgui/packages/tgui/interfaces/CharacterDirectory.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useState } from 'react'; +import { type ReactNode, useState } from 'react'; import { useBackend } from 'tgui/backend'; import { Window } from 'tgui/layouts'; import { diff --git a/tgui/packages/tgui/interfaces/ChemAnalyzerPro.tsx b/tgui/packages/tgui/interfaces/ChemAnalyzerPro.tsx new file mode 100644 index 0000000000..09b5d2028f --- /dev/null +++ b/tgui/packages/tgui/interfaces/ChemAnalyzerPro.tsx @@ -0,0 +1,160 @@ +import { type Dispatch, type SetStateAction, useState } from 'react'; +import { useBackend } from 'tgui/backend'; +import { Window } from 'tgui/layouts'; +import { + Button, + Divider, + Input, + ProgressBar, + Section, + Stack, +} from 'tgui-core/components'; +import { capitalize, createSearch } from 'tgui-core/string'; + +import type { ReagentData } from './PublicLibraryWiki/types'; +import { WikiChemistryPage } from './PublicLibraryWiki/WikiPages/WikiSubPages/WikiChemistryPage'; + +type AnalyzerData = ReagentData & { beakerAmount: number }; + +type Data = { + scannedReagents: AnalyzerData[]; + beakerTotal: number; + beakerMax: number; +}; + +export const ChemAnalyzerPro = () => { + const { data } = useBackend(); + const { scannedReagents, beakerTotal, beakerMax } = data; + + const [selectedReagent, setSelectedReagent] = useState( + null, + ); + const [searchText, setSearchText] = useState(''); + + const customSearch = createSearch( + searchText, + (search: AnalyzerData) => search.title, + ); + const toDisplay = scannedReagents.filter(customSearch); + + return ( + + +
+ + + + {selectedReagent && ( + + )} + + +
+
+
+ ); +}; + +export const AnalyzerSearchList = (props: { + title: string; + searchText: string; + onSearchText: Dispatch>; + listEntries: AnalyzerData[]; + basis: string; + activeEntry: AnalyzerData | null; + onActiveEntry: Dispatch>; + total: number; +}) => { + const { + title, + searchText, + onSearchText, + onActiveEntry, + listEntries, + activeEntry, + basis, + total, + } = props; + + return ( + +
+ + + onSearchText(value)} + /> + + + +
+ + {listEntries + .sort((a, b) => b.beakerAmount - a.beakerAmount) + .map((entry) => ( + + + + + + ))} + +
+
+
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/ChemDispenser/types.ts b/tgui/packages/tgui/interfaces/ChemDispenser/types.ts index fe250fbf7e..09eb0c2daa 100644 --- a/tgui/packages/tgui/interfaces/ChemDispenser/types.ts +++ b/tgui/packages/tgui/interfaces/ChemDispenser/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Recipe = { id: string; diff --git a/tgui/packages/tgui/interfaces/ChemMaster/ChemMasterBeaker.tsx b/tgui/packages/tgui/interfaces/ChemMaster/ChemMasterBeaker.tsx index c9c7c12b10..55498ab7aa 100644 --- a/tgui/packages/tgui/interfaces/ChemMaster/ChemMasterBeaker.tsx +++ b/tgui/packages/tgui/interfaces/ChemMaster/ChemMasterBeaker.tsx @@ -15,7 +15,7 @@ export const ChemMasterBeaker = (props: { const { act } = useBackend(); const { beaker, beakerReagents, bufferNonEmpty } = props; - let headerButton = bufferNonEmpty ? ( + const headerButton = bufferNonEmpty ? ( { ); } - let messageRows = messages.map((m) => { + const messageRows = messages.map((m) => { return ( )); - let finalArray: React.JSX.Element[] = []; + const finalArray: React.JSX.Element[] = []; for (let i = 0; i < buttonArray.length; i += 4) { finalArray.push( diff --git a/tgui/packages/tgui/interfaces/Communicator/types.ts b/tgui/packages/tgui/interfaces/Communicator/types.ts index eee771e941..b62d2126c0 100644 --- a/tgui/packages/tgui/interfaces/Communicator/types.ts +++ b/tgui/packages/tgui/interfaces/Communicator/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { // GENERAL diff --git a/tgui/packages/tgui/interfaces/ComputerFabricator/types.ts b/tgui/packages/tgui/interfaces/ComputerFabricator/types.ts index a31b0e0846..f93d32147c 100644 --- a/tgui/packages/tgui/interfaces/ComputerFabricator/types.ts +++ b/tgui/packages/tgui/interfaces/ComputerFabricator/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { state: number; diff --git a/tgui/packages/tgui/interfaces/CrewManifest.tsx b/tgui/packages/tgui/interfaces/CrewManifest.tsx index 456ab4544c..408c862c82 100644 --- a/tgui/packages/tgui/interfaces/CrewManifest.tsx +++ b/tgui/packages/tgui/interfaces/CrewManifest.tsx @@ -43,7 +43,7 @@ export const CrewManifestContent = (props) => { return No Manifest Data; } - let crew_count = manifest + const crew_count = manifest .map((val) => val.elems.length) .reduce((a, c) => a + c, 0); if (!crew_count) { diff --git a/tgui/packages/tgui/interfaces/CrewMonitor/functions.ts b/tgui/packages/tgui/interfaces/CrewMonitor/functions.ts index 5d051ba898..842a54fc62 100644 --- a/tgui/packages/tgui/interfaces/CrewMonitor/functions.ts +++ b/tgui/packages/tgui/interfaces/CrewMonitor/functions.ts @@ -1,6 +1,6 @@ import { flow } from 'tgui-core/fp'; -import { crewmember } from './types'; +import type { crewmember } from './types'; export function getStatText(cm: crewmember) { if (cm.dead) { diff --git a/tgui/packages/tgui/interfaces/CrewMonitor/types.ts b/tgui/packages/tgui/interfaces/CrewMonitor/types.ts index 79449b42a2..d5a3b281ab 100644 --- a/tgui/packages/tgui/interfaces/CrewMonitor/types.ts +++ b/tgui/packages/tgui/interfaces/CrewMonitor/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { zoomScale: number; diff --git a/tgui/packages/tgui/interfaces/Cryo/types.ts b/tgui/packages/tgui/interfaces/Cryo/types.ts index 52b7fdbb67..e596e7f35a 100644 --- a/tgui/packages/tgui/interfaces/Cryo/types.ts +++ b/tgui/packages/tgui/interfaces/Cryo/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { isOperating: BooleanLike; diff --git a/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierBlocks.tsx b/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierBlocks.tsx index 652dce4b45..1cd1909461 100644 --- a/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierBlocks.tsx +++ b/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierBlocks.tsx @@ -14,10 +14,10 @@ export const DNAModifierBlocks = (props: { props; const characters: string[] = dnaString.split(''); - let dnaBlocks: React.JSX.Element[] = []; + const dnaBlocks: React.JSX.Element[] = []; for (let block = 0; block < characters.length; block += blockSize) { const realBlock: number = block / blockSize + 1; - let subBlocks: React.JSX.Element[] = []; + const subBlocks: React.JSX.Element[] = []; for (let subblock = 0; subblock < blockSize; subblock++) { const realSubblock: number = subblock + 1; subBlocks.push( diff --git a/tgui/packages/tgui/interfaces/EmbeddedController/types.ts b/tgui/packages/tgui/interfaces/EmbeddedController/types.ts index 28329acef9..cf1c573dff 100644 --- a/tgui/packages/tgui/interfaces/EmbeddedController/types.ts +++ b/tgui/packages/tgui/interfaces/EmbeddedController/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { internalTemplateName: string }; diff --git a/tgui/packages/tgui/interfaces/ExosuitFabricator/Material.tsx b/tgui/packages/tgui/interfaces/ExosuitFabricator/Material.tsx index 669afeb408..c52833ab81 100644 --- a/tgui/packages/tgui/interfaces/ExosuitFabricator/Material.tsx +++ b/tgui/packages/tgui/interfaces/ExosuitFabricator/Material.tsx @@ -71,7 +71,7 @@ export const Materials = (props: { const { materials = [] } = data; - let display_materials = materials.filter( + const display_materials = materials.filter( (mat) => displayAllMat || mat.amount > 0, ); diff --git a/tgui/packages/tgui/interfaces/ExosuitFabricator/Parts.tsx b/tgui/packages/tgui/interfaces/ExosuitFabricator/Parts.tsx index ee33395cf4..0498334205 100644 --- a/tgui/packages/tgui/interfaces/ExosuitFabricator/Parts.tsx +++ b/tgui/packages/tgui/interfaces/ExosuitFabricator/Parts.tsx @@ -76,7 +76,7 @@ export const PartLists = (props: { let partsObj: { Parts: internalPart[] } = { Parts: [], }; - let partsList: internalPart[] = []; + const partsList: internalPart[] = []; // Build list of sub-categories if not using a search filter. if (!searchText) { partsObj = { Parts: [] }; diff --git a/tgui/packages/tgui/interfaces/ExosuitFabricator/functions.ts b/tgui/packages/tgui/interfaces/ExosuitFabricator/functions.ts index 3c9982073e..57079d678f 100644 --- a/tgui/packages/tgui/interfaces/ExosuitFabricator/functions.ts +++ b/tgui/packages/tgui/interfaces/ExosuitFabricator/functions.ts @@ -2,12 +2,12 @@ import { uniqBy } from 'common/collections'; import { createSearch } from 'tgui-core/string'; import { COLOR_AVERAGE, COLOR_BAD, COLOR_NONE } from './constants'; -import { material, part, queueFormat } from './types'; +import type { material, part, queueFormat } from './types'; export function materialArrayToObj( materials: material[], ): Record { - let materialObj = {}; + const materialObj = {}; materials.forEach((m) => { materialObj[m.name] = m.amount; @@ -41,7 +41,7 @@ export function partCondFormat( tally: Record, part: part, ) { - let format = { textColor: COLOR_NONE }; + const format = { textColor: COLOR_NONE }; Object.keys(part.cost).forEach((mat) => { format[mat] = partBuildColor(part.cost[mat], tally[mat], materials[mat]); @@ -58,10 +58,10 @@ export function queueCondFormat( materials: material | {}, queue: part[] | null, ): queueFormat { - let materialTally = {}; - let matFormat = {}; - let missingMatTally = {}; - let textColors = {}; + const materialTally = {}; + const matFormat = {}; + const missingMatTally = {}; + const textColors = {}; queue && queue.forEach((part, i) => { @@ -121,7 +121,7 @@ export function getFirstValidPartSet( sets: string[], buildableParts: Record | [], ): string | null { - for (let set of sets) { + for (const set of sets) { if (buildableParts[set]) { return set; } diff --git a/tgui/packages/tgui/interfaces/ExosuitFabricator/types.ts b/tgui/packages/tgui/interfaces/ExosuitFabricator/types.ts index e6e98027a9..6a5aecb5a7 100644 --- a/tgui/packages/tgui/interfaces/ExosuitFabricator/types.ts +++ b/tgui/packages/tgui/interfaces/ExosuitFabricator/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { partSets: string[]; diff --git a/tgui/packages/tgui/interfaces/FishingMinigame.tsx b/tgui/packages/tgui/interfaces/FishingMinigame.tsx index ab8427a021..a2aa757962 100644 --- a/tgui/packages/tgui/interfaces/FishingMinigame.tsx +++ b/tgui/packages/tgui/interfaces/FishingMinigame.tsx @@ -1,8 +1,8 @@ import { Component, - ComponentProps, - PropsWithChildren, - ReactNode, + type ComponentProps, + type PropsWithChildren, + type ReactNode, useEffect, useState, } from 'react'; diff --git a/tgui/packages/tgui/interfaces/GeneralAtmoControl/Sensors.tsx b/tgui/packages/tgui/interfaces/GeneralAtmoControl/Sensors.tsx index 211dced03a..d34a9aecfd 100644 --- a/tgui/packages/tgui/interfaces/GeneralAtmoControl/Sensors.tsx +++ b/tgui/packages/tgui/interfaces/GeneralAtmoControl/Sensors.tsx @@ -34,7 +34,7 @@ const AtmoSensor = (props: { sensor: sensor }) => { const { pressure, temperature, oxygen, nitrogen, carbon_dioxide, phoron } = sensor.sensor_data; - let labeledListContents: React.JSX.Element[] = []; + const labeledListContents: React.JSX.Element[] = []; if (pressure) { labeledListContents.push( {pressure} kPa, diff --git a/tgui/packages/tgui/interfaces/GeneralAtmoControl/types.ts b/tgui/packages/tgui/interfaces/GeneralAtmoControl/types.ts index 449edd67e7..063552187b 100644 --- a/tgui/packages/tgui/interfaces/GeneralAtmoControl/types.ts +++ b/tgui/packages/tgui/interfaces/GeneralAtmoControl/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { sensors: sensor[]; diff --git a/tgui/packages/tgui/interfaces/GeneralRecords/functions.ts b/tgui/packages/tgui/interfaces/GeneralRecords/functions.ts index 1ae7673aea..81485e7296 100644 --- a/tgui/packages/tgui/interfaces/GeneralRecords/functions.ts +++ b/tgui/packages/tgui/interfaces/GeneralRecords/functions.ts @@ -2,7 +2,7 @@ import { flow } from 'tgui-core/fp'; import { createSearch } from 'tgui-core/string'; import { modalOpen } from '../common/ComplexModal'; -import { field, record } from './types'; +import type { field, record } from './types'; export function doEdit(field: field) { modalOpen('edit', { diff --git a/tgui/packages/tgui/interfaces/GeneralRecords/types.ts b/tgui/packages/tgui/interfaces/GeneralRecords/types.ts index 0a12865129..4579817a19 100644 --- a/tgui/packages/tgui/interfaces/GeneralRecords/types.ts +++ b/tgui/packages/tgui/interfaces/GeneralRecords/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { temp: { color: string; text: string } | null; diff --git a/tgui/packages/tgui/interfaces/ICAssembly/CircuitComponent.tsx b/tgui/packages/tgui/interfaces/ICAssembly/CircuitComponent.tsx index caf646c065..0f2506bdf0 100644 --- a/tgui/packages/tgui/interfaces/ICAssembly/CircuitComponent.tsx +++ b/tgui/packages/tgui/interfaces/ICAssembly/CircuitComponent.tsx @@ -1,10 +1,10 @@ -import { Component, ComponentProps } from 'react'; +import { Component, type ComponentProps } from 'react'; import { useBackend } from 'tgui/backend'; import { Box, Button, Icon, Stack } from 'tgui-core/components'; import { shallowDiffers } from 'tgui-core/react'; import { decodeHtmlEntities } from 'tgui-core/string'; -import { Port, PortProps } from './Port'; +import { Port, type PortProps } from './Port'; import { type CircuitData, PortTypesToColor as PORT_TYPES_TO_COLOR, @@ -102,8 +102,8 @@ export class CircuitComponent extends Component { e.preventDefault(); const { screenZoomX, screenZoomY, screenX, screenY } = e; - let xPos = screenZoomX || screenX; - let yPos = screenZoomY || screenY; + const xPos = screenZoomX || screenX; + const yPos = screenZoomY || screenY; if (lastMousePos) { this.setState({ diff --git a/tgui/packages/tgui/interfaces/ICAssembly/Plane.tsx b/tgui/packages/tgui/interfaces/ICAssembly/Plane.tsx index ce99586312..7dd0e9f158 100644 --- a/tgui/packages/tgui/interfaces/ICAssembly/Plane.tsx +++ b/tgui/packages/tgui/interfaces/ICAssembly/Plane.tsx @@ -5,15 +5,15 @@ import { useBackend, useSharedState } from 'tgui/backend'; import { InfinitePlane } from 'tgui-core/components'; import { decodeHtmlEntities } from 'tgui-core/string'; -import { Connection, Connections } from '../common/Connections'; +import { type Connection, Connections } from '../common/Connections'; import { CircuitComponent } from './CircuitComponent'; -import { PortProps } from './Port'; +import type { PortProps } from './Port'; import { ABSOLUTE_Y_OFFSET, - CircuitData, - Data, + type CircuitData, + type Data, MOUSE_BUTTON_LEFT, - PortData, + type PortData, PortTypesToColor, } from './types'; diff --git a/tgui/packages/tgui/interfaces/IdentificationComputer.tsx b/tgui/packages/tgui/interfaces/IdentificationComputer.tsx index 7f35940216..b20a12f5df 100644 --- a/tgui/packages/tgui/interfaces/IdentificationComputer.tsx +++ b/tgui/packages/tgui/interfaces/IdentificationComputer.tsx @@ -278,7 +278,7 @@ export const IdentificationComputerRegions = (props: { actName: string }) => { if (regions) { regions.sort((a, b) => a.name.localeCompare(b.name)); - for (let region of regions) { + for (const region of regions) { region.accesses.sort((a, b) => a.desc.localeCompare(b.desc)); } } diff --git a/tgui/packages/tgui/interfaces/JanitorCart.tsx b/tgui/packages/tgui/interfaces/JanitorCart.tsx index 0c59e79c95..6c45903c11 100644 --- a/tgui/packages/tgui/interfaces/JanitorCart.tsx +++ b/tgui/packages/tgui/interfaces/JanitorCart.tsx @@ -1,6 +1,6 @@ import { useBackend } from 'tgui/backend'; import { Window } from 'tgui/layouts'; -import { Button, Icon, Image } from 'tgui-core/components'; +import { Button, Icon, Image, Stack } from 'tgui-core/components'; type Data = { mybag: string | null; @@ -18,92 +18,110 @@ export const JanitorCart = (props) => { const { mybag, mybucket, mymop, myspray, myreplacer, signs } = data; return ( - + - - - - - - + + + + + + + + + + + + + + + + + + + + ); @@ -128,7 +146,7 @@ const JanicartIcon = (props: { iconkey: string }) => { if (iconkey in icons) { return ( { admin, } = data; - let genre_songs = + const genre_songs = tracks.length && tracks.reduce((acc, obj) => { - let key = obj.genre || 'Uncategorized'; + const key = obj.genre || 'Uncategorized'; if (!acc[key]) { acc[key] = []; } @@ -65,7 +65,7 @@ export const Jukebox = (props) => { return acc; }, {}); - let true_genre = playing && (current_genre || 'Uncategorized'); + const true_genre = playing && (current_genre || 'Uncategorized'); const [newTitle, setNewTitle] = useState('Unknown'); const [newUrl, setNewUrl] = useState(''); diff --git a/tgui/packages/tgui/interfaces/LateChoices.tsx b/tgui/packages/tgui/interfaces/LateChoices.tsx index 154399c93e..10a4ba8e73 100644 --- a/tgui/packages/tgui/interfaces/LateChoices.tsx +++ b/tgui/packages/tgui/interfaces/LateChoices.tsx @@ -42,14 +42,14 @@ type Data = { const splitJobs = ( jobs: Job[], ): { favorites: Job[]; departments: { [key: string]: Job[] } } => { - let favorites: Job[] = []; - let departments: { [key: string]: Job[] } = {}; + const favorites: Job[] = []; + const departments: { [key: string]: Job[] } = {}; - for (let job of jobs) { + for (const job of jobs) { if (job.priority !== 0) { favorites.push(job); } else { - for (let department of job.departments) { + for (const department of job.departments) { if (department in departments) { departments[department].push(job); } else { diff --git a/tgui/packages/tgui/interfaces/LookingGlass.tsx b/tgui/packages/tgui/interfaces/LookingGlass.tsx index 5992c49929..6c0d284e6b 100644 --- a/tgui/packages/tgui/interfaces/LookingGlass.tsx +++ b/tgui/packages/tgui/interfaces/LookingGlass.tsx @@ -15,7 +15,7 @@ export const LookingGlass = (props) => { const { supportedPrograms, currentProgram, immersion, gravity } = data; - let height = Math.min(180 + supportedPrograms.length * 23, 600); + const height = Math.min(180 + supportedPrograms.length * 23, 600); return ( diff --git a/tgui/packages/tgui/interfaces/MaterialStack.tsx b/tgui/packages/tgui/interfaces/MaterialStack.tsx index 4b78a60567..47fdbc288e 100644 --- a/tgui/packages/tgui/interfaces/MaterialStack.tsx +++ b/tgui/packages/tgui/interfaces/MaterialStack.tsx @@ -81,7 +81,7 @@ const RecipeList = (props: { //
// ); // } - let recipe = recipes[title]; + const recipe = recipes[title]; if (recipe.ref === undefined) { return ( @@ -109,7 +109,7 @@ const Multipliers = (props) => { const { recipe, maxMultiplier } = props; - let maxM = Math.min( + const maxM = Math.min( maxMultiplier, Math.floor(recipe.max_res_amount / recipe.res_amount), ); @@ -118,7 +118,7 @@ const Multipliers = (props) => { const finalResult: React.JSX.Element[] = []; - for (let multiplier of multipliers) { + for (const multiplier of multipliers) { if (maxM >= multiplier) { finalResult.push( + + ))} + + + + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WIkiDonationbanner.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WIkiDonationbanner.tsx new file mode 100644 index 0000000000..cbeb236f91 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WIkiDonationbanner.tsx @@ -0,0 +1,167 @@ +import type { Dispatch, SetStateAction } from 'react'; +import { useBackend } from 'tgui/backend'; +import { Box, Button, NoticeBox, Stack } from 'tgui-core/components'; +import type { BooleanLike } from 'tgui-core/react'; + +import { WikiAdColors, WikiDonIcons } from '../constants'; + +export function WikiDonationBanner(props: { + donated: number; + goal: number; + displayedMessage: string; + hasDonated: BooleanLike; + onDisplayedDonations: Dispatch>; +}) { + const { donated, goal, displayedMessage, hasDonated, onDisplayedDonations } = + props; + + const progress = donated / goal; + + if (hasDonated) { + return ( + + + + ); + } + + if (progress < 0.33) { + return ( + + + + ); + } + + if (progress < 0.66) { + return ( + + + + ); + } + + if (progress < 1) { + return ( + + + + ); + } + + return ( + + + + ); +} + +const WikiDonationContent = (props: { + donated: number; + goal: number; + message: string; + hideButtons?: boolean; + onDisplayedDonations: Dispatch>; +}) => { + const { donated, goal, message, onDisplayedDonations, hideButtons } = props; + + return ( + <> + + + + {message} + + + + {donated} / {goal}â‚® + + + {!hideButtons && donated < goal && ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} + + + ); +}; + +// Intentionally not state safe +const DonationButtons = (props) => { + const { act } = useBackend(); + + const donation = Math.round(Math.random() * 100 + 10); + + return ( + + ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiErrorPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiErrorPage.tsx new file mode 100644 index 0000000000..464cabb1b2 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiErrorPage.tsx @@ -0,0 +1,37 @@ +import { Box, Divider, Section, Stack } from 'tgui-core/components'; + +import { WikiLogo } from '../WikiCommon/WikiLogo'; + +export const WikiErrorPage = (props) => { + return ( +
+ + + + + + + + + This program has performed an illegal operation! + + + The cyber police have been notified of your illegal action! + + + Stand by for arrest! + + + + + + {'>:( This is your fault stupid. Why did you you do that? You caused a FAULT ID: #' + + Math.floor(Math.random() * 99999999) + .toString() + .padStart(8, '0')} + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiLoadingPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiLoadingPage.tsx new file mode 100644 index 0000000000..00c5730715 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiLoadingPage.tsx @@ -0,0 +1,60 @@ +import { useEffect, useState } from 'react'; +import { + Box, + Divider, + ProgressBar, + Section, + Stack, +} from 'tgui-core/components'; + +import { WikiLogo } from '../WikiCommon/WikiLogo'; + +export const WikiLoadingPage = (props: { endTime: number; tipp: string }) => { + const { endTime, tipp } = props; + + const [ourProgress, setOurProgress] = useState(0); + const [updateProgress, setUpdateProgress] = useState(false); + + useEffect(() => { + if (ourProgress < endTime - 100) { + setTimeout(() => { + setOurProgress(ourProgress + 100); + setUpdateProgress(!updateProgress); + }, 100); + } else { + setOurProgress(endTime); + } + }, [updateProgress]); + + return ( +
+ + + + + + + + + + + + Did you know? + + + + + {tipp} + + + + + + Have you bingled that? + + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiMainPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiMainPage.tsx new file mode 100644 index 0000000000..b763aa2ebc --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiMainPage.tsx @@ -0,0 +1,70 @@ +import { useBackend } from 'tgui/backend'; +import { + Box, + Button, + Divider, + Section, + Stack, + Tooltip, +} from 'tgui-core/components'; + +import { WikiPages } from '../constants'; + +export const WikiMainPage = (props: { + displayedAds: string[][]; + donationSuccess: boolean; +}) => { + const { act } = useBackend(); + + const { displayedAds, donationSuccess } = props; + + return ( +
+ + + + The galaxys 18th most tollerated + { + + * + + }{' '} + infocore dispenser! + + + + + + {WikiPages.sort((a, b) => a.localeCompare(b)).map((title) => ( + + + + ))} + {!donationSuccess && + displayedAds.map((ad, index) => ( + + + + ))} + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSearchPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSearchPage.tsx new file mode 100644 index 0000000000..d48914b5a6 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSearchPage.tsx @@ -0,0 +1,157 @@ +import { type Dispatch, type SetStateAction, useEffect, useState } from 'react'; +import { useBackend } from 'tgui/backend'; +import { Button, Divider, Section, Stack } from 'tgui-core/components'; +import { createSearch } from 'tgui-core/string'; + +import type { PageData } from '../types'; +import { WikiSearchList } from '../WikiCommon/WikiSearchList'; +import { WikiBotanyPage } from './WikiSubPages/WikiBotanyPage'; +import { WikiCatalogPage } from './WikiSubPages/WIkiCatalogPage'; +import { WikiChemistryPage } from './WikiSubPages/WikiChemistryPage'; +import { WikiFoodPage } from './WikiSubPages/WikiFoodPage'; +import { WikiMaterialPage } from './WikiSubPages/WikiMaterialPage'; +import { WikiNoDataPage } from './WikiSubPages/WikiNoDataPage'; +import { WikiOrePage } from './WikiSubPages/WikiOrePare'; +import { WikiParticlePage } from './WikiSubPages/WikiParticlePage'; + +export const WikiSearchPage = ( + props: { + onUpdateAds: Dispatch>; + updateAds: boolean; + searchmode: string; + search: string[]; + print: string; + subCats: string[] | null; + } & Required, +) => { + const { act } = useBackend(); + const [subCatSearchText, setSubCatSearchText] = useState(''); + const [subCatActiveEntry, setSubCatActiveEntry] = useState(''); + const [searchText, setSearchText] = useState(''); + const [activeEntry, setActiveEntry] = useState(''); + const [hideGroup, setHideGroup] = useState(false); + const [noData, setNoData] = useState(false); + const { + onUpdateAds, + updateAds, + searchmode, + botany_data, + ore_data, + food_data, + drink_data, + chemistry_data, + material_data, + particle_data, + catalog_data, + search, + print, + subCats, + } = props; + + // Intentionally bad for the effect + useEffect(() => { + setNoData(false); + if (!search.length) { + setTimeout(() => { + if (!search.length && subCatActiveEntry && !noData) { + setNoData(true); + } + }, 200); + } + }, [search || subCatActiveEntry]); + + const customSearch = createSearch(searchText, (search: string) => search); + const toDisplay = search.filter(customSearch); + + const customSubSearch = createSearch( + subCatSearchText, + (search: string) => search, + ); + const subToDisplay = subCats?.filter(customSubSearch); + + const tabs: React.JSX.Element[] = []; + tabs['Food Recipes'] = !!food_data && ; + tabs['Drink Recipes'] = !!drink_data && ; + tabs['Chemistry'] = !!chemistry_data && ( + + ); + tabs['Botany'] = !!botany_data && ; + tabs['Ores'] = !!ore_data && ; + tabs['Materials'] = !!material_data && ( + + ); + tabs['Particle Physics'] = !!particle_data && ( + + ); + tabs['Catalogs'] = !!catalog_data && ( + + ); + + return ( +
+ + {!!print && ( + + )} + + + {!!subToDisplay && + (hideGroup ? ( + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WIkiCatalogPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WIkiCatalogPage.tsx new file mode 100644 index 0000000000..fbe72b0cc6 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WIkiCatalogPage.tsx @@ -0,0 +1,19 @@ +import { Section, Stack } from 'tgui-core/components'; +import { capitalize } from 'tgui-core/string'; + +import type { CatalogData } from '../../types'; + +export const WikiCatalogPage = (props: { catalog: CatalogData }) => { + const { catalog } = props; + + return ( +
+ + + {/* eslint-disable-next-line react/no-danger */} +
+ + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiBotanyPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiBotanyPage.tsx new file mode 100644 index 0000000000..07fd80ab2b --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiBotanyPage.tsx @@ -0,0 +1,112 @@ +import { Box, LabeledList, Section, Stack } from 'tgui-core/components'; +import { capitalize } from 'tgui-core/string'; + +import type { BotanyData } from '../../types'; +import { ColorizedImage } from '../../WikiCommon/WikiColorIcon'; +import { WikiSpoileredList } from '../../WikiCommon/WikiListElements'; +import { NotAvilableBox } from '../../WikiCommon/WikiQuickElements'; + +export const WikiBotanyPage = (props: { seeds: BotanyData }) => { + const { + title, + feeding, + watering, + lighting, + crop_yield, + traits, + mob_product, + chem_breakdown, + gas_consumed, + gas_exuded, + mutations, + icon_data, + } = props.seeds; + + return ( +
+ + + + + + + + + {feeding ? ( + {feeding} + ) : ( + + )} + + + {watering ? ( + {watering} + ) : ( + + )} + + + {lighting ? ( + {lighting} + ) : ( + + )} + + + {!!crop_yield && crop_yield > 0 ? crop_yield : } + + {!!traits && ( + + )} + {!!mob_product && ( + <> + + + + DANGER - MAY BE MOBILE + + + + )} + {!!chem_breakdown && ( + + )} + {!!gas_consumed && ( + + )} + {!!gas_exuded && ( + + )} + {!!mutations && ( + + )} + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiChemistryPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiChemistryPage.tsx new file mode 100644 index 0000000000..11334d19ac --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiChemistryPage.tsx @@ -0,0 +1,111 @@ +import { Box, LabeledList, Section, Stack } from 'tgui-core/components'; +import { capitalize } from 'tgui-core/string'; + +import type { ReagentData } from '../../types'; +import { ChemicalReactionList } from '../../WikiCommon/WikiChemList'; +import { ColorizedImage } from '../../WikiCommon/WikiColorIcon'; +import { WikiSpoileredList } from '../../WikiCommon/WikiListElements'; +import { + NotAvilableBox, + SupplyEntry, + TierdBox, +} from '../../WikiCommon/WikiQuickElements'; + +export const WikiChemistryPage = (props: { + chems: ReagentData & Partial<{ beakerAmount: number }>; + beakerFill: number; +}) => { + const { beakerFill, chems } = props; + const { + title, + beakerAmount, + description, + addictive, + industrial_use, + supply_points, + market_price, + sintering, + overdose, + flavor, + allergen, + grinding, + instant_reactions, + distilled_reactions, + fluid, + produces, + icon_data, + } = chems; + + const capitalizedTitle = capitalize(title); + const pageTitle = beakerAmount + ? 'Detected Reagent: ' + capitalizedTitle + : capitalizedTitle; + + return ( +
+ + + + + + + {!!beakerAmount && ( + + {beakerAmount}u + + )} + + + {description ? description : } + + + + {!!addictive && } + + + {overdose ? ( + {overdose + 'u'} + ) : ( + + )} + + + {flavor ? flavor : } + + + + {industrial_use ? industrial_use : } + + + + {sintering ? sintering : } + + {!!allergen && ( + + )} + + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiFoodPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiFoodPage.tsx new file mode 100644 index 0000000000..677180234d --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiFoodPage.tsx @@ -0,0 +1,68 @@ +import { LabeledList, Section, Stack } from 'tgui-core/components'; +import { capitalize } from 'tgui-core/string'; + +import type { FoodData } from '../../types'; +import { ChemicalReactionList } from '../../WikiCommon/WikiChemList'; +import { ColorizedImage } from '../../WikiCommon/WikiColorIcon'; +import { RecipeList } from '../../WikiCommon/WikiFoodList'; +import { WikiSpoileredList } from '../../WikiCommon/WikiListElements'; +import { NotAvilableBox } from '../../WikiCommon/WikiQuickElements'; + +export const WikiFoodPage = (props: { food: FoodData }) => { + const { + title, + description, + flavor, + allergen, + grinding, + instant_reactions, + distilled_reactions, + fluid, + produces, + icon_data, + recipe, + } = props.food; + + return ( +
+ + + + + + + + + {description ? description : } + + + {flavor ? flavor : } + + {!!allergen && ( + + )} + {!!recipe && } + {!recipe && ( + + )} + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiMaterialPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiMaterialPage.tsx new file mode 100644 index 0000000000..b706bd4616 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiMaterialPage.tsx @@ -0,0 +1,121 @@ +import { Box, LabeledList, Section, Stack } from 'tgui-core/components'; +import { capitalize } from 'tgui-core/string'; + +import type { MaterialData } from '../../types'; +import { ColorizedImage } from '../../WikiCommon/WikiColorIcon'; +import { WikiSpoileredList } from '../../WikiCommon/WikiListElements'; +import { + NoBox, + NotAvilableBox, + SupplyEntry, + TemperatureBox, + YesBox, +} from '../../WikiCommon/WikiQuickElements'; + +export const WikiMaterialPage = (props: { materials: MaterialData }) => { + const { + title, + integrity, + hardness, + weight, + stack_size, + supply_points, + market_price, + opacity, + conductive, + protectiveness, + explosion_resistance, + radioactivity, + reflectivity, + melting_point, + ignition_point, + grind_reagents, + recipies, + icon_data, + } = props.materials; + + return ( +
+ + + + + + + + {integrity} + {hardness} + {weight} + + + + + {opacity > 0.5 ? : } + + + {conductive ? : } + + + + {protectiveness ? protectiveness : } + + + {explosion_resistance ? explosion_resistance : } + + + {radioactivity ? ( + {radioactivity} + ) : ( + + )} + + + {reflectivity ? ( + {reflectivity * 100} + ) : ( + + )} + + + + {melting_point > 0 ? ( + + ) : ( + + )} + + + {ignition_point > 0 ? ( + + ) : ( + + )} + + {grind_reagents && ( + + )} + {recipies && ( + + )} + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiNoDataPage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiNoDataPage.tsx new file mode 100644 index 0000000000..318bc4a4ba --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiNoDataPage.tsx @@ -0,0 +1,30 @@ +import { Box, Section, Stack } from 'tgui-core/components'; + +import { WikiLogo } from '../../WikiCommon/WikiLogo'; + +export const WikiNoDataPage = (props) => { + return ( +
+ + + + + + + Oh No... No Data... + + + + + We deeply sorry!!! + + + + + Maybe check back later! + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiOrePare.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiOrePare.tsx new file mode 100644 index 0000000000..b57d270996 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiOrePare.tsx @@ -0,0 +1,53 @@ +import { LabeledList, Section, Stack } from 'tgui-core/components'; +import { capitalize } from 'tgui-core/string'; + +import type { OreData } from '../../types'; +import { ColorizedImage } from '../../WikiCommon/WikiColorIcon'; +import { WikiList } from '../../WikiCommon/WikiListElements'; +import { NotAvilableBox } from '../../WikiCommon/WikiQuickElements'; + +export const WikiOrePage = (props: { ores: OreData }) => { + const { + title, + smelting, + compressing, + alloys, + pump_reagent, + grind_reagents, + icon_data, + } = props.ores; + + return ( +
+ + + + + + + + + {smelting ? smelting : } + + + + {compressing ? compressing : } + + {!!alloys && } + + + {pump_reagent ? pump_reagent : } + + {!!grind_reagents && ( + + )} + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiParticlePage.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiParticlePage.tsx new file mode 100644 index 0000000000..3d178e6e72 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/WikiPages/WikiSubPages/WikiParticlePage.tsx @@ -0,0 +1,82 @@ +import { LabeledList, Section, Stack } from 'tgui-core/components'; +import { capitalize } from 'tgui-core/string'; + +import type { ParticleData } from '../../types'; +import { ColorizedImage } from '../../WikiCommon/WikiColorIcon'; +import { WikiSpoileredList } from '../../WikiCommon/WikiListElements'; +import { + MinMaxBox, + MinMaxBoxTemperature, + ProbabilityBox, +} from '../../WikiCommon/WikiQuickElements'; + +export const WikiParticlePage = (props: { smasher: ParticleData }) => { + const { + title, + req_mat, + target_items, + required_energy_min, + required_energy_max, + required_atmos_temp_min, + required_atmos_temp_max, + inducers, + result, + probability, + icon_data, + } = props.smasher; + + return ( +
+ + + + {req_mat} + {!!target_items && ( + + )} + + + + + + + + {!!inducers && ( + + )} + + {result} + + + + + + + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/constants.ts b/tgui/packages/tgui/interfaces/PublicLibraryWiki/constants.ts new file mode 100644 index 0000000000..96083513c3 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/constants.ts @@ -0,0 +1,158 @@ +export const WikiPages = [ + 'Food Recipes', + 'Drink Recipes', + 'Ores', + 'Materials', + 'Particle Physics', + 'Botany', + 'Catalogs', +]; + +export const wikiAds = [ + 'Inferior ears? Teshari enhancement surgeries might be for you!', + 'Phoron huffers anonymous group chat. Join Today!', + 'Hot and single Vox raiders near your system!', + 'Need company? Holographic NIF friends! FREE DOWNLOAD!', + 'LostSpagetti.sol your one stop SYNX DATING website!', + 'HONK.bonk clown-only social media. Sign up TODAY!', + 'FREE ORGANS! FREE ORGANS! FREE ORGANS! Terms apply.', + 'Smile.me.com.net.skrell.node.exe.js DOWNLOAD NOW!', + 'Bankrupt? We can help! Buy uranium coins today!', + "CONGRATULATIONS, you're our " + + Math.floor(Math.random() * 1000 + 1) * 1000 + + 'th visitor! DOWNLOAD!', + 'Your system is out of date, DOWNLOAD DRIVERS!', + "Ms.Kitty can't hang in there long, click here to support FELINE INDEPENDENCE!", + 'Cortical borer therapy! Treats anxiety, stress, and impending sense of univeral collapse!', + 'Help I licked the supermatter! And other strange stories from Nanotrasen. FREE PDF!', + 'TIME IS COMING TO AN END, BUY GOLD NOW!', + 'Your own pet clown? It sounds too REAL to be TRUE! VIEW ARTICLE!', + 'Are you a BIGSHOT? Investment opportunities inside!', + 'Spacestation13.exe FREE DOWNLOAD NOW!', + 'Bored and alone? Date a wizard today! WIZZBIZZ.KAZAM!', + 'Hot skrell babes in your area!', +]; + +export const WikiAdColors = [ + 'black', + 'white', + 'red', + 'orange', + 'yellow', + 'olive', + 'green', + 'teal', + 'blue', + 'violet', + 'purple', + 'pink', + 'brown', + 'grey', + 'light-grey', + '', +]; + +export const WikiDonIcons = [ + 'dollar-sign', + 'sack-dollar', + 'money-check-dollar', + 'file-invoice-dollar', + 'circle-dollar-to-slot', + 'hand-holding-dollar', + 'credit-card', + 'euro-sign', + 'wallet', + 'coins', + 'yen-sign', + 'won-sign', + 'turkish-lira-sign', + 'tenge-sign', + 'sterling-sign', + 'shekel-sign', + 'rupiah-sign', + 'rupee-sign', + 'ruble-sign', + 'peso-sign', + 'peseta-sign', + 'naira-sign', + 'mill-sign', + 'manat-sign', + 'litecoin-sign', + 'lira-sign', + 'lari-sign', + 'kip-sign', + 'indian-rupee-sign', + 'hryvnia-sign', + 'guarani-sign', + 'franc-sign', + 'florin-sign', + 'dong-sign', + 'cruzeiro-sign', + 'colon-sign', + 'cent-sign', + 'cedi-sign', + 'brazilian-real-sign', + 'bitcoin-sign', + 'bangladeshi-taka-sign', + 'baht-sign', + 'austral-sign', +]; + +export const zeroC = 273.15; + +export const WikiDonationMessages = [ + 'Become a bingler today!', + 'Enjoying our content? Your donation keeps us in business!', + 'We all would love an ad free experience... Make it possible!', + 'Better to us than the Vox!', + 'Opersating and upkeeping trustworthy information since 1990.', + 'Suport or information revolution. From bluespace right into your brain.', +]; + +export const wikiDonatedMessages = [ + 'You are awesome!', + 'Your support is appreciated!', + "We'll do our best to improve your experience!", + 'Thank you! Thank you! Thank you!', +]; + +// Did you know? +export const WikiTippOfTheDay = [ + "Bingle wasn't built in typescript, but instead the crystalized tears of our programmers?", + 'Sleep()ing is illegal!', + 'Not all spaw()ns are friendly!', + 'A space carp a day keeps the virus away.', + 'Who thought two apple trees would be a good idea?', + 'Chemistry used to work on a trust based system? Where recipes had each chemical written down on their own post-it note per reaction!', + 'A toss to a wall once made everyone sprawl.', + 'New... New... New... why is it everywhere?', + 'Do we?', + 'Investments in books are so past century. Invest in bingle today!', + 'We can see the future!', + 'The code that runs Bingle is byond most mortal comprehension!', + 'You could just go on, milk that synx for inaprovaline!', + "Appendicitis is actually contagious, don't listen to medical's lies!", + 'Bingle is more trustworthy then books written 200 years ago!', + 'Did you know, you can hallucinate forever?', + 'The pain never ends!', + 'Did you know? Skrell are 40% more likely to donate their bodies for research?', + 'You can do it all yourself, go on fork the code again, I dare you!', + 'Ceilings are a myth made to sell you roofs!', + "It's illegal to turn elevators into showers in Solgov space!", + 'Supermatter, everywhere supermatter!', + 'You can live forever!', + 'Baits might have a telepathic side effect.', + 'There have been [' + + Math.floor(Math.random() * 1000) + + '] runtimes recorded by Bingle today!', + '9 out of 10 doctors agree the supermatter tastes like ranch dressing!', + 'Some oceans have infinite gravity!', + "Solgov has never said why it's illegal to have both a singularity and supermatter engine on the same station!", + 'Lead has the highest radiation resistance of all materials? Perfect for engine walls!', + 'In some regions of space, magic is illegal. Go on, try it nerd, your funny words have no power here!', + 'Forget who you are and summon the old gods.', + "Who's that initialize and why do they always call their parents?", + "Did you know? New isn't new anymore! It's so past century!", + 'Your kitchen is a chemistry set too!', + 'With Bingle, no sin will remain hidden from sight!', +]; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/index.tsx b/tgui/packages/tgui/interfaces/PublicLibraryWiki/index.tsx new file mode 100644 index 0000000000..ad473226ff --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/index.tsx @@ -0,0 +1,191 @@ +import { useEffect, useState } from 'react'; +import { useBackend } from 'tgui/backend'; +import { Window } from 'tgui/layouts'; +import { Box, NoticeBox, Section, Stack } from 'tgui-core/components'; + +import { + WikiAdColors, + wikiAds, + wikiDonatedMessages, + WikiDonationMessages, + WikiTippOfTheDay, +} from './constants'; +import type { Data } from './types'; +import { WikiDonationBanner } from './WikiPages/WIkiDonationbanner'; +import { WikiErrorPage } from './WikiPages/WikiErrorPage'; +import { WikiLoadingPage } from './WikiPages/WikiLoadingPage'; +import { WikiMainPage } from './WikiPages/WikiMainPage'; +import { WikiSearchPage } from './WikiPages/WikiSearchPage'; + +export const PublicLibraryWiki = (props) => { + const { data } = useBackend(); + const { + crash, + errorText, + searchmode, + search, + print, + sub_categories, + food_data, + drink_data, + chemistry_data, + botany_data, + material_data, + particle_data, + catalog_data, + ore_data, + has_donated, + donated, + goal, + } = data; + const [displayedAds, setDisplayedAds] = useState([]); + const [displayDonation, setDislayDonation] = useState(false); + const [displayedDonations, setDisplayedDonations] = useState(''); + const [displayedDonated, setDisplayDonated] = useState(''); + const [tippOfTheDay, setTipOfTheDay] = useState( + WikiTippOfTheDay[Math.floor(Math.random() * WikiTippOfTheDay.length)], + ); + const [updateAds, setUpdateAds] = useState(false); + const [loadTime, setLoadTime] = useState( + Math.floor(Math.random() * 2000) + 2000, + ); + const [activeTab, setactiveTab] = useState(0); + + useEffect(() => { + if (!crash) { + setTimeout(() => { + setactiveTab(1); + }, loadTime); + } else { + setactiveTab(1); + } + }, []); + + useEffect(() => { + if (!crash) { + setactiveTab(0); + setTimeout(() => { + setactiveTab(1); + }, loadTime); + } else { + setLoadTime(Math.floor(Math.random() * 2000) + 2000); + } + }, [crash]); + + useEffect(() => { + let shownAds: string[] = []; + const range = wikiAds.length; + const firstEntry = Math.floor(Math.random() * range); + let secondEntry = Math.floor(Math.random() * range); + if (firstEntry === secondEntry) { + if (secondEntry === range) { + secondEntry--; + } else { + secondEntry++; + } + } + const addEntries: string[][] = []; + shownAds.push(wikiAds[firstEntry]); + shownAds.push( + WikiAdColors[Math.floor(Math.random() * WikiAdColors.length)], + ); + addEntries.push([...shownAds]); + shownAds = []; + shownAds.push(wikiAds[secondEntry]); + shownAds.push( + WikiAdColors[Math.floor(Math.random() * WikiAdColors.length)], + ); + addEntries.push([...shownAds]); + setDisplayedAds(addEntries); + + if (Math.random() < 0.2 && !displayDonation) { + setDislayDonation(true); + } + }, [updateAds]); + + useEffect(() => { + if (displayDonation && !has_donated) { + setDisplayedDonations( + WikiDonationMessages[ + Math.floor(Math.random() * WikiDonationMessages.length) + ], + ); + } + }, [displayDonation]); + + useEffect(() => { + if (has_donated) { + setDisplayDonated( + wikiDonatedMessages[ + Math.floor(Math.random() * wikiDonatedMessages.length) + ], + ); + setTimeout(() => { + setDislayDonation(false); + }, 5000); + } + }, [has_donated]); + + const tabs: React.JSX.Element[] = []; + tabs[0] = ; + tabs[1] = crash ? ( + + ) : ( +
+ {searchmode && search ? ( + + ) : ( + = goal} + /> + )} +
+ ); + + return ( + + + + {!!errorText && ( + + + {errorText} + + + )} + {!crash && displayDonation && !!activeTab && ( + + + + )} + + {tabs[activeTab]} + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/PublicLibraryWiki/types.ts b/tgui/packages/tgui/interfaces/PublicLibraryWiki/types.ts new file mode 100644 index 0000000000..3c99f720f0 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PublicLibraryWiki/types.ts @@ -0,0 +1,159 @@ +import type { BooleanLike } from 'tgui-core/react'; + +export type Data = { + crash: BooleanLike; + errorText: string; + searchmode: string; + search: string[] | null; + title: string; + print: string; + sub_categories: string[] | null; + has_donated: BooleanLike; + donated: number; + goal: number; +} & Required; + +export type PageData = { + material_data: MaterialData | null; + particle_data: ParticleData | null; + catalog_data: CatalogData | null; + ore_data: OreData | null; + botany_data: BotanyData | null; + chemistry_data: ReagentData | null; + drink_data: DrinkData | null; + food_data: FoodData | null; +}; + +export type FoodData = DrinkData & Partial<{ recipe: RedipeData }>; + +export type DrinkData = BasicFood & Icon & Partial; + +type BasicFood = { + title: string; + description: string; + flavor?: string; + allergen: string[]; +}; + +export type RedipeData = { + supply_points: number; + market_price: number; + appliance: string; + has_coating: BooleanLike; + coating: number | string | null; + ingredients: Record | null; + fruits: Record | null; + reagents: Record | null; + catalysts: Record | null; +}; + +export type ReagentData = { + title: string; + description: string | null; + addictive?: number; + industrial_use?: string; + supply_points?: number; + market_price?: number; + sintering?: string | null; + overdose: number; + flavor: string | null; + allergen: string[] | null; +} & ReactionData & + Icon; + +export type BotanyData = { + title: string; + feeding: number | null; + watering: number | null; + lighting: number | null; + crop_yield: number | null; + traits: string[] | null; + mob_product: string; + chem_breakdown: string[] | null; + gas_consumed: Record | null; + gas_exuded: Record | null; + mutations: string[] | null; +} & Icon; + +export type OreData = { + title: string; + smelting: string | null; + compressing: string | null; + alloys: string[]; + pump_reagent: string | null; + grind_reagents: Record; +} & Icon; + +export type ParticleData = { + title: string; + req_mat: string | null; + target_items: string[] | null; + required_energy_min: number; + required_energy_max: number; + required_atmos_temp_min: number; + required_atmos_temp_max: number; + inducers: Record | null; + result: string; + probability: number; +} & Icon; + +export type MaterialData = { + title: string; + integrity: number; + hardness: number; + weight: number; + stack_size: number; + supply_points: number; + market_price: number; + opacity: number; + conductive: BooleanLike; + protectiveness: number; + explosion_resistance: number; + radioactivity: number | null; + reflectivity: number; + melting_point: number; + ignition_point: number; + grind_reagents: Record | null; + recipies: string[] | null; +} & Icon; + +export type CatalogData = { name: string; desc: string }; + +export type Icon = { + icon_data: { icon: string; state: string; color: string; dat: string }; +}; + +export type ReactionData = { + grinding: GroundMaterial; + instant_reactions: InstantReactions; + distilled_reactions: DistilledReactions; + fluid: string[] | null; + produces: string[] | null; +}; + +export type GroundMaterial = { + ore: String[] | null; + plant: string[] | null; + material: string[] | null; +} | null; +export type InstantReactions = ReactionComponent | ReactionComponent[] | null; +export type DistilledReactions = DistillComponent | DistillComponent[] | null; + +export type DistillComponent = + | (ReactionComponent & + Partial<{ + temp_min: number; + temp_max: number; + xgm_min: number; + xgm_max: number; + require_xgm_gas: string; + rejects_xgm_gas: string; + }>) + | null; + +export type ReactionComponent = { + is_slime: string | null; + required: string[] | null; + inhibitor: string[] | null; + catalysts: string[] | null; +} | null; diff --git a/tgui/packages/tgui/interfaces/RCON/types.ts b/tgui/packages/tgui/interfaces/RCON/types.ts index b09ea4c27b..cacdbafac2 100644 --- a/tgui/packages/tgui/interfaces/RCON/types.ts +++ b/tgui/packages/tgui/interfaces/RCON/types.ts @@ -1,6 +1,6 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; -import { smes } from '../Smes'; +import type { smes } from '../Smes'; export type Data = { pages: number; diff --git a/tgui/packages/tgui/interfaces/RIGSuit/types.ts b/tgui/packages/tgui/interfaces/RIGSuit/types.ts index 83ec6d1f8c..0c57ffb636 100644 --- a/tgui/packages/tgui/interfaces/RIGSuit/types.ts +++ b/tgui/packages/tgui/interfaces/RIGSuit/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { primarysystem: string | null; diff --git a/tgui/packages/tgui/interfaces/RapidPipeDispenser/types.ts b/tgui/packages/tgui/interfaces/RapidPipeDispenser/types.ts index 9cc2b05c88..b405355191 100644 --- a/tgui/packages/tgui/interfaces/RapidPipeDispenser/types.ts +++ b/tgui/packages/tgui/interfaces/RapidPipeDispenser/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { category: number; diff --git a/tgui/packages/tgui/interfaces/RequestConsole/types.ts b/tgui/packages/tgui/interfaces/RequestConsole/types.ts index 3075494ac7..b5d45b50eb 100644 --- a/tgui/packages/tgui/interfaces/RequestConsole/types.ts +++ b/tgui/packages/tgui/interfaces/RequestConsole/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { department: string; diff --git a/tgui/packages/tgui/interfaces/ResearchConsole/data.ts b/tgui/packages/tgui/interfaces/ResearchConsole/data.ts index d91bba1d56..e88314e2cf 100644 --- a/tgui/packages/tgui/interfaces/ResearchConsole/data.ts +++ b/tgui/packages/tgui/interfaces/ResearchConsole/data.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export enum Tab { Protolathe = 0, diff --git a/tgui/packages/tgui/interfaces/ResearchConsole/pages/Constructor.tsx b/tgui/packages/tgui/interfaces/ResearchConsole/pages/Constructor.tsx index 140ed3dfa5..03c5f0d3ad 100644 --- a/tgui/packages/tgui/interfaces/ResearchConsole/pages/Constructor.tsx +++ b/tgui/packages/tgui/interfaces/ResearchConsole/pages/Constructor.tsx @@ -16,8 +16,8 @@ import { capitalizeAll } from 'tgui-core/string'; import { PaginationChevrons } from '..'; import { - ConstructorDesign, - ConstructorEnum, + type ConstructorDesign, + type ConstructorEnum, constructorEnumToBuild, constructorEnumToBuildFive, constructorEnumToData, @@ -26,8 +26,8 @@ import { constructorEnumToEjectReagentAllAction, constructorEnumToName, constructorEnumToRemoveQueue, - Data, - LinkedConstructor, + type Data, + type LinkedConstructor, } from '../data'; enum ConstructorTabEnum { diff --git a/tgui/packages/tgui/interfaces/ResearchConsole/pages/DestructiveAnalyzer.tsx b/tgui/packages/tgui/interfaces/ResearchConsole/pages/DestructiveAnalyzer.tsx index 353a02bceb..42ef1d0a1f 100644 --- a/tgui/packages/tgui/interfaces/ResearchConsole/pages/DestructiveAnalyzer.tsx +++ b/tgui/packages/tgui/interfaces/ResearchConsole/pages/DestructiveAnalyzer.tsx @@ -29,7 +29,7 @@ const DestroyButton = (props: { destroyer: LinkedDestroyer }) => { const { act } = useBackend(); const { destroyer } = props; - let [buttonPressed, setButtonPressed] = useState(false); + const [buttonPressed, setButtonPressed] = useState(false); return ( diff --git a/tgui/packages/tgui/interfaces/ResearchServerController.tsx b/tgui/packages/tgui/interfaces/ResearchServerController.tsx index 99636f43b8..e0f3e64b4a 100644 --- a/tgui/packages/tgui/interfaces/ResearchServerController.tsx +++ b/tgui/packages/tgui/interfaces/ResearchServerController.tsx @@ -39,7 +39,7 @@ const ResearchControllerContent = (props) => { null, ); - let realServer = servers.find((s) => s.id === selectedServer); + const realServer = servers.find((s) => s.id === selectedServer); if (realServer) { return ( diff --git a/tgui/packages/tgui/interfaces/ResleevingConsole/types.ts b/tgui/packages/tgui/interfaces/ResleevingConsole/types.ts index 2e97ff3653..5b9933d92c 100644 --- a/tgui/packages/tgui/interfaces/ResleevingConsole/types.ts +++ b/tgui/packages/tgui/interfaces/ResleevingConsole/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { menu: number; diff --git a/tgui/packages/tgui/interfaces/RobotChoose/functions.ts b/tgui/packages/tgui/interfaces/RobotChoose/functions.ts index c0e5c7e7a5..e823209281 100644 --- a/tgui/packages/tgui/interfaces/RobotChoose/functions.ts +++ b/tgui/packages/tgui/interfaces/RobotChoose/functions.ts @@ -1,7 +1,7 @@ import { flow } from 'tgui-core/fp'; import { createSearch } from 'tgui-core/string'; -import { spriteOption } from './types'; +import type { spriteOption } from './types'; export function robotSpriteSearcher( searchText: string, @@ -17,7 +17,7 @@ export function robotSpriteSearcher( if (!sprites) { return []; } - let subtypes: string[] = []; + const subtypes: string[] = []; if (includeDefault) { subtypes.push('def'); } diff --git a/tgui/packages/tgui/interfaces/Robotact/types.ts b/tgui/packages/tgui/interfaces/Robotact/types.ts index ab908e6298..9e5a43f536 100644 --- a/tgui/packages/tgui/interfaces/Robotact/types.ts +++ b/tgui/packages/tgui/interfaces/Robotact/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Component = { key: string; diff --git a/tgui/packages/tgui/interfaces/SecureSafe.tsx b/tgui/packages/tgui/interfaces/SecureSafe.tsx index a17f064d18..08342ef773 100644 --- a/tgui/packages/tgui/interfaces/SecureSafe.tsx +++ b/tgui/packages/tgui/interfaces/SecureSafe.tsx @@ -65,7 +65,7 @@ export const SecureSafe = (props) => { const { act, data } = useBackend(); const { code, l_setshort, l_set, emagged, locked } = data; - let new_code: boolean = !(!!l_set || !!l_setshort); + const new_code: boolean = !(!!l_set || !!l_setshort); return ( diff --git a/tgui/packages/tgui/interfaces/SecurityRecords/types.ts b/tgui/packages/tgui/interfaces/SecurityRecords/types.ts index 269df69a98..350b5544a2 100644 --- a/tgui/packages/tgui/interfaces/SecurityRecords/types.ts +++ b/tgui/packages/tgui/interfaces/SecurityRecords/types.ts @@ -1,6 +1,6 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; -import { field } from '../GeneralRecords/types'; +import type { field } from '../GeneralRecords/types'; export type Data = { temp: { color: string; text: string } | null; diff --git a/tgui/packages/tgui/interfaces/ShuttleControl/types.ts b/tgui/packages/tgui/interfaces/ShuttleControl/types.ts index 2918ac75f9..4130a8c6d8 100644 --- a/tgui/packages/tgui/interfaces/ShuttleControl/types.ts +++ b/tgui/packages/tgui/interfaces/ShuttleControl/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = Partial< MultiData & diff --git a/tgui/packages/tgui/interfaces/Sleeper/types.ts b/tgui/packages/tgui/interfaces/Sleeper/types.ts index f7cee94e85..e37be9af0a 100644 --- a/tgui/packages/tgui/interfaces/Sleeper/types.ts +++ b/tgui/packages/tgui/interfaces/Sleeper/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { amounts: number[]; diff --git a/tgui/packages/tgui/interfaces/SupplyConsole/types.ts b/tgui/packages/tgui/interfaces/SupplyConsole/types.ts index d913b3e353..7d8bc8133b 100644 --- a/tgui/packages/tgui/interfaces/SupplyConsole/types.ts +++ b/tgui/packages/tgui/interfaces/SupplyConsole/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { shuttle_auth: BooleanLike; diff --git a/tgui/packages/tgui/interfaces/TextInputModal.tsx b/tgui/packages/tgui/interfaces/TextInputModal.tsx index b9ee6ede6c..5b6509fb05 100644 --- a/tgui/packages/tgui/interfaces/TextInputModal.tsx +++ b/tgui/packages/tgui/interfaces/TextInputModal.tsx @@ -1,4 +1,4 @@ -import { KeyboardEvent, useState } from 'react'; +import { type KeyboardEvent, useState } from 'react'; import { useBackend } from 'tgui/backend'; import { Window } from 'tgui/layouts'; import { Box, Section, Stack, TextArea } from 'tgui-core/components'; diff --git a/tgui/packages/tgui/interfaces/TimeClock.tsx b/tgui/packages/tgui/interfaces/TimeClock.tsx index 9cf17c78f8..0693f293eb 100644 --- a/tgui/packages/tgui/interfaces/TimeClock.tsx +++ b/tgui/packages/tgui/interfaces/TimeClock.tsx @@ -152,7 +152,7 @@ export const TimeClock = (props) => { (!!job_choices && Object.keys(job_choices).length && Object.keys(job_choices).map((job) => { - let alt_titles = job_choices[job]; + const alt_titles = job_choices[job]; return alt_titles.map((title) => ( ); - modalOnEscape = (e) => modalClose(id); // Different contents depending on the type if (bodyOverrides[id]) { modalBody = bodyOverrides[id](modal); diff --git a/tgui/packages/tgui/interfaces/common/RankIcon.tsx b/tgui/packages/tgui/interfaces/common/RankIcon.tsx index 6d51fecc20..ae08f32484 100644 --- a/tgui/packages/tgui/interfaces/common/RankIcon.tsx +++ b/tgui/packages/tgui/interfaces/common/RankIcon.tsx @@ -639,7 +639,7 @@ type rank_icon = { rank: string; color: string }; export const RankIcon = (props: rank_icon) => { const { rank, color = 'label' } = props; - let rankObj = rank2icon[rank]; + const rankObj = rank2icon[rank]; if (typeof rankObj === 'string') { return ; } else if (Array.isArray(rankObj)) { diff --git a/tgui/packages/tgui/layouts/Layout.tsx b/tgui/packages/tgui/layouts/Layout.tsx index 765ee2991c..a727440d80 100644 --- a/tgui/packages/tgui/layouts/Layout.tsx +++ b/tgui/packages/tgui/layouts/Layout.tsx @@ -5,7 +5,7 @@ */ import { useEffect, useRef } from 'react'; -import { Box } from 'tgui-core/components'; +import type { Box } from 'tgui-core/components'; import { addScrollableNode, removeScrollableNode } from 'tgui-core/events'; import { classes } from 'tgui-core/react'; import { computeBoxClassName, computeBoxProps } from 'tgui-core/ui'; diff --git a/tgui/packages/tgui/layouts/Window.tsx b/tgui/packages/tgui/layouts/Window.tsx index b53d0c73c0..9bd6a0932f 100644 --- a/tgui/packages/tgui/layouts/Window.tsx +++ b/tgui/packages/tgui/layouts/Window.tsx @@ -4,12 +4,17 @@ * @license MIT */ -import { ComponentProps, PropsWithChildren, ReactNode, useEffect } from 'react'; +import { + type ComponentProps, + type PropsWithChildren, + type ReactNode, + useEffect, +} from 'react'; import { backendSuspendStart, globalStore, useBackend } from 'tgui/backend'; import { UI_DISABLED, UI_INTERACTIVE, UI_UPDATE } from 'tgui/constants'; import { useDebug } from 'tgui/debug'; import { toggleKitchenSink } from 'tgui/debug/actions'; -import { Box, Icon } from 'tgui-core/components'; +import { type Box, Icon } from 'tgui-core/components'; import { classes } from 'tgui-core/react'; import { decodeHtmlEntities, toTitleCase } from 'tgui-core/string'; diff --git a/tgui/packages/tgui/renderer.ts b/tgui/packages/tgui/renderer.ts index bbdfeffc16..60df6f7285 100644 --- a/tgui/packages/tgui/renderer.ts +++ b/tgui/packages/tgui/renderer.ts @@ -1,6 +1,6 @@ import { perf } from 'common/perf'; -import { ReactNode } from 'react'; -import { createRoot, Root } from 'react-dom/client'; +import type { ReactNode } from 'react'; +import { createRoot, type Root } from 'react-dom/client'; import { createLogger } from './logging'; diff --git a/tgui/packages/tgui/store.ts b/tgui/packages/tgui/store.ts index aa3404997d..cb20bbf8a5 100644 --- a/tgui/packages/tgui/store.ts +++ b/tgui/packages/tgui/store.ts @@ -8,9 +8,9 @@ import { applyMiddleware, combineReducers, createStore, - Middleware, - Reducer, - Store, + type Middleware, + type Reducer, + type Store, } from 'common/redux'; import { flow } from 'tgui-core/fp'; diff --git a/tgui/packages/tgui/styles/themes/bingle.scss b/tgui/packages/tgui/styles/themes/bingle.scss new file mode 100644 index 0000000000..d00bf031c5 --- /dev/null +++ b/tgui/packages/tgui/styles/themes/bingle.scss @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2025 Kashargul + * SPDX-License-Identifier: MIT + */ + +@use 'sass:color'; +@use 'sass:meta'; + +.theme-bingle { + // Components + @include meta.load-css( + '~tgui-core/styles/components/Button.scss', + $with: ('color-selected': hsl(227, 100%, 26%)) + ); + @include meta.load-css( + '~tgui-core/styles/components/ProgressBar.scss', + $with: ('color-default-fill': hsl(15, 98%, 50%)) + ); + + // Layouts + .Layout__content { + background-image: url('../../assets/bg-neutral.svg'); + } +} diff --git a/tgui/yarn.lock b/tgui/yarn.lock index 38b07255e8..cb2dfc42ff 100644 --- a/tgui/yarn.lock +++ b/tgui/yarn.lock @@ -64,7 +64,7 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.26.5, @babel/compat-data@npm:^7.26.8": +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.26.8": version: 7.26.8 resolution: "@babel/compat-data@npm:7.26.8" checksum: 10c0/66408a0388c3457fff1c2f6c3a061278dd7b3d2f0455ea29bb7b187fa52c60ae8b4054b3c0a184e21e45f0eaac63cf390737bc7504d1f4a088a6e7f652c068ca @@ -118,16 +118,16 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.12.1, @babel/generator@npm:^7.26.10, @babel/generator@npm:^7.7.2": - version: 7.26.10 - resolution: "@babel/generator@npm:7.26.10" +"@babel/generator@npm:^7.12.1, @babel/generator@npm:^7.26.10, @babel/generator@npm:^7.27.0, @babel/generator@npm:^7.7.2": + version: 7.27.0 + resolution: "@babel/generator@npm:7.27.0" dependencies: - "@babel/parser": "npm:^7.26.10" - "@babel/types": "npm:^7.26.10" + "@babel/parser": "npm:^7.27.0" + "@babel/types": "npm:^7.27.0" "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^3.0.2" - checksum: 10c0/88b3b3ea80592fc89349c4e1a145e1386e4042866d2507298adf452bf972f68d13bf699a845e6ab8c028bd52c2247013eb1221b86e1db5c9779faacba9c4b10e + checksum: 10c0/7cb10693d2b365c278f109a745dc08856cae139d262748b77b70ce1d97da84627f79648cab6940d847392c0e5d180441669ed958b3aee98d9c7d274b37c553bd languageName: node linkType: hard @@ -141,45 +141,45 @@ __metadata: linkType: hard "@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.25.9, @babel/helper-compilation-targets@npm:^7.26.5": - version: 7.26.5 - resolution: "@babel/helper-compilation-targets@npm:7.26.5" + version: 7.27.0 + resolution: "@babel/helper-compilation-targets@npm:7.27.0" dependencies: - "@babel/compat-data": "npm:^7.26.5" + "@babel/compat-data": "npm:^7.26.8" "@babel/helper-validator-option": "npm:^7.25.9" browserslist: "npm:^4.24.0" lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - checksum: 10c0/9da5c77e5722f1a2fcb3e893049a01d414124522bbf51323bb1a0c9dcd326f15279836450fc36f83c9e8a846f3c40e88be032ed939c5a9840922bed6073edfb4 + checksum: 10c0/375c9f80e6540118f41bd53dd54d670b8bf91235d631bdead44c8b313b26e9cd89aed5c6df770ad13a87a464497b5346bb72b9462ba690473da422f5402618b6 languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.25.9": - version: 7.26.9 - resolution: "@babel/helper-create-class-features-plugin@npm:7.26.9" +"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.25.9, @babel/helper-create-class-features-plugin@npm:^7.27.0": + version: 7.27.0 + resolution: "@babel/helper-create-class-features-plugin@npm:7.27.0" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.25.9" "@babel/helper-member-expression-to-functions": "npm:^7.25.9" "@babel/helper-optimise-call-expression": "npm:^7.25.9" "@babel/helper-replace-supers": "npm:^7.26.5" "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9" - "@babel/traverse": "npm:^7.26.9" + "@babel/traverse": "npm:^7.27.0" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/808620b350ac012f22163fd44c38ed8e05b24ce5d37bc4aa99a44e9724205f11efcef6b25ccfa5bb5de82ac32b899f1e939123c688f335d2851f4b8d70742233 + checksum: 10c0/c4945903136d934050e070f69a4d72ec425f1f70634e0ddf14ad36695f935125a6df559f8d5b94cc1ed49abd4ce9c5be8ef3ba033fa8d09c5dd78d1a9b97d8cc languageName: node linkType: hard "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.25.9": - version: 7.26.3 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.26.3" + version: 7.27.0 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.27.0" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.25.9" regexpu-core: "npm:^6.2.0" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/266f30b99af621559467ed67634cb653408a9262930c0627c3d17691a9d477329fb4dabe4b1785cbf0490e892513d247836674271842d6a8da49fd0afae7d435 + checksum: 10c0/62513522a43521d8a29285a47127694ec28d66d793cd156cf875cdee6a9b3a9a1626c43c1eb75ce18fa2bf5dc3140f0a8081a34feb24272ecf66084f3cc3b00a languageName: node linkType: hard @@ -316,12 +316,12 @@ __metadata: linkType: hard "@babel/helpers@npm:^7.12.1, @babel/helpers@npm:^7.26.10": - version: 7.26.10 - resolution: "@babel/helpers@npm:7.26.10" + version: 7.27.0 + resolution: "@babel/helpers@npm:7.27.0" dependencies: - "@babel/template": "npm:^7.26.9" - "@babel/types": "npm:^7.26.10" - checksum: 10c0/f99e1836bcffce96db43158518bb4a24cf266820021f6461092a776cba2dc01d9fc8b1b90979d7643c5c2ab7facc438149064463a52dd528b21c6ab32509784f + "@babel/template": "npm:^7.27.0" + "@babel/types": "npm:^7.27.0" + checksum: 10c0/a3c64fd2d8b164c041808826cc00769d814074ea447daaacaf2e3714b66d3f4237ef6e420f61d08f463d6608f3468c2ac5124ab7c68f704e20384def5ade95f4 languageName: node linkType: hard @@ -337,14 +337,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.3, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.26.10, @babel/parser@npm:^7.26.9, @babel/parser@npm:^7.7.0": - version: 7.26.10 - resolution: "@babel/parser@npm:7.26.10" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.3, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.26.10, @babel/parser@npm:^7.27.0, @babel/parser@npm:^7.7.0": + version: 7.27.0 + resolution: "@babel/parser@npm:7.27.0" dependencies: - "@babel/types": "npm:^7.26.10" + "@babel/types": "npm:^7.27.0" bin: parser: ./bin/babel-parser.js - checksum: 10c0/c47f5c0f63cd12a663e9dc94a635f9efbb5059d98086a92286d7764357c66bceba18ccbe79333e01e9be3bfb8caba34b3aaebfd8e62c3d5921c8cf907267be75 + checksum: 10c0/ba2ed3f41735826546a3ef2a7634a8d10351df221891906e59b29b0a0cd748f9b0e7a6f07576858a9de8e77785aad925c8389ddef146de04ea2842047c9d2859 languageName: node linkType: hard @@ -785,13 +785,13 @@ __metadata: linkType: hard "@babel/plugin-transform-block-scoping@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-block-scoping@npm:7.25.9" + version: 7.27.0 + resolution: "@babel/plugin-transform-block-scoping@npm:7.27.0" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.26.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/a76e30becb6c75b4d87a2cd53556fddb7c88ddd56bfadb965287fd944810ac159aa8eb5705366fc37336041f63154ed9fab3862fb10482a45bf5ede63fd55fda + checksum: 10c0/15a604fac04151a795ff3213c73ece06bda7cd5f7c8cb7a3b29563ab243f0b3f7cba9e6facfc9d70e3e63b21af32f9d26bd10ccc58e1c425c7801186014b5ce4 languageName: node linkType: hard @@ -1019,7 +1019,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.25.9, @babel/plugin-transform-modules-commonjs@npm:^7.26.3": +"@babel/plugin-transform-modules-commonjs@npm:^7.26.3": version: 7.26.3 resolution: "@babel/plugin-transform-modules-commonjs@npm:7.26.3" dependencies: @@ -1258,14 +1258,14 @@ __metadata: linkType: hard "@babel/plugin-transform-regenerator@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-regenerator@npm:7.25.9" + version: 7.27.0 + resolution: "@babel/plugin-transform-regenerator@npm:7.27.0" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.26.5" regenerator-transform: "npm:^0.15.2" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/eef3ffc19f7d291b863635f32b896ad7f87806d9219a0d3404a470219abcfc5b43aabecd691026c48e875b965760d9c16abee25e6447272233f30cd07f453ec7 + checksum: 10c0/aa1c6a1592338df96034e0c3933d9c84d0ae25e9768413fda90d4896470192a11e2ab146dbcb92005c5059bbea67aea3d11936de8e4be382613efceafc9c92b5 languageName: node linkType: hard @@ -1354,28 +1354,28 @@ __metadata: linkType: hard "@babel/plugin-transform-typeof-symbol@npm:^7.26.7": - version: 7.26.7 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.26.7" + version: 7.27.0 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.27.0" dependencies: "@babel/helper-plugin-utils": "npm:^7.26.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/d5640e3457637e6eee1d7205d255602ccca124ed30e4de10ec75ba179d167e0a826ceeab424e119921f5c995dfddf39ef1f2c91efd2dcbf3f0dc1e7931dfd1d1 + checksum: 10c0/00adbd4e044166ac291978bd64173b4a0d36cbcfae3495a196816dd16ba889cc8b5becee232086241d714cd67a80c15742402504fc36f6db4f746a7dd8d2b1c4 languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.25.9": - version: 7.26.8 - resolution: "@babel/plugin-transform-typescript@npm:7.26.8" +"@babel/plugin-transform-typescript@npm:^7.27.0": + version: 7.27.0 + resolution: "@babel/plugin-transform-typescript@npm:7.27.0" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.25.9" - "@babel/helper-create-class-features-plugin": "npm:^7.25.9" + "@babel/helper-create-class-features-plugin": "npm:^7.27.0" "@babel/helper-plugin-utils": "npm:^7.26.5" "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9" "@babel/plugin-syntax-typescript": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c1dc02c357b8de0650d4e757fe71db9ac769b68e282a262ca5af2a7f1ff112c4533d54db6f1f58f13072ad547561b0461c46c08233566b37f778ac5f5550fb41 + checksum: 10c0/028e75dd6195495dc2d105ca8ded19d62aef90a215d597451cee57c35325960a87963913aa9a21b8ade190c638b588422292ea7e23b21565baf53c469254dbd4 languageName: node linkType: hard @@ -1535,72 +1535,72 @@ __metadata: linkType: hard "@babel/preset-typescript@npm:^7.16.0": - version: 7.26.0 - resolution: "@babel/preset-typescript@npm:7.26.0" + version: 7.27.0 + resolution: "@babel/preset-typescript@npm:7.27.0" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.26.5" "@babel/helper-validator-option": "npm:^7.25.9" "@babel/plugin-syntax-jsx": "npm:^7.25.9" - "@babel/plugin-transform-modules-commonjs": "npm:^7.25.9" - "@babel/plugin-transform-typescript": "npm:^7.25.9" + "@babel/plugin-transform-modules-commonjs": "npm:^7.26.3" + "@babel/plugin-transform-typescript": "npm:^7.27.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/20d86bc45d2bbfde2f84fc7d7b38746fa6481d4bde6643039ad4b1ff0b804c6d210ee43e6830effd8571f2ff43fa7ffd27369f42f2b3a2518bb92dc86c780c61 + checksum: 10c0/986b20edab3c18727d911a6e1a14095c1271afc6cc625b02f42b371f06c1e041e5d7c1baf2afe8b0029b60788a06f02fd6844dedfe54183b148ab9a7429438a9 languageName: node linkType: hard "@babel/runtime-corejs3@npm:^7.10.2": - version: 7.26.10 - resolution: "@babel/runtime-corejs3@npm:7.26.10" + version: 7.27.0 + resolution: "@babel/runtime-corejs3@npm:7.27.0" dependencies: core-js-pure: "npm:^3.30.2" regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/897b61d84809d6e63e08566d436cd08a3a78f218283641bb53533948d4bcd5524c6a1f83613e20485cf7fa8d054da20dd9039d17e06c92cf282f25d4d4f57250 + checksum: 10c0/eff7ad45e9edca218fe1c43341b1493b84f1d5682dc3e300cae8392b2f80a5601d4d4a25da2d8236df4fec669d168ff87e71672d2f306a1b4da7d46680977367 languageName: node linkType: hard "@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2": - version: 7.26.10 - resolution: "@babel/runtime@npm:7.26.10" + version: 7.27.0 + resolution: "@babel/runtime@npm:7.27.0" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/6dc6d88c7908f505c4f7770fb4677dfa61f68f659b943c2be1f2a99cb6680343462867abf2d49822adc435932919b36c77ac60125793e719ea8745f2073d3745 + checksum: 10c0/35091ea9de48bd7fd26fb177693d64f4d195eb58ab2b142b893b7f3fa0f1d7c677604d36499ae0621a3703f35ba0c6a8f6c572cc8f7dc0317213841e493cf663 languageName: node linkType: hard -"@babel/template@npm:^7.10.4, @babel/template@npm:^7.25.9, @babel/template@npm:^7.26.9, @babel/template@npm:^7.3.3": - version: 7.26.9 - resolution: "@babel/template@npm:7.26.9" +"@babel/template@npm:^7.10.4, @babel/template@npm:^7.25.9, @babel/template@npm:^7.26.9, @babel/template@npm:^7.27.0, @babel/template@npm:^7.3.3": + version: 7.27.0 + resolution: "@babel/template@npm:7.27.0" dependencies: "@babel/code-frame": "npm:^7.26.2" - "@babel/parser": "npm:^7.26.9" - "@babel/types": "npm:^7.26.9" - checksum: 10c0/019b1c4129cc01ad63e17529089c2c559c74709d225f595eee017af227fee11ae8a97a6ab19ae6768b8aa22d8d75dcb60a00b28f52e9fa78140672d928bc1ae9 + "@babel/parser": "npm:^7.27.0" + "@babel/types": "npm:^7.27.0" + checksum: 10c0/13af543756127edb5f62bf121f9b093c09a2b6fe108373887ccffc701465cfbcb17e07cf48aa7f440415b263f6ec006e9415c79dfc2e8e6010b069435f81f340 languageName: node linkType: hard -"@babel/traverse@npm:^7.1.0, @babel/traverse@npm:^7.12.1, @babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.10, @babel/traverse@npm:^7.26.5, @babel/traverse@npm:^7.26.8, @babel/traverse@npm:^7.26.9, @babel/traverse@npm:^7.7.0": - version: 7.26.10 - resolution: "@babel/traverse@npm:7.26.10" +"@babel/traverse@npm:^7.1.0, @babel/traverse@npm:^7.12.1, @babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.10, @babel/traverse@npm:^7.26.5, @babel/traverse@npm:^7.26.8, @babel/traverse@npm:^7.27.0, @babel/traverse@npm:^7.7.0": + version: 7.27.0 + resolution: "@babel/traverse@npm:7.27.0" dependencies: "@babel/code-frame": "npm:^7.26.2" - "@babel/generator": "npm:^7.26.10" - "@babel/parser": "npm:^7.26.10" - "@babel/template": "npm:^7.26.9" - "@babel/types": "npm:^7.26.10" + "@babel/generator": "npm:^7.27.0" + "@babel/parser": "npm:^7.27.0" + "@babel/template": "npm:^7.27.0" + "@babel/types": "npm:^7.27.0" debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: 10c0/4e86bb4e3c30a6162bb91df86329df79d96566c3e2d9ccba04f108c30473a3a4fd360d9990531493d90f6a12004f10f616bf9b9229ca30c816b708615e9de2ac + checksum: 10c0/c7af29781960dacaae51762e8bc6c4b13d6ab4b17312990fbca9fc38e19c4ad7fecaae24b1cf52fb844e8e6cdc76c70ad597f90e496bcb3cc0a1d66b41a0aa5b languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.1, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.10, @babel/types@npm:^7.26.9, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.0": - version: 7.26.10 - resolution: "@babel/types@npm:7.26.10" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.1, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.0": + version: 7.27.0 + resolution: "@babel/types@npm:7.27.0" dependencies: "@babel/helper-string-parser": "npm:^7.25.9" "@babel/helper-validator-identifier": "npm:^7.25.9" - checksum: 10c0/7a7f83f568bfc3dfabfaf9ae3a97ab5c061726c0afa7dcd94226d4f84a81559da368ed79671e3a8039d16f12476cf110381a377ebdea07587925f69628200dac + checksum: 10c0/6f1592eabe243c89a608717b07b72969be9d9d2fce1dee21426238757ea1fa60fdfc09b29de9e48d8104311afc6e6fb1702565a9cc1e09bc1e76f2b2ddb0f6e1 languageName: node linkType: hard @@ -1876,7 +1876,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.1": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 @@ -3160,90 +3160,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-darwin-arm64@npm:1.11.8" +"@swc/core-darwin-arm64@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-darwin-arm64@npm:1.11.13" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-darwin-x64@npm:1.11.8" +"@swc/core-darwin-x64@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-darwin-x64@npm:1.11.13" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.11.8" +"@swc/core-linux-arm-gnueabihf@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.11.13" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-linux-arm64-gnu@npm:1.11.8" +"@swc/core-linux-arm64-gnu@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-linux-arm64-gnu@npm:1.11.13" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-linux-arm64-musl@npm:1.11.8" +"@swc/core-linux-arm64-musl@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-linux-arm64-musl@npm:1.11.13" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-linux-x64-gnu@npm:1.11.8" +"@swc/core-linux-x64-gnu@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-linux-x64-gnu@npm:1.11.13" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-linux-x64-musl@npm:1.11.8" +"@swc/core-linux-x64-musl@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-linux-x64-musl@npm:1.11.13" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-win32-arm64-msvc@npm:1.11.8" +"@swc/core-win32-arm64-msvc@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-win32-arm64-msvc@npm:1.11.13" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-win32-ia32-msvc@npm:1.11.8" +"@swc/core-win32-ia32-msvc@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-win32-ia32-msvc@npm:1.11.13" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.11.8": - version: 1.11.8 - resolution: "@swc/core-win32-x64-msvc@npm:1.11.8" +"@swc/core-win32-x64-msvc@npm:1.11.13": + version: 1.11.13 + resolution: "@swc/core-win32-x64-msvc@npm:1.11.13" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.9.1": - version: 1.11.8 - resolution: "@swc/core@npm:1.11.8" + version: 1.11.13 + resolution: "@swc/core@npm:1.11.13" dependencies: - "@swc/core-darwin-arm64": "npm:1.11.8" - "@swc/core-darwin-x64": "npm:1.11.8" - "@swc/core-linux-arm-gnueabihf": "npm:1.11.8" - "@swc/core-linux-arm64-gnu": "npm:1.11.8" - "@swc/core-linux-arm64-musl": "npm:1.11.8" - "@swc/core-linux-x64-gnu": "npm:1.11.8" - "@swc/core-linux-x64-musl": "npm:1.11.8" - "@swc/core-win32-arm64-msvc": "npm:1.11.8" - "@swc/core-win32-ia32-msvc": "npm:1.11.8" - "@swc/core-win32-x64-msvc": "npm:1.11.8" + "@swc/core-darwin-arm64": "npm:1.11.13" + "@swc/core-darwin-x64": "npm:1.11.13" + "@swc/core-linux-arm-gnueabihf": "npm:1.11.13" + "@swc/core-linux-arm64-gnu": "npm:1.11.13" + "@swc/core-linux-arm64-musl": "npm:1.11.13" + "@swc/core-linux-x64-gnu": "npm:1.11.13" + "@swc/core-linux-x64-musl": "npm:1.11.13" + "@swc/core-win32-arm64-msvc": "npm:1.11.13" + "@swc/core-win32-ia32-msvc": "npm:1.11.13" + "@swc/core-win32-x64-msvc": "npm:1.11.13" "@swc/counter": "npm:^0.1.3" "@swc/types": "npm:^0.1.19" peerDependencies: @@ -3272,7 +3272,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 10c0/2bd5787f81333b11212022fb90318cdc3911e8408b34f3324cd76ce43c48ffd2b9f91295ecbeda11b43dcd86a59404fab70d00e67c5dd26f71c6311ea1a3c1b1 + checksum: 10c0/cb27cd19a14a35b54deb4827fdc43cb8761678b651479d845928bdd485a6c5d7498d4d75d5b863eb5bacc439f6e1bc44886099d8063f04331f9029b7c89d6b99 languageName: node linkType: hard @@ -3297,11 +3297,11 @@ __metadata: linkType: hard "@swc/types@npm:^0.1.19": - version: 0.1.19 - resolution: "@swc/types@npm:0.1.19" + version: 0.1.20 + resolution: "@swc/types@npm:0.1.20" dependencies: "@swc/counter": "npm:^0.1.3" - checksum: 10c0/21b727d97d38f1bdbe9ef8fdf693bca19ebd5334ab32d7d2624a925d9adc8934935ad0f168cdbfd938b2f4b754a1fb7581f253bf47ab416177b6ac2c5c72578b + checksum: 10c0/bc1e548516ed700c25e92459851a0a0bb4f7a1cecb786faf9ba60ed41ba4d13fd075191f98108dfacdb5e9d3d27913184ed698e1344c40b2748f49a15236c537 languageName: node linkType: hard @@ -3416,11 +3416,11 @@ __metadata: linkType: hard "@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.4, @types/babel__traverse@npm:^7.0.6": - version: 7.20.6 - resolution: "@types/babel__traverse@npm:7.20.6" + version: 7.20.7 + resolution: "@types/babel__traverse@npm:7.20.7" dependencies: "@babel/types": "npm:^7.20.7" - checksum: 10c0/7ba7db61a53e28cac955aa99af280d2600f15a8c056619c05b6fc911cbe02c61aa4f2823299221b23ce0cce00b294c0e5f618ec772aa3f247523c2e48cf7b888 + checksum: 10c0/5386f0af44f8746b063b87418f06129a814e16bb2686965a575e9d7376b360b088b89177778d8c426012abc43dd1a2d8ec3218bfc382280c898682746ce2ffbd languageName: node linkType: hard @@ -3455,9 +3455,9 @@ __metadata: linkType: hard "@types/estree@npm:*, @types/estree@npm:^1.0.6": - version: 1.0.6 - resolution: "@types/estree@npm:1.0.6" - checksum: 10c0/cdfd751f6f9065442cd40957c07fd80361c962869aa853c1c2fd03e101af8b9389d8ff4955a43a6fcfa223dd387a089937f95be0f3eec21ca527039fd2d9859a + version: 1.0.7 + resolution: "@types/estree@npm:1.0.7" + checksum: 10c0/be815254316882f7c40847336cd484c3bc1c3e34f710d197160d455dc9d6d050ffbf4c3bc76585dba86f737f020ab20bdb137ebe0e9116b0c86c7c0342221b8c languageName: node linkType: hard @@ -3569,11 +3569,11 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:^22.9.0": - version: 22.13.10 - resolution: "@types/node@npm:22.13.10" + version: 22.13.14 + resolution: "@types/node@npm:22.13.14" dependencies: undici-types: "npm:~6.20.0" - checksum: 10c0/a3865f9503d6f718002374f7b87efaadfae62faa499c1a33b12c527cfb9fd86f733e1a1b026b80c5a0e4a965701174bc3305595a7d36078aa1abcf09daa5dee9 + checksum: 10c0/fa2ab5b8277bfbcc86c42e46a3ea9871b0d559894cc9d955685d17178c9499f0b1bf03d1d1ea8d92ef2dda818988f4035acb8abf9dc15423a998fa56173ab804 languageName: node linkType: hard @@ -3622,12 +3622,12 @@ __metadata: linkType: hard "@types/react@npm:^18.3.12": - version: 18.3.18 - resolution: "@types/react@npm:18.3.18" + version: 18.3.20 + resolution: "@types/react@npm:18.3.20" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10c0/8fb2b00672072135d0858dc9db07873ea107cc238b6228aaa2a9afd1ef7a64a7074078250db38afbeb19064be8ea6af5eac32d404efdd5f45e093cc4829d87f8 + checksum: 10c0/65fa867c91357e4c4c646945c8b99044360f8973cb7f928ec4de115fe3207827985d45be236e6fd6c092b09f631c2126ce835c137be30718419e143d73300d8f languageName: node linkType: hard @@ -3766,6 +3766,50 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/eslint-plugin@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.18.0" + dependencies: + "@eslint-community/regexpp": "npm:^4.10.0" + "@typescript-eslint/scope-manager": "npm:7.18.0" + "@typescript-eslint/type-utils": "npm:7.18.0" + "@typescript-eslint/utils": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" + graphemer: "npm:^1.4.0" + ignore: "npm:^5.3.1" + natural-compare: "npm:^1.4.0" + ts-api-utils: "npm:^1.3.0" + peerDependencies: + "@typescript-eslint/parser": ^7.0.0 + eslint: ^8.56.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/2b37948fa1b0dab77138909dabef242a4d49ab93e4019d4ef930626f0a7d96b03e696cd027fa0087881c20e73be7be77c942606b4a76fa599e6b37f6985304c3 + languageName: node + linkType: hard + +"@typescript-eslint/eslint-plugin@npm:8.28.0": + version: 8.28.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.28.0" + dependencies: + "@eslint-community/regexpp": "npm:^4.10.0" + "@typescript-eslint/scope-manager": "npm:8.28.0" + "@typescript-eslint/type-utils": "npm:8.28.0" + "@typescript-eslint/utils": "npm:8.28.0" + "@typescript-eslint/visitor-keys": "npm:8.28.0" + graphemer: "npm:^1.4.0" + ignore: "npm:^5.3.1" + natural-compare: "npm:^1.4.0" + ts-api-utils: "npm:^2.0.1" + peerDependencies: + "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/f01b7d231b01ec2c1cc7c40599ddceb329532f2876664a39dec9d25c0aed4cfdbef3ec07f26bac357df000d798f652af6fdb6a2481b6120e43bfa38f7c7a7c48 + languageName: node + linkType: hard + "@typescript-eslint/eslint-plugin@npm:^4.5.0": version: 4.33.0 resolution: "@typescript-eslint/eslint-plugin@npm:4.33.0" @@ -3819,6 +3863,22 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/parser@npm:8.28.0, @typescript-eslint/parser@npm:^8.13.0": + version: 8.28.0 + resolution: "@typescript-eslint/parser@npm:8.28.0" + dependencies: + "@typescript-eslint/scope-manager": "npm:8.28.0" + "@typescript-eslint/types": "npm:8.28.0" + "@typescript-eslint/typescript-estree": "npm:8.28.0" + "@typescript-eslint/visitor-keys": "npm:8.28.0" + debug: "npm:^4.3.4" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/4bde6887bbf3fe031c01e46db90f9f384a8cac2e67c2972b113a62d607db75e01db943601279aac847b9187960a038981814042cb02fd5aa27ea4613028f9313 + languageName: node + linkType: hard + "@typescript-eslint/parser@npm:^4.5.0": version: 4.33.0 resolution: "@typescript-eslint/parser@npm:4.33.0" @@ -3836,22 +3896,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^8.13.0": - version: 8.26.1 - resolution: "@typescript-eslint/parser@npm:8.26.1" - dependencies: - "@typescript-eslint/scope-manager": "npm:8.26.1" - "@typescript-eslint/types": "npm:8.26.1" - "@typescript-eslint/typescript-estree": "npm:8.26.1" - "@typescript-eslint/visitor-keys": "npm:8.26.1" - debug: "npm:^4.3.4" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/21fe4306b6017bf183d92cdd493edacd302816071e29e1400452f3ccd224ab8111b75892507b9731545e98e6e4d153e54dab568b3433f6c9596b6cb2f7af922f - languageName: node - linkType: hard - "@typescript-eslint/scope-manager@npm:4.33.0": version: 4.33.0 resolution: "@typescript-eslint/scope-manager@npm:4.33.0" @@ -3862,13 +3906,55 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.26.1": - version: 8.26.1 - resolution: "@typescript-eslint/scope-manager@npm:8.26.1" +"@typescript-eslint/scope-manager@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/scope-manager@npm:7.18.0" dependencies: - "@typescript-eslint/types": "npm:8.26.1" - "@typescript-eslint/visitor-keys": "npm:8.26.1" - checksum: 10c0/ecd30eb615c7384f01cea8f2c8e8dda7507ada52ad0d002d3701bdd9d06f6d14cefb31c6c26ef55708adfaa2045a01151e8685656240268231a4bac8f792afe4 + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" + checksum: 10c0/038cd58c2271de146b3a594afe2c99290034033326d57ff1f902976022c8b0138ffd3cb893ae439ae41003b5e4bcc00cabf6b244ce40e8668f9412cc96d97b8e + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:8.28.0": + version: 8.28.0 + resolution: "@typescript-eslint/scope-manager@npm:8.28.0" + dependencies: + "@typescript-eslint/types": "npm:8.28.0" + "@typescript-eslint/visitor-keys": "npm:8.28.0" + checksum: 10c0/f3bd76b3f54e60f1efe108b233b2d818e44ecf0dc6422cc296542f784826caf3c66d51b8acc83d8c354980bd201e1d9aa1ea01011de96e0613d320c00e40ccfd + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/type-utils@npm:7.18.0" + dependencies: + "@typescript-eslint/typescript-estree": "npm:7.18.0" + "@typescript-eslint/utils": "npm:7.18.0" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^1.3.0" + peerDependencies: + eslint: ^8.56.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/ad92a38007be620f3f7036f10e234abdc2fdc518787b5a7227e55fd12896dacf56e8b34578723fbf9bea8128df2510ba8eb6739439a3879eda9519476d5783fd + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:8.28.0": + version: 8.28.0 + resolution: "@typescript-eslint/type-utils@npm:8.28.0" + dependencies: + "@typescript-eslint/typescript-estree": "npm:8.28.0" + "@typescript-eslint/utils": "npm:8.28.0" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^2.0.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/b8936edc2153bf794efba39bfb06393a228217830051767360f4b691fed7c82f3831c4fc6deac6d78b90a58596e61f866c17eaee9dd793c3efda3ebdcf5a71d8 languageName: node linkType: hard @@ -3886,10 +3972,17 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:8.26.1": - version: 8.26.1 - resolution: "@typescript-eslint/types@npm:8.26.1" - checksum: 10c0/805b239b57854fc12eae9e2bec6ccab24bac1d30a762c455f22c73b777a5859c64c58b4750458bd0ab4aadd664eb95cbef091348a071975acac05b15ebea9f1b +"@typescript-eslint/types@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/types@npm:7.18.0" + checksum: 10c0/eb7371ac55ca77db8e59ba0310b41a74523f17e06f485a0ef819491bc3dd8909bb930120ff7d30aaf54e888167e0005aa1337011f3663dc90fb19203ce478054 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:8.28.0": + version: 8.28.0 + resolution: "@typescript-eslint/types@npm:8.28.0" + checksum: 10c0/1f95895e20dac1cf063dc93c99142fd1871e53be816bcbbee93f22a05e6b2a82ca83c20ce3a551f65555910aa0956443a23268edbb004369d0d5cb282d13c377 languageName: node linkType: hard @@ -3930,12 +4023,31 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.26.1": - version: 8.26.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.26.1" +"@typescript-eslint/typescript-estree@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" dependencies: - "@typescript-eslint/types": "npm:8.26.1" - "@typescript-eslint/visitor-keys": "npm:8.26.1" + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" + debug: "npm:^4.3.4" + globby: "npm:^11.1.0" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/0c7f109a2e460ec8a1524339479cf78ff17814d23c83aa5112c77fb345e87b3642616291908dcddea1e671da63686403dfb712e4a4435104f92abdfddf9aba81 + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:8.28.0": + version: 8.28.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.28.0" + dependencies: + "@typescript-eslint/types": "npm:8.28.0" + "@typescript-eslint/visitor-keys": "npm:8.28.0" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" @@ -3944,22 +4056,36 @@ __metadata: ts-api-utils: "npm:^2.0.1" peerDependencies: typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/adc95e4735a8ded05ad35d7b4fae68c675afdd4b3531bc4a51eab5efe793cf80bc75f56dfc8022af4c0a5b316eec61f8ce6b77c2ead45fc675fea7e28cd52ade + checksum: 10c0/97a91c95b1295926098c12e2d2c2abaa68994dc879da132dcce1e75ec9d7dee8187695eaa5241d09cbc42b5e633917b6d35c624e78e3d3ee9bda42d1318080b6 languageName: node linkType: hard -"@typescript-eslint/utils@npm:^8.13.0": - version: 8.26.1 - resolution: "@typescript-eslint/utils@npm:8.26.1" +"@typescript-eslint/utils@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/utils@npm:7.18.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.26.1" - "@typescript-eslint/types": "npm:8.26.1" - "@typescript-eslint/typescript-estree": "npm:8.26.1" + "@typescript-eslint/scope-manager": "npm:7.18.0" + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/typescript-estree": "npm:7.18.0" + peerDependencies: + eslint: ^8.56.0 + checksum: 10c0/a25a6d50eb45c514469a01ff01f215115a4725fb18401055a847ddf20d1b681409c4027f349033a95c4ff7138d28c3b0a70253dfe8262eb732df4b87c547bd1e + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:8.28.0, @typescript-eslint/utils@npm:^8.13.0": + version: 8.28.0 + resolution: "@typescript-eslint/utils@npm:8.28.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.4.0" + "@typescript-eslint/scope-manager": "npm:8.28.0" + "@typescript-eslint/types": "npm:8.28.0" + "@typescript-eslint/typescript-estree": "npm:8.28.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/a5cb3bdf253cc8e8474a2ed8666c0a6194abe56f44039c6623bef0459ed17d0276ed6e40c70d35bd8ec4d41bafc255e4d3025469f32ac692ba2d89e7579c2a26 + checksum: 10c0/d3425be7f86c1245a11f0ea39136af681027797417348d8e666d38c76646945eaed7b35eb8db66372b067dee8b02a855caf2c24c040ec9c31e59681ab223b59d languageName: node linkType: hard @@ -3982,13 +4108,23 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.26.1": - version: 8.26.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.26.1" +"@typescript-eslint/visitor-keys@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.18.0" dependencies: - "@typescript-eslint/types": "npm:8.26.1" + "@typescript-eslint/types": "npm:7.18.0" + eslint-visitor-keys: "npm:^3.4.3" + checksum: 10c0/538b645f8ff1d9debf264865c69a317074eaff0255e63d7407046176b0f6a6beba34a6c51d511f12444bae12a98c69891eb6f403c9f54c6c2e2849d1c1cb73c0 + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:8.28.0": + version: 8.28.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.28.0" + dependencies: + "@typescript-eslint/types": "npm:8.28.0" eslint-visitor-keys: "npm:^4.2.0" - checksum: 10c0/51b1016d06cd2b9eac0a213de418b0a26022fd3b71478014541bfcbc2a3c4d666552390eb9c209fa9e52c868710d9f1b21a2c789d35c650239438c366a27a239 + checksum: 10c0/245a78ed983fe95fbd1b0f2d4cb9e9d1d964bddc0aa3e3d6ab10c19c4273855bfb27d840bb1fd55deb7ae3078b52f26592472baf6fd2c7019a5aa3b1da974f35 languageName: node linkType: hard @@ -6058,9 +6194,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001125, caniuse-lite@npm:^1.0.30001688": - version: 1.0.30001703 - resolution: "caniuse-lite@npm:1.0.30001703" - checksum: 10c0/ed88e318da28e9e59c4ac3a2e3c42859558b7b713aebf03696a1f916e4ed4b70734dda82be04635e2b62ec355b8639bbed829b7b12ff528d7f9cc31a3a5bea91 + version: 1.0.30001707 + resolution: "caniuse-lite@npm:1.0.30001707" + checksum: 10c0/a1beaf84bad4f6617bbc5616d6bc0c9cab73e73f7e9e09b6466af5195b1bc393e0f6f19643d7a1c88bd3f4bfa122d7bea81cf6225ec3ade57d5b1dd3478c1a1b languageName: node linkType: hard @@ -7884,9 +8020,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.3.564, electron-to-chromium@npm:^1.5.73": - version: 1.5.114 - resolution: "electron-to-chromium@npm:1.5.114" - checksum: 10c0/cb86057d78f1aeb53ab6550dedacfd9496bcc6676bab7b48466c3958ba9ce0ed78c7213b1eab99ba38542cbaaa176eb7f8ea8b0274c0688b8ce3058291549430 + version: 1.5.127 + resolution: "electron-to-chromium@npm:1.5.127" + checksum: 10c0/e8525538ed5c90d25e53b901fc404241b406b724150a5439dec89be569b5ccfab7d6f8e482370ec9f94aa07717094ef354833aabf08fef097b5d49d656e2cfa2 languageName: node linkType: hard @@ -9332,8 +9468,8 @@ __metadata: linkType: hard "fastify@npm:^5.1.0": - version: 5.2.1 - resolution: "fastify@npm:5.2.1" + version: 5.2.2 + resolution: "fastify@npm:5.2.2" dependencies: "@fastify/ajv-compiler": "npm:^4.0.0" "@fastify/error": "npm:^4.0.0" @@ -9350,7 +9486,7 @@ __metadata: secure-json-parse: "npm:^3.0.1" semver: "npm:^7.6.0" toad-cache: "npm:^3.7.0" - checksum: 10c0/00163bcac121e5fcb097dec0230d8e7918f0d5aa4be1ddce87f6571a13d31c9691d20def5dbd12df047bc3fc372cb0a72a392feecf3e2c958dc0931e52d262cb + checksum: 10c0/2925f6b8370f72f86c1461645cdf6895f335c30b3fca37deed70339f568e77f7d69e83656dc11994d70b239319a63615673714db3111363bd5f83a3e56424a88 languageName: node linkType: hard @@ -10131,7 +10267,7 @@ __metadata: languageName: node linkType: hard -"globby@npm:^11.0.3": +"globby@npm:^11.0.3, globby@npm:^11.1.0": version: 11.1.0 resolution: "globby@npm:11.1.0" dependencies: @@ -10775,7 +10911,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.1.4, ignore@npm:^5.1.8, ignore@npm:^5.2.0": +"ignore@npm:^5.1.4, ignore@npm:^5.1.8, ignore@npm:^5.2.0, ignore@npm:^5.3.1": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 @@ -10790,9 +10926,9 @@ __metadata: linkType: hard "immutable@npm:^5.0.2": - version: 5.0.3 - resolution: "immutable@npm:5.0.3" - checksum: 10c0/3269827789e1026cd25c2ea97f0b2c19be852ffd49eda1b674b20178f73d84fa8d945ad6f5ac5bc4545c2b4170af9f6e1f77129bc1cae7974a4bf9b04a9cdfb9 + version: 5.1.1 + resolution: "immutable@npm:5.1.1" + checksum: 10c0/5fd129ee9e448884003cc4f9e43bb91bab3b39dfeb3b49ddfb8bd563e0620eb47ae1f5b3ef96615d3ec38b52ab9a966dcacf9e39df00ed1a8ad062ddfba01cdf languageName: node linkType: hard @@ -13300,9 +13436,9 @@ __metadata: linkType: hard "lru-cache@npm:^11.0.0": - version: 11.0.2 - resolution: "lru-cache@npm:11.0.2" - checksum: 10c0/c993b8e06ead0b24b969c1dbb5b301716aed66e320e9014a80012f5febe280b438f28ff50046b2c55ff404e889351ccb332ff91f8dd175a21f5eae80e3fb155f + version: 11.1.0 + resolution: "lru-cache@npm:11.1.0" + checksum: 10c0/85c312f7113f65fae6a62de7985348649937eb34fb3d212811acbf6704dc322a421788aca253b62838f1f07049a84cc513d88f494e373d3756514ad263670a64 languageName: node linkType: hard @@ -15086,9 +15222,9 @@ __metadata: linkType: hard "pirates@npm:^4.0.1, pirates@npm:^4.0.4": - version: 4.0.6 - resolution: "pirates@npm:4.0.6" - checksum: 10c0/00d5fa51f8dded94d7429700fb91a0c1ead00ae2c7fd27089f0c5b63e6eca36197fe46384631872690a66f390c5e27198e99006ab77ae472692ab9c2ca903f36 + version: 4.0.7 + resolution: "pirates@npm:4.0.7" + checksum: 10c0/a51f108dd811beb779d58a76864bbd49e239fa40c7984cd11596c75a121a8cc789f1c8971d8bb15f0dbf9d48b76c05bb62fcbce840f89b688c0fa64b37e8478a languageName: node linkType: hard @@ -19174,6 +19310,7 @@ __metadata: "@types/react-dom": "npm:^18.3.1" "@types/webpack-env": "npm:^1.18.5" "@types/wicg-file-system-access": "npm:^2023.10.5" + "@typescript-eslint/eslint-plugin": "npm:7.18.0" "@typescript-eslint/parser": "npm:^8.13.0" "@typescript-eslint/utils": "npm:^8.13.0" css-loader: "npm:^7.1.2" @@ -19199,6 +19336,7 @@ __metadata: swc-loader: "npm:^0.2.6" tgui-core: "npm:^1.8.2" typescript: "npm:5.6.3" + typescript-eslint: "npm:^8.28.0" url-loader: "npm:^4.1.1" webpack: "npm:^5.96.1" webpack-bundle-analyzer: "npm:^4.10.2" @@ -19438,6 +19576,15 @@ __metadata: languageName: node linkType: hard +"ts-api-utils@npm:^1.3.0": + version: 1.4.3 + resolution: "ts-api-utils@npm:1.4.3" + peerDependencies: + typescript: ">=4.2.0" + checksum: 10c0/e65dc6e7e8141140c23e1dc94984bf995d4f6801919c71d6dc27cf0cd51b100a91ffcfe5217626193e5bea9d46831e8586febdc7e172df3f1091a7384299e23a + languageName: node + linkType: hard + "ts-api-utils@npm:^2.0.1": version: 2.0.1 resolution: "ts-api-utils@npm:2.0.1" @@ -19692,6 +19839,20 @@ __metadata: languageName: node linkType: hard +"typescript-eslint@npm:^8.28.0": + version: 8.28.0 + resolution: "typescript-eslint@npm:8.28.0" + dependencies: + "@typescript-eslint/eslint-plugin": "npm:8.28.0" + "@typescript-eslint/parser": "npm:8.28.0" + "@typescript-eslint/utils": "npm:8.28.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/bf1c1e4b2f21a95930758d5b285c39a394a50e3b6983f373413b93b80a6cb5aabc1d741780e60c63cb42ad5d645ea9c1e6d441d98174c5a2884ab88f4ac46df6 + languageName: node + linkType: hard + "typescript@npm:5.6.3": version: 5.6.3 resolution: "typescript@npm:5.6.3" diff --git a/vorestation.dme b/vorestation.dme index 1b646413d1..8697f6e8f5 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -182,6 +182,7 @@ #include "code\__defines\vote.dm" #include "code\__defines\vv.dm" #include "code\__defines\webhooks.dm" +#include "code\__defines\wiki.dm" #include "code\__defines\wires.dm" #include "code\__defines\xenoarcheaology.dm" #include "code\__defines\ZAS.dm" @@ -403,6 +404,7 @@ #include "code\controllers\subsystems\holomaps.dm" #include "code\controllers\subsystems\inactivity.dm" #include "code\controllers\subsystems\input.dm" +#include "code\controllers\subsystems\internal_wiki.dm" #include "code\controllers\subsystems\job.dm" #include "code\controllers\subsystems\lighting.dm" #include "code\controllers\subsystems\machines.dm" @@ -2968,6 +2970,7 @@ #include "code\modules\keybindings\setup.dm" #include "code\modules\library\lib_items.dm" #include "code\modules\library\lib_machines.dm" +#include "code\modules\library\wikicomp.dm" #include "code\modules\library\hardcode_library\_library.dm" #include "code\modules\library\hardcode_library\fiction\APsychonaut.dm" #include "code\modules\library\hardcode_library\fiction\battlefieldcommander.dm"