Example #1
0
        public static ItemClass.Zone GetBlockZoneOverride(ref ZoneBlock block, int x, int z, ItemClass.Zone zone1, ItemClass.Zone zone2)
        {
            ItemClass.Zone targetZone = block.GetZone(x, z);
            switch ((int)targetZone)
            {
            case 8:
            case 9:
            case 10:
            case 11:
            case 12:
            case 13:
            case 14:
                if (ZMController.m_ghostMode)
                {
                    ItemClass.Zone newValue = CustomZoneData.Instance[targetZone].HasZone(zone1) ? zone1 : CustomZoneData.Instance[targetZone].HasZone(zone2) ? zone2 : CustomZoneData.Instance[targetZone].GetLowerestZone();
                    block.SetZone(x, z, newValue);
                    block.RefreshZoning(0);
                    return(newValue);
                }
                else
                {
                    return(CustomZoneData.Instance[targetZone].HasZone(zone1) ? zone1 : CustomZoneData.Instance[targetZone].HasZone(zone2) ? zone2 : targetZone);
                }

            default:
                return(targetZone);
            }
        }
Example #2
0
        private static void CheckZoning(ref Building _this, ItemClass.Zone zone1, ItemClass.Zone zone2, ref uint validCells, ref bool secondary, ref ZoneBlock block)
        {
            BuildingInfo.ZoningMode zoningMode = _this.Info.m_zoningMode;
            int     width       = _this.Width;
            int     length      = _this.Length;
            Vector3 vector3_1   = new Vector3(Mathf.Cos(_this.m_angle), 0.0f, Mathf.Sin(_this.m_angle)) * 8f;
            Vector3 vector3_2   = new Vector3(vector3_1.z, 0.0f, -vector3_1.x);
            int     rowCount    = block.RowCount;
            int     columnCount = ZoneBlockDetour.GetColumnCount(ref block); // modified
            Vector3 vector3_3   = new Vector3(Mathf.Cos(block.m_angle), 0.0f, Mathf.Sin(block.m_angle)) * 8f;
            Vector3 vector3_4   = new Vector3(vector3_3.z, 0.0f, -vector3_3.x);
            Vector3 vector3_5   = block.m_position - _this.m_position + vector3_1 * (float)((double)width * 0.5 - 0.5) + vector3_2 * (float)((double)length * 0.5 - 0.5);

            for (int z = 0; z < rowCount; ++z)
            {
                Vector3 vector3_6 = ((float)z - 3.5f) * vector3_4;
                for (int x = 0; (long)x < columnCount; ++x) // modified
                {
                    if (((long)block.m_valid & ~(long)block.m_shared & 1L << (z << 3 | x)) != 0L)
                    {
                        ItemClass.Zone zone  = block.GetZone(x, z);
                        bool           flag1 = zone == zone1;
                        if (zone == zone2 && zone2 != ItemClass.Zone.None)
                        {
                            flag1     = true;
                            secondary = true;
                        }
                        if (flag1)
                        {
                            Vector3 vector3_7 = ((float)x - 3.5f) * vector3_3;
                            Vector3 vector3_8 = vector3_5 + vector3_7 + vector3_6;
                            float   num1      = (float)((double)vector3_1.x * (double)vector3_8.x + (double)vector3_1.z * (double)vector3_8.z);
                            float   num2      = (float)((double)vector3_2.x * (double)vector3_8.x + (double)vector3_2.z * (double)vector3_8.z);
                            int     num3      = Mathf.RoundToInt(num1 / 64f);
                            int     num4      = Mathf.RoundToInt(num2 / 64f);
                            bool    flag2     = false;
                            if (zoningMode == BuildingInfo.ZoningMode.Straight)
                            {
                                flag2 = num4 == 0;
                            }
                            else if (zoningMode == BuildingInfo.ZoningMode.CornerLeft)
                            {
                                flag2 = num4 == 0 && num3 >= width - 2 || num4 <= 1 && num3 == width - 1;
                            }
                            else if (zoningMode == BuildingInfo.ZoningMode.CornerRight)
                            {
                                flag2 = num4 == 0 && num3 <= 1 || num4 <= 1 && num3 == 0;
                            }
                            if ((!flag2 || x == 0) && (num3 >= 0 && num4 >= 0) && (num3 < width && num4 < length))
                            {
                                validCells = validCells | (uint)(1 << (num4 << 3) + num3);
                            }
                        }
                    }
                }
            }
        }
