diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 622ac1cef647..fc4df4501a65 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -153,3 +153,6 @@ #define CARTRIDGE_VOLUME_LARGE 500 #define CARTRIDGE_VOLUME_MEDIUM 250 #define CARTRIDGE_VOLUME_SMALL 100 + +/// Boiling point of water +#define BOILING_POINT_WATER 373.15 diff --git a/code/controllers/subsystem/processing/reagents.dm b/code/controllers/subsystem/processing/reagents.dm index 75e8c764919f..2a64c53bb2bc 100644 --- a/code/controllers/subsystem/processing/reagents.dm +++ b/code/controllers/subsystem/processing/reagents.dm @@ -4,7 +4,7 @@ PROCESSING_SUBSYSTEM_DEF(reagents) name = "Reagents" init_order = INIT_ORDER_REAGENTS priority = FIRE_PRIORITY_REAGENTS - wait = 0.25 SECONDS //You might think that rate_up_lim has to be set to half, but since everything is normalised around delta_time, it automatically adjusts it to be per second. Magic! + wait = 0.25 SECONDS //You might think that base_reaction_rate has to be set to half, but since everything is normalised around delta_time, it automatically adjusts it to be per second. Magic! flags = SS_KEEP_TIMING | SS_HIBERNATE runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME ///What time was it when we last ticked @@ -61,7 +61,6 @@ PROCESSING_SUBSYSTEM_DEF(reagents) if(isabstract(path))//Are we abstract? continue var/datum/reagent/D = new path() - D.mass = rand(10, 800) //This is terrible and should be removed ASAP! reagent_list[path] = D return reagent_list diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index 1028c07c9e7b..569ffe2e1a77 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -206,3 +206,8 @@ mid_length = 2.1 SECONDS end_sound = 'goon/sounds/phone/remote_pickup.ogg' volume = 10 + +/datum/looping_sound/boiling + mid_sounds = list('sound/effects/bubbles2.ogg') + mid_length = 7 SECONDS + volume = 40 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index c83b97d0140c..268b42823b3d 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -515,7 +515,7 @@ moving_from_pull = FALSE forcemove_should_maintain_grab = FALSE - update_offsets() + update_offsets(TRUE) /** * Called after a successful Move(). By this point, we've already moved. diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 136abd3d3253..c42c7752bce8 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -125,7 +125,7 @@ M.setDir(dir) post_buckle_mob(M) - M.update_offsets() + M.update_offsets(TRUE) SEND_SIGNAL(src, COMSIG_MOVABLE_BUCKLE, M, force) return TRUE @@ -177,7 +177,7 @@ buckled_mob.zFall() post_unbuckle_mob(.) - buckled_mob.update_offsets() + buckled_mob.update_offsets(TRUE) if(!QDELETED(buckled_mob) && !buckled_mob.currently_z_moving && isturf(buckled_mob.loc)) // In the case they unbuckled to a flying movable midflight. buckled_mob.zFall() @@ -362,5 +362,5 @@ span_hear("You hear metal clanking.")) add_fingerprint(user) - update_offsets() + update_offsets(TRUE) return M diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm index 3c03e7f5383f..30c5779a3ce1 100644 --- a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm @@ -421,6 +421,9 @@ /obj/effect/particle_effect/fluid/smoke/chem lifetime = 20 SECONDS +/obj/effect/particle_effect/fluid/smoke/chem/transparent + make_opaque = FALSE + /obj/effect/particle_effect/fluid/smoke/chem/process(seconds_per_tick) . = ..() if(!.) @@ -517,3 +520,4 @@ /datum/effect_system/fluid_spread/smoke/chem/quick effect_type = /obj/effect/particle_effect/fluid/smoke/chem/quick + diff --git a/code/modules/atmospherics/ZAS/zas_extras/gas_reagents.dm b/code/modules/atmospherics/ZAS/zas_extras/gas_reagents.dm index 2a63211b81bb..c0cb602cfe33 100644 --- a/code/modules/atmospherics/ZAS/zas_extras/gas_reagents.dm +++ b/code/modules/atmospherics/ZAS/zas_extras/gas_reagents.dm @@ -8,6 +8,9 @@ taste_description = "sweetness" chemical_flags = REAGENT_NO_RANDOM_RECIPE + boiling_point = 165 + dew_point = 165 * 0.9 + /datum/reagent/carbon_monoxide name = "Carbon Monoxide" description = "A dangerous carbon comubstion byproduct." diff --git a/code/modules/food_and_drinks/recipes/drinks_recipes.dm b/code/modules/food_and_drinks/recipes/drinks_recipes.dm index f09770b3c66d..cdda24b53890 100644 --- a/code/modules/food_and_drinks/recipes/drinks_recipes.dm +++ b/code/modules/food_and_drinks/recipes/drinks_recipes.dm @@ -4,7 +4,7 @@ optimal_temp = 250 temp_exponent_factor = 1 thermic_constant = 0 - rate_up_lim = 60 + base_reaction_rate = 60 ////////////////////////////////////////// COCKTAILS ////////////////////////////////////// diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm index 15d5c2c72e16..2f29300a9d89 100644 --- a/code/modules/food_and_drinks/recipes/food_mixtures.dm +++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm @@ -87,7 +87,7 @@ required_reagents = list(/datum/reagent/consumable/caramel = 1) required_temp = 483.15 optimal_temp = 1000 - rate_up_lim = 10 + base_reaction_rate = 10 mob_react = FALSE /datum/chemical_reaction/food/cheesewheel diff --git a/code/modules/grab/grab_datum.dm b/code/modules/grab/grab_datum.dm index 833b1791b930..a42018406476 100644 --- a/code/modules/grab/grab_datum.dm +++ b/code/modules/grab/grab_datum.dm @@ -118,7 +118,7 @@ GLOBAL_LIST_EMPTY(all_grabstates) remove_unique_grab_effects(G.affecting) update_stage_effects(G, src, TRUE) - G.affecting.update_offsets() + G.affecting.update_offsets(TRUE) SEND_SIGNAL(G.affecting, COMSIG_ATOM_NO_LONGER_GRABBED, G.assailant) SEND_SIGNAL(G.assailant, COMSIG_LIVING_NO_LONGER_GRABBING, G.affecting) diff --git a/code/modules/grab/grab_living.dm b/code/modules/grab/grab_living.dm index 5117a8366058..d01163724d39 100644 --- a/code/modules/grab/grab_living.dm +++ b/code/modules/grab/grab_living.dm @@ -166,7 +166,7 @@ G.downgrade() if(moving_diagonally != FIRST_DIAG_STEP) - pulling.update_offsets() + pulling.update_offsets(TRUE) var/list/my_grabs = active_grabs for(var/obj/item/hand_item/grab/G in my_grabs) diff --git a/code/modules/grab/grab_movable.dm b/code/modules/grab/grab_movable.dm index a88ced0321dd..d1a86c9b7300 100644 --- a/code/modules/grab/grab_movable.dm +++ b/code/modules/grab/grab_movable.dm @@ -42,7 +42,7 @@ for(var/obj/item/hand_item/grab/G in active_grabs) G.move_victim_towards(destination) -/atom/movable/proc/update_offsets() +/atom/movable/proc/update_offsets(animate = FALSE) var/last_pixel_x = pixel_x var/last_pixel_y = pixel_y @@ -55,7 +55,7 @@ if(length(buckled_mobs)) for(var/mob/M as anything in buckled_mobs) - M.update_offsets() + M.update_offsets(animate) if(isliving(src)) var/mob/living/L = src @@ -67,6 +67,10 @@ G.current_grab.get_grab_offsets(G, get_dir(G.assailant, G.affecting), &new_pixel_x, &new_pixel_y) if(last_pixel_x != new_pixel_x || last_pixel_y != new_pixel_y) - animate(src, pixel_x = new_pixel_x, pixel_y = new_pixel_y, 3, 1, (LINEAR_EASING|EASE_IN)) + if(animate) + animate(src, pixel_x = new_pixel_x, pixel_y = new_pixel_y, 3, 1, (LINEAR_EASING|EASE_IN), flags = ANIMATION_PARALLEL) + else + pixel_x = new_pixel_x + pixel_y = new_pixel_y UPDATE_OO_IF_PRESENT diff --git a/code/modules/grab/grab_object.dm b/code/modules/grab/grab_object.dm index 0d966a123ad7..eab12a77529f 100644 --- a/code/modules/grab/grab_object.dm +++ b/code/modules/grab/grab_object.dm @@ -452,7 +452,7 @@ affecting.move_from_pull(assailant, get_turf(assailant)) affecting.setDir(assailant.dir) - affecting.update_offsets() + affecting.update_offsets(TRUE) affecting.reset_plane_and_layer() /obj/item/hand_item/grab/proc/move_victim_towards(atom/destination) @@ -478,7 +478,7 @@ // Okay, now actually try to move . = affecting.Move(get_step(affecting.loc, move_dir), move_dir, glide_size) if(.) - affecting.update_offsets() + affecting.update_offsets(TRUE) /// Removes any grabs applied to the affected movable that aren't src /obj/item/hand_item/grab/proc/remove_competing_grabs() diff --git a/code/modules/jobs/job_types/chemist.dm b/code/modules/jobs/job_types/chemist.dm index 4105573fb940..698f55b74b47 100644 --- a/code/modules/jobs/job_types/chemist.dm +++ b/code/modules/jobs/job_types/chemist.dm @@ -57,3 +57,7 @@ box = /obj/item/storage/box/survival/medical chameleon_extras = /obj/item/gun/syringe + + backpack_contents = list( + /obj/item/clothing/mask/gas, + ) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index dabb4b88a879..09d06d4ae805 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -173,7 +173,7 @@ var/oldMloc = M.loc forceMove(oldMloc) M.forceMove(oldloc) - M.update_offsets() + M.update_offsets(TRUE) now_pushing = FALSE return TRUE diff --git a/code/modules/reagents/chemistry/equilibrium.dm b/code/modules/reagents/chemistry/equilibrium.dm index 9ff7ea5ecf76..0c6e29b7b0e7 100644 --- a/code/modules/reagents/chemistry/equilibrium.dm +++ b/code/modules/reagents/chemistry/equilibrium.dm @@ -230,6 +230,7 @@ if(!calculate_yield())//So that this can detect if we're missing reagents to_delete = TRUE return + delta_time = deal_with_time(delta_time) delta_t = 0 //how far off optimal temp we care @@ -266,7 +267,7 @@ delta_t *= speed_mod //Now we calculate how much to add - this is normalised to the rate up limiter - var/delta_chem_factor = reaction.rate_up_lim * delta_t *delta_time //add/remove factor + var/delta_chem_factor = reaction.base_reaction_rate * delta_t *delta_time //add/remove factor var/total_step_added = 0 //keep limited if(delta_chem_factor > step_target_vol) @@ -281,9 +282,34 @@ var/required_amount for(var/datum/reagent/requirement as anything in reaction.required_reagents) required_amount = reaction.required_reagents[requirement] - if(!holder.remove_reagent(requirement, delta_chem_factor * required_amount)) - to_delete = TRUE - return + var/alist/requirement_consumption_chance_list = reaction.requirement_consumption_modifiers[requirement.type] + #ifdef UNIT_TESTS + requirement_consumption_chance_list = null + #endif + + var/real_required_amount = delta_chem_factor * required_amount + + // null is an implicit 100% chance to consume the reagent on reaction. + if(isnull(requirement_consumption_chance_list)) + if(!holder.remove_reagent(requirement, real_required_amount)) + to_delete = TRUE + return + else + var/reagent_consumption_modifier = pick_weight(requirement_consumption_chance_list) + if(reagent_consumption_modifier == 1) + if(!holder.remove_reagent(requirement, real_required_amount)) + to_delete = TRUE + return + + else + if(!holder.has_reagent(requirement, real_required_amount)) + to_delete = TRUE + return + + // Modified required amount could be higher than the base consumption amount. In this instance we do NOT want it to fail the reaction + // if there isn't enough. That's fine. Otherwise reactions could randomly end and restart and leave players confused. + var/modified_required_amount = round(real_required_amount * reagent_consumption_modifier, CHEMICAL_VOLUME_ROUNDING) + holder.remove_reagent(requirement, modified_required_amount) var/step_add for(var/datum/reagent/product as anything in reaction.results) diff --git a/code/modules/reagents/chemistry/goon_reagents/other_reagents.dm b/code/modules/reagents/chemistry/goon_reagents/other_reagents.dm index 3d2fd16351b3..96c0d35549cc 100644 --- a/code/modules/reagents/chemistry/goon_reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/goon_reagents/other_reagents.dm @@ -57,8 +57,7 @@ reagent_state = LIQUID color = "#2D2D2D" taste_description = "oil" - burning_temperature = 1200//Oil is crude - burning_volume = 0.05 //but has a lot of hydrocarbons + boiling_point = 1200 //Oil is crude addiction_types = null @@ -83,8 +82,7 @@ glass_name = "glass of welder fuel" glass_desc = "Unless you're an industrial tool, this is probably not safe for consumption." penetrates_skin = NONE - burning_temperature = 1725 //more refined than oil - burning_volume = 0.2 + boiling_point = 1725 //more refined than oil addiction_types = list(/datum/addiction/alcohol = 4) @@ -350,6 +348,9 @@ metabolization_rate = 0.04 value = DISPENSER_REAGENT_VALUE + boiling_point = 329 + dew_point = 329 * 0.9 + /datum/reagent/acetone/affect_blood(mob/living/carbon/C, removed) C.adjustToxLoss(removed * 3, FALSE, cause_of_death = "Ingesting acetone") return TRUE diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 693962466727..0619a89275d9 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -504,7 +504,7 @@ return amount /// Transfer a specific reagent id to the target object. Accepts a reagent instance, but assumes the reagent is in src. -/datum/reagents/proc/trans_id_to(obj/target, datum/reagent/reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N +/datum/reagents/proc/trans_id_to(obj/target, datum/reagent/reagent, amount=1, preserve_data = TRUE, no_react = FALSE)//Not sure why this proc didn't exist before. It does now! /N var/list/cached_reagents = reagent_list if (!target) return @@ -548,7 +548,9 @@ update_total() holder.update_total() - holder.handle_reactions() + if(!no_react) + handle_reactions() + holder.handle_reactions() return amount /// Copies the reagents to the target object @@ -1626,7 +1628,7 @@ has_product = FALSE var/list/names = splittext("[reaction.type]", "/") var/product_name = names[names.len] - data["reagent_mode_recipe"] = list("name" = product_name, "id" = reaction.type, "hasProduct" = has_product, "reagentCol" = "#FFFFFF", "thermodynamics" = generate_thermodynamic_profile(reaction), "explosive" = generate_explosive_profile(reaction), "thermics" = determine_reaction_thermics(reaction), "thermoUpper" = reaction.rate_up_lim, "tempMin" = reaction.required_temp, "explodeTemp" = reaction.overheat_temp, "reqContainer" = container_name, "subReactLen" = 1, "subReactIndex" = 1) + data["reagent_mode_recipe"] = list("name" = product_name, "id" = reaction.type, "hasProduct" = has_product, "reagentCol" = "#FFFFFF", "thermodynamics" = generate_thermodynamic_profile(reaction), "explosive" = generate_explosive_profile(reaction), "thermics" = determine_reaction_thermics(reaction), "thermoUpper" = reaction.base_reaction_rate, "tempMin" = reaction.required_temp, "explodeTemp" = reaction.overheat_temp, "reqContainer" = container_name, "subReactLen" = 1, "subReactIndex" = 1) //If we do have a product then we find it else @@ -1648,7 +1650,7 @@ ui_reaction_index = i //update our index break i += 1 - data["reagent_mode_recipe"] = list("name" = primary_reagent.name, "id" = reaction.type, "hasProduct" = has_product, "reagentCol" = primary_reagent.color, "thermodynamics" = generate_thermodynamic_profile(reaction), "explosive" = generate_explosive_profile(reaction), "thermics" = determine_reaction_thermics(reaction), "thermoUpper" = reaction.rate_up_lim, "tempMin" = reaction.required_temp, "explodeTemp" = reaction.overheat_temp, "reqContainer" = container_name, "subReactLen" = sub_reaction_length, "subReactIndex" = ui_reaction_index) + data["reagent_mode_recipe"] = list("name" = primary_reagent.name, "id" = reaction.type, "hasProduct" = has_product, "reagentCol" = primary_reagent.color, "thermodynamics" = generate_thermodynamic_profile(reaction), "explosive" = generate_explosive_profile(reaction), "thermics" = determine_reaction_thermics(reaction), "thermoUpper" = reaction.base_reaction_rate, "tempMin" = reaction.required_temp, "explodeTemp" = reaction.overheat_temp, "reqContainer" = container_name, "subReactLen" = sub_reaction_length, "subReactIndex" = ui_reaction_index) //Results sweep var/has_reagent = "default" diff --git a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm index ff9d1e4a81d3..b47174aab7a2 100644 --- a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm +++ b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm @@ -246,7 +246,7 @@ list("name" = "overheat_temp" , "var" = edit_recipe.overheat_temp), list("name" = "temp_exponent_factor" , "var" = edit_recipe.temp_exponent_factor), list("name" = "thermic_constant" , "var" = edit_recipe.thermic_constant), - list("name" = "rate_up_lim" , "var" = edit_recipe.rate_up_lim), + list("name" = "base_reaction_rate" , "var" = edit_recipe.base_reaction_rate), ) return data @@ -338,7 +338,7 @@ optimal_temp = [edit_recipe.optimal_temp] overheat_temp = [edit_recipe.overheat_temp] temp_exponent_factor = [edit_recipe.temp_exponent_factor] thermic_constant = [edit_recipe.thermic_constant] -rate_up_lim = [edit_recipe.rate_up_lim]"} +base_reaction_rate = [edit_recipe.base_reaction_rate]"} say(export) text2file(export, "[GLOB.log_directory]/chem_parse.txt") diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index d63fca45192b..54cc29bd1230 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -44,8 +44,10 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) var/reagent_state = LIQUID /// Special data associated with the reagent that will be passed on upon transfer to a new holder. var/list/data + /// increments everytime on_mob_life is called var/current_cycle = 0 + ///pretend this is moles var/volume = 0 ///The molar mass of the reagent - if you're adding a reagent that doesn't have a recipe, just add a random number between 10 - 800. Higher numbers are "harder" but it's mostly arbitary. @@ -83,10 +85,13 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) var/show_in_codex = TRUE ///Thermodynamic vars - ///How hot this reagent burns when it's on fire - null means it can't burn - var/burning_temperature = null - ///How much is consumed when it is burnt per second - var/burning_volume = 0.5 + ///How hot this reagent needs to be to begin boiling. null means it will not boil. + var/boiling_point = BOILING_POINT_WATER + 100 // Arbitrary default that is "more than water". + /// When output from a condenser, the reagent will be this temperature. + var/dew_point = (BOILING_POINT_WATER + 100) * 0.9 // Value is arbitrary. + + /// Units lost per second while boiling. + var/boil_off_rate = 2.5 ///Assoc list with key type of addiction this reagent feeds, and value amount of addiction points added per unit of reagent metabolzied (which means * REAGENTS_METABOLISM every life()) var/list/addiction_types = null diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index fb406f3b42fc..c557f1593a0c 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -15,8 +15,7 @@ touch_met = 5 ingest_met = 0.2 - burning_temperature = 2193//ethanol burns at 1970C (at it's peak) - burning_volume = 0.1 + boiling_point = 2193 //ethanol burns at 1970C (at it's peak) var/boozepwr = 65 //Higher numbers equal higher hardness, higher hardness equals more intense alcohol poisoning var/toxicity = 1 diff --git a/code/modules/reagents/chemistry/reagents/dispenser_reagents.dm b/code/modules/reagents/chemistry/reagents/dispenser_reagents.dm index e8ff1d2adf9b..db6ff85fb462 100644 --- a/code/modules/reagents/chemistry/reagents/dispenser_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/dispenser_reagents.dm @@ -7,6 +7,8 @@ color = "#a8a8a8" value = DISPENSER_REAGENT_VALUE + boiling_point = null + /datum/reagent/ammonia name = "Ammonia" taste_description = "mordant" @@ -18,6 +20,9 @@ overdose_threshold = 5 value = DISPENSER_REAGENT_VALUE + boiling_point = 239 + dew_point = 239 * 0.9 + /datum/reagent/ammonia/affect_blood(mob/living/carbon/C, removed) C.adjustToxLoss(removed * 1.5, FALSE, cause_of_death = "Ingesting ammonia") return TRUE @@ -42,6 +47,8 @@ ingest_met = 2 value = DISPENSER_REAGENT_VALUE + boiling_point = null + /datum/reagent/carbon/affect_ingest(mob/living/carbon/C, removed) var/datum/reagents/ingested = C.get_ingested_reagents() if (ingested && length(ingested.reagent_list) > 1) // Need to have at least 2 reagents - cabon and something to remove @@ -64,13 +71,6 @@ else dirtoverlay.alpha = min(dirtoverlay.alpha + reac_volume * 30, 255) -/datum/reagent/copper - name = "Copper" - description = "A highly ductile metal." - taste_description = "copper" - color = "#6e3b08" - value = DISPENSER_REAGENT_VALUE - /datum/reagent/iron name = "Iron" description = "Pure iron is a metal." @@ -79,6 +79,8 @@ color = "#353535" value = DISPENSER_REAGENT_VALUE + boiling_point = null + /datum/reagent/iron/affect_blood(mob/living/carbon/C, removed) . = ..() C.adjustBloodVolume(2 * removed) @@ -91,6 +93,8 @@ color = "#808080" value = DISPENSER_REAGENT_VALUE + boiling_point = null + /datum/reagent/lithium/affect_blood(mob/living/carbon/C, removed) if(!isspaceturf(C.loc)) step(C, GLOB.cardinals) @@ -107,6 +111,9 @@ color = "#484848" value = DISPENSER_REAGENT_VALUE + boiling_point = 630 + dew_point = 630 * 0.9 + /datum/reagent/mercury/affect_blood(mob/living/carbon/C, removed) if(!isspaceturf(C.loc)) step(C, pick(GLOB.cardinals)) @@ -124,6 +131,9 @@ color = "#832828" value = DISPENSER_REAGENT_VALUE + boiling_point = 704 + dew_point = 704 * 0.9 + /datum/reagent/potassium name = "Potassium" description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water." @@ -132,6 +142,8 @@ color = "#a0a0a0" value = DISPENSER_REAGENT_VALUE + boiling_point = null + /datum/reagent/potassium/affect_blood(mob/living/carbon/C, removed) if(volume > 10) APPLY_CHEM_EFFECT(C, CE_PULSE, 2) @@ -151,6 +163,9 @@ var/max_damage = 40 value = DISPENSER_REAGENT_VALUE + boiling_point = 610 + dew_point = 610 * 0.9 + /datum/reagent/toxin/acid/affect_blood(mob/living/carbon/C, removed) C.adjustFireLoss(removed * acidpwr, FALSE) return TRUE @@ -205,6 +220,9 @@ max_damage = 30 value = DISPENSER_REAGENT_VALUE * 2 + boiling_point = 381 + dew_point = 381 * 0.9 + /datum/reagent/silicon name = "Silicon" description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon." @@ -212,6 +230,8 @@ color = "#a8a8a8" value = DISPENSER_REAGENT_VALUE + boiling_point = null + /datum/reagent/sodium name = "Sodium" description = "A chemical element, readily reacts with water." @@ -220,6 +240,8 @@ color = "#808080" value = DISPENSER_REAGENT_VALUE + boiling_point = null + /datum/reagent/sulfur name = "Sulfur" description = "A chemical element with a pungent smell." @@ -228,6 +250,9 @@ color = "#bf8c00" value = DISPENSER_REAGENT_VALUE + boiling_point = 717.8 + dew_point = 717.8 * 0.9 + /datum/reagent/tungsten name = "Tungsten" description = "A chemical element, and a strong oxidising agent." @@ -236,6 +261,8 @@ color = "#dcdcdc" value = DISPENSER_REAGENT_VALUE + boiling_point = null + /datum/reagent/oxygen name = "Oxygen" description = "A colorless, odorless gas. Grows on trees but is still pretty valuable." @@ -243,6 +270,8 @@ color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 // oderless and tasteless + boiling_point = 90.2 + dew_point = 90.2 * 0.9 /datum/reagent/oxygen/expose_turf(turf/exposed_turf, reac_volume, exposed_temperature) . = ..() @@ -257,6 +286,8 @@ color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 + boiling_point = 77.36 + dew_point = 77.36 * 0.9 /datum/reagent/nitrogen/expose_turf(turf/open/exposed_turf, reac_volume) . = ..() @@ -271,6 +302,8 @@ color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 + boiling_point = 20.28 + dew_point = 20.28 * 0.9 /datum/reagent/fluorine name = "Fluorine" @@ -279,6 +312,8 @@ color = "#808080" // rgb: 128, 128, 128 taste_description = "acid" + boiling_point = 85.04 + dew_point = 85.04 * 0.9 // You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial /datum/reagent/fluorine/on_hydroponics_apply(datum/plant_tick/plant_tick, datum/reagents/chems, volume, obj/machinery/hydroponics/mytray, mob/user) @@ -298,6 +333,8 @@ color = "#80919d" metabolization_rate = 0.15 + boiling_point = null + /datum/reagent/lead/affect_blood(mob/living/carbon/C, removed) C.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5) @@ -308,6 +345,8 @@ color = "#BC8A00" taste_description = "metal" + boiling_point = 457.4 + dew_point = 457.4 * 0.9 /datum/reagent/carbondioxide name = "Carbon Dioxide" @@ -316,6 +355,8 @@ color = "#B0B0B0" // rgb : 192, 192, 192 taste_description = "something unknowable" + boiling_point = 194.7 + dew_point = 194.8 * 0.9 /datum/reagent/carbondioxide/expose_turf(turf/open/exposed_turf, reac_volume) if(istype(exposed_turf)) @@ -330,7 +371,8 @@ color = "#FFFB89" //pale yellow? let's make it light gray taste_description = "chlorine" - + boiling_point = 239.11 + dew_point = 239.11 * 0.9 // You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial /datum/reagent/chlorine/on_hydroponics_apply(datum/plant_tick/plant_tick, datum/reagents/chems, volume, obj/machinery/hydroponics/mytray, mob/user) @@ -347,18 +389,25 @@ color = "#FFFFFF" reagent_state = SOLID + boiling_point = null + /datum/reagent/helium name = "Helium" description = "Does not make any sound." reagent_state = GAS color = "#ffffa099" + boiling_point = 4.22 + dew_point = 4 + /datum/reagent/nickel name = "Nickel" description = "Contrary to popular belief, this is not a currency." reagent_state = SOLID color = "#dcdcdc" + boiling_point = null + /datum/reagent/copper name = "Copper" description = "A highly ductile metal. Things made out of copper aren't very durable, but it makes a decent material for electrical wiring." @@ -366,6 +415,7 @@ color = "#6E3B08" // rgb: 110, 59, 8 taste_description = "metal" + boiling_point = null /datum/reagent/copper/expose_obj(obj/exposed_obj, reac_volume, exposed_temperature) . = ..() @@ -384,3 +434,5 @@ color = "#D0D0D0" // rgb: 208, 208, 208 taste_description = "expensive yet reasonable metal" material = /datum/material/silver + + boiling_point = null diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 722d7cd8b5c1..d20c43eefa7d 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -1085,3 +1085,35 @@ C.adjustToxLoss(1, cause_of_death = "Zedaphen overdose") // Counter-acted by the normal metabolization, resulting in minor organ damage. C.Unconscious(10 SECONDS) // You're in for it now. + +/datum/reagent/medicine/shmowder + name = "Shmowder" + taste_description = "horrible bitterness" + taste_mult = 100 + description = "A horrible mess of pharmaceuticals masquerading as \"medicine\"." + reagent_state = LIQUID + color = "#d8d8d8" + + ingest_met = 0.2 + +/datum/reagent/medicine/shmowder/affect_ingest(mob/living/carbon/C, removed) + . = ..() + // After having gone through 10u of the thing, there's a 5% chance every 10 units processed to cure all diseases. + if(current_cycle >= 50 && prob(current_cycle / 10)) + for(var/datum/pathogen/pathogen in C.diseases) + pathogen.force_cure(add_resistance = FALSE) + + if(prob(80)) // *THUD* + C.adjustBruteLoss(-10 * removed, FALSE) + + if(prob(80)) // *THUD* + C.adjustBruteLoss(-10 * removed, FALSE) + + if(prob(80)) // *THUD* + C.adjustBloodVolumeUpTo(10 * removed, BLOOD_VOLUME_NORMAL) + + if(prob(80)) // *THUD* + C.adjustToxLoss(-2 * removed, FALSE) + + C.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10 * removed, updating_health = FALSE) + return TRUE diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 28df850b49f7..ff6e45d74640 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -12,6 +12,9 @@ metabolization_rate = 2 ingest_met = 2 + boiling_point = BOILING_POINT_WATER + dew_point = BOILING_POINT_WATER * 0.9 + /datum/reagent/water/expose_turf(turf/open/exposed_turf, reac_volume, exposed_temperature) . = ..() if(!istype(exposed_turf)) @@ -657,6 +660,12 @@ color = "#604030" // rgb: 96, 64, 48 taste_description = "iron" + boiling_point = 328.6 + dew_point = 328.6 * 0.9 + +/datum/reagent/diethylamine/affect_blood(mob/living/carbon/C, removed) + C.adjustToxLoss(removed * 2, FALSE, cause_of_death = "Ingesting diethylamine") + return TRUE // This is more bad ass, and pests get hurt by the corrosive nature of it, not the plant. The new trade off is it culls stability. /datum/reagent/diethylamine/on_hydroponics_apply(datum/plant_tick/plant_tick, datum/reagents/chems, volume, obj/machinery/hydroponics/mytray, mob/user) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index dd85d996c281..f1380f4eb79f 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -211,9 +211,7 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "bitterness" self_consuming = TRUE - burning_temperature = null - burning_volume = 0.05 - + boiling_point = null /datum/reagent/pyrosium/affect_blood(mob/living/carbon/C, removed) if(holder.has_reagent(/datum/reagent/oxygen)) @@ -222,9 +220,10 @@ /datum/reagent/pyrosium/burn(datum/reagents/holder) if(holder.has_reagent(/datum/reagent/oxygen)) - burning_temperature = 3500 + boiling_point = 3500 return - burning_temperature = null + + boiling_point = null /datum/reagent/firefighting_foam name = "Firefighting Foam" diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 4f174b5b5213..d7056890c7b4 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -80,8 +80,7 @@ toxpwr = 3 material = /datum/material/plasma penetrates_skin = NONE - burning_temperature = 4500//plasma is hot!! - burning_volume = 0.3//But burns fast + boiling_point = 4500//plasma is hot!! codex_mechanics = "Plasma will ignite at 519.15 K, take care when handling." /datum/reagent/toxin/plasma/on_new(data) diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 0781c2c9cb25..8b5f156ef221 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -15,6 +15,10 @@ ///Reagents that block the reaction from occuring, like an inverse catalyst. var/list/inhibitors = list() + /// A nested alist where each pair is a type to another alist, with the alist being a weighted list of modifier -> chance. + /// See Bicardine for an example. + var/list/requirement_consumption_modifiers = alist() + /// the exact container path required for the reaction to happen. var/required_container /// Some stupid magic bullshit for slime reactions. Literally what the fuck. @@ -29,6 +33,7 @@ /// Set to TRUE if you want the recipe to only react when it's BELOW the required temp. var/is_cold_recipe = FALSE + ///FermiChem! - See fermi_readme.md ///Required temperature for the reaction to begin, for fermimechanics it defines the lower area of bell curve for determining heat based rate reactions, aka the minimum var/required_temp = 100 @@ -42,8 +47,9 @@ /// How much the temperature changes per unit of chem used. without REACTION_HEAT_ARBITARY flag the rate of change depends on the holder heat capacity else results are more accurate var/thermic_constant = 50 - /// Optimal/max rate possible if all conditions are perfect - var/rate_up_lim = 30 + + /// When at the optimal temperature, this is the rate at which the reaction occurs per second. Usually this is reagent conversion. + var/base_reaction_rate = 15 /// Affects how reactions occur var/reaction_flags = NONE @@ -466,3 +472,42 @@ equilibrium.data[id] = 0 return TRUE return FALSE + +/* +* Creates smoke of the given reagents if the container is open. +* Dose not remove reagents from the holder. +* +* Arguments: +* * reagent_list - a k:v list of reagent_type : amount, these are the reagents given to the smoke emitter. +* * smoke_range - The range of smoke emitted. +*/ +/datum/chemical_reaction/proc/kapuchem_smoke(datum/reagents/holder, datum/equilibrium/equilibrium, list/reagent_list, smoke_range) + smoke_range = floor(smoke_range) + if(smoke_range < 1) + return + + if(!(holder.flags & OPENCONTAINER)) + return + + var/atom/movable/AM = holder.my_atom + if(!istype(AM)) + return + + var/turf/smoke_loc = get_turf(AM) + if(isnull(smoke_loc)) + return + + var/datum/reagents/temp_holder = new(100, NO_REACT) + temp_holder.add_reagent_list(reagent_list) // Half of the ammonia reaction is lost to the air + + var/datum/effect_system/fluid_spread/smoke/chem/quick/smoke_emitter = new() + smoke_emitter.attach(smoke_loc) + smoke_emitter.set_up( + smoke_range, + location = smoke_loc, + carry = temp_holder, + silent = FALSE, + ) + + qdel(temp_holder) + smoke_emitter.start() diff --git a/code/modules/reagents/chemistry/recipes/drugs.dm b/code/modules/reagents/chemistry/recipes/drugs_recipes.dm similarity index 99% rename from code/modules/reagents/chemistry/recipes/drugs.dm rename to code/modules/reagents/chemistry/recipes/drugs_recipes.dm index 48998852a4ac..b0677457309f 100644 --- a/code/modules/reagents/chemistry/recipes/drugs.dm +++ b/code/modules/reagents/chemistry/recipes/drugs_recipes.dm @@ -29,7 +29,7 @@ overheat_temp = 380 temp_exponent_factor = 1 thermic_constant = 0.1 //exothermic nature is equal to impurty - rate_up_lim = 12.5 + base_reaction_rate = 12.5 reaction_flags = REACTION_HEAT_ARBITARY //Heating up is arbitary because of submechanics of this reaction. /datum/chemical_reaction/methamphetamine/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added) diff --git a/code/modules/reagents/chemistry/recipes/gateway.dm b/code/modules/reagents/chemistry/recipes/gateway_recipes.dm similarity index 91% rename from code/modules/reagents/chemistry/recipes/gateway.dm rename to code/modules/reagents/chemistry/recipes/gateway_recipes.dm index 1ac683437fe3..4d7134fa81fa 100644 --- a/code/modules/reagents/chemistry/recipes/gateway.dm +++ b/code/modules/reagents/chemistry/recipes/gateway_recipes.dm @@ -3,6 +3,10 @@ results = list(/datum/reagent/acetone = 3) required_reagents = list(/datum/reagent/fuel/oil = 1, /datum/reagent/fuel = 1, /datum/reagent/oxygen = 1) + overheat_temp = 650 + optimal_temp = 380 + required_temp = 178 // Acetone freezes around here + /datum/chemical_reaction/oil results = list(/datum/reagent/fuel/oil = 3) required_reagents = list(/datum/reagent/fuel = 1, /datum/reagent/hydrogen = 1, /datum/reagent/carbon = 1) diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine_recipes.dm similarity index 82% rename from code/modules/reagents/chemistry/recipes/medicine.dm rename to code/modules/reagents/chemistry/recipes/medicine_recipes.dm index a689f408d072..461b12c40695 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine_recipes.dm @@ -1,28 +1,51 @@ -/datum/chemical_reaction/inaprovaline - results = list(/datum/reagent/medicine/inaprovaline = 3) - required_reagents = list(/datum/reagent/acetone = 1, /datum/reagent/carbon = 1, /datum/reagent/consumable/sugar = 1, /datum/reagent/phenol = 1) - -/datum/chemical_reaction/dylovene - results = list(/datum/reagent/medicine/dylovene = 3) - required_reagents = list(/datum/reagent/silicon = 1, /datum/reagent/potassium = 1, /datum/reagent/ammonia = 1) - +// +// Brute chems +// /datum/chemical_reaction/bicaridine results = list(/datum/reagent/medicine/bicaridine = 2) - required_reagents = list(/datum/reagent/phosphorus = 1, /datum/reagent/carbon = 1, /datum/reagent/acetone = 1) + required_reagents = list( + /datum/reagent/phosphorus = 1, + /datum/reagent/carbon = 1, + /datum/reagent/acetone = 1 // da solvant + ) + + requirement_consumption_modifiers = alist( + /datum/reagent/acetone = alist( + 1 = 20, + 0.5 = 80 + ), + ) /datum/chemical_reaction/meralyne results = list(/datum/reagent/medicine/meralyne = 2) - required_reagents = list(/datum/reagent/medicine/bicaridine = 1, /datum/reagent/medicine/epinephrine = 1, /datum/reagent/acetone = 1) + required_reagents = list( + /datum/reagent/medicine/bicaridine = 1, + /datum/reagent/medicine/epinephrine = 1, + /datum/reagent/acetone = 1 // da solvant + ) inhibitors = list(/datum/reagent/consumable/sugar = 1) // Messes up with inaprovaline /datum/chemical_reaction/meralyne/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added) . = ..() explode_fire_vortex(holder, equilibrium, 2, 2, "overheat", TRUE) +/datum/chemical_reaction/styptic_powder + results = list(/datum/reagent/medicine/styptic_powder = 2) + required_reagents = list( + /datum/reagent/aluminium = 1, + /datum/reagent/hydrogen = 1, + /datum/reagent/oxygen = 1, + /datum/reagent/medicine/bicaridine = 1, + ) + mix_message = "The solution yields an astringent powder." + +// +// Burn chems +// /datum/chemical_reaction/kelotane - results = list(/datum/reagent/medicine/kelotane = 2) - required_reagents = list(/datum/reagent/silicon = 1, /datum/reagent/carbon = 1) + results = list(/datum/reagent/medicine/kelotane = 3) + required_reagents = list(/datum/reagent/water = 1, /datum/reagent/silicon = 1, /datum/reagent/carbon = 1) is_cold_recipe = TRUE optimal_temp = (-50 CELSIUS) - 50 required_temp = -50 CELSIUS @@ -40,16 +63,129 @@ . = ..() explode_fire_vortex(holder, equilibrium, 2, 2, "overheat", TRUE) +/datum/chemical_reaction/silver_sulfadiazine + results = list( + /datum/reagent/medicine/silver_sulfadiazine = 5, + /datum/reagent/silicon = 1, // The silicon from the kelotane gets left over. + ) + // C10H9AgN4O2S is the chemical compound for silver sulf in real life. we conveniently have all of these chemicals, so let's replicate it here + required_reagents = list( + /datum/reagent/medicine/kelotane = 1, // Kelotane brings the carbon + /datum/reagent/ammonia = 1, // Ammonia brings the hydrogen and nitrogen + /datum/reagent/silver = 1, + /datum/reagent/oxygen = 1, + /datum/reagent/sulfur = 1 + ) + mix_message = "A strong and cloying odor begins to bubble from the mixture." + +// +// Tox chems +// +/datum/chemical_reaction/dylovene + results = list(/datum/reagent/medicine/dylovene = 3) + required_reagents = list(/datum/reagent/silicon = 1, /datum/reagent/potassium = 1, /datum/reagent/ammonia = 1) + +/datum/chemical_reaction/ipecac + results = list(/datum/reagent/medicine/ipecac = 2) + required_reagents = list( + /datum/reagent/glycerol = 1, + /datum/reagent/consumable/ethanol = 1, + /datum/reagent/medicine/dylovene = 1 + ) + +/datum/chemical_reaction/charcoal + results = list(/datum/reagent/medicine/activated_charcoal = 3) + required_reagents = list(/datum/reagent/ash = 1, /datum/reagent/consumable/salt = 1) + mix_message = "The mixture yields a fine black powder." + mix_sound = 'sound/effects/fuse.ogg' + +/datum/chemical_reaction/antihol + results = list(/datum/reagent/medicine/antihol = 2) + required_reagents = list(/datum/reagent/consumable/ethanol = 1, /datum/reagent/medicine/activated_charcoal = 1) + mix_message = "A minty and refreshing smell drifts from the effervescent mixture." + +// +// Oxy chems +// /datum/chemical_reaction/dexalin results = list(/datum/reagent/medicine/dexalin = 1) required_reagents = list(/datum/reagent/acetone = 2, /datum/reagent/toxin/plasma = 0.1) inhibitors = list(/datum/reagent/water = 1) // Messes with cryox thermic_constant = 20 // Harder to ignite plasma +// +// Pain chems +// +/datum/chemical_reaction/tramadol + results = list(/datum/reagent/medicine/tramadol = 3) + required_reagents = list( + /datum/reagent/medicine/epinephrine = 1, + /datum/reagent/consumable/ethanol = 1, + /datum/reagent/acetone = 1, + ) + +/datum/chemical_reaction/oxycodone + results = list(/datum/reagent/medicine/tramadol/oxycodone = 1) + required_reagents = list(/datum/reagent/consumable/ethanol = 1, /datum/reagent/medicine/tramadol = 1) + required_catalysts = list(/datum/reagent/toxin/plasma = 5) + +/datum/chemical_reaction/morphine + results = list(/datum/reagent/medicine/morphine = 2) + required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/consumable/ethanol = 1, /datum/reagent/oxygen = 1) + required_temp = 480 + +// +// Organ chems +// +// Brain +/datum/chemical_reaction/alkysine + results = list(/datum/reagent/medicine/alkysine = 2) + required_reagents = list(/datum/reagent/toxin/acid/hydrochloric = 1, /datum/reagent/ammonia = 1, /datum/reagent/medicine/dylovene = 1) + reaction_flags = REACTION_INSTANT + +/datum/chemical_reaction/alkysine/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) + . = ..() + kapuchem_smoke( + holder, + reaction, + list(/datum/reagent/ammonia = round(created_volume, CHEMICAL_VOLUME_ROUNDING)), + clamp(created_volume / 5, 0, 3), // For every 10 units, smoke is 1 tile. + ) + +// General +/datum/chemical_reaction/peridaxon + results = list(/datum/reagent/medicine/peridaxon = 2) + required_reagents = list(/datum/reagent/medicine/bicaridine = 2, /datum/reagent/medicine/clonexadone = 2) + required_catalysts = list(/datum/reagent/toxin/plasma = 5) + +// Eyes +/datum/chemical_reaction/imidazoline + results = list(/datum/reagent/medicine/imidazoline = 2) + required_reagents = list(/datum/reagent/carbon = 1, /datum/reagent/phosphorus = 1, /datum/reagent/medicine/dylovene = 1) + +// Ears +/datum/chemical_reaction/inacusiate + results = list(/datum/reagent/medicine/inacusiate = 2) + required_reagents = list(/datum/reagent/water = 1, /datum/reagent/carbon = 1, /datum/reagent/medicine/dylovene = 1) + mix_message = "The mixture sputters loudly and becomes a light grey color." + required_temp = 300 + optimal_temp = 400 + overheat_temp = 500 + temp_exponent_factor = 0.35 + thermic_constant = 20 + base_reaction_rate = 3 + +// +// Other chems +// /datum/chemical_reaction/tricordrazine results = list(/datum/reagent/medicine/tricordrazine = 5) required_reagents = list(/datum/reagent/medicine/bicaridine = 1, /datum/reagent/medicine/kelotane = 1, /datum/reagent/medicine/dylovene = 1) +/datum/chemical_reaction/inaprovaline + results = list(/datum/reagent/medicine/inaprovaline = 3) + required_reagents = list(/datum/reagent/acetone = 1, /datum/reagent/carbon = 1, /datum/reagent/consumable/sugar = 1, /datum/reagent/phenol = 1) + /datum/chemical_reaction/zedaphen results = list(/datum/reagent/medicine/zedaphen = 3) required_reagents = list( @@ -82,14 +218,6 @@ results = list(/datum/reagent/medicine/hyperzine = 3) required_reagents = list(/datum/reagent/consumable/sugar = 1, /datum/reagent/phosphorus = 1, /datum/reagent/sulfur = 1) -/datum/chemical_reaction/tramadol - results = list(/datum/reagent/medicine/tramadol = 3) - required_reagents = list(/datum/reagent/medicine/epinephrine = 1, /datum/reagent/consumable/ethanol = 1, /datum/reagent/acetone = 1) - -/datum/chemical_reaction/oxycodone - results = list(/datum/reagent/medicine/tramadol/oxycodone = 1) - required_reagents = list(/datum/reagent/consumable/ethanol = 1, /datum/reagent/medicine/tramadol = 1) - required_catalysts = list(/datum/reagent/toxin/plasma = 5) /datum/chemical_reaction/spaceacillin results = list(/datum/reagent/medicine/spaceacillin = 2) @@ -102,24 +230,6 @@ optimal_temp = 80 CELSIUS overheat_temp = 130 CELSIUS -/datum/chemical_reaction/alkysine - results = list(/datum/reagent/medicine/alkysine = 2) - required_reagents = list(/datum/reagent/toxin/acid/hydrochloric = 1, /datum/reagent/ammonia = 1, /datum/reagent/medicine/dylovene = 1) - -/datum/chemical_reaction/morphine - results = list(/datum/reagent/medicine/morphine = 2) - required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/consumable/ethanol = 1, /datum/reagent/oxygen = 1) - required_temp = 480 - -/datum/chemical_reaction/imidazoline - results = list(/datum/reagent/medicine/imidazoline = 2) - required_reagents = list(/datum/reagent/carbon = 1, /datum/reagent/phosphorus = 1, /datum/reagent/medicine/dylovene = 1) - -/datum/chemical_reaction/peridaxon - results = list(/datum/reagent/medicine/peridaxon = 2) - required_reagents = list(/datum/reagent/medicine/bicaridine = 2, /datum/reagent/medicine/clonexadone = 2) - required_catalysts = list(/datum/reagent/toxin/plasma = 5) - /datum/chemical_reaction/leporazine results = list(/datum/reagent/medicine/leporazine = 2) required_reagents = list(/datum/reagent/silicon = 1, /datum/reagent/copper = 1) @@ -142,7 +252,7 @@ overheat_temp = 500 temp_exponent_factor = 0.1 thermic_constant = -0.25 - rate_up_lim = 15 + base_reaction_rate = 15 /datum/chemical_reaction/ephedrine/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, vol_added) default_explode(holder, equilibrium.reacted_vol, 0, 25) @@ -167,70 +277,44 @@ /datum/chemical_reaction/atropine results = list(/datum/reagent/medicine/atropine = 4) - required_reagents = list(/datum/reagent/consumable/ethanol = 1, /datum/reagent/diethylamine = 1, /datum/reagent/acetone = 1, /datum/reagent/phenol = 1, /datum/reagent/toxin/acid = 1) + required_reagents = list( + /datum/reagent/consumable/ethanol = 1, + /datum/reagent/diethylamine = 1, + /datum/reagent/acetone = 1, + /datum/reagent/phenol = 1, + /datum/reagent/toxin/acid = 1 + ) mix_message = "A horrid smell like something died drifts from the mixture." /datum/chemical_reaction/chlorpromazine results = list(/datum/reagent/medicine/chlorpromazine = 2) required_reagents = list(/datum/reagent/cryptobiolin = 1, /datum/reagent/medicine/haloperidol = 1, /datum/reagent/chlorine = 1) -/datum/chemical_reaction/inacusiate - results = list(/datum/reagent/medicine/inacusiate = 2) - required_reagents = list(/datum/reagent/water = 1, /datum/reagent/carbon = 1, /datum/reagent/medicine/dylovene = 1) - mix_message = "The mixture sputters loudly and becomes a light grey color." - required_temp = 300 - optimal_temp = 400 - overheat_temp = 500 - temp_exponent_factor = 0.35 - thermic_constant = 20 - rate_up_lim = 3 - -/datum/chemical_reaction/ipecac - results = list(/datum/reagent/medicine/ipecac = 2) - required_reagents = list(/datum/reagent/glycerol = 1, /datum/reagent/consumable/ethanol = 1, /datum/reagent/medicine/dylovene = 1) - -/datum/chemical_reaction/charcoal - results = list(/datum/reagent/medicine/activated_charcoal = 3) - required_reagents = list(/datum/reagent/ash = 1, /datum/reagent/consumable/salt = 1) - mix_message = "The mixture yields a fine black powder." - mix_sound = 'sound/effects/fuse.ogg' - -/datum/chemical_reaction/antihol - results = list(/datum/reagent/medicine/antihol = 2) - required_reagents = list(/datum/reagent/consumable/ethanol = 1, /datum/reagent/medicine/activated_charcoal = 1) - mix_message = "A minty and refreshing smell drifts from the effervescent mixture." - /datum/chemical_reaction/diphenhydramine results = list(/datum/reagent/medicine/diphenhydramine = 4) // Chlorine is a good enough substitute for bromine right? - required_reagents = list(/datum/reagent/fuel/oil = 1, /datum/reagent/carbon = 1, /datum/reagent/chlorine = 1, /datum/reagent/diethylamine = 1, /datum/reagent/consumable/ethanol = 1) - mix_message = "The mixture fizzes gently." - -/datum/chemical_reaction/styptic_powder - results = list(/datum/reagent/medicine/styptic_powder = 2) - required_reagents = list( - /datum/reagent/aluminium = 1, - /datum/reagent/hydrogen = 1, - /datum/reagent/oxygen = 1, - /datum/reagent/medicine/bicaridine = 1, - ) - mix_message = "The solution yields an astringent powder." - -/datum/chemical_reaction/silver_sulfadiazine - results = list( - /datum/reagent/medicine/silver_sulfadiazine = 5, - /datum/reagent/silicon = 1, // The silicon from the kelotane gets left over. - ) - // C10H9AgN4O2S is the chemical compound for silver sulf in real life. we conveniently have all of these chemicals, so let's replicate it here required_reagents = list( - /datum/reagent/medicine/kelotane = 1, // Kelotane brings the carbon - /datum/reagent/ammonia = 1, // Ammonia brings the hydrogen and nitrogen - /datum/reagent/silver = 1, - /datum/reagent/oxygen = 1, - /datum/reagent/sulfur = 1 + /datum/reagent/fuel/oil = 1, + /datum/reagent/carbon = 1, + /datum/reagent/chlorine = 1, + /datum/reagent/diethylamine = 1, + /datum/reagent/consumable/ethanol = 1 ) - mix_message = "A strong and cloying odor begins to bubble from the mixture." + mix_message = "The mixture fizzes gently." /datum/chemical_reaction/sterilizine results = list(/datum/reagent/space_cleaner/sterilizine = 3) required_reagents = list(/datum/reagent/consumable/ethanol = 1, /datum/reagent/medicine/dylovene = 1, /datum/reagent/toxin/acid/hydrochloric = 1) + +/datum/chemical_reaction/shmowder + results = list(/datum/reagent/medicine/shmowder = 1) + required_reagents = list( + /datum/reagent/medicine/bicaridine = 1, + /datum/reagent/medicine/meralyne = 1, + /datum/reagent/medicine/kelotane = 1, + /datum/reagent/medicine/dermaline = 1, + /datum/reagent/medicine/dylovene = 1, + /datum/reagent/medicine/dexalin = 1, + /datum/reagent/medicine/saline_glucose = 1, + /datum/reagent/medicine/peridaxon = 1 + ) diff --git a/code/modules/reagents/chemistry/recipes/other.dm b/code/modules/reagents/chemistry/recipes/other_recipes.dm similarity index 95% rename from code/modules/reagents/chemistry/recipes/other.dm rename to code/modules/reagents/chemistry/recipes/other_recipes.dm index 2dfa213eadf8..18650ae293e4 100644 --- a/code/modules/reagents/chemistry/recipes/other.dm +++ b/code/modules/reagents/chemistry/recipes/other_recipes.dm @@ -138,7 +138,7 @@ overheat_temp = 575 temp_exponent_factor = 0.2 thermic_constant = 35 //gives a bonus 15C wiggle room - rate_up_lim = 25 //Give a chance to pull back + base_reaction_rate = 25 //Give a chance to pull back /datum/chemical_reaction/nitrous_oxide/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added) return //This is empty because the explosion reaction will occur instead (see pyrotechnics.dm). This is just here to update the lookup ui. @@ -340,12 +340,31 @@ /datum/chemical_reaction/ammonia results = list(/datum/reagent/ammonia = 3) required_reagents = list(/datum/reagent/hydrogen = 3, /datum/reagent/nitrogen = 1) + reaction_flags = REACTION_INSTANT + +/datum/chemical_reaction/ammonia/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) + . = ..() + kapuchem_smoke( + holder, + reaction, + list(/datum/reagent/ammonia = round(created_volume * 3 * 0.5, CHEMICAL_VOLUME_ROUNDING)), + clamp(created_volume / 3, 0, 3), // For every 9 units, smoke is 1 tile. + ) /datum/chemical_reaction/diethylamine results = list(/datum/reagent/diethylamine = 2) required_reagents = list (/datum/reagent/ammonia = 1, /datum/reagent/consumable/ethanol = 1) + reaction_flags = REACTION_INSTANT +/datum/chemical_reaction/diethylamine/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) + . = ..() + kapuchem_smoke( + holder, + reaction, + list(/datum/reagent/diethylamine = round(created_volume * 2 * 0.5, CHEMICAL_VOLUME_ROUNDING)), + clamp(created_volume / 4, 0, 3), // For every 8 units, smoke is 1 tile. + ) /datum/chemical_reaction/plantbgone results = list(/datum/reagent/toxin/plantbgone = 5) @@ -355,6 +374,16 @@ /datum/chemical_reaction/weedkiller results = list(/datum/reagent/toxin/plantbgone/weedkiller = 5) required_reagents = list(/datum/reagent/toxin = 1, /datum/reagent/ammonia = 4) + reaction_flags = REACTION_INSTANT + +/datum/chemical_reaction/weedkiller/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) + . = ..() + kapuchem_smoke( + holder, + reaction, + list(/datum/reagent/toxin/plantbgone/weedkiller = round(created_volume * 5 * 0.5, CHEMICAL_VOLUME_ROUNDING)), + clamp(created_volume / 2, 0, 3), // For every 10 units, smoke is 1 tile. + ) /datum/chemical_reaction/pestkiller results = list(/datum/reagent/toxin/pestkiller = 5) @@ -362,21 +391,6 @@ //////////////////////////////////// Other goon stuff /////////////////////////////////////////// - -/datum/chemical_reaction/acetone - results = list(/datum/reagent/acetone = 3) - required_reagents = list(/datum/reagent/fuel/oil = 1, /datum/reagent/fuel = 1, /datum/reagent/oxygen = 1) - -/datum/chemical_reaction/oil - results = list(/datum/reagent/fuel/oil = 3) - required_reagents = list(/datum/reagent/fuel = 1, /datum/reagent/carbon = 1, /datum/reagent/hydrogen = 1) - - -/datum/chemical_reaction/phenol - results = list(/datum/reagent/phenol = 3) - required_reagents = list(/datum/reagent/water = 1, /datum/reagent/chlorine = 1, /datum/reagent/fuel/oil = 1) - - /datum/chemical_reaction/ash results = list(/datum/reagent/ash = 1) required_reagents = list(/datum/reagent/fuel/oil = 1) @@ -585,7 +599,7 @@ optimal_temp = 200 overheat_temp = 0 thermic_constant = 0 - rate_up_lim = 50 + base_reaction_rate = 50 mix_message = "The solution freezes up into ice!" reaction_flags = REACTION_COMPETITIVE @@ -596,7 +610,7 @@ optimal_temp = 350 overheat_temp = NO_OVERHEAT thermic_constant = 0 - rate_up_lim = 50 + base_reaction_rate = 50 mix_message = "The ice melts back into water!" diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics_recipes.dm similarity index 100% rename from code/modules/reagents/chemistry/recipes/pyrotechnics.dm rename to code/modules/reagents/chemistry/recipes/pyrotechnics_recipes.dm diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts_recipes.dm similarity index 100% rename from code/modules/reagents/chemistry/recipes/slime_extracts.dm rename to code/modules/reagents/chemistry/recipes/slime_extracts_recipes.dm diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special_recipes.dm similarity index 100% rename from code/modules/reagents/chemistry/recipes/special.dm rename to code/modules/reagents/chemistry/recipes/special_recipes.dm diff --git a/code/modules/reagents/chemistry/recipes/tinctures.dm b/code/modules/reagents/chemistry/recipes/tincture_recipes.dm similarity index 100% rename from code/modules/reagents/chemistry/recipes/tinctures.dm rename to code/modules/reagents/chemistry/recipes/tincture_recipes.dm diff --git a/code/modules/reagents/chemistry/recipes/toxins.dm b/code/modules/reagents/chemistry/recipes/toxin_recipes.dm similarity index 97% rename from code/modules/reagents/chemistry/recipes/toxins.dm rename to code/modules/reagents/chemistry/recipes/toxin_recipes.dm index 3f05c1023bc5..497328512b87 100644 --- a/code/modules/reagents/chemistry/recipes/toxins.dm +++ b/code/modules/reagents/chemistry/recipes/toxin_recipes.dm @@ -7,7 +7,7 @@ overheat_temp = 900 temp_exponent_factor = 2.5 thermic_constant = 150 - rate_up_lim = 15 + base_reaction_rate = 15 /datum/chemical_reaction/zombiepowder results = list(/datum/reagent/toxin/zombiepowder = 2) @@ -35,4 +35,4 @@ overheat_temp = 900 temp_exponent_factor = 1.6 thermic_constant = 250 - rate_up_lim = 10 + base_reaction_rate = 10 diff --git a/code/modules/reagents/condenser.dm b/code/modules/reagents/condenser.dm new file mode 100644 index 000000000000..be7787d8f7b8 --- /dev/null +++ b/code/modules/reagents/condenser.dm @@ -0,0 +1,132 @@ +/obj/item/reagent_containers/cup/condenser + name = "chemical condenser" + desc = "TODO" + + icon = 'goon/icons/obj/condenser.dmi' + icon_state = "condenser" + inhand_icon_state = "beaker" + worn_icon_state = "beaker" + + fill_icon_file = 'goon/icons/obj/condenser.dmi' + fill_icon_state = "f-condenser" + fill_icon_thresholds = list(0, 1, 25, 50, 75, 100) + + volume = 60 + + var/tmp/datum/looping_sound/boiling/loop + + /// Cup attached to the assembly + var/tmp/obj/item/reagent_containers/cup/beaker/output + + /// Holds the vaporized reagent so we can cool it down before passing it onto the output. + var/tmp/datum/reagents/temp_holder + +/obj/item/reagent_containers/cup/condenser/Initialize(mapload, vol) + . = ..() + temp_holder = new(volume) + loop = new(src) + register_context() + START_PROCESSING(SSfastprocess, src) + +/obj/item/reagent_containers/cup/condenser/Destroy(force) + STOP_PROCESSING(SSfastprocess, src) + QDEL_NULL(output) + QDEL_NULL(temp_holder) + QDEL_NULL(loop) + return ..() + +/obj/item/reagent_containers/cup/condenser/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + if(istype(held_item, /obj/item/reagent_containers/cup/beaker)) + context[SCREENTIP_CONTEXT_RMB] = "Attach Beaker" + . = CONTEXTUAL_SCREENTIP_SET + + else if(isnull(held_item) && output) + context[SCREENTIP_CONTEXT_LMB] = "Remove Beaker" + . = CONTEXTUAL_SCREENTIP_SET + +/obj/item/reagent_containers/cup/condenser/item_interaction_secondary(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/reagent_containers/cup/beaker)) + return ..() + + if(output) + to_chat(user, span_warning("[src]'s output already has a container.")) + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + set_output(tool) + visible_message("[user] attaches [tool] to [src].") + return ITEM_INTERACT_SUCCESS + +/obj/item/reagent_containers/cup/condenser/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + + if(!output) + return + + if(!user.pickup_item(output)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + output.do_pickup_animation(user, get_turf(src)) + set_output(null) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/item/reagent_containers/cup/condenser/update_overlays() + . = ..() + if(!output) + return + + var/mutable_appearance/output_overlay = new(output) + output_overlay.plane = FLOAT_PLANE + output_overlay.layer = FLOAT_LAYER + output_overlay.pixel_x = 11 + output_overlay.pixel_y = output.condenser_offset_y + . += output_overlay + + . += image(icon, "condenser-pipe") + +/obj/item/reagent_containers/cup/condenser/proc/set_output(obj/item/reagent_containers/cup/beaker/new_output) + if(output) + UnregisterSignal(output, COMSIG_PARENT_QDELETING) + + output = new_output + + if(!output) + update_appearance(UPDATE_OVERLAYS) + return + + RegisterSignal(output, COMSIG_PARENT_QDELETING, PROC_REF(output_deleted)) + update_appearance(UPDATE_OVERLAYS) + +/obj/item/reagent_containers/cup/condenser/proc/output_deleted(datum/source) + SIGNAL_HANDLER + set_output(null) + +/obj/item/reagent_containers/cup/condenser/process(delta_time) + var/reagents_moved = FALSE + for(var/datum/reagent/R as anything in reagents.reagent_list) + if(isnull(R.boiling_point) || reagents.chem_temp < R.boiling_point) // Solids can sublimate, theoretically. + continue + + reagents_moved = TRUE + var/transfer_rate = R.boil_off_rate * delta_time + + if(!output || (R.reagent_state == GAS)) + reagents.remove_reagent(R.type, transfer_rate) + continue + + reagents.trans_id_to(temp_holder, R.type, transfer_rate, no_react = TRUE) + temp_holder.set_temperature(R.dew_point) + temp_holder.trans_to(output, temp_holder.maximum_volume, no_react = TRUE) + + if(reagents_moved) + loop.start() + reagents.handle_reactions() + output?.reagents.handle_reactions() + else + loop.stop() + diff --git a/code/modules/reagents/hotplate.dm b/code/modules/reagents/hotplate.dm new file mode 100644 index 000000000000..d73656ec15ed --- /dev/null +++ b/code/modules/reagents/hotplate.dm @@ -0,0 +1,107 @@ +/obj/item/hotplate + name = "hot plate" + desc = "TODO" + icon = 'icons/obj/chemical.dmi' + icon_state = "hotplate" + + w_class = WEIGHT_CLASS_NORMAL + + /// Thermal energy coeff + var/heater_coefficient = 0.5 + /// At max ramp-up, multiply the thermal energy by this. + var/heat_rampup_temp = 10 + /// How many seconds it takes to reach max heat ramp-up. + var/heat_rampup_time = 15 + var/tmp/current_rampup = 0 + + var/tmp/on = FALSE + var/tmp/obj/item/reagent_containers/cup/container + +/obj/item/hotplate/Destroy(force) + QDEL_NULL(container) + if(on) + toggle_on() + return ..() + +/obj/item/hotplate/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + + toggle_on() + visible_message(span_notice("[user] turns [src] [on ? "on" : "off"].")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/item/hotplate/IsContainedAtomAccessible(atom/contained, atom/movable/user) + return contained == container + +/obj/item/hotplate/equipped(mob/user, slot, initial) + . = ..() + if(on) + toggle_on() + +/obj/item/hotplate/update_overlays() + . = ..() + if(on) + . += image(icon, "hotplate-on") + . += emissive_appearance(icon, "hotplate-on", alpha = 100) + +/obj/item/hotplate/proc/toggle_on() + on = !on + if(on) + START_PROCESSING(SSfastprocess, src) + else + STOP_PROCESSING(SSfastprocess, src) + current_rampup = 0 + + update_appearance(UPDATE_OVERLAYS) + +/obj/item/hotplate/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/reagent_containers/cup)) + return NONE + + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + set_container(tool) + return ITEM_INTERACT_SUCCESS + +/obj/item/hotplate/proc/set_container(obj/item/reagent_containers/cup/new_container) + if(container) + UnregisterSignal(container, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) + remove_viscontents(container) + container.update_offsets() + + container = new_container + + if(!container) + return + + RegisterSignal(container, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED), PROC_REF(container_moved_or_deleted)) + add_viscontents(container) + container.pixel_y = 4 + +/obj/item/hotplate/get_temperature() + if(!on) + return 0 + + // 80% to 110% + var/random_mult = rand(8,11) * 0.1 + var/rampup_coeff = (current_rampup / heat_rampup_time) * heat_rampup_temp + return SPECIFIC_HEAT_DEFAULT * rampup_coeff * heater_coefficient * random_mult + +/obj/item/hotplate/process(delta_time) + if(!container) + return + + if(container.reagents.chem_temp >= 800) + return + + var/thermal_adjustment = get_temperature() * delta_time * container.reagents.total_volume + + container.reagents.adjust_thermal_energy(thermal_adjustment) + current_rampup = clamp(current_rampup + delta_time, 0, heat_rampup_time) + +/obj/item/hotplate/proc/container_moved_or_deleted(datum/source) + SIGNAL_HANDLER + set_container(null) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index bfc1cd14118a..865ea66d4ed3 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -7,6 +7,7 @@ has_combat_mode_interaction = TRUE + var/fill_icon_file = 'icons/obj/reagentfillings.dmi' var/amount_per_transfer_from_this = 5 var/list/possible_transfer_amounts = list(5,10,15,20,25,30) /// Where we are in the possible transfer amount list. @@ -227,7 +228,7 @@ return var/fill_name = fill_icon_state? fill_icon_state : icon_state - var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[fill_name][fill_icon_thresholds[1]]") + var/mutable_appearance/filling = mutable_appearance(fill_icon_file, "[fill_name][fill_icon_thresholds[1]]") var/percent = round((reagents.total_volume / volume) * 100) for(var/i in 1 to fill_icon_thresholds.len) diff --git a/code/modules/reagents/reagent_containers/cups/_cup.dm b/code/modules/reagents/reagent_containers/cups/_cup.dm index c22c108d0446..59a0a832c8d8 100644 --- a/code/modules/reagents/reagent_containers/cups/_cup.dm +++ b/code/modules/reagents/reagent_containers/cups/_cup.dm @@ -260,13 +260,18 @@ TYPEINFO_DEF(/obj/item/reagent_containers/cup/beaker) name = "beaker" desc = "A beaker. It can hold up to 60 units." icon = 'icons/obj/chemical.dmi' + icon_state = "beaker" inhand_icon_state = "beaker" worn_icon_state = "beaker" + fill_icon_thresholds = list(0, 1, 20, 40, 60, 80, 100) possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 60) volume = 60 + // Used for condenser rendering. + var/condenser_offset_y = -3 + /obj/item/reagent_containers/cup/beaker/Initialize(mapload) . = ..() update_appearance() diff --git a/daedalus.dme b/daedalus.dme index b091982b91e2..0d6d46cd3854 100644 --- a/daedalus.dme +++ b/daedalus.dme @@ -4330,6 +4330,8 @@ #include "code\modules\projectiles\projectile\special\temperature.dm" #include "code\modules\projectiles\projectile\special\wormhole.dm" #include "code\modules\reagents\chem_splash.dm" +#include "code\modules\reagents\condenser.dm" +#include "code\modules\reagents\hotplate.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm" #include "code\modules\reagents\chemistry\chem_wiki_render.dm" @@ -4365,15 +4367,15 @@ #include "code\modules\reagents\chemistry\reagents\pyrotechnic_reagents.dm" #include "code\modules\reagents\chemistry\reagents\tincture_reagents.dm" #include "code\modules\reagents\chemistry\reagents\toxin_reagents.dm" -#include "code\modules\reagents\chemistry\recipes\drugs.dm" -#include "code\modules\reagents\chemistry\recipes\gateway.dm" -#include "code\modules\reagents\chemistry\recipes\medicine.dm" -#include "code\modules\reagents\chemistry\recipes\other.dm" -#include "code\modules\reagents\chemistry\recipes\pyrotechnics.dm" -#include "code\modules\reagents\chemistry\recipes\slime_extracts.dm" -#include "code\modules\reagents\chemistry\recipes\special.dm" -#include "code\modules\reagents\chemistry\recipes\tinctures.dm" -#include "code\modules\reagents\chemistry\recipes\toxins.dm" +#include "code\modules\reagents\chemistry\recipes\drugs_recipes.dm" +#include "code\modules\reagents\chemistry\recipes\gateway_recipes.dm" +#include "code\modules\reagents\chemistry\recipes\medicine_recipes.dm" +#include "code\modules\reagents\chemistry\recipes\other_recipes.dm" +#include "code\modules\reagents\chemistry\recipes\pyrotechnics_recipes.dm" +#include "code\modules\reagents\chemistry\recipes\slime_extracts_recipes.dm" +#include "code\modules\reagents\chemistry\recipes\special_recipes.dm" +#include "code\modules\reagents\chemistry\recipes\tincture_recipes.dm" +#include "code\modules\reagents\chemistry\recipes\toxin_recipes.dm" #include "code\modules\reagents\reagent_containers\blood_pack.dm" #include "code\modules\reagents\reagent_containers\borghydro.dm" #include "code\modules\reagents\reagent_containers\bottle.dm" diff --git a/goon/icons/obj/condenser.dmi b/goon/icons/obj/condenser.dmi new file mode 100644 index 000000000000..20e1a5097ec8 Binary files /dev/null and b/goon/icons/obj/condenser.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 572f28ec6130..20ba05f65292 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/tgui/packages/tgui/interfaces/ChemMaster.jsx b/tgui/packages/tgui/interfaces/ChemMaster.tsx similarity index 87% rename from tgui/packages/tgui/interfaces/ChemMaster.jsx rename to tgui/packages/tgui/interfaces/ChemMaster.tsx index b3c8e3eeafba..36cfaefe2182 100644 --- a/tgui/packages/tgui/interfaces/ChemMaster.jsx +++ b/tgui/packages/tgui/interfaces/ChemMaster.tsx @@ -1,3 +1,5 @@ +import { BooleanLike } from 'common/react'; + import { useBackend, useSharedState } from '../backend'; import { AnimatedNumber, @@ -11,21 +13,59 @@ import { } from '../components'; import { Window } from '../layouts'; +type AnalysisVariables = { + addicD: string; + color: string; + description: string; + metaRate: string; + name: string; + overD: string; + state: string; +}; + +type ChemMasterData = { + analyzeVars: AnalysisVariables; + screen: string; +}; + export const ChemMaster = (props) => { - const { data } = useBackend(); - const { screen } = data; + const { data } = useBackend(); + const { analyzeVars, screen } = data; return ( - {(screen === 'analyze' && ) || } + {(screen === 'analyze' && ( + + )) || } ); }; +type Chemical = { + id: string; + name: string; + volume: number; +}; + +type ChemMasterContentData = { + analyzeVars: AnalysisVariables; + beakerContents: Chemical[]; + beakerCurrentVolume?: number; + beakerMaxVolume?: number; + bufferContents: Chemical[]; + isBeakerLoaded: BooleanLike; + isPillBottleLoaded: BooleanLike; + mode: BooleanLike; + pillBottleCurrentAmount: number; + pillBottleMaxAmount: number; + screen: string; +}; + const ChemMasterContent = (props) => { - const { act, data } = useBackend(); + const { act, data } = useBackend(); const { + analyzeVars, screen, beakerContents = [], bufferContents = [], @@ -37,7 +77,7 @@ const ChemMasterContent = (props) => { pillBottleMaxAmount, } = data; if (screen === 'analyze') { - return ; + return ; } return ( <> @@ -234,14 +274,39 @@ const PackagingControlsItem = (props) => { ); }; +type CondiStyle = { + className: string; + id: string; + title: string; +}; + +type PillStyle = { + className: string; + id: string; +}; + +type PatchStyle = { + class_name: string; + style: string; +}; + +type PackagingData = { + autoCondiStyle: string; + chosenCondiStyle: string; + chosenPillStyle: string; + condi: BooleanLike; + condiStyles: CondiStyle[]; + patch_style: string; + patch_styles: PatchStyle[]; + pillStyles: PillStyle[]; +}; + const PackagingControls = (props) => { - const { act, data } = useBackend(); + const { act, data } = useBackend(); const [pillAmount, setPillAmount] = useSharedState('pillAmount', 1); const [patchAmount, setPatchAmount] = useSharedState('patchAmount', 1); const [bottleAmount, setBottleAmount] = useSharedState('bottleAmount', 1); - // PARIAH EDIT ADDITION const [vialAmount, setVialAmount] = useSharedState('vialAmount', 1); - // PARIAH EDIT END const [packAmount, setPackAmount] = useSharedState('packAmount', 1); const { condi, @@ -421,9 +486,13 @@ const PackagingControls = (props) => { ); }; -const AnalysisResults = (props) => { +type AnalysisProps = { + analyzeVars: AnalysisVariables; +}; + +const AnalysisResults = (props: AnalysisProps) => { const { act, data } = useBackend(); - const { analyzeVars } = data; + const { analyzeVars } = props; return (
{ {analyzeVars.name} {analyzeVars.state} - {analyzeVars.ph} {analyzeVars.color}