private PlayerState NextStateServer(PlayerState state, PlayerAction action) { bool matrixChangeDetected; PlayerState nextState = NextState(state, action, out matrixChangeDetected); if (!matrixChangeDetected) { return(nextState); } //todo: subscribe to current matrix rotations on spawn var newMatrix = MatrixManager.Get(nextState.MatrixId); Logger.Log($"Matrix will change to {newMatrix}", Category.Movement); if (newMatrix.MatrixMove) { //Subbing to new matrix rotations newMatrix.MatrixMove.OnRotate.AddListener(OnRotation); // Logger.Log( $"Registered rotation listener to {newMatrix.MatrixMove}" ); } //Unsubbing from old matrix rotations MatrixMove oldMatrixMove = MatrixManager.Get(matrix).MatrixMove; if (oldMatrixMove) { // Logger.Log( $"Unregistered rotation listener from {oldMatrixMove}" ); oldMatrixMove.OnRotate.RemoveListener(OnRotation); } return(nextState); }
private void SyncMatrix() { if (registerTile && !serverState.IsUninitialized) { registerTile.ParentNetId = MatrixManager.Get(serverState.MatrixId).NetId; } }
private void SyncMatrix() { if (registerTile) { registerTile.ParentNetId = MatrixManager.Get(serverState.MatrixId).NetId; } }
private void StartNormalOperation() { EntryList.AddItems(MapIconType.Ship, GetObjectsOf <MatrixMove>( mm => mm != MatrixMove && //ignore current ship (mm.HasWorkingThrusters || mm.gameObject.name.Equals("Escape Pod")) //until pod gets engines )); try { EntryList.AddItems(MapIconType.Asteroids, GetObjectsOf <Asteroid>()); var stationBounds = MatrixManager.Get(0).MetaTileMap.GetBounds(); int stationRadius = (int)Mathf.Abs(stationBounds.center.x - stationBounds.xMin); EntryList.AddStaticItem(MapIconType.Station, stationBounds.center, stationRadius); EntryList.AddItems(MapIconType.Waypoint, new List <GameObject>(new[] { Waypoint })); RescanElements(); StartRefresh(); } catch (NullReferenceException exception) { Logger.LogError("Caught NRE in GUI_ShuttleControl.StartNormalOperation: " + exception.Message, Category.Shuttles); } }
IEnumerator WaitForMatrixManager() { while (!MatrixManager.IsInitialized) { yield return(WaitFor.EndOfFrame); } yield return(WaitFor.EndOfFrame); if (CustomNetworkManager.IsServer) { InitServerState(); MatrixMoveEvents.OnStartMovementServer.AddListener(() => { if (floatingSyncHandle == null) { this.StartCoroutine(FloatingAwarenessSync(), ref floatingSyncHandle); } }); MatrixMoveEvents.OnStopMovementServer.AddListener(() => this.TryStopCoroutine(ref floatingSyncHandle)); NotifyPlayers(); } else { SyncPivot(pivot, pivot); SyncInitialPosition(initialPosition, initialPosition); MatrixMoveNewPlayer.Send(networkedMatrix.MatrixSync.netId); clientStarted = true; var child = transform.GetChild(0); matrixInfo = MatrixManager.Get(child.gameObject); } }
public void OnSpawnServer(SpawnInfo info) { ShuttleMatrixMove = GetComponentInParent <MatrixMove>(); if (ShuttleMatrixMove == null) { ShuttleMatrixMove = MatrixManager.Get(registerTile.Matrix).MatrixMove; if (ShuttleMatrixMove == null) { Logger.Log($"{this} is not on a movable matrix, so won't function.", Category.Shuttles); hasNetworkTab.enabled = false; return; } else { Logger.Log($"No MatrixMove reference set to {this}, found {ShuttleMatrixMove} automatically", Category.Shuttles); } } if (ShuttleMatrixMove.IsNotPilotable) { hasNetworkTab.enabled = false; } else { hasNetworkTab.enabled = true; } }
private IEnumerator InitMatrixMove() { ShuttleMatrixMove = GetComponentInParent <MatrixMove>(); if (ShuttleMatrixMove == null) { while (!registerTile.Matrix) { yield return(WaitFor.EndOfFrame); } ShuttleMatrixMove = MatrixManager.Get(registerTile.Matrix).MatrixMove; } if (ShuttleMatrixMove == null) { Logger.Log($"{this} is not on a movable matrix, so won't function.", Category.Matrix); hasNetworkTab.enabled = false; } else { Logger.Log($"No MatrixMove reference set to {this}, found {ShuttleMatrixMove} automatically", Category.Matrix); } if (ShuttleMatrixMove != null) { hasNetworkTab.enabled = true; } }
private void Start() { //Not doing this for clients if (IsServer) { EntryList.Origin = MatrixMove; //Init listeners MatrixMove.OnStart.AddListener(() => this["StartButton"].SetValue = "1"); MatrixMove.OnStop.AddListener(() => { this["StartButton"].SetValue = "0"; HideWaypoint(); }); if (!Waypoint) { Waypoint = new GameObject($"{MatrixMove.gameObject.name}Waypoint"); } HideWaypoint(false); // EntryList.AddItems( MapIconType.Airlock, GetObjectsOf<AirLockAnimator>( null, "AirLock" ) ); EntryList.AddItems(MapIconType.Ship, GetObjectsOf(new HashSet <MatrixMove>(new[] { MatrixMove }))); var stationBounds = MatrixManager.Get(0).MetaTileMap.GetBounds(); int stationRadius = (int)Mathf.Abs(stationBounds.center.x - stationBounds.xMin); EntryList.AddStaticItem(MapIconType.Station, stationBounds.center, stationRadius); EntryList.AddItems(MapIconType.Waypoint, new List <GameObject>(new[] { Waypoint })); RescanElements(); StartRefresh(); } }
private void Expose(Vector3Int hotspotPosition, Vector3Int atLocalPosition) { var isSideExposure = hotspotPosition != atLocalPosition; //calculate world position var hotspotWorldPosition = MatrixManager.LocalToWorldInt(hotspotPosition, MatrixManager.Get(matrix)); var atWorldPosition = MatrixManager.LocalToWorldInt(atLocalPosition, MatrixManager.Get(matrix)); var exposure = FireExposure.FromMetaDataNode(hotspots[hotspotPosition], hotspotWorldPosition.To2Int(), atLocalPosition.To2Int(), atWorldPosition.To2Int()); if (isSideExposure) { //side exposure logic //already exposed by a different hotspot if (hotspots.ContainsKey(atLocalPosition)) { return; } var metadata = metaDataLayer.Get(atLocalPosition); if (!metadata.IsOccupied) { //atmos can pass here, so no need to check side exposure (nothing to brush up against) return; } //only expose to atmos impassable objects, since those are the things the flames would //actually brush up against var regTiles = matrix.Get <RegisterTile>(atLocalPosition, true); foreach (var regTile in regTiles) { if (!regTile.IsAtmosPassable(exposure.HotspotLocalPosition.To3Int(), true)) { var exposable = regTile.GetComponent <IFireExposable>(); exposable.OnExposed(exposure); } } //expose the tiles there foreach (var tilemapDamage in tilemapDamages) { tilemapDamage.OnExposed(exposure); } } else { //direct exposure logic var fireExposables = matrix.Get <IFireExposable>(atLocalPosition, true); foreach (var exposable in fireExposables) { exposable.OnExposed(exposure); } //expose the tiles foreach (var tilemapDamage in tilemapDamages) { tilemapDamage.OnExposed(exposure); } } }
/// <summary> /// Target the specified gameobject /// </summary> /// <param name="target"></param> /// <returns></returns> public static ActionTarget Object(RegisterTile target) { if (target == null) { return(null); } return(new ActionTarget(false, target, target.LocalPosition, MatrixManager.Get(target.Matrix.Id))); }
public Vector3Int GetNextPosition(Vector3Int currentPosition, PlayerAction action, bool isReplay, Matrix curMatrix = null) { if (!curMatrix) { curMatrix = matrix; } Vector3Int direction = GetDirection(action, MatrixManager.Get(curMatrix), isReplay); return(currentPosition + direction); }
private void InitServerState() { if (flyingDirection == Vector2.zero) { Logger.LogWarning($"{gameObject.name} move direction unclear", Category.Matrix); serverState.Direction = Orientation.Up; } else { serverState.Direction = Orientation.From(Vector2Int.RoundToInt(flyingDirection)); } Vector3Int initialPositionInt = Vector3Int.RoundToInt(new Vector3(transform.position.x, transform.position.y, 0)); initialPosition = initialPositionInt; InitialPos = initialPosition.RoundToInt(); //initialOrientation = Orientation.From( serverState.Direction ); serverState.initialOrientation = serverState.Direction; var child = transform.GetChild(0); MatrixInfo = MatrixManager.Get(child.gameObject); var childPosition = Vector3Int.CeilToInt(new Vector3(child.transform.position.x, child.transform.position.y, 0)); pivot = initialPosition - childPosition; Pivot = pivot.RoundToInt(); Logger.LogTraceFormat("{0}: pivot={1} initialPos={2}, initialOrientation={3}", Category.Matrix, gameObject.name, pivot, initialPositionInt, serverState.initialOrientation); serverState.Speed = 1f; serverState.Position = initialPosition; serverState.orientation = serverState.initialOrientation; serverTargetState = serverState; clientState = serverState; clientTargetState = serverState; if (SensorPositions == null) { CollisionSensor[] sensors = GetComponentsInChildren <CollisionSensor>(); if (sensors.Length == 0) { SensorPositions = new Vector3Int[0]; return; } SensorPositions = sensors.Select(sensor => Vector3Int.RoundToInt(sensor.transform.localPosition)).ToArray(); Logger.Log($"Initialized sensors at {string.Join(",", SensorPositions)}," + $" direction is {State.Direction}", Category.Matrix); } }
/// Clientside lerping (transform to clientState position) private void Lerp() { Vector3 targetPos = MatrixManager.WorldToLocal(clientState.WorldPosition, MatrixManager.Get(matrix)); //Set position immediately if not moving if (clientState.Speed.Equals(0)) { transform.localPosition = targetPos; return; } transform.localPosition = Vector3.MoveTowards(transform.localPosition, targetPos, clientState.Speed * Time.deltaTime); }
private void SetupNeighbors(MetaDataNode node) { // Vector3Int[] neighbors = MetaUtils.GetNeighbors(node.Position); Vector3 nodeWorldPosition = MatrixManager.LocalToWorldInt(node.Position, MatrixManager.Get(matrix.Id)); foreach (Vector3Int dir in MetaUtils.Directions) { Vector3Int neighbor = dir + node.Position; if (metaTileMap.IsSpaceAt(neighbor)) { if (node.IsRoom) { externalNodes.Add(node); } Vector3 neighborWorldPosition = MatrixManager.LocalToWorldInt(neighbor, MatrixManager.Get(matrix.Id)); if (!MatrixManager.IsSpaceAt(neighborWorldPosition.RoundToInt())) { MatrixInfo matrixInfo = MatrixManager.AtPoint(neighborWorldPosition.RoundToInt()); if (matrixInfo.MetaTileMap != metaTileMap) { Vector3Int neighborlocalPosition = MatrixManager.WorldToLocalInt(neighborWorldPosition, matrixInfo); Vector3Int nodeLocalPosition = MatrixManager.WorldToLocalInt(nodeWorldPosition, matrixInfo); if (matrixInfo.MetaTileMap.IsAtmosPassableAt(nodeLocalPosition, neighborlocalPosition)) { node.AddNeighbor(matrixInfo.MetaDataLayer.Get(neighborlocalPosition)); } continue; } } } if (metaTileMap.IsAtmosPassableAt(node.Position, neighbor)) { MetaDataNode neighborNode = metaDataLayer.Get(neighbor); if (metaTileMap.IsSpaceAt(neighbor)) { neighborNode.Type = NodeType.Space; } node.AddNeighbor(neighborNode); } } }
public Vector3Int GetNextPosition(Vector3Int currentPosition, PlayerAction action, bool isReplay, Matrix curMatrix = null) { if (!curMatrix) { curMatrix = matrix; } Vector3Int direction = GetDirection(action, MatrixManager.Get(curMatrix)); Vector3Int adjustedDirection = AdjustDirection(currentPosition, direction, isReplay, curMatrix); if (adjustedDirection == Vector3.zero) { Interact(currentPosition, direction); } return(currentPosition + adjustedDirection); }
private void StartNormalOperation() { // EntryList.AddItems( MapIconType.Airlock, GetObjectsOf<AirLockAnimator>( null, "AirLock" ) ); EntryList.AddItems(MapIconType.Ship, GetObjectsOf(new HashSet <MatrixMove>(new[] { MatrixMove }))); var stationBounds = MatrixManager.Get(0).MetaTileMap.GetBounds(); int stationRadius = (int)Mathf.Abs(stationBounds.center.x - stationBounds.xMin); EntryList.AddStaticItem(MapIconType.Station, stationBounds.center, stationRadius); EntryList.AddItems(MapIconType.Waypoint, new List <GameObject>(new[] { Waypoint })); RescanElements(); StartRefresh(); }
private static void Incinerate() { if (CustomNetworkManager.Instance._isServer) { var playerScript = PlayerManager.LocalPlayerScript; var matrix = MatrixManager.Get(playerScript.registerTile.Matrix); foreach (var worldPos in playerScript.WorldPos.BoundsAround().allPositionsWithin) { var localPos = MatrixManager.WorldToLocalInt(worldPos, matrix); var gasMix = matrix.MetaDataLayer.Get(localPos).GasMix; gasMix.AddGas(Gas.Plasma, 100); gasMix.AddGas(Gas.Oxygen, 100); matrix.ReactionManager.ExposeHotspot(localPos); } } }
public bool CanPass(Vector3Int localPos, Vector3Int direction, Matrix currentMatrix) { MatrixInfo matrixInfo = MatrixManager.Get(currentMatrix); if (matrixInfo.MatrixMove) { //Converting local direction to world direction direction = Vector3Int.RoundToInt(matrixInfo.MatrixMove.ClientState.Orientation.Euler * direction); } Vector3Int position = MatrixManager.LocalToWorldInt(localPos, MatrixManager.Get(currentMatrix)); if (!MatrixManager.IsPassableAt(position, position + direction)) { return(false); } return(true); }
/// Clientside lerping (transform to clientState position) private void Lerp() { Vector3 targetPos = MatrixManager.WorldToLocal(clientState.WorldPosition, MatrixManager.Get(matrix)); //Set position immediately if not moving if (clientState.Speed.Equals(0)) { transform.localPosition = targetPos; onClientTileReached.Invoke(Vector3Int.RoundToInt(clientState.WorldPosition)); return; } transform.localPosition = Vector3.MoveTowards(transform.localPosition, targetPos, clientState.Speed * Time.deltaTime * transform.localPosition.SpeedTo(targetPos)); if (transform.localPosition == targetPos) { onClientTileReached.Invoke(Vector3Int.RoundToInt(clientState.WorldPosition)); } }
private void StartNormalOperation() { EntryList.AddItems(MapIconType.Ship, GetObjectsOf <MatrixMove>( mm => mm != MatrixMove && //ignore current ship (mm.HasWorkingThrusters || mm.gameObject.name.Equals("Escape Pod")) //until pod gets engines )); EntryList.AddItems(MapIconType.Asteroids, GetObjectsOf <Asteroid>()); var stationBounds = MatrixManager.Get(0).MetaTileMap.GetBounds(); int stationRadius = (int)Mathf.Abs(stationBounds.center.x - stationBounds.xMin); EntryList.AddStaticItem(MapIconType.Station, stationBounds.center, stationRadius); EntryList.AddItems(MapIconType.Waypoint, new List <GameObject>(new[] { Waypoint })); RescanElements(); StartRefresh(); }
/// Clientside lerping (transform to clientState position) private void Lerp() { var worldPos = predictedState.WorldPosition; Vector2 targetPos = MatrixManager.WorldToLocal(worldPos, MatrixManager.Get(matrix)); //Set position immediately if not moving if (predictedState.Speed.Equals(0)) { transform.localPosition = targetPos; OnClientTileReached().Invoke(worldPos.RoundToInt()); return; } transform.localPosition = Vector3.MoveTowards(transform.localPosition, targetPos, predictedState.Speed * Time.deltaTime * transform.localPosition.SpeedTo(targetPos)); if ((Vector2)transform.localPosition == targetPos) { OnClientTileReached().Invoke(predictedState.WorldPosition.RoundToInt()); } }
/// Serverside lerping private void ServerLerp() { Vector3 targetPos = MatrixManager.WorldToLocal(serverState.WorldPosition, MatrixManager.Get(matrix)); //Set position immediately if not moving if (serverState.Speed.Equals(0)) { serverLerpState = serverState; onTileReached.Invoke(Vector3Int.RoundToInt(serverState.WorldPosition)); return; } serverLerpState.Position = Vector3.MoveTowards(serverLerpState.Position, targetPos, serverState.Speed * Time.deltaTime * serverLerpState.Position.SpeedTo(targetPos)); if (serverLerpState.Position == targetPos) { onTileReached.Invoke(Vector3Int.RoundToInt(serverState.WorldPosition)); } }
private void InitServerState() { if (IsHiddenOnInit) { return; } //If object is supposed to be hidden, keep it that way // var worldPos = serverState.WorldPosition;// serverState.Speed = 0; serverState.Rotation = transform.rotation.eulerAngles.z; serverState.SpinFactor = 0; registerTile = GetComponent <RegisterTile>(); //Matrix id init if (registerTile && registerTile.Matrix) { //pre-placed serverState.MatrixId = MatrixManager.Get(matrix).Id; serverState.Position = Vector3Int.RoundToInt(new Vector3(transform.localPosition.x, transform.localPosition.y, 0)); } else { //runtime-placed bool initError = !MatrixManager.Instance || !registerTile; if (initError) { serverState.MatrixId = 0; Logger.LogWarning($"{gameObject.name}: unable to detect MatrixId!", Category.Transform); } else { serverState.MatrixId = MatrixManager.AtPoint(Vector3Int.RoundToInt(transform.position)).Id; } serverState.WorldPosition = Vector3Int.RoundToInt((Vector2)transform.position); } serverLerpState = serverState; }
private IEnumerator InitMatrixMove() { ShuttleMatrixMove = GetComponentInParent <MatrixMove>(); if (ShuttleMatrixMove == null) { while (!registerTile.Matrix) { yield return(WaitFor.EndOfFrame); } ShuttleMatrixMove = MatrixManager.Get(registerTile.Matrix).MatrixMove; } if (ShuttleMatrixMove == null) { Logger.LogError($"{this} has no reference to MatrixMove, current matrix doesn't seem to have it either", Category.Matrix); } else { Logger.Log($"No MatrixMove reference set to {this}, found {ShuttleMatrixMove} automatically", Category.Matrix); } }
private void Lerp() { if (!ClientPositionReady) { //PlayerLerp var worldPos = predictedState.WorldPosition; Vector3 targetPos = MatrixManager.WorldToLocal(worldPos, MatrixManager.Get(Matrix)); if (playerState.NoLerp || Vector3.Distance(transform.localPosition, targetPos) > 30) { transform.localPosition = targetPos; } else { transform.localPosition = Vector3.MoveTowards(transform.localPosition, targetPos, playerMove.speed * Time.deltaTime * transform.localPosition.SpeedTo(targetPos)); } if (ClientPositionReady) { OnClientTileReached().Invoke(Vector3Int.RoundToInt(worldPos)); } } }
private void SetupNeighbors(MetaDataNode node) { Vector3 nodeWorldPosition = MatrixManager.LocalToWorldInt(node.Position, MatrixManager.Get(matrix.Id)); // Look in every direction for neighboring tiles. foreach (Vector3Int dir in MetaUtils.Directions) { Vector3Int neighbor = dir + node.Position; if (metaTileMap.IsSpaceAt(neighbor, true)) { // // if current node is a room, but the neighboring is a space tile, this node needs to be checked regularly for changes by other matrices // if (node.IsRoom && !externalNodes.ContainsKey(node) && metaTileMap.IsSpaceAt(node.Position, true) == false) // { // externalNodes[node] = node; // } // If the node is not space, check other matrices if it has a tile next to this node. if (!node.IsSpace) { Vector3 neighborWorldPosition = MatrixManager.LocalToWorldInt(neighbor, MatrixManager.Get(matrix.Id)); // if matrixManager says, it's not space at the neighboring position, there must be a matrix with a non-space tile if (!MatrixManager.IsSpaceAt(neighborWorldPosition.RoundToInt(), true)) { MatrixInfo matrixInfo = MatrixManager.AtPoint(neighborWorldPosition.RoundToInt(), true); // ignore tilemap of current node if (matrixInfo.MetaTileMap != metaTileMap) { // Check if atmos can pass to the neighboring position Vector3Int neighborlocalPosition = MatrixManager.WorldToLocalInt(neighborWorldPosition, matrixInfo); Vector3Int nodeLocalPosition = MatrixManager.WorldToLocalInt(nodeWorldPosition, matrixInfo); if (matrixInfo.MetaTileMap.IsAtmosPassableAt(nodeLocalPosition, neighborlocalPosition, true)) { // add node of other matrix to the neighbors of the current node node.AddNeighbor(matrixInfo.MetaDataLayer.Get(neighborlocalPosition), dir); } // skip other checks for neighboring tile on local tilemap, to prevent the space tile to be added as a neighbor continue; } } } } // If neighboring tile on local tilemap is atmos passable, add it as a neighbor if (metaTileMap.IsAtmosPassableAt(node.Position, neighbor, true)) { MetaDataNode neighborNode = metaDataLayer.Get(neighbor); if (metaTileMap.IsSpaceAt(neighbor, true)) { neighborNode.Type = NodeType.Space; } node.AddNeighbor(neighborNode, dir); } } }
private void CreateRoom(Vector3Int origin) { var roomPositions = new HashSet <Vector3Int>(); var freePositions = new UniqueQueue <Vector3Int>(); freePositions.Enqueue(origin); var isSpace = false; // breadth-first search of the connected tiles that are not occupied while (!freePositions.IsEmpty) { if (freePositions.TryDequeue(out Vector3Int position)) { roomPositions.Add(position); Vector3Int[] neighbors = MetaUtils.GetNeighbors(position, null); for (var i = 0; i < neighbors.Length; i++) { Vector3Int neighbor = neighbors[i]; if (metaTileMap.IsSpaceAt(neighbor, true)) { Vector3Int worldPosition = MatrixManager.LocalToWorldInt(neighbor, MatrixManager.Get(matrix.Id)); // If matrix manager says, the neighboring positions is space, the whole room is connected to space. // Otherwise there is another matrix, blocking off the connection to space. if (MatrixManager.IsSpaceAt(worldPosition, true)) { isSpace = true; } } else if (metaTileMap.IsAtmosPassableAt(position, neighbor, true)) { // if neighbor position is not yet a room in the meta data layer and not in the room positions list, // add it to the positions that need be checked if (!roomPositions.Contains(neighbor) && !metaDataLayer.IsRoomAt(neighbor)) { freePositions.Enqueue(neighbor); } } } } } AssignType(roomPositions, isSpace ? NodeType.Space : NodeType.Room); SetupNeighbors(roomPositions); }
private void SetupNeighbors(MetaDataNode node) { // Look in every direction for neighboring tiles. foreach (Vector3Int dir in MetaUtils.Directions) { Vector3Int neighbor = dir + node.Position; if (metaTileMap.IsSpaceAt(neighbor, true)) { // if current node is a room, but the neighboring is a space tile, this node needs to be checked regularly for changes by other matrices if (node.IsRoom && !externalNodes.ContainsKey(node) && metaTileMap.IsSpaceAt(node.Position, true) == false) { externalNodes[node] = node; } // If the node is not space, check other matrices if it has a tile next to this node. if (!node.IsSpace) { Vector3 neighborWorldPosition = MatrixManager.LocalToWorldInt(neighbor, MatrixManager.Get(matrix.Id)); // if matrixManager says, it's not space at the neighboring position, there must be a matrix with a non-space tile if (!MatrixManager.IsSpaceAt(neighborWorldPosition.RoundToInt(), true, matrix.MatrixInfo)) { MatrixInfo matrixInfo = MatrixManager.AtPoint(neighborWorldPosition.RoundToInt(), true); // ignore tilemap of current node if (matrixInfo != null && matrixInfo.MetaTileMap != metaTileMap) { // Check if atmos can pass to the neighboring position Vector3Int neighborlocalPosition = MatrixManager.WorldToLocalInt(neighborWorldPosition, matrixInfo); var OppositeNode = matrixInfo.MetaDataLayer.Get(neighborlocalPosition); // add node of other matrix to the neighbors of the current node node.AddNeighbor(OppositeNode, dir); if (dir == Vector3Int.up) { OppositeNode.AddNeighbor(node, Vector3Int.down); } else if (dir == Vector3Int.down) { OppositeNode.AddNeighbor(node, Vector3Int.up); } else if (dir == Vector3Int.right) { OppositeNode.AddNeighbor(node, Vector3Int.left); } else if (dir == Vector3Int.left) { OppositeNode.AddNeighbor(node, Vector3Int.right); } // if current node is a room, but the neighboring is a space tile, this node needs to be checked regularly for changes by other matrices if (OppositeNode.IsRoom && !OppositeNode.MetaDataSystem.externalNodes.ContainsKey(node) && OppositeNode.MetaDataSystem.metaTileMap.IsSpaceAt(OppositeNode.Position, true) == false) { OppositeNode.MetaDataSystem.externalNodes[OppositeNode] = OppositeNode; } // skip other checks for neighboring tile on local tilemap, to prevent the space tile to be added as a neighbor continue; } } } } MetaDataNode neighborNode = metaDataLayer.Get(neighbor); if (metaTileMap.IsSpaceAt(neighbor, true)) { neighborNode.Type = NodeType.Space; } if (neighborNode.Type == NodeType.Space) { neighborNode.ThermalConductivity = 0.4f; neighborNode.HeatCapacity = 700000f; } else if (neighborNode.Type == NodeType.Room) { neighborNode.ThermalConductivity = 0.04f; neighborNode.HeatCapacity = 10000f; } node.AddNeighbor(neighborNode, dir); } }
private void Expose(Vector3Int hotspotPosition, Vector3Int atLocalPosition) { Profiler.BeginSample("ExposureInit"); var isSideExposure = hotspotPosition != atLocalPosition; //calculate world position var hotspotWorldPosition = MatrixManager.LocalToWorldInt(hotspotPosition, MatrixManager.Get(matrix)); var atWorldPosition = MatrixManager.LocalToWorldInt(atLocalPosition, MatrixManager.Get(matrix)); if (!hotspots.ContainsKey(hotspotPosition)) { Logger.LogError("Hotspot position key was not found in the hotspots dictionary", Category.Atmos); return; } //update fire exposure, reusing it to avoid creating GC. applyExposure.Update(isSideExposure, hotspots[hotspotPosition], hotspotWorldPosition, atLocalPosition, atWorldPosition); Profiler.EndSample(); if (isSideExposure) { Profiler.BeginSample("SideExposure"); //side exposure logic //already exposed by a different hotspot if (hotspots.ContainsKey(atLocalPosition)) { Profiler.EndSample(); return; } var metadata = metaDataLayer.Get(atLocalPosition); if (!metadata.IsOccupied) { //atmos can pass here, so no need to check side exposure (nothing to brush up against) Profiler.EndSample(); return; } //only expose to atmos impassable objects, since those are the things the flames would //actually brush up against matrix.ForEachRegisterTileSafe(applyExposure, atLocalPosition, true); //expose the tiles there foreach (var tilemapDamage in tilemapDamages) { tilemapDamage.OnExposed(applyExposure.FireExposure); } Profiler.EndSample(); } else { Profiler.BeginSample("DirectExposure"); //direct exposure logic matrix.ForEachRegisterTileSafe(applyExposure, atLocalPosition, true); //expose the tiles foreach (var tilemapDamage in tilemapDamages) { tilemapDamage.OnExposed(applyExposure.FireExposure); } Profiler.EndSample(); } }
/// Same as ExposeHotspot but allows providing a world position and handles the conversion public void ExposeHotspotWorldPosition(Vector2Int tileWorldPosition, float temperature, float volume) { ExposeHotspot(MatrixManager.WorldToLocalInt(tileWorldPosition.To3Int(), MatrixManager.Get(matrix)), temperature, volume); }