public void Notify_ConnectorAdded(CompGas comp)
        {
            Log.Debug($"adding connector for '{comp.parent.Label}'");

            // sanity check; does this comp already exist?
            if (GasNetworks.Any(n => n.connectors.Contains(comp)) || comp.Network != null)
            {
                Log.Error($"adding gas comp that is already in a network: {comp.parent.Label}");
            }

            // check if it has neighbours that are in a Network.
            var neighbours    = comp.GetAdjacentGasComps(true);
            var neighbourNets = neighbours.Select(g => g.Network)
                                .Distinct()
                                .Where(n => n != null);

            // if 1, add
            if (neighbourNets.Count() == 1)
            {
                neighbourNets.First().Register(comp);
            }
            else
            {
                // if multiple, destroy
                foreach (var neighbourNet in neighbourNets)
                {
                    DestroyGasNet(neighbourNet);
                }

                // (re)create network(s)
                CreateGasNetworks(neighbours);
            }
        }
 public static List <CompGas> GetAdjacentGasComps(this CompGas gas, bool includeSelf = false)
 {
     if (gas.parent.Map == null)
     {
         Log.Error(
             $"cannot get map for {gas.parent.Label}, it is {( gas.parent.Spawned ? "" : "NOT" )} spawned.");
     }
     return(GetAdjacentGasComps(gas, gas.parent.Map, includeSelf));
 }
        public GasNet CreateGasNetFrom(CompGas root, out HashSet <CompGas> seen)
        {
            // set up vars
            var queue   = new Queue <CompGas>();
            var network = new HashSet <CompGas>();

            seen = new HashSet <CompGas>();

            // sanity checks
            if (root == null)
            {
                throw new ArgumentNullException(nameof(root), $"tried to create gas net from null root");
            }

            // if this itself does not allow flow, create network from single comp.
            if (!root.TransmitsGasNow)
            {
                seen.Add(root);
                return(new GasNet(new[] { root }, map));
            }

            // basic flood fill. Start somewhere, put all neighbours on a queue,
            // continue until there are no more neighbours.
            queue.Enqueue(root);
            seen.Add(root);
            while (queue.Count > 0)
            {
                var cur = queue.Dequeue();
                // sanity check; is this already in a network?
                if (cur.Network != null)
                {
                    Log.Error($"trying to add {cur.parent.Label} to a new network while it still has a network");
                }

                network.Add(cur);

                // check neighbours, add to queue if eligible
                foreach (var neighbour in cur.GetAdjacentGasComps())
                {
                    if (!seen.Contains(neighbour))
                    {
                        seen.Add(neighbour);
                        if (!neighbour.TransmitsGasNow)
                        {
                            continue;
                        }
                        queue.Enqueue(neighbour);
                    }
                }
            }

            return(new GasNet(network, map));
        }
        public static List <CompGas> GetAdjacentGasComps(this CompGas gas, Map map, bool includeSelf = false)
        {
            var cells = GenAdj.CellsAdjacentCardinal(gas.parent).ToList();

            if (includeSelf)
            {
                cells.AddRange(gas.parent.OccupiedRect().Cells);
            }
            return(cells.SelectMany(c => c.GetThingList(map))
                   .Distinct()
                   .TryGetComps <CompGas>()
                   .ToList());
        }
        public virtual void Register(CompGas comp)
        {
            connectors.Add(comp);
            if (comp is CompGasTrader trader)
            {
                traders.Add(trader);
            }
            if (comp is CompGasStorage storage)
            {
                storages.Add(storage);
            }
            comp.Network = this;

            foreach (var cell in comp.parent.OccupiedRect().Cells)
            {
                netGrid.Set(cell, true);
            }

#if DEBUG
            drawer.SetDirty();
#endif
        }
 public void Notify_ConnectorRemoved(CompGas comp)
 {
     DestroyGasNet(comp.Network);
     CreateGasNetworks(comp.GetAdjacentGasComps(map));
 }