# Medical machine and IV drip harmonization
###### tags: `design-doc` `gooncode`
:::info
Feel free to make good-faith edits and comments to this design document as necessary.
:::
[toc]
## Introduction
- IV drips implement similar behaviour to dialysis machines and the abstract `/obj/machinery/medical` type.
- See [#24860.](https://github.com/goonstation/goonstation/pull/24860)
- Lots of identical, copy-pasted code.
- This increases technical debt and difficulty to make improvements to either system.
- Replacement of shared functionality with components is required.
- Objects which share these behaviours henceforth referred to as "(medical) equipment".
## Current Functionality
### IV drip similarities with medical machines
#### `/obj/machinery/medical`
- "Patient" concept; each object is connected to one patient.
- `mob/living` attempting to connect a new patient `mob/living/carbon` to a equipment.
- Click-drag `mob/living/carbon` onto medical equipment.
- Fail if Manhattan distance between equipment and new patient `>1`.
- Actionbar to successfully connect.
- Sucessfully connecting a new patient `mob/living/carbon` to a equipment.
- Disconnecting the connected patient from a equipment (by a `mob/living` or otherwise).
- Check that distance between a equipment and its patient `<= 1` when either moves/sets new `loc`.
- Forcefully removing patient from a equipment if distance `>1`. UNLESS pulling/pushing in which case god help you there's `src.can_push_or_pull()`
- Can impart an effect onto patient with each process tick.
- `/obj/machinery/medical`: `processing_machines`.
- `/obj/item/reagent_containers/glass/iv_drip`: `processing_items`.
- **N.B. `processing_machines` has `mult` support, `processing_items` does NOT.**
- Distinction between if patient connected and if equipment is `active`/currently imparting an effect.
#### `/obj/machinery/medical/blood`
- Utilises internal reagent container.
- Infuse fluid into patient.
- Fail if patient's reagents capped.
- Draw blood from patient.
- Fail if no patient fluid volume.
- Calculate fluid transfer volumes accounting for `mult`.
### Unique functionality
#### `/obj/machinery/medical`
- Can connect to station objects (beds, optables, chairs).
- Relies on power availability to activate.
#### `/obj/machinery/medical/blood`
- Variable fluid transfer volume.
- Helper procs `get_patient_blood_volume()` and `get_patient_fluid_volume()` used for dialysis as it will not operate on hypovolemic patients and will combat hypertension.
#### `/obj/machinery/medical/blood/iv_stand`
- Unique in being the only medical machine that takes some other medical object (IV drips) and applies their effect onto that IV drip's patient.
- A nightmare in that patients and mutual references between the IV drip and stand need to be managed somewhere.
#### `/obj/item/reagent_containers/glass/iv_drip`
- Switch inject/draw at will.
- IV drips explicitly increases patient blood absorption rate to `*3` of standard.
- Will transfuse independent of active status of attached IV stand.
- If the attached IV stand is disabled, move to `processing_items` and continue transfusion at default rate (5u).
- Otherwise, hitch onto `processing_machines` and transfuse at the rate set by the IV stand.
# Design
### `/datum/medical_equipment`
- All objects with previous medical machinery/IV drip behaviour now contain this datum.
- Manages the connection between a patient and a equipment.
- (Attempted) connection of patients to parent equipment.
- Disconnection of patient.
- Checking connection on patient/equipment movement.
- Status effect to provide visual feedback on connection.
- Chat log feedback.
- Effects determined by contained `/datum/component/medical_function`s.
- Can be subordinate to each other.
- e.g. IV stands will take over management of patients; applying effects from any attached IV drips.
- When subordinate, attempting to manage a patient with a lower level equipment should fail.
### `/datum/medical_equipment_function`
- ~~Defines verbs and nouns for chat log feedback on `/datum/medical_equipment` connection management.~~
- Override for each piece of equipment, `/datum/medical_equipment::functions` is a list.
- Defines forceful disconnection consequences.
- Defines if this function operates independently of power availability.
- Equipment may operate at lower effectiveness without power (IV stand exclusive)
### `/datum/medical_equipment_function/blood_transfuser`
- Transfusion of blood and fluid between a referenced reagent container in a equipment and its patient.
- Inject/draw toggle.
- `transfer_volume`: Units per tick to transfer.
- `transfer_volume_unpowered`: If unpowered and defined, fall back on this. Only if it can operate without power.
- Patient blood and fluid volume helpers.
### `/datum/medical_equipment_function/blood_transfuser/dialysis`
- Scrubbing functionality.
- Destroy chems outside of a given whitelist.
- EMAG reverses scrubbing function: destroying all chems in the whitelist.
- Transfusion procs use the maximum volume of the equipment's reagent container.
- All reagents purged from equipment's reagent container on infusion.
## Objects
### `/obj/item/reagent_containers/glass/iv_drip`
- `/datum/medical_equipment_function/blood_transfuser`
- Icon management
- IV bag label
- Using `/obj/overlay` to display inject/draw status.
- Cuts down on `SPAWN` abuse.
### `/obj/machinery/medical/`
- Brakes.
- Attachment to/detachment from whitelisted objects.
- Spoken feedback on signal from `/datum/medical_equipment`.