Beispiel #1
0
        /// <summary>
        /// Destroy the block
        /// </summary>
        /// <param name="entity">entity who destroyed the block</param>
        /// <param name="block">block that has been destroyed</param>
        public virtual void Destroy(IEntityBase entity, IStructBlock iBlock)
        {
            StructBlock           block     = (StructBlock)iBlock;
            BlockDestroyEventArgs eventArgs = RaiseDestroyEvent(entity, block);

            if (eventArgs.EventCanceled)
            {
                return;
            }

            PlaySoundOnDestroy(entity, block);

            UpdateWorld(block, true);

            // Check if the entity is a player
            if ((entity != null) && (entity is Player))
            {
                // Check if the player is not in creative mode
                // Don't drop any items if the player is in creative mode
                if (((Player)entity).GameMode == GameMode.Normal)
                {
                    DropItems(entity as EntityBase, block);
                }
            }

            NotifyNearbyBlocks((EntityBase)entity, block);
        }
Beispiel #2
0
        protected override void OnStop()
        {
            UniversalCoords currentBlockCoords = UniversalCoords.FromAbsWorld(Position);
            byte? blockId = World.GetBlockId(currentBlockCoords);

            if (blockId == null)
                return;

            if (BlockHelper.Instance.IsAir((byte)blockId))
            {
                var item = ItemHelper.GetInstance(BlockId);
                item.Count = 1;
                World.Server.DropItem(World, currentBlockCoords, item);
            }
            else
            {
                UniversalCoords aboveBlockCoords = UniversalCoords.FromWorld(currentBlockCoords.WorldX,
                                                                             currentBlockCoords.WorldY + 1,
                                                                             currentBlockCoords.WorldZ);
                StructBlock aboveBlock = new StructBlock(aboveBlockCoords, BlockId, 0, World);
                BlockHelper.Instance.CreateBlockInstance(BlockId).Spawn(aboveBlock);

                foreach (LivingEntity living in World.Server.GetNearbyLivings(World, aboveBlockCoords))
                {
                    if (Math.Abs(living.Position.X - aboveBlockCoords.WorldX) < 2 &&
                        Math.Abs(living.Position.Z - aboveBlockCoords.WorldZ) < 2 &&
                        Math.Abs(living.Position.Y + living.Height - aboveBlockCoords.WorldY) < 2)
                        living.CheckSuffocation();
                }
            }
            base.OnStop();
        }
Beispiel #3
0
        /// <summary>
        /// Destroy the block
        /// </summary>
        /// <param name="entity">entity who destroyed the block</param>
        /// <param name="block">block that has been destroyed</param>
        public virtual void Destroy(IEntityBase entity, IStructBlock iBlock)
        {
            StructBlock block = (StructBlock)iBlock;
            BlockDestroyEventArgs eventArgs = RaiseDestroyEvent(entity, block);
            if (eventArgs.EventCanceled)
                return;
            
            PlaySoundOnDestroy(entity, block);

            UpdateWorld(block, true);

            // Check if the entity is a player
            if ((entity != null) && (entity.GetType() == typeof(Player)))
            {
                // Check if the player is in creative mode
                if (((Player)entity).GameMode == System.Convert.ToByte(1))
                {
                    // Don't drop any items as the player is in creative mode
                    goto skipDrop;
                }
            }

            DropItems(entity as EntityBase, block);

            skipDrop:
            DamageItem(entity);

            NotifyNearbyBlocks((EntityBase)entity, block);
        }
Beispiel #4
0
        /// <summary>
        /// Checks if the block can be placed next to the target one
        /// </summary>
        /// <param name="who">the entity who places the block</param>
        /// <param name="block">the block being placed</param>
        /// <param name="targetBlock">the block being targeted (aimed)</param>
        /// <param name="targetSide">the side of the target block</param>
        /// <returns>true if the block can be placed, false otherwise</returns>
        protected virtual bool CanBePlacedOn(EntityBase who, StructBlock block, StructBlock targetBlock, BlockFace targetSide)
        {
            if (!BlockHelper.Instance.IsSolid(targetBlock.Type))
                return false;

            byte? originalBlock = block.World.GetBlockId(block.Coords);

            if ( originalBlock == null || (originalBlock != (byte)BlockData.Blocks.Air &&
                originalBlock != (byte)BlockData.Blocks.Water &&
                originalBlock != (byte)BlockData.Blocks.Still_Water &&
                originalBlock != (byte)BlockData.Blocks.Lava &&
                originalBlock != (byte)BlockData.Blocks.Still_Lava))
                return false;

            if (!BlockHelper.Instance.IsAir(block.Type) && !BlockHelper.Instance.IsLiquid(block.Type))
            {
                foreach ( EntityBase entity in block.World.Server.GetNearbyEntitiesInternal(block.World, block.Coords))
                {
                    LivingEntity living = entity as LivingEntity;
                    if (living == null)
                        continue;

                    if (living.BoundingBox.IntersectsWith(GetCollisionBoundingBox(block)))
                        return false;
                }
            }

            return true;
        }
