diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 52d707d964..03d42b2638 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -58,6 +58,8 @@ jobs:
tools/bootstrap/python -c ''
- name: Run Grep Checks
run: tools/ci/validate_files.sh
+ - name: Run Define Sanity Checks
+ run: tools/bootstrap/python -m define_sanity.check
- name: Run TGUI Checks
run: tools/build/build --ci lint tgui-test
diff --git a/.gitignore b/.gitignore
index 28f0cda51c..3ef44b3109 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,6 @@ tgui/public/tgui.bundle.css
tgui/public/tgui.bundle.js
#ignore tracy dll
prof.dll
+
+# From /tools/define_sanity/check.py - potential output file that we load onto the user's machine that we don't want to have committed.
+define_sanity_output.txt
diff --git a/ATTRIBUTIONS.md b/ATTRIBUTIONS.md
index abaf97a0b9..b9680f5c65 100644
--- a/ATTRIBUTIONS.md
+++ b/ATTRIBUTIONS.md
@@ -86,3 +86,9 @@
**Creator:** VerySoft (https://github.com/TS-Rogue-Star/Rogue-Star/pull/669)
**URL:** [Website](https://rogue-star.net/)
**License:** Permission granted in writing for use by Virgo and Chomp with proper attribution
+
+**File:** icons/mob/vore_grayscale_drake.dmi
+**Title:** drake
+**Creator:** grayscaledrake (Discord user)
+**License:** [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)
+**Notes:** Permission to use assets also given in writing, assets were created for use in Virgo and other space station 13 servers.
diff --git a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm
index 84ba70f55f..fbbc59cd67 100644
--- a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm
@@ -30,8 +30,8 @@
var/ui_error = null // For error messages to show up in nano ui.
var/datum/gas_mixture/internal = new()
- var/const/input_gas = "carbon_dioxide"
- var/const/output_gas = "oxygen"
+ var/const/input_gas = GAS_CO2
+ var/const/output_gas = GAS_O2
/obj/machinery/atmospherics/binary/algae_farm/filled
stored_material = list(MAT_ALGAE = 10000, MAT_GRAPHITE = 0)
diff --git a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm
index 1a357327fb..9b00134cde 100644
--- a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm
+++ b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm
@@ -14,7 +14,7 @@
//--------------------------------------------
// Omni port datum
//
-// Used by omni devices to manage connections
+// Used by omni devices to manage connections
// to other atmospheric objects.
//--------------------------------------------
/datum/omni_port
@@ -70,10 +70,10 @@
string = "East"
if(WEST)
string = "West"
-
+
if(!capitalize && string)
string = lowertext(string)
-
+
return string
//returns a direction flag based on the string passed to it
@@ -94,16 +94,15 @@
/proc/mode_to_gasid(var/mode)
switch(mode)
- if(ATM_O2)
- return "oxygen"
- if(ATM_N2)
- return "nitrogen"
- if(ATM_CO2)
- return "carbon_dioxide"
- if(ATM_P)
- return "phoron"
- if(ATM_N2O)
- return "nitrous_oxide"
+ if(ATM_O2)
+ return GAS_O2
+ if(ATM_N2)
+ return GAS_N2
+ if(ATM_CO2)
+ return GAS_CO2
+ if(ATM_P)
+ return GAS_PHORON
+ if(ATM_N2O)
+ return GAS_N2O
else
return null
-
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
index f332afee61..29004bc234 100755
--- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
@@ -44,15 +44,15 @@
switch(filter_type)
if(0) //removing hydrocarbons
- filtered_out = list("phoron")
+ filtered_out = list(GAS_PHORON)
if(1) //removing O2
- filtered_out = list("oxygen")
+ filtered_out = list(GAS_O2)
if(2) //removing N2
- filtered_out = list("nitrogen")
+ filtered_out = list(GAS_N2)
if(3) //removing CO2
- filtered_out = list("carbon_dioxide")
+ filtered_out = list(GAS_CO2)
if(4)//removing N2O
- filtered_out = list("nitrous_oxide")
+ filtered_out = list(GAS_N2O)
air1.volume = ATMOS_DEFAULT_VOLUME_FILTER
air2.volume = ATMOS_DEFAULT_VOLUME_FILTER
@@ -138,18 +138,18 @@
// current_filter_type = "ERROR - Report this bug to the admin, please!"
// dat += {"
- // Power: [use_power?"On":"Off"]
+ // Power: [use_power?"On":"Off"]
// Filtering: [current_filter_type]
// Set Filter Type:
- // Phoron
- // Oxygen
- // Nitrogen
- // Carbon Dioxide
- // Nitrous Oxide
- // Nothing
+ // Phoron
+ // Oxygen
+ // Nitrogen
+ // Carbon Dioxide
+ // Nitrous Oxide
+ // Nothing
//
// Set Flow Rate Limit:
- // [src.set_flow_rate]L/s | Change
+ // [src.set_flow_rate]L/s | Change
// Flow rate: [round(last_flow_rate, 0.1)]L/s
// "}
@@ -205,16 +205,16 @@
filtered_out.Cut() //no need to create new lists unnecessarily
switch(filter_type)
if(0) //removing hydrocarbons
- filtered_out += "phoron"
+ filtered_out += GAS_PHORON
filtered_out += "oxygen_agent_b"
if(1) //removing O2
- filtered_out += "oxygen"
+ filtered_out += GAS_O2
if(2) //removing N2
- filtered_out += "nitrogen"
+ filtered_out += GAS_N2
if(3) //removing CO2
- filtered_out += "carbon_dioxide"
+ filtered_out += GAS_CO2
if(4)//removing N2O
- filtered_out += "nitrous_oxide"
+ filtered_out += GAS_N2O
add_fingerprint(ui.user)
update_icon()
diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
index 86ee751762..02b0127b32 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
@@ -106,25 +106,25 @@
// return
// user.set_machine(src)
// var/list/node_connects = get_node_connect_dirs()
- // var/dat = {span_bold("Power: ") + "[use_power?"On":"Off"]
+ // var/dat = {span_bold("Power: ") + "[use_power?"On":"Off"]
// Set Flow Rate Limit:
- // [set_flow_rate]L/s | Change
+ // [set_flow_rate]L/s | Change
//
// Flow Rate: [round(last_flow_rate, 0.1)]L/s
//
// Node 1 ([dir_name(node_connects[1],TRUE)]) Concentration:
- // -
- // -
+ // -
+ // -
// [mixing_inputs[air1]]([mixing_inputs[air1]*100]%)
- // +
- // +
+ // +
+ // +
//
// Node 2 ([dir_name(node_connects[2],TRUE)]) Concentration:
- // -
- // -
+ // -
+ // -
// [mixing_inputs[air2]]([mixing_inputs[air2]*100]%)
- // +
- // +
+ // +
+ // +
// "}
// user << browse("[src.name] control[dat]", "window=atmo_mixer")
diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm
index 110c581955..699a376ac0 100644
--- a/code/ATMOSPHERICS/components/unary/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm
@@ -321,6 +321,7 @@
/obj/machinery/atmospherics/unary/vent_pump/proc/set_frequency(new_frequency)
radio_connection = register_radio(src, frequency, new_frequency, radio_filter_in)
frequency = new_frequency
+ broadcast_status()
/obj/machinery/atmospherics/unary/vent_pump/receive_signal(datum/signal/signal)
if(stat & (NOPOWER|BROKEN))
diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
index 4ab5156968..909ac6658b 100644
--- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
@@ -20,7 +20,7 @@
var/hibernate = 0 //Do we even process?
var/scrubbing = 1 //0 = siphoning, 1 = scrubbing
- var/list/scrubbing_gas = list("carbon_dioxide", "phoron")
+ var/list/scrubbing_gas = list(GAS_CO2, GAS_PHORON)
var/panic = 0 //is this scrubber panicked?
@@ -109,12 +109,12 @@
"power" = use_power,
"scrubbing" = scrubbing,
"panic" = panic,
- "filter_o2" = ("oxygen" in scrubbing_gas),
- "filter_n2" = ("nitrogen" in scrubbing_gas),
- "filter_co2" = ("carbon_dioxide" in scrubbing_gas),
- "filter_phoron" = ("phoron" in scrubbing_gas),
- "filter_n2o" = ("nitrous_oxide" in scrubbing_gas),
- "filter_fuel" = ("volatile_fuel" in scrubbing_gas),
+ "filter_o2" = (GAS_O2 in scrubbing_gas),
+ "filter_n2" = (GAS_N2 in scrubbing_gas),
+ "filter_co2" = (GAS_CO2 in scrubbing_gas),
+ "filter_phoron" = (GAS_PHORON in scrubbing_gas),
+ "filter_n2o" = (GAS_N2O in scrubbing_gas),
+ "filter_fuel" = (GAS_VOLATILE_FUEL in scrubbing_gas),
"sigtype" = "status"
)
if(!initial_loc.air_scrub_names[id_tag])
@@ -216,35 +216,35 @@
var/list/toggle = list()
- if(!isnull(signal.data["o2_scrub"]) && text2num(signal.data["o2_scrub"]) != ("oxygen" in scrubbing_gas))
- toggle += "oxygen"
+ if(!isnull(signal.data["o2_scrub"]) && text2num(signal.data["o2_scrub"]) != (GAS_O2 in scrubbing_gas))
+ toggle += GAS_O2
else if(signal.data["toggle_o2_scrub"])
- toggle += "oxygen"
+ toggle += GAS_O2
- if(!isnull(signal.data["n2_scrub"]) && text2num(signal.data["n2_scrub"]) != ("nitrogen" in scrubbing_gas))
- toggle += "nitrogen"
+ if(!isnull(signal.data["n2_scrub"]) && text2num(signal.data["n2_scrub"]) != (GAS_N2 in scrubbing_gas))
+ toggle += GAS_N2
else if(signal.data["toggle_n2_scrub"])
- toggle += "nitrogen"
+ toggle += GAS_N2
- if(!isnull(signal.data["co2_scrub"]) && text2num(signal.data["co2_scrub"]) != ("carbon_dioxide" in scrubbing_gas))
- toggle += "carbon_dioxide"
+ if(!isnull(signal.data["co2_scrub"]) && text2num(signal.data["co2_scrub"]) != (GAS_CO2 in scrubbing_gas))
+ toggle += GAS_CO2
else if(signal.data["toggle_co2_scrub"])
- toggle += "carbon_dioxide"
+ toggle += GAS_CO2
- if(!isnull(signal.data["tox_scrub"]) && text2num(signal.data["tox_scrub"]) != ("phoron" in scrubbing_gas))
- toggle += "phoron"
+ if(!isnull(signal.data["tox_scrub"]) && text2num(signal.data["tox_scrub"]) != (GAS_PHORON in scrubbing_gas))
+ toggle += GAS_PHORON
else if(signal.data["toggle_tox_scrub"])
- toggle += "phoron"
+ toggle += GAS_PHORON
- if(!isnull(signal.data["n2o_scrub"]) && text2num(signal.data["n2o_scrub"]) != ("nitrous_oxide" in scrubbing_gas))
- toggle += "nitrous_oxide"
+ if(!isnull(signal.data["n2o_scrub"]) && text2num(signal.data["n2o_scrub"]) != (GAS_N2O in scrubbing_gas))
+ toggle += GAS_N2O
else if(signal.data["toggle_n2o_scrub"])
- toggle += "nitrous_oxide"
+ toggle += GAS_N2O
- if(!isnull(signal.data["fuel_scrub"]) && text2num(signal.data["fuel_scrub"]) != ("volatile_fuel" in scrubbing_gas))
- toggle += "volatile_fuel"
+ if(!isnull(signal.data["fuel_scrub"]) && text2num(signal.data["fuel_scrub"]) != (GAS_VOLATILE_FUEL in scrubbing_gas))
+ toggle += GAS_VOLATILE_FUEL
else if(signal.data["toggle_fuel_scrub"])
- toggle += "volatile_fuel"
+ toggle += GAS_VOLATILE_FUEL
scrubbing_gas ^= toggle
diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber_vr.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber_vr.dm
index ee8eda90b3..92869d8811 100644
--- a/code/ATMOSPHERICS/components/unary/vent_scrubber_vr.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_scrubber_vr.dm
@@ -1,2 +1,2 @@
/obj/machinery/atmospherics/unary/vent_scrubber
- scrubbing_gas = list("carbon_dioxide", "phoron")
\ No newline at end of file
+ scrubbing_gas = list(GAS_CO2, GAS_PHORON)
diff --git a/code/ATMOSPHERICS/pipes/tank.dm b/code/ATMOSPHERICS/pipes/tank.dm
index 34afa7bbe4..5560c5b197 100644
--- a/code/ATMOSPHERICS/pipes/tank.dm
+++ b/code/ATMOSPHERICS/pipes/tank.dm
@@ -79,8 +79,8 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
- air_temporary.adjust_multi("oxygen", (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \
- "nitrogen",(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
+ air_temporary.adjust_multi(GAS_O2, (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \
+ GAS_N2,(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
. = ..()
@@ -95,7 +95,7 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
- air_temporary.adjust_gas("oxygen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
+ air_temporary.adjust_gas(GAS_O2, (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
. = ..()
icon_state = "o2"
@@ -110,7 +110,7 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
- air_temporary.adjust_gas("nitrogen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
+ air_temporary.adjust_gas(GAS_N2, (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
. = ..()
icon_state = "n2"
@@ -124,7 +124,7 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
- air_temporary.adjust_gas("carbon_dioxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
+ air_temporary.adjust_gas(GAS_CO2, (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
. = ..()
icon_state = "co2"
@@ -139,7 +139,7 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
- air_temporary.adjust_gas("phoron", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
+ air_temporary.adjust_gas(GAS_PHORON, (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
. = ..()
icon_state = "phoron"
@@ -153,7 +153,7 @@
air_temporary.volume = volume
air_temporary.temperature = T0C
- air_temporary.adjust_gas("nitrous_oxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
+ air_temporary.adjust_gas(GAS_N2O, (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
. = ..()
icon_state = "n2o"
diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm
index 9cbf665f83..907c3583cc 100644
--- a/code/ZAS/Fire.dm
+++ b/code/ZAS/Fire.dm
@@ -301,7 +301,7 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin
//remove_by_flag() and adjust_gas() handle the group_multiplier for us.
remove_by_flag(XGM_GAS_OXIDIZER, used_oxidizers)
remove_by_flag(XGM_GAS_FUEL, used_gas_fuel)
- adjust_gas("carbon_dioxide", used_oxidizers)
+ adjust_gas(GAS_CO2, used_oxidizers)
if(zone)
zone.remove_liquidfuel(used_liquid_fuel, !check_combustability())
diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm
index cab64a11f8..c3e3097fb6 100644
--- a/code/ZAS/Phoron.dm
+++ b/code/ZAS/Phoron.dm
@@ -99,7 +99,7 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi')
return
//Burn skin if exposed.
- if(vsc.plc.SKIN_BURNS && (species.breath_type != "phoron"))
+ if(vsc.plc.SKIN_BURNS && (species.breath_type != GAS_PHORON))
if(!pl_head_protected() || !pl_suit_protected())
burn_skin(0.75)
if(prob(20))
@@ -107,7 +107,7 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi')
updatehealth()
//Burn eyes if exposed.
- if(vsc.plc.EYE_BURNS && species.breath_type && (species.breath_type != "phoron")) //VOREStation Edit: those who don't breathe
+ if(vsc.plc.EYE_BURNS && species.breath_type && (species.breath_type != GAS_PHORON)) //VOREStation Edit: those who don't breathe
var/burn_eyes = 1
//Check for protective glasses
@@ -131,7 +131,7 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi')
burn_eyes()
//Genetic Corruption
- if(vsc.plc.GENETIC_CORRUPTION && (species.breath_type != "phoron"))
+ if(vsc.plc.GENETIC_CORRUPTION && (species.breath_type != GAS_PHORON))
if(rand(1,10000) < vsc.plc.GENETIC_CORRUPTION)
randmutb(src)
to_chat(src, span_danger("High levels of toxins cause you to spontaneously mutate!"))
diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm
index a67970c63a..ba155379a3 100644
--- a/code/ZAS/Turf.dm
+++ b/code/ZAS/Turf.dm
@@ -237,7 +237,7 @@
//Create gas mixture to hold data for passing
var/datum/gas_mixture/GM = new
- GM.adjust_multi("oxygen", oxygen, "carbon_dioxide", carbon_dioxide, "nitrogen", nitrogen, "phoron", phoron)
+ GM.adjust_multi(GAS_O2, oxygen, GAS_CO2, carbon_dioxide, GAS_N2, nitrogen, GAS_PHORON, phoron)
GM.temperature = temperature
return GM
@@ -247,10 +247,10 @@
var/sum = oxygen + carbon_dioxide + nitrogen + phoron
if(sum>0)
- GM.gas["oxygen"] = (oxygen/sum)*amount
- GM.gas["carbon_dioxide"] = (carbon_dioxide/sum)*amount
- GM.gas["nitrogen"] = (nitrogen/sum)*amount
- GM.gas["phoron"] = (phoron/sum)*amount
+ GM.gas[GAS_O2] = (oxygen/sum)*amount
+ GM.gas[GAS_CO2] = (carbon_dioxide/sum)*amount
+ GM.gas[GAS_N2] = (nitrogen/sum)*amount
+ GM.gas[GAS_PHORON] = (phoron/sum)*amount
GM.temperature = temperature
GM.update_values()
@@ -293,7 +293,7 @@
/turf/proc/make_air()
air = new/datum/gas_mixture
air.temperature = temperature
- air.adjust_multi("oxygen", oxygen, "carbon_dioxide", carbon_dioxide, "nitrogen", nitrogen, "phoron", phoron)
+ air.adjust_multi(GAS_O2, oxygen, GAS_CO2, carbon_dioxide, GAS_N2, nitrogen, GAS_PHORON, phoron)
air.group_multiplier = 1
air.volume = CELL_VOLUME
diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm
index 8867060e6f..1b097b776c 100644
--- a/code/ZAS/Variable Settings.dm
+++ b/code/ZAS/Variable Settings.dm
@@ -110,7 +110,7 @@ var/global/vs_control/vsc = new
vw = vars[ch]
if("[ch]_DESC" in vars) vw_desc = vars["[ch]_DESC"]
if("[ch]_NAME" in vars) vw_name = vars["[ch]_NAME"]
- dat += span_bold("[vw_name] = [vw]") + " \[Change\]
"
+ dat += span_bold("[vw_name] = [vw]") + " \[Change\]
"
dat += "[vw_desc]
"
user << browse(dat,"window=settings")
diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm
index b6d012afe7..c38b92199e 100644
--- a/code/ZAS/Zone.dm
+++ b/code/ZAS/Zone.dm
@@ -171,8 +171,8 @@ Class Procs:
to_chat(M,name)
for(var/g in air.gas)
to_chat(M, "[gas_data.name[g]]: [air.gas[g]]")
- to_chat(M, "P: [air.return_pressure()] kPa V: [air.volume]L T: [air.temperature]�K ([air.temperature - T0C]�C)")
- to_chat(M, "O2 per N2: [(air.gas["nitrogen"] ? air.gas["oxygen"]/air.gas["nitrogen"] : "N/A")] Moles: [air.total_moles]")
+ to_chat(M, "P: [air.return_pressure()] kPa V: [air.volume]L T: [air.temperature]°K ([air.temperature - T0C]°C)")
+ to_chat(M, "O2 per N2: [(air.gas[GAS_N2] ? air.gas[GAS_O2]/air.gas[GAS_N2] : "N/A")] Moles: [air.total_moles]")
to_chat(M, "Simulated: [contents.len] ([air.group_multiplier])")
//to_chat(M, "Unsimulated: [unsimulated_contents.len]")
//to_chat(M, "Edges: [edges.len]")
diff --git a/code/__defines/_fruits.dm b/code/__defines/_fruits.dm
new file mode 100644
index 0000000000..827d64b471
--- /dev/null
+++ b/code/__defines/_fruits.dm
@@ -0,0 +1,134 @@
+#define PLANT_AMBROSIA "ambrosia"
+#define PLANT_APPLE "apple"
+#define PLANT_BANANA "banana"
+#define PLANT_BERRIES "berries"
+#define PLANT_CABBAGE "cabbage"
+#define PLANT_CARROT "carrot"
+#define PLANT_CELERY "celery"
+#define PLANT_CHERRY "cherry"
+#define PLANT_CHILI "chili"
+#define PLANT_COCOA "cocoa"
+#define PLANT_CORN "corn"
+#define PLANT_DURIAN "durian"
+#define PLANT_EGGPLANT "eggplant"
+#define PLANT_GRAPES "grapes"
+#define PLANT_GREENGRAPES "greengrapes"
+#define PLANT_HAREBELLS "harebells"
+#define PLANT_LAVENDER "lavender"
+#define PLANT_LEMON "lemon"
+#define PLANT_LETTUCE "lettuce"
+#define PLANT_LIME "lime"
+#define PLANT_ONION "onion"
+#define PLANT_ORANGE "orange"
+#define PLANT_PEANUT "peanut"
+#define PLANT_POPPIES "poppies"
+#define PLANT_POTATO "potato"
+#define PLANT_PUMPKIN "pumpkin"
+#define PLANT_RICE "rice"
+#define PLANT_ROSE "rose"
+#define PLANT_RHUBARB "rhubarb"
+#define PLANT_SOYBEAN "soybean"
+#define PLANT_SPINEAPPLE "spineapple"
+#define PLANT_SUGARCANE "sugarcane"
+#define PLANT_SUNFLOWERS "sunflowers"
+#define PLANT_TOMATO "tomato"
+#define PLANT_VANILLA "vanilla"
+#define PLANT_WATERMELON "watermelon"
+#define PLANT_WHEAT "wheat"
+#define PLANT_WHITEBEET "whitebeet"
+#define PLANT_DIONA "diona"
+#define PLANT_GHOSTCHILI "ghostchili"
+#define PLANT_PLASTIC "plastic"
+#define PLANT_SHAND "shand"
+#define PLANT_MTEAR "mtear"
+#define PLANT_GLOWBERRIES "glowberries"
+#define PLANT_PEPPERCORNS "peppercorns"
+#define PLANT_BLOODTOMATO "bloodtomato"
+#define PLANT_KILLERTOMATO "killertomato"
+#define PLANT_BLUETOMATO "bluetomato"
+#define PLANT_BLUESPACETOMATO "bluespacetomato"
+#define PLANT_ICECHILI "icechili"
+#define PLANT_REISHI "reishi"
+#define PLANT_AMANITA "amanita"
+#define PLANT_DESTROYINGANGEL "destroyingangel"
+#define PLANT_LIBERTYCAP "libertycap"
+#define PLANT_MUSHROOMS "mushrooms"
+#define PLANT_TOWERCAP "towercap"
+#define PLANT_REDCAP "redcap"
+#define PLANT_GLOWSHROOM "glowshroom"
+#define PLANT_PLUMPHELMET "plumphelmet"
+#define PLANT_SPORESHROOM "sporeshroom"
+#define PLANT_NETTLE "nettle"
+#define PLANT_DEATHNETTLE "deathnettle"
+#define PLANT_WEEDS "weeds"
+#define PLANT_MOLD "mold"
+#define PLANT_POISONAPPLE "poisonapple"
+#define PLANT_GOLDAPPLE "goldapple"
+#define PLANT_AMBROSIADEUS "ambrosiadeus"
+#define PLANT_AMBROSIAGAIA "ambrosiagaia"
+#define PLANT_AMBROSIAINFERNUS "ambrosiainfernus"
+#define PLANT_POISONBERRIES "poisonberries"
+#define PLANT_DEATHBERRIES "deathberries"
+#define PLANT_GRASS "grass"
+#define PLANT_CARPET "carpet"
+#define PLANT_TOBACCO "tobacco"
+#define PLANT_KUDZU "kudzu"
+#define PLANT_JURLMAH "jurlmah"
+#define PLANT_AMAURI "amauri"
+#define PLANT_GELTHI "gelthi"
+#define PLANT_VALE "vale"
+#define PLANT_SURIK "surik"
+#define PLANT_TELRIIS "telriis"
+#define PLANT_THAADRA "thaadra"
+#define PLANT_WHITEWABBACK "whitewabback"
+#define PLANT_BLACKWABBACK "blackwabback"
+#define PLANT_WILDWABBACK "wildwabback"
+#define PLANT_SIFLETTUCE "siflettuce"
+#define PLANT_EGG_PLANT "egg-plant"
+#define PLANT_PINEAPPLE "pineapple"
+#define PLANT_BLOODROSE "bloodrose"
+#define PLANT_GNOMES "gnomes"
+#define PLANT_SIFBULB "sifbulb"
+#define PLANT_WURMWOAD "wurmwoad"
+#define PLANT_MICROM "microm"
+#define PLANT_MEGAM "megam"
+
+GLOBAL_LIST_INIT(acceptable_fruit_types, list(
+ PLANT_AMBROSIA,
+ PLANT_APPLE,
+ PLANT_BANANA,
+ PLANT_BERRIES,
+ PLANT_CABBAGE,
+ PLANT_CARROT,
+ PLANT_CELERY,
+ PLANT_CHERRY,
+ PLANT_CHILI,
+ PLANT_COCOA,
+ PLANT_CORN,
+ PLANT_DURIAN,
+ PLANT_EGGPLANT,
+ PLANT_GRAPES,
+ PLANT_GREENGRAPES,
+ PLANT_HAREBELLS,
+ PLANT_LAVENDER,
+ PLANT_LEMON,
+ PLANT_LETTUCE,
+ PLANT_LIME,
+ PLANT_ONION,
+ PLANT_ORANGE,
+ PLANT_PEANUT,
+ PLANT_POPPIES,
+ PLANT_POTATO,
+ PLANT_PUMPKIN,
+ PLANT_RICE,
+ PLANT_ROSE,
+ PLANT_RHUBARB,
+ PLANT_SOYBEAN,
+ PLANT_SPINEAPPLE,
+ PLANT_SUGARCANE,
+ PLANT_SUNFLOWERS,
+ PLANT_TOMATO,
+ PLANT_VANILLA,
+ PLANT_WATERMELON,
+ PLANT_WHEAT,
+ PLANT_WHITEBEET))
diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm
index 7da2ddbfe8..c0af4ea1e1 100644
--- a/code/__defines/_planes+layers.dm
+++ b/code/__defines/_planes+layers.dm
@@ -106,6 +106,8 @@ What is the naming convention for planes or layers?
// Invisible things plane
#define CLOAKED_PLANE -15
+#define PLANE_CH_STOMACH -11 //Stomach Plane
+
// Top plane (in the sense that it's the highest in 'the world' and not a UI element)
#define ABOVE_PLANE -10
@@ -161,6 +163,12 @@ What is the naming convention for planes or layers?
#define PLANE_CH_SPECIAL 23 //Special role icon (revhead or w/e)
#define PLANE_CH_STATUS_OOC 24 //OOC status hud for spooks
+// "Character HUDs", aka HUDs, but not the game's UI. Things like medhuds.
+#define PLANE_CH_HEALTH_VR 26 //Hidden healthbar when at full health
+#define PLANE_CH_STATUS_R 27 //Right-side status icon
+#define PLANE_CH_BACKUP 28 //Backup implant
+#define PLANE_CH_VANTAG 29 //Vore Antag hud
+
#define PLANE_MESONS 30 //Stuff seen with mesons, like open ceilings. This is 30 for downstreams.
#define PLANE_JANHUD 31 //Stuff seen with janiHUD. Mostly highlight of dirt.
@@ -168,6 +176,9 @@ What is the naming convention for planes or layers?
#define PLANE_BUILDMODE 39 //Things that only show up when you have buildmode on
+#define PLANE_AUGMENTED 40 //Augmented-reality plane
+#define PLANE_SOULCATCHER 41 //Soulcatcher
+
//Fullscreen overlays under inventory
#define PLANE_FULLSCREEN 90 //Blindness, mesons, druggy, etc
#define OBFUSCATION_LAYER 5 //Where images covering the view for eyes are put
diff --git a/code/__defines/_planes+layers_vr.dm b/code/__defines/_planes+layers_vr.dm
deleted file mode 100644
index a9266aa701..0000000000
--- a/code/__defines/_planes+layers_vr.dm
+++ /dev/null
@@ -1,8 +0,0 @@
-// "Character HUDs", aka HUDs, but not the game's UI. Things like medhuds.
-#define PLANE_CH_HEALTH_VR 26 //Hidden healthbar when at full health
-#define PLANE_CH_STATUS_R 27 //Right-side status icon
-#define PLANE_CH_BACKUP 28 //Backup implant
-#define PLANE_CH_VANTAG 29 //Vore Antag hud
-#define PLANE_CH_STOMACH -11 //Stomach Plane
-
-#define PLANE_AUGMENTED 40 //Augmented-reality plane
diff --git a/code/__defines/_reagents.dm b/code/__defines/_reagents.dm
new file mode 100644
index 0000000000..5c3a1720bb
--- /dev/null
+++ b/code/__defines/_reagents.dm
@@ -0,0 +1,1346 @@
+// Gasses
+
+#define GAS_CO2 "carbon_dioxide"
+#define GAS_N2 "nitrogen"
+#define GAS_N2O "nitrous_oxide"
+#define GAS_O2 "oxygen"
+#define GAS_PHORON "phoron"
+#define GAS_VOLATILE_FUEL "volatile_fuel"
+
+// Gas Reagents
+#define REAGENT_CARBON_DIOXIDE "Carbon Dioxide"
+#define REAGENT_NITROGEN "Nitrogen"
+#define REAGENT_ID_NITROGEN "nitrogen"
+#define REAGENT_NITROUS_OXIDE "Nitrous Oxide"
+#define REAGENT_OXYGEN "Oxygen"
+#define REAGENT_ID_OXYGEN "oxygen"
+#define REAGENT_VOLATILE_FUEL "Volatile Fuel"
+#define REAGENT_HYDROGEN "Hydrogen"
+#define REAGENT_ID_HYDROGEN "hydrogen"
+#define REAGENT_FLUORINE "Fluorine"
+#define REAGENT_ID_FLUORINE "fluorine"
+#define REAGENT_CHLORINE "Chlorine"
+#define REAGENT_ID_CHLORINE "chlorine"
+
+
+// Fluid Reagents
+#define REAGENT_ETHANOL "Ethanol"
+#define REAGENT_ID_ETHANOL "ethanol"
+#define REAGENT_SACID "Sulphuric acid"
+#define REAGENT_ID_SACID "sacid"
+#define REAGENT_BLOOD "Blood"
+#define REAGENT_ID_BLOOD "blood"
+#define REAGENT_SYNTHBLOOD "synthetic blood"
+#define REAGENT_ID_SYNTHBLOOD "synthblood"
+#define REAGENT_SYNTHBLOOD_DILUTE "synthetic plasma"
+#define REAGENT_ID_SYNTHBLOOD_DILUTE "synthblood_dilute"
+#define REAGENT_ANTIBODIES "Antibodies"
+#define REAGENT_ID_ANTIBODIES "antibodies"
+#define REAGENT_WATER "Water"
+#define REAGENT_ID_WATER "water"
+#define REAGENT_FUEL "Welding fuel"
+#define REAGENT_ID_FUEL "fuel"
+
+
+// Solid Reagents
+#define REAGENT_IRON "Iron"
+#define REAGENT_ID_IRON "iron"
+#define REAGENT_LITHIUM "Lithium"
+#define REAGENT_ID_LITHIUM "lithium"
+#define REAGENT_ALUMINIUM "Aluminum"
+#define REAGENT_ID_ALUMINIUM "aluminum"
+#define REAGENT_CALCIUM "Calcium"
+#define REAGENT_ID_CALCIUM "calcium"
+#define REAGENT_CARBON "Carbon"
+#define REAGENT_ID_CARBON "carbon"
+#define REAGENT_COPPER "Copper"
+#define REAGENT_ID_COPPER "copper"
+#define REAGENT_MERCURY "Mercury"
+#define REAGENT_ID_MERCURY "mercury"
+#define REAGENT_PHOSPHORUS "Phosphorus"
+#define REAGENT_ID_PHOSPHORUS "phosphorus"
+#define REAGENT_POTASSIUM "Potassium"
+#define REAGENT_ID_POTASSIUM "potassium"
+#define REAGENT_RADIUM "Radium"
+#define REAGENT_ID_RADIUM "radium"
+#define REAGENT_SILICON "Silicon"
+#define REAGENT_ID_SILICON "silicon"
+#define REAGENT_SODIUM "Sodium"
+#define REAGENT_ID_SODIUM "sodium"
+#define REAGENT_SUGAR "Sugar"
+#define REAGENT_ID_SUGAR "sugar"
+#define REAGENT_SULFUR "Sulfur"
+#define REAGENT_ID_SULFUR "sulfur"
+#define REAGENT_TUNGSTEN "Tungsten"
+#define REAGENT_ID_TUNGSTEN "tungsten"
+#define REAGENT_NUTRIMENT "Nutriment"
+#define REAGENT_ID_NUTRIMENT "nutriment"
+#define REAGENT_STEEL "Liquid Steel"
+#define REAGENT_ID_STEEL "steel"
+#define REAGENT_PLASTEEL "Liquid Plasteel"
+#define REAGENT_ID_PLASTEEL "plasteel"
+
+
+// Xeno chem react
+#define XENO_CHEM_NUTRI "nutr"
+#define XENO_CHEM_MUT "mut"
+#define XENO_CHEM_TOXIC "toxic"
+#define XENO_CHEM_HEAL "heal"
+
+
+// VR reagents
+#define REAGENT_SIZEOXADONE "Sizeoxadone"
+#define REAGENT_ID_SIZEOXADONE "sizeoxadone"
+#define REAGENT_MACROCILLIN "Macrocillin"
+#define REAGENT_ID_MACROCILLIN "macrocillin"
+#define REAGENT_MICROCILLIN "Microcillin"
+#define REAGENT_ID_MICROCILLIN "microcillin"
+#define REAGENT_NORMALCILLIN "Normalcillin"
+#define REAGENT_ID_NORMALCILLIN "normalcillin"
+#define REAGENT_ICKYPAK "Ickypak"
+#define REAGENT_ID_ICKYPAK "ickypak"
+#define REAGENT_UNSORBITOL "Unsorbitol"
+#define REAGENT_ID_UNSORBITOL "unsorbitol"
+#define REAGENT_AMORPHOROVIR "Amorphorovir"
+#define REAGENT_ID_AMORPHOROVIR "amorphorovir"
+#define REAGENT_ANDROROVIR "Androrovir"
+#define REAGENT_ID_ANDROROVIR "androrovir"
+#define REAGENT_GYNOROVIR "Gynorovir"
+#define REAGENT_ID_GYNOROVIR "gynorovir"
+#define REAGENT_ANDROGYNOROVIR "Androgynorovir"
+#define REAGENT_ID_ANDROGYNOROVIR "androgynorovir"
+#define REAGENT_RAINBOWTOXIN "Rainbow Toxin"
+#define REAGENT_ID_RAINBOWTOXIN "rainbowtoxin"
+#define REAGENT_PARALYSISTOXIN "Tetrodotoxin"
+#define REAGENT_ID_PARALYSISTOXIN "paralysistoxin"
+#define REAGENT_PAINENZYME "Pain Enzyme"
+#define REAGENT_ID_PAINENZYME "painenzyme"
+
+
+// Drugs
+#define REAGENT_DRUGS "generic drugs"
+#define REAGENT_ID_DRUGS "drugs"
+#define REAGENT_BLISS "Bliss"
+#define REAGENT_ID_BLISS "bliss"
+#define REAGENT_AMBROSIAEXTRACT "Ambrosia extract"
+#define REAGENT_ID_AMBROSIAEXTRACT "ambrosia_extract"
+#define REAGENT_PSILOCYBIN "Psilocybin"
+#define REAGENT_ID_PSILOCYBIN "psilocybin"
+#define REAGENT_TALUMQUEM "Talum-quem"
+#define REAGENT_ID_TALUMQUEM "talum_quem"
+#define REAGENT_NICOTINE "Nicotine"
+#define REAGENT_ID_NICOTINE "nicotine"
+#define REAGENT_METHYLPHENIDATE "Methylphenidate"
+#define REAGENT_ID_METHYLPHENIDATE "methylphenidate"
+#define REAGENT_CITALOPRAM "Citalopram"
+#define REAGENT_ID_CITALOPRAM "citalopram"
+#define REAGENT_PAROXETINE "Paroxetine"
+#define REAGENT_ID_PAROXETINE "paroxetine"
+#define REAGENT_QERRQUEM "Qerr-quem"
+#define REAGENT_ID_QERRQUEM "qerr_quem"
+
+
+// Modifiers
+#define REAGENT_BERSERKMED "brute juice"
+#define REAGENT_ID_BERSERKMED "berserkmed"
+#define REAGENT_CRYOSLURRY "cryogenic slurry"
+#define REAGENT_ID_CRYOSLURRY "cryoslurry"
+#define REAGENT_VATSTABILIZER "clone growth inhibitor"
+#define REAGENT_ID_VATSTABILIZER "vatstabilizer"
+
+
+// Medicines
+#define REAGENT_ADRANOL "Adranol"
+#define REAGENT_ID_ADRANOL "adranol"
+#define REAGENT_NUMBENZYME "Numbing Enzyme"
+#define REAGENT_ID_NUMBENZYME "numbenzyme"
+#define REAGENT_VERMICETOL "Vermicetol"
+#define REAGENT_ID_VERMICETOL "vermicetol"
+#define REAGENT_SLEEVINGCURE "Kitsuhanan Cure"
+#define REAGENT_ID_SLEEVINGCURE "sleevingcure"
+#define REAGENT_PRUSSIANBLUE "Prussian Blue"
+#define REAGENT_ID_PRUSSIANBLUE "prussian_blue"
+#define REAGENT_LIPOZILASE "Lipozilase"
+#define REAGENT_ID_LIPOZILASE "lipozilase"
+#define REAGENT_LIPOSTIPO "Lipostipo"
+#define REAGENT_ID_LIPOSTIPO "lipostipo"
+#define REAGENT_POLYMORPH "Transforitine"
+#define REAGENT_ID_POLYMORPH "polymorph"
+#define REAGENT_GLAMOUR "Glamour"
+#define REAGENT_ID_GLAMOUR "glamour"
+#define REAGENT_INAPROVALINE "Inaprovaline"
+#define REAGENT_ID_INAPROVALINE "inaprovaline"
+#define REAGENT_INAPROVALAZE "Inaprovalaze"
+#define REAGENT_ID_INAPROVALAZE "inaprovalaze"
+#define REAGENT_BICARIDINE "Bicaridine"
+#define REAGENT_ID_BICARIDINE "bicaridine"
+#define REAGENT_BICARIDAZE "Bicaridaze"
+#define REAGENT_ID_BICARIDAZE "bicaridaze"
+#define REAGENT_CALCIUMCARBONATE "calcium carbonate"
+#define REAGENT_ID_CALCIUMCARBONATE "calciumcarbonate"
+#define REAGENT_KELOTANE "Kelotane"
+#define REAGENT_ID_KELOTANE "kelotane"
+#define REAGENT_DERMALINE "Dermaline"
+#define REAGENT_ID_DERMALINE "dermaline"
+#define REAGENT_DERMALAZE "Dermalaze"
+#define REAGENT_ID_DERMALAZE "dermalaze"
+#define REAGENT_ANTITOXIN "Dylovene"
+#define REAGENT_ID_ANTITOXIN "anti_toxin"
+#define REAGENT_CARTHATOLINE "Carthatoline"
+#define REAGENT_ID_CARTHATOLINE "carthatoline"
+#define REAGENT_DEXALIN "Dexalin"
+#define REAGENT_ID_DEXALIN "dexalin"
+#define REAGENT_DEXALINP "Dexalin Plus"
+#define REAGENT_ID_DEXALINP "dexalinp"
+#define REAGENT_TRICORDRAZINE "Tricordrazine"
+#define REAGENT_ID_TRICORDRAZINE "tricordrazine"
+#define REAGENT_TRICORLIDAZE "Tricorlidaze"
+#define REAGENT_ID_TRICORLIDAZE "tricorlidaze"
+#define REAGENT_CRYOXADONE "Cryoxadone"
+#define REAGENT_ID_CRYOXADONE "cryoxadone"
+#define REAGENT_CLONEXADONE "Clonexadone"
+#define REAGENT_ID_CLONEXADONE "clonexadone"
+#define REAGENT_MORTIFERIN "Mortiferin"
+#define REAGENT_ID_MORTIFERIN "mortiferin"
+#define REAGENT_NECROXADONE "Necroxadone"
+#define REAGENT_ID_NECROXADONE "necroxadone"
+#define REAGENT_PARACETAMOL "Paracetamol"
+#define REAGENT_ID_PARACETAMOL "paracetamol"
+#define REAGENT_TRAMADOL "Tramadol"
+#define REAGENT_ID_TRAMADOL "tramadol"
+#define REAGENT_OXYCODONE "Oxycodone"
+#define REAGENT_ID_OXYCODONE "oxycodone"
+#define REAGENT_SYNAPTIZINE "Synaptizine"
+#define REAGENT_ID_SYNAPTIZINE "synaptizine"
+#define REAGENT_HYPERZINE "Hyperzine"
+#define REAGENT_ID_HYPERZINE "hyperzine"
+#define REAGENT_ALKYSINE "Alkysine"
+#define REAGENT_ID_ALKYSINE "alkysine"
+#define REAGENT_IMIDAZOLINE "Imidazoline"
+#define REAGENT_ID_IMIDAZOLINE "imidazoline"
+#define REAGENT_PERIDAXON "Peridaxon"
+#define REAGENT_ID_PERIDAXON "peridaxon"
+#define REAGENT_OSTEODAXON "Osteodaxon"
+#define REAGENT_ID_OSTEODAXON "osteodaxon"
+#define REAGENT_MYELAMINE "Myelamine"
+#define REAGENT_ID_MYELAMINE "myelamine"
+#define REAGENT_RESPIRODAXON "Respirodaxon"
+#define REAGENT_ID_RESPIRODAXON "respirodaxon"
+#define REAGENT_GASTIRODAXON "Gastirodaxon"
+#define REAGENT_ID_GASTIRODAXON "gastirodaxon"
+#define REAGENT_HEPANEPHRODAXON "Hepanephrodaxon"
+#define REAGENT_ID_HEPANEPHRODAXON "hepanephrodaxon"
+#define REAGENT_CORDRADAXON "Cordradaxon"
+#define REAGENT_ID_CORDRADAXON "cordradaxon"
+#define REAGENT_IMMUNOSUPRIZINE "Immunosuprizine"
+#define REAGENT_ID_IMMUNOSUPRIZINE "immunosuprizine"
+#define REAGENT_MALISHQUALEM "Malish-Qualem"
+#define REAGENT_ID_MALISHQUALEM "malish-qualem"
+#define REAGENT_RYETALYN "Ryetalyn"
+#define REAGENT_ID_RYETALYN "ryetalyn"
+#define REAGENT_ETHYLREDOXRAZINE "Ethylredoxrazine"
+#define REAGENT_ID_ETHYLREDOXRAZINE "ethylredoxrazine"
+#define REAGENT_HYRONALIN "Hyronalin"
+#define REAGENT_ID_HYRONALIN "hyronalin"
+#define REAGENT_ARITHRAZINE "Arithrazine"
+#define REAGENT_ID_ARITHRAZINE "arithrazine"
+#define REAGENT_SPACEACILLIN "Spaceacillin"
+#define REAGENT_ID_SPACEACILLIN "spaceacillin"
+#define REAGENT_COROPHIZINE "Corophizine"
+#define REAGENT_ID_COROPHIZINE "corophizine"
+#define REAGENT_SPACOMYCAZE "Spacomycaze"
+#define REAGENT_ID_SPACOMYCAZE "spacomycaze"
+#define REAGENT_STERILIZINE "Sterilizine"
+#define REAGENT_ID_STERILIZINE "sterilizine"
+#define REAGENT_LEPORAZINE "Leporazine"
+#define REAGENT_ID_LEPORAZINE "leporazine"
+#define REAGENT_REZADONE "Rezadone"
+#define REAGENT_ID_REZADONE "rezadone"
+#define REAGENT_HEALINGNANITES "Restorative Nanites"
+#define REAGENT_ID_HEALINGNANITES "healing_nanites"
+#define REAGENT_MENTHOL "Menthol"
+#define REAGENT_ID_MENTHOL "menthol"
+#define REAGENT_EARTHSBLOOD "Earthsblood"
+#define REAGENT_ID_EARTHSBLOOD "earthsblood"
+
+
+// Virology
+#define REAGENT_VACCINE "Vaccine"
+#define REAGENT_ID_VACCINE "vaccine"
+#define REAGENT_MUTAGENVIRUSFOOD "Mutagenic agar"
+#define REAGENT_ID_MUTAGENVIRUSFOOD "mutagenvirusfood"
+#define REAGENT_SUGARVIRUSFOOD "Sucrose agar"
+#define REAGENT_ID_SUGARVIRUSFOOD "sugarvirusfood"
+#define REAGENT_ADRANOLVIRUSFOOD "Virus rations"
+#define REAGENT_ID_ADRANOLVIRUSFOOD "adranolvirusfood"
+#define REAGENT_PHORONVIRUSFOOD "Phoronic virus food"
+#define REAGENT_ID_PHORONVIRUSFOOD "phoronvirusfood"
+#define REAGENT_WEAKPHORONVIRUSFOOD "Weakened phoronic virus food"
+#define REAGENT_ID_WEAKPHORONVIRUSFOOD "weakphoronvirusfood"
+#define REAGENT_SIZEVIRUSFOOD "Sizeoxadone virus food"
+#define REAGENT_ID_SIZEVIRUSFOOD "sizevirusfood"
+
+
+// Misc reagents
+#define REAGENT_ADVMUTATIONTOXIN "Advanced Mutation Toxin"
+#define REAGENT_ID_ADVMUTATIONTOXIN "advmutationtoxin"
+#define REAGENT_NIFREPAIRNANITES "Programmed Nanomachines"
+#define REAGENT_ID_NIFREPAIRNANITES "nifrepairnanites"
+#define REAGENT_FIREFOAM "Firefighting Foam"
+#define REAGENT_ID_FIREFOAM "firefoam"
+#define REAGENT_LIQUIDPROTEAN "Liquid protean"
+#define REAGENT_ID_LIQUIDPROTEAN "liquid_protean"
+#define REAGENT_SHOCKCHEM "200 V"
+#define REAGENT_ID_SHOCKCHEM "shockchem"
+#define REAGENT_CRAYONDUST "Crayon dust"
+#define REAGENT_ID_CRAYONDUST "crayon_dust"
+#define REAGENT_CRAYONDUSTRED "Red crayon dust"
+#define REAGENT_ID_CRAYONDUSTRED "crayon_dust_red"
+#define REAGENT_CRAYONDUSTORANGE "Orange crayon dust"
+#define REAGENT_ID_CRAYONDUSTORANGE "crayon_dust_orange"
+#define REAGENT_CRAYONDUSTYELLOW "Yellow crayon dust"
+#define REAGENT_ID_CRAYONDUSTYELLOW "crayon_dust_yellow"
+#define REAGENT_CRAYONDUSTGREEN "Green crayon dust"
+#define REAGENT_ID_CRAYONDUSTGREEN "crayon_dust_green"
+#define REAGENT_CRAYONDUSTBLUE "Blue crayon dust"
+#define REAGENT_ID_CRAYONDUSTBLUE "crayon_dust_blue"
+#define REAGENT_CRAYONDUSTPURPLE "Purple crayon dust"
+#define REAGENT_ID_CRAYONDUSTPURPLE "crayon_dust_purple"
+#define REAGENT_CRAYONDUSTGREY "Grey crayon dust"
+#define REAGENT_ID_CRAYONDUSTGREY "crayon_dust_grey"
+#define REAGENT_CRAYONDUSTBROWN "Brown crayon dust"
+#define REAGENT_ID_CRAYONDUSTBROWN "crayon_dust_brown"
+#define REAGENT_MARKERINK "Marker ink"
+#define REAGENT_ID_MARKERINK "marker_ink"
+#define REAGENT_MARKERINKBLACK "Black marker ink"
+#define REAGENT_ID_MARKERINKBLACK "marker_ink_black"
+#define REAGENT_MARKERINKRED "Red marker ink"
+#define REAGENT_ID_MARKERINKRED "marker_ink_red"
+#define REAGENT_MARKERINKORANGE "Orange marker ink"
+#define REAGENT_ID_MARKERINKORANGE "marker_ink_orange"
+#define REAGENT_MARKERINKYELLOW "Yellow marker ink"
+#define REAGENT_ID_MARKERINKYELLOW "marker_ink_yellow"
+#define REAGENT_MARKERINKGREEN "Green marker ink"
+#define REAGENT_ID_MARKERINKGREEN "marker_ink_green"
+#define REAGENT_MARKERINKBLUE "Blue marker ink"
+#define REAGENT_ID_MARKERINKBLUE "marker_ink_blue"
+#define REAGENT_MARKERINKPURPLE "Purple marker ink"
+#define REAGENT_ID_MARKERINKPURPLE "marker_ink_purple"
+#define REAGENT_MARKERINKGREY "Grey marker ink"
+#define REAGENT_ID_MARKERINKGREY "marker_ink_grey"
+#define REAGENT_MARKERINKBROWN "Brown marker ink"
+#define REAGENT_ID_MARKERINKBROWN "marker_ink_brown"
+#define REAGENT_PAINT "Paint"
+#define REAGENT_ID_PAINT "paint"
+#define REAGENT_GOLD "Gold"
+#define REAGENT_ID_GOLD "gold"
+#define REAGENT_SILVER "Silver"
+#define REAGENT_ID_SILVER "silver"
+#define REAGENT_PLATINUM "Platinum"
+#define REAGENT_ID_PLATINUM "platinum"
+#define REAGENT_URANIUM "Uranium"
+#define REAGENT_ID_URANIUM "uranium"
+#define REAGENT_DEUTERIUM "Deuterium"
+#define REAGENT_ID_DEUTERIUM "deuterium"
+#define REAGENT_TRITIUM "Tritium"
+#define REAGENT_ID_TRITIUM "tritium"
+#define REAGENT_LITHIUM6 "Lithium-6"
+#define REAGENT_ID_LITHIUM6 "lithium6"
+#define REAGENT_HELIUM3 "Helium-3"
+#define REAGENT_ID_HELIUM3 "helium3"
+#define REAGENT_BORON11 "Boron-11"
+#define REAGENT_ID_BORON11 "boron11"
+#define REAGENT_SUPERMATTER "Supermatter"
+#define REAGENT_ID_SUPERMATTER "supermatter"
+#define REAGENT_ADRENALINE "Adrenaline"
+#define REAGENT_ID_ADRENALINE "adrenaline"
+#define REAGENT_HOLYWATER "Holy Water"
+#define REAGENT_ID_HOLYWATER "holywater"
+#define REAGENT_AMMONIA "Ammonia"
+#define REAGENT_ID_AMMONIA "ammonia"
+#define REAGENT_DIETHYLAMINE "Diethylamine"
+#define REAGENT_ID_DIETHYLAMINE "diethylamine"
+#define REAGENT_FLUOROSURFACTANT "Fluorosurfactant"
+#define REAGENT_ID_FLUOROSURFACTANT "fluorosurfactant"
+#define REAGENT_FOAMINGAGENT "Foaming agent"
+#define REAGENT_ID_FOAMINGAGENT "foaming_agent"
+#define REAGENT_THERMITE "Thermite"
+#define REAGENT_ID_THERMITE "thermite"
+#define REAGENT_CLEANER "Space cleaner"
+#define REAGENT_ID_CLEANER "cleaner"
+#define REAGENT_LUBE "Space Lube"
+#define REAGENT_ID_LUBE "lube"
+#define REAGENT_SILICATE "Silicate"
+#define REAGENT_ID_SILICATE "silicate"
+#define REAGENT_GLYCEROL "Glycerol"
+#define REAGENT_ID_GLYCEROL "glycerol"
+#define REAGENT_NITROGLYCERIN "Nitroglycerin"
+#define REAGENT_ID_NITROGLYCERIN "nitroglycerin"
+#define REAGENT_COOLANT "Coolant"
+#define REAGENT_ID_COOLANT "coolant"
+#define REAGENT_GLUE "Ultra Glue"
+#define REAGENT_ID_GLUE "glue"
+#define REAGENT_WOODPULP "Wood Pulp"
+#define REAGENT_ID_WOODPULP "woodpulp"
+#define REAGENT_LUMINOL "Luminol"
+#define REAGENT_ID_LUMINOL "luminol"
+#define REAGENT_BIOMASS "Biomass"
+#define REAGENT_ID_BIOMASS "biomass"
+#define REAGENT_MINERALIZEDFLUID "Mineral-Rich Fluid"
+#define REAGENT_ID_MINERALIZEDFLUID "mineralizedfluid"
+#define REAGENT_DEFECTIVENANITES "Defective Nanites"
+#define REAGENT_ID_DEFECTIVENANITES "defective_nanites"
+#define REAGENT_FISHBAIT "Fish Bait"
+#define REAGENT_ID_FISHBAIT "fishbait"
+#define REAGENT_LIQUIDCARPET "Liquid Carpet"
+#define REAGENT_ID_LIQUIDCARPET "liquidcarpet"
+#define REAGENT_LIQUIDCARPETB "Liquid Black Carpet"
+#define REAGENT_ID_LIQUIDCARPETB "liquidcarpetb"
+#define REAGENT_LIQUIDCARPETBLU "Liquid Blue Carpet"
+#define REAGENT_ID_LIQUIDCARPETBLU "liquidcarpetblu"
+#define REAGENT_LIQUIDCARPETTUR "Liquid Turquoise Carpet"
+#define REAGENT_ID_LIQUIDCARPETTUR "liquidcarpettur"
+#define REAGENT_LIQUIDCARPETSBLU "Liquid Silver Blue Carpet"
+#define REAGENT_ID_LIQUIDCARPETSBLU "liquidcarpetsblu"
+#define REAGENT_LIQUIDCARPETC "Liquid Clown Carpet"
+#define REAGENT_ID_LIQUIDCARPETC "liquidcarpetc"
+#define REAGENT_LIQUIDCARPETP "Liquid Purple Carpet"
+#define REAGENT_ID_LIQUIDCARPETP "liquidcarpetp"
+#define REAGENT_LIQUIDCARPETO "Liquid Orange Carpet"
+#define REAGENT_ID_LIQUIDCARPETO "liquidcarpeto"
+#define REAGENT_ESSENTIALOIL "Essential Oils"
+#define REAGENT_ID_ESSENTIALOIL "essential_oil"
+
+
+// Admin chems
+#define REAGENT_ADMINORDRAZINE "Adminordrazine"
+#define REAGENT_ID_ADMINORDRAZINE "adminordrazine"
+
+
+// Foods & Drinks
+#define REAGENT_MEATCOLONY "A colony of meat cells"
+#define REAGENT_ID_MEATCOLONY "meatcolony"
+#define REAGENT_PLANTCOLONY "A colony of plant cells"
+#define REAGENT_ID_PLANTCOLONY "plantcolony"
+#define REAGENT_GRUBSHAKE "Grub shake"
+#define REAGENT_ID_GRUBSHAKE "grubshake"
+#define REAGENT_BURNOUT "Burnout"
+#define REAGENT_ID_BURNOUT "burnout"
+#define REAGENT_MONSTERTAMER "Monster Tamer"
+#define REAGENT_ID_MONSTERTAMER "monstertamer"
+#define REAGENT_PINKRUSSIAN "Pink Russian"
+#define REAGENT_ID_PINKRUSSIAN "pinkrussian"
+#define REAGENT_ORIGINALSIN "Original Sin"
+#define REAGENT_ID_ORIGINALSIN "originalsin"
+#define REAGENT_NEWYORKSOUR "New York Sour"
+#define REAGENT_ID_NEWYORKSOUR "newyorksour"
+#define REAGENT_WINDGARITA "WND-Garita"
+#define REAGENT_ID_WINDGARITA "windgarita"
+#define REAGENT_MUDSLIDE "Mudslide"
+#define REAGENT_ID_MUDSLIDE "mudslide"
+#define REAGENT_GALACTICPANIC "Galactic Panic Attack"
+#define REAGENT_ID_GALACTICPANIC "galacticpanic"
+#define REAGENT_BULLDOG "Space Bulldog"
+#define REAGENT_ID_BULLDOG "bulldog"
+#define REAGENT_SBAGLIATO "Negroni Sbagliato"
+#define REAGENT_ID_SBAGLIATO "sbagliato"
+#define REAGENT_ITALIANCRISIS "Italian Crisis"
+#define REAGENT_ID_ITALIANCRISIS "italiancrisis"
+#define REAGENT_SUGARRUSH "Sweet Rush"
+#define REAGENT_ID_SUGARRUSH "sugarrush"
+#define REAGENT_LOTUS "Lotus"
+#define REAGENT_ID_LOTUS "lotus"
+#define REAGENT_SHROOMJUICE "Dumb Shroom Juice"
+#define REAGENT_ID_SHROOMJUICE "shroomjuice"
+#define REAGENT_RUSSIANROULETTE "Russian Roulette"
+#define REAGENT_ID_RUSSIANROULETTE "russianroulette"
+#define REAGENT_LOVEMAKER "The Love Maker"
+#define REAGENT_ID_LOVEMAKER "lovemaker"
+#define REAGENT_HONEYSHOT "Honey Shot"
+#define REAGENT_ID_HONEYSHOT "honeyshot"
+#define REAGENT_APPLETINI "Appletini"
+#define REAGENT_ID_APPLETINIT "appletini"
+#define REAGENT_GLOWINGAPPLETINI "Glowing Appletini"
+#define REAGENT_ID_GLOWINGAPPLETINI "glowingappletini"
+#define REAGENT_SCSATW "Slow Comfortable Screw Against the Wall"
+#define REAGENT_ID_SCSATW "scsatw"
+#define REAGENT_CHOCCYMILK "Choccy Milk"
+#define REAGENT_ID_CHOCCYMILK "choccymilk"
+#define REAGENT_REDSPACEFLUSH "Redspace Flush"
+#define REAGENT_ID_REDSPACEFLUSH "redspaceflush"
+#define REAGENT_GRAVEYARD "Graveyard"
+#define REAGENT_ID_GRAVEYARD "graveyard"
+#define REAGENT_BIGBEER "Giant Beer"
+#define REAGENT_ID_BIGBEER "bigbeer"
+#define REAGENT_MANAGERSUMMONER "Manager Summoner"
+#define REAGENT_ID_MANAGERSUMMONER "manager_summoner"
+#define REAGENT_SWEETTEA "Sweet Tea"
+#define REAGENT_ID_SWEETTEA "sweettea"
+#define REAGENT_UNSWEETTEA "Unsweetened Tea"
+#define REAGENT_ID_UNSWEETTEA "unsweettea"
+#define REAGENT_HAIROFTHERAT "Hair of the Rat"
+#define REAGENT_ID_HAIROFTHERAT "hairoftherat"
+#define REAGENT_BEPIS "Bepis Cola"
+#define REAGENT_ID_BEPIS "bepis"
+#define REAGENT_BUZZFUZZ "Buzz Fuzz"
+#define REAGENT_ID_BUZZFUZZ "buzz_fuzz"
+#define REAGENT_SPRITEDCRANBERRY "Sprited Cranberry"
+#define REAGENT_ID_SPRITEDCRANBERRY "sprited_cranberry"
+#define REAGENT_SHAMBLERS "Shambler's Juice"
+#define REAGENT_ID_SHAMBLERS "shamblers"
+#define REAGENT_BRAINPROTEIN "grey matter"
+#define REAGENT_ID_BRAINPROTEIN "brain_protein"
+#define REAGENT_ID_REDBRAINPROTEIN "red_brain_protein"
+#define REAGENT_PROTEINPOWDER "Protein Powder"
+#define REAGENT_ID_PROTEINPOWDER "protein_powder"
+#define REAGENT_PROTEINSHAKE "Protein Shake"
+#define REAGENT_ID_PROTEINSHAKE "protein_shake"
+#define REAGENT_VANILLAPROTEINPOWDER "Vanilla Protein Powder"
+#define REAGENT_ID_VANILLAPROTEINPOWDER "vanilla_protein_powder"
+#define REAGENT_VANILLAPROTEINSHAKE "Vanilla Protein Shake"
+#define REAGENT_ID_VANILLAPROTEINSHAKER "vanilla_protein_shake"
+#define REAGENT_BANANAPROTEINPOWDER "Banana Protein Powder"
+#define REAGENT_ID_BANANAPROTEINPOWDER "banana_protein_powder"
+#define REAGENT_BANANAPROTEINSHAKE "Banana Protein Shake"
+#define REAGENT_ID_BANANAPROTEINSHAKE "banana_protein_shake"
+#define REAGENT_CHOCOLATEPROTEINPOWDER "Chocolate Protein Powder"
+#define REAGENT_ID_CHOCOLATEPROTEINPOWDER "chocolate_protein_powder"
+#define REAGENT_CHOCOLATEPROTEINSHAKE "Chocolate Protein Shake"
+#define REAGENT_ID_CHOCOLATEPROTEINSHAKE "chocolate_protein_shake"
+#define REAGENT_STRAWBERRYPROTEINPOWDER "Strawberry Protein Powder"
+#define REAGENT_ID_STRAWBERRYPROTEINPOWDER "strawberry_protein_powder"
+#define REAGENT_STRAWBERRYPROTEINSHAKE "Strawberry Protein Shake"
+#define REAGENT_ID_STRAWBERRYPROTEINSHAKE "strawberry_protein_shake"
+#define REAGENT_SOUP "Soup"
+#define REAGENT_ID_SOUP "generic_soup"
+#define REAGENT_TOMATOSOUP "Tomato Soup"
+#define REAGENT_ID_TOMATOSOUP "tomato_soup"
+#define REAGENT_MUSHROOMSOUP "Cream of Mushroom Soup"
+#define REAGENT_ID_MUSHROOMSOUP "mushroom_soup"
+#define REAGENT_CHICKENSOUP "Cream of Chicken Soup"
+#define REAGENT_ID_CHICKENSOUP "chicken_soup"
+#define REAGENT_CHICKENNOODLESOUP "Chicken Noodle Soup"
+#define REAGENT_ID_CHICKENNOODLESOUP "chicken_noodle_soup"
+#define REAGENT_ONIONSOUP "Onion Soup"
+#define REAGENT_ID_ONIONSOUP "onion_soup"
+#define REAGENT_VEGETABLESOUP "Vegetable Soup"
+#define REAGENT_ID_VEGETABLESOUP "vegetable_soup"
+#define REAGENT_BEETSOUP "Beet Soup"
+#define REAGENT_ID_BEETSOUP "beet_soup"
+#define REAGENT_HOTNSOURSOUP "Hot & Sour Soup"
+#define REAGENT_ID_HOTNSOURSOUP "hot_n_sour_soup"
+#define REAGENT_NUKIE "Nukie"
+#define REAGENT_ID_NUKIE "nukie"
+#define REAGENT_NUKIEPEACH "Nukie Peach"
+#define REAGENT_ID_NUKIEPEACH "nukie_peach"
+#define REAGENT_NUKIEPEAR "Nukie Pear"
+#define REAGENT_ID_NUKIEPEAR "nukie_pear"
+#define REAGENT_NUKIECHERRY "Nukie Cherry"
+#define REAGENT_ID_NUKIECHERRY "nukie_cherry"
+#define REAGENT_NUKIEMELON "Nukie Melon"
+#define REAGENT_ID_NUKIEMELON "nukie_melon"
+#define REAGENT_NUKIEBANANA "Nukie Banana"
+#define REAGENT_ID_NUKIEBANANA "nukie_banana"
+#define REAGENT_NUKIEROSE "Nukie Rose"
+#define REAGENT_ID_NUKIEROSE "nukie_rose"
+#define REAGENT_NUKIELEMON "Nukie Lemon"
+#define REAGENT_ID_NUKIELEMON "nukie_lemon"
+#define REAGENT_NUKIEFRUIT "Nukie Fruit"
+#define REAGENT_ID_NUKIEFRUIT "nukie_fruit"
+#define REAGENT_NUKIESPECIAL "Nukie Limited Edition"
+#define REAGENT_ID_NUKIESPECIAL "nukie_special"
+#define REAGENT_NUKIEMEGA "Mega Nukie"
+#define REAGENT_ID_NUKIEMEGA "nukie_mega"
+#define REAGENT_NUKIEMEGASIGHT "Nukie Mega Plum"
+#define REAGENT_ID_NUKIEMEGASIGHT "nukie_mega_sight"
+#define REAGENT_NUKIEMEGAHEART "Nukie Mega Juice"
+#define REAGENT_ID_NUKIEMEGAHEART "nukie_mega_heart"
+#define REAGENT_NUKIEMEGASLEEP "Nukie Nega"
+#define REAGENT_ID_NUKIEMEGASLEEP "nukie_mega_sleep"
+#define REAGENT_NUKIEMEGASHOCK "Nukie Mega Shock"
+#define REAGENT_ID_NUKIEMEGASHOCK "nukie_mega_shock"
+#define REAGENT_NUKIEMEGAFAST "Nukie Mega Rapid"
+#define REAGENT_ID_NUKIEMEGAFAST "nukie_mega_fast"
+#define REAGENT_NUKIEMEGAHIGH "Nukie Mega Sky"
+#define REAGENT_ID_NUKIEMEGAHIGH "nukie_mega_high"
+#define REAGENT_NUKIEMEGASHRINK "Nukie Mega Shrink"
+#define REAGENT_ID_NUKIEMEGASHRINK "nukie_mega_shrink"
+#define REAGENT_NUKIEMEGAGROWTH "Nukie Mega Growth"
+#define REAGENT_ID_NUKIEMEGAGROWTH "nukie_mega_growth"
+#define REAGENT_COATING "coating"
+#define REAGENT_ID_COATING "coating"
+#define REAGENT_BATTER "batter mix"
+#define REAGENT_ID_BATTER "batter"
+#define REAGENT_BEERBATTER "beer batter mix"
+#define REAGENT_ID_BEERBATTER "beerbatter"
+#define REAGENT_TRIGLYCERIDE "triglyceride"
+#define REAGENT_ID_TRIGLYCERIDE "triglyceride"
+#define REAGENT_OIL "Oil"
+#define REAGENT_ID_OIL "oil"
+#define REAGENT_COOKINGOIL "Cooking Oil"
+#define REAGENT_ID_COOKINGOIL "cookingoil"
+#define REAGENT_CORNOIL "Corn Oil"
+#define REAGENT_ID_CORNOIL "cornoil"
+#define REAGENT_PEANUTOIL "Peanut Oil"
+#define REAGENT_ID_PEANUTOIL "peanutoil"
+#define REAGENT_GLUCOSE "Glucose"
+#define REAGENT_ID_GLUCOSE "glucose"
+#define REAGENT_PROTEIN "animal protein"
+#define REAGENT_ID_PROTEIN "protein"
+#define REAGENT_TOFU "tofu protein"
+#define REAGENT_ID_TOFU "tofu"
+#define REAGENT_SEAFOOD "seafood protein"
+#define REAGENT_ID_SEAFOOD "seafood"
+#define REAGENT_CHEESE "cheese"
+#define REAGENT_ID_CHEESE "cheese"
+#define REAGENT_EGG "egg yolk"
+#define REAGENT_ID_EGG "egg"
+#define REAGENT_MURK_PROTEIN "murkfin protein"
+#define REAGENT_ID_MURK_PROTEIN "murk_protein"
+#define REAGENT_BEANPROTEIN "beans"
+#define REAGENT_ID_BEANPROTEIN "bean_protein"
+#define REAGENT_HONEY "Honey"
+#define REAGENT_ID_HONEY "honey"
+#define REAGENT_MAYO "Mayonnaise"
+#define REAGENT_ID_MAYO "mayo"
+#define REAGENT_YEAST "Yeast"
+#define REAGENT_ID_YEAST "yeast"
+#define REAGENT_FLOUR "Flour"
+#define REAGENT_ID_FLOUR "flour"
+#define REAGENT_COFFEEPOWDER "Coffee Powder"
+#define REAGENT_ID_COFFEEPOWDER "coffeepowder"
+#define REAGENT_TEAPOWDER "Tea Powder"
+#define REAGENT_ID_TEAPOWDER "teapowder"
+#define REAGENT_DECAFTEAPOWDER "Decaf Tea Powder"
+#define REAGENT_ID_DECAFTEAPOWDER "decafteapowder"
+#define REAGENT_COCO "Coco Powder"
+#define REAGENT_ID_COCO "coco"
+#define REAGENT_CHOCOLATE "Chocolate"
+#define REAGENT_ID_CHOCOLATE "chocolate"
+#define REAGENT_INSTANTJUICE "Juice Powder"
+#define REAGENT_ID_INSTANTJUICE "instantjuice"
+#define REAGENT_INSTANTGRAPE "Grape Juice Powder"
+#define REAGENT_ID_INSTANTGRAPE "instantgrape"
+#define REAGENT_INSTANTORANGE "Orange Juice Powder"
+#define REAGENT_ID_INSTANTORANGE "instantorange"
+#define REAGENT_INSTANTWATERMELON "Watermelon Juice Powder"
+#define REAGENT_ID_INSTANTWATERMELON "instantwatermelon"
+#define REAGENT_INSTANTAPPLE "Apple Juice Powder"
+#define REAGENT_ID_INSTANTAPPLE "instantapple"
+#define REAGENT_SOYSAUCE "Soy Sauce"
+#define REAGENT_ID_SOYSAUCE "soysauce"
+#define REAGENT_VINEGAR "Vinegar"
+#define REAGENT_ID_VINEGAR "vinegar"
+#define REAGENT_KETCHUP "Ketchup"
+#define REAGENT_ID_KETCHUP "ketchup"
+#define REAGENT_MUSTARD "Mustard"
+#define REAGENT_ID_MUSTARD "mustard"
+#define REAGENT_BARBECUE "Barbeque Sauce"
+#define REAGENT_ID_BARBECUE "barbecue"
+#define REAGENT_RICE "Rice"
+#define REAGENT_ID_RICE "rice"
+#define REAGENT_CHERRYJELLY "Cherry Jelly"
+#define REAGENT_ID_CHERRYJELLY "cherryjelly"
+#define REAGENT_PEANUTBUTTER "Peanut Butter"
+#define REAGENT_ID_PEANUTBUTTER "peanutbutter"
+#define REAGENT_VANILLA "Vanilla Extract"
+#define REAGENT_ID_VANILLA "vanilla"
+#define REAGENT_DURIANPASTE "Durian Paste"
+#define REAGENT_ID_DURIANPASTE "durianpaste"
+#define REAGENT_VIRUSFOOD "Virus Food"
+#define REAGENT_ID_VIRUSFOOD "virusfood"
+#define REAGENT_SPRINKLES "Sprinkles"
+#define REAGENT_ID_SPRINKLES "sprinkles"
+#define REAGENT_MINT "Mint"
+#define REAGENT_ID_MINT "mint"
+#define REAGENT_LIPOZINE "Lipozine"
+#define REAGENT_ID_LIPOZINE "lipozine"
+#define REAGENT_SODIUMCHLORIDE "Table Salt"
+#define REAGENT_ID_SODIUMCHLORIDE "sodiumchloride"
+#define REAGENT_BLACKPEPPER "Black Pepper"
+#define REAGENT_ID_BLACKPEPPER "blackpepper"
+#define REAGENT_ENZYME "Universal Enzyme"
+#define REAGENT_ID_ENZYME "enzyme"
+#define REAGENT_SPACESPICE "Wurmwoad"
+#define REAGENT_ID_SPACESPICE "spacespice"
+#define REAGENT_BROWNIEMIX "Brownie Mix"
+#define REAGENT_ID_BROWNIEMIX "browniemix"
+#define REAGENT_CAKEBATTER "Cake Batter"
+#define REAGENT_ID_CAKEBATTER "cakebatter"
+#define REAGENT_FROSTOIL "Frost Oil"
+#define REAGENT_ID_FROSTOIL "frostoil"
+#define REAGENT_CRYOTOXIN "Cryotoxin"
+#define REAGENT_ID_CRYOTOXIN "cryotoxin"
+#define REAGENT_CAPSAICIN "Capsaicin Oil"
+#define REAGENT_ID_CAPSAICIN "capsaicin"
+#define REAGENT_CONDENSEDCAPSAICIN "Condensed Capsaicin"
+#define REAGENT_ID_CONDENSEDCAPSAICIN "condensedcapsaicin"
+
+#define REAGENT_DRINK "Drink"
+#define REAGENT_ID_DRINK "drink"
+
+// Juices
+#define REAGENT_BANANA "Banana Juice"
+#define REAGENT_ID_BANANA "banana"
+#define REAGENT_BERRYJUICE "Berry Juice"
+#define REAGENT_ID_BERRYJUICE "berryjuice"
+#define REAGENT_PINEAPPLEJUICE "Pineapple Juice"
+#define REAGENT_ID_PINEAPPLEJUICE "pineapplejuice"
+#define REAGENT_CARROTJUICE "Carrot juice"
+#define REAGENT_ID_CARROTJUICE "carrotjuice"
+#define REAGENT_LETTUCEJUICE "Lettuce Juice"
+#define REAGENT_ID_LETTUCEJUICE "lettucejuice"
+#define REAGENT_GRAPEJUICE "Grape Juice"
+#define REAGENT_ID_GRAPEJUICE "grapejuice"
+#define REAGENT_LEMONJUICE "Lemon Juice"
+#define REAGENT_ID_LEMONJUICE "lemonjuice"
+#define REAGENT_APPLEJUICE "Apple Juice"
+#define REAGENT_ID_APPLEJUICE "applejuice"
+#define REAGENT_LIMEJUICE "Lime Juice"
+#define REAGENT_ID_LIMEJUICE "limejuice"
+#define REAGENT_ORANGEJUICE "Orange juice"
+#define REAGENT_ID_ORANGEJUICE "orangejuice"
+#define REAGENT_POISONBERRYJUICE "Poison Berry Juice"
+#define REAGENT_ID_POISONBERRYJUICE "poisonberryjuice"
+#define REAGENT_POTATOJUICE "Potato Juice"
+#define REAGENT_ID_POTATOJUICE "potatojuice"
+#define REAGENT_TURNIPJUICE "Turnip Juice"
+#define REAGENT_ID_TURNIPJUICE "turnipjuice"
+#define REAGENT_TOMATOJUICE "Tomato Juice"
+#define REAGENT_ID_TOMATOJUICE "tomatojuice"
+#define REAGENT_WATERMELONJUICE "Watermelon Juice"
+#define REAGENT_ID_WATERMELONJUICE "watermelonjuice"
+
+// Drinks
+#define REAGENT_MILK "Milk"
+#define REAGENT_ID_MILK "milk"
+#define REAGENT_CHOCOLATEMILK "Chocolate Milk"
+#define REAGENT_ID_CHOCOLATEMILK "chocolate_milk"
+#define REAGENT_CREAM "Cream"
+#define REAGENT_ID_CREAM "cream"
+#define REAGENT_SOYMILK "Soy Milk"
+#define REAGENT_ID_SOYMILK "soymilk"
+#define REAGENT_MILKFOAM "Milk Foam"
+#define REAGENT_ID_MILKFOAM "milk_foam"
+#define REAGENT_TEA "Tea"
+#define REAGENT_ID_TEA "tea"
+#define REAGENT_TEADECAF "Decaf Tea"
+#define REAGENT_ID_TEADECAF "teadecaf"
+#define REAGENT_ICETEA "Iced Tea"
+#define REAGENT_ID_ICETEA "icetea"
+#define REAGENT_ICETEADECAF "Decaf Iced Tea"
+#define REAGENT_ID_ICETEADECAF "iceteadecaf"
+#define REAGENT_MINTTEA "Mint Tea"
+#define REAGENT_ID_MINTTEA "minttea"
+#define REAGENT_MINTTEADECAF "Decaf Mint Tea"
+#define REAGENT_ID_MINTTEADECAF "mintteadecaf"
+#define REAGENT_LEMONTEA "Lemon Tea"
+#define REAGENT_ID_LEMONTEA "lemontea"
+#define REAGENT_LEMONTEADECAF "Decaf Lemon Tea"
+#define REAGENT_ID_LEMONTEADECAF "lemonteadecaf"
+#define REAGENT_LIMETEA "Lime Tea"
+#define REAGENT_ID_LIMETEA "limetea"
+#define REAGENT_LIMETEADECAF "Decaf Lime Tea"
+#define REAGENT_ID_LIMETEADECAF "limeteadecaf"
+#define REAGENT_ORANGETEA "Orange Tea"
+#define REAGENT_ID_ORANGETEA "orangetea"
+#define REAGENT_ORANGETEADECAF "Decaf orange Tea"
+#define REAGENT_ID_ORANGETEADECAF "orangeteadecaf"
+#define REAGENT_BERRYTEA "Berry Tea"
+#define REAGENT_ID_BERRYTEA "berrytea"
+#define REAGENT_BERRYTEADECAF "Decaf Berry Tea"
+#define REAGENT_ID_BERRYTEADECAF "berryteadecaf"
+#define REAGENT_GREENTEA "Green Tea"
+#define REAGENT_ID_GREENTEA "greentea"
+#define REAGENT_CHAITEA "Chai Tea"
+#define REAGENT_ID_CHAITEA "chaitea"
+#define REAGENT_CHAITEADECAF "Decaf Chai Tea"
+#define REAGENT_ID_CHAITEADECAF "chaiteadecaf"
+#define REAGENT_COFFEE "Coffee"
+#define REAGENT_ID_COFFEE "coffee"
+#define REAGENT_ICECOFFEE "Iced Coffee"
+#define REAGENT_ID_ICECOFFEE "icecoffee"
+#define REAGENT_SOYLATTE "Soy Latte"
+#define REAGENT_ID_SOYLATTE "soy_latte"
+#define REAGENT_CAFELATTE "Cafe Latte"
+#define REAGENT_ID_CAFELATTE "cafe_latte"
+#define REAGENT_DECAF "Decaf Coffee"
+#define REAGENT_ID_DECAF "decaf"
+#define REAGENT_HOTCOCO "Hot Chocolate"
+#define REAGENT_ID_HOTCOCO "hot_coco"
+#define REAGENT_BLACKEYE "Black Eye Coffee"
+#define REAGENT_ID_BLACKEYE "black_eye"
+#define REAGENT_DRIPCOFFEE "Drip Coffee"
+#define REAGENT_ID_DRIPCOFFEE "drip_coffee"
+#define REAGENT_AMERICANO "Americano"
+#define REAGENT_ID_AMERICANO "americano"
+#define REAGENT_LONGBLACK "Long Black Coffee"
+#define REAGENT_ID_LONGBLACK "long_black"
+#define REAGENT_MACCHIATO "Macchiato"
+#define REAGENT_ID_MACCHIATO "macchiato"
+#define REAGENT_CORTADO "Cortado"
+#define REAGENT_ID_CORTADO "cortado"
+#define REAGENT_BREVE "Breve"
+#define REAGENT_ID_BREVE "breve"
+#define REAGENT_CAPPUCCINO "Cappuccino"
+#define REAGENT_ID_CAPPUCCINO "cappuccino"
+#define REAGENT_FLATWHITE "Flat White Coffee"
+#define REAGENT_ID_FLATWHITE "flat_white"
+#define REAGENT_MOCHA "Mocha"
+#define REAGENT_ID_MOCHA "mocha"
+#define REAGENT_VIENNA "Vienna"
+#define REAGENT_ID_VIENNA "vienna"
+#define REAGENT_SODAWATER "Soda Water"
+#define REAGENT_ID_SODAWATER "sodawater"
+#define REAGENT_TONIC "Tonic Water"
+#define REAGENT_ID_TONIC "tonic"
+#define REAGENT_LEMONADE "Lemonade"
+#define REAGENT_ID_LEMONADE "lemonade"
+#define REAGENT_MELONADE "Melonade"
+#define REAGENT_ID_MELONADE "melonade"
+#define REAGENT_APPLEADE "Appleade"
+#define REAGENT_ID_APPLEADE "appleade"
+#define REAGENT_PINEAPPLEADE "Pineappleade"
+#define REAGENT_ID_PINEAPPLEADE "pineappleade"
+#define REAGENT_KIRASPECIAL "Kira Special"
+#define REAGENT_ID_KIRASPECIAL "kiraspecial"
+#define REAGENT_BROWNSTAR "Brown Star"
+#define REAGENT_ID_BROWNSTAR "brownstar"
+#define REAGENT_BROWNSTARDECAF "Decaf Brown Star"
+#define REAGENT_ID_BROWNSTARDECAF "brownstar_decaf"
+#define REAGENT_MILKSHAKE "Milkshake"
+#define REAGENT_ID_MILKSHAKE "milkshake"
+#define REAGENT_CHOCOSHAKE "Chocolate Milkshake"
+#define REAGENT_ID_CHOCOSHAKE "chocoshake"
+#define REAGENT_BERRYSHAKE "Berry Milkshake"
+#define REAGENT_ID_BERRYSHAKE "berryshake"
+#define REAGENT_COFFEESHAKE "Coffee Milkshake"
+#define REAGENT_ID_COFFEESHAKE "coffeeshake"
+#define REAGENT_PEANUTMILKSHAKE "Peanut Milkshake"
+#define REAGENT_ID_PEANUTMILKSHAKE "peanutmilkshake"
+#define REAGENT_REWRITER "Rewriter"
+#define REAGENT_ID_REWRITER "rewriter"
+#define REAGENT_NUKACOLA "Nuka Cola"
+#define REAGENT_ID_NUKACOLA "nuka_cola"
+#define REAGENT_GRENADINE "Grenadine Syrup"
+#define REAGENT_ID_GRENADINE "grenadine"
+#define REAGENT_COLA "Space Cola"
+#define REAGENT_ID_COLA "cola"
+#define REAGENT_DECAFCOLA "Space Cola Free"
+#define REAGENT_ID_DECAFCOLA "decafcola"
+#define REAGENT_LEMONSODA "Lemon Soda"
+#define REAGENT_ID_LEMONSODA "lemonsoda"
+#define REAGENT_APPLESODA "Apple Soda"
+#define REAGENT_ID_APPLESODA "applesoda"
+#define REAGENT_STRAWSODA "Strawberry Soda"
+#define REAGENT_ID_STRAWSODA "strawsoda"
+#define REAGENT_ORANGESODA "Orange Soda"
+#define REAGENT_ID_ORANGESODA "orangesoda"
+#define REAGENT_GRAPESODA "Grape Soda"
+#define REAGENT_ID_GRAPESODA "grapesoda"
+#define REAGENT_SARSAPARILLA "Sarsaparilla"
+#define REAGENT_ID_SARSAPARILLA "sarsaparilla"
+#define REAGENT_PORKSODA "Bacon Soda"
+#define REAGENT_ID_PORKSODA "porksoda"
+#define REAGENT_SPACEMOUNTAINWIND "Mountain Wind"
+#define REAGENT_ID_SPACEMOUNTAINWIND "spacemountainwind"
+#define REAGENT_DRGIBB "Dr. Gibb"
+#define REAGENT_ID_DRGIBB "dr_gibb"
+#define REAGENT_SPACEUP "Space-Up"
+#define REAGENT_ID_SPACEUP "space_up"
+#define REAGENT_LEMONLIME "Lemon-Lime"
+#define REAGENT_ID_LEMONLIME "lemon_lime"
+#define REAGENT_GINGERALE "Ginger Ale"
+#define REAGENT_ID_GINGERALE "gingerale"
+#define REAGENT_ROOTBEER "R&D Root Beer"
+#define REAGENT_ID_ROOTBEER "rootbeer"
+#define REAGENT_DIETDRGIBB "Diet Dr. Gibb"
+#define REAGENT_ID_DIETDRGIBB "diet_dr_gibb"
+#define REAGENT_SHIRLEYTEMPLE "Shirley Temple"
+#define REAGENT_ID_SHIRLEYTEMPLE "shirley_temple"
+#define REAGENT_ROYROGERS "Roy Rogers"
+#define REAGENT_ID_ROYROGERS "roy_rogers"
+#define REAGENT_COLLINSMIX "Collins Mix"
+#define REAGENT_ID_COLLINSMIX "collins_mix"
+#define REAGENT_ARNOLDPALMER "Arnold Palmer"
+#define REAGENT_ID_ARNOLDPALMER "arnold_palmer"
+#define REAGENT_DOCTORSDELIGHT "The Doctor's Delight"
+#define REAGENT_ID_DOCTORSDELIGHT "doctorsdelight"
+#define REAGENT_DRYRAMEN "Dry Ramen"
+#define REAGENT_ID_DRYRAMEN "dry_ramen"
+#define REAGENT_HOTRAMEN "Hot Ramen"
+#define REAGENT_ID_HOTRAMEN "hot_ramen"
+#define REAGENT_HELLRAMEN "Hell Ramen"
+#define REAGENT_ID_HELLRAMEN "hell_ramen"
+#define REAGENT_DESSERTRAMEN "Dessert Ramen"
+#define REAGENT_ID_DESSERTRAMEN "dessertramen"
+#define REAGENT_ICE "Ice"
+#define REAGENT_ID_ICE "ice"
+#define REAGENT_NOTHING "Nothing"
+#define REAGENT_ID_NOTHING "nothing"
+#define REAGENT_DREAMCREAM "Dream Cream"
+#define REAGENT_ID_DREAMCREAM "dreamcream"
+#define REAGENT_VILELEMON "Vile Lemon"
+#define REAGENT_ID_VILELEMON "vilelemon"
+#define REAGENT_ENTDRAUGHT "Ent's Draught"
+#define REAGENT_ID_ENTDRAUGHT "entdraught"
+#define REAGENT_LOVEPOTION "Love Potion"
+#define REAGENT_ID_LOVEPOTION "lovepotion"
+#define REAGENT_OILSLICK "Oil Slick"
+#define REAGENT_ID_OILSLICK "oilslick"
+#define REAGENT_SLIMESLAMMER "Slick Slimes Slammer"
+#define REAGENT_ID_SLIMESLAMMER "slimeslammer"
+#define REAGENT_EGGNOG "Eggnog"
+#define REAGENT_ID_EGGNOG "eggnog"
+#define REAGENT_NUCLEARWASTE "Nuclear Waste"
+#define REAGENT_ID_NUCLEARWASTE "nuclearwaste"
+#define REAGENT_SODAOIL "Soda Oil"
+#define REAGENT_ID_SODAOIL "sodaoil"
+#define REAGENT_VIRGINMOJITO "Mojito"
+#define REAGENT_ID_VIRGINMOJITO "virginmojito"
+#define REAGENT_VIRGINSEXONTHEBEACH "Virgin Sex On The Beach"
+#define REAGENT_ID_VIRGINSEXONTHEBEACH "virginsexonthebeach"
+#define REAGENT_DRIVERSPUNCH "Driver's Punch"
+#define REAGENT_ID_DRIVERSPUNCH "driverspunch"
+#define REAGENT_MINTAPPLESPARKLE "Mint Apple Sparkle"
+#define REAGENT_ID_MINTAPPLESPARKLE "mintapplesparkle"
+#define REAGENT_BERRYCORDIAL "Berry Cordial"
+#define REAGENT_ID_BERRYCORDIAL "berrycordial"
+#define REAGENT_TROPICALFIZZ "Tropical Fizz"
+#define REAGENT_ID_TROPICALFIZZ "tropicalfizz"
+#define REAGENT_FAUXFIZZ "Faux Fizz"
+#define REAGENT_ID_FAUXFIZZ "fauxfizz"
+#define REAGENT_SYRUP "syrup"
+#define REAGENT_ID_SYRUP "syrup"
+#define REAGENT_SYRUPPUMPKIN "pumpkin spice syrup"
+#define REAGENT_ID_SYRUPPUMPKIN "syrup_pumpkin"
+#define REAGENT_SYRUPCARAMEL "caramel syrup"
+#define REAGENT_ID_SYRUPCARAMEL "syrup_caramel"
+#define REAGENT_SYRUPSALTEDCARAMEL "salted caramel syrup"
+#define REAGENT_ID_SYRUPSALTEDCARAMEL "syrup_salted_caramel"
+#define REAGENT_SYRUPIRISH "irish cream syrup"
+#define REAGENT_ID_SYRUPIRISH "syrup_irish"
+#define REAGENT_SYRUPALMOND "almond syrup"
+#define REAGENT_ID_SYRUPALMOND "syrup_almond"
+#define REAGENT_SYRUPCINNAMON "cinnamon syrup"
+#define REAGENT_ID_SYRUPCINNAMON "syrup_cinnamon"
+#define REAGENT_SYRUPPISTACHIO "pistachio syrup"
+#define REAGENT_ID_SYRUPPISTACHIO "syrup_pistachio"
+#define REAGENT_SYRUPVANILLA "vanilla syrup"
+#define REAGENT_ID_SYRUPVANILLA "syrup_vanilla"
+#define REAGENT_SYRUPTOFFEE "toffee syrup"
+#define REAGENT_ID_SYRUPTOFFEE "syrup_toffee"
+#define REAGENT_SYRUPCHERRY "cherry syrup"
+#define REAGENT_ID_SYRUPCHERRY "syrup_cherry"
+#define REAGENT_SYRUPBUTTERSCOTCH "butterscotch syrup"
+#define REAGENT_ID_SYRUPBUTTERSCOTCH "syrup_butterscotch"
+#define REAGENT_SYRUPCHOCOLATE "chocolate syrup"
+#define REAGENT_ID_SYRUPCHOCOLATE "syrup_chocolate"
+#define REAGENT_SYRUPWHITECHOCOLATE "white chocolate syrup"
+#define REAGENT_ID_SYRUPWHITECHOCOLATE "syrup_white_chocolate"
+#define REAGENT_SYRUPSTRAWBERRY "strawberry syrup"
+#define REAGENT_ID_SYRUPSTRAWBERRY "syrup_strawberry"
+#define REAGENT_SYRUPCOCONUT "coconut syrup"
+#define REAGENT_ID_SYRUPCOCONUT "syrup_coconut"
+#define REAGENT_SYRUPGINGER "ginger syrup"
+#define REAGENT_ID_SYRUPGINGER "syrup_ginger"
+#define REAGENT_SYRUPGINGERBREAD "gingerbread syrup"
+#define REAGENT_ID_SYRUPGINGERBREAD "syrup_gingerbread"
+#define REAGENT_SYRUPPEPPERMINT "peppermint syrup"
+#define REAGENT_ID_SYRUPPEPPERMINT "syrup_peppermint"
+#define REAGENT_SYRUPBIRTHDAY "birthday cake syrup"
+#define REAGENT_ID_SYRUPBIRTHDAY "syrup_birthday"
+
+// Alcohol
+#define REAGENT_ABSINTHE "Absinthe"
+#define REAGENT_ID_ABSINTHE "absinthe"
+#define REAGENT_ALE "Ale"
+#define REAGENT_ID_ALE "ale"
+#define REAGENT_BEER "Beer"
+#define REAGENT_ID_BEER "beer"
+#define REAGENT_LITEBEER "Lite Beer"
+#define REAGENT_ID_LITEBEER "litebeer"
+#define REAGENT_BLUECURACAO "Blue Curacao"
+#define REAGENT_ID_BLUECURACAO "bluecuracao"
+#define REAGENT_COGNAC "Cognac"
+#define REAGENT_ID_COGNAC "cognac"
+#define REAGENT_DEADRUM "Deadrum"
+#define REAGENT_ID_DEADRUM "deadrum"
+#define REAGENT_FIREPUNCH "Fire Punch"
+#define REAGENT_ID_FIREPUNCH "firepunch"
+#define REAGENT_GIN "Gin"
+#define REAGENT_ID_GIN "gin"
+#define REAGENT_KAHLUA "Kahlua"
+#define REAGENT_ID_KAHLUA "kahlua"
+#define REAGENT_MELONLIQUOR "Melon Liquor"
+#define REAGENT_ID_MELONLIQUOR "melonliquor"
+#define REAGENT_MELONSPRITZER "Melon Spritzer"
+#define REAGENT_ID_MELONSPRITZER "melonspritzer"
+#define REAGENT_RUM "Rum"
+#define REAGENT_ID_RUM "rum"
+#define REAGENT_SAKE "Sake"
+#define REAGENT_ID_SAKE "sake"
+#define REAGENT_SEXONTHEBEACH "Sex On The Beach"
+#define REAGENT_ID_SEXONTHEBEACH "sexonthebeach"
+#define REAGENT_TEQUILLA "Tequila"
+#define REAGENT_ID_TEQUILLA "tequilla"
+#define REAGENT_THIRTEENLOKO "Thirteen Loko"
+#define REAGENT_ID_THIRTEENLOKO "thirteenloko"
+#define REAGENT_VERMOUTH "Vermouth"
+#define REAGENT_ID_VERMOUTH "vermouth"
+#define REAGENT_VODKA "Vodka"
+#define REAGENT_ID_VODKA "vodka"
+#define REAGENT_WHISKEY "Whiskey"
+#define REAGENT_ID_WHISKEY "whiskey"
+#define REAGENT_REDWINE "Red Wine"
+#define REAGENT_ID_REDWINE "redwine"
+#define REAGENT_WHITEWINE "White Wine"
+#define REAGENT_ID_WHITEWINE "whitewine"
+#define REAGENT_CARNOTH "Carnoth"
+#define REAGENT_ID_CARNOTH "carnoth"
+#define REAGENT_PWINE "Poison Wine"
+#define REAGENT_ID_PWINE "pwine"
+#define REAGENT_CHAMPAGNE "Champagne"
+#define REAGENT_ID_CHAMPAGNE "champagne"
+#define REAGENT_CIDER "Cider"
+#define REAGENT_ID_CIDER "cider"
+
+// Cocktails
+#define REAGENT_ACIDSPIT "Acid Spit"
+#define REAGENT_ID_ACIDSPIT "acidspit"
+#define REAGENT_ALLIESCOCKTAIL "Allies Cocktail"
+#define REAGENT_ID_ALLIESCOCKTAIL "alliescocktail"
+#define REAGENT_ALOE "Aloe"
+#define REAGENT_ID_ALOE "aloe"
+#define REAGENT_AMASEC "Amasec"
+#define REAGENT_ID_AMASEC "amasec"
+#define REAGENT_ANDALUSIA "Andalusia"
+#define REAGENT_ID_ANDALUSIA "andalusia"
+#define REAGENT_ANTIFREEZE "Anti-freeze"
+#define REAGENT_ID_ANTIFREEZE "antifreeze"
+#define REAGENT_ATOMICBOMB "Atomic Bomb"
+#define REAGENT_ID_ATOMICBOMB "atomicbomb"
+#define REAGENT_B52 "B-52"
+#define REAGENT_ID_B52 "b52"
+#define REAGENT_BAHAMAMAMA "Bahama mama"
+#define REAGENT_ID_BAHAMAMAMA "bahama_mama"
+#define REAGENT_BANANAHONK "Banana Mama"
+#define REAGENT_ID_BANANAHONK "bananahonk"
+#define REAGENT_BAREFOOT "Barefoot"
+#define REAGENT_ID_BAREFOOT "barefoot"
+#define REAGENT_BEEPSKYSMASH "Beepsky Smash"
+#define REAGENT_ID_BEEPSKYSMASH "beepskysmash"
+#define REAGENT_BILK "Bilk"
+#define REAGENT_ID_BILK "bilk"
+#define REAGENT_BLACKRUSSIAN "Black Russian"
+#define REAGENT_ID_BLACKRUSSIAN "blackrussian"
+#define REAGENT_BLOODYMARY "Bloody Mary"
+#define REAGENT_ID_BLOODYMARY "bloodymary"
+#define REAGENT_BOOGER "Booger"
+#define REAGENT_ID_BOOGER "booger"
+#define REAGENT_BRAVEBULL "Brave Bull"
+#define REAGENT_ID_BRAVEBULL "bravebull"
+#define REAGENT_CHANGELINGSTING "Changeling Sting"
+#define REAGENT_ID_CHANGELINGSTING "changelingsting"
+#define REAGENT_MARTINI "Classic Martini"
+#define REAGENT_ID_MARTINI "martini"
+#define REAGENT_CUBALIBRE "Cuba Libre"
+#define REAGENT_ID_CUBALIBRE "cubalibre"
+#define REAGENT_RUMANDCOLA "Rum and Cola"
+#define REAGENT_ID_RUMANDCOLA "rumandcola"
+#define REAGENT_DEMONSBLOOD "Demons Blood"
+#define REAGENT_ID_DEMONSBLOOD "demonsblood"
+#define REAGENT_DEVILSKISS "Devils Kiss"
+#define REAGENT_ID_DEVILSKISS "devilskiss"
+#define REAGENT_DRIESTMARTINI "Driest Martini"
+#define REAGENT_ID_DRIESTMARTINI "driestmartini"
+#define REAGENT_GINFIZZ "Gin Fizz"
+#define REAGENT_ID_GINFIZZ "ginfizz"
+#define REAGENT_GROG "Grog"
+#define REAGENT_ID_GROG "grog"
+#define REAGENT_ERIKASURPRISE "Erika Surprise"
+#define REAGENT_ID_ERIKASURPRISE "erikasurprise"
+#define REAGENT_GARGLEBLASTER "Pan-Galactic Gargle Blaster"
+#define REAGENT_ID_GARGLEBLASTER "gargleblaster"
+#define REAGENT_GINTONIC "Gin and Tonic"
+#define REAGENT_ID_GINTONIC "gintonic"
+#define REAGENT_GOLDSCHLAGER "Goldschlager"
+#define REAGENT_ID_GOLDSCHLAGER "goldschlager"
+#define REAGENT_HIPPIESDELIGHT "Hippies' Delight"
+#define REAGENT_ID_HIPPIESDELIGHT "hippiesdelight"
+#define REAGENT_HOOCH "Hooch"
+#define REAGENT_ID_HOOCH "hooch"
+#define REAGENT_ICEDBEER "Iced Beer"
+#define REAGENT_ID_ICEDBEER "iced_beer"
+#define REAGENT_IRISHCARBOMB "Irish Car Bomb"
+#define REAGENT_ID_IRISHCARBOMB "irishcarbomb"
+#define REAGENT_IRISHCOFFEE "Irish Coffee"
+#define REAGENT_ID_IRISHCOFFEE "irishcoffee"
+#define REAGENT_IRISHCREAM "Irish Cream"
+#define REAGENT_ID_IRISHCREAM "irishcream"
+#define REAGENT_LONGISLANDICEDTEA "Long Island Iced Tea"
+#define REAGENT_ID_LONGISLANDICEDTEA "longislandicedtea"
+#define REAGENT_MANHATTAN "Manhattan"
+#define REAGENT_ID_MANHATTAN "manhattan"
+#define REAGENT_MANHATTANPROJ "Manhattan Project"
+#define REAGENT_ID_MANHATTANPROJ "manhattan_proj"
+#define REAGENT_MANLYDORF "The Manly Dorf"
+#define REAGENT_ID_MANLYDORF "manlydorf"
+#define REAGENT_MARGARITA "Margarita"
+#define REAGENT_ID_MARGARITA "margarita"
+#define REAGENT_MEAD "Mead"
+#define REAGENT_ID_MEAD "mead"
+#define REAGENT_MOONSHINE "Moonshine"
+#define REAGENT_ID_MOONSHINE "moonshine"
+#define REAGENT_NEUROTOXIN "Neurotoxin"
+#define REAGENT_ID_NEUROTOXIN "neurotoxin"
+#define REAGENT_PATRON "Patron"
+#define REAGENT_ID_PATRON "patron"
+#define REAGENT_REDMEAD "Red Mead"
+#define REAGENT_ID_REDMEAD "red_mead"
+#define REAGENT_SBITEN "Sbiten"
+#define REAGENT_ID_SBITEN "sbiten"
+#define REAGENT_SCREWDRIVERCOCKTAIL "Screwdriver"
+#define REAGENT_ID_SCREWDRIVERCOCKTAIL "screwdrivercocktail"
+#define REAGENT_SILENCER "Silencer"
+#define REAGENT_ID_SILENCER "silencer"
+#define REAGENT_SINGULO "Singulo"
+#define REAGENT_ID_SINGULO "singulo"
+#define REAGENT_SNOWWHITE "Snow White"
+#define REAGENT_ID_SNOWWHITE "snowwhite"
+#define REAGENT_SUIDREAM "Sui Dream"
+#define REAGENT_ID_SUIDREAM "suidream"
+#define REAGENT_SYNDICATEBOMB "Syndicate Bomb"
+#define REAGENT_ID_SYNDICATEBOMB "syndicatebomb"
+#define REAGENT_TEQUILLASUNRISE "Tequila Sunrise"
+#define REAGENT_ID_TEQUILLASUNRISE "tequillasunrise"
+#define REAGENT_THREEMILEISLAND "Three Mile Island Iced Tea"
+#define REAGENT_ID_THREEMILEISLAND "threemileisland"
+#define REAGENT_PHORONSPECIAL "Toxins Special"
+#define REAGENT_ID_PHORONSPECIAL "phoronspecial"
+#define REAGENT_VODKAMARTINI "Vodka Martini"
+#define REAGENT_ID_VODKAMARTINI "vodkamartini"
+#define REAGENT_VODKATONIC "Vodka and Tonic"
+#define REAGENT_ID_VODKATONIC "vodkatonic"
+#define REAGENT_WHITERUSSIAN "White Russian"
+#define REAGENT_ID_WHITERUSSIAN "whiterussian"
+#define REAGENT_WHISKEYCOLA "Whiskey Cola"
+#define REAGENT_ID_WHISKEYCOLA "whiskeycola"
+#define REAGENT_WHISKEYSODA "Whiskey Soda"
+#define REAGENT_ID_WHISKEYSODA "whiskeysoda"
+#define REAGENT_SPECIALWHISKEY "Special Blend Whiskey"
+#define REAGENT_ID_SPECIALWHISKEY "specialwhiskey"
+#define REAGENT_UNATHILIQUOR "Redeemer's Brew"
+#define REAGENT_ID_UNATHILIQUOR "unathiliquor"
+#define REAGENT_SAKEBOMB "Sake Bomb"
+#define REAGENT_ID_SAKEBOMB "sakebomb"
+#define REAGENT_TAMAGOZAKE "Tamagozake"
+#define REAGENT_ID_TAMAGOZAKE "tamagozake"
+#define REAGENT_GINZAMARY "Ginza Mary"
+#define REAGENT_ID_GINZAMARY "ginzamary"
+#define REAGENT_TOKYOROSE "Tokyo Rose"
+#define REAGENT_ID_TOKYOROSE "tokyorose"
+#define REAGENT_SAKETINI "Saketini"
+#define REAGENT_ID_SAKETINI "saketini"
+#define REAGENT_ELYSIUMFACEPUNCH "Elysium Facepunch"
+#define REAGENT_ID_ELYSIUMFACEPUNCH "elysiumfacepunch"
+#define REAGENT_EREBUSMOONRISE "Erebus Moonrise"
+#define REAGENT_ID_EREBUSMOONRISE "erebusmoonrise"
+#define REAGENT_BALLOON "Balloon"
+#define REAGENT_ID_BALLOON "balloon"
+#define REAGENT_NATUNABRANDY "Natuna Brandy"
+#define REAGENT_ID_NATUNABRANDY "natunabrandy"
+#define REAGENT_EUPHORIA "Euphoria"
+#define REAGENT_ID_EUPHORIA "euphoria"
+#define REAGENT_XANADUCANNON "Xanadu Cannon"
+#define REAGENT_ID_XANADUCANNON "xanaducannon"
+#define REAGENT_DEBUGGER "Debugger"
+#define REAGENT_ID_DEBUGGER "debugger"
+#define REAGENT_SPACERSBREW "Spacer's Brew"
+#define REAGENT_ID_SPACERSBREW "spacersbrew"
+#define REAGENT_BINMANBLISS "Binman Bliss"
+#define REAGENT_ID_BINMANBLISS "binmanbliss"
+#define REAGENT_CHRYSANTHEMUM "Chrysanthemum"
+#define REAGENT_ID_CHRYSANTHEMUM "chrysanthemum"
+#define REAGENT_BITTERS "Bitters"
+#define REAGENT_ID_BITTERS "bitters"
+#define REAGENT_SOEMMERFIRE "Soemmer Fire"
+#define REAGENT_ID_SOEMMERFIRE "soemmerfire"
+#define REAGENT_WINEBRANDY "Wine Brandy"
+#define REAGENT_ID_WINEBRANDY "winebrandy"
+#define REAGENT_MORNINGAFTER "Morning After"
+#define REAGENT_ID_MORNINGAFTER "morningafter"
+#define REAGENT_VESPER "Vesper"
+#define REAGENT_ID_VESPER "vesper"
+#define REAGENT_ROTGUT "Rotgut Fever Dream"
+#define REAGENT_ID_ROTGUT "rotgut"
+#define REAGENT_VOXDELIGHT "Vox's Delight"
+#define REAGENT_ID_VOXDELIGHT "voxdelight"
+#define REAGENT_SCREAMINGVIKING "Screaming Viking"
+#define REAGENT_ID_SCREAMINGVIKING "screamingviking"
+#define REAGENT_ROBUSTIN "Robustin"
+#define REAGENT_ID_ROBUSTIN "robustin"
+#define REAGENT_VIRGINSIP "Virgin Sip"
+#define REAGENT_ID_VIRGINSIP "virginsip"
+#define REAGENT_JELLYSHOT "Jelly Shot"
+#define REAGENT_ID_JELLYSHOT "jellyshot"
+#define REAGENT_SLIMESHOT "Named Bullet"
+#define REAGENT_ID_SLIMESHOT "slimeshot"
+#define REAGENT_CLOVERCLUB "Clover Club"
+#define REAGENT_ID_CLOVERCLUB "cloverclub"
+#define REAGENT_NEGRONI "Negroni"
+#define REAGENT_ID_NEGRONI "negroni"
+#define REAGENT_WHISKEYSOUR "Whiskey Sour"
+#define REAGENT_ID_WHISKEYSOUR "whiskeysour"
+#define REAGENT_OLDFASHIONED "Old Fashioned"
+#define REAGENT_ID_OLDFASHIONED "oldfashioned"
+#define REAGENT_DAIQUIRI "Daiquiri"
+#define REAGENT_ID_DAIQUIRI "daiquiri"
+#define REAGENT_MOJITO "Mojito"
+#define REAGENT_ID_MOJITO "mojito"
+#define REAGENT_PALOMA "Paloma"
+#define REAGENT_ID_PALOMA "paloma"
+#define REAGENT_PISCOSOUR "Pisco Sour"
+#define REAGENT_ID_PISCOSOUR "piscosour"
+#define REAGENT_COLDFRONT "Cold Front"
+#define REAGENT_ID_COLDFRONT "coldfront"
+#define REAGENT_MINTJULEP "Mint Julep"
+#define REAGENT_ID_MINTJULEP "mintjulep"
+#define REAGENT_GODSAKE "Gods Sake"
+#define REAGENT_ID_GODSAKE "godsake"
+#define REAGENT_GODKA "Godka"
+#define REAGENT_ID_GODKA "godka"
+#define REAGENT_HOLYWINE "Angel Ichor"
+#define REAGENT_ID_HOLYWINE "holywine"
+#define REAGENT_HOLYMARY "Holy Mary"
+#define REAGENT_ID_HOLYMARY "holymary"
+#define REAGENT_ANGELSWRATH "Angels Wrath"
+#define REAGENT_ID_ANGELSWRATH "angelswrath"
+#define REAGENT_ANGELSKISS "Angels Kiss"
+#define REAGENT_ID_ANGELSKISS "angelskiss"
+#define REAGENT_ICHORMEAD "Ichor Mead"
+#define REAGENT_ID_ICHORMEAD "ichor_mead"
+#define REAGENT_SCHNAPPSPEP "Peppermint Schnapps"
+#define REAGENT_ID_SCHNAPPSPEP "schnapps_pep"
+#define REAGENT_SCHNAPPSPEA "Peach Schnapps"
+#define REAGENT_ID_SCHNAPPSPEA "schnapps_pea"
+#define REAGENT_SCHNAPPSLEM "Lemonade Schnapps"
+#define REAGENT_ID_SCHNAPPSLEM "schnapps_lem"
+#define REAGENT_JAGER "Schuss Konig"
+#define REAGENT_ID_JAGER "jager"
+#define REAGENT_FUSIONNAIRE "Fusionnaire"
+#define REAGENT_ID_FUSIONNAIRE "fusionnaire"
+#define REAGENT_DEATHBELL "Deathbell"
+#define REAGENT_ID_DEATHBELL "deathbell"
+#define REAGENT_MAGICDUST "Magic Dust"
+#define REAGENT_ID_MAGICDUST "magicdust"
+#define REAGENT_KOMPOT "Kompot"
+#define REAGENT_ID_KOMPOT "kompot"
+#define REAGENT_KVASS "Kvass"
+#define REAGENT_ID_KVASS "kvass"
+
+
+// Toxins
+#define REAGENT_TOXIN "Toxin"
+#define REAGENT_ID_TOXIN "toxin"
+#define REAGENT_PACID "Polytrinic acid"
+#define REAGENT_ID_PACID "pacid"
+#define REAGENT_PHORON "Phoron"
+#define REAGENT_ID_PHORON "phoron"
+#define REAGENT_SPIDERTOXIN "Spidertoxin"
+#define REAGENT_ID_SPIDERTOXIN "spidertoxin"
+#define REAGENT_LEAD "Lead"
+#define REAGENT_ID_LEAD "lead"
+#define REAGENT_PLASTICIDE "Plasticide"
+#define REAGENT_ID_PLASTICIDE "plasticide"
+#define REAGENT_AMATOXIN "Amatoxin"
+#define REAGENT_ID_AMATOXIN "amatoxin"
+#define REAGENT_CARPOTOXIN "Carpotoxin"
+#define REAGENT_ID_CARPOTOXIN "carpotoxin"
+#define REAGENT_NEUROTOXIC_PROTEIN "toxic protein"
+#define REAGENT_ID_NEUROTOXIC_PROTEIN "neurotoxic_protein"
+#define REAGENT_HYDROPHORON "Hydrophoron"
+#define REAGENT_ID_HYDROPHORON "hydrophoron"
+#define REAGENT_CYANIDE "Cyanide"
+#define REAGENT_ID_CYANIDE "cyanide"
+#define REAGENT_MOLD "Mold"
+#define REAGENT_ID_MOLD "mold"
+#define REAGENT_EXPIREDMEDICINE "Expired Medicine"
+#define REAGENT_ID_EXPIREDMEDICINE "expired_medicine"
+#define REAGENT_STIMM "Stimm"
+#define REAGENT_ID_STIMM "stimm"
+#define REAGENT_POTASSIUMCHLORIDE "Potassium Chloride"
+#define REAGENT_ID_POTASSIUMCHLORIDE "potassium_chloride"
+#define REAGENT_POTASSIUMCHLOROPHORIDE "Potassium Chlorophoride"
+#define REAGENT_ID_POTASSIUMCHLOROPHORIDE "potassium_chlorophoride"
+#define REAGENT_ZOMBIEPOWDER "Zombie Powder"
+#define REAGENT_ID_ZOMBIEPOWDER "zombiepowder"
+#define REAGENT_LICHPOWDER "Lich Powder"
+#define REAGENT_ID_LICHPOWDER "lichpowder"
+#define REAGENT_FERTILIZER "Fertilizer"
+#define REAGENT_ID_FERTILIZER "fertilizer"
+#define REAGENT_EZNUTRIENT "EZ Nutrient"
+#define REAGENT_ID_EZNUTRIENT "eznutrient"
+#define REAGENT_LEFT4ZED "Left-4-Zed"
+#define REAGENT_ID_LEFT4ZED "left4zed"
+#define REAGENT_ROBUSTHARVEST "Robust Harvest"
+#define REAGENT_ID_ROBUSTHARVEST "robustharvest"
+#define REAGENT_TANNIN "Tannin"
+#define REAGENT_ID_TANNIN "tannin"
+#define REAGENT_PLANTBGONE "Plant-B-Gone"
+#define REAGENT_ID_PLANTBGONE "plantbgone"
+#define REAGENT_SIFSAP "Sivian Sap"
+#define REAGENT_ID_SIFSAP "sifsap"
+#define REAGENT_STOMACID "Digestive acid"
+#define REAGENT_ID_STOMACID "stomacid"
+#define REAGENT_THERMITEV "Pyrotoxin"
+#define REAGENT_ID_THERMITEV "thermite_v"
+#define REAGENT_CONDENSEDCAPSAICINV "Irritant toxin"
+#define REAGENT_ID_CONDENSEDCAPSAICINV "condensedcapsaicin_v"
+#define REAGENT_LEXORIN "Lexorin"
+#define REAGENT_ID_LEXORIN "lexorin"
+#define REAGENT_MUTAGEN "Unstable mutagen"
+#define REAGENT_ID_MUTAGEN "mutagen"
+#define REAGENT_SLIMEJELLY "Slime Jelly"
+#define REAGENT_ID_SLIMEJELLY "slimejelly"
+#define REAGENT_STOXIN "Soporific"
+#define REAGENT_ID_STOXIN "stoxin"
+#define REAGENT_CHLORALHYDRATE "Chloral Hydrate"
+#define REAGENT_ID_CHLORALHYDRATE "chloralhydrate"
+#define REAGENT_BEER2 REAGENT_BEER
+#define REAGENT_ID_BEER2 "beer2"
+#define REAGENT_SEROTROTIUM "Serotrotium"
+#define REAGENT_ID_SEROTROTIUM "serotrotium"
+#define REAGENT_SEROTROTIUMV "Serotropic venom"
+#define REAGENT_ID_SEROTROTIUMV "serotrotium_v"
+#define REAGENT_CRYPTOBIOLIN "Cryptobiolin"
+#define REAGENT_ID_CRYPTOBIOLIN "cryptobiolin"
+#define REAGENT_IMPEDREZENE "Impedrezene"
+#define REAGENT_ID_IMPEDREZENE "impedrezene"
+#define REAGENT_MINDBREAKER "Mindbreaker Toxin"
+#define REAGENT_ID_MINDBREAKER "mindbreaker"
+#define REAGENT_MUTATIONTOXIN "Mutation Toxin"
+#define REAGENT_ID_MUTATIONTOXIN "mutationtoxin"
+#define REAGENT_DOCILITYTOXIN "Docility Toxin"
+#define REAGENT_ID_DOCILITYTOXIN "docilitytoxin"
+#define REAGENT_SHREDDINGNANITES REAGENT_HEALINGNANITES
+#define REAGENT_ID_SHREDDINGNANITES "shredding_nanites"
+#define REAGENT_IRRADIATEDNANITES REAGENT_HEALINGNANITES
+#define REAGENT_ID_IRRADIATEDNANITES "irradiated_nanites"
+#define REAGENT_NEUROPHAGENANITES REAGENT_HEALINGNANITES
+#define REAGENT_ID_NEUROPHAGENANITES "neurophage_nanites"
+#define REAGENT_SALMONELLA "Salmonella"
+#define REAGENT_ID_SALMONELLA "salmonella"
+#define REAGENT_METAMORPHIC "Metamorphic Metal"
+#define REAGENT_ID_METAMORPHIC "metamorphic"
+#define REAGENT_BINDING "Binding Metal"
+#define REAGENT_ID_BINDING "binding"
+
+
+// Xenoslimes
+#define REAGENT_SLIMEBLEEDFIXER "Agent A"
+#define REAGENT_ID_SLIMEBLEEDFIXER "slime_bleed_fixer"
+#define REAGENT_SLIMEBONEFIXER "Agent B"
+#define REAGENT_ID_SLIMEBONEFIXER "slime_bone_fixer"
+#define REAGENT_SLIMEORGANFIXER "Agent C"
+#define REAGENT_ID_SLIMEORGANFIXER "slime_organ_fixer"
diff --git a/code/__defines/admin.dm b/code/__defines/admin.dm
index 4895a51ae6..e4934f522b 100644
--- a/code/__defines/admin.dm
+++ b/code/__defines/admin.dm
@@ -48,26 +48,26 @@
#define SMITE_LIGHTNINGBOLT "Lightning Bolt"
#define SMITE_TERROR "Terrify"
-#define ADMIN_QUE(user) "(?)"
-#define ADMIN_FLW(user) "(FLW)"
-#define ADMIN_PP(user) "(PP)"
-#define ADMIN_VV(atom) "(VV)"
-#define ADMIN_SM(user) "(SM)"
-#define ADMIN_TP(user) "(TP)"
-#define ADMIN_BSA(user) "(BSA)"
-#define ADMIN_KICK(user) "(KICK)"
-#define ADMIN_CENTCOM_REPLY(user) "(RPLY)"
-#define ADMIN_SYNDICATE_REPLY(user) "(RPLY)"
-#define ADMIN_SC(user) "(SC)"
-#define ADMIN_SMITE(user) "(SMITE)"
+#define ADMIN_QUE(user) "(?)"
+#define ADMIN_FLW(user) "(FLW)"
+#define ADMIN_PP(user) "(PP)"
+#define ADMIN_VV(atom) "(VV)"
+#define ADMIN_SM(user) "(SM)"
+#define ADMIN_TP(user) "(TP)"
+#define ADMIN_BSA(user) "(BSA)"
+#define ADMIN_KICK(user) "(KICK)"
+#define ADMIN_CENTCOM_REPLY(user) "(RPLY)"
+#define ADMIN_SYNDICATE_REPLY(user) "(RPLY)"
+#define ADMIN_SC(user) "(SC)"
+#define ADMIN_SMITE(user) "(SMITE)"
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)]"
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]"
-#define ADMIN_JMP(src) "(JMP)"
+#define ADMIN_JMP(src) "(JMP)"
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
-#define ADMIN_CA(user) "(?)"
+#define ADMIN_CA(user) "(?)"
#define AHELP_ACTIVE 1
#define AHELP_CLOSED 2
diff --git a/code/__defines/belly_modes_vr.dm b/code/__defines/belly_modes_vr.dm
index b0e7976dbd..266d2f583a 100644
--- a/code/__defines/belly_modes_vr.dm
+++ b/code/__defines/belly_modes_vr.dm
@@ -43,3 +43,9 @@
#define DR_SLEEP "Sleep"
#define DR_FAKE "False Sleep"
#define DR_WEIGHT "Weight Drain"
+
+//Vore Sprite Flags
+#define DM_FLAG_VORESPRITE_BELLY 0x1
+#define DM_FLAG_VORESPRITE_TAIL 0x2
+#define DM_FLAG_VORESPRITE_MARKING 0x4
+#define DM_FLAG_VORESPRITE_ARTICLE 0x8
diff --git a/code/__defines/borg_overlays.dm b/code/__defines/borg_overlays.dm
new file mode 100644
index 0000000000..bc5365e25e
--- /dev/null
+++ b/code/__defines/borg_overlays.dm
@@ -0,0 +1,61 @@
+/// This file contains everything that involves the borg overlay system that is applied to borgs in robot/sprites_sprite_datum.dm
+
+/// These are applied ON /datum/robot_sprite to tell it what overlays it can or can not have.
+
+/// If you make a borg that has a laser, taser, and shield, here's an Example:
+/// sprite_flags = ROBOT_HAS_LASER_SPRITE | ROBOT_HAS_TASER_SPRITE | ROBOT_HAS_SHIELD_SPRITE
+
+/// NOTES: You are NOT EXPECTED TO HAVE A GUN SPRITE IF YOU HAVE A DEDICATED LASER/TASER/DISABLER SPRITE. Doing so will cause BAD THINGS to happen!!!
+/// IMPORTANT: Flags operate on a 1 2 4 8 10 20 40 80 100 200 400 800 1000 2000 4000 8000 etc system. Not 1 2 4 8 16 32 64 like I thought at first (oops)
+#define ROBOT_HAS_SPEED_SPRITE 0x1 //Ex: /obj/item/borg/combat/mobility Replaces old has_speed_sprite
+#define ROBOT_HAS_SHIELD_SPRITE 0x2 //Ex: /obj/item/borg/combat/shield Replaces old has_shield_sprite
+#define ROBOT_HAS_SHIELD_SPEED_SPRITE 0x4 //Ex: Has a sprite for when both is activated AND has /obj/item/borg/combat/mobility
+#define ROBOT_HAS_LASER_SPRITE 0x8 //Ex: /obj/item/gun/energy/robotic/laser Replaces old has_laser_sprite
+#define ROBOT_HAS_TASER_SPRITE 0x10 //Ex: /obj/item/gun/energy/robotic/taser Replaces old has_taser_sprite
+#define ROBOT_HAS_GUN_SPRITE 0x20 //Ex: Has a general gun sprite. Replaces old has_gun_sprite
+#define ROBOT_HAS_DISABLER_SPRITE 0x40 //Ex: /obj/item/gun/energy/taser/mounted/cyborg/ertgun HOWEVER it is not used on this codebase (Virgo) but may be used downstream.
+
+#define ROBOT_HAS_MELEE_SPRITE 0x80 //Ex: Generic borg melee
+#define ROBOT_HAS_DAGGER_SPRITE 0x100 //Ex: Specialized dagger.
+#define ROBOT_HAS_BLADE_SPRITE 0x200 //Ex: Specialized blade
+/// For sanity's sake for you spriters out there that don't want to dig through the code, attach the below as a suffix for your sprites:
+/// Speed: -roll
+/// Shield: -shield
+/// Both: -speed_shield
+
+/// Laser: -laser
+/// Taser: -taser
+/// Gun: -gun
+/// Disabler: -disabler
+
+/// Melee: -melee
+/// Blade: -blade
+/// Dagger: -dagger
+
+/// GUN DEFINES
+/// These are applied on GUNS to classify them as a GUN, TASER, OR LASER.
+/// So every borg weapon is a child of '/obj/item/gun/energy/robotic' and given the 'laser' 'taser' 'gun' etc flag. ALL guns have 'gun' by default.
+#define COUNTS_AS_ROBOT_GUN 0x1
+#define COUNTS_AS_ROBOT_TASER 0x2
+#define COUNTS_AS_ROBOT_LASER 0x4
+#define COUNTS_AS_ROBOT_DISABLER 0x8
+
+/// MELEE WEAPON DEFINES
+/// These are applied on MELEE WEAPONS to classify them as MELEE WEAPONS that give sprites.
+/// Use 'melee' if your borg ONLY has a generic melee sprite. If they have more unique sprites, use the other ones!
+/// Currently, only the borg blade is used. But you could expand this define list!
+#define COUNTS_AS_ROBOTIC_MELEE 0x1
+#define COUNTS_AS_ROBOT_DAGGER 0x2
+#define COUNTS_AS_ROBOT_BLADE 0x4
+
+/// ADDITIONAL NOTES:
+/// If you want to have a special type of item that will be used on borgs that is NOT a gun OR is not included above that causes an overlay, have no fear!
+/// Currently, the SHIELD, SPEED, and both are included. If you want your borg to have a cool special overlay, use 'handle_extra_icon_updates'!
+/// Here's an example:
+
+/*
+/datum/robot_sprite/combat/fluff/foopwotch/handle_extra_icon_updates(var/mob/living/silicon/robot/ourborg) //Make sure the path is correct!
+ ..() //THIS IS ESSENTIAL. IF YOU FORGET THIS LINE, YOU WILL NOT GET THE NORMAL SPRITES.
+ if(ourborg.has_active_type(/obj/item/weapon/combat_borgblade))
+ ourborg.add_overlay("[sprite_icon_state]-dagger")
+*/
diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm
index 8213aa200f..8073d6a8ca 100644
--- a/code/__defines/chemistry.dm
+++ b/code/__defines/chemistry.dm
@@ -49,10 +49,10 @@
#define ANTIBIO_SUPER 3
// Chemistry lists.
-var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine") // Increase heart rate.
-var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "bliss", "stoxin", "ambrosia_extract") // Decrease heart rate.
-var/list/heartstopper = list("potassium_chlorophoride", "zombiepowder") // This stops the heart.
-var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional
+var/list/tachycardics = list(REAGENT_ID_COFFEE, REAGENT_ID_INAPROVALINE, REAGENT_ID_HYPERZINE, REAGENT_ID_NITROGLYCERIN,REAGENT_ID_THIRTEENLOKO, REAGENT_ID_NICOTINE) // Increase heart rate.
+var/list/bradycardics = list(REAGENT_ID_NEUROTOXIN, REAGENT_ID_CRYOXADONE, REAGENT_ID_CLONEXADONE, REAGENT_ID_BLISS, REAGENT_ID_STOXIN, REAGENT_ID_AMBROSIAEXTRACT) // Decrease heart rate.
+var/list/heartstopper = list(REAGENT_ID_POTASSIUMCHLOROPHORIDE, REAGENT_ID_ZOMBIEPOWDER) // This stops the heart.
+var/list/cheartstopper = list(REAGENT_ID_POTASSIUMCHLORIDE) // This stops the heart when overdose is met. -- c = conditional
#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites
#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites
diff --git a/code/__defines/dna.dm b/code/__defines/dna.dm
index 10fe4d729b..b958466201 100644
--- a/code/__defines/dna.dm
+++ b/code/__defines/dna.dm
@@ -154,3 +154,9 @@ var/SMALLSIZEBLOCK = 0
#define DNA2_BUF_UI 1
#define DNA2_BUF_UE 2
#define DNA2_BUF_SE 4
+
+// Mutation flags
+#define MUTCHK_FORCED 1
+
+// Gene flags
+#define GENE_ALWAYS_ACTIVATE 1
diff --git a/code/__defines/is_helpers.dm b/code/__defines/is_helpers.dm
index 1039819289..fff94f906e 100644
--- a/code/__defines/is_helpers.dm
+++ b/code/__defines/is_helpers.dm
@@ -68,3 +68,6 @@
#define istaurtail(A) istype(A, /datum/sprite_accessory/tail/taur)
#define islongtail(A) istype(A, /datum/sprite_accessory/tail/longtail)
+
+// Diveable water
+#define isdiveablewater(A) istype(A, /turf/simulated/floor/water/deep/ocean/diving)
diff --git a/code/__defines/materials.dm b/code/__defines/materials.dm
index 0e24246954..f4f947d7df 100644
--- a/code/__defines/materials.dm
+++ b/code/__defines/materials.dm
@@ -5,7 +5,7 @@
#define MAT_GLASS "glass"
#define MAT_RGLASS "rglass"
#define MAT_PGLASS "borosilicate glass"
-#define MAT_RPGLASS "reinforced borosilicate glass"
+#define MAT_RPGLASS "reinforced borosilicate glass"
#define MAT_SILVER "silver"
#define MAT_GOLD "gold"
#define MAT_URANIUM "uranium"
@@ -18,7 +18,7 @@
#define MAT_LOG "log"
#define MAT_SIFWOOD "alien wood"
#define MAT_SIFLOG "alien log"
-#define MAT_HARDWOOD "hardwood"
+#define MAT_HARDWOOD "hardwood"
#define MAT_HARDLOG "hardwood log"
#define MAT_STEELHULL "steel hull"
#define MAT_PLASTEEL "plasteel"
@@ -35,12 +35,10 @@
#define MAT_METALHYDROGEN "mhydrogen"
#define MAT_OSMIUM "osmium"
#define MAT_GRAPHITE "graphite"
-#define MAT_LEATHER "leather"
#define MAT_CHITIN "chitin"
-#define MAT_CLOTH "cloth"
+#define MAT_ALIENCHITIN "alien chitin"
+#define MAT_ALIENCLAW "alien claw"
#define MAT_FUR "fur"
-#define MAT_SYNCLOTH "syncloth"
-#define MAT_FIBERS "fibers"
#define MAT_COPPER "copper"
#define MAT_QUARTZ "quartz"
#define MAT_TIN "tin"
@@ -48,15 +46,41 @@
#define MAT_ALUMINIUM "aluminium"
#define MAT_BRONZE "bronze"
#define MAT_PAINITE "painite"
-#define MAT_BOROSILICATE "borosilicate glass"
#define MAT_SANDSTONE "sandstone"
-#define MAT_FLINT "flint"
+#define MAT_FLINT "flint"
#define MAT_PLATINUM "platinum"
#define MAT_TRITIUM "tritium"
#define MAT_DEUTERIUM "deuterium"
#define MAT_CONCRETE "concrete"
#define MAT_PLASTEELREBAR "plasteel rebar"
#define MAT_GRASS "grass"
+#define MAT_RESIN "resin"
+#define MAT_CULT "cult"
+#define MAT_CULT2 "cult2"
+#define MAT_ALIENALLOY "alienalloy"
+#define MAT_COMPOSITE "composite"
+#define MAT_BIOMASS "biomass"
+#define MAT_WEEDEXTRACT "weed extract"
+#define MAT_CARDBOARD "cardboard"
+#define MAT_COTTON "cotton"
+
+// cloth materials
+#define MAT_WOOL "wool"
+#define MAT_FIBERS "fibers"
+#define MAT_LEATHER "leather"
+#define MAT_CLOTH "cloth"
+#define MAT_SYNCLOTH "syncloth"
+#define MAT_CARPET "carpet"
+// colours
+#define MAT_CLOTH_TEAL "teal"
+#define MAT_CLOTH_BLACK "black"
+#define MAT_CLOTH_GREEN "green"
+#define MAT_CLOTH_PURPLE "purple"
+#define MAT_CLOTH_BLUE "blue"
+#define MAT_CLOTH_BEIGE "beige"
+#define MAT_CLOTH_LIME "lime"
+#define MAT_CLOTH_YELLOW "yellow"
+#define MAT_CLOTH_ORANGE "orange"
#define DEFAULT_TABLE_MATERIAL MAT_PLASTIC
@@ -84,4 +108,4 @@
///if the user won't receive a warning when attacking the container with an unallowed item.
#define MATCONTAINER_SILENT (1<<3)
-#define GET_MATERIAL_REF(arguments...) _GetMaterialRef(list(##arguments))
\ No newline at end of file
+#define GET_MATERIAL_REF(arguments...) _GetMaterialRef(list(##arguments))
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 0a96c63bec..ab3d82c281 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -44,7 +44,11 @@
#define SPECIALROLE_HUD 8 // AntagHUD image.
#define STATUS_HUD_OOC 9 // STATUS_HUD without virus DB check for someone being ill.
#define LIFE_HUD 10 // STATUS_HUD that only reports dead or alive
-#define TOTAL_HUDS 10 // Total number of HUDs. Like body layers, and other things, it comes up sometimes.
+#define BACKUP_HUD 11 // HUD for showing whether or not they have a backup implant.
+#define STATUS_R_HUD 12 // HUD for showing the same STATUS_HUD info on the right side, but not for 'boring' statuses (transparent icons)
+#define HEALTH_VR_HUD 13 // HUD with blank 100% bar so it's hidden most of the time.
+#define VANTAG_HUD 14 // HUD for showing being-an-antag-target prefs
+#define TOTAL_HUDS 14 // Total number of HUDs. Like body layers, and other things, it comes up sometimes.
#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (isclient(I) ? I : null))
@@ -108,8 +112,9 @@
#define AREA_ALLOW_LARGE_SIZE 0x400 // If mob size is limited in the area.
#define AREA_BLOCK_SUIT_SENSORS 0x800 // If suit sensors are blocked in the area.
#define AREA_BLOCK_TRACKING 0x1000 // If camera tracking is blocked in the area.
-#define TEMPERATURE_SHIELDED 0x2000 // YW Addition: Temperature change shielding
-#define PHASE_SHIELDED 0x4000 // YW Addition: Prevents shadekin phasing in/out in this area
+#define AREA_BLOCK_GHOST_SIGHT 0x2000 // If an area blocks sight for ghosts
+#define TEMPERATURE_SHIELDED 0x4000 // YW Addition: Temperature change shielding
+#define PHASE_SHIELDED 0x8000 // YW Addition: Prevents shadekin phasing in/out in this area
// OnTopic return values
#define TOPIC_NOACTION 0
@@ -485,3 +490,79 @@ GLOBAL_LIST_INIT(all_volume_channels, list(
// Vote Types
#define VOTE_RESULT_TYPE_MAJORITY "Majority"
#define VOTE_RESULT_TYPE_SKEWED "Seventy"
+
+#define ECO_MODIFIER 10
+
+#define VANTAG_NONE "hudblank"
+#define VANTAG_VORE "vantag_vore"
+#define VANTAG_KIDNAP "vantag_kidnap"
+#define VANTAG_KILL "vantag_kill"
+
+// ColorMate states
+#define COLORMATE_TINT 1
+#define COLORMATE_HSV 2
+#define COLORMATE_MATRIX 3
+
+#define DEPARTMENT_OFFDUTY "Off-Duty"
+
+#define ANNOUNCER_NAME "Facility PA"
+
+//For custom species
+#define STARTING_SPECIES_POINTS 2
+#define MAX_SPECIES_TRAITS 5
+
+// Xenochimera thing mostly
+#define REVIVING_NOW -1
+#define REVIVING_DONE 0
+#define REVIVING_READY 1
+
+// Resleeving Mind Record Status
+#define MR_NORMAL 0
+#define MR_UNSURE 1
+#define MR_DEAD 2
+
+//Shuttle madness!
+#define SHUTTLE_CRASHED 3 // Yup that can happen now
+
+//Herm Gender
+#define HERM "herm"
+
+// Bluespace shelter deploy checks
+#define SHELTER_DEPLOY_ALLOWED "allowed"
+#define SHELTER_DEPLOY_BAD_TURFS "bad turfs"
+#define SHELTER_DEPLOY_BAD_AREA "bad area"
+#define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
+#define SHELTER_DEPLOY_SHIP_SPACE "ship not in space"
+
+#define PTO_SECURITY "Security"
+#define PTO_MEDICAL "Medical"
+#define PTO_ENGINEERING "Engineering"
+#define PTO_SCIENCE "Science"
+#define PTO_EXPLORATION "Exploration"
+#define PTO_CARGO "Cargo"
+#define PTO_CIVILIAN "Civilian"
+#define PTO_CYBORG "Cyborg"
+#define PTO_TALON "Talon Contractor"
+
+#define DEPARTMENT_TALON "ITV Talon"
+
+#define MAT_TITANIUMGLASS "ti-glass"
+#define MAT_PLASTITANIUM "plastitanium"
+#define MAT_PLASTITANIUMHULL "plastitanium hull"
+#define MAT_PLASTITANIUMGLASS "plastitanium glass"
+#define MAT_GOLDHULL "gold hull"
+
+#define RESIZE_MINIMUM 0.25
+#define RESIZE_MAXIMUM 2
+#define RESIZE_MINIMUM_DORMS 0.01
+#define RESIZE_MAXIMUM_DORMS 6
+
+#define RESIZE_HUGE 2
+#define RESIZE_BIG 1.5
+#define RESIZE_NORMAL 1
+#define RESIZE_SMALL 0.5
+#define RESIZE_TINY 0.25
+#define RESIZE_A_HUGEBIG (RESIZE_HUGE + RESIZE_BIG) / 2
+#define RESIZE_A_BIGNORMAL (RESIZE_BIG + RESIZE_NORMAL) / 2
+#define RESIZE_A_NORMALSMALL (RESIZE_NORMAL + RESIZE_SMALL) / 2
+#define RESIZE_A_SMALLTINY (RESIZE_SMALL + RESIZE_TINY) / 2
diff --git a/code/__defines/misc_vr.dm b/code/__defines/misc_vr.dm
deleted file mode 100644
index ab083010b1..0000000000
--- a/code/__defines/misc_vr.dm
+++ /dev/null
@@ -1,84 +0,0 @@
-#define ECO_MODIFIER 10
-
-// Because of omnihud having overlapping issues, we have extra ones.
-#define BACKUP_HUD 11 // HUD for showing whether or not they have a backup implant.
-#define STATUS_R_HUD 12 // HUD for showing the same STATUS_HUD info on the right side, but not for 'boring' statuses (transparent icons)
-#define HEALTH_VR_HUD 13 // HUD with blank 100% bar so it's hidden most of the time.
-#define VANTAG_HUD 14 // HUD for showing being-an-antag-target prefs
-
-#undef TOTAL_HUDS //Undo theirs.
-#define TOTAL_HUDS 14 // Total number of HUDs.
-
-#define VANTAG_NONE "hudblank"
-#define VANTAG_VORE "vantag_vore"
-#define VANTAG_KIDNAP "vantag_kidnap"
-#define VANTAG_KILL "vantag_kill"
-
-// ColorMate states
-#define COLORMATE_TINT 1
-#define COLORMATE_HSV 2
-#define COLORMATE_MATRIX 3
-
-#define DEPARTMENT_OFFDUTY "Off-Duty"
-
-#define ANNOUNCER_NAME "Facility PA"
-
-//For custom species
-#define STARTING_SPECIES_POINTS 2
-#define MAX_SPECIES_TRAITS 5
-
-// Xenochimera thing mostly
-#define REVIVING_NOW -1
-#define REVIVING_DONE 0
-#define REVIVING_READY 1
-
-// Resleeving Mind Record Status
-#define MR_NORMAL 0
-#define MR_UNSURE 1
-#define MR_DEAD 2
-
-//Shuttle madness!
-#define SHUTTLE_CRASHED 3 // Yup that can happen now
-
-//Herm Gender
-#define HERM "herm"
-
-// Bluespace shelter deploy checks
-#define SHELTER_DEPLOY_ALLOWED "allowed"
-#define SHELTER_DEPLOY_BAD_TURFS "bad turfs"
-#define SHELTER_DEPLOY_BAD_AREA "bad area"
-#define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
-#define SHELTER_DEPLOY_SHIP_SPACE "ship not in space"
-
-#define PTO_SECURITY "Security"
-#define PTO_MEDICAL "Medical"
-#define PTO_ENGINEERING "Engineering"
-#define PTO_SCIENCE "Science"
-#define PTO_EXPLORATION "Exploration"
-#define PTO_CARGO "Cargo"
-#define PTO_CIVILIAN "Civilian"
-#define PTO_CYBORG "Cyborg"
-#define PTO_TALON "Talon Contractor"
-
-#define DEPARTMENT_TALON "ITV Talon"
-
-#define MAT_TITANIUMGLASS "ti-glass"
-#define MAT_PLASTITANIUM "plastitanium"
-#define MAT_PLASTITANIUMHULL "plastitanium hull"
-#define MAT_PLASTITANIUMGLASS "plastitanium glass"
-#define MAT_GOLDHULL "gold hull"
-
-#define RESIZE_MINIMUM 0.25
-#define RESIZE_MAXIMUM 2
-#define RESIZE_MINIMUM_DORMS 0.01
-#define RESIZE_MAXIMUM_DORMS 6
-
-#define RESIZE_HUGE 2
-#define RESIZE_BIG 1.5
-#define RESIZE_NORMAL 1
-#define RESIZE_SMALL 0.5
-#define RESIZE_TINY 0.25
-#define RESIZE_A_HUGEBIG (RESIZE_HUGE + RESIZE_BIG) / 2
-#define RESIZE_A_BIGNORMAL (RESIZE_BIG + RESIZE_NORMAL) / 2
-#define RESIZE_A_NORMALSMALL (RESIZE_NORMAL + RESIZE_SMALL) / 2
-#define RESIZE_A_SMALLTINY (RESIZE_SMALL + RESIZE_TINY) / 2
diff --git a/code/__defines/ores.dm b/code/__defines/ores.dm
new file mode 100644
index 0000000000..acc85cc518
--- /dev/null
+++ b/code/__defines/ores.dm
@@ -0,0 +1,20 @@
+#define ORE_MARBLE "marble"
+#define ORE_QUARTZ "quartz"
+#define ORE_COPPER "copper"
+#define ORE_TIN "tin"
+#define ORE_BAUXITE "bauxite"
+#define ORE_URANIUM "uranium"
+#define ORE_PLATINUM "platinum"
+#define ORE_HEMATITE "hematite"
+#define ORE_RUTILE "rutile"
+#define ORE_CARBON "carbon"
+#define ORE_DIAMOND "diamond"
+#define ORE_GOLD "gold"
+#define ORE_SILVER "silver"
+#define ORE_PHORON "phoron"
+#define ORE_LEAD "lead"
+#define ORE_VOPAL "void opal"
+#define ORE_VERDANTIUM "verdantium"
+#define ORE_PAINITE "painite"
+#define ORE_MHYDROGEN "mhydrogen"
+#define ORE_SAND "sand"
diff --git a/code/__defines/phobias.dm b/code/__defines/phobias.dm
new file mode 100644
index 0000000000..0bf2fc1613
--- /dev/null
+++ b/code/__defines/phobias.dm
@@ -0,0 +1,9 @@
+//Handling and defining of phobias and fears
+#define NYCTOPHOBIA 1
+#define ARACHNOPHOBIA 2
+#define HEMOPHOBIA 4
+#define THALASSOPHOBIA 8
+#define CLAUSTROPHOBIA_MINOR 16
+#define CLAUSTROPHOBIA_MAJOR 32
+#define ANATIDAEPHOBIA 64
+#define AGRAVIAPHOBIA 128
diff --git a/code/__defines/plants.dm b/code/__defines/plants.dm
index cd4dc9e701..910e6c4193 100644
--- a/code/__defines/plants.dm
+++ b/code/__defines/plants.dm
@@ -106,9 +106,9 @@ GLOBAL_LIST_INIT(plant_item_products, list(
))
GLOBAL_LIST_INIT(forbidden_plant_growth_sprites, list(
- "gnomes"
+ PLANT_GNOMES
))
GLOBAL_LIST_INIT(forbidden_plant_product_sprites, list(
- "gnomes"
- ))
\ No newline at end of file
+ PLANT_GNOMES
+ ))
diff --git a/code/__defines/rust_g.dm b/code/__defines/rust_g.dm
index bd0e0879b4..14dc8f0c28 100644
--- a/code/__defines/rust_g.dm
+++ b/code/__defines/rust_g.dm
@@ -19,21 +19,21 @@
/* This comment bypasses grep checks */ /var/__rust_g
/proc/__detect_rust_g()
- if (world.system_type == UNIX)
- if (fexists("./librust_g.so"))
- // No need for LD_LIBRARY_PATH badness.
- return __rust_g = "./librust_g.so"
- else if (fexists("./rust_g"))
- // Old dumb filename.
- return __rust_g = "./rust_g"
- else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/rust_g"))
- // Old dumb filename in `~/.byond/bin`.
- return __rust_g = "rust_g"
- else
- // It's not in the current directory, so try others
- return __rust_g = "librust_g.so"
- else
- return __rust_g = "rust_g"
+ if (world.system_type == UNIX)
+ if (fexists("./librust_g.so"))
+ // No need for LD_LIBRARY_PATH badness.
+ return __rust_g = "./librust_g.so"
+ else if (fexists("./rust_g"))
+ // Old dumb filename.
+ return __rust_g = "./rust_g"
+ else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/rust_g"))
+ // Old dumb filename in `~/.byond/bin`.
+ return __rust_g = "rust_g"
+ else
+ // It's not in the current directory, so try others
+ return __rust_g = "librust_g.so"
+ else
+ return __rust_g = "rust_g"
#define RUST_G (__rust_g || __detect_rust_g())
#endif
@@ -48,6 +48,82 @@
/// Gets the version of rust_g
/proc/rustg_get_version() return RUSTG_CALL(RUST_G, "get_version")()
+
+/**
+ * Sets up the Aho-Corasick automaton with its default options.
+ *
+ * The search patterns list and the replacements must be of the same length when replace is run, but an empty replacements list is allowed if replacements are supplied with the replace call
+ * Arguments:
+ * * key - The key for the automaton, to be used with subsequent rustg_acreplace/rustg_acreplace_with_replacements calls
+ * * patterns - A non-associative list of strings to search for
+ * * replacements - Default replacements for this automaton, used with rustg_acreplace
+ */
+#define rustg_setup_acreplace(key, patterns, replacements) RUSTG_CALL(RUST_G, "setup_acreplace")(key, json_encode(patterns), json_encode(replacements))
+
+/**
+ * Sets up the Aho-Corasick automaton using supplied options.
+ *
+ * The search patterns list and the replacements must be of the same length when replace is run, but an empty replacements list is allowed if replacements are supplied with the replace call
+ * Arguments:
+ * * key - The key for the automaton, to be used with subsequent rustg_acreplace/rustg_acreplace_with_replacements calls
+ * * options - An associative list like list("anchored" = 0, "ascii_case_insensitive" = 0, "match_kind" = "Standard"). The values shown on the example are the defaults, and default values may be omitted. See the identically named methods at https://docs.rs/aho-corasick/latest/aho_corasick/struct.AhoCorasickBuilder.html to see what the options do.
+ * * patterns - A non-associative list of strings to search for
+ * * replacements - Default replacements for this automaton, used with rustg_acreplace
+ */
+#define rustg_setup_acreplace_with_options(key, options, patterns, replacements) RUSTG_CALL(RUST_G, "setup_acreplace")(key, json_encode(options), json_encode(patterns), json_encode(replacements))
+
+/**
+ * Run the specified replacement engine with the provided haystack text to replace, returning replaced text.
+ *
+ * Arguments:
+ * * key - The key for the automaton
+ * * text - Text to run replacements on
+ */
+#define rustg_acreplace(key, text) RUSTG_CALL(RUST_G, "acreplace")(key, text)
+
+/**
+ * Run the specified replacement engine with the provided haystack text to replace, returning replaced text.
+ *
+ * Arguments:
+ * * key - The key for the automaton
+ * * text - Text to run replacements on
+ * * replacements - Replacements for this call. Must be the same length as the set-up patterns
+ */
+#define rustg_acreplace_with_replacements(key, text, replacements) RUSTG_CALL(RUST_G, "acreplace_with_replacements")(key, text, json_encode(replacements))
+
+/**
+ * This proc generates a cellular automata noise grid which can be used in procedural generation methods.
+ *
+ * Returns a single string that goes row by row, with values of 1 representing an alive cell, and a value of 0 representing a dead cell.
+ *
+ * Arguments:
+ * * percentage: The chance of a turf starting closed
+ * * smoothing_iterations: The amount of iterations the cellular automata simulates before returning the results
+ * * birth_limit: If the number of neighboring cells is higher than this amount, a cell is born
+ * * death_limit: If the number of neighboring cells is lower than this amount, a cell dies
+ * * width: The width of the grid.
+ * * height: The height of the grid.
+ */
+#define rustg_cnoise_generate(percentage, smoothing_iterations, birth_limit, death_limit, width, height) \
+ RUSTG_CALL(RUST_G, "cnoise_generate")(percentage, smoothing_iterations, birth_limit, death_limit, width, height)
+
+/**
+ * This proc generates a grid of perlin-like noise
+ *
+ * Returns a single string that goes row by row, with values of 1 representing an turned on cell, and a value of 0 representing a turned off cell.
+ *
+ * Arguments:
+ * * seed: seed for the function
+ * * accuracy: how close this is to the original perlin noise, as accuracy approaches infinity, the noise becomes more and more perlin-like
+ * * stamp_size: Size of a singular stamp used by the algorithm, think of this as the same stuff as frequency in perlin noise
+ * * world_size: size of the returned grid.
+ * * lower_range: lower bound of values selected for. (inclusive)
+ * * upper_range: upper bound of values selected for. (exclusive)
+ */
+#define rustg_dbp_generate(seed, accuracy, stamp_size, world_size, lower_range, upper_range) \
+ RUSTG_CALL(RUST_G, "dbp_generate")(seed, accuracy, stamp_size, world_size, lower_range, upper_range)
+
+
#define rustg_dmi_strip_metadata(fname) RUSTG_CALL(RUST_G, "dmi_strip_metadata")(fname)
#define rustg_dmi_create_png(path, width, height, data) RUSTG_CALL(RUST_G, "dmi_create_png")(path, width, height, data)
#define rustg_dmi_resize_png(path, width, height, resizetype) RUSTG_CALL(RUST_G, "dmi_resize_png")(path, width, height, resizetype)
@@ -66,29 +142,47 @@
#define rustg_file_seek_line(fname, line) RUSTG_CALL(RUST_G, "file_seek_line")(fname, "[line]")
#ifdef RUSTG_OVERRIDE_BUILTINS
-#define file2text(fname) rustg_file_read("[fname]")
-#define text2file(text, fname) rustg_file_append(text, "[fname]")
+ #define file2text(fname) rustg_file_read("[fname]")
+ #define text2file(text, fname) rustg_file_append(text, "[fname]")
#endif
/// Returns the git hash of the given revision, ex. "HEAD".
#define rustg_git_revparse(rev) RUSTG_CALL(RUST_G, "rg_git_revparse")(rev)
/**
- * Returns the date of the given revision in the format YYYY-MM-DD.
- * Returns null if the revision is invalid.
+ * Returns the date of the given revision using the provided format.
+ * Defaults to returning %F which is YYYY-MM-DD.
*/
-#define rustg_git_commit_date(rev) RUSTG_CALL(RUST_G, "rg_git_commit_date")(rev)
+/proc/rustg_git_commit_date(rev, format = "%F")
+ return RUSTG_CALL(RUST_G, "rg_git_commit_date")(rev, format)
-#define rustg_hash_string(algorithm, text) LIBCALL(RUST_G, "hash_string")(algorithm, text)
-#define rustg_hash_file(algorithm, fname) LIBCALL(RUST_G, "hash_file")(algorithm, fname)
+/**
+ * Returns the formatted datetime string of HEAD using the provided format.
+ * Defaults to returning %F which is YYYY-MM-DD.
+ * This is different to rustg_git_commit_date because it only needs the logs directory.
+ */
+/proc/rustg_git_commit_date_head(format = "%F")
+ return RUSTG_CALL(RUST_G, "rg_git_commit_date_head")(format)
+
+#define rustg_hash_string(algorithm, text) RUSTG_CALL(RUST_G, "hash_string")(algorithm, text)
+#define rustg_hash_file(algorithm, fname) RUSTG_CALL(RUST_G, "hash_file")(algorithm, fname)
+#define rustg_hash_generate_totp(seed) RUSTG_CALL(RUST_G, "generate_totp")(seed)
+#define rustg_hash_generate_totp_tolerance(seed, tolerance) RUSTG_CALL(RUST_G, "generate_totp_tolerance")(seed, tolerance)
#define RUSTG_HASH_MD5 "md5"
#define RUSTG_HASH_SHA1 "sha1"
#define RUSTG_HASH_SHA256 "sha256"
#define RUSTG_HASH_SHA512 "sha512"
+#define RUSTG_HASH_XXH64 "xxh64"
+#define RUSTG_HASH_BASE64 "base64"
+
+/// Encode a given string into base64
+#define rustg_encode_base64(str) rustg_hash_string(RUSTG_HASH_BASE64, str)
+/// Decode a given base64 string
+#define rustg_decode_base64(str) RUSTG_CALL(RUST_G, "decode_base64")(str)
#ifdef RUSTG_OVERRIDE_BUILTINS
-#define md5(thing) (isfile(thing) ? rustg_hash_file(RUSTG_HASH_MD5, "[thing]") : rustg_hash_string(RUSTG_HASH_MD5, thing))
+ #define md5(thing) (isfile(thing) ? rustg_hash_file(RUSTG_HASH_MD5, "[thing]") : rustg_hash_string(RUSTG_HASH_MD5, thing))
#endif
#define RUSTG_HTTP_METHOD_GET "get"
@@ -101,17 +195,171 @@
#define rustg_http_request_async(method, url, body, headers, options) RUSTG_CALL(RUST_G, "http_request_async")(method, url, body, headers, options)
#define rustg_http_check_request(req_id) RUSTG_CALL(RUST_G, "http_check_request")(req_id)
+/// Generates a spritesheet at: [file_path][spritesheet_name]_[size_id].png
+/// The resulting spritesheet arranges icons in a random order, with the position being denoted in the "sprites" return value.
+/// All icons have the same y coordinate, and their x coordinate is equal to `icon_width * position`.
+///
+/// hash_icons is a boolean (0 or 1), and determines if the generator will spend time creating hashes for the output field dmi_hashes.
+/// These hashes can be heplful for 'smart' caching (see rustg_iconforge_cache_valid), but require extra computation.
+///
+/// Spritesheet will contain all sprites listed within "sprites".
+/// "sprites" format:
+/// list(
+/// "sprite_name" = list( // <--- this list is a [SPRITE_OBJECT]
+/// icon_file = 'icons/path_to/an_icon.dmi',
+/// icon_state = "some_icon_state",
+/// dir = SOUTH,
+/// frame = 1,
+/// transform = list([TRANSFORM_OBJECT], ...)
+/// ),
+/// ...,
+/// )
+/// TRANSFORM_OBJECT format:
+/// list("type" = RUSTG_ICONFORGE_BLEND_COLOR, "color" = "#ff0000", "blend_mode" = ICON_MULTIPLY)
+/// list("type" = RUSTG_ICONFORGE_BLEND_ICON, "icon" = [SPRITE_OBJECT], "blend_mode" = ICON_OVERLAY)
+/// list("type" = RUSTG_ICONFORGE_SCALE, "width" = 32, "height" = 32)
+/// list("type" = RUSTG_ICONFORGE_CROP, "x1" = 1, "y1" = 1, "x2" = 32, "y2" = 32) // (BYOND icons index from 1,1 to the upper bound, inclusive)
+///
+/// Returns a SpritesheetResult as JSON, containing fields:
+/// list(
+/// "sizes" = list("32x32", "64x64", ...),
+/// "sprites" = list("sprite_name" = list("size_id" = "32x32", "position" = 0), ...),
+/// "dmi_hashes" = list("icons/path_to/an_icon.dmi" = "d6325c5b4304fb03", ...),
+/// "sprites_hash" = "a2015e5ff403fb5c", // This is the xxh64 hash of the INPUT field "sprites".
+/// "error" = "[A string, empty if there were no errors.]"
+/// )
+/// In the case of an unrecoverable panic from within Rust, this function ONLY returns a string containing the error.
+#define rustg_iconforge_generate(file_path, spritesheet_name, sprites, hash_icons) RUSTG_CALL(RUST_G, "iconforge_generate")(file_path, spritesheet_name, sprites, "[hash_icons]")
+/// Returns a job_id for use with rustg_iconforge_check()
+#define rustg_iconforge_generate_async(file_path, spritesheet_name, sprites, hash_icons) RUSTG_CALL(RUST_G, "iconforge_generate_async")(file_path, spritesheet_name, sprites, "[hash_icons]")
+/// Returns the status of an async job_id, or its result if it is completed. See RUSTG_JOB DEFINEs.
+#define rustg_iconforge_check(job_id) RUSTG_CALL(RUST_G, "iconforge_check")("[job_id]")
+/// Clears all cached DMIs and images, freeing up memory.
+/// This should be used after spritesheets are done being generated.
+#define rustg_iconforge_cleanup RUSTG_CALL(RUST_G, "iconforge_cleanup")
+/// Takes in a set of hashes, generate inputs, and DMI filepaths, and compares them to determine cache validity.
+/// input_hash: xxh64 hash of "sprites" from the cache.
+/// dmi_hashes: xxh64 hashes of the DMIs in a spritesheet, given by `rustg_iconforge_generate` with `hash_icons` enabled. From the cache.
+/// sprites: The new input that will be passed to rustg_iconforge_generate().
+/// Returns a CacheResult with the following structure: list(
+/// "result": "1" (if cache is valid) or "0" (if cache is invalid)
+/// "fail_reason": "" (emtpy string if valid, otherwise a string containing the invalidation reason or an error with ERROR: prefixed.)
+/// )
+/// In the case of an unrecoverable panic from within Rust, this function ONLY returns a string containing the error.
+#define rustg_iconforge_cache_valid(input_hash, dmi_hashes, sprites) RUSTG_CALL(RUST_G, "iconforge_cache_valid")(input_hash, dmi_hashes, sprites)
+/// Returns a job_id for use with rustg_iconforge_check()
+#define rustg_iconforge_cache_valid_async(input_hash, dmi_hashes, sprites) RUSTG_CALL(RUST_G, "iconforge_cache_valid_async")(input_hash, dmi_hashes, sprites)
+
+#define RUSTG_ICONFORGE_BLEND_COLOR "BlendColor"
+#define RUSTG_ICONFORGE_BLEND_ICON "BlendIcon"
+#define RUSTG_ICONFORGE_CROP "Crop"
+#define RUSTG_ICONFORGE_SCALE "Scale"
+
#define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET"
#define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB"
#define RUSTG_JOB_ERROR "JOB PANICKED"
#define rustg_json_is_valid(text) (RUSTG_CALL(RUST_G, "json_is_valid")(text) == "true")
-#define rustg_log_write(fname, text, format) LIBCALL(RUST_G, "log_write")(fname, text, format)
-/proc/rustg_log_close_all() return LIBCALL(RUST_G, "log_close_all")()
+#define rustg_log_write(fname, text, format) RUSTG_CALL(RUST_G, "log_write")(fname, text, format)
+/proc/rustg_log_close_all() return RUSTG_CALL(RUST_G, "log_close_all")()
#define rustg_noise_get_at_coordinates(seed, x, y) RUSTG_CALL(RUST_G, "noise_get_at_coordinates")(seed, x, y)
+/**
+ * Generates a 2D poisson disk distribution ('blue noise'), which is relatively uniform.
+ *
+ * params:
+ * `seed`: str
+ * `width`: int, width of the noisemap (see world.maxx)
+ * `length`: int, height of the noisemap (see world.maxy)
+ * `radius`: int, distance between points on the noisemap
+ *
+ * returns:
+ * a width*length length string of 1s and 0s representing a 2D poisson sample collapsed into a 1D string
+ */
+#define rustg_noise_poisson_map(seed, width, length, radius) RUSTG_CALL(RUST_G, "noise_poisson_map")(seed, width, length, radius)
+
+/**
+ * Register a list of nodes into a rust library. This list of nodes must have been serialized in a json.
+ * Node {// Index of this node in the list of nodes
+ * unique_id: usize,
+ * // Position of the node in byond
+ * x: usize,
+ * y: usize,
+ * z: usize,
+ * // Indexes of nodes connected to this one
+ * connected_nodes_id: Vec}
+ * It is important that the node with the unique_id 0 is the first in the json, unique_id 1 right after that, etc.
+ * It is also important that all unique ids follow. {0, 1, 2, 4} is not a correct list and the registering will fail
+ * Nodes should not link across z levels.
+ * A node cannot link twice to the same node and shouldn't link itself either
+ */
+#define rustg_register_nodes_astar(json) RUSTG_CALL(RUST_G, "register_nodes_astar")(json)
+
+/**
+ * Add a new node to the static list of nodes. Same rule as registering_nodes applies.
+ * This node unique_id must be equal to the current length of the static list of nodes
+ */
+#define rustg_add_node_astar(json) RUSTG_CALL(RUST_G, "add_node_astar")(json)
+
+/**
+ * Remove every link to the node with unique_id. Replace that node by null
+ */
+#define rustg_remove_node_astar(unique_id) RUSTG_CALL(RUST_G, "remove_node_astar")("[unique_id]")
+
+/**
+ * Compute the shortest path between start_node and goal_node using A*. Heuristic used is simple geometric distance
+ */
+#define rustg_generate_path_astar(start_node_id, goal_node_id) RUSTG_CALL(RUST_G, "generate_path_astar")("[start_node_id]", "[goal_node_id]")
+
+#define RUSTG_REDIS_ERROR_CHANNEL "RUSTG_REDIS_ERROR_CHANNEL"
+
+#define rustg_redis_connect(addr) RUSTG_CALL(RUST_G, "redis_connect")(addr)
+/proc/rustg_redis_disconnect() return RUSTG_CALL(RUST_G, "redis_disconnect")()
+#define rustg_redis_subscribe(channel) RUSTG_CALL(RUST_G, "redis_subscribe")(channel)
+/proc/rustg_redis_get_messages() return RUSTG_CALL(RUST_G, "redis_get_messages")()
+#define rustg_redis_publish(channel, message) RUSTG_CALL(RUST_G, "redis_publish")(channel, message)
+
+/**
+ * Connects to a given redis server.
+ *
+ * Arguments:
+ * * addr - The address of the server, for example "redis://127.0.0.1/"
+ */
+#define rustg_redis_connect_rq(addr) RUSTG_CALL(RUST_G, "redis_connect_rq")(addr)
+/**
+ * Disconnects from a previously connected redis server
+ */
+/proc/rustg_redis_disconnect_rq() return RUSTG_CALL(RUST_G, "redis_disconnect_rq")()
+/**
+ * https://redis.io/commands/lpush/
+ *
+ * Arguments
+ * * key (string) - The key to use
+ * * elements (list) - The elements to push, use a list even if there's only one element.
+ */
+#define rustg_redis_lpush(key, elements) RUSTG_CALL(RUST_G, "redis_lpush")(key, json_encode(elements))
+/**
+ * https://redis.io/commands/lrange/
+ *
+ * Arguments
+ * * key (string) - The key to use
+ * * start (string) - The zero-based index to start retrieving at
+ * * stop (string) - The zero-based index to stop retrieving at (inclusive)
+ */
+#define rustg_redis_lrange(key, start, stop) RUSTG_CALL(RUST_G, "redis_lrange")(key, start, stop)
+/**
+ * https://redis.io/commands/lpop/
+ *
+ * Arguments
+ * * key (string) - The key to use
+ * * count (string|null) - The amount to pop off the list, pass null to omit (thus just 1)
+ *
+ * Note: `count` was added in Redis version 6.2.0
+ */
+#define rustg_redis_lpop(key, count) RUSTG_CALL(RUST_G, "redis_lpop")(key, count)
+
/*
* Takes in a string and json_encode()"d lists to produce a sanitized string.
* This function operates on whitelists, there is currently no way to blacklist.
@@ -122,12 +370,55 @@
*/
#define rustg_sanitize_html(text, attribute_whitelist_json, tag_whitelist_json) RUSTG_CALL(RUST_G, "sanitize_html")(text, attribute_whitelist_json, tag_whitelist_json)
-#define rustg_sql_connect_pool(options) LIBCALL(RUST_G, "sql_connect_pool")(options)
-#define rustg_sql_query_async(handle, query, params) LIBCALL(RUST_G, "sql_query_async")(handle, query, params)
-#define rustg_sql_query_blocking(handle, query, params) LIBCALL(RUST_G, "sql_query_blocking")(handle, query, params)
-#define rustg_sql_connected(handle) LIBCALL(RUST_G, "sql_connected")(handle)
-#define rustg_sql_disconnect_pool(handle) LIBCALL(RUST_G, "sql_disconnect_pool")(handle)
-#define rustg_sql_check_query(job_id) LIBCALL(RUST_G, "sql_check_query")("[job_id]")
+/// Provided a static RSC file path or a raw text file path, returns the duration of the file in deciseconds as a float.
+/proc/rustg_sound_length(file_path)
+ var/static/list/sound_cache
+ if(isnull(sound_cache))
+ sound_cache = list()
+
+ . = 0
+
+ if(!istext(file_path))
+ if(!isfile(file_path))
+ CRASH("rustg_sound_length error: Passed non-text object")
+
+ if(length("[file_path]")) // Runtime generated RSC references stringify into 0-length strings.
+ file_path = "[file_path]"
+ else
+ CRASH("rustg_sound_length does not support non-static file refs.")
+
+ var/cached_length = sound_cache[file_path]
+ if(!isnull(cached_length))
+ return cached_length
+
+ var/ret = RUSTG_CALL(RUST_G, "sound_len")(file_path)
+ var/as_num = text2num(ret)
+ if(isnull(ret))
+ . = 0
+ CRASH("rustg_sound_length error: [ret]")
+
+ sound_cache[file_path] = as_num
+ return as_num
+
+
+#define RUSTG_SOUNDLEN_SUCCESSES "successes"
+#define RUSTG_SOUNDLEN_ERRORS "errors"
+/**
+ * Returns a nested key-value list containing "successes" and "errors"
+ * The format is as follows:
+ * list(
+ * RUSTG_SOUNDLEN_SUCCESES = list("sounds/test.ogg" = 25.34),
+ * RUSTG_SOUNDLEN_ERRORS = list("sound/bad.png" = "SoundLen: Unable to decode file."),
+ *)
+*/
+#define rustg_sound_length_list(file_paths) json_decode(RUSTG_CALL(RUST_G, "sound_len_list")(json_encode(file_paths)))
+
+#define rustg_sql_connect_pool(options) RUSTG_CALL(RUST_G, "sql_connect_pool")(options)
+#define rustg_sql_query_async(handle, query, params) RUSTG_CALL(RUST_G, "sql_query_async")(handle, query, params)
+#define rustg_sql_query_blocking(handle, query, params) RUSTG_CALL(RUST_G, "sql_query_blocking")(handle, query, params)
+#define rustg_sql_connected(handle) RUSTG_CALL(RUST_G, "sql_connected")(handle)
+#define rustg_sql_disconnect_pool(handle) RUSTG_CALL(RUST_G, "sql_disconnect_pool")(handle)
+#define rustg_sql_check_query(job_id) RUSTG_CALL(RUST_G, "sql_check_query")("[job_id]")
#define rustg_time_microseconds(id) text2num(RUSTG_CALL(RUST_G, "time_microseconds")(id))
#define rustg_time_milliseconds(id) text2num(RUSTG_CALL(RUST_G, "time_milliseconds")(id))
@@ -135,30 +426,49 @@
/// Returns the timestamp as a string
/proc/rustg_unix_timestamp()
- return RUSTG_CALL(RUST_G, "unix_timestamp")()
+ return RUSTG_CALL(RUST_G, "unix_timestamp")()
#define rustg_raw_read_toml_file(path) json_decode(RUSTG_CALL(RUST_G, "toml_file_to_json")(path) || "null")
/proc/rustg_read_toml_file(path)
- var/list/output = rustg_raw_read_toml_file(path)
- if (output["success"])
- return json_decode(output["content"])
- else
- CRASH(output["content"])
+ var/list/output = rustg_raw_read_toml_file(path)
+ if (output["success"])
+ return json_decode(output["content"])
+ else
+ CRASH(output["content"])
#define rustg_raw_toml_encode(value) json_decode(RUSTG_CALL(RUST_G, "toml_encode")(json_encode(value)))
/proc/rustg_toml_encode(value)
- var/list/output = rustg_raw_toml_encode(value)
- if (output["success"])
- return output["content"]
- else
- CRASH(output["content"])
+ var/list/output = rustg_raw_toml_encode(value)
+ if (output["success"])
+ return output["content"]
+ else
+ CRASH(output["content"])
+
+#define rustg_unzip_download_async(url, unzip_directory) RUSTG_CALL(RUST_G, "unzip_download_async")(url, unzip_directory)
+#define rustg_unzip_check(job_id) RUSTG_CALL(RUST_G, "unzip_check")("[job_id]")
#define rustg_url_encode(text) RUSTG_CALL(RUST_G, "url_encode")("[text]")
#define rustg_url_decode(text) RUSTG_CALL(RUST_G, "url_decode")(text)
#ifdef RUSTG_OVERRIDE_BUILTINS
- #define url_encode(text) rustg_url_encode(text)
- #define url_decode(text) rustg_url_decode(text)
+ #define url_encode(text) rustg_url_encode(text)
+ #define url_decode(text) rustg_url_decode(text)
#endif
+
+/**
+ * This proc generates a noise grid using worley noise algorithm
+ *
+ * Returns a single string that goes row by row, with values of 1 representing an alive cell, and a value of 0 representing a dead cell.
+ *
+ * Arguments:
+ * * region_size: The size of regions
+ * * threshold: the value that determines wether a cell is dead or alive
+ * * node_per_region_chance: chance of a node existiing in a region
+ * * size: size of the returned grid
+ * * node_min: minimum amount of nodes in a region (after the node_per_region_chance is applied)
+ * * node_max: maximum amount of nodes in a region
+ */
+#define rustg_worley_generate(region_size, threshold, node_per_region_chance, size, node_min, node_max) \
+ RUSTG_CALL(RUST_G, "worley_generate")(region_size, threshold, node_per_region_chance, size, node_min, node_max)
diff --git a/code/__defines/update_icons.dm b/code/__defines/update_icons.dm
index 7120edd168..711eda080d 100644
--- a/code/__defines/update_icons.dm
+++ b/code/__defines/update_icons.dm
@@ -2,14 +2,14 @@
// Technically the layers used are all -100+layer to make them FLOAT_LAYER overlays.
//Human Overlays Indexes/////////
#define MUTATIONS_LAYER 1 //Mutations like fat, and lasereyes
-#define SKIN_LAYER 2 //Skin things added by a call on species
-#define BLOOD_LAYER 3 //Bloodied hands/feet/anything else
+#define TAIL_LOWER_LAYER 2 //Tail as viewed from the south
+#define WING_LOWER_LAYER 3 //Wings as viewed from the south
#define BODYPARTS_LAYER 4 //Bodyparts layer
-#define MOB_DAM_LAYER 5 //Injury overlay sprites like open wounds
-#define SURGERY_LAYER 6 //Overlays for open surgical sites
-#define UNDERWEAR_LAYER 7 //Underwear/bras/etc
-#define TAIL_LOWER_LAYER 8 //Tail as viewed from the south
-#define WING_LOWER_LAYER 9 //Wings as viewed from the south
+#define SKIN_LAYER 5 //Skin things added by a call on species
+#define BLOOD_LAYER 6 //Bloodied hands/feet/anything else
+#define MOB_DAM_LAYER 7 //Injury overlay sprites like open wounds
+#define SURGERY_LAYER 8 //Overlays for open surgical sites
+#define UNDERWEAR_LAYER 9 //Underwear/bras/etc
#define SHOES_LAYER_ALT 10 //Shoe-slot item (when set to be under uniform via verb)
#define UNIFORM_LAYER 11 //Uniform-slot item
#define ID_LAYER 12 //ID-slot item
@@ -34,16 +34,16 @@
#define L_HAND_LAYER 31 //Left-hand item
#define R_HAND_LAYER 32 //Right-hand item
#define WING_LAYER 33 //Wings or protrusions over the suit.
-#define TAIL_UPPER_LAYER_ALT 34 //Modified tail-sprite layer. Tend to be larger.
-#define MODIFIER_EFFECTS_LAYER 35 //Effects drawn by modifiers
-#define FIRE_LAYER 36 //'Mob on fire' overlay layer
-#define MOB_WATER_LAYER 37
-#define TARGETED_LAYER 38 //'Aimed at' overlay layer
-#define VORE_BELLY_LAYER 39
-#define VORE_TAIL_LAYER 40
-
+#define VORE_BELLY_LAYER 34 //Move this and everything after up if things are added.
+#define VORE_TAIL_LAYER 35 //Move this and everything after up if things are added.
+#define TAIL_UPPER_LAYER_ALT 36 //Modified tail-sprite layer. Tend to be larger.
+#define MODIFIER_EFFECTS_LAYER 37 //Effects drawn by modifiers
+#define FIRE_LAYER 38 //'Mob on fire' overlay layer
+#define MOB_WATER_LAYER 39 //'Mob submerged' overlay layer
+#define TARGETED_LAYER 40 //'Aimed at' overlay layer
#define TOTAL_LAYERS 40 // <---- KEEP THIS UPDATED, should always equal the highest number here, used to initialize a list.
+
//These two are only used for gargoyles currently
#define HUMAN_BODY_LAYERS list(MUTATIONS_LAYER, TAIL_LOWER_LAYER, WING_LOWER_LAYER, BODYPARTS_LAYER, SKIN_LAYER, BLOOD_LAYER, MOB_DAM_LAYER, TAIL_UPPER_LAYER, HAIR_LAYER, HAIR_ACCESSORY_LAYER, EYES_LAYER, WING_LAYER, VORE_BELLY_LAYER, VORE_TAIL_LAYER, TAIL_UPPER_LAYER_ALT)
#define HUMAN_OTHER_LAYERS list(MODIFIER_EFFECTS_LAYER, FIRE_LAYER, MOB_WATER_LAYER, TARGETED_LAYER)
diff --git a/code/__defines/visualnet.dm b/code/__defines/visualnet.dm
new file mode 100644
index 0000000000..4b503bee2d
--- /dev/null
+++ b/code/__defines/visualnet.dm
@@ -0,0 +1 @@
+#define CHUNK_SIZE 16
diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index 80abfae652..a687776f88 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -62,6 +62,7 @@ var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg)
var/list/datum/visualnet/visual_nets = list()
var/datum/visualnet/camera/cameranet = new()
var/datum/visualnet/cult/cultnet = new()
+var/datum/visualnet/ghost/ghostnet = new()
// Runes
var/global/list/rune_list = new()
diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm
index d016b7111d..05b6ff6158 100644
--- a/code/_helpers/logging.dm
+++ b/code/_helpers/logging.dm
@@ -228,7 +228,7 @@
if(key)
if(include_link && C)
- . += ""
+ . += ""
if(C && C.holder && C.holder.fakekey)
. += "Administrator"
diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm
index e78123fe64..0efc265b49 100644
--- a/code/_helpers/mobs.dm
+++ b/code/_helpers/mobs.dm
@@ -1,3 +1,40 @@
+/atom/movable/proc/get_mob()
+ if(buckled_mobs) return buckled_mobs.Copy()
+
+/obj/mecha/get_mob()
+ return occupant
+
+/obj/vehicle_old/train/get_mob()
+ return buckled_mobs
+
+/mob/get_mob()
+ return src
+
+/mob/living/bot/mulebot/get_mob()
+ if(load && istype(load, /mob/living))
+ return list(src, load)
+ return src
+
+/proc/mobs_in_view(range, source)
+ var/list/mobs = list()
+ for(var/atom/movable/AM in view(range, source))
+ var/M = AM.get_mob()
+ if(M)
+ mobs += M
+
+ return mobs
+
+/// This gets a list of mobs ALL around us as if we had xray vision and can see through walls.
+/// Currently only used in portable_turret.dm if you wish to see an example of how to use it.
+/proc/mobs_in_xray_view(range, source)
+ var/list/mobs = list()
+ for(var/atom/movable/AM in orange(range, source))
+ var/M = AM.get_mob()
+ if(M)
+ mobs += M
+
+ return mobs
+
/proc/random_hair_style(gender, species = SPECIES_HUMAN)
var/h_style = "Bald"
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index 8b5c5d0325..05bfc9a444 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -1199,7 +1199,7 @@ var/list/WALLITEMS = list(
/proc/topic_link(var/datum/D, var/arglist, var/content)
if(istype(arglist,/list))
arglist = list2params(arglist)
- return "[content]"
+ return "[content]"
/proc/get_random_colour(var/simple, var/lower=0, var/upper=255)
var/colour
@@ -1534,7 +1534,7 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
// Note that object refs will be converted to text, as if \ref[thing] was done. To get the ref back on Topic() side, you will need to use locate().
// Third one is the text that will be clickable.
/proc/href(href_src, list/href_params, href_text)
- return "[href_text]"
+ return "[href_text]"
// This is a helper for anything that wants to render the map in TGUI
/proc/get_tgui_plane_masters()
@@ -1565,6 +1565,7 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
. += new /obj/screen/plane_master{plane = PLANE_MESONS} //Meson-specific things like open ceilings.
. += new /obj/screen/plane_master{plane = PLANE_BUILDMODE} //Things that only show up while in build mode
+ . += new /obj/screen/plane_master{plane = PLANE_JANHUD}
// Real tangible stuff planes
. += new /obj/screen/plane_master/main{plane = TURF_PLANE}
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index cc567b9e2e..4d221c9c4f 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -347,7 +347,7 @@
else
var/list/nicename = null
var/list/tankcheck = null
- var/breathes = "oxygen" //default, we'll check later
+ var/breathes = GAS_O2 //default, we'll check later
var/list/contents = list()
var/from = "on"
@@ -376,30 +376,30 @@
continue //in it, so we're going to believe the tank is what it says it is
switch(breathes)
//These tanks we're sure of their contents
- if("nitrogen") //So we're a bit more picky about them.
+ if(GAS_N2) //So we're a bit more picky about them.
- if(t.air_contents.gas["nitrogen"] && !t.air_contents.gas["oxygen"])
- contents.Add(t.air_contents.gas["nitrogen"])
+ if(t.air_contents.gas[GAS_N2] && !t.air_contents.gas[GAS_O2])
+ contents.Add(t.air_contents.gas[GAS_N2])
else
contents.Add(0)
- if ("oxygen")
- if(t.air_contents.gas["oxygen"] && !t.air_contents.gas["phoron"])
- contents.Add(t.air_contents.gas["oxygen"])
+ if (GAS_O2)
+ if(t.air_contents.gas[GAS_O2] && !t.air_contents.gas[GAS_PHORON])
+ contents.Add(t.air_contents.gas[GAS_O2])
else
contents.Add(0)
// No races breath this, but never know about downstream servers.
if ("carbon dioxide")
- if(t.air_contents.gas["carbon_dioxide"] && !t.air_contents.gas["phoron"])
- contents.Add(t.air_contents.gas["carbon_dioxide"])
+ if(t.air_contents.gas[GAS_CO2] && !t.air_contents.gas[GAS_PHORON])
+ contents.Add(t.air_contents.gas[GAS_CO2])
else
contents.Add(0)
// And here's for the Vox
- if ("phoron")
- if(t.air_contents.gas["phoron"] && !t.air_contents.gas["oxygen"])
- contents.Add(t.air_contents.gas["phoron"])
+ if (GAS_PHORON)
+ if(t.air_contents.gas[GAS_PHORON] && !t.air_contents.gas[GAS_O2])
+ contents.Add(t.air_contents.gas[GAS_PHORON])
else
contents.Add(0)
@@ -431,7 +431,7 @@
if(C.internals)
C.internals.icon_state = "internal1"
else
- to_chat(C, span_notice("You don't have a[breathes=="oxygen" ? "n oxygen" : addtext(" ",breathes)] tank."))
+ to_chat(C, span_notice("You don't have a[breathes==GAS_O2 ? "n " + GAS_O2 : addtext(" ",breathes)] tank."))
if("act_intent")
usr.a_intent_change("right")
if(I_HELP)
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index 9b7430c016..cdd3d1ec33 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -264,10 +264,10 @@
return num_val MINUTES
/datum/config_entry/string/respawn_message
- default = "Make sure to play a different character, and please roleplay correctly!"
+ default = span_boldnotice("Make sure to play a different character, and please roleplay correctly!")
/datum/config_entry/string/respawn_message/ValidateAndSet(str_val)
- return "[str_val]"
+ return span_boldnotice("[str_val]")
/datum/config_entry/flag/guest_jobban
default = TRUE
diff --git a/code/controllers/subsystems/chemistry.dm b/code/controllers/subsystems/chemistry.dm
index 6f0c5959eb..e31b71dc00 100644
--- a/code/controllers/subsystems/chemistry.dm
+++ b/code/controllers/subsystems/chemistry.dm
@@ -27,7 +27,7 @@ SUBSYSTEM_DEF(chemistry)
//Chemical Reactions - Initialises all /decl/chemical_reaction into a list
// It is filtered into multiple lists within a list.
// For example:
-// chemical_reactions_by_reagent["phoron"] is a list of all reactions relating to phoron
+// chemical_reactions_by_reagent[REAGENT_ID_PHORON] is a list of all reactions relating to phoron
// Note that entries in the list are NOT duplicated. So if a reaction pertains to
// more than one chemical it will still only appear in only one of the sublists.
/datum/controller/subsystem/chemistry/proc/initialize_chemical_reactions()
diff --git a/code/controllers/subsystems/inactivity.dm b/code/controllers/subsystems/inactivity.dm
index bc7a5a7dde..4708be526c 100644
--- a/code/controllers/subsystems/inactivity.dm
+++ b/code/controllers/subsystems/inactivity.dm
@@ -46,7 +46,7 @@ SUBSYSTEM_DEF(inactivity)
information = " while an AI."
var/adminlinks
- adminlinks = " (JMP|CRYO)"
+ adminlinks = " (JMP|CRYO)"
log_and_message_admins("being kicked for AFK[information][adminlinks]", C.mob)
diff --git a/code/controllers/subsystems/plants.dm b/code/controllers/subsystems/plants.dm
index 7f25024c4a..b46cc00172 100644
--- a/code/controllers/subsystems/plants.dm
+++ b/code/controllers/subsystems/plants.dm
@@ -108,10 +108,10 @@ SUBSYSTEM_DEF(plants)
if(survive_on_station)
if(seed.consume_gasses)
- seed.consume_gasses["phoron"] = null
- seed.consume_gasses["carbon_dioxide"] = null
- if(seed.chems && !isnull(seed.chems["pacid"]))
- seed.chems["pacid"] = null // Eating through the hull will make these plants completely inviable, albeit very dangerous.
+ seed.consume_gasses[GAS_PHORON] = null
+ seed.consume_gasses[GAS_CO2] = null
+ if(seed.chems && !isnull(seed.chems[REAGENT_ID_PACID]))
+ seed.chems[REAGENT_ID_PACID] = null // Eating through the hull will make these plants completely inviable, albeit very dangerous.
seed.chems -= null // Setting to null does not actually remove the entry, which is weird.
seed.set_trait(TRAIT_IDEAL_HEAT,293)
seed.set_trait(TRAIT_HEAT_TOLERANCE,20)
diff --git a/code/controllers/subsystems/statpanel.dm b/code/controllers/subsystems/statpanel.dm
index 2400e1da80..af505585f1 100644
--- a/code/controllers/subsystems/statpanel.dm
+++ b/code/controllers/subsystems/statpanel.dm
@@ -427,8 +427,8 @@ SUBSYSTEM_DEF(statpanels)
COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout),
)
AddComponent(/datum/component/connect_mob_behalf, parent, connections)
- RegisterSignal(parent.tracked_turf, COMSIG_ATOM_ENTERED, PROC_REF(turflist_changed))
- RegisterSignal(parent.tracked_turf, COMSIG_ATOM_EXITED, PROC_REF(turflist_changed))
+ RegisterSignal(new_turf, COMSIG_ATOM_ENTERED, PROC_REF(turflist_changed))
+ RegisterSignal(new_turf, COMSIG_ATOM_EXITED, PROC_REF(turflist_changed))
parent.stat_panel.send_message("create_listedturf", new_turf)
parent.tracked_turf = new_turf
diff --git a/code/controllers/subsystems/vote.dm b/code/controllers/subsystems/vote.dm
index 834af1769e..3d2b5d63fa 100644
--- a/code/controllers/subsystems/vote.dm
+++ b/code/controllers/subsystems/vote.dm
@@ -253,7 +253,7 @@ SUBSYSTEM_DEF(vote)
log_vote(text)
- to_world(span_filter_system(span_purple(span_bold("[text]") + "\nType " + span_bold("vote") + " or click here to place your votes.\nYou have [config.vote_period / 10] seconds to vote.")))
+ to_world(span_filter_system(span_purple(span_bold("[text]") + "\nType " + span_bold("vote") + " or click here to place your votes.\nYou have [config.vote_period / 10] seconds to vote.")))
if(vote_type == VOTE_CREW_TRANSFER || vote_type == VOTE_GAMEMODE || vote_type == VOTE_CUSTOM)
world << sound('sound/misc/notice1.ogg', repeat = 0, wait = 0, volume = 50, channel = 3) //YW Edit
@@ -293,55 +293,55 @@ SUBSYSTEM_DEF(vote)
. += ""
var/thisVote = (current_votes[C.ckey] == i)
if(mode == VOTE_GAMEMODE)
- . += "| [thisVote ? "" : ""][gamemode_names[choices[i]]][thisVote ? "" : ""] | [votes] | "
+ . += "[thisVote ? "" : ""][gamemode_names[choices[i]]][thisVote ? "" : ""] | [votes] | "
else
- . += "[thisVote ? "" : ""][choices[i]][thisVote ? "" : ""] | [votes] | "
+ . += "[thisVote ? "" : ""][choices[i]][thisVote ? "" : ""] | [votes] | "
if (additional_text.len >= i)
. += additional_text[i]
. += "
"
- . += "| Unvote |
"
+ . += "| Unvote |
"
. += "
"
if(admin)
- . += "(Cancel Vote) "
+ . += "(Cancel Vote) "
else
. += "Start a vote:
"
- . += "Close