public static bool Prefix(Resource resource, int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level, DistrictPolicies.Taxation taxationPolicies, ref int __result, out bool __state) { __state = false; // Always ignore the private income handler if it's called from AddResource AddPrivateIncome.DontRunPatch = true; // Don't run patch when we are applying from the command handler if (DontRunPatch) { return(true); } // Flag to prevent adding resources when it's not possible in the respective command handler if (DontAddResource) { __result = amount; // Don't run actual method return(false); } if (amount == 0) { return(true); } // Check for resource types that only change in the simulation tick (ignore them in the client) if (MultiplayerManager.Instance.CurrentRole == MultiplayerRole.Client) { switch (resource) { case Resource.RewardAmount: case Resource.CitizenIncome: case Resource.PublicIncome: case Resource.TourismIncome: case Resource.ResourcePrice: // Tell the method caller that the money was added successfully __result = amount; return(false); case Resource.PrivateIncome: // Return the same amount as the real method would return (see EconomyManager::AddPrivateIncome) int taxRate = EconomyManager.instance.GetTaxRate(service, subService, level, taxationPolicies); taxRate = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Economics, taxRate); int taxMultiplier = ReflectionHelper.GetAttr <int>(EconomyManager.instance, "m_taxMultiplier"); __result = (int)((amount * taxRate * taxMultiplier + 999999L) / 1000000L); return(false); } } __state = true; return(true); }
public static bool Prefix(int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level, int taxRate) { if (amount < 0) { DebugLog.LogToFileOnly($"Error: EconomyManagerAddPrivateIncomePatch amount < 0 {service} {subService} {level}"); amount = 0; } if (taxRate == 115333) { //115333 means playerbuilding income //taxRate = 100; no need to send taxRate. CustomAddGovermentIncome(ref amount, service); service = ItemClass.Service.Industrial; subService = ItemClass.SubService.IndustrialGeneric; level = ItemClass.Level.Level3; } else if ((taxRate == 113333) || (taxRate == 114333)) { //113333 means tourist tourism income // 114333 means resident tourism income CustomAddTourismIncome(ref amount, taxRate); } else if (taxRate == 112333) { //112333 means personal slary tax income //taxRate = 100; no need to send taxRate. CustomAddPersonalTaxIncome(ref amount, service); } else if (taxRate == 111333) { //111333 means trade income //taxRate = 100; no need to send taxRate. CustomAddPrivateTradeIncome(ref amount, subService); } else if (taxRate >= 100) { taxRate = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Economics, taxRate); taxRate /= 100; CustomAddPrivateLandIncome(ref amount, subService, taxRate); } else { amount = 0; } Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.ResourcePrice, amount, service, subService, level, DistrictPolicies.Taxation.None); return(false); }
public static float GetResourcePrice(TransferManager.TransferReason material) { //Need to sync with RealCity mod float num; if (!RealConstructionThreading.reduceVehicle) { switch (material) { case TransferManager.TransferReason.Petrol: num = 3f; break; case TransferManager.TransferReason.Food: num = 1.5f; break; case TransferManager.TransferReason.Lumber: num = 2f; break; case TransferManager.TransferReason.Coal: num = 2.5f; break; default: DebugLog.LogToFileOnly("Error: Unknow material in RealConstruction = " + material.ToString()); num = 0f; break; } } else { switch (material) { case TransferManager.TransferReason.Petrol: num = 3f * RealConstructionThreading.reduceCargoDiv; break; case TransferManager.TransferReason.Food: num = 1.5f * RealConstructionThreading.reduceCargoDiv; break; case TransferManager.TransferReason.Lumber: num = 2f * RealConstructionThreading.reduceCargoDiv; break; case TransferManager.TransferReason.Coal: num = 2.5f * RealConstructionThreading.reduceCargoDiv; break; default: DebugLog.LogToFileOnly("Error: Unknow material in RealConstruction = " + material.ToString()); num = 0f; break; } } return((float)(UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f) * num); }
public static bool Prefix(ref int __result, TransferManager.TransferReason material, ItemClass.Service sourceService = ItemClass.Service.None) { bool canRisePrice = true; switch (material) { case TransferManager.TransferReason.AnimalProducts: __result = 150; break; case TransferManager.TransferReason.Flours: __result = 150; break; case TransferManager.TransferReason.Paper: __result = 200; break; case TransferManager.TransferReason.PlanedTimber: __result = 200; break; case TransferManager.TransferReason.Petroleum: __result = 300; break; case TransferManager.TransferReason.Plastics: __result = 300; break; case TransferManager.TransferReason.Glass: __result = 250; break; case TransferManager.TransferReason.Metals: __result = 250; break; case TransferManager.TransferReason.LuxuryProducts: __result = 350; break; case TransferManager.TransferReason.Oil: __result = 200; break; case TransferManager.TransferReason.Ore: __result = 160; break; case TransferManager.TransferReason.Logs: __result = 130; break; case TransferManager.TransferReason.Grain: __result = 100; break; case TransferManager.TransferReason.Goods: if (sourceService == ItemClass.Service.Fishing) { __result = 500; } else { __result = 0; } break; case TransferManager.TransferReason.Fish: __result = 150; canRisePrice = false; break; case TransferManager.TransferReason.Petrol: __result = 0; break; case TransferManager.TransferReason.Food: __result = 0; break; case TransferManager.TransferReason.Lumber: __result = 0; break; case TransferManager.TransferReason.Coal: __result = 0; break; case TransferManager.TransferReason.Shopping: case TransferManager.TransferReason.ShoppingB: case TransferManager.TransferReason.ShoppingC: case TransferManager.TransferReason.ShoppingD: case TransferManager.TransferReason.ShoppingE: case TransferManager.TransferReason.ShoppingH: if (sourceService == ItemClass.Service.Fishing) { __result = 200; canRisePrice = false; } else { __result = 0; } break; case TransferManager.TransferReason.Entertainment: case TransferManager.TransferReason.EntertainmentB: case TransferManager.TransferReason.EntertainmentC: case TransferManager.TransferReason.EntertainmentD: __result = 0; break; default: __result = 0; break; } if (RealCity.reduceVehicle) { if (canRisePrice) { __result <<= MainDataStore.reduceCargoDivShift; } } __result = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, __result); return(false); }
public static float GetResourcePrice(TransferManager.TransferReason material) { int priceInt = 0; float price; switch (material) { case TransferManager.TransferReason.Goods: price = 3.5f; if (RealCity.reduceVehicle) { price *= MainDataStore.reduceCargoDiv; } price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); break; case TransferManager.TransferReason.Petrol: price = 3f; if (RealCity.reduceVehicle) { price *= MainDataStore.reduceCargoDiv; } price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); break; case TransferManager.TransferReason.Food: price = 2.4f; if (RealCity.reduceVehicle) { price *= MainDataStore.reduceCargoDiv; } price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); break; case TransferManager.TransferReason.Lumber: price = 2.6f; if (RealCity.reduceVehicle) { price *= MainDataStore.reduceCargoDiv; } price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); break; case TransferManager.TransferReason.Coal: price = 2.8f; if (RealCity.reduceVehicle) { price *= MainDataStore.reduceCargoDiv; } price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); break; case TransferManager.TransferReason.Shopping: case TransferManager.TransferReason.ShoppingB: case TransferManager.TransferReason.ShoppingC: case TransferManager.TransferReason.ShoppingD: case TransferManager.TransferReason.ShoppingE: case TransferManager.TransferReason.ShoppingH: price = 5f; if (RealCity.reduceVehicle) { price *= MainDataStore.reduceCargoDiv; } price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); break; case TransferManager.TransferReason.Entertainment: case TransferManager.TransferReason.EntertainmentB: case TransferManager.TransferReason.EntertainmentC: case TransferManager.TransferReason.EntertainmentD: price = 1f; break; default: IndustryBuildingGetResourcePricePatch.Prefix(ref priceInt, material); price = priceInt / 100f; break; } return(price); }
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 int ProcessCitizenSalary(uint citizenId, bool checkOnly) { int salary = 0; if (citizenId != 0u) { Citizen.Flags citizenFlag = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenId].m_flags; if ((citizenFlag & Citizen.Flags.Student) != Citizen.Flags.None) { return(salary); } ushort workBuilding = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenId].m_workBuilding; if (workBuilding != 0u) { Building buildingData = Singleton <BuildingManager> .instance.m_buildings.m_buffer[workBuilding]; if (!IsGoverment(workBuilding)) { salary = BuildingData.buildingWorkCount[workBuilding]; if (!checkOnly) { if (buildingData.Info.m_class.m_service != ItemClass.Service.Office) { BuildingData.buildingMoney[workBuilding] -= salary; } } } else { //Goverment int aliveWorkCount = 0; int totalWorkCount = 0; Citizen.BehaviourData behaviour = default; RealCityCommonBuildingAI.InitDelegate(); RealCityCommonBuildingAI.GetWorkBehaviour((CommonBuildingAI)buildingData.Info.m_buildingAI, workBuilding, ref buildingData, ref behaviour, ref aliveWorkCount, ref totalWorkCount); int salaryMax = 0; switch (Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenId].EducationLevel) { case Citizen.Education.Uneducated: salaryMax = (int)(MainDataStore.govermentSalary * 0.5); salary = MainDataStore.govermentEducation0SalaryFixed; break; case Citizen.Education.OneSchool: salaryMax = (int)(MainDataStore.govermentSalary * 0.55); salary = MainDataStore.govermentEducation1SalaryFixed; break; case Citizen.Education.TwoSchools: salaryMax = (int)(MainDataStore.govermentSalary * 0.65); salary = MainDataStore.govermentEducation2SalaryFixed; break; case Citizen.Education.ThreeSchools: salaryMax = (int)(MainDataStore.govermentSalary * 0.8); salary = MainDataStore.govermentEducation3SalaryFixed; break; } int allWorkCount = 0; //Update to see if there is building workplace change. //If a building have 10 workers and have 100 workplacecount, we assume that the other 90 vitual workers are from outside //Which will give addition cost allWorkCount = TotalWorkCount(workBuilding, buildingData, false, false); if (totalWorkCount > allWorkCount) { Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenId].SetWorkplace(citizenId, 0, 0u); } float vitualWorkersRatio = (totalWorkCount != 0) ? (allWorkCount / (float)totalWorkCount) : 1f; //Budget offset for Salary int budget = Singleton <EconomyManager> .instance.GetBudget(buildingData.Info.m_class); salary = (int)(salary * budget / 100f); salary = Math.Max(salary, salaryMax); #if Debug DebugLog.LogToFileOnly("DebugInfo: LandPrice offset for Salary is " + landPriceOffset.ToString()); #endif salary = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, salary); if (!checkOnly) { var m_class = Singleton <BuildingManager> .instance.m_buildings.m_buffer[workBuilding].Info.m_class; Singleton <EconomyManager> .instance.FetchResource((EconomyManager.Resource) 16, (int)(salary * vitualWorkersRatio), m_class); MainDataStore.outsideTouristMoney += (salary * (vitualWorkersRatio - 1f) * MainDataStore.outsideTouristSalaryProfitRatio); } } } } return(salary); } //public
public static void ProcessFamily(uint homeID, ref CitizenUnit data) { if (RealCityResidentAI.preCitizenId > homeID) { //DebugLog.LogToFileOnly("Another period started"); MainDataStore.familyCount = RealCityResidentAI.familyCount; MainDataStore.citizenCount = RealCityResidentAI.citizenCount; MainDataStore.level2HighWealth = RealCityResidentAI.level2HighWealth; MainDataStore.level3HighWealth = RealCityResidentAI.level3HighWealth; MainDataStore.level1HighWealth = RealCityResidentAI.level1HighWealth; if (RealCityResidentAI.familyCount != 0) { MainDataStore.citizenSalaryPerFamily = ((RealCityResidentAI.citizenSalaryCount / RealCityResidentAI.familyCount)); MainDataStore.citizenExpensePerFamily = ((RealCityResidentAI.citizenExpenseCount / RealCityResidentAI.familyCount)); } MainDataStore.citizenExpense = RealCityResidentAI.citizenExpenseCount; MainDataStore.citizenSalaryTaxTotal = RealCityResidentAI.citizenSalaryTaxTotal; MainDataStore.citizenSalaryTotal = RealCityResidentAI.citizenSalaryCount; if (MainDataStore.familyCount < MainDataStore.familyWeightStableHigh) { MainDataStore.familyWeightStableHigh = (uint)MainDataStore.familyCount; } else { MainDataStore.familyWeightStableHigh = RealCityResidentAI.familyWeightStableHigh; } if (MainDataStore.familyCount < MainDataStore.familyWeightStableLow) { MainDataStore.familyWeightStableLow = (uint)MainDataStore.familyCount; } else { MainDataStore.familyWeightStableLow = RealCityResidentAI.familyWeightStableLow; } RealCityPrivateBuildingAI.profitBuildingMoneyFinal = RealCityPrivateBuildingAI.profitBuildingMoney; RealCityResidentAI.level3HighWealth = 0; RealCityResidentAI.level2HighWealth = 0; RealCityResidentAI.level1HighWealth = 0; RealCityResidentAI.familyCount = 0; RealCityResidentAI.citizenCount = 0; RealCityResidentAI.citizenSalaryCount = 0; RealCityResidentAI.citizenExpenseCount = 0; RealCityResidentAI.citizenSalaryTaxTotal = 0; RealCityResidentAI.tempCitizenSalaryTaxTotal = 0f; RealCityResidentAI.familyWeightStableHigh = 0; RealCityResidentAI.familyWeightStableLow = 0; RealCityPrivateBuildingAI.profitBuildingMoney = 0; } RealCityResidentAI.preCitizenId = homeID; RealCityResidentAI.familyCount++; if (homeID > 524288) { DebugLog.LogToFileOnly("Error: citizen ID greater than 524288"); } //DebugLog.LogToFileOnly($"ProcessCitizen pre family {homeID} moneny {CitizenUnitData.familyMoney[homeID]}"); //ProcessCitizen pre, gather all citizenMoney to familyMoney ProcessCitizen(homeID, ref data, true); //DebugLog.LogToFileOnly($"ProcessCitizen post family {homeID} moneny {CitizenUnitData.familyMoney[homeID]}"); //1.We calculate citizen income int familySalaryCurrent = 0; familySalaryCurrent += RealCityResidentAI.ProcessCitizenSalary(data.m_citizen0, false); familySalaryCurrent += RealCityResidentAI.ProcessCitizenSalary(data.m_citizen1, false); familySalaryCurrent += RealCityResidentAI.ProcessCitizenSalary(data.m_citizen2, false); familySalaryCurrent += RealCityResidentAI.ProcessCitizenSalary(data.m_citizen3, false); familySalaryCurrent += RealCityResidentAI.ProcessCitizenSalary(data.m_citizen4, false); RealCityResidentAI.citizenSalaryCount = RealCityResidentAI.citizenSalaryCount + familySalaryCurrent; if (familySalaryCurrent < 0) { DebugLog.LogToFileOnly("familySalaryCurrent< 0 in ResidentAI"); familySalaryCurrent = 0; } //2.We calculate salary tax float tax = (float)(Politics.residentTax << 1) * familySalaryCurrent / 100f; RealCityResidentAI.tempCitizenSalaryTaxTotal = RealCityResidentAI.tempCitizenSalaryTaxTotal + (int)tax; RealCityResidentAI.citizenSalaryTaxTotal = (int)RealCityResidentAI.tempCitizenSalaryTaxTotal; ProcessCitizenIncomeTax(homeID, tax); //3. We calculate expense int educationFee = 0; int hospitalFee = 0; int expenseRate = 0; CitizenManager instance = Singleton <CitizenManager> .instance; int tempEducationFee; int tempHospitalFee; if (data.m_citizen4 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen4)].Dead) { GetExpenseRate(data.m_citizen4, out expenseRate, out tempEducationFee, out tempHospitalFee); educationFee += tempEducationFee; hospitalFee += tempHospitalFee; } if (data.m_citizen3 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen3)].Dead) { GetExpenseRate(data.m_citizen3, out expenseRate, out tempEducationFee, out tempHospitalFee); educationFee += tempEducationFee; hospitalFee += tempHospitalFee; } if (data.m_citizen2 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen2)].Dead) { GetExpenseRate(data.m_citizen2, out expenseRate, out tempEducationFee, out tempHospitalFee); educationFee += tempEducationFee; hospitalFee += tempHospitalFee; } if (data.m_citizen1 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen1)].Dead) { GetExpenseRate(data.m_citizen1, out expenseRate, out tempEducationFee, out tempHospitalFee); educationFee += tempEducationFee; hospitalFee += tempHospitalFee; } if (data.m_citizen0 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen0)].Dead) { GetExpenseRate(data.m_citizen0, out expenseRate, out tempEducationFee, out tempHospitalFee); educationFee += tempEducationFee; hospitalFee += tempHospitalFee; } ProcessCitizenHouseRent(homeID, expenseRate); //campus DLC added. expenseRate = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Economics, expenseRate); RealCityResidentAI.citizenExpenseCount += (educationFee + expenseRate + hospitalFee); //4. income - expense float incomeMinusExpense = familySalaryCurrent - tax - educationFee - expenseRate; CitizenUnitData.familyMoney[homeID] += incomeMinusExpense; //5. Limit familyMoney if (CitizenUnitData.familyMoney[homeID] > 100000000f) { CitizenUnitData.familyMoney[homeID] = 100000000f; } if (CitizenUnitData.familyMoney[homeID] < -100000000f) { CitizenUnitData.familyMoney[homeID] = -100000000f; } //6. Caculate minimumLivingAllowance and benefitOffset if (CitizenUnitData.familyMoney[homeID] < (-(Politics.benefitOffset * MainDataStore.govermentSalary) / 100f)) { int num = (int)(-CitizenUnitData.familyMoney[homeID]); CitizenUnitData.familyMoney[homeID] += num; MainDataStore.minimumLivingAllowance += num; Singleton <EconomyManager> .instance.FetchResource((EconomyManager.Resource) 17, num, ItemClass.Service.Residential, ItemClass.SubService.None, ItemClass.Level.Level1); } else { if (Politics.benefitOffset > 0) { CitizenUnitData.familyMoney[homeID] += ((Politics.benefitOffset * MainDataStore.govermentSalary) / 100f); MainDataStore.minimumLivingAllowance += (int)((Politics.benefitOffset * MainDataStore.govermentSalary) / 100f); Singleton <EconomyManager> .instance.FetchResource((EconomyManager.Resource) 17, (int)((Politics.benefitOffset * MainDataStore.govermentSalary) / 100f), ItemClass.Service.Residential, ItemClass.SubService.None, ItemClass.Level.Level1); } } var canBuyGoodMoney = MainDataStore.maxGoodPurchase * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping); var familySalaryCurrentTmp = (familySalaryCurrent > canBuyGoodMoney) ? canBuyGoodMoney : familySalaryCurrent; //7. Process citizen status if ((CitizenUnitData.familyMoney[homeID] / (canBuyGoodMoney + 1000f - familySalaryCurrentTmp)) >= 30) { RealCityResidentAI.level3HighWealth++; } else if ((CitizenUnitData.familyMoney[homeID] / (canBuyGoodMoney + 1000f - familySalaryCurrentTmp)) >= 20) { RealCityResidentAI.level2HighWealth++; } else if ((CitizenUnitData.familyMoney[homeID] / (canBuyGoodMoney + 1000f - familySalaryCurrentTmp)) >= 10) { RealCityResidentAI.level1HighWealth++; } //8 reduce goods float reducedGoods; if (CitizenUnitData.familyMoney[homeID] < canBuyGoodMoney) { reducedGoods = CitizenUnitData.familyGoods[homeID] / 100f; } else { reducedGoods = CitizenUnitData.familyGoods[homeID] / 50f; } CitizenUnitData.familyGoods[homeID] = (ushort)COMath.Clamp((int)(CitizenUnitData.familyGoods[homeID] - reducedGoods), 0, 60000); data.m_goods = (ushort)(CitizenUnitData.familyGoods[homeID] / 10f); //9 Buy good from outside and try move family if (data.m_goods == 0) { if ((CitizenUnitData.familyMoney[homeID] > canBuyGoodMoney) && (familySalaryCurrent > 1)) { uint citizenID = 0u; int familySize = 0; if (data.m_citizen4 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen4)].Dead) { familySize++; citizenID = data.m_citizen4; instance.m_citizens.m_buffer[citizenID].m_flags &= ~Citizen.Flags.NeedGoods; } if (data.m_citizen3 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen3)].Dead) { familySize++; citizenID = data.m_citizen3; instance.m_citizens.m_buffer[citizenID].m_flags &= ~Citizen.Flags.NeedGoods; } if (data.m_citizen2 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen2)].Dead) { familySize++; citizenID = data.m_citizen2; instance.m_citizens.m_buffer[citizenID].m_flags &= ~Citizen.Flags.NeedGoods; } if (data.m_citizen1 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen1)].Dead) { familySize++; citizenID = data.m_citizen1; instance.m_citizens.m_buffer[citizenID].m_flags &= ~Citizen.Flags.NeedGoods; } if (data.m_citizen0 != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)data.m_citizen0)].Dead) { familySize++; citizenID = data.m_citizen0; instance.m_citizens.m_buffer[citizenID].m_flags &= ~Citizen.Flags.NeedGoods; } Singleton <ResidentAI> .instance.TryMoveFamily(citizenID, ref instance.m_citizens.m_buffer[citizenID], familySize); CitizenUnitData.familyGoods[homeID] = 5000; data.m_goods = (ushort)(CitizenUnitData.familyGoods[homeID] / 10f); CitizenUnitData.familyMoney[homeID] -= canBuyGoodMoney; MainDataStore.outsideGovermentMoney += (canBuyGoodMoney * MainDataStore.outsideGovermentProfitRatio); MainDataStore.outsideTouristMoney += (canBuyGoodMoney * MainDataStore.outsideCompanyProfitRatio * MainDataStore.outsideTouristSalaryProfitRatio); } } //ProcessCitizen post, split all familyMoney to CitizenMoney ProcessCitizen(homeID, ref data, false); }