initial commit - cross reference with 5th port - obviously has compile errors

This commit is contained in:
LetterJay
2016-07-03 02:17:19 -05:00
commit 35a1723e98
4355 changed files with 2221257 additions and 0 deletions
+991
View File
@@ -0,0 +1,991 @@
//The advanced pea-green monochrome lcd of tomorrow.
var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda
name = "\improper PDA"
desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
icon = 'icons/obj/pda.dmi'
icon_state = "pda"
item_state = "electronic"
flags = NOBLUDGEON
w_class = 1
slot_flags = SLOT_ID | SLOT_BELT
origin_tech = "programming=2"
//Main variables
var/owner = null // String name of owner
var/default_cartridge = 0 // Access level defined by cartridge
var/obj/item/weapon/cartridge/cartridge = null //current cartridge
var/mode = 0 //Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge.
var/icon_alert = "pda-r" //Icon to be overlayed for message alerts. Taken from the pda icon file.
//Secondary variables
var/scanmode = 0 //1 is medical scanner, 2 is forensics, 3 is reagent scanner.
var/fon = 0 //Is the flashlight function on?
var/f_lum = 3 //Luminosity for the flashlight function
var/silent = 0 //To beep or not to beep, that is the question
var/toff = 0 //If 1, messenger disabled
var/tnote = null //Current Texts
var/last_text //No text spamming
var/last_noise //Also no honk spamming that's bad too
var/ttone = "beep" //The ringtone!
var/lock_code = "" // Lockcode to unlock uplink
var/honkamt = 0 //How many honks left when infected with honk.exe
var/mimeamt = 0 //How many silence left when infected with mime.exe
var/note = "Congratulations, your station has chosen the Thinktronic 5230 Personal Data Assistant!" //Current note in the notepad function
var/notehtml = ""
var/notescanned = 0 // True if what is in the notekeeper was from a paper.
var/cart = "" //A place to stick cartridge menu information
var/detonate = 1 // Can the PDA be blown up?
var/hidden = 0 // Is the PDA hidden from the PDA list?
var/emped = 0
var/obj/item/weapon/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both.
var/ownjob = null //related to above
var/obj/item/device/paicard/pai = null // A slot for a personal AI device
var/image/photo = null //Scanned photo
/obj/item/device/pda/pickup(mob/user)
..()
if(fon)
SetLuminosity(0)
user.AddLuminosity(f_lum)
/obj/item/device/pda/dropped(mob/user)
..()
if(fon)
user.AddLuminosity(-f_lum)
SetLuminosity(f_lum)
/obj/item/device/pda/New()
..()
if(fon)
if(!isturf(loc))
loc.AddLuminosity(f_lum)
SetLuminosity(0)
else
SetLuminosity(f_lum)
PDAs += src
if(default_cartridge)
cartridge = new default_cartridge(src)
new /obj/item/weapon/pen(src)
/obj/item/device/pda/proc/update_label()
name = "PDA-[owner] ([ownjob])" //Name generalisation
/obj/item/device/pda/GetAccess()
if(id)
return id.GetAccess()
else
return ..()
/obj/item/device/pda/GetID()
return id
/obj/item/device/pda/MouseDrop(obj/over_object, src_location, over_location)
var/mob/M = usr
if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src))
return attack_self(M)
return
/obj/item/device/pda/attack_self(mob/user)
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/pda)
assets.send(user)
user.set_machine(src)
if(hidden_uplink && hidden_uplink.active)
hidden_uplink.interact(user)
return
var/dat = "<html><head><title>Personal Data Assistant</title></head><body bgcolor=\"#808000\"><style>a, a:link, a:visited, a:active, a:hover { color: #000000; }img {border-style:none;}</style>"
dat += "<a href='byond://?src=\ref[src];choice=Refresh'><img src=pda_refresh.png> Refresh</a>"
if ((!isnull(cartridge)) && (mode == 0))
dat += " | <a href='byond://?src=\ref[src];choice=Eject'><img src=pda_eject.png> Eject [cartridge]</a>"
if (mode)
dat += " | <a href='byond://?src=\ref[src];choice=Return'><img src=pda_menu.png> Return</a>"
dat += "<br>"
if (!owner)
dat += "Warning: No owner information entered. Please swipe card.<br><br>"
dat += "<a href='byond://?src=\ref[src];choice=Refresh'><img src=pda_refresh.png> Retry</a>"
else
switch (mode)
if (0)
dat += "<h2>PERSONAL DATA ASSISTANT v.1.2</h2>"
dat += "Owner: [owner], [ownjob]<br>"
dat += text("ID: <A href='?src=\ref[src];choice=Authenticate'>[id ? "[id.registered_name], [id.assignment]" : "----------"]")
dat += text("<br><A href='?src=\ref[src];choice=UpdateInfo'>[id ? "Update PDA Info" : ""]</A><br><br>")
dat += "[worldtime2text()]<br>" //:[world.time / 100 % 6][world.time / 100 % 10]"
dat += "[time2text(world.realtime, "MMM DD")] [year_integer+540]"
dat += "<br><br>"
dat += "<h4>General Functions</h4>"
dat += "<ul>"
dat += "<li><a href='byond://?src=\ref[src];choice=1'><img src=pda_notes.png> Notekeeper</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=2'><img src=pda_mail.png> Messenger</a></li>"
if (cartridge)
if (cartridge.access_clown)
dat += "<li><a href='byond://?src=\ref[src];choice=Honk'><img src=pda_honk.png> Honk Synthesizer</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=Trombone'><img src=pda_honk.png> Sad Trombone</a></li>"
if (cartridge.access_manifest)
dat += "<li><a href='byond://?src=\ref[src];choice=41'><img src=pda_notes.png> View Crew Manifest</a></li>"
if(cartridge.access_status_display)
dat += "<li><a href='byond://?src=\ref[src];choice=42'><img src=pda_status.png> Set Status Display</a></li>"
dat += "</ul>"
if (cartridge.access_engine)
dat += "<h4>Engineering Functions</h4>"
dat += "<ul>"
dat += "<li><a href='byond://?src=\ref[src];choice=43'><img src=pda_power.png> Power Monitor</a></li>"
dat += "</ul>"
if (cartridge.access_medical)
dat += "<h4>Medical Functions</h4>"
dat += "<ul>"
dat += "<li><a href='byond://?src=\ref[src];choice=44'><img src=pda_medical.png> Medical Records</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=Medical Scan'><img src=pda_scanner.png> [scanmode == 1 ? "Disable" : "Enable"] Medical Scanner</a></li>"
dat += "</ul>"
if (cartridge.access_security)
dat += "<h4>Security Functions</h4>"
dat += "<ul>"
dat += "<li><a href='byond://?src=\ref[src];choice=45'><img src=pda_cuffs.png> Security Records</A></li>"
dat += "</ul>"
if(cartridge.access_quartermaster)
dat += "<h4>Quartermaster Functions:</h4>"
dat += "<ul>"
dat += "<li><a href='byond://?src=\ref[src];choice=47'><img src=pda_crate.png> Supply Records</A></li>"
dat += "</ul>"
dat += "</ul>"
dat += "<h4>Utilities</h4>"
dat += "<ul>"
if (cartridge)
if(cartridge.bot_access_flags)
dat += "<li><a href='byond://?src=\ref[src];choice=54'><img src=pda_medbot.png> Bots Access</a></li>"
if (cartridge.access_janitor)
dat += "<li><a href='byond://?src=\ref[src];choice=49'><img src=pda_bucket.png> Custodial Locator</a></li>"
if (istype(cartridge.radio, /obj/item/radio/integrated/signal))
dat += "<li><a href='byond://?src=\ref[src];choice=40'><img src=pda_signaler.png> Signaler System</a></li>"
if (cartridge.access_newscaster)
dat += "<li><a href='byond://?src=\ref[src];choice=53'><img src=pda_notes.png> Newscaster Access </a></li>"
if (cartridge.access_reagent_scanner)
dat += "<li><a href='byond://?src=\ref[src];choice=Reagent Scan'><img src=pda_reagent.png> [scanmode == 3 ? "Disable" : "Enable"] Reagent Scanner</a></li>"
if (cartridge.access_engine)
dat += "<li><a href='byond://?src=\ref[src];choice=Halogen Counter'><img src=pda_reagent.png> [scanmode == 4 ? "Disable" : "Enable"] Halogen Counter</a></li>"
if (cartridge.access_atmos)
dat += "<li><a href='byond://?src=\ref[src];choice=Gas Scan'><img src=pda_reagent.png> [scanmode == 5 ? "Disable" : "Enable"] Gas Scanner</a></li>"
if (cartridge.access_remote_door)
dat += "<li><a href='byond://?src=\ref[src];choice=Toggle Door'><img src=pda_rdoor.png> Toggle Remote Door</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=3'><img src=pda_atmos.png> Atmospheric Scan</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=Light'><img src=pda_flashlight.png> [fon ? "Disable" : "Enable"] Flashlight</a></li>"
if (pai)
if(pai.loc != src)
pai = null
else
dat += "<li><a href='byond://?src=\ref[src];choice=pai;option=1'>pAI Device Configuration</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=pai;option=2'>Eject pAI Device</a></li>"
dat += "</ul>"
if (1)
dat += "<h4><img src=pda_notes.png> Notekeeper V2.2</h4>"
dat += "<a href='byond://?src=\ref[src];choice=Edit'>Edit</a><br>"
if(notescanned)
dat += "(This is a scanned image, editing it may cause some text formatting to change.)<br>"
dat += "<HR><font face=\"[PEN_FONT]\">[(!notehtml ? note : notehtml)]</font>"
if (2)
dat += "<h4><img src=pda_mail.png> SpaceMessenger V3.9.6</h4>"
dat += "<a href='byond://?src=\ref[src];choice=Toggle Ringer'><img src=pda_bell.png> Ringer: [silent == 1 ? "Off" : "On"]</a> | "
dat += "<a href='byond://?src=\ref[src];choice=Toggle Messenger'><img src=pda_mail.png> Send / Receive: [toff == 1 ? "Off" : "On"]</a> | "
dat += "<a href='byond://?src=\ref[src];choice=Ringtone'><img src=pda_bell.png> Set Ringtone</a> | "
dat += "<a href='byond://?src=\ref[src];choice=21'><img src=pda_mail.png> Messages</a><br>"
if (istype(cartridge, /obj/item/weapon/cartridge/syndicate))
dat += "<b>[cartridge:shock_charges] detonation charges left.</b><HR>"
if (istype(cartridge, /obj/item/weapon/cartridge/clown))
dat += "<b>[cartridge:honk_charges] viral files left.</b><HR>"
if (istype(cartridge, /obj/item/weapon/cartridge/mime))
dat += "<b>[cartridge:mime_charges] viral files left.</b><HR>"
dat += "<h4><img src=pda_menu.png> Detected PDAs</h4>"
dat += "<ul>"
var/count = 0
if (!toff)
for (var/obj/item/device/pda/P in sortNames(get_viewable_pdas()))
if (P == src)
continue
dat += "<li><a href='byond://?src=\ref[src];choice=Message;target=\ref[P]'>[P]</a>"
if (istype(cartridge, /obj/item/weapon/cartridge/syndicate) && P.detonate)
dat += " (<a href='byond://?src=\ref[src];choice=Detonate;target=\ref[P]'><img src=pda_boom.png>*Detonate*</a>)"
if (istype(cartridge, /obj/item/weapon/cartridge/clown))
dat += " (<a href='byond://?src=\ref[src];choice=Send Honk;target=\ref[P]'><img src=pda_honk.png>*Send Virus*</a>)"
if (istype(cartridge, /obj/item/weapon/cartridge/mime))
dat += " (<a href='byond://?src=\ref[src];choice=Send Silence;target=\ref[P]'>*Send Virus*</a>)"
dat += "</li>"
count++
dat += "</ul>"
if (count == 0)
dat += "None detected.<br>"
else if(cartridge && cartridge.spam_enabled)
dat += "<a href='byond://?src=\ref[src];choice=MessageAll'>Send To All</a>"
if(21)
dat += "<h4><img src=pda_mail.png> SpaceMessenger V3.9.6</h4>"
dat += "<a href='byond://?src=\ref[src];choice=Clear'><img src=pda_blank.png> Clear Messages</a>"
dat += "<h4><img src=pda_mail.png> Messages</h4>"
dat += tnote
dat += "<br>"
if (3)
dat += "<h4><img src=pda_atmos.png> Atmospheric Readings</h4>"
var/turf/T = user.loc
if (isnull(T))
dat += "Unable to obtain a reading.<br>"
else
var/datum/gas_mixture/environment = T.return_air()
var/list/env_gases = environment.gases
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
dat += "Air Pressure: [round(pressure,0.1)] kPa<br>"
if (total_moles)
for(var/id in env_gases)
var/gas_level = env_gases[id][MOLES]/total_moles
if(gas_level > 0)
dat += "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_level*100, 0.01)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>"
dat += "<br>"
else//Else it links to the cart menu proc. Although, it really uses menu hub 4--menu 4 doesn't really exist as it simply redirects to hub.
dat += cart
dat += "</body></html>"
user << browse(dat, "window=pda;size=400x450;border=1;can_resize=1;can_minimize=0")
onclose(user, "pda", src)
/obj/item/device/pda/Topic(href, href_list)
..()
var/mob/living/U = usr
//Looking for master was kind of pointless since PDAs don't appear to have one.
if(usr.canUseTopic(src) && !href_list["close"])
add_fingerprint(U)
U.set_machine(src)
switch(href_list["choice"])
//BASIC FUNCTIONS===================================
if("Refresh")//Refresh, goes to the end of the proc.
if("Return")//Return
if(mode<=9)
mode = 0
else
mode = round(mode/10)
if(mode==4 || mode == 5)//Fix for cartridges. Redirects to hub.
mode = 0
else if(mode >= 40 && mode <= 59)//Fix for cartridges. Redirects to refresh the menu.
cartridge.mode = mode
cartridge.unlock()
if ("Authenticate")//Checks for ID
id_check(U, 1)
if("UpdateInfo")
ownjob = id.assignment
update_label()
if("Eject")//Ejects the cart, only done from hub.
if (!isnull(cartridge))
var/turf/T = loc
if(ismob(T))
T = T.loc
cartridge.loc = T
scanmode = 0
if (cartridge.radio)
cartridge.radio.hostpda = null
cartridge = null
//MENU FUNCTIONS===================================
if("0")//Hub
mode = 0
if("1")//Notes
mode = 1
if("2")//Messenger
mode = 2
if("21")//Read messeges
mode = 21
if("3")//Atmos scan
mode = 3
if("4")//Redirects to hub
mode = 0
//MAIN FUNCTIONS===================================
if("Light")
if(fon)
fon = 0
if(src in U.contents)
U.AddLuminosity(-f_lum)
else
SetLuminosity(0)
else
fon = 1
if(src in U.contents)
U.AddLuminosity(f_lum)
else
SetLuminosity(f_lum)
if("Medical Scan")
if(scanmode == 1)
scanmode = 0
else if((!isnull(cartridge)) && (cartridge.access_medical))
scanmode = 1
if("Reagent Scan")
if(scanmode == 3)
scanmode = 0
else if((!isnull(cartridge)) && (cartridge.access_reagent_scanner))
scanmode = 3
if("Halogen Counter")
if(scanmode == 4)
scanmode = 0
else if((!isnull(cartridge)) && (cartridge.access_engine))
scanmode = 4
if("Honk")
if ( !(last_noise && world.time < last_noise + 20) )
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
last_noise = world.time
if("Trombone")
if ( !(last_noise && world.time < last_noise + 20) )
playsound(loc, 'sound/misc/sadtrombone.ogg', 50, 1)
last_noise = world.time
if("Gas Scan")
if(scanmode == 5)
scanmode = 0
else if((!isnull(cartridge)) && (cartridge.access_atmos))
scanmode = 5
//NOTEKEEPER FUNCTIONS===================================
if ("Edit")
var/n = stripped_multiline_input(U, "Please enter message", name, note)
if (in_range(src, U) && loc == U)
if (mode == 1 && n)
note = n
notehtml = parsepencode(n, U, SIGNFONT)
notescanned = 0
else
U << browse(null, "window=pda")
return
//MESSENGER FUNCTIONS===================================
if("Toggle Messenger")
toff = !toff
if("Toggle Ringer")//If viewing texts then erase them, if not then toggle silent status
silent = !silent
if("Clear")//Clears messages
tnote = null
if("Ringtone")
var/t = input(U, "Please enter new ringtone", name, ttone) as text
if(in_range(src, U) && loc == U)
if(t)
if(hidden_uplink && (trim(lowertext(t)) == trim(lowertext(lock_code))))
hidden_uplink.interact(U)
U << "The PDA softly beeps."
U << browse(null, "window=pda")
src.mode = 0
else
t = copytext(sanitize(t), 1, 20)
ttone = t
else
U << browse(null, "window=pda")
return
if("Message")
var/obj/item/device/pda/P = locate(href_list["target"])
src.create_message(U, P)
if("MessageAll")
src.send_to_all(U)
if("Send Honk")//Honk virus
if(istype(cartridge, /obj/item/weapon/cartridge/clown))//Cartridge checks are kind of unnecessary since everything is done through switch.
var/obj/item/device/pda/P = locate(href_list["target"])//Leaving it alone in case it may do something useful, I guess.
if(!isnull(P))
if (!P.toff && cartridge:honk_charges > 0)
cartridge:honk_charges--
U.show_message("<span class='notice'>Virus sent!</span>", 1)
P.honkamt = (rand(15,20))
else
U << "PDA not found."
else
U << browse(null, "window=pda")
return
if("Send Silence")//Silent virus
if(istype(cartridge, /obj/item/weapon/cartridge/mime))
var/obj/item/device/pda/P = locate(href_list["target"])
if(!isnull(P))
if (!P.toff && cartridge:mime_charges > 0)
cartridge:mime_charges--
U.show_message("<span class='notice'>Virus sent!</span>", 1)
P.silent = 1
P.ttone = "silence"
else
U << "PDA not found."
else
U << browse(null, "window=pda")
return
//SYNDICATE FUNCTIONS===================================
if("Toggle Door")
if(cartridge && cartridge.access_remote_door)
for(var/obj/machinery/door/poddoor/M in machines)
if(M.id == cartridge.remote_door_id)
if(M.density)
M.open()
else
M.close()
if("Detonate")//Detonate PDA
if(istype(cartridge, /obj/item/weapon/cartridge/syndicate))
var/obj/item/device/pda/P = locate(href_list["target"])
if(!isnull(P))
if (!P.toff && cartridge:shock_charges > 0)
cartridge:shock_charges--
var/difficulty = 0
if(P.cartridge)
difficulty += P.cartridge.access_medical
difficulty += P.cartridge.access_security
difficulty += P.cartridge.access_engine
difficulty += P.cartridge.access_clown
difficulty += P.cartridge.access_janitor
difficulty += P.cartridge.access_manifest * 2
else
difficulty += 2
if(prob(difficulty * 15) || (P.hidden_uplink))
U.show_message("<span class='danger'>An error flashes on your [src].</span>", 1)
else
U.show_message("<span class='notice'>Success!</span>", 1)
P.explode()
else
U << "PDA not found."
else
U.unset_machine()
U << browse(null, "window=pda")
return
//pAI FUNCTIONS===================================
if("pai")
switch(href_list["option"])
if("1") // Configure pAI device
pai.attack_self(U)
if("2") // Eject pAI device
var/turf/T = get_turf(src.loc)
if(T)
pai.loc = T
//LINK FUNCTIONS===================================
else//Cartridge menu linking
mode = text2num(href_list["choice"])
if(cartridge)
cartridge.mode = mode
cartridge.unlock()
else//If not in range, can't interact or not using the pda.
U.unset_machine()
U << browse(null, "window=pda")
return
//EXTRA FUNCTIONS===================================
if (mode == 2||mode == 21)//To clear message overlays.
cut_overlays()
if ((honkamt > 0) && (prob(60)))//For clown virus.
honkamt--
playsound(loc, 'sound/items/bikehorn.ogg', 30, 1)
if(U.machine == src && href_list["skiprefresh"]!="1")//Final safety.
attack_self(U)//It auto-closes the menu prior if the user is not in range and so on.
else
U.unset_machine()
U << browse(null, "window=pda")
return
/obj/item/device/pda/proc/remove_id()
if (id)
if (ismob(loc))
var/mob/M = loc
M.put_in_hands(id)
usr << "<span class='notice'>You remove the ID from the [name].</span>"
else
id.loc = get_turf(src)
id = null
/obj/item/device/pda/proc/msg_input(mob/living/U = usr)
var/t = stripped_input(U, "Please enter message", name, null, MAX_MESSAGE_LEN)
if (!t || toff)
return
if (!in_range(src, U) && loc != U)
return
if(!U.canUseTopic(src))
return
if(emped)
t = Gibberish(t, 100)
return t
/obj/item/device/pda/proc/send_message(mob/living/user = usr,list/obj/item/device/pda/targets)
var/message = msg_input(user)
if(!message || !targets.len)
return
if(last_text && world.time < last_text + 5)
return
var/multiple = targets.len > 1
var/datum/data_pda_msg/last_sucessful_msg
for(var/obj/item/device/pda/P in targets)
if(P == src)
continue
var/obj/machinery/message_server/MS = null
MS = can_send(P)
if(MS)
var/datum/data_pda_msg/msg = MS.send_pda_message("[P.owner]","[owner]","[message]",photo)
if(msg)
last_sucessful_msg = msg
if(!multiple)
show_to_sender(msg)
P.show_recieved_message(msg,src)
if(!multiple)
show_to_ghosts(user,msg)
log_pda("[user] (PDA: [src.name]) sent \"[message]\" to [P.name]")
else
if(!multiple)
user << "<span class='notice'>ERROR: Server isn't responding.</span>"
return
photo = null
if(multiple)
show_to_sender(last_sucessful_msg,1)
show_to_ghosts(user,last_sucessful_msg,1)
log_pda("[user] (PDA: [src.name]) sent \"[message]\" to Everyone")
/obj/item/device/pda/proc/show_to_sender(datum/data_pda_msg/msg,multiple = 0)
tnote += "<i><b>&rarr; To [multiple ? "Everyone" : msg.recipient]:</b></i><br>[msg.message][msg.get_photo_ref()]<br>"
/obj/item/device/pda/proc/show_recieved_message(datum/data_pda_msg/msg,obj/item/device/pda/source)
tnote += "<i><b>&larr; From <a href='byond://?src=\ref[src];choice=Message;target=\ref[source]'>[source.owner]</a> ([source.ownjob]):</b></i><br>[msg.message][msg.get_photo_ref()]<br>"
if (!silent)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
audible_message("\icon[src] *[ttone]*", null, 3)
//Search for holder of the PDA.
var/mob/living/L = null
if(loc && isliving(loc))
L = loc
//Maybe they are a pAI!
else
L = get(src, /mob/living/silicon)
if(L && L.stat != UNCONSCIOUS)
L << "\icon[src] <b>Message from [source.owner] ([source.ownjob]), </b>\"[msg.message]\"[msg.get_photo_ref()] (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[source]'>Reply</a>)"
cut_overlays()
add_overlay(image(icon, icon_alert))
/obj/item/device/pda/proc/show_to_ghosts(mob/living/user, datum/data_pda_msg/msg,multiple = 0)
for(var/mob/M in player_list)
if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTPDA))
var/link = FOLLOW_LINK(M, user)
M << "[link] <span class='name'>[msg.sender] </span><span class='game say'>PDA Message</span> --> <span class='name'>[multiple ? "Everyone" : msg.recipient]</span>: <span class='message'>[msg.message][msg.get_photo_ref()]</span></span>"
/obj/item/device/pda/proc/can_send(obj/item/device/pda/P)
if(!P || qdeleted(P) || P.toff)
return null
var/obj/machinery/message_server/useMS = null
if(message_servers)
for (var/obj/machinery/message_server/MS in message_servers)
//PDAs are now dependant on the Message Server.
if(MS.active)
useMS = MS
break
var/datum/signal/signal = src.telecomms_process()
if(!P || qdeleted(P) || P.toff) //in case the PDA or mob gets destroyed during telecomms_process()
return null
var/useTC = 0
if(signal)
if(signal.data["done"])
useTC = 1
var/turf/pos = get_turf(P)
if(pos.z in signal.data["level"])
useTC = 2
if(useTC == 2)
return useMS
else
return null
/obj/item/device/pda/proc/send_to_all(mob/living/U = usr)
send_message(U,get_viewable_pdas())
/obj/item/device/pda/proc/create_message(mob/living/U = usr, obj/item/device/pda/P)
send_message(U,list(P))
/obj/item/device/pda/AltClick()
..()
if(issilicon(usr))
return
if(usr.canUseTopic(src))
if(id)
remove_id()
else
usr << "<span class='warning'>This PDA does not have an ID in it!</span>"
/obj/item/device/pda/verb/verb_remove_id()
set category = "Object"
set name = "Eject ID"
set src in usr
if(issilicon(usr))
return
if (usr.canUseTopic(src))
if(id)
remove_id()
else
usr << "<span class='warning'>This PDA does not have an ID in it!</span>"
/obj/item/device/pda/verb/verb_remove_pen()
set category = "Object"
set name = "Remove Pen"
set src in usr
if(issilicon(usr))
return
if (usr.canUseTopic(src))
var/obj/item/weapon/pen/O = locate() in src
if(O)
if (istype(loc, /mob))
var/mob/M = loc
if(M.get_active_hand() == null)
M.put_in_hands(O)
usr << "<span class='notice'>You remove \the [O] from \the [src].</span>"
return
O.loc = get_turf(src)
else
usr << "<span class='warning'>This PDA does not have a pen in it!</span>"
/obj/item/device/pda/proc/id_check(mob/user, choice as num)//To check for IDs; 1 for in-pda use, 2 for out of pda use.
if(choice == 1)
if (id)
remove_id()
else
var/obj/item/I = user.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
if(!user.unEquip(I))
return 0
I.loc = src
id = I
else
var/obj/item/weapon/card/I = user.get_active_hand()
if (istype(I, /obj/item/weapon/card/id) && I:registered_name)
if(!user.unEquip(I))
return 0
var/obj/old_id = id
I.loc = src
id = I
user.put_in_hands(old_id)
return 1
// access to status display signals
/obj/item/device/pda/attackby(obj/item/C, mob/user, params)
if(istype(C, /obj/item/weapon/cartridge) && !cartridge)
cartridge = C
if(!user.unEquip(C))
return
cartridge.loc = src
user << "<span class='notice'>You insert [cartridge] into [src].</span>"
if(cartridge.radio)
cartridge.radio.hostpda = src
else if(istype(C, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/idcard = C
if(!idcard.registered_name)
user << "<span class='warning'>\The [src] rejects the ID!</span>"
return
if(!owner)
owner = idcard.registered_name
ownjob = idcard.assignment
update_label()
user << "<span class='notice'>Card scanned.</span>"
else
//Basic safety check. If either both objects are held by user or PDA is on ground and card is in hand.
if(((src in user.contents) && (C in user.contents)) || (istype(loc, /turf) && in_range(src, user) && (C in user.contents)) )
if(!id_check(user, 2))
return
user << "<span class='notice'>You put the ID into \the [src]'s slot.</span>"
updateSelfDialog()//Update self dialog on success.
return //Return in case of failed check or when successful.
updateSelfDialog()//For the non-input related code.
else if(istype(C, /obj/item/device/paicard) && !src.pai)
if(!user.unEquip(C))
return
C.loc = src
pai = C
user << "<span class='notice'>You slot \the [C] into [src].</span>"
updateUsrDialog()
else if(istype(C, /obj/item/weapon/pen))
var/obj/item/weapon/pen/O = locate() in src
if(O)
user << "<span class='warning'>There is already a pen in \the [src]!</span>"
else
if(!user.unEquip(C))
return
C.loc = src
user << "<span class='notice'>You slide \the [C] into \the [src].</span>"
else if(istype(C, /obj/item/weapon/photo))
var/obj/item/weapon/photo/P = C
photo = P.img
user << "<span class='notice'>You scan \the [C].</span>"
else
return ..()
/obj/item/device/pda/attack(mob/living/carbon/C, mob/living/user)
if(istype(C))
switch(scanmode)
if(1)
C.visible_message("<span class='alert'>[user] has analyzed [C]'s vitals!</span>")
healthscan(user, C, 1)
add_fingerprint(user)
if(2)
// Unused
if(4)
C.visible_message("<span class='warning'>[user] has analyzed [C]'s radiation levels!</span>")
user.show_message("<span class='notice'>Analyzing Results for [C]:</span>")
if(C.radiation)
user.show_message("\green Radiation Level: \black [C.radiation]")
else
user.show_message("<span class='notice'>No radiation detected.</span>")
/obj/item/device/pda/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
if(!proximity) return
switch(scanmode)
if(3)
if(!isnull(A.reagents))
if(A.reagents.reagent_list.len > 0)
var/reagents_length = A.reagents.reagent_list.len
user << "<span class='notice'>[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found.</span>"
for (var/re in A.reagents.reagent_list)
user << "<span class='notice'>\t [re]</span>"
else
user << "<span class='notice'>No active chemical agents found in [A].</span>"
else
user << "<span class='notice'>No significant chemical agents found in [A].</span>"
if(5)
if (istype(A, /obj/item/weapon/tank))
var/obj/item/weapon/tank/T = A
atmosanalyzer_scan(T.air_contents, user, T)
else if (istype(A, /obj/machinery/portable_atmospherics))
var/obj/machinery/portable_atmospherics/PA = A
atmosanalyzer_scan(PA.air_contents, user, PA)
else if (istype(A, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = A
atmosanalyzer_scan(P.parent.air, user, P)
else if (istype(A, /obj/machinery/power/rad_collector))
var/obj/machinery/power/rad_collector/RC = A
if(RC.loaded_tank)
atmosanalyzer_scan(RC.loaded_tank.air_contents, user, RC)
else if (istype(A, /obj/item/weapon/flamethrower))
var/obj/item/weapon/flamethrower/F = A
if(F.ptank)
atmosanalyzer_scan(F.ptank.air_contents, user, F)
if (!scanmode && istype(A, /obj/item/weapon/paper) && owner)
var/obj/item/weapon/paper/PP = A
if (!PP.info)
user << "<span class='warning'>Unable to scan! Paper is blank.</span>"
return
notehtml = PP.info
note = replacetext(notehtml, "<BR>", "\[br\]")
note = replacetext(note, "<li>", "\[*\]")
note = replacetext(note, "<ul>", "\[list\]")
note = replacetext(note, "</ul>", "\[/list\]")
note = html_encode(note)
notescanned = 1
user << "<span class='notice'>Paper scanned. Saved to PDA's notekeeper.</span>" //concept of scanning paper copyright brainoblivion 2009
/obj/item/device/pda/proc/explode() //This needs tuning.
if(!detonate) return
var/turf/T = get_turf(src)
if (ismob(loc))
var/mob/M = loc
M.show_message("<span class='userdanger'>Your [src] explodes!</span>", 1)
else
visible_message("<span class='danger'>[src] explodes!</span>", "<span class='warning'>You hear a loud *pop*!</span>")
if(T)
T.hotspot_expose(700,125)
if(istype(cartridge, /obj/item/weapon/cartridge/syndicate))
explosion(T, -1, 1, 3, 4)
else
explosion(T, -1, -1, 2, 3)
qdel(src)
return
/obj/item/device/pda/Destroy()
PDAs -= src
return ..()
//AI verb and proc for sending PDA messages.
/mob/living/silicon/ai/proc/cmd_send_pdamesg(mob/user)
var/list/names = list()
var/list/plist = list()
var/list/namecounts = list()
if(user.stat == 2)
return //won't work if dead
if(src.aiPDA.toff)
user << "Turn on your receiver in order to send messages."
return
for (var/obj/item/device/pda/P in get_viewable_pdas())
if (P == src)
continue
else if (P == src.aiPDA)
continue
var/name = P.owner
if (name in names)
namecounts[name]++
name = text("[name] ([namecounts[name]])")
else
names.Add(name)
namecounts[name] = 1
plist[text("[name]")] = P
var/c = input(user, "Please select a PDA") as null|anything in sortList(plist)
if (!c)
return
var/selected = plist[c]
if(aicamera.aipictures.len>0)
var/add_photo = input(user,"Do you want to attach a photo?","Photo","No") as null|anything in list("Yes","No")
if(add_photo=="Yes")
var/datum/picture/Pic = aicamera.selectpicture(aicamera)
src.aiPDA.photo = Pic.fields["img"]
src.aiPDA.create_message(src, selected)
/mob/living/silicon/ai/verb/cmd_toggle_pda_receiver()
set category = "AI Commands"
set name = "PDA - Toggle Sender/Receiver"
if(usr.stat == 2)
return //won't work if dead
if(!isnull(aiPDA))
aiPDA.toff = !aiPDA.toff
usr << "<span class='notice'>PDA sender/receiver toggled [(aiPDA.toff ? "Off" : "On")]!</span>"
else
usr << "You do not have a PDA. You should make an issue report about this."
/mob/living/silicon/ai/verb/cmd_toggle_pda_silent()
set category = "AI Commands"
set name = "PDA - Toggle Ringer"
if(usr.stat == 2)
return //won't work if dead
if(!isnull(aiPDA))
//0
aiPDA.silent = !aiPDA.silent
usr << "<span class='notice'>PDA ringer toggled [(aiPDA.silent ? "Off" : "On")]!</span>"
else
usr << "You do not have a PDA. You should make an issue report about this."
/mob/living/silicon/ai/proc/cmd_show_message_log(mob/user)
if(user.stat == 2)
return //won't work if dead
if(!isnull(aiPDA))
var/HTML = "<html><head><title>AI PDA Message Log</title></head><body>[aiPDA.tnote]</body></html>"
user << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
else
user << "You do not have a PDA. You should make an issue report about this."
//Some spare PDAs in a box
/obj/item/weapon/storage/box/PDAs
name = "spare PDAs"
desc = "A box of spare PDA microcomputers."
icon = 'icons/obj/storage.dmi'
icon_state = "pda"
/obj/item/weapon/storage/box/PDAs/New()
..()
new /obj/item/device/pda(src)
new /obj/item/device/pda(src)
new /obj/item/device/pda(src)
new /obj/item/device/pda(src)
new /obj/item/weapon/cartridge/head(src)
var/newcart = pick( /obj/item/weapon/cartridge/engineering,
/obj/item/weapon/cartridge/security,
/obj/item/weapon/cartridge/medical,
/obj/item/weapon/cartridge/signal/toxins,
/obj/item/weapon/cartridge/quartermaster)
new newcart(src)
// Pass along the pulse to atoms in contents, largely added so pAIs are vulnerable to EMP
/obj/item/device/pda/emp_act(severity)
for(var/atom/A in src)
A.emp_act(severity)
emped += 1
spawn(200 * severity)
emped -= 1
/proc/get_viewable_pdas()
. = list()
// Returns a list of PDAs which can be viewed from another PDA/message monitor.
for(var/obj/item/device/pda/P in PDAs)
if(!P.owner || P.toff || P.hidden) continue
. += P
return .
@@ -0,0 +1,200 @@
//Clown PDA is slippery.
/obj/item/device/pda/clown
name = "clown PDA"
default_cartridge = /obj/item/weapon/cartridge/clown
icon_state = "pda-clown"
desc = "A portable microcomputer by Thinktronic Systems, LTD. The surface is coated with polytetrafluoroethylene and banana drippings."
ttone = "honk"
/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 (ishuman(M) && (M.real_name != src.owner))
if (istype(src.cartridge, /obj/item/weapon/cartridge/clown))
var/obj/item/weapon/cartridge/clown/cart = src.cartridge
if(cart.honk_charges < 5)
cart.honk_charges++
// Special AI/pAI PDAs that cannot explode.
/obj/item/device/pda/ai
icon_state = "NONE"
ttone = "data"
fon = 0
detonate = 0
/obj/item/device/pda/ai/attack_self(mob/user)
if ((honkamt > 0) && (prob(60)))//For clown virus.
honkamt--
playsound(loc, 'sound/items/bikehorn.ogg', 30, 1)
return
/obj/item/device/pda/ai/pai
ttone = "assist"
/obj/item/device/pda/medical
name = "medical PDA"
default_cartridge = /obj/item/weapon/cartridge/medical
icon_state = "pda-medical"
/obj/item/device/pda/viro
name = "virology PDA"
default_cartridge = /obj/item/weapon/cartridge/medical
icon_state = "pda-virology"
/obj/item/device/pda/engineering
name = "engineering PDA"
default_cartridge = /obj/item/weapon/cartridge/engineering
icon_state = "pda-engineer"
/obj/item/device/pda/security
name = "security PDA"
default_cartridge = /obj/item/weapon/cartridge/security
icon_state = "pda-security"
/obj/item/device/pda/detective
name = "detective PDA"
default_cartridge = /obj/item/weapon/cartridge/detective
icon_state = "pda-detective"
/obj/item/device/pda/warden
name = "warden PDA"
default_cartridge = /obj/item/weapon/cartridge/security
icon_state = "pda-warden"
/obj/item/device/pda/janitor
name = "janitor PDA"
default_cartridge = /obj/item/weapon/cartridge/janitor
icon_state = "pda-janitor"
ttone = "slip"
/obj/item/device/pda/toxins
name = "scientist PDA"
default_cartridge = /obj/item/weapon/cartridge/signal/toxins
icon_state = "pda-science"
ttone = "boom"
/obj/item/device/pda/mime
name = "mime PDA"
default_cartridge = /obj/item/weapon/cartridge/mime
icon_state = "pda-mime"
silent = 1
ttone = "silence"
/obj/item/device/pda/heads
default_cartridge = /obj/item/weapon/cartridge/head
icon_state = "pda-hop"
/obj/item/device/pda/heads/hop
name = "head of personnel PDA"
default_cartridge = /obj/item/weapon/cartridge/hop
icon_state = "pda-hop"
/obj/item/device/pda/heads/hos
name = "head of security PDA"
default_cartridge = /obj/item/weapon/cartridge/hos
icon_state = "pda-hos"
/obj/item/device/pda/heads/ce
name = "chief engineer PDA"
default_cartridge = /obj/item/weapon/cartridge/ce
icon_state = "pda-ce"
/obj/item/device/pda/heads/cmo
name = "chief medical officer PDA"
default_cartridge = /obj/item/weapon/cartridge/cmo
icon_state = "pda-cmo"
/obj/item/device/pda/heads/rd
name = "research director PDA"
default_cartridge = /obj/item/weapon/cartridge/rd
icon_state = "pda-rd"
/obj/item/device/pda/captain
name = "captain PDA"
default_cartridge = /obj/item/weapon/cartridge/captain
icon_state = "pda-captain"
detonate = 0
/obj/item/device/pda/cargo
name = "cargo technician PDA"
default_cartridge = /obj/item/weapon/cartridge/quartermaster
icon_state = "pda-cargo"
/obj/item/device/pda/quartermaster
name = "quartermaster PDA"
default_cartridge = /obj/item/weapon/cartridge/quartermaster
icon_state = "pda-qm"
/obj/item/device/pda/shaftminer
name = "shaft miner PDA"
icon_state = "pda-miner"
/obj/item/device/pda/syndicate
default_cartridge = /obj/item/weapon/cartridge/syndicate
icon_state = "pda-syndi"
name = "military PDA"
owner = "John Doe"
hidden = 1
/obj/item/device/pda/chaplain
name = "chaplain PDA"
icon_state = "pda-chaplain"
ttone = "holy"
/obj/item/device/pda/lawyer
name = "lawyer PDA"
default_cartridge = /obj/item/weapon/cartridge/lawyer
icon_state = "pda-lawyer"
ttone = "objection"
/obj/item/device/pda/botanist
name = "botanist PDA"
//default_cartridge = /obj/item/weapon/cartridge/botanist
icon_state = "pda-hydro"
/obj/item/device/pda/roboticist
name = "roboticist PDA"
icon_state = "pda-roboticist"
default_cartridge = /obj/item/weapon/cartridge/roboticist
/obj/item/device/pda/librarian
name = "librarian PDA"
icon_state = "pda-library"
icon_alert = "pda-r-library"
default_cartridge = /obj/item/weapon/cartridge/librarian
desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a WGW-11 series e-reader."
note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!"
silent = 1 //Quiet in the library!
/obj/item/device/pda/clear
name = "clear PDA"
icon_state = "pda-clear"
desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a special edition with a transparent case."
note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!"
/obj/item/device/pda/cook
name = "cook PDA"
icon_state = "pda-cook"
/obj/item/device/pda/bar
name = "bartender PDA"
icon_state = "pda-bartender"
/obj/item/device/pda/atmos
name = "atmospherics PDA"
default_cartridge = /obj/item/weapon/cartridge/atmos
icon_state = "pda-atmos"
/obj/item/device/pda/chemist
name = "chemist PDA"
default_cartridge = /obj/item/weapon/cartridge/chemistry
icon_state = "pda-chemistry"
/obj/item/device/pda/geneticist
name = "geneticist PDA"
default_cartridge = /obj/item/weapon/cartridge/medical
icon_state = "pda-genetics"
+778
View File
@@ -0,0 +1,778 @@
/obj/item/weapon/cartridge
name = "generic cartridge"
desc = "A data cartridge for portable microcomputers."
icon = 'icons/obj/pda.dmi'
icon_state = "cart"
item_state = "electronic"
w_class = 1
var/obj/item/radio/integrated/radio = null
var/access_security = 0
var/access_engine = 0
var/access_atmos = 0
var/access_medical = 0
var/access_manifest = 0
var/access_clown = 0
var/access_mime = 0
var/access_janitor = 0
// var/access_flora = 0
var/access_reagent_scanner = 0
var/access_newscaster = 0
var/access_remote_door = 0 //Control some blast doors remotely!!
var/remote_door_id = ""
var/access_status_display = 0
var/access_quartermaster = 0
var/access_hydroponics = 0
var/bot_access_flags = 0 //Bit flags. Selection: SEC_BOT|MULE_BOT|FLOOR_BOT|CLEAN_BOT|MED_BOT
var/spam_enabled = 0 //Enables "Send to All" Option
var/mode = null
var/menu
var/datum/data/record/active1 = null //General
var/datum/data/record/active2 = null //Medical
var/datum/data/record/active3 = null //Security
var/obj/machinery/computer/monitor/powmonitor = null // Power Monitor
var/list/powermonitors = list()
var/message1 // used for status_displays
var/message2
var/list/stored_data = list()
var/current_channel
var/mob/living/simple_animal/bot/active_bot
var/list/botlist = list()
/obj/item/weapon/cartridge/engineering
name = "\improper Power-ON cartridge"
icon_state = "cart-e"
access_engine = 1
bot_access_flags = FLOOR_BOT
/obj/item/weapon/cartridge/atmos
name = "\improper BreatheDeep cartridge"
icon_state = "cart-a"
access_atmos = 1
bot_access_flags = FLOOR_BOT
/obj/item/weapon/cartridge/medical
name = "\improper Med-U cartridge"
icon_state = "cart-m"
access_medical = 1
bot_access_flags = MED_BOT
/obj/item/weapon/cartridge/chemistry
name = "\improper ChemWhiz cartridge"
icon_state = "cart-chem"
access_reagent_scanner = 1
bot_access_flags = MED_BOT
/obj/item/weapon/cartridge/security
name = "\improper R.O.B.U.S.T. cartridge"
icon_state = "cart-s"
access_security = 1
bot_access_flags = SEC_BOT
/obj/item/weapon/cartridge/detective
name = "\improper D.E.T.E.C.T. cartridge"
icon_state = "cart-s"
access_security = 1
access_medical = 1
access_manifest = 1
bot_access_flags = SEC_BOT
/obj/item/weapon/cartridge/janitor
name = "\improper CustodiPRO cartridge"
desc = "The ultimate in clean-room design."
icon_state = "cart-j"
access_janitor = 1
bot_access_flags = CLEAN_BOT
/obj/item/weapon/cartridge/lawyer
name = "\improper P.R.O.V.E. cartridge"
icon_state = "cart-s"
access_security = 1
spam_enabled = 1
/obj/item/weapon/cartridge/clown
name = "\improper Honkworks 5.0 cartridge"
icon_state = "cart-clown"
access_clown = 1
var/honk_charges = 5
/obj/item/weapon/cartridge/mime
name = "\improper Gestur-O 1000 cartridge"
icon_state = "cart-mi"
access_mime = 1
var/mime_charges = 5
/obj/item/weapon/cartridge/librarian
name = "\improper Lib-Tweet cartridge"
icon_state = "cart-s"
access_newscaster = 1
/*
/obj/item/weapon/cartridge/botanist
name = "\improper Green Thumb v4.20 cartridge"
icon_state = "cart-b"
access_flora = 1
*/
/obj/item/weapon/cartridge/roboticist
name = "\improper B.O.O.P. Remote Control cartridge"
desc = "Packed with heavy duty triple-bot interlink!"
bot_access_flags = FLOOR_BOT|CLEAN_BOT|MED_BOT
/obj/item/weapon/cartridge/signal
name = "generic signaler cartridge"
desc = "A data cartridge with an integrated radio signaler module."
/obj/item/weapon/cartridge/signal/toxins
name = "\improper Signal Ace 2 cartridge"
desc = "Complete with integrated radio signaler!"
icon_state = "cart-tox"
access_reagent_scanner = 1
access_atmos = 1
/obj/item/weapon/cartridge/signal/New()
..()
radio = new /obj/item/radio/integrated/signal(src)
/obj/item/weapon/cartridge/quartermaster
name = "space parts & space vendors cartridge"
desc = "Perfect for the Quartermaster on the go!"
icon_state = "cart-q"
access_quartermaster = 1
bot_access_flags = MULE_BOT
/obj/item/weapon/cartridge/head
name = "\improper Easy-Record DELUXE cartridge"
icon_state = "cart-h"
access_manifest = 1
access_status_display = 1
/obj/item/weapon/cartridge/hop
name = "\improper HumanResources9001 cartridge"
icon_state = "cart-h"
access_manifest = 1
access_status_display = 1
bot_access_flags = MULE_BOT|CLEAN_BOT
access_janitor = 1
access_security = 1
access_newscaster = 1
access_quartermaster = 1
/obj/item/weapon/cartridge/hos
name = "\improper R.O.B.U.S.T. DELUXE cartridge"
icon_state = "cart-hos"
access_manifest = 1
access_status_display = 1
access_security = 1
bot_access_flags = SEC_BOT
/obj/item/weapon/cartridge/ce
name = "\improper Power-On DELUXE cartridge"
icon_state = "cart-ce"
access_manifest = 1
access_status_display = 1
access_engine = 1
access_atmos = 1
bot_access_flags = FLOOR_BOT
/obj/item/weapon/cartridge/cmo
name = "\improper Med-U DELUXE cartridge"
icon_state = "cart-cmo"
access_manifest = 1
access_status_display = 1
access_reagent_scanner = 1
access_medical = 1
bot_access_flags = MED_BOT
/obj/item/weapon/cartridge/rd
name = "\improper Signal Ace DELUXE cartridge"
icon_state = "cart-rd"
access_manifest = 1
access_status_display = 1
access_reagent_scanner = 1
access_atmos = 1
bot_access_flags = FLOOR_BOT|CLEAN_BOT|MED_BOT
/obj/item/weapon/cartridge/rd/New()
..()
radio = new /obj/item/radio/integrated/signal(src)
/obj/item/weapon/cartridge/captain
name = "\improper Value-PAK cartridge"
desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime and Clown)
icon_state = "cart-c"
access_manifest = 1
access_engine = 1
access_security = 1
access_medical = 1
access_reagent_scanner = 1
access_status_display = 1
access_atmos = 1
access_newscaster = 1
access_quartermaster = 1
access_janitor = 1
bot_access_flags = SEC_BOT|MULE_BOT|FLOOR_BOT|CLEAN_BOT|MED_BOT
spam_enabled = 1
/obj/item/weapon/cartridge/captain/New()
..()
radio = new /obj/item/radio/integrated/signal(src)
/obj/item/weapon/cartridge/syndicate
name = "\improper Detomatix cartridge"
icon_state = "cart"
access_remote_door = 1
remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing.
var/shock_charges = 4
/obj/item/weapon/cartridge/proc/unlock()
if (!istype(loc, /obj/item/device/pda))
return
generate_menu()
print_to_host(menu)
return
/obj/item/weapon/cartridge/proc/print_to_host(text)
if (!istype(loc, /obj/item/device/pda))
return
var/obj/item/device/pda/P = loc
P.cart = text
for (var/mob/M in viewers(1, loc.loc))
if (M.client && M.machine == loc)
P.attack_self(M)
return
/obj/item/weapon/cartridge/proc/post_status(command, data1, data2)
var/datum/radio_frequency/frequency = SSradio.return_frequency(1435)
if(!frequency) return
var/datum/signal/status_signal = new
status_signal.source = src
status_signal.transmission_method = 1
status_signal.data["command"] = command
switch(command)
if("message")
status_signal.data["msg1"] = data1
status_signal.data["msg2"] = data2
if("alert")
status_signal.data["picture_state"] = data1
frequency.post_signal(src, status_signal)
/obj/item/weapon/cartridge/proc/generate_menu(mob/user)
switch(mode)
if(40) //signaller
var/obj/item/radio/integrated/signal/S = radio
menu = "<h4><img src=pda_signaler.png> Remote Signaling System</h4>"
menu += {"
<a href='byond://?src=\ref[src];choice=Send Signal'>Send Signal</A><BR>
Frequency:
<a href='byond://?src=\ref[src];choice=Signal Frequency;sfreq=-10'>-</a>
<a href='byond://?src=\ref[src];choice=Signal Frequency;sfreq=-2'>-</a>
[format_frequency(S.frequency)]
<a href='byond://?src=\ref[src];choice=Signal Frequency;sfreq=2'>+</a>
<a href='byond://?src=\ref[src];choice=Signal Frequency;sfreq=10'>+</a><br>
<br>
Code:
<a href='byond://?src=\ref[src];choice=Signal Code;scode=-5'>-</a>
<a href='byond://?src=\ref[src];choice=Signal Code;scode=-1'>-</a>
[S.code]
<a href='byond://?src=\ref[src];choice=Signal Code;scode=1'>+</a>
<a href='byond://?src=\ref[src];choice=Signal Code;scode=5'>+</a><br>"}
if (41) //crew manifest
menu = "<h4><img src=pda_notes.png> Crew Manifest</h4>"
menu += "Entries cannot be modified from this terminal.<br><br>"
if(data_core.general)
for (var/datum/data/record/t in sortRecord(data_core.general))
menu += "[t.fields["name"]] - [t.fields["rank"]]<br>"
menu += "<br>"
if (42) //status displays
menu = "<h4><img src=pda_status.png> Station Status Display Interlink</h4>"
menu += "\[ <A HREF='?src=\ref[src];choice=Status;statdisp=blank'>Clear</A> \]<BR>"
menu += "\[ <A HREF='?src=\ref[src];choice=Status;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
menu += "\[ <A HREF='?src=\ref[src];choice=Status;statdisp=message'>Message</A> \]"
menu += "<ul><li> Line 1: <A HREF='?src=\ref[src];choice=Status;statdisp=setmsg1'>[ message1 ? message1 : "(none)"]</A>"
menu += "<li> Line 2: <A HREF='?src=\ref[src];choice=Status;statdisp=setmsg2'>[ message2 ? message2 : "(none)"]</A></ul><br>"
menu += "\[ Alert: <A HREF='?src=\ref[src];choice=Status;statdisp=alert;alert=default'>None</A> |"
menu += " <A HREF='?src=\ref[src];choice=Status;statdisp=alert;alert=redalert'>Red Alert</A> |"
menu += " <A HREF='?src=\ref[src];choice=Status;statdisp=alert;alert=lockdown'>Lockdown</A> |"
menu += " <A HREF='?src=\ref[src];choice=Status;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR>"
if (43)
menu = "<h4><img src=pda_power.png> Power Monitors - Please select one</h4><BR>"
powmonitor = null
powermonitors = list()
var/powercount = 0
for(var/obj/machinery/computer/monitor/pMon in machines)
if(!(pMon.stat & (NOPOWER|BROKEN)) )
powercount++
powermonitors += pMon
if(!powercount)
menu += "<span class='danger'>No connection<BR></span>"
else
menu += "<FONT SIZE=-1>"
var/count = 0
for(var/obj/machinery/computer/monitor/pMon in powermonitors)
count++
menu += "<a href='byond://?src=\ref[src];choice=Power Select;target=[count]'>[pMon] </a><BR>"
menu += "</FONT>"
if (433)
menu = "<h4><img src=pda_power.png> Power Monitor </h4><BR>"
if(!powmonitor)
menu += "<span class='danger'>No connection<BR></span>"
else
var/list/L = list()
for(var/obj/machinery/power/terminal/term in powmonitor.attached.powernet.nodes)
if(istype(term.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = term.master
L += A
menu += "<PRE>Total power: [powmonitor.attached.powernet.viewavail] W<BR>Total load: [num2text(powmonitor.attached.powernet.viewload,10)] W<BR>"
menu += "<FONT SIZE=-1>"
if(L.len > 0)
menu += "Area Eqp./Lgt./Env. Load Cell<HR>"
var/list/S = list(" Off","AOff"," On", " AOn")
var/list/chg = list("N","C","F")
for(var/obj/machinery/power/apc/A in L)
menu += copytext(add_tspace(A.area.name, 30), 1, 30)
menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(A.lastused_total, 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]<BR>"
menu += "</FONT></PRE>"
if (44) //medical records //This thing only displays a single screen so it's hard to really get the sub-menu stuff working.
menu = "<h4><img src=pda_medical.png> Medical Record List</h4>"
if(data_core.general)
for(var/datum/data/record/R in sortRecord(data_core.general))
menu += "<a href='byond://?src=\ref[src];choice=Medical Records;target=[R.fields["id"]]'>[R.fields["id"]]: [R.fields["name"]]<br>"
menu += "<br>"
if(441)
menu = "<h4><img src=pda_medical.png> Medical Record</h4>"
if(active1 in data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
menu += "Sex: [active1.fields["sex"]]<br>"
menu += "Age: [active1.fields["age"]]<br>"
menu += "Rank: [active1.fields["rank"]]<br>"
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
menu += "Physical Status: [active1.fields["p_stat"]]<br>"
menu += "Mental Status: [active1.fields["m_stat"]]<br>"
else
menu += "<b>Record Lost!</b><br>"
menu += "<br>"
menu += "<h4><img src=pda_medical.png> Medical Data</h4>"
if(active2 in data_core.medical)
menu += "Blood Type: [active2.fields["blood_type"]]<br><br>"
menu += "Minor Disabilities: [active2.fields["mi_dis"]]<br>"
menu += "Details: [active2.fields["mi_dis_d"]]<br><br>"
menu += "Major Disabilities: [active2.fields["ma_dis"]]<br>"
menu += "Details: [active2.fields["ma_dis_d"]]<br><br>"
menu += "Allergies: [active2.fields["alg"]]<br>"
menu += "Details: [active2.fields["alg_d"]]<br><br>"
menu += "Current Diseases: [active2.fields["cdi"]]<br>"
menu += "Details: [active2.fields["cdi_d"]]<br><br>"
menu += "Important Notes: [active2.fields["notes"]]<br>"
else
menu += "<b>Record Lost!</b><br>"
menu += "<br>"
if (45) //security records
menu = "<h4><img src=pda_cuffs.png> Security Record List</h4>"
if(data_core.general)
for (var/datum/data/record/R in sortRecord(data_core.general))
menu += "<a href='byond://?src=\ref[src];choice=Security Records;target=[R.fields["id"]]'>[R.fields["id"]]: [R.fields["name"]]<br>"
menu += "<br>"
if(451)
menu = "<h4><img src=pda_cuffs.png> Security Record</h4>"
if(active1 in data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
menu += "Sex: [active1.fields["sex"]]<br>"
menu += "Age: [active1.fields["age"]]<br>"
menu += "Rank: [active1.fields["rank"]]<br>"
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
menu += "Physical Status: [active1.fields["p_stat"]]<br>"
menu += "Mental Status: [active1.fields["m_stat"]]<br>"
else
menu += "<b>Record Lost!</b><br>"
menu += "<br>"
menu += "<h4><img src=pda_cuffs.png> Security Data</h4>"
if(active3 in data_core.security)
menu += "Criminal Status: [active3.fields["criminal"]]<br>"
menu += text("<BR>\nMinor Crimes:")
menu +={"<table style="text-align:center;" border="1" cellspacing="0" width="100%">
<tr>
<th>Crime</th>
<th>Details</th>
<th>Author</th>
<th>Time Added</th>
</tr>"}
for(var/datum/data/crime/c in active3.fields["mi_crim"])
menu += "<tr><td>[c.crimeName]</td>"
menu += "<td>[c.crimeDetails]</td>"
menu += "<td>[c.author]</td>"
menu += "<td>[c.time]</td>"
menu += "</tr>"
menu += "</table>"
menu += text("<BR>\nMajor Crimes:")
menu +={"<table style="text-align:center;" border="1" cellspacing="0" width="100%">
<tr>
<th>Crime</th>
<th>Details</th>
<th>Author</th>
<th>Time Added</th>
</tr>"}
for(var/datum/data/crime/c in active3.fields["ma_crim"])
menu += "<tr><td>[c.crimeName]</td>"
menu += "<td>[c.crimeDetails]</td>"
menu += "<td>[c.author]</td>"
menu += "<td>[c.time]</td>"
menu += "</tr>"
menu += "</table>"
menu += "<BR>\nImportant Notes:<br>"
menu += "[active3.fields["notes"]]"
else
menu += "<b>Record Lost!</b><br>"
menu += "<br>"
if (47) //quartermaster order records
menu = "<h4><img src=pda_crate.png> Supply Record Interlink</h4>"
menu += "<BR><B>Supply shuttle</B><BR>"
menu += "Location: "
switch(SSshuttle.supply.mode)
if(SHUTTLE_CALL)
menu += "Moving to "
if(SSshuttle.supply.z != ZLEVEL_STATION)
menu += "station"
else
menu += "centcomm"
menu += " ([SSshuttle.supply.timeLeft(600)] Mins)"
else
menu += "At "
if(SSshuttle.supply.z != ZLEVEL_STATION)
menu += "centcomm"
else
menu += "station"
menu += "<BR>Current approved orders: <BR><ol>"
for(var/S in SSshuttle.shoppinglist)
var/datum/supply_order/SO = S
menu += "<li>#[SO.id] - [SO.pack.name] approved by [SO.orderer] [SO.reason ? "([SO.reason])":""]</li>"
menu += "</ol>"
menu += "Current requests: <BR><ol>"
for(var/S in SSshuttle.requestlist)
var/datum/supply_order/SO = S
menu += "<li>#[SO.id] - [SO.pack.name] requested by [SO.orderer]</li>"
menu += "</ol><font size=\"-3\">Upgrade NOW to Space Parts & Space Vendors PLUS for full remote order control and inventory management."
if (49) //janitorial locator
menu = "<h4><img src=pda_bucket.png> Persistent Custodial Object Locator</h4>"
var/turf/cl = get_turf(src)
if (cl)
menu += "Current Orbital Location: <b>\[[cl.x],[cl.y]\]</b>"
menu += "<h4>Located Mops:</h4>"
var/ldat
for (var/obj/item/weapon/mop/M in world)
var/turf/ml = get_turf(M)
if(ml)
if (ml.z != cl.z)
continue
var/direction = get_dir(src, M)
ldat += "Mop - <b>\[[ml.x],[ml.y] ([uppertext(dir2text(direction))])\]</b> - [M.reagents.total_volume ? "Wet" : "Dry"]<br>"
if (!ldat)
menu += "None"
else
menu += "[ldat]"
menu += "<h4>Located Janitorial Cart:</h4>"
ldat = null
for (var/obj/structure/janitorialcart/B in world)
var/turf/bl = get_turf(B)
if(bl)
if (bl.z != cl.z)
continue
var/direction = get_dir(src, B)
ldat += "Cart - <b>\[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\]</b> - Water level: [B.reagents.total_volume]/100<br>"
if (!ldat)
menu += "None"
else
menu += "[ldat]"
menu += "<h4>Located Cleanbots:</h4>"
ldat = null
for (var/mob/living/simple_animal/bot/cleanbot/B in living_mob_list)
var/turf/bl = get_turf(B)
if(bl)
if (bl.z != cl.z)
continue
var/direction = get_dir(src, B)
ldat += "Cleanbot - <b>\[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\]</b> - [B.on ? "Online" : "Offline"]<br>"
if (!ldat)
menu += "None"
else
menu += "[ldat]"
else
menu += "ERROR: Unable to determine current location."
menu += "<br><br><A href='byond://?src=\ref[src];choice=49'>Refresh GPS Locator</a>"
if (53) // Newscaster
menu = "<h4><img src=pda_notes.png> Newscaster Access</h4>"
menu += "<br> Current Newsfeed: <A href='byond://?src=\ref[src];choice=Newscaster Switch Channel'>[current_channel ? current_channel : "None"]</a> <br>"
var/datum/newscaster/feed_channel/current
for(var/datum/newscaster/feed_channel/chan in news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(!current)
menu += "<h5> ERROR : NO CHANNEL FOUND </h5>"
return
var/i = 1
for(var/datum/newscaster/feed_message/msg in current.messages)
menu +="-[msg.returnBody(-1)] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[msg.returnAuthor(-1)]</FONT>\]</FONT><BR>"
menu +="<b><font size=1>[msg.comments.len] comment[msg.comments.len > 1 ? "s" : ""]</font></b><br>"
if(msg.img)
user << browse_rsc(msg.img, "tmp_photo[i].png")
menu +="<img src='tmp_photo[i].png' width = '180'><BR>"
i++
for(var/datum/newscaster/feed_comment/comment in msg.comments)
menu +="<font size=1><small>[comment.body]</font><br><font size=1><small><small><small>[comment.author] [comment.time_stamp]</small></small></small></small></font><br>"
menu += "<br> <A href='byond://?src=\ref[src];choice=Newscaster Message'>Post Message</a>"
if (54) // Beepsky, Medibot, Floorbot, and Cleanbot access
menu = "<h4><img src=pda_medbot.png> Bots Interlink</h4>"
bot_control()
/obj/item/weapon/cartridge/Topic(href, href_list)
..()
if (!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr.unset_machine()
usr << browse(null, "window=pda")
return
var/obj/item/device/pda/pda = loc
switch(href_list["choice"])
if("Medical Records")
active1 = find_record("id", href_list["target"], data_core.general)
if(active1)
active2 = find_record("id", href_list["target"], data_core.medical)
pda.mode = 441
mode = 441
if(!active2)
active1 = null
if("Security Records")
active1 = find_record("id", href_list["target"], data_core.general)
if(active1)
active3 = find_record("id", href_list["target"], data_core.security)
pda.mode = 451
mode = 451
if(!active3)
active1 = null
if("Send Signal")
spawn( 0 )
var/obj/item/radio/integrated/signal/S = radio
S.send_signal("ACTIVATE")
return
if("Signal Frequency")
var/obj/item/radio/integrated/signal/S = radio
var/new_frequency = sanitize_frequency(S.frequency + text2num(href_list["sfreq"]))
S.set_frequency(new_frequency)
if("Signal Code")
var/obj/item/radio/integrated/signal/S = radio
S.code += text2num(href_list["scode"])
S.code = round(S.code)
S.code = min(100, S.code)
S.code = max(1, S.code)
if("Status")
switch(href_list["statdisp"])
if("message")
post_status("message", message1, message2)
if("alert")
post_status("alert", href_list["alert"])
if("setmsg1")
message1 = reject_bad_text(input("Line 1", "Enter Message Text", message1) as text|null, 40)
updateSelfDialog()
if("setmsg2")
message2 = reject_bad_text(input("Line 2", "Enter Message Text", message2) as text|null, 40)
updateSelfDialog()
else
post_status(href_list["statdisp"])
if("Power Select")
var/pnum = text2num(href_list["target"])
powmonitor = powermonitors[pnum]
pda.mode = 433
mode = 433
if("Supply Orders")
pda.mode =47
mode = 47
if("Newscaster Access")
mode = 53
if("Newscaster Message")
var/pda_owner_name = pda.id ? "[pda.id.registered_name] ([pda.id.assignment])" : "Unknown"
var/message = pda.msg_input()
var/datum/newscaster/feed_channel/current
for(var/datum/newscaster/feed_channel/chan in news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(current.locked && current.author != pda_owner_name)
pda.cart += "<h5> ERROR : NOT AUTHORIZED [pda.id ? "" : "- ID SLOT EMPTY"] </h5>"
pda.Topic(null,list("choice"="Refresh"))
return
news_network.SubmitArticle(message,pda.owner,current_channel)
pda.Topic(null,list("choice"=num2text(mode)))
return
if("Newscaster Switch Channel")
current_channel = pda.msg_input()
pda.Topic(null,list("choice"=num2text(mode)))
return
//Bot control section! Viciously ripped from radios for being laggy and terrible.
if(href_list["op"])
switch(href_list["op"])
if("control")
active_bot = locate(href_list["bot"])
if("botlist")
active_bot = null
if("summon") //Args are in the correct order, they are stated here just as an easy reminder.
active_bot.bot_control(command= "summon", user_turf= get_turf(usr), user_access= pda.GetAccess())
else //Forward all other bot commands to the bot itself!
active_bot.bot_control(command= href_list["op"], user= usr)
if(href_list["mule"]) //MULEbots are special snowflakes, and need different args due to how they work.
active_bot.bot_control(command= href_list["mule"], user= usr, pda= 1)
generate_menu(usr)
print_to_host(menu)
/obj/item/weapon/cartridge/proc/bot_control()
var/mob/living/simple_animal/bot/Bot
// if(!SC)
// menu = "Interlink Error - Please reinsert cartridge."
// return
if(active_bot)
menu += "<B>[active_bot]</B><BR> Status: (<A href='byond://?src=\ref[src];op=control;bot=\ref[active_bot]'><img src=pda_refresh.png><i>refresh</i></A>)<BR>"
menu += "Model: [active_bot.model]<BR>"
menu += "Location: [get_area(active_bot)]<BR>"
menu += "Mode: [active_bot.get_mode()]"
if(active_bot.allow_pai)
menu += "<BR>pAI: "
if(active_bot.paicard && active_bot.paicard.pai)
menu += "[active_bot.paicard.pai.name]"
if(active_bot.bot_core.allowed(usr))
menu += " (<A href='byond://?src=\ref[src];op=ejectpai'><i>eject</i></A>)"
else
menu += "<i>none</i>"
//MULEs!
if(active_bot.bot_type == MULE_BOT)
var/mob/living/simple_animal/bot/mulebot/MULE = active_bot
var/atom/Load = MULE.load
menu += "<BR>Current Load: [ !Load ? "<i>none</i>" : "[Load.name] (<A href='byond://?src=\ref[src];mule=unload'><i>unload</i></A>)" ]<BR>"
menu += "Destination: [MULE.destination ? MULE.destination : "<i>None</i>"] (<A href='byond://?src=\ref[src];mule=destination'><i>set</i></A>)<BR>"
menu += "Set ID: [MULE.suffix] <A href='byond://?src=\ref[src];mule=setid'><i> Modify</i></A><BR>"
menu += "Power: [MULE.cell ? MULE.cell.percent() : 0]%<BR>"
menu += "Home: [!MULE.home_destination ? "<i>none</i>" : MULE.home_destination ]<BR>"
menu += "Delivery Reporting: <A href='byond://?src=\ref[src];mule=report'>[MULE.report_delivery ? "(<B>On</B>)": "(<B>Off</B>)"]</A><BR>"
menu += "Auto Return Home: <A href='byond://?src=\ref[src];mule=autoret'>[MULE.auto_return ? "(<B>On</B>)": "(<B>Off</B>)"]</A><BR>"
menu += "Auto Pickup Crate: <A href='byond://?src=\ref[src];mule=autopick'>[MULE.auto_pickup ? "(<B>On</B>)": "(<B>Off</B>)"]</A><BR><BR>" //Hue.
menu += "\[<A href='byond://?src=\ref[src];mule=stop'>Stop</A>\] "
menu += "\[<A href='byond://?src=\ref[src];mule=go'>Proceed</A>\] "
menu += "\[<A href='byond://?src=\ref[src];mule=home'>Return Home</A>\]<BR>"
else
menu += "<BR>\[<A href='byond://?src=\ref[src];op=patroloff'>Stop Patrol</A>\] " //patrolon
menu += "\[<A href='byond://?src=\ref[src];op=patrolon'>Start Patrol</A>\] " //patroloff
menu += "\[<A href='byond://?src=\ref[src];op=summon'>Summon Bot</A>\]<BR>" //summon
menu += "Keep an ID inserted to upload access codes upon summoning."
menu += "<HR><A href='byond://?src=\ref[src];op=botlist'><img src=pda_back.png>Return to bot list</A>"
else
menu += "<BR><A href='byond://?src=\ref[src];op=botlist'><img src=pda_refresh.png>Scan for active bots</A><BR><BR>"
var/turf/current_turf = get_turf(src)
var/zlevel = current_turf.z
var/botcount = 0
for(Bot in living_mob_list) //Git da botz
if(!Bot.on || Bot.z != zlevel || Bot.remote_disabled || !(bot_access_flags & Bot.bot_type)) //Only non-emagged bots on the same Z-level are detected!
continue //Also, the PDA must have access to the bot type.
menu += "<A href='byond://?src=\ref[src];op=control;bot=\ref[Bot]'><b>[Bot.name]</b> ([Bot.get_mode()])<BR>"
botcount++
if(!botcount) //No bots at all? Lame.
menu += "No bots found.<BR>"
return
return menu
@@ -0,0 +1,70 @@
/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/obj/item/device/pda/hostpda = null
var/on = 0 //Are we currently active??
var/menu_message = ""
/obj/item/radio/integrated/New()
..()
if (istype(loc.loc, /obj/item/device/pda))
hostpda = loc.loc
/obj/item/radio/integrated/Destroy()
hostpda = null
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/New()
..()
if(SSradio)
initialize()
/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)
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