Example #3
0
        private static void CalculateFillBuffer(ZoneTool zt, Vector3 position, Vector3 direction, float angle, ushort blockIndex, ref ZoneBlock block, ItemClass.Zone requiredZone, bool occupied1, bool occupied2)
        {
            var m_fillBuffer1 = (ulong[])typeof(ZoneTool).GetField("m_fillBuffer1", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(zt);

            float f1   = Mathf.Abs(block.m_angle - angle) * 0.6366197f;
            float num1 = f1 - Mathf.Floor(f1);

            if ((double)num1 >= 0.00999999977648258 && (double)num1 <= 0.990000009536743)
            {
                return;
            }
            int     rowCount  = block.RowCount;
            Vector3 vector3_1 = new Vector3(Mathf.Cos(block.m_angle), 0.0f, Mathf.Sin(block.m_angle)) * 8f;
            Vector3 vector3_2 = new Vector3(vector3_1.z, 0.0f, -vector3_1.x);

            for (int z = 0; z < rowCount; ++z)
            {
                Vector3 vector3_3 = ((float)z - 3.5f) * vector3_2;
                for (int x = 0; x < 4; ++x)
                {
                    if (((long)block.m_valid & 1L << (z << 3 | x)) != 0L && block.GetZone(x, z) == requiredZone)
                    {
                        if (occupied1)
                        {
                            if (requiredZone == ItemClass.Zone.Unzoned && ((long)block.m_occupied1 & 1L << (z << 3 | x)) == 0L)
                            {
                                continue;
                            }
                        }
                        else if (occupied2)
                        {
                            if (requiredZone == ItemClass.Zone.Unzoned && ((long)block.m_occupied2 & 1L << (z << 3 | x)) == 0L)
                            {
                                continue;
                            }
                        }
                        else if ((((long)block.m_occupied1 | (long)block.m_occupied2) & 1L << (z << 3 | x)) != 0L)
                        {
                            continue;
                        }
                        Vector3 vector3_4 = ((float)x - 3.5f) * vector3_1;
                        Vector3 vector3_5 = block.m_position + vector3_4 + vector3_3 - position;
                        float   f2        = (float)(((double)vector3_5.x * (double)direction.x + (double)vector3_5.z * (double)direction.z) * 0.125 + 32.0);
                        float   f3        = (float)(((double)vector3_5.x * (double)direction.z - (double)vector3_5.z * (double)direction.x) * 0.125 + 32.0);
                        int     num2      = Mathf.RoundToInt(f2);
                        int     index     = Mathf.RoundToInt(f3);
                        if (num2 >= 0 && num2 < 64 && (index >= 0 && index < 64) && ((double)Mathf.Abs(f2 - (float)num2) < 0.0125000001862645 && (double)Mathf.Abs(f3 - (float)index) < 0.0125000001862645))
                        {
                            m_fillBuffer1[index] |= (ulong)(1L << num2);
                        }
                    }
                }
            }
        }
Example #4
0
        private static void ApplyBrush(ZoneTool z, ushort blockIndex, ref ZoneBlock data, Vector3 position, float brushRadius)
        {
            Vector3 a = data.m_position - position;

            if (Mathf.Abs(a.x) > 46f + brushRadius || Mathf.Abs(a.z) > 46f + brushRadius)
            {
                return;
            }

            bool    m_zoning   = (bool)z.GetType().GetField("m_zoning", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(z);
            bool    m_dezoning = (bool)z.GetType().GetField("m_dezoning", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(z);
            int     num        = (int)((data.m_flags & 65280u) >> 8);
            Vector3 a2         = new Vector3(Mathf.Cos(data.m_angle), 0f, Mathf.Sin(data.m_angle)) * 8f;
            Vector3 a3         = new Vector3(a2.z, 0f, -a2.x);
            bool    flag       = false;

            for (int i = 0; i < num; i++)
            {
                Vector3 b = ((float)i - 3.5f) * a3;
                for (int j = 0; j < 4; j++)
                {
                    Vector3 b2     = ((float)j - 3.5f) * a2;
                    Vector3 vector = a + b2 + b;
                    float   num2   = vector.x * vector.x + vector.z * vector.z;
                    if (num2 <= brushRadius * brushRadius)
                    {
                        if (m_zoning)
                        {
                            if ((z.m_zone == ItemClass.Zone.Unzoned || data.GetZone(j, i) == ItemClass.Zone.Unzoned) && data.SetZone(j, i, z.m_zone))
                            {
                                flag = true;
                            }
                        }
                        else if (m_dezoning && data.SetZone(j, i, ItemClass.Zone.Unzoned))
                        {
                            flag = true;
                        }
                    }
                }
            }
            if (!flag)
            {
                return;
            }
            data.RefreshZoning(blockIndex);
            if (!m_zoning)
            {
                return;
            }
            UsedZone(z, z.m_zone);
        }
 private static void CheckZoning(ref Building _this, ItemClass.Zone zone1, ItemClass.Zone zone2, ref uint validCells, ref bool secondary, ref ZoneBlock block)
 {
     BuildingInfo.ZoningMode zoningMode = _this.Info.m_zoningMode;
     int width = _this.Width;
     int length = _this.Length;
     Vector3 vector3_1 = new Vector3(Mathf.Cos(_this.m_angle), 0.0f, Mathf.Sin(_this.m_angle)) * 8f;
     Vector3 vector3_2 = new Vector3(vector3_1.z, 0.0f, -vector3_1.x);
     int rowCount = block.RowCount;
     int columnCount = ZoneBlockDetour.GetColumnCount(ref block); // modified
     Vector3 vector3_3 = new Vector3(Mathf.Cos(block.m_angle), 0.0f, Mathf.Sin(block.m_angle)) * 8f;
     Vector3 vector3_4 = new Vector3(vector3_3.z, 0.0f, -vector3_3.x);
     Vector3 vector3_5 = block.m_position - _this.m_position + vector3_1 * (float)((double)width * 0.5 - 0.5) + vector3_2 * (float)((double)length * 0.5 - 0.5);
     for (int z = 0; z < rowCount; ++z)
     {
         Vector3 vector3_6 = ((float)z - 3.5f) * vector3_4;
         for (int x = 0; (long)x < columnCount; ++x) // modified
         {
             if (((long)block.m_valid & ~(long)block.m_shared & 1L << (z << 3 | x)) != 0L)
             {
                 ItemClass.Zone zone = block.GetZone(x, z);
                 bool flag1 = zone == zone1;
                 if (zone == zone2 && zone2 != ItemClass.Zone.None)
                 {
                     flag1 = true;
                     secondary = true;
                 }
                 if (flag1)
                 {
                     Vector3 vector3_7 = ((float)x - 3.5f) * vector3_3;
                     Vector3 vector3_8 = vector3_5 + vector3_7 + vector3_6;
                     float num1 = (float)((double)vector3_1.x * (double)vector3_8.x + (double)vector3_1.z * (double)vector3_8.z);
                     float num2 = (float)((double)vector3_2.x * (double)vector3_8.x + (double)vector3_2.z * (double)vector3_8.z);
                     int num3 = Mathf.RoundToInt(num1 / 64f);
                     int num4 = Mathf.RoundToInt(num2 / 64f);
                     bool flag2 = false;
                     if (zoningMode == BuildingInfo.ZoningMode.Straight)
                         flag2 = num4 == 0;
                     else if (zoningMode == BuildingInfo.ZoningMode.CornerLeft)
                         flag2 = num4 == 0 && num3 >= width - 2 || num4 <= 1 && num3 == width - 1;
                     else if (zoningMode == BuildingInfo.ZoningMode.CornerRight)
                         flag2 = num4 == 0 && num3 <= 1 || num4 <= 1 && num3 == 0;
                     if ((!flag2 || x == 0) && (num3 >= 0 && num4 >= 0) && (num3 < width && num4 < length))
                         validCells = validCells | (uint)(1 << (num4 << 3) + num3);
                 }
             }
         }
     }
 }
Example #6
0
 public static bool GetBlockZoneSanitize(ref ZoneBlock block, int x, int z)
 {
     ItemClass.Zone targetZone = block.GetZone(x, z);
     switch ((int)targetZone)
     {
     case 8:
     case 9:
     case 10:
     case 11:
     case 12:
     case 13:
     case 14:
         if (ZMController.m_ghostMode)
         {
             ItemClass.Zone newValue = CustomZoneData.Instance[targetZone].GetLowerestZone();
             block.SetZone(x, z, newValue);
             return(true);
         }
         break;
     }
     return(false);
 }
        private static void Snap(ZoneTool _this, ref Vector3 point, ref Vector3 direction, ref ItemClass.Zone zone, ref bool occupied1, ref bool occupied2, ref ZoneBlock block)
        {
            direction = new Vector3(Mathf.Cos(block.m_angle), 0.0f, Mathf.Sin(block.m_angle));
            Vector3 vector3_1 = direction * 8f;
            Vector3 vector3_2 = new Vector3(vector3_1.z, 0.0f, -vector3_1.x);
            Vector3 vector3_3 = block.m_position + vector3_1 * 0.5f + vector3_2 * 0.5f;
            Vector2 vector2   = new Vector2(point.x - vector3_3.x, point.z - vector3_3.z);
            int     num1      = Mathf.RoundToInt((float)(((double)vector2.x * (double)vector3_1.x + (double)vector2.y * (double)vector3_1.z) * (1.0 / 64.0)));
            int     num2      = Mathf.RoundToInt((float)(((double)vector2.x * (double)vector3_2.x + (double)vector2.y * (double)vector3_2.z) * (1.0 / 64.0)));

            point.x = (float)((double)vector3_3.x + (double)num1 * (double)vector3_1.x + (double)num2 * (double)vector3_2.x);
            point.z = (float)((double)vector3_3.z + (double)num1 * (double)vector3_1.z + (double)num2 * (double)vector3_2.z);
            // changed from:
            // if (num1 < -4 || num1 >= 0 || (num2 < -4 || num2 >= 4))
            if (num1 < -4 || num1 >= 4 || (num2 < -4 || num2 >= 4))
            {
                return;
            }
            zone      = block.GetZone(num1 + 4, num2 + 4); // keep old method (it's only a single call)
            occupied1 = block.IsOccupied1(num1 + 4, num2 + 4);
            occupied2 = block.IsOccupied2(num1 + 4, num2 + 4);
        }
 private static void CalculateImplementation2(ref ZoneBlock z, ushort blockID, ref ZoneBlock other, ref ulong valid, ref ulong shared, float minX, float minZ, float maxX, float maxZ)
 {
     if (((int)other.m_flags & 1) == 0 || (double)Mathf.Abs(other.m_position.x - z.m_position.x) >= 92.0 || (double)Mathf.Abs(other.m_position.z - z.m_position.z) >= 92.0)
         return;
     bool flag1 = ((int)other.m_flags & 2) != 0;
     int rowCount1 = z.RowCount;
     int rowCount2 = other.RowCount;
     Vector2 vector2_1 = new Vector2(Mathf.Cos(z.m_angle), Mathf.Sin(z.m_angle)) * 8f;
     Vector2 vector2_2 = new Vector2(vector2_1.y, -vector2_1.x);
     Vector2 vector2_3 = new Vector2(Mathf.Cos(other.m_angle), Mathf.Sin(other.m_angle)) * 8f;
     Vector2 vector2_4 = new Vector2(vector2_3.y, -vector2_3.x);
     Vector2 vector2_5 = VectorUtils.XZ(other.m_position);
     Quad2 quad = new Quad2();
     quad.a = vector2_5 - 4f * vector2_3 - 4f * vector2_4;
     quad.b = vector2_5 + 0.0f * vector2_3 - 4f * vector2_4;
     quad.c = vector2_5 + 0.0f * vector2_3 + (float)(rowCount2 - 4) * vector2_4;
     quad.d = vector2_5 - 4f * vector2_3 + (float)(rowCount2 - 4) * vector2_4;
     Vector2 vector2_6 = quad.Min();
     Vector2 vector2_7 = quad.Max();
     if ((double)vector2_6.x > (double)maxX || (double)vector2_6.y > (double)maxZ || ((double)minX > (double)vector2_7.x || (double)minZ > (double)vector2_7.y))
         return;
     Vector2 vector2_8 = VectorUtils.XZ(z.m_position);
     Quad2 quad2_1 = new Quad2();
     quad2_1.a = vector2_8 - 4f * vector2_1 - 4f * vector2_2;
     quad2_1.b = vector2_8 + 0.0f * vector2_1 - 4f * vector2_2;
     quad2_1.c = vector2_8 + 0.0f * vector2_1 + (float)(rowCount1 - 4) * vector2_2;
     quad2_1.d = vector2_8 - 4f * vector2_1 + (float)(rowCount1 - 4) * vector2_2;
     if (!quad2_1.Intersect(quad))
         return;
     for (int z1 = 0; z1 < rowCount1; ++z1)
     {
         Vector2 vector2_9 = ((float)z1 - 3.99f) * vector2_2;
         Vector2 vector2_10 = ((float)z1 - 3.01f) * vector2_2;
         quad2_1.a = vector2_8 - 4f * vector2_1 + vector2_9;
         quad2_1.b = vector2_8 + 0.0f * vector2_1 + vector2_9;
         quad2_1.c = vector2_8 + 0.0f * vector2_1 + vector2_10;
         quad2_1.d = vector2_8 - 4f * vector2_1 + vector2_10;
         if (quad2_1.Intersect(quad))
         {
             for (int x1 = 0; (long)x1 < 4L && ((long)valid & 1L << (z1 << 3 | x1)) != 0L; ++x1)
             {
                 Vector2 vector2_11 = ((float)x1 - 3.99f) * vector2_1;
                 Vector2 vector2_12 = ((float)x1 - 3.01f) * vector2_1;
                 Vector2 p = vector2_8 + (vector2_12 + vector2_11 + vector2_10 + vector2_9) * 0.5f;
                 if (Quad2.Intersect(quad.a - vector2_3 - vector2_4, quad.b + vector2_3 - vector2_4, quad.c + vector2_3 + vector2_4, quad.d - vector2_3 + vector2_4, p))
                 {
                     Quad2 quad2_2 = new Quad2();
                     quad2_2.a = vector2_8 + vector2_11 + vector2_9;
                     quad2_2.b = vector2_8 + vector2_12 + vector2_9;
                     quad2_2.c = vector2_8 + vector2_12 + vector2_10;
                     quad2_2.d = vector2_8 + vector2_11 + vector2_10;
                     bool flag2 = true;
                     bool flag3 = false;
                     for (int z2 = 0; z2 < rowCount2 && flag2; ++z2)
                     {
                         Vector2 vector2_13 = ((float)z2 - 3.99f) * vector2_4;
                         Vector2 vector2_14 = ((float)z2 - 3.01f) * vector2_4;
                         for (int x2 = 0; (long)x2 < 4L && flag2; ++x2)
                         {
                             if (((long)other.m_valid & ~(long)other.m_shared & 1L << (z2 << 3 | x2)) != 0L)
                             {
                                 Vector2 vector2_15 = ((float)x2 - 3.99f) * vector2_3;
                                 Vector2 vector2_16 = ((float)x2 - 3.01f) * vector2_3;
                                 float num1 = Vector2.SqrMagnitude(vector2_5 + (vector2_16 + vector2_15 + vector2_14 + vector2_13) * 0.5f - p);
                                 if ((double)num1 < 144.0)
                                 {
                                     if (!flag1)
                                     {
                                         float f = Mathf.Abs(other.m_angle - z.m_angle) * 0.6366197f;
                                         float num2 = f - Mathf.Floor(f);
                                         if ((double)num1 < 0.00999999977648258 && ((double)num2 < 0.00999999977648258 || (double)num2 > 0.990000009536743))
                                         {
                                             if (x1 < x2 || x1 == x2 && z.m_buildIndex < other.m_buildIndex)
                                                 other.m_shared |= (ulong)(1L << (z2 << 3 | x2));
                                             else
                                                 flag3 = true;
                                         }
                                         else if (quad2_2.Intersect(new Quad2()
                                         {
                                             a = vector2_5 + vector2_15 + vector2_13,
                                             b = vector2_5 + vector2_16 + vector2_13,
                                             c = vector2_5 + vector2_16 + vector2_14,
                                             d = vector2_5 + vector2_15 + vector2_14
                                         }))
                                         {
                                             if (x2 >= 4 && x1 >= 4 || x2 < 4 && x1 < 4)
                                             {
                                                 if (x2 >= 2 && x1 >= 2 || x2 < 2 && x1 < 2)
                                                 {
                                                     if (z.m_buildIndex < other.m_buildIndex)
                                                         other.m_valid &= (ulong)~(1L << (z2 << 3 | x2));
                                                     else
                                                         flag2 = false;
                                                 }
                                                 else if (x2 < 2)
                                                     flag2 = false;
                                                 else
                                                     other.m_valid &= (ulong)~(1L << (z2 << 3 | x2));
                                             }
                                             else if (x2 < 4)
                                                 flag2 = false;
                                             else
                                                 other.m_valid &= (ulong)~(1L << (z2 << 3 | x2));
                                         }
                                     }
                                     if ((double)num1 < 36.0 && x1 < 4 && x2 < 4)
                                     {
                                         ItemClass.Zone zone1 = z.GetZone(x1, z1);
                                         ItemClass.Zone zone2 = other.GetZone(x2, z2);
                                         if (zone1 == ItemClass.Zone.Unzoned)
                                             z.SetZone(x1, z1, zone2);
                                         else if (zone2 == ItemClass.Zone.Unzoned && !flag1)
                                             other.SetZone(x2, z2, zone1);
                                     }
                                 }
                             }
                         }
                     }
                     if (!flag2)
                     {
                         valid = valid & (ulong)~(1L << (z1 << 3 | x1));
                         break;
                     }
                     if (flag3)
                         shared = shared | (ulong)(1L << (z1 << 3 | x1));
                 }
             }
         }
     }
 }
 public static void SimulationStep(ref ZoneBlock b, ushort blockID)
 {
     ZoneManager instance = Singleton<ZoneManager>.instance;
     int rowCount = b.RowCount;
     Vector2 vector = new Vector2(Mathf.Cos(b.m_angle), Mathf.Sin(b.m_angle)) * 8f;
     Vector2 vector2 = new Vector2(vector.y, -vector.x);
     ulong num = b.m_valid & ~(b.m_occupied1 | b.m_occupied2);
     int num2 = 0;
     ItemClass.Zone zone = ItemClass.Zone.Unzoned;
     int num3 = 0;
     while (num3 < 4 && zone == ItemClass.Zone.Unzoned)
     {
         num2 = Singleton<SimulationManager>.instance.m_randomizer.Int32((uint)rowCount);
         if ((num & 1uL << (num2 << 3)) != 0uL)
         {
             zone = b.GetZone(0, num2);
         }
         num3++;
     }
     DistrictManager instance2 = Singleton<DistrictManager>.instance;
     byte district = instance2.GetDistrict(b.m_position);
     int num4;
     switch (zone)
     {
         case ItemClass.Zone.ResidentialLow:
             num4 = instance.m_actualResidentialDemand;
             num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialLowDemandOffset();
             break;
         case ItemClass.Zone.ResidentialHigh:
             num4 = instance.m_actualResidentialDemand;
             num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialHighDemandOffset();
             break;
         case ItemClass.Zone.CommercialLow:
             num4 = instance.m_actualCommercialDemand;
             num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialLowDemandOffset();
             break;
         case ItemClass.Zone.CommercialHigh:
             num4 = instance.m_actualCommercialDemand;
             num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialHighDemandOffset();
             break;
         case ItemClass.Zone.Industrial:
             num4 = instance.m_actualWorkplaceDemand;
             num4 += instance2.m_districts.m_buffer[(int)district].CalculateIndustrialDemandOffset();
             break;
         case ItemClass.Zone.Office:
             num4 = instance.m_actualWorkplaceDemand;
             num4 += instance2.m_districts.m_buffer[(int)district].CalculateOfficeDemandOffset();
             break;
         default:
             return;
     }
     Vector2 a = VectorUtils.XZ(b.m_position);
     Vector2 vector3 = a - 3.5f * vector + ((float)num2 - 3.5f) * vector2;
     int[] tmpXBuffer = instance.m_tmpXBuffer;
     for (int i = 0; i < 13; i++)
     {
         tmpXBuffer[i] = 0;
     }
     Quad2 quad = default(Quad2);
     quad.a = a - 4f * vector + ((float)num2 - 10f) * vector2;
     quad.b = a + 3f * vector + ((float)num2 - 10f) * vector2;
     quad.c = a + 3f * vector + ((float)num2 + 2f) * vector2;
     quad.d = a - 4f * vector + ((float)num2 + 2f) * vector2;
     Vector2 vector4 = quad.Min();
     Vector2 vector5 = quad.Max();
     int num5 = Mathf.Max((int)((vector4.x - 46f) / 64f + FakeZoneManager.HALFGRID), 0);
     int num6 = Mathf.Max((int)((vector4.y - 46f) / 64f + FakeZoneManager.HALFGRID), 0);
     int num7 = Mathf.Min((int)((vector5.x + 46f) / 64f + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);
     int num8 = Mathf.Min((int)((vector5.y + 46f) / 64f + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);
     for (int j = num6; j <= num8; j++)
     {
         for (int k = num5; k <= num7; k++)
         {
             ushort num9 = FakeZoneManager.zoneGrid[j * FakeZoneManager.GRIDSIZE + k];
             int num10 = 0;
             while (num9 != 0)
             {
                 Vector3 position = instance.m_blocks.m_buffer[(int)num9].m_position;
                 float num11 = Mathf.Max(Mathf.Max(vector4.x - 46f - position.x, vector4.y - 46f - position.z), Mathf.Max(position.x - vector5.x - 46f, position.z - vector5.y - 46f));
                 if (num11 < 0f)
                 {
                     CheckBlock(b,ref instance.m_blocks.m_buffer[(int)num9], tmpXBuffer, zone, vector3, vector, vector2, quad);
                 }
                 num9 = instance.m_blocks.m_buffer[(int)num9].m_nextGridBlock;
                 if (++num10 >= 32768)
                 {
                     CODebugBase<LogChannel>.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                     break;
                 }
             }
         }
     }
     for (int l = 0; l < 13; l++)
     {
         uint num12 = (uint)tmpXBuffer[l];
         int num13 = 0;
         bool flag = (num12 & 196608u) == 196608u;
         bool flag2 = false;
         while ((num12 & 1u) != 0u)
         {
             num13++;
             flag2 = ((num12 & 65536u) != 0u);
             num12 >>= 1;
         }
         if (num13 == 5 || num13 == 6)
         {
             if (flag2)
             {
                 num13 -= Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) + 2;
             }
             else
             {
                 num13 = 4;
             }
             num13 |= 131072;
         }
         else if (num13 == 7)
         {
             num13 = 4;
             num13 |= 131072;
         }
         if (flag)
         {
             num13 |= 65536;
         }
         tmpXBuffer[l] = num13;
     }
     int num14 = tmpXBuffer[6] & 65535;
     if (num14 == 0)
     {
         return;
     }
     bool flag3 = IsGoodPlace(b,vector3);
     if (Singleton<SimulationManager>.instance.m_randomizer.Int32(100u) >= num4)
     {
         if (flag3)
         {
             instance.m_goodAreaFound[(int)zone] = 1024;
         }
         return;
     }
     if (!flag3 && instance.m_goodAreaFound[(int)zone] > -1024)
     {
         if (instance.m_goodAreaFound[(int)zone] == 0)
         {
             instance.m_goodAreaFound[(int)zone] = -1;
         }
         return;
     }
     int num15 = 6;
     int num16 = 6;
     bool flag4 = true;
     while (true)
     {
         if (flag4)
         {
             while (num15 != 0)
             {
                 if ((tmpXBuffer[num15 - 1] & 65535) != num14)
                 {
                     break;
                 }
                 num15--;
             }
             while (num16 != 12)
             {
                 if ((tmpXBuffer[num16 + 1] & 65535) != num14)
                 {
                     break;
                 }
                 num16++;
             }
         }
         else
         {
             while (num15 != 0)
             {
                 if ((tmpXBuffer[num15 - 1] & 65535) < num14)
                 {
                     break;
                 }
                 num15--;
             }
             while (num16 != 12)
             {
                 if ((tmpXBuffer[num16 + 1] & 65535) < num14)
                 {
                     break;
                 }
                 num16++;
             }
         }
         int num17 = num15;
         int num18 = num16;
         while (num17 != 0)
         {
             if ((tmpXBuffer[num17 - 1] & 65535) < 2)
             {
                 break;
             }
             num17--;
         }
         while (num18 != 12)
         {
             if ((tmpXBuffer[num18 + 1] & 65535) < 2)
             {
                 break;
             }
             num18++;
         }
         bool flag5 = num17 != 0 && num17 == num15 - 1;
         bool flag6 = num18 != 12 && num18 == num16 + 1;
         if (flag5 && flag6)
         {
             if (num16 - num15 > 2)
             {
                 break;
             }
             if (num14 <= 2)
             {
                 if (!flag4)
                 {
                     goto Block_34;
                 }
             }
             else
             {
                 num14--;
             }
         }
         else if (flag5)
         {
             if (num16 - num15 > 1)
             {
                 goto Block_36;
             }
             if (num14 <= 2)
             {
                 if (!flag4)
                 {
                     goto Block_38;
                 }
             }
             else
             {
                 num14--;
             }
         }
         else if (flag6)
         {
             if (num16 - num15 > 1)
             {
                 goto Block_40;
             }
             if (num14 <= 2)
             {
                 if (!flag4)
                 {
                     goto Block_42;
                 }
             }
             else
             {
                 num14--;
             }
         }
         else
         {
             if (num15 != num16)
             {
                 goto IL_884;
             }
             if (num14 <= 2)
             {
                 if (!flag4)
                 {
                     goto Block_45;
                 }
             }
             else
             {
                 num14--;
             }
         }
         flag4 = false;
     }
     num15++;
     num16--;
     Block_34:
     goto IL_891;
     Block_36:
     num15++;
     Block_38:
     goto IL_891;
     Block_40:
     num16--;
     Block_42:
     Block_45:
     IL_884:
     IL_891:
     int num19;
     int num20;
     if (num14 == 1 && num16 - num15 >= 1)
     {
         num15 += Singleton<SimulationManager>.instance.m_randomizer.Int32((uint)(num16 - num15));
         num16 = num15 + 1;
         num19 = num15 + Singleton<SimulationManager>.instance.m_randomizer.Int32(2u);
         num20 = num19;
     }
     else
     {
         do
         {
             num19 = num15;
             num20 = num16;
             if (num16 - num15 == 2)
             {
                 if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                 {
                     num20--;
                 }
                 else
                 {
                     num19++;
                 }
             }
             else if (num16 - num15 == 3)
             {
                 if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                 {
                     num20 -= 2;
                 }
                 else
                 {
                     num19 += 2;
                 }
             }
             else if (num16 - num15 == 4)
             {
                 if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                 {
                     num16 -= 2;
                     num20 -= 3;
                 }
                 else
                 {
                     num15 += 2;
                     num19 += 3;
                 }
             }
             else if (num16 - num15 == 5)
             {
                 if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                 {
                     num16 -= 3;
                     num20 -= 2;
                 }
                 else
                 {
                     num15 += 3;
                     num19 += 2;
                 }
             }
             else if (num16 - num15 >= 6)
             {
                 if (num15 == 0 || num16 == 12)
                 {
                     if (num15 == 0)
                     {
                         num15 = 3;
                         num19 = 2;
                     }
                     if (num16 == 12)
                     {
                         num16 = 9;
                         num20 = 10;
                     }
                 }
                 else if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                 {
                     num16 = num15 + 3;
                     num20 = num19 + 2;
                 }
                 else
                 {
                     num15 = num16 - 3;
                     num19 = num20 - 2;
                 }
             }
         }
         while (num16 - num15 > 3 || num20 - num19 > 3);
     }
     int num21 = 4;
     int num22 = num16 - num15 + 1;
     BuildingInfo.ZoningMode zoningMode = BuildingInfo.ZoningMode.Straight;
     bool flag7 = true;
     for (int m = num15; m <= num16; m++)
     {
         num21 = Mathf.Min(num21, tmpXBuffer[m] & 65535);
         if ((tmpXBuffer[m] & 131072) == 0)
         {
             flag7 = false;
         }
     }
     if (num16 > num15)
     {
         if ((tmpXBuffer[num15] & 65536) != 0)
         {
             zoningMode = BuildingInfo.ZoningMode.CornerLeft;
             num20 = num15 + num20 - num19;
             num19 = num15;
         }
         if ((tmpXBuffer[num16] & 65536) != 0 && (zoningMode != BuildingInfo.ZoningMode.CornerLeft || Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0))
         {
             zoningMode = BuildingInfo.ZoningMode.CornerRight;
             num19 = num16 + num19 - num20;
             num20 = num16;
         }
     }
     int num23 = 4;
     int num24 = num20 - num19 + 1;
     BuildingInfo.ZoningMode zoningMode2 = BuildingInfo.ZoningMode.Straight;
     bool flag8 = true;
     for (int n = num19; n <= num20; n++)
     {
         num23 = Mathf.Min(num23, tmpXBuffer[n] & 65535);
         if ((tmpXBuffer[n] & 131072) == 0)
         {
             flag8 = false;
         }
     }
     if (num20 > num19)
     {
         if ((tmpXBuffer[num19] & 65536) != 0)
         {
             zoningMode2 = BuildingInfo.ZoningMode.CornerLeft;
         }
         if ((tmpXBuffer[num20] & 65536) != 0 && (zoningMode2 != BuildingInfo.ZoningMode.CornerLeft || Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0))
         {
             zoningMode2 = BuildingInfo.ZoningMode.CornerRight;
         }
     }
     ItemClass.SubService subService = ItemClass.SubService.None;
     ItemClass.Level level = ItemClass.Level.Level1;
     ItemClass.Service service;
     switch (zone)
     {
         case ItemClass.Zone.ResidentialLow:
             service = ItemClass.Service.Residential;
             subService = ItemClass.SubService.ResidentialLow;
             break;
         case ItemClass.Zone.ResidentialHigh:
             service = ItemClass.Service.Residential;
             subService = ItemClass.SubService.ResidentialHigh;
             break;
         case ItemClass.Zone.CommercialLow:
             service = ItemClass.Service.Commercial;
             subService = ItemClass.SubService.CommercialLow;
             break;
         case ItemClass.Zone.CommercialHigh:
             service = ItemClass.Service.Commercial;
             subService = ItemClass.SubService.CommercialHigh;
             break;
         case ItemClass.Zone.Industrial:
             service = ItemClass.Service.Industrial;
             break;
         case ItemClass.Zone.Office:
             service = ItemClass.Service.Office;
             subService = ItemClass.SubService.None;
             break;
         default:
             return;
     }
     BuildingInfo buildingInfo = null;
     Vector3 vector6 = Vector3.zero;
     int num25 = 0;
     int num26 = 0;
     int num27 = 0;
     BuildingInfo.ZoningMode zoningMode3 = BuildingInfo.ZoningMode.Straight;
     int num28 = 0;
     while (num28 < 6)
     {
         switch (num28)
         {
             case 0:
                 if (zoningMode != BuildingInfo.ZoningMode.Straight)
                 {
                     num25 = num15 + num16 + 1;
                     num26 = num21;
                     num27 = num22;
                     zoningMode3 = zoningMode;
                     goto IL_D6A;
                 }
                 break;
             case 1:
                 if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                 {
                     num25 = num19 + num20 + 1;
                     num26 = num23;
                     num27 = num24;
                     zoningMode3 = zoningMode2;
                     goto IL_D6A;
                 }
                 break;
             case 2:
                 if (zoningMode != BuildingInfo.ZoningMode.Straight)
                 {
                     if (num21 >= 4)
                     {
                         num25 = num15 + num16 + 1;
                         num26 = ((!flag7) ? 2 : 3);
                         num27 = num22;
                         zoningMode3 = zoningMode;
                         goto IL_D6A;
                     }
                 }
                 break;
             case 3:
                 if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                 {
                     if (num23 >= 4)
                     {
                         num25 = num19 + num20 + 1;
                         num26 = ((!flag8) ? 2 : 3);
                         num27 = num24;
                         zoningMode3 = zoningMode2;
                         goto IL_D6A;
                     }
                 }
                 break;
             case 4:
                 num25 = num15 + num16 + 1;
                 num26 = num21;
                 num27 = num22;
                 zoningMode3 = BuildingInfo.ZoningMode.Straight;
                 goto IL_D6A;
             case 5:
                 num25 = num19 + num20 + 1;
                 num26 = num23;
                 num27 = num24;
                 zoningMode3 = BuildingInfo.ZoningMode.Straight;
                 goto IL_D6A;
             default:
                 goto IL_D6A;
         }
     IL_DF0:
         num28++;
         continue;
     IL_D6A:
         vector6 = b.m_position + VectorUtils.X_Y(((float)num26 * 0.5f - 4f) * vector + ((float)num25 * 0.5f + (float)num2 - 10f) * vector2);
         if (zone == ItemClass.Zone.Industrial)
         {
             ZoneBlock.GetIndustryType(vector6, out subService, out level);
         }
         buildingInfo = Singleton<BuildingManager>.instance.GetRandomBuildingInfo(ref Singleton<SimulationManager>.instance.m_randomizer, service, subService, level, num27, num26, zoningMode3, 0);
         if (buildingInfo != null)
         {
             break;
         }
         goto IL_DF0;
     }
     if (buildingInfo == null)
     {
         return;
     }
     float num29 = Singleton<TerrainManager>.instance.WaterLevel(VectorUtils.XZ(vector6));
     if (num29 > vector6.y)
     {
         return;
     }
     float num30 = b.m_angle + 1.57079637f;
     if (zoningMode3 == BuildingInfo.ZoningMode.CornerLeft && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerRight)
     {
         num30 -= 1.57079637f;
         num26 = num27;
     }
     else if (zoningMode3 == BuildingInfo.ZoningMode.CornerRight && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft)
     {
         num30 += 1.57079637f;
         num26 = num27;
     }
     ushort num31;
     if (Singleton<BuildingManager>.instance.CreateBuilding(out num31, ref Singleton<SimulationManager>.instance.m_randomizer, buildingInfo, vector6, num30, num26, Singleton<SimulationManager>.instance.m_currentBuildIndex))
     {
         Singleton<SimulationManager>.instance.m_currentBuildIndex += 1u;
         switch (service)
         {
             case ItemClass.Service.Residential:
                 instance.m_actualResidentialDemand = Mathf.Max(0, instance.m_actualResidentialDemand - 5);
                 break;
             case ItemClass.Service.Commercial:
                 instance.m_actualCommercialDemand = Mathf.Max(0, instance.m_actualCommercialDemand - 5);
                 break;
             case ItemClass.Service.Industrial:
                 instance.m_actualWorkplaceDemand = Mathf.Max(0, instance.m_actualWorkplaceDemand - 5);
                 break;
             case ItemClass.Service.Office:
                 instance.m_actualWorkplaceDemand = Mathf.Max(0, instance.m_actualWorkplaceDemand - 5);
                 break;
         }
     }
     instance.m_goodAreaFound[(int)zone] = 1024;
 }
 internal static void CheckBlock(ZoneBlock b, ref ZoneBlock other, int[] xBuffer, ItemClass.Zone zone, Vector2 startPos, Vector2 xDir, Vector2 zDir, Quad2 quad)
 {
     float f1 = Mathf.Abs(other.m_angle - b.m_angle) * 0.6366197f;
     float num1 = f1 - Mathf.Floor(f1);
     if ((double)num1 >= 0.00999999977648258 && (double)num1 <= 0.990000009536743)
         return;
     int rowCount = other.RowCount;
     Vector2 vector2_1 = new Vector2(Mathf.Cos(other.m_angle), Mathf.Sin(other.m_angle)) * 8f;
     Vector2 vector2_2 = new Vector2(vector2_1.y, -vector2_1.x);
     ulong num2 = other.m_valid & (ulong)~((long)other.m_occupied1 | (long)other.m_occupied2);
     Vector2 vector2_3 = VectorUtils.XZ(other.m_position);
     if (!quad.Intersect(new Quad2()
     {
         a = vector2_3 - 4f * vector2_1 - 4f * vector2_2,
         b = vector2_3 - 4f * vector2_2,
         c = vector2_3 + (float)(rowCount - 4) * vector2_2,
         d = vector2_3 - 4f * vector2_1 + (float)(rowCount - 4) * vector2_2
     }))
         return;
     for (int z = 0; z < rowCount; ++z)
     {
         Vector2 vector2_4 = ((float)z - 3.5f) * vector2_2;
         for (int x = 0; x < 4; ++x)
         {
             if (((long)num2 & 1L << (z << 3 | x)) != 0L && other.GetZone(x, z) == zone)
             {
                 Vector2 vector2_5 = ((float)x - 3.5f) * vector2_1;
                 Vector2 vector2_6 = vector2_3 + vector2_5 + vector2_4 - startPos;
                 float f2 = (float)(((double)vector2_6.x * (double)xDir.x + (double)vector2_6.y * (double)xDir.y) * (1.0 / 64.0));
                 float f3 = (float)(((double)vector2_6.x * (double)zDir.x + (double)vector2_6.y * (double)zDir.y) * (1.0 / 64.0));
                 int num3 = Mathf.RoundToInt(f2);
                 int num4 = Mathf.RoundToInt(f3);
                 if (num3 >= 0 && num3 <= 6 && (num4 >= -6 && num4 <= 6) && ((double)Mathf.Abs(f2 - (float)num3) < 0.0125000001862645 && (double)Mathf.Abs(f3 - (float)num4) < 0.0125000001862645 && (x == 0 || num3 != 0)))
                 {
                     xBuffer[num4 + 6] |= 1 << num3;
                     if (x == 0)
                         xBuffer[num4 + 6] |= 1 << num3 + 16;
                 }
             }
         }
     }
 }
Example #11
0
        // Detours

        public static void SimulationStep(ref ZoneBlock zoneBlock, ushort blockID)
        {
            // This is the decompiled ZoneBlock.SimulationStep() method
            // Segments which were changed are marked with "begin mod" and "end mod"

            if (Debugger.Enabled && debugCount < 10)
            {
                debugCount++;
                Debugger.LogFormat("Building Themes: Detoured ZoneBlock.SimulationStep was called. blockID: {0}, position: {1}.", blockID, zoneBlock.m_position);
            }

            ZoneManager zoneManager = Singleton <ZoneManager> .instance;
            int         rowCount    = zoneBlock.RowCount;
            float       m_angle     = zoneBlock.m_angle;

            Vector2 xDirection    = new Vector2(Mathf.Cos(m_angle), Mathf.Sin(m_angle)) * 8f;
            Vector2 zDirection    = new Vector2(xDirection.y, -xDirection.x);
            ulong   num           = zoneBlock.m_valid & ~(zoneBlock.m_occupied1 | zoneBlock.m_occupied2);
            int     spawnpointRow = 0;

            ItemClass.Zone zone = ItemClass.Zone.Unzoned;
            int            num3 = 0;

            while (num3 < 4 && zone == ItemClass.Zone.Unzoned)
            {
                spawnpointRow = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)rowCount);

                if ((num & 1uL << (spawnpointRow << 3)) != 0uL)
                {
                    zone = zoneBlock.GetZone(0, spawnpointRow);
                }
                num3++;
            }
            DistrictManager instance2 = Singleton <DistrictManager> .instance;

            Vector3 m_position = (Vector3)zoneBlock.m_position;

            byte district = instance2.GetDistrict(m_position);
            int  num4;

            switch (zone)
            {
            case ItemClass.Zone.ResidentialLow:
                num4  = zoneManager.m_actualResidentialDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialLowDemandOffset();
                break;

            case ItemClass.Zone.ResidentialHigh:
                num4  = zoneManager.m_actualResidentialDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialHighDemandOffset();
                break;

            case ItemClass.Zone.CommercialLow:
                num4  = zoneManager.m_actualCommercialDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialLowDemandOffset();
                break;

            case ItemClass.Zone.CommercialHigh:
                num4  = zoneManager.m_actualCommercialDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialHighDemandOffset();
                break;

            case ItemClass.Zone.Industrial:
                num4  = zoneManager.m_actualWorkplaceDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateIndustrialDemandOffset();
                break;

            case ItemClass.Zone.Office:
                num4  = zoneManager.m_actualWorkplaceDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateOfficeDemandOffset();
                break;

            default:
                return;
            }
            Vector2 a       = VectorUtils.XZ(m_position);
            Vector2 vector3 = a - 3.5f * xDirection + ((float)spawnpointRow - 3.5f) * zDirection;

            int[] tmpXBuffer = zoneManager.m_tmpXBuffer;
            for (int i = 0; i < 13; i++)
            {
                tmpXBuffer[i] = 0;
            }

            Quad2 quad = default(Quad2);

            quad.a = a - 4f * xDirection + ((float)spawnpointRow - 10f) * zDirection;
            quad.b = a + 3f * xDirection + ((float)spawnpointRow - 10f) * zDirection;
            quad.c = a + 3f * xDirection + ((float)spawnpointRow + 2f) * zDirection;
            quad.d = a - 4f * xDirection + ((float)spawnpointRow + 2f) * zDirection;
            Vector2 vector4 = quad.Min();
            Vector2 vector5 = quad.Max();

            //begin mod
            int num5 = Mathf.Max((int)((vector4.x - 46f) / 64f + _zoneGridHalfResolution), 0);
            int num6 = Mathf.Max((int)((vector4.y - 46f) / 64f + _zoneGridHalfResolution), 0);
            int num7 = Mathf.Min((int)((vector5.x + 46f) / 64f + _zoneGridHalfResolution), _zoneGridResolution - 1);
            int num8 = Mathf.Min((int)((vector5.y + 46f) / 64f + _zoneGridHalfResolution), _zoneGridResolution - 1);

            //end mod
            for (int j = num6; j <= num8; j++)
            {
                for (int k = num5; k <= num7; k++)
                {
                    //begin mod
                    ushort num9 = zoneManager.m_zoneGrid[j * _zoneGridResolution + k];
                    //end mod
                    int num10 = 0;
                    while (num9 != 0)
                    {
                        Vector3 positionVar = zoneManager.m_blocks.m_buffer[(int)num9].m_position;
                        float   num11       = Mathf.Max(Mathf.Max(vector4.x - 46f - positionVar.x, vector4.y - 46f - positionVar.z),
                                                        Mathf.Max(positionVar.x - vector5.x - 46f, positionVar.z - vector5.y - 46f));

                        if (num11 < 0f)
                        {
                            _CheckBlock.Invoke(zoneBlock, new object[] { zoneManager.m_blocks.m_buffer[(int)num9], tmpXBuffer, zone, vector3, xDirection, zDirection, quad });
                        }
                        num9 = zoneManager.m_blocks.m_buffer[(int)num9].m_nextGridBlock;
                        if (++num10 >= 49152)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }

            for (int l = 0; l < 13; l++)
            {
                uint num12 = (uint)tmpXBuffer[l];
                int  num13 = 0;
                bool flag  = (num12 & 196608u) == 196608u;
                bool flag2 = false;
                while ((num12 & 1u) != 0u)
                {
                    num13++;
                    flag2   = ((num12 & 65536u) != 0u);
                    num12 >>= 1;
                }
                if (num13 == 5 || num13 == 6)
                {
                    if (flag2)
                    {
                        num13 -= Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) + 2;
                    }
                    else
                    {
                        num13 = 4;
                    }
                    num13 |= 131072;
                }
                else if (num13 == 7)
                {
                    num13  = 4;
                    num13 |= 131072;
                }
                if (flag)
                {
                    num13 |= 65536;
                }
                tmpXBuffer[l] = num13;
            }
            int num14 = tmpXBuffer[6] & 65535;

            if (num14 == 0)
            {
                return;
            }

            bool flag3 = (bool)_IsGoodPlace.Invoke(zoneBlock, new object[] { vector3 });

            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(100u) >= num4)
            {
                if (flag3)
                {
                    zoneManager.m_goodAreaFound[(int)zone] = 1024;
                }
                return;
            }
            if (!flag3 && zoneManager.m_goodAreaFound[(int)zone] > -1024)
            {
                if (zoneManager.m_goodAreaFound[(int)zone] == 0)
                {
                    zoneManager.m_goodAreaFound[(int)zone] = -1;
                }
                return;
            }
            int  num15 = 6;
            int  num16 = 6;
            bool flag4 = true;

            while (true)
            {
                if (flag4)
                {
                    while (num15 != 0)
                    {
                        if ((tmpXBuffer[num15 - 1] & 65535) != num14)
                        {
                            break;
                        }
                        num15--;
                    }
                    while (num16 != 12)
                    {
                        if ((tmpXBuffer[num16 + 1] & 65535) != num14)
                        {
                            break;
                        }
                        num16++;
                    }
                }
                else
                {
                    while (num15 != 0)
                    {
                        if ((tmpXBuffer[num15 - 1] & 65535) < num14)
                        {
                            break;
                        }
                        num15--;
                    }
                    while (num16 != 12)
                    {
                        if ((tmpXBuffer[num16 + 1] & 65535) < num14)
                        {
                            break;
                        }
                        num16++;
                    }
                }
                int num17 = num15;
                int num18 = num16;
                while (num17 != 0)
                {
                    if ((tmpXBuffer[num17 - 1] & 65535) < 2)
                    {
                        break;
                    }
                    num17--;
                }
                while (num18 != 12)
                {
                    if ((tmpXBuffer[num18 + 1] & 65535) < 2)
                    {
                        break;
                    }
                    num18++;
                }
                bool flag5 = num17 != 0 && num17 == num15 - 1;
                bool flag6 = num18 != 12 && num18 == num16 + 1;
                if (flag5 && flag6)
                {
                    if (num16 - num15 > 2)
                    {
                        break;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_34;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                else if (flag5)
                {
                    if (num16 - num15 > 1)
                    {
                        goto Block_36;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_38;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                else if (flag6)
                {
                    if (num16 - num15 > 1)
                    {
                        goto Block_40;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_42;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                else
                {
                    if (num15 != num16)
                    {
                        goto IL_884;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_45;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                flag4 = false;
            }
            num15++;
            num16--;
Block_34:
            goto IL_891;
Block_36:
            num15++;
Block_38:
            goto IL_891;
Block_40:
            num16--;
Block_42:
Block_45:
IL_884:
IL_891:
            int num19;
            int num20;

            if (num14 == 1 && num16 - num15 >= 1)
            {
                num15 += Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)(num16 - num15));

                num16 = num15 + 1;
                num19 = num15 + Singleton <SimulationManager> .instance.m_randomizer.Int32(2u);

                num20 = num19;
            }
            else
            {
                do
                {
                    num19 = num15;
                    num20 = num16;
                    if (num16 - num15 == 2)
                    {
                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num20--;
                        }
                        else
                        {
                            num19++;
                        }
                    }
                    else if (num16 - num15 == 3)
                    {
                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num20 -= 2;
                        }
                        else
                        {
                            num19 += 2;
                        }
                    }
                    else if (num16 - num15 == 4)
                    {
                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num16 -= 2;
                            num20 -= 3;
                        }
                        else
                        {
                            num15 += 2;
                            num19 += 3;
                        }
                    }
                    else if (num16 - num15 == 5)
                    {
                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num16 -= 3;
                            num20 -= 2;
                        }
                        else
                        {
                            num15 += 3;
                            num19 += 2;
                        }
                    }
                    else if (num16 - num15 >= 6)
                    {
                        if (num15 == 0 || num16 == 12)
                        {
                            if (num15 == 0)
                            {
                                num15 = 3;
                                num19 = 2;
                            }
                            if (num16 == 12)
                            {
                                num16 = 9;
                                num20 = 10;
                            }
                        }
                        else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num16 = num15 + 3;
                            num20 = num19 + 2;
                        }
                        else
                        {
                            num15 = num16 - 3;
                            num19 = num20 - 2;
                        }
                    }
                }while (num16 - num15 > 3 || num20 - num19 > 3);
            }
            int depth_A = 4;
            int width_A = num16 - num15 + 1;

            BuildingInfo.ZoningMode zoningMode = BuildingInfo.ZoningMode.Straight;
            bool flag7 = true;

            for (int m = num15; m <= num16; m++)
            {
                depth_A = Mathf.Min(depth_A, tmpXBuffer[m] & 65535);
                if ((tmpXBuffer[m] & 131072) == 0)
                {
                    flag7 = false;
                }
            }
            if (num16 > num15)
            {
                if ((tmpXBuffer[num15] & 65536) != 0)
                {
                    zoningMode = BuildingInfo.ZoningMode.CornerLeft;
                    num20      = num15 + num20 - num19;
                    num19      = num15;
                }
                if ((tmpXBuffer[num16] & 65536) != 0 && (zoningMode != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0))
                {
                    zoningMode = BuildingInfo.ZoningMode.CornerRight;
                    num19      = num16 + num19 - num20;
                    num20      = num16;
                }
            }
            int depth_B = 4;
            int width_B = num20 - num19 + 1;

            BuildingInfo.ZoningMode zoningMode2 = BuildingInfo.ZoningMode.Straight;
            bool flag8 = true;

            for (int n = num19; n <= num20; n++)
            {
                depth_B = Mathf.Min(depth_B, tmpXBuffer[n] & 65535);
                if ((tmpXBuffer[n] & 131072) == 0)
                {
                    flag8 = false;
                }
            }
            if (num20 > num19)
            {
                if ((tmpXBuffer[num19] & 65536) != 0)
                {
                    zoningMode2 = BuildingInfo.ZoningMode.CornerLeft;
                }
                if ((tmpXBuffer[num20] & 65536) != 0 && (zoningMode2 != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0))
                {
                    zoningMode2 = BuildingInfo.ZoningMode.CornerRight;
                }
            }
            ItemClass.SubService subService = ItemClass.SubService.None;
            ItemClass.Level      level      = ItemClass.Level.Level1;
            ItemClass.Service    service;
            switch (zone)
            {
            case ItemClass.Zone.ResidentialLow:
                service    = ItemClass.Service.Residential;
                subService = ItemClass.SubService.ResidentialLow;
                break;

            case ItemClass.Zone.ResidentialHigh:
                service    = ItemClass.Service.Residential;
                subService = ItemClass.SubService.ResidentialHigh;
                break;

            case ItemClass.Zone.CommercialLow:
                service    = ItemClass.Service.Commercial;
                subService = ItemClass.SubService.CommercialLow;
                break;

            case ItemClass.Zone.CommercialHigh:
                service    = ItemClass.Service.Commercial;
                subService = ItemClass.SubService.CommercialHigh;
                break;

            case ItemClass.Zone.Industrial:
                service = ItemClass.Service.Industrial;
                break;

            case ItemClass.Zone.Office:
                service    = ItemClass.Service.Office;
                subService = ItemClass.SubService.None;
                break;

            default:
                return;
            }
            BuildingInfo buildingInfo = null;
            Vector3      vector6      = Vector3.zero;
            int          num25_row    = 0;
            int          length       = 0;
            int          width        = 0;

            BuildingInfo.ZoningMode zoningMode3 = BuildingInfo.ZoningMode.Straight;
            int num28 = 0;

            // begin mod
            int depth_alt = Mathf.Min(depth_A, 4);
            int width_alt = width_A;

            // end mod

            while (num28 < 8) // while (num28 < 6)
            {
                switch (num28)
                {
                // Corner cases

                case 0:
                    if (zoningMode != BuildingInfo.ZoningMode.Straight)
                    {
                        num25_row   = num15 + num16 + 1;
                        length      = depth_A;
                        width       = width_A;
                        zoningMode3 = zoningMode;
                        goto IL_D6A;
                    }
                    break;

                case 1:
                    if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                    {
                        num25_row   = num19 + num20 + 1;
                        length      = depth_B;
                        width       = width_B;
                        zoningMode3 = zoningMode2;
                        goto IL_D6A;
                    }
                    break;

                case 2:
                    if (zoningMode != BuildingInfo.ZoningMode.Straight)
                    {
                        if (depth_A >= 4)
                        {
                            num25_row   = num15 + num16 + 1;
                            length      = ((!flag7) ? 2 : 3);
                            width       = width_A;
                            zoningMode3 = zoningMode;
                            goto IL_D6A;
                        }
                    }
                    break;

                case 3:
                    if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                    {
                        if (depth_B >= 4)
                        {
                            num25_row   = num19 + num20 + 1;
                            length      = ((!flag8) ? 2 : 3);
                            width       = width_B;
                            zoningMode3 = zoningMode2;
                            goto IL_D6A;
                        }
                    }
                    break;

                // begin mod
                case 4:
                    if (zoningMode != BuildingInfo.ZoningMode.Straight)
                    {
                        if (width_alt > 1)
                        {
                            width_alt--;
                        }
                        else if (depth_alt > 1)
                        {
                            depth_alt--;
                            width_alt = width_A;
                        }
                        else
                        {
                            break;
                        }

                        if (width_alt == width_A)
                        {
                            num25_row = num15 + num16 + 1;
                        }
                        else
                        {
                            if (zoningMode == BuildingInfo.ZoningMode.CornerLeft)
                            {
                                num25_row = num15 + num16 + 1 - (width_A - width_alt);
                            }
                            else
                            {
                                num25_row = num15 + num16 + 1 + (width_A - width_alt);
                            }
                        }

                        length = depth_alt;
                        width  = width_alt;

                        zoningMode3 = zoningMode;

                        num28--;
                        goto IL_D6A;
                    }
                    break;

                // end mod
                // Straight cases
                case 5:
                    num25_row   = num15 + num16 + 1;
                    length      = depth_A;
                    width       = width_A;
                    zoningMode3 = BuildingInfo.ZoningMode.Straight;
                    goto IL_D6A;

                case 6:
                    // begin mod

                    // reset variables
                    depth_alt = Mathf.Min(depth_A, 4);
                    width_alt = width_A;

                    // end mod

                    //int width_B = num20 - num19 + 1;
                    num25_row   = num19 + num20 + 1;
                    length      = depth_B;
                    width       = width_B;
                    zoningMode3 = BuildingInfo.ZoningMode.Straight;
                    goto IL_D6A;

                // begin mod
                case 7:

                    if (width_alt > 1)
                    {
                        width_alt--;
                    }
                    else
                    {
                        break;
                    }

                    if (width_alt == width_A)
                    {
                        num25_row = num15 + num16 + 1;
                    }
                    else if (width_A % 2 != width_alt % 2)
                    {
                        num25_row = num15 + num16;
                    }
                    else
                    {
                        num25_row = num15 + num16 + 1;
                    }

                    length = depth_alt;
                    width  = width_alt;

                    zoningMode3 = BuildingInfo.ZoningMode.Straight;

                    num28--;
                    goto IL_D6A;

                // end mod
                default:
                    goto IL_D6A;
                }
IL_DF0:
                num28++;
                continue;
IL_D6A:
                vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection);
                if (zone == ItemClass.Zone.Industrial)
                {
                    ZoneBlock.GetIndustryType(vector6, out subService, out level);
                }
                else if (zone == ItemClass.Zone.CommercialLow || zone == ItemClass.Zone.CommercialHigh)
                {
                    ZoneBlock.GetCommercialType(vector6, zone, width, length, out subService, out level);
                }

                byte   district2 = instance2.GetDistrict(vector6);
                ushort style     = instance2.m_districts.m_buffer[(int)district2].m_Style;

                // begin mod

                // Here we are calling a custom getRandomBuildingInfo method

                buildingInfo = BuildingManagerDetour.GetRandomBuildingInfo_Spawn(vector6, ref Singleton <SimulationManager> .instance.m_randomizer, service, subService, level, width, length, zoningMode3, style);

                // end mod

                if (buildingInfo != null)
                {
                    // begin mod

                    // If the depth of the found prefab is smaller than the one we were looking for, recalculate the size
                    // This is done by checking the position of every prop
                    // Plots only get shrinked when no assets are placed on the extra space

                    // This is needed for themes which only contain small buildings (e.g. 1x2)
                    // because those buildings would occupy more space than needed!

                    if (buildingInfo.GetWidth() == width && buildingInfo.GetLength() != length)
                    {
                        // Calculate the z position of the furthest away prop
                        float biggestPropPosZ = 0;

                        if (buildingInfo.m_props != null)
                        {
                            foreach (var prop in buildingInfo.m_props)
                            {
                                if (prop == null)
                                {
                                    continue;
                                }

                                biggestPropPosZ = Mathf.Max(biggestPropPosZ, buildingInfo.m_expandFrontYard ? prop.m_position.z : -prop.m_position.z);
                            }
                        }

                        // Check if the furthest away prop is outside of the bounds of the prefab
                        float occupiedExtraSpace = biggestPropPosZ - buildingInfo.GetLength() * 4;
                        if (occupiedExtraSpace <= 0)
                        {
                            // No? Then shrink the plot to the prefab length so no space is wasted!
                            length = buildingInfo.GetLength();
                        }
                        else
                        {
                            // Yes? Shrink the plot so all props are in the bounds
                            int newLength = buildingInfo.GetLength() + Mathf.CeilToInt(occupiedExtraSpace / 8);
                            length = Mathf.Min(length, newLength);
                        }

                        vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection);
                    }

                    // This block handles Corner buildings. We always shrink them
                    else if (buildingInfo.GetLength() == width && buildingInfo.GetWidth() != length)
                    {
                        length  = buildingInfo.GetWidth();
                        vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection);
                    }

                    // end mod

                    if (Debugger.Enabled)
                    {
                        Debugger.LogFormat("Found prefab: {5} - {0}, {1}, {2}, {3} x {4}", service, subService, level, width, length, buildingInfo.name);
                    }
                    break;
                }
                if (Debugger.Enabled)
                {
                }
                goto IL_DF0;
            }
            if (buildingInfo == null)
            {
                if (Debugger.Enabled)
                {
                    Debugger.LogFormat("No prefab found: {0}, {1}, {2}, {3} x {4}", service, subService, level, width, length);
                }
                return;
            }
            float num29 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector6));

            if (num29 > vector6.y)
            {
                return;
            }
            float num30 = m_angle + 1.57079637f;

            if (zoningMode3 == BuildingInfo.ZoningMode.CornerLeft && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerRight)
            {
                num30 -= 1.57079637f;
                length = width;
            }
            else if (zoningMode3 == BuildingInfo.ZoningMode.CornerRight && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft)
            {
                num30 += 1.57079637f;
                length = width;
            }
            ushort num31;

            if (Singleton <BuildingManager> .instance.CreateBuilding(out num31, ref Singleton <SimulationManager> .instance.m_randomizer, buildingInfo, vector6, num30, length, Singleton <SimulationManager> .instance.m_currentBuildIndex))
            {
                Singleton <SimulationManager> .instance.m_currentBuildIndex += 1u;
                switch (service)
                {
                case ItemClass.Service.Residential:
                    zoneManager.m_actualResidentialDemand = Mathf.Max(0, zoneManager.m_actualResidentialDemand - 5);
                    break;

                case ItemClass.Service.Commercial:
                    zoneManager.m_actualCommercialDemand = Mathf.Max(0, zoneManager.m_actualCommercialDemand - 5);
                    break;

                case ItemClass.Service.Industrial:
                    zoneManager.m_actualWorkplaceDemand = Mathf.Max(0, zoneManager.m_actualWorkplaceDemand - 5);
                    break;

                case ItemClass.Service.Office:
                    zoneManager.m_actualWorkplaceDemand = Mathf.Max(0, zoneManager.m_actualWorkplaceDemand - 5);
                    break;
                }

                switch (zone)
                {
                case ItemClass.Zone.ResidentialHigh:
                case ItemClass.Zone.CommercialHigh:
                {
                    Building[] expr_FD7_cp_0 = Singleton <BuildingManager> .instance.m_buildings.m_buffer;
                    ushort     expr_FD7_cp_1 = num31;
                    expr_FD7_cp_0[(int)expr_FD7_cp_1].m_flags = (expr_FD7_cp_0[(int)expr_FD7_cp_1].m_flags | Building.Flags.HighDensity);
                    break;
                }
                }
            }
            zoneManager.m_goodAreaFound[(int)zone] = 1024;
        }
 private static void Snap(ZoneTool _this, ref Vector3 point, ref Vector3 direction, ref ItemClass.Zone zone, ref bool occupied1, ref bool occupied2, ref ZoneBlock block)
 {
     direction = new Vector3(Mathf.Cos(block.m_angle), 0.0f, Mathf.Sin(block.m_angle));
     Vector3 vector3_1 = direction * 8f;
     Vector3 vector3_2 = new Vector3(vector3_1.z, 0.0f, -vector3_1.x);
     Vector3 vector3_3 = block.m_position + vector3_1 * 0.5f + vector3_2 * 0.5f;
     Vector2 vector2 = new Vector2(point.x - vector3_3.x, point.z - vector3_3.z);
     int num1 = Mathf.RoundToInt((float)(((double)vector2.x * (double)vector3_1.x + (double)vector2.y * (double)vector3_1.z) * (1.0 / 64.0)));
     int num2 = Mathf.RoundToInt((float)(((double)vector2.x * (double)vector3_2.x + (double)vector2.y * (double)vector3_2.z) * (1.0 / 64.0)));
     point.x = (float)((double)vector3_3.x + (double)num1 * (double)vector3_1.x + (double)num2 * (double)vector3_2.x);
     point.z = (float)((double)vector3_3.z + (double)num1 * (double)vector3_1.z + (double)num2 * (double)vector3_2.z);
     // changed from:
     // if (num1 < -4 || num1 >= 0 || (num2 < -4 || num2 >= 4))
     if (num1 < -4 || num1 >= 4 || (num2 < -4 || num2 >= 4))
         return;
     zone = block.GetZone(num1 + 4, num2 + 4); // keep old method (it's only a single call)
     occupied1 = block.IsOccupied1(num1 + 4, num2 + 4);
     occupied2 = block.IsOccupied2(num1 + 4, num2 + 4);
 }
