diff --git a/CustomAI/RealCityCommercialBuildingAI.cs b/CustomAI/RealCityCommercialBuildingAI.cs index ab96ffd..84a8591 100644 --- a/CustomAI/RealCityCommercialBuildingAI.cs +++ b/CustomAI/RealCityCommercialBuildingAI.cs @@ -4,28 +4,28 @@ namespace RealCity.CustomAI { - public class RealCityCommercialBuildingAI - { - public delegate TransferManager.TransferReason CommercialBuildingAIGetIncomingTransferReason(CommercialBuildingAI CommercialBuildingAI); - public static CommercialBuildingAIGetIncomingTransferReason GetIncomingTransferReason; + public class RealCityCommercialBuildingAI + { + public delegate TransferManager.TransferReason CommercialBuildingAIGetIncomingTransferReason(CommercialBuildingAI CommercialBuildingAI); + public static CommercialBuildingAIGetIncomingTransferReason GetIncomingTransferReason; - public delegate int CommercialBuildingAIMaxIncomingLoadSize(CommercialBuildingAI CommercialBuildingAI); - public static CommercialBuildingAIMaxIncomingLoadSize MaxIncomingLoadSize; + public delegate int CommercialBuildingAIMaxIncomingLoadSize(CommercialBuildingAI CommercialBuildingAI); + public static CommercialBuildingAIMaxIncomingLoadSize MaxIncomingLoadSize; - public delegate void CommercialBuildingAIGetVisitBehaviour(CommercialBuildingAI CommercialBuildingAI, ushort buildingID, ref Building buildingData, ref Citizen.BehaviourData behaviour, ref int aliveCount, ref int totalCount); - public static CommercialBuildingAIGetVisitBehaviour GetVisitBehaviour; + public delegate void CommercialBuildingAIGetVisitBehaviour(CommercialBuildingAI CommercialBuildingAI, ushort buildingID, ref Building buildingData, ref Citizen.BehaviourData behaviour, ref int aliveCount, ref int totalCount); + public static CommercialBuildingAIGetVisitBehaviour GetVisitBehaviour; - public static void InitDelegate() - { - if (GetIncomingTransferReason != null) - return; - if (MaxIncomingLoadSize != null) - return; - if (GetVisitBehaviour != null) - return; - GetVisitBehaviour = FastDelegateFactory.Create(typeof(CommercialBuildingAI), "GetVisitBehaviour", instanceMethod: true); - GetIncomingTransferReason = FastDelegateFactory.Create(typeof(CommercialBuildingAI), "GetIncomingTransferReason", instanceMethod: true); - MaxIncomingLoadSize = FastDelegateFactory.Create(typeof(CommercialBuildingAI), "MaxIncomingLoadSize", instanceMethod: true); - } - } + public static void InitDelegate() + { + if (GetIncomingTransferReason != null) + return; + if (MaxIncomingLoadSize != null) + return; + if (GetVisitBehaviour != null) + return; + GetVisitBehaviour = FastDelegateFactory.Create(typeof(CommercialBuildingAI), "GetVisitBehaviour", instanceMethod: true); + GetIncomingTransferReason = FastDelegateFactory.Create(typeof(CommercialBuildingAI), "GetIncomingTransferReason", instanceMethod: true); + MaxIncomingLoadSize = FastDelegateFactory.Create(typeof(CommercialBuildingAI), "MaxIncomingLoadSize", instanceMethod: true); + } + } } diff --git a/CustomAI/RealCityCommonBuildingAI.cs b/CustomAI/RealCityCommonBuildingAI.cs index 4c8f0fa..e49949f 100644 --- a/CustomAI/RealCityCommonBuildingAI.cs +++ b/CustomAI/RealCityCommonBuildingAI.cs @@ -6,34 +6,34 @@ namespace RealCity.CustomAI { - public class RealCityCommonBuildingAI - { - public delegate void CommonBuildingAICalculateGuestVehicles1(CommonBuildingAI CommonBuildingAI, ushort buildingID, ref Building data, TransferManager.TransferReason material1, TransferManager.TransferReason material2, ref int count, ref int cargo, ref int capacity, ref int outside); - public static CommonBuildingAICalculateGuestVehicles1 CalculateGuestVehicles1; + public class RealCityCommonBuildingAI + { + public delegate void CommonBuildingAICalculateGuestVehicles1(CommonBuildingAI CommonBuildingAI, ushort buildingID, ref Building data, TransferManager.TransferReason material1, TransferManager.TransferReason material2, ref int count, ref int cargo, ref int capacity, ref int outside); + public static CommonBuildingAICalculateGuestVehicles1 CalculateGuestVehicles1; - public delegate void CommonBuildingAICalculateGuestVehicles(CommonBuildingAI CommonBuildingAI, ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int count, ref int cargo, ref int capacity, ref int outside); - public static CommonBuildingAICalculateGuestVehicles CalculateGuestVehicles; + public delegate void CommonBuildingAICalculateGuestVehicles(CommonBuildingAI CommonBuildingAI, ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int count, ref int cargo, ref int capacity, ref int outside); + public static CommonBuildingAICalculateGuestVehicles CalculateGuestVehicles; - public delegate void CommonBuildingAICalculateOwnVehicles(CommonBuildingAI CommonBuildingAI, ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int count, ref int cargo, ref int capacity, ref int outside); - public static CommonBuildingAICalculateOwnVehicles CalculateOwnVehicles; + public delegate void CommonBuildingAICalculateOwnVehicles(CommonBuildingAI CommonBuildingAI, ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int count, ref int cargo, ref int capacity, ref int outside); + public static CommonBuildingAICalculateOwnVehicles CalculateOwnVehicles; - public delegate void CommonBuildingAIGetWorkBehaviour(CommonBuildingAI CommonBuildingAI, ushort buildingID, ref Building buildingData, ref Citizen.BehaviourData behaviour, ref int aliveCount, ref int totalCount); - public static CommonBuildingAIGetWorkBehaviour GetWorkBehaviour; + public delegate void CommonBuildingAIGetWorkBehaviour(CommonBuildingAI CommonBuildingAI, ushort buildingID, ref Building buildingData, ref Citizen.BehaviourData behaviour, ref int aliveCount, ref int totalCount); + public static CommonBuildingAIGetWorkBehaviour GetWorkBehaviour; - public static void InitDelegate() - { - if (CalculateOwnVehicles != null) - return; - if (GetWorkBehaviour != null) - return; - if (CalculateGuestVehicles != null) - return; - if (CalculateGuestVehicles1 != null) - return; - CalculateOwnVehicles = FastDelegateFactory.Create(typeof(CommonBuildingAI), "CalculateOwnVehicles", instanceMethod: true); - GetWorkBehaviour = FastDelegateFactory.Create(typeof(CommonBuildingAI), "GetWorkBehaviour", instanceMethod: true); - CalculateGuestVehicles = FastDelegateFactory.Create(typeof(CommonBuildingAI), "CalculateGuestVehicles", instanceMethod: true); - CalculateGuestVehicles1 = FastDelegateFactory.Create(typeof(CommonBuildingAI), "CalculateGuestVehicles", instanceMethod: true); - } - } + public static void InitDelegate() + { + if (CalculateOwnVehicles != null) + return; + if (GetWorkBehaviour != null) + return; + if (CalculateGuestVehicles != null) + return; + if (CalculateGuestVehicles1 != null) + return; + CalculateOwnVehicles = FastDelegateFactory.Create(typeof(CommonBuildingAI), "CalculateOwnVehicles", instanceMethod: true); + GetWorkBehaviour = FastDelegateFactory.Create(typeof(CommonBuildingAI), "GetWorkBehaviour", instanceMethod: true); + CalculateGuestVehicles = FastDelegateFactory.Create(typeof(CommonBuildingAI), "CalculateGuestVehicles", instanceMethod: true); + CalculateGuestVehicles1 = FastDelegateFactory.Create(typeof(CommonBuildingAI), "CalculateGuestVehicles", instanceMethod: true); + } + } } diff --git a/CustomAI/RealCityIndustrialBuildingAI.cs b/CustomAI/RealCityIndustrialBuildingAI.cs index 157f0da..34208ec 100644 --- a/CustomAI/RealCityIndustrialBuildingAI.cs +++ b/CustomAI/RealCityIndustrialBuildingAI.cs @@ -6,40 +6,40 @@ namespace RealCity.CustomAI { - public class RealCityIndustrialBuildingAI - { - public delegate TransferManager.TransferReason IndustrialBuildingAIGetIncomingTransferReason(IndustrialBuildingAI IndustrialBuildingAI, ushort buildingID); - public static IndustrialBuildingAIGetIncomingTransferReason GetIncomingTransferReason; + public class RealCityIndustrialBuildingAI + { + public delegate TransferManager.TransferReason IndustrialBuildingAIGetIncomingTransferReason(IndustrialBuildingAI IndustrialBuildingAI, ushort buildingID); + public static IndustrialBuildingAIGetIncomingTransferReason GetIncomingTransferReason; - public delegate TransferManager.TransferReason IndustrialBuildingAIGetOutgoingTransferReason(IndustrialBuildingAI IndustrialBuildingAI); - public static IndustrialBuildingAIGetOutgoingTransferReason GetOutgoingTransferReason; + public delegate TransferManager.TransferReason IndustrialBuildingAIGetOutgoingTransferReason(IndustrialBuildingAI IndustrialBuildingAI); + public static IndustrialBuildingAIGetOutgoingTransferReason GetOutgoingTransferReason; - public delegate TransferManager.TransferReason IndustrialBuildingAIGetSecondaryIncomingTransferReason(IndustrialBuildingAI IndustrialBuildingAI, ushort buildingID); - public static IndustrialBuildingAIGetSecondaryIncomingTransferReason GetSecondaryIncomingTransferReason; + public delegate TransferManager.TransferReason IndustrialBuildingAIGetSecondaryIncomingTransferReason(IndustrialBuildingAI IndustrialBuildingAI, ushort buildingID); + public static IndustrialBuildingAIGetSecondaryIncomingTransferReason GetSecondaryIncomingTransferReason; - public delegate int IndustrialBuildingAIMaxIncomingLoadSize(IndustrialBuildingAI IndustrialBuildingAI); - public static IndustrialBuildingAIMaxIncomingLoadSize MaxIncomingLoadSize; - - public delegate int IndustrialBuildingAIGetConsumptionDivider(IndustrialBuildingAI IndustrialBuildingAI); - public static IndustrialBuildingAIGetConsumptionDivider GetConsumptionDivider; + public delegate int IndustrialBuildingAIMaxIncomingLoadSize(IndustrialBuildingAI IndustrialBuildingAI); + public static IndustrialBuildingAIMaxIncomingLoadSize MaxIncomingLoadSize; - public static void InitDelegate() - { - if (GetIncomingTransferReason != null) - return; - if (GetOutgoingTransferReason != null) - return; - if (GetSecondaryIncomingTransferReason != null) - return; - if (MaxIncomingLoadSize != null) - return; - if (GetConsumptionDivider != null) - return; - GetIncomingTransferReason = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "GetIncomingTransferReason", instanceMethod: true); - GetOutgoingTransferReason = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "GetOutgoingTransferReason", instanceMethod: true); - GetSecondaryIncomingTransferReason = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "GetSecondaryIncomingTransferReason", instanceMethod: true); - MaxIncomingLoadSize = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "MaxIncomingLoadSize", instanceMethod: true); - GetConsumptionDivider = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "GetConsumptionDivider", instanceMethod: true); - } - } + public delegate int IndustrialBuildingAIGetConsumptionDivider(IndustrialBuildingAI IndustrialBuildingAI); + public static IndustrialBuildingAIGetConsumptionDivider GetConsumptionDivider; + + public static void InitDelegate() + { + if (GetIncomingTransferReason != null) + return; + if (GetOutgoingTransferReason != null) + return; + if (GetSecondaryIncomingTransferReason != null) + return; + if (MaxIncomingLoadSize != null) + return; + if (GetConsumptionDivider != null) + return; + GetIncomingTransferReason = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "GetIncomingTransferReason", instanceMethod: true); + GetOutgoingTransferReason = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "GetOutgoingTransferReason", instanceMethod: true); + GetSecondaryIncomingTransferReason = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "GetSecondaryIncomingTransferReason", instanceMethod: true); + MaxIncomingLoadSize = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "MaxIncomingLoadSize", instanceMethod: true); + GetConsumptionDivider = FastDelegateFactory.Create(typeof(IndustrialBuildingAI), "GetConsumptionDivider", instanceMethod: true); + } + } } diff --git a/CustomAI/RealCityIndustrialExtractorAI.cs b/CustomAI/RealCityIndustrialExtractorAI.cs index 218c140..b564ea1 100644 --- a/CustomAI/RealCityIndustrialExtractorAI.cs +++ b/CustomAI/RealCityIndustrialExtractorAI.cs @@ -2,17 +2,16 @@ namespace RealCity.CustomAI { - public class RealCityIndustrialExtractorAI - { - public delegate TransferManager.TransferReason IndustrialExtractorAIGetOutgoingTransferReason(IndustrialExtractorAI IndustrialExtractorAI); - public static IndustrialExtractorAIGetOutgoingTransferReason GetOutgoingTransferReason; + public class RealCityIndustrialExtractorAI + { + public delegate TransferManager.TransferReason IndustrialExtractorAIGetOutgoingTransferReason(IndustrialExtractorAI IndustrialExtractorAI); + public static IndustrialExtractorAIGetOutgoingTransferReason GetOutgoingTransferReason; - public static void InitDelegate() - { - if (GetOutgoingTransferReason != null) - return; - GetOutgoingTransferReason = FastDelegateFactory.Create(typeof(IndustrialExtractorAI), "GetOutgoingTransferReason", instanceMethod: true); - } - } + public static void InitDelegate() + { + if (GetOutgoingTransferReason != null) + return; + GetOutgoingTransferReason = FastDelegateFactory.Create(typeof(IndustrialExtractorAI), "GetOutgoingTransferReason", instanceMethod: true); + } + } } - diff --git a/CustomAI/RealCityIndustryBuildingAI.cs b/CustomAI/RealCityIndustryBuildingAI.cs index 1ae7b3e..5a7f337 100644 --- a/CustomAI/RealCityIndustryBuildingAI.cs +++ b/CustomAI/RealCityIndustryBuildingAI.cs @@ -3,77 +3,77 @@ namespace RealCity.CustomAI { - public class RealCityIndustryBuildingAI - { - 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 = 1.5f; - if (RealCity.reduceVehicle) - { - price *= MainDataStore.reduceCargoDiv; - } - price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); - break; - case TransferManager.TransferReason.Lumber: - price = 2f; - if (RealCity.reduceVehicle) - { - price *= MainDataStore.reduceCargoDiv; - } - price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); - break; - case TransferManager.TransferReason.Coal: - price = 2.5f; - 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; - } + public class RealCityIndustryBuildingAI + { + 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 = 1.5f; + if (RealCity.reduceVehicle) + { + price *= MainDataStore.reduceCargoDiv; + } + price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); + break; + case TransferManager.TransferReason.Lumber: + price = 2f; + if (RealCity.reduceVehicle) + { + price *= MainDataStore.reduceCargoDiv; + } + price *= (UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, 100) / 100f); + break; + case TransferManager.TransferReason.Coal: + price = 2.5f; + 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; - } - } + return price; + } + } } diff --git a/CustomAI/RealCityMarketAI.cs b/CustomAI/RealCityMarketAI.cs index 1026985..d76e0a4 100644 --- a/CustomAI/RealCityMarketAI.cs +++ b/CustomAI/RealCityMarketAI.cs @@ -4,16 +4,16 @@ namespace RealCity.CustomAI { - public class RealCityMarketAI - { - public delegate void MarketAIGetVisitBehaviour(MarketAI MarketAI, ushort buildingID, ref Building buildingData, ref Citizen.BehaviourData behaviour, ref int aliveCount, ref int totalCount); - public static MarketAIGetVisitBehaviour GetVisitBehaviour; + public class RealCityMarketAI + { + public delegate void MarketAIGetVisitBehaviour(MarketAI MarketAI, ushort buildingID, ref Building buildingData, ref Citizen.BehaviourData behaviour, ref int aliveCount, ref int totalCount); + public static MarketAIGetVisitBehaviour GetVisitBehaviour; - public static void InitDelegate() - { - if (GetVisitBehaviour != null) - return; - GetVisitBehaviour = FastDelegateFactory.Create(typeof(MarketAI), "GetVisitBehaviour", instanceMethod: true); - } - } + public static void InitDelegate() + { + if (GetVisitBehaviour != null) + return; + GetVisitBehaviour = FastDelegateFactory.Create(typeof(MarketAI), "GetVisitBehaviour", instanceMethod: true); + } + } } diff --git a/CustomAI/RealCityPlayerBuildingAI.cs b/CustomAI/RealCityPlayerBuildingAI.cs index 2f7f186..6957264 100644 --- a/CustomAI/RealCityPlayerBuildingAI.cs +++ b/CustomAI/RealCityPlayerBuildingAI.cs @@ -5,38 +5,38 @@ namespace RealCity.CustomAI { - public class RealCityPlayerBuildingAI - { - public static float CaculateEmployeeOutcome(ushort buildingID, Building building) - { - float allSalary = 0; - Citizen.BehaviourData behaviour = default(Citizen.BehaviourData); - int aliveWorkerCount = 0; - int totalWorkerCount = 0; - RealCityCommonBuildingAI.InitDelegate(); - RealCityCommonBuildingAI.GetWorkBehaviour((PlayerBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviour, ref aliveWorkerCount, ref totalWorkerCount); - int budget = Singleton.instance.GetBudget(building.Info.m_class); - int education0Salary = Math.Max((int)((budget * MainDataStore.govermentEducation0SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.5f)); - int education1Salary = Math.Max((int)((budget * MainDataStore.govermentEducation1SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.55f)); - int education2Salary = Math.Max((int)((budget * MainDataStore.govermentEducation2SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.65f)); - int education3Salary = Math.Max((int)((budget * MainDataStore.govermentEducation3SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.8f)); - allSalary += behaviour.m_educated0Count * education0Salary; - allSalary += behaviour.m_educated1Count * education1Salary; - allSalary += behaviour.m_educated2Count * education2Salary; - allSalary += behaviour.m_educated3Count * education3Salary; - int allWorkCount = RealCityResidentAI.TotalWorkCount(buildingID, building, true, false); - if (totalWorkerCount > allWorkCount) - { - allWorkCount = RealCityResidentAI.TotalWorkCount(buildingID, building, true, true); - } + public class RealCityPlayerBuildingAI + { + public static float CaculateEmployeeOutcome(ushort buildingID, Building building) + { + float allSalary = 0; + Citizen.BehaviourData behaviour = default(Citizen.BehaviourData); + int aliveWorkerCount = 0; + int totalWorkerCount = 0; + RealCityCommonBuildingAI.InitDelegate(); + RealCityCommonBuildingAI.GetWorkBehaviour((PlayerBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviour, ref aliveWorkerCount, ref totalWorkerCount); + int budget = Singleton.instance.GetBudget(building.Info.m_class); + int education0Salary = Math.Max((int)((budget * MainDataStore.govermentEducation0SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.5f)); + int education1Salary = Math.Max((int)((budget * MainDataStore.govermentEducation1SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.55f)); + int education2Salary = Math.Max((int)((budget * MainDataStore.govermentEducation2SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.65f)); + int education3Salary = Math.Max((int)((budget * MainDataStore.govermentEducation3SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.8f)); + allSalary += behaviour.m_educated0Count * education0Salary; + allSalary += behaviour.m_educated1Count * education1Salary; + allSalary += behaviour.m_educated2Count * education2Salary; + allSalary += behaviour.m_educated3Count * education3Salary; + int allWorkCount = RealCityResidentAI.TotalWorkCount(buildingID, building, true, false); + if (totalWorkerCount > allWorkCount) + { + allWorkCount = RealCityResidentAI.TotalWorkCount(buildingID, building, true, true); + } - if ((aliveWorkerCount == 0) && (allWorkCount != 0)) - { - allSalary = education3Salary * allWorkCount; - } + if ((aliveWorkerCount == 0) && (allWorkCount != 0)) + { + allSalary = education3Salary * allWorkCount; + } - float outsideWorkerRatio = (totalWorkerCount != 0) ? (allWorkCount / totalWorkerCount) : 1; - return allSalary * outsideWorkerRatio / 16f; - } - } + float outsideWorkerRatio = (totalWorkerCount != 0) ? (allWorkCount / totalWorkerCount) : 1; + return allSalary * outsideWorkerRatio / 16f; + } + } } diff --git a/CustomAI/RealCityPrivateBuildingAI.cs b/CustomAI/RealCityPrivateBuildingAI.cs index 83fe065..553dbc9 100644 --- a/CustomAI/RealCityPrivateBuildingAI.cs +++ b/CustomAI/RealCityPrivateBuildingAI.cs @@ -7,504 +7,504 @@ namespace RealCity.CustomAI { - public class RealCityPrivateBuildingAI - { - public static ushort allBuildings = 0; - public static uint preBuidlingId = 0; + public class RealCityPrivateBuildingAI + { + public static ushort allBuildings = 0; + public static uint preBuidlingId = 0; - public static int allOfficeLevel1WorkCount = 0; - public static int allOfficeLevel2WorkCount = 0; - public static int allOfficeLevel3WorkCount = 0; - public static int allOfficeHighTechWorkCount = 0; + public static int allOfficeLevel1WorkCount = 0; + public static int allOfficeLevel2WorkCount = 0; + public static int allOfficeLevel3WorkCount = 0; + public static int allOfficeHighTechWorkCount = 0; - public static int allOfficeLevel1WorkCountFinal = 0; - public static int allOfficeLevel2WorkCountFinal = 0; - public static int allOfficeLevel3WorkCountFinal = 0; - public static int allOfficeHighTechWorkCountFinal = 0; - public static long profitBuildingMoney = 0; - public static long profitBuildingMoneyFinal = 0; - public static ushort profitBuildingCount = 0; - public static ushort profitBuildingCountFinal = 0; - public static ushort allBuildingsFinal = 0; + public static int allOfficeLevel1WorkCountFinal = 0; + public static int allOfficeLevel2WorkCountFinal = 0; + public static int allOfficeLevel3WorkCountFinal = 0; + public static int allOfficeHighTechWorkCountFinal = 0; + public static long profitBuildingMoney = 0; + public static long profitBuildingMoneyFinal = 0; + public static ushort profitBuildingCount = 0; + public static ushort profitBuildingCountFinal = 0; + public static ushort allBuildingsFinal = 0; - public static void Load(ref byte[] saveData) - { - //60 - int i = 0; - SaveAndRestore.LoadData(ref i, saveData, ref preBuidlingId); + public static void Load(ref byte[] saveData) + { + //60 + int i = 0; + SaveAndRestore.LoadData(ref i, saveData, ref preBuidlingId); - SaveAndRestore.LoadData(ref i, saveData, ref allBuildings); - SaveAndRestore.LoadData(ref i, saveData, ref allBuildingsFinal); - SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel1WorkCount); - SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel2WorkCount); - SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel3WorkCount); - SaveAndRestore.LoadData(ref i, saveData, ref allOfficeHighTechWorkCount); - SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel1WorkCountFinal); - SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel2WorkCountFinal); - SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel3WorkCountFinal); - SaveAndRestore.LoadData(ref i, saveData, ref allOfficeHighTechWorkCountFinal); + SaveAndRestore.LoadData(ref i, saveData, ref allBuildings); + SaveAndRestore.LoadData(ref i, saveData, ref allBuildingsFinal); + SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel1WorkCount); + SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel2WorkCount); + SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel3WorkCount); + SaveAndRestore.LoadData(ref i, saveData, ref allOfficeHighTechWorkCount); + SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel1WorkCountFinal); + SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel2WorkCountFinal); + SaveAndRestore.LoadData(ref i, saveData, ref allOfficeLevel3WorkCountFinal); + SaveAndRestore.LoadData(ref i, saveData, ref allOfficeHighTechWorkCountFinal); - SaveAndRestore.LoadData(ref i, saveData, ref profitBuildingMoney); - SaveAndRestore.LoadData(ref i, saveData, ref profitBuildingMoneyFinal); - SaveAndRestore.LoadData(ref i, saveData, ref profitBuildingCount); - SaveAndRestore.LoadData(ref i, saveData, ref profitBuildingCountFinal); + SaveAndRestore.LoadData(ref i, saveData, ref profitBuildingMoney); + SaveAndRestore.LoadData(ref i, saveData, ref profitBuildingMoneyFinal); + SaveAndRestore.LoadData(ref i, saveData, ref profitBuildingCount); + SaveAndRestore.LoadData(ref i, saveData, ref profitBuildingCountFinal); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"RealCityPrivateBuildingAI Load Error: saveData.Length = {saveData.Length} + i = {i}"); - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"RealCityPrivateBuildingAI Load Error: saveData.Length = {saveData.Length} + i = {i}"); + } + } - public static void Save(ref byte[] saveData) - { - //60 - int i = 0; - SaveAndRestore.SaveData(ref i, preBuidlingId, ref saveData); + public static void Save(ref byte[] saveData) + { + //60 + int i = 0; + SaveAndRestore.SaveData(ref i, preBuidlingId, ref saveData); - SaveAndRestore.SaveData(ref i, allBuildings, ref saveData); - SaveAndRestore.SaveData(ref i, allBuildingsFinal, ref saveData); - SaveAndRestore.SaveData(ref i, allOfficeLevel1WorkCount, ref saveData); - SaveAndRestore.SaveData(ref i, allOfficeLevel2WorkCount, ref saveData); - SaveAndRestore.SaveData(ref i, allOfficeLevel3WorkCount, ref saveData); - SaveAndRestore.SaveData(ref i, allOfficeHighTechWorkCount, ref saveData); - SaveAndRestore.SaveData(ref i, allOfficeLevel1WorkCountFinal, ref saveData); - SaveAndRestore.SaveData(ref i, allOfficeLevel2WorkCountFinal, ref saveData); - SaveAndRestore.SaveData(ref i, allOfficeLevel3WorkCountFinal, ref saveData); - SaveAndRestore.SaveData(ref i, allOfficeHighTechWorkCountFinal, ref saveData); + SaveAndRestore.SaveData(ref i, allBuildings, ref saveData); + SaveAndRestore.SaveData(ref i, allBuildingsFinal, ref saveData); + SaveAndRestore.SaveData(ref i, allOfficeLevel1WorkCount, ref saveData); + SaveAndRestore.SaveData(ref i, allOfficeLevel2WorkCount, ref saveData); + SaveAndRestore.SaveData(ref i, allOfficeLevel3WorkCount, ref saveData); + SaveAndRestore.SaveData(ref i, allOfficeHighTechWorkCount, ref saveData); + SaveAndRestore.SaveData(ref i, allOfficeLevel1WorkCountFinal, ref saveData); + SaveAndRestore.SaveData(ref i, allOfficeLevel2WorkCountFinal, ref saveData); + SaveAndRestore.SaveData(ref i, allOfficeLevel3WorkCountFinal, ref saveData); + SaveAndRestore.SaveData(ref i, allOfficeHighTechWorkCountFinal, ref saveData); - SaveAndRestore.SaveData(ref i, profitBuildingMoney, ref saveData); - SaveAndRestore.SaveData(ref i, profitBuildingMoneyFinal, ref saveData); - SaveAndRestore.SaveData(ref i, profitBuildingCount, ref saveData); - SaveAndRestore.SaveData(ref i, profitBuildingCountFinal, ref saveData); + SaveAndRestore.SaveData(ref i, profitBuildingMoney, ref saveData); + SaveAndRestore.SaveData(ref i, profitBuildingMoneyFinal, ref saveData); + SaveAndRestore.SaveData(ref i, profitBuildingCount, ref saveData); + SaveAndRestore.SaveData(ref i, profitBuildingCountFinal, ref saveData); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"RealCityPrivateBuildingAI Save Error: saveData.Length = {saveData.Length} + i = {i}"); - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"RealCityPrivateBuildingAI Save Error: saveData.Length = {saveData.Length} + i = {i}"); + } + } - public static TransferManager.TransferReason GetIncomingProductionType(ushort buildingID, Building data) - { - RealCityIndustrialBuildingAI.InitDelegate(); - if (data.Info.m_buildingAI is IndustrialExtractorAI) - { - } - else - { - switch (data.Info.m_class.m_subService) - { - case ItemClass.SubService.CommercialHigh: - case ItemClass.SubService.CommercialLow: - case ItemClass.SubService.CommercialEco: - case ItemClass.SubService.CommercialLeisure: - case ItemClass.SubService.CommercialTourist: - CommercialBuildingAI commercialBuildingAI = data.Info.m_buildingAI as CommercialBuildingAI; - return commercialBuildingAI.m_incomingResource; - case ItemClass.SubService.IndustrialForestry: - case ItemClass.SubService.IndustrialFarming: - case ItemClass.SubService.IndustrialOil: - case ItemClass.SubService.IndustrialOre: - case ItemClass.SubService.IndustrialGeneric: - return RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); - } - } - return TransferManager.TransferReason.None; - } + public static TransferManager.TransferReason GetIncomingProductionType(ushort buildingID, Building data) + { + RealCityIndustrialBuildingAI.InitDelegate(); + if (data.Info.m_buildingAI is IndustrialExtractorAI) + { + } + else + { + switch (data.Info.m_class.m_subService) + { + case ItemClass.SubService.CommercialHigh: + case ItemClass.SubService.CommercialLow: + case ItemClass.SubService.CommercialEco: + case ItemClass.SubService.CommercialLeisure: + case ItemClass.SubService.CommercialTourist: + CommercialBuildingAI commercialBuildingAI = data.Info.m_buildingAI as CommercialBuildingAI; + return commercialBuildingAI.m_incomingResource; + case ItemClass.SubService.IndustrialForestry: + case ItemClass.SubService.IndustrialFarming: + case ItemClass.SubService.IndustrialOil: + case ItemClass.SubService.IndustrialOre: + case ItemClass.SubService.IndustrialGeneric: + return RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); + } + } + return TransferManager.TransferReason.None; + } - public static string GetProductionType(bool isSelling, ushort buildingID, Building data) - { - RealCityIndustrialBuildingAI.InitDelegate(); - string material = ""; - if (!isSelling) - { - if (data.Info.m_buildingAI is IndustrialExtractorAI) - { - } - else - { - switch (data.Info.m_class.m_subService) - { - case ItemClass.SubService.CommercialHigh: - case ItemClass.SubService.CommercialLow: - case ItemClass.SubService.CommercialEco: - case ItemClass.SubService.CommercialLeisure: - case ItemClass.SubService.CommercialTourist: - CommercialBuildingAI commercialBuildingAI = data.Info.m_buildingAI as CommercialBuildingAI; - switch (commercialBuildingAI.m_incomingResource) - { - case TransferManager.TransferReason.Goods: - material = Localization.Get("PREGOODS") + Localization.Get("LUXURY_PRODUCTS"); break; - case TransferManager.TransferReason.Food: - material = Localization.Get("FOOD") + Localization.Get("LUXURY_PRODUCTS"); break; - case TransferManager.TransferReason.Petrol: - material = Localization.Get("PETROL"); break; - case TransferManager.TransferReason.Lumber: - material = Localization.Get("LUMBER"); break; - case TransferManager.TransferReason.Logs: - material = Localization.Get("LOG"); break; - case TransferManager.TransferReason.Oil: - material = Localization.Get("OIL"); break; - case TransferManager.TransferReason.Ore: - material = Localization.Get("ORE"); break; - case TransferManager.TransferReason.Grain: - material = Localization.Get("GRAIN_MEAT"); break; - default: break; - } - break; - case ItemClass.SubService.IndustrialForestry: - case ItemClass.SubService.IndustrialFarming: - case ItemClass.SubService.IndustrialOil: - case ItemClass.SubService.IndustrialOre: - switch (RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID)) - { - case TransferManager.TransferReason.Grain: - material = Localization.Get("GRAIN_MEAT"); break; - case TransferManager.TransferReason.Logs: - material = Localization.Get("LOG"); break; - case TransferManager.TransferReason.Ore: - material = Localization.Get("ORE"); break; - case TransferManager.TransferReason.Oil: - material = Localization.Get("OIL"); break; - default: break; - } - break; - case ItemClass.SubService.IndustrialGeneric: - switch (RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID)) - { - case TransferManager.TransferReason.Food: - material = Localization.Get("FOOD"); break; - case TransferManager.TransferReason.Lumber: - material = Localization.Get("LUMBER"); break; - case TransferManager.TransferReason.Petrol: - material = Localization.Get("PETROL"); break; - case TransferManager.TransferReason.Coal: - material = Localization.Get("COAL"); break; - default: break; - } - switch (RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID)) - { - case TransferManager.TransferReason.AnimalProducts: - material += Localization.Get("ANIMALPRODUCTS"); break; - case TransferManager.TransferReason.Flours: - material += Localization.Get("FLOURS"); break; - case TransferManager.TransferReason.Paper: - material += Localization.Get("PAPER"); break; - case TransferManager.TransferReason.PlanedTimber: - material += Localization.Get("PLANEDTIMBER"); break; - case TransferManager.TransferReason.Petroleum: - material += Localization.Get("PETROLEUM"); break; - case TransferManager.TransferReason.Plastics: - material += Localization.Get("PLASTICS"); break; - case TransferManager.TransferReason.Glass: - material += Localization.Get("GLASS"); break; - case TransferManager.TransferReason.Metals: - material += Localization.Get("METALS"); break; - default: break; - } - break; - default: - material = ""; break; - } - } - } - else - { - if (data.Info.m_buildingAI is IndustrialExtractorAI) - { - switch (data.Info.m_class.m_subService) - { - case ItemClass.SubService.IndustrialForestry: - material = Localization.Get("LOG"); break; - case ItemClass.SubService.IndustrialFarming: - material = Localization.Get("GRAIN_MEAT"); break; - case ItemClass.SubService.IndustrialOil: - material = Localization.Get("OIL"); break; - case ItemClass.SubService.IndustrialOre: - material = Localization.Get("ORE"); break; - default: - material = ""; break; - } - } - else - { - switch (data.Info.m_class.m_subService) - { - case ItemClass.SubService.IndustrialForestry: - material = Localization.Get("LUMBER"); break; - case ItemClass.SubService.IndustrialFarming: - material = Localization.Get("FOOD"); break; - case ItemClass.SubService.IndustrialOil: - material = Localization.Get("PETROL"); break; - case ItemClass.SubService.IndustrialOre: - material = Localization.Get("COAL"); break; - case ItemClass.SubService.IndustrialGeneric: - material = Localization.Get("PREGOODS"); break; - case ItemClass.SubService.CommercialHigh: - case ItemClass.SubService.CommercialLow: - case ItemClass.SubService.CommercialEco: - case ItemClass.SubService.CommercialLeisure: - case ItemClass.SubService.CommercialTourist: - material = Localization.Get("GOODS"); break; - default: - material = ""; break; - } - } - } - return material; - } + public static string GetProductionType(bool isSelling, ushort buildingID, Building data) + { + RealCityIndustrialBuildingAI.InitDelegate(); + string material = ""; + if (!isSelling) + { + if (data.Info.m_buildingAI is IndustrialExtractorAI) + { + } + else + { + switch (data.Info.m_class.m_subService) + { + case ItemClass.SubService.CommercialHigh: + case ItemClass.SubService.CommercialLow: + case ItemClass.SubService.CommercialEco: + case ItemClass.SubService.CommercialLeisure: + case ItemClass.SubService.CommercialTourist: + CommercialBuildingAI commercialBuildingAI = data.Info.m_buildingAI as CommercialBuildingAI; + switch (commercialBuildingAI.m_incomingResource) + { + case TransferManager.TransferReason.Goods: + material = Localization.Get("PREGOODS") + Localization.Get("LUXURY_PRODUCTS"); break; + case TransferManager.TransferReason.Food: + material = Localization.Get("FOOD") + Localization.Get("LUXURY_PRODUCTS"); break; + case TransferManager.TransferReason.Petrol: + material = Localization.Get("PETROL"); break; + case TransferManager.TransferReason.Lumber: + material = Localization.Get("LUMBER"); break; + case TransferManager.TransferReason.Logs: + material = Localization.Get("LOG"); break; + case TransferManager.TransferReason.Oil: + material = Localization.Get("OIL"); break; + case TransferManager.TransferReason.Ore: + material = Localization.Get("ORE"); break; + case TransferManager.TransferReason.Grain: + material = Localization.Get("GRAIN_MEAT"); break; + default: break; + } + break; + case ItemClass.SubService.IndustrialForestry: + case ItemClass.SubService.IndustrialFarming: + case ItemClass.SubService.IndustrialOil: + case ItemClass.SubService.IndustrialOre: + switch (RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID)) + { + case TransferManager.TransferReason.Grain: + material = Localization.Get("GRAIN_MEAT"); break; + case TransferManager.TransferReason.Logs: + material = Localization.Get("LOG"); break; + case TransferManager.TransferReason.Ore: + material = Localization.Get("ORE"); break; + case TransferManager.TransferReason.Oil: + material = Localization.Get("OIL"); break; + default: break; + } + break; + case ItemClass.SubService.IndustrialGeneric: + switch (RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID)) + { + case TransferManager.TransferReason.Food: + material = Localization.Get("FOOD"); break; + case TransferManager.TransferReason.Lumber: + material = Localization.Get("LUMBER"); break; + case TransferManager.TransferReason.Petrol: + material = Localization.Get("PETROL"); break; + case TransferManager.TransferReason.Coal: + material = Localization.Get("COAL"); break; + default: break; + } + switch (RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID)) + { + case TransferManager.TransferReason.AnimalProducts: + material += Localization.Get("ANIMALPRODUCTS"); break; + case TransferManager.TransferReason.Flours: + material += Localization.Get("FLOURS"); break; + case TransferManager.TransferReason.Paper: + material += Localization.Get("PAPER"); break; + case TransferManager.TransferReason.PlanedTimber: + material += Localization.Get("PLANEDTIMBER"); break; + case TransferManager.TransferReason.Petroleum: + material += Localization.Get("PETROLEUM"); break; + case TransferManager.TransferReason.Plastics: + material += Localization.Get("PLASTICS"); break; + case TransferManager.TransferReason.Glass: + material += Localization.Get("GLASS"); break; + case TransferManager.TransferReason.Metals: + material += Localization.Get("METALS"); break; + default: break; + } + break; + default: + material = ""; break; + } + } + } + else + { + if (data.Info.m_buildingAI is IndustrialExtractorAI) + { + switch (data.Info.m_class.m_subService) + { + case ItemClass.SubService.IndustrialForestry: + material = Localization.Get("LOG"); break; + case ItemClass.SubService.IndustrialFarming: + material = Localization.Get("GRAIN_MEAT"); break; + case ItemClass.SubService.IndustrialOil: + material = Localization.Get("OIL"); break; + case ItemClass.SubService.IndustrialOre: + material = Localization.Get("ORE"); break; + default: + material = ""; break; + } + } + else + { + switch (data.Info.m_class.m_subService) + { + case ItemClass.SubService.IndustrialForestry: + material = Localization.Get("LUMBER"); break; + case ItemClass.SubService.IndustrialFarming: + material = Localization.Get("FOOD"); break; + case ItemClass.SubService.IndustrialOil: + material = Localization.Get("PETROL"); break; + case ItemClass.SubService.IndustrialOre: + material = Localization.Get("COAL"); break; + case ItemClass.SubService.IndustrialGeneric: + material = Localization.Get("PREGOODS"); break; + case ItemClass.SubService.CommercialHigh: + case ItemClass.SubService.CommercialLow: + case ItemClass.SubService.CommercialEco: + case ItemClass.SubService.CommercialLeisure: + case ItemClass.SubService.CommercialTourist: + material = Localization.Get("GOODS"); break; + default: + material = ""; break; + } + } + } + return material; + } - public static float GetPrice(bool isSelling, ushort buildingID, Building data) - { - RealCityIndustrialBuildingAI.InitDelegate(); - float price = 0f; - if (!isSelling) - { - if (!(data.Info.m_buildingAI is IndustrialExtractorAI)) - { - switch (data.Info.m_class.m_subService) - { - case ItemClass.SubService.CommercialHigh: - case ItemClass.SubService.CommercialLow: - case ItemClass.SubService.CommercialEco: - case ItemClass.SubService.CommercialLeisure: - case ItemClass.SubService.CommercialTourist: - CommercialBuildingAI commercialBuildingAI = data.Info.m_buildingAI as CommercialBuildingAI; - if (commercialBuildingAI.m_incomingResource == TransferManager.TransferReason.Food || commercialBuildingAI.m_incomingResource == TransferManager.TransferReason.Goods) - { - //SecondaryIncoming : FirstIncoming = 1:3 - price = (3f * RealCityIndustryBuildingAI.GetResourcePrice(commercialBuildingAI.m_incomingResource) + (RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.LuxuryProducts))) / 4f; - } - else - { - price = RealCityIndustryBuildingAI.GetResourcePrice(commercialBuildingAI.m_incomingResource); - } - break; - case ItemClass.SubService.IndustrialForestry: - case ItemClass.SubService.IndustrialFarming: - case ItemClass.SubService.IndustrialOil: - case ItemClass.SubService.IndustrialOre: - TransferManager.TransferReason tempReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); - price = RealCityIndustryBuildingAI.GetResourcePrice(tempReason); - break; - case ItemClass.SubService.IndustrialGeneric: - TransferManager.TransferReason firstReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); - TransferManager.TransferReason secondReason = RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); - //SecondaryIncoming : FirstIncoming = 1:3 - price = (3f * RealCityIndustryBuildingAI.GetResourcePrice(firstReason) + (RealCityIndustryBuildingAI.GetResourcePrice(secondReason))) / 4f; - break; - default: - price = 0; break; - } - } - } - else - { - if (data.Info.m_buildingAI is IndustrialExtractorAI) - { - switch (data.Info.m_class.m_subService) - { - case ItemClass.SubService.IndustrialForestry: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Logs); break; - case ItemClass.SubService.IndustrialFarming: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Grain); break; - case ItemClass.SubService.IndustrialOil: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Oil); break; - case ItemClass.SubService.IndustrialOre: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Ore); break; - default: - price = 0; break; - } - } - else - { - switch (data.Info.m_class.m_subService) - { - case ItemClass.SubService.IndustrialForestry: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Lumber); break; - case ItemClass.SubService.IndustrialFarming: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Food); break; - case ItemClass.SubService.IndustrialOil: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Petrol); break; - case ItemClass.SubService.IndustrialOre: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Coal); break; - case ItemClass.SubService.IndustrialGeneric: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Goods); break; - case ItemClass.SubService.CommercialHigh: - case ItemClass.SubService.CommercialLow: - case ItemClass.SubService.CommercialEco: - case ItemClass.SubService.CommercialLeisure: - case ItemClass.SubService.CommercialTourist: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping); break; - default: - price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.None); break; - } - } - } - return price; - } + public static float GetPrice(bool isSelling, ushort buildingID, Building data) + { + RealCityIndustrialBuildingAI.InitDelegate(); + float price = 0f; + if (!isSelling) + { + if (!(data.Info.m_buildingAI is IndustrialExtractorAI)) + { + switch (data.Info.m_class.m_subService) + { + case ItemClass.SubService.CommercialHigh: + case ItemClass.SubService.CommercialLow: + case ItemClass.SubService.CommercialEco: + case ItemClass.SubService.CommercialLeisure: + case ItemClass.SubService.CommercialTourist: + CommercialBuildingAI commercialBuildingAI = data.Info.m_buildingAI as CommercialBuildingAI; + if (commercialBuildingAI.m_incomingResource == TransferManager.TransferReason.Food || commercialBuildingAI.m_incomingResource == TransferManager.TransferReason.Goods) + { + //SecondaryIncoming : FirstIncoming = 1:3 + price = (3f * RealCityIndustryBuildingAI.GetResourcePrice(commercialBuildingAI.m_incomingResource) + (RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.LuxuryProducts))) / 4f; + } + else + { + price = RealCityIndustryBuildingAI.GetResourcePrice(commercialBuildingAI.m_incomingResource); + } + break; + case ItemClass.SubService.IndustrialForestry: + case ItemClass.SubService.IndustrialFarming: + case ItemClass.SubService.IndustrialOil: + case ItemClass.SubService.IndustrialOre: + TransferManager.TransferReason tempReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); + price = RealCityIndustryBuildingAI.GetResourcePrice(tempReason); + break; + case ItemClass.SubService.IndustrialGeneric: + TransferManager.TransferReason firstReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); + TransferManager.TransferReason secondReason = RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); + //SecondaryIncoming : FirstIncoming = 1:3 + price = (3f * RealCityIndustryBuildingAI.GetResourcePrice(firstReason) + (RealCityIndustryBuildingAI.GetResourcePrice(secondReason))) / 4f; + break; + default: + price = 0; break; + } + } + } + else + { + if (data.Info.m_buildingAI is IndustrialExtractorAI) + { + switch (data.Info.m_class.m_subService) + { + case ItemClass.SubService.IndustrialForestry: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Logs); break; + case ItemClass.SubService.IndustrialFarming: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Grain); break; + case ItemClass.SubService.IndustrialOil: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Oil); break; + case ItemClass.SubService.IndustrialOre: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Ore); break; + default: + price = 0; break; + } + } + else + { + switch (data.Info.m_class.m_subService) + { + case ItemClass.SubService.IndustrialForestry: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Lumber); break; + case ItemClass.SubService.IndustrialFarming: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Food); break; + case ItemClass.SubService.IndustrialOil: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Petrol); break; + case ItemClass.SubService.IndustrialOre: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Coal); break; + case ItemClass.SubService.IndustrialGeneric: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Goods); break; + case ItemClass.SubService.CommercialHigh: + case ItemClass.SubService.CommercialLow: + case ItemClass.SubService.CommercialEco: + case ItemClass.SubService.CommercialLeisure: + case ItemClass.SubService.CommercialTourist: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping); break; + default: + price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.None); break; + } + } + } + return price; + } - public static int GetTaxRate(Building data) - { - if (data.Info.m_class.m_service == ItemClass.Service.Commercial) - { - return Politics.commercialTax; - } - else if (data.Info.m_class.m_service == ItemClass.Service.Industrial) - { - return Politics.industryTax; - } + public static int GetTaxRate(Building data) + { + if (data.Info.m_class.m_service == ItemClass.Service.Commercial) + { + return Politics.commercialTax; + } + else if (data.Info.m_class.m_service == ItemClass.Service.Industrial) + { + return Politics.industryTax; + } - return 0; - } + return 0; + } - public static float GetComsumptionDivider(Building data, ushort buildingID) - { - Citizen.BehaviourData behaviourData = default; - int aliveWorkerCount = 0; - int totalWorkerCount = 0; - RealCityCommonBuildingAI.GetWorkBehaviour((CommonBuildingAI)data.Info.m_buildingAI, buildingID, ref data, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); - float comsumptionDivider = aliveWorkerCount / 8f; + public static float GetComsumptionDivider(Building data, ushort buildingID) + { + Citizen.BehaviourData behaviourData = default; + int aliveWorkerCount = 0; + int totalWorkerCount = 0; + RealCityCommonBuildingAI.GetWorkBehaviour((CommonBuildingAI)data.Info.m_buildingAI, buildingID, ref data, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); + float comsumptionDivider = aliveWorkerCount / 8f; - if (comsumptionDivider < 1f) - { - comsumptionDivider = 1f; - } + if (comsumptionDivider < 1f) + { + comsumptionDivider = 1f; + } - if (data.Info.m_class.m_service == ItemClass.Service.Industrial) - { - RealCityIndustrialBuildingAI.InitDelegate(); - var incomingTransferReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)data.Info.m_buildingAI, buildingID); - //petrol related - if (incomingTransferReason == TransferManager.TransferReason.Petrol) - { - //*2 / 4 - comsumptionDivider /= 2f; - } - else if (incomingTransferReason == TransferManager.TransferReason.Coal) - { - //*1.67 / 4 - comsumptionDivider /= 2.4f; - } - else if (incomingTransferReason == TransferManager.TransferReason.Lumber) - { - //*1.33 / 4 - comsumptionDivider /= 3f; - } - else if (incomingTransferReason == TransferManager.TransferReason.Food) - { - comsumptionDivider /= 4f; - } - } + if (data.Info.m_class.m_service == ItemClass.Service.Industrial) + { + RealCityIndustrialBuildingAI.InitDelegate(); + var incomingTransferReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)data.Info.m_buildingAI, buildingID); + //petrol related + if (incomingTransferReason == TransferManager.TransferReason.Petrol) + { + //*2 / 4 + comsumptionDivider /= 2f; + } + else if (incomingTransferReason == TransferManager.TransferReason.Coal) + { + //*1.67 / 4 + comsumptionDivider /= 2.4f; + } + else if (incomingTransferReason == TransferManager.TransferReason.Lumber) + { + //*1.33 / 4 + comsumptionDivider /= 3f; + } + else if (incomingTransferReason == TransferManager.TransferReason.Food) + { + comsumptionDivider /= 4f; + } + } - return comsumptionDivider; - } + return comsumptionDivider; + } - public static void ProcessAdditionProduct(ushort buildingID, ref Building buildingData, ref ushort[] __state, bool is16Times = true) - { - //add production pre 16times - byte shift = 0; - if (is16Times) - { - shift = 4; - } + public static void ProcessAdditionProduct(ushort buildingID, ref Building buildingData, ref ushort[] __state, bool is16Times = true) + { + //add production pre 16times + byte shift = 0; + if (is16Times) + { + shift = 4; + } - if ((RealCityEconomyExtension.Can16timesUpdate(buildingID)) || (!is16Times)) - { - float comsumptionDivider = GetComsumptionDivider(buildingData, buildingID); - int deltaCustomBuffer1 = __state[0] - buildingData.m_customBuffer1; - if (deltaCustomBuffer1 > 0) - { - if (RealCity.reduceVehicle) - { - if (!Singleton.instance.m_isNightTime) - { - buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1 - ((int)(deltaCustomBuffer1 / (comsumptionDivider * MainDataStore.reduceCargoDiv)) << shift)); - } - else - { - buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1 - ((int)(deltaCustomBuffer1 / comsumptionDivider) << shift)); - } - } - else - { - if (!Singleton.instance.m_isNightTime) - { - buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1 - ((int)(deltaCustomBuffer1 / comsumptionDivider) << shift)); - } - else - { - buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1 - ((int)((deltaCustomBuffer1 << 1) / comsumptionDivider) << shift)); - } - } - } + if ((RealCityEconomyExtension.Can16timesUpdate(buildingID)) || (!is16Times)) + { + float comsumptionDivider = GetComsumptionDivider(buildingData, buildingID); + int deltaCustomBuffer1 = __state[0] - buildingData.m_customBuffer1; + if (deltaCustomBuffer1 > 0) + { + if (RealCity.reduceVehicle) + { + if (!Singleton.instance.m_isNightTime) + { + buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1 - ((int)(deltaCustomBuffer1 / (comsumptionDivider * MainDataStore.reduceCargoDiv)) << shift)); + } + else + { + buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1 - ((int)(deltaCustomBuffer1 / comsumptionDivider) << shift)); + } + } + else + { + if (!Singleton.instance.m_isNightTime) + { + buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1 - ((int)(deltaCustomBuffer1 / comsumptionDivider) << shift)); + } + else + { + buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1 - ((int)((deltaCustomBuffer1 << 1) / comsumptionDivider) << shift)); + } + } + } - int deltaCustomBuffer2 = buildingData.m_customBuffer2 - __state[1]; - if (deltaCustomBuffer2 > 0) - { - if (RealCity.reduceVehicle) - { - if (!Singleton.instance.m_isNightTime) - { - buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 - deltaCustomBuffer2 + ((deltaCustomBuffer2 >> MainDataStore.reduceCargoDivShift) << shift)); - } - else - { - //NightTime 2x , reduceVehicle 1/2, so do nothing - buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 - deltaCustomBuffer2 + (((int)(deltaCustomBuffer2 / (float)MainDataStore.reduceCargoDiv) << 1) << shift)); - } - } - else - { - if (!Singleton.instance.m_isNightTime) - { - buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 - deltaCustomBuffer2 + (deltaCustomBuffer2 << shift)); - } - else - { - buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 - deltaCustomBuffer2 + ((deltaCustomBuffer2 << MainDataStore.reduceCargoDivShift) << shift)); - //buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 + (deltaCustomBuffer2 << 4)); - } - } - } - } - else - { - //DebugLog.LogToFileOnly($"Process buildingID outside 16times = {buildingID}"); - buildingData.m_customBuffer1 = (ushort)Mathf.Clamp(__state[0], 0, 64000); - buildingData.m_customBuffer2 = (ushort)Mathf.Clamp(__state[1], 0, 64000); - } - } + int deltaCustomBuffer2 = buildingData.m_customBuffer2 - __state[1]; + if (deltaCustomBuffer2 > 0) + { + if (RealCity.reduceVehicle) + { + if (!Singleton.instance.m_isNightTime) + { + buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 - deltaCustomBuffer2 + ((deltaCustomBuffer2 >> MainDataStore.reduceCargoDivShift) << shift)); + } + else + { + //NightTime 2x , reduceVehicle 1/2, so do nothing + buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 - deltaCustomBuffer2 + (((int)(deltaCustomBuffer2 / (float)MainDataStore.reduceCargoDiv) << 1) << shift)); + } + } + else + { + if (!Singleton.instance.m_isNightTime) + { + buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 - deltaCustomBuffer2 + (deltaCustomBuffer2 << shift)); + } + else + { + buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 - deltaCustomBuffer2 + ((deltaCustomBuffer2 << MainDataStore.reduceCargoDivShift) << shift)); + //buildingData.m_customBuffer2 = (ushort)(buildingData.m_customBuffer2 + (deltaCustomBuffer2 << 4)); + } + } + } + } + else + { + //DebugLog.LogToFileOnly($"Process buildingID outside 16times = {buildingID}"); + buildingData.m_customBuffer1 = (ushort)Mathf.Clamp(__state[0], 0, 64000); + buildingData.m_customBuffer2 = (ushort)Mathf.Clamp(__state[1], 0, 64000); + } + } - public static void ProcessAdditionProduct(ref Building buildingData, ref ushort[] __state) - { - int deltaCustomBuffer1 = buildingData.m_customBuffer1 - __state[0]; - if (deltaCustomBuffer1 > 0) - { - if (RealCity.reduceVehicle) - { - if (!Singleton.instance.m_isNightTime) - { - buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 - deltaCustomBuffer1 + (deltaCustomBuffer1 >> MainDataStore.reduceCargoDivShift)); - } - //else - //{ - //NightTime 2x , reduceVehicle 1/2, so do nothing - //buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 - deltaCustomBuffer1 + (deltaCustomBuffer1 / (float)MainDataStore.reduceCargoDiv) * 2f); - //} - } - else - { - if (!Singleton.instance.m_isNightTime) - { - //buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 - deltaCustomBuffer1 + deltaCustomBuffer1); - } - else - { - //buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 - deltaCustomBuffer1 + 2 * deltaCustomBuffer1); - buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1); - } - } - } - } - } + public static void ProcessAdditionProduct(ref Building buildingData, ref ushort[] __state) + { + int deltaCustomBuffer1 = buildingData.m_customBuffer1 - __state[0]; + if (deltaCustomBuffer1 > 0) + { + if (RealCity.reduceVehicle) + { + if (!Singleton.instance.m_isNightTime) + { + buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 - deltaCustomBuffer1 + (deltaCustomBuffer1 >> MainDataStore.reduceCargoDivShift)); + } + //else + //{ + //NightTime 2x , reduceVehicle 1/2, so do nothing + //buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 - deltaCustomBuffer1 + (deltaCustomBuffer1 / (float)MainDataStore.reduceCargoDiv) * 2f); + //} + } + else + { + if (!Singleton.instance.m_isNightTime) + { + //buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 - deltaCustomBuffer1 + deltaCustomBuffer1); + } + else + { + //buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 - deltaCustomBuffer1 + 2 * deltaCustomBuffer1); + buildingData.m_customBuffer1 = (ushort)(buildingData.m_customBuffer1 + deltaCustomBuffer1); + } + } + } + } + } } diff --git a/CustomAI/RealCityResidentAI.cs b/CustomAI/RealCityResidentAI.cs index 4bfc468..7352184 100644 --- a/CustomAI/RealCityResidentAI.cs +++ b/CustomAI/RealCityResidentAI.cs @@ -6,416 +6,416 @@ namespace RealCity.CustomAI { - public static class RealCityResidentAI - { - public static uint preCitizenId = 0; - public static int familyCount = 0; - public static int citizenCount = 0; - public static uint level3HighWealth = 0; - public static uint level2HighWealth = 0; - public static uint level1HighWealth = 0; - public static int citizenSalaryCount = 0; - public static int citizenExpenseCount = 0; - public static int citizenSalaryTaxTotal = 0; - public static float tempCitizenSalaryTaxTotal = 0f; - public static uint familyWeightStableHigh = 0; - public static uint familyWeightStableLow = 0; + public static class RealCityResidentAI + { + public static uint preCitizenId = 0; + public static int familyCount = 0; + public static int citizenCount = 0; + public static uint level3HighWealth = 0; + public static uint level2HighWealth = 0; + public static uint level1HighWealth = 0; + public static int citizenSalaryCount = 0; + public static int citizenExpenseCount = 0; + public static int citizenSalaryTaxTotal = 0; + public static float tempCitizenSalaryTaxTotal = 0f; + public static uint familyWeightStableHigh = 0; + public static uint familyWeightStableLow = 0; - public static void Load(ref byte[] saveData) - { - int i = 0; - SaveAndRestore.LoadData(ref i, saveData, ref preCitizenId); - SaveAndRestore.LoadData(ref i, saveData, ref familyCount); - SaveAndRestore.LoadData(ref i, saveData, ref level3HighWealth); - SaveAndRestore.LoadData(ref i, saveData, ref level2HighWealth); - SaveAndRestore.LoadData(ref i, saveData, ref level1HighWealth); - SaveAndRestore.LoadData(ref i, saveData, ref citizenSalaryCount); - SaveAndRestore.LoadData(ref i, saveData, ref citizenExpenseCount); - SaveAndRestore.LoadData(ref i, saveData, ref citizenSalaryTaxTotal); - SaveAndRestore.LoadData(ref i, saveData, ref tempCitizenSalaryTaxTotal); - SaveAndRestore.LoadData(ref i, saveData, ref familyWeightStableHigh); - SaveAndRestore.LoadData(ref i, saveData, ref familyWeightStableLow); - SaveAndRestore.LoadData(ref i, saveData, ref citizenCount); + public static void Load(ref byte[] saveData) + { + int i = 0; + SaveAndRestore.LoadData(ref i, saveData, ref preCitizenId); + SaveAndRestore.LoadData(ref i, saveData, ref familyCount); + SaveAndRestore.LoadData(ref i, saveData, ref level3HighWealth); + SaveAndRestore.LoadData(ref i, saveData, ref level2HighWealth); + SaveAndRestore.LoadData(ref i, saveData, ref level1HighWealth); + SaveAndRestore.LoadData(ref i, saveData, ref citizenSalaryCount); + SaveAndRestore.LoadData(ref i, saveData, ref citizenExpenseCount); + SaveAndRestore.LoadData(ref i, saveData, ref citizenSalaryTaxTotal); + SaveAndRestore.LoadData(ref i, saveData, ref tempCitizenSalaryTaxTotal); + SaveAndRestore.LoadData(ref i, saveData, ref familyWeightStableHigh); + SaveAndRestore.LoadData(ref i, saveData, ref familyWeightStableLow); + SaveAndRestore.LoadData(ref i, saveData, ref citizenCount); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"RealCityResidentAI Load Error: saveData.Length = {saveData.Length} + i = {i}"); - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"RealCityResidentAI Load Error: saveData.Length = {saveData.Length} + i = {i}"); + } + } - public static void Save(ref byte[] saveData) - { - int i = 0; + public static void Save(ref byte[] saveData) + { + int i = 0; - //48 - SaveAndRestore.SaveData(ref i, preCitizenId, ref saveData); - SaveAndRestore.SaveData(ref i, familyCount, ref saveData); - SaveAndRestore.SaveData(ref i, level3HighWealth, ref saveData); - SaveAndRestore.SaveData(ref i, level2HighWealth, ref saveData); - SaveAndRestore.SaveData(ref i, level1HighWealth, ref saveData); - SaveAndRestore.SaveData(ref i, citizenSalaryCount, ref saveData); - SaveAndRestore.SaveData(ref i, citizenExpenseCount, ref saveData); - SaveAndRestore.SaveData(ref i, citizenSalaryTaxTotal, ref saveData); - SaveAndRestore.SaveData(ref i, tempCitizenSalaryTaxTotal, ref saveData); - SaveAndRestore.SaveData(ref i, familyWeightStableHigh, ref saveData); - SaveAndRestore.SaveData(ref i, familyWeightStableLow, ref saveData); - SaveAndRestore.SaveData(ref i, citizenCount, ref saveData); + //48 + SaveAndRestore.SaveData(ref i, preCitizenId, ref saveData); + SaveAndRestore.SaveData(ref i, familyCount, ref saveData); + SaveAndRestore.SaveData(ref i, level3HighWealth, ref saveData); + SaveAndRestore.SaveData(ref i, level2HighWealth, ref saveData); + SaveAndRestore.SaveData(ref i, level1HighWealth, ref saveData); + SaveAndRestore.SaveData(ref i, citizenSalaryCount, ref saveData); + SaveAndRestore.SaveData(ref i, citizenExpenseCount, ref saveData); + SaveAndRestore.SaveData(ref i, citizenSalaryTaxTotal, ref saveData); + SaveAndRestore.SaveData(ref i, tempCitizenSalaryTaxTotal, ref saveData); + SaveAndRestore.SaveData(ref i, familyWeightStableHigh, ref saveData); + SaveAndRestore.SaveData(ref i, familyWeightStableLow, ref saveData); + SaveAndRestore.SaveData(ref i, citizenCount, ref saveData); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"RealCityResidentAI Save Error: saveData.Length = {saveData.Length} + i = {i}"); - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"RealCityResidentAI Save Error: saveData.Length = {saveData.Length} + i = {i}"); + } + } - public static bool IsGoverment(ushort buildingID) - { - bool isGoverment = false; - Building buildingData = Singleton.instance.m_buildings.m_buffer[buildingID]; - switch (buildingData.Info.m_class.m_service) - { - case ItemClass.Service.Disaster: - case ItemClass.Service.PoliceDepartment: - case ItemClass.Service.Education: - case ItemClass.Service.Road: - case ItemClass.Service.Garbage: - case ItemClass.Service.HealthCare: - case ItemClass.Service.Beautification: - case ItemClass.Service.Monument: - case ItemClass.Service.Water: - case ItemClass.Service.Electricity: - case ItemClass.Service.FireDepartment: - case ItemClass.Service.PlayerIndustry: - case ItemClass.Service.PublicTransport: - case ItemClass.Service.PlayerEducation: - case ItemClass.Service.Museums: - case ItemClass.Service.VarsitySports: - case ItemClass.Service.Fishing: - isGoverment = true; break; - } - return isGoverment; - } + public static bool IsGoverment(ushort buildingID) + { + bool isGoverment = false; + Building buildingData = Singleton.instance.m_buildings.m_buffer[buildingID]; + switch (buildingData.Info.m_class.m_service) + { + case ItemClass.Service.Disaster: + case ItemClass.Service.PoliceDepartment: + case ItemClass.Service.Education: + case ItemClass.Service.Road: + case ItemClass.Service.Garbage: + case ItemClass.Service.HealthCare: + case ItemClass.Service.Beautification: + case ItemClass.Service.Monument: + case ItemClass.Service.Water: + case ItemClass.Service.Electricity: + case ItemClass.Service.FireDepartment: + case ItemClass.Service.PlayerIndustry: + case ItemClass.Service.PublicTransport: + case ItemClass.Service.PlayerEducation: + case ItemClass.Service.Museums: + case ItemClass.Service.VarsitySports: + case ItemClass.Service.Fishing: + isGoverment = true; break; + } + return isGoverment; + } - public static int ProcessCitizenSalary(uint citizenId, bool checkOnly) - { - int salary = 0; - if (citizenId != 0u) - { - Citizen.Flags citizenFlag = Singleton.instance.m_citizens.m_buffer[citizenId].m_flags; - if ((citizenFlag & Citizen.Flags.Student) != Citizen.Flags.None) - { - return salary; - } - ushort workBuilding = Singleton.instance.m_citizens.m_buffer[citizenId].m_workBuilding; - if (workBuilding != 0u) - { - Building buildingData = Singleton.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.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.instance.m_citizens.m_buffer[citizenId].SetWorkplace(citizenId, 0, 0u); - } - float vitualWorkersRatio = (totalWorkCount != 0) ? (allWorkCount / (float)totalWorkCount) : 1f; + public static int ProcessCitizenSalary(uint citizenId, bool checkOnly) + { + int salary = 0; + if (citizenId != 0u) + { + Citizen.Flags citizenFlag = Singleton.instance.m_citizens.m_buffer[citizenId].m_flags; + if ((citizenFlag & Citizen.Flags.Student) != Citizen.Flags.None) + { + return salary; + } + ushort workBuilding = Singleton.instance.m_citizens.m_buffer[citizenId].m_workBuilding; + if (workBuilding != 0u) + { + Building buildingData = Singleton.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.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.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.instance.GetBudget(buildingData.Info.m_class); - salary = (int)(salary * budget / 100f); - salary = Math.Max(salary, salaryMax); + //Budget offset for Salary + int budget = Singleton.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()); + DebugLog.LogToFileOnly("DebugInfo: LandPrice offset for Salary is " + landPriceOffset.ToString()); #endif - salary = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, salary); - if (!checkOnly) - { - var m_class = Singleton.instance.m_buildings.m_buffer[workBuilding].Info.m_class; - Singleton.instance.FetchResource((EconomyManager.Resource)16, (int)(salary * vitualWorkersRatio), m_class); - MainDataStore.outsideTouristMoney += (salary * (vitualWorkersRatio - 1f) * MainDataStore.outsideTouristSalaryProfitRatio); - } - } - } - } + salary = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, salary); + if (!checkOnly) + { + var m_class = Singleton.instance.m_buildings.m_buffer[workBuilding].Info.m_class; + Singleton.instance.FetchResource((EconomyManager.Resource)16, (int)(salary * vitualWorkersRatio), m_class); + MainDataStore.outsideTouristMoney += (salary * (vitualWorkersRatio - 1f) * MainDataStore.outsideTouristSalaryProfitRatio); + } + } + } + } - return salary; - }//public + return salary; + }//public - public static int TotalWorkCount(ushort buildingID, Building data, bool checkOnly, bool update) - { - int totalWorkCount = 0; - //For performance + public static int TotalWorkCount(ushort buildingID, Building data, bool checkOnly, bool update) + { + int totalWorkCount = 0; + //For performance #if FASTRUN - update = false; + update = false; #endif - if (BuildingData.isBuildingWorkerUpdated[buildingID] && !update) - { - totalWorkCount = BuildingData.buildingWorkCount[buildingID]; - } - else - { - if (data.Info.m_buildingAI is LandfillSiteAI) - { - LandfillSiteAI buildingAI = data.Info.m_buildingAI as LandfillSiteAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is ExtractingFacilityAI) - { - ExtractingFacilityAI buildingAI = data.Info.m_buildingAI as ExtractingFacilityAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is ProcessingFacilityAI) - { - ProcessingFacilityAI buildingAI = data.Info.m_buildingAI as ProcessingFacilityAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is PoliceStationAI) - { - PoliceStationAI buildingAI = data.Info.m_buildingAI as PoliceStationAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is FireStationAI) - { - FireStationAI buildingAI = data.Info.m_buildingAI as FireStationAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is HospitalAI) - { - HospitalAI buildingAI = data.Info.m_buildingAI as HospitalAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is CargoStationAI) - { - CargoStationAI buildingAI = data.Info.m_buildingAI as CargoStationAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is TransportStationAI) - { - TransportStationAI buildingAI = data.Info.m_buildingAI as TransportStationAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is CemeteryAI) - { - CemeteryAI buildingAI = data.Info.m_buildingAI as CemeteryAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is MedicalCenterAI) - { - MedicalCenterAI buildingAI = data.Info.m_buildingAI as MedicalCenterAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is MonumentAI) - { - MonumentAI buildingAI = data.Info.m_buildingAI as MonumentAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is DepotAI) - { - DepotAI buildingAI = data.Info.m_buildingAI as DepotAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is HelicopterDepotAI) - { - HelicopterDepotAI buildingAI = data.Info.m_buildingAI as HelicopterDepotAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is MaintenanceDepotAI) - { - MaintenanceDepotAI buildingAI = data.Info.m_buildingAI as MaintenanceDepotAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is FirewatchTowerAI) - { - FirewatchTowerAI buildingAI = data.Info.m_buildingAI as FirewatchTowerAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is DoomsdayVaultAI) - { - DoomsdayVaultAI buildingAI = data.Info.m_buildingAI as DoomsdayVaultAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is DisasterResponseBuildingAI) - { - DisasterResponseBuildingAI buildingAI = data.Info.m_buildingAI as DisasterResponseBuildingAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is HadronColliderAI) - { - HadronColliderAI buildingAI = data.Info.m_buildingAI as HadronColliderAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is SchoolAI) - { - SchoolAI buildingAI = data.Info.m_buildingAI as SchoolAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is PowerPlantAI) - { - PowerPlantAI buildingAI = data.Info.m_buildingAI as PowerPlantAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is SnowDumpAI) - { - SnowDumpAI buildingAI = data.Info.m_buildingAI as SnowDumpAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is WarehouseAI) - { - WarehouseAI buildingAI = data.Info.m_buildingAI as WarehouseAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is WaterFacilityAI) - { - WaterFacilityAI buildingAI = data.Info.m_buildingAI as WaterFacilityAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is SaunaAI) - { - SaunaAI buildingAI = data.Info.m_buildingAI as SaunaAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is PostOfficeAI) - { - PostOfficeAI buildingAI = data.Info.m_buildingAI as PostOfficeAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is RadioMastAI) - { - RadioMastAI buildingAI = data.Info.m_buildingAI as RadioMastAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is SpaceElevatorAI) - { - SpaceElevatorAI buildingAI = data.Info.m_buildingAI as SpaceElevatorAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is SpaceRadarAI) - { - SpaceRadarAI buildingAI = data.Info.m_buildingAI as SpaceRadarAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is MainIndustryBuildingAI) - { - MainIndustryBuildingAI buildingAI = data.Info.m_buildingAI as MainIndustryBuildingAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is AuxiliaryBuildingAI) - { - AuxiliaryBuildingAI buildingAI = data.Info.m_buildingAI as AuxiliaryBuildingAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is ShelterAI) - { - ShelterAI buildingAI = data.Info.m_buildingAI as ShelterAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is HeatingPlantAI) - { - HeatingPlantAI buildingAI = data.Info.m_buildingAI as HeatingPlantAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is MainCampusBuildingAI) - { - MainCampusBuildingAI buildingAI = data.Info.m_buildingAI as MainCampusBuildingAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is MuseumAI) - { - MuseumAI buildingAI = data.Info.m_buildingAI as MuseumAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is UniqueFactoryAI) - { - UniqueFactoryAI buildingAI = data.Info.m_buildingAI as UniqueFactoryAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is UniqueFacultyAI) - { - UniqueFacultyAI buildingAI = data.Info.m_buildingAI as UniqueFacultyAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is VarsitySportsArenaAI) - { - VarsitySportsArenaAI buildingAI = data.Info.m_buildingAI as VarsitySportsArenaAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is LibraryAI) - { - LibraryAI buildingAI = data.Info.m_buildingAI as LibraryAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is FishFarmAI) - { - FishFarmAI buildingAI = data.Info.m_buildingAI as FishFarmAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is FishingHarborAI) - { - FishingHarborAI buildingAI = data.Info.m_buildingAI as FishingHarborAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is EldercareAI) - { - EldercareAI buildingAI = data.Info.m_buildingAI as EldercareAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is ChildcareAI) - { - ChildcareAI buildingAI = data.Info.m_buildingAI as ChildcareAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else if (data.Info.m_buildingAI is MarketAI) - { - MarketAI buildingAI = data.Info.m_buildingAI as MarketAI; - totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; - } - else - { - if (!checkOnly) - { - DebugLog.LogToFileOnly("Error: find unknow building = " + data.Info.m_buildingAI.ToString()); - } - } + if (BuildingData.isBuildingWorkerUpdated[buildingID] && !update) + { + totalWorkCount = BuildingData.buildingWorkCount[buildingID]; + } + else + { + if (data.Info.m_buildingAI is LandfillSiteAI) + { + LandfillSiteAI buildingAI = data.Info.m_buildingAI as LandfillSiteAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is ExtractingFacilityAI) + { + ExtractingFacilityAI buildingAI = data.Info.m_buildingAI as ExtractingFacilityAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is ProcessingFacilityAI) + { + ProcessingFacilityAI buildingAI = data.Info.m_buildingAI as ProcessingFacilityAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is PoliceStationAI) + { + PoliceStationAI buildingAI = data.Info.m_buildingAI as PoliceStationAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is FireStationAI) + { + FireStationAI buildingAI = data.Info.m_buildingAI as FireStationAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is HospitalAI) + { + HospitalAI buildingAI = data.Info.m_buildingAI as HospitalAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is CargoStationAI) + { + CargoStationAI buildingAI = data.Info.m_buildingAI as CargoStationAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is TransportStationAI) + { + TransportStationAI buildingAI = data.Info.m_buildingAI as TransportStationAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is CemeteryAI) + { + CemeteryAI buildingAI = data.Info.m_buildingAI as CemeteryAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is MedicalCenterAI) + { + MedicalCenterAI buildingAI = data.Info.m_buildingAI as MedicalCenterAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is MonumentAI) + { + MonumentAI buildingAI = data.Info.m_buildingAI as MonumentAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is DepotAI) + { + DepotAI buildingAI = data.Info.m_buildingAI as DepotAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is HelicopterDepotAI) + { + HelicopterDepotAI buildingAI = data.Info.m_buildingAI as HelicopterDepotAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is MaintenanceDepotAI) + { + MaintenanceDepotAI buildingAI = data.Info.m_buildingAI as MaintenanceDepotAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is FirewatchTowerAI) + { + FirewatchTowerAI buildingAI = data.Info.m_buildingAI as FirewatchTowerAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is DoomsdayVaultAI) + { + DoomsdayVaultAI buildingAI = data.Info.m_buildingAI as DoomsdayVaultAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is DisasterResponseBuildingAI) + { + DisasterResponseBuildingAI buildingAI = data.Info.m_buildingAI as DisasterResponseBuildingAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is HadronColliderAI) + { + HadronColliderAI buildingAI = data.Info.m_buildingAI as HadronColliderAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is SchoolAI) + { + SchoolAI buildingAI = data.Info.m_buildingAI as SchoolAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is PowerPlantAI) + { + PowerPlantAI buildingAI = data.Info.m_buildingAI as PowerPlantAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is SnowDumpAI) + { + SnowDumpAI buildingAI = data.Info.m_buildingAI as SnowDumpAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is WarehouseAI) + { + WarehouseAI buildingAI = data.Info.m_buildingAI as WarehouseAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is WaterFacilityAI) + { + WaterFacilityAI buildingAI = data.Info.m_buildingAI as WaterFacilityAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is SaunaAI) + { + SaunaAI buildingAI = data.Info.m_buildingAI as SaunaAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is PostOfficeAI) + { + PostOfficeAI buildingAI = data.Info.m_buildingAI as PostOfficeAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is RadioMastAI) + { + RadioMastAI buildingAI = data.Info.m_buildingAI as RadioMastAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is SpaceElevatorAI) + { + SpaceElevatorAI buildingAI = data.Info.m_buildingAI as SpaceElevatorAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is SpaceRadarAI) + { + SpaceRadarAI buildingAI = data.Info.m_buildingAI as SpaceRadarAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is MainIndustryBuildingAI) + { + MainIndustryBuildingAI buildingAI = data.Info.m_buildingAI as MainIndustryBuildingAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is AuxiliaryBuildingAI) + { + AuxiliaryBuildingAI buildingAI = data.Info.m_buildingAI as AuxiliaryBuildingAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is ShelterAI) + { + ShelterAI buildingAI = data.Info.m_buildingAI as ShelterAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is HeatingPlantAI) + { + HeatingPlantAI buildingAI = data.Info.m_buildingAI as HeatingPlantAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is MainCampusBuildingAI) + { + MainCampusBuildingAI buildingAI = data.Info.m_buildingAI as MainCampusBuildingAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is MuseumAI) + { + MuseumAI buildingAI = data.Info.m_buildingAI as MuseumAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is UniqueFactoryAI) + { + UniqueFactoryAI buildingAI = data.Info.m_buildingAI as UniqueFactoryAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is UniqueFacultyAI) + { + UniqueFacultyAI buildingAI = data.Info.m_buildingAI as UniqueFacultyAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is VarsitySportsArenaAI) + { + VarsitySportsArenaAI buildingAI = data.Info.m_buildingAI as VarsitySportsArenaAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is LibraryAI) + { + LibraryAI buildingAI = data.Info.m_buildingAI as LibraryAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is FishFarmAI) + { + FishFarmAI buildingAI = data.Info.m_buildingAI as FishFarmAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is FishingHarborAI) + { + FishingHarborAI buildingAI = data.Info.m_buildingAI as FishingHarborAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is EldercareAI) + { + EldercareAI buildingAI = data.Info.m_buildingAI as EldercareAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is ChildcareAI) + { + ChildcareAI buildingAI = data.Info.m_buildingAI as ChildcareAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else if (data.Info.m_buildingAI is MarketAI) + { + MarketAI buildingAI = data.Info.m_buildingAI as MarketAI; + totalWorkCount = buildingAI.m_workPlaceCount0 + buildingAI.m_workPlaceCount1 + buildingAI.m_workPlaceCount2 + buildingAI.m_workPlaceCount3; + } + else + { + if (!checkOnly) + { + DebugLog.LogToFileOnly("Error: find unknow building = " + data.Info.m_buildingAI.ToString()); + } + } - BuildingData.isBuildingWorkerUpdated[buildingID] = true; - BuildingData.buildingWorkCount[buildingID] = totalWorkCount; - } - return totalWorkCount; - } - } + BuildingData.isBuildingWorkerUpdated[buildingID] = true; + BuildingData.buildingWorkCount[buildingID] = totalWorkCount; + } + return totalWorkCount; + } + } } diff --git a/CustomData/BuildingData.cs b/CustomData/BuildingData.cs index 396ca59..d25e5c1 100644 --- a/CustomData/BuildingData.cs +++ b/CustomData/BuildingData.cs @@ -1,57 +1,56 @@ - -using RealCity.Util; +using RealCity.Util; namespace RealCity.CustomData { - public class BuildingData - { - public static float[] buildingMoney = new float[49152]; - public static float[] buildingMoneyThreat = new float[49152]; - public static int[] buildingWorkCount = new int[49152]; - public static bool[] isBuildingWorkerUpdated = new bool[49152]; - public static ushort lastBuildingID = 0; - public static ushort[] commBuildingID = new ushort[49152]; - public static ushort commBuildingNum = 0; - public static ushort commBuildingNumFinal = 0; + public class BuildingData + { + public static float[] buildingMoney = new float[49152]; + public static float[] buildingMoneyThreat = new float[49152]; + public static int[] buildingWorkCount = new int[49152]; + public static bool[] isBuildingWorkerUpdated = new bool[49152]; + public static ushort lastBuildingID = 0; + public static ushort[] commBuildingID = new ushort[49152]; + public static ushort commBuildingNum = 0; + public static ushort commBuildingNumFinal = 0; - public static void DataInit() - { - for (int i = 0; i < buildingWorkCount.Length; i++) - { - buildingMoney[i] = 0; - buildingWorkCount[i] = 0; - isBuildingWorkerUpdated[i] = false; - commBuildingID[i] = 0; - buildingMoneyThreat[i] = 1f; - } - } + public static void DataInit() + { + for (int i = 0; i < buildingWorkCount.Length; i++) + { + buildingMoney[i] = 0; + buildingWorkCount[i] = 0; + isBuildingWorkerUpdated[i] = false; + commBuildingID[i] = 0; + buildingMoneyThreat[i] = 1f; + } + } - public static void Save(ref byte[] saveData) - { - //442368 - int i = 0; - SaveAndRestore.SaveData(ref i, buildingMoney, ref saveData); - SaveAndRestore.SaveData(ref i, buildingWorkCount, ref saveData); - SaveAndRestore.SaveData(ref i, isBuildingWorkerUpdated, ref saveData); + public static void Save(ref byte[] saveData) + { + //442368 + int i = 0; + SaveAndRestore.SaveData(ref i, buildingMoney, ref saveData); + SaveAndRestore.SaveData(ref i, buildingWorkCount, ref saveData); + SaveAndRestore.SaveData(ref i, isBuildingWorkerUpdated, ref saveData); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"BuildingData Save Error: saveData.Length = {saveData.Length} actually = {i}"); - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"BuildingData Save Error: saveData.Length = {saveData.Length} actually = {i}"); + } + } - public static void Load(ref byte[] saveData) - { - int i = 0; - SaveAndRestore.LoadData(ref i, saveData, ref buildingMoney); - SaveAndRestore.LoadData(ref i, saveData, ref buildingWorkCount); - SaveAndRestore.LoadData(ref i, saveData, ref isBuildingWorkerUpdated); + public static void Load(ref byte[] saveData) + { + int i = 0; + SaveAndRestore.LoadData(ref i, saveData, ref buildingMoney); + SaveAndRestore.LoadData(ref i, saveData, ref buildingWorkCount); + SaveAndRestore.LoadData(ref i, saveData, ref isBuildingWorkerUpdated); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"BuildingData Load Error: saveData.Length = {saveData.Length} actually = {i}"); - } - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"BuildingData Load Error: saveData.Length = {saveData.Length} actually = {i}"); + } + } + } } diff --git a/CustomData/CitizenData.cs b/CustomData/CitizenData.cs index f5a5aad..7ad281e 100644 --- a/CustomData/CitizenData.cs +++ b/CustomData/CitizenData.cs @@ -10,10 +10,10 @@ public class CitizenData public static void DataInit() { - for (int i = 0; i < citizenMoney.Length; i++) - { - citizenMoney[i] = 0f; - } + //for (int i = 0; i < citizenMoney.Length; i++) { + // citizenMoney[i] = 0f; + //} + citizenMoney.Initialize(); } public static void Save(ref byte[] saveData) diff --git a/CustomData/CitizenUnitData.cs b/CustomData/CitizenUnitData.cs index 9958376..c0947d8 100644 --- a/CustomData/CitizenUnitData.cs +++ b/CustomData/CitizenUnitData.cs @@ -2,44 +2,46 @@ namespace RealCity.CustomData { - public class CitizenUnitData - { - public static float[] familyMoney = new float[524288]; - public static ushort[] familyGoods = new ushort[524288]; + public class CitizenUnitData + { + //人口的一半 + public static float[] familyMoney = new float[524288]; + public static ushort[] familyGoods = new ushort[524288]; - public static void DataInit() - { - for (int i = 0; i < familyMoney.Length; i++) - { - familyMoney[i] = 0f; - //default; - familyGoods[i] = 65535; - } - } + public static void DataInit() + { + //for (int i = 0; i < familyMoney.Length; i++) { + // familyMoney[i] = 0f; + // //default; + // familyGoods[i] = 65535; + //} + familyMoney.Initialize(); + familyGoods.Initialize(ushort.MaxValue); + } - public static void Save(ref byte[] saveData) - { - //3145728; - int i = 0; - SaveAndRestore.SaveData(ref i, familyMoney, ref saveData); - SaveAndRestore.SaveData(ref i, familyGoods, ref saveData); + public static void Save(ref byte[] saveData) + { + //3145728; + int i = 0; + SaveAndRestore.SaveData(ref i, familyMoney, ref saveData); + SaveAndRestore.SaveData(ref i, familyGoods, ref saveData); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"CitizenData Save Error: saveData.Length = {saveData.Length} actually = {i}"); - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"CitizenData Save Error: saveData.Length = {saveData.Length} actually = {i}"); + } + } - public static void Load(ref byte[] saveData) - { - int i = 0; - SaveAndRestore.LoadData(ref i, saveData, ref familyMoney); - SaveAndRestore.LoadData(ref i, saveData, ref familyGoods); + public static void Load(ref byte[] saveData) + { + int i = 0; + SaveAndRestore.LoadData(ref i, saveData, ref familyMoney); + SaveAndRestore.LoadData(ref i, saveData, ref familyGoods); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"CitizenData Load Error: saveData.Length = {saveData.Length} actually = {i}"); - } - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"CitizenData Load Error: saveData.Length = {saveData.Length} actually = {i}"); + } + } + } } diff --git a/CustomData/TransportLineData.cs b/CustomData/TransportLineData.cs index d6ee9d2..9e15897 100644 --- a/CustomData/TransportLineData.cs +++ b/CustomData/TransportLineData.cs @@ -2,43 +2,43 @@ namespace RealCity.CustomData { - public class TransportLineData - { - public static byte[] WeekDayPlan = new byte[256]; - public static byte[] WeekEndPlan = new byte[256]; - public static ushort lastLineID = 0; + public class TransportLineData + { + public static byte[] WeekDayPlan = new byte[256]; + public static byte[] WeekEndPlan = new byte[256]; + public static ushort lastLineID = 0; - public static void DataInit() - { - for (int i = 0; i < WeekDayPlan.Length; i++) - { - WeekDayPlan[i] = 1; - WeekEndPlan[i] = 2; - } - } + public static void DataInit() + { + for (int i = 0; i < WeekDayPlan.Length; i++) + { + WeekDayPlan[i] = 1; + WeekEndPlan[i] = 2; + } + } - public static void Save(ref byte[] saveData) - { - int i = 0; - SaveAndRestore.SaveData(ref i, WeekDayPlan, ref saveData); - SaveAndRestore.SaveData(ref i, WeekEndPlan, ref saveData); + public static void Save(ref byte[] saveData) + { + int i = 0; + SaveAndRestore.SaveData(ref i, WeekDayPlan, ref saveData); + SaveAndRestore.SaveData(ref i, WeekEndPlan, ref saveData); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"TransportLineData Save Error: saveData.Length = {saveData.Length} actually = {i}"); - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"TransportLineData Save Error: saveData.Length = {saveData.Length} actually = {i}"); + } + } - public static void Load(ref byte[] saveData) - { - int i = 0; - SaveAndRestore.LoadData(ref i, saveData, ref WeekDayPlan); - SaveAndRestore.LoadData(ref i, saveData, ref WeekEndPlan); + public static void Load(ref byte[] saveData) + { + int i = 0; + SaveAndRestore.LoadData(ref i, saveData, ref WeekDayPlan); + SaveAndRestore.LoadData(ref i, saveData, ref WeekEndPlan); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"TransportLineData Load Error: saveData.Length = {saveData.Length} actually = {i}"); - } - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"TransportLineData Load Error: saveData.Length = {saveData.Length} actually = {i}"); + } + } + } } diff --git a/CustomData/VehicleData.cs b/CustomData/VehicleData.cs index dd0a0f9..697236d 100644 --- a/CustomData/VehicleData.cs +++ b/CustomData/VehicleData.cs @@ -2,43 +2,44 @@ namespace RealCity.CustomData { - public class VehicleData - { - public static ushort[] vehicleTransferTime = new ushort[65536]; - public static bool[] isVehicleCharged = new bool[65536]; + public class VehicleData + { + public static ushort[] vehicleTransferTime = new ushort[65536]; + public static bool[] isVehicleCharged = new bool[65536]; - public static void DataInit() - { - for (int i = 0; i < isVehicleCharged.Length; i++) - { - vehicleTransferTime[i] = 0; - isVehicleCharged[i] = false; - } - } + public static void DataInit() + { + //for (int i = 0; i < isVehicleCharged.Length; i++) { + // vehicleTransferTime[i] = 0; + // isVehicleCharged[i] = false; + //} + vehicleTransferTime.Initialize(); + isVehicleCharged.Initialize(); + } - public static void Save(ref byte[] saveData) - { - //3 * 65536 = 196608; - int i = 0; - SaveAndRestore.SaveData(ref i, vehicleTransferTime, ref saveData); - SaveAndRestore.SaveData(ref i, isVehicleCharged, ref saveData); + public static void Save(ref byte[] saveData) + { + //3 * 65536 = 196608; + int i = 0; + SaveAndRestore.SaveData(ref i, vehicleTransferTime, ref saveData); + SaveAndRestore.SaveData(ref i, isVehicleCharged, ref saveData); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"VehicleData Save Error: saveData.Length = {saveData.Length} actually = {i}"); - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"VehicleData Save Error: saveData.Length = {saveData.Length} actually = {i}"); + } + } - public static void Load(ref byte[] saveData) - { - int i = 0; - SaveAndRestore.LoadData(ref i, saveData, ref vehicleTransferTime); - SaveAndRestore.LoadData(ref i, saveData, ref isVehicleCharged); + public static void Load(ref byte[] saveData) + { + int i = 0; + SaveAndRestore.LoadData(ref i, saveData, ref vehicleTransferTime); + SaveAndRestore.LoadData(ref i, saveData, ref isVehicleCharged); - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"VehicleData Load Error: saveData.Length = {saveData.Length} actually = {i}"); - } - } - } + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"VehicleData Load Error: saveData.Length = {saveData.Length} actually = {i}"); + } + } + } } diff --git a/CustomManager/RealCityEconomyManager.cs b/CustomManager/RealCityEconomyManager.cs index 6159cdd..abf8c85 100644 --- a/CustomManager/RealCityEconomyManager.cs +++ b/CustomManager/RealCityEconomyManager.cs @@ -2,223 +2,224 @@ namespace RealCity.CustomManager { - public class RealCityEconomyManager - { - - public static int[] citizenTaxIncomeForUI = new int[17]; - public static int[] citizenIncomeForUI = new int[17]; - public static int[] touristIncomeForUI = new int[17]; - //land income - public static int[] residentHighLandIncomeForUI = new int[17]; - public static int[] residentLowLandIncomeForUI = new int[17]; - public static int[] residentHighEcoLandIncomeForUI = new int[17]; - public static int[] residentLowEcoLandIncomeForUI = new int[17]; - public static int[] commHighLandIncomeForUI = new int[17]; - public static int[] commLowLandIncomeForUI = new int[17]; - public static int[] commLeiLandIncomeForUI = new int[17]; - public static int[] commTouLandIncomeForUI = new int[17]; - public static int[] commEcoLandIncomeForUI = new int[17]; - public static int[] induGenLandIncomeForUI = new int[17]; - public static int[] induFarmerLandIncomeForUI = new int[17]; - public static int[] induForestyLandIncomeForUI = new int[17]; - public static int[] induOilLandIncomeForUI = new int[17]; - public static int[] induOreLandIncomeForUI = new int[17]; - public static int[] officeGenLandIncomeForUI = new int[17]; - public static int[] officeHighTechLandIncomeForUI = new int[17]; - //trade income - public static int[] commHighTradeIncomeForUI = new int[17]; - public static int[] commLowTradeIncomeForUI = new int[17]; - public static int[] commLeiTradeIncomeForUI = new int[17]; - public static int[] commTouTradeIncomeForUI = new int[17]; - public static int[] commEcoTradeIncomeForUI = new int[17]; - public static int[] induGenTradeIncomeForUI = new int[17]; - public static int[] induFarmerTradeIncomeForUI = new int[17]; - public static int[] induForestyTradeIncomeForUI = new int[17]; - public static int[] induOilTradeIncomeForUI = new int[17]; - public static int[] induOreTradeIncomeForUI = new int[17]; - //govement income - public static int[] garbageIncomeForUI = new int[17]; - public static int[] roadIncomeForUI = new int[17]; - public static int[] playerIndustryIncomeForUI = new int[17]; - public static int[] schoolIncomeForUI = new int[17]; - public static int[] policeStationIncomeForUI = new int[17]; - public static int[] healthCareIncomeForUI = new int[17]; - public static int[] fireStationIncomeForUI = new int[17]; + public class RealCityEconomyManager + { - public static void CleanCurrent(int current_idex) - { - citizenTaxIncomeForUI[current_idex] = 0; - citizenIncomeForUI[current_idex] = 0; - touristIncomeForUI[current_idex] = 0; - residentHighLandIncomeForUI[current_idex] = 0; - residentLowLandIncomeForUI[current_idex] = 0; - residentHighEcoLandIncomeForUI[current_idex] = 0; - residentLowEcoLandIncomeForUI[current_idex] = 0; - commHighLandIncomeForUI[current_idex] = 0; - commLowLandIncomeForUI[current_idex] = 0; - commLeiLandIncomeForUI[current_idex] = 0; - commTouLandIncomeForUI[current_idex] = 0; - commEcoLandIncomeForUI[current_idex] = 0; - induGenLandIncomeForUI[current_idex] = 0; - induFarmerLandIncomeForUI[current_idex] = 0; - induForestyLandIncomeForUI[current_idex] = 0; - induOilLandIncomeForUI[current_idex] = 0; - induOreLandIncomeForUI[current_idex] = 0; - officeGenLandIncomeForUI[current_idex] = 0; - officeHighTechLandIncomeForUI[current_idex] = 0; - commHighTradeIncomeForUI[current_idex] = 0; - commLowTradeIncomeForUI[current_idex] = 0; - commLeiTradeIncomeForUI[current_idex] = 0; - commTouTradeIncomeForUI[current_idex] = 0; - commEcoTradeIncomeForUI[current_idex] = 0; - induGenTradeIncomeForUI[current_idex] = 0; - induFarmerTradeIncomeForUI[current_idex] = 0; - induForestyTradeIncomeForUI[current_idex] = 0; - induOilTradeIncomeForUI[current_idex] = 0; - induOreTradeIncomeForUI[current_idex] = 0; - garbageIncomeForUI[current_idex] = 0; - playerIndustryIncomeForUI[current_idex] = 0; - roadIncomeForUI[current_idex] = 0; - schoolIncomeForUI[current_idex] = 0; - policeStationIncomeForUI[current_idex] = 0; - fireStationIncomeForUI[current_idex] = 0; - healthCareIncomeForUI[current_idex] = 0; - } + public static int[] citizenTaxIncomeForUI = new int[17]; + public static int[] citizenIncomeForUI = new int[17]; + public static int[] touristIncomeForUI = new int[17]; + //land income + public static int[] residentHighLandIncomeForUI = new int[17]; + public static int[] residentLowLandIncomeForUI = new int[17]; + public static int[] residentHighEcoLandIncomeForUI = new int[17]; + public static int[] residentLowEcoLandIncomeForUI = new int[17]; + public static int[] commHighLandIncomeForUI = new int[17]; + public static int[] commLowLandIncomeForUI = new int[17]; + public static int[] commLeiLandIncomeForUI = new int[17]; + public static int[] commTouLandIncomeForUI = new int[17]; + public static int[] commEcoLandIncomeForUI = new int[17]; + public static int[] induGenLandIncomeForUI = new int[17]; + public static int[] induFarmerLandIncomeForUI = new int[17]; + public static int[] induForestyLandIncomeForUI = new int[17]; + public static int[] induOilLandIncomeForUI = new int[17]; + public static int[] induOreLandIncomeForUI = new int[17]; + public static int[] officeGenLandIncomeForUI = new int[17]; + public static int[] officeHighTechLandIncomeForUI = new int[17]; + //trade income + public static int[] commHighTradeIncomeForUI = new int[17]; + public static int[] commLowTradeIncomeForUI = new int[17]; + public static int[] commLeiTradeIncomeForUI = new int[17]; + public static int[] commTouTradeIncomeForUI = new int[17]; + public static int[] commEcoTradeIncomeForUI = new int[17]; + public static int[] induGenTradeIncomeForUI = new int[17]; + public static int[] induFarmerTradeIncomeForUI = new int[17]; + public static int[] induForestyTradeIncomeForUI = new int[17]; + public static int[] induOilTradeIncomeForUI = new int[17]; + public static int[] induOreTradeIncomeForUI = new int[17]; + //govement income + public static int[] garbageIncomeForUI = new int[17]; + public static int[] roadIncomeForUI = new int[17]; + public static int[] playerIndustryIncomeForUI = new int[17]; + public static int[] schoolIncomeForUI = new int[17]; + public static int[] policeStationIncomeForUI = new int[17]; + public static int[] healthCareIncomeForUI = new int[17]; + public static int[] fireStationIncomeForUI = new int[17]; - public static void DataInit() - { - for (int i = 0; i < citizenTaxIncomeForUI.Length; i++) - { - citizenTaxIncomeForUI[i] = 0; - citizenIncomeForUI[i] = 0; - touristIncomeForUI[i] = 0; - residentHighLandIncomeForUI[i] = 0; - residentLowLandIncomeForUI[i] = 0; - residentHighEcoLandIncomeForUI[i] = 0; - residentLowEcoLandIncomeForUI[i] = 0; - commHighLandIncomeForUI[i] = 0; - commLowLandIncomeForUI[i] = 0; - commLeiLandIncomeForUI[i] = 0; - commTouLandIncomeForUI[i] = 0; - commEcoLandIncomeForUI[i] = 0; - induGenLandIncomeForUI[i] = 0; - induFarmerLandIncomeForUI[i] = 0; - induForestyLandIncomeForUI[i] = 0; - induOilLandIncomeForUI[i] = 0; - induOreLandIncomeForUI[i] = 0; - officeGenLandIncomeForUI[i] = 0; - officeHighTechLandIncomeForUI[i] = 0; - commHighTradeIncomeForUI[i] = 0; - commLowTradeIncomeForUI[i] = 0; - commLeiTradeIncomeForUI[i] = 0; - commTouTradeIncomeForUI[i] = 0; - commEcoTradeIncomeForUI[i] = 0; - induGenTradeIncomeForUI[i] = 0; - induFarmerTradeIncomeForUI[i] = 0; - induForestyTradeIncomeForUI[i] = 0; - induOilTradeIncomeForUI[i] = 0; - induOreTradeIncomeForUI[i] = 0; - roadIncomeForUI[i] = 0; - playerIndustryIncomeForUI[i] = 0; - garbageIncomeForUI[i] = 0; - schoolIncomeForUI[i] = 0; - policeStationIncomeForUI[i] = 0; - fireStationIncomeForUI[i] = 0; - healthCareIncomeForUI[i] = 0; - } - } + public static void CleanCurrent(int current_idex) + { + citizenTaxIncomeForUI[current_idex] = 0; + citizenIncomeForUI[current_idex] = 0; + touristIncomeForUI[current_idex] = 0; + residentHighLandIncomeForUI[current_idex] = 0; + residentLowLandIncomeForUI[current_idex] = 0; + residentHighEcoLandIncomeForUI[current_idex] = 0; + residentLowEcoLandIncomeForUI[current_idex] = 0; + commHighLandIncomeForUI[current_idex] = 0; + commLowLandIncomeForUI[current_idex] = 0; + commLeiLandIncomeForUI[current_idex] = 0; + commTouLandIncomeForUI[current_idex] = 0; + commEcoLandIncomeForUI[current_idex] = 0; + induGenLandIncomeForUI[current_idex] = 0; + induFarmerLandIncomeForUI[current_idex] = 0; + induForestyLandIncomeForUI[current_idex] = 0; + induOilLandIncomeForUI[current_idex] = 0; + induOreLandIncomeForUI[current_idex] = 0; + officeGenLandIncomeForUI[current_idex] = 0; + officeHighTechLandIncomeForUI[current_idex] = 0; + commHighTradeIncomeForUI[current_idex] = 0; + commLowTradeIncomeForUI[current_idex] = 0; + commLeiTradeIncomeForUI[current_idex] = 0; + commTouTradeIncomeForUI[current_idex] = 0; + commEcoTradeIncomeForUI[current_idex] = 0; + induGenTradeIncomeForUI[current_idex] = 0; + induFarmerTradeIncomeForUI[current_idex] = 0; + induForestyTradeIncomeForUI[current_idex] = 0; + induOilTradeIncomeForUI[current_idex] = 0; + induOreTradeIncomeForUI[current_idex] = 0; + garbageIncomeForUI[current_idex] = 0; + playerIndustryIncomeForUI[current_idex] = 0; + roadIncomeForUI[current_idex] = 0; + schoolIncomeForUI[current_idex] = 0; + policeStationIncomeForUI[current_idex] = 0; + fireStationIncomeForUI[current_idex] = 0; + healthCareIncomeForUI[current_idex] = 0; + } - public static void Load(ref byte[] saveData) - { - int i = 0; - SaveAndRestore.LoadData(ref i, saveData, ref citizenTaxIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref citizenIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref touristIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref residentHighLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref residentLowLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref residentHighEcoLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref residentLowEcoLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commHighLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commLowLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commLeiLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commTouLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commEcoLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induGenLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induFarmerLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induForestyLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induOilLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induOreLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref officeGenLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref officeHighTechLandIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commHighTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commLowTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commLeiTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commTouTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref commEcoTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induGenTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induFarmerTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induForestyTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induOilTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref induOreTradeIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref roadIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref playerIndustryIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref garbageIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref schoolIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref policeStationIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref healthCareIncomeForUI); - SaveAndRestore.LoadData(ref i, saveData, ref fireStationIncomeForUI); + public static void DataInit() + { + for (int i = 0; i < citizenTaxIncomeForUI.Length; i++) + { + CleanCurrent(i); + //citizenTaxIncomeForUI[i] = 0; + //citizenIncomeForUI[i] = 0; + //touristIncomeForUI[i] = 0; + //residentHighLandIncomeForUI[i] = 0; + //residentLowLandIncomeForUI[i] = 0; + //residentHighEcoLandIncomeForUI[i] = 0; + //residentLowEcoLandIncomeForUI[i] = 0; + //commHighLandIncomeForUI[i] = 0; + //commLowLandIncomeForUI[i] = 0; + //commLeiLandIncomeForUI[i] = 0; + //commTouLandIncomeForUI[i] = 0; + //commEcoLandIncomeForUI[i] = 0; + //induGenLandIncomeForUI[i] = 0; + //induFarmerLandIncomeForUI[i] = 0; + //induForestyLandIncomeForUI[i] = 0; + //induOilLandIncomeForUI[i] = 0; + //induOreLandIncomeForUI[i] = 0; + //officeGenLandIncomeForUI[i] = 0; + //officeHighTechLandIncomeForUI[i] = 0; + //commHighTradeIncomeForUI[i] = 0; + //commLowTradeIncomeForUI[i] = 0; + //commLeiTradeIncomeForUI[i] = 0; + //commTouTradeIncomeForUI[i] = 0; + //commEcoTradeIncomeForUI[i] = 0; + //induGenTradeIncomeForUI[i] = 0; + //induFarmerTradeIncomeForUI[i] = 0; + //induForestyTradeIncomeForUI[i] = 0; + //induOilTradeIncomeForUI[i] = 0; + //induOreTradeIncomeForUI[i] = 0; + //roadIncomeForUI[i] = 0; + //playerIndustryIncomeForUI[i] = 0; + //garbageIncomeForUI[i] = 0; + //schoolIncomeForUI[i] = 0; + //policeStationIncomeForUI[i] = 0; + //fireStationIncomeForUI[i] = 0; + //healthCareIncomeForUI[i] = 0; + } + } - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"RealCityEconomyManager Load Error: saveData.Length = {saveData.Length} + i = {i}"); - } - } + public static void Load(ref byte[] saveData) + { + int i = 0; + SaveAndRestore.LoadData(ref i, saveData, ref citizenTaxIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref citizenIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref touristIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref residentHighLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref residentLowLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref residentHighEcoLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref residentLowEcoLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commHighLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commLowLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commLeiLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commTouLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commEcoLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induGenLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induFarmerLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induForestyLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induOilLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induOreLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref officeGenLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref officeHighTechLandIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commHighTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commLowTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commLeiTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commTouTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref commEcoTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induGenTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induFarmerTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induForestyTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induOilTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref induOreTradeIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref roadIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref playerIndustryIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref garbageIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref schoolIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref policeStationIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref healthCareIncomeForUI); + SaveAndRestore.LoadData(ref i, saveData, ref fireStationIncomeForUI); - public static void Save(ref byte[] saveData) - { - int i = 0; - //36 * 4 * 17 = 2448 - SaveAndRestore.SaveData(ref i, citizenTaxIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, citizenIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, touristIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, residentHighLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, residentLowLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, residentHighEcoLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, residentLowEcoLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commHighLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commLowLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commLeiLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commTouLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commEcoLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induGenLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induFarmerLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induForestyLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induOilLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induOreLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, officeGenLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, officeHighTechLandIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commHighTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commLowTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commLeiTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commTouTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, commEcoTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induGenTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induFarmerTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induForestyTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induOilTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, induOreTradeIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, roadIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, playerIndustryIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, garbageIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, schoolIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, policeStationIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, healthCareIncomeForUI, ref saveData); - SaveAndRestore.SaveData(ref i, fireStationIncomeForUI, ref saveData); + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"RealCityEconomyManager Load Error: saveData.Length = {saveData.Length} + i = {i}"); + } + } - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"RealCityEconomyManager Save Error: saveData.Length = {saveData.Length} + i = {i}"); - } - } - } + public static void Save(ref byte[] saveData) + { + int i = 0; + //36 * 4 * 17 = 2448 + SaveAndRestore.SaveData(ref i, citizenTaxIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, citizenIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, touristIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, residentHighLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, residentLowLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, residentHighEcoLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, residentLowEcoLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commHighLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commLowLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commLeiLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commTouLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commEcoLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induGenLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induFarmerLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induForestyLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induOilLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induOreLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, officeGenLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, officeHighTechLandIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commHighTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commLowTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commLeiTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commTouTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, commEcoTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induGenTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induFarmerTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induForestyTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induOilTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, induOreTradeIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, roadIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, playerIndustryIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, garbageIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, schoolIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, policeStationIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, healthCareIncomeForUI, ref saveData); + SaveAndRestore.SaveData(ref i, fireStationIncomeForUI, ref saveData); + + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"RealCityEconomyManager Save Error: saveData.Length = {saveData.Length} + i = {i}"); + } + } + } } diff --git a/Loader.cs b/Loader.cs index 7a93109..cf00e80 100644 --- a/Loader.cs +++ b/Loader.cs @@ -14,474 +14,477 @@ namespace RealCity { - public class Loader : LoadingExtensionBase - { - public static bool HarmonyDetourInited = false; - public static bool HarmonyDetourFailed = true; - public static UIView parentGuiView; - public static UIPanel HumanInfo; - public static UIPanel TouristInfo; - public static EcnomicUI ecnomicUI; - public static RealCityUI realCityUI; - public static HumanUI humanUI; - public static PoliticsUI politicsUI; - public static TouristUI touristUI; - public static GameObject buildingWindowGameObject; - public static GameObject HumanWindowGameObject; - public static GameObject TouristWindowGameObject; - public static LoadMode CurrentLoadMode; - public static bool isGuiRunning = false; - public static PoliticsButton PlButton; - public static EcnomicButton EcButton; - public static RealCityButton RcButton; - public static BuildingButton BButton; - public static PlayerBuildingButton PBButton; - public static string m_atlasName = "RealCity"; - public static bool m_atlasLoaded; - public static UIPanel PBLInfo; - public static PBLUI PBLUI; - public static GameObject PBLWindowGameObject; - public static bool isTransportLinesManagerRunning = false; - public static bool isRealTimeRunning = false; - - public override void OnCreated(ILoading loading) - { - HarmonyInitDetour(); - base.OnCreated(loading); - } - - public override void OnLevelLoaded(LoadMode mode) - { - base.OnLevelLoaded(mode); - CurrentLoadMode = mode; - if (RealCity.IsEnabled) - { - if (mode == LoadMode.LoadGame || mode == LoadMode.NewGame) - { - isTransportLinesManagerRunning = CheckTransportLinesManagerIsLoaded(); - DebugLog.LogToFileOnly($"Check TLM running = {isTransportLinesManagerRunning}"); - isRealTimeRunning = CheckRealTimeIsLoaded(); - DebugLog.LogToFileOnly($"Check RealTime running = {isRealTimeRunning}"); - isTransportLinesManagerRunning = isTransportLinesManagerRunning || (!isRealTimeRunning); - //refresh OptionsMainPanel - MethodInfo method = typeof(OptionsMainPanel).GetMethod("OnLocaleChanged", BindingFlags.Instance | BindingFlags.NonPublic); - method.Invoke(UIView.library.Get("OptionsPanel"), new object[0]); - SetupGui(); - HarmonyInitDetour(); - OptionUI.LoadSetting(); - RealCityThreading.isFirstTime = true; - DebugLog.LogToFileOnly("OnLevelLoaded"); - if (mode == LoadMode.NewGame) - { - InitData(); - } - } - else - { - if (RealCity.IsEnabled) - { - HarmonyRevertDetour(); - } - } - } - } - - public static void InitData() - { - DebugLog.LogToFileOnly("InitData"); - TransportLineData.DataInit(); - VehicleData.DataInit(); - BuildingData.DataInit(); - CitizenUnitData.DataInit(); - CitizenData.DataInit(); - RealCityEconomyManager.DataInit(); - System.Random rand = new System.Random(); - RealCityEconomyExtension.partyTrend = (byte)rand.Next(5); - RealCityEconomyExtension.partyTrendStrength = (byte)rand.Next(300); - - DebugLog.LogToFileOnly("InitData Done"); - } - - public override void OnLevelUnloading() - { - base.OnLevelUnloading(); - if (CurrentLoadMode == LoadMode.LoadGame || CurrentLoadMode == LoadMode.NewGame) - { - if (RealCity.IsEnabled && isGuiRunning) - { - RemoveGui(); - } - if (RealCity.IsEnabled) - { - RealCityThreading.isFirstTime = true; - HarmonyRevertDetour(); - } - } - } - - public override void OnReleased() - { - base.OnReleased(); - } - - private static void LoadSprites() - { - if (SpriteUtilities.GetAtlas(m_atlasName) != null) return; - var modPath = PluginManager.instance.FindPluginInfo(Assembly.GetExecutingAssembly()).modPath; - m_atlasLoaded = SpriteUtilities.InitialiseAtlas(Path.Combine(modPath, "Icon/RealCity.png"), m_atlasName); - if (m_atlasLoaded) - { - var spriteSuccess = true; - spriteSuccess = SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(382, 0), new Vector2(191, 191)), "EcButton", m_atlasName) - && SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(0, 0), new Vector2(191, 191)), "Blank", m_atlasName) - && SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(191, 0), new Vector2(191, 191)), "BuildingButton", m_atlasName) - && SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(573, 0), new Vector2(191, 191)), "Politics", m_atlasName) - && SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(764, 0), new Vector2(191, 191)), "RcButton", m_atlasName) - && spriteSuccess; - if (!spriteSuccess) DebugLog.LogToFileOnly("Some sprites haven't been loaded. This is abnormal; you should probably report this to the mod creator."); - } - else DebugLog.LogToFileOnly("The texture atlas (provides custom icons) has not loaded. All icons have reverted to text prompts."); - } - - public static void SetupGui() - { - LoadSprites(); - if (m_atlasLoaded) - { - parentGuiView = null; - parentGuiView = UIView.GetAView(); - if (ecnomicUI == null) - { - ecnomicUI = (EcnomicUI)parentGuiView.AddUIComponent(typeof(EcnomicUI)); - } - - if (realCityUI == null) - { - realCityUI = (RealCityUI)parentGuiView.AddUIComponent(typeof(RealCityUI)); - } - - if (politicsUI == null) - { - politicsUI = (PoliticsUI)parentGuiView.AddUIComponent(typeof(PoliticsUI)); - } - - SetupHumanGui(); - SetupTouristGui(); - SetupEcnomicButton(); - SetupPLButton(); - SetupCityButton(); - SetupBuildingButton(); - SetupPlayerBuildingButton(); - if (!isTransportLinesManagerRunning) - SetupPBLUIGui(); - isGuiRunning = true; - } - } - public static void SetupPBLUIGui() - { - PBLWindowGameObject = new GameObject("PBLWindowGameObject"); - PBLUI = (PBLUI)PBLWindowGameObject.AddComponent(typeof(PBLUI)); - PBLInfo = UIView.Find("(Library) PublicTransportWorldInfoPanel"); - if (PBLInfo == null) - { - DebugLog.LogToFileOnly("UIPanel not found (update broke the mod!): (Library) PublicTransportWorldInfoPanel\nAvailable panels are:\n"); - } - else - { - PBLUI.transform.parent = PBLInfo.transform; - PBLUI.size = new Vector3(150, 100); - PBLUI.baseBuildingWindow = PBLInfo.gameObject.transform.GetComponentInChildren(); - UILabel UILabel = PBLUI.baseBuildingWindow.Find("ModelLabel"); - PBLUI.position = new Vector3(UILabel.relativePosition.x + 50f, PBLInfo.size.y - (UILabel.relativePosition.y + 160f)); - PBLInfo.eventVisibilityChanged += PBLInfo_eventVisibilityChanged; - } - } - public static void PBLInfo_eventVisibilityChanged(UIComponent component, bool value) - { - PBLUI.isEnabled = value; - if (value) - { - //initialize PBL ui again - PBLUI.transform.parent = PBLInfo.transform; - PBLUI.size = new Vector3(150, 100); - PBLUI.baseBuildingWindow = PBLInfo.gameObject.transform.GetComponentInChildren(); - UILabel UILabel = PBLUI.baseBuildingWindow.Find("ModelLabel"); - //DebugLog.LogToFileOnly(UILabel.relativePosition.x.ToString() + " " + UILabel.relativePosition.y.ToString()); - PBLUI.position = new Vector3(UILabel.relativePosition.x + 50f, PBLInfo.size.y - (UILabel.relativePosition.y + 160f)); - PBLUI.refeshOnce = true; - PBLUI.Show(); - } - else - { - PBLUI.Hide(); - } - } - public static void SetupHumanGui() - { - HumanWindowGameObject = new GameObject("HumanWindowGameObject"); - humanUI = (HumanUI)HumanWindowGameObject.AddComponent(typeof(HumanUI)); - HumanInfo = UIView.Find("(Library) CitizenWorldInfoPanel"); - if (HumanInfo == null) - { - DebugLog.LogToFileOnly("UIPanel not found (update broke the mod!): (Library) CitizenWorldInfoPanel\nAvailable panels are:\n"); - } - humanUI.transform.parent = HumanInfo.transform; - humanUI.size = new Vector3(HumanInfo.size.x, HumanInfo.size.y); - humanUI.baseBuildingWindow = HumanInfo.gameObject.transform.GetComponentInChildren(); - humanUI.position = new Vector3(HumanInfo.size.x, HumanInfo.size.y); - HumanInfo.eventVisibilityChanged += HumanInfo_eventVisibilityChanged; - } - - public static void SetupTouristGui() - { - TouristWindowGameObject = new GameObject("TouristWindowGameObject"); - touristUI = (TouristUI)TouristWindowGameObject.AddComponent(typeof(TouristUI)); - TouristInfo = UIView.Find("(Library) TouristWorldInfoPanel"); - if (TouristInfo == null) - { - DebugLog.LogToFileOnly("UIPanel not found (update broke the mod!): (Library) TouristWorldInfoPanel\nAvailable panels are:\n"); - } - touristUI.transform.parent = TouristInfo.transform; - touristUI.size = new Vector3(TouristInfo.size.x, TouristInfo.size.y); - touristUI.baseBuildingWindow = TouristInfo.gameObject.transform.GetComponentInChildren(); - touristUI.position = new Vector3(TouristInfo.size.x, TouristInfo.size.y); - TouristInfo.eventVisibilityChanged += TouristInfo_eventVisibilityChanged; - } - - public static void SetupEcnomicButton() - { - if (EcButton == null) - { - EcButton = (parentGuiView.AddUIComponent(typeof(EcnomicButton)) as EcnomicButton); - } - EcButton.Show(); - } - - public static void SetupCityButton() - { - if (RcButton == null) - { - RcButton = (parentGuiView.AddUIComponent(typeof(RealCityButton)) as RealCityButton); - } - RcButton.Show(); - } - - public static void SetupBuildingButton() - { - var buildingInfo = UIView.Find("(Library) ZonedBuildingWorldInfoPanel"); - if (BButton == null) - { - BButton = (buildingInfo.AddUIComponent(typeof(BuildingButton)) as BuildingButton); - } - BButton.width = 40f; - BButton.height = 35f; - BButton.relativePosition = new Vector3(120, buildingInfo.size.y - BButton.height); - BButton.Show(); - } - - public static void SetupPlayerBuildingButton() - { - var playerBuildingInfo = UIView.Find("(Library) CityServiceWorldInfoPanel"); - if (PBButton == null) - { - PBButton = (playerBuildingInfo.AddUIComponent(typeof(PlayerBuildingButton)) as PlayerBuildingButton); - } - PBButton.width = 40f; - PBButton.height = 35f; - PBButton.relativePosition = new Vector3(120, playerBuildingInfo.size.y - PBButton.height); - PBButton.Show(); - } - - public static void SetupPLButton() - { - if (PlButton == null) - { - PlButton = (parentGuiView.AddUIComponent(typeof(PoliticsButton)) as PoliticsButton); - } - PlButton.Show(); - } - - public static void HumanInfo_eventVisibilityChanged(UIComponent component, bool value) - { - humanUI.isEnabled = value; - if (value) - { - //initialize human ui again - humanUI.transform.parent = HumanInfo.transform; - humanUI.size = new Vector3(HumanInfo.size.x, HumanInfo.size.y); - humanUI.baseBuildingWindow = HumanInfo.gameObject.transform.GetComponentInChildren(); - humanUI.position = new Vector3(HumanInfo.size.x, HumanInfo.size.y); - HumanUI.refeshOnce = true; - humanUI.Show(); - } - else - { - humanUI.Hide(); - } - } - - public static void TouristInfo_eventVisibilityChanged(UIComponent component, bool value) - { - touristUI.isEnabled = value; - if (value) - { - //initialize human ui again - touristUI.transform.parent = TouristInfo.transform; - touristUI.size = new Vector3(TouristInfo.size.x, HumanInfo.size.y); - touristUI.baseBuildingWindow = TouristInfo.gameObject.transform.GetComponentInChildren(); - touristUI.position = new Vector3(TouristInfo.size.x, TouristInfo.size.y); - TouristUI.refeshOnce = true; - touristUI.Show(); - } - else - { - touristUI.Hide(); - } - } - - public static void RemoveGui() - { - isGuiRunning = false; - if (parentGuiView != null) - { - parentGuiView = null; - UnityEngine.Object.Destroy(ecnomicUI); - UnityEngine.Object.Destroy(realCityUI); - UnityEngine.Object.Destroy(politicsUI); - UnityEngine.Object.Destroy(EcButton); - UnityEngine.Object.Destroy(RcButton); - UnityEngine.Object.Destroy(PlButton); - ecnomicUI = null; - realCityUI = null; - politicsUI = null; - EcButton = null; - RcButton = null; - PlButton = null; - } - - if (BButton != null) - { - UnityEngine.Object.Destroy(BButton); - BButton = null; - } - - if (PBButton != null) - { - UnityEngine.Object.Destroy(PBButton); - PBButton = null; - } - - if (buildingWindowGameObject != null) - { - UnityEngine.Object.Destroy(buildingWindowGameObject); - } - //remove HumanUI - if (humanUI != null) - { - if (humanUI.parent != null) - { - humanUI.parent.eventVisibilityChanged -= HumanInfo_eventVisibilityChanged; - } - } - if (HumanWindowGameObject != null) - { - UnityEngine.Object.Destroy(HumanWindowGameObject); - } - //remove TouristUI - if (touristUI != null) - { - if (touristUI.parent != null) - { - touristUI.parent.eventVisibilityChanged -= TouristInfo_eventVisibilityChanged; - } - } - - if (TouristWindowGameObject != null) - { - UnityEngine.Object.Destroy(TouristWindowGameObject); - } - - if (!isTransportLinesManagerRunning) - { - if (PBLUI != null) - { - if (PBLUI.parent != null) - { - PBLUI.parent.eventVisibilityChanged -= PBLInfo_eventVisibilityChanged; - } - } - - if (PBLWindowGameObject != null) - { - UnityEngine.Object.Destroy(PBLWindowGameObject); - } - PBLUI._initialized = false; - } - } - - private bool Check3rdPartyModLoaded(string namespaceStr, bool printAll = false) - { - bool result = false; - FieldInfo field = typeof(LoadingWrapper).GetField("m_LoadingExtensions", BindingFlags.Instance | BindingFlags.NonPublic); - List list = (List)field.GetValue(Singleton.instance.m_LoadingWrapper); - if (list != null) - { - foreach (ILoadingExtension current in list) - { - if (printAll) - { - DebugLog.LogToFileOnly(string.Format("Detected extension: {0} in namespace {1}", current.GetType().Name, current.GetType().Namespace)); - } - if (current.GetType().Namespace != null) - { - string value = current.GetType().Namespace.ToString(); - if (namespaceStr.Equals(value)) - { - DebugLog.LogToFileOnly(string.Format("The mod '{0}' has been detected.", namespaceStr)); - result = true; - break; - } - } - } - } - return result; - } - - public static void HarmonyInitDetour() - { - if (HarmonyHelper.IsHarmonyInstalled) - { - if (!HarmonyDetourInited) - { - DebugLog.LogToFileOnly("Init harmony detours"); - HarmonyDetours.Apply(); - HarmonyDetourInited = true; - } - } - } - - public static void HarmonyRevertDetour() - { - if (HarmonyHelper.IsHarmonyInstalled) - { - if (HarmonyDetourInited) - { - DebugLog.LogToFileOnly("Revert harmony detours"); - HarmonyDetours.DeApply(); - HarmonyDetourFailed = true; - HarmonyDetourInited = false; - } - } - } - - private bool CheckTransportLinesManagerIsLoaded() - { - return Check3rdPartyModLoaded("Klyte.TransportLinesManager", false); - } - - private bool CheckRealTimeIsLoaded() - { - return Check3rdPartyModLoaded("RealTime.Core", false); - } - } + public class Loader : LoadingExtensionBase + { + public static bool HarmonyDetourInited = false; + public static bool HarmonyDetourFailed = true; + public static UIView parentGuiView; + public static UIPanel HumanInfo; + public static UIPanel TouristInfo; + public static EcnomicUI ecnomicUI; + public static RealCityUI realCityUI; + public static HumanUI humanUI; + public static PoliticsUI politicsUI; + public static TouristUI touristUI; + public static GameObject buildingWindowGameObject; + public static GameObject HumanWindowGameObject; + public static GameObject TouristWindowGameObject; + public static LoadMode CurrentLoadMode; + public static bool isGuiRunning = false; + public static PoliticsButton PlButton; + public static EcnomicButton EcButton; + public static RealCityButton RcButton; + public static BuildingButton BButton; + public static PlayerBuildingButton PBButton; + public static string m_atlasName = "RealCity"; + public static bool m_atlasLoaded; + public static UIPanel PBLInfo; + public static PBLUI PBLUI; + public static GameObject PBLWindowGameObject; + public static bool isTransportLinesManagerRunning = false; + public static bool isRealTimeRunning = false; + + public override void OnCreated(ILoading loading) + { + HarmonyInitDetour(); + base.OnCreated(loading); + } + + public override void OnLevelLoaded(LoadMode mode) + { + base.OnLevelLoaded(mode); + CurrentLoadMode = mode; + if (RealCity.IsEnabled) + { + if (mode == LoadMode.LoadGame || mode == LoadMode.NewGame) + { + isTransportLinesManagerRunning = CheckTransportLinesManagerIsLoaded(); + DebugLog.LogToFileOnly($"Check TLM running = {isTransportLinesManagerRunning}"); + isRealTimeRunning = CheckRealTimeIsLoaded(); + DebugLog.LogToFileOnly($"Check RealTime running = {isRealTimeRunning}"); + isTransportLinesManagerRunning = isTransportLinesManagerRunning || (!isRealTimeRunning); + //refresh OptionsMainPanel + MethodInfo method = typeof(OptionsMainPanel).GetMethod("OnLocaleChanged", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(UIView.library.Get("OptionsPanel"), new object[0]); + SetupGui(); + HarmonyInitDetour(); + OptionUI.LoadSetting(); + RealCityThreading.isFirstTime = true; + DebugLog.LogToFileOnly("OnLevelLoaded"); + if (mode == LoadMode.NewGame) + { + InitData(); + } + } + else + { + if (RealCity.IsEnabled) + { + HarmonyRevertDetour(); + } + } + } + } + + public static void InitData() + { + DebugLog.LogToFileOnly("InitData"); + TransportLineData.DataInit(); + VehicleData.DataInit(); + BuildingData.DataInit(); + CitizenUnitData.DataInit(); + CitizenData.DataInit(); + RealCityEconomyManager.DataInit(); + + Politics.DataInit(); + + //System.Random rand = new System.Random(); + //RealCityEconomyExtension.partyTrend = (byte)rand.Next(5); + //RealCityEconomyExtension.partyTrendStrength = (byte)rand.Next(300); + + DebugLog.LogToFileOnly("InitData Done"); + } + + public override void OnLevelUnloading() + { + base.OnLevelUnloading(); + if (CurrentLoadMode == LoadMode.LoadGame || CurrentLoadMode == LoadMode.NewGame) + { + if (RealCity.IsEnabled && isGuiRunning) + { + RemoveGui(); + } + if (RealCity.IsEnabled) + { + RealCityThreading.isFirstTime = true; + HarmonyRevertDetour(); + } + } + } + + public override void OnReleased() + { + base.OnReleased(); + } + + private static void LoadSprites() + { + if (SpriteUtilities.GetAtlas(m_atlasName) != null) return; + var modPath = PluginManager.instance.FindPluginInfo(Assembly.GetExecutingAssembly()).modPath; + m_atlasLoaded = SpriteUtilities.InitialiseAtlas(Path.Combine(modPath, "Icon/RealCity.png"), m_atlasName); + if (m_atlasLoaded) + { + var spriteSuccess = true; + spriteSuccess = SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(382, 0), new Vector2(191, 191)), "EcButton", m_atlasName) + && SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(0, 0), new Vector2(191, 191)), "Blank", m_atlasName) + && SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(191, 0), new Vector2(191, 191)), "BuildingButton", m_atlasName) + && SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(573, 0), new Vector2(191, 191)), "Politics", m_atlasName) + && SpriteUtilities.AddSpriteToAtlas(new Rect(new Vector2(764, 0), new Vector2(191, 191)), "RcButton", m_atlasName) + && spriteSuccess; + if (!spriteSuccess) DebugLog.LogToFileOnly("Some sprites haven't been loaded. This is abnormal; you should probably report this to the mod creator."); + } + else DebugLog.LogToFileOnly("The texture atlas (provides custom icons) has not loaded. All icons have reverted to text prompts."); + } + + public static void SetupGui() + { + LoadSprites(); + if (m_atlasLoaded) + { + parentGuiView = null; + parentGuiView = UIView.GetAView(); + if (ecnomicUI == null) + { + ecnomicUI = (EcnomicUI)parentGuiView.AddUIComponent(typeof(EcnomicUI)); + } + + if (realCityUI == null) + { + realCityUI = (RealCityUI)parentGuiView.AddUIComponent(typeof(RealCityUI)); + } + + if (politicsUI == null) + { + politicsUI = (PoliticsUI)parentGuiView.AddUIComponent(typeof(PoliticsUI)); + } + + SetupHumanGui(); + SetupTouristGui(); + SetupEcnomicButton(); + SetupPLButton(); + SetupCityButton(); + SetupBuildingButton(); + SetupPlayerBuildingButton(); + if (!isTransportLinesManagerRunning) + SetupPBLUIGui(); + isGuiRunning = true; + } + } + public static void SetupPBLUIGui() + { + PBLWindowGameObject = new GameObject("PBLWindowGameObject"); + PBLUI = (PBLUI)PBLWindowGameObject.AddComponent(typeof(PBLUI)); + PBLInfo = UIView.Find("(Library) PublicTransportWorldInfoPanel"); + if (PBLInfo == null) + { + DebugLog.LogToFileOnly("UIPanel not found (update broke the mod!): (Library) PublicTransportWorldInfoPanel\nAvailable panels are:\n"); + } + else + { + PBLUI.transform.parent = PBLInfo.transform; + PBLUI.size = new Vector3(150, 100); + PBLUI.baseBuildingWindow = PBLInfo.gameObject.transform.GetComponentInChildren(); + UILabel UILabel = PBLUI.baseBuildingWindow.Find("ModelLabel"); + PBLUI.position = new Vector3(UILabel.relativePosition.x + 50f, PBLInfo.size.y - (UILabel.relativePosition.y + 160f)); + PBLInfo.eventVisibilityChanged += PBLInfo_eventVisibilityChanged; + } + } + public static void PBLInfo_eventVisibilityChanged(UIComponent component, bool value) + { + PBLUI.isEnabled = value; + if (value) + { + //initialize PBL ui again + PBLUI.transform.parent = PBLInfo.transform; + PBLUI.size = new Vector3(150, 100); + PBLUI.baseBuildingWindow = PBLInfo.gameObject.transform.GetComponentInChildren(); + UILabel UILabel = PBLUI.baseBuildingWindow.Find("ModelLabel"); + //DebugLog.LogToFileOnly(UILabel.relativePosition.x.ToString() + " " + UILabel.relativePosition.y.ToString()); + PBLUI.position = new Vector3(UILabel.relativePosition.x + 50f, PBLInfo.size.y - (UILabel.relativePosition.y + 160f)); + PBLUI.refeshOnce = true; + PBLUI.Show(); + } + else + { + PBLUI.Hide(); + } + } + public static void SetupHumanGui() + { + HumanWindowGameObject = new GameObject("HumanWindowGameObject"); + humanUI = (HumanUI)HumanWindowGameObject.AddComponent(typeof(HumanUI)); + HumanInfo = UIView.Find("(Library) CitizenWorldInfoPanel"); + if (HumanInfo == null) + { + DebugLog.LogToFileOnly("UIPanel not found (update broke the mod!): (Library) CitizenWorldInfoPanel\nAvailable panels are:\n"); + } + humanUI.transform.parent = HumanInfo.transform; + humanUI.size = new Vector3(HumanInfo.size.x, HumanInfo.size.y); + humanUI.baseBuildingWindow = HumanInfo.gameObject.transform.GetComponentInChildren(); + humanUI.position = new Vector3(HumanInfo.size.x, HumanInfo.size.y); + HumanInfo.eventVisibilityChanged += HumanInfo_eventVisibilityChanged; + } + + public static void SetupTouristGui() + { + TouristWindowGameObject = new GameObject("TouristWindowGameObject"); + touristUI = (TouristUI)TouristWindowGameObject.AddComponent(typeof(TouristUI)); + TouristInfo = UIView.Find("(Library) TouristWorldInfoPanel"); + if (TouristInfo == null) + { + DebugLog.LogToFileOnly("UIPanel not found (update broke the mod!): (Library) TouristWorldInfoPanel\nAvailable panels are:\n"); + } + touristUI.transform.parent = TouristInfo.transform; + touristUI.size = new Vector3(TouristInfo.size.x, TouristInfo.size.y); + touristUI.baseBuildingWindow = TouristInfo.gameObject.transform.GetComponentInChildren(); + touristUI.position = new Vector3(TouristInfo.size.x, TouristInfo.size.y); + TouristInfo.eventVisibilityChanged += TouristInfo_eventVisibilityChanged; + } + + public static void SetupEcnomicButton() + { + if (EcButton == null) + { + EcButton = (parentGuiView.AddUIComponent(typeof(EcnomicButton)) as EcnomicButton); + } + EcButton.Show(); + } + + public static void SetupCityButton() + { + if (RcButton == null) + { + RcButton = (parentGuiView.AddUIComponent(typeof(RealCityButton)) as RealCityButton); + } + RcButton.Show(); + } + + public static void SetupBuildingButton() + { + var buildingInfo = UIView.Find("(Library) ZonedBuildingWorldInfoPanel"); + if (BButton == null) + { + BButton = (buildingInfo.AddUIComponent(typeof(BuildingButton)) as BuildingButton); + } + BButton.width = 40f; + BButton.height = 35f; + BButton.relativePosition = new Vector3(120, buildingInfo.size.y - BButton.height); + BButton.Show(); + } + + public static void SetupPlayerBuildingButton() + { + var playerBuildingInfo = UIView.Find("(Library) CityServiceWorldInfoPanel"); + if (PBButton == null) + { + PBButton = (playerBuildingInfo.AddUIComponent(typeof(PlayerBuildingButton)) as PlayerBuildingButton); + } + PBButton.width = 40f; + PBButton.height = 35f; + PBButton.relativePosition = new Vector3(120, playerBuildingInfo.size.y - PBButton.height); + PBButton.Show(); + } + + public static void SetupPLButton() + { + if (PlButton == null) + { + PlButton = (parentGuiView.AddUIComponent(typeof(PoliticsButton)) as PoliticsButton); + } + PlButton.Show(); + } + + public static void HumanInfo_eventVisibilityChanged(UIComponent component, bool value) + { + humanUI.isEnabled = value; + if (value) + { + //initialize human ui again + humanUI.transform.parent = HumanInfo.transform; + humanUI.size = new Vector3(HumanInfo.size.x, HumanInfo.size.y); + humanUI.baseBuildingWindow = HumanInfo.gameObject.transform.GetComponentInChildren(); + humanUI.position = new Vector3(HumanInfo.size.x, HumanInfo.size.y); + HumanUI.refeshOnce = true; + humanUI.Show(); + } + else + { + humanUI.Hide(); + } + } + + public static void TouristInfo_eventVisibilityChanged(UIComponent component, bool value) + { + touristUI.isEnabled = value; + if (value) + { + //initialize human ui again + touristUI.transform.parent = TouristInfo.transform; + touristUI.size = new Vector3(TouristInfo.size.x, HumanInfo.size.y); + touristUI.baseBuildingWindow = TouristInfo.gameObject.transform.GetComponentInChildren(); + touristUI.position = new Vector3(TouristInfo.size.x, TouristInfo.size.y); + TouristUI.refeshOnce = true; + touristUI.Show(); + } + else + { + touristUI.Hide(); + } + } + + public static void RemoveGui() + { + isGuiRunning = false; + if (parentGuiView != null) + { + parentGuiView = null; + UnityEngine.Object.Destroy(ecnomicUI); + UnityEngine.Object.Destroy(realCityUI); + UnityEngine.Object.Destroy(politicsUI); + UnityEngine.Object.Destroy(EcButton); + UnityEngine.Object.Destroy(RcButton); + UnityEngine.Object.Destroy(PlButton); + ecnomicUI = null; + realCityUI = null; + politicsUI = null; + EcButton = null; + RcButton = null; + PlButton = null; + } + + if (BButton != null) + { + UnityEngine.Object.Destroy(BButton); + BButton = null; + } + + if (PBButton != null) + { + UnityEngine.Object.Destroy(PBButton); + PBButton = null; + } + + if (buildingWindowGameObject != null) + { + UnityEngine.Object.Destroy(buildingWindowGameObject); + } + //remove HumanUI + if (humanUI != null) + { + if (humanUI.parent != null) + { + humanUI.parent.eventVisibilityChanged -= HumanInfo_eventVisibilityChanged; + } + } + if (HumanWindowGameObject != null) + { + UnityEngine.Object.Destroy(HumanWindowGameObject); + } + //remove TouristUI + if (touristUI != null) + { + if (touristUI.parent != null) + { + touristUI.parent.eventVisibilityChanged -= TouristInfo_eventVisibilityChanged; + } + } + + if (TouristWindowGameObject != null) + { + UnityEngine.Object.Destroy(TouristWindowGameObject); + } + + if (!isTransportLinesManagerRunning) + { + if (PBLUI != null) + { + if (PBLUI.parent != null) + { + PBLUI.parent.eventVisibilityChanged -= PBLInfo_eventVisibilityChanged; + } + } + + if (PBLWindowGameObject != null) + { + UnityEngine.Object.Destroy(PBLWindowGameObject); + } + PBLUI._initialized = false; + } + } + + private bool Check3rdPartyModLoaded(string namespaceStr, bool printAll = false) + { + bool result = false; + FieldInfo field = typeof(LoadingWrapper).GetField("m_LoadingExtensions", BindingFlags.Instance | BindingFlags.NonPublic); + List list = (List)field.GetValue(Singleton.instance.m_LoadingWrapper); + if (list != null) + { + foreach (ILoadingExtension current in list) + { + if (printAll) + { + DebugLog.LogToFileOnly(string.Format("Detected extension: {0} in namespace {1}", current.GetType().Name, current.GetType().Namespace)); + } + if (current.GetType().Namespace != null) + { + string value = current.GetType().Namespace.ToString(); + if (namespaceStr.Equals(value)) + { + DebugLog.LogToFileOnly(string.Format("The mod '{0}' has been detected.", namespaceStr)); + result = true; + break; + } + } + } + } + return result; + } + + public static void HarmonyInitDetour() + { + if (HarmonyHelper.IsHarmonyInstalled) + { + if (!HarmonyDetourInited) + { + DebugLog.LogToFileOnly("Init harmony detours"); + HarmonyDetours.Apply(); + HarmonyDetourInited = true; + } + } + } + + public static void HarmonyRevertDetour() + { + if (HarmonyHelper.IsHarmonyInstalled) + { + if (HarmonyDetourInited) + { + DebugLog.LogToFileOnly("Revert harmony detours"); + HarmonyDetours.DeApply(); + HarmonyDetourFailed = true; + HarmonyDetourInited = false; + } + } + } + + private bool CheckTransportLinesManagerIsLoaded() + { + return Check3rdPartyModLoaded("Klyte.TransportLinesManager", false); + } + + private bool CheckRealTimeIsLoaded() + { + return Check3rdPartyModLoaded("RealTime.Core", false); + } + } } diff --git a/Patch/AuxiliaryBuildingAIGetResourceRatePatch.cs b/Patch/AuxiliaryBuildingAIGetResourceRatePatch.cs index 9625a8b..43e4ba6 100644 --- a/Patch/AuxiliaryBuildingAIGetResourceRatePatch.cs +++ b/Patch/AuxiliaryBuildingAIGetResourceRatePatch.cs @@ -7,20 +7,20 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class AuxiliaryBuildingAIGetResourceRatePatch - { - public static MethodBase TargetMethod() - { - return typeof(AuxiliaryBuildingAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); - } - public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) - { - if (resource == EconomyManager.Resource.Maintenance) - { - float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); - __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); - } - } - } + [HarmonyPatch] + public class AuxiliaryBuildingAIGetResourceRatePatch + { + public static MethodBase TargetMethod() + { + return typeof(AuxiliaryBuildingAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); + } + public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) + { + if (resource == EconomyManager.Resource.Maintenance) + { + float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); + __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); + } + } + } } diff --git a/Patch/BuildingAIVisitorEnterPatch.cs b/Patch/BuildingAIVisitorEnterPatch.cs index 4364ac1..d9b130d 100644 --- a/Patch/BuildingAIVisitorEnterPatch.cs +++ b/Patch/BuildingAIVisitorEnterPatch.cs @@ -8,153 +8,153 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class BuildingAIVisitorEnterPatch - { - public static MethodBase TargetMethod() - { - return typeof(BuildingAI).GetMethod("VisitorEnter", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(uint) }, null); - } - public static void Postfix(ushort buildingID, ref Building data, uint citizen) - { - ushort eventIndex = data.m_eventIndex; - if (eventIndex == 0) - { - ProcessTourismIncome(buildingID, ref data, citizen); - } - else - { - EventManager instance = Singleton.instance; - EventInfo info = instance.m_events.m_buffer[(int)eventIndex].Info; - if ((info.m_eventAI is SportMatchAI) || (info.m_eventAI is VarsitySportsMatchAI)) - { - if (buildingID == instance.m_events.m_buffer[(int)eventIndex].m_building && (instance.m_events.m_buffer[(int)eventIndex].m_flags & (EventData.Flags.Preparing | EventData.Flags.Active)) != EventData.Flags.None) - { - if ((Singleton.instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) - { - MainDataStore.outsideTouristMoney -= instance.m_events.m_buffer[(int)eventIndex].m_ticketPrice; - } - else - { - CitizenData.citizenMoney[citizen] -= instance.m_events.m_buffer[(int)eventIndex].m_ticketPrice; - } - } - } - } - } + [HarmonyPatch] + public class BuildingAIVisitorEnterPatch + { + public static MethodBase TargetMethod() + { + return typeof(BuildingAI).GetMethod("VisitorEnter", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(uint) }, null); + } + public static void Postfix(ushort buildingID, ref Building data, uint citizen) + { + ushort eventIndex = data.m_eventIndex; + if (eventIndex == 0) + { + ProcessTourismIncome(buildingID, ref data, citizen); + } + else + { + EventManager instance = Singleton.instance; + EventInfo info = instance.m_events.m_buffer[(int)eventIndex].Info; + if ((info.m_eventAI is SportMatchAI) || (info.m_eventAI is VarsitySportsMatchAI)) + { + if (buildingID == instance.m_events.m_buffer[(int)eventIndex].m_building && (instance.m_events.m_buffer[(int)eventIndex].m_flags & (EventData.Flags.Preparing | EventData.Flags.Active)) != EventData.Flags.None) + { + if ((Singleton.instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) + { + MainDataStore.outsideTouristMoney -= instance.m_events.m_buffer[(int)eventIndex].m_ticketPrice; + } + else + { + CitizenData.citizenMoney[citizen] -= instance.m_events.m_buffer[(int)eventIndex].m_ticketPrice; + } + } + } + } + } - public static void ProcessTourismIncome(ushort buildingID, ref Building data, uint citizen) - { - CitizenManager instance = Singleton.instance; - BuildingInfo info = data.Info; - if (info.m_class.m_service == ItemClass.Service.Monument) - { - if (IsRealUniqueBuilding(buildingID)) - { - if ((instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) - { - ProcessMonumentTourismTouristIncome(ref data, citizen); - } - else - { - ProcessMonumentTourismResidentIncome(ref data, citizen); - } - } - } - else if (info.m_buildingAI is ParkBuildingAI) - { - if ((instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) - { - ProcessParkIncome(ref data, citizen, true); - } - else - { - ProcessParkIncome(ref data, citizen, false); - } - } - } + public static void ProcessTourismIncome(ushort buildingID, ref Building data, uint citizen) + { + CitizenManager instance = Singleton.instance; + BuildingInfo info = data.Info; + if (info.m_class.m_service == ItemClass.Service.Monument) + { + if (IsRealUniqueBuilding(buildingID)) + { + if ((instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) + { + ProcessMonumentTourismTouristIncome(ref data, citizen); + } + else + { + ProcessMonumentTourismResidentIncome(ref data, citizen); + } + } + } + else if (info.m_buildingAI is ParkBuildingAI) + { + if ((instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) + { + ProcessParkIncome(ref data, citizen, true); + } + else + { + ProcessParkIncome(ref data, citizen, false); + } + } + } - public static void ProcessMonumentTourismTouristIncome(ref Building data, uint citizen) - { - CitizenManager instance = Singleton.instance; - int tourism_fee = 1000; - if (instance.m_citizens.m_buffer[citizen].WealthLevel == Citizen.Wealth.High) - tourism_fee <<= 2; - else if (instance.m_citizens.m_buffer[citizen].WealthLevel == Citizen.Wealth.Medium) - tourism_fee <<= 1; + public static void ProcessMonumentTourismTouristIncome(ref Building data, uint citizen) + { + CitizenManager instance = Singleton.instance; + int tourism_fee = 1000; + if (instance.m_citizens.m_buffer[citizen].WealthLevel == Citizen.Wealth.High) + tourism_fee <<= 2; + else if (instance.m_citizens.m_buffer[citizen].WealthLevel == Citizen.Wealth.Medium) + tourism_fee <<= 1; - if (MainDataStore.outsideTouristMoney > 0) - { - MainDataStore.outsideTouristMoney -= tourism_fee; - Singleton.instance.AddPrivateIncome(tourism_fee, ItemClass.Service.Commercial, ItemClass.SubService.CommercialTourist, ItemClass.Level.Level1, 113333); - } - } + if (MainDataStore.outsideTouristMoney > 0) + { + MainDataStore.outsideTouristMoney -= tourism_fee; + Singleton.instance.AddPrivateIncome(tourism_fee, ItemClass.Service.Commercial, ItemClass.SubService.CommercialTourist, ItemClass.Level.Level1, 113333); + } + } - public static void ProcessMonumentTourismResidentIncome(ref Building data, uint citizen) - { - int tourism_fee = (int)(0.2f * CitizenData.citizenMoney[citizen]); - if (tourism_fee > 0) - { - CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - tourism_fee); - Singleton.instance.AddPrivateIncome(tourism_fee, ItemClass.Service.Commercial, ItemClass.SubService.CommercialTourist, ItemClass.Level.Level1, 114333); - } - } + public static void ProcessMonumentTourismResidentIncome(ref Building data, uint citizen) + { + int tourism_fee = (int)(0.2f * CitizenData.citizenMoney[citizen]); + if (tourism_fee > 0) + { + CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - tourism_fee); + Singleton.instance.AddPrivateIncome(tourism_fee, ItemClass.Service.Commercial, ItemClass.SubService.CommercialTourist, ItemClass.Level.Level1, 114333); + } + } - public static void ProcessParkIncome(ref Building data, uint citizen, bool isTourist) - { - DistrictManager instance2 = Singleton.instance; - byte b = instance2.GetPark(data.m_position); - if (b != 0 && !instance2.m_parks.m_buffer[b].IsPark) - { - b = 0; - } + public static void ProcessParkIncome(ref Building data, uint citizen, bool isTourist) + { + DistrictManager instance2 = Singleton.instance; + byte b = instance2.GetPark(data.m_position); + if (b != 0 && !instance2.m_parks.m_buffer[b].IsPark) + { + b = 0; + } - if (b != 0) - { - int ticketPrice = instance2.m_parks.m_buffer[b].GetTicketPrice(); - //Negetive price to help identify tourist and resident. - if (isTourist) - { - if (MainDataStore.outsideTouristMoney > 0) - { - Singleton.instance.AddResource(EconomyManager.Resource.PublicIncome, -(int)ticketPrice, data.Info.m_class); - MainDataStore.outsideTouristMoney -= ticketPrice; - } - else - { - ticketPrice = 0; - } - } - else - { - if (CitizenData.citizenMoney[citizen] > ticketPrice) - { - CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - ticketPrice); - Singleton.instance.AddResource(EconomyManager.Resource.PublicIncome, (int)ticketPrice, data.Info.m_class); - } - } + if (b != 0) + { + int ticketPrice = instance2.m_parks.m_buffer[b].GetTicketPrice(); + //Negetive price to help identify tourist and resident. + if (isTourist) + { + if (MainDataStore.outsideTouristMoney > 0) + { + Singleton.instance.AddResource(EconomyManager.Resource.PublicIncome, -(int)ticketPrice, data.Info.m_class); + MainDataStore.outsideTouristMoney -= ticketPrice; + } + else + { + ticketPrice = 0; + } + } + else + { + if (CitizenData.citizenMoney[citizen] > ticketPrice) + { + CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - ticketPrice); + Singleton.instance.AddResource(EconomyManager.Resource.PublicIncome, (int)ticketPrice, data.Info.m_class); + } + } - DistrictPark[] park = instance2.m_parks.m_buffer; - park[b].m_tempTicketIncome = park[b].m_tempTicketIncome + (uint)(ticketPrice); - } - } + DistrictPark[] park = instance2.m_parks.m_buffer; + park[b].m_tempTicketIncome = park[b].m_tempTicketIncome + (uint)(ticketPrice); + } + } - public static bool IsRealUniqueBuilding(ushort buildingId) - { - if (buildingId == 0) - { - return false; - } + public static bool IsRealUniqueBuilding(ushort buildingId) + { + if (buildingId == 0) + { + return false; + } - var buildingInfo = BuildingManager.instance.m_buildings.m_buffer[buildingId].Info; - if (buildingInfo?.m_class?.m_service != ItemClass.Service.Monument) - { - return false; - } + var buildingInfo = BuildingManager.instance.m_buildings.m_buffer[buildingId].Info; + if (buildingInfo?.m_class?.m_service != ItemClass.Service.Monument) + { + return false; + } - var monumentAI = buildingInfo.m_buildingAI as MonumentAI; - return monumentAI != null - && (monumentAI.m_supportEvents & (EventManager.EventType.Football | EventManager.EventType.Concert)) == 0; - } - } + var monumentAI = buildingInfo.m_buildingAI as MonumentAI; + return monumentAI != null + && (monumentAI.m_supportEvents & (EventManager.EventType.Football | EventManager.EventType.Concert)) == 0; + } + } } diff --git a/Patch/CargoTruckAIArriveAtSourcePatch.cs b/Patch/CargoTruckAIArriveAtSourcePatch.cs index ecbe009..3d65c36 100644 --- a/Patch/CargoTruckAIArriveAtSourcePatch.cs +++ b/Patch/CargoTruckAIArriveAtSourcePatch.cs @@ -8,27 +8,27 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CargoTruckAIArriveAtSourcePatch - { - public static MethodBase TargetMethod() - { - return typeof(CargoTruckAI).GetMethod("ArriveAtSource", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType()}, null); - } - public static bool Prefix(ref Vehicle data) - { - if (data.m_sourceBuilding == 0) - { - return true; - } + [HarmonyPatch] + public class CargoTruckAIArriveAtSourcePatch + { + public static MethodBase TargetMethod() + { + return typeof(CargoTruckAI).GetMethod("ArriveAtSource", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType() }, null); + } + public static bool Prefix(ref Vehicle data) + { + if (data.m_sourceBuilding == 0) + { + return true; + } - if ((data.m_flags & Vehicle.Flags.TransferToTarget) != (Vehicle.Flags)0) - { - int transferSize = (int)data.m_transferSize; - BuildingInfo info = Singleton.instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].Info; - info.m_buildingAI.ModifyMaterialBuffer(data.m_sourceBuilding, ref Singleton.instance.m_buildings.m_buffer[(int)data.m_sourceBuilding], (TransferManager.TransferReason)data.m_transferType, ref transferSize); - } - return true; - } - } + if ((data.m_flags & Vehicle.Flags.TransferToTarget) != (Vehicle.Flags)0) + { + int transferSize = (int)data.m_transferSize; + BuildingInfo info = Singleton.instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].Info; + info.m_buildingAI.ModifyMaterialBuffer(data.m_sourceBuilding, ref Singleton.instance.m_buildings.m_buffer[(int)data.m_sourceBuilding], (TransferManager.TransferReason)data.m_transferType, ref transferSize); + } + return true; + } + } } diff --git a/Patch/CargoTruckAIArriveAtTargetPatch.cs b/Patch/CargoTruckAIArriveAtTargetPatch.cs index 0e40874..d15c0f6 100644 --- a/Patch/CargoTruckAIArriveAtTargetPatch.cs +++ b/Patch/CargoTruckAIArriveAtTargetPatch.cs @@ -3,69 +3,66 @@ using RealCity.CustomAI; using RealCity.Util; using System; -using System.Collections.Generic; -using System.Linq; using System.Reflection; -using System.Text; using UnityEngine; namespace RealCity.Patch { - [HarmonyPatch] - public static class CargoTruckAIArriveAtTargetPatch - { - public static MethodBase TargetMethod() - { - return typeof(CargoTruckAI).GetMethod("ArriveAtTarget", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType() }, null); - } - public static void Prefix(ref CargoTruckAI __instance, ref Vehicle data) - { - int transferSize = 0; - if ((data.m_flags & Vehicle.Flags.TransferToTarget) != 0) - { - transferSize = data.m_transferSize; - } - if ((data.m_flags & Vehicle.Flags.TransferToSource) != 0) - { - transferSize = Mathf.Min(0, data.m_transferSize - __instance.m_cargoCapacity); - } - // NON-STOCK CODE START - ProcessResourceArriveAtTarget(ref data, ref transferSize); - } - public static void ProcessResourceArriveAtTarget(ref Vehicle data, ref int transferSize) - { - BuildingManager instance = Singleton.instance; - BuildingInfo info = instance.m_buildings.m_buffer[data.m_targetBuilding].Info; - if ((data.m_flags & Vehicle.Flags.TransferToTarget) != 0) - { - if ((info.m_class.m_service == ItemClass.Service.Electricity) || (info.m_class.m_service == ItemClass.Service.Water) || (info.m_class.m_service == ItemClass.Service.Disaster)) - { - info.m_buildingAI.ModifyMaterialBuffer(data.m_targetBuilding, ref instance.m_buildings.m_buffer[data.m_targetBuilding], (TransferManager.TransferReason)data.m_transferType, ref transferSize); - float productValue; - switch ((TransferManager.TransferReason)data.m_transferType) - { - case TransferManager.TransferReason.Petrol: - productValue = transferSize * RealCityIndustryBuildingAI.GetResourcePrice((TransferManager.TransferReason)data.m_transferType); - Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOil, ItemClass.Level.Level1); - break; - case TransferManager.TransferReason.Coal: - productValue = transferSize * RealCityIndustryBuildingAI.GetResourcePrice((TransferManager.TransferReason)data.m_transferType); - Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOre, ItemClass.Level.Level1); - break; - case TransferManager.TransferReason.Goods: - productValue = transferSize * RealCityIndustryBuildingAI.GetResourcePrice((TransferManager.TransferReason)data.m_transferType); - Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.None, ItemClass.Level.Level1); - break; - case (TransferManager.TransferReason)124: - case (TransferManager.TransferReason)125: break; - default: DebugLog.LogToFileOnly("Error: ProcessResourceArriveAtTarget find unknow play building transition" + info.m_class.ToString() + "transfer reason " + data.m_transferType.ToString()); break; - } - if ((data.m_flags & Vehicle.Flags.TransferToTarget) != 0) - { - data.m_transferSize = (ushort)Mathf.Clamp(data.m_transferSize - transferSize, 0, data.m_transferSize); - } - } - } - } - } + [HarmonyPatch] + public static class CargoTruckAIArriveAtTargetPatch + { + public static MethodBase TargetMethod() + { + return typeof(CargoTruckAI).GetMethod("ArriveAtTarget", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType() }, null); + } + public static void Prefix(ref CargoTruckAI __instance, ref Vehicle data) + { + int transferSize = 0; + if ((data.m_flags & Vehicle.Flags.TransferToTarget) != 0) + { + transferSize = data.m_transferSize; + } + if ((data.m_flags & Vehicle.Flags.TransferToSource) != 0) + { + transferSize = Mathf.Min(0, data.m_transferSize - __instance.m_cargoCapacity); + } + // NON-STOCK CODE START + ProcessResourceArriveAtTarget(ref data, ref transferSize); + } + public static void ProcessResourceArriveAtTarget(ref Vehicle data, ref int transferSize) + { + BuildingManager instance = Singleton.instance; + BuildingInfo info = instance.m_buildings.m_buffer[data.m_targetBuilding].Info; + if ((data.m_flags & Vehicle.Flags.TransferToTarget) != 0) + { + if ((info.m_class.m_service == ItemClass.Service.Electricity) || (info.m_class.m_service == ItemClass.Service.Water) || (info.m_class.m_service == ItemClass.Service.Disaster)) + { + info.m_buildingAI.ModifyMaterialBuffer(data.m_targetBuilding, ref instance.m_buildings.m_buffer[data.m_targetBuilding], (TransferManager.TransferReason)data.m_transferType, ref transferSize); + float productValue; + switch ((TransferManager.TransferReason)data.m_transferType) + { + case TransferManager.TransferReason.Petrol: + productValue = transferSize * RealCityIndustryBuildingAI.GetResourcePrice((TransferManager.TransferReason)data.m_transferType); + Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOil, ItemClass.Level.Level1); + break; + case TransferManager.TransferReason.Coal: + productValue = transferSize * RealCityIndustryBuildingAI.GetResourcePrice((TransferManager.TransferReason)data.m_transferType); + Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOre, ItemClass.Level.Level1); + break; + case TransferManager.TransferReason.Goods: + productValue = transferSize * RealCityIndustryBuildingAI.GetResourcePrice((TransferManager.TransferReason)data.m_transferType); + Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.None, ItemClass.Level.Level1); + break; + case (TransferManager.TransferReason)124: + case (TransferManager.TransferReason)125: break; + default: DebugLog.LogToFileOnly("Error: ProcessResourceArriveAtTarget find unknow play building transition" + info.m_class.ToString() + "transfer reason " + data.m_transferType.ToString()); break; + } + if ((data.m_flags & Vehicle.Flags.TransferToTarget) != 0) + { + data.m_transferSize = (ushort)Mathf.Clamp(data.m_transferSize - transferSize, 0, data.m_transferSize); + } + } + } + } + } } diff --git a/Patch/CitizenManagerCreateCitizenInstancePatch.cs b/Patch/CitizenManagerCreateCitizenInstancePatch.cs index e846e18..e6cfd35 100644 --- a/Patch/CitizenManagerCreateCitizenInstancePatch.cs +++ b/Patch/CitizenManagerCreateCitizenInstancePatch.cs @@ -8,48 +8,58 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CitizenManagerCreateCitizenInstancePatch - { - public static MethodBase TargetMethod() - { - return typeof(CitizenManager).GetMethod("CreateCitizenInstance", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort).MakeByRefType(), typeof(Randomizer).MakeByRefType(), typeof(CitizenInfo), typeof(uint) }, null); - } - public static bool Prefix(ref CitizenManager __instance, uint citizen, ref bool __result) - { - var data = __instance.m_citizens.m_buffer[citizen]; + [HarmonyPatch] + public class CitizenManagerCreateCitizenInstancePatch + { + public static MethodBase TargetMethod() + { + return typeof(CitizenManager).GetMethod( + "CreateCitizenInstance", + BindingFlags.Public | BindingFlags.Instance, + null, + new Type[] { + typeof(ushort).MakeByRefType(), + typeof(Randomizer).MakeByRefType(), + typeof(CitizenInfo), + typeof(uint) + }, + null); + } + public static bool Prefix(ref CitizenManager __instance, uint citizen, ref bool __result) + { + var data = __instance.m_citizens.m_buffer[citizen]; - if (data.m_flags.IsFlagSet(Citizen.Flags.DummyTraffic)) - { - if (RealCity.realCityV10) - { - if (MainDataStore.outsideTouristMoney < 0) - { - __result = false; - return false; - } - } - } - else if (data.m_flags.IsFlagSet(Citizen.Flags.Tourist)) - { - if (data.m_flags.IsFlagSet(Citizen.Flags.MovingIn)) - { - //Add initial money - if (data.WealthLevel == Citizen.Wealth.Low) - { - CitizenData.citizenMoney[citizen] = 2048; - } - else if (data.WealthLevel == Citizen.Wealth.Medium) - { - CitizenData.citizenMoney[citizen] = 4096; - } - else - { - CitizenData.citizenMoney[citizen] = 8192; - } - } - } - return true; - } - } + if (data.m_flags.IsFlagSet(Citizen.Flags.DummyTraffic)) + { + if (RealCity.realCityV10) + { + if (MainDataStore.outsideTouristMoney < 0) + { + __result = false; + return false; + } + } + } + else if (data.m_flags.IsFlagSet(Citizen.Flags.Tourist)) + { + if (data.m_flags.IsFlagSet(Citizen.Flags.MovingIn)) + { + //Add initial money + if (data.WealthLevel == Citizen.Wealth.Low) + { + CitizenData.citizenMoney[citizen] = 2048; + } + else if (data.WealthLevel == Citizen.Wealth.Medium) + { + CitizenData.citizenMoney[citizen] = 4096; + } + else + { + CitizenData.citizenMoney[citizen] = 8192; + } + } + } + return true; + } + } } diff --git a/Patch/CitizenManagerReleaseCitizenImplementationPatch.cs b/Patch/CitizenManagerReleaseCitizenImplementationPatch.cs index 6e49a61..6be0cb7 100644 --- a/Patch/CitizenManagerReleaseCitizenImplementationPatch.cs +++ b/Patch/CitizenManagerReleaseCitizenImplementationPatch.cs @@ -5,16 +5,16 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CitizenManagerReleaseCitizenImplementationPatch - { - public static MethodBase TargetMethod() - { - return typeof(CitizenManager).GetMethod("ReleaseCitizenImplementation", BindingFlags.NonPublic | BindingFlags.Instance); - } - public static void Postfix(uint citizen) - { - CitizenData.citizenMoney[citizen] = 0; - } - } + [HarmonyPatch] + public class CitizenManagerReleaseCitizenImplementationPatch + { + public static MethodBase TargetMethod() + { + return typeof(CitizenManager).GetMethod("ReleaseCitizenImplementation", BindingFlags.NonPublic | BindingFlags.Instance); + } + public static void Postfix(uint citizen) + { + CitizenData.citizenMoney[citizen] = 0; + } + } } diff --git a/Patch/CitizenManagerReleaseUnitCitizenPatch.cs b/Patch/CitizenManagerReleaseUnitCitizenPatch.cs index 83f5e49..21fc5f4 100644 --- a/Patch/CitizenManagerReleaseUnitCitizenPatch.cs +++ b/Patch/CitizenManagerReleaseUnitCitizenPatch.cs @@ -4,18 +4,18 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CitizenManagerReleaseUnitCitizenPatch - { - public static MethodBase TargetMethod() - { - return typeof(CitizenManager).GetMethod("ReleaseUnitCitizen", BindingFlags.NonPublic | BindingFlags.Instance); - } - public static void Postfix(uint unit) - { - CitizenUnitData.familyMoney[unit] = 0; - //65535 stand for uninitial money - CitizenUnitData.familyGoods[unit] = 65535; - } - } + [HarmonyPatch] + public class CitizenManagerReleaseUnitCitizenPatch + { + public static MethodBase TargetMethod() + { + return typeof(CitizenManager).GetMethod("ReleaseUnitCitizen", BindingFlags.NonPublic | BindingFlags.Instance); + } + public static void Postfix(uint unit) + { + CitizenUnitData.familyMoney[unit] = 0; + //65535 stand for uninitial money + CitizenUnitData.familyGoods[unit] = 65535; + } + } } diff --git a/Patch/CommercialBuildingAICreateBuildingPatch.cs b/Patch/CommercialBuildingAICreateBuildingPatch.cs index 6e57435..f51e671 100644 --- a/Patch/CommercialBuildingAICreateBuildingPatch.cs +++ b/Patch/CommercialBuildingAICreateBuildingPatch.cs @@ -7,18 +7,18 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CommercialBuildingAICreateBuildingPatch - { - public static MethodBase TargetMethod() - { - return typeof(CommercialBuildingAI).GetMethod("CreateBuilding", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType() }, null); - } - public static void Postfix(ushort buildingID, ref Building data) - { - var material = TransferManager.TransferReason.Goods; - float initialMaterialFee = data.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(material) + 10000; - BuildingData.buildingMoney[buildingID] = -initialMaterialFee; - } - } + [HarmonyPatch] + public class CommercialBuildingAICreateBuildingPatch + { + public static MethodBase TargetMethod() + { + return typeof(CommercialBuildingAI).GetMethod("CreateBuilding", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType() }, null); + } + public static void Postfix(ushort buildingID, ref Building data) + { + var material = TransferManager.TransferReason.Goods; + float initialMaterialFee = data.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(material) + 10000; + BuildingData.buildingMoney[buildingID] = -initialMaterialFee; + } + } } diff --git a/Patch/CommercialBuildingAIModifyMaterialBufferPatch.cs b/Patch/CommercialBuildingAIModifyMaterialBufferPatch.cs index 87781d0..60bdf80 100644 --- a/Patch/CommercialBuildingAIModifyMaterialBufferPatch.cs +++ b/Patch/CommercialBuildingAIModifyMaterialBufferPatch.cs @@ -8,87 +8,87 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CommercialBuildingAIModifyMaterialBufferPatch - { - public static MethodBase TargetMethod() - { - return typeof(CommercialBuildingAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); - } + [HarmonyPatch] + public class CommercialBuildingAIModifyMaterialBufferPatch + { + public static MethodBase TargetMethod() + { + return typeof(CommercialBuildingAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); + } - public static bool Prefix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - if (material == TransferManager.TransferReason.Entertainment) - { - CaculateTradeIncome(buildingID, ref data, material, ref amountDelta); - } - else - { - switch (material) - { - case TransferManager.TransferReason.Shopping: - case TransferManager.TransferReason.ShoppingB: - case TransferManager.TransferReason.ShoppingC: - case TransferManager.TransferReason.ShoppingD: - case TransferManager.TransferReason.ShoppingE: - case TransferManager.TransferReason.ShoppingF: - case TransferManager.TransferReason.ShoppingG: - case TransferManager.TransferReason.ShoppingH: - if (amountDelta == -100) - { - // Disable other - 100 ModifyMaterialBuffer - return false; - } - break; - } - } - return true; - } + public static bool Prefix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + if (material == TransferManager.TransferReason.Entertainment) + { + CaculateTradeIncome(buildingID, ref data, material, ref amountDelta); + } + else + { + switch (material) + { + case TransferManager.TransferReason.Shopping: + case TransferManager.TransferReason.ShoppingB: + case TransferManager.TransferReason.ShoppingC: + case TransferManager.TransferReason.ShoppingD: + case TransferManager.TransferReason.ShoppingE: + case TransferManager.TransferReason.ShoppingF: + case TransferManager.TransferReason.ShoppingG: + case TransferManager.TransferReason.ShoppingH: + if (amountDelta == -100) + { + // Disable other - 100 ModifyMaterialBuffer + return false; + } + break; + } + } + return true; + } - public static void Postfix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - switch (material) - { - case TransferManager.TransferReason.ShoppingB: - case TransferManager.TransferReason.ShoppingC: - case TransferManager.TransferReason.ShoppingD: - case TransferManager.TransferReason.ShoppingE: - case TransferManager.TransferReason.ShoppingF: - case TransferManager.TransferReason.ShoppingG: - case TransferManager.TransferReason.ShoppingH: - break; - default: - if (material != TransferManager.TransferReason.Shopping) - { - if (material == TransferManager.TransferReason.Goods || material == TransferManager.TransferReason.Petrol || material == TransferManager.TransferReason.Food || material == TransferManager.TransferReason.LuxuryProducts) - { - ProcessIncoming(buildingID, ref data, material, ref amountDelta); - } - return; - } - break; - } - CaculateTradeIncome(buildingID, ref data, material, ref amountDelta); - } + public static void Postfix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + switch (material) + { + case TransferManager.TransferReason.ShoppingB: + case TransferManager.TransferReason.ShoppingC: + case TransferManager.TransferReason.ShoppingD: + case TransferManager.TransferReason.ShoppingE: + case TransferManager.TransferReason.ShoppingF: + case TransferManager.TransferReason.ShoppingG: + case TransferManager.TransferReason.ShoppingH: + break; + default: + if (material != TransferManager.TransferReason.Shopping) + { + if (material == TransferManager.TransferReason.Goods || material == TransferManager.TransferReason.Petrol || material == TransferManager.TransferReason.Food || material == TransferManager.TransferReason.LuxuryProducts) + { + ProcessIncoming(buildingID, ref data, material, ref amountDelta); + } + return; + } + break; + } + CaculateTradeIncome(buildingID, ref data, material, ref amountDelta); + } - public static void ProcessIncoming(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - if (amountDelta > 0) - { - float tradeIncome1 = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - BuildingData.buildingMoney[buildingID] = BuildingData.buildingMoney[buildingID] - tradeIncome1; - } - } + public static void ProcessIncoming(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + if (amountDelta > 0) + { + float tradeIncome1 = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + BuildingData.buildingMoney[buildingID] = BuildingData.buildingMoney[buildingID] - tradeIncome1; + } + } - public static void CaculateTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - if (amountDelta < 0) - { - float tradeIncome = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; - Singleton.instance.AddPrivateIncome((int)tradeTax, ItemClass.Service.Commercial, data.Info.m_class.m_subService, data.Info.m_class.m_level, 111333); - BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (tradeIncome + tradeTax)); - } - } - } + public static void CaculateTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + if (amountDelta < 0) + { + float tradeIncome = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; + Singleton.instance.AddPrivateIncome((int)tradeTax, ItemClass.Service.Commercial, data.Info.m_class.m_subService, data.Info.m_class.m_level, 111333); + BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (tradeIncome + tradeTax)); + } + } + } } diff --git a/Patch/CommercialBuildingAISimulationStepActivePatch.cs b/Patch/CommercialBuildingAISimulationStepActivePatch.cs index e1b2bdf..bf93a4e 100644 --- a/Patch/CommercialBuildingAISimulationStepActivePatch.cs +++ b/Patch/CommercialBuildingAISimulationStepActivePatch.cs @@ -10,24 +10,24 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CommercialBuildingAISimulationStepActivePatch - { - public static MethodBase TargetMethod() - { - return typeof(CommercialBuildingAI).GetMethod("SimulationStepActive", BindingFlags.NonPublic | BindingFlags.Instance); - } + [HarmonyPatch] + public class CommercialBuildingAISimulationStepActivePatch + { + public static MethodBase TargetMethod() + { + return typeof(CommercialBuildingAI).GetMethod("SimulationStepActive", BindingFlags.NonPublic | BindingFlags.Instance); + } - public static void Prefix(ref Building buildingData, ref ushort[] __state) - { - __state = new ushort[2]; - __state[0] = buildingData.m_customBuffer1; - __state[1] = buildingData.m_customBuffer2; - } + public static void Prefix(ref Building buildingData, ref ushort[] __state) + { + __state = new ushort[2]; + __state[0] = buildingData.m_customBuffer1; + __state[1] = buildingData.m_customBuffer2; + } - public static void Postfix(ushort buildingID, ref Building buildingData, ref ushort[] __state) - { - RealCityPrivateBuildingAI.ProcessAdditionProduct(buildingID, ref buildingData, ref __state, false); - } - } + public static void Postfix(ushort buildingID, ref Building buildingData, ref ushort[] __state) + { + RealCityPrivateBuildingAI.ProcessAdditionProduct(buildingID, ref buildingData, ref __state, false); + } + } } diff --git a/Patch/CommercialBuildingAIVisitorEnterPatch.cs b/Patch/CommercialBuildingAIVisitorEnterPatch.cs index 19e9662..6bf12e6 100644 --- a/Patch/CommercialBuildingAIVisitorEnterPatch.cs +++ b/Patch/CommercialBuildingAIVisitorEnterPatch.cs @@ -8,114 +8,114 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CommercialBuildingAIVisitorEnterPatch - { - public static MethodBase TargetMethod() - { - return typeof(CommercialBuildingAI).GetMethod("VisitorEnter", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(uint) }, null); - } - public static bool Prefix(ushort buildingID, ref Building data, uint citizen) - { - CitizenManager citizenManager = Singleton.instance; - BuildingInfo buildingInfo = data.Info; - if ((citizenManager.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) - { - int consumptionMoney = MainDataStore.govermentSalary << 4; - if (citizenManager.m_citizens.m_buffer[citizen].WealthLevel == Citizen.Wealth.High) - { - consumptionMoney <<= 2; - } - if (citizenManager.m_citizens.m_buffer[citizen].WealthLevel == Citizen.Wealth.Medium) - { - consumptionMoney <<= 1; - } + [HarmonyPatch] + public class CommercialBuildingAIVisitorEnterPatch + { + public static MethodBase TargetMethod() + { + return typeof(CommercialBuildingAI).GetMethod("VisitorEnter", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(uint) }, null); + } + public static bool Prefix(ushort buildingID, ref Building data, uint citizen) + { + CitizenManager citizenManager = Singleton.instance; + BuildingInfo buildingInfo = data.Info; + if ((citizenManager.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) + { + int consumptionMoney = MainDataStore.govermentSalary << 4; + if (citizenManager.m_citizens.m_buffer[citizen].WealthLevel == Citizen.Wealth.High) + { + consumptionMoney <<= 2; + } + if (citizenManager.m_citizens.m_buffer[citizen].WealthLevel == Citizen.Wealth.Medium) + { + consumptionMoney <<= 1; + } - consumptionMoney = -consumptionMoney; - if (MainDataStore.outsideTouristMoney > 0) - { - buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Entertainment, ref consumptionMoney); - MainDataStore.outsideTouristMoney += (consumptionMoney); - } - consumptionMoney = -MainDataStore.maxGoodPurchase; - buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Shopping, ref consumptionMoney); - int priceInt = 0; - IndustryBuildingGetResourcePricePatch.Prefix(ref priceInt, TransferManager.TransferReason.Shopping, data.Info.m_class.m_service); - var m_goodsSellPrice = priceInt / 100; - MainDataStore.outsideTouristMoney += (consumptionMoney * m_goodsSellPrice); - } - else - { - ushort homeBuilding = citizenManager.m_citizens.m_buffer[citizen].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = citizenManager.m_citizens.m_buffer[citizen].GetContainingUnit((uint)citizen, citizenUnit, CitizenUnit.Flags.Home); + consumptionMoney = -consumptionMoney; + if (MainDataStore.outsideTouristMoney > 0) + { + buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Entertainment, ref consumptionMoney); + MainDataStore.outsideTouristMoney += (consumptionMoney); + } + consumptionMoney = -MainDataStore.maxGoodPurchase; + buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Shopping, ref consumptionMoney); + int priceInt = 0; + IndustryBuildingGetResourcePricePatch.Prefix(ref priceInt, TransferManager.TransferReason.Shopping, data.Info.m_class.m_service); + var m_goodsSellPrice = priceInt / 100; + MainDataStore.outsideTouristMoney += (consumptionMoney * m_goodsSellPrice); + } + else + { + ushort homeBuilding = citizenManager.m_citizens.m_buffer[citizen].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = citizenManager.m_citizens.m_buffer[citizen].GetContainingUnit((uint)citizen, citizenUnit, CitizenUnit.Flags.Home); - if (containingUnit != 0) - { - //int goodAmount = (int)(-(CitizenUnitData.familyMoney[containingUnit]) / RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)); - int goodAmount = -MainDataStore.maxGoodPurchase; + if (containingUnit != 0) + { + //int goodAmount = (int)(-(CitizenUnitData.familyMoney[containingUnit]) / RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)); + int goodAmount = -MainDataStore.maxGoodPurchase; - if (goodAmount < 0) - { - buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Shopping, ref goodAmount); + if (goodAmount < 0) + { + buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Shopping, ref goodAmount); - if (goodAmount != 0) - { - CitizenUnitData.familyGoods[containingUnit] = (ushort)(CitizenUnitData.familyGoods[containingUnit] - (goodAmount * 10)); - if (CitizenUnitData.familyGoods[containingUnit] > 2000) - { - citizenManager.m_citizens.m_buffer[citizen].m_flags &= ~Citizen.Flags.NeedGoods; - } - } - } - else - { - goodAmount = 0; - } + if (goodAmount != 0) + { + CitizenUnitData.familyGoods[containingUnit] = (ushort)(CitizenUnitData.familyGoods[containingUnit] - (goodAmount * 10)); + if (CitizenUnitData.familyGoods[containingUnit] > 2000) + { + citizenManager.m_citizens.m_buffer[citizen].m_flags &= ~Citizen.Flags.NeedGoods; + } + } + } + else + { + goodAmount = 0; + } - var familyMoney = (CitizenUnitData.familyMoney[containingUnit] + goodAmount * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)); + var familyMoney = (CitizenUnitData.familyMoney[containingUnit] + goodAmount * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)); - float consumptionIndex; - if (buildingInfo.m_class.m_subService == ItemClass.SubService.CommercialLeisure) - { - consumptionIndex = 0.25f; - } - else if ((buildingInfo.m_class.m_subService == ItemClass.SubService.CommercialTourist)) - { - consumptionIndex = 0.2f; - } - else if ((buildingInfo.m_class.m_subService == ItemClass.SubService.CommercialEco)) - { - consumptionIndex = 0.05f; - } - else if ((buildingInfo.m_class.m_subService == ItemClass.SubService.CommercialHigh)) - { - consumptionIndex = 0.15f; - } - else - { - consumptionIndex = 0.1f; - } + float consumptionIndex; + if (buildingInfo.m_class.m_subService == ItemClass.SubService.CommercialLeisure) + { + consumptionIndex = 0.25f; + } + else if ((buildingInfo.m_class.m_subService == ItemClass.SubService.CommercialTourist)) + { + consumptionIndex = 0.2f; + } + else if ((buildingInfo.m_class.m_subService == ItemClass.SubService.CommercialEco)) + { + consumptionIndex = 0.05f; + } + else if ((buildingInfo.m_class.m_subService == ItemClass.SubService.CommercialHigh)) + { + consumptionIndex = 0.15f; + } + else + { + consumptionIndex = 0.1f; + } - int consumptionMoney = -(int)(consumptionIndex * familyMoney); + int consumptionMoney = -(int)(consumptionIndex * familyMoney); - if (consumptionMoney < 0) - { - int money = consumptionMoney; - buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Entertainment, ref money); - } - else - { - consumptionMoney = 0; - } + if (consumptionMoney < 0) + { + int money = consumptionMoney; + buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Entertainment, ref money); + } + else + { + consumptionMoney = 0; + } - CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] + consumptionMoney + goodAmount * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)); - CitizenUnitData.familyMoney[containingUnit] = CitizenUnitData.familyMoney[containingUnit] + consumptionMoney + goodAmount * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping); - } - } + CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] + consumptionMoney + goodAmount * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)); + CitizenUnitData.familyMoney[containingUnit] = CitizenUnitData.familyMoney[containingUnit] + consumptionMoney + goodAmount * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping); + } + } - Singleton.instance.VisitorEnter(buildingID, ref data, citizen); - return false; - } - } + Singleton.instance.VisitorEnter(buildingID, ref data, citizen); + return false; + } + } } diff --git a/Patch/CommonBuildingAIGetColorPatch.cs b/Patch/CommonBuildingAIGetColorPatch.cs index d71c158..2bf56a4 100644 --- a/Patch/CommonBuildingAIGetColorPatch.cs +++ b/Patch/CommonBuildingAIGetColorPatch.cs @@ -7,38 +7,38 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CommonBuildingAIGetColorPatch - { - public static MethodBase TargetMethod() - { - return typeof(CommonBuildingAI).GetMethod( - "GetColor", - BindingFlags.Instance | BindingFlags.Public, - null, - new[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(InfoManager.InfoMode) }, - new ParameterModifier[0]); - } + [HarmonyPatch] + public class CommonBuildingAIGetColorPatch + { + public static MethodBase TargetMethod() + { + return typeof(CommonBuildingAI).GetMethod( + "GetColor", + BindingFlags.Instance | BindingFlags.Public, + null, + new[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(InfoManager.InfoMode) }, + new ParameterModifier[0]); + } - public static void Postfix(ushort buildingID, ref Building data, InfoManager.InfoMode infoMode, ref Color __result) - { - if (infoMode == InfoManager.InfoMode.LandValue) - { - ItemClass @class = data.Info.m_class; - ItemClass.Service service = @class.m_service; - switch (service) - { - case ItemClass.Service.Residential: - case ItemClass.Service.Office: - case ItemClass.Service.Industrial: - case ItemClass.Service.Commercial: - if (BuildingData.buildingMoneyThreat[buildingID] < 0.5f) - __result = Color.Lerp(Color.green, Color.yellow, BuildingData.buildingMoneyThreat[buildingID] * 2.0f); - else - __result = Color.Lerp(Color.yellow, Color.red, (BuildingData.buildingMoneyThreat[buildingID] - 0.5f) * 2.0f); - break; - } - } - } - } + public static void Postfix(ushort buildingID, ref Building data, InfoManager.InfoMode infoMode, ref Color __result) + { + if (infoMode == InfoManager.InfoMode.LandValue) + { + ItemClass @class = data.Info.m_class; + ItemClass.Service service = @class.m_service; + switch (service) + { + case ItemClass.Service.Residential: + case ItemClass.Service.Office: + case ItemClass.Service.Industrial: + case ItemClass.Service.Commercial: + if (BuildingData.buildingMoneyThreat[buildingID] < 0.5f) + __result = Color.Lerp(Color.green, Color.yellow, BuildingData.buildingMoneyThreat[buildingID] * 2.0f); + else + __result = Color.Lerp(Color.yellow, Color.red, (BuildingData.buildingMoneyThreat[buildingID] - 0.5f) * 2.0f); + break; + } + } + } + } } diff --git a/Patch/CommonBuildingAIReleaseBuildingPatch.cs b/Patch/CommonBuildingAIReleaseBuildingPatch.cs index 1c3bfda..61e3d02 100644 --- a/Patch/CommonBuildingAIReleaseBuildingPatch.cs +++ b/Patch/CommonBuildingAIReleaseBuildingPatch.cs @@ -4,19 +4,19 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class CommonBuildingAIReleaseBuildingPatch - { - public static MethodBase TargetMethod() - { - return typeof(CommonBuildingAI).GetMethod("ReleaseBuilding"); - } - public static void Postfix(ushort buildingID) - { - BuildingData.buildingMoney[buildingID] = 0; - BuildingData.buildingWorkCount[buildingID] = 0; - BuildingData.isBuildingWorkerUpdated[buildingID] = false; - BuildingData.buildingMoneyThreat[buildingID] = 1f; - } - } + [HarmonyPatch] + public class CommonBuildingAIReleaseBuildingPatch + { + public static MethodBase TargetMethod() + { + return typeof(CommonBuildingAI).GetMethod("ReleaseBuilding"); + } + public static void Postfix(ushort buildingID) + { + BuildingData.buildingMoney[buildingID] = 0; + BuildingData.buildingWorkCount[buildingID] = 0; + BuildingData.isBuildingWorkerUpdated[buildingID] = false; + BuildingData.buildingMoneyThreat[buildingID] = 1f; + } + } } diff --git a/Patch/EconomyManagerAddPrivateIncomePatch.cs b/Patch/EconomyManagerAddPrivateIncomePatch.cs index 000078a..66c9d16 100644 --- a/Patch/EconomyManagerAddPrivateIncomePatch.cs +++ b/Patch/EconomyManagerAddPrivateIncomePatch.cs @@ -6,310 +6,311 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class EconomyManagerAddPrivateIncomePatch - { - - public static float citizenIncome = 0f; - public static float touristIncome = 0f; - public static float residentTaxIncome = 0f; - public static float commercialLowIncome = 0f; - public static float commercialHighIncome = 0f; - public static float commercialLeiIncome = 0f; - public static float commercialLTouIncome = 0f; - public static float commercialLEcoIncome = 0f; - public static float industyForestIncome = 0f; - public static float industyFarmIncome = 0f; - public static float industyOilIncome = 0f; - public static float industyOreIncome = 0f; - public static float industyGenIncome = 0f; - public static float officeGenIncome = 0f; - public static float officeHighTechIncome = 0f; - public static float residentLowIncome = 0f; - public static float residentLowEcoIncome = 0f; - public static float residentHighIncome = 0f; - public static float residentHighEcoIncome = 0f; - public static float commercialLowTradeIncome = 0f; - public static float commercialHighTradeIncome = 0f; - public static float commercialLeiTradeIncome = 0f; - public static float commercialTouTradeIncome = 0f; - public static float commercialEcoTradeIncome = 0f; - public static float industyForestTradeIncome = 0f; - public static float industyFarmTradeIncome = 0f; - public static float industyOilTradeIncome = 0f; - public static float industyOreTradeIncome = 0f; - public static float industyGenTradeIncome = 0f; - public static float garbageIncome = 0f; - public static float roadIncome = 0f; - public static float playerIndustryIncome = 0f; - public static float schoolIncome = 0f; - public static float policeStationIncome = 0f; - public static float healthCareIncome = 0f; - public static float fireStationIncome = 0f; + [HarmonyPatch] + public class EconomyManagerAddPrivateIncomePatch + { - public static MethodBase TargetMethod() - { - return typeof(EconomyManager).GetMethod("AddPrivateIncome", BindingFlags.Public | BindingFlags.Instance); - } + public static float citizenIncome = 0f; + public static float touristIncome = 0f; + public static float residentTaxIncome = 0f; + public static float commercialLowIncome = 0f; + public static float commercialHighIncome = 0f; + public static float commercialLeiIncome = 0f; + public static float commercialLTouIncome = 0f; + public static float commercialLEcoIncome = 0f; + public static float industyForestIncome = 0f; + public static float industyFarmIncome = 0f; + public static float industyOilIncome = 0f; + public static float industyOreIncome = 0f; + public static float industyGenIncome = 0f; + public static float officeGenIncome = 0f; + public static float officeHighTechIncome = 0f; + public static float residentLowIncome = 0f; + public static float residentLowEcoIncome = 0f; + public static float residentHighIncome = 0f; + public static float residentHighEcoIncome = 0f; + public static float commercialLowTradeIncome = 0f; + public static float commercialHighTradeIncome = 0f; + public static float commercialLeiTradeIncome = 0f; + public static float commercialTouTradeIncome = 0f; + public static float commercialEcoTradeIncome = 0f; + public static float industyForestTradeIncome = 0f; + public static float industyFarmTradeIncome = 0f; + public static float industyOilTradeIncome = 0f; + public static float industyOreTradeIncome = 0f; + public static float industyGenTradeIncome = 0f; + public static float garbageIncome = 0f; + public static float roadIncome = 0f; + public static float playerIndustryIncome = 0f; + public static float schoolIncome = 0f; + public static float policeStationIncome = 0f; + public static float healthCareIncome = 0f; + public static float fireStationIncome = 0f; - public static void CustomAddGovermentIncome(ref int amount, ItemClass.Service service) - { - switch (service) - { - case ItemClass.Service.Garbage: - ProcessUnitTax100(ref amount, ref garbageIncome); - RealCityEconomyManager.garbageIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.Service.Education: - ProcessUnitTax100(ref amount, ref schoolIncome); - RealCityEconomyManager.schoolIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.Service.HealthCare: - ProcessUnitTax100(ref amount, ref healthCareIncome); - RealCityEconomyManager.healthCareIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.Service.FireDepartment: - ProcessUnitTax100(ref amount, ref fireStationIncome); - RealCityEconomyManager.fireStationIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.Service.PoliceDepartment: - ProcessUnitTax100(ref amount, ref policeStationIncome); - RealCityEconomyManager.policeStationIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - default: - amount = 0; - DebugLog.LogToFileOnly("Error: Find unknown EXAddGovermentIncome building" + " service is" + service.ToString()); - break; - } - } + public static MethodBase TargetMethod() + { + return typeof(EconomyManager).GetMethod("AddPrivateIncome", BindingFlags.Public | BindingFlags.Instance); + } - public static void CustomAddPersonalTaxIncome(ref int amount, ItemClass.Service service) - { - switch (service) - { - case ItemClass.Service.Residential: - ProcessUnitTax100(ref amount, ref residentTaxIncome); - break; - default: - DebugLog.LogToFileOnly("Find unknown EXAddPrivateLandIncome building" + " building service is" + service); - break; - } - RealCityEconomyManager.citizenTaxIncomeForUI[MainDataStore.updateMoneyCount] = RealCityEconomyManager.citizenTaxIncomeForUI[MainDataStore.updateMoneyCount] + amount; - } + public static void CustomAddGovermentIncome(ref int amount, ItemClass.Service service) + { + switch (service) + { + case ItemClass.Service.Garbage: + ProcessUnitTax100(ref amount, ref garbageIncome); + RealCityEconomyManager.garbageIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.Service.Education: + ProcessUnitTax100(ref amount, ref schoolIncome); + RealCityEconomyManager.schoolIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.Service.HealthCare: + ProcessUnitTax100(ref amount, ref healthCareIncome); + RealCityEconomyManager.healthCareIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.Service.FireDepartment: + ProcessUnitTax100(ref amount, ref fireStationIncome); + RealCityEconomyManager.fireStationIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.Service.PoliceDepartment: + ProcessUnitTax100(ref amount, ref policeStationIncome); + RealCityEconomyManager.policeStationIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + default: + amount = 0; + DebugLog.LogToFileOnly("Error: Find unknown EXAddGovermentIncome building" + " service is" + service.ToString()); + break; + } + } - public static void CustomAddTourismIncome(ref int amount, int taxRate) - { - if (taxRate == 114333) - { - ProcessUnitTax100(ref amount, ref citizenIncome); - RealCityEconomyManager.citizenIncomeForUI[MainDataStore.updateMoneyCount] += amount; - } - else - { - ProcessUnitTax100(ref amount, ref touristIncome); - RealCityEconomyManager.touristIncomeForUI[MainDataStore.updateMoneyCount] += amount; - } - } + public static void CustomAddPersonalTaxIncome(ref int amount, ItemClass.Service service) + { + switch (service) + { + case ItemClass.Service.Residential: + ProcessUnitTax100(ref amount, ref residentTaxIncome); + break; + default: + DebugLog.LogToFileOnly("Find unknown EXAddPrivateLandIncome building" + " building service is" + service); + break; + } + RealCityEconomyManager.citizenTaxIncomeForUI[MainDataStore.updateMoneyCount] + = RealCityEconomyManager.citizenTaxIncomeForUI[MainDataStore.updateMoneyCount] + amount; + } - public static void CustomAddPrivateTradeIncome(ref int amount, ItemClass.SubService subService) - { - switch (subService) - { - case ItemClass.SubService.IndustrialFarming: - ProcessUnitTax100(ref amount, ref industyFarmTradeIncome); - RealCityEconomyManager.induFarmerTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.IndustrialForestry: - ProcessUnitTax100(ref amount, ref industyForestTradeIncome); - RealCityEconomyManager.induForestyTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.IndustrialOil: - ProcessUnitTax100(ref amount, ref industyOilTradeIncome); - RealCityEconomyManager.induOilTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.IndustrialOre: - ProcessUnitTax100(ref amount, ref industyOreTradeIncome); - RealCityEconomyManager.induOreTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.IndustrialGeneric: - ProcessUnitTax100(ref amount, ref industyGenTradeIncome); - RealCityEconomyManager.induGenTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialHigh: - ProcessUnitTax100(ref amount, ref commercialHighTradeIncome); - RealCityEconomyManager.commHighTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialLow: - ProcessUnitTax100(ref amount, ref commercialLowTradeIncome); - RealCityEconomyManager.commLowTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialLeisure: - ProcessUnitTax100(ref amount, ref commercialLeiTradeIncome); - RealCityEconomyManager.commLeiTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialTourist: - ProcessUnitTax100(ref amount, ref commercialTouTradeIncome); - RealCityEconomyManager.commTouTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialEco: - ProcessUnitTax100(ref amount, ref commercialEcoTradeIncome); - RealCityEconomyManager.commEcoTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - default: - amount = 0; - DebugLog.LogToFileOnly("Find unknown EXAddPrivateTradeIncome building" + " building subservise is" + subService); - break; - } - } + public static void CustomAddTourismIncome(ref int amount, int taxRate) + { + if (taxRate == 114333) + { + ProcessUnitTax100(ref amount, ref citizenIncome); + RealCityEconomyManager.citizenIncomeForUI[MainDataStore.updateMoneyCount] += amount; + } + else + { + ProcessUnitTax100(ref amount, ref touristIncome); + RealCityEconomyManager.touristIncomeForUI[MainDataStore.updateMoneyCount] += amount; + } + } - public static void CustomAddPrivateLandIncome(ref int amount, ItemClass.SubService subService, int taxRate) - { - switch (subService) - { - case ItemClass.SubService.IndustrialFarming: - ProcessUnit(ref amount, ref industyFarmIncome, taxRate); - RealCityEconomyManager.induFarmerLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.IndustrialForestry: - ProcessUnit(ref amount, ref industyForestIncome, taxRate); - RealCityEconomyManager.induForestyLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.IndustrialOil: - ProcessUnit(ref amount, ref industyOilIncome, taxRate); - RealCityEconomyManager.induOilLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.IndustrialOre: - ProcessUnit(ref amount, ref industyOreIncome, taxRate); - RealCityEconomyManager.induOreLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.IndustrialGeneric: - ProcessUnit(ref amount, ref industyGenIncome, taxRate); - RealCityEconomyManager.induGenLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialHigh: - ProcessUnit(ref amount, ref commercialHighIncome, taxRate); - RealCityEconomyManager.commHighLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialLow: - ProcessUnit(ref amount, ref commercialLowIncome, taxRate); - RealCityEconomyManager.commLowLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialLeisure: - ProcessUnit(ref amount, ref commercialLeiIncome, taxRate); - RealCityEconomyManager.commLeiLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialTourist: - ProcessUnit(ref amount, ref commercialLTouIncome, taxRate); - RealCityEconomyManager.commTouLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.CommercialEco: - ProcessUnit(ref amount, ref commercialLEcoIncome, taxRate); - RealCityEconomyManager.commEcoLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.ResidentialHigh: - ProcessUnit(ref amount, ref residentHighIncome, taxRate); - RealCityEconomyManager.residentHighLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.ResidentialLow: - ProcessUnit(ref amount, ref residentLowIncome, taxRate); - RealCityEconomyManager.residentLowLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.ResidentialHighEco: - ProcessUnit(ref amount, ref residentHighEcoIncome, taxRate); - RealCityEconomyManager.residentHighEcoLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.ResidentialLowEco: - ProcessUnit(ref amount, ref residentLowEcoIncome, taxRate); - RealCityEconomyManager.residentLowEcoLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.OfficeGeneric: - ProcessUnit(ref amount, ref officeGenIncome, taxRate); - RealCityEconomyManager.officeGenLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - case ItemClass.SubService.OfficeHightech: - ProcessUnit(ref amount, ref officeHighTechIncome, taxRate); - RealCityEconomyManager.officeHighTechLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; - break; - default: - amount = 0; - DebugLog.LogToFileOnly("find unknown EXAddPrivateLandIncome building" + " building subService is" + subService + " buildlevelandtax is " + taxRate); - break; - } - } + public static void CustomAddPrivateTradeIncome(ref int amount, ItemClass.SubService subService) + { + switch (subService) + { + case ItemClass.SubService.IndustrialFarming: + ProcessUnitTax100(ref amount, ref industyFarmTradeIncome); + RealCityEconomyManager.induFarmerTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.IndustrialForestry: + ProcessUnitTax100(ref amount, ref industyForestTradeIncome); + RealCityEconomyManager.induForestyTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.IndustrialOil: + ProcessUnitTax100(ref amount, ref industyOilTradeIncome); + RealCityEconomyManager.induOilTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.IndustrialOre: + ProcessUnitTax100(ref amount, ref industyOreTradeIncome); + RealCityEconomyManager.induOreTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.IndustrialGeneric: + ProcessUnitTax100(ref amount, ref industyGenTradeIncome); + RealCityEconomyManager.induGenTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialHigh: + ProcessUnitTax100(ref amount, ref commercialHighTradeIncome); + RealCityEconomyManager.commHighTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialLow: + ProcessUnitTax100(ref amount, ref commercialLowTradeIncome); + RealCityEconomyManager.commLowTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialLeisure: + ProcessUnitTax100(ref amount, ref commercialLeiTradeIncome); + RealCityEconomyManager.commLeiTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialTourist: + ProcessUnitTax100(ref amount, ref commercialTouTradeIncome); + RealCityEconomyManager.commTouTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialEco: + ProcessUnitTax100(ref amount, ref commercialEcoTradeIncome); + RealCityEconomyManager.commEcoTradeIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + default: + amount = 0; + DebugLog.LogToFileOnly("Find unknown EXAddPrivateTradeIncome building" + " building subservise is" + subService); + break; + } + } - public static void ProcessUnit(ref int amount, ref float container, int taxRate) - { - container += (amount * taxRate / 100f); - if (container > 1) - { - amount = (int)container; - container -= (int)container; - } - else - { - amount = 0; - } - } + public static void CustomAddPrivateLandIncome(ref int amount, ItemClass.SubService subService, int taxRate) + { + switch (subService) + { + case ItemClass.SubService.IndustrialFarming: + ProcessUnit(ref amount, ref industyFarmIncome, taxRate); + RealCityEconomyManager.induFarmerLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.IndustrialForestry: + ProcessUnit(ref amount, ref industyForestIncome, taxRate); + RealCityEconomyManager.induForestyLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.IndustrialOil: + ProcessUnit(ref amount, ref industyOilIncome, taxRate); + RealCityEconomyManager.induOilLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.IndustrialOre: + ProcessUnit(ref amount, ref industyOreIncome, taxRate); + RealCityEconomyManager.induOreLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.IndustrialGeneric: + ProcessUnit(ref amount, ref industyGenIncome, taxRate); + RealCityEconomyManager.induGenLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialHigh: + ProcessUnit(ref amount, ref commercialHighIncome, taxRate); + RealCityEconomyManager.commHighLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialLow: + ProcessUnit(ref amount, ref commercialLowIncome, taxRate); + RealCityEconomyManager.commLowLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialLeisure: + ProcessUnit(ref amount, ref commercialLeiIncome, taxRate); + RealCityEconomyManager.commLeiLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialTourist: + ProcessUnit(ref amount, ref commercialLTouIncome, taxRate); + RealCityEconomyManager.commTouLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.CommercialEco: + ProcessUnit(ref amount, ref commercialLEcoIncome, taxRate); + RealCityEconomyManager.commEcoLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.ResidentialHigh: + ProcessUnit(ref amount, ref residentHighIncome, taxRate); + RealCityEconomyManager.residentHighLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.ResidentialLow: + ProcessUnit(ref amount, ref residentLowIncome, taxRate); + RealCityEconomyManager.residentLowLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.ResidentialHighEco: + ProcessUnit(ref amount, ref residentHighEcoIncome, taxRate); + RealCityEconomyManager.residentHighEcoLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.ResidentialLowEco: + ProcessUnit(ref amount, ref residentLowEcoIncome, taxRate); + RealCityEconomyManager.residentLowEcoLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.OfficeGeneric: + ProcessUnit(ref amount, ref officeGenIncome, taxRate); + RealCityEconomyManager.officeGenLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + case ItemClass.SubService.OfficeHightech: + ProcessUnit(ref amount, ref officeHighTechIncome, taxRate); + RealCityEconomyManager.officeHighTechLandIncomeForUI[MainDataStore.updateMoneyCount] += amount; + break; + default: + amount = 0; + DebugLog.LogToFileOnly("find unknown EXAddPrivateLandIncome building" + " building subService is" + subService + " buildlevelandtax is " + taxRate); + break; + } + } - public static void ProcessUnitTax100(ref int amount, ref float container) - { - container += amount; - if (container > 1) - { - amount = (int)container; - container -= (int)container; - } - else - { - amount = 0; - } - } - 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; - } + public static void ProcessUnit(ref int amount, ref float container, int taxRate) + { + container += (amount * taxRate / 100f); + if (container > 1) + { + amount = (int)container; + container -= (int)container; + } + else + { + amount = 0; + } + } - Singleton.instance.AddResource(EconomyManager.Resource.ResourcePrice, amount, service, subService, level, DistrictPolicies.Taxation.None); - return false; - } - } + public static void ProcessUnitTax100(ref int amount, ref float container) + { + container += amount; + if (container > 1) + { + amount = (int)container; + container -= (int)container; + } + else + { + amount = 0; + } + } + 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.instance.AddResource(EconomyManager.Resource.ResourcePrice, amount, service, subService, level, DistrictPolicies.Taxation.None); + return false; + } + } } diff --git a/Patch/EconomyManagerAddResourceItemClassPatch.cs b/Patch/EconomyManagerAddResourceItemClassPatch.cs index d6786ad..77c762d 100644 --- a/Patch/EconomyManagerAddResourceItemClassPatch.cs +++ b/Patch/EconomyManagerAddResourceItemClassPatch.cs @@ -6,42 +6,42 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class EconomyManagerAddResourceItemClassPatch - { - public static MethodBase TargetMethod() - { - return typeof(EconomyManager).GetMethod("AddResource", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(EconomyManager.Resource), typeof(int), typeof(ItemClass) }, null); - } + [HarmonyPatch] + public class EconomyManagerAddResourceItemClassPatch + { + public static MethodBase TargetMethod() + { + return typeof(EconomyManager).GetMethod("AddResource", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(EconomyManager.Resource), typeof(int), typeof(ItemClass) }, null); + } - public static void Prefix(EconomyManager.Resource resource, ref int amount, ItemClass itemClass) - { - // NON-STOCK CODE START - if (resource == EconomyManager.Resource.TourismIncome) - { - amount = 0; - } - else if (resource == EconomyManager.Resource.ResourcePrice) - { - RealCityEconomyManager.playerIndustryIncomeForUI[MainDataStore.updateMoneyCount] += amount; - } - else if (resource == EconomyManager.Resource.PublicIncome && itemClass.m_service == ItemClass.Service.Beautification) - { - if (amount > 0) - { - RealCityEconomyManager.citizenIncomeForUI[MainDataStore.updateMoneyCount] += amount; - } - else - { - //We use negetive amount to identify tourist income - amount = -amount; - RealCityEconomyManager.touristIncomeForUI[MainDataStore.updateMoneyCount] += amount; - } - } - else if (resource == EconomyManager.Resource.PublicIncome && itemClass.m_service == ItemClass.Service.PlayerEducation) - { - RealCityEconomyManager.schoolIncomeForUI[MainDataStore.updateMoneyCount] += amount; - } - } - } + public static void Prefix(EconomyManager.Resource resource, ref int amount, ItemClass itemClass) + { + // NON-STOCK CODE START + if (resource == EconomyManager.Resource.TourismIncome) + { + amount = 0; + } + else if (resource == EconomyManager.Resource.ResourcePrice) + { + RealCityEconomyManager.playerIndustryIncomeForUI[MainDataStore.updateMoneyCount] += amount; + } + else if (resource == EconomyManager.Resource.PublicIncome && itemClass.m_service == ItemClass.Service.Beautification) + { + if (amount > 0) + { + RealCityEconomyManager.citizenIncomeForUI[MainDataStore.updateMoneyCount] += amount; + } + else + { + //We use negetive amount to identify tourist income + amount = -amount; + RealCityEconomyManager.touristIncomeForUI[MainDataStore.updateMoneyCount] += amount; + } + } + else if (resource == EconomyManager.Resource.PublicIncome && itemClass.m_service == ItemClass.Service.PlayerEducation) + { + RealCityEconomyManager.schoolIncomeForUI[MainDataStore.updateMoneyCount] += amount; + } + } + } } diff --git a/Patch/EconomyManagerAddResourcePatchItemClassDetail.cs b/Patch/EconomyManagerAddResourcePatchItemClassDetail.cs index edaa30d..5c6e983 100644 --- a/Patch/EconomyManagerAddResourcePatchItemClassDetail.cs +++ b/Patch/EconomyManagerAddResourcePatchItemClassDetail.cs @@ -6,37 +6,37 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class EconomyManagerAddResourcePatchItemClassDetail - { - public static MethodBase TargetMethod() - { - return typeof(EconomyManager).GetMethod("AddResource", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(EconomyManager.Resource), typeof(int), typeof(ItemClass.Service), typeof(ItemClass.SubService), typeof(ItemClass.Level) }, null); - } + [HarmonyPatch] + public class EconomyManagerAddResourcePatchItemClassDetail + { + public static MethodBase TargetMethod() + { + return typeof(EconomyManager).GetMethod("AddResource", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(EconomyManager.Resource), typeof(int), typeof(ItemClass.Service), typeof(ItemClass.SubService), typeof(ItemClass.Level) }, null); + } - public static void Prefix(EconomyManager.Resource resource, ref int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level) - { - // NON-STOCK CODE START - if (resource == EconomyManager.Resource.PublicIncome) - { - if (service == ItemClass.Service.Vehicles) - { - RealCityEconomyManager.roadIncomeForUI[MainDataStore.updateMoneyCount] += amount; + public static void Prefix(EconomyManager.Resource resource, ref int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level) + { + // NON-STOCK CODE START + if (resource == EconomyManager.Resource.PublicIncome) + { + if (service == ItemClass.Service.Vehicles) + { + RealCityEconomyManager.roadIncomeForUI[MainDataStore.updateMoneyCount] += amount; - if (subService == ItemClass.SubService.None) - { - if (level == ItemClass.Level.Level2) - MainDataStore.outsideGovermentMoney -= amount; - else - MainDataStore.outsideTouristMoney -= amount; - } - } - } - else if (resource == EconomyManager.Resource.ResourcePrice) - { - RealCityEconomyManager.playerIndustryIncomeForUI[MainDataStore.updateMoneyCount] += amount; - } - /// NON-STOCK CODE END /// - } - } + if (subService == ItemClass.SubService.None) + { + if (level == ItemClass.Level.Level2) + MainDataStore.outsideGovermentMoney -= amount; + else + MainDataStore.outsideTouristMoney -= amount; + } + } + } + else if (resource == EconomyManager.Resource.ResourcePrice) + { + RealCityEconomyManager.playerIndustryIncomeForUI[MainDataStore.updateMoneyCount] += amount; + } + /// NON-STOCK CODE END /// + } + } } diff --git a/Patch/EconomyManagerFetchResourcePatch.cs b/Patch/EconomyManagerFetchResourcePatch.cs index a80d99d..1342a8d 100644 --- a/Patch/EconomyManagerFetchResourcePatch.cs +++ b/Patch/EconomyManagerFetchResourcePatch.cs @@ -5,146 +5,146 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class EconomyManagerFetchResourcePatch - { - public static float Road = 0f; - public static float Electricity = 0f; - public static float Water = 0f; - public static float Beautification = 0f; - public static float Garbage = 0f; - public static float HealthCare = 0f; - public static float PoliceDepartment = 0f; - public static float Education = 0f; - public static float Monument = 0f; - public static float FireDepartment = 0f; - public static float PublicTransport = 0f; - public static float Policy_cost = 0f; - public static float Disaster = 0f; - public static float PlayerIndustry = 0f; - public static float PlayerEducation = 0f; - public static float Museums = 0f; - public static float Fishing = 0f; - public static float VarsitySports = 0f; - public static MethodBase TargetMethod() - { - return typeof(EconomyManager).GetMethod("FetchResource", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(EconomyManager.Resource), typeof(int), typeof(ItemClass.Service), typeof(ItemClass.SubService), typeof(ItemClass.Level) }, null); - } - public static void OnFetchResourceMaintenance(EconomyManager.Resource resource, ref int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level) - { - switch (service) - { - case ItemClass.Service.Road: - ProcessUnit(ref amount, ref Road); - break; - case ItemClass.Service.Garbage: - ProcessUnit(ref amount, ref Garbage); - break; - case ItemClass.Service.PoliceDepartment: - ProcessUnit(ref amount, ref PoliceDepartment); - break; - case ItemClass.Service.Beautification: - ProcessUnit(ref amount, ref Beautification); - break; - case ItemClass.Service.Water: - ProcessUnit(ref amount, ref Water); - break; - case ItemClass.Service.Education: - ProcessUnit(ref amount, ref Education); - break; - case ItemClass.Service.Electricity: - ProcessUnit(ref amount, ref Electricity); - break; - case ItemClass.Service.FireDepartment: - ProcessUnit(ref amount, ref FireDepartment); - break; - case ItemClass.Service.Monument: - ProcessUnit(ref amount, ref Monument); - break; - case ItemClass.Service.HealthCare: - ProcessUnit(ref amount, ref HealthCare); - break; - case ItemClass.Service.PublicTransport: - ProcessUnit(ref amount, ref PublicTransport); - break; - case ItemClass.Service.Disaster: - ProcessUnit(ref amount, ref Disaster); - break; - case ItemClass.Service.PlayerIndustry: - ProcessUnit(ref amount, ref PlayerIndustry); - break; - case ItemClass.Service.PlayerEducation: - ProcessUnit(ref amount, ref PlayerEducation); - break; - case ItemClass.Service.Museums: - ProcessUnit(ref amount, ref Museums); - break; - case ItemClass.Service.VarsitySports: - ProcessUnit(ref amount, ref VarsitySports); - break; - case ItemClass.Service.Fishing: - ProcessUnit(ref amount, ref Fishing); - break; - default: break; - } - } + [HarmonyPatch] + public class EconomyManagerFetchResourcePatch + { + public static float Road = 0f; + public static float Electricity = 0f; + public static float Water = 0f; + public static float Beautification = 0f; + public static float Garbage = 0f; + public static float HealthCare = 0f; + public static float PoliceDepartment = 0f; + public static float Education = 0f; + public static float Monument = 0f; + public static float FireDepartment = 0f; + public static float PublicTransport = 0f; + public static float Policy_cost = 0f; + public static float Disaster = 0f; + public static float PlayerIndustry = 0f; + public static float PlayerEducation = 0f; + public static float Museums = 0f; + public static float Fishing = 0f; + public static float VarsitySports = 0f; + public static MethodBase TargetMethod() + { + return typeof(EconomyManager).GetMethod("FetchResource", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(EconomyManager.Resource), typeof(int), typeof(ItemClass.Service), typeof(ItemClass.SubService), typeof(ItemClass.Level) }, null); + } + public static void OnFetchResourceMaintenance(EconomyManager.Resource resource, ref int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level) + { + switch (service) + { + case ItemClass.Service.Road: + ProcessUnit(ref amount, ref Road); + break; + case ItemClass.Service.Garbage: + ProcessUnit(ref amount, ref Garbage); + break; + case ItemClass.Service.PoliceDepartment: + ProcessUnit(ref amount, ref PoliceDepartment); + break; + case ItemClass.Service.Beautification: + ProcessUnit(ref amount, ref Beautification); + break; + case ItemClass.Service.Water: + ProcessUnit(ref amount, ref Water); + break; + case ItemClass.Service.Education: + ProcessUnit(ref amount, ref Education); + break; + case ItemClass.Service.Electricity: + ProcessUnit(ref amount, ref Electricity); + break; + case ItemClass.Service.FireDepartment: + ProcessUnit(ref amount, ref FireDepartment); + break; + case ItemClass.Service.Monument: + ProcessUnit(ref amount, ref Monument); + break; + case ItemClass.Service.HealthCare: + ProcessUnit(ref amount, ref HealthCare); + break; + case ItemClass.Service.PublicTransport: + ProcessUnit(ref amount, ref PublicTransport); + break; + case ItemClass.Service.Disaster: + ProcessUnit(ref amount, ref Disaster); + break; + case ItemClass.Service.PlayerIndustry: + ProcessUnit(ref amount, ref PlayerIndustry); + break; + case ItemClass.Service.PlayerEducation: + ProcessUnit(ref amount, ref PlayerEducation); + break; + case ItemClass.Service.Museums: + ProcessUnit(ref amount, ref Museums); + break; + case ItemClass.Service.VarsitySports: + ProcessUnit(ref amount, ref VarsitySports); + break; + case ItemClass.Service.Fishing: + ProcessUnit(ref amount, ref Fishing); + break; + default: break; + } + } - public static void OnFetchResourcePolicy(EconomyManager.Resource resource, ref int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level) - { - ProcessUnit(ref amount, ref Policy_cost); - } + public static void OnFetchResourcePolicy(EconomyManager.Resource resource, ref int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level) + { + ProcessUnit(ref amount, ref Policy_cost); + } - public static void ProcessUnit(ref int amount, ref float container) - { - container += amount / MainDataStore.gameExpenseDivide; - if (container > 1) - { - amount = (int)container; - container -= (int)container; - } - else - { - amount = 0; - } - } + public static void ProcessUnit(ref int amount, ref float container) + { + container += amount / MainDataStore.gameExpenseDivide; + if (container > 1) + { + amount = (int)container; + container -= (int)container; + } + else + { + amount = 0; + } + } - public static void Prefix(ref EconomyManager.Resource resource, ref int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level, ref uint __state) - { - if (amount < 0) - { - DebugLog.LogToFileOnly($"Error: EconomyManagerFetchResourcePatch: amount < 0 {service} {subService} {level}"); - amount = 0; - } + public static void Prefix(ref EconomyManager.Resource resource, ref int amount, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level, ref uint __state) + { + if (amount < 0) + { + DebugLog.LogToFileOnly($"Error: EconomyManagerFetchResourcePatch: amount < 0 {service} {subService} {level}"); + amount = 0; + } - __state = 0xdeadbeaf; + __state = 0xdeadbeaf; - if (resource == EconomyManager.Resource.PolicyCost) - { - OnFetchResourcePolicy(resource, ref amount, service, subService, level); - } - if (resource == EconomyManager.Resource.Maintenance) - { - //we must return right amount for playerbuilding to work normally. - if (amount > 0) - __state = (uint)amount; - OnFetchResourceMaintenance(resource, ref amount, service, subService, level); - } - else if (resource == (EconomyManager.Resource)16) - { - resource = EconomyManager.Resource.Maintenance; - } - else if (resource == (EconomyManager.Resource)17) - { - resource = EconomyManager.Resource.PolicyCost; - } - } + if (resource == EconomyManager.Resource.PolicyCost) + { + OnFetchResourcePolicy(resource, ref amount, service, subService, level); + } + if (resource == EconomyManager.Resource.Maintenance) + { + //we must return right amount for playerbuilding to work normally. + if (amount > 0) + __state = (uint)amount; + OnFetchResourceMaintenance(resource, ref amount, service, subService, level); + } + else if (resource == (EconomyManager.Resource)16) + { + resource = EconomyManager.Resource.Maintenance; + } + else if (resource == (EconomyManager.Resource)17) + { + resource = EconomyManager.Resource.PolicyCost; + } + } - public static void Postfix(ref int __result, ref uint __state) - { - if (__state != 0xdeadbeaf) - { - __result = (int)__state; - } - } - } + public static void Postfix(ref int __result, ref uint __state) + { + if (__state != 0xdeadbeaf) + { + __result = (int)__state; + } + } + } } diff --git a/Patch/EconomyPanelIncomeExpensesPollPatch.cs b/Patch/EconomyPanelIncomeExpensesPollPatch.cs index 5b85833..88a4f62 100644 --- a/Patch/EconomyPanelIncomeExpensesPollPatch.cs +++ b/Patch/EconomyPanelIncomeExpensesPollPatch.cs @@ -7,60 +7,60 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class EconomyPanelIncomeExpensesPollPatch - { - public static MethodBase TargetMethod() - { - return typeof(EconomyPanel).GetNestedType("IncomeExpensesPoll", BindingFlags.NonPublic).GetMethod("CalculateArenasExpenses", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(EconomyPanel.ArenaIndex), typeof(long).MakeByRefType() }, null); - } - public static void Init() - { - DebugLog.LogToFileOnly("Init fake RealCityEconomyPanel"); - try - { - var inst = Singleton.instance; - var arenas = typeof(EconomyPanel).GetField("m_arenas", BindingFlags.NonPublic | BindingFlags.Static); - if (inst == null) - { - DebugLog.LogToFileOnly("No instance of EconomyPanel found!"); - return; - } - m_arenas = arenas.GetValue(inst) as List[]; - if (m_arenas == null) - { - DebugLog.LogToFileOnly("EconomyPanel Arrays are null"); - } - } - catch (Exception ex) - { - DebugLog.LogToFileOnly("EconomyPanel Exception: " + ex.Message); - } - } + [HarmonyPatch] + public class EconomyPanelIncomeExpensesPollPatch + { + public static MethodBase TargetMethod() + { + return typeof(EconomyPanel).GetNestedType("IncomeExpensesPoll", BindingFlags.NonPublic).GetMethod("CalculateArenasExpenses", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(EconomyPanel.ArenaIndex), typeof(long).MakeByRefType() }, null); + } + public static void Init() + { + DebugLog.LogToFileOnly("Init fake RealCityEconomyPanel"); + try + { + var inst = Singleton.instance; + var arenas = typeof(EconomyPanel).GetField("m_arenas", BindingFlags.NonPublic | BindingFlags.Static); + if (inst == null) + { + DebugLog.LogToFileOnly("No instance of EconomyPanel found!"); + return; + } + m_arenas = arenas.GetValue(inst) as List[]; + if (m_arenas == null) + { + DebugLog.LogToFileOnly("EconomyPanel Arrays are null"); + } + } + catch (Exception ex) + { + DebugLog.LogToFileOnly("EconomyPanel Exception: " + ex.Message); + } + } - public static bool Prefix(EconomyPanel.ArenaIndex arenaIndex, ref long expenses) - { - if (!init) - { - Init(); - init = true; - } + public static bool Prefix(EconomyPanel.ArenaIndex arenaIndex, ref long expenses) + { + if (!init) + { + Init(); + init = true; + } - for (int i = 0; i < m_arenas[(int)arenaIndex].Count; i++) - { - ushort buildingID = m_arenas[(int)arenaIndex][i]; - var Info = Singleton.instance.m_buildings.m_buffer[buildingID].Info; - if (Info != null) - { - Singleton.instance.GetIncomeAndExpenses(Info.m_class.m_service, Info.m_class.m_subService, Info.m_class.m_level, out long _, out long expense); - expenses += expense; - return false; - } - } - return false; - } + for (int i = 0; i < m_arenas[(int)arenaIndex].Count; i++) + { + ushort buildingID = m_arenas[(int)arenaIndex][i]; + var Info = Singleton.instance.m_buildings.m_buffer[buildingID].Info; + if (Info != null) + { + Singleton.instance.GetIncomeAndExpenses(Info.m_class.m_service, Info.m_class.m_subService, Info.m_class.m_level, out long _, out long expense); + expenses += expense; + return false; + } + } + return false; + } - public static bool init = false; - private static List[] m_arenas; - } + public static bool init = false; + private static List[] m_arenas; + } } diff --git a/Patch/ExtractingFacilityAIGetResourceRatePatch.cs b/Patch/ExtractingFacilityAIGetResourceRatePatch.cs index 76a0588..ba81905 100644 --- a/Patch/ExtractingFacilityAIGetResourceRatePatch.cs +++ b/Patch/ExtractingFacilityAIGetResourceRatePatch.cs @@ -7,20 +7,20 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class ExtractingFacilityAIGetResourceRatePatch - { - public static MethodBase TargetMethod() - { - return typeof(ExtractingFacilityAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); - } - public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) - { - if (resource == EconomyManager.Resource.Maintenance) - { - float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); - __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); - } - } - } + [HarmonyPatch] + public class ExtractingFacilityAIGetResourceRatePatch + { + public static MethodBase TargetMethod() + { + return typeof(ExtractingFacilityAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); + } + public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) + { + if (resource == EconomyManager.Resource.Maintenance) + { + float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); + __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); + } + } + } } diff --git a/Patch/HumanAIEnterParkAreaPatch.cs b/Patch/HumanAIEnterParkAreaPatch.cs index 882aaa6..38b27bd 100644 --- a/Patch/HumanAIEnterParkAreaPatch.cs +++ b/Patch/HumanAIEnterParkAreaPatch.cs @@ -7,17 +7,17 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class HumanAIEnterParkAreaPatch - { - public static MethodBase TargetMethod() - { - return typeof(HumanAI).GetMethod("EnterParkArea", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(CitizenInstance).MakeByRefType(), typeof(byte), typeof(ushort) }, null); - } - public static bool Prefix() - { - //do not allow ticket price - return false; - } - } + [HarmonyPatch] + public class HumanAIEnterParkAreaPatch + { + public static MethodBase TargetMethod() + { + return typeof(HumanAI).GetMethod("EnterParkArea", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(CitizenInstance).MakeByRefType(), typeof(byte), typeof(ushort) }, null); + } + public static bool Prefix() + { + //do not allow ticket price + return false; + } + } } diff --git a/Patch/HumanAIEnterVehiclePatch.cs b/Patch/HumanAIEnterVehiclePatch.cs index eb061ca..de01195 100644 --- a/Patch/HumanAIEnterVehiclePatch.cs +++ b/Patch/HumanAIEnterVehiclePatch.cs @@ -7,53 +7,53 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class HumanAIEnterVehiclePatch - { - public static MethodBase TargetMethod() - { - return typeof(HumanAI).GetMethod("EnterVehicle", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(CitizenInstance).MakeByRefType() }, null); - } - public static void Prefix(ref CitizenInstance citizenData) - { - uint citizen = citizenData.m_citizen; - if (citizen != 0u) - { - VehicleManager vehicleManager = Singleton.instance; - ushort vehicleID = Singleton.instance.m_citizens.m_buffer[citizen].m_vehicle; - if (vehicleID != 0) - { - vehicleID = vehicleManager.m_vehicles.m_buffer[vehicleID].GetFirstVehicle(vehicleID); - } - if (vehicleID != 0) - { - VehicleInfo info = vehicleManager.m_vehicles.m_buffer[vehicleID].Info; - int ticketPrice = info.m_vehicleAI.GetTicketPrice(vehicleID, ref vehicleManager.m_vehicles.m_buffer[vehicleID]); - if (ticketPrice != 0) - { - // NON-STOCK CODE START - CitizenManager citizenManager = Singleton.instance; - if ((citizenManager.m_citizens.m_buffer[citizenData.m_citizen].m_flags & Citizen.Flags.Tourist) == Citizen.Flags.None) - { - CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - (ticketPrice)); - } - else - { - if (CitizenData.citizenMoney[citizen] < ticketPrice) - { - ticketPrice = (CitizenData.citizenMoney[citizen] > 0) ? (int)CitizenData.citizenMoney[citizen] + 1 : 1; - CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - ticketPrice); - } - else - { - CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - (ticketPrice)); - } - MainDataStore.outsideTouristMoney -= ticketPrice; - } - /// NON-STOCK CODE END /// - } - } - } - } - } + [HarmonyPatch] + public class HumanAIEnterVehiclePatch + { + public static MethodBase TargetMethod() + { + return typeof(HumanAI).GetMethod("EnterVehicle", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(CitizenInstance).MakeByRefType() }, null); + } + public static void Prefix(ref CitizenInstance citizenData) + { + uint citizen = citizenData.m_citizen; + if (citizen != 0u) + { + VehicleManager vehicleManager = Singleton.instance; + ushort vehicleID = Singleton.instance.m_citizens.m_buffer[citizen].m_vehicle; + if (vehicleID != 0) + { + vehicleID = vehicleManager.m_vehicles.m_buffer[vehicleID].GetFirstVehicle(vehicleID); + } + if (vehicleID != 0) + { + VehicleInfo info = vehicleManager.m_vehicles.m_buffer[vehicleID].Info; + int ticketPrice = info.m_vehicleAI.GetTicketPrice(vehicleID, ref vehicleManager.m_vehicles.m_buffer[vehicleID]); + if (ticketPrice != 0) + { + // NON-STOCK CODE START + CitizenManager citizenManager = Singleton.instance; + if ((citizenManager.m_citizens.m_buffer[citizenData.m_citizen].m_flags & Citizen.Flags.Tourist) == Citizen.Flags.None) + { + CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - (ticketPrice)); + } + else + { + if (CitizenData.citizenMoney[citizen] < ticketPrice) + { + ticketPrice = (CitizenData.citizenMoney[citizen] > 0) ? (int)CitizenData.citizenMoney[citizen] + 1 : 1; + CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - ticketPrice); + } + else + { + CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - (ticketPrice)); + } + MainDataStore.outsideTouristMoney -= ticketPrice; + } + /// NON-STOCK CODE END /// + } + } + } + } + } } diff --git a/Patch/HumanAIStartMovingPatch.cs b/Patch/HumanAIStartMovingPatch.cs index 5fe49c2..8329788 100644 --- a/Patch/HumanAIStartMovingPatch.cs +++ b/Patch/HumanAIStartMovingPatch.cs @@ -1,4 +1,4 @@ -using System; +using System; using ColossalFramework; using UnityEngine; using RealCity.Util; @@ -10,71 +10,71 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class HumanAIStartMovingPatch - { - public static MethodBase TargetMethod() - { - var method = typeof(HumanAI).GetMethod("StartMoving", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(uint), typeof(Citizen).MakeByRefType(), typeof(ushort), typeof(ushort) }, null); - return method; - } + [HarmonyPatch] + public class HumanAIStartMovingPatch + { + public static MethodBase TargetMethod() + { + var method = typeof(HumanAI).GetMethod("StartMoving", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(uint), typeof(Citizen).MakeByRefType(), typeof(ushort), typeof(ushort) }, null); + return method; + } - public static void Prefix(uint citizenID, ref Citizen data, ref ushort sourceBuilding, ref ushort targetBuilding) - { - if (data.m_workBuilding != targetBuilding) - { - var building = Singleton.instance.m_buildings.m_buffer[targetBuilding]; - if (building.Info.m_class.m_service == ItemClass.Service.Commercial) - { - CitizenManager instance = Singleton.instance; - ushort homeBuilding = data.m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = data.GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); + public static void Prefix(uint citizenID, ref Citizen data, ref ushort sourceBuilding, ref ushort targetBuilding) + { + if (data.m_workBuilding != targetBuilding) + { + var building = Singleton.instance.m_buildings.m_buffer[targetBuilding]; + if (building.Info.m_class.m_service == ItemClass.Service.Commercial) + { + CitizenManager instance = Singleton.instance; + ushort homeBuilding = data.m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = data.GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); - Citizen.BehaviourData behaviour = default; - int aliveVisitCount = 0; - int totalVisitCount = 0; - RealCityCommercialBuildingAI.InitDelegate(); - RealCityCommercialBuildingAI.GetVisitBehaviour((CommercialBuildingAI)(building.Info.m_buildingAI), targetBuilding, ref building, ref behaviour, ref aliveVisitCount, ref totalVisitCount); - var amount = building.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount; - var CommercialBuildingAI = building.Info.m_buildingAI as CommercialBuildingAI; - var maxCount = CommercialBuildingAI.CalculateVisitplaceCount((ItemClass.Level)building.m_level, new Randomizer(targetBuilding), building.m_width, building.m_length); - if ((amount <= 0) || (maxCount <= totalVisitCount)) - { - //Close CommercialBuilding - //Reject citizen to building which lack of goods - sourceBuilding = targetBuilding; - building.m_flags &= ~Building.Flags.Active; - return; - } + Citizen.BehaviourData behaviour = default; + int aliveVisitCount = 0; + int totalVisitCount = 0; + RealCityCommercialBuildingAI.InitDelegate(); + RealCityCommercialBuildingAI.GetVisitBehaviour((CommercialBuildingAI)(building.Info.m_buildingAI), targetBuilding, ref building, ref behaviour, ref aliveVisitCount, ref totalVisitCount); + var amount = building.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount; + var CommercialBuildingAI = building.Info.m_buildingAI as CommercialBuildingAI; + var maxCount = CommercialBuildingAI.CalculateVisitplaceCount((ItemClass.Level)building.m_level, new Randomizer(targetBuilding), building.m_width, building.m_length); + if ((amount <= 0) || (maxCount <= totalVisitCount)) + { + //Close CommercialBuilding + //Reject citizen to building which lack of goods + sourceBuilding = targetBuilding; + building.m_flags &= ~Building.Flags.Active; + return; + } - if (data.m_flags.IsFlagSet(Citizen.Flags.Tourist)) - { - //DebugLog.LogToFileOnly("Find Tourist in HumanAIStartMovingPatch"); - } - else - { - //DebugLog.LogToFileOnly("Find Resident in HumanAIStartMovingPatch"); - if (CitizenUnitData.familyMoney[containingUnit] < MainDataStore.maxGoodPurchase * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)) - { - //Reject poor citizen to building - if (CitizenUnitData.familyGoods[containingUnit] > 1000) - { - //If a family is lacking goods very seriously, even they do not have enough money, they can buy goods. - //minimumLivingAllowance will cover this expense. - sourceBuilding = targetBuilding; - return; - } - } - else if (CitizenUnitData.familyGoods[containingUnit] > 2000) - { - //Reject citizen who already have enough goods to building - sourceBuilding = targetBuilding; - return; - } - } - } - } - } - } + if (data.m_flags.IsFlagSet(Citizen.Flags.Tourist)) + { + //DebugLog.LogToFileOnly("Find Tourist in HumanAIStartMovingPatch"); + } + else + { + //DebugLog.LogToFileOnly("Find Resident in HumanAIStartMovingPatch"); + if (CitizenUnitData.familyMoney[containingUnit] < MainDataStore.maxGoodPurchase * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)) + { + //Reject poor citizen to building + if (CitizenUnitData.familyGoods[containingUnit] > 1000) + { + //If a family is lacking goods very seriously, even they do not have enough money, they can buy goods. + //minimumLivingAllowance will cover this expense. + sourceBuilding = targetBuilding; + return; + } + } + else if (CitizenUnitData.familyGoods[containingUnit] > 2000) + { + //Reject citizen who already have enough goods to building + sourceBuilding = targetBuilding; + return; + } + } + } + } + } + } } \ No newline at end of file diff --git a/Patch/IndustrialBuildingAICreateBuildingPatch.cs b/Patch/IndustrialBuildingAICreateBuildingPatch.cs index 538efe5..ca4a968 100644 --- a/Patch/IndustrialBuildingAICreateBuildingPatch.cs +++ b/Patch/IndustrialBuildingAICreateBuildingPatch.cs @@ -7,19 +7,19 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class IndustrialBuildingAICreateBuildingPatch - { - public static MethodBase TargetMethod() - { - return typeof(IndustrialBuildingAI).GetMethod("CreateBuilding", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType()}, null); - } - public static void Postfix(ushort buildingID, ref Building data) - { - RealCityIndustrialBuildingAI.InitDelegate(); - var material = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); - float initialMaterialFee = data.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(material) + 10000; - BuildingData.buildingMoney[buildingID] = -initialMaterialFee; - } - } + [HarmonyPatch] + public class IndustrialBuildingAICreateBuildingPatch + { + public static MethodBase TargetMethod() + { + return typeof(IndustrialBuildingAI).GetMethod("CreateBuilding", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType() }, null); + } + public static void Postfix(ushort buildingID, ref Building data) + { + RealCityIndustrialBuildingAI.InitDelegate(); + var material = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); + float initialMaterialFee = data.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(material) + 10000; + BuildingData.buildingMoney[buildingID] = -initialMaterialFee; + } + } } diff --git a/Patch/IndustrialBuildingAIModifyMaterialBufferPatch.cs b/Patch/IndustrialBuildingAIModifyMaterialBufferPatch.cs index 259d3b0..90cf202 100644 --- a/Patch/IndustrialBuildingAIModifyMaterialBufferPatch.cs +++ b/Patch/IndustrialBuildingAIModifyMaterialBufferPatch.cs @@ -9,66 +9,66 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class IndustrialBuildingAIModifyMaterialBufferPatch - { - public static MethodBase TargetMethod() - { - return typeof(IndustrialBuildingAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); - } + [HarmonyPatch] + public class IndustrialBuildingAIModifyMaterialBufferPatch + { + public static MethodBase TargetMethod() + { + return typeof(IndustrialBuildingAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); + } - public static void Prefix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - RealCityIndustrialBuildingAI.InitDelegate(); - if (material == RealCityIndustrialBuildingAI.GetOutgoingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI))) - { - RevertTradeIncome(buildingID, ref data, material, ref amountDelta); - } - } + public static void Prefix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + RealCityIndustrialBuildingAI.InitDelegate(); + if (material == RealCityIndustrialBuildingAI.GetOutgoingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI))) + { + RevertTradeIncome(buildingID, ref data, material, ref amountDelta); + } + } - public static void Postfix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - RealCityIndustrialBuildingAI.InitDelegate(); - if (material == RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID) || material == RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID)) - { - ProcessIncoming(buildingID, material, ref amountDelta); - } - else if (material == RealCityIndustrialBuildingAI.GetOutgoingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI))) - { - CaculateTradeIncome(buildingID, ref data, material, ref amountDelta); - } - } + public static void Postfix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + RealCityIndustrialBuildingAI.InitDelegate(); + if (material == RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID) || material == RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID)) + { + ProcessIncoming(buildingID, material, ref amountDelta); + } + else if (material == RealCityIndustrialBuildingAI.GetOutgoingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI))) + { + CaculateTradeIncome(buildingID, ref data, material, ref amountDelta); + } + } - public static void ProcessIncoming(ushort buildingID, TransferManager.TransferReason material, ref int amountDelta) - { - float tradeIncome = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - BuildingData.buildingMoney[buildingID] = BuildingData.buildingMoney[buildingID] - tradeIncome; - } + public static void ProcessIncoming(ushort buildingID, TransferManager.TransferReason material, ref int amountDelta) + { + float tradeIncome = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + BuildingData.buildingMoney[buildingID] = BuildingData.buildingMoney[buildingID] - tradeIncome; + } - public static void RevertTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - if (amountDelta > 0) - { - //revert - data.m_customBuffer2 = (ushort)Mathf.Clamp(data.m_customBuffer2 + amountDelta, 0, 65535); - float tradeIncome = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; - MainDataStore.unfinishedTransitionLost += (int)(tradeTax / 100f); - Singleton.instance.FetchResource((EconomyManager.Resource)17, (int)tradeTax, ItemClass.Service.Industrial, data.Info.m_class.m_subService, data.Info.m_class.m_level); - BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] + (tradeIncome + tradeTax)); - } - } + public static void RevertTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + if (amountDelta > 0) + { + //revert + data.m_customBuffer2 = (ushort)Mathf.Clamp(data.m_customBuffer2 + amountDelta, 0, 65535); + float tradeIncome = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; + MainDataStore.unfinishedTransitionLost += (int)(tradeTax / 100f); + Singleton.instance.FetchResource((EconomyManager.Resource)17, (int)tradeTax, ItemClass.Service.Industrial, data.Info.m_class.m_subService, data.Info.m_class.m_level); + BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] + (tradeIncome + tradeTax)); + } + } - public static void CaculateTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - if (amountDelta < 0) - { - float tradeIncome = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; - Singleton.instance.AddPrivateIncome((int)tradeTax, ItemClass.Service.Industrial, data.Info.m_class.m_subService, data.Info.m_class.m_level, 111333); - BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (tradeIncome + tradeTax)); - } - } - } + public static void CaculateTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + if (amountDelta < 0) + { + float tradeIncome = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; + Singleton.instance.AddPrivateIncome((int)tradeTax, ItemClass.Service.Industrial, data.Info.m_class.m_subService, data.Info.m_class.m_level, 111333); + BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (tradeIncome + tradeTax)); + } + } + } } diff --git a/Patch/IndustrialBuildingAISimulationStepActivePatch.cs b/Patch/IndustrialBuildingAISimulationStepActivePatch.cs index 21f39cc..2da7627 100644 --- a/Patch/IndustrialBuildingAISimulationStepActivePatch.cs +++ b/Patch/IndustrialBuildingAISimulationStepActivePatch.cs @@ -10,25 +10,25 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class IndustrialBuildingAISimulationStepActivePatch - { - public static MethodBase TargetMethod() - { - return typeof(IndustrialBuildingAI).GetMethod("SimulationStepActive", BindingFlags.NonPublic | BindingFlags.Instance); - } + [HarmonyPatch] + public class IndustrialBuildingAISimulationStepActivePatch + { + public static MethodBase TargetMethod() + { + return typeof(IndustrialBuildingAI).GetMethod("SimulationStepActive", BindingFlags.NonPublic | BindingFlags.Instance); + } - public static void Prefix(ref Building buildingData, ref ushort[] __state) - { - __state = new ushort[2]; - __state[0] = buildingData.m_customBuffer1; - __state[1] = buildingData.m_customBuffer2; - } + public static void Prefix(ref Building buildingData, ref ushort[] __state) + { + __state = new ushort[2]; + __state[0] = buildingData.m_customBuffer1; + __state[1] = buildingData.m_customBuffer2; + } - public static void Postfix(ushort buildingID, ref Building buildingData, ref ushort[] __state) - { - RealCityPrivateBuildingAI.ProcessAdditionProduct(buildingID, ref buildingData, ref __state); - } + public static void Postfix(ushort buildingID, ref Building buildingData, ref ushort[] __state) + { + RealCityPrivateBuildingAI.ProcessAdditionProduct(buildingID, ref buildingData, ref __state); + } - } + } } diff --git a/Patch/IndustrialExtractorAIModifyMaterialBufferPatch.cs b/Patch/IndustrialExtractorAIModifyMaterialBufferPatch.cs index c3a337e..a331065 100644 --- a/Patch/IndustrialExtractorAIModifyMaterialBufferPatch.cs +++ b/Patch/IndustrialExtractorAIModifyMaterialBufferPatch.cs @@ -9,56 +9,56 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class IndustrialExtractorAIModifyMaterialBufferPatch - { - public static MethodBase TargetMethod() - { - return typeof(IndustrialExtractorAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); - } + [HarmonyPatch] + public class IndustrialExtractorAIModifyMaterialBufferPatch + { + public static MethodBase TargetMethod() + { + return typeof(IndustrialExtractorAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); + } - public static void Prefix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - RealCityIndustrialExtractorAI.InitDelegate(); - if (material == RealCityIndustrialExtractorAI.GetOutgoingTransferReason((IndustrialExtractorAI)(data.Info.m_buildingAI))) - { - RevertTradeIncome(buildingID, ref data, material, ref amountDelta); - } - } + public static void Prefix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + RealCityIndustrialExtractorAI.InitDelegate(); + if (material == RealCityIndustrialExtractorAI.GetOutgoingTransferReason((IndustrialExtractorAI)(data.Info.m_buildingAI))) + { + RevertTradeIncome(buildingID, ref data, material, ref amountDelta); + } + } - public static void Postfix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - RealCityIndustrialExtractorAI.InitDelegate(); - if (material == RealCityIndustrialExtractorAI.GetOutgoingTransferReason((IndustrialExtractorAI)(data.Info.m_buildingAI))) - { - CaculateTradeIncome(buildingID, ref data, material, ref amountDelta); - } - } + public static void Postfix(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + RealCityIndustrialExtractorAI.InitDelegate(); + if (material == RealCityIndustrialExtractorAI.GetOutgoingTransferReason((IndustrialExtractorAI)(data.Info.m_buildingAI))) + { + CaculateTradeIncome(buildingID, ref data, material, ref amountDelta); + } + } - public static void RevertTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - if (amountDelta > 0) - { - //revert - data.m_customBuffer1 = (ushort)Mathf.Clamp(data.m_customBuffer1 + amountDelta, 0, 65535); - float tradeIncome = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; - MainDataStore.unfinishedTransitionLost += (int)(tradeTax / 100f); - Singleton.instance.FetchResource((EconomyManager.Resource)17, (int)tradeTax, ItemClass.Service.Industrial, data.Info.m_class.m_subService, data.Info.m_class.m_level); - BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] + (tradeIncome + tradeTax)); - } - } + public static void RevertTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + if (amountDelta > 0) + { + //revert + data.m_customBuffer1 = (ushort)Mathf.Clamp(data.m_customBuffer1 + amountDelta, 0, 65535); + float tradeIncome = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; + MainDataStore.unfinishedTransitionLost += (int)(tradeTax / 100f); + Singleton.instance.FetchResource((EconomyManager.Resource)17, (int)tradeTax, ItemClass.Service.Industrial, data.Info.m_class.m_subService, data.Info.m_class.m_level); + BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] + (tradeIncome + tradeTax)); + } + } - public static void CaculateTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - if (amountDelta < 0) - { - float tradeIncome = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; - Singleton.instance.AddPrivateIncome((int)tradeTax, ItemClass.Service.Industrial, data.Info.m_class.m_subService, data.Info.m_class.m_level, 111333); - BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (tradeIncome + tradeTax)); - } - } + public static void CaculateTradeIncome(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + if (amountDelta < 0) + { + float tradeIncome = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + float tradeTax = -tradeIncome * RealCityPrivateBuildingAI.GetTaxRate(data) / 100f; + Singleton.instance.AddPrivateIncome((int)tradeTax, ItemClass.Service.Industrial, data.Info.m_class.m_subService, data.Info.m_class.m_level, 111333); + BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (tradeIncome + tradeTax)); + } + } - } + } } diff --git a/Patch/IndustrialExtractorAISimulationStepActivePatch.cs b/Patch/IndustrialExtractorAISimulationStepActivePatch.cs index 12ac237..37e233e 100644 --- a/Patch/IndustrialExtractorAISimulationStepActivePatch.cs +++ b/Patch/IndustrialExtractorAISimulationStepActivePatch.cs @@ -10,23 +10,23 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class IndustrialExtractorAISimulationStepActivePatch - { - public static MethodBase TargetMethod() - { - return typeof(IndustrialExtractorAI).GetMethod("SimulationStepActive", BindingFlags.NonPublic | BindingFlags.Instance); - } + [HarmonyPatch] + public class IndustrialExtractorAISimulationStepActivePatch + { + public static MethodBase TargetMethod() + { + return typeof(IndustrialExtractorAI).GetMethod("SimulationStepActive", BindingFlags.NonPublic | BindingFlags.Instance); + } - public static void Prefix(ref Building buildingData, ref ushort[] __state) - { - __state = new ushort[1]; - __state[0] = buildingData.m_customBuffer1; - } + public static void Prefix(ref Building buildingData, ref ushort[] __state) + { + __state = new ushort[1]; + __state[0] = buildingData.m_customBuffer1; + } - public static void Postfix(ref Building buildingData, ref ushort[] __state) - { - RealCityPrivateBuildingAI.ProcessAdditionProduct(ref buildingData, ref __state); - } - } + public static void Postfix(ref Building buildingData, ref ushort[] __state) + { + RealCityPrivateBuildingAI.ProcessAdditionProduct(ref buildingData, ref __state); + } + } } diff --git a/Patch/IndustryBuildingGetResourcePricePatch.cs b/Patch/IndustryBuildingGetResourcePricePatch.cs index 48e9b9c..1d01dbe 100644 --- a/Patch/IndustryBuildingGetResourcePricePatch.cs +++ b/Patch/IndustryBuildingGetResourcePricePatch.cs @@ -8,96 +8,96 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class IndustryBuildingGetResourcePricePatch - { - public static MethodBase TargetMethod() - { - return typeof(IndustryBuildingAI).GetMethod("GetResourcePrice", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - 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; - } + [HarmonyPatch] + public class IndustryBuildingGetResourcePricePatch + { + public static MethodBase TargetMethod() + { + return typeof(IndustryBuildingAI).GetMethod("GetResourcePrice", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); + } + 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; - } + if (RealCity.reduceVehicle) + { + if (canRisePrice) + __result <<= MainDataStore.reduceCargoDivShift; + } - __result = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, __result); - return false; - } - } + __result = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, __result); + return false; + } + } } diff --git a/Patch/LandfillSiteAIModifyMaterialBufferPatch.cs b/Patch/LandfillSiteAIModifyMaterialBufferPatch.cs index d2e6985..0392557 100644 --- a/Patch/LandfillSiteAIModifyMaterialBufferPatch.cs +++ b/Patch/LandfillSiteAIModifyMaterialBufferPatch.cs @@ -9,80 +9,80 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class LandfillSiteAIModifyMaterialBufferPatch - { - public static MethodBase TargetMethod() - { - return typeof(LandfillSiteAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); - } + [HarmonyPatch] + public class LandfillSiteAIModifyMaterialBufferPatch + { + public static MethodBase TargetMethod() + { + return typeof(LandfillSiteAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); + } - public static void Prefix(ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - if ((material == TransferManager.TransferReason.Lumber) || (material == TransferManager.TransferReason.Coal) || (material == TransferManager.TransferReason.Petrol)) - { - if (amountDelta > 0) - { - RevertGabargeIncome(ref data, amountDelta, material); - } - } - } + public static void Prefix(ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + if ((material == TransferManager.TransferReason.Lumber) || (material == TransferManager.TransferReason.Coal) || (material == TransferManager.TransferReason.Petrol)) + { + if (amountDelta > 0) + { + RevertGabargeIncome(ref data, amountDelta, material); + } + } + } - public static void Postfix(ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - if ((material == TransferManager.TransferReason.Lumber) || (material == TransferManager.TransferReason.Coal) || (material == TransferManager.TransferReason.Petrol)) - { - if (amountDelta < 0) - { - ProcessGabargeIncome(ref data, amountDelta, material); - } - } - } + public static void Postfix(ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + if ((material == TransferManager.TransferReason.Lumber) || (material == TransferManager.TransferReason.Coal) || (material == TransferManager.TransferReason.Petrol)) + { + if (amountDelta < 0) + { + ProcessGabargeIncome(ref data, amountDelta, material); + } + } + } - public static void ProcessGabargeIncome(ref Building building, int amountDelta, TransferManager.TransferReason material) - { - if (building.Info.m_class.m_service == ItemClass.Service.Garbage) - { - float product_value; - switch (material) - { - case TransferManager.TransferReason.Lumber: - product_value = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - Singleton.instance.AddResource(EconomyManager.Resource.ResourcePrice, (int)product_value, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryForestry, ItemClass.Level.Level1); - break; - case TransferManager.TransferReason.Coal: - product_value = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - Singleton.instance.AddResource(EconomyManager.Resource.ResourcePrice, (int)product_value, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOre, ItemClass.Level.Level1); - break; - case TransferManager.TransferReason.Petrol: - product_value = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - Singleton.instance.AddResource(EconomyManager.Resource.ResourcePrice, (int)product_value, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOil, ItemClass.Level.Level1); - break; - default: DebugLog.LogToFileOnly($"Error: ProcessGabargeIncome find unknown gabarge transition {building.Info.m_class} transfer reason {material}"); break; - } - } - } + public static void ProcessGabargeIncome(ref Building building, int amountDelta, TransferManager.TransferReason material) + { + if (building.Info.m_class.m_service == ItemClass.Service.Garbage) + { + float product_value; + switch (material) + { + case TransferManager.TransferReason.Lumber: + product_value = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + Singleton.instance.AddResource(EconomyManager.Resource.ResourcePrice, (int)product_value, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryForestry, ItemClass.Level.Level1); + break; + case TransferManager.TransferReason.Coal: + product_value = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + Singleton.instance.AddResource(EconomyManager.Resource.ResourcePrice, (int)product_value, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOre, ItemClass.Level.Level1); + break; + case TransferManager.TransferReason.Petrol: + product_value = -amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + Singleton.instance.AddResource(EconomyManager.Resource.ResourcePrice, (int)product_value, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOil, ItemClass.Level.Level1); + break; + default: DebugLog.LogToFileOnly($"Error: ProcessGabargeIncome find unknown gabarge transition {building.Info.m_class} transfer reason {material}"); break; + } + } + } - public static void RevertGabargeIncome(ref Building building, int amountDelta, TransferManager.TransferReason material) - { - building.m_customBuffer2 = (ushort)Mathf.Clamp(building.m_customBuffer2 + amountDelta, 0, 65535); - float productValue; - switch (material) - { - case TransferManager.TransferReason.Lumber: - productValue = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryForestry, ItemClass.Level.Level1); - break; - case TransferManager.TransferReason.Coal: - productValue = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOre, ItemClass.Level.Level1); - break; - case TransferManager.TransferReason.Petrol: - productValue = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); - Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOil, ItemClass.Level.Level1); - break; - default: DebugLog.LogToFileOnly($"Error: RevertGabargeIncome find unknown gabarge transition {building.Info.m_class} transfer reason {material}"); break; - } - } - } + public static void RevertGabargeIncome(ref Building building, int amountDelta, TransferManager.TransferReason material) + { + building.m_customBuffer2 = (ushort)Mathf.Clamp(building.m_customBuffer2 + amountDelta, 0, 65535); + float productValue; + switch (material) + { + case TransferManager.TransferReason.Lumber: + productValue = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryForestry, ItemClass.Level.Level1); + break; + case TransferManager.TransferReason.Coal: + productValue = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOre, ItemClass.Level.Level1); + break; + case TransferManager.TransferReason.Petrol: + productValue = amountDelta * RealCityIndustryBuildingAI.GetResourcePrice(material); + Singleton.instance.FetchResource(EconomyManager.Resource.ResourcePrice, (int)productValue, ItemClass.Service.PlayerIndustry, ItemClass.SubService.PlayerIndustryOil, ItemClass.Level.Level1); + break; + default: DebugLog.LogToFileOnly($"Error: RevertGabargeIncome find unknown gabarge transition {building.Info.m_class} transfer reason {material}"); break; + } + } + } } diff --git a/Patch/MarketAIModifyMaterialBufferPatch.cs b/Patch/MarketAIModifyMaterialBufferPatch.cs index 85762da..c4fd495 100644 --- a/Patch/MarketAIModifyMaterialBufferPatch.cs +++ b/Patch/MarketAIModifyMaterialBufferPatch.cs @@ -6,49 +6,49 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class MarketAIModifyMaterialBufferPatch - { - public static MethodBase TargetMethod() - { - return typeof(MarketAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); - } + [HarmonyPatch] + public class MarketAIModifyMaterialBufferPatch + { + public static MethodBase TargetMethod() + { + return typeof(MarketAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); + } - public static bool Prefix(ref Building data, TransferManager.TransferReason material, ref int amountDelta) - { - switch (material) - { - case TransferManager.TransferReason.ShoppingB: - case TransferManager.TransferReason.ShoppingC: - case TransferManager.TransferReason.ShoppingD: - case TransferManager.TransferReason.ShoppingE: - case TransferManager.TransferReason.ShoppingF: - case TransferManager.TransferReason.ShoppingG: - case TransferManager.TransferReason.ShoppingH: - { - if (amountDelta == -100) - { - //Disable other -100 ModifyMaterialBuffer - return false; - } + public static bool Prefix(ref Building data, TransferManager.TransferReason material, ref int amountDelta) + { + switch (material) + { + case TransferManager.TransferReason.ShoppingB: + case TransferManager.TransferReason.ShoppingC: + case TransferManager.TransferReason.ShoppingD: + case TransferManager.TransferReason.ShoppingE: + case TransferManager.TransferReason.ShoppingF: + case TransferManager.TransferReason.ShoppingG: + case TransferManager.TransferReason.ShoppingH: + { + if (amountDelta == -100) + { + //Disable other -100 ModifyMaterialBuffer + return false; + } - int customBuffer2 = data.m_customBuffer2; - amountDelta = Mathf.Clamp(amountDelta, -customBuffer2, 0); - data.m_customBuffer2 = (ushort)(customBuffer2 + amountDelta); - data.m_outgoingProblemTimer = 0; - data.m_education1 = (byte)Mathf.Clamp(data.m_education1 + (-amountDelta + 99) / 100, 0, 255); - int priceInt = 0; - IndustryBuildingGetResourcePricePatch.Prefix(ref priceInt, material, data.Info.m_class.m_service); - var m_goodsSellPrice = priceInt / 100; - int num = (-amountDelta * m_goodsSellPrice + 50) / 100; - if (num != 0) - { - Singleton.instance.AddResource(EconomyManager.Resource.ResourcePrice, num, data.Info.m_class); - } - return false; - } - default: return true; - } - } - } + int customBuffer2 = data.m_customBuffer2; + amountDelta = Mathf.Clamp(amountDelta, -customBuffer2, 0); + data.m_customBuffer2 = (ushort)(customBuffer2 + amountDelta); + data.m_outgoingProblemTimer = 0; + data.m_education1 = (byte)Mathf.Clamp(data.m_education1 + (-amountDelta + 99) / 100, 0, 255); + int priceInt = 0; + IndustryBuildingGetResourcePricePatch.Prefix(ref priceInt, material, data.Info.m_class.m_service); + var m_goodsSellPrice = priceInt / 100; + int num = (-amountDelta * m_goodsSellPrice + 50) / 100; + if (num != 0) + { + Singleton.instance.AddResource(EconomyManager.Resource.ResourcePrice, num, data.Info.m_class); + } + return false; + } + default: return true; + } + } + } } diff --git a/Patch/MarketAIVisitorEnterPatch.cs b/Patch/MarketAIVisitorEnterPatch.cs index d62b890..d48e2d9 100644 --- a/Patch/MarketAIVisitorEnterPatch.cs +++ b/Patch/MarketAIVisitorEnterPatch.cs @@ -8,65 +8,65 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class MarketAIVisitorEnterPatch - { - public static MethodBase TargetMethod() - { - return typeof(MarketAI).GetMethod("VisitorEnter", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(uint) }, null); - } - public static bool Prefix(ushort buildingID, ref Building data, uint citizen) - { - CitizenManager citizenManager = Singleton.instance; - BuildingInfo buildingInfo = data.Info; - if ((citizenManager.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) - { - var consumptionMoney = -MainDataStore.maxGoodPurchase; - buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Shopping, ref consumptionMoney); - int priceInt = 0; - IndustryBuildingGetResourcePricePatch.Prefix(ref priceInt, TransferManager.TransferReason.Shopping, data.Info.m_class.m_service); - var m_goodsSellPrice = priceInt / 100; - MainDataStore.outsideTouristMoney += (consumptionMoney * m_goodsSellPrice); - } - else - { - ushort homeBuilding = citizenManager.m_citizens.m_buffer[citizen].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = citizenManager.m_citizens.m_buffer[citizen].GetContainingUnit((uint)citizen, citizenUnit, CitizenUnit.Flags.Home); - int priceInt = 0; - IndustryBuildingGetResourcePricePatch.Prefix(ref priceInt, TransferManager.TransferReason.Shopping, data.Info.m_class.m_service); - var m_goodsSellPrice = priceInt / 100; + [HarmonyPatch] + public class MarketAIVisitorEnterPatch + { + public static MethodBase TargetMethod() + { + return typeof(MarketAI).GetMethod("VisitorEnter", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(uint) }, null); + } + public static bool Prefix(ushort buildingID, ref Building data, uint citizen) + { + CitizenManager citizenManager = Singleton.instance; + BuildingInfo buildingInfo = data.Info; + if ((citizenManager.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None) + { + var consumptionMoney = -MainDataStore.maxGoodPurchase; + buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Shopping, ref consumptionMoney); + int priceInt = 0; + IndustryBuildingGetResourcePricePatch.Prefix(ref priceInt, TransferManager.TransferReason.Shopping, data.Info.m_class.m_service); + var m_goodsSellPrice = priceInt / 100; + MainDataStore.outsideTouristMoney += (consumptionMoney * m_goodsSellPrice); + } + else + { + ushort homeBuilding = citizenManager.m_citizens.m_buffer[citizen].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = citizenManager.m_citizens.m_buffer[citizen].GetContainingUnit((uint)citizen, citizenUnit, CitizenUnit.Flags.Home); + int priceInt = 0; + IndustryBuildingGetResourcePricePatch.Prefix(ref priceInt, TransferManager.TransferReason.Shopping, data.Info.m_class.m_service); + var m_goodsSellPrice = priceInt / 100; - if (containingUnit != 0) - { - //int goodAmount = (int)(-(CitizenUnitData.familyMoney[containingUnit]) / m_goodsSellPrice); - int goodAmount = -MainDataStore.maxGoodPurchase; + if (containingUnit != 0) + { + //int goodAmount = (int)(-(CitizenUnitData.familyMoney[containingUnit]) / m_goodsSellPrice); + int goodAmount = -MainDataStore.maxGoodPurchase; - if (goodAmount < 0) - { - buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Shopping, ref goodAmount); + if (goodAmount < 0) + { + buildingInfo.m_buildingAI.ModifyMaterialBuffer(buildingID, ref data, TransferManager.TransferReason.Shopping, ref goodAmount); - if (goodAmount != 0) - { - CitizenUnitData.familyGoods[containingUnit] = (ushort)(CitizenUnitData.familyGoods[containingUnit] - (goodAmount * 10)); - if (CitizenUnitData.familyGoods[containingUnit] > 2000) - { - citizenManager.m_citizens.m_buffer[citizen].m_flags &= ~Citizen.Flags.NeedGoods; - } - } - } - else - { - goodAmount = 0; - } + if (goodAmount != 0) + { + CitizenUnitData.familyGoods[containingUnit] = (ushort)(CitizenUnitData.familyGoods[containingUnit] - (goodAmount * 10)); + if (CitizenUnitData.familyGoods[containingUnit] > 2000) + { + citizenManager.m_citizens.m_buffer[citizen].m_flags &= ~Citizen.Flags.NeedGoods; + } + } + } + else + { + goodAmount = 0; + } - CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] + goodAmount * m_goodsSellPrice); - CitizenUnitData.familyMoney[containingUnit] = CitizenUnitData.familyMoney[containingUnit] + goodAmount * m_goodsSellPrice; - } - } + CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] + goodAmount * m_goodsSellPrice); + CitizenUnitData.familyMoney[containingUnit] = CitizenUnitData.familyMoney[containingUnit] + goodAmount * m_goodsSellPrice; + } + } - Singleton.instance.VisitorEnter(buildingID, ref data, citizen); - return false; - } - } + Singleton.instance.VisitorEnter(buildingID, ref data, citizen); + return false; + } + } } diff --git a/Patch/OfficeBuildingAIGetOutgoingTransferReasonPatch.cs b/Patch/OfficeBuildingAIGetOutgoingTransferReasonPatch.cs index 99245aa..5a41a59 100644 --- a/Patch/OfficeBuildingAIGetOutgoingTransferReasonPatch.cs +++ b/Patch/OfficeBuildingAIGetOutgoingTransferReasonPatch.cs @@ -5,17 +5,17 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class OfficeBuildingAIGetOutgoingTransferReasonPatch - { - public static MethodBase TargetMethod() - { - return typeof(OfficeBuildingAI).GetMethod("GetOutgoingTransferReason", BindingFlags.NonPublic | BindingFlags.Instance); - } - public static bool Prefix(ref TransferManager.TransferReason __result) - { - __result = TransferManager.TransferReason.None; - return false; - } - } + [HarmonyPatch] + public class OfficeBuildingAIGetOutgoingTransferReasonPatch + { + public static MethodBase TargetMethod() + { + return typeof(OfficeBuildingAI).GetMethod("GetOutgoingTransferReason", BindingFlags.NonPublic | BindingFlags.Instance); + } + public static bool Prefix(ref TransferManager.TransferReason __result) + { + __result = TransferManager.TransferReason.None; + return false; + } + } } diff --git a/Patch/OutsideConnectionAIModifyMaterialBufferPatch.cs b/Patch/OutsideConnectionAIModifyMaterialBufferPatch.cs index 22176de..a83cad1 100644 --- a/Patch/OutsideConnectionAIModifyMaterialBufferPatch.cs +++ b/Patch/OutsideConnectionAIModifyMaterialBufferPatch.cs @@ -6,48 +6,48 @@ namespace RealCity.Patch { - [HarmonyPatch] - [HarmonyBefore("pcfantasy.moreoutsideinteraction")] - public static class OutsideConnectionAIModifyMaterialBufferPatch - { - public static MethodBase TargetMethod() - { - return typeof(OutsideConnectionAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); - } - public static void Prefix(TransferManager.TransferReason material, ref int amountDelta) - { - switch (material) - { - case TransferManager.TransferReason.Oil: - case TransferManager.TransferReason.Ore: - case TransferManager.TransferReason.Coal: - case TransferManager.TransferReason.Petrol: - case TransferManager.TransferReason.Food: - case TransferManager.TransferReason.Grain: - case TransferManager.TransferReason.Lumber: - case TransferManager.TransferReason.Fish: - case TransferManager.TransferReason.Logs: - case TransferManager.TransferReason.Goods: - case TransferManager.TransferReason.LuxuryProducts: - case TransferManager.TransferReason.AnimalProducts: - case TransferManager.TransferReason.Flours: - case TransferManager.TransferReason.Petroleum: - case TransferManager.TransferReason.Plastics: - case TransferManager.TransferReason.Metals: - case TransferManager.TransferReason.Glass: - case TransferManager.TransferReason.PlanedTimber: - case TransferManager.TransferReason.Paper: - if (amountDelta < 0) - { - int transferSize = -amountDelta; - MainDataStore.outsideGovermentMoney += (transferSize * RealCityIndustryBuildingAI.GetResourcePrice(material) * MainDataStore.outsideGovermentProfitRatio); - MainDataStore.outsideTouristMoney += (transferSize * RealCityIndustryBuildingAI.GetResourcePrice(material) * MainDataStore.outsideCompanyProfitRatio * MainDataStore.outsideTouristSalaryProfitRatio); - //DebugLog.LogToFileOnly($"OutsideConnectionAIModifyMaterialBufferPatch: Find {material} amount = {amountDelta}"); - } - break; - default: - break; - } - } - } + [HarmonyPatch] + [HarmonyBefore("pcfantasy.moreoutsideinteraction")] + public static class OutsideConnectionAIModifyMaterialBufferPatch + { + public static MethodBase TargetMethod() + { + return typeof(OutsideConnectionAI).GetMethod("ModifyMaterialBuffer", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(TransferManager.TransferReason), typeof(int).MakeByRefType() }, null); + } + public static void Prefix(TransferManager.TransferReason material, ref int amountDelta) + { + switch (material) + { + case TransferManager.TransferReason.Oil: + case TransferManager.TransferReason.Ore: + case TransferManager.TransferReason.Coal: + case TransferManager.TransferReason.Petrol: + case TransferManager.TransferReason.Food: + case TransferManager.TransferReason.Grain: + case TransferManager.TransferReason.Lumber: + case TransferManager.TransferReason.Fish: + case TransferManager.TransferReason.Logs: + case TransferManager.TransferReason.Goods: + case TransferManager.TransferReason.LuxuryProducts: + case TransferManager.TransferReason.AnimalProducts: + case TransferManager.TransferReason.Flours: + case TransferManager.TransferReason.Petroleum: + case TransferManager.TransferReason.Plastics: + case TransferManager.TransferReason.Metals: + case TransferManager.TransferReason.Glass: + case TransferManager.TransferReason.PlanedTimber: + case TransferManager.TransferReason.Paper: + if (amountDelta < 0) + { + int transferSize = -amountDelta; + MainDataStore.outsideGovermentMoney += (transferSize * RealCityIndustryBuildingAI.GetResourcePrice(material) * MainDataStore.outsideGovermentProfitRatio); + MainDataStore.outsideTouristMoney += (transferSize * RealCityIndustryBuildingAI.GetResourcePrice(material) * MainDataStore.outsideCompanyProfitRatio * MainDataStore.outsideTouristSalaryProfitRatio); + //DebugLog.LogToFileOnly($"OutsideConnectionAIModifyMaterialBufferPatch: Find {material} amount = {amountDelta}"); + } + break; + default: + break; + } + } + } } diff --git a/Patch/PassengerCarAIArriveAtTargetPatch.cs b/Patch/PassengerCarAIArriveAtTargetPatch.cs index 7f4e73b..87a97bf 100644 --- a/Patch/PassengerCarAIArriveAtTargetPatch.cs +++ b/Patch/PassengerCarAIArriveAtTargetPatch.cs @@ -12,113 +12,113 @@ namespace RealCity.Patch { - [HarmonyPatch] - public static class PassengerCarAIArriveAtTargetPatch - { - public static MethodBase TargetMethod() - { - return typeof(PassengerCarAI).GetMethod("ArriveAtTarget", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType() }, null); - } - public static void Prefix(ushort vehicleID, ref Vehicle data) - { - GetVehicleRunningTiming(vehicleID, ref data); - } - public static void GetVehicleRunningTiming(ushort vehicleID, ref Vehicle vehicleData) - { - CitizenManager citizenManager = Singleton.instance; - ushort instanceID = GetDriverInstance(vehicleID, ref vehicleData); + [HarmonyPatch] + public static class PassengerCarAIArriveAtTargetPatch + { + public static MethodBase TargetMethod() + { + return typeof(PassengerCarAI).GetMethod("ArriveAtTarget", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType() }, null); + } + public static void Prefix(ushort vehicleID, ref Vehicle data) + { + GetVehicleRunningTiming(vehicleID, ref data); + } + public static void GetVehicleRunningTiming(ushort vehicleID, ref Vehicle vehicleData) + { + CitizenManager citizenManager = Singleton.instance; + ushort instanceID = GetDriverInstance(vehicleID, ref vehicleData); - if (instanceID != 0) - { - uint citizenID = citizenManager.m_instances.m_buffer[instanceID].m_citizen; - if (citizenID != 0) - { - if (!(citizenManager.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.DummyTraffic))) - { - if (!(citizenManager.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist))) - { - if (!IsOutSide(citizenManager.m_instances.m_buffer[instanceID].GetLastFramePosition())) - { - MainDataStore.totalCitizenDrivingTime += VehicleData.vehicleTransferTime[vehicleID]; - if (vehicleData.m_citizenUnits != 0) - { - CitizenData.citizenMoney[citizenID] -= VehicleData.vehicleTransferTime[vehicleID]; - } - } - else - { - MainDataStore.outsideTouristMoney -= VehicleData.vehicleTransferTime[vehicleID]; - if (RealCity.noPassengerCar) - { - if (vehicleData.m_citizenUnits != 0) - { - if (citizenManager.m_citizens.m_buffer[citizenID].m_vehicle == vehicleID) - { - Singleton.instance.ReleaseVehicle(vehicleID); - citizenManager.m_citizens.m_buffer[citizenID].m_vehicle = 0; - } - else if (citizenManager.m_citizens.m_buffer[citizenID].m_vehicle != 0) - { - DebugLog.LogToFileOnly($"Warning: citizen vehicleID = {citizenManager.m_citizens.m_buffer[citizenID].m_vehicle}, but vehicleID = {vehicleID}"); - Singleton.instance.ReleaseVehicle(citizenManager.m_citizens.m_buffer[citizenID].m_vehicle); - Singleton.instance.ReleaseVehicle(vehicleID); - citizenManager.m_citizens.m_buffer[citizenID].m_vehicle = 0; - } + if (instanceID != 0) + { + uint citizenID = citizenManager.m_instances.m_buffer[instanceID].m_citizen; + if (citizenID != 0) + { + if (!(citizenManager.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.DummyTraffic))) + { + if (!(citizenManager.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist))) + { + if (!IsOutSide(citizenManager.m_instances.m_buffer[instanceID].GetLastFramePosition())) + { + MainDataStore.totalCitizenDrivingTime += VehicleData.vehicleTransferTime[vehicleID]; + if (vehicleData.m_citizenUnits != 0) + { + CitizenData.citizenMoney[citizenID] -= VehicleData.vehicleTransferTime[vehicleID]; + } + } + else + { + MainDataStore.outsideTouristMoney -= VehicleData.vehicleTransferTime[vehicleID]; + if (RealCity.noPassengerCar) + { + if (vehicleData.m_citizenUnits != 0) + { + if (citizenManager.m_citizens.m_buffer[citizenID].m_vehicle == vehicleID) + { + Singleton.instance.ReleaseVehicle(vehicleID); + citizenManager.m_citizens.m_buffer[citizenID].m_vehicle = 0; + } + else if (citizenManager.m_citizens.m_buffer[citizenID].m_vehicle != 0) + { + DebugLog.LogToFileOnly($"Warning: citizen vehicleID = {citizenManager.m_citizens.m_buffer[citizenID].m_vehicle}, but vehicleID = {vehicleID}"); + Singleton.instance.ReleaseVehicle(citizenManager.m_citizens.m_buffer[citizenID].m_vehicle); + Singleton.instance.ReleaseVehicle(vehicleID); + citizenManager.m_citizens.m_buffer[citizenID].m_vehicle = 0; + } - if (citizenManager.m_citizens.m_buffer[citizenID].m_parkedVehicle != 0) - { - Singleton.instance.ReleaseParkedVehicle(citizenManager.m_citizens.m_buffer[citizenID].m_parkedVehicle); - citizenManager.m_citizens.m_buffer[citizenID].m_parkedVehicle = 0; - } - } - } - } - } - else - { - MainDataStore.outsideTouristMoney -= VehicleData.vehicleTransferTime[vehicleID]; - } - } - } - } - VehicleData.vehicleTransferTime[vehicleID] = 0; - } + if (citizenManager.m_citizens.m_buffer[citizenID].m_parkedVehicle != 0) + { + Singleton.instance.ReleaseParkedVehicle(citizenManager.m_citizens.m_buffer[citizenID].m_parkedVehicle); + citizenManager.m_citizens.m_buffer[citizenID].m_parkedVehicle = 0; + } + } + } + } + } + else + { + MainDataStore.outsideTouristMoney -= VehicleData.vehicleTransferTime[vehicleID]; + } + } + } + } + VehicleData.vehicleTransferTime[vehicleID] = 0; + } - public static bool IsOutSide(Vector3 pos) - { - if (pos.x > 8400 || pos.z > 8400 || pos.x < -8400 || pos.z < -8400) - return true; - return false; - } + public static bool IsOutSide(Vector3 pos) + { + if (pos.x > 8400 || pos.z > 8400 || pos.x < -8400 || pos.z < -8400) + return true; + return false; + } - public static ushort GetDriverInstance(ushort vehicleID, ref Vehicle data) - { - CitizenManager instance = Singleton.instance; - uint num = data.m_citizenUnits; - int num2 = 0; - while (num != 0u) - { - uint nextUnit = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_nextUnit; - for (int i = 0; i < 5; i++) - { - uint citizen = instance.m_units.m_buffer[(int)((UIntPtr)num)].GetCitizen(i); - if (citizen != 0u) - { - ushort instance2 = instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_instance; - if (instance2 != 0) - { - return instance2; - } - } - } - num = nextUnit; - if (++num2 > 524288) - { - CODebugBase.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); - break; - } - } - return 0; - } - } + public static ushort GetDriverInstance(ushort vehicleID, ref Vehicle data) + { + CitizenManager instance = Singleton.instance; + uint num = data.m_citizenUnits; + int num2 = 0; + while (num != 0u) + { + uint nextUnit = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_nextUnit; + for (int i = 0; i < 5; i++) + { + uint citizen = instance.m_units.m_buffer[(int)((UIntPtr)num)].GetCitizen(i); + if (citizen != 0u) + { + ushort instance2 = instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_instance; + if (instance2 != 0) + { + return instance2; + } + } + } + num = nextUnit; + if (++num2 > 524288) + { + CODebugBase.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); + break; + } + } + return 0; + } + } } diff --git a/Patch/PlayerBuildingAIGetResourceRatePatch.cs b/Patch/PlayerBuildingAIGetResourceRatePatch.cs index 1b7e900..c9b79cc 100644 --- a/Patch/PlayerBuildingAIGetResourceRatePatch.cs +++ b/Patch/PlayerBuildingAIGetResourceRatePatch.cs @@ -7,20 +7,20 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class PlayerBuildingAIGetResourceRatePatch - { - public static MethodBase TargetMethod() - { - return typeof(PlayerBuildingAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); - } - public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) - { - if (resource == EconomyManager.Resource.Maintenance) - { - float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); - __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); - } - } - } + [HarmonyPatch] + public class PlayerBuildingAIGetResourceRatePatch + { + public static MethodBase TargetMethod() + { + return typeof(PlayerBuildingAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); + } + public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) + { + if (resource == EconomyManager.Resource.Maintenance) + { + float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); + __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); + } + } + } } diff --git a/Patch/PlayerBuildingAISimulationStepPatch.cs b/Patch/PlayerBuildingAISimulationStepPatch.cs index bf0b3e6..4dd86f9 100644 --- a/Patch/PlayerBuildingAISimulationStepPatch.cs +++ b/Patch/PlayerBuildingAISimulationStepPatch.cs @@ -8,49 +8,49 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class PlayerBuildingAISimulationStepPatch - { - public static MethodBase TargetMethod() - { - return typeof(PlayerBuildingAI).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(Building.Frame).MakeByRefType() }, null); - } - public static void Postfix(ushort buildingID, ref Building buildingData) - { - ProcessZeroWorker(buildingID, ref buildingData); - } + [HarmonyPatch] + public class PlayerBuildingAISimulationStepPatch + { + public static MethodBase TargetMethod() + { + return typeof(PlayerBuildingAI).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(Building.Frame).MakeByRefType() }, null); + } + public static void Postfix(ushort buildingID, ref Building buildingData) + { + ProcessZeroWorker(buildingID, ref buildingData); + } - public static void ProcessZeroWorker(ushort buildingID, ref Building data) - { - if (data.m_flags.IsFlagSet(Building.Flags.Completed)) - { - int aliveWorkCount = 0; - int totalWorkCount = 0; - Citizen.BehaviourData behaviour = default; - RealCityCommonBuildingAI.InitDelegate(); - RealCityCommonBuildingAI.GetWorkBehaviour((PlayerBuildingAI)data.Info.m_buildingAI, buildingID, ref data, ref behaviour, ref aliveWorkCount, ref totalWorkCount); - int allWorkCount; - if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) - { - allWorkCount = RealCityResidentAI.TotalWorkCount(buildingID, data, true, true); - } - else - { - allWorkCount = RealCityResidentAI.TotalWorkCount(buildingID, data, true, false); - } + public static void ProcessZeroWorker(ushort buildingID, ref Building data) + { + if (data.m_flags.IsFlagSet(Building.Flags.Completed)) + { + int aliveWorkCount = 0; + int totalWorkCount = 0; + Citizen.BehaviourData behaviour = default; + RealCityCommonBuildingAI.InitDelegate(); + RealCityCommonBuildingAI.GetWorkBehaviour((PlayerBuildingAI)data.Info.m_buildingAI, buildingID, ref data, ref behaviour, ref aliveWorkCount, ref totalWorkCount); + int allWorkCount; + if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) + { + allWorkCount = RealCityResidentAI.TotalWorkCount(buildingID, data, true, true); + } + else + { + allWorkCount = RealCityResidentAI.TotalWorkCount(buildingID, data, true, false); + } - if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) - { - if (totalWorkCount == 0 && allWorkCount != 0) - { - int budget = Singleton.instance.GetBudget(data.Info.m_class); - int education3Salary = Math.Max((int)((budget * MainDataStore.govermentEducation3SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.8f)); - float num1 = education3Salary * allWorkCount; - Singleton.instance.FetchResource((EconomyManager.Resource)16, (int)num1, data.Info.m_class); - MainDataStore.outsideTouristMoney += (num1 * MainDataStore.outsideTouristSalaryProfitRatio); - } - } - } - } - } + if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) + { + if (totalWorkCount == 0 && allWorkCount != 0) + { + int budget = Singleton.instance.GetBudget(data.Info.m_class); + int education3Salary = Math.Max((int)((budget * MainDataStore.govermentEducation3SalaryFixed) / 100), (int)(MainDataStore.govermentSalary * 0.8f)); + float num1 = education3Salary * allWorkCount; + Singleton.instance.FetchResource((EconomyManager.Resource)16, (int)num1, data.Info.m_class); + MainDataStore.outsideTouristMoney += (num1 * MainDataStore.outsideTouristSalaryProfitRatio); + } + } + } + } + } } diff --git a/Patch/PrivateBuildingAISimulationStepActivePatch.cs b/Patch/PrivateBuildingAISimulationStepActivePatch.cs index 2deb46d..60a5e41 100644 --- a/Patch/PrivateBuildingAISimulationStepActivePatch.cs +++ b/Patch/PrivateBuildingAISimulationStepActivePatch.cs @@ -11,762 +11,762 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class PrivateBuildingAISimulationStepActivePatch - { - public static MethodBase TargetMethod() - { - return typeof(PrivateBuildingAI).GetMethod("SimulationStepActive", BindingFlags.NonPublic | BindingFlags.Instance); - } - - public static void Prefix(ref Building buildingData, ref ushort[] __state) - { - __state = new ushort[2]; - __state[0] = buildingData.m_customBuffer1; - __state[1] = buildingData.m_customBuffer2; - } - - public static void Postfix(ushort buildingID, ref Building buildingData) - { - ProcessLandFeeNoOffice(buildingData, buildingID); - if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) - { - CalculateBuildingMoneyAndSalary(buildingData, buildingID); - } - LimitCommericalBuildingAccess(buildingID, ref buildingData); - ProcessBuildingDataFinal(buildingID, ref buildingData); - } - - public static void ProcessBuildingDataFinal(ushort buildingID, ref Building buildingData) - { - if (RealCityPrivateBuildingAI.preBuidlingId > buildingID) - { - RealCityPrivateBuildingAI.allOfficeHighTechWorkCountFinal = RealCityPrivateBuildingAI.allOfficeHighTechWorkCount; - RealCityPrivateBuildingAI.allOfficeLevel1WorkCountFinal = RealCityPrivateBuildingAI.allOfficeLevel1WorkCount; - RealCityPrivateBuildingAI.allOfficeLevel2WorkCountFinal = RealCityPrivateBuildingAI.allOfficeLevel2WorkCount; - RealCityPrivateBuildingAI.allOfficeLevel3WorkCountFinal = RealCityPrivateBuildingAI.allOfficeLevel3WorkCount; - RealCityPrivateBuildingAI.profitBuildingCountFinal = RealCityPrivateBuildingAI.profitBuildingCount; - BuildingData.commBuildingNumFinal = BuildingData.commBuildingNum; - BuildingData.commBuildingNum = 0; - RealCityPrivateBuildingAI.profitBuildingCount = 0; - RealCityPrivateBuildingAI.allOfficeLevel1WorkCount = 0; - RealCityPrivateBuildingAI.allOfficeLevel2WorkCount = 0; - RealCityPrivateBuildingAI.allOfficeLevel3WorkCount = 0; - RealCityPrivateBuildingAI.allOfficeHighTechWorkCount = 0; - } - RealCityPrivateBuildingAI.preBuidlingId = buildingID; - if (buildingData.Info.m_class.m_service == ItemClass.Service.Residential) - { - BuildingData.buildingMoney[buildingID] = 0; - } - - float building_money = BuildingData.buildingMoney[buildingID]; - - if (buildingData.Info.m_class.m_service == ItemClass.Service.Industrial) - { - if (building_money < 0) - RealCityEconomyExtension.industrialLackMoneyCount++; - else - RealCityEconomyExtension.industrialEarnMoneyCount++; - } - - if (building_money < 0) - BuildingData.buildingMoneyThreat[buildingID] = 1.0f; - - switch (buildingData.Info.m_class.m_service) - { - case ItemClass.Service.Residential: - float familyMoney = GetResidentialBuildingAverageMoney(buildingData); - if (familyMoney < (MainDataStore.highWealth >> 1)) - BuildingData.buildingMoneyThreat[buildingID] = 1.0f - familyMoney / MainDataStore.highWealth; - else - BuildingData.buildingMoneyThreat[buildingID] = (((MainDataStore.highWealth << 1) - (MainDataStore.highWealth >> 1)) - familyMoney) / (MainDataStore.highWealth << 1); - - if (BuildingData.buildingMoneyThreat[buildingID] < 0) - BuildingData.buildingMoneyThreat[buildingID] = 0; - break; - case ItemClass.Service.Commercial: - case ItemClass.Service.Industrial: - case ItemClass.Service.Office: - float averageBuildingSalary = BuildingUI.CaculateEmployeeOutcome(buildingData, out _); - - if (MainDataStore.citizenCount > 0.0) - { - float averageCitySalary = MainDataStore.citizenSalaryTotal / MainDataStore.citizenCount; - float salaryFactor = averageBuildingSalary / averageCitySalary; - if (salaryFactor > 3f) - salaryFactor = 3f; - else if (salaryFactor < 0.0f) - salaryFactor = 0.0f; - - BuildingData.buildingMoneyThreat[buildingID] = (1.0f - salaryFactor / 3f); - } - else - BuildingData.buildingMoneyThreat[buildingID] = 1.0f; - - break; - } - - if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) - { - //get all commercial building for resident. - if (buildingData.m_customBuffer2 > 2000) - { - BuildingData.commBuildingNum++; - BuildingData.commBuildingID[BuildingData.commBuildingNum] = buildingID; - } - if (BuildingData.buildingMoney[buildingID] < 0) - { - RealCityEconomyExtension.commercialLackMoneyCount++; - } - else - { - RealCityEconomyExtension.commercialEarnMoneyCount++; - } - } - - if (buildingData.m_problems == Notification.Problem.None) - { - //mark no good - if ((buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) && (RealCity.debugMode)) - { - Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoGoods); - if (buildingData.m_customBuffer2 < 500) - { - problem = Notification.AddProblems(problem, Notification.Problem.NoGoods | Notification.Problem.MajorProblem); - } - else if (buildingData.m_customBuffer2 < 1000) - { - problem = Notification.AddProblems(problem, Notification.Problem.NoGoods); - } - else - { - problem = Notification.Problem.None; - } - buildingData.m_problems = problem; - } - } - } - - public static float GetResidentialBuildingAverageMoney(Building buildingData) - { - CitizenManager instance = Singleton.instance; - uint citzenUnit = buildingData.m_citizenUnits; - int unitCount = 0; - long totalMoney = 0; - float averageMoney = 0; - while (citzenUnit != 0u) - { - if ((ushort)(instance.m_units.m_buffer[citzenUnit].m_flags & CitizenUnit.Flags.Home) != 0) - { - if ((instance.m_units.m_buffer[citzenUnit].m_citizen0 != 0) || (instance.m_units.m_buffer[citzenUnit].m_citizen1 != 0) || (instance.m_units.m_buffer[citzenUnit].m_citizen2 != 0) || (instance.m_units.m_buffer[citzenUnit].m_citizen3 != 0) || (instance.m_units.m_buffer[citzenUnit].m_citizen4 != 0)) - { - unitCount++; - totalMoney += (long)CitizenUnitData.familyMoney[citzenUnit]; - } - } - citzenUnit = instance.m_units.m_buffer[citzenUnit].m_nextUnit; - if (++unitCount > 524288) - { - CODebugBase.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); - break; - } - } - - if (unitCount != 0) - { - averageMoney = (float)totalMoney / unitCount; - } - - return averageMoney; - } - - public static void LimitCommericalBuildingAccess(ushort buildingID, ref Building buildingData) - { - if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) - { - Citizen.BehaviourData behaviour = default; - int aliveVisitCount = 0; - int totalVisitCount = 0; - RealCityCommercialBuildingAI.InitDelegate(); - RealCityCommercialBuildingAI.GetVisitBehaviour((CommercialBuildingAI)buildingData.Info.m_buildingAI, buildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount); - var amount = buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount; - var AI = buildingData.Info.m_buildingAI as CommercialBuildingAI; - var maxcount = AI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer(buildingID), buildingData.m_width, buildingData.m_length); - if ((amount <= 0) || (maxcount <= totalVisitCount)) - { - buildingData.m_flags &= ~Building.Flags.Active; - } - - if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) - { - //Remove citizen which already have goods - CitizenManager instance = Singleton.instance; - uint num = buildingData.m_citizenUnits; - int num2 = 0; - while (num != 0u) - { - if ((ushort)(instance.m_units.m_buffer[(int)((UIntPtr)num)].m_flags & CitizenUnit.Flags.Visit) != 0) - { - var citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen0; - if (citizenID != 0u) - { - ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); - if (CitizenUnitData.familyGoods[containingUnit] > 2000) - { - if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) - { - BuildingManager instance1 = Singleton.instance; - instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); - return; - } - } - } - citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen1; - if (citizenID != 0u) - { - ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); - if (CitizenUnitData.familyGoods[containingUnit] > 2000) - { - if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) - { - BuildingManager instance1 = Singleton.instance; - instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); - return; - } - } - } - citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen2; - if (citizenID != 0u) - { - ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); - if (CitizenUnitData.familyGoods[containingUnit] > 2000) - { - if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) - { - BuildingManager instance1 = Singleton.instance; - instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); - return; - } - } - } - citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen3; - if (citizenID != 0u) - { - ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); - if (CitizenUnitData.familyGoods[containingUnit] > 2000) - { - if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) - { - BuildingManager instance1 = Singleton.instance; - instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); - return; - } - } - } - citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen4; - if (citizenID != 0u) - { - ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); - if (CitizenUnitData.familyGoods[containingUnit] > 2000) - { - if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) - { - BuildingManager instance1 = Singleton.instance; - instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); - return; - } - } - } - } - num = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_nextUnit; - if (++num2 > 524288) - { - CODebugBase.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); - break; - } - } - } - } - } - - public static void CalculateBuildingMoneyAndSalary(Building building, ushort buildingID) - { - if (BuildingData.buildingMoney[buildingID] > MainDataStore.maxBuildingMoneyLimit) - { - BuildingData.buildingMoney[buildingID] = MainDataStore.maxBuildingMoneyLimit; - } - else if (BuildingData.buildingMoney[buildingID] < -MainDataStore.maxBuildingMoneyLimit) - { - BuildingData.buildingMoney[buildingID] = -MainDataStore.maxBuildingMoneyLimit; - } - - - if (building.Info.m_class.m_service == ItemClass.Service.Industrial || building.Info.m_class.m_service == ItemClass.Service.Commercial || building.Info.m_class.m_service == ItemClass.Service.Office) - { - Citizen.BehaviourData behaviourData = default; - int aliveWorkerCount = 0; - int totalWorkerCount = 0; - RealCityCommonBuildingAI.InitDelegate(); - RealCityCommonBuildingAI.GetWorkBehaviour((CommonBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); - float bossTake = 0; - float investToOffice = 0; - float profitShare = 0; - - switch (building.Info.m_class.m_subService) - { - case ItemClass.SubService.OfficeGeneric: - case ItemClass.SubService.OfficeHightech: - profitShare = 1f; break; - case ItemClass.SubService.IndustrialFarming: - case ItemClass.SubService.IndustrialForestry: - if (building.Info.m_buildingAI is IndustrialExtractorAI) - { - bossTake = MainDataStore.bossRatioInduExtractor; - investToOffice = MainDataStore.investRatioInduExtractor; - profitShare = MainDataStore.profitShareRatioInduExtractor; - } - else - { - bossTake = MainDataStore.bossRatioInduOther; - investToOffice = MainDataStore.investRatioInduOther; - profitShare = MainDataStore.profitShareRatioInduOther; - } - break; - case ItemClass.SubService.IndustrialOil: - case ItemClass.SubService.IndustrialOre: - bossTake = MainDataStore.bossRatioInduOther; - investToOffice = MainDataStore.investRatioInduOther; - profitShare = MainDataStore.profitShareRatioInduOther; break; - case ItemClass.SubService.IndustrialGeneric: - if (building.Info.m_class.m_level == ItemClass.Level.Level1) - { - bossTake = MainDataStore.bossRatioInduLevel1; - investToOffice = MainDataStore.investRatioInduLevel1; - profitShare = MainDataStore.profitShareRatioInduLevel1; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level2) - { - bossTake = MainDataStore.bossRatioInduLevel2; - investToOffice = MainDataStore.investRatioInduLevel2; - profitShare = MainDataStore.profitShareRatioInduLevel2; - } - else - { - bossTake = MainDataStore.bossRatioInduLevel3; - investToOffice = MainDataStore.investRatioInduLevel3; - profitShare = MainDataStore.profitShareRatioInduLevel3; - } - break; - case ItemClass.SubService.CommercialHigh: - case ItemClass.SubService.CommercialLow: - if (building.Info.m_class.m_level == ItemClass.Level.Level1) - { - bossTake = MainDataStore.bossRatioCommLevel1; - investToOffice = MainDataStore.investRatioCommLevel1; - profitShare = MainDataStore.profitShareRatioCommLevel1; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level2) - { - bossTake = MainDataStore.bossRatioCommLevel2; - investToOffice = MainDataStore.investRatioCommLevel2; - profitShare = MainDataStore.profitShareRatioCommLevel2; - } - else - { - bossTake = MainDataStore.bossRatioCommLevel3; - investToOffice = MainDataStore.investRatioCommLevel3; - profitShare = MainDataStore.profitShareRatioCommLevel1; - } - break; - case ItemClass.SubService.CommercialTourist: - bossTake = MainDataStore.bossRatioCommTou; - investToOffice = MainDataStore.investRatioCommTou; - profitShare = MainDataStore.profitShareRatioCommTou; - break; - case ItemClass.SubService.CommercialLeisure: - bossTake = MainDataStore.bossRatioCommOther; - investToOffice = MainDataStore.investRatioCommOther; - profitShare = MainDataStore.profitShareRatioCommOther; break; - case ItemClass.SubService.CommercialEco: - bossTake = MainDataStore.bossRatioCommECO; - investToOffice = MainDataStore.investRatioCommECO; - profitShare = MainDataStore.profitShareRatioCommECO; break; - } - // boss take and return to office - if (BuildingData.buildingMoney[buildingID] > 0) - { - //Reduce Boss fee - long investToOfficeFee = (long)(BuildingData.buildingMoney[buildingID] * investToOffice); - long bossTakeFee = (long)(BuildingData.buildingMoney[buildingID] * bossTake); - if (building.Info.m_class.m_service == ItemClass.Service.Commercial) - { - //Commercial have help tourism - MainDataStore.outsideTouristMoney += ((bossTakeFee - investToOfficeFee) * MainDataStore.outsideCompanyProfitRatio * MainDataStore.outsideTouristSalaryProfitRatio); - } - RealCityPrivateBuildingAI.profitBuildingMoney += investToOfficeFee; - BuildingData.buildingMoney[buildingID] -= bossTakeFee; - } - - if (building.Info.m_class.m_service == ItemClass.Service.Office) - { - float allOfficeWorker = RealCityPrivateBuildingAI.allOfficeLevel1WorkCountFinal + RealCityPrivateBuildingAI.allOfficeLevel2WorkCountFinal + RealCityPrivateBuildingAI.allOfficeLevel3WorkCountFinal + RealCityPrivateBuildingAI.allOfficeHighTechWorkCountFinal; - float averageOfficeSalary = 0; - if (allOfficeWorker != 0) - { - averageOfficeSalary = (RealCityPrivateBuildingAI.profitBuildingMoneyFinal / allOfficeWorker); - } - - if (building.Info.m_class.m_subService == ItemClass.SubService.OfficeGeneric) - { - if (building.Info.m_class.m_level == ItemClass.Level.Level1) - { - BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.6f; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level2) - { - BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.8f; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level3) - { - BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 1f; - } - } - else if (building.Info.m_class.m_subService == ItemClass.SubService.OfficeHightech) - { - BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.75f; - } - - ProcessLandFeeOffice(building, buildingID, totalWorkerCount); - } - - //Calculate building salary - int buildingAsset = (int)(BuildingData.buildingMoney[buildingID] + building.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(RealCityPrivateBuildingAI.GetIncomingProductionType(buildingID, building))); - int salary = 0; - if ((buildingAsset > 0) && (totalWorkerCount != 0)) - { - salary = (int)(buildingAsset * profitShare / totalWorkerCount); - switch (building.Info.m_class.m_subService) - { - case ItemClass.SubService.IndustrialFarming: - case ItemClass.SubService.IndustrialForestry: - case ItemClass.SubService.IndustrialOil: - case ItemClass.SubService.IndustrialOre: - salary = Math.Min(salary, MainDataStore.salaryInduOtherMax); break; - case ItemClass.SubService.IndustrialGeneric: - if (building.Info.m_class.m_level == ItemClass.Level.Level1) - salary = Math.Min(salary, MainDataStore.salaryInduLevel1Max); - else if (building.Info.m_class.m_level == ItemClass.Level.Level2) - salary = Math.Min(salary, MainDataStore.salaryInduLevel2Max); - else - salary = Math.Min(salary, MainDataStore.salaryInduLevel3Max); - break; - case ItemClass.SubService.CommercialHigh: - case ItemClass.SubService.CommercialLow: - if (building.Info.m_class.m_level == ItemClass.Level.Level1) - salary = Math.Min(salary, MainDataStore.salaryCommLevel1Max); - else if (building.Info.m_class.m_level == ItemClass.Level.Level2) - salary = Math.Min(salary, MainDataStore.salaryCommLevel2Max); - else - salary = Math.Min(salary, MainDataStore.salaryCommLevel3Max); - break; - case ItemClass.SubService.CommercialTourist: - salary = Math.Min(salary, MainDataStore.salaryCommTouMax); break; - case ItemClass.SubService.CommercialLeisure: - salary = Math.Min(salary, MainDataStore.salaryCommOtherMax); break; - case ItemClass.SubService.CommercialEco: - salary = Math.Min(salary, MainDataStore.salaryCommECOMax); break; - } - } - - if (salary > 0) - BuildingData.buildingWorkCount[buildingID] = salary; - else - BuildingData.buildingWorkCount[buildingID] = 0; - } - else - { - //resident building - ItemClass @class = building.Info.m_class; - int incomeAccumulation = 0; - DistrictManager instance = Singleton.instance; - byte district = instance.GetDistrict(building.m_position); - DistrictPolicies.Taxation taxationPolicies = instance.m_districts.m_buffer[district].m_taxationPolicies; - if (@class.m_subService == ItemClass.SubService.ResidentialLow) - { - switch (@class.m_level) - { - case ItemClass.Level.Level1: - incomeAccumulation = MainDataStore.residentLowLevel1Rent; - break; - case ItemClass.Level.Level2: - incomeAccumulation = MainDataStore.residentLowLevel2Rent; - break; - case ItemClass.Level.Level3: - incomeAccumulation = MainDataStore.residentLowLevel3Rent; - break; - case ItemClass.Level.Level4: - incomeAccumulation = MainDataStore.residentLowLevel4Rent; - break; - case ItemClass.Level.Level5: - incomeAccumulation = MainDataStore.residentLowLevel5Rent; - break; - } - } - else if (@class.m_subService == ItemClass.SubService.ResidentialLowEco) - { - switch (@class.m_level) - { - case ItemClass.Level.Level1: - incomeAccumulation = MainDataStore.residentLowLevel1Rent << 1; - break; - case ItemClass.Level.Level2: - incomeAccumulation = MainDataStore.residentLowLevel2Rent << 1; - break; - case ItemClass.Level.Level3: - incomeAccumulation = MainDataStore.residentLowLevel3Rent << 1; - break; - case ItemClass.Level.Level4: - incomeAccumulation = MainDataStore.residentLowLevel4Rent << 1; - break; - case ItemClass.Level.Level5: - incomeAccumulation = MainDataStore.residentLowLevel5Rent << 1; - break; - } - } - else if (@class.m_subService == ItemClass.SubService.ResidentialHigh) - { - switch (@class.m_level) - { - case ItemClass.Level.Level1: - incomeAccumulation = MainDataStore.residentHighLevel1Rent; - break; - case ItemClass.Level.Level2: - incomeAccumulation = MainDataStore.residentHighLevel2Rent; - break; - case ItemClass.Level.Level3: - incomeAccumulation = MainDataStore.residentHighLevel3Rent; - break; - case ItemClass.Level.Level4: - incomeAccumulation = MainDataStore.residentHighLevel4Rent; - break; - case ItemClass.Level.Level5: - incomeAccumulation = MainDataStore.residentHighLevel5Rent; - break; - } - } - else - { - switch (@class.m_level) - { - case ItemClass.Level.Level1: - incomeAccumulation = MainDataStore.residentHighLevel1Rent << 1; - break; - case ItemClass.Level.Level2: - incomeAccumulation = MainDataStore.residentHighLevel2Rent << 1; - break; - case ItemClass.Level.Level3: - incomeAccumulation = MainDataStore.residentHighLevel3Rent << 1; - break; - case ItemClass.Level.Level4: - incomeAccumulation = MainDataStore.residentHighLevel4Rent << 1; - break; - case ItemClass.Level.Level5: - incomeAccumulation = MainDataStore.residentHighLevel5Rent << 1; - break; - } - } - int num2; - num2 = Singleton.instance.GetTaxRate(@class, taxationPolicies); - incomeAccumulation = (int)((num2 * incomeAccumulation) / 100f); - BuildingData.buildingWorkCount[buildingID] = incomeAccumulation; - } - } - - public static void ProcessLandFeeOffice(Building building, ushort buildingID, int totalWorkerCount) - { - DistrictManager instance = Singleton.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; - - int landFee = totalWorkerCount * 10; - int taxRate; - taxRate = Singleton.instance.GetTaxRate(building.Info.m_class, taxationPolicies); - - if (instance.IsPolicyLoaded(DistrictPolicies.Policies.ExtraInsulation)) - { - if ((servicePolicies & DistrictPolicies.Services.ExtraInsulation) != DistrictPolicies.Services.None) - { - landFee = landFee * 95 / 100; - } - } - if ((servicePolicies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None) - { - landFee = landFee * 95 / 100; - } - - if (BuildingData.buildingMoney[buildingID] >= 0) - { - BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (float)(landFee * taxRate) / 100); - Singleton.instance.AddPrivateIncome(landFee, building.Info.m_class.m_service, building.Info.m_class.m_subService, building.Info.m_class.m_level, taxRate * 100); - } - } - - public static void ProcessLandFeeNoOffice(Building building, ushort buildingID) - { - DistrictManager instance = Singleton.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; - - int landFee; - GetLandRentNoOffice(out landFee, building, buildingID); - int taxRate; - - taxRate = Singleton.instance.GetTaxRate(building.Info.m_class, taxationPolicies); - - if (((taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure) != DistrictPolicies.Taxation.None) && (building.Info.m_class.m_subService == ItemClass.SubService.CommercialLeisure)) - { - landFee = 0; - } - - if (instance.IsPolicyLoaded(DistrictPolicies.Policies.ExtraInsulation)) - { - if ((servicePolicies & DistrictPolicies.Services.ExtraInsulation) != DistrictPolicies.Services.None) - { - landFee = landFee * 95 / 100; - } - } - if ((servicePolicies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None) - { - landFee = landFee * 95 / 100; - } - - if (BuildingData.buildingMoney[buildingID] <= ((landFee * taxRate) / 100f)) - { - landFee = 0; - } - else - { - RealCityPrivateBuildingAI.profitBuildingCount++; - } - - if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) - { - Singleton.instance.AddPrivateIncome(landFee, building.Info.m_class.m_service, building.Info.m_class.m_subService, building.Info.m_class.m_level, taxRate * 100); - if ((building.Info.m_class.m_service == ItemClass.Service.Commercial) || (building.Info.m_class.m_service == ItemClass.Service.Industrial)) - { - BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (float)(landFee * taxRate) / 100); - } - } - } - - public static void GetLandRentNoOffice(out int landRent, Building building, ushort buildingID) - { - ItemClass @class = building.Info.m_class; - landRent = 0; - Citizen.BehaviourData behaviourData = default; - int aliveWorkerCount = 0; - int totalWorkerCount = 0; - ItemClass.SubService subService = @class.m_subService; - RealCityCommonBuildingAI.InitDelegate(); - switch (subService) - { - case ItemClass.SubService.OfficeHightech: - RealCityCommonBuildingAI.GetWorkBehaviour((OfficeBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); - RealCityPrivateBuildingAI.allOfficeHighTechWorkCount += totalWorkerCount; - break; - case ItemClass.SubService.OfficeGeneric: - RealCityCommonBuildingAI.GetWorkBehaviour((OfficeBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); - if (building.Info.m_class.m_level == ItemClass.Level.Level1) - { - RealCityPrivateBuildingAI.allOfficeLevel1WorkCount += totalWorkerCount; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level2) - { - RealCityPrivateBuildingAI.allOfficeLevel2WorkCount += totalWorkerCount; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level3) - { - RealCityPrivateBuildingAI.allOfficeLevel3WorkCount += totalWorkerCount; - } - break; - case ItemClass.SubService.IndustrialFarming: - landRent = MainDataStore.induFarm; - break; - case ItemClass.SubService.IndustrialForestry: - landRent = MainDataStore.induForest; - break; - case ItemClass.SubService.IndustrialOil: - landRent = MainDataStore.induOil; - break; - case ItemClass.SubService.IndustrialOre: - landRent = MainDataStore.induOre; - break; - case ItemClass.SubService.IndustrialGeneric: - if (building.Info.m_class.m_level == ItemClass.Level.Level1) - { - landRent = MainDataStore.induGenLevel1; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level2) - { - landRent = MainDataStore.induGenLevel2; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level3) - { - landRent = MainDataStore.induGenLevel3; - } - break; - case ItemClass.SubService.CommercialHigh: - if (building.Info.m_class.m_level == ItemClass.Level.Level1) - { - landRent = MainDataStore.commHighLevel1; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level2) - { - landRent = MainDataStore.commHighLevel2; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level3) - { - landRent = MainDataStore.commHighLevel3; - } - break; - case ItemClass.SubService.CommercialLow: - if (building.Info.m_class.m_level == ItemClass.Level.Level1) - { - landRent = MainDataStore.commLowLevel1; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level2) - { - landRent = MainDataStore.commLowLevel2; - } - else if (building.Info.m_class.m_level == ItemClass.Level.Level3) - { - landRent = MainDataStore.commLowLevel3; - } - break; - case ItemClass.SubService.CommercialLeisure: - landRent = MainDataStore.commLeisure; - break; - case ItemClass.SubService.CommercialTourist: - landRent = MainDataStore.commTourist; - break; - case ItemClass.SubService.CommercialEco: - landRent = MainDataStore.commEco; - break; - default: break; - } - } - } + [HarmonyPatch] + public class PrivateBuildingAISimulationStepActivePatch + { + public static MethodBase TargetMethod() + { + return typeof(PrivateBuildingAI).GetMethod("SimulationStepActive", BindingFlags.NonPublic | BindingFlags.Instance); + } + + public static void Prefix(ref Building buildingData, ref ushort[] __state) + { + __state = new ushort[2]; + __state[0] = buildingData.m_customBuffer1; + __state[1] = buildingData.m_customBuffer2; + } + + public static void Postfix(ushort buildingID, ref Building buildingData) + { + ProcessLandFeeNoOffice(buildingData, buildingID); + if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) + { + CalculateBuildingMoneyAndSalary(buildingData, buildingID); + } + LimitCommericalBuildingAccess(buildingID, ref buildingData); + ProcessBuildingDataFinal(buildingID, ref buildingData); + } + + public static void ProcessBuildingDataFinal(ushort buildingID, ref Building buildingData) + { + if (RealCityPrivateBuildingAI.preBuidlingId > buildingID) + { + RealCityPrivateBuildingAI.allOfficeHighTechWorkCountFinal = RealCityPrivateBuildingAI.allOfficeHighTechWorkCount; + RealCityPrivateBuildingAI.allOfficeLevel1WorkCountFinal = RealCityPrivateBuildingAI.allOfficeLevel1WorkCount; + RealCityPrivateBuildingAI.allOfficeLevel2WorkCountFinal = RealCityPrivateBuildingAI.allOfficeLevel2WorkCount; + RealCityPrivateBuildingAI.allOfficeLevel3WorkCountFinal = RealCityPrivateBuildingAI.allOfficeLevel3WorkCount; + RealCityPrivateBuildingAI.profitBuildingCountFinal = RealCityPrivateBuildingAI.profitBuildingCount; + BuildingData.commBuildingNumFinal = BuildingData.commBuildingNum; + BuildingData.commBuildingNum = 0; + RealCityPrivateBuildingAI.profitBuildingCount = 0; + RealCityPrivateBuildingAI.allOfficeLevel1WorkCount = 0; + RealCityPrivateBuildingAI.allOfficeLevel2WorkCount = 0; + RealCityPrivateBuildingAI.allOfficeLevel3WorkCount = 0; + RealCityPrivateBuildingAI.allOfficeHighTechWorkCount = 0; + } + RealCityPrivateBuildingAI.preBuidlingId = buildingID; + if (buildingData.Info.m_class.m_service == ItemClass.Service.Residential) + { + BuildingData.buildingMoney[buildingID] = 0; + } + + float building_money = BuildingData.buildingMoney[buildingID]; + + if (buildingData.Info.m_class.m_service == ItemClass.Service.Industrial) + { + if (building_money < 0) + RealCityEconomyExtension.industrialLackMoneyCount++; + else + RealCityEconomyExtension.industrialEarnMoneyCount++; + } + + if (building_money < 0) + BuildingData.buildingMoneyThreat[buildingID] = 1.0f; + + switch (buildingData.Info.m_class.m_service) + { + case ItemClass.Service.Residential: + float familyMoney = GetResidentialBuildingAverageMoney(buildingData); + if (familyMoney < (MainDataStore.highWealth >> 1)) + BuildingData.buildingMoneyThreat[buildingID] = 1.0f - familyMoney / MainDataStore.highWealth; + else + BuildingData.buildingMoneyThreat[buildingID] = (((MainDataStore.highWealth << 1) - (MainDataStore.highWealth >> 1)) - familyMoney) / (MainDataStore.highWealth << 1); + + if (BuildingData.buildingMoneyThreat[buildingID] < 0) + BuildingData.buildingMoneyThreat[buildingID] = 0; + break; + case ItemClass.Service.Commercial: + case ItemClass.Service.Industrial: + case ItemClass.Service.Office: + float averageBuildingSalary = BuildingUI.CaculateEmployeeOutcome(buildingData, out _); + + if (MainDataStore.citizenCount > 0.0) + { + float averageCitySalary = MainDataStore.citizenSalaryTotal / MainDataStore.citizenCount; + float salaryFactor = averageBuildingSalary / averageCitySalary; + if (salaryFactor > 3f) + salaryFactor = 3f; + else if (salaryFactor < 0.0f) + salaryFactor = 0.0f; + + BuildingData.buildingMoneyThreat[buildingID] = (1.0f - salaryFactor / 3f); + } + else + BuildingData.buildingMoneyThreat[buildingID] = 1.0f; + + break; + } + + if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) + { + //get all commercial building for resident. + if (buildingData.m_customBuffer2 > 2000) + { + BuildingData.commBuildingNum++; + BuildingData.commBuildingID[BuildingData.commBuildingNum] = buildingID; + } + if (BuildingData.buildingMoney[buildingID] < 0) + { + RealCityEconomyExtension.commercialLackMoneyCount++; + } + else + { + RealCityEconomyExtension.commercialEarnMoneyCount++; + } + } + + if (buildingData.m_problems == Notification.Problem.None) + { + //mark no good + if ((buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) && (RealCity.debugMode)) + { + Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoGoods); + if (buildingData.m_customBuffer2 < 500) + { + problem = Notification.AddProblems(problem, Notification.Problem.NoGoods | Notification.Problem.MajorProblem); + } + else if (buildingData.m_customBuffer2 < 1000) + { + problem = Notification.AddProblems(problem, Notification.Problem.NoGoods); + } + else + { + problem = Notification.Problem.None; + } + buildingData.m_problems = problem; + } + } + } + + public static float GetResidentialBuildingAverageMoney(Building buildingData) + { + CitizenManager instance = Singleton.instance; + uint citzenUnit = buildingData.m_citizenUnits; + int unitCount = 0; + long totalMoney = 0; + float averageMoney = 0; + while (citzenUnit != 0u) + { + if ((ushort)(instance.m_units.m_buffer[citzenUnit].m_flags & CitizenUnit.Flags.Home) != 0) + { + if ((instance.m_units.m_buffer[citzenUnit].m_citizen0 != 0) || (instance.m_units.m_buffer[citzenUnit].m_citizen1 != 0) || (instance.m_units.m_buffer[citzenUnit].m_citizen2 != 0) || (instance.m_units.m_buffer[citzenUnit].m_citizen3 != 0) || (instance.m_units.m_buffer[citzenUnit].m_citizen4 != 0)) + { + unitCount++; + totalMoney += (long)CitizenUnitData.familyMoney[citzenUnit]; + } + } + citzenUnit = instance.m_units.m_buffer[citzenUnit].m_nextUnit; + if (++unitCount > 524288) + { + CODebugBase.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); + break; + } + } + + if (unitCount != 0) + { + averageMoney = (float)totalMoney / unitCount; + } + + return averageMoney; + } + + public static void LimitCommericalBuildingAccess(ushort buildingID, ref Building buildingData) + { + if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) + { + Citizen.BehaviourData behaviour = default; + int aliveVisitCount = 0; + int totalVisitCount = 0; + RealCityCommercialBuildingAI.InitDelegate(); + RealCityCommercialBuildingAI.GetVisitBehaviour((CommercialBuildingAI)buildingData.Info.m_buildingAI, buildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount); + var amount = buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount; + var AI = buildingData.Info.m_buildingAI as CommercialBuildingAI; + var maxcount = AI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer(buildingID), buildingData.m_width, buildingData.m_length); + if ((amount <= 0) || (maxcount <= totalVisitCount)) + { + buildingData.m_flags &= ~Building.Flags.Active; + } + + if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) + { + //Remove citizen which already have goods + CitizenManager instance = Singleton.instance; + uint num = buildingData.m_citizenUnits; + int num2 = 0; + while (num != 0u) + { + if ((ushort)(instance.m_units.m_buffer[(int)((UIntPtr)num)].m_flags & CitizenUnit.Flags.Visit) != 0) + { + var citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen0; + if (citizenID != 0u) + { + ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); + if (CitizenUnitData.familyGoods[containingUnit] > 2000) + { + if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) + { + BuildingManager instance1 = Singleton.instance; + instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); + return; + } + } + } + citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen1; + if (citizenID != 0u) + { + ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); + if (CitizenUnitData.familyGoods[containingUnit] > 2000) + { + if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) + { + BuildingManager instance1 = Singleton.instance; + instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); + return; + } + } + } + citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen2; + if (citizenID != 0u) + { + ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); + if (CitizenUnitData.familyGoods[containingUnit] > 2000) + { + if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) + { + BuildingManager instance1 = Singleton.instance; + instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); + return; + } + } + } + citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen3; + if (citizenID != 0u) + { + ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); + if (CitizenUnitData.familyGoods[containingUnit] > 2000) + { + if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) + { + BuildingManager instance1 = Singleton.instance; + instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); + return; + } + } + } + citizenID = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_citizen4; + if (citizenID != 0u) + { + ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); + if (CitizenUnitData.familyGoods[containingUnit] > 2000) + { + if (!instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Tourist)) + { + BuildingManager instance1 = Singleton.instance; + instance.m_citizens.m_buffer[citizenID].RemoveFromUnits(citizenID, instance1.m_buildings.m_buffer[buildingID].m_citizenUnits, CitizenUnit.Flags.Visit); + return; + } + } + } + } + num = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_nextUnit; + if (++num2 > 524288) + { + CODebugBase.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); + break; + } + } + } + } + } + + public static void CalculateBuildingMoneyAndSalary(Building building, ushort buildingID) + { + if (BuildingData.buildingMoney[buildingID] > MainDataStore.maxBuildingMoneyLimit) + { + BuildingData.buildingMoney[buildingID] = MainDataStore.maxBuildingMoneyLimit; + } + else if (BuildingData.buildingMoney[buildingID] < -MainDataStore.maxBuildingMoneyLimit) + { + BuildingData.buildingMoney[buildingID] = -MainDataStore.maxBuildingMoneyLimit; + } + + + if (building.Info.m_class.m_service == ItemClass.Service.Industrial || building.Info.m_class.m_service == ItemClass.Service.Commercial || building.Info.m_class.m_service == ItemClass.Service.Office) + { + Citizen.BehaviourData behaviourData = default; + int aliveWorkerCount = 0; + int totalWorkerCount = 0; + RealCityCommonBuildingAI.InitDelegate(); + RealCityCommonBuildingAI.GetWorkBehaviour((CommonBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); + float bossTake = 0; + float investToOffice = 0; + float profitShare = 0; + + switch (building.Info.m_class.m_subService) + { + case ItemClass.SubService.OfficeGeneric: + case ItemClass.SubService.OfficeHightech: + profitShare = 1f; break; + case ItemClass.SubService.IndustrialFarming: + case ItemClass.SubService.IndustrialForestry: + if (building.Info.m_buildingAI is IndustrialExtractorAI) + { + bossTake = MainDataStore.bossRatioInduExtractor; + investToOffice = MainDataStore.investRatioInduExtractor; + profitShare = MainDataStore.profitShareRatioInduExtractor; + } + else + { + bossTake = MainDataStore.bossRatioInduOther; + investToOffice = MainDataStore.investRatioInduOther; + profitShare = MainDataStore.profitShareRatioInduOther; + } + break; + case ItemClass.SubService.IndustrialOil: + case ItemClass.SubService.IndustrialOre: + bossTake = MainDataStore.bossRatioInduOther; + investToOffice = MainDataStore.investRatioInduOther; + profitShare = MainDataStore.profitShareRatioInduOther; break; + case ItemClass.SubService.IndustrialGeneric: + if (building.Info.m_class.m_level == ItemClass.Level.Level1) + { + bossTake = MainDataStore.bossRatioInduLevel1; + investToOffice = MainDataStore.investRatioInduLevel1; + profitShare = MainDataStore.profitShareRatioInduLevel1; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level2) + { + bossTake = MainDataStore.bossRatioInduLevel2; + investToOffice = MainDataStore.investRatioInduLevel2; + profitShare = MainDataStore.profitShareRatioInduLevel2; + } + else + { + bossTake = MainDataStore.bossRatioInduLevel3; + investToOffice = MainDataStore.investRatioInduLevel3; + profitShare = MainDataStore.profitShareRatioInduLevel3; + } + break; + case ItemClass.SubService.CommercialHigh: + case ItemClass.SubService.CommercialLow: + if (building.Info.m_class.m_level == ItemClass.Level.Level1) + { + bossTake = MainDataStore.bossRatioCommLevel1; + investToOffice = MainDataStore.investRatioCommLevel1; + profitShare = MainDataStore.profitShareRatioCommLevel1; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level2) + { + bossTake = MainDataStore.bossRatioCommLevel2; + investToOffice = MainDataStore.investRatioCommLevel2; + profitShare = MainDataStore.profitShareRatioCommLevel2; + } + else + { + bossTake = MainDataStore.bossRatioCommLevel3; + investToOffice = MainDataStore.investRatioCommLevel3; + profitShare = MainDataStore.profitShareRatioCommLevel1; + } + break; + case ItemClass.SubService.CommercialTourist: + bossTake = MainDataStore.bossRatioCommTou; + investToOffice = MainDataStore.investRatioCommTou; + profitShare = MainDataStore.profitShareRatioCommTou; + break; + case ItemClass.SubService.CommercialLeisure: + bossTake = MainDataStore.bossRatioCommOther; + investToOffice = MainDataStore.investRatioCommOther; + profitShare = MainDataStore.profitShareRatioCommOther; break; + case ItemClass.SubService.CommercialEco: + bossTake = MainDataStore.bossRatioCommECO; + investToOffice = MainDataStore.investRatioCommECO; + profitShare = MainDataStore.profitShareRatioCommECO; break; + } + // boss take and return to office + if (BuildingData.buildingMoney[buildingID] > 0) + { + //Reduce Boss fee + long investToOfficeFee = (long)(BuildingData.buildingMoney[buildingID] * investToOffice); + long bossTakeFee = (long)(BuildingData.buildingMoney[buildingID] * bossTake); + if (building.Info.m_class.m_service == ItemClass.Service.Commercial) + { + //Commercial have help tourism + MainDataStore.outsideTouristMoney += ((bossTakeFee - investToOfficeFee) * MainDataStore.outsideCompanyProfitRatio * MainDataStore.outsideTouristSalaryProfitRatio); + } + RealCityPrivateBuildingAI.profitBuildingMoney += investToOfficeFee; + BuildingData.buildingMoney[buildingID] -= bossTakeFee; + } + + if (building.Info.m_class.m_service == ItemClass.Service.Office) + { + float allOfficeWorker = RealCityPrivateBuildingAI.allOfficeLevel1WorkCountFinal + RealCityPrivateBuildingAI.allOfficeLevel2WorkCountFinal + RealCityPrivateBuildingAI.allOfficeLevel3WorkCountFinal + RealCityPrivateBuildingAI.allOfficeHighTechWorkCountFinal; + float averageOfficeSalary = 0; + if (allOfficeWorker != 0) + { + averageOfficeSalary = (RealCityPrivateBuildingAI.profitBuildingMoneyFinal / allOfficeWorker); + } + + if (building.Info.m_class.m_subService == ItemClass.SubService.OfficeGeneric) + { + if (building.Info.m_class.m_level == ItemClass.Level.Level1) + { + BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.6f; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level2) + { + BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.8f; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level3) + { + BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 1f; + } + } + else if (building.Info.m_class.m_subService == ItemClass.SubService.OfficeHightech) + { + BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.75f; + } + + ProcessLandFeeOffice(building, buildingID, totalWorkerCount); + } + + //Calculate building salary + int buildingAsset = (int)(BuildingData.buildingMoney[buildingID] + building.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(RealCityPrivateBuildingAI.GetIncomingProductionType(buildingID, building))); + int salary = 0; + if ((buildingAsset > 0) && (totalWorkerCount != 0)) + { + salary = (int)(buildingAsset * profitShare / totalWorkerCount); + switch (building.Info.m_class.m_subService) + { + case ItemClass.SubService.IndustrialFarming: + case ItemClass.SubService.IndustrialForestry: + case ItemClass.SubService.IndustrialOil: + case ItemClass.SubService.IndustrialOre: + salary = Math.Min(salary, MainDataStore.salaryInduOtherMax); break; + case ItemClass.SubService.IndustrialGeneric: + if (building.Info.m_class.m_level == ItemClass.Level.Level1) + salary = Math.Min(salary, MainDataStore.salaryInduLevel1Max); + else if (building.Info.m_class.m_level == ItemClass.Level.Level2) + salary = Math.Min(salary, MainDataStore.salaryInduLevel2Max); + else + salary = Math.Min(salary, MainDataStore.salaryInduLevel3Max); + break; + case ItemClass.SubService.CommercialHigh: + case ItemClass.SubService.CommercialLow: + if (building.Info.m_class.m_level == ItemClass.Level.Level1) + salary = Math.Min(salary, MainDataStore.salaryCommLevel1Max); + else if (building.Info.m_class.m_level == ItemClass.Level.Level2) + salary = Math.Min(salary, MainDataStore.salaryCommLevel2Max); + else + salary = Math.Min(salary, MainDataStore.salaryCommLevel3Max); + break; + case ItemClass.SubService.CommercialTourist: + salary = Math.Min(salary, MainDataStore.salaryCommTouMax); break; + case ItemClass.SubService.CommercialLeisure: + salary = Math.Min(salary, MainDataStore.salaryCommOtherMax); break; + case ItemClass.SubService.CommercialEco: + salary = Math.Min(salary, MainDataStore.salaryCommECOMax); break; + } + } + + if (salary > 0) + BuildingData.buildingWorkCount[buildingID] = salary; + else + BuildingData.buildingWorkCount[buildingID] = 0; + } + else + { + //resident building + ItemClass @class = building.Info.m_class; + int incomeAccumulation = 0; + DistrictManager instance = Singleton.instance; + byte district = instance.GetDistrict(building.m_position); + DistrictPolicies.Taxation taxationPolicies = instance.m_districts.m_buffer[district].m_taxationPolicies; + if (@class.m_subService == ItemClass.SubService.ResidentialLow) + { + switch (@class.m_level) + { + case ItemClass.Level.Level1: + incomeAccumulation = MainDataStore.residentLowLevel1Rent; + break; + case ItemClass.Level.Level2: + incomeAccumulation = MainDataStore.residentLowLevel2Rent; + break; + case ItemClass.Level.Level3: + incomeAccumulation = MainDataStore.residentLowLevel3Rent; + break; + case ItemClass.Level.Level4: + incomeAccumulation = MainDataStore.residentLowLevel4Rent; + break; + case ItemClass.Level.Level5: + incomeAccumulation = MainDataStore.residentLowLevel5Rent; + break; + } + } + else if (@class.m_subService == ItemClass.SubService.ResidentialLowEco) + { + switch (@class.m_level) + { + case ItemClass.Level.Level1: + incomeAccumulation = MainDataStore.residentLowLevel1Rent << 1; + break; + case ItemClass.Level.Level2: + incomeAccumulation = MainDataStore.residentLowLevel2Rent << 1; + break; + case ItemClass.Level.Level3: + incomeAccumulation = MainDataStore.residentLowLevel3Rent << 1; + break; + case ItemClass.Level.Level4: + incomeAccumulation = MainDataStore.residentLowLevel4Rent << 1; + break; + case ItemClass.Level.Level5: + incomeAccumulation = MainDataStore.residentLowLevel5Rent << 1; + break; + } + } + else if (@class.m_subService == ItemClass.SubService.ResidentialHigh) + { + switch (@class.m_level) + { + case ItemClass.Level.Level1: + incomeAccumulation = MainDataStore.residentHighLevel1Rent; + break; + case ItemClass.Level.Level2: + incomeAccumulation = MainDataStore.residentHighLevel2Rent; + break; + case ItemClass.Level.Level3: + incomeAccumulation = MainDataStore.residentHighLevel3Rent; + break; + case ItemClass.Level.Level4: + incomeAccumulation = MainDataStore.residentHighLevel4Rent; + break; + case ItemClass.Level.Level5: + incomeAccumulation = MainDataStore.residentHighLevel5Rent; + break; + } + } + else + { + switch (@class.m_level) + { + case ItemClass.Level.Level1: + incomeAccumulation = MainDataStore.residentHighLevel1Rent << 1; + break; + case ItemClass.Level.Level2: + incomeAccumulation = MainDataStore.residentHighLevel2Rent << 1; + break; + case ItemClass.Level.Level3: + incomeAccumulation = MainDataStore.residentHighLevel3Rent << 1; + break; + case ItemClass.Level.Level4: + incomeAccumulation = MainDataStore.residentHighLevel4Rent << 1; + break; + case ItemClass.Level.Level5: + incomeAccumulation = MainDataStore.residentHighLevel5Rent << 1; + break; + } + } + int num2; + num2 = Singleton.instance.GetTaxRate(@class, taxationPolicies); + incomeAccumulation = (int)((num2 * incomeAccumulation) / 100f); + BuildingData.buildingWorkCount[buildingID] = incomeAccumulation; + } + } + + public static void ProcessLandFeeOffice(Building building, ushort buildingID, int totalWorkerCount) + { + DistrictManager instance = Singleton.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; + + int landFee = totalWorkerCount * 10; + int taxRate; + taxRate = Singleton.instance.GetTaxRate(building.Info.m_class, taxationPolicies); + + if (instance.IsPolicyLoaded(DistrictPolicies.Policies.ExtraInsulation)) + { + if ((servicePolicies & DistrictPolicies.Services.ExtraInsulation) != DistrictPolicies.Services.None) + { + landFee = landFee * 95 / 100; + } + } + if ((servicePolicies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None) + { + landFee = landFee * 95 / 100; + } + + if (BuildingData.buildingMoney[buildingID] >= 0) + { + BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (float)(landFee * taxRate) / 100); + Singleton.instance.AddPrivateIncome(landFee, building.Info.m_class.m_service, building.Info.m_class.m_subService, building.Info.m_class.m_level, taxRate * 100); + } + } + + public static void ProcessLandFeeNoOffice(Building building, ushort buildingID) + { + DistrictManager instance = Singleton.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; + + int landFee; + GetLandRentNoOffice(out landFee, building, buildingID); + int taxRate; + + taxRate = Singleton.instance.GetTaxRate(building.Info.m_class, taxationPolicies); + + if (((taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure) != DistrictPolicies.Taxation.None) && (building.Info.m_class.m_subService == ItemClass.SubService.CommercialLeisure)) + { + landFee = 0; + } + + if (instance.IsPolicyLoaded(DistrictPolicies.Policies.ExtraInsulation)) + { + if ((servicePolicies & DistrictPolicies.Services.ExtraInsulation) != DistrictPolicies.Services.None) + { + landFee = landFee * 95 / 100; + } + } + if ((servicePolicies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None) + { + landFee = landFee * 95 / 100; + } + + if (BuildingData.buildingMoney[buildingID] <= ((landFee * taxRate) / 100f)) + { + landFee = 0; + } + else + { + RealCityPrivateBuildingAI.profitBuildingCount++; + } + + if (RealCityEconomyExtension.Can16timesUpdate(buildingID)) + { + Singleton.instance.AddPrivateIncome(landFee, building.Info.m_class.m_service, building.Info.m_class.m_subService, building.Info.m_class.m_level, taxRate * 100); + if ((building.Info.m_class.m_service == ItemClass.Service.Commercial) || (building.Info.m_class.m_service == ItemClass.Service.Industrial)) + { + BuildingData.buildingMoney[buildingID] = (BuildingData.buildingMoney[buildingID] - (float)(landFee * taxRate) / 100); + } + } + } + + public static void GetLandRentNoOffice(out int landRent, Building building, ushort buildingID) + { + ItemClass @class = building.Info.m_class; + landRent = 0; + Citizen.BehaviourData behaviourData = default; + int aliveWorkerCount = 0; + int totalWorkerCount = 0; + ItemClass.SubService subService = @class.m_subService; + RealCityCommonBuildingAI.InitDelegate(); + switch (subService) + { + case ItemClass.SubService.OfficeHightech: + RealCityCommonBuildingAI.GetWorkBehaviour((OfficeBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); + RealCityPrivateBuildingAI.allOfficeHighTechWorkCount += totalWorkerCount; + break; + case ItemClass.SubService.OfficeGeneric: + RealCityCommonBuildingAI.GetWorkBehaviour((OfficeBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount); + if (building.Info.m_class.m_level == ItemClass.Level.Level1) + { + RealCityPrivateBuildingAI.allOfficeLevel1WorkCount += totalWorkerCount; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level2) + { + RealCityPrivateBuildingAI.allOfficeLevel2WorkCount += totalWorkerCount; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level3) + { + RealCityPrivateBuildingAI.allOfficeLevel3WorkCount += totalWorkerCount; + } + break; + case ItemClass.SubService.IndustrialFarming: + landRent = MainDataStore.induFarm; + break; + case ItemClass.SubService.IndustrialForestry: + landRent = MainDataStore.induForest; + break; + case ItemClass.SubService.IndustrialOil: + landRent = MainDataStore.induOil; + break; + case ItemClass.SubService.IndustrialOre: + landRent = MainDataStore.induOre; + break; + case ItemClass.SubService.IndustrialGeneric: + if (building.Info.m_class.m_level == ItemClass.Level.Level1) + { + landRent = MainDataStore.induGenLevel1; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level2) + { + landRent = MainDataStore.induGenLevel2; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level3) + { + landRent = MainDataStore.induGenLevel3; + } + break; + case ItemClass.SubService.CommercialHigh: + if (building.Info.m_class.m_level == ItemClass.Level.Level1) + { + landRent = MainDataStore.commHighLevel1; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level2) + { + landRent = MainDataStore.commHighLevel2; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level3) + { + landRent = MainDataStore.commHighLevel3; + } + break; + case ItemClass.SubService.CommercialLow: + if (building.Info.m_class.m_level == ItemClass.Level.Level1) + { + landRent = MainDataStore.commLowLevel1; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level2) + { + landRent = MainDataStore.commLowLevel2; + } + else if (building.Info.m_class.m_level == ItemClass.Level.Level3) + { + landRent = MainDataStore.commLowLevel3; + } + break; + case ItemClass.SubService.CommercialLeisure: + landRent = MainDataStore.commLeisure; + break; + case ItemClass.SubService.CommercialTourist: + landRent = MainDataStore.commTourist; + break; + case ItemClass.SubService.CommercialEco: + landRent = MainDataStore.commEco; + break; + default: break; + } + } + } } diff --git a/Patch/ProcessingFacilityAIGetResourceRatePatch.cs b/Patch/ProcessingFacilityAIGetResourceRatePatch.cs index 8ae1d8c..468c658 100644 --- a/Patch/ProcessingFacilityAIGetResourceRatePatch.cs +++ b/Patch/ProcessingFacilityAIGetResourceRatePatch.cs @@ -7,20 +7,20 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class ProcessingFacilityAIGetResourceRatePatch - { - public static MethodBase TargetMethod() - { - return typeof(ProcessingFacilityAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); - } - public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) - { - if (resource == EconomyManager.Resource.Maintenance) - { - float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); - __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); - } - } - } + [HarmonyPatch] + public class ProcessingFacilityAIGetResourceRatePatch + { + public static MethodBase TargetMethod() + { + return typeof(ProcessingFacilityAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); + } + public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) + { + if (resource == EconomyManager.Resource.Maintenance) + { + float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); + __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); + } + } + } } diff --git a/Patch/ResidentAICitizenInstanceSimulationStepPatch.cs b/Patch/ResidentAICitizenInstanceSimulationStepPatch.cs index 0d31ea1..ea5401b 100644 --- a/Patch/ResidentAICitizenInstanceSimulationStepPatch.cs +++ b/Patch/ResidentAICitizenInstanceSimulationStepPatch.cs @@ -6,42 +6,42 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class ResidentAICitizenInstanceSimulationStepPatch - { - public static MethodBase TargetMethod() - { - return typeof(ResidentAI).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(CitizenInstance).MakeByRefType(), typeof(CitizenInstance.Frame).MakeByRefType(), typeof(bool) }, null); - } - public static void Prefix(ref CitizenInstance citizenData) - { - CitizenManager instance = Singleton.instance; - uint citizen = citizenData.m_citizen; - if (citizen != 0 && (instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.NeedGoods) != 0) - { - instance.m_citizens.m_buffer[citizen].m_flags &= ~Citizen.Flags.NeedGoods; - } - } + [HarmonyPatch] + public class ResidentAICitizenInstanceSimulationStepPatch + { + public static MethodBase TargetMethod() + { + return typeof(ResidentAI).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(CitizenInstance).MakeByRefType(), typeof(CitizenInstance.Frame).MakeByRefType(), typeof(bool) }, null); + } + public static void Prefix(ref CitizenInstance citizenData) + { + CitizenManager instance = Singleton.instance; + uint citizen = citizenData.m_citizen; + if (citizen != 0 && (instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.NeedGoods) != 0) + { + instance.m_citizens.m_buffer[citizen].m_flags &= ~Citizen.Flags.NeedGoods; + } + } - public static void Postfix(ref CitizenInstance citizenData) - { - CitizenManager instance = Singleton.instance; - uint citizen = citizenData.m_citizen; - if (citizen != 0) - { - ushort homeBuilding = instance.m_citizens.m_buffer[citizen].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = instance.m_citizens.m_buffer[citizen].GetContainingUnit((uint)citizen, citizenUnit, CitizenUnit.Flags.Home); + public static void Postfix(ref CitizenInstance citizenData) + { + CitizenManager instance = Singleton.instance; + uint citizen = citizenData.m_citizen; + if (citizen != 0) + { + ushort homeBuilding = instance.m_citizens.m_buffer[citizen].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = instance.m_citizens.m_buffer[citizen].GetContainingUnit((uint)citizen, citizenUnit, CitizenUnit.Flags.Home); - if (containingUnit != 0) - { - if (CitizenUnitData.familyGoods[containingUnit] < 2000) - { - instance.m_citizens.m_buffer[citizen].m_flags |= Citizen.Flags.NeedGoods; - } - } - } - } + if (containingUnit != 0) + { + if (CitizenUnitData.familyGoods[containingUnit] < 2000) + { + instance.m_citizens.m_buffer[citizen].m_flags |= Citizen.Flags.NeedGoods; + } + } + } + } - } + } } diff --git a/Patch/ResidentAICitizenSimulationStepPatch.cs b/Patch/ResidentAICitizenSimulationStepPatch.cs index b383395..24ed2b5 100644 --- a/Patch/ResidentAICitizenSimulationStepPatch.cs +++ b/Patch/ResidentAICitizenSimulationStepPatch.cs @@ -8,34 +8,34 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class ResidentAICitizenSimulationStepPatch - { - public static MethodBase TargetMethod() - { - return typeof(ResidentAI).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(uint), typeof(Citizen).MakeByRefType() }, null); - } - public static void Postfix(uint citizenID, ref Citizen data) - { - BuildingManager instance = Singleton.instance; - ushort homeBuilding = data.m_homeBuilding; - uint homeId = data.GetContainingUnit(citizenID, instance.m_buildings.m_buffer[homeBuilding].m_citizenUnits, CitizenUnit.Flags.Home); - if (homeId != 0) - { - //Change wealth - if (CitizenUnitData.familyMoney[homeId] > MainDataStore.highWealth) - { - data.WealthLevel = Citizen.Wealth.High; - } - else if (CitizenUnitData.familyMoney[homeId] < MainDataStore.lowWealth) - { - data.WealthLevel = Citizen.Wealth.Low; - } - else - { - data.WealthLevel = Citizen.Wealth.Medium; - } - } - } - } + [HarmonyPatch] + public class ResidentAICitizenSimulationStepPatch + { + public static MethodBase TargetMethod() + { + return typeof(ResidentAI).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(uint), typeof(Citizen).MakeByRefType() }, null); + } + public static void Postfix(uint citizenID, ref Citizen data) + { + BuildingManager instance = Singleton.instance; + ushort homeBuilding = data.m_homeBuilding; + uint homeId = data.GetContainingUnit(citizenID, instance.m_buildings.m_buffer[homeBuilding].m_citizenUnits, CitizenUnit.Flags.Home); + if (homeId != 0) + { + //Change wealth + if (CitizenUnitData.familyMoney[homeId] > MainDataStore.highWealth) + { + data.WealthLevel = Citizen.Wealth.High; + } + else if (CitizenUnitData.familyMoney[homeId] < MainDataStore.lowWealth) + { + data.WealthLevel = Citizen.Wealth.Low; + } + else + { + data.WealthLevel = Citizen.Wealth.Medium; + } + } + } + } } diff --git a/Patch/ResidentAICitizenUnitSimulationStepPatch.cs b/Patch/ResidentAICitizenUnitSimulationStepPatch.cs index 03550d8..8203786 100644 --- a/Patch/ResidentAICitizenUnitSimulationStepPatch.cs +++ b/Patch/ResidentAICitizenUnitSimulationStepPatch.cs @@ -1,754 +1,665 @@ -using System; -using ColossalFramework; -using UnityEngine; -using RealCity.Util; +using ColossalFramework; +using ColossalFramework.UI; using HarmonyLib; -using System.Reflection; -using RealCity.CustomData; using RealCity.CustomAI; +using RealCity.CustomData; +using RealCity.Util; +using RealCity.Util.Politic; +using RealCity.Util.Politic.ElectionUtil; +using System; +using System.Reflection; namespace RealCity.Patch { - [HarmonyPatch] - public class ResidentAICitizenUnitSimulationStepPatch - { - public static MethodBase TargetMethod() - { - return typeof(ResidentAI).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(uint), typeof(CitizenUnit).MakeByRefType() }, null); - } - - public static void ProcessCitizen(uint homeID, ref CitizenUnit data, bool isPre) - { - if (isPre) - { - CitizenUnitData.familyMoney[homeID] = 0; - if (data.m_citizen0 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen0]; - if ((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) - { - if (citizenData.Dead == false) - { - RealCityResidentAI.citizenCount++; - CitizenUnitData.familyMoney[homeID] += CitizenData.citizenMoney[data.m_citizen0]; - } - } - } - if (data.m_citizen1 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen1]; - if ((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) - { - if (citizenData.Dead == false) - { - RealCityResidentAI.citizenCount++; - CitizenUnitData.familyMoney[homeID] += CitizenData.citizenMoney[data.m_citizen1]; - } - } - } - if (data.m_citizen2 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen2]; - if ((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) - { - if (citizenData.Dead == false) - { - RealCityResidentAI.citizenCount++; - CitizenUnitData.familyMoney[homeID] += CitizenData.citizenMoney[data.m_citizen2]; - } - } - } - if (data.m_citizen3 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen3]; - if ((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) - { - if (citizenData.Dead == false) - { - RealCityResidentAI.citizenCount++; - CitizenUnitData.familyMoney[homeID] += CitizenData.citizenMoney[data.m_citizen3]; - } - } - } - if (data.m_citizen4 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen4]; - if ((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) - { - if (citizenData.Dead == false) - { - RealCityResidentAI.citizenCount++; - CitizenUnitData.familyMoney[homeID] += CitizenData.citizenMoney[data.m_citizen4]; - } - } - } - } - else - { - if (CitizenUnitData.familyMoney[homeID] < MainDataStore.lowWealth) - { - RealCityResidentAI.familyWeightStableLow++; - } - else if (CitizenUnitData.familyMoney[homeID] >= MainDataStore.highWealth) - { - RealCityResidentAI.familyWeightStableHigh++; - } - - int temp = 0; - if (data.m_citizen0 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen0]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { - temp++; -#if FASTRUN -#else - GetVoteChance(data.m_citizen0, citizenData, homeID); -#endif - } - } - if (data.m_citizen1 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen1]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { -#if FASTRUN -#else - GetVoteChance(data.m_citizen1, citizenData, homeID); -#endif - temp++; - } - } - if (data.m_citizen2 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen2]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { -#if FASTRUN -#else - GetVoteChance(data.m_citizen2, citizenData, homeID); -#endif - temp++; - } - } - if (data.m_citizen3 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen3]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { -#if FASTRUN -#else - GetVoteChance(data.m_citizen3, citizenData, homeID); -#endif - temp++; - } - } - if (data.m_citizen4 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen4]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { + [HarmonyPatch] + public class ResidentAICitizenUnitSimulationStepPatch + { + public static MethodBase TargetMethod() + { + return typeof(ResidentAI).GetMethod( + "SimulationStep", + BindingFlags.Public | BindingFlags.Instance, + null, + new Type[] { typeof(uint), typeof(CitizenUnit).MakeByRefType() }, + null); + } + + /// + /// 处理市民 + /// + /// + /// + /// + public static void ProcessCitizen(uint homeID, ref CitizenUnit data, bool isPre) + { + FieldInfo fieldInfo; + if (isPre) + { + CitizenUnitData.familyMoney[homeID] = 0; + for (int i = 0; i <= 4; i++) + { + fieldInfo = data.GetType().GetField($"m_citizen{i}"); + uint m_citizenI = (uint)fieldInfo.GetValue(data); + if (m_citizenI != 0) + { + Citizen citizenData = Singleton.instance.m_citizens.m_buffer[m_citizenI]; + if ((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) + { + if (citizenData.Dead == false) + { + RealCityResidentAI.citizenCount++; + CitizenUnitData.familyMoney[homeID] += CitizenData.citizenMoney[m_citizenI]; + } + } + } + } + } + else + { + // post-process + if (CitizenUnitData.familyMoney[homeID] < MainDataStore.lowWealth) + { + RealCityResidentAI.familyWeightStableLow++; + } + else if (CitizenUnitData.familyMoney[homeID] >= MainDataStore.highWealth) + { + RealCityResidentAI.familyWeightStableHigh++; + } + + int temp = 0; + for (int i = 0; i <= 4; i++) + { + fieldInfo = data.GetType().GetField($"m_citizen{i}"); + uint m_citizenI = (uint)fieldInfo.GetValue(data); + + if (m_citizenI != 0) + { + Citizen citizenData = Singleton.instance.m_citizens.m_buffer[m_citizenI]; + if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) + { + ++temp; #if FASTRUN #else - GetVoteChance(data.m_citizen4, citizenData, homeID); + //add a party.chancce by its citizen data + //GetVoteChance(m_citizenI, citizenData, homeID); + if (Politics.IsOnElection() && Politics.IsOverVotingAge(Citizen.GetAgeGroup(citizenData.m_age))) + { + ElectionVoter v = new ElectionVoter(m_citizenI, ref citizenData, homeID, Election.CurrentElectionInfo); + v.VoteTicket(); + } #endif - temp++; - } - } - - if (temp != 0) - { - if (data.m_citizen0 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen0]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { - CitizenData.citizenMoney[data.m_citizen0] = CitizenUnitData.familyMoney[homeID] / temp; - } - } - if (data.m_citizen1 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen1]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { - CitizenData.citizenMoney[data.m_citizen1] = CitizenUnitData.familyMoney[homeID] / temp; - } - } - if (data.m_citizen2 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen2]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { - CitizenData.citizenMoney[data.m_citizen2] = CitizenUnitData.familyMoney[homeID] / temp; - } - } - if (data.m_citizen3 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen3]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { - CitizenData.citizenMoney[data.m_citizen3] = CitizenUnitData.familyMoney[homeID] / temp; - } - } - if (data.m_citizen4 != 0) - { - Citizen citizenData = Singleton.instance.m_citizens.m_buffer[data.m_citizen4]; - if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) - { - CitizenData.citizenMoney[data.m_citizen4] = CitizenUnitData.familyMoney[homeID] / temp; - } - } - } - } - - } - - 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.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.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.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.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); - } - - - public static void ProcessCitizenIncomeTax(uint homeID, float tax) - { - CitizenManager instance = Singleton.instance; - ushort building = instance.m_units.m_buffer[(int)((UIntPtr)homeID)].m_building; - Building buildingdata = Singleton.instance.m_buildings.m_buffer[building]; - Singleton.instance.AddPrivateIncome((int)(tax), buildingdata.Info.m_class.m_service, buildingdata.Info.m_class.m_subService, buildingdata.Info.m_class.m_level, 112333); - } - - public static void ProcessCitizenHouseRent(uint homeID, int expenserate) - { - CitizenManager instance = Singleton.instance; - ushort building = instance.m_units.m_buffer[(int)((UIntPtr)homeID)].m_building; - Building buildingdata = Singleton.instance.m_buildings.m_buffer[building]; - Singleton.instance.AddPrivateIncome(expenserate * 100, buildingdata.Info.m_class.m_service, buildingdata.Info.m_class.m_subService, buildingdata.Info.m_class.m_level, 100); - } - - public static void Prefix(uint homeID, ref CitizenUnit data) - { - if (CitizenUnitData.familyGoods[homeID] == 65535) - { - //first time - if (data.m_goods < 6000) - CitizenUnitData.familyGoods[homeID] = (ushort)(data.m_goods * 10); - else - CitizenUnitData.familyGoods[homeID] = 60000; - } - } - - // ResidentAI - public static void Postfix(uint homeID, ref CitizenUnit data) - { - if ((Singleton.instance.m_buildings.m_buffer[data.m_building].m_flags & (Building.Flags.Completed | Building.Flags.Upgrading)) != Building.Flags.None) - { - ProcessFamily(homeID, ref data); - } - } - - public static void GetExpenseRate(uint citizenID, out int incomeAccumulation, out int educationFee, out int hospitalFee) - { - BuildingManager instance1 = Singleton.instance; - CitizenManager instance2 = Singleton.instance; - var buildingID = Singleton.instance.m_citizens.m_buffer[citizenID].m_homeBuilding; - incomeAccumulation = BuildingData.buildingWorkCount[buildingID]; - - educationFee = 0; - hospitalFee = 0; - if ((Singleton.instance.m_citizens.m_buffer[citizenID].m_flags & Citizen.Flags.Student) != Citizen.Flags.None) - { - //Only university will cost money - bool isCampusDLC = false; - //Campus DLC cost 50 - ushort visitBuilding = Singleton.instance.m_citizens.m_buffer[citizenID].m_visitBuilding; - if (visitBuilding != 0u) - { - Building buildingData = Singleton.instance.m_buildings.m_buffer[visitBuilding]; - if (buildingData.Info.m_class.m_service == ItemClass.Service.PlayerEducation) - { - var tempEducationFee = (uint)((MainDataStore.govermentSalary) / 100f); - if (tempEducationFee < 1) - tempEducationFee = 1; - - educationFee = (int)tempEducationFee * 100; - isCampusDLC = true; - } - } - - if (!isCampusDLC) - { - if (Singleton.instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Education2)) - { - educationFee = MainDataStore.govermentSalary >> 1; - Singleton.instance.AddPrivateIncome(educationFee, ItemClass.Service.Education, ItemClass.SubService.None, ItemClass.Level.Level3, 115333); - } - else if (Singleton.instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Education1)) - { - educationFee = MainDataStore.govermentSalary >> 2; - Singleton.instance.AddPrivateIncome(educationFee, ItemClass.Service.Education, ItemClass.SubService.None, ItemClass.Level.Level2, 115333); - } - else - { - educationFee = MainDataStore.govermentSalary >> 2; - Singleton.instance.AddPrivateIncome(educationFee, ItemClass.Service.Education, ItemClass.SubService.None, ItemClass.Level.Level1, 115333); - } - } - } - - if (Singleton.instance.m_citizens.m_buffer[citizenID].Sick) - { - ushort visitBuilding = Singleton.instance.m_citizens.m_buffer[citizenID].m_visitBuilding; - if (visitBuilding != 0u) - { - Building buildingData = Singleton.instance.m_buildings.m_buffer[visitBuilding]; - if (visitBuilding != Singleton.instance.m_citizens.m_buffer[citizenID].m_workBuilding) - { - if (buildingData.Info.m_class.m_service == ItemClass.Service.HealthCare) - { - hospitalFee = MainDataStore.govermentSalary >> 1; - Singleton.instance.AddPrivateIncome(hospitalFee, ItemClass.Service.HealthCare, ItemClass.SubService.None, ItemClass.Level.Level2, 115333); - } - } - } - } - } - - public static void GetVoteTickets() - { - System.Random rand = new System.Random(); - if (Politics.cPartyChance + Politics.gPartyChance + Politics.sPartyChance + Politics.lPartyChance + Politics.nPartyChance != (800 + RealCityEconomyExtension.partyTrendStrength)) - { - if (rand.Next(64) <= 1) - { - DebugLog.LogToFileOnly($"Error: GetVoteTickets Chance is not equal 800 {(Politics.cPartyChance + Politics.gPartyChance + Politics.sPartyChance + Politics.lPartyChance + Politics.nPartyChance)}"); - } - } - - int voteRandom = rand.Next(800 + RealCityEconomyExtension.partyTrendStrength) + 1; - if (voteRandom < Politics.cPartyChance) - { - Politics.cPartyTickets++; - } - else if (voteRandom < Politics.cPartyChance + Politics.gPartyChance) - { - Politics.gPartyTickets++; - } - else if (voteRandom < Politics.cPartyChance + Politics.gPartyChance + Politics.sPartyChance) - { - Politics.sPartyTickets++; - } - else if (voteRandom < Politics.cPartyChance + Politics.gPartyChance + Politics.sPartyChance + Politics.lPartyChance) - { - Politics.lPartyTickets++; - } - else - { - Politics.nPartyTickets++; - } - } - - public static void GetVoteChance(uint citizenID, Citizen citizen, uint homeID) - { - if ((int)Citizen.GetAgeGroup(citizen.m_age) >= 2) - { - if (Politics.parliamentCount == 1) - { - Politics.cPartyChance = 0; - Politics.gPartyChance = 0; - Politics.sPartyChance = 0; - Politics.lPartyChance = 0; - Politics.nPartyChance = 0; - - Politics.cPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 0] << 1); - Politics.gPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 1] << 1); - Politics.sPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 2] << 1); - Politics.lPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 3] << 1); - Politics.nPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 4] << 1); - - int idex = 14; - if (RealCityResidentAI.IsGoverment(citizen.m_workBuilding)) - { - idex = 0; - } - - switch (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_subService) - { - case ItemClass.SubService.CommercialLow: - case ItemClass.SubService.CommercialHigh: - if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level1) - { - idex = 1; - } - else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level2) - { - idex = 2; - } - else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level3) - { - idex = 3; - } - break; - case ItemClass.SubService.CommercialTourist: - case ItemClass.SubService.CommercialLeisure: - idex = 4; break; - case ItemClass.SubService.CommercialEco: - idex = 5; break; - case ItemClass.SubService.IndustrialGeneric: - if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level1) - { - idex = 6; - } - else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level2) - { - idex = 7; - } - else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level3) - { - idex = 8; - } - break; - case ItemClass.SubService.IndustrialFarming: - case ItemClass.SubService.IndustrialForestry: - case ItemClass.SubService.IndustrialOil: - case ItemClass.SubService.IndustrialOre: - idex = 9; break; - case ItemClass.SubService.OfficeGeneric: - if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level1) - { - idex = 10; - } - else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level2) - { - idex = 11; - } - else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level3) - { - idex = 12; - } - break; - case ItemClass.SubService.OfficeHightech: - idex = 13; break; - } - - if (idex < 0 || idex > 14) - { - DebugLog.LogToFileOnly($"Error: GetVoteChance workplace idex {idex}"); - } - - - Politics.cPartyChance += (ushort)(Politics.workplace[idex, 0] << 1); - Politics.gPartyChance += (ushort)(Politics.workplace[idex, 1] << 1); - Politics.sPartyChance += (ushort)(Politics.workplace[idex, 2] << 1); - Politics.lPartyChance += (ushort)(Politics.workplace[idex, 3] << 1); - Politics.nPartyChance += (ushort)(Politics.workplace[idex, 4] << 1); - - if (CitizenUnitData.familyMoney[homeID] < 5000) - { - idex = 0; - } - else if (CitizenUnitData.familyMoney[homeID] >= 20000) - { - idex = 2; - } - else - { - idex = 1; - } - - if (idex < 0 || idex > 3) - { - DebugLog.LogToFileOnly($"Error: GetVoteChance Invaid money idex = {idex}"); - } - Politics.cPartyChance += (ushort)(Politics.money[idex, 0] << 1); - Politics.gPartyChance += (ushort)(Politics.money[idex, 1] << 1); - Politics.sPartyChance += (ushort)(Politics.money[idex, 2] << 1); - Politics.lPartyChance += (ushort)(Politics.money[idex, 3] << 1); - Politics.nPartyChance += (ushort)(Politics.money[idex, 4] << 1); - - int temp = 0; - - temp = (int)Citizen.GetAgeGroup(citizen.m_age) - 2; - - if (temp < 0) - { - DebugLog.LogToFileOnly($"Error: GetVoteChance temp = {temp} < 0, GetAgeGroup = {Citizen.GetAgeGroup(citizen.m_age)}"); - } - - Politics.cPartyChance += Politics.age[temp, 0]; - Politics.gPartyChance += Politics.age[temp, 1]; - Politics.sPartyChance += Politics.age[temp, 2]; - Politics.lPartyChance += Politics.age[temp, 3]; - Politics.nPartyChance += Politics.age[temp, 4]; - - temp = (int)Citizen.GetGender(citizenID); - - - Politics.cPartyChance += Politics.gender[temp, 0]; - Politics.gPartyChance += Politics.gender[temp, 1]; - Politics.sPartyChance += Politics.gender[temp, 2]; - Politics.lPartyChance += Politics.gender[temp, 3]; - Politics.nPartyChance += Politics.gender[temp, 4]; - - if (RealCityEconomyExtension.partyTrend == 0) - { - Politics.cPartyChance += RealCityEconomyExtension.partyTrendStrength; - } - else if (RealCityEconomyExtension.partyTrend == 1) - { - Politics.gPartyChance += RealCityEconomyExtension.partyTrendStrength; - } - else if (RealCityEconomyExtension.partyTrend == 2) - { - Politics.sPartyChance += RealCityEconomyExtension.partyTrendStrength; - } - else if (RealCityEconomyExtension.partyTrend == 3) - { - Politics.lPartyChance += RealCityEconomyExtension.partyTrendStrength; - } - else if (RealCityEconomyExtension.partyTrend == 4) - { - Politics.nPartyChance += RealCityEconomyExtension.partyTrendStrength; - } - else - { - DebugLog.LogToFileOnly($"Error: GetVoteChance Invalid partyTrend = {RealCityEconomyExtension.partyTrend}"); - } - - GetVoteTickets(); - } - } - } - } + } + } + } + + if (temp != 0) + { + for (int i = 0; i <= 4; i++) + { + fieldInfo = data.GetType().GetField($"m_citizen{i}"); + uint m_citizenI = (uint)fieldInfo.GetValue(data); + + if (m_citizenI != 0) + { + Citizen citizenData = Singleton.instance.m_citizens.m_buffer[m_citizenI]; + if (((citizenData.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None) && (citizenData.Dead == false)) + { + CitizenData.citizenMoney[m_citizenI] = CitizenUnitData.familyMoney[homeID] / temp; + } + } + } + } + } + } + + 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]}"); + //把家庭成员的财产汇总。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.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.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.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.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); + } + } + + //把家庭财产分配给家庭成员。split all familyMoney to CitizenMoney + ProcessCitizen(homeID, ref data, false); + } + + + public static void ProcessCitizenIncomeTax(uint homeID, float tax) + { + CitizenManager instance = Singleton.instance; + ushort building = instance.m_units.m_buffer[(int)((UIntPtr)homeID)].m_building; + Building buildingdata = Singleton.instance.m_buildings.m_buffer[building]; + Singleton.instance.AddPrivateIncome((int)(tax), buildingdata.Info.m_class.m_service, buildingdata.Info.m_class.m_subService, buildingdata.Info.m_class.m_level, 112333); + } + + public static void ProcessCitizenHouseRent(uint homeID, int expenserate) + { + CitizenManager instance = Singleton.instance; + ushort building = instance.m_units.m_buffer[(int)((UIntPtr)homeID)].m_building; + Building buildingdata = Singleton.instance.m_buildings.m_buffer[building]; + Singleton.instance.AddPrivateIncome(expenserate * 100, buildingdata.Info.m_class.m_service, buildingdata.Info.m_class.m_subService, buildingdata.Info.m_class.m_level, 100); + } + + public static void Prefix(uint homeID, ref CitizenUnit data) + { + if (CitizenUnitData.familyGoods[homeID] == 65535) + { + //first time + if (data.m_goods < 6000) + CitizenUnitData.familyGoods[homeID] = (ushort)(data.m_goods * 10); + else + CitizenUnitData.familyGoods[homeID] = 60000; + } + } + + // ResidentAI + public static void Postfix(uint homeID, ref CitizenUnit data) + { + if ((Singleton.instance.m_buildings.m_buffer[data.m_building].m_flags & (Building.Flags.Completed | Building.Flags.Upgrading)) != Building.Flags.None) + { + ProcessFamily(homeID, ref data); + } + } + + public static void GetExpenseRate(uint citizenID, out int incomeAccumulation, out int educationFee, out int hospitalFee) + { + BuildingManager instance1 = Singleton.instance; + CitizenManager instance2 = Singleton.instance; + var buildingID = Singleton.instance.m_citizens.m_buffer[citizenID].m_homeBuilding; + incomeAccumulation = BuildingData.buildingWorkCount[buildingID]; + + educationFee = 0; + hospitalFee = 0; + if ((Singleton.instance.m_citizens.m_buffer[citizenID].m_flags & Citizen.Flags.Student) != Citizen.Flags.None) + { + //Only university will cost money + bool isCampusDLC = false; + //Campus DLC cost 50 + ushort visitBuilding = Singleton.instance.m_citizens.m_buffer[citizenID].m_visitBuilding; + if (visitBuilding != 0u) + { + Building buildingData = Singleton.instance.m_buildings.m_buffer[visitBuilding]; + if (buildingData.Info.m_class.m_service == ItemClass.Service.PlayerEducation) + { + var tempEducationFee = (uint)((MainDataStore.govermentSalary) / 100f); + if (tempEducationFee < 1) + tempEducationFee = 1; + + educationFee = (int)tempEducationFee * 100; + isCampusDLC = true; + } + } + + if (!isCampusDLC) + { + if (Singleton.instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Education2)) + { + educationFee = MainDataStore.govermentSalary >> 1; + Singleton.instance.AddPrivateIncome(educationFee, ItemClass.Service.Education, ItemClass.SubService.None, ItemClass.Level.Level3, 115333); + } + else if (Singleton.instance.m_citizens.m_buffer[citizenID].m_flags.IsFlagSet(Citizen.Flags.Education1)) + { + educationFee = MainDataStore.govermentSalary >> 2; + Singleton.instance.AddPrivateIncome(educationFee, ItemClass.Service.Education, ItemClass.SubService.None, ItemClass.Level.Level2, 115333); + } + else + { + educationFee = MainDataStore.govermentSalary >> 2; + Singleton.instance.AddPrivateIncome(educationFee, ItemClass.Service.Education, ItemClass.SubService.None, ItemClass.Level.Level1, 115333); + } + } + } + + if (Singleton.instance.m_citizens.m_buffer[citizenID].Sick) + { + ushort visitBuilding = Singleton.instance.m_citizens.m_buffer[citizenID].m_visitBuilding; + if (visitBuilding != 0u) + { + Building buildingData = Singleton.instance.m_buildings.m_buffer[visitBuilding]; + if (visitBuilding != Singleton.instance.m_citizens.m_buffer[citizenID].m_workBuilding) + { + if (buildingData.Info.m_class.m_service == ItemClass.Service.HealthCare) + { + hospitalFee = MainDataStore.govermentSalary >> 1; + Singleton.instance.AddPrivateIncome(hospitalFee, ItemClass.Service.HealthCare, ItemClass.SubService.None, ItemClass.Level.Level2, 115333); + } + } + } + } + } + + [Obsolete("It's calculated in ElectionVoter. If wants to vote, call ElectionVoter.VoteTicket() instead.")] + public static void GetVoteChance(uint citizenID, Citizen citizen, uint homeID) + { + //如果即将选举,而且达到投票年龄 if (gonna be election) and (over Voting Age) + if (Politics.IsOnElection() + && Politics.IsOverVotingAge(Citizen.GetAgeGroup(citizen.m_age))) + { + + ////重置机率 + Politics.cPartyChance = 0; + Politics.gPartyChance = 0; + Politics.sPartyChance = 0; + Politics.lPartyChance = 0; + Politics.nPartyChance = 0; + + + Politics.cPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 0] << 1); + Politics.gPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 1] << 1); + Politics.sPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 2] << 1); + Politics.lPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 3] << 1); + Politics.nPartyChance += (ushort)(Politics.education[(int)citizen.EducationLevel, 4] << 1); + + + int choiceIndex = 14; + //根据工作地点决定投票策略 + if (RealCityResidentAI.IsGoverment(citizen.m_workBuilding)) + { + choiceIndex = 0; + } + switch (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_subService) + { + case ItemClass.SubService.CommercialLow: + case ItemClass.SubService.CommercialHigh: + if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level1) + { + choiceIndex = 1; + } + else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level2) + { + choiceIndex = 2; + } + else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level3) + { + choiceIndex = 3; + } + break; + case ItemClass.SubService.CommercialTourist: + case ItemClass.SubService.CommercialLeisure: + choiceIndex = 4; break; + case ItemClass.SubService.CommercialEco: + choiceIndex = 5; break; + case ItemClass.SubService.IndustrialGeneric: + if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level1) + { + choiceIndex = 6; + } + else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level2) + { + choiceIndex = 7; + } + else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level3) + { + choiceIndex = 8; + } + break; + case ItemClass.SubService.IndustrialFarming: + case ItemClass.SubService.IndustrialForestry: + case ItemClass.SubService.IndustrialOil: + case ItemClass.SubService.IndustrialOre: + choiceIndex = 9; break; + case ItemClass.SubService.OfficeGeneric: + if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level1) + { + choiceIndex = 10; + } + else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level2) + { + choiceIndex = 11; + } + else if (Singleton.instance.m_buildings.m_buffer[citizen.m_workBuilding].Info.m_class.m_level == ItemClass.Level.Level3) + { + choiceIndex = 12; + } + break; + case ItemClass.SubService.OfficeHightech: + choiceIndex = 13; break; + } + if (choiceIndex < 0 || choiceIndex > 14) + { + DebugLog.LogToFileOnly($"Error: GetVoteChance workplace idex {choiceIndex}"); + } + Politics.cPartyChance += (ushort)(Politics.workplace[choiceIndex, 0] << 1); + Politics.gPartyChance += (ushort)(Politics.workplace[choiceIndex, 1] << 1); + Politics.sPartyChance += (ushort)(Politics.workplace[choiceIndex, 2] << 1); + Politics.lPartyChance += (ushort)(Politics.workplace[choiceIndex, 3] << 1); + Politics.nPartyChance += (ushort)(Politics.workplace[choiceIndex, 4] << 1); + + + if (CitizenUnitData.familyMoney[homeID] < 5000) + { + choiceIndex = 0; + } + else if (CitizenUnitData.familyMoney[homeID] >= 20000) + { + choiceIndex = 2; + } + else + { + choiceIndex = 1; + } + if (choiceIndex < 0 || choiceIndex > 3) + { + DebugLog.LogToFileOnly($"Error: GetVoteChance Invaid money idex = {choiceIndex}"); + } + Politics.cPartyChance += (ushort)(Politics.money[choiceIndex, 0] << 1); + Politics.gPartyChance += (ushort)(Politics.money[choiceIndex, 1] << 1); + Politics.sPartyChance += (ushort)(Politics.money[choiceIndex, 2] << 1); + Politics.lPartyChance += (ushort)(Politics.money[choiceIndex, 3] << 1); + Politics.nPartyChance += (ushort)(Politics.money[choiceIndex, 4] << 1); + + + int temp = (int)Citizen.GetAgeGroup(citizen.m_age) - 2; + if (temp < 0) + { + DebugLog.LogToFileOnly($"Error: GetVoteChance temp = {temp} < 0, GetAgeGroup = {Citizen.GetAgeGroup(citizen.m_age)}"); + } + Politics.cPartyChance += Politics.age[temp, 0]; + Politics.gPartyChance += Politics.age[temp, 1]; + Politics.sPartyChance += Politics.age[temp, 2]; + Politics.lPartyChance += Politics.age[temp, 3]; + Politics.nPartyChance += Politics.age[temp, 4]; + + + temp = (int)Citizen.GetGender(citizenID); + Politics.cPartyChance += Politics.gender[temp, 0]; + Politics.gPartyChance += Politics.gender[temp, 1]; + Politics.sPartyChance += Politics.gender[temp, 2]; + Politics.lPartyChance += Politics.gender[temp, 3]; + Politics.nPartyChance += Politics.gender[temp, 4]; + + + if (RealCityEconomyExtension.partyTrend == 0) + { + Politics.cPartyChance += RealCityEconomyExtension.partyTrendStrength; + } + else if (RealCityEconomyExtension.partyTrend == 1) + { + Politics.gPartyChance += RealCityEconomyExtension.partyTrendStrength; + } + else if (RealCityEconomyExtension.partyTrend == 2) + { + Politics.sPartyChance += RealCityEconomyExtension.partyTrendStrength; + } + else if (RealCityEconomyExtension.partyTrend == 3) + { + Politics.lPartyChance += RealCityEconomyExtension.partyTrendStrength; + } + else if (RealCityEconomyExtension.partyTrend == 4) + { + Politics.nPartyChance += RealCityEconomyExtension.partyTrendStrength; + } + else + { + DebugLog.LogToFileOnly($"Error: GetVoteChance Invalid partyTrend = {RealCityEconomyExtension.partyTrend}"); + } + GetVoteTickets(); + } + } + + [Obsolete("Call ElectionVoter.VoteTicket() instead.")] + public static void GetVoteTickets() + { + System.Random rand = new System.Random(); + //魔数800参见PartyInterestCalc.GetFromEducationLevel()中的注释 + if (Politics.cPartyChance + Politics.gPartyChance + Politics.sPartyChance + Politics.lPartyChance + Politics.nPartyChance + != (800 + RealCityEconomyExtension.partyTrendStrength)) + { + //有1/64的机率打印这句话(WTF?) + if (rand.Next(64) <= 1) + { + DebugLog.LogToFileOnly($"Error: GetVoteTickets Chance is not equal 800 {(Politics.cPartyChance + Politics.gPartyChance + Politics.sPartyChance + Politics.lPartyChance + Politics.nPartyChance)}"); + } + } + + //大转盘,政党的chance越大,得票机率就越大 + int voteRandom = rand.Next(800 + RealCityEconomyExtension.partyTrendStrength) + 1; + if (voteRandom < Politics.cPartyChance) + { + Politics.cPartyTickets++; + } + else if (voteRandom < Politics.cPartyChance + Politics.gPartyChance) + { + Politics.gPartyTickets++; + } + else if (voteRandom < Politics.cPartyChance + Politics.gPartyChance + Politics.sPartyChance) + { + Politics.sPartyTickets++; + } + else if (voteRandom < Politics.cPartyChance + Politics.gPartyChance + Politics.sPartyChance + Politics.lPartyChance) + { + Politics.lPartyTickets++; + } + else + { + Politics.nPartyTickets++; + } + } + } } diff --git a/Patch/ResidentAIGetCarProbabilityPatch.cs b/Patch/ResidentAIGetCarProbabilityPatch.cs index b2bf1cf..faca4d0 100644 --- a/Patch/ResidentAIGetCarProbabilityPatch.cs +++ b/Patch/ResidentAIGetCarProbabilityPatch.cs @@ -7,36 +7,36 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class ResidentAIGetCarProbabilityPatch - { - public static MethodBase TargetMethod() - { - return typeof(ResidentAI).GetMethod("GetCarProbability", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(CitizenInstance).MakeByRefType(), typeof(Citizen.AgeGroup)}, null); - } - [HarmonyPriority(Priority.First)] - public static void Prefix(ref CitizenInstance citizenData, ref Citizen.AgeGroup ageGroup) - { - if (RealCity.noPassengerCar) - { - CitizenManager instance = Singleton.instance; - var citizenID = citizenData.m_citizen; - ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); - if ((containingUnit == 0) || (citizenID == 0)) - { - //Change ageGroup to Child to disable car. - ageGroup = Citizen.AgeGroup.Child; - } - else - { - if (CitizenUnitData.familyMoney[containingUnit] < MainDataStore.highWealth) - { - ageGroup = Citizen.AgeGroup.Child; - } - } - } - } - } + [HarmonyPatch] + public class ResidentAIGetCarProbabilityPatch + { + public static MethodBase TargetMethod() + { + return typeof(ResidentAI).GetMethod("GetCarProbability", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(CitizenInstance).MakeByRefType(), typeof(Citizen.AgeGroup) }, null); + } + [HarmonyPriority(Priority.First)] + public static void Prefix(ref CitizenInstance citizenData, ref Citizen.AgeGroup ageGroup) + { + if (RealCity.noPassengerCar) + { + CitizenManager instance = Singleton.instance; + var citizenID = citizenData.m_citizen; + ushort homeBuilding = instance.m_citizens.m_buffer[citizenID].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = instance.m_citizens.m_buffer[citizenID].GetContainingUnit((uint)citizenID, citizenUnit, CitizenUnit.Flags.Home); + if ((containingUnit == 0) || (citizenID == 0)) + { + //Change ageGroup to Child to disable car. + ageGroup = Citizen.AgeGroup.Child; + } + else + { + if (CitizenUnitData.familyMoney[containingUnit] < MainDataStore.highWealth) + { + ageGroup = Citizen.AgeGroup.Child; + } + } + } + } + } } diff --git a/Patch/TaxiAIUnloadPassengersPatch.cs b/Patch/TaxiAIUnloadPassengersPatch.cs index 784b1a8..9e897fe 100644 --- a/Patch/TaxiAIUnloadPassengersPatch.cs +++ b/Patch/TaxiAIUnloadPassengersPatch.cs @@ -8,62 +8,62 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class TaxiAIUnloadPassengersPatch - { - public static MethodBase TargetMethod() - { - return typeof(TaxiAI).GetMethod("UnloadPassengers", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType(), typeof(TransportPassengerData).MakeByRefType() }, null); - } - public static void Prefix(ref TaxiAI __instance, ref Vehicle data) - { - CitizenManager instance = Singleton.instance; - Vector3 lastFramePosition = data.GetLastFramePosition(); - uint num2 = data.m_citizenUnits; - int num3 = 0; - while (num2 != 0u) - { - uint nextUnit = instance.m_units.m_buffer[(int)((UIntPtr)num2)].m_nextUnit; - for (int i = 0; i < 5; i++) - { - uint citizen = instance.m_units.m_buffer[(int)((UIntPtr)num2)].GetCitizen(i); - if (citizen != 0u) - { - ushort instance2 = instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_instance; - if (instance2 != 0) - { - Vector3 lastFramePosition2 = instance.m_instances.m_buffer[instance2].GetLastFramePosition(); - int expense = Mathf.RoundToInt(__instance.m_transportInfo.m_ticketPrice * Vector3.Distance(lastFramePosition2, lastFramePosition) * 0.001f); - //new added begin - if (expense != 0) - { - //DebugLog.LogToFileOnly("UnloadPassengers ticketPrice pre = " + num4.ToString()); - if ((Singleton.instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) == Citizen.Flags.None) - { - CitizenData.citizenMoney[citizen] -= (expense); - } - else - { - if (CitizenData.citizenMoney[citizen] < expense) - { - expense = (CitizenData.citizenMoney[citizen] > 0) ? (int)CitizenData.citizenMoney[citizen] + 1 : 1; - CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - (expense) - 1); - MainDataStore.outsideTouristMoney -= (expense + 1); - } - } - Singleton.instance.AddResource(EconomyManager.Resource.PublicIncome, expense, data.Info.m_class); - } - //new added end - } - } - } - num2 = nextUnit; - if (++num3 > 524288) - { - CODebugBase.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); - break; - } - } - } - } + [HarmonyPatch] + public class TaxiAIUnloadPassengersPatch + { + public static MethodBase TargetMethod() + { + return typeof(TaxiAI).GetMethod("UnloadPassengers", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType(), typeof(TransportPassengerData).MakeByRefType() }, null); + } + public static void Prefix(ref TaxiAI __instance, ref Vehicle data) + { + CitizenManager instance = Singleton.instance; + Vector3 lastFramePosition = data.GetLastFramePosition(); + uint num2 = data.m_citizenUnits; + int num3 = 0; + while (num2 != 0u) + { + uint nextUnit = instance.m_units.m_buffer[(int)((UIntPtr)num2)].m_nextUnit; + for (int i = 0; i < 5; i++) + { + uint citizen = instance.m_units.m_buffer[(int)((UIntPtr)num2)].GetCitizen(i); + if (citizen != 0u) + { + ushort instance2 = instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_instance; + if (instance2 != 0) + { + Vector3 lastFramePosition2 = instance.m_instances.m_buffer[instance2].GetLastFramePosition(); + int expense = Mathf.RoundToInt(__instance.m_transportInfo.m_ticketPrice * Vector3.Distance(lastFramePosition2, lastFramePosition) * 0.001f); + //new added begin + if (expense != 0) + { + //DebugLog.LogToFileOnly("UnloadPassengers ticketPrice pre = " + num4.ToString()); + if ((Singleton.instance.m_citizens.m_buffer[citizen].m_flags & Citizen.Flags.Tourist) == Citizen.Flags.None) + { + CitizenData.citizenMoney[citizen] -= (expense); + } + else + { + if (CitizenData.citizenMoney[citizen] < expense) + { + expense = (CitizenData.citizenMoney[citizen] > 0) ? (int)CitizenData.citizenMoney[citizen] + 1 : 1; + CitizenData.citizenMoney[citizen] = (CitizenData.citizenMoney[citizen] - (expense) - 1); + MainDataStore.outsideTouristMoney -= (expense + 1); + } + } + Singleton.instance.AddResource(EconomyManager.Resource.PublicIncome, expense, data.Info.m_class); + } + //new added end + } + } + } + num2 = nextUnit; + if (++num3 > 524288) + { + CODebugBase.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); + break; + } + } + } + } } diff --git a/Patch/TollBoothAIGetResourceRatePatch.cs b/Patch/TollBoothAIGetResourceRatePatch.cs index 2e17972..97bd116 100644 --- a/Patch/TollBoothAIGetResourceRatePatch.cs +++ b/Patch/TollBoothAIGetResourceRatePatch.cs @@ -7,20 +7,20 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class TollBoothAIGetResourceRatePatch - { - public static MethodBase TargetMethod() - { - return typeof(TollBoothAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); - } - public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) - { - if (resource == EconomyManager.Resource.Maintenance) - { - float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); - __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); - } - } - } + [HarmonyPatch] + public class TollBoothAIGetResourceRatePatch + { + public static MethodBase TargetMethod() + { + return typeof(TollBoothAI).GetMethod("GetResourceRate", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(EconomyManager.Resource) }, null); + } + public static void Postfix(ushort buildingID, ref Building data, EconomyManager.Resource resource, ref int __result) + { + if (resource == EconomyManager.Resource.Maintenance) + { + float salary = RealCityPlayerBuildingAI.CaculateEmployeeOutcome(buildingID, data); + __result = (int)((float)__result / MainDataStore.gameExpenseDivide - salary * 100f); + } + } + } } diff --git a/Patch/TollBoothEnterBuildingSegmentPatch.cs b/Patch/TollBoothEnterBuildingSegmentPatch.cs index 0f70064..56fa21d 100644 --- a/Patch/TollBoothEnterBuildingSegmentPatch.cs +++ b/Patch/TollBoothEnterBuildingSegmentPatch.cs @@ -6,80 +6,80 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class TollBoothEnterBuildingSegmentPatch - { - public static MethodBase TargetMethod() - { - return typeof(TollBoothAI).GetMethod("EnterBuildingSegment", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(ushort), typeof(byte), typeof(InstanceID) }, null); - } + [HarmonyPatch] + public class TollBoothEnterBuildingSegmentPatch + { + public static MethodBase TargetMethod() + { + return typeof(TollBoothAI).GetMethod("EnterBuildingSegment", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Building).MakeByRefType(), typeof(ushort), typeof(byte), typeof(InstanceID) }, null); + } - public static bool Prefix(ref Building data, InstanceID itemID) - { - bool canCharge = false; - if ((data.m_flags & Building.Flags.Active) != Building.Flags.None) - { - ushort vehicle = itemID.Vehicle; - if (vehicle != 0) - { - VehicleManager instance = Singleton.instance; - Vehicle vehicleData = instance.m_vehicles.m_buffer[vehicle]; - VehicleInfo info = instance.m_vehicles.m_buffer[vehicle].Info; - if (vehicleData.m_transferType != 212 && vehicleData.m_transferType != 213) - { - if (!VehicleData.isVehicleCharged[vehicle]) - { - if (info.m_vehicleAI is CargoTruckAI && (instance.m_vehicles.m_buffer[vehicle].m_flags.IsFlagSet(Vehicle.Flags.DummyTraffic))) - { - canCharge = true; - VehicleData.isVehicleCharged[vehicle] = true; - } - else if (info.m_vehicleAI is PassengerCarAI) - { - bool isTourist = false; - bool isDummy = false; - if (instance.m_vehicles.m_buffer[vehicle].m_citizenUnits != 0) - { - CitizenManager instance2 = Singleton.instance; - if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen0 != 0) - { - isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen0].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); - isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen0].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); - } - if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen1 != 0) - { - isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen1].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); - isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen1].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); - } - if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen2 != 0) - { - isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen2].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); - isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen2].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); + public static bool Prefix(ref Building data, InstanceID itemID) + { + bool canCharge = false; + if ((data.m_flags & Building.Flags.Active) != Building.Flags.None) + { + ushort vehicle = itemID.Vehicle; + if (vehicle != 0) + { + VehicleManager instance = Singleton.instance; + Vehicle vehicleData = instance.m_vehicles.m_buffer[vehicle]; + VehicleInfo info = instance.m_vehicles.m_buffer[vehicle].Info; + if (vehicleData.m_transferType != 212 && vehicleData.m_transferType != 213) + { + if (!VehicleData.isVehicleCharged[vehicle]) + { + if (info.m_vehicleAI is CargoTruckAI && (instance.m_vehicles.m_buffer[vehicle].m_flags.IsFlagSet(Vehicle.Flags.DummyTraffic))) + { + canCharge = true; + VehicleData.isVehicleCharged[vehicle] = true; + } + else if (info.m_vehicleAI is PassengerCarAI) + { + bool isTourist = false; + bool isDummy = false; + if (instance.m_vehicles.m_buffer[vehicle].m_citizenUnits != 0) + { + CitizenManager instance2 = Singleton.instance; + if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen0 != 0) + { + isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen0].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); + isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen0].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); + } + if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen1 != 0) + { + isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen1].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); + isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen1].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); + } + if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen2 != 0) + { + isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen2].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); + isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen2].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); - } - if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen3 != 0) - { - isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen3].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); - isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen3].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); - } - if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen4 != 0) - { - isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen4].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); - isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen4].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); - } - } - if (isDummy || isTourist) - { - VehicleData.isVehicleCharged[vehicle] = true; - canCharge = true; - } - } - } - } - } - } - if (!canCharge) { return false; } - return true; - } - } + } + if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen3 != 0) + { + isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen3].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); + isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen3].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); + } + if (instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen4 != 0) + { + isTourist = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen4].m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None); + isDummy = ((instance2.m_citizens.m_buffer[instance2.m_units.m_buffer[instance.m_vehicles.m_buffer[vehicle].m_citizenUnits].m_citizen4].m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None); + } + } + if (isDummy || isTourist) + { + VehicleData.isVehicleCharged[vehicle] = true; + canCharge = true; + } + } + } + } + } + } + if (!canCharge) { return false; } + return true; + } + } } diff --git a/Patch/TouristAISimulationStepPatch.cs b/Patch/TouristAISimulationStepPatch.cs index 89528b8..abc22d8 100644 --- a/Patch/TouristAISimulationStepPatch.cs +++ b/Patch/TouristAISimulationStepPatch.cs @@ -1,4 +1,4 @@ -using ColossalFramework; +using ColossalFramework; using HarmonyLib; using RealCity.CustomData; using RealCity.Util; @@ -7,49 +7,49 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class TouristAISimulationStepPatch - { - public static ushort touristCount; - public static MethodBase TargetMethod() - { - return typeof(TouristAI).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(uint), typeof(Citizen).MakeByRefType() }, null); - } - public static void Postfix(uint citizenID, ref Citizen data) - { - if (!data.m_flags.IsFlagSet(Citizen.Flags.DummyTraffic)) - { - if (CitizenData.citizenMoney[citizenID] < 100) - { - FindVisitPlace(citizenID, data.m_visitBuilding, GetLeavingReason(ref data)); - } - } - } + [HarmonyPatch] + public class TouristAISimulationStepPatch + { + public static ushort touristCount; + public static MethodBase TargetMethod() + { + return typeof(TouristAI).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(uint), typeof(Citizen).MakeByRefType() }, null); + } + public static void Postfix(uint citizenID, ref Citizen data) + { + if (!data.m_flags.IsFlagSet(Citizen.Flags.DummyTraffic)) + { + if (CitizenData.citizenMoney[citizenID] < 100) + { + FindVisitPlace(citizenID, data.m_visitBuilding, GetLeavingReason(ref data)); + } + } + } - public static TransferManager.TransferReason GetLeavingReason(ref Citizen data) - { - switch (data.WealthLevel) - { - case Citizen.Wealth.Low: - return TransferManager.TransferReason.LeaveCity0; - case Citizen.Wealth.Medium: - return TransferManager.TransferReason.LeaveCity1; - case Citizen.Wealth.High: - return TransferManager.TransferReason.LeaveCity2; - default: - return TransferManager.TransferReason.LeaveCity0; - } - } + public static TransferManager.TransferReason GetLeavingReason(ref Citizen data) + { + switch (data.WealthLevel) + { + case Citizen.Wealth.Low: + return TransferManager.TransferReason.LeaveCity0; + case Citizen.Wealth.Medium: + return TransferManager.TransferReason.LeaveCity1; + case Citizen.Wealth.High: + return TransferManager.TransferReason.LeaveCity2; + default: + return TransferManager.TransferReason.LeaveCity0; + } + } - public static void FindVisitPlace(uint citizenID, ushort sourceBuilding, TransferManager.TransferReason reason) - { - TransferManager.TransferOffer offer = default; - offer.Priority = Singleton.instance.m_randomizer.Int32(7u); - offer.Citizen = citizenID; - offer.Position = Singleton.instance.m_buildings.m_buffer[sourceBuilding].m_position; - offer.Amount = 1; - offer.Active = true; - Singleton.instance.AddIncomingOffer(reason, offer); - } - } + public static void FindVisitPlace(uint citizenID, ushort sourceBuilding, TransferManager.TransferReason reason) + { + TransferManager.TransferOffer offer = default; + offer.Priority = Singleton.instance.m_randomizer.Int32(7u); + offer.Citizen = citizenID; + offer.Position = Singleton.instance.m_buildings.m_buffer[sourceBuilding].m_position; + offer.Amount = 1; + offer.Active = true; + Singleton.instance.AddIncomingOffer(reason, offer); + } + } } \ No newline at end of file diff --git a/Patch/TransferManagerAddIncomingOfferPatch.cs b/Patch/TransferManagerAddIncomingOfferPatch.cs index 5aac505..39ea20e 100644 --- a/Patch/TransferManagerAddIncomingOfferPatch.cs +++ b/Patch/TransferManagerAddIncomingOfferPatch.cs @@ -10,167 +10,167 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class TransferManagerAddIncomingOfferPatch - { - public static MethodBase TargetMethod() - { - return typeof(TransferManager).GetMethod("AddIncomingOffer", BindingFlags.Public | BindingFlags.Instance); - } + [HarmonyPatch] + public class TransferManagerAddIncomingOfferPatch + { + public static MethodBase TargetMethod() + { + return typeof(TransferManager).GetMethod("AddIncomingOffer", BindingFlags.Public | BindingFlags.Instance); + } - [HarmonyPriority(Priority.First)] - public static bool Prefix(TransferManager.TransferReason material, ref TransferManager.TransferOffer offer) - { - switch (material) - { - case TransferManager.TransferReason.Shopping: - case TransferManager.TransferReason.ShoppingB: - case TransferManager.TransferReason.ShoppingC: - case TransferManager.TransferReason.ShoppingD: - case TransferManager.TransferReason.ShoppingE: - case TransferManager.TransferReason.ShoppingF: - case TransferManager.TransferReason.ShoppingG: - case TransferManager.TransferReason.ShoppingH: - case TransferManager.TransferReason.Entertainment: - case TransferManager.TransferReason.EntertainmentB: - case TransferManager.TransferReason.EntertainmentC: - case TransferManager.TransferReason.EntertainmentD: - case TransferManager.TransferReason.TouristA: - case TransferManager.TransferReason.TouristB: - case TransferManager.TransferReason.TouristC: - case TransferManager.TransferReason.TouristD: - if (RealCity.realCityV10) - { - if (MainDataStore.outsideTouristMoney < 0) - { - if (Singleton.instance.m_buildings.m_buffer[offer.Building].Info.m_buildingAI is OutsideConnectionAI) - return false; - } - } - break; - case TransferManager.TransferReason.Oil: - case TransferManager.TransferReason.Ore: - case TransferManager.TransferReason.Coal: - case TransferManager.TransferReason.Petrol: - case TransferManager.TransferReason.Food: - case TransferManager.TransferReason.Grain: - case TransferManager.TransferReason.Lumber: - case TransferManager.TransferReason.Logs: - case TransferManager.TransferReason.Goods: - case TransferManager.TransferReason.LuxuryProducts: - case TransferManager.TransferReason.AnimalProducts: - case TransferManager.TransferReason.Flours: - case TransferManager.TransferReason.Petroleum: - case TransferManager.TransferReason.Plastics: - case TransferManager.TransferReason.Metals: - case TransferManager.TransferReason.Glass: - case TransferManager.TransferReason.PlanedTimber: - case TransferManager.TransferReason.Paper: - break; - default: - return true; - } - - if (offer.Citizen != 0) - { - var instance = Singleton.instance; - ushort homeBuilding = instance.m_citizens.m_buffer[offer.Citizen].m_homeBuilding; - uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); - uint containingUnit = instance.m_citizens.m_buffer[offer.Citizen].GetContainingUnit((uint)offer.Citizen, citizenUnit, CitizenUnit.Flags.Home); + [HarmonyPriority(Priority.First)] + public static bool Prefix(TransferManager.TransferReason material, ref TransferManager.TransferOffer offer) + { + switch (material) + { + case TransferManager.TransferReason.Shopping: + case TransferManager.TransferReason.ShoppingB: + case TransferManager.TransferReason.ShoppingC: + case TransferManager.TransferReason.ShoppingD: + case TransferManager.TransferReason.ShoppingE: + case TransferManager.TransferReason.ShoppingF: + case TransferManager.TransferReason.ShoppingG: + case TransferManager.TransferReason.ShoppingH: + case TransferManager.TransferReason.Entertainment: + case TransferManager.TransferReason.EntertainmentB: + case TransferManager.TransferReason.EntertainmentC: + case TransferManager.TransferReason.EntertainmentD: + case TransferManager.TransferReason.TouristA: + case TransferManager.TransferReason.TouristB: + case TransferManager.TransferReason.TouristC: + case TransferManager.TransferReason.TouristD: + if (RealCity.realCityV10) + { + if (MainDataStore.outsideTouristMoney < 0) + { + if (Singleton.instance.m_buildings.m_buffer[offer.Building].Info.m_buildingAI is OutsideConnectionAI) + return false; + } + } + break; + case TransferManager.TransferReason.Oil: + case TransferManager.TransferReason.Ore: + case TransferManager.TransferReason.Coal: + case TransferManager.TransferReason.Petrol: + case TransferManager.TransferReason.Food: + case TransferManager.TransferReason.Grain: + case TransferManager.TransferReason.Lumber: + case TransferManager.TransferReason.Logs: + case TransferManager.TransferReason.Goods: + case TransferManager.TransferReason.LuxuryProducts: + case TransferManager.TransferReason.AnimalProducts: + case TransferManager.TransferReason.Flours: + case TransferManager.TransferReason.Petroleum: + case TransferManager.TransferReason.Plastics: + case TransferManager.TransferReason.Metals: + case TransferManager.TransferReason.Glass: + case TransferManager.TransferReason.PlanedTimber: + case TransferManager.TransferReason.Paper: + break; + default: + return true; + } - if (!instance.m_citizens.m_buffer[offer.Citizen].m_flags.IsFlagSet(Citizen.Flags.Tourist)) - { - if (CitizenUnitData.familyMoney[containingUnit] < MainDataStore.maxGoodPurchase * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)) - { - //Reject poor citizen to building - return false; - } - } - } - else if (offer.Building != 0) - { - var instance = Singleton.instance; - var buildingID = offer.Building; - var buildingData = instance.m_buildings.m_buffer[buildingID]; - if (buildingData.Info.m_class.m_service == ItemClass.Service.Industrial) - { - RealCityIndustrialBuildingAI.InitDelegate(); - RealCityCommonBuildingAI.InitDelegate(); - var industrialBuildingAI = buildingData.Info.m_buildingAI as IndustrialBuildingAI; - TransferManager.TransferReason incomingTransferReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID); - TransferManager.TransferReason secondaryIncomingTransferReason = RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID); - int maxIncomingLoadSize = RealCityIndustrialBuildingAI.MaxIncomingLoadSize((IndustrialBuildingAI)(buildingData.Info.m_buildingAI)); - int num = 0; - int num1 = 0; - int incomingCargoCapacity = 0; - int value = 0; - if (incomingTransferReason != TransferManager.TransferReason.None) - { - if (secondaryIncomingTransferReason != TransferManager.TransferReason.None) - { - RealCityCommonBuildingAI.CalculateGuestVehicles1((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, secondaryIncomingTransferReason, ref num, ref num1, ref incomingCargoCapacity, ref value); - } - else - { - RealCityCommonBuildingAI.CalculateGuestVehicles((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, ref num, ref num1, ref incomingCargoCapacity, ref value); - } - } - int productionCapacity = industrialBuildingAI.CalculateProductionCapacity((ItemClass.Level)buildingData.m_level, new Randomizer((int)buildingID), buildingData.m_width, buildingData.m_length); - int consumptionDivider = RealCityIndustrialBuildingAI.GetConsumptionDivider((IndustrialBuildingAI)(buildingData.Info.m_buildingAI)); - int fullCapacity = Mathf.Max(productionCapacity * 500 / consumptionDivider, maxIncomingLoadSize * 4); - int incomingAmontNeeded = fullCapacity - (int)buildingData.m_customBuffer1 - incomingCargoCapacity; - incomingAmontNeeded -= 8000; + if (offer.Citizen != 0) + { + var instance = Singleton.instance; + ushort homeBuilding = instance.m_citizens.m_buffer[offer.Citizen].m_homeBuilding; + uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); + uint containingUnit = instance.m_citizens.m_buffer[offer.Citizen].GetContainingUnit((uint)offer.Citizen, citizenUnit, CitizenUnit.Flags.Home); - if (incomingAmontNeeded < 0) - { - return false; - } - else - { - if (material == incomingTransferReason) - { - //first remove. - //game bug, will send 2 incomingTransferReason per period - TransferManager.TransferOffer offer1 = default; - offer1.Building = buildingID; - Singleton.instance.RemoveIncomingOffer(incomingTransferReason, offer1); - } - } - } - else if(buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) - { - RealCityCommercialBuildingAI.InitDelegate(); - RealCityCommonBuildingAI.InitDelegate(); - var commercialBuildingAI = buildingData.Info.m_buildingAI as CommercialBuildingAI; - int maxIncomingLoadSize = RealCityCommercialBuildingAI.MaxIncomingLoadSize((CommercialBuildingAI)(buildingData.Info.m_buildingAI)); - int visitplaceCount = commercialBuildingAI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer((int)buildingID), buildingData.m_width, buildingData.m_length); - int fullCapacity = Mathf.Max(visitplaceCount * 500, maxIncomingLoadSize * 4); - int num = 0; - int num1 = 0; - int incomingCargoCapacity = 0; - int value = 0; - TransferManager.TransferReason incomingTransferReason = RealCityCommercialBuildingAI.GetIncomingTransferReason((CommercialBuildingAI)(buildingData.Info.m_buildingAI)); - if (incomingTransferReason != TransferManager.TransferReason.None) - { - if (incomingTransferReason == TransferManager.TransferReason.Goods || incomingTransferReason == TransferManager.TransferReason.Food) - { - RealCityCommonBuildingAI.CalculateGuestVehicles1((CommercialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, TransferManager.TransferReason.LuxuryProducts, ref num, ref num1, ref incomingCargoCapacity, ref value); - } - else - { - RealCityCommonBuildingAI.CalculateGuestVehicles((CommercialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, ref num, ref num1, ref incomingCargoCapacity, ref value); - } - buildingData.m_tempImport = (byte)Mathf.Clamp(value, (int)buildingData.m_tempImport, 255); - } - int incomingAmontNeeded = fullCapacity - (int)buildingData.m_customBuffer1 - incomingCargoCapacity; - incomingAmontNeeded -= 6000; - if (incomingAmontNeeded < 0) - { - return false; - } - } - } - return true; - } - } + if (!instance.m_citizens.m_buffer[offer.Citizen].m_flags.IsFlagSet(Citizen.Flags.Tourist)) + { + if (CitizenUnitData.familyMoney[containingUnit] < MainDataStore.maxGoodPurchase * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)) + { + //Reject poor citizen to building + return false; + } + } + } + else if (offer.Building != 0) + { + var instance = Singleton.instance; + var buildingID = offer.Building; + var buildingData = instance.m_buildings.m_buffer[buildingID]; + if (buildingData.Info.m_class.m_service == ItemClass.Service.Industrial) + { + RealCityIndustrialBuildingAI.InitDelegate(); + RealCityCommonBuildingAI.InitDelegate(); + var industrialBuildingAI = buildingData.Info.m_buildingAI as IndustrialBuildingAI; + TransferManager.TransferReason incomingTransferReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID); + TransferManager.TransferReason secondaryIncomingTransferReason = RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID); + int maxIncomingLoadSize = RealCityIndustrialBuildingAI.MaxIncomingLoadSize((IndustrialBuildingAI)(buildingData.Info.m_buildingAI)); + int num = 0; + int num1 = 0; + int incomingCargoCapacity = 0; + int value = 0; + if (incomingTransferReason != TransferManager.TransferReason.None) + { + if (secondaryIncomingTransferReason != TransferManager.TransferReason.None) + { + RealCityCommonBuildingAI.CalculateGuestVehicles1((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, secondaryIncomingTransferReason, ref num, ref num1, ref incomingCargoCapacity, ref value); + } + else + { + RealCityCommonBuildingAI.CalculateGuestVehicles((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, ref num, ref num1, ref incomingCargoCapacity, ref value); + } + } + int productionCapacity = industrialBuildingAI.CalculateProductionCapacity((ItemClass.Level)buildingData.m_level, new Randomizer((int)buildingID), buildingData.m_width, buildingData.m_length); + int consumptionDivider = RealCityIndustrialBuildingAI.GetConsumptionDivider((IndustrialBuildingAI)(buildingData.Info.m_buildingAI)); + int fullCapacity = Mathf.Max(productionCapacity * 500 / consumptionDivider, maxIncomingLoadSize * 4); + int incomingAmontNeeded = fullCapacity - (int)buildingData.m_customBuffer1 - incomingCargoCapacity; + incomingAmontNeeded -= 8000; + + if (incomingAmontNeeded < 0) + { + return false; + } + else + { + if (material == incomingTransferReason) + { + //first remove. + //game bug, will send 2 incomingTransferReason per period + TransferManager.TransferOffer offer1 = default; + offer1.Building = buildingID; + Singleton.instance.RemoveIncomingOffer(incomingTransferReason, offer1); + } + } + } + else if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) + { + RealCityCommercialBuildingAI.InitDelegate(); + RealCityCommonBuildingAI.InitDelegate(); + var commercialBuildingAI = buildingData.Info.m_buildingAI as CommercialBuildingAI; + int maxIncomingLoadSize = RealCityCommercialBuildingAI.MaxIncomingLoadSize((CommercialBuildingAI)(buildingData.Info.m_buildingAI)); + int visitplaceCount = commercialBuildingAI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer((int)buildingID), buildingData.m_width, buildingData.m_length); + int fullCapacity = Mathf.Max(visitplaceCount * 500, maxIncomingLoadSize * 4); + int num = 0; + int num1 = 0; + int incomingCargoCapacity = 0; + int value = 0; + TransferManager.TransferReason incomingTransferReason = RealCityCommercialBuildingAI.GetIncomingTransferReason((CommercialBuildingAI)(buildingData.Info.m_buildingAI)); + if (incomingTransferReason != TransferManager.TransferReason.None) + { + if (incomingTransferReason == TransferManager.TransferReason.Goods || incomingTransferReason == TransferManager.TransferReason.Food) + { + RealCityCommonBuildingAI.CalculateGuestVehicles1((CommercialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, TransferManager.TransferReason.LuxuryProducts, ref num, ref num1, ref incomingCargoCapacity, ref value); + } + else + { + RealCityCommonBuildingAI.CalculateGuestVehicles((CommercialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, ref num, ref num1, ref incomingCargoCapacity, ref value); + } + buildingData.m_tempImport = (byte)Mathf.Clamp(value, (int)buildingData.m_tempImport, 255); + } + int incomingAmontNeeded = fullCapacity - (int)buildingData.m_customBuffer1 - incomingCargoCapacity; + incomingAmontNeeded -= 6000; + if (incomingAmontNeeded < 0) + { + return false; + } + } + } + return true; + } + } } \ No newline at end of file diff --git a/Patch/TransferManagerAddOutgoingOfferPatch.cs b/Patch/TransferManagerAddOutgoingOfferPatch.cs index 26ec774..6aa45bb 100644 --- a/Patch/TransferManagerAddOutgoingOfferPatch.cs +++ b/Patch/TransferManagerAddOutgoingOfferPatch.cs @@ -19,77 +19,77 @@ public static MethodBase TargetMethod() [HarmonyPriority(Priority.VeryHigh)] public static bool Prefix(ref TransferManager.TransferReason material, ref TransferManager.TransferOffer offer) { - switch (material) - { - case TransferManager.TransferReason.Shopping: - case TransferManager.TransferReason.ShoppingB: - case TransferManager.TransferReason.ShoppingC: - case TransferManager.TransferReason.ShoppingD: - case TransferManager.TransferReason.ShoppingE: - case TransferManager.TransferReason.ShoppingF: - case TransferManager.TransferReason.ShoppingG: - case TransferManager.TransferReason.ShoppingH: - case TransferManager.TransferReason.Entertainment: - case TransferManager.TransferReason.EntertainmentB: - case TransferManager.TransferReason.EntertainmentC: - case TransferManager.TransferReason.EntertainmentD: - break; - default: - return true; - } + switch (material) + { + case TransferManager.TransferReason.Shopping: + case TransferManager.TransferReason.ShoppingB: + case TransferManager.TransferReason.ShoppingC: + case TransferManager.TransferReason.ShoppingD: + case TransferManager.TransferReason.ShoppingE: + case TransferManager.TransferReason.ShoppingF: + case TransferManager.TransferReason.ShoppingG: + case TransferManager.TransferReason.ShoppingH: + case TransferManager.TransferReason.Entertainment: + case TransferManager.TransferReason.EntertainmentB: + case TransferManager.TransferReason.EntertainmentC: + case TransferManager.TransferReason.EntertainmentD: + break; + default: + return true; + } - var instance = Singleton.instance; - var buildingID = offer.Building; - if (buildingID != 0) - { - var buildingData = instance.m_buildings.m_buffer[buildingID]; - if (instance.m_buildings.m_buffer[buildingID].Info.m_class.m_service == ItemClass.Service.Commercial) - { - Citizen.BehaviourData behaviour = default; - int aliveVisitCount = 0; - int totalVisitCount = 0; - RealCityCommercialBuildingAI.InitDelegate(); - RealCityCommercialBuildingAI.GetVisitBehaviour((CommercialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount); - var AI = buildingData.Info.m_buildingAI as CommercialBuildingAI; - var maxCount = AI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer(buildingID), buildingData.m_width, buildingData.m_length); - var amount = Math.Min(buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount, maxCount - totalVisitCount); + var instance = Singleton.instance; + var buildingID = offer.Building; + if (buildingID != 0) + { + var buildingData = instance.m_buildings.m_buffer[buildingID]; + if (instance.m_buildings.m_buffer[buildingID].Info.m_class.m_service == ItemClass.Service.Commercial) + { + Citizen.BehaviourData behaviour = default; + int aliveVisitCount = 0; + int totalVisitCount = 0; + RealCityCommercialBuildingAI.InitDelegate(); + RealCityCommercialBuildingAI.GetVisitBehaviour((CommercialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount); + var AI = buildingData.Info.m_buildingAI as CommercialBuildingAI; + var maxCount = AI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer(buildingID), buildingData.m_width, buildingData.m_length); + var amount = Math.Min(buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount, maxCount - totalVisitCount); - if ((amount <= 0) || (maxCount <= totalVisitCount)) - { - buildingData.m_flags &= ~Building.Flags.Active; - //no resource - return false; - } - else - { - offer.Amount = amount; - return true; - } - } - else if (instance.m_buildings.m_buffer[buildingID].Info.m_class.m_service == ItemClass.Service.Fishing) - { - Citizen.BehaviourData behaviour = default; - int aliveVisitCount = 0; - int totalVisitCount = 0; - RealCityMarketAI.InitDelegate(); - RealCityMarketAI.GetVisitBehaviour((MarketAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount); - var amount = buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount; + if ((amount <= 0) || (maxCount <= totalVisitCount)) + { + buildingData.m_flags &= ~Building.Flags.Active; + //no resource + return false; + } + else + { + offer.Amount = amount; + return true; + } + } + else if (instance.m_buildings.m_buffer[buildingID].Info.m_class.m_service == ItemClass.Service.Fishing) + { + Citizen.BehaviourData behaviour = default; + int aliveVisitCount = 0; + int totalVisitCount = 0; + RealCityMarketAI.InitDelegate(); + RealCityMarketAI.GetVisitBehaviour((MarketAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount); + var amount = buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount; - if (amount <= 0) - { - buildingData.m_flags &= ~Building.Flags.Active; - //no resource - return false; - } - else - { - return true; - } - } - } + if (amount <= 0) + { + buildingData.m_flags &= ~Building.Flags.Active; + //no resource + return false; + } + else + { + return true; + } + } + } - //Remove cotenancy - if (material == TransferManager.TransferReason.Single0 || material == TransferManager.TransferReason.Single0B) + //Remove cotenancy + if (material == TransferManager.TransferReason.Single0 || material == TransferManager.TransferReason.Single0B) { material = TransferManager.TransferReason.Family0; } @@ -105,7 +105,7 @@ public static bool Prefix(ref TransferManager.TransferReason material, ref Trans { material = TransferManager.TransferReason.Family3; } - return true; + return true; } - } + } } \ No newline at end of file diff --git a/Patch/TransportLineCalculateTargetVehicleCountPatch.cs b/Patch/TransportLineCalculateTargetVehicleCountPatch.cs index 7f2391a..fcb9383 100644 --- a/Patch/TransportLineCalculateTargetVehicleCountPatch.cs +++ b/Patch/TransportLineCalculateTargetVehicleCountPatch.cs @@ -7,275 +7,278 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class TransportLineCalculateTargetVehicleCountPatch - { - public static MethodBase TargetMethod() - { - return typeof(TransportLine).GetMethod("CalculateTargetVehicleCount", BindingFlags.Public | BindingFlags.Instance); - } + [HarmonyPatch] + public class TransportLineCalculateTargetVehicleCountPatch + { + public static MethodBase TargetMethod() + { + return typeof(TransportLine).GetMethod("CalculateTargetVehicleCount", BindingFlags.Public | BindingFlags.Instance); + } - public static void Postfix(ref TransportLine __instance, ref int __result) - { - if (Loader.isTransportLinesManagerRunning) { return; } - float budget = 1f; - if (IsWeekend(Singleton.instance.m_currentGameTime)) - { - if (TransportLineData.WeekEndPlan[FindLineID(ref __instance)] == 1) - { - if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) - { - budget = OptionUI.morningBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) - { - budget = OptionUI.otherBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) - { - budget = OptionUI.eveningBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) - { - budget = OptionUI.otherBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) - { - budget = OptionUI.deepNightBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) - { - budget = OptionUI.otherBudgetWeekDay * 0.01f; - } - } - else if (TransportLineData.WeekEndPlan[FindLineID(ref __instance)] == 2) - { - if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) - { - budget = OptionUI.morningBudgetWeekEnd * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) - { - budget = OptionUI.otherBudgetWeekEnd * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) - { - budget = OptionUI.eveningBudgetWeekEnd * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) - { - budget = OptionUI.otherBudgetWeekEnd * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) - { - budget = OptionUI.deepNightBudgetWeekEnd * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) - { - budget = OptionUI.otherBudgetWeekEnd * 0.01f; - } - } - else if (TransportLineData.WeekEndPlan[FindLineID(ref __instance)] == 3) - { - if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) - { - budget = OptionUI.morningBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) - { - budget = OptionUI.otherBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) - { - budget = OptionUI.eveningBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) - { - budget = OptionUI.otherBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) - { - budget = OptionUI.deepNightBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) - { - budget = OptionUI.otherBudgetMax * 0.01f; - } - } - else if (TransportLineData.WeekEndPlan[FindLineID(ref __instance)] == 4) - { - if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) - { - budget = OptionUI.morningBudgetMin * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) - { - budget = OptionUI.otherBudgetMin * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) - { - budget = OptionUI.eveningBudgetMin * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) - { - budget = OptionUI.otherBudgetMin * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) - { - budget = OptionUI.deepNightBudgetMin * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) - { - budget = OptionUI.otherBudgetMin * 0.01f; - } - } - } - else - { - //PlanA - if (TransportLineData.WeekDayPlan[FindLineID(ref __instance)] == 1) - { - if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) - { - budget = OptionUI.morningBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) - { - budget = OptionUI.otherBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) - { - budget = OptionUI.eveningBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) - { - budget = OptionUI.otherBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) - { - budget = OptionUI.deepNightBudgetWeekDay * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) - { - budget = OptionUI.otherBudgetWeekDay * 0.01f; - } - } - else if (TransportLineData.WeekDayPlan[FindLineID(ref __instance)] == 2) - { - if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) - { - budget = OptionUI.morningBudgetWeekEnd * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) - { - budget = OptionUI.otherBudgetWeekEnd * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) - { - budget = OptionUI.eveningBudgetWeekEnd * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) - { - budget = OptionUI.otherBudgetWeekEnd * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) - { - budget = (OptionUI.deepNightBudgetWeekEnd) * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) - { - budget = OptionUI.otherBudgetWeekEnd * 0.01f; - } - } - else if (TransportLineData.WeekDayPlan[FindLineID(ref __instance)] == 3) - { - if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) - { - budget = OptionUI.morningBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) - { - budget = OptionUI.otherBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) - { - budget = OptionUI.eveningBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) - { - budget = OptionUI.otherBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) - { - budget = OptionUI.deepNightBudgetMax * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) - { - budget = OptionUI.otherBudgetMax * 0.01f; - } - } - else if (TransportLineData.WeekDayPlan[FindLineID(ref __instance)] == 4) - { - if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) - { - budget = (OptionUI.morningBudgetMin) * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) - { - budget = (OptionUI.otherBudgetMin) * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) - { - budget = (OptionUI.eveningBudgetMin) * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) - { - budget = (OptionUI.otherBudgetMin) * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) - { - budget = (OptionUI.deepNightBudgetMin) * 0.01f; - } - else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) - { - budget = (OptionUI.otherBudgetMin) * 0.01f; - } - } - } + public static void Postfix(ref TransportLine __instance, ref int __result) + { + if (Loader.isTransportLinesManagerRunning) + { + return; + } + float budget = 1f; + if (IsWeekend(Singleton.instance.m_currentGameTime)) + { + if (TransportLineData.WeekEndPlan[FindLineID(ref __instance)] == 1) + { + if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) + { + budget = OptionUI.morningBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) + { + budget = OptionUI.otherBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) + { + budget = OptionUI.eveningBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) + { + budget = OptionUI.otherBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) + { + budget = OptionUI.deepNightBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) + { + budget = OptionUI.otherBudgetWeekDay * 0.01f; + } + } + else if (TransportLineData.WeekEndPlan[FindLineID(ref __instance)] == 2) + { + if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) + { + budget = OptionUI.morningBudgetWeekEnd * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) + { + budget = OptionUI.otherBudgetWeekEnd * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) + { + budget = OptionUI.eveningBudgetWeekEnd * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) + { + budget = OptionUI.otherBudgetWeekEnd * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) + { + budget = OptionUI.deepNightBudgetWeekEnd * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) + { + budget = OptionUI.otherBudgetWeekEnd * 0.01f; + } + } + else if (TransportLineData.WeekEndPlan[FindLineID(ref __instance)] == 3) + { + if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) + { + budget = OptionUI.morningBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) + { + budget = OptionUI.otherBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) + { + budget = OptionUI.eveningBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) + { + budget = OptionUI.otherBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) + { + budget = OptionUI.deepNightBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) + { + budget = OptionUI.otherBudgetMax * 0.01f; + } + } + else if (TransportLineData.WeekEndPlan[FindLineID(ref __instance)] == 4) + { + if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) + { + budget = OptionUI.morningBudgetMin * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) + { + budget = OptionUI.otherBudgetMin * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) + { + budget = OptionUI.eveningBudgetMin * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) + { + budget = OptionUI.otherBudgetMin * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) + { + budget = OptionUI.deepNightBudgetMin * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) + { + budget = OptionUI.otherBudgetMin * 0.01f; + } + } + } + else + { + //PlanA + if (TransportLineData.WeekDayPlan[FindLineID(ref __instance)] == 1) + { + if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) + { + budget = OptionUI.morningBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) + { + budget = OptionUI.otherBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) + { + budget = OptionUI.eveningBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) + { + budget = OptionUI.otherBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) + { + budget = OptionUI.deepNightBudgetWeekDay * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) + { + budget = OptionUI.otherBudgetWeekDay * 0.01f; + } + } + else if (TransportLineData.WeekDayPlan[FindLineID(ref __instance)] == 2) + { + if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) + { + budget = OptionUI.morningBudgetWeekEnd * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) + { + budget = OptionUI.otherBudgetWeekEnd * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) + { + budget = OptionUI.eveningBudgetWeekEnd * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) + { + budget = OptionUI.otherBudgetWeekEnd * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) + { + budget = (OptionUI.deepNightBudgetWeekEnd) * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) + { + budget = OptionUI.otherBudgetWeekEnd * 0.01f; + } + } + else if (TransportLineData.WeekDayPlan[FindLineID(ref __instance)] == 3) + { + if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) + { + budget = OptionUI.morningBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) + { + budget = OptionUI.otherBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) + { + budget = OptionUI.eveningBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) + { + budget = OptionUI.otherBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) + { + budget = OptionUI.deepNightBudgetMax * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) + { + budget = OptionUI.otherBudgetMax * 0.01f; + } + } + else if (TransportLineData.WeekDayPlan[FindLineID(ref __instance)] == 4) + { + if (Singleton.instance.m_currentGameTime.Hour >= 8 && Singleton.instance.m_currentGameTime.Hour < 10) + { + budget = (OptionUI.morningBudgetMin) * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 10 && Singleton.instance.m_currentGameTime.Hour < 17) + { + budget = (OptionUI.otherBudgetMin) * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 17 && Singleton.instance.m_currentGameTime.Hour < 19) + { + budget = (OptionUI.eveningBudgetMin) * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 19 && Singleton.instance.m_currentGameTime.Hour < 24) + { + budget = (OptionUI.otherBudgetMin) * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 0 && Singleton.instance.m_currentGameTime.Hour < 4) + { + budget = (OptionUI.deepNightBudgetMin) * 0.01f; + } + else if (Singleton.instance.m_currentGameTime.Hour >= 4 && Singleton.instance.m_currentGameTime.Hour < 8) + { + budget = (OptionUI.otherBudgetMin) * 0.01f; + } + } + } - __result = (int)(__result * budget); - if (__result <= 0) - __result = 1; - } + __result = (int)(__result * budget); + if (__result <= 0) + __result = 1; + } - public static bool IsWeekend(DateTime dateTime) - { - if (dateTime.DayOfWeek != DayOfWeek.Saturday) - { - return dateTime.DayOfWeek == DayOfWeek.Sunday; - } - return true; - } + public static bool IsWeekend(DateTime dateTime) + { + if (dateTime.DayOfWeek != DayOfWeek.Saturday) + { + return dateTime.DayOfWeek == DayOfWeek.Sunday; + } + return true; + } - public static ushort FindLineID(ref TransportLine transportLine) - { - for (int i = 0; i < 256; i++) - { - if (Singleton.instance.m_lines.m_buffer[i].m_flags.IsFlagSet(TransportLine.Flags.Created)) - { - if (transportLine.m_lineNumber != 0) - { - if (transportLine.Info.m_transportType == Singleton.instance.m_lines.m_buffer[i].Info.m_transportType) - { - if (transportLine.m_lineNumber == Singleton.instance.m_lines.m_buffer[i].m_lineNumber) - { - return (ushort)i; - } - } - } - } - } - return 0; - } - } -} + public static ushort FindLineID(ref TransportLine transportLine) + { + for (int i = 0; i < 256; i++) + { + if (Singleton.instance.m_lines.m_buffer[i].m_flags.IsFlagSet(TransportLine.Flags.Created)) + { + if (transportLine.m_lineNumber != 0) + { + if (transportLine.Info.m_transportType == Singleton.instance.m_lines.m_buffer[i].Info.m_transportType) + { + if (transportLine.m_lineNumber == Singleton.instance.m_lines.m_buffer[i].m_lineNumber) + { + return (ushort)i; + } + } + } + } + } + return 0; + } + } +} \ No newline at end of file diff --git a/Patch/VehicleManagerReleaseVehicleImplementationPatch.cs b/Patch/VehicleManagerReleaseVehicleImplementationPatch.cs index b68471a..ef4f7be 100644 --- a/Patch/VehicleManagerReleaseVehicleImplementationPatch.cs +++ b/Patch/VehicleManagerReleaseVehicleImplementationPatch.cs @@ -5,17 +5,17 @@ namespace RealCity.Patch { - [HarmonyPatch] - public class VehicleManagerReleaseVehicleImplementationPatch - { - public static MethodBase TargetMethod() - { - return typeof(VehicleManager).GetMethod("ReleaseVehicleImplementation", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType() }, null); - } - public static void Postfix(ushort vehicle) - { - VehicleData.vehicleTransferTime[vehicle] = 0; - VehicleData.isVehicleCharged[vehicle] = false; - } - } + [HarmonyPatch] + public class VehicleManagerReleaseVehicleImplementationPatch + { + public static MethodBase TargetMethod() + { + return typeof(VehicleManager).GetMethod("ReleaseVehicleImplementation", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort), typeof(Vehicle).MakeByRefType() }, null); + } + public static void Postfix(ushort vehicle) + { + VehicleData.vehicleTransferTime[vehicle] = 0; + VehicleData.isVehicleCharged[vehicle] = false; + } + } } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 745daff..4ea8581 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -9,7 +9,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RealCity")] -[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -32,4 +32,4 @@ // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("10.0.08.24")] -[assembly: AssemblyFileVersion("10.0.08.24")] +[assembly: AssemblyFileVersion("10.0.08.24")] \ No newline at end of file diff --git a/README.md b/README.md index 4d49ae9..7bc8c33 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,15 @@ -# RealCity [![Steam Downloads](https://img.shields.io/steam/downloads/1192503086.svg?label=Steam%20downloads&logo=steam)](https://steamcommunity.com/sharedfiles/filedetails/?id=1192503086) -Cities: Skylines Mod: Make your city act like a real world! Combine CS and Simcity in game playing! - -### MOD关系图 -![](https://github.com/pcfantasy/RealCity/blob/master/img/RealCityFlow.jpg) - -[English UG/详细说明书](https://github.com/pcfantasy/RealCity/wiki)
+# RealCity +Cities: Skylines Mod by [@pcfantasy](https://github.com/pcfantasy). +Make your city act like a real world! Combine CS and Simcity in game playing! +## Download +[![Steam Workshop](https://img.shields.io/steam/downloads/1192503086.svg?label=Steam%20Workshop&logo=steam)](https://steamcommunity.com/sharedfiles/filedetails/?id=1192503086) +It's available on Steam Workshop, but the game comtent may be somehow different from this fork. +## Userguide +Mod Wiki is available at [here \(English and Simplified Chinese\)](https://github.com/bac0id/RealCity-master/wiki). Also there are some [game guides \(Simplified Chinese\)](https://github.com/bac0id/RealCity-master/tree/master/%E4%B8%AD%E6%96%87%E6%94%BB%E7%95%A5) +有中文和英文版本的[模组Wiki](https://github.com/bac0id/RealCity-master/wiki)。这里也有原作者写的一些[攻略](https://github.com/bac0id/RealCity-master/tree/master/%E4%B8%AD%E6%96%87%E6%94%BB%E7%95%A5)。您也可以移步至[原主页](https://github.com/pcfantasy/RealCity)去查阅这些信息。 +## Inter Relationship +![](https://github.com/bac0id/RealCity-master/blob/master/img/RealCityFlow.jpg) +## Sponsor +You can donate something to the author [@pcfantasy](https://github.com/pcfantasy). +扫码让[原作者](https://github.com/pcfantasy)恰饭 +![](https://github.com/bac0id/RealCity-master/blob/master/%E8%B5%9E%E8%B5%8F%E7%A0%81.jpg) diff --git a/RealCity.cs b/RealCity.cs index 55c2d60..a35c7a9 100644 --- a/RealCity.cs +++ b/RealCity.cs @@ -7,86 +7,85 @@ namespace RealCity { - public class RealCity : IUserMod - { - public static bool IsEnabled = false; - public static bool debugMode = false; - public static bool reduceVehicle = false; - public static bool realCityV10 = true; - public static bool noPassengerCar = true; + public class RealCity : IUserMod + { + public static bool IsEnabled = false; + public static bool debugMode = false; + public static bool reduceVehicle = false; + public static bool realCityV10 = true; + public static bool noPassengerCar = true; - public string Name - { - get { return "Real City"; } - } + public string Name + { + get { return "Real City"; } + } - public string Description - { - get { return "Make your city reality, Combine CS and SimCity in game playing"; } - } + public string Description + { + get { return "Make your city reality, Combine CS and SimCity in game playing"; } + } - public void OnEnabled() - { - IsEnabled = true; - FileStream fs = File.Create("RealCity.txt"); - fs.Close(); - HarmonyHelper.EnsureHarmonyInstalled(); - if (UIView.GetAView() != null) - { - OnGameIntroLoaded(); - } - else - { - LoadingManager.instance.m_introLoaded += OnGameIntroLoaded; - } - } + public void OnEnabled() + { + IsEnabled = true; + FileStream fs = File.Create("RealCity.txt"); + fs.Close(); + HarmonyHelper.EnsureHarmonyInstalled(); + if (UIView.GetAView() != null) + { + OnGameIntroLoaded(); + } + else + { + LoadingManager.instance.m_introLoaded += OnGameIntroLoaded; + } + } - public void OnDisabled() - { - IsEnabled = false; - LoadingManager.instance.m_introLoaded -= OnGameIntroLoaded; - } + public void OnDisabled() + { + IsEnabled = false; + LoadingManager.instance.m_introLoaded -= OnGameIntroLoaded; + } - private static void OnGameIntroLoaded() - { - ModsCompatibilityChecker mcc = new ModsCompatibilityChecker(); - mcc.PerformModCheck(); - } + private static void OnGameIntroLoaded() + { + ModsCompatibilityChecker mcc = new ModsCompatibilityChecker(); + mcc.PerformModCheck(); + } - public void OnSettingsUI(UIHelperBase helper) - { - OptionUI.MakeSettings(helper); - } + public void OnSettingsUI(UIHelperBase helper) + { + OptionUI.MakeSettings(helper); + } - public static bool GetRealCityV10() - { - return realCityV10; - } + public static bool GetRealCityV10() + { + return realCityV10; + } - public static int GetReduceCargoDiv() - { - return MainDataStore.reduceCargoDiv; - } + public static int GetReduceCargoDiv() + { + return MainDataStore.reduceCargoDiv; + } - public static float GetOutsideTouristMoney() - { - return MainDataStore.outsideTouristMoney; - } + public static float GetOutsideTouristMoney() + { + return MainDataStore.outsideTouristMoney; + } - public static void SetOutsideTouristMoney(float value) - { - MainDataStore.outsideTouristMoney = value; - } + public static void SetOutsideTouristMoney(float value) + { + MainDataStore.outsideTouristMoney = value; + } - public static float GetOutsideGovermentMoney() - { - return MainDataStore.outsideGovermentMoney; - } + public static float GetOutsideGovermentMoney() + { + return MainDataStore.outsideGovermentMoney; + } - public static void SetOutsideGovermentMoney(float value) - { - MainDataStore.outsideGovermentMoney = value; - } - } + public static void SetOutsideGovermentMoney(float value) + { + MainDataStore.outsideGovermentMoney = value; + } + } } - diff --git a/RealCity.csproj b/RealCity.csproj index 3817879..6db1ff1 100644 --- a/RealCity.csproj +++ b/RealCity.csproj @@ -50,32 +50,32 @@ 7.3 - - packages\Lib.Harmony.2.0.1\lib\net35\0Harmony.dll + + ..\CitiesHarmony-master\libs\0Harmony.dll - F:\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\Assembly-CSharp.dll + ..\..\..\..\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\Assembly-CSharp.dll - F:\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\Assembly-CSharp-firstpass.dll + ..\..\..\..\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\Assembly-CSharp-firstpass.dll - - packages\CitiesHarmony.API.1.0.5\lib\net35\CitiesHarmony.API.dll + + ..\..\..\..\SteamLibrary\steamapps\workshop\content\255710\1192503086\CitiesHarmony.API.dll - F:\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\ColossalManaged.dll + ..\..\..\..\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\ColossalManaged.dll - F:\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\ICities.dll + ..\..\..\..\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\ICities.dll - F:\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\ICSharpCode.SharpZipLib.dll + ..\..\..\..\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\ICSharpCode.SharpZipLib.dll - F:\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\Mono.Posix.dll + ..\..\..\..\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\Mono.Posix.dll - F:\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\Mono.Security.dll + ..\..\..\..\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\Mono.Security.dll @@ -84,14 +84,37 @@ - F:\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\UnityEngine.dll + ..\..\..\..\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\UnityEngine.dll - F:\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\UnityEngine.UI.dll + ..\..\..\..\SteamLibrary\steamapps\common\Cities_Skylines\Cities_Data\Managed\UnityEngine.UI.dll + + + + + + + + + + + + + + + + + + + + + + + @@ -181,13 +204,17 @@ + + + + @@ -199,23 +226,20 @@ + + + + + + - rd /q /s "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086" -mkdir "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086" -copy "D:\Mod\RealCity\bin\Release\RealCity.dll" "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086\RealCity.dll" -copy "D:\Mod\RealCity\bin\Release\CitiesHarmony.API.dll" "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086\CitiesHarmony.API.dll" -rd /q /s "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086\Resources" -mkdir "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086\Resources" -copy "D:\Mod\RealCity\Resources\*.*" "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086\Resources" -rd /q /s "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086\Icon" -mkdir "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086\Icon" -copy "D:\Mod\RealCity\Icon\*.png" "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086\Icon" -copy "D:\Mod\RealCity\PreviewImage.png" "F:\SteamLibrary\steamapps\workshop\content\255710\1192503086\PreviewImage.png" + + |<------>|<-------->| + * ^ vote ^ length is the sum of party.WinChance + * ^ initial Segment + * |<--------------->|<------>|<-------->| + * ^ S move forward, now vote is smaller than S, which means P.B gets 1 ticket + */ + + while (i < this.EleInfo.Parties.Length) + { + if (vote < segment) + { + this.EleInfo.TicketCounter[i]++; + break; + } + segment += this.Chance[++i]; + } + } + private void CalcChance() + { + for (int i = 0; i < this.EleInfo.PartiesCount; i++) + { + this.Interests[i].Calc(); + this.Chance[i] = this.Interests[i].Val; + } + // choose a lucky party as trend party + this.trandPartyIdx = this.r.Next(this.EleInfo.PartiesCount); + this.trendStrength = this.r.Next(MaxTrandStrength); + // add its chance + this.Chance[trandPartyIdx] += this.trendStrength; + } + } +} diff --git a/Util/Politic/ElectionUtil/PartyInterestCalc.cs b/Util/Politic/ElectionUtil/PartyInterestCalc.cs new file mode 100644 index 0000000..3def241 --- /dev/null +++ b/Util/Politic/ElectionUtil/PartyInterestCalc.cs @@ -0,0 +1,189 @@ +using ColossalFramework; +using RealCity.CustomAI; +using RealCity.CustomData; + +namespace RealCity.Util.Politic.ElectionUtil +{ + /// + /// 政党兴趣度计算 + /// + public class PartyInterestCalc + { + private PartyInterestData partyInterestData; + private Citizen citizen; + private uint citizenId; + private uint homeId; + + public IParty Party { get; } + public ushort Val { get; private set; } = 0; + + /// + /// 政党兴趣度计算 + /// + /// 政党 + /// 市民 + /// 市民Id + /// 家庭Id + public PartyInterestCalc(IParty party, ref Citizen citizen, uint citizenId, uint homeId) + { + this.Party = party; + this.partyInterestData = party.GetPartyInterestData(); + this.citizen = citizen; + this.citizenId = citizenId; + this.homeId = homeId; + } + + /// + /// 计算市民对政党的兴趣度 + /// + public void Calc() + { + this.Val += GetFromEducationLevel(this.citizen.EducationLevel); + this.Val += GetFromSubService(this.citizen.m_workBuilding); + this.Val += GetFromFamilyMoney(CitizenUnitData.familyMoney[this.homeId]); + this.Val += GetFromAgeGroup(Citizen.GetAgeGroup(this.citizen.Age)); + this.Val += GetFromGender(Citizen.GetGender(this.citizenId)); + } + + /// + /// 以教育背景计算对政党的兴趣度 + /// + /// + /// + private ushort GetFromEducationLevel(Citizen.Education education) + { + /* + * 根据ResidentAICitizenUnitSimulationStepPatch.GetVoteTickets()方法 + * 似乎所有政党的WinChance加起来应该是800 + * 而同一个类里的GetVoteChance()也曾把Politics.education[i,j]的参数乘2 + * 这地方要问一下作者... + */ + ushort val = (ushort)(this.partyInterestData.EducationLevel[(int)education] << 1); + return val; + } + + /// + /// 以行业计算对政党的兴趣度 + /// + /// + /// + private ushort GetFromSubService(ushort workplaceId) + { + //默认市民是没有工作的 + int choiceIndex = 0; + //自定义行业:在政府工作 + if (RealCityResidentAI.IsGoverment(workplaceId)) + { + choiceIndex = 1; + } + else + { + ItemClass workplaceItemClass = Singleton.instance + .m_buildings.m_buffer[workplaceId].Info.m_class; + //其他游戏内置行业 + switch (workplaceItemClass.m_subService) + { + case ItemClass.SubService.CommercialLow: + case ItemClass.SubService.CommercialHigh: + if (workplaceItemClass.m_level == ItemClass.Level.Level1) + { + choiceIndex = 2; + } + else if (workplaceItemClass.m_level == ItemClass.Level.Level2) + { + choiceIndex = 3; + } + else if (workplaceItemClass.m_level == ItemClass.Level.Level3) + { + choiceIndex = 4; + } + break; + case ItemClass.SubService.CommercialTourist: + case ItemClass.SubService.CommercialLeisure: + choiceIndex = 5; break; + case ItemClass.SubService.CommercialEco: + choiceIndex = 6; break; + case ItemClass.SubService.IndustrialGeneric: + if (workplaceItemClass.m_level == ItemClass.Level.Level1) + { + choiceIndex = 7; + } + else if (workplaceItemClass.m_level == ItemClass.Level.Level2) + { + choiceIndex = 8; + } + else if (workplaceItemClass.m_level == ItemClass.Level.Level3) + { + choiceIndex = 9; + } + break; + case ItemClass.SubService.IndustrialFarming: + case ItemClass.SubService.IndustrialForestry: + case ItemClass.SubService.IndustrialOil: + case ItemClass.SubService.IndustrialOre: + choiceIndex = 10; break; + case ItemClass.SubService.OfficeGeneric: + if (workplaceItemClass.m_level == ItemClass.Level.Level1) + { + choiceIndex = 11; + } + else if (workplaceItemClass.m_level == ItemClass.Level.Level2) + { + choiceIndex = 12; + } + else if (workplaceItemClass.m_level == ItemClass.Level.Level3) + { + choiceIndex = 13; + } + break; + case ItemClass.SubService.OfficeHightech: + choiceIndex = 14; break; + } + } + return this.partyInterestData.SubService[choiceIndex]; + } + + /// + /// 以家庭财富计算对政党的兴趣度 + /// + /// + /// + private ushort GetFromFamilyMoney(float familyMoney) + { + int choiceIndex; + if (familyMoney < 5000) + { + choiceIndex = 0; + } + else if (familyMoney >= 20000) + { + choiceIndex = 2; + } + else + { + choiceIndex = 1; + } + return this.partyInterestData.FamilyMoney[choiceIndex]; + } + + /// + /// 以年龄计算对政党的兴趣度 + /// + /// + /// + private ushort GetFromAgeGroup(Citizen.AgeGroup ageGroup) + { + return this.partyInterestData.Age[(int)ageGroup - 2]; + } + + /// + /// 以性别计算对政党的兴趣度 + /// + /// + /// + private ushort GetFromGender(Citizen.Gender gender) + { + return this.partyInterestData.Gender[(int)gender]; + } + } +} diff --git a/Util/Politic/Government.cs b/Util/Politic/Government.cs new file mode 100644 index 0000000..dccd4f8 --- /dev/null +++ b/Util/Politic/Government.cs @@ -0,0 +1,194 @@ +using RealCity.Util.Politic.ElectionUtil; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace RealCity.Util.Politic +{ + /// + /// 政府 + /// + public class Government : IGovernment + { + private const int MinSeatCount = 99; + + public static Government Null = new Government(); + public static Government Instance { get; set; } + + public IGovernmentalMeeting LastMeeting { get; private set; } + + public IBill currentBill = Bills.GetRandomBill(); + public IParty[] Parties { get; private set; } + public GovernmentType GovernmentType { get; private set; } + public IParty[] RulingParties { get; private set; } + // refer RealCityEconomyExtension.cs + public int[] Seats { get; private set; } + public int AllSeatCount => this.Seats.Sum(); + + public void UpdateSeats(ElectionInfo info) + { + int cnt = info.GetAllTickets(); + this.Seats = new int[info.PartiesCount]; + for (int i = 0; i < info.PartiesCount; i++) + { + this.Seats[i] = GetSeatCount(info.TicketCounter[i], ref cnt); + } + this.FixSeatCount(); + + #region old codes + ////int allTickets = Politics.cPartyTickets + Politics.gPartyTickets + Politics.sPartyTickets + Politics.lPartyTickets + Politics.nPartyTickets; + //int cnt = Politics.GetAllTicket(); + //if (cnt != 0) { + // Politics.cPartySeats = (ushort)(99 * Politics.cPartyTickets / cnt); + // Politics.gPartySeats = (ushort)(99 * Politics.gPartyTickets / cnt); + // Politics.sPartySeats = (ushort)(99 * Politics.sPartyTickets / cnt); + // Politics.lPartySeats = (ushort)(99 * Politics.lPartyTickets / cnt); + // Politics.nPartySeats = (ushort)(99 * Politics.nPartyTickets / cnt); + //} else { + // Politics.cPartySeats = 0; + // Politics.gPartySeats = 0; + // Politics.sPartySeats = 0; + // Politics.lPartySeats = 0; + // Politics.nPartySeats = 0; + //} + //Politics.cPartyTickets = 0; + //Politics.gPartyTickets = 0; + //Politics.sPartyTickets = 0; + //Politics.lPartyTickets = 0; + //Politics.nPartyTickets = 0; + + ////allTickets = Politics.cPartySeats + Politics.gPartySeats + Politics.sPartySeats + Politics.lPartySeats + Politics.nPartySeats; + //cnt = Politics.GetAllSeatCount(); + //if (cnt < 99) { + // System.Random rand = new System.Random(); + // switch (rand.Next(5)) { + // case 0: + // Politics.cPartySeats += (ushort)(99 - cnt); break; + // case 1: + // Politics.gPartySeats += (ushort)(99 - cnt); break; + // case 2: + // Politics.sPartySeats += (ushort)(99 - cnt); break; + // case 3: + // Politics.lPartySeats += (ushort)(99 - cnt); break; + // case 4: + // Politics.nPartySeats += (ushort)(99 - cnt); break; + // } + //} + #endregion + } + + public void UpdateGovType() + { + bool isOk = default; + int halfSeatCount = (MinSeatCount >> 1) + 1; + for (int i = 0; i < this.Seats.Length; i++) + { + if (this.Seats[i] >= halfSeatCount) + { + this.GovernmentType = GovernmentType.Single; + this.RulingParties = new IParty[] { this.Parties[i] }; + isOk = true; + } + } + + if (isOk) + return; + + // bad codes + int left, wideLeft, right; + left = wideLeft = right = default; + for (int i = 0; i < this.Seats.Length; i++) + { + if (this.Parties[i].PartyType == PartyType.Green || this.Parties[i].PartyType == PartyType.Socialist) + { + left += this.Seats[i]; + } + else if (this.Parties[i].PartyType == PartyType.Communist) + { + wideLeft += this.Seats[i]; + } + else if (this.Parties[i].PartyType == PartyType.Liberal || this.Parties[i].PartyType == PartyType.National) + { + right += this.Seats[i]; + } + } + wideLeft += left; + if (left >= halfSeatCount) + { + this.GovernmentType = GovernmentType.LeftUnion; + this.RulingParties = this.Parties + .Where(p => p.PartyType == PartyType.Green || p.PartyType == PartyType.Socialist) + .ToArray(); + } + else if (wideLeft >= halfSeatCount) + { + this.GovernmentType = GovernmentType.WideLeftUnion; + this.RulingParties = this.Parties + .Where(p => p.PartyType == PartyType.Green || p.PartyType == PartyType.Socialist || p.PartyType == PartyType.Communist) + .ToArray(); + } + else if (right >= halfSeatCount) + { + this.GovernmentType = GovernmentType.RightUnion; + this.RulingParties = this.Parties + .Where(p => p.PartyType == PartyType.Liberal || p.PartyType == PartyType.National) + .ToArray(); + } + else + { + this.GovernmentType = GovernmentType.Grand; + this.RulingParties = this.Parties; + } + } + + /// + /// Hold a governmental meeting and decide a to implement. + /// + /// + public IGovernmentalMeeting HoldMeeting() + { + //if(this.currentBill == null) { + // this.currentBill = Bills.GetRandomBill(); + //} + IGovernmentalMeeting meeting = new GovernmentalMeeting(this, Bills.GetAnotherBill(this.currentBill)); + meeting.Start(); + if (IsVoteResultApprovable(meeting.VoteResult)) + { + meeting.Bill.Implement(); + } + this.LastMeeting = meeting; + return meeting; + } + + private int GetSeatCount(int ticketCount, ref int ticketSum) + { + return (int)(99 * ticketCount / ticketSum); + } + + /// + /// 修正Seat数量至 个 + /// + private void FixSeatCount() + { + int missingCount = MinSeatCount - this.AllSeatCount; + // if have missing seats + if (missingCount > 0) + { + System.Random r = new System.Random(); + int idx = r.Next(this.Seats.Length); + this.Seats[idx] += missingCount; + } + } + + public static void Start() + { + Instance = Null as Government; + Instance.Parties = Politics.Parties; + } + + public bool IsVoteResultApprovable(VoteResult voteResult) + { + return voteResult.Agree >= (voteResult.Sum >> 1); + } + } +} diff --git a/Util/Politic/GovernmentalMeeting.cs b/Util/Politic/GovernmentalMeeting.cs new file mode 100644 index 0000000..a7afb80 --- /dev/null +++ b/Util/Politic/GovernmentalMeeting.cs @@ -0,0 +1,216 @@ +using RealCity.Util.Politic.Bill; +using System.Linq; + +namespace RealCity.Util.Politic +{ + /// + /// 会议 + /// + public class GovernmentalMeeting : IGovernmentalMeeting + { + private IGovernment gov; + private IParty[] parties; + + public IBill Bill { get; } + public VoteResult VoteResult { get; private set; } + + public GovernmentalMeeting(IGovernment gov, IBill bill) + { + this.gov = gov; + this.parties = gov.Parties; + this.Bill = bill; + } + + public void Start() + { + VoteResult r = new VoteResult(); + + int seatCount = this.gov.AllSeatCount; + int resiTaxOffset = 10 - (Politics.residentTax); + int commTaxOffset = 10 - (Politics.commercialTax); + int induTaxOffset = 10 - (Politics.industryTax); + int beneOffset = 10 - (Politics.benefitOffset / 5); + int moneyOffset = 0; // money offset + int citizenOffset = 0; // citizen offset + int industrialBuildingOffset = 0; //industrial building offset + int commercialBuildingOffset = 0; //commercial building offset + + VoteOffset(ref moneyOffset, ref citizenOffset, ref industrialBuildingOffset, ref commercialBuildingOffset); + + r.AppendChange( + +this.parties.Sum(p => p.BillAttitudes[this.Bill].Agree), + +this.parties.Sum(p => p.BillAttitudes[this.Bill].Disagree), + +this.parties.Sum(p => p.BillAttitudes[this.Bill].Neutral) + ); + + // offset the value of agree by the class of IBill + // bad codes + if (this.Bill is RiseResidentTaxBill) + { + //agree += resiTaxOffset * this.parties.Length; + //agree -= moneyOffset; + //agree -= citizenOffset; + //disagree -= resiTaxOffset * this.parties.Length; + r.AppendChange( + +(resiTaxOffset * this.parties.Length - moneyOffset - citizenOffset), + -(resiTaxOffset * this.parties.Length) + ); + } + else if (this.Bill is ReduceResidentTaxBill) + { + //agree -= resiTaxOffset * this.parties.Length; + //agree += moneyOffset; + //agree += citizenOffset; + //disagree += resiTaxOffset * this.parties.Length; + r.AppendChange( + -(resiTaxOffset * this.parties.Length - moneyOffset - citizenOffset), + +(resiTaxOffset * this.parties.Length) + ); + } + else if (this.Bill is RiseCommercialTaxBill) + { + //agree += commTaxOffset * this.parties.Length; + //agree -= moneyOffset; + //agree += commercialBuildingOffset; + //disagree -= commTaxOffset * this.parties.Length; + r.AppendChange( + +(commTaxOffset * this.parties.Length - moneyOffset + commercialBuildingOffset), + -(resiTaxOffset * this.parties.Length) + ); + } + else if (this.Bill is ReduceCommercialTaxBill) + { + //agree -= commTaxOffset * this.parties.Length; + //agree += moneyOffset; + //agree -= commercialBuildingOffset; + //disagree += commTaxOffset * this.parties.Length; + r.AppendChange( + -(commTaxOffset * this.parties.Length - moneyOffset + commercialBuildingOffset), + +(resiTaxOffset * this.parties.Length) + ); + } + else if (this.Bill is RiseIndustryTaxBill) + { + //agree += induTaxOffset * this.parties.Length; + //agree -= moneyOffset; + //agree += industrialBuildingOffset; + //disagree -= induTaxOffset * this.parties.Length; + r.AppendChange( + +(induTaxOffset * this.parties.Length - moneyOffset + industrialBuildingOffset), + -(induTaxOffset * this.parties.Length) + ); + } + else if (this.Bill is ReduceIndustryTaxBill) + { + //agree -= induTaxOffset * this.parties.Length; + //agree += moneyOffset; + //agree -= industrialBuildingOffset; + //disagree += induTaxOffset * this.parties.Length; + r.AppendChange( + -(induTaxOffset * this.parties.Length - moneyOffset + industrialBuildingOffset), + +(induTaxOffset * this.parties.Length) + ); + } + else if (this.Bill is RiseBenefitBill) + { + //agree += beneOffset * this.parties.Length; + //agree += moneyOffset; + //disagree -= beneOffset * this.parties.Length; + r.AppendChange( + +(beneOffset * this.parties.Length + moneyOffset), + -(beneOffset * this.parties.Length) + ); + } + else if (this.Bill is ReduceBenefitBill) + { + //agree -= beneOffset * this.parties.Length; + //agree -= moneyOffset; + //disagree += beneOffset * this.parties.Length; + r.AppendChange( + -(beneOffset * this.parties.Length + moneyOffset), + +(beneOffset * this.parties.Length) + ); + } + this.VoteResult = r; + } + + private void VoteOffset(ref int moneyOffset, ref int citizenOffset, ref int buildingOffset, ref int commBuildingOffset) + { + //moenyOffset + //FieldInfo cashAmountField = typeof(EconomyManager).GetField("m_cashAmount", BindingFlags.NonPublic | BindingFlags.Instance); + //long cashAmount = (long)cashAmountField.GetValue(Singleton.instance); + long cashAmount = EconomyManager.instance.GetPrivateField("m_cashAmount"); + if (cashAmount < 0) + { + moneyOffset = -4000; + } + else if (cashAmount > 24000000) + { // 2.4e7 + moneyOffset = 4000; + } + else + { + moneyOffset = -4000 + (int)(cashAmount / 3000); // equals 0 when cashAmount = 1.2e7 + } + + + //citizenOffset + int citizenOffsetBySalary = 0; + if (MainDataStore.familyCount > 0) + { + //citizenOffsetBySalary is the salary of its family excluding the tax and expense. + //citizenOffsetBySalary是家庭工资减去赋税和开销的值 + citizenOffsetBySalary = (int)(MainDataStore.citizenSalaryPerFamily - (MainDataStore.citizenSalaryTaxTotal / MainDataStore.familyCount) - MainDataStore.citizenExpensePerFamily); + } + if (citizenOffsetBySalary < 100) + { + citizenOffset = 500; + } + else if (citizenOffsetBySalary > 300) + { + citizenOffset = -500; + } + else + { + citizenOffset = 1000 - 5 * citizenOffsetBySalary; + } + + + //buildingOffset + buildingOffset = 0; + // if have industrial buildings + if (RealCityEconomyExtension.industrialEarnMoneyCount + RealCityEconomyExtension.industrialLackMoneyCount > 0) + { + buildingOffset = ( + (int)(100f * (RealCityEconomyExtension.industrialEarnMoneyCount - RealCityEconomyExtension.industrialLackMoneyCount) + / (RealCityEconomyExtension.industrialEarnMoneyCount + RealCityEconomyExtension.industrialLackMoneyCount)) + ) << 4; + if (buildingOffset > 1500) + { + buildingOffset = 1500; + } + + if (buildingOffset < -1500) + { + buildingOffset = -1500; + } + } + + commBuildingOffset = 0; + // if have commercial buildings + if (RealCityEconomyExtension.commercialEarnMoneyCount + RealCityEconomyExtension.commercialLackMoneyCount > 0) + { + commBuildingOffset = ((int)(100f * (RealCityEconomyExtension.commercialEarnMoneyCount - RealCityEconomyExtension.commercialLackMoneyCount) / (RealCityEconomyExtension.commercialEarnMoneyCount + RealCityEconomyExtension.commercialLackMoneyCount))) << 4; + if (commBuildingOffset > 1500) + { + commBuildingOffset = 1500; + } + + if (commBuildingOffset < -1500) + { + commBuildingOffset = -1500; + } + } + } + } +} diff --git a/Util/Politic/IBill.cs b/Util/Politic/IBill.cs new file mode 100644 index 0000000..dda5d1d --- /dev/null +++ b/Util/Politic/IBill.cs @@ -0,0 +1,9 @@ +namespace RealCity.Util.Politic +{ + public interface IBill + { + string Name { get; } + void Implement(); + bool IsImplementable(); + } +} diff --git a/Util/Politic/IGovernment.cs b/Util/Politic/IGovernment.cs new file mode 100644 index 0000000..0cc6358 --- /dev/null +++ b/Util/Politic/IGovernment.cs @@ -0,0 +1,25 @@ +using RealCity.Util.Politic.ElectionUtil; + +namespace RealCity.Util.Politic +{ + public interface IGovernment + { + int[] Seats { get; } + int AllSeatCount { get; } + IParty[] Parties { get; } + GovernmentType GovernmentType { get; } + //IParty[] RulingParties { get; } + void UpdateSeats(ElectionInfo info); + void UpdateGovType(); + IGovernmentalMeeting HoldMeeting(); + bool IsVoteResultApprovable(VoteResult meeting); + } + public enum GovernmentType + { + Single, + LeftUnion, + WideLeftUnion, + RightUnion, + Grand, + } +} diff --git a/Util/Politic/IGovernmentalMeeting.cs b/Util/Politic/IGovernmentalMeeting.cs new file mode 100644 index 0000000..f5bc425 --- /dev/null +++ b/Util/Politic/IGovernmentalMeeting.cs @@ -0,0 +1,9 @@ +namespace RealCity.Util.Politic +{ + public interface IGovernmentalMeeting + { + IBill Bill { get; } + VoteResult VoteResult { get; } + void Start(); + } +} diff --git a/Util/Politic/IParty.cs b/Util/Politic/IParty.cs new file mode 100644 index 0000000..7229f16 --- /dev/null +++ b/Util/Politic/IParty.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace RealCity.Util.Politic +{ + public interface IParty + { + PartyInterestData GetPartyInterestData(); + void AddWinChance(ushort val); + void ResetWinChance(); + string Name { get; } + ushort WinChance { get; } + ushort Ticket { get; } + ushort SeatCount { get; } + ushort Id { get; } + PartyType PartyType { get; } + IDictionary BillAttitudes { get; } + VoteResult GetBillAttitude(IBill bill); + } + public enum PartyType + { + Communist, + Green, + Socialist, + Liberal, + National, + } +} diff --git a/Util/Politic/Party.cs b/Util/Politic/Party.cs new file mode 100644 index 0000000..7e3008b --- /dev/null +++ b/Util/Politic/Party.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; + +namespace RealCity.Util.Politic +{ + /// + /// 政党 + /// + public class Party : IParty + { + private PartyInterestData interestData; + public string Name { get; } + public ushort WinChance { get; private set; } = default; + public ushort Ticket { get; } = default; + public ushort SeatCount { get; } = default; + public ushort Id { get; } + public PartyType PartyType { get; } + public IDictionary BillAttitudes { get; } + + /// + /// 政党 + /// + /// 名称 + /// Id + /// 民众对政党的兴趣度 + /// 政党对政策的态度 + public Party(string name, ushort id, PartyType type, PartyInterestData interestData, Dictionary billAttitude) + { + this.Name = name; + this.Id = id; + this.PartyType = type; + this.interestData = interestData; + this.BillAttitudes = billAttitude; + } + + public PartyInterestData GetPartyInterestData() + { + return this.interestData; + } + + public void AddWinChance(ushort val) + { + this.WinChance += val; + } + + public void ResetWinChance() + { + this.WinChance = default; + } + + public VoteResult GetBillAttitude(IBill bill) + { + if (this.BillAttitudes.ContainsKey(bill)) + { + return this.BillAttitudes[bill]; + } + // dont wanna Party know VoteResult... + return null; + } + + public override string ToString() + { + return Localization.Get(this.PartyType.ToString("G").ToUpper()); + } + } +} diff --git a/Util/Politic/PartyFactory.cs b/Util/Politic/PartyFactory.cs new file mode 100644 index 0000000..e28e1cf --- /dev/null +++ b/Util/Politic/PartyFactory.cs @@ -0,0 +1,202 @@ +using System.Collections.Generic; + +namespace RealCity.Util.Politic +{ + /// + /// 政党工厂 + /// + public class PartyFactory + { + //TODO: Too much similar codes, need extract same parts + + /// + /// 下一个政党的Id + /// + public ushort NextPartyId { get; private set; } = 0; + + public IParty MakeCParty() + { + var billAttitudeMap = new Dictionary(); + VoteResult raiseResidentTax = new VoteResult(55, 40, 5); + VoteResult reduceResidentTax = new VoteResult(40, 55, 5); + VoteResult raiseCommercialTax = new VoteResult(80, 20, 0); + VoteResult reduceCommercialTax = new VoteResult(20, 80, 0); + VoteResult raiseIndustryTax = new VoteResult(20, 70, 10); + VoteResult reduceIndustryTax = new VoteResult(70, 20, 10); + VoteResult raiseBenefitOffset = new VoteResult(40, 50, 10); + VoteResult reduceBenefitOffset = new VoteResult(50, 40, 10); + + billAttitudeMap.Add(Bills.RiseResidentTax, raiseResidentTax); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceResidentTax); + billAttitudeMap.Add(Bills.RiseCommercialTax, raiseCommercialTax); + billAttitudeMap.Add(Bills.ReduceCommercialTax, reduceCommercialTax); + billAttitudeMap.Add(Bills.RiseIndustryTax, raiseIndustryTax); + billAttitudeMap.Add(Bills.ReduceIndustryTax, reduceIndustryTax); + billAttitudeMap.Add(Bills.RiseBenefit, raiseBenefitOffset); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceBenefitOffset); + + IParty party = new Party( + "COMMUNIST", + this.NextPartyId++, + PartyType.Communist, + new PartyInterestData( + new byte[4] { 30, 20, 10, 5 }, + new byte[15] { 35, 0, 20, 10, 0, 0, 35, 50, 30, 15, 25, 10, 5, 0, 0, }, + new byte[3] { 35, 10, 0 }, + new byte[3] { 15, 10, 5 }, + new byte[2] { 10, 5 } + ), + billAttitudeMap + ); + return party; + } + + public IParty MakeGParty() + { + var billAttitudeMap = new Dictionary(); + VoteResult raiseResidentTax = new VoteResult(10, 80, 10); + VoteResult reduceResidentTax = new VoteResult(80, 10, 10); + VoteResult raiseCommercialTax = new VoteResult(40, 50, 10); + VoteResult reduceCommercialTax = new VoteResult(50, 40, 10); + VoteResult raiseIndustryTax = new VoteResult(50, 50, 0); + VoteResult reduceIndustryTax = new VoteResult(50, 50, 0); + VoteResult raiseBenefitOffset = new VoteResult(70, 20, 10); + VoteResult reduceBenefitOffset = new VoteResult(20, 70, 10); + + billAttitudeMap.Add(Bills.RiseResidentTax, raiseResidentTax); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceResidentTax); + billAttitudeMap.Add(Bills.RiseCommercialTax, raiseCommercialTax); + billAttitudeMap.Add(Bills.ReduceCommercialTax, reduceCommercialTax); + billAttitudeMap.Add(Bills.RiseIndustryTax, raiseIndustryTax); + billAttitudeMap.Add(Bills.ReduceIndustryTax, reduceIndustryTax); + billAttitudeMap.Add(Bills.RiseBenefit, raiseBenefitOffset); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceBenefitOffset); + + IParty party = new Party( + "GREEN", + this.NextPartyId++, + PartyType.Green, + new PartyInterestData( + new byte[4] { 0, 10, 20, 25 }, + new byte[15] { 0, 20, 10, 15, 20, 30, 10, 0, 5, 10, 5, 30, 35, 40, 50, }, + new byte[3] { 0, 10, 30 }, + new byte[3] { 20, 15, 10 }, + new byte[2] { 10, 15 } + ), + billAttitudeMap + ); + return party; + } + + public IParty MakeSParty() + { + var billAttitudeMap = new Dictionary(); + VoteResult raiseResidentTax = new VoteResult(30, 70, 0); + VoteResult reduceResidentTax = new VoteResult(70, 30, 0); + VoteResult raiseCommercialTax = new VoteResult(55, 40, 5); + VoteResult reduceCommercialTax = new VoteResult(40, 55, 5); + VoteResult raiseIndustryTax = new VoteResult(60, 30, 10); + VoteResult reduceIndustryTax = new VoteResult(30, 60, 10); + VoteResult raiseBenefitOffset = new VoteResult(90, 10, 0); + VoteResult reduceBenefitOffset = new VoteResult(10, 90, 0); + + billAttitudeMap.Add(Bills.RiseResidentTax, raiseResidentTax); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceResidentTax); + billAttitudeMap.Add(Bills.RiseCommercialTax, raiseCommercialTax); + billAttitudeMap.Add(Bills.ReduceCommercialTax, reduceCommercialTax); + billAttitudeMap.Add(Bills.RiseIndustryTax, raiseIndustryTax); + billAttitudeMap.Add(Bills.ReduceIndustryTax, reduceIndustryTax); + billAttitudeMap.Add(Bills.RiseBenefit, raiseBenefitOffset); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceBenefitOffset); + + IParty party = new Party( + "SOCIALIST", + this.NextPartyId++, + PartyType.Socialist, + new PartyInterestData( + new byte[4] { 10, 25, 30, 40 }, + new byte[15] { 35, 0, 20, 10, 0, 0, 35, 50, 30, 15, 25, 10, 5, 0, 0, }, + new byte[3] { 25, 35, 15 }, + new byte[3] { 30, 25, 20 }, + new byte[2] { 35, 40 } + ), + billAttitudeMap + ); + return party; + } + + public IParty MakeLParty() + { + var billAttitudeMap = new Dictionary(); + VoteResult raiseResidentTax = new VoteResult(70, 30, 0); + VoteResult reduceResidentTax = new VoteResult(30, 70, 0); + VoteResult raiseCommercialTax = new VoteResult(10, 90, 0); + VoteResult reduceCommercialTax = new VoteResult(90, 10, 0); + VoteResult raiseIndustryTax = new VoteResult(70, 30, 0); + VoteResult reduceIndustryTax = new VoteResult(30, 70, 0); + VoteResult raiseBenefitOffset = new VoteResult(10, 90, 0); + VoteResult reduceBenefitOffset = new VoteResult(90, 10, 0); + + billAttitudeMap.Add(Bills.RiseResidentTax, raiseResidentTax); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceResidentTax); + billAttitudeMap.Add(Bills.RiseCommercialTax, raiseCommercialTax); + billAttitudeMap.Add(Bills.ReduceCommercialTax, reduceCommercialTax); + billAttitudeMap.Add(Bills.RiseIndustryTax, raiseIndustryTax); + billAttitudeMap.Add(Bills.ReduceIndustryTax, reduceIndustryTax); + billAttitudeMap.Add(Bills.RiseBenefit, raiseBenefitOffset); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceBenefitOffset); + + IParty party = new Party( + "LIBERAL", + this.NextPartyId++, + PartyType.Liberal, + new PartyInterestData( + new byte[4] { 10, 20, 30, 25 }, + new byte[15] { 35, 0, 20, 10, 0, 0, 35, 50, 30, 15, 25, 10, 5, 0, 0, }, + new byte[3] { 10, 35, 40 }, + new byte[3] { 20, 30, 40 }, + new byte[2] { 35, 35 } + ), + billAttitudeMap + ); + return party; + } + + public IParty MakeNParty() + { + var billAttitudeMap = new Dictionary(); + VoteResult raiseResidentTax = new VoteResult(35, 55, 10); + VoteResult reduceResidentTax = new VoteResult(55, 35, 10); + VoteResult raiseCommercialTax = new VoteResult(45, 45, 100); + VoteResult reduceCommercialTax = new VoteResult(45, 45, 10); + VoteResult raiseIndustryTax = new VoteResult(30, 70, 0); + VoteResult reduceIndustryTax = new VoteResult(70, 30, 0); + VoteResult raiseBenefitOffset = new VoteResult(30, 60, 10); + VoteResult reduceBenefitOffset = new VoteResult(60, 30, 10); + + billAttitudeMap.Add(Bills.RiseResidentTax, raiseResidentTax); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceResidentTax); + billAttitudeMap.Add(Bills.RiseCommercialTax, raiseCommercialTax); + billAttitudeMap.Add(Bills.ReduceCommercialTax, reduceCommercialTax); + billAttitudeMap.Add(Bills.RiseIndustryTax, raiseIndustryTax); + billAttitudeMap.Add(Bills.ReduceIndustryTax, reduceIndustryTax); + billAttitudeMap.Add(Bills.RiseBenefit, raiseBenefitOffset); + billAttitudeMap.Add(Bills.ReduceResidentTax, reduceBenefitOffset); + + IParty party = new Party( + "NATIONAL", + this.NextPartyId++, + PartyType.National, + new PartyInterestData( + new byte[4] { 50, 25, 10, 5 }, + new byte[15] { 35, 0, 20, 10, 0, 0, 35, 50, 30, 15, 25, 10, 5, 0, 0, }, + new byte[3] { 30, 10, 15 }, + new byte[3] { 15, 20, 25 }, + new byte[2] { 10, 5 } + ), + billAttitudeMap + ); + return party; + } + } +} diff --git a/Util/Politic/PartyInterestData.cs b/Util/Politic/PartyInterestData.cs new file mode 100644 index 0000000..d1d23f8 --- /dev/null +++ b/Util/Politic/PartyInterestData.cs @@ -0,0 +1,42 @@ +namespace RealCity.Util.Politic +{ + /// + /// 政党兴趣度数据 + /// + public class PartyInterestData + { + private const byte EducationLevelNum = 4; + private const byte SubServiceNum = 15; + private const byte FamilyMoneyNum = 3; + private const byte AgeNum = 3; + private const byte GenderNum = 2; + + public byte[] EducationLevel { get; private set; } + public byte[] SubService { get; private set; } + public byte[] FamilyMoney { get; private set; } + public byte[] Age { get; private set; } + public byte[] Gender { get; private set; } + + /// + /// 政党兴趣度数据 + /// + /// 长度为4的数组,代表4个学历 + /// 长度为15的数组,代表15种行业 + /// 长度为3的数组,代表3种家庭富裕程度 + /// 长度为3的数组,代表3种(有投票权的)年龄阶段 + /// 长度为2的数组,代表2种性别 + public PartyInterestData(byte[] edu, byte[] service, byte[] familyMoney, byte[] age, byte[] gender) + { + edu = edu.EnsureLength(EducationLevelNum); + service = service.EnsureLength(SubServiceNum); + familyMoney = familyMoney.EnsureLength(FamilyMoneyNum); + age = age.EnsureLength(AgeNum); + gender = gender.EnsureLength(GenderNum); + this.EducationLevel = edu; + this.SubService = service; + this.FamilyMoney = familyMoney; + this.Age = age; + this.Gender = gender; + } + } +} diff --git a/Util/Politic/VoteResult.cs b/Util/Politic/VoteResult.cs new file mode 100644 index 0000000..4697164 --- /dev/null +++ b/Util/Politic/VoteResult.cs @@ -0,0 +1,52 @@ +namespace RealCity.Util.Politic +{ + /// + /// 投票结果 + /// + public class VoteResult + { + /// + /// 同意 + /// + public int Agree { get; private set; } + /// + /// 反对 + /// + public int Disagree { get; private set; } + /// + /// 弃权 + /// + public int Neutral { get; private set; } + public int Sum => this.Agree + this.Disagree + this.Neutral; + + /// + /// 投票结果 + /// + public VoteResult() + : this(default, default, default) + { + } + /// + /// 投票结果 + /// + /// 同意 + /// 反对 + /// 弃权 + public VoteResult(int agree, int disagree, int neutral) + { + this.Agree = agree; + this.Disagree = disagree; + this.Neutral = neutral; + } + public void AppendChange(int dAgree, int dDisagree) + { + this.AppendChange(dAgree, dDisagree, 0); + } + public void AppendChange(int dAgree, int dDisagree, int dNeutral) + { + this.Agree += dAgree; + this.Disagree += dDisagree; + this.Neutral += dNeutral; + } + } +} diff --git a/Util/Politic/VoteResult11.cs b/Util/Politic/VoteResult11.cs new file mode 100644 index 0000000..edabee1 --- /dev/null +++ b/Util/Politic/VoteResult11.cs @@ -0,0 +1,30 @@ +//namespace RealCity.Util.Politic +//{ +// /// +// /// 投票结果 +// /// +// public class VoteResult : VoteResult +// { +// public override bool IsApprovable => this.Agree >= (this.Sum >> 1); + +// /// +// /// 投票结果 +// /// +// public VoteResult() +// : base() +// { + +// } +// /// +// /// 投票结果 +// /// +// /// 同意 +// /// 反对 +// /// 弃权 +// public VoteResult(int agree, int disagree, int neutral) +// : base(agree, disagree, neutral) +// { + +// } +// } +//} diff --git a/Util/Politic/bill-desc.txt b/Util/Politic/bill-desc.txt new file mode 100644 index 0000000..f75718d --- /dev/null +++ b/Util/Politic/bill-desc.txt @@ -0,0 +1,16 @@ +case 0: +Politics.residentTax += 1; +case 1: +Politics.residentTax -= 1; +case 2: +Politics.benefitOffset += 10; +case 3: +Politics.benefitOffset -= 10; +case 4: +Politics.commercialTax += 1; +case 5: +Politics.commercialTax -= 1; +case 6: +Politics.industryTax += 1; +case 7: +Politics.industryTax -= 1; \ No newline at end of file diff --git a/Util/Politic/gov-desc.txt b/Util/Politic/gov-desc.txt new file mode 100644 index 0000000..82ad09f --- /dev/null +++ b/Util/Politic/gov-desc.txt @@ -0,0 +1,18 @@ +case1 +COMMUNIST +case2 +GREEN +case3 +SOCIALIST +case4 +LIBERAL +case5 +NATIONAL +case6 +LEFT_UNION GREEN SOCIALIST +case7 +WIDE_LEFT_UNION COMMUNIST GREEN SOCIALIST +case8 +RIGHT_UNION LIBERAL NATIONAL +none of above +ALL_UNION COMMUNIST GREEN SOCIALIST LIBERAL NATIONAL \ No newline at end of file diff --git a/Util/Politics.cs b/Util/Politics.cs index 9403978..2e95319 100644 --- a/Util/Politics.cs +++ b/Util/Politics.cs @@ -1,279 +1,361 @@ using ColossalFramework; +using RealCity.Util.Politic; using System; +using System.Linq; namespace RealCity.Util { - public class Politics - { - public static byte[,] education = { {30, 0, 10, 10, 50}, - {20, 10, 25, 20, 25}, - {10, 20, 30, 30, 10}, - {5 , 25, 40, 25, 5}}; - - //0 govement - //1 comm level1 - //2 comm level2 - //3 comm level3 - //4 comm tour comm leisure - //5 comm eco - //6 indus gen level1 - //7 indus gen level2 - //8 indus gen level3 - //9 indus farming foresty oil ore - //10 office level1 - //11 office level2 - //12 office level3 - //13 office high tech - //14 no work - public static byte[,] workplace = { {0, 20, 40, 40, 0}, //goverment - {20, 10, 40, 30, 0}, //comm level1 - {10, 15, 35, 35, 5}, //comm level2 - {0, 20, 30, 40, 10}, //comm level3 - {0, 30, 25, 45, 0}, //comm tour leisure - {35, 10, 5, 20, 30}, //comm eco - {50, 0, 25, 10, 15}, //indus gen level1 - {30, 5, 35, 15, 15}, //indus gen level2 - {15, 10, 40, 20, 15}, //indus gen level3 - {25, 5, 20, 20, 30}, //9 indus farming foresty oil ore - {10, 30, 30, 30, 0}, //office level1 - {5 , 35, 25, 35, 0}, //office level2 - {0, 40, 10, 35, 15}, //office level3 - {0, 50, 10, 40, 0}, //office high tech - {35, 0, 10, 10, 45}}; //no work - - // money < 2000 - // 6000 > money > 2000 - // money > 6000 - public static byte[,] money = { {35, 0, 25, 10, 30}, - {10, 10, 35, 35, 10}, - {0 , 30, 15, 40, 15}}; - - //youg - //adult - //senior - public static byte[,] age = { {15, 20, 30, 20, 15}, - {10, 15, 25, 30, 20}, - {5, 10, 20, 40, 25}}; - //man - //woman - public static byte[,] gender = { {10, 10, 35, 35, 10}, - {5, 15, 40, 35, 5 }}; - - - //riseSalaryTax - public static byte[,] riseSalaryTax = { - {55, 40, 5}, - {10, 80, 10}, - {30, 70, 0}, - {70, 30, 0}, - {35, 55, 10}, - }; - - //fallSalaryTax - public static byte[,] fallSalaryTax = { - {40, 55, 5}, - {80, 10, 10}, - {70, 30, 0}, - {30, 70, 0}, - {55, 35, 10}, - }; - - //riseCommericalTax - public static byte[,] riseCommericalTax = { - {80, 20, 0}, - {40, 50, 10}, - {55, 40, 5}, - {10, 90, 0}, - {45, 45, 10}, - }; - - //fallCommericalTax - public static byte[,] fallCommericalTax = { - {20, 80, 0}, - {50, 40, 10}, - {40, 55, 5}, - {90, 10, 0}, - {45, 45, 10}, - }; - - //riseBenefit - public static byte[,] riseBenefit = { - {40, 50, 10}, - {70, 20, 10}, - {90, 10, 0}, - {10, 90, 0}, - {30, 60, 10}, - }; - - //fallBenefit - public static byte[,] fallBenefit = { - {50, 40, 10}, - {20, 70, 10}, - {10, 90, 0}, - {90, 10, 0}, - {60, 30, 10}, - }; - - - //riseIndustryTax - public static byte[,] riseIndustryTax = { - {20, 70, 10}, - {50, 50, 0}, - {60, 30, 10}, - {70, 30, 0}, - {30, 70, 0}, - }; - - //fallIndustryTax - public static byte[,] fallIndustryTax = { - {70, 20, 10}, - {50, 50, 0}, - {30, 60, 10}, - {30, 70, 0}, - {70, 30, 0}, - }; - - public static ushort cPartyChance = 0; - public static ushort gPartyChance = 0; - public static ushort sPartyChance = 0; - public static ushort lPartyChance = 0; - public static ushort nPartyChance = 0; - - public static ushort cPartyTickets = 0; - public static ushort gPartyTickets = 0; - public static ushort sPartyTickets = 0; - public static ushort lPartyTickets = 0; - public static ushort nPartyTickets = 0; - - public static ushort cPartySeats = 0; - public static ushort gPartySeats = 0; - public static ushort sPartySeats = 0; - public static ushort lPartySeats = 0; - public static ushort nPartySeats = 0; - - public static short parliamentCount = 0; - - public static bool case1 = false; - public static bool case2 = false; - public static bool case3 = false; - public static bool case4 = false; - public static bool case5 = false; - public static bool case6 = false; - public static bool case7 = false; - public static bool case8 = false; - - public static byte currentIdx = 14; - public static byte currentYes = 0; - public static byte currentNo = 0; - public static byte currentNoAttend = 0; - public static int residentTax = 20; //(0-20) - public static int commercialTax = 20; //(0-20) - public static int industryTax = 20; //(0-20) - public static short benefitOffset = 0; //(0-100) - - public static void Save(ref byte[] saveData) - { - //58 - int i = 0; - - //30 - SaveAndRestore.SaveData(ref i, cPartyChance, ref saveData); - SaveAndRestore.SaveData(ref i, gPartyChance, ref saveData); - SaveAndRestore.SaveData(ref i, sPartyChance, ref saveData); - SaveAndRestore.SaveData(ref i, lPartyChance, ref saveData); - SaveAndRestore.SaveData(ref i, nPartyChance, ref saveData); - - SaveAndRestore.SaveData(ref i, cPartyTickets, ref saveData); - SaveAndRestore.SaveData(ref i, gPartyTickets, ref saveData); - SaveAndRestore.SaveData(ref i, sPartyTickets, ref saveData); - SaveAndRestore.SaveData(ref i, lPartyTickets, ref saveData); - SaveAndRestore.SaveData(ref i, nPartyTickets, ref saveData); - - SaveAndRestore.SaveData(ref i, cPartySeats, ref saveData); - SaveAndRestore.SaveData(ref i, gPartySeats, ref saveData); - SaveAndRestore.SaveData(ref i, sPartySeats, ref saveData); - SaveAndRestore.SaveData(ref i, lPartySeats, ref saveData); - SaveAndRestore.SaveData(ref i, nPartySeats, ref saveData); - - //14 - SaveAndRestore.SaveData(ref i, parliamentCount, ref saveData); - SaveAndRestore.SaveData(ref i, case1, ref saveData); - SaveAndRestore.SaveData(ref i, case2, ref saveData); - SaveAndRestore.SaveData(ref i, case3, ref saveData); - SaveAndRestore.SaveData(ref i, case4, ref saveData); - SaveAndRestore.SaveData(ref i, case5, ref saveData); - SaveAndRestore.SaveData(ref i, case6, ref saveData); - SaveAndRestore.SaveData(ref i, case7, ref saveData); - SaveAndRestore.SaveData(ref i, case8, ref saveData); - SaveAndRestore.SaveData(ref i, currentIdx, ref saveData); - SaveAndRestore.SaveData(ref i, currentYes, ref saveData); - SaveAndRestore.SaveData(ref i, currentNo, ref saveData); - SaveAndRestore.SaveData(ref i, currentNoAttend, ref saveData); - - //14 - SaveAndRestore.SaveData(ref i, residentTax, ref saveData); - SaveAndRestore.SaveData(ref i, commercialTax, ref saveData); - SaveAndRestore.SaveData(ref i, industryTax, ref saveData); - SaveAndRestore.SaveData(ref i, benefitOffset, ref saveData); - - residentTax = COMath.Clamp((int)residentTax, 0, 20); - commercialTax = COMath.Clamp((int)commercialTax, 0, 20); - industryTax = COMath.Clamp((int)industryTax, 0, 20); - benefitOffset = (short)COMath.Clamp((int)benefitOffset, 0, 100); - - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"Politics Save Error: saveData.Length = {saveData.Length} + i = {i}"); - } - } - - public static void Load(ref byte[] saveData) - { - int i = 0; - - - SaveAndRestore.LoadData(ref i, saveData, ref cPartyChance); - SaveAndRestore.LoadData(ref i, saveData, ref gPartyChance); - SaveAndRestore.LoadData(ref i, saveData, ref sPartyChance); - SaveAndRestore.LoadData(ref i, saveData, ref lPartyChance); - SaveAndRestore.LoadData(ref i, saveData, ref nPartyChance); - - SaveAndRestore.LoadData(ref i, saveData, ref cPartyTickets); - SaveAndRestore.LoadData(ref i, saveData, ref gPartyTickets); - SaveAndRestore.LoadData(ref i, saveData, ref sPartyTickets); - SaveAndRestore.LoadData(ref i, saveData, ref lPartyTickets); - SaveAndRestore.LoadData(ref i, saveData, ref nPartyTickets); - - SaveAndRestore.LoadData(ref i, saveData, ref cPartySeats); - SaveAndRestore.LoadData(ref i, saveData, ref gPartySeats); - SaveAndRestore.LoadData(ref i, saveData, ref sPartySeats); - SaveAndRestore.LoadData(ref i, saveData, ref lPartySeats); - SaveAndRestore.LoadData(ref i, saveData, ref nPartySeats); - - SaveAndRestore.LoadData(ref i, saveData, ref parliamentCount); - - SaveAndRestore.LoadData(ref i, saveData, ref case1); - SaveAndRestore.LoadData(ref i, saveData, ref case2); - SaveAndRestore.LoadData(ref i, saveData, ref case3); - SaveAndRestore.LoadData(ref i, saveData, ref case4); - SaveAndRestore.LoadData(ref i, saveData, ref case5); - SaveAndRestore.LoadData(ref i, saveData, ref case6); - SaveAndRestore.LoadData(ref i, saveData, ref case7); - SaveAndRestore.LoadData(ref i, saveData, ref case8); - - SaveAndRestore.LoadData(ref i, saveData, ref currentIdx); - SaveAndRestore.LoadData(ref i, saveData, ref currentYes); - SaveAndRestore.LoadData(ref i, saveData, ref currentNo); - SaveAndRestore.LoadData(ref i, saveData, ref currentNoAttend); - SaveAndRestore.LoadData(ref i, saveData, ref residentTax); - SaveAndRestore.LoadData(ref i, saveData, ref commercialTax); - SaveAndRestore.LoadData(ref i, saveData, ref industryTax); - SaveAndRestore.LoadData(ref i, saveData, ref benefitOffset); - - if (i != saveData.Length) - { - DebugLog.LogToFileOnly($"Politics Load Error: saveData.Length = {saveData.Length} + i = {i}"); - } - } - } + public class Politics + { + private const Citizen.AgeGroup VotingAge = Citizen.AgeGroup.Young; + private const int MaxTaxValue = 20; + private const int MinTaxValue = 0; + private const int MaxBenefitValue = 100; + private const int MinBenefitValue = 0; + + private static IParty cParty; + private static IParty gParty; + private static IParty sParty; + private static IParty lParty; + private static IParty nParty; + + public static IParty[] Parties; + public static bool CanRiseResidentTax => residentTax < MaxTaxValue; + public static bool CanReduceResidentTax => residentTax > MinTaxValue; + public static bool CanRiseCommercialTax => commercialTax < MaxTaxValue; + public static bool CanReduceCommercialTax => commercialTax > MinTaxValue; + public static bool CanRiseIndustryTax => industryTax < MaxTaxValue; + public static bool CanReduceIndustryTax => industryTax > MinTaxValue; + public static bool CanRiseBenefit => benefitOffset < MaxBenefitValue; + public static bool CanReduceBenefit => benefitOffset > MinBenefitValue; + + public static IParty[] FindPartiesByType(PartyType type) + { + var q = + from p in Parties + where p.PartyType == type + select p; + return q.ToArray(); + } + + public static bool IsOnElection() + { + return nextMeetingInterval == 1; + } + + /// + /// 是否达到最低投票年龄 + /// + /// + /// + public static bool IsOverVotingAge(Citizen.AgeGroup age) + { + return age >= VotingAge; + } + + /// + /// 是否达到最低投票年龄 + /// + /// + /// + public static bool IsOverVotingAge(ref Citizen citizen) + { + return IsOverVotingAge(Citizen.GetAgeGroup(citizen.m_age)); + } + + + //学历对选举投票的影响因子 + public static byte[,] education = { {30, 0, 10, 10, 50}, + {20, 10, 25, 20, 25}, + {10, 20, 30, 30, 10}, + { 5, 25, 40, 25, 5}}; + + //工作场所对选举投票的影响因子 + public static byte[,] workplace = { { 0, 20, 40, 40, 0}, //goverment + {20, 10, 40, 30, 0}, //comm level1 + {10, 15, 35, 35, 5}, //comm level2 + { 0, 20, 30, 40, 10}, //comm level3 + { 0, 30, 25, 45, 0}, //comm tour, comm leisure + {35, 10, 5, 20, 30}, //comm eco + {50, 0, 25, 10, 15}, //indus gen level1 + {30, 5, 35, 15, 15}, //indus gen level2 + {15, 10, 40, 20, 15}, //indus gen level3 + {25, 5, 20, 20, 30}, //9 indus farming foresty oil ore + {10, 30, 30, 30, 0}, //office level1 + { 5, 35, 25, 35, 0}, //office level2 + { 0, 40, 10, 35, 15}, //office level3 + { 0, 50, 10, 40, 0}, //office high tech + {35, 0, 10, 10, 45}}; //no work + + //财富积累对选举投票的影响因子 + // money < 2000 + // 6000 > money > 2000 + // money > 6000 + public static byte[,] money = { {35, 0, 25, 10, 30}, + {10, 10, 35, 35, 10}, + { 0, 30, 15, 40, 15}}; + //年龄 + //young + //adult + //senior + public static byte[,] age = { {15, 20, 30, 20, 15}, + {10, 15, 25, 30, 20}, + { 5, 10, 20, 40, 25}}; + //man + //woman + public static byte[,] gender = { {10, 10, 35, 35, 10}, + { 5, 15, 40, 35, 5}}; + + + //5个政党对一项议案的赞成度 + //riseSalaryTax + public static byte[,] riseSalaryTax = { + {55, 40, 5}, + {10, 80, 10}, + {30, 70, 0}, + {70, 30, 0}, + {35, 55, 10}, + }; + + //fallSalaryTax + public static byte[,] fallSalaryTax = { + {40, 55, 5}, + {80, 10, 10}, + {70, 30, 0}, + {30, 70, 0}, + {55, 35, 10}, + }; + + //riseCommericalTax + public static byte[,] riseCommericalTax = { + {80, 20, 0}, + {40, 50, 10}, + {55, 40, 5}, + {10, 90, 0}, + {45, 45, 10}, + }; + + //fallCommericalTax + public static byte[,] fallCommericalTax = { + {20, 80, 0}, + {50, 40, 10}, + {40, 55, 5}, + {90, 10, 0}, + {45, 45, 10}, + }; + + + //riseIndustryTax + public static byte[,] riseIndustryTax = { + {20, 70, 10}, + {50, 50, 0}, + {60, 30, 10}, + {70, 30, 0}, + {30, 70, 0}, + }; + + //fallIndustryTax + public static byte[,] fallIndustryTax = { + {70, 20, 10}, + {50, 50, 0}, + {30, 60, 10}, + {30, 70, 0}, + {70, 30, 0}, + }; + + //riseBenefit + public static byte[,] riseBenefit = { + {40, 50, 10}, + {70, 20, 10}, + {90, 10, 0}, + {10, 90, 0}, + {30, 60, 10}, + }; + + //fallBenefit + public static byte[,] fallBenefit = { + {50, 40, 10}, + {20, 70, 10}, + {10, 90, 0}, + {90, 10, 0}, + {60, 30, 10}, + }; + + + public static ushort cPartyChance = 0; + public static ushort gPartyChance = 0; + public static ushort sPartyChance = 0; + public static ushort lPartyChance = 0; + public static ushort nPartyChance = 0; + + public static ushort cPartyTickets = 0; + public static ushort gPartyTickets = 0; + public static ushort sPartyTickets = 0; + public static ushort lPartyTickets = 0; + public static ushort nPartyTickets = 0; + + public static ushort cPartySeats = 0; + public static ushort gPartySeats = 0; + public static ushort sPartySeats = 0; + public static ushort lPartySeats = 0; + public static ushort nPartySeats = 0; + + //下一次_____倒计时 + public static short nextMeetingInterval = 0; + + public static bool case1 = false; + public static bool case2 = false; + public static bool case3 = false; + public static bool case4 = false; + public static bool case5 = false; + public static bool case6 = false; + public static bool case7 = false; + public static bool case8 = false; + + + + //当前议案Id + public static byte currentBillId = 14; + //赞成票数 + public static byte currentYes = 0; + //否定票数 + public static byte currentNo = 0; + //中立/缺席(?) + public static byte currentNoAttend = 0; + + //居民税(0-20) + public static int residentTax = 20; + //商业税(0-20) + public static int commercialTax = 20; + //工业税(0-20) + public static int industryTax = 20; + //社会福利(0-100) + public static int benefitOffset = 0; + + + public static void DataInit() + { + PartyFactory factory = new PartyFactory(); + cParty = factory.MakeCParty(); + gParty = factory.MakeGParty(); + sParty = factory.MakeSParty(); + lParty = factory.MakeLParty(); + nParty = factory.MakeNParty(); + IParty[] ps = new IParty[] { + cParty, gParty, sParty, lParty, nParty + }; + // sort ps using p.Id as key + // maybe this can help improve performance + Array.Sort(ps, ps.Select(p => p.Id).ToArray()); + Parties = ps; + + Government.Start(); + Government.Instance.UpdateSeats(Election.CurrentElectionInfo); + } + + public static void Save(ref byte[] saveData) + { + //58 + int i = 0; + + //30 + SaveAndRestore.SaveData(ref i, cPartyChance, ref saveData); + SaveAndRestore.SaveData(ref i, gPartyChance, ref saveData); + SaveAndRestore.SaveData(ref i, sPartyChance, ref saveData); + SaveAndRestore.SaveData(ref i, lPartyChance, ref saveData); + SaveAndRestore.SaveData(ref i, nPartyChance, ref saveData); + + SaveAndRestore.SaveData(ref i, cPartyTickets, ref saveData); + SaveAndRestore.SaveData(ref i, gPartyTickets, ref saveData); + SaveAndRestore.SaveData(ref i, sPartyTickets, ref saveData); + SaveAndRestore.SaveData(ref i, lPartyTickets, ref saveData); + SaveAndRestore.SaveData(ref i, nPartyTickets, ref saveData); + + SaveAndRestore.SaveData(ref i, cPartySeats, ref saveData); + SaveAndRestore.SaveData(ref i, gPartySeats, ref saveData); + SaveAndRestore.SaveData(ref i, sPartySeats, ref saveData); + SaveAndRestore.SaveData(ref i, lPartySeats, ref saveData); + SaveAndRestore.SaveData(ref i, nPartySeats, ref saveData); + + //14 + SaveAndRestore.SaveData(ref i, nextMeetingInterval, ref saveData); + SaveAndRestore.SaveData(ref i, case1, ref saveData); + SaveAndRestore.SaveData(ref i, case2, ref saveData); + SaveAndRestore.SaveData(ref i, case3, ref saveData); + SaveAndRestore.SaveData(ref i, case4, ref saveData); + SaveAndRestore.SaveData(ref i, case5, ref saveData); + SaveAndRestore.SaveData(ref i, case6, ref saveData); + SaveAndRestore.SaveData(ref i, case7, ref saveData); + SaveAndRestore.SaveData(ref i, case8, ref saveData); + SaveAndRestore.SaveData(ref i, currentBillId, ref saveData); + SaveAndRestore.SaveData(ref i, currentYes, ref saveData); + SaveAndRestore.SaveData(ref i, currentNo, ref saveData); + SaveAndRestore.SaveData(ref i, currentNoAttend, ref saveData); + + //14 + SaveAndRestore.SaveData(ref i, residentTax, ref saveData); + SaveAndRestore.SaveData(ref i, commercialTax, ref saveData); + SaveAndRestore.SaveData(ref i, industryTax, ref saveData); + SaveAndRestore.SaveData(ref i, benefitOffset, ref saveData); + + residentTax = COMath.Clamp((int)residentTax, 0, 20); + commercialTax = COMath.Clamp((int)commercialTax, 0, 20); + industryTax = COMath.Clamp((int)industryTax, 0, 20); + benefitOffset = (short)COMath.Clamp((int)benefitOffset, 0, 100); + + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"Politics Save Error: saveData.Length = {saveData.Length} + i = {i}"); + } + } + + public static void Load(ref byte[] saveData) + { + int i = 0; + + + SaveAndRestore.LoadData(ref i, saveData, ref cPartyChance); + SaveAndRestore.LoadData(ref i, saveData, ref gPartyChance); + SaveAndRestore.LoadData(ref i, saveData, ref sPartyChance); + SaveAndRestore.LoadData(ref i, saveData, ref lPartyChance); + SaveAndRestore.LoadData(ref i, saveData, ref nPartyChance); + + SaveAndRestore.LoadData(ref i, saveData, ref cPartyTickets); + SaveAndRestore.LoadData(ref i, saveData, ref gPartyTickets); + SaveAndRestore.LoadData(ref i, saveData, ref sPartyTickets); + SaveAndRestore.LoadData(ref i, saveData, ref lPartyTickets); + SaveAndRestore.LoadData(ref i, saveData, ref nPartyTickets); + + SaveAndRestore.LoadData(ref i, saveData, ref cPartySeats); + SaveAndRestore.LoadData(ref i, saveData, ref gPartySeats); + SaveAndRestore.LoadData(ref i, saveData, ref sPartySeats); + SaveAndRestore.LoadData(ref i, saveData, ref lPartySeats); + SaveAndRestore.LoadData(ref i, saveData, ref nPartySeats); + + SaveAndRestore.LoadData(ref i, saveData, ref nextMeetingInterval); + + SaveAndRestore.LoadData(ref i, saveData, ref case1); + SaveAndRestore.LoadData(ref i, saveData, ref case2); + SaveAndRestore.LoadData(ref i, saveData, ref case3); + SaveAndRestore.LoadData(ref i, saveData, ref case4); + SaveAndRestore.LoadData(ref i, saveData, ref case5); + SaveAndRestore.LoadData(ref i, saveData, ref case6); + SaveAndRestore.LoadData(ref i, saveData, ref case7); + SaveAndRestore.LoadData(ref i, saveData, ref case8); + + SaveAndRestore.LoadData(ref i, saveData, ref currentBillId); + SaveAndRestore.LoadData(ref i, saveData, ref currentYes); + SaveAndRestore.LoadData(ref i, saveData, ref currentNo); + SaveAndRestore.LoadData(ref i, saveData, ref currentNoAttend); + SaveAndRestore.LoadData(ref i, saveData, ref residentTax); + SaveAndRestore.LoadData(ref i, saveData, ref commercialTax); + SaveAndRestore.LoadData(ref i, saveData, ref industryTax); + SaveAndRestore.LoadData(ref i, saveData, ref benefitOffset); + + if (i != saveData.Length) + { + DebugLog.LogToFileOnly($"Politics Load Error: saveData.Length = {saveData.Length} + i = {i}"); + } + } + } } diff --git a/Util/SaveAndRestore.cs b/Util/SaveAndRestore.cs index 84ca6cf..04c890c 100644 --- a/Util/SaveAndRestore.cs +++ b/Util/SaveAndRestore.cs @@ -6,550 +6,550 @@ namespace RealCity.Util { - public class SaveAndRestore : SerializableDataExtensionBase - { - private static ISerializableData _serializableData; - - public static void SaveData(ref int idex, long item, ref byte[] container) - { - int i; - byte[] temp_data; - temp_data = BitConverter.GetBytes(item); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - - public static void SaveData(ref int idex, float item, ref byte[] container) - { - int i; - byte[] temp_data; - temp_data = BitConverter.GetBytes(item); - for(i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - - public static void SaveData(ref int idex, float[] item, ref byte[] container) - { - int i; int j; - byte[] temp_data; - for (j = 0; j < item.Length; j++) - { - temp_data = BitConverter.GetBytes(item[j]); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - } - - public static void SaveData(ref int idex, uint item, ref byte[] container) - { - int i; - byte[] temp_data; - temp_data = BitConverter.GetBytes(item); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - - public static void SaveData(ref int idex, int item, ref byte[] container) - { - int i; - byte[] temp_data; - temp_data = BitConverter.GetBytes(item); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - - public static void SaveData(ref int idex, int[] item, ref byte[] container) - { - int i; int j; - byte[] temp_data; - for (j = 0; j < item.Length; j++) - { - temp_data = BitConverter.GetBytes(item[j]); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - } - - public static void SaveData(ref int idex, byte item, ref byte[] container) - { - container[idex] = item; - idex = idex + 1; - } - - - public static void SaveData(ref int idex, byte[] item, ref byte[] container) - { - int j; - for (j = 0; j < item.Length; j++) - { - container[idex + j] = item[j]; - } - idex = idex + item.Length; - } - - public static void SaveData(ref int idex, short item, ref byte[] container) - { - int i; - byte[] temp_data; - temp_data = BitConverter.GetBytes(item); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - - public static void SaveData(ref int idex, ushort item, ref byte[] container) - { - int i; - byte[] temp_data; - temp_data = BitConverter.GetBytes(item); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - - public static void SaveData(ref int idex, ushort[] item, ref byte[] container) - { - int i; int j; - byte[] temp_data; - for (j = 0; j < item.Length; j++) - { - temp_data = BitConverter.GetBytes(item[j]); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - } - - public static void SaveData(ref int idex, bool item, ref byte[] container) - { - int i; - byte[] temp_data; - temp_data = BitConverter.GetBytes(item); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - - public static void SaveData(ref int idex, bool[] item, ref byte[] container) - { - int i; int j; - byte[] temp_data; - for (j = 0; j < item.Length; j++) - { - temp_data = BitConverter.GetBytes(item[j]); - for (i = 0; i < temp_data.Length; i++) - { - container[idex + i] = temp_data[i]; - } - idex = idex + temp_data.Length; - } - } - - public static void LoadData(ref int idex, byte[] container, ref bool item) - { - if (idex < container.Length) - { - item = BitConverter.ToBoolean(container, idex); - } - else - { - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - item = false; - } - idex = idex + 1; - } - - public static void LoadData(ref int idex, byte[] container, ref bool[] item) - { - if (idex < container.Length) - { - int i; - for (i = 0; i < item.Length; i++) - { - item[i] = BitConverter.ToBoolean(container, idex); - idex = idex + 1; - } - } - else - { - int i; - for (i = 0; i < item.Length; i++) - { - idex = idex + 1; - } - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - } - } - - public static void LoadData(ref int idex, byte[] container, ref int item) - { - if (idex < container.Length) - { - item = BitConverter.ToInt32(container, idex); - } - else - { - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - item = 0; - } - idex = idex + 4; - } - - public static void LoadData(ref int idex, byte[] container, ref int[] item) - { - if (idex < container.Length) - { - int i; - for (i = 0; i < item.Length; i++) - { - item[i] = BitConverter.ToInt32(container, idex); - idex = idex + 4; - } - } - else - { - int i; - for (i = 0; i < item.Length; i++) - { - idex = idex + 4; - } - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - } - } - - public static void LoadData(ref int idex, byte[] container, ref float item) - { - if (idex < container.Length) - { - item = BitConverter.ToSingle(container, idex); - } - else - { - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - item = 0; - } - idex = idex + 4; - } - - public static void LoadData(ref int idex, byte[] container, ref float[] item) - { - int i; - if (idex < container.Length) - { - for (i = 0; i < item.Length; i++) - { - item[i] = BitConverter.ToSingle(container, idex); - idex = idex + 4; - } - } - else - { - for (i = 0; i < item.Length; i++) - { - idex = idex + 4; - } - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - } - } - - public static void LoadData(ref int idex, byte[] container, ref uint item) - { - if (idex < container.Length) - { - item = BitConverter.ToUInt32(container, idex); - } - else - { - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - item = 0; - } - idex = idex + 4; - } - - public static void LoadData(ref int idex, byte[] container, ref uint[] item) - { - int i; - if (idex < container.Length) - { - for (i = 0; i < item.Length; i++) - { - item[i] = BitConverter.ToUInt32(container, idex); - idex = idex + 4; - } - } - else - { - for (i = 0; i < item.Length; i++) - { - idex = idex + 4; - } - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - } - } - - public static void LoadData(ref int idex, byte[] container, ref ushort item) - { - if (idex < container.Length) - { - item = BitConverter.ToUInt16(container, idex); - } - else - { - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - item = 0; - } - idex = idex + 2; - } - - public static void LoadData(ref int idex, byte[] container, ref short item) - { - if (idex < container.Length) - { - item = BitConverter.ToInt16(container, idex); - } - else - { - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - item = 0; - } - idex = idex + 2; - } - - public static void LoadData(ref int idex, byte[] container, ref ushort[] item) - { - int i; - if (idex < container.Length) - { - for (i = 0; i < item.Length; i++) - { - item[i] = BitConverter.ToUInt16(container, idex); - idex = idex + 2; - } - } - else - { - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - for (i = 0; i < item.Length; i++) - { - idex = idex + 2; - } - } - } - - public static void LoadData(ref int idex, byte[] container, ref long item) - { - if (idex < container.Length) - { - item = BitConverter.ToInt64(container, idex); - } - else - { - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - item = 0; - } - idex = idex + 8; - } - - public static void LoadData(ref int idex, byte[] container, ref byte item) - { - if (idex < container.Length) - { - item = container[idex]; - } - else - { - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - item = 0; - } - idex = idex + 1; - } - - public static void LoadData(ref int idex, byte[] container, ref byte[] item) - { - int i; - if (idex < container.Length) - { - for (i = 0; i < item.Length; i++) - { - item[i] = container[idex]; - idex = idex + 1; - } - } - else - { - for (i = 0; i < item.Length; i++) - { - idex = idex + 1; - } - DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); - } - } - - public override void OnCreated(ISerializableData serializableData) - { - _serializableData = serializableData; - } - - public override void OnReleased() - { - } - - public override void OnSaveData() - { - if (Loader.CurrentLoadMode == LoadMode.LoadGame || Loader.CurrentLoadMode == LoadMode.NewGame) - { - DebugLog.LogToFileOnly("StartSave"); - //1 - var saveData = new byte[2448]; - RealCityEconomyManager.Save(ref saveData); - _serializableData.SaveData("RealCity RealCityEconomyManager", saveData); - - //2 - saveData = new byte[125]; - MainDataStore.Save(ref saveData); - _serializableData.SaveData("RealCity MainDataStore", saveData); - - //3 - saveData = new byte[48]; - RealCityResidentAI.Save(ref saveData); - _serializableData.SaveData("RealCity RealCityResidentAI", saveData); - - //4 - saveData = new byte[60]; - RealCityPrivateBuildingAI.Save(ref saveData); - _serializableData.SaveData("RealCity RealCityPrivateBuildingAI", saveData); - - //5 - saveData = new byte[4194304]; - CitizenData.Save(ref saveData); - _serializableData.SaveData("RealCity CitizenData", saveData); - - //6 - saveData = new byte[58]; - Politics.Save(ref saveData); - _serializableData.SaveData("RealCity Politics", saveData); - - //7 - saveData = new byte[512]; - TransportLineData.Save(ref saveData); - _serializableData.SaveData("RealCity TransportLineData", saveData); - - //8 - saveData = new byte[442368]; - BuildingData.Save(ref saveData); - _serializableData.SaveData("RealCity BuildingData", saveData); - - //9 - saveData = new byte[196608]; - VehicleData.Save(ref saveData); - _serializableData.SaveData("RealCity VehicleData", saveData); - - //10 - saveData = new byte[3145728]; - CitizenUnitData.Save(ref saveData); - _serializableData.SaveData("RealCity CitizenUnitData", saveData); - } - } - - public override void OnLoadData() - { - Loader.InitData(); - DebugLog.LogToFileOnly("StartLoad"); - //1 - var saveData = _serializableData.LoadData("RealCity RealCityEconomyManager"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity RealCityEconomyManager, please check"); - else - RealCityEconomyManager.Load(ref saveData); - - //2 - saveData = _serializableData.LoadData("RealCity MainDataStore"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity MainDataStore, please check"); - else - MainDataStore.Load(ref saveData); - - //3 - saveData = _serializableData.LoadData("RealCity RealCityResidentAI"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity RealCityResidentAI, please check"); - else - RealCityResidentAI.Load(ref saveData); - - //4 - saveData = _serializableData.LoadData("RealCity RealCityPrivateBuildingAI"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity RealCityPrivateBuildingAI, please check"); - else - RealCityPrivateBuildingAI.Load(ref saveData); - - //5 - saveData = _serializableData.LoadData("RealCity CitizenData"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity CitizenData, please check"); - else - CitizenData.Load(ref saveData); - - //6 - saveData = _serializableData.LoadData("RealCity Politics"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity Politics, please check"); - else - Politics.Load(ref saveData); - - //7 - saveData = _serializableData.LoadData("RealCity TransportLineData"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity TransportLineData, please check"); - else - TransportLineData.Load(ref saveData); - - //8 - saveData = _serializableData.LoadData("RealCity BuildingData"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity BuildingData, please check"); - else - BuildingData.Load(ref saveData); - - //9 - saveData = _serializableData.LoadData("RealCity VehicleData"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity VehicleData, please check"); - else - VehicleData.Load(ref saveData); - - //10 - saveData = _serializableData.LoadData("RealCity CitizenUnitData"); - if (saveData == null) - DebugLog.LogToFileOnly("no RealCity CitizenUnitData, please check"); - else - CitizenUnitData.Load(ref saveData); - } - } + public class SaveAndRestore : SerializableDataExtensionBase + { + private static ISerializableData _serializableData; + + public static void SaveData(ref int idex, long item, ref byte[] container) + { + int i; + byte[] temp_data; + temp_data = BitConverter.GetBytes(item); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + + public static void SaveData(ref int idex, float item, ref byte[] container) + { + int i; + byte[] temp_data; + temp_data = BitConverter.GetBytes(item); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + + public static void SaveData(ref int idex, float[] item, ref byte[] container) + { + int i, j; + byte[] temp_data; + for (j = 0; j < item.Length; j++) + { + temp_data = BitConverter.GetBytes(item[j]); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + } + + public static void SaveData(ref int idex, uint item, ref byte[] container) + { + int i; + byte[] temp_data; + temp_data = BitConverter.GetBytes(item); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + + public static void SaveData(ref int idex, int item, ref byte[] container) + { + int i; + byte[] temp_data; + temp_data = BitConverter.GetBytes(item); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + + public static void SaveData(ref int idex, int[] item, ref byte[] container) + { + int i, j; + byte[] temp_data; + for (j = 0; j < item.Length; j++) + { + temp_data = BitConverter.GetBytes(item[j]); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + } + + public static void SaveData(ref int idex, byte item, ref byte[] container) + { + container[idex] = item; + idex++; + } + + + public static void SaveData(ref int idex, byte[] item, ref byte[] container) + { + int j; + for (j = 0; j < item.Length; j++) + { + container[idex + j] = item[j]; + } + idex += item.Length; + } + + public static void SaveData(ref int idex, short item, ref byte[] container) + { + int i; + byte[] temp_data; + temp_data = BitConverter.GetBytes(item); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + + public static void SaveData(ref int idex, ushort item, ref byte[] container) + { + int i; + byte[] temp_data; + temp_data = BitConverter.GetBytes(item); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + + public static void SaveData(ref int idex, ushort[] item, ref byte[] container) + { + int i; int j; + byte[] temp_data; + for (j = 0; j < item.Length; j++) + { + temp_data = BitConverter.GetBytes(item[j]); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + } + + public static void SaveData(ref int idex, bool item, ref byte[] container) + { + int i; + byte[] temp_data; + temp_data = BitConverter.GetBytes(item); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + + public static void SaveData(ref int idex, bool[] item, ref byte[] container) + { + int i; int j; + byte[] temp_data; + for (j = 0; j < item.Length; j++) + { + temp_data = BitConverter.GetBytes(item[j]); + for (i = 0; i < temp_data.Length; i++) + { + container[idex + i] = temp_data[i]; + } + idex += temp_data.Length; + } + } + + public static void LoadData(ref int idex, byte[] container, ref bool item) + { + if (idex < container.Length) + { + item = BitConverter.ToBoolean(container, idex); + } + else + { + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + item = false; + } + idex++; + } + + public static void LoadData(ref int idex, byte[] container, ref bool[] item) + { + if (idex < container.Length) + { + int i; + for (i = 0; i < item.Length; i++) + { + item[i] = BitConverter.ToBoolean(container, idex); + idex++; + } + } + else + { + int i; + for (i = 0; i < item.Length; i++) + { + idex++; + } + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + } + } + + public static void LoadData(ref int idex, byte[] container, ref int item) + { + if (idex < container.Length) + { + item = BitConverter.ToInt32(container, idex); + } + else + { + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + item = 0; + } + idex += 4; + } + + public static void LoadData(ref int idex, byte[] container, ref int[] item) + { + if (idex < container.Length) + { + int i; + for (i = 0; i < item.Length; i++) + { + item[i] = BitConverter.ToInt32(container, idex); + idex += 4; + } + } + else + { + int i; + for (i = 0; i < item.Length; i++) + { + idex += 4; + } + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + } + } + + public static void LoadData(ref int idex, byte[] container, ref float item) + { + if (idex < container.Length) + { + item = BitConverter.ToSingle(container, idex); + } + else + { + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + item = 0; + } + idex += 4; + } + + public static void LoadData(ref int idex, byte[] container, ref float[] item) + { + int i; + if (idex < container.Length) + { + for (i = 0; i < item.Length; i++) + { + item[i] = BitConverter.ToSingle(container, idex); + idex += 4; + } + } + else + { + for (i = 0; i < item.Length; i++) + { + idex += 4; + } + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + } + } + + public static void LoadData(ref int idex, byte[] container, ref uint item) + { + if (idex < container.Length) + { + item = BitConverter.ToUInt32(container, idex); + } + else + { + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + item = 0; + } + idex += 4; + } + + public static void LoadData(ref int idex, byte[] container, ref uint[] item) + { + int i; + if (idex < container.Length) + { + for (i = 0; i < item.Length; i++) + { + item[i] = BitConverter.ToUInt32(container, idex); + idex += 4; + } + } + else + { + for (i = 0; i < item.Length; i++) + { + idex += 4; + } + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + } + } + + public static void LoadData(ref int idex, byte[] container, ref ushort item) + { + if (idex < container.Length) + { + item = BitConverter.ToUInt16(container, idex); + } + else + { + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + item = 0; + } + idex += 2; + } + + public static void LoadData(ref int idex, byte[] container, ref short item) + { + if (idex < container.Length) + { + item = BitConverter.ToInt16(container, idex); + } + else + { + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + item = 0; + } + idex += 2; + } + + public static void LoadData(ref int idex, byte[] container, ref ushort[] item) + { + int i; + if (idex < container.Length) + { + for (i = 0; i < item.Length; i++) + { + item[i] = BitConverter.ToUInt16(container, idex); + idex += 2; + } + } + else + { + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + for (i = 0; i < item.Length; i++) + { + idex += 2; + } + } + } + + public static void LoadData(ref int idex, byte[] container, ref long item) + { + if (idex < container.Length) + { + item = BitConverter.ToInt64(container, idex); + } + else + { + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + item = 0; + } + idex += 8; + } + + public static void LoadData(ref int idex, byte[] container, ref byte item) + { + if (idex < container.Length) + { + item = container[idex]; + } + else + { + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + item = 0; + } + idex++; + } + + public static void LoadData(ref int idex, byte[] container, ref byte[] item) + { + int i; + if (idex < container.Length) + { + for (i = 0; i < item.Length; i++) + { + item[i] = container[idex]; + idex++; + } + } + else + { + for (i = 0; i < item.Length; i++) + { + idex++; + } + DebugLog.LogToFileOnly($"load data is too short, please check {container.Length}"); + } + } + + public override void OnCreated(ISerializableData serializableData) + { + _serializableData = serializableData; + } + + public override void OnReleased() + { + } + + public override void OnSaveData() + { + if (Loader.CurrentLoadMode == LoadMode.LoadGame || Loader.CurrentLoadMode == LoadMode.NewGame) + { + DebugLog.LogToFileOnly("StartSave"); + //1 + var saveData = new byte[2448]; + RealCityEconomyManager.Save(ref saveData); + _serializableData.SaveData("RealCity RealCityEconomyManager", saveData); + + //2 + saveData = new byte[125]; + MainDataStore.Save(ref saveData); + _serializableData.SaveData("RealCity MainDataStore", saveData); + + //3 + saveData = new byte[48]; + RealCityResidentAI.Save(ref saveData); + _serializableData.SaveData("RealCity RealCityResidentAI", saveData); + + //4 + saveData = new byte[60]; + RealCityPrivateBuildingAI.Save(ref saveData); + _serializableData.SaveData("RealCity RealCityPrivateBuildingAI", saveData); + + //5 + saveData = new byte[4194304]; + CitizenData.Save(ref saveData); + _serializableData.SaveData("RealCity CitizenData", saveData); + + //6 + saveData = new byte[58]; + Politics.Save(ref saveData); + _serializableData.SaveData("RealCity Politics", saveData); + + //7 + saveData = new byte[512]; + TransportLineData.Save(ref saveData); + _serializableData.SaveData("RealCity TransportLineData", saveData); + + //8 + saveData = new byte[442368]; + BuildingData.Save(ref saveData); + _serializableData.SaveData("RealCity BuildingData", saveData); + + //9 + saveData = new byte[196608]; + VehicleData.Save(ref saveData); + _serializableData.SaveData("RealCity VehicleData", saveData); + + //10 + saveData = new byte[3145728]; + CitizenUnitData.Save(ref saveData); + _serializableData.SaveData("RealCity CitizenUnitData", saveData); + } + } + + public override void OnLoadData() + { + Loader.InitData(); + DebugLog.LogToFileOnly("StartLoad"); + //1 + var saveData = _serializableData.LoadData("RealCity RealCityEconomyManager"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity RealCityEconomyManager, please check"); + else + RealCityEconomyManager.Load(ref saveData); + + //2 + saveData = _serializableData.LoadData("RealCity MainDataStore"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity MainDataStore, please check"); + else + MainDataStore.Load(ref saveData); + + //3 + saveData = _serializableData.LoadData("RealCity RealCityResidentAI"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity RealCityResidentAI, please check"); + else + RealCityResidentAI.Load(ref saveData); + + //4 + saveData = _serializableData.LoadData("RealCity RealCityPrivateBuildingAI"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity RealCityPrivateBuildingAI, please check"); + else + RealCityPrivateBuildingAI.Load(ref saveData); + + //5 + saveData = _serializableData.LoadData("RealCity CitizenData"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity CitizenData, please check"); + else + CitizenData.Load(ref saveData); + + //6 + saveData = _serializableData.LoadData("RealCity Politics"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity Politics, please check"); + else + Politics.Load(ref saveData); + + //7 + saveData = _serializableData.LoadData("RealCity TransportLineData"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity TransportLineData, please check"); + else + TransportLineData.Load(ref saveData); + + //8 + saveData = _serializableData.LoadData("RealCity BuildingData"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity BuildingData, please check"); + else + BuildingData.Load(ref saveData); + + //9 + saveData = _serializableData.LoadData("RealCity VehicleData"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity VehicleData, please check"); + else + VehicleData.Load(ref saveData); + + //10 + saveData = _serializableData.LoadData("RealCity CitizenUnitData"); + if (saveData == null) + DebugLog.LogToFileOnly("no RealCity CitizenUnitData, please check"); + else + CitizenUnitData.Load(ref saveData); + } + } } diff --git a/Util/SpriteUtilities.cs b/Util/SpriteUtilities.cs index ff271ec..5884c05 100644 --- a/Util/SpriteUtilities.cs +++ b/Util/SpriteUtilities.cs @@ -6,178 +6,178 @@ namespace RealCity.Util { - /// - /// Utilities for sprite handling. Takes care of atlases and sprites. - /// - /// Atlases are a large map of many small sprites. Cities handles all - /// individual sprites using a single large atlas, and each sprite has a - /// location on the atlas. - /// - /// - public class SpriteUtilities - { - /* - FYI - Atlas' are essentially sprite maps. They contain - multiple sprites, and locations to those areas of the atlas. - It's much better than storing individual sprites. - */ - internal static Dictionary m_atlasStore = new Dictionary(); - - /// - /// Returns a stored atlas. - /// - /// The name of the atlas to return. - /// - public static UITextureAtlas GetAtlas(string atlasName) - { - UITextureAtlas returnAtlas = null; - - if (m_atlasStore.ContainsKey(atlasName)) - { - returnAtlas = m_atlasStore[atlasName]; - } - - return returnAtlas; - } - - /// - /// Creates a new atlas from a texture and a name. - /// - /// The full path to the texture. - /// The name to give the atlas. Used for finding and using later. - /// Whether the atlas was created successfully. - public static bool InitialiseAtlas(string texturePath, string atlasName) - { - bool createdAtlas = false; - - if (texturePath != null) - { - Shader shader = Shader.Find("UI/Default UI Shader"); - - if (shader != null) - { - if (File.Exists(texturePath)) - { - Texture2D spriteTexture = new Texture2D(2, 2, TextureFormat.ARGB32, false); - FileStream fileStream = new FileStream(texturePath, FileMode.Open, FileAccess.Read); - byte[] imageData = new byte[fileStream.Length]; - - fileStream.Read(imageData, 0, (int)fileStream.Length); - spriteTexture.LoadImage(imageData); - FixTransparency(spriteTexture); - - Material atlasMaterial = new Material(shader) - { - mainTexture = spriteTexture - }; - - UITextureAtlas atlas = ScriptableObject.CreateInstance(); - atlas.name = atlasName; - atlas.material = atlasMaterial; - - m_atlasStore.Add(atlasName, atlas); - - createdAtlas = true; - } - else - { - Debug.LogError("SpriteUtilities: Could not find atlas at " + texturePath); - } - } - else - { - Debug.LogError("SpriteUtilities: Couldn't find the default UI Shader!"); - } - } - else - { - Debug.LogError("SpriteUtilities: Could not find the mod path, which is odd."); - } - - return createdAtlas; - } - - /// - /// Creates a new sprite using the size of the image inside the atlas. - /// - /// The location and size of the sprite within the atlas (in pixels). - /// The name of the sprite to create - /// The name of the atlas to add the sprite to. - /// - public static bool AddSpriteToAtlas(Rect dimensions, string spriteName, string atlasName) - { - bool returnValue = false; - - if (m_atlasStore.ContainsKey(atlasName)) - { - UITextureAtlas foundAtlas = m_atlasStore[atlasName]; - Texture2D atlasTexture = foundAtlas.texture; - Vector2 atlasSize = new Vector2(atlasTexture.width, atlasTexture.height); - Rect relativeLocation = new Rect(new Vector2(dimensions.position.x / atlasSize.x, dimensions.position.y / atlasSize.y), new Vector2(dimensions.width / atlasSize.x, dimensions.height / atlasSize.y)); - Texture2D spriteTexture = new Texture2D((int)Math.Round(dimensions.width), (int)Math.Round(dimensions.height)); - - spriteTexture.SetPixels(atlasTexture.GetPixels((int)dimensions.position.x, (int)dimensions.position.y, (int)dimensions.width, (int)dimensions.height)); - - UITextureAtlas.SpriteInfo createdSprite = new UITextureAtlas.SpriteInfo() - { - name = spriteName, - region = relativeLocation, - texture = spriteTexture - }; - - foundAtlas.AddSprite(createdSprite); - returnValue = true; - } - - return returnValue; - } - - //I copied this from Traffic++, which was copied from below - //========================================================================= - // Methods created by petrucio -> http://answers.unity3d.com/questions/238922/png-transparency-has-white-borderhalo.html - - /// - /// Copy the values of adjacent pixels to transparent pixels color info, to - /// remove the white border artifact when importing transparent .PNGs. - /// - /// - public static void FixTransparency(Texture2D texture) - { - Color32[] pixels = texture.GetPixels32(); - int w = texture.width; - int h = texture.height; - - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - int idx = y * w + x; - Color32 pixel = pixels[idx]; - if (pixel.a == 0) - { - bool done = false; - if (!done && x > 0) done = TryAdjacent(ref pixel, pixels[idx - 1]); // Left pixel - if (!done && x < w - 1) done = TryAdjacent(ref pixel, pixels[idx + 1]); // Right pixel - if (!done && y > 0) done = TryAdjacent(ref pixel, pixels[idx - w]); // Top pixel - if (!done && y < h - 1) done = TryAdjacent(ref pixel, pixels[idx + w]); // Bottom pixel - pixels[idx] = pixel; - } - } - } - - texture.SetPixels32(pixels); - texture.Apply(); - } - - private static bool TryAdjacent(ref Color32 pixel, Color32 adjacent) - { - if (adjacent.a == 0) return false; - - pixel.r = adjacent.r; - pixel.g = adjacent.g; - pixel.b = adjacent.b; - return true; - } - //========================================================================= - } -} \ No newline at end of file + /// + /// Utilities for sprite handling. Takes care of atlases and sprites. + /// + /// Atlases are a large map of many small sprites. Cities handles all + /// individual sprites using a single large atlas, and each sprite has a + /// location on the atlas. + /// + /// + public class SpriteUtilities + { + /* + FYI - Atlas' are essentially sprite maps. They contain + multiple sprites, and locations to those areas of the atlas. + It's much better than storing individual sprites. + */ + internal static Dictionary m_atlasStore = new Dictionary(); + + /// + /// Returns a stored atlas. + /// + /// The name of the atlas to return. + /// + public static UITextureAtlas GetAtlas(string atlasName) + { + UITextureAtlas returnAtlas = null; + + if (m_atlasStore.ContainsKey(atlasName)) + { + returnAtlas = m_atlasStore[atlasName]; + } + + return returnAtlas; + } + + /// + /// Creates a new atlas from a texture and a name. + /// + /// The full path to the texture. + /// The name to give the atlas. Used for finding and using later. + /// Whether the atlas was created successfully. + public static bool InitialiseAtlas(string texturePath, string atlasName) + { + bool createdAtlas = false; + + if (texturePath != null) + { + Shader shader = Shader.Find("UI/Default UI Shader"); + + if (shader != null) + { + if (File.Exists(texturePath)) + { + Texture2D spriteTexture = new Texture2D(2, 2, TextureFormat.ARGB32, false); + FileStream fileStream = new FileStream(texturePath, FileMode.Open, FileAccess.Read); + byte[] imageData = new byte[fileStream.Length]; + + fileStream.Read(imageData, 0, (int)fileStream.Length); + spriteTexture.LoadImage(imageData); + FixTransparency(spriteTexture); + + Material atlasMaterial = new Material(shader) + { + mainTexture = spriteTexture + }; + + UITextureAtlas atlas = ScriptableObject.CreateInstance(); + atlas.name = atlasName; + atlas.material = atlasMaterial; + + m_atlasStore.Add(atlasName, atlas); + + createdAtlas = true; + } + else + { + Debug.LogError("SpriteUtilities: Could not find atlas at " + texturePath); + } + } + else + { + Debug.LogError("SpriteUtilities: Couldn't find the default UI Shader!"); + } + } + else + { + Debug.LogError("SpriteUtilities: Could not find the mod path, which is odd."); + } + + return createdAtlas; + } + + /// + /// Creates a new sprite using the size of the image inside the atlas. + /// + /// The location and size of the sprite within the atlas (in pixels). + /// The name of the sprite to create + /// The name of the atlas to add the sprite to. + /// + public static bool AddSpriteToAtlas(Rect dimensions, string spriteName, string atlasName) + { + bool returnValue = false; + + if (m_atlasStore.ContainsKey(atlasName)) + { + UITextureAtlas foundAtlas = m_atlasStore[atlasName]; + Texture2D atlasTexture = foundAtlas.texture; + Vector2 atlasSize = new Vector2(atlasTexture.width, atlasTexture.height); + Rect relativeLocation = new Rect(new Vector2(dimensions.position.x / atlasSize.x, dimensions.position.y / atlasSize.y), new Vector2(dimensions.width / atlasSize.x, dimensions.height / atlasSize.y)); + Texture2D spriteTexture = new Texture2D((int)Math.Round(dimensions.width), (int)Math.Round(dimensions.height)); + + spriteTexture.SetPixels(atlasTexture.GetPixels((int)dimensions.position.x, (int)dimensions.position.y, (int)dimensions.width, (int)dimensions.height)); + + UITextureAtlas.SpriteInfo createdSprite = new UITextureAtlas.SpriteInfo() + { + name = spriteName, + region = relativeLocation, + texture = spriteTexture + }; + + foundAtlas.AddSprite(createdSprite); + returnValue = true; + } + + return returnValue; + } + + //I copied this from Traffic++, which was copied from below + //========================================================================= + // Methods created by petrucio -> http://answers.unity3d.com/questions/238922/png-transparency-has-white-borderhalo.html + + /// + /// Copy the values of adjacent pixels to transparent pixels color info, to + /// remove the white border artifact when importing transparent .PNGs. + /// + /// + public static void FixTransparency(Texture2D texture) + { + Color32[] pixels = texture.GetPixels32(); + int w = texture.width; + int h = texture.height; + + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + int idx = y * w + x; + Color32 pixel = pixels[idx]; + if (pixel.a == 0) + { + bool done = false; + if (!done && x > 0) done = TryAdjacent(ref pixel, pixels[idx - 1]); // Left pixel + if (!done && x < w - 1) done = TryAdjacent(ref pixel, pixels[idx + 1]); // Right pixel + if (!done && y > 0) done = TryAdjacent(ref pixel, pixels[idx - w]); // Top pixel + if (!done && y < h - 1) done = TryAdjacent(ref pixel, pixels[idx + w]); // Bottom pixel + pixels[idx] = pixel; + } + } + } + + texture.SetPixels32(pixels); + texture.Apply(); + } + + private static bool TryAdjacent(ref Color32 pixel, Color32 adjacent) + { + if (adjacent.a == 0) return false; + + pixel.r = adjacent.r; + pixel.g = adjacent.g; + pixel.b = adjacent.b; + return true; + } + //========================================================================= + } +} diff --git a/img/PoliticsStaticModel-fixed.png b/img/PoliticsStaticModel-fixed.png new file mode 100644 index 0000000..298fb07 Binary files /dev/null and b/img/PoliticsStaticModel-fixed.png differ diff --git a/img/PoliticsStaticModel.png b/img/PoliticsStaticModel.png new file mode 100644 index 0000000..1a8731f Binary files /dev/null and b/img/PoliticsStaticModel.png differ diff --git a/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs b/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs new file mode 100644 index 0000000..5d01041 --- /dev/null +++ b/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")] diff --git a/obj/Debug/RealCity.csproj.FileListAbsolute.txt b/obj/Debug/RealCity.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..e69de29