private bool TryFalling(IWorldAccessor world, BlockPos pos)
        {
            if (world.Side == EnumAppSide.Client)
            {
                return(false);
            }

            ICoreServerAPI sapi = (world as IServerWorldAccessor).Api as ICoreServerAPI;

            if (!sapi.Server.Config.AllowFallingBlocks)
            {
                return(false);
            }

            if (IsReplacableBeneath(world, pos))
            {
                // Prevents duplication
                Entity entity = world.GetNearestEntity(pos.ToVec3d().Add(0.5, 0.5, 0.5), 1, 3, (e) =>
                {
                    return(e is EntityBlockFalling && ((EntityBlockFalling)e).initialPos.Equals(pos));
                }
                                                       );

                if (entity == null)
                {
                    EntityBlockFalling entityblock = new EntityBlockFalling(block, world.BlockAccessor.GetBlockEntity(pos), pos);
                    world.SpawnEntity(entityblock);
                }

                return(true);
            }

            return(false);
        }
        private bool TryFalling(IWorldAccessor world, BlockPos pos, ref EnumHandling handling, ref string failureCode)
        {
            if (world.Side != EnumAppSide.Server)
            {
                return(false);
            }
            if (!fallSideways && IsAttached(world.BlockAccessor, pos))
            {
                return(false);
            }

            ICoreServerAPI sapi = (world as IServerWorldAccessor).Api as ICoreServerAPI;

            if (!sapi.Server.Config.AllowFallingBlocks)
            {
                return(false);
            }


            if (IsReplacableBeneath(world, pos) || (fallSideways && world.Rand.NextDouble() < fallSidewaysChance && IsReplacableBeneathAndSideways(world, pos)))
            {
                // Prevents duplication
                Entity entity = world.GetNearestEntity(pos.ToVec3d().Add(0.5, 0.5, 0.5), 1, 1.5f, (e) =>
                {
                    return(e is EntityBlockFalling && ((EntityBlockFalling)e).initialPos.Equals(pos));
                });

                if (entity == null)
                {
                    EntityBlockFalling entityblock = new EntityBlockFalling(block, world.BlockAccessor.GetBlockEntity(pos), pos, fallSound, impactDamageMul, true, dustIntensity);
                    world.SpawnEntity(entityblock);
                }
                else
                {
                    handling    = EnumHandling.PreventDefault;
                    failureCode = "entityintersecting";
                    return(false);
                }

                handling = EnumHandling.PreventSubsequent;
                return(true);
            }

            handling = EnumHandling.PassThrough;
            return(false);
        }
Beispiel #3
0
        private bool TryPartialCollapse(BlockPos pos, int quantity)
        {
            if (inventory[0].Empty)
            {
                return(false);
            }

            IWorldAccessor world = Api.World;

            if (world.Side == EnumAppSide.Server)
            {
                ICoreServerAPI sapi = (world as IServerWorldAccessor).Api as ICoreServerAPI;
                if (!sapi.Server.Config.AllowFallingBlocks)
                {
                    return(false);
                }
            }

            if (IsReplacableBeneath(world, pos) || IsReplacableBeneathAndSideways(world, pos))
            {
                // Prevents duplication
                Entity entity = world.GetNearestEntity(pos.ToVec3d().Add(0.5, 0.5, 0.5), 1, 1.5f, (e) =>
                {
                    return(e is EntityBlockFalling && ((EntityBlockFalling)e).initialPos.Equals(pos));
                });

                if (entity == null)
                {
                    int prevstacksize = inventory[0].StackSize;

                    inventory[0].Itemstack.StackSize = quantity;
                    EntityBlockFalling entityblock = new EntityBlockFalling(Block, this, pos, null, 1, true, 0.05f);
                    entityblock.DoRemoveBlock = false; // We want to split the pile, not remove it
                    world.SpawnEntity(entityblock);
                    entityblock.ServerPos.Y -= 0.25f;
                    entityblock.Pos.Y       -= 0.25f;

                    inventory[0].Itemstack.StackSize = prevstacksize - quantity;
                    return(true);
                }
            }


            return(false);
        }
Beispiel #4
0
        public override void OnBlockBroken(IWorldAccessor world, BlockPos pos, IPlayer byPlayer, float dropQuantityMultiplier = 1)
        {
            base.OnBlockBroken(world, pos, byPlayer, dropQuantityMultiplier);

            EntityProperties type   = world.GetEntityType(new AssetLocation("beemob"));
            Entity           entity = world.ClassRegistry.CreateEntity(type);

            if (entity != null)
            {
                entity.ServerPos.X   = pos.X + 0.5f;
                entity.ServerPos.Y   = pos.Y + 0.5f;
                entity.ServerPos.Z   = pos.Z + 0.5f;
                entity.ServerPos.Yaw = (float)world.Rand.NextDouble() * 2 * GameMath.PI;
                entity.Pos.SetFrom(entity.ServerPos);

                entity.Attributes.SetString("origin", "brokenbeehive");
                world.SpawnEntity(entity);
            }
        }
