Files
Bubberstation/code/datums/elements/chemical_transfer.dm
SkyratBot 020d2ad13e [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>
2023-11-16 18:27:20 -05:00

67 lines
2.7 KiB
Plaintext

//the default chemical transfer messages if they aren't set
#define DEFAULT_ATTACKER_MESSAGE span_notice("You transfer your chemicals to %VICTIM.")
#define DEFAULT_VICTIM_MESSAGE span_userdanger("Chemicals have been transferred into you from %ATTACKER!")
/**
* ## chemical transfer element!
*
* Bespoke element that, on a certain chance to proc, transfers all chemicals from the person attacking to the victim being attacked
* with whatever item has this element.
*
* attacker_message uses %VICTIM as whomever is getting attacked.
* victim_message uses %ATTACKER for the same.
*/
/datum/element/chemical_transfer
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
///chance for the chemical transfer to proc.
var/transfer_prob
///message attacker gets when the chemical transfer procs
var/attacker_message
///message victim gets when the chemical transfer procs
var/victim_message
/datum/element/chemical_transfer/Attach(datum/target, attacker_message = DEFAULT_ATTACKER_MESSAGE, victim_message = DEFAULT_VICTIM_MESSAGE, transfer_prob = 100)
. = ..()
if(!isitem(target))
return ELEMENT_INCOMPATIBLE
src.transfer_prob = transfer_prob
src.attacker_message = attacker_message
src.victim_message = victim_message
RegisterSignal(target, COMSIG_ITEM_ATTACK, PROC_REF(on_attack))
RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
/datum/element/chemical_transfer/Detach(datum/target)
. = ..()
UnregisterSignal(target, list(COMSIG_ITEM_ATTACK, COMSIG_ATOM_EXAMINE))
///signal called on parent being examined
/datum/element/chemical_transfer/proc/on_examine(datum/target, mob/user, list/examine_list)
SIGNAL_HANDLER
var/probability_description
switch(transfer_prob)
if(1 to 25)
probability_description = "rarely"
if(26 to 66)
probability_description = "sometimes"
if(67 to 99)
probability_description = "often"
if(100)
probability_description = "always"
examine_list += span_notice("Attacking with [target] will [probability_description] transfer reagents inside of you to your victim.")
///signal called on parent being used to attack a victim
/datum/element/chemical_transfer/proc/on_attack(datum/target, mob/living/transfer_victim, mob/living/transfer_attacker)
SIGNAL_HANDLER
if(!istype(transfer_attacker) || !prob(transfer_prob))
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, transferred_by = transfer_attacker)
to_chat(transfer_attacker, built_attacker_message)
to_chat(transfer_victim, built_victim_message)
#undef DEFAULT_ATTACKER_MESSAGE
#undef DEFAULT_VICTIM_MESSAGE