781b01c2bf
Menambahkan bypas nama gwa Nambahkan ban/unban/ban list menambahkan world clasik ringan
114 lines
3.4 KiB
Go
114 lines
3.4 KiB
Go
package generator
|
|
|
|
import (
|
|
"math"
|
|
|
|
"github.com/df-mc/dragonfly/server/block"
|
|
"github.com/df-mc/dragonfly/server/block/cube"
|
|
"github.com/df-mc/dragonfly/server/world"
|
|
"github.com/df-mc/dragonfly/server/world/biome"
|
|
"github.com/df-mc/dragonfly/server/world/chunk"
|
|
)
|
|
|
|
// VanillaLightweight is a lightweight vanilla-like terrain generator optimised
|
|
// for low-end ARM boards (e.g. Armbian H680P). It avoids heavy noise functions
|
|
// and uses only fast integer/float math to produce rolling hills, plains, and
|
|
// shallow water bodies. Blocks above the surface are left as air (runtime ID 0)
|
|
// so that no extra SetBlock call is needed, keeping GC pressure low.
|
|
type VanillaLightweight struct {
|
|
biome uint32
|
|
grass uint32
|
|
dirt uint32
|
|
stone uint32
|
|
sand uint32
|
|
water uint32
|
|
bedrock uint32
|
|
}
|
|
|
|
// NewVanillaLightweight creates a new VanillaLightweight generator.
|
|
func NewVanillaLightweight(br world.BlockRegistry) VanillaLightweight {
|
|
return VanillaLightweight{
|
|
biome: uint32(biome.Plains{}.EncodeBiome()),
|
|
grass: br.BlockRuntimeID(block.Grass{}),
|
|
dirt: br.BlockRuntimeID(block.Dirt{}),
|
|
stone: br.BlockRuntimeID(block.Stone{}),
|
|
sand: br.BlockRuntimeID(block.Sand{}),
|
|
water: br.BlockRuntimeID(block.Water{Still: true, Depth: 8}),
|
|
bedrock: br.BlockRuntimeID(block.Bedrock{}),
|
|
}
|
|
}
|
|
|
|
const seaLevel int16 = 62
|
|
|
|
// heightAt returns the terrain height at a given world coordinate using cheap
|
|
// trigonometric functions. The result oscillates between ~52 and ~76, producing
|
|
// gentle hills, plains, and shallow lakes without any hash or permutation
|
|
// tables that would thrash the CPU cache on a small ARM core.
|
|
func heightAt(wx, wz float64) int16 {
|
|
h := 64.0 +
|
|
8.0*math.Sin(wx*0.0157)*math.Cos(wz*0.0157) +
|
|
4.0*math.Sin(wx*0.0341+wz*0.0271) +
|
|
2.0*math.Cos(wx*0.083)*math.Sin(wz*0.083)
|
|
return int16(h)
|
|
}
|
|
|
|
// GenerateChunk generates a single chunk.
|
|
func (v VanillaLightweight) GenerateChunk(pos world.ChunkPos, c *chunk.Chunk) {
|
|
min := int16(c.Range().Min())
|
|
cx, cz := int32(pos.X())<<4, int32(pos.Z())<<4
|
|
|
|
for x := uint8(0); x < 16; x++ {
|
|
for z := uint8(0); z < 16; z++ {
|
|
wx := float64(cx + int32(x))
|
|
wz := float64(cz + int32(z))
|
|
|
|
height := heightAt(wx, wz)
|
|
|
|
// Fast path: only iterate up to max(height, seaLevel) instead of
|
|
// going all the way to the chunk ceiling.
|
|
top := height
|
|
if seaLevel > top {
|
|
top = seaLevel
|
|
}
|
|
|
|
for y := min; y <= top; y++ {
|
|
c.SetBiome(x, y, z, v.biome)
|
|
|
|
switch {
|
|
case y == min:
|
|
c.SetBlock(x, y, z, 0, v.bedrock)
|
|
case y < height-3:
|
|
c.SetBlock(x, y, z, 0, v.stone)
|
|
case y < height:
|
|
c.SetBlock(x, y, z, 0, v.dirt)
|
|
case y == height:
|
|
if height < seaLevel-1 {
|
|
// Underwater floor → sand.
|
|
c.SetBlock(x, y, z, 0, v.sand)
|
|
} else {
|
|
c.SetBlock(x, y, z, 0, v.grass)
|
|
}
|
|
default:
|
|
// y > height && y <= seaLevel → water.
|
|
if y <= seaLevel {
|
|
c.SetBlock(x, y, z, 0, v.water)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set biome for a few sub-chunks above the terrain so the client
|
|
// shows the correct biome colour for sky/fog without iterating the
|
|
// entire column up to max.
|
|
for y := top + 1; y <= top+16 && y <= int16(c.Range().Max()); y++ {
|
|
c.SetBiome(x, y, z, v.biome)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// DefaultSpawn returns a fixed, safe spawn position on solid ground at 0, 0.
|
|
func (v VanillaLightweight) DefaultSpawn(dim world.Dimension) cube.Pos {
|
|
h := heightAt(0, 0)
|
|
return cube.Pos{0, int(h) + 1, 0}
|
|
}
|