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