public override void OnBlockBroken(IWorldAccessor world, BlockPos pos, IPlayer byPlayer, float dropQuantityMultiplier = 1)
        {
            var block = world.BlockAccessor.GetBlock(pos.DownCopy()) as BlockFruitPress;

            if (block != null)
            {
                block.OnBlockBroken(world, pos.DownCopy(), byPlayer, dropQuantityMultiplier);
            }
        }
        internal override bool CanPlantStay(IBlockAccessor blockAccessor, BlockPos pos)
        {
            Block belowBlock      = blockAccessor.GetBlock(pos.DownCopy());
            Block belowbelowBlock = blockAccessor.GetBlock(pos.DownCopy(2));

            return
                (belowBlock.Fertility > 0 ||
                 (Attributes?["stackable"]?.AsBool() == true && belowBlock.Attributes?["stackable"]?.AsBool() == true && belowBlock is BlockBerryBush && belowbelowBlock.Fertility > 0));
        }
        public override void OnNeighbourBlockChange(IWorldAccessor world, BlockPos pos, BlockPos neibpos)
        {
            Block belowBlock = world.BlockAccessor.GetBlock(pos.DownCopy());

            if (!belowBlock.CanAttachBlockAt(world.BlockAccessor, this, pos.DownCopy(), BlockFacing.UP) && (belowBlock != this || FillLevel(world.BlockAccessor, pos.DownCopy()) < 8))
            {
                world.BlockAccessor.BreakBlock(pos, null);
            }
        }
        public override ItemStack OnPickBlock(IWorldAccessor world, BlockPos pos)
        {
            var block = world.BlockAccessor.GetBlock(pos.DownCopy()) as BlockFruitPress;

            if (block != null)
            {
                return(block.OnPickBlock(world, pos.DownCopy()));
            }
            return(base.OnPickBlock(world, pos));
        }
示例#5
0
        public override void OnNeighbourBlockChange(IWorldAccessor world, BlockPos pos, BlockPos neibpos)
        {
            Block belowBlock = world.BlockAccessor.GetBlock(pos.DownCopy());

            if (!belowBlock.CanAttachBlockAt(world.BlockAccessor, this, pos.DownCopy(), BlockFacing.UP) && (belowBlock != this || FillLevel(world.BlockAccessor, pos.DownCopy()) < 8))
            {
                world.BlockAccessor.BreakBlock(pos, null);
                //world.PlaySoundAt(new AssetLocation("sounds/block/plate"), pos.X, pos.Y, pos.Z, null, false);
            }
        }
        public override string GetPlacedBlockInfo(IWorldAccessor world, BlockPos pos, IPlayer forPlayer)
        {
            var block = world.BlockAccessor.GetBlock(pos.DownCopy()) as BlockFruitPress;

            if (block != null)
            {
                return(block.GetPlacedBlockInfo(world, pos.DownCopy(), forPlayer));
            }

            return(base.GetPlacedBlockInfo(world, pos, forPlayer));
        }
示例#7
0
        public override void OnHeldInteractStart(ItemSlot itemslot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handHandling)
        {
            if (blockSel == null || byEntity?.World == null || !byEntity.Controls.Sneak)
            {
                return;
            }

            IWorldAccessor world        = byEntity.World;
            Block          firepitBlock = world.GetBlock(new AssetLocation("firepit-construct1"));

            if (firepitBlock == null)
            {
                return;
            }


            BlockPos onPos = blockSel.DidOffset ? blockSel.Position : blockSel.Position.AddCopy(blockSel.Face);

            IPlayer byPlayer = byEntity.World.PlayerByUid((byEntity as EntityPlayer)?.PlayerUID);

            if (!byEntity.World.Claims.TryAccess(byPlayer, onPos, EnumBlockAccessFlags.BuildOrBreak))
            {
                return;
            }



            Block block   = world.BlockAccessor.GetBlock(onPos.DownCopy());
            Block atBlock = world.BlockAccessor.GetBlock(onPos);

            string useless = "";

            if (!block.CanAttachBlockAt(byEntity.World.BlockAccessor, firepitBlock, onPos.DownCopy(), BlockFacing.UP))
            {
                return;
            }
            if (!firepitBlock.CanPlaceBlock(world, byPlayer, new BlockSelection()
            {
                Position = onPos, Face = BlockFacing.UP
            }, ref useless))
            {
                return;
            }

            world.BlockAccessor.SetBlock(firepitBlock.BlockId, onPos);

            if (firepitBlock.Sounds != null)
            {
                world.PlaySoundAt(firepitBlock.Sounds.Place, blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z, byPlayer);
            }

            itemslot.Itemstack.StackSize--;
            handHandling = EnumHandHandling.PreventDefaultAction;
        }
