Esempio n. 1
0
    public void EmptyPipeContents()
    {
        int cell = Grid.PosToCell(base.transform.GetPosition());

        ConduitFlow.ConduitContents conduitContents = GetFlowManager().RemoveElement(cell, float.PositiveInfinity);
        elapsedTime = 0f;
        if (conduitContents.mass > 0f && conduitContents.element != SimHashes.Vacuum)
        {
            IChunkManager instance;
            switch (conduit.type)
            {
            case ConduitType.Gas:
                instance = GasSourceManager.Instance;
                break;

            case ConduitType.Liquid:
                instance = LiquidSourceManager.Instance;
                break;

            default:
                throw new ArgumentException();
            }
            instance.CreateChunk(conduitContents.element, conduitContents.mass, conduitContents.temperature, conduitContents.diseaseIdx, conduitContents.diseaseCount, Grid.CellToPosCCC(cell, Grid.SceneLayer.Ore));
        }
    }
    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);
                    }
                }
            }
        }
    }
Esempio n. 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);
        }
Esempio n. 4
0
        void InputPort2ConduitUpdate(float dt)
        {
            if (!this.Operational.IsOperational)
            {
                return;
            }

            var conduitMgr = this.GetConduitManager();

            var input2Content = conduitMgr.GetContents(InputPort2Cell);

            float massMoved = Mathf.Min(input2Content.mass, this.StorageRemainingCapacity);

            if (massMoved <= 0)
            {
                return;
            }

            ConduitFlow.ConduitContents conduitContents = conduitMgr.RemoveElement(this.InputPort2Cell, massMoved);


            int disease_count = (int)(input2Content.diseaseCount * (massMoved / input2Content.mass));

            switch (this.InputPort2ConduitType)
            {
            case ConduitType.Gas:
                this.Storage.AddGasChunk(input2Content.element, massMoved, input2Content.temperature, input2Content.diseaseIdx, disease_count, this.KeepZeroMassObject, false);
                break;

            case ConduitType.Liquid:
                this.Storage.AddLiquid(input2Content.element, massMoved, input2Content.temperature, input2Content.diseaseIdx, disease_count, this.KeepZeroMassObject, false);
                break;
            }
        }
Esempio n. 5
0
 protected override void UpdateVisualState(bool force = false)
 {
     if (wasOn != switchedOn || force)
     {
         wasOn = switchedOn;
         if (switchedOn)
         {
             animController.Play(ConduitSensor.ON_ANIMS, KAnim.PlayMode.Loop);
             int         cell        = Grid.PosToCell(this);
             ConduitFlow flowManager = Conduit.GetFlowManager(conduitType);
             ConduitFlow.ConduitContents contents = flowManager.GetContents(cell);
             Color32 c = Color.white;
             if (contents.diseaseIdx != 255)
             {
                 Disease disease = Db.Get().Diseases[contents.diseaseIdx];
                 c = disease.overlayColour;
             }
             animController.SetSymbolTint(TINT_SYMBOL, c);
         }
         else
         {
             animController.Play(ConduitSensor.OFF_ANIMS, KAnim.PlayMode.Once);
         }
     }
 }
Esempio n. 6
0
        protected virtual void OnConduitUpdate(float data)
        {
            if (!FlowMgr.HasConduit(this.InputCell) || !FlowMgr.HasConduit(this.OutputCell))
            {
            }
            else
            {
                ConduitFlow.Conduit         conduit  = FlowMgr.GetConduit(this.InputCell);
                ConduitFlow.ConduitContents contents = conduit.GetContents(FlowMgr);
                float massSrc = Mathf.Min(contents.mass, this.DesiredFlow);
                if (massSrc > 0)
                {
                    int disease_count = (int)((massSrc / contents.mass) * contents.diseaseCount);
                    var massMoved     = FlowMgr.AddElement(this.OutputCell, contents.element, massSrc, contents.temperature, contents.diseaseIdx, disease_count);
                    MassMoved += massMoved;
                    if (massMoved > 0)
                    {
                        FlowMgr.RemoveElement(this.InputCell, massMoved);

                        DesiredFlow -= massMoved;
                    }
                }
            }

            this.UpdateAnim();
        }
Esempio n. 7
0
 public void SetData(HandleVector <int> .Handle handle, ref ConduitFlow.ConduitContents contents)
 {
     if (handle.IsValid())
     {
         temperatures[Sim.GetHandleIndex(handle.index)] = contents.temperature;
         ConduitTemperatureManager_Set(handle.index, contents.temperature, contents.mass, (int)contents.element);
     }
 }
