Exemplo n.º 1
0
 /// <summary>
 /// Creates a default instance.
 /// </summary>
 public WorldConfiguration()
 {
     LoadWholeMap = DefaultLoadWholeMap;
      NewPlayerSpawnPoint = new Point3D(DefaultNewPlayerSpawnX,
                                    DefaultNewPlayerSpawnY,
                                    DefaultNewPlayerSpawnZ);
 }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a new point based on given point.
        /// </summary>
        /// <param name="point">Base point</param>
        public Point3D(Point3D point)
        {
            X = point.X;
             Y = point.Y;
             Z = point.Z;

            #if DIAG
             _CloneCounter++;
            #endif
        }
Exemplo n.º 3
0
        internal static float[] GetHighlightCoordinates(this Player player)
        {
            float[] result = new float[12];

             Segment playerSegment = player.CurrentSegment;
             List<Box> checkBoxes = new List<Box>(playerSegment.GetBoxesSynchronized());

             for (int x = playerSegment.X - 8; x <= playerSegment.X + 8; x += 8)
             {
            for (int y = playerSegment.Y - 8; y <= playerSegment.Y + 8; y += 8)
            {
               for (int z = playerSegment.Z - 8; z <= playerSegment.Z + 8; z += 8)
               {
                  if (x == playerSegment.X && y == playerSegment.Y && z == playerSegment.Z)
                  {
                     continue;
                  }

                  checkBoxes.AddRange(ClientWorldManager.Instance.GetSegment(ref x, ref y, ref z).GetBoxesSynchronized());
               }
            }
             }

             Point3D intersection = new Point3D(float.MaxValue, float.MaxValue, float.MaxValue);
             foreach (Box box in checkBoxes)
             {
            if (box.CenterPoint.GetDistanceSquare(player.Location) > HighlightEliminationDistance)
            {
               // too far to even consider
               continue;
            }

            // TODO: calculate interesection
             }

             return result;
        }
