示例#1
0
 public UndoMod()
 {
     ActionQueueItem.exceptionHandler = (a, e) => { InvalidateAll(); return(false); };
     Queue = new ActionQueue(ModInfo.sa_queueCapacity);
     WrappersDictionary         = new WrappersDictionary();
     WrappedBuilding.dictionary = WrappersDictionary;
 }
示例#2
0
        public MakeConnections(HashSet <ConnectionPoint> borderNodes, FastList <ushort> createdNodes, WrappersDictionary dictionary, ActionGroup actionGroup)
        {
            if (!UIWindow.instance.m_connectRoadsCheckBox.isChecked)
            {
                return;
            }

            if (borderNodes == null)
            {
                return;
            }

            _networkDictionary = dictionary;
            _actionGroup       = actionGroup;

            HashSet <ushort> filteredCreatedNodes = FilterCreatedNodes(createdNodes);
            // (Border nodes are already filtered)

            HashSet <ConnectionPoint> usedPoints = new HashSet <ConnectionPoint>();
            HashSet <ushort>          usedNodes  = new HashSet <ushort>();

            List <ConnectionPair> connectionPairs = new List <ConnectionPair>();

            /* For each pair of nodes we make an attempt to connect them */
            foreach (ushort node1 in filteredCreatedNodes)
            {
                foreach (ConnectionPoint cpoint in borderNodes)
                {
                    if (RankConnection(node1, cpoint, out int rank))
                    {
                        connectionPairs.Add(new ConnectionPair(node1, cpoint, rank));
                    }
                }
            }

            connectionPairs.Sort((a, b) => - a.rank.CompareTo(b.rank));

            foreach (var pair in connectionPairs)
            {
                if (!usedPoints.Contains(pair.point2) && !usedNodes.Contains(pair.node1))
                {
                    ushort     segment1    = NetUtil.GetFirstSegment(NetUtil.Node(pair.node1));
                    NetSegment netSegment1 = NetUtil.Segment(segment1);
                    Connect(pair.node1, pair.point2.Node, -netSegment1.GetDirection(pair.node1), pair.point2.Direction, pair.point2.NetInfo, !pair.point2.DirectionBool);

                    usedNodes.Add(pair.node1);
                    usedPoints.Add(pair.point2);
                }
            }
        }
示例#3
0
 public void InvalidateAll(bool error = true)
 {
     if (error)
     {
         Debug.LogWarning("Error: Invalidate all");
         Singleton <SimulationManager> .instance.AddAction(() => CleanGhostNodes());
     }
     Queue.Clear();
     WrappersDictionary.Clear();
     //Invalidator.Instance.Clear();
     Observing = false;
     ObservingOnlyBuildings = 0;
     Invalidated            = true;
 }
 public static void Prefix(BuildingInfo info)
 {
     if (!SmartIntersections.instance.Active)
     {
         return;
     }
     if (info.m_paths != null)
     {
         // ns start
         if (info.m_paths.Length > 0)
         {
             _networkDictionary = new WrappersDictionary();
             _actionGroup       = new ActionGroup("Build intersection");
             ReleaseCollidingSegments();
         }
         // ns end
     }
 }
