Honey Village: six model builds + hub frontend, Dockerized for Dokploy
This commit is contained in:
@@ -0,0 +1,647 @@
|
||||
/**
|
||||
* Generate 10 Tiled-compatible JSON maps per PRD §10.
|
||||
* Also writes .tmx for optional `tiled --export-map` round-trip.
|
||||
*/
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const outDir = path.join(__dirname, '../public/assets/maps');
|
||||
const tmxDir = path.join(__dirname, '../mapsrc');
|
||||
fs.mkdirSync(outDir, { recursive: true });
|
||||
fs.mkdirSync(tmxDir, { recursive: true });
|
||||
|
||||
const TILE = 16;
|
||||
|
||||
const TILESET = {
|
||||
firstgid: 1,
|
||||
columns: 16,
|
||||
image: '../tilesets/village.png',
|
||||
imagewidth: 256,
|
||||
imageheight: 128,
|
||||
tilecount: 128,
|
||||
tilewidth: 16,
|
||||
tileheight: 16,
|
||||
name: 'village',
|
||||
margin: 0,
|
||||
spacing: 0,
|
||||
tiles: [
|
||||
// collidable tiles
|
||||
...[9, 10, 11, 12, 13, 14, 15, 19, 20, 21, 22, 24, 26, 29, 30, 35, 41, 46].map((id) => ({
|
||||
id,
|
||||
properties: [{ name: 'collides', type: 'bool', value: true }],
|
||||
})),
|
||||
],
|
||||
};
|
||||
|
||||
function emptyGrid(w, h, fill = 0) {
|
||||
return Array.from({ length: w * h }, () => fill);
|
||||
}
|
||||
|
||||
function set(data, w, x, y, v) {
|
||||
if (x < 0 || y < 0 || x >= w) return;
|
||||
data[y * w + x] = v;
|
||||
}
|
||||
|
||||
function fillRect(data, w, x0, y0, x1, y1, v) {
|
||||
for (let y = y0; y <= y1; y++) {
|
||||
for (let x = x0; x <= x1; x++) set(data, w, x, y, v);
|
||||
}
|
||||
}
|
||||
|
||||
function border(data, w, h, v) {
|
||||
for (let x = 0; x < w; x++) {
|
||||
set(data, w, x, 0, v);
|
||||
set(data, w, x, h - 1, v);
|
||||
}
|
||||
for (let y = 0; y < h; y++) {
|
||||
set(data, w, 0, y, v);
|
||||
set(data, w, w - 1, y, v);
|
||||
}
|
||||
}
|
||||
|
||||
function makeMap(name, w, h, build) {
|
||||
const ground = emptyGrid(w, h, 1); // grass gid 1 (tile index 0 is empty, firstgid=1 → tile 0 empty, tile1 grass)
|
||||
// Our tileset: tile index in image 0 = empty transparent; index 1 = grass
|
||||
// firstgid 1 means GID 1 = tile index 0. Let's use firstgid 1 where GID N = image tile (N-1)
|
||||
// Simpler: firstgid=1, and we store image-tile-index+1 as GID.
|
||||
// grass is image tile 1 → GID 2
|
||||
for (let i = 0; i < ground.length; i++) ground[i] = 2; // grass
|
||||
|
||||
const obstacles = emptyGrid(w, h, 0);
|
||||
const objects = [];
|
||||
|
||||
const api = {
|
||||
w,
|
||||
h,
|
||||
ground,
|
||||
obstacles,
|
||||
objects,
|
||||
// GID 0 = empty; image tile index N → GID N+1. Passing 0 clears (no collision).
|
||||
setG: (x, y, imgTile) => set(ground, w, x, y, imgTile <= 0 ? 0 : imgTile + 1),
|
||||
setO: (x, y, imgTile) => set(obstacles, w, x, y, imgTile <= 0 ? 0 : imgTile + 1),
|
||||
clearO: (x, y) => set(obstacles, w, x, y, 0),
|
||||
fillG: (x0, y0, x1, y1, imgTile) =>
|
||||
fillRect(ground, w, x0, y0, x1, y1, imgTile <= 0 ? 0 : imgTile + 1),
|
||||
fillO: (x0, y0, x1, y1, imgTile) =>
|
||||
fillRect(obstacles, w, x0, y0, x1, y1, imgTile <= 0 ? 0 : imgTile + 1),
|
||||
borderO: (imgTile) => {
|
||||
const gid = imgTile <= 0 ? 0 : imgTile + 1;
|
||||
for (let x = 0; x < w; x++) {
|
||||
set(obstacles, w, x, 0, gid);
|
||||
set(obstacles, w, x, h - 1, gid);
|
||||
}
|
||||
for (let y = 0; y < h; y++) {
|
||||
set(obstacles, w, 0, y, gid);
|
||||
set(obstacles, w, w - 1, y, gid);
|
||||
}
|
||||
},
|
||||
spawn: (x, y) => {
|
||||
objects.push({
|
||||
id: objects.length + 1,
|
||||
name: 'spawn',
|
||||
type: 'spawn',
|
||||
x: x * TILE,
|
||||
y: y * TILE,
|
||||
width: TILE,
|
||||
height: TILE,
|
||||
});
|
||||
},
|
||||
npc: (name, x, y) => {
|
||||
objects.push({
|
||||
id: objects.length + 1,
|
||||
name,
|
||||
type: 'npc',
|
||||
x: x * TILE,
|
||||
y: y * TILE,
|
||||
width: TILE,
|
||||
height: TILE,
|
||||
properties: [{ name: 'npcId', type: 'string', value: name }],
|
||||
});
|
||||
},
|
||||
door: (name, x, y, target, targetSpawn) => {
|
||||
// Door tiles must be walkable (clear obstacle collision)
|
||||
set(obstacles, w, x, y, 0);
|
||||
objects.push({
|
||||
id: objects.length + 1,
|
||||
name,
|
||||
type: 'door',
|
||||
x: x * TILE,
|
||||
y: y * TILE,
|
||||
width: TILE,
|
||||
height: TILE,
|
||||
properties: [
|
||||
{ name: 'target', type: 'string', value: target },
|
||||
{ name: 'spawn', type: 'string', value: targetSpawn || 'spawn' },
|
||||
],
|
||||
});
|
||||
},
|
||||
interact: (name, x, y, interactId) => {
|
||||
objects.push({
|
||||
id: objects.length + 1,
|
||||
name,
|
||||
type: 'interact',
|
||||
x: x * TILE,
|
||||
y: y * TILE,
|
||||
width: TILE,
|
||||
height: TILE,
|
||||
properties: [{ name: 'interactId', type: 'string', value: interactId }],
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
build(api);
|
||||
|
||||
const map = {
|
||||
compressionlevel: -1,
|
||||
height: h,
|
||||
width: w,
|
||||
infinite: false,
|
||||
layers: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'ground',
|
||||
type: 'tilelayer',
|
||||
width: w,
|
||||
height: h,
|
||||
data: ground,
|
||||
opacity: 1,
|
||||
visible: true,
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'obstacles',
|
||||
type: 'tilelayer',
|
||||
width: w,
|
||||
height: h,
|
||||
data: obstacles,
|
||||
opacity: 1,
|
||||
visible: true,
|
||||
x: 0,
|
||||
y: 0,
|
||||
properties: [{ name: 'collides', type: 'bool', value: true }],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'objects',
|
||||
type: 'objectgroup',
|
||||
objects,
|
||||
opacity: 1,
|
||||
visible: true,
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
],
|
||||
nextlayerid: 4,
|
||||
nextobjectid: objects.length + 1,
|
||||
orientation: 'orthogonal',
|
||||
renderorder: 'right-down',
|
||||
tiledversion: '1.12.2',
|
||||
tileheight: TILE,
|
||||
tilewidth: TILE,
|
||||
type: 'map',
|
||||
version: '1.10',
|
||||
tilesets: [
|
||||
{
|
||||
...TILESET,
|
||||
// embed relative path for Phaser
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const jsonPath = path.join(outDir, `${name}.json`);
|
||||
fs.writeFileSync(jsonPath, JSON.stringify(map, null, 2));
|
||||
console.log('wrote', jsonPath);
|
||||
|
||||
// Minimal TMX for Tiled CLI export verification
|
||||
const tmx = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.12.2" orientation="orthogonal" renderorder="right-down" width="${w}" height="${h}" tilewidth="16" tileheight="16" infinite="0" nextlayerid="4" nextobjectid="${objects.length + 1}">
|
||||
<tileset firstgid="1" source="village.tsx"/>
|
||||
<layer id="1" name="ground" width="${w}" height="${h}">
|
||||
<data encoding="csv">
|
||||
${ground.join(',')}
|
||||
</data>
|
||||
</layer>
|
||||
<layer id="2" name="obstacles" width="${w}" height="${h}">
|
||||
<properties>
|
||||
<property name="collides" type="bool" value="true"/>
|
||||
</properties>
|
||||
<data encoding="csv">
|
||||
${obstacles.join(',')}
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup id="3" name="objects">
|
||||
${objects
|
||||
.map(
|
||||
(o) =>
|
||||
` <object id="${o.id}" name="${o.name}" type="${o.type}" x="${o.x}" y="${o.y}" width="${o.width}" height="${o.height}"/>`,
|
||||
)
|
||||
.join('\n')}
|
||||
</objectgroup>
|
||||
</map>
|
||||
`;
|
||||
fs.writeFileSync(path.join(tmxDir, `${name}.tmx`), tmx);
|
||||
return map;
|
||||
}
|
||||
|
||||
// TSX tileset for Tiled
|
||||
fs.writeFileSync(
|
||||
path.join(tmxDir, 'village.tsx'),
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.10" tiledversion="1.12.2" name="village" tilewidth="16" tileheight="16" tilecount="128" columns="16">
|
||||
<image source="../public/assets/tilesets/village.png" width="256" height="128"/>
|
||||
</tileset>
|
||||
`,
|
||||
);
|
||||
|
||||
// --- Maps ---
|
||||
|
||||
// 1. House 12x8
|
||||
makeMap('house', 12, 8, (m) => {
|
||||
m.fillG(0, 0, 11, 7, 16); // wood floor
|
||||
m.borderO(11);
|
||||
m.setO(2, 2, 18); // bed
|
||||
m.setO(3, 2, 18);
|
||||
m.setO(9, 2, 28); // calendar
|
||||
m.setO(5, 4, 22); // table
|
||||
m.setO(1, 5, 23); // chair
|
||||
// clear door at bottom
|
||||
m.setO(5, 7, 0);
|
||||
m.setO(6, 7, 0);
|
||||
m.setG(5, 7, 17);
|
||||
m.setG(6, 7, 17);
|
||||
m.spawn(6, 5);
|
||||
m.door('to_plaza', 5, 7, 'PlazaScene', 'from_house');
|
||||
m.door('to_plaza2', 6, 7, 'PlazaScene', 'from_house');
|
||||
m.interact('bed', 2, 2, 'bed');
|
||||
m.interact('calendar', 9, 2, 'calendar');
|
||||
});
|
||||
|
||||
// 2. Plaza 30x20 hub
|
||||
makeMap('plaza', 30, 20, (m) => {
|
||||
m.fillG(0, 0, 29, 19, 1);
|
||||
// path cross
|
||||
m.fillG(13, 0, 16, 19, 3);
|
||||
m.fillG(0, 8, 29, 11, 3);
|
||||
// flower beds
|
||||
m.fillO(10, 6, 12, 7, 12 + 0); // use flower tile 7
|
||||
m.setO(10, 6, 7);
|
||||
m.setO(11, 6, 7);
|
||||
m.setO(12, 6, 7);
|
||||
m.setO(10, 7, 7);
|
||||
m.setO(11, 7, 7);
|
||||
m.setO(12, 7, 7);
|
||||
// board
|
||||
m.setO(15, 5, 29);
|
||||
// tree + birds
|
||||
m.setO(20, 4, 10);
|
||||
m.setO(20, 5, 9);
|
||||
m.setO(21, 4, 10);
|
||||
// mailbox
|
||||
m.setO(4, 10, 30);
|
||||
// houses facades as doors targets
|
||||
m.setO(5, 2, 13);
|
||||
m.setO(6, 2, 13);
|
||||
m.setO(5, 3, 12);
|
||||
m.setO(6, 3, 14); // door visual
|
||||
m.setO(22, 2, 13);
|
||||
m.setO(23, 2, 13);
|
||||
m.setO(22, 3, 12);
|
||||
m.setO(23, 3, 14);
|
||||
m.setO(8, 14, 13);
|
||||
m.setO(9, 14, 13);
|
||||
m.setO(8, 15, 12);
|
||||
m.setO(9, 15, 14);
|
||||
// walls edge soft
|
||||
for (let x = 0; x < 30; x++) {
|
||||
m.setO(x, 0, 35);
|
||||
m.setO(x, 19, 35);
|
||||
}
|
||||
// openings
|
||||
m.setO(14, 0, 0);
|
||||
m.setO(15, 0, 0);
|
||||
m.setO(14, 19, 0);
|
||||
m.setO(15, 19, 0);
|
||||
m.setO(0, 9, 0);
|
||||
m.setO(0, 10, 0);
|
||||
m.setO(29, 9, 0);
|
||||
m.setO(29, 10, 0);
|
||||
|
||||
m.spawn(15, 12);
|
||||
m.npc('afu', 15, 6);
|
||||
m.npc('dabao', 5, 11);
|
||||
m.npc('twinbirds', 20, 3);
|
||||
m.npc('extra1', 18, 14);
|
||||
m.npc('extra4', 10, 12);
|
||||
|
||||
m.door('from_house', 6, 4, 'HouseScene', 'spawn'); // visual marker only when entering - actual door below
|
||||
// Fix: doors as interact targets
|
||||
// Re-define doors properly
|
||||
m.objects.length = m.objects.filter((o) => o.type !== 'door').length; // no, just add
|
||||
});
|
||||
|
||||
// Fix plaza - rebuild cleanly
|
||||
function rebuildPlaza() {
|
||||
return makeMap('plaza', 30, 20, (m) => {
|
||||
m.fillG(0, 0, 29, 19, 1);
|
||||
m.fillG(13, 0, 16, 19, 3);
|
||||
m.fillG(0, 8, 29, 11, 3);
|
||||
// flower bed tiles
|
||||
for (const [x, y] of [
|
||||
[10, 6],
|
||||
[11, 6],
|
||||
[12, 6],
|
||||
[10, 7],
|
||||
[11, 7],
|
||||
[12, 7],
|
||||
]) {
|
||||
m.setO(x, y, 7);
|
||||
}
|
||||
m.setO(15, 5, 29); // board
|
||||
m.setO(20, 4, 10);
|
||||
m.setO(20, 5, 9);
|
||||
m.setO(4, 10, 30); // mailbox
|
||||
// house doors on north
|
||||
m.setO(5, 2, 13);
|
||||
m.setO(6, 2, 13);
|
||||
m.setO(5, 3, 12);
|
||||
m.setO(6, 3, 14);
|
||||
m.setO(22, 2, 13);
|
||||
m.setO(23, 2, 13);
|
||||
m.setO(22, 3, 12);
|
||||
m.setO(23, 3, 14);
|
||||
// clinic south-west
|
||||
m.setO(3, 15, 12);
|
||||
m.setO(4, 15, 14);
|
||||
// bakery east-ish
|
||||
m.setO(25, 8, 12);
|
||||
m.setO(25, 9, 14);
|
||||
// shop west
|
||||
m.setO(2, 8, 12);
|
||||
m.setO(2, 9, 14);
|
||||
// ribbon posts
|
||||
m.setO(12, 10, 33);
|
||||
m.setO(17, 10, 33);
|
||||
m.setO(12, 13, 33);
|
||||
m.setO(17, 13, 33);
|
||||
|
||||
m.spawn(15, 12);
|
||||
// named entry spawns as objects
|
||||
m.objects.push({
|
||||
id: 100,
|
||||
name: 'from_house',
|
||||
type: 'spawn',
|
||||
x: 6 * 16,
|
||||
y: 5 * 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
});
|
||||
m.objects.push({
|
||||
id: 101,
|
||||
name: 'from_bakery',
|
||||
type: 'spawn',
|
||||
x: 24 * 16,
|
||||
y: 9 * 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
});
|
||||
m.objects.push({
|
||||
id: 102,
|
||||
name: 'from_shop',
|
||||
type: 'spawn',
|
||||
x: 3 * 16,
|
||||
y: 9 * 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
});
|
||||
m.objects.push({
|
||||
id: 103,
|
||||
name: 'from_clinic',
|
||||
type: 'spawn',
|
||||
x: 4 * 16,
|
||||
y: 14 * 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
});
|
||||
m.objects.push({
|
||||
id: 104,
|
||||
name: 'from_lake',
|
||||
type: 'spawn',
|
||||
x: 15 * 16,
|
||||
y: 17 * 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
});
|
||||
m.objects.push({
|
||||
id: 105,
|
||||
name: 'from_field',
|
||||
type: 'spawn',
|
||||
x: 15 * 16,
|
||||
y: 2 * 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
});
|
||||
m.objects.push({
|
||||
id: 106,
|
||||
name: 'from_well',
|
||||
type: 'spawn',
|
||||
x: 27 * 16,
|
||||
y: 10 * 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
});
|
||||
m.objects.push({
|
||||
id: 107,
|
||||
name: 'from_fog',
|
||||
type: 'spawn',
|
||||
x: 2 * 16,
|
||||
y: 16 * 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
});
|
||||
|
||||
m.npc('afu', 15, 6);
|
||||
m.npc('dabao', 5, 11);
|
||||
m.npc('twinbirds', 20, 3);
|
||||
m.npc('extra1', 18, 14);
|
||||
m.npc('extra4', 10, 12);
|
||||
|
||||
m.door('house', 6, 3, 'HouseScene', 'spawn');
|
||||
m.door('bakery', 25, 9, 'BakeryScene', 'spawn');
|
||||
m.door('shop', 2, 9, 'ShopScene', 'spawn');
|
||||
m.door('clinic', 4, 15, 'ClinicScene', 'spawn');
|
||||
m.door('lake', 15, 19, 'LakeScene', 'spawn');
|
||||
m.door('field', 15, 0, 'FieldScene', 'spawn');
|
||||
m.door('well', 29, 10, 'WellScene', 'spawn');
|
||||
m.door('fog', 0, 16, 'FogScene', 'spawn');
|
||||
|
||||
m.interact('board', 15, 5, 'board');
|
||||
m.interact('flowers', 11, 6, 'flowers');
|
||||
m.interact('mailbox', 4, 10, 'mailbox');
|
||||
m.interact('ribbon1', 12, 10, 'ribbon');
|
||||
m.interact('ribbon2', 17, 10, 'ribbon');
|
||||
m.interact('ribbon3', 12, 13, 'ribbon');
|
||||
m.interact('ribbon4', 17, 13, 'ribbon');
|
||||
});
|
||||
}
|
||||
rebuildPlaza();
|
||||
|
||||
// 3. Bakery 15x10
|
||||
makeMap('bakery', 15, 10, (m) => {
|
||||
m.fillG(0, 0, 14, 9, 16);
|
||||
m.borderO(12);
|
||||
m.fillO(2, 2, 6, 3, 19); // counter
|
||||
m.setO(12, 2, 20); // oven
|
||||
m.setO(10, 2, 42); // recipe paper
|
||||
m.setO(4, 6, 22);
|
||||
m.setO(5, 7, 0);
|
||||
m.setO(6, 9, 0);
|
||||
m.setO(7, 9, 0);
|
||||
m.spawn(7, 7);
|
||||
m.npc('yuanyuan', 4, 4);
|
||||
m.door('to_plaza', 7, 9, 'PlazaScene', 'from_bakery');
|
||||
m.interact('recipe', 10, 2, 'recipe');
|
||||
m.interact('counter', 4, 3, 'bread');
|
||||
m.interact('knead', 3, 3, 'knead');
|
||||
});
|
||||
|
||||
// 4. Shop 15x10
|
||||
makeMap('shop', 15, 10, (m) => {
|
||||
m.fillG(0, 0, 14, 9, 17);
|
||||
m.borderO(12);
|
||||
for (let x = 2; x <= 12; x++) {
|
||||
m.setO(x, 2, 21);
|
||||
m.setO(x, 4, 21);
|
||||
}
|
||||
m.setO(7, 9, 0);
|
||||
m.setO(8, 9, 0);
|
||||
m.spawn(7, 7);
|
||||
m.npc('mimi', 7, 5);
|
||||
m.door('to_plaza', 7, 9, 'PlazaScene', 'from_shop');
|
||||
m.interact('shelf', 5, 2, 'shelf');
|
||||
});
|
||||
|
||||
// 5. Clinic 12x8
|
||||
makeMap('clinic', 12, 8, (m) => {
|
||||
m.fillG(0, 0, 11, 7, 17);
|
||||
m.borderO(12);
|
||||
m.setO(3, 2, 22);
|
||||
m.setO(4, 2, 43); // form
|
||||
m.setO(8, 3, 18);
|
||||
m.setO(5, 7, 0);
|
||||
m.setO(6, 7, 0);
|
||||
m.spawn(6, 5);
|
||||
m.npc('fu', 3, 3);
|
||||
m.door('to_plaza', 6, 7, 'PlazaScene', 'from_clinic');
|
||||
m.interact('form', 4, 2, 'form');
|
||||
});
|
||||
|
||||
// 6. Lake 24x16
|
||||
makeMap('lake', 24, 16, (m) => {
|
||||
m.fillG(0, 0, 23, 15, 1);
|
||||
m.fillG(0, 8, 23, 15, 5); // water
|
||||
m.fillG(0, 8, 23, 8, 6);
|
||||
m.fillO(8, 4, 10, 5, 23); // bench area chairs
|
||||
m.setO(9, 4, 23);
|
||||
m.setO(12, 6, 31); // picnic
|
||||
m.setO(13, 6, 31);
|
||||
// path from north
|
||||
m.fillG(11, 0, 12, 7, 3);
|
||||
m.setO(11, 0, 0);
|
||||
m.setO(12, 0, 0);
|
||||
m.spawn(11, 2);
|
||||
m.npc('gui', 9, 5);
|
||||
m.npc('extra3', 18, 4);
|
||||
m.door('to_plaza', 11, 0, 'PlazaScene', 'from_lake');
|
||||
m.interact('picnic', 12, 6, 'picnic');
|
||||
m.interact('bench', 9, 4, 'bench');
|
||||
});
|
||||
|
||||
// 7. Field 20x14
|
||||
makeMap('field', 20, 14, (m) => {
|
||||
m.fillG(0, 0, 19, 13, 1);
|
||||
m.fillG(9, 10, 10, 13, 3);
|
||||
for (const [x, y] of [
|
||||
[3, 3],
|
||||
[5, 4],
|
||||
[7, 3],
|
||||
[12, 5],
|
||||
[14, 3],
|
||||
[4, 7],
|
||||
[15, 7],
|
||||
[8, 6],
|
||||
]) {
|
||||
m.setO(x, y, 8); // berry
|
||||
}
|
||||
m.setO(10, 2, 32); // pot
|
||||
m.spawn(10, 11);
|
||||
m.npc('extra2', 6, 8);
|
||||
m.door('to_plaza', 10, 13, 'PlazaScene', 'from_field');
|
||||
m.interact('berry1', 3, 3, 'berry');
|
||||
m.interact('berry2', 5, 4, 'berry');
|
||||
m.interact('berry3', 7, 3, 'berry');
|
||||
m.interact('berry4', 12, 5, 'berry');
|
||||
m.interact('berry5', 14, 3, 'berry');
|
||||
m.interact('pot', 10, 2, 'pot');
|
||||
});
|
||||
|
||||
// 8. Well 14x10
|
||||
makeMap('well', 14, 10, (m) => {
|
||||
m.fillG(0, 0, 13, 9, 1);
|
||||
m.fillG(0, 4, 3, 5, 3);
|
||||
m.setO(7, 4, 24); // well
|
||||
m.setO(6, 4, 24);
|
||||
m.setO(7, 5, 24);
|
||||
m.setO(6, 5, 24);
|
||||
m.spawn(2, 5);
|
||||
m.npc('extra5', 10, 7);
|
||||
m.door('to_plaza', 0, 5, 'PlazaScene', 'from_well');
|
||||
m.interact('well', 7, 4, 'well');
|
||||
});
|
||||
|
||||
// 9. Fog 20x8
|
||||
makeMap('fog', 20, 8, (m) => {
|
||||
m.fillG(0, 0, 19, 7, 1);
|
||||
m.fillG(0, 3, 5, 4, 3);
|
||||
for (let x = 12; x < 20; x++) {
|
||||
for (let y = 0; y < 8; y++) m.setO(x, y, 25);
|
||||
}
|
||||
m.spawn(3, 4);
|
||||
m.door('to_plaza', 0, 4, 'PlazaScene', 'from_fog');
|
||||
m.interact('fogwall', 12, 4, 'fogwall');
|
||||
});
|
||||
|
||||
// 10. White layer corridor 20x6 + ward via objects
|
||||
makeMap('white', 20, 14, (m) => {
|
||||
m.fillG(0, 0, 19, 13, 27);
|
||||
m.fillO(0, 0, 19, 0, 26);
|
||||
m.fillO(0, 5, 19, 5, 26);
|
||||
m.fillO(0, 0, 0, 5, 26);
|
||||
m.fillO(19, 0, 19, 5, 26);
|
||||
// ward below
|
||||
m.fillG(5, 6, 14, 13, 27);
|
||||
m.fillO(5, 6, 14, 6, 26);
|
||||
m.fillO(5, 13, 14, 13, 26);
|
||||
m.fillO(5, 6, 5, 13, 26);
|
||||
m.fillO(14, 6, 14, 13, 26);
|
||||
m.setO(10, 5, 0); // opening
|
||||
m.setO(9, 9, 18); // bed
|
||||
m.setO(11, 8, 43);
|
||||
m.spawn(2, 3);
|
||||
m.interact('record', 11, 8, 'record');
|
||||
m.door('to_ward', 10, 5, 'WhiteScene', 'ward');
|
||||
m.objects.push({
|
||||
id: 200,
|
||||
name: 'ward',
|
||||
type: 'spawn',
|
||||
x: 10 * 16,
|
||||
y: 8 * 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
});
|
||||
});
|
||||
|
||||
console.log('All 10 maps generated.');
|
||||
Reference in New Issue
Block a user