Exemplo n.º 1
0
    private IEnumerator BloodDryUp(MetaDataNode tile)
    {
        //Blood should take 3 mins to dry (TG STATION)
        yield return(WaitFor.Seconds(180));

        tile.IsSlippery = false;

        var floorDecals = matrix.Get <FloorDecal>(tile.Position, isServer: true);

        foreach (var decal in floorDecals)
        {
            if (decal.isBlood)
            {
                decal.color = new Color(decal.color.r / 2, decal.color.g / 2, decal.color.b / 2, decal.color.a);
                decal.name  = $"dried {decal.name}";
            }
        }
    }
Exemplo n.º 2
0
    public MetaDataNode Get(Vector3Int localPosition, bool createIfNotExists = true)
    {
        localPosition.z = 0;         //Z Positions are always on 0

        if (nodes.ContainsKey(localPosition) == false)
        {
            if (createIfNotExists)
            {
                nodes[localPosition] = new MetaDataNode(localPosition, reactionManager, matrix);
            }
            else
            {
                return(MetaDataNode.None);
            }
        }

        return(nodes[localPosition]);
    }
Exemplo n.º 3
0
    private float DealDamageAt(float damage, AttackType attackType, Vector3Int cellPos, Vector3 worldPosition)
    {
        var basicTile = metaTileMap.GetTile(cellPos, Layer.LayerType) as BasicTile;

        if (basicTile == null)
        {
            return(0);
        }

        if (basicTile.indestructible)
        {
            return(0);
        }

        MetaDataNode data = metaDataLayer.Get(cellPos);

        return(AddDamage(damage, attackType, data, basicTile, worldPosition));
    }
Exemplo n.º 4
0
    private void AddGrillDamage(int damage, MetaDataNode data, Vector3Int cellPos, Vector3 bulletHitTarget)
    {
        data.Damage += damage;

        //Make grills a little bit weaker (set to 60 hp):
        if (data.Damage >= 60)
        {
            tileChangeManager.RemoveTile(cellPos, LayerType.Grills);
            tileChangeManager.UpdateTile(cellPos, TileType.WindowDamaged, "GrillDestroyed");

            SoundManager.PlayNetworkedAtPos("GrillHit", bulletHitTarget, 1f);

            //Spawn rods:
            SpawnRods(bulletHitTarget);

            data.ResetDamage();
        }
    }
Exemplo n.º 5
0
        private void OnWillDestroyServer(DestructionInfo info)
        {
            var tileWorldPosition = gameObject.TileWorldPosition().To3Int();
            //release all of our gases at once when destroyed
            MetaDataLayer metaDataLayer  = MatrixManager.AtPoint(tileWorldPosition, true).MetaDataLayer;
            Vector3Int    position       = transform.localPosition.RoundToInt();
            MetaDataNode  node           = metaDataLayer.Get(position, false);
            var           shakeIntensity = (byte)Mathf.Lerp(byte.MinValue, byte.MaxValue / 2, GasMix.Pressure / MAX_EXPLOSION_EFFECT_PRESSURE);
            var           shakeDistance  = Mathf.Lerp(1, 64, GasMix.Pressure / MAX_EXPLOSION_EFFECT_PRESSURE);

            node.GasMix += GasMix;
            metaDataLayer.UpdateSystemsAt(position);
            ChatRelay.Instance.AddToChatLogServer(ChatEvent.Local($"{name} exploded!", gameObject.TileWorldPosition()));

            ItemFactory.SpawnMetal(2, tileWorldPosition.To2Int(), parent: transform.parent);

            ExplosionUtils.PlaySoundAndShake(tileWorldPosition, shakeIntensity, (int)shakeDistance);
        }
