示例#1
0
 protected virtual void ConduitUpdate(float dt)
 {
     if (!SkipSetOperational)
     {
         this.operational.SetFlag(PortConduitDispenserBase.outputConduitFlag, this.IsConnected);
     }
     if (this.operational.IsOperational || this.alwaysDispense)
     {
         PrimaryElement primaryElement = this.FindSuitableElement();
         if (primaryElement != null)
         {
             primaryElement.KeepZeroMassObject = true;
             ConduitFlow conduitManager = this.GetConduitManager();
             float       num            = conduitManager.AddElement(this.utilityCell, primaryElement.ElementID, primaryElement.Mass, primaryElement.Temperature, primaryElement.DiseaseIdx, primaryElement.DiseaseCount);
             if (num > 0f)
             {
                 float num2 = num / primaryElement.Mass;
                 int   num3 = (int)(num2 * (float)primaryElement.DiseaseCount);
                 primaryElement.ModifyDiseaseCount(-num3, "CustomConduitDispenser.ConduitUpdate");
                 primaryElement.Mass -= num;
                 base.Trigger(-1697596308, primaryElement.gameObject);
             }
         }
     }
 }
    private void ConduitUpdate(float dt)
    {
        ConduitFlow flowManager = Conduit.GetFlowManager(portInfo.conduitType);

        if (flowManager.HasConduit(inputCell))
        {
            ConduitFlow.ConduitContents contents = flowManager.GetContents(inputCell);
            if (!(contents.mass <= 0f))
            {
                int cell = outputCell;
                ConduitFlow.ConduitContents contents2 = flowManager.GetContents(cell);
                if (contents2.mass > 0f)
                {
                    cell      = secondaryOutput.Cell;
                    contents2 = flowManager.GetContents(cell);
                }
                if (contents2.mass <= 0f)
                {
                    float num = flowManager.AddElement(cell, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount);
                    if (num > 0f)
                    {
                        flowManager.RemoveElement(inputCell, num);
                    }
                }
            }
        }
    }
示例#3
0
        public static bool Prefix(float dt, ValveBase __instance, float ___currentFlow, int ___outputCell, int ___inputCell, HandleVector <int> .Handle ___flowAccumulator)
        {
            ConduitFlow flowManager = Conduit.GetFlowManager(__instance.conduitType);

            if (!flowManager.HasConduit(___inputCell) || !flowManager.HasConduit(___outputCell))
            {
                __instance.UpdateAnim();
            }
            else
            {
                ConduitFlow.ConduitContents input_content  = flowManager.GetConduit(___inputCell).GetContents(flowManager);
                ConduitFlow.ConduitContents output_content = flowManager.GetConduit(___outputCell).GetContents(flowManager);

                float mass_input  = Mathf.Min(input_content.mass, ___currentFlow * dt);
                float mass_output = output_content.mass;

                float mass_limit = Mathf.Max(___currentFlow - mass_output, 0);  // mass on output cannot exceed flow setting
                mass_input = Mathf.Min(mass_input, mass_limit);                 // set new input mass

                if (mass_input > 0f)
                {
                    float disease_percent = mass_input / input_content.mass;
                    int   disease_count   = (int)(disease_percent * input_content.diseaseCount);
                    float mass_moved      = flowManager.AddElement(___outputCell, input_content.element, mass_input, input_content.temperature, input_content.diseaseIdx, disease_count);
                    Game.Instance.accumulators.Accumulate(___flowAccumulator, mass_moved);
                    if (mass_moved > 0f)
                    {
                        flowManager.RemoveElement(___inputCell, mass_moved);
                    }
                }
                __instance.UpdateAnim();
            }

            return(false);
        }
示例#4
0
    private void UpdateState(float dt)
    {
        bool value = consumer.IsSatisfied;

        envTemp   = 0f;
        cellCount = 0;
        if ((UnityEngine.Object)occupyArea != (UnityEngine.Object)null && (UnityEngine.Object)base.gameObject != (UnityEngine.Object)null)
        {
            occupyArea.TestArea(Grid.PosToCell(base.gameObject), this, UpdateStateCb);
            envTemp /= (float)cellCount;
        }
        lastEnvTemp = envTemp;
        List <GameObject> items = storage.items;

        for (int i = 0; i < items.Count; i++)
        {
            PrimaryElement component = items[i].GetComponent <PrimaryElement>();
            if (component.Mass > 0f && (!isLiquidConditioner || !component.Element.IsGas) && (isLiquidConditioner || !component.Element.IsLiquid))
            {
                value       = true;
                lastGasTemp = component.Temperature;
                float num = component.Temperature + temperatureDelta;
                if (num < 1f)
                {
                    num        = 1f;
                    lowTempLag = Mathf.Min(lowTempLag + dt / 5f, 1f);
                }
                else
                {
                    lowTempLag = Mathf.Min(lowTempLag - dt / 5f, 0f);
                }
                ConduitFlow conduitFlow = (!isLiquidConditioner) ? Game.Instance.gasConduitFlow : Game.Instance.liquidConduitFlow;
                float       num2        = conduitFlow.AddElement(cooledAirOutputCell, component.ElementID, component.Mass, num, component.DiseaseIdx, component.DiseaseCount);
                component.KeepZeroMassObject = true;
                float num3 = num2 / component.Mass;
                int   num4 = (int)((float)component.DiseaseCount * num3);
                component.Mass -= num2;
                component.ModifyDiseaseCount(-num4, "AirConditioner.UpdateState");
                float num5       = num - component.Temperature;
                float num6       = num5 * component.Element.specificHeatCapacity * num2;
                float display_dt = (!(lastSampleTime > 0f)) ? 1f : (Time.time - lastSampleTime);
                lastSampleTime = Time.time;
                GameComps.StructureTemperatures.ProduceEnergy(structureTemperature, 0f - num6, BUILDING.STATUSITEMS.OPERATINGENERGY.PIPECONTENTS_TRANSFER, display_dt);
                break;
            }
        }
        if (Time.time - lastSampleTime > 2f)
        {
            GameComps.StructureTemperatures.ProduceEnergy(structureTemperature, 0f, BUILDING.STATUSITEMS.OPERATINGENERGY.PIPECONTENTS_TRANSFER, Time.time - lastSampleTime);
            lastSampleTime = Time.time;
        }
        operational.SetActive(value, false);
        UpdateStatus();
    }
