//The advanced pea-green monochrome lcd of tomorrow. GLOBAL_LIST_EMPTY(PDAs) /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" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' flags_1 = NOBLUDGEON_1 w_class = WEIGHT_CLASS_TINY slot_flags = SLOT_ID | SLOT_BELT origin_tech = "programming=2" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100) resistance_flags = FIRE_PROOF | ACID_PROOF //Main variables var/owner = null // String name of owner var/default_cartridge = 0 // Access level defined by cartridge var/obj/item/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 = 2.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/detonatable = TRUE // Can the PDA be blown up? var/hidden = 0 // Is the PDA hidden from the PDA list? var/emped = 0 var/obj/item/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/icon/photo //Scanned photo var/list/contained_item = list(/obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/device/flashlight/pen, /obj/item/clothing/mask/cigarette) var/obj/item/inserted_item //Used for pen, crayon, and lipstick insertion or removal. Same as above. var/overlays_x_offset = 0 //x offset to use for certain overlays /obj/item/device/pda/Initialize() . = ..() if(fon) set_light(f_lum) GLOB.PDAs += src if(default_cartridge) cartridge = new default_cartridge(src) if(inserted_item) inserted_item = new inserted_item(src) else inserted_item = new /obj/item/pen(src) update_icon() /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/update_icon() cut_overlays() var/mutable_appearance/overlay = new() overlay.pixel_x = overlays_x_offset if(id) overlay.icon_state = "id_overlay" add_overlay(new /mutable_appearance(overlay)) if(inserted_item) overlay.icon_state = "insert_overlay" add_overlay(new /mutable_appearance(overlay)) if(fon) overlay.icon_state = "light_overlay" add_overlay(new /mutable_appearance(overlay)) if(pai) if(pai.pai) overlay.icon_state = "pai_overlay" add_overlay(new /mutable_appearance(overlay)) else overlay.icon_state = "pai_off_overlay" add_overlay(new /mutable_appearance(overlay)) /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) if(!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") return 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 = "Personal Data Assistant" dat += " Refresh" if ((!isnull(cartridge)) && (mode == 0)) dat += " | Eject [cartridge]" if (mode) dat += " | Return" dat += "
" if (!owner) dat += "Warning: No owner information entered. Please swipe card.

" dat += " Retry" else switch (mode) if (0) dat += "

PERSONAL DATA ASSISTANT v.1.2

" dat += "Owner: [owner], [ownjob]
" dat += text("ID: [id ? "[id.registered_name], [id.assignment]" : "----------"]") dat += text("
[id ? "Update PDA Info" : ""]

") dat += "[worldtime2text()]
" //:[world.time / 100 % 6][world.time / 100 % 10]" dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer+540]" dat += "

" dat += "

General Functions

" dat += "" if (cartridge.access & CART_ENGINE) dat += "

Engineering Functions

" dat += "" if (cartridge.access & CART_MEDICAL) dat += "

Medical Functions

" dat += "" if (cartridge.access & CART_SECURITY) dat += "

Security Functions

" dat += "" if(cartridge.access & CART_QUARTERMASTER) dat += "

Quartermaster Functions:

" dat += "" dat += "" dat += "

Utilities

" dat += "" if (1) dat += "

Notekeeper V2.2

" dat += "Edit
" if(notescanned) dat += "(This is a scanned image, editing it may cause some text formatting to change.)
" dat += "
[(!notehtml ? note : notehtml)]" if (2) dat += "

SpaceMessenger V3.9.6

" dat += " Ringer: [silent == 1 ? "Off" : "On"] | " dat += " Send / Receive: [toff == 1 ? "Off" : "On"] | " dat += " Set Ringtone | " dat += " Messages
" if(cartridge) dat += cartridge.message_header() dat += "

Detected PDAs

" dat += "" if (count == 0) dat += "None detected.
" else if(cartridge && cartridge.spam_enabled) dat += "Send To All" if(21) dat += "

SpaceMessenger V3.9.6

" dat += " Clear Messages" dat += "

Messages

" dat += tnote dat += "
" if (3) dat += "

Atmospheric Readings

