private void MonitorSystem()
    {
        if (!livingHealthBehaviour.IsDead)
        {
            Vector3Int   position = objectBehaviour.AssumedWorldPositionServer();
            MetaDataNode node     = MatrixManager.GetMetaDataAt(position);

            if (!IsEVACompatible())
            {
                temperature = node.GasMix.Temperature;
                pressure    = node.GasMix.Pressure;
                CheckPressureDamage();
            }
            else
            {
                pressure    = 101.325f;
                temperature = 293.15f;
            }

            if (livingHealthBehaviour.OverallHealth >= HealthThreshold.SoftCrit)
            {
                //if (Breathe(node))
                //	{
                //		AtmosManager.Update(node);
                //	}
            }
            else
            {
                bloodSystem.OxygenDamage += 1;
            }
        }
    }
    //Find the APC in the same room as the light switch and assign it to RelatedAPC
    private void DetectAPC()
    {
        if (RelatedAPC != null)
        {
            return;
        }

        int layerMask    = LayerMask.GetMask("WallMounts");
        var possibleApcs = Physics2D.OverlapCircleAll(GetCastPos(), radius, layerMask);

        int thisRoomNum = MatrixManager.GetMetaDataAt(Vector3Int.RoundToInt(transform.position - transform.up)).RoomNumber;

        foreach (Collider2D col in possibleApcs)
        {
            if (col.tag == "APC")
            {
                //Light switch has no room number, assign it to the first APC it finds so it still functions
                if (thisRoomNum == -1)
                {
                    RelatedAPC = col.gameObject.GetComponent <APC>();
                    break;
                }

                if (MatrixManager.GetMetaDataAt(Vector3Int.RoundToInt(col.transform.position - col.transform.up)).RoomNumber == thisRoomNum)
                {
                    RelatedAPC = col.gameObject.GetComponent <APC>();
                    break;
                }
            }
        }
        if (RelatedAPC == null && !SelfPowered)
        {
            SyncLightSwitch(isOn, States.PowerCut);
        }
    }
Exemple #3
0
    private void MonitorSystem()
    {
        if (!livingHealthBehaviour.IsDead)
        {
            Vector3Int   position = objectBehaviour.AssumedLocation().RoundToInt();
            MetaDataNode node     = MatrixManager.GetMetaDataAt(position);
            PressureStatus = CheckPressureStatus(node.GasMix.Pressure);
            TempStatus     = CheckTempStatus(node.GasMix.Temperature);
            if (!IsEVACompatible())
            {
                CheckPressureDamage(node.GasMix.Pressure);
            }

            if (livingHealthBehaviour.OverallHealth >= HealthThreshold.SoftCrit)
            {
                if (Breathe(node))
                {
                    AtmosManager.Update(node);
                }
            }
            else
            {
                bloodSystem.OxygenDamage += 1;
            }
        }
    }
Exemple #4
0
        private void MonitorSystem()
        {
            if (!healthMaster.IsDead)
            {
                Vector3Int   position = objectBehaviour.AssumedWorldPositionServer();
                MetaDataNode node     = MatrixManager.GetMetaDataAt(position);

                if (!IsEVACompatible())
                {
                    healthStateController.SetTemperature(node.GasMix.Temperature);
                    healthStateController.SetPressure(node.GasMix.Pressure);
                    CheckPressureDamage();
                }
                else
                {
                    healthStateController.SetPressure(101.325f);
                    healthStateController.SetTemperature(293.15f);
                }

                // if(healthMaster.OverallHealth >= HealthThreshold.SoftCrit)
                // {
                //  if (Breathe(node))
                //  {
                //      AtmosManager.Update(node);
                //  }
                // }
            }
        }
Exemple #5
0
    private void UpdateCycle()
    {
        if (!CustomNetworkManager.IsServer)
        {
            return;
        }

        var pos = registerTile.WorldPosition;

        if (pos == posCache && metaDataNode.GasMix.Temperature > AtmosDefines.WATER_VAPOR_FREEZE)
        {
            metaDataNode.GasMix.AddGas(Gas.WaterVapor, 2f);
            Despawn.ServerSingle(gameObject);
            return;
        }
        else
        {
            posCache     = pos;
            metaDataNode = MatrixManager.GetMetaDataAt(pos);

            if (metaDataNode.GasMix.Temperature > AtmosDefines.WATER_VAPOR_FREEZE)
            {
                metaDataNode.GasMix.AddGas(Gas.WaterVapor, 2f);
                Despawn.ServerSingle(gameObject);
                return;
            }
        }
    }