Beispiel #5
0
 /// <summary>
 /// Updates world data upon block destruction
 /// </summary>
 /// <param name="block">block that has been destroyed</param>
 protected virtual void UpdateWorld(StructBlock block, bool isDestroyed = false)
 {
     byte newType = (isDestroyed ? (byte)BlockData.Blocks.Air : block.Type);
     byte newMeta = (isDestroyed ? (byte)0 : block.MetaData);
     block.World.SetBlockAndData(block.Coords, newType, newMeta);
     RecalculateChunkValues(block);
 }
Beispiel #6
0
        /// <summary>
        /// Notifies the nearby block that the current block has been destroyed
        /// May be used by recipient block to start the physic simulation etc
        /// </summary>
        /// <param name="entity">entity who destroyed the block</param>
        /// <param name="block">block that has been destroyed</param>
        protected virtual void NotifyNearbyBlocks(EntityBase entity, StructBlock block, bool destroyed = true)
        {
            List<UniversalCoords> blocks = new List<UniversalCoords>(6);
            if (block.Coords.WorldY < 127)
                blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ));
            if (block.Coords.WorldY > 0)
                blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY - 1, block.Coords.WorldZ));
            blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX - 1, block.Coords.WorldY, block.Coords.WorldZ));
            blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX + 1, block.Coords.WorldY, block.Coords.WorldZ));
            blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY, block.Coords.WorldZ - 1));
            blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY, block.Coords.WorldZ + 1));
            byte blockId = 0;
            byte blockMeta = 0;
            foreach (var coords in blocks)
            {
                Chunk chunk = block.World.GetChunk(coords) as Chunk;

                if (chunk == null)
                    break;

                blockId = (byte)chunk.GetType(coords);
                blockMeta = chunk.GetData(coords);
                if (destroyed)
                    BlockHelper.Instance.CreateBlockInstance(blockId).NotifyDestroy(entity, block, new StructBlock(coords, blockId, blockMeta, block.World));
                else
                    BlockHelper.Instance.CreateBlockInstance(blockId).NotifyPlace(entity, block, new StructBlock(coords, blockId, blockMeta, block.World));
            }
        }
Beispiel #7
0
        public virtual void RecalculateChunkValues(StructBlock block)
        {
            Chunk chunk = GetBlockChunk(block);

            if (chunk == null)
            {
                return;
            }
            byte blockX, blockY, blockZ;

            blockX = (byte)block.Coords.BlockX;
            blockY = (byte)block.Coords.BlockY;
            blockZ = (byte)block.Coords.BlockZ;

            byte oldHeight = chunk.HeightMap[blockX, blockZ];

            if (blockY + 1 >= chunk.HeightMap[blockX, blockZ])
            {
                chunk.RecalculateHeight(block.Coords);
            }
#if PROFILE
            Stopwatch watch = new Stopwatch();
            watch.Start();
#endif
            //chunk.SpreadLightFromBlock(blockX, blockY, blockZ, chunk.GetBlockLight(blockX, blockY, blockZ), oldHeight);
#if PROFILE
            watch.Stop();

            block.World.Logger.Log(LogLevel.Info, "Block skylight recalc: {0}ms", watch.ElapsedMilliseconds);
#endif
            block.World.Update(block.Coords, false);
        }
