---
# System prepended metadata

title: Medical machine and IV drip harmonization
tags: [design-doc, gooncode]

---

# 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`.