Esempio n. 1
0
        int RebuildSegment(int segmentIndex, NetInfo newPrefab, bool roadDirectionMatters, Vector3 directionPoint, Vector3 direction, ref ToolError error)
        {
            NetManager net = Singleton <NetManager> .instance;

            NetInfo prefab = net.m_segments.m_buffer[segmentIndex].Info;

            NetTool.ControlPoint startPoint;
            NetTool.ControlPoint middlePoint;
            NetTool.ControlPoint endPoint;
            GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);

            if (direction.magnitude > 0.0f)
            {
                float dot       = Vector3.Dot(direction.normalized, (endPoint.m_position - startPoint.m_position).normalized);
                float threshold = Mathf.Cos(Mathf.PI / 4);

                if (dot > -threshold && dot < threshold)
                {
                    return(0);
                }

                if (roadDirectionMatters)
                {
                    bool inverted = (net.m_segments.m_buffer[segmentIndex].m_flags & NetSegment.Flags.Invert) != 0;

                    if (Singleton <SimulationManager> .instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True)
                    {
                        inverted = !inverted; // roads need to be placed in the opposite direction with left-hand traffic
                    }

                    bool reverseDirection = inverted ? (dot > 0.0f) : (dot < -0.0f);

                    if (reverseDirection)
                    {
                        var tmp = startPoint;
                        startPoint = endPoint;
                        endPoint   = tmp;

                        startPoint.m_direction  = -startPoint.m_direction;
                        endPoint.m_direction    = -endPoint.m_direction;
                        middlePoint.m_direction = startPoint.m_direction;
                    }
                    else
                    {
                        if (prefab == newPrefab)
                        {
                            error = ToolError.SameDirection;
                            return(0);
                        }
                    }
                }
            }

            bool test      = false;
            bool visualize = false;
            bool autoFix   = true;
            bool needMoney = false;
            bool invert    = false;

            ushort node           = 0;
            ushort segment        = 0;
            int    cost           = 0;
            int    productionRate = 0;

            NetTool.CreateNode(newPrefab, startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000, test, visualize, autoFix, needMoney, invert, false, (ushort)0, out node, out segment, out cost, out productionRate);

            if (segment != 0)
            {
                if (newPrefab.m_class.m_service == ItemClass.Service.Road)
                {
                    Singleton <CoverageManager> .instance.CoverageUpdated(ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Level.None);
                }

                error = ToolError.None;
                return(segment);
            }

            return(0);
        }
Esempio n. 2
0
        void _OnBeforeSimulationTick()
        {
            if (toolMode == ToolMode.None)
            {
                return;
            }

            if (!mouseDown)
            {
                dragging = false;
                prevBuiltSegmentIndex = 0;
            }

            if (buildTool != null)
            {
                buildTool.isHoveringSegment = false;
                buildTool.toolMode          = toolMode;
                buildTool.ToolCursor        = netTool.m_upgradeCursor;
            }

            if (!mouseRayValid)
            {
                return;
            }

            ToolBase.RaycastInput raycastInput = new ToolBase.RaycastInput(mouseRay, mouseRayLength);
            raycastInput.m_netService         = raycastService;
            raycastInput.m_ignoreTerrain      = true;
            raycastInput.m_ignoreNodeFlags    = NetNode.Flags.All;
            raycastInput.m_ignoreSegmentFlags = NetSegment.Flags.Untouchable;

            ToolBase.RaycastOutput raycastOutput;
            if (BuildTool118.RayCast(raycastInput, out raycastOutput))
            {
                int segmentIndex = raycastOutput.m_netSegment;
                if (segmentIndex != 0)
                {
                    NetManager net           = Singleton <NetManager> .instance;
                    NetInfo    newRoadPrefab = null;

                    NetTool.ControlPoint startPoint;
                    NetTool.ControlPoint middlePoint;
                    NetTool.ControlPoint endPoint;

                    GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);

                    ushort node;
                    ushort outSegment;
                    int    cost;
                    int    productionRate;
                    // Check for out-of-area error and initialized collide arrays for visualization
                    ToolBase.ToolErrors errors = NetTool.CreateNode(net.m_segments.m_buffer[segmentIndex].Info,
                                                                    startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000,
                                                                    true, false, true, false, false, false, (ushort)0, out node, out outSegment, out cost, out productionRate);

                    if ((errors & ToolBase.ToolErrors.OutOfArea) != 0)
                    {
                        toolError = ToolError.OutOfArea;
                    }
                    else
                    {
                        if (mouseDown)
                        {
                            HandleMouseDrag(ref raycastOutput, ref toolError, false, ref newRoadPrefab, ref segmentIndex);

                            if (segmentIndex == prevBuiltSegmentIndex)
                            {
                                toolError = ToolError.AlreadyBuilt;
                            }
                        }
                        else
                        {
                            HandleMouseDrag(ref raycastOutput, ref toolError, true, ref newRoadPrefab, ref segmentIndex);
                        }
                    }

                    if (buildTool != null)
                    {
                        buildTool.segment           = net.m_segments.m_buffer[segmentIndex];
                        buildTool.segmentIndex      = segmentIndex;
                        buildTool.isHoveringSegment = toolError != ToolError.Unknown;
                        if (newRoadPrefab != null)
                        {
                            buildTool.newPrefab = newRoadPrefab;
                        }
                        GetSegmentControlPoints(segmentIndex, out buildTool.startPoint, out buildTool.middlePoint, out buildTool.endPoint);
                    }
                }
            }

            if (buildTool != null)
            {
                buildTool.toolError = toolError;
            }
        }
