예제 #1
0
        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);
        }
예제 #2
0
 private void SyncMatrix()
 {
     if (registerTile && !serverState.IsUninitialized)
     {
         registerTile.ParentNetId = MatrixManager.Get(serverState.MatrixId).NetId;
     }
 }
예제 #3
0
 private void SyncMatrix()
 {
     if (registerTile)
     {
         registerTile.ParentNetId = MatrixManager.Get(serverState.MatrixId).NetId;
     }
 }
예제 #4
0
        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);
            }
        }
예제 #5
0
    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);
        }
    }
예제 #6
0
        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;
            }
        }
예제 #7
0
        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;
            }
        }
예제 #8
0
    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();
        }
    }
예제 #9
0
    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);
            }
        }
    }
예제 #10
0
    /// <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)));
    }
예제 #11
0
    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);
    }
예제 #12
0
    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);
    }
예제 #14
0
    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);
            }
        }
    }
예제 #15
0
        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);
        }
예제 #16
0
    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);
    }
예제 #19
0
    /// 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));
        }
    }
예제 #20
0
    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();
    }
예제 #21
0
    /// 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());
        }
    }
예제 #22
0
    /// 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));
        }
    }
예제 #23
0
    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;
    }
예제 #24
0
    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);
        }
    }
예제 #25
0
    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));
            }
        }
    }
예제 #26
0
    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);
            }
        }
    }
예제 #27
0
    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);
    }
예제 #28
0
    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);
        }
    }
예제 #29
0
        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();
            }
        }
예제 #30
0
 /// 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);
 }