示例#5
0
    private void OnConduitTick(float dt)
    {
        bool value = false;

        if (this.operational.IsOperational)
        {
            ConduitFlow gasFlow = Conduit.GetFlowManager(this.portInfo.conduitType);

            ConduitFlow.ConduitContents contentsI1 = gasFlow.GetContents(this.inputCell1);
            ConduitFlow.ConduitContents contentsI2 = gasFlow.GetContents(this.inputCell2);

            //Debug.Log("contentsI1.mass: " + contentsI1.mass);
            //Debug.Log("contentsI2.mass: " + contentsI2.mass);

            //int num = (contents.element != this.filteredElem) ? this.outputCell : this.filteredCell;
            ConduitFlow.ConduitContents contentsO = gasFlow.GetContents(this.outputCell);

            if (contentsI1.element != SimHashes.Hydrogen || contentsI2.element != SimHashes.Oxygen)
            {
                base.Trigger((int)GameHashes.DoBuildingDamage, new BuildingHP.DamageSourceInfo
                {
                    damage    = 1,
                    source    = STRINGS.BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT,
                    popString = STRINGS.UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT
                });
                gasFlow.RemoveElement(this.inputCell1, 0.111999989f);
                gasFlow.RemoveElement(this.inputCell2, 0.888f);
            }
            else
            {
                if (contentsI1.mass > 0.111999989f &&
                    contentsI2.mass > 0.888f &&
                    contentsO.mass <= 0f)
                {
                    value = true;
                    //float num2 = flowManager.AddElement(num, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount);
                    float outputTemperature = contentsI1.temperature * 0.111999989f + contentsI2.temperature * 0.888f;
                    //Debug.Log("outputTemperature: " + outputTemperature);
                    ConduitFlow liquidFlow = Conduit.GetFlowManager(ConduitType.Liquid);
                    float       num2       = liquidFlow.AddElement(this.outputCell, SimHashes.Water, 1f, outputTemperature, contentsI1.diseaseIdx, 0);
                    if (num2 > 0f)
                    {
                        gasFlow.RemoveElement(this.inputCell1, 0.111999989f);
                        gasFlow.RemoveElement(this.inputCell2, 0.888f);
                    }
                }
            }
        }
        this.operational.SetActive(value, false);
    }
示例#6
0
    private void ConduitUpdate(float dt)
    {
        ConduitFlow flowManager = Conduit.GetFlowManager(type);

        if (flowManager.HasConduit(inputCell))
        {
            ConduitFlow.ConduitContents contents = flowManager.GetContents(inputCell);
            if (contents.mass > 0f)
            {
                float num = flowManager.AddElement(outputCell, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount);
                if (num > 0f)
                {
                    flowManager.RemoveElement(inputCell, num);
                    Game.Instance.accumulators.Accumulate(accumulator, contents.mass);
                }
            }
        }
    }
    private void OnConduitTick(float dt)
    {
        bool value = false;

        if (this.operational.IsOperational)
        {
            ConduitFlow flowManager = Conduit.GetFlowManager(this.portInfo.conduitType);

            ConduitFlow.ConduitContents contents = flowManager.GetContents(this.inputCell);
            //int num = (contents.element != this.filteredElem) ? this.outputCell : this.filteredCell;
            ConduitFlow.ConduitContents contentsO = flowManager.GetContents(this.outputCell);
            ConduitFlow.ConduitContents contents2 = flowManager.GetContents(this.sInputCell);
            if (contents.mass > 0.111999989f &&
                contents2.mass > 0.888f &&
                contentsO.mass <= 0f)
            {
                if (contents.element != SimHashes.Hydrogen || contents2.element != SimHashes.Oxygen)
                {
                    base.Trigger(-794517298, new BuildingHP.DamageSourceInfo
                    {
                        damage    = 1,
                        source    = STRINGS.BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT,
                        popString = STRINGS.UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT
                    });
                    flowManager.RemoveElement(this.inputCell, 0.111999989f);
                    flowManager.RemoveElement(this.sInputCell, 0.888f);
                }
                else
                {
                    value = true;
                    //float num2 = flowManager.AddElement(num, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount);
                    float num2 = flowManager.AddElement(this.outputCell, SimHashes.Steam, 1f, 523.15f, contents.diseaseIdx, 0);
                    if (num2 > 0f)
                    {
                        flowManager.RemoveElement(this.inputCell, 0.111999989f);
                        flowManager.RemoveElement(this.sInputCell, 0.888f);
                    }
                }
            }
        }
        this.operational.SetActive(value, false);
    }
示例#8
0
 private void ConduitUpdate(float dt)
 {
     operational.SetFlag(outputConduitFlag, IsConnected);
     if (operational.IsOperational || alwaysDispense)
     {
         PrimaryElement primaryElement = FindSuitableElement();
         if ((Object)primaryElement != (Object)null)
         {
             primaryElement.KeepZeroMassObject = true;
             ConduitFlow conduitManager = GetConduitManager();
             float       num            = conduitManager.AddElement(utilityCell, primaryElement.ElementID, primaryElement.Mass, primaryElement.Temperature, primaryElement.DiseaseIdx, primaryElement.DiseaseCount);
             if (num > 0f)
             {
                 float num2 = num / primaryElement.Mass;
                 int   num3 = (int)(num2 * (float)primaryElement.DiseaseCount);
                 primaryElement.ModifyDiseaseCount(-num3, "ConduitDispenser.ConduitUpdate");
                 primaryElement.Mass -= num;
                 Trigger(-1697596308, primaryElement.gameObject);
             }
         }
     }
 }
