303 lines
12 KiB
JavaScript
303 lines
12 KiB
JavaScript
export class FeedbackUI {
|
|
constructor(parentContainer, game) {
|
|
this.parentContainer = parentContainer;
|
|
this.game = game;
|
|
|
|
this.logContainer = null;
|
|
this.initLogContainer();
|
|
}
|
|
|
|
initLogContainer() {
|
|
this.logContainer = document.createElement('div');
|
|
Object.assign(this.logContainer.style, {
|
|
position: 'absolute',
|
|
top: '20%', // Leave space for top HUD
|
|
right: '20px',
|
|
width: '350px',
|
|
height: '60vh', // Fixed height or max height? User said "muy pequeño". Let's give it good vertical space.
|
|
maxHeight: 'none',
|
|
overflowY: 'auto',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'flex-start', // Align text to left
|
|
pointerEvents: 'none', // Allow clicking through if needed, but 'auto' for scroll?
|
|
// We need pointerEvents auto for scrolling.
|
|
pointerEvents: 'auto',
|
|
zIndex: '400',
|
|
fontFamily: '"Cinzel", serif',
|
|
scrollbarWidth: 'thin',
|
|
scrollbarColor: '#444 #222'
|
|
});
|
|
|
|
// Add a subtle background
|
|
this.logContainer.style.background = 'linear-gradient(to left, rgba(0,0,0,0.8), rgba(0,0,0,0))';
|
|
this.logContainer.style.padding = '10px';
|
|
this.logContainer.style.borderRadius = '8px';
|
|
this.logContainer.style.borderRight = '2px solid #555';
|
|
|
|
this.parentContainer.appendChild(this.logContainer);
|
|
}
|
|
|
|
addLogMessage(message, type = 'info') {
|
|
const entry = document.createElement('div');
|
|
Object.assign(entry.style, {
|
|
width: '100%',
|
|
marginBottom: '6px',
|
|
fontSize: '14px',
|
|
color: '#ccc',
|
|
textShadow: '1px 1px 0 #000',
|
|
opacity: '0',
|
|
transition: 'opacity 0.3s',
|
|
lineHeight: '1.4'
|
|
});
|
|
|
|
// Color coding based on type
|
|
if (type === 'combat-hit') entry.style.color = '#ff6666';
|
|
if (type === 'combat-miss') entry.style.color = '#aaaaaa';
|
|
if (type === 'combat-kill') entry.style.color = '#ff3333';
|
|
if (type === 'success') entry.style.color = '#66ff66';
|
|
if (type === 'warning') entry.style.color = '#ffcc00';
|
|
if (type === 'system') entry.style.color = '#88ccff';
|
|
if (type === 'event-log') entry.style.color = '#44ff44'; // Bright Green
|
|
|
|
entry.innerHTML = message;
|
|
|
|
this.logContainer.appendChild(entry);
|
|
|
|
// Auto scroll to bottom
|
|
this.logContainer.scrollTop = this.logContainer.scrollHeight;
|
|
|
|
// Fade In
|
|
requestAnimationFrame(() => { entry.style.opacity = '1'; });
|
|
|
|
// Optional: Fade out very old messages? Or keep history?
|
|
// Let's keep history for now, maybe limit children coune
|
|
if (this.logContainer.children.length > 50) {
|
|
this.logContainer.removeChild(this.logContainer.firstChild);
|
|
}
|
|
}
|
|
|
|
showModal(title, message, onClose) {
|
|
const overlay = document.createElement('div');
|
|
Object.assign(overlay.style, {
|
|
position: 'absolute', top: '0', left: '0', width: '100%', height: '100%',
|
|
backgroundColor: 'rgba(0, 0, 0, 0.7)', display: 'flex', justifyContent: 'center', alignItems: 'center',
|
|
pointerEvents: 'auto', zIndex: '1000'
|
|
});
|
|
|
|
const content = document.createElement('div');
|
|
Object.assign(content.style, {
|
|
backgroundColor: '#222', border: '2px solid #888', borderRadius: '8px', padding: '20px',
|
|
width: '300px', textAlign: 'center', color: '#fff', fontFamily: 'sans-serif'
|
|
});
|
|
|
|
const titleEl = document.createElement('h2');
|
|
titleEl.textContent = title;
|
|
Object.assign(titleEl.style, { marginTop: '0', color: '#f44' });
|
|
content.appendChild(titleEl);
|
|
|
|
const msgEl = document.createElement('p');
|
|
msgEl.innerHTML = message;
|
|
Object.assign(msgEl.style, { fontSize: '16px', lineHeight: '1.5' });
|
|
content.appendChild(msgEl);
|
|
|
|
const btn = document.createElement('button');
|
|
btn.textContent = 'Entendido';
|
|
Object.assign(btn.style, {
|
|
marginTop: '20px', padding: '10px 20px', fontSize: '16px', cursor: 'pointer',
|
|
backgroundColor: '#444', color: '#fff', border: '1px solid #888'
|
|
});
|
|
btn.onclick = () => {
|
|
if (overlay.parentNode) this.parentContainer.removeChild(overlay);
|
|
if (onClose) onClose();
|
|
};
|
|
content.appendChild(btn);
|
|
|
|
overlay.appendChild(content);
|
|
this.parentContainer.appendChild(overlay);
|
|
}
|
|
|
|
showConfirm(title, message, onConfirm) {
|
|
const overlay = document.createElement('div');
|
|
Object.assign(overlay.style, {
|
|
position: 'absolute', top: '0', left: '0', width: '100%', height: '100%',
|
|
backgroundColor: 'rgba(0, 0, 0, 0.7)', display: 'flex', justifyContent: 'center', alignItems: 'center',
|
|
pointerEvents: 'auto', zIndex: '1000'
|
|
});
|
|
|
|
const content = document.createElement('div');
|
|
Object.assign(content.style, {
|
|
backgroundColor: '#222', border: '2px solid #888', borderRadius: '8px', padding: '20px',
|
|
width: '300px', textAlign: 'center', color: '#fff', fontFamily: 'sans-serif'
|
|
});
|
|
|
|
const titleEl = document.createElement('h2');
|
|
titleEl.textContent = title;
|
|
Object.assign(titleEl.style, { marginTop: '0', color: '#f44' });
|
|
content.appendChild(titleEl);
|
|
|
|
const msgEl = document.createElement('p');
|
|
msgEl.innerHTML = message;
|
|
Object.assign(msgEl.style, { fontSize: '16px', lineHeight: '1.5' });
|
|
content.appendChild(msgEl);
|
|
|
|
const buttons = document.createElement('div');
|
|
Object.assign(buttons.style, { display: 'flex', justifyContent: 'space-around', marginTop: '20px' });
|
|
|
|
const cancelBtn = document.createElement('button');
|
|
cancelBtn.textContent = 'Cancelar';
|
|
Object.assign(cancelBtn.style, {
|
|
padding: '10px 20px', fontSize: '16px', cursor: 'pointer',
|
|
backgroundColor: '#555', color: '#fff', border: '1px solid #888'
|
|
});
|
|
cancelBtn.onclick = () => { this.parentContainer.removeChild(overlay); };
|
|
buttons.appendChild(cancelBtn);
|
|
|
|
const confirmBtn = document.createElement('button');
|
|
confirmBtn.textContent = 'Aceptar';
|
|
Object.assign(confirmBtn.style, {
|
|
padding: '10px 20px', fontSize: '16px', cursor: 'pointer',
|
|
backgroundColor: '#2a5', color: '#fff', border: '1px solid #888'
|
|
});
|
|
confirmBtn.onclick = () => {
|
|
if (onConfirm) onConfirm();
|
|
this.parentContainer.removeChild(overlay);
|
|
};
|
|
buttons.appendChild(confirmBtn);
|
|
|
|
content.appendChild(buttons);
|
|
overlay.appendChild(content);
|
|
this.parentContainer.appendChild(overlay);
|
|
}
|
|
|
|
showEventCard(cardData, callback) {
|
|
const overlay = document.createElement('div');
|
|
Object.assign(overlay.style, {
|
|
position: 'absolute', top: '0', left: '0', width: '100%', height: '100%',
|
|
backgroundColor: 'rgba(0, 0, 0, 0.85)', display: 'flex', justifyContent: 'center', alignItems: 'center',
|
|
pointerEvents: 'auto', zIndex: '2000'
|
|
});
|
|
|
|
// Card Container
|
|
const card = document.createElement('div');
|
|
Object.assign(card.style, {
|
|
backgroundColor: '#1a1a1a',
|
|
backgroundImage: 'repeating-linear-gradient(45deg, #222 25%, transparent 25%, transparent 75%, #222 75%, #222), repeating-linear-gradient(45deg, #222 25%, #1a1a1a 25%, #1a1a1a 75%, #222 75%, #222)',
|
|
backgroundPosition: '0 0, 10px 10px',
|
|
backgroundSize: '20px 20px',
|
|
border: '4px solid #8b0000',
|
|
borderRadius: '12px',
|
|
padding: '30px',
|
|
width: '320px',
|
|
textAlign: 'center',
|
|
color: '#fff',
|
|
fontFamily: '"Cinzel", serif',
|
|
boxShadow: '0 0 30px rgba(139, 0, 0, 0.6), inset 0 0 50px rgba(0,0,0,0.8)',
|
|
position: 'relative'
|
|
});
|
|
|
|
// Title
|
|
const titleEl = document.createElement('h2');
|
|
titleEl.textContent = cardData.titulo || "Evento";
|
|
Object.assign(titleEl.style, {
|
|
marginTop: '0',
|
|
marginBottom: '10px',
|
|
color: '#ff4444',
|
|
textTransform: 'uppercase',
|
|
letterSpacing: '2px',
|
|
fontSize: '24px',
|
|
textShadow: '2px 2px 0 #000'
|
|
});
|
|
card.appendChild(titleEl);
|
|
|
|
// Subtitle/Type
|
|
if (cardData.tipo) {
|
|
const typeEl = document.createElement('div');
|
|
typeEl.textContent = cardData.tipo;
|
|
Object.assign(typeEl.style, {
|
|
fontSize: '12px',
|
|
color: '#aaa',
|
|
marginBottom: '20px',
|
|
textTransform: 'uppercase',
|
|
borderBottom: '1px solid #444',
|
|
paddingBottom: '5px'
|
|
});
|
|
card.appendChild(typeEl);
|
|
}
|
|
|
|
// Image Placeholder (Optional)
|
|
// const img = document.createElement('div'); ...
|
|
|
|
// Message
|
|
const msgEl = document.createElement('p');
|
|
// If it's pure text or HTML
|
|
msgEl.innerHTML = cardData.descripcion || cardData.texto || "";
|
|
Object.assign(msgEl.style, {
|
|
fontSize: '16px',
|
|
lineHeight: '1.6',
|
|
color: '#ddd',
|
|
textAlign: 'justify',
|
|
fontStyle: 'italic',
|
|
marginBottom: '25px'
|
|
});
|
|
card.appendChild(msgEl);
|
|
|
|
// Action Button
|
|
const btn = document.createElement('button');
|
|
btn.textContent = 'CONTINUAR';
|
|
Object.assign(btn.style, {
|
|
padding: '12px 30px',
|
|
fontSize: '16px',
|
|
cursor: 'pointer',
|
|
backgroundColor: '#8b0000',
|
|
color: '#fff',
|
|
border: '2px solid #ff4444',
|
|
borderRadius: '4px',
|
|
fontFamily: 'inherit',
|
|
fontWeight: 'bold',
|
|
textTransform: 'uppercase',
|
|
boxShadow: '0 4px 0 #440000',
|
|
transition: 'transform 0.1s'
|
|
});
|
|
|
|
btn.onmousedown = () => btn.style.transform = 'translateY(2px)';
|
|
btn.onmouseup = () => btn.style.transform = 'translateY(0)';
|
|
|
|
btn.onclick = () => {
|
|
if (overlay.parentNode) this.parentContainer.removeChild(overlay);
|
|
if (callback) callback();
|
|
};
|
|
card.appendChild(btn);
|
|
|
|
overlay.appendChild(card);
|
|
this.parentContainer.appendChild(overlay);
|
|
}
|
|
|
|
showTemporaryMessage(title, message, duration = 2000) {
|
|
const modal = document.createElement('div');
|
|
Object.assign(modal.style, {
|
|
position: 'absolute', top: '25%', left: '50%', transform: 'translate(-50%, -50%)',
|
|
backgroundColor: 'rgba(139, 0, 0, 0.9)', color: '#fff', padding: '15px 30px',
|
|
borderRadius: '8px', border: '2px solid #ff4444', fontFamily: '"Cinzel", serif',
|
|
fontSize: '20px', textShadow: '2px 2px 4px black', zIndex: '2000', pointerEvents: 'none',
|
|
opacity: '0', transition: 'opacity 0.5s ease-in-out'
|
|
});
|
|
|
|
modal.innerHTML = `
|
|
<h3 style="margin:0; text-align:center; color: #FFD700; text-transform: uppercase;">⚠️ ${title}</h3>
|
|
<div style="margin-top:5px; font-size: 16px;">${message}</div>
|
|
`;
|
|
|
|
document.body.appendChild(modal);
|
|
|
|
requestAnimationFrame(() => { modal.style.opacity = '1'; });
|
|
|
|
setTimeout(() => {
|
|
modal.style.opacity = '0';
|
|
setTimeout(() => {
|
|
if (modal.parentNode) document.body.removeChild(modal);
|
|
}, 500);
|
|
}, duration);
|
|
}
|
|
}
|