Exemplo n.º 4
0
        internal float GetBoxCenterPointDistanceSquare(Point3D point)
        {
            Point3D center = new Point3D(_Box.CenterPoint);

             switch (_Side)
             {
            case Sides.BackX:
               if (center.X - point.X > WorldHelper.HalfSizeX)
               {
                  center.X -= WorldHelper.SizeX;
               }
               break;
            case Sides.BackZ:
               if (center.Z - point.Z > WorldHelper.HalfSizeX)
               {
                  center.Z -= WorldHelper.SizeZ;
               }
               break;
            case Sides.FrontX:
               if (point.X - center.X > WorldHelper.HalfSizeX)
               {
                  center.X += WorldHelper.SizeX;
               }
               break;
            case Sides.FrontZ:
               if (point.Z - center.Z > WorldHelper.HalfSizeX)
               {
                  center.Z += WorldHelper.SizeZ;
               }
               break;
            default:
               throw new InvalidOperationException("Collision wall with invalid side: " + _Side);
             }

             return point.GetDistanceSquare(center);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Sets this point's coordinates to the given point's coordinates and
 /// shift.
 /// </summary>
 /// <param name="point">Base point</param>
 /// <param name="shiftX">X shift</param>
 /// <param name="shiftY">Y shift</param>
 /// <param name="shiftZ">Z shift</param>
 public void Set(Point3D point, float shiftX, float shiftY, float shiftZ)
 {
     Set(point.X + shiftX, point.Y + shiftY, point.Z + shiftZ);
 }
 public void TerrainDataRequest(Connection connection, int terrainMessageId, Point3D location, float rotationLeft, float rotationUp)
 {
     ClientWorldManager.Instance.LoadPlayerColumns(terrainMessageId);
 }
Exemplo n.º 7
0
 /// <summary>
 /// Sets this point's coordinates to the given point's coordinates.
 /// </summary>
 /// <param name="point">Base point</param>
 public void Set(Point3D point)
 {
     X = point.X;
      Y = point.Y;
      Z = point.Z;
 }
Exemplo n.º 8
0
        /// <summary>
        /// Places or removes a block.
        /// </summary>
        /// <param name="place">True to place block</param>
        /// <param name="x">X coordinate of the placed/removed block</param>
        /// <param name="y">Y coordinate of the placed/removed block</param>
        /// <param name="z">Z coordinate of the placed/removed block</param>
        /// <param name="version">Current segment version</param>
        /// <returns>True if block has been placed/removed</returns>
        public bool PlaceOrRemoveBlock(bool place, out int x, out int y, out int z, out uint version)
        {
            x = -1;
             y = -1;
             z = -1;
             version = 0;

             if (!_CanPlaceBlocks)
             {
            return false;
             }

             // check closest intersection
             Point3D eyeLocation = new Point3D(Location, 0.0f, _EyeHeightFromCenter, 0.0f);
             Vector3D line = new Vector3D(eyeLocation, NewDirection);
             Intersection closest = new Intersection();
             List<Tuple<Box, int, int>> boxes = new List<Tuple<Box, int, int>>();

             // first add current segment's boxes which have 0 shift
             foreach (Box box in _CurrentSegment.GetBoxesSynchronized())
             {
            boxes.Add(Tuple.Create(box, 0, 0));
             }
             // now add other boxes and determine possible shift
             foreach (Segment neighbour in _CurrentSegmentNeighbours)
             {
            int shiftX = 0;
            if (_CurrentSegment.X - neighbour.X > WorldHelper.HalfSizeX)
            {
               shiftX = WorldHelper.SizeX;
            }
            else if (neighbour.X - _CurrentSegment.X > WorldHelper.HalfSizeX)
            {
               shiftX = -WorldHelper.SizeX;
            }

            int shiftZ = 0;
            if (_CurrentSegment.Z - neighbour.Z > WorldHelper.HalfSizeZ)
            {
               shiftZ = WorldHelper.SizeZ;
            }
            else if (neighbour.Z - _CurrentSegment.Z > WorldHelper.HalfSizeZ)
            {
               shiftZ = -WorldHelper.SizeZ;
            }

            foreach (Box box in neighbour.GetBoxesSynchronized())
            {
               boxes.Add(Tuple.Create(box, shiftX, shiftZ));
            }
             }

             if (eyeLocation.Y * eyeLocation.Y < BlockInteractionRange)
             {
            boxes.Add(Tuple.Create(Box.FloorBox, 0, 0));
             }

             int reverseShiftX = 0;
             int reverseShiftZ = 0;
             foreach (Tuple<Box, int, int> box in boxes)
             {
            Intersection intersection = box.Item1.GetIntersection(line, box.Item2, box.Item3);
            if (intersection.Distance < closest.Distance)
            {
               closest = intersection;
               reverseShiftX = -box.Item2;
               reverseShiftZ = -box.Item3;
            }
             }

             // check if there is a close intersection at all
             if (closest.IntersectionPoint == null || closest.Distance > BlockInteractionRange)
             {
            // not close enough or no point at all
            return false;
             }

             // adjust the reverse shift by accounting for reverse number truncating
             // when below 0
             if (closest.IntersectionPoint.X < 0 && closest.IntersectionPoint.X % 1 != 0)
             {
            reverseShiftX--;
             }
             if (closest.IntersectionPoint.Z < 0 && closest.IntersectionPoint.Z % 1 != 0)
             {
            reverseShiftZ--;
             }
             // calculate cube location without the shift
             x = Convert.ToInt32(Math.Truncate(closest.IntersectionPoint.X)) + reverseShiftX;
             y = Convert.ToInt32(Math.Truncate(closest.IntersectionPoint.Y));
             z = Convert.ToInt32(Math.Truncate(closest.IntersectionPoint.Z)) + reverseShiftZ;

             if (place)
             {
            // correct the location based on intersection side
            switch (closest.Side)
            {
               case Sides.FrontX:
                  x--;
                  break;
               case Sides.FrontY:
                  y--;
                  break;
               case Sides.FrontZ:
                  z--;
                  break;
            }
             }
             else
             {
            // correct the location based on intersection side
            switch (closest.Side)
            {
               case Sides.BackX:
                  x--;
                  break;
               case Sides.BackY:
                  y--;
                  break;
               case Sides.BackZ:
                  z--;
                  break;
            }
             }

             // check for floor/ceiling limits
             if (y < 0 || y > byte.MaxValue)
             {
            return false;
             }

             // adjust possible shift over the edge of the world after correction
             if (x < 0)
             {
            x += WorldHelper.SizeX;
             }
             else if (x >= WorldHelper.SizeX)
             {
            x -= WorldHelper.SizeX;
             }

             if (z < 0)
             {
            z += WorldHelper.SizeZ;
             }
             else if (z >= WorldHelper.SizeZ)
             {
            z -= WorldHelper.SizeZ;
             }

             // check if placing the block will clip into an entity
             if (place)
             {
            Box box = new Box(new Cube(x, y, z, 0), null);
            List<Entity> entities = WorldHelper.GetEntities(box.CenterPoint, BlockEntityCollisionSelectRange);

            bool collides = false;
            foreach (Entity entity in entities)
            {
               box.CheckSuffocation(entity.Location, ref entity._HalfSizeX, ref entity._HalfSizeY, ref collides);
               if (collides)
               {
                  // at least one entity collides with the newly placed box
                  return false;
               }
            }
             }

             // retrieve the destination segment and place or remove the block
             Segment destinationSegment = WorldHelper.GetSegment(x, y, z);
             version = destinationSegment.PlaceOrRemoveBlockAndUpdateVersion(place, x, y, z, GetSelectedMaterial());

             return true;
        }
Exemplo n.º 9
0
        private void CheckSegmentChanged()
        {
            int segmentX = Convert.ToInt32(Math.Truncate(Location.X));
             segmentX -= segmentX % 8;
             if (segmentX >= WorldHelper.SizeX)
             {
            segmentX -= WorldHelper.SizeX;
             }
             else if (segmentX < 0)
             {
            segmentX += WorldHelper.SizeX;
             }
             int segmentY = Convert.ToInt32(Math.Truncate(Location.Y));
             segmentY -= segmentY % 8;
             int segmentZ = Convert.ToInt32(Math.Truncate(Location.Z));
             segmentZ -= segmentZ % 8;
             if (segmentZ >= WorldHelper.SizeZ)
             {
            segmentZ -= WorldHelper.SizeZ;
             }
             else if (segmentZ < 0)
             {
            segmentZ += WorldHelper.SizeZ;
             }

             bool refreshNeighbours = false;
             // check if segment needs to be changed
             if (_CurrentSegment == null ||
             !(_CurrentSegment.X == segmentX &&
               _CurrentSegment.Y == segmentY &&
               _CurrentSegment.Z == segmentZ))
             {
            _CurrentSegment = WorldHelper.GetSegment(segmentX, segmentY, segmentZ);
            refreshNeighbours = true;
             }

             Point3D inBorderCheckPoint = new Point3D(Location.X - _CurrentSegment.X,
                                                  Location.Y - _CurrentSegment.Y,
                                                  Location.Z - _CurrentSegment.Z);
             bool xRefresh = (inBorderCheckPoint.X < 4 != _PreviousCheckPoint.X < 4);
             bool yRefresh = (inBorderCheckPoint.Y < 4 != _PreviousCheckPoint.Y < 4);
             bool zRefresh = (inBorderCheckPoint.Z < 4 != _PreviousCheckPoint.Z < 4);
             // check if neighbours are to be refreshed
             if (refreshNeighbours || xRefresh || yRefresh || zRefresh)
             {
            _CurrentSegmentNeighbours = WorldHelper.GetSegmentNeighboursForCollisions(_CurrentSegment, Location);
             }

             _PreviousCheckPoint = inBorderCheckPoint;

             // check if column area isn't changed
             int x = Convert.ToInt32(Math.Truncate(Location.X));
             x -= x % 64;
             int z = Convert.ToInt32(Math.Truncate(Location.Z));
             z -= z % 64;

             if (CurrentColumnX != x || CurrentColumnZ != z)
             {
            _CurrentColumnX = x;
            _CurrentColumnZ = z;

            if (OnColumnChanged != null)
            {
               OnColumnChanged(this, EventArgs.Empty);
            }
             }
        }
Exemplo n.º 10
0
        public void ProcessReceivedMessage(Connection connection, ref byte messageCode, ref byte[] data)
        {
            switch (messageCode)
             {
            case MessageCodes.Chat:
               string chatMessage = Encoding.ASCII.GetString(data, 1, data[0]);
               ChatMessage(connection, chatMessage);
               break;
            case MessageCodes.Disconnecting:
               DisconnectingNotification(connection);
               break;
            case MessageCodes.FileDataExchangeAdd:
               byte addExchangeType = 0;
               byte[] addHash = null;
               byte[] addFileData = null;
               FileDataExchangeUtils.ParseAddFileMessage(ref data, out addExchangeType, out addHash, out addFileData);

               AddFile(connection, addExchangeType, addHash, addFileData);
               break;
            case MessageCodes.FileDataExchangeRequest:
               byte requestExchangeType = 0;
               byte[] requestHash = null;
               FileDataExchangeUtils.ParseCheckFileExistRequest(ref data, out requestExchangeType, out requestHash);

               CheckFileExistRequest(connection, requestExchangeType, requestHash);
               break;
            case MessageCodes.FileDataExchangeResponse:
               byte responseExchangeType = 0;
               byte[] responseHash = null;
               bool responseExists = false;
               FileDataExchangeUtils.ParseCheckFileExistResponse(ref data, out responseExchangeType, out responseHash, out responseExists);

               CheckFileExistResponse(connection, responseExchangeType, responseHash, responseExists);
               break;
            case MessageCodes.FileDataRequest:
               byte fileExchangeType = 0;
               byte[] fileHash = null;

               FileDataExchangeUtils.ParseFileRequest(ref data, out fileExchangeType, out fileHash);

               RequestFile(connection, fileExchangeType, fileHash);
               break;
            case MessageCodes.GeneralNo:
               break;
            case MessageCodes.GeneralYes:
               break;
            case MessageCodes.Login:
               int offset = 0;

               int nameLength = data[offset];
               offset++;
               string name = Encoding.ASCII.GetString(data, offset, nameLength);
               offset += nameLength;

               int passwordLength = data[offset];
               offset++;
               string password = Encoding.ASCII.GetString(data, offset, passwordLength);
               offset += passwordLength;

               int versionLength = data[offset];
               offset++;
               string version = Encoding.ASCII.GetString(data, offset, versionLength);
               offset += versionLength;

               byte[] skinHash = new byte[16];
               for (int i = 0; i < 16; i++)
               {
                  skinHash[i] = data[offset + i];
               }

               LoginRequest(connection, name, password, version, skinHash);
               break;
            case MessageCodes.Moved:
               Point3D movedLocation = new Point3D();
               movedLocation.InitializeFromByteArray(ref data, 0);
               float rotationLeft = BitConverter.ToSingle(data, Point3D.SerializedSize);
               float rotationUp = BitConverter.ToSingle(data, Point3D.SerializedSize + 4);

               PlayerMovedNotification(connection, movedLocation, rotationLeft, rotationUp);
               break;
            case MessageCodes.Moving:
               break;
            //case MessageCodes.MultipartCompressed:
            //   connection.ProcessMultipartMessage(ref data);
            //   break;
            case MessageCodes.PlaceOrRemoveCube:
               bool place = (data[0] > 0);
               Point3D placeLocation = new Point3D();
               placeLocation.InitializeFromByteArray(ref data, 1);
               float placeRotationLeft = BitConverter.ToSingle(data, Point3D.SerializedSize + 1);
               float placeRotationUp = BitConverter.ToSingle(data, Point3D.SerializedSize + 5);
               ushort placeMaterialId = BitConverter.ToUInt16(data, Point3D.SerializedSize + 9);

               PlaceOrRemoveCubeNotification(connection, place, placeLocation, placeRotationLeft, placeRotationUp, placeMaterialId);
               break;
            case MessageCodes.Terrain:
               int terrainMessageId = BitConverter.ToInt32(data, 0);
               Point3D terrainLocation = new Point3D();
               terrainLocation.InitializeFromByteArray(ref data, 4);
               float terrainRotationLeft = BitConverter.ToSingle(data, Point3D.SerializedSize + 4);
               float terrainRotationUp = BitConverter.ToSingle(data, Point3D.SerializedSize + 8);

               TerrainDataRequest(connection, terrainMessageId, terrainLocation, terrainRotationLeft, terrainRotationUp);
               break;
             }
        }
Exemplo n.º 11
0
 /// <summary>
 /// Creates an intersection from given parameters.
 /// </summary>
 /// <param name="distance">Distance to intersection</param>
 /// <param name="intersectionPoint">Point of intersection</param>
 /// <param name="side">Side of intersection</param>
 public Intersection(float distance, Point3D intersectionPoint, int side)
 {
     Distance = distance;
      IntersectionPoint = intersectionPoint;
      Side = side;
 }
Exemplo n.º 12
0
        /// <summary>
        /// Gets whether a given point is inside a triangle
        /// </summary>
        /// <param name="p">Point</param>
        /// <param name="triangle">Triangle defined by 3 points</param>
        /// <returns>True if the point is inside given triangle</returns>
        public static bool IsPointInTriangle(Point3D p, Tuple<Point3D, Point3D, Point3D> triangle)
        {
            // taken from http://www.blackpawn.com/texts/pointinpoly/default.html

             // Compute vectors
             Point3D a = triangle.Item1;
             Point3D b = triangle.Item2;
             Point3D c = triangle.Item3;

             Point3D v0 = c - a;
             Point3D v1 = b - a;
             Point3D v2 = p - a;

             // Compute dot products
             float dot00 = v0.DotProduct(v0);
             float dot01 = v0.DotProduct(v1);
             float dot02 = v0.DotProduct(v2);
             float dot11 = v1.DotProduct(v1);
             float dot12 = v1.DotProduct(v2);

             // Compute barycentric coordinates
             double invDenom = 1F / (dot00 * dot11 - dot01 * dot01);
             double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
             double v = (dot00 * dot12 - dot01 * dot02) * invDenom;

             // Check if point is in triangle
             return (u >= 0) && (v >= 0) && (u + v <= 1);
        }
Exemplo n.º 13
0
 /// <summary>
 /// Gets a dot product from this and given vector.
 /// </summary>
 /// <param name="other">Other vector</param>
 /// <returns>Dot product</returns>
 public float DotProduct(Point3D other)
 {
     return X * other.X + Y * other.Y + Z * other.Z;
 }
Exemplo n.º 14
0
 /// <summary>
 /// Gets a cross product between two points.
 /// </summary>
 /// <param name="point1">Vector 1</param>
 /// <param name="point2">Vector 2</param>
 /// <returns>Cross product</returns>
 public static Point3D CrossProduct(Point3D point1, Point3D point2)
 {
     return new Point3D(point1.Y * point2.Z - point1.Z * point2.Y,
                     point1.Z * point2.X - point1.X * point2.Z,
                     point1.X * point2.Y - point1.Y * point2.X);
 }
Exemplo n.º 15
0
        /// <summary>
        /// Gets an angle between two vectors.
        /// </summary>
        /// <param name="origin">Origin</param>
        /// <param name="vector1">Vector 1</param>
        /// <param name="vector2">Vector 2</param>
        /// <returns>Angle between two vectors which is not divided by
        /// Math.PI</returns>
        public static double GetAngleRadians(Point3D origin, Point3D vector1, Point3D vector2)
        {
            // this is extremely unlikely to happen so lets just ignore this case
             //if ((vector1.X == 0.0f && vector1.Y == 0.0f && vector1.Z == 0.0f) ||
             //    (vector2.X == 0.0f && vector2.Y == 0.0f && vector2.Z == 0.0f))
             //{
             //   // unable to calculate so return -1
             //   return -1;
             //}

             Point3D a = (vector1 - origin);
             a.Normalize();
             Point3D b = (vector2 - origin);
             b.Normalize();

            #if DIAG
             _AngleCounter++;
            #endif

             return Math.Acos(a.X * b.X + a.Y * b.Y + a.Z * b.Z);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Creates a new point based on given point and coordinate shifts.
        /// </summary>
        /// <param name="point">Base point</param>
        /// <param name="shiftX">X coordinate shift</param>
        /// <param name="shiftY">Y coordinate shift</param>
        /// <param name="shiftZ">Z coordinate shift</param>
        public Point3D(Point3D point, float shiftX, float shiftY, float shiftZ)
            : this(point)
        {
            X += shiftX;
             Y += shiftY;
             Z += shiftZ;

            #if DIAG
             _CloneCounter++;
            #endif
        }
 public void PlayerMovedNotification(Connection connection, Point3D location, float rotationLeft, float rotationUp)
 {
     // empty
 }
Exemplo n.º 18
0
 /// <summary>
 /// Creates a vector using given points.
 /// </summary>
 /// <param name="point1">First point</param>
 /// <param name="point2">Second point</param>
 public Vector3D(Point3D point1, Point3D point2)
 {
     Point1 = point1;
      Point2 = point2;
 }
Exemplo n.º 19
0
        public void PlaceOrRemoveCubeNotification(Connection connection, bool place, Point3D location, float rotationLeft, float rotationUp, ushort materialId)
        {
            //Console.WriteLine("> PlaceOrRemoveCubeNotification");

             // adjust player's location and heading
             PlayerMovedNotification(connection, location, rotationLeft, rotationUp);

             // set material
             connection.Player.SelectedMaterial = materialId;

             int x = -1;
             int y = -1;
             int z = -1;
             uint version = 0;
             if (!connection.Player.PlaceOrRemoveBlock(place, out x, out y, out z, out version))
             {
            // ignore
            return;
             }

             // distribute info about changed terrain
             Segment segment = ServerWorldManager.Instance.GetSegmentBasedOnInsidePoint(x, y, z);
             foreach (Connection other in ServerManager.Instance.GetAuthenticatedPlayers())
             {
            if (ServerWorldManager.Instance.IsPlayersArea(other.Player, segment.Area.Key))
            {
               ServerManager.Instance.ServerToClientProvider.PlaceOrRemoveCubeNotification(other, place, segment, x, y, z, connection.Player.GetSelectedMaterial(), version);
            }
             }
        }
Exemplo n.º 20
0
        /// <summary>
        /// Gets the distance between this and given point.
        /// </summary>
        /// <param name="point2">Second point</param>
        /// <returns>Distance between this and given point</returns>
        public double GetDistance(Point3D point2)
        {
            #if DIAG
             _DistanceCounter++;
            #endif

             return Math.Sqrt(Square(X - point2.X) + Square(Y - point2.Y) + Square(Z - point2.Z));
        }
Exemplo n.º 21
0
        public void PlayerMovedNotification(Connection connection, Point3D location, float rotationLeft, float rotationUp)
        {
            //Console.WriteLine("> PlayerMovedNotification: Pos {0}, L {1:0.0}, U {2:0.0}", location, rotationLeft, rotationUp);

             connection.Player.SetLocation(location, rotationLeft, rotationUp, true, Environment.TickCount);

             foreach (Connection other in ServerManager.Instance.GetAuthenticatedPlayers(connection.Player.ID))
             {
            ServerManager.Instance.ServerToClientProvider.EntityMovedNotification(other, connection.Player.ID, location, rotationLeft, rotationUp, connection.Player.LastLocationUpdate);
             }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Gets the distance square between this and given point.
        /// </summary>
        /// <param name="other">Other point</param>
        /// <returns>Distance square between this and given point</returns>
        public float GetDistanceSquare(Point3D other)
        {
            #if DIAG
             _DistanceCounter++;
            #endif

             return Square(X - other.X) + Square(Y - other.Y) + Square(Z - other.Z);
        }
Exemplo n.º 23
0
        public void TerrainDataRequest(Connection connection, int terrainMessageId, Point3D location, float rotationLeft, float rotationUp)
        {
            Console.WriteLine("> TerrainDataRequest: {0}", terrainMessageId);

             PlayerMovedNotification(connection, location, rotationLeft, rotationUp);

             ServerWorldManager.Instance.LoadClientColumns(terrainMessageId, connection.Player);
        }
 public void PlaceOrRemoveCubeNotification(Connection connection, bool place, Point3D location, float rotationLeft, float rotationUp, ushort materialId)
 {
     ClientWorldManager.Instance.Player.PlaceOrRemoveBlock(place);
 }
Exemplo n.º 25
0
        /// <summary>
        /// Handles the entity movement in the world.
        /// </summary>
        /// <returns>True if moved</returns>
        public bool HandleMovement()
        {
            bool moved = false;

             if (!_CanMove)
             {
            return moved;
             }

             // calculate movement
             _CurrentTime = Environment.TickCount;
             if (MoveX != 0 || MoveY != 0 || MoveZ != 0)
             {
            moved = true;

            if (_CurrentSegment == null)
            {
               CheckSegmentChanged();
            }

            double distance = (_CurrentTime - _LastMoveTime) * Speed.EntityBaseSpeed;
            Point3D move = new Point3D(MoveX * distance, MoveY * distance, MoveZ * distance);
            move.Rotate(ref _RotationLeft, ref _ZeroUpDownRotation);
            Point3D original = new Point3D(Location);
            Location += move;

            // check collisions and adjust location if needed
            Vector3D moveVector = new Vector3D(original, Location);
            List<Box> boxesForCheck = new List<Box>(_CurrentSegment.GetBoxesSynchronized());
            foreach (Segment neighbour in _CurrentSegmentNeighbours)
            {
               if (neighbour != null)
               {
                  boxesForCheck.AddRange(neighbour.GetBoxesSynchronized());
               }
            }

            // floor/ceiling collisions
            _Falling = true;
            foreach (Box box in boxesForCheck)
            {
               Location.Y += box.CheckFloorCeilingCollisions(moveVector, ref _HalfSizeX,
                                                             ref _HalfSizeY, ref _Falling);
            }
            // world floor/ceiling check
            if (Location.Y - _HalfSizeY < 0.0f)
            {
               Location.Y = _HalfSizeY;
            }
            else if (Location.Y + _HalfSizeY > 255.0f)
            {
               Location.Y = 255.0f - _HalfSizeY;
            }

            // assemble collision walls
            List<CollisionWall> walls = new List<CollisionWall>(_CurrentSegment.GetCollisionWalls());
            foreach (Segment neighbour in _CurrentSegmentNeighbours)
            {
               if (neighbour != null)
               {
                  walls.AddRange(neighbour.GetCollisionWalls());
               }
            }
            // walls.RemoveAll(w => w.GetBoxCenterPointDistanceSquare(Location) > 4.0f);
            // check wall collisions
            float[] xData = new float[] { 512.0f, 0.0f };
            float[] zData = new float[] { 512.0f, 0.0f };
            foreach (CollisionWall wall in walls)
            {
               if (wall.Side == Sides.FrontX || wall.Side == Sides.BackX)
               {
                  wall.CheckWallCollisions(moveVector, ref _HalfSizeX, ref _HalfSizeY, ref xData);
               }
               if (wall.Side == Sides.FrontZ || wall.Side == Sides.BackZ)
               {
                  wall.CheckWallCollisions(moveVector, ref _HalfSizeX, ref _HalfSizeY, ref zData);
               }
            }
            // apply shift based on wall collisons
            Location.X += xData[1];
            Location.Z += zData[1];

            // check suffocation
            _Suffocating = false;
            foreach (Box box in boxesForCheck)
            {
               box.CheckSuffocation(Location, ref _HalfSizeX, ref _HalfSizeY,
                                    ref _Suffocating);
            }

            // check move over map edge
            if (Location.X < 0)
            {
               Location.X += WorldHelper.SizeX;
            }
            else if (Location.X >= WorldHelper.SizeX)
            {
               Location.X -= WorldHelper.SizeX;
            }

            if (Location.Z < 0)
            {
               Location.Z += WorldHelper.SizeZ;
            }
            else if (Location.Z >= WorldHelper.SizeZ)
            {
               Location.Z -= WorldHelper.SizeZ;
            }

            // check if segment changed
            CheckSegmentChanged();
             }

             // calculate new direction
             moved |= HandleRotation();

             // update last moved time
             _LastMoveTime = _CurrentTime;

             return moved;
        }
Exemplo n.º 26
0
 /// <summary>
 /// Rotates the point around given origin by given angles.
 /// </summary>
 /// <param name="origin">Origin point to rotate around</param>
 /// <param name="leftRightAngle">Left/right rotation angle</param>
 /// <param name="upDownAngle">Up/down rotation angle</param>
 public void Rotate(Point3D origin, float leftRightAngle, float upDownAngle)
 {
     Rotate(origin, ref leftRightAngle, ref upDownAngle);
 }
Exemplo n.º 27
0
        /// <summary>
        /// Set the entity location and direction.
        /// </summary>
        /// <param name="location">Current location</param>
        /// <param name="rotationLeft">Rotation left</param>
        /// <param name="rotationUp">Rotation up</param>
        /// <param name="handleMovement">Determines whether movement should be
        /// handled</param>
        /// <param name="movedTime">Moved time</param>
        public void SetLocation(Point3D location, float rotationLeft, float rotationUp, bool handleMovement, int movedTime)
        {
            if (movedTime < LastLocationUpdate)
             {
            return;
             }

             LastLocationUpdate = movedTime;
             Location = location;
             NewRotationLeft = rotationLeft;
             NewRotationUp = rotationUp;
             if (handleMovement)
             {
            CheckSegmentChanged();
            HandleMovement();
             }
             else
             {
            HandleRotation();
             }
        }
Exemplo n.º 28
0
        /// <summary>
        /// Rotates the point around given origin by given angles.
        /// </summary>
        /// <param name="origin">Origin point to rotate around</param>
        /// <param name="leftRightAngle">Left/right rotation angle</param>
        /// <param name="upDownAngle">Up/down rotation angle</param>
        public void Rotate(Point3D origin, ref float leftRightAngle,
                         ref float upDownAngle)
        {
            #if DIAG
             _RotationCounter++;
            #endif

             double x = (X -= origin.X);
             double y = (Y -= origin.Y);
             double z = (Z -= origin.Z);

             double upDownDegrees = upDownAngle * _Pi;
             double upDownCosDegrees = Math.Cos(upDownDegrees);
             double upDownSinDegrees = Math.Sin(upDownDegrees);

             double leftRightDegrees = leftRightAngle * _Pi;
             double leftRightCosDegrees = Math.Cos(leftRightDegrees);
             double leftRightSinDegrees = Math.Sin(leftRightDegrees);

             y = (Y * upDownCosDegrees) + (Z * upDownSinDegrees);
             z = (Y * -upDownSinDegrees) + (Z * upDownCosDegrees);
             x = (X * leftRightCosDegrees) + (z * leftRightSinDegrees);
             z = (X * -leftRightSinDegrees) + (z * leftRightCosDegrees);

             X = Convert.ToSingle(x) + origin.X;
             Y = Convert.ToSingle(y) + origin.Y;
             Z = Convert.ToSingle(z) + origin.Z;
        }
Exemplo n.º 29
0
        private void InitializeFromByteArray(ref byte[] data)
        {
            // initialize the base part
             Location = new Point3D();
             _EntityType = data[OffsetEntityType];
             _ID = BitConverter.ToUInt16(data, OffsetID);
             Location.InitializeFromByteArray(ref data, OffsetLocation);
             _RotationLeft = BitConverter.ToSingle(data, OffsetRotationLeft);
             _NewRotationLeft = _RotationLeft;
             _RotationUp = BitConverter.ToSingle(data, OffsetRotationUp);
             _NewRotationUp = _RotationUp;

             int x = Convert.ToInt32(Location.X);
             int z = Convert.ToInt32(Location.Z);
             _CurrentColumnX = x - x % 64;
             _CurrentColumnZ = z - z % 64;

             lock (_NextIdLock)
             {
            if (_NextId <= ID)
            {
               _NextIdLock = ID + 1;
            }
             }

             // initialize the deriving part
             InitializeFromByteArray(ref data, SerializedSize);
        }
Exemplo n.º 30
0
        public void GetRectangleIntersectionTest()
        {
            Point3D pl1 = new Point3D(-5, 0, -5);
             Point3D pl2 = new Point3D(5, 0, -5);
             Point3D pl3 = new Point3D(5, 0, 5);
             Point3D pl4 = new Point3D(-5, 0, 5);
             var pl = Tuple.Create(pl1, pl2, pl3, pl4);

             // one intersection at [-4; 0; 4]
             Point3D u1 = new Point3D(-4, 2, 4);
             Point3D u2 = new Point3D(-4, -2, 4);
             var u = new Vector3D(u1, u2);

             var result = Point3D.GetRectangleIntersection(pl, u);
             Assert.IsTrue(result.Item1 == 1);
             Assert.AreEqual<Point3D>(result.Item2, new Point3D(-4, 0, 4));

             // one intersection at [-4; 0; 4]
             u1 = new Point3D(-5, 2, 5);
             u2 = new Point3D(-3, -2, 3);
             u = new Vector3D(u1, u2);

             result = Point3D.GetRectangleIntersection(pl, u);
             Assert.IsTrue(result.Item1 == 1);
             Assert.AreEqual<Point3D>(result.Item2, new Point3D(-4, 0, 4));

             // one intersection at [0; 0; 0]
             u1 = new Point3D(0, 2, 0);
             u2 = new Point3D(0, -2, 0);
             u = new Vector3D(u1, u2);

             result = Point3D.GetRectangleIntersection(pl, u);
             Assert.IsTrue(result.Item1 == 1);
             Assert.AreEqual<Point3D>(result.Item2, new Point3D(0, 0, 0));

             // no intersection
             u1 = new Point3D(-4, -1, 4);
             u2 = new Point3D(-4, -2, 4);
             u = new Vector3D(u1, u2);

             result = Point3D.GetRectangleIntersection(pl, u);
             Assert.IsTrue(result.Item1 == 0);
             Assert.IsNull(result.Item2);

             // no intersection
             u1 = new Point3D(-5.5, 2, 5);
             u2 = new Point3D(-5, -2, 5);
             u = new Vector3D(u1, u2);

             result = Point3D.GetRectangleIntersection(pl, u);
             Assert.IsTrue(result.Item1 == 0);
             Assert.IsNull(result.Item2);

             // line is in the plane
             u1 = new Point3D(4, 0, 4);
             u2 = new Point3D(3, 0, 3);
             u = new Vector3D(u1, u2);

             result = Point3D.GetRectangleIntersection(pl, u);
             Assert.IsTrue(result.Item1 == 2);
             Assert.IsNull(result.Item2);
        }