[MIRROR] Code compression for reagent holder. Lowers plumbing reaction chamber tick usage [MDB IGNORE] (#25050)

* Code compression for reagent holder. Lowers plumbing reaction chamber tick usage (#79686)

## About The Pull Request
More code improvements for reagent holder. As you can see it removes a
lot more code than it adds so code savings are significant. This does
not touch on any floating point arithmetic, all that is behind us, this
focuses on removing redundant procs and merging existing procs to
achieve the same functionality so if you do see any changes in reagent
related behaviour it's not intentional and should be reported as a bug
here.

The following code changes can be summarized into points.

**1. Removes procs `get_master_reagent_id()` &
`get_master_reagent_name()`**
Both of these procs have the exact same functionality as
`get_master_reagent()` with the only exception of returning a different
value. Instead we can just call `get_master_reagent()` directly and
infer the name & type of it ourselves rather than creating a wrapper
proc to do it for us, therefore reducing overall code

**2. Removes & Merges `remove_all_type()` proc into `remove_reagent()`**
The proc `remove_all_type()` is highly inefficient, it first uses a for
loop to look for the reagent to remove & then it again calls
`remove_reagent()` on the reagent once it has found it. We can just
embed this functionality directly into `remove_reagent()` by simply
adding an additional parameter `include_subtypes`. This way the
operation is faster, and we reduce the code to get the job done. Also
now `remove_reagent()` will return the total volume of reagents removed
rather that a simple TRUE/FALSE

**3. Removes & Merges `trans_id_to()` proc into `trans_to()`**
Both these procs have the same job of transferring either a single
reagent or all reagents. `trans_id_to()` is a scaled down version of
`trans_to()` because
- It does not have any `method` var. This means if you want to transfer
a single reagent to a mob/organ or any other object it does not have the
functionality to expose the target to that transferred reagent.
- It does not have a `multiplier` var to scale reagent volumes
- It does not have code to deal with organs or stop reactions i.e. it
does not have the `no_react` var.

We can overcome all these short comings by simply adding an extra var
`target_id` to specify what specific reagent to transfer therefore
attaining the same functionality while keeping the benefits of
`trans_to()` proc therefore reducing overall code

**4. Lowers plumbing reaction chamber tick usage for balancing ph.**
Rather than invoking a while loop to balance ph it's much easier for the
player to simply make the reaction chamber wait for e.g. add a reagent
that will never come. This will make the chamber wait therefore giving
the reaction chamber ample time to correctly balance the ph and then
remove that reagent from the list therefore getting correct ph levels.
No need to create code hacks when the player can do it themselves  so
the while loop has been removed

## Changelog
🆑
code: removed redundant procs `get_master_reagent_id()` &
`get_master_reagent_name()`
code: merged `remove_all_type()` proc with `remove_reagent()` now this
proc can perform both functions. `remove_reagent()` now returns the
total volume of reagents removed rather than a simple TRUE/FALSE.
code: merged `trans_id_to()` proc with `trans_to()` now this proc can
perform both functions
refactor: plumbing reaction chamber will now use only a single tick to
balance ph of a solution making it less efficient but more faster. Just
make the reaction chamber wait for longer periods of time to accurately
balance ph
refactor: reagent holder code has been condensed. Report any bugs on
GitHub
/🆑

* Code compression for reagent holder. Lowers plumbing reaction chamber tick usage

* Modular update

* Update alcohol_reagents.dm

---------

Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-11-16 18:27:20 -05:00
committed by GitHub
co-authored by SyncIt21 Giz
parent 4a6637ed6e
commit 020d2ad13e
45 changed files with 188 additions and 272 deletions
+2 -6
View File
@@ -20,8 +20,6 @@
var/ducting_layer = DUCT_LAYER_DEFAULT
///In-case we don't want the main machine to get the reagents, but perhaps whoever is buckled to it
var/recipient_reagents_holder
///How do we apply the new reagents to the receiver? Generally doesn't matter, but some stuff, like people, does care if its injected or whatevs
var/methods
///What color is our demand connect?
var/demand_color = COLOR_RED
///What color is our supply connect?
@@ -139,10 +137,8 @@
/datum/component/plumbing/proc/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net)
if(!reagents || !target || !target.reagents)
return FALSE
if(reagent)
reagents.trans_id_to(target.recipient_reagents_holder, reagent, amount)
else
reagents.trans_to(target.recipient_reagents_holder, amount, methods = methods)
reagents.trans_to(target.recipient_reagents_holder, amount, target_id = reagent)
///We create our luxurious piping overlays/underlays, to indicate where we do what. only called once if use_overlays = TRUE in Initialize()
/datum/component/plumbing/proc/create_overlays(atom/movable/parent_movable, list/overlays)
+2 -2
View File
@@ -31,7 +31,7 @@
direction = get_original_direction(text2num(A))
break
if(reagent)
reagents.trans_id_to(target.parent, reagent, amount)
reagents.trans_to(target.parent, amount, target_id = reagent)
else
for(var/A in reagents.reagent_list)
var/datum/reagent/R = A
@@ -40,7 +40,7 @@
var/new_amount
if(R.volume < amount)
new_amount = amount - R.volume
reagents.trans_id_to(target.parent, R.type, amount)
reagents.trans_to(target.parent, amount, target_id = R.type)
amount = new_amount
if(amount <= 0)
break
+4 -4
View File
@@ -51,15 +51,15 @@
. |= COMPONENT_AFTERATTACK_PROCESSED_ITEM
var/obj/item/reagent_containers/container = parent
var/refill = container.reagents.get_master_reagent_id()
var/amount = min((container.amount_per_transfer_from_this + container.reagents.total_volume), container.reagents.total_volume)
if (amount == 0)
return
if (!is_path_in_list(refill, whitelisted_reagents))
var/datum/reagent/refill = container.reagents.get_master_reagent()
if (!is_path_in_list(refill?.type, whitelisted_reagents))
return
addtimer(CALLBACK(src, PROC_REF(add_reagents), container, container.loc, refill, amount), time_to_refill)
addtimer(CALLBACK(src, PROC_REF(add_reagents), container, container.loc, refill.type, amount), time_to_refill)
/// Refills the reagent container, and uses cell power if applicable
/datum/component/reagent_refiller/proc/add_reagents(obj/item/reagent_containers/target, oldloc, reagent_to_refill, amount)
@@ -51,7 +51,7 @@
M.adjust_confusion(-2 SECONDS)
if(purge_alcohol)
M.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3)
M.reagents.remove_reagent(/datum/reagent/consumable/ethanol, 3, include_subtypes = TRUE)
M.adjust_drunk_effect(-5)
if(A.stage >= 4)
+1 -1
View File
@@ -58,7 +58,7 @@
return
var/built_attacker_message = replacetext(attacker_message, "%VICTIM", transfer_victim)
var/built_victim_message = replacetext(attacker_message, "%ATTACKER", transfer_attacker)
transfer_attacker.reagents?.trans_to(transfer_victim, transfer_attacker.reagents.total_volume, multiplier = 1, preserve_data = 1, no_react = 0, transferred_by = transfer_attacker)
transfer_attacker.reagents?.trans_to(transfer_victim, transfer_attacker.reagents.total_volume, transferred_by = transfer_attacker)
to_chat(transfer_attacker, built_attacker_message)
to_chat(transfer_victim, built_victim_message)
+1 -1
View File
@@ -173,7 +173,7 @@
return FALSE
to_chat(transferred, span_warning("You feel a tiny prick!"))
transferer.reagents.trans_to(transferred, transferer.reagents.total_volume, 1, 1, 0, transferred_by = transferer)
transferer.reagents.trans_to(transferred, transferer.reagents.total_volume, transferred_by = transferer)
var/obj/item/hardened_spike/chem/chem_spike = target
var/obj/item/bodypart/spike_location = chem_spike.check_embedded()
+1 -1
View File
@@ -481,7 +481,7 @@
var/datum/reagents/reactants = new(time_release)
reactants.my_atom = src
for(var/obj/item/reagent_containers/RC in beakers)
RC.reagents.trans_to(reactants, RC.reagents.total_volume*fraction, 1, 1, 1)
RC.reagents.trans_to(reactants, RC.reagents.total_volume * fraction, no_react = TRUE)
chem_splash(get_turf(src), reagents, spread_range, list(reactants), temp_boost)
// Detonate it again in one second, until it's out of juice.
@@ -121,11 +121,15 @@
/obj/item/storage/portable_chem_mixer/proc/update_contents()
dispensable_reagents.Cut()
for (var/obj/item/reagent_containers/container in contents)
var/key = container.reagents.get_master_reagent_id()
if (!(key in dispensable_reagents))
dispensable_reagents[key] = list()
dispensable_reagents[key]["reagents"] = list()
dispensable_reagents[key]["reagents"] += container.reagents
var/datum/reagent/key = container.reagents.get_master_reagent()
if(isnull(key)) //no reagent inside container
continue
var/key_type = key.type
if (!(key_type in dispensable_reagents))
dispensable_reagents[key_type] = list()
dispensable_reagents[key_type]["reagents"] = list()
dispensable_reagents[key_type]["reagents"] += container.reagents
/obj/item/storage/portable_chem_mixer/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
. = ..()
@@ -313,11 +313,11 @@
var/container_ratio = available_extract_volume / beaker_total_volume
var/datum/reagents/tmp_holder = new/datum/reagents(beaker_total_volume)
for(var/obj/item/container as anything in other_containers)
container.reagents.trans_to(tmp_holder, container.reagents.total_volume * container_ratio, 1, preserve_data = TRUE, no_react = TRUE)
container.reagents.trans_to(tmp_holder, container.reagents.total_volume * container_ratio, no_react = TRUE)
for(var/obj/item/slime_extract/extract as anything in extracts)
var/available_volume = extract.reagents.maximum_volume - extract.reagents.total_volume
tmp_holder.trans_to(extract, beaker_total_volume * (available_volume / available_extract_volume), 1, preserve_data = TRUE, no_react = TRUE)
tmp_holder.trans_to(extract, beaker_total_volume * (available_volume / available_extract_volume), no_react = TRUE)
extract.reagents.handle_reactions() // Reaction handling in the transfer proc is reciprocal and we don't want to blow up the tmp holder early.
if(QDELETED(extract))
@@ -390,7 +390,12 @@
var/datum/reagents/reactants = new(unit_spread)
reactants.my_atom = src
for(var/obj/item/reagent_containers/reagent_container in beakers)
reagent_container.reagents.trans_to(reactants, reagent_container.reagents.total_volume*fraction, threatscale, 1, 1)
reagent_container.reagents.trans_to(
reactants,
reagent_container.reagents.total_volume * fraction,
threatscale,
no_react = TRUE
)
chem_splash(get_turf(src), reagents, affected_area, list(reactants), ignition_temp, threatscale)
var/turf/detonated_turf = get_turf(src)
+1 -1
View File
@@ -467,7 +467,7 @@
var/inj_am = injection_amount * seconds_per_tick
var/used_amount = inj_am / usage_ratio
reagents.trans_to(user, used_amount, multiplier=usage_ratio, methods = INJECT)
reagents.trans_to(user, used_amount, usage_ratio, methods = INJECT)
update_appearance()
user.update_worn_back() //for overlays update
@@ -101,11 +101,11 @@
to_chat(user, span_warning("[powder_keg] doesn't have at least 15u of gunpowder to fill [src]!"))
return
if(has_enough_gunpowder)
powder_keg.reagents.trans_id_to(src, /datum/reagent/gunpowder, amount = charge_size)
powder_keg.reagents.trans_to(src, charge_size, target_id = /datum/reagent/gunpowder)
balloon_alert(user, "[src] loaded with gunpowder")
return
if(has_enough_alt_fuel)
powder_keg.reagents.trans_id_to(src, /datum/reagent/fuel, amount = charge_size)
powder_keg.reagents.trans_to(src, charge_size, target_id = /datum/reagent/fuel)
balloon_alert(user, "[src] loaded with welding fuel")
return
..()
@@ -322,7 +322,12 @@
if(air1.total_moles() > CRYO_MIN_GAS_MOLES)
if(beaker)
beaker.reagents.trans_to(occupant, (CRYO_TX_QTY / (efficiency * CRYO_MULTIPLY_FACTOR)) * seconds_per_tick, efficiency * CRYO_MULTIPLY_FACTOR, methods = VAPOR) // Transfer reagents.
beaker.reagents.trans_to(
occupant,
(CRYO_TX_QTY / (efficiency * CRYO_MULTIPLY_FACTOR)) * seconds_per_tick,
efficiency * CRYO_MULTIPLY_FACTOR,
methods = VAPOR
)
consume_gas = TRUE
return TRUE
@@ -111,7 +111,7 @@
return
for(var/datum/reagent/R in beaker.reagents.reagent_list)
if(R.type in icecream_vat_reagents)
beaker.reagents.trans_id_to(src, R.type, R.volume)
beaker.reagents.trans_to(src, R.volume, target_id = R.type)
say("Internalizing reagent.")
playsound(src, 'sound/items/drink.ogg', 25, TRUE)
return
@@ -171,7 +171,8 @@
var/datum/reagents/holder = object_used.reagents
// The container must be majority reagent
if(holder.get_master_reagent_id() != reagent_type)
var/datum/reagent/master_reagent = holder.get_master_reagent()
if(master_reagent?.type != reagent_type)
return FALSE
// We must fulfill the sample size threshold
if(reagents_needed > holder.total_volume)
+1 -1
View File
@@ -148,7 +148,7 @@
var/average_purity = reagents.get_average_purity()
var/total_nutriment_amount = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment, include_subtypes = TRUE)
var/single_reagent_amount = grind_results_num > 1 ? round(total_nutriment_amount / grind_results_num, CHEMICAL_QUANTISATION_LEVEL) : total_nutriment_amount
reagents.remove_all_type(/datum/reagent/consumable/nutriment, total_nutriment_amount)
reagents.remove_reagent(/datum/reagent/consumable/nutriment, total_nutriment_amount, include_subtypes = TRUE)
for(var/reagent in grind_results)
reagents.add_reagent(reagent, single_reagent_amount, added_purity = average_purity)
+2 -2
View File
@@ -253,7 +253,7 @@
// Move the leaked water from nutrients to... water
var/leaking_water_amount = nutri_reagents.get_reagent_amount(/datum/reagent/water)
if(leaking_water_amount)
nutri_reagents.trans_id_to(water_reagents, /datum/reagent/water, leaking_water_amount)
nutri_reagents.trans_to(water_reagents, leaking_water_amount, target_id = /datum/reagent/water)
// We should only take MACHINE_REAGENT_TRANSFER every tick; this is the remaining amount we can take
var/remaining_transfer_amount = max(MACHINE_REAGENT_TRANSFER - (nutri_reagents.total_volume - initial_nutri_amount), 0)
@@ -887,7 +887,7 @@
if(istype(not_water_reagent,/datum/reagent/water))
continue
var/transfer_me_to_tray = reagent_source.reagents.get_reagent_amount(not_water_reagent.type) * transfer_amount / reagent_source.reagents.total_volume
reagent_source.reagents.trans_id_to(H.reagents, not_water_reagent.type, transfer_me_to_tray)
reagent_source.reagents.trans_to(H.reagents, transfer_me_to_tray, target_id = not_water_reagent.type)
else
reagent_source.reagents.trans_to(H.reagents, transfer_amount, transferred_by = user)
lastuser = WEAKREF(user)
+2 -2
View File
@@ -292,14 +292,14 @@
// Heats up the plant's contents by 25 kelvin per 1 unit of nutriment. Mutually exclusive with cooling.
if(get_gene(/datum/plant_gene/trait/chem_heating))
T.visible_message(span_notice("[T] releases freezing air, consuming its nutriments to heat its contents."))
T.reagents.remove_all_type(/datum/reagent/consumable/nutriment, num_nutriment, strict = TRUE)
T.reagents.remove_reagent(/datum/reagent/consumable/nutriment, num_nutriment)
T.reagents.chem_temp = min(1000, (T.reagents.chem_temp + num_nutriment * 25))
T.reagents.handle_reactions()
playsound(T.loc, 'sound/effects/wounds/sizzle2.ogg', 5)
// Cools down the plant's contents by 5 kelvin per 1 unit of nutriment. Mutually exclusive with heating.
else if(get_gene(/datum/plant_gene/trait/chem_cooling))
T.visible_message(span_notice("[T] releases a blast of hot air, consuming its nutriments to cool its contents."))
T.reagents.remove_all_type(/datum/reagent/consumable/nutriment, num_nutriment, strict = TRUE)
T.reagents.remove_reagent(/datum/reagent/consumable/nutriment, num_nutriment)
T.reagents.chem_temp = max(3, (T.reagents.chem_temp + num_nutriment * -5))
T.reagents.handle_reactions()
playsound(T.loc, 'sound/effects/space_wind.ogg', 50)
+1 -1
View File
@@ -463,7 +463,7 @@
if(reagents.has_reagent(reagent_required, reagent_required_amount))
balloon_alert(mod.wearer, "already charged!")
return FALSE
if(!attacking_item.reagents.trans_id_to(src, reagent_required, reagent_required_amount))
if(!attacking_item.reagents.trans_to(src, reagent_required_amount, target_id = reagent_required))
return FALSE
balloon_alert(mod.wearer, "charge [reagents.has_reagent(reagent_required, reagent_required_amount) ? "fully" : "partially"] reloaded")
return TRUE
+1 -1
View File
@@ -174,7 +174,7 @@ GLOBAL_VAR_INIT(nt_fax_department, pick("NT HR Department", "NT Legal Department
var/obj/item/reagent_containers/spray/clean_spray = item
if(!clean_spray.reagents.has_reagent(/datum/reagent/space_cleaner, clean_spray.amount_per_transfer_from_this))
return FALSE
clean_spray.reagents.remove_reagent(/datum/reagent/space_cleaner, clean_spray.amount_per_transfer_from_this, 1)
clean_spray.reagents.remove_reagent(/datum/reagent/space_cleaner, clean_spray.amount_per_transfer_from_this)
playsound(loc, 'sound/effects/spray3.ogg', 50, TRUE, MEDIUM_RANGE_SOUND_EXTRARANGE)
user.visible_message(span_notice("[user] cleans \the [src]."), span_notice("You clean \the [src]."))
jammed = FALSE
+3 -3
View File
@@ -91,13 +91,13 @@
var/obj/item/B = AM
///see if it would overflow else inject
if((B.reagents.total_volume + wanted_amount) <= B.reagents.maximum_volume)
reagents.trans_to(B, wanted_amount, transferred_by = src)
reagents.trans_to(B, wanted_amount)
B.forceMove(goodspot)
return
///glass was full so we move it away
AM.forceMove(badspot)
else if(istype(AM, /obj/item/slime_extract)) ///slime extracts need inject
AM.forceMove(goodspot)
reagents.trans_to(AM, wanted_amount, transferred_by = src, methods = INJECT)
reagents.trans_to(AM, wanted_amount, methods = INJECT)
else if(istype(AM, /obj/item/slimecross/industrial)) ///no need to move slimecross industrial things
reagents.trans_to(AM, wanted_amount, transferred_by = src, methods = INJECT)
reagents.trans_to(AM, wanted_amount, methods = INJECT)
@@ -3,9 +3,6 @@
/// coefficient to convert temperature to joules. same lvl as acclimator
#define HEATER_COEFFICIENT 0.05
/// maximum number of attempts the reaction chamber will make to balance the ph(More means better results but higher tick usage)
#define MAX_PH_ADJUSTMENTS 3
/obj/machinery/plumbing/reaction_chamber
name = "mixing chamber"
desc = "Keeps chemicals separated until given conditions are met."
@@ -175,8 +172,7 @@
return ..()
/obj/machinery/plumbing/reaction_chamber/chem/handle_reagents(seconds_per_tick)
var/ph_balance_attempts = 0
while(ph_balance_attempts < MAX_PH_ADJUSTMENTS && (reagents.ph < acidic_limit || reagents.ph > alkaline_limit))
if(reagents.ph < acidic_limit || reagents.ph > alkaline_limit)
//no power
if(machine_stat & NOPOWER)
return
@@ -197,15 +193,12 @@
//transfer buffer and handle reactions
var/ph_change = max((reagents.ph > alkaline_limit ? (reagents.ph - alkaline_limit) : (acidic_limit - reagents.ph)), 0.25)
if(ph_change <= 0.7) //make big jumps towards the end so we can end our work quickly
ph_change *= 2
var/buffer_amount = ((ph_change * reagents.total_volume) / (BUFFER_IONIZING_STRENGTH * num_of_reagents)) * seconds_per_tick
if(!buffer.trans_to(reagents, buffer_amount))
return
//some power for accurate ph balancing & keep track of attempts made
use_power(active_power_usage * 0.03 * buffer_amount)
ph_balance_attempts += 1
/obj/machinery/plumbing/reaction_chamber/chem/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
@@ -231,4 +224,3 @@
return FALSE
#undef HEATER_COEFFICIENT
#undef MAX_PH_ADJUSTMENTS
@@ -45,7 +45,9 @@
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
if(!victim.reagents)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
if(!victim.reagents.has_reagent(/datum/reagent/gold, check_subtypes = TRUE))
var/gold_amount = victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE)
if(!gold_amount)
balloon_alert(user, "no gold in bloodstream")
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
var/gold_beam = user.Beam(victim, icon_state="drain_gold")
@@ -53,8 +55,8 @@
qdel(gold_beam)
balloon_alert(user, "link broken")
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
handle_gold_charges(user, victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE))
victim.reagents.remove_all_type(/datum/reagent/gold, victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE))
handle_gold_charges(user, gold_amount)
victim.reagents.remove_reagent(/datum/reagent/gold, gold_amount, include_subtypes = TRUE)
victim.remove_status_effect(/datum/status_effect/midas_blight)
qdel(gold_beam)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+1 -1
View File
@@ -50,7 +50,7 @@
holder.multiply_reagents(threatscale)
for(var/datum/reagents/reactant as anything in reactants)
reactant.trans_to(holder, reactant.total_volume, threatscale, preserve_data = TRUE, no_react = TRUE)
reactant.trans_to(holder, reactant.total_volume, threatscale, no_react = TRUE)
holder.chem_temp += extra_heat // Average temperature of reagents + extra heat.
holder.handle_reactions() // React them now.
@@ -332,7 +332,7 @@
//Calculate how much product to make and how much reactant to remove factors..
for(var/reagent in reaction.required_reagents)
holder.remove_reagent(reagent, (delta_chem_factor * reaction.required_reagents[reagent]), safety = TRUE)
holder.remove_reagent(reagent, (delta_chem_factor * reaction.required_reagents[reagent]))
//Apply pH changes
var/pH_adjust
if(reaction.reaction_flags & REACTION_PH_VOL_CONSTANT)
@@ -414,4 +414,4 @@
///Panic stop a reaction - cleanup should be handled by the next timestep
/datum/equilibrium/proc/force_clear_reactive_agents()
for(var/reagent in reaction.required_reagents)
holder.remove_reagent(reagent, (multiplier * reaction.required_reagents[reagent]), safety = 1)
holder.remove_reagent(reagent, (multiplier * reaction.required_reagents[reagent]))
+51 -143
View File
@@ -205,8 +205,9 @@
* * [reagent_type][datum/reagent] - the type of reagent
* * amount - the volume to remove
* * safety - if FALSE will initiate reactions upon removing. used for trans_id_to
* * include_subtypes - if TRUE will remove the specified amount from all subtypes of reagent_type as well
*/
/datum/reagents/proc/remove_reagent(datum/reagent/reagent_type, amount, safety = TRUE)
/datum/reagents/proc/remove_reagent(datum/reagent/reagent_type, amount, safety = TRUE, include_subtypes = FALSE)
if(!ispath(reagent_type))
stack_trace("invalid reagent passed to remove reagent [reagent_type]")
return FALSE
@@ -219,23 +220,37 @@
if(amount <= 0)
return FALSE
var/total_removed_amount = 0
var/remove_amount = 0
var/list/cached_reagents = reagent_list
for(var/datum/reagent/cached_reagent as anything in cached_reagents)
if(cached_reagent.type == reagent_type)
cached_reagent.volume -= amount
//check for specific type or subtypes
if(!include_subtypes)
if(cached_reagent.type != reagent_type)
continue
else if(!istype(cached_reagent, reagent_type))
continue
update_total()
if(!safety)//So it does not handle reactions when it need not to
handle_reactions()
remove_amount = min(cached_reagent.volume, amount)
cached_reagent.volume -= remove_amount
SEND_SIGNAL(src, COMSIG_REAGENTS_REM_REAGENT, QDELING(cached_reagent) ? reagent_type : cached_reagent, amount)
update_total()
if(!safety)//So it does not handle reactions when it need not to
handle_reactions()
SEND_SIGNAL(src, COMSIG_REAGENTS_REM_REAGENT, QDELING(cached_reagent) ? reagent_type : cached_reagent, amount)
return TRUE
total_removed_amount += remove_amount
return FALSE
//if we reached here means we have found our specific reagent type so break
if(!include_subtypes)
break
return total_removed_amount
/**
* Removes a reagent at random by the specified amount
* Removes a reagent at random and by a random quantity till the specified amount has been removed.
* Used to create a shower/spray effect for e.g. when you spill a bottle or turn a shower on
* and you want an chaotic effect of whatever coming out
* Arguments
*
* * amount- the volume to remove
@@ -298,56 +313,13 @@
var/list/cached_reagents = reagent_list
var/part = amount / total_volume
var/remove_amount
var/removed_amount = 0
var/total_removed_amount = 0
for(var/datum/reagent/reagent as anything in cached_reagents)
remove_amount = reagent.volume * part
remove_reagent(reagent.type, remove_amount)
removed_amount += remove_amount
total_removed_amount += remove_reagent(reagent.type, reagent.volume * part)
handle_reactions()
return round(removed_amount, CHEMICAL_VOLUME_ROUNDING)
/**
* Removes all reagent of X type
* Arguments
*
* * [reagent_type][datum/reagent] - the reagent typepath we are trying to remove
* * amount - the volume of reagent to remove
* * strict - If TRUE will also remove childs of this reagent type
*/
/datum/reagents/proc/remove_all_type(datum/reagent/reagent_type, amount, strict = 0, safety = 1)
if(!ispath(reagent_type))
stack_trace("invalid reagent path passed to remove all type [reagent_type]")
return FALSE
if(!IS_FINITE(amount))
stack_trace("non finite amount passed to remove all type reagent [amount] [reagent_type]")
return FALSE
amount = round(amount, CHEMICAL_QUANTISATION_LEVEL)
if(amount <= 0)
return FALSE
var/list/cached_reagents = reagent_list
var/has_removed_reagent = 0
for(var/datum/reagent/reagent as anything in cached_reagents)
var/matches = 0
// Switch between how we check the reagent type
if(strict)
if(reagent.type == reagent_type)
matches = 1
else
if(istype(reagent, reagent_type))
matches = 1
// We found a match, proceed to remove the reagent. Keep looping, we might find other reagents of the same type.
if(matches)
// Have our other proc handle removement
has_removed_reagent = remove_reagent(reagent.type, amount, safety)
return has_removed_reagent
return round(total_removed_amount, CHEMICAL_VOLUME_ROUNDING)
/**
* Removes an specific reagent from this holder
@@ -487,6 +459,7 @@
* * obj/target - Target to attempt transfer to
* * amount - amount of reagent volume to transfer
* * multiplier - multiplies each reagent amount by this number well byond their available volume before transfering. used to create reagents from thin air if you ever need to
* * datum/reagent/target_id - transfer only this reagent in this holder leaving others untouched
* * preserve_data - if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
* * no_react - passed through to [/datum/reagents/proc/add_reagent]
* * mob/transferred_by - used for logging
@@ -499,6 +472,7 @@
obj/target,
amount = 1,
multiplier = 1,
datum/reagent/target_id,
preserve_data = TRUE,
no_react = FALSE,
mob/transferred_by,
@@ -508,12 +482,16 @@
ignore_stomach = FALSE
)
if(QDELETED(target) || !total_volume)
return
return FALSE
if(!IS_FINITE(amount))
stack_trace("non finite amount passed to trans_to [amount] amount of reagents")
return FALSE
if(!isnull(target_id) && !ispath(target_id))
stack_trace("invalid target reagent id [target_id] passed to trans_to")
return FALSE
var/list/cached_reagents = reagent_list
var/atom/target_atom
@@ -554,7 +532,7 @@
var/list/r_to_send = list() // Validated list of reagents to be exposed
var/list/reagents_to_remove = list()
var/part = amount / total_volume
var/part = isnull(target_id) ? (amount / total_volume) : 1
var/transfer_amount
var/transfered_amount
var/total_transfered_amount = 0
@@ -563,11 +541,20 @@
for(var/datum/reagent/reagent as anything in cached_reagents)
if(remove_blacklisted && !(reagent.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED))
continue
if(!isnull(target_id))
if(reagent.type == target_id)
force_stop_reagent_reacting(reagent)
transfer_amount = min(amount, reagent.volume)
else
continue
else
transfer_amount = reagent.volume * part
if(preserve_data)
trans_data = copy_data(reagent)
if(reagent.intercept_reagents_transfer(target_holder, cached_amount))
continue
transfer_amount = reagent.volume * part
transfered_amount = target_holder.add_reagent(reagent.type, transfer_amount * multiplier, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT) //we only handle reaction after every reagent has been transferred.
if(!transfered_amount)
continue
@@ -576,6 +563,9 @@
reagents_to_remove += list(list("R" = reagent, "T" = transfer_amount))
total_transfered_amount += transfered_amount
if(!isnull(target_id))
break
//expose target to reagent changes
target_holder.expose_multiple(r_to_send, isorgan(target_atom) ? target : target_atom, methods, part, show_message)
@@ -600,64 +590,6 @@
return round(total_transfered_amount, CHEMICAL_VOLUME_ROUNDING)
/**
* Transfer a specific reagent id to the target object
* Arguments
*
* * [target][obj] - the target to transfer reagents to
* * [reagent_type][datum/reagent] - the type of reagent to transfer to the target
* * amount - volume to transfer
* * preserve_data- if TRUE reagent user data will remain preserved
*/
/datum/reagents/proc/trans_id_to(
obj/target,
datum/reagent/reagent_type,
amount = 1,
preserve_data = 1
)
if (QDELETED(target) || !total_volume)
return
if(!IS_FINITE(amount))
stack_trace("non finite amount passed to trans_id_to [amount] [reagent_type]")
return FALSE
var/cached_amount = amount
var/available_volume = get_reagent_amount(reagent_type)
var/datum/reagents/holder
if(istype(target, /datum/reagents))
holder = target
else if(target.reagents && available_volume)
holder = target.reagents
else
return
// Prevents small amount problems, as well as zero and below zero amounts.
amount = round(min(amount, available_volume, holder.maximum_volume - holder.total_volume), CHEMICAL_QUANTISATION_LEVEL)
if(amount <= 0)
return
var/list/cached_reagents = reagent_list
var/trans_data = null
for (var/looping_through_reagents in cached_reagents)
var/datum/reagent/current_reagent = looping_through_reagents
if(current_reagent.type == reagent_type)
if(preserve_data)
trans_data = current_reagent.data
if(current_reagent.intercept_reagents_transfer(holder, cached_amount))//Use input amount instead.
break
force_stop_reagent_reacting(current_reagent)
holder.add_reagent(current_reagent.type, amount, trans_data, chem_temp, current_reagent.purity, current_reagent.ph, no_react = TRUE, ignore_splitting = current_reagent.chemical_flags & REAGENT_DONOTSPLIT)
remove_reagent(current_reagent.type, amount, 1)
break
update_total()
holder.update_total()
holder.handle_reactions()
return amount
/**
* Copies the reagents to the target object
* Arguments
@@ -704,7 +636,7 @@
for(var/datum/reagent/reagent as anything in cached_reagents)
transfer_amount = reagent.volume * part * multiplier
if(preserve_data)
trans_data = reagent.data
trans_data = copy_data(reagent)
transfered_amount = target_holder.add_reagent(reagent.type, transfer_amount, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)
if(!transfered_amount)
continue
@@ -739,30 +671,6 @@
handle_reactions()
/// Get the name of the reagent there is the most of in this holder
/datum/reagents/proc/get_master_reagent_name()
var/list/cached_reagents = reagent_list
var/name
var/max_volume = 0
for(var/datum/reagent/reagent as anything in cached_reagents)
if(reagent.volume > max_volume)
max_volume = reagent.volume
name = reagent.name
return name
/// Get the id of the reagent there is the most of in this holder
/datum/reagents/proc/get_master_reagent_id()
var/list/cached_reagents = reagent_list
var/max_type
var/max_volume = 0
for(var/datum/reagent/reagent as anything in cached_reagents)
if(reagent.volume > max_volume)
max_volume = reagent.volume
max_type = reagent.type
return max_type
/// Get a reference to the reagent there is the most of in this holder
/datum/reagents/proc/get_master_reagent()
var/list/cached_reagents = reagent_list
@@ -1279,7 +1187,7 @@
if (!reagent)
continue
sum_purity += reagent.purity
remove_reagent(_reagent, (multiplier * cached_required_reagents[_reagent]), safety = 1)
remove_reagent(_reagent, (multiplier * cached_required_reagents[_reagent]))
sum_purity /= cached_required_reagents.len
for(var/product in selected_reaction.results)
@@ -447,10 +447,10 @@ To continue set your target temperature to 390K."}
if(acid_reagent_heater)
cur_vol = acid_reagent_heater.volume
volume = 100 - cur_vol
beaker.reagents.trans_id_to(src, acid_reagent.type, volume)//negative because we're going backwards
beaker.reagents.trans_to(src, volume, target_id = acid_reagent.type)//negative because we're going backwards
return
//We must be positive here
reagents.trans_id_to(beaker, /datum/reagent/reaction_agent/acidic_buffer, dispense_volume)
reagents.trans_to(beaker, dispense_volume, target_id = /datum/reagent/reaction_agent/acidic_buffer)
return
if(buffer_type == "basic")
@@ -464,9 +464,9 @@ To continue set your target temperature to 390K."}
if(basic_reagent_heater)
cur_vol = basic_reagent_heater.volume
volume = 100 - cur_vol
beaker.reagents.trans_id_to(src, basic_reagent.type, volume)//negative because we're going backwards
beaker.reagents.trans_to(src, volume, target_id = basic_reagent.type)//negative because we're going backwards
return
reagents.trans_id_to(beaker, /datum/reagent/reaction_agent/basic_buffer, dispense_volume)
reagents.trans_to(beaker, dispense_volume, target_id = /datum/reagent/reaction_agent/basic_buffer)
return
@@ -340,10 +340,11 @@
// Generate item name
var/item_name_default = initial(container_style.name)
var/datum/reagent/master_reagent = reagents.get_master_reagent()
if(selected_container == default_container) // Tubes and bottles gain reagent name
item_name_default = "[reagents.get_master_reagent_name()] [item_name_default]"
item_name_default = "[master_reagent.name] [item_name_default]"
if(!(initial(container_style.reagent_flags) & OPENCONTAINER)) // Closed containers get both reagent name and units in the name
item_name_default = "[reagents.get_master_reagent_name()] [item_name_default] ([volume_in_each]u)"
item_name_default = "[master_reagent.name] [item_name_default] ([volume_in_each]u)"
var/item_name = tgui_input_text(usr,
"Container name",
"Name",
@@ -395,7 +396,7 @@
if (target == TARGET_BUFFER)
if(!check_reactions(reagent, beaker.reagents))
return FALSE
beaker.reagents.trans_id_to(src, reagent.type, amount)
beaker.reagents.trans_to(src, amount, target_id = reagent.type)
update_appearance(UPDATE_ICON)
return TRUE
@@ -406,7 +407,7 @@
if (target == TARGET_BEAKER && transfer_mode == TRANSFER_MODE_MOVE)
if(!check_reactions(reagent, reagents))
return FALSE
reagents.trans_id_to(beaker, reagent.type, amount)
reagents.trans_to(beaker, amount, target_id = reagent.type)
update_appearance(UPDATE_ICON)
return TRUE
@@ -231,7 +231,7 @@
soundloop.start()
var/vapor_amount = distillation_rate * seconds_per_tick
// Vapor to condenser
reagents.trans_id_to(condenser, separating_reagent.type, vapor_amount)
reagents.trans_to(condenser, vapor_amount, target_id = separating_reagent.type)
// Cool the vapor down
condenser.set_temperature(air.temperature)
// Condense into container
@@ -225,7 +225,7 @@
if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE))
. = UPDATE_MOB_HEALTH
if(holder.has_reagent(/datum/reagent/consumable/capsaicin))
holder.remove_reagent(/datum/reagent/consumable/capsaicin, 1 * seconds_per_tick)
holder.remove_reagent(/datum/reagent/consumable/capsaicin, seconds_per_tick)
return ..() || .
/datum/reagent/consumable/soymilk
@@ -1148,7 +1148,7 @@
. = ..()
for(var/effect in status_effects_to_clear)
affected_mob.remove_status_effect(effect)
affected_mob.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3 * REM * seconds_per_tick * normalise_creation_purity(), FALSE, TRUE)
affected_mob.reagents.remove_reagent(/datum/reagent/consumable/ethanol, 3 * REM * seconds_per_tick * normalise_creation_purity(), include_subtypes = TRUE)
if(affected_mob.adjustToxLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
. = UPDATE_MOB_HEALTH
affected_mob.adjust_drunk_effect(-10 * REM * seconds_per_tick * normalise_creation_purity())
@@ -1285,7 +1285,7 @@
/datum/reagent/medicine/syndicate_nanites/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) //wtb flavortext messages that hint that you're vomitting up robots
. = ..()
if(SPT_PROB(13, seconds_per_tick))
affected_mob.reagents.remove_reagent(type, metabolization_rate*15) // ~5 units at a rate of 0.4 but i wanted a nice number in code
affected_mob.reagents.remove_reagent(type, metabolization_rate * 15) // ~5 units at a rate of 0.4 but i wanted a nice number in code
affected_mob.vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, vomit_type = /obj/effect/decal/cleanable/vomit/nanites, lost_nutrition = 20) // nanite safety protocols make your body expel them to prevent harmies
/datum/reagent/medicine/earthsblood //Created by ambrosia gaia plants
@@ -549,7 +549,7 @@
need_mob_update += affected_mob.adjustFireLoss(0.5*seconds_per_tick, updating_health = FALSE) //Hence the other damages... ain't I a bastard?
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2.5*seconds_per_tick, 150)
if(holder)
holder.remove_reagent(type, 0.5*seconds_per_tick)
holder.remove_reagent(type, 0.5 * seconds_per_tick)
if(need_mob_update)
return UPDATE_MOB_HEALTH
@@ -782,7 +782,7 @@
if(SPT_PROB(1.5, seconds_per_tick))
holder.add_reagent(/datum/reagent/toxin/histamine,rand(1,3))
holder.remove_reagent(/datum/reagent/toxin/itching_powder,1.2)
holder.remove_reagent(/datum/reagent/toxin/itching_powder, 1.2)
return
else
return ..() || .
@@ -963,7 +963,7 @@
affected_mob.vomit(vomit_flags = constructed_flags, distance = rand(0,4))
for(var/datum/reagent/toxin/R in affected_mob.reagents.reagent_list)
if(R != src)
affected_mob.reagents.remove_reagent(R.type,1)
affected_mob.reagents.remove_reagent(R.type, 1)
/datum/reagent/toxin/spewium/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
+1 -1
View File
@@ -168,7 +168,7 @@
var/cached_purity = reagent.purity
if((reaction_flags & REACTION_CLEAR_INVERSE) && reagent.inverse_chem)
if(reagent.inverse_chem_val > reagent.purity)
holder.remove_reagent(reagent.type, cached_volume, FALSE)
holder.remove_reagent(reagent.type, cached_volume, safety = FALSE)
holder.add_reagent(reagent.inverse_chem, cached_volume, FALSE, added_purity = reagent.get_inverse_purity(cached_purity))
return
@@ -17,7 +17,7 @@
if(holder.has_reagent(/datum/reagent/exotic_stabilizer,round(created_volume / 25, CHEMICAL_QUANTISATION_LEVEL)))
return
holder.remove_reagent(/datum/reagent/nitroglycerin, created_volume*2)
holder.remove_reagent(/datum/reagent/nitroglycerin, created_volume * 2)
..()
/datum/chemical_reaction/reagent_explosion/nitroglycerin_explosion
@@ -35,7 +35,7 @@
/datum/chemical_reaction/reagent_explosion/rdx/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
if(holder.has_reagent(/datum/reagent/stabilizing_agent))
return
holder.remove_reagent(/datum/reagent/rdx, created_volume*2)
holder.remove_reagent(/datum/reagent/rdx, created_volume * 2)
..()
/datum/chemical_reaction/reagent_explosion/rdx_explosion
@@ -242,7 +242,7 @@
/datum/chemical_reaction/sorium/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
if(holder.has_reagent(/datum/reagent/stabilizing_agent))
return
holder.remove_reagent(/datum/reagent/sorium, created_volume*4)
holder.remove_reagent(/datum/reagent/sorium, created_volume * 4)
var/turf/T = get_turf(holder.my_atom)
var/range = clamp(sqrt(created_volume*4), 1, 6)
goonchem_vortex(T, 1, range)
@@ -265,7 +265,7 @@
/datum/chemical_reaction/liquid_dark_matter/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
if(holder.has_reagent(/datum/reagent/stabilizing_agent))
return
holder.remove_reagent(/datum/reagent/liquid_dark_matter, created_volume*3)
holder.remove_reagent(/datum/reagent/liquid_dark_matter, created_volume * 3)
var/turf/T = get_turf(holder.my_atom)
var/range = clamp(sqrt(created_volume*3), 1, 6)
goonchem_vortex(T, 0, range)
@@ -301,7 +301,7 @@
C.Paralyze(60)
else
C.Stun(100)
holder.remove_reagent(/datum/reagent/flash_powder, created_volume*3)
holder.remove_reagent(/datum/reagent/flash_powder, created_volume * 3)
/datum/chemical_reaction/flash_powder_flash
required_reagents = list(/datum/reagent/flash_powder = 1)
@@ -331,7 +331,7 @@
/datum/chemical_reaction/smoke_powder/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
if(holder.has_reagent(/datum/reagent/stabilizing_agent))
return
holder.remove_reagent(/datum/reagent/smoke_powder, created_volume*3)
holder.remove_reagent(/datum/reagent/smoke_powder, created_volume * 3)
var/location = get_turf(holder.my_atom)
var/datum/effect_system/fluid_spread/smoke/chem/S = new
S.attach(location)
@@ -368,7 +368,7 @@
/datum/chemical_reaction/sonic_powder/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
if(holder.has_reagent(/datum/reagent/stabilizing_agent))
return
holder.remove_reagent(/datum/reagent/sonic_powder, created_volume*3)
holder.remove_reagent(/datum/reagent/sonic_powder, created_volume * 3)
var/location = get_turf(holder.my_atom)
playsound(location, 'sound/effects/bang.ogg', 25, TRUE)
for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/3, location))
@@ -574,7 +574,7 @@
modifier = 1
/datum/chemical_reaction/reagent_explosion/nitrous_oxide/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
holder.remove_reagent(/datum/reagent/sorium, created_volume*2)
holder.remove_reagent(/datum/reagent/sorium, created_volume * 2)
var/turf/turfie = get_turf(holder.my_atom)
//generally half as strong as sorium.
var/range = clamp(sqrt(created_volume*2), 1, 6)
@@ -466,9 +466,12 @@
/// Handles reagents getting added to the condiment pack.
/obj/item/reagent_containers/condiment/pack/proc/on_reagent_add(datum/reagents/reagents)
SIGNAL_HANDLER
var/main_reagent = reagents.get_master_reagent_id()
if(main_reagent in possible_states)
var/list/temp_list = possible_states[main_reagent]
var/datum/reagent/main_reagent = reagents.get_master_reagent()
var/main_reagent_type = main_reagent?.type
if(main_reagent_type in possible_states)
var/list/temp_list = possible_states[main_reagent_type]
icon_state = temp_list[1]
desc = temp_list[3]
else
@@ -14,10 +14,10 @@ Burning extracts:
create_reagents(10, INJECTABLE | DRAWABLE)
/obj/item/slimecross/burning/attack_self(mob/user)
if(!reagents.has_reagent(/datum/reagent/toxin/plasma,10))
if(!reagents.has_reagent(/datum/reagent/toxin/plasma, 10))
to_chat(user, span_warning("This extract needs to be full of plasma to activate!"))
return
reagents.remove_reagent(/datum/reagent/toxin/plasma,10)
reagents.remove_reagent(/datum/reagent/toxin/plasma, 10)
to_chat(user, span_notice("You squeeze the extract, and it absorbs the plasma!"))
playsound(src, 'sound/effects/bubbles.ogg', 50, TRUE)
playsound(src, 'sound/magic/fireball.ogg', 50, TRUE)
@@ -15,10 +15,10 @@ Charged extracts:
create_reagents(10, INJECTABLE | DRAWABLE)
/obj/item/slimecross/charged/attack_self(mob/user)
if(!reagents.has_reagent(/datum/reagent/toxin/plasma,10))
if(!reagents.has_reagent(/datum/reagent/toxin/plasma, 10))
to_chat(user, span_warning("This extract needs to be full of plasma to activate!"))
return
reagents.remove_reagent(/datum/reagent/toxin/plasma,10)
reagents.remove_reagent(/datum/reagent/toxin/plasma, 10)
to_chat(user, span_notice("You squeeze the extract, and it absorbs the plasma!"))
playsound(src, 'sound/effects/bubbles.ogg', 50, TRUE)
playsound(src, 'sound/effects/light_flicker.ogg', 50, TRUE)
@@ -14,10 +14,10 @@ Chilling extracts:
create_reagents(10, INJECTABLE | DRAWABLE)
/obj/item/slimecross/chilling/attack_self(mob/user)
if(!reagents.has_reagent(/datum/reagent/toxin/plasma,10))
if(!reagents.has_reagent(/datum/reagent/toxin/plasma, 10))
to_chat(user, span_warning("This extract needs to be full of plasma to activate!"))
return
reagents.remove_reagent(/datum/reagent/toxin/plasma,10)
reagents.remove_reagent(/datum/reagent/toxin/plasma, 10)
to_chat(user, span_notice("You squeeze the extract, and it absorbs the plasma!"))
playsound(src, 'sound/effects/bubbles.ogg', 50, TRUE)
playsound(src, 'sound/effects/glassbr1.ogg', 50, TRUE)
@@ -32,11 +32,11 @@ Industrial extracts:
var/IsWorking = FALSE
if(reagents.has_reagent(/datum/reagent/toxin/plasma,amount = 2) && plasmarequired > 1) //Can absorb as much as 2
IsWorking = TRUE
reagents.remove_reagent(/datum/reagent/toxin/plasma,2)
reagents.remove_reagent(/datum/reagent/toxin/plasma, 2)
plasmaabsorbed += 2
else if(reagents.has_reagent(/datum/reagent/toxin/plasma,amount = 1)) //Can absorb as little as 1
IsWorking = TRUE
reagents.remove_reagent(/datum/reagent/toxin/plasma,1)
reagents.remove_reagent(/datum/reagent/toxin/plasma, 1)
plasmaabsorbed += 1
if(plasmaabsorbed >= plasmarequired)
@@ -82,7 +82,7 @@
// transfer the reagents over to the body at the rate of the stomach metabolim
// this way the body is where all reagents that are processed and react
// the stomach manages how fast they are feed in a drip style
reagents.trans_id_to(body, bit.type, amount=amount)
reagents.trans_to(body, amount, target_id = bit.type)
//Handle disgust
if(body)
@@ -198,7 +198,7 @@
log_message("Injecting [patient] with [to_inject] units of [R.name].", LOG_MECHA)
for(var/driver in chassis.return_drivers())
log_combat(driver, patient, "injected", "[name] ([R] - [to_inject] units)")
SG.reagents.trans_id_to(patient,R.type,to_inject)
SG.reagents.trans_to(patient, to_inject, target_id = R.type)
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/container_resist_act(mob/living/user)
go_out()
@@ -173,7 +173,7 @@
var/datum/reagents/water_reagents = new /datum/reagents(required_amount/8) //required_amount/8, because the water usage is split between eight sprays. As of this comment, required_amount/8 = 10u each.
water.reagents = water_reagents
water_reagents.my_atom = water
reagents.trans_to(water, required_amount/8)
reagents.trans_to(water, required_amount / 8)
water.move_at(get_step(chassis, get_dir(targetturf, chassis)), 2, 4) //Target is the tile opposite of the mech as the starting turf.
playsound(chassis, 'sound/effects/extinguish.ogg', 75, TRUE, -3)
@@ -27,11 +27,11 @@
name = "glass of synthanol"
desc = "The equivalent of alcohol for synthetic crewmembers. They'd find it awful if they had tastebuds too."
/datum/reagent/consumable/ethanol/synthanol/on_mob_life(mob/living/carbon/C)
if(!(C.mob_biotypes & MOB_ROBOTIC))
C.reagents.remove_reagent(type, 3.6) //gets removed from organics very fast
/datum/reagent/consumable/ethanol/synthanol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(!(affected_mob.mob_biotypes & MOB_ROBOTIC))
affected_mob.reagents.remove_reagent(type, 3.6 * REM * seconds_per_tick) //gets removed from organics very fast
if(prob(25))
C.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 5)
affected_mob.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 5)
return ..()
/datum/reagent/consumable/ethanol/synthanol/expose_mob(mob/living/carbon/C, method=TOUCH, volume)
@@ -162,9 +162,9 @@
name = "glass of hellfire"
desc = "An amber colored drink that isn't quite as hot as it looks."
/datum/reagent/consumable/ethanol/hellfire/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(30 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL + 30)
return ..()
/datum/reagent/consumable/ethanol/hellfire/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
affected_mob.adjust_bodytemperature(30 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 0, BODYTEMP_NORMAL + 30)
/datum/reagent/consumable/ethanol/sins_delight
name = "Sin's Delight"
@@ -256,10 +256,11 @@
name = "glass of hotlime miami"
desc = "This looks very aesthetically pleasing."
/datum/reagent/consumable/ethanol/hotlime_miami/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
M.set_drugginess(1.5 MINUTES * REM * seconds_per_tick)
M.adjustStaminaLoss(-2)
return ..()
/datum/reagent/consumable/ethanol/hotlime_miami/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
affected_mob.set_drugginess(1.5 MINUTES * REM * seconds_per_tick)
if(affected_mob.adjustStaminaLoss(-2 * REM * seconds_per_tick, updating_stamina = FALSE))
return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/coggrog
name = "Cog Grog"
@@ -321,9 +322,9 @@
name = "glass of mercuryblast"
desc = "No thermometers were harmed in the creation of this drink"
/datum/reagent/consumable/ethanol/mercuryblast/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-30 * TEMPERATURE_DAMAGE_COEFFICIENT, T0C)
return ..()
/datum/reagent/consumable/ethanol/mercuryblast/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
affected_mob.adjust_bodytemperature(-30 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, T0C)
/datum/reagent/consumable/ethanol/piledriver
name = "Piledriver"
@@ -540,10 +541,11 @@
name = "glass of jell wyrm"
desc = "A bubbly drink that is rather inviting to those that don't know who it's meant for."
/datum/reagent/consumable/ethanol/jell_wyrm/on_mob_life(mob/living/carbon/M)
/datum/reagent/consumable/ethanol/jell_wyrm/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
if(prob(20))
M.adjustToxLoss(1, 0)
return ..()
if(affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE))
return UPDATE_MOB_HEALTH
#define JELLWYRM_DISGUST 25
@@ -643,12 +645,10 @@
#undef BLOODSHOT_DISGUST
/datum/reagent/consumable/ethanol/bloodshot/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
. = ..()
if(drinker.blood_volume < drinker.blood_volume_normal)
drinker.blood_volume = max(drinker.blood_volume, min(drinker.blood_volume + (3 * REM * seconds_per_tick), BLOOD_VOLUME_NORMAL)) //Bloodshot quickly restores blood loss.
return ..()
/datum/reagent/consumable/ethanol/blizzard_brew
name = "Blizzard Brew"
description = "An ancient recipe. Served best chilled as much as dwarvenly possible."
@@ -675,18 +675,18 @@
return ..()
/datum/reagent/consumable/ethanol/blizzard_brew/overdose_start(mob/living/carbon/drinker)
. = ..()
cube = new /obj/structure/ice_stasis(get_turf(drinker))
cube.color = COLOR_CYAN
cube.set_anchored(TRUE)
drinker.forceMove(cube)
cryostylane_alert = drinker.throw_alert("cryostylane_alert", /atom/movable/screen/alert/status_effect/freon/cryostylane)
cryostylane_alert.attached_effect = src //so the alert can reference us, if it needs to
..()
/datum/reagent/consumable/ethanol/blizzard_brew/on_mob_delete(mob/living/carbon/drinker, amount)
QDEL_NULL(cube)
drinker.clear_alert("cryostylane_alert")
..()
return ..()
/datum/reagent/consumable/ethanol/molten_mead
name = "Molten Mead"
@@ -743,14 +743,14 @@
quality = DRINK_FANTASTIC
return ..()
/datum/reagent/consumable/ethanol/hippie_hooch/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
/datum/reagent/consumable/ethanol/hippie_hooch/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
for(var/effect in status_effects_to_clear)
drinker.remove_status_effect(effect)
drinker.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3 * REM * seconds_per_tick, FALSE, TRUE)
drinker.adjustToxLoss(-0.2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
drinker.adjust_drunk_effect(-10 * REM * seconds_per_tick)
..()
. = TRUE
affected_mob.remove_status_effect(effect)
affected_mob.reagents.remove_reagent(/datum/reagent/consumable/ethanol, 3 * REM * seconds_per_tick, include_subtypes = TRUE)
. = ..()
if(affected_mob.adjustToxLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
. = UPDATE_MOB_HEALTH
affected_mob.adjust_drunk_effect(-10 * REM * seconds_per_tick)
/datum/reagent/consumable/ethanol/research_rum
name = "Research Rum"
@@ -774,10 +774,9 @@
return ..()
/datum/reagent/consumable/ethanol/research_rum/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
. = ..()
if(prob(5))
drinker.say(pick_list_replacements(VISTA_FILE, "ballmer_good_msg"), forced = "ballmer")
..()
. = TRUE
/datum/reagent/consumable/ethanol/golden_grog
name = "Golden Grog"
@@ -290,7 +290,7 @@
balloon_alert(mod.wearer, "already full!")
return FALSE
/// And if the reagent's wrong.
if(!attacking_item.reagents.trans_id_to(src, reagent_required, reagent_required_amount))
if(!attacking_item.reagents.trans_to(src, reagent_required_amount, target_id = reagent_required))
return FALSE
/// And if you got to that point without screwing up then it awards you with being refilled.
balloon_alert(mod.wearer, "charge reloaded")
@@ -590,12 +590,12 @@
for(var/datum/reagent/weapon_reagent as anything in attacking_weapon.reagents.reagent_list)
if(weapon_reagent.volume < MINIMUM_IMBUING_REAGENT_AMOUNT)
attacking_weapon.reagents.remove_all_type(weapon_reagent.type)
attacking_weapon.reagents.remove_reagent(weapon_reagent.type)
continue
if(is_type_in_typecache(weapon_reagent, disallowed_reagents))
balloon_alert(user, "cannot imbue with [weapon_reagent.name]")
attacking_weapon.reagents.remove_all_type(weapon_reagent.type)
attacking_weapon.reagents.remove_reagent(weapon_reagent.type, include_subtypes = TRUE)
continue
weapon_component.imbued_reagent += weapon_reagent.type
@@ -640,12 +640,12 @@
for(var/datum/reagent/clothing_reagent as anything in attacking_clothing.reagents.reagent_list)
if(clothing_reagent.volume < MINIMUM_IMBUING_REAGENT_AMOUNT)
attacking_clothing.reagents.remove_all_type(clothing_reagent.type)
attacking_clothing.reagents.remove_reagent(clothing_reagent.type, include_subtypes = TRUE)
continue
if(is_type_in_typecache(clothing_reagent, disallowed_reagents))
balloon_alert(user, "cannot imbue with [clothing_reagent.name]")
attacking_clothing.reagents.remove_all_type(clothing_reagent.type)
attacking_clothing.reagents.remove_reagent(clothing_reagent.type, include_subtypes = TRUE)
continue
clothing_component.imbued_reagent += clothing_reagent.type