public static bool RayCastNodeMasked(ref NetNode node, Segment3 ray, float snapElevation, bool bothSides, out float t, out float priority)
        {
            bool lht = false;
            //if (SimulationManager.instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True) lht = true;
            NetInfo info = node.Info;
            float   num  = (float)node.m_elevation + info.m_netAI.GetSnapElevation();
            float   t2;

            if (info.m_netAI.IsUnderground())
            {
                t2 = Mathf.Clamp01(Mathf.Abs(snapElevation + num) / 12f);
            }
            else
            {
                t2 = Mathf.Clamp01(Mathf.Abs(snapElevation - num) / 12f);
            }
            float collisionHalfWidth = Mathf.Max(3f, info.m_halfWidth);
            float maskHalfWidth      = Mathf.Min(collisionHalfWidth - 1.5f, info.m_pavementWidth);
            float num2      = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth, t2);
            float num2m     = Mathf.Lerp(info.GetMinNodeDistance(), maskHalfWidth, t2);
            float num2delta = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth - maskHalfWidth, t2);

            if (node.CountSegments() != 0)
            {
                NetManager instance  = Singleton <NetManager> .instance;
                NetSegment mysegment = CSURUtil.GetSameInfoSegment(node);
                Vector3    direction = CSURUtil.CheckNodeEq(mysegment.m_startNode, node) ? mysegment.m_startDirection : -mysegment.m_endDirection;
                //Debug.Log(direction);
                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;
                Vector3 trueNodeCenter = node.m_position + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal;
                //Debug.Log($"num2: {num2}, num2m: {num2m}");
                //Debug.Log($"node: {node.m_position}, center: {trueNodeCenter}");
                if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t))
                {
                    float num3 = Vector3.Distance(ray.Position(t), trueNodeCenter);
                    if (num3 < num2delta)
                    {
                        priority = Mathf.Max(0f, num3 - collisionHalfWidth);
                        return(true);
                    }
                }
            }
            else
            {
                if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t))
                {
                    float num3 = Vector3.Distance(ray.Position(t), node.m_position);
                    if (num3 < num2)
                    {
                        priority = Mathf.Max(0f, num3 - collisionHalfWidth);
                        return(true);
                    }
                }
            }
            t        = 0f;
            priority = 0f;
            return(false);
        }
        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);
        }
        //to detour move it
        public static bool MoveItRayCastNode(ref NetNode node, Segment3 ray, float snapElevation, out float t, out float priority)
        {
            NetInfo info = node.Info;
            // NON-STOCK CODE STARTS
            float laneOffset  = 0;
            float startOffset = 0;
            float endOffset   = 0;
            bool  IsCSURSLane = CSURUtil.IsCSURSLane(info.m_netAI.m_info, ref laneOffset, ref startOffset, ref endOffset);

            if (CSURUtil.IsCSUROffset(info.m_netAI.m_info) && !IsCSURSLane)
            {
                return(RayCastNodeMasked(ref node, ray, snapElevation, false, out t, out priority));
            }
            // NON-STOCK CODE ENDS
            //if ((node.m_flags & (NetNode.Flags.Middle | NetNode.Flags.Outside)) == NetNode.Flags.None)
            //{
            float num = (float)node.m_elevation + info.m_netAI.GetSnapElevation();
            float t2;

            if (info.m_netAI.IsUnderground())
            {
                t2 = Mathf.Clamp01(Mathf.Abs(snapElevation + num) / 12f);
            }
            else
            {
                t2 = Mathf.Clamp01(Mathf.Abs(snapElevation - num) / 12f);
            }
            float collisionHalfWidth = Mathf.Max(3f, info.m_netAI.GetCollisionHalfWidth());
            float num2 = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth, t2);

            if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t))
            {
                float num3 = Vector3.Distance(ray.Position(t), node.m_position);
                // NON-STOCK CODE STARTS
                if (IsCSURSLane)
                {
                    bool       lht       = false;
                    NetManager instance  = Singleton <NetManager> .instance;
                    NetSegment mysegment = CSURUtil.GetSameInfoSegment(node);
                    bool       isStart   = CSURUtil.CheckNodeEq(mysegment.m_startNode, node);
                    Vector3    direction = isStart ? mysegment.m_startDirection : -mysegment.m_endDirection;
                    //Debug.Log(direction);
                    if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
                    {
                        lht = true;
                    }
                    Vector3 normal         = new Vector3(direction.z, 0, -direction.x).normalized;
                    float   vehicleLaneNum = CSURUtil.CountCSURSVehicleLanes(info);
                    float   otherLaneNum   = CSURUtil.CountCSURSOtherLanes(info);
                    float   laneNum        = otherLaneNum + vehicleLaneNum;
                    startOffset = startOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                    endOffset   = endOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                    var     Offset         = isStart ? startOffset : endOffset;
                    Vector3 trueNodeCenter = node.m_position + (lht ? -Offset : Offset) * normal;
                    num3 = Vector3.Distance(ray.Position(t), trueNodeCenter);
                }
                // NON-STOCK CODE ENDS

                if (num3 < num2)
                {
                    priority = Mathf.Max(0f, num3 - collisionHalfWidth);
                    return(true);
                }
            }
            //}
            t        = 0f;
            priority = 0f;
            return(false);
        }
