Пример #1
0
        public void PlayerDigging(DiggingStatus status, BlockCoordinates position, BlockFace face, Vector3 cursorPosition)
        {
            if (WorldReceiver?.GetPlayerEntity() is Entities.Player player)
            {
                var item = player.Inventory[player.Inventory.SelectedSlot];
                if (status == DiggingStatus.Started)
                {
                    SendPlayerAction(PlayerAction.StartBreak, position, (int)face);
                }
                else if (status == DiggingStatus.Finished)
                {
                    SendPlayerAction(PlayerAction.StopBreak, position, (int)face);
                    var packet = McpeInventoryTransaction.CreateObject();
                    packet.transaction = new Transaction()
                    {
                        ActionType    = (int)McpeInventoryTransaction.ItemUseAction.Destroy,
                        ClickPosition =
                            new System.Numerics.Vector3(cursorPosition.X, cursorPosition.Y, cursorPosition.Z),
                        TransactionType = McpeInventoryTransaction.TransactionType.ItemUse,
                        EntityId        = NetworkEntityId,
                        Position        = new MiNET.Utils.BlockCoordinates(position.X, position.Y, position.Z),
                        //Item = MiNET.Items.ItemFactory.GetItem()
                    };

                    SendPacket(packet);
                }
                else if (status == DiggingStatus.Cancelled)
                {
                    SendPlayerAction(PlayerAction.AbortBreak, position, (int)face);
                }
            }
        }
Пример #2
0
        public Block GetBlock(BlockCoordinates blockCoordinates, ChunkColumn tryChunk = null)
        {
            ChunkColumn chunk = null;

            var chunkCoordinates = new ChunkCoordinates(blockCoordinates.X >> 4, blockCoordinates.Z >> 4);

            if (tryChunk != null && tryChunk.X == chunkCoordinates.X && tryChunk.Z == chunkCoordinates.Z)
            {
                chunk = tryChunk;
            }
            else
            {
                chunk = GetChunk(chunkCoordinates);
            }

            if (chunk == null)
            {
                return((Block)Airstate.Block);
            }

            var block = (Block)chunk.GetBlockState(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0xff, blockCoordinates.Z & 0x0f).Block;

            block.Coordinates = blockCoordinates;

            return(block);
        }
Пример #3
0
        private void StartBreakingBlock()
        {
            SwingArm(true);

            var floored  = new BlockCoordinates(Vector3.Floor(Raytraced));
            var adjacent = AdjacentRaytrace;

            var block = Level.GetBlock(floored);

            if (!block.HasHitbox)
            {
                return;
            }

            var face = GetTargetFace();

            _destroyingBlock  = true;
            _destroyingTarget = floored;
            _destroyingFace   = face;

            Interlocked.Exchange(ref _destroyingTick, 0);

            _destroyTimeNeeded = block.GetBreakTime(Inventory.MainHand ?? new ItemAir());

            Log.Debug($"Start break block ({_destroyingTarget}, {_destroyTimeNeeded} ticks.)");

            var flooredAdj = Vector3.Floor(adjacent);
            var remainder  = new Vector3(adjacent.X - flooredAdj.X, adjacent.Y - flooredAdj.Y, adjacent.Z - flooredAdj.Z);

            Network?.PlayerDigging(DiggingStatus.Started, floored, face, remainder);
        }
Пример #4
0
        private void StartBreakingBlock()
        {
            SwingArm(true);

            var floored = Vector3.Floor(Raytraced);

            var block = Level.GetBlock(floored);

            if (!block.HasHitbox)
            {
                return;
            }

            _destroyingBlock  = true;
            _destroyingTarget = floored;
            _destroyingFace   = GetTargetFace();
            _destroyingTick   = DateTime.UtcNow;

            //if (Inventory.MainHand != null)
            {
                _destroyTimeNeeded = block.GetBreakTime(Inventory.MainHand ?? new ItemAir()) * 20f;
            }

            Log.Debug($"Start break block ({_destroyingTarget}, {_destroyTimeNeeded} ticks.)");

            var flooredAdj = Vector3.Floor(AdjacentRaytrace);
            var remainder  = new Vector3(AdjacentRaytrace.X - flooredAdj.X, AdjacentRaytrace.Y - flooredAdj.Y, AdjacentRaytrace.Z - flooredAdj.Z);

            Network?.PlayerDigging(DiggingStatus.Started, _destroyingTarget, _destroyingFace, remainder);
        }