Esempio n. 8
0
            private static ConduitFlow.ConduitContents SetMaxFlow(ConduitFlow.ConduitContents contents, ConduitBridge bridge, ConduitFlow manager)
            {
                if (bridge.GetComponent <BuildingHP>().HitPoints == 0)
                {
                    //does not actually remove mass from the conduit, just changes what the bridge sees
                    contents.RemoveMass(contents.mass);
                    return(contents);
                }
                int        outputCell   = (int)bridgeOutputCell.GetValue(bridge);
                GameObject outputObject = Grid.Objects[outputCell, Integration.layers[(int)bridge.type]];

                if (outputObject == null)
                {
                    return(contents);
                }
                Pressurized pressure = bridge.GetComponent <Pressurized>();
                float       capacity;

                if (!Pressurized.IsDefault(pressure))
                {
                    capacity = pressure.Info.Capacity;
                }
                else
                {
                    capacity = (float)maxMass.GetValue(manager);
                }

                //If the ConduitBridge is not supposed to support the amount of fluid currently in the contents, only make the bridge's intended max visible
                //Also immediately deal damage if the current contents are higher than the intended max.
                if (capacity < contents.mass)
                {
                    float initial = contents.mass;
                    float removed = contents.RemoveMass(initial - capacity);
                    float ratio   = removed / initial;
                    contents.diseaseCount = (int)((float)contents.diseaseCount * ratio);
                    BuildingHP.DamageSourceInfo damage = Integration.GetPressureDamage();
                    bridge.Trigger((int)GameHashes.DoBuildingDamage, damage);
                }
                {
                    float       targetCapacity;
                    Pressurized outPressure = outputObject.GetComponent <Pressurized>();
                    if (!Pressurized.IsDefault(outPressure))
                    {
                        targetCapacity = outPressure.Info.Capacity;
                    }
                    else
                    {
                        targetCapacity = (float)maxMass.GetValue(manager);
                    }

                    if (contents.mass > targetCapacity * 2)
                    {
                        BuildingHP.DamageSourceInfo damage = Integration.GetPressureDamage();
                        outputObject.Trigger((int)GameHashes.DoBuildingDamage, damage);
                    }
                }
                return(contents);
            }
Esempio n. 9
0
        // Tries to request fluid for current requestor in specified list of Warp Gates
        // returns false when all providers are dry at the moment and no more fluid can be transfered in this channel
        private static bool RequestFluid(ValvesList warpGates)
        {
            var requestor = warpGates.getCurrentRequestor();
            var provider  = warpGates.getNextProvider();
            var start     = provider;

            if (null == provider || null == requestor)
            {
                return(false);
            }
            int toCell      = requestor.GetOutputCell();
            var flowManager = warpGates.FlowManager;

            // Fill input cell from various providers, in case when provider's conduit is not full
            do
            {
                int fromCell = provider.GetInputCell();
                if (provider != requestor)
                {
                    ConduitFlow.Conduit         providerConduit  = flowManager.GetConduit(fromCell);
                    ConduitFlow.ConduitContents providerContents = providerConduit.GetContents(flowManager);
                    if (!SimHashes.Vacuum.Equals(providerContents.element))
                    {
                        ConduitFlow.Conduit         requestorConduit  = flowManager.GetConduit(toCell);
                        ConduitFlow.ConduitContents requestorContents = requestorConduit.GetContents(flowManager);
#if DEBUG
                        Logger.LogFormat("Trying to move {0} kg. of {1} from {2} to {3}", providerContents.mass, providerContents.element, fromCell, toCell);
                        Logger.LogFormat("Requestor contents is: {0} kg. of {1}", requestorContents.mass, requestorContents.element);
#endif
                        if (requestorContents.mass < 1f && requestorContents.element != providerContents.element && requestorContents.element != SimHashes.Vacuum)
                        {
                            flowManager.RemoveElement(requestorConduit, requestorContents.mass);
                        }
                        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)
                        {
#if DEBUG
                            Logger.LogFormat("Moved {0} kg. from {1} to {2}", addedMass, fromCell, toCell);
#endif
                            ConduitFlow.ConduitContents removed = flowManager.RemoveElement(providerConduit, addedMass);
                            Game.Instance.accumulators.Accumulate(requestor.AccumulatorHandle, addedMass);
                        }
                    }
                }
                if (flowManager.IsConduitFull(toCell))
                {
                    return(true);
                }
                provider = warpGates.getNextProvider();
            } while (provider != start);
            return(false);
        }
    public void SetData(HandleVector <int> .Handle handle, ref ConduitFlow.ConduitContents contents)
    {
        Data data = GetData(handle);

        data.diseaseCount = contents.diseaseCount;
        if (contents.diseaseIdx != data.diseaseIdx)
        {
            data.diseaseIdx = contents.diseaseIdx;
            byte elem_idx = (byte)ElementLoader.GetElementIndex(contents.element);
            data.growthInfo = GetGrowthInfo(contents.diseaseIdx, elem_idx);
        }
        SetData(handle, data);
    }
