Merge pull request #4221 from tigercat2000/tgalerts

-tg- screen alerts
This commit is contained in:
TheDZD
2016-04-19 19:13:31 -04:00
54 changed files with 1764 additions and 1178 deletions
+8
View File
@@ -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"
+400
View File
@@ -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 << "<span class='boldnotice'>[name]</span> - <span class='info'>[desc]</span>"
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
+1 -19
View File
@@ -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
+1 -21
View File
@@ -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
+1 -13
View File
@@ -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
+4 -1
View File
@@ -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.")
+1 -37
View File
@@ -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
+1 -37
View File
@@ -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
+1 -20
View File
@@ -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')
+1 -27
View File
@@ -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
+1 -4
View File
@@ -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, "<span class='ghostalert'>Your corpse has been placed into a cloning scanner. Return to your body if you want to be cloned!</span> (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()
+1 -1
View File
@@ -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
@@ -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, "<span class='danger'>You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).</span>")
to_chat(B.host, "<span class='danger'>You feel the captive mind of [src] begin to resist your control.</span>")
spawn(rand(350,450) + B.host.brainloss)
if(!B || !B.controlling)
return
B.host.adjustBrainLoss(rand(5,10))
to_chat(src, "<span class='danger'>With an immense exertion of will, you regain control of your body!</span>")
to_chat(B.host, "<span class='danger'>You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.</span>")
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"
@@ -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)]! <a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>")
notify_ghosts("An unactivated swarmer has been created in [get_area(src)]!", enter_link = "<a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>", source = src, attack_not_jump = 1)
..()
/obj/item/unactivated_swarmer/Topic(href, href_list)
+3 -1
View File
@@ -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(.)
+1
View File
@@ -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:
+3 -110
View File
@@ -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, "<span class='notice'>You handcuff [C].</span>")
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("<span class='suicide'>[user] is sticking \his head in the [src.name]! It looks like \he's trying to commit suicide.</span>")
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, "<span class='notice'>[src] is now [armed ? "armed" : "disarmed"]</span>")
/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, "<span class='warning'>This beartrap already has an IED hooked up to it!</span>")
return
IED = I
switch(IED.assembled)
if(0,1) //if it's not fueled/hooked up
to_chat(user, "<span class='warning'>You haven't prepared this IED yet!</span>")
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, "<span class='notice'>You sneak the [IED] underneath the pressure plate and connect the trigger wire.</span>")
desc = "A trap used to catch bears and other legged creatures. <span class='warning'>There is an IED hooked up to it.</span>"
else
to_chat(user, "<span class='danger'>You shouldn't be reading this message! Contact a coder or someone, something broke!</span>")
IED = null
return
if(istype(I, /obj/item/weapon/screwdriver))
if(IED)
IED.forceMove(get_turf(src))
IED = null
to_chat(user, "<span class='notice'>You remove the IED from the [src].</span>")
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("<span class='danger'>[L] triggers \the [src].</span>", \
"<span class='userdanger'>You trigger \the [src]!</span>")
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)
..()
+98 -3
View File
@@ -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("<span class='suicide'>[user] is sticking \his head in the [src.name]! It looks like \he's trying to commit suicide.</span>")
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, "<span class='notice'>[src] is now [armed ? "armed" : "disarmed"]</span>")
/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, "<span class='warning'>This beartrap already has an IED hooked up to it!</span>")
return
IED = I
switch(IED.assembled)
if(0,1) //if it's not fueled/hooked up
to_chat(user, "<span class='warning'>You haven't prepared this IED yet!</span>")
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, "<span class='notice'>You sneak the [IED] underneath the pressure plate and connect the trigger wire.</span>")
desc = "A trap used to catch bears and other legged creatures. <span class='warning'>There is an IED hooked up to it.</span>"
else
to_chat(user, "<span class='danger'>You shouldn't be reading this message! Contact a coder or someone, something broke!</span>")
IED = null
return
if(istype(I, /obj/item/weapon/screwdriver))
if(IED)
IED.forceMove(get_turf(src))
IED = null
to_chat(user, "<span class='notice'>You remove the IED from the [src].</span>")
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("<span class='danger'>[L] triggers \the [src].</span>", \
"<span class='userdanger'>You trigger \the [src]!</span>")
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"
+1 -1
View File
@@ -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
..()
+1 -8
View File
@@ -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 <b>Someone has begun playing with a [src.name] in [A.name]!. (<a href='?src=\ref[O];jump=\ref[src]'>Teleport</a>)</b>")
/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]\".")
+4 -1
View File
@@ -81,4 +81,7 @@
control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
var/datum/click_intercept/click_intercept = null
var/datum/click_intercept/click_intercept = null
//datum that controls the displaying and hiding of tooltips
var/datum/tooltip/tooltips
+4
View File
@@ -317,6 +317,10 @@
to_chat(src, "<span class='warning'>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.</span>")
//This is down here because of the browse() calls in tooltip/New()
if(!tooltips)
tooltips = new /datum/tooltip(src)
//////////////
//DISCONNECT//
//////////////
@@ -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, "<span class='ghostalert'>[message]</span>")
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, "<span class='ghostalert'><a href=?src=\ref[src];reenter=1>(Click to re-enter)</a></span>")
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
@@ -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
@@ -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
+4 -12
View File
@@ -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, "<span class='danger'>You feel a searing heat in your lungs!</span>")
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
@@ -47,8 +47,6 @@
for(var/mob/dead/observer/O in player_list)
if(check_observer(O))
to_chat(O, "<span class='boldnotice'>\A [src] has been activated. (<a href='?src=\ref[O];jump=\ref[src]'>Teleport</a> | <a href='?src=\ref[src];signup=\ref[O]'>Sign Up</a>)</span>")
// 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)
+127 -2
View File
@@ -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("<span class='warning'>[src] attempts to unbuckle themself!</span>", \
"<span class='notice'>You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)</span>")
if(do_after(src, 600, 0, target = src))
if(!buckled)
return
buckled.user_unbuckle_mob(src,src)
else
if(src && buckled)
src << "<span class='warning'>You fail to unbuckle yourself!</span>"
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("<span class='danger'>[src] rolls on the floor, trying to put themselves out!</span>", \
"<span class='notice'>You stop, drop, and roll!</span>")
sleep(30)
if(fire_stacks <= 0)
visible_message("<span class='danger'>[src] has successfully extinguished themselves!</span>", \
"<span class='notice'>You extinguish yourself.</span>")
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("<span class='warning'>[src] attempts to remove [I]!</span>")
to_chat(src, "<span class='notice'>You attempt to remove [I]... (This will take around [displaytime] minutes and you need to stand still.)</span>")
if(do_after(src, breakouttime, 0, target = src))
if(I.loc != src || buckled)
return
visible_message("<span class='danger'>[src] manages to remove [I]!</span>")
to_chat(src, "<span class='notice'>You successfully remove [I].</span>")
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, "<span class='warning'>You fail to remove [I]!</span>")
else
breakouttime = 50
visible_message("<span class='warning'>[src] is trying to break [I]!</span>")
to_chat(src, "<span class='notice'>You attempt to break [I]... (This will take around 5 seconds and you need to stand still.)</span>")
if(do_after(src, breakouttime, 0, target = src))
if(!I.loc || buckled)
return
visible_message("<span class='danger'>[src] manages to break [I]!</span>")
to_chat(src, "<span class='notice'>You successfully break [I].</span>")
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, "<span class='warning'>You fail to break [I]!</span>")
//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)
@@ -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()
+22 -22
View File
@@ -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()
@@ -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, "<span class='warning'>You feel your face freezing and an icicle forming in your lungs!</span>")
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, "<span class='warning'>You feel your face burning and a searing heat in your lungs!</span>")
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
/*
@@ -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"
@@ -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)
+5 -8
View File
@@ -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)
+7 -4
View File
@@ -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))
+42 -226
View File
@@ -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 <B>You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).</B>")
to_chat(B.host, "\red <B>You feel the captive mind of [src] begin to resist your control.</B>")
spawn(rand(350,450)+B.host.brainloss)
if(!B || !B.controlling)
return
B.host.adjustBrainLoss(rand(5,10))
to_chat(H, "\red <B>With an immense exertion of will, you regain control of your body!</B>")
to_chat(B.host, "\red <B>You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.</b>")
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("<span class='danger'>[src] has broken free of [G.assailant]'s grip!</span>")
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("<span class='danger'>[src] has broken free of [G.assailant]'s headlock!</span>")
qdel(G)
if(resisting)
for(var/mob/O in viewers(usr, null))
O.show_message(text("\red <B>[] resists!</B>", L), 1)
visible_message("<span class='danger'>[src] resists!</span>")
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)</span>")
for(var/mob/O in viewers(L))
O.show_message("\red <B>[usr] attempts to unbuckle themself!</B>", 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 <B>[usr] manages to unbuckle themself!</B>", 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("<span class='danger'>[CM] rolls on the floor, trying to put themselves out!</span>", \
"<span class='notice'>You stop, drop, and roll!</span>")
sleep(30)
if(fire_stacks <= 0)
CM.visible_message("<span class='danger'>[CM] has successfully extinguished themselves!</span>", \
"<span class='notice'>You extinguish yourself.</span>")
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 <B>[usr] attempts to [hulklien ? "break" : "remove"] \the [HC]!</B>", 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 <B>[CM] manages to [hulklien ? "break" : "remove"] the handcuffs!</B>", 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 <B>[usr] attempts to [hulklien ? "break" : "remove"] \the [HC]!</B>", 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 <B>[CM] manages to [hulklien ? "break" : "remove"] the legcuffs!</B>", 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, "<span class='notice'>You're too exhausted to keep going...</span>")
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)
@@ -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()
+11 -3
View File
@@ -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, "<span class='warning'>Internal camera is currently being accessed.</span>")
/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)
+37 -65
View File
@@ -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()
@@ -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, "<b>Obey these laws:</b>")
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()
@@ -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"
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)
@@ -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()
@@ -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()
@@ -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
-6
View File
@@ -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
+19 -3
View File
@@ -556,12 +556,28 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM)
lname = "<span class='name'>[lname]</span> "
to_chat(M, "<span class='deadsay'>[lname][follow][message]</span>")
/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, "<span class='ghostalert'>[message]<span>")
to_chat(O, "<span class='ghostalert'>[message][(enter_link) ? " [enter_link]" : ""]<span>")
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))
+2 -4
View File
@@ -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)
@@ -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
+116
View File
@@ -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 = "<h1>[title]</h1>"
content = "<p>[content]</p>"
else if (title && !content)
title = "<p>[title]</p>"
else if (!title && content)
content = "<p>[content]</p>"
//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()
+238
View File
@@ -0,0 +1,238 @@
<!DOCTYPE html>
<html>
<head>
<title>Tooltip</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
body, html {
margin: 0;
padding: 0;
overflow: hidden;
}
.wrap {
position: absolute;
top: 0;
left: 0;
max-width: 298px;
border: 2px solid #1B2967;
}
.content {
font: bold 12px Arial, 'Helvetica Neue', Helvetica, sans-serif;
color: #ffffff;
padding: 8px;
border: 2px solid #0033CC;
background: #005CB8;
}
h1 {
margin: -5px 0 2px 0;
font-size: 1.2em;
line-height: 1.4;
}
p {
margin: 0;
line-height: 1.2;
}
/* Custom Themes */
.blob .wrap {border-color: #2E2E2E;}
.blob .content {color: #82ED00; border-color: #4E4C4A; background-color: #191918;}
.parasite .wrap {border-color: #88868D;}
.parasite .content {color: #EFEEEF; border-color: #35333A; background-color: #636169;}
.alien .wrap {border-color: #33165B;}
.alien .content {color: #25004A; border-color: #5A3076; background-color: #6D3A8E;}
.wraith .wrap {border-color: #492136;}
.wraith .content {border-color: #331726; background-color: #471962;}
.cult .wrap {border-color: #610002;}
.cult .content {color: #0F0B0C; border-color: #A10000; background-color: #4A363B;}
.pod .wrap {border-color: #052401;}
.pod .content {border-color: #326D29; background-color: #569F4B;}
.colo-pod .wrap {border-color: #256fb9;}
.colo-pod .content {border-color: #000000; background-color: #000000;}
/* TG: Themes */
/* ScreenUI */
.midnight .wrap {border-color: #2B2B33;}
.midnight .content {color: #6087A0; border-color: #2B2B33; background-color: #36363C;}
.plasmafire .wrap {border-color: #21213D;}
.plasmafire .content {color: #FFA800 ; border-color: #21213D; background-color:#1D1D36;}
.retro .wrap {border-color: #005E00;}
.retro .content {color: #003366; border-color: #005E00; background-color: #00BD00;}
.slimecore .wrap {border-color: #18640E;}
.slimecore .content {color: #6EA161; border-color: #11450B; background-color: #354E35;}
.operative .wrap {border-color: #1E0101;}
.operative .content {color: #FFFFFF; border-color: #750000; background-color: #350000;}
</style>
</head>
<body>
<div id="wrap" class="wrap">
<div id="content" class="content"></div>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
var tooltip = {
'tileSize': 32,
'control': '',
'params': {},
'clientView': 0,
'text': '',
'theme': '',
'padding': 2,
init: function(tileSize, control) {
tooltip.tileSize = parseInt(tileSize);
tooltip.control = control;
},
hide: function() {
window.location = 'byond://winset?id='+tooltip.control+';is-visible=false';
},
updateCallback: function(map) {
if (typeof map === 'undefined' || !map) {return false;}
//alert(tooltip.params+' | '+tooltip.clientView+' | '+tooltip.text+' | '+tooltip.theme); //DEBUG
//Some reset stuff to avoid fringe issues with sizing
window.location = 'byond://winset?id='+tooltip.control+';anchor1=0,0;size=999x999';
//Get the real icon size according to the client view
var mapWidth = map['view-size'].x,
mapHeight = map['view-size'].y,
tilesShown = (tooltip.clientView * 2) + 1,
realIconSize = mapWidth / tilesShown,
resizeRatio = realIconSize / tooltip.tileSize,
//Calculate letterboxing offsets
leftOffset = (map.size.x - mapWidth) / 2,
topOffset = (map.size.y - mapHeight) / 2;
//alert(realIconSize + ' | ' +tooltip.tileSize + ' | ' + resizeRatio); //DEBUG
//Parse out the tile and cursor locations from params (e.g. "icon-x=32;icon-y=29;screen-loc=3:10,15:29")
var paramsA = tooltip.params.cursor.split(';');
if (paramsA.length < 3) {return false;} //Sometimes screen-loc is never sent ahaha fuck you byond
//icon-x
var iconX = paramsA[0];
iconX = iconX.split('=');
iconX = parseInt(iconX[1]);
//icon-y
var iconY = paramsA[1];
iconY = iconY.split('=');
iconY = parseInt(iconY[1]);
//screen-loc
var screenLoc = paramsA[2];
screenLoc = screenLoc.split('=');
screenLoc = screenLoc[1].split(',');
if (screenLoc.length < 2) {return false;}
var left = screenLoc[0];
var top = screenLoc[1];
if (!left || !top) {return false;}
screenLoc = left.split(':');
left = parseInt(screenLoc[0]);
var enteredX = parseInt(screenLoc[1]);
screenLoc = top.split(':');
top = parseInt(screenLoc[0]);
var enteredY = parseInt(screenLoc[1]);
//Screen loc offsets on objects (e.g. "WEST+0:6,NORTH-1:26") can royally mess with positioning depending on where the cursor enters
//This is a giant bitch to parse. Note that it only expects screen_loc in the format <west>,<north>.
var oScreenLoc = tooltip.params.screenLoc.split(','); //o for original ok
var west = oScreenLoc[0].split(':');
if (west.length > 1) { //Only if west has a pixel offset
var westOffset = parseInt(west[1]);
if (westOffset !== 0) {
if ((iconX + westOffset) !== enteredX) { //Cursor entered on the offset tile
left = left + (westOffset < 0 ? 1 : -1);
}
leftOffset = leftOffset + (westOffset * resizeRatio);
}
}
if (oScreenLoc.length > 1) { //If north is given
var north = oScreenLoc[1].split(':');
if (north.length > 1) { //Only if north has a pixel offset
var northOffset = parseInt(north[1]);
if (northOffset !== 0) {
if ((iconY + northOffset) === enteredY) { //Cursor entered on the original tile
top--;
topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatio);
} else { //Cursor entered on the offset tile
if (northOffset < 0) { //Offset southwards
topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatio);
} else { //Offset northwards
top--;
topOffset = topOffset - (northOffset * resizeRatio);
}
}
}
}
}
//Handle special cases (for fuck sake)
if (tooltip.special !== 'none') {
//Put yo special cases here
}
//Clamp values
left = (left < 0 ? 0 : (left > tilesShown ? tilesShown : left));
top = (top < 0 ? 0 : (top > tilesShown ? tilesShown : top));
//Calculate where on the screen the popup should appear (below the hovered tile)
var posX = Math.round(((left - 1) * realIconSize) + leftOffset + tooltip.padding); //-1 to position at the left of the target tile
var posY = Math.round(((tilesShown - top + 1) * realIconSize) + topOffset + tooltip.padding); //+1 to position at the bottom of the target tile
//alert(mapWidth+' | '+mapHeight+' | '+tilesShown+' | '+realIconSize+' | '+leftOffset+' | '+topOffset+' | '+left+' | '+top+' | '+posX+' | '+posY); //DEBUG
$('body').attr('class', tooltip.theme);
var $content = $('#content'),
$wrap = $('#wrap');
$wrap.attr('style', '');
$content.off('mouseover');
$content.html(tooltip.text);
$wrap.width($wrap.width() + 2); //Dumb hack to fix a bizarre sizing bug
var docWidth = $wrap.outerWidth(),
docHeight = $wrap.outerHeight();
if (posY + docHeight > map.size.y) { //Is the bottom edge below the window? Snap it up if so
posY = (posY - docHeight) - realIconSize - tooltip.padding;
}
//Actually size, move and show the tooltip box
window.location = 'byond://winset?id='+tooltip.control+';size='+docWidth+'x'+docHeight+';pos='+posX+','+posY+';is-visible=true';
$content.on('mouseover', function() {
tooltip.hide();
});
},
update: function(params, clientView, text, theme, special) {
//Assign our global object
tooltip.params = $.parseJSON(params);
tooltip.clientView = parseInt(clientView);
tooltip.text = text;
tooltip.theme = theme;
tooltip.special = special;
//Go get the map details
window.location = 'byond://winget?callback=tooltip.updateCallback;id=mapwindow.map;property=size,view-size';
},
};
</script>
</body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 KiB

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+367 -341
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -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"