fix: remove unused socket.io import to resolve build error

This commit is contained in:
2025-12-29 21:28:05 +01:00
parent c8cc35772f
commit 5804db396f

View File

@@ -1,7 +1,7 @@
import './style.css';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { io } from "socket.io-client";
// import { io } from "socket.io-client";
import { turnManager, PHASES } from './systems/TurnManager.js';
import { dungeonDeck } from './dungeon/DungeonDecks.js';
import * as TileDefinitions from './dungeon/TileDefinitions.js';
@@ -11,7 +11,13 @@ import { TILE_DEFINITIONS, getTileDefinition } from './dungeon/TileDefinitions.j
// --- NETWORK SETUP ---
// Dynamic connection to support playing from mobile on the same network
const socketUrl = `http://${window.location.hostname}:3001`;
const socket = io(socketUrl);
// const socket = io(socketUrl);
// MOCK SOCKET to avoid connection errors while debugging
const socket = {
on: (event, callback) => console.log(`[MockSocket] Listening for ${event}`),
emit: (event, data) => console.log(`[MockSocket] Emitting ${event}`, data),
id: 'mock-id'
};
let lobbyCode = null;
socket.on("connect", () => {
@@ -101,6 +107,35 @@ function generateDungeon() {
};
}
// Helper function to create a flipped version of a tile
function createFlippedTile(tileDef, direction) {
const flipped = { ...tileDef };
// Create a new flipped walkability matrix
const { walkability, width, height } = tileDef;
const newWalkability = [];
if (direction === 'horizontal') {
// Flip horizontally (mirror left-right)
for (let y = 0; y < height; y++) {
newWalkability[y] = [...walkability[y]].reverse();
}
flipped.id = tileDef.id + '_flipped_h';
} else {
// Flip vertically (mirror top-bottom)
for (let y = 0; y < height; y++) {
newWalkability[y] = walkability[height - 1 - y];
}
flipped.id = tileDef.id + '_flipped_v';
}
flipped.walkability = newWalkability;
// Note: We keep the same image, the flip is only for walkability logic
// If you want visual flipping, you'd need to modify the rendering code
return flipped;
}
// --- EXPLORACIÓN DINÁMICA ---
function exploreRoom(originRoom, door) {
// Draw an event card
@@ -119,7 +154,7 @@ function exploreRoom(originRoom, door) {
// Try to draw a compatible abstract tile type (up to 10 attempts)
let card = null;
let alignmentOffset = 0;
let placementOffset = 0; // Offset for L-shapes based on selection
let attempts = 0;
const maxAttempts = 10;
@@ -151,34 +186,111 @@ function exploreRoom(originRoom, door) {
});
break;
case 'L':
candidates = [...TileDefinitions.L_SHAPES];
// NEW RULE: Select L-shape based on corridor exit direction
if (door.side === 'N') {
// North exit (vertical corridor going up): choose LSE or LSW
const lOptions = [
{ tile: TileDefinitions.TILE_DEFINITIONS.L_SE, offset: -1 }, // LSE with offset -1
{ tile: TileDefinitions.TILE_DEFINITIONS.L_WS, offset: 1 } // LSW with offset +1
];
const selected = lOptions[Math.floor(Math.random() * lOptions.length)];
card = selected.tile;
placementOffset = selected.offset;
console.log(`✓ Selected ${card.id} for N exit with offset ${placementOffset}`);
} else if (door.side === 'S') {
// South exit (vertical corridor going down): choose LNE or LNW
const lOptions = [
{ tile: TileDefinitions.TILE_DEFINITIONS.L_NE, offset: 1 }, // LNE with offset 0
{ tile: TileDefinitions.TILE_DEFINITIONS.L_WN, offset: -1 } // LNW with offset +2
];
const selected = lOptions[Math.floor(Math.random() * lOptions.length)];
card = selected.tile;
placementOffset = selected.offset;
console.log(`✓ Selected ${card.id} for S exit with offset ${placementOffset}`);
} else if (door.side === 'E') {
// East exit: choose LWN or LWS
const lOptions = [
{ tile: TileDefinitions.TILE_DEFINITIONS.L_WN, offset: 1 }, // LWN with offset 0
{ tile: TileDefinitions.TILE_DEFINITIONS.L_WS, offset: -1 } // LWS with offset +2
];
const selected = lOptions[Math.floor(Math.random() * lOptions.length)];
card = selected.tile;
placementOffset = selected.offset;
console.log(`✓ Selected ${card.id} for E exit with offset ${placementOffset}`);
} else if (door.side === 'W') {
// West exit: choose LNE or LSE
const lOptions = [
{ tile: TileDefinitions.TILE_DEFINITIONS.L_NE, offset: 1 }, // LNE with offset +2
{ tile: TileDefinitions.TILE_DEFINITIONS.L_SE, offset: -1 } // LSE with offset 0
];
const selected = lOptions[Math.floor(Math.random() * lOptions.length)];
card = selected.tile;
placementOffset = selected.offset;
console.log(`✓ Selected ${card.id} for W exit with offset ${placementOffset}`);
}
break;
case 'T':
candidates = [...TileDefinitions.T_JUNCTIONS];
// T-junction placement based on corridor exit direction
if (door.side === 'N') {
// North exit: choose T_NES, T_WNS, or T_WSE
const tOptions = [
{ tile: TileDefinitions.TILE_DEFINITIONS.T_NES, offset: -1 }, // T_NES with offset -1
{ tile: TileDefinitions.TILE_DEFINITIONS.T_WNS, offset: 1 }, // T_WNS with offset +1
{ tile: TileDefinitions.TILE_DEFINITIONS.T_WSE, offset: 0 } // T_WSE with offset 0 (placeholder)
];
const selected = tOptions[Math.floor(Math.random() * tOptions.length)];
card = selected.tile;
placementOffset = selected.offset;
console.log(`✓ Selected ${card.id} for N exit with offset ${placementOffset}`);
} else {
// For other exits, use all T-junctions (fallback)
candidates = [...TileDefinitions.T_JUNCTIONS];
}
break;
}
// If we already selected a specific card (L-shapes with N/S exits), skip validation
if (card) {
break;
}
if (candidates.length === 0) {
console.warn(`No candidates found for type ${abstractCard.type}`);
attempts++;
continue;
}
// Try all candidates and collect those that fit
// For rooms: randomly select one and optionally flip it
if (abstractCard.type === 'room_4x4' || abstractCard.type === 'room_4x6') {
const selectedRoom = candidates[Math.floor(Math.random() * candidates.length)];
// Randomly decide to flip horizontally or vertically
const shouldFlip = Math.random() < 0.5;
const flipDirection = Math.random() < 0.5 ? 'horizontal' : 'vertical';
if (shouldFlip) {
card = createFlippedTile(selectedRoom, flipDirection);
console.log(`✓ Selected ${selectedRoom.id} and flipped ${flipDirection}`);
} else {
card = selectedRoom;
console.log(`✓ Selected ${selectedRoom.id} without flipping`);
}
break;
}
// For corridors and T-junctions: validate and select
const fittingVariants = [];
for (const variant of candidates) {
const connectionResult = canConnectTiles(originRoom, variant, door.side);
if (connectionResult.valid) {
fittingVariants.push({ variant, offset: connectionResult.offset });
fittingVariants.push(variant);
}
}
if (fittingVariants.length > 0) {
// RANDOM selection from fitting variants
const selected = fittingVariants[Math.floor(Math.random() * fittingVariants.length)];
card = selected.variant;
alignmentOffset = selected.offset;
console.log(`✓ Selected ${card.id} (${card.tileType}) randomly from ${fittingVariants.length} fitting variants, offset ${alignmentOffset}`);
card = fittingVariants[Math.floor(Math.random() * fittingVariants.length)];
console.log(`✓ Selected ${card.id} (${card.tileType}) randomly from ${fittingVariants.length} fitting variants`);
} else {
console.log(`✗ No ${abstractCard.type} variant fits, trying another tile type...`);
attempts++;
@@ -193,35 +305,33 @@ function exploreRoom(originRoom, door) {
const nextTileDef = card;
const newRoomId = ROOMS.rooms.length + 1;
// Calculate entry door position in the new tile
// Calculate entry door position relative to the new tile origin
// We use external adjacent coordinates (-1 or width/height) to place the new tile
// strictly adjacent to the previous one, preventing 1-cell overlaps.
let entryGridX, entryGridY;
// Use explicit door coordinates if available (for asymmetric tiles like L/T)
const doorCoords = nextTileDef.doorCoordinates ? nextTileDef.doorCoordinates[entrySide] : null;
if (entrySide === 'N') {
entryGridX = Math.floor(nextTileDef.width / 2);
entryGridY = 0;
entryGridX = doorCoords ? doorCoords.x : Math.floor(nextTileDef.width / 2);
entryGridY = -1;
} else if (entrySide === 'S') {
entryGridX = Math.floor(nextTileDef.width / 2);
entryGridX = doorCoords ? doorCoords.x : Math.floor(nextTileDef.width / 2);
entryGridY = nextTileDef.height;
} else if (entrySide === 'E') {
entryGridX = nextTileDef.width;
entryGridY = Math.floor(nextTileDef.height / 2);
entryGridY = doorCoords ? doorCoords.y : Math.floor(nextTileDef.height / 2);
} else if (entrySide === 'W') {
entryGridX = 0;
entryGridY = Math.floor(nextTileDef.height / 2);
entryGridX = -1;
entryGridY = doorCoords ? doorCoords.y : Math.floor(nextTileDef.height / 2);
}
// Calculate absolute position for the new tile
let newX = originRoom.tile.x + door.gridX - entryGridX;
let newY = originRoom.tile.y + door.gridY - entryGridY;
// Apply alignment offset based on exit direction
if (door.side === 'N' || door.side === 'S') {
// Vertical connection - offset horizontally
newX += alignmentOffset;
} else {
// Horizontal connection - offset vertically
newY += alignmentOffset;
}
// Manual placementOffset removed: Handled by explicit doorCoordinates via TileDefinitions.js
// Check for collisions
if (!isAreaFree(newX, newY, nextTileDef.width, nextTileDef.height)) {
@@ -258,27 +368,37 @@ function exploreRoom(originRoom, door) {
nextTileDef.exits.forEach(exitDir => {
if (exitDir === entrySide) return; // Already have this connection
// Check if this is an L or T tile to make exit open by default
// For L and T tiles, exits are open passages, not closed doors
const isOpenPassage = (nextTileDef.tileType === 'L' || nextTileDef.tileType === 'T');
const exitDoor = {
side: exitDir,
leadsTo: null,
isOpen: false,
isDoor: true, // Will be determined when connected
isOpen: isOpenPassage, // Open by default for L/T
isDoor: !isOpenPassage, // Not a blocking door for L/T
id: `door_${newRoomId}_${exitDir}`
};
// Calculate door coordinates
if (exitDir === 'N') {
exitDoor.gridX = Math.floor(nextTileDef.width / 2);
exitDoor.gridY = 0;
} else if (exitDir === 'S') {
exitDoor.gridX = Math.floor(nextTileDef.width / 2);
exitDoor.gridY = nextTileDef.height;
} else if (exitDir === 'E') {
exitDoor.gridX = nextTileDef.width;
exitDoor.gridY = Math.floor(nextTileDef.height / 2);
} else if (exitDir === 'W') {
exitDoor.gridX = 0;
exitDoor.gridY = Math.floor(nextTileDef.height / 2);
// Calculate door coordinates using explicit definition or default centering
if (nextTileDef.doorCoordinates && nextTileDef.doorCoordinates[exitDir]) {
exitDoor.gridX = nextTileDef.doorCoordinates[exitDir].x;
exitDoor.gridY = nextTileDef.doorCoordinates[exitDir].y;
} else {
// Default centering logic
if (exitDir === 'N') {
exitDoor.gridX = Math.floor(nextTileDef.width / 2);
exitDoor.gridY = 0;
} else if (exitDir === 'S') {
exitDoor.gridX = Math.floor(nextTileDef.width / 2);
exitDoor.gridY = nextTileDef.height - 1;
} else if (exitDir === 'E') {
exitDoor.gridX = nextTileDef.width - 1;
exitDoor.gridY = Math.floor(nextTileDef.height / 2);
} else if (exitDir === 'W') {
exitDoor.gridX = 0;
exitDoor.gridY = Math.floor(nextTileDef.height / 2);
}
}
newRoom.doors.push(exitDoor);
@@ -743,7 +863,7 @@ function shouldPlaceDoor(tileTypeA, tileTypeB) {
}
// Validate walkability alignment between two tiles at their connection point
// Returns: { valid: boolean, offset: number } - offset is how much to shift tileB to align with tileA
// Returns: { valid: boolean } - whether the tiles can connect
function validateWalkabilityAlignment(tileDefA, posA, tileDefB, posB, exitSide) {
// Get the edge cells that will connect
const edgeA = getEdgeCells(tileDefA, exitSide);
@@ -753,101 +873,18 @@ function validateWalkabilityAlignment(tileDefA, posA, tileDefB, posB, exitSide)
console.log(`[ALIGN] EdgeA (${tileDefA.id}):`, edgeA);
console.log(`[ALIGN] EdgeB (${tileDefB.id}):`, edgeB);
// Special handling for corridor connections
// Corridors are 2 tiles wide, rooms/L/T are typically 4 tiles wide
// We need to find where the corridor's walkable area aligns with the room's walkable area
// For now, we just check that both edges have at least some walkable cells
// The actual alignment will be handled manually by the user
const hasWalkableA = edgeA.some(cell => cell > 0);
const hasWalkableB = edgeB.some(cell => cell > 0);
if (edgeA.length !== edgeB.length) {
// Different edge lengths - need to find alignment
const smallerEdge = edgeA.length < edgeB.length ? edgeA : edgeB;
const largerEdge = edgeA.length < edgeB.length ? edgeB : edgeA;
const isASmaller = edgeA.length < edgeB.length;
console.log(`[ALIGN] Different sizes: ${edgeA.length} vs ${edgeB.length}`);
console.log(`[ALIGN] isASmaller: ${isASmaller}`);
// Find walkable cells in smaller edge
const smallerWalkable = smallerEdge.filter(cell => cell > 0);
if (smallerWalkable.length === 0) {
console.warn('[ALIGN] No walkable cells in smaller edge');
return { valid: false, offset: 0 };
}
const smallerWidth = smallerEdge.length;
const largerWidth = largerEdge.length;
// FIRST: Try offset 0 (no displacement needed)
let validAtZero = true;
for (let i = 0; i < smallerWidth; i++) {
const smallCell = smallerEdge[i];
const largeCell = largerEdge[i];
const isSmallWalkable = smallCell > 0;
const isLargeWalkable = largeCell > 0;
console.log(`[ALIGN] Offset 0, index ${i}: small=${smallCell}(${isSmallWalkable}) vs large=${largeCell}(${isLargeWalkable})`);
if (isSmallWalkable !== isLargeWalkable) {
validAtZero = false;
console.log(`[ALIGN] ❌ Offset 0 FAILED at index ${i}: walkability mismatch`);
break;
}
}
if (validAtZero) {
console.log(`✓ [ALIGN] Valid alignment at offset 0 (no displacement needed)`);
return { valid: true, offset: 0 };
}
// If offset 0 doesn't work, try offset of 2 (corridor width)
// This aligns the corridor with the other walkable section of the L/T
const offset = 2;
if (offset <= largerWidth - smallerWidth) {
let valid = true;
for (let i = 0; i < smallerWidth; i++) {
const smallCell = smallerEdge[i];
const largeCell = largerEdge[offset + i];
const isSmallWalkable = smallCell > 0;
const isLargeWalkable = largeCell > 0;
if (isSmallWalkable !== isLargeWalkable) {
valid = false;
console.log(`[ALIGN] Offset ${offset} failed at index ${i}: ${smallCell} vs ${largeCell}`);
break;
}
}
if (valid) {
// Calculate final offset
// If A (corridor) is smaller than B (L/T), we need to shift B by +offset
// If B is smaller than A, we need to shift B by -offset
const finalOffset = isASmaller ? offset : -offset;
console.log(`✓ [ALIGN] Valid alignment at offset ${offset}, final offset: ${finalOffset} (isASmaller: ${isASmaller})`);
return { valid: true, offset: finalOffset };
}
}
console.warn('[ALIGN] Could not find valid alignment for edges of different sizes');
return { valid: false, offset: 0 };
if (!hasWalkableA || !hasWalkableB) {
console.warn('[ALIGN] One or both edges have no walkable cells');
return { valid: false };
}
// Same length - check direct alignment
for (let i = 0; i < edgeA.length; i++) {
const cellA = edgeA[i];
const cellB = edgeB[i];
// Rule: Cannot connect 0 (not walkable) with >0 (walkable)
const isAWalkable = cellA > 0;
const isBWalkable = cellB > 0;
if (isAWalkable !== isBWalkable) {
console.warn(`[ALIGN] Walkability mismatch at index ${i}: ${cellA} vs ${cellB}`);
return { valid: false, offset: 0 };
}
}
return { valid: true, offset: 0 };
console.log(`✓ [ALIGN] Both edges have walkable cells - connection allowed`);
return { valid: true };
}
// Get edge cells from a tile definition for a given side
@@ -892,7 +929,7 @@ function getOppositeSide(side) {
}
// Check if two tiles can connect based on type rules and walkability alignment
// Returns: { valid: boolean, offset: number } - offset for positioning the new tile
// Returns: { valid: boolean } - whether the tiles can connect
function canConnectTiles(roomA, tileDefB, exitSide) {
const tileDefA = roomA.tileDef;
@@ -909,7 +946,7 @@ function canConnectTiles(roomA, tileDefB, exitSide) {
if (!validConnections[typeA] || !validConnections[typeA].includes(typeB)) {
console.warn(`Invalid connection: ${typeA} cannot connect to ${typeB}`);
return { valid: false, offset: 0 };
return { valid: false };
}
// CRITICAL: Check that tileB has an exit in the opposite direction
@@ -917,17 +954,17 @@ function canConnectTiles(roomA, tileDefB, exitSide) {
const requiredExit = getOppositeSide(exitSide);
if (!tileDefB.exits.includes(requiredExit)) {
console.warn(`Exit direction mismatch: ${tileDefB.id} doesn't have required exit '${requiredExit}' (exiting via '${exitSide}')`);
return { valid: false, offset: 0 };
return { valid: false };
}
// Check walkability alignment and get offset
// Check walkability alignment
const alignmentResult = validateWalkabilityAlignment(tileDefA, roomA.tile, tileDefB, null, exitSide);
if (!alignmentResult.valid) {
console.warn('Walkability alignment failed');
return { valid: false, offset: 0 };
return { valid: false };
}
return alignmentResult;
return { valid: true };
}
// --- CREACIÓN DE MARCADORES ---
@@ -1274,9 +1311,77 @@ async function animateMovement() {
SESSION.selectedUnitId = null; // Deseleccionar unidad al terminar de mover
updateSelectionVisuals();
SESSION.isAnimating = false;
// Auto-exploration check for open passages (L/T tiles)
checkAutoExploration(unit);
drawMinimap(); // Actualizar posición final del jugador
}
// Check if unit is on an open passage leading to unexplored area
function checkAutoExploration(unit) {
// Find unit's current room
const currentRoom = ROOMS.rooms.find(r => r.entities.some(e => e.id === unit.id));
if (!currentRoom) return;
// DEBUG: Log unit position for troubleshooting
console.log(`[AutoExplore] Unit at (${unit.x}, ${unit.y}) in Room ${currentRoom.id}`);
const door = currentRoom.doors.find(d => {
const doorGlobalX = currentRoom.tile.x + d.gridX;
const doorGlobalY = currentRoom.tile.y + d.gridY;
// DEBUG: Log each door check
console.log(`[CheckDoor] ${d.id} (${d.side}): Global(${doorGlobalX}, ${doorGlobalY}) vs Unit(${unit.x}, ${unit.y})`);
// Check 1: Is Unit on the door line? (Internal or External adjacent)
let isMainAxisMatch = false;
let isCrossAxisMatch = false;
if (d.side === 'N' || d.side === 'S') {
// Main axis = Y. Internal: doorGlobalY. External: +/- 1
const deltaY = unit.y - doorGlobalY;
// Allow 0 (internal) or 1 step out (external)
if (d.side === 'N') isMainAxisMatch = (deltaY === 0 || deltaY === -1);
else isMainAxisMatch = (deltaY === 0 || deltaY === 1);
// Cross axis = X. Allow +/- 1 for corridor width
isCrossAxisMatch = Math.abs(unit.x - doorGlobalX) <= 1;
} else { // E or W
// Main axis = X. Internal: doorGlobalX. External: +/- 1
const deltaX = unit.x - doorGlobalX;
// Allow 0 (internal) or 1 step out (external)
if (d.side === 'W') isMainAxisMatch = (deltaX === 0 || deltaX === -1);
else isMainAxisMatch = (deltaX === 0 || deltaX === 1);
// Cross axis = Y. Allow +/- 1 for corridor width
isCrossAxisMatch = Math.abs(unit.y - doorGlobalY) <= 1;
}
if (isMainAxisMatch && isCrossAxisMatch) {
console.log(`[AutoExplore] MATCH! Door ${d.id} (${d.side}). Unit(${unit.x}, ${unit.y}) vs Door(${doorGlobalX}, ${doorGlobalY})`);
return true;
}
return false;
});
if (door) {
console.log(`[AutoExplore] Found door at unit pos: ${door.id}, Open: ${door.isOpen}, LeadsTo: ${door.leadsTo}`);
if (door.isOpen && door.leadsTo === null) {
console.log("[AutoExplore] Triggering exploration...");
// Use timeout to allow movement animation to settle/feel natural
setTimeout(() => {
const newRoom = exploreRoom(currentRoom, door);
if (newRoom) {
renderRoom(newRoom);
}
}, 100);
}
}
}
// Verifica si la unidad ha entrado físicamente en una sala diferente a la registrada
function detectRoomChange(unit, currentLogicalRoom) {
for (const room of ROOMS.rooms) {
@@ -1520,6 +1625,14 @@ async function renderRoom(room) {
for (const config of wallConfigs) {
const wallSide = config.side;
// Skip wall rendering for L and T tiles on their exit sides
if ((room.tileDef.tileType === 'L' || room.tileDef.tileType === 'T') &&
room.tileDef.exits.includes(wallSide)) {
console.log(`Skipping wall on ${wallSide} for ${room.tileDef.tileType} tile (exit side)`);
continue; // Don't render wall on exit sides
}
const door = doorsOnSides[wallSide];
// Función helper para crear un segmento de pared