示例#5
0
        public MakeConnections(HashSet <ConnectionPoint> borderNodes, FastList <ushort> createdNodes, WrappersDictionary dictionary, ActionGroup actionGroup)
        {
            if (!UIWindow.instance.m_connectRoadsCheckBox.isChecked)
            {
                return;
            }

            if (borderNodes == null)
            {
                return;
            }

            _networkDictionary = dictionary;
            _actionGroup       = actionGroup;

            HashSet <ushort> filteredCreatedNodes = FilterCreatedNodes(createdNodes);
            // (Border nodes are already filtered)

            HashSet <ConnectionPoint> connectedPrimaryPoints = new HashSet <ConnectionPoint>();

            /* For each pair of nodes we make an attempt to connect them */
            foreach (ushort node1 in filteredCreatedNodes)
            {
                foreach (ConnectionPoint cpoint in borderNodes)
                {
                    if (connectedPrimaryPoints.Contains(cpoint))
                    {
                        continue;
                    }

                    if (TryConnect(node1, cpoint))
                    {
                        connectedPrimaryPoints.Add(cpoint);
                        break;
                    }
                }
            }
        }
        public static bool LoadPaths(BuildingInfo info, ushort buildingID, ref Building data, float elevation)
        {
            if (info.m_paths != null)
            {
                // ns start
                if (info.m_paths.Length > 0)
                {
                    _networkDictionary = new WrappersDictionary();
                    _actionGroup       = new ActionGroup("Build intersection");
                    //Debug.Log("LoadPaths detour");
                    ReleaseCollidingSegments();
                }
                // ns end

                NetManager instance = Singleton <NetManager> .instance;
                instance.m_tempNodeBuffer.Clear();
                instance.m_tempSegmentBuffer.Clear();
                for (int i = 0; i < info.m_paths.Length; i++)
                {
                    BuildingInfo.PathInfo pathInfo = info.m_paths[i];
                    if (pathInfo.m_finalNetInfo != null && pathInfo.m_nodes != null && pathInfo.m_nodes.Length != 0)
                    {
                        Vector3 vector = data.CalculatePosition(pathInfo.m_nodes[0]);
                        bool    flag   = /*BuildingDecoration.*/ RequireFixedHeight(info, pathInfo.m_finalNetInfo, pathInfo.m_nodes[0]);
                        if (!flag)
                        {
                            vector.y = NetSegment.SampleTerrainHeight(pathInfo.m_finalNetInfo, vector, false, pathInfo.m_nodes[0].y + elevation);
                        }
                        Ray ray = new Ray(vector + new Vector3(0f, 8f, 0f), Vector3.down);
                        NetTool.ControlPoint controlPoint;
                        if (!FindConnectNode(instance.m_tempNodeBuffer, vector, pathInfo.m_finalNetInfo, out controlPoint))
                        {
                            if (NetTool.MakeControlPoint(ray, 16f, pathInfo.m_finalNetInfo, true, NetNode.Flags.Untouchable, NetSegment.Flags.Untouchable, Building.Flags.All, pathInfo.m_nodes[0].y + elevation - pathInfo.m_finalNetInfo.m_buildHeight, true, out controlPoint))
                            {
                                Vector3 vector2 = controlPoint.m_position - vector;
                                if (!flag)
                                {
                                    vector2.y = 0f;
                                }
                                float sqrMagnitude = vector2.sqrMagnitude;
                                if (sqrMagnitude > pathInfo.m_maxSnapDistance * pathInfo.m_maxSnapDistance)
                                {
                                    controlPoint.m_position  = vector;
                                    controlPoint.m_elevation = 0f;
                                    controlPoint.m_node      = 0;
                                    controlPoint.m_segment   = 0;
                                }
                                else
                                {
                                    controlPoint.m_position.y = vector.y;
                                }
                            }
                            else
                            {
                                controlPoint.m_position = vector;
                            }
                        }

                        // ns start

                        /*if (!instance.m_tempNodeBuffer.Contains(controlPoint.m_node))
                         * {
                         *  controlPoint.m_position = vector;
                         *  controlPoint.m_elevation = 0f;
                         *  controlPoint.m_node = 0;
                         *  controlPoint.m_segment = 0;
                         * }*/
                        // ns end

                        //CheckSplitSegmentAngle(ref controlPoint, instance.m_tempSegmentBuffer, borderNodes); // ns

                        ushort node;
                        ushort num2;
                        int    num3;
                        int    num4;
                        if (controlPoint.m_node != 0)
                        {
                            instance.m_tempNodeBuffer.Add(controlPoint.m_node);
                        }
                        else if (NetTool.CreateNode(pathInfo.m_finalNetInfo, controlPoint, controlPoint, controlPoint, NetTool.m_nodePositionsSimulation, 0, false, false, false, false, pathInfo.m_invertSegments, false, 0, out node, out num2, out num3, out num4) == ToolBase.ToolErrors.None)
                        {
                            instance.m_tempNodeBuffer.Add(node);
                            controlPoint.m_node = node;
                            if (pathInfo.m_forbidLaneConnection != null && pathInfo.m_forbidLaneConnection.Length > 0 && pathInfo.m_forbidLaneConnection[0])
                            {
                                NetNode[] buffer = instance.m_nodes.m_buffer;
                                ushort    num5   = node;
                                buffer[(int)num5].m_flags = (buffer[(int)num5].m_flags | NetNode.Flags.ForbidLaneConnection);
                            }
                            if (pathInfo.m_trafficLights != null && pathInfo.m_trafficLights.Length > 0)
                            {
                                /*BuildingDecoration.*/
                                TrafficLightsToFlags(pathInfo.m_trafficLights[0], ref instance.m_nodes.m_buffer[(int)node].m_flags);
                            }
                        }
                        for (int j = 1; j < pathInfo.m_nodes.Length; j++)
                        {
                            vector = data.CalculatePosition(pathInfo.m_nodes[j]);
                            bool flag2 = /*BuildingDecoration.*/ RequireFixedHeight(info, pathInfo.m_finalNetInfo, pathInfo.m_nodes[j]);
                            if (!flag2)
                            {
                                vector.y = NetSegment.SampleTerrainHeight(pathInfo.m_finalNetInfo, vector, false, pathInfo.m_nodes[j].y + elevation);
                            }
                            ray = new Ray(vector + new Vector3(0f, 8f, 0f), Vector3.down);
                            NetTool.ControlPoint controlPoint2;
                            if (!/*BuildingDecoration.*/ FindConnectNode(instance.m_tempNodeBuffer, vector, pathInfo.m_finalNetInfo, out controlPoint2))
                            {
                                if (NetTool.MakeControlPoint(ray, 16f, pathInfo.m_finalNetInfo, true, NetNode.Flags.Untouchable, NetSegment.Flags.Untouchable, Building.Flags.All, pathInfo.m_nodes[j].y + elevation - pathInfo.m_finalNetInfo.m_buildHeight, true, out controlPoint2))
                                {
                                    Vector3 vector3 = controlPoint2.m_position - vector;
                                    if (!flag2)
                                    {
                                        vector3.y = 0f;
                                    }
                                    float sqrMagnitude2 = vector3.sqrMagnitude;
                                    if (sqrMagnitude2 > pathInfo.m_maxSnapDistance * pathInfo.m_maxSnapDistance)
                                    {
                                        controlPoint2.m_position  = vector;
                                        controlPoint2.m_elevation = 0f;
                                        controlPoint2.m_node      = 0;
                                        controlPoint2.m_segment   = 0;
                                    }
                                    else
                                    {
                                        controlPoint2.m_position.y = vector.y;
                                    }
                                }
                                else
                                {
                                    controlPoint2.m_position = vector;
                                }
                            }
                            NetTool.ControlPoint middlePoint = controlPoint2;
                            if (pathInfo.m_curveTargets != null && pathInfo.m_curveTargets.Length >= j)
                            {
                                middlePoint.m_position = data.CalculatePosition(pathInfo.m_curveTargets[j - 1]);
                                if (!flag || !flag2)
                                {
                                    middlePoint.m_position.y = NetSegment.SampleTerrainHeight(pathInfo.m_finalNetInfo, middlePoint.m_position, false, pathInfo.m_curveTargets[j - 1].y + elevation);
                                }
                            }
                            else
                            {
                                middlePoint.m_position = (controlPoint.m_position + controlPoint2.m_position) * 0.5f;
                            }
                            middlePoint.m_direction   = VectorUtils.NormalizeXZ(middlePoint.m_position - controlPoint.m_position);
                            controlPoint2.m_direction = VectorUtils.NormalizeXZ(controlPoint2.m_position - middlePoint.m_position);
                            ushort num6;
                            ushort num7;
                            ushort num8;
                            int    num9;
                            int    num10;
                            if (NetTool.CreateNode(pathInfo.m_finalNetInfo, controlPoint, middlePoint, controlPoint2, NetTool.m_nodePositionsSimulation, 1, false, false, false, false, false, pathInfo.m_invertSegments, false, 0, out num6, out num7, out num8, out num9, out num10) == ToolBase.ToolErrors.None)
                            {
                                instance.m_tempNodeBuffer.Add(num7);
                                instance.m_tempSegmentBuffer.Add(num8);
                                controlPoint2.m_node = num7;
                                if (pathInfo.m_forbidLaneConnection != null && pathInfo.m_forbidLaneConnection.Length > j && pathInfo.m_forbidLaneConnection[j])
                                {
                                    NetNode[] buffer2 = instance.m_nodes.m_buffer;
                                    ushort    num11   = num7;
                                    buffer2[(int)num11].m_flags = (buffer2[(int)num11].m_flags | NetNode.Flags.ForbidLaneConnection);
                                }
                                if (pathInfo.m_trafficLights != null && pathInfo.m_trafficLights.Length > j)
                                {
                                    /*BuildingDecoration.*/
                                    TrafficLightsToFlags(pathInfo.m_trafficLights[j], ref instance.m_nodes.m_buffer[(int)num7].m_flags);
                                }
                                if (pathInfo.m_yieldSigns != null && pathInfo.m_yieldSigns.Length >= j * 2)
                                {
                                    if (pathInfo.m_yieldSigns[j * 2 - 2])
                                    {
                                        NetSegment[] buffer3 = instance.m_segments.m_buffer;
                                        ushort       num12   = num8;
                                        buffer3[(int)num12].m_flags = (buffer3[(int)num12].m_flags | NetSegment.Flags.YieldStart);
                                    }
                                    if (pathInfo.m_yieldSigns[j * 2 - 1])
                                    {
                                        NetSegment[] buffer4 = instance.m_segments.m_buffer;
                                        ushort       num13   = num8;
                                        buffer4[(int)num13].m_flags = (buffer4[(int)num13].m_flags | NetSegment.Flags.YieldEnd);
                                    }
                                }
                            }
                            controlPoint = controlPoint2;
                            flag         = flag2;
                        }
                    }
                }
                for (int k = 0; k < instance.m_tempNodeBuffer.m_size; k++)
                {
                    ushort num14 = instance.m_tempNodeBuffer.m_buffer[k];
                    if ((instance.m_nodes.m_buffer[(int)num14].m_flags & NetNode.Flags.Untouchable) == NetNode.Flags.None)
                    {
                        if (buildingID != 0)
                        {
                            if ((data.m_flags & Building.Flags.Active) == Building.Flags.None && instance.m_nodes.m_buffer[(int)num14].Info.m_canDisable)
                            {
                                NetNode[] buffer5 = instance.m_nodes.m_buffer;
                                ushort    num15   = num14;
                                buffer5[(int)num15].m_flags = (buffer5[(int)num15].m_flags | NetNode.Flags.Disabled);
                            }
                            NetNode[] buffer6 = instance.m_nodes.m_buffer;
                            ushort    num16   = num14;
                            buffer6[(int)num16].m_flags = (buffer6[(int)num16].m_flags | NetNode.Flags.Untouchable);
                            instance.UpdateNode(num14);
                            instance.m_nodes.m_buffer[(int)num14].m_nextBuildingNode = data.m_netNode;
                            data.m_netNode = num14;
                        }
                        else
                        {
                            instance.UpdateNode(num14);
                        }
                    }
                }
                for (int l = 0; l < instance.m_tempSegmentBuffer.m_size; l++)
                {
                    ushort num17 = instance.m_tempSegmentBuffer.m_buffer[l];
                    if ((instance.m_segments.m_buffer[(int)num17].m_flags & NetSegment.Flags.Untouchable) == NetSegment.Flags.None)
                    {
                        if (buildingID != 0)
                        {
                            NetSegment[] buffer7 = instance.m_segments.m_buffer;
                            ushort       num18   = num17;
                            buffer7[(int)num18].m_flags = (buffer7[(int)num18].m_flags | NetSegment.Flags.Untouchable);
                            instance.UpdateSegment(num17);
                        }
                        else
                        {
                            if ((Singleton <ToolManager> .instance.m_properties.m_mode & ItemClass.Availability.AssetEditor) != ItemClass.Availability.None)
                            {
                                NetInfo info2 = instance.m_segments.m_buffer[(int)num17].Info;
                                if ((info2.m_availableIn & ItemClass.Availability.AssetEditor) == ItemClass.Availability.None)
                                {
                                    NetSegment[] buffer8 = instance.m_segments.m_buffer;
                                    ushort       num19   = num17;
                                    buffer8[(int)num19].m_flags = (buffer8[(int)num19].m_flags | NetSegment.Flags.Untouchable);
                                }
                            }
                            instance.UpdateSegment(num17);
                        }
                    }
                }
                // ns start
                AfterIntersectionBuilt(info, instance.m_tempNodeBuffer, instance.m_tempSegmentBuffer);
                // ns end
                instance.m_tempNodeBuffer.Clear();
                instance.m_tempSegmentBuffer.Clear();
            }

            return(false); // ns
        }
