// Handles the emittion of BUD to neighboring blocks public void EmitBlockUpdate(BUDCode type, int x, int y, int z, int tickOffset, ChunkLoader_Server cl) { CastCoord thisPos = new CastCoord(new Vector3(x, y, z)); CastCoord[] neighbors = { thisPos.Add(1, 0, 0), thisPos.Add(-1, 0, 0), thisPos.Add(0, 1, 0), thisPos.Add(0, -1, 0), thisPos.Add(0, 0, 1), thisPos.Add(0, 0, -1) }; int[] facings = { 2, 0, 4, 5, 1, 3 }; int blockCode; int faceCounter = 0; foreach (CastCoord c in neighbors) { blockCode = cl.chunks[c.GetChunkPos()].data.GetCell(c.blockX, c.blockY, c.blockZ); cl.budscheduler.ScheduleBUD(new BUDSignal(type, c.GetWorldX(), c.GetWorldY(), c.GetWorldZ(), thisPos.GetWorldX(), thisPos.GetWorldY(), thisPos.GetWorldZ(), facings[faceCounter]), tickOffset); faceCounter++; } }
// Triggers DECAY BUD on this block public override void OnBlockUpdate(BUDCode type, int myX, int myY, int myZ, int budX, int budY, int budZ, int facing, ChunkLoader_Server cl) { if (type == BUDCode.DECAY) { CastCoord thisPos = new CastCoord(new Vector3(myX, myY, myZ)); GetSurroundings(thisPos, this.decayDistance, cl); if (!RunLeavesRecursion(cl)) { if (cl.chunks.ContainsKey(thisPos.GetChunkPos())) { cl.chunks[thisPos.GetChunkPos()].data.SetCell(thisPos.blockX, thisPos.blockY, thisPos.blockZ, 0); cl.chunks[thisPos.GetChunkPos()].metadata.Reset(thisPos.blockX, thisPos.blockY, thisPos.blockZ); this.Update(thisPos, BUDCode.BREAK, facing, cl); cl.budscheduler.ScheduleSave(thisPos.GetChunkPos()); } // Applies Decay BUD to surrounding leaves if this one is invalid GetLastSurrounding(thisPos); foreach (CastCoord c in cache) { EmitBUDTo(BUDCode.DECAY, c.GetWorldX(), c.GetWorldY(), c.GetWorldZ(), Random.Range(minDecayTime, maxDecayTime), cl); } } distances.Clear(); openList.Clear(); cache.Clear(); } }
// Handles the emittion of BUD to neighboring blocks public void EmitBlockUpdate(BUDCode type, int x, int y, int z, int tickOffset, ChunkLoader_Server cl) { CastCoord thisPos = new CastCoord(new Vector3(x, y, z)); CastCoord[] neighbors = { thisPos.Add(1, 0, 0), thisPos.Add(-1, 0, 0), thisPos.Add(0, 1, 0), thisPos.Add(0, -1, 0), thisPos.Add(0, 0, 1), thisPos.Add(0, 0, -1) }; int[] facings = { 2, 0, 4, 5, 1, 3 }; int faceCounter = 0; foreach (CastCoord c in neighbors) { if (c.blockY < 0 || c.blockY > Chunk.chunkDepth - 1) { continue; } cl.budscheduler.ScheduleBUD(new BUDSignal(type, c.GetWorldX(), c.GetWorldY(), c.GetWorldZ(), thisPos.GetWorldX(), thisPos.GetWorldY(), thisPos.GetWorldZ(), facings[faceCounter]), tickOffset); faceCounter++; } }
public BUDSignal(BUDCode t, int x, int y, int z, int bX, int bY, int bZ, int facing = -1) { this.type = t; this.x = x; this.y = y; this.z = z; this.budX = bX; this.budY = bY; this.budZ = bZ; this.facing = facing; }
// Client or Server send a single voxel data to each other public void DirectBlockUpdate(BUDCode type, ChunkPos pos, int x, int y, int z, int facing, ushort blockCode, ushort state, ushort hp) { NetDecoder.WriteChunkPos(pos, NetMessage.buffer, 1); NetDecoder.WriteInt(x, NetMessage.buffer, 9); NetDecoder.WriteInt(y, NetMessage.buffer, 13); NetDecoder.WriteInt(z, NetMessage.buffer, 17); NetDecoder.WriteInt(facing, NetMessage.buffer, 21); NetDecoder.WriteUshort(blockCode, NetMessage.buffer, 25); NetDecoder.WriteUshort(state, NetMessage.buffer, 27); NetDecoder.WriteUshort(hp, NetMessage.buffer, 29); NetDecoder.WriteInt((int)type, NetMessage.buffer, 31); this.size = 35; }
// Handles the emittion of BUD to neighboring blocks public void EmitDelayedBUD(BUDCode type, int x, int y, int z, int minOffset, int maxOffset, ChunkLoader_Server cl) { CastCoord thisPos = new CastCoord(new Vector3(x, y, z)); cache.Clear(); cache.Add(thisPos.Add(1, 0, 0)); cache.Add(thisPos.Add(-1, 0, 0)); cache.Add(thisPos.Add(0, 1, 0)); cache.Add(thisPos.Add(0, -1, 0)); cache.Add(thisPos.Add(0, 0, 1)); cache.Add(thisPos.Add(0, 0, -1)); foreach (CastCoord c in cache) { cl.budscheduler.ScheduleBUD(new BUDSignal(type, c.GetWorldX(), c.GetWorldY(), c.GetWorldZ(), thisPos.GetWorldX(), thisPos.GetWorldY(), thisPos.GetWorldZ(), 0), Random.Range(minOffset, maxOffset)); } }
// Breaks Torch if broken public override void OnBlockUpdate(BUDCode type, int x, int y, int z, int budX, int budY, int budZ, int facing, ChunkLoader_Server cl) { if (facing >= 4) { return; } CastCoord aux = new CastCoord(new Vector3(x, y, z)); if (type == BUDCode.LOAD) { this.OnLoad(aux, cl); } ChunkPos thisPos = aux.GetChunkPos(); //new ChunkPos(Mathf.FloorToInt(x/Chunk.chunkWidth), Mathf.FloorToInt(z/Chunk.chunkWidth)); int X = aux.blockX; //x%Chunk.chunkWidth; int Y = aux.blockY; //y%Chunk.chunkDepth; int Z = aux.blockZ; //z%Chunk.chunkWidth; aux = new CastCoord(new Vector3(budX, budY, budZ)); ChunkPos budPos = aux.GetChunkPos(); //new ChunkPos(Mathf.FloorToInt(budX/Chunk.chunkWidth), Mathf.FloorToInt(budZ/Chunk.chunkWidth)); int bX = aux.blockX; //budX%Chunk.chunkWidth; int bY = aux.blockY; //budY%Chunk.chunkDepth; int bZ = aux.blockZ; //budZ%Chunk.chunkWidth; ushort state = cl.chunks[thisPos].metadata.GetState(X, Y, Z); // Breaks Torch if broken attached block if (type == BUDCode.BREAK && (facing == state || facing + 4 == state)) { cl.chunks[thisPos].data.SetCell(X, Y, Z, 0); this.OnBreak(thisPos, X, Y, Z, cl); NetMessage message = new NetMessage(NetCode.DIRECTBLOCKUPDATE); message.DirectBlockUpdate(BUDCode.BREAK, thisPos, X, Y, Z, facing, ushort.MaxValue, state, 0); cl.server.SendToClients(thisPos, message); EraseMetadata(thisPos, X, Y, Z, cl); } // Breaks Torch if changed block is not solid else if (type == BUDCode.CHANGE) { int blockCode = cl.chunks[budPos].data.GetCell(bX, bY, bZ); if (blockCode >= 0) { // If changed block is not solid, break if (!cl.blockBook.blocks[blockCode].solid) { cl.chunks[thisPos].data.SetCell(X, Y, Z, 0); this.OnBreak(thisPos, X, Y, Z, cl); NetMessage message = new NetMessage(NetCode.DIRECTBLOCKUPDATE); message.DirectBlockUpdate(BUDCode.BREAK, thisPos, X, Y, Z, facing, ushort.MaxValue, state, 0); cl.server.SendToClients(thisPos, message); EraseMetadata(thisPos, X, Y, Z, cl); } } else { if (!cl.blockBook.objects[ushort.MaxValue - blockCode].solid) { cl.chunks[thisPos].data.SetCell(X, Y, Z, 0); this.OnBreak(thisPos, X, Y, Z, cl); NetMessage message = new NetMessage(NetCode.DIRECTBLOCKUPDATE); message.DirectBlockUpdate(BUDCode.BREAK, thisPos, X, Y, Z, facing, ushort.MaxValue, state, 0); cl.server.SendToClients(thisPos, message); EraseMetadata(thisPos, X, Y, Z, cl); } } } }
// Sends a DirectBlockUpdate call to users public void Update(CastCoord c, BUDCode type, int facing, ChunkLoader_Server cl) { this.reloadMessage = new NetMessage(NetCode.DIRECTBLOCKUPDATE); this.reloadMessage.DirectBlockUpdate(type, c.GetChunkPos(), c.blockX, c.blockY, c.blockZ, facing, 0, cl.GetState(c), ushort.MaxValue); cl.server.SendToClients(c.GetChunkPos(), this.reloadMessage); }
// Emits a BUD signal with no information about sender public void EmitBUDTo(BUDCode type, int x, int y, int z, int tickOffset, ChunkLoader_Server cl) { cl.budscheduler.ScheduleBUD(new BUDSignal(type, x, y, z, 0, 0, 0, 0), tickOffset); }
/* * VIRTUAL METHODS */ /* BUD Types * "break": When emitting block is broken * "change": When emitting block has been turned into another block or changed properties * "trigger": When emitting block has been electrically triggered */ public virtual void OnBlockUpdate(BUDCode budType, int myX, int myY, int myZ, int budX, int budY, int budZ, int facing, ChunkLoader_Server cl) { }