private static List<string> GetDistrictsForLine(TransportLine transportLine, NetManager theNetworkManager, DistrictManager theDistrictManager, out int stopCount) { var stop = TransportLine.GetPrevStop(transportLine.m_stops); var firstStop = stop; stopCount = 0; var districts = new List<string>(); while (stop != 0) { stopCount++; var position = theNetworkManager.m_nodes.m_buffer[stop].m_position; var district = theDistrictManager.GetDistrict(position); if (district != 0) { var districtName = theDistrictManager.GetDistrictName(district); districtName = districtName.Trim(); if (districts.Contains(districtName) == false) districts.Add(districtName); } else { if (districts.Contains(string.Empty) == false) districts.Add(string.Empty); } stop = TransportLine.GetNextStop(stop); if (stop == firstStop) break; } return districts; }
public override void SimulationStep(ushort buildingID, ref Building buildingData, ref Building.Frame frameData) { base.SimulationStep(buildingID, ref buildingData, ref frameData); if (Singleton <SimulationManager> .instance.m_randomizer.Int32(10U) == 0) { DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(buildingData.m_position); ushort num = instance.m_districts.m_buffer[(int)district].m_Style; if ((int)num > 0 && (int)num - 1 < instance.m_Styles.Length) { DistrictStyle districtStyle = instance.m_Styles[(int)num - 1]; if (districtStyle != null && (UnityEngine.Object) this.m_info.m_class != (UnityEngine.Object)null && (districtStyle.AffectsService(this.m_info.GetService(), this.m_info.GetSubService(), this.m_info.m_class.m_level) && !districtStyle.Contains(this.m_info)) && (int)Singleton <ZoneManager> .instance.m_lastBuildIndex == (int)Singleton <SimulationManager> .instance.m_currentBuildIndex) { buildingData.m_flags |= Building.Flags.Demolishing; ++Singleton <SimulationManager> .instance.m_currentBuildIndex; } } } if ((buildingData.m_flags & Building.Flags.ZonesUpdated) != Building.Flags.None) { SimulationManager instance = Singleton <SimulationManager> .instance; if ((int)buildingData.m_fireIntensity != 0 || instance.m_randomizer.Int32(10U) != 0 || (int)Singleton <ZoneManager> .instance.m_lastBuildIndex != (int)instance.m_currentBuildIndex) { return; } buildingData.m_flags &= ~Building.Flags.ZonesUpdated; if (buildingData.CheckZoning(this.m_info.m_class.GetZone(), this.m_info.m_class.GetSecondaryZone())) { return; } buildingData.m_flags |= Building.Flags.Demolishing; PrivateBuildingAIDetour.CheckNearbyBuildingZones(buildingData.m_position); ++instance.m_currentBuildIndex; } else { if ((buildingData.m_flags & (Building.Flags.Abandoned | Building.Flags.Downgrading)) == Building.Flags.None || (int)buildingData.m_majorProblemTimer != (int)byte.MaxValue && (buildingData.m_flags & Building.Flags.Abandoned) != Building.Flags.None) { return; } SimulationManager instance1 = Singleton <SimulationManager> .instance; ZoneManager instance2 = Singleton <ZoneManager> .instance; int num1; switch (this.m_info.m_class.m_service) { case ItemClass.Service.Residential: num1 = instance2.m_actualResidentialDemand; break; case ItemClass.Service.Commercial: num1 = instance2.m_actualCommercialDemand; break; case ItemClass.Service.Industrial: num1 = instance2.m_actualWorkplaceDemand; break; case ItemClass.Service.Office: num1 = instance2.m_actualWorkplaceDemand; break; default: num1 = 0; break; } if (instance1.m_randomizer.Int32(100U) >= num1 || (int)instance2.m_lastBuildIndex != (int)instance1.m_currentBuildIndex || (double)Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(buildingData.m_position)) > (double)buildingData.m_position.y) { return; } ItemClass.SubService subService = this.m_info.m_class.m_subService; ItemClass.Level level = ItemClass.Level.Level1; int width = buildingData.Width; int num2 = buildingData.Length; if (this.m_info.m_class.m_service == ItemClass.Service.Industrial) { ZoneBlock.GetIndustryType(buildingData.m_position, out subService, out level); } else if (this.m_info.m_class.m_service == ItemClass.Service.Commercial) { ZoneBlock.GetCommercialType(buildingData.m_position, this.m_info.m_class.GetZone(), width, num2, out subService, out level); } DistrictManager instance3 = Singleton <DistrictManager> .instance; byte district = instance3.GetDistrict(buildingData.m_position); ushort num3 = instance3.m_districts.m_buffer[(int)district].m_Style; BuildingInfo randomBuildingInfo = Singleton <BuildingManager> .instance.GetRandomBuildingInfo(ref Singleton <SimulationManager> .instance.m_randomizer, this.m_info.m_class.m_service, subService, level, width, num2, this.m_info.m_zoningMode, (int)num3); if (randomBuildingInfo == null) { return; } buildingData.m_flags |= Building.Flags.Demolishing; float num4 = buildingData.m_angle + 1.570796f; float num5; if (this.m_info.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft && randomBuildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerRight) { num5 = num4 - 1.570796f; num2 = width; } else if (this.m_info.m_zoningMode == BuildingInfo.ZoningMode.CornerRight && randomBuildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft) { num5 = num4 + 1.570796f; num2 = width; } ushort building; if (Singleton <BuildingManager> .instance.CreateBuilding(out building, ref Singleton <SimulationManager> .instance.m_randomizer, randomBuildingInfo, buildingData.m_position, buildingData.m_angle, num2, Singleton <SimulationManager> .instance.m_currentBuildIndex)) { ++Singleton <SimulationManager> .instance.m_currentBuildIndex; switch (this.m_info.m_class.m_service) { case ItemClass.Service.Residential: instance2.m_actualResidentialDemand = Mathf.Max(0, instance2.m_actualResidentialDemand - 5); break; case ItemClass.Service.Commercial: instance2.m_actualCommercialDemand = Mathf.Max(0, instance2.m_actualCommercialDemand - 5); break; case ItemClass.Service.Industrial: instance2.m_actualWorkplaceDemand = Mathf.Max(0, instance2.m_actualWorkplaceDemand - 5); break; case ItemClass.Service.Office: instance2.m_actualWorkplaceDemand = Mathf.Max(0, instance2.m_actualWorkplaceDemand - 5); break; } } ++instance1.m_currentBuildIndex; } }
/// <summary> /// Eventual handler of all service requests /// </summary> private static bool IsTransferAllowed(Vector3 source, Vector3 destination, ushort buildingID, ushort destBuildingID, TransferManager.TransferReason reason, bool isResidentTransfer) { ServiceBuildingOptions opts = ServiceBuildingOptions.GetInstance(); DistrictManager districtManager = Singleton <DistrictManager> .instance; byte srcDistrict = districtManager.GetDistrict(source); byte dstDistrict = districtManager.GetDistrict(destination); if (srcDistrict != 0 && !IsActive(srcDistrict)) { Utils.LogGeneral($"IsTransferAllowed: srcDistrict {srcDistrict} not active, setting to zero!"); srcDistrict = 0; } if (dstDistrict != 0 && !IsActive(dstDistrict)) { Utils.LogGeneral($"IsTransferAllowed: dstDistrict {dstDistrict} not active, setting to zero!"); dstDistrict = 0; } // check whether this transfer represents a resident going out to do something if (isResidentTransfer) { switch (reason) { // resident going to a hospital or clinic case TransferManager.TransferReason.Sick: case TransferManager.TransferReason.Sick2: return(Settings.RestrictCitizenHealthAccess ? (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true); // resident going to an educational building case TransferManager.TransferReason.Student1: case TransferManager.TransferReason.Student2: case TransferManager.TransferReason.Student3: return(Settings.RestrictCitizenEducationalAccess ? (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true); // resident going to a park case TransferManager.TransferReason.Entertainment: case TransferManager.TransferReason.EntertainmentB: case TransferManager.TransferReason.EntertainmentC: case TransferManager.TransferReason.EntertainmentD: return(Settings.RestrictCitizenParkAccess ? (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true); // resident going to a shop case TransferManager.TransferReason.Shopping: case TransferManager.TransferReason.ShoppingB: case TransferManager.TransferReason.ShoppingC: case TransferManager.TransferReason.ShoppingD: case TransferManager.TransferReason.ShoppingE: case TransferManager.TransferReason.ShoppingF: case TransferManager.TransferReason.ShoppingG: case TransferManager.TransferReason.ShoppingH: return(Settings.RestrictCitizenShoppingAccess ? (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true); // resident going to work case TransferManager.TransferReason.Worker0: case TransferManager.TransferReason.Worker1: case TransferManager.TransferReason.Worker2: case TransferManager.TransferReason.Worker3: return(Settings.RestrictCitizenWorkAccess ? (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true); default: return(true); } } else { switch (reason) { // vehicle fetching something case TransferManager.TransferReason.Garbage: case TransferManager.TransferReason.Crime: case TransferManager.TransferReason.Sick: case TransferManager.TransferReason.Sick2: case TransferManager.TransferReason.Dead: case TransferManager.TransferReason.Fire: case TransferManager.TransferReason.Fire2: case TransferManager.TransferReason.Taxi: case TransferManager.TransferReason.Snow: case TransferManager.TransferReason.RoadMaintenance: return(!Settings.RestrictServiceDispatching ? true : (srcDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(buildingID, dstDistrict))); // vehicle freeing building capacity case TransferManager.TransferReason.DeadMove: case TransferManager.TransferReason.GarbageMove: case TransferManager.TransferReason.SnowMove: return(!Settings.RestrictMaterialTransfer ? true : (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict))); //inverted logic: destination must cover source of move! // ignore prisons case TransferManager.TransferReason.CriminalMove: return(true); default: return(true); } } }
public void CustomCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position nextPosition, PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID, byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed) { var netManager = Singleton <NetManager> .instance; ushort targetNodeId; ushort nextTargetNodeId; if (offset < position.m_offset) { targetNodeId = netManager.m_segments.m_buffer[position.m_segment].m_startNode; nextTargetNodeId = netManager.m_segments.m_buffer[position.m_segment].m_endNode; } else { targetNodeId = netManager.m_segments.m_buffer[position.m_segment].m_endNode; nextTargetNodeId = netManager.m_segments.m_buffer[position.m_segment].m_startNode; } var prevTargetNodeId = prevOffset == 0 ? netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode : netManager.m_segments.m_buffer[prevPos.m_segment].m_endNode; Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData(); Vector3 lastFrameVehiclePos = lastFrameData.m_position; float sqrVelocity = lastFrameData.m_velocity.sqrMagnitude; netManager.m_lanes.m_buffer[laneID].CalculatePositionAndDirection(offset * 0.003921569f, out pos, out dir); float braking = this.m_info.m_braking; if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) != (Vehicle.Flags) 0) { braking *= 2f; } // car position on the Bezier curve of the lane var vehiclePosOnBezier = netManager.m_lanes.m_buffer[prevLaneID].CalculatePosition(prevOffset * 0.003921569f); //ushort currentSegmentId = netManager.m_lanes.m_buffer[prevLaneID].m_segment; // this seems to be like the required braking force in order to stop the vehicle within its half length. var crazyValue = 0.5f * sqrVelocity / braking + m_info.m_generatedInfo.m_size.z * 0.5f; bool withinBrakingDistance = Vector3.Distance(lastFrameVehiclePos, vehiclePosOnBezier) >= crazyValue - 1f; // NON-STOCK CODE START #if BENCHMARK using (var bm = new Benchmark(null, "UpdateVehiclePosition")) { #endif VehicleStateManager.Instance.UpdateVehiclePosition(vehicleId, ref vehicleData, lastFrameData.m_velocity.magnitude); #if BENCHMARK } #endif // NON-STOCK CODE END bool isRecklessDriver = VehicleStateManager.Instance.VehicleStates[vehicleId].recklessDriver; if (targetNodeId == prevTargetNodeId && withinBrakingDistance) { // NON-STOCK CODE START (stock code replaced) #if BENCHMARK using (var bm = new Benchmark(null, "MayChangeSegment")) { #endif //bool isRecklessDriver = VehicleStateManager.Instance.IsRecklessDriver(vehicleId, ref vehicleData); // NON-STOCK CODE if (!VehicleBehaviorManager.Instance.MayChangeSegment(vehicleId, ref VehicleStateManager.Instance.VehicleStates[vehicleId], ref vehicleData, sqrVelocity, isRecklessDriver, ref prevPos, ref netManager.m_segments.m_buffer[prevPos.m_segment], prevTargetNodeId, prevLaneID, ref position, targetNodeId, ref netManager.m_nodes.m_buffer[targetNodeId], laneID, ref nextPosition, nextTargetNodeId, out maxSpeed)) // NON-STOCK CODE { return; } #if BENCHMARK } #endif // NON-STOCK CODE END } var segmentInfo = netManager.m_segments.m_buffer[position.m_segment].Info; if (segmentInfo.m_lanes != null && segmentInfo.m_lanes.Length > position.m_lane) { // NON-STOCK CODE START // NON-STOCK CODE START float laneSpeedLimit = 1f; #if BENCHMARK using (var bm = new Benchmark(null, "GetLockFreeGameSpeedLimit")) { #endif if (!Options.customSpeedLimitsEnabled) { laneSpeedLimit = segmentInfo.m_lanes[position.m_lane].m_speedLimit; } else { // === START INLINED VERSION OF SpeedLimitManager.GetLockFreeGameSpeedLimit === ushort?[] fastArray = Flags.laneSpeedLimitArray[position.m_segment]; if (fastArray != null && fastArray.Length > position.m_lane && fastArray[position.m_lane] != null) { // === START INLINED VERSION OF SpeedLimitManager.ToGameSpeedLimit === laneSpeedLimit = (float)fastArray[position.m_lane]; if (laneSpeedLimit == 0) { laneSpeedLimit = SpeedLimitManager.MAX_SPEED; } else { laneSpeedLimit = laneSpeedLimit / 50f; } // === END INLINED VERSION OF SpeedLimitManager.ToGameSpeedLimit === // laneSpeedLimit = ToGameSpeedLimit((ushort)fastArray[position.m_lane]); } else { laneSpeedLimit = segmentInfo.m_lanes[position.m_lane].m_speedLimit; } // === END INLINED VERSION OF SpeedLimitManager.GetLockFreeGameSpeedLimit === //laneSpeedLimit = SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, segmentInfo.m_lanes[position.m_lane]); // info2.m_lanes[position.m_lane].m_speedLimit; // NON-STOCK CODE } #if BENCHMARK } #endif // NON-STOCK CODE END maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit, netManager.m_lanes.m_buffer[laneID].m_curve); } else { maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f); } // NON-STOCK CODE START (stock code replaced) #if BENCHMARK using (var bm = new Benchmark(null, "CalcMaxSpeed")) { #endif // === START INLINED VERSION OF VehicleBehaviorManager.CalcMaxSpeed === if (Singleton <NetManager> .instance.m_treatWetAsSnow) { DistrictManager districtManager = Singleton <DistrictManager> .instance; byte district = districtManager.GetDistrict(pos); DistrictPolicies.CityPlanning cityPlanningPolicies = districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None) { if (Options.strongerRoadConditionEffects) { if (maxSpeed > VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED) { maxSpeed = VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED); } } else { maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.0005882353f; // vanilla: -15% .. ±0% } districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= DistrictPolicies.CityPlanning.StuddedTires; } else { if (Options.strongerRoadConditionEffects) { if (maxSpeed > VehicleBehaviorManager.ICY_ROADS_MIN_SPEED) { maxSpeed = VehicleBehaviorManager.ICY_ROADS_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - VehicleBehaviorManager.ICY_ROADS_MIN_SPEED); } } else { maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.00117647066f; // vanilla: -30% .. ±0% } } } else { if (Options.strongerRoadConditionEffects) { float minSpeed = Math.Min(maxSpeed * VehicleBehaviorManager.WET_ROADS_FACTOR, VehicleBehaviorManager.WET_ROADS_MAX_SPEED); // custom: -25% .. 0 if (maxSpeed > minSpeed) { maxSpeed = minSpeed + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - minSpeed); } } else { maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.0005882353f; // vanilla: -15% .. ±0% } } if (Options.strongerRoadConditionEffects) { float minSpeed = Math.Min(maxSpeed * VehicleBehaviorManager.BROKEN_ROADS_FACTOR, VehicleBehaviorManager.BROKEN_ROADS_MAX_SPEED); if (maxSpeed > minSpeed) { maxSpeed = minSpeed + (float)netManager.m_segments.m_buffer[position.m_segment].m_condition * 0.0039215686f * (maxSpeed - minSpeed); } } else { maxSpeed *= 1f + (float)netManager.m_segments.m_buffer[position.m_segment].m_condition * 0.0005882353f; // vanilla: ±0% .. +15 % } // === START INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds === if (Options.realisticSpeeds) { // === START INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds === float vehicleRand = 0.01f * (float)(vehicleId % 100); // float vehicleRand = 0.01f * (float)GetVehicleRand(vehicleId); // === END INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds === if (this.m_info.m_isLargeVehicle) { maxSpeed *= 0.9f + vehicleRand * 0.1f; // a little variance, 0.9 .. 1 } else if (isRecklessDriver) { maxSpeed *= 1.3f + vehicleRand * 1.7f; // woohooo, 1.3 .. 3 } else { maxSpeed *= 0.8f + vehicleRand * 0.5f; // a little variance, 0.8 .. 1.3 } } else if (isRecklessDriver) { maxSpeed *= 1.5f; } // === END INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds === //maxSpeed = ApplyRealisticSpeeds(maxSpeed, vehicleId, this.m_info, isRecklessDriver); maxSpeed = Math.Max(VehicleBehaviorManager.MIN_SPEED, maxSpeed); // at least 10 km/h // === END INLINED VERSION OF VehicleBehaviorManager.CalcMaxSpeed === //maxSpeed = VehicleBehaviorManager.Instance.CalcMaxSpeed(vehicleId, this.m_info, position, ref netManager.m_segments.m_buffer[position.m_segment], pos, maxSpeed, isRecklessDriver); #if BENCHMARK } #endif // NON-STOCK CODE END }
private void CheckBuildingLevel(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, ref Citizen.BehaviourData behaviour) { DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(buildingData.m_position); DistrictPolicies.CityPlanning cityPlanningPolicies = instance.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; int num = behaviour.m_educated1Count + behaviour.m_educated2Count * 2 + behaviour.m_educated3Count * 3; int num2 = behaviour.m_teenCount + behaviour.m_youngCount * 2 + behaviour.m_adultCount * 3 + behaviour.m_seniorCount * 3; int averageEducation; ItemClass.Level level; int num3; if (num2 != 0) { averageEducation = (num * 300 + (num2 >> 1)) / num2; num = (num * 72 + (num2 >> 1)) / num2; if (num < 15) { level = ItemClass.Level.Level1; num3 = 1 + num; } else if (num < 30) { level = ItemClass.Level.Level2; num3 = 1 + (num - 15); } else if (num < 45) { level = ItemClass.Level.Level3; num3 = 1 + (num - 30); } else if (num < 60) { level = ItemClass.Level.Level4; num3 = 1 + (num - 45); } else { level = ItemClass.Level.Level5; num3 = 1; } if (level < this.m_info.m_class.m_level) { num3 = 1; } else if (level > this.m_info.m_class.m_level) { num3 = 15; } } else { level = ItemClass.Level.Level1; averageEducation = 0; num3 = 0; } int num4; Singleton <ImmaterialResourceManager> .instance.CheckLocalResource(ImmaterialResourceManager.Resource.LandValue, buildingData.m_position, out num4); ItemClass.Level level2; int num5; if (num3 != 0) { if (num4 < 6) { level2 = ItemClass.Level.Level1; num5 = 1 + (num4 * 15 + 3) / 6; } else if (num4 < 21) { level2 = ItemClass.Level.Level2; num5 = 1 + ((num4 - 6) * 15 + 7) / 15; } else if (num4 < 41) { level2 = ItemClass.Level.Level3; num5 = 1 + ((num4 - 21) * 15 + 10) / 20; } else if (num4 < 61) { level2 = ItemClass.Level.Level4; num5 = 1 + ((num4 - 41) * 15 + 10) / 20; } else { level2 = ItemClass.Level.Level5; num5 = 1; } if (level2 < this.m_info.m_class.m_level) { num5 = 1; } else if (level2 > this.m_info.m_class.m_level) { num5 = 15; } } else { level2 = ItemClass.Level.Level1; num5 = 0; } bool flag = false; if (this.m_info.m_class.m_level == ItemClass.Level.Level2) { if (num4 == 0) { flag = true; } } else if (this.m_info.m_class.m_level == ItemClass.Level.Level3) { if (num4 < 11) { flag = true; } } else if (this.m_info.m_class.m_level == ItemClass.Level.Level4) { if (num4 < 31) { flag = true; } } else if (this.m_info.m_class.m_level == ItemClass.Level.Level5 && num4 < 51) { flag = true; } ItemClass.Level level3 = (ItemClass.Level)Mathf.Min((int)level, (int)level2); Singleton <BuildingManager> .instance.m_LevelUpWrapper.OnCalculateResidentialLevelUp(ref level3, ref num3, ref num5, ref flag, averageEducation, num4, buildingID, this.m_info.m_class.m_service, this.m_info.m_class.m_subService, this.m_info.m_class.m_level); if (flag) { buildingData.m_serviceProblemTimer = (byte)Mathf.Min(255, (int)(buildingData.m_serviceProblemTimer + 1)); if (buildingData.m_serviceProblemTimer >= 8) { buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.LandValueLow | Notification.Problem.MajorProblem); } else if (buildingData.m_serviceProblemTimer >= 4) { buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.LandValueLow); } else { buildingData.m_problems = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.LandValueLow); } } else { buildingData.m_serviceProblemTimer = 0; buildingData.m_problems = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.LandValueLow); } /* Remove high rise ban * if (level3 > this.m_info.m_class.m_level) * { * num3 = 0; * num5 = 0; * if (this.m_info.m_class.m_subService == ItemClass.SubService.ResidentialHigh && (cityPlanningPolicies & DistrictPolicies.CityPlanning.HighriseBan) != DistrictPolicies.CityPlanning.None && level3 == ItemClass.Level.Level5) * { * District[] expr_41B_cp_0 = instance.m_districts.m_buffer; * byte expr_41B_cp_1 = district; * expr_41B_cp_0[(int)expr_41B_cp_1].m_cityPlanningPoliciesEffect = (expr_41B_cp_0[(int)expr_41B_cp_1].m_cityPlanningPoliciesEffect | DistrictPolicies.CityPlanning.HighriseBan); * level3 = ItemClass.Level.Level4; * num3 = 1; * } * if (buildingData.m_problems == Notification.Problem.None && level3 > this.m_info.m_class.m_level && this.GetUpgradeInfo(buildingID, ref buildingData) != null) * { * frameData.m_constructState = 0; * base.StartUpgrading(buildingID, ref buildingData); * } * } */ buildingData.m_levelUpProgress = (byte)(num3 | num5 << 4); }
private void ProcessHumansUpdated() { SkylinesOverwatch.Data data = SkylinesOverwatch.Data.Instance; uint[] humans = data.HumansUpdated; if (humans.Length == 0) { return; } CitizenManager instance = Singleton <CitizenManager> .instance; foreach (uint i in humans) { if (!data.IsResident(i)) { continue; } Citizen[] residents = instance.m_citizens.m_buffer; Citizen resident = residents[(int)i]; if (resident.Dead) { continue; } if ((resident.m_flags & Citizen.Flags.Created) == Citizen.Flags.None) { continue; } if ((resident.m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None) { continue; } if (!Kill(resident)) { continue; } residents[(int)i].Sick = false; residents[(int)i].Dead = true; residents[(int)i].SetParkedVehicle(i, 0); ushort home = resident.GetBuildingByLocation(); if (home == 0) { home = resident.m_homeBuilding; } if (home != 0) { DistrictManager dm = Singleton <DistrictManager> .instance; Vector3 position = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)home].m_position; byte district = dm.GetDistrict(position); District[] buffer = dm.m_districts.m_buffer; buffer[(int)district].m_deathData.m_tempCount = buffer[(int)district].m_deathData.m_tempCount + 1; } if (_randomizer.Int32(2) == 0) { instance.ReleaseCitizen(i); } SkylinesOverwatch.Helper.Instance.RequestHumanRemoval(i); } }
protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount) { base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount); int num = productionRate * this.m_noiseAccumulation / 100; if (num != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num, buildingData.m_position, this.m_noiseRadius); } base.HandleDead(buildingID, ref buildingData, ref behaviour, totalWorkerCount); TransferManager.TransferReason vehicleReason = this.m_transportInfo.m_vehicleReason; if (vehicleReason != TransferManager.TransferReason.None) { int num2 = (productionRate * this.m_maxVehicleCount + 99) / 100; if (this.m_transportInfo.m_transportType == TransportInfo.TransportType.Taxi) { DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(buildingData.m_position); District[] expr_B4_cp_0_cp_0 = instance.m_districts.m_buffer; byte expr_B4_cp_0_cp_1 = district; expr_B4_cp_0_cp_0 [(int)expr_B4_cp_0_cp_1].m_productionData.m_tempTaxiCapacity = expr_B4_cp_0_cp_0 [(int)expr_B4_cp_0_cp_1].m_productionData.m_tempTaxiCapacity + (uint)num2; } int num3 = 0; int num4 = 0; ushort num5 = 0; VehicleManager instance2 = Singleton <VehicleManager> .instance; ushort num6 = buildingData.m_ownVehicles; int num7 = 0; while (num6 != 0) { if ((TransferManager.TransferReason)instance2.m_vehicles.m_buffer [(int)num6].m_transferType == vehicleReason) { VehicleInfo info = instance2.m_vehicles.m_buffer [(int)num6].Info; int num8; int num9; info.m_vehicleAI.GetSize(num6, ref instance2.m_vehicles.m_buffer [(int)num6], out num8, out num9); num3++; if ((instance2.m_vehicles.m_buffer [(int)num6].m_flags & Vehicle.Flags.GoingBack) != Vehicle.Flags.None) { num4++; } else { if ((instance2.m_vehicles.m_buffer [(int)num6].m_flags & Vehicle.Flags.WaitingTarget) != Vehicle.Flags.None) { num5 = num6; } else { if (instance2.m_vehicles.m_buffer [(int)num6].m_targetBuilding != 0) { num5 = num6; } } } } num6 = instance2.m_vehicles.m_buffer [(int)num6].m_nextOwnVehicle; if (++num7 > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } if (this.m_maxVehicleCount < 65536 && num3 - num4 > num2 && num5 != 0) { VehicleInfo info2 = instance2.m_vehicles.m_buffer [(int)num5].Info; info2.m_vehicleAI.SetTarget(num5, ref instance2.m_vehicles.m_buffer [(int)num5], buildingID); } if (num3 < num2) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = 0; offer.Building = buildingID; offer.Position = buildingData.m_position; offer.Amount = Mathf.Min(2, num2 - num3); offer.Active = true; Singleton <TransferManager> .instance.AddOutgoingOffer(vehicleReason, offer); } } }
new protected int HandleCommonConsumption(ushort buildingID, ref Building data, ref Building.Frame frameData, ref int electricityConsumption, ref int heatingConsumption, ref int waterConsumption, ref int sewageAccumulation, ref int garbageAccumulation, DistrictPolicies.Services policies) { int num = 100; DistrictManager instance = Singleton <DistrictManager> .instance; Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Electricity | Notification.Problem.Water | Notification.Problem.Sewage | Notification.Problem.Flood | Notification.Problem.Heating); bool flag = data.m_electricityProblemTimer != 0; bool flag2 = false; bool flag3 = false; int electricityUsage = 0; int heatingUsage = 0; int waterUsage = 0; int sewageUsage = 0; if (electricityConsumption != 0) { int num2 = Mathf.RoundToInt((20f - Singleton <WeatherManager> .instance.SampleTemperature(data.m_position, false)) * 8f); num2 = Mathf.Clamp(num2, 0, 400); int num3 = heatingConsumption; heatingConsumption = (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100; if ((policies & DistrictPolicies.Services.PowerSaving) != DistrictPolicies.Services.None) { electricityConsumption = Mathf.Max(1, electricityConsumption * 90 / 100); Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class); } bool flag4 = false; int num4 = heatingConsumption * 2 - (int)data.m_heatingBuffer; if (num4 > 0 && (policies & DistrictPolicies.Services.OnlyElectricity) == DistrictPolicies.Services.None) { int num5 = Singleton <WaterManager> .instance.TryFetchHeating(data.m_position, heatingConsumption, num4, out flag4); data.m_heatingBuffer += (ushort)num5; } if ((int)data.m_heatingBuffer < heatingConsumption) { if ((policies & DistrictPolicies.Services.NoElectricity) != DistrictPolicies.Services.None) { flag3 = true; data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1)); if (data.m_heatingProblemTimer >= 65) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Heating | Notification.Problem.MajorProblem); } else if (data.m_heatingProblemTimer >= 3) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Heating); } } else { num2 = ((num2 + 50) * (heatingConsumption - (int)data.m_heatingBuffer) + heatingConsumption - 1) / heatingConsumption; electricityConsumption += (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100; if (flag4) { flag3 = true; data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1)); if (data.m_heatingProblemTimer >= 3) { problem = Notification.AddProblems(problem, Notification.Problem.Heating); } } } heatingUsage = (int)data.m_heatingBuffer; data.m_heatingBuffer = 0; } else { heatingUsage = heatingConsumption; data.m_heatingBuffer -= (ushort)heatingConsumption; } int num6; int a; if (this.CanStockpileElectricity(buildingID, ref data, out num6, out a)) { num4 = num6 + electricityConsumption * 2 - (int)data.m_electricityBuffer; if (num4 > 0) { int num7 = electricityConsumption; if ((int)data.m_electricityBuffer < num6) { num7 += Mathf.Min(a, num6 - (int)data.m_electricityBuffer); } int num8 = Singleton <ElectricityManager> .instance.TryFetchElectricity(data.m_position, num7, num4); data.m_electricityBuffer += (ushort)num8; if (num8 < num4 && num8 < num7) { flag2 = true; problem = Notification.AddProblems(problem, Notification.Problem.Electricity); if (data.m_electricityProblemTimer < 64) { data.m_electricityProblemTimer = 64; } } } } else { num4 = electricityConsumption * 2 - (int)data.m_electricityBuffer; if (num4 > 0) { int num9 = Singleton <ElectricityManager> .instance.TryFetchElectricity(data.m_position, electricityConsumption, num4); data.m_electricityBuffer += (ushort)num9; } } if ((int)data.m_electricityBuffer < electricityConsumption) { flag2 = true; data.m_electricityProblemTimer = (byte)Mathf.Min(255, (int)(data.m_electricityProblemTimer + 1)); if (data.m_electricityProblemTimer >= 65) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Electricity | Notification.Problem.MajorProblem); } else if (data.m_electricityProblemTimer >= 3) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Electricity); } electricityUsage = (int)data.m_electricityBuffer; data.m_electricityBuffer = 0; if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Electricity)) { GuideController properties = Singleton <GuideManager> .instance.m_properties; if (properties != null) { int publicServiceIndex = ItemClass.GetPublicServiceIndex(ItemClass.Service.Electricity); int electricityCapacity = instance.m_districts.m_buffer[0].GetElectricityCapacity(); int electricityConsumption2 = instance.m_districts.m_buffer[0].GetElectricityConsumption(); if (electricityCapacity >= electricityConsumption2) { Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded2, ItemClass.Service.Electricity); } else { Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded, ItemClass.Service.Electricity); } } } } else { electricityUsage = electricityConsumption; data.m_electricityBuffer -= (ushort)electricityConsumption; } } else { heatingConsumption = 0; } if (!flag2) { data.m_electricityProblemTimer = 0; } if (flag != flag2) { Singleton <BuildingManager> .instance.UpdateBuildingColors(buildingID); } if (!flag3) { data.m_heatingProblemTimer = 0; } bool flag5 = false; int num10 = sewageAccumulation; if (waterConsumption != 0) { if ((policies & DistrictPolicies.Services.WaterSaving) != DistrictPolicies.Services.None) { waterConsumption = Mathf.Max(1, waterConsumption * 85 / 100); if (sewageAccumulation != 0) { sewageAccumulation = Mathf.Max(1, sewageAccumulation * 85 / 100); } Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class); } int num11; int a2; if (this.CanStockpileWater(buildingID, ref data, out num11, out a2)) { int num12 = num11 + waterConsumption * 2 - (int)data.m_waterBuffer; if (num12 > 0) { int num13 = waterConsumption; if ((int)data.m_waterBuffer < num11) { num13 += Mathf.Min(a2, num11 - (int)data.m_waterBuffer); } int num14 = Singleton <WaterManager> .instance.TryFetchWater(data.m_position, num13, num12, ref data.m_waterPollution); data.m_waterBuffer += (ushort)num14; if (num14 < num12 && num14 < num13) { flag5 = true; problem = Notification.AddProblems(problem, Notification.Problem.Water); if (data.m_waterProblemTimer < 64) { data.m_waterProblemTimer = 64; } } } } else { int num15 = waterConsumption * 2 - (int)data.m_waterBuffer; if (num15 > 0) { int num16 = Singleton <WaterManager> .instance.TryFetchWater(data.m_position, waterConsumption, num15, ref data.m_waterPollution); data.m_waterBuffer += (ushort)num16; } } if ((int)data.m_waterBuffer < waterConsumption) { flag5 = true; data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1)); if (data.m_waterProblemTimer >= 65) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Water | Notification.Problem.MajorProblem); } else if (data.m_waterProblemTimer >= 3) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Water); } num10 = sewageAccumulation * (waterConsumption + (int)data.m_waterBuffer) / (waterConsumption << 1); waterUsage = (int)data.m_waterBuffer; data.m_waterBuffer = 0; if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Water)) { GuideController properties2 = Singleton <GuideManager> .instance.m_properties; if (properties2 != null) { int publicServiceIndex2 = ItemClass.GetPublicServiceIndex(ItemClass.Service.Water); int waterCapacity = instance.m_districts.m_buffer[0].GetWaterCapacity(); int waterConsumption2 = instance.m_districts.m_buffer[0].GetWaterConsumption(); if (waterCapacity >= waterConsumption2) { Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded2, ItemClass.Service.Water); } else { Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded, ItemClass.Service.Water); } } } } else { num10 = sewageAccumulation; waterUsage = waterConsumption; data.m_waterBuffer -= (ushort)waterConsumption; } } int num17; int b; if (this.CanStockpileWater(buildingID, ref data, out num17, out b)) { int num18 = Mathf.Max(0, num17 + num10 * 2 - (int)data.m_sewageBuffer); if (num18 < num10) { if (!flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None) { flag5 = true; data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1)); if (data.m_waterProblemTimer >= 65) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Sewage | Notification.Problem.MajorProblem); } else if (data.m_waterProblemTimer >= 3) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Sewage); } } sewageUsage = num18; data.m_sewageBuffer = (ushort)(num17 + num10 * 2); } else { sewageUsage = num10; data.m_sewageBuffer += (ushort)num10; } int num19 = num10 + Mathf.Max(num10, b); num18 = Mathf.Min(num19, (int)data.m_sewageBuffer); if (num18 > 0) { int num20 = Singleton <WaterManager> .instance.TryDumpSewage(data.m_position, num19, num18); data.m_sewageBuffer -= (ushort)num20; if (num20 < num19 && num20 < num18 && !flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None) { flag5 = true; problem = Notification.AddProblems(problem, Notification.Problem.Sewage); if (data.m_waterProblemTimer < 64) { data.m_waterProblemTimer = 64; } } } } else if (num10 != 0) { int num21 = Mathf.Max(0, num10 * 2 - (int)data.m_sewageBuffer); if (num21 < num10) { if (!flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None) { flag5 = true; data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1)); if (data.m_waterProblemTimer >= 65) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Sewage | Notification.Problem.MajorProblem); } else if (data.m_waterProblemTimer >= 3) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Sewage); } } sewageUsage = num21; data.m_sewageBuffer = (ushort)(num10 * 2); } else { sewageUsage = num10; data.m_sewageBuffer += (ushort)num10; } num21 = Mathf.Min(num10 * 2, (int)data.m_sewageBuffer); if (num21 > 0) { int num22 = Singleton <WaterManager> .instance.TryDumpSewage(data.m_position, num10 * 2, num21); data.m_sewageBuffer -= (ushort)num22; } } if (!flag5) { data.m_waterProblemTimer = 0; } if (garbageAccumulation != 0) { int num23 = (int)(65535 - data.m_garbageBuffer); if (num23 < garbageAccumulation) { num = 0; data.m_garbageBuffer = (ushort)num23; } else { //start edit StormDrainAI stormDrainAI = data.Info.m_buildingAI as StormDrainAI; if (stormDrainAI == null) { data.m_garbageBuffer += (ushort)garbageAccumulation; } else if (stormDrainAI.m_filter == false) { data.m_garbageBuffer += (ushort)garbageAccumulation; } else { int pollutantAccumulation = Hydraulics.removePollutants(buildingID, Hydraulics.getPollutants(buildingID)); data.m_garbageBuffer += (ushort)pollutantAccumulation; //Debug.Log("[RF]CommonBuildingAI.handleCommonConsumption garbagebuffer = " + data.m_garbageBuffer.ToString()); } //end edit } } if (garbageAccumulation != 0) { int num24 = (int)data.m_garbageBuffer; if (num24 >= 200 && Singleton <SimulationManager> .instance.m_randomizer.Int32(5u) == 0 && Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Garbage)) { int num25 = 0; int num26 = 0; int num27 = 0; int num28 = 0; this.CalculateGuestVehicles(buildingID, ref data, TransferManager.TransferReason.Garbage, ref num25, ref num26, ref num27, ref num28); num24 -= num27 - num26; if (num24 >= 200) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = num24 / 1000; offer.Building = buildingID; offer.Position = data.m_position; offer.Amount = 1; Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Garbage, offer); } } } bool flag6; if (this.CanSufferFromFlood(out flag6)) { float num29 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(data.m_position)); if (num29 > data.m_position.y) { bool flag7 = num29 > data.m_position.y + Mathf.Max(4f, this.m_info.m_collisionHeight); if ((!flag6 || flag7) && (data.m_flags & Building.Flags.Flooded) == Building.Flags.None && data.m_fireIntensity == 0) { DisasterManager instance2 = Singleton <DisasterManager> .instance; ushort num30 = instance2.FindDisaster <FloodBaseAI>(data.m_position); if (num30 == 0) { DisasterInfo disasterInfo = DisasterManager.FindDisasterInfo <GenericFloodAI>(); if (disasterInfo != null && instance2.CreateDisaster(out num30, disasterInfo)) { instance2.m_disasters.m_buffer[(int)num30].m_intensity = 10; instance2.m_disasters.m_buffer[(int)num30].m_targetPosition = data.m_position; disasterInfo.m_disasterAI.StartNow(num30, ref instance2.m_disasters.m_buffer[(int)num30]); } } if (num30 != 0) { InstanceID srcID = default(InstanceID); InstanceID dstID = default(InstanceID); srcID.Disaster = num30; dstID.Building = buildingID; Singleton <InstanceManager> .instance.CopyGroup(srcID, dstID); DisasterInfo info = instance2.m_disasters.m_buffer[(int)num30].Info; info.m_disasterAI.ActivateNow(num30, ref instance2.m_disasters.m_buffer[(int)num30]); if ((instance2.m_disasters.m_buffer[(int)num30].m_flags & DisasterData.Flags.Significant) != DisasterData.Flags.None) { instance2.DetectDisaster(num30, false); instance2.FollowDisaster(num30); } } data.m_flags |= Building.Flags.Flooded; } if (flag7) { frameData.m_constructState = (byte)Mathf.Max(0, (int)frameData.m_constructState - 1088 / this.GetCollapseTime()); data.SetFrameData(Singleton <SimulationManager> .instance.m_currentFrameIndex, frameData); InstanceID id = default(InstanceID); id.Building = buildingID; InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id); if (group != null) { ushort disaster = group.m_ownerInstance.Disaster; if (disaster != 0) { DisasterData[] expr_D18_cp_0 = Singleton <DisasterManager> .instance.m_disasters.m_buffer; ushort expr_D18_cp_1 = disaster; expr_D18_cp_0[(int)expr_D18_cp_1].m_collapsedCount = (ushort)(expr_D18_cp_0[(int)expr_D18_cp_1].m_collapsedCount + 1); } } if (frameData.m_constructState == 0) { Singleton <InstanceManager> .instance.SetGroup(id, null); } data.m_levelUpProgress = 0; data.m_fireIntensity = 0; data.m_garbageBuffer = 0; data.m_flags |= Building.Flags.Collapsed; num = 0; this.RemovePeople(buildingID, ref data, 90); this.BuildingDeactivated(buildingID, ref data); if (this.m_info.m_hasParkingSpaces != VehicleInfo.VehicleType.None) { Singleton <BuildingManager> .instance.UpdateParkingSpaces(buildingID, ref data); } Singleton <BuildingManager> .instance.UpdateBuildingRenderer(buildingID, true); Singleton <BuildingManager> .instance.UpdateBuildingColors(buildingID); GuideController properties3 = Singleton <GuideManager> .instance.m_properties; if (properties3 != null) { Singleton <BuildingManager> .instance.m_buildingFlooded.Deactivate(buildingID, false); Singleton <BuildingManager> .instance.m_buildingFlooded2.Deactivate(buildingID, false); } } else if (!flag6) { if ((data.m_flags & Building.Flags.RoadAccessFailed) == Building.Flags.None) { int num31 = 0; int num32 = 0; int num33 = 0; int num34 = 0; this.CalculateGuestVehicles(buildingID, ref data, TransferManager.TransferReason.FloodWater, ref num31, ref num32, ref num33, ref num34); if (num31 == 0) { TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer); offer2.Priority = 5; offer2.Building = buildingID; offer2.Position = data.m_position; offer2.Amount = 1; Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.FloodWater, offer2); } } if (num29 > data.m_position.y + (float)ModSettings.BuildingFloodedTolerance / 100f) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem); } else if (num29 > data.m_position.y + (float)ModSettings.BuildingFloodingTolerance / 100f) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Flood); } GuideController properties4 = Singleton <GuideManager> .instance.m_properties; if (properties4 != null) { if (Singleton <LoadingManager> .instance.SupportsExpansion(Expansion.NaturalDisasters) && Singleton <UnlockManager> .instance.Unlocked(UnlockManager.Feature.WaterPumping)) { Singleton <BuildingManager> .instance.m_buildingFlooded2.Activate(properties4.m_buildingFlooded2, buildingID); } else { Singleton <BuildingManager> .instance.m_buildingFlooded.Activate(properties4.m_buildingFlooded, buildingID); } } } } else if ((data.m_flags & Building.Flags.Flooded) != Building.Flags.None) { InstanceID id2 = default(InstanceID); id2.Building = buildingID; Singleton <InstanceManager> .instance.SetGroup(id2, null); data.m_flags &= ~Building.Flags.Flooded; } } byte district = instance.GetDistrict(data.m_position); instance.m_districts.m_buffer[(int)district].AddUsageData(electricityUsage, heatingUsage, waterUsage, sewageUsage); data.m_problems = problem; return(num); }
//Static or Override? /////////////////////////////////////////////////////////// public override void SimulationStep(ushort buildingID, ref Building buildingData, ref Building.Frame frameData) { if (Tracker.GetAccessibilityActive() && !m_logged) //Simply check to see if a log is needed, usage is activated in AI classes { TrafficLog.TryAddBuildingLog(buildingID); m_logged = true; } //base.SimulationStep(buildingID, ref buildingData, ref frameData); DistrictManager instanceG = Singleton <DistrictManager> .instance; //DistrictManagerDetour instanceG = Singleton<DistrictManagerDetour>.instance; //Create a new policy or modify an existing policy DistrictPolicies.Policies policyG = DistrictPolicies.Policies.Recycling; //tra tra = new tra(); //Tracker.Activate(); //tra.serialize(new byte[255]); if (instanceG.IsDistrictPolicySet(policyG, instanceG.GetDistrict(buildingData.m_position))) { //This functiion does implement a district effect. However, Abandonment as a resource //does not induce abandonment itself. //Singleton<ImmaterialResourceManager>.instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, 1000000, buildingData.m_position, 400); //base.EmptyBuilding(buildingID, ref buildingData); //base.ManualDeactivation(buildingID, ref buildingData); Vector3 m_vector3 = buildingData.m_position; //string m_districtname = instanceG.GetDistrictName(instanceG.GetDistrict(m_vector3), true); string m_districtname = instanceG.GetDistrictName(instanceG.GetDistrict(m_vector3)); byte m_districtbyte = instanceG.GetDistrict(m_vector3); Debug.Log("CommonBuildingAIDetour: " + m_districtname + " X: " + m_vector3.x + " Y: " + m_vector3.y + " Z: " + m_vector3.z); //This function adds gentrification by district. The concept works but //it is implemented in the wrong place and by an arbitrary cause //that requires a temporary slowdown via RNG to avoid overburdening //the chirper ChirperPanel instance. //TRANSFER LATER, GENTRIFICATION TRACKING /* * System.Random rng = new System.Random(); * int r = rng.Next(0, 10); * if (r==5) * { * Tracker.Load(m_districtbyte, 1); * //Tracker.Load(m_districtbyte, 1); * int m_gentrifiedint = Convert.ToInt32(Tracker.Get(m_districtbyte)); * string m_gentrifiedstring = Convert.ToString(m_gentrifiedint); * ChirpPanel chirper = Singleton<ChirpPanel>.instance; * if ((m_gentrifiedint % 100) == 0) * { * //chirper.AddMessage(new ChirpMessage(m_districtname + " Gentrification Status: ", m_gentrifiedstring + " households have been gentrified")); * } * //Debug.Log(m_districtname + " Gentrification Status: "+ m_gentrifiedstring + " (" + Convert.ToString(m_districtbyte) + ") " + "households have been gentrified"); * } */ } if ((buildingData.m_flags & Building.Flags.Abandoned) != Building.Flags.None) { GuideController guideController = Singleton <GuideManager> .instance.m_properties; if (guideController != null) { Singleton <BuildingManager> .instance.m_buildingAbandoned1.Activate(guideController.m_buildingAbandoned1, buildingID); Singleton <BuildingManager> .instance.m_buildingAbandoned2.Activate(guideController.m_buildingAbandoned2, buildingID); } if ((int)buildingData.m_majorProblemTimer < (int)byte.MaxValue) { ++buildingData.m_majorProblemTimer; } float radius = (float)(buildingData.Width + buildingData.Length) * 2.5f; Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Abandonment, 10, buildingData.m_position, radius); } else if ((buildingData.m_flags & Building.Flags.BurnedDown) != Building.Flags.None) { GuideController guideController = Singleton <GuideManager> .instance.m_properties; if (guideController != null) { Singleton <BuildingManager> .instance.m_buildingBurned.Activate(guideController.m_buildingBurned, buildingID); } float radius = (float)(buildingData.Width + buildingData.Length) * 2.5f; Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Abandonment, 10, buildingData.m_position, radius); } else if ((buildingData.m_flags & Building.Flags.Completed) == Building.Flags.None) { bool flag = (buildingData.m_flags & Building.Flags.Upgrading) != Building.Flags.None; int constructionTime = this.GetConstructionTime(); frameData.m_constructState = constructionTime != 0 ? (byte)Mathf.Min((int)byte.MaxValue, (int)frameData.m_constructState + 1088 / constructionTime) : byte.MaxValue; if ((int)frameData.m_constructState == (int)byte.MaxValue) { this.BuildingCompleted(buildingID, ref buildingData); if (Singleton <GuideManager> .instance.m_properties != null) { Singleton <BuildingManager> .instance.m_buildingLevelUp.Deactivate(buildingID, true); } } else if (flag) { GuideController guideController = Singleton <GuideManager> .instance.m_properties; if (guideController != null) { Singleton <BuildingManager> .instance.m_buildingLevelUp.Activate(guideController.m_buildingLevelUp, buildingID); } } if (!flag) { return; } this.SimulationStepActive(buildingID, ref buildingData, ref frameData); } else { this.SimulationStepActive(buildingID, ref buildingData, ref frameData); } }
protected override void CalculateSegmentPosition(ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position nextPosition, PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID, byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed) { NetManager instance = Singleton <NetManager> .instance; instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection((float)offset * 0.003921569f, out pos, out dir); Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData(); Vector3 position2 = lastFrameData.m_position; Vector3 b = instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition((float)prevOffset * 0.003921569f); float num = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking + this.m_info.m_generatedInfo.m_size.z * 0.5f; if (Vector3.Distance(position2, b) >= num - 1f) { Segment3 segment; segment.a = pos; ushort num2; ushort num3; if (offset < position.m_offset) { segment.b = pos + dir.normalized * this.m_info.m_generatedInfo.m_size.z; num2 = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode; num3 = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode; } else { segment.b = pos - dir.normalized * this.m_info.m_generatedInfo.m_size.z; num2 = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode; num3 = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode; } ushort num4; if (prevOffset == 0) { num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode; } else { num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode; } if (num2 == num4) { NetNode.Flags flags = instance.m_nodes.m_buffer[(int)num2].m_flags; NetLane.Flags flags2 = (NetLane.Flags)instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_flags; bool flag = (flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None; bool flag2 = (flags & NetNode.Flags.LevelCrossing) != NetNode.Flags.None; bool flag3 = (flags2 & NetLane.Flags.JoinedJunction) != NetLane.Flags.None; if ((flags & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) == NetNode.Flags.Junction && instance.m_nodes.m_buffer[(int)num2].CountSegments() != 2) { float len = vehicleData.CalculateTotalLength(vehicleID) + 2f; if (!instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(len)) { bool flag4 = false; if (nextPosition.m_segment != 0 && instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_length < 30f) { NetNode.Flags flags3 = instance.m_nodes.m_buffer[(int)num3].m_flags; if ((flags3 & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) != NetNode.Flags.Junction || instance.m_nodes.m_buffer[(int)num3].CountSegments() == 2) { uint laneID2 = PathManager.GetLaneID(nextPosition); if (laneID2 != 0u) { flag4 = instance.m_lanes.m_buffer[(int)((UIntPtr)laneID2)].CheckSpace(len); } } } if (!flag4) { maxSpeed = 0f; return; } } } if (flag && (!flag3 || flag2)) { uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex; uint num5 = (uint)(((int)num4 << 8) / 32768); uint num6 = currentFrameIndex - num5 & 255u; NetInfo info = instance.m_nodes.m_buffer[(int)num2].Info; RoadBaseAI.TrafficLightState vehicleLightState; RoadBaseAI.TrafficLightState pedestrianLightState; bool flag5; bool pedestrians; RoadBaseAI.GetTrafficLightState(num4, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num5, out vehicleLightState, out pedestrianLightState, out flag5, out pedestrians); if (!flag5 && num6 >= 196u) { flag5 = true; RoadBaseAI.SetTrafficLightState(num4, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num5, vehicleLightState, pedestrianLightState, flag5, pedestrians); } if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == 0 || info.m_class.m_service != ItemClass.Service.Road) { switch (vehicleLightState) { case RoadBaseAI.TrafficLightState.RedToGreen: if (num6 < 60u) { maxSpeed = 0f; return; } break; case RoadBaseAI.TrafficLightState.Red: maxSpeed = 0f; return; case RoadBaseAI.TrafficLightState.GreenToRed: if (num6 >= 30u) { maxSpeed = 0f; return; } break; } } } } } NetInfo info2 = instance.m_segments.m_buffer[(int)position.m_segment].Info; if (info2.m_lanes != null && info2.m_lanes.Length > (int)position.m_lane) { maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, LaneManager.GetLaneSpeed(laneID, info2.m_lanes[(int)position.m_lane]), instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve); } else { maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f); } if (instance.m_treatWetAsSnow) { DistrictManager instance2 = Singleton <DistrictManager> .instance; byte district = instance2.GetDistrict(pos); DistrictPolicies.CityPlanning cityPlanningPolicies = instance2.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None) { maxSpeed *= 1f - (float)instance.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.0005882353f; District[] expr_5C2_cp_0 = instance2.m_districts.m_buffer; byte expr_5C2_cp_1 = district; expr_5C2_cp_0[(int)expr_5C2_cp_1].m_cityPlanningPoliciesEffect = (expr_5C2_cp_0[(int)expr_5C2_cp_1].m_cityPlanningPoliciesEffect | DistrictPolicies.CityPlanning.StuddedTires); } else { maxSpeed *= 1f - (float)instance.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.00117647066f; } } else { maxSpeed *= 1f - (float)instance.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.0005882353f; } maxSpeed *= 1f + (float)instance.m_segments.m_buffer[(int)position.m_segment].m_condition * 0.0005882353f; }
public static void SimulationStep(ref ZoneBlock block, ushort blockID) { ZoneManager instance1 = Singleton <ZoneManager> .instance; int rowCount = block.RowCount; Vector2 xDir = new Vector2(Mathf.Cos(block.m_angle), Mathf.Sin(block.m_angle)) * 8f; Vector2 zDir = new Vector2(xDir.y, -xDir.x); ulong num1 = block.m_valid & (ulong)~((long)block.m_occupied1 | (long)block.m_occupied2); int z = 0; ItemClass.Zone zone = ItemClass.Zone.Unzoned; for (int index = 0; index < 4 && zone == ItemClass.Zone.Unzoned; ++index) { z = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)rowCount); if (((long)num1 & 1L << (z << 3)) != 0L) { zone = block.GetZone(0, z); } } DistrictManager instance2 = Singleton <DistrictManager> .instance; byte district1 = instance2.GetDistrict(block.m_position); int num2; switch (zone) { case ItemClass.Zone.ResidentialLow: num2 = instance1.m_actualResidentialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateResidentialLowDemandOffset(); break; case ItemClass.Zone.ResidentialHigh: num2 = instance1.m_actualResidentialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateResidentialHighDemandOffset(); break; case ItemClass.Zone.CommercialLow: num2 = instance1.m_actualCommercialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateCommercialLowDemandOffset(); break; case ItemClass.Zone.CommercialHigh: num2 = instance1.m_actualCommercialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateCommercialHighDemandOffset(); break; case ItemClass.Zone.Industrial: num2 = instance1.m_actualWorkplaceDemand + instance2.m_districts.m_buffer[(int)district1].CalculateIndustrialDemandOffset(); break; case ItemClass.Zone.Office: num2 = instance1.m_actualWorkplaceDemand + instance2.m_districts.m_buffer[(int)district1].CalculateOfficeDemandOffset(); break; default: return; } Vector2 vector2_1 = VectorUtils.XZ(block.m_position); Vector2 vector2_2 = vector2_1 - 3.5f * xDir + ((float)z - 3.5f) * zDir; int[] xBuffer = instance1.m_tmpXBuffer; for (int index = 0; index < 13; ++index) { xBuffer[index] = 0; } Quad2 quad = new Quad2(); quad.a = vector2_1 - 4f * xDir + ((float)z - 10f) * zDir; quad.b = vector2_1 + 3f * xDir + ((float)z - 10f) * zDir; quad.c = vector2_1 + 3f * xDir + ((float)z + 2f) * zDir; quad.d = vector2_1 - 4f * xDir + ((float)z + 2f) * zDir; Vector2 vector2_3 = quad.Min(); Vector2 vector2_4 = quad.Max(); //begin mod int num3 = Mathf.Max((int)(((double)vector2_3.x - 46.0) / 64.0 + FakeZoneManager.HALFGRID), 0); int num4 = Mathf.Max((int)(((double)vector2_3.y - 46.0) / 64.0 + FakeZoneManager.HALFGRID), 0); int num5 = Mathf.Min((int)(((double)vector2_4.x + 46.0) / 64.0 + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1); int num6 = Mathf.Min((int)(((double)vector2_4.y + 46.0) / 64.0 + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1); //end mod for (int index1 = num4; index1 <= num6; ++index1) { for (int index2 = num3; index2 <= num5; ++index2) { //begin mod ushort num7 = instance1.m_zoneGrid[index1 * FakeZoneManager.GRIDSIZE + index2]; //end mod int num8 = 0; while ((int)num7 != 0) { Vector3 vector3 = instance1.m_blocks.m_buffer[(int)num7].m_position; if ((double)Mathf.Max(Mathf.Max(vector2_3.x - 46f - vector3.x, vector2_3.y - 46f - vector3.z), Mathf.Max((float)((double)vector3.x - (double)vector2_4.x - 46.0), (float)((double)vector3.z - (double)vector2_4.y - 46.0))) < 0.0) { //begin mod CheckBlock(ref block, ref instance1.m_blocks.m_buffer[(int)num7], xBuffer, zone, vector2_2, xDir, zDir, quad); } //end mod num7 = instance1.m_blocks.m_buffer[(int)num7].m_nextGridBlock; if (++num8 >= 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace); break; } } } } for (int index = 0; index < 13; ++index) { uint num7 = (uint)xBuffer[index]; int num8 = 0; bool flag1 = ((int)num7 & 196608) == 196608; bool flag2 = false; while (((int)num7 & 1) != 0) { ++num8; flag2 = ((int)num7 & 65536) != 0; num7 >>= 1; } if (num8 == 5 || num8 == 6) { num8 = (!flag2 ? 4 : num8 - (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) + 2)) | 131072; } else if (num8 == 7) { num8 = 4 | 131072; } if (flag1) { num8 |= 65536; } xBuffer[index] = num8; } int num9 = xBuffer[6] & (int)ushort.MaxValue; if (num9 == 0) { return; } //begin mod bool flag3 = IsGoodPlace(ref block, vector2_2); //end mod if (Singleton <SimulationManager> .instance.m_randomizer.Int32(100U) >= num2) { if (!flag3) { return; } instance1.m_goodAreaFound[(int)zone] = (short)1024; } else if (!flag3 && (int)instance1.m_goodAreaFound[(int)zone] > -1024) { if ((int)instance1.m_goodAreaFound[(int)zone] != 0) { return; } instance1.m_goodAreaFound[(int)zone] = (short)-1; } else { int index1 = 6; int index2 = 6; bool flag1 = true; while (true) { if (flag1) { while (index1 != 0 && (xBuffer[index1 - 1] & (int)ushort.MaxValue) == num9) { --index1; } while (index2 != 12 && (xBuffer[index2 + 1] & (int)ushort.MaxValue) == num9) { ++index2; } } else { while (index1 != 0 && (xBuffer[index1 - 1] & (int)ushort.MaxValue) >= num9) { --index1; } while (index2 != 12 && (xBuffer[index2 + 1] & (int)ushort.MaxValue) >= num9) { ++index2; } } int num7 = index1; int num8 = index2; while (num7 != 0 && (xBuffer[num7 - 1] & (int)ushort.MaxValue) >= 2) { --num7; } while (num8 != 12 && (xBuffer[num8 + 1] & (int)ushort.MaxValue) >= 2) { ++num8; } bool flag2 = num7 != 0 && num7 == index1 - 1; bool flag4 = num8 != 12 && num8 == index2 + 1; if (flag2 && flag4) { if (index2 - index1 <= 2) { if (num9 <= 2) { if (!flag1) { goto label_88; } } else { --num9; } } else { break; } } else if (flag2) { if (index2 - index1 <= 1) { if (num9 <= 2) { if (!flag1) { goto label_88; } } else { --num9; } } else { goto label_73; } } else if (flag4) { if (index2 - index1 <= 1) { if (num9 <= 2) { if (!flag1) { goto label_88; } } else { --num9; } } else { goto label_79; } } else if (index1 == index2) { if (num9 <= 2) { if (!flag1) { goto label_88; } } else { --num9; } } else { goto label_88; } flag1 = false; } ++index1; --index2; goto label_88; label_73: ++index1; goto label_88; label_79: --index2; label_88: int index3; int index4; if (num9 == 1 && index2 - index1 >= 1) { index1 += Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)(index2 - index1)); index2 = index1 + 1; index3 = index1 + Singleton <SimulationManager> .instance.m_randomizer.Int32(2U); index4 = index3; } else { do { index3 = index1; index4 = index2; if (index2 - index1 == 2) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0) { --index4; } else { ++index3; } } else if (index2 - index1 == 3) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0) { index4 -= 2; } else { index3 += 2; } } else if (index2 - index1 == 4) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0) { index2 -= 2; index4 -= 3; } else { index1 += 2; index3 += 3; } } else if (index2 - index1 == 5) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0) { index2 -= 3; index4 -= 2; } else { index1 += 3; index3 += 2; } } else if (index2 - index1 >= 6) { if (index1 == 0 || index2 == 12) { if (index1 == 0) { index1 = 3; index3 = 2; } if (index2 == 12) { index2 = 9; index4 = 10; } } else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0) { index2 = index1 + 3; index4 = index3 + 2; } else { index1 = index2 - 3; index3 = index4 - 2; } } }while (index2 - index1 > 3 || index4 - index3 > 3); } int a1 = 4; int num10 = index2 - index1 + 1; BuildingInfo.ZoningMode zoningMode1 = BuildingInfo.ZoningMode.Straight; bool flag5 = true; for (int index5 = index1; index5 <= index2; ++index5) { a1 = Mathf.Min(a1, xBuffer[index5] & (int)ushort.MaxValue); if ((xBuffer[index5] & 131072) == 0) { flag5 = false; } } if (index2 > index1) { if ((xBuffer[index1] & 65536) != 0) { zoningMode1 = BuildingInfo.ZoningMode.CornerLeft; index4 = index1 + index4 - index3; index3 = index1; } if ((xBuffer[index2] & 65536) != 0 && (zoningMode1 != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)) { zoningMode1 = BuildingInfo.ZoningMode.CornerRight; index3 = index2 + index3 - index4; index4 = index2; } } int a2 = 4; int num11 = index4 - index3 + 1; BuildingInfo.ZoningMode zoningMode2 = BuildingInfo.ZoningMode.Straight; bool flag6 = true; for (int index5 = index3; index5 <= index4; ++index5) { a2 = Mathf.Min(a2, xBuffer[index5] & (int)ushort.MaxValue); if ((xBuffer[index5] & 131072) == 0) { flag6 = false; } } if (index4 > index3) { if ((xBuffer[index3] & 65536) != 0) { zoningMode2 = BuildingInfo.ZoningMode.CornerLeft; } if ((xBuffer[index4] & 65536) != 0 && (zoningMode2 != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)) { zoningMode2 = BuildingInfo.ZoningMode.CornerRight; } } ItemClass.SubService subService = ItemClass.SubService.None; ItemClass.Level level = ItemClass.Level.Level1; ItemClass.Service service; switch (zone) { case ItemClass.Zone.ResidentialLow: service = ItemClass.Service.Residential; subService = ItemClass.SubService.ResidentialLow; break; case ItemClass.Zone.ResidentialHigh: service = ItemClass.Service.Residential; subService = ItemClass.SubService.ResidentialHigh; break; case ItemClass.Zone.CommercialLow: service = ItemClass.Service.Commercial; subService = ItemClass.SubService.CommercialLow; break; case ItemClass.Zone.CommercialHigh: service = ItemClass.Service.Commercial; subService = ItemClass.SubService.CommercialHigh; break; case ItemClass.Zone.Industrial: service = ItemClass.Service.Industrial; break; case ItemClass.Zone.Office: service = ItemClass.Service.Office; break; default: return; } BuildingInfo info = (BuildingInfo)null; Vector3 vector3 = Vector3.zero; int num12 = 0; int num13 = 0; int width = 0; BuildingInfo.ZoningMode zoningMode3 = BuildingInfo.ZoningMode.Straight; for (int index5 = 0; index5 < 6; ++index5) { switch (index5) { case 0: if (zoningMode1 != BuildingInfo.ZoningMode.Straight) { num12 = index1 + index2 + 1; num13 = a1; width = num10; zoningMode3 = zoningMode1; goto default; } else { break; } case 1: if (zoningMode2 != BuildingInfo.ZoningMode.Straight) { num12 = index3 + index4 + 1; num13 = a2; width = num11; zoningMode3 = zoningMode2; goto default; } else { break; } case 2: if (zoningMode1 != BuildingInfo.ZoningMode.Straight && a1 >= 4) { num12 = index1 + index2 + 1; num13 = !flag5 ? 2 : 3; width = num10; zoningMode3 = zoningMode1; goto default; } else { break; } case 3: if (zoningMode2 != BuildingInfo.ZoningMode.Straight && a2 >= 4) { num12 = index3 + index4 + 1; num13 = !flag6 ? 2 : 3; width = num11; zoningMode3 = zoningMode2; goto default; } else { break; } case 4: num12 = index1 + index2 + 1; num13 = a1; width = num10; zoningMode3 = BuildingInfo.ZoningMode.Straight; goto default; case 5: num12 = index3 + index4 + 1; num13 = a2; width = num11; zoningMode3 = BuildingInfo.ZoningMode.Straight; goto default; default: vector3 = block.m_position + VectorUtils.X_Y((float)((double)num13 * 0.5 - 4.0) * xDir + (float)((double)num12 * 0.5 + (double)z - 10.0) * zDir); if (zone == ItemClass.Zone.Industrial) { ZoneBlock.GetIndustryType(vector3, out subService, out level); } else if (zone == ItemClass.Zone.CommercialLow || zone == ItemClass.Zone.CommercialHigh) { ZoneBlock.GetCommercialType(vector3, zone, width, num13, out subService, out level); } else if (zone == ItemClass.Zone.ResidentialLow || zone == ItemClass.Zone.ResidentialHigh) { ZoneBlock.GetResidentialType(vector3, zone, width, num13, out subService, out level); } else if (zone == ItemClass.Zone.Office) { ZoneBlock.GetOfficeType(vector3, zone, width, num13, out subService, out level); } byte district2 = instance2.GetDistrict(vector3); ushort style = instance2.m_districts.m_buffer[(int)district2].m_Style; if (Singleton <BuildingManager> .instance.m_BuildingWrapper != null) { Singleton <BuildingManager> .instance.m_BuildingWrapper.OnCalculateSpawn(vector3, ref service, ref subService, ref level, ref style); } info = Singleton <BuildingManager> .instance.GetRandomBuildingInfo(ref Singleton <SimulationManager> .instance.m_randomizer, service, subService, level, width, num13, zoningMode3, (int)style); if (info == null) { break; } goto label_169; } } label_169: if (info == null || (double)Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector3)) > (double)vector3.y || Singleton <DisasterManager> .instance.IsEvacuating(vector3)) { return; } float angle = block.m_angle + 1.570796f; if (zoningMode3 == BuildingInfo.ZoningMode.CornerLeft && info.m_zoningMode == BuildingInfo.ZoningMode.CornerRight) { angle -= 1.570796f; num13 = width; } else if (zoningMode3 == BuildingInfo.ZoningMode.CornerRight && info.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft) { angle += 1.570796f; num13 = width; } ushort building; if (Singleton <BuildingManager> .instance.CreateBuilding(out building, ref Singleton <SimulationManager> .instance.m_randomizer, info, vector3, angle, num13, Singleton <SimulationManager> .instance.m_currentBuildIndex)) { ++Singleton <SimulationManager> .instance.m_currentBuildIndex; switch (service) { case ItemClass.Service.Residential: instance1.m_actualResidentialDemand = Mathf.Max(0, instance1.m_actualResidentialDemand - 5); break; case ItemClass.Service.Commercial: instance1.m_actualCommercialDemand = Mathf.Max(0, instance1.m_actualCommercialDemand - 5); break; case ItemClass.Service.Industrial: instance1.m_actualWorkplaceDemand = Mathf.Max(0, instance1.m_actualWorkplaceDemand - 5); break; case ItemClass.Service.Office: instance1.m_actualWorkplaceDemand = Mathf.Max(0, instance1.m_actualWorkplaceDemand - 5); break; } switch (zone) { case ItemClass.Zone.ResidentialHigh: case ItemClass.Zone.CommercialHigh: Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)building].m_flags |= Building.Flags.HighDensity; break; } } instance1.m_goodAreaFound[(int)zone] = (short)1024; } }
public override void OnAfterSimulationFrame() { if (!LoadingExtension.installed) { return; } if (s_info == null) { return; } BuildingManager instance = Singleton <BuildingManager> .instance; int num6 = (int)(Singleton <SimulationManager> .instance.m_currentFrameIndex & 255u); ushort minBuildingID = (ushort)(num6 * 192); ushort maxBuildingID = (ushort)((num6 + 1) * 192 - 1); //check if building should be added as part of a resilient district DistrictManager instance2 = Singleton <DistrictManager> .instance; for (ushort i = minBuildingID; i < maxBuildingID; i++) { if (instance.m_buildings.m_buffer[i].m_flags == Building.Flags.None) { continue; } Building build = instance.m_buildings.m_buffer[i]; byte districtID = instance2.GetDistrict(build.m_position); int districtIndex = s_info.GetResilientDistrictIndex(districtID); if (districtIndex != -1) { if (s_info.m_districts[districtIndex].unsuscribed) { //s_info.RemoveBuilding(i); s_info.UnsuscribeBuilding(i); } else if (s_info.m_districts[districtIndex].resiliencyActivated) { bool newly_added = s_info.AddBuilding(i, true); if (newly_added) { ResilientBuildings.ResilientDistrict rd = s_info.m_districts[districtIndex]; rd.totalBuildings++; s_info.m_districts[districtIndex] = rd; } } } } //districts timers for (int i = 0; i < s_info.m_districts.Count; i++) { if (s_info.m_districts[i].unsuscribed) { ResilientBuildings.ResilientDistrict rd = s_info.m_districts[i]; rd.unsuscribeTimer++; s_info.m_districts[i] = rd; if (rd.unsuscribeTimer > REMOVE_DISTRICT_AFTER_UPDATES) { s_info.RemoveDistrict(rd.districtID); } } } //check all buildings in resilients list for (int i = 0; i < s_info.m_resilients.Count; i++) { ushort buildingID = s_info.m_resilients[i].buildingID; //sync with buildManager, update only buildings that just had a SimulationStep if (buildingID < minBuildingID || buildingID >= maxBuildingID) { continue; } ResilientBuildings.ResilientInfoV1 build = s_info.m_resilients[i]; if (s_info.m_resilients[i].unsuscribed) //building unsuscribed { build.unsuscribeTimer++; if (build.unsuscribeTimer > REMOVE_AFTER_UPDATES) { s_info.m_resilients.RemoveAt(i); i--; continue; } s_info.m_resilients[i] = build; continue; } if (instance.m_buildings.m_buffer[buildingID].m_flags == Building.Flags.None) //building was bulldozed, remove it from the list { s_info.m_resilients.RemoveAt(i); i--; continue; } //update infos BuildingInfo buildinfo = Singleton <BuildingManager> .instance.m_buildings.m_buffer[buildingID].Info; if (buildinfo.m_class.m_service == ItemClass.Service.Residential) { s_info.UpdateResidentFamilies(i); } else { s_info.UpdateWorkers(i); if (buildinfo.m_class.m_service == ItemClass.Service.Commercial) { s_info.UpdateVisitsCount(i); } else if (buildinfo.m_class.m_service == ItemClass.Service.Industrial) { if (buildinfo.m_buildingAI.GetType().Equals(typeof(IndustrialExtractorAI))) { s_info.UpdatePrimaryResourceExport(i); } else if (buildinfo.m_buildingAI.GetType().Equals(typeof(IndustrialBuildingAI))) { s_info.UpdateGoodsExport(i); } } } if (build.resiliencyActivated) { //instance.m_buildings.m_buffer[buildingID].m_electricityProblemTimer = 0; //instance.m_buildings.m_buffer[buildingID].m_majorProblemTimer = 0; //instance.m_buildings.m_buffer[buildingID].m_problems = Notification.Problem.TurnedOff; //building will not be removed when dezoning, it must be bulldozed //instance.m_buildings.m_buffer[buildingID].m_flags &= ~Building.Flags.ZonesUpdated; //avoid major problem to trigger abandonment instance.m_buildings.m_buffer[buildingID].m_majorProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_problems &= ~Notification.Problem.MajorProblem; //lower cap on unhappiness if problems if (instance.m_buildings.m_buffer[buildingID].m_problems != Notification.Problem.None) { instance.m_buildings.m_buffer[buildingID].m_happiness = 60; } //reoccupy building when it is abandoned/burned down if ((instance.m_buildings.m_buffer[buildingID].m_flags & (Building.Flags.Abandoned | Building.Flags.BurnedDown)) != Building.Flags.None) { //reset timers instance.m_buildings.m_buffer[buildingID].m_electricityProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_waterProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_majorProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_deathProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_serviceProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_taxProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_outgoingProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_incomingProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_heatingProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_healthProblemTimer = 0; instance.m_buildings.m_buffer[buildingID].m_workerProblemTimer = 0; //reset buffers instance.m_buildings.m_buffer[buildingID].m_crimeBuffer = 0; instance.m_buildings.m_buffer[buildingID].m_customBuffer1 = 0; instance.m_buildings.m_buffer[buildingID].m_customBuffer2 = 0; instance.m_buildings.m_buffer[buildingID].m_electricityBuffer = 0; instance.m_buildings.m_buffer[buildingID].m_heatingBuffer = 0; instance.m_buildings.m_buffer[buildingID].m_garbageBuffer = 0; instance.m_buildings.m_buffer[buildingID].m_sewageBuffer = 0; instance.m_buildings.m_buffer[buildingID].m_waterBuffer = 0; //renovate building Building.Frame carpentry = instance.m_buildings.m_buffer[buildingID].GetLastFrameData(); carpentry.m_constructState /= 2; carpentry.m_fireDamage = 0; instance.m_buildings.m_buffer[buildingID].SetFrameData(Singleton <SimulationManager> .instance.m_currentFrameIndex, carpentry); //repopulate building instance.m_buildings.m_buffer[buildingID].m_flags = Building.Flags.Created; instance.m_buildings.m_buffer[buildingID].Info.m_buildingAI.CreateBuilding(buildingID, ref instance.m_buildings.m_buffer[buildingID]); //user feedback : remove notification instance.m_buildings.m_buffer[buildingID].m_problems = Notification.Problem.None; } if (instance.m_buildings.m_buffer[buildingID].GetLastFrameData().m_fireDamage > 230 && Settings.inst.extinguishFires) //extinguish fire at last minute { instance.m_buildings.m_buffer[buildingID].m_fireIntensity = 0; // Building.Frame carpentry = instance.m_buildings.m_buffer[buildingID].GetLastFrameData(); // carpentry.m_fireDamage = 0; // instance.m_buildings.m_buffer[buildingID].SetFrameData(Singleton<SimulationManager>.instance.m_currentFrameIndex+1, carpentry); } } s_UI.CheckUpdateUI(buildingID); } }
public District GetDistrict(long id) { return(_districtManagerManager.GetDistrict(id)); }
public static void SimulationStepActive(CommercialBuildingAI thisAI, ushort buildingID, ref Building buildingData, ref Building.Frame frameData) { //This is a mess because I pulled it directly from the decompiled code and patched it up slightly. //It works though, and that's all I'm bothered about for now. if (thisAI) { DistrictManager instance1 = Singleton <DistrictManager> .instance; byte district = instance1.GetDistrict(buildingData.m_position); DistrictPolicies.Services policies = instance1.m_districts.m_buffer[(int)district].m_servicePolicies; DistrictPolicies.Taxation taxationPolicies = instance1.m_districts.m_buffer[(int)district].m_taxationPolicies; DistrictPolicies.CityPlanning cityPlanningPolicies = instance1.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; instance1.m_districts.m_buffer[(int)district].m_servicePoliciesEffect |= policies & (DistrictPolicies.Services.PowerSaving | DistrictPolicies.Services.WaterSaving | DistrictPolicies.Services.SmokeDetectors | DistrictPolicies.Services.Recycling | DistrictPolicies.Services.RecreationalUse | DistrictPolicies.Services.ExtraInsulation | DistrictPolicies.Services.NoElectricity | DistrictPolicies.Services.OnlyElectricity); switch (thisAI.m_info.m_class.m_subService) { case ItemClass.SubService.CommercialLow: if ((taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComLow | DistrictPolicies.Taxation.TaxLowerComLow)) != (DistrictPolicies.Taxation.TaxRaiseComLow | DistrictPolicies.Taxation.TaxLowerComLow)) { instance1.m_districts.m_buffer[(int)district].m_taxationPoliciesEffect |= taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComLow | DistrictPolicies.Taxation.TaxLowerComLow); } instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.SmallBusiness; break; case ItemClass.SubService.CommercialHigh: if ((taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComHigh | DistrictPolicies.Taxation.TaxLowerComHigh)) != (DistrictPolicies.Taxation.TaxRaiseComHigh | DistrictPolicies.Taxation.TaxLowerComHigh)) { instance1.m_districts.m_buffer[(int)district].m_taxationPoliciesEffect |= taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComHigh | DistrictPolicies.Taxation.TaxLowerComHigh); } instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.BigBusiness; break; case ItemClass.SubService.CommercialLeisure: instance1.m_districts.m_buffer[(int)district].m_taxationPoliciesEffect |= taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure; instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises; break; case ItemClass.SubService.CommercialTourist: instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.LightningRods; break; } Citizen.BehaviourData behaviour = new Citizen.BehaviourData(); int aliveWorkerCount = 0; int totalWorkerCount = 0; int workPlaceCount = 0; int num1 = NewPrivateBuildingAI.HandleWorkers(thisAI, buildingID, ref buildingData, ref behaviour, ref aliveWorkerCount, ref totalWorkerCount, ref workPlaceCount); if ((buildingData.m_flags & Building.Flags.Evacuating) != Building.Flags.None) { num1 = 0; } int width = buildingData.Width; int length = buildingData.Length; int num2 = MaxIncomingLoadSize(thisAI); int aliveCount = 0; int totalCount = 0; GetVisitBehaviour(thisAI, buildingID, ref buildingData, ref behaviour, ref aliveCount, ref totalCount); int visitCount = thisAI.CalculateVisitplaceCount(new Randomizer((int)buildingID), width, length); int num3 = Mathf.Max(0, visitCount - totalCount); int a1 = visitCount * 500; int num4 = Mathf.Max(a1, num2 * 4); TransferManager.TransferReason incomingTransferReason = GetIncomingTransferReason(thisAI); TransferManager.TransferReason outgoingTransferReason = GetOutgoingTransferReason(thisAI, buildingID); if (num1 != 0) { int num5 = num4; if (incomingTransferReason != TransferManager.TransferReason.None) { num5 = Mathf.Min(num5, (int)buildingData.m_customBuffer1); } if (outgoingTransferReason != TransferManager.TransferReason.None) { num5 = Mathf.Min(num5, num4 - (int)buildingData.m_customBuffer2); } int num6 = Mathf.Max(0, Mathf.Min(num1, (num5 * 200 + num4 - 1) / num4)); int a2 = (visitCount * num6 + 9) / 10; if (Singleton <SimulationManager> .instance.m_isNightTime) { a2 = a2 + 1 >> 1; } int num7 = Mathf.Max(0, Mathf.Min(a2, num5)); if (incomingTransferReason != TransferManager.TransferReason.None) { buildingData.m_customBuffer1 -= (ushort)num7; } if (outgoingTransferReason != TransferManager.TransferReason.None) { buildingData.m_customBuffer2 += (ushort)num7; } num1 = (num7 + 9) / 10; } int electricityConsumption; int waterConsumption; int sewageAccumulation; int garbageAccumulation; int incomeAccumulation; thisAI.GetConsumptionRates(new Randomizer((int)buildingID), num1, out electricityConsumption, out waterConsumption, out sewageAccumulation, out garbageAccumulation, out incomeAccumulation); int heatingConsumption = 0; if (electricityConsumption != 0 && instance1.IsPolicyLoaded(DistrictPolicies.Policies.ExtraInsulation)) { if ((policies & DistrictPolicies.Services.ExtraInsulation) != DistrictPolicies.Services.None) { heatingConsumption = Mathf.Max(1, electricityConsumption * 3 + 8 >> 4); incomeAccumulation = incomeAccumulation * 95 / 100; } else { heatingConsumption = Mathf.Max(1, electricityConsumption + 2 >> 2); } } if (garbageAccumulation != 0 && (policies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None) { garbageAccumulation = Mathf.Max(1, garbageAccumulation * 85 / 100); incomeAccumulation = incomeAccumulation * 95 / 100; } int taxRate; switch (thisAI.m_info.m_class.m_subService) { case ItemClass.SubService.CommercialLeisure: taxRate = (buildingData.m_flags & Building.Flags.HighDensity) == Building.Flags.None ? Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialLow, thisAI.m_info.m_class.m_level, taxationPolicies) : Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialHigh, thisAI.m_info.m_class.m_level, taxationPolicies); if ((taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure) != DistrictPolicies.Taxation.None) { taxRate = 0; } if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises) != DistrictPolicies.CityPlanning.None && Singleton <SimulationManager> .instance.m_isNightTime) { electricityConsumption = electricityConsumption + 1 >> 1; waterConsumption = waterConsumption + 1 >> 1; sewageAccumulation = sewageAccumulation + 1 >> 1; garbageAccumulation = garbageAccumulation + 1 >> 1; incomeAccumulation = 0; break; } break; case ItemClass.SubService.CommercialTourist: taxRate = (buildingData.m_flags & Building.Flags.HighDensity) == Building.Flags.None ? Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialLow, thisAI.m_info.m_class.m_level, taxationPolicies) : Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialHigh, thisAI.m_info.m_class.m_level, taxationPolicies); break; default: taxRate = Singleton <EconomyManager> .instance.GetTaxRate(thisAI.m_info.m_class, taxationPolicies); break; } if (num1 != 0) { int num5 = HandleCommonConsumption(thisAI, buildingID, ref buildingData, ref frameData, ref electricityConsumption, ref heatingConsumption, ref waterConsumption, ref sewageAccumulation, ref garbageAccumulation, policies); num1 = (num1 * num5 + 99) / 100; if (num1 != 0) { int amount1 = incomeAccumulation; if (amount1 != 0) { if (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialLow) { if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.SmallBusiness) != DistrictPolicies.CityPlanning.None) { Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 12, thisAI.m_info.m_class); amount1 *= 2; } } else if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BigBusiness) != DistrictPolicies.CityPlanning.None) { Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 25, thisAI.m_info.m_class); amount1 *= 3; } if ((policies & DistrictPolicies.Services.RecreationalUse) != DistrictPolicies.Services.None) { amount1 = (amount1 * 105 + 99) / 100; } int num6 = Singleton <EconomyManager> .instance.AddPrivateIncome(amount1, ItemClass.Service.Commercial, thisAI.m_info.m_class.m_subService, thisAI.m_info.m_class.m_level, taxRate); int amount2 = (behaviour.m_touristCount * num6 + (aliveCount >> 1)) / Mathf.Max(1, aliveCount); int amount3 = Mathf.Max(0, num6 - amount2); if (amount3 != 0) { Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.CitizenIncome, amount3, thisAI.m_info.m_class); } if (amount2 != 0) { Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.TourismIncome, amount2, thisAI.m_info.m_class); } } int groundPollution; int noisePollution; thisAI.GetPollutionRates(num1, cityPlanningPolicies, out groundPollution, out noisePollution); if (groundPollution != 0 && Singleton <SimulationManager> .instance.m_randomizer.Int32(3U) == 0) { Singleton <NaturalResourceManager> .instance.TryDumpResource(NaturalResourceManager.Resource.Pollution, groundPollution, groundPollution, buildingData.m_position, 60f); } if (noisePollution != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, noisePollution, buildingData.m_position, 60f); } if (num5 < 100) { buildingData.m_flags |= Building.Flags.RateReduced; } else { buildingData.m_flags &= ~Building.Flags.RateReduced; } buildingData.m_flags |= Building.Flags.Active; } else { buildingData.m_flags &= ~(Building.Flags.RateReduced | Building.Flags.Active); } } else { electricityConsumption = 0; heatingConsumption = 0; waterConsumption = 0; sewageAccumulation = 0; garbageAccumulation = 0; buildingData.m_problems = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.Electricity | Notification.Problem.Water | Notification.Problem.Sewage | Notification.Problem.Flood | Notification.Problem.Heating); buildingData.m_flags &= ~(Building.Flags.RateReduced | Building.Flags.Active); } int health = 0; int wellbeing = 0; float radius = (float)(buildingData.Width + buildingData.Length) * 2.5f; if (behaviour.m_healthAccumulation != 0) { if (aliveWorkerCount + aliveCount != 0) { health = (behaviour.m_healthAccumulation + (aliveWorkerCount + aliveCount >> 1)) / (aliveWorkerCount + aliveCount); } Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Health, behaviour.m_healthAccumulation, buildingData.m_position, radius); } if (behaviour.m_wellbeingAccumulation != 0) { if (aliveWorkerCount + aliveCount != 0) { wellbeing = (behaviour.m_wellbeingAccumulation + (aliveWorkerCount + aliveCount >> 1)) / (aliveWorkerCount + aliveCount); } Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Wellbeing, behaviour.m_wellbeingAccumulation, buildingData.m_position, radius); } int num8 = Citizen.GetHappiness(health, wellbeing) * 15 / 100; int a3 = aliveWorkerCount * 20 / workPlaceCount; if ((buildingData.m_problems & Notification.Problem.MajorProblem) == Notification.Problem.None) { num8 += 20; } if (buildingData.m_problems == Notification.Problem.None) { num8 += 25; } int num9 = num8 + Mathf.Min(a3, (int)buildingData.m_customBuffer1 * a3 / num4) + (a3 - Mathf.Min(a3, (int)buildingData.m_customBuffer2 * a3 / num4)); int num10 = (int)(8 - thisAI.m_info.m_class.m_level); int num11 = (int)(11 - thisAI.m_info.m_class.m_level); if (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialHigh) { ++num10; ++num11; } if (taxRate < num10) { num9 += num10 - taxRate; } if (taxRate > num11) { num9 -= taxRate - num11; } if (taxRate >= num11 + 4) { if ((int)buildingData.m_taxProblemTimer != 0 || Singleton <SimulationManager> .instance.m_randomizer.Int32(32U) == 0) { int num5 = taxRate - num11 >> 2; buildingData.m_taxProblemTimer = (byte)Mathf.Min((int)byte.MaxValue, (int)buildingData.m_taxProblemTimer + num5); if ((int)buildingData.m_taxProblemTimer >= 96) { buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.TaxesTooHigh | Notification.Problem.MajorProblem); } else if ((int)buildingData.m_taxProblemTimer >= 32) { buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.TaxesTooHigh); } } } else { buildingData.m_taxProblemTimer = (byte)Mathf.Max(0, (int)buildingData.m_taxProblemTimer - 1); buildingData.m_problems = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.TaxesTooHigh); } int entertainment; int attractiveness; GetAccumulation(thisAI, new Randomizer((int)buildingID), num1, taxRate, cityPlanningPolicies, taxationPolicies, out entertainment, out attractiveness); if (entertainment != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Entertainment, entertainment, buildingData.m_position, radius); } if (attractiveness != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Attractiveness, attractiveness); } int happiness = Mathf.Clamp(num9, 0, 100); buildingData.m_health = (byte)health; buildingData.m_happiness = (byte)happiness; buildingData.m_citizenCount = (byte)(aliveWorkerCount + aliveCount); HandleDead(thisAI, buildingID, ref buildingData, ref behaviour, totalWorkerCount + totalCount); int crimeAccumulation = behaviour.m_crimeAccumulation / 10; if (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialLeisure) { crimeAccumulation = crimeAccumulation * 5 + 3 >> 2; } if ((policies & DistrictPolicies.Services.RecreationalUse) != DistrictPolicies.Services.None) { crimeAccumulation = crimeAccumulation * 3 + 3 >> 2; } HandleCrime(thisAI, buildingID, ref buildingData, crimeAccumulation, (int)buildingData.m_citizenCount); int num12 = (int)buildingData.m_crimeBuffer; if (aliveWorkerCount != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Density, aliveWorkerCount, buildingData.m_position, radius); int num5 = (behaviour.m_educated0Count * 100 + behaviour.m_educated1Count * 50 + behaviour.m_educated2Count * 30) / aliveWorkerCount + 50; buildingData.m_fireHazard = (byte)num5; } else { buildingData.m_fireHazard = (byte)0; } int crimeRate = (int)buildingData.m_citizenCount == 0 ? 0 : (num12 + ((int)buildingData.m_citizenCount >> 1)) / (int)buildingData.m_citizenCount; int count = 0; int cargo = 0; int capacity = 0; int outside = 0; if (incomingTransferReason != TransferManager.TransferReason.None) { CalculateGuestVehicles(thisAI, buildingID, ref buildingData, incomingTransferReason, ref count, ref cargo, ref capacity, ref outside); buildingData.m_tempImport = (byte)Mathf.Clamp(outside, (int)buildingData.m_tempImport, (int)byte.MaxValue); } buildingData.m_tempExport = (byte)Mathf.Clamp(behaviour.m_touristCount, (int)buildingData.m_tempExport, (int)byte.MaxValue); SimulationManager _simulationManager = Singleton <SimulationManager> .instance; if ((long)((_simulationManager.m_currentFrameIndex & 3840U) >> 8) == (long)((int)buildingID & 15) && (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialLow || thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialHigh) && ((int)Singleton <ZoneManager> .instance.m_lastBuildIndex == (int)_simulationManager.m_currentBuildIndex && (buildingData.m_flags & Building.Flags.Upgrading) == Building.Flags.None)) { CheckBuildingLevel(thisAI, buildingID, ref buildingData, ref frameData, ref behaviour, aliveCount); } if ((buildingData.m_flags & (Building.Flags.Completed | Building.Flags.Upgrading)) == Building.Flags.None) { return; } Notification.Problem problems1 = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoCustomers | Notification.Problem.NoGoods); //Begin edited section if ((int)buildingData.m_customBuffer2 > num4 - (a1 >> 1) && aliveCount <= visitCount >> 1) { if (_simulationManager.m_currentDayTimeHour > 19 && _simulationManager.m_currentDayTimeHour < 20) { buildingData.m_outgoingProblemTimer = (byte)Mathf.Min(byte.MaxValue, buildingData.m_outgoingProblemTimer + 1); if (buildingData.m_outgoingProblemTimer >= 192) { problems1 = Notification.AddProblems(problems1, Notification.Problem.NoCustomers | Notification.Problem.MajorProblem); } else if (buildingData.m_outgoingProblemTimer >= 128) { problems1 = Notification.AddProblems(problems1, Notification.Problem.NoCustomers); } } else { buildingData.m_outgoingProblemTimer = 0; } } else { buildingData.m_outgoingProblemTimer = (byte)0; } if (!CityEventManager.instance.EventStartsWithin(3D) && !CityEventManager.instance.EventTakingPlace() && !CityEventManager.instance.EventJustEnded()) { if ((int)buildingData.m_customBuffer1 == 0) { buildingData.m_incomingProblemTimer = (byte)Mathf.Min((int)byte.MaxValue, (int)buildingData.m_incomingProblemTimer + 1); problems1 = (int)buildingData.m_incomingProblemTimer >= 64 ? Notification.AddProblems(problems1, Notification.Problem.NoGoods | Notification.Problem.MajorProblem) : Notification.AddProblems(problems1, Notification.Problem.NoGoods); } else { buildingData.m_incomingProblemTimer = (byte)0; } float currentHour = _simulationManager.m_currentDayTimeHour; //Artifically shop at night to keep industry happy. Will give the effect of industry stocking up commercial over night. //Note: ModifyMaterialBuffer is expensive, so if there's any performance impact with the mod now, it'll most likely be this. if ((currentHour > 20f || currentHour < 4f)) { if (_simulationManager.m_randomizer.Int32(80) < 2) { //Simulate 2 people buying things int amount = -200; thisAI.ModifyMaterialBuffer(buildingID, ref buildingData, TransferManager.TransferReason.Shopping, ref amount); } } else if (Experiments.ExperimentsToggle.AllowActiveCommercialFix && _simulationManager.m_randomizer.Int32(40) < 5) //Added in as a potential fix to random inactive buildings. Lack of customers still shuts down commercial. { int amount = -50; thisAI.ModifyMaterialBuffer(buildingID, ref buildingData, TransferManager.TransferReason.Shopping, ref amount); } } else { buildingData.m_incomingProblemTimer = 0; } //End edited section buildingData.m_problems = problems1; instance1.m_districts.m_buffer[(int)district].AddCommercialData(ref behaviour, health, happiness, crimeRate, workPlaceCount, aliveWorkerCount, Mathf.Max(0, workPlaceCount - totalWorkerCount), visitCount, aliveCount, num3, (int)thisAI.m_info.m_class.m_level, electricityConsumption, heatingConsumption, waterConsumption, sewageAccumulation, garbageAccumulation, incomeAccumulation, Mathf.Min(100, (int)buildingData.m_garbageBuffer / 50), (int)buildingData.m_waterPollution * 100 / (int)byte.MaxValue, (int)buildingData.m_finalImport, (int)buildingData.m_finalExport, thisAI.m_info.m_class.m_subService); if ((int)buildingData.m_fireIntensity == 0 && incomingTransferReason != TransferManager.TransferReason.None) { int num5 = num4 - (int)buildingData.m_customBuffer1 - capacity - (num2 >> 1); if (num5 >= 0) { Singleton <TransferManager> .instance.AddIncomingOffer(incomingTransferReason, new TransferManager.TransferOffer() { Priority = num5 * 8 / num2, Building = buildingID, Position = buildingData.m_position, Amount = 1, Active = false }); } } if ((int)buildingData.m_fireIntensity == 0 && outgoingTransferReason != TransferManager.TransferReason.None) { int num5 = (int)buildingData.m_customBuffer2 - aliveCount * 100; if (num5 >= 100 && num3 > 0) { Singleton <TransferManager> .instance.AddOutgoingOffer(outgoingTransferReason, new TransferManager.TransferOffer() { Priority = Mathf.Max(1, num5 * 8 / num4), Building = buildingID, Position = buildingData.m_position, Amount = Mathf.Min(num5 / 100, num3), Active = false }); } } PrivateBuildingAI baseAI = thisAI as PrivateBuildingAI; //Because we don't have access to base here. if (baseAI != null) { NewPrivateBuildingAI.SimulationStepActive(baseAI, buildingID, ref buildingData, ref frameData); } HandleFire(thisAI, buildingID, ref buildingData, ref frameData, policies); } else { Debug.LogError("Commercial building " + buildingID + " has no AI! This could have been bad."); } }
protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, int finalProductionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount) { DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(buildingData.m_position); DistrictPolicies.Services servicePolicies = instance.m_districts.m_buffer[(int)district].m_servicePolicies; Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.WaterNotConnected | Notification.Problem.NoResources | Notification.Problem.NoNaturalResources | Notification.Problem.FishFarmWaterDirty | Notification.Problem.NoPlaceForFishingGoods); int num = 0; int num2 = 0; int num3 = 0; if (this.m_extractionPositions != null && this.m_extractionPositions.Length > 0) { for (int i = 0; i < this.m_extractionPositions.Length; i++) { Vector3 position = buildingData.CalculatePosition(this.m_extractionPositions[i]); int b; int num4; int value; Singleton <TerrainManager> .instance.CountWaterCoverage(position, 20f, out b, out num4, out value); num += Mathf.Clamp(value, 0, 128); num3 = Mathf.Max(num3, b); } if (this.m_info.name == "Algae Tank") { this.m_info.m_placementMode = BuildingInfo.PlacementMode.Roadside; num2 = 0; num3 = 1; } else { num2 = num / this.m_extractionPositions.Length; } } else { finalProductionRate = 0; } if (num2 > 32) { GuideController properties = Singleton <GuideManager> .instance.m_properties; if (properties != null) { Singleton <BuildingManager> .instance.m_fishingPollutionDetected.Activate(properties.m_fishingPollutionDetected, buildingID); } } if (num3 == 0) { finalProductionRate = 0; } if (finalProductionRate != 0) { int num5 = finalProductionRate; if (num2 > 96) { problem = (Notification.Problem.FishFarmWaterDirty | Notification.Problem.FatalProblem); } else if (num2 > 64) { problem = Notification.AddProblems(problem, Notification.Problem.FishFarmWaterDirty | Notification.Problem.MajorProblem); } else if (num2 > 32) { problem = Notification.AddProblems(problem, Notification.Problem.FishFarmWaterDirty); } finalProductionRate = finalProductionRate * Mathf.Clamp(255 - num2 * 2, 0, 255) / 255; int num6 = finalProductionRate * this.m_noiseAccumulation / 100; if (num6 != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num6, buildingData.m_position, this.m_noiseRadius); } base.HandleDead(buildingID, ref buildingData, ref behaviour, totalWorkerCount); int num7 = 0; int num8 = 0; if (this.m_outputResource != TransferManager.TransferReason.None) { int num9 = (this.m_productionRate * finalProductionRate + 99) / 100; if (this.m_info.m_class.m_level == ItemClass.Level.Level3 && (servicePolicies & DistrictPolicies.Services.AlgaeBasedWaterFiltering) != DistrictPolicies.Services.None) { District[] buffer = instance.m_districts.m_buffer; byte b2 = district; buffer[(int)b2].m_servicePoliciesEffect = (buffer[(int)b2].m_servicePoliciesEffect | DistrictPolicies.Services.AlgaeBasedWaterFiltering); num9 = (num9 * 50 + 49) / 100; } int cycleBufferSize = this.GetCycleBufferSize(buildingID, ref buildingData); int num10 = (int)buildingData.m_customBuffer1; num7 = this.GetStorageBufferSize(buildingID, ref buildingData); num8 = (int)(buildingData.m_customBuffer2 * 100); if (num9 >= cycleBufferSize - num10) { if (cycleBufferSize > num7 - num8) { num9 = cycleBufferSize - num10; num10 = cycleBufferSize; problem = Notification.AddProblems(problem, Notification.Problem.NoPlaceForFishingGoods); } else { num10 = num10 + num9 - cycleBufferSize; num8 += cycleBufferSize; } } else { num10 += num9; } Singleton <StatisticsManager> .instance.Acquire <StatisticInt64>(StatisticType.FishFarmed).Add(num9); buildingData.m_customBuffer1 = (ushort)num10; buildingData.m_customBuffer2 = (ushort)(num8 / 100); } if (this.m_outputResource != TransferManager.TransferReason.None) { int num11 = (num5 * this.m_outputVehicleCount + 99) / 100; int num12 = 0; int num13 = 0; int num14 = 0; int value2 = 0; base.CalculateOwnVehicles(buildingID, ref buildingData, this.m_outputResource, ref num12, ref num13, ref num14, ref value2); buildingData.m_tempExport = (byte)Mathf.Clamp(value2, (int)buildingData.m_tempExport, 255); if (buildingData.m_finalExport != 0) { District[] buffer2 = instance.m_districts.m_buffer; byte b3 = district; buffer2[(int)b3].m_playerConsumption.m_finalExportAmount = buffer2[(int)b3].m_playerConsumption.m_finalExportAmount + (uint)buildingData.m_finalExport; } int num15 = num8; if (num15 >= 8000 && num12 < num11) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = Mathf.Max(1, num15 * 8 / num7); offer.Building = buildingID; offer.Position = buildingData.m_position; offer.Amount = 1; offer.Active = true; Singleton <TransferManager> .instance.AddOutgoingOffer(this.m_outputResource, offer); } } } buildingData.m_problems = problem; buildingData.m_education3 = (byte)Mathf.Clamp(finalProductionRate * this.m_productionRate / Mathf.Max(1, this.m_productionRate), 0, 255); base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount); }
public static bool RenderPropsPrefix(BuildingAI __instance, RenderManager.CameraInfo cameraInfo, ushort buildingID, ref Building data, int layerMask, ref RenderManager.Instance instance, bool renderFixed, bool renderNonfixed, bool isActive) { if (__instance.m_info.m_props == null || ((layerMask & __instance.m_info.m_treeLayers) == 0 && !cameraInfo.CheckRenderDistance(instance.m_position, __instance.m_info.m_maxPropDistance + 72f))) { return(false); } int length = data.Length; Texture _HeightMap = null; Vector4 _HeightMapping = Vector4.zero; Vector4 _SurfaceMapping = Vector4.zero; Matrix4x4 lhs = Matrix4x4.zero; bool flag = false; DistrictManager instance2 = Singleton <DistrictManager> .instance; byte district = instance2.GetDistrict(data.m_position); Vector3 position = data.m_position; ushort num = Building.FindParentBuilding(buildingID); if (num != 0) { position = Singleton <BuildingManager> .instance.m_buildings.m_buffer[num].m_position; } byte park = instance2.GetPark(position); for (int i = 0; i < __instance.m_info.m_props.Length; i++) { BuildingInfo.Prop prop = __instance.m_info.m_props[i]; Randomizer r = new Randomizer((buildingID << 6) | prop.m_index); if (r.Int32(100u) >= prop.m_probability || length < prop.m_requiredLength) { continue; } PropInfo finalProp = prop.m_finalProp; TreeInfo finalTree = prop.m_finalTree; if (finalProp != null) { finalProp = finalProp.GetVariation(ref r, ref instance2.m_districts.m_buffer[district], park); float num2 = finalProp.m_minScale + (float)r.Int32(10000u) * (finalProp.m_maxScale - finalProp.m_minScale) * 0.0001f; Color color = finalProp.GetColor(ref r); if ((layerMask & (1 << finalProp.m_prefabDataLayer)) == 0 && !finalProp.m_hasEffects) { continue; } Vector4 dataVector = instance.m_dataVector3; Vector3 vector; if (prop.m_fixedHeight) { if (!renderFixed) { continue; } if (__instance.m_info.m_isFloating) { if (!flag) { Singleton <TerrainManager> .instance.HeightMap_sampleWaterHeightAndNormal(instance.m_position, 0.15f, out float h, out Vector3 normal); Vector3 position2 = instance.m_position; position2.y = h; Quaternion q = Quaternion.FromToRotation(Vector3.up, normal) * instance.m_rotation; lhs = Matrix4x4.TRS(position2, q, Vector3.one); flag = true; } Matrix4x4 rhs = default(Matrix4x4); rhs.SetTRS(prop.m_position, Quaternion.AngleAxis(prop.m_radAngle * 57.29578f, Vector3.down), new Vector3(num2, num2, num2)); rhs = lhs * rhs; vector = rhs.MultiplyPoint(Vector3.zero); if (cameraInfo.CheckRenderDistance(vector, finalProp.m_maxRenderDistance)) { InstanceID propRenderID = GetPropRenderIDReverse(__instance, buildingID, i, ref data); PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID, rhs, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive); continue; } } else { vector = instance.m_dataMatrix1.MultiplyPoint(prop.m_position); if (__instance.m_info.m_requireHeightMap) { vector.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f; } } } else { if (!renderNonfixed) { continue; } vector = instance.m_dataMatrix1.MultiplyPoint(prop.m_position); if (!__instance.m_info.m_isFloating) { vector.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f; } if (!__instance.m_info.m_colorizeEverything || finalProp.m_isDecal) { dataVector.z = 0f; } } if (!cameraInfo.CheckRenderDistance(vector, finalProp.m_maxRenderDistance)) { continue; } InstanceID propRenderID2 = GetPropRenderIDReverse(__instance, buildingID, i, ref data); if (finalProp.m_requireWaterMap) { if (_HeightMap == null) { Singleton <TerrainManager> .instance.GetWaterMapping(data.m_position, out _HeightMap, out _HeightMapping, out _SurfaceMapping); } #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, localData.m_angle + prop.m_radAngle, color, dataVector, isActive, localInstance.m_dataTexture0, localInstance.m_dataVector1, localInstance.m_dataVector2, _HeightMap, _HeightMapping, _SurfaceMapping)); #else PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive, instance.m_dataTexture0, instance.m_dataVector1, instance.m_dataVector2, _HeightMap, _HeightMapping, _SurfaceMapping); #endif } else if (finalProp.m_requireHeightMap) { #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, localData.m_angle + prop.m_radAngle, color, dataVector, isActive, localInstance.m_dataTexture0, localInstance.m_dataVector1, localInstance.m_dataVector2)); #else PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive, instance.m_dataTexture0, instance.m_dataVector1, instance.m_dataVector2); #endif } else { #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, localData.m_angle + prop.m_radAngle, color, dataVector, isActive)); #else PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive); #endif } } else { if (!(finalTree != null)) { continue; } finalTree = finalTree.GetVariation(ref r); float scale = finalTree.m_minScale + (float)r.Int32(10000u) * (finalTree.m_maxScale - finalTree.m_minScale) * 0.0001f; float brightness = finalTree.m_minBrightness + (float)r.Int32(10000u) * (finalTree.m_maxBrightness - finalTree.m_minBrightness) * 0.0001f; if ((layerMask & (1 << finalTree.m_prefabDataLayer)) != 0 && ((!prop.m_fixedHeight) ? renderNonfixed : renderFixed)) { Vector3 position3 = instance.m_dataMatrix1.MultiplyPoint(prop.m_position); if (!prop.m_fixedHeight || __instance.m_info.m_requireHeightMap) { position3.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f; } Vector4 dataVector2 = instance.m_dataVector3; if (!__instance.m_info.m_colorizeEverything) { dataVector2.z = 0f; } #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => TreeInstance.RenderInstance(cameraInfo, finalTree, position3, scale, brightness, dataVector2)); #else TreeInstance.RenderInstance(cameraInfo, finalTree, position3, scale, brightness, dataVector2); #endif } } } return(false); }
protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, int finalProductionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount) { DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(buildingData.m_position); byte b = instance.GetPark(buildingData.m_position); if (b != 0) { if (!instance.m_parks.m_buffer[(int)b].IsIndustry) { b = 0; } else if (this.m_industryType == DistrictPark.ParkType.Industry || this.m_industryType != instance.m_parks.m_buffer[(int)b].m_parkType) { b = 0; } } float num = (float)buildingData.Width * -4f; float num2 = (float)buildingData.Width * 4f; float num3 = (float)buildingData.Length * -4f; float num4 = (float)buildingData.Length * 4f; if (this.m_info.m_subBuildings != null) { for (int i = 0; i < this.m_info.m_subBuildings.Length; i++) { if (this.m_info.m_subBuildings[i].m_buildingInfo != null) { float num5 = (float)this.m_info.m_subBuildings[i].m_buildingInfo.m_cellWidth; float num6 = (float)this.m_info.m_subBuildings[i].m_buildingInfo.m_cellLength; float x = this.m_info.m_subBuildings[i].m_position.x; float num7 = -this.m_info.m_subBuildings[i].m_position.z; num = Mathf.Min(num, x - num5 * 4f); num2 = Mathf.Max(num2, x + num5 * 4f); num3 = Mathf.Min(num3, num7 - num6 * 4f); num4 = Mathf.Max(num4, num7 + num6 * 4f); } } } float angle = buildingData.m_angle; float num8 = -(num + num2) * 0.5f; float num9 = -(num3 + num4) * 0.5f; float num10 = Mathf.Sin(angle); float num11 = Mathf.Cos(angle); Vector3 position = buildingData.m_position - new Vector3(num11 * num8 + num10 * num9, 0f, num10 * num8 - num11 * num9); Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoResources | Notification.Problem.NoPlaceforGoods | Notification.Problem.NoInputProducts | Notification.Problem.NoFishingGoods); bool flag = this.m_info.m_class.m_service == ItemClass.Service.Fishing; DistrictPolicies.Park parkPolicies = instance.m_parks.m_buffer[(int)b].m_parkPolicies; DistrictPark[] buffer = instance.m_parks.m_buffer; byte b2 = b; buffer[(int)b2].m_parkPoliciesEffect = (buffer[(int)b2].m_parkPoliciesEffect | (parkPolicies & (DistrictPolicies.Park.ImprovedLogistics | DistrictPolicies.Park.WorkSafety | DistrictPolicies.Park.AdvancedAutomation))); if ((parkPolicies & DistrictPolicies.Park.ImprovedLogistics) != DistrictPolicies.Park.None) { int num12 = this.GetMaintenanceCost() / 100; num12 = finalProductionRate * num12 / 1000; if (num12 != 0) { Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, num12, this.m_info.m_class); } } int num13 = this.m_outputRate; if ((parkPolicies & DistrictPolicies.Park.AdvancedAutomation) != DistrictPolicies.Park.None) { num13 = (num13 * 110 + 50) / 100; int num14 = this.GetMaintenanceCost() / 100; num14 = finalProductionRate * num14 / 1000; if (num14 != 0) { Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, num14, this.m_info.m_class); } } if ((parkPolicies & DistrictPolicies.Park.WorkSafety) != DistrictPolicies.Park.None) { int num15 = (aliveWorkerCount + (int)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15U)) / 16; if (num15 != 0) { Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, num15, this.m_info.m_class); } } if (finalProductionRate != 0) { int num16 = this.m_pollutionAccumulation; if (b != 0) { int num17; int num18; instance.m_parks.m_buffer[(int)b].GetProductionFactors(out num17, out num18); finalProductionRate = (finalProductionRate * num17 + 50) / 100; num16 = (num16 * num18 + 50) / 100; } else if (this.m_industryType != DistrictPark.ParkType.Industry) { finalProductionRate = 0; } int num19 = 0; int num20 = 0; if (this.m_inputResource1 != TransferManager.TransferReason.None) { num19 = this.GetInputBufferSize1(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta); num20 = (int)buildingData.m_customBuffer2; int num21 = (this.m_inputRate1 * finalProductionRate + 99) / 100; if (num20 < num21) { finalProductionRate = (num20 * 100 + this.m_inputRate1 - 1) / this.m_inputRate1; problem = Notification.AddProblems(problem, (!flag) ? ((!this.IsRawMaterial(this.m_inputResource1)) ? Notification.Problem.NoInputProducts : Notification.Problem.NoResources) : Notification.Problem.NoFishingGoods); } } int num22 = 0; int num23 = 0; if (this.m_inputResource2 != TransferManager.TransferReason.None) { num22 = this.GetInputBufferSize2(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta); num23 = ((int)buildingData.m_teens << 8 | (int)buildingData.m_youngs); int num24 = (this.m_inputRate2 * finalProductionRate + 99) / 100; if (num23 < num24) { finalProductionRate = (num23 * 100 + this.m_inputRate2 - 1) / this.m_inputRate2; problem = Notification.AddProblems(problem, (!flag) ? ((!this.IsRawMaterial(this.m_inputResource2)) ? Notification.Problem.NoInputProducts : Notification.Problem.NoResources) : Notification.Problem.NoFishingGoods); } } int num25 = 0; int num26 = 0; if (this.m_inputResource3 != TransferManager.TransferReason.None) { num25 = this.GetInputBufferSize3(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta); num26 = ((int)buildingData.m_adults << 8 | (int)buildingData.m_seniors); int num27 = (this.m_inputRate3 * finalProductionRate + 99) / 100; if (num26 < num27) { finalProductionRate = (num26 * 100 + this.m_inputRate3 - 1) / this.m_inputRate3; problem = Notification.AddProblems(problem, (!flag) ? ((!this.IsRawMaterial(this.m_inputResource3)) ? Notification.Problem.NoInputProducts : Notification.Problem.NoResources) : Notification.Problem.NoFishingGoods); } } int num28 = 0; int num29 = 0; if (this.m_inputResource4 != TransferManager.TransferReason.None) { num28 = this.GetInputBufferSize4(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta); num29 = ((int)buildingData.m_education1 << 8 | (int)buildingData.m_education2); int num30 = (this.m_inputRate4 * finalProductionRate + 99) / 100; if (num29 < num30) { finalProductionRate = (num29 * 100 + this.m_inputRate4 - 1) / this.m_inputRate4; problem = Notification.AddProblems(problem, (!flag) ? ((!this.IsRawMaterial(this.m_inputResource4)) ? Notification.Problem.NoInputProducts : Notification.Problem.NoResources) : Notification.Problem.NoFishingGoods); } } int num31 = 0; int num32 = 0; if (this.m_outputResource != TransferManager.TransferReason.None) { num31 = this.GetOutputBufferSize(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta); num32 = (int)buildingData.m_customBuffer1; int num33 = (num13 * finalProductionRate + 99) / 100; if (num31 - num32 < num33) { num33 = Mathf.Max(0, num31 - num32); finalProductionRate = (num33 * 100 + num13 - 1) / num13; if (this.m_outputVehicleCount != 0) { problem = Notification.AddProblems(problem, Notification.Problem.NoPlaceforGoods); if (this.m_info.m_class.m_service == ItemClass.Service.PlayerIndustry) { GuideController properties = Singleton <GuideManager> .instance.m_properties; if (properties != null) { Singleton <BuildingManager> .instance.m_warehouseNeeded.Activate(properties.m_warehouseNeeded, buildingID); } } } } } if (this.m_inputResource1 != TransferManager.TransferReason.None) { int num34 = (this.m_inputRate1 * finalProductionRate + 99) / 100; num20 = Mathf.Max(0, num20 - num34); buildingData.m_customBuffer2 = (ushort)num20; instance.m_parks.m_buffer[(int)b].AddConsumptionAmount(this.m_inputResource1, num34); } if (this.m_inputResource2 != TransferManager.TransferReason.None) { int num35 = (this.m_inputRate2 * finalProductionRate + 99) / 100; num23 = Mathf.Max(0, num23 - num35); buildingData.m_youngs = (byte)(num23 & 255); buildingData.m_teens = (byte)(num23 >> 8); instance.m_parks.m_buffer[(int)b].AddConsumptionAmount(this.m_inputResource2, num35); } if (this.m_inputResource3 != TransferManager.TransferReason.None) { int num36 = (this.m_inputRate3 * finalProductionRate + 99) / 100; num26 = Mathf.Max(0, num26 - num36); buildingData.m_seniors = (byte)(num26 & 255); buildingData.m_adults = (byte)(num26 >> 8); instance.m_parks.m_buffer[(int)b].AddConsumptionAmount(this.m_inputResource3, num36); } if (this.m_inputResource4 != TransferManager.TransferReason.None) { int num37 = (this.m_inputRate4 * finalProductionRate + 99) / 100; num29 = Mathf.Max(0, num29 - num37); buildingData.m_education2 = (byte)(num29 & 255); buildingData.m_education1 = (byte)(num29 >> 8); instance.m_parks.m_buffer[(int)b].AddConsumptionAmount(this.m_inputResource4, num37); } if (this.m_outputResource != TransferManager.TransferReason.None) { int num38 = (num13 * finalProductionRate + 99) / 100; num32 = Mathf.Min(num31, num32 + num38); buildingData.m_customBuffer1 = (ushort)num32; instance.m_parks.m_buffer[(int)b].AddProductionAmountFish(this.m_outputResource, num38); } num16 = (finalProductionRate * num16 + 50) / 100; if (num16 != 0) { num16 = UniqueFacultyAI.DecreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, num16); Singleton <NaturalResourceManager> .instance.TryDumpResource(NaturalResourceManager.Resource.Pollution, num16, num16, position, this.m_pollutionRadius); } base.HandleDead2(buildingID, ref buildingData, ref behaviour, totalWorkerCount); if (b != 0 || this.m_industryType == DistrictPark.ParkType.Industry) { int num39 = 0; if (this.m_inputResource1 != TransferManager.TransferReason.None) { int num40 = 0; int num41 = 0; int num42 = 0; int num43 = 0; base.CalculateGuestVehicles(buildingID, ref buildingData, this.m_inputResource1, ref num40, ref num41, ref num42, ref num43); if (num43 != 0) { num39 |= 1; } int num44 = num19 - num20 - num41; if (num44 >= 8000) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = Mathf.Max(1, num44 * 8 / num19); offer.Building = buildingID; offer.Position = buildingData.m_position; offer.Amount = 1; offer.Active = false; Singleton <TransferManager> .instance.AddIncomingOffer(this.m_inputResource1, offer); } instance.m_parks.m_buffer[(int)b].AddBufferStatus(this.m_inputResource1, num20, num41, num19); } if (this.m_inputResource2 != TransferManager.TransferReason.None) { int num45 = 0; int num46 = 0; int num47 = 0; int num48 = 0; base.CalculateGuestVehicles(buildingID, ref buildingData, this.m_inputResource2, ref num45, ref num46, ref num47, ref num48); if (num48 != 0) { num39 |= 2; } int num49 = num22 - num23 - num46; if (num49 >= 8000) { TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer); offer2.Priority = Mathf.Max(1, num49 * 8 / num22); offer2.Building = buildingID; offer2.Position = buildingData.m_position; offer2.Amount = 1; offer2.Active = false; Singleton <TransferManager> .instance.AddIncomingOffer(this.m_inputResource2, offer2); } instance.m_parks.m_buffer[(int)b].AddBufferStatus(this.m_inputResource2, num23, num46, num22); } if (this.m_inputResource3 != TransferManager.TransferReason.None) { int num50 = 0; int num51 = 0; int num52 = 0; int num53 = 0; base.CalculateGuestVehicles(buildingID, ref buildingData, this.m_inputResource3, ref num50, ref num51, ref num52, ref num53); if (num53 != 0) { num39 |= 4; } int num54 = num25 - num26 - num51; if (num54 >= 8000) { TransferManager.TransferOffer offer3 = default(TransferManager.TransferOffer); offer3.Priority = Mathf.Max(1, num54 * 8 / num25); offer3.Building = buildingID; offer3.Position = buildingData.m_position; offer3.Amount = 1; offer3.Active = false; Singleton <TransferManager> .instance.AddIncomingOffer(this.m_inputResource3, offer3); } instance.m_parks.m_buffer[(int)b].AddBufferStatus(this.m_inputResource3, num26, num51, num25); } if (this.m_inputResource4 != TransferManager.TransferReason.None) { int num55 = 0; int num56 = 0; int num57 = 0; int num58 = 0; base.CalculateGuestVehicles(buildingID, ref buildingData, this.m_inputResource4, ref num55, ref num56, ref num57, ref num58); if (num58 != 0) { num39 |= 8; } int num59 = num28 - num29 - num56; if (num59 >= 8000) { TransferManager.TransferOffer offer4 = default(TransferManager.TransferOffer); offer4.Priority = Mathf.Max(1, num59 * 8 / num28); offer4.Building = buildingID; offer4.Position = buildingData.m_position; offer4.Amount = 1; offer4.Active = false; Singleton <TransferManager> .instance.AddIncomingOffer(this.m_inputResource4, offer4); } instance.m_parks.m_buffer[(int)b].AddBufferStatus(this.m_inputResource4, num29, num56, num28); } buildingData.m_tempImport |= (byte)num39; if (this.m_outputResource != TransferManager.TransferReason.None) { if (this.m_outputVehicleCount == 0) { if (num32 == num31) { int num60 = (num32 * IndustryBuildingAI.GetResourcePrice(this.m_outputResource, ItemClass.Service.None) + 50) / 100; if ((instance.m_districts.m_buffer[(int)district].m_cityPlanningPolicies & DistrictPolicies.CityPlanning.SustainableFishing) != DistrictPolicies.CityPlanning.None) { num60 = (num60 * 105 + 99) / 100; } num60 = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, num60); Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.ResourcePrice, num60, this.m_info.m_class); if (b != 0) { instance.m_parks.m_buffer[(int)b].AddExportAmountFish(this.m_outputResource, num32); } num32 = 0; buildingData.m_customBuffer1 = (ushort)num32; buildingData.m_tempExport = byte.MaxValue; } } else { int num61 = 0; int num62 = 0; int num63 = 0; int value = 0; base.CalculateOwnVehicles(buildingID, ref buildingData, this.m_outputResource, ref num61, ref num62, ref num63, ref value); buildingData.m_tempExport = (byte)Mathf.Clamp(value, (int)buildingData.m_tempExport, 255); int budget = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class); int productionRate2 = PlayerBuildingAI.GetProductionRate(100, budget); int num64 = (productionRate2 * this.m_outputVehicleCount + 99) / 100; int num65 = num32; if (num65 >= 8000 && num61 < num64) { TransferManager.TransferOffer offer5 = default(TransferManager.TransferOffer); offer5.Priority = Mathf.Max(1, num65 * 8 / num31); offer5.Building = buildingID; offer5.Position = buildingData.m_position; offer5.Amount = 1; offer5.Active = true; Singleton <TransferManager> .instance.AddOutgoingOffer(this.m_outputResource, offer5); } } instance.m_parks.m_buffer[(int)b].AddBufferStatusFish(this.m_outputResource, num32, 0, num31); } } if (buildingData.m_finalImport != 0) { District[] buffer2 = instance.m_districts.m_buffer; byte b3 = district; buffer2[(int)b3].m_playerConsumption.m_finalImportAmount = buffer2[(int)b3].m_playerConsumption.m_finalImportAmount + (uint)buildingData.m_finalImport; } if (buildingData.m_finalExport != 0) { District[] buffer3 = instance.m_districts.m_buffer; byte b4 = district; buffer3[(int)b4].m_playerConsumption.m_finalExportAmount = buffer3[(int)b4].m_playerConsumption.m_finalExportAmount + (uint)buildingData.m_finalExport; } int num66 = finalProductionRate * this.m_noiseAccumulation / 100; if (num66 != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num66, position, this.m_noiseRadius); } } buildingData.m_problems = problem; buildingData.m_education3 = (byte)Mathf.Clamp(finalProductionRate * num13 / Mathf.Max(1, this.m_outputRate), 0, 255); buildingData.m_health = (byte)Mathf.Clamp(finalProductionRate, 0, 255); if (b != 0) { instance.m_parks.m_buffer[(int)b].AddWorkers(aliveWorkerCount); } else if (this.m_industryType != DistrictPark.ParkType.Industry) { GuideController properties2 = Singleton <GuideManager> .instance.m_properties; if (properties2 != null) { Singleton <BuildingManager> .instance.m_industryBuildingOutsideIndustryArea.Activate(properties2.m_industryBuildingOutsideIndustryArea, buildingID); } } base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount); }
public static void CalculateBuildingMoneyAndSalary(Building building, ushort buildingID) { if (BuildingData.buildingMoney[buildingID] > MainDataStore.maxBuildingMoneyLimit) { BuildingData.buildingMoney[buildingID] = MainDataStore.maxBuildingMoneyLimit; } else if (BuildingData.buildingMoney[buildingID] < -MainDataStore.maxBuildingMoneyLimit) { BuildingData.buildingMoney[buildingID] = -MainDataStore.maxBuildingMoneyLimit; } if (building.Info.m_class.m_service == ItemClass.Service.Industrial || building.Info.m_class.m_service == ItemClass.Service.Commercial || building.Info.m_class.m_service == ItemClass.Service.Office) { Citizen.BehaviourData behaviourData = default; int aliveWorkerCount = 0; int totalWorkerCount = 0; RealCityCommonBuildingAI.InitDelegate(); RealCityCommonBuildingAI.GetWorkBehaviour((CommonBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); float bossTake = 0; float investToOffice = 0; float profitShare = 0; switch (building.Info.m_class.m_subService) { case ItemClass.SubService.OfficeGeneric: case ItemClass.SubService.OfficeHightech: profitShare = 1f; break; case ItemClass.SubService.IndustrialFarming: case ItemClass.SubService.IndustrialForestry: if (building.Info.m_buildingAI is IndustrialExtractorAI) { bossTake = MainDataStore.bossRatioInduExtractor; investToOffice = MainDataStore.investRatioInduExtractor; profitShare = MainDataStore.profitShareRatioInduExtractor; } else { bossTake = MainDataStore.bossRatioInduOther; investToOffice = MainDataStore.investRatioInduOther; profitShare = MainDataStore.profitShareRatioInduOther; } break; case ItemClass.SubService.IndustrialOil: case ItemClass.SubService.IndustrialOre: bossTake = MainDataStore.bossRatioInduOther; investToOffice = MainDataStore.investRatioInduOther; profitShare = MainDataStore.profitShareRatioInduOther; break; case ItemClass.SubService.IndustrialGeneric: if (building.Info.m_class.m_level == ItemClass.Level.Level1) { bossTake = MainDataStore.bossRatioInduLevel1; investToOffice = MainDataStore.investRatioInduLevel1; profitShare = MainDataStore.profitShareRatioInduLevel1; } else if (building.Info.m_class.m_level == ItemClass.Level.Level2) { bossTake = MainDataStore.bossRatioInduLevel2; investToOffice = MainDataStore.investRatioInduLevel2; profitShare = MainDataStore.profitShareRatioInduLevel2; } else { bossTake = MainDataStore.bossRatioInduLevel3; investToOffice = MainDataStore.investRatioInduLevel3; profitShare = MainDataStore.profitShareRatioInduLevel3; } break; case ItemClass.SubService.CommercialHigh: case ItemClass.SubService.CommercialLow: if (building.Info.m_class.m_level == ItemClass.Level.Level1) { bossTake = MainDataStore.bossRatioCommLevel1; investToOffice = MainDataStore.investRatioCommLevel1; profitShare = MainDataStore.profitShareRatioCommLevel1; } else if (building.Info.m_class.m_level == ItemClass.Level.Level2) { bossTake = MainDataStore.bossRatioCommLevel2; investToOffice = MainDataStore.investRatioCommLevel2; profitShare = MainDataStore.profitShareRatioCommLevel2; } else { bossTake = MainDataStore.bossRatioCommLevel3; investToOffice = MainDataStore.investRatioCommLevel3; profitShare = MainDataStore.profitShareRatioCommLevel1; } break; case ItemClass.SubService.CommercialTourist: bossTake = MainDataStore.bossRatioCommTou; investToOffice = MainDataStore.investRatioCommTou; profitShare = MainDataStore.profitShareRatioCommTou; break; case ItemClass.SubService.CommercialLeisure: bossTake = MainDataStore.bossRatioCommOther; investToOffice = MainDataStore.investRatioCommOther; profitShare = MainDataStore.profitShareRatioCommOther; break; case ItemClass.SubService.CommercialEco: bossTake = MainDataStore.bossRatioCommECO; investToOffice = MainDataStore.investRatioCommECO; profitShare = MainDataStore.profitShareRatioCommECO; break; } // boss take and return to office if (BuildingData.buildingMoney[buildingID] > 0) { //Reduce Boss fee long investToOfficeFee = (long)(BuildingData.buildingMoney[buildingID] * investToOffice); long bossTakeFee = (long)(BuildingData.buildingMoney[buildingID] * bossTake); if (building.Info.m_class.m_service == ItemClass.Service.Commercial) { //Commercial have help tourism MainDataStore.outsideTouristMoney += ((bossTakeFee - investToOfficeFee) * MainDataStore.outsideCompanyProfitRatio * MainDataStore.outsideTouristSalaryProfitRatio); } RealCityPrivateBuildingAI.profitBuildingMoney += investToOfficeFee; BuildingData.buildingMoney[buildingID] -= bossTakeFee; } if (building.Info.m_class.m_service == ItemClass.Service.Office) { float allOfficeWorker = RealCityPrivateBuildingAI.allOfficeLevel1WorkCountFinal + RealCityPrivateBuildingAI.allOfficeLevel2WorkCountFinal + RealCityPrivateBuildingAI.allOfficeLevel3WorkCountFinal + RealCityPrivateBuildingAI.allOfficeHighTechWorkCountFinal; float averageOfficeSalary = 0; if (allOfficeWorker != 0) { averageOfficeSalary = (RealCityPrivateBuildingAI.profitBuildingMoneyFinal / allOfficeWorker); } if (building.Info.m_class.m_subService == ItemClass.SubService.OfficeGeneric) { if (building.Info.m_class.m_level == ItemClass.Level.Level1) { BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.6f; } else if (building.Info.m_class.m_level == ItemClass.Level.Level2) { BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.8f; } else if (building.Info.m_class.m_level == ItemClass.Level.Level3) { BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 1f; } } else if (building.Info.m_class.m_subService == ItemClass.SubService.OfficeHightech) { BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.75f; } ProcessLandFeeOffice(building, buildingID, totalWorkerCount); } //Calculate building salary int buildingAsset = (int)(BuildingData.buildingMoney[buildingID] + building.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(RealCityPrivateBuildingAI.GetIncomingProductionType(buildingID, building))); int salary = 0; if ((buildingAsset > 0) && (totalWorkerCount != 0)) { salary = (int)(buildingAsset * profitShare / totalWorkerCount); switch (building.Info.m_class.m_subService) { case ItemClass.SubService.IndustrialFarming: case ItemClass.SubService.IndustrialForestry: case ItemClass.SubService.IndustrialOil: case ItemClass.SubService.IndustrialOre: salary = Math.Min(salary, MainDataStore.salaryInduOtherMax); break; case ItemClass.SubService.IndustrialGeneric: if (building.Info.m_class.m_level == ItemClass.Level.Level1) { salary = Math.Min(salary, MainDataStore.salaryInduLevel1Max); } else if (building.Info.m_class.m_level == ItemClass.Level.Level2) { salary = Math.Min(salary, MainDataStore.salaryInduLevel2Max); } else { salary = Math.Min(salary, MainDataStore.salaryInduLevel3Max); } break; case ItemClass.SubService.CommercialHigh: case ItemClass.SubService.CommercialLow: if (building.Info.m_class.m_level == ItemClass.Level.Level1) { salary = Math.Min(salary, MainDataStore.salaryCommLevel1Max); } else if (building.Info.m_class.m_level == ItemClass.Level.Level2) { salary = Math.Min(salary, MainDataStore.salaryCommLevel2Max); } else { salary = Math.Min(salary, MainDataStore.salaryCommLevel3Max); } break; case ItemClass.SubService.CommercialTourist: salary = Math.Min(salary, MainDataStore.salaryCommTouMax); break; case ItemClass.SubService.CommercialLeisure: salary = Math.Min(salary, MainDataStore.salaryCommOtherMax); break; case ItemClass.SubService.CommercialEco: salary = Math.Min(salary, MainDataStore.salaryCommECOMax); break; } } if (salary > 0) { BuildingData.buildingWorkCount[buildingID] = salary; } else { BuildingData.buildingWorkCount[buildingID] = 0; } } else { //resident building ItemClass @class = building.Info.m_class; int incomeAccumulation = 0; DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(building.m_position); DistrictPolicies.Taxation taxationPolicies = instance.m_districts.m_buffer[district].m_taxationPolicies; if (@class.m_subService == ItemClass.SubService.ResidentialLow) { switch (@class.m_level) { case ItemClass.Level.Level1: incomeAccumulation = MainDataStore.residentLowLevel1Rent; break; case ItemClass.Level.Level2: incomeAccumulation = MainDataStore.residentLowLevel2Rent; break; case ItemClass.Level.Level3: incomeAccumulation = MainDataStore.residentLowLevel3Rent; break; case ItemClass.Level.Level4: incomeAccumulation = MainDataStore.residentLowLevel4Rent; break; case ItemClass.Level.Level5: incomeAccumulation = MainDataStore.residentLowLevel5Rent; break; } } else if (@class.m_subService == ItemClass.SubService.ResidentialLowEco) { switch (@class.m_level) { case ItemClass.Level.Level1: incomeAccumulation = MainDataStore.residentLowLevel1Rent; break; case ItemClass.Level.Level2: incomeAccumulation = MainDataStore.residentLowLevel2Rent; break; case ItemClass.Level.Level3: incomeAccumulation = MainDataStore.residentLowLevel3Rent; break; case ItemClass.Level.Level4: incomeAccumulation = MainDataStore.residentLowLevel4Rent; break; case ItemClass.Level.Level5: incomeAccumulation = MainDataStore.residentLowLevel5Rent; break; } } else if (@class.m_subService == ItemClass.SubService.ResidentialHigh) { switch (@class.m_level) { case ItemClass.Level.Level1: incomeAccumulation = MainDataStore.residentHighLevel1Rent; break; case ItemClass.Level.Level2: incomeAccumulation = MainDataStore.residentHighLevel2Rent; break; case ItemClass.Level.Level3: incomeAccumulation = MainDataStore.residentHighLevel3Rent; break; case ItemClass.Level.Level4: incomeAccumulation = MainDataStore.residentHighLevel4Rent; break; case ItemClass.Level.Level5: incomeAccumulation = MainDataStore.residentHighLevel5Rent; break; } } else { switch (@class.m_level) { case ItemClass.Level.Level1: incomeAccumulation = MainDataStore.residentHighLevel1Rent; break; case ItemClass.Level.Level2: incomeAccumulation = MainDataStore.residentHighLevel2Rent; break; case ItemClass.Level.Level3: incomeAccumulation = MainDataStore.residentHighLevel3Rent; break; case ItemClass.Level.Level4: incomeAccumulation = MainDataStore.residentHighLevel4Rent; break; case ItemClass.Level.Level5: incomeAccumulation = MainDataStore.residentHighLevel5Rent; break; } } int num2; num2 = Singleton <EconomyManager> .instance.GetTaxRate(@class, taxationPolicies); incomeAccumulation = (int)((num2 * incomeAccumulation) / 100f); BuildingData.buildingWorkCount[buildingID] = incomeAccumulation; } }
protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, int finalProductionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount) { base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount); int num = productionRate * m_deathCareAccumulation / 100; if (num != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.DeathCare, num, buildingData.m_position, m_deathCareRadius); } if (finalProductionRate != 0) { int num2 = buildingData.m_customBuffer1; int num3 = (m_burialRate * finalProductionRate * 100 + m_corpseCapacity - 1) / m_corpseCapacity; CitizenManager instance = Singleton <CitizenManager> .instance; uint num4 = buildingData.m_citizenUnits; int num5 = 0; int num6 = 0; int num7 = 0; while (num4 != 0) { uint nextUnit = instance.m_units.m_buffer[num4].m_nextUnit; if ((instance.m_units.m_buffer[num4].m_flags & CitizenUnit.Flags.Visit) != 0) { for (int i = 0; i < 5; i++) { uint citizen = instance.m_units.m_buffer[num4].GetCitizen(i); if (citizen != 0) { if (instance.m_citizens.m_buffer[citizen].Dead) { if (instance.m_citizens.m_buffer[citizen].CurrentLocation == Citizen.Location.Visit) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(10000u) < num3) { instance.ReleaseCitizen(citizen); num7++; num2++; } else { num6++; } } else { num6++; } } else if (instance.m_citizens.m_buffer[citizen].Sick && instance.m_citizens.m_buffer[citizen].CurrentLocation == Citizen.Location.Visit) { instance.m_citizens.m_buffer[citizen].Sick = false; } } } } num4 = nextUnit; if (++num5 > 524288) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } behaviour.m_deadCount += num6; if (m_graveCount == 0) { for (int j = num7; j < num2; j++) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(10000u) < num3) { num7++; num2--; } else { num6++; } } } buildingData.m_tempExport = (byte)Mathf.Min(buildingData.m_tempExport + num7, 255); DistrictManager instance2 = Singleton <DistrictManager> .instance; byte district = instance2.GetDistrict(buildingData.m_position); bool flag = IsFull(buildingID, ref buildingData); if (m_graveCount != 0) { num2 = Mathf.Min(num2, m_graveCount); buildingData.m_customBuffer1 = (ushort)num2; instance2.m_districts.m_buffer[district].m_productionData.m_tempDeadAmount += (uint)num2; instance2.m_districts.m_buffer[district].m_productionData.m_tempDeadCapacity += (uint)m_graveCount; } else { buildingData.m_customBuffer1 = (ushort)num2; instance2.m_districts.m_buffer[district].m_productionData.m_tempCremateCapacity += (uint)m_corpseCapacity; } bool flag2 = IsFull(buildingID, ref buildingData); if (flag != flag2) { if (flag2) { if ((object)m_fullPassMilestone != null) { m_fullPassMilestone.Unlock(); } } else if ((object)m_fullPassMilestone != null) { m_fullPassMilestone.Relock(); } } int count = 0; int count2 = 0; int cargo = 0; int capacity = 0; int outside = 0; CalculateOwnVehicles(buildingID, ref buildingData, TransferManager.TransferReason.Dead, ref count, ref cargo, ref capacity, ref outside); CalculateGuestVehicles(buildingID, ref buildingData, TransferManager.TransferReason.DeadMove, ref count2, ref cargo, ref capacity, ref outside); int num8 = m_corpseCapacity - num6 - capacity; int num9 = (finalProductionRate * m_hearseCount + 99) / 100; if ((buildingData.m_flags & Building.Flags.Downgrading) != 0) { if (m_graveCount != 0) { int count3 = 0; int cargo2 = 0; int capacity2 = 0; int outside2 = 0; CalculateOwnVehicles(buildingID, ref buildingData, TransferManager.TransferReason.DeadMove, ref count3, ref cargo2, ref capacity2, ref outside2); if (num2 > 0 && count3 < num9) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = 7; offer.Building = buildingID; offer.Position = buildingData.m_position; offer.Amount = 1; offer.Active = true; Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.DeadMove, offer); } } } else if (m_graveCount != 0) { num8 = Mathf.Min(num8, m_graveCount - num2 - num6 - capacity + 9); int num10 = num8 / 10; if (count != 0) { num10--; } bool flag4 = num10 >= 1 && count < num9 && (num10 > 1); if (flag4) { TransferManager.TransferOffer offer3 = default(TransferManager.TransferOffer); offer3.Priority = 2 - count; offer3.Building = buildingID; offer3.Position = buildingData.m_position; offer3.Amount = 1; offer3.Active = true; Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.Dead, offer3); } if (buildingData.m_customBuffer1 > (m_corpseCapacity * 2 / 3)) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = 0; offer.Building = buildingID; offer.Position = buildingData.m_position; offer.Amount = 1; offer.Active = true; Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.DeadMove, offer); } } else { int num11 = num8 / 10; bool flag5 = num11 >= 1 && (num11 > 1 || count >= num9 || Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0); bool flag6 = num11 >= 1 && count < num9 && (num11 > 1 || !flag5); if (flag5) { TransferManager.TransferOffer offer4 = default(TransferManager.TransferOffer); offer4.Priority = Mathf.Max(1, num8 * 6 / m_corpseCapacity); offer4.Building = buildingID; offer4.Position = buildingData.m_position; offer4.Amount = Mathf.Max(1, num11 - 1); offer4.Active = false; Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.DeadMove, offer4); } if (flag6) { TransferManager.TransferOffer offer5 = default(TransferManager.TransferOffer); offer5.Priority = 2 - count; offer5.Building = buildingID; offer5.Position = buildingData.m_position; offer5.Amount = 1; offer5.Active = true; Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.Dead, offer5); } } } }
private static bool CalculateLocalResources(int x, int z, ushort[] buffer, int[] global, ushort[] target, int index) { //int num10 = ((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate1, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate3, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate2, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate4, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate5, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate6, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate7, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate8, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate12, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate10, 100, 500, 100, 200) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate17, 60, 100, 0, 50) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate16, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate17, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate16, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(num9, 50, (int)byte.MaxValue, 50, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate9, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate15, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate14, 50, 100, 10, 50) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate11, 15, 50, 100, 200) + (ImmaterialResourceManager.CalculateResourceEffect(resourceRate13, 33, 67, 300, 0) * Mathf.Max(0, 32 - num9) >> 5)) / 10 : 0; int resourceRate1 = (int)buffer[index] + global[0]; int resourceRate2 = (int)buffer[index + 1] + global[1]; int resourceRate3 = (int)buffer[index + 2] + global[2]; int resourceRate4 = (int)buffer[index + 3] + global[3]; int resourceRate5 = (int)buffer[index + 4] + global[4]; int resourceRate6 = (int)buffer[index + 5] + global[5]; int resourceRate7 = (int)buffer[index + 6] + global[6]; int resourceRate8 = (int)buffer[index + 7] + global[7]; int resourceRate9 = (int)buffer[index + 8] + global[8]; int num1 = (int)buffer[index + 9] + global[9]; int num2 = (int)buffer[index + 10] + global[10]; int num3 = (int)buffer[index + 11] + global[11]; int num4 = (int)buffer[index + 12] + global[12]; int resourceRate10 = (int)buffer[index + 13] + global[13]; int num5 = (int)buffer[index + 14] + global[14]; int num6 = (int)buffer[index + 15] + global[15]; int num7 = (int)buffer[index + 16] + global[16]; int num8 = (int)buffer[index + 17] + global[17]; int resourceRate11 = (int)buffer[index + 18] + global[18]; int resourceRate12 = (int)buffer[index + 19] + global[19]; Rect area = new Rect((float)(((double)x - 128.0 - 1.5) * 38.4000015258789), (float)(((double)z - 128.0 - 1.5) * 38.4000015258789), 153.6f, 153.6f); float groundPollution; float waterProximity; Singleton <NaturalResourceManager> .instance.AveragePollutionAndWater(area, out groundPollution, out waterProximity); int num9 = (int)((double)groundPollution * 100.0); int resourceRate13 = (int)((double)waterProximity * 100.0); if (resourceRate13 > 33 && resourceRate13 < 99) { area = new Rect((float)(((double)x - 128.0 + 0.25) * 38.4000015258789), (float)(((double)z - 128.0 + 0.25) * 38.4000015258789), 19.2f, 19.2f); Singleton <NaturalResourceManager> .instance.AveragePollutionAndWater(area, out groundPollution, out waterProximity); resourceRate13 = Mathf.Max(Mathf.Min(resourceRate13, (int)((double)waterProximity * 100.0)), 33); } int resourceRate14 = num8 * 2 / (resourceRate2 + 50); int resourceRate15; int resourceRate16; int resourceRate17; if (num4 == 0) { resourceRate15 = 0; resourceRate16 = 50; resourceRate17 = 50; } else { resourceRate15 = num1 / num4; resourceRate16 = num2 / num4; resourceRate17 = num3 / num4; num7 += Mathf.Min(num4, 10) * 10; } //Accessibility Grid Test Chamber float[,] grid3; //Now it calls every 256^2 steps //However, there are unexplained errors, and the ratings are never properly reached int num10 = 0; try { if (Tracker.CheckAccessibilityUpdate()) { grid3 = TrafficLog.CollectRatings(); } else { grid3 = TrafficLog.GetLastGrid(); } float accessValue; try { //Debug.Log("Attemping Grid Query. X: " + x + " . Z: " + z + ". + Value: " + grid3[x, z] + "."); accessValue = grid3[x, z]; } catch (IndexOutOfRangeException e) { accessValue = 0; } catch (NullReferenceException e) { accessValue = 0; } //Debug.Log("X: " + x + " Z: " + z + "AccessValue: " + accessValue); num10 = (int)accessValue; } catch (NullReferenceException e) { num10 = 0; } //num10 Notes /* * HealthCare = 0, * Yes * FireDepartment = 1, * Yes * PoliceDepartment = 2, * Yes * EducationElementary = 3, * Yes * EducationHighSchool = 4, * Yes * EducationUniversity = 5, * Yes * DeathCare = 6, * Yes * PublicTransport = 7, * Yes / Imperfect * NoisePollution = 8, * Yes * CrimeRate = 9, * Yes * Health = 10, * Yes * Wellbeing = 11, * Ambiguous * Density = 12, * Ambiguous * Entertainment = 13, * Yes * LandValue = 14, * Ambiguous * Attractiveness = 15, * Global * Coverage = 16, * Ambiguous * FireHazard = 17, * Useless * Abandonment = 18, * X * CargoTransport = 19, * Yes * * Ground Pollution * Yes * Water Proximity * Yes */ ////////////////////num10 Test Chamber/////////////// //Water Proximity - Needs scaling //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(Math.Sqrt(waterProximity))*20) : 0); //Ground Pollution - Needs scaling //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(groundPollution) * 10) : 0); //Wellbeing - Needs scaling //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num3) * 2) : 0); //Density //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num4) * 10) : 0); //Land Value??? //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num5) * 1) : 0); //Attractiveness - Either broken or a totally global variable that provides city-wide bonuses? //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(buffer[index + 15]) * 1) : 0); //Coverage - Unclear but it seems to matter when building become inhabited //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num7) * 1) : 0); //Fire Hazard - Even water towers set this off. //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num8) * 1) : 0); //Abandonment //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(resourceRate11) * 1) : 0); //////////////////////////Num10///////////////////////////// //Original //int num10 = ((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate1, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate3, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate2, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate4, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate5, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate6, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate7, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate8, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate12, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate10, 100, 500, 100, 200) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate17, 60, 100, 0, 50) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate16, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate17, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate16, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(num9, 50, (int)byte.MaxValue, 50, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate9, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate15, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate14, 50, 100, 10, 50) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate11, 15, 50, 100, 200) + (ImmaterialResourceManager.CalculateResourceEffect(resourceRate13, 33, 67, 300, 0) * Mathf.Max(0, 32 - num9) >> 5)) / 10 : 0; //Add arbirary value if (((x % 2 == 1) & (z % 2 == 1))) { Vector3 m_vector3 = new Vector3((Convert.ToInt32(x * 38.4000015258789)) - 4915, 0, (Convert.ToInt32(z * 38.4000015258789) - 4915)); DistrictManager DM = Singleton <DistrictManager> .instance; byte m_byte = DM.GetDistrict(m_vector3); string m_name = DM.GetDistrictName(m_byte); //Full Name //Solve Single Operator Crash if ((m_name.Length == 1) & ((m_name.EndsWith("+") | m_name.EndsWith("-")) | (m_name.EndsWith("*") | m_name.EndsWith("/")))) { Singleton <ChirpPanel> .instance.AddMessage(new ChirpMessage("System", "Invalid Syntax: Cannot Pass Single Operator Token")); DM.StartCoroutine(DM.SetDistrictName(m_byte, null)); } else { string m_lastvalidname; m_lastvalidname = m_name; string m_realname = m_name; //Real Name string m_operator = Tracker.GetOperator(m_byte); //Operator string m_deltaS = ""; //Value String double m_deltaD = 0; //Value Number string m_currentOperator = Tracker.GetOperator(m_byte); double m_CurrentValue = Convert.ToDouble(Tracker.GetLandValue(m_byte)); //Set current operator num10 = Convert.ToInt32(m_CurrentValue); if ((m_name.EndsWith("+") | m_name.EndsWith("-")) | (m_name.EndsWith("*") | m_name.EndsWith("/"))) { num10 = 0; Tracker.SetOperator(m_byte, m_name.Substring(m_name.Length - 1)); //Set new operator m_operator = Tracker.GetOperator(m_byte); // Get Operator try { m_deltaS = getSubstring(m_name.Substring(0, m_name.Length - 1)); //Get the Value } catch (ArgumentOutOfRangeException e) { m_deltaS = "0"; } try { m_deltaD = Convert.ToDouble(m_deltaS); } catch (FormatException e2) { m_deltaD = 0; } if (!((m_name.Length - (m_deltaS.Length + 1)) < 0)) { m_realname = m_name.Substring(0, (m_name.Length - (m_deltaS.Length + 1))); //Get name without value and operator } while (m_realname.EndsWith(" ")) { m_realname = m_realname.Substring(0, m_realname.Length - 1); //Remove extra spaces from end } while (m_realname.StartsWith(" ")) { m_realname = m_realname.Substring(1, m_realname.Length); //Remove extra spaces from start } while (((m_realname.EndsWith("+") | m_realname.EndsWith("-")) | (m_realname.EndsWith("*") | m_realname.EndsWith("/")))) { if (m_realname.Length > 1) { m_realname = m_realname.Substring(0, m_realname.Length - 1); //Remove extra operators } } if (!((m_realname.EndsWith("+") | m_realname.EndsWith("-")) | (m_realname.EndsWith("*") | m_realname.EndsWith("/")))) { DM.StartCoroutine(DM.SetDistrictName(m_byte, m_realname)); // Rename District } else { if (m_realname.IsNullOrWhiteSpace()) { DM.StartCoroutine(DM.SetDistrictName(m_byte, m_lastvalidname)); } else //Not null but ends in an operator { DM.StartCoroutine(DM.SetDistrictName(m_byte, m_lastvalidname)); } } Tracker.SetLandValue(m_byte, m_deltaS); //Assign number to Array } else { m_operator = " "; } m_currentOperator = Tracker.GetOperator(m_byte); //Reassign operator string landModifier = Tracker.GetLandValue(m_byte); if (m_operator.EndsWith("+")) { num10 = Mathf.Clamp(Convert.ToInt32(num10 + Convert.ToDouble(landModifier)), 0, ushort.MaxValue); // + current or new value to num10 } else if (m_operator.EndsWith("-")) { num10 = Mathf.Clamp(Convert.ToInt32(num10 - Convert.ToDouble(landModifier)), 0, ushort.MaxValue); // - current or new value to num10 } else if (m_operator.EndsWith("*")) { num10 = Mathf.Clamp(Convert.ToInt32(num10 * Convert.ToDouble(landModifier)), 0, ushort.MaxValue); // * current or new value to num10 } else if (m_operator.EndsWith("/")) { try { num10 = Mathf.Clamp(Convert.ToInt32(num10 / Convert.ToDouble(landModifier)), 0, ushort.MaxValue); // / current or new value to num10 } catch (DivideByZeroException e4) { } } Tracker.SetLandValue(m_byte, Convert.ToString(num10)); } } //ResourceRate1 = Medicine //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate1, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate2 = Fire Protection //num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate2, 1, 1000, 1, 3000) >> 5) / 1 : 0); //ResourceRate3 = Police Protection //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate3, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate4 = Elementary //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate4, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate5 = High School //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate5, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate6 = College //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate6, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate7 = Deathcare //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate7, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate8 = Public Transport //num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate8, 1, 1000, 1, 3000) >> 5) / 1 : 0); //ResourceRate9 = NoisePollition //num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate9, 1, 2, 1, 1000) >> 5) / 1 : 0); //ResourceRate10 = Entertainment //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate10, 1, 500, 1, 3000) >> 5) / 10 : 0); //ResourceRate11 = -? (Abandonment (R)) //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate11, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate12 = Cargo Transport //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate12, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate13 = Proximity to Water and Pollution //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate13, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate14 = FireHazard over Fire Protection? (R) - Water and shoreline confirmed add value. //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate14, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate15 = If Density=0 then 0, otherwise its Crime Rate divided by density? (R) //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate15, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate16 = Starts at a positive value, reduced by public buildings. If Density = 0 then 50, otherwise its health divided by density? (R) //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate16, 1, 2, 1, 1000) >> 5) / 10 : 0); //ResourceRate17 = If Density= 0 then 50, otherwise Wellbeing deivided by density? (R) //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate17, 1, 2, 1, 1000) >> 5) / 10 : 0); /* 1. Yes * 2. Yes * 3. Yes * 4. Yes * 5. Yes * 6. Yes * 7. Yes * 8. Yes but imperfect * 9. Yes * 10. Yes * 11. Unproven * 12. Yes * 13. Yes * 14. Inconsistent * 15. Yes but uncertain * 16. Yes but weird * 17. Various buildings have effect, weird */ //End int num11 = Mathf.Clamp(resourceRate1, 0, (int)ushort.MaxValue); int num12 = Mathf.Clamp(resourceRate2, 0, (int)ushort.MaxValue); int num13 = Mathf.Clamp(resourceRate3, 0, (int)ushort.MaxValue); int num14 = Mathf.Clamp(resourceRate4, 0, (int)ushort.MaxValue); int num15 = Mathf.Clamp(resourceRate5, 0, (int)ushort.MaxValue); int num16 = Mathf.Clamp(resourceRate6, 0, (int)ushort.MaxValue); int num17 = Mathf.Clamp(resourceRate7, 0, (int)ushort.MaxValue); int num18 = Mathf.Clamp(resourceRate8, 0, (int)ushort.MaxValue); int num19 = Mathf.Clamp(resourceRate9, 0, (int)ushort.MaxValue); int num20 = Mathf.Clamp(resourceRate15, 0, (int)ushort.MaxValue); int num21 = Mathf.Clamp(resourceRate16, 0, (int)ushort.MaxValue); int num22 = Mathf.Clamp(resourceRate17, 0, (int)ushort.MaxValue); int num23 = Mathf.Clamp(num4, 0, (int)ushort.MaxValue); int num24 = Mathf.Clamp(resourceRate10, 0, (int)ushort.MaxValue); /////////////////////////////////Clamp Land Value////////////////////////////// //Landvalue comes from num10 //Original //int landvalue = Mathf.Clamp(num10, 0, (int)ushort.MaxValue); //Test int landvalue = Mathf.Clamp(num10, 0, (int)ushort.MaxValue); int num25 = Mathf.Clamp(num6, 0, (int)ushort.MaxValue); int coverage = Mathf.Clamp(num7, 0, (int)ushort.MaxValue); int num26 = Mathf.Clamp(resourceRate14, 0, (int)ushort.MaxValue); int num27 = Mathf.Clamp(resourceRate11, 0, (int)ushort.MaxValue); int num28 = Mathf.Clamp(resourceRate12, 0, (int)ushort.MaxValue); DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(x * 2, z * 2); /////////////////////////////////Apply to District////////////////////////////// //Districts have landvalue, pollution and coverage. num9 refers to ground pollution, coverage //has something to do with num7. The method assigns templandvalue, temppollution and tempcoverage. //The first two are the inputs * coverage, tempcoverage is simply coverage. instance.m_districts.m_buffer[(int)district].AddGroundData(landvalue, num9, coverage); bool flag = false; if (num11 != (int)target[index]) { target[index] = (ushort)num11; flag = true; } if (num12 != (int)target[index + 1]) { target[index + 1] = (ushort)num12; flag = true; } if (num13 != (int)target[index + 2]) { target[index + 2] = (ushort)num13; flag = true; } if (num14 != (int)target[index + 3]) { target[index + 3] = (ushort)num14; flag = true; } if (num15 != (int)target[index + 4]) { target[index + 4] = (ushort)num15; flag = true; } if (num16 != (int)target[index + 5]) { target[index + 5] = (ushort)num16; flag = true; } if (num17 != (int)target[index + 6]) { target[index + 6] = (ushort)num17; flag = true; } if (num18 != (int)target[index + 7]) { target[index + 7] = (ushort)num18; flag = true; } if (num19 != (int)target[index + 8]) { target[index + 8] = (ushort)num19; flag = true; } if (num20 != (int)target[index + 9]) { target[index + 9] = (ushort)num20; flag = true; } if (num21 != (int)target[index + 10]) { target[index + 10] = (ushort)num21; flag = true; } if (num22 != (int)target[index + 11]) { target[index + 11] = (ushort)num22; flag = true; } if (num23 != (int)target[index + 12]) { target[index + 12] = (ushort)num23; flag = true; } if (num24 != (int)target[index + 13]) { target[index + 13] = (ushort)num24; flag = true; } ///////////////////////////////Flag/////////////////////// //What this means is unceertain, flag is a bool returned. If a condition is met //then it is true, otherwise false. This probably does not matter. if (landvalue != (int)target[index + 14]) { target[index + 14] = (ushort)landvalue; flag = true; } if (num25 != (int)target[index + 15]) { target[index + 15] = (ushort)num25; flag = true; } if (coverage != (int)target[index + 16]) { target[index + 16] = (ushort)coverage; flag = true; } if (num26 != (int)target[index + 17]) { target[index + 17] = (ushort)num26; flag = true; } if (num27 != (int)target[index + 18]) { target[index + 18] = (ushort)num27; flag = true; } if (num28 != (int)target[index + 19]) { target[index + 19] = (ushort)num28; flag = true; } return(flag); }
new int HandleCommonConsumption(ushort buildingID, ref Building data, ref int electricityConsumption, ref int heatingConsumption, ref int waterConsumption, ref int sewageAccumulation, ref int garbageAccumulation, DistrictPolicies.Services policies) { int num = 100; DistrictManager instance = Singleton <DistrictManager> .instance; Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Electricity | Notification.Problem.Water | Notification.Problem.Sewage | Notification.Problem.Flood | Notification.Problem.Heating); bool flag = data.m_electricityProblemTimer != 0; bool flag2 = false; bool flag3 = false; int electricityUsage = 0; int heatingUsage = 0; int waterUsage = 0; int sewageUsage = 0; if (electricityConsumption != 0) { int num2 = Mathf.RoundToInt((20f - Singleton <WeatherManager> .instance.SampleTemperature(data.m_position, false)) * 8f); num2 = Mathf.Clamp(num2, 0, 400); int num3 = heatingConsumption; heatingConsumption = (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100; if ((policies & DistrictPolicies.Services.PowerSaving) != DistrictPolicies.Services.None) { electricityConsumption = Mathf.Max(1, electricityConsumption * 90 / 100); Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class); } bool flag4 = false; int num4 = heatingConsumption * 2 - (int)data.m_heatingBuffer; if (num4 > 0 && (policies & DistrictPolicies.Services.OnlyElectricity) == DistrictPolicies.Services.None) { int num5 = Singleton <WaterManager> .instance.TryFetchHeating(data.m_position, heatingConsumption, num4, out flag4); data.m_heatingBuffer += (ushort)num5; } if ((int)data.m_heatingBuffer < heatingConsumption) { if ((policies & DistrictPolicies.Services.NoElectricity) != DistrictPolicies.Services.None) { flag3 = true; data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1)); if (data.m_heatingProblemTimer >= 65) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Heating | Notification.Problem.MajorProblem); } else if (data.m_heatingProblemTimer >= 3) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Heating); } } else { num2 = ((num2 + 50) * (heatingConsumption - (int)data.m_heatingBuffer) + heatingConsumption - 1) / heatingConsumption; electricityConsumption += (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100; if (flag4) { flag3 = true; data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1)); if (data.m_heatingProblemTimer >= 3) { problem = Notification.AddProblems(problem, Notification.Problem.Heating); } } } heatingUsage = (int)data.m_heatingBuffer; data.m_heatingBuffer = 0; } else { heatingUsage = heatingConsumption; data.m_heatingBuffer -= (ushort)heatingConsumption; } num4 = electricityConsumption * 2 - (int)data.m_electricityBuffer; if (num4 > 0) { int num6 = Singleton <ElectricityManager> .instance.TryFetchElectricity(data.m_position, electricityConsumption, num4); data.m_electricityBuffer += (ushort)num6; } if ((int)data.m_electricityBuffer < electricityConsumption) { flag2 = true; data.m_electricityProblemTimer = (byte)Mathf.Min(255, (int)(data.m_electricityProblemTimer + 1)); if (data.m_electricityProblemTimer >= 65) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Electricity | Notification.Problem.MajorProblem); } else if (data.m_electricityProblemTimer >= 3) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Electricity); } electricityUsage = (int)data.m_electricityBuffer; data.m_electricityBuffer = 0; if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Electricity)) { GuideController properties = Singleton <GuideManager> .instance.m_properties; if (properties != null) { int publicServiceIndex = ItemClass.GetPublicServiceIndex(ItemClass.Service.Electricity); int electricityCapacity = instance.m_districts.m_buffer[0].GetElectricityCapacity(); int electricityConsumption2 = instance.m_districts.m_buffer[0].GetElectricityConsumption(); if (electricityCapacity >= electricityConsumption2) { Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded2, ItemClass.Service.Electricity); } else { Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded, ItemClass.Service.Electricity); } } } } else { electricityUsage = electricityConsumption; data.m_electricityBuffer -= (ushort)electricityConsumption; } } else { heatingConsumption = 0; } if (!flag2) { data.m_electricityProblemTimer = 0; } if (flag != flag2) { Singleton <BuildingManager> .instance.UpdateBuildingColors(buildingID); } if (!flag3) { data.m_heatingProblemTimer = 0; } bool flag5 = false; int num7 = sewageAccumulation; if (waterConsumption != 0) { if ((policies & DistrictPolicies.Services.WaterSaving) != DistrictPolicies.Services.None) { waterConsumption = Mathf.Max(1, waterConsumption * 85 / 100); if (sewageAccumulation != 0) { sewageAccumulation = Mathf.Max(1, sewageAccumulation * 85 / 100); } Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class); } int num8 = waterConsumption * 2 - (int)data.m_waterBuffer; if (num8 > 0) { int num9 = Singleton <WaterManager> .instance.TryFetchWater(data.m_position, waterConsumption, num8, ref data.m_waterPollution); data.m_waterBuffer += (ushort)num9; } if ((int)data.m_waterBuffer < waterConsumption) { flag5 = true; data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1)); if (data.m_waterProblemTimer >= 65) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Water | Notification.Problem.MajorProblem); } else if (data.m_waterProblemTimer >= 3) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Water); } num7 = sewageAccumulation * (waterConsumption + (int)data.m_waterBuffer) / (waterConsumption << 1); waterUsage = (int)data.m_waterBuffer; data.m_waterBuffer = 0; if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Water)) { GuideController properties2 = Singleton <GuideManager> .instance.m_properties; if (properties2 != null) { int publicServiceIndex2 = ItemClass.GetPublicServiceIndex(ItemClass.Service.Water); int waterCapacity = instance.m_districts.m_buffer[0].GetWaterCapacity(); int waterConsumption2 = instance.m_districts.m_buffer[0].GetWaterConsumption(); if (waterCapacity >= waterConsumption2) { Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded2, ItemClass.Service.Water); } else { Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded, ItemClass.Service.Water); } } } } else { num7 = sewageAccumulation; waterUsage = waterConsumption; data.m_waterBuffer -= (ushort)waterConsumption; } } if (num7 != 0) { int num10 = num7 * 2 - (int)data.m_sewageBuffer; if (num10 < num7) { if (!flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None) { flag5 = true; data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1)); if (data.m_waterProblemTimer >= 65) { num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Sewage | Notification.Problem.MajorProblem); } else if (data.m_waterProblemTimer >= 3) { num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Sewage); } } sewageUsage = num10; data.m_sewageBuffer = (ushort)(num7 * 2); } else { sewageUsage = num7; data.m_sewageBuffer += (ushort)num7; } } if (!flag5) { data.m_waterProblemTimer = 0; } if (garbageAccumulation != 0) { int num11 = (int)(65535 - data.m_garbageBuffer); if (num11 < garbageAccumulation) { num = 0; data.m_garbageBuffer = (ushort)num11; } else { //start edit StormDrainAI stormDrainAI = data.Info.m_buildingAI as StormDrainAI; if (stormDrainAI == null) { data.m_garbageBuffer += (ushort)garbageAccumulation; } else if (stormDrainAI.m_filter == false) { data.m_garbageBuffer += (ushort)garbageAccumulation; } else { int pollutantAccumulation = Hydraulics.removePollutants(buildingID, Hydraulics.getPollutants(buildingID)); data.m_garbageBuffer += (ushort)pollutantAccumulation; //Debug.Log("[RF]CommonBuildingAI.handleCommonConsumption garbagebuffer = " + data.m_garbageBuffer.ToString()); } //end edit } } if (num7 != 0) { int num12 = Mathf.Min(num7 * 2, (int)data.m_sewageBuffer); if (num12 > 0) { int num13 = Singleton <WaterManager> .instance.TryDumpSewage(data.m_position, num7 * 2, num12); data.m_sewageBuffer -= (ushort)num13; } } if (garbageAccumulation != 0) { int num14 = (int)data.m_garbageBuffer; if (num14 >= 200 && Singleton <SimulationManager> .instance.m_randomizer.Int32(5u) == 0 && Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Garbage)) { int num15 = 0; int num16 = 0; int num17 = 0; int num18 = 0; this.CalculateGuestVehicles(buildingID, ref data, TransferManager.TransferReason.Garbage, ref num15, ref num16, ref num17, ref num18); num14 -= num17 - num16; if (num14 >= 200) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = num14 / 1000; offer.Building = buildingID; offer.Position = data.m_position; offer.Amount = 1; Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Garbage, offer); } } } if (this.CanSufferFromFlood()) { float num19 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(data.m_position)); if (num19 > data.m_position.y) { if (num19 > data.m_position.y + (float)ModSettings.BuildingFloodedTolerance / 100f) { //Debug.Log("[RF].CBAId Detoured Flooded Notification"); num = 0; problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem); } else if (num19 > data.m_position.y + (float)ModSettings.BuildingFloodingTolerance / 100f) { //Debug.Log("[RF].CBAId Detoured Flooding Notification"); num /= 2; problem = Notification.AddProblems(problem, Notification.Problem.Flood); GuideController properties3 = Singleton <GuideManager> .instance.m_properties; if (properties3 != null) { Singleton <BuildingManager> .instance.m_buildingFlooded.Activate(properties3.m_buildingFlooded, buildingID); } } } //Debug.Log("[RF].CBAId Detouring was sucessful!"); } byte district = instance.GetDistrict(data.m_position); instance.m_districts.m_buffer[(int)district].AddUsageData(electricityUsage, heatingUsage, waterUsage, sewageUsage); data.m_problems = problem; return(num); }
protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount) { bool flag = false; if (buildingData.m_netNode != 0) { NetManager instance = NetManager.instance; for (int i = 0; i < 8; i++) { if (instance.m_nodes.m_buffer[(int)buildingData.m_netNode].GetSegment(i) != 0) { flag = true; break; } } } if (!flag) { productionRate = 0; } DistrictManager instance2 = Singleton <DistrictManager> .instance; byte district = instance2.GetDistrict(buildingData.m_position); int waterProdMp = m_waterConsumption * m_consumption_multiplier; int waterRate = waterProdMp; //Debug.Log("Produce goods"); //Debug.Log("waterRate = " + waterRate); //Debug.Log("productionRate = " + productionRate); if (waterRate != 0) { int bufferedWater = (int)(buildingData.m_waterBuffer * m_bufferMultiplier); //Debug.Log("bufferedWater = " + bufferedWater); int missingWater = waterRate * 10 - bufferedWater; //Debug.Log("missingWater = " + missingWater); if (missingWater > 0) { byte pollution = 0; int fetchedWater = WaterManager.instance.TryFetchWater(buildingData.m_position, missingWater, missingWater, ref pollution); if (buildingData.m_productionRate < 100) { int fetchedWater2 = WaterManager.instance.TryFetchWater(buildingData.m_position, missingWater / 2, missingWater / 2, ref pollution); if (fetchedWater2 > 0) { if (buildingData.m_productionRate + 3 <= 100) { buildingData.m_productionRate += 3; } } } //Debug.Log("fetchedWater = " + fetchedWater); bufferedWater += fetchedWater; } int waterFinalRate = waterRate * productionRate / 100; if (bufferedWater - waterFinalRate > 0) { //Debug.Log("dumping water"); bufferedWater -= waterFinalRate; // Dump water to env this.HandleWaterSource(buildingID, ref buildingData, true, waterFinalRate, waterFinalRate, this.m_maxWaterDistance); } //if (bufferedWater - waterFinalRate * 4 > 0) //{ // if (buildingData.m_productionRate + 3 <= 100) // buildingData.m_productionRate += 3; //} if (bufferedWater - waterFinalRate * 4 < 0) { if (buildingData.m_productionRate > 3) { buildingData.m_productionRate -= 3; } } // Decrease buffer buildingData.m_waterBuffer = (ushort)((bufferedWater) / m_bufferMultiplier); //Debug.Log("m_waterBuffer =" + bufferedWater); DistrictManager.instance.m_districts.m_buffer[district].m_playerConsumption.m_tempWaterConsumption += (uint)waterRate; } base.HandleDead(buildingID, ref buildingData, ref behaviour, totalWorkerCount); int noiseRate = productionRate * this.m_noiseAccumulation / 100; if (noiseRate != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, noiseRate, buildingData.m_position, this.m_noiseRadius); } base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount); }
internal static float CalcMaxSpeed(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position position, Vector3 pos, float maxSpeed, bool isRecklessDriver) { var netManager = Singleton <NetManager> .instance; NetInfo segmentInfo = netManager.m_segments.m_buffer[(int)position.m_segment].Info; bool highwayRules = (segmentInfo.m_netAI is RoadBaseAI && ((RoadBaseAI)segmentInfo.m_netAI).m_highwayRules); if (!highwayRules) { if (netManager.m_treatWetAsSnow) { DistrictManager districtManager = Singleton <DistrictManager> .instance; byte district = districtManager.GetDistrict(pos); DistrictPolicies.CityPlanning cityPlanningPolicies = districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None) { if (Options.strongerRoadConditionEffects) { if (maxSpeed > ICY_ROADS_STUDDED_MIN_SPEED) { maxSpeed = ICY_ROADS_STUDDED_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - ICY_ROADS_STUDDED_MIN_SPEED); } } else { maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.0005882353f; // vanilla: -15% .. � } districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= DistrictPolicies.CityPlanning.StuddedTires; } else { if (Options.strongerRoadConditionEffects) { if (maxSpeed > ICY_ROADS_MIN_SPEED) { maxSpeed = ICY_ROADS_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - ICY_ROADS_MIN_SPEED); } } else { maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.00117647066f; // vanilla: -30% .. � } } } else { if (Options.strongerRoadConditionEffects) { float minSpeed = Math.Min(maxSpeed * WET_ROADS_FACTOR, WET_ROADS_MAX_SPEED); if (maxSpeed > minSpeed) { maxSpeed = minSpeed + (float)(255 - netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - minSpeed); } } else { maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.0005882353f; // vanilla: -15% .. � } } if (Options.strongerRoadConditionEffects) { float minSpeed = Math.Min(maxSpeed * BROKEN_ROADS_FACTOR, BROKEN_ROADS_MAX_SPEED); if (maxSpeed > minSpeed) { maxSpeed = minSpeed + (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_condition * 0.0039215686f * (maxSpeed - minSpeed); } } else { maxSpeed *= 1f + (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_condition * 0.0005882353f; // vanilla: � .. +15 % } } ExtVehicleType?vehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicle(vehicleId, ref vehicleData); float vehicleRand = Math.Min(1f, (float)(vehicleId % 101) * 0.01f); // we choose 101 because it's a prime number if (isRecklessDriver) { maxSpeed *= 1.5f + vehicleRand * 1.5f; // woohooo, 1.5 .. 3 } else if ((vehicleType & ExtVehicleType.PassengerCar) != ExtVehicleType.None) { maxSpeed *= 0.8f + vehicleRand * 0.3f; // a little variance, 0.8 .. 1.1 } else if ((vehicleType & ExtVehicleType.Taxi) != ExtVehicleType.None) { maxSpeed *= 0.9f + vehicleRand * 0.4f; // a little variance, 0.9 .. 1.3 } maxSpeed = Math.Max(MIN_SPEED, maxSpeed); // at least 10 km/h return(maxSpeed); }
// Detours public static void SimulationStep(ref ZoneBlock zoneBlock, ushort blockID) { // This is the decompiled ZoneBlock.SimulationStep() method // Segments which were changed are marked with "begin mod" and "end mod" if (Debugger.Enabled && debugCount < 10) { debugCount++; Debugger.LogFormat("Building Themes: Detoured ZoneBlock.SimulationStep was called. blockID: {0}, position: {1}.", blockID, zoneBlock.m_position); } ZoneManager zoneManager = Singleton <ZoneManager> .instance; int rowCount = zoneBlock.RowCount; float m_angle = zoneBlock.m_angle; Vector2 xDirection = new Vector2(Mathf.Cos(m_angle), Mathf.Sin(m_angle)) * 8f; Vector2 zDirection = new Vector2(xDirection.y, -xDirection.x); ulong num = zoneBlock.m_valid & ~(zoneBlock.m_occupied1 | zoneBlock.m_occupied2); int spawnpointRow = 0; ItemClass.Zone zone = ItemClass.Zone.Unzoned; int num3 = 0; while (num3 < 4 && zone == ItemClass.Zone.Unzoned) { spawnpointRow = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)rowCount); if ((num & 1uL << (spawnpointRow << 3)) != 0uL) { zone = zoneBlock.GetZone(0, spawnpointRow); } num3++; } DistrictManager instance2 = Singleton <DistrictManager> .instance; Vector3 m_position = (Vector3)zoneBlock.m_position; byte district = instance2.GetDistrict(m_position); int num4; switch (zone) { case ItemClass.Zone.ResidentialLow: num4 = zoneManager.m_actualResidentialDemand; num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialLowDemandOffset(); break; case ItemClass.Zone.ResidentialHigh: num4 = zoneManager.m_actualResidentialDemand; num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialHighDemandOffset(); break; case ItemClass.Zone.CommercialLow: num4 = zoneManager.m_actualCommercialDemand; num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialLowDemandOffset(); break; case ItemClass.Zone.CommercialHigh: num4 = zoneManager.m_actualCommercialDemand; num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialHighDemandOffset(); break; case ItemClass.Zone.Industrial: num4 = zoneManager.m_actualWorkplaceDemand; num4 += instance2.m_districts.m_buffer[(int)district].CalculateIndustrialDemandOffset(); break; case ItemClass.Zone.Office: num4 = zoneManager.m_actualWorkplaceDemand; num4 += instance2.m_districts.m_buffer[(int)district].CalculateOfficeDemandOffset(); break; default: return; } Vector2 a = VectorUtils.XZ(m_position); Vector2 vector3 = a - 3.5f * xDirection + ((float)spawnpointRow - 3.5f) * zDirection; int[] tmpXBuffer = zoneManager.m_tmpXBuffer; for (int i = 0; i < 13; i++) { tmpXBuffer[i] = 0; } Quad2 quad = default(Quad2); quad.a = a - 4f * xDirection + ((float)spawnpointRow - 10f) * zDirection; quad.b = a + 3f * xDirection + ((float)spawnpointRow - 10f) * zDirection; quad.c = a + 3f * xDirection + ((float)spawnpointRow + 2f) * zDirection; quad.d = a - 4f * xDirection + ((float)spawnpointRow + 2f) * zDirection; Vector2 vector4 = quad.Min(); Vector2 vector5 = quad.Max(); //begin mod int num5 = Mathf.Max((int)((vector4.x - 46f) / 64f + _zoneGridHalfResolution), 0); int num6 = Mathf.Max((int)((vector4.y - 46f) / 64f + _zoneGridHalfResolution), 0); int num7 = Mathf.Min((int)((vector5.x + 46f) / 64f + _zoneGridHalfResolution), _zoneGridResolution - 1); int num8 = Mathf.Min((int)((vector5.y + 46f) / 64f + _zoneGridHalfResolution), _zoneGridResolution - 1); //end mod for (int j = num6; j <= num8; j++) { for (int k = num5; k <= num7; k++) { //begin mod ushort num9 = zoneManager.m_zoneGrid[j * _zoneGridResolution + k]; //end mod int num10 = 0; while (num9 != 0) { Vector3 positionVar = zoneManager.m_blocks.m_buffer[(int)num9].m_position; float num11 = Mathf.Max(Mathf.Max(vector4.x - 46f - positionVar.x, vector4.y - 46f - positionVar.z), Mathf.Max(positionVar.x - vector5.x - 46f, positionVar.z - vector5.y - 46f)); if (num11 < 0f) { _CheckBlock.Invoke(zoneBlock, new object[] { zoneManager.m_blocks.m_buffer[(int)num9], tmpXBuffer, zone, vector3, xDirection, zDirection, quad }); } num9 = zoneManager.m_blocks.m_buffer[(int)num9].m_nextGridBlock; if (++num10 >= 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } for (int l = 0; l < 13; l++) { uint num12 = (uint)tmpXBuffer[l]; int num13 = 0; bool flag = (num12 & 196608u) == 196608u; bool flag2 = false; while ((num12 & 1u) != 0u) { num13++; flag2 = ((num12 & 65536u) != 0u); num12 >>= 1; } if (num13 == 5 || num13 == 6) { if (flag2) { num13 -= Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) + 2; } else { num13 = 4; } num13 |= 131072; } else if (num13 == 7) { num13 = 4; num13 |= 131072; } if (flag) { num13 |= 65536; } tmpXBuffer[l] = num13; } int num14 = tmpXBuffer[6] & 65535; if (num14 == 0) { return; } bool flag3 = (bool)_IsGoodPlace.Invoke(zoneBlock, new object[] { vector3 }); if (Singleton <SimulationManager> .instance.m_randomizer.Int32(100u) >= num4) { if (flag3) { zoneManager.m_goodAreaFound[(int)zone] = 1024; } return; } if (!flag3 && zoneManager.m_goodAreaFound[(int)zone] > -1024) { if (zoneManager.m_goodAreaFound[(int)zone] == 0) { zoneManager.m_goodAreaFound[(int)zone] = -1; } return; } int num15 = 6; int num16 = 6; bool flag4 = true; while (true) { if (flag4) { while (num15 != 0) { if ((tmpXBuffer[num15 - 1] & 65535) != num14) { break; } num15--; } while (num16 != 12) { if ((tmpXBuffer[num16 + 1] & 65535) != num14) { break; } num16++; } } else { while (num15 != 0) { if ((tmpXBuffer[num15 - 1] & 65535) < num14) { break; } num15--; } while (num16 != 12) { if ((tmpXBuffer[num16 + 1] & 65535) < num14) { break; } num16++; } } int num17 = num15; int num18 = num16; while (num17 != 0) { if ((tmpXBuffer[num17 - 1] & 65535) < 2) { break; } num17--; } while (num18 != 12) { if ((tmpXBuffer[num18 + 1] & 65535) < 2) { break; } num18++; } bool flag5 = num17 != 0 && num17 == num15 - 1; bool flag6 = num18 != 12 && num18 == num16 + 1; if (flag5 && flag6) { if (num16 - num15 > 2) { break; } if (num14 <= 2) { if (!flag4) { goto Block_34; } } else { num14--; } } else if (flag5) { if (num16 - num15 > 1) { goto Block_36; } if (num14 <= 2) { if (!flag4) { goto Block_38; } } else { num14--; } } else if (flag6) { if (num16 - num15 > 1) { goto Block_40; } if (num14 <= 2) { if (!flag4) { goto Block_42; } } else { num14--; } } else { if (num15 != num16) { goto IL_884; } if (num14 <= 2) { if (!flag4) { goto Block_45; } } else { num14--; } } flag4 = false; } num15++; num16--; Block_34: goto IL_891; Block_36: num15++; Block_38: goto IL_891; Block_40: num16--; Block_42: Block_45: IL_884: IL_891: int num19; int num20; if (num14 == 1 && num16 - num15 >= 1) { num15 += Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)(num16 - num15)); num16 = num15 + 1; num19 = num15 + Singleton <SimulationManager> .instance.m_randomizer.Int32(2u); num20 = num19; } else { do { num19 = num15; num20 = num16; if (num16 - num15 == 2) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0) { num20--; } else { num19++; } } else if (num16 - num15 == 3) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0) { num20 -= 2; } else { num19 += 2; } } else if (num16 - num15 == 4) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0) { num16 -= 2; num20 -= 3; } else { num15 += 2; num19 += 3; } } else if (num16 - num15 == 5) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0) { num16 -= 3; num20 -= 2; } else { num15 += 3; num19 += 2; } } else if (num16 - num15 >= 6) { if (num15 == 0 || num16 == 12) { if (num15 == 0) { num15 = 3; num19 = 2; } if (num16 == 12) { num16 = 9; num20 = 10; } } else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0) { num16 = num15 + 3; num20 = num19 + 2; } else { num15 = num16 - 3; num19 = num20 - 2; } } }while (num16 - num15 > 3 || num20 - num19 > 3); } int depth_A = 4; int width_A = num16 - num15 + 1; BuildingInfo.ZoningMode zoningMode = BuildingInfo.ZoningMode.Straight; bool flag7 = true; for (int m = num15; m <= num16; m++) { depth_A = Mathf.Min(depth_A, tmpXBuffer[m] & 65535); if ((tmpXBuffer[m] & 131072) == 0) { flag7 = false; } } if (num16 > num15) { if ((tmpXBuffer[num15] & 65536) != 0) { zoningMode = BuildingInfo.ZoningMode.CornerLeft; num20 = num15 + num20 - num19; num19 = num15; } if ((tmpXBuffer[num16] & 65536) != 0 && (zoningMode != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)) { zoningMode = BuildingInfo.ZoningMode.CornerRight; num19 = num16 + num19 - num20; num20 = num16; } } int depth_B = 4; int width_B = num20 - num19 + 1; BuildingInfo.ZoningMode zoningMode2 = BuildingInfo.ZoningMode.Straight; bool flag8 = true; for (int n = num19; n <= num20; n++) { depth_B = Mathf.Min(depth_B, tmpXBuffer[n] & 65535); if ((tmpXBuffer[n] & 131072) == 0) { flag8 = false; } } if (num20 > num19) { if ((tmpXBuffer[num19] & 65536) != 0) { zoningMode2 = BuildingInfo.ZoningMode.CornerLeft; } if ((tmpXBuffer[num20] & 65536) != 0 && (zoningMode2 != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)) { zoningMode2 = BuildingInfo.ZoningMode.CornerRight; } } ItemClass.SubService subService = ItemClass.SubService.None; ItemClass.Level level = ItemClass.Level.Level1; ItemClass.Service service; switch (zone) { case ItemClass.Zone.ResidentialLow: service = ItemClass.Service.Residential; subService = ItemClass.SubService.ResidentialLow; break; case ItemClass.Zone.ResidentialHigh: service = ItemClass.Service.Residential; subService = ItemClass.SubService.ResidentialHigh; break; case ItemClass.Zone.CommercialLow: service = ItemClass.Service.Commercial; subService = ItemClass.SubService.CommercialLow; break; case ItemClass.Zone.CommercialHigh: service = ItemClass.Service.Commercial; subService = ItemClass.SubService.CommercialHigh; break; case ItemClass.Zone.Industrial: service = ItemClass.Service.Industrial; break; case ItemClass.Zone.Office: service = ItemClass.Service.Office; subService = ItemClass.SubService.None; break; default: return; } BuildingInfo buildingInfo = null; Vector3 vector6 = Vector3.zero; int num25_row = 0; int length = 0; int width = 0; BuildingInfo.ZoningMode zoningMode3 = BuildingInfo.ZoningMode.Straight; int num28 = 0; // begin mod int depth_alt = Mathf.Min(depth_A, 4); int width_alt = width_A; // end mod while (num28 < 8) // while (num28 < 6) { switch (num28) { // Corner cases case 0: if (zoningMode != BuildingInfo.ZoningMode.Straight) { num25_row = num15 + num16 + 1; length = depth_A; width = width_A; zoningMode3 = zoningMode; goto IL_D6A; } break; case 1: if (zoningMode2 != BuildingInfo.ZoningMode.Straight) { num25_row = num19 + num20 + 1; length = depth_B; width = width_B; zoningMode3 = zoningMode2; goto IL_D6A; } break; case 2: if (zoningMode != BuildingInfo.ZoningMode.Straight) { if (depth_A >= 4) { num25_row = num15 + num16 + 1; length = ((!flag7) ? 2 : 3); width = width_A; zoningMode3 = zoningMode; goto IL_D6A; } } break; case 3: if (zoningMode2 != BuildingInfo.ZoningMode.Straight) { if (depth_B >= 4) { num25_row = num19 + num20 + 1; length = ((!flag8) ? 2 : 3); width = width_B; zoningMode3 = zoningMode2; goto IL_D6A; } } break; // begin mod case 4: if (zoningMode != BuildingInfo.ZoningMode.Straight) { if (width_alt > 1) { width_alt--; } else if (depth_alt > 1) { depth_alt--; width_alt = width_A; } else { break; } if (width_alt == width_A) { num25_row = num15 + num16 + 1; } else { if (zoningMode == BuildingInfo.ZoningMode.CornerLeft) { num25_row = num15 + num16 + 1 - (width_A - width_alt); } else { num25_row = num15 + num16 + 1 + (width_A - width_alt); } } length = depth_alt; width = width_alt; zoningMode3 = zoningMode; num28--; goto IL_D6A; } break; // end mod // Straight cases case 5: num25_row = num15 + num16 + 1; length = depth_A; width = width_A; zoningMode3 = BuildingInfo.ZoningMode.Straight; goto IL_D6A; case 6: // begin mod // reset variables depth_alt = Mathf.Min(depth_A, 4); width_alt = width_A; // end mod //int width_B = num20 - num19 + 1; num25_row = num19 + num20 + 1; length = depth_B; width = width_B; zoningMode3 = BuildingInfo.ZoningMode.Straight; goto IL_D6A; // begin mod case 7: if (width_alt > 1) { width_alt--; } else { break; } if (width_alt == width_A) { num25_row = num15 + num16 + 1; } else if (width_A % 2 != width_alt % 2) { num25_row = num15 + num16; } else { num25_row = num15 + num16 + 1; } length = depth_alt; width = width_alt; zoningMode3 = BuildingInfo.ZoningMode.Straight; num28--; goto IL_D6A; // end mod default: goto IL_D6A; } IL_DF0: num28++; continue; IL_D6A: vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection); if (zone == ItemClass.Zone.Industrial) { ZoneBlock.GetIndustryType(vector6, out subService, out level); } else if (zone == ItemClass.Zone.CommercialLow || zone == ItemClass.Zone.CommercialHigh) { ZoneBlock.GetCommercialType(vector6, zone, width, length, out subService, out level); } byte district2 = instance2.GetDistrict(vector6); ushort style = instance2.m_districts.m_buffer[(int)district2].m_Style; // begin mod // Here we are calling a custom getRandomBuildingInfo method buildingInfo = BuildingManagerDetour.GetRandomBuildingInfo_Spawn(vector6, ref Singleton <SimulationManager> .instance.m_randomizer, service, subService, level, width, length, zoningMode3, style); // end mod if (buildingInfo != null) { // begin mod // If the depth of the found prefab is smaller than the one we were looking for, recalculate the size // This is done by checking the position of every prop // Plots only get shrinked when no assets are placed on the extra space // This is needed for themes which only contain small buildings (e.g. 1x2) // because those buildings would occupy more space than needed! if (buildingInfo.GetWidth() == width && buildingInfo.GetLength() != length) { // Calculate the z position of the furthest away prop float biggestPropPosZ = 0; if (buildingInfo.m_props != null) { foreach (var prop in buildingInfo.m_props) { if (prop == null) { continue; } biggestPropPosZ = Mathf.Max(biggestPropPosZ, buildingInfo.m_expandFrontYard ? prop.m_position.z : -prop.m_position.z); } } // Check if the furthest away prop is outside of the bounds of the prefab float occupiedExtraSpace = biggestPropPosZ - buildingInfo.GetLength() * 4; if (occupiedExtraSpace <= 0) { // No? Then shrink the plot to the prefab length so no space is wasted! length = buildingInfo.GetLength(); } else { // Yes? Shrink the plot so all props are in the bounds int newLength = buildingInfo.GetLength() + Mathf.CeilToInt(occupiedExtraSpace / 8); length = Mathf.Min(length, newLength); } vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection); } // This block handles Corner buildings. We always shrink them else if (buildingInfo.GetLength() == width && buildingInfo.GetWidth() != length) { length = buildingInfo.GetWidth(); vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection); } // end mod if (Debugger.Enabled) { Debugger.LogFormat("Found prefab: {5} - {0}, {1}, {2}, {3} x {4}", service, subService, level, width, length, buildingInfo.name); } break; } if (Debugger.Enabled) { } goto IL_DF0; } if (buildingInfo == null) { if (Debugger.Enabled) { Debugger.LogFormat("No prefab found: {0}, {1}, {2}, {3} x {4}", service, subService, level, width, length); } return; } float num29 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector6)); if (num29 > vector6.y) { return; } float num30 = m_angle + 1.57079637f; if (zoningMode3 == BuildingInfo.ZoningMode.CornerLeft && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerRight) { num30 -= 1.57079637f; length = width; } else if (zoningMode3 == BuildingInfo.ZoningMode.CornerRight && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft) { num30 += 1.57079637f; length = width; } ushort num31; if (Singleton <BuildingManager> .instance.CreateBuilding(out num31, ref Singleton <SimulationManager> .instance.m_randomizer, buildingInfo, vector6, num30, length, Singleton <SimulationManager> .instance.m_currentBuildIndex)) { Singleton <SimulationManager> .instance.m_currentBuildIndex += 1u; switch (service) { case ItemClass.Service.Residential: zoneManager.m_actualResidentialDemand = Mathf.Max(0, zoneManager.m_actualResidentialDemand - 5); break; case ItemClass.Service.Commercial: zoneManager.m_actualCommercialDemand = Mathf.Max(0, zoneManager.m_actualCommercialDemand - 5); break; case ItemClass.Service.Industrial: zoneManager.m_actualWorkplaceDemand = Mathf.Max(0, zoneManager.m_actualWorkplaceDemand - 5); break; case ItemClass.Service.Office: zoneManager.m_actualWorkplaceDemand = Mathf.Max(0, zoneManager.m_actualWorkplaceDemand - 5); break; } switch (zone) { case ItemClass.Zone.ResidentialHigh: case ItemClass.Zone.CommercialHigh: { Building[] expr_FD7_cp_0 = Singleton <BuildingManager> .instance.m_buildings.m_buffer; ushort expr_FD7_cp_1 = num31; expr_FD7_cp_0[(int)expr_FD7_cp_1].m_flags = (expr_FD7_cp_0[(int)expr_FD7_cp_1].m_flags | Building.Flags.HighDensity); break; } } } zoneManager.m_goodAreaFound[(int)zone] = 1024; }
/// <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); }
private static bool CalculateLocalResources(int x, int z, ushort[] buffer, int[] global, ushort[] target, int index) { int resourceRate1 = (int)buffer[index] + global[0]; int resourceRate2 = (int)buffer[index + 1] + global[1]; int resourceRate3 = (int)buffer[index + 2] + global[2]; int resourceRate4 = (int)buffer[index + 3] + global[3]; int resourceRate5 = (int)buffer[index + 4] + global[4]; int resourceRate6 = (int)buffer[index + 5] + global[5]; int resourceRate7 = (int)buffer[index + 6] + global[6]; int resourceRate8 = (int)buffer[index + 7] + global[7]; int resourceRate9 = (int)buffer[index + 8] + global[8]; int num1 = (int)buffer[index + 9] + global[9]; int num2 = (int)buffer[index + 10] + global[10]; int num3 = (int)buffer[index + 11] + global[11]; int a = (int)buffer[index + 12] + global[12]; int resourceRate10 = (int)buffer[index + 13] + global[13]; int num4 = (int)buffer[index + 14] + global[14]; int num5 = (int)buffer[index + 15] + global[15]; int num6 = (int)buffer[index + 16] + global[16]; int num7 = (int)buffer[index + 17] + global[17]; int resourceRate11 = (int)buffer[index + 18] + global[18]; int resourceRate12 = (int)buffer[index + 19] + global[19]; int resourceRate13 = (int)buffer[index + 20] + global[20]; int resourceRate14 = (int)buffer[index + 21]; int num8 = (int)buffer[index + 22] + global[22]; int resourceRate15 = (int)buffer[index + 23] + global[23]; //begin mod Rect area = new Rect((float)(((double)x - HALFGRID - 1.5) * 38.4f), (float)(((double)z - HALFGRID - 1.5) * 38.4f), 153.6f, 153.6f); //end mod float groundPollution; float waterProximity; Singleton <NaturalResourceManager> .instance.AveragePollutionAndWater(area, out groundPollution, out waterProximity); int num9 = (int)((double)groundPollution * 100.0); int num10 = (int)((double)waterProximity * 100.0); if (num10 > 33 && num10 < 99) { //begin mod area = new Rect((float)(((double)x - HALFGRID + 0.25) * 38.4000015258789), (float)(((double)z - HALFGRID + 0.25) * 38.4000015258789), 19.2f, 19.2f); //end mod Singleton <NaturalResourceManager> .instance.AveragePollutionAndWater(area, out groundPollution, out waterProximity); num10 = Mathf.Max(Mathf.Min(num10, (int)((double)waterProximity * 100.0)), 33); } int resourceRate16 = num7 * 2 / (resourceRate2 + 50); int resourceRate17; int resourceRate18; int resourceRate19; if (a == 0) { resourceRate17 = 0; resourceRate18 = 50; resourceRate19 = 50; } else { resourceRate17 = num1 / a; resourceRate18 = num2 / a; resourceRate19 = num3 / a; num6 += Mathf.Min(a, 10) * 10; } //begin mod int num11 = ((Singleton <GameAreaManager> .instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= GRID - 2 || z <= 1 ? 1 : (z >= GRID - 2 ? 1 : 0))) == 0 ? (num4 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate1, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate3, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate2, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate4, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate5, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate6, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate7, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate8, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate12, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate10, 100, 500, 100, 200) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate19, 60, 100, 0, 50) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate18, 60, 100, 0, 50) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate13, 50, 100, 20, 25) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate15, 50, 100, 20, 25) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate14, 100, 1000, 0, 25) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate19, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate18, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(num9, 50, (int)byte.MaxValue, 50, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate9, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate17, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate16, 50, 100, 10, 50) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate11, 15, 50, 100, 200) + (ImmaterialResourceManager.CalculateResourceEffect(num10, 33, 67, 300, 0) * Mathf.Max(0, 32 - num9) >> 5)) / 10 : 0; //end mod int num12 = Mathf.Clamp(resourceRate1, 0, (int)ushort.MaxValue); int num13 = Mathf.Clamp(resourceRate2, 0, (int)ushort.MaxValue); int num14 = Mathf.Clamp(resourceRate3, 0, (int)ushort.MaxValue); int num15 = Mathf.Clamp(resourceRate4, 0, (int)ushort.MaxValue); int num16 = Mathf.Clamp(resourceRate5, 0, (int)ushort.MaxValue); int num17 = Mathf.Clamp(resourceRate6, 0, (int)ushort.MaxValue); int num18 = Mathf.Clamp(resourceRate7, 0, (int)ushort.MaxValue); int num19 = Mathf.Clamp(resourceRate8, 0, (int)ushort.MaxValue); int num20 = Mathf.Clamp(resourceRate9, 0, (int)ushort.MaxValue); int num21 = Mathf.Clamp(resourceRate17, 0, (int)ushort.MaxValue); int num22 = Mathf.Clamp(resourceRate18, 0, (int)ushort.MaxValue); int num23 = Mathf.Clamp(resourceRate19, 0, (int)ushort.MaxValue); int num24 = Mathf.Clamp(a, 0, (int)ushort.MaxValue); int num25 = Mathf.Clamp(resourceRate10, 0, (int)ushort.MaxValue); int landvalue = Mathf.Clamp(num11, 0, (int)ushort.MaxValue); int num26 = Mathf.Clamp(num5, 0, (int)ushort.MaxValue); int coverage = Mathf.Clamp(num6, 0, (int)ushort.MaxValue); int num27 = Mathf.Clamp(resourceRate16, 0, (int)ushort.MaxValue); int num28 = Mathf.Clamp(resourceRate11, 0, (int)ushort.MaxValue); int num29 = Mathf.Clamp(resourceRate12, 0, (int)ushort.MaxValue); int num30 = Mathf.Clamp(resourceRate13, 0, (int)ushort.MaxValue); int num31 = Mathf.Clamp(resourceRate14, 0, (int)ushort.MaxValue); int num32 = Mathf.Clamp(num8, 0, (int)ushort.MaxValue); int num33 = Mathf.Clamp(resourceRate15, 0, (int)ushort.MaxValue); DistrictManager instance = Singleton <DistrictManager> .instance; //begin mod byte district = instance.GetDistrict(x * FakeDistrictManager.GRID / GRID, z * FakeDistrictManager.GRID / GRID); //end mod instance.m_districts.m_buffer[(int)district].AddGroundData(landvalue, num9, coverage); bool flag = false; if (num12 != (int)target[index]) { target[index] = (ushort)num12; flag = true; } if (num13 != (int)target[index + 1]) { target[index + 1] = (ushort)num13; flag = true; } if (num14 != (int)target[index + 2]) { target[index + 2] = (ushort)num14; flag = true; } if (num15 != (int)target[index + 3]) { target[index + 3] = (ushort)num15; flag = true; } if (num16 != (int)target[index + 4]) { target[index + 4] = (ushort)num16; flag = true; } if (num17 != (int)target[index + 5]) { target[index + 5] = (ushort)num17; flag = true; } if (num18 != (int)target[index + 6]) { target[index + 6] = (ushort)num18; flag = true; } if (num19 != (int)target[index + 7]) { target[index + 7] = (ushort)num19; flag = true; } if (num20 != (int)target[index + 8]) { target[index + 8] = (ushort)num20; flag = true; } if (num21 != (int)target[index + 9]) { target[index + 9] = (ushort)num21; flag = true; } if (num22 != (int)target[index + 10]) { target[index + 10] = (ushort)num22; flag = true; } if (num23 != (int)target[index + 11]) { target[index + 11] = (ushort)num23; flag = true; } if (num24 != (int)target[index + 12]) { target[index + 12] = (ushort)num24; flag = true; } if (num25 != (int)target[index + 13]) { target[index + 13] = (ushort)num25; flag = true; } if (landvalue != (int)target[index + 14]) { target[index + 14] = (ushort)landvalue; flag = true; } if (num26 != (int)target[index + 15]) { target[index + 15] = (ushort)num26; flag = true; } if (coverage != (int)target[index + 16]) { target[index + 16] = (ushort)coverage; flag = true; } if (num27 != (int)target[index + 17]) { target[index + 17] = (ushort)num27; flag = true; } if (num28 != (int)target[index + 18]) { target[index + 18] = (ushort)num28; flag = true; } if (num29 != (int)target[index + 19]) { target[index + 19] = (ushort)num29; flag = true; } if (num30 != (int)target[index + 20]) { target[index + 20] = (ushort)num30; flag = true; } if (num31 != (int)target[index + 21]) { target[index + 21] = (ushort)num31; flag = true; } if (num32 != (int)target[index + 22]) { target[index + 22] = (ushort)num32; flag = true; } if (num33 != (int)target[index + 23]) { target[index + 23] = (ushort)num33; flag = true; } return(flag); }
public void CustomCalculateSegmentPositionPathFinder(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position position, uint laneId, byte offset, out Vector3 pos, out Vector3 dir, out float maxSpeed) { var netManager = Singleton <NetManager> .instance; netManager.m_lanes.m_buffer[laneId].CalculatePositionAndDirection(offset * 0.003921569f, out pos, out dir); var segmentInfo = netManager.m_segments.m_buffer[position.m_segment].Info; if (segmentInfo.m_lanes != null && segmentInfo.m_lanes.Length > position.m_lane) { // NON-STOCK CODE START float laneSpeedLimit = 1f; #if BENCHMARK using (var bm = new Benchmark(null, "GetLockFreeGameSpeedLimit")) { #endif if (!Options.customSpeedLimitsEnabled) { laneSpeedLimit = segmentInfo.m_lanes[position.m_lane].m_speedLimit; } else { // === START INLINED VERSION OF SpeedLimitManager.GetLockFreeGameSpeedLimit === ushort?[] fastArray = Flags.laneSpeedLimitArray[position.m_segment]; if (fastArray != null && fastArray.Length > position.m_lane && fastArray[position.m_lane] != null) { // === START INLINED VERSION OF SpeedLimitManager.ToGameSpeedLimit === laneSpeedLimit = (float)fastArray[position.m_lane]; if (laneSpeedLimit == 0) { laneSpeedLimit = SpeedLimitManager.MAX_SPEED; } else { laneSpeedLimit = laneSpeedLimit / 50f; } // === END INLINED VERSION OF SpeedLimitManager.ToGameSpeedLimit === // laneSpeedLimit = ToGameSpeedLimit((ushort)fastArray[position.m_lane]); } else { laneSpeedLimit = segmentInfo.m_lanes[position.m_lane].m_speedLimit; } // === END INLINED VERSION OF SpeedLimitManager.GetLockFreeGameSpeedLimit === //laneSpeedLimit = SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, segmentInfo.m_lanes[position.m_lane]); // info2.m_lanes[position.m_lane].m_speedLimit; // NON-STOCK CODE } //laneSpeedLimit = Options.customSpeedLimitsEnabled ? SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneId, info.m_lanes[position.m_lane]) : info.m_lanes[position.m_lane].m_speedLimit; // NON-STOCK CODE #if BENCHMARK } #endif // NON-STOCK CODE END maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit, netManager.m_lanes.m_buffer[laneId].m_curve); } else { maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f); } // NON-STOCK CODE START (stock code replaced) bool isRecklessDriver = VehicleStateManager.Instance.VehicleStates[vehicleId].recklessDriver; #if BENCHMARK using (var bm = new Benchmark(null, "CalcMaxSpeed")) { #endif // === START INLINED VERSION OF VehicleBehaviorManager.CalcMaxSpeed === if (Singleton <NetManager> .instance.m_treatWetAsSnow) { DistrictManager districtManager = Singleton <DistrictManager> .instance; byte district = districtManager.GetDistrict(pos); DistrictPolicies.CityPlanning cityPlanningPolicies = districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None) { if (Options.strongerRoadConditionEffects) { if (maxSpeed > VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED) { maxSpeed = VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED); } } else { maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.0005882353f; // vanilla: -15% .. ±0% } districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= DistrictPolicies.CityPlanning.StuddedTires; } else { if (Options.strongerRoadConditionEffects) { if (maxSpeed > VehicleBehaviorManager.ICY_ROADS_MIN_SPEED) { maxSpeed = VehicleBehaviorManager.ICY_ROADS_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - VehicleBehaviorManager.ICY_ROADS_MIN_SPEED); } } else { maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.00117647066f; // vanilla: -30% .. ±0% } } } else { if (Options.strongerRoadConditionEffects) { float minSpeed = Math.Min(maxSpeed * VehicleBehaviorManager.WET_ROADS_FACTOR, VehicleBehaviorManager.WET_ROADS_MAX_SPEED); // custom: -25% .. 0 if (maxSpeed > minSpeed) { maxSpeed = minSpeed + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - minSpeed); } } else { maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.0005882353f; // vanilla: -15% .. ±0% } } if (Options.strongerRoadConditionEffects) { float minSpeed = Math.Min(maxSpeed * VehicleBehaviorManager.BROKEN_ROADS_FACTOR, VehicleBehaviorManager.BROKEN_ROADS_MAX_SPEED); if (maxSpeed > minSpeed) { maxSpeed = minSpeed + (float)netManager.m_segments.m_buffer[position.m_segment].m_condition * 0.0039215686f * (maxSpeed - minSpeed); } } else { maxSpeed *= 1f + (float)netManager.m_segments.m_buffer[position.m_segment].m_condition * 0.0005882353f; // vanilla: ±0% .. +15 % } // === START INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds === if (Options.realisticSpeeds) { // === START INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds === float vehicleRand = 0.01f * (float)(vehicleId % 100); // float vehicleRand = 0.01f * (float)GetVehicleRand(vehicleId); // === END INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds === if (this.m_info.m_isLargeVehicle) { maxSpeed *= 0.9f + vehicleRand * 0.1f; // a little variance, 0.9 .. 1 } else if (isRecklessDriver) { maxSpeed *= 1.3f + vehicleRand * 1.7f; // woohooo, 1.3 .. 3 } else { maxSpeed *= 0.8f + vehicleRand * 0.5f; // a little variance, 0.8 .. 1.3 } } else if (isRecklessDriver) { maxSpeed *= 1.5f; } // === END INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds === //maxSpeed = ApplyRealisticSpeeds(maxSpeed, vehicleId, this.m_info, isRecklessDriver); maxSpeed = Math.Max(VehicleBehaviorManager.MIN_SPEED, maxSpeed); // at least 10 km/h // === END INLINED VERSION OF VehicleBehaviorManager.CalcMaxSpeed === //maxSpeed = VehicleBehaviorManager.Instance.CalcMaxSpeed(vehicleId, this.m_info, position, ref netManager.m_segments.m_buffer[position.m_segment], pos, maxSpeed, isRecklessDriver); #if BENCHMARK } #endif // NON-STOCK CODE END }
public void OriginalSimulationStep(ushort segmentID, ref NetSegment data) { if ((data.m_flags & NetSegment.Flags.Original) == NetSegment.Flags.None) { NetManager netManager = Singleton <NetManager> .instance; Vector3 pos = netManager.m_nodes.m_buffer[(int)data.m_startNode].m_position; Vector3 pos2 = netManager.m_nodes.m_buffer[(int)data.m_endNode].m_position; int n = this.GetMaintenanceCost(pos, pos2); bool f = (ulong)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15)); if (n != 0) { if (f) { n = n * 16 / 100 - n / 100 * 15; } else { n /= 100; } Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, n, this.m_info.m_class); } if (f) { float n2 = (float)netManager.m_nodes.m_buffer[(int)data.m_startNode].m_elevation; float n3 = (float)netManager.m_nodes.m_buffer[(int)data.m_endNode].m_elevation; if (this.IsUnderground()) { n2 = -n2; n3 = -n3; } int constructionCost = this.GetConstructionCost(pos, pos2, n2, n3); if (constructionCost != 0) { StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt64>(StatisticType.CityValue); if (statisticBase != null) { statisticBase.Add(constructionCost); } } } } SimulationManager instance = Singleton <SimulationManager> .instance; NetManager instance2 = Singleton <NetManager> .instance; Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Flood | Notification.Problem.Snow); float num = 0f; uint num2 = data.m_lanes; int num3 = 0; while (num3 < this.m_info.m_lanes.Length && num2 != 0u) { NetInfo.Lane lane = this.m_info.m_lanes[num3].ShallowClone(); if ((byte)(lane.m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != 0 && (lane.m_vehicleType & ~VehicleInfo.VehicleType.Bicycle) != VehicleInfo.VehicleType.None) { num += instance2.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_length; } num2 = instance2.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_nextLane; num3++; } int num4 = 0; if (data.m_trafficBuffer == 65535) { if ((data.m_flags & NetSegment.Flags.Blocked) == NetSegment.Flags.None) { data.m_flags |= NetSegment.Flags.Blocked; data.m_modifiedIndex = instance.m_currentBuildIndex++; } } else { data.m_flags &= ~NetSegment.Flags.Blocked; int num5 = Mathf.RoundToInt(num) << 4; if (num5 != 0) { num4 = (int)((byte)Mathf.Min((int)(data.m_trafficBuffer * 100) / num5, 100)); } } data.m_trafficBuffer = 0; if (num4 > (int)data.m_trafficDensity) { data.m_trafficDensity = (byte)Mathf.Min((int)(data.m_trafficDensity + 5), num4); } else if (num4 < (int)data.m_trafficDensity) { data.m_trafficDensity = (byte)Mathf.Max((int)(data.m_trafficDensity - 5), num4); } Vector3 position = instance2.m_nodes.m_buffer[(int)data.m_startNode].m_position; Vector3 position2 = instance2.m_nodes.m_buffer[(int)data.m_endNode].m_position; Vector3 vector = (position + position2) * 0.5f; bool flag = false; if ((this.m_info.m_setVehicleFlags & Vehicle.Flags.Underground) == 0) { float num6 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector)); if (num6 > vector.y + 1f) { flag = true; data.m_flags |= NetSegment.Flags.Flooded; problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem); } else { data.m_flags &= ~NetSegment.Flags.Flooded; if (num6 > vector.y) { flag = true; problem = Notification.AddProblems(problem, Notification.Problem.Flood); } } } DistrictManager instance3 = Singleton <DistrictManager> .instance; byte district = instance3.GetDistrict(vector); DistrictPolicies.CityPlanning cityPlanningPolicies = instance3.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; int num7 = (int)(100 - (data.m_trafficDensity - 100) * (data.m_trafficDensity - 100) / 100); if ((this.m_info.m_vehicleTypes & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None) { if ((this.m_info.m_setVehicleFlags & Vehicle.Flags.Underground) == 0) { int num8 = (int)data.m_wetness; if (!instance2.m_treatWetAsSnow) { if (flag) { num8 = 255; } else { int num9 = -(num8 + 63 >> 5); float num10 = Singleton <WeatherManager> .instance.SampleRainIntensity(vector, false); if (num10 != 0f) { int num11 = Mathf.RoundToInt(Mathf.Min(num10 * 4000f, 1000f)); num9 += instance.m_randomizer.Int32(num11, num11 + 99) / 100; } num8 = Mathf.Clamp(num8 + num9, 0, 255); } } else if (this.m_accumulateSnow) { if (flag) { num8 = 128; } else { float num12 = Singleton <WeatherManager> .instance.SampleRainIntensity(vector, false); if (num12 != 0f) { int num13 = Mathf.RoundToInt(num12 * 400f); int num14 = instance.m_randomizer.Int32(num13, num13 + 99) / 100; if (Singleton <UnlockManager> .instance.Unlocked(UnlockManager.Feature.Snowplow)) { num8 = Mathf.Min(num8 + num14, 255); } else { num8 = Mathf.Min(num8 + num14, 128); } } else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(4u) == 0) { num8 = Mathf.Max(num8 - 1, 0); } if (num8 >= 64 && (data.m_flags & (NetSegment.Flags.Blocked | NetSegment.Flags.Flooded)) == NetSegment.Flags.None && instance.m_randomizer.Int32(10u) == 0) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = num8 / 50; offer.NetSegment = segmentID; offer.Position = vector; offer.Amount = 1; Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Snow, offer); } if (num8 >= 192) { problem = Notification.AddProblems(problem, Notification.Problem.Snow); } District[] expr_4E2_cp_0_cp_0 = instance3.m_districts.m_buffer; byte expr_4E2_cp_0_cp_1 = district; expr_4E2_cp_0_cp_0[(int)expr_4E2_cp_0_cp_1].m_productionData.m_tempSnowCover = expr_4E2_cp_0_cp_0[(int)expr_4E2_cp_0_cp_1].m_productionData.m_tempSnowCover + (uint)num8; } } if (num8 != (int)data.m_wetness) { if (Mathf.Abs((int)data.m_wetness - num8) > 10) { data.m_wetness = (byte)num8; InstanceID empty = InstanceID.Empty; empty.NetSegment = segmentID; instance2.AddSmoothColor(empty); empty.NetNode = data.m_startNode; instance2.AddSmoothColor(empty); empty.NetNode = data.m_endNode; instance2.AddSmoothColor(empty); } else { data.m_wetness = (byte)num8; instance2.m_wetnessChanged = 256; } } } int num15; if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None) { num7 = num7 * 3 + 1 >> 1; num15 = Mathf.Min(700, (int)(50 + data.m_trafficDensity * 6)); } else { num15 = Mathf.Min(500, (int)(50 + data.m_trafficDensity * 4)); } if (!this.m_highwayRules) { int num16 = instance.m_randomizer.Int32(num15, num15 + 99) / 100; data.m_condition = (byte)Mathf.Max((int)data.m_condition - num16, 0); if (data.m_condition < 192 && (data.m_flags & (NetSegment.Flags.Blocked | NetSegment.Flags.Flooded)) == NetSegment.Flags.None && instance.m_randomizer.Int32(20u) == 0) { TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer); offer2.Priority = (int)((255 - data.m_condition) / 50); offer2.NetSegment = segmentID; offer2.Position = vector; offer2.Amount = 1; Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.RoadMaintenance, offer2); } } } if (!this.m_highwayRules) { if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.HeavyTrafficBan) != DistrictPolicies.CityPlanning.None) { data.m_flags |= NetSegment.Flags.HeavyBan; } else { data.m_flags &= ~NetSegment.Flags.HeavyBan; } if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BikeBan) != DistrictPolicies.CityPlanning.None) { data.m_flags |= NetSegment.Flags.BikeBan; } else { data.m_flags &= ~NetSegment.Flags.BikeBan; } if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.OldTown) != DistrictPolicies.CityPlanning.None) { data.m_flags |= NetSegment.Flags.CarBan; } else { data.m_flags &= ~NetSegment.Flags.CarBan; } } int num17 = this.m_noiseAccumulation * num7 / 100; if (num17 != 0) { float num18 = Vector3.Distance(position, position2); int num19 = Mathf.FloorToInt(num18 / this.m_noiseRadius); for (int i = 0; i < num19; i++) { Vector3 position3 = Vector3.Lerp(position, position2, (float)(i + 1) / (float)(num19 + 1)); Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num17, position3, this.m_noiseRadius); } } if (data.m_trafficDensity >= 50 && data.m_averageLength < 25f && (instance2.m_nodes.m_buffer[(int)data.m_startNode].m_flags & (NetNode.Flags.LevelCrossing | NetNode.Flags.TrafficLights)) == NetNode.Flags.TrafficLights && (instance2.m_nodes.m_buffer[(int)data.m_endNode].m_flags & (NetNode.Flags.LevelCrossing | NetNode.Flags.TrafficLights)) == NetNode.Flags.TrafficLights) { GuideController properties = Singleton <GuideManager> .instance.m_properties; if (properties != null) { Singleton <NetManager> .instance.m_shortRoadTraffic.Activate(properties.m_shortRoadTraffic, segmentID, false); } } data.m_problems = problem; }
public override void SimulationStep(ushort segmentID, ref NetSegment data) { //Start PlayerNEtAI.SimulationStep if (this.HasMaintenanceCost(segmentID, ref data)) { NetManager playerNetAIinstance = Singleton <NetManager> .instance; Vector3 playerNetAIposition = playerNetAIinstance.m_nodes.m_buffer[(int)data.m_startNode].m_position; Vector3 playerNetAIposition2 = playerNetAIinstance.m_nodes.m_buffer[(int)data.m_endNode].m_position; int playerNetAInum = this.GetMaintenanceCost(playerNetAIposition, playerNetAIposition2); bool playerNetAIflag = (ulong)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15)); if (playerNetAInum != 0) { if (playerNetAIflag) { playerNetAInum = playerNetAInum * 16 / 100 - playerNetAInum / 100 * 15; } else { playerNetAInum /= 100; } Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, playerNetAInum, this.m_info.m_class); } if (playerNetAIflag) { float playerNetAInum2 = (float)playerNetAIinstance.m_nodes.m_buffer[(int)data.m_startNode].m_elevation; float playerNetAInum3 = (float)playerNetAIinstance.m_nodes.m_buffer[(int)data.m_endNode].m_elevation; if (this.IsUnderground()) { playerNetAInum2 = -playerNetAInum2; playerNetAInum3 = -playerNetAInum3; } int constructionCost = this.GetConstructionCost(playerNetAIposition, playerNetAIposition2, playerNetAInum2, playerNetAInum3); if (constructionCost != 0) { StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt64>(StatisticType.CityValue); if (statisticBase != null) { statisticBase.Add(constructionCost); } } } } //End PlayerNEtAI.SimulationStep SimulationManager instance = Singleton <SimulationManager> .instance; NetManager instance2 = Singleton <NetManager> .instance; Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Flood | Notification.Problem.Snow); if ((data.m_flags & NetSegment.Flags.AccessFailed) != NetSegment.Flags.None && Singleton <SimulationManager> .instance.m_randomizer.Int32(16u) == 0) { data.m_flags &= ~NetSegment.Flags.AccessFailed; } float num = 0f; uint num2 = data.m_lanes; int num3 = 0; while (num3 < this.m_info.m_lanes.Length && num2 != 0u) { NetInfo.Lane lane = this.m_info.m_lanes[num3]; if ((byte)(lane.m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != 0 && (lane.m_vehicleType & ~VehicleInfo.VehicleType.Bicycle) != VehicleInfo.VehicleType.None) { num += instance2.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_length; } num2 = instance2.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_nextLane; num3++; } int num4 = 0; if (data.m_trafficBuffer == 65535) { if ((data.m_flags & NetSegment.Flags.Blocked) == NetSegment.Flags.None) { data.m_flags |= NetSegment.Flags.Blocked; data.m_modifiedIndex = instance.m_currentBuildIndex++; } } else { data.m_flags &= ~NetSegment.Flags.Blocked; int num5 = Mathf.RoundToInt(num) << 4; if (num5 != 0) { num4 = (int)((byte)Mathf.Min((int)(data.m_trafficBuffer * 100) / num5, 100)); } } data.m_trafficBuffer = 0; if (num4 > (int)data.m_trafficDensity) { data.m_trafficDensity = (byte)Mathf.Min((int)(data.m_trafficDensity + 5), num4); } else if (num4 < (int)data.m_trafficDensity) { data.m_trafficDensity = (byte)Mathf.Max((int)(data.m_trafficDensity - 5), num4); } Vector3 position = instance2.m_nodes.m_buffer[(int)data.m_startNode].m_position; Vector3 position2 = instance2.m_nodes.m_buffer[(int)data.m_endNode].m_position; Vector3 vector = (position + position2) * 0.5f; bool flag = false; if ((this.m_info.m_setVehicleFlags & Vehicle.Flags.Underground) == (Vehicle.Flags) 0) { float num6 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector)); // NON-STOCK CODE START if (num6 > vector.y + (float)ModSettings.RoadwayFloodedTolerance / 100) { flag = true; data.m_flags |= NetSegment.Flags.Flooded; //Debug.Log("[RF] Successfully detoured roadway flooded tolerance"); problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem); /*DisasterData floodedSinkHoleData = new DisasterData(); * floodedSinkHoleData.m_targetPosition = data.m_middlePosition; * floodedSinkHoleData.m_intensity = (byte)instance.m_randomizer.Int32(100u); */ Vector3 min = data.m_bounds.min; Vector3 max = data.m_bounds.max; RoadBaseAI.FloodParkedCars(min.x, min.z, max.x, max.z); } else { data.m_flags &= ~NetSegment.Flags.Flooded; // Rainfall compatibility float add = (float)ModSettings.RoadwayFloodingTolerance / 100; //Debug.Log("[RF] Successfully detoured roadway flooding tolerance"); if (num6 > vector.y + add) { flag = true; problem = Notification.AddProblems(problem, Notification.Problem.Flood); } } //Debug.Log("[RF] Successfully detoured roadway flooding tolerance: not flooding"); // NON-STOCK CODE END } DistrictManager instance3 = Singleton <DistrictManager> .instance; byte district = instance3.GetDistrict(vector); DistrictPolicies.CityPlanning cityPlanningPolicies = instance3.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; int num7 = (int)(100 - (data.m_trafficDensity - 100) * (data.m_trafficDensity - 100) / 100); if ((this.m_info.m_vehicleTypes & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None) { if ((this.m_info.m_setVehicleFlags & Vehicle.Flags.Underground) == (Vehicle.Flags) 0) { if (flag && (data.m_flags & (NetSegment.Flags.AccessFailed | NetSegment.Flags.Blocked)) == NetSegment.Flags.None && instance.m_randomizer.Int32(10u) == 0) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = 4; offer.NetSegment = segmentID; offer.Position = vector; offer.Amount = 1; Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.FloodWater, offer); } int num8 = (int)data.m_wetness; if (!instance2.m_treatWetAsSnow) { if (flag) { num8 = 255; } else { int num9 = -(num8 + 63 >> 5); float num10 = Singleton <WeatherManager> .instance.SampleRainIntensity(vector, false); if (num10 != 0f) { int num11 = Mathf.RoundToInt(Mathf.Min(num10 * 4000f, 1000f)); num9 += instance.m_randomizer.Int32(num11, num11 + 99) / 100; } num8 = Mathf.Clamp(num8 + num9, 0, 255); } } else if (this.m_accumulateSnow) { if (flag) { num8 = 128; } else { float num12 = Singleton <WeatherManager> .instance.SampleRainIntensity(vector, false); if (num12 != 0f) { int num13 = Mathf.RoundToInt(num12 * 400f); int num14 = instance.m_randomizer.Int32(num13, num13 + 99) / 100; if (Singleton <UnlockManager> .instance.Unlocked(UnlockManager.Feature.Snowplow)) { num8 = Mathf.Min(num8 + num14, 255); } else { num8 = Mathf.Min(num8 + num14, 128); } } else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(4u) == 0) { num8 = Mathf.Max(num8 - 1, 0); } if (num8 >= 64 && (data.m_flags & (NetSegment.Flags.AccessFailed | NetSegment.Flags.Blocked | NetSegment.Flags.Flooded)) == NetSegment.Flags.None && instance.m_randomizer.Int32(10u) == 0) { TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer); offer2.Priority = num8 / 50; offer2.NetSegment = segmentID; offer2.Position = vector; offer2.Amount = 1; Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Snow, offer2); } if (num8 >= 192) { problem = Notification.AddProblems(problem, Notification.Problem.Snow); } District[] expr_5B7_cp_0_cp_0 = instance3.m_districts.m_buffer; byte expr_5B7_cp_0_cp_1 = district; expr_5B7_cp_0_cp_0[(int)expr_5B7_cp_0_cp_1].m_productionData.m_tempSnowCover = expr_5B7_cp_0_cp_0[(int)expr_5B7_cp_0_cp_1].m_productionData.m_tempSnowCover + (uint)num8; } } if (num8 != (int)data.m_wetness) { if (Mathf.Abs((int)data.m_wetness - num8) > 10) { data.m_wetness = (byte)num8; InstanceID empty = InstanceID.Empty; empty.NetSegment = segmentID; instance2.AddSmoothColor(empty); empty.NetNode = data.m_startNode; instance2.AddSmoothColor(empty); empty.NetNode = data.m_endNode; instance2.AddSmoothColor(empty); } else { data.m_wetness = (byte)num8; instance2.m_wetnessChanged = 256; } } } int num15; if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None) { num7 = num7 * 3 + 1 >> 1; num15 = Mathf.Min(700, (int)(50 + data.m_trafficDensity * 6)); } else { num15 = Mathf.Min(500, (int)(50 + data.m_trafficDensity * 4)); } if (!this.m_highwayRules) { int num16 = instance.m_randomizer.Int32(num15, num15 + 99) / 100; data.m_condition = (byte)Mathf.Max((int)data.m_condition - num16, 0); if (data.m_condition < 192 && (data.m_flags & (NetSegment.Flags.AccessFailed | NetSegment.Flags.Blocked | NetSegment.Flags.Flooded)) == NetSegment.Flags.None && instance.m_randomizer.Int32(20u) == 0) { TransferManager.TransferOffer offer3 = default(TransferManager.TransferOffer); offer3.Priority = (int)((255 - data.m_condition) / 50); offer3.NetSegment = segmentID; offer3.Position = vector; offer3.Amount = 1; Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.RoadMaintenance, offer3); } } } if (!this.m_highwayRules) { if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.HeavyTrafficBan) != DistrictPolicies.CityPlanning.None) { data.m_flags |= NetSegment.Flags.HeavyBan; } else { data.m_flags &= ~NetSegment.Flags.HeavyBan; } if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BikeBan) != DistrictPolicies.CityPlanning.None) { data.m_flags |= NetSegment.Flags.BikeBan; } else { data.m_flags &= ~NetSegment.Flags.BikeBan; } if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.OldTown) != DistrictPolicies.CityPlanning.None) { data.m_flags |= NetSegment.Flags.CarBan; } else { data.m_flags &= ~NetSegment.Flags.CarBan; } } int num17 = this.m_noiseAccumulation * num7 / 100; if (num17 != 0) { float num18 = Vector3.Distance(position, position2); int num19 = Mathf.FloorToInt(num18 / this.m_noiseRadius); for (int i = 0; i < num19; i++) { Vector3 position3 = Vector3.Lerp(position, position2, (float)(i + 1) / (float)(num19 + 1)); Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num17, position3, this.m_noiseRadius); } } if (data.m_trafficDensity >= 50 && data.m_averageLength < 25f && (instance2.m_nodes.m_buffer[(int)data.m_startNode].m_flags & (NetNode.Flags.LevelCrossing | NetNode.Flags.TrafficLights)) == NetNode.Flags.TrafficLights && (instance2.m_nodes.m_buffer[(int)data.m_endNode].m_flags & (NetNode.Flags.LevelCrossing | NetNode.Flags.TrafficLights)) == NetNode.Flags.TrafficLights) { GuideController properties = Singleton <GuideManager> .instance.m_properties; if (properties != null) { Singleton <NetManager> .instance.m_shortRoadTraffic.Activate(properties.m_shortRoadTraffic, segmentID); } } if ((data.m_flags & NetSegment.Flags.Collapsed) != NetSegment.Flags.None) { GuideController properties2 = Singleton <GuideManager> .instance.m_properties; if (properties2 != null) { Singleton <NetManager> .instance.m_roadDestroyed.Activate(properties2.m_roadDestroyed, segmentID); Singleton <NetManager> .instance.m_roadDestroyed2.Activate(properties2.m_roadDestroyed2, this.m_info.m_class.m_service); } if ((ulong)(instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15))) { int delta = Mathf.RoundToInt(data.m_averageLength); StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DestroyedLength); statisticBase.Add(delta); } } data.m_problems = problem; }
public override void SimulationStep(ushort segmentID, ref NetSegment data) { //Start PlayerNEtAI.SimulationStep if (this.HasMaintenanceCost(segmentID, ref data)) { NetManager playerNetAIinstance = Singleton <NetManager> .instance; Vector3 playerNetAIposition = playerNetAIinstance.m_nodes.m_buffer[(int)data.m_startNode].m_position; Vector3 playerNetAIposition2 = playerNetAIinstance.m_nodes.m_buffer[(int)data.m_endNode].m_position; int playerNetAInum = this.GetMaintenanceCost(playerNetAIposition, playerNetAIposition2); bool playerNetAIflag = (ulong)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15)); if (playerNetAInum != 0) { if (playerNetAIflag) { playerNetAInum = playerNetAInum * 16 / 100 - playerNetAInum / 100 * 15; } else { playerNetAInum /= 100; } Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, playerNetAInum, this.m_info.m_class); } if (playerNetAIflag) { float playerNetAInum2 = (float)playerNetAIinstance.m_nodes.m_buffer[(int)data.m_startNode].m_elevation; float playerNetAInum3 = (float)playerNetAIinstance.m_nodes.m_buffer[(int)data.m_endNode].m_elevation; if (this.IsUnderground()) { playerNetAInum2 = -playerNetAInum2; playerNetAInum3 = -playerNetAInum3; } int constructionCost = this.GetConstructionCost(playerNetAIposition, playerNetAIposition2, playerNetAInum2, playerNetAInum3); if (constructionCost != 0) { StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt64>(StatisticType.CityValue); if (statisticBase != null) { statisticBase.Add(constructionCost); } } } } //End PlayerNEtAI.SimulationStep if (!this.m_invisible) { NetManager instance = Singleton <NetManager> .instance; Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Flood); Vector3 position = instance.m_nodes.m_buffer[(int)data.m_startNode].m_position; Vector3 position2 = instance.m_nodes.m_buffer[(int)data.m_endNode].m_position; Vector3 vector = (position + position2) * 0.5f; float num = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector)); if (num > vector.y + ModSettings.PedestrianPathFloodedTolerance) { if ((data.m_flags & NetSegment.Flags.Flooded) == NetSegment.Flags.None) { data.m_flags |= NetSegment.Flags.Flooded; data.m_modifiedIndex = Singleton <SimulationManager> .instance.m_currentBuildIndex++; } problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem); } else { data.m_flags &= ~NetSegment.Flags.Flooded; if (num > vector.y + ModSettings.PedestrianPathFloodingTolerance) { problem = Notification.AddProblems(problem, Notification.Problem.Flood); } } DistrictManager instance2 = Singleton <DistrictManager> .instance; byte district = instance2.GetDistrict(vector); DistrictPolicies.CityPlanning cityPlanningPolicies = instance2.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BikeBan) != DistrictPolicies.CityPlanning.None) { data.m_flags |= NetSegment.Flags.BikeBan; } else { data.m_flags &= ~NetSegment.Flags.BikeBan; } data.m_problems = problem; } if ((data.m_flags & NetSegment.Flags.Collapsed) != NetSegment.Flags.None && (ulong)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15))) { int delta = Mathf.RoundToInt(data.m_averageLength); StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DestroyedLength); statisticBase.Add(delta); } }
private static bool ticketPriceForPrefix(ushort vehicleID, ref Vehicle vehicleData, ref int __result) { var def = TransportSystemDefinition.from(vehicleData.Info); if (def == default(TransportSystemDefinition)) { return(true); } DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(vehicleData.m_targetPos3); DistrictPolicies.Services servicePolicies = instance.m_districts.m_buffer[(int)district].m_servicePolicies; DistrictPolicies.Event @event = instance.m_districts.m_buffer[(int)district].m_eventPolicies & Singleton <EventManager> .instance.GetEventPolicyMask(); float multiplier; if (vehicleData.Info.m_class.m_subService == ItemClass.SubService.PublicTransportTours) { multiplier = 1; } else { if ((servicePolicies & DistrictPolicies.Services.FreeTransport) != DistrictPolicies.Services.None) { __result = 0; return(false); } if ((@event & DistrictPolicies.Event.ComeOneComeAll) != DistrictPolicies.Event.None) { __result = 0; return(false); } if ((servicePolicies & DistrictPolicies.Services.HighTicketPrices) != DistrictPolicies.Services.None) { District[] expr_114_cp_0 = instance.m_districts.m_buffer; byte expr_114_cp_1 = district; expr_114_cp_0[(int)expr_114_cp_1].m_servicePoliciesEffect = (expr_114_cp_0[(int)expr_114_cp_1].m_servicePoliciesEffect | DistrictPolicies.Services.HighTicketPrices); multiplier = 5f / 4f; } else { multiplier = 1; } } if (vehicleData.m_transportLine == 0) { __result = (int)(def.GetTransportExtension().GetDefaultTicketPrice(0) * multiplier); return(false); } else { if (TLMTransportLineExtension.instance.IsUsingCustomConfig(vehicleData.m_transportLine)) { __result = (int)(TLMTransportLineExtension.instance.GetTicketPrice(vehicleData.m_transportLine) * multiplier); } else { __result = (int)(def.GetTransportExtension().GetTicketPrice(TLMLineUtils.getPrefix(vehicleData.m_transportLine)) * multiplier); } return(false); } }
/// <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; }