Esempio n. 3
0
        void HandleMouseDrag(ref ToolBase.RaycastOutput raycastOutput, ref ToolError error, bool test, ref NetInfo newRoadPrefab, ref int newSegmentIndex)
        {
            Vector3 hitPosDelta = Vector3.zero;

            if (!test)
            {
                if (currentTime - prevRebuildTime < 0.1f)
                {
                    return;
                }

                if (dragging)
                {
                    hitPosDelta = raycastOutput.m_hitPos - prevHitPos;
                    if (hitPosDelta.magnitude < 12.0f)
                    {
                        return;
                    }
                }
                else
                {
                    prevHitPos = raycastOutput.m_hitPos;
                    dragging   = true;
                    if (toolMode == ToolMode.Oneway)
                    {
                        return;
                    }
                }

                prevHitPos = raycastOutput.m_hitPos;
            }

            int segmentIndex = raycastOutput.m_netSegment;

            if (segmentIndex != 0)
            {
                NetManager net    = Singleton <NetManager> .instance;
                NetInfo    prefab = net.m_segments.m_buffer[segmentIndex].Info;

                bool isOneway = !prefab.m_hasForwardVehicleLanes || !prefab.m_hasBackwardVehicleLanes;


                string prefabName = null;
                if (!roadPrefabNames.TryGetValue(prefab.GetInstanceID(), out prefabName) || prefabName == null)
                {
                    ModDebug.Error("Prefab name not found");
                    error = ToolError.Unknown;
                    return;
                }

                string newPrefabName = null;
                if (toolMode == ToolMode.Oneway)
                {
                    if (!isOneway)
                    {
                        newPrefabName = FindMatchingName(prefabName, twowayNames, onewayNames);
                    }
                    else
                    {
                        newPrefabName = prefabName;
                    }
                }
                else
                {
                    if (isOneway)
                    {
                        newPrefabName = FindMatchingName(prefabName, onewayNames, twowayNames);
                    }
                    else
                    {
                        toolError = ToolError.AlreadyTwoway;
                        return;
                    }
                }

                if (newPrefabName != null)
                {
                    if (test)
                    {
                        toolError = ToolError.None;
                        return;
                    }

                    NetInfo newPrefab;
                    if (!roadPrefabs.TryGetValue(newPrefabName, out newPrefab) || newPrefab == null)
                    {
                        ModDebug.Error("Prefab not found: " + newPrefabName);
                        error = ToolError.Unknown;
                        return;
                    }

                    newRoadPrefab = newPrefab;

                    int newIndex = RebuildSegment(segmentIndex, newPrefab, toolMode == ToolMode.Oneway, raycastOutput.m_hitPos, hitPosDelta, ref error);

                    if (newIndex != 0)
                    {
                        if (error != ToolError.None)
                        {
                            return;
                        }

                        prevBuiltSegmentIndex = newSegmentIndex;
                        prevRebuildTime       = currentTime;
                        newSegmentIndex       = newIndex;
                    }
                }
                else
                {
                    toolError = ToolError.CannotUpgradeThisType;
                    return;
                }
            }
        }