Exemple #6
0
        private void OnWelderUse(Interaction interaction)
        {
            if (Validations.HasUsedActiveWelder(interaction) == false)
            {
                return;
            }

            var pos = registerTile.WorldPositionServer;

            //If in inventory use player pos instead, check root in case player is in something
            if (pickupable.ItemSlot != null)
            {
                pos = pickupable.ItemSlot.GetRootStorage().gameObject.WorldPosServer().RoundToInt();
            }

            //If hidden then stop
            if (pos == TransformState.HiddenPos)
            {
                return;
            }

            Chat.AddActionMsgToChat(interaction.Performer, $"You melt the {gameObject.ExpensiveName()} with the {interaction.UsedObject.ExpensiveName()}",
                                    $"{interaction.Performer.ExpensiveName()} melts the {gameObject.ExpensiveName()} with the {interaction.UsedObject.ExpensiveName()}");

            if (isHotIce == false)
            {
                MeltIce(MatrixManager.GetMetaDataAt(pos));
                return;
            }

            MeltHotIce(MatrixManager.GetMetaDataAt(pos));
        }
Exemple #7
0
    //Removes all plasma from tiles, in effect putting out fires
    public static void ExtinguishTile(Vector3 worldPos)
    {
        var          worldPosInt = worldPos.CutToInt();
        var          matrix      = MatrixManager.AtPoint(worldPosInt);
        var          localPosInt = MatrixManager.WorldToLocalInt(worldPosInt, matrix);
        MetaDataNode node        = MatrixManager.GetMetaDataAt(worldPosInt);

        node.GasMix.RemoveGas(Atmospherics.Gas.Plasma, node.GasMix.GetMoles(Atmospherics.Gas.Plasma));
    }
        public void OnSpawnServer(SpawnInfo info)
        {
            var registerTile = gameObject.RegisterTile();

            metaNode = MatrixManager.GetMetaDataAt(registerTile.WorldPosition);

            registerTile.OnLocalPositionChangedServer.AddListener((newLocalPosition) =>
            {
                metaNode = MatrixManager.GetMetaDataAt(registerTile.WorldPosition);
            });
        }
Exemple #9
0
    public override void ImplantPeriodicUpdate()
    {
        base.ImplantPeriodicUpdate();

        Vector3Int   position = healthMaster.ObjectBehaviour.AssumedWorldPositionServer();
        MetaDataNode node     = MatrixManager.GetMetaDataAt(position);

        if (TryBreathing(node, TotalModified))
        {
            AtmosManager.Update(node);
        }
    }
Exemple #10
0
        public override void ImplantPeriodicUpdate()
        {
            base.ImplantPeriodicUpdate();

            // Disable breathing for dead and brain damaged players
            if (RelatedPart.HealthMaster.IsDead)
            {
                return;
            }

            Brain brain = RelatedPart.HealthMaster.brain;

            if (brain && brain.RelatedPart.TotalModified <= 0.2f)
            {
                return;
            }

            Vector3Int   position      = RelatedPart.HealthMaster.ObjectBehaviour.AssumedWorldPositionServer();
            MetaDataNode node          = MatrixManager.GetMetaDataAt(position);
            var          TotalModified = 1f;

            foreach (var modifier in bodyPart.AppliedModifiers)
            {
                var toMultiply = 1f;
                if (modifier == bodyPart.DamageModifier)
                {
                    toMultiply = Mathf.Max(0f,
                                           Mathf.Max(bodyPart.MaxHealth - bodyPart.TotalDamageWithoutOxyCloneRadStam, 0) /
                                           bodyPart.MaxHealth);
                }
                else if (modifier == bodyPart.HungerModifier)
                {
                    continue;
                }
                else
                {
                    toMultiply = Mathf.Max(0f, modifier.Multiplier);
                }

                TotalModified *= toMultiply;
            }

            if (TryBreathing(node, TotalModified))
            {
                AtmosManager.Instance.UpdateNode(node);
            }

            if (RelatedPart.IsBleedingInternally)
            {
                InternalDamageLogic();
            }
        }