Esempio n. 11
0
        private bool SetContents(int cell, ConduitType conduitType, Element element, float mass, float temperature, byte diseaseIdx, int diseaseCount)
        {
            if (conduitType == ConduitType.Solid)
            {
                var conduitFlow = Game.Instance.solidConduitFlow;
                if (!conduitFlow.HasConduit(cell))
                {
                    return(false);
                }

                mass = Mathf.Clamp(mass, 0, MAX_SOLID_MASS);
                var res = element.substance.SpawnResource(Vector3.zero, mass, temperature, diseaseIdx, diseaseCount);
                var pc  = res.GetComponent <Pickupable>();
                var p   = conduitFlow.RemovePickupable(cell);
                if (p != null)
                {
                    DestroyPickupable(p);
                }

                conduitFlow.SetContents(cell, pc);
                updateSolidFlowVisualization = true;
            }
            else
            {
                ConduitFlow conduitFlow = conduitType == ConduitType.Liqud
                    ? Game.Instance.liquidConduitFlow
                    : Game.Instance.gasConduitFlow;

                if (!conduitFlow.HasConduit(cell))
                {
                    return(false);
                }

                var maxMass = conduitType == ConduitType.Liqud ? MAX_LIQUID_MASS : MAX_GAS_MASS;
                mass = Mathf.Clamp(mass, 0, maxMass);

                var contents = new ConduitFlow.ConduitContents(element.id, mass, temperature, diseaseIdx, diseaseCount);
                conduitFlow.SetContents(cell, contents);

                if (conduitType == ConduitType.Liqud)
                {
                    updateLiquidFlowVisualization = true;
                }
                else
                {
                    updateGasFlowVisualization = true;
                }
            }

            return(true);
        }
Esempio n. 12
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);
    }
Esempio n. 13
0
    protected override void ConduitUpdate(float dt)
    {
        ConduitFlow flowManager = Conduit.GetFlowManager(conduitType);
        int         cell        = Grid.PosToCell(base.transform.GetPosition());

        ConduitFlow.ConduitContents contents = flowManager.GetContents(cell);
        if (base.IsSwitchedOn)
        {
            if (contents.element != desiredElement)
            {
                Toggle();
            }
        }
        else if (contents.element == desiredElement)
        {
            Toggle();
        }
    }
Esempio n. 14
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);
                }
            }
        }
    }
Esempio n. 15
0
            private static ConduitFlow.ConduitContents SetMaxFlow(ConduitFlow.ConduitContents contents, ConduitBridge bridge, ConduitFlow manager)
            {
                //If the bridge is broken, prevent the bridge from operating by limiting what it sees.
                if (bridge.GetComponent <BuildingHP>().HitPoints == 0)
                {
                    //does not actually remove mass from the conduit, just causes the bridge to assume there is no mass available to move.
                    contents.RemoveMass(contents.mass);
                    return(contents);
                }

                GameObject outputObject;
                int        outputCell     = (int)bridgeOutputCell.GetValue(bridge);
                float      targetCapacity = Integration.GetMaxCapacityWithObject(outputCell, bridge.type, out outputObject, false);

                if (outputObject == null)
                {
                    return(contents);
                }
                float capacity = Pressurized.GetMaxCapacity(bridge.GetComponent <Pressurized>());

                //If the ConduitBridge is not supposed to support the amount of fluid currently in the contents, only make the bridge's intended max visible
                //Also immediately deal damage if the current contents are higher than 110% of the intended max (110% is set because at 100%, a system with no pressurized pipes would seem to randomly deal damage as if the contents
                //  were barely over 100%
                if (contents.mass > capacity)
                {
                    if (contents.mass > capacity * 1.1)
                    {
                        Integration.DoPressureDamage(bridge.gameObject);
                    }

                    float initial = contents.mass;
                    float removed = contents.RemoveMass(initial - capacity);
                    float ratio   = removed / initial;
                    contents.diseaseCount = (int)((float)contents.diseaseCount * ratio);
                }


                if (contents.mass > targetCapacity * 2 && UnityEngine.Random.Range(0f, 1f) < 0.33f)
                {
                    Integration.DoPressureDamage(outputObject);
                }

                return(contents);
            }
    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);
    }
 static void Postfix(BuildingStatusItems __instance)
 {
     __instance.Pipe.resolveStringCallback = delegate(string str, object data)
     {
         Conduit obj   = (Conduit)data;
         int     cell2 = Grid.PosToCell(obj);
         ConduitFlow.ConduitContents contents2 = obj.GetFlowManager().GetContents(cell2);
         string text3 = BUILDING.STATUSITEMS.PIPECONTENTS.EMPTY;
         if (contents2.mass > 0f)
         {
             Element element3 = ElementLoader.FindElementByHash(contents2.element);
             text3 = string.Format(BUILDING.STATUSITEMS.PIPECONTENTS.CONTENTS, GameUtil.GetFormattedMass(contents2.mass), element3.name, GameUtil.GetFormattedTemperature(contents2.temperature));
             if (contents2.diseaseIdx != byte.MaxValue)
             {
                 text3 += string.Format(BUILDING.STATUSITEMS.PIPECONTENTS.CONTENTS_WITH_DISEASE, GameUtil.GetFormattedDisease(contents2.diseaseIdx, contents2.diseaseCount, color: true));
             }
         }
         str = str.Replace("{Contents}", text3);
         return(str);
     };
 }
