From ffdd69ed922cbbaba8e13479f38a393735682377 Mon Sep 17 00:00:00 2001 From: Cody Swendrowski Date: Sun, 30 Jun 2024 14:14:52 -0500 Subject: [PATCH] Add "What everyone knows" context --- scripts/apps/ActoriNpcConfiguration.mjs | 8 +++++--- scripts/apps/IntelligentNpcsBrowser.mjs | 1 + scripts/hooks/createChatMessage.mjs | 9 ++++++--- styles/intelligent-npcs.css | 4 ++++ styles/intelligent-npcs.css.map | 2 +- styles/intelligent-npcs.scss | 6 ++++++ templates/actor-inpc-configuration.hbs | 8 ++++---- templates/journal/page-inpc-edit.hbs | 18 ++++++++++++------ templates/journal/page-inpc-view.hbs | 15 ++++++++++++--- 9 files changed, 51 insertions(+), 20 deletions(-) diff --git a/scripts/apps/ActoriNpcConfiguration.mjs b/scripts/apps/ActoriNpcConfiguration.mjs index 8d1f0ed..22d4ae3 100644 --- a/scripts/apps/ActoriNpcConfiguration.mjs +++ b/scripts/apps/ActoriNpcConfiguration.mjs @@ -30,7 +30,8 @@ export default class ActoriNpcConfiguration extends FormApplication { const config = this.actor.flags["intelligent-npcs"] ?? {}; if ( foundry.utils.isEmpty(config) ) { - config["summary"] = "You are a generic NPC named Bob."; + config["summary"] = "A generic NPC named Bob."; + config["whatEveryoneKnows"] = "You don't know anything about this person beyond what you can glean from their appearance."; config["appearance"] = "Farmer attire"; } @@ -59,8 +60,8 @@ export default class ActoriNpcConfiguration extends FormApplication { const selectedPageConfig = page?.flags["intelligent-npcs"] ?? {}; const hasMessageHistory = config["messageHistory"] && config["messageHistory"].length > 0; - const hasDifferentMemory = config["memory"] && config["memory"].length > 0 - && config["memory"] !== selectedPageConfig["memory"]; + const hasDifferentMemory = config.memory?.length > 0 + && config.memory !== selectedPageConfig.memory; const hasDifferentName = (this.actor && page) ? this.actor.name !== page.name : false; const canSwap = (pageId === "none") || !(hasMessageHistory || hasDifferentMemory || hasDifferentName); @@ -238,6 +239,7 @@ export default class ActoriNpcConfiguration extends FormApplication { // Clear the customizations await this.actor.setFlag("intelligent-npcs", "summary", ""); + await this.actor.setFlag("intelligent-npcs", "whatEveryoneKnows", ""); await this.actor.setFlag("intelligent-npcs", "appearance", ""); await this.actor.setFlag("intelligent-npcs", "messageHistory", []); await this.actor.setFlag("intelligent-npcs", "memory", ""); diff --git a/scripts/apps/IntelligentNpcsBrowser.mjs b/scripts/apps/IntelligentNpcsBrowser.mjs index ad6038e..dabc47a 100644 --- a/scripts/apps/IntelligentNpcsBrowser.mjs +++ b/scripts/apps/IntelligentNpcsBrowser.mjs @@ -232,6 +232,7 @@ export default class IntelligentNpcsBrowser extends Application { "img": img, "personality": npc.fields.personality, "summary": npc.fields.summary, + "whatEveryoneKnows": npc.fields.whatEveryoneKnows, "airtableId": npc.id, } }); diff --git a/scripts/hooks/createChatMessage.mjs b/scripts/hooks/createChatMessage.mjs index 4a55e1c..cca84de 100644 --- a/scripts/hooks/createChatMessage.mjs +++ b/scripts/hooks/createChatMessage.mjs @@ -88,12 +88,14 @@ export async function getConfig(npc) { ...selectedPageConfig }; if ( actorConfig.summary ) config.summary = actorConfig.summary; + if ( actorConfig.whatEveryoneKnows ) config.whatEveryoneKnows = actorConfig.whatEveryoneKnows; if ( actorConfig.appearance ) config.appearance = actorConfig.appearance; if ( actorConfig.messageHistory ) config.messageHistory = actorConfig.messageHistory; if ( actorConfig.memory ) config.memory = actorConfig.memory; if ( page.name !== npc.name ) { config.summary = config.summary.replace(new RegExp(page.name, "g"), npc.name); + config.whatEveryoneKnows = config.whatEveryoneKnows.replace(new RegExp(page.name, "g"), npc.name); config.appearance = config.appearance.replace(new RegExp(page.name, "g"), npc.name); config.background = config.background.replace(new RegExp(page.name, "g"), npc.name); config.personality = config.personality.replace(new RegExp(page.name, "g"), npc.name); @@ -117,7 +119,7 @@ async function chatCompletion(npc, message, scene) { // If the speaker has a summary, load it const speakerToken = scene.tokens.get(message.speaker.token); const speakerConfig = await getConfig(speakerToken?.actor); - const speakerSummary = speakerConfig?.summary ?? ""; + const speakerWhatEveryoneKnows = speakerConfig?.whatEveryoneKnows ?? ""; const speakerAppearance = speakerConfig?.appearance ?? ""; // Get the subarea context if it exists @@ -129,7 +131,7 @@ async function chatCompletion(npc, message, scene) { "message": message.content, "tokenNames": allTokenNames, "speaker": message.speaker.alias ?? (message.user.isGM ? "GM" : "Unknown"), - "speakerSummary": speakerSummary, + "speakerSummary": speakerWhatEveryoneKnows, "speakerAppearance": speakerAppearance, "sceneContext": sceneContext + "\n\n" + subareaContext, "worldContext": worldContext, @@ -320,7 +322,8 @@ export async function createChatMessage(message, options, userId) { // If the target is not an AI, return const aiNpcs = scene.tokens.filter(t => t.actor?.flags["intelligent-npcs"]?.enabled === true).map(t => t.actor._id); const speakerIsTarget = targetedNpc._id === message.speaker.actor; - if (!aiNpcs.includes(targetedNpc._id) || speakerIsTarget) return; + const hidden = targetedNpc?.token?.hidden || targetedToken?.document?.hidden; + if ( !aiNpcs.includes(targetedNpc._id) || speakerIsTarget || hidden ) return; // get the message history from the npc flags const messageHistory = targetedNpc.getFlag("intelligent-npcs", "messageHistory") || []; diff --git a/styles/intelligent-npcs.css b/styles/intelligent-npcs.css index f61692b..708ba2a 100644 --- a/styles/intelligent-npcs.css +++ b/styles/intelligent-npcs.css @@ -1,3 +1,7 @@ +#client-settings select[name="intelligent-npcs.model"] { + width: 100%; +} + .chat-message .message-header .message-sender { flex: 4; text-overflow: ellipsis; diff --git a/styles/intelligent-npcs.css.map b/styles/intelligent-npcs.css.map index 7cd74fc..c90a39a 100644 --- a/styles/intelligent-npcs.css.map +++ b/styles/intelligent-npcs.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["intelligent-npcs.scss"],"names":[],"mappings":"AAEI;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAKF;EACE;;;AAKF;EACE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;;AAGF;EACE;;;AAIJ;EACE;;;AAIA;EACE;EACA;;AAEA;EACE;;AAGJ;EACE;;AAGF;EACE;EACA;;AAEA;EACE;;AAGF;EACE","file":"intelligent-npcs.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["intelligent-npcs.scss"],"names":[],"mappings":"AACE;EACE;;;AAMA;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAKF;EACE;;;AAKF;EACE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;;AAGF;EACE;;;AAIJ;EACE;;;AAIA;EACE;EACA;;AAEA;EACE;;AAGJ;EACE;;AAGF;EACE;EACA;;AAEA;EACE;;AAGF;EACE","file":"intelligent-npcs.css"} \ No newline at end of file diff --git a/styles/intelligent-npcs.scss b/styles/intelligent-npcs.scss index fbd4611..b5eb9d1 100644 --- a/styles/intelligent-npcs.scss +++ b/styles/intelligent-npcs.scss @@ -1,3 +1,9 @@ +#client-settings { + select[name='intelligent-npcs.model'] { + width: 100%; + } +} + .chat-message { .message-header { .message-sender { diff --git a/templates/actor-inpc-configuration.hbs b/templates/actor-inpc-configuration.hbs index 0b20f3e..ceff2e8 100644 --- a/templates/actor-inpc-configuration.hbs +++ b/templates/actor-inpc-configuration.hbs @@ -45,12 +45,12 @@
Public -

These fields override any journal selected, and will be read by Intelligent NPCs, so don't include any info that others shouldn't generally know

+

These fields override any journal selected, and will be read by other Intelligent NPCs, so don't include any info that others shouldn't generally know

- - -

A quick summary of what others generally know about this person. Write in third person. Overrides the Journal details if set. Max length: 500 characters

+ + +

A quick summary of what others generally know about this person. Write in third person. Max length: 500 characters

diff --git a/templates/journal/page-inpc-edit.hbs b/templates/journal/page-inpc-edit.hbs index 20ee34f..cc91395 100644 --- a/templates/journal/page-inpc-edit.hbs +++ b/templates/journal/page-inpc-edit.hbs @@ -4,26 +4,32 @@

+
+ + +

A quick summary of this NPC for human reference. Intelligent NPCs do not read this field.

+
+
- Public -

These fields will be read by Intelligent NPCs, so don't include any info that others shouldn't generally know. These fields should be written in third person.

+ Public Info +

These fields will be read by other Intelligent NPCs, so don't include any info that others shouldn't generally know. These fields should be written in third person.

- - + +

A quick summary of what others generally know about this person. Write in third person. Max length: 500 characters

- +

What this character looks like to others. Write in third person. Max length: 500 characters

- Personality + Private Info

The following fields should be written in first person.

diff --git a/templates/journal/page-inpc-view.hbs b/templates/journal/page-inpc-view.hbs index bc8259c..f3d9d9c 100644 --- a/templates/journal/page-inpc-view.hbs +++ b/templates/journal/page-inpc-view.hbs @@ -6,15 +6,24 @@

Summary

{{config.summary}}

- -

Appearance

-

{{config.appearance}}

+
+ +

Public Info

+ +

What Everyone Knows

+

{{config.whatEveryoneKnows}}

+ +

Appearance

+

{{config.appearance}}

+ {{#if user.isGM}}
+

Private Info

+

Background

{{config.background}}