Exemple #11
0
    private void ServerUpdateCycle()
    {
        var pos = registerTile.WorldPosition;

        if (pos != posCache)
        {
            metaDataNode = MatrixManager.GetMetaDataAt(pos);
            posCache     = pos;
        }

        if (metaDataNode.GasMix.Temperature > AtmosDefines.WATER_VAPOR_FREEZE)
        {
            metaDataNode.GasMix.AddGas(Gas.WaterVapor, 2f);
            Despawn.ServerSingle(gameObject);
        }
    }
    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.BodyPartList)
        {
            if (bodyPart.BodyPartType == TargetBodyPart)
            {
                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.");
        }
    }
Exemple #13
0
        /// <summary>
        ///  Checks each side of the door, returns true if not considered safe and updates pressureLevel.
        ///  Used to allow the player to be made aware of the pressure difference for safety.
        /// </summary>
        /// <returns></returns>
        private bool DoorUnderPressure()
        {
            if (!enablePressureWarning)
            {
                // Pressure warning system is disabled, so pretend everything is fine.
                return(false);
            }

            // Obtain the adjacent tiles to the door.
            var upMetaNode    = MatrixManager.GetMetaDataAt(registerTile.WorldPositionServer + Vector3Int.up);
            var downMetaNode  = MatrixManager.GetMetaDataAt(registerTile.WorldPositionServer + Vector3Int.down);
            var leftMetaNode  = MatrixManager.GetMetaDataAt(registerTile.WorldPositionServer + Vector3Int.left);
            var rightMetaNode = MatrixManager.GetMetaDataAt(registerTile.WorldPositionServer + Vector3Int.right);

            // Only find the pressure comparison if both opposing sides are atmos. passable.
            // If both sides are not atmos. passable, then we don't care about the pressure difference.
            var vertPressureDiff = 0.0;
            var horzPressureDiff = 0.0;

            if (!upMetaNode.IsOccupied || !downMetaNode.IsOccupied)
            {
                vertPressureDiff = Math.Abs(upMetaNode.GasMix.Pressure - downMetaNode.GasMix.Pressure);
            }
            if (!leftMetaNode.IsOccupied || !rightMetaNode.IsOccupied)
            {
                horzPressureDiff = Math.Abs(leftMetaNode.GasMix.Pressure - rightMetaNode.GasMix.Pressure);
            }

            // Set pressureLevel according to the pressure difference found.
            if (vertPressureDiff >= pressureThresholdWarning || horzPressureDiff >= pressureThresholdWarning)
            {
                pressureLevel = PressureLevel.Warning;
                return(true);
            }
            else if (vertPressureDiff >= pressureThresholdCaution || horzPressureDiff >= pressureThresholdCaution)
            {
                pressureLevel = PressureLevel.Caution;
                return(true);
            }
            else
            {
                pressureLevel = PressureLevel.Safe;
                return(false);
            }
        }
    private void MonitorSystem()
    {
        if (!livingHealthBehaviour.IsDead)
        {
            Vector3Int   position = transform.position.RoundToInt();
            MetaDataNode node     = MatrixManager.GetMetaDataAt(position);

            if (!IsEVACompatible())
            {
                CheckPressureDamage(node.GasMix.Pressure);
            }

            if (Breathe(node))
            {
                AtmosManager.Update(node);
            }
        }
    }
