Files
logic-gates/js/world/maps.js
Jose Luis f8aa4e2eab fix: make spawn optional — only required for initial map
Spawn can now be deleted in the editor (click same tile with Spawn tool,
use Delete tool, or press Delete key). Interior maps no longer have
spawn objects. The editor shows "None" when no spawn is set, and the
generated maps.js omits the spawn field for maps without one.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 17:20:19 +01:00

193 lines
5.2 KiB
JavaScript

/**
* maps.js - PNG-based world maps (auto-generated by Level Editor)
*/
function buildWallSet(wallData) {
const set = new Set();
for (const [row, cols] of Object.entries(wallData)) {
for (const col of cols) set.add(col + ',' + row);
}
return set;
}
function r(a, b) { const arr = []; for (let i = a; i <= b; i++) arr.push(i); return arr; }
// ==================== Circuit Lab ====================
const labWalls = {
0: [...r(0,9)],
1: [0,1,2,3,6,7,8,9],
3: [6,7,8],
6: [0,1,2,3,6,7,8,9],
7: [0,1,2,3,6,7,8,9],
};
const labMap = {
id: 'lab',
name: 'Circuit Lab',
image: 'map:lab',
widthTiles: 10,
heightTiles: 12,
// No spawn — player enters via door from town
wallSet: buildWallSet(labWalls),
exits: [
// Bidirectional: these doors return to the specific town door (12,12 = tile in front of lab entrance)
{ x: 4, y: 11, targetMap: 'town', targetX: 12, targetY: 12 },
{ x: 5, y: 11, targetMap: 'town', targetX: 12, targetY: 12 },
],
npcs: [
{ id: 'professor', x: 5, y: 1, facing: 'down', dialog: ["Welcome to the Circuit Lab!","I\"m the Professor. We study logic gates here.","Use the workshop tables to design circuits.","Press TAB to open the Workshop anytime!"] },
],
interactions: [
{ x: 7, y: 3, type: 'workshop', label: 'Workshop Table' },
{ x: 8, y: 3, type: 'workshop', label: 'Workshop Table' },
{ x: 6, y: 3, type: 'workshop', label: 'Workshop Table' },
{ x: 1, y: 7, type: 'sign', label: 'Bookshelf', dialog: ["A collection of logic circuit manuals."] },
{ x: 7, y: 7, type: 'sign', label: 'Bookshelf', dialog: ["Advanced boolean algebra textbooks."] },
{ x: 0, y: 1, type: 'terminal', label: 'Terminal', dialog: ["Circuit analysis terminal.","Connect components to solve puzzles."] },
]
};
// ==================== Neon Town ====================
const palletTownWalls = {
0: [...r(0,19)],
1: [0,1,2,3,4,5,6,7,8,9,10,11,18,19],
2: [0,19],
3: [0,4,5,6,7,12,13,14,15,19],
4: [0,4,5,6,7,12,13,14,15,19],
5: [0,3,4,5,6,7,11,12,13,14,15,19],
6: [0,19],
7: [0,19],
8: [0,10,11,12,13,14,15,19],
9: [0,4,5,6,7,10,11,12,13,14,15,19],
10: [0,10,11,12,13,14,15,19],
11: [0,10,11,13,14,15,19],
12: [0,19],
13: [0,10,11,12,13,14,15,19],
14: [0,19],
15: [0,19],
16: [0,19],
17: [0,1,8,9,10,11,12,13,14,15,16,17,18,19],
};
const palletTownMap = {
id: 'town',
name: 'Neon Town',
image: 'map:pallet-town',
widthTiles: 20,
heightTiles: 18,
spawn: { x: 12, y: 12 },
wallSet: buildWallSet(palletTownWalls),
exits: [
{ x: 12, y: 11, targetMap: 'lab', targetX: 4, targetY: 10 },
],
npcs: [
{ id: 'merchant', x: 8, y: 10, facing: 'right', dialog: ["Welcome to Neon Town!","I trade in rare logic components."] },
{ id: 'guide', x: 11, y: 12, facing: 'down', dialog: ["The Circuit Lab is in the big building up north.","Press TAB anytime to open your Workshop."] },
],
interactions: [
{ x: 3, y: 5, type: 'door', label: 'House', dialog: ["The door is locked."] },
{ x: 7, y: 9, type: 'sign', label: 'Sign', dialog: ["Welcome to Neon Town!","Circuit Lab ↑"] },
{ x: 11, y: 5, type: 'sign', label: 'Sign', dialog: ["CIRCUIT LAB","Open for research!"] },
]
};
// ==================== House Interior ====================
const houseA1fWalls = {
};
const houseA1fMap = {
id: 'house-a-1f',
name: 'House Interior',
image: 'map:house-a-1f',
widthTiles: 8,
heightTiles: 8,
wallSet: buildWallSet(houseA1fWalls),
exits: [
],
npcs: [
],
interactions: [
]
};
// ==================== Route 1 ====================
const route1Walls = {
};
const route1Map = {
id: 'route-1',
name: 'Route 1',
image: 'map:route-1',
widthTiles: 20,
heightTiles: 36,
wallSet: buildWallSet(route1Walls),
exits: [
],
npcs: [
],
interactions: [
]
};
// ==================== Registry ====================
const maps = {
'lab': labMap,
'town': palletTownMap,
'house-a-1f': houseA1fMap,
'route-1': route1Map,
};
export function getMap(id) { return maps[id] || null; }
export function isWall(mapId, x, y) {
const map = maps[mapId];
if (!map) return true;
if (x < 0 || x >= map.widthTiles || y < 0 || y >= map.heightTiles) return true;
return map.wallSet.has(x + ',' + y);
}
export function isWalkable(mapId, x, y) {
if (isWall(mapId, x, y)) return false;
if (getNPC(mapId, x, y)) return false;
return true;
}
export function getInteraction(mapId, x, y) {
const map = maps[mapId];
if (!map) return null;
return map.interactions.find(i => i.x === x && i.y === y) || null;
}
export function getNPC(mapId, x, y) {
const map = maps[mapId];
if (!map) return null;
return map.npcs.find(npc => npc.x === x && npc.y === y) || null;
}
export function getExit(mapId, x, y) {
const map = maps[mapId];
if (!map) return null;
return map.exits.find(e => e.x === x && e.y === y) || null;
}
export function getTile(mapId, x, y) { return isWall(mapId, x, y) ? 1 : 0; }
export { maps };