private HashSet <Instance> GetMarqueeList(Ray mouseRay) { HashSet <Instance> list = new HashSet <Instance>(); Building[] buildingBuffer = BuildingManager.instance.m_buildings.m_buffer; PropInstance[] propBuffer = PropManager.instance.m_props.m_buffer; NetNode[] nodeBuffer = NetManager.instance.m_nodes.m_buffer; NetSegment[] segmentBuffer = NetManager.instance.m_segments.m_buffer; TreeInstance[] treeBuffer = TreeManager.instance.m_trees.m_buffer; m_selection.a = m_mouseStartPosition; m_selection.c = RaycastMouseLocation(mouseRay); if (m_selection.a.x == m_selection.c.x && m_selection.a.z == m_selection.c.z) { m_selection = default(Quad3); } else { float angle = Camera.main.transform.localEulerAngles.y * Mathf.Deg2Rad; Vector3 down = new Vector3(Mathf.Cos(angle), 0, -Mathf.Sin(angle)); Vector3 right = new Vector3(-down.z, 0, down.x); Vector3 a = m_selection.c - m_selection.a; float dotDown = Vector3.Dot(a, down); float dotRight = Vector3.Dot(a, right); if ((dotDown > 0 && dotRight > 0) || (dotDown <= 0 && dotRight <= 0)) { m_selection.b = m_selection.a + dotDown * down; m_selection.d = m_selection.a + dotRight * right; } else { m_selection.b = m_selection.a + dotRight * right; m_selection.d = m_selection.a + dotDown * down; } // Disables select-during-drag //if (ToolState == ToolStates.DrawingSelection) //{ // return list; //} Vector3 min = m_selection.Min(); Vector3 max = m_selection.Max(); int gridMinX = Mathf.Max((int)((min.x - 16f) / 64f + 135f), 0); int gridMinZ = Mathf.Max((int)((min.z - 16f) / 64f + 135f), 0); int gridMaxX = Mathf.Min((int)((max.x + 16f) / 64f + 135f), 269); int gridMaxZ = Mathf.Min((int)((max.z + 16f) / 64f + 135f), 269); InstanceID id = new InstanceID(); ItemClass.Layer itemLayers = GetItemLayers(); if (!HidePO && PO.Active && filterProcs) { //string msg = ""; foreach (IPO_Object obj in PO.Objects) { if (PointInRectangle(m_selection, obj.Position)) { //msg += $"{obj.Id},"; id.NetLane = obj.Id; list.Add(id); } } //Debug.Log(msg); } for (int i = gridMinZ; i <= gridMaxZ; i++) { for (int j = gridMinX; j <= gridMaxX; j++) { if (filterBuildings || filterSurfaces) { ushort building = BuildingManager.instance.m_buildingGrid[i * 270 + j]; int count = 0; while (building != 0u) { //Debug.Log($"Building:{building}"); if (IsBuildingValid(ref buildingBuffer[building], itemLayers) && PointInRectangle(m_selection, buildingBuffer[building].m_position)) { if (Filters.Filter(buildingBuffer[building].Info)) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } list.Add(id); } } building = buildingBuffer[building].m_nextGridBuilding; if (++count > 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } if (filterProps || filterDecals || filterSurfaces) { ushort prop = PropManager.instance.m_propGrid[i * 270 + j]; int count = 0; while (prop != 0u) { //Debug.Log($"Prop:{prop}"); if (Filters.Filter(propBuffer[prop].Info)) { if (PointInRectangle(m_selection, propBuffer[prop].Position)) { id.Prop = prop; list.Add(id); } } prop = propBuffer[prop].m_nextGridProp; if (++count > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); } } } if (filterNodes || filterBuildings) { ushort node = NetManager.instance.m_nodeGrid[i * 270 + j]; int count = 0; while (node != 0u) { //Debug.Log($"Node:{node}"); if (IsNodeValid(ref nodeBuffer[node], itemLayers) && PointInRectangle(m_selection, nodeBuffer[node].m_position)) { ushort building = NetNode.FindOwnerBuilding(node, 363f); if (building != 0) { if (filterBuildings) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } list.Add(id); } } else if (filterNodes) { if (Filters.Filter(nodeBuffer[node])) { //Debug.Log($"Node:{node}"); id.NetNode = node; list.Add(id); } } } node = nodeBuffer[node].m_nextGridNode; if (++count > 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); } } } if (filterSegments || filterBuildings) { ushort segment = NetManager.instance.m_segmentGrid[i * 270 + j]; int count = 0; while (segment != 0u) { //Debug.Log($"Segment:{segment}"); if (IsSegmentValid(ref segmentBuffer[segment], itemLayers) && PointInRectangle(m_selection, segmentBuffer[segment].m_bounds.center)) { ushort building = FindOwnerBuilding(segment, 363f); if (building != 0) { if (filterBuildings) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } list.Add(id); } } else if (filterSegments) { if (Filters.Filter(segmentBuffer[segment])) { id.NetSegment = segment; list.Add(id); } } } segment = segmentBuffer[segment].m_nextGridSegment; if (++count > 36864) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); } } } } } if (filterTrees) { gridMinX = Mathf.Max((int)((min.x - 8f) / 32f + 270f), 0); gridMinZ = Mathf.Max((int)((min.z - 8f) / 32f + 270f), 0); gridMaxX = Mathf.Min((int)((max.x + 8f) / 32f + 270f), 539); gridMaxZ = Mathf.Min((int)((max.z + 8f) / 32f + 270f), 539); for (int i = gridMinZ; i <= gridMaxZ; i++) { for (int j = gridMinX; j <= gridMaxX; j++) { uint tree = TreeManager.instance.m_treeGrid[i * 540 + j]; int count = 0; while (tree != 0) { //Debug.Log($"Tree:{tree}"); if (PointInRectangle(m_selection, treeBuffer[tree].Position)) { id.Tree = tree; list.Add(id); } tree = treeBuffer[tree].m_nextGridTree; if (++count > 262144) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); } } } } } } return(list); }
private HashSet <Instance> GetMarqueeList(Ray mouseRay) { HashSet <Instance> list = new HashSet <Instance>(); Building[] buildingBuffer = Singleton <BuildingManager> .instance.m_buildings.m_buffer; NetNode[] nodeBuffer = Singleton <NetManager> .instance.m_nodes.m_buffer; NetSegment[] segmentBuffer = Singleton <NetManager> .instance.m_segments.m_buffer; TreeInstance[] treeBuffer = Singleton <TreeManager> .instance.m_trees.m_buffer; m_selection.a = m_clickPositionAbs; m_selection.c = RaycastMouseLocation(mouseRay); if (m_selection.a.x == m_selection.c.x && m_selection.a.z == m_selection.c.z) { m_selection = default; } else { float angle = Camera.main.transform.localEulerAngles.y * Mathf.Deg2Rad; Vector3 down = new Vector3(Mathf.Cos(angle), 0, -Mathf.Sin(angle)); Vector3 right = new Vector3(-down.z, 0, down.x); Vector3 a = m_selection.c - m_selection.a; float dotDown = Vector3.Dot(a, down); float dotRight = Vector3.Dot(a, right); if ((dotDown > 0 && dotRight > 0) || (dotDown <= 0 && dotRight <= 0)) { m_selection.b = m_selection.a + dotDown * down; m_selection.d = m_selection.a + dotRight * right; } else { m_selection.b = m_selection.a + dotRight * right; m_selection.d = m_selection.a + dotDown * down; } Vector3 min = m_selection.Min(); Vector3 max = m_selection.Max(); int gridMinX = Mathf.Max((int)((min.x - 16f) / 64f + 135f), 0); int gridMinZ = Mathf.Max((int)((min.z - 16f) / 64f + 135f), 0); int gridMaxX = Mathf.Min((int)((max.x + 16f) / 64f + 135f), 269); int gridMaxZ = Mathf.Min((int)((max.z + 16f) / 64f + 135f), 269); InstanceID id = new InstanceID(); ItemClass.Layer itemLayers = GetItemLayers(); if (PO.Active && (filterProcs || filterPicker)) { foreach (PO_Object obj in PO.Objects) { if (!filterProcs) { // Implies filterPicker is true if (obj.GetPrefab() != Filters.Picker.Info) { continue; } } if (!obj.isHidden() && PointInRectangle(m_selection, obj.Position)) { id.NetLane = obj.Id; list.AddObject(id); } } } for (int i = gridMinZ; i <= gridMaxZ; i++) { for (int j = gridMinX; j <= gridMaxX; j++) { if (filterBuildings || filterSurfaces || (filterPicker && Filters.Picker.IsBuilding)) { ushort building = BuildingManager.instance.m_buildingGrid[i * 270 + j]; int count = 0; while (building != 0u) { if (IsBuildingValid(ref buildingBuffer[building], itemLayers) && PointInRectangle(m_selection, buildingBuffer[building].m_position)) { if (Filters.Filter(buildingBuffer[building].Info, ref buildingBuffer[building])) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } list.Add(id); } } building = buildingBuffer[building].m_nextGridBuilding; if (++count > 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Buildings: Invalid list detected!\n" + Environment.StackTrace); break; } } } if (filterProps || filterDecals || filterSurfaces || (filterPicker && Filters.Picker.IsProp)) { PropLayer.Manager.GetMarqueeList(ref i, ref j, ref id, ref m_selection, ref list); } if (filterNodes || filterBuildings || (filterPicker && Filters.Picker.IsNode)) { ushort node = NetManager.instance.m_nodeGrid[i * 270 + j]; int count = 0; while (node != 0u) { if (IsNodeValid(ref nodeBuffer[node], itemLayers) && PointInRectangle(m_selection, nodeBuffer[node].m_position)) { ushort building = NetNode.FindOwnerBuilding(node, 363f); if (building != 0) { if (filterBuildings) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } list.Add(id); } } else if (filterNodes || (filterPicker && Filters.Picker.IsNode)) { if (Filters.Filter(nodeBuffer[node])) { id.NetNode = node; list.Add(id); } } } node = nodeBuffer[node].m_nextGridNode; if (++count > 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Nodes: Invalid list detected!\n" + Environment.StackTrace); } } } if (filterSegments || filterBuildings || (filterPicker && Filters.Picker.IsSegment)) { ushort segment = NetManager.instance.m_segmentGrid[i * 270 + j]; int count = 0; while (segment != 0u) { if (IsSegmentValid(ref segmentBuffer[segment], itemLayers) && PointInRectangle(m_selection, segmentBuffer[segment].m_bounds.center)) { ushort building = FindOwnerBuilding(segment, 363f); if (building != 0) { if (filterBuildings) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } list.Add(id); } } else if (filterSegments || (filterPicker && Filters.Picker.IsSegment)) { if (Filters.Filter(segmentBuffer[segment])) { id.NetSegment = segment; list.Add(id); } } } segment = segmentBuffer[segment].m_nextGridSegment; if (++count > 36864) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Segments: Invalid list detected!\n" + Environment.StackTrace); } } } } } if (filterTrees || (filterPicker && Filters.Picker.IsTree)) { gridMinX = Mathf.Max((int)((min.x - 8f) / 32f + 270f), 0); gridMinZ = Mathf.Max((int)((min.z - 8f) / 32f + 270f), 0); gridMaxX = Mathf.Min((int)((max.x + 8f) / 32f + 270f), 539); gridMaxZ = Mathf.Min((int)((max.z + 8f) / 32f + 270f), 539); for (int i = gridMinZ; i <= gridMaxZ; i++) { for (int j = gridMinX; j <= gridMaxX; j++) { uint tree = TreeManager.instance.m_treeGrid[i * 540 + j]; while (tree != 0) { if (PointInRectangle(m_selection, treeBuffer[tree].Position)) { if (Filters.Filter(treeBuffer[tree].Info)) { id.Tree = tree; list.Add(id); } } tree = treeBuffer[tree].m_nextGridTree; } } } } } return(list); }
private void RaycastHoverInstance(Ray mouseRay) { Vector3 origin = mouseRay.origin; Vector3 normalized = mouseRay.direction.normalized; Vector3 vector = mouseRay.origin + normalized * Camera.main.farClipPlane; Segment3 ray = new Segment3(origin, vector); Building[] buildingBuffer = BuildingManager.instance.m_buildings.m_buffer; PropInstance[] propBuffer = PropManager.instance.m_props.m_buffer; NetNode[] nodeBuffer = NetManager.instance.m_nodes.m_buffer; NetSegment[] segmentBuffer = NetManager.instance.m_segments.m_buffer; TreeInstance[] treeBuffer = TreeManager.instance.m_trees.m_buffer; Vector3 location = RaycastMouseLocation(mouseRay); InstanceID id = InstanceID.Empty; ItemClass.Layer itemLayers = GetItemLayers(); bool selectBuilding = true; bool selectProps = true; bool selectDecals = true; bool selectSurfaces = true; bool selectNodes = true; bool selectSegments = true; bool selectTrees = true; bool selectProc = PO.Active; bool repeatSearch = false; if (marqueeSelection) { selectBuilding = filterBuildings; selectProps = filterProps; selectDecals = filterDecals; selectSurfaces = filterSurfaces; selectNodes = filterNodes; selectSegments = filterSegments; selectTrees = filterTrees; selectProc = PO.Active ? filterProcs : false; } float smallestDist = 640000f; do { if (!HidePO && PO.Active && selectProc) { //string msg = ""; foreach (IPO_Object obj in PO.Objects) { if (stepOver.isValidPO(obj.Id)) { //msg += $"{obj.Id},"; bool inXBounds = obj.Position.x > (location.x - 4f) && obj.Position.x < (location.x + 4f); bool inZBounds = obj.Position.z > (location.z - 4f) && obj.Position.z < (location.z + 4f); if (inXBounds && inZBounds) { float t = obj.GetDistance(location); //Debug.Log($"Object {obj.Id}: {t}m"); if (t < smallestDist) { id.NetLane = obj.Id; smallestDist = t; } } } } //Debug.Log(msg); } int gridMinX = Mathf.Max((int)((location.x - 16f) / 64f + 135f) - 1, 0); int gridMinZ = Mathf.Max((int)((location.z - 16f) / 64f + 135f) - 1, 0); int gridMaxX = Mathf.Min((int)((location.x + 16f) / 64f + 135f) + 1, 269); int gridMaxZ = Mathf.Min((int)((location.z + 16f) / 64f + 135f) + 1, 269); for (int i = gridMinZ; i <= gridMaxZ; i++) { for (int j = gridMinX; j <= gridMaxX; j++) { if (selectBuilding || selectSurfaces) { ushort building = BuildingManager.instance.m_buildingGrid[i * 270 + j]; int count = 0; while (building != 0u) { if (stepOver.isValidB(building) && IsBuildingValid(ref buildingBuffer[building], itemLayers) && buildingBuffer[building].RayCast(building, ray, out float t) && t < smallestDist) { if (Filters.Filter(buildingBuffer[building].Info, true)) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } smallestDist = t; } } building = buildingBuffer[building].m_nextGridBuilding; if (++count > 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } if (selectProps || selectDecals || selectSurfaces) { ushort prop = PropManager.instance.m_propGrid[i * 270 + j]; int count = 0; while (prop != 0u) { if (stepOver.isValidP(prop) && Filters.Filter(propBuffer[prop].Info)) { //Debug.Log($"Prop:{prop}"); if (propBuffer[prop].RayCast(prop, ray, out float t, out float targetSqr) && t < smallestDist) { id.Prop = prop; smallestDist = t; } } prop = propBuffer[prop].m_nextGridProp; if (++count > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); } } } if (selectNodes || selectBuilding) { ushort node = NetManager.instance.m_nodeGrid[i * 270 + j]; int count = 0; while (node != 0u) { if (stepOver.isValidN(node) && IsNodeValid(ref nodeBuffer[node], itemLayers) && RayCastNode(ref nodeBuffer[node], ray, -1000f, out float t, out float priority) && t < smallestDist) { //Debug.Log($"Node:{node}"); ushort building = 0; if (!Event.current.alt) { building = NetNode.FindOwnerBuilding(node, 363f); } if (building != 0) { if (selectBuilding) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } smallestDist = t; } } else if (selectNodes) { if (Filters.Filter(nodeBuffer[node])) { id.NetNode = node; smallestDist = t; } } } node = nodeBuffer[node].m_nextGridNode; if (++count > 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); } } } if (selectSegments || selectBuilding) { ushort segment = NetManager.instance.m_segmentGrid[i * 270 + j]; int count = 0; while (segment != 0u) { if (stepOver.isValidS(segment) && IsSegmentValid(ref segmentBuffer[segment], itemLayers) && segmentBuffer[segment].RayCast(segment, ray, -1000f, false, out float t, out float priority) && t < smallestDist) { //Debug.Log($"Segment:{segment}"); ushort building = 0; if (!Event.current.alt) { building = FindOwnerBuilding(segment, 363f); } if (building != 0) { if (selectBuilding) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } smallestDist = t; } } else if (selectSegments) { if (!selectNodes || ( (!stepOver.isValidN(segmentBuffer[segment].m_startNode) || !RayCastNode(ref nodeBuffer[segmentBuffer[segment].m_startNode], ray, -1000f, out float t2, out priority)) && (!stepOver.isValidN(segmentBuffer[segment].m_endNode) || !RayCastNode(ref nodeBuffer[segmentBuffer[segment].m_endNode], ray, -1000f, out t2, out priority)) )) { if (Filters.Filter(segmentBuffer[segment])) { id.NetSegment = segment; smallestDist = t; } } } } segment = segmentBuffer[segment].m_nextGridSegment; if (++count > 36864) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); } } } } } if (selectTrees) { gridMinX = Mathf.Max((int)((location.x - 8f) / 32f + 270f), 0); gridMinZ = Mathf.Max((int)((location.z - 8f) / 32f + 270f), 0); gridMaxX = Mathf.Min((int)((location.x + 8f) / 32f + 270f), 539); gridMaxZ = Mathf.Min((int)((location.z + 8f) / 32f + 270f), 539); for (int i = gridMinZ; i <= gridMaxZ; i++) { for (int j = gridMinX; j <= gridMaxX; j++) { uint tree = TreeManager.instance.m_treeGrid[i * 540 + j]; int count = 0; while (tree != 0) { if (stepOver.isValidT(tree) && treeBuffer[tree].RayCast(tree, ray, out float t, out float targetSqr) && t < smallestDist) { id.Tree = tree; smallestDist = t; } tree = treeBuffer[tree].m_nextGridTree; if (++count > 262144) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); } } } } } repeatSearch = false; if (OptionsKeymapping.stepOverKey.IsPressed()) { if (!_stepProcessed) { _stepProcessed = true; repeatSearch = true; stepOver.Add(id); } } else { _stepProcessed = false; } }while (repeatSearch); //Debug.Log($"Id={InstanceIDDebug(id)}"); if (debugPanel != null) { debugPanel.Update(id); } m_hoverInstance = id; }
private void RaycastHoverInstance(Ray mouseRay) { Vector3 origin = mouseRay.origin; Vector3 normalized = mouseRay.direction.normalized; Vector3 vector = mouseRay.origin + normalized * Camera.main.farClipPlane; Segment3 ray = new Segment3(origin, vector); Building[] buildingBuffer = Singleton <BuildingManager> .instance.m_buildings.m_buffer; NetNode[] nodeBuffer = Singleton <NetManager> .instance.m_nodes.m_buffer; NetSegment[] segmentBuffer = Singleton <NetManager> .instance.m_segments.m_buffer; TreeInstance[] treeBuffer = Singleton <TreeManager> .instance.m_trees.m_buffer; Vector3 location = RaycastMouseLocation(mouseRay); InstanceID id = InstanceID.Empty; ItemClass.Layer itemLayers = GetItemLayers(); bool selectPicker = false; bool selectBuilding = true; bool selectProps = true; bool selectDecals = true; bool selectSurfaces = true; bool selectNodes = true; bool selectSegments = true; bool selectTrees = true; bool selectProc = PO.Active; if (marqueeSelection) { selectPicker = filterPicker; selectBuilding = filterBuildings; selectProps = filterProps; selectDecals = filterDecals; selectSurfaces = filterSurfaces; selectNodes = filterNodes; selectSegments = filterSegments; selectTrees = filterTrees; selectProc = PO.Active && filterProcs; } if (MT_Tool == MT_Tools.Group || MT_Tool == MT_Tools.Inplace) { selectNodes = false; selectTrees = false; } else if (MT_Tool == MT_Tools.Mirror) { selectBuilding = false; selectProps = false; selectDecals = false; selectSurfaces = false; selectProc = false; selectTrees = false; selectNodes = false; } float smallestDist = 640000f; bool repeatSearch; do { if (PO.Active && (selectProc || selectPicker)) { foreach (PO_Object obj in PO.Objects) { if (!obj.isHidden() && stepOver.isValidPO(obj.Id)) { if (!selectProc) { // Implies selectPicker is true if (obj.GetPrefab() != Filters.Picker.Info) { continue; } } float radius = obj.Size / 2; bool inXBounds = obj.Position.x > (location.x - radius) && obj.Position.x < (location.x + radius); bool inZBounds = obj.Position.z > (location.z - radius) && obj.Position.z < (location.z + radius); if (inXBounds && inZBounds) { float t = obj.GetDistance(location); if (t < smallestDist) { id.NetLane = obj.Id; smallestDist = t; } } } } } int gridMinX = Mathf.Max((int)((location.x - 16f) / 64f + 135f) - 1, 0); int gridMinZ = Mathf.Max((int)((location.z - 16f) / 64f + 135f) - 1, 0); int gridMaxX = Mathf.Min((int)((location.x + 16f) / 64f + 135f) + 1, 269); int gridMaxZ = Mathf.Min((int)((location.z + 16f) / 64f + 135f) + 1, 269); for (int i = gridMinZ; i <= gridMaxZ; i++) { for (int j = gridMinX; j <= gridMaxX; j++) { if (selectBuilding || selectSurfaces || (selectPicker && Filters.Picker.IsBuilding)) { ushort building = BuildingManager.instance.m_buildingGrid[i * 270 + j]; int count = 0; while (building != 0u) { if (stepOver.isValidB(building) && IsBuildingValid(ref buildingBuffer[building], itemLayers) && buildingBuffer[building].RayCast(building, ray, out float t) && t < smallestDist) { if (Filters.Filter(buildingBuffer[building].Info, ref buildingBuffer[building], true)) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } smallestDist = t; } } building = buildingBuffer[building].m_nextGridBuilding; if (++count > 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Buildings: Invalid list detected!\n" + Environment.StackTrace); break; } } } if (selectProps || selectDecals || selectSurfaces || (selectPicker && Filters.Picker.IsProp)) { PropLayer.Manager.RaycastHoverInstance(ref i, ref j, ref stepOver, ref ray, ref smallestDist, ref id); } if (selectNodes || selectBuilding || (selectPicker && Filters.Picker.IsNode)) { ushort node = NetManager.instance.m_nodeGrid[i * 270 + j]; int count = 0; while (node != 0u) { if (stepOver.isValidN(node) && IsNodeValid(ref nodeBuffer[node], itemLayers) && RayCastNode(ref nodeBuffer[node], ray, -1000f, out float t, out float priority) && t < smallestDist) { ushort building = 0; if (!Event.current.alt) { building = NetNode.FindOwnerBuilding(node, 363f); } if (building != 0) { if (selectBuilding) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } smallestDist = t; } } else if (selectNodes || (selectPicker && Filters.Picker.IsNode)) { if (Filters.Filter(nodeBuffer[node])) { id.NetNode = node; smallestDist = t; } } } node = nodeBuffer[node].m_nextGridNode; if (++count > 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Nodes: Invalid list detected!\n" + Environment.StackTrace); } } } if (selectSegments || selectBuilding || (selectPicker && Filters.Picker.IsSegment)) { ushort segment = NetManager.instance.m_segmentGrid[i * 270 + j]; int count = 0; while (segment != 0u) { if (stepOver.isValidS(segment) && IsSegmentValid(ref segmentBuffer[segment], itemLayers) && segmentBuffer[segment].RayCast(segment, ray, -1000f, false, out float t, out float priority) && t < smallestDist) { ushort building = 0; if (!Event.current.alt) { building = FindOwnerBuilding(segment, 363f); } if (building != 0) { if (selectBuilding) { id.Building = Building.FindParentBuilding(building); if (id.Building == 0) { id.Building = building; } smallestDist = t; } } else if (selectSegments || (selectPicker && Filters.Picker.IsSegment)) { if (!selectNodes || ( (!stepOver.isValidN(segmentBuffer[segment].m_startNode) || !RayCastNode(ref nodeBuffer[segmentBuffer[segment].m_startNode], ray, -1000f, out float t2, out priority)) && (!stepOver.isValidN(segmentBuffer[segment].m_endNode) || !RayCastNode(ref nodeBuffer[segmentBuffer[segment].m_endNode], ray, -1000f, out t2, out priority)) )) { if (Filters.Filter(segmentBuffer[segment])) { id.NetSegment = segment; smallestDist = t; } } } } segment = segmentBuffer[segment].m_nextGridSegment; if (++count > 36864) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Segments: Invalid list detected!\n" + Environment.StackTrace); segment = 0; } } } } } if (selectTrees || (selectPicker && Filters.Picker.IsTree)) { gridMinX = Mathf.Max((int)((location.x - 8f) / 32f + 270f), 0); gridMinZ = Mathf.Max((int)((location.z - 8f) / 32f + 270f), 0); gridMaxX = Mathf.Min((int)((location.x + 8f) / 32f + 270f), 539); gridMaxZ = Mathf.Min((int)((location.z + 8f) / 32f + 270f), 539); for (int i = gridMinZ; i <= gridMaxZ; i++) { for (int j = gridMinX; j <= gridMaxX; j++) { uint tree = TreeManager.instance.m_treeGrid[i * 540 + j]; while (tree != 0) { if (stepOver.isValidT(tree) && treeBuffer[tree].RayCast(tree, ray, out float t, out float targetSqr) && t < smallestDist) { if (Filters.Filter(treeBuffer[tree].Info)) { id.Tree = tree; smallestDist = t; } } tree = treeBuffer[tree].m_nextGridTree; } } } } repeatSearch = false; if (OptionsKeymapping.stepOverKey.IsPressed()) { if (!_stepProcessed) { _stepProcessed = true; repeatSearch = true; stepOver.Add(id); } } else { _stepProcessed = false; } }while (repeatSearch); m_hoverInstance = id; m_debugPanel?.UpdatePanel(id); ActionQueue.instance.current?.OnHover(); }