diff --git a/src/app/DataFetcher.ts b/src/app/DataFetcher.ts
index e6546796..81468acc 100644
--- a/src/app/DataFetcher.ts
+++ b/src/app/DataFetcher.ts
@@ -156,6 +156,9 @@ async function fetchDynamicRegistries(version: Version, target: CollectionRegist
console.warn('Error occurred while fetching dynamic registries:', message(e))
}
}
+ if (checkVersion(version.id, '1.18')) {
+ target.register('worldgen/noise', Noises)
+ }
}
export async function fetchPreset(version: VersionId, registry: string, id: string) {
@@ -252,3 +255,58 @@ async function deleteMatching(matches: (url: string) => boolean) {
console.warn(`[deleteMatching] Failed to open cache ${CACHE_NAME}: ${message(e)}`)
}
}
+
+const Noises = [
+ 'minecraft:aquifer_barrier',
+ 'minecraft:aquifer_fluid_level_floodedness',
+ 'minecraft:aquifer_fluid_level_spread',
+ 'minecraft:aquifer_lava',
+ 'minecraft:calcite',
+ 'minecraft:cave_cheese',
+ 'minecraft:cave_entrance',
+ 'minecraft:cave_layer',
+ 'minecraft:clay_bands_offset',
+ 'minecraft:continentalness',
+ 'minecraft:erosion',
+ 'minecraft:gravel',
+ 'minecraft:gravel_layer',
+ 'minecraft:ice',
+ 'minecraft:iceberg_and_badlands_pillar',
+ 'minecraft:iceberg_and_badlands_pillar_roof',
+ 'minecraft:jagged',
+ 'minecraft:nether_state_selector',
+ 'minecraft:nether_wart',
+ 'minecraft:netherrack',
+ 'minecraft:noodle',
+ 'minecraft:noodle_ridge_a',
+ 'minecraft:noodle_ridge_b',
+ 'minecraft:noodle_thickness',
+ 'minecraft:offset',
+ 'minecraft:ore_gap',
+ 'minecraft:ore_vein_a',
+ 'minecraft:ore_vein_b',
+ 'minecraft:ore_veininess',
+ 'minecraft:packed_ice',
+ 'minecraft:patch',
+ 'minecraft:pillar',
+ 'minecraft:pillar_rareness',
+ 'minecraft:pillar_thickness',
+ 'minecraft:powder_snow_surface',
+ 'minecraft:powder_snow_under',
+ 'minecraft:ridge',
+ 'minecraft:soul_sand_layer',
+ 'minecraft:spaghetti_2d',
+ 'minecraft:spaghetti_2d_elevation',
+ 'minecraft:spaghetti_2d_modulator',
+ 'minecraft:spaghetti_2d_thickness',
+ 'minecraft:spaghetti_3d_1',
+ 'minecraft:spaghetti_3d_2',
+ 'minecraft:spaghetti_3d_rarity',
+ 'minecraft:spaghetti_3d_thickness',
+ 'minecraft:spaghetti_roughness',
+ 'minecraft:spaghetti_roughness_modulator',
+ 'minecraft:surface',
+ 'minecraft:surface_swamp',
+ 'minecraft:temperature',
+ 'minecraft:vegetation',
+]
diff --git a/src/app/components/generator/PreviewPanel.tsx b/src/app/components/generator/PreviewPanel.tsx
index dd854adc..4c0689cf 100644
--- a/src/app/components/generator/PreviewPanel.tsx
+++ b/src/app/components/generator/PreviewPanel.tsx
@@ -3,9 +3,9 @@ import { Path } from '@mcschema/core'
import { useState } from 'preact/hooks'
import { useModel } from '../../hooks'
import type { VersionId } from '../../Schemas'
-import { BiomeSourcePreview, DecoratorPreview, NoiseSettingsPreview } from '../previews'
+import { BiomeSourcePreview, DecoratorPreview, NoisePreview, NoiseSettingsPreview } from '../previews'
-export const HasPreview = ['dimension', 'worldgen/noise_settings', 'worldgen/configured_feature']
+export const HasPreview = ['dimension', 'worldgen/noise', 'worldgen/noise_settings', 'worldgen/configured_feature']
type PreviewPanelProps = {
lang: string,
@@ -27,6 +27,11 @@ export function PreviewPanel({ lang, model, version, id, shown }: PreviewPanelPr
if (data) return
}
+ if (id === 'worldgen/noise' && model) {
+ const data = model.get(new Path([]))
+ if (data) return
+ }
+
if (id === 'worldgen/noise_settings' && model) {
const data = model.get(new Path([]))
if (data) return
diff --git a/src/app/components/previews/NoisePreview.tsx b/src/app/components/previews/NoisePreview.tsx
new file mode 100644
index 00000000..72d15aaf
--- /dev/null
+++ b/src/app/components/previews/NoisePreview.tsx
@@ -0,0 +1,53 @@
+import { useEffect, useRef, useState } from 'preact/hooks'
+import type { PreviewProps } from '.'
+import { Btn } from '..'
+import { useCanvas } from '../../hooks'
+import { locale } from '../../Locales'
+import { normalNoise } from '../../previews'
+import { randomSeed } from '../../Utils'
+
+export const NoisePreview = ({ lang, data, shown, version }: PreviewProps) => {
+ const [seed, setSeed] = useState(randomSeed())
+ const [scale, setScale] = useState(2)
+ const offset = useRef<[number, number]>([0, 0])
+ const state = JSON.stringify([data])
+
+ const { canvas, redraw } = useCanvas({
+ size() {
+ return [256, 256]
+ },
+ async draw(img) {
+ const options = { offset: offset.current, scale, seed, version }
+ normalNoise(data, img, options)
+ },
+ async onDrag(dx, dy) {
+ offset.current[0] = offset.current[0] + dx * 256
+ offset.current[1] = offset.current[1] + dy * 256
+ redraw()
+ },
+ }, [state, scale, seed])
+
+ useEffect(() => {
+ if (shown) {
+ redraw()
+ }
+ }, [state, scale, seed, shown])
+
+ const changeScale = (newScale: number) => {
+ offset.current[0] = offset.current[0] * scale / newScale
+ offset.current[1] = offset.current[1] * scale / newScale
+ setScale(newScale)
+ }
+
+ return <>
+
+ changeScale(scale * 1.5)} />
+ changeScale(scale / 1.5)} />
+ setSeed(randomSeed())} />
+
+
+ >
+}
diff --git a/src/app/components/previews/index.ts b/src/app/components/previews/index.ts
index 15e6975d..4cafa253 100644
--- a/src/app/components/previews/index.ts
+++ b/src/app/components/previews/index.ts
@@ -3,6 +3,7 @@ import type { VersionId } from '../../Schemas'
export * from './BiomeSourcePreview'
export * from './DecoratorPreview'
+export * from './NoisePreview'
export * from './NoiseSettingsPreview'
export type PreviewProps = {
diff --git a/src/app/previews/NormalNoise.ts b/src/app/previews/NormalNoise.ts
new file mode 100644
index 00000000..94ed2e24
--- /dev/null
+++ b/src/app/previews/NormalNoise.ts
@@ -0,0 +1,32 @@
+import { DataModel } from '@mcschema/core'
+import { NoiseParameters, NormalNoise, Random } from 'deepslate'
+import type { VersionId } from '../Schemas'
+
+export type NoiseOptions = {
+ offset: [number, number],
+ scale: number,
+ seed: bigint,
+ version: VersionId,
+}
+
+export function normalNoise(state: any, img: ImageData, options: NoiseOptions) {
+ const random = new Random(options.seed)
+ const params = NoiseParameters.fromJson(DataModel.unwrapLists(state))
+ const noise = new NormalNoise(random, params)
+
+ const ox = -options.offset[0] - 100
+ const oz = -options.offset[1] - 100
+ const data = img.data
+ for (let x = 0; x < 256; x += 1) {
+ for (let y = 0; y < 256; y += 1) {
+ const i = x * 4 + y * 4 * 256
+ const xx = (x + ox) * options.scale
+ const yy = (y + oz) * options.scale
+ const color = (noise.sample(xx, yy, 0) + 1) * 128
+ data[i] = color
+ data[i + 1] = color
+ data[i + 2] = color
+ data[i + 3] = 255
+ }
+ }
+}
diff --git a/src/app/previews/index.ts b/src/app/previews/index.ts
index 613ca206..b1102f26 100644
--- a/src/app/previews/index.ts
+++ b/src/app/previews/index.ts
@@ -1,3 +1,4 @@
export * from './BiomeSource'
export * from './Decorator'
export * from './NoiseSettings'
+export * from './NormalNoise'