Fix extension loading, enhance theming, add horizontal scrolling, improve emoji parsing, rename to Main Quests

This commit is contained in:
Spicy_Marinara
2025-10-26 22:31:21 +01:00
parent d68ddd601e
commit 141a3f4bec
17 changed files with 2888 additions and 437 deletions
+86 -7
View File
@@ -7,6 +7,45 @@ import { extensionSettings, FEATURE_FLAGS, addDebugLog } from '../../core/state.
import { saveSettings } from '../../core/persistence.js';
import { extractInventory } from './inventoryParser.js';
/**
* Helper to separate emoji from text in a string
* Handles cases where there's no comma or space after emoji
* @param {string} str - String potentially containing emoji followed by text
* @returns {{emoji: string, text: string}} Separated emoji and text
*/
function separateEmojiFromText(str) {
if (!str) return { emoji: '', text: '' };
str = str.trim();
// Regex to match emoji at the start (handles most emoji including compound ones)
// This matches emoji sequences including skin tones, gender modifiers, etc.
const emojiRegex = /^[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{1F000}-\u{1F02F}\u{1F0A0}-\u{1F0FF}\u{1F100}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{1F910}-\u{1F96B}\u{1F980}-\u{1F9E0}\u{FE00}-\u{FE0F}\u{200D}\u{20E3}]+/u;
const emojiMatch = str.match(emojiRegex);
if (emojiMatch) {
const emoji = emojiMatch[0];
let text = str.substring(emoji.length).trim();
// Remove leading comma or space if present
text = text.replace(/^[,\s]+/, '');
return { emoji, text };
}
// No emoji found - check if there's a comma separator anyway
const commaParts = str.split(',');
if (commaParts.length >= 2) {
return {
emoji: commaParts[0].trim(),
text: commaParts.slice(1).join(',').trim()
};
}
// No clear separation - return original as text
return { emoji: '', text: str };
}
/**
* Helper to log to both console and debug logs array
*/
@@ -169,18 +208,36 @@ export function parseUserStats(statsText) {
// Format 2: Status: [Emoji], [Conditions]
// Format 3: [Emoji]: [Conditions] (legacy)
// Format 4: Mood: [Emoji] - [Conditions]
// Format 5: Status: [Emoji Conditions] (no separator - FIXED)
let moodMatch = null;
// Try new format: Status: emoji, conditions
const statusMatch = statsText.match(/Status:\s*(.+?),\s*(.+)/i);
// Try new format: Status: emoji, conditions OR Status: emojiConditions
const statusMatch = statsText.match(/Status:\s*(.+)/i);
if (statusMatch) {
moodMatch = [null, statusMatch[1].trim(), statusMatch[2].trim()];
const statusContent = statusMatch[1].trim();
const { emoji, text } = separateEmojiFromText(statusContent);
if (emoji && text) {
moodMatch = [null, emoji, text];
} else if (statusContent.includes(',')) {
// Fallback to comma split if emoji detection failed
const parts = statusContent.split(',').map(p => p.trim());
moodMatch = [null, parts[0], parts.slice(1).join(', ')];
}
}
// Try alternative: Mood: emoji, conditions
else {
const moodAltMatch = statsText.match(/Mood:\s*(.+?)[,\-]\s*(.+)/i);
// Try alternative: Mood: emoji, conditions OR Mood: emojiConditions
if (!moodMatch) {
const moodAltMatch = statsText.match(/Mood:\s*(.+)/i);
if (moodAltMatch) {
moodMatch = [null, moodAltMatch[1].trim(), moodAltMatch[2].trim()];
const moodContent = moodAltMatch[1].trim();
const { emoji, text } = separateEmojiFromText(moodContent);
if (emoji && text) {
moodMatch = [null, emoji, text];
} else if (moodContent.includes(',') || moodContent.includes('-')) {
// Fallback to comma/dash split if emoji detection failed
const parts = moodContent.split(/[,\-]/).map(p => p.trim());
moodMatch = [null, parts[0], parts.slice(1).join(', ')];
}
}
}
@@ -245,6 +302,28 @@ export function parseUserStats(statsText) {
extensionSettings.userStats.conditions = moodMatch[2].trim(); // Conditions
}
// Extract quests
const mainQuestMatch = statsText.match(/Main Quests?:\s*(.+)/i);
if (mainQuestMatch) {
extensionSettings.quests.main = mainQuestMatch[1].trim();
debugLog('[RPG Parser] Main quests extracted:', mainQuestMatch[1].trim());
}
const optionalQuestsMatch = statsText.match(/Optional Quests:\s*(.+)/i);
if (optionalQuestsMatch) {
const questsText = optionalQuestsMatch[1].trim();
if (questsText && questsText !== 'None') {
// Split by comma and clean up
extensionSettings.quests.optional = questsText
.split(',')
.map(q => q.trim())
.filter(q => q && q !== 'None');
} else {
extensionSettings.quests.optional = [];
}
debugLog('[RPG Parser] Optional quests extracted:', extensionSettings.quests.optional);
}
debugLog('[RPG Parser] Final userStats after parsing:', {
health: extensionSettings.userStats.health,
satiety: extensionSettings.userStats.satiety,