示例#8
0
        public override string GetPlacedBlockInfo(IWorldAccessor world, BlockPos pos, IPlayer forPlayer)
        {
            Block block = world.BlockAccessor.GetBlock(pos.DownCopy());

            if (block is BlockFarmland)
            {
                return(block.GetPlacedBlockInfo(world, pos.DownCopy(), forPlayer));
            }

            return
                (Lang.Get("Required Nutrient: {0}", CropProps.RequiredNutrient) + "\n" +
                 Lang.Get("Growth Stage: {0} / {1}", CurrentStage(), CropProps.GrowthStages)
                );
        }
        public override bool TryPlaceBlockForWorldGen(IBlockAccessor blockAccessor, BlockPos pos, BlockFacing onBlockFace, LCGRandom worldGenRand)
        {
            Block block = blockAccessor.GetBlock(pos);


            if (block.IsReplacableBy(this) && block.SideSolid[BlockFacing.UP.Index])
            {
                blockAccessor.SetBlock(rndGearBlock().BlockId, pos);
                return(true);
            }

            pos   = pos.DownCopy();
            block = blockAccessor.GetBlock(pos);

            if (block.IsReplacableBy(this) && block.SideSolid[BlockFacing.UP.Index])
            {
                blockAccessor.SetBlock(rndGearBlock().BlockId, pos);
                return(true);
            }

            pos.Down();
            block = blockAccessor.GetBlock(pos);

            if (block.IsReplacableBy(this) && block.SideSolid[BlockFacing.UP.Index])
            {
                blockAccessor.SetBlock(rndGearBlock().BlockId, pos);
                return(true);
            }

            return(false);
        }
        private void SpreadAndUpdateLiquidLevels(IWorldAccessor world, BlockPos pos)
        {
            // Slightly weird hack
            // 1. We call this method also for other blocks, so can't rely on this.bock
            // 2. our own liquid level might have changed from other nearby liquid sources
            Block block = world.BlockAccessor.GetBlock(pos);

            int liquidLevel = block.LiquidLevel;

            if (liquidLevel > 0)
            {
                if (TryLoweringLiquidLevel(block, world, pos) == false)//Lower liquid if not connected to source block
                {
                    Block downBlock     = world.BlockAccessor.GetBlock(pos.DownCopy());
                    bool  onSolidGround = downBlock.Replaceable < ReplacableThreshold;
                    if (!onSolidGround)
                    {
                        TrySpreadDownwards(block, world, pos);
                    }
                    else if (liquidLevel > 1)//Can we still spread somewhere
                    {
                        List <PosAndDist> downwardPaths = FindDownwardPaths(world, pos, block);
                        if (downwardPaths.Count > 0)//Prefer flowing to downward paths rather than outward
                        {
                            FlowTowardDownwardPaths(downwardPaths, block, world);
                        }
                        else if (TryFindSourceAndSpread(pos, world) == false)
                        {
                            TrySpreadHorizontal(block, world, pos);
                        }
                    }
                }
            }
        }
        public override void OnJsonTesselation(ref MeshData sourceMesh, ref int[] lightRgbsByCorner, BlockPos pos, Block[] chunkExtBlocks, int extIndex3d)
        {
            var block = chunkExtBlocks[extIndex3d + TileSideEnum.MoveIndex[TileSideEnum.Down]] as BlockStoneCoffinSection;

            if (block != null)
            {
                int temp      = block.GetTemperature(api.World, pos.DownCopy());
                int extraGlow = GameMath.Clamp((temp - 550) / 2, 0, 255);
                for (int i = 0; i < sourceMesh.FlagsCount; i++)
                {
                    sourceMesh.Flags[i] &= ~0xff;
                    sourceMesh.Flags[i] |= extraGlow;
                }

                int[] incade = ColorUtil.getIncandescenceColor(temp);
                float ina    = GameMath.Clamp(incade[3] / 255f, 0, 1);

                for (int i = 0; i < lightRgbsByCorner.Length; i++)
                {
                    int col = lightRgbsByCorner[i];

                    int r = col & 0xff;
                    int g = (col >> 8) & 0xff;
                    int b = (col >> 16) & 0xff;
                    int a = (col >> 24) & 0xff;

                    lightRgbsByCorner[i] = (GameMath.Mix(a, 0, System.Math.Min(1, 1.5f * ina)) << 24) | (GameMath.Mix(b, incade[2], ina) << 16) | (GameMath.Mix(g, incade[1], ina) << 8) | GameMath.Mix(r, incade[0], ina);
                }
            }
        }
