/// <summary> /// if a new client has entered the world, /// notify them about surrounding physical objects /// this routine will send the client mobile's /// position as one of the 'nearby' mobiles. /// </summary> public void SendInitialWorldView(ClientConnection client) { client.Send(Weather); // TODO: Just subscribe them to the cubes instead? //foreach (EntityModel p in GetNearby(client.Avatar)) //client.Send(p); }
public void SendInitialWorldView(ClientConnection client) { // if a new client has entered the world, // notify them about surrounding physical objects // NB: this routine will send the client mobile's // position as one of the 'nearby' mobiles. // TODO: figure out how to make client.Avatar the right type var mob = (MobileAvatar)client.Avatar; client.Send(Weather); // TODO: zomg I don't know if this divtruncate is right int squareX = DivTruncate((int)(mob.Position.X - _lowX), Square.SquareSize); int squareZ = DivTruncate((int)(mob.Position.Z - _lowZ), Square.SquareSize); int i, j; var nearbyPhysicalObjects = new List<PhysicalObject>(); // TODO: use xorder, zorder to descide the resolution? for (i = -1; i <= 1; i++) { for (j = -1; j <= 1; j++) { // check that neighbor exists if (squareX + i < 0 || squareX + i >= _squaresInX || squareZ + j < 0 || squareZ + j >= _squaresInZ || _square[squareX + i, squareZ + j] == null) continue; // add all neighboring physical objects // to the clients world view // that are in scope /** TODO: * could only send based upon a radius, but this makes * relocations harder... maybe be better to just use squares // NB: using Manhattan distance not Cartesian float distx = Math.Abs(p.Position.X - mob.Position.X); float distz = Math.Abs(p.Position.Z - mob.Position.Z); if ( distx <= Constants.objectScopeRadius && distz <= Constants.objectScopeRadius ) */ nearbyPhysicalObjects.AddRange( _square[squareX + i, squareZ + j].PhysicalObjects); } } /* ToClient.AddPhysicalObjects message = new ToClient.AddPhysicalObjects( nearbyPhysicalObjects ); client.Send( message ); */ foreach (PhysicalObject p in nearbyPhysicalObjects) client.Send(ToClient.AddPhysicalObject.CreateMessage(p)); for (int k = 0; k < Constants.TerrainZoomOrder; k++) { int tbx = DivTruncate((int)mob.Position.X, Constants.TerrainPieceSize) - Constants.xRadius[k]; int tbz = DivTruncate((int)mob.Position.Z, Constants.TerrainPieceSize) - Constants.zRadius[k]; // Normalize to a 'grid' point tbx = DivTruncate(tbx, Constants.scale[k]) * Constants.scale[k]; tbz = DivTruncate(tbz, Constants.scale[k]) * Constants.scale[k]; for (i = 0; i <= Constants.xRadius[k] * 2; i += Constants.scale[k]) { for (j = 0; j <= Constants.zRadius[k] * 2; j += Constants.scale[k]) { int tx = tbx + i; int tz = tbz + j; int terrainX = tx - (int)_lowX / Constants.TerrainPieceSize; int terrainZ = tz - (int)_lowZ / Constants.TerrainPieceSize; if (terrainX >= 0 && terrainX < _squaresInX * Square.SquareSize / Constants.TerrainPieceSize && terrainZ >= 0 && terrainZ < _squaresInZ * Square.SquareSize / Constants.TerrainPieceSize) { Terrain t = _terrain[terrainX, terrainZ]; if (t != null) { if (// there is no higher zoom order k == (Constants.TerrainZoomOrder - 1) // this is not a higher order point || (tx % Constants.scale[k + 1]) != 0 || (tz % Constants.scale[k + 1]) != 0) client.Send(ToClient.AddPhysicalObject.CreateMessage(t)); } } } } } }
void ProcessMessage(ClientConnection client, Pong message) { client.Latency = (DateTime.Now - client.PingedAt).Milliseconds; World.Weather.Latency = client.Latency; client.Send(World.Weather); }