public static void Prefix(uint citizenID, ref Citizen data, ref ushort sourceBuilding, ref ushort targetBuilding)
        {
            if (data.m_workBuilding != targetBuilding)
            {
                var building = Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetBuilding];
                if (building.Info.m_class.m_service == ItemClass.Service.Commercial)
                {
                    CitizenManager instance       = Singleton <CitizenManager> .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;
                    }

                    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;
                        }
                    }
                }
            }
        }
        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;

            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:
                if (MainDataStore.noImport)
                {
                    if (Singleton <BuildingManager> .instance.m_buildings.m_buffer[offer.Building].Info.m_buildingAI is OutsideConnectionAI)
                    {
                        return(false);
                    }
                }
                break;

            default:
                return(true);
            }

            var instance   = Singleton <BuildingManager> .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)
                    {
                        buildingData.m_flags &= ~Building.Flags.Active;
                        //no resource
                        return(false);
                    }
                    else
                    {
                        return(true);
                    }
                }
            }

            //Remove cotenancy
            if (material == TransferManager.TransferReason.Single0 || material == TransferManager.TransferReason.Single0B)
            {
                material = TransferManager.TransferReason.Family0;
            }
            else if (material == TransferManager.TransferReason.Single1 || material == TransferManager.TransferReason.Single1B)
            {
                material = TransferManager.TransferReason.Family1;
            }
            else if (material == TransferManager.TransferReason.Single2 || material == TransferManager.TransferReason.Single2B)
            {
                material = TransferManager.TransferReason.Family2;
            }
            else if (material == TransferManager.TransferReason.Single3 || material == TransferManager.TransferReason.Single3B)
            {
                material = TransferManager.TransferReason.Family3;
            }
            return(true);
        }
        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 <CitizenManager> .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 <BuildingManager> .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 <BuildingManager> .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 <BuildingManager> .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 <BuildingManager> .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 <BuildingManager> .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 <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
        }