示例#9
0
    private void OnConduitTick(float dt)
    {
        bool value = false;

        UpdateConduitBlockedStatus();
        if (operational.IsOperational)
        {
            ConduitFlow flowManager = Conduit.GetFlowManager(portInfo.conduitType);
            ConduitFlow.ConduitContents contents = flowManager.GetContents(inputCell);
            int num = (contents.element != filteredElem) ? outputCell : filteredCell;
            ConduitFlow.ConduitContents contents2 = flowManager.GetContents(num);
            if (contents.mass > 0f && contents2.mass <= 0f)
            {
                value = true;
                float num2 = flowManager.AddElement(num, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount);
                if (num2 > 0f)
                {
                    flowManager.RemoveElement(inputCell, num2);
                }
            }
        }
        operational.SetActive(value, false);
    }
示例#10
0
        //Since our input/output ports are inert, we must define the behavior of the ports ourself.
        //float dt is the amount of time that has passed. typically not used as far as i am aware, likely always just 1 (1 second)
        private void OnConduitTick(float dt)
        {
            //The ConduitFlow task is an overarching flow manager for a specific conduit type. If our bridge is a liquid bridge, we will get the liquid manager.
            ConduitFlow flowManager = Conduit.GetFlowManager(conduitType);

            //If there is a pipe connected to the location of the input port, and a pipe connected to the location of the output port
            if (flowManager.HasConduit(inputPort.GetPortCell()) && flowManager.HasConduit(outputPort.GetPortCell()))
            {
                //Get the contents of the input pipe
                ConduitFlow.ConduitContents contents = flowManager.GetContents(inputPort.GetPortCell());
                if (contents.mass > 0f)
                {
                    //The AddElement method will attempt to move as much fluid from the input to the output as it can, and will return the amount successfully moved (if any).
                    //This method also handles things such as merging disease amounts and temperature based on how much is moved
                    float amountMOved = flowManager.AddElement(outputPort.GetPortCell(), contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount);
                    if (amountMOved > 0f)
                    {
                        //RemoveElement, similar to AddElement, automatically reduces the disease count (if any germs are present)
                        flowManager.RemoveElement(inputPort.GetPortCell(), amountMOved);
                    }
                }
            }
        }
示例#11
0
        private void ConduitUpdate(float dt)
        {
            ConduitFlow flowManager = Conduit.GetFlowManager(this.conduitType);

            if (!flowManager.HasConduit(this.inputCell) || !flowManager.HasConduit(this.outputCell))
            {
                this.UpdateAnim();
            }
            else
            {
                ConduitFlow.ConduitContents input_content  = flowManager.GetConduit(this.inputCell).GetContents(flowManager);
                ConduitFlow.ConduitContents output_content = flowManager.GetConduit(this.outputCell).GetContents(flowManager);

                float mass_input  = Mathf.Min(input_content.mass, this.CurrentFlow * dt);
                float mass_output = output_content.mass;

                if (limitPressure)
                {
                    float mass_limit = Mathf.Max(this.CurrentFlow - mass_output, 0);  // mass on output cannot exceed flow setting
                    mass_input = Mathf.Min(mass_input, mass_limit);                   // set new input mass
                }

                if (mass_input > 0f)
                {
                    float disease_percent = mass_input / input_content.mass;
                    int   disease_count   = (int)(disease_percent * input_content.diseaseCount);
                    float mass_moved      = flowManager.AddElement(this.outputCell, input_content.element, mass_input, input_content.temperature, input_content.diseaseIdx, disease_count);
                    Game.Instance.accumulators.Accumulate(this.flowAccumulator, mass_moved);
                    if (mass_moved > 0f)
                    {
                        flowManager.RemoveElement(this.inputCell, mass_moved);
                    }
                }
                this.UpdateAnim();
            }
        }
