Match vanilla placement height sampling

This commit is contained in:
Daniar Mannanov 2026-08-11 09:42:11 +03:00
parent e9fe526300
commit 674d0192c9
2 changed files with 30 additions and 7 deletions

View file

@ -176,18 +176,24 @@ func (p PlacementPlan) SampleY(r RandomSource, minY, height int) int {
} }
span := hi - lo + 1 span := hi - lo + 1
if p.HeightDistribution == "minecraft:trapezoid" { if p.HeightDistribution == "minecraft:trapezoid" {
plateau := 0 // Vanilla's TrapezoidHeight works with the inclusive range distance,
triangle := span - plateau // then performs two inclusive random draws around the midpoint.
return lo + int(r.NextIntN(int32((triangle+1)/2))) + int(r.NextIntN(int32(triangle/2+1))) rangeSize := span - 1
if rangeSize <= 0 {
return lo
}
left := rangeSize / 2
right := rangeSize - left
return lo + int(r.NextIntN(int32(right+1))) + int(r.NextIntN(int32(left+1)))
} }
if p.HeightDistribution == "minecraft:very_biased_to_bottom" { if p.HeightDistribution == "minecraft:very_biased_to_bottom" {
const inner = 8 const inner = 8
outer := span - inner + 1 if span-inner <= 0 {
if outer <= 0 {
return lo return lo
} }
bound := int(r.NextIntN(int32(outer))) + inner first := lo + inner + int(r.NextIntN(int32(span-inner)))
return lo + int(r.NextIntN(int32(bound))) second := lo + int(r.NextIntN(int32(first-lo)))
return lo + int(r.NextIntN(int32(second-lo+inner)))
} }
return lo + int(r.NextIntN(int32(span))) return lo + int(r.NextIntN(int32(span)))
} }

View file

@ -80,3 +80,20 @@ func TestFeatureStepsRejectsCycles(t *testing.T) {
t.Fatal("cyclic feature order succeeded") t.Fatal("cyclic feature order succeeded")
} }
} }
func TestPlacementHeightDistributionsStayWithinInclusiveBounds(t *testing.T) {
r := NewLegacy(12345)
for _, distribution := range []string{"minecraft:trapezoid", "minecraft:very_biased_to_bottom", "minecraft:uniform"} {
plan := PlacementPlan{
HeightDistribution: distribution,
MinY: HeightProvider{Absolute: intPtr(-20)},
MaxY: HeightProvider{Absolute: intPtr(20)},
}
for i := 0; i < 1000; i++ {
got := plan.SampleY(r, -64, 384)
if got < -20 || got > 20 {
t.Fatalf("%s sample %d outside [-20,20]: %d", distribution, i, got)
}
}
}
}