Пример #5
0
        public void SetBlockEntity(int x, int y, int z, BlockEntity blockEntity)
        {
            var coords      = new BlockCoordinates(x, y, z);
            var chunkCoords = new ChunkCoordinates(x >> 4, z >> 4);

            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(chunkCoords, out chunk))
            {
                var cx = x & 0xf;
                var cy = y & 0xff;
                var cz = z & 0xf;

                var chunkPos   = new BlockCoordinates(cx, cy, cz);
                var blockAtPos = chunk.GetBlockState(cx, cy, cz);

                if (blockAtPos.Block.BlockMaterial == Material.Air)
                {
                    return;
                }

                chunk.RemoveBlockEntity(chunkPos);
                EntityManager.RemoveBlockEntity(coords);

                chunk.AddBlockEntity(chunkPos, blockEntity);
                EntityManager.AddBlockEntity(coords, blockEntity);
            }
        }
Пример #6
0
 private void ScheduleBlockUpdate(BlockCoordinates updatedBlock, BlockCoordinates block)
 {
     Ticker.ScheduleTick(() =>
     {
         GetBlockState(block).Block.BlockUpdate(this, block, updatedBlock);
         //GetBlock(block).BlockUpdate(this, block, updatedBlock);
     }, 1);
 }
Пример #7
0
        public ChunkColumn GetChunk(BlockCoordinates coordinates, bool cacheOnly = false)
        {
            if (ChunkManager.TryGetChunk(new ChunkCoordinates(coordinates), out var c))
            {
                return((ChunkColumn)c);
            }

            return(null);
        }
Пример #8
0
 public void PlayerDigging(DiggingStatus status, BlockCoordinates position, BlockFace face, Vector3 cursorPosition)
 {
     SendPacket(new PlayerDiggingPacket()
     {
         Face     = face,
         Location = position,
         Status   = status
     });
 }
Пример #9
0
        public void SetSkyLight(BlockCoordinates coordinates, byte p1)
        {
            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(new ChunkCoordinates(coordinates), out chunk))
            {
                chunk.SetSkyLight(coordinates.X & 0xf, coordinates.Y & 0xff, coordinates.Z & 0xf, p1);
            }
        }
Пример #10
0
 public void BlockPlaced(BlockCoordinates position, BlockFace face, int hand, Vector3 cursorPosition, IEntity p)
 {
     SendPacket(new PlayerBlockPlacementPacket()
     {
         CursorPosition = cursorPosition,
         Location       = position,
         Face           = face,
         Hand           = hand
     });
 }
Пример #11
0
        public void DropHeldItem()
        {
            var floored = new BlockCoordinates(Vector3.Floor(Raytraced));
            var face    = GetTargetFace();

            var adjacent   = AdjacentRaytrace;
            var flooredAdj = Vector3.Floor(adjacent);
            var remainder  = new Vector3(adjacent.X - flooredAdj.X, adjacent.Y - flooredAdj.Y, adjacent.Z - flooredAdj.Z);

            Network?.PlayerDigging(DiggingStatus.DropItem, floored, face, remainder);
        }
Пример #12
0
        public int GetHeight(BlockCoordinates coords)
        {
            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(new ChunkCoordinates(coords.X >> 4, coords.Z >> 4), out chunk))
            {
                //Worlds.ChunkColumn realColumn = (Worlds.ChunkColumn)chunk;
                return(chunk.GetHeight(coords.X & 0xf, coords.Z & 0xf));
            }

            return(255);
        }
Пример #13
0
        private bool CanPlaceBlock(BlockCoordinates coordinates, Block block)
        {
            var bb       = block.GetBoundingBox(coordinates);
            var playerBb = GetBoundingBox(KnownPosition);

            if (playerBb.Intersects(bb))
            {
                return(false);
            }

            return(true);
        }
