@lewismoten/gamemaker-sandbox-tools 3.1.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/NOTICE.md +105 -3
- package/README.md +301 -15
- package/dist/audio-files.js +82 -0
- package/dist/audio.js +23 -138
- package/dist/block-merge.js +43 -0
- package/dist/color-reduce.js +44 -0
- package/dist/colors.js +87 -0
- package/dist/delta.js +75 -0
- package/dist/disk-diff.js +220 -0
- package/dist/drawing.js +83 -869
- package/dist/embroidery/compile.js +85 -0
- package/dist/embroidery/dst.js +79 -0
- package/dist/embroidery/exp.js +26 -0
- package/dist/embroidery/fill.js +49 -0
- package/dist/embroidery/geom.js +82 -0
- package/dist/embroidery/pes.js +79 -0
- package/dist/embroidery/satin.js +29 -0
- package/dist/embroidery/simulate.js +30 -0
- package/dist/embroidery/strokeFont.js +253 -0
- package/dist/embroidery/svg.js +24 -0
- package/dist/embroidery/types.js +13 -0
- package/dist/embroidery/units.js +26 -0
- package/dist/embroidery/validate.js +15 -0
- package/dist/formats/blocks.js +1 -103
- package/dist/formats/character.js +1 -83
- package/dist/formats/cmf.js +1 -37
- package/dist/formats/fli.js +1 -296
- package/dist/formats/fliLimits.js +1 -54
- package/dist/formats/game.js +1 -193
- package/dist/formats/gif.js +1 -125
- package/dist/formats/graphicScripts.js +1 -44
- package/dist/formats/map.js +1 -38
- package/dist/formats/monster.js +1 -69
- package/dist/formats/palette.js +1 -58
- package/dist/formats/recording.js +1 -17
- package/dist/formats/sound.js +1 -44
- package/dist/formats/voc.js +1 -303
- package/dist/gif-shrink.js +56 -0
- package/dist/image/png.js +42 -0
- package/dist/images.js +81 -43
- package/dist/kit/actors.js +19 -0
- package/dist/kit/align.js +204 -0
- package/dist/kit/blit.js +45 -0
- package/dist/kit/blockRoles.js +97 -0
- package/dist/kit/clips.js +40 -0
- package/dist/kit/coverPaint.js +18 -0
- package/dist/kit/disk.js +76 -0
- package/dist/kit/fadeOut.js +13 -0
- package/dist/kit/fliClips.js +133 -0
- package/dist/kit/fliShrink.js +277 -0
- package/dist/kit/gameSim.js +235 -0
- package/dist/kit/hopBot.js +142 -0
- package/dist/kit/levelGen.js +1423 -0
- package/dist/kit/levelGrid.js +33 -0
- package/dist/kit/levelPicture.js +27 -0
- package/dist/kit/menuVersion.js +19 -0
- package/dist/kit/microText.js +35 -0
- package/dist/kit/mumble.js +74 -0
- package/dist/kit/music.js +8 -0
- package/dist/kit/palRamps.js +32 -0
- package/dist/kit/palette.js +49 -0
- package/dist/kit/pcText.js +72 -0
- package/dist/kit/photo.js +150 -0
- package/dist/kit/pixels.js +79 -0
- package/dist/kit/png.js +40 -0
- package/dist/kit/quantize.js +72 -0
- package/dist/kit/raytrace.js +379 -0
- package/dist/kit/recordedDemo.js +10 -0
- package/dist/kit/reel.js +77 -0
- package/dist/kit/road3d.js +67 -0
- package/dist/kit/routeChecks.js +8 -0
- package/dist/kit/saveSlots.js +11 -0
- package/dist/kit/sceneInit.js +13 -0
- package/dist/kit/sceneSim.js +112 -0
- package/dist/kit/screenText.js +15 -0
- package/dist/kit/sdftext.js +237 -0
- package/dist/kit/shading.js +69 -0
- package/dist/kit/song.js +251 -0
- package/dist/kit/songFx.js +179 -0
- package/dist/kit/sound.js +52 -0
- package/dist/kit/synthParts.js +20 -0
- package/dist/kit/tar.js +53 -0
- package/dist/kit/textBounds.js +84 -0
- package/dist/kit/textfit.js +246 -0
- package/dist/kit/transforms.js +57 -0
- package/dist/kit/tune.js +21 -0
- package/dist/look-alike.js +50 -0
- package/dist/menu-version.js +4 -0
- package/dist/mesh/colorBodies.js +137 -0
- package/dist/mesh/decimate.js +207 -0
- package/dist/mesh/meshCheck.js +51 -0
- package/dist/mesh/overhang.js +41 -0
- package/dist/mesh/sampledField.js +12 -0
- package/dist/mesh/stl.js +36 -0
- package/dist/mesh/surfaceNets.js +79 -0
- package/dist/mesh/tetraMesh.js +62 -0
- package/dist/mesh/threeMf.js +58 -0
- package/dist/mesh/zipFile.js +52 -0
- package/dist/microFont.js +101 -0
- package/dist/music/compose.js +72 -0
- package/dist/pack/meshPack.js +198 -0
- package/dist/pack/threeMfPack.js +92 -0
- package/dist/palette-reserve.js +116 -0
- package/dist/palettes.js +138 -0
- package/dist/release-notes.js +40 -0
- package/dist/simulation.js +16 -2774
- package/dist/text.js +74 -0
- package/dist/types/audio.d.ts +4 -0
- package/dist/types/audioFiles.d.ts +22 -0
- package/dist/types/audioWav.d.ts +4 -0
- package/dist/types/blockMerge.d.ts +24 -0
- package/dist/types/colorReduce.d.ts +23 -0
- package/dist/types/{web/packages/tools/src/colors.d.ts → colors.d.ts} +6 -0
- package/dist/types/delta.d.ts +32 -0
- package/dist/types/diskDiff.d.ts +47 -0
- package/dist/types/drawing.d.ts +15 -0
- package/dist/types/embroidery/compile.d.ts +3 -0
- package/dist/types/embroidery/dst.d.ts +13 -0
- package/dist/types/embroidery/exp.d.ts +8 -0
- package/dist/types/embroidery/fill.d.ts +6 -0
- package/dist/types/embroidery/geom.d.ts +19 -0
- package/dist/types/embroidery/pes.d.ts +10 -0
- package/dist/types/embroidery/satin.d.ts +11 -0
- package/dist/types/embroidery/simulate.d.ts +19 -0
- package/dist/types/embroidery/strokeFont.d.ts +20 -0
- package/dist/types/embroidery/svg.d.ts +3 -0
- package/dist/types/embroidery/types.d.ts +70 -0
- package/dist/types/embroidery/units.d.ts +10 -0
- package/dist/types/embroidery/validate.d.ts +22 -0
- package/dist/types/formats/blocks.d.ts +1 -0
- package/dist/types/formats/character.d.ts +1 -0
- package/dist/types/formats/cmf.d.ts +1 -0
- package/dist/types/formats/fli.d.ts +1 -0
- package/dist/types/formats/fliLimits.d.ts +1 -0
- package/dist/types/formats/game.d.ts +1 -0
- package/dist/types/formats/gif.d.ts +1 -0
- package/dist/types/formats/graphicScripts.d.ts +1 -0
- package/dist/types/formats/map.d.ts +1 -0
- package/dist/types/formats/monster.d.ts +1 -0
- package/dist/types/formats/palette.d.ts +1 -0
- package/dist/types/formats/recording.d.ts +1 -0
- package/dist/types/formats/sound.d.ts +1 -0
- package/dist/types/formats/voc.d.ts +1 -0
- package/dist/types/gifShrink.d.ts +8 -0
- package/dist/types/image/animatedGif.d.ts +9 -0
- package/dist/types/image/surface.d.ts +26 -0
- package/dist/types/images.d.ts +13 -0
- package/dist/types/kit/actors.d.ts +7 -0
- package/dist/types/kit/align.d.ts +93 -0
- package/dist/types/kit/audioEvents.d.ts +26 -0
- package/dist/types/kit/blit.d.ts +20 -0
- package/dist/types/kit/blockRoles.d.ts +243 -0
- package/dist/types/{games/kit → kit}/clips.d.ts +1 -1
- package/dist/types/kit/coverPaint.d.ts +7 -0
- package/dist/types/kit/disk.d.ts +15 -0
- package/dist/types/kit/fadeOut.d.ts +12 -0
- package/dist/types/kit/fliClips.d.ts +32 -0
- package/dist/types/kit/fliShrink.d.ts +149 -0
- package/dist/types/{games/kit → kit}/gameSim.d.ts +9 -5
- package/dist/types/kit/hopBot.d.ts +72 -0
- package/dist/types/kit/laserClearance.d.ts +16 -0
- package/dist/types/kit/laserJoints.d.ts +39 -0
- package/dist/types/kit/laserLayout.d.ts +54 -0
- package/dist/types/kit/laserPixels.d.ts +52 -0
- package/dist/types/kit/laserPreview.d.ts +9 -0
- package/dist/types/kit/laserSvg.d.ts +35 -0
- package/dist/types/kit/levelGen/castle.d.ts +17 -0
- package/dist/types/kit/levelGen/dungeon.d.ts +11 -0
- package/dist/types/kit/levelGen/forest.d.ts +17 -0
- package/dist/types/kit/levelGen/furnish.d.ts +31 -0
- package/dist/types/kit/levelGen/grid.d.ts +46 -0
- package/dist/types/kit/levelGen/index.d.ts +138 -0
- package/dist/types/kit/levelGen/interior.d.ts +18 -0
- package/dist/types/kit/levelGen/jumpModel.d.ts +78 -0
- package/dist/types/kit/levelGen/needs.d.ts +44 -0
- package/dist/types/kit/levelGen/overworld.d.ts +21 -0
- package/dist/types/kit/levelGen/platform.d.ts +59 -0
- package/dist/types/kit/levelGen/platformCap.d.ts +13 -0
- package/dist/types/kit/levelGen/platformReach.d.ts +37 -0
- package/dist/types/kit/levelGen/props.d.ts +37 -0
- package/dist/types/kit/levelGen/town.d.ts +24 -0
- package/dist/types/kit/levelGrid.d.ts +16 -0
- package/dist/types/kit/levelPicture.d.ts +9 -0
- package/dist/types/kit/menuVersion.d.ts +7 -0
- package/dist/types/kit/microText.d.ts +18 -0
- package/dist/types/kit/mumble.d.ts +41 -0
- package/dist/types/kit/music.d.ts +1 -0
- package/dist/types/kit/palMerge.d.ts +10 -0
- package/dist/types/kit/palRamps.d.ts +28 -0
- package/dist/types/kit/pcText.d.ts +19 -0
- package/dist/types/kit/photo.d.ts +69 -0
- package/dist/types/kit/png.d.ts +7 -0
- package/dist/types/kit/quantize.d.ts +20 -0
- package/dist/types/kit/raytrace.d.ts +169 -0
- package/dist/types/kit/recordedDemo.d.ts +1 -0
- package/dist/types/kit/road3d.d.ts +71 -0
- package/dist/types/kit/routeChecks.d.ts +6 -0
- package/dist/types/kit/saveSlots.d.ts +17 -0
- package/dist/types/kit/sceneInit.d.ts +11 -0
- package/dist/types/{games/kit → kit}/sceneSim.d.ts +5 -5
- package/dist/types/kit/screenText.d.ts +3 -0
- package/dist/types/kit/sdftext.d.ts +34 -0
- package/dist/types/kit/shading.d.ts +23 -0
- package/dist/types/kit/shareBlocks.d.ts +20 -0
- package/dist/types/kit/song.d.ts +89 -0
- package/dist/types/kit/songFx.d.ts +99 -0
- package/dist/types/kit/synthParts.d.ts +7 -0
- package/dist/types/kit/tar.d.ts +13 -0
- package/dist/types/kit/textfit.d.ts +74 -0
- package/dist/types/kit/transforms.d.ts +8 -0
- package/dist/types/lookAlike.d.ts +31 -0
- package/dist/types/menuVersionEntry.d.ts +1 -0
- package/dist/types/mesh/colorBodies.d.ts +18 -0
- package/dist/types/mesh/decimate.d.ts +10 -0
- package/dist/types/mesh/fieldTrinket.d.ts +40 -0
- package/dist/types/mesh/figureShapes.d.ts +24 -0
- package/dist/types/mesh/mesh.d.ts +9 -0
- package/dist/types/mesh/meshCheck.d.ts +22 -0
- package/dist/types/mesh/overhang.d.ts +24 -0
- package/dist/types/mesh/pixelFigure.d.ts +41 -0
- package/dist/types/mesh/sampledField.d.ts +3 -0
- package/dist/types/mesh/sdfShapes.d.ts +20 -0
- package/dist/types/mesh/stl.d.ts +9 -0
- package/dist/types/mesh/strokeText.d.ts +8 -0
- package/dist/types/mesh/surfaceNets.d.ts +14 -0
- package/dist/types/mesh/tetraMesh.d.ts +4 -0
- package/dist/types/mesh/threeMf.d.ts +12 -0
- package/dist/types/mesh/trinketKinds.d.ts +72 -0
- package/dist/types/mesh/trinketTool.d.ts +26 -0
- package/dist/types/mesh/voxel.d.ts +10 -0
- package/dist/types/mesh/zipFile.d.ts +13 -0
- package/dist/types/microFont.d.ts +6 -0
- package/dist/types/pack/meshPack.d.ts +26 -0
- package/dist/types/pack/threeMfPack.d.ts +11 -0
- package/dist/types/palettePresetData.d.ts +4 -0
- package/dist/types/palettePresets.d.ts +12 -0
- package/dist/types/paletteReserve.d.ts +52 -0
- package/dist/types/palettes.d.ts +4 -0
- package/dist/types/releaseNotes.d.ts +3 -0
- package/dist/types/simulation.d.ts +6 -0
- package/dist/types/{web/packages/tools/src/text.d.ts → text.d.ts} +6 -6
- package/package.json +145 -15
- package/dist/binary-D7wuaC5g.js +0 -120
- package/dist/pixels-DzfIIUOl.js +0 -76
- package/dist/types/games/kit/blit.d.ts +0 -10
- package/dist/types/games/kit/music.d.ts +0 -1
- package/dist/types/games/kit/pcText.d.ts +0 -8
- package/dist/types/games/kit/shading.d.ts +0 -11
- package/dist/types/web/packages/tools/src/audio.d.ts +0 -3
- package/dist/types/web/packages/tools/src/drawing.d.ts +0 -10
- package/dist/types/web/packages/tools/src/images.d.ts +0 -2
- package/dist/types/web/packages/tools/src/microFont.d.ts +0 -1
- package/dist/types/web/packages/tools/src/simulation.d.ts +0 -3
- package/dist/types/web/scripts/cdGames.d.ts +0 -103
- package/dist/types/web/scripts/gameShots.d.ts +0 -12
- package/dist/types/web/scripts/ogImage.d.ts +0 -21
- package/dist/types/web/src/audio/cmfLoad.d.ts +0 -7
- package/dist/types/web/src/audio/cmfPlayer.d.ts +0 -69
- package/dist/types/web/src/audio/context.d.ts +0 -12
- package/dist/types/web/src/audio/engine.d.ts +0 -39
- package/dist/types/web/src/audio/music.worklet.d.ts +0 -14
- package/dist/types/web/src/audio/opl.d.ts +0 -37
- package/dist/types/web/src/audio/output.d.ts +0 -13
- package/dist/types/web/src/desk/boxes/boxFacts.d.ts +0 -85
- package/dist/types/web/src/dosPlayer/fileExtensions.d.ts +0 -44
- package/dist/types/web/src/dosPlayer/patchRules.d.ts +0 -24
- package/dist/types/web/src/dosPlayer/patchTable.d.ts +0 -80
- package/dist/types/web/src/edition.d.ts +0 -6
- package/dist/types/web/src/eggs/eggState.d.ts +0 -26
- package/dist/types/web/src/eggs/eggs.d.ts +0 -31
- package/dist/types/web/src/engine/character.d.ts +0 -30
- package/dist/types/web/src/engine/funcKeys.d.ts +0 -33
- package/dist/types/web/src/engine/game.d.ts +0 -52
- package/dist/types/web/src/engine/keys.d.ts +0 -17
- package/dist/types/web/src/engine/machine.d.ts +0 -99
- package/dist/types/web/src/engine/menus.d.ts +0 -46
- package/dist/types/web/src/engine/monsters.d.ts +0 -19
- package/dist/types/web/src/engine/playGain.d.ts +0 -11
- package/dist/types/web/src/engine/playerLook.d.ts +0 -26
- package/dist/types/web/src/engine/recorder.d.ts +0 -60
- package/dist/types/web/src/engine/render.d.ts +0 -8
- package/dist/types/web/src/engine/scene.d.ts +0 -156
- package/dist/types/web/src/engine/scroll.d.ts +0 -16
- package/dist/types/web/src/engine/showGraphic.d.ts +0 -39
- package/dist/types/web/src/engine/slowPc.d.ts +0 -62
- package/dist/types/web/src/engine/touch.d.ts +0 -33
- package/dist/types/web/src/engine/world.d.ts +0 -215
- package/dist/types/web/src/export/gameAbout.d.ts +0 -15
- package/dist/types/web/src/formats/binary.d.ts +0 -44
- package/dist/types/web/src/formats/blocks.d.ts +0 -52
- package/dist/types/web/src/formats/character.d.ts +0 -65
- package/dist/types/web/src/formats/cmf.d.ts +0 -33
- package/dist/types/web/src/formats/fli.d.ts +0 -45
- package/dist/types/web/src/formats/fliLimits.d.ts +0 -13
- package/dist/types/web/src/formats/game.d.ts +0 -72
- package/dist/types/web/src/formats/gif.d.ts +0 -15
- package/dist/types/web/src/formats/graphicScripts.d.ts +0 -18
- package/dist/types/web/src/formats/highscore.d.ts +0 -10
- package/dist/types/web/src/formats/map.d.ts +0 -24
- package/dist/types/web/src/formats/monster.d.ts +0 -48
- package/dist/types/web/src/formats/palette.d.ts +0 -15
- package/dist/types/web/src/formats/recording.d.ts +0 -7
- package/dist/types/web/src/formats/sound.d.ts +0 -13
- package/dist/types/web/src/formats/voc.d.ts +0 -13
- package/dist/types/web/src/gfx/cp437Glyphs.d.ts +0 -2
- package/dist/types/web/src/gfx/font8x8.d.ts +0 -2
- package/dist/types/web/src/gfx/levelPicture.d.ts +0 -81
- package/dist/types/web/src/gfx/screen.d.ts +0 -46
- package/dist/types/web/src/gfx/titlePicture.d.ts +0 -21
- package/dist/types/web/src/input/chords.d.ts +0 -22
- package/dist/types/web/src/input/deskMouse.d.ts +0 -14
- package/dist/types/web/src/input/keyboard.d.ts +0 -39
- package/dist/types/web/src/input/scancodes.d.ts +0 -3
- package/dist/types/web/src/manual/printables/types.d.ts +0 -277
- package/dist/types/web/src/project/bizarre.d.ts +0 -28
- package/dist/types/web/src/project/companion.d.ts +0 -35
- package/dist/types/web/src/project/diskFacts.d.ts +0 -30
- package/dist/types/web/src/project/files.d.ts +0 -124
- package/dist/types/web/src/project/gameFiles.d.ts +0 -49
- package/dist/types/web/src/project/gamePack.d.ts +0 -17
- package/dist/types/web/src/project/health.d.ts +0 -30
- package/dist/types/web/src/project/secretGames.d.ts +0 -19
- package/dist/types/web/src/project/storage.d.ts +0 -46
- package/dist/types/web/src/project/streamGame.d.ts +0 -38
- package/dist/types/web/src/project/zip.d.ts +0 -33
- package/dist/types/web/src/retro/dos/disks.d.ts +0 -33
- package/dist/types/web/src/retro/text/cp437.d.ts +0 -4
- package/dist/types/web/src/seededRandom.d.ts +0 -6
- package/dist/types/web/src/tinHearts/deskHearts.d.ts +0 -33
- package/dist/types/web/src/tinHearts/manifest.d.ts +0 -30
- package/dist/types/web/src/tinHearts/tinHearts.d.ts +0 -84
- package/dist/types/web/src/walkthrough/format.d.ts +0 -92
- package/dist/types/web/src/walkthrough/madeUpScores.d.ts +0 -6
- package/dist/types/web/src/walkthrough/runtime.d.ts +0 -134
- /package/dist/types/{web/src/assistant → image}/png.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/palette.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/pixels.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/reel.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/sound.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/textBounds.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/tune.d.ts +0 -0
- /package/dist/types/{web/src/audio → music}/compose.d.ts +0 -0
|
@@ -0,0 +1,1423 @@
|
|
|
1
|
+
import { blocksWithRole as X, ROLES as ue, MAX_PAIR as Zt, FACINGS as de } from "./blockRoles.js";
|
|
2
|
+
import { CHARBL as pe, BLEN as j } from "@lewismoten/gamemaker-sandbox-engine/formats/blocks";
|
|
3
|
+
import { GRAVSPEED as ye, MAXGRAV as gt } from "@lewismoten/gamemaker-sandbox-engine/engine/world";
|
|
4
|
+
import { MAXSEQ as xe } from "@lewismoten/gamemaker-sandbox-engine/formats/character";
|
|
5
|
+
const ke = [
|
|
6
|
+
{
|
|
7
|
+
id: "platform",
|
|
8
|
+
label: "Platform",
|
|
9
|
+
blurb: "A side view, left to right: ground with pits, steps, ladders, spikes and stepping stones, sized to what the hero can really jump.",
|
|
10
|
+
min: { w: 40, h: 20 },
|
|
11
|
+
must: ["wall", "sky"],
|
|
12
|
+
want: [
|
|
13
|
+
{
|
|
14
|
+
role: "platform",
|
|
15
|
+
use: "Ledges to jump up to, and stepping stones across wide pits (solid on top only).",
|
|
16
|
+
without: "stones are made of wall blocks and there are no ledges"
|
|
17
|
+
},
|
|
18
|
+
{ role: "ladder", use: "Beside tall towers the hero cannot jump up (he needs an up key that climbs).", without: "no towers" },
|
|
19
|
+
{ role: "hazard", use: "Spikes to jump over, and in the bottom of pits.", without: "pits are floored with wall and there are no spikes" },
|
|
20
|
+
{ role: "wall-top", use: "The top row of the ground.", without: "the ground top uses the wall block" },
|
|
21
|
+
{ role: "treasure", use: "Coins along the path and over pits, where a jump reaches them.", without: "no coins" },
|
|
22
|
+
{ role: "life", use: "One heart on the highest place he can stand.", without: "no heart" },
|
|
23
|
+
{ role: "locked-door", use: "A tall door late in the level (needs a key block with the same lock number).", without: "no locked door" },
|
|
24
|
+
{ role: "key", use: "On an earlier stretch, picked up on the way.", without: "no locked door" },
|
|
25
|
+
{ role: "decoration", use: "Bushes and flowers on the ground.", without: "no decoration" }
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "dungeon",
|
|
30
|
+
min: { w: 12, h: 12 },
|
|
31
|
+
label: "Dungeon",
|
|
32
|
+
blurb: "Rooms joined by corridors, with the walls drawn round them.",
|
|
33
|
+
must: ["wall", "floor"],
|
|
34
|
+
want: [
|
|
35
|
+
{ role: "decoration", use: "Scattered inside the bigger rooms.", without: "the rooms are left bare" },
|
|
36
|
+
{
|
|
37
|
+
role: "locked-door",
|
|
38
|
+
use: "Shut in a narrow passage on the way to the exit (needs a key block with the same lock number).",
|
|
39
|
+
without: "no locked doors"
|
|
40
|
+
},
|
|
41
|
+
{ role: "key", use: "Placed where it can be reached before its locked door.", without: "no locked doors" },
|
|
42
|
+
{ role: "treasure", use: "In corners and dead ends, more of it far from the entry.", without: "no treasure" },
|
|
43
|
+
{ role: "life", use: "One heart in a far corner.", without: "no heart" }
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "forest",
|
|
48
|
+
min: { w: 12, h: 12 },
|
|
49
|
+
label: "Forest",
|
|
50
|
+
blurb: "Trees with clearings and a winding path through them.",
|
|
51
|
+
must: ["floor", "tree"],
|
|
52
|
+
want: [
|
|
53
|
+
{ role: "path", use: "A winding trail from one side to the other.", without: "no trail" },
|
|
54
|
+
{ role: "rock", use: "A few rocks in the open.", without: "no rocks" },
|
|
55
|
+
{ role: "decoration", use: "Flowers and bushes in the open.", without: "no flowers" },
|
|
56
|
+
{ role: "treasure", use: "In dead ends and nooks among the trees.", without: "no treasure" },
|
|
57
|
+
{ role: "life", use: "One heart in a far nook.", without: "no heart" }
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "home",
|
|
62
|
+
label: "Home",
|
|
63
|
+
blurb: "One to three rooms with a front door; furniture against the walls and chairs facing the table.",
|
|
64
|
+
min: { w: 12, h: 10 },
|
|
65
|
+
must: ["wall", "floor"],
|
|
66
|
+
want: [
|
|
67
|
+
{ role: "door", use: "The front door in the south wall (the entry and exit).", without: "the front door is plain floor" },
|
|
68
|
+
{ role: "table", use: "A table in the living room.", without: "no table" },
|
|
69
|
+
{ role: "chair", use: "Next to the table, facing it (a chair block must say which way it faces).", without: "no chairs" },
|
|
70
|
+
{ role: "bed", use: "Against a wall, front to the room.", without: "no beds" },
|
|
71
|
+
{ role: "shelf", use: "Against walls.", without: "no shelves" },
|
|
72
|
+
{ role: "stove", use: "Against a wall of the living room.", without: "no stove" },
|
|
73
|
+
{ role: "rug", use: "Under and around the table.", without: "no rugs" },
|
|
74
|
+
{ role: "lamp", use: "Against walls.", without: "no lamps" },
|
|
75
|
+
{ role: "plant", use: "In a corner.", without: "no plants" }
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "shop",
|
|
80
|
+
label: "Shop",
|
|
81
|
+
blurb: "One room: shelves on the back wall, a counter across it, and room for customers by the door.",
|
|
82
|
+
min: { w: 12, h: 10 },
|
|
83
|
+
must: ["wall", "floor"],
|
|
84
|
+
want: [
|
|
85
|
+
{ role: "door", use: "The front door in the south wall (the entry and exit).", without: "the front door is plain floor" },
|
|
86
|
+
{ role: "counter", use: "Across the room, facing the door (the block must face south), with an open end to the shopkeeper.", without: "no counter" },
|
|
87
|
+
{ role: "shelf", use: "Along the back wall and the side walls.", without: "no shelves" },
|
|
88
|
+
{ role: "table", use: "A display table for customers.", without: "no display table" },
|
|
89
|
+
{ role: "rug", use: "Inside the door.", without: "no rug" },
|
|
90
|
+
{ role: "lamp", use: "Against the side walls.", without: "no lamps" },
|
|
91
|
+
{ role: "plant", use: "In a corner.", without: "no plants" }
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "castle",
|
|
96
|
+
label: "Castle",
|
|
97
|
+
blurb: "An outer wall with corner towers and a gate, a courtyard, and a keep of rooms.",
|
|
98
|
+
min: { w: 30, h: 24 },
|
|
99
|
+
must: ["wall", "floor"],
|
|
100
|
+
want: [
|
|
101
|
+
{ role: "door", use: "In the gate and the keep door.", without: "the gate and keep door are plain floor" },
|
|
102
|
+
{ role: "path", use: "A road from the gate to the keep door.", without: "no road" },
|
|
103
|
+
{ role: "decoration", use: "Scattered in the courtyard and the keep rooms.", without: "the courtyard is bare" },
|
|
104
|
+
{ role: "locked-door", use: "Shut in a narrow passage of the keep (needs a key block with the same lock number).", without: "no locked doors" },
|
|
105
|
+
{ role: "key", use: "Placed where it can be reached before its locked door.", without: "no locked doors" },
|
|
106
|
+
{ role: "treasure", use: "In tower rooms, corners and dead ends of the keep.", without: "no treasure" },
|
|
107
|
+
{ role: "life", use: "One heart in a far corner.", without: "no heart" }
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: "town",
|
|
112
|
+
label: "Town",
|
|
113
|
+
blurb: "A winding main street between two gates, cross streets, a plaza and houses with their doors on the street.",
|
|
114
|
+
min: { w: 40, h: 28 },
|
|
115
|
+
must: ["wall", "floor"],
|
|
116
|
+
want: [
|
|
117
|
+
{ role: "door", use: "On each house front and in the two gates (proposed links to interiors and the overworld).", without: "the doors are plain floor" },
|
|
118
|
+
{ role: "wall-top", use: "The two top rows of each house (its roof).", without: "roofs use the wall block" },
|
|
119
|
+
{ role: "path", use: "The streets and the plaza.", without: "streets are plain floor" },
|
|
120
|
+
{ role: "tree", use: "A ring round the town and a few in the open.", without: "no trees" },
|
|
121
|
+
{ role: "decoration", use: "In the plaza and scattered in the open.", without: "no decoration" }
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: "overworld",
|
|
126
|
+
label: "Overworld",
|
|
127
|
+
blurb: "Land and sea with forests and mountains, shores drawn with the water brush, and a road joining towns, dungeon entrances and a castle.",
|
|
128
|
+
min: { w: 40, h: 40 },
|
|
129
|
+
must: ["floor", "water"],
|
|
130
|
+
want: [
|
|
131
|
+
{ role: "tree", use: "Forest where the land is wet.", without: "no forests" },
|
|
132
|
+
{ role: "rock", use: "Mountains on the highest ground.", without: "no mountains" },
|
|
133
|
+
{ role: "path", use: "A road joining the sites.", without: "roads are plain floor" },
|
|
134
|
+
{ role: "door", use: "The mark of each site (a town, dungeon entrance or castle).", without: "sites are marked by a clearing only" },
|
|
135
|
+
{ role: "decoration", use: "Scattered on the grass.", without: "no flowers" }
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
], se = (t) => ke.find((e) => e.id === t), qt = (t) => ue.find((e) => e.id === t).label;
|
|
139
|
+
function ge(t, e) {
|
|
140
|
+
const o = se(t), s = (h) => X(e, h).length, n = [
|
|
141
|
+
...o.must.map((h) => ({ role: h, label: qt(h), must: !0, count: s(h) })),
|
|
142
|
+
...o.want.map((h) => ({ role: h.role, label: qt(h.role), must: !1, count: s(h.role), use: h.use, without: h.without }))
|
|
143
|
+
], c = n.filter((h) => h.must && !h.count).map((h) => h.label.toLowerCase()), a = c.length ? `Needs ${c.map((h) => `a ${h} block`).join(" and ")}. Mark ${c.length > 1 ? "them" : "one"} in the block editor's Uses tab.` : "", x = n.filter((h) => !h.must && !h.count), y = [...new Set(x.map((h) => h.without))].map(
|
|
144
|
+
(h) => `No ${x.filter((l) => l.without === h).map((l) => l.label.toLowerCase()).join(" or ")} block: ${h}.`
|
|
145
|
+
);
|
|
146
|
+
return { kind: t, items: n, ok: !c.length, message: a, skipped: y };
|
|
147
|
+
}
|
|
148
|
+
function zt(t) {
|
|
149
|
+
let e = t >>> 0;
|
|
150
|
+
const o = () => {
|
|
151
|
+
e = e + 1831565813 >>> 0;
|
|
152
|
+
let s = e;
|
|
153
|
+
return s = Math.imul(s ^ s >>> 15, s | 1), s ^= s + Math.imul(s ^ s >>> 7, s | 61), ((s ^ s >>> 14) >>> 0) / 4294967296;
|
|
154
|
+
};
|
|
155
|
+
return {
|
|
156
|
+
next: o,
|
|
157
|
+
/** An integer from lo to hi, both included. */
|
|
158
|
+
int: (s, n) => s + Math.floor(o() * (n - s + 1)),
|
|
159
|
+
chance: (s) => o() < s,
|
|
160
|
+
pick: (s) => s[Math.floor(o() * s.length)]
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const Q = 0, Z = 1, ct = 2, J = 3, Et = 4, ut = 5, Ot = 6, Kt = 7, Bt = 8, Gt = 9, le = 10, dt = 11, it = 12, bt = 13, yt = 14, ft = 15, ht = 16, xt = 17, tt = (t) => t === Q || t === J || t === Et || t === le || t === it || t === bt, pt = (t, e, o) => ({ w: t, h: e, cells: new Uint8Array(t * e).fill(o) }), me = [
|
|
164
|
+
[1, 0],
|
|
165
|
+
[-1, 0],
|
|
166
|
+
[0, 1],
|
|
167
|
+
[0, -1]
|
|
168
|
+
];
|
|
169
|
+
function st(t, e) {
|
|
170
|
+
const o = new Int32Array(t.cells.length).fill(-1);
|
|
171
|
+
if (tt(t.cells[e])) return o;
|
|
172
|
+
o[e] = 0;
|
|
173
|
+
const s = [e];
|
|
174
|
+
for (let n = 0; n < s.length; n++) {
|
|
175
|
+
const c = s[n], a = c % t.w, x = c / t.w | 0;
|
|
176
|
+
for (const [y, h] of me) {
|
|
177
|
+
const l = a + y, i = x + h;
|
|
178
|
+
if (l < 0 || i < 0 || l >= t.w || i >= t.h) continue;
|
|
179
|
+
const r = i * t.w + l;
|
|
180
|
+
o[r] < 0 && !tt(t.cells[r]) && (o[r] = o[c] + 1, s.push(r));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return o;
|
|
184
|
+
}
|
|
185
|
+
function Yt(t, e, o) {
|
|
186
|
+
for (let s = -1; s <= 1; s++)
|
|
187
|
+
for (let n = -1; n <= 1; n++) {
|
|
188
|
+
const c = e + n, a = o + s;
|
|
189
|
+
if (c < 0 || a < 0 || c >= t.w || a >= t.h || tt(t.cells[a * t.w + c])) return !1;
|
|
190
|
+
}
|
|
191
|
+
return !0;
|
|
192
|
+
}
|
|
193
|
+
function ce(t, e) {
|
|
194
|
+
const o = st(t, e);
|
|
195
|
+
let s = e;
|
|
196
|
+
for (let n = 0; n < o.length; n++) o[n] > o[s] && (s = n);
|
|
197
|
+
return s;
|
|
198
|
+
}
|
|
199
|
+
const re = [
|
|
200
|
+
[1, 0],
|
|
201
|
+
[-1, 0],
|
|
202
|
+
[0, 1],
|
|
203
|
+
[0, -1]
|
|
204
|
+
];
|
|
205
|
+
function Rt(t, e) {
|
|
206
|
+
const o = e % t.w, s = e / t.w | 0;
|
|
207
|
+
let n = 0;
|
|
208
|
+
for (let c = -1; c <= 1; c++)
|
|
209
|
+
for (let a = -1; a <= 1; a++) {
|
|
210
|
+
if (!a && !c) continue;
|
|
211
|
+
const x = o + a, y = s + c;
|
|
212
|
+
(x < 0 || y < 0 || x >= t.w || y >= t.h || tt(t.cells[y * t.w + x])) && n++;
|
|
213
|
+
}
|
|
214
|
+
return n;
|
|
215
|
+
}
|
|
216
|
+
function Wt(t, e) {
|
|
217
|
+
const o = { w: t.w, h: t.h, cells: t.cells.slice() };
|
|
218
|
+
for (const s of e) o.cells[s] = 0;
|
|
219
|
+
return o;
|
|
220
|
+
}
|
|
221
|
+
function we(t, e, o) {
|
|
222
|
+
const s = st(t, o);
|
|
223
|
+
if (s[e] < 0) return [];
|
|
224
|
+
const n = [e];
|
|
225
|
+
for (; n[n.length - 1] !== o; ) {
|
|
226
|
+
const c = n[n.length - 1], a = c % t.w, x = c / t.w | 0;
|
|
227
|
+
let y = -1;
|
|
228
|
+
for (const [h, l] of re) {
|
|
229
|
+
const i = a + h, r = x + l;
|
|
230
|
+
if (i < 0 || r < 0 || i >= t.w || r >= t.h) continue;
|
|
231
|
+
const M = r * t.w + i;
|
|
232
|
+
s[M] >= 0 && s[M] < s[c] && y < 0 && (y = M);
|
|
233
|
+
}
|
|
234
|
+
n.push(y);
|
|
235
|
+
}
|
|
236
|
+
return n;
|
|
237
|
+
}
|
|
238
|
+
function Me(t, e) {
|
|
239
|
+
const o = e % t.w, s = e / t.w | 0, n = (c, a) => {
|
|
240
|
+
const x = o + c, y = s + a;
|
|
241
|
+
return x >= 0 && y >= 0 && x < t.w && y < t.h && !tt(t.cells[y * t.w + x]);
|
|
242
|
+
};
|
|
243
|
+
return n(1, 0) && n(-1, 0) && !n(0, 1) && !n(0, -1) || n(0, 1) && n(0, -1) && !n(1, 0) && !n(-1, 0);
|
|
244
|
+
}
|
|
245
|
+
function be(t, e, o, s, n) {
|
|
246
|
+
const c = /* @__PURE__ */ new Set([e, o]), a = [], x = [], y = [], h = (M, T, k) => M.every((b) => Math.max(Math.abs(b % t.w - T % t.w), Math.abs((b / t.w | 0) - (T / t.w | 0))) >= k);
|
|
247
|
+
if (n.pairs.length) {
|
|
248
|
+
const M = we(t, e, o), T = M.filter(
|
|
249
|
+
(p, f) => f >= 4 && f < M.length - 3 && t.cells[p] === Z && Me(t, p) && st(Wt(t, [p]), e)[o] < 0
|
|
250
|
+
), k = Math.min(n.pairs.length, 3, T.length), b = [];
|
|
251
|
+
for (let p = 0; p < k; p++) b.push(T[Math.min(T.length - 1, Math.floor((p + 1) * T.length / (k + 1)))]);
|
|
252
|
+
const C = [...new Set(b)];
|
|
253
|
+
C.forEach((p, f) => {
|
|
254
|
+
const w = C.slice(f), L = st(Wt(t, w), e);
|
|
255
|
+
let P = -1, z = -1;
|
|
256
|
+
for (let E = 0; E < L.length; E++) {
|
|
257
|
+
if (L[E] < 3 || c.has(E) || w.includes(E)) continue;
|
|
258
|
+
const U = Rt(t, E) * 4 + Math.min(L[E], 40) + s.next() * 3;
|
|
259
|
+
U > z && (z = U, P = E);
|
|
260
|
+
}
|
|
261
|
+
P < 0 || (c.add(p), c.add(P), a.push({ cell: p, key: P, pair: n.pairs[f % n.pairs.length], order: f }));
|
|
262
|
+
});
|
|
263
|
+
for (const p of a)
|
|
264
|
+
t.cells[p.cell] = Ot, t.cells[p.key] = Kt;
|
|
265
|
+
}
|
|
266
|
+
const l = st(t, e), i = [];
|
|
267
|
+
for (let M = 0; M < l.length; M++) l[M] >= 0 && !c.has(M) && t.cells[M] !== Ot && i.push(M);
|
|
268
|
+
if (n.treasure) {
|
|
269
|
+
const M = Math.max(3, Math.min(12, Math.round(i.length / 150))), T = i.filter((k) => l[k] >= 3 && Rt(t, k) >= 5).map((k) => ({ i: k, s: Rt(t, k) * 3 + Math.min(l[k], 60) / 2 + s.next() * 4 })).sort((k, b) => b.s - k.s || k.i - b.i);
|
|
270
|
+
for (const { i: k } of T) {
|
|
271
|
+
if (x.length >= M) break;
|
|
272
|
+
h(x, k, 4) && (x.push(k), c.add(k));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
let r;
|
|
276
|
+
n.life && x.length > 2 && (r = x.pop(), t.cells[r] = Gt);
|
|
277
|
+
for (const M of x) t.cells[M] = Bt;
|
|
278
|
+
if (n.monsters.length) {
|
|
279
|
+
const M = Math.max(2, Math.min(10, Math.round(i.length / 130))), T = i.filter((b) => l[b] >= 5 && !c.has(b) && Rt(t, b) <= 2), k = [];
|
|
280
|
+
for (let b = 0; b < T.length * 2 && y.length < M && T.length; b++) {
|
|
281
|
+
const C = T[Math.floor(s.next() * T.length)];
|
|
282
|
+
h(k, C, 5) && (k.push(C), y.push({ cell: C, monnum: s.pick(n.monsters) }));
|
|
283
|
+
}
|
|
284
|
+
y.sort((b, C) => b.cell - C.cell);
|
|
285
|
+
}
|
|
286
|
+
return { locks: a, treasure: x, life: r, monsters: y };
|
|
287
|
+
}
|
|
288
|
+
function ve(t, e, o, s, n) {
|
|
289
|
+
const c = /* @__PURE__ */ new Set(), a = new Map(s.map((i) => [i.cell, i])), x = new Map(s.map((i) => [i.key, i.pair]));
|
|
290
|
+
let y = new Uint8Array(t.cells.length);
|
|
291
|
+
for (let i = !0; i; ) {
|
|
292
|
+
i = !1, y = new Uint8Array(t.cells.length);
|
|
293
|
+
const r = [e];
|
|
294
|
+
for (y[e] = 1; r.length; ) {
|
|
295
|
+
const M = r.pop(), T = x.get(M);
|
|
296
|
+
T !== void 0 && !c.has(T) && (c.add(T), i = !0);
|
|
297
|
+
const k = M % t.w, b = M / t.w | 0;
|
|
298
|
+
for (const [C, p] of re) {
|
|
299
|
+
const f = k + C, w = b + p;
|
|
300
|
+
if (f < 0 || w < 0 || f >= t.w || w >= t.h) continue;
|
|
301
|
+
const L = w * t.w + f, P = a.get(L);
|
|
302
|
+
y[L] || tt(t.cells[L]) || P && !c.has(P.pair) || (y[L] = 1, r.push(L));
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
const h = y[o] === 1 && s.every((i) => y[i.cell] && y[i.key]) && n.every((i) => y[i]), l = s.every((i) => {
|
|
307
|
+
const r = s.filter((M) => M.order >= i.order).map((M) => M.cell);
|
|
308
|
+
return st(Wt(t, r), e)[i.key] >= 0;
|
|
309
|
+
});
|
|
310
|
+
return { ok: h, strict: l };
|
|
311
|
+
}
|
|
312
|
+
const Dt = 9;
|
|
313
|
+
function _t(t, e, o) {
|
|
314
|
+
const s = t.w < t.h ? !0 : t.h < t.w ? !1 : e.chance(0.5), n = s ? t.h : t.w;
|
|
315
|
+
if (o > 6 || n < Dt * 2 || o > 1 && e.chance(0.15)) return;
|
|
316
|
+
const c = e.int(Dt, n - Dt);
|
|
317
|
+
t.a = s ? { x: t.x, y: t.y, w: t.w, h: c } : { x: t.x, y: t.y, w: c, h: t.h }, t.b = s ? { x: t.x, y: t.y + c, w: t.w, h: t.h - c } : { x: t.x + c, y: t.y, w: t.w - c, h: t.h }, _t(t.a, e, o + 1), _t(t.b, e, o + 1);
|
|
318
|
+
}
|
|
319
|
+
const Lt = (t) => t.a && t.b ? [...Lt(t.a), ...Lt(t.b)] : [t], St = (t) => ({ x: t.room.x + (t.room.w >> 1), y: t.room.y + (t.room.h >> 1) });
|
|
320
|
+
function At(t, e, o, s, n) {
|
|
321
|
+
for (let c = Math.min(o, n); c <= Math.max(o, n); c++) for (let a = Math.min(e, s); a <= Math.max(e, s); a++) t.cells[c * t.w + a] = Z;
|
|
322
|
+
}
|
|
323
|
+
function ie(t, e, o, s) {
|
|
324
|
+
s.chance(0.5) ? (At(t, e.x, e.y, o.x, e.y), At(t, o.x, e.y, o.x, o.y)) : (At(t, e.x, e.y, e.x, o.y), At(t, e.x, o.y, o.x, o.y));
|
|
325
|
+
}
|
|
326
|
+
const Jt = (t, e) => e.pick(Lt(t));
|
|
327
|
+
function Ut(t, e, o) {
|
|
328
|
+
!t.a || !t.b || (Ut(t.a, e, o), Ut(t.b, e, o), ie(e, St(Jt(t.a, o)), St(Jt(t.b, o)), o));
|
|
329
|
+
}
|
|
330
|
+
function ae(t, e, o, s) {
|
|
331
|
+
const n = pt(t, e, Q), c = { x: 1, y: 1, w: t - 2, h: e - 2 };
|
|
332
|
+
_t(c, o, 0);
|
|
333
|
+
const a = Lt(c);
|
|
334
|
+
for (const i of a) {
|
|
335
|
+
const r = o.int(Math.min(4, i.w - 3), i.w - 3), M = o.int(Math.min(4, i.h - 3), i.h - 3);
|
|
336
|
+
i.room = { x: i.x + 1 + o.int(0, i.w - 2 - r), y: i.y + 1 + o.int(0, i.h - 2 - M), w: r, h: M }, At(n, i.room.x, i.room.y, i.room.x + r - 1, i.room.y + M - 1);
|
|
337
|
+
}
|
|
338
|
+
Ut(c, n, o);
|
|
339
|
+
for (let i = 0; i < a.length >> 2; i++) ie(n, St(o.pick(a)), St(o.pick(a)), o);
|
|
340
|
+
const x = St(a[0]), y = x.y * t + x.x, h = ce(n, y);
|
|
341
|
+
let l = !1;
|
|
342
|
+
if (s)
|
|
343
|
+
for (const i of a) {
|
|
344
|
+
const r = i.room;
|
|
345
|
+
if (!(r.w * r.h < 20))
|
|
346
|
+
for (let M = o.int(1, 3); M > 0; M--) {
|
|
347
|
+
const T = r.x + o.int(0, r.w - 1), k = r.y + o.int(0, r.h - 1), b = k * t + T;
|
|
348
|
+
b === y || b === h || !Yt(n, T, k) || (n.cells[b] = ut, l = !0);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return { area: n, entry: y, exit: h, rooms: a.length, decorated: l };
|
|
352
|
+
}
|
|
353
|
+
function Ae(t) {
|
|
354
|
+
const { w: e, h: o, cells: s } = t, n = s.slice();
|
|
355
|
+
for (let c = 0; c < o; c++) {
|
|
356
|
+
const a = c > 0 && c < o - 1;
|
|
357
|
+
for (let x = 0; x < e; x++) {
|
|
358
|
+
let y = 0;
|
|
359
|
+
if (a && x > 0 && x < e - 1) {
|
|
360
|
+
const h = c * e + x;
|
|
361
|
+
y = +(s[h - e - 1] === J) + +(s[h - e] === J) + +(s[h - e + 1] === J) + +(s[h - 1] === J) + +(s[h + 1] === J) + +(s[h + e - 1] === J) + +(s[h + e] === J) + +(s[h + e + 1] === J);
|
|
362
|
+
} else
|
|
363
|
+
for (let h = -1; h <= 1; h++)
|
|
364
|
+
for (let l = -1; l <= 1; l++) {
|
|
365
|
+
if (!l && !h) continue;
|
|
366
|
+
const i = x + l, r = c + h;
|
|
367
|
+
(i < 0 || r < 0 || i >= e || r >= o || s[r * e + i] === J) && y++;
|
|
368
|
+
}
|
|
369
|
+
n[c * e + x] = y >= 4 ? J : Z;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
s.set(n);
|
|
373
|
+
}
|
|
374
|
+
function Se(t) {
|
|
375
|
+
const { w: e, h: o, cells: s } = t, n = new Int32Array(s.length).fill(-1), c = new Int32Array(s.length);
|
|
376
|
+
let a = -1, x = 0, y = 0;
|
|
377
|
+
for (let h = 0; h < s.length; h++) {
|
|
378
|
+
if (tt(s[h]) || n[h] >= 0) continue;
|
|
379
|
+
let l = 0, i = 0;
|
|
380
|
+
for (c[i++] = h, n[h] = y; l < i; ) {
|
|
381
|
+
const r = c[l++], M = r % e, T = r / e | 0;
|
|
382
|
+
M + 1 < e && n[r + 1] < 0 && !tt(s[r + 1]) && (n[r + 1] = y, c[i++] = r + 1), M > 0 && n[r - 1] < 0 && !tt(s[r - 1]) && (n[r - 1] = y, c[i++] = r - 1), T + 1 < o && n[r + e] < 0 && !tt(s[r + e]) && (n[r + e] = y, c[i++] = r + e), T > 0 && n[r - e] < 0 && !tt(s[r - e]) && (n[r - e] = y, c[i++] = r - e);
|
|
383
|
+
}
|
|
384
|
+
i > x && (a = y, x = i), y++;
|
|
385
|
+
}
|
|
386
|
+
for (let h = 0; h < s.length; h++) !tt(s[h]) && n[h] !== a && (s[h] = J);
|
|
387
|
+
return x;
|
|
388
|
+
}
|
|
389
|
+
function fe(t, e, o, s) {
|
|
390
|
+
const n = new Float64Array(t.cells.length).fill(1 / 0), c = new Int32Array(t.cells.length).fill(-1), a = [[0, e]];
|
|
391
|
+
n[e] = 0;
|
|
392
|
+
const x = (l) => {
|
|
393
|
+
a.push(l);
|
|
394
|
+
let i = a.length - 1;
|
|
395
|
+
for (; i > 0; ) {
|
|
396
|
+
const r = i - 1 >> 1;
|
|
397
|
+
if (a[r][0] <= a[i][0]) break;
|
|
398
|
+
[a[r], a[i]] = [a[i], a[r]], i = r;
|
|
399
|
+
}
|
|
400
|
+
}, y = () => {
|
|
401
|
+
const l = a[0], i = a.pop();
|
|
402
|
+
if (a.length) {
|
|
403
|
+
a[0] = i;
|
|
404
|
+
let r = 0;
|
|
405
|
+
for (; ; ) {
|
|
406
|
+
const M = 2 * r + 1, T = M + 1;
|
|
407
|
+
let k = r;
|
|
408
|
+
if (M < a.length && a[M][0] < a[k][0] && (k = M), T < a.length && a[T][0] < a[k][0] && (k = T), k === r) break;
|
|
409
|
+
[a[k], a[r]] = [a[r], a[k]], r = k;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return l;
|
|
413
|
+
};
|
|
414
|
+
for (; a.length; ) {
|
|
415
|
+
const [l, i] = y();
|
|
416
|
+
if (l > n[i]) continue;
|
|
417
|
+
if (i === o) break;
|
|
418
|
+
const r = i % t.w, M = i / t.w | 0;
|
|
419
|
+
for (const [T, k] of [
|
|
420
|
+
[1, 0],
|
|
421
|
+
[-1, 0],
|
|
422
|
+
[0, 1],
|
|
423
|
+
[0, -1]
|
|
424
|
+
]) {
|
|
425
|
+
const b = r + T, C = M + k;
|
|
426
|
+
if (b < 0 || C < 0 || b >= t.w || C >= t.h) continue;
|
|
427
|
+
const p = C * t.w + b;
|
|
428
|
+
if (tt(t.cells[p])) continue;
|
|
429
|
+
const f = l + s[p];
|
|
430
|
+
f < n[p] && (n[p] = f, c[p] = i, x([f, p]));
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
const h = [];
|
|
434
|
+
for (let l = o; l >= 0; l = c[l]) h.push(l);
|
|
435
|
+
return h.reverse();
|
|
436
|
+
}
|
|
437
|
+
function Ee(t, e, o, s) {
|
|
438
|
+
const n = pt(t, e, J);
|
|
439
|
+
let c = 0;
|
|
440
|
+
for (let h = 0; h < 6 && c < t * e * 0.22; h++) {
|
|
441
|
+
const l = 0.5 - h * 0.03;
|
|
442
|
+
for (let i = 0; i < n.cells.length; i++) n.cells[i] = o.chance(l) ? J : Z;
|
|
443
|
+
for (let i = 0; i < 4; i++) Ae(n);
|
|
444
|
+
for (let i = o.int(2, 4); i > 0; i--) {
|
|
445
|
+
const r = o.int(3, 5), M = o.int(r, Math.max(r, t - 1 - r)), T = o.int(r, Math.max(r, e - 1 - r));
|
|
446
|
+
for (let k = T - r; k <= T + r; k++)
|
|
447
|
+
for (let b = M - r; b <= M + r; b++)
|
|
448
|
+
b >= 0 && k >= 0 && b < t && k < e && (b - M) ** 2 + (k - T) ** 2 <= r * r && (n.cells[k * t + b] = Z);
|
|
449
|
+
}
|
|
450
|
+
c = Se(n);
|
|
451
|
+
}
|
|
452
|
+
let a = n.cells.findIndex((h) => !tt(h));
|
|
453
|
+
for (let h = 0; h < n.cells.length; h++) !tt(n.cells[h]) && h % t < a % t && (a = h);
|
|
454
|
+
const x = ce(n, a);
|
|
455
|
+
let y = !1;
|
|
456
|
+
if (s.path && a !== x) {
|
|
457
|
+
const h = new Float32Array(n.cells.length);
|
|
458
|
+
for (let l = 0; l < h.length; l++) h[l] = 1 + o.next() * 4;
|
|
459
|
+
for (const l of fe(n, a, x, h)) n.cells[l] = ct;
|
|
460
|
+
y = !0;
|
|
461
|
+
}
|
|
462
|
+
for (let h = 0; h < e; h++)
|
|
463
|
+
for (let l = 0; l < t; l++) {
|
|
464
|
+
const i = h * t + l;
|
|
465
|
+
n.cells[i] !== Z || i === a || i === x || !Yt(n, l, h) || (s.rock && o.chance(0.02) ? n.cells[i] = Et : s.decor && o.chance(0.05) && (n.cells[i] = ut));
|
|
466
|
+
}
|
|
467
|
+
return { area: n, entry: a, exit: x, open: c, trail: y };
|
|
468
|
+
}
|
|
469
|
+
const Ct = { N: [0, -1], E: [1, 0], S: [0, 1], W: [-1, 0] }, Tt = { N: "S", E: "W", S: "N", W: "E" };
|
|
470
|
+
function Oe(t, e, o, s, n) {
|
|
471
|
+
const c = [], a = /* @__PURE__ */ new Set(), x = (p, f) => f * t.w + p, y = (p) => t.cells[p] === Z && !n.has(p), h = (p) => p.map((f) => [s.next(), f]).sort((f, w) => f[0] - w[0]).map((f) => f[1]), l = (p, f, w) => f >= p.x && f < p.x + p.w && w >= p.y && w < p.y + p.h;
|
|
472
|
+
function i(p) {
|
|
473
|
+
const f = st(t, e);
|
|
474
|
+
for (let w = 0; w < f.length; w++) if (!tt(t.cells[w]) && f[w] < 0) return !1;
|
|
475
|
+
return [...c, ...p].every((w) => {
|
|
476
|
+
if (w.open) return !0;
|
|
477
|
+
const L = w.cell % t.w, P = w.cell / t.w | 0;
|
|
478
|
+
return Object.values(Ct).some(([z, E]) => {
|
|
479
|
+
const U = L + z, N = P + E;
|
|
480
|
+
return U >= 0 && N >= 0 && U < t.w && N < t.h && f[x(U, N)] >= 0;
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
function r(p) {
|
|
485
|
+
if (new Set(p.map((f) => f.cell)).size !== p.length || !p.every((f) => y(f.cell))) return !1;
|
|
486
|
+
for (const f of p) t.cells[f.cell] = le;
|
|
487
|
+
if (i(p))
|
|
488
|
+
return c.push(...p), !0;
|
|
489
|
+
for (const f of p) t.cells[f.cell] = Z;
|
|
490
|
+
return !1;
|
|
491
|
+
}
|
|
492
|
+
const M = (p, f) => !!o[p]?.includes(f);
|
|
493
|
+
function T(p, f, w, L = ["N", "E", "S", "W"]) {
|
|
494
|
+
if (!o[f]?.length) return !1;
|
|
495
|
+
const P = h(L).filter((z) => M(f, Tt[z]) || !["bed", "counter", "shelf", "stove", "chair"].includes(f));
|
|
496
|
+
P.length || a.add(f);
|
|
497
|
+
for (let z = 0; z < 14 && P.length; z++) {
|
|
498
|
+
const E = P[z % P.length], U = E === "N" || E === "S", N = U ? p.w : p.h, m = s.int(0, Math.max(0, N - w)), R = [];
|
|
499
|
+
for (let F = 0; F < w; F++) {
|
|
500
|
+
const B = m + F, v = U ? p.x + B : E === "W" ? p.x : p.x + p.w - 1, u = U ? E === "N" ? p.y : p.y + p.h - 1 : p.y + B;
|
|
501
|
+
if (!l(p, v, u)) break;
|
|
502
|
+
R.push({ cell: x(v, u), role: f, facing: Tt[E] });
|
|
503
|
+
}
|
|
504
|
+
if (R.length === w && r(R)) return !0;
|
|
505
|
+
}
|
|
506
|
+
return !1;
|
|
507
|
+
}
|
|
508
|
+
function k(p, f, w) {
|
|
509
|
+
if (o.table?.length)
|
|
510
|
+
for (let L = 0; L < 30; L++) {
|
|
511
|
+
const P = s.chance(0.6), z = P ? w : 1, E = P ? 1 : w;
|
|
512
|
+
if (p.w < z + 2 || p.h < E + 2) continue;
|
|
513
|
+
const U = s.int(p.x + 1, p.x + p.w - z - 1), N = s.int(p.y + 1, p.y + p.h - E - 1), m = [];
|
|
514
|
+
let R = !0;
|
|
515
|
+
for (let F = N - 1; F <= N + E; F++)
|
|
516
|
+
for (let B = U - 1; B <= U + z; B++) {
|
|
517
|
+
const v = x(B, F);
|
|
518
|
+
B >= U && B < U + z && F >= N && F < N + E ? m.push(v) : (!l(p, B, F) || t.cells[v] !== Z || n.has(v)) && (R = !1);
|
|
519
|
+
}
|
|
520
|
+
if (!(!R || !m.every(y)) && r(m.map((F) => ({ cell: F, role: "table" })))) {
|
|
521
|
+
if (f)
|
|
522
|
+
if (o.chair?.length) {
|
|
523
|
+
const F = [];
|
|
524
|
+
for (const v of m) {
|
|
525
|
+
const u = v % t.w, d = v / t.w | 0;
|
|
526
|
+
for (const g of ["N", "E", "S", "W"]) {
|
|
527
|
+
const [A, $] = Ct[g], I = x(u + A, d + $);
|
|
528
|
+
!m.includes(I) && M("chair", Tt[g]) && F.push({ cell: I, role: "chair", facing: Tt[g] });
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
let B = s.int(1, Math.min(4, Math.max(1, F.length)));
|
|
532
|
+
for (const v of h(F)) B > 0 && r([v]) && B--;
|
|
533
|
+
} else o.chair && a.add("chair");
|
|
534
|
+
return m;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
function b(p, f) {
|
|
539
|
+
return o[f]?.length ? h([x(p.x, p.y), x(p.x + p.w - 1, p.y), x(p.x, p.y + p.h - 1), x(p.x + p.w - 1, p.y + p.h - 1)]).some((L) => r([{ cell: L, role: f, facing: "S" }])) : !1;
|
|
540
|
+
}
|
|
541
|
+
function C(p) {
|
|
542
|
+
if (o.rug?.length)
|
|
543
|
+
for (const f of p) t.cells[f] === Z && !c.some((w) => w.cell === f) && c.push({ cell: f, role: "rug", open: !0 });
|
|
544
|
+
}
|
|
545
|
+
return { items: c, skipped: a, commit: r, against: T, table: k, corner: b, rug: C, free: y, at: x, shuffle: h };
|
|
546
|
+
}
|
|
547
|
+
function Re(t, e, o, s, n) {
|
|
548
|
+
const c = pt(t, e, Q), a = Math.min(t, s === "home" ? 24 : 26), x = Math.min(e, s === "home" ? 16 : 14), y = t - a >> 1, h = e - x >> 1, l = { x: y + 1, y: h + 1, w: a - 2, h: x - 2 }, i = (w, L) => L * t + w;
|
|
549
|
+
for (let w = l.y; w < l.y + l.h; w++) for (let L = l.x; L < l.x + l.w; L++) c.cells[i(L, w)] = Z;
|
|
550
|
+
const r = Math.max(l.x + 1, Math.min(l.x + l.w - 3, l.x + (l.w >> 1) + o.int(-2, 2))), M = h + x - 1;
|
|
551
|
+
c.cells[i(r, M)] = dt;
|
|
552
|
+
const T = i(r, M - 1), k = /* @__PURE__ */ new Set(), b = (w) => {
|
|
553
|
+
for (let L = 1; L <= w; L++) for (const P of [r, r + 1]) k.add(i(P, M - L));
|
|
554
|
+
}, C = Oe(c, T, n, o, k), p = [l];
|
|
555
|
+
let f;
|
|
556
|
+
if (s === "home") {
|
|
557
|
+
if (b(4), l.w >= 13 && o.chance(0.75)) {
|
|
558
|
+
const E = o.int(l.x + 5, l.x + l.w - 6);
|
|
559
|
+
if (Math.abs(E - r - 0.5) > 3) {
|
|
560
|
+
const U = o.int(l.y + 1, l.y + l.h - 4);
|
|
561
|
+
for (let N = l.y; N < l.y + l.h; N++) c.cells[i(E, N)] = N === U || N === U + 1 ? Z : Q;
|
|
562
|
+
for (const N of [U, U + 1]) for (const m of [E - 1, E, E + 1]) k.add(i(m, N));
|
|
563
|
+
p.splice(0, 1, { x: l.x, y: l.y, w: E - l.x, h: l.h }, { x: E + 1, y: l.y, w: l.x + l.w - E - 1, h: l.h });
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
const w = p.find((E) => !(r >= E.x && r < E.x + E.w));
|
|
567
|
+
if (w && w.w >= 6 && w.h >= 10 && o.chance(0.5)) {
|
|
568
|
+
const E = o.int(w.y + 4, w.y + w.h - 5), U = o.int(w.x + 1, w.x + w.w - 3);
|
|
569
|
+
for (let N = w.x; N < w.x + w.w; N++) c.cells[i(N, E)] = N === U || N === U + 1 ? Z : Q;
|
|
570
|
+
for (const N of [U, U + 1]) for (const m of [E - 1, E, E + 1]) k.add(i(N, m));
|
|
571
|
+
p.splice(p.indexOf(w), 1, { ...w, h: E - w.y }, { x: w.x, y: E + 1, w: w.w, h: w.y + w.h - E - 1 });
|
|
572
|
+
}
|
|
573
|
+
const L = p.find((E) => r >= E.x && r < E.x + E.w), P = C.table(L, !0, o.int(2, 3)) ?? [];
|
|
574
|
+
C.against(L, "stove", 1), C.against(L, "shelf", o.int(1, 2)), C.corner(L, "plant"), C.against(L, "lamp", 1), p.length === 1 && C.against(L, "bed", 2);
|
|
575
|
+
const z = [];
|
|
576
|
+
for (const E of P) for (let U = -1; U <= 1; U++) for (let N = -1; N <= 1; N++) z.push(E + U * t + N);
|
|
577
|
+
C.rug(z.filter((E) => E >= 0 && E < c.cells.length));
|
|
578
|
+
for (const E of p)
|
|
579
|
+
if (E !== L) {
|
|
580
|
+
for (let U = o.int(1, 2); U > 0; U--) C.against(E, "bed", 2);
|
|
581
|
+
o.chance(0.6) && C.against(E, "shelf", o.int(1, 2)), C.against(E, "lamp", 1), C.corner(E, "plant");
|
|
582
|
+
}
|
|
583
|
+
} else {
|
|
584
|
+
const w = l.y + Math.max(3, Math.floor(l.h * 0.4));
|
|
585
|
+
for (let N = w + 1; N < M; N++) for (const m of [r, r + 1]) k.add(i(m, N));
|
|
586
|
+
const P = r - l.x > l.x + l.w - r - 2 ? [l.x, l.x + 1] : [l.x + l.w - 2, l.x + l.w - 1], z = !!n.counter?.includes("S");
|
|
587
|
+
if (n.counter?.length && !z && C.skipped.add("counter"), z) {
|
|
588
|
+
const N = [];
|
|
589
|
+
for (let R = l.x; R < l.x + l.w; R++) P.includes(R) || N.push({ cell: i(R, w), role: "counter", facing: "S" });
|
|
590
|
+
const m = l.x + (l.w >> 1);
|
|
591
|
+
f = i(m, w - 1), k.add(f), C.commit(N);
|
|
592
|
+
}
|
|
593
|
+
const E = l.y;
|
|
594
|
+
for (let N = l.x; N < l.x + l.w; N++)
|
|
595
|
+
o.chance(0.25) || C.against({ x: N, y: E, w: 1, h: 1 }, "shelf", 1, ["N"]);
|
|
596
|
+
const U = { x: l.x, y: w + 1, w: l.w, h: M - w - 1 };
|
|
597
|
+
C.against(U, "shelf", o.int(1, 2), ["W", "E"]), C.table(U, !1, o.int(1, 2)), C.corner(U, "plant"), C.against(U, "lamp", 1, ["W", "E"]), C.rug([r, r + 1].flatMap((N) => [i(N, M - 1), i(N, M - 2)]));
|
|
598
|
+
}
|
|
599
|
+
return { area: c, entry: T, exit: i(r, M), items: C.items, shopkeeper: f, skipped: [...C.skipped] };
|
|
600
|
+
}
|
|
601
|
+
const mt = 5;
|
|
602
|
+
function Te(t, e, o, s) {
|
|
603
|
+
const n = pt(t, e, Q), c = (f, w) => w * t + f;
|
|
604
|
+
for (let f = 2; f < e - 2; f++) for (let w = 2; w < t - 2; w++) n.cells[c(w, f)] = Z;
|
|
605
|
+
for (const [f, w] of [
|
|
606
|
+
[0, 0],
|
|
607
|
+
[t - mt, 0],
|
|
608
|
+
[0, e - mt],
|
|
609
|
+
[t - mt, e - mt]
|
|
610
|
+
]) {
|
|
611
|
+
for (let P = w; P < w + mt; P++) for (let z = f; z < f + mt; z++) n.cells[c(z, P)] = Q;
|
|
612
|
+
for (let P = w + 1; P <= w + 3; P++) for (let z = f + 1; z <= f + 3; z++) n.cells[c(z, P)] = Z;
|
|
613
|
+
const L = f === 0;
|
|
614
|
+
n.cells[c(L ? f + 4 : f, w + 2)] = Z, n.cells[c(L ? f + 5 : f - 1, w + 2)] = Z;
|
|
615
|
+
}
|
|
616
|
+
const a = (t >> 1) - 1;
|
|
617
|
+
for (const f of [a, a + 1])
|
|
618
|
+
n.cells[c(f, e - 1)] = dt, n.cells[c(f, e - 2)] = Z;
|
|
619
|
+
const x = c(a, e - 3), y = t - 4, h = e - 4, l = Math.min(Math.max(12, Math.round(y * 0.6)), y - 6), i = Math.min(Math.max(12, Math.round(h * 0.62)), h - 6), r = 2 + (y - l >> 1), M = 3, T = ae(l, i, o, s.decorate);
|
|
620
|
+
for (let f = 0; f < i; f++) for (let w = 0; w < l; w++) n.cells[c(r + w, M + f)] = T.area.cells[f * l + w];
|
|
621
|
+
const k = r + (l >> 1) + o.int(-2, 2), b = M + i - 1;
|
|
622
|
+
n.cells[c(k, b)] = dt;
|
|
623
|
+
for (let f = b - 1; f > M && n.cells[c(k, f)] === Q; f--) n.cells[c(k, f)] = Z;
|
|
624
|
+
if (s.path) {
|
|
625
|
+
for (let f = e - 3; f >= b + 1; f--) n.cells[c(a, f)] = ct;
|
|
626
|
+
for (let f = Math.min(a, k); f <= Math.max(a, k); f++) n.cells[c(f, b + 1)] = ct;
|
|
627
|
+
}
|
|
628
|
+
if (s.decorate)
|
|
629
|
+
for (let f = o.int(4, 8); f > 0; f--) {
|
|
630
|
+
const w = o.int(3, t - 4), L = o.int(b + 2, e - 5), P = c(w, L);
|
|
631
|
+
n.cells[P] === Z && Yt(n, w, L) && Math.abs(w - a) > 2 && (n.cells[P] = ut);
|
|
632
|
+
}
|
|
633
|
+
const C = st(n, x);
|
|
634
|
+
let p = c(k, b);
|
|
635
|
+
for (let f = M; f < M + i; f++) for (let w = r; w < r + l; w++) C[c(w, f)] > C[p] && (p = c(w, f));
|
|
636
|
+
return { area: n, entry: x, exit: p };
|
|
637
|
+
}
|
|
638
|
+
function Ie(t, e, o, s) {
|
|
639
|
+
const n = pt(t, e, Z), c = (m, R) => R * t + m, a = (m, R, F) => m >= 0 && R >= 0 && m < t && R < e && (n.cells[c(m, R)] = F), x = e >> 1, y = Math.max(5, x - (e >> 3)), h = Math.min(e - 6, x + (e >> 3)), l = [];
|
|
640
|
+
let i = x;
|
|
641
|
+
for (let m = 0; m < t; m++)
|
|
642
|
+
m % 4 === 3 && (i = Math.min(h, Math.max(y, i + o.int(-1, 1)))), l.push(i);
|
|
643
|
+
const r = new Uint8Array(t * e), M = (m, R, F) => {
|
|
644
|
+
for (let B = -F; B <= F; B++)
|
|
645
|
+
for (let v = -F; v <= F; v++) m + v >= 0 && R + B >= 0 && m + v < t && R + B < e && (r[c(m + v, R + B)] = 1);
|
|
646
|
+
};
|
|
647
|
+
if (s.tree)
|
|
648
|
+
for (let m = 0; m < t * e; m++) (m % t < 1 || m % t >= t - 1 || m < t || m >= t * (e - 1)) && (n.cells[m] = J);
|
|
649
|
+
const T = [], k = t >> 1;
|
|
650
|
+
T.push(k - 1);
|
|
651
|
+
for (let m = k - o.int(17, 21); m > 8; m -= o.int(20, 26)) T.push(m);
|
|
652
|
+
for (let m = k + o.int(17, 21); m < t - 9; m += o.int(20, 26)) T.push(m);
|
|
653
|
+
T.forEach((m, R) => {
|
|
654
|
+
const F = R % 2 === 0, B = o.int(0, 1) ? 0.4 : 0.6, v = o.chance(0.5) ? 1 : -1, u = o.int(3, 5);
|
|
655
|
+
for (let d = 0; d <= 1; d++) {
|
|
656
|
+
const g = l[Math.min(t - 1, m + d)], A = F ? [u, g] : [g, e - 1 - u];
|
|
657
|
+
for (let $ = A[0]; $ <= A[1]; $++) {
|
|
658
|
+
const I = m + d + (Math.abs($ - g) > B * (A[1] - A[0]) ? v : 0);
|
|
659
|
+
a(I, $, ct), M(I, $, 1);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
for (let m = 0; m < t; m++)
|
|
664
|
+
for (let R = -1; R <= 1; R++)
|
|
665
|
+
a(m, l[m] + R, ct), M(m, l[m] + R, 1);
|
|
666
|
+
const b = [];
|
|
667
|
+
a(0, l[0], dt), a(t - 1, l[t - 1], dt), b.push({ cell: c(0, l[0]), kind: "overworld", label: "West gate" }, { cell: c(t - 1, l[t - 1]), kind: "overworld", label: "East gate" });
|
|
668
|
+
const C = k - 1, p = l[k];
|
|
669
|
+
for (let m = p - 3; m <= p + 3; m++)
|
|
670
|
+
for (let R = C - 4; R <= C + 5; R++)
|
|
671
|
+
a(R, m, ct), M(R, m, 1);
|
|
672
|
+
s.decor && (a(C + 0, p, ut), a(C + 1, p, ut));
|
|
673
|
+
const f = [];
|
|
674
|
+
for (const m of [!0, !1])
|
|
675
|
+
for (let R = 2; R < t - 8; ) {
|
|
676
|
+
const F = o.int(5, 7), B = o.int(4, 5);
|
|
677
|
+
let v = m ? e : 0;
|
|
678
|
+
for (let I = 0; I < F; I++) v = m ? Math.min(v, l[R + I] - 2) : Math.max(v, l[R + I] + 2);
|
|
679
|
+
const u = m ? v - 2 : v + 2, d = m ? u - B + 1 : u;
|
|
680
|
+
let g = d >= 2 && d + B <= e - 2;
|
|
681
|
+
for (let I = d - 1; g && I <= d + B; I++)
|
|
682
|
+
for (let W = R - 1; W <= R + F; W++) (W < 1 || W >= t - 1 || r[c(W, I)] || n.cells[c(W, I)] !== Z) && (g = !1);
|
|
683
|
+
if (!g) {
|
|
684
|
+
R += 1;
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
for (let I = d; I < d + B; I++) for (let W = R; W < R + F; W++) a(W, I, I < d + 2 ? bt : Q);
|
|
688
|
+
const A = R + (F >> 1), $ = m ? d + B - 1 : d;
|
|
689
|
+
if (a(A, $, dt), m) for (let I = $ + 1; I <= l[A] - 1; I++) a(A, I, ct);
|
|
690
|
+
else for (let I = $ - 1; I >= l[A] + 1; I--) a(A, I, ct);
|
|
691
|
+
M(R, d, 0);
|
|
692
|
+
for (let I = d; I < d + B; I++) for (let W = R; W < R + F; W++) r[c(W, I)] = 1;
|
|
693
|
+
f.push({ cell: c(A, $), d: Math.abs(A - C) }), R += F + o.int(1, 2);
|
|
694
|
+
}
|
|
695
|
+
const w = f.slice().sort((m, R) => m.d - R.d || m.cell - R.cell), L = new Set(w.slice(0, Math.min(3, Math.floor(f.length / 3))).map((m) => m.cell));
|
|
696
|
+
let P = 0, z = 0;
|
|
697
|
+
for (const m of f.slice().sort((R, F) => R.cell - F.cell))
|
|
698
|
+
b.push(L.has(m.cell) ? { cell: m.cell, kind: "shop", label: `Shop ${++z}` } : { cell: m.cell, kind: "home", label: `Home ${++P}` });
|
|
699
|
+
for (let m = 2; m < e - 2; m++)
|
|
700
|
+
for (let R = 2; R < t - 2; R++) {
|
|
701
|
+
const F = c(R, m);
|
|
702
|
+
n.cells[F] !== Z || r[F] || (s.tree && o.chance(0.03) ? n.cells[F] = J : s.decor && o.chance(0.05) && (n.cells[F] = ut));
|
|
703
|
+
}
|
|
704
|
+
const E = c(1, l[1]), U = c(t - 2, l[t - 2]), N = st(n, E);
|
|
705
|
+
for (let m = 0; m < N.length; m++) !tt(n.cells[m]) && N[m] < 0 && (n.cells[m] = s.tree ? J : Q);
|
|
706
|
+
return { area: n, entry: E, exit: U, links: b };
|
|
707
|
+
}
|
|
708
|
+
const Qt = (t) => t * t * (3 - 2 * t);
|
|
709
|
+
function It(t, e, o, s, n) {
|
|
710
|
+
const c = n ? Math.max(2, Math.round(t / s)) : Math.ceil(t / s) + 1, a = n ? Math.max(2, Math.round(e / s)) : Math.ceil(e / s) + 1, x = Array.from({ length: c * a }, () => o.next()), y = new Float32Array(t * e), h = n ? c / t : 1 / s, l = n ? a / e : 1 / s;
|
|
711
|
+
for (let i = 0; i < e; i++)
|
|
712
|
+
for (let r = 0; r < t; r++) {
|
|
713
|
+
const M = r * h, T = i * l, k = Math.floor(M), b = Math.floor(T), C = Qt(M - k), p = Qt(T - b), f = (P, z) => x[z % a * c + P % c], w = f(k, b) + (f(k + 1, b) - f(k, b)) * C, L = f(k, b + 1) + (f(k + 1, b + 1) - f(k, b + 1)) * C;
|
|
714
|
+
y[i * t + r] = w + (L - w) * p;
|
|
715
|
+
}
|
|
716
|
+
return y;
|
|
717
|
+
}
|
|
718
|
+
const Ft = (t, e) => [...t].sort((o, s) => o - s)[Math.floor(t.length * e)];
|
|
719
|
+
function Le(t, e, o, s) {
|
|
720
|
+
const n = pt(t, e, Z), c = (v, u) => u * t + v, a = It(t, e, o, 16, s.wrap), x = It(t, e, o, 8, s.wrap), y = It(t, e, o, 4, s.wrap), h = a.map((v, u) => v * 0.6 + x[u] * 0.3 + y[u] * 0.1), l = It(t, e, o, 12, s.wrap), i = Ft(h, 0.24), r = Ft(h, 0.93), M = Ft(l, 0.66);
|
|
721
|
+
for (let v = 0; v < t * e; v++)
|
|
722
|
+
h[v] < i ? n.cells[v] = it : s.rock && h[v] > r ? n.cells[v] = Et : s.tree && l[v] > M ? n.cells[v] = J : s.decor && o.chance(0.04) && (n.cells[v] = ut);
|
|
723
|
+
const T = (v) => v !== it, k = new Int32Array(t * e).fill(-1);
|
|
724
|
+
let b = -1, C = 0, p = 0;
|
|
725
|
+
for (let v = 0; v < t * e; v++) {
|
|
726
|
+
if (!T(n.cells[v]) || k[v] >= 0) continue;
|
|
727
|
+
const u = [v];
|
|
728
|
+
k[v] = p;
|
|
729
|
+
let d = 0;
|
|
730
|
+
for (; u.length; ) {
|
|
731
|
+
const g = u.pop();
|
|
732
|
+
d++;
|
|
733
|
+
const A = g % t, $ = g / t | 0;
|
|
734
|
+
for (const [I, W] of [
|
|
735
|
+
[1, 0],
|
|
736
|
+
[-1, 0],
|
|
737
|
+
[0, 1],
|
|
738
|
+
[0, -1]
|
|
739
|
+
]) {
|
|
740
|
+
const q = A + I, O = $ + W;
|
|
741
|
+
if (q < 0 || O < 0 || q >= t || O >= e) continue;
|
|
742
|
+
const _ = c(q, O);
|
|
743
|
+
k[_] < 0 && T(n.cells[_]) && (k[_] = p, u.push(_));
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
d > C && (b = p, C = d), p++;
|
|
747
|
+
}
|
|
748
|
+
for (let v = 0; v < t * e; v++) T(n.cells[v]) && k[v] !== b && (n.cells[v] = it);
|
|
749
|
+
const f = ["town", "dungeon", "castle", "town", "dungeon"], w = t * e >= 3600 ? 5 : 4, L = [], P = Math.max(10, Math.floor(Math.min(t, e) / 4));
|
|
750
|
+
for (let v = 0; v < 4e3 && L.length < w; v++) {
|
|
751
|
+
const u = o.int(3, t - 4), d = o.int(3, e - 4);
|
|
752
|
+
let g = !0;
|
|
753
|
+
for (let A = -2; A <= 2 && g; A++) for (let $ = -2; $ <= 2; $++) n.cells[c(u + $, d + A)] === it && (g = !1);
|
|
754
|
+
g && L.every((A) => Math.abs(A % t - u) + Math.abs((A / t | 0) - d) >= P) && L.push(c(u, d));
|
|
755
|
+
}
|
|
756
|
+
L.sort((v, u) => v % t - u % t);
|
|
757
|
+
for (const v of L) {
|
|
758
|
+
const u = v % t, d = v / t | 0;
|
|
759
|
+
for (let g = -1; g <= 1; g++) for (let A = -1; A <= 1; A++) n.cells[c(u + A, d + g)] = Z;
|
|
760
|
+
}
|
|
761
|
+
const z = { w: t, h: e, cells: n.cells.map((v) => v === it ? it : Z) }, E = new Float32Array(t * e);
|
|
762
|
+
for (let v = 0; v < E.length; v++) E[v] = n.cells[v] === Et ? 14 : n.cells[v] === J ? 4 : 1 + o.next() * 0.6;
|
|
763
|
+
const U = L.length ? [L[0]] : [];
|
|
764
|
+
for (const v of L.slice(1)) {
|
|
765
|
+
const u = U.reduce(
|
|
766
|
+
(d, g) => Math.abs(d % t - v % t) + Math.abs((d / t | 0) - (v / t | 0)) <= Math.abs(g % t - v % t) + Math.abs((g / t | 0) - (v / t | 0)) ? d : g
|
|
767
|
+
);
|
|
768
|
+
for (const d of fe(z, u, v, E))
|
|
769
|
+
n.cells[d] = ct, E[d] = 0.2;
|
|
770
|
+
U.push(v);
|
|
771
|
+
}
|
|
772
|
+
const N = [], m = {};
|
|
773
|
+
L.forEach((v, u) => {
|
|
774
|
+
n.cells[v] = dt;
|
|
775
|
+
const d = f[u % f.length];
|
|
776
|
+
m[d] = (m[d] ?? 0) + 1, N.push({ cell: v, kind: d, label: `${d[0].toUpperCase()}${d.slice(1)} ${m[d]}` });
|
|
777
|
+
});
|
|
778
|
+
const R = L.length ? L[0] + t : c(t >> 1, e >> 1), F = st(n, R);
|
|
779
|
+
for (let v = 0; v < F.length; v++) !tt(n.cells[v]) && F[v] < 0 && (n.cells[v] = it);
|
|
780
|
+
const B = L.length > 1 ? L[L.length - 1] : R;
|
|
781
|
+
return { area: n, entry: R, exit: B, links: N };
|
|
782
|
+
}
|
|
783
|
+
const te = (t) => Math.max(1, t);
|
|
784
|
+
function Ce(t) {
|
|
785
|
+
let e, o, s = !1, n, c, a;
|
|
786
|
+
const x = (i) => i >> 8;
|
|
787
|
+
for (let i = 5; i < xe; i++) {
|
|
788
|
+
const r = t.sequences[i];
|
|
789
|
+
if (!r.key && !r.jstkMov) continue;
|
|
790
|
+
const M = r.frames.findIndex((p) => p.pic2 === pe + 1), T = r.frames.slice(0, M < 0 ? r.frames.length : M);
|
|
791
|
+
if (!T.length) continue;
|
|
792
|
+
const k = T.reduce((p, f) => p + f.x, 0), b = T.reduce((p, f) => p + f.y, 0), C = T.reduce((p, f) => p + te(f.pause), 0);
|
|
793
|
+
if (r.momentum && b < 0 && !o) {
|
|
794
|
+
const p = [];
|
|
795
|
+
let f = 0;
|
|
796
|
+
for (const w of T)
|
|
797
|
+
p[f] = (p[f] ?? 0) + w.y, f += te(w.pause);
|
|
798
|
+
o = { push: p, ground: !!r.ground, key: x(r.key) };
|
|
799
|
+
} else !r.momentum && k > 0 && b === 0 && !e ? e = { dx: k, ticks: C, key: x(r.key) } : !r.momentum && k < 0 && b === 0 && n === void 0 ? n = r.key ? x(r.key) : void 0 : !r.momentum && b < 0 && k === 0 ? (s = !0, c ??= r.key ? x(r.key) : void 0) : !r.momentum && b > 0 && k === 0 && (a ??= r.key ? x(r.key) : void 0);
|
|
800
|
+
}
|
|
801
|
+
if (!e) return { ok: !1, message: "The hero has no walking sequence to the right, so there is nothing to measure a side view by." };
|
|
802
|
+
if (!o) return { ok: !1, message: "The hero has no jump (a sequence that pushes him up as momentum), so a side view cannot be checked." };
|
|
803
|
+
const y = {
|
|
804
|
+
vx: e.dx / e.ticks,
|
|
805
|
+
push: o.push,
|
|
806
|
+
steer: !o.ground,
|
|
807
|
+
climb: s,
|
|
808
|
+
rise: 0,
|
|
809
|
+
keys: { right: e.key, left: n, jump: o.key, up: c, down: a }
|
|
810
|
+
}, h = je(y, "jump", 0, 0);
|
|
811
|
+
let l = 0;
|
|
812
|
+
for (const i of h.dy) y.rise = Math.max(y.rise, l -= i);
|
|
813
|
+
return y.rise < 10 ? { ok: !1, message: "The hero’s jump is too small to cross anything." } : { ok: !0, physics: y };
|
|
814
|
+
}
|
|
815
|
+
function Ve(t, e, o) {
|
|
816
|
+
return { ...t, vx: t.vx * e, push: t.push.map((s) => Math.round(s * o)), rise: t.rise * o * o };
|
|
817
|
+
}
|
|
818
|
+
const jt = 90;
|
|
819
|
+
class he {
|
|
820
|
+
constructor(e, o, s, n) {
|
|
821
|
+
this.p = e, this.kind = o, this.dir = s, this.steerTicks = n;
|
|
822
|
+
}
|
|
823
|
+
p;
|
|
824
|
+
kind;
|
|
825
|
+
dir;
|
|
826
|
+
steerTicks;
|
|
827
|
+
vy = 0;
|
|
828
|
+
t = 0;
|
|
829
|
+
step() {
|
|
830
|
+
const { p: e, t: o } = this;
|
|
831
|
+
return this.kind === "jump" && (this.vy += e.push[o] ?? 0), o % ye === 0 && (this.vy += 1), this.vy = Math.max(-gt * 4, Math.min(gt * 4, this.vy)), this.t++, {
|
|
832
|
+
dy: Math.max(-gt, Math.min(gt, this.vy)),
|
|
833
|
+
dx: this.dir && o >= 1 && o <= this.steerTicks && (e.steer || this.kind === "fall") ? Math.round(this.dir * e.vx) : 0
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* A block with no gravity holds him (engine/character.ts onGround): the tick he reaches it his speed fades to 5/6 once; after
|
|
838
|
+
* that `slide` moves him by his speed and fades it twice a tick (the ground check runs after the sideways move and again
|
|
839
|
+
* after the vertical one), while the walk key goes on steering him for its ticks.
|
|
840
|
+
*/
|
|
841
|
+
fade() {
|
|
842
|
+
this.vy = Math.trunc(this.vy * 5 / 6);
|
|
843
|
+
}
|
|
844
|
+
slide() {
|
|
845
|
+
const { p: e, t: o } = this, s = Math.max(-gt, Math.min(gt, this.vy)), n = this.dir && o >= 1 && o <= this.steerTicks && (e.steer || this.kind === "fall") ? Math.round(this.dir * e.vx) : 0;
|
|
846
|
+
return this.vy = Math.trunc(Math.trunc(this.vy * 5 / 6) * 5 / 6), this.t++, { dx: n, dy: s, done: this.vy === 0 && s === 0 && this.t > this.steerTicks };
|
|
847
|
+
}
|
|
848
|
+
/** He has landed (the ground check stopped his fall): his speed is gone, and the gravity clock runs on. */
|
|
849
|
+
land() {
|
|
850
|
+
this.vy = 0;
|
|
851
|
+
}
|
|
852
|
+
bump() {
|
|
853
|
+
this.vy < 0 && (this.vy = 0);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
function je(t, e, o, s) {
|
|
857
|
+
const n = new he(t, e, o, s), c = [], a = [];
|
|
858
|
+
for (let x = 0; x < jt; x++) {
|
|
859
|
+
const y = n.step();
|
|
860
|
+
c.push(y.dx), a.push(y.dy);
|
|
861
|
+
}
|
|
862
|
+
return { dx: c, dy: a };
|
|
863
|
+
}
|
|
864
|
+
function Ne() {
|
|
865
|
+
const t = [], e = [3, 6, 9, 12, 15, 18, 22, jt];
|
|
866
|
+
for (const o of ["jump", "fall"])
|
|
867
|
+
for (const s of [-1, 0, 1]) for (const n of s ? e : [0]) t.push({ kind: o, dir: s, steerTicks: n });
|
|
868
|
+
return t;
|
|
869
|
+
}
|
|
870
|
+
const nt = 0, Pt = 1, wt = 2, vt = 3;
|
|
871
|
+
function Ht(t, e, o, s, n = {}) {
|
|
872
|
+
const { goal: c } = n, { w: a, h: x } = t, y = new Uint8Array(a * x), h = new Uint8Array(a * x), l = (u, d) => u < 0 || u >= a || d >= x ? Q : d < 0 ? 255 : t.cells[d * a + u], i = (u) => u === Q || u === bt || u === Ot && !s, r = (u, d) => {
|
|
873
|
+
const g = Math.floor((d - j) / j), A = Math.floor((d + j - 1) / j);
|
|
874
|
+
let $ = nt;
|
|
875
|
+
for (let I = g; I <= A; I++)
|
|
876
|
+
for (let W = Math.floor(u / j); W <= Math.floor((u + j - 1) / j); W++) {
|
|
877
|
+
const q = l(W, I);
|
|
878
|
+
if (q === ht) return wt;
|
|
879
|
+
if (q === 255) return vt;
|
|
880
|
+
i(q) && ($ = Pt);
|
|
881
|
+
}
|
|
882
|
+
return $;
|
|
883
|
+
}, M = (u, d) => {
|
|
884
|
+
const g = Math.floor((d - j) / j), A = Math.floor((d + j - 1) / j);
|
|
885
|
+
for (let $ = g; $ <= A; $++) for (let I = Math.floor(u / j); I <= Math.floor((u + j - 1) / j); I++) if (l(I, $) === xt) return !0;
|
|
886
|
+
return !1;
|
|
887
|
+
}, T = (u, d) => {
|
|
888
|
+
const g = Math.floor((d - j) / j), A = Math.floor((d + j - 1) / j);
|
|
889
|
+
for (let $ = Math.max(0, g); $ <= Math.min(x - 1, A); $++)
|
|
890
|
+
for (let I = Math.floor(u / j); I <= Math.floor((u + j - 1) / j); I++) I >= 0 && I < a && (y[$ * a + I] = 1);
|
|
891
|
+
}, k = (u) => i(u) || u === xt, b = (u, d) => {
|
|
892
|
+
const g = Math.floor(u / j), A = u - g * j, $ = l(g, d + 1), I = A > 0 ? l(g + 1, d + 1) : nt, W = k($), q = k(I), O = $ === ht || I === ht;
|
|
893
|
+
return !W && !q ? { held: !1, x: u, spiked: O } : W && !q && A > j / 2 ? { held: !1, x: (g + 1) * j, spiked: O } : q && !W && A < j / 2 ? { held: !1, x: g * j, spiked: O } : { held: !0, x: u, spiked: O };
|
|
894
|
+
}, C = (u, d) => {
|
|
895
|
+
const g = Math.floor((u + j / 2) / j);
|
|
896
|
+
return l(g, d) === ft || l(g, d - 1) === ft;
|
|
897
|
+
}, p = (u, d) => {
|
|
898
|
+
const g = b(u, d);
|
|
899
|
+
return C(u, d) || g.held && !g.spiked;
|
|
900
|
+
}, f = Math.max(1, Math.round(e.vx)), w = (u, d) => {
|
|
901
|
+
const g = Math.floor((u + j / 2) / j);
|
|
902
|
+
if (g < 6 || g > a - 7 || d < 5 || d + 1 >= x) return !1;
|
|
903
|
+
for (let A = g - 5; A <= g + 5; A++) {
|
|
904
|
+
const $ = l(A, d + 1);
|
|
905
|
+
if (!(i($) || $ === xt)) return !1;
|
|
906
|
+
for (let I = d - 5; I <= d; I++) {
|
|
907
|
+
const W = l(A, I);
|
|
908
|
+
if (i(W) || W === ht || W === ft || W === xt) return !1;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
return !0;
|
|
912
|
+
}, L = a * j * x, P = new Uint8Array(L), z = (u, d) => d * a * j + u, E = [];
|
|
913
|
+
let U = !1;
|
|
914
|
+
const N = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), R = (u, d, g) => {
|
|
915
|
+
if (d < 0 || d >= x || u < 0 || u >= a * j) return;
|
|
916
|
+
const A = z(u, d);
|
|
917
|
+
if (P[A]) return;
|
|
918
|
+
P[A] = 1, E.push(u, d);
|
|
919
|
+
const $ = d * a + Math.min(a - 1, Math.floor((u + j / 2) / j));
|
|
920
|
+
n.route && (g && N.set(A, { ...g, to: { X: u, row: d } }), m.has($) || m.set($, A)), h[$] = 1, c !== void 0 && h[c] && (U = !0);
|
|
921
|
+
}, F = Ne(), B = (u, d, g, A, $, I) => {
|
|
922
|
+
const W = I ?? { X: u, row: Math.round(d / j) }, q = new he(e, g, A, $);
|
|
923
|
+
let O = u, _ = d;
|
|
924
|
+
for (let Y = 0; Y < jt; Y++) {
|
|
925
|
+
const K = q.step();
|
|
926
|
+
if (K.dx) {
|
|
927
|
+
const G = r(O + K.dx, _);
|
|
928
|
+
if (G === wt || G === vt || G === nt && M(O + K.dx, _)) return;
|
|
929
|
+
G === nt && (O += K.dx);
|
|
930
|
+
}
|
|
931
|
+
const H = _ + K.dy;
|
|
932
|
+
if (K.dy > 0) {
|
|
933
|
+
const G = Math.floor((H + j - 1) / j);
|
|
934
|
+
if (G >= x) return;
|
|
935
|
+
const V = Math.floor((O + j / 2) / j);
|
|
936
|
+
if (G > Math.floor((_ + j - 1) / j)) {
|
|
937
|
+
const lt = b(O, G - 1);
|
|
938
|
+
if (lt.held || lt.x !== O) {
|
|
939
|
+
if (r(O, H) === wt) return;
|
|
940
|
+
const rt = G - 1;
|
|
941
|
+
if (r(O, rt * j) !== nt) return;
|
|
942
|
+
if (lt.held) {
|
|
943
|
+
if (lt.spiked && !C(O, rt)) return;
|
|
944
|
+
T(O, rt * j), R(O, rt, { kind: g, dir: A, steerTicks: $, from: W, startX: u });
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
if (r(lt.x, rt * j) !== nt) return;
|
|
948
|
+
O = lt.x, _ = rt * j, q.land(), T(O, _);
|
|
949
|
+
continue;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
const et = r(O, H);
|
|
953
|
+
if (et === wt || et === vt || et === Pt && [Math.floor((H - j) / j), Math.floor((H + j - 1) / j)].some((lt) => i(l(V, lt)))) return;
|
|
954
|
+
_ = H;
|
|
955
|
+
} else if (K.dy < 0) {
|
|
956
|
+
const G = r(O, H);
|
|
957
|
+
if (G === vt) return;
|
|
958
|
+
if (G === Pt) {
|
|
959
|
+
q.bump();
|
|
960
|
+
let V = _;
|
|
961
|
+
for (; r(O, V - 1) === nt; ) V--;
|
|
962
|
+
_ = V;
|
|
963
|
+
} else {
|
|
964
|
+
if (G === wt) return;
|
|
965
|
+
_ = H;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
T(O, _);
|
|
969
|
+
const S = () => Math.floor((O + j / 2) / j), D = () => Math.floor((_ + j / 2) / j);
|
|
970
|
+
if (l(S(), D()) === ft) {
|
|
971
|
+
q.fade();
|
|
972
|
+
for (let G = 0; G < jt; G++) {
|
|
973
|
+
const V = q.slide();
|
|
974
|
+
if (V.dx) {
|
|
975
|
+
const et = r(O + V.dx, _);
|
|
976
|
+
if (et === wt || et === vt) return;
|
|
977
|
+
et === nt && (O += V.dx);
|
|
978
|
+
}
|
|
979
|
+
if (V.dy) {
|
|
980
|
+
if (r(O, _ + V.dy) !== nt) return;
|
|
981
|
+
_ += V.dy;
|
|
982
|
+
}
|
|
983
|
+
if (T(O, _), l(S(), D()) !== ft) return;
|
|
984
|
+
if (V.done) break;
|
|
985
|
+
}
|
|
986
|
+
r(O, D() * j) === nt && R(O, D(), { kind: g, dir: A, steerTicks: $, from: W, startX: u });
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
R(o % a * j, Math.floor(o / a));
|
|
992
|
+
for (let u = 0; u < E.length && !U; u += 2) {
|
|
993
|
+
const d = E[u], g = E[u + 1], A = g * j;
|
|
994
|
+
if (r(d, A) !== nt) continue;
|
|
995
|
+
T(d, A);
|
|
996
|
+
const $ = l(Math.floor((d + j / 2) / j), g) === ft;
|
|
997
|
+
for (const I of [-1, 1]) {
|
|
998
|
+
const W = d + I * f;
|
|
999
|
+
if (!(W < 0 || W > a * j - j || r(W, A) !== nt) && !(b(W, g).spiked && !C(W, g)))
|
|
1000
|
+
if (T(W, A), p(W, g)) R(W, g, { kind: "walk", dir: I, steerTicks: 0, from: { X: d, row: g }, startX: d });
|
|
1001
|
+
else {
|
|
1002
|
+
const q = b(W, g).x;
|
|
1003
|
+
if (r(q, A) === nt)
|
|
1004
|
+
for (const O of F) O.kind === "fall" && O.dir !== 0 && B(q, A, "fall", O.dir, O.steerTicks, { X: d, row: g });
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
if (!$ && !w(d, g))
|
|
1008
|
+
for (const I of F) I.kind === "jump" && B(d, A, "jump", I.dir, I.steerTicks);
|
|
1009
|
+
if (!p(d, g))
|
|
1010
|
+
for (const I of F) I.kind === "fall" && B(d, A, "fall", I.dir, I.steerTicks, { X: d, row: g });
|
|
1011
|
+
if ($ && e.climb) {
|
|
1012
|
+
const I = Math.floor((d + j / 2) / j);
|
|
1013
|
+
for (const W of [-1, 1])
|
|
1014
|
+
l(I, g + W) === ft && r(d, (g + W) * j) === nt && R(d, g + W, { kind: "climb", dir: 0, steerTicks: 0, from: { X: d, row: g }, startX: d });
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
return { touched: y, stood: h, routeTo: (u) => {
|
|
1018
|
+
const d = m.get(u);
|
|
1019
|
+
if (d === void 0) return;
|
|
1020
|
+
const g = [];
|
|
1021
|
+
for (let A = N.get(d); A; A = N.get(z(A.from.X, A.from.row))) g.unshift(A);
|
|
1022
|
+
return g;
|
|
1023
|
+
} };
|
|
1024
|
+
}
|
|
1025
|
+
const ee = 26, Mt = 18;
|
|
1026
|
+
function $t(t, e, o, s = !1) {
|
|
1027
|
+
const n = 10 + e + 8, c = pt(n, ee, yt), a = (y, h) => {
|
|
1028
|
+
for (let l = h; l < ee; l++) c.cells[l * n + y] = Q;
|
|
1029
|
+
};
|
|
1030
|
+
for (let y = 0; y < 10; y++) a(y, Mt);
|
|
1031
|
+
for (let y = 10 + e; y < n; y++) a(y, Mt - o);
|
|
1032
|
+
if (s)
|
|
1033
|
+
for (let y = 10; y < 10 + e; y++) a(y, Mt), c.cells[(Mt - 1) * n + y] = ht;
|
|
1034
|
+
const x = 10 + e + 4 + (Mt - o - 1) * n;
|
|
1035
|
+
return Ht(c, t, 5 + (Mt - 1) * n, !0, { goal: x }).stood[x] === 1;
|
|
1036
|
+
}
|
|
1037
|
+
const oe = /* @__PURE__ */ new Map();
|
|
1038
|
+
function ze(t) {
|
|
1039
|
+
const e = JSON.stringify([t.vx, t.push.map((x) => x ?? 0), t.steer, t.climb]), o = oe.get(e);
|
|
1040
|
+
if (o) return o;
|
|
1041
|
+
let s = 0;
|
|
1042
|
+
for (; s < 10 && $t(t, 0, s + 1); ) s++;
|
|
1043
|
+
const n = [];
|
|
1044
|
+
for (let x = 0; x <= s; x++) {
|
|
1045
|
+
let y = 0;
|
|
1046
|
+
for (; y < 14 && $t(t, y + 1, x); ) y++;
|
|
1047
|
+
n.push(y);
|
|
1048
|
+
}
|
|
1049
|
+
let c = 0;
|
|
1050
|
+
for (; c < 10 && $t(t, c + 1, 0, !0); ) c++;
|
|
1051
|
+
const a = { maxRise: s, maxGap: n[0], gapAt: n, maxSpikes: c };
|
|
1052
|
+
return oe.set(e, a), a;
|
|
1053
|
+
}
|
|
1054
|
+
const ne = 2;
|
|
1055
|
+
function De(t, e, o, s, n) {
|
|
1056
|
+
const c = pt(t, e, yt), a = ze(s.physics), x = [], y = Math.max(1, Math.floor(a.maxRise * n)), h = (O) => Math.max(1, Math.floor((a.gapAt[Math.max(0, Math.min(O, a.gapAt.length - 1))] ?? a.maxGap) * n)), l = Math.ceil((s.physics.rise + j) / j), i = Math.max(l + 1, Math.ceil(s.physics.rise / j) + 3), r = e - 4, M = (O, _, Y) => c.cells[_ * t + O] = Y, T = (O, _) => {
|
|
1057
|
+
for (let Y = _; Y < e; Y++) M(O, Y, Y === _ && s.cap ? bt : Q);
|
|
1058
|
+
};
|
|
1059
|
+
for (let O = 0; O < e; O++) M(0, O, Q), M(t - 1, O, Q);
|
|
1060
|
+
let k = 1, b = Math.max(i, Math.min(r, e - 6));
|
|
1061
|
+
const C = [], p = [], f = [], w = [], L = [], P = (O) => {
|
|
1062
|
+
const _ = k;
|
|
1063
|
+
for (let Y = 0; Y < O && k < t - 1; Y++) T(k++, b);
|
|
1064
|
+
C.push({ x0: _, len: k - _, s: b });
|
|
1065
|
+
}, z = { rise: 0, gap: 0 };
|
|
1066
|
+
P(6);
|
|
1067
|
+
const E = (b - 1) * t + 3, U = Math.min(2, y);
|
|
1068
|
+
for (; k < t - 12; ) {
|
|
1069
|
+
const O = ["flat", "flat", "gap", "gap", "gap", "step", "step", "step"];
|
|
1070
|
+
s.hazard && O.push("spikes", "spikes");
|
|
1071
|
+
const _ = (r - b) / Math.max(1, r - i);
|
|
1072
|
+
s.ladder && s.physics.climb && b - (y + 1) >= i && _ < 0.6 && O.push("tower"), s.ledge && y >= 2 && b - l - 1 >= 2 && O.push("ledge", "ledge"), t - 1 - k > 24 && O.push("stones", "stones");
|
|
1073
|
+
const Y = o.pick(O);
|
|
1074
|
+
if (Y === "flat") P(o.int(3, 8));
|
|
1075
|
+
else if (Y === "gap") {
|
|
1076
|
+
const K = o.int(1, h(0)), H = Math.min(e - 2, b + U);
|
|
1077
|
+
for (let S = 0; S < K; S++) {
|
|
1078
|
+
s.hazard && M(k + S, H, ht);
|
|
1079
|
+
for (let D = H + (s.hazard ? 1 : 0); D < e; D++) M(k + S, D, Q);
|
|
1080
|
+
}
|
|
1081
|
+
z.gap = Math.max(z.gap, K), p.push({ x: k, g: K, s: b }), k += K, P(o.int(2, 4));
|
|
1082
|
+
} else if (Y === "step") {
|
|
1083
|
+
const K = o.chance(0.7 - 0.6 * _), H = o.int(1, y), S = K ? b - H : b + H;
|
|
1084
|
+
S >= i && S <= r && (z.rise = Math.max(z.rise, H), b = S), P(o.int(2, 5));
|
|
1085
|
+
} else if (Y === "spikes") {
|
|
1086
|
+
const K = o.int(1, Math.max(1, Math.min(2, Math.floor(a.maxSpikes * n * 0.5)))), H = 8 + K, S = k;
|
|
1087
|
+
P(H);
|
|
1088
|
+
const D = S + 3 + o.int(0, 1);
|
|
1089
|
+
for (let G = 0; G < K; G++) M(D + G, b - 1, ht);
|
|
1090
|
+
w.push(D);
|
|
1091
|
+
} else if (Y === "tower") {
|
|
1092
|
+
const K = o.int(y + 1, y + 4), H = b - K;
|
|
1093
|
+
if (H < i) continue;
|
|
1094
|
+
T(k, b);
|
|
1095
|
+
for (let S = H - 1; S <= b - 1; S++) M(k, S, ft);
|
|
1096
|
+
k++, b = H, P(o.int(3, 5));
|
|
1097
|
+
} else if (Y === "ledge") {
|
|
1098
|
+
const K = o.int(2, Math.min(y, b - l - 1)), H = 9, S = k;
|
|
1099
|
+
P(H);
|
|
1100
|
+
const D = o.int(3, 4), G = S + 3;
|
|
1101
|
+
for (let V = 0; V < D; V++) M(G + V, b - K, xt);
|
|
1102
|
+
L.push({ x: G, len: D, t: b - K });
|
|
1103
|
+
} else {
|
|
1104
|
+
const K = o.int(2, 4), H = [];
|
|
1105
|
+
let S = k, D = b;
|
|
1106
|
+
for (let ot = 0; ot < K; ot++) {
|
|
1107
|
+
const at = o.int(-y, y);
|
|
1108
|
+
let kt = Math.max(i, Math.min(r - 1, D - at));
|
|
1109
|
+
ot === 0 && (kt = Math.min(kt, b));
|
|
1110
|
+
const Nt = o.int(1, h(Math.max(0, D - kt)));
|
|
1111
|
+
z.gap = Math.max(z.gap, Nt), z.rise = Math.max(z.rise, Math.abs(D - kt));
|
|
1112
|
+
const Xt = o.int(2, 3);
|
|
1113
|
+
H.push({ x: S + Nt, len: Xt, t: kt }), S += Nt + Xt, D = kt;
|
|
1114
|
+
}
|
|
1115
|
+
const G = Math.max(...H.map((ot) => ot.t)), V = H[H.length - 1], et = o.int(1, h(0));
|
|
1116
|
+
z.gap = Math.max(z.gap, et);
|
|
1117
|
+
const lt = S + et;
|
|
1118
|
+
if (lt + 8 >= t - 1) continue;
|
|
1119
|
+
const rt = Math.min(e - 2, G + 1), Vt = Math.max(V.t, rt - y);
|
|
1120
|
+
if (Vt > r) continue;
|
|
1121
|
+
for (let ot = k; ot < lt; ot++) {
|
|
1122
|
+
s.hazard && M(ot, rt, ht);
|
|
1123
|
+
for (let at = rt + (s.hazard ? 1 : 0); at < e; at++) M(ot, at, Q);
|
|
1124
|
+
}
|
|
1125
|
+
for (const ot of H) {
|
|
1126
|
+
for (let at = ot.x; at < ot.x + ot.len; at++) M(at, ot.t, s.ledge ? xt : Q);
|
|
1127
|
+
f.push(ot);
|
|
1128
|
+
}
|
|
1129
|
+
k = lt, b = Vt, P(o.int(3, 5));
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
P(t - 1 - k);
|
|
1133
|
+
const N = t - 4, m = (b - 1) * t + N, R = { exit: !1, collectable: !0, lockHolds: !0 }, F = Ht(c, s.physics, E, !0);
|
|
1134
|
+
R.exit = F.stood[m] === 1;
|
|
1135
|
+
const B = /* @__PURE__ */ new Set([E, m]), v = [];
|
|
1136
|
+
let u;
|
|
1137
|
+
const d = [], g = [], A = (O) => c.cells[O] === yt && !B.has(O), $ = (O, _, Y) => _.some((K) => Math.abs(K % t - O % t) < Y && Math.abs((K / t | 0) - (O / t | 0)) < 3), I = s.pairs[0];
|
|
1138
|
+
if (I !== void 0 && R.exit) {
|
|
1139
|
+
const O = C.filter((K) => K.len >= 7 && K.x0 > t * 0.4 && K.x0 + K.len < t - 10), _ = (K) => C.filter((H) => H.len >= 4 && H.x0 + H.len < K.x0 - 4 && H.x0 > 6), Y = O.find((K) => _(K).length > 0);
|
|
1140
|
+
if (Y) {
|
|
1141
|
+
const K = Y.x0 + (Y.len >> 1), H = Math.min(Y.s, Math.ceil(s.physics.rise / j) + 3), S = [];
|
|
1142
|
+
for (let V = Y.s - H; V < Y.s; V++) S.push(V * t + K);
|
|
1143
|
+
const D = o.pick(_(Y)), G = (D.s - 1) * t + D.x0 + (D.len >> 1);
|
|
1144
|
+
if (S.every((V) => c.cells[V] === yt) && c.cells[G] === yt) {
|
|
1145
|
+
for (const et of S) c.cells[et] = Ot;
|
|
1146
|
+
const V = Ht(c, s.physics, E, !1);
|
|
1147
|
+
if (V.stood[m] === 0 && V.touched[G] === 1) {
|
|
1148
|
+
c.cells[G] = Kt, B.add(G);
|
|
1149
|
+
for (const et of S) B.add(et);
|
|
1150
|
+
g.push(...S), d.push({ cell: S[S.length - 1], key: G, pair: I, order: 0 });
|
|
1151
|
+
} else {
|
|
1152
|
+
for (const et of S) c.cells[et] = yt;
|
|
1153
|
+
x.push(
|
|
1154
|
+
V.stood[m] ? "A locked door could be jumped over, so none was drawn." : "The key could not be reached before its door, so no door was drawn."
|
|
1155
|
+
);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
const W = F;
|
|
1161
|
+
if (s.treasure && R.exit) {
|
|
1162
|
+
const O = [], _ = (S, D) => {
|
|
1163
|
+
if (S < 1 || S >= t - 1 || D < 1 || D >= e) return;
|
|
1164
|
+
const G = D * t + S;
|
|
1165
|
+
A(G) && W.touched[G] && O.push(G);
|
|
1166
|
+
};
|
|
1167
|
+
for (const S of C) for (let D = S.x0 + 1; D < S.x0 + S.len - 1; D += 3) Math.abs(D - 3) > 3 && Math.abs(D - N) > 3 && _(D, S.s - 1);
|
|
1168
|
+
for (const S of p) {
|
|
1169
|
+
const D = S.x + (S.g >> 1);
|
|
1170
|
+
for (const G of [3, 2]) {
|
|
1171
|
+
const V = (S.s - G) * t + D;
|
|
1172
|
+
if (A(V) && W.touched[V]) {
|
|
1173
|
+
O.push(V);
|
|
1174
|
+
break;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
for (const S of f) _(S.x + (S.len >> 1), S.t - 1);
|
|
1179
|
+
for (const S of L) _(S.x + 1, S.t - 1);
|
|
1180
|
+
const Y = Math.max(4, Math.min(30, Math.floor(t / 5))), K = [...new Set(O)].sort((S, D) => S % t - D % t), H = Math.max(1, K.length / Y);
|
|
1181
|
+
for (let S = 0; S < K.length && v.length < Y; S += H) {
|
|
1182
|
+
const D = K[Math.floor(S)];
|
|
1183
|
+
$(D, v, 2) || v.push(D);
|
|
1184
|
+
}
|
|
1185
|
+
if (s.life && v.length > 2) {
|
|
1186
|
+
let S = -1;
|
|
1187
|
+
for (let D = 0; D < t * e; D++) {
|
|
1188
|
+
if (!W.stood[D] || D % t < 8 || D % t > t - 9 || !A(D)) continue;
|
|
1189
|
+
const G = D / t | 0;
|
|
1190
|
+
(S < 0 || G < (S / t | 0) || G === (S / t | 0) && o.chance(0.3)) && (S = D);
|
|
1191
|
+
}
|
|
1192
|
+
if (S >= 0) {
|
|
1193
|
+
u = S;
|
|
1194
|
+
const D = v.findIndex((G) => Math.abs(G % t - S % t) < 3);
|
|
1195
|
+
D >= 0 && v.splice(D, 1);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
for (const S of v) c.cells[S] = Bt, B.add(S);
|
|
1199
|
+
u !== void 0 && (c.cells[u] = Gt, B.add(u));
|
|
1200
|
+
}
|
|
1201
|
+
R.collectable = [...v, ...u === void 0 ? [] : [u], ...d.map((O) => O.key)].every((O) => W.touched[O] === 1);
|
|
1202
|
+
const q = [];
|
|
1203
|
+
if (s.monsters.length && R.exit) {
|
|
1204
|
+
const O = g.length ? g[0] % t : -99, _ = [];
|
|
1205
|
+
for (const H of C)
|
|
1206
|
+
if (H.len >= 6) {
|
|
1207
|
+
for (let S = H.x0 + ne + 1; S < H.x0 + H.len - ne - 1; S++)
|
|
1208
|
+
if (S > 12 && S < t - 8 && Math.abs(S - O) > 2) {
|
|
1209
|
+
const D = (H.s - 1) * t + S;
|
|
1210
|
+
A(D) && W.stood[D] && _.push(D);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
const Y = Math.max(1, Math.min(6, Math.floor(t / 18))), K = [];
|
|
1214
|
+
for (let H = 0; H < _.length * 2 && q.length < Y && _.length; H++) {
|
|
1215
|
+
const S = _[Math.floor(o.next() * _.length)];
|
|
1216
|
+
K.some((D) => Math.abs(D % t - S % t) < 8) || (K.push(S), B.add(S), q.push({ cell: S, monnum: o.pick(s.monsters) }));
|
|
1217
|
+
}
|
|
1218
|
+
q.sort((H, S) => H.cell - S.cell);
|
|
1219
|
+
}
|
|
1220
|
+
if (s.decorate) {
|
|
1221
|
+
for (const O of C)
|
|
1222
|
+
if (O.len >= 5 && o.chance(0.6)) {
|
|
1223
|
+
const _ = (O.s - 1) * t + O.x0 + O.len - 2;
|
|
1224
|
+
A(_) && _ % t < t - 6 && !w.includes(_ % t) && (c.cells[_] = ut);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
return !w.length && s.hazard && x.push("No spikes fit this layout."), { area: c, entry: E, exit: m, locks: d, doorCells: g, treasure: v, life: u, monsters: q, notes: x, proof: R, difficulty: n, can: { rise: a.maxRise, gap: a.maxGap }, asked: z };
|
|
1228
|
+
}
|
|
1229
|
+
function Fe(t, e, o, s) {
|
|
1230
|
+
let n;
|
|
1231
|
+
for (let c = 0; c < 8; c++) {
|
|
1232
|
+
const a = Math.max(0.2, s.difficulty - (c >= 3 ? 0.1 * (c - 2) : 0)), x = De(t, e, o, s, a);
|
|
1233
|
+
if (x.proof.exit && x.proof.collectable && x.proof.lockHolds)
|
|
1234
|
+
return a < s.difficulty && x.notes.push(`Drawn a little easier than asked (${Math.round(a * 100)}%): the first layouts could not be proven.`), x;
|
|
1235
|
+
n ??= x;
|
|
1236
|
+
}
|
|
1237
|
+
return n.notes.push("No layout could be proven reachable by jump math."), n;
|
|
1238
|
+
}
|
|
1239
|
+
const Pe = {
|
|
1240
|
+
home: { w: 24, h: 16 },
|
|
1241
|
+
shop: { w: 26, h: 14 },
|
|
1242
|
+
castle: { w: 56, h: 40 },
|
|
1243
|
+
town: { w: 80, h: 56 },
|
|
1244
|
+
platform: { w: 120, h: 24 }
|
|
1245
|
+
}, Xe = 10, Ze = (t, e) => t + Math.imul(e, 2654435761) >>> 0, $e = (t, e) => X(t, e)[0];
|
|
1246
|
+
function We(t, e) {
|
|
1247
|
+
const o = ge(e.kind, t);
|
|
1248
|
+
if (!o.ok) return { ok: !1, message: o.message };
|
|
1249
|
+
const s = se(e.kind).min;
|
|
1250
|
+
if (e.rect.w < s.w || e.rect.h < s.h)
|
|
1251
|
+
return { ok: !1, message: `That area is small: a ${e.kind} needs at least ${s.w} by ${s.h} blocks.` };
|
|
1252
|
+
const n = Pe[e.kind], c = Math.min(e.rect.w, n?.w ?? 1 / 0), a = Math.min(e.rect.h, n?.h ?? 1 / 0), x = { x: e.rect.x + (e.rect.w - c >> 1), y: e.rect.y + (e.rect.h - a >> 1), w: c, h: a }, y = zt(e.seed), h = [...o.skipped], l = (u) => X(t, u).length > 0;
|
|
1253
|
+
let i, r, M;
|
|
1254
|
+
const T = {};
|
|
1255
|
+
let k, b, C = [], p, f = [];
|
|
1256
|
+
const w = (u, d) => {
|
|
1257
|
+
const g = X(t, u);
|
|
1258
|
+
return g.find((A) => t[A].facing === d) ?? g.find((A) => !t[A].facing) ?? g[0];
|
|
1259
|
+
};
|
|
1260
|
+
if (e.kind === "platform") {
|
|
1261
|
+
if (!e.hero) return { ok: !1, message: "A side view needs the hero’s character file, to measure how he jumps." };
|
|
1262
|
+
const u = Ce(e.hero);
|
|
1263
|
+
if (!u.ok) return { ok: !1, message: u.message };
|
|
1264
|
+
const d = Array.from({ length: Zt }, (A, $) => $ + 1).filter(
|
|
1265
|
+
(A) => X(t, "locked-door", A).length && X(t, "key", A).length
|
|
1266
|
+
), g = Fe(c, a, y, {
|
|
1267
|
+
physics: u.physics,
|
|
1268
|
+
difficulty: Math.max(0.1, Math.min(1, (e.difficulty ?? 80) / 100)),
|
|
1269
|
+
ladder: l("ladder"),
|
|
1270
|
+
hazard: l("hazard"),
|
|
1271
|
+
ledge: l("platform"),
|
|
1272
|
+
cap: l("wall-top"),
|
|
1273
|
+
pairs: d,
|
|
1274
|
+
treasure: l("treasure"),
|
|
1275
|
+
life: l("life"),
|
|
1276
|
+
monsters: e.monsters ?? [],
|
|
1277
|
+
decorate: l("decoration")
|
|
1278
|
+
});
|
|
1279
|
+
({ area: i, entry: r, exit: M } = g), h.push(...g.notes), l("locked-door") && !d.length && h.push("The locked door blocks and key blocks share no lock number, so no doors were locked."), k = { proof: g.proof, difficulty: g.difficulty, can: g.can, asked: g.asked }, b = { locks: g.locks, treasure: g.treasure, life: g.life, monsters: g.monsters, doorCells: g.doorCells };
|
|
1280
|
+
} else if (e.kind === "dungeon")
|
|
1281
|
+
({ area: i, entry: r, exit: M } = ae(c, a, y, l("decoration")));
|
|
1282
|
+
else if (e.kind === "castle")
|
|
1283
|
+
({ area: i, entry: r, exit: M } = Te(c, a, y, { path: l("path"), decorate: l("decoration") }));
|
|
1284
|
+
else if (e.kind === "town")
|
|
1285
|
+
({ area: i, entry: r, exit: M, links: f } = Ie(c, a, y, { tree: l("tree"), decor: l("decoration") }));
|
|
1286
|
+
else if (e.kind === "overworld")
|
|
1287
|
+
({ area: i, entry: r, exit: M, links: f } = Le(c, a, y, { tree: l("tree"), rock: l("rock"), decor: l("decoration"), wrap: !!e.wrap }));
|
|
1288
|
+
else if (e.kind === "home" || e.kind === "shop") {
|
|
1289
|
+
const u = {};
|
|
1290
|
+
for (const g of ["table", "chair", "bed", "counter", "shelf", "stove", "rug", "lamp", "plant"]) {
|
|
1291
|
+
const A = X(t, g);
|
|
1292
|
+
A.length && (u[g] = A.some(($) => !t[$].facing) ? de : [...new Set(A.map(($) => t[$].facing))]);
|
|
1293
|
+
}
|
|
1294
|
+
const d = Re(c, a, y, e.kind, u);
|
|
1295
|
+
({ area: i, entry: r, exit: M } = d), p = d.shopkeeper, C = d.items.map((g) => ({ ...g, block: w(g.role, g.facing) }));
|
|
1296
|
+
for (const g of d.skipped)
|
|
1297
|
+
h.push(
|
|
1298
|
+
g === "chair" ? "Chairs skipped: no chair block faces the way a chair beside a table must." : `Some ${g}s skipped: no ${g} block faces the way it must stand against a wall.`
|
|
1299
|
+
);
|
|
1300
|
+
} else
|
|
1301
|
+
({ area: i, entry: r, exit: M } = Ee(c, a, y, { path: l("path"), rock: l("rock"), decor: l("decoration") }));
|
|
1302
|
+
const L = e.kind === "dungeon" || e.kind === "castle" ? Array.from({ length: Zt }, (u, d) => d + 1).filter(
|
|
1303
|
+
(u) => X(t, "locked-door", u).length && X(t, "key", u).length
|
|
1304
|
+
) : [], P = e.kind === "home" || e.kind === "shop" || e.kind === "town" || e.kind === "overworld", z = b || (P ? { locks: [], treasure: [], life: void 0, monsters: [] } : be(i, r, M, zt(e.seed ^ 2654435769), {
|
|
1305
|
+
pairs: L,
|
|
1306
|
+
treasure: l("treasure"),
|
|
1307
|
+
life: l("life"),
|
|
1308
|
+
monsters: e.monsters ?? []
|
|
1309
|
+
})), E = e.kind === "dungeon" || e.kind === "castle";
|
|
1310
|
+
E && l("locked-door") && !L.length && h.push("The locked door blocks and key blocks share no lock number, so no doors were locked."), E && L.length && !z.locks.length && h.push("No narrow passage fit a locked door in this layout.");
|
|
1311
|
+
const U = {
|
|
1312
|
+
[Q]: X(t, "wall").slice(0, 1),
|
|
1313
|
+
[Z]: X(t, "floor"),
|
|
1314
|
+
[ct]: X(t, "path").slice(0, 1),
|
|
1315
|
+
[J]: X(t, "tree").slice(0, 1),
|
|
1316
|
+
[Et]: X(t, "rock").slice(0, 1),
|
|
1317
|
+
[ut]: X(t, "decoration"),
|
|
1318
|
+
[dt]: X(t, "door").slice(0, 1),
|
|
1319
|
+
[it]: X(t, "water").slice(0, 1),
|
|
1320
|
+
[yt]: X(t, "sky").slice(0, 1),
|
|
1321
|
+
[ft]: X(t, "ladder").slice(0, 1),
|
|
1322
|
+
[ht]: X(t, "hazard").slice(0, 1),
|
|
1323
|
+
[xt]: X(t, "platform").slice(0, 1),
|
|
1324
|
+
[bt]: X(t, "wall-top").length ? X(t, "wall-top").slice(0, 1) : X(t, "wall").slice(0, 1)
|
|
1325
|
+
}, N = $e(t, "floor"), m = new Uint8Array(i.cells.length), R = zt(e.seed ^ 1540483477);
|
|
1326
|
+
for (let u = 0; u < m.length; u++) {
|
|
1327
|
+
const d = U[i.cells[u]] ?? [N];
|
|
1328
|
+
m[u] = i.cells[u] === Z && d.length > 1 && R.chance(0.1) ? d[R.int(1, d.length - 1)] : d[0] ?? N;
|
|
1329
|
+
}
|
|
1330
|
+
const F = (u) => {
|
|
1331
|
+
const d = [];
|
|
1332
|
+
return i.cells.forEach((g, A) => g === u && d.push(A)), d;
|
|
1333
|
+
}, B = (u, d) => u.forEach((g, A) => m[g] = d[A % d.length]);
|
|
1334
|
+
for (const u of z.locks)
|
|
1335
|
+
m[u.cell] = X(t, "locked-door", u.pair)[0], m[u.key] = X(t, "key", u.pair)[0];
|
|
1336
|
+
if (b) for (const u of b.doorCells) m[u] = X(t, "locked-door", b.locks[0].pair)[0];
|
|
1337
|
+
B(z.treasure, X(t, "treasure").length ? X(t, "treasure") : [N]), z.life !== void 0 && (m[z.life] = X(t, "life")[0]);
|
|
1338
|
+
for (const u of C) m[u.cell] = u.block;
|
|
1339
|
+
const v = e.kind === "town" && !l("wall-top");
|
|
1340
|
+
return T.wall = e.kind !== "forest" && e.kind !== "overworld" ? [...F(Q), ...v ? F(bt) : []] : void 0, T.tree = e.kind === "forest" || e.kind === "town" || e.kind === "overworld" ? F(J) : void 0, T.water = e.kind === "overworld" ? F(it) : void 0, T.path = F(ct).length ? F(ct) : void 0, {
|
|
1341
|
+
ok: !0,
|
|
1342
|
+
result: {
|
|
1343
|
+
rect: x,
|
|
1344
|
+
blocks: m,
|
|
1345
|
+
kinds: i.cells,
|
|
1346
|
+
terrainCells: T,
|
|
1347
|
+
entry: r,
|
|
1348
|
+
exit: M,
|
|
1349
|
+
locks: z.locks,
|
|
1350
|
+
treasure: z.treasure,
|
|
1351
|
+
life: z.life,
|
|
1352
|
+
monsters: z.monsters,
|
|
1353
|
+
furniture: C,
|
|
1354
|
+
shopkeeper: p,
|
|
1355
|
+
links: f,
|
|
1356
|
+
platform: k,
|
|
1357
|
+
notes: h
|
|
1358
|
+
}
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
function _e(t) {
|
|
1362
|
+
const e = { w: t.rect.w, h: t.rect.h, cells: t.kinds }, o = st(e, t.entry);
|
|
1363
|
+
let s = 0, n = 0;
|
|
1364
|
+
for (let c = 0; c < o.length; c++)
|
|
1365
|
+
tt(e.cells[c]) || (s++, o[c] >= 0 && n++);
|
|
1366
|
+
return { ok: s === n && s > 0, open: s, reached: n };
|
|
1367
|
+
}
|
|
1368
|
+
function Ue(t) {
|
|
1369
|
+
if (!t.furniture.length) return !0;
|
|
1370
|
+
const e = { w: t.rect.w, h: t.rect.h, cells: t.kinds }, o = st(e, t.entry), s = new Set(t.furniture.filter((n) => n.role === "table").map((n) => n.cell));
|
|
1371
|
+
return t.furniture.every((n) => {
|
|
1372
|
+
const c = n.cell % e.w, a = n.cell / e.w | 0;
|
|
1373
|
+
if (n.open) return o[n.cell] >= 0;
|
|
1374
|
+
if (n.role === "chair") {
|
|
1375
|
+
const [x, y] = Ct[n.facing];
|
|
1376
|
+
if (!s.has((a + y) * e.w + c + x)) return !1;
|
|
1377
|
+
}
|
|
1378
|
+
return Object.values(Ct).some(([x, y]) => {
|
|
1379
|
+
const h = c + x, l = a + y;
|
|
1380
|
+
return h >= 0 && l >= 0 && h < e.w && l < e.h && o[l * e.w + h] >= 0;
|
|
1381
|
+
});
|
|
1382
|
+
});
|
|
1383
|
+
}
|
|
1384
|
+
function He(t) {
|
|
1385
|
+
if (!t.links.length) return !0;
|
|
1386
|
+
const e = { w: t.rect.w, h: t.rect.h, cells: t.kinds }, o = st(e, t.entry);
|
|
1387
|
+
return t.links.every((s) => o[s.cell] >= 0);
|
|
1388
|
+
}
|
|
1389
|
+
function qe(t) {
|
|
1390
|
+
const e = { w: t.rect.w, h: t.rect.h, cells: t.kinds }, o = [...t.treasure, ...t.life === void 0 ? [] : [t.life]];
|
|
1391
|
+
if (t.platform) {
|
|
1392
|
+
const c = t.platform.proof;
|
|
1393
|
+
return { reach: c.exit, keysFirst: c.lockHolds, collectable: c.collectable, furnished: !0, linked: !0 };
|
|
1394
|
+
}
|
|
1395
|
+
const s = ve(e, t.entry, t.exit, t.locks, o);
|
|
1396
|
+
return { reach: _e(t).ok, keysFirst: s.strict, collectable: s.ok, furnished: Ue(t), linked: He(t) };
|
|
1397
|
+
}
|
|
1398
|
+
const Je = { LOCK: Ot, KEY: Kt, TREASURE: Bt, LIFE: Gt };
|
|
1399
|
+
function Qe(t) {
|
|
1400
|
+
return We(t.roles, { kind: "platform", seed: t.seed, rect: t.rect, hero: t.hero, difficulty: t.difficulty, monsters: t.monsters });
|
|
1401
|
+
}
|
|
1402
|
+
export {
|
|
1403
|
+
dt as DOOR_CELL,
|
|
1404
|
+
Z as FLOOR_CELL,
|
|
1405
|
+
ke as KINDS,
|
|
1406
|
+
ft as LADDER_CELL,
|
|
1407
|
+
Ot as LOCK_CELL,
|
|
1408
|
+
Xe as MIN_SIDE,
|
|
1409
|
+
ct as PATH_CELL,
|
|
1410
|
+
Je as PROP_KINDS,
|
|
1411
|
+
ze as capability,
|
|
1412
|
+
ge as checkNeeds,
|
|
1413
|
+
tt as closedCell,
|
|
1414
|
+
We as generate,
|
|
1415
|
+
Qe as generatePlatform,
|
|
1416
|
+
Ce as heroPhysics,
|
|
1417
|
+
se as kindInfo,
|
|
1418
|
+
Ze as offerSeed,
|
|
1419
|
+
qe as proveResult,
|
|
1420
|
+
Ht as reachFrom,
|
|
1421
|
+
_e as verifyReach,
|
|
1422
|
+
Ve as weaker
|
|
1423
|
+
};
|