Exemple #15
0
    public override void ImplantPeriodicUpdate()
    {
        base.ImplantPeriodicUpdate();

        Vector3Int   position = RelatedPart.HealthMaster.ObjectBehaviour.AssumedWorldPositionServer();
        MetaDataNode node     = MatrixManager.GetMetaDataAt(position);


        var TotalModified = 1f;

        foreach (var Modifier in RelatedPart.AppliedModifiers)
        {
            var toMultiply = 1f;
            if (Modifier == RelatedPart.DamageModifier)
            {
                toMultiply = Mathf.Max(0f, Mathf.Max(RelatedPart.MaxHealth - RelatedPart.TotalDamageWithoutOxyCloneRadStam, 0) / RelatedPart.MaxHealth);
            }
            else if (Modifier == RelatedPart.HungerModifier)
            {
                continue;
            }
            else
            {
                toMultiply = Mathf.Max(0f, Modifier.Multiplier);
            }
            TotalModified *= toMultiply;
        }


        if (TryBreathing(node, TotalModified))
        {
            AtmosManager.Update(node);
        }

        if (RelatedPart.IsBleedingInternally)
        {
            InternalDamageLogic();
        }
    }
Exemple #16
0
        private void ServerUpdateCycle()
        {
            var pos = registerTile.WorldPosition;

            //If in an itemslot try to get that root position
            if (pickupable.ItemSlot != null)
            {
                pos = pickupable.ItemSlot.GetRootStorage().gameObject.WorldPosServer().RoundToInt();
            }

            //If the position is still hidden then the shard or the top pickupable is also hidden
            if (pos == TransformState.HiddenPos)
            {
                return;
            }

            //Cache pos so we dont try to get the metadata every update if we haven't moved
            if (pos != posCache)
            {
                metaDataNode = MatrixManager.GetMetaDataAt(pos);
                posCache     = pos;
            }

            if (metaDataNode == null)
            {
                return;
            }

            if (isHotIce == false && metaDataNode.GasMix.Temperature > AtmosDefines.WATER_VAPOR_FREEZE)
            {
                MeltIce(metaDataNode);
            }

            if (isHotIce && metaDataNode.GasMix.Temperature > 373.15)
            {
                MeltHotIce(metaDataNode);
            }
        }
