Space Mission Simulator / Log Generator

and outputDiv.style.display = 'block'; outputDiv.scrollIntoView({ behavior: 'smooth', block: 'center' }); }; // --- Event Listeners --- generateBtn.addEventListener('click', () => { console.log("Simulate button clicked"); try { const inputs = { commanderName: commanderNameInput.value.trim(), missionType: missionTypeSelect.value, destinationType: destinationTypeSelect.value, shipClass: shipClassSelect.value, crewFocus: crewFocusSelect.value }; currentMission = generateMissionLog(inputs); console.log("Mission log generated:", currentMission.codename); displayMissionLog(currentMission); } catch(error) { console.error("Error in generate click handler:", error); codenameH4.textContent = "Simulation Error"; headerDiv.innerHTML = ""; logBodyDiv.innerHTML = "

ERROR: Failed to generate mission log. Check console (F12).

"; outputDiv.style.display = 'block'; } }); downloadBtn.addEventListener('click', () => { console.log("Download button clicked"); if (!currentMission || !currentMission.codename) { alert("Please simulate a mission first!"); return; } try { const { jsPDF } = window.jspdf; const { autoTable } = window.jspdfAutotable; const doc = new jsPDF(); // --- PDF Styling --- const primaryColorPDF = '#00bcd4'; // Cyan const secondaryColorPDF = '#ff9800'; // Orange const textColorPDF = '#333333'; // Dark Gray text on white const headerColorPDF = '#0a192f'; // Dark Blue header bg const logFont = 'Courier'; // Monospace for log const titleFont = 'Helvetica'; // Standard for titles const headingFontSize = 16; const subHeadingFontSize = 11; const normalFontSize = 9; const codenameFontSize = 18; let yPos = 15; const leftMargin = 15; const textWidth = doc.internal.pageSize.getWidth() - (leftMargin * 2); const lineSpacing = 4.5; // Adjust for smaller font const sectionSpacing = 6; // --- PDF Content --- // Title doc.setFontSize(headingFontSize); doc.setFont(titleFont, 'bold'); doc.setTextColor(headerColorPDF); doc.text("Mission After-Action Report // CLASSIFIED", doc.internal.pageSize.getWidth() / 2, yPos, { align: 'center' }); yPos += sectionSpacing * 1.5; // Codename & Header Info Table doc.setFontSize(codenameFontSize); doc.setFont(titleFont, 'bold'); doc.setTextColor(primaryColorPDF); doc.text(currentMission.codename, leftMargin, yPos); yPos += lineSpacing * 2; autoTable(doc, { startY: yPos, theme: 'plain', styles: { fontSize: normalFontSize, font: titleFont, cellPadding: 1 }, columnStyles: { 0: { fontStyle: 'bold', textColor: headerColorPDF } }, body: [ ['Commander:', currentMission.commanderName], ['Ship:', currentMission.shipNameClass], ['Destination:', currentMission.destination], ['Final Status:', currentMission.finalStatus], // Include status here ], didDrawPage: (data) => { yPos = data.cursor.y + sectionSpacing; } }); // yPos updated by hook // Mission Log doc.setFontSize(subHeadingFontSize); doc.setFont(titleFont, 'bold'); doc.setTextColor(headerColorPDF); doc.text("Mission Log:", leftMargin, yPos); yPos += lineSpacing * 1.5; doc.setFont(logFont, 'normal'); doc.setFontSize(normalFontSize); doc.setTextColor(textColorPDF); // Process log narrative for PDF (remove HTML, handle lines) const logTextForPDF = currentMission.missionLogNarrative .replace(/

/g, '') // Remove

tags .replace(/<\/p>/g, '\n') // Replace

with newline .replace(/(.*?)<\/strong>/g, '$1') // Remove tags but keep content .replace(/(.*?)<\/span>/g, '$1') // Remove span tags but keep content .trim(); // Trim whitespace const logLines = doc.splitTextToSize(logTextForPDF, textWidth); logLines.forEach(line => { const requiredHeight = (normalFontSize * 0.4) + lineSpacing; if (yPos + requiredHeight > doc.internal.pageSize.getHeight() - 15) { // Page break check doc.addPage(); yPos = 15; // Reset font doc.setFont(logFont, 'normal'); doc.setFontSize(normalFontSize); doc.setTextColor(textColorPDF); } doc.text(line, leftMargin, yPos); yPos += lineSpacing; // Simple line spacing for mono font }); // Save PDF const safeCodename = currentMission.codename.replace(/[^a-z0-9]/gi, '_').toLowerCase(); doc.save(`mission_log_${safeCodename}.pdf`); } catch(error) { console.error("Error generating PDF:", error); alert("Subspace interference corrupted the PDF printer! Check console (F12)."); } }); }); // End DOMContentLoaded
Scroll to Top