示例#12
0
        public static SimpleParticleProperties TemporalEffectAtPos(this BlockPos pos, ICoreAPI api)
        {
            SimpleParticleProperties p = TemporalEffect;
            Vec3d posvec = pos.DownCopy().MidPoint();
            int   r      = 53;
            int   g      = 221;
            int   b      = 172;

            p.Color = (r << 16) | (g << 8) | (b << 0) | (50 << 24);

            p.AddPos.Set(0, 0, 0);
            p.BlueEvolve    = null;
            p.RedEvolve     = null;
            p.GreenEvolve   = null;
            p.MinSize       = 0.1f;
            p.MaxSize       = 0.2f;
            p.SizeEvolve    = null;
            p.OpacityEvolve = EvolvingNatFloat.create(EnumTransformFunction.LINEAR, 100f);

            double xpos = rndPos.nextFloat();
            double ypos = 1.9 + api.World.Rand.NextDouble() * 0.2;
            double zpos = rndPos.nextFloat();

            p.LifeLength = GameMath.Sqrt(xpos * xpos + zpos * zpos) / 10;
            p.MinPos.Set(posvec.X + xpos, posvec.Y + ypos, posvec.Z + zpos);
            p.MinVelocity.Set(-(float)xpos, -1 - (float)api.World.Rand.NextDouble() / 2, -(float)zpos);
            p.MinQuantity = 0.25f;
            p.AddQuantity = 0;

            return(p);
        }
        bool CanLayerStay(IWorldAccessor world, BlockPos pos)
        {
            BlockPos belowPos = pos.DownCopy();
            Block    block    = world.BlockAccessor.GetBlock(world.BlockAccessor.GetBlockId(belowPos));

            return(block.CanAttachBlockAt(world.BlockAccessor, this, belowPos, BlockFacing.UP));
        }
示例#14
0
 public override void OnNeighourBlockChange(IWorldAccessor world, BlockPos pos, BlockPos neibpos)
 {
     if (!world.BlockAccessor.GetBlock(pos.DownCopy()).SideSolid[BlockFacing.UP.Index])
     {
         world.BlockAccessor.BreakBlock(pos, null);
     }
 }
示例#15
0
        private void TrySpawnNewVine()
        {
            BlockFacing spawnDir       = GetVineSpawnDirection();
            BlockPos    newVinePos     = Pos.AddCopy(spawnDir);
            Block       blockToReplace = Api.World.BlockAccessor.GetBlock(newVinePos);

            if (!IsReplaceable(blockToReplace))
            {
                return;
            }

            Block supportBlock = Api.World.BlockAccessor.GetBlock(newVinePos.DownCopy());

            if (!CanGrowOn(supportBlock))
            {
                return;
            }

            Api.World.BlockAccessor.SetBlock(stage1VineBlock.BlockId, newVinePos);

            BlockEntityPumpkinVine be = Api.World.BlockAccessor.GetBlockEntity(newVinePos) as BlockEntityPumpkinVine;

            if (be != null)
            {
                be.CreatedFromParent(Pos, spawnDir, totalHoursForNextStage);
            }
        }
示例#16
0
        bool TryPlace(EntityItem entityItem, int offX, int offY, int offZ)
        {
            IWorldAccessor world = entityItem.World;
            BlockPos       pos   = entityItem.ServerPos.AsBlockPos.Add(offX, offY, offZ);
            Block          block = world.BlockAccessor.GetBlock(pos.DownCopy());

            if (!block.SideSolid[BlockFacing.UP.Index])
            {
                return(false);
            }

            bool ok = TryPlaceBlock(world, null, entityItem.Itemstack, new BlockSelection()
            {
                Position    = pos,
                Face        = BlockFacing.UP,
                HitPosition = new Vec3d(0.5, 1, 0.5)
            });

            if (ok)
            {
                entityItem.World.PlaySoundAt(entityItem.Itemstack.Block.Sounds?.Place, pos.X, pos.Y, pos.Z, null);
            }

            return(ok);
        }
