// 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); }
// Receives an Interaction command from client private void Interact(byte[] data) { ChunkPos pos = NetDecoder.ReadChunkPos(data, 1); int x = NetDecoder.ReadInt(data, 9); int y = NetDecoder.ReadInt(data, 13); int z = NetDecoder.ReadInt(data, 17); int facing = NetDecoder.ReadInt(data, 21); int callback; CastCoord current = new CastCoord(pos, x, y, z); ushort blockCode = this.cl.GetBlock(current); if (blockCode <= ushort.MaxValue / 2) { callback = this.cl.blockBook.blocks[blockCode].OnInteract(pos, current.blockX, current.blockY, current.blockZ, this.cl); } else { callback = this.cl.blockBook.objects[ushort.MaxValue - blockCode].OnInteract(pos, current.blockX, current.blockY, current.blockZ, this.cl); } // Actual handling of message CallbackHandler(callback, pos, current, facing); }
// 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 = GetCoordinates(x, y, z); BUDSignal cachedBUD; 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) { // Ignores void updates if (c.blockY < 0 || c.blockY > Chunk.chunkDepth - 1) { continue; } cachedBUD = new BUDSignal(type, c.GetWorldX(), c.GetWorldY(), c.GetWorldZ(), thisPos.GetWorldX(), thisPos.GetWorldY(), thisPos.GetWorldZ(), facings[faceCounter]); cl.budscheduler.ScheduleBUD(cachedBUD, tickOffset); faceCounter++; } }
/* * Main Callback function for block interactions * (REFER TO THESE CODES WHENEVER ADDING NEW BLOCK INTERACTIONS) * (MAY BE NEEDED IN ORDER TO IMPLEMENT NEW POST HANDLERS FOR NEW BLOCKS) */ private void CallbackHandler(int code, ChunkPos targetChunk, CastCoord thisPos, int facing) { // 0: No further actions necessary if (code == 0) { return; } // 1: Saves chunk and sends a DIRECTBLOCKUPDATE to all connected clients else if (code == 1) { ushort blockCode = this.cl.GetBlock(thisPos); ushort state = this.cl.GetState(thisPos); ushort hp = this.cl.GetHP(thisPos); this.cl.regionHandler.SaveChunk(this.cl.chunks[targetChunk]); NetMessage message = new NetMessage(NetCode.DIRECTBLOCKUPDATE); message.DirectBlockUpdate(BUDCode.CHANGE, targetChunk, thisPos.blockX, thisPos.blockY, thisPos.blockZ, facing, blockCode, state, hp); SendToClients(targetChunk, message); } // 2: Saves Chunk only else if (code == 2) { this.cl.budscheduler.ScheduleSave(targetChunk); } }
// 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); } } } }
// 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(); }
// Update is called once per frame void Update() { if (!cl.PLAYERSPAWNED) { return; } this.currentPos = new CastCoord(character.position.x, character.position.y, character.position.z); str.text = timer.ToString(); if (cl.chunks.ContainsKey(this.currentPos.GetChunkPos())) { // Biome sb.Append(cl.chunks[this.currentPos.GetChunkPos()].biomeName); sb.Append(" | "); // ChunkPos sb.Append(this.currentPos.GetChunkPos().ToString()); sb.Append(" // "); // XYZ only sb.Append(Mathf.RoundToInt(character.position.x)); sb.Append(", "); sb.Append(Mathf.CeilToInt(character.position.y)); sb.Append(", "); sb.Append(Mathf.RoundToInt(character.position.z)); biome.text = sb.ToString(); sb.Clear(); } }
/* * Main Callback function for block interactions * (REFER TO THESE CODES WHENEVER ADDING NEW BLOCK INTERACTIONS) * (MAY BE NEEDED IN ORDER TO IMPLEMENT NEW POST HANDLERS FOR NEW BLOCKS) */ private void CallbackHandler(int code, ChunkPos targetChunk, CastCoord thisPos, int facing) { // 0: No further actions necessary if (code == 0) { return; } // 1: Interaction forces the target chunk to reload/rebuild else if (code == 1) { loader.chunks[targetChunk].BuildChunk(); loader.chunks[targetChunk].BuildSideBorder(reload: true); loader.regionHandler.SaveChunk(loader.chunks[targetChunk]); } // 2: Emits BUD instantly and forces chunk reload else if (code == 2) { EmitBlockUpdate("change", current.GetWorldX(), current.GetWorldY(), current.GetWorldZ(), 0, loader); loader.budscheduler.ScheduleReload(targetChunk, 0); } // 3: Emits BUD in next tick and forces chunk reload else if (code == 3) { EmitBlockUpdate("change", current.GetWorldX(), current.GetWorldY(), current.GetWorldZ(), 1, loader); loader.budscheduler.ScheduleReload(targetChunk, 1); } // 4: Saves chunk to RDF file silently else if (code == 4) { loader.regionHandler.SaveChunk(loader.chunks[targetChunk]); } }
// 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++; } }
// Handles the emittion of BUD to neighboring blocks public void EmitBlockUpdate(string type, int x, int y, int z, int tickOffset, ChunkLoader 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) { cl.budscheduler.ScheduleBUD(new BUDSignal(type, c.GetWorldX(), c.GetWorldY(), c.GetWorldZ(), thisPos.GetWorldX(), thisPos.GetWorldY(), thisPos.GetWorldZ(), facings[faceCounter]), tickOffset); faceCounter++; } }
// Detects hit of solid block public bool HitSolid(CastCoord coords) { ChunkPos ck = new ChunkPos(coords.chunkX, coords.chunkZ); ushort blockID = loader.chunks[ck].data.GetCell(coords.blockX, coords.blockY, coords.blockZ); // If hits a full block if (blockID <= ushort.MaxValue / 2) { if (loader.chunks.ContainsKey(ck)) { if (loader.blockBook.blocks[blockID].solid) { return(true); } } } // If hits an Asset else { if (loader.chunks.ContainsKey(ck)) { blockID = (ushort)(ushort.MaxValue - blockID); if (loader.blockBook.objects[blockID].solid) { return(true); } } } return(false); }
// 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(); } }
// 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(); } }
public static bool Eq(CastCoord a, CastCoord b) { if (a.chunkX != b.chunkX || a.chunkZ != b.chunkZ || a.blockX != b.blockX || a.blockY != b.blockY || a.blockZ != b.blockZ) { return(false); } return(true); }
// Fills toDestroy and Safe list // Returns true if all blocks in currentList are connected to a stem // Returns false if all blocks in currentList doesn't connect to a stem or connects to a to-be-destroyed block private int SearchWood(CastCoord init, ChunkLoader cl) { ushort blockCode; ushort state; GetAroundCoords(init, cl); // Filters only Leaf blocks for (int i = 0; i < currentList.Count; i++) { // If it's connected to a marked-to-destroy block if (toDestroy.Contains(currentList[i])) { return(1); } // If it's connected to a safe block if (safeList.Contains(currentList[i])) { return(0); } // If current block is found in initial direction if (validDirections.Contains(currentList[i])) { validDirections.Remove(currentList[i]); } // PANIC if there's too many blocks if (currentList.Count > this.maxAnalysed) { currentList.Clear(); return(2); } blockCode = cl.GetBlock(currentList[i]); state = cl.GetState(currentList[i]); // If it's a spreadable block if (blockCode == this.thisCode && state == 0) { GetAroundCoords(currentList[i], cl); } // Check if it's a root else if (cl.blockBook.CheckSolid(blockCode)) { return(0); } else { currentList.RemoveAt(i); i--; } } return(1); }
// Gets surrounding on cache private void GetLastSurrounding(CastCoord init) { cache.Clear(); cache.Add(init.Add(0, 0, 1)); // North cache.Add(init.Add(0, 0, -1)); // South cache.Add(init.Add(1, 0, 0)); // East cache.Add(init.Add(-1, 0, 0)); // West cache.Add(init.Add(0, 1, 0)); // Up cache.Add(init.Add(0, -1, 0)); // Down }
// 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 } }
// Activates OnBreak event -> Emits normal BUD, emits special BUD to breadt-first search leaves public override int OnBreak(ChunkPos pos, int blockX, int blockY, int blockZ, ChunkLoader cl) { CastCoord thisCoord = new CastCoord(pos, blockX, blockY, blockZ); EmitBlockUpdate("break", thisCoord.GetWorldX(), thisCoord.GetWorldY(), thisCoord.GetWorldZ(), 0, cl); TreeCheck(thisCoord, cl); GetSurroundingLeaves(thisCoord, decayDistance, cl); RunLeavesRecursion(cl, thisCoord); return(0); }
public CastCoord Copy() { CastCoord c = new CastCoord(true); c.chunkX = this.chunkX; c.chunkZ = this.chunkZ; c.blockX = this.blockX; c.blockY = this.blockY; c.blockZ = this.blockZ; return(c); }
// 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); }
// Receives a BatchLoadBUD request from client, with plenty of block coordinates in a chunk private void BatchLoadBUD(byte[] data, ulong id) { ChunkPos pos; int x, y, z, facing; ushort blockCode, state, hp; int currentByte = 9; CastCoord lastCoord; pos = NetDecoder.ReadChunkPos(data, 1); while (data.Length > currentByte) { x = NetDecoder.ReadInt(data, currentByte); y = NetDecoder.ReadInt(data, currentByte + 4); z = NetDecoder.ReadInt(data, currentByte + 8); facing = NetDecoder.ReadInt(data, currentByte + 12); blockCode = NetDecoder.ReadUshort(data, currentByte + 16); state = NetDecoder.ReadUshort(data, currentByte + 18); hp = NetDecoder.ReadUshort(data, currentByte + 20); currentByte += 22; lastCoord = new CastCoord(pos, x, y, z); // 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); } } } }
// Returns a filled cache list full of surrounding coords private bool GetSurroundings(CastCoord init, int currentDistance, ChunkLoader_Server cl) { // End if (currentDistance == 0) { return(false); } cache.Clear(); cache.Add(init.Add(0, 0, 1)); // North cache.Add(init.Add(0, 0, -1)); // South cache.Add(init.Add(1, 0, 0)); // East cache.Add(init.Add(-1, 0, 0)); // West cache.Add(init.Add(0, 1, 0)); // Up cache.Add(init.Add(0, -1, 0)); // Down // Filters only Leaf blocks foreach (CastCoord c in cache) { if (cl.GetBlock(c) == this.thisCode && cl.GetState(c) == 0) { // If is already in dict if (distances.ContainsKey(c)) { if (distances[c] > currentDistance) { distances[c] = currentDistance; openList.Add(c); } } else { distances.Add(c, currentDistance); openList.Add(c); } } if (cl.GetBlock(c) == this.assignedWoodCode && cl.GetState(c) == 0) { return(true); } } return(false); }
// When on client, sends player position to Server whenever there's movement private void SendPlayerPosition() { if (this.player == null) { return; } if (position == null) { position = this.player.controller.transform.position; } if (rotation == null) { rotation = this.player.controller.transform.eulerAngles; } // If has moved if (this.player.controller.transform.position != position || this.player.controller.transform.eulerAngles != rotation) { SendPositionMessage(); position = this.player.controller.transform.position; rotation = this.player.controller.transform.eulerAngles; this.cacheCoord = new CastCoord(this.position); if (this.currentPos == null) { this.currentPos = this.cacheCoord.GetChunkPos(); this.lastPos = this.cacheCoord.GetChunkPos(); } else if (this.currentPos != this.cacheCoord.GetChunkPos()) { this.currentPos = this.cacheCoord.GetChunkPos(); SendChunkPosMessage(); this.lastPos = this.currentPos; } this.sendZeroNotification = 2; } // If hasn't moved but notification must be sent else if (this.sendZeroNotification > 0) { this.sendZeroNotification -= 1; SendPositionMessage(); } }
// Check if there's any wood block around this block private bool CheckWoodAround(CastCoord init, ChunkLoader cl) { cache.Clear(); cache.Add(init.Add(0, 0, 1)); // North cache.Add(init.Add(0, 0, -1)); // South cache.Add(init.Add(1, 0, 0)); // East cache.Add(init.Add(-1, 0, 0)); // West cache.Add(init.Add(0, 1, 0)); // Up cache.Add(init.Add(0, -1, 0)); // Down foreach (CastCoord c in cache) { if (cl.GetBlock(c) == this.thisCode && cl.GetState(c) == 0) { return(true); } } return(false); }
// Handles the emittion of BUD to neighboring blocks public void EmitDelayedBUD(string type, int x, int y, int z, int minOffset, int maxOffset, ChunkLoader 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)); } }
// 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); }
// 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); }
// Does Search for invalid leaves private void RunLeavesRecursion(ChunkLoader cl, CastCoord init) { while (openList.Count > 0) { GetSurroundingLeaves(openList[0], distances[openList[0]] - 1, cl); openList.RemoveAt(0); } // Applies DECAY BUD to distant leaves foreach (CastCoord c in distances.Keys) { if (distances[c] == 0) { EmitBUDTo("decay", c.GetWorldX(), c.GetWorldY(), c.GetWorldZ(), 1, cl); } } // Applies DECAY BUD to around blocks if there's no wood around EmitDelayedBUD("decay", init.GetWorldX(), init.GetWorldY(), init.GetWorldZ(), 2, 15, cl); distances.Clear(); }
// Detects hit in any block except air public bool HitAll(CastCoord coords) { ChunkPos ck = new ChunkPos(coords.chunkX, coords.chunkZ); // Exception if (!loader.chunks.ContainsKey(ck)) { return(false); } ushort blockID = loader.chunks[ck].data.GetCell(coords.blockX, coords.blockY, coords.blockZ); // If hits something if (blockID != 0) { if (loader.chunks.ContainsKey(ck)) { // DEBUG //print(blockID + " : " + loader.chunks[ck].metadata.GetState(coords.blockX, coords.blockY, coords.blockZ)); return(true); } } return(false); }