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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
 }
Exemple #11
0
        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);
        }
Exemple #12
0
        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));
            }
        }
Exemple #13
0
        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;
        }
Exemple #14
0
        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();
        }
Exemple #15
0
        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;
			}
		}
Exemple #17
0
 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);
 }
Exemple #18
0
        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);
        }
Exemple #21
0
        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) &&