Beispiel #5
0
        public static void Postfix(BlockBehaviorUnstableFalling __instance, IWorldAccessor world, BlockPos pos, ref EnumHandling handling, ref string failureCode)
        {
            if (world.Side == EnumAppSide.Client)
            {
                return;
            }

            Block block = __instance.block;

            BlockPhysics physics = new BlockPhysics(world.Api);

            if (physics.CanCollapse(pos, block))
            {
                AssetLocation fallSound       = __instance.GetField <AssetLocation>("fallSound");
                float         impactDamageMul = __instance.GetField <float>("impactDamageMul");
                float         dustIntensity   = __instance.GetField <float>("dustIntensity");

                // Prevents duplication
                Entity entity = world.GetNearestEntity(pos.ToVec3d().Add(0.5, 0.5, 0.5), 1, 1.5f, (e) =>
                {
                    return(e is EntityBlockFalling && ((EntityBlockFalling)e).initialPos.Equals(pos));
                });

                if (entity == null)
                {
                    EntityBlockFalling entityblock = new EntityBlockFalling(block, world.BlockAccessor.GetBlockEntity(pos), pos, fallSound, impactDamageMul, true, dustIntensity);
                    world.SpawnEntity(entityblock);
                }
                else
                {
                    handling    = EnumHandling.PreventDefault;
                    failureCode = "entityintersecting";
                    return;
                }

                handling = EnumHandling.PreventSubsequent;
                return;
            }

            handling = EnumHandling.PassThrough;
        }
Beispiel #6
0
        private bool TryFalling(IWorldAccessor world, BlockPos pos)
        {
            if (IsReplacableBeneath(world, pos))
            {
                // Prevents duplication
                IEntity entity = world.GetNearestEntity(pos.ToVec3d().Add(0.5, 0.5, 0.5), 1, 3, (e) =>
                {
                    return(e is EntityBlockFalling && ((EntityBlockFalling)e).initialPos.Equals(pos));
                }
                                                        );

                if (entity == null)
                {
                    EntityBlockFalling entityblock = new EntityBlockFalling(block, world.BlockAccessor.GetBlockEntity(pos), pos);
                    world.SpawnEntity(entityblock);
                }

                return(true);
            }

            return(false);
        }
Beispiel #7
0
        /// <summary>
        /// Places all the entities and blocks in the schematic at the position.
        /// </summary>
        /// <param name="blockAccessor"></param>
        /// <param name="worldForCollectibleResolve"></param>
        /// <param name="startPos"></param>
        public void PlaceEntitiesAndBlockEntities(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos startPos)
        {
            BlockPos curPos = new BlockPos();

            int schematicSeed = worldForCollectibleResolve.Rand.Next();

            foreach (var val in BlockEntities)
            {
                uint index = val.Key;
                int  dx    = (int)(index & 0x1ff);
                int  dy    = (int)((index >> 20) & 0x1ff);
                int  dz    = (int)((index >> 10) & 0x1ff);

                curPos.Set(dx + startPos.X, dy + startPos.Y, dz + startPos.Z);

                BlockEntity be = blockAccessor.GetBlockEntity(curPos);


                // Block entities need to be manually initialized for world gen block access
                if (be == null && blockAccessor is IWorldGenBlockAccessor)
                {
                    Block block = blockAccessor.GetBlock(curPos);

                    if (block.EntityClass != null)
                    {
                        blockAccessor.SpawnBlockEntity(block.EntityClass, curPos);
                        be = blockAccessor.GetBlockEntity(curPos);
                    }
                }

                if (be != null)
                {
                    Block block = blockAccessor.GetBlock(curPos);
                    if (block.EntityClass != worldForCollectibleResolve.ClassRegistry.GetBlockEntityClass(be.GetType()))
                    {
                        worldForCollectibleResolve.Logger.Warning("Could not import block entity data for schematic at {0}. There is already {1}, expected {2}. Probably overlapping ruins.", curPos, be.GetType(), block.EntityClass);
                        continue;
                    }

                    ITreeAttribute tree = DecodeBlockEntityData(val.Value);
                    tree.SetInt("posx", curPos.X);
                    tree.SetInt("posy", curPos.Y);
                    tree.SetInt("posz", curPos.Z);

                    be.FromTreeAttributes(tree, worldForCollectibleResolve);
                    be.OnLoadCollectibleMappings(worldForCollectibleResolve, BlockCodes, ItemCodes, schematicSeed);
                    be.Pos = curPos.Copy();
                }
            }

            foreach (string entityData in Entities)
            {
                using (MemoryStream ms = new MemoryStream(Ascii85.Decode(entityData)))
                {
                    BinaryReader reader = new BinaryReader(ms);

                    string className = reader.ReadString();
                    Entity entity    = worldForCollectibleResolve.ClassRegistry.CreateEntity(className);

                    entity.FromBytes(reader, false);
                    entity.DidImportOrExport(startPos);

                    // Not ideal but whatever
                    if (blockAccessor is IWorldGenBlockAccessor)
                    {
                        (blockAccessor as IWorldGenBlockAccessor).AddEntity(entity);
                    }
                    else
                    {
                        worldForCollectibleResolve.SpawnEntity(entity);
                    }
                }
            }
        }