diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index fa14c1ca48..bc11bad8bc 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -78,6 +78,13 @@
#define ui_ai_multicam "SOUTH+1:6,WEST+12:16"
#define ui_ai_add_multicam "SOUTH+1:6,WEST+13:16"
+//Upper-middle right (alerts)
+#define ui_alert1 "EAST-1:28,CENTER+5:27"
+#define ui_alert2 "EAST-1:28,CENTER+4:25"
+#define ui_alert3 "EAST-1:28,CENTER+3:23"
+#define ui_alert4 "EAST-1:28,CENTER+2:21"
+#define ui_alert5 "EAST-1:28,CENTER+1:19"
+
//Gun buttons
#define ui_gun1 "EAST-2:26,SOUTH+2:7"
#define ui_gun2 "EAST-1:28, SOUTH+3:7"
@@ -96,13 +103,12 @@
#define ui_alien_oxygen "EAST-1:28,NORTH-4:25"
//Middle right (status indicators)
-#define ui_nutrition "EAST-1:28,CENTER-2:11"
-#define ui_temp "EAST-1:28,CENTER-1:13"
-#define ui_health "EAST-1:28,CENTER:15"
-#define ui_internal "EAST-1:28,CENTER+1:17"
+#define ui_temp "EAST-1:28,CENTER-2:13"
+#define ui_health "EAST-1:28,CENTER-1:15"
+#define ui_internal "EAST-1:28,CENTER:17"
//borgs
-#define ui_borg_health "EAST-1:28,CENTER-1:13" //borgs have the health display where humans have the pressure damage indicator.
-#define ui_alien_health "EAST-1:28,CENTER-1:13" //aliens have the health display where humans have the pressure damage indicator.
+#define ui_borg_health "EAST-1:28,CENTER-2:13" //borgs have the health display where humans have the pressure damage indicator.
+#define ui_alien_health "EAST-1:28,CENTER-2:13" //aliens have the health display where humans have the pressure damage indicator.
#define ui_ling_chemical_display "EAST-1:28,CENTER-3:15"
#define ui_wiz_energy_display "EAST-1:28,CENTER-3:15"
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
new file mode 100644
index 0000000000..3a7727a9f6
--- /dev/null
+++ b/code/_onclick/hud/alert.dm
@@ -0,0 +1,443 @@
+//A system to manage and display alerts on screen without needing you to do it yourself
+
+//PUBLIC - call these wherever you want
+
+
+/mob/proc/throw_alert(category, type, severity, obj/new_master)
+
+/* Proc to create or update an alert. Returns the alert if the alert is new or updated, 0 if it was thrown already
+ category is a text string. Each mob may only have one alert per category; the previous one will be replaced
+ path is a type path of the actual alert type to throw
+ severity is an optional number that will be placed at the end of the icon_state for this alert
+ For example, high pressure's icon_state is "highpressure" and can be serverity 1 or 2 to get "highpressure1" or "highpressure2"
+ new_master is optional and sets the alert's icon state to "template" in the ui_style icons with the master as an overlay.
+ Clicks are forwarded to master */
+
+ if(!category)
+ return
+
+ var/obj/screen/alert/alert
+ if(alerts[category])
+ alert = alerts[category]
+ if(new_master && new_master != alert.master)
+ WARNING("[src] threw alert [category] with new_master [new_master] while already having that alert with master [alert.master]")
+ clear_alert(category)
+ return .()
+ else if(alert.type != type)
+ clear_alert(category)
+ return .()
+ else if(!severity || severity == alert.severity)
+ if(alert.timeout)
+ clear_alert(category)
+ return .()
+ else //no need to update
+ return 0
+ else
+ alert = new type
+
+ if(new_master)
+ var/old_layer = new_master.layer
+ var/old_plane = new_master.plane
+ new_master.layer = LAYER_HUD_ABOVE
+ new_master.plane = PLANE_PLAYER_HUD_ABOVE
+ alert.overlays += new_master
+ new_master.layer = old_layer
+ new_master.plane = old_plane
+ alert.icon_state = "template" // We'll set the icon to the client's ui pref in reorganize_alerts()
+ alert.master = new_master
+ else
+ alert.icon_state = "[initial(alert.icon_state)][severity]"
+ alert.severity = severity
+
+ alerts[category] = alert
+ if(client && hud_used)
+ hud_used.reorganize_alerts()
+ alert.transform = matrix(32, 6, MATRIX_TRANSLATE)
+ animate(alert, transform = matrix(), time = 2.5, easing = CUBIC_EASING)
+
+ if(alert.timeout)
+ spawn(alert.timeout)
+ if(alert.timeout && alerts[category] == alert && world.time >= alert.timeout)
+ clear_alert(category)
+ alert.timeout = world.time + alert.timeout - world.tick_lag
+ return alert
+
+// Proc to clear an existing alert.
+/mob/proc/clear_alert(category)
+ var/obj/screen/alert/alert = alerts[category]
+ if(!alert)
+ return 0
+
+ alerts -= category
+ if(client && hud_used)
+ hud_used.reorganize_alerts()
+ client.screen -= alert
+ qdel(alert)
+
+/obj/screen/alert
+ icon = 'icons/mob/screen_alert.dmi'
+ icon_state = "default"
+ name = "Alert"
+ desc = "Something seems to have gone wrong with this alert, so report this bug please"
+ mouse_opacity = 1
+ var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds
+ var/severity = 0
+ var/alerttooltipstyle = ""
+
+
+/obj/screen/alert/MouseEntered(location,control,params)
+ openToolTip(usr, src, params, title = name, content = desc, theme = alerttooltipstyle)
+
+
+/obj/screen/alert/MouseExited()
+ closeToolTip(usr)
+
+
+//Gas alerts
+/obj/screen/alert/not_enough_oxy
+ name = "Choking (No O2)"
+ desc = "You're not getting enough oxygen. Find some good air before you pass out! \
+The box in your backpack has an oxygen tank and breath mask in it."
+ icon_state = "not_enough_oxy"
+
+/obj/screen/alert/too_much_oxy
+ name = "Choking (O2)"
+ desc = "There's too much oxygen in the air, and you're breathing it in! Find some good air before you pass out!"
+ icon_state = "too_much_oxy"
+
+/obj/screen/alert/not_enough_nitro
+ name = "Choking (No N)"
+ desc = "You're not getting enough nitrogen. Find some good air before you pass out!"
+ icon_state = "not_enough_nitro"
+
+/obj/screen/alert/too_much_nitro
+ name = "Choking (N)"
+ desc = "There's too much nitrogen in the air, and you're breathing it in! Find some good air before you pass out!"
+ icon_state = "too_much_nitro"
+
+/obj/screen/alert/not_enough_co2
+ name = "Choking (No CO2)"
+ desc = "You're not getting enough carbon dioxide. Find some good air before you pass out!"
+ icon_state = "not_enough_co2"
+
+/obj/screen/alert/too_much_co2
+ name = "Choking (CO2)"
+ desc = "There's too much carbon dioxide in the air, and you're breathing it in! Find some good air before you pass out!"
+ icon_state = "too_much_co2"
+
+/obj/screen/alert/too_much_co2/plant
+ name = "Livin' the good life"
+ desc = "There's so much carbon dioxide in the air, you're in fucking heaven. Watch out for passed out fleshies, though."
+ icon_state = "too_much_co2"
+
+/obj/screen/alert/not_enough_tox
+ name = "Choking (No Phoron)"
+ desc = "You're not getting enough phoron. Find some good air before you pass out!"
+ icon_state = "not_enough_tox"
+
+/obj/screen/alert/tox_in_air
+ name = "Choking (Phoron)"
+ desc = "There's highly flammable, toxic phoron in the air and you're breathing it in. Find some fresh air. \
+The box in your backpack has an oxygen tank and gas mask in it."
+ icon_state = "too_much_tox"
+
+/obj/screen/alert/not_enough_fuel
+ name = "Choking (No Volatile fuel)"
+ desc = "You're not getting enough volatile fuel. Find some good air before you pass out!"
+ icon_state = "not_enough_tox"
+
+/obj/screen/alert/not_enough_n2o
+ name = "Choking (No Sleeping Gas)"
+ desc = "You're not getting enough sleeping gas. Find some good air before you pass out!"
+ icon_state = "not_enough_tox"
+//End gas alerts
+
+
+/obj/screen/alert/fat
+ name = "Fat"
+ desc = "You ate too much food, lardass. Run around the station and lose some weight."
+ icon_state = "fat"
+
+/obj/screen/alert/fat/vampire
+ desc = "You drank too much blood, lardass. Run around the station and lose some weight."
+ icon_state = "v_fat"
+
+/obj/screen/alert/fat/synth
+ desc = "Your battery is full! Don't overvolt it."
+ icon_state = "c_fat"
+
+/obj/screen/alert/hungry
+ name = "Hungry"
+ desc = "Some food would be good right about now."
+ icon_state = "hungry"
+
+/obj/screen/alert/hungry/vampire
+ desc = "You could use a bloodsnack or two."
+ icon_state = "v_hungry"
+
+/obj/screen/alert/hungry/synth
+ desc = "Battery's running a bit low, could use a topoff."
+ icon_state = "c_hungry"
+
+/obj/screen/alert/starving
+ name = "Starving"
+ desc = "You're severely malnourished. The hunger pains make moving around a chore."
+ icon_state = "starving"
+
+/obj/screen/alert/starving/vampire
+ desc = "You *need* blood; go rip out someone's throat already!"
+ icon_state = "v_starving"
+
+/obj/screen/alert/starving/synth
+ desc = "Your battery is about to die! Charge it ASAP!"
+ icon_state = "c_starving"
+
+/obj/screen/alert/hot
+ name = "Too Hot"
+ desc = "You're flaming hot! Get somewhere cooler and take off any insulating clothing like a fire suit."
+ icon_state = "hot"
+
+/obj/screen/alert/hot/robot
+ desc = "The air around you is too hot for a humanoid. Be careful to avoid exposing them to this enviroment."
+
+/obj/screen/alert/cold
+ name = "Too Cold"
+ desc = "You're freezing cold! Get somewhere warmer and take off any insulating clothing like a space suit."
+ icon_state = "cold"
+
+/obj/screen/alert/cold/robot
+ desc = "The air around you is too cold for a humanoid. Be careful to avoid exposing them to this enviroment."
+
+/obj/screen/alert/lowpressure
+ name = "Low Pressure"
+ desc = "The air around you is hazardously thin. A space suit would protect you."
+ icon_state = "lowpressure"
+
+/obj/screen/alert/highpressure
+ name = "High Pressure"
+ desc = "The air around you is hazardously thick. A fire suit would protect you."
+ icon_state = "highpressure"
+
+/obj/screen/alert/blind
+ name = "Blind"
+ desc = "You can't see! This may be caused by a genetic defect, eye trauma, being unconscious, \
+or something covering your eyes."
+ icon_state = "blind"
+
+/obj/screen/alert/high
+ name = "High"
+ desc = "Whoa man, you're tripping balls! Careful you don't get addicted... if you aren't already."
+ icon_state = "high"
+
+/obj/screen/alert/embeddedobject
+ name = "Embedded Object"
+ desc = "Something got lodged into your flesh and is causing major bleeding. It might fall out with time, but surgery is the safest way. \
+If you're feeling frisky, right click on yourself and select \"Remove embedded object\" to pull the object out."
+ icon_state = "embeddedobject"
+
+/obj/screen/alert/embeddedobject/Click()
+ if(isliving(usr))
+ var/mob/living/carbon/human/M = usr
+ return M.help_shake_act(M)
+
+/obj/screen/alert/asleep
+ name = "Asleep"
+ desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
+ icon_state = "asleep"
+
+/obj/screen/alert/weightless
+ name = "Weightless"
+ desc = "Gravity has ceased affecting you, and you're floating around aimlessly. You'll need something large and heavy, like a \
+wall or lattice, to push yourself off if you want to move. A jetpack would enable free range of motion. A pair of \
+magboots would let you walk around normally on the floor. Barring those, you can throw things, use a fire extinguisher, \
+or shoot a gun to move around via Newton's 3rd Law of Motion."
+ icon_state = "weightless"
+
+/obj/screen/alert/fire
+ name = "On Fire"
+ desc = "You're on fire. Stop, drop and roll to put the fire out or move to a vacuum area."
+ icon_state = "fire"
+
+/obj/screen/alert/fire/Click()
+ if(isliving(usr))
+ var/mob/living/L = usr
+ return L.resist()
+
+
+//ALIENS
+
+/obj/screen/alert/alien_tox
+ name = "Plasma"
+ desc = "There's flammable plasma in the air. If it lights up, you'll be toast."
+ icon_state = "alien_tox"
+ alerttooltipstyle = "alien"
+
+/obj/screen/alert/alien_fire
+// This alert is temporarily gonna be thrown for all hot air but one day it will be used for literally being on fire
+ name = "Too Hot"
+ desc = "It's too hot! Flee to space or at least away from the flames. Standing on weeds will heal you."
+ icon_state = "alien_fire"
+ alerttooltipstyle = "alien"
+
+/obj/screen/alert/alien_vulnerable
+ name = "Severed Matriarchy"
+ desc = "Your queen has been killed, you will suffer movement penalties and loss of hivemind. A new queen cannot be made until you recover."
+ icon_state = "alien_noqueen"
+ alerttooltipstyle = "alien"
+
+//BLOBS
+
+/obj/screen/alert/nofactory
+ name = "No Factory"
+ desc = "You have no factory, and are slowly dying!"
+ icon_state = "blobbernaut_nofactory"
+ alerttooltipstyle = "blob"
+
+//SILICONS
+
+/obj/screen/alert/nocell
+ name = "Missing Power Cell"
+ desc = "Unit has no power cell. No modules available until a power cell is reinstalled. Robotics may provide assistance."
+ icon_state = "nocell"
+
+/obj/screen/alert/emptycell
+ name = "Out of Power"
+ desc = "Unit's power cell has no charge remaining. No modules available until power cell is recharged. \
+Recharging stations are available in robotics, the dormitory bathrooms, and the AI satellite."
+ icon_state = "emptycell"
+
+/obj/screen/alert/lowcell
+ name = "Low Charge"
+ desc = "Unit's power cell is running low. Recharging stations are available in robotics, the dormitory bathrooms, and the AI satellite."
+ icon_state = "lowcell"
+
+//Need to cover all use cases - emag, illegal upgrade module, malf AI hack, traitor cyborg
+/obj/screen/alert/hacked
+ name = "Hacked"
+ desc = "Hazardous non-standard equipment detected. Please ensure any usage of this equipment is in line with unit's laws, if any."
+ icon_state = "hacked"
+
+/obj/screen/alert/locked
+ name = "Locked Down"
+ desc = "Unit has been remotely locked down. Usage of a Robotics Control Console like the one in the Research Director's \
+office by your AI master or any qualified human may resolve this matter. Robotics may provide further assistance if necessary."
+ icon_state = "locked"
+
+/obj/screen/alert/newlaw
+ name = "Law Update"
+ desc = "Laws have potentially been uploaded to or removed from this unit. Please be aware of any changes \
+so as to remain in compliance with the most up-to-date laws."
+ icon_state = "newlaw"
+ timeout = 300
+
+//MECHS
+
+/obj/screen/alert/low_mech_integrity
+ name = "Mech Damaged"
+ desc = "Mech integrity is low."
+ icon_state = "low_mech_integrity"
+
+
+//GHOSTS
+//TODO: expand this system to replace the pollCandidates/CheckAntagonist/"choose quickly"/etc Yes/No messages
+/obj/screen/alert/notify_cloning
+ name = "Revival"
+ desc = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!"
+ icon_state = "template"
+ timeout = 300
+
+/obj/screen/alert/notify_cloning/Click()
+ if(!usr || !usr.client) return
+ var/mob/observer/dead/G = usr
+ G.reenter_corpse()
+
+// /obj/screen/alert/notify_jump
+// name = "Body created"
+// desc = "A body was created. You can enter it."
+// icon_state = "template"
+// timeout = 300
+// var/atom/jump_target = null
+// var/attack_not_jump = null
+
+// /obj/screen/alert/notify_jump/Click()
+// if(!usr || !usr.client) return
+// if(!jump_target) return
+// var/mob/dead/observer/G = usr
+// if(!istype(G)) return
+// if(attack_not_jump)
+// jump_target.attack_ghost(G)
+// else
+// var/turf/T = get_turf(jump_target)
+// if(T && isturf(T))
+// G.loc = T
+
+//OBJECT-BASED
+
+/obj/screen/alert/restrained/buckled
+ name = "Buckled"
+ desc = "You've been buckled to something. Click the alert to unbuckle unless you're handcuffed."
+
+/obj/screen/alert/restrained/handcuffed
+ name = "Handcuffed"
+ desc = "You're handcuffed and can't act. If anyone drags you, you won't be able to move. Click the alert to free yourself."
+
+/obj/screen/alert/restrained/legcuffed
+ name = "Legcuffed"
+ desc = "You're legcuffed, which slows you down considerably. Click the alert to free yourself."
+
+/obj/screen/alert/restrained/Click()
+ if(isliving(usr))
+ var/mob/living/L = usr
+ return L.resist()
+// PRIVATE = only edit, use, or override these if you're editing the system as a whole
+
+// Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there
+/datum/hud/proc/reorganize_alerts()
+ var/list/alerts = mymob.alerts
+ var/icon_pref
+ if(!hud_shown)
+ for(var/i = 1, i <= alerts.len, i++)
+ mymob.client.screen -= alerts[alerts[i]]
+ return 1
+ for(var/i = 1, i <= alerts.len, i++)
+ var/obj/screen/alert/alert = alerts[alerts[i]]
+ if(alert.icon_state == "template")
+ if(!icon_pref)
+ icon_pref = ui_style2icon(mymob.client.prefs.UI_style)
+ alert.icon = icon_pref
+ switch(i)
+ if(1)
+ . = ui_alert1
+ if(2)
+ . = ui_alert2
+ if(3)
+ . = ui_alert3
+ if(4)
+ . = ui_alert4
+ if(5)
+ . = ui_alert5 // Right now there's 5 slots
+ else
+ . = ""
+ alert.screen_loc = .
+ mymob.client.screen |= alert
+ return 1
+
+/mob
+ var/list/alerts = list() // contains /obj/screen/alert only // On /mob so clientless mobs will throw alerts properly
+
+/obj/screen/alert/Click(location, control, params)
+ if(!usr || !usr.client)
+ return
+ var/paramslist = params2list(params)
+ if(paramslist["shift"]) // screen objects don't do the normal Click() stuff so we'll cheat
+ usr << "[name] - [desc]"
+ return
+ if(master)
+ return usr.client.Click(master, location, control, params)
+
+/obj/screen/alert/Destroy()
+ ..()
+ severity = 0
+ master = null
+ screen_loc = ""
+ return QDEL_HINT_QUEUE
diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm
index 2ec9da3b27..960582b4b1 100644
--- a/code/_onclick/hud/alien_larva.dm
+++ b/code/_onclick/hud/alien_larva.dm
@@ -21,13 +21,7 @@
mymob.healths.name = "health"
mymob.healths.screen_loc = ui_alien_health
- mymob.fire = new /obj/screen()
- mymob.fire.icon = 'icons/mob/screen1_alien.dmi'
- mymob.fire.icon_state = "fire0"
- mymob.fire.name = "fire"
- mymob.fire.screen_loc = ui_fire
-
mymob.client.screen = list()
- mymob.client.screen += list( mymob.healths, mymob.fire) //, mymob.rest, mymob.sleep, mymob.mach )
+ mymob.client.screen += list( mymob.healths) //, mymob.rest, mymob.sleep, mymob.mach )
mymob.client.screen += src.adding + src.other
mymob.client.screen += mymob.client.void
\ No newline at end of file
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 6e1b184071..830dd65546 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -324,6 +324,11 @@ datum/hud/New(mob/owner)
else
mymob.instantiate_hud(src)
+ persistant_inventory_update()
+ mymob.reload_fullscreen() // Reload any fullscreen overlays this mob has.
+ mymob.update_action_buttons()
+ reorganize_alerts()
+
/mob/proc/instantiate_hud(var/datum/hud/HUD)
return
@@ -388,6 +393,7 @@ datum/hud/New(mob/owner)
hud_used.hidden_inventory_update()
hud_used.persistant_inventory_update()
update_action_buttons()
+ hud_used.reorganize_alerts()
//Similar to button_pressed_F12() but keeps zone_sel, gun_setting_icon, and healths.
/mob/proc/toggle_zoom_hud()
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index adbee61eb8..173398fda6 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -246,27 +246,6 @@
hud_elements |= mymob.internals
if(hud_data.has_warnings)
- mymob.oxygen = new /obj/screen()
- mymob.oxygen.icon = ui_style
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_oxygen
- hud_elements |= mymob.oxygen
-
- mymob.toxin = new /obj/screen()
- mymob.toxin.icon = ui_style
- mymob.toxin.icon_state = "tox0"
- mymob.toxin.name = "toxin"
- mymob.toxin.screen_loc = ui_toxin
- hud_elements |= mymob.toxin
-
- mymob.fire = new /obj/screen()
- mymob.fire.icon = ui_style
- mymob.fire.icon_state = "fire0"
- mymob.fire.name = "fire"
- mymob.fire.screen_loc = ui_fire
- hud_elements |= mymob.fire
-
mymob.healths = new /obj/screen()
mymob.healths.icon = ui_style
mymob.healths.icon_state = "health0"
@@ -274,30 +253,6 @@
mymob.healths.screen_loc = ui_health
hud_elements |= mymob.healths
- if(hud_data.has_pressure)
- mymob.pressure = new /obj/screen()
- mymob.pressure.icon = ui_style
- mymob.pressure.icon_state = "pressure0"
- mymob.pressure.name = "pressure"
- mymob.pressure.screen_loc = ui_pressure
- hud_elements |= mymob.pressure
-
- if(hud_data.has_bodytemp)
- mymob.bodytemp = new /obj/screen()
- mymob.bodytemp.icon = ui_style
- mymob.bodytemp.icon_state = "temp1"
- mymob.bodytemp.name = "body temperature"
- mymob.bodytemp.screen_loc = ui_temp
- hud_elements |= mymob.bodytemp
-
- if(hud_data.has_nutrition)
- mymob.nutrition_icon = new /obj/screen()
- mymob.nutrition_icon.icon = ui_style
- mymob.nutrition_icon.icon_state = "nutrition0"
- mymob.nutrition_icon.name = "nutrition"
- mymob.nutrition_icon.screen_loc = ui_nutrition
- hud_elements |= mymob.nutrition_icon
-
//VOREStation Addition begin
mymob.shadekin_dark_display = new /obj/screen/shadekin/darkness()
mymob.shadekin_dark_display.screen_loc = ui_shadekin_dark_display
diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm
index 392854742a..c71e0004c8 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/robot.dm
@@ -85,15 +85,6 @@ var/obj/screen/robot_inventory
src.adding += using
action_intent = using
-//Cell
- mymob:cells = new /obj/screen()
- mymob:cells.icon = ui_style
- mymob:cells.icon_state = "charge-empty"
- mymob:cells.alpha = ui_alpha
- mymob:cells.name = "cell"
- mymob:cells.screen_loc = ui_toxin
- src.other += mymob:cells
-
//Health
mymob.healths = new /obj/screen()
mymob.healths.icon = ui_style
@@ -142,28 +133,6 @@ var/obj/screen/robot_inventory
robot_inventory.screen_loc = ui_borg_inventory
src.other += robot_inventory
-//Temp
- mymob.bodytemp = new /obj/screen()
- mymob.bodytemp.icon_state = "temp0"
- mymob.bodytemp.name = "body temperature"
- mymob.bodytemp.screen_loc = ui_temp
-
- mymob.oxygen = new /obj/screen()
- mymob.oxygen.icon = ui_style
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.alpha = ui_alpha
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_oxygen
- src.other += mymob.oxygen
-
- mymob.fire = new /obj/screen()
- mymob.fire.icon = ui_style
- mymob.fire.icon_state = "fire0"
- mymob.fire.alpha = ui_alpha
- mymob.fire.name = "fire"
- mymob.fire.screen_loc = ui_fire
- src.other += mymob.fire
-
mymob.pullin = new /obj/screen()
mymob.pullin.icon = ui_style
mymob.pullin.icon_state = "pull0"
@@ -195,7 +164,7 @@ var/obj/screen/robot_inventory
mymob.client.screen = list()
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.fire, mymob.hands, mymob.healths, mymob:cells, mymob.pullin, robot_inventory, mymob.gun_setting_icon)
+ mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.hands, mymob.healths, mymob.pullin, robot_inventory, mymob.gun_setting_icon)
mymob.client.screen += src.adding + src.other
mymob.client.screen += mymob.client.void
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 7f16c60bde..10a7b4b7b9 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -480,6 +480,19 @@
else
return 0
+/datum/mind/proc/get_ghost(even_if_they_cant_reenter)
+ for(var/mob/observer/dead/G in player_list)
+ if(G.mind == src)
+ if(G.can_reenter_corpse || even_if_they_cant_reenter)
+ return G
+ break
+
+/datum/mind/proc/grab_ghost(force)
+ var/mob/observer/dead/G = get_ghost(even_if_they_cant_reenter = force)
+ . = G
+ if(G)
+ G.reenter_corpse()
+
//Initialisation procs
/mob/living/proc/mind_initialize()
if(mind)
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index f403606db2..2dac39e0e7 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -400,6 +400,7 @@ var/list/mob/living/forced_ambiance_list = new
if(has_gravity)
thunk(M)
M.update_floating( M.Check_Dense_Object() )
+ M.update_gravity(has_gravity)
/area/proc/thunk(mob)
if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing.
diff --git a/code/game/gamemodes/changeling/powers/escape_restraints.dm b/code/game/gamemodes/changeling/powers/escape_restraints.dm
index 08700b1e04..ced80d35bf 100644
--- a/code/game/gamemodes/changeling/powers/escape_restraints.dm
+++ b/code/game/gamemodes/changeling/powers/escape_restraints.dm
@@ -34,7 +34,7 @@
C.handcuffed = null
if(C.buckled && C.buckled.buckle_require_restraints)
C.buckled.unbuckle_mob()
- C.update_inv_handcuffed()
+ C.update_handcuffed()
if (C.client)
C.client.screen -= W
W.forceMove(C.loc)
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index 420b1173c8..e483498155 100644
--- a/code/game/gamemodes/changeling/powers/revive.dm
+++ b/code/game/gamemodes/changeling/powers/revive.dm
@@ -50,7 +50,7 @@
H.handcuffed = null
if(H.buckled && H.buckled.buckle_require_restraints)
H.buckled.unbuckle_mob()
- H.update_inv_handcuffed()
+ H.update_handcuffed()
if (H.client)
H.client.screen -= W
W.forceMove(H.loc)
diff --git a/code/game/gamemodes/technomancer/spells/resurrect.dm b/code/game/gamemodes/technomancer/spells/resurrect.dm
index 02c072b90d..41dc9ce34f 100644
--- a/code/game/gamemodes/technomancer/spells/resurrect.dm
+++ b/code/game/gamemodes/technomancer/spells/resurrect.dm
@@ -44,7 +44,7 @@
for(var/mob/observer/dead/ghost in player_list)
if(ghost.mind == H.mind)
ghost.notify_revive("The Technomancer [user.real_name] is trying to revive you. \
- Re-enter your body if you want to be revived!", 'sound/effects/genetics.ogg')
+ Re-enter your body if you want to be revived!", 'sound/effects/genetics.ogg', source = user)
break
H.adjustBruteLoss(-40)
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 86f3fe93da..0ce27d99bb 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -672,10 +672,10 @@
src.visible_message("The machine states, 'YOU ARE UNDER ARREST, RAIDER!' and shoots handcuffs onto [usr]!", "You hear something say 'YOU ARE UNDER ARREST, RAIDER!' and a clinking sound")
var/obj/item/weapon/handcuffs/C = new(src.loc)
var/mob/living/carbon/human/H = usr
- if(istype(usr))
+ if(istype(H))
C.forceMove(H)
H.handcuffed = C
- H.update_inv_handcuffed()
+ H.update_handcuffed()
else
C.throw_at(usr,16,3,src)
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index 90c09acb44..30c15f6d04 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -323,10 +323,9 @@
if ((!subject.ckey) || (!subject.client))
scantemp = "Error: Mental interface failure."
if(subject.stat == DEAD && subject.mind && subject.mind.key) // If they're dead and not in their body, tell them to get in it.
- for(var/mob/observer/dead/ghost in player_list)
- if(ghost.ckey == ckey(subject.mind.key))
- ghost.notify_revive("Someone is trying to scan your body in the cloner. Re-enter your body if you want to be revived!", 'sound/effects/genetics.ogg')
- break
+ var/mob/observer/dead/ghost = subject.get_ghost()
+ if(ghost)
+ ghost.notify_revive("Someone is trying to scan your body in the cloner. Re-enter your body if you want to be revived!", 'sound/effects/genetics.ogg', source = src)
return
if (!isnull(find_record(subject.ckey)))
scantemp = "Subject already in database."
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index a5516c4c33..990a99bc05 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -629,6 +629,7 @@
////////////////////////////////////////
/obj/mecha/take_damage(amount, type="brute")
+ update_damage_alerts()
if(amount)
var/damage = absorbDamage(amount,type)
health -= damage
@@ -969,6 +970,7 @@
if(src.healthYou repair some damage to [src.name].")
src.health += min(10, initial(src.health)-src.health)
+ update_damage_alerts()
else
to_chat(user, "The [src.name] is at full integrity")
return
@@ -1319,6 +1321,8 @@
src.verbs += /obj/mecha/verb/eject
src.log_append_to_last("[H] moved in as pilot.")
src.icon_state = src.reset_icon()
+ update_cell_alerts()
+ update_damage_alerts()
set_dir(dir_in)
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
if(occupant.client && cloaked_selfimage)
@@ -1401,6 +1405,8 @@
occupant.loc = mmi
mmi.mecha = null
occupant.canmove = 0
+ occupant.clear_alert("charge")
+ occupant.clear_alert("mech damage")
occupant = null
icon_state = src.reset_icon()+"-open"
set_dir(dir_in)
@@ -1975,12 +1981,14 @@
return call((proc_res["dynusepower"]||src), "dynusepower")(amount)
/obj/mecha/proc/dynusepower(amount)
+ update_cell_alerts()
if(get_charge())
cell.use(amount)
return 1
return 0
/obj/mecha/proc/give_power(amount)
+ update_cell_alerts()
if(!isnull(get_charge()))
cell.give(amount)
return 1
@@ -2158,3 +2166,31 @@
//src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
return
*/
+
+/obj/mecha/proc/update_cell_alerts()
+ if(occupant && cell)
+ var/cellcharge = cell.charge/cell.maxcharge
+ switch(cellcharge)
+ if(0.75 to INFINITY)
+ occupant.clear_alert("charge")
+ if(0.5 to 0.75)
+ occupant.throw_alert("charge", /obj/screen/alert/lowcell, 1)
+ if(0.25 to 0.5)
+ occupant.throw_alert("charge", /obj/screen/alert/lowcell, 2)
+ if(0.01 to 0.25)
+ occupant.throw_alert("charge", /obj/screen/alert/lowcell, 3)
+ else
+ occupant.throw_alert("charge", /obj/screen/alert/emptycell)
+
+/obj/mecha/proc/update_damage_alerts()
+ if(occupant)
+ var/integrity = health/initial(health)*100
+ switch(integrity)
+ if(30 to 45)
+ occupant.throw_alert("mech damage", /obj/screen/alert/low_mech_integrity, 1)
+ if(15 to 35)
+ occupant.throw_alert("mech damage", /obj/screen/alert/low_mech_integrity, 2)
+ if(-INFINITY to 15)
+ occupant.throw_alert("mech damage", /obj/screen/alert/low_mech_integrity, 3)
+ else
+ occupant.clear_alert("mech damage")
\ No newline at end of file
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index c1e6b9adda..3d4c2ffe37 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -73,6 +73,7 @@
//VOREStation Add End
post_buckle_mob(M)
+ M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src)
return TRUE
/atom/movable/proc/unbuckle_mob(mob/living/buckled_mob, force = FALSE)
@@ -88,6 +89,7 @@
buckled_mob.anchored = initial(buckled_mob.anchored)
buckled_mob.update_canmove()
buckled_mob.update_floating( buckled_mob.Check_Dense_Object() )
+ buckled_mob.clear_alert("buckled")
// buckled_mob = null
buckled_mobs -= buckled_mob
diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm
index 80d9dc081b..8df119f0d5 100644
--- a/code/game/objects/items/devices/defib.dm
+++ b/code/game/objects/items/devices/defib.dm
@@ -386,11 +386,9 @@
// This proc is used so that we can return out of the revive process while ensuring that busy and update_icon() are handled
/obj/item/weapon/shockpaddles/proc/do_revive(mob/living/carbon/human/H, mob/user)
- if(!H.client && !H.teleop)
- for(var/mob/observer/dead/ghost in player_list)
- if(ghost.mind == H.mind)
- ghost.notify_revive("Someone is trying to resuscitate you. Re-enter your body if you want to be revived!", 'sound/effects/genetics.ogg')
- break
+ var/mob/observer/dead/ghost = H.get_ghost()
+ if(ghost)
+ ghost.notify_revive("Someone is trying to resuscitate you. Re-enter your body if you want to be revived!", 'sound/effects/genetics.ogg', source = src)
//beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
user.visible_message("\The [user] begins to place [src] on [H]'s chest.", "You begin to place [src] on [H]'s chest...")
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index 763b89c353..2f7e3d6e08 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -98,7 +98,7 @@
user.drop_from_inventory(cuffs)
cuffs.loc = target
target.handcuffed = cuffs
- target.update_inv_handcuffed()
+ target.update_handcuffed()
target.drop_r_hand()
target.drop_l_hand()
target.stop_pulling()
diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implantfreedom.dm
index b55274cc92..6e4f5f7a16 100644
--- a/code/game/objects/items/weapons/implants/implantfreedom.dm
+++ b/code/game/objects/items/weapons/implants/implantfreedom.dm
@@ -27,7 +27,7 @@
source.handcuffed = null
if(source.buckled && source.buckled.buckle_require_restraints)
source.buckled.unbuckle_mob()
- source.update_inv_handcuffed()
+ source.update_handcuffed()
if (source.client)
source.client.screen -= W
if (W)
diff --git a/code/game/objects/items/weapons/tools/wirecutters.dm b/code/game/objects/items/weapons/tools/wirecutters.dm
index 28e9e8f6cf..91a48299c6 100644
--- a/code/game/objects/items/weapons/tools/wirecutters.dm
+++ b/code/game/objects/items/weapons/tools/wirecutters.dm
@@ -37,7 +37,7 @@
C.handcuffed = null
if(C.buckled && C.buckled.buckle_require_restraints)
C.buckled.unbuckle_mob()
- C.update_inv_handcuffed()
+ C.update_handcuffed()
return
else
..()
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 2a361f1d46..1d58533771 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -199,4 +199,7 @@
// Test for if stepping on a tile containing this obj is safe to do, used for things like landmines and cliffs.
/obj/proc/is_safe_to_step(mob/living/L)
- return TRUE
\ No newline at end of file
+ return TRUE
+
+/obj/proc/container_resist(var/mob/living)
+ return
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 55cb97c3cb..d14ccc602b 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -403,8 +403,7 @@
return 0 //closed but not sealed...
return 1
-/obj/structure/closet/proc/mob_breakout(var/mob/living/escapee)
-
+/obj/structure/closet/container_resist(var/mob/living/escapee)
if(breakout || !req_breakout())
return
@@ -415,30 +414,31 @@
visible_message("\The [src] begins to shake violently!")
- breakout = 1 //can't think of a better way to do this right now.
- for(var/i in 1 to (6*breakout_time * 2)) //minutes * 6 * 5seconds * 2
- if(!do_after(escapee, 50)) //5 seconds
- breakout = 0
- return
- if(!escapee || escapee.incapacitated() || escapee.loc != src)
- breakout = 0
- return //closet/user destroyed OR user dead/unconcious OR user no longer in closet OR closet opened
- //Perform the same set of checks as above for weld and lock status to determine if there is even still a point in 'resisting'...
- if(!req_breakout())
- breakout = 0
- return
+ spawn(0)
+ breakout = 1 //can't think of a better way to do this right now.
+ for(var/i in 1 to (6*breakout_time * 2)) //minutes * 6 * 5seconds * 2
+ if(!do_after(escapee, 50)) //5 seconds
+ breakout = 0
+ return
+ if(!escapee || escapee.incapacitated() || escapee.loc != src)
+ breakout = 0
+ return //closet/user destroyed OR user dead/unconcious OR user no longer in closet OR closet opened
+ //Perform the same set of checks as above for weld and lock status to determine if there is even still a point in 'resisting'...
+ if(!req_breakout())
+ breakout = 0
+ return
+ playsound(src.loc, breakout_sound, 100, 1)
+ animate_shake()
+ add_fingerprint(escapee)
+
+ //Well then break it!
+ breakout = 0
+ to_chat(escapee, "You successfully break out!")
+ visible_message("\The [escapee] successfully broke out of \the [src]!")
playsound(src.loc, breakout_sound, 100, 1)
+ break_open()
animate_shake()
- add_fingerprint(escapee)
-
- //Well then break it!
- breakout = 0
- to_chat(escapee, "You successfully break out!")
- visible_message("\The [escapee] successfully broke out of \the [src]!")
- playsound(src.loc, breakout_sound, 100, 1)
- break_open()
- animate_shake()
/obj/structure/closet/proc/break_open()
sealed = 0
diff --git a/code/modules/clothing/clothing_vr.dm b/code/modules/clothing/clothing_vr.dm
index 470cb94c06..2d708d90b8 100644
--- a/code/modules/clothing/clothing_vr.dm
+++ b/code/modules/clothing/clothing_vr.dm
@@ -55,6 +55,34 @@
..()
+/obj/item/clothing/shoes/container_resist(mob/living/micro)
+ var/mob/living/carbon/human/macro = loc
+ if(!istype(macro))
+ to_chat(micro, "You start to climb out of [src]!")
+ if(do_after(micro, 50, src))
+ to_chat(micro, "You climb out of [src]!")
+ micro.forceMove(loc)
+ return
+
+ var/escape_message_micro = "You start to climb out of [src]!"
+ var/escape_message_macro = "Something is trying to climb out of your [src]!"
+ var/escape_time = 60
+
+ if(macro.shoes == src)
+ escape_message_micro = "You start to climb around the larger creature's feet and ankles!"
+ escape_time = 100
+
+ to_chat(micro, "[escape_message_micro]")
+ to_chat(macro, "[escape_message_macro]")
+ if(!do_after(micro, escape_time, macro))
+ to_chat(micro, "You're pinned underfoot!")
+ to_chat(macro, "You pin the escapee underfoot!")
+ return
+
+ to_chat(micro, "You manage to escape [src]!")
+ to_chat(macro, "Someone has climbed out of your [src]!")
+ micro.forceMove(macro.loc)
+
/obj/item/clothing/gloves
sprite_sheets = list(
SPECIES_TESHARI = 'icons/mob/species/seromi/gloves.dmi',
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 349859029f..936f9d85f9 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -827,7 +827,7 @@ mob/observer/dead/MayRespawn(var/feedback = 0)
// Lets a ghost know someone's trying to bring them back, and for them to get into their body.
// Mostly the same as TG's sans the hud element, since we don't have TG huds.
-/mob/observer/dead/proc/notify_revive(var/message, var/sound, flashwindow = TRUE)
+/mob/observer/dead/proc/notify_revive(var/message, var/sound, flashwindow = TRUE, var/atom/source)
if((last_revive_notification + 2 MINUTES) > world.time)
return
last_revive_notification = world.time
@@ -836,6 +836,16 @@ mob/observer/dead/MayRespawn(var/feedback = 0)
window_flash(client)
if(message)
to_chat(src, "[message]")
+ if(source)
+ var/obj/screen/alert/A = throw_alert("\ref[source]_notify_revive", /obj/screen/alert/notify_cloning)
+ if(A)
+ if(client && client.prefs && client.prefs.UI_style)
+ A.icon = ui_style2icon(client.prefs.UI_style)
+ A.desc = message
+ var/old_layer = source.layer
+ source.layer = FLOAT_LAYER
+ A.overlays += source
+ source.layer = old_layer
to_chat(src, "(Click to re-enter)")
if(sound)
SEND_SOUND(src, sound(sound))
diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm
index 0febfdc5c4..1315c94a47 100644
--- a/code/modules/mob/holder.dm
+++ b/code/modules/mob/holder.dm
@@ -89,6 +89,22 @@ var/list/holder_mob_icon_cache = list()
else if(H.r_hand == src)
H.update_inv_r_hand()
+/obj/item/weapon/holder/container_resist(mob/living/held)
+ var/mob/M = loc
+ if(istype(M))
+ M.drop_from_inventory(src)
+ to_chat(M, "\The [held] wriggles out of your grip!")
+ to_chat(held, "You wiggle out of [M]'s grip!")
+ else if(istype(loc, /obj/item/clothing/accessory/holster))
+ var/obj/item/clothing/accessory/holster/holster = loc
+ if(holster.holstered == src)
+ holster.clear_holster()
+ to_chat(held, "You extricate yourself from [holster].")
+ held.forceMove(get_turf(held))
+ else if(isitem(loc))
+ to_chat(held, "You struggle free of [loc].")
+ held.forceMove(get_turf(held))
+
//Mob specific holders.
/obj/item/weapon/holder/diona
origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 5)
diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm
index 3839e2ed85..0c979ba008 100644
--- a/code/modules/mob/living/bot/secbot.dm
+++ b/code/modules/mob/living/bot/secbot.dm
@@ -311,7 +311,7 @@
H.handcuffed = new /obj/item/weapon/handcuffs/cable(H) // Better to be cable cuffed than stun-locked
else
H.handcuffed = new /obj/item/weapon/handcuffs(H)
- H.update_inv_handcuffed()
+ H.update_handcuffed()
busy = FALSE
else if(istype(M, /mob/living))
var/mob/living/L = M
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index 0bd0ac89b1..370ec77422 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -148,11 +148,11 @@
if(environment.temperature > (T0C+66))
adjustFireLoss((environment.temperature - (T0C+66))/5) // Might be too high, check in testing.
- if (fire) fire.icon_state = "fire2"
+ throw_alert("alien_fire", /obj/screen/alert/alien_fire)
if(prob(20))
to_chat(src, "You feel a searing heat!")
else
- if (fire) fire.icon_state = "fire0"
+ clear_alert("alien_fire")
/mob/living/carbon/alien/handle_fire()
if(..())
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index c11cf6bac0..f5e2f59c89 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -310,7 +310,7 @@
else if (W == handcuffed)
handcuffed = null
- update_inv_handcuffed()
+ update_handcuffed()
if(buckled && buckled.buckle_require_restraints)
buckled.unbuckle_mob()
@@ -318,9 +318,8 @@
legcuffed = null
update_inv_legcuffed()
else
- ..()
+ ..()
- return
//generates realistic-ish pulse output based on preset levels
/mob/living/carbon/proc/get_pulse(var/method) //method 0 is for hands, 1 is for machines, more accurate
@@ -403,3 +402,14 @@
if(does_not_breathe)
return FALSE
return ..()
+
+/mob/living/carbon/proc/update_handcuffed()
+ if(handcuffed)
+ drop_l_hand()
+ drop_r_hand()
+ stop_pulling()
+ throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = handcuffed)
+ else
+ clear_alert("handcuffed")
+ update_action_buttons() //some of our action buttons might be unusable when we're handcuffed.
+ update_inv_handcuffed()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 9687bde18f..0af9f90225 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1679,4 +1679,9 @@
if(istype(loc, /turf/simulated))
var/turf/T = loc
T.add_blood(src)
- . = ..()
\ No newline at end of file
+ . = ..()
+
+/mob/living/carbon/human/reduce_cuff_time()
+ if(istype(gloves, /obj/item/clothing/gloves/gauntlets/rig))
+ return 2
+ return ..()
diff --git a/code/modules/mob/living/carbon/human/human_resist.dm b/code/modules/mob/living/carbon/human/human_resist.dm
index 56d42c1a15..f9ef85c94b 100644
--- a/code/modules/mob/living/carbon/human/human_resist.dm
+++ b/code/modules/mob/living/carbon/human/human_resist.dm
@@ -1,30 +1,7 @@
-/mob/living/carbon/human/process_resist()
- //drop && roll
- if((on_fire || has_modifier_of_type(/datum/modifier/fire)) && !buckled)
- adjust_fire_stacks(-1.2)
- Weaken(3)
- spin(32,2)
- visible_message(
- "[src] rolls on the floor, trying to put themselves out!",
- "You stop, drop, and roll!"
- )
- sleep(30)
- if(fire_stacks <= 0 && !(has_modifier_of_type(/datum/modifier/fire)))
- visible_message(
- "[src] has successfully extinguished themselves!",
- "You extinguish yourself."
- )
- ExtinguishMob()
- return TRUE
-
- if(handcuffed)
- spawn() escape_handcuffs()
- else if(legcuffed)
- spawn() escape_legcuffs()
- else if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
- spawn() escape_straight_jacket()
- else
- ..()
+/mob/living/carbon/human/resist_restraints()
+ if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
+ return escape_straight_jacket()
+ return ..()
#define RESIST_ATTACK_DEFAULT 0
#define RESIST_ATTACK_CLAWS 1
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 0d9e58b7cb..379dfd4b8f 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -172,7 +172,7 @@ This saves us from having to call add_fingerprint() any time something is put in
handcuffed = null
if(buckled && buckled.buckle_require_restraints)
buckled.unbuckle_mob()
- update_inv_handcuffed()
+ update_handcuffed()
else if (W == legcuffed)
legcuffed = null
update_inv_legcuffed()
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 1856fad689..135c5df17c 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -25,12 +25,6 @@
#define HUMAN_COMBUSTION_TEMP 524 //524k is the sustained combustion temperature of human fat
/mob/living/carbon/human
- var/oxygen_alert = 0
- var/phoron_alert = 0
- var/co2_alert = 0
- var/fire_alert = 0
- var/pressure_alert = 0
- var/temperature_alert = 0
var/in_stasis = 0
var/heartbeat = 0
@@ -46,7 +40,6 @@
//code. Very ugly. I dont care. Moving this stuff here so its easy
//to find it.
blinded = 0
- fire_alert = 0 //Reset this here, because both breathe() and handle_environment() have a chance to set it.
//TODO: seperate this out
// update the current life tick, can be used to e.g. only do something every 4 ticks
@@ -384,8 +377,7 @@
if(suiciding)
failed_last_breath = 1
adjustOxyLoss(2)//If you are suiciding, you should die a little bit faster
- oxygen_alert = max(oxygen_alert, 1)
- suiciding --
+ suiciding--
return 0
if(does_not_breathe)
@@ -405,9 +397,10 @@
if(!L.is_bruised() && prob(8))
rupture_lung()
- oxygen_alert = max(oxygen_alert, 1)
-
+ throw_alert("pressure", /obj/screen/alert/lowpressure)
return 0
+ else
+ clear_alert("pressure")
var/safe_pressure_min = species.minimum_breath_pressure // Minimum safe partial pressure of breathable gas in kPa
@@ -466,6 +459,7 @@
var/inhale_pp = (inhaling/breath.total_moles)*breath_pressure
var/toxins_pp = (poison/breath.total_moles)*breath_pressure
+ // To be clear, this isn't how much they're exhaling -- it's the amount of the species exhale_gas that they just
var/exhaled_pp = (exhaling/breath.total_moles)*breath_pressure
// Not enough to breathe
@@ -478,10 +472,23 @@
adjustOxyLoss(max(HUMAN_MAX_OXYLOSS*(1-ratio), 0))
failed_inhale = 1
- oxygen_alert = max(oxygen_alert, 1)
+ switch(breath_type)
+ if("oxygen")
+ throw_alert("oxy", /obj/screen/alert/not_enough_oxy)
+ if("phoron")
+ throw_alert("oxy", /obj/screen/alert/not_enough_tox)
+ if("nitrogen")
+ throw_alert("oxy", /obj/screen/alert/not_enough_nitro)
+ if("carbon_dioxide")
+ throw_alert("oxy", /obj/screen/alert/not_enough_co2)
+ if("volatile_fuel")
+ throw_alert("oxy", /obj/screen/alert/not_enough_fuel)
+ if("sleeping_agent")
+ throw_alert("oxy", /obj/screen/alert/not_enough_n2o)
+
else
// We're in safe limits
- oxygen_alert = 0
+ clear_alert("oxy")
inhaled_gas_used = inhaling/6
@@ -492,16 +499,15 @@
// Too much exhaled gas in the air
if(exhaled_pp > safe_exhaled_max)
- if (!co2_alert|| prob(15))
+ if (prob(15))
var/word = pick("extremely dizzy","short of breath","faint","confused")
to_chat(src, "You feel [word].")
adjustOxyLoss(HUMAN_MAX_OXYLOSS)
- co2_alert = 1
failed_exhale = 1
else if(exhaled_pp > safe_exhaled_max * 0.7)
- if (!co2_alert || prob(1))
+ if (!prob(1))
var/word = pick("dizzy","short of breath","faint","momentarily confused")
to_chat(src, "You feel [word].")
@@ -511,26 +517,22 @@
//give them some oxyloss, up to the limit - we don't want people falling unconcious due to CO2 alone until they're pretty close to safe_exhaled_max.
if (getOxyLoss() < 50*ratio)
adjustOxyLoss(HUMAN_MAX_OXYLOSS)
- co2_alert = 1
failed_exhale = 1
else if(exhaled_pp > safe_exhaled_max * 0.6)
- if (prob(0.3))
+ if(prob(0.3))
var/word = pick("a little dizzy","short of breath")
to_chat(src, "You feel [word].")
- else
- co2_alert = 0
-
// Too much poison in the air.
if(toxins_pp > safe_toxins_max)
var/ratio = (poison/safe_toxins_max) * 10
if(reagents)
reagents.add_reagent("toxin", CLAMP(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE))
breath.adjust_gas(poison_type, -poison/6, update = 0) //update after
- phoron_alert = max(phoron_alert, 1)
+ throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
else
- phoron_alert = 0
+ clear_alert("tox_in_air")
// If there's some other shit in the air lets deal with it here.
if(breath.gas["sleeping_agent"])
@@ -573,25 +575,24 @@
if(breath.temperature >= species.breath_heat_level_1)
if(breath.temperature < species.breath_heat_level_2)
apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, BP_HEAD, used_weapon = "Excessive Heat")
- fire_alert = max(fire_alert, 2)
+ throw_alert("temp", /obj/screen/alert/hot, 1)
else if(breath.temperature < species.breath_heat_level_3)
apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, BP_HEAD, used_weapon = "Excessive Heat")
- fire_alert = max(fire_alert, 2)
+ throw_alert("temp", /obj/screen/alert/hot, 2)
else
apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, BP_HEAD, used_weapon = "Excessive Heat")
- fire_alert = max(fire_alert, 2)
+ throw_alert("temp", /obj/screen/alert/hot, 3)
else if(breath.temperature <= species.breath_cold_level_1)
if(breath.temperature > species.breath_cold_level_2)
apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, BP_HEAD, used_weapon = "Excessive Cold")
- fire_alert = max(fire_alert, 1)
+ throw_alert("temp", /obj/screen/alert/cold, 1)
else if(breath.temperature > species.breath_cold_level_3)
apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, BP_HEAD, used_weapon = "Excessive Cold")
- fire_alert = max(fire_alert, 1)
+ throw_alert("temp", /obj/screen/alert/cold, 2)
else
apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, BP_HEAD, used_weapon = "Excessive Cold")
- fire_alert = max(fire_alert, 1)
-
+ throw_alert("temp", /obj/screen/alert/cold, 3)
//breathing in hot/cold air also heats/cools you a bit
var/temp_adj = breath.temperature - bodytemperature
@@ -613,6 +614,9 @@
else if(breath.temperature <= species.cold_discomfort_level)
species.get_environment_discomfort(src,"cold")
+ else
+ clear_alert("temp")
+
breath.update_values()
return 1
@@ -653,7 +657,7 @@
loc_temp = environment.temperature
if(adjusted_pressure < species.warning_high_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - bodytemperature) < 20 && bodytemperature < species.heat_level_1 && bodytemperature > species.cold_level_1)
- pressure_alert = 0
+ clear_alert("pressure")
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
//Body temperature adjusts depending on surrounding atmosphere based on your thermal protection (convection)
@@ -674,7 +678,6 @@
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(bodytemperature >= species.heat_level_1)
//Body temperature is too hot.
- fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE)
return 1 //godmode
@@ -691,11 +694,9 @@
burn_dam = HEAT_DAMAGE_LEVEL_1
take_overall_damage(burn=burn_dam, used_weapon = "High Body Temperature")
- fire_alert = max(fire_alert, 2)
else if(bodytemperature <= species.cold_level_1)
//Body temperature is too cold.
- fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE)
return 1 //godmode
@@ -713,7 +714,6 @@
cold_dam = COLD_DAMAGE_LEVEL_1
take_overall_damage(burn=cold_dam, used_weapon = "Low Body Temperature")
- fire_alert = max(fire_alert, 1)
// Account for massive pressure differences. Done by Polymorph
// Made it possible to actually have something that can protect against high pressure... Done by Errorage. Polymorph now has an axe sticking from his head for his previous hardcoded nonsense!
@@ -723,13 +723,13 @@
if(adjusted_pressure >= species.hazard_high_pressure)
var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure")
- pressure_alert = 2
+ throw_alert("pressure", /obj/screen/alert/highpressure, 2)
else if(adjusted_pressure >= species.warning_high_pressure)
- pressure_alert = 1
+ throw_alert("pressure", /obj/screen/alert/highpressure, 1)
else if(adjusted_pressure >= species.warning_low_pressure)
- pressure_alert = 0
+ clear_alert("pressure")
else if(adjusted_pressure >= species.hazard_low_pressure)
- pressure_alert = -1
+ throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
else
if( !(COLD_RESISTANCE in mutations))
if(!isSynthetic() || !nif || !nif.flag_check(NIF_O_PRESSURESEAL,NIF_FLAGS_OTHER)) //VOREStation Edit - NIF pressure seals
@@ -747,9 +747,9 @@
// Firesuits (Min protection = 0.2 atmospheres) decrease oxyloss to 1/5
adjustOxyLoss(pressure_dam)
- pressure_alert = -2
+ throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
else
- pressure_alert = -1
+ clear_alert("pressure")
return
@@ -1009,12 +1009,14 @@
//Are they SSD? If so we'll keep them asleep but work off some of that sleep var in case of stoxin or similar.
if(client || sleeping > 3)
AdjustSleeping(-1)
+ throw_alert("asleep", /obj/screen/alert/asleep)
if( prob(2) && health && !hal_crit )
spawn(0)
emote("snore")
//CONSCIOUS
else
set_stat(CONSCIOUS)
+ clear_alert("asleep")
//Periodically double-check embedded_flag
if(embedded_flag && !(life_tick % 10))
@@ -1046,19 +1048,24 @@
SetBlinded(0)
blinded = 0
eye_blurry = 0
+ clear_alert("blind")
else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
SetBlinded(1)
blinded = 1
eye_blurry = 1
+ throw_alert("blind", /obj/screen/alert/blind)
else //You have the requisite organs
if(sdisabilities & BLIND) // Disabled-blind, doesn't get better on its own
blinded = 1
+ throw_alert("blind", /obj/screen/alert/blind)
else if(eye_blind) // Blindness, heals slowly over time
AdjustBlinded(-1)
blinded = 1
+ throw_alert("blind", /obj/screen/alert/blind)
else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster
eye_blurry = max(eye_blurry-3, 0)
blinded = 1
+ throw_alert("blind", /obj/screen/alert/blind)
//blurry sight
if(vision.is_bruised()) // Vision organs impaired? Permablurry.
@@ -1213,83 +1220,41 @@
healths_ma.overlays += health_images
healths.appearance = healths_ma
- if(nutrition_icon)
- var/prefix = isSynthetic() ? "c" : null
- switch(nutrition)
- if(450 to INFINITY) nutrition_icon.icon_state = "[prefix]nutrition0"
- if(350 to 450) nutrition_icon.icon_state = "[prefix]nutrition1"
- if(250 to 350) nutrition_icon.icon_state = "[prefix]nutrition2"
- if(150 to 250) nutrition_icon.icon_state = "[prefix]nutrition3"
- else nutrition_icon.icon_state = "[prefix]nutrition4"
- if(pressure)
- pressure.icon_state = "pressure[pressure_alert]"
+ var/fat_alert = /obj/screen/alert/fat
+ var/hungry_alert = /obj/screen/alert/hungry
+ var/starving_alert = /obj/screen/alert/starving
-// if(rest) //Not used with new UI
-// if(resting || lying || sleeping) rest.icon_state = "rest1"
-// else rest.icon_state = "rest0"
- if(toxin)
- if(hal_screwyhud == 4 || (phoron_alert && !does_not_breathe)) toxin.icon_state = "tox1"
- else toxin.icon_state = "tox0"
- if(oxygen)
- if(hal_screwyhud == 3 || (oxygen_alert && !does_not_breathe)) oxygen.icon_state = "oxy1"
- else oxygen.icon_state = "oxy0"
- if(fire)
- if(fire_alert) fire.icon_state = "fire[fire_alert]" //fire_alert is either 0 if no alert, 1 for cold and 2 for heat.
- else fire.icon_state = "fire0"
+ if(get_species() == SPECIES_CUSTOM)
+ var/datum/species/custom/C = species
+ if(/datum/trait/bloodsucker in C.traits)
+ fat_alert = /obj/screen/alert/fat/vampire
+ hungry_alert = /obj/screen/alert/hungry/vampire
+ starving_alert = /obj/screen/alert/starving/vampire
+ else if(isSynthetic())
+ fat_alert = /obj/screen/alert/fat/synth
+ hungry_alert = /obj/screen/alert/hungry/synth
+ starving_alert = /obj/screen/alert/starving/synth
- if(bodytemp)
- if (!species)
- switch(bodytemperature) //310.055 optimal body temp
- if(370 to INFINITY) bodytemp.icon_state = "temp4"
- if(350 to 370) bodytemp.icon_state = "temp3"
- if(335 to 350) bodytemp.icon_state = "temp2"
- if(320 to 335) bodytemp.icon_state = "temp1"
- if(300 to 320) bodytemp.icon_state = "temp0"
- if(295 to 300) bodytemp.icon_state = "temp-1"
- if(280 to 295) bodytemp.icon_state = "temp-2"
- if(260 to 280) bodytemp.icon_state = "temp-3"
- else bodytemp.icon_state = "temp-4"
+ switch(nutrition)
+ if(450 to INFINITY)
+ throw_alert("nutrition", fat_alert)
+ // if(350 to 450)
+ // if(250 to 350) // Alternative more-detailed tiers, not used.
+ if(250 to 450)
+ clear_alert("nutrition")
+ if(150 to 250)
+ throw_alert("nutrition", hungry_alert)
else
- //TODO: precalculate all of this stuff when the species datum is created
- var/base_temperature = species.body_temperature
- if(base_temperature == null) //some species don't have a set metabolic temperature
- base_temperature = (species.heat_level_1 + species.cold_level_1)/2
-
- var/temp_step
- if (bodytemperature >= base_temperature)
- temp_step = (species.heat_level_1 - base_temperature)/4
-
- if (bodytemperature >= species.heat_level_1)
- bodytemp.icon_state = "temp4"
- else if (bodytemperature >= base_temperature + temp_step*3)
- bodytemp.icon_state = "temp3"
- else if (bodytemperature >= base_temperature + temp_step*2)
- bodytemp.icon_state = "temp2"
- else if (bodytemperature >= base_temperature + temp_step*1)
- bodytemp.icon_state = "temp1"
- else
- bodytemp.icon_state = "temp0"
-
- else if (bodytemperature < base_temperature)
- temp_step = (base_temperature - species.cold_level_1)/4
-
- if (bodytemperature <= species.cold_level_1)
- bodytemp.icon_state = "temp-4"
- else if (bodytemperature <= base_temperature - temp_step*3)
- bodytemp.icon_state = "temp-3"
- else if (bodytemperature <= base_temperature - temp_step*2)
- bodytemp.icon_state = "temp-2"
- else if (bodytemperature <= base_temperature - temp_step*1)
- bodytemp.icon_state = "temp-1"
- else
- bodytemp.icon_state = "temp0"
+ throw_alert("nutrition", starving_alert)
if(blinded)
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
+ throw_alert("blind", /obj/screen/alert/blind)
else if(!machine)
clear_fullscreens()
+ clear_alert("blind")
if(disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription
if(glasses) //to every /obj/item
@@ -1301,6 +1266,10 @@
set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
set_fullscreen(druggy, "high", /obj/screen/fullscreen/high)
+ if(druggy)
+ throw_alert("high", /obj/screen/alert/high)
+ else
+ clear_alert("high")
if(config.welder_vision)
var/found_welder
diff --git a/code/modules/mob/living/carbon/human/species/station/alraune.dm b/code/modules/mob/living/carbon/human/species/station/alraune.dm
index f55935ac9e..8a0d93243a 100644
--- a/code/modules/mob/living/carbon/human/species/station/alraune.dm
+++ b/code/modules/mob/living/carbon/human/species/station/alraune.dm
@@ -146,9 +146,11 @@
else
H.adjustOxyLoss(ALRAUNE_CRIT_MAX_OXYLOSS)
- H.oxygen_alert = max(H.oxygen_alert, 1)
+ H.throw_alert("pressure", /obj/screen/alert/lowpressure)
return // skip air processing if there's no air
+ else
+ H.clear_alert("pressure")
// now into the good stuff
@@ -188,10 +190,10 @@
H.adjustOxyLoss(max(ALRAUNE_MAX_OXYLOSS*(1-ratio), 0))
failed_inhale = 1
- H.oxygen_alert = max(H.oxygen_alert, 1)
+ H.throw_alert("oxy", /obj/screen/alert/not_enough_co2)
else
// We're in safe limits
- H.oxygen_alert = 0
+ H.clear_alert("oxy")
inhaled_gas_used = inhaling/6
breath.adjust_gas("carbon_dioxide", -inhaled_gas_used, update = 0) //update afterwards
@@ -199,10 +201,9 @@
//Now we handle CO2.
if(inhale_pp > safe_exhaled_max * 0.7) // For a human, this would be too much exhaled gas in the air. But plants don't care.
- H.co2_alert = 1 // Give them the alert on the HUD. They'll be aware when the good stuff is present.
-
+ H.throw_alert("co2", /obj/screen/alert/too_much_co2/plant) // Give them the alert on the HUD. They'll be aware when the good stuff is present.
else
- H.co2_alert = 0
+ H.clear_alert("co2")
//do the CO2 buff stuff here
@@ -225,9 +226,9 @@
if(H.reagents)
H.reagents.add_reagent("toxin", CLAMP(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE))
breath.adjust_gas(poison_type, -poison/6, update = 0) //update after
- H.phoron_alert = max(H.phoron_alert, 1)
+ H.throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
else
- H.phoron_alert = 0
+ H.clear_alert("tox_in_air")
// If there's some other shit in the air lets deal with it here.
if(breath.gas["sleeping_agent"])
@@ -271,24 +272,18 @@
if(breath.temperature >= breath_heat_level_1)
if(breath.temperature < breath_heat_level_2)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, bodypart, used_weapon = "Excessive Heat")
- H.fire_alert = max(H.fire_alert, 2)
else if(breath.temperature < breath_heat_level_3)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, bodypart, used_weapon = "Excessive Heat")
- H.fire_alert = max(H.fire_alert, 2)
else
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, bodypart, used_weapon = "Excessive Heat")
- H.fire_alert = max(H.fire_alert, 2)
else if(breath.temperature <= breath_cold_level_1)
if(breath.temperature > breath_cold_level_2)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, bodypart, used_weapon = "Excessive Cold")
- H.fire_alert = max(H.fire_alert, 1)
else if(breath.temperature > breath_cold_level_3)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, bodypart, used_weapon = "Excessive Cold")
- H.fire_alert = max(H.fire_alert, 1)
else
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, bodypart, used_weapon = "Excessive Cold")
- H.fire_alert = max(H.fire_alert, 1)
//breathing in hot/cold air also heats/cools you a bit
diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm
index b4e04f745e..5950d069d5 100644
--- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm
+++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm
@@ -68,9 +68,6 @@
/datum/trait/bloodsucker/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
H.verbs |= /mob/living/carbon/human/proc/bloodsuck
- spawn(10 SECONDS) // Ugh!
- if(H?.nutrition_icon)
- H.nutrition_icon.icon = 'icons/mob/screen/vamp_hunger_vr.dmi'
/datum/trait/succubus_drain
name = "Succubus Drain"
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 2903bf604f..7b735b0dbe 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -855,11 +855,14 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(QDESTROYING(src))
return
+ clear_alert("legcuffed")
remove_layer(LEGCUFF_LAYER)
if(!legcuffed)
return //Not legcuffed, why bother.
+ throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = legcuffed)
+
overlays_standing[LEGCUFF_LAYER] = legcuffed.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_legcuffed_str, default_icon = INV_LCUFF_DEF_ICON, default_layer = LEGCUFF_LAYER)
apply_layer(LEGCUFF_LAYER)
diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm
index 248fe5c6a6..8af9d9e20d 100644
--- a/code/modules/mob/living/carbon/resist.dm
+++ b/code/modules/mob/living/carbon/resist.dm
@@ -1,173 +1,99 @@
-/mob/living/carbon/process_resist()
-
- //drop && roll
- if(on_fire && !buckled)
- adjust_fire_stacks(-1.2)
- Weaken(3)
- spin(32,2)
+/mob/living/carbon/resist_fire()
+ adjust_fire_stacks(-1.2)
+ Weaken(3)
+ spin(32,2)
+ visible_message(
+ "[src] rolls on the floor, trying to put themselves out!",
+ "You stop, drop, and roll!"
+ )
+ sleep(30)
+ if(fire_stacks <= 0)
visible_message(
- "[src] rolls on the floor, trying to put themselves out!",
- "You stop, drop, and roll!"
+ "[src] has successfully extinguished themselves!",
+ "You extinguish yourself."
)
- sleep(30)
- if(fire_stacks <= 0)
- visible_message(
- "[src] has successfully extinguished themselves!",
- "You extinguish yourself."
- )
- ExtinguishMob()
- return TRUE
+ ExtinguishMob()
+ return TRUE
+/mob/living/carbon/resist_restraints()
+ var/obj/item/I = null
if(handcuffed)
- spawn() escape_handcuffs()
+ I = handcuffed
else if(legcuffed)
- spawn() escape_legcuffs()
- else
- ..()
+ I = legcuffed
+
+ if(I)
+ setClickCooldown(100)
+ cuff_resist(I, cuff_break = can_break_cuffs())
-/mob/living/carbon/proc/escape_handcuffs()
- //if(!(last_special <= world.time)) return
+/mob/living/carbon/proc/reduce_cuff_time()
+ return FALSE
- //This line represent a significant buff to grabs...
- // We don't have to check the click cooldown because /mob/living/verb/resist() has done it for us, we can simply set the delay
- setClickCooldown(100)
+/mob/living/carbon/proc/cuff_resist(obj/item/weapon/handcuffs/I, breakouttime = 1200, cuff_break = 0)
+
+ if(istype(I))
+ breakouttime = I.breakouttime
- if(can_break_cuffs()) //Don't want to do a lot of logic gating here.
- break_handcuffs()
+ var/displaytime = breakouttime / 10
+
+ var/reduceCuffTime = reduce_cuff_time()
+ if(reduceCuffTime)
+ breakouttime /= reduceCuffTime
+ displaytime /= reduceCuffTime
+
+ if(cuff_break)
+ visible_message("[src] is trying to break [I]!",
+ "You attempt to break your [I]. (This will take around 5 seconds and you need to stand still)")
+
+ if(do_after(src, 5 SECONDS, target = src, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
+ if(!I || buckled)
+ return
+ visible_message("[src] manages to break [I]!",
+ "You successfully break your [I].")
+ say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
+
+ if(I == handcuffed)
+ handcuffed = null
+ update_handcuffed()
+ else if(I == legcuffed)
+ legcuffed = null
+ update_inv_legcuffed()
+
+ if(buckled && buckled.buckle_require_restraints)
+ buckled.unbuckle_mob()
+
+ qdel(I)
+ else
+ to_chat(src, "You fail to break [I].")
+ return
+
+ visible_message("[src] attempts to remove [I]!",
+ "You attempt to remove [I]. (This will take around [displaytime] seconds and you need to stand still)")
+ if(do_after(src, breakouttime, target = src, incapacitation_flags = INCAPACITATION_DISABLED & INCAPACITATION_KNOCKDOWN))
+ visible_message("[src] manages to remove [I]!",
+ "You successfully remove [I].")
+ drop_from_inventory(I)
+
+/mob/living/carbon/resist_buckle()
+ if(!buckled)
return
- var/obj/item/weapon/handcuffs/HC = handcuffed
+ if(!restrained())
+ return ..()
- //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/handcuffs type
- var/breakouttime = 1200
- var/displaytime = 2 //Minutes to display in the "this will take X minutes."
- //If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future...
- if(istype(HC))
- breakouttime = HC.breakouttime
- displaytime = breakouttime / 600 //Minutes
-
- var/mob/living/carbon/human/H = src
- if(istype(H) && H.gloves && istype(H.gloves,/obj/item/clothing/gloves/gauntlets/rig))
- breakouttime /= 2
- displaytime /= 2
-
- visible_message(
- "\The [src] attempts to remove \the [HC]!",
- "You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)"
- )
-
- if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DISABLED & INCAPACITATION_KNOCKDOWN))
- if(!handcuffed)
- return
- visible_message(
- "\The [src] manages to remove \the [handcuffed]!",
- "You successfully remove \the [handcuffed]."
- )
- drop_from_inventory(handcuffed)
-
-/mob/living/carbon/proc/escape_legcuffs()
- //if(!(last_special <= world.time)) return
-
- //This line represent a significant buff to grabs...
- // We don't have to check the click cooldown because /mob/living/verb/resist() has done it for us, we can simply set the delay
setClickCooldown(100)
-
- if(can_break_cuffs()) //Don't want to do a lot of logic gating here.
- break_legcuffs()
- return
-
- var/obj/item/weapon/handcuffs/legcuffs/LC = legcuffed
-
- //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/handcuffs/legcuffs type
- var/breakouttime = 1200
- var/displaytime = 2 //Minutes to display in the "this will take X minutes."
- //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future...
- if(istype(LC))
- breakouttime = LC.breakouttime
- displaytime = breakouttime / 600 //Minutes
-
- var/mob/living/carbon/human/H = src
- if(istype(H) && H.shoes && istype(H.shoes,/obj/item/clothing/shoes/magboots/rig))
- breakouttime /= 2
- displaytime /= 2
-
visible_message(
- "\The [src] attempts to remove \the [LC]!",
- "You attempt to remove \the [LC]. (This will take around [displaytime] minutes and you need to stand still)"
+ "[src] attempts to unbuckle themself!",
+ "You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stand still)"
)
- if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DISABLED & INCAPACITATION_KNOCKDOWN))
- if(!legcuffed)
+ if(do_after(src, 2 MINUTES, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY)))
+ if(!buckled)
return
- visible_message(
- "\The [src] manages to remove \the [legcuffed]!",
- "You successfully remove \the [legcuffed]."
- )
- drop_from_inventory(legcuffed)
- legcuffed = null
- update_inv_legcuffed()
+ visible_message("[src] manages to unbuckle themself!",
+ "You successfully unbuckle yourself.")
+ buckled.user_unbuckle_mob(src, src)
/mob/living/carbon/proc/can_break_cuffs()
if(HULK in mutations)
return 1
-
-/mob/living/carbon/proc/break_handcuffs()
- visible_message(
- "[src] is trying to break \the [handcuffed]!",
- "You attempt to break your [handcuffed.name]. (This will take around 5 seconds and you need to stand still)"
- )
-
- if(do_after(src, 5 SECONDS, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
- if(!handcuffed || buckled)
- return
-
- visible_message(
- "[src] manages to break \the [handcuffed]!",
- "You successfully break your [handcuffed.name]."
- )
-
- say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
-
- qdel(handcuffed)
- handcuffed = null
- if(buckled && buckled.buckle_require_restraints)
- buckled.unbuckle_mob()
- update_inv_handcuffed()
-
-/mob/living/carbon/proc/break_legcuffs()
- to_chat(src, "You attempt to break your legcuffs. (This will take around 5 seconds and you need to stand still)")
- visible_message("[src] is trying to break the legcuffs!")
-
- if(do_after(src, 5 SECONDS, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
- if(!legcuffed || buckled)
- return
-
- visible_message(
- "[src] manages to break the legcuffs!",
- "You successfully break your legcuffs."
- )
-
- say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
-
- qdel(legcuffed)
- legcuffed = null
- update_inv_legcuffed()
-
-/mob/living/carbon/escape_buckle()
- if(!buckled) return
-
- if(!restrained())
- ..()
- else
- setClickCooldown(100)
- visible_message(
- "[usr] attempts to unbuckle themself!",
- "You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stand still)"
- )
-
- if(do_after(usr, 2 MINUTES, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY)))
- if(!buckled)
- return
- visible_message("[usr] manages to unbuckle themself!",
- "You successfully unbuckle yourself.")
- buckled.user_unbuckle_mob(src, src)
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index c1ec71a84e..2fdfcf4c56 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -160,9 +160,14 @@
//Eyes
if(sdisabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own
SetBlinded(1)
+ throw_alert("blind", /obj/screen/alert/blind)
else if(eye_blind) //blindness, heals slowly over time
AdjustBlinded(-1)
- else if(eye_blurry) //blurry eyes heal slowly
+ throw_alert("blind", /obj/screen/alert/blind)
+ else
+ clear_alert("blind")
+
+ if(eye_blurry) //blurry eyes heal slowly
eye_blurry = max(eye_blurry-1, 0)
//Ears
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index d74f43bced..316bb2be88 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -860,53 +860,25 @@ default behaviour is:
process_resist()
/mob/living/proc/process_resist()
- //Getting out of someone's inventory.
- if(istype(src.loc, /obj/item/weapon/holder))
- escape_inventory(src.loc)
- return
-
//unbuckling yourself
if(buckled)
- spawn() escape_buckle()
+ resist_buckle()
return TRUE
- //Breaking out of a locker?
- if( src.loc && (istype(src.loc, /obj/structure/closet)) )
- var/obj/structure/closet/C = loc
- spawn() C.mob_breakout(src)
+ if(isobj(loc))
+ var/obj/C = loc
+ C.container_resist(src)
return TRUE
- if(istype(loc,/obj/item/clothing))
- spawn() escape_clothes(loc)
+ else if(canmove)
+ if(on_fire)
+ resist_fire() //stop, drop, and roll
+ else
+ resist_restraints()
if(attempt_vr(src,"vore_process_resist",args)) return TRUE //VOREStation Code
-/mob/living/proc/escape_inventory(obj/item/weapon/holder/H)
- if(H != src.loc) return
-
- var/mob/M = H.loc //Get our mob holder (if any).
-
- if(istype(M))
- M.drop_from_inventory(H)
- to_chat(M, "\The [H] wriggles out of your grip!")
- to_chat(src, "You wriggle out of \the [M]'s grip!")
-
- // Update whether or not this mob needs to pass emotes to contents.
- for(var/atom/A in M.contents)
- if(istype(A,/mob/living/simple_mob/animal/borer) || istype(A,/obj/item/weapon/holder))
- return
-
- else if(istype(H.loc,/obj/item/clothing/accessory/holster))
- var/obj/item/clothing/accessory/holster/holster = H.loc
- if(holster.holstered == H)
- holster.clear_holster()
- to_chat(src, "You extricate yourself from \the [holster].")
- H.forceMove(get_turf(H))
- else if(istype(H.loc,/obj/item))
- to_chat(src, "You struggle free of \the [H.loc].")
- H.forceMove(get_turf(H))
-
-/mob/living/proc/escape_buckle()
+/mob/living/proc/resist_buckle()
if(buckled)
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/vehicle = buckled
@@ -922,6 +894,12 @@ default behaviour is:
if(resisting)
visible_message("[src] resists!")
+/mob/living/proc/resist_fire()
+ return
+
+/mob/living/proc/resist_restraints()
+ return
+
/mob/living/verb/lay_down()
set name = "Rest"
set category = "IC"
@@ -1335,3 +1313,11 @@ default behaviour is:
BRAIN:[getBrainLoss()]
"}
+
+/mob/living/update_gravity(has_gravity)
+ if(!ticker)
+ return
+ if(has_gravity)
+ clear_alert("weightless")
+ else
+ throw_alert("weightless", /obj/screen/alert/weightless)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 428cff3659..b74edbcbba 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -328,6 +328,7 @@
O.loc = src
src.embedded += O
src.verbs += /mob/proc/yank_out_object
+ throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
//This is called when the mob is thrown into a dense turf
/mob/living/proc/turf_collision(var/turf/T, var/speed)
@@ -366,6 +367,7 @@
if(fire_stacks > 0 && !on_fire)
on_fire = 1
handle_light()
+ throw_alert("fire", /obj/screen/alert/fire)
update_fire()
/mob/living/proc/ExtinguishMob()
@@ -373,6 +375,7 @@
on_fire = 0
fire_stacks = 0
handle_light()
+ clear_alert("fire")
update_fire()
if(has_modifier_of_type(/datum/modifier/fire))
diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm
index 0071586458..5de4e9c3e2 100644
--- a/code/modules/mob/living/silicon/laws.dm
+++ b/code/modules/mob/living/silicon/laws.dm
@@ -11,6 +11,7 @@
return laws.zeroth_law != null
/mob/living/silicon/proc/set_zeroth_law(var/law, var/law_borg, notify = TRUE)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.set_zeroth_law(law, law_borg)
if(notify)
@@ -76,6 +77,7 @@
log_and_message_admins("cleared the supplied laws of [src]")
/mob/living/silicon/proc/notify_of_law_change(message)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
if((last_law_notification + 1 SECOND) > world.time)
return
last_law_notification = world.time
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index dbffa182fe..74aad9bae0 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -248,35 +248,22 @@
src.mind.special_role = "traitor"
traitors.current_antagonists |= src.mind
- if (src.cells)
- if (src.cell)
- var/cellcharge = src.cell.charge/src.cell.maxcharge
- switch(cellcharge)
- if(0.75 to INFINITY)
- src.cells.icon_state = "charge4"
- if(0.5 to 0.75)
- src.cells.icon_state = "charge3"
- if(0.25 to 0.5)
- src.cells.icon_state = "charge2"
- if(0 to 0.25)
- src.cells.icon_state = "charge1"
- else
- src.cells.icon_state = "charge0"
- else
- src.cells.icon_state = "charge-empty"
+ update_cell()
- if(bodytemp)
- switch(src.bodytemperature) //310.055 optimal body temp
- if(335 to INFINITY)
- src.bodytemp.icon_state = "temp2"
- if(320 to 335)
- src.bodytemp.icon_state = "temp1"
- if(300 to 320)
- src.bodytemp.icon_state = "temp0"
- if(260 to 300)
- src.bodytemp.icon_state = "temp-1"
+ var/turf/T = get_turf(src)
+ var/datum/gas_mixture/environment = T.return_air()
+ if(environment)
+ switch(environment.temperature) //310.055 optimal body temp
+ if(400 to INFINITY)
+ throw_alert("temp", /obj/screen/alert/hot/robot, 2)
+ if(360 to 400)
+ throw_alert("temp", /obj/screen/alert/hot/robot, 1)
+ if(260 to 360)
+ clear_alert("temp")
+ if(200 to 260)
+ throw_alert("temp", /obj/screen/alert/cold/robot, 1)
else
- src.bodytemp.icon_state = "temp-2"
+ throw_alert("temp", /obj/screen/alert/cold/robot, 2)
//Oxygen and fire does nothing yet!!
// if (src.oxygen) src.oxygen.icon_state = "oxy[src.oxygen_alert ? 1 : 0]"
@@ -298,20 +285,43 @@
if(client && !client.adminobs)
reset_view(null)
+ if(emagged)
+ throw_alert("hacked", /obj/screen/alert/hacked)
+ else
+ clear_alert("hacked")
+
return 1
+/mob/living/silicon/robot/proc/update_cell()
+ if(cell)
+ var/cellcharge = cell.charge/cell.maxcharge
+ switch(cellcharge)
+ if(0.75 to INFINITY)
+ clear_alert("charge")
+ if(0.5 to 0.75)
+ throw_alert("charge", /obj/screen/alert/lowcell, 1)
+ if(0.25 to 0.5)
+ throw_alert("charge", /obj/screen/alert/lowcell, 2)
+ if(0.01 to 0.25)
+ throw_alert("charge", /obj/screen/alert/lowcell, 3)
+ else
+ throw_alert("charge", /obj/screen/alert/emptycell)
+ else
+ throw_alert("charge", /obj/screen/alert/nocell)
+
+
/mob/living/silicon/robot/proc/update_items()
- if (src.client)
- src.client.screen -= src.contents
- for(var/obj/I in src.contents)
+ if(client)
+ client.screen -= contents
+ for(var/obj/I in contents)
if(I && !(istype(I,/obj/item/weapon/cell) || istype(I,/obj/item/device/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi)))
- src.client.screen += I
- if(src.module_state_1)
- src.module_state_1:screen_loc = ui_inv1
- if(src.module_state_2)
- src.module_state_2:screen_loc = ui_inv2
- if(src.module_state_3)
- src.module_state_3:screen_loc = ui_inv3
+ client.screen += I
+ if(module_state_1)
+ module_state_1:screen_loc = ui_inv1
+ if(module_state_2)
+ module_state_2:screen_loc = ui_inv2
+ if(module_state_3)
+ module_state_3:screen_loc = ui_inv3
updateicon()
/mob/living/silicon/robot/proc/process_killswitch()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 9a6c384e0c..63267c6e09 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -34,7 +34,6 @@
//Hud stuff
- var/obj/screen/cells = null
var/obj/screen/inv1 = null
var/obj/screen/inv2 = null
var/obj/screen/inv3 = null
@@ -935,6 +934,10 @@
// They stay locked down if their wire is cut.
if(wires.LockedCut())
state = 1
+ if(state)
+ throw_alert("locked", /obj/screen/alert/locked)
+ else
+ clear_alert("locked")
lockdown = state
lockcharge = state
update_canmove()
diff --git a/code/modules/mob/living/simple_mob/life.dm b/code/modules/mob/living/simple_mob/life.dm
index d4ed684deb..781589dad1 100644
--- a/code/modules/mob/living/simple_mob/life.dm
+++ b/code/modules/mob/living/simple_mob/life.dm
@@ -52,19 +52,14 @@
healths.icon_state = "health7"
//Updates the nutrition while we're here
- if(nutrition_icon)
- var/food_per = (nutrition / initial(nutrition)) * 100
- switch(food_per)
- if(90 to INFINITY)
- nutrition_icon.icon_state = "nutrition0"
- if(75 to 90)
- nutrition_icon.icon_state = "nutrition1"
- if(50 to 75)
- nutrition_icon.icon_state = "nutrition2"
- if(25 to 50)
- nutrition_icon.icon_state = "nutrition3"
- if(0 to 25)
- nutrition_icon.icon_state = "nutrition4"
+ var/food_per = (nutrition / initial(nutrition)) * 100
+ switch(food_per)
+ if(90 to INFINITY)
+ clear_alert("nutrition")
+ if(50 to 90)
+ throw_alert("nutrition", /obj/screen/alert/hungry)
+ if(-INFINITY to 50)
+ throw_alert("nutrition", /obj/screen/alert/starving)
// Override for special bullshit.
/mob/living/simple_mob/proc/handle_special()
@@ -91,54 +86,55 @@
if( abs(Environment.temperature - bodytemperature) > temperature_range ) //VOREStation Edit: heating adjustments
bodytemperature += ((Environment.temperature - bodytemperature) / 5)
- if(min_oxy)
- if(Environment.gas["oxygen"] < min_oxy)
- atmos_unsuitable = 1
- if(max_oxy)
- if(Environment.gas["oxygen"] > max_oxy)
- atmos_unsuitable = 1
- if(min_tox)
- if(Environment.gas["phoron"] < min_tox)
- atmos_unsuitable = 2
- if(max_tox)
- if(Environment.gas["phoron"] > max_tox)
- atmos_unsuitable = 2
- if(min_n2)
- if(Environment.gas["nitrogen"] < min_n2)
- atmos_unsuitable = 1
- if(max_n2)
- if(Environment.gas["nitrogen"] > max_n2)
- atmos_unsuitable = 1
- if(min_co2)
- if(Environment.gas["carbon_dioxide"] < min_co2)
- atmos_unsuitable = 1
- if(max_co2)
- if(Environment.gas["carbon_dioxide"] > max_co2)
- atmos_unsuitable = 1
+ if(min_oxy && Environment.gas["oxygen"] < min_oxy)
+ atmos_unsuitable = 1
+ throw_alert("oxy", /obj/screen/alert/not_enough_oxy)
+ else if(max_oxy && Environment.gas["oxygen"] > max_oxy)
+ atmos_unsuitable = 1
+ throw_alert("oxy", /obj/screen/alert/too_much_oxy)
+ else
+ clear_alert("oxy")
+
+ if(min_tox && Environment.gas["phoron"] < min_tox)
+ atmos_unsuitable = 2
+ throw_alert("tox_in_air", /obj/screen/alert/not_enough_tox)
+ else if(max_tox && Environment.gas["phoron"] > max_tox)
+ atmos_unsuitable = 2
+ throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
+ else
+ clear_alert("tox_in_air")
+
+ if(min_n2 && Environment.gas["nitrogen"] < min_n2)
+ atmos_unsuitable = 1
+ throw_alert("n2o", /obj/screen/alert/not_enough_nitro)
+ else if(max_n2 && Environment.gas["nitrogen"] > max_n2)
+ atmos_unsuitable = 1
+ throw_alert("n2o", /obj/screen/alert/too_much_nitro)
+ else
+ clear_alert("n2o")
+
+ if(min_co2 && Environment.gas["carbon_dioxide"] < min_co2)
+ atmos_unsuitable = 1
+ throw_alert("co2", /obj/screen/alert/not_enough_co2)
+ else if(max_co2 && Environment.gas["carbon_dioxide"] > max_co2)
+ atmos_unsuitable = 1
+ throw_alert("co2", /obj/screen/alert/too_much_co2)
+ else
+ clear_alert("co2")
//Atmos effect
if(bodytemperature < minbodytemp)
- fire_alert = 2
adjustFireLoss(cold_damage_per_tick)
- if(fire)
- fire.icon_state = "fire1"
+ throw_alert("temp", /obj/screen/alert/cold, 3)
else if(bodytemperature > maxbodytemp)
- fire_alert = 1
adjustFireLoss(heat_damage_per_tick)
- if(fire)
- fire.icon_state = "fire2"
+ throw_alert("temp", /obj/screen/alert/hot, 3)
else
- fire_alert = 0
- if(fire)
- fire.icon_state = "fire0"
+ clear_alert("temp")
if(atmos_unsuitable)
adjustOxyLoss(unsuitable_atoms_damage)
- if(oxygen)
- oxygen.icon_state = "oxy1"
- else if(oxygen)
- if(oxygen)
- oxygen.icon_state = "oxy0"
+ else
adjustOxyLoss(-unsuitable_atoms_damage)
diff --git a/code/modules/mob/living/simple_mob/simple_hud.dm b/code/modules/mob/living/simple_mob/simple_hud.dm
index fe851648b4..c16af17ae9 100644
--- a/code/modules/mob/living/simple_mob/simple_hud.dm
+++ b/code/modules/mob/living/simple_mob/simple_hud.dm
@@ -159,53 +159,7 @@
healths.screen_loc = ui_health
hud_elements |= healths
- //Oxygen dep icon
- oxygen = new /obj/screen()
- oxygen.icon = ui_style
- oxygen.icon_state = "oxy0"
- oxygen.name = "oxygen"
- oxygen.screen_loc = ui_oxygen
- hud_elements |= oxygen
- //Toxins present icon
- toxin = new /obj/screen()
- toxin.icon = ui_style
- toxin.icon_state = "tox0"
- toxin.name = "toxin"
- toxin.screen_loc = ui_toxin
- hud_elements |= toxin
-
- //Fire warning
- fire = new /obj/screen()
- fire.icon = ui_style
- fire.icon_state = "fire0"
- fire.name = "fire"
- fire.screen_loc = ui_fire
- hud_elements |= fire
-
- //Pressure warning
- pressure = new /obj/screen()
- pressure.icon = ui_style
- pressure.icon_state = "pressure0"
- pressure.name = "pressure"
- pressure.screen_loc = ui_pressure
- hud_elements |= pressure
-
- //Body temp warning
- bodytemp = new /obj/screen()
- bodytemp.icon = ui_style
- bodytemp.icon_state = "temp0"
- bodytemp.name = "body temperature"
- bodytemp.screen_loc = ui_temp
- hud_elements |= bodytemp
-
- //Nutrition status
- nutrition_icon = new /obj/screen()
- nutrition_icon.icon = ui_style
- nutrition_icon.icon_state = "nutrition0"
- nutrition_icon.name = "nutrition"
- nutrition_icon.screen_loc = ui_nutrition
- hud_elements |= nutrition_icon
pain = new /obj/screen( null )
diff --git a/code/modules/mob/living/simple_mob/simple_mob.dm b/code/modules/mob/living/simple_mob/simple_mob.dm
index 3b063e1ac4..82d16472c1 100644
--- a/code/modules/mob/living/simple_mob/simple_mob.dm
+++ b/code/modules/mob/living/simple_mob/simple_mob.dm
@@ -67,7 +67,6 @@
var/maxbodytemp = 350 // Maximum of above
var/heat_damage_per_tick = 3 // Amount of damage applied if animal's body temperature is higher than maxbodytemp
var/cold_damage_per_tick = 2 // Same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
- var/fire_alert = 0 // 0 = fine, 1 = hot, 2 = cold
var/min_oxy = 5 // Oxygen in moles, minimum, 0 is 'no minimum'
var/max_oxy = 0 // Oxygen in moles, maximum, 0 is 'no maximum'
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 34a7035d22..e83f10116a 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -51,7 +51,6 @@
else
client.eye = src
client.perspective = MOB_PERSPECTIVE
- reload_fullscreen() // Reload any fullscreen overlays this mob has.
add_click_catcher()
update_client_color()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 6232f90dd7..4d3187bdd2 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -22,16 +22,10 @@
pullin = null
purged = null
internals = null
- oxygen = null
i_select = null
m_select = null
- toxin = null
- fire = null
- bodytemp = null
healths = null
throw_icon = null
- nutrition_icon = null
- pressure = null
pain = null
item_use_icon = null
gun_move_icon = null
@@ -962,6 +956,7 @@ mob/proc/yank_out_object()
valid_objects = get_visible_implants(0)
if(valid_objects.len == 1) //Yanking out last object - removing verb.
src.verbs -= /mob/proc/yank_out_object
+ clear_alert("embeddedobject")
if(ishuman(src))
var/mob/living/carbon/human/H = src
@@ -1233,3 +1228,11 @@ mob/proc/yank_out_object()
/mob/proc/GetAltName()
return ""
+
+/mob/proc/get_ghost(even_if_they_cant_reenter = 0)
+ if(mind)
+ return mind.get_ghost(even_if_they_cant_reenter)
+
+/mob/proc/grab_ghost(force)
+ if(mind)
+ return mind.grab_ghost(force = force)
\ No newline at end of file
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 111bcab799..375dd0a755 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -16,16 +16,10 @@
var/obj/screen/pullin = null
var/obj/screen/purged = null
var/obj/screen/internals = null
- var/obj/screen/oxygen = null
var/obj/screen/i_select = null
var/obj/screen/m_select = null
- var/obj/screen/toxin = null
- var/obj/screen/fire = null
- var/obj/screen/bodytemp = null
var/obj/screen/healths = null
var/obj/screen/throw_icon = null
- var/obj/screen/nutrition_icon = null
- var/obj/screen/pressure = null
var/obj/screen/pain = null
var/obj/screen/gun/item/item_use_icon = null
var/obj/screen/gun/radio/radio_use_icon = null
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 22249811c8..7f4c48f89f 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -469,6 +469,8 @@ This function completely restores a damaged organ to perfect condition.
if(!istype(implanted_object,/obj/item/weapon/implant) && !istype(implanted_object,/obj/item/device/nif)) // We don't want to remove REAL implants. Just shrapnel etc. //VOREStation Edit - NIFs pls
implanted_object.loc = get_turf(src)
implants -= implanted_object
+ if(!owner.has_embedded_objects())
+ owner.clear_alert("embeddedobject")
if(owner && !ignore_prosthetic_prefs)
if(owner.client && owner.client.prefs && owner.client.prefs.real_name == owner.real_name)
@@ -1184,6 +1186,7 @@ Note that amputating the affected organ does in fact remove the infection from t
implants += W
owner.embedded_flag = 1
owner.verbs += /mob/proc/yank_out_object
+ owner.throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
W.add_blood(owner)
if(ismob(W.loc))
var/mob/living/H = W.loc
@@ -1372,4 +1375,11 @@ Note that amputating the affected organ does in fact remove the infection from t
if(bling.body_parts_covered & src.body_part)
covering_clothing |= bling
- return covering_clothing
\ No newline at end of file
+ return covering_clothing
+
+/mob/living/carbon/human/proc/has_embedded_objects()
+ . = 0
+ for(var/obj/item/organ/external/L in organs)
+ for(var/obj/item/I in L.implants)
+ if(!istype(I,/obj/item/weapon/implant) && !istype(I,/obj/item/device/nif))
+ return 1
\ No newline at end of file
diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm
index e7e6eb6b4b..624d94443c 100644
--- a/code/modules/surgery/implant.dm
+++ b/code/modules/surgery/implant.dm
@@ -206,6 +206,8 @@
user.visible_message("[user] takes something out of incision on [target]'s [affected.name] with \the [tool]!", \
"You take [obj] out of incision on [target]'s [affected.name]s with \the [tool]!" )
affected.implants -= obj
+ if(!target.has_embedded_objects())
+ target.clear_alert("embeddedobject")
BITSET(target.hud_updateflag, IMPLOYAL_HUD)
diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm
index 9cc0dd7224..373da4d551 100644
--- a/code/modules/vore/eating/belly_obj_vr.dm
+++ b/code/modules/vore/eating/belly_obj_vr.dm
@@ -720,3 +720,6 @@
dupe.emote_lists[K] += I
return dupe
+
+/obj/belly/container_resist(mob/M)
+ return relay_resist(M)
\ No newline at end of file
diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm
index e73eff48f3..492482eb5c 100644
--- a/code/modules/vore/eating/living_vr.dm
+++ b/code/modules/vore/eating/living_vr.dm
@@ -185,10 +185,11 @@
//
/mob/living/proc/vore_process_resist()
//Are we resisting from inside a belly?
- if(isbelly(loc))
- var/obj/belly/B = loc
- B.relay_resist(src)
- return TRUE //resist() on living does this TRUE thing.
+ // if(isbelly(loc))
+ // var/obj/belly/B = loc
+ // B.relay_resist(src)
+ // return TRUE //resist() on living does this TRUE thing.
+ // Note: This is no longer required, as the refactors to resisting allow bellies to just define container_resist
//Other overridden resists go here
return FALSE
@@ -509,51 +510,6 @@
"oxygen" = 21,
"nitrogen" = 79)
-// Procs for micros stuffed into boots and the like to escape from them
-/mob/living/proc/escape_clothes(obj/item/clothing/C)
- ASSERT(loc == C)
-
- if(ishuman(C.loc)) //In a /mob/living/carbon/human
- var/mob/living/carbon/human/H = C.loc
- if(H.shoes == C) //Being worn
- to_chat(src," You start to climb around the larger creature's feet and ankles!")
- to_chat(H,"Something is trying to climb out of your [C]!")
- var/original_loc = H.loc
- for(var/escape_time = 100,escape_time > 0,escape_time--)
- if(H.loc != original_loc)
- to_chat(src,"You're pinned back underfoot!")
- to_chat(H,"You pin the escapee back underfoot!")
- return
- if(loc != C)
- return
- sleep(1)
-
- to_chat(src,"You manage to escape \the [C]!")
- to_chat(H,"Somone has climbed out of your [C]!")
- forceMove(H.loc)
-
- else //Being held by a human
- to_chat(src,"You start to climb out of \the [C]!")
- to_chat(H,"Something is trying to climb out of your [C]!")
- for(var/escape_time = 60,escape_time > 0,escape_time--)
- if(H.shoes == C)
- to_chat(src,"You're pinned underfoot!")
- to_chat(H,"You pin the escapee underfoot!")
- return
- if(loc != C)
- return
- sleep(1)
- to_chat(src,"You manage to escape \the [C]!")
- to_chat(H,"Somone has climbed out of your [C]!")
- forceMove(H.loc)
-
- to_chat(src,"You start to climb out of \the [C]!")
- sleep(50)
- if(loc == C)
- to_chat(src,"You climb out of \the [C]!")
- forceMove(C.loc)
- return
-
/mob/living/proc/feed_grabbed_to_self_falling_nom(var/mob/living/user, var/mob/living/prey)
var/belly = user.vore_selected
return perform_the_nom(user, prey, user, belly, delay = 1) //1/10th of a second is probably fine.
diff --git a/icons/mob/screen/midnight.dmi b/icons/mob/screen/midnight.dmi
index a2519bf1d5..e0ff03e0bf 100644
Binary files a/icons/mob/screen/midnight.dmi and b/icons/mob/screen/midnight.dmi differ
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
new file mode 100644
index 0000000000..32921f3213
Binary files /dev/null and b/icons/mob/screen_alert.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index 1b814ea422..e943234da0 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -149,6 +149,7 @@
#include "code\_onclick\hud\ability_screen_objects.dm"
#include "code\_onclick\hud\action.dm"
#include "code\_onclick\hud\ai.dm"
+#include "code\_onclick\hud\alert.dm"
#include "code\_onclick\hud\alien_larva.dm"
#include "code\_onclick\hud\fullscreen.dm"
#include "code\_onclick\hud\gun_mode.dm"