MF Line endings

This commit is contained in:
Artur
2020-01-20 14:09:22 +02:00
parent f5ad854c2c
commit 8b21a60ac9
34 changed files with 5037 additions and 5037 deletions
+226 -226
View File
@@ -1,226 +1,226 @@
GLOBAL_LIST_EMPTY(GPS_list)
/obj/item/gps
name = "global positioning system"
desc = "Helping lost spacemen find their way through the planets since 2016."
icon = 'icons/obj/telescience.dmi'
icon_state = "gps-c"
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
obj_flags = UNIQUE_RENAME
var/gpstag = "COM0"
var/emped = FALSE
var/tracking = TRUE
var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user.
var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown
/obj/item/gps/examine(mob/user)
. = ..()
var/turf/curr = get_turf(src)
. += "The screen says: [get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
. += "<span class='notice'>Alt-click to switch it [tracking ? "off":"on"].</span>"
/obj/item/gps/Initialize()
. = ..()
GLOB.GPS_list += src
name = "global positioning system ([gpstag])"
add_overlay("working")
/obj/item/gps/Destroy()
GLOB.GPS_list -= src
return ..()
/obj/item/gps/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
emped = TRUE
cut_overlay("working")
add_overlay("emp")
addtimer(CALLBACK(src, .proc/reboot), 300, TIMER_UNIQUE|TIMER_OVERRIDE) //if a new EMP happens, remove the old timer so it doesn't reactivate early
SStgui.close_uis(src) //Close the UI control if it is open.
/obj/item/gps/proc/reboot()
emped = FALSE
cut_overlay("emp")
add_overlay("working")
/obj/item/gps/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, BE_CLOSE))
return
toggletracking(user)
return TRUE
/obj/item/gps/proc/toggletracking(mob/user)
if(!user.canUseTopic(src, BE_CLOSE))
return //user not valid to use gps
if(emped)
to_chat(user, "It's busted!")
return
if(tracking)
cut_overlay("working")
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
tracking = FALSE
else
add_overlay("working")
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
tracking = TRUE
/obj/item/gps/ui_interact(mob/user, ui_key = "gps", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
if(emped)
to_chat(user, "[src] fizzles weakly.")
return
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
// Variable window height, depending on how many GPS units there are
// to show, clamped to relatively safe range.
var/gps_window_height = CLAMP(325 + GLOB.GPS_list.len * 14, 325, 700)
ui = new(user, src, ui_key, "gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height
ui.open()
ui.set_autoupdate(state = updating)
/obj/item/gps/ui_data(mob/user)
var/list/data = list()
data["power"] = tracking
data["tag"] = gpstag
data["updating"] = updating
data["globalmode"] = global_mode
if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
return data
var/turf/curr = get_turf(src)
data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
data["currentArea"] = "[get_area_name(curr, TRUE)]"
data["currentCoords"] = "[curr.x], [curr.y], [curr.z]"
var/list/signals = list()
data["signals"] = list()
for(var/gps in GLOB.GPS_list)
var/obj/item/gps/G = gps
if(G.emped || !G.tracking || G == src)
continue
var/turf/pos = get_turf(G)
if(!global_mode && pos.z != curr.z)
continue
var/list/signal = list()
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
signal["coords"] = "[pos.x], [pos.y], [pos.z]"
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
signals += list(signal) //Add this signal to the list of signals
data["signals"] = signals
return data
/obj/item/gps/ui_act(action, params)
if(..())
return
switch(action)
if("rename")
var/a = input("Please enter desired tag.", name, gpstag) as text
a = copytext(sanitize(a), 1, 20)
gpstag = a
. = TRUE
name = "global positioning system ([gpstag])"
if("power")
toggletracking(usr)
. = TRUE
if("updating")
updating = !updating
. = TRUE
if("globalmode")
global_mode = !global_mode
. = TRUE
/obj/item/gps/science
icon_state = "gps-s"
gpstag = "SCI0"
/obj/item/gps/engineering
icon_state = "gps-e"
gpstag = "ENG0"
/obj/item/gps/mining
icon_state = "gps-m"
gpstag = "MINE0"
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
/obj/item/gps/cyborg
icon_state = "gps-b"
gpstag = "BORG0"
desc = "A mining cyborg internal positioning system. Used as a recovery beacon for damaged cyborg assets, or a collaboration tool for mining teams."
/obj/item/gps/cyborg/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT)
/obj/item/gps/internal
icon_state = null
item_flags = ABSTRACT
gpstag = "Eerie Signal"
desc = "Report to a coder immediately."
invisibility = INVISIBILITY_MAXIMUM
var/obj/item/implant/gps/implant
/obj/item/gps/internal/Initialize(mapload, obj/item/implant/gps/_implant)
. = ..()
implant = _implant
/obj/item/gps/internal/Destroy()
if(implant?.imp_in)
qdel(implant)
else
return ..()
/obj/item/gps/internal/mining
icon_state = "gps-m"
gpstag = "MINER"
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
/obj/item/gps/internal/base
gpstag = "NT_AUX"
desc = "A homing signal from Nanotrasen's mining base."
/obj/item/gps/visible_debug
name = "visible GPS"
gpstag = "ADMIN"
desc = "This admin-spawn GPS unit leaves the coordinates visible \
on any turf that it passes over, for debugging. Especially useful \
for marking the area around the transition edges."
var/list/turf/tagged
/obj/item/gps/visible_debug/Initialize()
. = ..()
tagged = list()
START_PROCESSING(SSfastprocess, src)
/obj/item/gps/visible_debug/process()
var/turf/T = get_turf(src)
if(T)
// I assume it's faster to color,tag and OR the turf in, rather
// then checking if its there
T.color = RANDOM_COLOUR
T.maptext = "[T.x],[T.y],[T.z]"
tagged |= T
/obj/item/gps/visible_debug/proc/clear()
while(tagged.len)
var/turf/T = pop(tagged)
T.color = initial(T.color)
T.maptext = initial(T.maptext)
/obj/item/gps/visible_debug/Destroy()
if(tagged)
clear()
tagged = null
STOP_PROCESSING(SSfastprocess, src)
. = ..()
GLOBAL_LIST_EMPTY(GPS_list)
/obj/item/gps
name = "global positioning system"
desc = "Helping lost spacemen find their way through the planets since 2016."
icon = 'icons/obj/telescience.dmi'
icon_state = "gps-c"
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
obj_flags = UNIQUE_RENAME
var/gpstag = "COM0"
var/emped = FALSE
var/tracking = TRUE
var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user.
var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown
/obj/item/gps/examine(mob/user)
. = ..()
var/turf/curr = get_turf(src)
. += "The screen says: [get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
. += "<span class='notice'>Alt-click to switch it [tracking ? "off":"on"].</span>"
/obj/item/gps/Initialize()
. = ..()
GLOB.GPS_list += src
name = "global positioning system ([gpstag])"
add_overlay("working")
/obj/item/gps/Destroy()
GLOB.GPS_list -= src
return ..()
/obj/item/gps/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
emped = TRUE
cut_overlay("working")
add_overlay("emp")
addtimer(CALLBACK(src, .proc/reboot), 300, TIMER_UNIQUE|TIMER_OVERRIDE) //if a new EMP happens, remove the old timer so it doesn't reactivate early
SStgui.close_uis(src) //Close the UI control if it is open.
/obj/item/gps/proc/reboot()
emped = FALSE
cut_overlay("emp")
add_overlay("working")
/obj/item/gps/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, BE_CLOSE))
return
toggletracking(user)
return TRUE
/obj/item/gps/proc/toggletracking(mob/user)
if(!user.canUseTopic(src, BE_CLOSE))
return //user not valid to use gps
if(emped)
to_chat(user, "It's busted!")
return
if(tracking)
cut_overlay("working")
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
tracking = FALSE
else
add_overlay("working")
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
tracking = TRUE
/obj/item/gps/ui_interact(mob/user, ui_key = "gps", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
if(emped)
to_chat(user, "[src] fizzles weakly.")
return
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
// Variable window height, depending on how many GPS units there are
// to show, clamped to relatively safe range.
var/gps_window_height = CLAMP(325 + GLOB.GPS_list.len * 14, 325, 700)
ui = new(user, src, ui_key, "gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height
ui.open()
ui.set_autoupdate(state = updating)
/obj/item/gps/ui_data(mob/user)
var/list/data = list()
data["power"] = tracking
data["tag"] = gpstag
data["updating"] = updating
data["globalmode"] = global_mode
if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
return data
var/turf/curr = get_turf(src)
data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
data["currentArea"] = "[get_area_name(curr, TRUE)]"
data["currentCoords"] = "[curr.x], [curr.y], [curr.z]"
var/list/signals = list()
data["signals"] = list()
for(var/gps in GLOB.GPS_list)
var/obj/item/gps/G = gps
if(G.emped || !G.tracking || G == src)
continue
var/turf/pos = get_turf(G)
if(!global_mode && pos.z != curr.z)
continue
var/list/signal = list()
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
signal["coords"] = "[pos.x], [pos.y], [pos.z]"
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
signals += list(signal) //Add this signal to the list of signals
data["signals"] = signals
return data
/obj/item/gps/ui_act(action, params)
if(..())
return
switch(action)
if("rename")
var/a = input("Please enter desired tag.", name, gpstag) as text
a = copytext(sanitize(a), 1, 20)
gpstag = a
. = TRUE
name = "global positioning system ([gpstag])"
if("power")
toggletracking(usr)
. = TRUE
if("updating")
updating = !updating
. = TRUE
if("globalmode")
global_mode = !global_mode
. = TRUE
/obj/item/gps/science
icon_state = "gps-s"
gpstag = "SCI0"
/obj/item/gps/engineering
icon_state = "gps-e"
gpstag = "ENG0"
/obj/item/gps/mining
icon_state = "gps-m"
gpstag = "MINE0"
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
/obj/item/gps/cyborg
icon_state = "gps-b"
gpstag = "BORG0"
desc = "A mining cyborg internal positioning system. Used as a recovery beacon for damaged cyborg assets, or a collaboration tool for mining teams."
/obj/item/gps/cyborg/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT)
/obj/item/gps/internal
icon_state = null
item_flags = ABSTRACT
gpstag = "Eerie Signal"
desc = "Report to a coder immediately."
invisibility = INVISIBILITY_MAXIMUM
var/obj/item/implant/gps/implant
/obj/item/gps/internal/Initialize(mapload, obj/item/implant/gps/_implant)
. = ..()
implant = _implant
/obj/item/gps/internal/Destroy()
if(implant?.imp_in)
qdel(implant)
else
return ..()
/obj/item/gps/internal/mining
icon_state = "gps-m"
gpstag = "MINER"
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
/obj/item/gps/internal/base
gpstag = "NT_AUX"
desc = "A homing signal from Nanotrasen's mining base."
/obj/item/gps/visible_debug
name = "visible GPS"
gpstag = "ADMIN"
desc = "This admin-spawn GPS unit leaves the coordinates visible \
on any turf that it passes over, for debugging. Especially useful \
for marking the area around the transition edges."
var/list/turf/tagged
/obj/item/gps/visible_debug/Initialize()
. = ..()
tagged = list()
START_PROCESSING(SSfastprocess, src)
/obj/item/gps/visible_debug/process()
var/turf/T = get_turf(src)
if(T)
// I assume it's faster to color,tag and OR the turf in, rather
// then checking if its there
T.color = RANDOM_COLOUR
T.maptext = "[T.x],[T.y],[T.z]"
tagged |= T
/obj/item/gps/visible_debug/proc/clear()
while(tagged.len)
var/turf/T = pop(tagged)
T.color = initial(T.color)
T.maptext = initial(T.maptext)
/obj/item/gps/visible_debug/Destroy()
if(tagged)
clear()
tagged = null
STOP_PROCESSING(SSfastprocess, src)
. = ..()
+436 -436
View File
@@ -1,436 +1,436 @@
/obj/item/radio
icon = 'icons/obj/radio.dmi'
name = "station bounced radio"
icon_state = "walkietalkie"
item_state = "walkietalkie"
desc = "A basic handheld radio that communicates with local telecommunication networks."
dog_fashion = /datum/dog_fashion/back
flags_1 = CONDUCT_1 | HEAR_1
slot_flags = ITEM_SLOT_BELT
throw_speed = 3
throw_range = 7
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=75, MAT_GLASS=25)
obj_flags = USES_TGUI
var/on = TRUE
var/frequency = FREQ_COMMON
var/canhear_range = 3 // The range around the radio in which mobs can hear what it receives.
var/emped = 0 // Tracks the number of EMPs currently stacked.
var/broadcasting = FALSE // Whether the radio will transmit dialogue it hears nearby.
var/listening = TRUE // Whether the radio is currently receiving.
var/prison_radio = FALSE // If true, the transmit wire starts cut.
var/unscrewed = FALSE // Whether wires are accessible. Toggleable by screwdrivering.
var/freerange = FALSE // If true, the radio has access to the full spectrum.
var/subspace_transmission = FALSE // If true, the radio transmits and receives on subspace exclusively.
var/subspace_switchable = FALSE // If true, subspace_transmission can be toggled at will.
var/freqlock = FALSE // Frequency lock to stop the user from untuning specialist radios.
var/use_command = FALSE // If true, broadcasts will be large and BOLD.
var/command = FALSE // If true, use_command can be toggled at will.
var/commandspan = SPAN_COMMAND //allow us to set what the fuck we want for headsets
// Encryption key handling
var/obj/item/encryptionkey/keyslot
var/translate_binary = FALSE // If true, can hear the special binary channel.
var/independent = FALSE // If true, can say/hear on the special CentCom channel.
var/syndie = FALSE // If true, hears all well-known channels automatically, and can say/hear on the Syndicate channel.
var/list/channels = list() // Map from name (see communications.dm) to on/off. First entry is current department (:h).
var/list/secure_radio_connections
var/const/FREQ_LISTENING = 1
//FREQ_BROADCASTING = 2
/obj/item/radio/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] starts bouncing [src] off [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/radio/proc/set_frequency(new_frequency)
SEND_SIGNAL(src, COMSIG_RADIO_NEW_FREQUENCY, args)
remove_radio(src, frequency)
frequency = add_radio(src, new_frequency)
/obj/item/radio/proc/recalculateChannels()
channels = list()
translate_binary = FALSE
syndie = FALSE
independent = FALSE
if(keyslot)
for(var/ch_name in keyslot.channels)
if(!(ch_name in channels))
channels[ch_name] = keyslot.channels[ch_name]
if(keyslot.translate_binary)
translate_binary = TRUE
if(keyslot.syndie)
syndie = TRUE
if(keyslot.independent)
independent = TRUE
for(var/ch_name in channels)
secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name])
/obj/item/radio/proc/make_syndie() // Turns normal radios into Syndicate radios!
qdel(keyslot)
keyslot = new /obj/item/encryptionkey/syndicate
syndie = 1
recalculateChannels()
/obj/item/radio/Destroy()
remove_radio_all(src) //Just to be sure
QDEL_NULL(wires)
QDEL_NULL(keyslot)
return ..()
/obj/item/radio/Initialize()
wires = new /datum/wires/radio(src)
if(prison_radio)
wires.cut(WIRE_TX) // OH GOD WHY
secure_radio_connections = new
. = ..()
frequency = sanitize_frequency(frequency, freerange)
set_frequency(frequency)
for(var/ch_name in channels)
secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name])
/obj/item/radio/ComponentInitialize()
. = ..()
AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES)
/obj/item/radio/interact(mob/user)
if(unscrewed && !isAI(user))
wires.interact(user)
add_fingerprint(user)
else
..()
/obj/item/radio/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
. = ..()
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/ui_width = 360
var/ui_height = 106
if(subspace_transmission)
if(channels.len > 0)
ui_height += 6 + channels.len * 21
else
ui_height += 24
ui = new(user, src, ui_key, "radio", name, ui_width, ui_height, master_ui, state)
ui.open()
/obj/item/radio/ui_data(mob/user)
var/list/data = list()
data["broadcasting"] = broadcasting
data["listening"] = listening
data["frequency"] = frequency
data["minFrequency"] = freerange ? MIN_FREE_FREQ : MIN_FREQ
data["maxFrequency"] = freerange ? MAX_FREE_FREQ : MAX_FREQ
data["freqlock"] = freqlock
data["channels"] = list()
for(var/channel in channels)
data["channels"][channel] = channels[channel] & FREQ_LISTENING
data["command"] = command
data["useCommand"] = use_command
data["subspace"] = subspace_transmission
data["subspaceSwitchable"] = subspace_switchable
data["headset"] = istype(src, /obj/item/radio/headset)
return data
/obj/item/radio/ui_act(action, params, datum/tgui/ui)
if(..())
return
switch(action)
if("frequency")
if(freqlock)
return
var/tune = params["tune"]
var/adjust = text2num(params["adjust"])
if(tune == "input")
var/min = format_frequency(freerange ? MIN_FREE_FREQ : MIN_FREQ)
var/max = format_frequency(freerange ? MAX_FREE_FREQ : MAX_FREQ)
tune = input("Tune frequency ([min]-[max]):", name, format_frequency(frequency)) as null|num
if(!isnull(tune) && !..())
if (tune < MIN_FREE_FREQ && tune <= MAX_FREE_FREQ / 10)
// allow typing 144.7 to get 1447
tune *= 10
. = TRUE
else if(adjust)
tune = frequency + adjust * 10
. = TRUE
else if(text2num(tune) != null)
tune = tune * 10
. = TRUE
if(.)
set_frequency(sanitize_frequency(tune, freerange))
if("listen")
listening = !listening
. = TRUE
if("broadcast")
broadcasting = !broadcasting
. = TRUE
if("channel")
var/channel = params["channel"]
if(!(channel in channels))
return
if(channels[channel] & FREQ_LISTENING)
channels[channel] &= ~FREQ_LISTENING
else
channels[channel] |= FREQ_LISTENING
. = TRUE
if("command")
use_command = !use_command
. = TRUE
if("subspace")
if(subspace_switchable)
subspace_transmission = !subspace_transmission
if(!subspace_transmission)
channels = list()
else
recalculateChannels()
. = TRUE
/obj/item/radio/talk_into(atom/movable/M, message, channel, list/spans, datum/language/language)
if(!spans)
spans = list(M.speech_span)
if(!language)
language = M.get_default_language()
INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans.Copy(), language)
return ITALICS | REDUCE_RANGE
/obj/item/radio/proc/talk_into_impl(atom/movable/M, message, channel, list/spans, datum/language/language)
if(!on)
return // the device has to be on
if(!M || !message)
return
if(wires.is_cut(WIRE_TX)) // Permacell and otherwise tampered-with radios
return
if(!M.IsVocal())
return
if(use_command)
spans |= commandspan
/*
Roughly speaking, radios attempt to make a subspace transmission (which
is received, processed, and rebroadcast by the telecomms satellite) and
if that fails, they send a mundane radio transmission.
Headsets cannot send/receive mundane transmissions, only subspace.
Syndicate radios can hear transmissions on all well-known frequencies.
CentCom radios can hear the CentCom frequency no matter what.
*/
// From the channel, determine the frequency and get a reference to it.
var/freq
if(channel && channels && channels.len > 0)
if(channel == MODE_DEPARTMENT)
channel = channels[1]
freq = secure_radio_connections[channel]
if (!channels[channel]) // if the channel is turned off, don't broadcast
return
else
freq = frequency
channel = null
// Nearby active jammers severely gibberish the message
var/turf/position = get_turf(src)
for(var/obj/item/jammer/jammer in GLOB.active_jammers)
var/turf/jammer_turf = get_turf(jammer)
if(position.z == jammer_turf.z && (get_dist(position, jammer_turf) < jammer.range))
message = Gibberish(message,100)
break
// Determine the identity information which will be attached to the signal.
var/atom/movable/virtualspeaker/speaker = new(null, M, src)
// Construct the signal
var/datum/signal/subspace/vocal/signal = new(src, freq, speaker, language, message, spans)
// Independent radios, on the CentCom frequency, reach all independent radios
if (independent && (freq == FREQ_CENTCOM || freq == FREQ_CTF_RED || freq == FREQ_CTF_BLUE))
signal.data["compression"] = 0
signal.transmission_method = TRANSMISSION_SUPERSPACE
signal.levels = list(0) // reaches all Z-levels
signal.broadcast()
return
// All radios make an attempt to use the subspace system first
signal.send_to_receivers()
// If the radio is subspace-only, that's all it can do
if (subspace_transmission)
return
// Non-subspace radios will check in a couple of seconds, and if the signal
// was never received, send a mundane broadcast (no headsets).
addtimer(CALLBACK(src, .proc/backup_transmission, signal), 20)
/obj/item/radio/proc/backup_transmission(datum/signal/subspace/vocal/signal)
var/turf/T = get_turf(src)
if (signal.data["done"] && (T.z in signal.levels))
return
// Okay, the signal was never processed, send a mundane broadcast.
signal.data["compression"] = 0
signal.transmission_method = TRANSMISSION_RADIO
signal.levels = list(T.z)
signal.broadcast()
/obj/item/radio/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
. = ..()
if(radio_freq || !broadcasting || get_dist(src, speaker) > canhear_range)
return
if(message_mode == MODE_WHISPER || message_mode == MODE_WHISPER_CRIT)
// radios don't pick up whispers very well
raw_message = stars(raw_message)
else if(message_mode == MODE_L_HAND || message_mode == MODE_R_HAND)
// try to avoid being heard double
if (loc == speaker && ismob(speaker))
var/mob/M = speaker
var/idx = M.get_held_index_of_item(src)
// left hands are odd slots
if (idx && (idx % 2) == (message_mode == MODE_L_HAND))
return
talk_into(speaker, raw_message, , spans, language=message_language)
// Checks if this radio can receive on the given frequency.
/obj/item/radio/proc/can_receive(freq, level)
// deny checks
if (!on || !listening || wires.is_cut(WIRE_RX))
return FALSE
if (freq == FREQ_SYNDICATE && !syndie)
return FALSE
if (freq == FREQ_CENTCOM)
return independent // hard-ignores the z-level check
if (!(0 in level))
var/turf/position = get_turf(src)
if(!position || !(position.z in level))
return FALSE
// allow checks: are we listening on that frequency?
if (freq == frequency)
return TRUE
for(var/ch_name in channels)
if(channels[ch_name] & FREQ_LISTENING)
//the GLOB.radiochannels list is located in communications.dm
if(GLOB.radiochannels[ch_name] == text2num(freq) || syndie)
return TRUE
return FALSE
/obj/item/radio/examine(mob/user)
. = ..()
if (unscrewed)
. += "<span class='notice'>It can be attached and modified.</span>"
else
. += "<span class='notice'>It cannot be modified or attached.</span>"
/obj/item/radio/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
if(istype(W, /obj/item/screwdriver))
unscrewed = !unscrewed
if(unscrewed)
to_chat(user, "<span class='notice'>The radio can now be attached and modified!</span>")
else
to_chat(user, "<span class='notice'>The radio can no longer be modified or attached!</span>")
else
return ..()
/obj/item/radio/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
emped++ //There's been an EMP; better count it
var/curremp = emped //Remember which EMP this was
if (listening && ismob(loc)) // if the radio is turned on and on someone's person they notice
to_chat(loc, "<span class='warning'>\The [src] overloads.</span>")
broadcasting = FALSE
listening = FALSE
for (var/ch_name in channels)
channels[ch_name] = 0
on = FALSE
spawn(200)
if(emped == curremp) //Don't fix it if it's been EMP'd again
emped = 0
if (!istype(src, /obj/item/radio/intercom)) // intercoms will turn back on on their own
on = TRUE
///////////////////////////////
//////////Borg Radios//////////
///////////////////////////////
//Giving borgs their own radio to have some more room to work with -Sieve
/obj/item/radio/borg
name = "cyborg radio"
subspace_switchable = TRUE
dog_fashion = null
/obj/item/radio/borg/Initialize(mapload)
. = ..()
/obj/item/radio/borg/syndicate
syndie = 1
keyslot = new /obj/item/encryptionkey/syndicate
/obj/item/radio/borg/syndicate/Initialize()
. = ..()
set_frequency(FREQ_SYNDICATE)
/obj/item/radio/borg/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
if(keyslot)
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.forceMove(T)
keyslot = null
recalculateChannels()
to_chat(user, "<span class='notice'>You pop out the encryption key in the radio.</span>")
else
to_chat(user, "<span class='warning'>This radio doesn't have any encryption keys!</span>")
else if(istype(W, /obj/item/encryptionkey/))
if(keyslot)
to_chat(user, "<span class='warning'>The radio can't hold another key!</span>")
return
if(!keyslot)
if(!user.transferItemToLoc(W, src))
return
keyslot = W
recalculateChannels()
/obj/item/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
/obj/item/radio/internal
var/obj/item/implant/radio/implant
/obj/item/radio/internal/Initialize(mapload, obj/item/implant/radio/_implant)
. = ..()
implant = _implant
/obj/item/radio/internal/Destroy()
if(implant?.imp_in)
qdel(implant)
else
return ..()
/obj/item/radio
icon = 'icons/obj/radio.dmi'
name = "station bounced radio"
icon_state = "walkietalkie"
item_state = "walkietalkie"
desc = "A basic handheld radio that communicates with local telecommunication networks."
dog_fashion = /datum/dog_fashion/back
flags_1 = CONDUCT_1 | HEAR_1
slot_flags = ITEM_SLOT_BELT
throw_speed = 3
throw_range = 7
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=75, MAT_GLASS=25)
obj_flags = USES_TGUI
var/on = TRUE
var/frequency = FREQ_COMMON
var/canhear_range = 3 // The range around the radio in which mobs can hear what it receives.
var/emped = 0 // Tracks the number of EMPs currently stacked.
var/broadcasting = FALSE // Whether the radio will transmit dialogue it hears nearby.
var/listening = TRUE // Whether the radio is currently receiving.
var/prison_radio = FALSE // If true, the transmit wire starts cut.
var/unscrewed = FALSE // Whether wires are accessible. Toggleable by screwdrivering.
var/freerange = FALSE // If true, the radio has access to the full spectrum.
var/subspace_transmission = FALSE // If true, the radio transmits and receives on subspace exclusively.
var/subspace_switchable = FALSE // If true, subspace_transmission can be toggled at will.
var/freqlock = FALSE // Frequency lock to stop the user from untuning specialist radios.
var/use_command = FALSE // If true, broadcasts will be large and BOLD.
var/command = FALSE // If true, use_command can be toggled at will.
var/commandspan = SPAN_COMMAND //allow us to set what the fuck we want for headsets
// Encryption key handling
var/obj/item/encryptionkey/keyslot
var/translate_binary = FALSE // If true, can hear the special binary channel.
var/independent = FALSE // If true, can say/hear on the special CentCom channel.
var/syndie = FALSE // If true, hears all well-known channels automatically, and can say/hear on the Syndicate channel.
var/list/channels = list() // Map from name (see communications.dm) to on/off. First entry is current department (:h).
var/list/secure_radio_connections
var/const/FREQ_LISTENING = 1
//FREQ_BROADCASTING = 2
/obj/item/radio/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] starts bouncing [src] off [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/radio/proc/set_frequency(new_frequency)
SEND_SIGNAL(src, COMSIG_RADIO_NEW_FREQUENCY, args)
remove_radio(src, frequency)
frequency = add_radio(src, new_frequency)
/obj/item/radio/proc/recalculateChannels()
channels = list()
translate_binary = FALSE
syndie = FALSE
independent = FALSE
if(keyslot)
for(var/ch_name in keyslot.channels)
if(!(ch_name in channels))
channels[ch_name] = keyslot.channels[ch_name]
if(keyslot.translate_binary)
translate_binary = TRUE
if(keyslot.syndie)
syndie = TRUE
if(keyslot.independent)
independent = TRUE
for(var/ch_name in channels)
secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name])
/obj/item/radio/proc/make_syndie() // Turns normal radios into Syndicate radios!
qdel(keyslot)
keyslot = new /obj/item/encryptionkey/syndicate
syndie = 1
recalculateChannels()
/obj/item/radio/Destroy()
remove_radio_all(src) //Just to be sure
QDEL_NULL(wires)
QDEL_NULL(keyslot)
return ..()
/obj/item/radio/Initialize()
wires = new /datum/wires/radio(src)
if(prison_radio)
wires.cut(WIRE_TX) // OH GOD WHY
secure_radio_connections = new
. = ..()
frequency = sanitize_frequency(frequency, freerange)
set_frequency(frequency)
for(var/ch_name in channels)
secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name])
/obj/item/radio/ComponentInitialize()
. = ..()
AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES)
/obj/item/radio/interact(mob/user)
if(unscrewed && !isAI(user))
wires.interact(user)
add_fingerprint(user)
else
..()
/obj/item/radio/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
. = ..()
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/ui_width = 360
var/ui_height = 106
if(subspace_transmission)
if(channels.len > 0)
ui_height += 6 + channels.len * 21
else
ui_height += 24
ui = new(user, src, ui_key, "radio", name, ui_width, ui_height, master_ui, state)
ui.open()
/obj/item/radio/ui_data(mob/user)
var/list/data = list()
data["broadcasting"] = broadcasting
data["listening"] = listening
data["frequency"] = frequency
data["minFrequency"] = freerange ? MIN_FREE_FREQ : MIN_FREQ
data["maxFrequency"] = freerange ? MAX_FREE_FREQ : MAX_FREQ
data["freqlock"] = freqlock
data["channels"] = list()
for(var/channel in channels)
data["channels"][channel] = channels[channel] & FREQ_LISTENING
data["command"] = command
data["useCommand"] = use_command
data["subspace"] = subspace_transmission
data["subspaceSwitchable"] = subspace_switchable
data["headset"] = istype(src, /obj/item/radio/headset)
return data
/obj/item/radio/ui_act(action, params, datum/tgui/ui)
if(..())
return
switch(action)
if("frequency")
if(freqlock)
return
var/tune = params["tune"]
var/adjust = text2num(params["adjust"])
if(tune == "input")
var/min = format_frequency(freerange ? MIN_FREE_FREQ : MIN_FREQ)
var/max = format_frequency(freerange ? MAX_FREE_FREQ : MAX_FREQ)
tune = input("Tune frequency ([min]-[max]):", name, format_frequency(frequency)) as null|num
if(!isnull(tune) && !..())
if (tune < MIN_FREE_FREQ && tune <= MAX_FREE_FREQ / 10)
// allow typing 144.7 to get 1447
tune *= 10
. = TRUE
else if(adjust)
tune = frequency + adjust * 10
. = TRUE
else if(text2num(tune) != null)
tune = tune * 10
. = TRUE
if(.)
set_frequency(sanitize_frequency(tune, freerange))
if("listen")
listening = !listening
. = TRUE
if("broadcast")
broadcasting = !broadcasting
. = TRUE
if("channel")
var/channel = params["channel"]
if(!(channel in channels))
return
if(channels[channel] & FREQ_LISTENING)
channels[channel] &= ~FREQ_LISTENING
else
channels[channel] |= FREQ_LISTENING
. = TRUE
if("command")
use_command = !use_command
. = TRUE
if("subspace")
if(subspace_switchable)
subspace_transmission = !subspace_transmission
if(!subspace_transmission)
channels = list()
else
recalculateChannels()
. = TRUE
/obj/item/radio/talk_into(atom/movable/M, message, channel, list/spans, datum/language/language)
if(!spans)
spans = list(M.speech_span)
if(!language)
language = M.get_default_language()
INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans.Copy(), language)
return ITALICS | REDUCE_RANGE
/obj/item/radio/proc/talk_into_impl(atom/movable/M, message, channel, list/spans, datum/language/language)
if(!on)
return // the device has to be on
if(!M || !message)
return
if(wires.is_cut(WIRE_TX)) // Permacell and otherwise tampered-with radios
return
if(!M.IsVocal())
return
if(use_command)
spans |= commandspan
/*
Roughly speaking, radios attempt to make a subspace transmission (which
is received, processed, and rebroadcast by the telecomms satellite) and
if that fails, they send a mundane radio transmission.
Headsets cannot send/receive mundane transmissions, only subspace.
Syndicate radios can hear transmissions on all well-known frequencies.
CentCom radios can hear the CentCom frequency no matter what.
*/
// From the channel, determine the frequency and get a reference to it.
var/freq
if(channel && channels && channels.len > 0)
if(channel == MODE_DEPARTMENT)
channel = channels[1]
freq = secure_radio_connections[channel]
if (!channels[channel]) // if the channel is turned off, don't broadcast
return
else
freq = frequency
channel = null
// Nearby active jammers severely gibberish the message
var/turf/position = get_turf(src)
for(var/obj/item/jammer/jammer in GLOB.active_jammers)
var/turf/jammer_turf = get_turf(jammer)
if(position.z == jammer_turf.z && (get_dist(position, jammer_turf) < jammer.range))
message = Gibberish(message,100)
break
// Determine the identity information which will be attached to the signal.
var/atom/movable/virtualspeaker/speaker = new(null, M, src)
// Construct the signal
var/datum/signal/subspace/vocal/signal = new(src, freq, speaker, language, message, spans)
// Independent radios, on the CentCom frequency, reach all independent radios
if (independent && (freq == FREQ_CENTCOM || freq == FREQ_CTF_RED || freq == FREQ_CTF_BLUE))
signal.data["compression"] = 0
signal.transmission_method = TRANSMISSION_SUPERSPACE
signal.levels = list(0) // reaches all Z-levels
signal.broadcast()
return
// All radios make an attempt to use the subspace system first
signal.send_to_receivers()
// If the radio is subspace-only, that's all it can do
if (subspace_transmission)
return
// Non-subspace radios will check in a couple of seconds, and if the signal
// was never received, send a mundane broadcast (no headsets).
addtimer(CALLBACK(src, .proc/backup_transmission, signal), 20)
/obj/item/radio/proc/backup_transmission(datum/signal/subspace/vocal/signal)
var/turf/T = get_turf(src)
if (signal.data["done"] && (T.z in signal.levels))
return
// Okay, the signal was never processed, send a mundane broadcast.
signal.data["compression"] = 0
signal.transmission_method = TRANSMISSION_RADIO
signal.levels = list(T.z)
signal.broadcast()
/obj/item/radio/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
. = ..()
if(radio_freq || !broadcasting || get_dist(src, speaker) > canhear_range)
return
if(message_mode == MODE_WHISPER || message_mode == MODE_WHISPER_CRIT)
// radios don't pick up whispers very well
raw_message = stars(raw_message)
else if(message_mode == MODE_L_HAND || message_mode == MODE_R_HAND)
// try to avoid being heard double
if (loc == speaker && ismob(speaker))
var/mob/M = speaker
var/idx = M.get_held_index_of_item(src)
// left hands are odd slots
if (idx && (idx % 2) == (message_mode == MODE_L_HAND))
return
talk_into(speaker, raw_message, , spans, language=message_language)
// Checks if this radio can receive on the given frequency.
/obj/item/radio/proc/can_receive(freq, level)
// deny checks
if (!on || !listening || wires.is_cut(WIRE_RX))
return FALSE
if (freq == FREQ_SYNDICATE && !syndie)
return FALSE
if (freq == FREQ_CENTCOM)
return independent // hard-ignores the z-level check
if (!(0 in level))
var/turf/position = get_turf(src)
if(!position || !(position.z in level))
return FALSE
// allow checks: are we listening on that frequency?
if (freq == frequency)
return TRUE
for(var/ch_name in channels)
if(channels[ch_name] & FREQ_LISTENING)
//the GLOB.radiochannels list is located in communications.dm
if(GLOB.radiochannels[ch_name] == text2num(freq) || syndie)
return TRUE
return FALSE
/obj/item/radio/examine(mob/user)
. = ..()
if (unscrewed)
. += "<span class='notice'>It can be attached and modified.</span>"
else
. += "<span class='notice'>It cannot be modified or attached.</span>"
/obj/item/radio/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
if(istype(W, /obj/item/screwdriver))
unscrewed = !unscrewed
if(unscrewed)
to_chat(user, "<span class='notice'>The radio can now be attached and modified!</span>")
else
to_chat(user, "<span class='notice'>The radio can no longer be modified or attached!</span>")
else
return ..()
/obj/item/radio/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
emped++ //There's been an EMP; better count it
var/curremp = emped //Remember which EMP this was
if (listening && ismob(loc)) // if the radio is turned on and on someone's person they notice
to_chat(loc, "<span class='warning'>\The [src] overloads.</span>")
broadcasting = FALSE
listening = FALSE
for (var/ch_name in channels)
channels[ch_name] = 0
on = FALSE
spawn(200)
if(emped == curremp) //Don't fix it if it's been EMP'd again
emped = 0
if (!istype(src, /obj/item/radio/intercom)) // intercoms will turn back on on their own
on = TRUE
///////////////////////////////
//////////Borg Radios//////////
///////////////////////////////
//Giving borgs their own radio to have some more room to work with -Sieve
/obj/item/radio/borg
name = "cyborg radio"
subspace_switchable = TRUE
dog_fashion = null
/obj/item/radio/borg/Initialize(mapload)
. = ..()
/obj/item/radio/borg/syndicate
syndie = 1
keyslot = new /obj/item/encryptionkey/syndicate
/obj/item/radio/borg/syndicate/Initialize()
. = ..()
set_frequency(FREQ_SYNDICATE)
/obj/item/radio/borg/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
if(keyslot)
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.forceMove(T)
keyslot = null
recalculateChannels()
to_chat(user, "<span class='notice'>You pop out the encryption key in the radio.</span>")
else
to_chat(user, "<span class='warning'>This radio doesn't have any encryption keys!</span>")
else if(istype(W, /obj/item/encryptionkey/))
if(keyslot)
to_chat(user, "<span class='warning'>The radio can't hold another key!</span>")
return
if(!keyslot)
if(!user.transferItemToLoc(W, src))
return
keyslot = W
recalculateChannels()
/obj/item/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
/obj/item/radio/internal
var/obj/item/implant/radio/implant
/obj/item/radio/internal/Initialize(mapload, obj/item/implant/radio/_implant)
. = ..()
implant = _implant
/obj/item/radio/internal/Destroy()
if(implant?.imp_in)
qdel(implant)
else
return ..()
+111 -111
View File
@@ -1,111 +1,111 @@
#define TANK_DISPENSER_CAPACITY 10
/obj/structure/tank_dispenser
name = "tank dispenser"
desc = "A simple yet bulky storage device for gas tanks. Holds up to 10 oxygen tanks and 10 plasma tanks."
icon = 'icons/obj/objects.dmi'
icon_state = "dispenser"
density = TRUE
anchored = TRUE
max_integrity = 300
var/oxygentanks = TANK_DISPENSER_CAPACITY
var/plasmatanks = TANK_DISPENSER_CAPACITY
/obj/structure/tank_dispenser/oxygen
plasmatanks = 0
/obj/structure/tank_dispenser/plasma
oxygentanks = 0
/obj/structure/tank_dispenser/Initialize()
. = ..()
for(var/i in 1 to oxygentanks)
new /obj/item/tank/internals/oxygen(src)
for(var/i in 1 to plasmatanks)
new /obj/item/tank/internals/plasma(src)
update_icon()
/obj/structure/tank_dispenser/update_icon()
cut_overlays()
switch(oxygentanks)
if(1 to 3)
add_overlay("oxygen-[oxygentanks]")
if(4 to TANK_DISPENSER_CAPACITY)
add_overlay("oxygen-4")
switch(plasmatanks)
if(1 to 4)
add_overlay("plasma-[plasmatanks]")
if(5 to TANK_DISPENSER_CAPACITY)
add_overlay("plasma-5")
/obj/structure/tank_dispenser/attackby(obj/item/I, mob/user, params)
var/full
if(istype(I, /obj/item/tank/internals/plasma))
if(plasmatanks < TANK_DISPENSER_CAPACITY)
plasmatanks++
else
full = TRUE
else if(istype(I, /obj/item/tank/internals/oxygen))
if(oxygentanks < TANK_DISPENSER_CAPACITY)
oxygentanks++
else
full = TRUE
else if(istype(I, /obj/item/wrench))
default_unfasten_wrench(user, I, time = 20)
return
else if(user.a_intent != INTENT_HARM)
to_chat(user, "<span class='notice'>[I] does not fit into [src].</span>")
return
else
return ..()
if(full)
to_chat(user, "<span class='notice'>[src] can't hold any more of [I].</span>")
return
if(!user.transferItemToLoc(I, src))
return
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
update_icon()
/obj/structure/tank_dispenser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "tank_dispenser", name, 275, 103, master_ui, state)
ui.open()
/obj/structure/tank_dispenser/ui_data(mob/user)
var/list/data = list()
data["oxygen"] = oxygentanks
data["plasma"] = plasmatanks
return data
/obj/structure/tank_dispenser/ui_act(action, params)
if(..())
return
switch(action)
if("plasma")
var/obj/item/tank/internals/plasma/tank = locate() in src
if(tank && Adjacent(usr))
usr.put_in_hands(tank)
plasmatanks--
. = TRUE
if("oxygen")
var/obj/item/tank/internals/oxygen/tank = locate() in src
if(tank && Adjacent(usr))
usr.put_in_hands(tank)
oxygentanks--
. = TRUE
update_icon()
/obj/structure/tank_dispenser/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
for(var/X in src)
var/obj/item/I = X
I.forceMove(loc)
new /obj/item/stack/sheet/metal (loc, 2)
qdel(src)
#undef TANK_DISPENSER_CAPACITY
#define TANK_DISPENSER_CAPACITY 10
/obj/structure/tank_dispenser
name = "tank dispenser"
desc = "A simple yet bulky storage device for gas tanks. Holds up to 10 oxygen tanks and 10 plasma tanks."
icon = 'icons/obj/objects.dmi'
icon_state = "dispenser"
density = TRUE
anchored = TRUE
max_integrity = 300
var/oxygentanks = TANK_DISPENSER_CAPACITY
var/plasmatanks = TANK_DISPENSER_CAPACITY
/obj/structure/tank_dispenser/oxygen
plasmatanks = 0
/obj/structure/tank_dispenser/plasma
oxygentanks = 0
/obj/structure/tank_dispenser/Initialize()
. = ..()
for(var/i in 1 to oxygentanks)
new /obj/item/tank/internals/oxygen(src)
for(var/i in 1 to plasmatanks)
new /obj/item/tank/internals/plasma(src)
update_icon()
/obj/structure/tank_dispenser/update_icon()
cut_overlays()
switch(oxygentanks)
if(1 to 3)
add_overlay("oxygen-[oxygentanks]")
if(4 to TANK_DISPENSER_CAPACITY)
add_overlay("oxygen-4")
switch(plasmatanks)
if(1 to 4)
add_overlay("plasma-[plasmatanks]")
if(5 to TANK_DISPENSER_CAPACITY)
add_overlay("plasma-5")
/obj/structure/tank_dispenser/attackby(obj/item/I, mob/user, params)
var/full
if(istype(I, /obj/item/tank/internals/plasma))
if(plasmatanks < TANK_DISPENSER_CAPACITY)
plasmatanks++
else
full = TRUE
else if(istype(I, /obj/item/tank/internals/oxygen))
if(oxygentanks < TANK_DISPENSER_CAPACITY)
oxygentanks++
else
full = TRUE
else if(istype(I, /obj/item/wrench))
default_unfasten_wrench(user, I, time = 20)
return
else if(user.a_intent != INTENT_HARM)
to_chat(user, "<span class='notice'>[I] does not fit into [src].</span>")
return
else
return ..()
if(full)
to_chat(user, "<span class='notice'>[src] can't hold any more of [I].</span>")
return
if(!user.transferItemToLoc(I, src))
return
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
update_icon()
/obj/structure/tank_dispenser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "tank_dispenser", name, 275, 103, master_ui, state)
ui.open()
/obj/structure/tank_dispenser/ui_data(mob/user)
var/list/data = list()
data["oxygen"] = oxygentanks
data["plasma"] = plasmatanks
return data
/obj/structure/tank_dispenser/ui_act(action, params)
if(..())
return
switch(action)
if("plasma")
var/obj/item/tank/internals/plasma/tank = locate() in src
if(tank && Adjacent(usr))
usr.put_in_hands(tank)
plasmatanks--
. = TRUE
if("oxygen")
var/obj/item/tank/internals/oxygen/tank = locate() in src
if(tank && Adjacent(usr))
usr.put_in_hands(tank)
oxygentanks--
. = TRUE
update_icon()
/obj/structure/tank_dispenser/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
for(var/X in src)
var/obj/item/I = X
I.forceMove(loc)
new /obj/item/stack/sheet/metal (loc, 2)
qdel(src)
#undef TANK_DISPENSER_CAPACITY