diff --git a/src/core/state.js b/src/core/state.js index 9c79f73..4802b65 100644 --- a/src/core/state.js +++ b/src/core/state.js @@ -74,6 +74,7 @@ export let extensionSettings = { ], // RPG Attributes (customizable D&D-style attributes) showRPGAttributes: true, + alwaysSendAttributes: false, // If true, always send attributes; if false, only send with dice rolls rpgAttributes: [ { id: 'str', name: 'STR', enabled: true }, { id: 'dex', name: 'DEX', enabled: true }, @@ -91,7 +92,8 @@ export let extensionSettings = { // Optional skills field skillsSection: { enabled: false, - label: 'Skills' // User-editable + label: 'Skills', // User-editable + customFields: [] // Array of skill names } }, infoBox: { diff --git a/src/systems/generation/promptBuilder.js b/src/systems/generation/promptBuilder.js index 9ed6ff7..19f8410 100644 --- a/src/systems/generation/promptBuilder.js +++ b/src/systems/generation/promptBuilder.js @@ -283,12 +283,21 @@ export function generateTrackerInstructions(includeHtmlPrompt = true, includeCon instructions += `After updating the trackers, continue directly from where the last message in the chat history left off. Ensure the trackers you provide naturally reflect and influence the narrative. Character behavior, dialogue, and story events should acknowledge these conditions when relevant, such as fatigue affecting the protagonist's performance, low hygiene influencing their social interactions, environmental factors shaping the scene, a character's emotional state coloring their responses, and so on. Remember, all bracketed placeholders (e.g., [Location], [Mood Emoji]) MUST be replaced with actual content without the square brackets.\n\n`; } - // Include attributes and dice roll only if there was a dice roll - if (extensionSettings.lastDiceRoll) { - const roll = extensionSettings.lastDiceRoll; + // Include attributes based on settings + const alwaysSendAttributes = trackerConfig?.userStats?.alwaysSendAttributes; + const shouldSendAttributes = alwaysSendAttributes || extensionSettings.lastDiceRoll; + + if (shouldSendAttributes) { const attributesString = buildAttributesString(); instructions += `${userName}'s attributes: ${attributesString}\n`; - instructions += `${userName} rolled ${roll.total} on the last ${roll.formula} roll. Based on their attributes, decide whether they succeeded or failed the action they attempted.\n\n`; + + // Add dice roll context if there was one + if (extensionSettings.lastDiceRoll) { + const roll = extensionSettings.lastDiceRoll; + instructions += `${userName} rolled ${roll.total} on the last ${roll.formula} roll. Based on their attributes, decide whether they succeeded or failed the action they attempted.\n\n`; + } else { + instructions += `\n`; + } } } diff --git a/src/systems/rendering/thoughts.js b/src/systems/rendering/thoughts.js index 5f8a3cd..e79be3e 100644 --- a/src/systems/rendering/thoughts.js +++ b/src/systems/rendering/thoughts.js @@ -151,7 +151,23 @@ export function renderThoughts() { let lineNumber = 0; let currentCharacter = null; - for (const line of lines) { + // Pre-process: normalize the format to handle cases where "- char" appears mid-line + // This handles: "Thoughts: ... - char 2" by splitting it into separate lines + const normalizedLines = []; + for (let line of lines) { + // Check if line contains "- [name]" pattern after some content (not at start) + // Match pattern like "some text - CharName" where there's content before the dash + const midLineCharMatch = line.match(/^(.+?)\s+-\s+([A-Z][a-zA-Z\s]+)$/); + if (midLineCharMatch && !line.trim().startsWith('- ')) { + // Split: first part stays as one line, "- Name" becomes new line + normalizedLines.push(midLineCharMatch[1].trim()); + normalizedLines.push('- ' + midLineCharMatch[2].trim()); + } else { + normalizedLines.push(line); + } + } + + for (const line of normalizedLines) { lineNumber++; // Skip empty lines, headers, dividers, and code fences diff --git a/src/systems/ui/trackerEditor.js b/src/systems/ui/trackerEditor.js index f872fab..5da8a53 100644 --- a/src/systems/ui/trackerEditor.js +++ b/src/systems/ui/trackerEditor.js @@ -143,7 +143,8 @@ function resetToDefaults() { }, skillsSection: { enabled: false, - label: 'Skills' + label: 'Skills', + customFields: [] } }, infoBox: { @@ -230,6 +231,14 @@ function renderUserStatsTab() { html += ''; html += ''; + // Always send attributes toggle + const alwaysSendAttributes = config.alwaysSendAttributes !== undefined ? config.alwaysSendAttributes : false; + html += '
'; + html += ``; + html += ''; + html += '
'; + html += 'If disabled, attributes are only sent when a dice roll is active.'; + html += '
'; // Ensure rpgAttributes exists in the actual config (not just local fallback) @@ -286,6 +295,10 @@ function renderUserStatsTab() { html += ''; html += ``; + html += ''; + const skillFields = config.skillsSection.customFields || []; + html += ``; + html += '
'; $('#rpg-editor-tab-userStats').html(html); @@ -380,6 +393,11 @@ function setupUserStatsListeners() { extensionSettings.trackerConfig.userStats.showRPGAttributes = $(this).is(':checked'); }); + // Always send attributes toggle + $('#rpg-always-send-attrs').off('change').on('change', function() { + extensionSettings.trackerConfig.userStats.alwaysSendAttributes = $(this).is(':checked'); + }); + // Status section toggles $('#rpg-status-enabled').off('change').on('change', function() { extensionSettings.trackerConfig.userStats.statusSection.enabled = $(this).is(':checked'); @@ -402,6 +420,11 @@ function setupUserStatsListeners() { $('#rpg-skills-label').off('blur').on('blur', function() { extensionSettings.trackerConfig.userStats.skillsSection.label = $(this).val(); }); + + $('#rpg-skills-fields').off('blur').on('blur', function() { + const fields = $(this).val().split(',').map(f => f.trim()).filter(f => f); + extensionSettings.trackerConfig.userStats.skillsSection.customFields = fields; + }); } /**