diff --git a/frontend/src/App.css b/frontend/src/App.css index 51c0b60..bf471d2 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -153,3 +153,61 @@ body { background: rgba(255, 50, 50, 0.3); color: #ffffff; } + +/* Loading Screen */ +.loading-screen { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background: #050505 url('/assets/runtime/generated/ui/loading_screen_v001.png') center/cover no-repeat; + position: relative; + z-index: 9999; +} + +.loading-screen::before { + content: ''; + position: absolute; + inset: 0; + background: radial-gradient(circle at center, transparent 0%, rgba(0,0,0,0.8) 100%); +} + +.loading-content { + position: relative; + z-index: 1; + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; +} + +.loading-spinner { + width: 50px; + height: 50px; + border: 3px solid rgba(255, 50, 50, 0.1); + border-top-color: #ff3333; + border-radius: 50%; + animation: spin 1s linear infinite; + box-shadow: 0 0 15px rgba(255, 50, 50, 0.4); +} + +.loading-text { + font-family: 'Rajdhani', monospace; + font-size: 14px; + color: #ff3333; + letter-spacing: 4px; + font-weight: 700; + text-shadow: 0 0 10px rgba(255, 50, 50, 0.5); + animation: pulse 2s ease-in-out infinite; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +@keyframes pulse { + 0%, 100% { opacity: 0.6; } + 50% { opacity: 1; } +} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index cadb0e9..cc949c9 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -70,12 +70,11 @@ import './App.css'; // ─── Lazy fallback ──────────────────────────────────────────── const LazyFallback: React.FC = () => ( -
- Loading... +
+
+
+
INITIALIZING SYSTEMS...
+
); @@ -218,11 +217,7 @@ const App: React.FC = () => { // Show loading while checking auth if (!authChecked) { - return ( -
-
Loading...
-
- ); + return ; } // Show auth screen if not logged in (skipped in demo mode) diff --git a/frontend/src/assets/assetManifest.ts b/frontend/src/assets/assetManifest.ts index 2c39647..c51814c 100644 --- a/frontend/src/assets/assetManifest.ts +++ b/frontend/src/assets/assetManifest.ts @@ -252,6 +252,13 @@ export const environmentAssets: Record = { streetBackdropDay: `${ENVS}/street/block_stripplaza_day_street_v001.png`, streetBackdropNight: `${ENVS}/street/block_stripplaza_night_street_v001.png`, }, + block_lasolas_miami_001: { + id: 'block_lasolas_miami_001', + displayName: 'Las Olas Boulevard', + topdownBg: `/assets/runtime/generated/environments/topdown/block_lasolas_topdown_v001.png`, + streetBackdropDay: `/assets/runtime/generated/environments/street/block_lasolas_driveby_street_v001.png`, + streetBackdropNight: `/assets/runtime/generated/environments/street/block_lasolas_driveby_street_v001.png`, + }, }; // ─── UI Icons (generated set) ──────────────────────────────── diff --git a/frontend/src/components/layout/OSShell.css b/frontend/src/components/layout/OSShell.css index ed87e32..ecc6aed 100644 --- a/frontend/src/components/layout/OSShell.css +++ b/frontend/src/components/layout/OSShell.css @@ -22,7 +22,7 @@ content: ''; position: fixed; inset: 0; - background: url('/assets/bg_desktop.jpg') center/cover no-repeat; + background: url('/assets/runtime/generated/ui/os_shell_wallpaper_v001.png') center/cover no-repeat; opacity: 0.25; z-index: 0; filter: brightness(0.6) saturate(1.2); diff --git a/frontend/src/components/map/BlockModeView.tsx b/frontend/src/components/map/BlockModeView.tsx index 6086a17..fcfca4a 100644 --- a/frontend/src/components/map/BlockModeView.tsx +++ b/frontend/src/components/map/BlockModeView.tsx @@ -332,7 +332,7 @@ const BlockModeView: React.FC = ({ ) : viewMode === 'topdown' ? ( // Use the Phaser scene when a real satellite URL is available; // fall back to the CSS grid for dev/no-token environments - block.topdownBgUrl && block.topdownBgUrl.startsWith('http') ? ( + block.topdownBgUrl && (block.topdownBgUrl.startsWith('http') || block.topdownBgUrl.startsWith('/assets/')) ? ( {}} diff --git a/frontend/src/components/slide/PhaserSlideGame.tsx b/frontend/src/components/slide/PhaserSlideGame.tsx index e499e96..bd5abcd 100644 --- a/frontend/src/components/slide/PhaserSlideGame.tsx +++ b/frontend/src/components/slide/PhaserSlideGame.tsx @@ -82,7 +82,6 @@ export const PhaserSlideGame: React.FC = ({ scene.events.on('cell_click', handleCellClick); } catch (err) { - // eslint-disable-next-line no-console console.error('[PhaserSlideGame] failed to init Phaser', err); setError(err instanceof Error ? err.message : 'Unknown Phaser error'); } diff --git a/frontend/src/stores/npcStore.ts b/frontend/src/stores/npcStore.ts index 48a44da..9f83771 100644 --- a/frontend/src/stores/npcStore.ts +++ b/frontend/src/stores/npcStore.ts @@ -119,9 +119,9 @@ function makeNPCMember( const DEFAULT_GANGS: NPCGang[] = [ { - id: 'npc-scorpions', - name: 'The Scorpions', - faction: 'eastside', + id: 'npc-12ocho', + name: '12Ocho / Twelve-O', + faction: 'southside', difficulty: 2, aggression: 65, wealth: 40, @@ -129,101 +129,87 @@ const DEFAULT_GANGS: NPCGang[] = [ controlledBlocks: [], threatening: false, lastTickAt: new Date(Date.now() - 600_000).toISOString(), - lastAction: 'Patrolling their blocks', + lastAction: 'Patrolling Las Olas', lastActionType: 'patrol', members: [ - makeNPCMember('sc-1', 'Big Mike', 'shooter', 3), - makeNPCMember('sc-2', 'Lil D', 'dealer', 2), - makeNPCMember('sc-3', 'Crazy Jay', 'enforcer', 4), - makeNPCMember('sc-4', 'Young Ace', 'shooter', 1), + makeNPCMember('12-1', 'Ocho', 'shooter', 3), + makeNPCMember('12-2', 'Lil 12', 'dealer', 2), + makeNPCMember('12-3', 'V-Twelve', 'enforcer', 4), ], }, { - id: 'npc-deadend', - name: 'Dead End Boys', - faction: 'westside', - difficulty: 3, - aggression: 80, - wealth: 55, + id: 'npc-nofed', + name: 'No Fed, All Fed', + faction: 'eastside', + difficulty: 4, + aggression: 85, + wealth: 65, territoryCount: 5, controlledBlocks: [], threatening: false, lastTickAt: new Date(Date.now() - 1_800_000).toISOString(), - lastAction: 'Expanding territory', + lastAction: 'Monitoring Federal Hwy', lastActionType: 'expand', members: [ - makeNPCMember('de-1', 'OG Reaper', 'enforcer', 5), - makeNPCMember('de-2', 'Mad Tee', 'shooter', 4), - makeNPCMember('de-3', 'Quick Shadow', 'shooter', 3), - makeNPCMember('de-4', 'Fat King', 'dealer', 3), - makeNPCMember('de-5', 'Baby Blade', 'dealer', 2), - makeNPCMember('de-6', 'Dirty Smoke', 'shooter', 4), + makeNPCMember('nf-1', 'Fed Buster', 'enforcer', 5), + makeNPCMember('nf-2', 'All-Day', 'shooter', 4), + makeNPCMember('nf-3', 'Zero Fed', 'shooter', 4), ], }, { - id: 'npc-blockburners', - name: 'Block Burners', - faction: 'southside', - difficulty: 1, - aggression: 35, - wealth: 25, - territoryCount: 1, + id: 'npc-sevendown', + name: 'Seven Down / 7DWN', + faction: 'westside', + difficulty: 3, + aggression: 70, + wealth: 50, + territoryCount: 4, controlledBlocks: [], threatening: false, lastTickAt: new Date(Date.now() - 3_600_000).toISOString(), - lastAction: 'Defending their block', + lastAction: 'Holding SW 7th Ave', lastActionType: 'defend', members: [ - makeNPCMember('bb-1', 'Tiny Rock', 'shooter', 1), - makeNPCMember('bb-2', 'Slick Stone', 'dealer', 1), - makeNPCMember('bb-3', 'Smooth Duke', 'shooter', 2), + makeNPCMember('7d-1', 'Lucky 7', 'shooter', 3), + makeNPCMember('7d-2', 'Down-Low', 'dealer', 3), + makeNPCMember('7d-3', 'Seven-Up', 'enforcer', 3), ], }, { - id: 'npc-400boyz', - name: 'The 400 Boyz', - faction: 'northside', - difficulty: 4, - aggression: 90, - wealth: 72, - territoryCount: 7, + id: 'npc-nineside', + name: 'Nine Side / N9NE', + faction: 'westside', + difficulty: 2, + aggression: 60, + wealth: 35, + territoryCount: 2, controlledBlocks: [], threatening: false, lastTickAt: new Date(Date.now() - 900_000).toISOString(), - lastAction: 'Raiding a rival block', - lastActionType: 'raid', + lastAction: 'Tagging N9 on the block', + lastActionType: 'patrol', members: [ - makeNPCMember('fb-1', 'Ghost', 'enforcer', 5), - makeNPCMember('fb-2', 'Reaper', 'shooter', 5), - makeNPCMember('fb-3', 'Ice', 'shooter', 4), - makeNPCMember('fb-4', 'Blade', 'enforcer', 4), - makeNPCMember('fb-5', 'Smoke', 'dealer', 3), - makeNPCMember('fb-6', 'Shadow', 'shooter', 4), - makeNPCMember('fb-7', 'Duke', 'dealer', 3), + makeNPCMember('n9-1', 'Cloud 9', 'shooter', 2), + makeNPCMember('n9-2', 'Nine-Life', 'dealer', 2), ], }, { - id: 'npc-vipers', - name: 'The Vipers', + id: 'npc-olasboys', + name: 'Olas Boys / OLB', faction: 'downtown', difficulty: 5, aggression: 95, wealth: 90, - territoryCount: 10, + territoryCount: 8, controlledBlocks: [], threatening: false, lastTickAt: new Date(Date.now() - 300_000).toISOString(), - lastAction: 'Consolidating power', - lastActionType: 'patrol', + lastAction: 'Controlling downtown Las Olas', + lastActionType: 'raid', members: [ - makeNPCMember('vp-1', 'The Don', 'enforcer', 5), - makeNPCMember('vp-2', 'Venom', 'shooter', 5), - makeNPCMember('vp-3', 'Fang', 'shooter', 5), - makeNPCMember('vp-4', 'Cobra', 'enforcer', 5), - makeNPCMember('vp-5', 'Asp', 'dealer', 4), - makeNPCMember('vp-6', 'Mamba', 'shooter', 5), - makeNPCMember('vp-7', 'Rattler', 'shooter', 4), - makeNPCMember('vp-8', 'Adder', 'dealer', 4), + makeNPCMember('ol-1', 'Olas King', 'enforcer', 5), + makeNPCMember('ol-2', 'Strip Boss', 'shooter', 5), + makeNPCMember('ol-3', 'Beach Boy', 'dealer', 4), ], }, ]; diff --git a/frontend/src/utils/demoSeed.ts b/frontend/src/utils/demoSeed.ts index 7bb4571..bc667c1 100644 --- a/frontend/src/utils/demoSeed.ts +++ b/frontend/src/utils/demoSeed.ts @@ -215,8 +215,8 @@ export function seedDemoState(): void { members: 1, viewMode: 'topdown' as const, pendingIncome: 0, - topdownBgUrl: '/assets/runtime/generated/environments/topdown/block_stripplaza_topdown_v001.webp', - streetBackdropUrl: '/assets/runtime/generated/environments/street/block_stripplaza_night_street_v001.webp', + topdownBgUrl: '/assets/runtime/generated/environments/topdown/block_lasolas_topdown_v001.png', + streetBackdropUrl: '/assets/runtime/generated/environments/street/block_lasolas_driveby_street_v001.png', }; blockStore.upsertBlock(demoBlock);