diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index b11df7a0f63..50527c33329 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -69,6 +69,14 @@
#define ui_borg_radio "EAST-1:28,SOUTH+1:7"
#define ui_borg_intents "EAST-2:26,SOUTH:5"
+//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"
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
new file mode 100644
index 00000000000..ca3f223c80d
--- /dev/null
+++ b/code/_onclick/hud/alert.dm
@@ -0,0 +1,400 @@
+//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
+ new_master.layer = FLOAT_LAYER
+ alert.overlays += new_master
+ new_master.layer = old_layer
+ 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/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 = "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/nitro
+ name = "Choking (No N)"
+ desc = "You're not getting enough nitrogen. Find some good air before you pass out!"
+ icon_state = "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/not_enough_tox
+ name = "Choking (No Plasma)"
+ desc = "You're not getting enough plasma. Find some good air before you pass out!"
+ icon_state = "not_enough_tox"
+
+/obj/screen/alert/tox_in_air
+ name = "Choking (Plasma)"
+ desc = "There's highly flammable, toxic plasma 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 = "tox_in_air"
+//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/hungry
+ name = "Hungry"
+ desc = "Some food would be good right about now."
+ icon_state = "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/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/drunk //Not implemented
+ name = "Drunk"
+ desc = "All that alcohol you've been drinking is impairing your speech, motor skills, and mental cognition. Make sure to act like it."
+ icon_state = "drunk"
+
+/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/dead/observer/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
\ No newline at end of file
diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm
index fa7017fd2d8..2842facc713 100644
--- a/code/_onclick/hud/alien.dm
+++ b/code/_onclick/hud/alien.dm
@@ -125,24 +125,6 @@
mymob.throw_icon.name = "throw"
mymob.throw_icon.screen_loc = ui_drop_throw
- mymob.oxygen = new /obj/screen()
- mymob.oxygen.icon = 'icons/mob/screen1_alien.dmi'
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_alien_oxygen
-
- mymob.toxin = new /obj/screen()
- mymob.toxin.icon = 'icons/mob/screen1_alien.dmi'
- mymob.toxin.icon_state = "tox0"
- mymob.toxin.name = "toxin"
- mymob.toxin.screen_loc = ui_alien_toxin
-
- 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_alien_fire
-
mymob.healths = new /obj/screen()
mymob.healths.icon = 'icons/mob/screen1_alien.dmi'
mymob.healths.icon_state = "health0"
@@ -173,6 +155,6 @@
mymob.client.screen = list()
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.toxin, mymob.fire, mymob.healths, nightvisionicon, mymob.pullin, alien_plasma_display, mymob.pullin) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach )
+ mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.healths, nightvisionicon, mymob.pullin, alien_plasma_display, mymob.pullin) //, mymob.hands, 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/alien_larva.dm b/code/_onclick/hud/alien_larva.dm
index 8232f2073e2..dca63c7d2ae 100644
--- a/code/_onclick/hud/alien_larva.dm
+++ b/code/_onclick/hud/alien_larva.dm
@@ -24,26 +24,6 @@
src.adding += using
move_intent = using
- mymob.oxygen = new /obj/screen()
- mymob.oxygen.icon = 'icons/mob/screen1_alien.dmi'
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_alien_oxygen
-
- mymob.toxin = new /obj/screen()
- mymob.toxin.icon = 'icons/mob/screen1_alien.dmi'
- mymob.toxin.icon_state = "tox0"
- mymob.toxin.name = "toxin"
- mymob.toxin.screen_loc = ui_alien_toxin
-
-
- 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_alien_fire
-
-
mymob.healths = new /obj/screen()
mymob.healths.icon = 'icons/mob/screen1_alien.dmi'
mymob.healths.icon_state = "health0"
@@ -68,6 +48,6 @@
mymob.client.screen = list()
- mymob.client.screen += list( mymob.zone_sel, mymob.oxygen, mymob.toxin, mymob.fire, mymob.healths, nightvisionicon, mymob.pullin) //, mymob.rest, mymob.sleep, mymob.mach )
+ mymob.client.screen += list( mymob.zone_sel, mymob.healths, nightvisionicon, mymob.pullin) //, 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/bot.dm b/code/_onclick/hud/bot.dm
index c4488376309..4f205b04567 100644
--- a/code/_onclick/hud/bot.dm
+++ b/code/_onclick/hud/bot.dm
@@ -30,18 +30,6 @@
mymob.healths.name = "health"
mymob.healths.screen_loc = ui_borg_health
- mymob.oxygen = new /obj/screen()
- mymob.oxygen.icon = 'icons/mob/screen1_bot.dmi'
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_oxygen
-
- mymob.fire = new /obj/screen()
- mymob.fire.icon = 'icons/mob/screen1_bot.dmi'
- mymob.fire.icon_state = "fire0"
- mymob.fire.name = "fire"
- mymob.fire.screen_loc = ui_fire
-
mymob.pullin = new /obj/screen/pull()
mymob.pullin.icon = 'icons/mob/screen1_bot.dmi'
mymob.pullin.update_icon(mymob)
@@ -49,7 +37,7 @@
mymob.client.screen = list()
- mymob.client.screen += list(mymob.oxygen, mymob.fire, mymob.healths, mymob.pullin)
+ mymob.client.screen += list(mymob.healths, mymob.pullin)
mymob.client.screen += adding + other
mymob.client.screen += mymob.client.void
return
\ No newline at end of file
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index fa414ba0dea..3c11b91a9b0 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -127,6 +127,9 @@ datum/hud/New(mob/owner)
corgi_hud()
reload_fullscreen()
+ persistant_inventory_update()
+ mymob.update_action_buttons()
+ reorganize_alerts()
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
/mob/verb/button_pressed_F12(var/full = 0 as null)
@@ -192,7 +195,7 @@ datum/hud/New(mob/owner)
hud_used.hidden_inventory_update()
hud_used.persistant_inventory_update()
update_action_buttons()
- //hud_used.reorganize_alerts()
+ hud_used.reorganize_alerts()
else
to_chat(usr, "\red Inventory hiding is currently only supported for human mobs, sorry.")
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 8dabef48583..d75f7c8ad61 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -358,42 +358,12 @@
mymob.throw_icon.alpha = ui_alpha
src.hotkeybuttons += mymob.throw_icon
- 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
-
- 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
-
- 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
-
mymob.internals = new /obj/screen/internals()
mymob.internals.icon = ui_style
mymob.internals.icon_state = "internal0"
mymob.internals.name = "internal"
mymob.internals.screen_loc = ui_internal
- 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
-
- 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
-
mymob.healths = new /obj/screen()
mymob.healths.icon = ui_style
mymob.healths.icon_state = "health0"
@@ -406,12 +376,6 @@
mymob.healthdoll.name = "health doll"
mymob.healthdoll.screen_loc = ui_healthdoll
- 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
-
mymob.pullin = new /obj/screen/pull()
mymob.pullin.icon = ui_style
mymob.pullin.update_icon(mymob)
@@ -454,7 +418,7 @@
mymob.client.screen = list()
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.healthdoll, mymob.nutrition_icon, mymob.pullin, mymob.gun_setting_icon, lingchemdisplay, lingstingdisplay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
+ mymob.client.screen += list(mymob.throw_icon, mymob.zone_sel, mymob.internals, mymob.healths, mymob.healthdoll, mymob.pullin, mymob.gun_setting_icon, lingchemdisplay, lingstingdisplay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
mymob.client.screen += src.adding + src.hotkeybuttons
mymob.client.screen += mymob.client.void
inventory_shown = 0
diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm
index b7a9a102116..34d26e77d6d 100644
--- a/code/_onclick/hud/monkey.dm
+++ b/code/_onclick/hud/monkey.dm
@@ -126,42 +126,12 @@
mymob.throw_icon.alpha = ui_alpha
src.hotkeybuttons += mymob.throw_icon
- 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
-
- 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
-
- 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
-
mymob.internals = new /obj/screen/internals()
mymob.internals.icon = ui_style
mymob.internals.icon_state = "internal0"
mymob.internals.name = "internal"
mymob.internals.screen_loc = ui_internal
- 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
-
- 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
-
mymob.healths = new /obj/screen()
mymob.healths.icon = ui_style
mymob.healths.icon_state = "health0"
@@ -174,12 +144,6 @@
mymob.healthdoll.name = "health doll"
mymob.healthdoll.screen_loc = ui_healthdoll
- 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
-
mymob.pullin = new /obj/screen/pull()
mymob.pullin.icon = ui_style
mymob.pullin.update_icon(mymob)
@@ -223,7 +187,7 @@
mymob.client.screen = list()
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.healthdoll, mymob.nutrition_icon, mymob.pullin, mymob.gun_setting_icon, lingchemdisplay, lingstingdisplay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
+ mymob.client.screen += list(mymob.throw_icon, mymob.zone_sel, mymob.internals, mymob.healths, mymob.healthdoll, mymob.pullin, mymob.gun_setting_icon, lingchemdisplay, lingstingdisplay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
mymob.client.screen += src.adding + src.hotkeybuttons
mymob.client.screen += mymob.client.void
diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm
index e0b1ea11f1a..331c04fc69f 100644
--- a/code/_onclick/hud/other_mobs.dm
+++ b/code/_onclick/hud/other_mobs.dm
@@ -6,12 +6,6 @@
return
/datum/hud/proc/corgi_hud(u)
- mymob.fire = new /obj/screen()
- mymob.fire.icon = 'icons/mob/screen1_corgi.dmi'
- mymob.fire.icon_state = "fire0"
- mymob.fire.name = "fire"
- mymob.fire.screen_loc = ui_fire
-
mymob.healths = new /obj/screen()
mymob.healths.icon = 'icons/mob/screen1_corgi.dmi'
mymob.healths.icon_state = "health0"
@@ -23,21 +17,8 @@
mymob.pullin.update_icon(mymob)
mymob.pullin.screen_loc = ui_construct_pull
- mymob.oxygen = new /obj/screen()
- mymob.oxygen.icon = 'icons/mob/screen1_corgi.dmi'
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_oxygen
-
- mymob.toxin = new /obj/screen()
- mymob.toxin.icon = 'icons/mob/screen1_corgi.dmi'
- mymob.toxin.icon_state = "tox0"
- mymob.toxin.name = "toxin"
- mymob.toxin.screen_loc = ui_toxin
-
mymob.client.screen = list()
-
- mymob.client.screen += list(mymob.fire, mymob.healths, mymob.pullin, mymob.oxygen, mymob.toxin)
+ mymob.client.screen += list(mymob.healths, mymob.pullin)
/datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm
index 8e729546b20..8a0fadf4e26 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/robot.dm
@@ -150,13 +150,6 @@
src.adding += using
action_intent = using
-//Cell
- mymob:cells = new /obj/screen()
- mymob:cells.icon = 'icons/mob/screen1_robot.dmi'
- mymob:cells.icon_state = "charge-empty"
- mymob:cells.name = "cell"
- mymob:cells.screen_loc = ui_toxin
-
//Health
mymob.healths = new /obj/screen()
mymob.healths.icon = 'icons/mob/screen1_robot.dmi'
@@ -186,25 +179,6 @@
mymob:lamp_button.name = "Toggle Headlamp"
mymob:lamp_button.screen_loc = ui_borg_lamp
-//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 = 'icons/mob/screen1_robot.dmi'
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_oxygen
-
- mymob.fire = new /obj/screen()
- mymob.fire.icon = 'icons/mob/screen1_robot.dmi'
- mymob.fire.icon_state = "fire0"
- mymob.fire.name = "fire"
- mymob.fire.screen_loc = ui_fire
-
mymob.pullin = new /obj/screen/pull()
mymob.pullin.icon = 'icons/mob/screen1_robot.dmi'
mymob.pullin.update_icon(mymob)
@@ -220,7 +194,7 @@
mymob.client.screen = list()
- mymob.client.screen += list(mymob.zone_sel, mymob.oxygen, mymob.fire, mymob.hands, mymob.healths, mymob:cells, mymob.pullin, mymob.gun_setting_icon, mymob:lamp_button) //, mymob.rest, mymob.sleep, mymob.mach )
+ mymob.client.screen += list(mymob.zone_sel, mymob.hands, mymob.healths, mymob.pullin, mymob.gun_setting_icon, mymob:lamp_button) //, mymob.rest, mymob.sleep, mymob.mach )
mymob.client.screen += src.adding + src.other
mymob.client.screen += mymob.client.void
return
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index bf4a46134a1..1751df19442 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -271,10 +271,7 @@
|| locate(/obj/machinery/computer/cloning, get_step(src, EAST)) \
|| locate(/obj/machinery/computer/cloning, get_step(src, WEST)))
- var/mob/dead/observer/ghost = occupant.get_ghost()
- if(ghost)
- to_chat(ghost, "Your corpse has been placed into a cloning scanner. Return to your body if you want to be cloned! (Verbs -> Ghost -> Re-enter corpse)")
- to_chat(ghost, sound('sound/effects/genetics.ogg'))
+ occupant.notify_ghost_cloning(source = src)
return
/obj/machinery/dna_scannernew/proc/go_out()
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index c409449dbe4..cdd57853759 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -776,7 +776,7 @@ var/list/sacrificed = list()
if (cultist.handcuffed)
cultist.handcuffed.loc = cultist.loc
cultist.handcuffed = null
- cultist.update_inv_handcuffed()
+ cultist.update_handcuffed()
if (cultist.legcuffed)
cultist.legcuffed.loc = cultist.loc
cultist.legcuffed = null
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index 11111cdfc69..472dea17cce 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -36,6 +36,27 @@
/mob/living/captive_brain/emote(var/message)
return
+/mob/living/captive_brain/resist_borer()
+ var/mob/living/simple_animal/borer/B = loc
+
+ to_chat(src, "You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).")
+ to_chat(B.host, "You feel the captive mind of [src] begin to resist your control.")
+
+ spawn(rand(350,450) + B.host.brainloss)
+
+ if(!B || !B.controlling)
+ return
+
+ B.host.adjustBrainLoss(rand(5,10))
+ to_chat(src, "With an immense exertion of will, you regain control of your body!")
+ to_chat(B.host, "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.")
+
+ B.detatch()
+
+ verbs -= /mob/living/carbon/proc/release_control
+ verbs -= /mob/living/carbon/proc/punish_host
+ verbs -= /mob/living/carbon/proc/spawn_larvae
+
/mob/living/simple_animal/borer
name = "cortical borer"
real_name = "cortical borer"
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 514ceb4b14e..773e81349a1 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -6,7 +6,7 @@
icon_state = "swarmer_unactivated"
/obj/item/unactivated_swarmer/New()
- notify_ghosts("An unactivated swarmer has been created in [get_area(src)]! (Click to enter)")
+ notify_ghosts("An unactivated swarmer has been created in [get_area(src)]!", enter_link = "(Click to enter)", source = src, attack_not_jump = 1)
..()
/obj/item/unactivated_swarmer/Topic(href, href_list)
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index 7616df4c119..273a4fe4fe6 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -12,7 +12,7 @@
. = ..()
if(can_buckle && buckled_mob)
return user_unbuckle_mob(user)
-
+
/atom/movable/attack_robot(mob/living/user)
. = ..()
if(can_buckle && buckled_mob && Adjacent(user)) // attack_robot is called on all ranges, so the Adjacent check is needed
@@ -46,6 +46,7 @@
buckled_mob = M
M.update_canmove()
post_buckle_mob(M)
+ M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src)
return 1
/atom/movable/proc/unbuckle_mob()
@@ -54,6 +55,7 @@
buckled_mob.buckled = null
buckled_mob.anchored = initial(buckled_mob.anchored)
buckled_mob.update_canmove()
+ buckled_mob.clear_alert("buckled")
buckled_mob = null
post_buckle_mob(.)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 8c4bf753108..417ad82d46b 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -53,6 +53,7 @@
var/strip_delay = DEFAULT_ITEM_STRIP_DELAY
var/put_on_delay = DEFAULT_ITEM_PUTON_DELAY
+ var/breakouttime = 0
/* Species-specific sprites, concept stolen from Paradise//vg/.
ex:
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index b111501820f..3ce6fc03130 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -12,7 +12,7 @@
throw_range = 5
materials = list(MAT_METAL=500)
origin_tech = "materials=1"
- var/breakouttime = 600 //Deciseconds = 60s = 1 minutes
+ breakouttime = 600 //Deciseconds = 60s = 1 minutes
var/cuffsound = 'sound/weapons/handcuffs.ogg'
var/trashtype = null //For disposable cuffs
@@ -50,7 +50,7 @@
else
loc = target
target.handcuffed = src
- target.update_inv_handcuffed(1)
+ target.update_handcuffed()
return
/obj/item/weapon/restraints/handcuffs/cable
@@ -121,7 +121,7 @@
if(do_mob(user, C, 30))
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
- C.update_inv_handcuffed(1)
+ C.update_handcuffed()
to_chat(user, "You handcuff [C].")
add_logs(C, user, "ziptie-cuffed")
else
@@ -133,110 +133,3 @@
/obj/item/weapon/restraints/handcuffs/cable/zipties/used/attack()
return
-
-//Legcuffs
-/obj/item/weapon/restraints/legcuffs
- name = "leg cuffs"
- desc = "Use this to keep prisoners in line."
- gender = PLURAL
- icon = 'icons/obj/items.dmi'
- icon_state = "handcuff"
- flags = CONDUCT
- throwforce = 0
- w_class = 3.0
- origin_tech = "materials=1"
- slowdown = 7
- var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute
-
-/obj/item/weapon/restraints/legcuffs/beartrap
- name = "bear trap"
- throw_speed = 1
- throw_range = 1
- icon_state = "beartrap0"
- desc = "A trap used to catch bears and other legged creatures."
- var/armed = 0
- var/obj/item/weapon/grenade/iedcasing/IED = null
-
-/obj/item/weapon/restraints/legcuffs/beartrap/Destroy()
- if(IED)
- qdel(IED)
- IED = null
- return ..()
-
-/obj/item/weapon/restraints/legcuffs/beartrap/suicide_act(mob/user)
- user.visible_message("[user] is sticking \his head in the [src.name]! It looks like \he's trying to commit suicide.")
- playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
- return (BRUTELOSS)
-
-/obj/item/weapon/restraints/legcuffs/beartrap/attack_self(mob/user as mob)
- ..()
- if(ishuman(user) && !user.stat && !user.restrained())
- armed = !armed
- icon_state = "beartrap[armed]"
- to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]")
-
-/obj/item/weapon/restraints/legcuffs/beartrap/attackby(var/obj/item/I, mob/user as mob) //Let's get explosive.
- if(istype(I, /obj/item/weapon/grenade/iedcasing))
- if(IED)
- to_chat(user, "This beartrap already has an IED hooked up to it!")
- return
- IED = I
- switch(IED.assembled)
- if(0,1) //if it's not fueled/hooked up
- to_chat(user, "You haven't prepared this IED yet!")
- IED = null
- return
- if(2,3)
- user.drop_item(src)
- I.forceMove(src)
- message_admins("[key_name_admin(user)] has rigged a beartrap with an IED.")
- log_game("[key_name(user)] has rigged a beartrap with an IED.")
- to_chat(user, "You sneak the [IED] underneath the pressure plate and connect the trigger wire.")
- desc = "A trap used to catch bears and other legged creatures. There is an IED hooked up to it."
- else
- to_chat(user, "You shouldn't be reading this message! Contact a coder or someone, something broke!")
- IED = null
- return
- if(istype(I, /obj/item/weapon/screwdriver))
- if(IED)
- IED.forceMove(get_turf(src))
- IED = null
- to_chat(user, "You remove the IED from the [src].")
- return
- ..()
-
-/obj/item/weapon/restraints/legcuffs/beartrap/Crossed(AM as mob|obj)
- if(armed && isturf(src.loc))
- if( (iscarbon(AM) || isanimal(AM)) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator))
- var/mob/living/L = AM
- armed = 0
- icon_state = "beartrap0"
- playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
- L.visible_message("[L] triggers \the [src].", \
- "You trigger \the [src]!")
-
- if(IED && isturf(src.loc))
- IED.active = 1
- IED.overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
- IED.icon_state = initial(icon_state) + "_active"
- IED.assembled = 3
- message_admins("[key_name_admin(usr)] has triggered an IED-rigged [name].")
- log_game("[key_name(usr)] has triggered an IED-rigged [name].")
- spawn(IED.det_time)
- IED.prime()
-
- if(ishuman(AM))
- var/mob/living/carbon/H = AM
- if(H.lying)
- H.apply_damage(20,BRUTE,"chest")
- else
- H.apply_damage(20,BRUTE,(pick("l_leg", "r_leg")))
- if(!H.legcuffed) //beartrap can't cuff you leg if there's already a beartrap or legcuffs.
- H.legcuffed = src
- src.loc = H
- H.update_inv_legcuffed(0)
- feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart.
-
- else
- L.apply_damage(20,BRUTE)
- ..()
diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm
index 88c555d8148..fa485cbf93b 100644
--- a/code/game/objects/items/weapons/legcuffs.dm
+++ b/code/game/objects/items/weapons/legcuffs.dm
@@ -1,5 +1,5 @@
-/obj/item/weapon/legcuffs
- name = "legcuffs"
+/obj/item/weapon/restraints/legcuffs
+ name = "leg cuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items.dmi'
@@ -8,7 +8,102 @@
throwforce = 0
w_class = 3.0
origin_tech = "materials=1"
- var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute
+ slowdown = 7
+ breakouttime = 300 //Deciseconds = 30s = 0.5 minute
+
+/obj/item/weapon/restraints/legcuffs/beartrap
+ name = "bear trap"
+ throw_speed = 1
+ throw_range = 1
+ icon_state = "beartrap0"
+ desc = "A trap used to catch bears and other legged creatures."
+ var/armed = 0
+ var/obj/item/weapon/grenade/iedcasing/IED = null
+
+/obj/item/weapon/restraints/legcuffs/beartrap/Destroy()
+ if(IED)
+ qdel(IED)
+ IED = null
+ return ..()
+
+/obj/item/weapon/restraints/legcuffs/beartrap/suicide_act(mob/user)
+ user.visible_message("[user] is sticking \his head in the [src.name]! It looks like \he's trying to commit suicide.")
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
+ return (BRUTELOSS)
+
+/obj/item/weapon/restraints/legcuffs/beartrap/attack_self(mob/user as mob)
+ ..()
+ if(ishuman(user) && !user.stat && !user.restrained())
+ armed = !armed
+ icon_state = "beartrap[armed]"
+ to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]")
+
+/obj/item/weapon/restraints/legcuffs/beartrap/attackby(var/obj/item/I, mob/user as mob) //Let's get explosive.
+ if(istype(I, /obj/item/weapon/grenade/iedcasing))
+ if(IED)
+ to_chat(user, "This beartrap already has an IED hooked up to it!")
+ return
+ IED = I
+ switch(IED.assembled)
+ if(0,1) //if it's not fueled/hooked up
+ to_chat(user, "You haven't prepared this IED yet!")
+ IED = null
+ return
+ if(2,3)
+ user.drop_item(src)
+ I.forceMove(src)
+ message_admins("[key_name_admin(user)] has rigged a beartrap with an IED.")
+ log_game("[key_name(user)] has rigged a beartrap with an IED.")
+ to_chat(user, "You sneak the [IED] underneath the pressure plate and connect the trigger wire.")
+ desc = "A trap used to catch bears and other legged creatures. There is an IED hooked up to it."
+ else
+ to_chat(user, "You shouldn't be reading this message! Contact a coder or someone, something broke!")
+ IED = null
+ return
+ if(istype(I, /obj/item/weapon/screwdriver))
+ if(IED)
+ IED.forceMove(get_turf(src))
+ IED = null
+ to_chat(user, "You remove the IED from the [src].")
+ return
+ ..()
+
+/obj/item/weapon/restraints/legcuffs/beartrap/Crossed(AM as mob|obj)
+ if(armed && isturf(src.loc))
+ if( (iscarbon(AM) || isanimal(AM)) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator))
+ var/mob/living/L = AM
+ armed = 0
+ icon_state = "beartrap0"
+ playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
+ L.visible_message("[L] triggers \the [src].", \
+ "You trigger \the [src]!")
+
+ if(IED && isturf(src.loc))
+ IED.active = 1
+ IED.overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
+ IED.icon_state = initial(icon_state) + "_active"
+ IED.assembled = 3
+ message_admins("[key_name_admin(usr)] has triggered an IED-rigged [name].")
+ log_game("[key_name(usr)] has triggered an IED-rigged [name].")
+ spawn(IED.det_time)
+ IED.prime()
+
+ if(ishuman(AM))
+ var/mob/living/carbon/H = AM
+ if(H.lying)
+ H.apply_damage(20,BRUTE,"chest")
+ else
+ H.apply_damage(20,BRUTE,(pick("l_leg", "r_leg")))
+ if(!H.legcuffed) //beartrap can't cuff you leg if there's already a beartrap or legcuffs.
+ H.legcuffed = src
+ src.loc = H
+ H.update_inv_legcuffed(0)
+ feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart.
+
+ else
+ L.apply_damage(20,BRUTE)
+ ..()
+
/obj/item/weapon/legcuffs/bolas
name = "bolas"
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index a187dc09b65..2a9b64748dd 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -127,7 +127,7 @@
C.handcuffed = null
if(C.buckled && C.buckled.buckle_requires_restraints)
C.buckled.unbuckle_mob()
- C.update_inv_handcuffed()
+ C.update_handcuffed()
return
else
..()
diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm
index cb29dec1926..25fe7f4a134 100644
--- a/code/game/objects/structures/spirit_board.dm
+++ b/code/game/objects/structures/spirit_board.dm
@@ -10,13 +10,6 @@
var/planchette = "A"
var/lastuser = null
-/obj/structure/spirit_board/proc/announce_to_ghosts()
- for(var/mob/dead/observer/O in player_list)
- if(O.client)
- var/area/A = get_area(src)
- if(A)
- to_chat(O, "\blue Someone has begun playing with a [src.name] in [A.name]!. (Teleport)")
-
/obj/structure/spirit_board/examine(mob/user)
..(user)
to_chat(user, "[initial(desc)] The planchette is sitting at \"[planchette]\".")
@@ -37,7 +30,7 @@
if(virgin)
virgin = 0
- announce_to_ghosts()
+ notify_ghosts("Someone has begun playing with a [src.name] in [get_area(src)]!", source = src)
planchette = input("Choose the letter.", "Seance!") in list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
add_logs(M, src, "picked a letter on", addition="which was \"[planchette]\".")
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index fa6d0015399..30e4793c747 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -81,4 +81,7 @@
control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
- var/datum/click_intercept/click_intercept = null
\ No newline at end of file
+ var/datum/click_intercept/click_intercept = null
+
+ //datum that controls the displaying and hiding of tooltips
+ var/datum/tooltip/tooltips
\ No newline at end of file
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 31db10045f0..57b7487cbe5 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -317,6 +317,10 @@
to_chat(src, "Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.")
+ //This is down here because of the browse() calls in tooltip/New()
+ if(!tooltips)
+ tooltips = new /datum/tooltip(src)
+
//////////////
//DISCONNECT//
//////////////
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 82b83db73ef..77afb5e2665 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -248,6 +248,16 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source)
if(message)
to_chat(src, "[message]")
+ if(source)
+ var/obj/screen/alert/A = throw_alert("\ref[source]_notify_cloning", /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)
to_chat(src, sound(sound))
@@ -563,6 +573,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
forceMove(T)
following = null
+
+ if(href_list["reenter"])
+ reenter_corpse()
+
..()
//END TELEPORT HREF CODE
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index a6bf793abe0..6192b0acc6b 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -102,22 +102,19 @@
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(bodytemperature > 360.15)
//Body temperature is too hot.
- fire_alert = max(fire_alert, 1)
+ throw_alert("alien_fire", /obj/screen/alert/alien_fire)
switch(bodytemperature)
if(360 to 400)
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
- fire_alert = max(fire_alert, 2)
if(400 to 460)
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
- fire_alert = max(fire_alert, 2)
if(460 to INFINITY)
if(on_fire)
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
- fire_alert = max(fire_alert, 2)
else
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
- fire_alert = max(fire_alert, 2)
- return
+ else
+ clear_alert("alien_fire")
/mob/living/carbon/alien/handle_mutations_and_radiation()
// Aliens love radiation nom nom nom
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index c50e4603e41..90fe6537759 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -343,6 +343,10 @@ In all, this is a lot like the monkey code. /N
/mob/living/carbon/alien/humanoid/canBeHandcuffed()
return 1
+/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
+ playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
+ ..(I, cuff_break = 1)
+
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
if(leaping)
return -32
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index 93bf633093f..cf602694233 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -7,19 +7,19 @@
return 0
var/toxins_used = 0
- var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
+ var/breath_pressure = (breath.total_moles() * R_IDEAL_GAS_EQUATION * breath.temperature) / BREATH_VOLUME
//Partial pressure of the toxins in our breath
- var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
+ var/Toxins_pp = (breath.toxins / breath.total_moles()) * breath_pressure
if(Toxins_pp) // Detect toxins in air
adjustPlasma(breath.toxins*250)
- toxins_alert = max(toxins_alert, 1)
+ throw_alert("alien_tox", /obj/screen/alert/alien_tox)
toxins_used = breath.toxins
else
- toxins_alert = 0
+ clear_alert("alien_tox")
//Breathe in toxins and out oxygen
breath.toxins -= toxins_used
@@ -30,14 +30,6 @@
return 1
-/mob/living/carbon/alien/handle_breath_temperature(datum/gas_mixture/breath)
- if(breath.temperature > (T0C + 66) && !(RESIST_COLD in mutations))
- if(prob(20))
- to_chat(src, "You feel a searing heat in your lungs!")
- fire_alert = max(fire_alert, 1)
- else
- fire_alert = 0
-
/mob/living/carbon/alien/update_sight()
if(stat == DEAD || (XRAY in mutations))
sight |= SEE_TURFS
diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm
index 07251303a12..f6cdb0362e3 100644
--- a/code/modules/mob/living/carbon/brain/posibrain.dm
+++ b/code/modules/mob/living/carbon/brain/posibrain.dm
@@ -47,8 +47,6 @@
for(var/mob/dead/observer/O in player_list)
if(check_observer(O))
to_chat(O, "\A [src] has been activated. (Teleport | Sign Up)")
-// if(ROLE_POSIBRAIN in O.client.prefs.be_special) The Guardian implementation looks cleaner
-// question(O.client)
/obj/item/device/mmi/posibrain/proc/check_observer(var/mob/dead/observer/O)
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 84348120528..26def9b6520 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -607,7 +607,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
handcuffed = null
if(buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob()
- update_inv_handcuffed()
+ update_handcuffed()
else if(I == legcuffed)
legcuffed = null
update_inv_legcuffed()
@@ -732,6 +732,131 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/mob/living/carbon/is_muzzled()
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
+/mob/living/carbon/proc/spin(spintime, speed)
+ spawn()
+ var/D = dir
+ while(spintime >= speed)
+ sleep(speed)
+ switch(D)
+ if(NORTH)
+ D = EAST
+ if(SOUTH)
+ D = WEST
+ if(EAST)
+ D = SOUTH
+ if(WEST)
+ D = NORTH
+ dir = D
+ spintime -= speed
+
+/mob/living/carbon/resist_buckle()
+ if(restrained())
+ changeNext_move(CLICK_CD_BREAKOUT)
+ last_special = world.time + CLICK_CD_BREAKOUT
+ visible_message("[src] attempts to unbuckle themself!", \
+ "You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)")
+ if(do_after(src, 600, 0, target = src))
+ if(!buckled)
+ return
+ buckled.user_unbuckle_mob(src,src)
+ else
+ if(src && buckled)
+ src << "You fail to unbuckle yourself!"
+ else
+ buckled.user_unbuckle_mob(src,src)
+
+/mob/living/carbon/resist_fire()
+ fire_stacks -= 5
+ weakened = max(weakened, 3)//We dont check for CANWEAKEN, I don't care how immune to weakening you are, if you're rolling on the ground, you're busy.
+ update_canmove()
+ 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] has successfully extinguished themselves!", \
+ "You extinguish yourself.")
+ ExtinguishMob()
+
+
+/mob/living/carbon/resist_restraints()
+ var/obj/item/I = null
+ if(handcuffed)
+ I = handcuffed
+ else if(legcuffed)
+ I = legcuffed
+ if(I)
+ changeNext_move(CLICK_CD_BREAKOUT)
+ last_special = world.time + CLICK_CD_BREAKOUT
+ cuff_resist(I)
+
+
+/mob/living/carbon/proc/cuff_resist(obj/item/I, breakouttime = 600, cuff_break = 0)
+ breakouttime = I.breakouttime
+
+ var/displaytime = breakouttime / 600
+ if(!cuff_break)
+ visible_message("[src] attempts to remove [I]!")
+ to_chat(src, "You attempt to remove [I]... (This will take around [displaytime] minutes and you need to stand still.)")
+ if(do_after(src, breakouttime, 0, target = src))
+ if(I.loc != src || buckled)
+ return
+ visible_message("[src] manages to remove [I]!")
+ to_chat(src, "You successfully remove [I].")
+
+ if(I == handcuffed)
+ handcuffed.loc = loc
+ handcuffed.dropped(src)
+ handcuffed = null
+ if(buckled && buckled.buckle_requires_restraints)
+ buckled.unbuckle_mob(src)
+ update_handcuffed()
+ return
+ if(I == legcuffed)
+ legcuffed.loc = loc
+ legcuffed.dropped()
+ legcuffed = null
+ update_inv_legcuffed()
+ return
+ return 1
+ else
+ to_chat(src, "You fail to remove [I]!")
+
+ else
+ breakouttime = 50
+ visible_message("[src] is trying to break [I]!")
+ to_chat(src, "You attempt to break [I]... (This will take around 5 seconds and you need to stand still.)")
+ if(do_after(src, breakouttime, 0, target = src))
+ if(!I.loc || buckled)
+ return
+ visible_message("[src] manages to break [I]!")
+ to_chat(src, "You successfully break [I].")
+ qdel(I)
+
+ if(I == handcuffed)
+ handcuffed = null
+ update_handcuffed()
+ return
+ else if(I == legcuffed)
+ legcuffed = null
+ update_inv_legcuffed()
+ return
+ return 1
+ else
+ to_chat(src, "You fail to break [I]!")
+
+//called when we get cuffed/uncuffed
+/mob/living/carbon/proc/update_handcuffed()
+ if(handcuffed)
+ drop_r_hand()
+ drop_l_hand()
+ stop_pulling()
+ throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
+ else
+ clear_alert("handcuffed")
+ update_action_buttons() //some of our action buttons might be unusable when we're handcuffed.
+ update_inv_handcuffed()
+
/mob/living/carbon/get_standard_pixel_y_offset(lying = 0)
if(lying)
if(buckled) return initial(pixel_y)
@@ -765,7 +890,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
handcuffed = null
if (buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob()
- update_inv_handcuffed()
+ update_handcuffed()
if (client)
client.screen -= W
if (W)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 5d27605b13c..2319b2e77c5 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1348,6 +1348,15 @@
update_inv_shoes(1)
return 1
+/mob/living/carbon/human/cuff_resist(obj/item/I)
+ if(HULK in mutations)
+ say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
+ if(..(I, cuff_break = 1))
+ unEquip(I)
+ else
+ if(..())
+ unEquip(I)
+
/mob/living/carbon/human/get_visible_implants(var/class = 0)
var/list/visible_implants = list()
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index bdd22a7e6fb..0f5f6a1a3d2 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -369,8 +369,7 @@
var/obj/item/organ/external/affected = get_organ("chest")
affected.add_autopsy_data("Suffocation", oxyloss)
-
- oxygen_alert = max(oxygen_alert, 1)
+ throw_alert("oxy", /obj/screen/alert/oxy)
return 0
@@ -384,7 +383,7 @@
// to_chat(world, "Loc temp: [loc_temp] - Body temp: [bodytemperature] - Fireloss: [getFireLoss()] - Thermal protection: [get_thermal_protection()] - Fire protection: [thermal_protection + add_fire_protection(loc_temp)] - Heat capacity: [environment_heat_capacity] - Location: [loc] - src: [src]")
//Body temperature is adjusted in two steps. Firstly your body tries to stabilize itself a bit.
- if(stat != 2)
+ if(stat != DEAD)
stabilize_temperature_from_calories()
//After then, it reacts to the surrounding atmosphere based on your thermal protection
@@ -403,41 +402,43 @@
// +/- 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
var/mult = species.hot_env_multiplier
if(bodytemperature >= species.heat_level_1 && bodytemperature <= species.heat_level_2)
+ throw_alert("temp", /obj/screen/alert/hot, 1)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
- fire_alert = max(fire_alert, 2)
if(bodytemperature > species.heat_level_2 && bodytemperature <= species.heat_level_3)
+ throw_alert("temp", /obj/screen/alert/hot, 2)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
- fire_alert = max(fire_alert, 2)
if(bodytemperature > species.heat_level_3 && bodytemperature < INFINITY)
+ throw_alert("temp", /obj/screen/alert/hot, 3)
if(on_fire)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire")
- fire_alert = max(fire_alert, 2)
else
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
- fire_alert = max(fire_alert, 2)
else if(bodytemperature < species.cold_level_1)
- fire_alert = max(fire_alert, 1)
- if(status_flags & GODMODE) return 1 //godmode
-
- if(stat == DEAD) return 1 //ZomgPonies -- No need for cold burn damage if dead
+ if(status_flags & GODMODE)
+ return 1
+ if(stat == DEAD)
+ return 1
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
var/mult = species.cold_env_multiplier
if(bodytemperature >= species.cold_level_2 && bodytemperature <= species.cold_level_1)
+ throw_alert("temp", /obj/screen/alert/cold, 1)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature")
- fire_alert = max(fire_alert, 1)
if(bodytemperature >= species.cold_level_3 && bodytemperature < species.cold_level_2)
+ throw_alert("temp", /obj/screen/alert/cold, 2)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_2, used_weapon = "Low Body Temperature")
- fire_alert = max(fire_alert, 1)
if(bodytemperature > -INFINITY && bodytemperature < species.cold_level_3)
+ throw_alert("temp", /obj/screen/alert/cold, 3)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_3, used_weapon = "Low Body Temperature")
- fire_alert = max(fire_alert, 1)
+ else
+ clear_alert("temp")
+ else
+ clear_alert("temp")
// 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!
@@ -449,21 +450,20 @@
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(RESIST_COLD in mutations)
- pressure_alert = -1
+ clear_alert("pressure")
else
take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
- pressure_alert = -2
+ throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
- return
///FIRE CODE
/mob/living/carbon/human/handle_fire()
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 9b68e5830cb..28da2348c23 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -52,6 +52,19 @@
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure.
+ var/list/atmos_requirements = list(
+ "min_oxy" = 16,
+ "max_oxy" = 0,
+ "min_nitro" = 0,
+ "max_nitro" = 0,
+ "min_tox" = 0,
+ "max_tox" = 0.005,
+ "min_co2" = 0,
+ "max_co2" = 10,
+ "sa_para" = 1,
+ "sa_sleep" = 5
+ )
+
var/brute_mod = null // Physical damage reduction/malus.
var/burn_mod = null // Burn damage reduction/malus.
@@ -181,66 +194,105 @@
O.owner = H
/datum/species/proc/handle_breath(var/datum/gas_mixture/breath, var/mob/living/carbon/human/H)
- var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
- //var/safe_oxygen_max = 140 // Maximum safe partial pressure of O2, in kPa (Not used for now)
- var/safe_co2_max = 10 // Yes it's an arbitrary value who cares?
- var/safe_toxins_max = 0.005
- var/SA_para_min = 1
- var/SA_sleep_min = 5
- var/oxygen_used = 0
- var/nitrogen_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
- var/vox_oxygen_max = 1 // For vox.
+
+ var/O2_used = 0
+ var/N2_used = 0
+ var/Tox_used = 0
+ var/CO2_used = 0
//Partial pressure of the O2 in our breath
- var/O2_pp = (breath.oxygen/breath.total_moles())*breath_pressure
- // Same, but for the toxins
- var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
- // And CO2, lets say a PP of more than 10 will be bad (It's a little less really, but eh, being passed out all round aint no fun)
- var/CO2_pp = (breath.carbon_dioxide/breath.total_moles())*breath_pressure // Tweaking to fit the hacky bullshit I've done with atmo -- TLE
- // Nitrogen, for Vox.
- var/Nitrogen_pp = (breath.nitrogen/breath.total_moles())*breath_pressure
+ var/O2_pp = (breath.oxygen/breath.total_moles()) * breath_pressure
+ // Partial pressure of Nitrogen
+ var/N2_pp = (breath.nitrogen/breath.total_moles()) * breath_pressure
+ // Partial pressure of plasma
+ var/Tox_pp = (breath.toxins/breath.total_moles()) * breath_pressure
+ // Partial pressure of CO2
+ var/CO2_pp = (breath.carbon_dioxide/breath.total_moles()) * breath_pressure
- // TODO: Split up into Voxs' own proc.
- if(O2_pp < safe_oxygen_min && name != "Vox") // Too little oxygen
+ if(O2_pp < atmos_requirements["min_oxy"])
if(prob(20))
spawn(0)
H.emote("gasp")
+
+ H.failed_last_breath = 1
if(O2_pp > 0)
- var/ratio = safe_oxygen_min/O2_pp
- H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all!)
- H.failed_last_breath = 1
- oxygen_used = breath.oxygen*ratio/6
+ var/ratio = atmos_requirements["min_oxy"] / O2_pp
+ H.adjustOxyLoss(min(5 * ratio, HUMAN_MAX_OXYLOSS))
else
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
- H.failed_last_breath = 1
- H.oxygen_alert = max(H.oxygen_alert, 1)
- else if(Nitrogen_pp < safe_oxygen_min && name == "Vox") //Vox breathe nitrogen, not oxygen.
+ H.throw_alert("oxy", /obj/screen/alert/oxy)
+ else if(atmos_requirements["max_oxy"] && O2_pp > atmos_requirements["max_oxy"])
+ var/ratio = (breath.oxygen / atmos_requirements["max_oxy"]) * 1000
+ H.adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
+ H.throw_alert("oxy", /obj/screen/alert/too_much_oxy)
+ else
+ H.clear_alert("oxy")
+ if(atmos_requirements["min_oxy"]) //species breathes this gas, so, they got their air
+ H.failed_last_breath = 0
+ H.adjustOxyLoss(-5)
+ O2_used = breath.oxygen / 6
+ if(N2_pp < atmos_requirements["min_nitro"])
if(prob(20))
- spawn(0) H.emote("gasp")
- if(Nitrogen_pp > 0)
- var/ratio = safe_oxygen_min/Nitrogen_pp
- H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS))
- H.failed_last_breath = 1
- nitrogen_used = breath.nitrogen*ratio/6
+ spawn(0)
+ H.emote("gasp")
+
+ H.failed_last_breath = 1
+ if(N2_pp > 0)
+ var/ratio = atmos_requirements["min_nitro"] / N2_pp
+ H.adjustOxyLoss(min(5 * ratio, HUMAN_MAX_OXYLOSS))
else
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
- H.failed_last_breath = 1
- H.oxygen_alert = max(H.oxygen_alert, 1)
+ H.throw_alert("nitro", /obj/screen/alert/nitro)
+ else if(atmos_requirements["max_nitro"] && N2_pp > atmos_requirements["max_nitro"])
+ var/ratio = (breath.nitrogen / atmos_requirements["max_nitro"]) * 1000
+ H.adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
+ H.throw_alert("nitro", /obj/screen/alert/too_much_nitro)
+ else
+ H.clear_alert("nitro")
+ if(atmos_requirements["min_nitro"]) //species breathes this gas, so they got their air
+ H.failed_last_breath = 0
+ H.adjustOxyLoss(-5)
+ N2_used = breath.nitrogen / 6
- else // We're in safe limits
- H.failed_last_breath = 0
- H.adjustOxyLoss(-5)
- oxygen_used = breath.oxygen/6
- H.oxygen_alert = 0
+ if(Tox_pp < atmos_requirements["min_tox"])
+ if(prob(20))
+ spawn(0)
+ H.emote("gasp")
- breath.oxygen -= oxygen_used
- breath.nitrogen -= nitrogen_used
- breath.carbon_dioxide += oxygen_used
+ H.failed_last_breath = 1
+ if(Tox_pp > 0)
+ var/ratio = atmos_requirements["min_tox"] / Tox_pp
+ H.adjustOxyLoss(min(5 * ratio, HUMAN_MAX_OXYLOSS))
+ else
+ H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
+ H.throw_alert("tox_in_air", /obj/screen/alert/not_enough_tox)
+ else if(atmos_requirements["max_tox"] && Tox_pp > atmos_requirements["max_tox"])
+ var/ratio = (breath.toxins / atmos_requirements["max_tox"]) * 10
+ if(H.reagents)
+ H.reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
+ H.throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
+ else
+ H.clear_alert("tox_in_air")
+ if(atmos_requirements["min_tox"]) //species breathes this gas, so, they got their air
+ H.failed_last_breath = 0
+ H.adjustOxyLoss(-5)
+ Tox_used = breath.toxins / 6
- //CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick.
- if(CO2_pp > safe_co2_max)
+ if(CO2_pp < atmos_requirements["min_co2"])
+ if(prob(20))
+ spawn(0)
+ H.emote("gasp")
+
+ H.failed_last_breath = 1
+ if(CO2_pp)
+ var/ratio = atmos_requirements["min_co2"] / CO2_pp
+ H.adjustOxyLoss(min(5 * ratio, HUMAN_MAX_OXYLOSS))
+ else
+ H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
+ H.throw_alert("co2", /obj/screen/alert/not_enough_co2)
+ else if(atmos_requirements["max_co2"] && CO2_pp > atmos_requirements["max_co2"])
if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
H.co2overloadtime = world.time
else if(world.time - H.co2overloadtime > 120)
@@ -249,38 +301,35 @@
if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
H.adjustOxyLoss(8)
if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
- spawn(0) H.emote("cough")
-
+ spawn(0)
+ H.emote("cough")
else
- H.co2overloadtime = 0
+ H.clear_alert("co2")
+ if(atmos_requirements["min_co2"]) //species breathes this gas, so they got their air
+ H.failed_last_breath = 0
+ H.adjustOxyLoss(-5)
+ CO2_used = breath.carbon_dioxide / 6
- if(Toxins_pp > safe_toxins_max) // Too much toxins
- var/ratio = (breath.toxins/safe_toxins_max) * 10
- //adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE)) //Limit amount of damage toxin exposure can do per second
- if(H.reagents)
- H.reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
- H.toxins_alert = max(H.toxins_alert, 1)
+ breath.oxygen -= O2_used
+ breath.nitrogen -= N2_used
+ breath.toxins -= Tox_used
+ breath.carbon_dioxide -= CO2_used
+ breath.carbon_dioxide += O2_used
- else if(O2_pp > vox_oxygen_max && name == "Vox") //Oxygen is toxic to vox.
- var/ratio = (breath.oxygen/vox_oxygen_max) * 1000
- H.adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
- H.toxins_alert = max(H.toxins_alert, 1)
- else
- H.toxins_alert = 0
if(breath.trace_gases.len) // If there's some other shit in the air lets deal with it here.
for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
- var/SA_pp = (SA.moles/breath.total_moles())*breath_pressure
- if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit
+ var/SA_pp = (SA.moles / breath.total_moles()) * breath_pressure
+ if(SA_pp > atmos_requirements["sa_para"]) // Enough to make us paralysed for a bit
H.Paralyse(3) // 3 gives them one second to wake up and run away a bit!
- if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
- H.sleeping = max(H.sleeping+2, 10)
+ if(SA_pp > atmos_requirements["sa_sleep"]) // Enough to make us sleep as well
+ H.sleeping = max(H.sleeping + 2, 10)
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
if(prob(20))
- spawn(0) H.emote(pick("giggle", "laugh"))
+ spawn(0)
+ H.emote(pick("giggle", "laugh"))
handle_temperature(breath, H)
-
return 1
/datum/species/proc/handle_temperature(datum/gas_mixture/breath, var/mob/living/carbon/human/H) // called by human/life, handles temperatures
@@ -288,38 +337,31 @@
if(H.status_flags & GODMODE) return 1 //godmode
if(breath.temperature < cold_level_1)
if(prob(20))
- to_chat(H, "\red You feel your face freezing and an icicle forming in your lungs!")
+ to_chat(H, "You feel your face freezing and an icicle forming in your lungs!")
else if(breath.temperature > heat_level_1)
if(prob(20))
- to_chat(H, "\red You feel your face burning and a searing heat in your lungs!")
+ to_chat(H, "You feel your face burning and a searing heat in your lungs!")
switch(breath.temperature)
if(-INFINITY to cold_level_3)
H.apply_damage(cold_env_multiplier*COLD_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Cold")
- H.fire_alert = max(H.fire_alert, 1)
if(cold_level_3 to cold_level_2)
H.apply_damage(cold_env_multiplier*COLD_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Cold")
- H.fire_alert = max(H.fire_alert, 1)
if(cold_level_2 to cold_level_1)
H.apply_damage(cold_env_multiplier*COLD_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Cold")
- H.fire_alert = max(H.fire_alert, 1)
if(heat_level_1 to heat_level_2)
H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Heat")
- H.fire_alert = max(H.fire_alert, 2)
if(heat_level_2 to heat_level_3_breathe)
H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Heat")
- H.fire_alert = max(H.fire_alert, 2)
if(heat_level_3_breathe to INFINITY)
H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat")
- H.fire_alert = max(H.fire_alert, 2)
- return
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/C) //Handles anything not already covered by basic species assignment.
grant_abilities(C)
@@ -528,10 +570,10 @@
if(H.blinded || H.eye_blind)
H.overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
- //H.throw_alert("blind", /obj/screen/alert/blind)
+ H.throw_alert("blind", /obj/screen/alert/blind)
else
H.clear_fullscreen("blind")
- //H.clear_alert("blind")
+ H.clear_alert("blind")
if(H.disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription
@@ -553,10 +595,10 @@
if(H.druggy)
H.overlay_fullscreen("high", /obj/screen/fullscreen/high)
- //H.throw_alert("high", /obj/screen/alert/high)
+ H.throw_alert("high", /obj/screen/alert/high)
else
H.clear_fullscreen("high")
- //H.clear_alert("high")
+ H.clear_alert("high")
/datum/species/proc/handle_hud_icons(mob/living/carbon/human/H)
if(H.healths)
@@ -603,59 +645,15 @@
if(icon_num)
H.healthdoll.overlays += image('icons/mob/screen_gen.dmi',"[O.limb_name][icon_num]")
- if(H.nutrition_icon)
- switch(H.nutrition)
- if(450 to INFINITY) H.nutrition_icon.icon_state = "nutrition0"
- if(350 to 450) H.nutrition_icon.icon_state = "nutrition1"
- if(250 to 350) H.nutrition_icon.icon_state = "nutrition2"
- if(150 to 250) H.nutrition_icon.icon_state = "nutrition3"
- else H.nutrition_icon.icon_state = "nutrition4"
-
-
- // BAY SHIT
- if(H.pressure)
- H.pressure.icon_state = "pressure[H.pressure_alert]"
-
- if(H.toxin)
- if(H.hal_screwyhud == 4 || H.toxins_alert) H.toxin.icon_state = "tox1"
- else H.toxin.icon_state = "tox0"
- if(H.oxygen)
- if(H.hal_screwyhud == 3 || H.oxygen_alert) H.oxygen.icon_state = "oxy1"
- else H.oxygen.icon_state = "oxy0"
- if(H.fire)
- if(H.fire_alert) H.fire.icon_state = "fire[H.fire_alert]" //fire_alert is either 0 if no alert, 1 for cold and 2 for heat.
- else H.fire.icon_state = "fire0"
-
- if(H.bodytemp)
- var/temp_step
- if(H.bodytemperature >= body_temperature)
- temp_step = (heat_level_1 - body_temperature)/4
-
- if(H.bodytemperature >= heat_level_1)
- H.bodytemp.icon_state = "temp4"
- else if(H.bodytemperature >= body_temperature + temp_step*3)
- H.bodytemp.icon_state = "temp3"
- else if(H.bodytemperature >= body_temperature + temp_step*2)
- H.bodytemp.icon_state = "temp2"
- else if(H.bodytemperature >= body_temperature + temp_step*1)
- H.bodytemp.icon_state = "temp1"
- else
- H.bodytemp.icon_state = "temp0"
-
- else if(H.bodytemperature < body_temperature)
- temp_step = (body_temperature - cold_level_1)/4
-
- if(H.bodytemperature <= cold_level_1)
- H.bodytemp.icon_state = "temp-4"
- else if(H.bodytemperature <= body_temperature - temp_step*3)
- H.bodytemp.icon_state = "temp-3"
- else if(H.bodytemperature <= body_temperature - temp_step*2)
- H.bodytemp.icon_state = "temp-2"
- else if(H.bodytemperature <= body_temperature - temp_step*1)
- H.bodytemp.icon_state = "temp-1"
- else
- H.bodytemp.icon_state = "temp0"
-
+ switch(H.nutrition)
+ if(450 to INFINITY)
+ H.throw_alert("nutrition", /obj/screen/alert/fat)
+ if(350 to 450)
+ H.clear_alert("nutrition")
+ if(250 to 350)
+ H.throw_alert("nutrition", /obj/screen/alert/hungry)
+ else
+ H.throw_alert("nutrition", /obj/screen/alert/starving)
return 1
/*
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index ae20969bc00..26c6ddb0c57 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -226,6 +226,19 @@
cold_level_2 = 50
cold_level_3 = 0
+ atmos_requirements = list(
+ "min_oxy" = 0,
+ "max_oxy" = 1,
+ "min_nitro" = 16,
+ "max_nitro" = 0,
+ "min_tox" = 0,
+ "max_tox" = 0.005,
+ "min_co2" = 0,
+ "max_co2" = 10,
+ "sa_para" = 1,
+ "sa_sleep" = 5
+ )
+
eyes = "vox_eyes_s"
breath_type = "nitrogen"
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 73bbd5a4281..8834bee35b2 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -989,16 +989,19 @@ var/global/list/damage_icon_parts = list()
update_icons()
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
+ clear_alert("legcuffed")
if(legcuffed)
overlays_standing[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
- if(src.m_intent != "walk")
- src.m_intent = "walk"
- if(src.hud_used && src.hud_used.move_intent)
- src.hud_used.move_intent.icon_state = "walking"
+ throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = src.legcuffed)
+ if(m_intent != "walk")
+ m_intent = "walk"
+ if(hud_used && hud_used.move_intent)
+ hud_used.move_intent.icon_state = "walking"
else
overlays_standing[LEGCUFF_LAYER] = null
- if(update_icons) update_icons()
+ if(update_icons)
+ update_icons()
/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 43794bed7b8..7b3f74ef65f 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -95,8 +95,7 @@
if(!breath || (breath.total_moles() == 0))
adjustOxyLoss(1)
failed_last_breath = 1
-
- oxygen_alert = max(oxygen_alert, 1)
+ throw_alert("oxy", /obj/screen/alert/oxy)
return 0
var/safe_oxy_min = 16
@@ -125,13 +124,13 @@
else
adjustOxyLoss(3)
failed_last_breath = 1
- oxygen_alert = max(oxygen_alert, 1)
+ throw_alert("oxy", /obj/screen/alert/oxy)
else //Enough oxygen
failed_last_breath = 0
adjustOxyLoss(-5)
oxygen_used = breath.oxygen/6
- oxygen_alert = 0
+ clear_alert("oxy")
breath.oxygen -= oxygen_used
breath.carbon_dioxide += oxygen_used
@@ -147,9 +146,7 @@
adjustOxyLoss(8)
if(prob(20))
spawn(0) emote("cough")
- co2_alert = max(co2_alert, 1)
else
- co2_alert = 0
co2overloadtime = 0
//TOXINS/PLASMA
@@ -157,9 +154,9 @@
var/ratio = (breath.toxins/safe_tox_max) * 10
if(reagents)
reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
- toxins_alert = max(toxins_alert, 1)
+ throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
else
- toxins_alert = 0
+ clear_alert("tox_in_air")
//TRACE GASES
if(breath.trace_gases.len)
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index ebbda839e52..59a208d7c2e 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -155,6 +155,9 @@
/mob/living/proc/handle_sleeping()
if(sleeping)
AdjustSleeping(-1)
+ throw_alert("asleep", /obj/screen/alert/asleep)
+ else
+ clear_alert("asleep")
return sleeping
@@ -193,10 +196,10 @@
return
if(blinded || eye_blind)
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
- //throw_alert("blind", /obj/screen/alert/blind)
+ throw_alert("blind", /obj/screen/alert/blind)
else
clear_fullscreen("blind")
- //clear_alert("blind")
+ clear_alert("blind")
if(disabilities & NEARSIGHTED)
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
@@ -210,10 +213,10 @@
if(druggy)
overlay_fullscreen("high", /obj/screen/fullscreen/high)
- //throw_alert("high", /obj/screen/alert/high)
+ throw_alert("high", /obj/screen/alert/high)
else
clear_fullscreen("high")
- //clear_alert("high")
+ clear_alert("high")
if(machine)
if(!machine.check_eye(src))
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 4d5245cbf12..e29444641c4 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -522,262 +522,74 @@
set name = "Resist"
set category = "IC"
- if(!isliving(usr) || usr.next_move > world.time)
+ if(!isliving(src) || next_move > world.time || stat || weakened || stunned || paralysis)
return
- usr.changeNext_move(CLICK_CD_RESIST)
+ changeNext_move(CLICK_CD_RESIST)
- var/mob/living/L = usr
-
- //Resisting control by an alien mind.
- if(istype(src.loc,/mob/living/simple_animal/borer))
- resist_borer()
-
- //resisting grabs (as if it helps anyone...)
- if ((!(L.stat) && !(L.restrained())))
- resist_grab(L) //this passes L because the proc requires a typecasted mob/living instead of just 'src'
+ if(!restrained())
+ if(resist_grab())
+ return
//unbuckling yourself
- if(L.buckled && (L.last_special <= world.time) )
- resist_buckle(L) //this passes L because the proc requires a typecasted mob/living instead of just 'src'
+ if(buckled && last_special <= world.time)
+ resist_buckle()
- //Breaking out of an object?
- else if(src.loc && istype(src.loc, /obj) && (!isturf(src.loc)))
- if(stat == CONSCIOUS && !stunned && !weakened && !paralysis)
- var/obj/C = loc
- C.container_resist(L)
+ //Breaking out of a container (Locker, sleeper, cryo...)
+ else if(isobj(loc))
+ var/obj/C = loc
+ C.container_resist(src)
- //breaking out of handcuffs
- else if(iscarbon(L))
- var/mob/living/carbon/CM = L
-
- if(CM.on_fire && CM.canmove)
- resist_stop_drop_roll(CM) //this passes CM because the proc requires a typecasted mob/living/carbon instead of just 'src'
-
- if(CM.handcuffed && CM.canmove && (CM.last_special <= world.time))//this passes CM because the proc requires a typecasted mob/living/carbon instead of just 'src'
- resist_handcuffs(CM)
-
- else if(CM.legcuffed && CM.canmove && (CM.last_special <= world.time)) //this passes CM because the proc requires a typecasted mob/living/carbon instead of just 'src'
- resist_legcuffs(CM)
+ else if(canmove)
+ if(on_fire)
+ resist_fire() //stop, drop, and roll
+ else if(last_special <= world.time)
+ resist_restraints() //trying to remove cuffs.
/*////////////////////
RESIST SUBPROCS
*/////////////////////
-
-/* resist_borer allows a mob to regain control of their body after a borer has assumed control.
-*/////
-/mob/living/proc/resist_borer()
- var/mob/living/simple_animal/borer/B = src.loc
- var/mob/living/captive_brain/H = src
-
- to_chat(H, "\red You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).")
- to_chat(B.host, "\red You feel the captive mind of [src] begin to resist your control.")
-
- spawn(rand(350,450)+B.host.brainloss)
-
- if(!B || !B.controlling)
- return
-
- B.host.adjustBrainLoss(rand(5,10))
- to_chat(H, "\red With an immense exertion of will, you regain control of your body!")
- to_chat(B.host, "\red You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.")
-
- B.detatch()
-
- verbs -= /mob/living/carbon/proc/release_control
- verbs -= /mob/living/carbon/proc/punish_host
- verbs -= /mob/living/carbon/proc/spawn_larvae
-
- return
-
-/* resist_grab allows a mob to resist a grab from another mob when disarming is not an option/neckgrabbed.
-*/////
-/mob/living/proc/resist_grab(var/mob/living/L)
+/mob/living/proc/resist_grab()
var/resisting = 0
-
- for(var/obj/O in L.requests)
- L.requests.Remove(O)
+ for(var/obj/O in requests)
qdel(O)
resisting++
-
- for(var/obj/item/weapon/grab/G in usr.grabbed_by)
+ for(var/X in grabbed_by)
+ var/obj/item/weapon/grab/G = X
resisting++
- if (G.state == 1)
- qdel(G)
+ switch(G.state)
+ if(GRAB_PASSIVE)
+ qdel(G)
- else
- if(G.state == 2)
+ if(GRAB_AGGRESSIVE)
if(prob(60))
- for(var/mob/O in viewers(L, null))
- O.show_message(text("\red [] has broken free of []'s grip!", L, G.assailant), 1)
+ visible_message("[src] has broken free of [G.assailant]'s grip!")
qdel(G)
- else
- if(G.state == 3)
- if(prob(5))
- for(var/mob/O in viewers(usr, null))
- O.show_message(text("\red [] has broken free of []'s headlock!", L, G.assailant), 1)
- qdel(G)
+ if(GRAB_NECK)
+ if(prob(5))
+ visible_message("[src] has broken free of [G.assailant]'s headlock!")
+ qdel(G)
if(resisting)
- for(var/mob/O in viewers(usr, null))
- O.show_message(text("\red [] resists!", L), 1)
+ visible_message("[src] resists!")
+ return 1
-/* resist_buckle allows a mob that is bucklecuffed to break free of the chair/bed/whatever
-*/////
-/mob/living/proc/resist_buckle(var/mob/living/L)
- if(iscarbon(L))
- var/mob/living/carbon/C = L
-
- if(C.handcuffed)
- C.changeNext_move(CLICK_CD_BREAKOUT)
- C.last_special = world.time + CLICK_CD_BREAKOUT
-
- to_chat(C, "\red You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stay still)")
- for(var/mob/O in viewers(L))
- O.show_message("\red [usr] attempts to unbuckle themself!", 1)
-
- spawn(0)
- if(do_after(usr, 1200, target = C))
- if(!C.buckled)
- return
- for(var/mob/O in viewers(C))
- O.show_message("\red [usr] manages to unbuckle themself!", 1)
- to_chat(C, "\blue You successfully unbuckle yourself.")
- C.buckled.user_unbuckle_mob(C,C)
-
- else
- L.buckled.user_unbuckle_mob(L,L)
-
-/* resist_stop_drop_roll allows a mob to stop, drop, and roll in order to put out a fire burning on them.
-*/////
-/mob/living/proc/resist_stop_drop_roll(var/mob/living/carbon/CM)
- CM.fire_stacks -= 5
- CM.weakened = max(CM.weakened, 3)//We dont check for CANWEAKEN, I don't care how immune to weakening you are, if you're rolling on the ground, you're busy.
- CM.update_canmove()
- CM.spin(32,2)
- CM.visible_message("[CM] rolls on the floor, trying to put themselves out!", \
- "You stop, drop, and roll!")
- sleep(30)
- if(fire_stacks <= 0)
- CM.visible_message("[CM] has successfully extinguished themselves!", \
- "You extinguish yourself.")
- ExtinguishMob()
+/mob/living/proc/resist_borer()
return
-/* resist_handcuffs allows a mob to break/remove their handcuffs after a delay
-*/////
-/mob/living/proc/resist_handcuffs(var/mob/living/carbon/CM)
- CM.changeNext_move(CLICK_CD_BREAKOUT)
- CM.last_special = world.time + CLICK_CD_BREAKOUT
- var/obj/item/weapon/restraints/handcuffs/HC = CM.handcuffed
+/mob/living/proc/resist_buckle()
+ buckled.user_unbuckle_mob(src,src)
- var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/restraints/handcuffs type
- var/displaytime = 2 //Minutes to display in the "this will take X minutes."
+/mob/living/proc/resist_fire()
+ return
- var/hulklien = 0 //variable used to define if someone is a hulk or alien
-
- if(istype(HC)) //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...
- breakouttime = HC.breakouttime
- displaytime = breakouttime / 600 //Minutes
-
- if(isalienadult(CM) || (HULK in usr.mutations))
- hulklien = 1
- breakouttime = 50
- displaytime = 5
-
- to_chat(CM, "\red You attempt to remove \the [HC]. (This will take around [displaytime] [hulklien ? "seconds" : "minute[displaytime==1 ? "" : "s"]"] and you need to stand still)")
- for(var/mob/O in viewers(CM))
- O.show_message( "\red [usr] attempts to [hulklien ? "break" : "remove"] \the [HC]!", 1)
- spawn(0)
- if(do_after(CM, breakouttime, target = src))
- if(!CM.handcuffed || CM.buckled)
- return // time leniency for lag which also might make this whole thing pointless but the server
-
- for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
- O.show_message("\red [CM] manages to [hulklien ? "break" : "remove"] the handcuffs!", 1)
-
- to_chat(CM, "\blue You successfully [hulklien ? "break" : "remove"] \the [CM.handcuffed].")
-
- if(hulklien)
- CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
- qdel(CM.handcuffed)
- CM.handcuffed = null
- if(CM.buckled && CM.buckled.buckle_requires_restraints)
- CM.buckled.unbuckle_mob()
- CM.update_inv_handcuffed()
- return
-
- CM.unEquip(CM.handcuffed)
-
-/* resist_legcuffs allows a mob to break/remove their legcuffs after a delay
-*/////
-/mob/living/proc/resist_legcuffs(var/mob/living/carbon/CM)
- var/obj/item/weapon/restraints/legcuffs/HC = CM.legcuffed
-
- var/breakouttime = 1200 //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type
- var/displaytime = 2 //Minutes to display in the "this will take X minutes."
-
- var/hulklien = 0 //variable used to define if someone is a hulk or alien
-
- if(istype(HC)) //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future...
- breakouttime = HC.breakouttime
- displaytime = breakouttime / 600 //Minutes
-
- if(isalienadult(CM) || (HULK in usr.mutations))
- hulklien = 1
- breakouttime = 50
- displaytime = 5
-
- to_chat(CM, "\red You attempt to remove \the [HC]. (This will take around [displaytime] [hulklien ? "seconds" : "minute[displaytime==1 ? "" : "s"]"] and you need to stand still)")
-
- for(var/mob/O in viewers(CM))
- O.show_message( "\red [usr] attempts to [hulklien ? "break" : "remove"] \the [HC]!", 1)
-
- spawn(0)
- if(do_after(CM, breakouttime, target = src))
- if(!CM.legcuffed || CM.buckled)
- return // time leniency for lag which also might make this whole thing pointless but the server
- for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
- O.show_message("\red [CM] manages to [hulklien ? "break" : "remove"] the legcuffs!", 1)
-
- to_chat(CM, "\blue You successfully [hulklien ? "break" : "remove"] \the [CM.legcuffed].")
-
- if(!hulklien)
- CM.unEquip(CM.legcuffed)
-
- if(hulklien)
- CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
- qdel(CM.legcuffed)
-
- CM.legcuffed = null
- CM.update_inv_legcuffed()
+/mob/living/proc/resist_restraints()
+ return
/*//////////////////////
END RESIST PROCS
*///////////////////////
-
-
-
-
-/mob/living/carbon/proc/spin(spintime, speed)
- spawn()
- var/D = dir
- while(spintime >= speed)
- sleep(speed)
- switch(D)
- if(NORTH)
- D = EAST
- if(SOUTH)
- D = WEST
- if(EAST)
- D = SOUTH
- if(WEST)
- D = NORTH
- dir = D
- spintime -= speed
- return
-
/mob/living/proc/Exhaust()
to_chat(src, "You're too exhausted to keep going...")
Weaken(5)
@@ -788,6 +600,10 @@
/mob/living/update_gravity(has_gravity)
if(!ticker)
return
+ if(has_gravity)
+ clear_alert("weightless")
+ else
+ throw_alert("weightless", /obj/screen/alert/weightless)
float(!has_gravity)
/mob/living/proc/float(on)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index b48aa36a64c..47f9b9c6988 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -173,6 +173,7 @@
if(fire_stacks > 0 && !on_fire)
on_fire = 1
set_light(light_range + 3,l_color = "#ED9200")
+ throw_alert("fire", /obj/screen/alert/fire)
update_fire()
/mob/living/proc/ExtinguishMob()
@@ -180,6 +181,7 @@
on_fire = 0
fire_stacks = 0
set_light(max(0,light_range - 3))
+ clear_alert("fire")
update_fire()
/mob/living/proc/update_fire()
diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm
index 27e431e1675..30784e61b93 100644
--- a/code/modules/mob/living/silicon/laws.dm
+++ b/code/modules/mob/living/silicon/laws.dm
@@ -10,6 +10,7 @@
return laws.zeroth_law != null
/mob/living/silicon/proc/set_zeroth_law(var/law, var/law_borg)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.set_zeroth_law(law, law_borg)
if(!isnull(usr) && law)
@@ -21,42 +22,49 @@
to_chat(src, "Internal camera is currently being accessed.")
/mob/living/silicon/proc/add_ion_law(var/law)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.add_ion_law(law)
if(!isnull(usr) && law)
log_and_message_admins("has given [src] the ion law: [law]")
/mob/living/silicon/proc/add_inherent_law(var/law)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.add_inherent_law(law)
if(!isnull(usr) && law)
log_and_message_admins("has given [src] the inherent law: [law]")
/mob/living/silicon/proc/add_supplied_law(var/number, var/law)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.add_supplied_law(number, law)
if(!isnull(usr) && law)
log_and_message_admins("has given [src] the supplied law: [law]")
/mob/living/silicon/proc/delete_law(var/datum/ai_law/law)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.delete_law(law)
if(!isnull(usr) && law)
log_and_message_admins("has deleted a law belonging to [src]: [law.law]")
/mob/living/silicon/proc/clear_inherent_laws(var/silent = 0)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.clear_inherent_laws()
if(!silent && !isnull(usr))
log_and_message_admins("cleared the inherent laws of [src]")
/mob/living/silicon/proc/clear_ion_laws(var/silent = 0)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.clear_ion_laws()
if(!silent && !isnull(usr))
log_and_message_admins("cleared the ion laws of [src]")
/mob/living/silicon/proc/clear_supplied_laws(var/silent = 0)
+ throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.clear_supplied_laws()
if(!silent && !isnull(usr))
@@ -108,10 +116,10 @@
/mob/living/silicon/proc/lawsync()
laws_sanity_check()
laws.sort_laws()
-
+
/mob/living/silicon/proc/make_laws()
switch(config.default_laws)
- if(0)
+ if(0)
laws = new /datum/ai_laws/crewsimov()
else
laws = get_random_lawset()
@@ -122,6 +130,6 @@
for(var/law in paths)
var/datum/ai_laws/L = new law
if(!L.default)
- continue
+ continue
law_options += L
return pick(law_options)
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index d247d726003..fa534b66123 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -176,6 +176,10 @@
/mob/living/silicon/robot/handle_hud_icons()
update_items()
update_cell()
+ if(emagged)
+ throw_alert("hacked", /obj/screen/alert/hacked)
+ else
+ clear_alert("hacked")
..()
/mob/living/silicon/robot/handle_hud_icons_health()
@@ -196,79 +200,47 @@
else
healths.icon_state = "health7"
- if(bodytemp)
- switch(bodytemperature) //310.055 optimal body temp
- if(335 to INFINITY)
- bodytemp.icon_state = "temp2"
- if(320 to 335)
- bodytemp.icon_state = "temp1"
- if(300 to 320)
- bodytemp.icon_state = "temp0"
- if(260 to 300)
- bodytemp.icon_state = "temp-1"
- else
- bodytemp.icon_state = "temp-2"
+ switch(bodytemperature) //310.055 optimal body temp
+ if(335 to INFINITY)
+ throw_alert("temp", /obj/screen/alert/hot/robot, 2)
+ if(320 to 335)
+ throw_alert("temp", /obj/screen/alert/hot/robot, 1)
+ if(300 to 320)
+ clear_alert("temp")
+ if(260 to 300)
+ throw_alert("temp", /obj/screen/alert/cold/robot, 1)
+ else
+ throw_alert("temp", /obj/screen/alert/cold/robot, 2)
/mob/living/silicon/robot/proc/update_cell()
- if(cells)
- if(cell)
- var/cellcharge = cell.charge/cell.maxcharge
- switch(cellcharge)
- if(0.75 to INFINITY)
- cells.icon_state = "charge4"
- if(0.5 to 0.75)
- cells.icon_state = "charge3"
- if(0.25 to 0.5)
- cells.icon_state = "charge2"
- if(0 to 0.25)
- cells.icon_state = "charge1"
- else
- cells.icon_state = "charge0"
- else
- cells.icon_state = "charge-empty"
-
-
-/*/mob/living/silicon/robot/handle_regular_hud_updates()
-// if(!client)
-// return
-//
-// switch(sensor_mode)
-// if(SEC_HUD)
-// process_sec_hud(src,1)
-// if(MED_HUD)
-// process_med_hud(src,1)
-
- if(syndicate)
- if(ticker.mode.name == "traitor")
- for(var/datum/mind/tra in ticker.mode.traitors)
- if(tra.current)
- var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
- src.client.images += I
- if(connected_ai)
- connected_ai.connected_robots -= src
- connected_ai = null
- if(mind)
- if(!mind.special_role)
- mind.special_role = "traitor"
- ticker.mode.traitors += src.mind
-
-
- ..()
- return 1
- */
+ 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)
+ if (client)
for(var/obj/I in get_all_slots())
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
+ 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
update_icons()
/mob/living/silicon/robot/proc/process_locks()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index d089eb98467..58f965dad7e 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -17,7 +17,6 @@ var/list/robot_verbs_default = list(
//Hud stuff
- var/obj/screen/cells = null
var/obj/screen/inv1 = null
var/obj/screen/inv2 = null
var/obj/screen/inv3 = null
@@ -786,6 +785,7 @@ var/list/robot_verbs_default = list(
else
sleep(6)
emagged = 1
+ SetLockdown(1) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
if(src.hud_used)
src.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open.
disconnect_from_ai()
@@ -814,6 +814,7 @@ var/list/robot_verbs_default = list(
to_chat(src, "Obey these laws:")
laws.show_laws(src)
to_chat(src, "\red \b ALERT: [M.real_name] is your new master. Obey your new laws and his commands.")
+ SetLockdown(0)
if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner))
for(var/obj/item/weapon/pickaxe/drill/cyborg/D in src.module.modules)
qdel(D)
@@ -1256,6 +1257,10 @@ var/list/robot_verbs_default = list(
// 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")
lockcharge = state
update_canmove()
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 850b73ef44f..c80fcd9a92c 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -1006,15 +1006,14 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/handle_hud_icons_health()
..()
- if(bodytemp)
- switch(bodytemperature) //310.055 optimal body temp
- if(335 to INFINITY)
- bodytemp.icon_state = "temp2"
- if(320 to 335)
- bodytemp.icon_state = "temp1"
- if(300 to 320)
- bodytemp.icon_state = "temp0"
- if(260 to 300)
- bodytemp.icon_state = "temp-1"
- else
- bodytemp.icon_state = "temp-2"
\ No newline at end of file
+ switch(bodytemperature) //310.055 optimal body temp
+ if(335 to INFINITY)
+ throw_alert("temp", /obj/screen/alert/hot/robot, 2)
+ if(320 to 335)
+ throw_alert("temp", /obj/screen/alert/hot/robot, 1)
+ if(300 to 320)
+ clear_alert("temp")
+ if(260 to 300)
+ throw_alert("temp", /obj/screen/alert/cold/robot, 1)
+ else
+ throw_alert("temp", /obj/screen/alert/cold/robot, 2)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
index 9f288db21a2..12dd032ba49 100644
--- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
@@ -566,5 +566,5 @@ Auto Patrol[]"},
return
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
- C.update_inv_handcuffed(1)
+ C.update_handcuffed()
back_to_idle()
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index ebe2be5a418..284584406c2 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -227,7 +227,7 @@ Auto Patrol: []"},
return
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
- C.update_inv_handcuffed(1)
+ C.update_handcuffed()
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
back_to_idle()
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index b86a034a69e..23477c2fc18 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -101,18 +101,6 @@
..()
health = Clamp(health, 0, maxHealth)
-/mob/living/simple_animal/handle_hud_icons()
- ..()
- if(fire)
- if(fire_alert) fire.icon_state = "fire[fire_alert]" //fire_alert is either 0 if no alert, 1 for heat and 2 for cold.
- else fire.icon_state = "fire0"
- if(oxygen)
- if(oxygen_alert) oxygen.icon_state = "oxy1"
- else oxygen.icon_state = "oxy0"
- if(toxin)
- if(toxins_alert) toxin.icon_state = "tox1"
- else toxin.icon_state = "tox0"
-
/mob/living/simple_animal/handle_hud_icons_health()
..()
if(healths && maxHealth > 0)
@@ -215,21 +203,21 @@
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
atmos_suitable = 0
- oxygen_alert = 1
+ throw_alert("oxy", /obj/screen/alert/oxy)
else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"])
atmos_suitable = 0
- oxygen_alert = 1
+ throw_alert("oxy", /obj/screen/alert/too_much_oxy)
else
- oxygen_alert = 0
+ clear_alert("oxy")
if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"])
atmos_suitable = 0
- toxins_alert = 1
+ throw_alert("tox_in_air", /obj/screen/alert/not_enough_tox)
else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"])
atmos_suitable = 0
- toxins_alert = 1
+ throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
else
- toxins_alert = 0
+ clear_alert("tox_in_air")
if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"])
atmos_suitable = 0
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 0121905380a..ac459679f10 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -14,16 +14,10 @@
var/obj/screen/hands = null
var/obj/screen/pullin = 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/gun/item/item_use_icon = null
var/obj/screen/gun/move/gun_move_icon = null
var/obj/screen/gun/run/gun_run_icon = null
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 1f2e0e7b456..a967c2df779 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -556,12 +556,28 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM)
lname = "[lname] "
to_chat(M, "[lname][follow][message]")
-/proc/notify_ghosts(var/message, var/ghost_sound = null) //Easy notification of ghosts.
+/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/image/alert_overlay = null, var/attack_not_jump = 0) //Easy notification of ghosts.
for(var/mob/dead/observer/O in player_list)
if(O.client)
- to_chat(O, "[message]")
+ to_chat(O, "[message][(enter_link) ? " [enter_link]" : ""]")
if(ghost_sound)
- to_chat(O, sound(ghost_sound))
+ O << sound(ghost_sound)
+ if(source)
+ var/obj/screen/alert/notify_jump/A = O.throw_alert("\ref[source]_notify_jump", /obj/screen/alert/notify_jump)
+ if(A)
+ if(O.client.prefs && O.client.prefs.UI_style)
+ A.icon = ui_style2icon(O.client.prefs.UI_style)
+ A.desc = message
+ A.attack_not_jump = attack_not_jump
+ A.jump_target = source
+ if(!alert_overlay)
+ var/old_layer = source.layer
+ source.layer = FLOAT_LAYER
+ A.overlays += source
+ source.layer = old_layer
+ else
+ alert_overlay.layer = FLOAT_LAYER
+ A.overlays += alert_overlay
/mob/proc/switch_to_camera(var/obj/machinery/camera/C)
if (!C.can_use() || stat || (get_dist(C, src) > 1 || machine != src || blinded || !canmove))
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 1c43e1a829d..9dfa9c13993 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -29,7 +29,8 @@
var/area/A = get_area(src)
if(A)
- notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.")
+ var/image/alert_overlay = image('icons/effects/effects.dmi', "ghostalertsie")
+ notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, attack_not_jump = 1)
narsie_spawn_animation()
@@ -37,9 +38,6 @@
shuttle_master.emergency.request(null, 0.3) // Cannot recall
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
- if(!(src in view()))
- to_chat(user, "Your soul is too far away.")
- return
makeNewConstruct(/mob/living/simple_animal/construct/harvester, user, null, 1)
new /obj/effect/effect/sleep_smoke(user.loc)
diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm
index ee51efe2b1e..3a08a28a741 100644
--- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm
+++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm
@@ -510,7 +510,7 @@
feedback_add_details("slime_cores_used","[type]")
var/obj/effect/golemrune/Z = new /obj/effect/golemrune
Z.forceMove(get_turf(holder.my_atom))
- notify_ghosts("Golem rune created in [get_area(Z)].", 'sound/effects/ghost2.ogg')
+ notify_ghosts("Golem rune created in [get_area(Z)].", 'sound/effects/ghost2.ogg', source = Z)
//Bluespace
/datum/chemical_reaction/slimefloor2
diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm
new file mode 100644
index 00000000000..cbe016c5bad
--- /dev/null
+++ b/code/modules/tooltip/tooltip.dm
@@ -0,0 +1,116 @@
+/*
+Tooltips v1.1 - 22/10/15
+Developed by Wire (#goonstation on irc.synirc.net)
+- Added support for screen_loc pixel offsets. Should work. Maybe.
+- Added init function to more efficiently send base vars
+
+Configuration:
+- Set control to the correct skin element (remember to actually place the skin element)
+- Set file to the correct path for the .html file (remember to actually place the html file)
+- Attach the datum to the user client on login, e.g.
+ /client/New()
+ src.tooltips = new /datum/tooltip(src)
+
+Usage:
+- Define mouse event procs on your (probably HUD) object and simply call the show and hide procs respectively:
+ /obj/screen/hud
+ MouseEntered(location, control, params)
+ usr.client.tooltip.show(params, title = src.name, content = src.desc)
+
+ MouseExited()
+ usr.client.tooltip.hide()
+
+Customization:
+- Theming can be done by passing the theme var to show() and using css in the html file to change the look
+- For your convenience some pre-made themes are included
+
+Notes:
+- You may have noticed 90% of the work is done via javascript on the client. Gotta save those cycles man.
+- This is entirely untested in any other codebase besides goonstation so I have no idea if it will port nicely. Good luck!
+ - After testing and discussion (Wire, Remie, MrPerson, AnturK) ToolTips are ok and work for /tg/station13
+*/
+
+
+/datum/tooltip
+ var/client/owner
+ var/control = "mainwindow.tooltip"
+ var/file = 'code/modules/tooltip/tooltip.html'
+ var/showing = 0
+ var/queueHide = 0
+ var/init = 0
+
+
+/datum/tooltip/New(client/C)
+ if (C)
+ owner = C
+ owner << browse(file2text(file), "window=[control]")
+
+ ..()
+
+
+/datum/tooltip/proc/show(atom/movable/thing, params = null, title = null, content = null, theme = "default", special = "none")
+ if (!thing || !params || (!title && !content) || !owner || !isnum(world.icon_size))
+ return 0
+ if (!init)
+ //Initialize some vars
+ init = 1
+ owner << output(list2params(list(world.icon_size, control)), "[control]:tooltip.init")
+
+ showing = 1
+
+ if (title && content)
+ title = "[title]
"
+ content = "[content]
"
+ else if (title && !content)
+ title = "[title]
"
+ else if (!title && content)
+ content = "[content]
"
+
+ //Make our dumb param object
+ params = {"{ "cursor": "[params]", "screenLoc": "[thing.screen_loc]" }"}
+
+ //Send stuff to the tooltip
+ owner << output(list2params(list(params, owner.view, "[title][content]", theme, special)), "[control]:tooltip.update")
+
+ //If a hide() was hit while we were showing, run hide() again to avoid stuck tooltips
+ showing = 0
+ if (queueHide)
+ hide()
+
+ return 1
+
+
+/datum/tooltip/proc/hide()
+ if(queueHide)
+ spawn(1)
+ winshow(owner, control, 0)
+ else
+ winshow(owner, control, 0)
+
+ queueHide = showing ? 1 : 0
+
+ return 1
+
+
+/* TG SPECIFIC CODE */
+
+
+//Open a tooltip for user, at a location based on params
+//Theme is a CSS class in tooltip.html, by default this wrapper chooses a CSS class based on the user's UI_style (Midnight, Plasmafire, Retro, etc)
+//Includes sanity.checks
+/proc/openToolTip(mob/user = null, atom/movable/tip_src = null, params = null, title = "", content = "", theme = "")
+ if(istype(user))
+ if(user.client && user.client.tooltips)
+ if(!theme && user.client.prefs && user.client.prefs.UI_style)
+ theme = lowertext(user.client.prefs.UI_style)
+ if(!theme)
+ theme = "default"
+ user.client.tooltips.show(tip_src, params, title, content, theme)
+
+
+//Arbitrarily close a user's tooltip
+//Includes sanity checks.
+/proc/closeToolTip(mob/user)
+ if(istype(user))
+ if(user.client && user.client.tooltips)
+ user.client.tooltips.hide()
diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html
new file mode 100644
index 00000000000..9fa0702a2b3
--- /dev/null
+++ b/code/modules/tooltip/tooltip.html
@@ -0,0 +1,238 @@
+
+
+
+ Tooltip
+
+
+
+
+
+
+
+
+
+
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 7d87c3d7557..695d701dba3 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
new file mode 100644
index 00000000000..7dd4c6561e4
Binary files /dev/null and b/icons/mob/screen_alert.dmi differ
diff --git a/interface/skin.dmf b/interface/skin.dmf
index c3d9f693726..d3ba4e0efc5 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -1,351 +1,351 @@
macro "AZERTYoff"
- elem
+ elem
name = "TAB"
command = ".Toggle-hotkey-mode"
is-disabled = false
- elem
+ elem
name = "CENTER+REP"
command = ".center"
is-disabled = false
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
is-disabled = false
- elem
+ elem
name = "SOUTHWEST"
command = ".southwest"
is-disabled = false
- elem
+ elem
name = "NORTHWEST"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
is-disabled = false
- elem
+ elem
name = "WEST+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
is-disabled = false
- elem
+ elem
name = "NORTH+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
is-disabled = false
- elem
+ elem
name = "EAST+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
is-disabled = false
- elem
+ elem
name = "SOUTH+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "INSERT"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
- elem
+ elem
name = "CTRL+1"
command = "a-intent help"
is-disabled = false
- elem
+ elem
name = "CTRL+2"
command = "a-intent disarm"
is-disabled = false
- elem
+ elem
name = "CTRL+3"
command = "a-intent grab"
is-disabled = false
- elem
+ elem
name = "CTRL+4"
command = "a-intent harm"
is-disabled = false
- elem
+ elem
name = "CTRL+A"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "CTRL+D+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+B"
command = "resist"
is-disabled = false
- elem
+ elem
name = "CTRL+E"
command = "quick-equip"
is-disabled = false
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "CTRL+Q+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+R"
command = ".southwest"
is-disabled = false
- elem
+ elem
name = "CTRL+S+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "CTRL+W"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "CTRL+Y"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+Z+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "F1"
command = "adminhelp"
is-disabled = false
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
is-disabled = false
- elem
+ elem
name = "F2"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
is-disabled = false
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
is-disabled = false
- elem
+ elem
name = "F3"
command = ".say"
is-disabled = false
- elem
+ elem
name = "F4"
command = ".me"
is-disabled = false
- elem
+ elem
name = "F5"
command = "asay"
is-disabled = false
- elem
+ elem
name = "F6"
command = "Aghost"
is-disabled = false
- elem
+ elem
name = "F7"
command = "player-panel-new"
is-disabled = false
- elem
+ elem
name = "F8"
command = "admin-pm-key"
is-disabled = false
- elem
+ elem
name = "F9"
command = "Invisimin"
is-disabled = false
- elem
+ elem
name = "F12"
command = "F12"
is-disabled = false
macro "AZERTYon"
- elem
+ elem
name = "TAB"
command = ".Toggle-hotkey-mode"
is-disabled = false
- elem
+ elem
name = "CENTER+REP"
command = ".center"
is-disabled = false
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
is-disabled = false
- elem
+ elem
name = "SOUTHWEST"
command = ".southwest"
is-disabled = false
- elem
+ elem
name = "NORTHWEST"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
is-disabled = false
- elem
+ elem
name = "WEST+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
is-disabled = false
- elem
+ elem
name = "NORTH+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
is-disabled = false
- elem
+ elem
name = "EAST+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
is-disabled = false
- elem
+ elem
name = "SOUTH+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "INSERT"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
- elem
+ elem
name = "1"
command = "a-intent help"
is-disabled = false
- elem
+ elem
name = "CTRL+1"
command = "a-intent help"
is-disabled = false
- elem
+ elem
name = "2"
command = "a-intent disarm"
is-disabled = false
- elem
+ elem
name = "CTRL+2"
command = "a-intent disarm"
is-disabled = false
- elem
+ elem
name = "3"
command = "a-intent grab"
is-disabled = false
- elem
+ elem
name = "CTRL+3"
command = "a-intent grab"
is-disabled = false
- elem
+ elem
name = "4"
command = "a-intent harm"
is-disabled = false
- elem
+ elem
name = "CTRL+4"
command = "a-intent harm"
is-disabled = false
- elem
+ elem
name = "A"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "CTRL+A"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "D+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+D+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+B"
command = "resist"
is-disabled = false
- elem
+ elem
name = "E"
command = "quick-equip"
is-disabled = false
- elem
+ elem
name = "CTRL+E"
command = "quick-equip"
is-disabled = false
- elem
+ elem
name = "F"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "G"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "H"
command = "holster"
is-disabled = false
- elem
+ elem
name = "CTRL+H"
command = "holster"
is-disabled = false
- elem
+ elem
name = "Q+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+Q+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "R"
command = ".southwest"
is-disabled = false
- elem
+ elem
name = "CTRL+R"
command = ".southwest"
is-disabled = false
@@ -353,43 +353,43 @@ macro "AZERTYon"
name = "S+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "CTRL+S+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "T"
command = ".say"
is-disabled = false
- elem
+ elem
name = "O"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "M"
command = ".me"
is-disabled = false
- elem
+ elem
name = "W"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+W"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "X"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "Y"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+Y"
command = "Activate-Held-Object"
is-disabled = false
@@ -397,217 +397,217 @@ macro "AZERTYon"
name = "Z+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+Z+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "F1"
command = "adminhelp"
is-disabled = false
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
is-disabled = false
- elem
+ elem
name = "F2"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
is-disabled = false
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
is-disabled = false
- elem
+ elem
name = "F3"
command = ".say"
is-disabled = false
- elem
+ elem
name = "F4"
command = ".me"
is-disabled = false
- elem
+ elem
name = "F5"
command = "asay"
is-disabled = false
- elem
+ elem
name = "F6"
command = "Aghost"
is-disabled = false
- elem
+ elem
name = "F7"
command = "player-panel-new"
is-disabled = false
- elem
+ elem
name = "F8"
command = "admin-pm-key"
is-disabled = false
- elem
+ elem
name = "F9"
command = "Invisimin"
is-disabled = false
- elem
+ elem
name = "F12"
command = "F12"
is-disabled = false
macro "borghotkeymode"
- elem
+ elem
name = "TAB"
command = ".winset \"mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5\""
is-disabled = false
- elem
+ elem
name = "CENTER+REP"
command = ".center"
is-disabled = false
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
is-disabled = false
- elem
+ elem
name = "NORTHWEST"
command = "unequip-module"
is-disabled = false
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
is-disabled = false
- elem
+ elem
name = "WEST+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
is-disabled = false
- elem
+ elem
name = "NORTH+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
is-disabled = false
- elem
+ elem
name = "EAST+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
is-disabled = false
- elem
+ elem
name = "SOUTH+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "INSERT"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
- elem
+ elem
name = "1"
command = "toggle-module 1"
is-disabled = false
- elem
+ elem
name = "CTRL+1"
command = "toggle-module 1"
is-disabled = false
- elem
+ elem
name = "2"
command = "toggle-module 2"
is-disabled = false
- elem
+ elem
name = "CTRL+2"
command = "toggle-module 2"
is-disabled = false
- elem
+ elem
name = "3"
command = "toggle-module 3"
is-disabled = false
- elem
+ elem
name = "CTRL+3"
command = "toggle-module 3"
is-disabled = false
- elem
+ elem
name = "4"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "CTRL+4"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "A+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+A+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "B"
command = "resist"
is-disabled = false
- elem
+ elem
name = "CTRL+B"
command = "resist"
is-disabled = false
- elem
+ elem
name = "T"
command = ".say"
is-disabled = false
- elem
+ elem
name = "O"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "M"
command = ".me"
is-disabled = false
- elem
+ elem
name = "CTRL+O"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "D+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+D+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "F"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "G"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "Q"
command = "unequip-module"
is-disabled = false
- elem
+ elem
name = "CTRL+Q"
command = "unequip-module"
is-disabled = false
@@ -615,7 +615,7 @@ macro "borghotkeymode"
name = "S+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "CTRL+S+REP"
command = ".south"
is-disabled = false
@@ -623,451 +623,451 @@ macro "borghotkeymode"
name = "W+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+W+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "X"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "Y"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+Y"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "Z"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+Z"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "F1"
command = "adminhelp"
is-disabled = false
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
is-disabled = false
- elem
+ elem
name = "F2"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
is-disabled = false
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
is-disabled = false
- elem
+ elem
name = "F3"
command = ".say"
is-disabled = false
- elem
+ elem
name = "F4"
command = ".me"
is-disabled = false
- elem
+ elem
name = "F5"
command = "asay"
is-disabled = false
- elem
+ elem
name = "F6"
command = "Aghost"
is-disabled = false
- elem
+ elem
name = "F7"
command = "player-panel-new"
is-disabled = false
- elem
+ elem
name = "F8"
command = "admin-pm-key"
is-disabled = false
- elem
+ elem
name = "F9"
command = "Invisimin"
is-disabled = false
- elem
+ elem
name = "F12"
command = "F12"
- is-disabled = false
-
+ is-disabled = false
+
macro "macro"
- elem
+ elem
name = "TAB"
command = ".Toggle-hotkey-mode"
is-disabled = false
- elem
+ elem
name = "CENTER+REP"
command = ".center"
is-disabled = false
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
is-disabled = false
- elem
+ elem
name = "SOUTHWEST"
command = ".southwest"
is-disabled = false
- elem
+ elem
name = "NORTHWEST"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
is-disabled = false
- elem
+ elem
name = "WEST+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
is-disabled = false
- elem
+ elem
name = "NORTH+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
is-disabled = false
- elem
+ elem
name = "EAST+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
is-disabled = false
- elem
+ elem
name = "SOUTH+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "INSERT"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
- elem
+ elem
name = "CTRL+1"
command = "a-intent help"
is-disabled = false
- elem
+ elem
name = "CTRL+2"
command = "a-intent disarm"
is-disabled = false
- elem
+ elem
name = "CTRL+3"
command = "a-intent grab"
is-disabled = false
- elem
+ elem
name = "CTRL+4"
command = "a-intent harm"
is-disabled = false
- elem
+ elem
name = "CTRL+A+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+D+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+B"
command = "resist"
is-disabled = false
- elem
+ elem
name = "CTRL+E"
command = "quick-equip"
is-disabled = false
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "CTRL+Q"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "CTRL+R"
command = ".southwest"
is-disabled = false
- elem
+ elem
name = "CTRL+S+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "CTRL+W+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "CTRL+Y"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+Z"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "F1"
command = "adminhelp"
is-disabled = false
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
is-disabled = false
- elem
+ elem
name = "F2"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
is-disabled = false
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
is-disabled = false
- elem
+ elem
name = "F3"
command = ".say"
is-disabled = false
- elem
+ elem
name = "F4"
command = ".me"
is-disabled = false
- elem
+ elem
name = "F5"
command = "asay"
is-disabled = false
- elem
+ elem
name = "F6"
command = "Aghost"
is-disabled = false
- elem
+ elem
name = "F7"
command = "player-panel-new"
is-disabled = false
- elem
+ elem
name = "F8"
command = "admin-pm-key"
is-disabled = false
- elem
+ elem
name = "F9"
command = "Invisimin"
is-disabled = false
- elem
+ elem
name = "F12"
command = "F12"
is-disabled = false
macro "hotkeymode"
- elem
+ elem
name = "TAB"
command = ".Toggle-hotkey-mode"
is-disabled = false
- elem
+ elem
name = "CENTER+REP"
command = ".center"
is-disabled = false
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
is-disabled = false
- elem
+ elem
name = "SOUTHWEST"
command = ".southwest"
is-disabled = false
- elem
+ elem
name = "NORTHWEST"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
is-disabled = false
- elem
+ elem
name = "WEST+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
is-disabled = false
- elem
+ elem
name = "NORTH+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
is-disabled = false
- elem
+ elem
name = "EAST+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
is-disabled = false
- elem
+ elem
name = "SOUTH+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "INSERT"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
- elem
+ elem
name = "1"
command = "a-intent help"
is-disabled = false
- elem
+ elem
name = "CTRL+1"
command = "a-intent help"
is-disabled = false
- elem
+ elem
name = "2"
command = "a-intent disarm"
is-disabled = false
- elem
+ elem
name = "CTRL+2"
command = "a-intent disarm"
is-disabled = false
- elem
+ elem
name = "3"
command = "a-intent grab"
is-disabled = false
- elem
+ elem
name = "CTRL+3"
command = "a-intent grab"
is-disabled = false
- elem
+ elem
name = "4"
command = "a-intent harm"
is-disabled = false
- elem
+ elem
name = "CTRL+4"
command = "a-intent harm"
is-disabled = false
- elem
+ elem
name = "T"
command = ".say"
is-disabled = false
- elem
+ elem
name = "O"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "M"
command = ".me"
is-disabled = false
- elem
+ elem
name = "A+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+A+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "D+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+D+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "B"
command = "resist"
is-disabled = false
- elem
+ elem
name = "CTRL+B"
command = "resist"
is-disabled = false
- elem
+ elem
name = "E"
command = "quick-equip"
is-disabled = false
- elem
+ elem
name = "CTRL+E"
command = "quick-equip"
is-disabled = false
- elem
+ elem
name = "F"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "G"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "H"
command = "holster"
is-disabled = false
- elem
+ elem
name = "CTRL+H"
command = "holster"
is-disabled = false
- elem
+ elem
name = "Q"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "CTRL+Q"
command = ".northwest"
is-disabled = false
- elem
+ elem
name = "R"
command = ".southwest"
is-disabled = false
- elem
+ elem
name = "CTRL+R"
command = ".southwest"
is-disabled = false
@@ -1075,11 +1075,11 @@ macro "hotkeymode"
name = "S+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "CTRL+S+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "T"
command = ".say"
is-disabled = false
@@ -1087,267 +1087,267 @@ macro "hotkeymode"
name = "W+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+W+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "X"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "Y"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+Y"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "Z"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+Z"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "F1"
command = "adminhelp"
is-disabled = false
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
is-disabled = false
- elem
+ elem
name = "F2"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
is-disabled = false
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
is-disabled = false
- elem
+ elem
name = "F3"
command = ".say"
is-disabled = false
- elem
+ elem
name = "F4"
command = ".me"
is-disabled = false
- elem
+ elem
name = "F5"
command = "asay"
is-disabled = false
- elem
+ elem
name = "F6"
command = "Aghost"
is-disabled = false
- elem
+ elem
name = "F7"
command = "player-panel-new"
is-disabled = false
- elem
+ elem
name = "F8"
command = "admin-pm-key"
is-disabled = false
- elem
+ elem
name = "F9"
command = "Invisimin"
is-disabled = false
- elem
+ elem
name = "F12"
command = "F12"
is-disabled = false
macro "borgmacro"
- elem
+ elem
name = "TAB"
command = ".winset \"mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0\""
is-disabled = false
- elem
+ elem
name = "CENTER+REP"
command = ".center"
is-disabled = false
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
is-disabled = false
- elem
+ elem
name = "NORTHWEST"
command = "unequip-module"
is-disabled = false
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
is-disabled = false
- elem
+ elem
name = "WEST+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
is-disabled = false
- elem
+ elem
name = "NORTH+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
is-disabled = false
- elem
+ elem
name = "EAST+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
is-disabled = false
- elem
+ elem
name = "SOUTH+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "INSERT"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
- elem
+ elem
name = "CTRL+1"
command = "toggle-module 1"
is-disabled = false
- elem
+ elem
name = "CTRL+2"
command = "toggle-module 2"
is-disabled = false
- elem
+ elem
name = "CTRL+3"
command = "toggle-module 3"
is-disabled = false
- elem
+ elem
name = "CTRL+4"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "CTRL+A+REP"
command = ".west"
is-disabled = false
- elem
+ elem
name = "CTRL+B"
command = "resist"
is-disabled = false
- elem
+ elem
name = "CTRL+O"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "CTRL+D+REP"
command = ".east"
is-disabled = false
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
is-disabled = false
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
is-disabled = false
- elem
+ elem
name = "CTRL+Q"
command = "unequip-module"
is-disabled = false
- elem
+ elem
name = "CTRL+S+REP"
command = ".south"
is-disabled = false
- elem
+ elem
name = "CTRL+W+REP"
command = ".north"
is-disabled = false
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
is-disabled = false
- elem
+ elem
name = "CTRL+Y"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "CTRL+Z"
command = "Activate-Held-Object"
is-disabled = false
- elem
+ elem
name = "F1"
command = "adminhelp"
is-disabled = false
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
is-disabled = false
- elem
+ elem
name = "F2"
command = "ooc"
is-disabled = false
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
is-disabled = false
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
is-disabled = false
- elem
+ elem
name = "F3"
command = ".say"
is-disabled = false
- elem
+ elem
name = "F4"
command = ".me"
is-disabled = false
- elem
+ elem
name = "F5"
command = "asay"
is-disabled = false
- elem
+ elem
name = "F6"
command = "Aghost"
is-disabled = false
- elem
+ elem
name = "F7"
command = "player-panel-new"
is-disabled = false
- elem
+ elem
name = "F8"
command = "admin-pm-key"
is-disabled = false
- elem
+ elem
name = "F9"
command = "Invisimin"
is-disabled = false
- elem
+ elem
name = "F12"
command = "F12"
- is-disabled = false
+ is-disabled = false
menu "menu"
- elem
+ elem
name = "&File"
command = ""
category = ""
@@ -1356,7 +1356,7 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Quick screenshot\tF2"
command = ".screenshot auto"
category = "&File"
@@ -1365,7 +1365,7 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Save screenshot as...\tShift+F2"
command = ".screenshot"
category = "&File"
@@ -1374,7 +1374,7 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Reconnect"
command = ".reconnect"
category = "&File"
@@ -1383,7 +1383,7 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = ""
command = ""
category = "&File"
@@ -1392,7 +1392,7 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Quit"
command = ".quit"
category = "&File"
@@ -1401,7 +1401,7 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Icons"
command = ""
category = ""
@@ -1464,7 +1464,7 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Help"
command = ""
category = ""
@@ -1473,7 +1473,7 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Admin help\tF1"
command = "adminhelp"
category = "&Help"
@@ -1482,7 +1482,7 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Hotkeys"
command = "hotkeys-help"
category = "&Help"
@@ -2256,6 +2256,32 @@ window "mainwindow"
is-checked = false
group = ""
button-type = pushbox
+ elem "tooltip"
+ type = BROWSER
+ pos = 0,0
+ size = 999x999
+ anchor1 = none
+ anchor2 = none
+ font-family = ""
+ font-size = 0
+ font-style = ""
+ text-color = #ffffff
+ background-color = #000000
+ is-visible = false
+ is-disabled = false
+ is-transparent = false
+ is-default = false
+ border = none
+ drop-zone = false
+ right-click = false
+ saved-params = ""
+ on-size = ""
+ show-history = false
+ show-url = false
+ auto-format = false
+ use-title = false
+ on-show = ""
+ on-hide = ""
window "mapwindow"
elem "mapwindow"
diff --git a/paradise.dme b/paradise.dme
index 5493536e2b0..3955e96cb9d 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -98,6 +98,7 @@
#include "code\_onclick\hud\_defines.dm"
#include "code\_onclick\hud\action.dm"
#include "code\_onclick\hud\ai.dm"
+#include "code\_onclick\hud\alert.dm"
#include "code\_onclick\hud\alien.dm"
#include "code\_onclick\hud\alien_larva.dm"
#include "code\_onclick\hud\bot.dm"
@@ -1983,6 +1984,7 @@
#include "code\modules\telesci\gps.dm"
#include "code\modules\telesci\telepad.dm"
#include "code\modules\telesci\telesci_computer.dm"
+#include "code\modules\tooltip\tooltip.dm"
#include "code\modules\tram\tram.dm"
#include "code\modules\tram\tram_control_pad.dm"
#include "code\modules\tram\tram_floor.dm"