// Creates FireVFX on Load public override int OnLoad(CastCoord coord, ChunkLoader cl) { ushort? state = cl.chunks[coord.GetChunkPos()].metadata.GetState(coord.blockX, coord.blockY, coord.blockZ); Vector3 fireOffset; if (state == 0 || state == 4) { fireOffset = new Vector3(0.15f, 0f, 0f); } else if (state == 1 || state == 5) { fireOffset = new Vector3(0f, 0f, -0.15f); } else if (state == 2 || state == 6) { fireOffset = new Vector3(-0.15f, 0f, 0f); } else if (state == 3 || state == 7) { fireOffset = new Vector3(0f, 0f, 0.15f); } else { fireOffset = new Vector3(0f, 0f, 0f); } GameObject fire = GameObject.Instantiate(this.fireVFX, new Vector3(coord.GetChunkPos().x *Chunk.chunkWidth + coord.blockX, coord.blockY + 0.35f, coord.GetChunkPos().z *Chunk.chunkWidth + coord.blockZ) + fireOffset, Quaternion.identity); fire.name = BuildVFXName(coord.GetChunkPos(), coord.blockX, coord.blockY, coord.blockZ); this.vfx.Add(coord.GetChunkPos(), fire, active: true); ControlFire(coord.GetChunkPos(), coord.blockX, coord.blockY, coord.blockZ, state); return(1); }
// Triggers DECAY BUD on this block public override void OnBlockUpdate(string type, int myX, int myY, int myZ, int budX, int budY, int budZ, int facing, ChunkLoader cl) { if (type == "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); cl.budscheduler.ScheduleReload(thisPos.GetChunkPos(), 0, x: thisPos.blockX, y: thisPos.blockY, z: thisPos.blockZ); } // Applies Decay BUD to surrounding leaves if this one is invalid GetLastSurrounding(thisPos); foreach (CastCoord c in cache) { EmitBUDTo("decay", c.GetWorldX(), c.GetWorldY(), c.GetWorldZ(), Random.Range(3, 12), cl); } } distances.Clear(); openList.Clear(); cache.Clear(); } }
// 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(); } }
// Returns block code of a castcoord public ushort GetState(CastCoord c) { if (this.chunks.ContainsKey(c.GetChunkPos())) { return(this.chunks[c.GetChunkPos()].metadata.GetState(c.blockX, c.blockY, c.blockZ)); } else { return((ushort)(ushort.MaxValue / 2)); // Error Code } }
// Receives Player Information saved on server on startup private void SendServerInfo(byte[] data) { float x, y, z, xDir, yDir, zDir; CastCoord initialCoord; x = NetDecoder.ReadFloat(data, 1); y = NetDecoder.ReadFloat(data, 5); z = NetDecoder.ReadFloat(data, 9); xDir = NetDecoder.ReadFloat(data, 13); yDir = NetDecoder.ReadFloat(data, 17); zDir = NetDecoder.ReadFloat(data, 21); this.cl.PLAYERSPAWNED = true; this.cl.playerX = x; this.cl.playerY = y; this.cl.playerZ = z; this.cl.playerDirX = xDir; this.cl.playerDirY = yDir; this.cl.playerDirZ = zDir; // Finds current Chunk and sends position data initialCoord = new CastCoord(x, y, z); this.cl.time.SetCurrentChunkPos(initialCoord.GetChunkPos()); this.cl.time.SendChunkPosMessage(); }
// Breaks Torch if broken public override void OnBlockUpdate(string type, int x, int y, int z, int budX, int budY, int budZ, int facing, ChunkLoader cl) { if (facing >= 4) { return; } CastCoord aux = new CastCoord(new Vector3(x, y, z)); if (type == "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 == "break" && (facing == state || facing + 4 == state)) { cl.chunks[thisPos].data.SetCell(X, Y, Z, 0); this.OnBreak(thisPos, X, Y, Z, cl); EraseMetadata(thisPos, X, Y, Z, cl); } // Breaks Torch if changed block is not solid else if (type == "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); 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); EraseMetadata(thisPos, X, Y, Z, cl); } } } }
// Creates FireVFX on Load public override int OnLoad(CastCoord coord, ChunkLoader_Server cl) { ushort state = cl.chunks[coord.GetChunkPos()].metadata.GetState(coord.blockX, coord.blockY, coord.blockZ); int facing; if (state >= 4) { facing = state - 4; } else { facing = state; } NetMessage message = new NetMessage(NetCode.VFXDATA); message.VFXData(coord.GetChunkPos(), coord.blockX, coord.blockY, coord.blockZ, facing, ushort.MaxValue, state); cl.vfx.Add(coord.GetChunkPos(), BuildVFXName(coord.GetChunkPos(), coord.blockX, coord.blockY, coord.blockZ), message); cl.server.SendToClients(coord.GetChunkPos(), message); return(1); }
// Block Placing mechanic private bool PlaceBlock(ushort blockCode) { // Won't happen if not raycasting something or if block is in player's body or head if (!current.active || (CastCoord.Eq(lastCoord, playerHead) && loader.blockBook.CheckSolid(blockCode)) || (CastCoord.Eq(lastCoord, playerBody) && loader.blockBook.CheckSolid(blockCode))) { return(false); } NetMessage message = new NetMessage(NetCode.DIRECTBLOCKUPDATE); message.DirectBlockUpdate(BUDCode.PLACE, lastCoord.GetChunkPos(), lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, facing, blockCode, ushort.MaxValue, ushort.MaxValue); this.loader.client.Send(message.GetMessage(), message.size); return(true); }
public ulong AddItem(float3 pos, float3 rot, float3 move, ushort itemCode, byte amount, ulong playerCode, ChunkLoader_Server cl) { CastCoord coord = new CastCoord(pos); ChunkPos chunk = coord.GetChunkPos(); ulong assignedCode = this.availableDropCodes.Pop(); if (!this.dropObject.ContainsKey(chunk)) { this.dropObject.Add(chunk, new Dictionary <ulong, DroppedItemAI>()); } this.dropObject[chunk].Add(assignedCode, new DroppedItemAI(pos, rot, move, assignedCode, itemCode, amount, playerCode, this, cl)); return(assignedCode); }
// Block Breaking mechanic public void BreakBlock() { if (!current.active) { return; } ChunkPos toUpdate = new ChunkPos(current.chunkX, current.chunkZ); ushort blockCode = loader.chunks[toUpdate].data.GetCell(current.blockX, current.blockY, current.blockZ); ushort state = loader.chunks[toUpdate].metadata.GetState(current.blockX, current.blockY, current.blockZ); ushort hp = loader.chunks[toUpdate].metadata.GetHP(current.blockX, current.blockY, current.blockZ); NetMessage message = new NetMessage(NetCode.BLOCKDAMAGE); message.BlockDamage(current.GetChunkPos(), current.blockX, current.blockY, current.blockZ, this.blockDamage, false); this.loader.client.Send(message.GetMessage(), message.size); }
// Triggers Blocktype.OnInteract() public void Interact() { loader.chunks[playerBody.GetChunkPos()].PrintDrawStage(); if (!current.active) { return; } ChunkPos toUpdate = new ChunkPos(current.chunkX, current.chunkZ); int blockCode = loader.chunks[toUpdate].data.GetCell(current.blockX, current.blockY, current.blockZ); NetMessage message = new NetMessage(NetCode.INTERACT); message.Interact(toUpdate, current.blockX, current.blockY, current.blockZ, facing); this.loader.client.Send(message.GetMessage(), message.size); }
// Receives a Drop Item notification and creates the DropItemAI Entity private void DropItem(byte[] data, ulong id) { float3 pos, rot, move; ushort itemCode; byte amount; NetMessage message = new NetMessage(NetCode.ITEMENTITYDATA); pos = NetDecoder.ReadFloat3(data, 1); rot = NetDecoder.ReadFloat3(data, 13); move = NetDecoder.ReadFloat3(data, 25); itemCode = NetDecoder.ReadUshort(data, 37); amount = data[39]; CastCoord coord = new CastCoord(pos); ChunkPos cp = coord.GetChunkPos(); ulong code = this.entityHandler.AddItem(pos, rot, move, itemCode, amount, id, this.cl); message.ItemEntityData(pos.x, pos.y, pos.z, rot.x, rot.y, rot.z, itemCode, amount, code); this.SendToClients(cp, message); }
// Returns two Voxeldata-like array of blocks and states respectively public bool GetField(CastCoord c, int2 radius, ref ushort[] blocks, ref ushort[] states) { if (!this.chunks.ContainsKey(c.GetChunkPos())) { return(false); } int minX, minZ; int cX, cY, cZ; int minBoundsX, minBoundsY, minBoundsZ; ChunkPos pos; ChunkPos middleChunk = c.GetChunkPos(); // Set affected chunks minX = ChunkOperation(c.blockX, radius.x, Chunk.chunkWidth); minZ = ChunkOperation(c.blockZ, radius.x, Chunk.chunkWidth); // Set border chunk bounds minBoundsX = NegativeFlip(c.blockX - radius.x, Chunk.chunkWidth); minBoundsZ = NegativeFlip(c.blockZ - radius.x, Chunk.chunkWidth); minBoundsY = c.blockY - radius.y; // Initial Pos pos = new ChunkPos(middleChunk.x + minX, middleChunk.z + minZ); cX = minBoundsX; for (int x = 0; x < (radius.x * 2 + 1); x++) { // If X goes to another chunk if (cX >= Chunk.chunkWidth) { pos = new ChunkPos(pos.x + 1, middleChunk.z); cX = 0; } // If chunk doesn't exist if (!this.chunks.ContainsKey(pos)) { cX++; continue; } cY = minBoundsY; for (int y = 0; y < (radius.y * 2 + 1); y++) { cZ = minBoundsZ; // Set Y Limits if (cY < 0 || cY >= Chunk.chunkDepth) { cY++; pos = new ChunkPos(pos.x, middleChunk.z); continue; } for (int z = 0; z < (radius.x * 2 + 1); z++) { // If Z goes to another chunk if (cZ >= Chunk.chunkWidth) { pos = new ChunkPos(pos.x, pos.z + 1); cZ = 0; } // If chunk doesn't exist if (!this.chunks.ContainsKey(pos)) { cZ++; continue; } blocks[x * (radius.x * 2 + 1) * (radius.y * 2 + 1) + y * (radius.x * 2 + 1) + z] = this.chunks[pos].data.GetCell(cX, cY, cZ); states[x * (radius.x * 2 + 1) * (radius.y * 2 + 1) + y * (radius.x * 2 + 1) + z] = this.chunks[pos].metadata.GetState(cX, cY, cZ); cZ++; } pos = new ChunkPos(pos.x, middleChunk.z); cY++; } cX++; } return(true); }
// 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 direct action BUD to a block // ComesFromMessage flag is used to call this function from within the Server Code and not triggered by any message private void DirectBlockUpdate(byte[] data, ulong id, bool comesFromMessage = true) { ChunkPos pos; int x, y, z, facing; ushort blockCode, state, hp; BUDCode type; NetMessage message; pos = NetDecoder.ReadChunkPos(data, 1); x = NetDecoder.ReadInt(data, 9); y = NetDecoder.ReadInt(data, 13); z = NetDecoder.ReadInt(data, 17); facing = NetDecoder.ReadInt(data, 21); blockCode = NetDecoder.ReadUshort(data, 25); state = 0; hp = 0; if (comesFromMessage) { state = NetDecoder.ReadUshort(data, 27); hp = NetDecoder.ReadUshort(data, 29); type = (BUDCode)NetDecoder.ReadInt(data, 31); } else { type = (BUDCode)NetDecoder.ReadInt(data, 27); } CastCoord lastCoord = new CastCoord(pos, x, y, z); switch (type) { case BUDCode.PLACE: // if chunk is still loaded if (this.cl.chunks.ContainsKey(lastCoord.GetChunkPos())) { // if it's a block if (blockCode <= ushort.MaxValue / 2) { // if placement rules fail if (!cl.blockBook.blocks[blockCode].PlacementRule(lastCoord.GetChunkPos(), lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, facing, cl)) { NetMessage denied = new NetMessage(NetCode.PLACEMENTDENIED); this.Send(denied.GetMessage(), denied.size, id); return; } } // if it's an object else { if (!cl.blockBook.objects[ushort.MaxValue - blockCode].PlacementRule(lastCoord.GetChunkPos(), lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, facing, cl)) { NetMessage denied = new NetMessage(NetCode.PLACEMENTDENIED); this.Send(denied.GetMessage(), denied.size, id); return; } } // Check if is trying to put block on players if (this.playersInChunk.ContainsKey(pos)) { foreach (ulong code in this.playersInChunk[pos]) { if (code == id) { continue; } if (!this.cl.regionHandler.allPlayerData[code].CheckValidPlacement(lastCoord.GetWorldX(), lastCoord.GetWorldY(), lastCoord.GetWorldZ())) { NetMessage denied = new NetMessage(NetCode.PLACEMENTDENIED); this.Send(denied.GetMessage(), denied.size, id); return; } } } // If doesn't have special place handling if (!cl.blockBook.CheckCustomPlace(blockCode)) { // Actually places block/asset into terrain cl.chunks[lastCoord.GetChunkPos()].data.SetCell(lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, blockCode); //cl.budscheduler.ScheduleReload(lastCoord.GetChunkPos(), 0); EmitBlockUpdate(BUDCode.CHANGE, lastCoord.GetWorldX(), lastCoord.GetWorldY(), lastCoord.GetWorldZ(), 0, cl); // Applies OnPlace Event if (blockCode <= ushort.MaxValue / 2) { cl.blockBook.blocks[blockCode].OnPlace(lastCoord.GetChunkPos(), lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, facing, cl); } else { cl.blockBook.objects[ushort.MaxValue - blockCode].OnPlace(lastCoord.GetChunkPos(), lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, facing, cl); } // Sends the updated voxel to loaded clients message = new NetMessage(NetCode.DIRECTBLOCKUPDATE); message.DirectBlockUpdate(BUDCode.PLACE, lastCoord.GetChunkPos(), lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, facing, blockCode, this.cl.chunks[lastCoord.GetChunkPos()].metadata.GetState(lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ), this.cl.chunks[lastCoord.GetChunkPos()].metadata.GetHP(lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ)); SendToClients(lastCoord.GetChunkPos(), message); this.cl.regionHandler.SaveChunk(this.cl.chunks[pos]); } // If has special handling else { // Actually places block/asset into terrain this.cl.chunks[lastCoord.GetChunkPos()].data.SetCell(lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, blockCode); if (blockCode <= ushort.MaxValue / 2) { cl.blockBook.blocks[blockCode].OnPlace(lastCoord.GetChunkPos(), lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, facing, cl); } else { cl.blockBook.objects[ushort.MaxValue - blockCode].OnPlace(lastCoord.GetChunkPos(), lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, facing, cl); } } // Make entities in this chunk update their TerrainVision this.entityHandler.SetRefreshVision(EntityType.DROP, lastCoord.GetChunkPos()); } break; case BUDCode.SETSTATE: if (this.cl.chunks.ContainsKey(lastCoord.GetChunkPos())) { this.cl.chunks[lastCoord.GetChunkPos()].metadata.SetState(lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, blockCode); this.entityHandler.SetRefreshVision(EntityType.DROP, lastCoord.GetChunkPos()); } break; case BUDCode.BREAK: // If doesn't has special break handling if (!this.cl.blockBook.CheckCustomBreak(blockCode)) { // Actually breaks new block and updates chunk this.cl.chunks[pos].data.SetCell(lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, 0); this.cl.chunks[pos].metadata.Reset(lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ); // Triggers OnBreak if (blockCode <= ushort.MaxValue / 2) { this.cl.blockBook.blocks[blockCode].OnBreak(pos, lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, this.cl); } else { this.cl.blockBook.objects[ushort.MaxValue - blockCode].OnBreak(pos, lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, this.cl); } EmitBlockUpdate(BUDCode.BREAK, lastCoord.GetWorldX(), lastCoord.GetWorldY(), lastCoord.GetWorldZ(), 0, this.cl); } // If has special break handlings else { if (blockCode <= ushort.MaxValue / 2) { this.cl.blockBook.blocks[blockCode].OnBreak(pos, lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, this.cl); } else { this.cl.blockBook.objects[ushort.MaxValue - blockCode].OnBreak(pos, lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, this.cl); } } // Sends the updated voxel to loaded clients this.entityHandler.SetRefreshVision(EntityType.DROP, lastCoord.GetChunkPos()); message = new NetMessage(NetCode.DIRECTBLOCKUPDATE); message.DirectBlockUpdate(BUDCode.BREAK, lastCoord.GetChunkPos(), lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ, facing, 0, ushort.MaxValue, ushort.MaxValue); SendToClients(lastCoord.GetChunkPos(), message); this.cl.regionHandler.SaveChunk(this.cl.chunks[pos]); break; case BUDCode.LOAD: // HP is set as the Chunk Coordinates vs World Coordinates flag if (hp == ushort.MaxValue) { lastCoord = new CastCoord(new Vector3(lastCoord.blockX, lastCoord.blockY, lastCoord.blockZ)); } blockCode = this.cl.GetBlock(lastCoord); if (this.cl.chunks.ContainsKey(lastCoord.GetChunkPos())) { if (blockCode <= ushort.MaxValue / 2) { this.cl.blockBook.blocks[blockCode].OnLoad(lastCoord, this.cl); } else { this.cl.blockBook.objects[ushort.MaxValue - blockCode].OnLoad(lastCoord, this.cl); } } break; default: break; } }
public ChunkPos GetChunkPos() { CastCoord coord = new CastCoord(this.posX, this.posY, this.posZ); return(coord.GetChunkPos()); }
// Update is called once per frame void Update() { // Gets this Unity Tick time this.newTime = schedulerTime.GetBUDTime(); // Checks if BUD Tick has changed if (this.newTime != this.currentTime) { bool shouldClean = false; this.currentDealocTime++; // Removes past queues if frame skipped to prevent Memory Leak if (currentDealocTime == byte.MaxValue) { currentDealocTime = 0; foreach (string s in this.data.Keys) { if (schedulerTime.IsPast(s)) { cachedString = s; shouldClean = true; break; } } if (shouldClean) { shouldClean = false; this.data.Remove(cachedString); } } // Saves the World Data every second if (loader.regionHandler != null) { loader.regionHandler.SaveWorld(); } // Batch Chunk Saver if (SaveCount() > 0) { foreach (ChunkPos pos in this.toSave[this.currentTime]) { if (loader.chunks.ContainsKey(pos)) { loader.regionHandler.SaveChunk(loader.chunks[pos]); } } } this.currentBUDonFrame = 0; // Pops all elements of BUD if (this.data.ContainsKey(this.currentTime)) { if (this.data[this.currentTime].Count > 0) { PassToNextTick(); } } // Frees memory of previous BUD Tick this.data.Remove(this.currentTime); this.toSave.Remove(this.currentTime); this.currentTime = this.newTime; } // Iterates through frame's list and triggers BUD if (DataCount() > 0) { for (currentBUDonFrame = 0; currentBUDonFrame < BUDperFrame; currentBUDonFrame++) { if (this.data[this.currentTime].Count > 0) { cachedCoord = new CastCoord(new Vector3(this.data[this.currentTime][0].x, this.data[this.currentTime][0].y, this.data[this.currentTime][0].z)); // If BUDSignal is still in the loaded area if (loader.chunks.ContainsKey(cachedCoord.GetChunkPos())) { cachedCode = loader.chunks[cachedCoord.GetChunkPos()].data.GetCell(cachedCoord.blockX, cachedCoord.blockY, cachedCoord.blockZ); if (cachedCode <= ushort.MaxValue / 2) { loader.blockBook.blocks[cachedCode].OnBlockUpdate(this.data[this.currentTime][0].type, this.data[this.currentTime][0].x, this.data[this.currentTime][0].y, this.data[this.currentTime][0].z, this.data[this.currentTime][0].budX, this.data[this.currentTime][0].budY, this.data[this.currentTime][0].budZ, this.data[this.currentTime][0].facing, loader); } else { loader.blockBook.objects[ushort.MaxValue - cachedCode].OnBlockUpdate(this.data[this.currentTime][0].type, this.data[this.currentTime][0].x, this.data[this.currentTime][0].y, this.data[this.currentTime][0].z, this.data[this.currentTime][0].budX, this.data[this.currentTime][0].budY, this.data[this.currentTime][0].budZ, this.data[this.currentTime][0].facing, loader); } } this.data[this.currentTime].RemoveAt(0); } else { break; } } } }
// 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); }