feat(thought): wire client socket, GameScene thought handling, emoji animation, and info panel display

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-03-08 21:12:00 +00:00
parent b515f7195f
commit daddf2583d
3 changed files with 100 additions and 3 deletions
+41 -3
View File
@@ -33,6 +33,7 @@ export class NpcInfoPanel {
private nameEl: HTMLDivElement;
private activityEl: HTMLDivElement;
private recentEventsEl: HTMLDivElement;
private thoughtEl: HTMLDivElement;
private separatorEl: HTMLDivElement;
private needsBarsContainer: HTMLDivElement;
private needsBars: Map<string, { wrapper: HTMLDivElement; fill: HTMLDivElement; valueEl: HTMLDivElement }> = new Map();
@@ -60,6 +61,9 @@ export class NpcInfoPanel {
border: 3px solid ${EB.borderOuter};
background: ${EB.borderGap};
z-index: 1000;
max-height: calc(100vh - 32px);
display: flex;
flex-direction: column;
transform: translateX(410px);
transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
box-shadow:
@@ -78,6 +82,9 @@ export class NpcInfoPanel {
background: ${EB.bgPanel};
overflow: hidden;
position: relative;
display: flex;
flex-direction: column;
min-height: 0;
`;
// Subtle diagonal shine overlay
@@ -106,6 +113,7 @@ export class NpcInfoPanel {
display: flex;
justify-content: center;
position: relative;
flex-shrink: 0;
`;
// Inner portrait border (another doubled frame, just for the portrait)
@@ -148,6 +156,7 @@ export class NpcInfoPanel {
display: flex;
border-bottom: 2px solid ${EB.borderInner};
font-family: 'Press Start 2P', monospace;
flex-shrink: 0;
`;
this.statusTab = document.createElement('div');
@@ -181,8 +190,15 @@ export class NpcInfoPanel {
tabBar.appendChild(this.relationshipsTab);
this.container.appendChild(tabBar);
// Content wrapper
// Content wrapper (scrollable area below portrait + tabs)
const contentWrapper = document.createElement('div');
contentWrapper.style.cssText = `
overflow-y: auto;
min-height: 0;
flex: 1;
scrollbar-width: thin;
scrollbar-color: ${EB.borderInner} ${EB.bgDeep};
`;
// Status content (existing info section)
this.statusContent = document.createElement('div');
@@ -234,6 +250,20 @@ export class NpcInfoPanel {
`;
this.statusContent.appendChild(this.backstoryEl);
// Inner thought (italic first-person, shown above recent events)
this.thoughtEl = document.createElement('div');
this.thoughtEl.style.cssText = `
display: none;
font-family: 'Press Start 2P', monospace;
font-size: 10px;
color: ${EB.textSecondary};
text-align: center;
padding: 4px 8px;
font-style: italic;
line-height: 1.6;
`;
this.statusContent.appendChild(this.thoughtEl);
// Recent events section (hidden by default)
this.recentEventsEl = document.createElement('div');
this.recentEventsEl.style.cssText = `
@@ -294,8 +324,6 @@ export class NpcInfoPanel {
display: none;
padding: 8px 12px;
font-family: 'Press Start 2P', monospace;
max-height: 300px;
overflow-y: auto;
`;
contentWrapper.appendChild(this.relationshipsContent);
@@ -394,6 +422,16 @@ export class NpcInfoPanel {
}
}
updateThought(text: string | null): void {
if (!text) {
this.thoughtEl.style.display = 'none';
return;
}
this.thoughtEl.style.display = '';
this.thoughtEl.textContent = `"${text}"`;
this.thoughtEl.title = text;
}
updatePortrait(portraitDataUrl: string): void {
this.portraitImg.style.opacity = '0';
setTimeout(() => {