Beispiel #8
0
        /// <summary>
        /// Gets the collision bounding box for the provided location.
        /// </summary>
        /// <returns>
        /// The collision bounding box.
        /// </returns>
        /// <param name='coords'>
        /// Coords.
        /// </param>
        public BoundingBox GetCollisionBoundingBox(StructBlock block)
        {
            UniversalCoords coords = block.Coords;

            return(new BoundingBox(coords.WorldX + BlockBoundsOffset.Minimum.X, coords.WorldY + BlockBoundsOffset.Minimum.Y, coords.WorldZ + BlockBoundsOffset.Minimum.Z,
                                   coords.WorldX + BlockBoundsOffset.Maximum.X, coords.WorldY + BlockBoundsOffset.Maximum.Y, coords.WorldZ + BlockBoundsOffset.Maximum.Z));
        }
Beispiel #9
0
        public override void Place(IEntityBase entity, IStructBlock iBlock, IStructBlock targetIBlock, BlockFace face)
        {
            StructBlock  block  = (StructBlock)iBlock;
            LivingEntity living = entity as LivingEntity;

            if (living == null)
            {
                return;
            }
            switch (living.FacingDirection(4))
            {
            case "N":
                block.MetaData = (byte)MetaData.Door.Northwest;
                break;

            case "W":
                block.MetaData = (byte)MetaData.Door.Southwest;
                break;

            case "S":
                block.MetaData = (byte)MetaData.Door.Southeast;
                break;

            case "E":
                block.MetaData = (byte)MetaData.Door.Northeast;
                break;

            default:
                return;
            }
            base.Place(entity, block, targetIBlock, face);
        }
Beispiel #10
0
 protected override void NotifyDestroy(EntityBase entity, StructBlock sourceBlock, StructBlock targetBlock)
 {
     if ((targetBlock.Coords.WorldY - sourceBlock.Coords.WorldY) == 1 &&
         targetBlock.Coords.WorldX == sourceBlock.Coords.WorldX &&
         targetBlock.Coords.WorldZ == sourceBlock.Coords.WorldZ)
         Destroy(targetBlock);
     base.NotifyDestroy(entity, sourceBlock, targetBlock);
 }
Beispiel #11
0
 protected override void UpdateWorld(StructBlock block, bool isDestroyed = false)
 {
     if (isDestroyed)
     {
         ContainerFactory.Destroy((WorldManager)block.World, block.Coords);
     }
     base.UpdateWorld(block, isDestroyed);
 }
Beispiel #12
0
 /// <summary>
 /// Raises the block placement event
 /// </summary>
 /// <param name="entity">entity who placed the block</param>
 /// <param name="block">block that has been placed</param>
 /// <returns>resulting event args</returns>
 protected virtual bool RaisePlaceEvent(IEntityBase entity, StructBlock block)
 {
     BlockPlaceEventArgs e = new BlockPlaceEventArgs(this, entity);
     block.World.Server.PluginManager.CallEvent(Event.BlockPlace, e);
     // Destruction made not by the living can not be interrupted?
     if (entity == null)
         return true;
     return !e.EventCanceled;
 }
Beispiel #13
0
 public RayTraceHitBlock RayTraceIntersection(StructBlock block, Vector3 start, Vector3 end)
 {
     BoundingBox boundingBox = GetCollisionBoundingBox(block);
     
     RayTraceHit rayTraceHit = boundingBox.RayTraceIntersection(start, end);
     if (rayTraceHit != null)
         return new RayTraceHitBlock(block.Coords, rayTraceHit.FaceHit, rayTraceHit.Hit);
     
     return null;          
 }
Beispiel #14
0
 protected override bool CanBePlacedOn(EntityBase who, StructBlock block, StructBlock targetBlock, BlockFace targetSide)
 {
     if (block.Coords.WorldY > 125)
         return false;
     UniversalCoords blockAbove = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1,
                                                            block.Coords.WorldZ);
     if (block.World.GetBlockId(blockAbove) != (byte)BlockData.Blocks.Air)
         return false;
     return base.CanBePlacedOn(who, block, targetBlock, targetSide);
 }
Beispiel #15
0
 protected override void NotifyDestroy(EntityBase entity, StructBlock sourceBlock, StructBlock targetBlock)
 {
     if ((targetBlock.Coords.WorldY - sourceBlock.Coords.WorldY) == 1 &&
         targetBlock.Coords.WorldX == sourceBlock.Coords.WorldX &&
         targetBlock.Coords.WorldZ == sourceBlock.Coords.WorldZ)
     {
         Destroy(targetBlock);
     }
     base.NotifyDestroy(entity, sourceBlock, targetBlock);
 }
