示例#1
0
        public override Instance Clone(InstanceState instanceState, Dictionary <ushort, ushort> clonedNodes)
        {
            SegmentState state = instanceState as SegmentState;

            Instance cloneInstance = null;

            ushort startNode = state.startNode;
            ushort endNode   = state.endNode;

            // Nodes should exist
            startNode = clonedNodes[startNode];
            endNode   = clonedNodes[endNode];

            if (netManager.CreateSegment(out ushort clone, ref SimulationManager.instance.m_randomizer, state.Info.Prefab as NetInfo,
                                         startNode, endNode, state.startDirection, state.endDirection,
                                         SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex,
                                         state.invert))
            {
                SimulationManager.instance.m_currentBuildIndex++;

                InstanceID cloneID = default(InstanceID);
                cloneID.NetSegment = clone;
                cloneInstance      = new MoveableSegment(cloneID);
            }

            return(cloneInstance);
        }
示例#2
0
        public override Instance Clone(InstanceState instanceState, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain, Dictionary <ushort, ushort> clonedNodes)
        {
            SegmentState state = instanceState as SegmentState;

            Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center);

            Instance cloneInstance = null;

            ushort startNode = state.startNode;
            ushort endNode   = state.endNode;

            // Nodes should exist
            startNode = clonedNodes[startNode];
            endNode   = clonedNodes[endNode];

            Vector3 startDirection = newPosition - nodeBuffer[startNode].m_position;
            Vector3 endDirection   = newPosition - nodeBuffer[endNode].m_position;

            startDirection.y = 0;
            endDirection.y   = 0;

            startDirection.Normalize();
            endDirection.Normalize();

            if (netManager.CreateSegment(out ushort clone, ref SimulationManager.instance.m_randomizer, state.Info.Prefab as NetInfo,
                                         startNode, endNode, startDirection, endDirection,
                                         SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex,
                                         state.invert))
            {
                SimulationManager.instance.m_currentBuildIndex++;

                InstanceID cloneID = default(InstanceID);
                cloneID.NetSegment = clone;
                cloneInstance      = new MoveableSegment(cloneID);
            }

            return(cloneInstance);
        }
示例#3
0
        public override void Do()
        {
            if (MoveItTool.POProcessing > 0)
            {
                return;
            }

            MoveItTool.instance.m_lastInstance = null;
            m_clones                 = new HashSet <Instance>();
            m_origToCloneUpdate      = new Dictionary <Instance, Instance>();
            m_nodeOrigToClone        = new Dictionary <ushort, ushort>();
            m_stateToClone           = new Dictionary <InstanceState, Instance>();
            m_InstanceID_origToClone = new Dictionary <InstanceID, InstanceID>();

            matrix4x.SetTRS(center + moveDelta, Quaternion.AngleAxis(angleDelta * Mathf.Rad2Deg, Vector3.down), Vector3.one);

            // Clone nodes first
            foreach (InstanceState state in m_states)
            {
                if (state is NodeState)
                {
                    Instance clone = state.instance.Clone(state, ref matrix4x, moveDelta.y, angleDelta, center, followTerrain, m_nodeOrigToClone, this);

                    if (clone != null)
                    {
                        m_clones.Add(clone);
                        m_stateToClone.Add(state, clone);
                        m_InstanceID_origToClone.Add(state.instance.id, clone.id);
                        m_origToCloneUpdate.Add(state.instance.id, clone.id);
                        m_nodeOrigToClone.Add(state.instance.id.NetNode, clone.id.NetNode);
                    }
                }
            }

            // Clone everything else except PO
            foreach (InstanceState state in m_states)
            {
                if (!(state is NodeState || state is ProcState))
                {
                    Instance clone = state.instance.Clone(state, ref matrix4x, moveDelta.y, angleDelta, center, followTerrain, m_nodeOrigToClone, this);

                    if (clone == null)
                    {
                        Log.Debug($"Failed to clone {state}");
                        continue;
                    }

                    m_clones.Add(clone);
                    m_stateToClone.Add(state, clone);
                    m_InstanceID_origToClone.Add(state.instance.id, clone.id);
                    m_origToCloneUpdate.Add(state.instance.id, clone.id);
                    ;
                    if (state is SegmentState segmentState)
                    {
                        MoveItTool.NS.SetSegmentModifiers(clone.id.NetSegment, segmentState);
                        if (segmentState.LaneIDs != null)
                        {
                            // old version does not store lane ids
                            var clonedLaneIds = MoveableSegment.GetLaneIds(clone.id.NetSegment);
                            DebugUtils.AssertEq(clonedLaneIds.Count, segmentState.LaneIDs.Count, "clonedLaneIds.Count, segmentState.LaneIDs.Count");
                            for (int i = 0; i < clonedLaneIds.Count; ++i)
                            {
                                var lane0 = new InstanceID {
                                    NetLane = segmentState.LaneIDs[i]
                                };
                                var lane = new InstanceID {
                                    NetLane = clonedLaneIds[i]
                                };
                                // Log.Debug($"Mapping lane:{lane0.NetLane} to {lane.NetLane}");
                                m_InstanceID_origToClone.Add(lane0, lane);
                            }
                        }
                    }
                }
            }

            // Clone PO
            foreach (InstanceState state in m_states)
            {
                if (state is ProcState)
                {
                    _ = state.instance.Clone(state, ref matrix4x, moveDelta.y, angleDelta, center, followTerrain, m_nodeOrigToClone, this);
                }
            }

            if (m_origToClone != null)
            {
                Dictionary <Instance, Instance> toReplace = new Dictionary <Instance, Instance>();

                foreach (Instance key in m_origToClone.Keys)
                {
                    toReplace.Add(m_origToClone[key], m_origToCloneUpdate[key]);
                    DebugUtils.Log("To replace: " + m_origToClone[key].id.RawData + " -> " + m_origToCloneUpdate[key].id.RawData);
                }

                ActionQueue.instance.ReplaceInstancesForward(toReplace);
            }

            m_origToClone = m_origToCloneUpdate;

            // Select clones
            selection = m_clones;
            MoveItTool.m_debugPanel.UpdatePanel();

            UpdateArea(GetTotalBounds(false));
            try
            {
                MoveItTool.UpdatePillarMap();
            }
            catch (Exception e)
            {
                DebugUtils.Log("CloneActionBase.Do failed");
                DebugUtils.LogException(e);
            }
        }
