public void updateFlag(float x, float y, float z, int connid) { int rx = ((int)x) % blockSize; int ry = ((int)y) % blockSize; int rz = ((int)z); RegionBlock rb = getRegion(x, y); if (rb != null) { if (rb.removeFlag(rx, ry, rz + 1, connid)) { rb.deleteBlock(rx, ry, rz + 1); PlayerFlagMessage m = new PlayerFlagMessage(); m.removed = true; NetworkServer.SendToClient(connid, LevelMsgType.PlayerFlagRequest, m); refreshMesh(); } else { PlayerFlagMessage m = new PlayerFlagMessage(); m.removed = false; NetworkServer.SendToClient(connid, LevelMsgType.PlayerFlagRequest, m); } } refreshMesh(); }
/// Create a level block corresponding to the given region block and /// add this to the cache of blocks. Assumes that such a block does /// not already exist, or a duplicate will be created. public LocalLevelBlock addLevelBlock(RegionBlock rb, Vector3 position) { // Debug.Log ("New local block " + position); LocalLevelBlock llb = new LocalLevelBlock(); llb.region = rb; llb.gobject = UnityEngine.Object.Instantiate(localLevelElement, position, Quaternion.identity); levelStructure.Add(llb); return(llb); }
public void OnSelectionSet(RegionBlock selectedRegion) { Debug.WriteLine($"New selection: X={selectedRegion.X} Y={selectedRegion.Y} Width={selectedRegion.Width} Height={selectedRegion.Height}"); Debug.Assert(ActiveRecordingService == null); ActiveRecordingService = recordingServiceProvider.Create(selectedRegion, KnownFourCC.Codecs.MotionJpeg, 70); HideSelectionViewCommand.Execute(null); BeginRecord(); }
public RegionBlock End(Point endPoint) { int x = (int)Math.Min(startPoint.X, endPoint.X); int width = (int)Math.Abs(endPoint.X - startPoint.X); int y = (int)Math.Min(startPoint.Y, endPoint.Y); int height = (int)Math.Abs(endPoint.Y - startPoint.Y); var result = new RegionBlock(x, y, width, height); return(result); }
/// Return the record for the given regionBlock, null /// if it doesn't exist. public AccessedRegion findRegion(RegionBlock rb) { foreach (AccessedRegion ar in activeRegions) { if (ar.region == rb) { return(ar); } } return(null); }
private void OnMouseLeftUp(object sender, MouseButtonEventArgs e) { var view = sender as IShowMouseSelectionView; if (view == null) { return; } if (drawRectangle.IsStarted) { RegionBlock selectedArea = drawRectangle.End(e.GetPosition(null)); CleanUpSelectionDraw(); view.SelectionViewModel?.OnSelectionSet(selectedArea); } }
/// Update the geometry representation of the level. Used on the server /// for visualization. public void refreshMesh() { for (int i = 0; i < levelStructures.GetLength(0); i += 1) { for (int j = 0; j < levelStructures.GetLength(1); j += 1) { RegionBlock rb = getRegion(i * blockSize, j * blockSize); if (rb != null) { GameObject t = levelViewObjects[i, j]; MeshFilter tmf = t.GetComponent <MeshFilter>(); rb.convertToMesh(tmf.mesh); } } } }
/// Place a block at the given coordinates, relative to the entire level itself. public void setBlock(float x, float y, float z, int type, int connid) { int rx = ((int)x) % blockSize; int ry = ((int)y) % blockSize; int rz = ((int)z); RegionBlock rb = getRegion(x, y); if (rb != null && rb.getBlock(rx, ry, rz) <= 0 && type != 10) { rb.setBlock(rx, ry, rz, type, connid); } else if (rb != null && rb.getBlock(rx, ry, rz) <= 0 && type == 10) { rb.setBlock(rx, ry, rz, type, connid); } refreshMesh(); }
/// Construct a level using a texture as the source of data. public LevelStructure(Texture2D levelPattern, int mblockSize) { blockSize = mblockSize; int blocksx = (int)((float)(levelPattern.width + blockSize - 1) / blockSize); int blocksy = (int)((float)(levelPattern.height + blockSize - 1) / blockSize); levelStructures = new RegionBlock [blocksx, blocksy]; levelViewObjects = new GameObject [blocksx, blocksy]; for (int i = 0; i < blocksx; i += 1) { for (int j = 0; j < blocksy; j += 1) { levelStructures[i, j] = new RegionBlock(levelPattern, i * blockSize, j * blockSize, blockSize); levelViewObjects[i, j] = null; } } }
/// Update a change of resource in the level structure. public void updateResource(float x, float y, float z, int amount) { int rx = ((int)x) % blockSize; int ry = ((int)y) % blockSize; int rz = ((int)z); RegionBlock rb = getRegion(x, y); if (rb != null) { rb.updateBlockHealth(rx, ry, rz, amount); int blockHealth = rb.getBlockHealth(rx, ry, rz); //Debug.LogError ("Health of block: " + blockHealth.ToString ()); if (blockHealth < 1) { rb.deleteBlock(rx, ry, rz); refreshMesh(); } } refreshMesh(); }
/// Create an instance of the geometry representation of the level, which can /// then be updated using refreshMesh. public void convertToMesh(GameObject regionBlank, Transform transform) { for (int i = 0; i < levelStructures.GetLength(0); i += 1) { for (int j = 0; j < levelStructures.GetLength(1); j += 1) { RegionBlock rb = getRegion(i * blockSize, j * blockSize); if (rb != null) { Vector3 pos = new Vector3(i * 1.0f, j * 1.0f, 0.0f); GameObject t = (GameObject)UnityEngine.Object.Instantiate(regionBlank, pos, Quaternion.identity); t.transform.SetParent(transform, false); MeshFilter tmf = t.GetComponent <MeshFilter>(); rb.convertToMesh(tmf.mesh); levelViewObjects[i, j] = t; } } } }
/// Send an update to the player identified by the given connection ID. Work out /// which regions have changed, and communicate those details. void sendPlayerUpdate(int connectionId, Vector3 position, float visibleRadius) { ClientDetails cd = getPlayerDetails(connectionId); cd.position = position; cd.radius = visibleRadius; // Check that the list of accessed regions is still up to date. if (Vector3.Distance(cd.position, cd.lastUpdatePosition) > ClientDetails.updateDistance) { // Clear tags. foreach (AccessedRegion ar in cd.activeRegions) { ar.tagged = false; } // Make sure all regions in the radius are tracked and tagged. int blockr = (int)(cd.radius / blockSize); for (int offx = -blockr; offx <= blockr; offx++) { for (int offy = -blockr; offy <= blockr; offy++) { RegionBlock rb = levelStructure.getRegion(cd.position.x + offx * blockSize, cd.position.z + offy * blockSize); if (rb != null) { // Debug.Log ("Updating player at rb " + rb + " xx " + rb.blockCoordX + " - " + rb.blockCoordY); AccessedRegion ar = cd.findRegion(rb); if (ar == null) { ar = new AccessedRegion(); ar.region = rb; ar.timeLastUpdate = 0; // force update. cd.activeRegions.Add(ar); } ar.tagged = true; } } } // Remove any regions not tagged (no longer in radius) for (int i = cd.activeRegions.Count - 1; i >= 0; i--) { if (!cd.activeRegions[i].tagged) { cd.activeRegions.RemoveAt(i); } } // Mark the position of last region list update. cd.lastUpdatePosition = cd.position; } // Debug.Log ("Updating player at " + cd.activeRegions + " --- " + cd.activeRegions.Count); // Send updates for those regions on the list who have changed since the last update timestamp. foreach (AccessedRegion ar in cd.activeRegions) { if (ar.timeLastUpdate < ar.region.timeLastChanged) { // Debug.Log ("Updating player at " + ar.timeLastUpdate + " - " + ar.region.timeLastChanged); NetworkServer.SendToClient(connectionId, LevelMsgType.LevelResponse, ar.region); // update timestamp. ar.timeLastUpdate = Time.time; } } }
/// Handle incoming updates from the server. void ServerCommandHandler(NetworkMessage netMsg) { switch (netMsg.msgType) { case LevelMsgType.LevelResponse: // Received an updated region block from the server. Update // the cache, and ensure that the local visual representation // is consistent. { RegionBlock rb = netMsg.ReadMessage <RegionBlock>(); // Debug.Log ("Server Got message: " + rb.blockSize); MeshFilter mf = GetComponent <MeshFilter>(); rb.convertToMesh(mf.mesh); Vector2 rbpos = rb.getPosition(); Vector3 llbpos = new Vector3(rbpos.x, WorldManager.minLevelHeight, rbpos.y); LocalLevelBlock llb = findLevelBlock(llbpos); if (llb == null) { llb = addLevelBlock(rb, llbpos); // llb should now be valid. llb.region.placeBlocks(llb.gobject.transform); } else { // if version is newer than the one we already have, then update it. if (rb.timeLastChanged > llb.region.timeLastChanged) { llb.region = rb; // Debug.Log ("Got update ..................................>"); llb.region.placeBlocks(llb.gobject.transform); } } flushRegions(); } break; case LevelMsgType.PlayerList: /// Message containing list of active players. { } break; case LevelMsgType.EmoteSingleSender: /// Handle incoming emotes from server { SendEmoteMessageAndClientID m = netMsg.ReadMessage <SendEmoteMessageAndClientID> (); displayEmote(m.emoteType, m.netId); Debug.Log("Incoming emote to client from server from network id: " + m.netId); } break; case LevelMsgType.PlayerFlagRequest: { PlayerFlagMessage m = netMsg.ReadMessage <PlayerFlagMessage> (); if (m.removed == false) { //Do UI message to player here informing them of failure to remove flag. } if (m.removed == true) { PlayerMove player = ClientScene.localPlayers[0].gameObject.GetComponent <PlayerMove>(); player.playerFlagPlaced = false; } } break; default: { Debug.Log("Unexpected message type in LocalWorld"); } break; } }