Exemplo n.º 6
0
    public override void UpdateAt(Vector3Int localPosition)
    {
        MetaDataNode node = metaDataLayer.Get(localPosition);

        MetaUtils.RemoveFromNeighbors(node);
        externalNodes.TryRemove(node, out MetaDataNode nothing);

        node.IsIsolatedNode = false;

        // If the node is atmos passable (i.e. space or room), we need to setup its neighbors again, otherwise it's occupied and does need a neighbor check
        if (metaTileMap.IsAtmosPassableAt(localPosition, true))
        {
            node.ClearNeighbors();
            node.Type = metaTileMap.IsSpaceAt(localPosition, true) ? NodeType.Space : NodeType.Room;

            if (node.Type == NodeType.Space)
            {
                node.ThermalConductivity = AtmosDefines.SPACE_THERMAL_CONDUCTIVITY;
                node.HeatCapacity        = AtmosDefines.SPACE_HEAT_CAPACITY;
            }
        }
        else
        {
            node.Type = NodeType.Occupied;
            if (matrix.GetFirst <RegisterDoor>(localPosition, true))
            {
                node.IsIsolatedNode = true;

                //TODO hard coded these values, might be better to put them in register door?
                node.ThermalConductivity = 0.001f;
                node.HeatCapacity        = 10000f;
            }
        }

        if (node.IsIsolatedNode == false && node.Type != NodeType.Space &&
            matrix.MetaTileMap.GetTile(localPosition, true) is BasicTile tile && tile != null)
        {
            node.HeatCapacity        = tile.HeatCapacity;
            node.ThermalConductivity = tile.ThermalConductivity;
        }

        SetupNeighbors(node);
        MetaUtils.AddToNeighbors(node);
    }