Beispiel #16
0
        protected override bool CanBePlacedOn(EntityBase who, StructBlock block, StructBlock targetBlock, BlockFace targetSide)
        {
            Chunk chunk = GetBlockChunk(block);
            Chunk targetChunk = GetBlockChunk(targetBlock);
            if (chunk == null || targetChunk == null)
                return false;
            if (targetSide == BlockFace.Down)
                return false;

            return base.CanBePlacedOn(who, block, targetBlock, targetSide);
        }
Beispiel #17
0
        public override void Place(IEntityBase entity, IStructBlock iBlock, IStructBlock targetIBlock, BlockFace face)
        {
            StructBlock  block       = (StructBlock)iBlock;
            StructBlock  targetBlock = (StructBlock)targetIBlock;
            LivingEntity living      = (entity as LivingEntity);

            if (living == null)
            {
                return;
            }
            block.MetaData = GetDirection(living, block, targetBlock, face);
            base.Place(entity, block, targetBlock, face);
        }
Beispiel #18
0
 protected override void UpdateWorld(StructBlock block, bool isDestroyed = false)
 {
     base.UpdateWorld(block, isDestroyed);
     if (isDestroyed)
         return;
     if ((block.MetaData & 8) != 0 && block.Coords.WorldY < 127)
     {
         UniversalCoords upperBlock = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1,
                                                                block.Coords.WorldZ);
         StructBlock upperHalf = new StructBlock(upperBlock, (byte)Type, (byte)(block.MetaData | 8), block.World);
         BlockHelper.Instance.CreateBlockInstance((byte)Type).Spawn(upperHalf);
     }
 }
Beispiel #19
0
        protected override bool CanBePlacedOn(EntityBase who, StructBlock block, StructBlock targetBlock, BlockFace targetSide)
        {
            if (block.Coords.WorldY > 125)
            {
                return(false);
            }
            UniversalCoords blockAbove = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1,
                                                                   block.Coords.WorldZ);

            if (block.World.GetBlockId(blockAbove) != (byte)BlockData.Blocks.Air)
            {
                return(false);
            }
            return(base.CanBePlacedOn(who, block, targetBlock, targetSide));
        }
Beispiel #20
0
 /// <summary>
 /// Invoked to drop the loot after block destruction
 /// </summary>
 /// <param name="entity">entity that destroyed the block</param>
 /// <param name="block">block that has been destroyed</param>
 protected virtual void DropItems(EntityBase entity, StructBlock block, List<ItemStack> overridedLoot = null)
 {
     List<ItemStack> toDrop;
     if (overridedLoot != null && overridedLoot.Count > 0)
         toDrop = overridedLoot;
     else if (LootTable != null && LootTable.Count > 0)
         toDrop = LootTable;
     else
         return;
     foreach (var lootEntry in toDrop)
     {
         if (lootEntry.Count > 0)
             block.World.Server.DropItem(block.World, block.Coords, lootEntry);
     }
 }
Beispiel #21
0
 protected override void UpdateWorld(StructBlock block, bool isDestroyed = false)
 {
     base.UpdateWorld(block, isDestroyed);
     if (isDestroyed)
     {
         return;
     }
     if ((block.MetaData & 8) != 0 && block.Coords.WorldY < 127)
     {
         UniversalCoords upperBlock = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1,
                                                                block.Coords.WorldZ);
         StructBlock upperHalf = new StructBlock(upperBlock, (byte)Type, (byte)(block.MetaData | 8), block.World);
         BlockHelper.Instance.CreateBlockInstance((byte)Type).Spawn(upperHalf);
     }
 }
Beispiel #22
0
        protected virtual byte GetDirection(LivingEntity living, StructBlock block, StructBlock targetBlock, BlockFace face)
        {
            byte direction = 0;

            switch (face)
            {
            case BlockFace.East:
                direction = (byte)MetaData.Container.East;
                break;

            case BlockFace.West:
                direction = (byte)MetaData.Container.West;
                break;

            case BlockFace.North:
                direction = (byte)MetaData.Container.North;
                break;

            case BlockFace.South:
                direction = (byte)MetaData.Container.South;
                break;

            default:
                switch (living.FacingDirection(4))     // Built on floor, set by facing dir
                {
                case "N":
                    direction = (byte)MetaData.Container.North;
                    break;

                case "W":
                    direction = (byte)MetaData.Container.West;
                    break;

                case "S":
                    direction = (byte)MetaData.Container.South;
                    break;

                case "E":
                    direction = (byte)MetaData.Container.East;
                    break;

                default:
                    return(0);
                }
                break;
            }
            return(direction);
        }
