diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index 23d7452f3d..0a73ea74c6 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -16,6 +16,7 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) var/mob/living/silicon/pai/pai var/image/screen_layer var/screen_color = "#00ff0d" + var/last_notify = 0 /obj/item/device/paicard/relaymove(var/mob/user, var/direction) if(user.stat || user.stunned) @@ -44,26 +45,52 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) if(choice == "No") return ..() - var/pai_name = input(user, "Choose your character's name", "Character Name") as text - var/actual_pai_name = sanitize_name(pai_name, ,1) - if(isnull(actual_pai_name)) - return ..() - + choice = tgui_alert(user, "Do you want to load your pAI data?", "Load", list("Yes", "No")) + var/actual_pai_name var/turf/location = get_turf(src) - if(istype(src , /obj/item/device/paicard/typeb)) - var/obj/item/device/paicard/typeb/card = new(location) - var/mob/living/silicon/pai/new_pai = new(card) - new_pai.key = user.key - card.setPersonality(new_pai) - new_pai.SetName(actual_pai_name) - else - var/obj/item/device/paicard/card = new(location) - var/mob/living/silicon/pai/new_pai = new(card) - new_pai.key = user.key - card.setPersonality(new_pai) - new_pai.SetName(actual_pai_name) + if(choice == "No") + var/pai_name = input(user, "Choose your character's name", "Character Name") as text + actual_pai_name = sanitize_name(pai_name, ,1) + if(isnull(actual_pai_name)) + return ..() + if(istype(src , /obj/item/device/paicard/typeb)) + var/obj/item/device/paicard/typeb/card = new(location) + var/mob/living/silicon/pai/new_pai = new(card) + new_pai.key = user.key + card.setPersonality(new_pai) + new_pai.SetName(actual_pai_name) + else + var/obj/item/device/paicard/card = new(location) + var/mob/living/silicon/pai/new_pai = new(card) + new_pai.key = user.key + card.setPersonality(new_pai) + new_pai.SetName(actual_pai_name) + + if(choice == "Yes") + if(istype(src , /obj/item/device/paicard/typeb)) + var/obj/item/device/paicard/typeb/card = new(location) + var/mob/living/silicon/pai/new_pai = new(card) + new_pai.key = user.key + card.setPersonality(new_pai) + if(!new_pai.savefile_load(new_pai)) + var/pai_name = input(new_pai, "Choose your character's name", "Character Name") as text + actual_pai_name = sanitize_name(pai_name, ,1) + if(isnull(actual_pai_name)) + return ..() + else + var/obj/item/device/paicard/card = new(location) + var/mob/living/silicon/pai/new_pai = new(card) + new_pai.key = user.key + card.setPersonality(new_pai) + if(!new_pai.savefile_load(new_pai)) + var/pai_name = input(new_pai, "Choose your character's name", "Character Name") as text + actual_pai_name = sanitize_name(pai_name, ,1) + if(isnull(actual_pai_name)) + return ..() + qdel(src) return ..() + // VOREStation Edit End /obj/item/device/paicard/attack_self(mob/user) @@ -352,9 +379,11 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) current_emotion = emotion /obj/item/device/paicard/proc/alertUpdate() - var/turf/T = get_turf_or_move(src.loc) - for (var/mob/M in viewers(T)) - M.show_message("\The [src] flashes a message across its screen, \"Additional personalities available for download.\"", 3, "\The [src] bleeps electronically.", 2) + if(pai) + return + if(last_notify == 0 || (5 MINUTES <= world.time - last_notify)) + audible_message("\The [src] flashes a message across its screen, \"Additional personalities available for download.\"", hearing_distance = world.view, runemessage = "bleeps!") + last_notify = world.time /obj/item/device/paicard/emp_act(severity) for(var/mob/M in src) diff --git a/code/modules/admin/admin_verb_lists_vr.dm b/code/modules/admin/admin_verb_lists_vr.dm index 9f4d81120c..b871c3315b 100644 --- a/code/modules/admin/admin_verb_lists_vr.dm +++ b/code/modules/admin/admin_verb_lists_vr.dm @@ -112,7 +112,7 @@ var/list/admin_verbs_admin = list( /client/proc/change_human_appearance_self, // Allows the human-based mob itself change its basic appearance , /client/proc/change_security_level, /client/proc/view_chemical_reaction_logs, - /client/proc/makePAI, + /client/proc/makepAI, /client/proc/toggle_debug_logs, /client/proc/toggle_attack_logs, /datum/admins/proc/paralyze_mob, @@ -519,7 +519,7 @@ var/list/admin_verbs_event_manager = list( /client/proc/change_human_appearance_admin, // Allows an admin to change the basic appearance of human-based mobs , /client/proc/change_human_appearance_self, // Allows the human-based mob itself change its basic appearance , /client/proc/change_security_level, - /client/proc/makePAI, + /client/proc/makepAI, /client/proc/toggle_debug_logs, /client/proc/toggle_attack_logs, /datum/admins/proc/paralyze_mob, diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 8b0baa5967..40635bb7fe 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -129,31 +129,35 @@ M.Animalize() -/client/proc/makepAI(var/turf/T in mob_list) +/client/proc/makepAI() set category = "Fun" set name = "Make pAI" - set desc = "Specify a location to spawn a pAI device, then specify a key to play that pAI" + set desc = "Spawn someone in as a pAI!" + if(!check_rights(R_ADMIN|R_EVENT|R_DEBUG)) + return + var/turf/T = get_turf(mob) var/list/available = list() for(var/mob/C in mob_list) - if(C.key) + if(C.key && isobserver(C)) available.Add(C) var/mob/choice = tgui_input_list(usr, "Choose a player to play the pAI", "Spawn pAI", available) if(!choice) return 0 - if(!istype(choice, /mob/observer/dead)) - var/confirm = tgui_alert(usr, "[choice.key] isn't ghosting right now. Are you sure you want to yank them out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", list("No", "Yes")) - if(confirm != "Yes") - return 0 - var/obj/item/device/paicard/card = new(T) + var/obj/item/device/paicard/typeb/card = new(T) var/mob/living/silicon/pai/pai = new(card) - pai.name = sanitizeSafe(input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text) pai.real_name = pai.name pai.key = choice.key card.setPersonality(pai) + if(tgui_alert(pai, "Do you want to load your pAI data?", "Load", list("Yes", "No")) == "Yes") + pai.savefile_load(pai) + else + pai.name = sanitizeSafe(input(pai, "Enter your pAI name:", "pAI Name", "Personal AI") as text) + card.setPersonality(pai) for(var/datum/paiCandidate/candidate in paiController.pai_candidates) if(candidate.key == choice.key) paiController.pai_candidates.Remove(candidate) + log_admin("made a pAI with key=[pai.key] at ([T.x],[T.y],[T.z])") feedback_add_details("admin_verb","MPAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_alienize(var/mob/M in mob_list) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 2d991e7290..f642131278 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -984,8 +984,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/obj/item/device/paicard/PP = p if(PP.pai == null) count++ - PP.icon = 'icons/obj/pda_vr.dmi' // VOREStation Edit PP.add_overlay("pai-ghostalert") + PP.alertUpdate() spawn(54) PP.cut_overlays() to_chat(usr,"Flashing the displays of [count] unoccupied PAIs.") diff --git a/code/modules/mob/living/silicon/pai/examine.dm b/code/modules/mob/living/silicon/pai/examine.dm index b6890470c9..9c009dcf6f 100644 --- a/code/modules/mob/living/silicon/pai/examine.dm +++ b/code/modules/mob/living/silicon/pai/examine.dm @@ -9,16 +9,10 @@ // VOREStation Edit: Start . += attempt_vr(src,"examine_bellies",args) //VOREStation Edit - if(ooc_notes) - . += "OOC Notes: \[View\]" - // VOREStation Edit: End - - . += "*---------*" - if(print_flavor_text()) . += "\n[print_flavor_text()]\n" - + // VOREStation Edit: End + . += "*---------*" if (pose) if(!findtext(pose, regex("\[.?!]$"))) // Will be zero if the last character is not a member of [.?!] pose = addtext(pose,".") //Makes sure all emotes end with a period. . += "
It is [pose]" //Extra
intentional - \ No newline at end of file diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 9c82783928..7187b245aa 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -286,6 +286,7 @@ if(istype(T)) T.visible_message("[src] folds outwards, expanding into a mobile form.") verbs |= /mob/living/silicon/pai/proc/pai_nom verbs |= /mob/living/proc/vertical_nom + update_icon() /mob/living/silicon/pai/verb/fold_up() set category = "pAI Commands" diff --git a/code/modules/mob/living/silicon/pai/pai_vr.dm b/code/modules/mob/living/silicon/pai/pai_vr.dm index f8eef7b8fe..6c36c82419 100644 --- a/code/modules/mob/living/silicon/pai/pai_vr.dm +++ b/code/modules/mob/living/silicon/pai/pai_vr.dm @@ -213,4 +213,64 @@ if(FEMALE) t_him = "her" visible_message("\The [src] hugs [A] to make [t_him] feel better!", \ - "You hug [A] to make [t_him] feel better!") \ No newline at end of file + "You hug [A] to make [t_him] feel better!") + +/mob/living/silicon/pai/proc/savefile_path(mob/user) + return "data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/pai.sav" + +/mob/living/silicon/pai/proc/savefile_save(mob/user) + if(IsGuestKey(user.key)) + return 0 + + var/savefile/F = new /savefile(src.savefile_path(user)) + + + F["name"] << src.name + F["description"] << src.flavor_text + F["eyecolor"] << src.eye_color + F["chassis"] << src.chassis + F["emotion"] << src.card.current_emotion + F["version"] << 1 + + return 1 + +/mob/living/silicon/pai/proc/savefile_load(mob/user, var/silent = 1) + if (IsGuestKey(user.key)) + return 0 + + var/path = savefile_path(user) + + if (!fexists(path)) + return 0 + + var/savefile/F = new /savefile(path) + + if(!F) return //Not everyone has a pai savefile. + + var/version = null + F["version"] >> version + + if (isnull(version) || version != 1) + fdel(path) + if (!silent) + tgui_alert_async(user, "Your savefile was incompatible with this version and was deleted.") + return 0 + var/ourname + var/ouremotion + F["name"] >> ourname + SetName(ourname) + F["description"] >> flavor_text + F["eyecolor"] >> eye_color + F["chassis"] >> chassis + F["emotion"] >> ouremotion + card.screen_color = eye_color + if(ouremotion) + card.setEmotion(ouremotion) + update_icon() + return 1 + +/mob/living/silicon/pai/verb/save_pai_to_slot() + set category = "pAI Commands" + set name = "Save Configuration" + savefile_save(src) + to_chat(src, "[name] configuration saved to global pAI settings.") diff --git a/code/modules/mob/living/silicon/pai/personality.dm b/code/modules/mob/living/silicon/pai/personality.dm index 73ae49dcb7..de2b8fa202 100644 --- a/code/modules/mob/living/silicon/pai/personality.dm +++ b/code/modules/mob/living/silicon/pai/personality.dm @@ -57,4 +57,8 @@ F["description"] >> src.description F["role"] >> src.role F["comments"] >> src.comments + F["eyecolor"] >> src.eye_color + F["chassis"] >> src.chassis + F["emotion"] >> src.ouremotion + return 1 diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm index ffd817d9c4..9b5afc434b 100644 --- a/code/modules/mob/living/silicon/pai/recruit.dm +++ b/code/modules/mob/living/silicon/pai/recruit.dm @@ -11,7 +11,9 @@ var/datum/paiController/paiController // Global handler for pAI candidates var/role var/comments var/ready = 0 - + var/chassis + var/ouremotion + var/eye_color /hook/startup/proc/paiControllerSetup() paiController = new /datum/paiController() @@ -33,14 +35,23 @@ var/datum/paiController/paiController // Global handler for pAI candidates return if(istype(card,/obj/item/device/paicard) && istype(candidate,/datum/paiCandidate)) var/mob/living/silicon/pai/pai = new(card) - if(!candidate.name) - pai.name = pick(ninja_names) - else - pai.name = candidate.name - pai.real_name = pai.name pai.key = candidate.key - card.setPersonality(pai) + if(!candidate.name) + pai.SetName(pick(ninja_names)) + else + pai.SetName(candidate.name) + if(candidate.description) + pai.flavor_text = candidate.description + if(candidate.eye_color) + pai.eye_color = candidate.eye_color + card.screen_color = pai.eye_color + if(candidate.chassis) + pai.chassis = candidate.chassis + if(candidate.ouremotion) + card.setEmotion(candidate.ouremotion) + pai.update_icon() + pai.real_name = pai.name card.looking_for_personality = 0 if(pai.mind) update_antag_icons(pai.mind) @@ -210,7 +221,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates - Load Personality + Load Personality
diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm index 4054caa54e..fa1b2a0bdf 100644 --- a/code/modules/vore/eating/belly_obj_vr.dm +++ b/code/modules/vore/eating/belly_obj_vr.dm @@ -342,7 +342,7 @@ owner.update_icons() //Print notifications/sound if necessary - if(!silent) + if(!silent && count) owner.visible_message("[owner] expels everything from their [lowertext(name)]!") var/soundfile if(!fancy_vore) diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index b82ecb07e7..aa356e74b1 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -147,8 +147,8 @@ resize(new_size/100, uncapped = has_large_resize_bounds(), ignore_prefs = TRUE) // I'm not entirely convinced that `src ? ADMIN_JMP(src) : "null"` here does anything // but just in case it does, I'm leaving the null-src checking - message_admins("[key_name(src)] used the resize command in-game to be [new_size]% size. [src ? ADMIN_JMP(src) : "null"]") - + log_admin("[key_name(src)] used the resize command in-game to be [new_size]% size. [src ? ADMIN_JMP(src) : "null"]") + /* //Add the set_size() proc to usable verbs. By commenting this out, we can leave the proc and hand it to species that need it. /hook/living_new/proc/resize_setup(mob/living/H) diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi index e7e7f0859c..f98d60b5bd 100644 Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ diff --git a/vorestation.dme b/vorestation.dme index f8347cdadc..add3c1e377 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -2906,7 +2906,6 @@ #include "code\modules\mob\living\silicon\decoy\death.dm" #include "code\modules\mob\living\silicon\decoy\decoy.dm" #include "code\modules\mob\living\silicon\decoy\life.dm" -#include "code\modules\mob\living\silicon\pai\admin.dm" #include "code\modules\mob\living\silicon\pai\death.dm" #include "code\modules\mob\living\silicon\pai\examine.dm" #include "code\modules\mob\living\silicon\pai\life.dm"