[MIRROR] Recipie conflict unit test + Chemanalyzer PRO (#10494)

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
Co-authored-by: Willburd <7099514+Willburd@users.noreply.github.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-03-22 11:23:35 -07:00
committed by GitHub
parent fcd380c69a
commit 848d52a683
21 changed files with 389 additions and 103 deletions

View File

@@ -101,6 +101,9 @@
while(reaction_occurred)
for(var/decl/chemical_reaction/C as anything in effect_reactions)
C.post_reaction(src)
#ifdef UNIT_TEST
SEND_SIGNAL(src, COMSIG_UNITTEST_DATA, list(C))
#endif
update_total()
/* Holder-to-chemical */

View File

@@ -1,9 +1,9 @@
// Detects reagents inside most containers, and acts as an infinite identification system for reagent-based unidentified objects.
/obj/machinery/chemical_analyzer
name = "chem analyzer"
desc = "Used to precisely scan chemicals and other liquids inside various containers. \
It may also identify the liquid contents of unknown objects."
name = "chem analyzer PRO"
desc = "New and improved! Used to precisely scan chemicals and other liquids inside various containers. \
It can also identify the liquid contents of unknown objects and their chemical breakdowns."
description_info = "This machine will try to tell you what reagents are inside of something capable of holding reagents. \
It is also used to 'identify' specific reagent-based objects with their properties obscured from inspection by normal means."
icon = 'icons/obj/chemical.dmi'
@@ -45,19 +45,153 @@
I.identify(IDENTITY_FULL, user)
// Now tell us everything that is inside.
var/final_message = ""
if(I.reagents && I.reagents.reagent_list.len)
to_chat(user, "<br>") // To add padding between regular chat and the output.
final_message += "<br>" // To add padding between regular chat and the output.
for(var/datum/reagent/R in I.reagents.reagent_list)
if(!R.name)
continue
to_chat(user, span_notice("Contains [R.volume]u of <b>[R.name]</b>.<br>[R.description]<br>"))
final_message += span_notice("*=*=*=*= Contains " + span_info("[R.volume]u") + " of " + span_bold(span_underline("[R.name]")) + " =*=*=*=*<br>[R.description][R.from_belly ? " Something seems strange about it...? (OOC: It's from a belly!)" : ""]<br><br>")
/* Downstream addiction code
if(R.id in addictives)
final_message += span_boldnotice(span_red("DANGER") + ", [(R.id in fast_addictives) ? "highly " : ""]addictive.)") + "<br>"
*/
var/list/products = SSchemistry.chemical_reactions_by_product[R.id]
if(products != null && products.len > 0)
var/segment = 1
var/list/display_reactions = list()
for(var/decl/chemical_reaction/CR in products)
// if(!CR.spoiler) - Downstream self documenting wiki code
display_reactions.Add(CR)
for(var/decl/chemical_reaction/CR in display_reactions)
if(display_reactions.len == 1)
final_message += span_underline("Potential Chemical breakdown: <br>")
else
final_message += span_underline("Potential Chemical breakdown [segment]: <br>")
segment += 1
// Last, unseal it if it's an autoinjector.
if(istype(I,/obj/item/reagent_containers/hypospray/autoinjector/biginjector) && !(I.flags & OPENCONTAINER))
I.flags |= OPENCONTAINER
to_chat(user, span_notice("Sample container unsealed.<br>"))
if(istype(CR,/decl/chemical_reaction/instant/slime))
// Handle slimes
var/decl/chemical_reaction/instant/slime/SR = CR
if(SR.required)
var/slime_path = SR.required
final_message += " -core [span_info(initial(slime_path:name))]<br>"
for(var/RQ in CR.required_reagents)
var/decl/chemical_reaction/r_RQ = SSchemistry.chemical_reagents[RQ]
if(!r_RQ)
continue
final_message += " -inducer [span_info(r_RQ.name)]<br>"
else
// Standard
for(var/RQ in CR.required_reagents)
var/decl/chemical_reaction/r_RQ = SSchemistry.chemical_reagents[RQ]
if(!r_RQ)
continue
final_message += " -parts [span_info(r_RQ.name)]<br>"
for(var/IH in CR.inhibitors)
var/decl/chemical_reaction/r_IH = SSchemistry.chemical_reagents[IH]
if(!r_IH)
continue
final_message += " -inhbi [span_info(r_IH.name)]<br>"
for(var/CL in CR.catalysts)
var/decl/chemical_reaction/r_CL = SSchemistry.chemical_reagents[CL]
if(!r_CL)
continue
final_message += " -catyl [span_info(r_CL.name)]<br>"
final_message += "<br>"
else
final_message += span_underline("Potential Chemical breakdown:") + "<br>" + span_red("UNKNOWN OR BASE-REAGENT") + "<br><br>"
var/list/distilled_products = SSchemistry.distilled_reactions_by_product[R.id]
if(distilled_products != null && distilled_products.len > 0)
var/segment = 1
to_chat(user, span_notice("Scanning of \the [I] complete."))
var/list/display_reactions = list()
for(var/decl/chemical_reaction/distilling/CR in distilled_products)
// if(!CR.spoiler) - Downstream self documenting wiki code
display_reactions.Add(CR)
for(var/decl/chemical_reaction/distilling/CR in display_reactions)
if(display_reactions.len == 1)
final_message += span_underline("Potential Chemical Distillation: <br>")
else
final_message += span_underline("Potential Chemical Distillation [segment]: <br>")
segment += 1
final_message += " -temps " + span_info("[CR.temp_range[1]]k") + " - " + span_info("[CR.temp_range[2]]k") + "<br>"
for(var/RQ in CR.required_reagents)
var/decl/chemical_reaction/r_RQ = SSchemistry.chemical_reagents[RQ]
if(!r_RQ)
continue
final_message += " -parts [span_info(r_RQ.name)]<br>"
for(var/IH in CR.inhibitors)
var/decl/chemical_reaction/r_IH = SSchemistry.chemical_reagents[IH]
if(!r_IH)
continue
final_message += " -inhbi [span_info(r_IH.name)]<br>"
for(var/CL in CR.catalysts)
var/decl/chemical_reaction/r_CL = SSchemistry.chemical_reagents[CL]
if(!r_CL)
continue
final_message += " -catyl [span_info(r_CL.name)]<br>"
final_message += "<br>"
// We can get some reagents by grinding sheets and ores!
var/grind_results = ""
for(var/source in global.sheet_reagents)
if(R.id in global.sheet_reagents[source])
var/nm = initial(source:name)
grind_results += " -grind [span_info(nm)]<br>"
if(grind_results != "")
final_message += span_underline("Material Sources: <br>")
final_message += grind_results
final_message += "<br>"
grind_results = ""
for(var/source in global.ore_reagents)
if(R.id in global.ore_reagents[source])
var/nm = initial(source:name)
grind_results += " -grind [span_info(nm)]<br>"
if(grind_results != "")
final_message += span_underline("Ore Sources: <br>")
final_message += grind_results
final_message += "<br>"
// The long forgotten fluid pumps!
// TODO : Update turfs to provide what their fluidpump outputs are too
var/pump_results = ""
for(var/O in GLOB.ore_data)
var/ore/OR = GLOB.ore_data[O]
if(OR.reagent == R.id)
pump_results += " -erosion [span_info(OR.display_name)]<br>"
if(pump_results != "")
final_message += span_underline("Fluid Pump Filtrate: <br>")
final_message += pump_results
final_message += "<br>"
var/makes_result = ""
var/list/instant_by_reagent = SSchemistry.instant_reactions_by_reagent["[R.id]"]
if(instant_by_reagent && instant_by_reagent.len)
for(var/i = 1, i <= instant_by_reagent.len, i++)
var/decl/chemical_reaction/OR = instant_by_reagent[i]
if(istype(OR,/decl/chemical_reaction/instant/slime)) // very bloated and meant to be a mystery
continue
makes_result += " -[span_info(OR.name)]<br>"
var/list/distilled_by_reagent = SSchemistry.distilled_reactions_by_reagent["[R.id]"]
if(distilled_by_reagent && distilled_by_reagent.len)
for(var/i = 1, i <= distilled_by_reagent.len, i++)
var/decl/chemical_reaction/OR = distilled_by_reagent[i]
makes_result += " -[span_info(OR.name)]<br>"
if(makes_result != "")
final_message += span_underline("Can Be Used To Produce: <br>")
final_message += makes_result
final_message += "<br>"
final_message += "Scanning of \the [I] complete."
to_chat(user, span_notice(final_message))
analyzing = FALSE
update_icon()
return

View File

@@ -7,8 +7,8 @@
conditions can cause different byproducts to be produced.<br>\
Magma or Lava can be pumped to produce mineralized fluid."
anchored = 0
density = 1
anchored = TRUE
density = TRUE
icon = 'icons/obj/machines/reagent.dmi'
icon_state = "pump"

View File

@@ -102,6 +102,9 @@
var/amt_produced = result_amount * reaction_progress
if(result)
holder.add_reagent(result, amt_produced, data, safety = 1, was_from_belly = belly_reagent)
// #ifdef UNIT_TEST
// log_unit_test("[name] - Reagent reaction result: [result] [amt_produced]") // Uncomment for UNIT_TEST debug assistance
// #endif
on_reaction(holder, amt_produced)

View File

@@ -87,7 +87,7 @@
/decl/chemical_reaction/instant/drinks/icecoffee/alt
name = "Iced Drip Coffee"
id = REAGENT_ID_ICECOFFEE
id = REAGENT_ID_ICECOFFEE + "_drip"
result = REAGENT_ID_ICECOFFEE
required_reagents = list(REAGENT_ID_ICE = 1, REAGENT_ID_DRIPCOFFEE = 2)
result_amount = 3
@@ -150,14 +150,14 @@
/decl/chemical_reaction/instant/drinks/mocha
name = REAGENT_MOCHA
id = REAGENT_ID_MOCHA
id = REAGENT_ID_MOCHA + "_milk"
result = REAGENT_ID_MOCHA
required_reagents = list(REAGENT_ID_MILK = 1, REAGENT_ID_CREAM = 1, REAGENT_ID_MILKFOAM = 1, REAGENT_ID_HOTCOCO = 2, REAGENT_ID_BREVE = 5) // 2 coffee, 2 milk, 2 cream, 2 milk foam and 2 hot coco
result_amount = 10
/decl/chemical_reaction/instant/drinks/mocha/alt //incase they use cream before milk
name = REAGENT_MOCHA
id = REAGENT_ID_MOCHA
id = REAGENT_ID_MOCHA + "_cream"
result = REAGENT_ID_MOCHA
required_reagents = list(REAGENT_ID_CREAM = 2, REAGENT_ID_HOTCOCO = 2, REAGENT_ID_CAPPUCCINO = 6) // 2 coffee, 2 milk, 2 cream, 2 milk foam and 2 hot coco
result_amount = 10
@@ -563,7 +563,7 @@
/decl/chemical_reaction/instant/drinks/iced_beer2
name = REAGENT_ICEDBEER
id = REAGENT_ID_ICEDBEER
id = REAGENT_ID_ICEDBEER + "_ice"
result = REAGENT_ID_ICEDBEER
required_reagents = list(REAGENT_ID_BEER = 5, REAGENT_ID_ICE = 1)
result_amount = 6

View File

@@ -31,7 +31,7 @@
/decl/chemical_reaction/instant/food/chocolate_bar
name = "Chocolate Bar"
id = "chocolate_bar"
id = "chocolate_bar_soy"
result = null
required_reagents = list(REAGENT_ID_SOYMILK = 2, REAGENT_ID_COCO = 2, REAGENT_ID_SUGAR = 2)
catalysts = list(REAGENT_ID_ENZYME = 5)
@@ -45,7 +45,7 @@
/decl/chemical_reaction/instant/food/chocolate_bar2
name = "Chocolate Bar"
id = "chocolate_bar"
id = "chocolate_bar_milk"
result = null
required_reagents = list(REAGENT_ID_MILK = 2, REAGENT_ID_COCO = 2, REAGENT_ID_SUGAR = 2)
catalysts = list(REAGENT_ID_ENZYME = 5)

View File

@@ -76,6 +76,7 @@
id = REAGENT_ID_WATER
result = REAGENT_ID_WATER
required_reagents = list(REAGENT_ID_OXYGEN = 1, REAGENT_ID_HYDROGEN = 2)
inhibitors = list(REAGENT_ID_CARBON = 1) // CHOMPAdd
result_amount = 1
/decl/chemical_reaction/instant/thermite
@@ -363,7 +364,7 @@
id = REAGENT_ID_STOXIN
result = REAGENT_ID_STOXIN
required_reagents = list(REAGENT_ID_CHLORALHYDRATE = 1, REAGENT_ID_SUGAR = 4)
inhibitors = list(REAGENT_ID_PHOSPHORUS) // Messes with the smoke
inhibitors = list(REAGENT_ID_PHOSPHORUS = 1) // Messes with the smoke
result_amount = 5
/decl/chemical_reaction/instant/chloralhydrate
@@ -614,14 +615,15 @@
/decl/chemical_reaction/instant/solidification/steel
name = "Solid Steel"
id = "solidsteel"
required_reagents = list(REAGENT_ID_FROSTOIL = 5, REAGENT_ID_STEEL = REAGENTS_PER_SHEET)
required_reagents = list(REAGENT_ID_FROSTOIL = 10, REAGENT_ID_IRON = REAGENTS_PER_SHEET, REAGENT_ID_CARBON = REAGENTS_PER_SHEET)
inhibitors = list(REAGENT_ID_PLATINUM = 1) // do not block plasteel formation
sheet_to_give = /obj/item/stack/material/steel
/decl/chemical_reaction/instant/solidification/plasteel
name = "Solid Plasteel"
id = "solidplasteel"
required_reagents = list(REAGENT_ID_FROSTOIL = 10, REAGENT_ID_PLASTEEL = REAGENTS_PER_SHEET)
required_reagents = list(REAGENT_ID_FROSTOIL = 10, REAGENT_ID_IRON = REAGENTS_PER_SHEET, REAGENT_ID_CARBON = REAGENTS_PER_SHEET, REAGENT_ID_PLATINUM = REAGENTS_PER_SHEET)
sheet_to_give = /obj/item/stack/material/plasteel
@@ -682,7 +684,7 @@
/decl/chemical_reaction/instant/carpetify/pcarpet
name = "Purple Carpet"
id = "Purplecarpet"
id = "purplecarpet"
required_reagents = list(REAGENT_ID_LIQUIDCARPETP = 2, REAGENT_ID_PLASTICIDE = 1)
carpet_type = /obj/item/stack/tile/carpet/purcarpet
@@ -784,6 +786,8 @@
result_amount = 2
log_is_important = 1
#ifndef UNIT_TEST
// If it becomes possible to make this without exploding and clearing reagents, remove the UNIT_TEST wrapper
/decl/chemical_reaction/instant/nitroglycerin/on_reaction(var/datum/reagents/holder, var/created_volume)
var/datum/effect/effect/system/reagents_explosion/e = new()
e.set_up(round (created_volume/2, 1), holder.my_atom, 0, 0)
@@ -792,14 +796,13 @@
var/mob/living/L = holder.my_atom
if(L.stat!=DEAD)
e.amount *= 0.5
//VOREStation Add Start
else
holder.clear_reagents() //No more powergaming by creating a tiny amount of this
//VOREStation Add End
e.start()
//holder.clear_reagents() //VOREStation Removal
return
#endif
/decl/chemical_reaction/instant/napalm
name = "Napalm"

View File

@@ -60,6 +60,7 @@
/decl/chemical_reaction/instant/glucose
name = REAGENT_GLUCOSE
id = REAGENT_ID_GLUCOSE
result = REAGENT_ID_GLUCOSE
required_reagents = list(REAGENT_ID_SODIUMCHLORIDE = 1, REAGENT_ID_WATER = 1, REAGENT_ID_SUGAR = 1)
result_amount = 1
@@ -67,7 +68,7 @@
/decl/chemical_reaction/instant/myelamine_sap //This is the clotting agent used by clotting packs.
name = REAGENT_MYELAMINE
id = REAGENT_ID_MYELAMINE
id = REAGENT_ID_MYELAMINE + "sap"
result = REAGENT_ID_MYELAMINE
required_reagents = list(REAGENT_ID_BICARIDINE = 1, REAGENT_ID_IRON = 2, REAGENT_ID_KELOTANE = 1, REAGENT_ID_BLUESAP = 1)
result_amount = 1

View File

@@ -103,6 +103,8 @@
/// Miscellaneous Reactions
/decl/chemical_reaction/instant/foam/softdrink
name = "Decarbonated Drink"
id = "soda_fizz"
required_reagents = list(REAGENT_ID_COLA = 1, REAGENT_ID_MINT = 1)
/decl/chemical_reaction/instant/firefightingfoam //TODO: Make it so we can add this to the foam tanks to refill them

View File

@@ -56,6 +56,7 @@
var/level_max = 2
/decl/chemical_reaction/instant/mix_virus/picky
id = "mixviruspicky"
var/list/datum/symptom/symptoms
/decl/chemical_reaction/instant/mix_virus/on_reaction(datum/reagents/holder)
@@ -156,6 +157,6 @@
name = REAGENT_ANTIBODIES
id = "antibodiesmix"
result = REAGENT_ID_ANTIBODIES
required_reagents = list(REAGENT_ID_VACCINE)
required_reagents = list(REAGENT_ID_VACCINE = 1)
catalysts = list(REAGENT_ID_INAPROVALINE = 0.1)
result_amount = 0.5