static bool Prefix(ref int __result, ushort instanceID, ref CitizenInstance citizenData, Citizen.AgeGroup ageGroup) { // Cache as best we can. The order of calls is car, bike, taxi AIUtils.citizenCache = citizenData.m_citizen; // Not needed, but just in case Citizen citizen = Singleton <CitizenManager> .instance.m_citizens.m_buffer[(int)((UIntPtr)citizenData.m_citizen)]; ushort homeBuilding = citizen.m_homeBuilding; ItemClass.SubService subService = ItemClass.SubService.ResidentialLow; if (homeBuilding != 0) { DistrictManager instance = Singleton <DistrictManager> .instance; Building building = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)homeBuilding]; District district = instance.m_districts.m_buffer[instance.GetDistrict(building.m_position)]; DistrictPolicies.CityPlanning cityPlanningPolicies = district.m_cityPlanningPolicies; AIUtils.livesInBike = (cityPlanningPolicies & DistrictPolicies.CityPlanning.EncourageBiking) != DistrictPolicies.CityPlanning.None; subService = Singleton <BuildingManager> .instance.m_buildings.m_buffer[homeBuilding].Info.GetSubService(); } // Set the cache AIUtils.cacheArray = AIUtils.GetArray(citizen.WealthLevel, subService, ageGroup); // Original method return value. __result = AIUtils.cacheArray[DataStore.CAR]; if (Debugging.UseTransportLog) { Debugging.WriteToLog(Debugging.TransportLogName, citizen.WealthLevel + "-wealth " + ageGroup + " has " + __result + "% chance of driving."); } // Don't execute base method after this. return(false); }
public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { ItemClass @class = this.m_info.m_class; int level = (int)(@class.m_level >= 0 ? @class.m_level : 0); // Force it to 0 if the level was set to None groundPollution = DataStore.office[level][DataStore.GROUND_POLLUTION]; noisePollution = DataStore.office[level][DataStore.NOISE_POLLUTION]; }
public int CaculateLandFee(Building building, ushort buildingID) { DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(building.m_position); DistrictPolicies.Services servicePolicies = instance.m_districts.m_buffer[district].m_servicePolicies; DistrictPolicies.Taxation taxationPolicies = instance.m_districts.m_buffer[district].m_taxationPolicies; DistrictPolicies.CityPlanning cityPlanningPolicies = instance.m_districts.m_buffer[district].m_cityPlanningPolicies; GetLandRent(building, out int landFee); float taxRate; taxRate = Singleton <EconomyManager> .instance.GetTaxRate(building.Info.m_class, taxationPolicies); if (instance.IsPolicyLoaded(DistrictPolicies.Policies.ExtraInsulation)) { if ((servicePolicies & DistrictPolicies.Services.ExtraInsulation) != DistrictPolicies.Services.None) { taxRate = taxRate * 95 / 100; } } if ((servicePolicies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None) { taxRate = taxRate * 95 / 100; } if (((taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure) != DistrictPolicies.Taxation.None) && (building.Info.m_class.m_subService == ItemClass.SubService.CommercialLeisure)) { landFee = 0; } if (BuildingData.buildingMoney[buildingID] > 0) { if ((building.Info.m_class.m_service == ItemClass.Service.Commercial) || (building.Info.m_class.m_service == ItemClass.Service.Industrial)) { if (BuildingData.buildingMoney[buildingID] > (taxRate * landFee / 100f)) { return((int)(taxRate * landFee / 100f)); } else { return(0); } } else if (building.Info.m_class.m_service == ItemClass.Service.Office) { Citizen.BehaviourData behaviourData = default; int aliveWorkerCount = 0; int totalWorkerCount = 0; RealCityCommonBuildingAI.InitDelegate(); RealCityCommonBuildingAI.GetWorkBehaviour((OfficeBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); return((int)(totalWorkerCount * taxRate / 10f)); } } return(0); }
public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { groundPollution = 0; noisePollution = 0; int[] array = getArray(this.m_info, EXTRACT_LEVEL); groundPollution = (productionRate * array[DataStore.GROUND_POLLUTION]) / 100; noisePollution = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100; }
public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { ItemClass @class = this.m_info.m_class; int level = (int)(@class.m_level >= 0 ? @class.m_level : 0); // Force it to 0 if the level was set to None int[] array = (@class.m_subService == ItemClass.SubService.ResidentialHigh) ? DataStore.residentialHigh[level] : DataStore.residentialLow[level]; groundPollution = array[DataStore.GROUND_POLLUTION]; noisePollution = array[DataStore.NOISE_POLLUTION]; }
public override void SimulationStep(ushort buildingID, ref Building buildingData, ref Building.Frame frameData) { base.SimulationStep(buildingID, ref buildingData, ref frameData); SimulationManager instance = Singleton <SimulationManager> .instance; DistrictManager instance2 = Singleton <DistrictManager> .instance; byte district = instance2.GetDistrict(buildingData.m_position); DistrictPolicies.CityPlanning cityPlanningPolicies = instance2.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; if ((buildingData.m_flags & (Building.Flags.Completed | Building.Flags.Upgrading)) != Building.Flags.None) { instance2.m_districts.m_buffer[(int)district].AddResidentialData(buildingData.Width * buildingData.Length, (buildingData.m_flags & Building.Flags.Abandoned) != Building.Flags.None, (buildingData.m_flags & Building.Flags.Collapsed) != Building.Flags.None && frameData.m_fireDamage == 255, (buildingData.m_flags & Building.Flags.Collapsed) != Building.Flags.None && frameData.m_fireDamage != 255, this.m_info.m_class.m_subService); } if ((buildingData.m_levelUpProgress == 255 || (buildingData.m_flags & Building.Flags.Collapsed) == Building.Flags.None) && buildingData.m_fireIntensity == 0) { /* * if ((this.m_info.m_class.m_subService == ItemClass.SubService.ResidentialHigh || this.m_info.m_class.m_subService == ItemClass.SubService.ResidentialHighEco) && * (cityPlanningPolicies & DistrictPolicies.CityPlanning.HighriseBan) != DistrictPolicies.CityPlanning.None && this.m_info.m_class.m_level == ItemClass.Level.Level5 && * instance.m_randomizer.Int32(10u) == 0 && Singleton<ZoneManager>.instance.m_lastBuildIndex == instance.m_currentBuildIndex) * { * District[] expr_184_cp_0 = instance2.m_districts.m_buffer; * byte expr_184_cp_1 = district; * expr_184_cp_0[(int)expr_184_cp_1].m_cityPlanningPoliciesEffect = (expr_184_cp_0[(int)expr_184_cp_1].m_cityPlanningPoliciesEffect | DistrictPolicies.CityPlanning.HighriseBan); * buildingData.m_flags |= Building.Flags.Demolishing; * instance.m_currentBuildIndex += 1u; * } */ if (instance.m_randomizer.Int32(10u) == 0) { DistrictPolicies.Specialization specializationPolicies = instance2.m_districts.m_buffer[(int)district].m_specializationPolicies; DistrictPolicies.Specialization specialization = this.SpecialPolicyNeeded(); if (specialization != DistrictPolicies.Specialization.None) { if ((specializationPolicies & specialization) == DistrictPolicies.Specialization.None) { if (Singleton <ZoneManager> .instance.m_lastBuildIndex == instance.m_currentBuildIndex) { buildingData.m_flags |= Building.Flags.Demolishing; instance.m_currentBuildIndex += 1u; } } else { District[] expr_240_cp_0 = instance2.m_districts.m_buffer; byte expr_240_cp_1 = district; expr_240_cp_0[(int)expr_240_cp_1].m_specializationPoliciesEffect = (expr_240_cp_0[(int)expr_240_cp_1].m_specializationPoliciesEffect | specialization); } } else if ((specializationPolicies & DistrictPolicies.Specialization.Selfsufficient) != DistrictPolicies.Specialization.None && Singleton <ZoneManager> .instance.m_lastBuildIndex == instance.m_currentBuildIndex) { buildingData.m_flags |= Building.Flags.Demolishing; instance.m_currentBuildIndex += 1u; } } } }
public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { groundPollution = 0; noisePollution = 0; if (!m_pollutionEnabled) { return; } base.GetPollutionRates(productionRate, cityPlanningPolicies, out groundPollution, out noisePollution); }
public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { ItemClass @class = this.m_info.m_class; groundPollution = 0; noisePollution = 0; int level = (int)(@class.m_level >= 0 ? @class.m_level : 0); // Force it to 0 if the level was set to None int[] array = getArray(this.m_info, level); groundPollution = (productionRate * array[DataStore.GROUND_POLLUTION]) / 100; noisePollution = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100; }
public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { ItemClass item = this.m_info.m_class; int level = (int)(item.m_level >= 0 ? item.m_level : 0); // Force it to 0 if the level was set to None int[] array = GetArray(this.m_info, level); groundPollution = array[DataStore.GROUND_POLLUTION]; noisePollution = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100; if (item.m_subService == ItemClass.SubService.CommercialLeisure) { if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises) != DistrictPolicies.CityPlanning.None) { noisePollution /= 2; } } }
private int GetBikeProbability(ushort instanceID, ref CitizenInstance citizenData, Citizen.AgeGroup ageGroup) { Log.Error("CustomResidentAI.GetBikeProbability called!"); CitizenManager citizenManager = Singleton <CitizenManager> .instance; uint citizenId = citizenData.m_citizen; ushort homeId = citizenManager.m_citizens.m_buffer[(int)((UIntPtr)citizenId)].m_homeBuilding; int bikeEncouragement = 0; if (homeId != 0) { Vector3 position = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)homeId].m_position; DistrictManager districtManager = Singleton <DistrictManager> .instance; byte district = districtManager.GetDistrict(position); DistrictPolicies.CityPlanning cityPlanningPolicies = districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.EncourageBiking) != DistrictPolicies.CityPlanning.None) { bikeEncouragement = 10; } } switch (ageGroup) { case Citizen.AgeGroup.Child: return(ResidentAI.BIKE_PROBABILITY_CHILD + bikeEncouragement); case Citizen.AgeGroup.Teen: return(ResidentAI.BIKE_PROBABILITY_TEEN + bikeEncouragement); case Citizen.AgeGroup.Young: return(ResidentAI.BIKE_PROBABILITY_YOUNG + bikeEncouragement); case Citizen.AgeGroup.Adult: return(ResidentAI.BIKE_PROBABILITY_ADULT + bikeEncouragement); case Citizen.AgeGroup.Senior: return(ResidentAI.BIKE_PROBABILITY_SENIOR + bikeEncouragement); default: return(0); } }
public override BuildingInfo GetUpgradeInfo(ushort buildingID, ref Building data) { if (this.m_info.m_class.m_level == ItemClass.Level.Level5) { return(null); } Randomizer randomizer = new Randomizer((int)buildingID); for (int i = 0; i <= (int)this.m_info.m_class.m_level; i++) { randomizer.Int32(1000u); } ItemClass.Level level = this.m_info.m_class.m_level + 1; DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(data.m_position); DistrictPolicies.CityPlanning cityPlanningPolicies = instance.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; highRiseBan = ((cityPlanningPolicies & DistrictPolicies.CityPlanning.HighriseBan) != DistrictPolicies.CityPlanning.None); ushort style = instance.m_districts.m_buffer[(int)district].m_Style; return(Singleton <BuildingManager> .instance.GetRandomBuildingInfo(ref randomizer, this.m_info.m_class.m_service, this.m_info.m_class.m_subService, level, data.Width, data.Length, this.m_info.m_zoningMode, (int)style)); }
static bool Prefix(CommercialBuildingAI __instance, ItemClass.Level level, int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { ItemClass item = __instance.m_info.m_class; int[] array = CommercialBuildingAIMod.GetArray(__instance.m_info, (int)level); groundPollution = array[DataStore.GROUND_POLLUTION]; noisePollution = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100; if (item.m_subService == ItemClass.SubService.CommercialLeisure) { if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises) != DistrictPolicies.CityPlanning.None) { noisePollution /= 2; } } // Don't execute base method after this. return(false); }
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 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 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); }
static bool Prefix(IndustrialBuildingAI __instance, ItemClass.Level level, int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { ItemClass @class = __instance.m_info.m_class; groundPollution = 0; noisePollution = 0; int[] array = IndustrialBuildingAIMod.GetArray(__instance.m_info, (int)level); groundPollution = (productionRate * array[DataStore.GROUND_POLLUTION]) / 100; noisePollution = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100; // Don't execute base method after this. return(false); }
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; }
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); }
/// <summary> /// Returns the pollution generated by this building. /// </summary> /// <param name="level">Building level</param> /// <param name="productionRate">Bulding production rate</param> /// <param name="cityPlanningPolicies">Any applicable policies</param> /// <param name="groundPollution">Ground pollution generated by this building</param> /// <param name="noisePollution">Noise pollution generated by this builidng</param> public override void GetPollutionRates(ItemClass.Level level, int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { // If pollution is disabled, return zero. if (!m_pollutionEnabled) { groundPollution = 0; noisePollution = 0; return; } // Otherwise, use base method to calculate normal pollution levels. base.GetPollutionRates(level, productionRate, cityPlanningPolicies, out groundPollution, out noisePollution); }
public override void GetPollutionRates(ItemClass.Level level, int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution) { ItemClass @class = this.m_info.m_class; int[] array = getArray(this.m_info, (int)level); groundPollution = array[DataStore.GROUND_POLLUTION]; noisePollution = array[DataStore.NOISE_POLLUTION]; }
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 | DistrictPolicies.Services.RecyclePlastic); 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; case ItemClass.SubService.CommercialEco: instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies; 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."); } }
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); } }
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 static void GetAccumulation(CommercialBuildingAI thisAI, Randomizer r, int productionRate, int taxRate, DistrictPolicies.CityPlanning cityPlanningPolicies, DistrictPolicies.Taxation taxationPolicies, out int entertainment, out int attractiveness) { entertainment = 0; attractiveness = 0; Debug.LogWarning("GetAccumulation is not overridden!"); }
internal void GetIncome(ushort buildingID, Building buildingData, ref int income, ref int tourists) { DistrictManager instance = Singleton <DistrictManager> .instance; byte district = instance.GetDistrict(buildingData.m_position); DistrictPolicies.Services servicePolicies = instance.m_districts.m_buffer[(int)district].m_servicePolicies; ItemClass.Zone zone = buildingData.Info.m_class.GetZone(); int baseIncome = 0;// GetBaseIncome(buildingData.Info.m_class.m_level, zone); if ((servicePolicies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None) { baseIncome = baseIncome * 95 / 100; } int percentage = 100; if (zone == ItemClass.Zone.ResidentialHigh || zone == ItemClass.Zone.ResidentialLow) { GetCitizenIncome(CitizenUnit.Flags.Home, buildingData, ref income, ref tourists); } else if (zone == ItemClass.Zone.CommercialHigh || zone == ItemClass.Zone.CommercialLow) { GetCitizenIncome(CitizenUnit.Flags.Visit, buildingData, ref income, ref tourists); DistrictPolicies.CityPlanning cityPlanningPolicies = instance.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; if (buildingData.Info.m_class.m_subService == ItemClass.SubService.CommercialLow) { if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.SmallBusiness) != DistrictPolicies.CityPlanning.None) { baseIncome += 20; } } else if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BigBusiness) != DistrictPolicies.CityPlanning.None) { baseIncome += 20; } if ((servicePolicies & DistrictPolicies.Services.RecreationalUse) != DistrictPolicies.Services.None) { baseIncome = (baseIncome * 105 + 99) / 100; } if (buildingData.m_outgoingProblemTimer >= 128 || buildingData.m_customBuffer1 == 0) { percentage = 0; } } else if (zone == ItemClass.Zone.Industrial) { GetCitizenIncome(CitizenUnit.Flags.Work, buildingData, ref income, ref tourists); if (buildingData.m_outgoingProblemTimer >= 128 || buildingData.m_customBuffer1 == 0) { percentage = 0; } } else if (zone == ItemClass.Zone.Office) { GetCitizenIncome(CitizenUnit.Flags.Work, buildingData, ref income, ref tourists); } income = (income * baseIncome + 99) / 100; tourists = (tourists * baseIncome + 99) / 100; if (buildingData.m_electricityProblemTimer >= 1 || buildingData.m_waterProblemTimer >= 1 || buildingData.m_waterProblemTimer >= 1 || buildingData.m_garbageBuffer > 60000) { percentage = 0; } float num18 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(buildingData.m_position)); if (num18 > buildingData.m_position.y) { percentage = 0; } income = (income * percentage + 99) / 100; tourists = (tourists * percentage * 2 + 99) / 100; }