Beispiel #23
0
        protected override bool CanBePlacedOn(EntityBase who, StructBlock block, StructBlock targetBlock, BlockFace targetSide)
        {
            Chunk chunk       = GetBlockChunk(block);
            Chunk targetChunk = GetBlockChunk(targetBlock);

            if (chunk == null || targetChunk == null)
            {
                return(false);
            }
            if (targetSide == BlockFace.Down)
            {
                return(false);
            }

            return(base.CanBePlacedOn(who, block, targetBlock, targetSide));
        }
Beispiel #24
0
        /// <summary>
        /// Plays the sound on block destruction
        /// </summary>
        /// <param name="entity">entity that destroyed the block</param>
        /// <param name="block">block that has been destroyed</param>
        protected virtual void PlaySoundOnDestroy(IEntityBase entity, StructBlock block)
        {
            foreach (Client c in block.World.Server.GetNearbyPlayersInternal(block.World, block.Coords))
            {
                if (c.Owner == entity)
                    continue;

                c.SendPacket(new SoundOrParticleEffectPacket
                {
                    EffectID = SoundOrParticleEffectPacket.SoundOrParticleEffect.PARTICLE_BLOCK_BREAK,
                    X = block.Coords.WorldX,
                    Y = block.Coords.WorldY,
                    Z = block.Coords.WorldZ,
                    SoundData = block.Type
                });
            }
        }
Beispiel #25
0
        /// <summary>
        /// Places the block
        /// </summary>
        /// <param name="entity">entity who placed the block</param>
        /// <param name="block">block that is being placed</param>
        /// <param name="targetBlock">block that is being targeted (aimed)</param>
        /// <param name="face">side of the target block</param>
        public virtual void Place(IEntityBase ientity, IStructBlock iBlock, IStructBlock targetIBlock, BlockFace face)
        {
            StructBlock block = (StructBlock) iBlock;
            StructBlock targetBlock = (StructBlock) targetIBlock;
            EntityBase entity = (EntityBase) ientity;
            if (!CanBePlacedOn(entity, block, targetBlock, face) || !RaisePlaceEvent(entity, block))
            {
                // Revert the change since the client has already graphically placed the block
                if(entity is Player)
                {
                    Player player = entity as Player;
                    player.Server.SendPacketToNearbyPlayers(player.World, player.Position, new BlockChangePacket{Data = targetBlock.MetaData, Type = targetBlock.Type, X = targetBlock.Coords.WorldX, Y = (sbyte)targetBlock.Coords.WorldY, Z = targetBlock.Coords.WorldZ});
                }
                return;
            }

            UpdateWorld(block);
            RemoveItem(entity);
            NotifyNearbyBlocks(entity, block, false);
        }
Beispiel #26
0
        protected virtual byte GetDirection(LivingEntity living, StructBlock block, StructBlock targetBlock, BlockFace face)
        {
            byte direction = 0;
            switch (face)
            {
                case BlockFace.East:
                    direction = (byte)MetaData.Container.East;
                    break;
                case BlockFace.West:
                    direction = (byte)MetaData.Container.West;
                    break;
                case BlockFace.North:
                    direction = (byte)MetaData.Container.North;
                    break;
                case BlockFace.South:
                    direction = (byte)MetaData.Container.South;
                    break;
                default:
                    switch (living.FacingDirection(4)) // Built on floor, set by facing dir
                    {
                        case "N":
                            direction = (byte)MetaData.Container.North;
                            break;
                        case "W":
                            direction = (byte)MetaData.Container.West;
                            break;
                        case "S":
                            direction = (byte)MetaData.Container.South;
                            break;
                        case "E":
                            direction = (byte)MetaData.Container.East;
                            break;
                        default:
                            return 0;

                    }
                    break;
            }
            return direction;
        }