示例#4
0
        private void RefreshDisplayData()
        {
            if (refeshOnce || (BuildingData.lastBuildingID != WorldInfoPanel.GetCurrentInstanceID().Building))
            {
                if (isVisible)
                {
                    BuildingData.lastBuildingID = WorldInfoPanel.GetCurrentInstanceID().Building;
                    Building buildingData = Singleton <BuildingManager> .instance.m_buildings.m_buffer[BuildingData.lastBuildingID];
                    if (buildingData.Info.m_class.m_service == ItemClass.Service.Residential)
                    {
                        Hide();
                    }
                    else
                    {
                        float  averageEmployeeFee = CaculateEmployeeOutcome(buildingData, out int totalWorkerCount);
                        int    landRentFee        = CaculateLandFee(buildingData, BuildingData.lastBuildingID);
                        string incomeType         = RealCityPrivateBuildingAI.GetProductionType(false, BuildingData.lastBuildingID, buildingData);
                        string outgoingType       = RealCityPrivateBuildingAI.GetProductionType(true, BuildingData.lastBuildingID, buildingData);
                        float  incomePrice        = RealCityPrivateBuildingAI.GetPrice(false, BuildingData.lastBuildingID, buildingData);
                        float  outgoingPrice      = RealCityPrivateBuildingAI.GetPrice(true, BuildingData.lastBuildingID, buildingData);
                        buildingMoney.text          = string.Format(Localization.Get("BUILDING_MONEY") + " [{0}]", BuildingData.buildingMoney[BuildingData.lastBuildingID]);
                        buildingNetAsset.text       = string.Format(Localization.Get("BUILDING_NETASSET") + " [{0}]", (BuildingData.buildingMoney[BuildingData.lastBuildingID] + buildingData.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(RealCityPrivateBuildingAI.GetIncomingProductionType(BuildingData.lastBuildingID, buildingData))));
                        buildingIncomeBuffer.text   = string.Format(Localization.Get("MATERIAL_BUFFER") + " [{0}]" + " " + incomeType, buildingData.m_customBuffer1);
                        buildingOutgoingBuffer.text = string.Format(Localization.Get("PRODUCTION_BUFFER") + " [{0}]" + " " + outgoingType, buildingData.m_customBuffer2);
                        employFee.text = Localization.Get("AVERAGE_EMPLOYFEE") + " " + averageEmployeeFee.ToString() + " " + Localization.Get("PROFIT_SHARING");
                        landRent.text  = string.Format(Localization.Get("BUILDING_LANDRENT") + " [{0:N2}]", landRentFee);
                        buyPrice.text  = string.Format(Localization.Get("BUY_PRICE") + " " + incomeType + "[{0:N2}]", incomePrice);
                        sellPrice.text = string.Format(Localization.Get("SELL_PRICE") + " " + outgoingType + " [{0:N2}]", outgoingPrice);

                        float consumptionDivider = 0f;
                        if (buildingData.Info.m_class.m_subService == ItemClass.SubService.IndustrialGeneric)
                        {
                            consumptionDivider    = RealCityPrivateBuildingAI.GetComsumptionDivider(buildingData, BuildingData.lastBuildingID) * 4f;
                            comsuptionDivide.text = string.Format(Localization.Get("MATERIAL_DIV_PRODUCTION") + " [1:{0:N2}]", consumptionDivider);
                        }
                        else
                        {
                            if ((buildingData.Info.m_buildingAI is IndustrialExtractorAI) || buildingData.Info.m_class.m_service == ItemClass.Service.Office)
                            {
                                comsuptionDivide.text = string.Format(Localization.Get("MATERIAL_DIV_PRODUCTION") + " N/A");
                            }
                            else
                            {
                                consumptionDivider    = RealCityPrivateBuildingAI.GetComsumptionDivider(buildingData, BuildingData.lastBuildingID);
                                comsuptionDivide.text = string.Format(Localization.Get("MATERIAL_DIV_PRODUCTION") + " [1:{0:N2}]", consumptionDivider);
                            }
                        }

                        int m_sellTax = RealCityPrivateBuildingAI.GetTaxRate(buildingData);
                        sellTax.text = string.Format(Localization.Get("SELL_TAX") + " [{0}%]", m_sellTax);

                        if (consumptionDivider == 0f)
                        {
                            profit.text = string.Format(Localization.Get("PROFIT") + " N/A");
                        }
                        else
                        {
                            float profitRatio = (outgoingPrice * (1f - m_sellTax / 100f) - (incomePrice / consumptionDivider)) / outgoingPrice;
                            if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial)
                            {
                                profit.text = string.Format(Localization.Get("PROFIT") + " [{0}%]" + Localization.Get("EXCLUDE_VISIT_INCOME"), (int)(profitRatio * 100f));
                            }
                            else
                            {
                                profit.text = string.Format(Localization.Get("PROFIT") + " [{0}%]", (int)(profitRatio * 100f));
                            }
                        }

                        int usedCar = 0;
                        int num     = 0;
                        int num1    = 0;
                        int num2    = 0;
                        int car     = 0;
                        if (buildingData.Info.m_class.m_service == ItemClass.Service.Industrial)
                        {
                            TransferManager.TransferReason tempReason = default(TransferManager.TransferReason);
                            if (buildingData.Info.m_buildingAI is IndustrialExtractorAI)
                            {
                                RealCityIndustrialExtractorAI.InitDelegate();
                                var industrialExtractorAI = (IndustrialExtractorAI)buildingData.Info.m_buildingAI;
                                int productionCapacity    = industrialExtractorAI.CalculateProductionCapacity((ItemClass.Level)buildingData.m_level, new Randomizer(BuildingData.lastBuildingID), buildingData.m_width, buildingData.m_length);
                                car        = Mathf.Max(1, productionCapacity / 6);
                                tempReason = RealCityIndustrialExtractorAI.GetOutgoingTransferReason((IndustrialExtractorAI)buildingData.Info.m_buildingAI);
                                RealCityCommonBuildingAI.InitDelegate();
                                RealCityCommonBuildingAI.CalculateOwnVehicles((IndustrialExtractorAI)buildingData.Info.m_buildingAI, BuildingData.lastBuildingID, ref buildingData, tempReason, ref usedCar, ref num, ref num1, ref num2);
                            }
                            else
                            {
                                RealCityIndustrialBuildingAI.InitDelegate();
                                var industrialBuildingAI = (IndustrialBuildingAI)buildingData.Info.m_buildingAI;
                                int productionCapacity   = industrialBuildingAI.CalculateProductionCapacity((ItemClass.Level)buildingData.m_level, new Randomizer(BuildingData.lastBuildingID), buildingData.m_width, buildingData.m_length);
                                car        = Mathf.Max(1, productionCapacity / 6);
                                tempReason = RealCityIndustrialBuildingAI.GetOutgoingTransferReason((IndustrialBuildingAI)buildingData.Info.m_buildingAI);
                                RealCityCommonBuildingAI.InitDelegate();
                                RealCityCommonBuildingAI.CalculateOwnVehicles((IndustrialBuildingAI)buildingData.Info.m_buildingAI, BuildingData.lastBuildingID, ref buildingData, tempReason, ref usedCar, ref num, ref num1, ref num2);
                            }

                            usedcar.text = string.Format(Localization.Get("CAR_USED") + " [{0}/{1}]", usedCar, car);
                        }
                        else 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), BuildingData.lastBuildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount);
                            var amount = buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount;
                            var commercialBuildingAI = buildingData.Info.m_buildingAI as CommercialBuildingAI;
                            var maxCount             = commercialBuildingAI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer(BuildingData.lastBuildingID), buildingData.m_width, buildingData.m_length);
                            usedcar.text = string.Format("FORDEBUG" + " [{0}/{1}/{2}/{3}]", aliveVisitCount, totalVisitCount, maxCount, amount);
                        }
                        else
                        {
                            usedcar.text = Localization.Get("CAR_USED") + " 0/0";
                        }

                        BringToFront();
                        refeshOnce = false;
                    }
                }
            }
        }