/datum/pda_app/messenger name = "Messenger" desc = "Allows the PDA to send messages, images and funds to other PDAs, if possible." price = 0 icon = "pda_mail" var/silent = 0 //To beep or not to beep, that is the question var/toff = 0 //If 1, messenger disabled var/list/tnote = list() //Current Texts var/last_text //No text spamming var/ttone = "beep" //The ringtone! var/list/icon/imglist = list() // Viewable message photos var/list/incoming_transactions = list() /datum/pda_app/messenger/get_dat(var/mob/user) var/dat = "" switch(mode) if (0) dat += {"

SpaceMessenger V3.9.4

Ringer: [silent == 1 ? "Off" : "On"] | Send / Receive: [toff == 1 ? "Off" : "On"] | Set Ringtone | Messages"} dat += "
" for(var/datum/pda_app/cart/virus/V in pda_device.applications) dat += "[V.charges] [V.virus_type] left.
" dat += {"

Detected PDAs

" if (count == 0) dat += "None detected.
" if(1) dat += {"

SpaceMessenger V3.9.4

Clear Messages

Messages

"} for(var/note in tnote) dat += tnote[note] var/icon/img = imglist[note] if(img) user << browse_rsc(ImagePDA(img), "tmp_photo_[note].png") dat += "
" dat += "
" return dat /datum/pda_app/messenger/Topic(href, href_list) if(..()) return var/mob/living/U = usr switch(href_list["choice"]) if("1") mode = 1 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 imglist.Cut() tnote.Cut() if("Ringtone") var/t = input(U, "Please enter new ringtone", name, ttone) as text if (pda_device.loc == U) if (t) if(INVOKE_EVENT(pda_device, /event/pda_change_ringtone, "user" = U, "new_ringtone" = t)) to_chat(U, "The PDA softly beeps.") U << browse(null, "window=pda") src.mode = 0 else t = copytext(sanitize(t), 1, 20) ttone = t return else U << browse(null, "window=pda") return if("Message") var/obj/item/device/pda/P = locate(href_list["target"]) P.overlays.len = 0 // replying to a message from chat clears alert P.update_icon() src.create_message(U, P) if("viewPhoto") var/obj/item/weapon/photo/PH = locate(href_list["image"]) PH.show(U) if("transferFunds") if(!pda_device.id) return var/obj/machinery/message_server/useMS = null if(message_servers) for (var/obj/machinery/message_server/MS in message_servers) if(MS.is_functioning()) useMS = MS break if(!useMS) to_chat(usr, "[bicon(pda_device)]The PDA's screen flashes, 'Error, Messaging server is not responding.'") return var/obj/item/device/pda/P = locate(href_list["target"]) var/datum/signal/signal = pda_device.telecomms_process() 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) // only send the message if it's stable to_chat(usr, "[bicon(pda_device)]The PDA's screen flashes, 'Error, Unable to receive signal from local subspace comms. PDA outside of comms range.'") return if(useTC != 2) // Does our recepient have a broadcaster on their level? to_chat(usr, "[bicon(pda_device)]The PDA's screen flashes, 'Error, Unable to receive handshake signal from recipient PDA. Recipient PDA outside of comms range.'") return var/amount = round(input("How much money do you wish to transfer to [P.owner]?", "Money Transfer", 0) as num) if(!amount || (amount < 0) || (pda_device.id.virtual_wallet.money <= 0)) to_chat(usr, "[bicon(pda_device)]The PDA's screen flashes, 'Invalid value.'") return if(amount > pda_device.id.virtual_wallet.money) amount = pda_device.id.virtual_wallet.money var/datum/pda_app/messenger/P_app = locate(/datum/pda_app/messenger) in P.applications if(P_app) switch(P_app.receive_funds(pda_device.owner,amount,name)) if(1) to_chat(usr, "[bicon(pda_device)]The PDA's screen flashes, 'Transaction complete!'") if(2) to_chat(usr, "[bicon(pda_device)]The PDA's screen flashes, 'Transaction complete! The recipient will earn the funds once he enters his ID in his PDA.'") else to_chat(usr, "[bicon(pda_device)]The PDA's screen flashes, 'Error, transaction canceled'") return else to_chat(usr, "[bicon(pda_device)]The PDA's screen flashes, 'Error, transaction canceled'") return pda_device.id.virtual_wallet.money -= amount new /datum/transaction(pda_device.id.virtual_wallet, "Money transfer", "-[amount]", pda_device.name, P.owner) refresh_pda() //Receive money transferred from another PDA /datum/pda_app/messenger/proc/receive_funds(var/creditor_name,var/arbitrary_sum,var/other_pda) var/datum/pda_app/balance_check/app = locate(/datum/pda_app/balance_check) in pda_device.applications if(!app.linked_db) app.reconnect_database() if(!app.linked_db || !app.linked_db.activated || app.linked_db.stat & (BROKEN|NOPOWER)) return 0 //This sends its own error message var/turf/U = get_turf(pda_device) if(!silent) playsound(U, 'sound/machines/twobeep.ogg', 50, 1) for (var/mob/O in hearers(3, U)) if(!silent) O.show_message(text("[bicon(pda_device)] *[ttone]*")) var/mob/living/L = null if(pda_device.loc && isliving(pda_device.loc)) L = pda_device.loc else L = get_holder_of_type(pda_device, /mob/living/silicon) if(L) to_chat(L, "[bicon(pda_device)] Money transfer from [creditor_name] ([arbitrary_sum]$) [pda_device.id ? "" : "Insert your ID in the PDA to receive the funds."]") tnote["msg_id"] = "← Money transfer from [creditor_name] ([arbitrary_sum]$)
" msg_id++ if(pda_device.id) if(!pda_device.id.virtual_wallet) pda_device.id.update_virtual_wallet() pda_device.id.virtual_wallet.money += arbitrary_sum new /datum/transaction(pda_device.id.virtual_wallet, "Money transfer", arbitrary_sum, other_pda, creditor_name, send2PDAs = FALSE) return 1 else incoming_transactions |= list(list(creditor_name,arbitrary_sum,other_pda)) return 2 //Receive money transferred from another PDA /datum/pda_app/messenger/proc/receive_incoming_transactions(var/obj/item/weapon/card/id/ID_card) var/mob/living/L = null if(pda_device.loc && isliving(pda_device.loc)) L = pda_device.loc to_chat(L, "[bicon(pda_device)] Transactions successfully received! ") for(var/transac in incoming_transactions) if(!pda_device.id.virtual_wallet) pda_device.id.update_virtual_wallet() pda_device.id.virtual_wallet.money += transac[2] new /datum/transaction(pda_device.id.virtual_wallet, "Money transfer", transac[2], transac[3], transac[1]) incoming_transactions = list() /datum/pda_app/messenger/proc/create_message(var/mob/living/U = usr, var/obj/item/device/pda/P, var/multicast_message = null, obj/item/device/pda/reply_to, var/overridemessage) if(!reply_to) reply_to = pda_device if (!istype(P)) return var/datum/pda_app/messenger/P_app = locate(/datum/pda_app/messenger) in P.applications if(!P_app || P_app.toff) return var/t = null if(overridemessage) t = overridemessage if(multicast_message) t = multicast_message if(!t) t = input(U, "Please enter message", "Message to [P]", null) as text|null t = copytext(parse_emoji(sanitize(t)), 1, MAX_MESSAGE_LEN) if (!t || P_app.toff || U.stat || (!in_range(pda_device, U) && pda_device.loc != U)) //If no message, messaging is off, and we're either dead, unconscious, out of range or not in usr return if (last_text && world.time < last_text + 0.5 SECONDS) return last_text = world.time // check if telecomms I/O route 1459 is stable //var/telecomms_intact = telecomms_process(P.owner, owner, t) 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.is_functioning()) useMS = MS break var/datum/signal/signal = pda_device.telecomms_process() var/useTC = FALSE if(signal) if(signal.data["done"]) var/turf/pos = get_turf(P) if(pos.z in signal.data["level"]) useTC = TRUE //Let's make this barely readable if(signal.data["compression"] > 0) t = Gibberish(t, signal.data["compression"] + 50) if(useMS && useTC) // only send the message if it's stable if(!useTC) // Does our recepient have a broadcaster on their level? to_chat(U, "ERROR: Cannot reach recepient.") return var/obj/item/weapon/photo/current_photo = null if(pda_device.photo) current_photo = pda_device.photo if(pda_device.cartridge && istype(pda_device.cartridge, /obj/item/weapon/cartridge/camera)) var/obj/item/weapon/cartridge/camera/CM = pda_device.cartridge if(CM.stored_photos.len) current_photo = input(U, "Photos found in [CM]. Please select one", "Cartridge Photo Selection") as null|anything in CM.stored_photos if(current_photo) imglist["[msg_id]"] = current_photo.img P_app.imglist["[msg_id]"] = current_photo.img useMS.send_pda_message("[P.owner]","[pda_device.owner]","[t]",imglist["[msg_id]"]) tnote["[msg_id]"] = "→ To [P.owner]:
[t]
" P_app.tnote["[msg_id]"] = "← From [pda_device.owner] ([pda_device.ownjob]):
[t]
" msg_id++ for(var/mob/dead/observer/M in player_list) if(!multicast_message && M.stat == DEAD && M.client && (M.client.prefs.get_pref(/datum/preference_setting/binary_flag/toggles) & CHAT_GHOSTPDA)) // src.client is so that ghosts don't have to listen to mice M.show_message("[formatFollow(U)] PDA Message - \ [U.real_name][U.real_name == pda_device.owner ? "" : " (as [pda_device.owner])"] -> [P.owner]: [t]\ [pda_device.photo ? " (View Photo)" : ""]") if (prob(15)&&!multicast_message) //Give the AI a chance of intercepting the message var/who = pda_device.owner if(prob(50)) who = P:owner for(var/mob/living/silicon/ai/ai in mob_list) // Allows other AIs to intercept the message but the AI won't intercept their own message. if(ai.aiPDA != P && ai.aiPDA != src) ai.show_message("Intercepted message from [who]: [t]") if (!P_app.silent) playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1) for (var/mob/O in hearers(3, P.loc)) if(!P_app.silent) O.show_message(text("[bicon(P)] *[P_app.ttone]*")) //Search for holder of the PDA. var/mob/living/L = null if(P.loc && isliving(P.loc)) L = P.loc //Maybe they are a pAI! else L = get_holder_of_type(P, /mob/living/silicon) if(L) L.show_message("[bicon(P)] Message from [pda_device.owner] ([pda_device.ownjob]), \"[t]\" [pda_device.photo ? "(View Photo)" : ""] (Reply)", 2) U.show_message("[bicon(pda_device)] Message for [P] has been sent.") log_pda("[key_name(usr)] (PDA: [pda_device.name]) sent \"[t]\" to [P.name]") P.overlays.len = 0 if(P.show_overlays) P.overlays += image('icons/obj/pda.dmi', "pda-r") else to_chat(U, "[bicon(pda_device)] ERROR: Messaging server is not responding.") /datum/pda_app/multimessage name = "Department Messenger" desc = "Messages an entire department at once." price = 0 has_screen = FALSE icon = "pda_mail" /datum/pda_app/multimessage/on_select(var/mob/user) var/list/department_list = list("security","engineering","medical","research","cargo","service") var/target = input("Select a department", "CAMO Service") as null|anything in department_list if(!target) return var/t = input(user, "Please enter message", "Message to [target]", null) as text|null t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN) var/datum/pda_app/messenger/message_app = locate(/datum/pda_app/messenger) in pda_device.applications //If no message or messenger, messaging is off, and we're either dead, unconscious, out of range or not in usr if (!message_app ||!t || message_app.toff || user.stat || (!in_range(pda_device, user) && pda_device.loc != user)) return if (message_app.last_text && world.time < message_app.last_text + 5) return message_app.last_text = world.time for(var/obj/machinery/pda_multicaster/multicaster in pda_multicasters) if(multicaster.check_status()) var/datum/signal/signal = pda_device.telecomms_process() if(signal) if(signal.data["done"]) var/turf/pos = get_turf(multicaster) if(pos.z in signal.data["level"]) //Let's make this barely readable if(signal.data["compression"] > 0) t = Gibberish(t, signal.data["compression"] + 50) multicaster.multicast(target,pda_device,user,t) message_app.tnote["msg_id"] = "→ To [target]:
[t]
" msg_id++ return to_chat(user, "[bicon(pda_device)]The PDA's screen flashes, 'Error, CAMO server is not responding.'")