예제 #1
0
        /// <summary>
        /// Returns a descriptive text indicating the districts that are served by the specified building.
        /// </summary>
        /// <param name="building"></param>
        /// <returns></returns>
        public static string GetOutputDistrictsServedText(ushort building)
        {
            if (building == 0)
            {
                return(string.Empty);
            }


            var txtItems = new List <string>();

            txtItems.Add($"<<Districts served>>");

            if (Constraints.OutputAllLocalAreas(building))
            {
                txtItems.Add($"All local areas");
            }
            else if (Constraints.OutputDistrictParkServiced(building) == null || Constraints.OutputDistrictParkServiced(building).Count == 0)
            {
                return($"<<No districts served!>>");
            }
            else
            {
                var districtParkNames = Constraints.OutputDistrictParkServiced(building)
                                        .Select(dp => dp.Name)
                                        .OrderBy(s => s);

                foreach (var districtParkName in districtParkNames)
                {
                    txtItems.Add(districtParkName);
                }
            }

            return(string.Join("\n", txtItems.ToArray()));
        }
        /// <summary>
        /// Returns true if we can potentially match the two given offers.
        /// </summary>
        /// <returns></returns>
        private static bool IsValidDistrictOffer(
            TransferManager.TransferReason material,
            ref TransferManager.TransferOffer requestOffer, int requestPriority,
            ref TransferManager.TransferOffer responseOffer, int responsePriority)
        {
            var requestBuilding  = TransferManagerInfo.GetHomeBuilding(ref requestOffer);
            var responseBuilding = TransferManagerInfo.GetHomeBuilding(ref responseOffer);

            if (responseBuilding == 0)
            {
                Logger.LogMaterial(
                    $"TransferManager::IsValidDistrictOffer: {Utils.ToString(ref responseOffer, material)}, not a district services building",
                    material);
                return(false);
            }

            // Special logic if both buildings are warehouses.  Used to prevent goods from being shuffled back and forth between warehouses.
            if (BuildingManager.instance.m_buildings.m_buffer[requestBuilding].Info.GetAI() is WarehouseAI &&
                BuildingManager.instance.m_buildings.m_buffer[responseBuilding].Info.GetAI() is WarehouseAI)
            {
                return(false);
            }

            if (Constraints.OutputAllLocalAreas(responseBuilding))
            {
                Logger.LogMaterial(
                    $"TransferManager::IsValidDistrictOffer: {Utils.ToString(ref responseOffer, material)}, serves all local areas",
                    material);
                return(true);
            }

            // The call to TransferManagerInfo.GetDistrict applies to offers that are come from buildings, service
            // vehicles, citizens, AND segments.  The latter needs to be considered for road maintenance.
            var requestDistrictPark         = TransferManagerInfo.GetDistrictPark(material, ref requestOffer);
            var responseDistrictParksServed = Constraints.OutputDistrictParkServiced(responseBuilding);

            if (requestDistrictPark.IsServedBy(responseDistrictParksServed))
            {
                Logger.LogMaterial(
                    $"TransferManager::IsValidDistrictOffer: {Utils.ToString(ref responseOffer, material)}, serves district {requestDistrictPark.Name}",
                    material);
                return(true);
            }

            Logger.LogMaterial(
                $"TransferManager::IsValidDistrictOffer: {Utils.ToString(ref responseOffer, material)}, not valid",
                material);
            return(false);
        }
