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]
(props: {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/ServerPreferencesFetcher.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/ServerPreferencesFetcher.tsx
index 4c20918d98..4615b66859 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/ServerPreferencesFetcher.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/ServerPreferencesFetcher.tsx
@@ -1,4 +1,4 @@
-import { Component, ReactNode } from 'react';
+import { Component, type ReactNode } from 'react';
import { resolveAsset } from 'tgui/assets';
import { fetchRetry } from 'tgui-core/http';
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/TabbedMenu.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/TabbedMenu.tsx
index 34091267c0..c576966e68 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/TabbedMenu.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/TabbedMenu.tsx
@@ -1,9 +1,9 @@
import {
Component,
- ComponentProps,
+ type ComponentProps,
createRef,
- ReactNode,
- RefObject,
+ type ReactNode,
+ type RefObject,
} from 'react';
import { Button, Section, Stack } from 'tgui-core/components';
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/abductor.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/abductor.ts
index 789e5e9823..4acc98e555 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/abductor.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/abductor.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const Abductor: Antagonist = {
key: 'abductor',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/blob.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/blob.ts
index 92cd5bdc44..fa8511ec58 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/blob.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/blob.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
export const BLOB_MECHANICAL_DESCRIPTION = `
The blob infests the station and destroys everything in its path, including
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/blobinfection.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/blobinfection.ts
index d8a5f135fe..6fab0ea65b 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/blobinfection.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/blobinfection.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { BLOB_MECHANICAL_DESCRIPTION } from './blob';
const BlobInfection: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodbrother.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodbrother.ts
index 56cbcbfc97..c3fabde185 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodbrother.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodbrother.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const BloodBrother: Antagonist = {
key: 'bloodbrother',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/changeling.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/changeling.ts
index 9124a07063..78106f5f5a 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/changeling.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/changeling.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
export const CHANGELING_MECHANICAL_DESCRIPTION = `
Transform yourself or others into different identities, and buy from an
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/changelingmidround.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/changelingmidround.ts
index 8324bdb858..ca581512d2 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/changelingmidround.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/changelingmidround.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { CHANGELING_MECHANICAL_DESCRIPTION } from './changeling';
const ChangelingMidround: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/clownoperative.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/clownoperative.ts
index 61f874a2e9..8917d49d9c 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/clownoperative.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/clownoperative.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { OPERATIVE_MECHANICAL_DESCRIPTION } from './operative';
const ClownOperative: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/cultist.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/cultist.ts
index c5cfaf61c2..2005dd9b64 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/cultist.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/cultist.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const Cultist: Antagonist = {
key: 'cultist',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/fugitive.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/fugitive.ts
index f05a96c2ec..14bd224290 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/fugitive.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/fugitive.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const Fugitive: Antagonist = {
key: 'fugitive',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/glitch.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/glitch.ts
index 3d269c54ca..954a3d5842 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/glitch.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/glitch.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const Glitch: Antagonist = {
key: 'glitch',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/headrevolutionary.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/headrevolutionary.ts
index 0a1d644266..6d0b8362a7 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/headrevolutionary.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/headrevolutionary.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
export const REVOLUTIONARY_MECHANICAL_DESCRIPTION = `
Armed with a flash, convert as many people to the revolution as you can.
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/heretic.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/heretic.ts
index 8c2d631bd5..dae865096c 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/heretic.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/heretic.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
export const HERETIC_MECHANICAL_DESCRIPTION = `
Find hidden influences and sacrifice crew members to gain magical
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/hereticsmuggler.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/hereticsmuggler.ts
index 6ce90a3552..bde3be6717 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/hereticsmuggler.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/hereticsmuggler.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { HERETIC_MECHANICAL_DESCRIPTION } from './heretic';
const HereticSmuggler: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/loneoperative.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/loneoperative.ts
index 3f8ac5c5b7..e83f8fa07d 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/loneoperative.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/loneoperative.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { OPERATIVE_MECHANICAL_DESCRIPTION } from './operative';
const LoneOperative: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/malfai.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/malfai.ts
index 03aadd752c..e7e7218cd6 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/malfai.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/malfai.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
export const MALF_AI_MECHANICAL_DESCRIPTION = `
With a law zero to complete your objectives at all costs, combine your
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/malfaimidround.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/malfaimidround.ts
index 84e52b43dc..9133546bd6 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/malfaimidround.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/malfaimidround.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { MALF_AI_MECHANICAL_DESCRIPTION } from './malfai';
const MalfAIMidround: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/nightmare.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/nightmare.ts
index 90046dd625..fcb2fe4150 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/nightmare.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/nightmare.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const Nightmare: Antagonist = {
key: 'nightmare',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/obsessed.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/obsessed.ts
index 8d4c981398..cbb57f03b2 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/obsessed.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/obsessed.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const Obsessed: Antagonist = {
key: 'obsessed',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/operative.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/operative.ts
index a8182de9e0..06b0e27f47 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/operative.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/operative.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
export const OPERATIVE_MECHANICAL_DESCRIPTION = `
Retrieve the nuclear authentication disk, use it to activate the nuclear
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/operativemidround.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/operativemidround.ts
index 7497c6442f..d46484d0ec 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/operativemidround.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/operativemidround.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { OPERATIVE_MECHANICAL_DESCRIPTION } from './operative';
const OperativeMidround: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/paradoxclone.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/paradoxclone.ts
index 1456df3ec6..8104e3798f 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/paradoxclone.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/paradoxclone.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const ParadoxClone: Antagonist = {
key: 'paradoxclone',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/provocateur.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/provocateur.ts
index 1d2879c867..51f887dc61 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/provocateur.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/provocateur.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { REVOLUTIONARY_MECHANICAL_DESCRIPTION } from './headrevolutionary';
const Provocateur: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/revenant.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/revenant.ts
index 241b52b3e4..642942a668 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/revenant.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/revenant.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const Revenant: Antagonist = {
key: 'revenant',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/sentiencepotionspawn.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/sentiencepotionspawn.ts
index e69db3bec3..8a53721c93 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/sentiencepotionspawn.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/sentiencepotionspawn.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const SentientCreature: Antagonist = {
key: 'sentiencepotionspawn',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spacedragon.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spacedragon.ts
index 4a11cc94d1..8681020495 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spacedragon.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spacedragon.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const SpaceDragon: Antagonist = {
key: 'spacedragon',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spaceninja.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spaceninja.ts
index e6db1b96f9..1402da62a0 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spaceninja.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spaceninja.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const SpaceNinja: Antagonist = {
key: 'spaceninja',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spy.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spy.ts
index b004b972d4..843a201f97 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spy.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/spy.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const Spy: Antagonist = {
key: 'spy',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/stowawaychangeling.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/stowawaychangeling.ts
index 20ba22ee07..f22b7208df 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/stowawaychangeling.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/stowawaychangeling.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { CHANGELING_MECHANICAL_DESCRIPTION } from './changeling';
const Stowaway_Changeling: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/syndicateinfiltrator.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/syndicateinfiltrator.ts
index 45ad29292b..f35e50057e 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/syndicateinfiltrator.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/syndicateinfiltrator.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { TRAITOR_MECHANICAL_DESCRIPTION } from './traitor';
const SyndicateInfiltrator: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/syndicatesleeperagent.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/syndicatesleeperagent.ts
index 4a680e5d34..1e6374c400 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/syndicatesleeperagent.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/syndicatesleeperagent.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { TRAITOR_MECHANICAL_DESCRIPTION } from './traitor';
const SyndicateSleeperAgent: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/traitor.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/traitor.ts
index ccb6391998..025b727f81 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/traitor.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/traitor.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
export const TRAITOR_MECHANICAL_DESCRIPTION = `
Start with an uplink to purchase your gear and take on your sinister
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/wizard.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/wizard.ts
index 62530a26f6..b59e3f4cd7 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/wizard.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/wizard.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
export const WIZARD_MECHANICAL_DESCRIPTION = `
Choose between a variety of powerful spells in order to cause chaos
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/wizardmidround.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/wizardmidround.ts
index b36a9f5170..6161e14752 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/wizardmidround.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/wizardmidround.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
import { WIZARD_MECHANICAL_DESCRIPTION } from './wizard';
const WizardMidround: Antagonist = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/xenomorph.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/xenomorph.ts
index a9a1960f3b..2fecacca9e 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/xenomorph.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/xenomorph.ts
@@ -1,4 +1,4 @@
-import { Antagonist, Category } from '../base';
+import { type Antagonist, Category } from '../base';
const Xenomorph: Antagonist = {
key: 'xenomorph',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/data.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/data.ts
index ff8d1b112a..46cd6ff967 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/data.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/data.ts
@@ -1,4 +1,4 @@
-import { sendAct } from '../../backend';
+import type { sendAct } from '../../backend';
export enum GamePreferencesSelectedPage {
Settings,
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/index.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/index.tsx
index 9f22976aa6..22df23192c 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/index.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/index.tsx
@@ -5,7 +5,7 @@ import { useBackend } from 'tgui/backend';
// import { CharacterPreferenceWindow } from './CharacterPreferenceWindow';
import {
GamePreferencesSelectedPage,
- PreferencesMenuData,
+ type PreferencesMenuData,
Window,
} from './data';
import { GamePreferenceWindow } from './GamePreferenceWindow';
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx
index b427f5ab11..8f5a4b34da 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx
@@ -1,12 +1,12 @@
import {
- ComponentType,
+ type ComponentType,
createElement,
- ReactNode,
+ type ReactNode,
useEffect,
useState,
} from 'react';
import React from 'react';
-import { sendAct, useBackend } from 'tgui/backend';
+import { type sendAct, useBackend } from 'tgui/backend';
import {
Box,
Button,
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dropdowns.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dropdowns.tsx
index cf4959ce62..df1f20e8f3 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dropdowns.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dropdowns.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { Box, Dropdown, Stack } from 'tgui-core/components';
import { classes } from 'tgui-core/react';
import { capitalizeFirst } from 'tgui-core/string';
@@ -37,7 +37,7 @@ export function FeatureDropdownInput(props: DropdownInputProps) {
const { choices, display_names } = serverData;
const dropdownOptions = choices.map((choice) => {
- let displayText: ReactNode = display_names
+ const displayText: ReactNode = display_names
? display_names[choice]
: capitalizeFirst(choice);
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx
index 62098710d8..df7b9e9c84 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx
@@ -1,8 +1,8 @@
import {
CheckboxInput,
- Feature,
+ type Feature,
FeatureColorInput,
- FeatureToggle,
+ type FeatureToggle,
} from '../base';
export const CHAT_ATTACKLOGS: FeatureToggle = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/adult.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/adult.tsx
index 7c212d8c73..c1a3b429bb 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/adult.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/adult.tsx
@@ -1,4 +1,4 @@
-import { CheckboxInput, FeatureToggle } from '../base';
+import { CheckboxInput, type FeatureToggle } from '../base';
// Vorey sounds
export const BELCH_NOISES: FeatureToggle = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/auto_fit_viewport.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/auto_fit_viewport.tsx
index 696b7534d2..a8c92784d9 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/auto_fit_viewport.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/auto_fit_viewport.tsx
@@ -1,4 +1,4 @@
-import { CheckboxInput, FeatureToggle } from '../base';
+import { CheckboxInput, type FeatureToggle } from '../base';
export const auto_fit_viewport: FeatureToggle = {
name: 'Auto fit viewport',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/chat.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/chat.tsx
index 71a00a535f..e7af497841 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/chat.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/chat.tsx
@@ -1,4 +1,4 @@
-import { CheckboxInput, FeatureToggle } from '../base';
+import { CheckboxInput, type FeatureToggle } from '../base';
export const CHAT_SHOWICONS: FeatureToggle = {
name: 'Chat Tags',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx
index 10cc2297af..ec90d173a0 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx
@@ -1,4 +1,4 @@
-import { CheckboxInput, FeatureToggle } from '../base';
+import { CheckboxInput, type FeatureToggle } from '../base';
export const WHISUBTLE_VIS: FeatureToggle = {
name: 'Allow ghosts to see whispers/subtles',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/misc.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/misc.tsx
index 30af7c11b3..a0da3a9422 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/misc.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/misc.tsx
@@ -1,4 +1,4 @@
-import { CheckboxInput, FeatureToggle } from '../base';
+import { CheckboxInput, type FeatureToggle } from '../base';
export const AMBIENT_OCCLUSION_PREF: FeatureToggle = {
name: 'Enable ambient occlusion',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/runechat.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/runechat.tsx
index 832c3d79fe..97a6f72bad 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/runechat.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/runechat.tsx
@@ -1,4 +1,4 @@
-import { CheckboxInput, FeatureToggle } from '../base';
+import { CheckboxInput, type FeatureToggle } from '../base';
export const RUNECHAT_MOB: FeatureToggle = {
name: 'Runechat: Mobs',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sound.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sound.tsx
index 5284e1435e..fa8cb8095b 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sound.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sound.tsx
@@ -1,8 +1,8 @@
import {
CheckboxInput,
FeatureNumberInput,
- FeatureNumeric,
- FeatureToggle,
+ type FeatureNumeric,
+ type FeatureToggle,
} from '../base';
export const SOUND_MIDI: FeatureToggle = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/tooltip.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/tooltip.tsx
index 52527bd0fe..5d6a484314 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/tooltip.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/tooltip.tsx
@@ -1,4 +1,8 @@
-import { CheckboxInput, FeatureChoiced, FeatureToggle } from '../base';
+import {
+ CheckboxInput,
+ type FeatureChoiced,
+ type FeatureToggle,
+} from '../base';
import { FeatureDropdownInput } from '../dropdowns';
export const MOB_TOOLTIPS: FeatureToggle = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui.tsx
index f9be483363..e37e1a0b09 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui.tsx
@@ -1,8 +1,8 @@
import {
CheckboxInput,
- FeatureNumeric,
+ type FeatureNumeric,
FeatureSliderInput,
- FeatureToggle,
+ type FeatureToggle,
} from '../base';
export const BROWSER_STYLED: FeatureToggle = {
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx
index 0257674f76..b28d67f5f0 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx
@@ -2,13 +2,13 @@ import { Box, Dropdown, Stack } from 'tgui-core/components';
import { classes } from 'tgui-core/react';
import {
- Feature,
- FeatureChoiced,
- FeatureChoicedServerData,
+ type Feature,
+ type FeatureChoiced,
+ type FeatureChoicedServerData,
FeatureColorInput,
FeatureNumberInput,
- FeatureNumeric,
- FeatureValueProps,
+ type FeatureNumeric,
+ type FeatureValueProps,
sortChoices,
} from '../base';
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/index.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/index.ts
index 8b49759534..fcfd3c4d03 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/index.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/index.ts
@@ -3,7 +3,7 @@
// extremely small, and so it's easier for everyone to just combine them
// together.
// This still helps to prevent the server from needing to send client UI data
-import { Feature } from './base';
+import type { Feature } from './base';
// while also preventing downstreams from needing to mutate existing files.
const features: Record tag
+ const bitmap = await offscreenCanvas.convertToBlob();
+ setBitmap(URL.createObjectURL(bitmap));
+ };
+
+ drawImage();
+
+ return () => {
+ if (bitmap !== '') {
+ URL.revokeObjectURL(bitmap);
+ }
+ };
+ }, [props.render]);
+
+ return
;
+};
+
+export const ColorizedImage = (props: {
+ icon: string | null;
+ iconState: string | null;
+ fillLevel?: number;
+ color?: string | null;
+}) => {
+ const { icon, iconState, color, fillLevel = 1 } = props;
+
+ const iconRef = icon ? Byond.iconRefMap?.[icon] : null;
+
+ const iconSize = 64;
+ const realFill = iconSize * (1 - fillLevel);
+
+ const render = useCallback(
+ async (canvas: OffscreenCanvas, ctx: OffscreenCanvasRenderingContext2D) => {
+ // Pixel art please
+ ctx.imageSmoothingEnabled = false;
+
+ // Load the image from the server
+ const image = await getImage(`${iconRef}?state=${iconState}`);
+
+ // Draw the image on top
+ ctx.drawImage(image, 0, 0, iconSize, iconSize);
+
+ // Draw a square over the image with the color
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.fillStyle = color || '#ffffff';
+ ctx.fillRect(0, realFill, iconSize, iconSize);
+
+ // Use the image as a mask
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.drawImage(image, 0, 0, iconSize, iconSize);
+
+ // Colour it white for the outline
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.fillStyle = '#ffffff';
+ ctx.fillRect(0, 0, iconSize, iconSize);
+
+ // Draw an outline
+ const factor = 1.1;
+ const scaleX = image.width * factor;
+ const scaleY = image.height * factor;
+ ctx.scale(factor, factor);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.drawImage(
+ image,
+ -(scaleX - image.width) / factor,
+ -(scaleY - image.height) / factor,
+ iconSize,
+ iconSize,
+ );
+ },
+ [iconRef, iconState, color],
+ );
+
+ return iconRef ? (
+