Пример #14
0
        public void SetBlockState(int x, int y, int z, BlockState block, int storage, BlockUpdatePriority priority = BlockUpdatePriority.High | BlockUpdatePriority.Neighbors)
        {
            var chunkCoords = new ChunkCoordinates(x >> 4, z >> 4);

            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(chunkCoords, out chunk))
            {
                var cx = x & 0xf;
                var cy = y & 0xff;
                var cz = z & 0xf;

                //var previousBlock = chunk.GetBlockState(cx, cy, cz, storage);
                //if (block.Block.RequiresUpdate)
                {
                    //block = block.Block.BlockPlaced(this, block, new BlockCoordinates(x,y,z));
                }

                chunk.SetBlockState(cx, cy, cz, block, storage);

                EntityManager.RemoveBlockEntity(new BlockCoordinates(x, y, z));

                var type = ScheduleType.Full;

                if ((priority & BlockUpdatePriority.Neighbors) != 0)
                {
                    UpdateNeighbors(x, y, z);
                }

                if ((priority & BlockUpdatePriority.NoGraphic) != 0)
                {
                    type |= ScheduleType.LowPriority;
                }

                var blockCoords = new BlockCoordinates(x, y, z);

                /*if (block.Block.BlockMaterial.BlocksLight)
                 * {
                 *      SetBlockLight(blockCoords, 0);
                 * }
                 */
                ChunkManager.SkyLightCalculator.Calculate(this, blockCoords);

                ChunkManager.BlockLightCalculations.Enqueue(blockCoords);

                //chunk.SetDirty();
                //chunk.IsDirty = true;
                ChunkManager.ScheduleChunkUpdate(chunkCoords, type, (priority & BlockUpdatePriority.Priority) != 0);

                CheckForUpdate(chunkCoords, cx, cz);
            }
        }
Пример #15
0
        private void UpdateNeighbors(int x, int y, int z)
        {
            var source = new BlockCoordinates(x, y, z);

            ScheduleBlockUpdate(source, new BlockCoordinates(x + 1, y, z));
            ScheduleBlockUpdate(source, new BlockCoordinates(x - 1, y, z));

            ScheduleBlockUpdate(source, new BlockCoordinates(x, y, z + 1));
            ScheduleBlockUpdate(source, new BlockCoordinates(x, y, z - 1));

            ScheduleBlockUpdate(source, new BlockCoordinates(x, y + 1, z));
            ScheduleBlockUpdate(source, new BlockCoordinates(x, y - 1, z));
        }
Пример #16
0
        public void ScheduleBlockUpdate(BlockCoordinates coordinates)
        {
            var chunkCoords = new ChunkCoordinates(coordinates.X >> 4, coordinates.Z >> 4);

            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(chunkCoords, out chunk))
            {
                var cx = coordinates.X & 0xf;
                var cy = coordinates.Y & 0xff;
                var cz = coordinates.Z & 0xf;

                chunk.ScheduleBlockUpdate(cx, cy, cz);
            }
        }
Пример #17
0
        public bool TryGetBlockLight(BlockCoordinates coordinates, out byte blockLight)
        {
            blockLight = 0;
            if (coordinates.Y < 0 || coordinates.Y > ChunkColumn.ChunkHeight)
            {
                return(false);
            }

            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(new ChunkCoordinates(coordinates), out chunk))
            {
                blockLight = chunk.GetBlocklight(coordinates.X & 0xf, coordinates.Y & 0xff, coordinates.Z & 0xf);
                return(true);
            }

            return(false);
        }
Пример #18
0
        private void UpdateNeighbors(int x, int y, int z)
        {
            var source = new BlockCoordinates(x, y, z);

            if (Options.VideoOptions.ClientSideLighting)
            {
                new SkyLightCalculations().Calculate(this, source);
            }

            ScheduleBlockUpdate(source, new BlockCoordinates(x + 1, y, z));
            ScheduleBlockUpdate(source, new BlockCoordinates(x - 1, y, z));

            ScheduleBlockUpdate(source, new BlockCoordinates(x, y, z + 1));
            ScheduleBlockUpdate(source, new BlockCoordinates(x, y, z - 1));

            ScheduleBlockUpdate(source, new BlockCoordinates(x, y + 1, z));
            ScheduleBlockUpdate(source, new BlockCoordinates(x, y - 1, z));
        }
Пример #19
0
        public void WorldInteraction(BlockCoordinates position, BlockFace face, int hand, Vector3 cursorPosition)
        {
            var packet = McpeInventoryTransaction.CreateObject();

            packet.transaction = new Transaction()
            {
                ActionType    = (int)McpeInventoryTransaction.ItemUseAction.Use,
                ClickPosition =
                    new System.Numerics.Vector3(cursorPosition.X, cursorPosition.Y, cursorPosition.Z),
                TransactionType = McpeInventoryTransaction.TransactionType.ItemUse,
                EntityId        = NetworkEntityId,
                Position        = new MiNET.Utils.BlockCoordinates(position.X, position.Y, position.Z),
                Face            = (int)face,

                //Item = MiNET.Items.ItemFactory.GetItem()
            };

            SendPacket(packet);
        }
