public UniqueBuildingInstance(ushort buildingID, UniqueBuilding uniqueBuilding) { UniqueName = uniqueBuilding.UniqueName; BuildingID = buildingID; OriginalName = uniqueBuilding.OriginalName; Flags = Building.Flags.Created; }
private static bool CheckInfoCompatibility(Vector3 pos, ItemClass.Service service, ItemClass.SubService subService, TransferManager.TransferReason[] allowedTypes, Building.Flags flagsRequired, Building.Flags flagsForbidden, BuildingManager bm, ref ushort result, ref float lastNearest, ushort buildingId, BuildingInfo info) { //doErrorLog($"CheckInfoCompatibility 0 {pos}, {service}, {subService}, {allowedTypes}, {flagsRequired}, {flagsForbidden}, {bm}, {result}, {lastNearest}, {buildingId}, {info}"); if (info != null && (info.m_class.m_service == service || service == ItemClass.Service.None) && (info.m_class.m_subService == subService || subService == ItemClass.SubService.None)) { //doErrorLog("CheckInfoCompatibility 1"); Building.Flags flags = bm.m_buildings.m_buffer[buildingId].m_flags; //doErrorLog("CheckInfoCompatibility 2"); if ((flags & (flagsRequired | flagsForbidden)) == flagsRequired) { //doErrorLog("CheckInfoCompatibility 3"); if (allowedTypes == null || allowedTypes.Length == 0 || !(info.GetAI() is DepotAI depotAI) || (depotAI.m_transportInfo != null && allowedTypes.Contains(depotAI.m_transportInfo.m_vehicleReason)) || (depotAI.m_secondaryTransportInfo != null && allowedTypes.Contains(depotAI.m_secondaryTransportInfo.m_vehicleReason))) { //doErrorLog("CheckInfoCompatibility 4"); float dist = Vector3.SqrMagnitude(pos - bm.m_buildings.m_buffer[buildingId].m_position); //doErrorLog("CheckInfoCompatibility 5"); if (dist < lastNearest) { result = buildingId; lastNearest = dist; return(true); } } } } return(false); }
protected void StartUpgrading(ushort buildingID, ref Building buildingData) { buildingData.m_frame0.m_constructState = (byte)0; buildingData.m_frame1.m_constructState = (byte)0; buildingData.m_frame2.m_constructState = (byte)0; buildingData.m_frame3.m_constructState = (byte)0; Building.Flags flags = (buildingData.m_flags | Building.Flags.Upgrading) & ~Building.Flags.Completed & ~Building.Flags.LevelUpEducation & ~Building.Flags.LevelUpLandValue; buildingData.m_flags = flags; BuildingManager instance1 = Singleton <BuildingManager> .instance; instance1.UpdateBuildingRenderer(buildingID, true); EffectInfo effect = instance1.m_properties.m_levelupEffect; if (effect != null) { InstanceID instance2 = new InstanceID(); instance2.Building = buildingID; Vector3 meshPosition; Quaternion meshRotation; buildingData.CalculateMeshPosition(out meshPosition, out meshRotation); EffectInfo.SpawnArea spawnArea = new EffectInfo.SpawnArea(Matrix4x4.TRS(meshPosition, meshRotation, Vector3.one), this.m_info.m_lodMeshData); Singleton <EffectManager> .instance.DispatchEffect(effect, instance2, spawnArea, Vector3.zero, 0.0f, 1f, instance1.m_audioGroup); } Vector3 position = buildingData.m_position; position.y += this.m_info.m_size.y; Singleton <NotificationManager> .instance.AddEvent(NotificationEvent.Type.LevelUp, position, 1f); ++Singleton <SimulationManager> .instance.m_currentBuildIndex; }
private bool MustCancelEvent(ICityEvent cityEvent) { Building.Flags flags = Building.Flags.Abandoned | Building.Flags.BurnedDown | Building.Flags.Collapsed | Building.Flags.Deleted | Building.Flags.Demolishing | Building.Flags.Evacuating | Building.Flags.Flooded; return(buildingManager.BuildingHasFlags(cityEvent.BuildingId, flags, true)); }
/// <summary> /// Check building flags contain at least one of the flags in <paramref name="flagMask"/>. /// </summary> /// /// <param name="buildingId">The id of the building to inspect.</param> /// <param name="flagMask">The flags to test.</param> /// <param name="expectedResult">If specified, ensure only the expected flags are found.</param> /// /// <returns>Returns <c>true</c> if the test passes, otherwise <c>false</c>.</returns> public bool CheckBuildingFlags(ushort buildingId, Building.Flags flagMask, Building.Flags?expectedResult = null) { Building.Flags result = Singleton <BuildingManager> .instance.m_buildings.m_buffer[buildingId].m_flags & flagMask; return(expectedResult == null ? result != 0 : result == expectedResult); }
Buildings(Building.Flags flags = Building.Flags.Created) { var mgr = Singleton <Cities::BuildingManager> .instance; return(mgr.m_buildings.m_buffer.Where(e => (e.m_flags & flags) != Cities::Building.Flags.None )); }
public bool CheckBuildingFlags(ushort buildingId, Building.Flags flagMask, Building.Flags?expectedResult = default(Building.Flags?)) { bool ret = false; ProcessBuilding(buildingId, delegate(ushort bId, ref Building building) { ret = LogicUtil.CheckFlags((uint)building.m_flags, (uint)flagMask, (uint?)expectedResult); return(true); }); return(ret); }
/// <summary> /// Gets a value indicating whether the building with specified ID has particular flags. /// The single <see cref="Building.Flags.None"/> value can also be checked for. /// </summary> /// <param name="buildingId">The ID of the building to check the flags of.</param> /// <param name="flags">The building flags to check.</param> /// <param name="includeZero"><c>true</c> if a building without any flags can also be considered.</param> /// <returns> /// <c>true</c> if the building with the specified ID has the specified <paramref name="flags"/>; /// otherwise, <c>false</c>. /// </returns> public bool BuildingHasFlags(ushort buildingId, Building.Flags flags, bool includeZero = false) { if (buildingId == 0) { return(false); } Building.Flags buildingFlags = BuildingManager.instance.m_buildings.m_buffer[buildingId].m_flags; return((buildingFlags & flags) != 0 || (includeZero && buildingFlags == Building.Flags.None)); }
private bool Check(Building.Flags problems, HashSet <ushort> category) { if ((_building.m_flags & problems) != Building.Flags.None) { category.Add(_id); return(true); } else { category.Remove(_id); return(false); } }
public static void Prefix(ushort building, ref Building.Flags changeMask, out bool __state) { if (IgnoreHelper.IsIgnored()) { __state = false; return; } __state = true; ArrayHandler.StartCollecting(); IgnoreHelper.StartIgnore(); }
//Used in PrivateBuildingAI simulation step; move to module later. private static void CheckNearbyBuildingZones(Vector3 position) { int num = Mathf.Max((int)((position.x - 35f) / 64f + 135f), 0); int num2 = Mathf.Max((int)((position.z - 35f) / 64f + 135f), 0); int num3 = Mathf.Min((int)((position.x + 35f) / 64f + 135f), 269); int num4 = Mathf.Min((int)((position.z + 35f) / 64f + 135f), 269); Array16 <Building> buildings = Singleton <BuildingManager> .instance.m_buildings; ushort[] buildingGrid = Singleton <BuildingManager> .instance.m_buildingGrid; for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = buildingGrid[i * 270 + j]; int num6 = 0; while (num5 != 0) { ushort nextGridBuilding = buildings.m_buffer[(int)num5].m_nextGridBuilding; Building.Flags flags = buildings.m_buffer[(int)num5].m_flags; if ((flags & (Building.Flags.Created | Building.Flags.Deleted | Building.Flags.Demolishing)) == Building.Flags.Created) { BuildingInfo info = buildings.m_buffer[(int)num5].Info; if (info != null && info.m_placementStyle == ItemClass.Placement.Automatic) { ItemClass.Zone zone = info.m_class.GetZone(); if (zone != ItemClass.Zone.None && (buildings.m_buffer[(int)num5].m_flags & Building.Flags.ZonesUpdated) != Building.Flags.None && VectorUtils.LengthSqrXZ(buildings.m_buffer[(int)num5].m_position - position) <= 1225f) { Building[] expr_198_cp_0 = buildings.m_buffer; ushort expr_198_cp_1 = num5; expr_198_cp_0[(int)expr_198_cp_1].m_flags = (expr_198_cp_0[(int)expr_198_cp_1].m_flags & ~Building.Flags.ZonesUpdated); if (!buildings.m_buffer[(int)num5].CheckZoning(zone)) { Singleton <BuildingManager> .instance.ReleaseBuilding(num5); } } } } num5 = nextGridBuilding; if (++num6 >= 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } }
public static void Postfix(ushort building, ref Building.Flags changeMask, ref bool __state) { if (!__state) { return; } IgnoreHelper.EndIgnore(); ArrayHandler.StopCollecting(); Command.SendToAll(new BuildingUpdateFlagsCommand() { Building = building, ChangeMask = changeMask }); }
/// <summary> /// Send list of buildings that have specified flags. /// </summary> /// <param name="flags">Flags.</param> protected void SendFlags(Building.Flags flags) { var buffer = Singleton <BuildingManager> .instance.m_buildings.m_buffer; var buildings = new List <CityWebServer.Models.BuildingInfo>(); for (int i = 0; i < buffer.Length; i++) { if ((buffer[i].m_flags & flags) != 0) { buildings.Add(GetBuilding(i)); } } //Using ProblemBuildings here because this is really only used for //the flags that indicate problems but aren't included in the //Notification.Problem enum for some reason, like BurnedDown. SendJson(buildings, "ProblemBuildings"); }
public static string GetStringForDirectionFlag(Building.Flags directionFlags) { var flag = directionFlags & Building.Flags.IncomingOutgoing; if (flag == Building.Flags.IncomingOutgoing) { return("In&Out"); } else if (flag == Building.Flags.Outgoing) // It's from the buildings perspektive, not the cities. { return("In"); } else if (flag == Building.Flags.Incoming) { return("Out"); } return("None"); }
private void ExportBuildings() { BuildingManager buildingManager = Singleton <BuildingManager> .instance; Building[] buildings = buildingManager.m_buildings.m_buffer; foreach (Building building in buildings) { Building.Flags buildingFlags = building.m_flags; if (buildingFlags.IsFlagSet(Building.Flags.Created)) { OSMWay generatedBuilding = CreateBuilding(unindexedWayOffset++, building); if (generatedBuilding != null) { osmWays.Add(generatedBuilding); } } } }
private bool ExtinguishFire(ushort vehicleID, ref Vehicle data, ushort buildingID, ref Building buildingData) { int width = buildingData.Width; int length = buildingData.Length; int num = Mathf.Min(5000, (int)buildingData.m_fireIntensity * (width * length)); if (num != 0 && Singleton <SimulationManager> .instance.m_randomizer.Int32(8u) == 0) { num = Mathf.Max(num - this.m_fireFightingRate, 0); num /= width * length; buildingData.m_fireIntensity = (byte)num; if (num == 0) { if (data.m_sourceBuilding != 0) { int tempExport = (int)Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_tempExport; Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_tempExport = (byte)Mathf.Min(tempExport + 1, 255); } Building.Flags flags = buildingData.m_flags; if (buildingData.m_productionRate != 0) { buildingData.m_flags |= Building.Flags.Active; } Building.Flags flags2 = buildingData.m_flags; Singleton <BuildingManager> .instance.UpdateBuildingRenderer(buildingID, buildingData.GetLastFrameData().m_fireDamage == 0); if (flags2 != flags) { Singleton <BuildingManager> .instance.UpdateFlags(buildingID, flags2 ^ flags); } GuideController properties = Singleton <GuideManager> .instance.m_properties; if (properties != null) { Singleton <BuildingManager> .instance.m_buildingOnFire.Deactivate(buildingID, false); } } } return(num == 0); }
private bool MustCancelEvent(ICityEvent cityEvent) { if (!config.AreEventsEnabled && cityEvent is RealTimeCityEvent) { return(true); } const Building.Flags flags = Building.Flags.Abandoned | Building.Flags.BurnedDown | Building.Flags.Collapsed | Building.Flags.Deleted | Building.Flags.Demolishing | Building.Flags.Evacuating | Building.Flags.Flooded; if (buildingManager.BuildingHasFlags(cityEvent.BuildingId, flags, includeZero: true)) { return(true); } if (cityEvent is VanillaEvent vanillaEvent) { EventData.Flags eventFlags = eventManager.GetEventFlags(vanillaEvent.EventId); return(eventFlags == 0 || (eventFlags & (EventData.Flags.Cancelled | EventData.Flags.Deleted)) != 0); } return(false); }
internal static void LightBuildingOnFire(ushort buildingId, ref Building data) { var bm = Singleton <BuildingManager> .instance; if ((bm.m_buildings.m_buffer[buildingId].m_problems & Notification.Problem.Fire) != 0) { return; } int fireHazard; int fireSize; int fireTolerance; bm.m_buildings.m_buffer[buildingId].Info.m_buildingAI.GetFireParameters(buildingId, ref data, out fireHazard, out fireSize, out fireTolerance); if (fireHazard != 0 && (data.m_flags & (Building.Flags.Abandoned | Building.Flags.Completed)) == Building.Flags.Completed && data.m_fireIntensity == 0 && data.GetLastFrameData().m_fireDamage == 0) { // Is the building under water by chance? float waterLevel = Singleton <TerrainManager> .instance.WaterLevel(new Vector2(data.m_position.x, data.m_position.z)); if (waterLevel <= data.m_position.y) { Building.Flags preDeactivateFlags = data.m_flags; data.m_fireIntensity = (byte)fireSize; data.Info.m_buildingAI.BuildingDeactivated(buildingId, ref data); Building.Flags postDeactivateFlags = data.m_flags; Singleton <BuildingManager> .instance.UpdateBuildingRenderer(buildingId, true); if (postDeactivateFlags != preDeactivateFlags) { Singleton <BuildingManager> .instance.UpdateFlags(buildingId, postDeactivateFlags ^ preDeactivateFlags); } } } }
public static void DestroyBuildings(int seed, InstanceManager.Group group, Vector3 position, float preRadius, float removeRadius, float destructionRadiusMin, float destructionRadiusMax, float burnRadiusMin, float burnRadiusMax, float probability) { int num = Mathf.Max((int)((position.x - preRadius - 72f) / 64f + 135f), 0); int num2 = Mathf.Max((int)((position.z - preRadius - 72f) / 64f + 135f), 0); int num3 = Mathf.Min((int)((position.x + preRadius + 72f) / 64f + 135f), 269); int num4 = Mathf.Min((int)((position.z + preRadius + 72f) / 64f + 135f), 269); Array16 <Building> buildings = Singleton <BuildingManager> .instance.m_buildings; ushort[] buildingGrid = Singleton <BuildingManager> .instance.m_buildingGrid; for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = buildingGrid[i * 270 + j]; int num6 = 0; while (num5 != 0) { ushort nextGridBuilding = buildings.m_buffer[(int)num5].m_nextGridBuilding; Building.Flags flags = buildings.m_buffer[(int)num5].m_flags; if ((flags & (Building.Flags.Created | Building.Flags.Deleted | Building.Flags.Untouchable | Building.Flags.Demolishing)) == Building.Flags.Created) { Vector3 position2 = buildings.m_buffer[(int)num5].m_position; float num7 = VectorUtils.LengthXZ(position2 - position); if (num7 < preRadius) { Randomizer randomizer = new Randomizer((int)num5 | seed << 16); float num8 = (destructionRadiusMax - num7) / Mathf.Max(1f, destructionRadiusMax - destructionRadiusMin); float num9 = (burnRadiusMax - num7) / Mathf.Max(1f, burnRadiusMax - burnRadiusMin); bool flag = false; bool flag2 = (float)randomizer.Int32(10000u) < num8 * probability * 10000f; bool flag3 = (float)randomizer.Int32(10000u) < num9 * probability * 10000f; if (removeRadius != 0f && num7 - 72f < removeRadius) { BuildingInfo info = buildings.m_buffer[(int)num5].Info; if (info.m_circular) { float num10 = (float)(buildings.m_buffer[(int)num5].Width + buildings.m_buffer[(int)num5].Length) * 2f; flag = (num7 < removeRadius + num10); } else { float angle = buildings.m_buffer[(int)num5].m_angle; Vector2 a = VectorUtils.XZ(position2); Vector2 vector = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)); Vector2 vector2 = new Vector2(vector.y, -vector.x); vector *= (float)buildings.m_buffer[(int)num5].Width * 4f; vector2 *= (float)buildings.m_buffer[(int)num5].Length * 4f; Quad2 quad = default(Quad2); quad.a = a - vector - vector2; quad.b = a + vector - vector2; quad.c = a + vector + vector2; quad.d = a - vector + vector2; float num11 = VectorUtils.LengthXZ(position - new Vector3(quad.a.x, position2.y, quad.a.y)); float num12 = VectorUtils.LengthXZ(position - new Vector3(quad.b.x, position2.y, quad.b.y)); float num13 = VectorUtils.LengthXZ(position - new Vector3(quad.c.x, position2.y, quad.c.y)); float num14 = VectorUtils.LengthXZ(position - new Vector3(quad.d.x, position2.y, quad.d.y)); flag = (quad.Intersect(VectorUtils.XZ(position)) || num11 < removeRadius || num12 < removeRadius || num13 < removeRadius || num14 < removeRadius); } } if (flag) { BuildingInfo info2 = buildings.m_buffer[(int)num5].Info; info2.m_buildingAI.CollapseBuilding(num5, ref buildings.m_buffer[(int)num5], group, false, true, Mathf.RoundToInt(num9 * 255f)); } else if (flag2) { BuildingInfo info3 = buildings.m_buffer[(int)num5].Info; ItemClass.Level lvl = (ItemClass.Level)buildings.m_buffer[(int)num5].m_level; float p = 0.5f; if (info3.m_buildingAI as OfficeBuildingAI != null || info3.m_buildingAI as CommercialBuildingAI != null || info3.m_buildingAI as IndustrialBuildingAI != null) { switch (lvl) { case ItemClass.Level.Level1: p = 1f; break; case ItemClass.Level.Level2: p = 0.6f; break; case ItemClass.Level.Level3: p = 0.2f; break; } } else if (info3.m_buildingAI as ResidentialBuildingAI != null) { switch (lvl) { case ItemClass.Level.Level1: p = 1f; break; case ItemClass.Level.Level2: p = 0.8f; break; case ItemClass.Level.Level3: p = 0.6f; break; case ItemClass.Level.Level4: p = 0.4f; break; case ItemClass.Level.Level5: p = 0.2f; break; } } // Large buildings are tougher float s = Mathf.Sqrt(buildings.m_buffer[(int)num5].Length * buildings.m_buffer[(int)num5].Width); if (s > 4) { p -= s / 16; } // Make shelters a little more useful if ((flags & Building.Flags.Evacuating) == Building.Flags.Evacuating) { p -= 0.2f; } if (p > 0 && (float)randomizer.Int32(10000u) < p * 10000f) { //Debug.Log("Destroyed: " + info3.name + " (" + info3.m_buildingAI.name + "), level: " + lvl.ToString()); info3.m_buildingAI.CollapseBuilding(num5, ref buildings.m_buffer[(int)num5], group, false, false, Mathf.RoundToInt(num9 * 255f)); } } else if (flag3 && (flags & Building.Flags.Collapsed) == Building.Flags.None && buildings.m_buffer[(int)num5].m_fireIntensity == 0) { BuildingInfo info4 = buildings.m_buffer[(int)num5].Info; info4.m_buildingAI.BurnBuilding(num5, ref buildings.m_buffer[(int)num5], group, false); } } } num5 = nextGridBuilding; if (++num6 >= 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } }
public bool BuildingHasFlags(ushort buildingId, Building.Flags flags) { return(buildingId == 0 ? false : (BuildingManager.instance.m_buildings.m_buffer[buildingId].m_flags & flags) != 0); }
protected override void setAutobudget() { DistrictManager dm = Singleton <DistrictManager> .instance; // Water int waterCapacity = dm.m_districts.m_buffer[0].GetWaterCapacity(); int waterConsumption = dm.m_districts.m_buffer[0].GetWaterConsumption(); // Sewage int sewageCapacity = dm.m_districts.m_buffer[0].GetSewageCapacity(); int sewageAccumulation = dm.m_districts.m_buffer[0].GetSewageAccumulation(); // No water and no sewage if (waterCapacity <= 0 && sewageCapacity <= 0) { return; } int waterStorageCapacity = dm.m_districts.m_buffer[0].GetWaterStorageCapacity(); int waterStorageAmount = dm.m_districts.m_buffer[0].GetWaterStorageAmount(); int waterStorageRatio = waterStorageCapacity == 0 ? 0 : waterStorageAmount * 100 / waterStorageCapacity; AutobudgetObjectsContainer o = Singleton <AutobudgetManager> .instance.container; EconomyManager em = Singleton <EconomyManager> .instance; SimulationManager sm = Singleton <SimulationManager> .instance; int budget = em.GetBudget(ItemClass.Service.Water, ItemClass.SubService.None, sm.m_isNightTime); float buffer = getBufferCoefficient(AutobudgetBuffer); int newWaterBudget = waterStorageRatio > TargetWaterStorageRatio ? 50 : calculateNewBudget(waterCapacity, waterConsumption, budget, buffer); int newSewageBudget = calculateNewBudget(sewageCapacity, sewageAccumulation, budget, buffer); int newBudget = Math.Max(newWaterBudget, newSewageBudget); newBudget = Math.Min(newBudget, BudgetMaxValue); if (newBudget == BudgetMaxValue && PauseWhenBudgetTooHigh && !isPausedRecently) { SetPause(); isPausedRecently = true; Singleton <InfoManager> .instance.SetCurrentMode(InfoManager.InfoMode.Water, InfoManager.SubInfoMode.Default); } if (newBudget < BudgetMaxValue) { isPausedRecently = false; } // Heating autobudget if (UseHeatingAutobudget && newBudget < HeatingBudgetMaxValue) { if (heatingCounter-- <= 0) { heatingCounter = heatingRefreshCount; if (currentHeatingBudget < newBudget) { currentHeatingBudget = newBudget; } int heatingProblemCount = 0; int allBldCount = 0; BuildingManager bm = Singleton <BuildingManager> .instance; for (int n = 0; n <= (255 + 1) * 192 - 1; n++) { Building.Flags flags = bm.m_buildings.m_buffer[n].m_flags; if ((flags & Building.Flags.Created) != Building.Flags.None) { if (bm.m_buildings.m_buffer[n].m_heatingProblemTimer > 0) { heatingProblemCount++; } allBldCount++; } } if (allBldCount > 0) { if (heatingProblemCount > 0) { currentHeatingBudget += 1 + heatingProblemCount * 20 / allBldCount; } else { currentHeatingBudget -= 1; } } } if (currentHeatingBudget > HeatingBudgetMaxValue) { currentHeatingBudget = HeatingBudgetMaxValue; } if (currentHeatingBudget > newBudget) { newBudget = currentHeatingBudget; } } setBudget(newBudget); }
protected override void StartActions() { if (m_ghostMode) { for (ushort a = 1; a < BuildingManager.instance.m_buildings.m_buffer.Length; a++) { if (BuildingManager.instance.m_buildings.m_buffer[a].Info.m_buildingAI is PrivateBuildingAI) { Vector3 position = BuildingManager.instance.m_buildings.m_buffer[a].m_position; int num = Mathf.Max((int)((position.x - 35f) / 64f + 135f), 0); int num2 = Mathf.Max((int)((position.z - 35f) / 64f + 135f), 0); int num3 = Mathf.Min((int)((position.x + 35f) / 64f + 135f), 269); int num4 = Mathf.Min((int)((position.z + 35f) / 64f + 135f), 269); Array16 <Building> buildings = Singleton <BuildingManager> .instance.m_buildings; ushort[] buildingGrid = Singleton <BuildingManager> .instance.m_buildingGrid; for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = buildingGrid[i * 270 + j]; int num6 = 0; while (num5 != 0) { ushort nextGridBuilding = buildings.m_buffer[num5].m_nextGridBuilding; Building.Flags flags = buildings.m_buffer[num5].m_flags; if ((flags & (Building.Flags.Created | Building.Flags.Deleted | Building.Flags.Demolishing | Building.Flags.Collapsed)) == Building.Flags.Created) { BuildingInfo info = buildings.m_buffer[num5].Info; if (info != null && info.m_placementStyle == ItemClass.Placement.Automatic) { ItemClass.Zone zone = info.m_class.GetZone(); ItemClass.Zone secondaryZone = info.m_class.GetSecondaryZone(); if (zone != ItemClass.Zone.None && VectorUtils.LengthSqrXZ(buildings.m_buffer[num5].m_position - position) <= 1225f) { buildings.m_buffer[num5].CheckZoning(zone, secondaryZone, true); } } } num5 = nextGridBuilding; if (++num6 >= 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } } } for (ushort i = 1; i < ZoneManager.instance.m_blocks.m_buffer.Length; i++) { bool changed = false; for (int x = 0; x < 4; x++) { for (int z = 0; z < 8; z++) { changed = ZoneMixerOverrides.GetBlockZoneSanitize(ref ZoneManager.instance.m_blocks.m_buffer[i], x, z) | changed; } } if (changed) { ZoneManager.instance.m_blocks.m_buffer[i].RefreshZoning(i); } } K45DialogControl.ShowModal(new K45DialogControl.BindProperties() { icon = ZoneMixerMod.Instance.IconName, title = Locale.Get("K45_ZM_GHOST_MODE_MODAL_TITLE"), message = Locale.Get("K45_ZM_GHOST_MODE_MODAL_MESSAGE"), showButton1 = true, textButton1 = Locale.Get("K45_ZM_OK_BUTTON") }, (x) => true); } }
public ushort FindBuilding(Vector3 pos, float maxDistance, ItemClass.Service service, ItemClass.SubService subService, Building.Flags flagsRequired, Building.Flags flagsForbidden) { int num1 = Mathf.Max((int)(((double)pos.x - (double)maxDistance) / 64.0 + 135.0), 0); int num2 = Mathf.Max((int)(((double)pos.z - (double)maxDistance) / 64.0 + 135.0), 0); int num3 = Mathf.Min((int)(((double)pos.x + (double)maxDistance) / 64.0 + 135.0), 269); int num4 = Mathf.Min((int)(((double)pos.z + (double)maxDistance) / 64.0 + 135.0), 269); ushort num5 = 0; float num6 = maxDistance * maxDistance; for (int index1 = num2; index1 <= num4; ++index1) { for (int index2 = num1; index2 <= num3; ++index2) { ushort num7 = this.m_buildingGrid[index1 * 270 + index2]; int num8 = 0; while ((int)num7 != 0) { BuildingInfo info = this.m_buildings.m_buffer[(int)num7].Info; //added null check //begin mod if (info != null && (info.m_class.m_service == service || service == ItemClass.Service.None) && (info.m_class.m_subService == subService || subService == ItemClass.SubService.None) && (this.m_buildings.m_buffer[(int)num7].m_flags & (flagsRequired | flagsForbidden)) == flagsRequired) { //end mod float num9 = Vector3.SqrMagnitude(pos - this.m_buildings.m_buffer[(int)num7].m_position); if ((double)num9 < (double)num6) { num5 = num7; num6 = num9; } } num7 = this.m_buildings.m_buffer[(int)num7].m_nextGridBuilding; if (++num8 >= 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace); break; } } } } return(num5); }
public static List <ushort> FindAllBuildings(this BuildingManager buildingManager, Vector3 position, float maxDistance, ItemClass.Service[] services, ItemClass.SubService[] subServices, Building.Flags flagsRequired, Building.Flags flagsForbidden) { List <ushort> buildings = new List <ushort>(); var halfBuildingGrid = BuildingManager.BUILDINGGRID_RESOLUTION / 2f; var area = maxDistance * maxDistance; var minX = Mathf.Max(((position.x - maxDistance) / BuildingManager.BUILDINGGRID_CELL_SIZE) + halfBuildingGrid, 0); var minZ = Mathf.Max(((position.z - maxDistance) / BuildingManager.BUILDINGGRID_CELL_SIZE) + halfBuildingGrid, 0); var maxX = Mathf.Min(((position.x + maxDistance) / BuildingManager.BUILDINGGRID_CELL_SIZE) + halfBuildingGrid, BuildingManager.BUILDINGGRID_RESOLUTION - 1); var maxZ = Mathf.Min(((position.z + maxDistance) / BuildingManager.BUILDINGGRID_CELL_SIZE) + halfBuildingGrid, BuildingManager.BUILDINGGRID_RESOLUTION - 1); for (var z = (int)minZ; z <= maxZ; ++z) { for (var x = (int)minX; x <= maxX; ++x) { var potentialBuildingId = buildingManager.m_buildingGrid[(z * BuildingManager.BUILDINGGRID_RESOLUTION) + x]; while (potentialBuildingId != 0) { var building = buildingManager.m_buildings.m_buffer[potentialBuildingId]; var buildingInfo = building.Info; if ((services.Contains(buildingInfo.GetService()) || services.Contains(ItemClass.Service.None) || services.Count() == 0) && (subServices.Contains(buildingInfo.GetSubService()) || subServices.Contains(ItemClass.SubService.None) || subServices.Count() == 0) && (building.m_flags & (flagsRequired | flagsForbidden)) == flagsRequired) { var magnitude = Vector3.SqrMagnitude(position - building.m_position); if (magnitude < area) { buildings.Add(potentialBuildingId); } } potentialBuildingId = building.m_nextGridBuilding; } } } return(buildings); }
public static ushort FindBuilding(Vector3 pos, float maxDistance, ItemClass.Service service, ItemClass.SubService subService, TransferManager.TransferReason[] allowedTypes, Building.Flags flagsRequired, Building.Flags flagsForbidden) { BuildingManager bm = Singleton <BuildingManager> .instance; //if (allowedTypes == null || allowedTypes.Length == 0) //{ // return bm.FindBuilding(pos, maxDistance, service, subService, flagsRequired, flagsForbidden); //} int num = Mathf.Max((int)(((pos.x - maxDistance) / 64f) + 135f), 0); int num2 = Mathf.Max((int)(((pos.z - maxDistance) / 64f) + 135f), 0); int num3 = Mathf.Min((int)(((pos.x + maxDistance) / 64f) + 135f), 269); int num4 = Mathf.Min((int)(((pos.z + maxDistance) / 64f) + 135f), 269); ushort result = 0; float currentDistance = maxDistance * maxDistance; for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort buildingId = bm.m_buildingGrid[(i * 270) + j]; int num7 = 0; while (buildingId != 0) { BuildingInfo info = bm.m_buildings.m_buffer[buildingId].Info; if (!CheckInfoCompatibility(pos, service, subService, allowedTypes, flagsRequired, flagsForbidden, bm, ref result, ref currentDistance, buildingId, info) && info.m_subBuildings?.Length > 0) { foreach (BuildingInfo.SubInfo subBuilding in info.m_subBuildings) { if (subBuilding != null && CheckInfoCompatibility(pos, service, subService, allowedTypes, flagsRequired, flagsForbidden, bm, ref result, ref currentDistance, buildingId, subBuilding.m_buildingInfo)) { break; } } } buildingId = bm.m_buildings.m_buffer[buildingId].m_nextGridBuilding; if (++num7 >= 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } return(result); }
internal static bool IsFlagSet(this Building.Flags value, Building.Flags flag) => (value & flag) != 0;
internal static bool CheckFlags(this Building.Flags value, Building.Flags required, Building.Flags forbidden = 0) => (value & (required | forbidden)) == required;
public override string GetLocalizedStatus(ushort vehicleID, ref Vehicle data, out InstanceID target) { if ((data.m_flags & Vehicle.Flags.TransferToTarget) != 0) { ushort targetBuilding = data.m_targetBuilding; if ((data.m_flags & Vehicle.Flags.GoingBack) != 0) { target = InstanceID.Empty; TransferManager.TransferReason transferType = (TransferManager.TransferReason)data.m_transferType; if (transferType == (TransferManager.TransferReason) 113) { return(Localization.Get("FOR_FUEL")); } return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_RETURN")); } if ((data.m_flags & Vehicle.Flags.WaitingTarget) != 0) { target = InstanceID.Empty; return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_UNLOAD")); } if (targetBuilding != 0) { Building.Flags flags = Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetBuilding].m_flags; TransferManager.TransferReason transferType = (TransferManager.TransferReason)data.m_transferType; if ((data.m_flags & Vehicle.Flags.Exporting) != 0 || (flags & Building.Flags.IncomingOutgoing) != 0) { target = InstanceID.Empty; if (transferType == (TransferManager.TransferReason) 113) { return(Localization.Get("FOR_FUEL")); } return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_EXPORT", transferType.ToString())); } if ((data.m_flags & Vehicle.Flags.Importing) != 0) { target = InstanceID.Empty; target.Building = targetBuilding; if (transferType == (TransferManager.TransferReason) 113) { return(Localization.Get("FOR_FUEL")); } return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_IMPORT", transferType.ToString())); } target = InstanceID.Empty; target.Building = targetBuilding; if (transferType == (TransferManager.TransferReason) 110) { return(Localization.Get("TRANSFER_CONSTRUCTION")); } else if (transferType == (TransferManager.TransferReason) 111) { return(Localization.Get("TRANSFER_OPERATION")); } else if (transferType == (TransferManager.TransferReason) 113) { return(Localization.Get("FOR_FUEL")); } else { return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_DELIVER", transferType.ToString())); } } } target = InstanceID.Empty; return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CONFUSED")); }