示例#12
0
        private void ConduitUpdate(float dt)
        {
            //If the building is broken, nothing normally stops it from operating!
            if (gameObject.GetComponent <BuildingHP>().HitPoints == 0)
            {
                return;
            }
            ConduitFlow manager = Conduit.GetFlowManager(valveBase.conduitType);

            ConduitFlow.Conduit inputConduit  = manager.GetConduit(InputCell);
            ConduitFlow.Conduit outputConduit = manager.GetConduit(OutputCell);
            if (!manager.HasConduit(InputCell) || !manager.HasConduit(OutputCell))
            {
                valveBase.UpdateAnim();
            }
            else
            {
                ConduitFlow.ConduitContents inputContents = inputConduit.GetContents(manager);
                if (!bufferMode)
                {
                    float     valveFlow = valveBase.CurrentFlow * dt;
                    float     maxFlow;
                    float     temp;
                    SimHashes element;
                    byte      diseaseIdx;
                    float     ratio;
                    int       disease_count;
                    bool      fromStorage = false;
                    Tag       storedTag   = Tag.Invalid;

                    if (!storage.IsEmpty())
                    {
                        //If there is still mass within the storage but we are not in buffer mode, take nothing in until the storage is emptied! (while still following the limit mode settings)
                        fromStorage = true;
                        GameObject     item          = storage.items.FirstOrDefault();
                        PrimaryElement storedPrimary = item.GetComponent <PrimaryElement>();
                        maxFlow       = Mathf.Min(valveFlow, storedPrimary.Mass);
                        element       = storedPrimary.ElementID;
                        temp          = storedPrimary.Temperature;
                        diseaseIdx    = storedPrimary.DiseaseIdx;
                        ratio         = maxFlow / storedPrimary.Mass;
                        disease_count = (int)(ratio * (float)storedPrimary.DiseaseCount);
                        storedTag     = storedPrimary.Element.tag;
                    }
                    else
                    {
                        maxFlow       = Mathf.Min(inputContents.mass, valveBase.CurrentFlow * dt);
                        element       = inputContents.element;
                        temp          = inputContents.temperature;
                        diseaseIdx    = inputContents.diseaseIdx;
                        ratio         = maxFlow / inputContents.mass;
                        disease_count = (int)(ratio * (float)inputContents.diseaseCount);
                    }

                    if (maxFlow > 0f)
                    {
                        float movableMass = manager.AddElement(OutputCell, element, maxFlow, temp, diseaseIdx, disease_count);
                        Game.Instance.accumulators.Accumulate(flowAccumulator, movableMass);
                        if (movableMass > 0f)
                        {
                            //If we took the mass from storage, make sure we use the right function
                            if (!fromStorage)
                            {
                                manager.RemoveElement(InputCell, movableMass);
                            }
                            else
                            {
                                storage.ConsumeIgnoringDisease(storedTag, movableMass);
                            }
                        }
                    }
                }
                else
                {
                    float      availableInput = inputContents.mass;
                    GameObject storedItem     = storage.items.FirstOrDefault();
                    Element    storedElement  = storedItem?.GetComponent <PrimaryElement>().Element;
                    float      storedMass     = storedItem != null?storedItem.GetComponent <PrimaryElement>().Mass : 0f;

                    float maxOutputCapacity = Integration.GetMaxCapacityAt(OutputCell, valveBase.conduitType);

                    //Override the set current flow if the output pipe cannot support a flow that large. This prevents the valve from storing, for example, 3KG, when it can only output 1KG at a time.
                    float minimumOutput = Mathf.Min(maxOutputCapacity, valveBase.CurrentFlow);
                    storage.capacityKg = maxOutputCapacity;

                    float movableToStorage = Mathf.Min(availableInput, storage.RemainingCapacity());
                    if (movableToStorage > 0f)
                    {
                        Element inputElement       = ElementLoader.FindElementByHash(inputContents.element);
                        float   ratio              = movableToStorage / inputContents.mass;
                        int     transferredDisease = (int)((float)inputContents.diseaseCount * ratio);
                        if (inputElement == storedElement || storedItem == null)
                        {
                            if (valveBase.conduitType == ConduitType.Gas)
                            {
                                storage.AddGasChunk(inputContents.element, movableToStorage, inputContents.temperature, inputContents.diseaseIdx, transferredDisease, false);
                            }
                            else
                            {
                                storage.AddLiquid(inputContents.element, movableToStorage, inputContents.temperature, inputContents.diseaseIdx, transferredDisease, false);
                            }
                            storedMass += movableToStorage;
                            if (storedItem == null)
                            {
                                storedElement = inputElement;
                            }
                        }
                        else
                        {
                            //The input has a different element than what is in storage! Deal damage and remove however much mass attempted to flow into the valve.
                            Trigger(-794517298, new BuildingHP.DamageSourceInfo
                            {
                                damage    = 1,
                                source    = STRINGS.BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT,
                                popString = STRINGS.UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT
                            });
                            SimMessages.AddRemoveSubstance(Grid.PosToCell(base.transform.GetPosition()), inputContents.element, CellEventLogger.Instance.ConduitConsumerWrongElement, movableToStorage, inputContents.temperature, inputContents.diseaseIdx, transferredDisease);
                        }
                        manager.RemoveElement(InputCell, movableToStorage);
                    }

                    ConduitFlow.ConduitContents outputContents = outputConduit.GetContents(manager);
                    float   initialOutputMass = outputContents.mass;
                    Element outputElement     = ElementLoader.FindElementByHash(outputContents.element);
                    //If we can create a packet of at least size CurrentFlow, including if we combined the valve's output into what is already in the output conduit
                    //Debug.Log($"[TogglableValve] InitialOut: {initialOutputMass}, StoredMass: {storedMass}, MinimumOutput: {minimumOutput}, MaxOutputCapacity: {maxOutputCapacity}, AvailableInput: {availableInput}, MovableToStorage: {movableToStorage}");
                    if (initialOutputMass + storedMass >= minimumOutput && (storedElement == outputElement || outputElement == null || outputElement.id == SimHashes.Vacuum))
                    {
                        float movableToOut = Mathf.Min(storedMass, maxOutputCapacity - initialOutputMass);
                        if (movableToOut > 0f)
                        {
                            PrimaryElement storedPrimary      = storage.items.FirstOrDefault()?.GetComponent <PrimaryElement>();
                            float          ratio              = movableToOut / storedMass;
                            int            transferredDisease = (int)((float)storedPrimary.DiseaseCount * ratio);
                            float          totalMovedOut      = manager.AddElement(OutputCell, storedPrimary.ElementID, storedMass, storedPrimary.Temperature, storedPrimary.DiseaseIdx, transferredDisease);
                            Game.Instance.accumulators.Accumulate(flowAccumulator, totalMovedOut);
                            if (totalMovedOut > 0f)
                            {
                                storage.ConsumeIgnoringDisease(storedPrimary.Element.tag, totalMovedOut);
                            }
                        }
                    }
                }
                valveBase.UpdateAnim();
            }
        }
        private void ConvertMass()
        {
            float             filterAmt = 0;
            List <GameObject> items     = this.storage.items;
            PrimaryElement    elem      = null;

            foreach (GameObject item in items)
            {
                elem = item.GetComponent <PrimaryElement>();
                if (elem.ElementID == SimHashes.BleachStone)
                {
                    filterAmt += elem.Mass;
                }
            }
            if (filterAmt <= 0)
            {
                return;
            }
            float       maxGerms      = Mathf.Min(GERMS_PER_KG * MAX_KG_PER_SEC, (int)(filterAmt * GERMS_PER_KG));
            float       removedAmount = 0;
            ConduitFlow flowManager   = Conduit.GetFlowManager(ConduitType.Liquid);

            if (!flowManager.HasConduit(inCell) || !flowManager.HasConduit(outCell))
            {
                return;
            }
            foreach (GameObject item in items)
            {
                elem = item.GetComponent <PrimaryElement>();
                if (elem.Element.IsLiquid)
                {
                    float mass    = Mathf.Min(10f, elem.Mass);
                    float disease = elem.DiseaseCount / elem.Mass * mass;
                    if (elem.DiseaseIdx == Byte.MaxValue)
                    {
                        disease = 0;
                    }
                    if (disease > maxGerms)
                    {
                        mass    = mass * maxGerms / disease;
                        disease = maxGerms;
                    }
                    float trueMass = flowManager.AddElement(outCell, elem.ElementID, mass, elem.Temperature, Byte.MaxValue, 0);
                    if (trueMass < mass)
                    {
                        disease = disease * trueMass / mass;
                        mass    = trueMass;
                    }
                    elem.Mass -= mass;
                    elem.ModifyDiseaseCount(-(int)disease, "");
                    removedAmount = disease;
                    Game.Instance.accumulators.Accumulate(fluidProcessedLastTick, mass);
                    if (mass > 0)
                    {
                        break;
                    }
                }
            }
            if (removedAmount > 0)
            {
                float removal = (float)removedAmount / GERMS_PER_KG;
                storage.ConsumeIgnoringDisease(ElementLoader.FindElementByHash(filterIn).tag, removal);
                Game.Instance.accumulators.Accumulate(filterConsumedLastTick, removal);
                if (EMIT_CHLORINE)
                {
                    float   addition      = (float)removedAmount / GERMS_PER_KG;
                    Element elementByHash = ElementLoader.FindElementByHash(filterOut);
                    Vector3 outVector3    = new Vector3(this.transform.GetPosition().x, this.transform.GetPosition().y, 0.0f);
                    int     outCell       = Grid.PosToCell(outVector3);
                    SimMessages.AddRemoveSubstance(outCell, filterOut, CellEventLogger.Instance.OxygenModifierSimUpdate, addition, 273.15f + 45f, Byte.MaxValue, 0);
                }
            }
            //TODO: find out what the nice name is
            this.storage.Trigger(-1697596308, (object)this.gameObject);
        }
