public static void FindColumnCount(ushort blockID, ref int columnCount)
 {
     if (blockID > 0)
     {
         columnCount = Mathf.Max(columnCount, ZoneBlockDetour.GetColumnCount(ref ZoneManager.instance.m_blocks.m_buffer[blockID]));
     }
 }
Exemplo n.º 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);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        private static void CalculateFillBuffer(ZoneTool _this, Vector3 position, Vector3 direction, float angle, ushort blockIndex, ref ZoneBlock block, ItemClass.Zone requiredZone, bool occupied1, bool occupied2)
        {
            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;
            int     columnCount = ZoneBlockDetour.GetColumnCount(ref block); // modified
            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);

            var m_fillBuffer1 = GetFillBuffer(_this);                   // modified
            var blockID       = ZoneBlockDetour.FindBlockId(ref block); // modified

            for (int z = 0; z < rowCount; ++z)
            {
                Vector3 vector3_3 = ((float)z - 3.5f) * vector3_2;
                for (int x = 0; x < columnCount; ++x) // modifed
                {
                    if (((long)block.m_valid & 1L << (z << 3 | x)) != 0L && ZoneBlockDetour.GetZoneDeep(ref block, blockID, 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);
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
        private static bool ApplyZoning(ZoneTool _this, ushort blockIndex, ref ZoneBlock data, Quad2 quad2)
        {
            int rowCount    = data.RowCount;
            int columnCount = ZoneBlockDetour.GetColumnCount(ref data); // modified

            Vector2 vector2_1 = new Vector2(Mathf.Cos(data.m_angle), Mathf.Sin(data.m_angle)) * 8f;
            Vector2 vector2_2 = new Vector2(vector2_1.y, -vector2_1.x);
            Vector2 vector2_3 = VectorUtils.XZ(data.m_position);

            if (!new Quad2()
            {
                a = (vector2_3 - 4f * vector2_1 - 4f * vector2_2),
                b = (vector2_3 + 4f * vector2_1 - 4f * vector2_2),
                c = (vector2_3 + 4f * vector2_1 + (float)(rowCount - 4) * vector2_2),
                d = (vector2_3 - 4f * vector2_1 + (float)(rowCount - 4) * vector2_2)
            }.Intersect(quad2))
            {
                return(false);
            }
            bool flag = false;

            var m_zoning   = IsZoningEnabled(_this);                // custom
            var m_dezoning = IsDezoningEnabled(_this);              // custom
            var blockID    = ZoneBlockDetour.FindBlockId(ref data); // modified

            for (int z = 0; z < rowCount; ++z)
            {
                Vector2 vector2_4 = ((float)z - 3.5f) * vector2_2;
                for (int x = 0; x < columnCount; ++x) // custom
                {
                    Vector2 vector2_5 = ((float)x - 3.5f) * vector2_1;
                    Vector2 p         = vector2_3 + vector2_5 + vector2_4;
                    if (quad2.Intersect(p))
                    {
                        if (m_zoning)
                        {
                            if ((_this.m_zone == ItemClass.Zone.Unzoned || ZoneBlockDetour.GetZoneDeep(ref data, blockID, x, z) == ItemClass.Zone.Unzoned) &&
                                ZoneBlockDetour.SetZoneDeep(ref data, blockID, x, z, _this.m_zone))
                            {
                                flag = true;
                            }
                        }
                        else if (m_dezoning && ZoneBlockDetour.SetZoneDeep(ref data, blockID, x, z, ItemClass.Zone.Unzoned))
                        {
                            flag = true;
                        }
                    }
                }
            }
            if (!flag)
            {
                return(false);
            }
            data.RefreshZoning(blockIndex);
            return(true);
        }
Exemplo n.º 5
0
        private static void ApplyBrush(ZoneTool _this, ushort blockIndex, ref ZoneBlock data, Vector3 position, float brushRadius)
        {
            Vector3 vector3_1 = data.m_position - position;

            if ((double)Mathf.Abs(vector3_1.x) > 46.0 + (double)brushRadius || (double)Mathf.Abs(vector3_1.z) > 46.0 + (double)brushRadius)
            {
                return;
            }
            int     num         = (int)((data.m_flags & 65280U) >> 8);
            int     columnCount = ZoneBlockDetour.GetColumnCount(ref data); // modified
            Vector3 vector3_2   = new Vector3(Mathf.Cos(data.m_angle), 0.0f, Mathf.Sin(data.m_angle)) * 8f;
            Vector3 vector3_3   = new Vector3(vector3_2.z, 0.0f, -vector3_2.x);
            bool    flag        = false;

            var m_zoning   = IsZoningEnabled(_this);                // custom
            var m_dezoning = IsDezoningEnabled(_this);              // custom
            var blockID    = ZoneBlockDetour.FindBlockId(ref data); // modified

            for (int z = 0; z < num; ++z)
            {
                Vector3 vector3_4 = ((float)z - 3.5f) * vector3_3;
                for (int x = 0; x < columnCount; ++x) // modified
                {
                    Vector3 vector3_5 = ((float)x - 3.5f) * vector3_2;
                    Vector3 vector3_6 = vector3_1 + vector3_5 + vector3_4;
                    if ((double)vector3_6.x * (double)vector3_6.x + (double)vector3_6.z * (double)vector3_6.z <= (double)brushRadius * (double)brushRadius)
                    {
                        if (m_zoning)
                        {
                            if ((_this.m_zone == ItemClass.Zone.Unzoned || ZoneBlockDetour.GetZoneDeep(ref data, blockID, x, z) == ItemClass.Zone.Unzoned) &&
                                ZoneBlockDetour.SetZoneDeep(ref data, blockID, x, z, _this.m_zone))
                            {
                                flag = true;
                            }
                        }
                        else if (m_dezoning && ZoneBlockDetour.SetZoneDeep(ref data, blockID, x, z, ItemClass.Zone.Unzoned))
                        {
                            flag = true;
                        }
                    }
                }
            }
            if (!flag)
            {
                return;
            }
            data.RefreshZoning(blockIndex);
            if (!m_zoning)
            {
                return;
            }
            UsedZone(_this, _this.m_zone);
        }
Exemplo n.º 6
0
 private static void CheckDataIntegrity(ulong[] zoneMask, int minDepth)
 {
     for (ushort blockID = 1; blockID < zoneMask.Length; blockID++)
     {
         {
             if (ZoneBlockDetour.GetColumnCount(ref ZoneManager.instance.m_blocks.m_buffer[blockID]) < minDepth &&
                 (zoneMask[blockID] != 0UL))
             {
                 zoneMask[blockID] = 0UL;
             }
         }
     }
 }
        private static void FindClosestZone(BuildingTool _this, BuildingInfo info, ushort block, Vector3 refPos, ref float minD, ref float min2, ref Vector3 minPos, ref float minAngle)
        {
            if ((int)block == 0)
            {
                return;
            }
            ZoneBlock zoneBlock = Singleton <ZoneManager> .instance.m_blocks.m_buffer[(int)block];

            if ((double)Mathf.Abs(zoneBlock.m_position.x - refPos.x) >= 52.0 || (double)Mathf.Abs(zoneBlock.m_position.z - refPos.z) >= 52.0)
            {
                return;
            }
            int     rowCount    = zoneBlock.RowCount;
            int     columnCount = ZoneBlockDetour.GetColumnCount(ref zoneBlock); // modified
            Vector3 lhs         = new Vector3(Mathf.Cos(zoneBlock.m_angle), 0.0f, Mathf.Sin(zoneBlock.m_angle)) * 8f;
            Vector3 vector3_1   = new Vector3(lhs.z, 0.0f, -lhs.x);

            for (int row = 0; row < rowCount; ++row)
            {
                Vector3 vector3_2 = ((float)row - 3.5f) * vector3_1;
                for (int column = 0; (long)column < columnCount; ++column) // modified
                {
                    if (((long)zoneBlock.m_valid & 1L << (row << 3 | column)) != 0L)
                    {
                        Vector3 vector3_3 = ((float)column - 3.5f) * lhs;
                        Vector3 vector3_4 = zoneBlock.m_position + vector3_3 + vector3_2;
                        float   num1      = Mathf.Sqrt((float)(((double)vector3_4.x - (double)refPos.x) * ((double)vector3_4.x - (double)refPos.x) + ((double)vector3_4.z - (double)refPos.z) * ((double)vector3_4.z - (double)refPos.z)));
                        float   num2      = Vector3.Dot(lhs, refPos - zoneBlock.m_position);
                        if ((double)num1 <= (double)minD - 0.200000002980232 || (double)num1 < (double)minD + 0.200000002980232 && (double)num2 < (double)min2)
                        {
                            minD = num1;
                            min2 = num2;
                            if ((info.m_cellWidth & 1) == 0)
                            {
                                Vector3 vector3_5 = vector3_4 + vector3_1 * 0.5f;
                                Vector3 vector3_6 = vector3_4 - vector3_1 * 0.5f;
                                minPos = ((double)vector3_5.x - (double)refPos.x) * ((double)vector3_5.x - (double)refPos.x) + ((double)vector3_5.z - (double)refPos.z) * ((double)vector3_5.z - (double)refPos.z) >= ((double)vector3_6.x - (double)refPos.x) * ((double)vector3_6.x - (double)refPos.x) + ((double)vector3_6.z - (double)refPos.z) * ((double)vector3_6.z - (double)refPos.z) ? zoneBlock.m_position + (float)((double)info.m_cellLength * 0.5 - 4.0) * lhs + ((float)row - 4f) * vector3_1 : zoneBlock.m_position + (float)((double)info.m_cellLength * 0.5 - 4.0) * lhs + ((float)row - 3f) * vector3_1;
                            }
                            else
                            {
                                minPos = zoneBlock.m_position + (float)((double)info.m_cellLength * 0.5 - 4.0) * lhs + ((float)row - 3.5f) * vector3_1;
                            }
                            minPos.y = refPos.y;
                            minAngle = zoneBlock.m_angle + 1.570796f;
                        }
                    }
                }
            }
        }
        [RedirectMethod(true)] // Detour Reason: Deeper zones data storage, custom depth
        public static bool CreateBlock(ZoneManager _this, out ushort block, ref Randomizer randomizer, Vector3 position, float angle, int rows, uint buildIndex)
        {
            bool result;
            var  columns = NetManagerDetour.newBlockColumnCount;

            if (columns == 0) // create no blocks if desired zone depth is 0
            {
                block  = 0;
                result = false;
            }
            else
            {
                // Call original method
                CreateBlockRedirector.Revert();
                result = _this.CreateBlock(out block, ref randomizer, position, angle, rows, buildIndex);
                CreateBlockRedirector.Apply();

                if (result)
                {
                    // --- support for larger zones ---
                    if (DataExtension.zones3 != null)
                    {
                        DataExtension.zones3[block] = 0UL;
                    }
                    if (DataExtension.zones4 != null)
                    {
                        DataExtension.zones4[block] = 0UL;
                    }

                    // --- dynamic column count ---
                    // TODO should only affect new roads, not ones replaced or splitted by the game (see Network Skins source code)
                    ZoneBlockDetour.SetColumnCount(ref _this.m_blocks.m_buffer[(int)block], columns);
                }
            }
            return(result);
        }
        public override void OnCreated(ILoading loading)
        {
            base.OnCreated(loading);

            Debugger.Initialize();

            Debugger.Log("ON_CREATED");
            Debugger.Log("Building Themes: Initializing Mod...");

            try
            {
                PolicyPanelEnabler.Register();
                BuildingThemesManager.instance.Reset();
                BuildingVariationManager.instance.Reset();

                UpdateConfig();

                try
                {
                    Redirector <BuildingManagerDetour> .Deploy();

                    Debugger.Log("Building Themes: BuildingManager Methods detoured!");
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }
                try
                {
                    Redirector <DistrictManagerDetour> .Deploy();

                    Debugger.Log("Building Themes: DistrictManager Methods detoured!");
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }
                try
                {
                    Redirector <ZoneBlockDetour> .Deploy();

                    Debugger.Log("Building Themes: ZoneBlock Methods detoured!");
                    ZoneBlockDetour.SetUp();
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }
                try
                {
                    Detour.ImmaterialResourceManagerDetour.Deploy();
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }
                try
                {
                    Detour.PrivateBuildingAIDetour <ResidentialBuildingAI> .Deploy();
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }
                try
                {
                    Detour.PrivateBuildingAIDetour <CommercialBuildingAI> .Deploy();
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }
                try
                {
                    Detour.PrivateBuildingAIDetour <IndustrialBuildingAI> .Deploy();
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }
                try
                {
                    Detour.PrivateBuildingAIDetour <OfficeBuildingAI> .Deploy();
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }
                try
                {
                    Detour.PoliciesPanelDetour.Deploy();
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }
                try
                {
                    Redirector <DistrictWorldInfoPanelDetour> .Deploy();

                    Debugger.Log("Building Themes: DistrictWorldInfoPanel Methods detoured!");
                }
                catch (Exception e)
                {
                    Debugger.LogException(e);
                }

                Debugger.Log("Building Themes: Mod successfully intialized.");
            }
            catch (Exception e)
            {
                Debugger.LogException(e);
            }
        }
Exemplo n.º 10
0
        private static bool ApplyFillBuffer(ZoneTool _this, Vector3 position, Vector3 direction, float angle, ushort blockIndex, ref ZoneBlock block)
        {
            var m_zoning   = IsZoningEnabled(_this);                 // custom
            var m_dezoning = IsDezoningEnabled(_this);               // custom
            var blockID    = ZoneBlockDetour.FindBlockId(ref block); // modified

            int rowCount    = block.RowCount;
            int columnCount = ZoneBlockDetour.GetColumnCount(ref block); // modified

            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);
            bool    flag1     = false;

            for (int z = 0; z < rowCount; ++z)
            {
                Vector3 vector3_3 = ((float)z - 3.5f) * vector3_2;
                for (int x = 0; x < columnCount; ++x) // custom
                {
                    Vector3 vector3_4 = ((float)x - 3.5f) * vector3_1;
                    Vector3 vector3_5 = block.m_position + vector3_4 + vector3_3 - position;
                    float   f1        = (float)(((double)vector3_5.x * (double)direction.x + (double)vector3_5.z * (double)direction.z) * 0.125 + 32.0);
                    float   f2        = (float)(((double)vector3_5.x * (double)direction.z - (double)vector3_5.z * (double)direction.x) * 0.125 + 32.0);
                    int     num1      = Mathf.Clamp(Mathf.RoundToInt(f1), 0, 63);
                    int     num2      = Mathf.Clamp(Mathf.RoundToInt(f2), 0, 63);
                    bool    flag2     = false;

                    var m_fillBuffer1 = GetFillBuffer(_this); // modified

                    for (int index1 = -1; index1 <= 1 && !flag2; ++index1)
                    {
                        for (int index2 = -1; index2 <= 1 && !flag2; ++index2)
                        {
                            int num3   = num1 + index2;
                            int index3 = num2 + index1;
                            if (num3 >= 0 && num3 < 64 && (index3 >= 0 && index3 < 64) && (((double)f1 - (double)num3) * ((double)f1 - (double)num3)
                                                                                           + ((double)f2 - (double)index3) * ((double)f2 - (double)index3) < 9.0 / 16.0 && ((long)m_fillBuffer1[index3] & 1L << num3) != 0L))
                            {
                                if (m_zoning)
                                {
                                    if ((_this.m_zone == ItemClass.Zone.Unzoned || ZoneBlockDetour.GetZoneDeep(ref block, blockID, x, z) == ItemClass.Zone.Unzoned) &&
                                        ZoneBlockDetour.SetZoneDeep(ref block, blockID, x, z, _this.m_zone))
                                    {
                                        flag1 = true;
                                    }
                                }
                                else if (m_dezoning && ZoneBlockDetour.SetZoneDeep(ref block, blockID, x, z, ItemClass.Zone.Unzoned))
                                {
                                    flag1 = true;
                                }
                                flag2 = true;
                            }
                        }
                    }
                }
            }
            if (!flag1)
            {
                return(false);
            }
            block.RefreshZoning(blockIndex);
            return(true);
        }
Exemplo n.º 11
0
        public static void CheckSpace(ZoneManager _this, ushort block, Vector3 position, float angle, int width, int length, ref ulong space1, ref ulong space2, ref ulong space3, ref ulong space4)
        {
            ZoneBlock zoneBlock = _this.m_blocks.m_buffer[(int)block];

            // difference of 2 radian angles (360 deg = 2*PI * 0.6366197f = 4f)
            // that means an angle difference of 90 deg would result in 1f
            float angleDiff      = Mathf.Abs(zoneBlock.m_angle - angle) * 0.6366197f;
            float rightAngleDiff = angleDiff - Mathf.Floor(angleDiff);

            // check if the input angle and the zone block are in right angle (0 90 180 270 deg), otherwise return
            if ((double)rightAngleDiff >= 0.0199999995529652 && (double)rightAngleDiff <= 0.980000019073486)
            {
                return;
            }

            float searchRadius = Mathf.Min(72f, (float)(width + length) * 4f) + 6f;

            float minX = position.x - searchRadius;
            float minZ = position.z - searchRadius;
            float maxX = position.x + searchRadius;
            float maxZ = position.z + searchRadius;

            // check if the zone block is in the area of interest, otherwise return
            if ((double)zoneBlock.m_position.x + 46.0 < (double)minX || (double)zoneBlock.m_position.x - 46.0 > (double)maxX ||
                ((double)zoneBlock.m_position.z + 46.0 < (double)minZ || (double)zoneBlock.m_position.z - 46.0 > (double)maxZ))
            {
                return;
            }

            // width of the zone block
            int rowCount    = zoneBlock.RowCount;
            int columnCount = ZoneBlockDetour.GetColumnCount(ref zoneBlock); // modified

            // orientation of the zone block
            Vector3 columnDirection = new Vector3(Mathf.Cos(zoneBlock.m_angle), 0.0f, Mathf.Sin(zoneBlock.m_angle)) * 8f;
            Vector3 rowDirection    = new Vector3(columnDirection.z, 0.0f, -columnDirection.x);

            // direction vectors for the given angle
            Vector3 angleParallelDirection   = new Vector3(Mathf.Cos(angle), 0.0f, Mathf.Sin(angle)) * 8f;
            Vector3 angleOrthogonalDirection = new Vector3(angleParallelDirection.z, 0.0f, -angleParallelDirection.x);

            for (int row = 0; row < rowCount; ++row)
            {
                Vector3 rowMiddleLength = ((float)row - 3.5f) * rowDirection;

                for (int column = 0; (long)column < columnCount; ++column)
                {
                    // check if the current cell is valid (not shared, not occupied)
                    if (((long)zoneBlock.m_valid & ~(long)zoneBlock.m_shared & ~((long)zoneBlock.m_occupied1 | (long)zoneBlock.m_occupied2) & 1L << (row << 3 | column)) != 0L)
                    {
                        Vector3 columnMiddleLength = ((float)column - 3.5f) * columnDirection;

                        // absolute position of the zone block cell
                        Vector3 cellPosition = zoneBlock.m_position + columnMiddleLength + rowMiddleLength;

                        // check if the cell is in search radius
                        if ((double)Mathf.Abs(position.x - cellPosition.x) < (double)searchRadius && (double)Mathf.Abs(position.z - cellPosition.z) < (double)searchRadius)
                        {
                            // cycle through every cell of the building plot
                            // find the cell that is in the same position as the zone block cell
                            bool cellsMatch = false;
                            for (int plotColumn = 0; plotColumn < length && !cellsMatch; ++plotColumn)
                            {
                                Vector3 plotColumnMiddleLength = (float)((double)plotColumn - (double)length * 0.5 + 0.5) * angleOrthogonalDirection;

                                for (int plotRow = 0; plotRow < width && !cellsMatch; ++plotRow)
                                {
                                    Vector3 plotRowMiddleLength = (float)((double)plotRow - (double)width * 0.5 + 0.5) * angleParallelDirection;

                                    // absolute position of the building plot cell
                                    Vector3 plotCellPosition = position + plotRowMiddleLength + plotColumnMiddleLength;

                                    // check if zone block cell and building plot cell positions match
                                    if ((double)Mathf.Abs(plotCellPosition.x - cellPosition.x) < 0.200000002980232 && (double)Mathf.Abs(plotCellPosition.z - cellPosition.z) < 0.200000002980232)
                                    {
                                        cellsMatch = true;
                                        // depending on column, use one of the 4 masks to report that a cell was found
                                        if (plotColumn < 4)
                                        {
                                            space1 = space1 | (ulong)(1L << (plotColumn << 4 | plotRow));
                                        }
                                        else if (plotColumn < 8)
                                        {
                                            space2 = space2 | (ulong)(1L << (plotColumn - 4 << 4 | plotRow));
                                        }
                                        else if (plotColumn < 12)
                                        {
                                            space3 = space3 | (ulong)(1L << (plotColumn - 8 << 4 | plotRow));
                                        }
                                        else
                                        {
                                            space4 = space4 | (ulong)(1L << (plotColumn - 12 << 4 | plotRow));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }