worldgen water, fixes
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								internal/asset/texture/world/planks_oak.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								internal/asset/texture/world/planks_oak.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 268 B  | 
							
								
								
									
										
											BIN
										
									
								
								internal/asset/texture/world/water.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								internal/asset/texture/world/water.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 411 B  | 
@@ -47,8 +47,8 @@ func (g *Game) Init(win *glfw.Window) {
 | 
				
			|||||||
	var seed int64 = time.Now().Unix()
 | 
						var seed int64 = time.Now().Unix()
 | 
				
			||||||
	gensync := make(chan struct{})
 | 
						gensync := make(chan struct{})
 | 
				
			||||||
	gensynccnt := 0
 | 
						gensynccnt := 0
 | 
				
			||||||
	for i := -4; i <= 4; i++ {
 | 
						for i := -8; i <= 8; i++ {
 | 
				
			||||||
		for j := -4; j <= 4; j++ {
 | 
							for j := -8; j <= 8; j++ {
 | 
				
			||||||
			c := &world.Chunk{}
 | 
								c := &world.Chunk{}
 | 
				
			||||||
			g.world.SetChunk(i, j, c)
 | 
								g.world.SetChunk(i, j, c)
 | 
				
			||||||
			go func() {
 | 
								go func() {
 | 
				
			||||||
@@ -68,7 +68,7 @@ func (g *Game) Init(win *glfw.Window) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	io.DisplaySize[0], io.DisplaySize[1] = win.GetFramebufferSize()
 | 
						io.DisplaySize[0], io.DisplaySize[1] = win.GetFramebufferSize()
 | 
				
			||||||
	win.SetSizeCallback(func(w *glfw.Window, width, height int) {
 | 
						win.SetSizeCallback(func(w *glfw.Window, width, height int) {
 | 
				
			||||||
		win.SetCursorPos(float64(width)/2, float64(height)/2)
 | 
							//win.SetCursorPos(float64(width)/2, float64(height)/2)
 | 
				
			||||||
		g.view.Aspect(float32(width) / float32(height))
 | 
							g.view.Aspect(float32(width) / float32(height))
 | 
				
			||||||
		io.DisplaySize = itype.Vec2i{width, height}
 | 
							io.DisplaySize = itype.Vec2i{width, height}
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,10 @@ func (v Vec3i) ToFloat64() Vec3d { return Vec3d{float64(v[0]), float64(v[1]), fl
 | 
				
			|||||||
func (v Vec3i) Add(add Vec3i) Vec3i         { return Vec3i{v[0] + add[0], v[1] + add[1], v[2] + add[2]} }
 | 
					func (v Vec3i) Add(add Vec3i) Vec3i         { return Vec3i{v[0] + add[0], v[1] + add[1], v[2] + add[2]} }
 | 
				
			||||||
func (v Vec3i) Addv(x, y, z int) Vec3i      { return Vec3i{v[0] + x, v[1] + y, v[2] + z} }
 | 
					func (v Vec3i) Addv(x, y, z int) Vec3i      { return Vec3i{v[0] + x, v[1] + y, v[2] + z} }
 | 
				
			||||||
func (v Vec3i) MultiplyInt(mult int) Vec3i  { return Vec3i{v[0] * mult, v[1] * mult, v[2] * mult} }
 | 
					func (v Vec3i) MultiplyInt(mult int) Vec3i  { return Vec3i{v[0] * mult, v[1] * mult, v[2] * mult} }
 | 
				
			||||||
 | 
					func (v Vec3i) Multiplyv(x, y, z int) Vec3i { return Vec3i{v[0] * x, v[1] * y, v[2] * z} }
 | 
				
			||||||
 | 
					func (v Vec3i) Multiply(mult Vec3i) Vec3i {
 | 
				
			||||||
 | 
						return Vec3i{v[0] * mult[0], v[1] * mult[1], v[2] * mult[2]}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Vec4i is a four-element int vector
 | 
					// Vec4i is a four-element int vector
 | 
				
			||||||
type Vec4i [4]int
 | 
					type Vec4i [4]int
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,7 @@ type BlockAppearance struct {
 | 
				
			|||||||
		position itype.Vec3i,
 | 
							position itype.Vec3i,
 | 
				
			||||||
		aux int,
 | 
							aux int,
 | 
				
			||||||
		data itype.Dataset,
 | 
							data itype.Dataset,
 | 
				
			||||||
 | 
							world *World,
 | 
				
			||||||
		vertexArray []Vertex,
 | 
							vertexArray []Vertex,
 | 
				
			||||||
	) []Vertex
 | 
						) []Vertex
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -59,7 +60,7 @@ type BlockBehaviour interface {
 | 
				
			|||||||
	// with Minor ID aux, and Dataset data.
 | 
						// with Minor ID aux, and Dataset data.
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
	// If RequireDataset if false, data is nil.
 | 
						// If RequireDataset if false, data is nil.
 | 
				
			||||||
	Appearance(position itype.Vec3i, aux int, data itype.Dataset) BlockAppearance
 | 
						Appearance(position itype.Vec3i, aux int, data itype.Dataset, world *World) BlockAppearance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// BlockUpdate is called when RequireBlockUpdate is true and the block at
 | 
						// BlockUpdate is called when RequireBlockUpdate is true and the block at
 | 
				
			||||||
	// global position Position, with Minor ID aux, and Dataset data has a neighbor
 | 
						// global position Position, with Minor ID aux, and Dataset data has a neighbor
 | 
				
			||||||
@@ -68,7 +69,7 @@ type BlockBehaviour interface {
 | 
				
			|||||||
	// If RequireDataset if false, data is nil.
 | 
						// If RequireDataset if false, data is nil.
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
	// Return true if this block also changed state, false otherwise.
 | 
						// Return true if this block also changed state, false otherwise.
 | 
				
			||||||
	BlockUpdate(position itype.Vec3i, aux int, data itype.Dataset) bool
 | 
						BlockUpdate(position itype.Vec3i, aux int, data itype.Dataset, world *World) bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type blockBehaviourStatic struct {
 | 
					type blockBehaviourStatic struct {
 | 
				
			||||||
@@ -78,10 +79,10 @@ type blockBehaviourStatic struct {
 | 
				
			|||||||
func (blockBehaviourStatic) Static() bool             { return true }
 | 
					func (blockBehaviourStatic) Static() bool             { return true }
 | 
				
			||||||
func (blockBehaviourStatic) RequireDataset() bool     { return false }
 | 
					func (blockBehaviourStatic) RequireDataset() bool     { return false }
 | 
				
			||||||
func (blockBehaviourStatic) RequireBlockUpdate() bool { return false }
 | 
					func (blockBehaviourStatic) RequireBlockUpdate() bool { return false }
 | 
				
			||||||
func (b blockBehaviourStatic) Appearance(position itype.Vec3i, aux int, data itype.Dataset) BlockAppearance {
 | 
					func (b blockBehaviourStatic) Appearance(position itype.Vec3i, aux int, data itype.Dataset, world *World) BlockAppearance {
 | 
				
			||||||
	return b.app
 | 
						return b.app
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (blockBehaviourStatic) BlockUpdate(position itype.Vec3i, aux int, data itype.Dataset) bool {
 | 
					func (blockBehaviourStatic) BlockUpdate(position itype.Vec3i, aux int, data itype.Dataset, world *World) bool {
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -112,7 +113,7 @@ func RegisterBlockBehaviour(id int, b BlockBehaviour) bool {
 | 
				
			|||||||
func DoneRegisteringBlockBehaviour() {
 | 
					func DoneRegisteringBlockBehaviour() {
 | 
				
			||||||
	for id, b := range behaviour {
 | 
						for id, b := range behaviour {
 | 
				
			||||||
		if b.Static() {
 | 
							if b.Static() {
 | 
				
			||||||
			appearance[id] = b.Appearance(itype.Vec3i{}, 0, nil)
 | 
								appearance[id] = b.Appearance(itype.Vec3i{}, 0, nil, nil)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,7 +121,7 @@ func DoneRegisteringBlockBehaviour() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetBlockAppearance gets the block appearance of the given block in the fastest way possible.
 | 
					// GetBlockAppearance gets the block appearance of the given block in the fastest way possible.
 | 
				
			||||||
func GetBlockAppearance(position itype.Vec3i, id, aux int, data itype.Dataset) BlockAppearance {
 | 
					func GetBlockAppearance(position itype.Vec3i, id, aux int, data itype.Dataset, world *World) BlockAppearance {
 | 
				
			||||||
	if app, ok := appearance[id]; ok { // Cache
 | 
						if app, ok := appearance[id]; ok { // Cache
 | 
				
			||||||
		if app.Hitbox == (itype.Boxd{}) {
 | 
							if app.Hitbox == (itype.Boxd{}) {
 | 
				
			||||||
			app.Hitbox = itype.Boxd{
 | 
								app.Hitbox = itype.Boxd{
 | 
				
			||||||
@@ -137,7 +138,7 @@ func GetBlockAppearance(position itype.Vec3i, id, aux int, data itype.Dataset) B
 | 
				
			|||||||
		panic(fmt.Sprint("invalid block type ", id))
 | 
							panic(fmt.Sprint("invalid block type ", id))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	app := b.Appearance(position, aux, data)
 | 
						app := b.Appearance(position, aux, data, world)
 | 
				
			||||||
	if app.Hitbox == (itype.Boxd{}) {
 | 
						if app.Hitbox == (itype.Boxd{}) {
 | 
				
			||||||
		app.Hitbox = itype.Boxd{
 | 
							app.Hitbox = itype.Boxd{
 | 
				
			||||||
			OffX: 0, OffY: 0, OffZ: 0,
 | 
								OffX: 0, OffY: 0, OffZ: 0,
 | 
				
			||||||
@@ -157,12 +158,13 @@ type Block struct {
 | 
				
			|||||||
	Id, Aux   int
 | 
						Id, Aux   int
 | 
				
			||||||
	Dataset   itype.Dataset
 | 
						Dataset   itype.Dataset
 | 
				
			||||||
	Behaviour BlockBehaviour
 | 
						Behaviour BlockBehaviour
 | 
				
			||||||
 | 
						World     *World
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Appearance is a shortcut for Behaviour.Appearance().
 | 
					// Appearance is a shortcut for Behaviour.Appearance().
 | 
				
			||||||
// It returns the Appearance of the block with the given parameters.
 | 
					// It returns the Appearance of the block with the given parameters.
 | 
				
			||||||
func (b *Block) Appearance(position itype.Vec3i) BlockAppearance {
 | 
					func (b Block) Appearance(position itype.Vec3i) BlockAppearance {
 | 
				
			||||||
	return b.Behaviour.Appearance(position, b.Aux, b.Dataset)
 | 
						return b.Behaviour.Appearance(position, b.Aux, b.Dataset, b.World)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BlockUpdate is a shortcut for Behaviour.BlockUpdate().
 | 
					// BlockUpdate is a shortcut for Behaviour.BlockUpdate().
 | 
				
			||||||
@@ -173,6 +175,6 @@ func (b *Block) Appearance(position itype.Vec3i) BlockAppearance {
 | 
				
			|||||||
// If RequireDataset if false, data is nil.
 | 
					// If RequireDataset if false, data is nil.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Return true if this block also changed state, false otherwise.
 | 
					// Return true if this block also changed state, false otherwise.
 | 
				
			||||||
func (b *Block) BlockUpdate(position itype.Vec3i) bool {
 | 
					func (b Block) BlockUpdate(position itype.Vec3i) bool {
 | 
				
			||||||
	return b.Behaviour.BlockUpdate(position, b.Aux, b.Dataset)
 | 
						return b.Behaviour.BlockUpdate(position, b.Aux, b.Dataset, b.World)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										49
									
								
								internal/world/blocks/default.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								internal/world/blocks/default.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					package blocks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "edgaru089.ml/go/gl01/internal/world"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						Nil = iota
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Debug
 | 
				
			||||||
 | 
						DebugDir
 | 
				
			||||||
 | 
						DebugNonexist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Stone
 | 
				
			||||||
 | 
						Dirt
 | 
				
			||||||
 | 
						Grass
 | 
				
			||||||
 | 
						Bedrock
 | 
				
			||||||
 | 
						Sand
 | 
				
			||||||
 | 
						LogOak
 | 
				
			||||||
 | 
						LeavesOak
 | 
				
			||||||
 | 
						PlanksOak
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Water
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Count
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(1, world.BlockBehaviourStatic(world.BlockAppearance{Name: "debug"}))
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(2, world.BlockBehaviourStatic(world.BlockAppearance{Name: "debug_dir", RenderType: world.SixTexture}))
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(3, world.BlockBehaviourStatic(world.BlockAppearance{Name: "debug_nonexist"}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(4, world.BlockBehaviourStatic(world.BlockAppearance{Name: "stone"}))
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(5, world.BlockBehaviourStatic(world.BlockAppearance{Name: "dirt"}))
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(6, world.BlockBehaviourStatic(world.BlockAppearance{Name: "grass", RenderType: world.ThreeTexture}))
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(7, world.BlockBehaviourStatic(world.BlockAppearance{Name: "bedrock"}))
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(8, world.BlockBehaviourStatic(world.BlockAppearance{Name: "sand"}))
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(9, world.BlockBehaviourStatic(world.BlockAppearance{Name: "log_oak", RenderType: world.ThreeTexture}))
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(10, world.BlockBehaviourStatic(world.BlockAppearance{Name: "leaves_oak"}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(11, world.BlockBehaviourStatic(world.BlockAppearance{Name: "planks_oak"}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						world.RegisterBlockBehaviour(12, WaterBehaviour{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if Count != 13 {
 | 
				
			||||||
 | 
							panic("world.DefaultBlocks: block count not correct (check for block numbering in default_blocks.go)")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						world.DoneRegisteringBlockBehaviour()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										78
									
								
								internal/world/blocks/helper_appendface.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								internal/world/blocks/helper_appendface.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					package blocks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"edgaru089.ml/go/gl01/internal/asset"
 | 
				
			||||||
 | 
						"edgaru089.ml/go/gl01/internal/util/itype"
 | 
				
			||||||
 | 
						"edgaru089.ml/go/gl01/internal/world"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// texname is the full filename of the texture file (with .png)
 | 
				
			||||||
 | 
					// faceOffset is added to each vertex
 | 
				
			||||||
 | 
					func appendFace(face itype.Direction, pos itype.Vec3i, texname string, faceOffset itype.Vec3f, arr []world.Vertex) []world.Vertex {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch face {
 | 
				
			||||||
 | 
						case itype.XPlus: // X+
 | 
				
			||||||
 | 
							arr = append(arr,
 | 
				
			||||||
 | 
								//     Vertex Position  Normal Vector(normalized)  Texture Coord  Light
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{1, 0, 0}, itype.Vec2f{1, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 1, 0).ToFloat32().Add(faceOffset), itype.Vec3f{1, 0, 0}, itype.Vec2f{1, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{1, 0, 0}, itype.Vec2f{0, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{1, 0, 0}, itype.Vec2f{1, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{1, 0, 0}, itype.Vec2f{0, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 0, 1).ToFloat32().Add(faceOffset), itype.Vec3f{1, 0, 0}, itype.Vec2f{0, 1}, 16},
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						case itype.XMinus: // X-
 | 
				
			||||||
 | 
							arr = append(arr,
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{-1, 0, 0}, itype.Vec2f{0, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{-1, 0, 0}, itype.Vec2f{1, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 1, 0).ToFloat32().Add(faceOffset), itype.Vec3f{-1, 0, 0}, itype.Vec2f{0, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{-1, 0, 0}, itype.Vec2f{0, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 0, 1).ToFloat32().Add(faceOffset), itype.Vec3f{-1, 0, 0}, itype.Vec2f{1, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{-1, 0, 0}, itype.Vec2f{1, 0}, 16},
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						case itype.YPlus: // Y+
 | 
				
			||||||
 | 
							arr = append(arr,
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 1, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, 1, 0}, itype.Vec2f{0, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, 1, 0}, itype.Vec2f{0, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 1, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, 1, 0}, itype.Vec2f{1, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, 1, 0}, itype.Vec2f{0, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, 1, 0}, itype.Vec2f{1, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 1, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, 1, 0}, itype.Vec2f{1, 0}, 16},
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						case itype.YMinus: // Y-
 | 
				
			||||||
 | 
							arr = append(arr,
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, -1, 0}, itype.Vec2f{1, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, -1, 0}, itype.Vec2f{0, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 0, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, -1, 0}, itype.Vec2f{0, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, -1, 0}, itype.Vec2f{1, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 0, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, -1, 0}, itype.Vec2f{0, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 0, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, -1, 0}, itype.Vec2f{1, 1}, 16},
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						case itype.ZPlus: // Z+
 | 
				
			||||||
 | 
							arr = append(arr,
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 0, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, 1}, itype.Vec2f{0, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 0, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, 1}, itype.Vec2f{1, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, 1}, itype.Vec2f{0, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, 1}, itype.Vec2f{1, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 1, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, 1}, itype.Vec2f{0, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 0, 1).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, 1}, itype.Vec2f{1, 1}, 16},
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						case itype.ZMinus: // Z-
 | 
				
			||||||
 | 
							arr = append(arr,
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, -1}, itype.Vec2f{1, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 1, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, -1}, itype.Vec2f{1, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 1, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, -1}, itype.Vec2f{0, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(0, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, -1}, itype.Vec2f{1, 1}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 1, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, -1}, itype.Vec2f{0, 0}, 16},
 | 
				
			||||||
 | 
								world.Vertex{pos.Addv(1, 0, 0).ToFloat32().Add(faceOffset), itype.Vec3f{0, 0, -1}, itype.Vec2f{0, 1}, 16},
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						texrect := asset.WorldTextureAtlas.RectNormalized(texname)
 | 
				
			||||||
 | 
						for i := len(arr) - 6; i < len(arr); i++ {
 | 
				
			||||||
 | 
							arr[i].Texture[0] = texrect.Left + arr[i].Texture[0]*texrect.Width
 | 
				
			||||||
 | 
							arr[i].Texture[1] = texrect.Top + arr[i].Texture[1]*texrect.Height
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return arr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								internal/world/blocks/water.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								internal/world/blocks/water.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					package blocks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"edgaru089.ml/go/gl01/internal/util/itype"
 | 
				
			||||||
 | 
						"edgaru089.ml/go/gl01/internal/world"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type WaterBehaviour struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (WaterBehaviour) Static() bool             { return false }
 | 
				
			||||||
 | 
					func (WaterBehaviour) RequireDataset() bool     { return false }
 | 
				
			||||||
 | 
					func (WaterBehaviour) RequireBlockUpdate() bool { return false }
 | 
				
			||||||
 | 
					func (b WaterBehaviour) Appearance(position itype.Vec3i, aux int, data itype.Dataset, w *world.World) world.BlockAppearance {
 | 
				
			||||||
 | 
						return world.BlockAppearance{
 | 
				
			||||||
 | 
							Name:        "water",
 | 
				
			||||||
 | 
							Transparent: true,
 | 
				
			||||||
 | 
							NotSolid:    true,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RenderType: world.CustomRendering,
 | 
				
			||||||
 | 
							CustomRenderAppend: func(
 | 
				
			||||||
 | 
								position itype.Vec3i,
 | 
				
			||||||
 | 
								aux int,
 | 
				
			||||||
 | 
								data itype.Dataset,
 | 
				
			||||||
 | 
								w *world.World,
 | 
				
			||||||
 | 
								vertexArray []world.Vertex) []world.Vertex {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if block := w.Block(position.Addv(0, 1, 0)); block.Id != Water {
 | 
				
			||||||
 | 
									return appendFace(itype.YPlus, position, "water.png", itype.Vec3f{0, -0.125, 0}, vertexArray)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return vertexArray
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (WaterBehaviour) BlockUpdate(position itype.Vec3i, aux int, data itype.Dataset, w *world.World) bool {
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -21,7 +21,13 @@ type Chunk struct {
 | 
				
			|||||||
	renderChanged bool
 | 
						renderChanged bool
 | 
				
			||||||
	vao, vbo      uint32
 | 
						vao, vbo      uint32
 | 
				
			||||||
	vbolen        int
 | 
						vbolen        int
 | 
				
			||||||
 | 
						water         struct {
 | 
				
			||||||
 | 
							vao, vbo uint32
 | 
				
			||||||
 | 
							vbolen   int
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	vertUpdate chan []Vertex
 | 
						vertUpdate chan []Vertex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						world *World
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Chunk) SetChunkID(x, z int) {
 | 
					func (c *Chunk) SetChunkID(x, z int) {
 | 
				
			||||||
@@ -30,8 +36,9 @@ func (c *Chunk) SetChunkID(x, z int) {
 | 
				
			|||||||
	c.renderChanged = true
 | 
						c.renderChanged = true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Chunk) SetBlock(x, y, z int, id int) {
 | 
					func (c *Chunk) SetBlock(x, y, z int, id, aux int) {
 | 
				
			||||||
	c.Id[x][y][z] = uint16(id)
 | 
						c.Id[x][y][z] = uint16(id)
 | 
				
			||||||
 | 
						c.Aux[x][y][z] = uint16(aux)
 | 
				
			||||||
	c.renderChanged = true
 | 
						c.renderChanged = true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,40 +0,0 @@
 | 
				
			|||||||
package world
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	BlockNil = iota
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	BlockDebug
 | 
					 | 
				
			||||||
	BlockDebugDir
 | 
					 | 
				
			||||||
	BlockDebugNonexist
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	BlockStone
 | 
					 | 
				
			||||||
	BlockDirt
 | 
					 | 
				
			||||||
	BlockGrass
 | 
					 | 
				
			||||||
	BlockBedrock
 | 
					 | 
				
			||||||
	BlockSand
 | 
					 | 
				
			||||||
	BlockLogOak
 | 
					 | 
				
			||||||
	BlockLeavesOak
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	BlockCount
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(1, BlockBehaviourStatic(BlockAppearance{Name: "debug"}))
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(2, BlockBehaviourStatic(BlockAppearance{Name: "debug_dir", RenderType: SixTexture}))
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(3, BlockBehaviourStatic(BlockAppearance{Name: "debug_nonexist"}))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(4, BlockBehaviourStatic(BlockAppearance{Name: "stone"}))
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(5, BlockBehaviourStatic(BlockAppearance{Name: "dirt"}))
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(6, BlockBehaviourStatic(BlockAppearance{Name: "grass", RenderType: ThreeTexture}))
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(7, BlockBehaviourStatic(BlockAppearance{Name: "bedrock"}))
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(8, BlockBehaviourStatic(BlockAppearance{Name: "sand"}))
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(9, BlockBehaviourStatic(BlockAppearance{Name: "log_oak", RenderType: ThreeTexture}))
 | 
					 | 
				
			||||||
	RegisterBlockBehaviour(10, BlockBehaviourStatic(BlockAppearance{Name: "leaves_oak"}))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if BlockCount != 11 {
 | 
					 | 
				
			||||||
		panic("world.DefaultBlocks: block count not correct (check for block numbering in default_blocks.go)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	DoneRegisteringBlockBehaviour()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -34,7 +34,7 @@ func (c *Chunk) InitRender() {
 | 
				
			|||||||
	gl.EnableVertexAttribArray(2)
 | 
						gl.EnableVertexAttribArray(2)
 | 
				
			||||||
	gl.EnableVertexAttribArray(3)
 | 
						gl.EnableVertexAttribArray(3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.vertUpdate = make(chan []Vertex)
 | 
						c.vertUpdate = make(chan []Vertex, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.renderChanged = true
 | 
						c.renderChanged = true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -127,7 +127,7 @@ func (c *Chunk) AppendVertex(arr []Vertex) []Vertex {
 | 
				
			|||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				app := GetBlockAppearance(off.Addv(i, j, k), int(c.Id[i][j][k]), int(c.Aux[i][j][k]), nil)
 | 
									app := GetBlockAppearance(off.Addv(i, j, k), int(c.Id[i][j][k]), int(c.Aux[i][j][k]), nil, c.world)
 | 
				
			||||||
				switch app.RenderType {
 | 
									switch app.RenderType {
 | 
				
			||||||
				case OneTexture:
 | 
									case OneTexture:
 | 
				
			||||||
					arr = c.appendFace(itype.XPlus, itype.Vec3i{i, j, k}, app.Name+".png", arr)
 | 
										arr = c.appendFace(itype.XPlus, itype.Vec3i{i, j, k}, app.Name+".png", arr)
 | 
				
			||||||
@@ -151,7 +151,7 @@ func (c *Chunk) AppendVertex(arr []Vertex) []Vertex {
 | 
				
			|||||||
					arr = c.appendFace(itype.ZPlus, itype.Vec3i{i, j, k}, app.Name+"_z+.png", arr)
 | 
										arr = c.appendFace(itype.ZPlus, itype.Vec3i{i, j, k}, app.Name+"_z+.png", arr)
 | 
				
			||||||
					arr = c.appendFace(itype.ZMinus, itype.Vec3i{i, j, k}, app.Name+"_z-.png", arr)
 | 
										arr = c.appendFace(itype.ZMinus, itype.Vec3i{i, j, k}, app.Name+"_z-.png", arr)
 | 
				
			||||||
				case CustomRendering:
 | 
									case CustomRendering:
 | 
				
			||||||
					arr = app.CustomRenderAppend(off.Addv(i, j, k), int(c.Aux[i][j][k]), nil, arr)
 | 
										arr = app.CustomRenderAppend(off.Addv(i, j, k), int(c.Aux[i][j][k]), nil, c.world, arr)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -174,11 +174,16 @@ func (c *Chunk) appendFace(face itype.Direction, pos itype.Vec3i, texname string
 | 
				
			|||||||
			next.Addv(c.X*ChunkSizeX, 0, c.Z*ChunkSizeZ),
 | 
								next.Addv(c.X*ChunkSizeX, 0, c.Z*ChunkSizeZ),
 | 
				
			||||||
			int(c.Id[next[0]][next[1]][next[2]]),
 | 
								int(c.Id[next[0]][next[1]][next[2]]),
 | 
				
			||||||
			int(c.Aux[next[0]][next[1]][next[2]]),
 | 
								int(c.Aux[next[0]][next[1]][next[2]]),
 | 
				
			||||||
			nil,
 | 
								nil, c.world,
 | 
				
			||||||
		).Transparent { // face next to a solid block
 | 
							).Transparent { // face next to a solid block
 | 
				
			||||||
		return arr // skip!
 | 
							return arr // skip!
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						worldnext := pos.Add(itype.DirectionVeci[face]).Addv(c.X*ChunkSizeX, 0, c.Z*ChunkSizeZ)
 | 
				
			||||||
 | 
						if block := c.world.Block(worldnext); block.Id != 0 && !block.Appearance(worldnext).Transparent {
 | 
				
			||||||
 | 
							return arr // skip!
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch face {
 | 
						switch face {
 | 
				
			||||||
	case itype.XPlus: // X+
 | 
						case itype.XPlus: // X+
 | 
				
			||||||
		arr = append(arr,
 | 
							arr = append(arr,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,6 +42,7 @@ func (w *World) SetChunk(x, z int, c *Chunk) {
 | 
				
			|||||||
	c.X = x
 | 
						c.X = x
 | 
				
			||||||
	c.Z = z
 | 
						c.Z = z
 | 
				
			||||||
	c.renderChanged = true
 | 
						c.renderChanged = true
 | 
				
			||||||
 | 
						c.world = w
 | 
				
			||||||
	w.Chunks[itype.Vec2i{x, z}] = c
 | 
						w.Chunks[itype.Vec2i{x, z}] = c
 | 
				
			||||||
	c.InitRender()
 | 
						c.InitRender()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -99,6 +100,26 @@ func (w *World) Block(pos itype.Vec3i) Block {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetBlock sets the block at the given position, returning its Block.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// It fails if the chunk is not loaded, and an empty Block{} is returned.
 | 
				
			||||||
 | 
					func (w *World) SetBlock(pos itype.Vec3i, id, aux int, dataset itype.Dataset) Block {
 | 
				
			||||||
 | 
						cx, cz := BlockPosToChunk(pos)
 | 
				
			||||||
 | 
						cix, ciy, ciz := BlockPosToInChunk(pos)
 | 
				
			||||||
 | 
						c, ok := w.Chunks[itype.Vec2i{cx, cz}]
 | 
				
			||||||
 | 
						if !ok || ciy < 0 || ciy >= ChunkSizeY {
 | 
				
			||||||
 | 
							return Block{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c.SetBlock(cix, ciy, ciz, id, aux)
 | 
				
			||||||
 | 
						return Block{
 | 
				
			||||||
 | 
							Id:        int(c.Id[cix][ciy][ciz]),
 | 
				
			||||||
 | 
							Aux:       int(c.Aux[cix][ciy][ciz]),
 | 
				
			||||||
 | 
							Dataset:   nil,
 | 
				
			||||||
 | 
							Behaviour: GetBlockBehaviour(int(c.Id[cix][ciy][ciz])),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LoadChunkFromGob loads (or overwrites) chunk [id.x, id.z] from the Gob-encoding file.
 | 
					// LoadChunkFromGob loads (or overwrites) chunk [id.x, id.z] from the Gob-encoding file.
 | 
				
			||||||
func (w *World) LoadChunkFromGob(id itype.Vec2i, file io.Reader) (err error) {
 | 
					func (w *World) LoadChunkFromGob(id itype.Vec2i, file io.Reader) (err error) {
 | 
				
			||||||
	c := &Chunk{}
 | 
						c := &Chunk{}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	packworld "edgaru089.ml/go/gl01/internal/world"
 | 
						packworld "edgaru089.ml/go/gl01/internal/world"
 | 
				
			||||||
 | 
						"edgaru089.ml/go/gl01/internal/world/blocks"
 | 
				
			||||||
	"github.com/aquilax/go-perlin"
 | 
						"github.com/aquilax/go-perlin"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,8 +16,8 @@ const (
 | 
				
			|||||||
	AltitudeDensity = 10 // Density of the noise in altitude
 | 
						AltitudeDensity = 10 // Density of the noise in altitude
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Sealevel = 63 // Space with Y=63 and lower should be the sea
 | 
						Sealevel = 63 // Space with Y=63 and lower should be the sea
 | 
				
			||||||
	Highest  = 72 // Highest part of the terrain
 | 
						Highest  = 84 // Highest part of the terrain
 | 
				
			||||||
	Lowest   = 56 // Lowest part of the terrain
 | 
						Lowest   = 60 // Lowest part of the terrain
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var perlins map[int64]*perlin.Perlin
 | 
					var perlins map[int64]*perlin.Perlin
 | 
				
			||||||
@@ -54,21 +55,30 @@ func Chunk(chunk *packworld.Chunk, world *packworld.World, seed int64) {
 | 
				
			|||||||
				float64(offZ+z)/AltitudeDensity))
 | 
									float64(offZ+z)/AltitudeDensity))
 | 
				
			||||||
			//log.Printf("height = %d (noise=%.5f)", height, p.Noise2D(float64(offX+x), float64(offZ+z)))
 | 
								//log.Printf("height = %d (noise=%.5f)", height, p.Noise2D(float64(offX+x), float64(offZ+z)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// water
 | 
				
			||||||
 | 
								for y := Sealevel; y > height; y-- {
 | 
				
			||||||
 | 
									chunk.Id[x][y][z] = blocks.Water
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// covering dirt
 | 
								// covering dirt
 | 
				
			||||||
			chunk.Id[x][height][z] = packworld.BlockGrass
 | 
								if height >= Sealevel {
 | 
				
			||||||
			//chunk.Id[x][height][z] = packworld.BlockDebugDir
 | 
									chunk.Id[x][height][z] = blocks.Grass
 | 
				
			||||||
			chunk.Id[x][height-1][z] = packworld.BlockDirt
 | 
								} else {
 | 
				
			||||||
			chunk.Id[x][height-2][z] = packworld.BlockDirt
 | 
									chunk.Id[x][height][z] = blocks.Dirt
 | 
				
			||||||
			chunk.Id[x][height-3][z] = packworld.BlockDirt
 | 
								}
 | 
				
			||||||
 | 
								//chunk.Id[x][height][z] = blocks.DebugDir
 | 
				
			||||||
 | 
								chunk.Id[x][height-1][z] = blocks.Dirt
 | 
				
			||||||
 | 
								chunk.Id[x][height-2][z] = blocks.Dirt
 | 
				
			||||||
 | 
								chunk.Id[x][height-3][z] = blocks.Dirt
 | 
				
			||||||
			height -= 4
 | 
								height -= 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// stone in the middle
 | 
								// stone in the middle
 | 
				
			||||||
			for y := height; y >= 1; y-- {
 | 
								for y := height; y >= 1; y-- {
 | 
				
			||||||
				chunk.Id[x][y][z] = packworld.BlockStone
 | 
									chunk.Id[x][y][z] = blocks.Stone
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// bedrock at the bottom
 | 
								// bedrock at the bottom
 | 
				
			||||||
			chunk.Id[x][0][z] = packworld.BlockBedrock
 | 
								chunk.Id[x][0][z] = blocks.Bedrock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// plant trees
 | 
								// plant trees
 | 
				
			||||||
			if height >= 50 && height <= 70 {
 | 
								if height >= 50 && height <= 70 {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user