Пример #20
0
        private void UpdateNeighbors(int x, int y, int z)
        {
            var source = new BlockCoordinates(x, y, z);

            if (Options.VideoOptions.ClientSideLighting && Dimension == Dimension.Overworld)
            {
                //ChunkManager.SkyLightCalculator.Calculate(this, source);
                //new SkyLightCalculations().Calculate(this, source);
            }

            ScheduleBlockUpdate(source, new BlockCoordinates(x + 1, y, z));
            ScheduleBlockUpdate(source, new BlockCoordinates(x - 1, y, z));

            ScheduleBlockUpdate(source, new BlockCoordinates(x, y, z + 1));
            ScheduleBlockUpdate(source, new BlockCoordinates(x, y, z - 1));

            ScheduleBlockUpdate(source, new BlockCoordinates(x, y + 1, z));
            ScheduleBlockUpdate(source, new BlockCoordinates(x, y - 1, z));
        }
Пример #21
0
        public void SetSkyLight(BlockCoordinates coordinates, byte p1)
        {
            var         chunkCoords = new ChunkCoordinates(coordinates);
            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(chunkCoords, out chunk))
            {
                if (chunk.SetSkyLight(coordinates.X & 0xf, coordinates.Y & 0xff, coordinates.Z & 0xf, p1))
                {
                    // if ((chunk.Scheduled & ScheduleType.Lighting) != ScheduleType.Lighting)
                    {
                        // ChunkManager.ScheduleChunkUpdate(chunkCoords, ScheduleType.Lighting);
                    }
                    // else
                    {
                        // chunk.Scheduled = chunk.Scheduled | ScheduleType.Lighting;
                    }
                }
            }
        }
Пример #22
0
        private void ScheduleLightingUpdate(BlockCoordinates coordinates, bool blockLight = false)
        {
            var chunkCoords = new ChunkCoordinates(coordinates.X >> 4, coordinates.Z >> 4);

            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(chunkCoords, out chunk))
            {
                var cx = coordinates.X & 0xf;
                var cy = coordinates.Y & 0xff;
                var cz = coordinates.Z & 0xf;

                if (blockLight)
                {
                    chunk.ScheduleBlocklightUpdate(cx, cy, cz);
                }
                else
                {
                    chunk.ScheduleSkylightUpdate(cx, cy, cz);
                }
            }
        }
Пример #23
0
        public void SetBlockLight(BlockCoordinates coordinates, byte value)
        {
            var         chunkCoords = new ChunkCoordinates(coordinates);
            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(chunkCoords, out chunk))
            {
                if (chunk.SetBlocklight(coordinates.X & 0xf, coordinates.Y & 0xff, coordinates.Z & 0xf, value))
                {
                    var x = coordinates.X;
                    var y = coordinates.Y;
                    var z = coordinates.Z;

                    ScheduleLightingUpdate(new BlockCoordinates(x + 1, y, z), true);
                    ScheduleLightingUpdate(new BlockCoordinates(x + -1, y, z), true);

                    ScheduleLightingUpdate(new BlockCoordinates(x, y, z + 1), true);
                    ScheduleLightingUpdate(new BlockCoordinates(x, y, z + -1), true);

                    ScheduleLightingUpdate(new BlockCoordinates(x, y + 1, z), true);
                    ScheduleLightingUpdate(new BlockCoordinates(x, y + -1, z), true);
                }
            }
        }
Пример #24
0
        public void SetSkyLight(BlockCoordinates coordinates, byte p1)
        {
            var         chunkCoords = new ChunkCoordinates(coordinates);
            ChunkColumn chunk;

            if (ChunkManager.TryGetChunk(chunkCoords, out chunk))
            {
                if (chunk.SetSkyLight(coordinates.X & 0xf, coordinates.Y & 0xff, coordinates.Z & 0xf, p1))
                {
                    var x = coordinates.X;
                    var y = coordinates.Y;
                    var z = coordinates.Z;

                    ScheduleLightingUpdate(new BlockCoordinates(x + 1, y, z));
                    ScheduleLightingUpdate(new BlockCoordinates(x - 1, y, z));

                    ScheduleLightingUpdate(new BlockCoordinates(x, y, z + 1));
                    ScheduleLightingUpdate(new BlockCoordinates(x, y, z - 1));

                    ScheduleLightingUpdate(new BlockCoordinates(x, y + 1, z));
                    ScheduleLightingUpdate(new BlockCoordinates(x, y - 1, z));
                }
            }
        }
