Ejemplo n.º 1
0
        /// <summary>
        /// Helper method for displaying information, including district and supply chain constraints, about the
        /// building with given building id.
        /// </summary>
        /// <param name="building"></param>
        /// <returns></returns>
        private static string GetBuildingInfoText(ushort building)
        {
            var inputType = TransferManagerInfo.GetBuildingInputType(building);

            var txtItems = new List <string>();

            txtItems.Add($"{TransferManagerInfo.GetBuildingName(building)} ({building})");
            txtItems.Add(TransferManagerInfo.GetDistrictParkText(building));

            // Early return.  Rest of info pertains to building types that we deal with in the mod.
            if (!(TransferManagerInfo.IsDistrictServicesBuilding(building) || TransferManagerInfo.IsCustomVehiclesBuilding(building)))
            {
                return(string.Join("\n", txtItems.ToArray()));
            }

            txtItems.Add(TransferManagerInfo.GetBuildingInputTypeText(building));
            txtItems.Add(TransferManagerInfo.GetServicesText(building));

            if (!TransferManagerInfo.IsSupplyChainBuilding(building))
            {
                if (TransferManagerInfo.IsDistrictServicesBuilding(building))
                {
                    txtItems.Add("");
                    txtItems.Add(TransferManagerInfo.GetOutputDistrictsServedText(building));
                }

                if (Settings.enableCustomVehicles &&
                    !VehicleManagerMod.BuildingUseDefaultVehicles[building] &&
                    VehicleManagerMod.BuildingToVehicles[building] != null &&
                    (inputType & InputType.VEHICLES) != InputType.NONE)
                {
                    txtItems.Add("");
                    txtItems.Add(TransferManagerInfo.GetCustomVehiclesText(building));
                }

                return(string.Join("\n", txtItems.ToArray()));
            }

            if (Settings.enableIndustriesControl)
            {
                // From this point forth, we know this is a supply chain building ...
                txtItems.Add($"Supply Reserve: {Constraints.InternalSupplyBuffer(building)}");

                if ((inputType & InputType.INCOMING) != InputType.NONE)
                {
                    txtItems.Add("");
                    txtItems.Add(TransferManagerInfo.GetSupplyBuildingSourcesText(building));
                }

                if ((inputType & InputType.OUTGOING) != InputType.NONE)
                {
                    txtItems.Add("");
                    txtItems.Add(TransferManagerInfo.GetSupplyBuildingDestinationsText(building));
                }

                if (Settings.enableCustomVehicles &&
                    !VehicleManagerMod.BuildingUseDefaultVehicles[building] &&
                    VehicleManagerMod.BuildingToVehicles[building] != null &&
                    (inputType & InputType.VEHICLES) != InputType.NONE)
                {
                    txtItems.Add("");
                    txtItems.Add(TransferManagerInfo.GetCustomVehiclesText(building));
                }

                var problemText = TransferManagerInfo.GetSupplyBuildingProblemsText(building);
                if (problemText != string.Empty)
                {
                    txtItems.Add("");
                    txtItems.Add($"<<WARNING: Cannot find the following materials to procure!>>");
                    txtItems.Add(problemText);
                }
            }

            return(string.Join("\n", txtItems.ToArray()));
        }
        /// <summary>
        /// Returns true if we can potentially match the two given offers.
        /// </summary>
        /// <returns></returns>
        private static bool IsValidLowPriorityOffer(
            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::IsValidLowPriorityOffer: {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);
            }

            // Special logic for recycling centers, since they can produce recycled goods but the district policies
            // should not apply to these materials.
            if (responseBuilding != 0 && BuildingManager.instance.m_buildings.m_buffer[responseBuilding].Info.GetAI() is LandfillSiteAI)
            {
                if (TransferManagerInfo.IsOutsideOffer(ref requestOffer))
                {
                    Logger.LogMaterial(
                        $"TransferManager::IsValidLowPriorityOffer: {Utils.ToString(ref responseOffer, material)}, allow recycling centers",
                        material);
                    return(true);
                }

                // Only allow if there are no restrictions on the request, OR if recycling center resides in an allowed district.
                var requestDistrictParksServed = Constraints.InputDistrictParkServiced(requestBuilding);
                var responseDistrictPark       = TransferManagerInfo.GetDistrictPark(responseBuilding);
                if (Constraints.InputAllLocalAreas(requestBuilding) || responseDistrictPark.IsServedBy(requestDistrictParksServed))
                {
                    Logger.LogMaterial(
                        $"TransferManager::IsValidLowPriorityOffer: {Utils.ToString(ref responseOffer, material)}, allow recycling centers",
                        material);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            // See if the request is from an outside connection ...
            if (TransferManagerInfo.IsOutsideOffer(ref requestOffer))
            {
                if (TransferManagerInfo.IsOutsideOffer(ref responseOffer))
                {
                    // Prevent matching roads that are too close together ...
                    var distanceSquared = Vector3.SqrMagnitude(responseOffer.Position - requestOffer.Position);
                    return(distanceSquared > 100000);
                }
                else if (TransferManagerInfo.GetSupplyBuildingAmount(responseBuilding) > Constraints.InternalSupplyBuffer(responseBuilding))
                {
                    Logger.LogMaterial(
                        $"TransferManager::IsValidLowPriorityOffer: {Utils.ToString(ref responseOffer, material)}, internal supply buffer, supply amount={TransferManagerInfo.GetSupplyBuildingAmount(responseBuilding)}, supply buffer={Constraints.InternalSupplyBuffer(responseBuilding)}",
                        material);
                    return(true);
                }
                else if (Constraints.OutputOutsideConnections(responseBuilding))
                {
                    Logger.LogMaterial(
                        $"TransferManager::IsValidLowPriorityOffer: {Utils.ToString(ref responseOffer, material)}, matched inside to outside offer",
                        material);
                    return(true);
                }
                else
                {
                    Logger.LogMaterial(
                        $"TransferManager::IsValidLowPriorityOffer: {Utils.ToString(ref responseOffer, material)}, disallowed outside offer",
                        material);
                    return(false);
                }
            }

            // Here, we are guaranteed that the request is a local offer.
            if (TransferManagerInfo.IsOutsideBuilding(responseBuilding))
            {
                // Don't be so aggressive in trying to serve low priority orders with outside connections.
                if (requestPriority > 1 && Constraints.InputOutsideConnections(requestBuilding))
                {
                    Logger.LogMaterial(
                        $"TransferManager::IsValidLowPriorityOffer: {Utils.ToString(ref responseOffer, material)}, matched outside to inside offer",
                        material);
                    return(true);
                }
            }
            else if (TransferManagerInfo.GetSupplyBuildingAmount(responseBuilding) > Constraints.InternalSupplyBuffer(responseBuilding))
            {
                // Only allow if the request building allows all incoming shipments
                if (Constraints.InputAllLocalAreas(requestBuilding))
                {
                    Logger.LogMaterial(
                        $"TransferManager::IsValidLowPriorityOffer: {Utils.ToString(ref responseOffer, material)}, internal supply buffer, supply amount={TransferManagerInfo.GetSupplyBuildingAmount(responseBuilding)}, supply buffer={Constraints.InternalSupplyBuffer(responseBuilding)}",
                        material);
                    return(true);
                }
            }

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