//The advanced pea-green monochrome lcd of tomorrow.
GLOBAL_LIST_EMPTY(PDAs)
#define PDA_SCANNER_NONE 0
#define PDA_SCANNER_MEDICAL 1
#define PDA_SCANNER_FORENSICS 2 //unused
#define PDA_SCANNER_REAGENT 3
#define PDA_SCANNER_GAS 5
#define PDA_SPAM_DELAY 2 MINUTES
/obj/item/pda
name = "\improper standard PDA"
desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
icon = 'icons/obj/pda.dmi'
icon_state = "pda"
inhand_icon_state = "electronic"
worn_icon_state = "pda"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
greyscale_config = /datum/greyscale_config/pda
greyscale_colors = "#999875#a92323"
item_flags = NOBLUDGEON
w_class = WEIGHT_CLASS_TINY
slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT
actions_types = list(/datum/action/item_action/toggle_light)
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 100, ACID = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
light_system = MOVABLE_LIGHT_DIRECTIONAL
light_range = 2.3
light_power = 0.6
light_color = "#FFCC66"
light_on = FALSE
custom_materials = list(/datum/material/iron=300, /datum/material/glass=100, /datum/material/plastic=100)
/// String name of owner
var/owner = null
/// Access level defined by cartridge
var/default_cartridge = 0
/// Current cartridge
var/obj/item/cartridge/cartridge = null
/// Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge.
var/mode = 0
/// Icon to be overlayed for message alerts. Taken from the pda icon file.
var/icon_alert = "pda-r"
/// Icon to be overlayed when an active pAI is slotted in.
var/icon_pai = "pai_overlay"
/// Same as above but for an inactive pAI.
var/icon_inactive_pai = "pai_off_overlay"
/**
* This int tells DM which font is currently selected and lets DM know when the last font has been selected
* so that it can cycle back to the first font when "toggle font" is pressed again.
*/
var/font_index = 0
/// The currently selected font.
var/font_mode = "font-family:monospace;"
/// The currently selected background color.
var/background_color = "#808000"
#define FONT_MONO "font-family:monospace;"
#define FONT_SHARE "font-family:\"Share Tech Mono\", monospace;letter-spacing:0px;"
#define FONT_ORBITRON "font-family:\"Orbitron\", monospace;letter-spacing:0px; font-size:15px"
#define FONT_VT "font-family:\"VT323\", monospace;letter-spacing:1px;"
#define MODE_MONO 0
#define MODE_SHARE 1
#define MODE_ORBITRON 2
#define MODE_VT 3
//Secondary variables
var/scanmode = PDA_SCANNER_NONE
var/silent = FALSE //To beep or not to beep, that is the question
var/toff = FALSE //If TRUE, messenger disabled
var/tnote = null //Current Texts
var/last_text //No text spamming
var/last_everyone //No text for everyone spamming
var/last_noise //Also no honk spamming that's bad too
var/ttone = "beep" //The ringtone!
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 = FALSE // True if what is in the notekeeper was from a paper.
var/hidden = FALSE // Is the PDA hidden from the PDA list?
var/emped = FALSE
var/equipped = FALSE //used here to determine if this is the first time its been picked up
var/allow_emojis = FALSE //if the pda can send emojis and actually have them parsed as such
var/sort_by_job = FALSE // If this is TRUE, will sort PDA list by job.
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
///account id of the ID held
var/account_id
var/obj/item/paicard/pai = null // A slot for a personal AI device
var/datum/picture/picture //Scanned photo
var/list/contained_item = list(/obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/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/underline_flag = TRUE //flag for underline
/obj/item/pda/suicide_act(mob/living/carbon/user)
var/deathMessage = msg_input(user)
if (!deathMessage)
deathMessage = "i ded"
user.visible_message(span_suicide("[user] is sending a message to the Grim Reaper! It looks like [user.p_theyre()] trying to commit suicide!"))
tnote += "→ To The Grim Reaper: [deathMessage] "//records a message in their PDA as being sent to the grim reaper
return BRUTELOSS
/obj/item/pda/examine(mob/user)
. = ..()
if(!id && !inserted_item)
return
if(id)
. += span_notice("Alt-click to remove the ID.") //won't name ID on examine in case it's stolen
if(inserted_item && (!isturf(loc)))
. += span_notice("Ctrl-click to remove [inserted_item].") //traitor pens are disguised so we're fine naming them on examine
if((!isnull(cartridge)))
. += span_notice("Ctrl+Shift-click to remove the cartridge.") //won't name cart on examine in case it's Detomatix
/obj/item/pda/Initialize(mapload)
. = ..()
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)
RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, .proc/on_light_eater)
update_appearance()
/obj/item/pda/equipped(mob/user, slot)
. = ..()
if(!equipped)
if(user.client)
background_color = user.client.prefs.read_preference(/datum/preference/color/pda_color)
switch(user.client.prefs.read_preference(/datum/preference/choiced/pda_style))
if(MONO)
font_index = MODE_MONO
font_mode = FONT_MONO
if(SHARE)
font_index = MODE_SHARE
font_mode = FONT_SHARE
if(ORBITRON)
font_index = MODE_ORBITRON
font_mode = FONT_ORBITRON
if(VT)
font_index = MODE_VT
font_mode = FONT_VT
else
font_index = MODE_MONO
font_mode = FONT_MONO
equipped = TRUE
/obj/item/pda/proc/update_label()
name = "PDA-[owner] ([ownjob])" //Name generalisation
/obj/item/pda/GetAccess()
if(id)
return id.GetAccess()
else
return ..()
/obj/item/pda/get_id_examine_strings(mob/user)
. = ..()
if(id)
. += "\The [src] is displaying [id]."
. += id.get_id_examine_strings(user)
/obj/item/pda/GetID()
return id
/obj/item/pda/RemoveID()
return do_remove_id()
/obj/item/pda/InsertID(obj/item/inserting_item)
var/obj/item/card/inserting_id = inserting_item.RemoveID()
if(!inserting_id)
return
insert_id(inserting_id)
if(id == inserting_id)
return TRUE
return FALSE
/obj/item/pda/update_overlays()
. = ..()
var/init_icon = initial(icon)
if(!init_icon)
return
if(id)
. += mutable_appearance(init_icon, "id_overlay")
if(inserted_item)
. += mutable_appearance(init_icon, "insert_overlay")
if(light_on)
. += mutable_appearance(init_icon, "light_overlay")
if(pai)
if(pai.pai)
. += mutable_appearance(init_icon, icon_pai)
else
. += mutable_appearance(init_icon, icon_inactive_pai)
/obj/item/pda/MouseDrop(mob/over, src_location, over_location)
var/mob/M = usr
if((M == over) && usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return attack_self(M)
return ..()
/obj/item/pda/attack_self_tk(mob/user)
to_chat(user, span_warning("The PDA's capacitive touch screen doesn't seem to respond!"))
return COMPONENT_CANCEL_ATTACK_CHAIN
/obj/item/pda/interact(mob/user)
if(!ISADVANCEDTOOLUSER(user))
to_chat(user, span_warning("You don't have the dexterity to do this!"))
return
..()
var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/simple/pda)
assets.send(user)
var/datum/asset/spritesheet/emoji_s = get_asset_datum(/datum/asset/spritesheet/chat)
emoji_s.send(user) //Already sent by chat but no harm doing this
user.set_machine(src)
var/dat = "
")
dat += "[station_time_timestamp()] " //:[world.time / 100 % 6][world.time / 100 % 10]"
dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer+540] "
dat += "It has been [ROUND_TIME] since the emergency shuttle was last called."
dat += "
"
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 += "
"
if (count == 0)
dat += "None detected. "
else if(cartridge?.spam_enabled)
dat += "Send To All"
if(6)
dat += "
[PDAIMG(mail)] ExperTrak® Skill Tracker V4.26.2
"
dat += "Thank you for choosing ExperTrak® brand software! ExperTrak® inc. is proud to be a Nanotrasen employee expertise and effectiveness department subsidary!"
dat += "
This software is designed to track and monitor your skill development as a Nanotrasen employee. Your job performance across different fields has been quantified and categorized below. "
var/datum/mind/targetmind = user.mind
if(targetmind)
for (var/type in GLOB.skill_types)
var/datum/skill/S = GetSkillRef(type)
var/lvl_num = targetmind.get_skill_level(type)
var/lvl_name = uppertext(targetmind.get_skill_level_name(type))
var/exp = targetmind.get_skill_exp(type)
var/xp_prog_to_level = targetmind.exp_needed_to_level_up(type)
var/xp_req_to_level = 0
if (xp_prog_to_level)//is it even possible to level up?
xp_req_to_level = SKILL_EXP_LIST[lvl_num+1] - SKILL_EXP_LIST[lvl_num]
dat += "[S.name]"
dat += " [S.desc]"
dat += "
EMPLOYEE SKILL LEVEL: [lvl_name]"
if (exp && xp_req_to_level)
var/progress_percent = (xp_req_to_level-xp_prog_to_level)/xp_req_to_level
var/overall_percent = exp / SKILL_EXP_LIST[length(SKILL_EXP_LIST)]
dat += " PROGRESS TO NEXT SKILL LEVEL:"
dat += " " + num2loadingbar(progress_percent) + "([progress_percent*100])%"
dat += " OVERALL DEVELOPMENT PROGRESS:"
dat += " " + num2loadingbar(overall_percent) + "([overall_percent*100])%"
if (lvl_num >= length(SKILL_EXP_LIST) && !(type in targetmind.skills_rewarded))
dat += " Contact the Professional [S.title] Association"
dat += "