Ejemplo n.º 1
0
        /// <summary>
        /// Set up prop types of vehicle props generated by Elektrix's TVP mod. Need the TVP Patch mod
        /// </summary>
        public void SetVehiclePropType(Dictionary <PropInfo, VehicleInfo> propVehicleInfoTable, PropInfo info)
        {
            propType = Asset.PropType.PropsUnsortedVehicle;
            if (!propVehicleInfoTable.ContainsKey(info))
            {
                return;
            }
            PrefabAI ai = propVehicleInfoTable[info].GetAI();

            if (ai == null)
            {
                return;
            }
            Type aiType = ai.GetType();

            if (IsMotorVehicle(aiType))
            {
                propType = Asset.PropType.PropsMoterVehicle;
            }
            else if (IsRailwayVehicle(aiType))
            {
                propType = Asset.PropType.PropsRailwayVehicle;
            }
            else if (IsAircraft(aiType))
            {
                propType = Asset.PropType.PropsAircraft;
            }
            else if (IsWatercraft(aiType))
            {
                propType = Asset.PropType.PropsWaterCraft;
            }
        }
Ejemplo n.º 2
0
        private static void GetGeneratedRoadName(NetSegment segment, PrefabAI ai, ushort district, out string genName)
        {
            string filename = AdrController.CurrentConfig.GetConfigForDistrict(district).RoadConfig?.NamesFile ?? "";

            if (string.IsNullOrEmpty(filename) || !AdrController.LoadedLocalesRoadName.ContainsKey(filename))
            {
                filename = AdrController.CurrentConfig.GetConfigForDistrict(0).RoadConfig?.NamesFile;
                if (string.IsNullOrEmpty(filename) || !AdrController.LoadedLocalesRoadName.ContainsKey(filename))
                {
                    filename = null;
                }
            }

            Randomizer randomizer = new Randomizer(segment.m_nameSeed);

            if (filename != null)
            {
                int range = AdrController.LoadedLocalesRoadName[filename]?.Length ?? 0;
                if (range == 0)
                {
                    genName = null;
                    return;
                }
                genName = AdrController.LoadedLocalesRoadName[filename][randomizer.Int32((uint)range)];
            }
            else
            {
                genName = m_roadBaseAiGenerateName.Invoke(ai, new object[] { randomizer })?.ToString();
            }
        }
        public void SetPrefab(VehicleInfo prefab)
        {
            if ((UnityEngine.Object)prefab == (UnityEngine.Object)null)
            {
                return;
            }
            PrefabAI ai = prefab.GetAI();

            if ((UnityEngine.Object)ai == (UnityEngine.Object)null)
            {
                return;
            }
            FieldInfo field = ai.GetType().GetField("m_transportInfo");

            if (field == null)
            {
                return;
            }
            TransportInfo.TransportType transportType = (field.GetValue((object)ai) as TransportInfo).m_transportType;
            if (this._firstShow)
            {
                this.FirstShowInit(transportType, prefab);
            }
            else
            {
                this.SetTransportType(transportType, prefab);
            }
        }
Ejemplo n.º 4
0
        public static TransportSystemDefinition from(PrefabAI buildingAI)
        {
            DepotAI depotAI = buildingAI as DepotAI;

            if (depotAI == null)
            {
                return(null);
            }
            return(from(depotAI.m_transportInfo));
        }