Beispiel #27
0
 /// <summary>
 /// Invoked to drop the loot after block destruction
 /// </summary>
 /// <param name="block">block that has been destroyed</param>
 protected virtual void DropItems(StructBlock block, List<ItemStack> overridedLoot = null)
 {
     DropItems(null, block, overridedLoot);
 }
Beispiel #28
0
 /// <summary>
 /// Spawns the block in the world (not placed by the player)
 /// </summary>
 /// <param name="block">block that is being spawned</param>
 public virtual void Spawn(StructBlock block)
 {
     UpdateWorld(block);
     NotifyNearbyBlocks(null, block, false);
 }
Beispiel #29
0
        /// <summary>
        /// Checks if the block can be placed next to the target one
        /// </summary>
        /// <param name="who">the entity who places the block</param>
        /// <param name="block">the block being placed</param>
        /// <param name="targetBlock">the block being targeted (aimed)</param>
        /// <param name="targetSide">the side of the target block</param>
        /// <returns>true if the block can be placed, false otherwise</returns>
        protected virtual bool CanBePlacedOn(EntityBase who, StructBlock block, StructBlock targetBlock, BlockFace targetSide)
        {
            if (!BlockHelper.Instance.IsSolid(targetBlock.Type))
                return false;

            byte? originalBlock = block.World.GetBlockId(block.Coords);

            if ( originalBlock == null || (originalBlock != (byte)BlockData.Blocks.Air &&
                originalBlock != (byte)BlockData.Blocks.Water &&
                originalBlock != (byte)BlockData.Blocks.Still_Water &&
                originalBlock != (byte)BlockData.Blocks.Lava &&
                originalBlock != (byte)BlockData.Blocks.Still_Lava))
                return false;

            if (!BlockHelper.Instance.IsAir(block.Type) && !BlockHelper.Instance.IsLiquid(block.Type))
            {
                foreach ( EntityBase entity in block.World.Server.GetNearbyEntitiesInternal(block.World, block.Coords))
                {
                    LivingEntity living = entity as LivingEntity;
                    if (living == null)
                        continue;

                    if (living.BoundingBox.IntersectsWith(GetCollisionBoundingBox(block)))
                        return false;
                }
            }

            return true;
        }
Beispiel #30
0
 /// <summary>
 /// Spawns the block in the world (not placed by the player)
 /// </summary>
 /// <param name="block">block that is being spawned</param>
 public virtual void Spawn(StructBlock block)
 {
     UpdateWorld(block);
     NotifyNearbyBlocks(null, block, false);
 }
Beispiel #31
0
 /// <summary>
 /// Removes the block from the world. Don't drop anything.
 /// </summary>
 /// <param name="block">block that is being removed</param>
 public virtual void Remove(StructBlock block)
 {
     UpdateWorld(block, true);
     NotifyNearbyBlocks(null, block);
 }
Beispiel #32
0
 protected virtual void NotifyPlace(EntityBase entity, StructBlock sourceBlock, StructBlock targetBlock)
 {
 }
Beispiel #33
0
 /// <summary>
 /// Raises the block destruction event
 /// </summary>
 /// <param name="entity">entity who destroyed the block</param>
 /// <param name="block">block that has been destroyed</param>
 /// <returns>resulting event args</returns>
 protected virtual BlockDestroyEventArgs RaiseDestroyEvent(IEntityBase entity, StructBlock block)
 {
     BlockDestroyEventArgs e = new BlockDestroyEventArgs(this, entity);
     block.World.Server.PluginManager.CallEvent(Event.BlockDestroy, e);
     return e;
 }
Beispiel #34
0
 public virtual void Fertilize(EntityBase entity, StructBlock block)
 { }
Beispiel #35
0
 public Chunk GetBlockChunk(StructBlock block)
 {
     return block.World.GetChunk(block.Coords) as Chunk;
 }
Beispiel #36
0
 /// <summary>
 /// Invoked to drop the loot after block destruction
 /// </summary>
 /// <param name="block">block that has been destroyed</param>
 protected virtual void DropItems(StructBlock block, List <ItemInventory> overridedLoot = null)
 {
     DropItems(null, block, overridedLoot);
 }
