Character Window — now matches v1 exactly: - Navy blue background (#000022) with gold/bronze borders (#af7a30) - Two side-by-side 320px tab containers - Left tabs: Attributes (vital bars with gold borders + attribute table with green/blue cell backgrounds + vitals base + skill credits) | Skills (specialized=purple gradient, trained=teal gradient, grouped and sorted) | Titles - Right tabs: Augmentations (with auras section) | Ratings | Other (allegiance with followers) - Active tab: green tint background with gold top/side borders - Header: large name + level (gold, right-floated) + race/gender - XP grid: total, unassigned, luminance earned/total, deaths - Live vital bars from WebSocket vitals data - Augmentation/aura/rating property ID maps from v1 Radar — passes full radarData message (not just objects array) so canvas can render map background + entity positions properly WindowRenderer — passes live vitals to CharacterWindow Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 lines
2.3 KiB
TypeScript
55 lines
2.3 KiB
TypeScript
import React from 'react';
|
|
import { useWindowManager } from '../../contexts/WindowManagerContext';
|
|
import { ChatWindow } from './ChatWindow';
|
|
import { StatsWindow } from './StatsWindow';
|
|
import { CharacterWindow } from './CharacterWindow';
|
|
import { InventoryWindow } from './InventoryWindow';
|
|
import { RadarWindow } from './RadarWindow';
|
|
import { CombatStatsWindow } from './CombatStatsWindow';
|
|
import { IssuesWindow } from './IssuesWindow';
|
|
import { VitalSharingWindow } from './VitalSharingWindow';
|
|
import type { CharacterState } from '../../types';
|
|
|
|
interface Props {
|
|
characters: Map<string, CharacterState>;
|
|
chatMessages: Map<string, Array<{ text: string; color?: number; timestamp: string }>>;
|
|
nearbyObjects: Map<string, any>;
|
|
socket: WebSocket | null;
|
|
}
|
|
|
|
export const WindowRenderer: React.FC<Props> = ({ characters, chatMessages, nearbyObjects, socket }) => {
|
|
const { windows } = useWindowManager();
|
|
|
|
return (
|
|
<>
|
|
{windows.map(w => {
|
|
const charName = w.charName ?? '';
|
|
const prefix = w.id.split('-')[0];
|
|
|
|
switch (prefix) {
|
|
case 'chat':
|
|
return <ChatWindow key={w.id} id={w.id} charName={charName} zIndex={w.zIndex}
|
|
messages={chatMessages.get(charName) ?? []} socket={socket} />;
|
|
case 'stats':
|
|
return <StatsWindow key={w.id} id={w.id} charName={charName} zIndex={w.zIndex} />;
|
|
case 'char':
|
|
return <CharacterWindow key={w.id} id={w.id} charName={charName} zIndex={w.zIndex}
|
|
vitals={characters.get(charName)?.vitals ?? undefined} />;
|
|
case 'inv':
|
|
return <InventoryWindow key={w.id} id={w.id} charName={charName} zIndex={w.zIndex} />;
|
|
case 'radar':
|
|
return <RadarWindow key={w.id} id={w.id} charName={charName} zIndex={w.zIndex}
|
|
socket={socket} radarData={nearbyObjects.get(charName) ?? null} />;
|
|
case 'combat':
|
|
return <CombatStatsWindow key={w.id} id={w.id} charName={charName} zIndex={w.zIndex} />;
|
|
case 'issues':
|
|
return <IssuesWindow key={w.id} id={w.id} zIndex={w.zIndex} />;
|
|
case 'vitalsharing':
|
|
return <VitalSharingWindow key={w.id} id={w.id} zIndex={w.zIndex} />;
|
|
default:
|
|
return null;
|
|
}
|
|
})}
|
|
</>
|
|
);
|
|
};
|