@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °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)] °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)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °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)] °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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user