示例#7
0
        public FinalConnector(NetInfo centerNodeNetInfo, EdgeIntersections2 edgeIntersections, Ellipse ellipse, bool insertControllingVertices)
        {
            intersections      = edgeIntersections?.Intersections ?? new List <RoundaboutNode>();
            actionGroupTMPE    = edgeIntersections?.ActionGroupTMPE ?? new ActionGroup("Set up TMPE");
            actionGroupRoads   = edgeIntersections?.ActionGroupRoads ?? new ActionGroup("Build roundabout");
            wrappersDictionary = edgeIntersections?.networkDictionary ?? new WrappersDictionary();

            this.ellipse = ellipse;
            pleasenoinfiniterecursion = 0;
            this.centerNodeNetInfo    = centerNodeNetInfo;
            leftHandTraffic           = Singleton <SimulationManager> .instance.m_metaData.m_invertTraffic ==
                                        SimulationMetaData.MetaBool.True;

            // We ensure that the segments are not too long. For circles only (with ellipses it would be more difficult)
            m_maxAngDistance = Math.Min(Math.PI * 25 / ellipse.RadiusMain, Math.PI / 2 + 0.1d);

            bool isCircle = ellipse.IsCircle();

            if (!isCircle && insertControllingVertices)
            {
                /* See doc in the method below */
                InsertIntermediateNodes();
            }

            /* If the list of edge nodes is empty, we add one default intersection. */
            if (isCircle && intersections.Count == 0)
            {
                Vector3 defaultIntersection = new Vector3(ellipse.RadiusMain, 0, 0) + ellipse.Center;
                //ushort newNodeId = NetAccess.CreateNode(centerNodeNetInfo, defaultIntersection);

                WrappedNode newNodeW = new WrappedNode();
                newNodeW.Position = defaultIntersection;
                newNodeW.NetInfo  = centerNodeNetInfo;
                RoundaboutNode raNode = new RoundaboutNode(newNodeW);
                raNode.Create(actionGroupRoads);
                intersections.Add(raNode);
            }

            int count = intersections.Count;

            foreach (RoundaboutNode item in intersections)
            {
                item.angle = Ellipse.VectorsAngle(item.wrappedNode.Position - ellipse.Center);
            }

            /* We sort the nodes according to their angles */
            intersections.Sort();

            /* Goes over all the nodes and conntets each of them to the angulary closest neighbour. (In a given direction) */

            for (int i = 0; i < count; i++)
            {
                RoundaboutNode prevNode = intersections[i];
                if (isCircle)
                {
                    prevNode = CheckAngularDistance(intersections[i], intersections[(i + 1) % count]);
                }
                ConnectNodes(intersections[(i + 1) % count], prevNode);
            }

            // Charge player
            var chargePlayerAction = new ChargePlayerAction(actionGroupRoads.DoCost(), centerNodeNetInfo.m_class);

            if (!chargePlayerAction.CheckMoney())
            {
                throw new PlayerException("Not enough money!");
            }

            actionGroupRoads.Actions.Add(chargePlayerAction);

            // Create
            ModThreading.PushAction(actionGroupRoads, actionGroupTMPE);
        }