示例#14
0
        public static void RequestFluidFromChannel(ValveBase requestor, int channelNo)
        {
            Logger.LogFormat("==Entry WarpSpaceManager.RequestFluidFromChannel(requestor={0}, channelNo={1})", requestor.GetInstanceID(), channelNo);
            try
            {
                ConduitFlow flowManager = null;
                if (requestor.conduitType == LiquidWarpConfig.CONDUIT_TYPE)
                {
                    flowManager = Conduit.GetFlowManager(ConduitType.Liquid);
                }
                else if (requestor.conduitType == GasWarpConfig.CONDUIT_TYPE)
                {
                    flowManager = Conduit.GetFlowManager(ConduitType.Gas);
                }
                else
                {
                    Logger.Log("unable to determine correct ConduitType.");
                    return;
                }

                ValveChannels channels = getChannelsForConduitType(requestor.conduitType);
                ValvesList    providers;

                if (!channels.TryGetValue(channelNo, out providers) || (providers.Count == 0))
                {
                    Logger.LogFormat("No providers for channel {0} found.", channelNo);
                    return;
                }

                ValveBase provider = providers.getNext();
                ValveBase start    = provider;
                if (null == provider)
                {
                    Logger.Log("You should never see this message! provider is null");
                    return;
                }
                int toCell = (int)valveBaseOutputCellFieldInfo.GetValue(requestor);
                ConduitFlow.ConduitContents requestorContents = flowManager.GetContents(toCell);
                // Fill input cell from various providers, in case when provider's conduit is not full
                do
                {
                    Logger.LogFormat("Trying to request from valveBase {0}", provider.GetInstanceID());
                    int fromCell = (int)valveBaseInputCellFieldInfo.GetValue(provider);
                    if (provider != requestor && flowManager.HasConduit(fromCell))
                    {
                        ConduitFlow.ConduitContents providerContents = flowManager.GetContents(fromCell);
                        float addedMass = flowManager.AddElement(toCell, providerContents.element, providerContents.mass, providerContents.temperature, providerContents.diseaseIdx, providerContents.diseaseCount);
                        Game.Instance.accumulators.Accumulate(provider.AccumulatorHandle, addedMass);
                        if (addedMass > 0f)
                        {
                            Logger.LogFormat("Adding Element to cell: requestor={0} provider={1} actually added mass={2}, element type={3}", requestor.GetInstanceID(), provider.GetInstanceID(), addedMass, providerContents.element);
                            flowManager.RemoveElement(fromCell, addedMass);
                            Game.Instance.accumulators.Accumulate(requestor.AccumulatorHandle, addedMass);
                        }
                    }
                    if (flowManager.IsConduitFull(toCell))
                    {
                        break;
                    }
                    provider = providers.getNext();
                } while (provider != start);
            }
            catch (Exception ex)
            {
                Logger.LogFormat("Exception in WarpSpaceManager.RequestFluidFromChannel: {0}\n{1}", ex.Message, ex.StackTrace);
            }
            Logger.Log("==Exit WarpSpaceManager.RequestFluidFromChannel");
        }
