mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 08:08:49 +01:00
[MIRROR] Refactors operating tables to be event driven + QoL + Unit Test [MDB IGNORE] (#15572)
* Refactors operating tables to be event driven + QoL + Unit Test (#69015) * Event driven table * Operating computer fix + loosening of check * Unit testing * IT NEEDS TO BE FORCE MOVE YOU GOTTA CLIMB TABLES AAAAH * Migrated patient to carbon instead of human Has no real bearing on the experiments tbh * DNAs can be null apparently * Simplify replacement code * Move comments * Refactors operating tables to be event driven + QoL + Unit Test * Refactors operating tables to be event driven + QoL + Unit Test Co-authored-by: vincentiusvin <54709710+vincentiusvin@users.noreply.github.com> Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>
This commit is contained in:
co-authored by
vincentiusvin
Tom
parent
89f64af148
commit
ea67bfb4d4
@@ -91,10 +91,10 @@
|
||||
return data
|
||||
|
||||
data["table"] = table
|
||||
if(!table.check_eligible_patient())
|
||||
return data
|
||||
data["patient"] = list()
|
||||
var/mob/living/carbon/human/patient = table.patient
|
||||
if(!table.patient)
|
||||
return data
|
||||
var/mob/living/carbon/patient = table.patient
|
||||
|
||||
switch(patient.stat)
|
||||
if(CONSCIOUS)
|
||||
@@ -110,7 +110,7 @@
|
||||
data["patient"]["stat"] = "Dead"
|
||||
data["patient"]["statstate"] = "bad"
|
||||
data["patient"]["health"] = patient.health
|
||||
data["patient"]["blood_type"] = patient.dna.blood_type
|
||||
data["patient"]["blood_type"] = patient.dna?.blood_type
|
||||
data["patient"]["maxHealth"] = patient.maxHealth
|
||||
data["patient"]["minHealth"] = HEALTH_THRESHOLD_DEAD
|
||||
data["patient"]["bruteLoss"] = patient.getBruteLoss()
|
||||
|
||||
@@ -687,7 +687,7 @@
|
||||
buckle_lying = 90 // SKYRAT EDIT old: NO_BUCKLE_LYING
|
||||
buckle_requires_restraints = FALSE // SKYRAT EDIT old: TRUE
|
||||
custom_materials = list(/datum/material/silver = 2000)
|
||||
var/mob/living/carbon/human/patient = null
|
||||
var/mob/living/carbon/patient = null
|
||||
var/obj/machinery/computer/operating/computer = null
|
||||
|
||||
/obj/structure/table/optable/Initialize(mapload)
|
||||
@@ -697,44 +697,57 @@
|
||||
if(computer)
|
||||
computer.table = src
|
||||
break
|
||||
RegisterSignal(loc, COMSIG_ATOM_ENTERED, .proc/mark_patient)
|
||||
RegisterSignal(loc, COMSIG_ATOM_EXITED, .proc/unmark_patient)
|
||||
|
||||
/obj/structure/table/optable/Destroy()
|
||||
. = ..()
|
||||
if(computer && computer.table == src)
|
||||
computer.table = null
|
||||
patient = null
|
||||
UnregisterSignal(loc, COMSIG_ATOM_ENTERED)
|
||||
UnregisterSignal(loc, COMSIG_ATOM_EXITED)
|
||||
return ..()
|
||||
|
||||
/obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob)
|
||||
pushed_mob.forceMove(loc)
|
||||
pushed_mob.set_resting(TRUE, TRUE)
|
||||
visible_message(span_notice("[user] lays [pushed_mob] on [src]."))
|
||||
get_patient()
|
||||
|
||||
/obj/structure/table/optable/proc/get_patient()
|
||||
var/mob/living/carbon/M = locate(/mob/living/carbon) in loc
|
||||
if(M)
|
||||
if(M.resting)
|
||||
set_patient(M)
|
||||
else
|
||||
set_patient(null)
|
||||
|
||||
/obj/structure/table/optable/proc/set_patient(new_patient)
|
||||
if(patient)
|
||||
UnregisterSignal(patient, COMSIG_PARENT_QDELETING)
|
||||
patient = new_patient
|
||||
if(patient)
|
||||
RegisterSignal(patient, COMSIG_PARENT_QDELETING, .proc/patient_deleted)
|
||||
|
||||
/obj/structure/table/optable/proc/patient_deleted(datum/source)
|
||||
/// Any mob that enters our tile will be marked as a potential patient. They will be turned into a patient if they lie down.
|
||||
/obj/structure/table/optable/proc/mark_patient(datum/source, mob/living/carbon/potential_patient)
|
||||
SIGNAL_HANDLER
|
||||
set_patient(null)
|
||||
if(!istype(potential_patient))
|
||||
return
|
||||
RegisterSignal(potential_patient, COMSIG_LIVING_SET_BODY_POSITION, .proc/recheck_patient)
|
||||
recheck_patient(potential_patient) // In case the mob is already lying down before they entered.
|
||||
|
||||
/obj/structure/table/optable/proc/check_eligible_patient()
|
||||
get_patient()
|
||||
if(!patient)
|
||||
return FALSE
|
||||
if(ishuman(patient))
|
||||
return TRUE
|
||||
return FALSE
|
||||
/// Unmark the potential patient.
|
||||
/obj/structure/table/optable/proc/unmark_patient(datum/source, mob/living/carbon/potential_patient)
|
||||
SIGNAL_HANDLER
|
||||
if(!istype(potential_patient))
|
||||
return
|
||||
if(potential_patient == patient)
|
||||
recheck_patient(patient) // Can just set patient to null, but doing the recheck lets us find a replacement patient.
|
||||
UnregisterSignal(potential_patient, COMSIG_LIVING_SET_BODY_POSITION)
|
||||
|
||||
/// Someone on our tile just lied down, got up, moved in, or moved out.
|
||||
/// potential_patient is the mob that had one of those four things change.
|
||||
/// The check is a bit broad so we can find a replacement patient.
|
||||
/obj/structure/table/optable/proc/recheck_patient(mob/living/carbon/potential_patient)
|
||||
SIGNAL_HANDLER
|
||||
if(patient && patient != potential_patient)
|
||||
return
|
||||
|
||||
if(potential_patient.body_position == LYING_DOWN && potential_patient.loc == loc)
|
||||
patient = potential_patient
|
||||
return
|
||||
|
||||
// Find another lying mob as a replacement.
|
||||
for (var/mob/living/carbon/replacement_patient in loc.contents)
|
||||
if(replacement_patient.body_position == LYING_DOWN)
|
||||
patient = replacement_patient
|
||||
return
|
||||
patient = null
|
||||
|
||||
/*
|
||||
* Racks
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
#include "ntnetwork_tests.dm"
|
||||
#include "nuke_cinematic.dm"
|
||||
#include "objectives.dm"
|
||||
#include "operating_table.dm"
|
||||
#include "outfit_sanity.dm"
|
||||
#include "paintings.dm"
|
||||
#include "pills.dm"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/// Make a mob hop on an optable, rest, get up, rest again, and then move to another tile.
|
||||
/// While the mob is still an active patient, move another mob in too.
|
||||
/// This is so the replacement code can kick in when the original mob is no longer valid.
|
||||
/datum/unit_test/operating_table
|
||||
|
||||
/datum/unit_test/operating_table/Run()
|
||||
var/obj/structure/table/optable/table = allocate(/obj/structure/table/optable)
|
||||
var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human, get_step(table, NORTH))
|
||||
var/mob/living/carbon/human/replacement_human = allocate(/mob/living/carbon/human, get_step(table, NORTH))
|
||||
|
||||
// Resting is a bit more high level than bodypos, gets us nicer coverage.
|
||||
human.set_resting(new_resting = FALSE, instant = TRUE)
|
||||
replacement_human.set_resting(new_resting = FALSE, instant = TRUE)
|
||||
|
||||
human.forceMove(get_turf(table))
|
||||
TEST_ASSERT_NULL(table.patient, "Operating table is occupied by a non-resting patient.")
|
||||
|
||||
human.set_resting(new_resting = TRUE, instant = TRUE)
|
||||
TEST_ASSERT_EQUAL(table.patient, human, "Operating table failed to update for a resting patient.")
|
||||
|
||||
human.set_resting(new_resting = FALSE, instant = TRUE)
|
||||
TEST_ASSERT_NULL(table.patient, "Operating table is occupied by a non-resting patient.")
|
||||
|
||||
human.set_resting(new_resting = TRUE, instant = TRUE)
|
||||
TEST_ASSERT_EQUAL(table.patient, human, "Operating table failed to update for a resting patient.")
|
||||
|
||||
replacement_human.forceMove(get_turf(table))
|
||||
replacement_human.set_resting(new_resting = TRUE, instant = TRUE)
|
||||
TEST_ASSERT_EQUAL(table.patient, human, "Operating table patient unset by another patient jumping in.")
|
||||
|
||||
human.forceMove(get_step(get_turf(table), NORTH))
|
||||
TEST_ASSERT_EQUAL(table.patient, replacement_human, "Operating table failed to find a replacement patient.")
|
||||
@@ -36,11 +36,11 @@
|
||||
REMOVE_TRAIT(target, TRAIT_NUMBED, REF(src))
|
||||
|
||||
/obj/structure/table/optable/post_buckle_mob(mob/living/patient)
|
||||
set_patient(patient)
|
||||
mark_patient(potential_patient = patient)
|
||||
if(numbing_capable)
|
||||
chill_out(patient)
|
||||
|
||||
/obj/structure/table/optable/post_unbuckle_mob(mob/living/patient)
|
||||
set_patient(null)
|
||||
unmark_patient(potential_patient = patient)
|
||||
if(numbing_capable)
|
||||
thaw_them(patient)
|
||||
|
||||
@@ -55,13 +55,13 @@ const PatientStateView = (props, context) => {
|
||||
return (
|
||||
<>
|
||||
<Section title="Patient State">
|
||||
{(patient && (
|
||||
{Object.keys(patient).length ? (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="State" color={patient.statstate}>
|
||||
{patient.stat}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Blood Type">
|
||||
{patient.blood_type}
|
||||
{patient.blood_type || 'Unable to determine blood type'}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Health">
|
||||
<ProgressBar
|
||||
@@ -82,8 +82,9 @@ const PatientStateView = (props, context) => {
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
)) ||
|
||||
'No Patient Detected'}
|
||||
) : (
|
||||
'No Patient Detected'
|
||||
)}
|
||||
</Section>
|
||||
{procedures.length === 0 && <Section>No Active Procedures</Section>}
|
||||
{procedures.map((procedure) => (
|
||||
|
||||
Reference in New Issue
Block a user