Make RPG attributes (STR/DEX/etc) customizable and editable
- Replace showRPGAttributes boolean with rpgAttributes array in trackerConfig - Add RPG Attributes section in Edit Trackers with add/remove/rename/toggle - Dynamically generate attribute display from config in userStats.js - Add migration from old showRPGAttributes to new rpgAttributes array - Initialize new attributes with default value of 10 in classicStats - Default attributes: STR, DEX, CON, INT, WIS, CHA (all enabled)
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"chat_completion_source": "custom",
|
||||||
|
"openai_model": "gpt-5-2025-08-07",
|
||||||
|
"claude_model": "claude-sonnet-4-0",
|
||||||
|
"openrouter_model": "anthropic/claude-sonnet-4.5",
|
||||||
|
"openrouter_use_fallback": false,
|
||||||
|
"openrouter_group_models": true,
|
||||||
|
"openrouter_sort_models": "context_length",
|
||||||
|
"openrouter_providers": [],
|
||||||
|
"openrouter_allow_fallbacks": false,
|
||||||
|
"openrouter_middleout": "off",
|
||||||
|
"ai21_model": "jamba-1.5-large",
|
||||||
|
"mistralai_model": "mistral-large-latest",
|
||||||
|
"cohere_model": "command-r-plus",
|
||||||
|
"perplexity_model": "",
|
||||||
|
"groq_model": "llama3-70b-8192",
|
||||||
|
"xai_model": "grok-3-beta",
|
||||||
|
"pollinations_model": "openai",
|
||||||
|
"aimlapi_model": "gpt-4o-mini-2024-07-18",
|
||||||
|
"electronhub_model": "gpt-4o-mini",
|
||||||
|
"electronhub_sort_models": "alphabetically",
|
||||||
|
"electronhub_group_models": false,
|
||||||
|
"moonshot_model": "kimi-latest",
|
||||||
|
"fireworks_model": "accounts/fireworks/models/kimi-k2-instruct",
|
||||||
|
"cometapi_model": "gpt-4o",
|
||||||
|
"zai_model": "glm-4.6",
|
||||||
|
"custom_model": "claude-opus-4-1-20250805-thinking-16k-v2",
|
||||||
|
"custom_prompt_post_processing": "semi",
|
||||||
|
"google_model": "gemini-2.0-flash-thinking-exp-01-21",
|
||||||
|
"vertexai_model": "gemini-2.0-flash-001",
|
||||||
|
"nanogpt_model": "gpt-4o-mini",
|
||||||
|
"deepseek_model": "chatgpt-4o-latest",
|
||||||
|
"azure_api_version": "2024-02-15-preview",
|
||||||
|
"azure_openai_model": "",
|
||||||
|
"temperature": 1,
|
||||||
|
"frequency_penalty": 0,
|
||||||
|
"presence_penalty": 0,
|
||||||
|
"top_p": 1,
|
||||||
|
"top_k": 0,
|
||||||
|
"top_a": 1,
|
||||||
|
"min_p": 0,
|
||||||
|
"repetition_penalty": 1,
|
||||||
|
"openai_max_context": 2000000,
|
||||||
|
"openai_max_tokens": 8192,
|
||||||
|
"wrap_in_quotes": false,
|
||||||
|
"names_behavior": -1,
|
||||||
|
"send_if_empty": "",
|
||||||
|
"impersonation_prompt": "Change of plans! Write a response as the user's {{user}} now. Match their style from the conversation history so far.",
|
||||||
|
"new_chat_prompt": "",
|
||||||
|
"new_group_chat_prompt": "",
|
||||||
|
"new_example_chat_prompt": "{{trim}}",
|
||||||
|
"continue_nudge_prompt": "Your last message got cut off. Continue writing it. Do not include any parts of the original one. Respond with a direct continuation only.",
|
||||||
|
"bias_preset_selected": "Marinara's Logit Bias",
|
||||||
|
"max_context_unlocked": false,
|
||||||
|
"wi_format": "{0}",
|
||||||
|
"scenario_format": "{{scenario}}",
|
||||||
|
"personality_format": "{{personality}}{{trim}}",
|
||||||
|
"group_nudge_prompt": "",
|
||||||
|
"stream_openai": true,
|
||||||
|
"show_external_models": false,
|
||||||
|
"assistant_prefill": "",
|
||||||
|
"assistant_impersonation": "",
|
||||||
|
"claude_use_sysprompt": true,
|
||||||
|
"use_makersuite_sysprompt": false,
|
||||||
|
"squash_system_messages": true,
|
||||||
|
"image_inlining": true,
|
||||||
|
"inline_image_quality": "high",
|
||||||
|
"bypass_status_check": false,
|
||||||
|
"continue_prefill": false,
|
||||||
|
"seed": -1,
|
||||||
|
"n": 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"scriptName": "RPG: Clean HTML (From Outgoing Prompt)",
|
||||||
|
"findRegex": "/\\s?<(?!\\!--)(?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g",
|
||||||
|
"replaceString": "",
|
||||||
|
"trimStrings": [],
|
||||||
|
"placement": [2],
|
||||||
|
"disabled": false,
|
||||||
|
"markdownOnly": false,
|
||||||
|
"promptOnly": true,
|
||||||
|
"runOnEdit": true,
|
||||||
|
"substituteRegex": 0,
|
||||||
|
"minDepth": null,
|
||||||
|
"maxDepth": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scriptName": "RPG: Clean Tracker Blocks (Keeping Last)",
|
||||||
|
"findRegex": "/```\\n[\\s\\S]*?\\n---\\n[\\s\\S]*?```\\n+/g",
|
||||||
|
"replaceString": "",
|
||||||
|
"trimStrings": [],
|
||||||
|
"placement": [1, 2],
|
||||||
|
"disabled": false,
|
||||||
|
"markdownOnly": false,
|
||||||
|
"promptOnly": true,
|
||||||
|
"runOnEdit": true,
|
||||||
|
"substituteRegex": 0,
|
||||||
|
"minDepth": 3,
|
||||||
|
"maxDepth": null
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -118,6 +118,9 @@ import { ensureHtmlCleaningRegex, detectConflictingRegexScripts } from './src/sy
|
|||||||
import { setupMemoryRecollectionButton, updateMemoryRecollectionButton } from './src/systems/features/memoryRecollection.js';
|
import { setupMemoryRecollectionButton, updateMemoryRecollectionButton } from './src/systems/features/memoryRecollection.js';
|
||||||
import { initLorebookLimiter } from './src/systems/features/lorebookLimiter.js';
|
import { initLorebookLimiter } from './src/systems/features/lorebookLimiter.js';
|
||||||
|
|
||||||
|
// Utility modules
|
||||||
|
import { importAllDefaults } from './src/utils/importDefaults.js';
|
||||||
|
|
||||||
// Integration modules
|
// Integration modules
|
||||||
import {
|
import {
|
||||||
commitTrackerData,
|
commitTrackerData,
|
||||||
@@ -601,6 +604,14 @@ jQuery(async () => {
|
|||||||
// Non-critical - continue anyway
|
// Non-critical - continue anyway
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Import default preset and regexes if user doesn't have them
|
||||||
|
try {
|
||||||
|
await importAllDefaults();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[RPG Companion] Failed to import defaults:', error);
|
||||||
|
// Non-critical - continue anyway
|
||||||
|
}
|
||||||
|
|
||||||
// Register all event listeners
|
// Register all event listeners
|
||||||
try {
|
try {
|
||||||
registerAllEvents({
|
registerAllEvents({
|
||||||
|
|||||||
+44
-1
@@ -365,7 +365,14 @@ function migrateToTrackerConfig() {
|
|||||||
extensionSettings.trackerConfig = {
|
extensionSettings.trackerConfig = {
|
||||||
userStats: {
|
userStats: {
|
||||||
customStats: [],
|
customStats: [],
|
||||||
showRPGAttributes: true,
|
rpgAttributes: [
|
||||||
|
{ id: 'str', name: 'STR', enabled: true },
|
||||||
|
{ id: 'dex', name: 'DEX', enabled: true },
|
||||||
|
{ id: 'con', name: 'CON', enabled: true },
|
||||||
|
{ id: 'int', name: 'INT', enabled: true },
|
||||||
|
{ id: 'wis', name: 'WIS', enabled: true },
|
||||||
|
{ id: 'cha', name: 'CHA', enabled: true }
|
||||||
|
],
|
||||||
statusSection: {
|
statusSection: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
showMoodEmoji: true,
|
showMoodEmoji: true,
|
||||||
@@ -423,6 +430,42 @@ function migrateToTrackerConfig() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Migrate old showRPGAttributes boolean to rpgAttributes array
|
||||||
|
if (extensionSettings.trackerConfig.userStats.showRPGAttributes !== undefined) {
|
||||||
|
const shouldShow = extensionSettings.trackerConfig.userStats.showRPGAttributes;
|
||||||
|
extensionSettings.trackerConfig.userStats.rpgAttributes = [
|
||||||
|
{ id: 'str', name: 'STR', enabled: shouldShow },
|
||||||
|
{ id: 'dex', name: 'DEX', enabled: shouldShow },
|
||||||
|
{ id: 'con', name: 'CON', enabled: shouldShow },
|
||||||
|
{ id: 'int', name: 'INT', enabled: shouldShow },
|
||||||
|
{ id: 'wis', name: 'WIS', enabled: shouldShow },
|
||||||
|
{ id: 'cha', name: 'CHA', enabled: shouldShow }
|
||||||
|
];
|
||||||
|
delete extensionSettings.trackerConfig.userStats.showRPGAttributes;
|
||||||
|
console.log('[RPG Companion] Migrated showRPGAttributes to rpgAttributes array');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure rpgAttributes exists even if no migration was needed
|
||||||
|
if (!extensionSettings.trackerConfig.userStats.rpgAttributes) {
|
||||||
|
extensionSettings.trackerConfig.userStats.rpgAttributes = [
|
||||||
|
{ id: 'str', name: 'STR', enabled: true },
|
||||||
|
{ id: 'dex', name: 'DEX', enabled: true },
|
||||||
|
{ id: 'con', name: 'CON', enabled: true },
|
||||||
|
{ id: 'int', name: 'INT', enabled: true },
|
||||||
|
{ id: 'wis', name: 'WIS', enabled: true },
|
||||||
|
{ id: 'cha', name: 'CHA', enabled: true }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure all rpgAttributes have corresponding values in classicStats
|
||||||
|
if (extensionSettings.classicStats) {
|
||||||
|
for (const attr of extensionSettings.trackerConfig.userStats.rpgAttributes) {
|
||||||
|
if (extensionSettings.classicStats[attr.id] === undefined) {
|
||||||
|
extensionSettings.classicStats[attr.id] = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Migrate old presentCharacters structure to new format
|
// Migrate old presentCharacters structure to new format
|
||||||
if (extensionSettings.trackerConfig.presentCharacters) {
|
if (extensionSettings.trackerConfig.presentCharacters) {
|
||||||
const pc = extensionSettings.trackerConfig.presentCharacters;
|
const pc = extensionSettings.trackerConfig.presentCharacters;
|
||||||
|
|||||||
+9
-2
@@ -71,8 +71,15 @@ export let extensionSettings = {
|
|||||||
{ id: 'hygiene', name: 'Hygiene', enabled: true },
|
{ id: 'hygiene', name: 'Hygiene', enabled: true },
|
||||||
{ id: 'arousal', name: 'Arousal', enabled: true }
|
{ id: 'arousal', name: 'Arousal', enabled: true }
|
||||||
],
|
],
|
||||||
// RPG Attributes toggle
|
// RPG Attributes (customizable D&D-style attributes)
|
||||||
showRPGAttributes: true,
|
rpgAttributes: [
|
||||||
|
{ id: 'str', name: 'STR', enabled: true },
|
||||||
|
{ id: 'dex', name: 'DEX', enabled: true },
|
||||||
|
{ id: 'con', name: 'CON', enabled: true },
|
||||||
|
{ id: 'int', name: 'INT', enabled: true },
|
||||||
|
{ id: 'wis', name: 'WIS', enabled: true },
|
||||||
|
{ id: 'cha', name: 'CHA', enabled: true }
|
||||||
|
],
|
||||||
// Status section config
|
// Status section config
|
||||||
statusSection: {
|
statusSection: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
|||||||
@@ -86,7 +86,14 @@ export function renderUserStats() {
|
|||||||
{ id: 'hygiene', name: 'Hygiene', enabled: true },
|
{ id: 'hygiene', name: 'Hygiene', enabled: true },
|
||||||
{ id: 'arousal', name: 'Arousal', enabled: true }
|
{ id: 'arousal', name: 'Arousal', enabled: true }
|
||||||
],
|
],
|
||||||
showRPGAttributes: true,
|
rpgAttributes: [
|
||||||
|
{ id: 'str', name: 'STR', enabled: true },
|
||||||
|
{ id: 'dex', name: 'DEX', enabled: true },
|
||||||
|
{ id: 'con', name: 'CON', enabled: true },
|
||||||
|
{ id: 'int', name: 'INT', enabled: true },
|
||||||
|
{ id: 'wis', name: 'WIS', enabled: true },
|
||||||
|
{ id: 'cha', name: 'CHA', enabled: true }
|
||||||
|
],
|
||||||
statusSection: { enabled: true, showMoodEmoji: true, customFields: ['Conditions'] },
|
statusSection: { enabled: true, showMoodEmoji: true, customFields: ['Conditions'] },
|
||||||
skillsSection: { enabled: false, label: 'Skills' }
|
skillsSection: { enabled: false, label: 'Skills' }
|
||||||
};
|
};
|
||||||
@@ -171,60 +178,32 @@ export function renderUserStats() {
|
|||||||
|
|
||||||
html += '</div>'; // Close rpg-stats-left
|
html += '</div>'; // Close rpg-stats-left
|
||||||
|
|
||||||
// RPG Attributes section (conditionally rendered)
|
// RPG Attributes section (dynamically generated from config)
|
||||||
if (config.showRPGAttributes) {
|
const rpgAttributes = config.rpgAttributes || [];
|
||||||
|
const enabledAttributes = rpgAttributes.filter(attr => attr && attr.enabled && attr.name && attr.id);
|
||||||
|
|
||||||
|
if (enabledAttributes.length > 0) {
|
||||||
html += `
|
html += `
|
||||||
<div class="rpg-stats-right">
|
<div class="rpg-stats-right">
|
||||||
<div class="rpg-classic-stats">
|
<div class="rpg-classic-stats">
|
||||||
<div class="rpg-classic-stats-grid">
|
<div class="rpg-classic-stats-grid">
|
||||||
<div class="rpg-classic-stat" data-stat="str">
|
`;
|
||||||
<span class="rpg-classic-stat-label">STR</span>
|
|
||||||
|
enabledAttributes.forEach(attr => {
|
||||||
|
const value = extensionSettings.classicStats[attr.id] !== undefined ? extensionSettings.classicStats[attr.id] : 10;
|
||||||
|
html += `
|
||||||
|
<div class="rpg-classic-stat" data-stat="${attr.id}">
|
||||||
|
<span class="rpg-classic-stat-label">${attr.name}</span>
|
||||||
<div class="rpg-classic-stat-buttons">
|
<div class="rpg-classic-stat-buttons">
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-decrease" data-stat="str">−</button>
|
<button class="rpg-classic-stat-btn rpg-stat-decrease" data-stat="${attr.id}">−</button>
|
||||||
<span class="rpg-classic-stat-value">${extensionSettings.classicStats.str}</span>
|
<span class="rpg-classic-stat-value">${value}</span>
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-increase" data-stat="str">+</button>
|
<button class="rpg-classic-stat-btn rpg-stat-increase" data-stat="${attr.id}">+</button>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rpg-classic-stat" data-stat="dex">
|
|
||||||
<span class="rpg-classic-stat-label">DEX</span>
|
|
||||||
<div class="rpg-classic-stat-buttons">
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-decrease" data-stat="dex">−</button>
|
|
||||||
<span class="rpg-classic-stat-value">${extensionSettings.classicStats.dex}</span>
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-increase" data-stat="dex">+</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rpg-classic-stat" data-stat="con">
|
|
||||||
<span class="rpg-classic-stat-label">CON</span>
|
|
||||||
<div class="rpg-classic-stat-buttons">
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-decrease" data-stat="con">−</button>
|
|
||||||
<span class="rpg-classic-stat-value">${extensionSettings.classicStats.con}</span>
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-increase" data-stat="con">+</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rpg-classic-stat" data-stat="int">
|
|
||||||
<span class="rpg-classic-stat-label">INT</span>
|
|
||||||
<div class="rpg-classic-stat-buttons">
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-decrease" data-stat="int">−</button>
|
|
||||||
<span class="rpg-classic-stat-value">${extensionSettings.classicStats.int}</span>
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-increase" data-stat="int">+</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rpg-classic-stat" data-stat="wis">
|
|
||||||
<span class="rpg-classic-stat-label">WIS</span>
|
|
||||||
<div class="rpg-classic-stat-buttons">
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-decrease" data-stat="wis">−</button>
|
|
||||||
<span class="rpg-classic-stat-value">${extensionSettings.classicStats.wis}</span>
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-increase" data-stat="wis">+</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rpg-classic-stat" data-stat="cha">
|
|
||||||
<span class="rpg-classic-stat-label">CHA</span>
|
|
||||||
<div class="rpg-classic-stat-buttons">
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-decrease" data-stat="cha">−</button>
|
|
||||||
<span class="rpg-classic-stat-value">${extensionSettings.classicStats.cha}</span>
|
|
||||||
<button class="rpg-classic-stat-btn rpg-stat-increase" data-stat="cha">+</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += `
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -127,7 +127,14 @@ function resetToDefaults() {
|
|||||||
{ id: 'hygiene', name: 'Hygiene', enabled: true },
|
{ id: 'hygiene', name: 'Hygiene', enabled: true },
|
||||||
{ id: 'arousal', name: 'Arousal', enabled: true }
|
{ id: 'arousal', name: 'Arousal', enabled: true }
|
||||||
],
|
],
|
||||||
showRPGAttributes: true,
|
rpgAttributes: [
|
||||||
|
{ id: 'str', name: 'STR', enabled: true },
|
||||||
|
{ id: 'dex', name: 'DEX', enabled: true },
|
||||||
|
{ id: 'con', name: 'CON', enabled: true },
|
||||||
|
{ id: 'int', name: 'INT', enabled: true },
|
||||||
|
{ id: 'wis', name: 'WIS', enabled: true },
|
||||||
|
{ id: 'cha', name: 'CHA', enabled: true }
|
||||||
|
],
|
||||||
statusSection: {
|
statusSection: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
showMoodEmoji: true,
|
showMoodEmoji: true,
|
||||||
@@ -212,11 +219,31 @@ function renderUserStatsTab() {
|
|||||||
html += '</div>';
|
html += '</div>';
|
||||||
html += '<button class="rpg-btn-secondary" id="rpg-add-stat"><i class="fa-solid fa-plus"></i> Add Custom Stat</button>';
|
html += '<button class="rpg-btn-secondary" id="rpg-add-stat"><i class="fa-solid fa-plus"></i> Add Custom Stat</button>';
|
||||||
|
|
||||||
// RPG Attributes toggle
|
// RPG Attributes section
|
||||||
html += '<div class="rpg-editor-toggle-row">';
|
html += '<h4><i class="fa-solid fa-dice-d20"></i> RPG Attributes</h4>';
|
||||||
html += `<input type="checkbox" id="rpg-show-rpg-attrs" ${config.showRPGAttributes ? 'checked' : ''}>`;
|
html += '<div class="rpg-editor-stats-list" id="rpg-editor-attrs-list">';
|
||||||
html += '<label for="rpg-show-rpg-attrs">Show RPG Attributes (STR, DEX, etc.)</label>';
|
|
||||||
|
const rpgAttributes = config.rpgAttributes || [
|
||||||
|
{ id: 'str', name: 'STR', enabled: true },
|
||||||
|
{ id: 'dex', name: 'DEX', enabled: true },
|
||||||
|
{ id: 'con', name: 'CON', enabled: true },
|
||||||
|
{ id: 'int', name: 'INT', enabled: true },
|
||||||
|
{ id: 'wis', name: 'WIS', enabled: true },
|
||||||
|
{ id: 'cha', name: 'CHA', enabled: true }
|
||||||
|
];
|
||||||
|
|
||||||
|
rpgAttributes.forEach((attr, index) => {
|
||||||
|
html += `
|
||||||
|
<div class="rpg-editor-stat-item" data-index="${index}">
|
||||||
|
<input type="checkbox" ${attr.enabled ? 'checked' : ''} class="rpg-attr-toggle" data-index="${index}">
|
||||||
|
<input type="text" value="${attr.name}" class="rpg-attr-name" data-index="${index}" placeholder="Attribute Name">
|
||||||
|
<button class="rpg-attr-remove" data-index="${index}" title="Remove attribute"><i class="fa-solid fa-trash"></i></button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
html += '<button class="rpg-btn-secondary" id="rpg-add-attr"><i class="fa-solid fa-plus"></i> Add Attribute</button>';
|
||||||
|
|
||||||
// Status Section
|
// Status Section
|
||||||
html += '<h4><i class="fa-solid fa-face-smile"></i> Status Section</h4>';
|
html += '<h4><i class="fa-solid fa-face-smile"></i> Status Section</h4>';
|
||||||
@@ -287,9 +314,41 @@ function setupUserStatsListeners() {
|
|||||||
extensionSettings.trackerConfig.userStats.customStats[index].name = $(this).val();
|
extensionSettings.trackerConfig.userStats.customStats[index].name = $(this).val();
|
||||||
});
|
});
|
||||||
|
|
||||||
// RPG attributes toggle
|
// Add attribute
|
||||||
$('#rpg-show-rpg-attrs').off('change').on('change', function() {
|
$('#rpg-add-attr').off('click').on('click', function() {
|
||||||
extensionSettings.trackerConfig.userStats.showRPGAttributes = $(this).is(':checked');
|
if (!extensionSettings.trackerConfig.userStats.rpgAttributes) {
|
||||||
|
extensionSettings.trackerConfig.userStats.rpgAttributes = [];
|
||||||
|
}
|
||||||
|
const newId = 'attr_' + Date.now();
|
||||||
|
extensionSettings.trackerConfig.userStats.rpgAttributes.push({
|
||||||
|
id: newId,
|
||||||
|
name: 'NEW',
|
||||||
|
enabled: true
|
||||||
|
});
|
||||||
|
// Initialize value in classicStats if doesn't exist
|
||||||
|
if (extensionSettings.classicStats[newId] === undefined) {
|
||||||
|
extensionSettings.classicStats[newId] = 10;
|
||||||
|
}
|
||||||
|
renderUserStatsTab();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove attribute
|
||||||
|
$('.rpg-attr-remove').off('click').on('click', function() {
|
||||||
|
const index = $(this).data('index');
|
||||||
|
extensionSettings.trackerConfig.userStats.rpgAttributes.splice(index, 1);
|
||||||
|
renderUserStatsTab();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Toggle attribute
|
||||||
|
$('.rpg-attr-toggle').off('change').on('change', function() {
|
||||||
|
const index = $(this).data('index');
|
||||||
|
extensionSettings.trackerConfig.userStats.rpgAttributes[index].enabled = $(this).is(':checked');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Rename attribute
|
||||||
|
$('.rpg-attr-name').off('blur').on('blur', function() {
|
||||||
|
const index = $(this).data('index');
|
||||||
|
extensionSettings.trackerConfig.userStats.rpgAttributes[index].name = $(this).val();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Status section toggles
|
// Status section toggles
|
||||||
|
|||||||
Reference in New Issue
Block a user