Esempio n. 1
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. 2
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);
        }
 private void AddAudioSource(ConduitFlow.Conduit conduit, Vector3 camera_pos)
 {
     using (new KProfiler.Region("AddAudioSource", null))
     {
         UtilityNetwork network = flowManager.GetNetwork(conduit);
         if (network != null)
         {
             Vector3 vector = Grid.CellToPosCCC(conduit.GetCell(flowManager), Grid.SceneLayer.Building);
             float   num    = Vector3.SqrMagnitude(vector - camera_pos);
             bool    flag   = false;
             for (int i = 0; i < audioInfo.Count; i++)
             {
                 AudioInfo value = audioInfo[i];
                 if (value.networkID == network.id)
                 {
                     if (num < value.distance)
                     {
                         value.distance = num;
                         value.position = vector;
                         audioInfo[i]   = value;
                     }
                     flag = true;
                     break;
                 }
             }
             if (!flag)
             {
                 AudioInfo item = default(AudioInfo);
                 item.networkID = network.id;
                 item.position  = vector;
                 item.distance  = num;
                 item.blobCount = 0;
                 audioInfo.Add(item);
             }
         }
     }
 }
Esempio n. 4
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();
            }
        }
        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));
                }
            }
        }
Esempio n. 6
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");
        }
        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);
        }