private static float CalculateCameraHeightOffset(Vector3 worldPos, float distance) { float num = TerrainManager.instance.SampleRawHeightSmoothWithWater(worldPos, true, 2f); float num2 = num - worldPos.y; distance *= 0.45f; num2 = Mathf.Max(num2, -distance); num2 += distance * 0.375f * Mathf.Pow(1f + 1f / distance, -num2); num = worldPos.y + num2; ItemClass.Availability mode = ToolManager.instance.m_properties.m_mode; if ((mode & ItemClass.Availability.AssetEditor) == ItemClass.Availability.None) { ItemClass.Layer layer = ItemClass.Layer.Default; if ((mode & ItemClass.Availability.MapEditor) != ItemClass.Availability.None) { layer |= ItemClass.Layer.Markers; } worldPos.y -= 5f; num = Mathf.Max(num, BuildingManager.instance.SampleSmoothHeight(worldPos, layer) + 5f); num = Mathf.Max(num, NetManager.instance.SampleSmoothHeight(worldPos) + 5f); num = Mathf.Max(num, PropManager.instance.SampleSmoothHeight(worldPos) + 5f); num = Mathf.Max(num, TreeManager.instance.SampleSmoothHeight(worldPos) + 5f); worldPos.y += 5f; } return(num - worldPos.y); }
private ItemClass.Layer GetItemLayers() { ItemClass.Layer itemLayers = ItemClass.Layer.Default; if (InfoManager.instance.CurrentMode == InfoManager.InfoMode.Water) { itemLayers |= ItemClass.Layer.WaterPipes; } if (InfoManager.instance.CurrentMode == InfoManager.InfoMode.Fishing) { itemLayers |= ItemClass.Layer.FishingPaths; } else if (InfoManager.instance.CurrentMode == InfoManager.InfoMode.Transport) { // Removes Default assignment itemLayers = ItemClass.Layer.MetroTunnels | ItemClass.Layer.BlimpPaths | ItemClass.Layer.FerryPaths | ItemClass.Layer.ShipPaths | ItemClass.Layer.AirplanePaths | ItemClass.Layer.HelicopterPaths; } else if (InfoManager.instance.CurrentMode == InfoManager.InfoMode.Traffic || InfoManager.instance.CurrentMode == InfoManager.InfoMode.Transport) { itemLayers |= ItemClass.Layer.MetroTunnels; } else if (InfoManager.instance.CurrentMode == InfoManager.InfoMode.Underground) { // Removes Default assignment itemLayers = ItemClass.Layer.MetroTunnels; } else { itemLayers |= ItemClass.Layer.Markers; } return(itemLayers); }
private bool IsBuildingValid(ref Building building, ItemClass.Layer itemLayers) { if ((building.m_flags & Building.Flags.Created) == Building.Flags.Created) { return((building.Info.m_class.m_layer & itemLayers) != ItemClass.Layer.None); } return(false); }
private bool IsNodeValid(ref NetNode node, ItemClass.Layer itemLayers) { if ((node.m_flags & NetNode.Flags.Created) == NetNode.Flags.Created) { return((node.Info.GetConnectionClass().m_layer & itemLayers) != ItemClass.Layer.None); } return(false); }
private bool IsSegmentValid(ref NetSegment segment, ItemClass.Layer itemLayers) { if ((segment.m_flags & NetSegment.Flags.Created) == NetSegment.Flags.Created) { return((segment.Info.GetConnectionClass().m_layer & itemLayers) != ItemClass.Layer.None); } return(false); }
private bool IsSegmentValid(ref NetSegment segment, ItemClass.Layer itemLayers) { //Debug.Log($"S:{segment.Info.name} - {segment.m_flags}\n{segment.m_startNode},{segment.m_endNode}"); if ((segment.m_flags & NetSegment.Flags.Created) == NetSegment.Flags.Created) { return((segment.Info.GetConnectionClass().m_layer & itemLayers) != ItemClass.Layer.None); } return(false); }
internal void ResetSubInstances() { List <Instance> instances = new List <Instance>(); int count = 0; if (!isSubInstance) { ushort building = buildingBuffer[id.Building].m_subBuilding; while (building != 0) { InstanceID buildingID = default; buildingID.Building = building; instances.Add(new MoveableBuilding(buildingID, true)); building = buildingBuffer[building].m_subBuilding; if (++count > 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Buildings: Invalid list detected!\n" + Environment.StackTrace); break; } } } ushort node = buildingBuffer[id.Building].m_netNode; count = 0; while (node != 0) { ItemClass.Layer layer = nodeBuffer[node].Info.m_class.m_layer; if (layer != ItemClass.Layer.PublicTransport) { InstanceID nodeID = default; nodeID.NetNode = node; instances.Add(new MoveableNode(nodeID)); } node = nodeBuffer[node].m_nextBuildingNode; if ((nodeBuffer[node].m_flags & NetNode.Flags.Created) != NetNode.Flags.Created) { node = 0; } if (++count > 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Nodes: Invalid list detected!\n" + Environment.StackTrace); break; } } subInstances = instances; }
private ItemClass.Layer GetItemLayers() { ItemClass.Layer layer = ItemClass.Layer.Default; if (Singleton <InfoManager> .instance.CurrentMode == InfoManager.InfoMode.Water) { layer |= ItemClass.Layer.WaterPipes; } if (Singleton <InfoManager> .instance.CurrentMode == InfoManager.InfoMode.Underground || Singleton <InfoManager> .instance.CurrentMode == InfoManager.InfoMode.Traffic || Singleton <InfoManager> .instance.CurrentMode == InfoManager.InfoMode.Transport) { layer |= ItemClass.Layer.MetroTunnels; } return(layer); }
private static bool FindConnectNode(FastList <ushort> buffer, Vector3 pos, NetInfo info2, out NetTool.ControlPoint point) { point = default(NetTool.ControlPoint); NetManager instance = Singleton <NetManager> .instance; ItemClass.Service service = info2.m_class.m_service; ItemClass.SubService subService = info2.m_class.m_subService; ItemClass.Layer layer = info2.m_class.m_layer; ItemClass.Service service2 = ItemClass.Service.None; ItemClass.SubService subService2 = ItemClass.SubService.None; ItemClass.Layer layer2 = ItemClass.Layer.Default; if (info2.m_intersectClass != null) { service2 = info2.m_intersectClass.m_service; subService2 = info2.m_intersectClass.m_subService; layer2 = info2.m_intersectClass.m_layer; } if (info2.m_netAI.SupportUnderground() || info2.m_netAI.IsUnderground()) { layer |= (ItemClass.Layer.Default | ItemClass.Layer.MetroTunnels); layer2 |= (ItemClass.Layer.Default | ItemClass.Layer.MetroTunnels); } for (int i = 0; i < buffer.m_size; i++) { ushort num = buffer.m_buffer[i]; if (Vector3.SqrMagnitude(pos - instance.m_nodes.m_buffer[(int)num].m_position) < 0.001f) { NetInfo info3 = instance.m_nodes.m_buffer[(int)num].Info; ItemClass connectionClass = info3.GetConnectionClass(); if (((service == ItemClass.Service.None || connectionClass.m_service == service) && (subService == ItemClass.SubService.None || connectionClass.m_subService == subService) && (layer == ItemClass.Layer.None || (connectionClass.m_layer & layer) != ItemClass.Layer.None)) || (info3.m_intersectClass != null && (service == ItemClass.Service.None || info3.m_intersectClass.m_service == service) && (subService == ItemClass.SubService.None || info3.m_intersectClass.m_subService == subService) && (layer == ItemClass.Layer.None || (info3.m_intersectClass.m_layer & layer) != ItemClass.Layer.None)) || (connectionClass.m_service == service2 && (subService2 == ItemClass.SubService.None || connectionClass.m_subService == subService2) && (layer2 == ItemClass.Layer.None || (connectionClass.m_layer & layer2) != ItemClass.Layer.None))) { point.m_position = instance.m_nodes.m_buffer[(int)num].m_position; point.m_direction = Vector3.zero; point.m_node = num; point.m_segment = 0; if (info3.m_netAI.IsUnderground()) { point.m_elevation = (float)(-(float)instance.m_nodes.m_buffer[(int)num].m_elevation); } else { point.m_elevation = (float)instance.m_nodes.m_buffer[(int)num].m_elevation; } return(true); } } } return(false); }
private static bool RequireFixedHeight(BuildingInfo buildingInfo, NetInfo info2, Vector3 pos) { if (info2.m_useFixedHeight) { return(true); } ItemClass.Service service = info2.m_class.m_service; ItemClass.SubService subService = info2.m_class.m_subService; ItemClass.Layer layer = info2.m_class.m_layer; ItemClass.Service service2 = ItemClass.Service.None; ItemClass.SubService subService2 = ItemClass.SubService.None; ItemClass.Layer layer2 = ItemClass.Layer.Default; if (info2.m_intersectClass != null) { service2 = info2.m_intersectClass.m_service; subService2 = info2.m_intersectClass.m_subService; layer2 = info2.m_intersectClass.m_layer; } if (info2.m_netAI.SupportUnderground() || info2.m_netAI.IsUnderground()) { layer |= (ItemClass.Layer.Default | ItemClass.Layer.MetroTunnels); layer2 |= (ItemClass.Layer.Default | ItemClass.Layer.MetroTunnels); } for (int i = 0; i < buildingInfo.m_paths.Length; i++) { BuildingInfo.PathInfo pathInfo = buildingInfo.m_paths[i]; if (pathInfo.m_finalNetInfo != null && pathInfo.m_finalNetInfo.m_useFixedHeight && pathInfo.m_nodes != null && pathInfo.m_nodes.Length != 0) { for (int j = 0; j < pathInfo.m_nodes.Length; j++) { if (Vector3.SqrMagnitude(pos - pathInfo.m_nodes[j]) < 0.001f) { NetInfo finalNetInfo = pathInfo.m_finalNetInfo; ItemClass connectionClass = finalNetInfo.GetConnectionClass(); if (((service == ItemClass.Service.None || connectionClass.m_service == service) && (subService == ItemClass.SubService.None || connectionClass.m_subService == subService) && (layer == ItemClass.Layer.None || (connectionClass.m_layer & layer) != ItemClass.Layer.None)) || (finalNetInfo.m_intersectClass != null && (service == ItemClass.Service.None || finalNetInfo.m_intersectClass.m_service == service) && (subService == ItemClass.SubService.None || finalNetInfo.m_intersectClass.m_subService == subService) && (layer == ItemClass.Layer.None || (finalNetInfo.m_intersectClass.m_layer & layer) != ItemClass.Layer.None)) || (finalNetInfo.m_netAI.CanIntersect(info2) && connectionClass.m_service == service2 && (subService2 == ItemClass.SubService.None || connectionClass.m_subService == subService2) && (layer2 == ItemClass.Layer.None || (connectionClass.m_layer & layer2) != ItemClass.Layer.None))) { return(true); } } } } } return(false); }
private ItemClass.Layer GetItemLayers() { ItemClass.Layer itemLayers = ItemClass.Layer.Default; if (InfoManager.instance.CurrentMode == InfoManager.InfoMode.Water) { itemLayers = itemLayers | ItemClass.Layer.WaterPipes; } if (InfoManager.instance.CurrentMode == InfoManager.InfoMode.Traffic || InfoManager.instance.CurrentMode == InfoManager.InfoMode.Transport) { itemLayers = itemLayers | ItemClass.Layer.MetroTunnels; } if (InfoManager.instance.CurrentMode == InfoManager.InfoMode.Underground) { itemLayers = ItemClass.Layer.MetroTunnels; } return(itemLayers); }
public override ToolBase.RaycastService GetService() { ItemClass.Layer trafficLayer = (this.GetType() != typeof(BulldozeTool)) ? ItemClass.Layer.Default | ItemClass.Layer.MetroTunnels | ItemClass.Layer.Markers : ItemClass.Layer.MetroTunnels; ItemClass.Availability mode = Singleton <ToolManager> .instance.m_properties.m_mode; if ((mode & ItemClass.Availability.MapAndAsset) != ItemClass.Availability.None) { InfoManager.InfoMode currentMode = Singleton <InfoManager> .instance.CurrentMode; if (currentMode == InfoManager.InfoMode.Transport) { return(new ToolBase.RaycastService(ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Layer.Default | ItemClass.Layer.MetroTunnels | ItemClass.Layer.AirplanePaths | ItemClass.Layer.ShipPaths | ItemClass.Layer.Markers)); } if (currentMode != InfoManager.InfoMode.Traffic) { return(new ToolBase.RaycastService(ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Layer.Default | ItemClass.Layer.Markers)); } return(new ToolBase.RaycastService(ItemClass.Service.None, ItemClass.SubService.None, trafficLayer | ItemClass.Layer.Markers)); } else { InfoManager.InfoMode currentMode = Singleton <InfoManager> .instance.CurrentMode; if (currentMode == InfoManager.InfoMode.Water) { return(new ToolBase.RaycastService(ItemClass.Service.Water, ItemClass.SubService.None, ItemClass.Layer.Default | ItemClass.Layer.WaterPipes)); } if (currentMode == InfoManager.InfoMode.Transport) { return(new ToolBase.RaycastService(ItemClass.Service.PublicTransport, ItemClass.SubService.None, ItemClass.Layer.Default | ItemClass.Layer.MetroTunnels)); } if (currentMode != InfoManager.InfoMode.Traffic) { return(new ToolBase.RaycastService(ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Layer.Default)); } return(new ToolBase.RaycastService(ItemClass.Service.None, ItemClass.SubService.None, trafficLayer)); } }
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(); }
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 static bool RayCast(TreeManager tm, Segment3 ray, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Layer itemLayers, TreeInstance.Flags ignoreFlags, out Vector3 hit, out uint treeIndex) { unsafe { int num; int num1; int num2; int num3; int num4; int num5; float single; float single1; Bounds bound = new Bounds(new Vector3(0f, 512f, 0f), new Vector3(17280f, 1152f, 17280f)); if (ray.Clip(bound)) { Vector3 vector3 = ray.b - ray.a; int num6 = (int)((double)ray.a.x / 32 + 270); int num7 = (int)((double)ray.a.z / 32 + 270); int num8 = (int)((double)ray.b.x / 32 + 270); int num9 = (int)((double)ray.b.z / 32 + 270); float single2 = Mathf.Abs(vector3.x); float single3 = Mathf.Abs(vector3.z); if ((double)single2 < (double)single3) { num = 0; num1 = ((double)vector3.z <= 0 ? -1 : 1); if ((double)single3 != 0) { vector3 = vector3 * (32f / single3); } } else { num = ((double)vector3.x <= 0 ? -1 : 1); num1 = 0; if ((double)single2 != 0) { vector3 = vector3 * (32f / single2); } } float single4 = 2f; float single5 = 10000f; treeIndex = 0; Vector3 vector31 = ray.a; Vector3 vector32 = ray.a; int num10 = num6; int num11 = num7; do { Vector3 vector33 = vector32 + vector3; if (num == 0) { num4 = ((num11 != num7 || num1 <= 0) && (num11 != num9 || num1 >= 0) ? Mathf.Max(num11, 0) : Mathf.Max((int)(((double)vector33.z - 72) / 32 + 270), 0)); num5 = ((num11 != num7 || num1 >= 0) && (num11 != num9 || num1 <= 0) ? Mathf.Min(num11, 539) : Mathf.Min((int)(((double)vector33.z + 72) / 32 + 270), 539)); num2 = Mathf.Max((int)(((double)Mathf.Min(vector31.x, vector33.x) - 72) / 32 + 270), 0); num3 = Mathf.Min((int)(((double)Mathf.Max(vector31.x, vector33.x) + 72) / 32 + 270), 539); } else { num2 = ((num10 != num6 || num <= 0) && (num10 != num8 || num >= 0) ? Mathf.Max(num10, 0) : Mathf.Max((int)(((double)vector33.x - 72) / 32 + 270), 0)); num3 = ((num10 != num6 || num >= 0) && (num10 != num8 || num <= 0) ? Mathf.Min(num10, 539) : Mathf.Min((int)(((double)vector33.x + 72) / 32 + 270), 539)); num4 = Mathf.Max((int)(((double)Mathf.Min(vector31.z, vector33.z) - 72) / 32 + 270), 0); num5 = Mathf.Min((int)(((double)Mathf.Max(vector31.z, vector33.z) + 72) / 32 + 270), 539); } for (int i = num4; i <= num5; i++) { for (int j = num2; j <= num3; j++) { uint mTreeGrid = tm.m_treeGrid[i * 540 + j]; int num12 = 0; while (mTreeGrid != 0) { if ((tm.m_trees.m_buffer[mTreeGrid].m_flags & (ushort)ignoreFlags) == (ushort)TreeInstance.Flags.None && (double)ray.DistanceSqr(tm.m_trees.m_buffer[mTreeGrid].Position) < 2500) { TreeInfo info = tm.m_trees.m_buffer[mTreeGrid].Info; if ((service == ItemClass.Service.None || info.m_class.m_service == service) && (subService == ItemClass.SubService.None || info.m_class.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info.m_class.m_layer & itemLayers) != ItemClass.Layer.None) && tm.m_trees.m_buffer[mTreeGrid].RayCast(mTreeGrid, ray, out single, out single1) && ((double)single < (double)single4 - 9.99999974737875E-05 || (double)single < (double)single4 + 9.99999974737875E-05 && (double)single1 < (double)single5)) { single4 = single; single5 = single1; treeIndex = mTreeGrid; } } mTreeGrid = tm.m_trees.m_buffer[mTreeGrid].m_nextGridTree; int num13 = num12 + 1; num12 = num13; if (num13 <= LimitTreeManager.Helper.TreeLimit) { continue; } CODebugBase<LogChannel>.Error(LogChannel.Core, string.Concat("Invalid list detected!\n", Environment.StackTrace)); break; } } } vector31 = vector32; vector32 = vector33; num10 = num10 + num; num11 = num11 + num1; } while ((num10 <= num8 || num <= 0) && (num10 >= num8 || num >= 0) && (num11 <= num9 || num1 <= 0) && (num11 >= num9 || num1 >= 0)); if ((double)single4 != 2) { hit = ray.Position(single4); return true; } } hit = Vector3.zero; treeIndex = 0; return false; } }
public bool OverlapQuad(Quad2 quad, float minY, float maxY, ItemClass.CollisionType collisionType, ItemClass.Layer layers, ushort ignoreNode1, ushort ignoreNode2, ushort ignoreSegment, ulong[] segmentMask) { return(false); }
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); }
public static bool Prefix(Quad2 quad, float minY, float maxY, ItemClass.CollisionType collisionType, ItemClass.Layer requireLayers, ItemClass.Layer forbidLayers, ushort ignoreNode1, ushort ignoreNode2, ushort ignoreSegment, ulong[] segmentMask, ref bool __result) { NetManager instance = Singleton <NetManager> .instance; Vector2 vector = quad.Min(); Vector2 vector2 = quad.Max(); int num = Mathf.Max((int)((vector.x - 64f) / 64f + 135f), 0); int num2 = Mathf.Max((int)((vector.y - 64f) / 64f + 135f), 0); int num3 = Mathf.Min((int)((vector2.x + 64f) / 64f + 135f), 269); int num4 = Mathf.Min((int)((vector2.y + 64f) / 64f + 135f), 269); ushort num5 = 0; ushort num6 = 0; if (ignoreSegment != 0) { ushort startNode = instance.m_segments.m_buffer[ignoreSegment].m_startNode; ushort endNode = instance.m_segments.m_buffer[ignoreSegment].m_endNode; NetNode.Flags flags = instance.m_nodes.m_buffer[startNode].m_flags; NetNode.Flags flags2 = instance.m_nodes.m_buffer[endNode].m_flags; if ((flags & NetNode.Flags.Middle) != 0) { num5 = startNode; } if ((flags2 & NetNode.Flags.Middle) != 0) { num6 = endNode; } } bool result = false; for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num7 = instance.m_segmentGrid[i * 270 + j]; int num8 = 0; while (num7 != 0) { if (num7 != ignoreSegment && ((long)instance.m_updatedSegments[num7 >> 6] & (1L << (int)num7)) == 0) { NetInfo info = instance.m_segments.m_buffer[num7].Info; if ((object)info != null) { ItemClass.Layer collisionLayers = info.m_netAI.GetCollisionLayers(); if ((object)info != null && (requireLayers == ItemClass.Layer.None || (collisionLayers & requireLayers) != 0) && (collisionLayers & forbidLayers) == ItemClass.Layer.None) { ushort startNode2 = instance.m_segments.m_buffer[num7].m_startNode; ushort endNode2 = instance.m_segments.m_buffer[num7].m_endNode; if (startNode2 != ignoreNode1 && startNode2 != ignoreNode2 && startNode2 != num5 && startNode2 != num6 && endNode2 != ignoreNode1 && endNode2 != ignoreNode2 && endNode2 != num5 && endNode2 != num6) { Vector3 position = instance.m_nodes.m_buffer[startNode2].m_position; Vector3 position2 = instance.m_nodes.m_buffer[endNode2].m_position; // NON-STOCK CODE STARTS if (CSURUtil.IsCSUROffset(instance.m_nodes.m_buffer[startNode2].Info)) { bool lht = false; if (instance.m_nodes.m_buffer[startNode2].CountSegments() != 0) { float collisionHalfWidth = Mathf.Max(3f, (instance.m_nodes.m_buffer[startNode2].Info.m_halfWidth + instance.m_nodes.m_buffer[startNode2].Info.m_pavementWidth) / 2f); NetSegment mysegment = CSURUtil.GetSameInfoSegment(instance.m_nodes.m_buffer[startNode2]); Vector3 direction = CSURUtil.CheckNodeEq(mysegment.m_startNode, instance.m_nodes.m_buffer[startNode2]) ? mysegment.m_startDirection : -mysegment.m_endDirection; if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0) { lht = true; } // normal to the right hand side Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized; position = position + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal; } } if (CSURUtil.IsCSUROffset(instance.m_nodes.m_buffer[endNode2].Info)) { bool lht = false; if (instance.m_nodes.m_buffer[endNode2].CountSegments() != 0) { float collisionHalfWidth = Mathf.Max(3f, (instance.m_nodes.m_buffer[endNode2].Info.m_halfWidth + instance.m_nodes.m_buffer[endNode2].Info.m_pavementWidth) / 2f); NetSegment mysegment = CSURUtil.GetSameInfoSegment(instance.m_nodes.m_buffer[endNode2]); Vector3 direction = CSURUtil.CheckNodeEq(mysegment.m_startNode, instance.m_nodes.m_buffer[endNode2]) ? mysegment.m_startDirection : -mysegment.m_endDirection; if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0) { lht = true; } // normal to the right hand side Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized; position2 = position2 + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal; } } // NON-STOCK CODE ENDS float num9 = Mathf.Max(Mathf.Max(vector.x - 64f - position.x, vector.y - 64f - position.z), Mathf.Max(position.x - vector2.x - 64f, position.z - vector2.y - 64f)); float num10 = Mathf.Max(Mathf.Max(vector.x - 64f - position2.x, vector.y - 64f - position2.z), Mathf.Max(position2.x - vector2.x - 64f, position2.z - vector2.y - 64f)); if ((num9 < 0f || num10 < 0f) && instance.m_segments.m_buffer[num7].OverlapQuad(num7, quad, minY, maxY, collisionType)) { if (segmentMask == null) { __result = true; return(false); } segmentMask[num7 >> 6] |= (ulong)(1L << (int)num7); result = true; } } } } } num7 = instance.m_segments.m_buffer[num7].m_nextGridSegment; if (++num8 >= 36864) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } __result = result; return(false); }
private bool RayCastSegmentAndNode(NetInfo connectedType, Segment3 ray, float snapElevation, bool nameOnly, ItemClass.Service service, ItemClass.Service service2, ItemClass.SubService subService, ItemClass.SubService subService2, ItemClass.Layer itemLayers, ItemClass.Layer itemLayers2, NetNode.Flags ignoreNodeFlags, NetSegment.Flags ignoreSegmentFlags, out Vector3 hit, out ushort nodeIndex, out ushort segmentIndex) { var bounds = new Bounds(new Vector3(0f, 512f, 0f), new Vector3(17280f, 1152f, 17280f)); if (ray.Clip(bounds)) { Vector3 vector = ray.b - ray.a; var num = (int)((ray.a.x / 64f) + 135f); var num2 = (int)((ray.a.z / 64f) + 135f); var num3 = (int)((ray.b.x / 64f) + 135f); var num4 = (int)((ray.b.z / 64f) + 135f); var num5 = Mathf.Abs(vector.x); var num6 = Mathf.Abs(vector.z); int num7; int num8; if (num5 >= num6) { num7 = ((vector.x <= 0f) ? -1 : 1); num8 = 0; if (num5 > 0.001f) { vector *= 64f / num5; } } else { num7 = 0; num8 = ((vector.z <= 0f) ? -1 : 1); if (num6 > 0.001f) { vector *= 64f / num6; } } var num9 = 2f; var num10 = 16f; var num11 = 2f; var num12 = 16f; ushort num13 = 0; ushort num14 = 0; ushort num15 = 0; Vector3 vector2 = ray.a; Vector3 vector3 = ray.a; var num16 = num; var num17 = num2; do { Vector3 vector4 = vector3 + vector; int num18; int num19; int num20; int num21; if (num7 != 0) { if ((num16 == num && num7 > 0) || (num16 == num3 && num7 < 0)) { num18 = Mathf.Max((int)(((vector4.x - 64f) / 64f) + 135f), 0); } else { num18 = Mathf.Max(num16, 0); } if ((num16 == num && num7 < 0) || (num16 == num3 && num7 > 0)) { num19 = Mathf.Min((int)(((vector4.x + 64f) / 64f) + 135f), 269); } else { num19 = Mathf.Min(num16, 269); } num20 = Mathf.Max((int)(((Mathf.Min(vector2.z, vector4.z) - 64f) / 64f) + 135f), 0); num21 = Mathf.Min((int)(((Mathf.Max(vector2.z, vector4.z) + 64f) / 64f) + 135f), 269); } else { if ((num17 == num2 && num8 > 0) || (num17 == num4 && num8 < 0)) { num20 = Mathf.Max((int)(((vector4.z - 64f) / 64f) + 135f), 0); } else { num20 = Mathf.Max(num17, 0); } if ((num17 == num2 && num8 < 0) || (num17 == num4 && num8 > 0)) { num21 = Mathf.Min((int)(((vector4.z + 64f) / 64f) + 135f), 269); } else { num21 = Mathf.Min(num17, 269); } num18 = Mathf.Max((int)(((Mathf.Min(vector2.x, vector4.x) - 64f) / 64f) + 135f), 0); num19 = Mathf.Min((int)(((Mathf.Max(vector2.x, vector4.x) + 64f) / 64f) + 135f), 269); } for (var i = num20; i <= num21; i++) { for (var j = num18; j <= num19; j++) { var num22 = Singleton <NetManager> .instance.m_nodeGrid[(i * 270) + j]; var num23 = 0; while (num22 != 0) { NetNode.Flags flags = NodeBuffer[num22].m_flags; NetInfo info = NodeBuffer[num22].Info; ItemClass connectionClass = info.GetConnectionClass(); if ((((service == ItemClass.Service.None || connectionClass.m_service == service) && (subService == ItemClass.SubService.None || connectionClass.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (connectionClass.m_layer & itemLayers) != ItemClass.Layer.None)) || (info.m_intersectClass != null && (service == ItemClass.Service.None || info.m_intersectClass.m_service == service) && (subService == ItemClass.SubService.None || info.m_intersectClass.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info.m_intersectClass.m_layer & itemLayers) != ItemClass.Layer.None)) || (info.m_netAI.CanIntersect(connectedType) && connectionClass.m_service == service2 && (subService2 == ItemClass.SubService.None || connectionClass.m_subService == subService2) && (itemLayers2 == ItemClass.Layer.None || (connectionClass.m_layer & itemLayers2) != ItemClass.Layer.None))) && (flags & ignoreNodeFlags) == NetNode.Flags.None && (connectedType == null || (info.m_netAI.CanConnect(connectedType) && connectedType.m_netAI.CanConnect(info)))) { var flag = false; if ((flags & (NetNode.Flags.Middle | NetNode.Flags.Untouchable)) == (NetNode.Flags.Middle | NetNode.Flags.Untouchable) && NodeBuffer[num22].CountSegments(NetSegment.Flags.Untouchable, 0) >= 2) { flag = true; } if (!flag && NodeBuffer[num22].RayCast(ray, snapElevation, out var num24, out var num25) && (num25 < num12 || (num25 == num12 && num24 < num11))) { num11 = num24; num12 = num25; num14 = num22; } } num22 = NodeBuffer[num22].m_nextGridNode; if (++num23 > 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } for (var k = num20; k <= num21; k++) { for (var l = num18; l <= num19; l++) { var num26 = Singleton <NetManager> .instance.m_segmentGrid[(k * 270) + l]; var num27 = 0; while (num26 != 0) { NetSegment.Flags flags2 = SegmentBuffer[num26].m_flags; NetInfo info2 = SegmentBuffer[num26].Info; ItemClass connectionClass2 = info2.GetConnectionClass(); if (((service == ItemClass.Service.None || connectionClass2.m_service == service) && (subService == ItemClass.SubService.None || connectionClass2.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (connectionClass2.m_layer & itemLayers) != ItemClass.Layer.None || nameOnly)) || (info2.m_intersectClass != null && (service == ItemClass.Service.None || info2.m_intersectClass.m_service == service) && (subService == ItemClass.SubService.None || info2.m_intersectClass.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info2.m_intersectClass.m_layer & itemLayers) != ItemClass.Layer.None || nameOnly)) || (info2.m_netAI.CanIntersect(connectedType) && connectionClass2.m_service == service2 && (subService2 == ItemClass.SubService.None || connectionClass2.m_subService == subService2) && (itemLayers2 == ItemClass.Layer.None || (connectionClass2.m_layer & itemLayers2) != ItemClass.Layer.None || nameOnly))) { var flag2 = (flags2 & ignoreSegmentFlags) != NetSegment.Flags.None && !nameOnly; if ((flags2 & ignoreSegmentFlags) == NetSegment.Flags.None && (connectedType == null || (info2.m_netAI.CanConnect(connectedType) && connectedType.m_netAI.CanConnect(info2))) && SegmentBuffer[num26].RayCast(num26, ray, snapElevation, nameOnly, out var num28, out var num29) && (num29 < num10 || (num29 == num10 && num28 < num9))) { var startNode = SegmentBuffer[num26].m_startNode; var endNode = SegmentBuffer[num26].m_endNode; Vector3 position = NodeBuffer[startNode].m_position; Vector3 position2 = NodeBuffer[endNode].m_position; var num30 = NodeBuffer[startNode].Info.GetMinNodeDistance(); var num31 = NodeBuffer[endNode].Info.GetMinNodeDistance(); num10 = num29; num9 = num28; Vector3 a = ray.a + ((ray.b - ray.a) * num28); NetNode.Flags flags3 = NodeBuffer[startNode].m_flags; if ((flags3 & NetNode.Flags.End) != NetNode.Flags.None) { flags3 &= ~NetNode.Flags.Moveable; } NetNode.Flags flags4 = NodeBuffer[endNode].m_flags; if ((flags4 & NetNode.Flags.End) != NetNode.Flags.None) { flags4 &= ~NetNode.Flags.Moveable; } if (flag2) { num30 = 1000f; num31 = 1000f; } var flag3 = (flags3 & (NetNode.Flags.Moveable | ignoreNodeFlags)) == NetNode.Flags.None; var flag4 = (flags4 & (NetNode.Flags.Moveable | ignoreNodeFlags)) == NetNode.Flags.None; var num32 = VectorUtils.LengthSqrXZ(a - position) / (num30 * num30); var num33 = VectorUtils.LengthSqrXZ(a - position2) / (num31 * num31); if (flag3 && num32 < 1f && (!flag4 || num32 < num33) && !nameOnly) { num13 = startNode; if (!flag2) { num15 = num26; } } else if (flag4 && num33 < 1f && !nameOnly) { num13 = endNode; if (!flag2) { num15 = num26; } } else if (!flag2) { num13 = 0; num15 = num26; } } } num26 = SegmentBuffer[num26].m_nextGridSegment; if (++num27 > 36864) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } vector2 = vector3; vector3 = vector4; num16 += num7; num17 += num8; }while ((num16 <= num3 || num7 <= 0) && (num16 >= num3 || num7 >= 0) && (num17 <= num4 || num8 <= 0) && (num17 >= num4 || num8 >= 0)); if (num12 < num10 || (num12 == num10 && num11 < num9)) { num9 = num11; num13 = num14; } if (num9 != 2f) { hit = ray.Position(num9); nodeIndex = num13; segmentIndex = num15; return(true); } } hit = Vector3.zero; nodeIndex = 0; segmentIndex = 0; return(false); }
private static bool Prefix(Ray mouseRay, MoveItTool __instance, ref Instance ___m_hoverInstance) { Traverse _MIT = Traverse.Create(__instance); // MoveIt code ___m_hoverInstance = null; 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 = _MIT.Method("RaycastMouseLocation", mouseRay).GetValue <Vector3>(); InstanceID id = InstanceID.Empty; ItemClass.Layer itemLayers = _MIT.Method("GetItemLayers").GetValue <ItemClass.Layer>(); bool selectBuilding = true; bool selectProps = true; bool selectDecals = true; bool selectSurfaces = true; bool selectNodes = true; bool selectSegments = true; bool selectTrees = true; bool _repeatSearch = false; if (MoveItTool.marqueeSelection) { selectBuilding = MoveItTool.filterBuildings; selectProps = MoveItTool.filterProps; selectDecals = MoveItTool.filterDecals; selectSurfaces = MITE.filterSurfaces; selectNodes = MoveItTool.filterNodes; selectSegments = MoveItTool.filterSegments; selectTrees = MoveItTool.filterTrees; } float smallestDist = 640000f; do { 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 (MITE.StepOver.isValidB(building) && Detour_Utils.IsBuildingValid(ref buildingBuffer[building], itemLayers) && buildingBuffer[building].RayCast(building, ray, out float t) && t < smallestDist) { //Debug.Log($"Building:{building}"); 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 (MITE.StepOver.isValidP(prop) && Filters.Filter(propBuffer[prop].Info) && MITE.StepOver.isValidP(prop)) { //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 (MITE.StepOver.isValidN(node) && Detour_Utils.IsNodeValid(ref nodeBuffer[node], itemLayers) && Detour_Utils.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 (MITE.StepOver.isValidS(segment) && Detour_Utils.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 = MoveItTool.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 || ( !Detour_Utils.RayCastNode(ref nodeBuffer[segmentBuffer[segment].m_startNode], ray, -1000f, out float t2, out priority) &&