示例#15
0
        private void ConvertMass()
        {
            SimUtil.DiseaseInfo diseaseInfo = SimUtil.DiseaseInfo.Invalid;
            diseaseInfo.idx   = byte.MaxValue;
            diseaseInfo.count = 0;

            float speedMultiplier = GetSpeedMultiplier();

            // Accumulators
            float oxygenMass      = 0f;
            float hydrogenMass    = 0f;
            float bleachStoneMass = 0f;

            float totalConsumedAmount  = 0f;
            float waterConsumptionRate = Config.waterConsumptionRate * speedMultiplier;

            Tag dirtyWaterTag = SimHashes.DirtyWater.CreateTag();
            Tag saltWaterTag  = SimHashes.SaltWater.CreateTag();
            Tag brineTag      = SimHashes.Brine.CreateTag();

            bool isDirty = false;

            for (int i = 0; i < storage.items.Count; i++)
            {
                GameObject storageItem = storage.items[i];
                if (storageItem != null && storageItem.HasTag(GameTags.AnyWater))
                {
                    PrimaryElement element = storageItem.GetComponent <PrimaryElement>();

                    //element.KeepZeroMassObject = true;
                    float consumedAmount     = Mathf.Min(waterConsumptionRate, element.Mass);
                    float consumedPercentage = consumedAmount / element.Mass;

                    int diseaseCount = (int)(consumedPercentage * element.DiseaseCount);

                    element.Mass -= consumedAmount;
                    element.ModifyDiseaseCount(-diseaseCount, "IndustrialElectrolyzer.ConvertMass");

                    if (storageItem.HasTag(saltWaterTag))
                    {
                        // 93% H2O
                        oxygenMass   += consumedAmount * Config.saltWater2WaterRatio * Config.water2OxygenRatio;
                        hydrogenMass += consumedAmount * Config.saltWater2WaterRatio * Config.water2HydrogenRatio;
                        // 7% NaCl
                        bleachStoneMass += consumedAmount * Config.saltWater2SaltRatio * Config.salt2BleachStoneRatio;
                    }
                    else if (storageItem.HasTag(brineTag))
                    {
                        // 70% H2O
                        oxygenMass   += consumedAmount * Config.brine2WaterRatio * Config.water2OxygenRatio;
                        hydrogenMass += consumedAmount * Config.brine2WaterRatio * Config.water2HydrogenRatio;
                        // 30% NaCl
                        bleachStoneMass += consumedAmount * Config.brine2SaltRatio * Config.salt2BleachStoneRatio;
                    }
                    else
                    {
                        oxygenMass   += consumedAmount * Config.water2OxygenRatio;
                        hydrogenMass += consumedAmount * Config.water2HydrogenRatio;
                    }

                    totalConsumedAmount += consumedAmount;

                    if (storageItem.HasTag(dirtyWaterTag) && consumedAmount > EPSILON)
                    {
                        isDirty = true;
                    }

                    diseaseInfo = SimUtil.CalculateFinalDiseaseInfo(diseaseInfo.idx, diseaseInfo.count, element.DiseaseIdx, element.DiseaseCount);

                    waterConsumptionRate -= consumedAmount;
                    if (waterConsumptionRate <= 0f)
                    {
                        Debug.Assert(waterConsumptionRate <= 0f);
                        break;
                    }
                }
            }

            float temperature = GetComponent <PrimaryElement>().Temperature;

            if (onConvertMass != null && totalConsumedAmount > EPSILON)
            {
                onConvertMass(totalConsumedAmount);
            }

            ConduitFlow gasFlowManager = Conduit.GetFlowManager(portInfo.conduitType);

            SimHashes oxygenHash      = isDirty ? SimHashes.ContaminatedOxygen : SimHashes.Oxygen;
            float     oxygenGenerated = gasFlowManager.AddElement(oxygenOutputCell, oxygenHash, oxygenMass * speedMultiplier, Mathf.Max(Config.oxygenTemperature, temperature), diseaseInfo.idx, diseaseInfo.count / 2);

            ReportManager.Instance.ReportValue(ReportManager.ReportType.OxygenCreated, oxygenGenerated, gameObject.GetProperName());
            Game.Instance.accumulators.Accumulate(OxygenAccumulator, oxygenGenerated);

            float hydrogenGenerated = gasFlowManager.AddElement(hydrogenOutputCell, SimHashes.Hydrogen, hydrogenMass * speedMultiplier, Mathf.Max(Config.hydrogenTemperature, temperature), diseaseInfo.idx, diseaseInfo.count / 2);

            Game.Instance.accumulators.Accumulate(HydrogenAccumulator, hydrogenGenerated);

            if (bleachStoneMass > EPSILON)
            {
                Element bleachStone = ElementLoader.FindElementByHash(SimHashes.BleachStone);

                Vector3 position = building.GetRotatedOffset(new CellOffset(1, 0)).ToVector3() + new Vector3(.5f, .5f, .0f) + transform.position;
                UnityEngine.Debug.Log("[AE] transform is at " + transform.position);
                UnityEngine.Debug.Log("[AE] exit is at " + position);

                bleachStone.substance.SpawnResource(position, bleachStoneMass, temperature, diseaseInfo.idx, diseaseInfo.count);
            }

            storage.Trigger((int)GameHashes.OnStorageChange, gameObject);
        }
        public void UpdateState(float dt)
        {
            bool isSatisfied = this.consumer.IsSatisfied;

            this.envTemp   = 0f;
            this.cellCount = 0;
            if (this.occupyArea != null && base.gameObject != null)
            {
                this.occupyArea.TestArea(Grid.PosToCell(base.gameObject), this, AdvancedAirConditioner.UpdateStateCbDelegate);
                this.envTemp /= (float)this.cellCount;
            }
            _lastEnvTemp(this, this.envTemp);   //this.lastEnvTemp = this.envTemp;

            List <GameObject> items = this.storage.items;

            for (int i = 0; i < items.Count; i++)
            {
                PrimaryElement element = items[i].GetComponent <PrimaryElement>();
                if (element.Mass > 0f && (!isLiquidConditioner && element.Element.IsGas || isLiquidConditioner && element.Element.IsLiquid))
                {
                    isSatisfied = true;
                    _lastGasTemp(this, element.Temperature);    //this.lastGasTemp = storage.Temperature;

                    float temperatureNew = element.Temperature + this.temperatureDelta;
                    if (this.useTarget)
                    {
                        temperatureNew = this.targetTemperature;                 //#
                    }
                    if (temperatureNew < 1f)
                    {
                        temperatureNew  = 1f;
                        this.lowTempLag = Mathf.Min(this.lowTempLag + dt / 5f, 1f);
                    }
                    else
                    {
                        this.lowTempLag = Mathf.Min(this.lowTempLag - dt / 5f, 0f);
                    }
                    _lowTempLag(this, this.lowTempLag);

                    ConduitFlow conduit           = this.isLiquidConditioner ? Game.Instance.liquidConduitFlow : Game.Instance.gasConduitFlow;
                    float       mass_max          = element.Mass;
                    float       temperatureCooled = temperatureNew - element.Temperature;

                    if (this.useMassReduction)
                    {
                        // mass cannot be greater than the pipe size minus pipe content
                        //mass_max = Math.Min(mass_max, this.consumer.consumptionRate - conduit.GetContents(this.cooledAirOutputCell).mass);

                        // max of mass that could be moved with the DPUMax
                        float mass_DPU = this.DPUMax / (temperatureCooled * element.Element.specificHeatCapacity);
                        mass_max = Math.Min(mass_max, mass_DPU);
                    }

                    float mass_output = conduit.AddElement(this.cooledAirOutputCell, element.ElementID, mass_max, temperatureNew, element.DiseaseIdx, element.DiseaseCount);
                    element.KeepZeroMassObject = true;
                    float diseasePercent = mass_output / element.Mass;
                    int   diseaseCount   = (int)((float)element.DiseaseCount * diseasePercent);
                    element.Mass -= mass_output;
                    element.ModifyDiseaseCount(-diseaseCount, "AirConditioner.UpdateState");

                    float DPU_removed = temperatureCooled * element.Element.specificHeatCapacity * mass_output;
                    float display_dt  = (this.lastSampleTime > 0f) ? (Time.time - this.lastSampleTime) : 1f;
                    this.lastSampleTime = Time.time;
                    GameComps.StructureTemperatures.ProduceEnergy(this.structureTemperature, -DPU_removed, STRINGS.BUILDING.STATUSITEMS.OPERATINGENERGY.PIPECONTENTS_TRANSFER, display_dt);
                    break;
                }
            }
            if (Time.time - this.lastSampleTime > 2f)
            {
                GameComps.StructureTemperatures.ProduceEnergy(this.structureTemperature, 0f, STRINGS.BUILDING.STATUSITEMS.OPERATINGENERGY.PIPECONTENTS_TRANSFER, Time.time - this.lastSampleTime);
                this.lastSampleTime = Time.time;
            }
            this.operational.SetActive(isSatisfied, false);
            this.Trigger((int)GameHashes.ActiveChanged, this);  //this.UpdateStatus();
        }
        private static bool Prefix(ValveBase __instance, float dt)
        {
            Debug.Log(" === ValveBase.ConduitUpdate(" + dt + ") Prefix " + __instance.conduitType);
            if (__instance.conduitType != (ConduitType)100 && __instance.conduitType != (ConduitType)101)
            {
                return(true);
            }

            FieldInfo fi1 = AccessTools.Field(typeof(ValveBase), "inputCell");
            FieldInfo fi2 = AccessTools.Field(typeof(ValveBase), "outputCell");
            FieldInfo fi3 = AccessTools.Field(typeof(ValveBase), "flowAccumulator");

            //Debug.Log("ConduitUpdate " + dt);
            ConduitFlow flowManager = Conduit.GetFlowManager(__instance.conduitType);

            ConduitFlow.Conduit conduit = flowManager.GetConduit((int)fi1.GetValue(__instance));

            if (!flowManager.HasConduit((int)fi1.GetValue(__instance)) || !flowManager.HasConduit((int)fi2.GetValue(__instance)))
            {
                __instance.UpdateAnim();
            }

            if ((int)fi1.GetValue(__instance) > 0 && flowManager.HasConduit((int)fi1.GetValue(__instance)) &&
                ((int)fi2.GetValue(__instance) > 0 && !flowManager.HasConduit((int)fi2.GetValue(__instance))))
            {
                ConduitFlow.ConduitContents contents = conduit.GetContents(flowManager);
                //float num = Mathf.Min(contents.mass, this.currentFlow * dt);
                FieldInfo fi = AccessTools.Field(typeof(ValveBase), "currentFlow");
                //float num = Mathf.Min(contents.mass, (float)fi.GetValue(this) * dt);
                float num = Mathf.Min(contents.mass, 10f * dt);
                Debug.Log("ConduitUpdate " + num);
                if (num > 0f)
                {
                    float num2          = num / contents.mass;
                    int   disease_count = (int)(num2 * (float)contents.diseaseCount);
                    Debug.Log("List " + num);

                    LiquidWarpData.LiquidPackets.Add(new PacketData((int)__instance.conduitType, (float)fi.GetValue(__instance), (int)fi2.GetValue(__instance), contents.element, num, contents.temperature, contents.diseaseIdx, disease_count));

                    //float num3 = flowManager.AddElement(this.outputCell, contents.element, num, contents.temperature, contents.diseaseIdx, disease_count);
                    //Game.Instance.accumulators.Accumulate(this.flowAccumulator, num3);

                    //float num3 = Mathf.Min(num, 10f - contents.mass);
                    float num3 = num;
                    if (num3 > 0f)
                    {
                        flowManager.RemoveElement((int)fi1.GetValue(__instance), num3);
                    }
                }
                __instance.UpdateAnim();
                return(false);
            }


            if ((int)fi2.GetValue(__instance) > 0 && flowManager.HasConduit((int)fi2.GetValue(__instance)))
            {
                ConduitFlow.Conduit conduitO = flowManager.GetConduit((int)fi2.GetValue(__instance));
                FieldInfo           fi       = AccessTools.Field(typeof(ValveBase), "currentFlow");

                PacketData toRemove = null;

                foreach (PacketData packet in LiquidWarpData.LiquidPackets)
                {
                    Debug.Log("currentFlow = " + (float)fi.GetValue(__instance) + ", packet.currentFlow = " + packet.current_flow);
                    if ((float)fi.GetValue(__instance) == packet.current_flow &&
                        (int)__instance.conduitType == packet.content_type)
                    {
                        float num3 = flowManager.AddElement((int)fi2.GetValue(__instance), packet.element, packet.mass, packet.temperature, packet.disease_idx, packet.disease_count);
                        Debug.Log("Adding Element to pipe: " + packet.mass + "," + num3);
                        Game.Instance.accumulators.Accumulate((HandleVector <int> .Handle)fi3.GetValue(__instance), num3);
                        toRemove = packet;
                        break;
                    }
                }

                if (toRemove != null)
                {
                    LiquidWarpData.LiquidPackets.Remove(toRemove);
                    toRemove = null;
                }


                __instance.UpdateAnim();
                return(false);
            }

            return(false);
        }