예제 #3
0
        /// <summary>
        /// Returns a descriptive text describing problems with this supply chain building ...
        /// </summary>
        /// <param name="building"></param>
        /// <returns></returns>
        public static string GetSupplyBuildingProblemsText(ushort building)
        {
            if (building == 0 || !TransferManagerInfo.IsSupplyChainBuilding(building))
            {
                return(string.Empty);
            }

            bool FindSourceBuilding(TransferManager.TransferReason material)
            {
                if (material == TransferManager.TransferReason.None)
                {
                    return(true);
                }

                // Assume for now that the outside connection can supply the building with the materials it needs.
                if (Constraints.InputOutsideConnections(building))
                {
                    return(true);
                }

                for (ushort buildingIn = 1; buildingIn < BuildingManager.MAX_BUILDING_COUNT; buildingIn++)
                {
                    if (!TransferManagerInfo.IsSupplyChainBuilding(building))
                    {
                        continue;
                    }

                    if (GetSupplyBuildingOutputMaterial(buildingIn) == material)
                    {
                        // Check if a supply link exists ...
                        if (Constraints.SupplyDestinations(buildingIn)?.Count > 0 && Constraints.SupplyDestinations(buildingIn).Contains(building))
                        {
                            return(true);
                        }

                        var requestDistrictPark  = TransferManagerInfo.GetDistrictPark(building);
                        var responseDistrictPark = TransferManagerInfo.GetDistrictPark(buildingIn);

                        if (!Constraints.InputAllLocalAreas(building))
                        {
                            var requestDistrictParksServed = Constraints.InputDistrictParkServiced(building);
                            if (!responseDistrictPark.IsServedBy(requestDistrictParksServed))
                            {
                                continue;
                            }
                        }

                        if (Constraints.OutputAllLocalAreas(buildingIn))
                        {
                            return(true);
                        }
                        else
                        {
                            // The call to TransferManagerInfo.GetDistrict applies to offers that are come from buildings, service
                            // vehicles, citizens, AND segments.  The latter needs to be considered for road maintenance.
                            var responseDistrictParksServed = Constraints.OutputDistrictParkServiced(buildingIn);
                            if (requestDistrictPark.IsServedBy(responseDistrictParksServed))
                            {
                                return(true);
                            }
                        }
                    }
                }

                return(false);
            }

            // Detect if we do have an other building that can supply materials to this building.
            List <TransferManager.TransferReason> notFound = new List <TransferManager.TransferReason>();

            switch (BuildingManager.instance.m_buildings.m_buffer[building].Info?.GetAI())
            {
            case ProcessingFacilityAI processingFacilityAI:
                if (!FindSourceBuilding(processingFacilityAI.m_inputResource1))
                {
                    notFound.Add(processingFacilityAI.m_inputResource1);
                }

                if (!FindSourceBuilding(processingFacilityAI.m_inputResource2))
                {
                    notFound.Add(processingFacilityAI.m_inputResource2);
                }

                if (!FindSourceBuilding(processingFacilityAI.m_inputResource3))
                {
                    notFound.Add(processingFacilityAI.m_inputResource3);
                }

                if (!FindSourceBuilding(processingFacilityAI.m_inputResource4))
                {
                    notFound.Add(processingFacilityAI.m_inputResource4);
                }

                break;

            default:
                break;
            }

            if (notFound.Count > 0)
            {
                return(string.Join(",", notFound.Select(x => x.ToString()).ToArray()));
            }
            else
            {
                return(string.Empty);
            }
        }
