mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-28 07:38:05 +01:00
[NO GBP] Some more reaction patches (#95660)
## About The Pull Request - Fixes #95651. Catalysts no longer get consumed - Removed `REACTION_CLEAR_IMPURE` flag as it is now redundant with `REACTION_CLEAR_INVERSE` - Removed `REACTION_CLEAR_INSTANT` flag as it was never used - Other minor nitpicks
This commit is contained in:
@@ -137,22 +137,18 @@
|
||||
#define REAGENT_SPAWN_ALL_RANDOM_SPAWNS ALL
|
||||
|
||||
//Chemical reaction flags, for determining reaction specialties
|
||||
///Convert into impure/pure on reaction completion
|
||||
#define REACTION_CLEAR_IMPURE (1<<0)
|
||||
///Convert into inverse on reaction completion when purity is low enough
|
||||
#define REACTION_CLEAR_INVERSE (1<<1)
|
||||
///Clear converted chems retain their purities/inverted purities. Requires 1 or both of the above.
|
||||
#define REACTION_CLEAR_RETAIN (1<<2)
|
||||
#define REACTION_CLEAR_INVERSE (1<<0)
|
||||
///Used to create instant reactions
|
||||
#define REACTION_INSTANT (1<<3)
|
||||
#define REACTION_INSTANT (1<<1)
|
||||
///Used to force reactions to create a specific amount of heat per 1u created. So if thermic_constant = 5, for 1u of reagent produced, the heat will be forced up arbitarily by 5 irresepective of other reagents. If you use this, keep in mind standard thermic_constant values are 100x what it should be with this enabled.
|
||||
#define REACTION_HEAT_ARBITARY (1<<4)
|
||||
#define REACTION_HEAT_ARBITARY (1<<2)
|
||||
///Used to bypass the chem_master transfer block (This is needed for competitive reactions unless you have an end state programmed). More stuff might be added later. When defining this, please add in the comments the associated reactions that it competes with
|
||||
#define REACTION_COMPETITIVE (1<<5)
|
||||
#define REACTION_COMPETITIVE (1<<3)
|
||||
///Used to force pH changes to be constant regardless of volume
|
||||
#define REACTION_PH_VOL_CONSTANT (1<<6)
|
||||
#define REACTION_PH_VOL_CONSTANT (1<<4)
|
||||
///If a reaction will generate its impure/inverse reagents in the middle of a reaction, as apposed to being determined on ingestion/on reaction completion
|
||||
#define REACTION_REAL_TIME_SPLIT (1<<7)
|
||||
#define REACTION_REAL_TIME_SPLIT (1<<5)
|
||||
|
||||
///Used for overheat_temp - This sets the overheat so high it effectively has no overheat temperature.
|
||||
#define NO_OVERHEAT 99999
|
||||
|
||||
@@ -494,9 +494,7 @@ DEFINE_BITFIELD(chemical_flags, list(
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(reaction_flags, list(
|
||||
"REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE,
|
||||
"REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE,
|
||||
"REACTION_CLEAR_RETAIN" = REACTION_CLEAR_RETAIN,
|
||||
"REACTION_INSTANT" = REACTION_INSTANT,
|
||||
"REACTION_HEAT_ARBITARY" = REACTION_HEAT_ARBITARY,
|
||||
"REACTION_COMPETITIVE" = REACTION_COMPETITIVE,
|
||||
|
||||
@@ -67,7 +67,7 @@ Lets go over the reaction vars below. These can be edited and set on a per chemi
|
||||
var/H_ion_release = 0.01 // pH change per 1u reaction
|
||||
var/rate_up_lim = 20 // Optimal/max rate possible if all conditions are perfect
|
||||
var/purity_min = 0.15 // If purity is below 0.15, it calls OverlyImpure() too. Set to 0 to disable this.
|
||||
var/reaction_flags // bitflags for clear conversions; REACTION_CLEAR_IMPURE, REACTION_CLEAR_INVERSE, REACTION_CLEAR_RETAIN, REACTION_INSTANT
|
||||
var/reaction_flags // bitflags for clear conversions;
|
||||
```
|
||||
|
||||
### How temperature ranges are set and how reaction rate is determined
|
||||
@@ -129,9 +129,7 @@ The thermic_constant is how much the temperature changes per u created, so for 1
|
||||
Reaction_flags can be used to set these defines:
|
||||
|
||||
```dm
|
||||
#define REACTION_CLEAR_IMPURE //Convert into impure/pure on reaction completion in the datum/reagents holder instead of on consumption
|
||||
#define REACTION_CLEAR_INVERSE //Convert into inverse on reaction completion when purity is low enough in the datum/reagents holder instead of on consumption
|
||||
#define REACTION_CLEAR_RETAIN //Clear converted chems retain their purities/inverted purities. Requires 1 or both of the above. This is so that it can split again after splitting from a reaction (i.e. if your impure_chem or inverse_chem has its own impure_chem/inverse_chem and you want it to split again on consumption).
|
||||
#define REACTION_INSTANT //Used to create instant reactions
|
||||
|
||||
/datum/chemical_reaction
|
||||
@@ -176,10 +174,9 @@ The new vars that are introduced are below:
|
||||
- `pH` is the innate pH of the reagent and is used to calculate the pH of a reagents datum on addition/removal. This does not change and is a reference value. The reagents datum pH changes.
|
||||
- `purity` is the INTERNAL value for splitting. This is set to 1 after splitting so that it doesn't infinite split
|
||||
- `creation_purity` is the purity of the reagent on creation. This won't change. If you want to write code that checks the purity in any of the methods, use this.
|
||||
- `impure_chem` is the datum type that is created provided that its `creation_purity` is above the `inverse_chem_val`. When the reagent is consumed it will split into this OR if the associated `datum/chemical_recipe` has a REACTION_CLEAR_IMPURE flag it will split at the end of the reaction in the `datum/reagents` holder
|
||||
- `impure_chem` is the datum type that is created provided that its `creation_purity` is above the `inverse_chem_val`. When the reagent is consumed it will split into this OR if the associated `datum/chemical_recipe` has a REACTION_CLEAR_INVERSE flag it will split at the end of the reaction in the `datum/reagents` holder
|
||||
- `inverse_chem_val` if a reagent's purity is below this value it will 100% convert into `inverse_chem`. If above it will split into `impure_chem`. See the note on purity effects above
|
||||
- `inverse_chem` is the datum type that is created provided that its `creation_purity` is below the `inverse_chem_val`. When the reagent is consumed it will 100% convert into this OR if the associated `datum/chemical_recipe` has a REACTION_CLEAR_INVERSE flag it will 100% convert at the end of the reaction in the `datum/reagents` holder
|
||||
- `failed_chem` is the chem that the product is 100% converted into if the purity is below the associated `datum/chemical_recipies`' `PurityMin` AT THE END OF A REACTION.
|
||||
|
||||
When writing any reagent code ALWAYS use creation_purity. Purity is kept for internal mechanics only and won’t reflect the purity on creation.
|
||||
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
force_stop_reacting() //Force anything that is trying to to stop
|
||||
return FALSE //Yup, no reactions here. No siree.
|
||||
|
||||
if(is_reacting)//Prevent wasteful calculations
|
||||
if(!(datum_flags & DF_ISPROCESSING))//If we're reacting - but not processing (i.e. we've transferred)
|
||||
START_PROCESSING(SSreagents, src)
|
||||
|
||||
#ifndef UNIT_TESTS
|
||||
// We assert that reagents will not need to react before the map is fully loaded
|
||||
// This is the best I can do, sorry :(
|
||||
@@ -37,7 +33,7 @@
|
||||
//is this reaction already going on?
|
||||
var/next_reaction = FALSE
|
||||
for(var/datum/equilibrium/E_exist as anything in reaction_list)
|
||||
if(ispath(E_exist.reaction.type, reaction.type)) //Don't add duplicates
|
||||
if(E_exist.reaction == reaction) //Don't add duplicates
|
||||
next_reaction = TRUE
|
||||
break
|
||||
if(next_reaction)
|
||||
@@ -48,9 +44,7 @@
|
||||
if(!(reaction.reaction_flags & REACTION_INSTANT))
|
||||
granularity = CHEMICAL_QUANTISATION_LEVEL
|
||||
var/present_volume = 0
|
||||
var/list/datum/reagent/requirements = reaction.required_reagents
|
||||
if(length(reaction.required_catalysts))
|
||||
requirements |= reaction.required_catalysts
|
||||
var/list/datum/reagent/requirements = reaction.required_reagents | reaction.required_catalysts
|
||||
for(var/datum/reagent/requirement as anything in requirements)
|
||||
present_volume = cached_reagents[requirement]
|
||||
if(!present_volume)
|
||||
@@ -101,7 +95,7 @@
|
||||
else
|
||||
//Adding is done in new(), deletion is in qdel
|
||||
is_reacting = TRUE//Prevent any on_reaction() procs from infinite looping
|
||||
equilibrium.reaction.on_reaction(src, equilibrium, equilibrium.multiplier)
|
||||
reaction.on_reaction(src, equilibrium, equilibrium.multiplier)
|
||||
equilibrium.react_timestep(1)//Get an initial
|
||||
|
||||
if(LAZYLEN(reaction_list))
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
*/
|
||||
/datum/chemical_reaction
|
||||
///Results of the chemical reactions
|
||||
var/list/results = new/list()
|
||||
var/list/results = list()
|
||||
///Required chemicals that are USED in the reaction
|
||||
var/list/required_reagents = new/list()
|
||||
var/list/required_reagents = list()
|
||||
///Required chemicals that must be present in the container but are not USED.
|
||||
var/list/required_catalysts = new/list()
|
||||
var/list/required_catalysts = list()
|
||||
|
||||
/// If required_container will check for the exact type, or will also accept subtypes
|
||||
var/required_container_accepts_subtypes = FALSE
|
||||
@@ -52,7 +52,7 @@
|
||||
var/rate_up_lim = 30
|
||||
/// If purity is below 0.15, it calls OverlyImpure() too. Set to 0 to disable this.
|
||||
var/purity_min = 0.15
|
||||
/// bitflags for clear conversions; REACTION_CLEAR_IMPURE, REACTION_CLEAR_INVERSE, REACTION_CLEAR_RETAIN, REACTION_INSTANT
|
||||
/// bitflags for clear conversions; see code/__DEFINES/reagents.dm
|
||||
var/reaction_flags = NONE
|
||||
///Tagging vars
|
||||
///A bitflag var for tagging reagents for the reagent loopup functon
|
||||
@@ -102,11 +102,7 @@
|
||||
return
|
||||
|
||||
/**
|
||||
* Stuff that occurs at the end of a reaction. This will proc if the beaker is forced to stop and start again (say for sudden temperature changes).
|
||||
* Only procs at the END of reaction
|
||||
* If reaction_flags & REACTION_INSTANT then this isn't called
|
||||
* if reaction_flags REACTION_CLEAR_IMPURE then the impurity chem is handled here, producing the result in the beaker instead of in a mob
|
||||
* Likewise for REACTION_CLEAR_INVERSE the inverse chem is produced at the end of the reaction in the beaker
|
||||
* Stuff that should happen at the end of the reaction. Presently only REACTION_CLEAR_INVERSE is respected here
|
||||
* You should be calling ..() if you're writing a child function of this proc otherwise purity methods won't work correctly
|
||||
*
|
||||
* Proc where the additional magic happens.
|
||||
@@ -116,39 +112,24 @@
|
||||
* * react_volume - volume created across the whole reaction
|
||||
*/
|
||||
/datum/chemical_reaction/proc/reaction_finish(datum/reagents/holder, datum/equilibrium/reaction, react_vol)
|
||||
//failed_chem handler
|
||||
var/cached_temp = holder.chem_temp
|
||||
for(var/id in results)
|
||||
var/datum/reagent/reagent = holder.has_reagent(id)
|
||||
if(!reagent)
|
||||
continue
|
||||
//Split like this so it's easier for people to edit this function in a child
|
||||
reaction_clear_check(reagent, holder)
|
||||
holder.chem_temp = cached_temp
|
||||
|
||||
/**
|
||||
* REACTION_CLEAR handler
|
||||
* If the reaction has the REACTION_CLEAR flag, then it will split using purity methods in the beaker instead
|
||||
*
|
||||
* Arguments:
|
||||
* * reagent - the target reagent to convert
|
||||
*/
|
||||
/datum/chemical_reaction/proc/reaction_clear_check(datum/reagent/reagent, datum/reagents/holder)
|
||||
if(!reagent)//Failures can delete R
|
||||
if(!(reaction_flags & REACTION_CLEAR_INVERSE))
|
||||
return
|
||||
if(reaction_flags & (REACTION_CLEAR_IMPURE | REACTION_CLEAR_INVERSE))
|
||||
if(reagent.purity == 1)
|
||||
return
|
||||
|
||||
if((reaction_flags & REACTION_CLEAR_INVERSE) && reagent.inverse_chem)
|
||||
if(reagent.inverse_chem_val > reagent.purity)
|
||||
var/inverse_chem = reagent.inverse_chem
|
||||
var/cached_volume = reagent.volume
|
||||
var/cached_purity = reagent.get_inverse_purity(reagent.purity)
|
||||
reagent.volume = 0
|
||||
holder.update_total()
|
||||
holder.add_reagent(inverse_chem, cached_volume, FALSE, added_purity = cached_purity)
|
||||
return
|
||||
var/list/inverse_data = list()
|
||||
for(var/datum/reagent/reagent as anything in holder.reagent_list)
|
||||
if(!results[reagent.type] || !reagent.inverse_chem || reagent.purity == 1 || reagent.purity > reagent.inverse_chem_val)
|
||||
continue
|
||||
|
||||
inverse_data += reagent.inverse_chem
|
||||
inverse_data += reagent.volume
|
||||
inverse_data += reagent.get_inverse_purity(reagent.purity)
|
||||
reagent.volume = 0
|
||||
|
||||
holder.update_total()
|
||||
|
||||
var/cached_temp = holder.chem_temp
|
||||
while(inverse_data.len)
|
||||
holder.add_reagent(popleft(inverse_data), popleft(inverse_data), reagtemp = cached_temp, added_purity = popleft(inverse_data))
|
||||
|
||||
/**
|
||||
* Occurs when a reation is overheated (i.e. past its overheatTemp)
|
||||
@@ -163,10 +144,9 @@
|
||||
* * step_volume_added - how much product (across all products) was added for this single step
|
||||
*/
|
||||
/datum/chemical_reaction/proc/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added)
|
||||
for(var/id in results)
|
||||
var/datum/reagent/reagent = holder.has_reagent(id)
|
||||
if(!reagent)
|
||||
return
|
||||
for(var/datum/reagent/reagent as anything in holder.reagent_list)
|
||||
if(!results[reagent.type])
|
||||
continue
|
||||
reagent.volume *= 0.98 //Slowly lower yield per tick
|
||||
holder.update_total()
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@
|
||||
H_ion_release = -0.25
|
||||
rate_up_lim = 15
|
||||
purity_min = 0.3
|
||||
reaction_flags = REACTION_CLEAR_IMPURE
|
||||
reaction_flags = REACTION_CLEAR_INVERSE
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DAMAGING | REACTION_TAG_OTHER
|
||||
|
||||
/datum/chemical_reaction/ghoulpowder
|
||||
@@ -303,7 +303,7 @@
|
||||
H_ion_release = -0.06
|
||||
rate_up_lim = 15
|
||||
purity_min = 0.4
|
||||
reaction_flags = REACTION_CLEAR_IMPURE
|
||||
reaction_flags = REACTION_CLEAR_INVERSE
|
||||
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DAMAGING | REACTION_TAG_OTHER
|
||||
|
||||
/datum/chemical_reaction/heparin
|
||||
|
||||
Reference in New Issue
Block a user