public override void OnCreated(IThreading threading) { _citizenManager = Singleton<CitizenManager>.instance; _buildingManager = Singleton<BuildingManager>.instance; base.OnCreated(threading); }
protected override bool StartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget) { VehicleInfo info = this.m_info; ushort driverInstance = this.GetDriverInstance(vehicleID, ref vehicleData); if (driverInstance == 0) { return(false); } CitizenManager instance = Singleton <CitizenManager> .instance; CitizenInfo info2 = instance.m_instances.m_buffer[(int)driverInstance].Info; NetInfo.LaneType laneTypes = NetInfo.LaneType.Vehicle | NetInfo.LaneType.Pedestrian; VehicleInfo.VehicleType vehicleType = this.m_info.m_vehicleType; bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != (Vehicle.Flags) 0; bool randomParking = false; ushort targetBuilding = instance.m_instances.m_buffer[(int)driverInstance].m_targetBuilding; if (targetBuilding != 0 && Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)targetBuilding].Info.m_class.m_service > ItemClass.Service.Office) { randomParking = true; } PathUnit.Position startPosA; PathUnit.Position startPosB; float num; float num2; PathUnit.Position endPosA; if (PathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) && info2.m_citizenAI.FindPathPosition(driverInstance, ref instance.m_instances.m_buffer[(int)driverInstance], endPos, laneTypes, vehicleType, undergroundTarget, out endPosA)) { if (!startBothWays || num < 10f) { startPosB = default(PathUnit.Position); } PathUnit.Position endPosB = default(PathUnit.Position); SimulationManager instance2 = Singleton <SimulationManager> .instance; uint path; if (Singleton <PathManager> .instance.CreatePath(ExtendedVehicleType.PassengerCar, out path, ref instance2.m_randomizer, instance2.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, default(PathUnit.Position), laneTypes, vehicleType, 20000f, false, false, false, false, randomParking)) { if (vehicleData.m_path != 0u) { Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path); } vehicleData.m_path = path; vehicleData.m_flags |= Vehicle.Flags.WaitingPath; return(true); } } return(false); }
IEnumerator InitPopulation() { yield return(0); for (int i = 0; i < homeless; i++) { GameObject citizen = walkerPool.GetCitizen(startTile, ScenarioMgr.Direction.Right); CitizenManager mgr = citizen.GetComponent("CitizenManager") as CitizenManager; mgr.SetUp(scenario, startTile, ScenarioMgr.Direction.Right, true, startTile, null, false); homelessCollection.Enqueue(mgr); yield return(0); } StartCoroutine("PopulationUpdate"); }
public DormStudentManager() { Logger.logInfo(LOG_SENIORS, "StudentManager Created"); _instance = this; this._randomizer = new Randomizer((uint)73); this._citizenManager = Singleton <CitizenManager> .instance; this._buildingManager = Singleton <BuildingManager> .instance; // TODO: This array size is excessive but will allow for never worrying about resizing, should consider allowing for resizing instead this._familiesWithStudents = new uint[CitizenManager.MAX_UNIT_COUNT]; this._seniorCitizensBeingProcessed = new HashSet <uint>(); }
public SeniorCitizenManager() { Logger.logInfo(LOG_SENIORS, "SeniorCitizenManager Created"); instance = this; this.randomizer = new Randomizer((uint) 73); this.citizenManager = Singleton<CitizenManager>.instance; this.buildingManager = Singleton<BuildingManager>.instance; // TODO: This array size is excessive but will allow for never worrying about resizing, should consider allowing for resizing instead this.familiesWithSeniors = new uint[CitizenManager.MAX_UNIT_COUNT]; this.seniorCitizensBeingProcessed = new HashSet<uint>(); }
/// <summary> /// Building Service requests wrapper /// </summary> public static bool IsBuildingTransferAllowed(ushort buildingID, ref Building data, TransferManager.TransferReason reason, TransferManager.TransferOffer offer, bool summarizedLog = false) { DistrictManager districtManager = Singleton <DistrictManager> .instance; BuildingManager buildingManager = Singleton <BuildingManager> .instance; CitizenManager citizenManager = Singleton <CitizenManager> .instance; Building srcBuilding = buildingManager.m_buildings.m_buffer[(int)buildingID]; Building dstBuilding = buildingManager.m_buildings.m_buffer[(int)offer.Building]; ushort dstBuildingId = offer.Building; //fix for services based on resident instead of building: if (offer.Building == 0 && offer.Citizen != 0) { dstBuildingId = citizenManager.m_citizens.m_buffer[offer.Citizen].GetBuildingByLocation(); dstBuilding = buildingManager.m_buildings.m_buffer[dstBuildingId]; //still no building -> citizen out in the wild (e.g. waiting for taxi) if (dstBuildingId == 0) { var instid = citizenManager.m_citizens.m_buffer[offer.Citizen].m_instance; dstBuilding.m_position = citizenManager.m_instances.m_buffer[instid].GetLastFramePosition(); //pass by value, overwrite OK } } string srcBuildingName = buildingManager.GetBuildingName(buildingID, InstanceID.Empty); string dstBuildingName = buildingManager.GetBuildingName(dstBuildingId, InstanceID.Empty); string dstCitizenName = citizenManager.GetCitizenName(offer.Citizen); string srcDistrictName = FindDistrictName(srcBuilding.m_position); string dstDistrictName = FindDistrictName(dstBuilding.m_position); bool allowed = DistrictChecker.IsTransferAllowed(data.m_position, dstBuilding.m_position, buildingID, dstBuildingId, reason, false); if (summarizedLog) { Utils.LogBuilding(String.Format(" - Building #{0} queried (allowed: {1})", buildingID, allowed)); } else { Utils.LogBuilding("------------------------------------------------------------" + String.Format("\nBuilding #{0} queried (allowed: {1})", buildingID, allowed) + String.Format("\n - Transfer: reason={0}, offer={1}", reason, Utils.ToString(offer)) + String.Format("\n - Origin: {0}", srcBuildingName) + String.Format("\n - Destination: building='{0}', citizen='{1}'", dstBuildingName, dstCitizenName) + String.Format("\n - District: {0} -> {1}", srcDistrictName, dstDistrictName)); } return(allowed); }
public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget) { CitizenManager instance = Singleton <CitizenManager> .instance; ushort passengerInstance = CustomTaxiAI.GetPassengerInstance(vehicleID, ref vehicleData); if (passengerInstance == 0 || (instance.m_instances.m_buffer[(int)passengerInstance].m_flags & CitizenInstance.Flags.Character) != CitizenInstance.Flags.None) { return(base.StartPathFind(vehicleID, ref vehicleData, startPos, endPos, startBothWays, endBothWays, undergroundTarget)); } VehicleInfo info = this.m_info; CitizenInfo info2 = instance.m_instances.m_buffer[(int)passengerInstance].Info; NetInfo.LaneType laneType = NetInfo.LaneType.Vehicle | NetInfo.LaneType.Pedestrian | NetInfo.LaneType.TransportVehicle; VehicleInfo.VehicleType vehicleType = this.m_info.m_vehicleType; bool allowUnderground = (vehicleData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None; PathUnit.Position startPosA; PathUnit.Position startPosB; float num; float num2; PathUnit.Position endPosA; if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) && info2.m_citizenAI.FindPathPosition(passengerInstance, ref instance.m_instances.m_buffer[(int)passengerInstance], endPos, laneType, vehicleType, undergroundTarget, out endPosA)) { if ((instance.m_instances.m_buffer[(int)passengerInstance].m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None) { laneType |= NetInfo.LaneType.PublicTransport; } if (!startBothWays || num < 10f) { startPosB = default(PathUnit.Position); } PathUnit.Position endPosB = default(PathUnit.Position); SimulationManager instance2 = Singleton <SimulationManager> .instance; uint path; if (Singleton <CustomPathManager> .instance.CreatePath(ExtVehicleType.Taxi, out path, ref instance2.m_randomizer, instance2.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, laneType, vehicleType, 20000f)) { if (vehicleData.m_path != 0u) { Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path); } vehicleData.m_path = path; vehicleData.m_flags |= Vehicle.Flags.WaitingPath; return(true); } } return(false); }
public void RemoveWorkOffers(uint citizenIndex) { // Actually we're going to look for any outstanding job/student transfer offers for this person and remove them CitizenManager citizenManager = Singleton <CitizenManager> .instance; TransferManager transferManager = Singleton <TransferManager> .instance; var offer = default(TransferManager.TransferOffer); offer.Citizen = citizenIndex; for (var reason = TransferManager.TransferReason.Worker0; reason <= TransferManager.TransferReason.Worker3; ++reason) { transferManager.RemoveOutgoingOffer(reason, offer); } }
public string getStats() { CitizenManager instance = Singleton <CitizenManager> .instance; EconomyManager econManager = Singleton <EconomyManager> .instance; m = m + "ID,flags,home,work,visiting,health,agegroup,education,wellbeing,gender,subculture,happiness,family,class,name,taxRate" + Environment.NewLine; int counter = 0; for (int i = 0; i < instance.m_citizens.m_buffer.Length; i++) { Citizen ci = instance.m_citizens.m_buffer[i]; uint ciInt = ci.m_instance; CitizenInfo ciInfo = ci.GetCitizenInfo(ciInt); //only get citizens that live in our city -> the list includes tourists etc if (instance.m_citizens.m_buffer[i].m_flags != 0 && !ci.Dead && ci.m_homeBuilding > 0) { m = m + ciInt + "," + (ci.m_flags + "").Replace(",", "-") + "," + ci.m_homeBuilding + "," + ci.m_workBuilding + "," + ci.m_visitBuilding + "," + Citizen.GetHealthLevel(ci.m_health) + "," + Citizen.GetAgeGroup(ci.Age) + "," + ci.EducationLevel + "," + ci.m_wellbeing + "," + ciInfo.m_gender + "," + ciInfo.m_subCulture + "," + Citizen.GetHappinessLevel(Citizen.GetHappiness(ci.m_health, ci.m_wellbeing)) + "," + ci.m_family + "," + ciInfo.m_class + "," + instance.GetInstanceName((ushort)ciInt) + "," + econManager.GetTaxRate(ciInfo.m_class) + Environment.NewLine; counter++; }// end if if (counter > dataLimit) { return(m); } }//end for return(m); }
public bool CustomParkVehicle(ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position pathPos, uint nextPath, int nextPositionIndex, out byte segmentOffset) { CitizenManager citizenManager = Singleton <CitizenManager> .instance; // TODO remove this: uint driverCitizenId = 0u; ushort driverCitizenInstanceId = 0; ushort targetBuildingId = 0; // NON-STOCK CODE uint curCitizenUnitId = vehicleData.m_citizenUnits; int numIterations = 0; while (curCitizenUnitId != 0u && driverCitizenId == 0u) { uint nextUnit = citizenManager.m_units.m_buffer[curCitizenUnitId].m_nextUnit; for (int i = 0; i < 5; i++) { uint citizenId = citizenManager.m_units.m_buffer[curCitizenUnitId].GetCitizen(i); if (citizenId != 0u) { driverCitizenInstanceId = citizenManager.m_citizens.m_buffer[citizenId].m_instance; if (driverCitizenInstanceId != 0) { driverCitizenId = citizenManager.m_instances.m_buffer[(int)driverCitizenInstanceId].m_citizen; // NON-STOCK CODE START targetBuildingId = citizenManager.m_instances.m_buffer[(int)driverCitizenInstanceId].m_targetBuilding; // NON-STOCK CODE END break; } } } curCitizenUnitId = nextUnit; if (++numIterations > 524288) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } #if BENCHMARK using (var bm = new Benchmark(null, "ExtParkVehicle")) { #endif return(ExtParkVehicle(vehicleID, ref vehicleData, driverCitizenId, driverCitizenInstanceId, ref ExtCitizenInstanceManager.Instance.ExtInstances[driverCitizenInstanceId], targetBuildingId, pathPos, nextPath, nextPositionIndex, out segmentOffset)); #if BENCHMARK } #endif }
/// <summary> /// Logs building info for debug use. /// </summary> /// <param name="buildings">The buildings.</param> /// <param name="vehicles">The vehicles.</param> /// <param name="districtManager">The district manager.</param> /// <param name="citizenManager">The citizen manager.</param> /// <param name="buildingId">The building identifier.</param> /// <param name="serviceBuilding">The service building.</param> /// <param name="targetBuilding">The target building.</param> /// <param name="buildingStamp">The building stamp.</param> private static void DebugListLog( Building[] buildings, Vehicle[] vehicles, DistrictManager districtManager, CitizenManager citizenManager, ushort buildingId, ServiceBuildingInfo serviceBuilding, TargetBuildingInfo targetBuilding, BuildingStamp buildingStamp) { if (buildings[buildingId].Info != null && (buildings[buildingId].m_flags & Building.Flags.Created) == Building.Flags.Created) { Log.InfoList info = DebugInfoMsg(buildings, vehicles, districtManager, citizenManager, buildingId, serviceBuilding, targetBuilding, buildingStamp); Log.DevDebug(typeof(BuildingHelper), "DebugListLog", info.ToString()); } }
private void ArrestCriminals(ushort vehicleID, ref Vehicle vehicleData, ushort building) { if ((int)vehicleData.m_transferSize >= this.m_criminalCapacity) { return; } BuildingManager instance = Singleton <BuildingManager> .instance; CitizenManager instance2 = Singleton <CitizenManager> .instance; uint num = instance.m_buildings.m_buffer[(int)building].m_citizenUnits; int num2 = 0; while (num != 0u) { uint nextUnit = instance2.m_units.m_buffer[(int)((UIntPtr)num)].m_nextUnit; for (int i = 0; i < 5; i++) { uint citizen = instance2.m_units.m_buffer[(int)((UIntPtr)num)].GetCitizen(i); if (citizen != 0u && (instance2.m_citizens.m_buffer[(int)((UIntPtr)citizen)].Criminal || instance2.m_citizens.m_buffer[(int)((UIntPtr)citizen)].Arrested) && !instance2.m_citizens.m_buffer[(int)((UIntPtr)citizen)].Dead && instance2.m_citizens.m_buffer[(int)((UIntPtr)citizen)].GetBuildingByLocation() == building) { instance2.m_citizens.m_buffer[(int)((UIntPtr)citizen)].SetVehicle(citizen, vehicleID, 0u); if (instance2.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_vehicle != vehicleID) { vehicleData.m_transferSize = (ushort)this.m_criminalCapacity; return; } instance2.m_citizens.m_buffer[(int)((UIntPtr)citizen)].Arrested = true; ushort instance3 = instance2.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_instance; if (instance3 != 0) { instance2.ReleaseCitizenInstance(instance3); } instance2.m_citizens.m_buffer[(int)((UIntPtr)citizen)].CurrentLocation = Citizen.Location.Moving; if ((int)(vehicleData.m_transferSize += 1) >= this.m_criminalCapacity) { return; } } } num = nextUnit; if (++num2 > 524288) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } }
// Copied from ResidentialBuildingAI private static int GetAverageResidentRequirement(ushort buildingID, ref Building data, ImmaterialResourceManager.Resource resource) { CitizenManager instance = Singleton <CitizenManager> .instance; uint num = data.m_citizenUnits; int num2 = 0; int num3 = 0; int num4 = 0; while (num != 0) { uint nextUnit = instance.m_units.m_buffer[num].m_nextUnit; if ((instance.m_units.m_buffer[num].m_flags & CitizenUnit.Flags.Home) != 0) { int num5 = 0; int num6 = 0; for (int i = 0; i < 5; i++) { uint citizen = instance.m_units.m_buffer[num].GetCitizen(i); if (citizen != 0 && !instance.m_citizens.m_buffer[citizen].Dead) { num5 += GetResidentRequirement(resource, ref instance.m_citizens.m_buffer[citizen]); num6++; } } if (num6 == 0) { num3 += 100; num4++; } else { num3 += num5; num4 += num6; } } num = nextUnit; if (++num2 > 524288) { break; } } if (num4 != 0) { return((num3 + (num4 >> 1)) / num4); } return(0); }
public override void OnLevelLoaded(LoadMode mode) { // Only run on loaded games (existing saves). if (mode != LoadMode.LoadGame) { return; } base.OnLevelLoaded(mode); // Get CitizenManager instance. CitizenManager citizenManager = Singleton <CitizenManager> .instance; StringBuilder logMessage = new StringBuilder("Remove Sickness mod:\r\n"); // Iterate though each citizen. for (int i = 0; i < citizenManager.m_citizens.m_buffer.Length; i++) { // Use zero age as a quick filter for non-existing citizens. if (citizenManager.m_citizens.m_buffer[i].m_age > 0) { // Add citizen data to logging buffer. logMessage.Append("Removing sickness from citizen "); logMessage.Append(i); logMessage.Append(" (age "); logMessage.Append(citizenManager.m_citizens.m_buffer[i].m_age); logMessage.Append(") with health status: "); logMessage.Append(citizenManager.m_citizens.m_buffer[i].Sick ? "sick" : "healthy"); logMessage.Append(" and health "); logMessage.Append(citizenManager.m_citizens.m_buffer[i].m_health); logMessage.AppendLine("."); // Heal! citizenManager.m_citizens.m_buffer[i].Sick = false; // Also make sure general health level is at least 51 (ResidentAI.UpdateHealth() threshold for setting bad health). if (citizenManager.m_citizens.m_buffer[i].m_health < 51) { citizenManager.m_citizens.m_buffer[i].m_health = 51; citizenManager.m_citizens.m_buffer[i].BadHealth = 0; } } } // Log the buffer. Debug.Log(logMessage); }
private bool TryJoinVehicle(ushort instanceID, ref CitizenInstance citizenData, ushort vehicleID, ref Vehicle vehicleData) { if ((vehicleData.m_flags & Vehicle.Flags.Stopped) == Vehicle.Flags.None) { return(false); } CitizenManager instance = Singleton <CitizenManager> .instance; uint num = vehicleData.m_citizenUnits; int num2 = 0; while (num != 0u) { uint nextUnit = instance.m_units.m_buffer [(int)((UIntPtr)num)].m_nextUnit; for (int i = 0; i < 5; i++) { uint citizen = instance.m_units.m_buffer [(int)((UIntPtr)num)].GetCitizen(i); if (citizen != 0u) { ushort instance2 = instance.m_citizens.m_buffer [(int)((UIntPtr)citizen)].m_instance; if (instance2 != 0 && instance.m_instances.m_buffer [(int)instance2].m_targetBuilding == citizenData.m_targetBuilding) { instance.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetVehicle(citizenData.m_citizen, vehicleID, 0u); if (instance.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].m_vehicle == vehicleID) { if (citizenData.m_path != 0u) { Singleton <PathManager> .instance.ReleasePath(citizenData.m_path); citizenData.m_path = 0u; } return(true); } } break; } } num = nextUnit; if (++num2 > 524288) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } return(false); }
/// <summary> /// Logs a list of building info for debug use. /// </summary> /// <param name="serviceBuildings">The service buildings.</param> public static void DebugListLog(IEnumerable <ServiceBuildingInfo> serviceBuildings) { Building[] buildings = Singleton <BuildingManager> .instance.m_buildings.m_buffer; Vehicle[] vehicles = Singleton <VehicleManager> .instance.m_vehicles.m_buffer; DistrictManager districtManager = Singleton <DistrictManager> .instance; CitizenManager citizenManager = Singleton <CitizenManager> .instance; foreach (ServiceBuildingInfo building in serviceBuildings) { DebugListLog(buildings, vehicles, districtManager, citizenManager, building.BuildingId, building, null, null); } foreach (ServiceBuildingInfo building in serviceBuildings) { VehicleHelper.DebugListLog(building); } }
private void CreateAnimal(ushort buildingID, ref Building data) { CitizenManager instance1 = Singleton <CitizenManager> .instance; Randomizer r = new Randomizer((int)buildingID); CitizenInfo groupAnimalInfo = PrefabCollection <CitizenInfo> .FindLoaded("Dog");//instance1.GetGroupAnimalInfo(ref r, ItemClass.Service.Residential, ItemClass.SubService.ResidentialLow); ushort instance2; if (groupAnimalInfo == null || !instance1.CreateCitizenInstance(out instance2, ref Singleton <SimulationManager> .instance.m_randomizer, groupAnimalInfo, 0U)) { return; } PetAIDetour.isCaged = true; groupAnimalInfo.m_citizenAI.SetSource(instance2, ref instance1.m_instances.m_buffer[(int)instance2], buildingID); PetAIDetour.SetTarget((PetAI)groupAnimalInfo.m_citizenAI, instance2, ref instance1.m_instances.m_buffer[(int)instance2], buildingID); PetAIDetour.isCaged = false; }
public string CustomGetLocalizedStatus(ushort vehicleID, ref Vehicle data, out InstanceID target) { CitizenManager citizenManager = Singleton <CitizenManager> .instance; ushort driverInstanceId = GetDriverInstanceId(vehicleID, ref data); ushort targetBuildingId = 0; if (driverInstanceId != 0) { if ((data.m_flags & Vehicle.Flags.Parking) != (Vehicle.Flags) 0) { uint citizen = citizenManager.m_instances.m_buffer[(int)driverInstanceId].m_citizen; if (citizen != 0u && citizenManager.m_citizens.m_buffer[citizen].m_parkedVehicle != 0) { target = InstanceID.Empty; return(Locale.Get("VEHICLE_STATUS_PARKING")); } } targetBuildingId = citizenManager.m_instances.m_buffer[(int)driverInstanceId].m_targetBuilding; } if (targetBuildingId == 0) { target = InstanceID.Empty; return(Locale.Get("VEHICLE_STATUS_CONFUSED")); } bool flag = (Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)targetBuildingId].m_flags & Building.Flags.IncomingOutgoing) != Building.Flags.None; if (flag) { target = InstanceID.Empty; return(Locale.Get("VEHICLE_STATUS_LEAVING")); } target = InstanceID.Empty; target.Building = targetBuildingId; string ret = Locale.Get("VEHICLE_STATUS_GOINGTO"); // NON-STOCK CODE START if (Options.prohibitPocketCars) { ret = AdvancedParkingManager.Instance.EnrichLocalizedCarStatus(ret, ref ExtCitizenInstanceManager.Instance.ExtInstances[driverInstanceId]); } // NON-STOCK CODE END return(ret); }
/// <summary> /// Updates the CitizenUnits of already existing (placed/grown) building instances of the specified prefab, or all buildings of the specified service or subservice if prefab name is null. /// Called after updating a prefab's household/worker/visitor count, or when applying new default calculations, in order to apply changes to existing buildings. /// </summary> /// <param name="prefabName">The (raw BuildingInfo) name of the prefab (null to ignore name match)</param> /// <param name="service">The service to apply to (ignored if 'none')</param> /// <param name="subService">The subservice to apply to (ignored if 'none')</param> /// <param name="preserveOccupied">Set to true to preserve occupied residential households from removal, false otherwise</param> internal static void UpdateCitizenUnits(string prefabName, ItemClass.Service service, ItemClass.SubService subService, bool preserveOccupied) { // Local references. CitizenManager citizenManager = Singleton <CitizenManager> .instance; Building[] buildingBuffer = Singleton <BuildingManager> .instance?.m_buildings?.m_buffer; // Don't do anything if we couldn't get the building buffer or if we're not in-game. if (buildingBuffer == null || Singleton <ToolManager> .instance?.m_properties?.m_mode != ItemClass.Availability.Game) { return; } // Iterate through each building in the scene. for (ushort i = 0; i < buildingBuffer.Length; i++) { // Get current building instance. Building thisBuilding = buildingBuffer[i]; // Only interested in buildings with private AI. if (thisBuilding.Info?.GetAI() is PrivateBuildingAI privateAI) { // Residential building; check that either the supplier prefab name is null or it matches this building's prefab. if ((prefabName == null || thisBuilding.Info.name.Equals(prefabName)) && ((service != ItemClass.Service.None && thisBuilding.Info.GetService() == service) || (subService != ItemClass.SubService.None && thisBuilding.Info.GetSubService() == subService))) { // Got one! Recalculate home and visit counts. privateAI.CalculateWorkplaceCount((ItemClass.Level)thisBuilding.m_level, new Randomizer(i), thisBuilding.Width, thisBuilding.Length, out int level0, out int level1, out int level2, out int level3); int workCount = level0 + level1 + level2 + level3; int homeCount = privateAI.CalculateHomeCount((ItemClass.Level)thisBuilding.m_level, new Randomizer(i), thisBuilding.Width, thisBuilding.Length); int visitCount = privateAI.CalculateVisitplaceCount((ItemClass.Level)thisBuilding.m_level, new Randomizer(i), thisBuilding.Width, thisBuilding.Length); // Apply changes via call to EnsureCitizenUnits reverse patch. EnsureCitizenUnits(privateAI, i, ref thisBuilding, homeCount, workCount, visitCount, 0); // Remove any extra CitizenUunts. RemoveCitizenUnits(ref buildingBuffer[i], homeCount, workCount, visitCount, preserveOccupied); // Log changes. Logging.Message("Reset CitizenUnits for building ", i.ToString(), " (", thisBuilding.Info.name, "); CitizenUnit count is now ", citizenManager.m_unitCount.ToString()); } } } Logging.Message("CitizenUnit count is now ", citizenManager.m_unitCount.ToString()); }
/// <summary> /// Check if resident is confused. /// </summary> /// <param name="data">The citizen.</param> /// <returns>True if resident is confused.</returns> public static bool IsConfused(ref Citizen data) { // From ResidentAI.GetLocalizedStatus from original game code at version 1.7.0-f5. CitizenManager instance1 = Singleton <CitizenManager> .instance; ushort instance2 = data.m_instance; if ((int)instance2 != 0) { return(IsConfused(ref instance1.m_instances.m_buffer[(int)instance2])); } Citizen.Location currentLocation = data.CurrentLocation; ushort homeBuilding = data.m_homeBuilding; ushort workBuilding = data.m_workBuilding; ushort visitBuilding = data.m_visitBuilding; //bool flag = (data.m_flags & Citizen.Flags.Student) != Citizen.Flags.None; if (currentLocation != Citizen.Location.Home) { if (currentLocation != Citizen.Location.Work) { if (currentLocation == Citizen.Location.Visit && (int)visitBuilding != 0) { //target = InstanceID.Empty; //target.Building = visitBuilding; //return ColossalFramework.Globalization.Locale.Get("CITIZEN_STATUS_VISITING"); return(false); } } else if ((int)workBuilding != 0) { //target = InstanceID.Empty; //return ColossalFramework.Globalization.Locale.Get(!flag ? "CITIZEN_STATUS_AT_WORK" : "CITIZEN_STATUS_AT_SCHOOL"); return(false); } } else if ((int)homeBuilding != 0) { //target = InstanceID.Empty; //return ColossalFramework.Globalization.Locale.Get("CITIZEN_STATUS_AT_HOME"); return(false); } //target = InstanceID.Empty; //return ColossalFramework.Globalization.Locale.Get("CITIZEN_STATUS_CONFUSED"); return(true); }
public override void SetTarget(ushort instanceID, ref CitizenInstance data, ushort targetIndex, bool targetIsNode) { CitizenManager citizenManager = Singleton <CitizenManager> .instance; uint citizen = citizenManager.m_instances.m_buffer[instanceID].m_citizen; // the citizen, found in m_buffer[] ushort sourceBuilding = data.m_sourceBuilding; ushort[] ListOfOutsideConnections = Utils.GetOutsideConnections(); if (!targetIsNode) // skip if it's just a node { if (ListOfOutsideConnections.Contains(sourceBuilding)) // tourist is from outside connection { // replace the targetBuilding if needed, there is no offer here so use a hacky workaround if (Utils.TargetBuildingUndesired_Tourists(targetIndex)) { targetIndex = Utils.FindOffer(GetRandomTransferReason(0), true).Building; Debug.Log(string.Format("found and replaced offer with buildingID {0}", targetIndex)); } // increase tourism volume here by creating more tourists //after that use the vanilla method _SetSource() and _SetTarget() on those tourists // 2 ways of modifying if (DataStorage.instance.modifierType == TourismIncreaseType.Multiplier) { CreateMoreTourists_ByMultiplier(citizen, sourceBuilding); } //else //{ // // TODO: Do I really need it in here??! Probably create a Unity object and get this job done // CreateMoreTourists_ByPopulationSize(citizen, sourceBuilding, targetIndex, targetIsNode); //} } } try { _SetTarget(instanceID, ref data, targetIndex, targetIsNode); } catch (Exception e) { Debug.Log("overriden SetTarget() calling _SetTarget() caused an exception: " + e); } }
public static void UpdateLocation(ResidentAI resident, uint citizenID, ref Citizen data) { try { CitizenManager _citizenManager = Singleton <CitizenManager> .instance; if (data.m_homeBuilding == 0 && data.m_workBuilding == 0 && data.m_visitBuilding == 0 && data.m_instance == 0 && data.m_vehicle == 0) { _citizenManager.ReleaseCitizen(citizenID); } else { bool goodsSatisfied = false; switch (data.CurrentLocation) { case Citizen.Location.Home: goodsSatisfied = ResidentLocationHandler.ProcessHome(ref resident, citizenID, ref data); break; case Citizen.Location.Work: goodsSatisfied = ResidentLocationHandler.ProcessWork(ref resident, citizenID, ref data); break; case Citizen.Location.Visit: goodsSatisfied = ResidentLocationHandler.ProcessVisit(ref resident, citizenID, ref data); break; case Citizen.Location.Moving: goodsSatisfied = ResidentLocationHandler.ProcessMoving(ref resident, citizenID, ref data); break; } if (goodsSatisfied) { data.m_flags &= ~Citizen.Flags.NeedGoods; } } } catch (Exception ex) { Debug.LogWarning("Error on " + citizenID); Debug.LogException(ex); } }
//Manual Because Bugs //public GameObject PolutionAButton; //public GameObject ResourceAButton; // Use this for initialization void Start() { weatherManager = FindObjectOfType <WeatherManager>(); energyManager = FindObjectOfType <EnergyManager>(); townManager = FindObjectOfType <TownManager>(); polutionManger = FindObjectOfType <PolutionManager>(); citizenManager = FindObjectOfType <CitizenManager>(); introCanvas.enabled = true; startCanvas.enabled = false; baseGameCanvas.enabled = false; polutionPanel.SetActive(false); resourcePanel.SetActive(false); buttonPanel.SetActive(false); defaultPanel.SetActive(false); EndGamePanel.SetActive(false); }
public override Color GetColor(ushort instanceID, ref CitizenInstance data, InfoManager.InfoMode infoMode) { //begin mod if (!IsCagedAnimal(data) && !LivestockAIDetour.isFreeAnimal(data)) { if (infoMode == InfoManager.InfoMode.Transport) { ushort instanceID1 = data.m_targetBuilding; if ((int)instanceID1 != 0) { CitizenManager instance = Singleton <CitizenManager> .instance; return(instance.m_instances.m_buffer[(int)instanceID1].Info.m_citizenAI.GetColor(instanceID1, ref instance.m_instances.m_buffer[(int)instanceID1], infoMode)); } } } //end mod return(base.GetColor(instanceID, ref data, infoMode)); }
static int TakeExam(uint citizenIndex) { SimulationManager simulationManager = Singleton <SimulationManager> .instance; CitizenManager citizenManager = Singleton <CitizenManager> .instance; DistrictManager districtManager = Singleton <DistrictManager> .instance; BuildingManager buildingManager = Singleton <BuildingManager> .instance; Vector3 position = buildingManager.m_buildings.m_buffer[citizenManager.m_citizens.m_buffer[citizenIndex].m_homeBuilding].m_position; byte district = districtManager.GetDistrict(position); DistrictPolicies.Services servicePolicies = districtManager.m_districts.m_buffer[(int)district].m_servicePolicies; int grade = simulationManager.m_randomizer.Int32(100); if ((servicePolicies & DistrictPolicies.Services.EducationBoost) != 0) { grade += 20; } return(grade); }
public bool StartPathFind2(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays) { VehicleInfo info = this.m_info; ushort driverInstance = CustomPassengerCarAI.GetDriverInstance2(vehicleID, ref vehicleData); if (driverInstance == 0) { return(false); } CitizenManager instance = Singleton <CitizenManager> .instance; CitizenInfo info2 = instance.m_instances.m_buffer[(int)driverInstance].Info; NetInfo.LaneType laneTypes = NetInfo.LaneType.Vehicle | NetInfo.LaneType.Pedestrian; VehicleInfo.VehicleType vehicleType = this.m_info.m_vehicleType; bool allowUnderground = (vehicleData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None; PathUnit.Position startPosA; PathUnit.Position startPosB; float num; float num2; PathUnit.Position endPosA; if (PathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) && info2.m_citizenAI.FindPathPosition(driverInstance, ref instance.m_instances.m_buffer[(int)driverInstance], endPos, laneTypes, vehicleType, false, out endPosA)) { if (!startBothWays || num < 10f) { startPosB = default(PathUnit.Position); } PathUnit.Position endPosB = default(PathUnit.Position); SimulationManager instance2 = Singleton <SimulationManager> .instance; uint path; if (Singleton <CustomPathManager> .instance.CreatePath(out path, ref instance2.m_randomizer, instance2.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, laneTypes, vehicleType, 20000f, false, false, false, false, ItemClass.Service.None)) { if (vehicleData.m_path != 0u) { Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path); } vehicleData.m_path = path; vehicleData.m_flags |= Vehicle.Flags.WaitingPath; return(true); } } return(false); }
void Awake() { if (instance == null) { instance = this; } else if (instance != this) { Destroy(gameObject); } DontDestroyOnLoad(gameObject); waterParticle = Resources.Load <GameObject>("Particles/WaterSpray"); policeFireParticle = Resources.Load <GameObject>("Particles/PoliceFire"); mafiaFireParticle = Resources.Load <GameObject>("Particles/MafiaFire"); blockmanParticle = Resources.Load <GameObject>("Particles/BlockmanTrail"); allBodytypes = Resources.LoadAll <BodyType>("CitizenParts/Bodypart"); allEyes = Resources.LoadAll <Eyes>("CitizenParts/Bodypart"); allHair = Resources.LoadAll <Hair>("CitizenParts/Bodypart"); allPants = Resources.LoadAll <Pants>("CitizenParts/Clothes"); allShirts = Resources.LoadAll <Shirt>("CitizenParts/Clothes"); allShoes = Resources.LoadAll <Shoe>("CitizenParts/Clothes"); allJackets = Resources.LoadAll <Jacket>("CitizenParts/Clothes"); allSuits = Resources.LoadAll <Suit>("CitizenParts/Clothes"); allHats = Resources.LoadAll <HatAccessory>("CitizenParts/Accessories"); allGlasses = Resources.LoadAll <GlassesAccessory>("CitizenParts/Accessories"); allBodyAccessories = Resources.LoadAll <BodyAccessory>("CitizenParts/Accessories"); allFaceAccessories = Resources.LoadAll <FaceAccessory>("CitizenParts/Accessories"); allSpecials = Resources.LoadAll <Special>("CitizenParts/Special"); foreach (Special s in allSpecials) { if (s.type == Special.SpecialType.BonusCitizen) { allBonusCitizens.Add(s); } } }
/// <summary> /// Logs a list of building info for debug use. /// </summary> public static void DebugListLog() { try { Building[] buildings = Singleton <BuildingManager> .instance.m_buildings.m_buffer; Vehicle[] vehicles = Singleton <VehicleManager> .instance.m_vehicles.m_buffer; DistrictManager districtManager = Singleton <DistrictManager> .instance; CitizenManager citizenManager = Singleton <CitizenManager> .instance; for (ushort id = 0; id < buildings.Length; id++) { DebugListLog(buildings, vehicles, districtManager, citizenManager, id, null, null, null); } } catch (Exception ex) { Log.Error(typeof(BuildingHelper), "DebugListLog", ex); } }
public static bool Prefix(ref bool __result, // Harmony magic END ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position pathPos, uint nextPath, int nextPositionIndex, out byte segmentOffset) { CitizenManager citizenManager = Singleton <CitizenManager> .instance; uint maxUnitCount = citizenManager.m_units.m_size; uint driverCitizenId = 0u; ushort driverCitizenInstanceId = 0; ushort targetBuildingId = 0; // NON-STOCK CODE uint curCitizenUnitId = vehicleData.m_citizenUnits; int numIterations = 0; while (curCitizenUnitId != 0u && driverCitizenId == 0u) { ref CitizenUnit currentCitizenUnit = ref curCitizenUnitId.ToCitizenUnit(); for (int i = 0; i < 5; i++) { uint citizenId = currentCitizenUnit.GetCitizen(i); if (citizenId == 0u) { continue; } driverCitizenInstanceId = citizenId.ToCitizen().m_instance; if (driverCitizenInstanceId == 0) { continue; } // NON-STOCK CODE START ref CitizenInstance driverCitizenInstance = ref driverCitizenInstanceId.ToCitizenInstance(); driverCitizenId = driverCitizenInstance.m_citizen; targetBuildingId = driverCitizenInstance.m_targetBuilding; // NON-STOCK CODE END break; }
public void RemoveHouse(IntPoint2D tileLoc) { HouseManager house; if (houseCollection.TryGetValue(tileLoc, out house)) { int pop = house.GetPop(); homeless = homeless + pop; for (int i = 0; i < pop; i++) { GameObject citizen = walkerPool.GetCitizen(tileLoc, ScenarioMgr.Direction.Left); CitizenManager mgr = citizen.GetComponent("CitizenManager") as CitizenManager; mgr.SetUp(scenario, tileLoc, ScenarioMgr.Direction.Right, true, startTile, null, false); homelessCollection.Enqueue(mgr); } houseCollection.Remove(tileLoc); homelessInfoText.text = "Homeless: " + homeless; } }
private void ReleaseUnusedCitizenUnits() { Utils.Log((object)"Find and clear unused citizen units."); CitizenManager instance = Singleton <CitizenManager> .instance; int num = 0; for (int index = 0; index < instance.m_units.m_buffer.Length; ++index) { CitizenUnit citizenUnit = instance.m_units.m_buffer[index]; if (citizenUnit.m_flags != CitizenUnit.Flags.None && (int)citizenUnit.m_building == 0 && ((int)citizenUnit.m_vehicle == 0 && (int)citizenUnit.m_goods == 0)) { ++num; instance.m_units.m_buffer[index] = new CitizenUnit(); instance.m_units.ReleaseItem((uint)index); Utils.LogToTxt((object)string.Format("CitizenUnit #{0} - Flags: {1} - Citizens: #{2} | #{3} | #{4} | #{5} | #{6}", (object)index, (object)citizenUnit.m_flags, (object)citizenUnit.m_citizen0, (object)citizenUnit.m_citizen1, (object)citizenUnit.m_citizen2, (object)citizenUnit.m_citizen3, (object)citizenUnit.m_citizen4)); } } Utils.Log((object)("Cleared " + (object)num + " unused citizen units.")); }
private static bool IsBoardingDone(ushort vehicleID, ref Vehicle vehicleData) { CitizenManager instance1 = Singleton <CitizenManager> .instance; bool flag = false; ushort firstVehicle = vehicleData.GetFirstVehicle(vehicleID); if ((int)Singleton <VehicleManager> .instance.m_vehicles.m_buffer[(int)firstVehicle].m_waitCounter >= 60) { flag = true; } uint num1 = vehicleData.m_citizenUnits; int num2 = 0; while ((int)num1 != 0) { uint nextUnit = instance1.m_units.m_buffer[(int)num1].m_nextUnit; for (int index = 0; index < 5; ++index) { uint citizen = instance1.m_units.m_buffer[(int)num1].GetCitizen(index); if ((int)citizen != 0) { ushort instance2 = instance1.m_citizens.m_buffer[(int)citizen].m_instance; if ((int)instance2 != 0 && (instance1.m_instances.m_buffer[(int)instance2].m_flags & CitizenInstance.Flags.EnteringVehicle) != CitizenInstance.Flags.None) { if (!flag) { return(false); } BusAIMod.EnterVehicle(firstVehicle, instance2, ref instance1.m_instances.m_buffer[(int)instance2]); } } } num1 = nextUnit; if (++num2 > 524288) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace); break; } } return(true); }
/// <summary> /// Collects building info for debug use. /// </summary> /// <param name="buildings">The buildings.</param> /// <param name="vehicles">The vehicles.</param> /// <param name="districtManager">The district manager.</param> /// <param name="citizenManager">The citizen manager.</param> /// <param name="buildingId">The building identifier.</param> /// <param name="serviceBuilding">The service building.</param> /// <param name="targetBuilding">The target building.</param> /// <param name="buildingStamp">The building stamp.</param> /// <param name="verbose">If set to <c>true</c> include more information.</param> /// <returns>The debug information.</returns> private static Log.InfoList DebugInfoMsg( Building[] buildings, Vehicle[] vehicles, DistrictManager districtManager, CitizenManager citizenManager, ushort buildingId, ServiceBuildingInfo serviceBuilding, TargetBuildingInfo targetBuilding, BuildingStamp buildingStamp, bool verbose = false) { Log.InfoList info = new Log.InfoList(); if (buildingStamp != null) { info.Add("O", "BuildingStamp"); } if (serviceBuilding != null) { info.Add("O", "ServiceBuilding"); } if (targetBuilding != null) { info.Add("O", "TargetBuilding"); } List<TargetBuildingInfo> targetBuildings = null; List<ServiceBuildingInfo> serviceBuildings = null; if (verbose && Global.Buildings != null) { targetBuildings = new List<TargetBuildingInfo>(); serviceBuildings = new List<ServiceBuildingInfo>(); if (serviceBuilding == null) { if (Global.Buildings.GarbageBuildings == null || !Global.Buildings.GarbageBuildings.TryGetValue(buildingId, out serviceBuilding)) { serviceBuildings.Add(serviceBuilding); } if (Global.Buildings.DeathCareBuildings == null || !Global.Buildings.DeathCareBuildings.TryGetValue(buildingId, out serviceBuilding)) { serviceBuildings.Add(serviceBuilding); } if (Global.Buildings.HealthCareBuildings == null || !Global.Buildings.HealthCareBuildings.TryGetValue(buildingId, out serviceBuilding)) { serviceBuildings.Add(serviceBuilding); } } if (targetBuilding == null) { if (Global.Buildings.DeadPeopleBuildings == null || !Global.Buildings.DeadPeopleBuildings.TryGetValue(buildingId, out targetBuilding)) { targetBuildings.Add(targetBuilding); } if (Global.Buildings.DirtyBuildings == null || !Global.Buildings.DirtyBuildings.TryGetValue(buildingId, out targetBuilding)) { targetBuildings.Add(targetBuilding); } if (Global.Buildings.SickPeopleBuildings == null || !Global.Buildings.SickPeopleBuildings.TryGetValue(buildingId, out targetBuilding)) { targetBuildings.Add(targetBuilding); } } } info.Add("BuildingId", buildingId); info.Add("AI", buildings[buildingId].Info.m_buildingAI.GetType()); info.Add("InfoName", buildings[buildingId].Info.name); string name = GetBuildingName(buildingId); if (!String.IsNullOrEmpty(name) && name != buildings[buildingId].Info.name) { info.Add("BuildingName", name); } byte district = districtManager.GetDistrict(buildings[buildingId].m_position); info.Add("District", district); info.Add("DistrictName", districtManager.GetDistrictName(district)); if (buildingStamp != null) { info.Add("Source", buildingStamp.Source); info.Add("SimulationTimeStamp", buildingStamp.SimulationTimeStamp); info.Add("SimulationTimeDelta", buildingStamp.SimulationTimeDelta); } if (serviceBuilding != null) { info.Add("CanReceive", serviceBuilding.CanReceive); info.Add("CapacityLevel", serviceBuilding.CapacityLevel); info.Add("CapactyFree", serviceBuilding.CapacityFree); info.Add("CapactyMax", serviceBuilding.CapacityMax); info.Add("CapactyOverflow", serviceBuilding.CapacityOverflow); info.Add("Range", serviceBuilding.Range); info.Add("VehiclesFree", serviceBuilding.VehiclesFree); info.Add("VehiclesSpare", serviceBuilding.VehiclesSpare); info.Add("VehiclesMade", serviceBuilding.VehiclesMade); info.Add("VehiclesTotal", serviceBuilding.VehiclesTotal); } if (serviceBuildings != null) { for (int i = 0; i < serviceBuildings.Count; i++) { serviceBuilding = serviceBuildings[i]; string n = (i + 1).ToString(); info.Add("CanReceive" + n, serviceBuilding.CanReceive); info.Add("CapacityLevel" + n, serviceBuilding.CapacityLevel); info.Add("CapactyFree" + n, serviceBuilding.CapacityFree); info.Add("CapactyMax" + n, serviceBuilding.CapacityMax); info.Add("CapactyOverflow" + n, serviceBuilding.CapacityOverflow); info.Add("Range" + n, serviceBuilding.Range); info.Add("VehiclesFree" + n, serviceBuilding.VehiclesFree); info.Add("VehiclesSpare" + n, serviceBuilding.VehiclesSpare); info.Add("VehiclesMade" + n, serviceBuilding.VehiclesMade); info.Add("VehiclesTotal" + n, serviceBuilding.VehiclesTotal); } } if (targetBuilding != null) { info.Add("Demand", targetBuilding.Demand); info.Add("HasProblem", targetBuilding.HasProblem); info.Add("ProblemSize", targetBuilding.ProblemSize); info.Add("ProblemValue", targetBuilding.ProblemValue); } if (targetBuildings != null) { for (int i = 0; i < targetBuildings.Count; i++) { targetBuilding = targetBuildings[i]; string n = (i + 1).ToString(); info.Add("Demand" + n, targetBuilding.Demand); info.Add("HasProblem" + n, targetBuilding.HasProblem); info.Add("ProblemSize" + n, targetBuilding.ProblemSize); info.Add("ProblemValue" + n, targetBuilding.ProblemValue); } } if (verbose && Global.Buildings != null) { Double desolate; if (Global.Buildings.DesolateBuildings != null && Global.Buildings.DesolateBuildings.TryGetValue(buildingId, out desolate)) { info.Add("Desolate", desolate); } } int materialMax = 0; int materialAmount = 0; int serviceVehicleCount = 0; if (buildings[buildingId].Info.m_buildingAI is CemeteryAI) { serviceVehicleCount = ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_hearseCount; info.Add("CorpseCapacity", ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_corpseCapacity); info.Add("GraveCount", ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_graveCount); info.Add("CustomBuffer1", buildings[buildingId].m_customBuffer1); // GraveCapacity? info.Add("CustomBuffer2", buildings[buildingId].m_customBuffer2); info.Add("PR_HC_Calc", ((buildings[buildingId].m_productionRate * ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_hearseCount) + 99) / 100); // Hearse capacity? buildings[buildingId].Info.m_buildingAI.GetMaterialAmount(buildingId, ref buildings[buildingId], TransferManager.TransferReason.Dead, out materialAmount, out materialMax); } else if (buildings[buildingId].Info.m_buildingAI is LandfillSiteAI) { serviceVehicleCount = ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).m_garbageTruckCount; buildings[buildingId].Info.m_buildingAI.GetMaterialAmount(buildingId, ref buildings[buildingId], TransferManager.TransferReason.Garbage, out materialAmount, out materialMax); } else if (buildings[buildingId].Info.m_buildingAI is HospitalAI) { serviceVehicleCount = ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_ambulanceCount; info.Add("", ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_patientCapacity); buildings[buildingId].Info.m_buildingAI.GetMaterialAmount(buildingId, ref buildings[buildingId], TransferManager.TransferReason.Sick, out materialAmount, out materialMax); } info.Add("materialMax", materialMax); info.Add("materialAmount", materialAmount); info.Add("materialFree", materialMax - materialAmount); int productionRate = buildings[buildingId].m_productionRate; ushort ownVehicleCount = 0; ushort madeVehicleCount = 0; ushort vehicleId = buildings[buildingId].m_ownVehicles; while (vehicleId != 0 && ownVehicleCount < ushort.MaxValue) { ownVehicleCount++; if ((vehicles[vehicleId].m_transferType == (byte)TransferManager.TransferReason.Garbage || vehicles[vehicleId].m_transferType == (byte)TransferManager.TransferReason.Dead) && vehicles[vehicleId].Info != null && (vehicles[vehicleId].m_flags & Vehicle.Flags.Created) == Vehicle.Flags.Created && (vehicles[vehicleId].m_flags & VehicleHelper.VehicleExists) != ~Vehicle.Flags.All) { madeVehicleCount++; } vehicleId = vehicles[vehicleId].m_nextOwnVehicle; } info.Add("OwnVehicles", ownVehicleCount); info.Add("MadeVehicles", madeVehicleCount); info.Add("VehicleCount", serviceVehicleCount); info.Add("ProductionRate", productionRate); info.Add("VehicleCountNominal", ((productionRate * serviceVehicleCount) + 99) / 100); int budget = Singleton<EconomyManager>.instance.GetBudget(buildings[buildingId].Info.m_buildingAI.m_info.m_class); productionRate = PlayerBuildingAI.GetProductionRate(100, budget); int actualVehicleCount = ((productionRate * serviceVehicleCount) + 99) / 100; info.Add("Budget", budget); info.Add("ProductionRateActual", productionRate); info.Add("VehicleCountActual", actualVehicleCount); info.Add("SpareVehicles", actualVehicleCount - ownVehicleCount); float range = buildings[buildingId].Info.m_buildingAI.GetCurrentRange(buildingId, ref buildings[buildingId]); range = range * range * Global.Settings.RangeModifier; if (range < Global.Settings.RangeMinimum) { info.Add("Range", range, Global.Settings.RangeMinimum); } else if (range > Global.Settings.RangeMaximum) { info.Add("Range", range, Global.Settings.RangeMaximum); } else { info.Add("Range", range); } List<string> needs = new List<string>(); if (buildings[buildingId].m_garbageBuffer >= Global.Settings.Garbage.MinimumAmountForDispatch) { needs.Add("Filthy"); } if (buildings[buildingId].m_garbageBuffer >= Global.Settings.Garbage.MinimumAmountForPatrol) { needs.Add("Dirty"); } else if (buildings[buildingId].m_garbageBuffer > 0) { needs.Add("Dusty"); } if (buildings[buildingId].m_deathProblemTimer > 0) { needs.Add("Dead"); } if (buildings[buildingId].m_garbageBuffer * Dispatcher.ProblemBufferModifier >= Dispatcher.ProblemLimitForgotten || buildings[buildingId].m_deathProblemTimer * Dispatcher.ProblemTimerModifier >= Dispatcher.ProblemLimitForgotten) { needs.Add("Forgotten"); } info.Add("Needs", needs); info.Add("DeathProblemTimer", buildings[buildingId].m_deathProblemTimer); info.Add("HealthProblemTimer", buildings[buildingId].m_healthProblemTimer); info.Add("MajorProblemTimer", buildings[buildingId].m_majorProblemTimer); int citizens = 0; int count = 0; uint unitId = buildings[buildingId].m_citizenUnits; while (unitId != 0) { CitizenUnit unit = citizenManager.m_units.m_buffer[unitId]; for (int i = 0; i < 5; i++) { uint citizenId = unit.GetCitizen(i); if (citizenId != 0) { Citizen citizen = citizenManager.m_citizens.m_buffer[citizenId]; if (citizen.Dead && citizen.GetBuildingByLocation() == buildingId) { citizens++; } } } count++; if (count > (int)ushort.MaxValue * 10) { break; } unitId = unit.m_nextUnit; } info.Add("DeadCitizens", citizens); info.Add("GarbageAmount", buildings[buildingId].Info.m_buildingAI.GetGarbageAmount(buildingId, ref buildings[buildingId])); info.Add("GarbageBuffer", buildings[buildingId].m_garbageBuffer); string problems = buildings[buildingId].m_problems.ToString(); if (problems.IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }) >= 0) { foreach (Notification.Problem problem in Enum.GetValues(typeof(Notification.Problem))) { if (problem != Notification.Problem.None && (buildings[buildingId].m_problems & problem) == problem) { problems += ", " + problem.ToString(); } } } info.Add("Problems", problems); string flags = buildings[buildingId].m_flags.ToString(); if (flags.IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }) >= 0) { foreach (Building.Flags flag in Enum.GetValues(typeof(Building.Flags))) { if (flag != Building.Flags.None && (buildings[buildingId].m_flags & flag) == flag) { flags += ", " + flag.ToString(); } } } info.Add("Flags", flags); string status = buildings[buildingId].Info.m_buildingAI.GetLocalizedStatus(buildingId, ref buildings[buildingId]); if (!String.IsNullOrEmpty(status)) { info.Add("Status", status); } info.Add("AI", buildings[buildingId].Info.m_buildingAI.GetType().AssemblyQualifiedName); return info; }
/// <summary> /// Check the household numbers /// </summary> /// <param name="buildings"></param> /// <param name="citizens"></param> /// <param name="i"></param> private void checkResidentialHouseholds(BuildingManager buildings, CitizenManager citizens, int i) { Building building = buildings.m_buildings.m_buffer[i]; BuildingInfo info = building.Info; int width = building.Width; int length = building.Length; if ((info != null) && (info.m_buildingAI is ResidentialBuildingAI)) { int modHomeCount = ((ResidentialBuildingAI)info.m_buildingAI).CalculateHomeCount(new ColossalFramework.Math.Randomizer(i), width, length); // If the modded home count is meant to be less than the original if (modHomeCount < Game_ResidentialAI.CalculateHomeCount(new ColossalFramework.Math.Randomizer(i), width, length, info.m_class.m_subService, info.m_class.m_level)) { int houseHoldCount = 0; uint citizenIndex = building.m_citizenUnits; while (houseHoldCount < modHomeCount) // Fast forward { citizenIndex = citizens.m_units.m_buffer[(int)((UIntPtr)citizenIndex)].m_nextUnit; houseHoldCount++; } // Disconnect the rest while (citizenIndex != 0u) { CitizenUnit c = citizens.m_units.m_buffer[(int)((UIntPtr)citizenIndex)]; citizens.ReleaseUnits(citizenIndex); citizenIndex = c.m_nextUnit; // Reset the flags which could make the game think this group has connections to a home c.m_nextUnit = 0u; c.m_building = 0; c.m_flags = CitizenUnit.Flags.None; } } } }
/* * Handles creation and removal of animals * * Note: Just because a animal has been removed visually, it does not mean * it is removed as far as the game is concerned. The animal is only truly removed * when the frame covers the animal's id, and that's when we will remove the * animal from our records. */ public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) { if (_terminated) return; if (!_helper.AnimalMonitorSpinnable) return; if (!_settings.Enable._AnimalMonitor) return; try { if (!_initialized) { _data = Data.Instance; _mapping = new AnimalPrefabMapping(); _buildingsAnimals = new Dictionary<ushort, HashSet<ushort>>(); _paused = false; _instance = Singleton<CitizenManager>.instance; _capacity = _instance.m_instances.m_buffer.Length; _id = (ushort)_capacity; for (int i = 0; i < _capacity; i++) UpdateAnimal((ushort)i); _initialized = true; _helper.AnimalMonitorSpun = true; _helper.AnimalMonitor = this; _helper.NotifyPlayer("Animal monitor initialized"); } else if (_data.BuildingsUpdated.Length > 0) { _data._AnimalsUpdated.Clear(); _data._AnimalsRemoved.Clear(); foreach (ushort building in _data._BuildingsUpdated) { ushort id = Singleton<BuildingManager>.instance.m_buildings.m_buffer[building].m_targetCitizens; while (id != 0) { if (UpdateAnimal(id)) { _data._AnimalsUpdated.Add(id); AddBuildingsAnimal(building, id); } else { _data._AnimalsRemoved.Add(id); if (_data._Animals.Contains(id)) RemoveAnimal(id); } id = _instance.m_instances.m_buffer[(int)id].m_nextTargetInstance; } CheckBuildingsAnimals(building); } foreach (ushort building in _data._BuildingsRemoved) RemoveBuildingsAnimals(building); } OutputDebugLog(); } catch (Exception e) { string error = "Animal monitor failed to initialize\r\n"; error += String.Format("Error: {0}\r\n", e.Message); error += "\r\n"; error += "==== STACK TRACE ====\r\n"; error += e.StackTrace; _helper.Log(error); _terminated = true; } base.OnUpdate(realTimeDelta, simulationTimeDelta); }
/* * Handles creation and removal of humans * * Note: Just because a human has been removed visually, it does not mean * it is removed as far as the game is concerned. The human is only truly removed * when the frame covers the human's id, and that's when we will remove the * human from our records. */ public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) { if (_terminated) return; if (!_helper.HumanMonitorSpinnable) return; if (!_settings.Enable._HumanMonitor) return; try { if (!_initialized) { _data = Data.Instance; _mapping = new HumanPrefabMapping(); _paused = false; _instance = Singleton<CitizenManager>.instance; _capacity = _instance.m_citizens.m_buffer.Length; _id = (uint)_capacity; for (int i = 0; i < _capacity; i++) UpdateHuman((uint)i); _lastProcessedFrame = GetFrame(); _initialized = true; _helper.HumanMonitorSpun = true; _helper.HumanMonitor = this; _helper.NotifyPlayer("Human monitor initialized"); } else if (!SimulationManager.instance.SimulationPaused) { _data._HumansUpdated.Clear(); _data._HumansRemoved.Clear(); int end = GetFrame(); while (_lastProcessedFrame != end) { _lastProcessedFrame = GetFrame(_lastProcessedFrame + 1); int[] boundaries = GetFrameBoundaries(); uint id; for (int i = boundaries[0]; i <= boundaries[1]; i++) { id = (uint)i; if (UpdateHuman(id)) _data._HumansUpdated.Add(id); else if (_data._Humans.Contains(id)) { _data._HumansRemoved.Add(id); RemoveHuman(id); } } } } OutputDebugLog(); } catch (Exception e) { string error = "Human monitor failed to initialize\r\n"; error += String.Format("Error: {0}\r\n", e.Message); error += "\r\n"; error += "==== STACK TRACE ====\r\n"; error += e.StackTrace; _helper.Log(error); _terminated = true; } base.OnUpdate(realTimeDelta, simulationTimeDelta); }