Ejemplo n.º 5
0
        public static IBasicBuildingAIOverrides getBuildingOverrideExtension(BuildingInfo info)
        {
            PrefabAI targetAi     = info.GetAI();
            Type     targetTypeAi = targetAi.GetType();

            if (subtypes == null)
            {
                subtypes = new Dictionary <Type, Type>();
                var subclasses = SVMUtils.GetSubtypesRecursive(typeof(BasicBuildingAIOverrides <,>), typeof(SVMBuildingAIOverrideUtils));
                SVMUtils.doLog("GetOverride pré - subclasses:\r\n\t{0}", string.Join("\r\n\t", subclasses?.Select(x => x.ToString())?.ToArray() ?? new string[0]));
                foreach (Type t in subclasses)
                {
                    try
                    {
                        subtypes[t.BaseType.GetGenericArguments()[1]] = t;
                    }
                    catch (Exception e)
                    {
                        SVMUtils.doErrorLog("ERROR ADDING SUBTYPE {0}!\r\n{1}", t, subclasses);
                    }
                }
                SVMUtils.doLog("GetOverride - Classes:\r\n\t{0}", string.Join("\r\n\t", subtypes?.Select(x => x.Key.ToString() + "=>" + x.Value.ToString())?.ToArray() ?? new string[0]));
            }
            Type targetClass = null;
            IBasicBuildingAIOverrides value = null;

            if (!subtypes.ContainsKey(targetTypeAi))
            {
                foreach (var clazz in subtypes.Keys)
                {
                    if (clazz.IsAssignableFrom(targetTypeAi))
                    {
                        value = (IBasicBuildingAIOverrides)SVMUtils.GetPrivateStaticField("instance", subtypes[clazz]);
                        //SVMUtils.doLog("GetOverride - clazz = {0}; value = {1}", clazz, value);
                        if (value.AcceptsAI(targetAi))
                        {
                            targetClass = subtypes[clazz];
                            break;
                        }
                    }
                }
                SVMUtils.doLog("GetOverride - targetClass = {0} ({1})", targetClass, targetTypeAi);
                if (targetClass == null)
                {
                    return(null);
                }
            }
            else
            {
                targetClass = subtypes[targetTypeAi];
                value       = (IBasicBuildingAIOverrides)SVMUtils.GetPrivateStaticField("instance", targetClass);
            }
            //SVMUtils.doLog("GetOverride - value = {0}", value);
            return((IBasicBuildingAIOverrides)value);
        }
Ejemplo n.º 6
0
        public static string GetLocalizedTooltip(Asset asset, PrefabInfo prefab, string title)
        {
            MilestoneInfo unlockMilestone = prefab.GetUnlockMilestone();

            string text = TooltipHelper.Format(new string[]
            {
                LocaleFormatter.Title,
                title,
                LocaleFormatter.Sprite,
                (!string.IsNullOrEmpty(prefab.m_InfoTooltipThumbnail)) ? prefab.m_InfoTooltipThumbnail : prefab.name,
                LocaleFormatter.Text,
                (asset.findIt2Description + Asset.GetLocalizedDescription(prefab)),
                LocaleFormatter.Locked,
                (!ToolsModifierControl.IsUnlocked(unlockMilestone)).ToString()
            });

            ToolsModifierControl.GetUnlockingInfo(unlockMilestone, out string unlockDesc, out string currentValue, out string targetValue, out string progress, out string locked);

            string addTooltip = TooltipHelper.Format(new string[]
            {
                LocaleFormatter.LockedInfo,
                locked,
                LocaleFormatter.UnlockDesc,
                unlockDesc,
                LocaleFormatter.UnlockPopulationProgressText,
                progress,
                LocaleFormatter.UnlockPopulationTarget,
                targetValue,
                LocaleFormatter.UnlockPopulationCurrent,
                currentValue
            });

            text = TooltipHelper.Append(text, addTooltip);
            PrefabAI aI = prefab.GetAI();

            if (aI != null)
            {
                text = TooltipHelper.Append(text, aI.GetLocalizedTooltip());
            }

            if (prefab is PropInfo || prefab is TreeInfo)
            {
                text = TooltipHelper.Append(text, TooltipHelper.Format(new string[]
                {
                    LocaleFormatter.Cost,
                    LocaleFormatter.FormatCost(prefab.GetConstructionCost(), false)
                }));
            }

            return(text);
        }
Ejemplo n.º 7
0
        public static List <ushort> getAllDepotsFromCity()
        {
            List <ushort> saida     = new List <ushort>();
            var           bm        = Singleton <BuildingManager> .instance;
            var           buildings = bm.GetServiceBuildings(ItemClass.Service.PublicTransport);

            foreach (ushort i in buildings)
            {
                PrefabAI prefAI = bm.m_buildings.m_buffer[i].Info.GetAI();
                if (prefAI is DepotAI buildingAI && buildingAI.m_maxVehicleCount > 0)
                {
                    saida.Add(i);
                }
            }
            return(saida);
        }
