July 5th TG sync (#1883)

July 5th TG sync
This commit is contained in:
Poojawa
2017-07-05 22:14:19 -05:00
committed by GitHub
parent 454b9c3d68
commit b1b4826c0c
1264 changed files with 149689 additions and 570309 deletions
+8 -12
View File
@@ -838,18 +838,14 @@ GLOBAL_LIST_EMPTY(PDAs)
/obj/item/device/pda/Destroy()
GLOB.PDAs -= src
if(id)
qdel(id)
id = null
if(cartridge)
qdel(cartridge)
cartridge = null
if(pai)
qdel(pai)
pai = null
if(inserted_item)
qdel(inserted_item)
inserted_item = null
if(istype(id))
QDEL_NULL(id)
if(istype(cartridge))
QDEL_NULL(cartridge)
if(istype(pai))
QDEL_NULL(pai)
if(istype(inserted_item))
QDEL_NULL(inserted_item)
return ..()
//AI verb and proc for sending PDA messages.
@@ -2,6 +2,7 @@
/obj/item/device/pda/clown
name = "clown PDA"
default_cartridge = /obj/item/weapon/cartridge/virus/clown
inserted_item = /obj/item/toy/crayon/rainbow
icon_state = "pda-clown"
desc = "A portable microcomputer by Thinktronic Systems, LTD. The surface is coated with polytetrafluoroethylene and banana drippings."
ttone = "honk"
@@ -9,7 +10,7 @@
/obj/item/device/pda/clown/Crossed(AM as mob|obj)
if (istype(AM, /mob/living/carbon))
var/mob/living/carbon/M = AM
if(M.slip(0, 6, src, NO_SLIP_WHEN_WALKING))
if(M.slip(120, src, NO_SLIP_WHEN_WALKING))
if (ishuman(M) && (M.real_name != src.owner))
if (istype(src.cartridge, /obj/item/weapon/cartridge/virus/clown))
var/obj/item/weapon/cartridge/virus/cart = src.cartridge
@@ -80,6 +81,7 @@
/obj/item/device/pda/mime
name = "mime PDA"
default_cartridge = /obj/item/weapon/cartridge/virus/mime
inserted_item = /obj/item/toy/crayon/mime
icon_state = "pda-mime"
silent = 1
ttone = "silence"
+59 -59
View File
@@ -1,62 +1,62 @@
/obj/item/radio/integrated
name = "\improper PDA radio module"
desc = "An electronic radio system of nanotrasen origin."
icon = 'icons/obj/module.dmi'
icon_state = "power_mod"
var/on = 0 //Are we currently active??
var/menu_message = ""
/obj/item/radio/integrated
name = "\improper PDA radio module"
desc = "An electronic radio system of nanotrasen origin."
icon = 'icons/obj/module.dmi'
icon_state = "power_mod"
var/on = 0 //Are we currently active??
var/menu_message = ""
/obj/item/radio/integrated/Initialize()
. = ..()
/obj/item/radio/integrated/Destroy()
return ..()
/*
* Radio Cartridge, essentially a signaler.
*/
/obj/item/radio/integrated/signal
var/frequency = 1457
var/code = 30
var/last_transmission
var/datum/radio_frequency/radio_connection
/obj/item/radio/integrated/signal/Destroy()
if(SSradio)
SSradio.remove_object(src, frequency)
radio_connection = null
return ..()
/obj/item/radio/integrated/signal/Initialize()
..()
if (src.frequency < 1200 || src.frequency > 1600)
src.frequency = sanitize_frequency(src.frequency)
set_frequency(frequency)
/obj/item/radio/integrated/signal/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency)
/obj/item/radio/integrated/signal/proc/send_signal(message="ACTIVATE")
if(last_transmission && world.time < (last_transmission + 5))
return
last_transmission = world.time
var/time = time2text(world.realtime,"hh:mm:ss")
var/turf/T = get_turf(src)
GLOB.lastsignalers.Add("[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(frequency)]/[code]")
var/datum/signal/signal = new
signal.source = src
signal.encryption = code
signal.data["message"] = message
radio_connection.post_signal(src, signal)
/obj/item/radio/integrated/Destroy()
return ..()
/*
* Radio Cartridge, essentially a signaler.
*/
/obj/item/radio/integrated/signal
var/frequency = 1457
var/code = 30
var/last_transmission
var/datum/radio_frequency/radio_connection
/obj/item/radio/integrated/signal/Destroy()
if(SSradio)
SSradio.remove_object(src, frequency)
radio_connection = null
return ..()
/obj/item/radio/integrated/signal/Initialize()
..()
if (src.frequency < 1200 || src.frequency > 1600)
src.frequency = sanitize_frequency(src.frequency)
set_frequency(frequency)
/obj/item/radio/integrated/signal/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency)
/obj/item/radio/integrated/signal/proc/send_signal(message="ACTIVATE")
if(last_transmission && world.time < (last_transmission + 5))
return
last_transmission = world.time
var/time = time2text(world.realtime,"hh:mm:ss")
var/turf/T = get_turf(src)
GLOB.lastsignalers.Add("[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(frequency)]/[code]")
var/datum/signal/signal = new
signal.source = src
signal.encryption = code
signal.data["message"] = message
radio_connection.post_signal(src, signal)
return
+85 -85
View File
@@ -1,87 +1,87 @@
/obj/item/device/aicard
name = "intelliCard"
desc = "A storage device for AIs. Patent pending."
icon = 'icons/obj/aicards.dmi'
icon_state = "aicard" // aicard-full
item_state = "electronic"
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
flags = NOBLUDGEON
var/flush = FALSE
var/mob/living/silicon/ai/AI
origin_tech = "programming=3;materials=3"
/obj/item/device/aicard/afterattack(atom/target, mob/user, proximity)
..()
if(!proximity || !target)
return
if(AI) //AI is on the card, implies user wants to upload it.
target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
add_logs(user, AI, "carded", src)
else //No AI on the card, therefore the user wants to download one.
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
update_icon() //Whatever happened, update the card's state (icon, name) to match.
/obj/item/device/aicard/update_icon()
/obj/item/device/aicard
name = "intelliCard"
desc = "A storage device for AIs. Patent pending."
icon = 'icons/obj/aicards.dmi'
icon_state = "aicard" // aicard-full
item_state = "electronic"
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
flags = NOBLUDGEON
var/flush = FALSE
var/mob/living/silicon/ai/AI
origin_tech = "programming=3;materials=3"
/obj/item/device/aicard/afterattack(atom/target, mob/user, proximity)
..()
if(!proximity || !target)
return
if(AI) //AI is on the card, implies user wants to upload it.
target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
add_logs(user, AI, "carded", src)
else //No AI on the card, therefore the user wants to download one.
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
update_icon() //Whatever happened, update the card's state (icon, name) to match.
/obj/item/device/aicard/update_icon()
cut_overlays()
if(AI)
name = "[initial(name)]- [AI.name]"
if(AI.stat == DEAD)
icon_state = "aicard-404"
else
icon_state = "aicard-full"
if(!AI.control_disabled)
if(AI)
name = "[initial(name)]- [AI.name]"
if(AI.stat == DEAD)
icon_state = "aicard-404"
else
icon_state = "aicard-full"
if(!AI.control_disabled)
add_overlay("aicard-on")
AI.cancel_camera()
else
name = initial(name)
icon_state = initial(icon_state)
/obj/item/device/aicard/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "intellicard", name, 500, 500, master_ui, state)
ui.open()
/obj/item/device/aicard/ui_data()
var/list/data = list()
if(AI)
data["name"] = AI.name
data["laws"] = AI.laws.get_law_list(include_zeroth = 1)
data["health"] = (AI.health + 100) / 2
data["wireless"] = !AI.control_disabled //todo disabled->enabled
data["radio"] = AI.radio_enabled
data["isDead"] = AI.stat == DEAD
data["isBraindead"] = AI.client ? FALSE : TRUE
data["wiping"] = flush
return data
/obj/item/device/aicard/ui_act(action,params)
if(..())
return
switch(action)
if("wipe")
if(flush)
flush = FALSE
else
var/confirm = alert("Are you sure you want to wipe this card's memory?", name, "Yes", "No")
if(confirm == "Yes" && !..())
flush = TRUE
if(AI && AI.loc == src)
to_chat(AI, "Your core files are being wiped!")
while(AI.stat != DEAD && flush)
AI.adjustOxyLoss(1)
AI.updatehealth()
sleep(5)
flush = FALSE
. = TRUE
if("wireless")
AI.control_disabled = !AI.control_disabled
to_chat(AI, "[src]'s wireless port has been [AI.control_disabled ? "disabled" : "enabled"]!")
. = TRUE
if("radio")
AI.radio_enabled = !AI.radio_enabled
to_chat(AI, "Your Subspace Transceiver has been [AI.radio_enabled ? "enabled" : "disabled"]!")
. = TRUE
update_icon()
AI.cancel_camera()
else
name = initial(name)
icon_state = initial(icon_state)
/obj/item/device/aicard/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "intellicard", name, 500, 500, master_ui, state)
ui.open()
/obj/item/device/aicard/ui_data()
var/list/data = list()
if(AI)
data["name"] = AI.name
data["laws"] = AI.laws.get_law_list(include_zeroth = 1)
data["health"] = (AI.health + 100) / 2
data["wireless"] = !AI.control_disabled //todo disabled->enabled
data["radio"] = AI.radio_enabled
data["isDead"] = AI.stat == DEAD
data["isBraindead"] = AI.client ? FALSE : TRUE
data["wiping"] = flush
return data
/obj/item/device/aicard/ui_act(action,params)
if(..())
return
switch(action)
if("wipe")
if(flush)
flush = FALSE
else
var/confirm = alert("Are you sure you want to wipe this card's memory?", name, "Yes", "No")
if(confirm == "Yes" && !..())
flush = TRUE
if(AI && AI.loc == src)
to_chat(AI, "Your core files are being wiped!")
while(AI.stat != DEAD && flush)
AI.adjustOxyLoss(1)
AI.updatehealth()
sleep(5)
flush = FALSE
. = TRUE
if("wireless")
AI.control_disabled = !AI.control_disabled
to_chat(AI, "[src]'s wireless port has been [AI.control_disabled ? "disabled" : "enabled"]!")
. = TRUE
if("radio")
AI.radio_enabled = !AI.radio_enabled
to_chat(AI, "Your Subspace Transceiver has been [AI.radio_enabled ? "enabled" : "disabled"]!")
. = TRUE
update_icon()
@@ -34,7 +34,7 @@
if(!check_sprite(target))
return
if(!active_dummy)
if(istype(target,/obj/item) && !istype(target, /obj/item/weapon/disk/nuclear))
if(isitem(target) && !istype(target, /obj/item/weapon/disk/nuclear))
playsound(get_turf(src), 'sound/weapons/flash.ogg', 100, 1, -6)
to_chat(user, "<span class='notice'>Scanned [target].</span>")
var/obj/temp = new/obj()
+401 -401
View File
@@ -1,66 +1,66 @@
/obj/item/device/flashlight
name = "flashlight"
desc = "A hand-held emergency light."
icon = 'icons/obj/lighting.dmi'
icon_state = "flashlight"
item_state = "flashlight"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
slot_flags = SLOT_BELT
materials = list(MAT_METAL=50, MAT_GLASS=20)
actions_types = list(/datum/action/item_action/toggle_light)
var/on = 0
var/brightness_on = 4 //range of light when on
/obj/item/device/flashlight
name = "flashlight"
desc = "A hand-held emergency light."
icon = 'icons/obj/lighting.dmi'
icon_state = "flashlight"
item_state = "flashlight"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
slot_flags = SLOT_BELT
materials = list(MAT_METAL=50, MAT_GLASS=20)
actions_types = list(/datum/action/item_action/toggle_light)
var/on = 0
var/brightness_on = 4 //range of light when on
var/flashlight_power = 1 //strength of the light when on
/obj/item/device/flashlight/Initialize()
..()
update_brightness()
/obj/item/device/flashlight/proc/update_brightness(mob/user = null)
if(on)
icon_state = "[initial(icon_state)]-on"
if(flashlight_power)
set_light(l_range = brightness_on, l_power = flashlight_power)
else
set_light(brightness_on)
else
icon_state = initial(icon_state)
set_light(0)
/obj/item/device/flashlight/attack_self(mob/user)
on = !on
update_brightness(user)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
return 1
/obj/item/device/flashlight/Initialize()
..()
update_brightness()
/obj/item/device/flashlight/proc/update_brightness(mob/user = null)
if(on)
icon_state = "[initial(icon_state)]-on"
if(flashlight_power)
set_light(l_range = brightness_on, l_power = flashlight_power)
else
set_light(brightness_on)
else
icon_state = initial(icon_state)
set_light(0)
/obj/item/device/flashlight/attack_self(mob/user)
on = !on
update_brightness(user)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
return 1
/obj/item/device/flashlight/suicide_act(mob/living/carbon/human/user)
user.visible_message("<span class='suicide'>[user] is putting [src] close to [user.p_their()] eyes and turning it on! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (FIRELOSS)
/obj/item/device/flashlight/attack(mob/living/carbon/M, mob/living/carbon/human/user)
add_fingerprint(user)
add_fingerprint(user)
if(istype(M) && on && user.zone_selected in list("eyes", "mouth"))
if((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(!M.get_bodypart("head"))
to_chat(user, "<span class='warning'>[M] doesn't have a head!</span>")
return
return
if(flashlight_power < 1)
to_chat(user, "<span class='warning'>\The [src] isn't bright enough to see anything!</span> ")
return
switch(user.zone_selected)
if("eyes")
if((M.head && M.head.flags_cover & HEADCOVERSEYES) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSEYES) || (M.glasses && M.glasses.flags_cover & GLASSESCOVERSEYES))
@@ -152,366 +152,366 @@
if(pill_count)
to_chat(user, "<span class='notice'>[M] has [pill_count] pill[pill_count > 1 ? "s" : ""] implanted in [their] teeth.")
else
return ..()
/obj/item/device/flashlight/pen
name = "penlight"
desc = "A pen-sized light, used by medical staff. It can also be used to create a hologram to alert people of incoming medical assistance."
icon_state = "penlight"
item_state = ""
flags = CONDUCT
brightness_on = 2
var/holo_cooldown = 0
/obj/item/device/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag)
if(!proximity_flag)
if(holo_cooldown > world.time)
to_chat(user, "<span class='warning'>[src] is not ready yet!</span>")
return
var/T = get_turf(target)
if(locate(/mob/living) in T)
else
return ..()
/obj/item/device/flashlight/pen
name = "penlight"
desc = "A pen-sized light, used by medical staff. It can also be used to create a hologram to alert people of incoming medical assistance."
icon_state = "penlight"
item_state = ""
flags = CONDUCT
brightness_on = 2
var/holo_cooldown = 0
/obj/item/device/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag)
if(!proximity_flag)
if(holo_cooldown > world.time)
to_chat(user, "<span class='warning'>[src] is not ready yet!</span>")
return
var/T = get_turf(target)
if(locate(/mob/living) in T)
new /obj/effect/temp_visual/medical_holosign(T,user) //produce a holographic glow
holo_cooldown = world.time + 100
return
..()
holo_cooldown = world.time + 100
return
..()
/obj/effect/temp_visual/medical_holosign
name = "medical holosign"
desc = "A small holographic glow that indicates a medic is coming to treat a patient."
icon_state = "medi_holo"
duration = 30
name = "medical holosign"
desc = "A small holographic glow that indicates a medic is coming to treat a patient."
icon_state = "medi_holo"
duration = 30
/obj/effect/temp_visual/medical_holosign/Initialize(mapload, creator)
. = ..()
playsound(loc, 'sound/machines/ping.ogg', 50, 0) //make some noise!
if(creator)
visible_message("<span class='danger'>[creator] created a medical hologram!</span>")
/obj/item/device/flashlight/seclite
name = "seclite"
desc = "A robust flashlight used by security."
icon_state = "seclite"
item_state = "seclite"
force = 9 // Not as good as a stun baton.
brightness_on = 5 // A little better than the standard flashlight.
hitsound = 'sound/weapons/genhit1.ogg'
// the desk lamps are a bit special
/obj/item/device/flashlight/lamp
name = "desk lamp"
desc = "A desk lamp with an adjustable mount."
icon_state = "lamp"
item_state = "lamp"
brightness_on = 5
w_class = WEIGHT_CLASS_BULKY
flags = CONDUCT
materials = list()
on = 1
// green-shaded desk lamp
/obj/item/device/flashlight/lamp/green
desc = "A classic green-shaded desk lamp."
icon_state = "lampgreen"
item_state = "lampgreen"
/obj/item/device/flashlight/lamp/verb/toggle_light()
set name = "Toggle light"
set category = "Object"
set src in oview(1)
if(!usr.stat)
attack_self(usr)
//Bananalamp
/obj/item/device/flashlight/lamp/bananalamp
name = "banana lamp"
desc = "Only a clown would think to make a ghetto banana-shaped lamp. Even has a goofy pullstring."
icon_state = "bananalamp"
item_state = "bananalamp"
// FLARES
/obj/item/device/flashlight/flare
name = "flare"
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
w_class = WEIGHT_CLASS_SMALL
brightness_on = 7 // Pretty bright.
icon_state = "flare"
item_state = "flare"
actions_types = list()
var/fuel = 0
var/on_damage = 7
var/produce_heat = 1500
heat = 1000
light_color = LIGHT_COLOR_FLARE
/obj/item/device/flashlight/flare/New()
fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds.
..()
/obj/item/device/flashlight/flare/process()
open_flame(heat)
fuel = max(fuel - 1, 0)
if(!fuel || !on)
turn_off()
if(!fuel)
icon_state = "[initial(icon_state)]-empty"
STOP_PROCESSING(SSobj, src)
/obj/item/device/flashlight/flare/ignition_effect(atom/A, mob/user)
if(fuel && on)
. = "<span class='notice'>[user] lights [A] with [src] like a real \
badass.</span>"
else
. = ""
/obj/item/device/flashlight/flare/proc/turn_off()
on = 0
force = initial(src.force)
damtype = initial(src.damtype)
if(ismob(loc))
var/mob/U = loc
update_brightness(U)
else
update_brightness(null)
/obj/item/device/flashlight/flare/update_brightness(mob/user = null)
..()
if(on)
item_state = "[initial(item_state)]-on"
else
item_state = "[initial(item_state)]"
/obj/item/device/flashlight/flare/attack_self(mob/user)
// Usual checks
if(!fuel)
to_chat(user, "<span class='warning'>[src] is out of fuel!</span>")
return
if(on)
to_chat(user, "<span class='notice'>[src] is already on.</span>")
return
. = ..()
// All good, turn it on.
if(.)
user.visible_message("<span class='notice'>[user] lights \the [src].</span>", "<span class='notice'>You light \the [src]!</span>")
force = on_damage
damtype = "fire"
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/flare/is_hot()
return on * heat
/obj/item/device/flashlight/flare/torch
name = "torch"
desc = "A torch fashioned from some leaves and a log."
w_class = WEIGHT_CLASS_BULKY
brightness_on = 4
icon_state = "torch"
item_state = "torch"
on_damage = 10
slot_flags = null
/obj/item/device/flashlight/lantern
name = "lantern"
icon_state = "lantern"
item_state = "lantern"
desc = "A mining lantern."
brightness_on = 6 // luminosity when on
/obj/item/device/flashlight/slime
gender = PLURAL
name = "glowing slime extract"
desc = "Extract from a yellow slime. It emits a strong light when squeezed."
icon = 'icons/obj/lighting.dmi'
icon_state = "slime"
item_state = "slime"
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
materials = list()
brightness_on = 6 //luminosity when on
/obj/item/device/flashlight/emp
origin_tech = "magnets=3;syndicate=1"
var/emp_max_charges = 4
var/emp_cur_charges = 4
var/charge_tick = 0
/obj/item/device/flashlight/emp/New()
..()
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/emp/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/device/flashlight/emp/process()
charge_tick++
if(charge_tick < 10)
return FALSE
charge_tick = 0
emp_cur_charges = min(emp_cur_charges+1, emp_max_charges)
return TRUE
/obj/item/device/flashlight/emp/attack(mob/living/M, mob/living/user)
playsound(loc, 'sound/machines/ping.ogg', 50, 0) //make some noise!
if(creator)
visible_message("<span class='danger'>[creator] created a medical hologram!</span>")
/obj/item/device/flashlight/seclite
name = "seclite"
desc = "A robust flashlight used by security."
icon_state = "seclite"
item_state = "seclite"
force = 9 // Not as good as a stun baton.
brightness_on = 5 // A little better than the standard flashlight.
hitsound = 'sound/weapons/genhit1.ogg'
// the desk lamps are a bit special
/obj/item/device/flashlight/lamp
name = "desk lamp"
desc = "A desk lamp with an adjustable mount."
icon_state = "lamp"
item_state = "lamp"
brightness_on = 5
w_class = WEIGHT_CLASS_BULKY
flags = CONDUCT
materials = list()
on = 1
// green-shaded desk lamp
/obj/item/device/flashlight/lamp/green
desc = "A classic green-shaded desk lamp."
icon_state = "lampgreen"
item_state = "lampgreen"
/obj/item/device/flashlight/lamp/verb/toggle_light()
set name = "Toggle light"
set category = "Object"
set src in oview(1)
if(!usr.stat)
attack_self(usr)
//Bananalamp
/obj/item/device/flashlight/lamp/bananalamp
name = "banana lamp"
desc = "Only a clown would think to make a ghetto banana-shaped lamp. Even has a goofy pullstring."
icon_state = "bananalamp"
item_state = "bananalamp"
// FLARES
/obj/item/device/flashlight/flare
name = "flare"
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
w_class = WEIGHT_CLASS_SMALL
brightness_on = 7 // Pretty bright.
icon_state = "flare"
item_state = "flare"
actions_types = list()
var/fuel = 0
var/on_damage = 7
var/produce_heat = 1500
heat = 1000
light_color = LIGHT_COLOR_FLARE
/obj/item/device/flashlight/flare/New()
fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds.
..()
/obj/item/device/flashlight/flare/process()
open_flame(heat)
fuel = max(fuel - 1, 0)
if(!fuel || !on)
turn_off()
if(!fuel)
icon_state = "[initial(icon_state)]-empty"
STOP_PROCESSING(SSobj, src)
/obj/item/device/flashlight/flare/ignition_effect(atom/A, mob/user)
if(fuel && on)
. = "<span class='notice'>[user] lights [A] with [src] like a real \
badass.</span>"
else
. = ""
/obj/item/device/flashlight/flare/proc/turn_off()
on = 0
force = initial(src.force)
damtype = initial(src.damtype)
if(ismob(loc))
var/mob/U = loc
update_brightness(U)
else
update_brightness(null)
/obj/item/device/flashlight/flare/update_brightness(mob/user = null)
..()
if(on)
item_state = "[initial(item_state)]-on"
else
item_state = "[initial(item_state)]"
/obj/item/device/flashlight/flare/attack_self(mob/user)
// Usual checks
if(!fuel)
to_chat(user, "<span class='warning'>[src] is out of fuel!</span>")
return
if(on)
to_chat(user, "<span class='notice'>[src] is already on.</span>")
return
. = ..()
// All good, turn it on.
if(.)
user.visible_message("<span class='notice'>[user] lights \the [src].</span>", "<span class='notice'>You light \the [src]!</span>")
force = on_damage
damtype = "fire"
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/flare/is_hot()
return on * heat
/obj/item/device/flashlight/flare/torch
name = "torch"
desc = "A torch fashioned from some leaves and a log."
w_class = WEIGHT_CLASS_BULKY
brightness_on = 4
icon_state = "torch"
item_state = "torch"
on_damage = 10
slot_flags = null
/obj/item/device/flashlight/lantern
name = "lantern"
icon_state = "lantern"
item_state = "lantern"
desc = "A mining lantern."
brightness_on = 6 // luminosity when on
/obj/item/device/flashlight/slime
gender = PLURAL
name = "glowing slime extract"
desc = "Extract from a yellow slime. It emits a strong light when squeezed."
icon = 'icons/obj/lighting.dmi'
icon_state = "slime"
item_state = "slime"
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
materials = list()
brightness_on = 6 //luminosity when on
/obj/item/device/flashlight/emp
origin_tech = "magnets=3;syndicate=1"
var/emp_max_charges = 4
var/emp_cur_charges = 4
var/charge_tick = 0
/obj/item/device/flashlight/emp/New()
..()
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/emp/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/device/flashlight/emp/process()
charge_tick++
if(charge_tick < 10)
return FALSE
charge_tick = 0
emp_cur_charges = min(emp_cur_charges+1, emp_max_charges)
return TRUE
/obj/item/device/flashlight/emp/attack(mob/living/M, mob/living/user)
if(on && user.zone_selected in list("eyes", "mouth")) // call original attack when examining organs
..()
return
/obj/item/device/flashlight/emp/afterattack(atom/movable/A, mob/user, proximity)
if(!proximity)
return
if(emp_cur_charges > 0)
emp_cur_charges -= 1
if(ismob(A))
var/mob/M = A
add_logs(user, M, "attacked", "EMP-light")
M.visible_message("<span class='danger'>[user] blinks \the [src] at \the [A].", \
"<span class='userdanger'>[user] blinks \the [src] at you.")
else
A.visible_message("<span class='danger'>[user] blinks \the [src] at \the [A].")
to_chat(user, "\The [src] now has [emp_cur_charges] charge\s.")
A.emp_act(1)
else
to_chat(user, "<span class='warning'>\The [src] needs time to recharge!</span>")
return
// Glowsticks, in the uncomfortable range of similar to flares,
// but not similar enough to make it worth a refactor
/obj/item/device/flashlight/glowstick
name = "glowstick"
desc = "A military-grade glowstick."
w_class = WEIGHT_CLASS_SMALL
brightness_on = 4
color = LIGHT_COLOR_GREEN
icon_state = "glowstick"
item_state = "glowstick"
var/fuel = 0
/obj/item/device/flashlight/glowstick/Initialize()
fuel = rand(1600, 2000)
light_color = color
..()
/obj/item/device/flashlight/glowstick/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/device/flashlight/glowstick/process()
fuel = max(fuel - 1, 0)
if(!fuel)
turn_off()
STOP_PROCESSING(SSobj, src)
update_icon()
/obj/item/device/flashlight/glowstick/proc/turn_off()
on = 0
update_icon()
/obj/item/device/flashlight/glowstick/update_icon()
item_state = "glowstick"
overlays.Cut()
if(!fuel)
icon_state = "glowstick-empty"
cut_overlays()
set_light(0)
else if(on)
..()
return
/obj/item/device/flashlight/emp/afterattack(atom/movable/A, mob/user, proximity)
if(!proximity)
return
if(emp_cur_charges > 0)
emp_cur_charges -= 1
if(ismob(A))
var/mob/M = A
add_logs(user, M, "attacked", "EMP-light")
M.visible_message("<span class='danger'>[user] blinks \the [src] at \the [A].", \
"<span class='userdanger'>[user] blinks \the [src] at you.")
else
A.visible_message("<span class='danger'>[user] blinks \the [src] at \the [A].")
to_chat(user, "\The [src] now has [emp_cur_charges] charge\s.")
A.emp_act(1)
else
to_chat(user, "<span class='warning'>\The [src] needs time to recharge!</span>")
return
// Glowsticks, in the uncomfortable range of similar to flares,
// but not similar enough to make it worth a refactor
/obj/item/device/flashlight/glowstick
name = "glowstick"
desc = "A military-grade glowstick."
w_class = WEIGHT_CLASS_SMALL
brightness_on = 4
color = LIGHT_COLOR_GREEN
icon_state = "glowstick"
item_state = "glowstick"
var/fuel = 0
/obj/item/device/flashlight/glowstick/Initialize()
fuel = rand(1600, 2000)
light_color = color
..()
/obj/item/device/flashlight/glowstick/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/device/flashlight/glowstick/process()
fuel = max(fuel - 1, 0)
if(!fuel)
turn_off()
STOP_PROCESSING(SSobj, src)
update_icon()
/obj/item/device/flashlight/glowstick/proc/turn_off()
on = 0
update_icon()
/obj/item/device/flashlight/glowstick/update_icon()
item_state = "glowstick"
overlays.Cut()
if(!fuel)
icon_state = "glowstick-empty"
cut_overlays()
set_light(0)
else if(on)
var/mutable_appearance/glowstick_overlay = mutable_appearance(icon, "glowstick-glow")
glowstick_overlay.color = color
add_overlay(glowstick_overlay)
item_state = "glowstick-on"
set_light(brightness_on)
else
icon_state = "glowstick"
cut_overlays()
/obj/item/device/flashlight/glowstick/attack_self(mob/user)
if(!fuel)
to_chat(user, "<span class='notice'>[src] is spent.</span>")
return
if(on)
to_chat(user, "<span class='notice'>[src] is already lit.</span>")
return
. = ..()
if(.)
user.visible_message("<span class='notice'>[user] cracks and shakes [src].</span>", "<span class='notice'>You crack and shake [src], turning it on!</span>")
activate()
/obj/item/device/flashlight/glowstick/proc/activate()
if(!on)
on = TRUE
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/glowstick/red
name = "red glowstick"
color = LIGHT_COLOR_RED
/obj/item/device/flashlight/glowstick/blue
name = "blue glowstick"
color = LIGHT_COLOR_BLUE
/obj/item/device/flashlight/glowstick/cyan
name = "cyan glowstick"
color = LIGHT_COLOR_CYAN
/obj/item/device/flashlight/glowstick/orange
name = "orange glowstick"
color = LIGHT_COLOR_ORANGE
/obj/item/device/flashlight/glowstick/yellow
name = "yellow glowstick"
color = LIGHT_COLOR_YELLOW
/obj/item/device/flashlight/glowstick/pink
name = "pink glowstick"
color = LIGHT_COLOR_PINK
/obj/item/device/flashlight/glowstick/random
name = "random colored glowstick"
/obj/item/device/flashlight/glowstick/random/Initialize()
var/list/glowtypes = typesof(/obj/item/device/flashlight/glowstick)
glowtypes -= /obj/item/device/flashlight/glowstick/random
var/obj/item/device/flashlight/glowstick/glowtype = pick(glowtypes)
name = initial(glowtype.name)
color = initial(glowtype.color)
. = ..()
/obj/item/device/flashlight/spotlight //invisible lighting source
item_state = "glowstick-on"
set_light(brightness_on)
else
icon_state = "glowstick"
cut_overlays()
/obj/item/device/flashlight/glowstick/attack_self(mob/user)
if(!fuel)
to_chat(user, "<span class='notice'>[src] is spent.</span>")
return
if(on)
to_chat(user, "<span class='notice'>[src] is already lit.</span>")
return
. = ..()
if(.)
user.visible_message("<span class='notice'>[user] cracks and shakes [src].</span>", "<span class='notice'>You crack and shake [src], turning it on!</span>")
activate()
/obj/item/device/flashlight/glowstick/proc/activate()
if(!on)
on = TRUE
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/glowstick/red
name = "red glowstick"
color = LIGHT_COLOR_RED
/obj/item/device/flashlight/glowstick/blue
name = "blue glowstick"
color = LIGHT_COLOR_BLUE
/obj/item/device/flashlight/glowstick/cyan
name = "cyan glowstick"
color = LIGHT_COLOR_CYAN
/obj/item/device/flashlight/glowstick/orange
name = "orange glowstick"
color = LIGHT_COLOR_ORANGE
/obj/item/device/flashlight/glowstick/yellow
name = "yellow glowstick"
color = LIGHT_COLOR_YELLOW
/obj/item/device/flashlight/glowstick/pink
name = "pink glowstick"
color = LIGHT_COLOR_PINK
/obj/item/device/flashlight/glowstick/random
name = "random colored glowstick"
/obj/item/device/flashlight/glowstick/random/Initialize()
var/list/glowtypes = typesof(/obj/item/device/flashlight/glowstick)
glowtypes -= /obj/item/device/flashlight/glowstick/random
var/obj/item/device/flashlight/glowstick/glowtype = pick(glowtypes)
name = initial(glowtype.name)
color = initial(glowtype.color)
. = ..()
/obj/item/device/flashlight/spotlight //invisible lighting source
name = "disco light"
desc = "Groovy..."
icon_state = null
light_color = null
brightness_on = 0
light_range = 0
light_power = 10
alpha = 0
layer = 0
on = TRUE
anchored = TRUE
var/range = null
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
/obj/item/device/flashlight/flashdark
name = "flashdark"
desc = "A strange device manufactured with mysterious elements that somehow emits darkness. Or maybe it just sucks in light? Nobody knows for sure."
icon_state = "flashdark"
item_state = "flashdark"
brightness_on = 2.5
flashlight_power = -3
icon_state = null
light_color = null
brightness_on = 0
light_range = 0
light_power = 10
alpha = 0
layer = 0
on = TRUE
anchored = TRUE
var/range = null
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
/obj/item/device/flashlight/flashdark
name = "flashdark"
desc = "A strange device manufactured with mysterious elements that somehow emits darkness. Or maybe it just sucks in light? Nobody knows for sure."
icon_state = "flashdark"
item_state = "flashdark"
brightness_on = 2.5
flashlight_power = -3
/obj/item/device/flashlight/eyelight
name = "eyelight"
@@ -99,7 +99,7 @@
return !density
/obj/structure/projected_forcefield/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1)
playsound(loc, 'sound/weapons/egloves.ogg', 80, 1)
/obj/structure/projected_forcefield/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
if(sound_effect)
@@ -125,7 +125,7 @@
if(!do_after(user, 40*I.toolspeed, target = user))
return 0
user.visible_message("<span class='notice'>[user] refastens [src]'s maintenance panel!</span>", "<span class='notice'>You reset [src] to its factory settings!</span>")
playsound(user, 'sound/items/Screwdriver2.ogg', 50, 1)
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
emagged = 0
radiation_count = 0
update_icon()
+3 -3
View File
@@ -118,9 +118,8 @@ GLOBAL_LIST_EMPTY(GPS_list)
switch(action)
if("rename")
var/a = input("Please enter desired tag.", name, gpstag) as text
a = uppertext(copytext(sanitize(a), 1, 5))
a = copytext(sanitize(a), 1, 20)
gpstag = a
name = "global positioning system ([gpstag])"
. = TRUE
if("power")
toggletracking(usr)
@@ -136,9 +135,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
..()
if(href_list["tag"] )
var/a = input("Please enter desired tag.", name, gpstag) as text
a = copytext(sanitize(a), 1, 20)
a = uppertext(copytext(sanitize(a), 1, 5))
if(in_range(src, usr))
gpstag = a
name = "global positioning system ([gpstag])"
attack_self(usr)
/obj/item/device/gps/science
@@ -108,7 +108,7 @@
//20% chance to actually hit the sensors
if(prob(effectchance * diode.rating))
S.flash_act(affect_silicon = 1)
S.Weaken(rand(5,10))
S.Knockdown(rand(100,200))
to_chat(S, "<span class='danger'>Your sensors were overloaded by a laser!</span>")
outmsg = "<span class='notice'>You overload [S] by shining [src] at their sensors.</span>"
add_logs(user, S, "shone in the sensors", src)
+139 -139
View File
@@ -1,147 +1,147 @@
/obj/item/device/paicard
name = "personal AI device"
icon = 'icons/obj/aicards.dmi'
icon_state = "pai"
item_state = "electronic"
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
origin_tech = "programming=2"
var/mob/living/silicon/pai/pai
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
/obj/item/device/paicard/Initialize()
SSpai.pai_card_list += src
add_overlay("pai-off")
/obj/item/device/paicard
name = "personal AI device"
icon = 'icons/obj/aicards.dmi'
icon_state = "pai"
item_state = "electronic"
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
origin_tech = "programming=2"
var/mob/living/silicon/pai/pai
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
/obj/item/device/paicard/Initialize()
SSpai.pai_card_list += src
add_overlay("pai-off")
return ..()
/obj/item/device/paicard/Destroy()
//Will stop people throwing friend pAIs into the singularity so they can respawn
SSpai.pai_card_list -= src
/obj/item/device/paicard/Destroy()
//Will stop people throwing friend pAIs into the singularity so they can respawn
SSpai.pai_card_list -= src
QDEL_NULL(pai)
return ..()
/obj/item/device/paicard/attack_self(mob/user)
if (!in_range(src, user))
return
user.set_machine(src)
var/dat = "<TT><B>Personal AI Device</B><BR>"
if(pai)
return ..()
/obj/item/device/paicard/attack_self(mob/user)
if (!in_range(src, user))
return
user.set_machine(src)
var/dat = "<TT><B>Personal AI Device</B><BR>"
if(pai)
if(!pai.master_dna || !pai.master)
dat += "<a href='byond://?src=\ref[src];setdna=1'>Imprint Master DNA</a><br>"
dat += "Installed Personality: [pai.name]<br>"
dat += "Prime directive: <br>[pai.laws.zeroth]<br>"
for(var/slaws in pai.laws.supplied)
dat += "Additional directives: <br>[slaws]<br>"
dat += "<a href='byond://?src=\ref[src];setlaws=1'>Configure Directives</a><br>"
dat += "<br>"
dat += "<h3>Device Settings</h3><br>"
if(pai.radio)
dat += "<b>Radio Uplink</b><br>"
dat += "Transmit: <A href='byond://?src=\ref[src];wires=[WIRE_TX]'>[(pai.radio.wires.is_cut(WIRE_TX)) ? "Disabled" : "Enabled"]</A><br>"
dat += "Receive: <A href='byond://?src=\ref[src];wires=[WIRE_RX]'>[(pai.radio.wires.is_cut(WIRE_RX)) ? "Disabled" : "Enabled"]</A><br>"
else
dat += "<b>Radio Uplink</b><br>"
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.real_name == pai.master || H.dna.unique_enzymes == pai.master_dna)
dat += "<A href='byond://?src=\ref[src];toggle_holo=1'>\[[pai.canholo? "Disable" : "Enable"] holomatrix projectors\]</a><br>"
dat += "<A href='byond://?src=\ref[src];wipe=1'>\[Wipe current pAI personality\]</a><br>"
else
dat += "No personality installed.<br>"
dat += "Searching for a personality... Press view available personalities to notify potential candidates."
dat += "<A href='byond://?src=\ref[src];request=1'>\[View available personalities\]</a><br>"
user << browse(dat, "window=paicard")
onclose(user, "paicard")
return
/obj/item/device/paicard/Topic(href, href_list)
if(!usr || usr.stat)
return
if(href_list["request"])
SSpai.findPAI(src, usr)
if(pai)
if(!(loc == usr))
return
if(href_list["setdna"])
if(pai.master_dna)
return
if(!istype(usr, /mob/living/carbon))
to_chat(usr, "<span class='warning'>You don't have any DNA, or your DNA is incompatible with this device!</span>")
else
var/mob/living/carbon/M = usr
pai.master = M.real_name
pai.master_dna = M.dna.unique_enzymes
to_chat(pai, "<span class='notice'>You have been bound to a new master.</span>")
pai.emittersemicd = FALSE
if(href_list["wipe"])
var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No")
if(confirm == "Yes")
if(pai)
to_chat(pai, "<span class='warning'>You feel yourself slipping away from reality.</span>")
to_chat(pai, "<span class='danger'>Byte by byte you lose your sense of self.</span>")
to_chat(pai, "<span class='userdanger'>Your mental faculties leave you.</span>")
to_chat(pai, "<span class='rose'>oblivion... </span>")
dat += "Installed Personality: [pai.name]<br>"
dat += "Prime directive: <br>[pai.laws.zeroth]<br>"
for(var/slaws in pai.laws.supplied)
dat += "Additional directives: <br>[slaws]<br>"
dat += "<a href='byond://?src=\ref[src];setlaws=1'>Configure Directives</a><br>"
dat += "<br>"
dat += "<h3>Device Settings</h3><br>"
if(pai.radio)
dat += "<b>Radio Uplink</b><br>"
dat += "Transmit: <A href='byond://?src=\ref[src];wires=[WIRE_TX]'>[(pai.radio.wires.is_cut(WIRE_TX)) ? "Disabled" : "Enabled"]</A><br>"
dat += "Receive: <A href='byond://?src=\ref[src];wires=[WIRE_RX]'>[(pai.radio.wires.is_cut(WIRE_RX)) ? "Disabled" : "Enabled"]</A><br>"
else
dat += "<b>Radio Uplink</b><br>"
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.real_name == pai.master || H.dna.unique_enzymes == pai.master_dna)
dat += "<A href='byond://?src=\ref[src];toggle_holo=1'>\[[pai.canholo? "Disable" : "Enable"] holomatrix projectors\]</a><br>"
dat += "<A href='byond://?src=\ref[src];wipe=1'>\[Wipe current pAI personality\]</a><br>"
else
dat += "No personality installed.<br>"
dat += "Searching for a personality... Press view available personalities to notify potential candidates."
dat += "<A href='byond://?src=\ref[src];request=1'>\[View available personalities\]</a><br>"
user << browse(dat, "window=paicard")
onclose(user, "paicard")
return
/obj/item/device/paicard/Topic(href, href_list)
if(!usr || usr.stat)
return
if(href_list["request"])
SSpai.findPAI(src, usr)
if(pai)
if(!(loc == usr))
return
if(href_list["setdna"])
if(pai.master_dna)
return
if(!iscarbon(usr))
to_chat(usr, "<span class='warning'>You don't have any DNA, or your DNA is incompatible with this device!</span>")
else
var/mob/living/carbon/M = usr
pai.master = M.real_name
pai.master_dna = M.dna.unique_enzymes
to_chat(pai, "<span class='notice'>You have been bound to a new master.</span>")
pai.emittersemicd = FALSE
if(href_list["wipe"])
var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No")
if(confirm == "Yes")
if(pai)
to_chat(pai, "<span class='warning'>You feel yourself slipping away from reality.</span>")
to_chat(pai, "<span class='danger'>Byte by byte you lose your sense of self.</span>")
to_chat(pai, "<span class='userdanger'>Your mental faculties leave you.</span>")
to_chat(pai, "<span class='rose'>oblivion... </span>")
removePersonality()
if(href_list["wires"])
var/wire = text2num(href_list["wires"])
if(pai.radio)
pai.radio.wires.cut(wire)
if(href_list["setlaws"])
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN)
if(newlaws && pai)
pai.add_supplied_law(0,newlaws)
if(href_list["toggle_holo"])
if(pai.canholo)
to_chat(pai, "<span class='userdanger'>Your owner has disabled your holomatrix projectors!</span>")
pai.canholo = FALSE
to_chat(usr, "<span class='warning'>You disable your pAI's holomatrix!</span>")
else
to_chat(pai, "<span class='boldnotice'>Your owner has enabled your holomatrix projectors!</span>")
pai.canholo = TRUE
to_chat(usr, "<span class='notice'>You enable your pAI's holomatrix!</span>")
attack_self(usr)
// WIRE_SIGNAL = 1
// WIRE_RECEIVE = 2
// WIRE_TRANSMIT = 4
/obj/item/device/paicard/proc/setPersonality(mob/living/silicon/pai/personality)
src.pai = personality
src.add_overlay("pai-null")
playsound(loc, 'sound/effects/pai_boot.ogg', 50, 1, -1)
audible_message("\The [src] plays a cheerful startup noise!")
/obj/item/device/paicard/proc/removePersonality()
if(href_list["wires"])
var/wire = text2num(href_list["wires"])
if(pai.radio)
pai.radio.wires.cut(wire)
if(href_list["setlaws"])
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN)
if(newlaws && pai)
pai.add_supplied_law(0,newlaws)
if(href_list["toggle_holo"])
if(pai.canholo)
to_chat(pai, "<span class='userdanger'>Your owner has disabled your holomatrix projectors!</span>")
pai.canholo = FALSE
to_chat(usr, "<span class='warning'>You disable your pAI's holomatrix!</span>")
else
to_chat(pai, "<span class='boldnotice'>Your owner has enabled your holomatrix projectors!</span>")
pai.canholo = TRUE
to_chat(usr, "<span class='notice'>You enable your pAI's holomatrix!</span>")
attack_self(usr)
// WIRE_SIGNAL = 1
// WIRE_RECEIVE = 2
// WIRE_TRANSMIT = 4
/obj/item/device/paicard/proc/setPersonality(mob/living/silicon/pai/personality)
src.pai = personality
src.add_overlay("pai-null")
playsound(loc, 'sound/effects/pai_boot.ogg', 50, 1, -1)
audible_message("\The [src] plays a cheerful startup noise!")
/obj/item/device/paicard/proc/removePersonality()
QDEL_NULL(pai)
cut_overlays()
add_overlay("pai-off")
/obj/item/device/paicard/proc/setEmotion(emotion)
if(pai)
src.cut_overlays()
switch(emotion)
if(1) src.add_overlay("pai-happy")
if(2) src.add_overlay("pai-cat")
if(3) src.add_overlay("pai-extremely-happy")
if(4) src.add_overlay("pai-face")
if(5) src.add_overlay("pai-laugh")
if(6) src.add_overlay("pai-off")
if(7) src.add_overlay("pai-sad")
if(8) src.add_overlay("pai-angry")
if(9) src.add_overlay("pai-what")
if(10) src.add_overlay("pai-null")
/obj/item/device/paicard/proc/alertUpdate()
visible_message("<span class ='info'>[src] flashes a message across its screen, \"Additional personalities available for download.\"", "<span class='notice'>[src] bleeps electronically.</span>")
/obj/item/device/paicard/emp_act(severity)
if(pai)
pai.emp_act(severity)
..()
/obj/item/device/paicard/proc/setEmotion(emotion)
if(pai)
src.cut_overlays()
switch(emotion)
if(1) src.add_overlay("pai-happy")
if(2) src.add_overlay("pai-cat")
if(3) src.add_overlay("pai-extremely-happy")
if(4) src.add_overlay("pai-face")
if(5) src.add_overlay("pai-laugh")
if(6) src.add_overlay("pai-off")
if(7) src.add_overlay("pai-sad")
if(8) src.add_overlay("pai-angry")
if(9) src.add_overlay("pai-what")
if(10) src.add_overlay("pai-null")
/obj/item/device/paicard/proc/alertUpdate()
visible_message("<span class ='info'>[src] flashes a message across its screen, \"Additional personalities available for download.\"", "<span class='notice'>[src] bleeps electronically.</span>")
/obj/item/device/paicard/emp_act(severity)
if(pai)
pai.emp_act(severity)
..()
+144 -144
View File
@@ -1,145 +1,145 @@
// Powersink - used to drain station power
/obj/item/device/powersink
desc = "A nulling power sink which drains energy from electrical systems."
name = "power sink"
icon_state = "powersink0"
item_state = "electronic"
w_class = WEIGHT_CLASS_BULKY
flags = CONDUCT
throwforce = 5
throw_speed = 1
throw_range = 2
materials = list(MAT_METAL=750)
origin_tech = "powerstorage=5;syndicate=5"
var/drain_rate = 1600000 // amount of power to drain per tick
var/power_drained = 0 // has drained this much power
var/max_power = 1e10 // maximum power that can be drained before exploding
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
var/admins_warned = 0 // stop spam, only warn the admins once that we are about to boom
var/const/DISCONNECTED = 0
var/const/CLAMPED_OFF = 1
var/const/OPERATING = 2
var/obj/structure/cable/attached // the attached cable
/obj/item/device/powersink/update_icon()
icon_state = "powersink[mode == OPERATING]"
/obj/item/device/powersink/proc/set_mode(value)
if(value == mode)
return
switch(value)
if(DISCONNECTED)
attached = null
if(mode == OPERATING)
STOP_PROCESSING(SSobj, src)
anchored = 0
if(CLAMPED_OFF)
if(!attached)
return
if(mode == OPERATING)
STOP_PROCESSING(SSobj, src)
anchored = 1
if(OPERATING)
if(!attached)
return
START_PROCESSING(SSobj, src)
anchored = 1
mode = value
update_icon()
set_light(0)
/obj/item/device/powersink/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/screwdriver))
if(mode == DISCONNECTED)
var/turf/T = loc
if(isturf(T) && !T.intact)
attached = locate() in T
if(!attached)
to_chat(user, "<span class='warning'>This device must be placed over an exposed, powered cable node!</span>")
else
set_mode(CLAMPED_OFF)
user.visible_message( \
"[user] attaches \the [src] to the cable.", \
"<span class='notice'>You attach \the [src] to the cable.</span>",
"<span class='italics'>You hear some wires being connected to something.</span>")
else
to_chat(user, "<span class='warning'>This device must be placed over an exposed, powered cable node!</span>")
else
set_mode(DISCONNECTED)
user.visible_message( \
"[user] detaches \the [src] from the cable.", \
"<span class='notice'>You detach \the [src] from the cable.</span>",
"<span class='italics'>You hear some wires being disconnected from something.</span>")
else
return ..()
/obj/item/device/powersink/attack_paw()
return
/obj/item/device/powersink/attack_ai()
return
/obj/item/device/powersink/attack_hand(mob/user)
switch(mode)
if(DISCONNECTED)
..()
if(CLAMPED_OFF)
user.visible_message( \
"[user] activates \the [src]!", \
"<span class='notice'>You activate \the [src].</span>",
"<span class='italics'>You hear a click.</span>")
message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_COORDJMP(src)]")
log_game("Power sink activated by [key_name(user)] at [COORD(src)]")
set_mode(OPERATING)
if(OPERATING)
user.visible_message( \
"[user] deactivates \the [src]!", \
"<span class='notice'>You deactivate \the [src].</span>",
"<span class='italics'>You hear a click.</span>")
set_mode(CLAMPED_OFF)
/obj/item/device/powersink/process()
if(!attached)
set_mode(DISCONNECTED)
return
var/datum/powernet/PN = attached.powernet
if(PN)
set_light(5)
// found a powernet, so drain up to max power from it
var/drained = min ( drain_rate, PN.avail )
PN.load += drained
power_drained += drained
// if tried to drain more than available on powernet
// now look for APCs and drain their cells
if(drained < drain_rate)
for(var/obj/machinery/power/terminal/T in PN.nodes)
if(istype(T.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = T.master
if(A.operating && A.cell)
A.cell.charge = max(0, A.cell.charge - 50)
power_drained += 50
if(A.charging == 2) // If the cell was full
A.charging = 1 // It's no longer full
if(power_drained > max_power * 0.98)
if (!admins_warned)
admins_warned = 1
message_admins("Power sink at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>) is 95% full. Explosion imminent.")
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
if(power_drained >= max_power)
STOP_PROCESSING(SSobj, src)
// Powersink - used to drain station power
/obj/item/device/powersink
desc = "A nulling power sink which drains energy from electrical systems."
name = "power sink"
icon_state = "powersink0"
item_state = "electronic"
w_class = WEIGHT_CLASS_BULKY
flags = CONDUCT
throwforce = 5
throw_speed = 1
throw_range = 2
materials = list(MAT_METAL=750)
origin_tech = "powerstorage=5;syndicate=5"
var/drain_rate = 1600000 // amount of power to drain per tick
var/power_drained = 0 // has drained this much power
var/max_power = 1e10 // maximum power that can be drained before exploding
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
var/admins_warned = 0 // stop spam, only warn the admins once that we are about to boom
var/const/DISCONNECTED = 0
var/const/CLAMPED_OFF = 1
var/const/OPERATING = 2
var/obj/structure/cable/attached // the attached cable
/obj/item/device/powersink/update_icon()
icon_state = "powersink[mode == OPERATING]"
/obj/item/device/powersink/proc/set_mode(value)
if(value == mode)
return
switch(value)
if(DISCONNECTED)
attached = null
if(mode == OPERATING)
STOP_PROCESSING(SSobj, src)
anchored = 0
if(CLAMPED_OFF)
if(!attached)
return
if(mode == OPERATING)
STOP_PROCESSING(SSobj, src)
anchored = 1
if(OPERATING)
if(!attached)
return
START_PROCESSING(SSobj, src)
anchored = 1
mode = value
update_icon()
set_light(0)
/obj/item/device/powersink/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/screwdriver))
if(mode == DISCONNECTED)
var/turf/T = loc
if(isturf(T) && !T.intact)
attached = locate() in T
if(!attached)
to_chat(user, "<span class='warning'>This device must be placed over an exposed, powered cable node!</span>")
else
set_mode(CLAMPED_OFF)
user.visible_message( \
"[user] attaches \the [src] to the cable.", \
"<span class='notice'>You attach \the [src] to the cable.</span>",
"<span class='italics'>You hear some wires being connected to something.</span>")
else
to_chat(user, "<span class='warning'>This device must be placed over an exposed, powered cable node!</span>")
else
set_mode(DISCONNECTED)
user.visible_message( \
"[user] detaches \the [src] from the cable.", \
"<span class='notice'>You detach \the [src] from the cable.</span>",
"<span class='italics'>You hear some wires being disconnected from something.</span>")
else
return ..()
/obj/item/device/powersink/attack_paw()
return
/obj/item/device/powersink/attack_ai()
return
/obj/item/device/powersink/attack_hand(mob/user)
switch(mode)
if(DISCONNECTED)
..()
if(CLAMPED_OFF)
user.visible_message( \
"[user] activates \the [src]!", \
"<span class='notice'>You activate \the [src].</span>",
"<span class='italics'>You hear a click.</span>")
message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_COORDJMP(src)]")
log_game("Power sink activated by [key_name(user)] at [COORD(src)]")
set_mode(OPERATING)
if(OPERATING)
user.visible_message( \
"[user] deactivates \the [src]!", \
"<span class='notice'>You deactivate \the [src].</span>",
"<span class='italics'>You hear a click.</span>")
set_mode(CLAMPED_OFF)
/obj/item/device/powersink/process()
if(!attached)
set_mode(DISCONNECTED)
return
var/datum/powernet/PN = attached.powernet
if(PN)
set_light(5)
// found a powernet, so drain up to max power from it
var/drained = min ( drain_rate, PN.avail )
PN.load += drained
power_drained += drained
// if tried to drain more than available on powernet
// now look for APCs and drain their cells
if(drained < drain_rate)
for(var/obj/machinery/power/terminal/T in PN.nodes)
if(istype(T.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = T.master
if(A.operating && A.cell)
A.cell.charge = max(0, A.cell.charge - 50)
power_drained += 50
if(A.charging == 2) // If the cell was full
A.charging = 1 // It's no longer full
if(power_drained > max_power * 0.98)
if (!admins_warned)
admins_warned = 1
message_admins("Power sink at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>) is 95% full. Explosion imminent.")
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
if(power_drained >= max_power)
STOP_PROCESSING(SSobj, src)
explosion(src.loc, 4,8,16,32)
qdel(src)
qdel(src)
@@ -27,7 +27,7 @@
sigdev = new
sigdev.code = roundstart_signaller_code
sigdev.frequency = roundstart_signaller_freq
if(istype(loc, /turf/open))
if(isopenturf(loc))
hide(TRUE)
/obj/item/device/pressure_plate/Crossed(atom/movable/AM)
+39 -39
View File
@@ -1,41 +1,41 @@
/obj/item/device/radio/beacon
name = "tracking beacon"
desc = "A beacon used by a teleporter."
icon_state = "beacon"
item_state = "beacon"
var/code = "electronic"
origin_tech = "bluespace=1"
dog_fashion = null
/obj/item/device/radio/beacon
name = "tracking beacon"
desc = "A beacon used by a teleporter."
icon_state = "beacon"
item_state = "beacon"
var/code = "electronic"
origin_tech = "bluespace=1"
dog_fashion = null
/obj/item/device/radio/beacon/Initialize()
. = ..()
GLOB.teleportbeacons += src
/obj/item/device/radio/beacon/Destroy()
GLOB.teleportbeacons.Remove(src)
return ..()
/obj/item/device/radio/beacon/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
return
/obj/item/device/radio/beacon/send_hear()
return null
/obj/item/device/radio/beacon/verb/alter_signal(t as text)
set name = "Alter Beacon's Signal"
set category = "Object"
set src in usr
if ((usr.canmove && !( usr.restrained() )))
src.code = t
if (!( src.code ))
src.code = "beacon"
src.add_fingerprint(usr)
return
/*
//Probably a better way of doing this, I'm lazy.
/obj/item/device/radio/beacon/bacon/proc/digest_delay()
spawn(600)
qdel(src)*/ //Bacon beacons are no more rip in peace
GLOB.teleportbeacons += src
/obj/item/device/radio/beacon/Destroy()
GLOB.teleportbeacons.Remove(src)
return ..()
/obj/item/device/radio/beacon/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
return
/obj/item/device/radio/beacon/send_hear()
return null
/obj/item/device/radio/beacon/verb/alter_signal(t as text)
set name = "Alter Beacon's Signal"
set category = "Object"
set src in usr
if ((usr.canmove && !( usr.restrained() )))
src.code = t
if (!( src.code ))
src.code = "beacon"
src.add_fingerprint(usr)
return
/*
//Probably a better way of doing this, I'm lazy.
/obj/item/device/radio/beacon/bacon/proc/digest_delay()
spawn(600)
qdel(src)*/ //Bacon beacons are no more rip in peace
@@ -78,14 +78,14 @@
on = !( on )
icon_state = "electropack[on]"
if(!( master ))
if(istype(loc, /mob))
if(ismob(loc))
attack_self(loc)
else
for(var/mob/M in viewers(1, src))
if(M.client)
attack_self(M)
else
if(istype(master.loc, /mob))
if(ismob(master.loc))
attack_self(master.loc)
else
for(var/mob/M in viewers(1, master))
@@ -100,21 +100,21 @@
if(!signal || signal.encryption != code)
return
if(ismob(loc) && on)
if(isliving(loc) && on)
if(shock_cooldown != 0)
return
shock_cooldown = 1
spawn(100)
shock_cooldown = 0
var/mob/M = loc
step(M, pick(GLOB.cardinal))
var/mob/living/L = loc
step(L, pick(GLOB.cardinal))
to_chat(M, "<span class='danger'>You feel a sharp shock!</span>")
to_chat(L, "<span class='danger'>You feel a sharp shock!</span>")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, M)
s.set_up(3, 1, L)
s.start()
M.Weaken(5)
L.Knockdown(100)
if(master)
master.receive_signal()
+300 -300
View File
@@ -1,309 +1,309 @@
/obj/item/device/radio/headset
name = "radio headset"
desc = "An updated, modular intercom that fits over the head. Takes encryption keys. \nTo speak on the general radio frequency, use ; before speaking."
icon_state = "headset"
item_state = "headset"
materials = list(MAT_METAL=75)
subspace_transmission = 1
canhear_range = 0 // can't hear headsets from very far away
slot_flags = SLOT_EARS
var/obj/item/device/encryptionkey/keyslot2 = null
dog_fashion = null
/obj/item/device/radio/headset
name = "radio headset"
desc = "An updated, modular intercom that fits over the head. Takes encryption keys. \nTo speak on the general radio frequency, use ; before speaking."
icon_state = "headset"
item_state = "headset"
materials = list(MAT_METAL=75)
subspace_transmission = 1
canhear_range = 0 // can't hear headsets from very far away
slot_flags = SLOT_EARS
var/obj/item/device/encryptionkey/keyslot2 = null
dog_fashion = null
/obj/item/device/radio/headset/Initialize()
. = ..()
recalculateChannels()
/obj/item/device/radio/headset/Destroy()
qdel(keyslot)
qdel(keyslot2)
keyslot = null
keyslot2 = null
return ..()
/obj/item/device/radio/headset/talk_into(mob/living/M, message, channel, list/spans,datum/language/language)
if (!listening)
return ITALICS | REDUCE_RANGE
return ..()
/obj/item/device/radio/headset/receive_range(freq, level, AIuser)
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(H.ears == src)
return ..(freq, level)
else if(AIuser)
return ..(freq, level)
return -1
/obj/item/device/radio/headset/syndicate //disguised to look like a normal headset for stealth ops
origin_tech = "syndicate=3"
/obj/item/device/radio/headset/syndicate/alt //undisguised bowman with flash protection
name = "syndicate headset"
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking."
origin_tech = "syndicate=3"
icon_state = "syndie_headset"
item_state = "syndie_headset"
/obj/item/device/radio/headset/syndicate/alt/Initialize(mapload)
recalculateChannels()
/obj/item/device/radio/headset/Destroy()
qdel(keyslot)
qdel(keyslot2)
keyslot = null
keyslot2 = null
return ..()
/obj/item/device/radio/headset/talk_into(mob/living/M, message, channel, list/spans,datum/language/language)
if (!listening)
return ITALICS | REDUCE_RANGE
return ..()
/obj/item/device/radio/headset/receive_range(freq, level, AIuser)
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(H.ears == src)
return ..(freq, level)
else if(AIuser)
return ..(freq, level)
return -1
/obj/item/device/radio/headset/syndicate //disguised to look like a normal headset for stealth ops
origin_tech = "syndicate=3"
/obj/item/device/radio/headset/syndicate/alt //undisguised bowman with flash protection
name = "syndicate headset"
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking."
origin_tech = "syndicate=3"
icon_state = "syndie_headset"
item_state = "syndie_headset"
/obj/item/device/radio/headset/syndicate/alt/Initialize(mapload)
. = ..()
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/syndicate/alt/leader
name = "team leader headset"
command = TRUE
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/syndicate/alt/leader
name = "team leader headset"
command = TRUE
/obj/item/device/radio/headset/syndicate/Initialize()
. = ..()
make_syndie()
/obj/item/device/radio/headset/binary
origin_tech = "syndicate=3"
make_syndie()
/obj/item/device/radio/headset/binary
origin_tech = "syndicate=3"
/obj/item/device/radio/headset/binary/Initialize()
. = ..()
qdel(keyslot)
keyslot = new /obj/item/device/encryptionkey/binary
recalculateChannels()
/obj/item/device/radio/headset/headset_sec
name = "security radio headset"
desc = "This is used by your elite security force. \nTo access the security channel, use :s."
icon_state = "sec_headset"
keyslot = new /obj/item/device/encryptionkey/headset_sec
/obj/item/device/radio/headset/headset_sec/alt
name = "security bowman headset"
desc = "This is used by your elite security force. Protects ears from flashbangs. \nTo access the security channel, use :s."
icon_state = "sec_headset_alt"
item_state = "sec_headset_alt"
/obj/item/device/radio/headset/headset_sec/alt/Initialize(mapload)
qdel(keyslot)
keyslot = new /obj/item/device/encryptionkey/binary
recalculateChannels()
/obj/item/device/radio/headset/headset_sec
name = "security radio headset"
desc = "This is used by your elite security force. \nTo access the security channel, use :s."
icon_state = "sec_headset"
keyslot = new /obj/item/device/encryptionkey/headset_sec
/obj/item/device/radio/headset/headset_sec/alt
name = "security bowman headset"
desc = "This is used by your elite security force. Protects ears from flashbangs. \nTo access the security channel, use :s."
icon_state = "sec_headset_alt"
item_state = "sec_headset_alt"
/obj/item/device/radio/headset/headset_sec/alt/Initialize(mapload)
. = ..()
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/headset_eng
name = "engineering radio headset"
desc = "When the engineers wish to chat like girls. \nTo access the engineering channel, use :e. "
icon_state = "eng_headset"
keyslot = new /obj/item/device/encryptionkey/headset_eng
/obj/item/device/radio/headset/headset_rob
name = "robotics radio headset"
desc = "Made specifically for the roboticists, who cannot decide between departments. \nTo access the engineering channel, use :e. For research, use :n."
icon_state = "rob_headset"
keyslot = new /obj/item/device/encryptionkey/headset_rob
/obj/item/device/radio/headset/headset_med
name = "medical radio headset"
desc = "A headset for the trained staff of the medbay. \nTo access the medical channel, use :m."
icon_state = "med_headset"
keyslot = new /obj/item/device/encryptionkey/headset_med
/obj/item/device/radio/headset/headset_sci
name = "science radio headset"
desc = "A sciency headset. Like usual. \nTo access the science channel, use :n."
icon_state = "sci_headset"
keyslot = new /obj/item/device/encryptionkey/headset_sci
/obj/item/device/radio/headset/headset_medsci
name = "medical research radio headset"
desc = "A headset that is a result of the mating between medical and science. \nTo access the medical channel, use :m. For science, use :n."
icon_state = "medsci_headset"
keyslot = new /obj/item/device/encryptionkey/headset_medsci
/obj/item/device/radio/headset/headset_com
name = "command radio headset"
desc = "A headset with a commanding channel. \nTo access the command channel, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/headset_com
/obj/item/device/radio/headset/heads
command = TRUE
/obj/item/device/radio/headset/heads/captain
name = "\proper the captain's headset"
desc = "The headset of the king. \nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/heads/captain/alt
name = "\proper the captain's bowman headset"
desc = "The headset of the boss. Protects ears from flashbangs. \nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
/obj/item/device/radio/headset/heads/captain/alt/Initialize(mapload)
. = ..()
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/heads/rd
name = "\proper the research director's headset"
desc = "Headset of the fellow who keeps society marching towards technological singularity. \nTo access the science channel, use :n. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/rd
/obj/item/device/radio/headset/heads/hos
name = "\proper the head of security's headset"
desc = "The headset of the man in charge of keeping order and protecting the station. \nTo access the security channel, use :s. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/heads/hos/alt
name = "\proper the head of security's bowman headset"
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs. \nTo access the security channel, use :s. For command, use :c."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
/obj/item/device/radio/headset/heads/hos/alt/Initialize(mapload)
. = ..()
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/heads/ce
name = "\proper the chief engineer's headset"
desc = "The headset of the guy in charge of keeping the station powered and undamaged. \nTo access the engineering channel, use :e. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/ce
/obj/item/device/radio/headset/heads/cmo
name = "\proper the chief medical officer's headset"
desc = "The headset of the highly trained medical chief. \nTo access the medical channel, use :m. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/cmo
/obj/item/device/radio/headset/heads/hop
name = "\proper the head of personnel's headset"
desc = "The headset of the guy who will one day be captain. \nChannels are as follows: :u - supply, :v - service, :c - command."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/hop
/obj/item/device/radio/headset/headset_cargo
name = "supply radio headset"
desc = "A headset used by the QM and his slaves. \nTo access the supply channel, use :u."
icon_state = "cargo_headset"
keyslot = new /obj/item/device/encryptionkey/headset_cargo
/obj/item/device/radio/headset/headset_cargo/mining
name = "mining radio headset"
desc = "Headset used by shaft miners. \nTo access the supply channel, use :u. For science, use :n."
icon_state = "mine_headset"
keyslot = new /obj/item/device/encryptionkey/headset_mining
/obj/item/device/radio/headset/headset_srv
name = "service radio headset"
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean. \nTo access the service channel, use :v."
icon_state = "srv_headset"
keyslot = new /obj/item/device/encryptionkey/headset_service
/obj/item/device/radio/headset/headset_cent
name = "\improper Centcom headset"
desc = "A headset used by the upper echelons of Nanotrasen. \nTo access the centcom channel, use :y."
icon_state = "cent_headset"
keyslot = new /obj/item/device/encryptionkey/headset_com
keyslot2 = new /obj/item/device/encryptionkey/headset_cent
/obj/item/device/radio/headset/headset_cent/commander
keyslot = new /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/headset_cent/alt
name = "\improper Centcom bowman headset"
desc = "A headset especially for emergency response personnel. Protects ears from flashbangs. \nTo access the centcom channel, use :y."
icon_state = "cent_headset_alt"
item_state = "cent_headset_alt"
keyslot = null
/obj/item/device/radio/headset/headset_cent/alt/Initialize(mapload)
. = ..()
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/ai
name = "\proper Integrated Subspace Transceiver "
keyslot2 = new /obj/item/device/encryptionkey/ai
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/headset_eng
name = "engineering radio headset"
desc = "When the engineers wish to chat like girls. \nTo access the engineering channel, use :e. "
icon_state = "eng_headset"
keyslot = new /obj/item/device/encryptionkey/headset_eng
/obj/item/device/radio/headset/headset_rob
name = "robotics radio headset"
desc = "Made specifically for the roboticists, who cannot decide between departments. \nTo access the engineering channel, use :e. For research, use :n."
icon_state = "rob_headset"
keyslot = new /obj/item/device/encryptionkey/headset_rob
/obj/item/device/radio/headset/headset_med
name = "medical radio headset"
desc = "A headset for the trained staff of the medbay. \nTo access the medical channel, use :m."
icon_state = "med_headset"
keyslot = new /obj/item/device/encryptionkey/headset_med
/obj/item/device/radio/headset/headset_sci
name = "science radio headset"
desc = "A sciency headset. Like usual. \nTo access the science channel, use :n."
icon_state = "sci_headset"
keyslot = new /obj/item/device/encryptionkey/headset_sci
/obj/item/device/radio/headset/headset_medsci
name = "medical research radio headset"
desc = "A headset that is a result of the mating between medical and science. \nTo access the medical channel, use :m. For science, use :n."
icon_state = "medsci_headset"
keyslot = new /obj/item/device/encryptionkey/headset_medsci
/obj/item/device/radio/headset/headset_com
name = "command radio headset"
desc = "A headset with a commanding channel. \nTo access the command channel, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/headset_com
/obj/item/device/radio/headset/heads
command = TRUE
/obj/item/device/radio/headset/ai/receive_range(freq, level)
return ..(freq, level, 1)
/obj/item/device/radio/headset/attackby(obj/item/weapon/W, mob/user, params)
user.set_machine(src)
if(istype(W, /obj/item/weapon/screwdriver))
if(keyslot || keyslot2)
for(var/ch_name in channels)
SSradio.remove_object(src, GLOB.radiochannels[ch_name])
secure_radio_connections[ch_name] = null
if(keyslot)
var/turf/T = get_turf(user)
if(T)
keyslot.loc = T
keyslot = null
if(keyslot2)
var/turf/T = get_turf(user)
if(T)
keyslot2.loc = T
keyslot2 = null
recalculateChannels()
to_chat(user, "<span class='notice'>You pop out the encryption keys in the headset.</span>")
else
to_chat(user, "<span class='warning'>This headset doesn't have any unique encryption keys! How useless...</span>")
else if(istype(W, /obj/item/device/encryptionkey/))
if(keyslot && keyslot2)
to_chat(user, "<span class='warning'>The headset can't hold another key!</span>")
return
if(!keyslot)
if(!user.transferItemToLoc(W, src))
return
keyslot = W
else
if(!user.transferItemToLoc(W, src))
return
keyslot2 = W
recalculateChannels()
else
return ..()
/obj/item/device/radio/headset/recalculateChannels()
..()
if(keyslot2)
for(var/ch_name in keyslot2.channels)
if(ch_name in src.channels)
continue
src.channels += ch_name
src.channels[ch_name] = keyslot2.channels[ch_name]
if(keyslot2.translate_binary)
src.translate_binary = 1
if(keyslot2.syndie)
src.syndie = 1
if (keyslot2.independent)
independent = TRUE
for(var/ch_name in channels)
secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name])
return
/obj/item/device/radio/headset/AltClick(mob/living/user)
if(!istype(user) || !Adjacent(user) || user.incapacitated())
return
if (command)
use_command = !use_command
to_chat(user, "<span class='notice'>You toggle high-volume mode [use_command ? "on" : "off"].</span>")
/obj/item/device/radio/headset/heads/captain
name = "\proper the captain's headset"
desc = "The headset of the king. \nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/heads/captain/alt
name = "\proper the captain's bowman headset"
desc = "The headset of the boss. Protects ears from flashbangs. \nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
/obj/item/device/radio/headset/heads/captain/alt/Initialize(mapload)
. = ..()
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/heads/rd
name = "\proper the research director's headset"
desc = "Headset of the fellow who keeps society marching towards technological singularity. \nTo access the science channel, use :n. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/rd
/obj/item/device/radio/headset/heads/hos
name = "\proper the head of security's headset"
desc = "The headset of the man in charge of keeping order and protecting the station. \nTo access the security channel, use :s. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/heads/hos/alt
name = "\proper the head of security's bowman headset"
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs. \nTo access the security channel, use :s. For command, use :c."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
/obj/item/device/radio/headset/heads/hos/alt/Initialize(mapload)
. = ..()
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/heads/ce
name = "\proper the chief engineer's headset"
desc = "The headset of the guy in charge of keeping the station powered and undamaged. \nTo access the engineering channel, use :e. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/ce
/obj/item/device/radio/headset/heads/cmo
name = "\proper the chief medical officer's headset"
desc = "The headset of the highly trained medical chief. \nTo access the medical channel, use :m. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/cmo
/obj/item/device/radio/headset/heads/hop
name = "\proper the head of personnel's headset"
desc = "The headset of the guy who will one day be captain. \nChannels are as follows: :u - supply, :v - service, :c - command."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/hop
/obj/item/device/radio/headset/headset_cargo
name = "supply radio headset"
desc = "A headset used by the QM and his slaves. \nTo access the supply channel, use :u."
icon_state = "cargo_headset"
keyslot = new /obj/item/device/encryptionkey/headset_cargo
/obj/item/device/radio/headset/headset_cargo/mining
name = "mining radio headset"
desc = "Headset used by shaft miners. \nTo access the supply channel, use :u. For science, use :n."
icon_state = "mine_headset"
keyslot = new /obj/item/device/encryptionkey/headset_mining
/obj/item/device/radio/headset/headset_srv
name = "service radio headset"
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean. \nTo access the service channel, use :v."
icon_state = "srv_headset"
keyslot = new /obj/item/device/encryptionkey/headset_service
/obj/item/device/radio/headset/headset_cent
name = "\improper Centcom headset"
desc = "A headset used by the upper echelons of Nanotrasen. \nTo access the centcom channel, use :y."
icon_state = "cent_headset"
keyslot = new /obj/item/device/encryptionkey/headset_com
keyslot2 = new /obj/item/device/encryptionkey/headset_cent
/obj/item/device/radio/headset/headset_cent/commander
keyslot = new /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/headset_cent/alt
name = "\improper Centcom bowman headset"
desc = "A headset especially for emergency response personnel. Protects ears from flashbangs. \nTo access the centcom channel, use :y."
icon_state = "cent_headset_alt"
item_state = "cent_headset_alt"
keyslot = null
/obj/item/device/radio/headset/headset_cent/alt/Initialize(mapload)
. = ..()
SET_SECONDARY_FLAG(src, BANG_PROTECT)
/obj/item/device/radio/headset/ai
name = "\proper Integrated Subspace Transceiver "
keyslot2 = new /obj/item/device/encryptionkey/ai
command = TRUE
/obj/item/device/radio/headset/ai/receive_range(freq, level)
return ..(freq, level, 1)
/obj/item/device/radio/headset/attackby(obj/item/weapon/W, mob/user, params)
user.set_machine(src)
if(istype(W, /obj/item/weapon/screwdriver))
if(keyslot || keyslot2)
for(var/ch_name in channels)
SSradio.remove_object(src, GLOB.radiochannels[ch_name])
secure_radio_connections[ch_name] = null
if(keyslot)
var/turf/T = get_turf(user)
if(T)
keyslot.loc = T
keyslot = null
if(keyslot2)
var/turf/T = get_turf(user)
if(T)
keyslot2.loc = T
keyslot2 = null
recalculateChannels()
to_chat(user, "<span class='notice'>You pop out the encryption keys in the headset.</span>")
else
to_chat(user, "<span class='warning'>This headset doesn't have any unique encryption keys! How useless...</span>")
else if(istype(W, /obj/item/device/encryptionkey/))
if(keyslot && keyslot2)
to_chat(user, "<span class='warning'>The headset can't hold another key!</span>")
return
if(!keyslot)
if(!user.transferItemToLoc(W, src))
return
keyslot = W
else
if(!user.transferItemToLoc(W, src))
return
keyslot2 = W
recalculateChannels()
else
return ..()
/obj/item/device/radio/headset/recalculateChannels()
..()
if(keyslot2)
for(var/ch_name in keyslot2.channels)
if(ch_name in src.channels)
continue
src.channels += ch_name
src.channels[ch_name] = keyslot2.channels[ch_name]
if(keyslot2.translate_binary)
src.translate_binary = 1
if(keyslot2.syndie)
src.syndie = 1
if (keyslot2.independent)
independent = TRUE
for(var/ch_name in channels)
secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name])
return
/obj/item/device/radio/headset/AltClick(mob/living/user)
if(!istype(user) || !Adjacent(user) || user.incapacitated())
return
if (command)
use_command = !use_command
to_chat(user, "<span class='notice'>You toggle high-volume mode [use_command ? "on" : "off"].</span>")
@@ -1,30 +1,30 @@
/obj/item/device/radio/intercom
name = "station intercom"
desc = "Talk through this."
icon_state = "intercom"
anchored = 1
w_class = WEIGHT_CLASS_BULKY
canhear_range = 2
var/number = 0
var/anyai = 1
var/mob/living/silicon/ai/ai = list()
var/last_tick //used to delay the powercheck
dog_fashion = null
/obj/item/device/radio/intercom
name = "station intercom"
desc = "Talk through this."
icon_state = "intercom"
anchored = 1
w_class = WEIGHT_CLASS_BULKY
canhear_range = 2
var/number = 0
var/anyai = 1
var/mob/living/silicon/ai/ai = list()
var/last_tick //used to delay the powercheck
dog_fashion = null
var/unfastened = FALSE
/obj/item/device/radio/intercom/unscrewed
unfastened = TRUE
/obj/item/device/radio/intercom/Initialize(mapload, ndir, building)
. = ..()
if(building)
setDir(ndir)
START_PROCESSING(SSobj, src)
/obj/item/device/radio/intercom/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
START_PROCESSING(SSobj, src)
/obj/item/device/radio/intercom/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/device/radio/intercom/examine(mob/user)
..()
if(!unfastened)
@@ -68,56 +68,56 @@
return
return ..()
/obj/item/device/radio/intercom/attack_ai(mob/user)
interact(user)
/obj/item/device/radio/intercom/attack_hand(mob/user)
interact(user)
/obj/item/device/radio/intercom/interact(mob/user)
..()
ui_interact(user, state = GLOB.default_state)
/obj/item/device/radio/intercom/receive_range(freq, level)
if(!on)
return -1
if(wires.is_cut(WIRE_RX))
return -1
if(!(0 in level))
var/turf/position = get_turf(src)
if(isnull(position) || !(position.z in level))
return -1
if(!src.listening)
return -1
if(freq == GLOB.SYND_FREQ)
if(!(src.syndie))
return -1//Prevents broadcast of messages over devices lacking the encryption
return canhear_range
/obj/item/device/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
if(!anyai && !(speaker in ai))
return
..()
/obj/item/device/radio/intercom/process()
if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
last_tick = world.timeofday
var/area/A = get_area(src)
if(!A || emped)
on = 0
else
on = A.powered(EQUIP) // set "on" to the power status
if(!on)
icon_state = "intercom-p"
else
icon_state = "intercom"
/obj/item/device/radio/intercom/add_blood(list/blood_dna)
return 0
/obj/item/device/radio/intercom/attack_ai(mob/user)
interact(user)
/obj/item/device/radio/intercom/attack_hand(mob/user)
interact(user)
/obj/item/device/radio/intercom/interact(mob/user)
..()
ui_interact(user, state = GLOB.default_state)
/obj/item/device/radio/intercom/receive_range(freq, level)
if(!on)
return -1
if(wires.is_cut(WIRE_RX))
return -1
if(!(0 in level))
var/turf/position = get_turf(src)
if(isnull(position) || !(position.z in level))
return -1
if(!src.listening)
return -1
if(freq == GLOB.SYND_FREQ)
if(!(src.syndie))
return -1//Prevents broadcast of messages over devices lacking the encryption
return canhear_range
/obj/item/device/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
if(!anyai && !(speaker in ai))
return
..()
/obj/item/device/radio/intercom/process()
if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
last_tick = world.timeofday
var/area/A = get_area(src)
if(!A || emped)
on = 0
else
on = A.powered(EQUIP) // set "on" to the power status
if(!on)
icon_state = "intercom-p"
else
icon_state = "intercom"
/obj/item/device/radio/intercom/add_blood(list/blood_dna)
return 0
//Created through the autolathe or through deconstructing intercoms. Can be applied to wall to make a new intercom on it!
/obj/item/wallframe/intercom
@@ -293,7 +293,6 @@
// --- Cold, emotionless machines. ---
else if(isobj(M))
jobname = "Machine"
voice = capitalize(voice)
// --- Unidentifiable mob ---
else
@@ -597,4 +596,4 @@
/obj/item/device/radio/off // Station bounced radios, their only difference is spawning with the speakers off, this was made to help the lag.
listening = 0 // And it's nice to have a subtype too for future features.
dog_fashion = /datum/dog_fashion/back
dog_fashion = /datum/dog_fashion/back
+407 -412
View File
@@ -1,33 +1,33 @@
/*
CONTAINS:
T-RAY
DETECTIVE SCANNER
HEALTH ANALYZER
GAS ANALYZER
MASS SPECTROMETER
*/
/obj/item/device/t_scanner
name = "\improper T-ray scanner"
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
icon_state = "t-ray0"
var/on = 0
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
materials = list(MAT_METAL=150)
origin_tech = "magnets=1;engineering=1"
/obj/item/device/t_scanner/attack_self(mob/user)
on = !on
icon_state = copytext(icon_state, 1, length(icon_state))+"[on]"
if(on)
START_PROCESSING(SSobj, src)
/obj/item/device/t_scanner/proc/flick_sonar(obj/pipe)
/*
CONTAINS:
T-RAY
DETECTIVE SCANNER
HEALTH ANALYZER
GAS ANALYZER
MASS SPECTROMETER
*/
/obj/item/device/t_scanner
name = "\improper T-ray scanner"
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
icon_state = "t-ray0"
var/on = 0
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
materials = list(MAT_METAL=150)
origin_tech = "magnets=1;engineering=1"
/obj/item/device/t_scanner/attack_self(mob/user)
on = !on
icon_state = copytext(icon_state, 1, length(icon_state))+"[on]"
if(on)
START_PROCESSING(SSobj, src)
/obj/item/device/t_scanner/proc/flick_sonar(obj/pipe)
if(ismob(loc))
var/mob/M = loc
var/image/I = new(loc = get_turf(pipe))
@@ -36,386 +36,381 @@ MASS SPECTROMETER
I.appearance = MA
if(M.client)
flick_overlay(I, list(M.client), 8)
/obj/item/device/t_scanner/process()
if(!on)
STOP_PROCESSING(SSobj, src)
return null
scan()
/obj/item/device/t_scanner/proc/scan()
for(var/turf/T in range(2, src.loc) )
for(var/obj/O in T.contents)
if(O.level != 1)
continue
if(O.invisibility == INVISIBILITY_MAXIMUM)
/obj/item/device/t_scanner/process()
if(!on)
STOP_PROCESSING(SSobj, src)
return null
scan()
/obj/item/device/t_scanner/proc/scan()
for(var/turf/T in range(2, src.loc) )
for(var/obj/O in T.contents)
if(O.level != 1)
continue
if(O.invisibility == INVISIBILITY_MAXIMUM)
flick_sonar(O)
/obj/item/device/healthanalyzer
name = "health analyzer"
icon_state = "health"
item_state = "analyzer"
desc = "A hand-held body scanner able to distinguish vital signs of the subject."
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
throwforce = 3
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=200)
origin_tech = "magnets=1;biotech=1"
var/mode = 1
var/scanmode = 0
/obj/item/device/healthanalyzer/attack_self(mob/user)
if(!scanmode)
to_chat(user, "<span class='notice'>You switch the health analyzer to scan chemical contents.</span>")
scanmode = 1
else
to_chat(user, "<span class='notice'>You switch the health analyzer to check physical health.</span>")
scanmode = 0
/obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user)
// Clumsiness/brain damage check
if ((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50))
to_chat(user, "<span class='notice'>You stupidly try to analyze the floor's vitals!</span>")
user.visible_message("<span class='warning'>[user] has analyzed the floor's vitals!</span>")
to_chat(user, "<span class='info'>Analyzing results for The floor:\n\tOverall status: <b>Healthy</b>")
to_chat(user, "<span class='info'>Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FF8000'>Burn</font>/<font color='red'>Brute</font></span>")
to_chat(user, "<span class='info'>\tDamage specifics: <font color='blue'>0</font>-<font color='green'>0</font>-<font color='#FF8000'>0</font>-<font color='red'>0</font></span>")
to_chat(user, "<span class='info'>Body temperature: ???</span>")
return
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>")
if(scanmode == 0)
healthscan(user, M, mode)
else if(scanmode == 1)
chemscan(user, M)
add_fingerprint(user)
// Used by the PDA medical scanner too
/proc/healthscan(mob/living/user, mob/living/M, mode = 1)
if(user.incapacitated() || user.eye_blind)
return
//Damage specifics
var/oxy_loss = M.getOxyLoss()
var/tox_loss = M.getToxLoss()
var/fire_loss = M.getFireLoss()
var/brute_loss = M.getBruteLoss()
var/mob_status = (M.stat > 1 ? "<span class='alert'><b>Deceased</b></span>" : "<b>[round(M.health/M.maxHealth,0.01)*100] % healthy</b>")
if(M.status_flags & FAKEDEATH)
mob_status = "<span class='alert'>Deceased</span>"
oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.undergoing_cardiac_arrest() && H.stat != DEAD)
to_chat(user, "<span class='danger'>Subject suffering from heart attack: Apply defibrillator immediately!</span>")
if(iscarbon(M))
var/mob/living/carbon/C = M
if(C.has_brain_worms())
to_chat(user, "<span class='danger'>Foreign organism detected in subject's cranium. Recommended treatment: Dosage of sucrose solution and removal of object via surgery.</span>")
to_chat(user, "<span class='info'>Analyzing results for [M]:\n\tOverall status: [mob_status]</span>")
// Damage descriptions
if(brute_loss > 10)
to_chat(user, "\t<span class='alert'>[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected.</span>")
if(fire_loss > 10)
to_chat(user, "\t<span class='alert'>[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected.</span>")
if(oxy_loss > 10)
to_chat(user, "\t<span class='info'><span class='alert'>[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.</span>")
if(tox_loss > 10)
to_chat(user, "\t<span class='alert'>[tox_loss > 50 ? "Critical" : "Dangerous"] amount of toxins detected.</span>")
if(M.getStaminaLoss())
to_chat(user, "\t<span class='alert'>Subject appears to be suffering from fatigue.</span>")
if (M.getCloneLoss())
to_chat(user, "\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.</span>")
if (M.reagents && M.reagents.get_reagent_amount("epinephrine"))
to_chat(user, "\t<span class='info'>Bloodstream analysis located [M.reagents:get_reagent_amount("epinephrine")] units of rejuvenation chemicals.</span>")
if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain))
to_chat(user, "\t<span class='alert'>Subject brain function is non-existent.</span>")
else if (M.getBrainLoss() >= 60)
to_chat(user, "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental retardation.</span>")
else if (M.getBrainLoss() >= 10)
to_chat(user, "\t<span class='alert'>Brain damage detected. Subject may have had a concussion.</span>")
// Organ damage report
if(iscarbon(M) && mode == 1)
var/mob/living/carbon/C = M
var/list/damaged = C.get_damaged_bodyparts(1,1)
if(length(damaged)>0 || oxy_loss>0 || tox_loss>0 || fire_loss>0)
to_chat(user, "<span class='info'>\tDamage: <span class='info'><font color='red'>Brute</font></span>-<font color='#FF8000'>Burn</font>-<font color='green'>Toxin</font>-<font color='blue'>Suffocation</font>\n\t\tSpecifics: <font color='red'>[brute_loss]</font>-<font color='#FF8000'>[fire_loss]</font>-<font color='green'>[tox_loss]</font>-<font color='blue'>[oxy_loss]</font></span>")
for(var/obj/item/bodypart/org in damaged)
to_chat(user, "\t\t<span class='info'>[capitalize(org.name)]: [(org.brute_dam > 0) ? "<font color='red'>[org.brute_dam]</font></span>" : "<font color='red'>0</font>"]-[(org.burn_dam > 0) ? "<font color='#FF8000'>[org.burn_dam]</font>" : "<font color='#FF8000'>0</font>"]")
// Species and body temperature
if(ishuman(M))
var/mob/living/carbon/human/H = M
to_chat(user, "<span class='info'>Species: [H.dna.species.name]</span>")
to_chat(user, "<span class='info'>Body temperature: [round(M.bodytemperature-T0C,0.1)] &deg;C ([round(M.bodytemperature*1.8-459.67,0.1)] &deg;F)</span>")
// Time of death
if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
to_chat(user, "<span class='info'>Time of Death:</span> [M.tod]")
var/tdelta = round(world.time - M.timeofdeath)
if(tdelta < (DEFIB_TIME_LIMIT * 10))
to_chat(user, "<span class='danger'>Subject died [tdelta / 10] seconds ago, defibrillation may be possible!</span>")
for(var/datum/disease/D in M.viruses)
if(!(D.visibility_flags & HIDDEN_SCANNER))
to_chat(user, "<span class='alert'><b>Warning: [D.form] detected</b>\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]</span>")
// Blood Level
if(M.has_dna())
var/mob/living/carbon/C = M
var/blood_id = C.get_blood_id()
if(blood_id)
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(H.bleed_rate)
to_chat(user, "<span class='danger'>Subject is bleeding!</span>")
var/blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
var/blood_type = C.dna.blood_type
if(blood_id != "blood")//special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
else
blood_type = blood_id
if(C.blood_volume <= BLOOD_VOLUME_SAFE && C.blood_volume > BLOOD_VOLUME_OKAY)
to_chat(user, "<span class='danger'>LOW blood level [blood_percent] %, [C.blood_volume] cl,</span> <span class='info'>type: [blood_type]</span>")
else if(C.blood_volume <= BLOOD_VOLUME_OKAY)
to_chat(user, "<span class='danger'>CRITICAL blood level [blood_percent] %, [C.blood_volume] cl,</span> <span class='info'>type: [blood_type]</span>")
else
to_chat(user, "<span class='info'>Blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]</span>")
var/cyberimp_detect
for(var/obj/item/organ/cyberimp/CI in C.internal_organs)
if(CI.status == ORGAN_ROBOTIC)
cyberimp_detect += "[C.name] is modified with a [CI.name].<br>"
if(cyberimp_detect)
to_chat(user, "<span class='notice'>Detected cybernetic modifications:</span>")
to_chat(user, "<span class='notice'>[cyberimp_detect]</span>")
/proc/chemscan(mob/living/user, mob/living/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.reagents)
if(H.reagents.reagent_list.len)
to_chat(user, "<span class='notice'>Subject contains the following reagents:</span>")
for(var/datum/reagent/R in H.reagents.reagent_list)
to_chat(user, "<span class='notice'>[R.volume] units of [R.name][R.overdosed == 1 ? "</span> - <span class='boldannounce'>OVERDOSING</span>" : ".</span>"]")
else
to_chat(user, "<span class='notice'>Subject contains no reagents.</span>")
if(H.reagents.addiction_list.len)
to_chat(user, "<span class='boldannounce'>Subject is addicted to the following reagents:</span>")
for(var/datum/reagent/R in H.reagents.addiction_list)
to_chat(user, "<span class='danger'>[R.name]</span>")
else
to_chat(user, "<span class='notice'>Subject is not addicted to any reagents.</span>")
/obj/item/device/healthanalyzer/verb/toggle_mode()
set name = "Switch Verbosity"
set category = "Object"
if(usr.stat || !usr.canmove || usr.restrained())
return
mode = !mode
switch (mode)
if(1)
to_chat(usr, "The scanner now shows specific limb damage.")
if(0)
to_chat(usr, "The scanner no longer shows limb damage.")
/obj/item/device/analyzer
desc = "A hand-held environmental scanner which reports current gas levels."
name = "analyzer"
icon_state = "atmos"
item_state = "analyzer"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
throwforce = 0
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=30, MAT_GLASS=20)
origin_tech = "magnets=1;engineering=1"
/obj/item/device/analyzer/attack_self(mob/user)
add_fingerprint(user)
if (user.stat || user.eye_blind)
return
var/turf/location = user.loc
if(!istype(location))
return
var/datum/gas_mixture/environment = location.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
to_chat(user, "<span class='info'><B>Results:</B></span>")
if(abs(pressure - ONE_ATMOSPHERE) < 10)
to_chat(user, "<span class='info'>Pressure: [round(pressure,0.1)] kPa</span>")
else
to_chat(user, "<span class='alert'>Pressure: [round(pressure,0.1)] kPa</span>")
if(total_moles)
var/list/env_gases = environment.gases
environment.assert_gases(arglist(GLOB.hardcoded_gases))
var/o2_concentration = env_gases["o2"][MOLES]/total_moles
var/n2_concentration = env_gases["n2"][MOLES]/total_moles
var/co2_concentration = env_gases["co2"][MOLES]/total_moles
var/plasma_concentration = env_gases["plasma"][MOLES]/total_moles
environment.garbage_collect()
if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
if(plasma_concentration > 0.005)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
for(var/id in env_gases)
if(id in GLOB.hardcoded_gases)
continue
var/gas_concentration = env_gases[id][MOLES]/total_moles
to_chat(user, "<span class='alert'>[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C)] &deg;C</span>")
/obj/item/device/mass_spectrometer
desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample."
name = "mass-spectrometer"
icon_state = "spectrometer"
item_state = "analyzer"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
slot_flags = SLOT_BELT
container_type = OPENCONTAINER
throwforce = 0
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=150, MAT_GLASS=100)
origin_tech = "magnets=2;biotech=1;plasmatech=2"
var/details = 0
/obj/item/device/mass_spectrometer/New()
..()
create_reagents(5)
/obj/item/device/mass_spectrometer/on_reagent_change()
if(reagents.total_volume)
icon_state = initial(icon_state) + "_s"
else
icon_state = initial(icon_state)
/obj/item/device/mass_spectrometer/attack_self(mob/user)
if (user.stat || user.eye_blind)
return
if (!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(reagents.total_volume)
var/list/blood_traces = list()
for(var/datum/reagent/R in reagents.reagent_list)
if(R.id != "blood")
reagents.clear_reagents()
to_chat(user, "<span class='warning'>The sample was contaminated! Please insert another sample.</span>")
return
else
blood_traces = params2list(R.data["trace_chem"])
break
var/dat = "<i><b>Trace Chemicals Found:</b>"
if(!blood_traces.len)
dat += "<br>None"
else
for(var/R in blood_traces)
dat += "<br>[GLOB.chemical_reagents_list[R]]"
if(details)
dat += " ([blood_traces[R]] units)"
dat += "</i>"
to_chat(user, dat)
reagents.clear_reagents()
/obj/item/device/mass_spectrometer/adv
name = "advanced mass-spectrometer"
icon_state = "adv_spectrometer"
details = 1
origin_tech = "magnets=4;biotech=3;plasmatech=3"
/obj/item/device/slime_scanner
name = "slime scanner"
desc = "A device that analyzes a slime's internal composition and measures its stats."
icon_state = "adv_spectrometer"
item_state = "analyzer"
origin_tech = "biotech=2"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
throwforce = 0
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=30, MAT_GLASS=20)
/obj/item/device/slime_scanner/attack(mob/living/M, mob/living/user)
if(user.stat || user.eye_blind)
return
if (!isslime(M))
to_chat(user, "<span class='warning'>This device can only scan slimes!</span>")
return
var/mob/living/simple_animal/slime/T = M
to_chat(user, "Slime scan results:")
to_chat(user, "[T.colour] [T.is_adult ? "adult" : "baby"] slime")
to_chat(user, "Nutrition: [T.nutrition]/[T.get_max_nutrition()]")
if (T.nutrition < T.get_starve_nutrition())
to_chat(user, "<span class='warning'>Warning: slime is starving!</span>")
else if (T.nutrition < T.get_hunger_nutrition())
to_chat(user, "<span class='warning'>Warning: slime is hungry</span>")
to_chat(user, "Electric change strength: [T.powerlevel]")
to_chat(user, "Health: [round(T.health/T.maxHealth,0.01)*100]")
if (T.slime_mutation[4] == T.colour)
to_chat(user, "This slime does not evolve any further.")
else
if (T.slime_mutation[3] == T.slime_mutation[4])
if (T.slime_mutation[2] == T.slime_mutation[1])
to_chat(user, "Possible mutation: [T.slime_mutation[3]]")
to_chat(user, "Genetic destability: [T.mutation_chance/2] % chance of mutation on splitting")
else
to_chat(user, "Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]] (x2)")
to_chat(user, "Genetic destability: [T.mutation_chance] % chance of mutation on splitting")
else
to_chat(user, "Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]], [T.slime_mutation[4]]")
to_chat(user, "Genetic destability: [T.mutation_chance] % chance of mutation on splitting")
if (T.cores > 1)
to_chat(user, "Anomalious slime core amount detected")
to_chat(user, "Growth progress: [T.amount_grown]/[SLIME_EVOLUTION_THRESHOLD]")
/obj/item/device/healthanalyzer
name = "health analyzer"
icon_state = "health"
item_state = "analyzer"
desc = "A hand-held body scanner able to distinguish vital signs of the subject."
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
throwforce = 3
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=200)
origin_tech = "magnets=1;biotech=1"
var/mode = 1
var/scanmode = 0
/obj/item/device/healthanalyzer/attack_self(mob/user)
if(!scanmode)
to_chat(user, "<span class='notice'>You switch the health analyzer to scan chemical contents.</span>")
scanmode = 1
else
to_chat(user, "<span class='notice'>You switch the health analyzer to check physical health.</span>")
scanmode = 0
/obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user)
// Clumsiness/brain damage check
if ((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50))
to_chat(user, "<span class='notice'>You stupidly try to analyze the floor's vitals!</span>")
user.visible_message("<span class='warning'>[user] has analyzed the floor's vitals!</span>")
to_chat(user, "<span class='info'>Analyzing results for The floor:\n\tOverall status: <b>Healthy</b>")
to_chat(user, "<span class='info'>Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FF8000'>Burn</font>/<font color='red'>Brute</font></span>")
to_chat(user, "<span class='info'>\tDamage specifics: <font color='blue'>0</font>-<font color='green'>0</font>-<font color='#FF8000'>0</font>-<font color='red'>0</font></span>")
to_chat(user, "<span class='info'>Body temperature: ???</span>")
return
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>")
if(scanmode == 0)
healthscan(user, M, mode)
else if(scanmode == 1)
chemscan(user, M)
add_fingerprint(user)
// Used by the PDA medical scanner too
/proc/healthscan(mob/living/user, mob/living/M, mode = 1)
if(user.incapacitated() || user.eye_blind)
return
//Damage specifics
var/oxy_loss = M.getOxyLoss()
var/tox_loss = M.getToxLoss()
var/fire_loss = M.getFireLoss()
var/brute_loss = M.getBruteLoss()
var/mob_status = (M.stat > 1 ? "<span class='alert'><b>Deceased</b></span>" : "<b>[round(M.health/M.maxHealth,0.01)*100] % healthy</b>")
if(M.status_flags & FAKEDEATH)
mob_status = "<span class='alert'>Deceased</span>"
oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.undergoing_cardiac_arrest() && H.stat != DEAD)
to_chat(user, "<span class='danger'>Subject suffering from heart attack: Apply defibrillator immediately!</span>")
to_chat(user, "<span class='info'>Analyzing results for [M]:\n\tOverall status: [mob_status]</span>")
// Damage descriptions
if(brute_loss > 10)
to_chat(user, "\t<span class='alert'>[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected.</span>")
if(fire_loss > 10)
to_chat(user, "\t<span class='alert'>[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected.</span>")
if(oxy_loss > 10)
to_chat(user, "\t<span class='info'><span class='alert'>[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.</span>")
if(tox_loss > 10)
to_chat(user, "\t<span class='alert'>[tox_loss > 50 ? "Critical" : "Dangerous"] amount of toxins detected.</span>")
if(M.getStaminaLoss())
to_chat(user, "\t<span class='alert'>Subject appears to be suffering from fatigue.</span>")
if (M.getCloneLoss())
to_chat(user, "\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.</span>")
if (M.reagents && M.reagents.get_reagent_amount("epinephrine"))
to_chat(user, "\t<span class='info'>Bloodstream analysis located [M.reagents:get_reagent_amount("epinephrine")] units of rejuvenation chemicals.</span>")
if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain))
to_chat(user, "\t<span class='alert'>Subject brain function is non-existent.</span>")
else if (M.getBrainLoss() >= 60)
to_chat(user, "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental retardation.</span>")
else if (M.getBrainLoss() >= 10)
to_chat(user, "\t<span class='alert'>Brain damage detected. Subject may have had a concussion.</span>")
// Organ damage report
if(iscarbon(M) && mode == 1)
var/mob/living/carbon/C = M
var/list/damaged = C.get_damaged_bodyparts(1,1)
if(length(damaged)>0 || oxy_loss>0 || tox_loss>0 || fire_loss>0)
to_chat(user, "<span class='info'>\tDamage: <span class='info'><font color='red'>Brute</font></span>-<font color='#FF8000'>Burn</font>-<font color='green'>Toxin</font>-<font color='blue'>Suffocation</font>\n\t\tSpecifics: <font color='red'>[brute_loss]</font>-<font color='#FF8000'>[fire_loss]</font>-<font color='green'>[tox_loss]</font>-<font color='blue'>[oxy_loss]</font></span>")
for(var/obj/item/bodypart/org in damaged)
to_chat(user, "\t\t<span class='info'>[capitalize(org.name)]: [(org.brute_dam > 0) ? "<font color='red'>[org.brute_dam]</font></span>" : "<font color='red'>0</font>"]-[(org.burn_dam > 0) ? "<font color='#FF8000'>[org.burn_dam]</font>" : "<font color='#FF8000'>0</font>"]")
// Species and body temperature
if(ishuman(M))
var/mob/living/carbon/human/H = M
to_chat(user, "<span class='info'>Species: [H.dna.species.name]</span>")
to_chat(user, "<span class='info'>Body temperature: [round(M.bodytemperature-T0C,0.1)] &deg;C ([round(M.bodytemperature*1.8-459.67,0.1)] &deg;F)</span>")
// Time of death
if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
to_chat(user, "<span class='info'>Time of Death:</span> [M.tod]")
var/tdelta = round(world.time - M.timeofdeath)
if(tdelta < (DEFIB_TIME_LIMIT * 10))
to_chat(user, "<span class='danger'>Subject died [tdelta / 10] seconds ago, defibrillation may be possible!</span>")
for(var/datum/disease/D in M.viruses)
if(!(D.visibility_flags & HIDDEN_SCANNER))
to_chat(user, "<span class='alert'><b>Warning: [D.form] detected</b>\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]</span>")
// Blood Level
if(M.has_dna())
var/mob/living/carbon/C = M
var/blood_id = C.get_blood_id()
if(blood_id)
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(H.bleed_rate)
to_chat(user, "<span class='danger'>Subject is bleeding!</span>")
var/blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
var/blood_type = C.dna.blood_type
if(blood_id != "blood")//special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
else
blood_type = blood_id
if(C.blood_volume <= BLOOD_VOLUME_SAFE && C.blood_volume > BLOOD_VOLUME_OKAY)
to_chat(user, "<span class='danger'>LOW blood level [blood_percent] %, [C.blood_volume] cl,</span> <span class='info'>type: [blood_type]</span>")
else if(C.blood_volume <= BLOOD_VOLUME_OKAY)
to_chat(user, "<span class='danger'>CRITICAL blood level [blood_percent] %, [C.blood_volume] cl,</span> <span class='info'>type: [blood_type]</span>")
else
to_chat(user, "<span class='info'>Blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]</span>")
var/cyberimp_detect
for(var/obj/item/organ/cyberimp/CI in C.internal_organs)
if(CI.status == ORGAN_ROBOTIC)
cyberimp_detect += "[C.name] is modified with a [CI.name].<br>"
if(cyberimp_detect)
to_chat(user, "<span class='notice'>Detected cybernetic modifications:</span>")
to_chat(user, "<span class='notice'>[cyberimp_detect]</span>")
/proc/chemscan(mob/living/user, mob/living/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.reagents)
if(H.reagents.reagent_list.len)
to_chat(user, "<span class='notice'>Subject contains the following reagents:</span>")
for(var/datum/reagent/R in H.reagents.reagent_list)
to_chat(user, "<span class='notice'>[R.volume] units of [R.name][R.overdosed == 1 ? "</span> - <span class='boldannounce'>OVERDOSING</span>" : ".</span>"]")
else
to_chat(user, "<span class='notice'>Subject contains no reagents.</span>")
if(H.reagents.addiction_list.len)
to_chat(user, "<span class='boldannounce'>Subject is addicted to the following reagents:</span>")
for(var/datum/reagent/R in H.reagents.addiction_list)
to_chat(user, "<span class='danger'>[R.name]</span>")
else
to_chat(user, "<span class='notice'>Subject is not addicted to any reagents.</span>")
/obj/item/device/healthanalyzer/verb/toggle_mode()
set name = "Switch Verbosity"
set category = "Object"
if(usr.stat || !usr.canmove || usr.restrained())
return
mode = !mode
switch (mode)
if(1)
to_chat(usr, "The scanner now shows specific limb damage.")
if(0)
to_chat(usr, "The scanner no longer shows limb damage.")
/obj/item/device/analyzer
desc = "A hand-held environmental scanner which reports current gas levels."
name = "analyzer"
icon_state = "atmos"
item_state = "analyzer"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
throwforce = 0
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=30, MAT_GLASS=20)
origin_tech = "magnets=1;engineering=1"
/obj/item/device/analyzer/attack_self(mob/user)
add_fingerprint(user)
if (user.stat || user.eye_blind)
return
var/turf/location = user.loc
if(!istype(location))
return
var/datum/gas_mixture/environment = location.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
to_chat(user, "<span class='info'><B>Results:</B></span>")
if(abs(pressure - ONE_ATMOSPHERE) < 10)
to_chat(user, "<span class='info'>Pressure: [round(pressure,0.1)] kPa</span>")
else
to_chat(user, "<span class='alert'>Pressure: [round(pressure,0.1)] kPa</span>")
if(total_moles)
var/list/env_gases = environment.gases
environment.assert_gases(arglist(GLOB.hardcoded_gases))
var/o2_concentration = env_gases["o2"][MOLES]/total_moles
var/n2_concentration = env_gases["n2"][MOLES]/total_moles
var/co2_concentration = env_gases["co2"][MOLES]/total_moles
var/plasma_concentration = env_gases["plasma"][MOLES]/total_moles
environment.garbage_collect()
if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
if(plasma_concentration > 0.005)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
for(var/id in env_gases)
if(id in GLOB.hardcoded_gases)
continue
var/gas_concentration = env_gases[id][MOLES]/total_moles
to_chat(user, "<span class='alert'>[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C)] &deg;C</span>")
/obj/item/device/mass_spectrometer
desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample."
name = "mass-spectrometer"
icon_state = "spectrometer"
item_state = "analyzer"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
slot_flags = SLOT_BELT
container_type = OPENCONTAINER
throwforce = 0
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=150, MAT_GLASS=100)
origin_tech = "magnets=2;biotech=1;plasmatech=2"
var/details = 0
/obj/item/device/mass_spectrometer/New()
..()
create_reagents(5)
/obj/item/device/mass_spectrometer/on_reagent_change()
if(reagents.total_volume)
icon_state = initial(icon_state) + "_s"
else
icon_state = initial(icon_state)
/obj/item/device/mass_spectrometer/attack_self(mob/user)
if (user.stat || user.eye_blind)
return
if (!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(reagents.total_volume)
var/list/blood_traces = list()
for(var/datum/reagent/R in reagents.reagent_list)
if(R.id != "blood")
reagents.clear_reagents()
to_chat(user, "<span class='warning'>The sample was contaminated! Please insert another sample.</span>")
return
else
blood_traces = params2list(R.data["trace_chem"])
break
var/dat = "<i><b>Trace Chemicals Found:</b>"
if(!blood_traces.len)
dat += "<br>None"
else
for(var/R in blood_traces)
dat += "<br>[GLOB.chemical_reagents_list[R]]"
if(details)
dat += " ([blood_traces[R]] units)"
dat += "</i>"
to_chat(user, dat)
reagents.clear_reagents()
/obj/item/device/mass_spectrometer/adv
name = "advanced mass-spectrometer"
icon_state = "adv_spectrometer"
details = 1
origin_tech = "magnets=4;biotech=3;plasmatech=3"
/obj/item/device/slime_scanner
name = "slime scanner"
desc = "A device that analyzes a slime's internal composition and measures its stats."
icon_state = "adv_spectrometer"
item_state = "analyzer"
origin_tech = "biotech=2"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
throwforce = 0
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=30, MAT_GLASS=20)
/obj/item/device/slime_scanner/attack(mob/living/M, mob/living/user)
if(user.stat || user.eye_blind)
return
if (!isslime(M))
to_chat(user, "<span class='warning'>This device can only scan slimes!</span>")
return
var/mob/living/simple_animal/slime/T = M
to_chat(user, "Slime scan results:")
to_chat(user, "[T.colour] [T.is_adult ? "adult" : "baby"] slime")
to_chat(user, "Nutrition: [T.nutrition]/[T.get_max_nutrition()]")
if (T.nutrition < T.get_starve_nutrition())
to_chat(user, "<span class='warning'>Warning: slime is starving!</span>")
else if (T.nutrition < T.get_hunger_nutrition())
to_chat(user, "<span class='warning'>Warning: slime is hungry</span>")
to_chat(user, "Electric change strength: [T.powerlevel]")
to_chat(user, "Health: [round(T.health/T.maxHealth,0.01)*100]")
if (T.slime_mutation[4] == T.colour)
to_chat(user, "This slime does not evolve any further.")
else
if (T.slime_mutation[3] == T.slime_mutation[4])
if (T.slime_mutation[2] == T.slime_mutation[1])
to_chat(user, "Possible mutation: [T.slime_mutation[3]]")
to_chat(user, "Genetic destability: [T.mutation_chance/2] % chance of mutation on splitting")
else
to_chat(user, "Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]] (x2)")
to_chat(user, "Genetic destability: [T.mutation_chance] % chance of mutation on splitting")
else
to_chat(user, "Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]], [T.slime_mutation[4]]")
to_chat(user, "Genetic destability: [T.mutation_chance] % chance of mutation on splitting")
if (T.cores > 1)
to_chat(user, "Anomalious slime core amount detected")
to_chat(user, "Growth progress: [T.amount_grown]/[SLIME_EVOLUTION_THRESHOLD]")
@@ -42,9 +42,7 @@ effective or pretty fucking useless.
for(var/mob/living/carbon/human/M in urange(10, user, 1))
if(prob(50))
M.Weaken(rand(10,20))
if(prob(25))
M.Stun(rand(5,10))
M.Knockdown(rand(200,400))
to_chat(M, "<span class='userdanger'>You feel a tremendous, paralyzing wave flood your mind.</span>")
else
@@ -90,7 +88,7 @@ effective or pretty fucking useless.
spawn((wavelength+(intensity*4))*5)
if(M)
if(intensity >= 5)
M.apply_effect(round(intensity/1.5), PARALYZE)
M.apply_effect(round(intensity/0.075), UNCONSCIOUS)
M.rad_act(intensity*10)
else
to_chat(user, "<span class='warning'>The radioactive microlaser is still recharging.</span>")
@@ -233,7 +231,7 @@ effective or pretty fucking useless.
var/range = 12
/obj/item/device/jammer/attack_self(mob/user)
to_chat(user,"<span class='notice'>You [active ? "deactivate" : "activate"] the [src]<span>")
to_chat(user,"<span class='notice'>You [active ? "deactivate" : "activate"] the [src]<span>")
active = !active
if(active)
GLOB.active_jammers |= src
@@ -241,4 +239,3 @@ effective or pretty fucking useless.
GLOB.active_jammers -= src
update_icon()