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'