Esempio n. 18
0
            private static ConduitFlow.ConduitContents OperationalValveOverPressure(ConduitFlow.ConduitContents contents, ValveBase valveBase, ConduitFlow flowManager)
            {
                OperationalValve op;

                if (op = valveBase as OperationalValve)
                {
                    if (op.CurrentFlow > 0f)
                    {
                        int        outputCell = (int)valveBaseOutputCell.GetValue(valveBase);
                        GameObject outputObject;
                        float      outputCapacity = Integration.GetMaxCapacityWithObject(outputCell, valveBase.conduitType, out outputObject);
                        float      inputMass      = contents.mass;
                        //If there is greater than 200% of the outputs capacity inside the shutoff valves input pipe, deal overpressure damage 33% of the time.
                        if (inputMass > (outputCapacity * 2) && UnityEngine.Random.Range(0f, 1f) < 0.33f)
                        {
                            Integration.DoPressureDamage(outputObject);
                        }
                    }
                }
                //since this patch consumed the contents variable on the stack, return the contents back to prevent issues with the next code statement in IL
                return(contents);
            }
Esempio n. 19
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);
    }
Esempio n. 20
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);
                    }
                }
            }
        }
Esempio n. 21
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();
            }
        }
Esempio n. 22
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();
            }
        }
