From b7b630d5921cd956eaced382e5fb268995660de9 Mon Sep 17 00:00:00 2001 From: SatinIsle <98125273+SatinIsle@users.noreply.github.com> Date: Sat, 25 Jan 2025 16:04:00 +0000 Subject: [PATCH] Adds a persistent notes feature (#16923) * Adds a persistent notes feature Added a new "Private Notes" option to character setup, and a new "Private Notes" verb that opens them up and allows you to see and edit them in-game in the same way as OOC Notes. These notes are simply a block of persistent text, purely for your own viewing. The entire purpose of them is for making notes for your own use, such as adding info if you come up with lore on the fly, so that you can easily reference it in the future. You can obviously store anything in there that you'd normally put into a txt file, it's just an easy way to organise info directly tied to your character. This works on a character by character basis. I've tried to follow the template used for OOC Notes as best I can, because I believe that shadow has updated those to be tg style prefs, so that it'll not need to be redone. I know that there are a few instances of usr instead of user in here too, I am not sure if they are appropriate or not as I just followed the way that similar settings work. Please do poke me if that needs changing. * Fixed requested usr's * Removed to_world * removed "as mob" --- .../client/preference_setup/vore/09_misc.dm | 6 ++ .../types/character/general/01_basic.dm | 11 +++ code/modules/mob/living/living_defines_vr.dm | 1 + code/modules/mob/living/living_vr.dm | 26 +++++++ code/modules/mob/living/private_notes.dm | 68 +++++++++++++++++++ code/modules/mob/living/silicon/ai/ai.dm | 1 + code/modules/mob/living/silicon/pai/pai.dm | 1 + .../modules/mob/living/silicon/robot/robot.dm | 1 + .../living/simple_mob/subtypes/vore/vore.dm | 1 + code/modules/mob/mob.dm | 6 +- code/modules/vore/eating/living_vr.dm | 6 ++ vorestation.dme | 1 + 12 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 code/modules/mob/living/private_notes.dm diff --git a/code/modules/client/preference_setup/vore/09_misc.dm b/code/modules/client/preference_setup/vore/09_misc.dm index 771f97b1649..935f9e4d08b 100644 --- a/code/modules/client/preference_setup/vore/09_misc.dm +++ b/code/modules/client/preference_setup/vore/09_misc.dm @@ -54,6 +54,8 @@ . += span_bold("Spawn With Backup Implant:") + " [pref.auto_backup_implant ? "Yes" : "No"]
" . += span_bold("Allow petting as robot:") + " [pref.borg_petting ? "Yes" : "No"]
" . += span_bold("Enable Stomach Sprites:") + " [pref.stomach_vision ? "Yes" : "No"]
" + if(CONFIG_GET(flag/allow_metadata)) + . += span_bold("Private Notes: Edit") + "
" /datum/category_item/player_setup_item/vore/misc/OnTopic(var/href, var/list/href_list, var/mob/user) if(href_list["toggle_show_in_directory"]) @@ -94,4 +96,8 @@ else if(href_list["toggle_stomach_vision"]) pref.stomach_vision = pref.stomach_vision ? 0 : 1; return TOPIC_REFRESH + else if(href_list["edit_private_notes"]) + var/new_metadata = sanitize(tgui_input_text(user,"Write some notes for yourself. These can be anything that is useful, whether it's character events that you want to remember or a bit of lore. Things that you would normally stick in a txt file for yourself!", "Private Notes", html_decode(pref.read_preference(/datum/preference/text/living/private_notes)), multiline = TRUE, prevent_enter = TRUE), extra = 0) + if(new_metadata && CanUseTopic(user)) + pref.update_preference_by_type(/datum/preference/text/living/private_notes, new_metadata) return ..(); diff --git a/code/modules/client/preferences/types/character/general/01_basic.dm b/code/modules/client/preferences/types/character/general/01_basic.dm index b156f7a3aec..e2a9652954c 100644 --- a/code/modules/client/preferences/types/character/general/01_basic.dm +++ b/code/modules/client/preferences/types/character/general/01_basic.dm @@ -173,3 +173,14 @@ /datum/preference/choiced/living/spawnpoint/apply_to_living(mob/living/target, value) return // handled in job_controller + +/datum/preference/text/living/private_notes + category = PREFERENCE_CATEGORY_MANUALLY_RENDERED + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "Private_Notes" + maximum_value_length = MAX_MESSAGE_LEN * 4 + can_randomize = FALSE + +/datum/preference/text/living/private_notes/apply_to_living(mob/living/target, value) + target.private_notes = value + return diff --git a/code/modules/mob/living/living_defines_vr.dm b/code/modules/mob/living/living_defines_vr.dm index 520f094d66e..4587fd6e819 100644 --- a/code/modules/mob/living/living_defines_vr.dm +++ b/code/modules/mob/living/living_defines_vr.dm @@ -10,6 +10,7 @@ var/custom_link = null appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER|LONG_GLIDE var/hunger_rate = DEFAULT_HUNGER_FACTOR + var/private_notes = null //custom say verbs var/custom_say = null var/custom_ask = null diff --git a/code/modules/mob/living/living_vr.dm b/code/modules/mob/living/living_vr.dm index 2161c549515..5f90e952d63 100644 --- a/code/modules/mob/living/living_vr.dm +++ b/code/modules/mob/living/living_vr.dm @@ -145,3 +145,29 @@ if(!choice) voice_sounds_list = talk_sound voice_sounds_list = get_talk_sound(choice) + +/mob/living/proc/save_private_notes(mob/user) + if(user != src) + return + if(client.prefs.real_name != real_name) + to_chat(src, span_danger("Your selected character slot name is not the same as your character's name. Aborting save. Please select [real_name]'s character slot in character setup before saving.")) + return + if(client.prefs.save_character()) + to_chat(src, span_filter_notice("Character preferences saved.")) + +/mob/living/verb/open_private_notes(mob/user) + set name = "Private Notes" + set desc = "View and edit your character's private notes, that persist between rounds!" + set category = "IC.Notes" + + private_notes_window(user) + +/mob/living/proc/set_metainfo_private_notes(mob/user) + if(user != src) + return + var/new_metadata = sanitize(tgui_input_text(src,"Write some notes for yourself. These can be anything that is useful, whether it's character events that you want to remember or a bit of lore. Things that you would normally stick in a txt file for yourself! This will not be saved unless you press save in the private notes panel.", "Private Notes", html_decode(private_notes), multiline = TRUE, prevent_enter = TRUE), extra = 0) + if(new_metadata && CanUseTopic(src)) + private_notes = new_metadata + client.prefs.update_preference_by_type(/datum/preference/text/living/private_notes, new_metadata) + to_chat(src, span_filter_notice("Private notes updated. Don't forget to save!")) + private_notes_window(user) diff --git a/code/modules/mob/living/private_notes.dm b/code/modules/mob/living/private_notes.dm new file mode 100644 index 00000000000..f17fc0bea96 --- /dev/null +++ b/code/modules/mob/living/private_notes.dm @@ -0,0 +1,68 @@ +/mob/living/proc/private_notes_window(mob/user) + if(!private_notes) + private_notes = " " + return + var/notes = replacetext(html_decode(src.private_notes), "\n", "
") + var/dat = {" + + + + + "} + + dat += {""} + if(user == src) + dat += {" + + "} + + if(user == src) + dat += {" +
+
+ Save Character Preferences +
+ +
+ Edit +
+ "} + + dat += {" +
+

[notes]

+ + "} + + var/key = "private_notes[src.real_name]" //Generate a unique key so we can make unique clones of windows, that way we can have more than one + if(src.ckey) + key = "[key][src.ckey]" //Add a ckey if they have one, in case their name is the same + + winclone(user, "private_notes", key) //Allows us to have more than one OOC notes panel open + + winshow(user, key, TRUE) //Register our window + var/datum/browser/popup = new(user, key, "Private Notes: [src.name]", 500, 600) //Create the window + popup.set_content(dat) //Populate window contents + popup.open(FALSE) // Skip registring onclose on the browser pane + onclose(user, key, src) // We want to register on the window itself diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 491876c8596..7733b9df0a8 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -213,6 +213,7 @@ var/list/ai_verbs_default = list( ooc_notes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes) ooc_notes_likes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes_likes) ooc_notes_dislikes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes_dislikes) + private_notes = client.prefs.read_preference(/datum/preference/text/living/private_notes) if (malf && !(mind in malf.current_antagonists)) show_laws() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 0e2d1056f95..3e1432f62a3 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -152,6 +152,7 @@ ooc_notes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes) ooc_notes_likes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes_likes) ooc_notes_dislikes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes_dislikes) + private_notes = client.prefs.read_preference(/datum/preference/text/living/private_notes) src << sound('sound/effects/pai_login.ogg', volume = 75) //VOREStation Add diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index b4c1a559b1d..3eae7ed6844 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -408,6 +408,7 @@ ooc_notes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes) ooc_notes_likes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes_likes) ooc_notes_dislikes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes_dislikes) + private_notes = client.prefs.read_preference(/datum/preference/text/living/private_notes) custom_link = client.prefs.custom_link /mob/living/silicon/robot/verb/namepick() diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm b/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm index d356e404161..ea33b588bde 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm @@ -20,6 +20,7 @@ ooc_notes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes) ooc_notes_likes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes_likes) ooc_notes_dislikes = client.prefs.read_preference(/datum/preference/text/living/ooc_notes_dislikes) + private_notes = client.prefs.read_preference(/datum/preference/text/living/private_notes) digestable = client.prefs_vr.digestable devourable = client.prefs_vr.devourable absorbable = client.prefs_vr.absorbable diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c3f2a2b470d..b565fd47b07 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -292,7 +292,8 @@ /mob/verb/memory() set name = "Notes" - set category = "IC.Game" + set desc = "View notes stored for this round only." + set category = "IC.Notes" if(mind) mind.show_memory(src) else @@ -300,7 +301,8 @@ /mob/verb/add_memory(msg as message) set name = "Add Note" - set category = "IC.Game" + set desc = "Add notes stored for this round only." + set category = "IC.Notes" msg = sanitize(msg) diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 48831b6f9cf..c2f510d9c07 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -1194,6 +1194,12 @@ save_ooc_panel() if(href_list["print_ooc_notes_to_chat"]) print_ooc_notes_to_chat() + if(href_list["save_private_notes"]) + if(usr == src) + save_private_notes(usr) + if(href_list["edit_private_notes"]) + if(usr == src) + set_metainfo_private_notes(usr) return ..() /mob/living/proc/display_voreprefs(mob/user) //Called by Topic() calls on instances of /mob/living (and subtypes) containing vore_prefs as an argument diff --git a/vorestation.dme b/vorestation.dme index e921324ef78..971012a6d2a 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -2983,6 +2983,7 @@ #include "code\modules\mob\living\login.dm" #include "code\modules\mob\living\logout.dm" #include "code\modules\mob\living\ooc_notes.dm" +#include "code\modules\mob\living\private_notes.dm" #include "code\modules\mob\living\organs.dm" #include "code\modules\mob\living\riding.dm" #include "code\modules\mob\living\say.dm"