" var/turf/T = user.loc if (isnull(T)) dat += "Unable to obtain a reading.
" 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
" 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)]%
" dat += "Temperature: [round(environment.temperature-T0C)]°C
" dat += "
" 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 += cartridge.generate_menu() dat += "" 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 if ("Authenticate")//Checks for ID id_check(U) if("UpdateInfo") ownjob = id.assignment if(istype(id, /obj/item/card/id/syndicate)) owner = id.registered_name update_label() if("Eject")//Ejects the cart, only done from hub. if (!isnull(cartridge)) U.put_in_hands(cartridge) to_chat(U, "You remove [cartridge] from [src].") scanmode = 0 cartridge.host_pda = null cartridge = null update_icon() //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 set_light(0) else if(f_lum) fon = 1 set_light(f_lum) update_icon() if("Medical Scan") if(scanmode == 1) scanmode = 0 else if((!isnull(cartridge)) && (cartridge.access & CART_MEDICAL)) scanmode = 1 if("Reagent Scan") if(scanmode == 3) scanmode = 0 else if((!isnull(cartridge)) && (cartridge.access & CART_REAGENT_SCANNER)) scanmode = 3 if("Halogen Counter") if(scanmode == 4) scanmode = 0 else if((!isnull(cartridge)) && (cartridge.access & CART_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 & CART_ATMOS)) scanmode = 5 if("Drone Phone") var/alert_s = input(U,"Alert severity level","Ping Drones",null) as null|anything in list("Low","Medium","High","Critical") var/area/A = get_area(U) if(A && alert_s && !QDELETED(U)) var/msg = "NON-DRONE PING: [U.name]: [alert_s] priority alert in [A.name]!" _alert_drones(msg, TRUE, U) to_chat(U, msg) //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 && t) if(hidden_uplink && (trim(lowertext(t)) == trim(lowertext(lock_code)))) hidden_uplink.interact(U) to_chat(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("cart") if(cartridge) cartridge.special(U, href_list) else U << browse(null, "window=pda") return //SYNDICATE FUNCTIONS=================================== if("Toggle Door") if(cartridge && cartridge.access & CART_REMOTE_DOOR) for(var/obj/machinery/door/poddoor/M in GLOB.machines) if(M.id == cartridge.remote_door_id) if(M.density) M.open() else M.close() //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 = max(text2num(href_list["choice"]), 0) 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. update_icon() 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) to_chat(usr, "You remove the ID from the [name].") else id.loc = get_turf(src) id = null update_icon() /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_talk(user,"[key_name(user)] (PDA: [name]) sent \"[message]\" to [key_name(P,null,TRUE)]",LOGPDA) else if(!multiple) to_chat(user, "ERROR: Server isn't responding.") return photo = null if(multiple) show_to_sender(last_sucessful_msg,1) show_to_ghosts(user,last_sucessful_msg,1) log_talk(user,"[user] (PDA: [name]) sent \"[message]\" to Everyone",LOGPDA) /obj/item/device/pda/proc/show_to_sender(datum/data_pda_msg/msg,multiple = 0) tnote += "→ To [multiple ? "Everyone" : msg.recipient]:
[msg.message][msg.get_photo_ref()]
" /obj/item/device/pda/proc/show_recieved_message(datum/data_pda_msg/msg,obj/item/device/pda/source) tnote += "← From [source.owner] ([source.ownjob]):
[msg.message][msg.get_photo_ref()]
" if (!silent) playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) audible_message("[icon2html(src, hearers(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) var/hrefstart var/hrefend if (isAI(L)) hrefstart = "" hrefend = "" to_chat(L, "[icon2html(src)] Message from [hrefstart][source.owner] ([source.ownjob])[hrefend], \"[msg.message]\"[msg.get_photo_ref()] (Reply)") update_icon() add_overlay(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 GLOB.player_list) if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTPDA)) var/link = FOLLOW_LINK(M, user) to_chat(M, "[link] [msg.sender] PDA Message --> [multiple ? "Everyone" : msg.recipient]: [msg.message][msg.get_photo_ref()]") /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(GLOB.message_servers) for (var/obj/machinery/message_server/MS in GLOB.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 remove_pen() /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 to_chat(usr, "This PDA does not have an ID in it!") /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)) remove_pen() /obj/item/device/pda/proc/remove_pen() if(inserted_item) if(ismob(loc)) var/mob/M = loc M.put_in_hands(inserted_item) else inserted_item.forceMove(get_turf(src)) to_chat(usr, "You remove \the [inserted_item] from \the [src].") inserted_item = null update_icon() else to_chat(usr, "This PDA does not have a pen in it!") //trying to insert or remove an id /obj/item/device/pda/proc/id_check(mob/user, obj/item/card/id/I) if(!I) if(id) remove_id() return 1 else var/obj/item/card/id/C = user.get_active_held_item() if(istype(C)) I = C if(I && I.registered_name) if(!user.transferItemToLoc(I, src)) return 0 var/obj/old_id = id id = I if(old_id) user.put_in_hands(old_id) update_icon() return 1 // access to status display signals /obj/item/device/pda/attackby(obj/item/C, mob/user, params) if(istype(C, /obj/item/cartridge) && !cartridge) if(!user.transferItemToLoc(C, src)) return cartridge = C cartridge.host_pda = src to_chat(user, "You insert [cartridge] into [src].") update_icon() else if(istype(C, /obj/item/card/id)) var/obj/item/card/id/idcard = C if(!idcard.registered_name) to_chat(user, "\The [src] rejects the ID!") return if(!owner) owner = idcard.registered_name ownjob = idcard.assignment update_label() to_chat(user, "Card scanned.") 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) || (isturf(loc) && in_range(src, user))) && (C in user.contents)) if(!id_check(user, idcard)) return to_chat(user, "You put the ID into \the [src]'s slot.") 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.transferItemToLoc(C, src)) return pai = C to_chat(user, "You slot \the [C] into [src].") update_icon() updateUsrDialog() else if(is_type_in_list(C, contained_item)) //Checks if there is a pen if(inserted_item) to_chat(user, "There is already \a [inserted_item] in \the [src]!") else if(!user.transferItemToLoc(C, src)) return to_chat(user, "You slide \the [C] into \the [src].") inserted_item = C update_icon() else if(istype(C, /obj/item/photo)) var/obj/item/photo/P = C photo = P.img to_chat(user, "You scan \the [C].") else if(hidden_uplink && hidden_uplink.active) hidden_uplink.attackby(C, user, params) else return ..() /obj/item/device/pda/attack(mob/living/carbon/C, mob/living/user) if(istype(C)) switch(scanmode) if(1) C.visible_message("[user] has analyzed [C]'s vitals!") healthscan(user, C, 1) add_fingerprint(user) if(2) // Unused if(4) C.visible_message("[user] has analyzed [C]'s radiation levels!") user.show_message("Analyzing Results for [C]:") if(C.radiation) user.show_message("\green Radiation Level: \black [C.radiation]") else user.show_message("No radiation detected.") /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 to_chat(user, "[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found.") for (var/re in A.reagents.reagent_list) to_chat(user, "\t [re]") else to_chat(user, "No active chemical agents found in [A].") else to_chat(user, "No significant chemical agents found in [A].") if(5) if (istype(A, /obj/item/tank)) var/obj/item/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/flamethrower)) var/obj/item/flamethrower/F = A if(F.ptank) atmosanalyzer_scan(F.ptank.air_contents, user, F) if (!scanmode && istype(A, /obj/item/paper) && owner) var/obj/item/paper/PP = A if (!PP.info) to_chat(user, "Unable to scan! Paper is blank.") return notehtml = PP.info note = replacetext(notehtml, "
", "\[br\]") note = replacetext(note, "
  • ", "\[*\]") note = replacetext(note, "", "\[/list\]") note = html_encode(note) notescanned = 1 to_chat(user, "Paper scanned. Saved to PDA's notekeeper." ) /obj/item/device/pda/proc/explode() //This needs tuning. if(!detonatable) return var/turf/T = get_turf(src) if (ismob(loc)) var/mob/M = loc M.show_message("Your [src] explodes!", 1) else visible_message("[src] explodes!", "You hear a loud *pop*!") if(T) T.hotspot_expose(700,125) if(istype(cartridge, /obj/item/cartridge/virus/syndicate)) explosion(T, -1, 1, 3, 4) else explosion(T, -1, -1, 2, 3) qdel(src) return /obj/item/device/pda/Destroy() GLOB.PDAs -= src if(istype(id)) QDEL_NULL(id) if(istype(cartridge)) QDEL_NULL(cartridge) if(istype(pai)) QDEL_NULL(pai) if(istype(inserted_item)) QDEL_NULL(inserted_item) return ..() //AI verb and proc for sending PDA messages. /mob/living/silicon/ai/proc/cmd_send_pdamesg(mob/user) var/list/plist = list() var/list/namecounts = list() if(src.aiPDA.toff) to_chat(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 plist[avoid_assoc_duplicate_keys(P.owner, namecounts)] = 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"] if(incapacitated()) return 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 == DEAD) return //won't work if dead if(!isnull(aiPDA)) aiPDA.toff = !aiPDA.toff to_chat(usr, "PDA sender/receiver toggled [(aiPDA.toff ? "Off" : "On")]!") else to_chat(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 == DEAD) return //won't work if dead if(!isnull(aiPDA)) //0 aiPDA.silent = !aiPDA.silent to_chat(usr, "PDA ringer toggled [(aiPDA.silent ? "Off" : "On")]!") else to_chat(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(incapacitated()) return if(!isnull(aiPDA)) var/HTML = "AI PDA Message Log[aiPDA.tnote]" user << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") else to_chat(user, "You do not have a PDA. You should make an issue report about this.") // 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 GLOB.PDAs) if(!P.owner || P.toff || P.hidden) continue . += P