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); } }
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); } } } } } }
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); } } } } }
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); } } } } }
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; } } } } }
// 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); }
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++; } } }