示例#17
0
        internal bool Construct(ItemSlot slot, IWorldAccessor world, BlockPos pos, IPlayer player)
        {
            Block belowBlock = world.BlockAccessor.GetBlock(pos.DownCopy());

            if (!belowBlock.CanAttachBlockAt(world.BlockAccessor, this, pos.DownCopy(), BlockFacing.UP) && (belowBlock != this || FillLevel(world.BlockAccessor, pos.DownCopy()) != 8))
            {
                return(false);
            }


            world.BlockAccessor.SetBlock(BlockId, pos);

            BlockEntity be = world.BlockAccessor.GetBlockEntity(pos);

            if (be is BlockEntityPeatPile)
            {
                BlockEntityPeatPile pile = (BlockEntityPeatPile)be;
                if (player.WorldData.CurrentGameMode == EnumGameMode.Creative)
                {
                    pile.inventory[0].Itemstack           = slot.Itemstack.Clone();
                    pile.inventory[0].Itemstack.StackSize = 1;
                }
                else
                {
                    pile.inventory[0].Itemstack = slot.TakeOut(player.Entity.Controls.Sprint ? pile.BulkTakeQuantity : pile.DefaultTakeQuantity);
                }

                pile.MarkDirty();
                world.BlockAccessor.MarkBlockDirty(pos);
                world.PlaySoundAt(new AssetLocation("sounds/block/dirt"), pos.X, pos.Y, pos.Z, player, false);
            }


            if (CollisionTester.AabbIntersect(
                    GetCollisionBoxes(world.BlockAccessor, pos)[0],
                    pos.X, pos.Y, pos.Z,
                    player.Entity.SelectionBox,
                    player.Entity.SidedPos.XYZ
                    ))
            {
                player.Entity.SidedPos.Y += GetCollisionBoxes(world.BlockAccessor, pos)[0].Y2;
            }

            (player as IClientPlayer)?.TriggerFpAnimation(EnumHandInteract.HeldItemInteract);

            return(true);
        }
示例#18
0
        public override void OnBlockBroken(IWorldAccessor world, BlockPos pos, IPlayer byPlayer, float dropQuantityMultiplier = 1)
        {
            base.OnBlockBroken(world, pos, byPlayer, dropQuantityMultiplier);

            BlockEntityFarmland befarmland = world.BlockAccessor.GetBlockEntity(pos.DownCopy()) as BlockEntityFarmland;

            befarmland?.OnCropBlockBroken();
        }
 private bool OnPath(IWorldAccessor world, BlockPos pos)
 {
     if (world.BlockAccessor.GetBlock(pos.DownCopy()).FirstCodePart() == this.ownFirstCodePart)
     {
         return(true);
     }
     return(false);
 }
        public override bool CanPlantStay(IBlockAccessor blockAccessor, BlockPos pos)
        {
            Block belowBlock = blockAccessor.GetBlock(pos.DownCopy());

            if (belowBlock.Fertility > 0)
            {
                return(true);
            }
            if (!(belowBlock is BlockBerryBush))
            {
                return(false);
            }

            Block belowbelowBlock = blockAccessor.GetBlock(pos.DownCopy(2));

            return(belowbelowBlock.Fertility > 0 && this.Attributes?.IsTrue("stackable") == true && belowBlock.Attributes?.IsTrue("stackable") == true);
        }
示例#21
0
        public override void OnHeldInteractStart(IItemSlot itemslot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, ref EnumHandHandling handHandling)
        {
            if (blockSel == null || byEntity?.World == null || !byEntity.Controls.Sneak)
            {
                return;
            }

            IWorldAccessor world        = byEntity.World;
            Block          firepitBlock = world.GetBlock(new AssetLocation("firepit-construct1"));

            if (firepitBlock == null)
            {
                return;
            }

            IPlayer player = byEntity.World.PlayerByUid((byEntity as EntityPlayer)?.PlayerUID);

            if (!byEntity.World.TestPlayerAccessBlock(player, blockSel.Position, EnumBlockAccessFlags.BuildOrBreak))
            {
                return;
            }

            BlockPos onPos = blockSel.DidOffset ? blockSel.Position : blockSel.Position.AddCopy(blockSel.Face);

            Block block   = world.BlockAccessor.GetBlock(onPos.DownCopy());
            Block atBlock = world.BlockAccessor.GetBlock(onPos);

            if (!block.CanAttachBlockAt(byEntity.World.BlockAccessor, firepitBlock, onPos.DownCopy(), BlockFacing.UP))
            {
                return;
            }
            if (!firepitBlock.IsSuitablePosition(world, onPos))
            {
                return;
            }

            world.BlockAccessor.SetBlock(firepitBlock.BlockId, onPos);

            if (firepitBlock.Sounds != null)
            {
                world.PlaySoundAt(firepitBlock.Sounds.Place, blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z);
            }

            itemslot.Itemstack.StackSize--;
            handHandling = EnumHandHandling.PreventDefaultAction;
        }