Example #13
0
        public static void SimulationStep(ref ZoneBlock block, ushort blockID)
        {
            ZoneManager instance1 = Singleton <ZoneManager> .instance;
            int         rowCount  = block.RowCount;
            Vector2     xDir      = new Vector2(Mathf.Cos(block.m_angle), Mathf.Sin(block.m_angle)) * 8f;
            Vector2     zDir      = new Vector2(xDir.y, -xDir.x);
            ulong       num1      = block.m_valid & (ulong)~((long)block.m_occupied1 | (long)block.m_occupied2);
            int         z         = 0;

            ItemClass.Zone zone = ItemClass.Zone.Unzoned;
            for (int index = 0; index < 4 && zone == ItemClass.Zone.Unzoned; ++index)
            {
                z = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)rowCount);

                if (((long)num1 & 1L << (z << 3)) != 0L)
                {
                    zone = block.GetZone(0, z);
                }
            }
            DistrictManager instance2 = Singleton <DistrictManager> .instance;
            byte            district1 = instance2.GetDistrict(block.m_position);
            int             num2;

            switch (zone)
            {
            case ItemClass.Zone.ResidentialLow:
                num2 = instance1.m_actualResidentialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateResidentialLowDemandOffset();
                break;

            case ItemClass.Zone.ResidentialHigh:
                num2 = instance1.m_actualResidentialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateResidentialHighDemandOffset();
                break;

            case ItemClass.Zone.CommercialLow:
                num2 = instance1.m_actualCommercialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateCommercialLowDemandOffset();
                break;

            case ItemClass.Zone.CommercialHigh:
                num2 = instance1.m_actualCommercialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateCommercialHighDemandOffset();
                break;

            case ItemClass.Zone.Industrial:
                num2 = instance1.m_actualWorkplaceDemand + instance2.m_districts.m_buffer[(int)district1].CalculateIndustrialDemandOffset();
                break;

            case ItemClass.Zone.Office:
                num2 = instance1.m_actualWorkplaceDemand + instance2.m_districts.m_buffer[(int)district1].CalculateOfficeDemandOffset();
                break;

            default:
                return;
            }
            Vector2 vector2_1 = VectorUtils.XZ(block.m_position);
            Vector2 vector2_2 = vector2_1 - 3.5f * xDir + ((float)z - 3.5f) * zDir;

            int[] xBuffer = instance1.m_tmpXBuffer;
            for (int index = 0; index < 13; ++index)
            {
                xBuffer[index] = 0;
            }
            Quad2 quad = new Quad2();

            quad.a = vector2_1 - 4f * xDir + ((float)z - 10f) * zDir;
            quad.b = vector2_1 + 3f * xDir + ((float)z - 10f) * zDir;
            quad.c = vector2_1 + 3f * xDir + ((float)z + 2f) * zDir;
            quad.d = vector2_1 - 4f * xDir + ((float)z + 2f) * zDir;
            Vector2 vector2_3 = quad.Min();
            Vector2 vector2_4 = quad.Max();
            //begin mod
            int num3 = Mathf.Max((int)(((double)vector2_3.x - 46.0) / 64.0 + FakeZoneManager.HALFGRID), 0);
            int num4 = Mathf.Max((int)(((double)vector2_3.y - 46.0) / 64.0 + FakeZoneManager.HALFGRID), 0);
            int num5 = Mathf.Min((int)(((double)vector2_4.x + 46.0) / 64.0 + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);
            int num6 = Mathf.Min((int)(((double)vector2_4.y + 46.0) / 64.0 + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);

            //end mod
            for (int index1 = num4; index1 <= num6; ++index1)
            {
                for (int index2 = num3; index2 <= num5; ++index2)
                {
                    //begin mod
                    ushort num7 = instance1.m_zoneGrid[index1 * FakeZoneManager.GRIDSIZE + index2];
                    //end mod
                    int num8 = 0;
                    while ((int)num7 != 0)
                    {
                        Vector3 vector3 = instance1.m_blocks.m_buffer[(int)num7].m_position;
                        if ((double)Mathf.Max(Mathf.Max(vector2_3.x - 46f - vector3.x, vector2_3.y - 46f - vector3.z), Mathf.Max((float)((double)vector3.x - (double)vector2_4.x - 46.0), (float)((double)vector3.z - (double)vector2_4.y - 46.0))) < 0.0)
                        {
                            //begin mod
                            CheckBlock(ref block, ref instance1.m_blocks.m_buffer[(int)num7], xBuffer, zone, vector2_2, xDir, zDir, quad);
                        }
                        //end mod
                        num7 = instance1.m_blocks.m_buffer[(int)num7].m_nextGridBlock;
                        if (++num8 >= 49152)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            for (int index = 0; index < 13; ++index)
            {
                uint num7  = (uint)xBuffer[index];
                int  num8  = 0;
                bool flag1 = ((int)num7 & 196608) == 196608;
                bool flag2 = false;
                while (((int)num7 & 1) != 0)
                {
                    ++num8;
                    flag2  = ((int)num7 & 65536) != 0;
                    num7 >>= 1;
                }
                if (num8 == 5 || num8 == 6)
                {
                    num8 = (!flag2 ? 4 : num8 - (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) + 2)) | 131072;
                }
                else if (num8 == 7)
                {
                    num8 = 4 | 131072;
                }
                if (flag1)
                {
                    num8 |= 65536;
                }
                xBuffer[index] = num8;
            }
            int num9 = xBuffer[6] & (int)ushort.MaxValue;

            if (num9 == 0)
            {
                return;
            }
            //begin mod
            bool flag3 = IsGoodPlace(ref block, vector2_2);

            //end mod
            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(100U) >= num2)
            {
                if (!flag3)
                {
                    return;
                }
                instance1.m_goodAreaFound[(int)zone] = (short)1024;
            }
            else if (!flag3 && (int)instance1.m_goodAreaFound[(int)zone] > -1024)
            {
                if ((int)instance1.m_goodAreaFound[(int)zone] != 0)
                {
                    return;
                }
                instance1.m_goodAreaFound[(int)zone] = (short)-1;
            }
            else
            {
                int  index1 = 6;
                int  index2 = 6;
                bool flag1  = true;
                while (true)
                {
                    if (flag1)
                    {
                        while (index1 != 0 && (xBuffer[index1 - 1] & (int)ushort.MaxValue) == num9)
                        {
                            --index1;
                        }
                        while (index2 != 12 && (xBuffer[index2 + 1] & (int)ushort.MaxValue) == num9)
                        {
                            ++index2;
                        }
                    }
                    else
                    {
                        while (index1 != 0 && (xBuffer[index1 - 1] & (int)ushort.MaxValue) >= num9)
                        {
                            --index1;
                        }
                        while (index2 != 12 && (xBuffer[index2 + 1] & (int)ushort.MaxValue) >= num9)
                        {
                            ++index2;
                        }
                    }
                    int num7 = index1;
                    int num8 = index2;
                    while (num7 != 0 && (xBuffer[num7 - 1] & (int)ushort.MaxValue) >= 2)
                    {
                        --num7;
                    }
                    while (num8 != 12 && (xBuffer[num8 + 1] & (int)ushort.MaxValue) >= 2)
                    {
                        ++num8;
                    }
                    bool flag2 = num7 != 0 && num7 == index1 - 1;
                    bool flag4 = num8 != 12 && num8 == index2 + 1;
                    if (flag2 && flag4)
                    {
                        if (index2 - index1 <= 2)
                        {
                            if (num9 <= 2)
                            {
                                if (!flag1)
                                {
                                    goto label_88;
                                }
                            }
                            else
                            {
                                --num9;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else if (flag2)
                    {
                        if (index2 - index1 <= 1)
                        {
                            if (num9 <= 2)
                            {
                                if (!flag1)
                                {
                                    goto label_88;
                                }
                            }
                            else
                            {
                                --num9;
                            }
                        }
                        else
                        {
                            goto label_73;
                        }
                    }
                    else if (flag4)
                    {
                        if (index2 - index1 <= 1)
                        {
                            if (num9 <= 2)
                            {
                                if (!flag1)
                                {
                                    goto label_88;
                                }
                            }
                            else
                            {
                                --num9;
                            }
                        }
                        else
                        {
                            goto label_79;
                        }
                    }
                    else if (index1 == index2)
                    {
                        if (num9 <= 2)
                        {
                            if (!flag1)
                            {
                                goto label_88;
                            }
                        }
                        else
                        {
                            --num9;
                        }
                    }
                    else
                    {
                        goto label_88;
                    }
                    flag1 = false;
                }
                ++index1;
                --index2;
                goto label_88;
label_73:
                ++index1;
                goto label_88;
label_79:
                --index2;
label_88:
                int index3;
                int index4;
                if (num9 == 1 && index2 - index1 >= 1)
                {
                    index1 += Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)(index2 - index1));

                    index2 = index1 + 1;
                    index3 = index1 + Singleton <SimulationManager> .instance.m_randomizer.Int32(2U);

                    index4 = index3;
                }
                else
                {
                    do
                    {
                        index3 = index1;
                        index4 = index2;
                        if (index2 - index1 == 2)
                        {
                            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                --index4;
                            }
                            else
                            {
                                ++index3;
                            }
                        }
                        else if (index2 - index1 == 3)
                        {
                            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                index4 -= 2;
                            }
                            else
                            {
                                index3 += 2;
                            }
                        }
                        else if (index2 - index1 == 4)
                        {
                            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                index2 -= 2;
                                index4 -= 3;
                            }
                            else
                            {
                                index1 += 2;
                                index3 += 3;
                            }
                        }
                        else if (index2 - index1 == 5)
                        {
                            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                index2 -= 3;
                                index4 -= 2;
                            }
                            else
                            {
                                index1 += 3;
                                index3 += 2;
                            }
                        }
                        else if (index2 - index1 >= 6)
                        {
                            if (index1 == 0 || index2 == 12)
                            {
                                if (index1 == 0)
                                {
                                    index1 = 3;
                                    index3 = 2;
                                }
                                if (index2 == 12)
                                {
                                    index2 = 9;
                                    index4 = 10;
                                }
                            }
                            else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                index2 = index1 + 3;
                                index4 = index3 + 2;
                            }
                            else
                            {
                                index1 = index2 - 3;
                                index3 = index4 - 2;
                            }
                        }
                    }while (index2 - index1 > 3 || index4 - index3 > 3);
                }
                int a1    = 4;
                int num10 = index2 - index1 + 1;
                BuildingInfo.ZoningMode zoningMode1 = BuildingInfo.ZoningMode.Straight;
                bool flag5 = true;
                for (int index5 = index1; index5 <= index2; ++index5)
                {
                    a1 = Mathf.Min(a1, xBuffer[index5] & (int)ushort.MaxValue);
                    if ((xBuffer[index5] & 131072) == 0)
                    {
                        flag5 = false;
                    }
                }
                if (index2 > index1)
                {
                    if ((xBuffer[index1] & 65536) != 0)
                    {
                        zoningMode1 = BuildingInfo.ZoningMode.CornerLeft;
                        index4      = index1 + index4 - index3;
                        index3      = index1;
                    }
                    if ((xBuffer[index2] & 65536) != 0 && (zoningMode1 != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0))
                    {
                        zoningMode1 = BuildingInfo.ZoningMode.CornerRight;
                        index3      = index2 + index3 - index4;
                        index4      = index2;
                    }
                }
                int a2    = 4;
                int num11 = index4 - index3 + 1;
                BuildingInfo.ZoningMode zoningMode2 = BuildingInfo.ZoningMode.Straight;
                bool flag6 = true;
                for (int index5 = index3; index5 <= index4; ++index5)
                {
                    a2 = Mathf.Min(a2, xBuffer[index5] & (int)ushort.MaxValue);
                    if ((xBuffer[index5] & 131072) == 0)
                    {
                        flag6 = false;
                    }
                }
                if (index4 > index3)
                {
                    if ((xBuffer[index3] & 65536) != 0)
                    {
                        zoningMode2 = BuildingInfo.ZoningMode.CornerLeft;
                    }
                    if ((xBuffer[index4] & 65536) != 0 && (zoningMode2 != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0))
                    {
                        zoningMode2 = BuildingInfo.ZoningMode.CornerRight;
                    }
                }
                ItemClass.SubService subService = ItemClass.SubService.None;
                ItemClass.Level      level      = ItemClass.Level.Level1;
                ItemClass.Service    service;
                switch (zone)
                {
                case ItemClass.Zone.ResidentialLow:
                    service    = ItemClass.Service.Residential;
                    subService = ItemClass.SubService.ResidentialLow;
                    break;

                case ItemClass.Zone.ResidentialHigh:
                    service    = ItemClass.Service.Residential;
                    subService = ItemClass.SubService.ResidentialHigh;
                    break;

                case ItemClass.Zone.CommercialLow:
                    service    = ItemClass.Service.Commercial;
                    subService = ItemClass.SubService.CommercialLow;
                    break;

                case ItemClass.Zone.CommercialHigh:
                    service    = ItemClass.Service.Commercial;
                    subService = ItemClass.SubService.CommercialHigh;
                    break;

                case ItemClass.Zone.Industrial:
                    service = ItemClass.Service.Industrial;
                    break;

                case ItemClass.Zone.Office:
                    service = ItemClass.Service.Office;
                    break;

                default:
                    return;
                }
                BuildingInfo            info        = (BuildingInfo)null;
                Vector3                 vector3     = Vector3.zero;
                int                     num12       = 0;
                int                     num13       = 0;
                int                     width       = 0;
                BuildingInfo.ZoningMode zoningMode3 = BuildingInfo.ZoningMode.Straight;
                for (int index5 = 0; index5 < 6; ++index5)
                {
                    switch (index5)
                    {
                    case 0:
                        if (zoningMode1 != BuildingInfo.ZoningMode.Straight)
                        {
                            num12       = index1 + index2 + 1;
                            num13       = a1;
                            width       = num10;
                            zoningMode3 = zoningMode1;
                            goto default;
                        }
                        else
                        {
                            break;
                        }

                    case 1:
                        if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                        {
                            num12       = index3 + index4 + 1;
                            num13       = a2;
                            width       = num11;
                            zoningMode3 = zoningMode2;
                            goto default;
                        }
                        else
                        {
                            break;
                        }

                    case 2:
                        if (zoningMode1 != BuildingInfo.ZoningMode.Straight && a1 >= 4)
                        {
                            num12       = index1 + index2 + 1;
                            num13       = !flag5 ? 2 : 3;
                            width       = num10;
                            zoningMode3 = zoningMode1;
                            goto default;
                        }
                        else
                        {
                            break;
                        }

                    case 3:
                        if (zoningMode2 != BuildingInfo.ZoningMode.Straight && a2 >= 4)
                        {
                            num12       = index3 + index4 + 1;
                            num13       = !flag6 ? 2 : 3;
                            width       = num11;
                            zoningMode3 = zoningMode2;
                            goto default;
                        }
                        else
                        {
                            break;
                        }

                    case 4:
                        num12       = index1 + index2 + 1;
                        num13       = a1;
                        width       = num10;
                        zoningMode3 = BuildingInfo.ZoningMode.Straight;
                        goto default;

                    case 5:
                        num12       = index3 + index4 + 1;
                        num13       = a2;
                        width       = num11;
                        zoningMode3 = BuildingInfo.ZoningMode.Straight;
                        goto default;

                    default:
                        vector3 = block.m_position + VectorUtils.X_Y((float)((double)num13 * 0.5 - 4.0) * xDir + (float)((double)num12 * 0.5 + (double)z - 10.0) * zDir);
                        if (zone == ItemClass.Zone.Industrial)
                        {
                            ZoneBlock.GetIndustryType(vector3, out subService, out level);
                        }
                        else if (zone == ItemClass.Zone.CommercialLow || zone == ItemClass.Zone.CommercialHigh)
                        {
                            ZoneBlock.GetCommercialType(vector3, zone, width, num13, out subService, out level);
                        }
                        else if (zone == ItemClass.Zone.ResidentialLow || zone == ItemClass.Zone.ResidentialHigh)
                        {
                            ZoneBlock.GetResidentialType(vector3, zone, width, num13, out subService, out level);
                        }
                        else if (zone == ItemClass.Zone.Office)
                        {
                            ZoneBlock.GetOfficeType(vector3, zone, width, num13, out subService, out level);
                        }
                        byte   district2 = instance2.GetDistrict(vector3);
                        ushort style     = instance2.m_districts.m_buffer[(int)district2].m_Style;
                        if (Singleton <BuildingManager> .instance.m_BuildingWrapper != null)
                        {
                            Singleton <BuildingManager> .instance.m_BuildingWrapper.OnCalculateSpawn(vector3, ref service, ref subService, ref level, ref style);
                        }
                        info = Singleton <BuildingManager> .instance.GetRandomBuildingInfo(ref Singleton <SimulationManager> .instance.m_randomizer, service, subService, level, width, num13, zoningMode3, (int)style);

                        if (info == null)
                        {
                            break;
                        }
                        goto label_169;
                    }
                }