Esempio n. 4
0
        private void updateParams()
        {
            //if a station is selected updating all of its parametters
            if (curStation != long.MaxValue)
            {
                // get features supported by the station
                curFeatures = JBC.GetStationFeatures(curStation);

                //updating station parametters
                lblModel.Text = JBC.GetStationModel(curStation);
                lblSW.Text    = JBC.GetStationSWversion(curStation);
                lblError.Text = JBC.GetStationError(curStation).ToString();
                lblName.Text  = JBC.GetStationName(curStation);
                CTemperature.TemperatureUnit units = JBC.GetStationTempUnits(curStation);

                // if station supports display settings changes
                butUnits.Enabled = curFeatures.DisplaySettings;
                butN2.Enabled    = curFeatures.DisplaySettings;
                butHelp.Enabled  = curFeatures.DisplaySettings;
                butBeep.Enabled  = curFeatures.DisplaySettings;
                if (curFeatures.DisplaySettings)
                {
                    lblUnits.Text = units.ToString();
                    lblN2.Text    = System.Convert.ToString(JBC.GetStationN2Mode(curStation).ToString().Replace("_", ""));
                    lblHelp.Text  = System.Convert.ToString(JBC.GetStationHelpText(curStation).ToString().Replace("_", ""));
                    lblBeep.Text  = System.Convert.ToString(JBC.GetStationBeep(curStation).ToString().Replace("_", ""));
                }
                else
                {
                    lblUnits.Text = "N/A";                  // not supported
                    lblN2.Text    = "N/A";                  // not supported
                    lblHelp.Text  = "N/A";                  // not supported
                    lblBeep.Text  = "N/A";                  // not supported
                }
                if (units == CTemperature.TemperatureUnit.Celsius)
                {
                    lblTrafoError.Text = JBC.GetStationTransformerErrorTemp(curStation).ToCelsius().ToString() + " ºC";
                    lblMOSerror.Text   = JBC.GetStationMOSerrorTemp(curStation).ToCelsius().ToString() + " ºC";
                    lblTrafo.Text      = JBC.GetStationTransformerTemp(curStation).ToCelsius().ToString() + " ºC";
                    lblMaxTemp.Text    = JBC.GetStationMaxTemp(curStation).ToRoundCelsius().ToString() + " ºC";
                    lblMinTemp.Text    = JBC.GetStationMinTemp(curStation).ToRoundCelsius().ToString() + " ºC";
                }
                else if (units == CTemperature.TemperatureUnit.Fahrenheit)
                {
                    lblTrafoError.Text = JBC.GetStationTransformerErrorTemp(curStation).ToFahrenheit().ToString() + " ºF";
                    lblMOSerror.Text   = JBC.GetStationMOSerrorTemp(curStation).ToFahrenheit().ToString() + " ºF";
                    lblTrafo.Text      = JBC.GetStationTransformerTemp(curStation).ToFahrenheit().ToString() + " ºF";
                    lblMaxTemp.Text    = JBC.GetStationMaxTemp(curStation).ToRoundFahrenheit().ToString() + " ºF";
                    lblMinTemp.Text    = JBC.GetStationMinTemp(curStation).ToRoundFahrenheit().ToString() + " ºF";
                }

                //clearing all the ports labels and disabling the ports group boxes
                for (int cnt = JBC.GetPortCount(curStation) + 1; cnt <= 4; cnt++)
                {
                    Control gbx = this.Controls.Find("gbxPort" + System.Convert.ToString(cnt), true)[0];
                    foreach (Control ctrl in gbx.Controls)
                    {
                        if (ctrl.Name.Contains("lbl"))
                        {
                            ctrl.Text = "";
                        }
                    }
                    gbx.Enabled = false;
                }

                //updating the ports parametters
                for (int cnt = 1; cnt <= JBC.GetPortCount(curStation); cnt++)
                {
                    Control  port      = this.Controls.Find("gbxPort" + System.Convert.ToString(cnt), true)[0];
                    Control  tool      = this.Controls.Find("lblPort" + System.Convert.ToString(cnt) + "Tool", true)[0];
                    Control  err       = this.Controls.Find("lblPort" + System.Convert.ToString(cnt) + "Error", true)[0];
                    Control  actual    = this.Controls.Find("lblPort" + System.Convert.ToString(cnt) + "ActualTemp", true)[0];
                    Control  selec     = this.Controls.Find("lblPort" + System.Convert.ToString(cnt) + "SelecTemp", true)[0];
                    CheckBox sleep     = (CheckBox)(this.Controls.Find("cbxPort" + System.Convert.ToString(cnt) + "Sleep", true)[0]);
                    CheckBox hiber     = (CheckBox)(this.Controls.Find("cbxPort" + System.Convert.ToString(cnt) + "Hibernation", true)[0]);
                    CheckBox extractor = (CheckBox)(this.Controls.Find("cbxPort" + System.Convert.ToString(cnt) + "Extractor", true)[0]);
                    tool.Text = JBC.GetPortToolID(curStation, (Port)(cnt - 1)).ToString();
                    if (tool.Text != "")
                    {
                        port.Enabled = true;
                        ToolError aux = JBC.GetPortToolError(curStation, (Port)(cnt - 1));
                        if (aux == ToolError.NO_TOOL)
                        {
                            err.Text = ToolError.NO_ERROR.ToString();
                        }
                        else
                        {
                            err.Text = JBC.GetPortToolError(curStation, (Port)(cnt - 1)).ToString();
                        }
                        if (units == CTemperature.TemperatureUnit.Celsius)
                        {
                            actual.Text = JBC.GetPortToolActualTemp(curStation, (Port)(cnt - 1)).ToRoundCelsius().ToString() + " ºC";
                            selec.Text  = JBC.GetPortToolSelectedTemp(curStation, (Port)(cnt - 1)).ToRoundCelsius().ToString() + " ºC";
                        }
                        else if (units == CTemperature.TemperatureUnit.Fahrenheit)
                        {
                            actual.Text = JBC.GetPortToolActualTemp(curStation, (Port)(cnt - 1)).ToRoundFahrenheit().ToString() + " ºF";
                            selec.Text  = JBC.GetPortToolSelectedTemp(curStation, (Port)(cnt - 1)).ToRoundFahrenheit().ToString() + " ºF";
                        }
                        sleep.Checked     = JBC.GetPortToolSleepStatus(curStation, (Port)(cnt - 1)) == OnOff._ON;
                        hiber.Checked     = JBC.GetPortToolHibernationStatus(curStation, (Port)(cnt - 1)) == OnOff._ON;
                        extractor.Checked = JBC.GetPortToolExtractorStatus(curStation, (Port)(cnt - 1)) == OnOff._ON;
                    }
                }
            }
        }
        public virtual void OnBeforeSimulationTick()
        {
            if (!this.enabled)
            {
                return;
            }
            if (Object.op_Inequality((Object)this.buildTool, (Object)null))
            {
                if (!this.mouseDown && this.buildTool.SegmentsTouched.Count > 0)
                {
                    this.buildTool.SegmentsTouched = new HashSet <int>();
                }
                this.buildTool.isHoveringSegment = false;
                this.buildTool.ToolCursor        = (CursorInfo)this.netTool.m_upgradeCursor;
                // ISSUE: variable of the null type
                __Null texture = ((CursorInfo)this.netTool.m_upgradeCursor).m_texture;
            }
            if (!this.mouseRayValid)
            {
                return;
            }
            ToolBase.RaycastInput input;
            ((ToolBase.RaycastInput) ref input).\u002Ector(this.mouseRay, this.mouseRayLength);
            input.m_netService         = (__Null)this.raycastService;
            input.m_ignoreTerrain      = (__Null)1;
            input.m_ignoreNodeFlags    = (__Null) - 1;
            input.m_ignoreSegmentFlags = (__Null)32;
            ToolBase.RaycastOutput output;
            if (ZoningTool11.RayCast(input, out output))
            {
                int netSegment = (int)output.m_netSegment;
                if (netSegment != 0)
                {
                    NetManager instance = Singleton <NetManager> .get_instance();

                    NetTool.ControlPoint startPoint;
                    NetTool.ControlPoint middlePoint;
                    NetTool.ControlPoint endPoint;
                    this.GetSegmentControlPoints(netSegment, out startPoint, out middlePoint, out endPoint);
                    ushort num1;
                    ushort num2;
                    int    num3;
                    int    num4;
                    if ((NetTool.CreateNode(((NetSegment) ref ((Array16 <NetSegment>)instance.m_segments).m_buffer[netSegment]).get_Info(), startPoint, middlePoint, endPoint, (FastList <NetTool.NodePosition>)NetTool.m_nodePositionsSimulation, 1000, true, false, true, false, false, false, (ushort)0, ref num1, ref num2, ref num3, ref num4) & 32L) != null)
                    {
                        this.toolError = ToolError.OutOfArea;
                    }
                    else if (this.mouseDown)
                    {
                        this.HandleMouseDrag(ref output, ref this.toolError, false, ref netSegment);
                    }
                    else
                    {
                        this.HandleMouseDrag(ref output, ref this.toolError, true, ref netSegment);
                    }
                    if (Object.op_Inequality((Object)this.buildTool, (Object)null))
                    {
                        this.buildTool.segment      = (NetSegment)((Array16 <NetSegment>)instance.m_segments).m_buffer[netSegment];
                        this.buildTool.segmentIndex = netSegment;
                        if (Object.op_Equality((Object)(((NetSegment) ref this.buildTool.segment).get_Info().m_netAI as RoadAI), (Object)null) && this.toolError != ToolError.OutOfArea)
                        {
                            this.toolError = ToolError.CannotUpgradeThisType;
                        }
                        this.buildTool.isHoveringSegment = this.toolError != ToolError.CannotUpgradeThisType;
                        this.GetSegmentControlPoints(netSegment, out this.buildTool.startPoint, out this.buildTool.middlePoint, out this.buildTool.endPoint);
                    }
                }
            }
Esempio n. 6
0
        void HandleMouseDrag(ref ToolBase.RaycastOutput raycastOutput, ref ToolError error, bool test, ref NetInfo newRoadPrefab, ref int newSegmentIndex) {

            Vector3 hitPosDelta = Vector3.zero;

            if (!test) {
                if (currentTime - prevRebuildTime < 0.1f) return;

                if (dragging) {
                    hitPosDelta = raycastOutput.m_hitPos - prevHitPos;
                    if (hitPosDelta.magnitude < 12.0f) return;
                }
                else {
                    prevHitPos = raycastOutput.m_hitPos;
                    dragging = true;
                    if (toolMode == ToolMode.Oneway) return;
                }

                prevHitPos = raycastOutput.m_hitPos;
            }

            int segmentIndex = raycastOutput.m_netSegment;
            if (segmentIndex != 0) {
                NetManager net = Singleton<NetManager>.instance;
                NetInfo prefab = net.m_segments.m_buffer[segmentIndex].Info;

                bool isOneway = !prefab.m_hasForwardVehicleLanes || !prefab.m_hasBackwardVehicleLanes;


                string prefabName = null;
                if (!roadPrefabNames.TryGetValue(prefab.GetInstanceID(), out prefabName) || prefabName == null) {
                    ModDebug.Error("Prefab name not found");
                    error = ToolError.Unknown;
                    return;
                }

                string newPrefabName = null;
                if (toolMode == ToolMode.Oneway) {
                    if (!isOneway) newPrefabName = FindMatchingName(prefabName, twowayNames, onewayNames);
                    else newPrefabName = prefabName;
                }
                else {
                    if (isOneway) {
                        newPrefabName = FindMatchingName(prefabName, onewayNames, twowayNames);
                    }
                    else {
                        toolError = ToolError.AlreadyTwoway;
                        return;
                    }
                }

                if (newPrefabName != null) {
                    if (test) {
                        toolError = ToolError.None;
                        return;
                    }

                    NetInfo newPrefab;
                    if (!roadPrefabs.TryGetValue(newPrefabName, out newPrefab) || newPrefab == null) {
                        ModDebug.Error("Prefab not found: " + newPrefabName);
                        error = ToolError.Unknown;
                        return;
                    }

                    newRoadPrefab = newPrefab;

                    int newIndex = RebuildSegment(segmentIndex, newPrefab, toolMode == ToolMode.Oneway, raycastOutput.m_hitPos, hitPosDelta, ref error);

                    if (newIndex != 0) {
                        if (error != ToolError.None) return;

                        prevBuiltSegmentIndex = newSegmentIndex;
                        prevRebuildTime = currentTime;
                        newSegmentIndex = newIndex;
                    }
                }
                else {
                    toolError = ToolError.CannotUpgradeThisType;
                    return;
                }
            }
        }
Esempio n. 7
0
        int RebuildSegment(int segmentIndex, NetInfo newPrefab, bool roadDirectionMatters, Vector3 directionPoint, Vector3 direction, ref ToolError error) {
            NetManager net = Singleton<NetManager>.instance;

            NetInfo prefab = net.m_segments.m_buffer[segmentIndex].Info;

            NetTool.ControlPoint startPoint;
            NetTool.ControlPoint middlePoint;
            NetTool.ControlPoint endPoint;
            GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);
            
            if (direction.magnitude > 0.0f) {
                float dot = Vector3.Dot(direction.normalized, (endPoint.m_position - startPoint.m_position).normalized);
                float threshold = Mathf.Cos(Mathf.PI / 4);

                if (dot > -threshold && dot < threshold) return 0;

                if (roadDirectionMatters) {
                    bool inverted = (net.m_segments.m_buffer[segmentIndex].m_flags & NetSegment.Flags.Invert) != 0;

                    if (Singleton<SimulationManager>.instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True) {
                        inverted = !inverted; // roads need to be placed in the opposite direction with left-hand traffic
                    }

                    bool reverseDirection = inverted ? (dot > 0.0f) : (dot < -0.0f);

                    if (reverseDirection) {
                        var tmp = startPoint;
                        startPoint = endPoint;
                        endPoint = tmp;

                        startPoint.m_direction = -startPoint.m_direction;
                        endPoint.m_direction = -endPoint.m_direction;
                        middlePoint.m_direction = startPoint.m_direction;
                    }
                    else {
                        if (prefab == newPrefab) {
                            error = ToolError.SameDirection;
                            return 0;
                        }
                    }
                }
            }

            bool test = false;
            bool visualize = false;
            bool autoFix = true;
            bool needMoney = false;
            bool invert = false;

            ushort node = 0;
            ushort segment = 0;
            int cost = 0;
            int productionRate = 0;
             
			NetTool.CreateNode(newPrefab, startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000, test, visualize, autoFix, needMoney, invert, false, (ushort)0, out node, out segment, out cost, out productionRate);

            if (segment != 0) {
                if (newPrefab.m_class.m_service == ItemClass.Service.Road) {
                    Singleton<CoverageManager>.instance.CoverageUpdated(ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Level.None);
                }

                error = ToolError.None;
                return segment;
            }

            return 0;
        }