示例#22
0
        private bool CanSpawnAt(IBlockAccessor blockAccessor, EntityProperties type, BlockPos pos, Vec3d posAsVec, BaseSpawnConditions sc, float rain, float temp, float forestDensity, float shrubsDensity)
        {
            if (!api.World.BlockAccessor.IsValidPos(pos))
            {
                return(false);
            }

            float?lightLevel = blockAccessor.GetLightLevel(pos, EnumLightLevelType.MaxLight);

            if (lightLevel == null)
            {
                return(false);
            }
            if (sc.MinLightLevel > lightLevel || sc.MaxLightLevel < lightLevel)
            {
                return(false);
            }
            if (sc.MinTemp > temp || sc.MaxTemp < temp)
            {
                return(false);
            }
            if (sc.MinRain > rain || sc.MaxRain < rain)
            {
                return(false);
            }
            if (sc.MinForest > forestDensity || sc.MaxForest < forestDensity)
            {
                return(false);
            }
            if (sc.MinShrubs > shrubsDensity || sc.MaxShrubs < shrubsDensity)
            {
                return(false);
            }
            if (sc.MinForestOrShrubs > Math.Max(forestDensity, shrubsDensity))
            {
                return(false);
            }


            Block belowBlock = blockAccessor.GetBlock(pos.X, pos.Y - 1, pos.Z);

            if (!belowBlock.CanCreatureSpawnOn(blockAccessor, pos.DownCopy(), type, sc))
            {
                return(false);
            }

            Block block = blockAccessor.GetBlock(pos);

            if (!block.WildCardMatch(sc.InsideBlockCodes))
            {
                return(false);
            }

            Cuboidf collisionBox = type.SpawnCollisionBox.OmniNotDownGrowBy(0.1f);

            return(!IsColliding(collisionBox, posAsVec));
        }
        protected bool TryStackDown(IPlayer byPlayer, IWorldAccessor world, BlockPos pos, BlockFacing face, ItemStack itemstack)
        {
            Block  ladderBlock = world.BlockAccessor.GetBlock(pos);
            string ladderType  = ladderBlock.GetBehavior <BlockBehaviorLadder>()?.LadderType;

            if (ladderType != LadderType)
            {
                return(false);
            }

            BlockPos belowPos   = pos.DownCopy();
            Block    belowBlock = null;

            while (belowPos.Y > 0)
            {
                belowBlock = world.BlockAccessor.GetBlock(belowPos);
                if (belowBlock.FirstCodePart() != ownFirstCodePart)
                {
                    break;
                }

                belowPos.Down();
            }

            string useless = "";

            if (belowBlock == null || belowBlock.FirstCodePart() == ownFirstCodePart)
            {
                return(false);
            }
            if (!belowBlock.IsReplacableBy(block))
            {
                return(false);
            }
            if (!ladderBlock.CanPlaceBlock(world, byPlayer, new BlockSelection()
            {
                Position = belowPos, Face = face
            }, ref useless))
            {
                return(false);
            }

            ladderBlock.DoPlaceBlock(world, byPlayer, new BlockSelection()
            {
                Position = belowPos, Face = face
            }, itemstack);

            BlockPos neibPos = new BlockPos();

            foreach (BlockFacing facing in BlockFacing.ALLFACES)
            {
                neibPos.Set(belowPos).Offset(facing);
                world.BlockAccessor.GetBlock(neibPos).OnNeighbourBlockChange(world, neibPos, belowPos);
            }

            return(true);
        }
示例#24
0
        public override string GetPlacedBlockInfo(IWorldAccessor world, BlockPos pos, IPlayer forPlayer)
        {
            string info = world.BlockAccessor.GetBlock(pos.DownCopy()).GetPlacedBlockInfo(world, pos.DownCopy(), forPlayer);

            return
                ("Required Nutrient: " + CropProps.RequiredNutrient + "\n" +
                 "Growth stage: " + CurrentStage() + " / " + CropProps.GrowthStages +
                 (info != null && info.Length > 0 ? "\n\nSoil:\n" + info : "")
                );
        }
