Files
WarhammerQuest/src/main.js

144 lines
4.0 KiB
JavaScript

import { GameEngine } from './engine/game/GameEngine.js';
import { GameRenderer } from './view/GameRenderer.js';
import { CameraManager } from './view/CameraManager.js';
import { UIManager } from './view/UIManager.js';
import { MissionConfig, MISSION_TYPES } from './engine/dungeon/MissionConfig.js';
console.log("🏗️ Warhammer Quest - Manual Dungeon Construction");
// 1. Setup Mission
const mission = new MissionConfig({
id: 'mission_1',
name: 'Manual Construction',
type: MISSION_TYPES.ESCAPE,
minTiles: 13
});
// 2. Initialize Core Systems
const renderer = new GameRenderer('app');
const cameraManager = new CameraManager(renderer);
const game = new GameEngine();
const ui = new UIManager(cameraManager, game);
// Global Access
window.GAME = game;
window.RENDERER = renderer;
// 3. Connect Dungeon Generator to Renderer
const generator = game.dungeon;
const originalPlaceTile = generator.grid.placeTile.bind(generator.grid);
generator.grid.placeTile = (instance, variant, card) => {
originalPlaceTile(instance, variant);
const cells = generator.grid.calculateCells(variant, instance.x, instance.y);
renderer.addTile(cells, card.type, card, instance);
setTimeout(() => {
renderer.renderExits(generator.availableExits);
}, 50);
};
// 4. Connect Player to Renderer
game.onEntityUpdate = (entity) => {
renderer.addEntity(entity);
renderer.updateEntityPosition(entity);
// Center camera on player spawn
if (entity.id === 'p1' && !entity._centered) {
cameraManager.centerOn(entity.x, entity.y);
entity._centered = true;
}
};
game.onEntityMove = (entity, path) => {
renderer.moveEntityAlongPath(entity, path);
};
game.onEntitySelect = (entityId, isSelected) => {
renderer.toggleEntitySelection(entityId, isSelected);
};
renderer.onHeroFinishedMove = (x, y) => {
cameraManager.centerOn(x, y);
};
// 5. Connect Generator State to UI
generator.onStateChange = (state) => {
console.log(`[Main] State: ${state}`);
if (state === 'PLACING_TILE') {
ui.showPlacementControls(true);
} else {
ui.showPlacementControls(false);
}
};
generator.onPlacementUpdate = (preview) => {
if (preview) {
renderer.showPlacementPreview(preview);
ui.updatePlacementStatus(preview.isValid);
} else {
renderer.hidePlacementPreview();
}
};
// 6. Handle Clicks
const handleClick = (x, y, doorMesh) => {
// PRIORITY 1: Tile Placement Mode - ignore all clicks
if (generator.state === 'PLACING_TILE') {
console.log('[Main] Use placement controls to place tile');
return;
}
// PRIORITY 2: Door Click (must be adjacent to player)
if (doorMesh && doorMesh.userData.isDoor && !doorMesh.userData.isOpen) {
const doorExit = doorMesh.userData.cells[0];
if (game.isPlayerAdjacentToDoor(doorExit)) {
console.log('[Main] 🚪 Opening door and drawing tile...');
// Open door visually
renderer.openDoor(doorMesh);
// Get proper exit data with direction
const exitData = doorMesh.userData.exitData;
if (exitData) {
generator.selectDoor(exitData);
} else {
console.error('[Main] Door missing exitData');
}
} else {
console.log('[Main] ⚠️ Move adjacent to the door first');
}
return;
}
// PRIORITY 3: Normal cell click (player selection/movement)
if (x !== null && y !== null) {
game.onCellClick(x, y);
}
};
renderer.setupInteraction(
() => cameraManager.getCamera(),
handleClick,
() => { } // No right-click
);
// 7. Start
console.log("--- Starting Game ---");
game.startMission(mission);
// 8. Render Loop
const animate = (time) => {
requestAnimationFrame(animate);
game.update(time);
cameraManager.update(time);
renderer.updateAnimations(time);
renderer.render(cameraManager.getCamera());
};
animate(0);
console.log("✅ Ready - Move barbarian next to a door and click it");