예제 #4
0
        /// <summary>
        /// Returns a descriptive text indicating the supply chain destination buildings that the given building
        /// will ship to.
        /// </summary>
        /// <param name="building"></param>
        /// <returns></returns>
        public static string GetSupplyBuildingDestinationsText(ushort building)
        {
            if (building == 0)
            {
                return(string.Empty);
            }

            var txtItems = new List <string>();

            txtItems.Add($"<<Supply Chain Shipments To>>");

            if (Constraints.OutputAllLocalAreas(building))
            {
                txtItems.Add($"All local areas");
            }

            if (Constraints.OutputOutsideConnections(building))
            {
                txtItems.Add($"All outside connections");
            }

            if (Constraints.OutputAllLocalAreas(building))
            {
                return(string.Join("\n", txtItems.ToArray()));
            }

            // Next, list output building names
            var supply = Constraints.SupplyDestinations(building);

            if (supply?.Count > 0)
            {
                var buildingNames = supply
                                    .Select(b => $"{GetBuildingName(b)} ({b})")
                                    .OrderBy(s => s);

                foreach (var buildingName in buildingNames)
                {
                    txtItems.Add(buildingName);
                }
            }

            var districts = Constraints.OutputDistrictParkServiced(building);

            if (districts?.Count > 0)
            {
                // Then add district names
                var districtParkNames = districts
                                        .Select(dp => dp.Name)
                                        .OrderBy(s => s);

                foreach (var districtParkName in districtParkNames)
                {
                    txtItems.Add($"{districtParkName} (DISTRICT)");
                }
            }

            if (txtItems.Count == 1)
            {
                return($"<<WARNING: No supply chain shipments output!>>");
            }
            else
            {
                return(string.Join("\n", txtItems.ToArray()));
            }
        }
        /// <summary>
        /// Returns true if we can potentially match the two given offers.
        /// </summary>
        /// <returns></returns>
        private static bool IsValidSupplyChainOffer(
            TransferManager.TransferReason material,
            ref TransferManager.TransferOffer requestOffer, int requestPriority,
            ref TransferManager.TransferOffer responseOffer, int responsePriority)
        {
            var requestBuilding  = TransferManagerInfo.GetHomeBuilding(ref requestOffer);
            var responseBuilding = TransferManagerInfo.GetHomeBuilding(ref responseOffer);

            if (responseBuilding == 0)
            {
                Logger.LogMaterial(
                    $"TransferManager::IsValidSupplyChainOffer: {Utils.ToString(ref responseOffer, material)}, not a district services building",
                    material);
                return(false);
            }

            // First check if a supply link exists.
            var responseSupplyDestinations = Constraints.SupplyDestinations(responseBuilding);

            if (responseSupplyDestinations?.Count > 0)
            {
                for (int i = 0; i < responseSupplyDestinations.Count; i++)
                {
                    if (responseSupplyDestinations[i] == (int)requestBuilding)
                    {
                        Logger.LogMaterial(
                            $"TransferManager::IsValidSupplyChainOffer: {Utils.ToString(ref responseOffer, material)}, supply link allowed",
                            material);
                        return(true);
                    }
                }
            }

            // Special logic if both buildings are warehouses.  Used to prevent goods from being shuffled back and forth between warehouses.
            if (BuildingManager.instance.m_buildings.m_buffer[requestBuilding].Info.GetAI() is WarehouseAI &&
                BuildingManager.instance.m_buildings.m_buffer[responseBuilding].Info.GetAI() is WarehouseAI)
            {
                return(false);
            }

            // Now match on all local areas and district restrictions, both on request an response buildings!
            var requestDistrictPark  = TransferManagerInfo.GetDistrictPark(material, ref requestOffer);
            var responseDistrictPark = TransferManagerInfo.GetDistrictPark(material, ref responseOffer);

            // If the request constrains the districts that it can accept orders from ...
            if (!Constraints.InputAllLocalAreas(requestBuilding))
            {
                var requestDistrictParksServed = Constraints.InputDistrictParkServiced(requestBuilding);
                if (!responseDistrictPark.IsServedBy(requestDistrictParksServed))
                {
                    Logger.LogMaterial(
                        $"TransferManager::IsValidSupplyChainOffer: {Utils.ToString(ref responseOffer, material)}, request is constrained to accept offers from certain districts only!",
                        material);
                    return(false);
                }
            }

            if (!Constraints.InputOutsideConnections(requestBuilding) && TransferManagerInfo.IsOutsideOffer(ref responseOffer))
            {
                Logger.LogMaterial(
                    $"TransferManager::IsValidSupplyChainOffer: {Utils.ToString(ref responseOffer, material)}, request is constrained not to accept outside offers!",
                    material);
                return(false);
            }

            if (Constraints.OutputAllLocalAreas(responseBuilding))
            {
                Logger.LogMaterial(
                    $"TransferManager::IsValidSupplyChainOffer: {Utils.ToString(ref responseOffer, material)}, serves all local areas",
                    material);
                return(true);
            }
            else
            {
                // The call to TransferManagerInfo.GetDistrict applies to offers that are come from buildings, service
                // vehicles, citizens, AND segments.  The latter needs to be considered for road maintenance.
                var responseDistrictParksServed = Constraints.OutputDistrictParkServiced(responseBuilding);
                if (requestDistrictPark.IsServedBy(responseDistrictParksServed))
                {
                    Logger.LogMaterial(
                        $"TransferManager::IsValidSupplyChainOffer: {Utils.ToString(ref responseOffer, material)}, serves district {requestDistrictPark.Name}",
                        material);
                    return(true);
                }
            }

            Logger.LogMaterial(
                $"TransferManager::IsValidSupplyChainOffer: {Utils.ToString(ref responseOffer, material)}, not valid",
                material);
            return(false);
        }