Esempio n. 23
0
        protected override void ConduitTick(float delta)
        {
            if (!AlwaysConsume && !operational.IsOperational)
            {
                return;
            }
            IConduitFlow conduitFlow = GetConduitManager();

            if (ConduitType != ConduitType.Solid)
            {
                ConduitFlow mngr = conduitFlow as ConduitFlow;
                ConduitFlow.ConduitContents contents = mngr.GetContents(portCell);
                if (contents.mass <= 0)
                {
                    return;
                }
                Element element         = ElementLoader.FindElementByHash(contents.element);
                bool    matchesTag      = StoreTag == GameTags.Any || element.HasTag(StoreTag);
                float   rateAmount      = ConsumptionRate * delta;
                float   maxTake         = 0f;
                float   storageContains = storage.MassStored();
                float   storageLeft     = storage.capacityKg - storageContains;
                float   portContains    = StoreTag == GameTags.Any ? storageContains : storage.GetMassAvailable(StoreTag);
                float   portLeft        = MaximumStore - portContains;
                maxTake = Mathf.Min(storageLeft, portLeft);
                maxTake = Mathf.Min(rateAmount, maxTake);
                float removed = 0f;
                if (maxTake > 0f)
                {
                    ConduitFlow.ConduitContents removedContents = mngr.RemoveElement(portCell, maxTake);
                    removed             = removedContents.mass;
                    LastConsumedElement = removedContents.element;
                    float ratio = removed / contents.mass;
                    if (!matchesTag)
                    {
                        BuildingHP.DamageSourceInfo damage = new BuildingHP.DamageSourceInfo
                        {
                            damage    = 1,
                            source    = BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT,
                            popString = UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT
                        };
                        Trigger((int)GameHashes.DoBuildingDamage, damage);
                        if (WrongElement == WrongElementResult.Dump)
                        {
                            int buildingCell = Grid.PosToCell(_parent.transform.GetPosition());
                            SimMessages.AddRemoveSubstance(buildingCell, contents.element, CellEventLogger.Instance.ConduitConsumerWrongElement, removed, contents.temperature, contents.diseaseIdx, contents.diseaseIdx);
                            return;
                        }
                    }
                    if (ConduitType == ConduitType.Gas)
                    {
                        if (!element.IsGas)
                        {
                            Debug.LogWarning($"[MultIO] Gas input port attempted to consume non gass: {element.id.ToString()}");
                        }
                        else
                        {
                            storage.AddGasChunk(element.id, removed, contents.temperature, contents.diseaseIdx, contents.diseaseCount, KeepZeroMassObject, false);
                        }
                    }
                    else if (ConduitType == ConduitType.Liquid)
                    {
                        if (!element.IsLiquid)
                        {
                            Debug.LogWarning($"[MultIO] Liquid input port attempted to consume non liquid: {element.id.ToString()}");
                        }
                        else
                        {
                            storage.AddLiquid(element.id, removed, contents.temperature, contents.diseaseIdx, contents.diseaseCount, KeepZeroMassObject, false);
                        }
                    }
                }
            }
            else
            {
                SolidConduitFlow mngr = conduitFlow as SolidConduitFlow;
                SolidConduitFlow.ConduitContents contents = mngr.GetContents(portCell);
                if (contents.pickupableHandle.IsValid() && (AlwaysConsume || operational.IsOperational))
                {
                    float stored           = StoreTag == GameTags.Any ? storage.MassStored() : storage.GetMassAvailable(StoreTag);
                    float maxStorage       = Mathf.Min(storage.capacityKg, MaximumStore);
                    float availableStorage = Mathf.Max(0f, maxStorage - stored);
                    if (availableStorage > 0f)
                    {
                        Pickupable tmp        = mngr.GetPickupable(contents.pickupableHandle);
                        bool       matchesTag = StoreTag == GameTags.Any || tmp.HasTag(StoreTag);
                        if (matchesTag)
                        {
                            if (tmp.PrimaryElement.Mass <= stored || tmp.PrimaryElement.Mass > maxStorage)
                            {
                                Pickupable take = mngr.RemovePickupable(portCell);
                                if (take != null)
                                {
                                    storage.Store(take.gameObject, true);
                                }
                            }
                        }
                        else
                        {
                            Pickupable take = mngr.RemovePickupable(portCell);
                            take.transform.SetPosition(Grid.CellToPos(portCell));
                            //TODO: Add a PopFX. Likely will not do damage.
                        }
                    }
                }
            }
        }
    private void Consume(float dt, ConduitFlow conduit_mgr)
    {
        this.IsSatisfied = false;
        if (this.building.Def.CanMove)
        {
            this.utilityCell = this.GetInputCell();
        }
        if (!this.IsConnected)
        {
            return;
        }
        ConduitFlow.ConduitContents contents = conduit_mgr.GetContents(this.utilityCell);
        if ((double)contents.mass <= 0.0)
        {
            return;
        }
        this.IsSatisfied = true;
        if (!this.alwaysConsume && !this.operational.IsOperational)
        {
            return;
        }
        float delta = Mathf.Min(this.ConsumptionRate * dt, this.space_remaining_kg);
        float mass  = 0.0f;

        if ((double)delta > 0.0)
        {
            ConduitFlow.ConduitContents conduitContents = conduit_mgr.RemoveElement(this.utilityCell, delta);
            mass = conduitContents.mass;
            this.lastConsumedElement = conduitContents.element;
        }
        bool flag = ElementLoader.FindElementByHash(contents.element).HasTag(this.capacityTag);

        if ((double)mass > 0.0 && this.capacityTag != GameTags.Any && !flag)
        {
            this.Trigger(-794517298, (object)new BuildingHP.DamageSourceInfo()
            {
                damage    = 1,
                source    = (string)BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT,
                popString = (string)UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT
            });
        }
        if (flag || this.wrongElementResult == ConduitConsumer2.WrongElementResult.Store || (contents.element == SimHashes.Vacuum || this.capacityTag == GameTags.Any))
        {
            if ((double)mass <= 0.0)
            {
                return;
            }
            int     disease_count = (int)((double)contents.diseaseCount * ((double)mass / (double)contents.mass));
            Element elementByHash = ElementLoader.FindElementByHash(contents.element);
            switch (this.conduitType)
            {
            case ConduitType.Gas:
                if (elementByHash.IsGas)
                {
                    this.storage.AddGasChunk(contents.element, mass, contents.temperature, contents.diseaseIdx, disease_count, this.keepZeroMassObject, false);
                    break;
                }
                Debug.LogWarning((object)("Gas conduit consumer consuming non gas: " + elementByHash.id.ToString()));
                break;

            case ConduitType.Liquid:
                if (elementByHash.IsLiquid)
                {
                    this.storage.AddLiquid(contents.element, mass, contents.temperature, contents.diseaseIdx, disease_count, this.keepZeroMassObject, false);
                    break;
                }
                Debug.LogWarning((object)("Liquid conduit consumer consuming non liquid: " + elementByHash.id.ToString()));
                break;
            }
        }
        else
        {
            if ((double)mass <= 0.0 || this.wrongElementResult != ConduitConsumer2.WrongElementResult.Dump)
            {
                return;
            }
            int disease_count = (int)((double)contents.diseaseCount * ((double)mass / (double)contents.mass));
            SimMessages.AddRemoveSubstance(Grid.PosToCell(this.transform.GetPosition()), contents.element, CellEventLogger.Instance.ConduitConsumerWrongElement, mass, contents.temperature, contents.diseaseIdx, disease_count, true, -1);
        }
    }
 private void Consume(float dt, ConduitFlow conduit_mgr)
 {
     if (this.building.Def.CanMove)
     {
         this.utilityCell = this.GetInputCell();
     }
     if (this.IsConnected)
     {
         ConduitFlow.ConduitContents contents = conduit_mgr.GetContents(this.utilityCell);
         if (contents.mass > 0f)
         {
             this.IsSatisfied = true;
             if (this.alwaysConsume || this.operational.IsOperational)
             {
                 float num  = (!(this.capacityTag != GameTags.Any)) ? this.storage.MassStored() : this.storage.GetMassAvailable(this.capacityTag);
                 float b    = Mathf.Min(this.storage.RemainingCapacity(), this.capacityKG - num);
                 float num2 = this.ConsumptionRate * dt;
                 num2 = Mathf.Min(num2, b);
                 float num3 = 0f;
                 if (num2 > 0f)
                 {
                     num3 = conduit_mgr.RemoveElement(this.utilityCell, num2).mass;
                 }
                 Element element = ElementLoader.FindElementByHash(contents.element);
                 bool    flag    = element.HasTag(this.capacityTag);
                 if (num3 > 0f && this.capacityTag != GameTags.Any && !flag)
                 {
                     base.Trigger(-794517298, new BuildingHP.DamageSourceInfo
                     {
                         damage    = 1,
                         source    = BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT,
                         popString = UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT
                     });
                 }
                 if (flag || this.wrongElementResult == ConduitConsumer.WrongElementResult.Store || contents.element == SimHashes.Vacuum || this.capacityTag == GameTags.Any)
                 {
                     if (num3 > 0f)
                     {
                         int         disease_count = (int)((float)contents.diseaseCount * (num3 / contents.mass));
                         Element     element2      = ElementLoader.FindElementByHash(contents.element);
                         ConduitType conduitType   = this.conduitType;
                         if (conduitType != ConduitType.Liquid)
                         {
                             if (conduitType == ConduitType.Gas)
                             {
                                 if (element2.IsGas)
                                 {
                                     this.storage.AddGasChunk(contents.element, num3, contents.temperature, contents.diseaseIdx, disease_count, this.keepZeroMassObject, false);
                                 }
                                 else
                                 {
                                     global::Debug.LogWarning("Gas conduit consumer consuming non gas: " + element2.id.ToString());
                                 }
                             }
                         }
                         else if (element2.IsLiquid)
                         {
                             this.storage.AddLiquid(contents.element, num3, contents.temperature, contents.diseaseIdx, disease_count, this.keepZeroMassObject, false);
                         }
                         else
                         {
                             global::Debug.LogWarning("Liquid conduit consumer consuming non liquid: " + element2.id.ToString());
                         }
                     }
                 }
                 else if (num3 > 0f && this.wrongElementResult == ConduitConsumer.WrongElementResult.Dump)
                 {
                     int disease_count2 = (int)((float)contents.diseaseCount * (num3 / contents.mass));
                     int gameCell       = Grid.PosToCell(base.transform.GetPosition());
                     SimMessages.AddRemoveSubstance(gameCell, contents.element, CellEventLogger.Instance.ConduitConsumerWrongElement, num3, contents.temperature, contents.diseaseIdx, disease_count2, true, -1);
                 }
             }
         }
         else
         {
             this.IsSatisfied = false;
         }
     }
     else
     {
         this.IsSatisfied = false;
     }
 }
