diff --git a/package-lock.json b/package-lock.json index 68c5a4e4..45eaa5d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,8 +15,8 @@ "@mcschema/java-1.17": "^0.2.24", "@mcschema/java-1.18": "^0.1.16", "@mcschema/locales": "^0.1.35", - "deepslate": "^0.9.0-beta.2", - "deepslate-rs": "^0.1.4", + "deepslate": "^0.9.0-beta.5", + "deepslate-rs": "^0.1.6", "howler": "^2.2.3", "rfdc": "^1.3.0" }, @@ -906,6 +906,14 @@ "node": ">=4" } }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "engines": { + "node": "*" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -956,6 +964,14 @@ "node": ">= 8" } }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "engines": { + "node": "*" + } + }, "node_modules/debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -980,18 +996,19 @@ "dev": true }, "node_modules/deepslate": { - "version": "0.9.0-beta.2", - "resolved": "https://registry.npmjs.org/deepslate/-/deepslate-0.9.0-beta.2.tgz", - "integrity": "sha512-qJTzAfngaYXGXS5nXiHUgLbw+6/GtSXOuz+bDVb+EWYHUfekYw5qxpIQdKEKNVGobqchE4mAKJ84KAeWKW5wjw==", + "version": "0.9.0-beta.5", + "resolved": "https://registry.npmjs.org/deepslate/-/deepslate-0.9.0-beta.5.tgz", + "integrity": "sha512-/f3cFDsgNWbSdo7dfHYSO7ZJEjjkEqIBlI6K9Q+elaKudduzE9SQdFlDAodW3ye2g/XhkA2jO9pc0i9F9fAMhw==", "dependencies": { "gl-matrix": "^3.3.0", + "md5": "^2.3.0", "pako": "^2.0.3" } }, "node_modules/deepslate-rs": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deepslate-rs/-/deepslate-rs-0.1.4.tgz", - "integrity": "sha512-vaajhtPObmqsjMM5PYD5SLPqb91tmpHGKwdR1cdwYWorKGk9yI9tf906MRQAG4J8QCO4TuQKV/+55TUvX/Xq4w==" + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/deepslate-rs/-/deepslate-rs-0.1.6.tgz", + "integrity": "sha512-Y8KCPz2Py76yvjhljg2cchFjMYzbbL81ajdbJRWvo2hBekJZRv9EjWDPNtHzYAvSTJ3HeMFpzKgZyIThftENlA==" }, "node_modules/dir-glob": { "version": "3.0.1", @@ -1710,6 +1727,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "node_modules/is-core-module": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", @@ -1898,6 +1920,16 @@ "node": ">=10" } }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3354,6 +3386,11 @@ "supports-color": "^5.3.0" } }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3401,6 +3438,11 @@ "which": "^2.0.1" } }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + }, "debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -3417,18 +3459,19 @@ "dev": true }, "deepslate": { - "version": "0.9.0-beta.2", - "resolved": "https://registry.npmjs.org/deepslate/-/deepslate-0.9.0-beta.2.tgz", - "integrity": "sha512-qJTzAfngaYXGXS5nXiHUgLbw+6/GtSXOuz+bDVb+EWYHUfekYw5qxpIQdKEKNVGobqchE4mAKJ84KAeWKW5wjw==", + "version": "0.9.0-beta.5", + "resolved": "https://registry.npmjs.org/deepslate/-/deepslate-0.9.0-beta.5.tgz", + "integrity": "sha512-/f3cFDsgNWbSdo7dfHYSO7ZJEjjkEqIBlI6K9Q+elaKudduzE9SQdFlDAodW3ye2g/XhkA2jO9pc0i9F9fAMhw==", "requires": { "gl-matrix": "^3.3.0", + "md5": "^2.3.0", "pako": "^2.0.3" } }, "deepslate-rs": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deepslate-rs/-/deepslate-rs-0.1.4.tgz", - "integrity": "sha512-vaajhtPObmqsjMM5PYD5SLPqb91tmpHGKwdR1cdwYWorKGk9yI9tf906MRQAG4J8QCO4TuQKV/+55TUvX/Xq4w==" + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/deepslate-rs/-/deepslate-rs-0.1.6.tgz", + "integrity": "sha512-Y8KCPz2Py76yvjhljg2cchFjMYzbbL81ajdbJRWvo2hBekJZRv9EjWDPNtHzYAvSTJ3HeMFpzKgZyIThftENlA==" }, "dir-glob": { "version": "3.0.1", @@ -3973,6 +4016,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "is-core-module": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", @@ -4122,6 +4170,16 @@ "yallist": "^4.0.0" } }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", diff --git a/package.json b/package.json index 080d4213..ad2b8744 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,8 @@ "@mcschema/java-1.17": "^0.2.24", "@mcschema/java-1.18": "^0.1.16", "@mcschema/locales": "^0.1.35", - "deepslate": "^0.9.0-beta.2", - "deepslate-rs": "^0.1.4", + "deepslate": "^0.9.0-beta.5", + "deepslate-rs": "^0.1.6", "howler": "^2.2.3", "rfdc": "^1.3.0" }, diff --git a/src/app/components/Octicon.tsx b/src/app/components/Octicon.tsx index 4a40c4f8..9826e040 100644 --- a/src/app/components/Octicon.tsx +++ b/src/app/components/Octicon.tsx @@ -28,6 +28,7 @@ export const Octicon = { plus: , plus_circle: , search: , + stack: , sun: , sync: , tag: , diff --git a/src/app/components/previews/BiomeSourcePreview.tsx b/src/app/components/previews/BiomeSourcePreview.tsx index 54b2aa6c..087aa8c6 100644 --- a/src/app/components/previews/BiomeSourcePreview.tsx +++ b/src/app/components/previews/BiomeSourcePreview.tsx @@ -3,15 +3,18 @@ import type { NoiseOctaves } from 'deepslate' import { NoiseGeneratorSettings } from 'deepslate' import { useEffect, useRef, useState } from 'preact/hooks' import type { PreviewProps } from '.' -import { Btn } from '..' +import { Btn, BtnMenu } from '..' import { useCanvas } from '../../hooks' import { locale } from '../../Locales' import { biomeMap, getBiome } from '../../previews' import { newSeed } from '../../Utils' +const LAYERS = ['biomes', 'temperature', 'humidity', 'continentalness', 'erosion', 'weirdness', 'offset', 'factor', 'jaggedness'] as const + export const BiomeSourcePreview = ({ model, data, shown, lang, version }: PreviewProps) => { const [scale, setScale] = useState(2) const [focused, setFocused] = useState(undefined) + const [layers, setLayers] = useState(new Set(['biomes'])) const offset = useRef<[number, number]>([0, 0]) const res = useRef(1) const refineTimeout = useRef(undefined) @@ -26,7 +29,7 @@ export const BiomeSourcePreview = ({ model, data, shown, lang, version }: Previe return [200 / res.current, 200 / res.current] }, async draw(img) { - const options = { octaves, biomeColors: {}, offset: offset.current, scale, seed, res: res.current, version } + const options = { octaves, biomeColors: {}, layers, offset: offset.current, scale, seed, res: res.current, version } await biomeMap(data, img, options) if (res.current === 4) { clearTimeout(refineTimeout.current) @@ -44,21 +47,21 @@ export const BiomeSourcePreview = ({ model, data, shown, lang, version }: Previe redraw() }, async onHover(x, y) { - const options = { octaves, biomeColors: {}, offset: offset.current, scale, seed, res: 1, version } + const options = { octaves, biomeColors: {}, layers, offset: offset.current, scale, seed, res: 1, version } const biome = await getBiome(data, Math.floor(x * 200), Math.floor(y * 200), options) setFocused(biome) }, onLeave() { setFocused(undefined) }, - }, [state, scale, seed]) + }, [state, scale, seed, layers]) useEffect(() => { if (shown) { res.current = type === 'multi_noise' ? 4 : 1 redraw() } - }, [state, scale, seed, shown]) + }, [state, scale, seed, layers, shown]) const changeScale = (newScale: number) => { offset.current[0] = offset.current[0] * scale / newScale @@ -69,6 +72,19 @@ export const BiomeSourcePreview = ({ model, data, shown, lang, version }: Previe return <>
{focused && } + {type === 'multi_noise' && + + {LAYERS.map(name => { + const enabled = layers.has(name) + return { + setLayers(new Set([name])) + e.stopPropagation() + }} /> + })} + } {(type === 'multi_noise' || type === 'checkerboard') && <> changeScale(scale * 1.5)} /> @@ -88,38 +104,40 @@ function calculateState(data: any, octaves: NoiseOctaves) { } function getOctaves(obj: any): NoiseOctaves { - if (typeof obj === 'string') { - switch (obj.replace(/^minecraft:/, '')) { - case 'overworld': - case 'amplified': - return { - temperature: { firstOctave: -9, amplitudes: [1.5, 0, 1, 0, 0, 0] }, - humidity: { firstOctave: -7, amplitudes: [1, 1, 0, 0, 0, 0] }, - continentalness: { firstOctave: -9, amplitudes: [1, 1, 2, 2, 2, 1, 1, 1, 1] }, - erosion: { firstOctave: -9, amplitudes: [1, 1, 0, 1, 1] }, - weirdness: { firstOctave: -7, amplitudes: [1, 2, 1, 0, 0, 0] }, - shift: { firstOctave: -3, amplitudes: [1, 1, 1, 0] }, - } - case 'end': - case 'floating_islands': - return { - temperature: { firstOctave: 0, amplitudes: [0] }, - humidity: { firstOctave: 0, amplitudes: [0] }, - continentalness: { firstOctave: 0, amplitudes: [0] }, - erosion: { firstOctave: 0, amplitudes: [0] }, - weirdness: { firstOctave: 0, amplitudes: [0] }, - shift: { firstOctave: 0, amplitudes: [0] }, - } - default: - return { - temperature: { firstOctave: -7, amplitudes: [1, 1] }, - humidity: { firstOctave: -7, amplitudes: [1, 1] }, - continentalness: { firstOctave: -7, amplitudes: [1, 1] }, - erosion: { firstOctave: -7, amplitudes: [1, 1] }, - weirdness: { firstOctave: -7, amplitudes: [1, 1] }, - shift: { firstOctave: 0, amplitudes: [0] }, - } - } + if (typeof obj !== 'string') { + const settings = NoiseGeneratorSettings.fromJson(obj) + obj = settings.noise.densityFactor === 0 && settings.noise.densityOffset === -0.030078125 + ? 'minecraft:nether' : 'minecraft:overworld' + } + switch (obj.replace(/^minecraft:/, '')) { + case 'overworld': + case 'amplified': + return { + temperature: { firstOctave: -9, amplitudes: [1.5, 0, 1, 0, 0, 0] }, + humidity: { firstOctave: -7, amplitudes: [1, 1, 0, 0, 0, 0] }, + continentalness: { firstOctave: -9, amplitudes: [1, 1, 2, 2, 2, 1, 1, 1, 1] }, + erosion: { firstOctave: -9, amplitudes: [1, 1, 0, 1, 1] }, + weirdness: { firstOctave: -7, amplitudes: [1, 2, 1, 0, 0, 0] }, + shift: { firstOctave: -3, amplitudes: [1, 1, 1, 0] }, + } + case 'end': + case 'floating_islands': + return { + temperature: { firstOctave: 0, amplitudes: [0] }, + humidity: { firstOctave: 0, amplitudes: [0] }, + continentalness: { firstOctave: 0, amplitudes: [0] }, + erosion: { firstOctave: 0, amplitudes: [0] }, + weirdness: { firstOctave: 0, amplitudes: [0] }, + shift: { firstOctave: 0, amplitudes: [0] }, + } + default: + return { + temperature: { firstOctave: -7, amplitudes: [1, 1] }, + humidity: { firstOctave: -7, amplitudes: [1, 1] }, + continentalness: { firstOctave: -7, amplitudes: [1, 1] }, + erosion: { firstOctave: -7, amplitudes: [1, 1] }, + weirdness: { firstOctave: -7, amplitudes: [1, 1] }, + shift: { firstOctave: 0, amplitudes: [0] }, + } } - return NoiseGeneratorSettings.fromJson(obj).octaves } diff --git a/src/app/previews/BiomeSource.ts b/src/app/previews/BiomeSource.ts index 48383b9a..a8ee6aec 100644 --- a/src/app/previews/BiomeSource.ts +++ b/src/app/previews/BiomeSource.ts @@ -1,7 +1,7 @@ import { DataModel } from '@mcschema/core' -import type { BiomeSource, Climate, NoiseOctaves } from 'deepslate' -import { FixedBiome, NoiseGeneratorSettings, NoiseSampler, NormalNoise, Random } from 'deepslate' -import init, { biome_parameters, climate_sampler, multi_noise } from 'deepslate-rs' +import type { NoiseOctaves } from 'deepslate' +import { FixedBiome, LegacyRandom, NormalNoise, TerrainShaper } from 'deepslate' +import init, { biome_parameters, climate_noise, climate_sampler, multi_noise } from 'deepslate-rs' // @ts-expect-error import wasm from 'deepslate-rs/deepslate_rs_bg.wasm?url' import { fetchPreset } from '../DataFetcher' @@ -16,7 +16,21 @@ async function loadWasm() { console.debug(`Loaded deepslate-rs from "${wasm}"`) } -type BiomeColors = Record +const OverworldShaper = TerrainShaper.overworld() + +const LAYERS = { + temperature: [-1, 1], + humidity: [-1, 1], + continentalness: [-1.1, 1], + erosion: [-1, 1], + weirdness: [-1, 1], + offset: [-1, 1], + factor: [0, 12], + jaggedness: [0, 1], +} + +type Triple = [number, number, number] +type BiomeColors = Record type BiomeSourceOptions = { octaves: NoiseOctaves, biomeColors: BiomeColors, @@ -25,18 +39,20 @@ type BiomeSourceOptions = { res: number, seed: bigint, version: VersionId, + layers: Set, } -interface CachedBiomeSource extends BiomeSource { +interface CachedBiomeSource { + getBiome(x: number, y: number, z: number): string getBiomes?(xFrom: number, xTo: number, xStep: number, yFrom: number, yTo: number, yStep: number, zFrom: number, zTo: number, zStep: number): string[] + getClimate?(layers: Set, xFrom: number, xTo: number, xStep: number, yFrom: number, yTo: number, yStep: number, zFrom: number, zTo: number, zStep: number): {[k: string]: number}[] } let cacheState: any let biomeSourceCache: CachedBiomeSource -let climateSamplerCache: Climate.Sampler export async function biomeMap(state: any, img: ImageData, options: BiomeSourceOptions) { - const { biomeSource, climateSampler } = await getCached(state, options) + const { biomeSource } = await getCached(state, options) const data = img.data const ox = -Math.round(options.offset[0]) - 100 + options.res / 2 @@ -44,19 +60,29 @@ export async function biomeMap(state: any, img: ImageData, options: BiomeSourceO const row = img.width * 4 / options.res const col = 4 / options.res - const biomes = biomeSource.getBiomes?.( - ox * options.scale, (200 + ox) * options.scale, options.res * options.scale, - 64, 65, 1, - oz * options.scale, (200 + oz) * options.scale, options.res * options.scale, - ) + const xRange: Triple = [ox * options.scale, (200 + ox) * options.scale, options.res * options.scale] + const zRange: Triple = [oz * options.scale, (200 + oz) * options.scale, options.res * options.scale] + + const biomes = !options.layers.has('biomes') ? undefined : biomeSource.getBiomes?.(...xRange, 64, 65, 1, ...zRange) + const layers = [...options.layers].filter(l => l !== 'biomes') as (keyof typeof LAYERS)[] + const noise = layers.length === 0 ? undefined : biomeSource.getClimate?.(new Set(layers), ...xRange, 64, 65, 1, ...zRange) for (let x = 0; x < 200; x += options.res) { for (let z = 0; z < 200; z += options.res) { const i = z * row + x * col + const j = (x / options.res) * 200 / options.res + z / options.res const worldX = (x + ox) * options.scale const worldZ = (z + oz) * options.scale - const b = biomes?.[(x / options.res) * 200 / options.res + z / options.res] ?? biomeSource.getBiome(worldX, 64, worldZ, climateSampler) - const color = getBiomeColor(b, options.biomeColors) + let color: Triple = [50, 50, 50] + if (options.layers.has('biomes')) { + const biome = biomes?.[j] ?? biomeSource.getBiome(worldX, 64, worldZ) + color = getBiomeColor(biome, options.biomeColors) + } else if (noise && layers[0]) { + const value = noise[j][layers[0]] + const [min, max] = LAYERS[layers[0]] + const brightness = (value - min) / (max - min) * 256 + color = [brightness, brightness, brightness] + } data[i] = color[0] data[i + 1] = color[1] data[i + 2] = color[2] @@ -66,26 +92,21 @@ export async function biomeMap(state: any, img: ImageData, options: BiomeSourceO } export async function getBiome(state: any, x: number, z: number, options: BiomeSourceOptions): Promise { - const { biomeSource, climateSampler } = await getCached(state, options) + const { biomeSource } = await getCached(state, options) const [xx, zz] = toWorld([x, z], options) - return biomeSource.getBiome(xx, 64, zz, climateSampler) + return biomeSource.getBiome(xx, 64, zz) } -async function getCached(state: any, options: BiomeSourceOptions): Promise<{ biomeSource: CachedBiomeSource, climateSampler: Climate.Sampler }> { +async function getCached(state: any, options: BiomeSourceOptions): Promise<{ biomeSource: CachedBiomeSource}> { const newState = [state, options.octaves, `${options.seed}`, options.version] if (!deepEqual(newState, cacheState)) { cacheState = deepClone(newState) biomeSourceCache = await getBiomeSource(state, options) - - const settings = NoiseGeneratorSettings.fromJson({ octaves: options.octaves }) - const noiseSampler = new NoiseSampler(4, 4, 32, biomeSourceCache, settings.noise, options.octaves, options.seed) - climateSamplerCache = noiseSampler.getClimate.bind(noiseSampler) } return { biomeSource: biomeSourceCache, - climateSampler: climateSamplerCache, } } @@ -149,13 +170,32 @@ async function getBiomeSource(state: any, options: BiomeSourceOptions): Promise< const ids = multi_noise(parameters, sampler, xFrom, xTo, xStep, yFrom, yTo, yStep, zFrom, zTo, zStep) return [...ids].map(id => BiomeIds.getA(id) ?? 'unknown') }, + getClimate(layers, xFrom, xTo, xStep, yFrom, yTo, yStep, zFrom, zTo, zStep) { + const climate = climate_noise(sampler, xFrom, xTo, xStep, yFrom, yTo, yStep, zFrom, zTo, zStep) + const result = [] + for (let i = 0; i < climate.length; i += 7) { + const [t, h, c, e, w] = climate.slice(i, i + 5) + const point = TerrainShaper.point(c, e, w) + result.push({ + temperature: t, + humidity: h, + continentalness: c, + erosion: e, + weirdness: w, + ...layers.has('offset') && { offset: OverworldShaper.offset(point) }, + ...layers.has('factor') && { factor: OverworldShaper.factor(point) }, + ...layers.has('jaggedness') && { jaggedness: OverworldShaper.jaggedness(point) }, + }) + } + return result + }, } } else { const noise = ['altitude', 'temperature', 'humidity', 'weirdness'] .map((id, i) => { const config = state[`${id}_noise`] config.firstOctave = clamp(config.firstOctave ?? -7, -100, -1) - return new NormalNoise(new Random(options.seed + BigInt(i)), config) + return new NormalNoise(new LegacyRandom(options.seed + BigInt(i)), config) }) if (!Array.isArray(state.biomes) || state.biomes.length === 0) { return new FixedBiome('unknown') @@ -180,7 +220,7 @@ async function getBiomeSource(state: any, options: BiomeSourceOptions): Promise< throw new Error('Unknown biome source') } -function getBiomeColor(biome: string, biomeColors: BiomeColors) { +function getBiomeColor(biome: string, biomeColors: BiomeColors): Triple { if (!biome) { return [128, 128, 128] } @@ -197,7 +237,7 @@ function toWorld([x, z]: [number, number], options: BiomeSourceOptions) { return [xx, zz] } -const VanillaColors: Record = { +const VanillaColors: Record = { 'minecraft:badlands': [217,69,21], 'minecraft:badlands_plateau': [202,140,101], 'minecraft:bamboo_jungle': [118,142,20], diff --git a/src/app/previews/Decorator.ts b/src/app/previews/Decorator.ts index 77a709ee..c07307fb 100644 --- a/src/app/previews/Decorator.ts +++ b/src/app/previews/Decorator.ts @@ -1,5 +1,6 @@ import { DataModel } from '@mcschema/core' -import { PerlinNoise, Random } from 'deepslate' +import type { Random } from 'deepslate' +import { LegacyRandom, PerlinNoise } from 'deepslate' import type { VersionId } from '../Schemas' import { clamp, stringToColor } from '../Utils' @@ -35,7 +36,7 @@ export type DecoratorOptions = { version: VersionId, } export function decorator(state: any, img: ImageData, options: DecoratorOptions) { - const random = new Random(options.seed) + const random = new LegacyRandom(options.seed) const ctx: PlacementContext = { placements: [], features: [], diff --git a/src/app/previews/NoiseSettings.ts b/src/app/previews/NoiseSettings.ts index 9fb94522..7890298e 100644 --- a/src/app/previews/NoiseSettings.ts +++ b/src/app/previews/NoiseSettings.ts @@ -82,7 +82,7 @@ function getCached(state: unknown, options: NoiseSettingsOptions) { cacheState = deepClone(newState) chunkCache = [] const biomeSource = new FixedBiome('unknown') - generatorCache = new NoiseChunkGenerator(options.seed, biomeSource, settings, shape) + generatorCache = new NoiseChunkGenerator(options.seed, biomeSource, settings) } return { settings, diff --git a/src/app/previews/NormalNoise.ts b/src/app/previews/NormalNoise.ts index 94ed2e24..aedc3e07 100644 --- a/src/app/previews/NormalNoise.ts +++ b/src/app/previews/NormalNoise.ts @@ -1,5 +1,5 @@ import { DataModel } from '@mcschema/core' -import { NoiseParameters, NormalNoise, Random } from 'deepslate' +import { LegacyRandom, NoiseParameters, NormalNoise } from 'deepslate' import type { VersionId } from '../Schemas' export type NoiseOptions = { @@ -10,7 +10,7 @@ export type NoiseOptions = { } export function normalNoise(state: any, img: ImageData, options: NoiseOptions) { - const random = new Random(options.seed) + const random = new LegacyRandom(options.seed) const params = NoiseParameters.fromJson(DataModel.unwrapLists(state)) const noise = new NormalNoise(random, params) diff --git a/src/app/previews/noise/NoiseChunkGenerator.ts b/src/app/previews/noise/NoiseChunkGenerator.ts index 054687fd..422685f4 100644 --- a/src/app/previews/noise/NoiseChunkGenerator.ts +++ b/src/app/previews/noise/NoiseChunkGenerator.ts @@ -1,4 +1,4 @@ -import { PerlinNoise, Random } from 'deepslate' +import { LegacyRandom, PerlinNoise } from 'deepslate' import { clampedLerp, lerp2 } from '../../Utils' export class NoiseChunkGenerator { @@ -18,7 +18,7 @@ export class NoiseChunkGenerator { private xOffset: number = 0 constructor(seed: bigint) { - const random = new Random(seed) + const random = new LegacyRandom(seed) this.minLimitPerlinNoise = new PerlinNoise(random, -15, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) this.maxLimitPerlinNoise = new PerlinNoise(random, -15, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) this.mainPerlinNoise = new PerlinNoise(random, -7, [1, 1, 1, 1, 1, 1, 1, 1]) diff --git a/src/locales/en.json b/src/locales/en.json index 2b7e82af..45232b7e 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -5,13 +5,16 @@ "advancement": "Advancement", "collapse": "Collapse", "collapse_all": "Hold %0% to collapse all", + "configure_layers": "Configure layers", "copy": "Copy", "copied": "Copied!", "copy_context": "Copy context", "dimension_type": "Dimension Type", "dimension": "Dimension", + "disabled": "Disabled", "download": "Download", "duplicate": "Duplicate", + "enabled": "Enabled", "entries_hidden": "%0% entries hidden", "entries_hidden.more": "Show %0% more", "entries_hidden.all": "Show all", @@ -31,6 +34,15 @@ "indentation.tabs": "Tabs", "item_modifier": "Item Modifier", "language": "Language", + "layer.biomes": "Biomes", + "layer.temperature": "Temperature", + "layer.humidity": "Humidity", + "layer.continentalness": "Continentalness", + "layer.erosion": "Erosion", + "layer.weirdness": "Weirdness", + "layer.offset": "Offset", + "layer.factor": "Factor", + "layer.jaggedness": "Jaggedness", "loot_table": "Loot Table", "more": "More", "move_down": "Move down",