Ejemplo n.º 8
0
        public static void TryCopyAttributes(PrefabAI src, PrefabAI dst, bool safe = true)
        {
            var oldAIFields = src.GetType()
                              .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
            var newAIFields = dst.GetType()
                              .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);

            var newAIFieldDic = new Dictionary <string, FieldInfo>(newAIFields.Length);

            foreach (var field in newAIFields)
            {
                newAIFieldDic.Add(field.Name, field);
            }

            foreach (var fieldInfo in oldAIFields)
            {
                // do not copy attributes marked NonSerialized
                bool copyField = !fieldInfo.IsDefined(typeof(NonSerializedAttribute), true);

                if (safe && !fieldInfo.IsDefined(typeof(CustomizablePropertyAttribute), true))
                {
                    copyField = false;
                }

                if (copyField)
                {
                    FieldInfo newAIField;
                    newAIFieldDic.TryGetValue(fieldInfo.Name, out newAIField);
                    try
                    {
                        if (newAIField != null && newAIField.GetType().Equals(fieldInfo.GetType()))
                        {
                            newAIField.SetValue(dst, fieldInfo.GetValue(src));
                        }
                    }
                    catch (NullReferenceException)
                    {
                    }
                }
            }
        }
        public override void RefreshLines()
        {
            var tsd = Singleton <T> .instance.GetTSD();

            bool hasPrefix = TLMLineUtils.hasPrefix(ref tsd);
            int  count     = 0;

            foreach (ushort buildingID in TLMDepotAI.getAllDepotsFromCity())
            {
                PrefabAI prefabAI = Singleton <BuildingManager> .instance.m_buildings.m_buffer[buildingID].Info.GetAI();
                if (prefabAI is ShelterAI && tsd.isShelterAiDepot())
                {
                    AddToList(buildingID, false, ref count);
                }
                else if (!tsd.isShelterAiDepot() && prefabAI is DepotAI ai)
                {
                    var tiArray = new TransportInfo[] { ai.m_transportInfo, ai.m_secondaryTransportInfo };
                    foreach (TransportInfo info in tiArray)
                    {
                        if (tsd.isFromSystem(info) && (!hasPrefix || m_prefixFilter.selectedIndex == 0 || TLMDepotAI.getPrefixesServedByDepot(buildingID, info == ai.m_secondaryTransportInfo).Contains((uint)(m_prefixFilter.selectedIndex - 1))))
                        {
                            AddToList(buildingID, info == ai.m_secondaryTransportInfo, ref count);
                        }
                    }
                }
            }

            RemoveExtraLines(count);

            switch (m_LastSortCriterion)
            {
            case DepotSortCriterion.NAME: OnNameSort(); break;

            case DepotSortCriterion.DISTRICT: OnDistrictSort(); break;
            }
            isUpdated = true;
        }
 public override bool AcceptsAI(PrefabAI ai) => ai.GetType() == typeof(DepotAI);
Ejemplo n.º 11
0
 public override bool AcceptsAI(PrefabAI ai) => typeof(DepotAI).IsAssignableFrom(ai.GetType());
Ejemplo n.º 12
0
        /// <summary>
        /// Copies all attributes that share the same name and type from one AI object to another
        /// </summary>
        /// <param name="oldAI">Source AI instance</param>
        /// <param name="newAI">Destination AI instance</param>
        private void TryCopyAttributes(PrefabAI oldAI, PrefabAI newAI)
        {
            var oldAIFields =
                oldAI.GetType()
                    .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic |
                               BindingFlags.FlattenHierarchy);
            var newAIFields = newAI.GetType()
                .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic |
                           BindingFlags.FlattenHierarchy);

            var newAIFieldDic = new Dictionary<String, FieldInfo>(newAIFields.Length);
            foreach (var field in newAIFields)
            {
                newAIFieldDic.Add(field.Name, field);
            }

            foreach (var fieldInfo in oldAIFields)
            {
                if (fieldInfo.IsDefined(typeof (CustomizablePropertyAttribute), true))
                {
                    FieldInfo newAIField;
                    newAIFieldDic.TryGetValue(fieldInfo.Name, out newAIField);

                    try
                    {
                        if (newAIField.GetType().Equals(fieldInfo.GetType()))
                        {
                            newAIField.SetValue(newAI, fieldInfo.GetValue(oldAI));
                        }
                    }
                    catch (NullReferenceException)
                    {
                    }
                }
            }
        }
 public virtual bool AcceptsAI(PrefabAI ai) => true;
 public bool AllowVehicleType(VehicleInfo.VehicleType veh, PrefabAI ai) => AllowVehicleType(veh, (U)ai);
