document.addEventListener('DOMContentLoaded', function() { // Initialize counters let classCount = 0; let raceCount = 0; // Generate RPG button functionality document.querySelector('button.bg-primary-500').addEventListener('click', function() { // Collect all form data const formData = { worldName: document.querySelector('input[type="text"]').value, backgroundStory: document.querySelector('textarea').value, majorFactions: document.querySelectorAll('input[type="text"]')[1].value, races: [], classes: [], settings: { sessionLength: document.querySelector('select').value, difficulty: document.querySelectorAll('select')[1].value, playerCount: document.querySelector('input[type="number"]').value, experienceSystem: document.querySelectorAll('select')[2].value } }; // Collect races data document.querySelectorAll('.race-card').forEach(card => { formData.races.push({ name: card.querySelector('h3').textContent, description: card.querySelector('textarea').value, size: card.querySelector('select').value, speed: card.querySelector('input[type="text"]').value, traits: Array.from(card.querySelectorAll('.traits-container input')).map(input => input.value) }); }); // Collect classes data document.querySelectorAll('.class-card').forEach(card => { formData.classes.push({ name: card.querySelector('h3').textContent, attribute: card.querySelector('select').value, hitPoints: card.querySelector('input[type="text"]').value, armor: card.querySelectorAll('select')[1].value, description: card.querySelector('textarea').value, abilities: Array.from(card.querySelectorAll('.abilities-container input')).map(input => input.value) }); }); // Create download link const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(formData, null, 2)); const downloadAnchor = document.createElement('a'); downloadAnchor.setAttribute('href', dataStr); downloadAnchor.setAttribute('download', `${formData.worldName || 'rpg'}_settings.json`); document.body.appendChild(downloadAnchor); downloadAnchor.click(); document.body.removeChild(downloadAnchor); }); // Handle lore file upload document.getElementById('lore-upload').addEventListener('change', function(e) { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(e) { try { let loreData; if (file.name.endsWith('.doc') || file.name.endsWith('.docx')) { // For DOC files, we'll just display the raw text loreData = { worldName: 'Imported DOC File', backgroundStory: e.target.result, majorFactions: 'From imported DOC file' }; } else { loreData = JSON.parse(e.target.result); } // Populate lore fields with uploaded data if (loreData.worldName) { document.querySelector('input[type="text"]').value = loreData.worldName; } if (loreData.backgroundStory) { document.querySelector('textarea').value = loreData.backgroundStory; } if (loreData.majorFactions) { document.querySelectorAll('input[type="text"]')[1].value = loreData.majorFactions; } } catch (error) { alert('Error parsing lore file. Please check the format.'); } }; reader.readAsText(file); }); // Handle races file upload document.getElementById('races-upload').addEventListener('change', function(e) { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(e) { try { let racesData; if (file.name.endsWith('.doc') || file.name.endsWith('.docx')) { // For DOC files, we'll parse into structured data const docContent = e.target.result; const lines = docContent.split('\n'); racesData = []; let currentRace = {}; lines.forEach(line => { if (line.trim().startsWith('Race:')) { if (Object.keys(currentRace).length > 0) { racesData.push(currentRace); } currentRace = { name: line.replace('Race:', '').trim(), description: '', size: 'Medium', speed: '30', traits: [] }; } else if (line.trim().startsWith('Description:')) { currentRace.description = line.replace('Description:', '').trim(); } else if (line.trim().startsWith('Trait:')) { currentRace.traits.push(line.replace('Trait:', '').trim()); } }); if (Object.keys(currentRace).length > 0) { racesData.push(currentRace); } if (racesData.length === 0) { racesData = [{name: 'Imported DOC', description: e.target.result}]; } } else { racesData = JSON.parse(e.target.result); } const container = document.getElementById('races-container'); container.innerHTML = ''; // Clear existing races racesData.forEach((raceData, index) => { raceCount++; const raceCard = document.createElement('div'); raceCard.className = 'race-card bg-gray-50 p-4 rounded-lg border border-gray-200 mb-4'; raceCard.innerHTML = `

${raceData.name || `New Race #${index+1}`}

${raceData.traits ? raceData.traits.map(trait => `
`).join('') : ''}
`; container.appendChild(raceCard); feather.replace(); // Add event listener for delete button raceCard.querySelector('button').addEventListener('click', function() { container.removeChild(raceCard); raceCount--; }); // Add event listener for add trait button const traitsBtn = raceCard.querySelector('.traits-container').nextElementSibling; traitsBtn.addEventListener('click', function() { addTraitField(this.previousElementSibling); }); }); } catch (error) { alert('Error processing races file. Showing raw content.'); const container = document.getElementById('races-container'); container.innerHTML = `

File Content

${e.target.result}
`; } }; if (file.name.endsWith('.doc') || file.name.endsWith('.docx')) { reader.readAsText(file); } else { reader.readAsText(file); } }); // Handle classes file upload document.getElementById('classes-upload').addEventListener('change', function(e) { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(e) { try { let classesData; if (file.name.endsWith('.doc') || file.name.endsWith('.docx')) { // For DOC files, we'll parse into structured data const docContent = e.target.result; const lines = docContent.split('\n'); classesData = []; let currentClass = {}; lines.forEach(line => { if (line.trim().startsWith('Class:')) { if (Object.keys(currentClass).length > 0) { classesData.push(currentClass); } currentClass = { name: line.replace('Class:', '').trim(), attribute: 'Strength', hitPoints: '1d8', armor: 'Light', description: '', abilities: [] }; } else if (line.trim().startsWith('Description:')) { currentClass.description = line.replace('Description:', '').trim(); } else if (line.trim().startsWith('Ability:')) { currentClass.abilities.push(line.replace('Ability:', '').trim()); } }); if (Object.keys(currentClass).length > 0) { classesData.push(currentClass); } if (classesData.length === 0) { classesData = [{name: 'Imported DOC', description: e.target.result}]; } } else { classesData = JSON.parse(e.target.result); } const container = document.getElementById('classes-container'); container.innerHTML = ''; // Clear existing classes classesData.forEach((classData, index) => { classCount++; const classCard = document.createElement('div'); classCard.className = 'class-card bg-gray-50 p-4 rounded-lg border border-gray-200 mb-4'; classCard.innerHTML = `

${classData.name || `New Class #${index+1}`}

${classData.abilities ? classData.abilities.map(ability => `
`).join('') : ''}
`; container.appendChild(classCard); feather.replace(); // Add event listener for delete button classCard.querySelector('button').addEventListener('click', function() { container.removeChild(classCard); classCount--; }); // Add event listeners for abilities const abilitiesBtn = classCard.querySelector('.abilities-container').nextElementSibling; abilitiesBtn.addEventListener('click', function() { addAbilityField(this.previousElementSibling); }); // Add event listeners for existing ability delete buttons classCard.querySelectorAll('.abilities-container button').forEach(btn => { btn.addEventListener('click', function() { this.parentElement.remove(); }); }); }); } catch (error) { alert('Error parsing classes file. Please check the format.'); } }; reader.readAsText(file); }); function addAbilityField(container) { const abilityDiv = document.createElement('div'); abilityDiv.className = 'flex items-center'; abilityDiv.innerHTML = ` `; container.appendChild(abilityDiv); feather.replace(); // Add event listener for delete ability button abilityDiv.querySelector('button').addEventListener('click', function() { container.removeChild(abilityDiv); }); } // Add race button functionality document.getElementById('add-race-btn').addEventListener('click', function() { raceCount++; const container = document.getElementById('races-container'); const raceCard = document.createElement('div'); raceCard.className = 'race-card bg-gray-50 p-4 rounded-lg border border-gray-200 mb-4'; raceCard.innerHTML = `

New Race #${raceCount}

`; container.appendChild(raceCard); feather.replace(); // Add event listener for delete button raceCard.querySelector('button').addEventListener('click', function() { container.removeChild(raceCard); raceCount--; }); // Add event listener for add trait button const traitsBtn = raceCard.querySelector('.traits-container').nextElementSibling; traitsBtn.addEventListener('click', function() { const traitsContainer = this.previousElementSibling; const traitDiv = document.createElement('div'); traitDiv.className = 'flex items-center'; traitDiv.innerHTML = ` `; traitsContainer.appendChild(traitDiv); feather.replace(); // Add event listener for delete trait button traitDiv.querySelector('button').addEventListener('click', function() { traitsContainer.removeChild(traitDiv); }); }); }); // Add class button functionality document.getElementById('add-class-btn').addEventListener('click', function() { classCount++; const container = document.getElementById('classes-container'); const classCard = document.createElement('div'); classCard.className = 'class-card bg-gray-50 p-4 rounded-lg border border-gray-200 mb-4'; classCard.innerHTML = `

New Class #${classCount}

`; container.appendChild(classCard); feather.replace(); // Add event listener for delete button classCard.querySelector('button').addEventListener('click', function() { container.removeChild(classCard); classCount--; }); // Add event listener for add ability button const abilitiesBtn = classCard.querySelector('.abilities-container').nextElementSibling; abilitiesBtn.addEventListener('click', function() { const abilitiesContainer = this.previousElementSibling; const abilityDiv = document.createElement('div'); abilityDiv.className = 'flex items-center'; abilityDiv.innerHTML = ` `; abilitiesContainer.appendChild(abilityDiv); feather.replace(); // Add event listener for delete ability button abilityDiv.querySelector('button').addEventListener('click', function() { abilitiesContainer.removeChild(abilityDiv); }); }); }); // Initialize tooltips for icons const tooltipTriggers = document.querySelectorAll('[data-tooltip]'); tooltipTriggers.forEach(trigger => { const tooltip = document.createElement('div'); tooltip.className = 'tooltip hidden absolute bg-black text-white text-xs px-2 py-1 rounded whitespace-nowrap -mt-8'; tooltip.textContent = trigger.getAttribute('data-tooltip'); trigger.appendChild(tooltip); trigger.addEventListener('mouseenter', () => { tooltip.classList.remove('hidden'); }); trigger.addEventListener('mouseleave', () => { tooltip.classList.add('hidden'); }); }); });