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 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; }