/// <summary> /// Adds the target building information to debug information message. /// </summary> /// <param name="info">The information.</param> /// <param name="targetBuilding">The target building.</param> /// <param name="tagSuffix">The tag suffix.</param> private static void AddTargetBuildingInfoToDebugInfoMsg(Log.InfoList info, TargetBuildingInfo targetBuilding, string tagSuffix) { if (targetBuilding != null) { info.Add("Demand" + tagSuffix, targetBuilding.Demand); info.Add("HasProblem" + tagSuffix, targetBuilding.HasProblem); info.Add("ProblemSize" + tagSuffix, targetBuilding.ProblemSize); info.Add("ProblemValue" + tagSuffix, targetBuilding.ProblemValue); info.Add("ProblemWeight" + tagSuffix, targetBuilding.ProblemWeight); info.Add("ServiceProblemCount" + tagSuffix, targetBuilding.ServiceProblemCount); info.Add("ServiceProblemSize" + tagSuffix, targetBuilding.ServiceProblemSize); } }
/// <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()); } }
/// <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(); info.Add("BuildingId", buildingId); if (buildingStamp != null) { info.Add("O", "BuildingStamp"); } if (serviceBuilding != null) { info.Add("O", "ServiceBuilding"); } if (targetBuilding != null) { info.Add("O", "TargetBuilding"); } List <KeyValuePair <string, TargetBuildingInfo> > targetBuildings = null; List <KeyValuePair <string, ServiceBuildingInfo> > serviceBuildings = null; if (verbose && Global.Buildings != null) { //if (serviceBuilding == null) //{ // serviceBuilding = Global.Buildings.GetServiceBuilding(buildingId); //} //if (targetBuilding == null) //{ // targetBuilding = Global.Buildings.GetTargetBuilding(buildingId); //} targetBuildings = new List <KeyValuePair <string, TargetBuildingInfo> >(); serviceBuildings = new List <KeyValuePair <string, ServiceBuildingInfo> >(); if (serviceBuilding == null) { if (Global.Buildings.Garbage.ServiceBuildings != null && Global.Buildings.Garbage.ServiceBuildings.TryGetValue(buildingId, out serviceBuilding)) { serviceBuildings.Add(new KeyValuePair <string, ServiceBuildingInfo>("GB", serviceBuilding)); } if (Global.Buildings.DeathCare.ServiceBuildings != null && Global.Buildings.DeathCare.ServiceBuildings.TryGetValue(buildingId, out serviceBuilding)) { serviceBuildings.Add(new KeyValuePair <string, ServiceBuildingInfo>("DCB", serviceBuilding)); } if (Global.Buildings.HealthCare.ServiceBuildings != null && Global.Buildings.HealthCare.ServiceBuildings.TryGetValue(buildingId, out serviceBuilding)) { serviceBuildings.Add(new KeyValuePair <string, ServiceBuildingInfo>("HCB", serviceBuilding)); } serviceBuilding = null; } if (targetBuilding == null) { if (Global.Buildings.DeathCare.TargetBuildings != null && Global.Buildings.DeathCare.TargetBuildings.TryGetValue(buildingId, out targetBuilding)) { targetBuildings.Add(new KeyValuePair <string, TargetBuildingInfo>("DPB", targetBuilding)); } if (Global.Buildings.Garbage.TargetBuildings != null && Global.Buildings.Garbage.TargetBuildings.TryGetValue(buildingId, out targetBuilding)) { targetBuildings.Add(new KeyValuePair <string, TargetBuildingInfo>("DB", targetBuilding)); } if (Global.Buildings.HealthCare.TargetBuildings != null && Global.Buildings.HealthCare.TargetBuildings.TryGetValue(buildingId, out targetBuilding)) { targetBuildings.Add(new KeyValuePair <string, TargetBuildingInfo>("SPB", targetBuilding)); } targetBuilding = null; } } try { 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); } } catch { info.Add("Error", "Info"); } try { byte district = districtManager.GetDistrict(buildings[buildingId].m_position); info.Add("District", district); info.Add("DistrictName", districtManager.GetDistrictName(district)); } catch (Exception ex) { info.Add("Exception", "District", ex.GetType().ToString(), ex.Message); } if (buildingStamp != null) { info.Add("Source", buildingStamp.Source); info.Add("SimulationTimeStamp", buildingStamp.SimulationTimeStamp); info.Add("SimulationTimeDelta", buildingStamp.SimulationTimeDelta); } AddServiceBuildingInfoToDebugInfoMsg(info, buildings, serviceBuilding, "B"); if (serviceBuildings != null) { foreach (KeyValuePair <string, ServiceBuildingInfo> building in serviceBuildings) { AddServiceBuildingInfoToDebugInfoMsg(info, buildings, building.Value, building.Key); } } AddTargetBuildingInfoToDebugInfoMsg(info, targetBuilding, "B"); if (targetBuildings != null) { foreach (KeyValuePair <string, TargetBuildingInfo> building in targetBuildings) { AddTargetBuildingInfoToDebugInfoMsg(info, building.Value, building.Key); } } if (verbose && Global.Buildings != null) { info.Add("Categories", Global.Buildings.GetCategories(buildingId)); } float radius = float.NaN; int materialMax = 0; int materialAmount = 0; int serviceVehicleCount = 0; try { if (GetCapacityAmount(buildingId, ref buildings[buildingId], out materialAmount, out materialMax, out serviceVehicleCount)) { info.Add("CapacityAmount", materialAmount); info.Add("CapacityMax", materialMax); info.Add("ServiceVehicleCount", serviceVehicleCount); } serviceVehicleCount = 0; if (buildings[buildingId].Info.m_buildingAI is CemeteryAI) { radius = ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_deathCareRadius; info.Add("DeathCareRadius", ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_deathCareRadius); 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); // GraveUsed? 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? info.Add("IsFull", buildings[buildingId].Info.m_buildingAI.IsFull(buildingId, ref buildings[buildingId])); 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) { radius = ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).m_collectRadius; info.Add("CollectRadius", ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).m_collectRadius); info.Add("GarbageAmount", ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).GetGarbageAmount(buildingId, ref buildings[buildingId])); info.Add("GarbageCapacity", ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).m_garbageCapacity); info.Add("GarbageBuffer", buildings[buildingId].m_garbageBuffer); info.Add("CustomBuffer1", buildings[buildingId].m_customBuffer1); // Garbage? info.Add("IsFull", buildings[buildingId].Info.m_buildingAI.IsFull(buildingId, ref buildings[buildingId])); 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) { radius = ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_healthCareRadius; info.Add("HealthCareRadius", ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_healthCareRadius); info.Add("PatientCapacity", ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_patientCapacity); info.Add("IsFull", buildings[buildingId].Info.m_buildingAI.IsFull(buildingId, ref buildings[buildingId])); 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); } catch { info.Add("Error", "Material"); } ushort ownVehicleCount = 0; ushort madeVehicleCount = 0; try { ushort vehicleId = buildings[buildingId].m_ownVehicles; while (vehicleId != 0 && ownVehicleCount < ushort.MaxValue) { ownVehicleCount++; try { 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) != ~VehicleHelper.VehicleAll) { madeVehicleCount++; } } catch { info.Add("Error", "Vehicle"); } vehicleId = vehicles[vehicleId].m_nextOwnVehicle; } info.Add("OwnVehicles", ownVehicleCount); info.Add("MadeVehicles", madeVehicleCount); } catch { info.Add("Error", "Vehicles"); } int productionRate = buildings[buildingId].m_productionRate; info.Add("VehicleCount", serviceVehicleCount); info.Add("ProductionRate", productionRate); info.Add("VehicleCountNominal", ((productionRate * serviceVehicleCount) + 99) / 100); try { int budget = Singleton <EconomyManager> .instance.GetBudget(buildings[buildingId].Info.m_buildingAI.m_info.m_class); productionRate = PlayerBuildingAI.GetProductionRate(productionRate, budget); int productionRate100 = PlayerBuildingAI.GetProductionRate(100, budget); int actualVehicleCount = ((productionRate * serviceVehicleCount) + 99) / 100; int actualVehicleCount100 = ((productionRate100 * serviceVehicleCount) + 99) / 100; if (!float.IsNaN(radius)) { info.Add("Radius", radius); } info.Add("Budget", budget); info.Add("ProductionRateActual", productionRate, productionRate100); info.Add("VehicleCountActual", actualVehicleCount, actualVehicleCount100); info.Add("SpareVehicles", actualVehicleCount - ownVehicleCount, actualVehicleCount100 - ownVehicleCount); if (!float.IsNaN(radius)) { info.Add("ProductionRange", (double)productionRate * (double)radius * 0.00999999977648258); } } catch { info.Add("Error", "Budget"); } try { 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, ">=<"); } } catch { info.Add("Error", "Range"); } try { List <string> needs = new List <string>(); if (buildings[buildingId].m_garbageBuffer >= Global.Settings.Garbage.MinimumAmountForDispatch) { needs.Add("Filthy"); } else 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); } catch { info.Add("Error", "Needs"); } info.Add("DeathProblemTimer", buildings[buildingId].m_deathProblemTimer); info.Add("HealthProblemTimer", buildings[buildingId].m_healthProblemTimer); info.Add("MajorProblemTimer", buildings[buildingId].m_majorProblemTimer); try { int citizens = 0; int count = 0; uint unitId = buildings[buildingId].m_citizenUnits; while (unitId != 0) { CitizenUnit unit = citizenManager.m_units.m_buffer[unitId]; try { 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++; } } } } catch { info.Add("Error", "Citizen"); } count++; if (count > (int)ushort.MaxValue * 10) { break; } unitId = unit.m_nextUnit; } info.Add("DeadCitizens", citizens); } catch { info.Add("Error", "Citizens"); } try { info.Add("GarbageAmount", buildings[buildingId].Info.m_buildingAI.GetGarbageAmount(buildingId, ref buildings[buildingId])); info.Add("GarbageBuffer", buildings[buildingId].m_garbageBuffer); } catch { info.Add("Error", "Garbage"); } try { 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); } catch { info.Add("Error", "Problems"); } info.Add("FireIntensoty", buildings[buildingId].m_fireIntensity); try { 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); } catch { info.Add("Error", "Flags"); } try { string status = buildings[buildingId].Info.m_buildingAI.GetLocalizedStatus(buildingId, ref buildings[buildingId]); if (!String.IsNullOrEmpty(status)) { info.Add("Status", status); } } catch { info.Add("Error", "Status"); } try { info.Add("AI", buildings[buildingId].Info.m_buildingAI.GetType().AssemblyQualifiedName); } catch { info.Add("Error", "AI"); } return(info); }