using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("TrafficChaos")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+affddc5fdc1786a94262c8cc0c742ef45067bf0d")] [assembly: AssemblyProduct("TrafficChaos")] [assembly: AssemblyTitle("TrafficChaos")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TrafficChaos { [BepInPlugin("sbg.trafficchaos", "TrafficChaos", "0.1.0")] public sealed class Plugin : BaseUnityPlugin { public const string ModGuid = "sbg.trafficchaos"; public const string ModName = "TrafficChaos"; public const string ModVersion = "0.1.0"; internal static ManualLogSource Log; internal static Plugin Instance; internal ConfigEntry enabledConfig; internal ConfigEntry speedMultiplierConfig; internal ConfigEntry spawnDelayMultiplierConfig; internal ConfigEntry travelDistanceMultiplierConfig; internal ConfigEntry honkCooldownMultiplierConfig; internal ConfigEntry knockbackMultiplierConfig; internal ConfigEntry forcedVehicleTypeConfig; internal ConfigEntry verboseLoggingConfig; private void Awake() { //IL_0132: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; enabledConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "Enabled", true, "Master toggle. When off, every knob below is ignored and traffic behaves exactly as vanilla."); speedMultiplierConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "SpeedMultiplier", 4f, "Multiplies TrafficSettings.VehicleSpeed. Spawn velocity is decided server-side and baked into synced state for clients, so this only takes effect for whoever is hosting."); spawnDelayMultiplierConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "SpawnDelayMultiplier", 0.3f, "Multiplies each TrafficSpawner lane's min/max delay between spawns. Lower = denser traffic. Host-only, same reason as SpeedMultiplier."); travelDistanceMultiplierConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "TravelDistanceMultiplier", 1.5f, "Multiplies each lane's travel distance before a vehicle fades out and returns to the pool, so vehicles stay on screen longer. Host-only."); honkCooldownMultiplierConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "HonkCooldownMultiplier", 0.25f, "Multiplies the cooldown between honks. Lower = more honking. Read locally by every client running the mod (host or not)."); knockbackMultiplierConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "KnockbackMultiplier", 1.6f, "Multiplies all four run-over knockback values (min/max horizontal, min/max vertical). The knockback is computed client-side for whoever got hit, so this applies to any client running the mod regardless of who hosts."); forcedVehicleTypeConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "ForcedVehicleType", ForcedVehicleType.Off, "Force every new spawn to be a single vehicle type instead of the normal weighted random mix. Host-only, same reason as SpeedMultiplier."); verboseLoggingConfig = ((BaseUnityPlugin)this).Config.Bind("Diagnostics", "VerboseLogging", false, "Log every multiplier application. Off by default."); new Harmony("sbg.trafficchaos").PatchAll(); Log.LogInfo((object)"TrafficChaos v0.1.0 loaded."); } internal static void LogVerbose(string message) { if ((Object)(object)Instance != (Object)null && Instance.verboseLoggingConfig.Value) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("TrafficChaos: " + message)); } } } } public enum ForcedVehicleType { Off, Car, Van, Taxi, Bus, PoliceCar } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class Patch_TrafficSettings_VehicleSpeed { private static void Postfix(ref int __result) { Plugin instance = Plugin.Instance; if (!((Object)(object)instance == (Object)null) && instance.enabledConfig.Value) { int num = Mathf.Max(1, Mathf.RoundToInt((float)__result * instance.speedMultiplierConfig.Value)); Plugin.LogVerbose($"VehicleSpeed {__result} -> {num}"); __result = num; } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class Patch_TrafficSettings_HonkCooldown { private static void Postfix(ref float __result) { Plugin instance = Plugin.Instance; if (!((Object)(object)instance == (Object)null) && instance.enabledConfig.Value) { __result = Mathf.Max(0.05f, __result * instance.honkCooldownMultiplierConfig.Value); } } } internal static class KnockbackHelper { public static void Apply(ref float value) { Plugin instance = Plugin.Instance; if (!((Object)(object)instance == (Object)null) && instance.enabledConfig.Value) { value = Mathf.Max(0f, value * instance.knockbackMultiplierConfig.Value); } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class Patch_TrafficSettings_MinHorizontalKnockback { private static void Postfix(ref float __result) { KnockbackHelper.Apply(ref __result); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class Patch_TrafficSettings_MaxHorizontalKnockback { private static void Postfix(ref float __result) { KnockbackHelper.Apply(ref __result); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class Patch_TrafficSettings_MinVerticalKnockback { private static void Postfix(ref float __result) { KnockbackHelper.Apply(ref __result); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class Patch_TrafficSettings_MaxVerticalKnockback { private static void Postfix(ref float __result) { KnockbackHelper.Apply(ref __result); } } [HarmonyPatch(typeof(TrafficSettings), "GetWeightedRandomVehicleType")] internal static class Patch_TrafficSettings_GetWeightedRandomVehicleType { private static void Postfix(ref TrafficVehicleType __result) { Plugin instance = Plugin.Instance; if (!((Object)(object)instance == (Object)null) && instance.enabledConfig.Value) { switch (instance.forcedVehicleTypeConfig.Value) { case ForcedVehicleType.Car: __result = (TrafficVehicleType)0; break; case ForcedVehicleType.Van: __result = (TrafficVehicleType)1; break; case ForcedVehicleType.Taxi: __result = (TrafficVehicleType)2; break; case ForcedVehicleType.Bus: __result = (TrafficVehicleType)3; break; case ForcedVehicleType.PoliceCar: __result = (TrafficVehicleType)4; break; case ForcedVehicleType.Off: break; } } } } [HarmonyPatch(typeof(TrafficSpawner), "OnStartServer")] internal static class Patch_TrafficSpawner_OnStartServer { private static void Prefix(TrafficSpawner __instance) { Plugin instance = Plugin.Instance; if (!((Object)(object)instance == (Object)null) && instance.enabledConfig.Value) { Traverse obj = Traverse.Create((object)__instance); Traverse val = obj.Field("minSpawnDelay"); Traverse val2 = obj.Field("maxSpawnDelay"); Traverse obj2 = obj.Field("travelDistance"); float num = Mathf.Max(0.05f, instance.spawnDelayMultiplierConfig.Value); float num2 = Mathf.Max(0.1f, instance.travelDistanceMultiplierConfig.Value); float value = val.GetValue(); float value2 = val2.GetValue(); float value3 = obj2.GetValue(); float num3 = Mathf.Max(0.1f, value * num); float num4 = Mathf.Max(num3 + 0.1f, value2 * num); float num5 = value3 * num2; val.SetValue((object)num3); val2.SetValue((object)num4); obj2.SetValue((object)num5); Plugin.LogVerbose($"TrafficSpawner '{((Object)__instance).name}': spawnDelay [{value:F2},{value2:F2}] -> " + $"[{num3:F2},{num4:F2}], travelDistance {value3:F1} -> {num5:F1}"); } } } }