mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-29 03:32:28 +00:00
* Initial commit Fixes up surgery.dm Adds some tool behavior * More basic changes * Checkpointing: this is a little gross right now * Add signal COMPONENT_CANCEL_ATTACK_CHAIN * Cleans up surgery initiator * Mostly gets surgery (and canceling it) working * Add abstract proxy surgery steps Also adds them to organ manipulation * Clean up most existing surgeries * Rework organ openness, adds define for aborting a beginstep * surgery works again, also implements retry defines * fix surgery computer * add limb repair to synth implant removal * retry implant checks * Clean up abductor surgeries as well as some other things * A lot - Reworks organ manipulation to use a series of surgery steps instead - Fixes some runtimes with open hands - Lets mito zero out the germ level while treating necrosis - Adds a debug surgery tool * add debug surgery tool, note some TODOs for later * Add conditional check for surgeries repeating * update surgery retry logic to make it more of a bonus * Lets abductors automatically retry any failed surgery steps * Rework robotic surgery to use abstract/proxy steps * Bunch of bugfixes and more! - Limb reattachment works properly now, you can just slap a limb onto a person - If the limb isn't robotic, it'll be useless until the surgery is finished with a hemostat, though it might be enough to get the patient out of the OR. * Remove more now-implicit checks * Slight reorganization * more fixes across the board * Remove unused variable * Trying not to lose my mind here - Does away with can_run() entirely - Cleans up visible messages in code - begin steps should now all have ..() afterwards - slime bone surgery should be fixed now - more docs * Robotic surgery is stoppable with a crowbar, all surgery can_start now checks parent * Fix some broken robotic typepaths * Typepath fixes, do away with some last TODOs * Forgor * Last cleanups before we go gold * jk lol * Make early surgery termination clearer * More "last" cleanups * Fixes tool flags, surgery initiation - Fixes surgery not being startable by sharp objects - Moves surgical tool flags to item traits * Clean up surgery cancellation, especially for borgos * I think this should GC better * Apply suggestions from code review Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com> * Status is now step number * Add a 20% chance to find nothing during organ manipulation * Improve documentation, make forced_surgery a normal arg * Charlie's reviews * Why are abductors like this * Little more verification, ensuring limb augmentation and organ manip healing work properly * Fix torso organ manip being unfinishable * Fix cavity implants, open-hand/any item steps * Make sharp objects not try to start an operation with help intent * Comments, quick target fix * Re-order list so advanced bruise pack is pulled first * Make surgical gripper function like an open hand * Make mito only use one unit per organ for now * Check if user is on operable surface before trying to operate * Reduce admin logging * Fix some bugs that appeared during the testmerge - you can no longer start robotic surgeries with a scalpel (lol) - you can now cancel surgeries on the first step after I fixed some bugs that I introduced (woo hoo) - Synthetic limb attachment is now combined into a single startable surgery step, though still retains the fun flavor of both * Swats some more bugs - (hopefully) fixes a huge source of runtimes where we tried to check if we could run surgeries before checking if the surgery used an organ - In doing so, moves the logic for determining if a surgery can start to the mob-level - Fixes robotic reattachment surgery not working * multi-bug drifting??? - Fixes a bug where a branching surgery with an any tool option could possibly override a step with a matching tool - Fixes some intermediate surgeries failing due to not having specified possible_locs * A few more fixes - Fixes any surgery tool steps again - Fixes cavity surgery again * Hopefully fixes getting stuck in robotic organ manip * Remove extra parent call * Steel review * Steel review * Fix spacing for possible locs * Roundstart traits * Advanced surgical traits and other hal fixes Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>
217 lines
7.8 KiB
Plaintext
217 lines
7.8 KiB
Plaintext
#define OP_COMPUTER_COOLDOWN 60
|
|
|
|
/obj/machinery/computer/operating
|
|
name = "operating computer"
|
|
density = TRUE
|
|
anchored = TRUE
|
|
icon_keyboard = "med_key"
|
|
icon_screen = "crew"
|
|
circuit = /obj/item/circuitboard/operating
|
|
light_color = LIGHT_COLOR_PURE_BLUE
|
|
var/obj/machinery/optable/table
|
|
var/verbose = TRUE //general speaker toggle
|
|
var/oxyAlarm = 30 //oxy damage at which the computer will beep
|
|
var/choice = FALSE //just for going into and out of the options menu
|
|
var/healthAnnounce = TRUE //healther announcer toggle
|
|
var/crit = TRUE //crit beeping toggle
|
|
var/nextTick = OP_COMPUTER_COOLDOWN
|
|
var/healthAlarm = 50
|
|
var/oxy = TRUE //oxygen beeping toggle
|
|
/// Who is on the Operating Table connected to the respective Operating Computer?
|
|
/// Only used to see if it changed from the previous occupant. If you want any actual information
|
|
/// about the mob - use `table.patient` instead.
|
|
var/mob/living/carbon/currentPatient
|
|
var/patientStatusHolder //Hold the last instance of table.patient.status. When table.patient.status no longer matches this variable, the computer should tell the doctor
|
|
|
|
/obj/machinery/computer/operating/Initialize(mapload)
|
|
. = ..()
|
|
table = locate(/obj/machinery/optable, orange(1, src))
|
|
if(table)
|
|
table.computer = src
|
|
|
|
/obj/machinery/computer/operating/Destroy()
|
|
if(table)
|
|
table.computer = null
|
|
table = null
|
|
if(currentPatient)
|
|
currentPatient = null
|
|
return ..()
|
|
|
|
/obj/machinery/computer/operating/detailed_examine()
|
|
return "This console gives information on the status of the patient on the adjacent operating table, notably their consciousness."
|
|
|
|
/obj/machinery/computer/operating/attack_ai(mob/user)
|
|
add_fingerprint(user)
|
|
if(stat & (BROKEN|NOPOWER))
|
|
return
|
|
ui_interact(user)
|
|
|
|
/obj/machinery/computer/operating/attack_hand(mob/user)
|
|
if(..(user))
|
|
return
|
|
|
|
if(stat & (NOPOWER|BROKEN))
|
|
return
|
|
|
|
add_fingerprint(user)
|
|
ui_interact(user)
|
|
|
|
/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
|
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
|
if(!ui)
|
|
ui = new(user, src, ui_key, "OperatingComputer", "Patient Monitor", 650, 455, master_ui, state)
|
|
ui.open()
|
|
|
|
/obj/machinery/computer/operating/ui_data(mob/user)
|
|
var/list/data = list()
|
|
var/mob/living/carbon/human/occupant
|
|
if(table)
|
|
occupant = table.patient
|
|
data["hasOccupant"] = occupant ? 1 : 0
|
|
var/occupantData[0]
|
|
|
|
if(occupant)
|
|
occupantData["name"] = occupant.name
|
|
occupantData["stat"] = occupant.stat
|
|
occupantData["health"] = occupant.health
|
|
occupantData["maxHealth"] = occupant.maxHealth
|
|
occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD
|
|
occupantData["bruteLoss"] = occupant.getBruteLoss()
|
|
occupantData["oxyLoss"] = occupant.getOxyLoss()
|
|
occupantData["toxLoss"] = occupant.getToxLoss()
|
|
occupantData["fireLoss"] = occupant.getFireLoss()
|
|
occupantData["paralysis"] = occupant.AmountParalyzed()
|
|
occupantData["hasBlood"] = 0
|
|
occupantData["bodyTemperature"] = occupant.bodytemperature
|
|
occupantData["maxTemp"] = 1000 // If you get a burning vox armalis into the sleeper, congratulations
|
|
// Because we can put simple_animals in here, we need to do something tricky to get things working nice
|
|
occupantData["temperatureSuitability"] = 0 // 0 is the baseline
|
|
if(ishuman(occupant) && occupant.dna.species)
|
|
var/datum/species/sp = occupant.dna.species
|
|
if(occupant.bodytemperature < sp.cold_level_3)
|
|
occupantData["temperatureSuitability"] = -3
|
|
else if(occupant.bodytemperature < sp.cold_level_2)
|
|
occupantData["temperatureSuitability"] = -2
|
|
else if(occupant.bodytemperature < sp.cold_level_1)
|
|
occupantData["temperatureSuitability"] = -1
|
|
else if(occupant.bodytemperature > sp.heat_level_3)
|
|
occupantData["temperatureSuitability"] = 3
|
|
else if(occupant.bodytemperature > sp.heat_level_2)
|
|
occupantData["temperatureSuitability"] = 2
|
|
else if(occupant.bodytemperature > sp.heat_level_1)
|
|
occupantData["temperatureSuitability"] = 1
|
|
else if(istype(occupant, /mob/living/simple_animal))
|
|
var/mob/living/simple_animal/silly = occupant
|
|
if(silly.bodytemperature < silly.minbodytemp)
|
|
occupantData["temperatureSuitability"] = -3
|
|
else if(silly.bodytemperature > silly.maxbodytemp)
|
|
occupantData["temperatureSuitability"] = 3
|
|
// Blast you, imperial measurement system
|
|
occupantData["btCelsius"] = occupant.bodytemperature - T0C
|
|
occupantData["btFaren"] = ((occupant.bodytemperature - T0C) * (9.0/5.0))+ 32
|
|
|
|
if(ishuman(occupant) && !(NO_BLOOD in occupant.dna.species.species_traits))
|
|
occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL)
|
|
occupantData["hasBlood"] = 1
|
|
occupantData["bloodLevel"] = round(occupant.blood_volume)
|
|
occupantData["bloodMax"] = occupant.max_blood
|
|
occupantData["bloodPercent"] = round(100*(occupant.blood_volume/occupant.max_blood), 0.01) //copy pasta ends here
|
|
|
|
occupantData["bloodType"] = occupant.dna.blood_type
|
|
if(length(occupant.surgeries))
|
|
occupantData["inSurgery"] = 1
|
|
for(var/datum/surgery/procedure in occupant.surgeries)
|
|
occupantData["surgeryName"] = "[capitalize(procedure.name)]"
|
|
var/datum/surgery_step/surgery_step = procedure.get_surgery_step()
|
|
var/surgery_desc = "[capitalize(surgery_step.get_step_information(procedure))]"
|
|
if(surgery_step.repeatable)
|
|
var/datum/surgery_step/next = procedure.get_surgery_next_step()
|
|
if(next)
|
|
surgery_desc += " or [capitalize(next.get_step_information(procedure))]"
|
|
occupantData["stepName"] = surgery_desc
|
|
|
|
data["occupant"] = occupantData
|
|
data["verbose"] = verbose
|
|
data["oxyAlarm"] = oxyAlarm
|
|
data["choice"] = choice
|
|
data["health"] = healthAnnounce
|
|
data["crit"] = crit
|
|
data["healthAlarm"] = healthAlarm
|
|
data["oxy"] = oxy
|
|
|
|
return data
|
|
|
|
|
|
/obj/machinery/computer/operating/ui_act(action, params)
|
|
if(..())
|
|
return
|
|
|
|
if(stat & (NOPOWER|BROKEN))
|
|
return
|
|
|
|
. = TRUE
|
|
switch(action)
|
|
if("verboseOn")
|
|
verbose = TRUE
|
|
if("verboseOff")
|
|
verbose = FALSE
|
|
if("healthOn")
|
|
healthAnnounce = TRUE
|
|
if("healthOff")
|
|
healthAnnounce = FALSE
|
|
if("critOn")
|
|
crit = TRUE
|
|
if("critOff")
|
|
crit = FALSE
|
|
if("oxyOn")
|
|
oxy = TRUE
|
|
if("oxyOff")
|
|
oxy = FALSE
|
|
if("oxy_adj")
|
|
oxyAlarm = clamp(text2num(params["new"]), -100, 100)
|
|
if("choiceOn")
|
|
choice = TRUE
|
|
if("choiceOff")
|
|
choice = FALSE
|
|
if("health_adj")
|
|
healthAlarm = clamp(text2num(params["new"]), -100, 100)
|
|
else
|
|
return FALSE
|
|
|
|
/obj/machinery/computer/operating/process()
|
|
if(!table) //Does this Operating Computer have an Operating Table connected to it?
|
|
return
|
|
if(!verbose) //Are the speakers on?
|
|
return
|
|
if(!table.patient) //Is there a patient on the table?
|
|
currentPatient = null
|
|
return
|
|
var/patientStatus // Tell the computer what to say based on the status of the patient on the table.
|
|
var/isNewPatient = (table.patient != currentPatient) //Is this a new Patient?
|
|
|
|
if(table.patient.stat == DEAD || HAS_TRAIT(table.patient, TRAIT_FAKEDEATH))
|
|
patientStatus = "Dead"
|
|
else if(table.patient.stat == CONSCIOUS)
|
|
patientStatus = "Awake"
|
|
else if(table.patient.stat == UNCONSCIOUS)
|
|
patientStatus = "Asleep"
|
|
|
|
if(isNewPatient)
|
|
atom_say("New patient detected, loading stats")
|
|
atom_say("[table.patient], [table.patient.dna.blood_type] blood, [patientStatus]")
|
|
SStgui.update_uis(src)
|
|
patientStatusHolder = table.patient.stat
|
|
currentPatient = table.patient
|
|
|
|
if(nextTick < world.time)
|
|
nextTick=world.time + OP_COMPUTER_COOLDOWN
|
|
if(crit && table.patient.health <= -50 )
|
|
playsound(src.loc, 'sound/machines/defib_success.ogg', 50, 0)
|
|
if(oxy && table.patient.getOxyLoss()>oxyAlarm)
|
|
playsound(src.loc, 'sound/machines/defib_saftyoff.ogg', 50, 0)
|
|
if(healthAnnounce && table.patient.health <= healthAlarm)
|
|
atom_say("[round(table.patient.health)]")
|
|
if(table.patient.stat != patientStatusHolder)
|
|
atom_say("Patient is now [patientStatus]")
|
|
patientStatusHolder = table.patient.stat
|