mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-23 15:17:09 +00:00
Start configured feature visualizer
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { DataModel } from '@mcschema/core'
|
||||
import type { BlockPos, ChunkPos, PerlinNoise, Random } from 'deepslate/worldgen'
|
||||
import type { Color } from '../../Utils.js'
|
||||
import { clamp, isObject, stringToColor } from '../../Utils.js'
|
||||
import { clamp, stringToColor } from '../../Utils.js'
|
||||
import type { VersionId } from '../../services/index.js'
|
||||
import { checkVersion } from '../../services/index.js'
|
||||
import { normalizeId, sampleHeight, sampleInt } from './WorldgenUtils.jsx'
|
||||
|
||||
export type Placement = [BlockPos, number]
|
||||
|
||||
@@ -54,90 +55,10 @@ export function decorateChunk(pos: ChunkPos, state: any, ctx: PlacementContext):
|
||||
})
|
||||
}
|
||||
|
||||
function normalize(id: string) {
|
||||
return id.startsWith('minecraft:') ? id.slice(10) : id
|
||||
}
|
||||
|
||||
function decorateY(pos: BlockPos, y: number): BlockPos[] {
|
||||
return [[ pos[0], y, pos[2] ]]
|
||||
}
|
||||
|
||||
export function sampleInt(value: any, ctx: PlacementContext): number {
|
||||
if (typeof value === 'number') {
|
||||
return value
|
||||
} else if (value.base) {
|
||||
return value.base ?? 1 + ctx.nextInt(1 + (value.spread ?? 0))
|
||||
} else {
|
||||
switch (normalize(value.type)) {
|
||||
case 'constant': return value.value
|
||||
case 'uniform': return value.value.min_inclusive + ctx.nextInt(value.value.max_inclusive - value.value.min_inclusive + 1)
|
||||
case 'biased_to_bottom': return value.value.min_inclusive + ctx.nextInt(ctx.nextInt(value.value.max_inclusive - value.value.min_inclusive + 1) + 1)
|
||||
case 'clamped': return clamp(sampleInt(value.value.source, ctx), value.value.min_inclusive, value.value.max_inclusive)
|
||||
case 'clamped_normal':
|
||||
const normal = value.value.mean + ctx.nextGaussian() * value.value.deviation
|
||||
return Math.floor(clamp(value.value.min_inclusive, value.value.max_inclusive, normal))
|
||||
case 'weighted_list':
|
||||
const totalWeight = (value.distribution as any[]).reduce<number>((sum, e) => sum + e.weight, 0)
|
||||
let i = ctx.nextInt(totalWeight)
|
||||
for (const e of value.distribution) {
|
||||
i -= e.weight
|
||||
if (i < 0) return sampleInt(e.data, ctx)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
function resolveAnchor(anchor: any, _ctx: PlacementContext): number {
|
||||
if (!isObject(anchor)) return 0
|
||||
if (anchor.absolute !== undefined) return anchor.absolute
|
||||
if (anchor.above_bottom !== undefined) return anchor.above_bottom
|
||||
if (anchor.below_top !== undefined) return 256 - anchor.below_top
|
||||
return 0
|
||||
}
|
||||
|
||||
function sampleHeight(height: any, ctx: PlacementContext): number {
|
||||
if (!isObject(height)) throw new Error('Invalid height provider')
|
||||
if (typeof height.type !== 'string') {
|
||||
return resolveAnchor(height, ctx)
|
||||
}
|
||||
switch (normalize(height.type)) {
|
||||
case 'constant': return resolveAnchor(height.value, ctx)
|
||||
case 'uniform': {
|
||||
const min = resolveAnchor(height.min_inclusive, ctx)
|
||||
const max = resolveAnchor(height.max_inclusive, ctx)
|
||||
return min + ctx.nextInt(max - min + 1)
|
||||
}
|
||||
case 'biased_to_bottom': {
|
||||
const min = resolveAnchor(height.min_inclusive, ctx)
|
||||
const max = resolveAnchor(height.max_inclusive, ctx)
|
||||
const n = ctx.nextInt(max - min - (height.inner ?? 1) + 1)
|
||||
return min + ctx.nextInt(n + (height.inner ?? 1))
|
||||
}
|
||||
case 'very_biased_to_bottom': {
|
||||
const min = resolveAnchor(height.min_inclusive, ctx)
|
||||
const max = resolveAnchor(height.max_inclusive, ctx)
|
||||
const inner = height.inner ?? 1
|
||||
const n1 = min + inner + ctx.nextInt(max - min - inner + 1)
|
||||
const n2 = min + ctx.nextInt(n1 - min)
|
||||
return min + ctx.nextInt(n2 - min + inner)
|
||||
}
|
||||
case 'trapezoid': {
|
||||
const min = resolveAnchor(height.min_inclusive, ctx)
|
||||
const max = resolveAnchor(height.max_inclusive, ctx)
|
||||
const plateau = height.plateau ?? 0
|
||||
if (plateau >= max - min) {
|
||||
return min + ctx.nextInt(max - min + 1)
|
||||
}
|
||||
const n1 = (max - min - plateau) / 2
|
||||
const n2 = (max - min) - n1
|
||||
return min + ctx.nextInt(n2 + 1) + ctx.nextInt(n1 + 1)
|
||||
}
|
||||
default: throw new Error(`Invalid height provider ${height.type}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 1.17 and before
|
||||
function useFeature(s: string, ctx: PlacementContext) {
|
||||
const i = ctx.features.indexOf(s)
|
||||
@@ -151,7 +72,7 @@ function getPlacements(pos: BlockPos, feature: any, ctx: PlacementContext): void
|
||||
ctx.placements.push([pos, useFeature(feature, ctx)])
|
||||
return
|
||||
}
|
||||
const type = normalize(feature?.type ?? 'no_op')
|
||||
const type = normalizeId(feature?.type ?? 'no_op')
|
||||
const featureFn = Features[type]
|
||||
if (featureFn) {
|
||||
featureFn(feature.config, pos, ctx)
|
||||
@@ -161,7 +82,7 @@ function getPlacements(pos: BlockPos, feature: any, ctx: PlacementContext): void
|
||||
}
|
||||
|
||||
function getPositions(pos: BlockPos, decorator: any, ctx: PlacementContext): BlockPos[] {
|
||||
const type = normalize(decorator?.type ?? 'nope')
|
||||
const type = normalizeId(decorator?.type ?? 'nope')
|
||||
const decoratorFn = Decorators[type]
|
||||
if (!decoratorFn) {
|
||||
return [pos]
|
||||
@@ -357,10 +278,10 @@ const Decorators: {
|
||||
function modifyPlacement(pos: BlockPos, placement: any[], ctx: PlacementContext) {
|
||||
let positions = [pos]
|
||||
for (const modifier of placement) {
|
||||
const modifierFn = PlacementModifiers[normalize(modifier?.type ?? 'nope')]
|
||||
const modifierFn = PlacementModifiers[normalizeId(modifier?.type ?? 'nope')]
|
||||
if (!modifierFn) continue
|
||||
positions = positions.flatMap(pos =>
|
||||
PlacementModifiers[normalize(modifier.type)](modifier, pos, ctx)
|
||||
PlacementModifiers[normalizeId(modifier.type)](modifier, pos, ctx)
|
||||
)
|
||||
}
|
||||
for (const pos of positions) {
|
||||
|
||||
Reference in New Issue
Block a user