label_169:
                if (info == null || (double)Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector3)) > (double)vector3.y || Singleton <DisasterManager> .instance.IsEvacuating(vector3))
                {
                    return;
                }
                float angle = block.m_angle + 1.570796f;
                if (zoningMode3 == BuildingInfo.ZoningMode.CornerLeft && info.m_zoningMode == BuildingInfo.ZoningMode.CornerRight)
                {
                    angle -= 1.570796f;
                    num13  = width;
                }
                else if (zoningMode3 == BuildingInfo.ZoningMode.CornerRight && info.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft)
                {
                    angle += 1.570796f;
                    num13  = width;
                }
                ushort building;
                if (Singleton <BuildingManager> .instance.CreateBuilding(out building, ref Singleton <SimulationManager> .instance.m_randomizer, info, vector3, angle, num13, Singleton <SimulationManager> .instance.m_currentBuildIndex))
                {
                    ++Singleton <SimulationManager> .instance.m_currentBuildIndex;
                    switch (service)
                    {
                    case ItemClass.Service.Residential:
                        instance1.m_actualResidentialDemand = Mathf.Max(0, instance1.m_actualResidentialDemand - 5);
                        break;

                    case ItemClass.Service.Commercial:
                        instance1.m_actualCommercialDemand = Mathf.Max(0, instance1.m_actualCommercialDemand - 5);
                        break;

                    case ItemClass.Service.Industrial:
                        instance1.m_actualWorkplaceDemand = Mathf.Max(0, instance1.m_actualWorkplaceDemand - 5);
                        break;

                    case ItemClass.Service.Office:
                        instance1.m_actualWorkplaceDemand = Mathf.Max(0, instance1.m_actualWorkplaceDemand - 5);
                        break;
                    }
                    switch (zone)
                    {
                    case ItemClass.Zone.ResidentialHigh:
                    case ItemClass.Zone.CommercialHigh:
                        Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)building].m_flags |= Building.Flags.HighDensity;
                        break;
                    }
                }
                instance1.m_goodAreaFound[(int)zone] = (short)1024;
            }
        }
        private static void CalculateFillBuffer(ZoneTool zt, Vector3 position, Vector3 direction, float angle, ushort blockIndex, ref ZoneBlock block, ItemClass.Zone requiredZone, bool occupied1, bool occupied2)
        {
            var m_fillBuffer1 = (ulong[])typeof(ZoneTool).GetField("m_fillBuffer1", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(zt);

            float f1 = Mathf.Abs(block.m_angle - angle) * 0.6366197f;
            float num1 = f1 - Mathf.Floor(f1);
            if ((double)num1 >= 0.00999999977648258 && (double)num1 <= 0.990000009536743)
                return;
            int rowCount = block.RowCount;
            Vector3 vector3_1 = new Vector3(Mathf.Cos(block.m_angle), 0.0f, Mathf.Sin(block.m_angle)) * 8f;
            Vector3 vector3_2 = new Vector3(vector3_1.z, 0.0f, -vector3_1.x);
            for (int z = 0; z < rowCount; ++z)
            {
                Vector3 vector3_3 = ((float)z - 3.5f) * vector3_2;
                for (int x = 0; x < 4; ++x)
                {
                    if (((long)block.m_valid & 1L << (z << 3 | x)) != 0L && block.GetZone(x, z) == requiredZone)
                    {
                        if (occupied1)
                        {
                            if (requiredZone == ItemClass.Zone.Unzoned && ((long)block.m_occupied1 & 1L << (z << 3 | x)) == 0L)
                                continue;
                        }
                        else if (occupied2)
                        {
                            if (requiredZone == ItemClass.Zone.Unzoned && ((long)block.m_occupied2 & 1L << (z << 3 | x)) == 0L)
                                continue;
                        }
                        else if ((((long)block.m_occupied1 | (long)block.m_occupied2) & 1L << (z << 3 | x)) != 0L)
                            continue;
                        Vector3 vector3_4 = ((float)x - 3.5f) * vector3_1;
                        Vector3 vector3_5 = block.m_position + vector3_4 + vector3_3 - position;
                        float f2 = (float)(((double)vector3_5.x * (double)direction.x + (double)vector3_5.z * (double)direction.z) * 0.125 + 32.0);
                        float f3 = (float)(((double)vector3_5.x * (double)direction.z - (double)vector3_5.z * (double)direction.x) * 0.125 + 32.0);
                        int num2 = Mathf.RoundToInt(f2);
                        int index = Mathf.RoundToInt(f3);
                        if (num2 >= 0 && num2 < 64 && (index >= 0 && index < 64) && ((double)Mathf.Abs(f2 - (float)num2) < 0.0125000001862645 && (double)Mathf.Abs(f3 - (float)index) < 0.0125000001862645))
                            m_fillBuffer1[index] |= (ulong)(1L << num2);
                    }
                }
            }
        }
        // Detours

        public static void SimulationStep(ref ZoneBlock zoneBlock, ushort blockID)
        {
            // This is the decompiled ZoneBlock.SimulationStep() method
            // Segments which were changed are marked with "begin mod" and "end mod"

            if (Debugger.Enabled && debugCount < 10)
            {
                debugCount++;
                Debugger.LogFormat("Building Themes: Detoured ZoneBlock.SimulationStep was called. blockID: {0}, position: {1}.", blockID, zoneBlock.m_position);
            }

            ZoneManager zoneManager = Singleton<ZoneManager>.instance;
            int rowCount = zoneBlock.RowCount;
            float m_angle = zoneBlock.m_angle;

            Vector2 xDirection = new Vector2(Mathf.Cos(m_angle), Mathf.Sin(m_angle)) * 8f;
            Vector2 zDirection = new Vector2(xDirection.y, -xDirection.x);
            ulong num = zoneBlock.m_valid & ~(zoneBlock.m_occupied1 | zoneBlock.m_occupied2);
            int spawnpointRow = 0;
            ItemClass.Zone zone = ItemClass.Zone.Unzoned;
            int num3 = 0;
            while (num3 < 4 && zone == ItemClass.Zone.Unzoned)
            {
                spawnpointRow = Singleton<SimulationManager>.instance.m_randomizer.Int32((uint)rowCount);
                if ((num & 1uL << (spawnpointRow << 3)) != 0uL)
                {
                    zone = zoneBlock.GetZone(0, spawnpointRow);
                }
                num3++;
            }
            DistrictManager instance2 = Singleton<DistrictManager>.instance;

            Vector3 m_position = (Vector3)zoneBlock.m_position;

            byte district = instance2.GetDistrict(m_position);
            int num4;
            switch (zone)
            {
                case ItemClass.Zone.ResidentialLow:
                    num4 = zoneManager.m_actualResidentialDemand;
                    num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialLowDemandOffset();
                    break;
                case ItemClass.Zone.ResidentialHigh:
                    num4 = zoneManager.m_actualResidentialDemand;
                    num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialHighDemandOffset();
                    break;
                case ItemClass.Zone.CommercialLow:
                    num4 = zoneManager.m_actualCommercialDemand;
                    num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialLowDemandOffset();
                    break;
                case ItemClass.Zone.CommercialHigh:
                    num4 = zoneManager.m_actualCommercialDemand;
                    num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialHighDemandOffset();
                    break;
                case ItemClass.Zone.Industrial:
                    num4 = zoneManager.m_actualWorkplaceDemand;
                    num4 += instance2.m_districts.m_buffer[(int)district].CalculateIndustrialDemandOffset();
                    break;
                case ItemClass.Zone.Office:
                    num4 = zoneManager.m_actualWorkplaceDemand;
                    num4 += instance2.m_districts.m_buffer[(int)district].CalculateOfficeDemandOffset();
                    break;
                default:
                    return;
            }
            Vector2 a = VectorUtils.XZ(m_position);
            Vector2 vector3 = a - 3.5f * xDirection + ((float)spawnpointRow - 3.5f) * zDirection;
            int[] tmpXBuffer = zoneManager.m_tmpXBuffer;
            for (int i = 0; i < 13; i++)
            {
                tmpXBuffer[i] = 0;
            }

            Quad2 quad = default(Quad2);
            quad.a = a - 4f * xDirection + ((float)spawnpointRow - 10f) * zDirection;
            quad.b = a + 3f * xDirection + ((float)spawnpointRow - 10f) * zDirection;
            quad.c = a + 3f * xDirection + ((float)spawnpointRow + 2f) * zDirection;
            quad.d = a - 4f * xDirection + ((float)spawnpointRow + 2f) * zDirection;
            Vector2 vector4 = quad.Min();
            Vector2 vector5 = quad.Max();

            //begin mod
            int num5 = Mathf.Max((int)((vector4.x - 46f) / 64f + _zoneGridHalfResolution), 0);
            int num6 = Mathf.Max((int)((vector4.y - 46f) / 64f + _zoneGridHalfResolution), 0);
            int num7 = Mathf.Min((int)((vector5.x + 46f) / 64f + _zoneGridHalfResolution), _zoneGridResolution - 1);
            int num8 = Mathf.Min((int)((vector5.y + 46f) / 64f + _zoneGridHalfResolution), _zoneGridResolution - 1);
            //end mod
            for (int j = num6; j <= num8; j++)
            {
                for (int k = num5; k <= num7; k++)
                {
                    //begin mod
                    ushort num9 = zoneManager.m_zoneGrid[j * _zoneGridResolution + k];
                    //end mod
                    int num10 = 0;
                    while (num9 != 0)
                    {
                        Vector3 positionVar = zoneManager.m_blocks.m_buffer[(int)num9].m_position;
                        float num11 = Mathf.Max(Mathf.Max(vector4.x - 46f - positionVar.x, vector4.y - 46f - positionVar.z),
                            Mathf.Max(positionVar.x - vector5.x - 46f, positionVar.z - vector5.y - 46f));

                        if (num11 < 0f)
                        {
                            _CheckBlock.Invoke(zoneBlock, new object[] { zoneManager.m_blocks.m_buffer[(int)num9], tmpXBuffer, zone, vector3, xDirection, zDirection, quad });
                        }
                        num9 = zoneManager.m_blocks.m_buffer[(int)num9].m_nextGridBlock;
                        if (++num10 >= 49152)
                        {
                            CODebugBase<LogChannel>.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                            break;
                        }
                    }
                }
            }

            for (int l = 0; l < 13; l++)
            {
                uint num12 = (uint)tmpXBuffer[l];
                int num13 = 0;
                bool flag = (num12 & 196608u) == 196608u;
                bool flag2 = false;
                while ((num12 & 1u) != 0u)
                {
                    num13++;
                    flag2 = ((num12 & 65536u) != 0u);
                    num12 >>= 1;
                }
                if (num13 == 5 || num13 == 6)
                {
                    if (flag2)
                    {
                        num13 -= Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) + 2;
                    }
                    else
                    {
                        num13 = 4;
                    }
                    num13 |= 131072;
                }
                else if (num13 == 7)
                {
                    num13 = 4;
                    num13 |= 131072;
                }
                if (flag)
                {
                    num13 |= 65536;
                }
                tmpXBuffer[l] = num13;
            }
            int num14 = tmpXBuffer[6] & 65535;
            if (num14 == 0)
            {
                return;
            }

            bool flag3 = (bool)_IsGoodPlace.Invoke(zoneBlock, new object[] { vector3 });
            if (Singleton<SimulationManager>.instance.m_randomizer.Int32(100u) >= num4)
            {
                if (flag3)
                {
                    zoneManager.m_goodAreaFound[(int)zone] = 1024;
                }
                return;
            }
            if (!flag3 && zoneManager.m_goodAreaFound[(int)zone] > -1024)
            {
                if (zoneManager.m_goodAreaFound[(int)zone] == 0)
                {
                    zoneManager.m_goodAreaFound[(int)zone] = -1;
                }
                return;
            }
            int num15 = 6;
            int num16 = 6;
            bool flag4 = true;
            while (true)
            {
                if (flag4)
                {
                    while (num15 != 0)
                    {
                        if ((tmpXBuffer[num15 - 1] & 65535) != num14)
                        {
                            break;
                        }
                        num15--;
                    }
                    while (num16 != 12)
                    {
                        if ((tmpXBuffer[num16 + 1] & 65535) != num14)
                        {
                            break;
                        }
                        num16++;
                    }
                }
                else
                {
                    while (num15 != 0)
                    {
                        if ((tmpXBuffer[num15 - 1] & 65535) < num14)
                        {
                            break;
                        }
                        num15--;
                    }
                    while (num16 != 12)
                    {
                        if ((tmpXBuffer[num16 + 1] & 65535) < num14)
                        {
                            break;
                        }
                        num16++;
                    }
                }
                int num17 = num15;
                int num18 = num16;
                while (num17 != 0)
                {
                    if ((tmpXBuffer[num17 - 1] & 65535) < 2)
                    {
                        break;
                    }
                    num17--;
                }
                while (num18 != 12)
                {
                    if ((tmpXBuffer[num18 + 1] & 65535) < 2)
                    {
                        break;
                    }
                    num18++;
                }
                bool flag5 = num17 != 0 && num17 == num15 - 1;
                bool flag6 = num18 != 12 && num18 == num16 + 1;
                if (flag5 && flag6)
                {
                    if (num16 - num15 > 2)
                    {
                        break;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_34;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                else if (flag5)
                {
                    if (num16 - num15 > 1)
                    {
                        goto Block_36;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_38;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                else if (flag6)
                {
                    if (num16 - num15 > 1)
                    {
                        goto Block_40;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_42;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                else
                {
                    if (num15 != num16)
                    {
                        goto IL_884;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_45;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                flag4 = false;
            }
            num15++;
            num16--;
            Block_34:
            goto IL_891;
            Block_36:
            num15++;
            Block_38:
            goto IL_891;
            Block_40:
            num16--;
            Block_42:
            Block_45:
            IL_884:
            IL_891:
            int num19;
            int num20;
            if (num14 == 1 && num16 - num15 >= 1)
            {
                num15 += Singleton<SimulationManager>.instance.m_randomizer.Int32((uint)(num16 - num15));
                num16 = num15 + 1;
                num19 = num15 + Singleton<SimulationManager>.instance.m_randomizer.Int32(2u);
                num20 = num19;
            }
            else
            {
                do
                {
                    num19 = num15;
                    num20 = num16;
                    if (num16 - num15 == 2)
                    {
                        if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                        {
                            num20--;
                        }
                        else
                        {
                            num19++;
                        }
                    }
                    else if (num16 - num15 == 3)
                    {
                        if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                        {
                            num20 -= 2;
                        }
                        else
                        {
                            num19 += 2;
                        }
                    }
                    else if (num16 - num15 == 4)
                    {
                        if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                        {
                            num16 -= 2;
                            num20 -= 3;
                        }
                        else
                        {
                            num15 += 2;
                            num19 += 3;
                        }
                    }
                    else if (num16 - num15 == 5)
                    {
                        if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                        {
                            num16 -= 3;
                            num20 -= 2;
                        }
                        else
                        {
                            num15 += 3;
                            num19 += 2;
                        }
                    }
                    else if (num16 - num15 >= 6)
                    {
                        if (num15 == 0 || num16 == 12)
                        {
                            if (num15 == 0)
                            {
                                num15 = 3;
                                num19 = 2;
                            }
                            if (num16 == 12)
                            {
                                num16 = 9;
                                num20 = 10;
                            }
                        }
                        else if (Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0)
                        {
                            num16 = num15 + 3;
                            num20 = num19 + 2;
                        }
                        else
                        {
                            num15 = num16 - 3;
                            num19 = num20 - 2;
                        }
                    }
                }
                while (num16 - num15 > 3 || num20 - num19 > 3);
            }
            int depth_A = 4;
            int width_A = num16 - num15 + 1;
            BuildingInfo.ZoningMode zoningMode = BuildingInfo.ZoningMode.Straight;
            bool flag7 = true;
            for (int m = num15; m <= num16; m++)
            {
                depth_A = Mathf.Min(depth_A, tmpXBuffer[m] & 65535);
                if ((tmpXBuffer[m] & 131072) == 0)
                {
                    flag7 = false;
                }
            }
            if (num16 > num15)
            {
                if ((tmpXBuffer[num15] & 65536) != 0)
                {
                    zoningMode = BuildingInfo.ZoningMode.CornerLeft;
                    num20 = num15 + num20 - num19;
                    num19 = num15;
                }
                if ((tmpXBuffer[num16] & 65536) != 0 && (zoningMode != BuildingInfo.ZoningMode.CornerLeft || Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0))
                {
                    zoningMode = BuildingInfo.ZoningMode.CornerRight;
                    num19 = num16 + num19 - num20;
                    num20 = num16;
                }
            }
            int depth_B = 4;
            int width_B = num20 - num19 + 1;
            BuildingInfo.ZoningMode zoningMode2 = BuildingInfo.ZoningMode.Straight;
            bool flag8 = true;
            for (int n = num19; n <= num20; n++)
            {
                depth_B = Mathf.Min(depth_B, tmpXBuffer[n] & 65535);
                if ((tmpXBuffer[n] & 131072) == 0)
                {
                    flag8 = false;
                }
            }
            if (num20 > num19)
            {
                if ((tmpXBuffer[num19] & 65536) != 0)
                {
                    zoningMode2 = BuildingInfo.ZoningMode.CornerLeft;
                }
                if ((tmpXBuffer[num20] & 65536) != 0 && (zoningMode2 != BuildingInfo.ZoningMode.CornerLeft || Singleton<SimulationManager>.instance.m_randomizer.Int32(2u) == 0))
                {
                    zoningMode2 = BuildingInfo.ZoningMode.CornerRight;
                }
            }
            ItemClass.SubService subService = ItemClass.SubService.None;
            ItemClass.Level level = ItemClass.Level.Level1;
            ItemClass.Service service;
            switch (zone)
            {
                case ItemClass.Zone.ResidentialLow:
                    service = ItemClass.Service.Residential;
                    subService = ItemClass.SubService.ResidentialLow;
                    break;
                case ItemClass.Zone.ResidentialHigh:
                    service = ItemClass.Service.Residential;
                    subService = ItemClass.SubService.ResidentialHigh;
                    break;
                case ItemClass.Zone.CommercialLow:
                    service = ItemClass.Service.Commercial;
                    subService = ItemClass.SubService.CommercialLow;
                    break;
                case ItemClass.Zone.CommercialHigh:
                    service = ItemClass.Service.Commercial;
                    subService = ItemClass.SubService.CommercialHigh;
                    break;
                case ItemClass.Zone.Industrial:
                    service = ItemClass.Service.Industrial;
                    break;
                case ItemClass.Zone.Office:
                    service = ItemClass.Service.Office;
                    subService = ItemClass.SubService.None;
                    break;
                default:
                    return;
            }
            BuildingInfo buildingInfo = null;
            Vector3 vector6 = Vector3.zero;
            int num25_row = 0;
            int length = 0;
            int width = 0;
            BuildingInfo.ZoningMode zoningMode3 = BuildingInfo.ZoningMode.Straight;
            int num28 = 0;

            // begin mod
            int depth_alt = Mathf.Min(depth_A, 4);
            int width_alt = width_A;
            // end mod

            while (num28 < 8) // while (num28 < 6)
            {
                switch (num28)
                {
                    // Corner cases

                    case 0:
                        if (zoningMode != BuildingInfo.ZoningMode.Straight)
                        {
                            num25_row = num15 + num16 + 1;
                            length = depth_A;
                            width = width_A;
                            zoningMode3 = zoningMode;
                            goto IL_D6A;
                        }
                        break;
                    case 1:
                        if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                        {
                            num25_row = num19 + num20 + 1;
                            length = depth_B;
                            width = width_B;
                            zoningMode3 = zoningMode2;
                            goto IL_D6A;
                        }
                        break;
                    case 2:
                        if (zoningMode != BuildingInfo.ZoningMode.Straight)
                        {
                            if (depth_A >= 4)
                            {
                                num25_row = num15 + num16 + 1;
                                length = ((!flag7) ? 2 : 3);
                                width = width_A;
                                zoningMode3 = zoningMode;
                                goto IL_D6A;
                            }
                        }
                        break;
                    case 3:
                        if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                        {
                            if (depth_B >= 4)
                            {
                                num25_row = num19 + num20 + 1;
                                length = ((!flag8) ? 2 : 3);
                                width = width_B;
                                zoningMode3 = zoningMode2;
                                goto IL_D6A;
                            }
                        }
                        break;
                    // begin mod
                    case 4:
                        if (zoningMode != BuildingInfo.ZoningMode.Straight)
                        {
                            if (width_alt > 1)
                            {
                                width_alt--;
                            }
                            else if (depth_alt > 1)
                            {
                                depth_alt--;
                                width_alt = width_A;
                            }
                            else
                            {
                                break;
                            }

                            if (width_alt == width_A)
                            {
                                num25_row = num15 + num16 + 1;

                            }
                            else
                            {
                                if (zoningMode == BuildingInfo.ZoningMode.CornerLeft)
                                {
                                    num25_row = num15 + num16 + 1 - (width_A - width_alt);
                                }
                                else
                                {
                                    num25_row = num15 + num16 + 1 + (width_A - width_alt);
                                }
                            }

                            length = depth_alt;
                            width = width_alt;

                            zoningMode3 = zoningMode;

                            num28--;
                            goto IL_D6A;
                        }
                        break;
                    // end mod
                    // Straight cases
                    case 5:
                        num25_row = num15 + num16 + 1;
                        length = depth_A;
                        width = width_A;
                        zoningMode3 = BuildingInfo.ZoningMode.Straight;
                        goto IL_D6A;
                    case 6:
                        // begin mod

                        // reset variables
                        depth_alt = Mathf.Min(depth_A, 4);
                        width_alt = width_A;

                        // end mod

                        //int width_B = num20 - num19 + 1;
                        num25_row = num19 + num20 + 1;
                        length = depth_B;
                        width = width_B;
                        zoningMode3 = BuildingInfo.ZoningMode.Straight;
                        goto IL_D6A;
                    // begin mod
                    case 7:

                        if (width_alt > 1)
                        {
                            width_alt--;
                        }
                        else
                        {
                            break;
                        }

                        if (width_alt == width_A)
                        {
                            num25_row = num15 + num16 + 1;
                        }
                        else if (width_A % 2 != width_alt % 2)
                        {
                            num25_row = num15 + num16;
                        }
                        else
                        {
                            num25_row = num15 + num16 + 1;
                        }

                        length = depth_alt;
                        width = width_alt;

                        zoningMode3 = BuildingInfo.ZoningMode.Straight;

                        num28--;
                        goto IL_D6A;
                    // end mod
                    default:
                        goto IL_D6A;
                }
                IL_DF0:
                num28++;
                continue;
                IL_D6A:
                vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection);
                if (zone == ItemClass.Zone.Industrial)
                {
                    ZoneBlock.GetIndustryType(vector6, out subService, out level);
                }
                else if (zone == ItemClass.Zone.CommercialLow || zone == ItemClass.Zone.CommercialHigh)
                {
                    ZoneBlock.GetCommercialType(vector6, zone, width, length, out subService, out level);
                }

                byte district2 = instance2.GetDistrict(vector6);
                ushort style = instance2.m_districts.m_buffer[(int)district2].m_Style;

                // begin mod

                // Here we are calling a custom getRandomBuildingInfo method

                buildingInfo = BuildingManagerDetour.GetRandomBuildingInfo_Spawn(vector6, ref Singleton<SimulationManager>.instance.m_randomizer, service, subService, level, width, length, zoningMode3, style);

                // end mod

                if (buildingInfo != null)
                {
                    // begin mod

                    // If the depth of the found prefab is smaller than the one we were looking for, recalculate the size
                    // This is done by checking the position of every prop
                    // Plots only get shrinked when no assets are placed on the extra space

                    // This is needed for themes which only contain small buildings (e.g. 1x2) 
                    // because those buildings would occupy more space than needed!

                    if (buildingInfo.GetWidth() == width && buildingInfo.GetLength() != length)
                    {
                        // Calculate the z position of the furthest away prop
                        float biggestPropPosZ = 0;

                        if (buildingInfo.m_props != null)
                        {
                            foreach (var prop in buildingInfo.m_props)
                            {
                                if (prop == null) continue;

                                biggestPropPosZ = Mathf.Max(biggestPropPosZ, buildingInfo.m_expandFrontYard ? prop.m_position.z : -prop.m_position.z);
                            }
                        }

                        // Check if the furthest away prop is outside of the bounds of the prefab
                        float occupiedExtraSpace = biggestPropPosZ - buildingInfo.GetLength() * 4;
                        if (occupiedExtraSpace <= 0)
                        {
                            // No? Then shrink the plot to the prefab length so no space is wasted!
                            length = buildingInfo.GetLength();
                        }
                        else
                        {
                            // Yes? Shrink the plot so all props are in the bounds
                            int newLength = buildingInfo.GetLength() + Mathf.CeilToInt(occupiedExtraSpace / 8);
                            length = Mathf.Min(length, newLength);
                        }

                        vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection);
                    }

                    // This block handles Corner buildings. We always shrink them
                    else if (buildingInfo.GetLength() == width && buildingInfo.GetWidth() != length)
                    {
                        length = buildingInfo.GetWidth();
                        vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection);
                    }

                    // end mod

                    if (Debugger.Enabled)
                    {
                        Debugger.LogFormat("Found prefab: {5} - {0}, {1}, {2}, {3} x {4}", service, subService, level, width, length, buildingInfo.name);
                    }
                    break;
                }
                if (Debugger.Enabled)
                {

                }
                goto IL_DF0;
            }
            if (buildingInfo == null)
            {
                if (Debugger.Enabled)
                {
                    Debugger.LogFormat("No prefab found: {0}, {1}, {2}, {3} x {4}", service, subService, level, width, length);
                }
                return;
            }
            float num29 = Singleton<TerrainManager>.instance.WaterLevel(VectorUtils.XZ(vector6));
            if (num29 > vector6.y)
            {
                return;
            }
            float num30 = m_angle + 1.57079637f;
            if (zoningMode3 == BuildingInfo.ZoningMode.CornerLeft && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerRight)
            {
                num30 -= 1.57079637f;
                length = width;
            }
            else if (zoningMode3 == BuildingInfo.ZoningMode.CornerRight && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft)
            {
                num30 += 1.57079637f;
                length = width;
            }
            ushort num31;
            if (Singleton<BuildingManager>.instance.CreateBuilding(out num31, ref Singleton<SimulationManager>.instance.m_randomizer, buildingInfo, vector6, num30, length, Singleton<SimulationManager>.instance.m_currentBuildIndex))
            {
                Singleton<SimulationManager>.instance.m_currentBuildIndex += 1u;
                switch (service)
                {
                    case ItemClass.Service.Residential:
                        zoneManager.m_actualResidentialDemand = Mathf.Max(0, zoneManager.m_actualResidentialDemand - 5);
                        break;
                    case ItemClass.Service.Commercial:
                        zoneManager.m_actualCommercialDemand = Mathf.Max(0, zoneManager.m_actualCommercialDemand - 5);
                        break;
                    case ItemClass.Service.Industrial:
                        zoneManager.m_actualWorkplaceDemand = Mathf.Max(0, zoneManager.m_actualWorkplaceDemand - 5);
                        break;
                    case ItemClass.Service.Office:
                        zoneManager.m_actualWorkplaceDemand = Mathf.Max(0, zoneManager.m_actualWorkplaceDemand - 5);
                        break;
                }

                switch (zone)
                {
                    case ItemClass.Zone.ResidentialHigh:
                    case ItemClass.Zone.CommercialHigh:
                        {
                            Building[] expr_FD7_cp_0 = Singleton<BuildingManager>.instance.m_buildings.m_buffer;
                            ushort expr_FD7_cp_1 = num31;
                            expr_FD7_cp_0[(int)expr_FD7_cp_1].m_flags = (expr_FD7_cp_0[(int)expr_FD7_cp_1].m_flags | Building.Flags.HighDensity);
                            break;
                        }
                }
            }
            zoneManager.m_goodAreaFound[(int)zone] = 1024;
        }
        private static void ApplyBrush(ZoneTool z,ushort blockIndex, ref ZoneBlock data, Vector3 position, float brushRadius)
        {
            Vector3 a = data.m_position - position;
            if (Mathf.Abs(a.x) > 46f + brushRadius || Mathf.Abs(a.z) > 46f + brushRadius)
            {
                return;
            }

            bool m_zoning = (bool)z.GetType().GetField("m_zoning", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(z);
            bool m_dezoning = (bool)z.GetType().GetField("m_dezoning", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(z);
            int num = (int)((data.m_flags & 65280u) >> 8);
            Vector3 a2 = new Vector3(Mathf.Cos(data.m_angle), 0f, Mathf.Sin(data.m_angle)) * 8f;
            Vector3 a3 = new Vector3(a2.z, 0f, -a2.x);
            bool flag = false;
            for (int i = 0; i < num; i++)
            {
                Vector3 b = ((float)i - 3.5f) * a3;
                for (int j = 0; j < 4; j++)
                {
                    Vector3 b2 = ((float)j - 3.5f) * a2;
                    Vector3 vector = a + b2 + b;
                    float num2 = vector.x * vector.x + vector.z * vector.z;
                    if (num2 <= brushRadius * brushRadius)
                    {
                        if (m_zoning)
                        {
                            if ((z.m_zone == ItemClass.Zone.Unzoned || data.GetZone(j, i) == ItemClass.Zone.Unzoned) && data.SetZone(j, i, z.m_zone))
                            {
                                flag = true;
                            }
                        }
                        else if (m_dezoning && data.SetZone(j, i, ItemClass.Zone.Unzoned))
                        {
                            flag = true;
                        }
                    }
                }
            }
            if (flag)
            {
                data.RefreshZoning(blockIndex);
                if (m_zoning)
                {
                    UsedZone(z.m_zone);
                }
            }
        }
 private static void CheckZoning(Building bz, ItemClass.Zone zone, ref uint validCells, ref ZoneBlock block)
 {
     BuildingInfo.ZoningMode zoningMode = bz.Info.m_zoningMode;
     int width = bz.Width;
     int length = bz.Length;
     Vector3 a = new Vector3(Mathf.Cos(bz.m_angle), 0f, Mathf.Sin(bz.m_angle)) * 8f;
     Vector3 a2 = new Vector3(a.z, 0f, -a.x);
     int rowCount = block.RowCount;
     Vector3 a3 = new Vector3(Mathf.Cos(block.m_angle), 0f, Mathf.Sin(block.m_angle)) * 8f;
     Vector3 a4 = new Vector3(a3.z, 0f, -a3.x);
     Vector3 a5 = block.m_position - bz.m_position + a * ((float)width * 0.5f - 0.5f) + a2 * ((float)length * 0.5f - 0.5f);
     for (int i = 0; i < rowCount; i++)
     {
         Vector3 b = ((float)i - 3.5f) * a4;
         int num = 0;
         while ((long)num < 4L)
         {
             if ((block.m_valid & ~block.m_shared & 1uL << (i << 3 | num)) != 0uL && block.GetZone(num, i) == zone)
             {
                 Vector3 b2 = ((float)num - 3.5f) * a3;
                 Vector3 vector = a5 + b2 + b;
                 float num2 = a.x * vector.x + a.z * vector.z;
                 float num3 = a2.x * vector.x + a2.z * vector.z;
                 int num4 = Mathf.RoundToInt(num2 / 64f);
                 int num5 = Mathf.RoundToInt(num3 / 64f);
                 bool flag = false;
                 if (zoningMode == BuildingInfo.ZoningMode.Straight)
                 {
                     flag = (num5 == 0);
                 }
                 else if (zoningMode == BuildingInfo.ZoningMode.CornerLeft)
                 {
                     flag = ((num5 == 0 && num4 >= width - 2) || (num5 <= 1 && num4 == width - 1));
                 }
                 else if (zoningMode == BuildingInfo.ZoningMode.CornerRight)
                 {
                     flag = ((num5 == 0 && num4 <= 1) || (num5 <= 1 && num4 == 0));
                 }
                 if ((!flag || num == 0) && num4 >= 0 && num5 >= 0 && num4 < width && num5 < length)
                 {
                     validCells |= 1u << (num5 << 3) + num4;
                 }
             }
             num++;
         }
     }
 }