Example #4
0
        public static bool Prefix(ref NetNode __instance, ushort nodeID, BuildingInfo newBuilding, float heightOffset)
        {
            float num = 0f;

            if ((object)newBuilding != null)
            {
                NetInfo info = __instance.Info;
                if ((object)info != null)
                {
                    num = info.m_netAI.GetNodeBuildingAngle(nodeID, ref __instance);
                }
            }
            BuildingInfo buildingInfo = null;

            if (__instance.m_building != 0)
            {
                buildingInfo = Singleton <BuildingManager> .instance.m_buildings.m_buffer[__instance.m_building].Info;
            }
            if ((object)newBuilding != buildingInfo)
            {
                if (__instance.m_building != 0)
                {
                    Singleton <BuildingManager> .instance.ReleaseBuilding(__instance.m_building);

                    __instance.m_building = 0;
                }
                if ((object)newBuilding != null)
                {
                    Vector3 position = __instance.m_position;
                    position.y += heightOffset;
                    // NON-STOCK CODE STARTS
                    if (CSURUtil.IsCSUROffset(__instance.Info))
                    {
                        float laneOffset  = 0;
                        float startOffset = 0;
                        float endOffset   = 0;
                        if (CSURUtil.IsCSURSLane(__instance.Info, ref laneOffset, ref startOffset, ref endOffset))
                        {
                            bool lht = false;
                            if (__instance.CountSegments() != 0)
                            {
                                float collisionHalfWidth = 0;
                                float vehicleLaneNum     = CSURUtil.CountCSURSVehicleLanes(__instance.Info);
                                float otherLaneNum       = CSURUtil.CountCSURSOtherLanes(__instance.Info);
                                float laneNum            = otherLaneNum + vehicleLaneNum;
                                if (CSURUtil.isStartNode(nodeID))
                                {
                                    if (startOffset != 0)
                                    {
                                        collisionHalfWidth = startOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                                    }
                                }
                                else
                                {
                                    if (endOffset != 0)
                                    {
                                        collisionHalfWidth = endOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                                    }
                                }
                                NetSegment mysegment = CSURUtil.GetSameInfoSegment(__instance);
                                Vector3    direction = CSURUtil.CheckNodeEq(mysegment.m_startNode, __instance) ? 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;
                            }
                        }
                        else
                        {
                            bool lht = false;
                            if (__instance.CountSegments() != 0)
                            {
                                float      collisionHalfWidth = Mathf.Max(3f, (__instance.Info.m_halfWidth + __instance.Info.m_pavementWidth) / 2f);
                                NetSegment mysegment          = CSURUtil.GetSameInfoSegment(__instance);
                                Vector3    direction          = CSURUtil.CheckNodeEq(mysegment.m_startNode, __instance) ? 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;
                            }
                        }
                    }
                    // NON-STOCK CODE ENDS
                    num *= 6.28318548f;
                    if ((object)buildingInfo != null || TestNodeBuilding(nodeID, newBuilding, position, num))
                    {
                        Randomizer randomizer = new Randomizer(nodeID);
                        if (Singleton <BuildingManager> .instance.CreateBuilding(out __instance.m_building, ref randomizer, newBuilding, position, num, 0, __instance.m_buildIndex + 1))
                        {
                            Singleton <BuildingManager> .instance.m_buildings.m_buffer[__instance.m_building].m_flags |= (Building.Flags.Untouchable | Building.Flags.FixedHeight);
                        }
                    }
                }
            }
            else if (__instance.m_building != 0)
            {
                BuildingManager instance  = Singleton <BuildingManager> .instance;
                Vector3         position2 = __instance.m_position;
                position2.y += heightOffset;
                // NON-STOCK CODE STARTS
                if (CSURUtil.IsCSUROffset(__instance.Info))
                {
                    float laneOffset  = 0;
                    float startOffset = 0;
                    float endOffset   = 0;
                    if (CSURUtil.IsCSURSLane(__instance.Info, ref laneOffset, ref startOffset, ref endOffset))
                    {
                        bool lht = false;
                        if (__instance.CountSegments() != 0)
                        {
                            float collisionHalfWidth = 0;
                            float vehicleLaneNum     = CSURUtil.CountCSURSVehicleLanes(__instance.Info);
                            float otherLaneNum       = CSURUtil.CountCSURSOtherLanes(__instance.Info);
                            float laneNum            = otherLaneNum + vehicleLaneNum;
                            if (CSURUtil.isStartNode(nodeID))
                            {
                                if (startOffset != 0)
                                {
                                    collisionHalfWidth = startOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                                }
                            }
                            else
                            {
                                if (endOffset != 0)
                                {
                                    collisionHalfWidth = endOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                                }
                            }
                            NetSegment mysegment = CSURUtil.GetSameInfoSegment(__instance);
                            Vector3    direction = CSURUtil.CheckNodeEq(mysegment.m_startNode, __instance) ? 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;
                        }
                    }
                    else
                    {
                        bool lht = false;
                        if (__instance.CountSegments() != 0)
                        {
                            float      collisionHalfWidth = Mathf.Max(3f, (__instance.Info.m_halfWidth + __instance.Info.m_pavementWidth) / 2f);
                            NetSegment mysegment          = CSURUtil.GetSameInfoSegment(__instance);
                            Vector3    direction          = CSURUtil.CheckNodeEq(mysegment.m_startNode, __instance) ? 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
                num *= 6.28318548f;
                // NON-STOCK CODE STARTS
                if (CSURUtil.IsCSUROffset(__instance.Info) && (instance.m_buildings.m_buffer[__instance.m_building].m_position != position2 || instance.m_buildings.m_buffer[__instance.m_building].m_angle != num))
                {
                    RemoveFromGrid(__instance.m_building, ref instance.m_buildings.m_buffer[__instance.m_building]);
                    instance.m_buildings.m_buffer[__instance.m_building].m_position = position2;
                    instance.m_buildings.m_buffer[__instance.m_building].m_angle    = num;
                    AddToGrid(__instance.m_building, ref instance.m_buildings.m_buffer[__instance.m_building]);
                    instance.m_buildings.m_buffer[__instance.m_building].CalculateBuilding(__instance.m_building);
                    Singleton <BuildingManager> .instance.UpdateBuildingRenderer(__instance.m_building, true);
                }
                else
                {
                    if (instance.m_buildings.m_buffer[__instance.m_building].m_position.y != position2.y || instance.m_buildings.m_buffer[__instance.m_building].m_angle != num)
                    {
                        instance.m_buildings.m_buffer[__instance.m_building].m_position.y = position2.y;
                        instance.m_buildings.m_buffer[__instance.m_building].m_angle      = num;
                        instance.UpdateBuilding(__instance.m_building);
                    }
                }
                // NON-STOCK CODE ENDS
            }
            return(false);
        }