Ejemplo n.º 15
0
        private static string DefaultPrefix(NetInfo info, PrefabAI ai)
        {
            string text = null;

            if ((info.m_vehicleTypes & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None)
            {
                if (ai is RoadTunnelAI roadTunnel)
                {
                    if ((!roadTunnel.m_highwayRules || info.m_forwardVehicleLaneCount + info.m_backwardVehicleLaneCount >= 2))
                    {
                        text = "TUNNEL_NAME_PATTERN";
                    }
                }

                if (ai is RoadAI roadAi)
                {
                    if (roadAi.m_enableZoning)
                    {
                        if ((info.m_setVehicleFlags & Vehicle.Flags.OnGravel) != 0)
                        {
                            text = "ROAD_NAME_PATTERN";
                        }
                        else if (info.m_halfWidth >= 12f)
                        {
                            text = "AVENUE_NAME_PATTERN";
                        }
                        else
                        {
                            text = "STREET_NAME_PATTERN";
                        }
                    }
                    else if (roadAi.m_highwayRules)
                    {
                        if (info.m_hasForwardVehicleLanes && info.m_hasBackwardVehicleLanes)
                        {
                            text = "ROAD_NAME_PATTERN";
                        }
                        else if (info.m_forwardVehicleLaneCount >= 2 || info.m_backwardVehicleLaneCount >= 2)
                        {
                            text = "HIGHWAY_NAME_PATTERN";
                        }
                    }
                }

                if (ai is DamAI)
                {
                    if ((info.m_vehicleTypes & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None)
                    {
                        text = "ROAD_NAME_PATTERN";
                    }
                }

                if (ai is RoadBridgeAI bridgeAi)
                {
                    if ((info.m_vehicleTypes & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None && (!bridgeAi.m_highwayRules || info.m_forwardVehicleLaneCount + info.m_backwardVehicleLaneCount >= 2))
                    {
                        text = "BRIDGE_NAME_PATTERN";
                    }
                }
            }
            return(text);
        }
Ejemplo n.º 16
0
        public static bool GenerateSegmentNameInternal(ushort segmentID, ref string __result, ref List <ushort> usedQueue, bool removePrefix)
        {
            LogUtils.DoLog($"[START {segmentID}]" + __result);
            if ((NetManager.instance.m_segments.m_buffer[segmentID].m_flags & NetSegment.Flags.CustomName) != 0)
            {
                if (usedQueue.Count == 0)
                {
                    return(true);
                }
                else
                {
                    InstanceID id = default;
                    id.NetSegment = segmentID;
                    __result      = Singleton <InstanceManager> .instance.GetName(id);

                    return(false);
                }
            }
            NetSegment segment    = NetManager.instance.m_segments.m_buffer[segmentID];
            NetInfo    info       = segment.Info;
            PrefabAI   ai         = info.GetAI();
            string     format     = null;
            Randomizer randomizer = new Randomizer(segment.m_nameSeed);
            ushort     district   = (ushort)(DistrictManager.instance.GetDistrict(segment.m_middlePosition) & 0xFF);

            Xml.AdrDistrictConfig districtConfig = AdrController.CurrentConfig.GetConfigForDistrict(district);
            Xml.AdrDistrictConfig cityConfig     = AdrController.CurrentConfig.GetConfigForDistrict(0);

            if ((info.m_vehicleTypes & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None)
            {
                string filenamePrefix = districtConfig.RoadConfig?.QualifierFile ?? "";
                ;
                if ((filenamePrefix == null || !AdrController.LoadedLocalesRoadPrefix.ContainsKey(filenamePrefix)) && district > 0)
                {
                    filenamePrefix = cityConfig.RoadConfig?.QualifierFile;
                }

                if (filenamePrefix != null && AdrController.LoadedLocalesRoadPrefix.ContainsKey(filenamePrefix))
                {
                    LocaleStruct.RoadPrefixFileIndexer currentPrefixFile = AdrController.LoadedLocalesRoadPrefix[filenamePrefix];
                    format = currentPrefixFile.GetPrefix(ai, info.m_forwardVehicleLaneCount == 0 || info.m_backwardVehicleLaneCount == 0, info.m_forwardVehicleLaneCount == info.m_backwardVehicleLaneCount, info.m_halfWidth * 2, (byte)(info.m_forwardVehicleLaneCount + info.m_backwardVehicleLaneCount), randomizer, segmentID);
                }
                LogUtils.DoLog("selectedPrefix = {0}", format);
                if (format == null)
                {
                    string key         = DefaultPrefix(info, ai);
                    uint   rangeFormat = Locale.Count(key);
                    format = Locale.Get(key, randomizer.Int32(rangeFormat));
                }
            }

            if (format == null)
            {
                return(true);
            }

            if (removePrefix)
            {
                format = Regex.Replace(format, "(?!\\{)(\\w+|\\.)(?!\\})", "");
                if (format.IsNullOrWhiteSpace())
                {
                    return(true);
                }
            }

            string genName             = "";
            string sourceRoad          = "";
            string targetRoad          = "";
            string sourceKm            = "";
            string sourceKmWithDecimal = "";
            string sourceDistrict      = "";
            string targetDistrict      = "";
            string direction           = "";

            if (format.Contains("{0}"))
            {
                GetGeneratedRoadName(segment, ai, district, out genName);
                if (genName == null)
                {
                    return(true);
                }
            }
            ushort sourceSeg = 0;
            ushort targetSeg = 0;

            if (format.Contains("{1}") || format.Contains("{2}") || format.Contains("{3}") || format.Contains("{4}") || format.Contains("{7}"))
            {
                SegmentUtils.GetSegmentRoadEdges(segmentID, true, true, true, out ComparableRoad startRef, out ComparableRoad endRef, out _);

                sourceSeg = startRef.segmentReference;
                targetSeg = endRef.segmentReference;

                if (format.Contains("{1}"))
                {
                    if (!usedQueue.Contains(sourceSeg))
                    {
                        usedQueue.Add(sourceSeg);
                        GenerateSegmentNameInternal(sourceSeg, ref sourceRoad, ref usedQueue, false);
                    }
                }
                if (format.Contains("{2}"))
                {
                    if (!usedQueue.Contains(targetSeg))
                    {
                        usedQueue.Add(targetSeg);
                        GenerateSegmentNameInternal(targetSeg, ref targetRoad, ref usedQueue, false);
                    }
                }
                if (format.Contains("{3}") || format.Contains("{4}"))
                {
                    float km = GetNumberAt(startRef.segmentReference, NetManager.instance.m_segments.m_buffer[startRef.segmentReference].m_startNode == startRef.nodeReference) / 1000f;
                    sourceKm            = km.ToString("0");
                    sourceKmWithDecimal = km.ToString("0.0");
                }
                if (format.Contains("{7}"))//direction
                {
                    int cardinalDirection = SegmentUtils.GetCardinalDirection(startRef, endRef);

                    direction = Locale.Get("K45_CARDINAL_POINT_SHORT", cardinalDirection.ToString());
                }
            }
            if (format.Contains("{5}") || format.Contains("{6}"))
            {
                GetSegmentRoadEdges(segmentID, false, false, false, out ComparableRoad startRef, out ComparableRoad endRef, out _);
                if (format.Contains("{5}"))//source district
                {
                    sourceDistrict = GetDistrictAt(startRef);
                }
                if (format.Contains("{6}"))//target district
                {
                    targetDistrict = GetDistrictAt(endRef);
                }
            }
            if (AddressesMod.DebugMode)
            {
                __result = $"[{segmentID}] " + StringUtils.SafeFormat(format, genName, sourceSeg, targetSeg, sourceKm, sourceKmWithDecimal, sourceDistrict, targetDistrict, direction)?.Trim();
            }
            else
            {
                __result = StringUtils.SafeFormat(format, genName, sourceRoad, targetRoad, sourceKm, sourceKmWithDecimal, sourceDistrict, targetDistrict, direction)?.Trim();
            }
            LogUtils.DoLog($"[END {segmentID}]" + __result);
            return(false);
        }
Ejemplo n.º 17
0
        public string GetPrefix(PrefabAI ai, bool isOneWay, bool isSymmetric, float width, byte lanes, Randomizer rand, ushort segmentId, ushort seedId)
        {
            Highway  highway = Highway.ANY;
            RoadType type    = RoadType.NONE;

            if (ai is RoadBaseAI baseAi)
            {
                if (baseAi is DamAI)
                {
                    type = RoadType.DAM;
                }
                else if (baseAi is RoadBridgeAI)
                {
                    type = RoadType.BRIDGE;
                }
                else if (baseAi.IsUnderground())
                {
                    type = RoadType.TUNNEL;
                }
                else
                {
                    type = RoadType.GROUND;
                }
                highway = baseAi.m_highwayRules ? Highway.TRUE : Highway.FALSE;
            }
            if (type == RoadType.NONE)
            {
                LogUtils.DoLog($"AI NAO IDENTIFICADA: {ai}");
                return(null);
            }

            OneWay            wayVal            = isOneWay ? OneWay.TRUE : OneWay.FALSE;
            Symmetry          symVal            = isSymmetric ? Symmetry.TRUE : Symmetry.FALSE;
            LinkingType       linking           = LinkingType.NO_LINKING;
            SeedConfiguration seedConfiguration =
                (AdrNameSeedDataXml.Instance.NameSeedConfigs.TryGetValue(seedId, out AdrNameSeedConfig seedConf) && !(seedConf.HighwayParent is null) ? SeedConfiguration.HAS_HIGHWAY_TYPE : SeedConfiguration.NO_HIGHWAY_TYPE)
                | ((seedConf?.ForcedName).IsNullOrWhiteSpace()? SeedConfiguration.NO_FORCED_NAME : SeedConfiguration.HAS_FORCED_NAME);
            bool hasStart = true;
            bool hasEnd   = true;

            if (wayVal == OneWay.TRUE && lanes <= 2)
            {
                SegmentUtils.GetSegmentRoadEdges(segmentId, true, true, true, out ComparableRoad startRef, out ComparableRoad endRef, out _);
                LogUtils.DoLog($"OneWay s={startRef}; e= {endRef}");
                if (startRef.segmentReference == 0 || endRef.segmentReference == 0)
                {
                    hasStart = startRef.segmentReference != 0;
                    hasEnd   = endRef.segmentReference != 0;
                }
                else if ((NetManager.instance.m_segments.m_buffer[startRef.segmentReference].Info.GetAI() is RoadBaseAI baseAiSource && baseAiSource.m_highwayRules) ||
                         (NetManager.instance.m_segments.m_buffer[endRef.segmentReference].Info.GetAI() is RoadBaseAI baseAiTarget && baseAiTarget.m_highwayRules))

                {
                    switch (startRef.CompareTo(endRef))
                    {
                    case 1:
                        linking = LinkingType.FROM_BIG;
                        break;

                    case 0:
                        linking = LinkingType.SAME_SIZE;
                        break;

                    case -1:
                        linking = LinkingType.FROM_SMALL;
                        break;
                    }
                }
            }

            List <RoadPrefixFileItem> filterResult = m_prefixes.Where(x =>
                                                                      (x.roadType & type) == type &&
                                                                      (x.oneWay & wayVal) == wayVal &&
                                                                      (x.symmetry & symVal) == symVal &&
                                                                      (x.highway & highway) == highway &&
                                                                      (wayVal == OneWay.FALSE || ((x.linking & linking) == linking)) &&
                                                                      (hasStart || !x.requireSource) &&
                                                                      (hasEnd || !x.requireTarget) &&
                                                                      x.minWidth <= width + 0.99f &&
                                                                      width + 0.99f < x.maxWidth &&
                                                                      x.minLanes <= lanes &&
                                                                      lanes < x.maxLanes &&
                                                                      (x.seedConfig & seedConfiguration) == seedConfiguration
                                                                      ).ToList();

            if (filterResult.Count == 0 && linking != LinkingType.NO_LINKING)
            {
                filterResult = m_prefixes.Where(x =>
                                                (x.roadType & type) == type &&
                                                (x.oneWay & wayVal) == wayVal &&
                                                (x.symmetry & symVal) == symVal &&
                                                (x.highway & highway) == highway &&
                                                (wayVal == OneWay.FALSE || ((x.linking & LinkingType.NO_LINKING) == LinkingType.NO_LINKING)) &&
                                                (hasStart || !x.requireSource) &&
                                                (hasEnd || !x.requireTarget) &&
                                                x.minWidth <= width + 0.99f &&
                                                width + 0.99f < x.maxWidth &&
                                                x.minLanes <= lanes &&
                                                lanes < x.maxLanes &&
                                                (x.seedConfig & seedConfiguration) == seedConfiguration
                                                ).ToList();
            }
            LogUtils.DoLog($"Results for: {type} O:{wayVal} S:{symVal} H:{highway} W:{width} L:{lanes} Lk:{linking} Hs:{hasStart} He:{hasEnd} Sc:{seedConfiguration} = {filterResult?.Count}");
            if (filterResult?.Count == 0)
            {
                return(null);
            }

            return(filterResult[rand.Int32((uint)(filterResult.Count))].name);
        }