public void Display(object data, bool isRowOdd) { if (data != null) { vehicleInfoIndex = (uint)(data); vehicleInfo = PrefabCollection <VehicleInfo> .GetPrefab(vehicleInfoIndex); vehicleName = PrefabCollection <VehicleInfo> .PrefabName(vehicleInfoIndex); if (vehicleInfo != null && background != null) { Match m = workshopRegex.Match(vehicleName); if (m.Success) { label.text = m.Groups[1].ToString().Replace("_", " "); } else { label.text = vehicleName; } if (isRowOdd) { background.backgroundSprite = "UnlockingItemBackground"; background.color = new Color32(0, 0, 0, 128); } else { background.backgroundSprite = null; } } } }
private bool IsMatch(uint index, BuildingAI bld) { switch (Matcher) { case MatchPatternKind.Category: Type t = bld.GetType(); while (true) { if (string.CompareOrdinal(Pattern, t.FullName) == 0) { return(true); } if (string.CompareOrdinal(t.FullName, typeof(BuildingAI).FullName) == 0) { return(false); } t = t.BaseType; } case MatchPatternKind.Name: return(string.CompareOrdinal(Pattern, PrefabCollection <BuildingInfo> .PrefabName(index)) == 0); case MatchPatternKind.Regex: return(Regex.IsMatch(PrefabCollection <BuildingInfo> .PrefabName(index), Pattern)); } return(false); }
/// <summary> /// NetInfos require more effort because the NotUsedGuide/UnlockMilestone stuff gets into way. /// </summary> void LookupSimulationNets(HashSet <string> packages, HashSet <string> assets) { try { NetNode[] buffer1 = NetManager.instance.m_nodes.m_buffer; int n = buffer1.Length; for (int i = 1; i < n; i++) { if (buffer1[i].m_flags != NetNode.Flags.None) { Add(PrefabCollection <NetInfo> .PrefabName(buffer1[i].m_infoIndex), packages, assets); } } NetSegment[] buffer2 = NetManager.instance.m_segments.m_buffer; n = buffer2.Length; for (int i = 1; i < n; i++) { if (buffer2[i].m_flags != NetSegment.Flags.None) { Add(PrefabCollection <NetInfo> .PrefabName(buffer2[i].m_infoIndex), packages, assets); } } } catch (Exception e) { UnityEngine.Debug.LogException(e); } }
/// <summary> /// Looks up the building prefabs used in the simulation. /// </summary> internal void LookupSimulationPrefabs() { if (simulationPrefabs == null) { simulationPrefabs = new HashSet <string>(); try { Building[] buffer = BuildingManager.instance.m_buildings.m_buffer; int n = buffer.Length; for (int i = 1; i < n; i++) { if (buffer[i].m_flags != Building.Flags.None) { string fullName = PrefabCollection <BuildingInfo> .PrefabName(buffer[i].m_infoIndex); // Recognize prefabs. if (!string.IsNullOrEmpty(fullName) && fullName.IndexOf('.') < 0) { simulationPrefabs.Add(fullName); } } } } catch (Exception e) { UnityEngine.Debug.LogException(e); } } }
/// <summary> /// Looks up the custom assets placed in the city. /// </summary> void LookupSimulationAssets <P>(HashSet <string> packages, HashSet <string> assets) where P : PrefabInfo { try { int n = PrefabCollection <P> .PrefabCount(); for (int i = 0; i < n; i++) { Add(PrefabCollection <P> .PrefabName((uint)i), packages, assets); } } catch (Exception e) { UnityEngine.Debug.LogException(e); } }
public override string GenerateName(ushort buildingID, InstanceID caller) { if (this.m_info.m_prefabDataIndex == -1) { return(null); } Randomizer randomizer = new Randomizer((int)buildingID); string key = PrefabCollection <BuildingInfo> .PrefabName((uint)this.m_info.m_prefabDataIndex); uint num = Locale.CountUnchecked("BUILDING_NAME", key); if (num != 0u) { return(Locale.Get("BUILDING_NAME", key, randomizer.Int32(num))); } return(BuildingNameGenerator.GenerateName(this.m_info.m_class.m_subService, randomizer)); }
/// <summary> /// BuildingInfos require more effort because the NotUsedGuide/UnlockMilestone stuff gets into way. /// </summary> void LookupSimulationBuildings(HashSet <string> packages, HashSet <string> assets) { try { Building[] buffer = BuildingManager.instance.m_buildings.m_buffer; int n = buffer.Length; for (int i = 1; i < n; i++) { if (buffer[i].m_flags != Building.Flags.None) { Add(PrefabCollection <BuildingInfo> .PrefabName(buffer[i].m_infoIndex), packages, assets); } } } catch (Exception e) { UnityEngine.Debug.LogException(e); } }
public void RefreshList() { String prefabName; vehicleList.rowsData.Clear(); for (uint i = 0; i < PrefabCollection <VehicleInfo> .PrefabCount(); i++) { //Filter out trailers for now( who'd want to drive a trailer???, and we have to match the workshop id anyways ) prefabName = PrefabCollection <VehicleInfo> .PrefabName(i); if (prefabName != null) { Match m = trailerRegex.Match(prefabName); if (!m.Success) { vehicleList.rowsData.Add(i); } } } vehicleList.DisplayAt(0); vehicleList.selectedIndex = 0; }
private void DumpPrefabsData() { SortedDictionary <string, string> prefabs = new SortedDictionary <string, string>(); int count = PrefabCollection <BuildingInfo> .PrefabCount(); for (uint i = 0; i < count; ++i) { BuildingInfo bi = PrefabCollection <BuildingInfo> .GetPrefab(i); if (bi.m_buildingAI != null) { Type type = bi.m_buildingAI.GetType(); string category = type.FullName; string name = PrefabCollection <BuildingInfo> .PrefabName(i); foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Instance)) { if ( fi.FieldType.FullName == typeof(bool).FullName || fi.FieldType.FullName == typeof(int).FullName || fi.FieldType.FullName == typeof(float).FullName) { prefabs.Add($"{category};{name};{fi.Name}", $"{fi.GetValue(bi.m_buildingAI)}"); } } } } using (StreamWriter sw = new StreamWriter(ConfigLoader.ConfigPath + "/prefabs.csv", false, Encoding.UTF8)) { foreach (KeyValuePair <string, string> kvp in prefabs) { sw.WriteLine($"{kvp.Key};{kvp.Value}"); } } }
public override void SimulationStep(ushort disasterID, ref DisasterData data) { //Begin Disaster AI SimulationStep if ((data.m_flags & DisasterData.Flags.Clearing) != DisasterData.Flags.None) { if (!this.IsStillClearing(disasterID, ref data)) { this.EndDisaster(disasterID, ref data); } } else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None) { if (!this.IsStillActive(disasterID, ref data)) { this.DeactivateDisaster(disasterID, ref data); } } else if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None) { if (!this.IsStillEmerging(disasterID, ref data)) { this.ActivateDisaster(disasterID, ref data); } } if ((data.m_flags & DisasterData.Flags.Detected) != DisasterData.Flags.None) { if ((data.m_flags & DisasterData.Flags.Warning) != DisasterData.Flags.None) { if (data.m_broadcastCooldown > 0) { data.m_broadcastCooldown -= 1; } if (data.m_broadcastCooldown == 0) { data.m_broadcastCooldown = 36; if (this.m_info.m_warningBroadcast != null) { Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_warningBroadcast); } } } else { StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DisasterCount); statisticBase.Add(16); InstanceID id = default(InstanceID); id.Disaster = disasterID; InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id); if (data.m_broadcastCooldown >= 200) { if (data.m_broadcastCooldown > 200) { data.m_broadcastCooldown -= 1; } if (data.m_broadcastCooldown == 200 && (group == null || group.m_refCount >= 2)) { data.m_broadcastCooldown = 236; if (this.m_info.m_activeBroadcast != null) { Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast); } } } else { if (data.m_broadcastCooldown > 0) { data.m_broadcastCooldown -= 1; } if (data.m_broadcastCooldown == 0) { data.m_broadcastCooldown = 236; if (this.m_info.m_activeBroadcast != null) { Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast); } } } if (group == null || group.m_refCount >= 2) { if (data.m_chirpCooldown > 0) { data.m_chirpCooldown -= 1; } else if (this.m_info.m_prefabDataIndex != -1) { string key = PrefabCollection <DisasterInfo> .PrefabName((uint)this.m_info.m_prefabDataIndex); if (Locale.Exists("CHIRP_DISASTER", key)) { string disasterName = Singleton <DisasterManager> .instance.GetDisasterName(disasterID); Singleton <MessageManager> .instance.TryCreateMessage("CHIRP_DISASTER", key, Singleton <MessageManager> .instance.GetRandomResidentID(), disasterName); data.m_chirpCooldown = (byte)Singleton <SimulationManager> .instance.m_randomizer.Int32(8, 24); } } } } GuideController properties = Singleton <GuideManager> .instance.m_properties; if (this.m_info.m_disasterWarningGuide != null && properties != null) { this.m_info.m_disasterWarningGuide.Activate(properties.m_disasterWarning, this.m_info); } } if ((data.m_flags & DisasterData.Flags.Repeat) != DisasterData.Flags.None && ((data.m_flags & (DisasterData.Flags.Finished | DisasterData.Flags.UnReported)) == DisasterData.Flags.Finished || (data.m_flags & (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)) == (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected))) { this.StartDisaster(disasterID, ref data); } //End DisasterAI.Simulation Step if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None) { uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex; if (currentFrameIndex + 1755u > data.m_activationFrame) { Singleton <DisasterManager> .instance.DetectDisaster(disasterID, false); Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f; Singleton <WeatherManager> .instance.m_targetFog = 0f; //Begin Edit float newTornadoTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f); Singleton <WeatherManager> .instance.m_targetRain = newTornadoTargetRain; Debug.Log("[RF]TornadoAIDetour Limtied Tornado Rain to " + Singleton <WeatherManager> .instance.m_targetRain); //End Edit Singleton <WeatherManager> .instance.m_targetCloud = 1f; } } else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None) { Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f; Singleton <WeatherManager> .instance.m_targetFog = 0f; //Begin Edit float newTornadoTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f); Singleton <WeatherManager> .instance.m_targetRain = newTornadoTargetRain; Debug.Log("[RF]TornadoAIDetour Limtied Tornado Rain to " + Singleton <WeatherManager> .instance.m_targetRain); //End Edit Singleton <WeatherManager> .instance.m_targetCloud = 1f; } }
public static string GetCustomVehiclesText(ushort building) { if (building == 0) { return(string.Empty); } if (!VehicleManagerMod.BuildingUseDefaultVehicles[building] && VehicleManagerMod.BuildingToVehicles[building] != null) { var txtItems = new List <string>(); txtItems.Add($"<<Custom Vehicles>>"); foreach (var prefabIndex in VehicleManagerMod.BuildingToVehicles[building]) { var name = ColossalFramework.Globalization.Locale.Get("VEHICLE_TITLE", PrefabCollection <VehicleInfo> .PrefabName((uint)prefabIndex)); txtItems.Add(name); } return(string.Join("\n", txtItems.ToArray())); } else { return(string.Empty); } }
public void Apply(uint index, BuildingAI bld) { if (IsMatch(index, bld)) { string name = PrefabCollection <BuildingInfo> .PrefabName(index); FieldInfo fld = bld.GetType().GetField(Field, BindingFlags.Public | BindingFlags.Instance); if (fld == null) { DebugOutputPanel.AddMessage(PluginManager.MessageType.Error, $"{name} doesn't have a '{Field}' field!"); return; } object oldValue = null; object newValue = null; switch (Operator) { case ValueOperation.Add: oldValue = fld.GetValue(bld); if (typeof(int).FullName == fld.FieldType.FullName) { newValue = (int)oldValue + int.Parse(Value); } else if (typeof(float).FullName == fld.FieldType.FullName) { newValue = (float)oldValue + float.Parse(Value); } else { throw new Exception($"Operation 'Add' not supported on field type: {fld.FieldType.FullName}"); } break; case ValueOperation.Mul: oldValue = fld.GetValue(bld); if (typeof(int).FullName == fld.FieldType.FullName) { newValue = (int)((int)oldValue * float.Parse(Value)); } else if (typeof(float).FullName == fld.FieldType.FullName) { newValue = (int)((float)oldValue * float.Parse(Value)); } else { throw new Exception($"Operation 'Mul' not supported on field type: {fld.FieldType.FullName}"); } break; case ValueOperation.Set: if (typeof(int).FullName == fld.FieldType.FullName) { newValue = int.Parse(Value); } else if (typeof(float).FullName == fld.FieldType.FullName) { newValue = float.Parse(Value); } else if (typeof(bool).FullName == fld.FieldType.FullName) { newValue = bool.Parse(Value); } else { throw new Exception($"Operation 'Set' not supported on field type: {fld.FieldType.FullName}"); } break; default: throw new Exception("Unkown operation!"); } fld.SetValue(bld, newValue); } }
/// <summary> /// Debugging function to dump treeinfo prefab data. /// </summary> /// <param name="idbyte">Debug Marker id of where in the code it's executing</param> internal static void DumpLoadedPrefabInfos(byte idbyte = 0) { int RealCount = PrefabCollection <TreeInfo> .PrefabCount(); //real? ie simulation_prefab size int LoadedCount = PrefabCollection <TreeInfo> .LoadedCount(); //attempted? scene_prefab size string tmpstr = string.Concat("Dumping Tree prefab information (" + idbyte.ToString() + ") ", "RealCount: " + RealCount.ToString(), " LoadedCount: " + LoadedCount.ToString()); Logger.dbgLog(tmpstr); if (RealCount > 0) { Logger.dbgLog("Simulation_prefabs:"); try { string ti_null = "nullobj"; string[] tmparray = new string[6] { ti_null, ti_null, ti_null, ti_null, ti_null, ti_null }; for (uint i = 0; i < RealCount; i++) { tmparray[0] = i.ToString(); tmparray[1] = PrefabCollection <TreeInfo> .PrefabName(i); TreeInfo ti = PrefabCollection <TreeInfo> .GetPrefab(i); tmparray[2] = ti_null.ToString(); tmparray[3] = ti_null.ToString(); tmparray[4] = ti_null.ToString(); tmparray[5] = ti_null.ToString(); if (ti != null) { tmparray[2] = ti.m_prefabDataIndex.ToString(); tmparray[3] = ti.m_prefabInitialized.ToString(); tmparray[4] = ti.name.ToString(); tmparray[5] = ti.m_dlcRequired.ToString(); } Logger.dbgLog(String.Format("CoreIdx:{0} PrefabName:{1} DataIdx:{2} Init:{3} gamename:{4} dlcneeded:{5} ", tmparray), null, false, true); tmparray[0] = ti_null; tmparray[1] = ti_null; tmparray[2] = ti_null; tmparray[3] = ti_null; tmparray[4] = ti_null; tmparray[5] = ti_null; } } catch (Exception ex) { Logger.dbgLog("simulationprefabs ", ex); } } if (LoadedCount > 0) { Logger.dbgLog("Loaded_scene_prefabs:"); try { string ti_null2 = "nullobj"; string[] tmparray2 = new string[6] { ti_null2, ti_null2, ti_null2, ti_null2, ti_null2, ti_null2 }; for (uint i = 0; i < LoadedCount; i++) { tmparray2[0] = i.ToString(); tmparray2[1] = PrefabCollection <TreeInfo> .PrefabName(i); TreeInfo ti = PrefabCollection <TreeInfo> .GetLoaded(i); tmparray2[2] = ti_null2.ToString(); tmparray2[3] = ti_null2.ToString(); tmparray2[4] = ti_null2.ToString(); tmparray2[5] = ti_null2.ToString(); if (ti != null) { tmparray2[2] = ti.m_prefabDataIndex.ToString(); tmparray2[3] = ti.m_prefabInitialized.ToString(); tmparray2[4] = ti.name.ToString(); tmparray2[5] = ti.m_dlcRequired.ToString(); } Logger.dbgLog(String.Format("CoreIdx:{0} PrefabName:{1} DataIdx:{2} Init:{3} gamename:{4} dlcneeded:{5}", tmparray2), null, false, true); tmparray2[0] = ti_null2; tmparray2[1] = ti_null2; tmparray2[2] = ti_null2; tmparray2[3] = ti_null2; tmparray2[4] = ti_null2; tmparray2[5] = ti_null2; } } catch (Exception ex) { Logger.dbgLog("loaded_scene_prefabs", ex); } } }
public override void SimulationStep(ushort disasterID, ref DisasterData data) { //Begin Disaster AI SimulationStep if ((data.m_flags & DisasterData.Flags.Clearing) != DisasterData.Flags.None) { if (!this.IsStillClearing(disasterID, ref data)) { this.EndDisaster(disasterID, ref data); } } else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None) { if (!this.IsStillActive(disasterID, ref data)) { this.DeactivateDisaster(disasterID, ref data); } } else if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None) { if (!this.IsStillEmerging(disasterID, ref data)) { this.ActivateDisaster(disasterID, ref data); } } if ((data.m_flags & DisasterData.Flags.Detected) != DisasterData.Flags.None) { if ((data.m_flags & DisasterData.Flags.Warning) != DisasterData.Flags.None) { if (data.m_broadcastCooldown > 0) { data.m_broadcastCooldown -= 1; } if (data.m_broadcastCooldown == 0) { data.m_broadcastCooldown = 36; if (this.m_info.m_warningBroadcast != null) { Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_warningBroadcast); } } } else { StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DisasterCount); statisticBase.Add(16); InstanceID id = default(InstanceID); id.Disaster = disasterID; InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id); if (data.m_broadcastCooldown >= 200) { if (data.m_broadcastCooldown > 200) { data.m_broadcastCooldown -= 1; } if (data.m_broadcastCooldown == 200 && (group == null || group.m_refCount >= 2)) { data.m_broadcastCooldown = 236; if (this.m_info.m_activeBroadcast != null) { Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast); } } } else { if (data.m_broadcastCooldown > 0) { data.m_broadcastCooldown -= 1; } if (data.m_broadcastCooldown == 0) { data.m_broadcastCooldown = 236; if (this.m_info.m_activeBroadcast != null) { Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast); } } } if (group == null || group.m_refCount >= 2) { if (data.m_chirpCooldown > 0) { data.m_chirpCooldown -= 1; } else if (this.m_info.m_prefabDataIndex != -1) { string key = PrefabCollection <DisasterInfo> .PrefabName((uint)this.m_info.m_prefabDataIndex); if (Locale.Exists("CHIRP_DISASTER", key)) { string disasterName = Singleton <DisasterManager> .instance.GetDisasterName(disasterID); Singleton <MessageManager> .instance.TryCreateMessage("CHIRP_DISASTER", key, Singleton <MessageManager> .instance.GetRandomResidentID(), disasterName); data.m_chirpCooldown = (byte)Singleton <SimulationManager> .instance.m_randomizer.Int32(8, 24); } } } } GuideController properties = Singleton <GuideManager> .instance.m_properties; if (this.m_info.m_disasterWarningGuide != null && properties != null) { this.m_info.m_disasterWarningGuide.Activate(properties.m_disasterWarning, this.m_info); } } if ((data.m_flags & DisasterData.Flags.Repeat) != DisasterData.Flags.None && ((data.m_flags & (DisasterData.Flags.Finished | DisasterData.Flags.UnReported)) == DisasterData.Flags.Finished || (data.m_flags & (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)) == (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected))) { this.StartDisaster(disasterID, ref data); } //End DisasterAI.Simulation Step if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None) { if (data.m_activationFrame != 0u) { uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex; if (currentFrameIndex + 1755u >= data.m_activationFrame) { if ((data.m_flags & DisasterData.Flags.Significant) != DisasterData.Flags.None) { Singleton <DisasterManager> .instance.DetectDisaster(disasterID, false); } if ((data.m_flags & DisasterData.Flags.SelfTrigger) != DisasterData.Flags.None) { Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f; Singleton <WeatherManager> .instance.m_targetFog = 0f; //Begin Edit float newThunderstormTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f); Singleton <WeatherManager> .instance.m_targetRain = newThunderstormTargetRain; Debug.Log("[RF]ThunderStormAIDetour Limtied Thunderstorm Rain to " + Singleton <WeatherManager> .instance.m_targetRain); Singleton <WeatherManager> .instance.m_targetCloud = newThunderstormTargetRain; //end edit } } } } else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None && (data.m_flags & DisasterData.Flags.SelfTrigger) != DisasterData.Flags.None) { Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f; Singleton <WeatherManager> .instance.m_targetFog = 0f; //Begin Edit float newThunderstormTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f); Singleton <WeatherManager> .instance.m_targetRain = newThunderstormTargetRain; Debug.Log("[RF]ThunderStormAIDetour Limtied Thunderstorm Rain to " + Singleton <WeatherManager> .instance.m_targetRain); Singleton <WeatherManager> .instance.m_targetCloud = newThunderstormTargetRain; //end edit uint currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex; int num = 100; num = Mathf.Min(num, (int)(currentFrameIndex2 - data.m_activationFrame >> 3)); num = Mathf.Min(num, (int)(data.m_activationFrame + this.m_activeDuration - currentFrameIndex2 >> 3)); num = (num * (int)data.m_intensity + 50) / 100; Randomizer randomizer = new Randomizer(data.m_randomSeed ^ (ulong)(currentFrameIndex2 >> 8)); int num2 = randomizer.Int32(Mathf.Max(1, num / 20), Mathf.Max(1, 1 + num / 10)); float num3 = this.m_radius * (0.25f + (float)data.m_intensity * 0.0075f); InstanceID id = default(InstanceID); id.Disaster = disasterID; InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id); for (int i = 0; i < num2; i++) { float f = (float)randomizer.Int32(10000u) * 0.0006283185f; float num4 = Mathf.Sqrt((float)randomizer.Int32(10000u) * 0.0001f) * num3; uint startFrame = currentFrameIndex2 + randomizer.UInt32(256u); Vector3 targetPosition = data.m_targetPosition; targetPosition.x += Mathf.Cos(f) * num4; targetPosition.z += Mathf.Sin(f) * num4; targetPosition.y = Singleton <TerrainManager> .instance.SampleRawHeightSmoothWithWater(targetPosition, false, 0f); Quaternion quaternion = Quaternion.AngleAxis((float)randomizer.Int32(360u), Vector3.up); quaternion *= Quaternion.AngleAxis((float)randomizer.Int32(-15, 15), Vector3.right); Singleton <WeatherManager> .instance.QueueLightningStrike(startFrame, targetPosition, quaternion, group); } } }
private string IDToName(ushort ID) { return(ColossalFramework.Globalization.Locale.Get("VEHICLE_TITLE", PrefabCollection <VehicleInfo> .PrefabName((uint)ID)) ?? ""); }