コード例 #1
0
        private static bool IsSameLocation(
            ref TransferManager.TransferOffer requestOffer,
            ref TransferManager.TransferOffer responseOffer)
        {
            if (requestOffer.m_object == responseOffer.m_object)
            {
                return(true);
            }

            var requestHomeBuilding  = TransferManagerInfo.GetHomeBuilding(ref requestOffer);
            var responseHomeBuilding = TransferManagerInfo.GetHomeBuilding(ref responseOffer);

            if (requestHomeBuilding == responseHomeBuilding)
            {
                return(true);
            }

            // Don't match a guest vehicle to its host building.  For instance, Taxi stands.
            if (responseOffer.Vehicle != 0 && BuildingManager.instance.m_buildings.m_buffer[requestHomeBuilding].m_guestVehicles != 0)
            {
                var vehicleID = BuildingManager.instance.m_buildings.m_buffer[requestHomeBuilding].m_guestVehicles;
                int num       = 0;
                while (vehicleID != 0)
                {
                    if (responseOffer.Vehicle == vehicleID)
                    {
                        return(true);
                    }

                    vehicleID = VehicleManager.instance.m_vehicles.m_buffer[vehicleID].m_nextGuestVehicle;
                    ++num;

                    if (++num > 16384)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                        break;
                    }
                }
            }

            // Don't match outside connections that are too close to each other.
            if (TransferManagerInfo.IsOutsideBuilding(requestHomeBuilding) && TransferManagerInfo.IsOutsideBuilding(responseHomeBuilding))
            {
                var requestPosition  = BuildingManager.instance.m_buildings.m_buffer[requestHomeBuilding].m_position;
                var responsePosition = BuildingManager.instance.m_buildings.m_buffer[responseHomeBuilding].m_position;

                var distanceSquared = Vector3.SqrMagnitude(responsePosition - requestPosition);
                return(distanceSquared <= 100000);
            }

            return(false);
        }
コード例 #2
0
        /// <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
        private static bool IsSameLocation(
            ref TransferManager.TransferOffer requestOffer,
            ref TransferManager.TransferOffer responseOffer)
        {
            if (requestOffer.m_object == responseOffer.m_object)
            {
                return(true);
            }

            var requestHomeBuilding  = TransferManagerInfo.GetHomeBuilding(ref requestOffer);
            var responseHomeBuilding = TransferManagerInfo.GetHomeBuilding(ref responseOffer);

            if (requestHomeBuilding == responseHomeBuilding)
            {
                return(true);
            }

            // Don't match a guest vehicle to its host building.  For instance, Taxi stands.
            if (responseOffer.Vehicle != 0 && BuildingManager.instance.m_buildings.m_buffer[requestHomeBuilding].m_guestVehicles != 0)
            {
                var vehicleID = BuildingManager.instance.m_buildings.m_buffer[requestHomeBuilding].m_guestVehicles;
                int num       = 0;
                while (vehicleID != 0)
                {
                    if (responseOffer.Vehicle == vehicleID)
                    {
                        return(true);
                    }

                    vehicleID = VehicleManager.instance.m_vehicles.m_buffer[vehicleID].m_nextGuestVehicle;
                    ++num;

                    if (++num > 16384)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                        break;
                    }
                }
            }

            return(false);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        /// <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);
        }