示例#25
0
        public override string GetPlacedBlockInfo(IWorldAccessor world, BlockPos pos, IPlayer forPlayer)
        {
            string info = world.BlockAccessor.GetBlock(pos.DownCopy()).GetPlacedBlockInfo(world, pos.DownCopy(), forPlayer);

            return
                (Lang.Get("Required Nutrient: {0}", CropProps.RequiredNutrient) + "\n" +
                 Lang.Get("Growth Stage: {0} / {1}", CurrentStage(), CropProps.GrowthStages - 1) +
                 (info != null && info.Length > 0 ? "\n\n" + Lang.Get("soil-tooltip") + "\n" + info : "")
                );
        }
示例#26
0
        public override void OnNeighourBlockChange(IWorldAccessor world, BlockPos pos, BlockPos neibpos)
        {
            Block belowBlock = world.BlockAccessor.GetBlock(pos.DownCopy());

            if (!belowBlock.SideSolid[BlockFacing.UP.Index] && (belowBlock != this || FillLevel(world.BlockAccessor, pos.DownCopy()) < 8))
            {
                world.BlockAccessor.BreakBlock(pos, null);
                //world.PlaySoundAt(new AssetLocation("sounds/block/ingot"), pos.X, pos.Y, pos.Z, null, false);
            }
        }
 public override void OnBlockPlaced(IWorldAccessor world, BlockPos blockPos, ref EnumHandling handling)
 {
     if (!world.BlockAccessor.GetBlock(blockPos.DownCopy()).Code.Path.Equals("firewoodpile"))
     {
         int completedFirepitBlockId = world.GetBlock(new AssetLocation("firepit-cold"))?.Id ?? 0;
         if (completedFirepitBlockId != 0)
         {
             world.BlockAccessor.SetBlock(completedFirepitBlockId, blockPos);
         }
     }
 }
示例#28
0
        public override bool TryPlaceBlockForWorldGen(IBlockAccessor blockAccessor, BlockPos pos, BlockFacing onBlockFace, LCGRandom worldGenRand)
        {
            blockAccessor.SetBlock(BlockId, pos);

            if (soilBlockId > 0 && blockAccessor.GetBlock(pos.X, pos.Y - 1, pos.Z).BlockMaterial == EnumBlockMaterial.Stone)
            {
                blockAccessor.SetBlock(soilBlockId, pos.DownCopy());
            }

            return(true);
        }
        protected bool TryCollectLowest(IPlayer byPlayer, IWorldAccessor world, BlockPos pos)
        {
            Block ladderBlock = world.BlockAccessor.GetBlock(pos);

            if (ladderBlock.FirstCodePart() != ownFirstCodePart)
            {
                return(false);
            }

            BlockPos belowPos = pos.DownCopy();
            Block    belowBlock;

            while (belowPos.Y > 0)
            {
                belowBlock = world.BlockAccessor.GetBlock(belowPos);
                if (belowBlock.FirstCodePart() != ownFirstCodePart)
                {
                    break;
                }

                belowPos.Down();
            }

            belowPos.Up();
            Block collectBlock = world.BlockAccessor.GetBlock(belowPos);

            var bh = collectBlock.GetBehavior <BlockBehaviorLadder>();

            if (bh == null || !bh.isFlexible)
            {
                return(false);
            }

            if (!world.Claims.TryAccess(byPlayer, belowPos, EnumBlockAccessFlags.BuildOrBreak))
            {
                return(false);
            }

            ItemStack[] stacks = collectBlock.GetDrops(world, pos, byPlayer);

            world.BlockAccessor.SetBlock(0, belowPos);
            world.PlaySoundAt(collectBlock.Sounds.Break, pos.X + 0.5, pos.Y + 0.5, pos.Z + 0.5, byPlayer);

            if (stacks.Length > 0)
            {
                if (!byPlayer.InventoryManager.TryGiveItemstack(stacks[0], true))
                {
                    world.SpawnItemEntity(stacks[0], byPlayer.Entity.Pos.XYZ);
                }
            }


            return(true);
        }
        public bool HasSupportDown(Block forBlock, IBlockAccessor blockAccess, BlockPos pos)
        {
            BlockFacing ownFacing = BlockFacing.FromCode(forBlock.LastCodePart());

            BlockPos downPos = pos.DownCopy();

            return
                (SideSolid(blockAccess, pos, ownFacing) ||
                 SideSolid(blockAccess, downPos, BlockFacing.DOWN) ||
                 (pos.Y > 0 && blockAccess.GetBlock(downPos) == forBlock && HasSupportDown(forBlock, blockAccess, downPos))
                );
        }