示例#1
0
        public BulldozeAction()
        {
            HashSet <Instance> newSelection = new HashSet <Instance>(selection);
            HashSet <Instance> extraNodes   = new HashSet <Instance>();
            HashSet <ushort>   segments     = new HashSet <ushort>(); // Segments to be removed

            NetManager netManager = Singleton <NetManager> .instance;

            // Add any segments whose node is selected
            foreach (Instance instance in selection)
            {
                if (instance.isValid)
                {
                    if (instance.id.Type == InstanceType.NetSegment)
                    {
                        segments.Add(instance.id.NetSegment);
                    }
                    else if (instance.id.Type == InstanceType.NetNode)
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            ushort segment = netManager.m_nodes.m_buffer[instance.id.NetNode].GetSegment(i);
                            if (segment != 0)
                            {
                                InstanceID instanceID = default;
                                instanceID.NetSegment = segment;

                                if (selection.Contains(instanceID))
                                {
                                    continue;
                                }

                                newSelection.Add(new MoveableSegment(instanceID));
                                segments.Add(segment);
                            }
                        }
                    }
                    else if (instance.id.Type == InstanceType.Building)
                    {
                        Building building = (Building)((MoveableBuilding)instance).data;
                        ushort   nodeId   = building.m_netNode;

                        int c = 0;
                        while (nodeId != 0)
                        {
                            NetNode node = netManager.m_nodes.m_buffer[nodeId];

                            if (node.m_building == 0 || node.Info.m_class.m_layer == ItemClass.Layer.WaterPipes)
                            { // Exclude attached nodes with attached buildings (e.g. water buildings)
                                for (int i = 0; i < 8; i++)
                                {
                                    ushort segmentId = node.GetSegment(i);
                                    if (segmentId != 0 && MoveableSegment.isSegmentValid(segmentId) &&
                                        ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Untouchable) == NetSegment.Flags.None))
                                    {
                                        InstanceID instanceID = default;
                                        instanceID.NetSegment = segmentId;

                                        if (selection.Contains(instanceID))
                                        {
                                            continue;
                                        }

                                        newSelection.Add(new MoveableSegment(instanceID));
                                        segments.Add(segmentId);
                                    }
                                }
                            }

                            nodeId = node.m_nextBuildingNode;

                            if (++c > 32768)
                            {
                                CODebugBase <LogChannel> .Error(LogChannel.Core, "Nodes: Invalid list detected!\n" + Environment.StackTrace);

                                break;
                            }
                        }
                    }
                }
            }

            // Add any nodes whose segments are all selected
            foreach (Instance instance in newSelection)
            {
                if (instance.isValid)
                {
                    if (instance.id.Type == InstanceType.NetSegment)
                    {
                        ushort   segId   = instance.id.NetSegment;
                        ushort[] nodeIds = { netManager.m_segments.m_buffer[segId].m_startNode, netManager.m_segments.m_buffer[segId].m_endNode };
                        foreach (ushort id in nodeIds)
                        {
                            bool    toDelete = true;
                            NetNode node     = netManager.m_nodes.m_buffer[id];
                            for (int i = 0; i < 8; i++)
                            {
                                if (node.GetSegment(i) != 0 && !segments.Contains(node.GetSegment(i)))
                                {
                                    toDelete = false;
                                    break;
                                }
                            }
                            if (toDelete)
                            {
                                if (node.Info.m_class.m_layer == ItemClass.Layer.WaterPipes)
                                {
                                    foreach (Building b in BuildingManager.instance.m_buildings.m_buffer)
                                    {
                                        if (b.m_netNode == id)
                                        {
                                            toDelete = false;
                                            break;
                                        }
                                    }
                                }
                            }
                            if (toDelete)
                            {
                                InstanceID instanceId = default;
                                instanceId.NetNode = id;
                                MoveableNode mn = new MoveableNode(instanceId);
                                if (newSelection.Contains(mn))
                                {
                                    continue;
                                }

                                extraNodes.Add(mn);
                            }
                        }
                    }
                }
            }

            // Sort segments by buildIndex
            HashSet <Instance> sorted  = new HashSet <Instance>();
            List <uint>        indexes = new List <uint>();

            foreach (Instance instance in newSelection)
            {
                if (instance.id.Type != InstanceType.NetSegment)
                {
                    sorted.Add(instance);
                }
                else
                {
                    uint bi = ((NetSegment)instance.data).m_buildIndex;
                    if (!indexes.Contains(bi))
                    {
                        indexes.Add(bi);
                    }
                }
            }

            indexes.Sort();

            foreach (uint i in indexes)
            {
                foreach (Instance instance in newSelection)
                {
                    if (instance.id.Type == InstanceType.NetSegment)
                    {
                        if (((NetSegment)instance.data).m_buildIndex == i)
                        {
                            sorted.Add(instance);
                        }
                    }
                }
            }

            foreach (Instance instance in sorted)
            {
                m_states.Add(instance.SaveToState());
            }
            foreach (Instance instance in extraNodes)
            {
                m_states.Add(instance.SaveToState());
            }
        }