Exemplo n.º 7
0
        /// <summary>
        /// Used to transfer heat between an Solid tile and Space
        /// Uses data from MetaDataNode for solid node and MetaDataNode date for Space node
        /// </summary>
        private void RadiateTemperatureToSpace(MetaDataNode currentNode, MetaDataNode openNode, float tempDelta)
        {
            if (currentNode.HeatCapacity <= 0)
            {
                return;
            }

            if (Mathf.Abs(tempDelta) <= AtmosDefines.MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
            {
                return;
            }

            //The larger the combined capacity the less is shared
            var heat = openNode.ThermalConductivity * tempDelta *
                       (currentNode.HeatCapacity * AtmosDefines.SPACE_HEAT_CAPACITY /
                        (currentNode.HeatCapacity + AtmosDefines.SPACE_HEAT_CAPACITY));

            currentNode.ConductivityTemperature -= heat / currentNode.HeatCapacity;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Calculate the average Gas tile if you averaged all the adjacent ones and itself
        /// </summary>
        /// <returns>The mean gas mix.</returns>
        private void CalcMeanGasMix()
        {
            meanGasMix.Clear();

            var targetCount = 0;

            for (var i = 0; i < nodes.Count; i++)
            {
                MetaDataNode node = nodes[i];

                if (node == null)
                {
                    continue;
                }

                //If node is not occupied then we want to add it to the total
                if (node.IsOccupied == false && node.IsIsolatedNode == false)
                {
                    meanGasMix.Volume += node.GasMix.Volume;
                    GasMix.TransferGas(meanGasMix, node.GasMix, node.GasMix.Moles, true);
                    targetCount++;
                }
                else if (node.IsIsolatedNode == false)
                {
                    //Remove all overlays for occupied tiles
                    RemovalAllGasOverlays(node);

                    //We trap the gas in the walls to stop instances where you remove a wall and theres a vacuum there
                }
            }

            // Sometimes, we calculate the meanGasMix of a tile surrounded by IsOccupied tiles (no atmos, ie: walls)
            if (targetCount == 0)
            {
                return;
            }

            meanGasMix.Volume /= targetCount;             //Note: this assumes the volume of all tiles are the same
            foreach (var gasData in meanGasMix.GasesArray)
            {
                meanGasMix.GasData.SetMoles(gasData.GasSO, meanGasMix.GasData.GetGasMoles(gasData.GasSO) / targetCount);
            }
        }
Exemplo n.º 9
0
        public float EqualisePipe(MetaDataNode Node, ReagentMix Mix)
        {
            //add Radiation of Heat

/*
 *                      float EnergyChange = 0f; //Minuses energy taken away, + is energy added to the pipe
 *                      if (Node.IsSpace)
 *                      {
 *                              //Radiation
 *                              //Invisible pipes to radiation
 *                              EnergyChange = -(StefanBoltzmannConstant * (Mix.InternalEnergy));
 *                              Node.GasMix = GasMixes.Space;
 *                      }
 *
 *                      float EnergyTransfered =
 *                              ((390 * (Node.GasMix.Temperature -Mix.Temperature)) / 0.01f);
 *
 *                      float EqualiseTemperature = (Node.GasMix.InternalEnergy + Mix.InternalEnergy) /
 *                              (Node.GasMix.WholeHeatCapacity + Mix.WholeHeatCapacity);
 *
 *                      var ChangeInInternalEnergy = Mix.WholeHeatCapacity* (EqualiseTemperature -Mix.Temperature);
 *
 *                      if (Math.Abs( EnergyTransfered) > Math.Abs( ChangeInInternalEnergy))
 *                      {
 *                              EnergyChange += ChangeInInternalEnergy;
 *                      }
 *                      else
 *                      {
 *                              EnergyChange += EnergyTransfered;
 *                      }
 *                      //Logger.Log("EnergyChange > " + EnergyChange);
 *                      var gas = Node.GasMix;
 *                      gas.InternalEnergy = gas.InternalEnergy + (-EnergyChange);
 *                      if (gas.InternalEnergy < 0)
 *                      {
 *                              Logger.LogWarning("OHHHH", Category.Atmos);
 *                              gas.InternalEnergy = 1;
 *                      }
 *                      Node.GasMix = gas;
 *                      return (EnergyChange);
 */
            return(0);
        }
Exemplo n.º 10
0
    private void FindRoomAt(Vector3Int position)
    {
        if (!metaTileMap.IsAtmosPassableAt(position, true))
        {
            MetaDataNode node = metaDataLayer.Get(position);
            node.Type = NodeType.Occupied;

            if (matrix.GetFirst <RegisterDoor>(position, true))
            {
                node.IsClosedAirlock = true;
            }

            SetupNeighbors(node);
        }
        else if (!metaTileMap.IsSpaceAt(position, true) && !metaDataLayer.IsRoomAt(position) && !metaDataLayer.IsSpaceAt(position))
        {
            CreateRoom(position);
        }
    }
Exemplo n.º 11
0
        /// <summary>
        /// The thing that actually equalises the tiles
        /// </summary>
        private void Equalize()
        {
            // If there is just one isolated tile, it's not nescessary to calculate the mean.  Speeds up things a bit.
            if (nodes.Count > 1)
            {
                //Calculate the average gas from adding up all the adjacent tiles and dividing by the number of tiles
                GasMix MeanGasMix = CalcMeanGasMix();

                for (var i = 0; i < nodes.Count; i++)
                {
                    MetaDataNode node = nodes[i];

                    if (!node.IsOccupied)
                    {
                        node.GasMix = CalcAtmos(node.GasMix, MeanGasMix);
                    }
                }
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Calculate the average Gas tile if you averaged all the adjacent ones and itself
        /// </summary>
        /// <returns>The mean gas mix.</returns>
        private GasMix CalcMeanGasMix()
        {
            meanGasMix.Copy(GasMixes.Space);

            int targetCount = 0;

            for (var i = 0; i < nodes.Count; i++)
            {
                MetaDataNode node = nodes[i];

                if (node.IsSpace)
                {
                    //Set to 0 if space
                    node.GasMix *= 0;
                }

                for (int j = 0; j < Gas.Count; j++)
                {
                    meanGasMix.Gases[j] += node.GasMix.Gases[j];
                }

                meanGasMix.Pressure += node.GasMix.Pressure;

                if (!node.IsOccupied)
                {
                    targetCount++;
                }
                else
                {
                    //Decay if occupied
                    node.GasMix *= 0;
                }
            }

            for (int j = 0; j < Gas.Count; j++)
            {
                meanGasMix.Gases[j] /= targetCount;
            }

            meanGasMix.Pressure /= targetCount;

            return(meanGasMix);
        }
Exemplo n.º 13
0
    private void ServerDoCPR(GameObject performer, GameObject target, BodyPartType TargetBodyPart)
    {
        var          health   = target.GetComponent <LivingHealthMasterBase>();
        Vector3Int   position = health.ObjectBehaviour.AssumedWorldPositionServer();
        MetaDataNode node     = MatrixManager.GetMetaDataAt(position);

        bool hasLung  = false;
        bool hasHeart = false;

        foreach (var BodyPart in health.GetBodyPartsInZone(TargetBodyPart, false))
        {
            foreach (var organ in BodyPart.OrganList)
            {
                if (organ is Lungs lung)
                {
                    lung.TryBreathing(node, 1);
                    hasLung = true;
                }

                if (organ is Heart heart)
                {
                    heart.Heartbeat(1);
                    hasHeart = true;
                }
            }
        }

        if (hasHeart && hasLung)
        {
            Chat.AddActionMsgToChat(
                performer,
                $"You perform CPR on {targetName}.",
                $"{performerName} performs CPR on {targetName}.");
            Chat.AddExamineMsgFromServer(target, $"You feel fresh air enter your lungs. It feels good!");
        }
        else
        {
            Chat.AddActionMsgToChat(
                performer,
                $"You perform CPR on {targetName}. It doesn't seem to work, maybe they're missing something.",
                $"{performerName} performs CPR on {targetName} In vain.");
        }
    }
Exemplo n.º 14
0
    private float AddDamage(float damage, AttackType attackType, MetaDataNode data,
                            BasicTile basicTile, Vector3 worldPosition)
    {
        if (basicTile.indestructible)
        {
            return(0);
        }

        data.AddTileDamage(Layer.LayerType, basicTile.Armor.GetDamage(damage < basicTile.damageDeflection? 0: damage, attackType));
        SoundManager.PlayNetworkedAtPos(basicTile.SoundOnHit, worldPosition);
        if (data.GetTileDamage(Layer.LayerType) >= basicTile.MaxHealth)
        {
            data.RemoveTileDamage(Layer.LayerType);
            tileChangeManager.RemoveTile(data.Position, Layer.LayerType);
            basicTile.LootOnDespawn?.SpawnLoot(worldPosition);
        }

        return(CalculateAbsorbDamaged(attackType, data, basicTile));
    }
Exemplo n.º 15
0
    public override void UpdateAt(Vector3Int position)
    {
        MetaDataNode node = metaDataLayer.Get(position);

        MetaUtils.RemoveFromNeighbors(node);

        if (metaTileMap.IsAtmosPassableAt(position))
        {
            node.ClearNeighbors();

            node.Type = metaTileMap.IsSpaceAt(position) ? NodeType.Space : NodeType.Room;
            SetupNeighbors(node);
            MetaUtils.AddToNeighbors(node);
        }
        else
        {
            node.Type = NodeType.Occupied;
        }
    }
Exemplo n.º 16
0
        private void OnWillDestroyServer(DestructionInfo info)
        {
            var tileWorldPosition = gameObject.TileWorldPosition().To3Int();
            //release all of our gases at once when destroyed
            MetaDataLayer metaDataLayer  = MatrixManager.AtPoint(tileWorldPosition, true).MetaDataLayer;
            Vector3Int    position       = transform.localPosition.RoundToInt();
            MetaDataNode  node           = metaDataLayer.Get(position, false);
            var           shakeIntensity = (byte)Mathf.Lerp(byte.MinValue, byte.MaxValue / 2, GasMix.Pressure / MAX_EXPLOSION_EFFECT_PRESSURE);
            var           shakeDistance  = Mathf.Lerp(1, 64, GasMix.Pressure / MAX_EXPLOSION_EFFECT_PRESSURE);

            node.GasMix += GasMix;
            metaDataLayer.UpdateSystemsAt(position);
            Chat.AddLocalDestroyMsgToChat(gameObject.ExpensiveName(), " exploded!", gameObject.TileWorldPosition());

            Spawn.ServerPrefab("Metal", gameObject.TileWorldPosition().To3Int(), transform.parent, count: 2,
                               scatterRadius: Spawn.DefaultScatterRadius, cancelIfImpassable: true);

            ExplosionUtils.PlaySoundAndShake(tileWorldPosition, shakeIntensity, (int)shakeDistance);
        }
Exemplo n.º 17
0
    private void AssignType(IEnumerable <Vector3Int> positions, NodeType nodeType)
    {
        // Bulk assign type to nodes at given positions
        foreach (Vector3Int position in positions)
        {
            MetaDataNode node = metaDataLayer.Get(position);

            node.Type = nodeType;

            // assign room number, if type is room
            node.RoomNumber = nodeType == NodeType.Room ? roomCounter : -1;
        }

        // increase room counter, so next room will get a new number
        if (nodeType == NodeType.Room)
        {
            roomCounter++;
        }
    }
Exemplo n.º 18
0
        /// <summary>
        /// Calculate the average Gas tile if you averaged all the adjacent ones and itself
        /// </summary>
        /// <returns>The mean gas mix.</returns>
        private GasMix CalcMeanGasMix()
        {
            meanGasMix.Copy(GasMixes.Space);

            int targetCount = 0;

            for (var i = 0; i < nodes.Count; i++)
            {
                MetaDataNode node = nodes[i];

                for (int j = 0; j < Gas.Count; j++)
                {
                    meanGasMix.Gases[j] += node.GasMix.Gases[j];
                }

                meanGasMix.Pressure += node.GasMix.Pressure;

                if (!node.IsOccupied)
                {
                    targetCount++;
                }
                else
                {
                    //Decay if occupied
                    node.GasMix *= 0;
                }
            }

            // Sometime, we calculate the meanGasMix of a tile surrounded by IsOccupied tiles (no atmos)
            // This condition is to avoid a divide by zero error (or 0 / 0 that gives NaN)
            if (targetCount != 0)
            {
                for (int j = 0; j < Gas.Count; j++)
                {
                    meanGasMix.Gases[j] /= targetCount;
                }

                meanGasMix.Pressure /= targetCount;
            }

            return(meanGasMix);
        }
Exemplo n.º 19
0
        public float EqualisePipe(MetaDataNode Node, ReagentMix Mix)
        {
            //add Radiation of Heat

            float EnergyChange = 0f;             //Minuses energy taken away, + is energy added to the pipe

            if (Node.IsSpace)
            {
                //Radiation
                //Invisible pipes to radiation
                EnergyChange = -(StefanBoltzmannConstant * (Mix.InternalEnergy));
                Node.GasMix  = GasMixes.Space;
            }

            float EnergyTransfered =
                ((390 * (Node.GasMix.Temperature - Mix.Temperature)) / 0.01f);

            float EqualiseTemperature = (Node.GasMix.InternalEnergy + Mix.InternalEnergy) /
                                        (Node.GasMix.WholeHeatCapacity + Mix.WholeHeatCapacity);

            var ChangeInInternalEnergy = Mix.WholeHeatCapacity * (EqualiseTemperature - Mix.Temperature);

            if (Math.Abs(EnergyTransfered) > Math.Abs(ChangeInInternalEnergy))
            {
                EnergyChange += ChangeInInternalEnergy;
            }
            else
            {
                EnergyChange += EnergyTransfered;
            }
            //Logger.Log("EnergyChange > " + EnergyChange);
            var gas = Node.GasMix;

            gas.InternalEnergy = gas.InternalEnergy + (-EnergyChange);
            if (gas.InternalEnergy < 0)
            {
                Logger.LogWarning("OHHHH", Category.Atmos);
                gas.InternalEnergy = 1;
            }
            Node.GasMix = gas;
            return(EnergyChange);
        }
Exemplo n.º 20
0
    /// <summary>
    /// Damage a window tile, incrementaly
    /// </summary>
    /// <param name="damage">The amount of damage the window received</param>
    /// <param name="data">The data about the current state of this window</param>
    /// <param name="cellPos">The position of the window tile</param>
    /// <param name="hitPos">Where exactly the bullet hit</param>
    /// <param name="attackType">The type of attack that did the damage</param>
    /// <returns>The remaining damage to apply to the tile if the window is broken, 0 otherwise.</returns>
    private float AddWindowDamage(float damage, MetaDataNode data, Vector3Int cellPos, Vector3 hitPos, AttackType attackType, bool spawnPieces = true)
    {
        data.Damage += REINFORCED_WINDOW_ARMOR.GetDamage(damage, attackType);

        if (data.Damage >= 20 && data.Damage < 50)
        {
            tileChangeManager.UpdateTile(cellPos, TileType.WindowDamaged, "crack01");
            data.WindowDamage = WindowDamageLevel.Crack01;
        }

        if (data.Damage >= 50 && data.Damage < 75)
        {
            tileChangeManager.UpdateTile(cellPos, TileType.WindowDamaged, "crack02");
            data.WindowDamage = WindowDamageLevel.Crack02;
        }

        if (data.Damage >= 75 && data.Damage < MAX_WINDOW_DAMAGE)
        {
            tileChangeManager.UpdateTile(cellPos, TileType.WindowDamaged, "crack03");
            data.WindowDamage = WindowDamageLevel.Crack03;
        }

        if (data.Damage >= MAX_WINDOW_DAMAGE)
        {
            tileChangeManager.RemoveTile(cellPos, LayerType.Effects);
            tileChangeManager.RemoveTile(cellPos, LayerType.Windows);
            data.WindowDamage = WindowDamageLevel.Broken;

            //Spawn 3 glass shards with different sprites:
            if (spawnPieces)
            {
                SpawnGlassShards(hitPos);
            }

            //Play the breaking window sfx:
            SoundManager.PlayNetworkedAtPos("GlassBreak0#", hitPos, 1f);

            return(data.ResetDamage() - MAX_WINDOW_DAMAGE);
        }

        return(0);        // The remaining damage after cracking the window.
    }
Exemplo n.º 21
0
    /// <summary>
    /// Gets the MetaDataNode from the Matrix at the given position.
    /// </summary>
    /// <param name="worldPosition">Position at which the node is looked for.</param>
    /// <returns>MetaDataNode at the position. If no Node that isn't space is found, MetaDataNode.Node will be returned.</returns>
    public static MetaDataNode GetMetaDataAt(Vector3Int worldPosition)
    {
        foreach (MatrixInfo mat in Instance.ActiveMatrices)
        {
            if (mat == null)
            {
                continue;
            }

            Vector3Int   position = WorldToLocalInt(worldPosition, mat);
            MetaDataNode node     = mat.MetaDataLayer.Get(position, false);

            if (node.Exists && node.IsSpace == false)
            {
                return(node);
            }
        }

        return(MetaDataNode.None);
    }
Exemplo n.º 22
0
    public void OnExposed(FireExposure exposure)
    {
        if (Layer.LayerType == LayerType.Floors ||
            Layer.LayerType == LayerType.Base ||
            Layer.LayerType == LayerType.Walls)
        {
            return;
        }

        var basicTile = metaTileMap.GetTile(exposure.ExposedLocalPosition, Layer.LayerType) as BasicTile;

        if (basicTile == null)
        {
            return;
        }

        MetaDataNode data = metaDataLayer.Get(exposure.ExposedLocalPosition);

        AddDamage(exposure.StandardDamage(), AttackType.Fire, data, basicTile, exposure.ExposedWorldPosition);
    }
Exemplo n.º 23
0
        //Handles checking for vfx changes
        //If needed, sends them to a queue in ReactionManager so that main thread will apply them
        private void GasVisualEffects(MetaDataNode node)
        {
            if (node.GasMix.GetMoles(Gas.Plasma) > 0.4)                         //If node has an almost combustible ammount of plasma
            {
                if (!fogTiles.Contains(node.Position))                          //And if it hasn't already been identified as a tile that should have plasma fx
                {
                    node.ReactionManager.AddFogEvent(node);                     //Add it to the atmos vfx queue in ReactionManager
                    fogTiles.Add(node.Position);                                //Add it to fogTiles
                }
            }

            else                                                                                                //If there isn't 0.4 moles of plasma, remove the fx
            {
                if (fogTiles.Contains(node.Position) && (node.GasMix.GetMoles(Gas.Plasma) < 0.3))
                {
                    node.ReactionManager.RemoveFogEvent(node);
                    fogTiles.Remove(node.Position);
                }
            }
        }
Exemplo n.º 24
0
    /// <summary>
    /// Damage a window tile, incrementaly
    /// </summary>
    /// <param name="damage">The amount of damage the window received</param>
    /// <param name="data">The data about the current state of this window</param>
    /// <param name="cellPos">The position of the window tile</param>
    /// <param name="hitPos">Where exactly the bullet hit</param>
    /// <param name="attackType">The type of attack that did the damage</param>
    /// <returns>The remaining damage to apply to the tile if the window is broken, 0 otherwise.</returns>
    private float AddWindowDamage(float damage, MetaDataNode data, Vector3Int cellPos, Vector3 hitPos, AttackType attackType, bool spawnPieces = true)
    {
        BasicTile tile = null;

        data.Damage += GetReducedDamage(cellPos, damage, attackType);

        if (data.Damage >= 20 && data.Damage < 50)
        {
            tileChangeManager.UpdateTile(cellPos, TileType.WindowDamaged, "crack01");
            data.WindowDamage = WindowDamageLevel.Crack01;
        }

        if (data.Damage >= 50 && data.Damage < 75)
        {
            tileChangeManager.UpdateTile(cellPos, TileType.WindowDamaged, "crack02");
            data.WindowDamage = WindowDamageLevel.Crack02;
        }

        if (data.Damage >= 75 && data.Damage < GetMaxDamage(cellPos))
        {
            tileChangeManager.UpdateTile(cellPos, TileType.WindowDamaged, "crack03");
            data.WindowDamage = WindowDamageLevel.Crack03;
        }

        if (data.Damage >= GetMaxDamage(cellPos))
        {
            tile = tileChangeManager.RemoveTile(cellPos, LayerType.Windows) as BasicTile;
            data.WindowDamage = WindowDamageLevel.Broken;

            //Spawn up to 2 glass shards with different sprites:
            if (spawnPieces)
            {
                SpawnGlassShards(hitPos);
            }

            //Play the breaking window sfx:
            SoundManager.PlayNetworkedAtPos("GlassBreak0#", hitPos, 1f);
        }

        return(CalculateAbsorbDamaged(cellPos, attackType, data, tile));
    }
Exemplo n.º 25
0
        //Handles checking for vfx changes
        //If needed, sends them to a queue in ReactionManager so that main thread will apply them
        private void GasVisualEffects(MetaDataNode node)
        {
            if (node == null || node.ReactionManager == null)
            {
                return;
            }

            foreach (var gasData in node.GasMix.GasesArray)
            {
                var gas = gasData.GasSO;
                if (!gas.HasOverlay)
                {
                    continue;
                }

                var gasAmount = node.GasMix.GetMoles(gas);

                if (gasAmount > gas.MinMolesToSee)
                {
                    if (node.GasOverlayData.Contains(gas))
                    {
                        continue;
                    }

                    node.AddGasOverlay(gas);

                    node.ReactionManager.TileChangeManager.AddOverlay(node.Position, TileManager.GetTile(TileType.Effects, gas.TileName) as OverlayTile);
                }
                else
                {
                    if (node.GasOverlayData.Contains(gas) == false)
                    {
                        continue;
                    }

                    node.RemoveGasOverlay(gas);

                    node.ReactionManager.TileChangeManager.RemoveOverlaysOfType(node.Position, LayerType.Effects, gas.OverlayType);
                }
            }
        }
Exemplo n.º 26
0
    private void Update()
    {
        timePassed += Time.deltaTime;

        if (timePassed < 0.5)
        {
            return;
        }

        timePassed = 0;

        foreach (MetaDataNode node in hotspots.Values.ToArray())
        {
            if (node.Hotspot != null)
            {
                if (node.Hotspot.Process())
                {
                    if (node.Hotspot.Volume > 0.95 * node.GasMix.Volume && node.Hotspot.Temperature > Reactions.FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
                    {
                        for (var i = 0; i < node.Neighbors.Length; i++)
                        {
                            MetaDataNode neighbor = node.Neighbors[i];

                            if (neighbor != null)
                            {
                                ExposeHotspot(node.Neighbors[i].Position, node.GasMix.Temperature * 0.85f, node.GasMix.Volume / 4);
                            }
                        }
                    }

                    tileChangeManager.UpdateTile(node.Position, TileType.Effects, "Fire");
                }
                else
                {
                    node.Hotspot = null;
                    hotspots.Remove(node.Position);
                    tileChangeManager.RemoveTile(node.Position, LayerType.Effects);
                }
            }
        }
    }
Exemplo n.º 27
0
        /// <summary>
        /// Calculate the average Gas tile if you averaged all the adjacent ones and itself
        /// </summary>
        /// <returns>The mean gas mix.</returns>
        private void CalcMeanGasMix()
        {
            meanGasMix.Copy(GasMixes.Empty);

            var targetCount = 0;

            for (var i = 0; i < nodes.Count; i++)
            {
                MetaDataNode node = nodes[i];

                if (node == null)
                {
                    continue;
                }

                meanGasMix.Volume += node.GasMix.Volume;
                GasMix.TransferGas(meanGasMix, node.GasMix, node.GasMix.Moles);

                if (!node.IsOccupied)
                {
                    targetCount++;
                }
                else
                {
                    //Decay if occupied
                    node.GasMix.SetToEmpty();
                }
            }

            // Sometimes, we calculate the meanGasMix of a tile surrounded by IsOccupied tiles (no atmos, ie: walls)
            if (targetCount == 0)
            {
                return;
            }

            meanGasMix.Volume /= targetCount;             //Note: this assumes the volume of all tiles are the same
            for (var i = 0; i < Gas.Count; i++)
            {
                meanGasMix.Gases[i] = meanGasMix.Gases[i] / targetCount;
            }
        }
Exemplo n.º 28
0
        public void React(GasMix gasMix, MetaDataNode node)
        {
            var waterMoles = gasMix.GetMoles(Gas.WaterVapor);

            if (waterMoles != 0 && waterMoles / gasMix.Moles > 0.1)
            {
                //No reaction
                return;
            }

            var cleanedAir =
                Mathf.Min(
                    gasMix.GetMoles(Gas.Miasma),
                    20 + (gasMix.Temperature - AtmosDefines.FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20);

            gasMix.RemoveGas(Gas.Miasma, cleanedAir);

            gasMix.AddGas(Gas.Oxygen, cleanedAir);

            gasMix.SetTemperature(gasMix.Temperature + cleanedAir * 0.002f);
        }
Exemplo n.º 29
0
        private void CollectorUpdate()
        {
            if (CustomNetworkManager.IsServer == false)
            {
                return;
            }

            MetaDataNode node = registerTile.Matrix.GetMetaDataNode(registerTile.LocalPositionServer);

            if (node == null)
            {
                radiationLevel = 0;
                moduleSupplyingDevice.ProducingWatts = 0;
                return;
            }

            radiationLevel = node.RadiationNode.RadiationLevel;
            generatedWatts = radiationLevel * radiationWatts;

            moduleSupplyingDevice.ProducingWatts = generatedWatts;
        }
Exemplo n.º 30
0
    public void ExposeHotspot(Vector3Int position, float temperature, float volume)
    {
        if (hotspots.ContainsKey(position) && hotspots[position].Hotspot != null)
        {
            // TODO soh?
            hotspots[position].Hotspot.UpdateValues(volume * 25, temperature);
        }
        else
        {
            MetaDataNode node   = metaDataLayer.Get(position);
            GasMix       gasMix = node.Atmos;

            if (gasMix.GetMoles(Gas.Plasma) > 0.5 && gasMix.GetMoles(Gas.Oxygen) > 0.5 && temperature > Reactions.PLASMA_MINIMUM_BURN_TEMPERATURE)
            {
                // igniting
                Hotspot hotspot = new Hotspot(node, temperature, volume * 25);
                node.Hotspot       = hotspot;
                hotspots[position] = node;
            }
        }
    }
		public virtual Value evaluate(Context cx, MetaDataNode node)
		{
			output("<MetaDataNode id=\"" + node.id + "\">");
			indent_Renamed_Field++;
			if (node.data != null)
			{
				MetaDataEvaluator mde = new MetaDataEvaluator();
				node.evaluate(cx, mde);
			}
			indent_Renamed_Field--;
			output("</MetaDataNode>");
			return null;
		}