Пример #25
0
 public byte GetBlockLight(BlockCoordinates coordinates)
 {
     return(GetBlockLight(coordinates.X, coordinates.Y, coordinates.Z));
 }
Пример #26
0
        private bool HandleClick(Item slot, int hand, bool canModifyWorld = true, bool isLeftClick = false)
        {
            SwingArm(true);
            //if (ItemFactory.ResolveItemName(slot.ItemID, out string itemName))
            {
                var flooredAdj      = Vector3.Floor(AdjacentRaytrace);
                var raytraceFloored = Vector3.Floor(Raytraced);

                var adj = flooredAdj - raytraceFloored;
                adj.Normalize();

                var face = adj.GetBlockFace();

                var remainder = new Vector3(AdjacentRaytrace.X - flooredAdj.X,
                                            AdjacentRaytrace.Y - flooredAdj.Y, AdjacentRaytrace.Z - flooredAdj.Z);

                var coordR = new BlockCoordinates(raytraceFloored);

                //IBlock block = null;
                if (!IsWorldImmutable && HasRaytraceResult)
                {
                    var  existingBlock = Level.GetBlock(coordR);
                    bool isBlockItem   = slot is ItemBlock;

                    if (existingBlock.CanInteract && (!isBlockItem || IsSneaking))
                    {
                        Network?.WorldInteraction(coordR, face, hand, remainder);

                        return(true);
                    }

                    if (slot is ItemBlock ib && canModifyWorld)
                    {
                        BlockState blockState = ib.Block;

                        if (blockState != null && !(blockState.Block is Air) && HasRaytraceResult)
                        {
                            if (existingBlock.IsReplacible || !existingBlock.Solid)
                            {
                                if (CanPlaceBlock(coordR, (Block)blockState.Block))
                                {
                                    Level.SetBlockState(coordR, blockState);

                                    Network?.BlockPlaced(coordR.BlockDown(), BlockFace.Up, hand, remainder, this);

                                    return(true);
                                }
                            }
                            else
                            {
                                var target = new BlockCoordinates(raytraceFloored + adj);
                                if (CanPlaceBlock(target, (Block)blockState.Block))
                                {
                                    Level.SetBlockState(target, blockState);

                                    Network?.BlockPlaced(coordR, face, hand, remainder, this);

                                    return(true);
                                }
                            }
                        }
                    }
                }

                if (!(slot is ItemAir) && slot.Id > 0 && slot.Count > 0)
                {
                    ItemUseAction action;
                    if (isLeftClick)
                    {
                        action = HasRaytraceResult ? ItemUseAction.ClickBlock : ItemUseAction.ClickAir;
                    }
                    else
                    {
                        action = HasRaytraceResult ? ItemUseAction.RightClickBlock : ItemUseAction.RightClickAir;
                    }

                    Network?.UseItem(slot, hand, action);
                    return(true);
                }
            }

            return(false);
        }
Пример #27
0
 public IBlock GetBlock(BlockCoordinates position)
 {
     return(GetBlock(position.X, position.Y, position.Z));
 }
Пример #28
0
 public void SetBlockState(BlockCoordinates coordinates, IBlockState blockState)
 {
     SetBlockState(coordinates.X, coordinates.Y, coordinates.Z, blockState);
 }
Пример #29
0
 public BlockCoordinates FindBlockPosition(BlockCoordinates coords, out IChunkColumn chunk)
 {
     ChunkManager.TryGetChunk(new ChunkCoordinates(coords.X >> 4, coords.Z >> 4), out chunk);
     return(new BlockCoordinates(coords.X & 0xf, coords.Y & 0xff, coords.Z & 0xf));
 }
Пример #30
0
 public IBlockState GetBlockState(BlockCoordinates coords)
 {
     return(GetBlockState(coords.X, coords.Y, coords.Z));
 }