示例#2
0
        public BulldozeAction()
        {
            HashSet <Instance> newSelection = new HashSet <Instance>(selection);
            HashSet <Instance> extraNodes   = new HashSet <Instance>();
            HashSet <ushort>   segments     = new HashSet <ushort>(); // Segments to be removed

            //string msg = $"\nBasic Selection: {selection.Count}\n";

            // Add any segments whose node is selected
            foreach (Instance instance in selection)
            {
                if (instance.isValid)
                {
                    if (instance.id.Type == InstanceType.NetSegment)
                    {
                        segments.Add(instance.id.NetSegment);
                    }
                    else if (instance.id.Type == InstanceType.NetNode)
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            ushort segment = NetManager.instance.m_nodes.m_buffer[instance.id.NetNode].GetSegment(i);
                            if (segment != 0)
                            {
                                InstanceID instanceID = default(InstanceID);
                                instanceID.NetSegment = segment;

                                if (selection.Contains(instanceID))
                                {
                                    continue;
                                }

                                newSelection.Add(new MoveableSegment(instanceID));
                                segments.Add(segment);
                            }
                        }
                    }
                    else if (instance.id.Type == InstanceType.Building)
                    {
                        Building building = (Building)((MoveableBuilding)instance).data;
                        ushort   nodeId   = building.m_netNode;

                        int c = 0;
                        while (nodeId != 0)
                        {
                            NetNode node = NetManager.instance.m_nodes.m_buffer[nodeId];

                            for (int i = 0; i < 8; i++)
                            {
                                ushort segmentId = node.GetSegment(i);
                                if (segmentId != 0 && MoveableSegment.isSegmentValid(segmentId) &&
                                    ((NetManager.instance.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Untouchable) == NetSegment.Flags.None))
                                {
                                    InstanceID instanceID = default(InstanceID);
                                    instanceID.NetSegment = segmentId;

                                    if (selection.Contains(instanceID))
                                    {
                                        continue;
                                    }

                                    newSelection.Add(new MoveableSegment(instanceID));
                                    segments.Add(segmentId);
                                }
                            }

                            nodeId = node.m_nextBuildingNode;

                            if (++c > 32768)
                            {
                                CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                                break;
                            }
                        }
                    }
                }
            }

            //msg += $"Selection With Extra Segments: {newSelection.Count}\nTotal Segments: {segments.Count}\n";

            // Add any nodes whose segments are all selected
            foreach (Instance instance in newSelection)
            {
                if (instance.isValid)
                {
                    if (instance.id.Type == InstanceType.NetSegment)
                    {
                        ushort   segId   = instance.id.NetSegment;
                        ushort[] nodeIds = { NetManager.instance.m_segments.m_buffer[segId].m_startNode, NetManager.instance.m_segments.m_buffer[segId].m_endNode };
                        foreach (ushort id in nodeIds)
                        {
                            bool    toDelete = true;
                            NetNode node     = NetManager.instance.m_nodes.m_buffer[id];
                            for (int i = 0; i < 8; i++)
                            {
                                if (node.GetSegment(i) != 0 && !segments.Contains(node.GetSegment(i)))
                                {
                                    toDelete = false;
                                    break;
                                }
                            }
                            if (toDelete)
                            {
                                InstanceID instanceId = default(InstanceID);
                                instanceId.NetNode = id;
                                MoveableNode mn = new MoveableNode(instanceId);
                                if (newSelection.Contains(mn))
                                {
                                    continue;
                                }

                                extraNodes.Add(mn);
                            }
                        }
                    }
                }
            }

            foreach (Instance instance in newSelection)
            {
                m_states.Add(instance.GetState());
            }
            foreach (Instance instance in extraNodes)
            {
                m_states.Add(instance.GetState());
            }

            //Debug.Log(msg + $"Final Selection: {m_states.Count}");
        }