forked from huin/chunkymonkey
/
block_sapling.go
87 lines (75 loc) · 2.54 KB
/
block_sapling.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package gamerules
import (
. "chunkymonkey/types"
"log"
"math/rand"
)
// Behaviour of a sapling block, takes care of growing or dying depending on
// world conditions.
func makeSaplingAspect() (aspect IBlockAspect) {
return &SaplingAspect{}
}
type SaplingAspect struct {
StandardAspect
}
func (aspect *SaplingAspect) Name() string {
return "Sapling"
}
func (aspect *SaplingAspect) Tick(instance *BlockInstance) bool {
// TODO: Use a random number that is reproduceable from merely the chunk
// location so that the world seed produces consistent worlds.
if rand.Intn(1e4) >= 1e4-1 {
// Turn this block into a tree
return aspect.makeTree(instance)
}
return true
}
func (aspect *SaplingAspect) makeTree(instance *BlockInstance) bool {
loc := instance.SubLoc
minheight := 3
maxheight := 6
height := minheight + rand.Intn(maxheight-minheight)
maxy := loc.Y + SubChunkCoord(height)
for y := loc.Y; y < maxy; y++ {
loc.Y = y
index, ok := loc.BlockIndex()
if !ok {
// TODO: Can't place a block outside chunk boundaries
log.Printf("Couldn't place a tree block (%v,%v,%v)", loc.X, loc.Y, loc.Z)
} else {
instance.Chunk.SetBlockByIndex(index, BlockId(17), byte(0))
}
}
// Store the location at the top block of the tree
treex, treey, treez := int(loc.X), int(loc.Y), int(loc.Z)
cradius := height / 2
// Start one block above the tree and move down
for y := treey + 1; y >= treey-1; y-- {
var radius int
// Slightly round out the canopy
if y > treey {
radius = cradius - 1
} else if y == treey {
radius = cradius
} else if y < treey {
radius = cradius - 1
}
for x := treex - radius; x <= treex+radius; x++ {
for z := treez - radius; z <= treez+radius; z++ {
if y > treey || x != treex || z != treez {
loc.X = SubChunkCoord(x)
loc.Y = SubChunkCoord(y)
loc.Z = SubChunkCoord(z)
index, ok := loc.BlockIndex()
if !ok {
// TODO: Can't place a block outside chunk boundaries
log.Printf("Couldn't place a leaf block (%v,%v,%v)", loc.X, loc.Y, loc.Z)
} else {
instance.Chunk.SetBlockByIndex(index, BlockId(18), byte(0))
}
}
}
}
}
return true
}