예제 #1
0
        protected virtual void PushOutOfBlocks(AbsWorldCoords absWorldCoords)
        {
            UniversalCoords coords = UniversalCoords.FromAbsWorld(absWorldCoords);

            byte?blockId = World.GetBlockId(coords);

            if (blockId == null)
            {
                return;
            }

            BlockBase blockClass = BlockHelper.Instance.CreateBlockInstance((byte)blockId);

            if (blockClass == null)
            {
                Server.Logger.Log(LogLevel.Error, "Block class not found for block type Id {0}", blockId);
                return;
            }

            if (blockClass.IsOpaque && blockClass.IsSolid)
            {
                // The offset within World (int) coords
                Vector3 coordsOffset = new Vector3(absWorldCoords.X - (double)coords.WorldX, absWorldCoords.Y - (double)coords.WorldY, absWorldCoords.Z - (double)coords.WorldZ);

                double    adjustment    = double.MaxValue;
                Direction?moveDirection = null;

                // Calculate the smallest distance needed to move the entity out of the block
                coords.ForAdjacent((aCoord, direction) =>
                {
                    byte?adjBlockId = World.GetBlockId(aCoord);

                    if (adjBlockId == null)
                    {
                        return;
                    }

                    var adjacentBlockClass = BlockHelper.Instance.CreateBlockInstance((byte)adjBlockId) as BlockBase;

                    if (!(adjacentBlockClass.IsOpaque && adjacentBlockClass.IsSolid))
                    {
                        switch (direction)
                        {
                        case Direction.South:
                            if (coordsOffset.X < adjustment)
                            {
                                moveDirection = Direction.South;
                                adjustment    = coordsOffset.X;
                            }
                            break;

                        case Direction.North:
                            if (1.0 - coordsOffset.X < adjustment)
                            {
                                moveDirection = Direction.North;
                                adjustment    = 1.0 - coordsOffset.X;
                            }
                            break;

                        case Direction.Down:
                            if (coordsOffset.Y < adjustment)
                            {
                                moveDirection = Direction.Down;
                                adjustment    = coordsOffset.Y;
                            }
                            break;

                        case Direction.Up:
                            if (1.0 - coordsOffset.Y < adjustment)
                            {
                                moveDirection = Direction.Up;
                                adjustment    = 1.0 - coordsOffset.Y;
                            }
                            break;

                        case Direction.East:
                            if (coordsOffset.Z < adjustment)
                            {
                                moveDirection = Direction.East;
                                adjustment    = coordsOffset.Z;
                            }
                            break;

                        case Direction.West:
                            if (coordsOffset.Z < adjustment)
                            {
                                moveDirection = Direction.West;
                                adjustment    = 1.0 - coordsOffset.Z;
                            }
                            break;
                        }
                    }
                });

                double motion = this.Server.Rand.NextDouble() * 0.2 + 0.1;
                if (moveDirection.HasValue)
                {
                    if (moveDirection.Value == Direction.South)
                    {
                        this.Velocity.X = motion;
                    }
                    else if (moveDirection.Value == Direction.North)
                    {
                        this.Velocity.X = -motion;
                    }
                    else if (moveDirection.Value == Direction.Down)
                    {
                        this.Velocity.Y = -motion;
                    }
                    else if (moveDirection.Value == Direction.Up)
                    {
                        this.Velocity.Y = motion;
                    }
                    else if (moveDirection.Value == Direction.East)
                    {
                        this.Velocity.Z = -motion;
                    }
                    else if (moveDirection.Value == Direction.West)
                    {
                        this.Velocity.Z = motion;
                    }
                }
            }
        }