From 926589fd585a4d5c4dfd4154b4d5dff14d52c49c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 27 Jun 2017 05:11:06 -0500 Subject: [PATCH] Update PDA.dm --- code/game/objects/items/devices/PDA/PDA.dm | 1867 ++++++++++---------- 1 file changed, 934 insertions(+), 933 deletions(-) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 561e142fce..081d41847f 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1,936 +1,937 @@ - -//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" - flags = NOBLUDGEON - 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/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/icon/photo //Scanned photo - - var/list/contained_item = list(/obj/item/weapon/pen, /obj/item/toy/crayon, /obj/item/weapon/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/New() - ..() - if(fon) - set_light(f_lum) - - GLOB.PDAs += src - if(default_cartridge) - cartridge = new default_cartridge(src) - inserted_item = new /obj/item/weapon/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) - 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_engine) - dat += "

Engineering Functions

" - dat += "" - if (cartridge.access_medical) - dat += "

Medical Functions

" - dat += "" - if (cartridge.access_security) - dat += "

Security Functions

" - dat += "" - if(cartridge.access_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/weapon/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 - fon = 1 - set_light(2.3) - update_icon() - 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 - if("Drone Phone") - var/area/A = get_area(U) - var/alert_s = input(U,"Alert severity level","Ping Drones",null) as null|anything in list("Low","Medium","High","Critical") - if(A && alert_s) - var/msg = "NON-DRONE PING: [U.name]: [alert_s] priority alert in [A.name]!" - _alert_drones(msg, TRUE) - 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_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 = text2num(href_list["choice"]) - else//If not in range, can't interact or not using the pda. - U.unset_machine() - U << browse(null, "window=pda") - return - -//EXTRA FUNCTIONS=================================== - +//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" + flags = NOBLUDGEON + 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/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/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/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/icon/photo //Scanned photo + + var/list/contained_item = list(/obj/item/weapon/pen, /obj/item/toy/crayon, /obj/item/weapon/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/weapon/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) + 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/weapon/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 + fon = 1 + set_light(2.3) + 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/area/A = get_area(U) + var/alert_s = input(U,"Alert severity level","Ping Drones",null) as null|anything in list("Low","Medium","High","Critical") + if(A && alert_s) + var/msg = "NON-DRONE PING: [U.name]: [alert_s] priority alert in [A.name]!" + _alert_drones(msg, TRUE) + 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 = text2num(href_list["choice"]) + + 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_pda("[user] (PDA: [src.name]) sent \"[message]\" to [P.name]") - 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_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 += "→ 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("[bicon(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, "[\bicon(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/weapon/card/id/I) - if(!I) - if(id) - remove_id() - return 1 - else - var/obj/item/weapon/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/weapon/cartridge) && !cartridge) - if(!user.transferItemToLoc(C, src)) - return - cartridge = C + 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_pda("[user] (PDA: [src.name]) sent \"[message]\" to [P.name]") + 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_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 += "→ 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("[bicon(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, "[\bicon(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/weapon/card/id/I) + if(!I) + if(id) + remove_id() + return 1 + else + var/obj/item/weapon/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/weapon/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/weapon/card/id)) - var/obj/item/weapon/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/weapon/photo)) - var/obj/item/weapon/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/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) - 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(!detonate) 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/weapon/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(id) - qdel(id) - id = null - if(cartridge) - qdel(cartridge) - cartridge = null - if(pai) - qdel(pai) - pai = null - if(inserted_item) - qdel(inserted_item) - inserted_item = null - 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(user.stat == 2) - return //won't work if dead - - 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"] - 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 - 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 == 2) - 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(user.stat == 2) - return //won't work if dead - 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 + to_chat(user, "You insert [cartridge] into [src].") + update_icon() + + else if(istype(C, /obj/item/weapon/card/id)) + var/obj/item/weapon/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/weapon/photo)) + var/obj/item/weapon/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/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) + 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/weapon/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(id) + qdel(id) + id = null + if(cartridge) + qdel(cartridge) + cartridge = null + if(pai) + qdel(pai) + pai = null + if(inserted_item) + qdel(inserted_item) + inserted_item = null + 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(user.stat == 2) + return //won't work if dead + + 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"] + 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 + 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 == 2) + 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(user.stat == 2) + return //won't work if dead + 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