Esempio n. 1
0
File: chunk.go Progetto: num5/steven
func (c *chunk) setBlock(b Block, x, y, z int) {
	s := y >> 4
	if s < 0 || s > 15 {
		return
	}
	sec := c.Sections[s]
	if sec == nil {
		sec = newChunkSection(c, s)
		sec.Buffer = render.AllocateChunkBuffer(c.X, s, c.Z)
	}

	if sec.block(x, y&0xF, z) == b {
		return
	}

	pos := Position{X: x, Y: y, Z: z}
	pos = pos.Shift(c.X<<4, 0, c.Z<<4)
	if be, ok := sec.BlockEntities[pos]; ok {
		delete(sec.BlockEntities, pos)
		Client.entities.container.RemoveEntity(be)
	}
	sec.setBlock(b, x, y&0xF, z)

	if be := b.CreateBlockEntity(); be != nil {
		sec.BlockEntities[pos] = be
		be.SetPosition(pos)
		Client.entities.container.AddEntity(be)
	}

	if y >= c.highestBlock(x, z) {
		c.calcHeightmapAt(x, z)
	}

	var maxB, maxS int8
	for _, d := range direction.Values {
		ox, oy, oz := d.Offset()
		l := int8(c.relLight(x+ox, y+oy, z+oz, (*chunkSection).blockLight, false)) - 1
		if l > maxB {
			maxB = l
		}
		l = int8(c.relLight(x+ox, y+oy, z+oz, (*chunkSection).skyLight, true))
		if !(l == 15 && d == direction.Up) {
			l--
		}
		if l > maxS {
			maxS = l
		}
	}
	updateLight(c, specialLight, maxB, x, y, z, (*chunkSection).blockLight, (*chunkSection).setBlockLight, false)
	updateLight(c, specialLight, maxS, x, y, z, (*chunkSection).skyLight, (*chunkSection).setSkyLight, true)
}
Esempio n. 2
0
File: chunk.go Progetto: num5/steven
func (c *chunk) postLoad() {
	render.AllocateColumn(c.X, c.Z)
	// Allocate the render buffers sync
	for y, section := range c.Sections {
		if section != nil && section.Buffer == nil {
			section.Buffer = render.AllocateChunkBuffer(c.X, y, c.Z)
		}
	}

	chunkMap[c.chunkPosition] = c
	for _, section := range c.Sections {
		if section == nil {
			continue
		}
		for _, be := range section.BlockEntities {
			Client.entities.container.AddEntity(be)
		}

		cx := c.X << 4
		cy := section.Y << 4
		cz := c.Z << 4
		for y := 0; y < 16; y++ {
			for z := 0; z < 16; z++ {
				for x := 0; x < 16; x++ {
					section.setBlock(
						section.block(x, y, z).UpdateState(cx+x, cy+y, cz+z),
						x, y, z,
					)
				}
			}
		}
	}

	self := c
	for xx := -1; xx <= 1; xx++ {
		for zz := -1; zz <= 1; zz++ {
			c := chunkMap[chunkPosition{c.X + xx, c.Z + zz}]
			if c != nil && c != self {
				for _, section := range c.Sections {
					if section == nil {
						continue
					}
					cx, cy, cz := c.X<<4, section.Y<<4, c.Z<<4
					for y := 0; y < 16; y++ {
						if !(xx != 0 && zz != 0) {
							// Row/Col
							for i := 0; i < 16; i++ {
								var bx, bz int
								if xx != 0 {
									bz = i
									if xx == -1 {
										bx = 15
									}
								} else {
									bx = i
									if zz == -1 {
										bz = 15
									}
								}
								section.setBlock(
									section.block(bx, y, bz).UpdateState(cx+bx, cy+y, cz+bz),
									bx, y, bz,
								)
							}
						} else {
							// Just the corner
							var bx, bz int
							if xx == -1 {
								bx = 15
							}
							if zz == -1 {
								bz = 15
							}
							section.setBlock(
								section.block(bx, y, bz).UpdateState(cx+bx, cy+y, cz+bz),
								bx, y, bz,
							)
						}
					}
					section.dirty = true
				}
			}
		}
	}

	// Execute pending tasks
	toLoad := loadingChunks[c.chunkPosition]
	delete(loadingChunks, c.chunkPosition)
	for _, f := range toLoad {
		f()
	}
}