Beispiel #37
0
 /// <summary>
 /// Updates world data upon block destruction
 /// </summary>
 /// <param name="block">block that has been destroyed</param>
 protected virtual void UpdateWorld(StructBlock block, bool isDestroyed = false)
 {
     byte newType = (isDestroyed ? (byte)BlockData.Blocks.Air : block.Type);
     byte newMeta = (isDestroyed ? (byte)0 : block.MetaData);
     block.World.SetBlockAndData(block.Coords, newType, newMeta);
     RecalculateChunkValues(block);
 }
Beispiel #38
0
 protected override void UpdateWorld(StructBlock block, bool isDestroyed = false)
 {
     if (isDestroyed)
         ContainerFactory.Destroy((WorldManager)block.World, block.Coords);
     base.UpdateWorld(block, isDestroyed);
 }
Beispiel #39
0
        /// <summary>
        /// Raises the block destruction event
        /// </summary>
        /// <param name="entity">entity who destroyed the block</param>
        /// <param name="block">block that has been destroyed</param>
        /// <returns>resulting event args</returns>
        protected virtual BlockDestroyEventArgs RaiseDestroyEvent(IEntityBase entity, StructBlock block)
        {
            BlockDestroyEventArgs e = new BlockDestroyEventArgs(this, entity);

            block.World.Server.PluginManager.CallEvent(Event.BlockDestroy, e);
            return(e);
        }
Beispiel #40
0
 protected virtual void NotifyPlace(EntityBase entity, StructBlock sourceBlock, StructBlock targetBlock)
 {
 }
Beispiel #41
0
 /// <summary>
 /// Invoked to drop the loot after block destruction
 /// </summary>
 /// <param name="entity">entity that destroyed the block</param>
 /// <param name="block">block that has been destroyed</param>
 protected virtual void DropItems(EntityBase entity, StructBlock block, List<ItemStack> overridedLoot = null)
 {
     List<ItemStack> toDrop;
     if (overridedLoot != null && overridedLoot.Count > 0)
         toDrop = overridedLoot;
     else if (LootTable != null && LootTable.Count > 0)
         toDrop = LootTable;
     else
         return;
     foreach (var lootEntry in toDrop)
     {
         if (lootEntry.Count > 0)
             block.World.Server.DropItem(block.World, block.Coords, lootEntry);
     }
 }
Beispiel #42
0
 /// <summary>
 /// Gets the collision bounding box for the provided location.
 /// </summary>
 /// <returns>
 /// The collision bounding box.
 /// </returns>
 /// <param name='coords'>
 /// Coords.
 /// </param>
 public BoundingBox GetCollisionBoundingBox(StructBlock block)
 {
     UniversalCoords coords = block.Coords;
     return new BoundingBox(coords.WorldX + BlockBoundsOffset.Minimum.X, coords.WorldY + BlockBoundsOffset.Minimum.Y, coords.WorldZ + BlockBoundsOffset.Minimum.Z,
                            coords.WorldX + BlockBoundsOffset.Maximum.X, coords.WorldY + BlockBoundsOffset.Maximum.Y, coords.WorldZ + BlockBoundsOffset.Maximum.Z);
 }
Beispiel #43
0
        /// <summary>
        /// Notifies the nearby block that the current block has been destroyed
        /// May be used by recipient block to start the physic simulation etc
        /// </summary>
        /// <param name="entity">entity who destroyed the block</param>
        /// <param name="block">block that has been destroyed</param>
        protected virtual void NotifyNearbyBlocks(EntityBase entity, StructBlock block, bool destroyed = true)
        {
            List<UniversalCoords> blocks = new List<UniversalCoords>(6);
            if (block.Coords.WorldY < 127)
                blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ));
            if (block.Coords.WorldY > 0)
                blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY - 1, block.Coords.WorldZ));
            blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX - 1, block.Coords.WorldY, block.Coords.WorldZ));
            blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX + 1, block.Coords.WorldY, block.Coords.WorldZ));
            blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY, block.Coords.WorldZ - 1));
            blocks.Add(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY, block.Coords.WorldZ + 1));
            byte blockId = 0;
            byte blockMeta = 0;
            foreach (var coords in blocks)
            {
                Chunk chunk = block.World.GetChunk(coords) as Chunk;

                if (chunk == null)
                    break;

                blockId = (byte)chunk.GetType(coords);
                blockMeta = chunk.GetData(coords);
                if (destroyed)
                    BlockHelper.Instance.CreateBlockInstance(blockId).NotifyDestroy(entity, block, new StructBlock(coords, blockId, blockMeta, block.World));
                else
                    BlockHelper.Instance.CreateBlockInstance(blockId).NotifyPlace(entity, block, new StructBlock(coords, blockId, blockMeta, block.World));
            }
        }
