private void FixNodes() { m_stopWatch.Reset(); m_stopWatch.Start(); NetNode[] nodes = NetManager.instance.m_nodes.m_buffer; bool singleMode = RoadPrefab.singleMode; RoadPrefab.singleMode = false; uint max = NetManager.instance.m_nodes.m_size; for (int i = m_fixNodesCount; i < max; i++) { if (nodes[i].m_flags == NetNode.Flags.None || (nodes[i].m_flags & NetNode.Flags.Untouchable) == NetNode.Flags.Untouchable) { continue; } if (m_stopWatch.ElapsedMilliseconds >= 1 && i > m_fixNodesCount + 16) { m_fixNodesCount = i; RoadPrefab.singleMode = singleMode; return; } NetInfo info = nodes[i].Info; if ((nodes[i].m_flags & NetNode.Flags.Underground) == NetNode.Flags.Underground) { if (info == null || info.m_netAI == null) { continue; } RoadPrefab prefab = RoadPrefab.GetPrefab(info); if (prefab == null) { continue; } if (info != prefab.roadAI.tunnel && info != prefab.roadAI.slope && !info.m_netAI.IsUnderground()) { nodes[i].m_elevation = 0; nodes[i].m_flags = nodes[i].m_flags & ~NetNode.Flags.Underground; // Updating terrain try { TerrainModify.UpdateArea(nodes[i].m_bounds.min.x, nodes[i].m_bounds.min.z, nodes[i].m_bounds.max.x, nodes[i].m_bounds.max.z, true, true, false); } catch {} } } } RoadPrefab.singleMode = singleMode; m_fixNodesCount = 0; }
private void AttachToolOptionsButton(RoadPrefab prefab) { m_buttonExists = false; RoadsOptionPanel[] panels = GameObject.FindObjectsOfType <RoadsOptionPanel>(); foreach (RoadsOptionPanel panel in panels) { // Find the visible RoadsOptionPanel if (panel.component.isVisible) { UIComponent button = panel.component.Find <UIComponent>("ElevationStep"); if (button == null) { continue; } // Put the main button in ElevationStep m_toolOptionButton.transform.SetParent(button.transform); m_buttonInOptionsBar = false; button.tooltip = null; m_buttonExists = true; // Add Upgrade button if needed List <NetTool.Mode> list = new List <NetTool.Mode>(panel.m_Modes); if (m_upgradeButtonTemplate != null && prefab != null && prefab.hasVariation && !list.Contains(NetTool.Mode.Upgrade)) { UITabstrip toolMode = panel.component.Find <UITabstrip>("ToolMode"); if (toolMode != null) { list.Add(NetTool.Mode.Upgrade); panel.m_Modes = list.ToArray(); toolMode.AddTab("Upgrade", m_upgradeButtonTemplate, false); DebugUtils.Log("Upgrade button added."); } } return; } } // No visible RoadsOptionPanel found. Put the main button in OptionsBar instead UIPanel optionBar = UIView.Find <UIPanel>("OptionsBar"); if (optionBar == null) { DebugUtils.Log("OptionBar not found!"); return; } m_toolOptionButton.transform.SetParent(optionBar.transform); m_buttonInOptionsBar = true; }
private void Activate(NetInfo info) { if (info == null) { return; } RoadPrefab prefab = RoadPrefab.GetPrefab(m_current); if (prefab != null) { prefab.Restore(true); } m_current = info; prefab = RoadPrefab.GetPrefab(info); AttachToolOptionsButton(prefab); // Is it a valid prefab? m_current.m_netAI.GetElevationLimits(out int min, out int max); if ((m_bulldozeTool.enabled || (min == 0 && max == 0)) && !m_buttonExists) { Deactivate(); return; } DisableDefaultKeys(); m_elevation = (int)m_elevationField.GetValue(m_netTool); if (prefab != null) { prefab.mode = m_mode; prefab.Update(straightSlope); } else { DebugUtils.Log("Selected prefab not registered"); } m_segmentCount = NetManager.instance.m_segmentCount; m_controlPointCount = 0; m_activated = true; m_toolOptionButton.isVisible = true; m_toolOptionButton.UpdateInfo(); }
private void Deactivate() { if (!isActive) { return; } RoadPrefab prefab = RoadPrefab.GetPrefab(m_current); if (prefab != null) { prefab.Restore(true); } m_current = null; RestoreDefaultKeys(); m_activated = false; DebugUtils.Log("Deactivated"); }
private static bool IsEndTunnel(ref NetNode node) { if ((node.m_flags & NetNode.Flags.Untouchable) == NetNode.Flags.Untouchable && (node.m_flags & NetNode.Flags.Underground) == NetNode.Flags.Underground) { return(false); } int count = 0; for (int i = 0; i < 8; i++) { int segment = node.GetSegment(i); if (segment == 0 || (NetManager.instance.m_segments.m_buffer[segment].m_flags & NetSegment.Flags.Created) != NetSegment.Flags.Created) { continue; } NetInfo info = NetManager.instance.m_segments.m_buffer[segment].Info; RoadPrefab prefab = RoadPrefab.GetPrefab(info); if (prefab == null) { return(true); } if (info != prefab.roadAI.tunnel && info != prefab.roadAI.slope) { return(true); } count++; } if (TerrainManager.instance.SampleRawHeightSmooth(node.m_position) > node.m_position.y + 8f) { return(false); } return(count == 1); }
private void FixTunnels() { m_stopWatch.Reset(); m_stopWatch.Start(); bool singleMode = RoadPrefab.singleMode; RoadPrefab.singleMode = false; NetNode[] nodes = NetManager.instance.m_nodes.m_buffer; NetSegment[] segments = NetManager.instance.m_segments.m_buffer; uint max = NetManager.instance.m_segments.m_size; for (ushort i = m_fixTunnelsCount; i < max; i++) { if (segments[i].m_flags == NetSegment.Flags.None || (segments[i].m_flags & NetSegment.Flags.Untouchable) == NetSegment.Flags.Untouchable) { continue; } if (m_stopWatch.ElapsedMilliseconds >= 1 && i > m_fixTunnelsCount + 16) { m_fixTunnelsCount = i; RoadPrefab.singleMode = singleMode; return; } NetInfo info = segments[i].Info; ushort startNode = segments[i].m_startNode; ushort endNode = segments[i].m_endNode; RoadPrefab prefab = RoadPrefab.GetPrefab(info); if (prefab == null) { continue; } // Is it a tunnel? if (info == prefab.roadAI.tunnel) { // Make sure tunnels have underground flag if ((nodes[startNode].m_flags & NetNode.Flags.Untouchable) == NetNode.Flags.None) { nodes[startNode].m_flags = nodes[startNode].m_flags | NetNode.Flags.Underground; } if ((nodes[endNode].m_flags & NetNode.Flags.Untouchable) == NetNode.Flags.None) { nodes[endNode].m_flags = nodes[endNode].m_flags | NetNode.Flags.Underground; } if (prefab.roadAI.slope == null) { continue; } // Convert tunnel entrance? if (IsEndTunnel(ref nodes[startNode])) { // Oops wrong way! Invert the segment segments[i].m_startNode = endNode; segments[i].m_endNode = startNode; Vector3 dir = segments[i].m_startDirection; segments[i].m_startDirection = segments[i].m_endDirection; segments[i].m_endDirection = dir; segments[i].m_flags = segments[i].m_flags ^ NetSegment.Flags.Invert; segments[i].CalculateSegment(i); // Make it a slope segments[i].Info = prefab.roadAI.slope; NetManager.instance.UpdateSegment(i); if ((nodes[startNode].m_flags & NetNode.Flags.Untouchable) == NetNode.Flags.None) { nodes[startNode].m_flags = nodes[startNode].m_flags & ~NetNode.Flags.Underground; } } else if (IsEndTunnel(ref nodes[endNode])) { // Make it a slope segments[i].Info = prefab.roadAI.slope; NetManager.instance.UpdateSegment(i); if ((nodes[endNode].m_flags & NetNode.Flags.Untouchable) == NetNode.Flags.None) { nodes[endNode].m_flags = nodes[endNode].m_flags & ~NetNode.Flags.Underground; } } } // Is it a slope? else if (info == prefab.roadAI.slope) { if (prefab.roadAI.tunnel == null) { continue; } // Convert to tunnel? if (!IsEndTunnel(ref nodes[startNode]) && !IsEndTunnel(ref nodes[endNode])) { if ((nodes[startNode].m_flags & NetNode.Flags.Untouchable) == NetNode.Flags.None) { nodes[startNode].m_flags = nodes[startNode].m_flags | NetNode.Flags.Underground; } if ((nodes[endNode].m_flags & NetNode.Flags.Untouchable) == NetNode.Flags.None) { nodes[endNode].m_flags = nodes[endNode].m_flags | NetNode.Flags.Underground; } // Make it a tunnel segments[i].Info = prefab.roadAI.tunnel; segments[i].UpdateBounds(i); // Updating terrain TerrainModify.UpdateArea(segments[i].m_bounds.min.x, segments[i].m_bounds.min.z, segments[i].m_bounds.max.x, segments[i].m_bounds.max.z, true, true, false); NetManager.instance.UpdateSegment(i); } // Is tunnel wrong way? if (IsEndTunnel(ref nodes[startNode])) { // Oops wrong way! Invert the segment segments[i].m_startNode = endNode; segments[i].m_endNode = startNode; Vector3 dir = segments[i].m_startDirection; segments[i].m_startDirection = segments[i].m_endDirection; segments[i].m_endDirection = dir; segments[i].m_flags = segments[i].m_flags ^ NetSegment.Flags.Invert; segments[i].CalculateSegment(i); } } } RoadPrefab.singleMode = singleMode; m_fixTunnelsCount = 0; }
public virtual void OnAfterSimulationTick() { if (m_buildingTool == null) { return; } // Removes HeightTooHigh & TooShort errors if (m_buildingTool.enabled) { ToolBase.ToolErrors errors = (ToolBase.ToolErrors)m_placementErrorsField.GetValue(m_buildingTool); if ((errors & ToolBase.ToolErrors.HeightTooHigh) == ToolBase.ToolErrors.HeightTooHigh) { errors = errors & ~ToolBase.ToolErrors.HeightTooHigh; m_placementErrorsField.SetValue(m_buildingTool, errors); } if ((errors & ToolBase.ToolErrors.TooShort) == ToolBase.ToolErrors.TooShort) { errors = errors & ~ToolBase.ToolErrors.TooShort; m_placementErrorsField.SetValue(m_buildingTool, errors); } } // Resume fixes if (m_fixNodesCount != 0 || m_fixTunnelsCount != 0) { RoadPrefab prefab = RoadPrefab.GetPrefab(m_current); if (prefab != null) { prefab.Restore(false); } if (m_fixTunnelsCount != 0) { FixTunnels(); } if (m_fixNodesCount != 0) { FixNodes(); } if (prefab != null) { prefab.Update(false); } } if (!isActive && !m_bulldozeTool.enabled) { return; } // Check if segment have been created/deleted/updated if (m_segmentCount != NetManager.instance.m_segmentCount || (bool)m_upgradingField.GetValue(m_netTool)) { m_segmentCount = NetManager.instance.m_segmentCount; RoadPrefab prefab = RoadPrefab.GetPrefab(m_current); if (prefab != null) { prefab.Restore(false); } m_fixTunnelsCount = 0; m_fixNodesCount = 0; FixTunnels(); FixNodes(); if (prefab != null) { prefab.Update(straightSlope); } } if (!isActive) { return; } // Fix first control point elevation int count = (int)m_controlPointCountField.GetValue(m_netTool); if (count != m_controlPointCount && m_controlPointCount == 0 && count == 1) { if (FixControlPoint(0)) { m_elevation = Mathf.RoundToInt(Mathf.RoundToInt(m_controlPoints[0].m_elevation / elevationStep) * elevationStep * 256f / 12f); UpdateElevation(); if (m_toolOptionButton != null) { m_toolOptionButton.UpdateInfo(); } } } // Fix last control point elevation else if (count == ((m_netTool.m_mode == NetTool.Mode.Curved || m_netTool.m_mode == NetTool.Mode.Freeform) ? 2 : 1)) { FixControlPoint(count); } m_controlPointCount = count; }
public void Start() { NetSkins_Support.Init(); // Getting NetTool m_netTool = GameObject.FindObjectOfType <NetTool>(); if (m_netTool == null) { DebugUtils.Warning("NetTool not found."); enabled = false; return; } // Getting BulldozeTool m_bulldozeTool = GameObject.FindObjectOfType <BulldozeTool>(); if (m_bulldozeTool == null) { DebugUtils.Warning("BulldozeTool not found."); enabled = false; return; } // Getting BuildingTool m_buildingTool = GameObject.FindObjectOfType <BuildingTool>(); if (m_buildingTool == null) { DebugUtils.Warning("BuildingTool not found."); enabled = false; return; } // Getting NetTool private fields m_elevationField = m_netTool.GetType().GetField("m_elevation", BindingFlags.NonPublic | BindingFlags.Instance); m_elevationUpField = m_netTool.GetType().GetField("m_buildElevationUp", BindingFlags.NonPublic | BindingFlags.Instance); m_elevationDownField = m_netTool.GetType().GetField("m_buildElevationDown", BindingFlags.NonPublic | BindingFlags.Instance); m_buildingElevationField = m_buildingTool.GetType().GetField("m_elevation", BindingFlags.NonPublic | BindingFlags.Instance); m_controlPointCountField = m_netTool.GetType().GetField("m_controlPointCount", BindingFlags.NonPublic | BindingFlags.Instance); m_upgradingField = m_netTool.GetType().GetField("m_upgrading", BindingFlags.NonPublic | BindingFlags.Instance); m_placementErrorsField = m_buildingTool.GetType().GetField("m_placementErrors", BindingFlags.NonPublic | BindingFlags.Instance); if (m_elevationField == null || m_elevationUpField == null || m_elevationDownField == null || m_buildingElevationField == null || m_controlPointCountField == null || m_upgradingField == null || m_placementErrorsField == null) { DebugUtils.Warning("NetTool fields not found"); m_netTool = null; enabled = false; return; } // Getting Upgrade button template try { m_upgradeButtonTemplate = GameObject.Find("RoadsSmallPanel").GetComponent <GeneratedScrollPanel>().m_OptionsBar.Find <UIButton>("Upgrade"); } catch { DebugUtils.Warning("Upgrade button template not found"); } // Creating UI CreateToolOptionsButton(); // Store segment count m_segmentCount = NetManager.instance.m_segmentCount; // Getting control points try { m_controlPoints = m_netTool.GetType().GetField("m_controlPoints", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(m_netTool) as NetTool.ControlPoint[]; m_cachedControlPoints = m_netTool.GetType().GetField("m_cachedControlPoints", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(m_netTool) as NetTool.ControlPoint[]; } catch { DebugUtils.Warning("ControlPoints not found"); } // Init dictionary RoadPrefab.Initialize(); m_inEditor = (ToolManager.instance.m_properties.m_mode & ItemClass.Availability.AssetEditor) != ItemClass.Availability.None; RoadPrefab.singleMode = m_inEditor; if (changeMaxTurnAngle.value) { RoadPrefab.SetMaxTurnAngle(maxTurnAngle.value); } // Update Catenary UpdateCatenary(); // Fix nodes FixNodes(); DebugUtils.Log("Initialized"); }
public void OnSettingsUI(UIHelperBase helper) { try { var group = helper.AddGroup(Name) as UIHelper; var panel = group.self as UIPanel; var checkBox = (UICheckBox)group.AddCheckbox("Disable debug messages logging", DebugUtils.hideDebugMessages.value, (b) => { DebugUtils.hideDebugMessages.value = b; }); checkBox.tooltip = "If checked, debug messages won't be logged."; group.AddSpace(10); checkBox = (UICheckBox)group.AddCheckbox("Reduce rail catenary masts", FineRoadTool.reduceCatenary.value, (b) => { FineRoadTool.reduceCatenary.value = b; if (FineRoadTool.instance != null) { FineRoadTool.instance.UpdateCatenary(); } }); checkBox.tooltip = "Reduce the number of catenary mast of rail lines from 3 to 1 per segment.\n"; group.AddSpace(10); checkBox = (UICheckBox)group.AddCheckbox("Change max turn angle for more realistic tram tracks turns", FineRoadTool.changeMaxTurnAngle.value, (b) => { FineRoadTool.changeMaxTurnAngle.value = b; if (b) { RoadPrefab.SetMaxTurnAngle(FineRoadTool.maxTurnAngle); } else { RoadPrefab.ResetMaxTurnAngle(); } }); checkBox.tooltip = "Change all roads with tram tracks max turn angle by the value below if current value is higher"; group.AddTextfield("Max turn angle: ", FineRoadTool.maxTurnAngle.ToString(), (f) => { }, (s) => { float.TryParse(s, out var f); FineRoadTool.maxTurnAngle.value = Mathf.Clamp(f, 0f, 180f); if (FineRoadTool.changeMaxTurnAngle.value) { RoadPrefab.SetMaxTurnAngle(FineRoadTool.maxTurnAngle.value); } }); group.AddSpace(10); panel.gameObject.AddComponent <OptionsKeymapping>(); group.AddSpace(10); group.AddButton("Reset tool window position", () => { UIToolOptionsButton.savedWindowX.Delete(); UIToolOptionsButton.savedWindowY.Delete(); if (UIToolOptionsButton.toolOptionsPanel) { UIToolOptionsButton.toolOptionsPanel.absolutePosition = new Vector3(-1000, -1000); } }); } catch (Exception e) { DebugUtils.Log("OnSettingsUI failed"); DebugUtils.LogException(e); } }
public static void Initialize() { m_roadPrefabs = new Dictionary <NetInfo, RoadPrefab>(); //string prefabsAdded = ""; for (uint i = 0; i < PrefabCollection <NetInfo> .PrefabCount(); i++) { NetInfo info = PrefabCollection <NetInfo> .GetPrefab(i); if (info == null) { continue; } RoadPrefab prefab = new RoadPrefab(info); if (prefab.m_hasElevation && prefab.isValid() && !m_roadPrefabs.ContainsKey(info)) { //prefabsAdded += info.name + "\n"; m_roadPrefabs.Add(info, prefab); if (info.m_flattenTerrain && !info.m_netAI.IsUnderground() && !prefab.m_roadAI.IsInvisible() && info != prefab.roadAI.elevated && info != prefab.roadAI.bridge && info != prefab.roadAI.slope && info != prefab.roadAI.tunnel) { info.m_followTerrain = false; } if (prefab.m_roadAI.elevated != null && !m_roadPrefabs.ContainsKey(prefab.m_roadAI.elevated)) { m_roadPrefabs.Add(prefab.m_roadAI.elevated, prefab); } if (prefab.m_roadAI.bridge != null && !m_roadPrefabs.ContainsKey(prefab.m_roadAI.bridge)) { m_roadPrefabs.Add(prefab.m_roadAI.bridge, prefab); } if (prefab.m_roadAI.slope != null && !m_roadPrefabs.ContainsKey(prefab.m_roadAI.slope)) { m_roadPrefabs.Add(prefab.m_roadAI.slope, prefab); } if (prefab.m_roadAI.tunnel != null && !m_roadPrefabs.ContainsKey(prefab.m_roadAI.tunnel)) { m_roadPrefabs.Add(prefab.m_roadAI.tunnel, prefab); } prefab.m_defaultMaxTurnAngle = info.m_maxTurnAngle; } } for (uint i = 0; i < PrefabCollection <NetInfo> .PrefabCount(); i++) { NetInfo info = PrefabCollection <NetInfo> .GetPrefab(i); if (info == null) { continue; } if (!m_roadPrefabs.ContainsKey(info)) { m_roadPrefabs.Add(info, new RoadPrefab(info)); if (info.m_flattenTerrain && !info.m_netAI.IsUnderground()) { info.m_followTerrain = false; } } } //DebugUtils.Log("Registered roads:\n" + prefabsAdded); }