Esempio n. 26
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);
            }
        }
Esempio n. 27
0
        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);
        }
Esempio n. 28
0
        private static void PushFluid(List <ValveBaseExt> requesters, List <ValveBaseExt> providers)
        {
            foreach (var provider in providers)
            {
                if (!provider.isValidProvider())
                {
                    continue;
                }
                Logger.LogFormat("-----WarpSpaceManager.RequestFluid start for channel: {0}", provider.Channel);
                var flowManager = provider.FlowManager;
                int fromCell    = provider.ValveBase.GetInputCell();
                ConduitFlow.Conduit         providerConduit  = flowManager.GetConduit(fromCell);
                ConduitFlow.ConduitContents providerContents = providerConduit.GetContents(flowManager);
                if (SimHashes.Vacuum.Equals(providerContents.element))
                {
                    continue;
                }

                var matchedRequesters = requesters.Where(x => x.Channel == provider.Channel).ToList();
                if (matchedRequesters.Count == 0)
                {
                    continue;
                }
                var splitMass = providerContents.mass / matchedRequesters.Count();

                Logger.Log(String.Format("WarpSpaceManager.RequestFluid splitMass: {0}", splitMass));
                Logger.Log(String.Format("WarpSpaceManager.RequestFluid matchedRequesters: {0}", matchedRequesters.Count));
                foreach (var requester in matchedRequesters)
                {
                    if (!requester.isValidRequestor())
                    {
                        continue;
                    }
                    int toCell = requester.ValveBase.GetOutputCell();
                    ConduitFlow.Conduit         requestorConduit  = flowManager.GetConduit(toCell);
                    ConduitFlow.ConduitContents requestorContents = requestorConduit.GetContents(flowManager);

                    if (requestorContents.mass < 1f && requestorContents.element != providerContents.element && requestorContents.element != SimHashes.Vacuum)
                    {
                        Logger.LogFormat("Removing contents is: {0} kg. of {1}", requestorContents.mass, requestorContents.element);
                        flowManager.RemoveElement(requestorConduit, requestorContents.mass);
                    }

                    float addedMass = flowManager.AddElement(toCell, providerContents.element, splitMass, providerContents.temperature, providerContents.diseaseIdx, providerContents.diseaseCount);
                    Game.Instance.accumulators.Accumulate(provider.ValveBase.AccumulatorHandle, addedMass);
                    Logger.LogFormat($@"Requestor Info 
requester mass: {requestorContents.mass} requester element: {requestorContents.element}
provider mass: {providerContents.mass} provider element: {providerContents.element}
provider split: {splitMass} added mass: {addedMass}
\r\n ");
                    if (addedMass > 0f)
                    {
                        ConduitFlow.ConduitContents removed = flowManager.RemoveElement(providerConduit, addedMass);
                        Game.Instance.accumulators.Accumulate(requester.ValveBase.AccumulatorHandle, addedMass);
                        Logger.LogFormat("Moved {0} kg. from {1} to {2}. ", addedMass, fromCell, toCell);
                    }
                    else
                    {
                        Logger.Log(String.Format("WarpSpaceManager.RequestFluid No mass moved"));
                    }
                }

                Logger.LogFormat("-----WarpSpaceManager.RequestFluid end for channel: {0}", provider.Channel);
            }

            Logger.LogFormat("WarpSpaceManager.RequestFluid end");
        }
Esempio n. 29
0
    public HandleVector <int> .Handle Allocate(ConduitType conduit_type, int conduit_idx, HandleVector <int> .Handle conduit_structure_temperature_handle, ref ConduitFlow.ConduitContents contents)
    {
        StructureTemperaturePayload payload = GameComps.StructureTemperatures.GetPayload(conduit_structure_temperature_handle);
        Element     element = payload.primaryElement.Element;
        BuildingDef def     = payload.building.Def;
        float       conduit_heat_capacity        = def.MassForTemperatureModification * element.specificHeatCapacity;
        float       conduit_thermal_conductivity = element.thermalConductivity * def.ThermalConductivity;
        int         num = ConduitTemperatureManager_Add(contents.temperature, contents.mass, (int)contents.element, payload.simHandleCopy, conduit_heat_capacity, conduit_thermal_conductivity, def.ThermalConductivity < 1f);

        HandleVector <int> .Handle result = default(HandleVector <int> .Handle);
        result.index = num;
        int handleIndex = Sim.GetHandleIndex(num);

        if (handleIndex + 1 > temperatures.Length)
        {
            Array.Resize(ref temperatures, (handleIndex + 1) * 2);
            Array.Resize(ref conduitInfo, (handleIndex + 1) * 2);
        }
        temperatures[handleIndex] = contents.temperature;
        conduitInfo[handleIndex]  = new ConduitInfo
        {
            type = conduit_type,
            idx  = conduit_idx
        };
        return(result);
    }
        public void Run(RenderMeshContext context)
        {
            Element element = null;

            for (int i = start; i != end; i++)
            {
                ConduitFlow.Conduit         conduit         = context.outer.flowManager.soaInfo.GetConduit(context.visible_conduits[i]);
                ConduitFlow.ConduitFlowInfo lastFlowInfo    = conduit.GetLastFlowInfo(context.outer.flowManager);
                ConduitFlow.ConduitContents initialContents = conduit.GetInitialContents(context.outer.flowManager);
                if (lastFlowInfo.contents.mass > 0f)
                {
                    int      cell = conduit.GetCell(context.outer.flowManager);
                    int      cellFromDirection = ConduitFlow.GetCellFromDirection(cell, lastFlowInfo.direction);
                    Vector2I v               = Grid.CellToXY(cell);
                    Vector2I vector2I        = Grid.CellToXY(cellFromDirection);
                    Vector2  pos             = (cell != -1) ? Vector2.Lerp(new Vector2((float)v.x, (float)v.y), new Vector2((float)vector2I.x, (float)vector2I.y), context.lerp_percent) : ((Vector2)v);
                    Color32  cellTintColour  = context.outer.GetCellTintColour(cell);
                    Color32  cellTintColour2 = context.outer.GetCellTintColour(cellFromDirection);
                    Color32  color           = Color32.Lerp(cellTintColour, cellTintColour2, context.lerp_percent);
                    bool     highlight       = false;
                    if (context.outer.showContents)
                    {
                        if (lastFlowInfo.contents.mass >= initialContents.mass)
                        {
                            moving_balls.Add(new Ball(lastFlowInfo.direction, pos, color, context.outer.tuning.size, false, false));
                        }
                        if (element == null || lastFlowInfo.contents.element != element.id)
                        {
                            element = ElementLoader.FindElementByHash(lastFlowInfo.contents.element);
                        }
                    }
                    else
                    {
                        element = null;
                        int num = Grid.PosToCell(new Vector3(pos.x + GRID_OFFSET.x, pos.y + GRID_OFFSET.y, 0f));
                        highlight = (num == context.outer.highlightedCell);
                    }
                    Color32 contentsColor = context.outer.GetContentsColor(element, color);
                    float   num2          = 1f;
                    if (context.outer.showContents || lastFlowInfo.contents.mass < initialContents.mass)
                    {
                        num2 = context.outer.CalculateMassScale(lastFlowInfo.contents.mass);
                    }
                    moving_balls.Add(new Ball(lastFlowInfo.direction, pos, contentsColor, context.outer.tuning.size * num2, true, highlight));
                    moving_conduits.Add(conduit);
                }
                if (initialContents.mass > lastFlowInfo.contents.mass && initialContents.mass > 0f)
                {
                    int      cell2           = conduit.GetCell(context.outer.flowManager);
                    Vector2I v2              = Grid.CellToXY(cell2);
                    Vector2  pos2            = v2;
                    float    mass            = initialContents.mass - lastFlowInfo.contents.mass;
                    bool     highlight2      = false;
                    Color32  cellTintColour3 = context.outer.GetCellTintColour(cell2);
                    float    num3            = context.outer.CalculateMassScale(mass);
                    if (context.outer.showContents)
                    {
                        static_balls.Add(new Ball(ConduitFlow.FlowDirections.None, pos2, cellTintColour3, context.outer.tuning.size * num3, false, false));
                        if (element == null || initialContents.element != element.id)
                        {
                            element = ElementLoader.FindElementByHash(initialContents.element);
                        }
                    }
                    else
                    {
                        element    = null;
                        highlight2 = (cell2 == context.outer.highlightedCell);
                    }
                    Color32 contentsColor2 = context.outer.GetContentsColor(element, cellTintColour3);
                    static_balls.Add(new Ball(ConduitFlow.FlowDirections.None, pos2, contentsColor2, context.outer.tuning.size * num3, true, highlight2));
                }
            }
        }