Files
VOREStation/code/modules/pda/core_apps.dm
Will 2194b87de0 Fixing client eye (#18577)
* signal foundation

* reset_perspective implemented

* you too

* setting mob

* no

* fix

* tweak

* remote view element

* these too

* use element

* cleanup more manual code

* fix element

* mutation signal

* handle being dropped from holders, and fix pai hud

* handle qdel

* it's a component now

* ugly holder fix

* another fix

* follow view target

* item remote view

* doc update

* unneeded

* this needs a recode to work better

* many fixes

* these are all unneeded

* almost working viewerlist remotes

* this uses component too

* this needs to die to it's item

* don't allow spamming tgui menus

* tg style args

* fixing behaviors

* fuk

* working view release from holders

* only final matters

* comment order and disposal fix

* cryotube loc fix

* no mob should reset its view every life tick

* major improvements

* still forbid z level change even if we allow moving

* this too

* don't doubledip

* qdel on self is unneeded

* wipe remote views on logout

* vore bellies need to manually clear views

* fixAI hud

* belly release fixes

* cannot use binoculars in a vore belly

* pai card can be picked up and dropped correctly

* ventcrawl fix and distracted fix

* this is better

* forcemove

* vr console fix

* use flag for this

* belly stuff

* various cleanups

* oops

* fixes statue spell

* unneeded perspective clear

* automatic instead

* continued cleanup

* that was dumb

* needed

* none of this works

* are these even needed

* lets lock down to these

* lets try to make this work

* extremely close to working

* needs to solve final pai issues

* mob eye change signal

* Revert "mob eye change signal"

This reverts commit eedd5da934.

* significant progress

* safety

* expected to be not null

* likely not needed

* don't spam component changes

* endview on logout

* accessors

* egg fixing

* Revert "egg fixing"

This reverts commit 6a54049c69.

* getting closer

* even closer

* needs type

* close...

* extremely close to working

* fixing pai stuff

* this too

* promising fixes

* docs

* this is recursive move's responsibility tbh

* unneeded now

* oops

* better decouple

* topmost check

* cleanup

* holder released from egg fix

* pai fix for reset view

* debug info

* some better pai ejection code

* better way

* unneeded

* needs to be null

* better vision restore

* use correct handling

* no longer needed

* required

* handle decouple on mecha too

* name clarity

* do not allow double dipping zoom items

* ethereal jaunt needs a full cleanup later

* fix blackscreen flicker

* remove set machine from pda

* Update code/game/objects/items.dm

* Update code/game/objects/items.dm

* Update code/game/objects/items.dm

* Update code/game/objects/items.dm

---------

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
2025-10-12 22:18:08 -04:00

308 lines
8.0 KiB
Plaintext

/datum/data/pda/app/main_menu
icon = "home"
template = "pda_main_menu"
hidden = 1
/datum/data/pda/app/main_menu/update_ui(mob/user as mob, list/data)
title = pda.name
data["app"]["is_home"] = 1
data["apps"] = pda.shortcut_cache
data["categories"] = pda.shortcut_cat_order
data["pai"] = !isnull(pda.pai) // pAI inserted?
var/list/notifying[0]
for(var/P in pda.notifying_programs)
notifying["\ref[P]"] = 1
data["notifying"] = notifying
/datum/data/pda/app/main_menu/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("UpdateInfo")
pda.ownjob = pda.id.assignment
pda.ownrank = pda.id.rank
pda.name = "PDA-[pda.owner] ([pda.ownjob])"
return TRUE
if("pai")
if(pda.pai)
if(pda.pai.loc != pda)
pda.pai = null
else
switch(text2num(params["option"]))
if(1) // Configure pAI device
pda.pai.attack_self(ui.user)
if(2) // Eject pAI device
var/turf/T = get_turf_or_move(pda.loc)
if(T)
pda.pai.forceMove(T)
pda.pai = null
return TRUE
/datum/data/pda/app/notekeeper
name = "Notekeeper"
icon = "sticky-note-o"
template = "pda_notekeeper"
var/greeted = FALSE
var/note = null
var/notetitle = null
var/currentnote = 1
var/list/storedtitles = list("","","","","","","","","","","","")
var/list/storednotes = list("","","","","","","","","","","","")
var/notehtml = ""
/datum/data/pda/app/notekeeper/start()
. = ..()
if(!note && greeted == FALSE)
// display greeting!
greeted = TRUE
note = "Thank you for choosing the [pda.model_name]!"
notetitle = "Congratulations!"
/datum/data/pda/app/notekeeper/update_ui(mob/user as mob, list/data)
data["note"] = note // current pda notes
data["notename"] = "Note [GLOB.alphabet_upper[currentnote]] : [notetitle]"
/datum/data/pda/app/notekeeper/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("Edit")
var/n = tgui_input_text(ui.user, "Please enter message", name, notehtml, multiline = TRUE, prevent_enter = TRUE)
if(pda.loc == ui.user)
note = adminscrub(n)
notehtml = html_decode(note)
note = replacetext(note, "\n", "<br>")
else
pda.close(ui.user)
return TRUE
if("Titleset")
var/n = tgui_input_text(ui.user, "Please enter title", name, notetitle, multiline = FALSE)
if(pda.loc == ui.user)
notetitle = adminscrub(n)
else
pda.close(ui.user)
return TRUE
if("Print")
if(pda.loc == ui.user)
printnote(ui.user)
else
pda.close(ui.user)
return TRUE
// dumb way to do this, but i don't know how to easily parse this without a lot of silly code outside the switch!
if("Note1")
if(pda.loc == ui.user)
changetonote(1)
else
pda.close(ui.user)
return TRUE
if("Note2")
if(pda.loc == ui.user)
changetonote(2)
else
pda.close(ui.user)
return TRUE
if("Note3")
if(pda.loc == ui.user)
changetonote(3)
else
pda.close(ui.user)
return TRUE
if("Note4")
if(pda.loc == ui.user)
changetonote(4)
else
pda.close(ui.user)
return TRUE
if("Note5")
if(pda.loc == ui.user)
changetonote(5)
else
pda.close(ui.user)
return TRUE
if("Note6")
if(pda.loc == ui.user)
changetonote(6)
else
pda.close(ui.user)
return TRUE
if("Note7")
if(pda.loc == ui.user)
changetonote(7)
else
pda.close(ui.user)
return TRUE
if("Note8")
if(pda.loc == ui.user)
changetonote(8)
else
pda.close(ui.user)
return TRUE
if("Note9")
if(pda.loc == ui.user)
changetonote(9)
else
pda.close(ui.user)
return TRUE
if("Note10")
if(pda.loc == ui.user)
changetonote(10)
else
pda.close(ui.user)
return TRUE
if("Note11")
if(pda.loc == ui.user)
changetonote(11)
else
pda.close(ui.user)
return TRUE
if("Note12")
if(pda.loc == ui.user)
changetonote(12)
else
pda.close(ui.user)
return TRUE
/datum/data/pda/app/notekeeper/proc/printnote(mob/user)
// get active hand of person holding PDA, and print the page to the paper in it
if(istype( user, /mob/living/carbon/human ))
var/mob/living/carbon/human/H = user
var/obj/item/I = H.get_active_hand()
if(istype(I,/obj/item/paper))
var/obj/item/paper/P = I
if(isnull(P.info) || P.info == "" )
var/titlenote = "Note [GLOB.alphabet_upper[currentnote]]"
if(!isnull(notetitle) && notetitle != "")
titlenote = notetitle
to_chat(user, span_notice("Successfully printed [titlenote]!"))
P.set_content( pencode2html(note), titlenote)
else
to_chat(user, span_notice("You can only print to empty paper!"))
else
to_chat(user, span_notice("You must be holding paper for the pda to print to!"))
/datum/data/pda/app/notekeeper/proc/changetonote(var/noteindex)
// save note to current slot, then load another slot
storednotes[currentnote] = note
storedtitles[currentnote] = notetitle
currentnote = noteindex
note = storednotes[currentnote]
notetitle = storedtitles[currentnote]
// update text on keeper, silly swapping!
note = replacetext(note, "<br>", "\n")
notehtml = html_decode(note)
note = replacetext(note, "\n", "<br>")
/datum/data/pda/app/manifest
name = "Crew Manifest"
icon = "user"
template = "pda_manifest"
/datum/data/pda/app/manifest/update_ui(mob/user as mob, list/data)
if(GLOB.data_core)
GLOB.data_core.get_manifest_list()
data["manifest"] = GLOB.PDA_Manifest
/datum/data/pda/app/manifest/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
/datum/data/pda/app/atmos_scanner
name = "Atmospheric Scan"
icon = "fire"
template = "pda_atmos_scan"
category = "Utilities"
/datum/data/pda/app/atmos_scanner/update_ui(mob/user as mob, list/data)
data["aircontents"] = get_gas_mixture_default_scan_data(get_turf(user))
/datum/data/pda/app/news
name = "News"
icon = "newspaper"
template = "pda_news"
var/newsfeed_channel
/datum/data/pda/app/news/update_ui(mob/user as mob, list/data)
data["feeds"] = compile_news()
data["latest_news"] = get_recent_news()
if(newsfeed_channel)
data["target_feed"] = data["feeds"][newsfeed_channel]
else
data["target_feed"] = null
/datum/data/pda/app/news/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("newsfeed")
newsfeed_channel = text2num(params["newsfeed"])
/datum/data/pda/app/news/proc/compile_news()
var/list/feeds = list()
for(var/datum/feed_channel/channel in news_network.network_channels)
var/list/messages = list()
if(!channel.censored)
var/index = 0
for(var/datum/feed_message/FM in channel.messages)
index++
var/list/msgdata = list(
"author" = FM.author,
"body" = FM.body,
"img" = null,
"message_type" = FM.message_type,
"time_stamp" = FM.time_stamp,
"caption" = FM.caption,
"index" = index
)
if(FM.img)
msgdata["img"] = icon2base64(FM.img)
messages[++messages.len] = msgdata
feeds[++feeds.len] = list(
"name" = channel.channel_name,
"censored" = channel.censored,
"author" = channel.author,
"messages" = messages,
"index" = feeds.len + 1
)
return feeds
/datum/data/pda/app/news/proc/get_recent_news()
var/list/news = list()
// Compile all the newscasts
for(var/datum/feed_channel/channel in news_network.network_channels)
if(!channel.censored)
var/index = 0
for(var/datum/feed_message/FM in channel.messages)
index++
var/body = replacetext(FM.body, "\n", "<br>")
news[++news.len] = list(
"channel" = channel.channel_name,
"author" = FM.author,
"body" = body,
"message_type" = FM.message_type,
"time_stamp" = FM.time_stamp,
"has_image" = (FM.img != null),
"caption" = FM.caption,
"time" = FM.post_time,
"index" = index
)
// Cut out all but the youngest three
if(news.len > 3)
sortByKey(news, "time")
news.Cut(1, news.len - 2) // Last three have largest timestamps, youngest posts
news.Swap(1, 3) // List is sorted in ascending order of timestamp, we want descending
return news