Exemple #17
0
    /// <summary>
    /// Used to call a spray coming from the player, where position is the target, bottle is the ReagentContainer of the item,
    /// spray is the prefab to spray, and customCol and col are for if you want the spray to have custom colours.
    /// </summary>
    /// <param name="bottle"></param>
    /// <param name="position"></param>
    /// <param name="spray"></param>
    /// <param name="customCol"></param>
    /// <param name="col"></param>
    /// <returns></returns>
    public static IEnumerator TriggerSpray(ReagentContainer bottle, Vector3 position, GameObject spray, bool customCol = false, Color col = new Color())
    {
        //Work out direction from player for spray transformations
        int xDir = -(PlayerManager.PlayerScript.WorldPos.x - position.CutToInt().x);
        int yDir = -(PlayerManager.PlayerScript.WorldPos.y - position.CutToInt().y);

        //Create spray game objects
        GameObject SprayGO = PoolManager.PoolNetworkInstantiate(spray, PlayerManager.PlayerScript.WorldPos);
        GameObject SprayGO2;
        GameObject SprayGO3;

        if (Mathf.Abs(xDir) == Mathf.Abs(yDir))
        {
            SprayGO2 = PoolManager.PoolNetworkInstantiate(spray, PlayerManager.PlayerScript.WorldPos + new Vector3(-yDir, xDir));
            SprayGO3 = PoolManager.PoolNetworkInstantiate(spray, PlayerManager.PlayerScript.WorldPos + new Vector3(yDir, -xDir));
        }
        else
        {
            SprayGO2 = PoolManager.PoolNetworkInstantiate(spray, PlayerManager.PlayerScript.WorldPos + new Vector3(yDir, xDir));
            SprayGO3 = PoolManager.PoolNetworkInstantiate(spray, PlayerManager.PlayerScript.WorldPos + new Vector3(-yDir, -xDir));
        }
        SprayGO2.SetActive(false);
        SprayGO3.SetActive(false);

        bool   canSpray = false;
        string effect   = "";

        //Search for chemicals in container to determine effects of spray
        foreach (KeyValuePair <string, float> Chemical in bottle.Contents)
        {
            if (Chemical.Key == "cleaner")
            {
                if (Chemical.Value >= 5f)
                {
                    canSpray = true;
                    effect   = "cleaning";
                }
            }
            else if (Chemical.Key == "water")
            {
                if (Chemical.Value >= 5f)
                {
                    canSpray = true;
                    effect   = "extinguish";
                }
            }
            else
            {
                if (Chemical.Value >= 5f) //Still sprays if there are more than 5 of any liquid in container
                {
                    canSpray = true;
                }
            }
        }
        if (canSpray)
        {
            Transform spraySprite  = SprayGO.transform.GetChild(0);
            Transform spray2Sprite = SprayGO2.transform.GetChild(0);
            Transform spray3Sprite = SprayGO3.transform.GetChild(0);
            //For custom colours
            if (customCol)
            {
                spraySprite.gameObject.GetComponent <SpriteRenderer>().color  = col;
                spray2Sprite.gameObject.GetComponent <SpriteRenderer>().color = col;
                spray3Sprite.gameObject.GetComponent <SpriteRenderer>().color = col;
            }
            //For directions of spray
            if (xDir > 0)
            {
                spraySprite.Rotate(new Vector3(0, 0, 180));
                spray2Sprite.Rotate(new Vector3(0, 0, 180));
                spray3Sprite.Rotate(new Vector3(0, 0, 180));
            }
            else if (xDir == 0)
            {
                spraySprite.Rotate(new Vector3(0, 0, 90 * -yDir));
                spray2Sprite.Rotate(new Vector3(0, 0, 90 * -yDir));
                spray3Sprite.Rotate(new Vector3(0, 0, 90 * -yDir));
            }
            //Cleaning spray
            if (effect == "cleaning")
            {
                for (int j = 0; j < 3; j++)
                {
                    //Clean and move if no wall
                    CleanTile(position + new Vector3(j * xDir, j * yDir));
                    if (!(MatrixManager.GetMetaDataAt(SprayGO.transform.position.CutToInt() + new Vector3(xDir, yDir).CutToInt()).IsOccupied))
                    {
                        SprayGO.transform.Translate(new Vector3(xDir, yDir));
                    }
                    yield return(new WaitForSecondsRealtime(0.5f));
                }
            }
            //Extinguishing spray
            else if (effect == "extinguish")
            {
                SprayGO2.SetActive(true);
                SprayGO3.SetActive(true);
                for (int j = 0; j < 3; j++)
                {
                    //Put out fire and move if no walls
                    ExtinguishTile(position + new Vector3(j * xDir, j * yDir));
                    ExtinguishTile(position + new Vector3((j * xDir) - yDir, (j * yDir) + xDir));
                    ExtinguishTile(position + new Vector3((j * xDir) + yDir, (j * yDir) - xDir));
                    if (!(MatrixManager.GetMetaDataAt(SprayGO.transform.position.CutToInt() + new Vector3(xDir, yDir).CutToInt()).IsOccupied))
                    {
                        SprayGO.transform.Translate(new Vector3(xDir, yDir));
                    }
                    if (!(MatrixManager.GetMetaDataAt(SprayGO2.transform.position.CutToInt() + new Vector3(xDir, yDir).CutToInt()).IsOccupied))
                    {
                        SprayGO2.transform.Translate(new Vector3(xDir, yDir));
                    }
                    if (!(MatrixManager.GetMetaDataAt(SprayGO3.transform.position.CutToInt() + new Vector3(xDir, yDir).CutToInt()).IsOccupied))
                    {
                        SprayGO3.transform.Translate(new Vector3(xDir, yDir));
                    }
                    yield return(new WaitForSecondsRealtime(0.5f));
                }
            }
            else
            {
                for (int j = 0; j < 3; j++)
                {
                    //Move if no walls
                    if (!(MatrixManager.GetMetaDataAt(SprayGO.transform.position.CutToInt() + new Vector3(xDir, yDir).CutToInt()).IsOccupied))
                    {
                        SprayGO.transform.Translate(new Vector3(xDir, yDir));
                    }
                    SprayGO.transform.Translate(new Vector3(xDir, yDir));
                    yield return(new WaitForSecondsRealtime(0.5f));
                }
            }
            //Destroy spray objects after 3 moves
            GameObject.Destroy(SprayGO);
            GameObject.Destroy(SprayGO2);
            GameObject.Destroy(SprayGO3);
        }
    }