示例#4
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());
            }
        }
示例#5
0
        public override void Do()
        {
            if (MoveItTool.POProcessing > 0)
            {
                return;
            }

            MoveItTool.instance.m_lastInstance = null;
            m_clones            = new HashSet <Instance>();
            m_origToCloneUpdate = new Dictionary <Instance, Instance>();
            m_nodeOrigToClone   = new Dictionary <ushort, ushort>();
            var stateToClone           = new Dictionary <InstanceState, Instance>();
            var InstanceID_origToClone = new Dictionary <InstanceID, InstanceID>();

            matrix4x.SetTRS(center + moveDelta, Quaternion.AngleAxis(angleDelta * Mathf.Rad2Deg, Vector3.down), Vector3.one);

            // Clone nodes first
            foreach (InstanceState state in m_states)
            {
                if (state is NodeState)
                {
                    Instance clone = state.instance.Clone(state, ref matrix4x, moveDelta.y, angleDelta, center, followTerrain, m_nodeOrigToClone, this);

                    if (clone != null)
                    {
                        m_clones.Add(clone);
                        stateToClone.Add(state, clone);
                        InstanceID_origToClone.Add(state.instance.id, clone.id);
                        m_origToCloneUpdate.Add(state.instance.id, clone.id);
                        m_nodeOrigToClone.Add(state.instance.id.NetNode, clone.id.NetNode);
                    }
                }
            }

            // Clone everything else except PO
            foreach (InstanceState state in m_states)
            {
                if (!(state is NodeState || state is ProcState))
                {
                    Instance clone = state.instance.Clone(state, ref matrix4x, moveDelta.y, angleDelta, center, followTerrain, m_nodeOrigToClone, this);

                    if (clone == null)
                    {
                        Debug.Log($"Failed to clone {state}");
                        continue;
                    }

                    m_clones.Add(clone);
                    stateToClone.Add(state, clone);
                    InstanceID_origToClone.Add(state.instance.id, clone.id);
                    m_origToCloneUpdate.Add(state.instance.id, clone.id);

                    if (state is SegmentState segmentState)
                    {
                        MoveItTool.NS.SetSegmentModifiers(clone.id.NetSegment, segmentState);
                        var clonedLaneIds = MoveableSegment.GetLaneIds(clone.id.NetSegment);
                        DebugUtils.AssertEq(clonedLaneIds.Count, segmentState.LaneIDs.Count, "clonedLaneIds.Count, segmentState.LaneIDs.Count");
                        for (int i = 0; i < clonedLaneIds.Count; ++i)
                        {
                            var lane0 = new InstanceID {
                                NetLane = segmentState.LaneIDs[i]
                            };
                            var lane = new InstanceID {
                                NetLane = clonedLaneIds[i]
                            };
                            // Debug.Log($"Mapping lane:{lane0.NetLane} to {lane.NetLane}");
                            InstanceID_origToClone.Add(lane0, lane);
                        }
                    }
                }
            }

            // Clone NodeController after segments have been added.
            foreach (var item in stateToClone)
            {
                if (item.Key is NodeState nodeState)
                {
                    Instance clone  = item.Value;
                    ushort   nodeID = clone.id.NetNode;
                    MoveItTool.NodeController.PasteNode(nodeID, nodeState);
                }
            }

            // Clone TMPE rules
            foreach (var state in m_states)
            {
                if (state is NodeState nodeState)
                {
                    MoveItTool.TMPE.Paste(nodeState.TMPE_NodeRecord, InstanceID_origToClone);
                }
                else if (state is SegmentState segmentState)
                {
                    MoveItTool.TMPE.Paste(segmentState.TMPE_SegmentRecord, InstanceID_origToClone);
                    MoveItTool.TMPE.Paste(segmentState.TMPE_SegmentStartRecord, InstanceID_origToClone);
                    MoveItTool.TMPE.Paste(segmentState.TMPE_SegmentEndRecord, InstanceID_origToClone);
                }
            }

            // Clone PO
            foreach (InstanceState state in m_states)
            {
                if (state is ProcState)
                {
                    Instance clone = state.instance.Clone(state, ref matrix4x, moveDelta.y, angleDelta, center, followTerrain, m_nodeOrigToClone, this);
                }
            }

            if (m_origToClone != null)
            {
                Dictionary <Instance, Instance> toReplace = new Dictionary <Instance, Instance>();

                foreach (Instance key in m_origToClone.Keys)
                {
                    toReplace.Add(m_origToClone[key], m_origToCloneUpdate[key]);
                    DebugUtils.Log("To replace: " + m_origToClone[key].id.RawData + " -> " + m_origToCloneUpdate[key].id.RawData);
                }

                ActionQueue.instance.ReplaceInstancesForward(toReplace);
            }

            m_origToClone = m_origToCloneUpdate;

            // Select clones
            selection = m_clones;
            MoveItTool.m_debugPanel.UpdatePanel();

            UpdateArea(GetTotalBounds(false));
        }
示例#6
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}");
        }