示例#18
0
        private void ConduitUpdate(float dt)
        {
            ConduitFlow flowManager = Conduit.GetFlowManager(type);

            if (!flowManager.HasConduit(inputCell))
            {
                return;
            }

            if (IsOperational)
            {
                ConduitFlow.ConduitContents contents = flowManager.GetContents(inputCell);
                if (contents.mass <= 0.0)
                {
                    return;
                }

                ConduitFlow.ConduitContents contentOutput1 = flowManager.GetContents(outputCell);
                ConduitFlow.ConduitContents contentOutput2 = flowManager.GetContents(secondaryOutputCell);

                var maxMass  = Traverse.Create(flowManager).Field("MaxMass").GetValue <float>();                //type == ConduitType.Liquid ? 10f : 1f;
                var halfMass = contents.mass / 2f;

                var willFitInOutput1 = maxMass - contentOutput1.mass;
                var willFitInOutput2 = maxMass - contentOutput2.mass;

                float delta1 = 0;
                float delta2 = 0;

                if (Math.Abs(willFitInOutput1) < 0.001f && Math.Abs(willFitInOutput2) < 0.001f)
                {
                    //do nothing
                }
                else if (!flowManager.HasConduit(secondaryOutputCell))
                {
                    delta1 = flowManager.AddElement(outputCell, contents.element, contents.mass, contents.temperature,
                                                    contents.diseaseIdx, contents.diseaseCount);
                }
                else if (!flowManager.HasConduit(outputCell))
                {
                    delta2 = flowManager.AddElement(secondaryOutputCell, contents.element, contents.mass, contents.temperature,
                                                    contents.diseaseIdx, contents.diseaseCount);
                }
                else if (willFitInOutput1 >= halfMass && willFitInOutput2 >= halfMass)
                {
                    delta1 = flowManager.AddElement(outputCell, contents.element, halfMass, contents.temperature,
                                                    contents.diseaseIdx, contents.diseaseCount / 2);
                    delta2 = flowManager.AddElement(secondaryOutputCell, contents.element, halfMass, contents.temperature,
                                                    contents.diseaseIdx, contents.diseaseCount / 2);
                }
                else if (willFitInOutput1 < halfMass)
                {
                    var overflowOutput1 = halfMass - willFitInOutput1;
                    var ratio           = (halfMass - overflowOutput1) / halfMass;
                    delta1 = flowManager.AddElement(outputCell, contents.element, halfMass - overflowOutput1,
                                                    contents.temperature, contents.diseaseIdx, (int)((contents.diseaseCount / 2f) * ratio));
                    delta2 = flowManager.AddElement(secondaryOutputCell, contents.element, halfMass + overflowOutput1,
                                                    contents.temperature, contents.diseaseIdx, (int)((contents.diseaseCount / 2f) * (1f / ratio)));
                }
                else
                {
                    var overflowOutput2 = halfMass - willFitInOutput2;
                    var ratio           = (halfMass - overflowOutput2) / halfMass;
                    delta1 = flowManager.AddElement(secondaryOutputCell, contents.element, halfMass - overflowOutput2,
                                                    contents.temperature, contents.diseaseIdx, (int)((contents.diseaseCount / 2f) * ratio));
                    delta2 = flowManager.AddElement(outputCell, contents.element, halfMass + overflowOutput2,
                                                    contents.temperature, contents.diseaseIdx, (int)((contents.diseaseCount / 2f) * (1f / ratio)));
                }

                flowManager.RemoveElement(inputCell, delta1);
                flowManager.RemoveElement(inputCell, delta2);

                Game.Instance.accumulators.Accumulate(accumulator, contents.mass);
            }
        }
