Merge pull request #3356 from pinatacolada/master

Makes the surgery computer useful
This commit is contained in:
Fox McCloud
2016-01-31 19:27:03 -05:00
3 changed files with 408 additions and 41 deletions
+163 -41
View File
@@ -1,4 +1,5 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
#define OP_COMPUTER_COOLDOWN 60
/obj/machinery/computer/operating
name = "operating computer"
@@ -7,10 +8,18 @@
icon_keyboard = "med_key"
icon_screen = "crew"
circuit = /obj/item/weapon/circuitboard/operating
var/mob/living/carbon/human/victim = null
var/obj/machinery/optable/table = null
var/mob/living/carbon/human/victim = null
light_color = LIGHT_COLOR_PURE_BLUE
var/verbose = 1 //general speaker toggle
var/patientName = null
var/oxyAlarm = 30 //oxy damage at which the computer will beep
var/choice = 0 //just for going into and out of the options menu
var/healthAnnounce = 1 //healther announcer toggle
var/crit = 1 //crit beeping toggle
var/nextTick = OP_COMPUTER_COOLDOWN
var/healthAlarm = 50
var/oxy = 1 //oxygen beeping toggle
/obj/machinery/computer/operating/New()
..()
@@ -24,7 +33,7 @@
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER))
return
interact(user)
ui_interact(user)
/obj/machinery/computer/operating/attack_hand(mob/user)
@@ -36,45 +45,119 @@
add_fingerprint(user)
interact(user)
ui_interact(user)
///obj/machinery/computer/operating/interact(mob/user)
// if ( ((get_dist(src, user) > 1) && !isobserver(user)) || (stat & (BROKEN|NOPOWER)) )
// if (!istype(user, /mob/living/silicon))
// user.unset_machine()
// user << browse(null, "window=op")
// return
//
// user.set_machine(src)
// var/dat = "<HEAD><TITLE>Operating Computer</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
// dat += "<A HREF='?src=\ref[user];mach_close=op'>Close</A><br><br>" //| <A HREF='?src=\ref[user];update=1'>Update</A>"
// if(src.table && (src.table.check_victim()))
// src.victim = src.table.victim
// dat += {"
//<B>Patient Information:</B><BR>
//<BR>
//<B>Name:</B> [src.victim.real_name]<BR>
//<B>Age:</B> [src.victim.age]<BR>
//<B>Blood Type:</B> [src.victim.b_type]<BR>
//<BR>
//<B>Health:</B> [src.victim.health]<BR>
//<B>Brute Damage:</B> [src.victim.getBruteLoss()]<BR>
//<B>Toxins Damage:</B> [src.victim.getToxLoss()]<BR>
//<B>Fire Damage:</B> [src.victim.getFireLoss()]<BR>
//<B>Suffocation Damage:</B> [src.victim.getOxyLoss()]<BR>
//<B>Patient Status:</B> [src.victim.stat ? "Non-Responsive" : "Awake"]<BR>
//<B>Heartbeat rate:</B> [victim.get_pulse(GETPULSE_TOOL)]<BR>
//"}
// else
// src.victim = null
// dat += {"
//<B>Patient Information:</B><BR>
//<BR>
//<B>No Patient Detected</B>
//"}
// user << browse(dat, "window=op")
// onclose(user, "op")
/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)//ui is mostly copy pasta from the sleeper ui
var/data[0]
var/mob/living/carbon/human/occupant = src.table.victim
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"] = config.health_threshold_dead
occupantData["bruteLoss"] = occupant.getBruteLoss()
occupantData["oxyLoss"] = occupant.getOxyLoss()
occupantData["toxLoss"] = occupant.getToxLoss()
occupantData["fireLoss"] = occupant.getFireLoss()
occupantData["paralysis"] = occupant.paralysis
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.species)
var/datum/species/sp = occupant.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) && occupant.vessel && !(occupant.species && occupant.species.flags & NO_BLOOD))
occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL)
occupantData["hasBlood"] = 1
occupantData["bloodLevel"] = round(occupant.vessel.get_reagent_amount("blood"))
occupantData["bloodMax"] = occupant.max_blood
occupantData["bloodPercent"] = round(100*(occupant.vessel.get_reagent_amount("blood")/occupant.max_blood), 0.01) //copy pasta ends here
occupantData["bloodType"]=occupant.b_type
data["occupant"] = occupantData
data["verbose"]=verbose
data["oxyAlarm"]=oxyAlarm
data["choice"]=choice
data["health"]=healthAnnounce
data["crit"]=crit
data["healthAlarm"]=healthAlarm
data["oxy"]=oxy
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "op_computer.tmpl", "Patient Monitor", 650, 455)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/operating/interact(mob/user)
if ( ((get_dist(src, user) > 1) && !isobserver(user)) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.unset_machine()
user << browse(null, "window=op")
return
user.set_machine(src)
var/dat = "<HEAD><TITLE>Operating Computer</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
dat += "<A HREF='?src=\ref[user];mach_close=op'>Close</A><br><br>" //| <A HREF='?src=\ref[user];update=1'>Update</A>"
if(src.table && (src.table.check_victim()))
src.victim = src.table.victim
dat += {"
<B>Patient Information:</B><BR>
<BR>
<B>Name:</B> [src.victim.real_name]<BR>
<B>Age:</B> [src.victim.age]<BR>
<B>Blood Type:</B> [src.victim.b_type]<BR>
<BR>
<B>Health:</B> [src.victim.health]<BR>
<B>Brute Damage:</B> [src.victim.getBruteLoss()]<BR>
<B>Toxins Damage:</B> [src.victim.getToxLoss()]<BR>
<B>Fire Damage:</B> [src.victim.getFireLoss()]<BR>
<B>Suffocation Damage:</B> [src.victim.getOxyLoss()]<BR>
<B>Patient Status:</B> [src.victim.stat ? "Non-Responsive" : "Stable"]<BR>
<B>Heartbeat rate:</B> [victim.get_pulse(GETPULSE_TOOL)]<BR>
"}
else
src.victim = null
dat += {"
<B>Patient Information:</B><BR>
<BR>
<B>No Patient Detected</B>
"}
user << browse(dat, "window=op")
onclose(user, "op")
/obj/machinery/computer/operating/Topic(href, href_list)
@@ -82,9 +165,48 @@
return 1
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
if(href_list["verboseOn"])
verbose=1
if(href_list["verboseOff"])
verbose=0
if(href_list["healthOn"])
healthAnnounce=1
if(href_list["healthOff"])
healthAnnounce=0
if(href_list["critOn"])
crit=1
if(href_list["critOff"])
crit=0
if(href_list["oxyOn"])
oxy=1
if(href_list["oxyOff"])
oxy=0
if(href_list["oxy_adj"]!=0)
oxyAlarm=oxyAlarm+text2num(href_list["oxy_adj"])
if(href_list["choiceOn"])
choice=1
if(href_list["choiceOff"])
choice=0
if(href_list["health_adj"]!=0)
healthAlarm=healthAlarm+text2num(href_list["health_adj"])
return
/obj/machinery/computer/operating/process()
if(..())
src.updateDialog()
if(table && table.check_victim())
if(verbose)
if(patientName!=table.victim.name)
patientName=table.victim.name
atom_say("New patient detected, loading stats")
victim = table.victim
atom_say("[victim.real_name], [victim.b_type] blood, [victim.stat ? "Non-Responsive" : "Awake"]")
if(nextTick < world.time)
nextTick=world.time + OP_COMPUTER_COOLDOWN
if(crit && victim.health <= -50 )
playsound(src.loc, 'sound/machines/defib_success.ogg', 50, 0)
if(oxy && victim.getOxyLoss()>oxyAlarm)
playsound(src.loc, 'sound/machines/defib_saftyOff.ogg', 50, 0)
if(healthAnnounce && victim.health <= healthAlarm)
atom_say("[round(victim.health)]")
@@ -0,0 +1,37 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# spellcheck (typo fixes)
# experiment
#################################
# Your name. Remove the quotation mark and put in your name when copy+pasting the example changelog.
author: "pinatacolada"
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Adds NanoUI to the operating computer"
- rscadd: "Adds health announcing, critical and oxygen damage aural alerts to the computer, with a menu to selectively turn them on and off"
+208
View File
@@ -0,0 +1,208 @@
<!--
Title: Operating Computer UI
Used In File(s): \code\game\machinery\computer\Operating.dm
-->
<h3>Patient Monitor</h3>
<div class="statusDisplay">
{{if data.choice==0}}
{{if !data.hasOccupant}}
<div class="line">No Patient Detected</div>
{{else}}
<div class="line">
{{:data.occupant.name}}&nbsp;=>&nbsp;
{{if data.occupant.stat == 0}}
<span class="good">Conscious</span>
{{else data.occupant.stat == 1}}
<span class="average">Unconscious</span>
{{else}}
<span class="bad">DEAD</span>
{{/if}}
</div>
<div class="line">
<div class="statusLabel">Health:</div>
{{if data.occupant.health >= data.occupant.maxHealth}}
{{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'good')}}
{{else data.occupant.health > 0}}
{{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'average')}}
{{else data.occupant.health >= data.minhealth}}
{{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'average alignRight')}}
{{else}}
{{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'bad alignRight')}}
{{/if}}
<div class="statusValue">{{:helper.round(data.occupant.health)}}</div>
</div>
<div class="line">
<div class="statusLabel">Brute Damage:</div>
{{:helper.displayBar(data.occupant.bruteLoss, 0, data.occupant.maxHealth, 'bad')}}
<div class="statusValue">{{:helper.round(data.occupant.bruteLoss)}}</div>
</div>
<div class="line">
<div class="statusLabel">Resp. Damage:</div>
{{:helper.displayBar(data.occupant.oxyLoss, 0, data.occupant.maxHealth, 'bad')}}
<div class="statusValue">{{:helper.round(data.occupant.oxyLoss)}}</div>
</div>
<div class="line">
<div class="statusLabel">Toxin Damage:</div>
{{:helper.displayBar(data.occupant.toxLoss, 0, data.occupant.maxHealth, 'bad')}}
<div class="statusValue">{{:helper.round(data.occupant.toxLoss)}}</div>
</div>
<div class="line">
<div class="statusLabel">Burn Severity:</div>
{{:helper.displayBar(data.occupant.fireLoss, 0, data.occupant.maxHealth, 'bad')}}
<div class="statusValue">{{:helper.round(data.occupant.fireLoss)}}</div>
</div>
<div class="line">
<div class="statusLabel">Patient Temperature:</div>
{{if data.occupant.temperatureSuitability == -3}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'bad')}}
<div class="statusValue bad">{{:helper.round(data.occupant.btCelsius)}}&deg;C, {{:helper.round(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == -2}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}}
<div class="statusValue bad">{{:helper.round(data.occupant.btCelsius)}}&deg;C, {{:helper.round(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == -1}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}}
<div class="statusValue">{{:helper.round(data.occupant.btCelsius)}}&deg;C, {{:helper.round(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 0}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'good')}}
<div class="statusValue">{{:helper.round(data.occupant.btCelsius)}}&deg;C, {{:helper.round(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 1}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}}
<div class="statusValue">{{:helper.round(data.occupant.btCelsius)}}&deg;C, {{:helper.round(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 2}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}}
<div class="statusValue bad">{{:helper.round(data.occupant.btCelsius)}}&deg;C, {{:helper.round(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 3}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'bad')}}
<div class="statusValue bad">{{:helper.round(data.occupant.btCelsius)}}&deg;C, {{:helper.round(data.occupant.btFaren)}}&deg;F</div>
{{/if}}
</div>
{{if data.occupant.hasBlood}}
<br>
<div class="line">
<div class="statusLabel">Blood Level:</div>
{{if data.occupant.bloodPercent <= 60}}
{{:helper.displayBar(data.occupant.bloodLevel, 0, data.occupant.bloodMax, 'bad')}}
<div class="statusValue">
{{:data.occupant.bloodPercent}}%, {{:data.occupant.bloodLevel}}cl
</div>
{{else data.occupant.bloodPercent <= 90}}
{{:helper.displayBar(data.occupant.bloodLevel, 0, data.occupant.bloodMax, 'average')}}
<div class="statusValue">
{{:data.occupant.bloodPercent}}%, {{:data.occupant.bloodLevel}}cl
</div>
{{else}}
{{:helper.displayBar(data.occupant.bloodLevel, 0, data.occupant.bloodMax, 'good')}}
<div class="statusValue">
{{:data.occupant.bloodPercent}}%, {{:data.occupant.bloodLevel}}cl
</div>
{{/if}}
<div class="line">
<div class="statusLabel">Blood Type:</div> <div class="statusValue">{{:data.occupant.bloodType}}</div>
</div>
</div>
<div class="line">
<div class="statusLabel">Pulse:</div> <div class="statusValue">{{:data.occupant.pulse}} bpm</div>
</div>
{{/if}}
<br>
<br>
{{/if}}
<div class="item">
<div class="itemLabelWide">
{{:helper.link('Options', 'gear', {'choiceOn' : 1})}}
</div>
</div>
{{else}}
<div class="item">
<div class="statusLabel">
Loudspeaker:
</div>
<div class="itemContentNarrow" style="float: left">
{{:helper.link('On', 'power-off', {'verboseOn' : 1}, data.verbose ? 'selected' : null)}}
{{:helper.link('Off', 'close', {'verboseOff' : 1}, data.verbose ? null : 'selected')}}
</div>
</div>
<br>
<div class="item">
<div class="statusLabel">
Health Announcer:
</div>
<div class="itemContentNarrow" style="float: left">
{{:helper.link('On', 'power-off', {'healthOn' : 1}, data.health ? 'selected' : null)}}
{{:helper.link('Off', 'close', {'healthOff' : 1}, data.health ? null : 'selected')}}
</div>
</div>
<div class="item">
<div class="line">
<div class="statusLabel">Health Announcer Threshold:</div>
{{:helper.link('-', null, {'health_adj' : -100}, (data.healthAlarm >= 0) ? null : 'disabled')}}
{{:helper.link('-', null, {'health_adj' : -10}, (data.healthAlarm >= -90) ? null : 'disabled')}}
{{:helper.link('-', null, {'health_adj' : -1}, (data.healthAlarm > -100) ? null : 'disabled')}}
{{if data.healthAlarm >= 100}}
{{:helper.displayBar(data.healthAlarm, 0, 100, 'good')}}
{{else data.healthAlarm > 0}}
{{:helper.displayBar(data.healthAlarm, 0, 100, 'average')}}
{{else data.healthAlarm >= -100}}
{{:helper.displayBar(data.healthAlarm, 0, -100, 'average alignRight')}}
{{else}}
{{:helper.displayBar(data.healthAlarm, 0, -100, 'bad alignRight')}}
{{/if}}
{{:helper.link('+', null, {'health_adj' : 1}, (data.healthAlarm < 100) ? null : 'disabled')}}
{{:helper.link('+', null, {'health_adj' : 10}, (data.healthAlarm <= 90) ? null : 'disabled')}}
{{:helper.link('+', null, {'health_adj' : 100}, (data.healthAlarm <= 0) ? null : 'disabled')}}
<div style="float: left; width: 80px; text-align: center;">&nbsp;{{: data.healthAlarm }} &nbsp;</div>
</div>
</div>
<br>
<div class="item">
<div class="statusLabel">
Oxygen Alarm:
</div>
<div class="itemContentNarrow" style="float: left">
{{:helper.link('On', 'power-off', {'oxyOn' : 1}, data.oxy ? 'selected' : null)}}
{{:helper.link('Off', 'close', {'oxyOff' : 1}, data.oxy ? null : 'selected')}}
</div>
</div>
<div class="item">
<div class="line">
<div class="statusLabel">Oxygen Alert Threshold:</div>
{{:helper.link('-', null, {'oxy_adj' : -100}, (data.oxyAlarm >= 100) ? null : 'disabled')}}
{{:helper.link('-', null, {'oxy_adj' : -10}, (data.oxyAlarm >= 10) ? null : 'disabled')}}
{{:helper.link('-', null, {'oxy_adj' : -1}, (data.oxyAlarm >= 0) ? null : 'disabled')}}
{{:helper.displayBar( data.oxyAlarm, 0, 200, 'good')}}
{{:helper.link('+', null, {'oxy_adj' : 1}, (data.oxyAlarm < 200) ? null : 'disabled')}}
{{:helper.link('+', null, {'oxy_adj' : 10}, (data.oxyAlarm <= 190) ? null : 'disabled')}}
{{:helper.link('+', null, {'oxy_adj' : 100}, (data.oxyAlarm <= 100) ? null : 'disabled')}}
<div style="float: left; width: 80px; text-align: center;">&nbsp;{{: data.oxyAlarm }} &nbsp;</div>
</div>
</div>
<br>
<div class="item">
<div class="statusLabel">
Critical Alert:
</div>
<div class="itemContentNarrow" style="float: left">
{{:helper.link('On', 'power-off', {'critOn' : 1}, data.crit ? 'selected' : null)}}
{{:helper.link('Off', 'close', {'critOff' : 1}, data.crit ? null : 'selected')}}
</div>
</div>
<br>
<div class="item">
<div class="itemLabelWide">
{{:helper.link('Return', 'arrow-left', {'choiceOff' : 1})}}
</div>
</div>
{{/if}}
</div>