Beispiel #44
0
        public RayTraceHitBlock RayTraceIntersection(StructBlock block, Vector3 start, Vector3 end)
        {
            BoundingBox boundingBox = GetCollisionBoundingBox(block);

            RayTraceHit rayTraceHit = boundingBox.RayTraceIntersection(start, end);
            if (rayTraceHit != null)
                return new RayTraceHitBlock(block.Coords, rayTraceHit.FaceHit, rayTraceHit.Hit);

            return null;
        }
Beispiel #45
0
        /// <summary>
        /// Plays the sound on block destruction
        /// </summary>
        /// <param name="entity">entity that destroyed the block</param>
        /// <param name="block">block that has been destroyed</param>
        protected virtual void PlaySoundOnDestroy(IEntityBase entity, StructBlock block)
        {
            foreach (Client c in block.World.Server.GetNearbyPlayersInternal(block.World, block.Coords))
            {
                if (c.Owner == entity)
                    continue;

                c.SendPacket(new SoundEffectPacket
                {
                    EffectID = SoundEffectPacket.SoundEffect.BLOCK_BREAK,
                    X = block.Coords.WorldX,
                    Y = block.Coords.WorldY,
                    Z = block.Coords.WorldZ,
                    SoundData = block.Type
                });
            }
        }
Beispiel #46
0
        public virtual void RecalculateChunkValues(StructBlock block)
        {
            Chunk chunk = GetBlockChunk(block);

            if (chunk == null)
                return;
            byte blockX, blockY, blockZ;

            blockX = (byte)block.Coords.BlockX;
            blockY = (byte)block.Coords.BlockY;
            blockZ = (byte)block.Coords.BlockZ;

            byte oldHeight = chunk.HeightMap[blockX, blockZ];

            if (blockY + 1 >= chunk.HeightMap[blockX, blockZ])
                chunk.RecalculateHeight(block.Coords);
            #if PROFILE
            Stopwatch watch = new Stopwatch();
            watch.Start();
            #endif
            //chunk.SpreadLightFromBlock(blockX, blockY, blockZ, chunk.GetBlockLight(blockX, blockY, blockZ), oldHeight);
            #if PROFILE
            watch.Stop();

            block.World.Logger.Log(LogLevel.Info, "Block skylight recalc: {0}ms", watch.ElapsedMilliseconds);
            #endif
            block.World.Update(block.Coords, false);
        }
Beispiel #47
0
 /// <summary>
 /// Raises the block placement event
 /// </summary>
 /// <param name="entity">entity who placed the block</param>
 /// <param name="block">block that has been placed</param>
 /// <returns>resulting event args</returns>
 protected virtual bool RaisePlaceEvent(IEntityBase entity, StructBlock block)
 {
     BlockPlaceEventArgs e = new BlockPlaceEventArgs(this, entity);
     block.World.Server.PluginManager.CallEvent(Event.BlockPlace, e);
     // Destruction made not by the living can not be interrupted?
     if (entity == null)
         return true;
     return !e.EventCanceled;
 }
Beispiel #48
0
 public virtual bool IsOpen(StructBlock block)
 {
     // TODO: correctly implement block state for doors
     return false;
 }
Beispiel #49
0
 public Chunk GetBlockChunk(StructBlock block)
 {
     return(block.World.GetChunk(block.Coords) as Chunk);
 }
Beispiel #50
0
 public virtual bool IsOpen(StructBlock block)
 {
     // TODO: correctly implement block state for doors
     return(false);
 }
Beispiel #51
0
 public virtual void Fertilize(EntityBase entity, StructBlock block)
 {
 }
Beispiel #52
0
 /// <summary>
 /// Removes the block from the world. Don't drop anything.
 /// </summary>
 /// <param name="block">block that is being removed</param>
 public virtual void Remove(StructBlock block)
 {
     UpdateWorld(block, true);
     NotifyNearbyBlocks(null, block);
 }