Exemplo n.º 1
0
    /*
     * 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);
        }
    }
Exemplo n.º 2
0
    // 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);
    }
Exemplo n.º 3
0
    // 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);
                }
            }
        }
    }
Exemplo n.º 4
0
    // 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;
        }
    }