示例#19
0
        protected override void ConduitTick(float delta)
        {
            UpdateConduitBlockedStatus();
            bool dispensed = false;

            if (!operational.IsOperational && !AlwaysDispense)
            {
                return;
            }
            foreach (GameObject item in storage.items)
            {
                if (item.GetComponent <PrimaryElement>()?.Element.id == SimHashes.Water)
                {
                    item.AddOrGet <Pickupable>();
                }
            }
            PrimaryElement element = FindSuitableElement();

            if (element != null)
            {
                element.KeepZeroMassObject = true;
                IConduitFlow iConduitManager = GetConduitManager();
                if (iConduitManager == null)
                {
                    Debug.LogError($"[MultiIO] OutputPort.ConduitTick(): iConduitManager is null");
                }
                //Solid Conduits do not use the same kind of flow manager, so the code must be separated
                if (ConduitType == ConduitType.Solid)
                {
                    SolidConduitFlow solidManager = iConduitManager as SolidConduitFlow;
                    if (solidManager == null)
                    {
                        Debug.LogError($"[MultiIO] OutputPort.ConduitTick(): solidManager is null");
                    }
                    //Solid conveyor only needs to take elements with a Pikcupable component. The only difference between Water and Bottled Water is a Pikcupable component.
                    Pickupable pickup = element.gameObject.GetComponent <Pickupable>();
                    if (pickup == null)
                    {
                        return;
                    }
                    if (pickup.PrimaryElement.Mass > SolidOutputMax)
                    {
                        pickup = pickup.Take(SolidOutputMax);
                    }
                    solidManager.AddPickupable(portCell, pickup);
                    dispensed = true;
                }
                else if (ConduitType == ConduitType.Liquid || ConduitType == ConduitType.Gas)
                {
                    ConduitFlow conduitManager = iConduitManager as ConduitFlow;
                    if (conduitManager == null)
                    {
                        Debug.LogError($"[MutiIO] OutputPort.ConduitTick(): conduitManager is null");
                        return;
                    }
                    float amountMoved = conduitManager.AddElement(portCell, element.ElementID, element.Mass, element.Temperature, element.DiseaseIdx, element.DiseaseCount);
                    if (amountMoved > 0f)
                    {
                        float movedRatio   = amountMoved / element.Mass;
                        int   movedDisease = (int)(movedRatio * (float)element.DiseaseCount);
                        element.ModifyDiseaseCount(-movedDisease, "ConduitDispenser.ConduitUpdate");
                        element.Mass -= amountMoved;
                        _parent.Trigger((int)GameHashes.OnStorageChange, element.gameObject);
                        dispensed = true;
                    }
                }
            }
            isDispensing = dispensed;
        }