Esempio n. 8
0
        void _OnBeforeSimulationTick() {
            if (toolMode == ToolMode.None) return;

            if (!mouseDown) {
                dragging = false;
                prevBuiltSegmentIndex = 0;
            }

            if (buildTool != null) {
                buildTool.isHoveringSegment = false;
                buildTool.toolMode = toolMode;
                buildTool.ToolCursor = netTool.m_upgradeCursor;
            }

            if (!mouseRayValid) return;

            ToolBase.RaycastInput raycastInput = new ToolBase.RaycastInput(mouseRay, mouseRayLength);
            raycastInput.m_netService = raycastService;
            raycastInput.m_ignoreTerrain = true;
            raycastInput.m_ignoreNodeFlags = NetNode.Flags.All;
            raycastInput.m_ignoreSegmentFlags = NetSegment.Flags.Untouchable;

            ToolBase.RaycastOutput raycastOutput;
            if (BuildTool118.RayCast(raycastInput, out raycastOutput)) {

                int segmentIndex = raycastOutput.m_netSegment;
                if (segmentIndex != 0) {

                    NetManager net = Singleton<NetManager>.instance;
                    NetInfo newRoadPrefab = null;

                    NetTool.ControlPoint startPoint;
                    NetTool.ControlPoint middlePoint;
                    NetTool.ControlPoint endPoint;

                    GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);

                    ushort node;
                    ushort outSegment;
                    int cost;
                    int productionRate;
                    // Check for out-of-area error and initialized collide arrays for visualization
                    ToolBase.ToolErrors errors = NetTool.CreateNode(net.m_segments.m_buffer[segmentIndex].Info,
                        startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000,
                        true, false, true, false, false, false, (ushort)0, out node, out outSegment, out cost, out productionRate);

                    if ((errors & ToolBase.ToolErrors.OutOfArea) != 0) {
                        toolError = ToolError.OutOfArea;
                    }
                    else {
                        if (mouseDown) {
                            HandleMouseDrag(ref raycastOutput, ref toolError, false, ref newRoadPrefab, ref segmentIndex);

                            if (segmentIndex == prevBuiltSegmentIndex) {
                                toolError = ToolError.AlreadyBuilt;
                            }
                        }
                        else {
                            HandleMouseDrag(ref raycastOutput, ref toolError, true, ref newRoadPrefab, ref segmentIndex);
                        }
                    }

                    if (buildTool != null) {
                        buildTool.segment = net.m_segments.m_buffer[segmentIndex];
                        buildTool.segmentIndex = segmentIndex;
                        buildTool.isHoveringSegment = toolError != ToolError.Unknown;
                        if (newRoadPrefab != null) buildTool.newPrefab = newRoadPrefab;
                        GetSegmentControlPoints(segmentIndex, out buildTool.startPoint, out buildTool.middlePoint, out buildTool.endPoint);
                    }
                }
            }

            if (buildTool != null) {
                buildTool.toolError = toolError;
            }
        }
        int RebuildSegment(int segmentIndex, NetInfo newPrefab, Vector3 directionPoint, Vector3 direction, ref ToolError error)
        {
            //  ModDebug.LogClassAndMethodName(this.GetType().Name, System.Reflection.MethodBase.GetCurrentMethod().Name);

            NetManager net    = Singleton <NetManager> .instance;
            NetInfo    prefab = net.m_segments.m_buffer[segmentIndex].Info;

            NetTool.ControlPoint startPoint;
            NetTool.ControlPoint middlePoint;
            NetTool.ControlPoint endPoint;

            MethodInfo dynMethod = netTool.GetType().GetMethod("ChangeElevation", BindingFlags.NonPublic | BindingFlags.Instance);

            if (toolMode == ToolMode.RoadHeightUp)
            {
                Singleton <SimulationManager> .instance.AddAction <bool>((IEnumerator <bool>) dynMethod.Invoke(new NetTool(), new object[] { 1 }));
            }
            else if (toolMode == ToolMode.RoadHeightDown)
            {
                Singleton <SimulationManager> .instance.AddAction <bool>((IEnumerator <bool>) dynMethod.Invoke(new NetTool(), new object[] { -1 }));
            }

            GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);

            if (direction.magnitude > 0.0f)
            {
                float dot       = Vector3.Dot(direction.normalized, (endPoint.m_position - startPoint.m_position).normalized);
                float threshold = Mathf.Cos(Mathf.PI / 4);

                if (dot > -threshold && dot < threshold)
                {
                    return(0);
                }
            }

            ushort node           = 0;
            ushort segment        = 0;
            int    cost           = 0;
            int    productionRate = 0;

            //  CreateNode(NetInfo info, NetTool.ControlPoint startPoint, NetTool.ControlPoint middlePoint, NetTool.ControlPoint endPoint, FastList<NetTool.NodePosition> nodeBuffer, int maxSegments, bool test, bool visualize, bool autoFix, bool needMoney, bool invert, bool switchDir, ushort relocateBuildingID, out ushort firstNode, out ushort lastNode, out ushort segment, out int cost, out int productionRate)
            if (mouseDown && ((currentTime - prevRebuildTime) > 0.4f))
            {
                newPrefab.m_minHeight = 12.0f;
                NetTool.CreateNode(newPrefab, startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000, false, false, true, false, false, false, (ushort)0, out node, out segment, out cost, out productionRate);
            }
            if (segment != 0)
            {
                if (newPrefab.m_class.m_service == ItemClass.Service.Road)
                {
                    Singleton <CoverageManager> .instance.CoverageUpdated(ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Level.None);
                }

                error = ToolError.None;
                return(segment);
            }

            return(0);
        }
        public override void OnUpdate(float realTimeDelta, float simulationTimeDelta)
        {
            ModDebug.LogClassAndMethodName(this.GetType().Name, System.Reflection.MethodBase.GetCurrentMethod().Name);
            if (loadingLevel)
            {
                return;
            }

            if (Input.GetKeyDown(KeyCode.Return))
            {
                ModDebug.Log(netTool.m_prefab + " " + netTool.m_mode);
            }

            if (roadsPanel == null)
            {
                roadsPanel = UIView.Find <UIPanel>("RoadsPanel");
            }

            if (roadsPanel == null || !roadsPanel.isVisible)
            {
                if (toolMode != ToolMode.None)
                {
                    ModDebug.Log("Roads panel no longer visible");
                    SetToolMode(ToolMode.None, true);
                }
                return;
            }

            if (netTool == null)
            {
                foreach (var tool in ToolsModifierControl.toolController.Tools)
                {
                    NetTool nt = tool as NetTool;
                    if (nt != null && nt.m_prefab != null)
                    {
                        ModDebug.Log("NetTool found: " + nt.name);
                        netTool = nt;
                        break;
                    }
                }

                if (netTool == null)
                {
                    return;
                }

                raycastService = new ToolBase.RaycastService(netTool.m_prefab.m_class.m_service, netTool.m_prefab.m_class.m_subService, netTool.m_prefab.m_class.m_layer);

                ModDebug.Log("UI visible: " + ui.isVisible);
            }

            if (!ui.isVisible)
            {
                ui.Show();
            }

            if (toolMode != ToolMode.None)
            {
                mouseDown      = Input.GetMouseButton(0);
                mouseRayValid  = !ToolsModifierControl.toolController.IsInsideUI && Cursor.visible;
                mouseRay       = Camera.main.ScreenPointToRay(Input.mousePosition);
                mouseRayLength = Camera.main.farClipPlane;
                currentTime    = Time.time;

                if (ToolsModifierControl.toolController.CurrentTool != buildTool)
                {
                    ModDebug.Log("Another tool selected");
                    SetToolMode(ToolMode.None);
                }
            }
            else
            {
                ui.toolMode = ToolMode.None;

                if (ToolsModifierControl.toolController.CurrentTool == buildTool)
                {
                    ToolsModifierControl.toolController.CurrentTool = netTool;
                }
            }

            //ModDebug.LogClassAndMethodName(this.GetType().Name, System.Reflection.MethodBase.GetCurrentMethod().Name);

            if (toolMode == ToolMode.None)
            {
                return;
            }

            if (!mouseDown)
            {
                prevBuiltSegmentIndex = 0;
            }

            if (buildTool != null)
            {
                buildTool.isHoveringSegment = false;
                buildTool.toolMode          = toolMode;
                buildTool.ToolCursor        = netTool.m_upgradeCursor;
            }

            if (!mouseRayValid)
            {
                return;
            }

            ToolBase.RaycastInput raycastInput = new ToolBase.RaycastInput(mouseRay, mouseRayLength);
            raycastInput.m_netService         = raycastService;
            raycastInput.m_ignoreTerrain      = true;
            raycastInput.m_ignoreNodeFlags    = NetNode.Flags.All;
            raycastInput.m_ignoreSegmentFlags = NetSegment.Flags.Untouchable;

            ToolBase.RaycastOutput raycastOutput;

            if (BuildTool21.RayCast(raycastInput, out raycastOutput))
            {
                int segmentIndex = raycastOutput.m_netSegment;
                if (segmentIndex != 0)
                {
                    NetManager net           = Singleton <NetManager> .instance;
                    NetInfo    newRoadPrefab = null;
                    NetInfo    prefab        = net.m_segments.m_buffer[segmentIndex].Info;

                    NetTool.ControlPoint startPoint;
                    NetTool.ControlPoint middlePoint;
                    NetTool.ControlPoint endPoint;

                    GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);

                    ushort node;
                    ushort outSegment;
                    int    cost;
                    int    productionRate;
                    // Check for out-of-area error and initialized collide arrays for visualization
                    ToolBase.ToolErrors errors = NetTool.CreateNode(net.m_segments.m_buffer[segmentIndex].Info,
                                                                    startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000,
                                                                    true, false, true, false, false, false, (ushort)0, out node, out outSegment, out cost, out productionRate);

                    if ((errors & ToolBase.ToolErrors.OutOfArea) != 0)
                    {
                        toolError = ToolError.OutOfArea;
                    }

                    string prefabName = null;
                    if (!roadPrefabNames.TryGetValue(prefab.GetInstanceID(), out prefabName) || prefabName == null)
                    {
                        ModDebug.Error("Prefab name not found");
                        toolError = ToolError.Unknown;
                        return;
                    }

                    NetInfo newPrefab;
                    if (!roadPrefabs.TryGetValue(prefabName, out newPrefab) || newPrefab == null)
                    {
                        ModDebug.Error("Prefab not found: " + prefabName);
                        toolError = ToolError.Unknown;
                        return;
                    }

                    newRoadPrefab = newPrefab;

                    //  ModDebug.Log("Going to rebuild segment");
                    int newIndex = RebuildSegment(segmentIndex, newPrefab, raycastOutput.m_hitPos, hitPosDelta, ref toolError);

                    if (newIndex != 0)
                    {
                        //    ModDebug.Log("newIndex: " + newIndex);
                        if (toolError != ToolError.None)
                        {
                            return;
                        }

                        prevBuiltSegmentIndex = segmentIndex;
                        prevRebuildTime       = currentTime;
                        segmentIndex          = newIndex;
                    }

                    if (buildTool != null)
                    {
                        // ModDebug.Log("Using segment from buffer");
                        buildTool.segment           = net.m_segments.m_buffer[segmentIndex];
                        buildTool.segmentIndex      = segmentIndex;
                        buildTool.isHoveringSegment = toolError != ToolError.Unknown;
                        if (newRoadPrefab != null)
                        {
                            buildTool.newPrefab = newRoadPrefab;
                        }
                        GetSegmentControlPoints(segmentIndex, out buildTool.startPoint, out buildTool.middlePoint, out buildTool.endPoint);
                    }
                }
            }

            if (buildTool != null)
            {
                buildTool.toolError = toolError;
            }
        }
        public override void OnUpdate(float realTimeDelta, float simulationTimeDelta)
        {
            ModDebug.LogClassAndMethodName(this.GetType().Name, System.Reflection.MethodBase.GetCurrentMethod().Name);
            if (loadingLevel) return;

            if (Input.GetKeyDown(KeyCode.Return))
            {
                ModDebug.Log(netTool.m_prefab + " " + netTool.m_mode);
            }

            if (roadsPanel == null)
            {
                roadsPanel = UIView.Find<UIPanel>("RoadsPanel");
            }

            if (roadsPanel == null || !roadsPanel.isVisible)
            {
                if (toolMode != ToolMode.None)
                {
                    ModDebug.Log("Roads panel no longer visible");
                    SetToolMode(ToolMode.None, true);
                }
                return;
            }

            if (netTool == null)
            {
                foreach (var tool in ToolsModifierControl.toolController.Tools)
                {
                    NetTool nt = tool as NetTool;
                    if (nt != null && nt.m_prefab != null)
                    {
                        ModDebug.Log("NetTool found: " + nt.name);
                        netTool = nt;
                        break;
                    }
                }

                if (netTool == null) return;

                raycastService = new ToolBase.RaycastService(netTool.m_prefab.m_class.m_service, netTool.m_prefab.m_class.m_subService, netTool.m_prefab.m_class.m_layer);

                ModDebug.Log("UI visible: " + ui.isVisible);
            }

            if (!ui.isVisible)
            {
                ui.Show();
            }

            if (toolMode != ToolMode.None)
            {
                mouseDown = Input.GetMouseButton(0);
                mouseRayValid = !ToolsModifierControl.toolController.IsInsideUI && Cursor.visible;
                mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
                mouseRayLength = Camera.main.farClipPlane;
                currentTime = Time.time;

                if (ToolsModifierControl.toolController.CurrentTool != buildTool)
                {
                    ModDebug.Log("Another tool selected");
                    SetToolMode(ToolMode.None);
                }
            }
            else
            {
                ui.toolMode = ToolMode.None;

                if (ToolsModifierControl.toolController.CurrentTool == buildTool)
                {
                    ToolsModifierControl.toolController.CurrentTool = netTool;
                }
            }

            //ModDebug.LogClassAndMethodName(this.GetType().Name, System.Reflection.MethodBase.GetCurrentMethod().Name);

            if (toolMode == ToolMode.None) return;

            if (!mouseDown)
            {
                prevBuiltSegmentIndex = 0;
            }

            if (buildTool != null)
            {
                buildTool.isHoveringSegment = false;
                buildTool.toolMode = toolMode;
                buildTool.ToolCursor = netTool.m_upgradeCursor;
            }

            if (!mouseRayValid) return;

            ToolBase.RaycastInput raycastInput = new ToolBase.RaycastInput(mouseRay, mouseRayLength);
            raycastInput.m_netService = raycastService;
            raycastInput.m_ignoreTerrain = true;
            raycastInput.m_ignoreNodeFlags = NetNode.Flags.All;
            raycastInput.m_ignoreSegmentFlags = NetSegment.Flags.Untouchable;

            ToolBase.RaycastOutput raycastOutput;

            if (BuildTool21.RayCast(raycastInput, out raycastOutput))
            {

                int segmentIndex = raycastOutput.m_netSegment;
                if (segmentIndex != 0)
                {

                    NetManager net = Singleton<NetManager>.instance;
                    NetInfo newRoadPrefab = null;
                    NetInfo prefab = net.m_segments.m_buffer[segmentIndex].Info;

                    NetTool.ControlPoint startPoint;
                    NetTool.ControlPoint middlePoint;
                    NetTool.ControlPoint endPoint;

                    GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);

                    ushort node;
                    ushort outSegment;
                    int cost;
                    int productionRate;
                    // Check for out-of-area error and initialized collide arrays for visualization
                    ToolBase.ToolErrors errors = NetTool.CreateNode(net.m_segments.m_buffer[segmentIndex].Info,
                        startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000,
                        true, false, true, false, false, false, (ushort)0, out node, out outSegment, out cost, out productionRate);

                    if ((errors & ToolBase.ToolErrors.OutOfArea) != 0)
                    {
                        toolError = ToolError.OutOfArea;
                    }

                    string prefabName = null;
                    if (!roadPrefabNames.TryGetValue(prefab.GetInstanceID(), out prefabName) || prefabName == null)
                    {
                        ModDebug.Error("Prefab name not found");
                        toolError = ToolError.Unknown;
                        return;
                    }

                    NetInfo newPrefab;
                    if (!roadPrefabs.TryGetValue(prefabName, out newPrefab) || newPrefab == null)
                    {
                        ModDebug.Error("Prefab not found: " + prefabName);
                        toolError = ToolError.Unknown;
                        return;
                    }

                    newRoadPrefab = newPrefab;

                      //  ModDebug.Log("Going to rebuild segment");
                        int newIndex = RebuildSegment(segmentIndex, newPrefab, raycastOutput.m_hitPos, hitPosDelta, ref toolError);

                        if (newIndex != 0)
                        {
                        //    ModDebug.Log("newIndex: " + newIndex);
                            if (toolError != ToolError.None) return;

                            prevBuiltSegmentIndex = segmentIndex;
                            prevRebuildTime = currentTime;
                            segmentIndex = newIndex;
                        }

                    if (buildTool != null)
                    {
                        // ModDebug.Log("Using segment from buffer");
                         buildTool.segment = net.m_segments.m_buffer[segmentIndex];
                         buildTool.segmentIndex = segmentIndex;
                         buildTool.isHoveringSegment = toolError != ToolError.Unknown;
                         if (newRoadPrefab != null) buildTool.newPrefab = newRoadPrefab;
                         GetSegmentControlPoints(segmentIndex, out buildTool.startPoint, out buildTool.middlePoint, out buildTool.endPoint);
                    }
                }
            }

            if (buildTool != null)
            {
                buildTool.toolError = toolError;
            }
        }
        int RebuildSegment(int segmentIndex, NetInfo newPrefab, Vector3 directionPoint, Vector3 direction, ref ToolError error)
        {
            //  ModDebug.LogClassAndMethodName(this.GetType().Name, System.Reflection.MethodBase.GetCurrentMethod().Name);

            NetManager net = Singleton<NetManager>.instance;
            NetInfo prefab = net.m_segments.m_buffer[segmentIndex].Info;

            NetTool.ControlPoint startPoint;
            NetTool.ControlPoint middlePoint;
            NetTool.ControlPoint endPoint;

            MethodInfo dynMethod = netTool.GetType().GetMethod("ChangeElevation", BindingFlags.NonPublic | BindingFlags.Instance);
            if (toolMode == ToolMode.RoadHeightUp)
            {
                Singleton<SimulationManager>.instance.AddAction<bool>((IEnumerator<bool>)dynMethod.Invoke(new NetTool(), new object[] { 1 }));
            }
            else if (toolMode == ToolMode.RoadHeightDown)
            {
                Singleton<SimulationManager>.instance.AddAction<bool>((IEnumerator<bool>)dynMethod.Invoke(new NetTool(), new object[] { -1 }));
            }

            GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);

            if (direction.magnitude > 0.0f)
            {
                float dot = Vector3.Dot(direction.normalized, (endPoint.m_position - startPoint.m_position).normalized);
                float threshold = Mathf.Cos(Mathf.PI / 4);

                if (dot > -threshold && dot < threshold) return 0;
            }

            ushort node = 0;
            ushort segment = 0;
            int cost = 0;
            int productionRate = 0;

            //  CreateNode(NetInfo info, NetTool.ControlPoint startPoint, NetTool.ControlPoint middlePoint, NetTool.ControlPoint endPoint, FastList<NetTool.NodePosition> nodeBuffer, int maxSegments, bool test, bool visualize, bool autoFix, bool needMoney, bool invert, bool switchDir, ushort relocateBuildingID, out ushort firstNode, out ushort lastNode, out ushort segment, out int cost, out int productionRate)
            if (mouseDown && ((currentTime - prevRebuildTime) > 0.4f))
            {
                newPrefab.m_minHeight = 12.0f;
                NetTool.CreateNode(newPrefab, startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000, false, false, true, false, false, false, (ushort)0, out node, out segment, out cost, out productionRate);
            }
               if (segment != 0)
               {
               if (newPrefab.m_class.m_service == ItemClass.Service.Road)
               {
                   Singleton<CoverageManager>.instance.CoverageUpdated(ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Level.None);
               }

               error = ToolError.None;
               return segment;
               }

            return 0;
        }