using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.Mono; using Effects; using Game; using Game.GameMode; using Game.UnlockableContent; using HarmonyLib; using Menus; using Menus.UI; using Microsoft.CodeAnalysis; using Obstacles; using Obstacles.ObstacleAffixes; using Obstacles.ObstacleGameModifiers; using Player; using SlipSkid.MoreCards.Cards; using SlipSkid.MoreCards.Runtime; using SlipSkid.MoreCards.Util; using UI; using UI.NotificationSystem; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using Utils; using Utils.Colors; [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("SlipSkid.MoreCards")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1+630028d86b9d3da140b17829af15fd81ebd52620")] [assembly: AssemblyProduct("SlipSkid.MoreCards")] [assembly: AssemblyTitle("SlipSkid.MoreCards")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.1.0")] [module: UnverifiableCode] [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 SlipSkid.MoreCards { internal static class GameLogForwarder { private static ManualLogSource _gameLog; private static Harmony _harmony; private static bool _installed; [ThreadStatic] private static bool _reentrant; public static void Install() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown if (!_installed) { _installed = true; _gameLog = Logger.CreateLogSource("Game"); _harmony = new Harmony("slipskid.morecards.logforwarder"); Type? typeFromHandle = typeof(GameLogForwarder); HarmonyMethod postfix = new HarmonyMethod(typeFromHandle.GetMethod("OnInfo", BindingFlags.Static | BindingFlags.NonPublic)); HarmonyMethod postfix2 = new HarmonyMethod(typeFromHandle.GetMethod("OnWarning", BindingFlags.Static | BindingFlags.NonPublic)); HarmonyMethod postfix3 = new HarmonyMethod(typeFromHandle.GetMethod("OnError", BindingFlags.Static | BindingFlags.NonPublic)); HarmonyMethod postfix4 = new HarmonyMethod(typeFromHandle.GetMethod("OnException", BindingFlags.Static | BindingFlags.NonPublic)); TryPatch("Log", new Type[1] { typeof(object) }, postfix); TryPatch("Log", new Type[2] { typeof(object), typeof(Object) }, postfix); TryPatch("LogWarning", new Type[1] { typeof(object) }, postfix2); TryPatch("LogWarning", new Type[2] { typeof(object), typeof(Object) }, postfix2); TryPatch("LogError", new Type[1] { typeof(object) }, postfix3); TryPatch("LogError", new Type[2] { typeof(object), typeof(Object) }, postfix3); TryPatch("LogException", new Type[1] { typeof(Exception) }, postfix4); Plugin.Log.LogInfo((object)"Game log forwarding installed."); } } public static void Uninstall() { if (_installed) { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _installed = false; } } private static void TryPatch(string name, Type[] args, HarmonyMethod postfix) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(Debug), name, args, (Type[])null); bool flag = default(bool); if (methodInfo == null) { ManualLogSource log = Plugin.Log; BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(31, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Debug."); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(string.Join(", ", Array.ConvertAll(args, (Type a) => a.Name))); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") not present; skipping."); } log.LogDebug(val); return; } try { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, postfix, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(26, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Could not forward Debug."); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log2.LogWarning(val2); } } private static void Write(LogLevel level, object message) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (_reentrant) { return; } _reentrant = true; try { _gameLog.Log(level, message ?? "null"); } catch { } finally { _reentrant = false; } } private static void OnInfo(object message) { Write((LogLevel)16, message); } private static void OnWarning(object message) { Write((LogLevel)4, message); } private static void OnError(object message) { Write((LogLevel)2, message); } private static void OnException(Exception exception) { Write((LogLevel)2, exception); } } internal static class ModConfig { public static ConfigEntry Enabled; public static ConfigEntry ForwardGameLogs; public static ConfigEntry Verbose; public static ConfigEntry ShowStateChanges; public static ConfigEntry DebugKey; public static ConfigEntry ReloadConfigKey; public static ConfigEntry OverrideCarStats; public static ConfigEntry MaxSpeedMultiplier; public static ConfigEntry ExtraJumps; public static ConfigEntry EnableCustomCards; public static ConfigEntry SpeedCardBoostPercent; public static ConfigEntry SizeCardGrowthPercent; public static ConfigEntry CarCardScale; public static ConfigEntry CarCardLength; public static ConfigEntry TreeScale; public static ConfigEntry TreeHeight; public static ConfigEntry SwatterScale; public static ConfigEntry SwatterWidth; public static ConfigEntry SwatterReach; public static ConfigEntry PropCarrierName; public static ConfigEntry ForceCustomCardInDraft; public static ConfigEntry GunFireInterval; public static ConfigEntry GunFiresOnlyWhileRacing; public static ConfigEntry GunLength; public static ConfigEntry GunOffsetRight; public static ConfigEntry GunOffsetUp; public static ConfigEntry GunOffsetForward; public static ConfigEntry GunYaw; public static ConfigEntry GunPitch; public static ConfigEntry GunRoll; public static ConfigEntry BulletLength; public static ConfigEntry BulletSpeed; public static ConfigEntry BulletLifetime; public static ConfigEntry BulletsKill; public static ConfigEntry BulletSlowPercent; public static ConfigEntry BulletSlowSeconds; public static ConfigEntry BulletHopSpeed; public static ConfigEntry BulletHitPadding; public static ConfigEntry BoinkSlowPercent; public static ConfigEntry BoinkSlowSeconds; public static ConfigEntry BoinkBounceDepth; public static ConfigEntry BoinkBounceSeconds; public static ConfigEntry BoinkMinHeight; public static ConfigEntry BoinkCooldownSeconds; public static ConfigEntry RingSize; public static ConfigEntry RingHeight; public static ConfigEntry RingYaw; public static ConfigEntry BouncePush; public static ConfigEntry BounceLift; public static ConfigEntry BounceRecoil; public static ConfigEntry BounceCooldownSeconds; public static ConfigEntry BounceOnlyWhileRacing; public static ConfigEntry RingWobbleSeconds; public static ConfigEntry RingWobbleDepth; public static ConfigEntry GravityReductionPercent; public static ConfigEntry SwoopSeconds; public static ConfigEntry LiftSeconds; public static ConfigEntry RestSeconds; public static ConfigEntry SwatPush; public static ConfigEntry SwatLift; public static ConfigEntry SwatCooldownSeconds; public static ConfigEntry SwatOnlyWhileRacing; public static ConfigEntry BollardScale; public static ConfigEntry BollardHeight; public static ConfigEntry DownSeconds; public static ConfigEntry UpSeconds; public static ConfigEntry RiseSeconds; public static void Bind(ConfigFile cfg) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Expected O, but got Unknown //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Expected O, but got Unknown //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Expected O, but got Unknown //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Expected O, but got Unknown //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Expected O, but got Unknown //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Expected O, but got Unknown //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Expected O, but got Unknown //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Expected O, but got Unknown //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Expected O, but got Unknown //IL_049b: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Expected O, but got Unknown //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Expected O, but got Unknown //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_0515: Expected O, but got Unknown //IL_0543: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Expected O, but got Unknown //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_0585: Expected O, but got Unknown //IL_05b3: Unknown result type (might be due to invalid IL or missing references) //IL_05bd: Expected O, but got Unknown //IL_05eb: Unknown result type (might be due to invalid IL or missing references) //IL_05f5: Expected O, but got Unknown //IL_063e: Unknown result type (might be due to invalid IL or missing references) //IL_0648: Expected O, but got Unknown //IL_0676: Unknown result type (might be due to invalid IL or missing references) //IL_0680: Expected O, but got Unknown //IL_06ae: Unknown result type (might be due to invalid IL or missing references) //IL_06b8: Expected O, but got Unknown //IL_06e6: Unknown result type (might be due to invalid IL or missing references) //IL_06f0: Expected O, but got Unknown //IL_071e: Unknown result type (might be due to invalid IL or missing references) //IL_0728: Expected O, but got Unknown //IL_0756: Unknown result type (might be due to invalid IL or missing references) //IL_0760: Expected O, but got Unknown //IL_078e: Unknown result type (might be due to invalid IL or missing references) //IL_0798: Expected O, but got Unknown //IL_07c6: Unknown result type (might be due to invalid IL or missing references) //IL_07d0: Expected O, but got Unknown //IL_07fe: Unknown result type (might be due to invalid IL or missing references) //IL_0808: Expected O, but got Unknown //IL_0836: Unknown result type (might be due to invalid IL or missing references) //IL_0840: Expected O, but got Unknown //IL_086e: Unknown result type (might be due to invalid IL or missing references) //IL_0878: Expected O, but got Unknown //IL_08a6: Unknown result type (might be due to invalid IL or missing references) //IL_08b0: Expected O, but got Unknown //IL_08de: Unknown result type (might be due to invalid IL or missing references) //IL_08e8: Expected O, but got Unknown //IL_0916: Unknown result type (might be due to invalid IL or missing references) //IL_0920: Expected O, but got Unknown //IL_094e: Unknown result type (might be due to invalid IL or missing references) //IL_0958: Expected O, but got Unknown //IL_0986: Unknown result type (might be due to invalid IL or missing references) //IL_0990: Expected O, but got Unknown //IL_09be: Unknown result type (might be due to invalid IL or missing references) //IL_09c8: Expected O, but got Unknown //IL_0a11: Unknown result type (might be due to invalid IL or missing references) //IL_0a1b: Expected O, but got Unknown //IL_0a49: Unknown result type (might be due to invalid IL or missing references) //IL_0a53: Expected O, but got Unknown //IL_0a81: Unknown result type (might be due to invalid IL or missing references) //IL_0a8b: Expected O, but got Unknown //IL_0ab9: Unknown result type (might be due to invalid IL or missing references) //IL_0ac3: Expected O, but got Unknown //IL_0af1: Unknown result type (might be due to invalid IL or missing references) //IL_0afb: Expected O, but got Unknown //IL_0b29: Unknown result type (might be due to invalid IL or missing references) //IL_0b33: Expected O, but got Unknown //IL_0b61: Unknown result type (might be due to invalid IL or missing references) //IL_0b6b: Expected O, but got Unknown //IL_0b99: Unknown result type (might be due to invalid IL or missing references) //IL_0ba3: Expected O, but got Unknown //IL_0bd1: Unknown result type (might be due to invalid IL or missing references) //IL_0bdb: Expected O, but got Unknown //IL_0c24: Unknown result type (might be due to invalid IL or missing references) //IL_0c2e: Expected O, but got Unknown //IL_0c5c: Unknown result type (might be due to invalid IL or missing references) //IL_0c66: Expected O, but got Unknown //IL_0c94: Unknown result type (might be due to invalid IL or missing references) //IL_0c9e: Expected O, but got Unknown //IL_0ccc: Unknown result type (might be due to invalid IL or missing references) //IL_0cd6: Expected O, but got Unknown //IL_0d04: Unknown result type (might be due to invalid IL or missing references) //IL_0d0e: Expected O, but got Unknown Enabled = cfg.Bind("General", "Enabled", true, "Turn the whole mod off without uninstalling it. Takes effect on restart."); ForwardGameLogs = cfg.Bind("Debug", "ForwardGameLogs", false, "Mirror the game's own Debug.Log output into the BepInEx log. This build is stripped, so BepInEx cannot capture it by itself. Leave off unless you are debugging — it is chatty. Turn it off if you also run the Custom Map Loader, which already forwards logs."); Verbose = cfg.Bind("Debug", "Verbose", false, "Log every hook as it fires. Useful when a patch silently is not running."); ShowStateChanges = cfg.Bind("Debug", "ShowStateChanges", false, "Log each race phase transition (Racing, ScoreBoard, SelectingObstacles, and so on)."); DebugKey = cfg.Bind("Debug", "DebugKey", (Key)101, "Prints a snapshot of game state to the log. Safe to press at any time."); ReloadConfigKey = cfg.Bind("Debug", "ReloadConfigKey", (Key)102, "Re-reads this file from disk, so you can tune values — CarCardScale in particular — with the game still running. Settings marked as taking effect on restart still do; the rest apply the next time they are read, which for the \"Wreck\" card means the next one placed."); OverrideCarStats = cfg.Bind("Car", "OverrideCarStats", false, "Re-applies the multipliers below on top of the host's rules every time the car reads them. Single player and private lobbies only: your car will not match what other players see, because each client simulates its own physics."); MaxSpeedMultiplier = cfg.Bind("Car", "MaxSpeedMultiplier", 1f, new ConfigDescription("Multiplier applied to top speed when OverrideCarStats is on.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 4f), Array.Empty())); ExtraJumps = cfg.Bind("Car", "ExtraJumps", 0, new ConfigDescription("Extra mid-air jumps granted when OverrideCarStats is on.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 10), Array.Empty())); EnableCustomCards = cfg.Bind("Cards", "EnableCustomCards", true, "Adds this mod's cards to the post-round draft. Because cards cross the network as indices into a shared catalog, EVERY player must run this mod with the same cards, or the draft desyncs and players draw different cards from the same roll. Takes effect on restart."); SpeedCardBoostPercent = cfg.Bind("Cards", "SpeedCardBoostPercent", 10f, new ConfigDescription("How much top speed the \"Overdrive\" card grants for the round, as a percent. The effect is applied the same way the game's own modifier cards apply theirs, so it replicates correctly as long as every peer has the mod.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 100f), Array.Empty())); SizeCardGrowthPercent = cfg.Bind("Cards", "SizeCardGrowthPercent", 10f, new ConfigDescription("How much bigger the \"Supersize\" card makes every car, as a percent. Like the game's own upgrade cards this stacks and lasts for the rest of the match, so the value compounds: at 10%, four picks is roughly a 1.5x car. Large values get silly fast — 100 means each pick doubles the car, which is wider than a lane after two.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 300f), Array.Empty())); CarCardScale = cfg.Bind("Cards", "CarCardScale", 1f, new ConfigDescription("Size of the car placed by the \"Wreck\" card, measured against a real player car. 1 makes the wreck exactly as long as the car you drive; 0.5 makes it half that; 2 makes it double. The player car is measured live, so this stays right whatever the map's scale is. Press ReloadConfigKey after editing to apply it without restarting the game. Every player must use the same value or the wreck will be a different size on each screen.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 5f), Array.Empty())); CarCardLength = cfg.Bind("Cards", "CarCardLength", 0f, new ConfigDescription("Exact length of the \"Wreck\" car in world units, ignoring CarCardScale and the player car entirely. Leave at 0 to size against the player car, which is what you want on an unfamiliar map. Set a number here when you want one specific size and do not care how big the cars are: the log prints \"wreck sized\" with the measured player-car length every time one is placed, so start from that number. Every player must use the same value.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); TreeScale = cfg.Bind("Cards", "TreeScale", 2.5f, new ConfigDescription("How tall the \"Timber!\" tree stands, measured in player-car lengths. At the default 2.5 it is two and a half cars tall, which reads as a tree without walling off the track — its canopy is about as wide as it is tall, so raising this widens the obstacle as fast as it heightens it. The player car is measured live, so this stays right whatever the map's scale is. Press ReloadConfigKey after editing to apply it to the next tree placed. Every player must use the same value or the tree will be a different size, and block different things, on each screen.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 15f), Array.Empty())); TreeHeight = cfg.Bind("Cards", "TreeHeight", 0f, new ConfigDescription("Exact height of the \"Timber!\" tree in world units, ignoring TreeScale and the player car entirely. Leave at 0 to size against the player car, which is what you want on an unfamiliar map. The log prints \"tree sized\" with the measured player-car length every time one is placed, so start from that number. Every player must use the same value.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 300f), Array.Empty())); SwatterScale = cfg.Bind("Swatter", "SwatterScale", 0.3f, new ConfigDescription("How big the \"SWAT!\" flyswatter's pad is across, measured in player-car lengths. The pad sweeps across the track standing on its edge, so this is also how tall a wall it presents to a car: at the default 0.3 it is about a third of a car wide and the same again high. The handle is scaled with it, and the handle is most of the model, so the whole swatter comes out about three times this long — use SwatterReach if you want a shorter sweep without a smaller pad. The player car is measured live, so this stays right whatever the map's scale is. Press ReloadConfigKey after editing and the swatter already on the track resizes itself; you do not have to draft another one. Every player must use the same value or the swatter will be a different size, and swat different things, on each screen.", (AcceptableValueBase)(object)new AcceptableValueRange(0.2f, 10f), Array.Empty())); SwatterWidth = cfg.Bind("Swatter", "SwatterWidth", 0f, new ConfigDescription("Exact size of the \"SWAT!\" pad across, in world units, ignoring SwatterScale and the player car entirely. Leave at 0 to size against the player car, which is what you want on an unfamiliar map. The log prints \"swatter sized\" with the measured player-car length every time one is placed, so start from that number. Every player must use the same value.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 200f), Array.Empty())); SwatterReach = cfg.Bind("Swatter", "SwatterReach", 1f, new ConfigDescription("How far out the \"SWAT!\" pad sweeps, as a fraction of the swatter's own length. This is the knob for \"the arc is too wide\" — it shortens the reach without shrinking the pad, where SwatterScale changes both together. At 1 the swatter is pinned at the very end of its handle and sweeps its whole length; at 0.5 it is held halfway down the handle, so the arc is half as wide and the tail of the handle pokes out past the post, the way it would in somebody's hand. The pad itself is not stretched or shrunk by this — only how far from the post it travels, which is also how hard the tip of a swat lands. Press ReloadConfigKey and the swatter on the track re-hangs itself. Every player must use the same value or the pad will sweep a different part of the road on each screen.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 1f), Array.Empty())); PropCarrierName = cfg.Bind("Cards", "PropCarrierName", "", "Which vanilla obstacle the \"Wreck\" card borrows to exist as a real, placeable object. Leave empty to let the mod pick the most inert prop it can find. The names it found are written to the log every launch, as \"prop carrier candidates\" — set one of those here if the automatic choice behaves oddly, since the borrowed prop's collision shape is inherited and cannot be changed. EVERY player must use the same value, or the same card will be a different object on each screen."); ForceCustomCardInDraft = cfg.Bind("Cards", "ForceCustomCardInDraft", false, "Testing aid: force this mod's cards into every obstacle draft so you do not have to wait for the weighted roll to offer it. Leave off for normal rarity-weighted behaviour. Host only — the roll happens server-side."); BindCardRarities(cfg); GunFireInterval = cfg.Bind("Gun", "GunFireInterval", 6f, new ConfigDescription("Seconds between shots from the \"GUN!\" card. Shown on the card itself, so the draft screen always matches what you set here.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 60f), Array.Empty())); GunFiresOnlyWhileRacing = cfg.Bind("Gun", "GunFiresOnlyWhileRacing", true, "Hold fire outside the race itself. The card is drafted between rounds, so with this off the gun starts shooting over the scoreboard and while the next round's obstacles are being placed."); GunLength = cfg.Bind("Gun", "GunLength", 0.1f, new ConfigDescription("Length of the gun as a fraction of the car it is mounted on. 0.1 is a tenth of the car, which reads as a sidearm bolted to the bodywork; much above that and it stops looking mounted and starts looking parked alongside. Because it is a fraction it stays right on any map, and it grows with a car the Supersize card has enlarged.", (AcceptableValueBase)(object)new AcceptableValueRange(0.02f, 3f), Array.Empty())); GunOffsetRight = cfg.Bind("Gun", "GunOffsetRight", 0.1f, new ConfigDescription("How far to the right of the car's centre the gun sits, in fractions of car length. 0.1 puts it on the flank of a stock car; 0 buries it in the middle of the bodywork and negative values move it across to the driver's side. This is measured out from the centre of the car rather than in from its edge, so raising it moves the gun by a predictable amount.", (AcceptableValueBase)(object)new AcceptableValueRange(-2f, 2f), Array.Empty())); GunOffsetUp = cfg.Bind("Gun", "GunOffsetUp", 0.05f, new ConfigDescription("How far above the car's mid-height the gun sits, in fractions of car length.", (AcceptableValueBase)(object)new AcceptableValueRange(-2f, 2f), Array.Empty())); GunOffsetForward = cfg.Bind("Gun", "GunOffsetForward", 0f, new ConfigDescription("How far toward the nose of the car the gun sits, in fractions of car length. 0 is level with the middle of the car.", (AcceptableValueBase)(object)new AcceptableValueRange(-2f, 2f), Array.Empty())); GunYaw = cfg.Bind("Gun", "GunYaw", 0f, new ConfigDescription("Turn the gun, in degrees, from straight ahead. Bullets follow the barrel, so this aims the shots too: 90 fires out the passenger side and 180 fires backwards. If a gun you swap in comes out pointing the wrong way down the car, this is the fix — the barrel's axis is worked out from the model's shape, and a bounding box cannot tell which end of that axis is the muzzle.", (AcceptableValueBase)(object)new AcceptableValueRange(-180f, 180f), Array.Empty())); GunPitch = cfg.Bind("Gun", "GunPitch", 0f, new ConfigDescription("Tilt the gun's nose down (positive) or up (negative), in degrees.", (AcceptableValueBase)(object)new AcceptableValueRange(-180f, 180f), Array.Empty())); GunRoll = cfg.Bind("Gun", "GunRoll", 180f, new ConfigDescription("Roll the gun about its own barrel, in degrees — which turns it over without changing where it points. It defaults to 180 because the bundled pistol is authored grip-up: the model's vertical axis is worked out from its shape, and that cannot tell a grip from a sight, so it is a coin toss which way up any given model lands.", (AcceptableValueBase)(object)new AcceptableValueRange(-180f, 180f), Array.Empty())); BulletLength = cfg.Bind("Gun", "BulletLength", 0.15f, new ConfigDescription("Length of each bullet as a fraction of the firing car.", (AcceptableValueBase)(object)new AcceptableValueRange(0.005f, 2f), Array.Empty())); BulletSpeed = cfg.Bind("Gun", "BulletSpeed", 8f, new ConfigDescription("How fast bullets travel, in car lengths per second. Expressed against the car rather than in world units so a shot looks equally quick whatever scale the map is built at.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 200f), Array.Empty())); BulletLifetime = cfg.Bind("Gun", "BulletLifetime", 2f, new ConfigDescription("Seconds before a bullet disappears. Bullets pass through walls and props — they only test against cars — so this is what stops a miss flying off forever.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 60f), Array.Empty())); BulletsKill = cfg.Bind("Gun", "BulletsKill", false, "Kill a player whose car a bullet touches, exactly as the game's own kill zones do: it costs a life, plays the usual explosion, and respawns them. You are immune to your own gun. It is off by default, which leaves bullets as harmless scenery. Every player should use the same value — each machine decides only for its own car, so with this off you would survive shots that everyone else sees kill you."); BulletSlowPercent = cfg.Bind("Gun", "BulletSlowPercent", 50f, new ConfigDescription("How much speed a bullet knocks off the car it hits while BulletsKill is off, as a percentage of the speed they were carrying. This and the hop below are what a harmless gun does instead of killing: a shot has to be worth taking without costing a life. 100 stops them where they stand; 0 leaves only the hop. Ignored while BulletsKill is on — there is nothing to slow down.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); BulletSlowSeconds = cfg.Bind("Gun", "BulletSlowSeconds", 0.1f, new ConfigDescription("How long that slow is held, in seconds. Only their speed along the ground is capped, so the hop still rises and falls normally underneath it. The default is a stumble rather than a handbrake — long enough to cost a car length, short enough that being shot is not the end of your lap.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); BulletHopSpeed = cfg.Bind("Gun", "BulletHopSpeed", 1.5f, new ConfigDescription("How hard a bullet pops the car it hits off the road while BulletsKill is off, as the upward speed it leaves with in car lengths per second. Expressed against the car rather than in world units so the hop reads the same whatever scale the map is built at. It is set rather than added, so a hit is the same little jump whatever the car was already doing. 0 leaves only the slow.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 20f), Array.Empty())); BulletHitPadding = cfg.Bind("Gun", "BulletHitPadding", 0.05f, new ConfigDescription("Extra hit radius around a car, in fractions of car length, on top of the car's own physics radius and the bullet's length. A little padding makes hits feel fair, because a bullet's position is only as fresh as the last frame. 0 is exact; large values make shots near-impossible to dodge.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); BoinkSlowPercent = cfg.Bind("Boink", "BoinkSlowPercent", 50f, new ConfigDescription("How much speed a car loses when someone lands on it, as a percent of the speed it was doing at that moment. 50 halves it. It is capped there for BoinkSlowSeconds rather than just knocked down once, so the victim cannot floor it straight back up to speed.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); BoinkSlowSeconds = cfg.Bind("Boink", "BoinkSlowSeconds", 0.5f, new ConfigDescription("How long the slow lasts, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 10f), Array.Empty())); BoinkBounceDepth = cfg.Bind("Boink", "BoinkBounceDepth", 0.35f, new ConfigDescription("How far the squashed car dips, as a fraction of its own height. The bounce overshoots on the way back up and settles, so this is the depth of the first dip rather than the whole travel. 0 turns the animation off and leaves only the slow.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); BoinkBounceSeconds = cfg.Bind("Boink", "BoinkBounceSeconds", 0.35f, new ConfigDescription("How long the bounce animation runs, in seconds. Independent of the slow — a short springy bounce under a longer slow reads well.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 5f), Array.Empty())); BoinkMinHeight = cfg.Bind("Boink", "BoinkMinHeight", 0.6f, new ConfigDescription("How far above a car you must be for the hit to count as landing on it, measured in the victim's own car radii. This is what separates a jump from a side-swipe: at 0 any contact from fractionally above counts, and high values demand you come down squarely on their roof.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 3f), Array.Empty())); BoinkCooldownSeconds = cfg.Bind("Boink", "BoinkCooldownSeconds", 0.4f, new ConfigDescription("Shortest gap between two boinks on the same car. Two cars settling against each other generate a stream of contacts, and without this one landing would read as a burst of them and pin the car to the floor.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); RingSize = cfg.Bind("Bouncy", "RingSize", 0.5f, new ConfigDescription("How big the swim ring is, as a multiple of the car wearing it. At the default 0.5 it rides on the car like a float; around 1.5 the hole is wide enough for the car to sit down inside it. Because it is a fraction it stays right on any map, and it grows with a car the Supersize card has enlarged. It also sets how far out the ring bumps people: below roughly 1.2 that reach is inside the car's own body, so bumps land on contact rather than early. Every player should use the same value.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 4f), Array.Empty())); RingHeight = cfg.Bind("Bouncy", "RingHeight", 0f, new ConfigDescription("How far above the middle of the car the ring floats, in fractions of car length. 0 puts it around the car's waist; negative values drop it towards the wheels.", (AcceptableValueBase)(object)new AcceptableValueRange(-2f, 2f), Array.Empty())); RingYaw = cfg.Bind("Bouncy", "RingYaw", 0f, new ConfigDescription("Turn the ring, in degrees. The duck's head faces the way the car does at 0; use 180 if you would rather it looked back at whoever you just bounced.", (AcceptableValueBase)(object)new AcceptableValueRange(-180f, 180f), Array.Empty())); BouncePush = cfg.Bind("Bouncy", "BouncePush", 1f, new ConfigDescription("How hard the ring throws the player it touches, in car lengths per second. Their momentum into the ring is cancelled first, so this is the speed they actually leave with rather than something added to what they had. A normal car-on-car bump is worth well under one car length per second, so the default already reads as a shove; 6 or so launches people off the track. Expressed against the car rather than in world units so it feels the same whatever scale the map is built at.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 20f), Array.Empty())); BounceLift = cfg.Bind("Bouncy", "BounceLift", 0.2f, new ConfigDescription("How much of the push goes upwards, as a fraction of it. A little lift makes the bump read as bouncy rather than as a shunt; 0 keeps it flat along the ground.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); BounceRecoil = cfg.Bind("Bouncy", "BounceRecoil", 0.2f, new ConfigDescription("How hard the ring's own wearer is pushed back, as a fraction of BouncePush. This is what makes a bump a bounce rather than a battering ram: at 0 you plough through everyone unmoved. Unlike the player you hit, your recoil is added to the speed you already had rather than replacing it, so a bump knocks you off line without stopping you dead.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); BounceCooldownSeconds = cfg.Bind("Bouncy", "BounceCooldownSeconds", 0.4f, new ConfigDescription("Shortest gap between two bounces of the same player. The ring keeps touching them for as long as they are inside it, so without this one bump would be a stream of them and the pair would never separate.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); BounceOnlyWhileRacing = cfg.Bind("Bouncy", "BounceOnlyWhileRacing", true, "Keep the ring limp outside the race itself. Cars sit close together on a start grid and between rounds, and a ring that bumps whatever is near it would spend that time shoving the neighbours around. The ring is still worn and still visible — it just does nothing until the race starts. Every player should use the same value."); RingWobbleSeconds = cfg.Bind("Bouncy", "RingWobbleSeconds", 0.45f, new ConfigDescription("How long the ring wobbles after a bump, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 5f), Array.Empty())); RingWobbleDepth = cfg.Bind("Bouncy", "RingWobbleDepth", 0.25f, new ConfigDescription("How far the ring squashes as it wobbles, as a fraction of its own size. It flattens and spreads, then springs back through and settles, so this is the depth of the first squash rather than the whole travel. 0 turns the animation off and leaves only the push.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 0.9f), Array.Empty())); GravityReductionPercent = cfg.Bind("Floaty", "GravityReductionPercent", 30f, new ConfigDescription("How much gravity the \"Floaty\" card takes off the drafting player's car, as a percent. It weakens the fall without touching the jump, so the height you gain runs ahead of the number: taking 30% off gravity is about 43% more air, and the hang time grows with it. Like the game's own upgrade cards it lasts the rest of the match and stacks, and it compounds rather than adding — a second pick takes 30% off what is left, so three picks is two thirds of gravity gone and no number of picks ever reaches weightlessness. Every player must use the same value — each client simulates its own car, so a mismatch means your jumps land somewhere different on your screen than on theirs.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 90f), Array.Empty())); SwoopSeconds = cfg.Bind("Swatter", "SwoopSeconds", 0.35f, new ConfigDescription("How long the swat itself takes, in seconds — the 90 degrees the pad sweeps across the track, from parked out to one side to pointing straight ahead. The pad accelerates the whole way round, so halving this doubles the speed of the sweep and halves the time anybody has to get clear of the arc; how hard a landed swat throws you is SwatPush, not this. Short and mean is the point — much above a second and it stops reading as a swat and starts reading as a barrier arm.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 5f), Array.Empty())); LiftSeconds = cfg.Bind("Swatter", "LiftSeconds", 1.2f, new ConfigDescription("How long the swatter takes to draw itself back to where it started afterwards, in seconds. Deliberately slower than the swat: the return is the window players use to get past, and it does not hit anybody — the pad only pushes while it is moving towards you.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 10f), Array.Empty())); RestSeconds = cfg.Bind("Swatter", "RestSeconds", 1.5f, new ConfigDescription("How long the swatter waits, parked out to one side, between one swat and the next. This plus SwoopSeconds plus LiftSeconds is the full cycle, which at the defaults is a swat roughly every three seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 30f), Array.Empty())); SwatPush = cfg.Bind("Swatter", "SwatPush", 9f, new ConfigDescription("How hard a clean swat throws a car, in car lengths per second. This is the figure for the middle of the pad catching a car square at the end of the sweep; catching the tip is worth more, and being clipped early in the sweep or brushed by an edge on the way past is worth much less, because the push follows how fast the pad is actually closing on you and in which direction. A normal car-on-car bump is worth well under one car length per second, so the default of 9 is a proper launch. Expressed against the car rather than in world units so it feels the same whatever scale the map is built at.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 30f), Array.Empty())); SwatLift = cfg.Bind("Swatter", "SwatLift", 0.25f, new ConfigDescription("How much of the push goes upwards, as a fraction of it. The sweep is level with the track, so the push is too, and a little lift is what makes a swat send cars tumbling rather than sliding them sideways along the road. 0 keeps it flat.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); SwatCooldownSeconds = cfg.Bind("Swatter", "SwatCooldownSeconds", 0.5f, new ConfigDescription("Shortest gap between two swats landing on the same car. The pad keeps touching a car for as long as it is sweeping past it, so without this one swing would read as a burst of hits and pin the car under the pad.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); SwatOnlyWhileRacing = cfg.Bind("Swatter", "SwatOnlyWhileRacing", false, "Hold the launch until the race itself starts. Off by default, so a swat throws cars around whenever the swatter is swinging. With it on, the pad still swings and is still solid to drive into between rounds — it simply stops flinging anyone until the race is running. Every player should use the same value: each machine decides only for its own car, so with this on for you and off for them you would take swats nobody else sees land."); BollardScale = cfg.Bind("Bollard", "BollardScale", 0.35f, new ConfigDescription("How tall the bollard stands when it is up, measured in player-car lengths. At the default 0.35 it comes to about the height of a car's waist — high enough to stop one, low enough to see over. The player car is measured live, so this stays right whatever the map's scale is. How far the post travels is derived from this, since a bollard retracts until its lid is flush with the road. Every player must use the same value or it will be a different size, and block different things, on each screen.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 5f), Array.Empty())); BollardHeight = cfg.Bind("Bollard", "BollardHeight", 0f, new ConfigDescription("Exact standing height of the bollard in world units, ignoring BollardScale and the player car entirely. Leave at 0 to size against the player car, which is what you want on an unfamiliar map. The log prints \"bollard sized\" with the measured player-car length every time one is placed, so start from that number. Every player must use the same value.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); DownSeconds = cfg.Bind("Bollard", "DownSeconds", 3f, new ConfigDescription("How long the bollard stays down, flush with the road, between one rise and the next. This is the window cars can cross it in.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 60f), Array.Empty())); UpSeconds = cfg.Bind("Bollard", "UpSeconds", 3f, new ConfigDescription("How long the bollard stands there once it is up, before dropping again.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 60f), Array.Empty())); RiseSeconds = cfg.Bind("Bollard", "RiseSeconds", 0.6f, new ConfigDescription("How long the post takes to travel, in seconds — used for the rise and for the drop, since they are the same movement in opposite directions. Eased at both ends, so it reads as hydraulics rather than as a lift. The model's own baked animation took about 1.7 seconds over each; 0.6 is meaner, and it is the difference between a bollard you can beat and one you cannot. DownSeconds plus UpSeconds plus twice this is the full cycle — 7.2 seconds at the defaults.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 10f), Array.Empty())); } private static void BindCardRarities(ConfigFile cfg) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown try { BindEach(cfg); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(87, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not bind the per-card rarity settings, so every card keeps its "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("authored default: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } private static void BindEach(ConfigFile cfg) { foreach (CustomCard item in CustomCards.All) { item.RarityConfig = cfg.Bind("Rarity", item.Key + "Rarity", item.Rarity, "How often the \"" + item.Name + "\" card is offered in the draft. These are the game's own rarity levels and they set the draw weight exactly as they do for a shipped card — Common 110, Uncommon 60, Rare 37, UltraRare 25, Legendary 12, Unique 2, against a pool holding every card in the game — so a Common turns up about three times as often as a Rare. It cuts the other way late on, though: a match that raises its minimum rarity drops the commonest cards from the pool first, so a card set to Common is the one that stops appearing. Off never offers the card, but leaves it registered: that is the only safe way to retire one, because cards cross the network as positions in a shared list and dropping one would renumber the rest. The level also colours the card's frame. Read live, so the ReloadConfigKey applies a change to the next draft. The roll happens server-side, so it is the host's settings that decide what the lobby is offered."); } } } [BepInPlugin("slipskid.morecards", "MoreCards", "1.1.1")] public class Plugin : BaseUnityPlugin { private Harmony _harmony; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static Harmony Harmony { get; private set; } private void Awake() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModConfig.Bind(((BaseUnityPlugin)this).Config); if (!ModConfig.Enabled.Value) { Log.LogInfo((object)"Disabled in config; not patching anything."); return; } if (ModConfig.ForwardGameLogs.Value) { GameLogForwarder.Install(); } _harmony = new Harmony("slipskid.morecards"); Harmony = _harmony; ApplyPatchClasses(Assembly.GetExecutingAssembly()); bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; foreach (MethodBase patchedMethod in _harmony.GetPatchedMethods()) { ManualLogSource log = Log; val = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Patched: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(patchedMethod.DeclaringType?.FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(patchedMethod.Name); } log.LogInfo(val); } ((MonoBehaviour)this).StartCoroutine(Startup()); ManualLogSource log2 = Log; val = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("MoreCards"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("1.1.1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ready."); } log2.LogInfo(val); } private void ApplyPatchClasses(Assembly assembly) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); bool flag = default(bool); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length == 0) { if (type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Any((MethodInfo m) => m.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0)) { Log.LogError((object)(type.Name + " declares [HarmonyPatch] methods but has no [HarmonyPatch] on the class, so Harmony ignores all of them. Add [HarmonyPatch] above the class declaration.")); } continue; } try { _harmony.CreateClassProcessor(type).Patch(); } catch (Exception ex) { ManualLogSource log = Log; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(44, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Patching "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(type.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed; its patches are inactive: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } } private IEnumerator Startup() { yield return GameHooks.WaitForGameManager(); GameHooks.Install(); ((Component)this).gameObject.AddComponent(); Log.LogInfo((object)"Startup complete."); } private void OnDestroy() { GameHooks.Uninstall(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class PluginInfo { public const string Guid = "slipskid.morecards"; public const string Name = "MoreCards"; public const string Version = "1.1.1"; public const string HarmonyId = "slipskid.morecards"; } } namespace SlipSkid.MoreCards.Util { internal static class CardArt { private static readonly Dictionary _cache = new Dictionary(StringComparer.Ordinal); public static Texture2D Load(string resource) { //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown if (string.IsNullOrEmpty(resource)) { return null; } if (_cache.TryGetValue(resource, out var value)) { return value; } Texture2D val = null; bool flag = default(bool); try { byte[] array = ReadResource(resource); if (array == null) { Plugin.Log.LogWarning((object)("[art] embedded resource '" + resource + "' not found; the card keeps the carrier's thumbnail. Check the LogicalName in the .csproj.")); } else { val = new Texture2D(2, 2, (TextureFormat)4, false) { name = resource, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, array)) { Object.Destroy((Object)(object)val); val = null; ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[art] '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(resource); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' is not a PNG this build can decode."); } log.LogWarning(val2); } else if (ModConfig.Verbose.Value) { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(16, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[art] loaded "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(resource); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Texture)val).width); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("x"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Texture)val).height); } log2.LogInfo(val3); } } } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(25, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[art] could not load '"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(resource); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex); } log3.LogError(val4); val = null; } _cache[resource] = val; return val; } private static byte[] ReadResource(string name) { using Stream stream = typeof(CardArt).Assembly.GetManifestResourceStream(name); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } return array; } } internal static class CarMeasure { public const float FallbackLength = 4.5f; public static float ReferenceLength(out bool measured) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) List players = GameManager.Players; if (players != null) { for (int i = 0; i < players.Count; i++) { Transform val = players[i]?.controller?.car; if (!((Object)(object)val == (Object)null) && TryMeasureBody(val, out var localBounds)) { measured = true; return WorldLength(val, localBounds); } } } measured = false; return 4.5f; } public static bool TryMeasureBody(Transform car, out Bounds localBounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) localBounds = default(Bounds); if ((Object)(object)car == (Object)null) { return false; } bool flag = false; MeshFilter[] componentsInChildren = ((Component)car).GetComponentsInChildren(false); Vector3 val3 = default(Vector3); foreach (MeshFilter val in componentsInChildren) { Mesh val2 = (((Object)(object)val != (Object)null) ? val.sharedMesh : null); if ((Object)(object)val2 == (Object)null) { continue; } MeshRenderer component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null || !((Renderer)component).enabled || (Object)(object)((Component)val).GetComponentInParent() != (Object)null) { continue; } Bounds bounds = val2.bounds; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; for (int j = 0; j < 8; j++) { ((Vector3)(ref val3))..ctor(center.x + (((j & 1) == 0) ? (0f - extents.x) : extents.x), center.y + (((j & 2) == 0) ? (0f - extents.y) : extents.y), center.z + (((j & 4) == 0) ? (0f - extents.z) : extents.z)); val3 = car.InverseTransformPoint(((Component)val).transform.TransformPoint(val3)); if (!flag) { localBounds = new Bounds(val3, Vector3.zero); flag = true; } else { ((Bounds)(ref localBounds)).Encapsulate(val3); } } } if (flag) { Vector3 size = ((Bounds)(ref localBounds)).size; return ((Vector3)(ref size)).sqrMagnitude > 1E-06f; } return false; } public static float WorldLength(Transform car, Bounds localBounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) Vector3 size = ((Bounds)(ref localBounds)).size; Vector3 lossyScale = car.lossyScale; return Mathf.Max(size.x * Mathf.Abs(lossyScale.x), size.z * Mathf.Abs(lossyScale.z)); } public static float LocalLength(Bounds localBounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return Mathf.Max(((Bounds)(ref localBounds)).size.x, ((Bounds)(ref localBounds)).size.z); } public static Transform CarOf(PlayerData player) { return player?.controller?.car; } } internal static class ModelOrientation { public static Quaternion LongestAxisForward(Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) Vector3 size = ((Bounds)(ref bounds)).size; int num = 0; if (size.y > ((Vector3)(ref size))[num]) { num = 1; } if (size.z > ((Vector3)(ref size))[num]) { num = 2; } int num2 = 0; if (size.y < ((Vector3)(ref size))[num2]) { num2 = 1; } if (size.z < ((Vector3)(ref size))[num2]) { num2 = 2; } if (num2 == num) { num2 = (num + 1) % 3; } int index = 3 - num - num2; Vector3 val = Axis(num); Vector3 val2 = Axis(num2); Vector3 val3 = Axis(index); if (Vector3.Dot(Vector3.Cross(val2, val3), val) < 0f) { val2 = -val2; } return Quaternion.Inverse(Quaternion.LookRotation(val, val3)); } public static float LongestExtent(Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Vector3 size = ((Bounds)(ref bounds)).size; return Mathf.Max(size.x, Mathf.Max(size.y, size.z)); } private static Vector3 Axis(int index) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return (Vector3)(index switch { 1 => Vector3.up, 0 => Vector3.right, _ => Vector3.forward, }); } } internal static class ModUi { public static void Toast(string message, float duration = 2f, Transform parent = null, Vector3 position = default(Vector3)) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); if ((Object)(object)FloatingTextLabelGenerator.instance == (Object)null) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[toast] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(message); } log.LogInfo(val); return; } try { FloatingTextLabelGenerator.Generate(message, position, parent, default(FloatingTextLabelCallBacks), 0.3f, duration, 0.3f); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(30, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Toast failed ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("); message was: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(message); } log2.LogWarning(val2); } } public static bool Notify(string header, string body, Texture thumbnail = null, float duration = 5f) { //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) NotificationManager instance = NotificationManager.instance; if ((Object)(object)instance == (Object)null) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(11, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[notify] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(header); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(body); } log.LogInfo(val); return false; } try { Type type = AccessTools.Inner(typeof(NotificationManager), "NotificationStyle"); Type type2 = AccessTools.Inner(typeof(NotificationManager), "NotificationContent"); MethodInfo methodInfo = AccessTools.Method(typeof(NotificationManager), "ShowNotification", new Type[3] { type, type2, typeof(float) }, (Type[])null); if (type == null || type2 == null || methodInfo == null) { Plugin.Log.LogWarning((object)"NotificationManager internals not found; falling back to a toast."); Toast(header + ": " + body); return false; } object value = AccessTools.Field(typeof(NotificationManager), "unlockableUnlockStyle").GetValue(instance); object obj = Activator.CreateInstance(type2); AccessTools.Field(type2, "headerText").SetValue(obj, null); AccessTools.Field(type2, "descriptionText").SetValue(obj, body ?? string.Empty); AccessTools.Field(type2, "thumbnail").SetValue(obj, thumbnail); methodInfo.Invoke(null, new object[3] { value, obj, duration }); if (!string.IsNullOrEmpty(header) && (Object)(object)instance.headerLabel != (Object)null) { instance.headerLabel.text = header; } return true; } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Notify failed ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("); falling back to a toast."); } log2.LogWarning(val2); Toast(header + ": " + body); return false; } } } internal static class ObjMaterials { private static readonly Dictionary _cache = new Dictionary(StringComparer.Ordinal); private static readonly int PlayerPrimaryColor = Shader.PropertyToID("_PlayerPrimaryColor"); private static readonly int PlayerSecondaryColor = Shader.PropertyToID("_PlayerSecondaryColor"); private static readonly int BaseColor = Shader.PropertyToID("_BaseColor"); private static readonly int LegacyColor = Shader.PropertyToID("_Color"); private static readonly string[] CommonMaps = new string[9] { "_BaseMap", "_MainTex", "_BumpMap", "_NormalMap", "_EmissionMap", "_MetallicGlossMap", "_SpecGlossMap", "_OcclusionMap", "_DetailAlbedoMap" }; public static Material[] Build(ObjModel model, Material template, string cacheKey, Color? overrideColor = null, bool untextured = false, bool opaque = false, bool doubleSided = false, Color? multiplyColor = null) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) int subMeshCount = model.Mesh.subMeshCount; Material[] array = (Material[])(object)new Material[subMeshCount]; for (int i = 0; i < subMeshCount; i++) { string text = ((i < model.MaterialNames.Length) ? model.MaterialNames[i] : string.Empty); string key = cacheKey + "/" + text; if (_cache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { array[i] = value; continue; } if ((Object)(object)template == (Object)null) { array[i] = null; continue; } Material val = new Material(template) { name = cacheKey + "_" + text }; if (untextured) { ClearTextures(val); } if (opaque) { MakeOpaque(val); } if (doubleSided) { SetIfPresent(val, "_Cull", 0f); } bool flag = true; Color val2; Color value2; if (overrideColor.HasValue) { val2 = overrideColor.Value; } else if (model.MaterialColors.TryGetValue(text, out value2)) { val2 = value2; } else { val2 = Color.white; flag = multiplyColor.HasValue; } if (multiplyColor.HasValue) { Color value3 = multiplyColor.Value; ((Color)(ref val2))..ctor(val2.r * value3.r, val2.g * value3.g, val2.b * value3.b, 1f); } if (flag) { Tint(val, val2); } _cache[key] = val; array[i] = val; } return array; } public static void ClearTextures(Material mat) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 Shader val = (((Object)(object)mat != (Object)null) ? mat.shader : null); if ((Object)(object)val == (Object)null) { return; } try { int propertyCount = val.GetPropertyCount(); for (int i = 0; i < propertyCount; i++) { if ((int)val.GetPropertyType(i) == 4) { mat.SetTexture(val.GetPropertyNameId(i), (Texture)null); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[obj] could not enumerate '" + ((Object)val).name + "' texture properties (" + ex.GetType().Name + "); clearing the usual ones instead.")); string[] commonMaps = CommonMaps; foreach (string text in commonMaps) { if (mat.HasProperty(text)) { mat.SetTexture(text, (Texture)null); } } } } public static void Tint(Material mat, Color color) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)mat == (Object)null)) { color.a = 1f; int num = 0; if (mat.HasProperty(PlayerPrimaryColor)) { mat.SetColor(PlayerPrimaryColor, color); num++; } if (mat.HasProperty(PlayerSecondaryColor)) { mat.SetColor(PlayerSecondaryColor, color); num++; } if (mat.HasProperty(BaseColor)) { mat.SetColor(BaseColor, color); num++; } if (mat.HasProperty(LegacyColor)) { mat.SetColor(LegacyColor, color); num++; } if (num == 0) { Plugin.Log.LogWarning((object)("[obj] none of the colour properties exist on " + Describe(mat) + ", so it kept the template's colour. The shader names its colour something we do not write.")); } } } public static void MakeOpaque(Material mat) { if ((Object)(object)mat == (Object)null) { return; } try { SetIfPresent(mat, "_Surface", 0f); SetIfPresent(mat, "_Blend", 0f); SetIfPresent(mat, "_AlphaClip", 0f); SetIfPresent(mat, "_SrcBlend", 1f); SetIfPresent(mat, "_DstBlend", 0f); SetIfPresent(mat, "_ZWrite", 1f); SetIfPresent(mat, "_Cutoff", 0f); mat.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); mat.DisableKeyword("_ALPHAPREMULTIPLY_ON"); mat.DisableKeyword("_ALPHABLEND_ON"); mat.DisableKeyword("_ALPHATEST_ON"); mat.SetOverrideTag("RenderType", "Opaque"); mat.renderQueue = 2000; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[obj] could not force '" + ((Object)mat).name + "' opaque (" + ex.GetType().Name + "); it will keep the borrowed prop's blend state.")); } } private static void SetIfPresent(Material mat, string property, float value) { if (mat.HasProperty(property)) { mat.SetFloat(property, value); } } public static string Describe(Material mat) { if ((Object)(object)mat == (Object)null) { return ""; } string arg = ((mat.renderQueue >= 3000) ? " TRANSPARENT-QUEUE" : string.Empty); return "'" + ((Object)mat).name + "' shader '" + (((Object)(object)mat.shader != (Object)null) ? ((Object)mat.shader).name : "") + "' " + $"queue {mat.renderQueue}{arg}"; } public static bool TryReadColor(Material mat, out Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) color = Color.white; if ((Object)(object)mat == (Object)null) { return false; } int[] array = new int[4] { PlayerPrimaryColor, BaseColor, LegacyColor, PlayerSecondaryColor }; foreach (int num in array) { if (!mat.HasProperty(num)) { continue; } Color color2 = mat.GetColor(num); if (!(color2.a <= 0.001f)) { float num2 = Mathf.Max(color2.r, Mathf.Max(color2.g, color2.b)); float num3 = Mathf.Min(color2.r, Mathf.Min(color2.g, color2.b)); if (!(num2 <= 0.001f) && (!(num3 >= 0.99f) || !(num2 >= 0.99f))) { color = color2; return true; } } } return false; } public static Material TemplateFrom(Transform root) { if ((Object)(object)root == (Object)null) { return null; } MeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(false); foreach (MeshRenderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && ((Renderer)val).enabled && (Object)(object)((Renderer)val).sharedMaterial != (Object)null) { return ((Renderer)val).sharedMaterial; } } return null; } } internal sealed class ObjModel { private readonly struct VertexKey : IEquatable { private readonly int _p; private readonly int _uv; private readonly int _n; public VertexKey(int p, int uv, int n) { _p = p; _uv = uv; _n = n; } public bool Equals(VertexKey o) { if (_p == o._p && _uv == o._uv) { return _n == o._n; } return false; } public override bool Equals(object o) { if (o is VertexKey o2) { return Equals(o2); } return false; } public override int GetHashCode() { return (((_p * 397) ^ _uv) * 397) ^ _n; } } private static readonly char[] Whitespace = new char[3] { ' ', '\t', '\r' }; public Mesh Mesh { get; private set; } public string[] MaterialNames { get; private set; } public Dictionary MaterialColors { get; } = new Dictionary(StringComparer.Ordinal); public static ObjModel Parse(string objText, string mtlText, string meshName) { if (string.IsNullOrEmpty(objText)) { throw new ArgumentException("OBJ text is empty.", "objText"); } ObjModel objModel = new ObjModel(); if (!string.IsNullOrEmpty(mtlText)) { objModel.ParseMtl(mtlText); } objModel.ParseObj(objText, meshName); return objModel; } public static ObjModel FromEmbeddedResource(string objResource, string mtlResource, string meshName) { Assembly assembly = typeof(ObjModel).Assembly; string objText = ReadResource(assembly, objResource) ?? throw new InvalidOperationException("Embedded resource '" + objResource + "' not found. Available: " + string.Join(", ", assembly.GetManifestResourceNames())); string mtlText = ReadResource(assembly, mtlResource); return Parse(objText, mtlText, meshName); } private static string ReadResource(Assembly asm, string name) { if (string.IsNullOrEmpty(name)) { return null; } using Stream stream = asm.GetManifestResourceStream(name); if (stream == null) { return null; } using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } private void ParseMtl(string text) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) string text2 = null; foreach (string item in EnumerateLines(text)) { string[] array = Tokenize(item); if (array.Length != 0) { if (array[0] == "newmtl" && array.Length >= 2) { text2 = array[1]; } else if (array[0] == "Kd" && array.Length >= 4 && text2 != null) { MaterialColors[text2] = new Color(F(array[1]), F(array[2]), F(array[3])); } } } } private void ParseObj(string text, string meshName) { //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List list2 = new List(); List list3 = new List(); List list4 = new List(); List> list5 = new List>(); int num = -1; Dictionary emitted = new Dictionary(); List list6 = new List(); List list7 = new List(); List list8 = new List(); List list9 = new List(8); foreach (string item2 in EnumerateLines(text)) { string[] array = Tokenize(item2); if (array.Length == 0) { continue; } switch (array[0]) { case "v": if (array.Length >= 4) { list.Add(ToUnity(F(array[1]), F(array[2]), F(array[3]))); } break; case "vn": if (array.Length >= 4) { list2.Add(ToUnity(F(array[1]), F(array[2]), F(array[3]))); } break; case "vt": if (array.Length >= 3) { list3.Add(new Vector2(F(array[1]), F(array[2]))); } break; case "usemtl": { string item = ((array.Length >= 2) ? array[1] : string.Empty); num = list4.IndexOf(item); if (num < 0) { list4.Add(item); list5.Add(new List()); num = list4.Count - 1; } break; } case "f": { if (array.Length < 4) { break; } if (num < 0) { list4.Add(string.Empty); list5.Add(new List()); num = 0; } list9.Clear(); for (int i = 1; i < array.Length; i++) { int num2 = EmitVertex(array[i], list, list3, list2, emitted, list6, list8, list7); if (num2 >= 0) { list9.Add(num2); } } List list10 = list5[num]; for (int j = 2; j < list9.Count; j++) { list10.Add(list9[0]); list10.Add(list9[j]); list10.Add(list9[j - 1]); } break; } } } if (list6.Count == 0) { throw new InvalidOperationException("OBJ contained no usable geometry."); } Mesh val = new Mesh { name = meshName }; if (list6.Count > 65535) { val.indexFormat = (IndexFormat)1; } val.SetVertices(list6); if (list7.Count == list6.Count) { val.SetNormals(list7); } if (list8.Count == list6.Count) { val.SetUVs(0, list8); } val.subMeshCount = list5.Count; for (int k = 0; k < list5.Count; k++) { val.SetTriangles(list5[k], k, false); } if (list7.Count != list6.Count) { val.RecalculateNormals(); } val.RecalculateBounds(); val.RecalculateTangents(); Mesh = val; MaterialNames = list4.ToArray(); } private static int EmitVertex(string token, List positions, List uvs, List normals, Dictionary emitted, List outPositions, List outUvs, List outNormals) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) string[] array = token.Split(new char[1] { '/' }); int num = ResolveIndex((array.Length != 0) ? array[0] : null, positions.Count); if (num < 0) { return -1; } int num2 = ((array.Length > 1) ? ResolveIndex(array[1], uvs.Count) : (-1)); int num3 = ((array.Length > 2) ? ResolveIndex(array[2], normals.Count) : (-1)); VertexKey key = new VertexKey(num, num2, num3); if (emitted.TryGetValue(key, out var value)) { return value; } outPositions.Add(positions[num]); outUvs.Add((num2 >= 0) ? uvs[num2] : Vector2.zero); outNormals.Add((num3 >= 0) ? normals[num3] : Vector3.zero); return emitted[key] = outPositions.Count - 1; } private static int ResolveIndex(string field, int count) { if (string.IsNullOrEmpty(field)) { return -1; } if (!int.TryParse(field, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return -1; } int num = ((result > 0) ? (result - 1) : (count + result)); if (num < 0 || num >= count) { return -1; } return num; } private static Vector3 ToUnity(float x, float y, float z) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) return new Vector3(0f - x, y, z); } private static IEnumerable EnumerateLines(string text) { using StringReader reader = new StringReader(text); string text2; while ((text2 = reader.ReadLine()) != null) { if (text2.Length != 0 && text2[0] != '#') { yield return text2; } } } private static string[] Tokenize(string line) { return line.Split(Whitespace, StringSplitOptions.RemoveEmptyEntries); } private static float F(string s) { if (!float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return 0f; } return result; } } internal static class PlayerPaint { private const float MinBrightness = 0.28f; private static readonly Dictionary _announced = new Dictionary(); public static void Announce(int obstacleId, Color colour) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (_announced.Count > 128) { _announced.Clear(); } _announced[obstacleId] = colour; } public static bool TryAnnounced(int obstacleId, out Color colour) { return _announced.TryGetValue(obstacleId, out colour); } public static bool TryIdentityColour(PlayerData player, out Color colour, out string source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) colour = Color.white; source = "none"; if ((Object)(object)player == (Object)null) { return false; } bool flag = false; Color val = Color.white; if (Usable(player.primaryColor?.Value, out var colour2)) { val = colour2; flag = true; source = "primaryColor"; } if (Usable(player.secondaryColor?.Value, out var colour3) && (!flag || Brightness(colour3) > Brightness(val))) { val = colour3; flag = true; source = "secondaryColor"; } if (!flag && TryCarEffectsColour(player, out var colour4)) { val = colour4; flag = true; source = "CarEffects"; } if (!flag && TryPaletteColour(player, out var colour5, out var source2)) { val = colour5; flag = true; source = source2; } if (!flag && TryCarMaterialColour(player, out var colour6, out var source3)) { val = colour6; flag = true; source = source3; } if (!flag) { return false; } colour = Legible(val); return true; } public static bool TryPickIdentity(Color32 primary, Color32 secondary, out Color colour) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) colour = Color.white; bool flag = false; Color val = Color.white; if (Usable(primary, out var colour2)) { val = colour2; flag = true; } if (Usable(secondary, out var colour3) && (!flag || Brightness(colour3) > Brightness(val))) { val = colour3; flag = true; } if (!flag) { return false; } colour = Legible(val); return true; } public static string Describe(PlayerData player) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return "no player"; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("primaryColor=").Append((player.primaryColor != null) ? ((object)player.primaryColor.Value/*cast due to .constrained prefix*/).ToString() : ""); stringBuilder.Append(" secondaryColor=").Append((player.secondaryColor != null) ? ((object)player.secondaryColor.Value/*cast due to .constrained prefix*/).ToString() : ""); stringBuilder.Append(" primaryIndex=").Append((player.primaryColorIndex != null) ? player.primaryColorIndex.Value.ToString() : ""); stringBuilder.Append(" secondaryIndex=").Append((player.secondaryColorIndex != null) ? player.secondaryColorIndex.Value.ToString() : ""); stringBuilder.Append(" paintIndex=").Append((player.carPaintIndex != null) ? player.carPaintIndex.Value.ToString() : ""); SphereCarController controller = player.controller; CarEffects val = (((Object)(object)controller != (Object)null) ? (((Component)controller).GetComponentInChildren(true) ?? ((Component)controller).GetComponentInParent()) : null); if ((Object)(object)val == (Object)null) { stringBuilder.Append(" CarEffects="); return stringBuilder.ToString(); } Traverse val2 = Traverse.Create((object)val); stringBuilder.Append(" CarEffects._primaryColor=").Append(val2.Field("_primaryColor").GetValue()); stringBuilder.Append(" ._secondaryColor=").Append(val2.Field("_secondaryColor").GetValue()); stringBuilder.Append(" paintMaterial=").Append(ObjMaterials.Describe(val.currentCarPaintMaterial)); return stringBuilder.ToString(); } private static bool Usable(Color32? value, out Color colour) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) colour = Color.white; if (!value.HasValue) { return false; } Color32 value2 = value.Value; if (value2.a == 0) { return false; } if (value2.r == 0 && value2.g == 0 && value2.b == 0) { return false; } colour = Color32.op_Implicit(value2); return true; } private static bool TryCarEffectsColour(PlayerData player, out Color colour) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) colour = Color.white; SphereCarController controller = player.controller; if ((Object)(object)controller == (Object)null) { return false; } CarEffects val = ((Component)controller).GetComponentInChildren(true) ?? ((Component)controller).GetComponentInParent(); if ((Object)(object)val == (Object)null) { return false; } Traverse val2 = Traverse.Create((object)val); bool flag = false; Color val3 = Color.white; string[] array = new string[2] { "_primaryColor", "_secondaryColor" }; foreach (string text in array) { Traverse val4 = val2.Field(text); if (val4 != null && val4.FieldExists() && Usable(val4.GetValue(), out var colour2) && (!flag || Brightness(colour2) > Brightness(val3))) { val3 = colour2; flag = true; } } colour = val3; return flag; } private static bool TryPaletteColour(PlayerData player, out Color colour, out string source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) colour = Color.white; source = "none"; try { SphereCarController controller = player.controller; if ((Object)(object)controller == (Object)null) { return false; } CarEffects val = ((Component)controller).GetComponentInChildren(true) ?? ((Component)controller).GetComponentInParent(); Material val2 = (((Object)(object)val != (Object)null) ? val.currentCarPaintMaterial : null); if ((Object)(object)val2 == (Object)null) { return false; } CarPaint val3 = null; CarPaint[] array = Resources.FindObjectsOfTypeAll(); foreach (CarPaint val4 in array) { if ((Object)(object)val4 != (Object)null && (Object)(object)val4.material == (Object)(object)val2) { val3 = val4; break; } } if ((Object)(object)val3 == (Object)null) { return false; } bool flag = false; Color val5 = Color.white; if (TryFromPalette(val3.primaryColors, player.primaryColorIndex, out var colour2)) { val5 = colour2; flag = true; } if (TryFromPalette(val3.secondaryColors, player.secondaryColorIndex, out var colour3) && (!flag || Brightness(colour3) > Brightness(val5))) { val5 = colour3; flag = true; } if (!flag) { return false; } colour = val5; source = "'" + ((Object)val3).name + "' palette"; return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[paint] could not read the car paint's palette (" + ex.GetType().Name + "); falling back to the colour on the car's material.")); return false; } } private static bool TryFromPalette(ColorPalette palette, NetworkVariable index, out Color colour) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) colour = Color.white; Color[] array = (((Object)(object)palette != (Object)null) ? palette.colors : null); if (array == null || array.Length == 0 || index == null) { return false; } int value = index.Value; if (value < 0 || value >= array.Length) { return false; } Color val = array[value]; if (Mathf.Max(val.r, Mathf.Max(val.g, val.b)) <= 0.001f) { return false; } colour = val; return true; } private static bool TryCarMaterialColour(PlayerData player, out Color colour, out string source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) colour = Color.white; source = "none"; SphereCarController controller = player.controller; if ((Object)(object)controller == (Object)null) { return false; } CarEffects val = ((Component)controller).GetComponentInChildren(true) ?? ((Component)controller).GetComponentInParent(); if ((Object)(object)val != (Object)null && (Object)(object)val.currentCarPaintMaterial != (Object)null && ObjMaterials.TryReadColor(val.currentCarPaintMaterial, out colour)) { source = "car paint material"; return true; } Transform car = controller.car; if ((Object)(object)car != (Object)null && ObjMaterials.TryReadColor(ObjMaterials.TemplateFrom(car), out colour)) { source = "car renderer material"; return true; } return false; } private static Color Legible(Color colour) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) colour.a = 1f; float num = Brightness(colour); if (num >= 0.28f) { return colour; } if (num <= 0.0001f) { return new Color(0.28f, 0.28f, 0.28f, 1f); } float num2 = 0.28f / num; return new Color(colour.r * num2, colour.g * num2, colour.b * num2, 1f); } private static float Brightness(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return Mathf.Max(c.r, Mathf.Max(c.g, c.b)); } } internal static class PropReskin { public static void Neutralise(Obstacle obstacle) { if ((Object)(object)obstacle == (Object)null) { return; } MonoBehaviour[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(val is Obstacle)) { string text = ((object)val).GetType().Namespace; if (text != null && text.StartsWith("Obstacles", StringComparison.Ordinal)) { ((Behaviour)val).enabled = false; } } } Collider[] componentsInChildren2 = ((Component)obstacle).GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && val2.isTrigger && HasBehaviourScript(((Component)val2).gameObject)) { val2.enabled = false; } } ParticleSystem[] componentsInChildren3 = ((Component)obstacle).GetComponentsInChildren(true); foreach (ParticleSystem val3 in componentsInChildren3) { if (!((Object)(object)val3 == (Object)null)) { val3.Stop(true, (ParticleSystemStopBehavior)0); ParticleSystemRenderer component = ((Component)val3).GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = false; } } } TrailRenderer[] componentsInChildren4 = ((Component)obstacle).GetComponentsInChildren(true); foreach (TrailRenderer val4 in componentsInChildren4) { if ((Object)(object)val4 != (Object)null) { ((Renderer)val4).enabled = false; } } LineRenderer[] componentsInChildren5 = ((Component)obstacle).GetComponentsInChildren(true); foreach (LineRenderer val5 in componentsInChildren5) { if ((Object)(object)val5 != (Object)null) { ((Renderer)val5).enabled = false; } } } private static bool HasBehaviourScript(GameObject go) { MonoBehaviour[] components = go.GetComponents(); foreach (MonoBehaviour val in components) { if (!((Object)(object)val == (Object)null) && !(val is Obstacle)) { string text = ((object)val).GetType().Namespace; if (text != null && text.StartsWith("Obstacles", StringComparison.Ordinal)) { return true; } } } return false; } public static bool TryGetWorldBounds(MeshFilter[] filters, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); bool flag = false; foreach (MeshFilter val in filters) { MeshRenderer val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if (!((Object)(object)val2 == (Object)null) && ((Renderer)val2).enabled) { if (!flag) { bounds = ((Renderer)val2).bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(((Renderer)val2).bounds); } } } if (flag) { Vector3 size = ((Bounds)(ref bounds)).size; return ((Vector3)(ref size)).sqrMagnitude > 1E-06f; } return false; } public static float NonZero(float v) { if (!(Mathf.Abs(v) < 0.0001f)) { return v; } return 1f; } public static MeshFilter TakeOverRenderers(MeshFilter[] filters) { for (int i = 1; i < filters.Length; i++) { MeshRenderer val = (((Object)(object)filters[i] != (Object)null) ? ((Component)filters[i]).GetComponent() : null); if ((Object)(object)val != (Object)null) { ((Renderer)val).enabled = false; } } if (filters.Length == 0) { return null; } return filters[0]; } } } namespace SlipSkid.MoreCards.Runtime { internal sealed class BoinkedCar : MonoBehaviour { private SphereCarController _car; private CarModifierInstance _bounce; private float _bounceAge; private float _bounceSeconds; private float _bounceDepth; private float _slowUntil; private float _speedCap; private float _lastBoink = float.NegativeInfinity; private const float Pi = (float)Math.PI; private static CarModifier _asset; public static void Boink(SphereCarController victim, bool applySlow) { if (!((Object)(object)victim == (Object)null)) { BoinkedCar boinkedCar = ((Component)victim).gameObject.GetComponent(); if ((Object)(object)boinkedCar == (Object)null) { boinkedCar = ((Component)victim).gameObject.AddComponent(); } boinkedCar.Trigger(victim, applySlow); } } private void Trigger(SphereCarController victim, bool applySlow) { if (!(Time.time - _lastBoink < ModConfig.BoinkCooldownSeconds.Value)) { _lastBoink = Time.time; _car = victim; StartBounce(); if (applySlow) { StartSlow(); } if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; PlayerData player = victim.player; log.LogInfo((object)("[boink] " + ((player != null) ? player.DisplayName : null) + " was landed on" + (applySlow ? $" — capped at {_speedCap:0.0}/s for {ModConfig.BoinkSlowSeconds.Value:0.##}s" : " (visual only)"))); } } } private void StartSlow() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Rigidbody sphereRigidbody = _car.sphereRigidbody; if (!((Object)(object)sphereRigidbody == (Object)null)) { float num = 1f - Mathf.Clamp01(ModConfig.BoinkSlowPercent.Value / 100f); Vector3 velocity = sphereRigidbody.velocity; _speedCap = ((Vector3)(ref velocity)).magnitude * num; _slowUntil = Time.time + ModConfig.BoinkSlowSeconds.Value; } } private void StartBounce() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) _bounceSeconds = ModConfig.BoinkBounceSeconds.Value; _bounceDepth = ModConfig.BoinkBounceDepth.Value * _car.SphereRadius * 2f; _bounceAge = 0f; ReleaseBounce(); CarModifier val = Asset(); val.durationSeconds = _bounceSeconds + 0.25f; _bounce = val.GetInstance((object)this); _bounce.carOffset = Vector3.zero; if (!_car.RegisterModifier(_bounce)) { _bounce = null; } } private void Update() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (_bounce != null) { _bounceAge += Time.deltaTime; float num = ((_bounceSeconds > 0.0001f) ? Mathf.Clamp01(_bounceAge / _bounceSeconds) : 1f); if (num >= 1f) { ReleaseBounce(); return; } float num2 = Mathf.Sin(num * (float)Math.PI * 2.5f) * (1f - num); _bounce.carOffset = new Vector3(0f, (0f - _bounceDepth) * num2, 0f); } } private void FixedUpdate() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (Time.time >= _slowUntil) { return; } Rigidbody val = (((Object)(object)_car != (Object)null) ? _car.sphereRigidbody : null); if (!((Object)(object)val == (Object)null)) { Vector3 velocity = val.velocity; float magnitude = ((Vector3)(ref velocity)).magnitude; if (magnitude > _speedCap && magnitude > 0.0001f) { val.velocity = velocity * (_speedCap / magnitude); } } } private void ReleaseBounce() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (_bounce != null) { _bounce.carOffset = Vector3.zero; if ((Object)(object)_car != (Object)null) { _car.UnregisterModifier(_bounce); } _bounce = null; } } private void OnDestroy() { ReleaseBounce(); } private static CarModifier Asset() { if ((Object)(object)_asset != (Object)null) { return _asset; } _asset = ScriptableObject.CreateInstance(); ((Object)_asset).name = "BoinkBounce"; _asset.id = "slipskid.morecards.boink"; _asset.hasInfiniteDuration = false; _asset.isUnique = false; _asset.isUniquePerApplier = false; _asset.killOnEnd = false; _asset.disableJump = false; _asset.disableDash = false; return _asset; } } internal sealed class Bollard : MonoBehaviour { public Transform Post; public float Travel; public string ColourKey; private void Update() { Apply(); } public void Apply() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Post == (Object)null)) { Post.localPosition = new Vector3(0f, (0f - Travel) * Retraction(Clock()), 0f); } } private static float Retraction(float t) { float num = Mathf.Max(ModConfig.DownSeconds.Value, 0f); float num2 = Mathf.Max(ModConfig.UpSeconds.Value, 0f); float num3 = Mathf.Max(ModConfig.RiseSeconds.Value, 0.01f); float num4 = num + num3 + num2 + num3; if (num4 <= 0.0001f) { return 0f; } float num5 = t - Mathf.Floor(t / num4) * num4; if (num5 < num) { return 1f; } num5 -= num; if (num5 < num3) { return 1f - Smooth(num5 / num3); } num5 -= num3; if (num5 < num2) { return 0f; } num5 -= num2; return Smooth(Mathf.Clamp01(num5 / num3)); } private static float Smooth(float t) { float num = Mathf.Clamp01(t); return num * num * (3f - 2f * num); } private static float Clock() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.IsListening) { NetworkTime serverTime = singleton.ServerTime; return ((NetworkTime)(ref serverTime)).TimeAsFloat; } return Time.time; } } internal sealed class Bullet : MonoBehaviour { public float Speed; public PlayerData Shooter; public float Radius; public float Padding; private float _age; private void Update() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) float value = ModConfig.BulletLifetime.Value; _age += Time.deltaTime; if (_age >= value) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Vector3 position = ((Component)this).transform.position; Vector3 val = ((Component)this).transform.forward * (Speed * Time.deltaTime); ((Component)this).transform.position = position + val; if (TryHit(position, position + val)) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private bool TryHit(Vector3 from, Vector3 to) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown IReadOnlyList players = GameManager.Players; if (players == null) { return false; } bool flag = default(bool); for (int i = 0; i < players.Count; i++) { PlayerData val = players[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)Shooter || (val.isDead != null && val.isDead.Value)) { continue; } SphereCarController controller = val.controller; Transform val2 = (((Object)(object)controller != (Object)null) ? controller.car : null); if ((Object)(object)val2 == (Object)null) { continue; } float num = controller.SphereRadius + Radius + Padding; if (DistanceToSegment(val2.position, from, to) > num) { continue; } PlayerNetworking playerNetworking = val.playerNetworking; if ((Object)(object)playerNetworking != (Object)null && ((NetworkBehaviour)playerNetworking).IsOwner) { if (ModConfig.BulletsKill.Value) { playerNetworking.Die((Obstacle)null); if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[gun] bullet killed "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val.DisplayName); } log.LogInfo(val3); } } else { ShotCar.Hit(controller); } } return true; } return false; } private static float DistanceToSegment(Vector3 point, Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = b - a; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; Vector3 val2; if (sqrMagnitude < 1E-07f) { val2 = point - a; return ((Vector3)(ref val2)).magnitude; } float num = Mathf.Clamp01(Vector3.Dot(point - a, val) / sqrMagnitude); val2 = point - (a + val * num); return ((Vector3)(ref val2)).magnitude; } } internal sealed class CarBoink : MonoBehaviour { } internal sealed class CarFloat : MonoBehaviour { public SphereCarController Car; public PlayerData Owner; public int Picks; private static FieldRef _gravityField; private static bool _gravityFieldResolved; private bool _loggedOnce; private void FixedUpdate() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.EnableCustomCards.Value || (Object)(object)Car == (Object)null || Picks <= 0) { return; } PlayerNetworking val = Car.player?.playerNetworking; if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).IsOwner || Car.OnGround) { return; } Rigidbody sphereRigidbody = Car.sphereRigidbody; if ((Object)(object)sphereRigidbody == (Object)null || sphereRigidbody.IsSleeping()) { return; } float num = Reduction(); if (!(num <= 0.0001f)) { Vector3 val2 = GravityOf(Car); if (!(((Vector3)(ref val2)).sqrMagnitude < 1E-06f)) { sphereRigidbody.AddForce(-val2 * num, (ForceMode)5); LogOnce(val2, num); } } } private float Reduction() { float num = Mathf.Clamp01(ModConfig.GravityReductionPercent.Value / 100f); return 1f - Mathf.Pow(1f - num, (float)Picks); } private static Vector3 GravityOf(SphereCarController car) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (!_gravityFieldResolved) { _gravityFieldResolved = true; try { _gravityField = AccessTools.FieldRefAccess("_gravity"); } catch (Exception ex) { Plugin.Log.LogError((object)("[floaty] could not reach SphereCarController._gravity, so the card does nothing. The field was probably renamed by a game update. (" + ex.GetType().Name + ")")); } } if (_gravityField == null) { return Vector3.zero; } return _gravityField.Invoke(car); } private void LogOnce(Vector3 gravity, float reduction) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (!_loggedOnce) { _loggedOnce = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(92, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[floaty] "); PlayerData owner = Owner; ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((owner != null) ? owner.DisplayName : null) ?? "a player"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is floating: gravity here is "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(gravity); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Vector3)(ref gravity)).magnitude, "0.##"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/s^2) and "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(reduction * 100f, "0.#"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("% of it is being held back "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("over "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Picks); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" pick(s)."); } log.LogInfo(val); } } } internal sealed class CarGun : MonoBehaviour { public Transform Car; public PlayerData Owner; public Transform MeshChild; public Material[] BulletMaterials; private const float RemeasureInterval = 0.25f; private float _fireTimer; private float _measureTimer = 0.25f; private float _carWorldLength = 4.5f; private float _gunWorldLength; private bool _loggedMeasurement; private void Update() { if ((Object)(object)Car == (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } _measureTimer += Time.deltaTime; if (_measureTimer >= 0.25f) { _measureTimer = 0f; Remount(); } float value = ModConfig.GunFireInterval.Value; if (value <= 0.01f) { return; } if (ModConfig.GunFiresOnlyWhileRacing.Value && !IsRacing()) { _fireTimer = 0f; return; } _fireTimer += Time.deltaTime; if (!(_fireTimer < value)) { _fireTimer -= value; Fire(); } } private void Remount() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if (CarMeasure.TryMeasureBody(Car, out var localBounds)) { float num = CarMeasure.LocalLength(localBounds); if (!(num <= 0.0001f)) { _carWorldLength = CarMeasure.WorldLength(Car, localBounds); Vector3 center = ((Bounds)(ref localBounds)).center; center.x += ModConfig.GunOffsetRight.Value * num; center.y += ModConfig.GunOffsetUp.Value * num; center.z += ModConfig.GunOffsetForward.Value * num; LogMeasurementOnce(localBounds, num, center); ((Component)this).transform.localPosition = center; ((Component)this).transform.localRotation = Quaternion.Euler(ModConfig.GunPitch.Value, ModConfig.GunYaw.Value, ModConfig.GunRoll.Value); float length = ModConfig.GunLength.Value * num; GunCard.FitMeshChild(MeshChild, GunCard.PistolModel, length); _gunWorldLength = ModConfig.GunLength.Value * _carWorldLength; } } } private void Fire() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown GunCard.Prepared bulletModel = GunCard.BulletModel; if (bulletModel == null) { return; } float num = ModConfig.BulletLength.Value * _carWorldLength; if (num <= 0.0001f) { return; } GameObject val = new GameObject("ModBullet") { layer = ((Component)this).gameObject.layer }; val.transform.position = ((Component)this).transform.position + ((Component)this).transform.forward * (_gunWorldLength * 0.5f); val.transform.rotation = ((Component)this).transform.rotation; GunCard.FitMeshChild(GunCard.BuildMeshChild(val.transform, bulletModel, BulletMaterials, "bullet"), bulletModel, num); Bullet bullet = val.AddComponent(); bullet.Speed = ModConfig.BulletSpeed.Value * _carWorldLength; bullet.Shooter = Owner; bullet.Radius = num * 0.5f; bullet.Padding = ModConfig.BulletHitPadding.Value * _carWorldLength; if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[gun] fired: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num, "0.00"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" units long at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(bullet.Speed, "0.0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/s"); } log.LogInfo(val2); } } private void LogMeasurementOnce(Bounds body, float localLength, Vector3 mount) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if (!_loggedMeasurement) { _loggedMeasurement = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(127, 8, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[gun] mounted on '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)Car).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': body box centre "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref body)).center); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" size "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref body)).size); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(car-local), lossyScale "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Car.lossyScale); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", local length "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(localLength, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("world length "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_carWorldLength, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Gun sits at local "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(mount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("world "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Car.TransformPoint(mount)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogInfo(val); } } private static bool IsRacing() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 GameManagerNetworkVariables val = GameManager.instance?.networkVariables; if ((Object)(object)val != (Object)null) { return (int)val.state.Value == 5; } return false; } } internal sealed class CarRing : MonoBehaviour { public Transform Car; public PlayerData Owner; public SphereCarController Controller; public Transform Mesh; public ObjModel Model; private const float RemeasureInterval = 0.25f; private const float Pi = (float)Math.PI; private float _measureTimer = 0.25f; private float _carWorldLength = 4.5f; private float _ringWorldRadius; private float _meshScale = 1f; private bool _loggedFit; private float _wobbleAge; private float _wobbleSeconds; private readonly Dictionary _lastBounce = new Dictionary(); private void Update() { if ((Object)(object)Car == (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } _measureTimer += Time.deltaTime; if (_measureTimer >= 0.25f) { _measureTimer = 0f; Fit(); } Wobble(); } private void Fit() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Mesh == (Object)null || Model == null || !CarMeasure.TryMeasureBody(Car, out var localBounds)) { return; } float num = CarMeasure.LocalLength(localBounds); if (!(num <= 0.0001f)) { Bounds bounds = Model.Mesh.bounds; float num2 = Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)); if (!(num2 <= 0.0001f)) { _carWorldLength = CarMeasure.WorldLength(Car, localBounds); Vector3 center = ((Bounds)(ref localBounds)).center; center.y += ModConfig.RingHeight.Value * num; ((Component)this).transform.localPosition = center; ((Component)this).transform.localRotation = Quaternion.Euler(0f, ModConfig.RingYaw.Value, 0f); _meshScale = ModConfig.RingSize.Value * num / num2; Mesh.localScale = new Vector3(_meshScale, _meshScale, _meshScale); Mesh.localPosition = -(((Bounds)(ref bounds)).center * _meshScale); float num3 = ModConfig.RingSize.Value * _carWorldLength / num2; _ringWorldRadius = 0.25f * (((Bounds)(ref bounds)).size.x + ((Bounds)(ref bounds)).size.z) * num3; LogFitOnce(localBounds, num); } } } private void FixedUpdate() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.EnableCustomCards.Value || (Object)(object)Car == (Object)null || (Object)(object)Controller == (Object)null || _ringWorldRadius <= 0.0001f || (ModConfig.BounceOnlyWhileRacing.Value && !IsRacing())) { return; } IReadOnlyList players = GameManager.Players; if (players == null) { return; } for (int i = 0; i < players.Count; i++) { PlayerData val = players[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)Owner || (val.isDead != null && val.isDead.Value)) { continue; } SphereCarController controller = val.controller; if ((Object)(object)controller == (Object)null || (Object)(object)controller == (Object)(object)Controller) { continue; } Transform car = controller.car; if (!((Object)(object)car == (Object)null)) { float num = _ringWorldRadius + controller.SphereRadius; Vector3 val2 = car.position - ((Component)this).transform.position; if (!(((Vector3)(ref val2)).sqrMagnitude > num * num)) { Bounce(controller); } } } } public void Bounce(SphereCarController other) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown if ((Object)(object)other == (Object)null || (Object)(object)other == (Object)(object)Controller || (Object)(object)Car == (Object)null || (ModConfig.BounceOnlyWhileRacing.Value && !IsRacing())) { return; } Transform car = other.car; if ((Object)(object)car == (Object)null) { return; } float time = Time.time; if (_lastBounce.TryGetValue(other, out var value) && time - value < ModConfig.BounceCooldownSeconds.Value) { return; } _lastBounce[other] = time; Vector3 val = car.position - ((Component)this).transform.position; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; Vector3 val2 = ((magnitude > 0.0001f) ? (val * (1f / magnitude)) : Car.forward); float num = ModConfig.BouncePush.Value * _carWorldLength; Shove(other, val2, num, stopApproach: true); Shove(Controller, -val2, num * ModConfig.BounceRecoil.Value, stopApproach: false); StartWobble(); if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(24, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[bouncy] "); PlayerData owner = Owner; ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((owner != null) ? owner.DisplayName : null) ?? "a player"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" bounced "); PlayerData player = other.player; ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((player != null) ? player.DisplayName : null) ?? "someone"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" at "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num, "0.0"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("/s"); } log.LogInfo(val3); } } private static bool IsRacing() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 GameManagerNetworkVariables val = GameManager.instance?.networkVariables; if ((Object)(object)val != (Object)null) { return (int)val.state.Value == 5; } return false; } public void StartWobble() { _wobbleAge = 0f; _wobbleSeconds = ModConfig.RingWobbleSeconds.Value; } private static void Shove(SphereCarController car, Vector3 direction, float speed, bool stopApproach) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)car == (Object)null || speed <= 0.0001f) { return; } PlayerNetworking val = car.player?.playerNetworking; if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).IsOwner) { return; } Rigidbody sphereRigidbody = car.sphereRigidbody; if (!((Object)(object)sphereRigidbody == (Object)null)) { Vector3 val2 = sphereRigidbody.velocity; float num = Vector3.Dot(val2, direction); if (stopApproach && num < 0f) { val2 -= direction * num; } val2 += direction * speed; val2 += new Vector3(0f, speed * ModConfig.BounceLift.Value, 0f); sphereRigidbody.velocity = val2; } } private void Wobble() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Mesh == (Object)null) && !(_wobbleAge >= _wobbleSeconds)) { _wobbleAge += Time.deltaTime; float num = ((_wobbleSeconds > 0.0001f) ? Mathf.Clamp01(_wobbleAge / _wobbleSeconds) : 1f); float num2 = Mathf.Sin(num * (float)Math.PI * 3f) * (1f - num) * ModConfig.RingWobbleDepth.Value; Mesh.localScale = new Vector3(_meshScale * (1f + num2), _meshScale * (1f - num2), _meshScale * (1f + num2)); } } private void LogFitOnce(Bounds body, float localLength) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!_loggedFit) { _loggedFit = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(158, 7, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[bouncy] ring fitted on '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)Car).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': body box centre "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref body)).center); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" size "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref body)).size); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(car-local), local length "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(localLength, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", world length "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_carWorldLength, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Ring is "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ModConfig.RingSize.Value, "0.##"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("x the car and bumps players within "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_ringWorldRadius, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" units of its centre."); } log.LogInfo(val); } } } internal static class GameHooks { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnStateChanged; public static PlayerDelegate <1>__OnPlayerDeath; public static PlayerDelegate <2>__OnPlayerJoin; public static PlayerDelegate <3>__OnPlayerLeave; } private static bool _installed; private static UnityAction _stateChanged; private static PlayerDelegate _playerDied; private static PlayerDelegate _playerJoined; private static PlayerDelegate _playerLeft; public static IEnumerator WaitForGameManager() { while ((Object)(object)GameManager.instance == (Object)null) { yield return null; } } public static void Install() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown if (_installed) { return; } _installed = true; GameManager instance = GameManager.instance; if ((Object)(object)instance == (Object)null) { Plugin.Log.LogWarning((object)"GameHooks.Install called with no GameManager; skipping."); return; } _stateChanged = OnStateChanged; instance.onStateChange?.AddListener(_stateChanged); object obj = <>O.<1>__OnPlayerDeath; if (obj == null) { PlayerDelegate val = OnPlayerDeath; <>O.<1>__OnPlayerDeath = val; obj = (object)val; } _playerDied = (PlayerDelegate)obj; instance.onPlayerDeathDelegate = (PlayerDelegate)Delegate.Combine((Delegate?)(object)instance.onPlayerDeathDelegate, (Delegate?)(object)_playerDied); PlayerManager instance2 = PlayerManager.instance; if ((Object)(object)instance2 != (Object)null) { object obj2 = <>O.<2>__OnPlayerJoin; if (obj2 == null) { PlayerDelegate val2 = OnPlayerJoin; <>O.<2>__OnPlayerJoin = val2; obj2 = (object)val2; } _playerJoined = (PlayerDelegate)obj2; object obj3 = <>O.<3>__OnPlayerLeave; if (obj3 == null) { PlayerDelegate val3 = OnPlayerLeave; <>O.<3>__OnPlayerLeave = val3; obj3 = (object)val3; } _playerLeft = (PlayerDelegate)obj3; instance2.onNewPlayerJoin = (PlayerDelegate)Delegate.Combine((Delegate?)(object)instance2.onNewPlayerJoin, (Delegate?)(object)_playerJoined); instance2.onPlayerLeave = (PlayerDelegate)Delegate.Combine((Delegate?)(object)instance2.onPlayerLeave, (Delegate?)(object)_playerLeft); } Plugin.Log.LogInfo((object)"Game event hooks installed."); } public static void Uninstall() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown if (!_installed) { return; } _installed = false; GameManager instance = GameManager.instance; if ((Object)(object)instance != (Object)null) { if (_stateChanged != null) { instance.onStateChange?.RemoveListener(_stateChanged); } if (_playerDied != null) { instance.onPlayerDeathDelegate = (PlayerDelegate)Delegate.Remove((Delegate?)(object)instance.onPlayerDeathDelegate, (Delegate?)(object)_playerDied); } } PlayerManager instance2 = PlayerManager.instance; if ((Object)(object)instance2 != (Object)null) { if (_playerJoined != null) { instance2.onNewPlayerJoin = (PlayerDelegate)Delegate.Remove((Delegate?)(object)instance2.onNewPlayerJoin, (Delegate?)(object)_playerJoined); } if (_playerLeft != null) { instance2.onPlayerLeave = (PlayerDelegate)Delegate.Remove((Delegate?)(object)instance2.onPlayerLeave, (Delegate?)(object)_playerLeft); } } _stateChanged = null; _playerDied = null; _playerJoined = null; _playerLeft = null; } private static void OnStateChanged(GameState state) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); if (ModConfig.ShowStateChanges.Value) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(11, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[state] -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(state); } log.LogInfo(val); } if ((int)state == 7) { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[cards] obstacle draft screen open — "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(CustomCards.RegistrationSummary()); } log2.LogInfo(val); } } private static void OnPlayerDeath(PlayerData player) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[death] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((player != null) ? player.DisplayName : null); } log.LogInfo(val); } } private static void OnPlayerJoin(PlayerData player) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(7, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[join] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((player != null) ? player.DisplayName : null); } log.LogInfo(val); } } private static void OnPlayerLeave(PlayerData player) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[leave] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((player != null) ? player.DisplayName : null); } log.LogInfo(val); } } } internal sealed class ModAttachment : MonoBehaviour { } internal class ModBehaviour : MonoBehaviour { private void Update() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current != null) { KeyControl val = current[ModConfig.DebugKey.Value]; if (val != null && ((ButtonControl)val).wasPressedThisFrame) { DumpState(); } KeyControl val2 = current[ModConfig.ReloadConfigKey.Value]; if (val2 != null && ((ButtonControl)val2).wasPressedThisFrame) { ReloadConfig(); } } } private static void ReloadConfig() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { ((BaseUnityPlugin)Plugin.Instance).Config.Reload(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not reload the config file: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); ModUi.Toast("Config reload failed - see log"); return; } CustomCards.ApplyDraftOdds(); ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(71, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Config reloaded. Wreck size: CarCardScale="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ModConfig.CarCardScale.Value, "0.###"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("CarCardLength="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ModConfig.CarCardLength.Value, "0.###"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Draft odds: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(CustomCards.DraftOddsSummary()); } log2.LogInfo(val2); ModUi.Toast("Config reloaded"); } private static void DumpState() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("--- Slip & Skid state dump ---"); GameManager instance = GameManager.instance; if ((Object)(object)instance == (Object)null) { stringBuilder.AppendLine("GameManager.instance = null (still in boot, or between scenes)"); Plugin.Log.LogInfo((object)stringBuilder.ToString()); return; } Scene activeScene = SceneManager.GetActiveScene(); stringBuilder.AppendLine("scene : " + ((Scene)(ref activeScene)).name); stringBuilder.AppendLine("level : " + (instance.selectedLevel?.name ?? "")); stringBuilder.AppendLine("game mode : " + (((object)Unsafe.As(ref instance.currentGameMode?.type)/*cast due to .constrained prefix*/).ToString() ?? "")); stringBuilder.AppendLine($"split screen : {GameManager.splitScreenCount}"); stringBuilder.AppendLine($"is playing : {GameManager.IsPlaying}"); stringBuilder.AppendLine($"dev mode : {GameManager.isDevModeEnabled}"); NetworkManager singleton = NetworkManager.Singleton; stringBuilder.AppendLine($"net : listening={((singleton != null) ? new bool?(singleton.IsListening) : ((bool?)null))} server={((singleton != null) ? new bool?(singleton.IsServer) : ((bool?)null))} host={((singleton != null) ? new bool?(singleton.IsHost) : ((bool?)null))} client={((singleton != null) ? new bool?(singleton.IsClient) : ((bool?)null))}"); GameManagerNetworkVariables networkVariables = instance.networkVariables; if ((Object)(object)networkVariables != (Object)null) { stringBuilder.AppendLine($"state : {networkVariables.state.Value} (last {networkVariables.lastState.Value})"); stringBuilder.AppendLine($"round : {networkVariables.roundIndex.Value}"); CustomGameRules value = networkVariables.currentGameRules.Value; stringBuilder.AppendLine($"rules : pointsToWin={value.pointsToWin} maxSpeed={value.playerMaxSpeed} " + $"jumps={value.playerJumpCount} dashes={value.playerDashCount} lives={value.playerLifeCount}"); } else { stringBuilder.AppendLine("networkVariables : null (not in a session)"); } List players = GameManager.Players; stringBuilder.AppendLine($"players : {players?.Count ?? 0}"); if (players != null) { foreach (PlayerData item in players) { if (!((Object)(object)item == (Object)null)) { stringBuilder.AppendLine($" - {item.DisplayName} idx={item.playerIndex.Value} local={item.LocalIndex} " + $"dead={item.isDead.Value} lives={item.lifeCount.Value} rank={item.rank.Value}"); } } } stringBuilder.AppendLine($"obstacles : current={ObstacleManager.CurrentObstacles?.Count ?? 0} " + $"all={ObstacleManager.AllObstacles?.Count ?? 0}"); ObstacleManager instance2 = ObstacleManager.instance; stringBuilder.AppendLine($"obstacle catalog : {(instance2?.allowedObstacleDescriptions?.Length).GetValueOrDefault()} allowed, " + $"{(instance2?.hiddenObstacleDescriptions?.Length).GetValueOrDefault()} hidden"); Plugin.Log.LogInfo((object)stringBuilder.ToString()); ModUi.Toast("State dumped to log"); } } internal sealed class ShotCar : MonoBehaviour { private SphereCarController _car; private float _slowUntil; private float _speedCap; public static void Hit(SphereCarController victim) { if (!((Object)(object)victim == (Object)null)) { ShotCar shotCar = ((Component)victim).gameObject.GetComponent(); if ((Object)(object)shotCar == (Object)null) { shotCar = ((Component)victim).gameObject.AddComponent(); } shotCar.Trigger(victim); } } private void Trigger(SphereCarController victim) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) _car = victim; Rigidbody sphereRigidbody = _car.sphereRigidbody; if ((Object)(object)sphereRigidbody == (Object)null) { return; } Vector3 velocity = sphereRigidbody.velocity; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(velocity.x, 0f, velocity.z); float num = 1f - Mathf.Clamp01(ModConfig.BulletSlowPercent.Value / 100f); _speedCap = ((Vector3)(ref val)).magnitude * num; _slowUntil = Time.time + ModConfig.BulletSlowSeconds.Value; float num2 = ModConfig.BulletHopSpeed.Value * CarLength(_car); if (num2 > 0.0001f && velocity.y < num2) { velocity.y = num2; sphereRigidbody.velocity = velocity; } if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(52, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[gun] bullet hit "); PlayerData player = _car.player; ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((player != null) ? player.DisplayName : null) ?? "someone"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" — capped at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_speedCap, "0.0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/s for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ModConfig.BulletSlowSeconds.Value, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("s, "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("hopped at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2, "0.0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/s"); } log.LogInfo(val2); } } private void FixedUpdate() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (Time.time >= _slowUntil) { return; } Rigidbody val = (((Object)(object)_car != (Object)null) ? _car.sphereRigidbody : null); if (!((Object)(object)val == (Object)null)) { Vector3 velocity = val.velocity; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(velocity.x, 0f, velocity.z); float magnitude = ((Vector3)(ref val2)).magnitude; if (!(magnitude <= _speedCap) && !(magnitude <= 0.0001f)) { val2 *= _speedCap / magnitude; val.velocity = new Vector3(val2.x, velocity.y, val2.z); } } } private static float CarLength(SphereCarController car) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) Transform car2 = car.car; if ((Object)(object)car2 != (Object)null && CarMeasure.TryMeasureBody(car2, out var localBounds)) { return CarMeasure.WorldLength(car2, localBounds); } if (!(car.SphereRadius > 0.0001f)) { return 4.5f; } return car.SphereRadius * 2f; } } internal sealed class Swatter : MonoBehaviour { public Transform Root; public Transform Model; public SwatterModel.SwatterShape Shape; public float MeshScale = 1f; public Vector3 FootprintLocal; public string ColourKey; private const float DegToRad = (float)Math.PI / 180f; private const float SwoopDegrees = 90f; private const float RemeasureInterval = 0.25f; private const float MaxStrength = 2f; private float _measureTimer = 0.25f; private float _carWorldLength = 4.5f; private float _resizeTimer; private float _fixedAngle; private bool _haveFixedAngle; private bool _loggedFirstSwat; private readonly Dictionary _lastSwat = new Dictionary(); private float PadHeight => Shape.PadWidth * MeshScale; private void Update() { _resizeTimer += Time.deltaTime; if (_resizeTimer >= 0.25f) { _resizeTimer = 0f; Resize(log: false); } Pose(); } public void Resize(bool log) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown if ((Object)(object)Root == (Object)null || !Shape.IsValid) { return; } float num = SwatterModel.WorldScale(log); bool flag = Mathf.Abs(num - MeshScale) > 1E-06f; if (!flag && !log) { return; } MeshScale = num; SwatterModel.RefitPost(this, Pivot(), PadHeight * 0.5f, num); if (flag && !log && ModConfig.Verbose.Value) { ManualLogSource log2 = Plugin.Log; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[swatter] resized to world scale "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num, "0.000"); } log2.LogInfo(val); } } private Vector3 Pivot() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) return Root.TransformPoint(FootprintLocal) + Root.up * (PadHeight * 0.5f); } private Vector3 Anchor() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(ModConfig.SwatterReach.Value, 0.05f, 1f); return Shape.Grip + Shape.ArmAxis * (Shape.PadReach * (1f - num)); } public void Pose() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Root == (Object)null) && !((Object)(object)Model == (Object)null) && Shape.IsValid) { float angle = AngleAt(Clock()); Quaternion val = SwingRotation(angle); Model.rotation = val; Vector3 val2 = (((Object)(object)Model.parent != (Object)null) ? Model.parent.lossyScale : Vector3.one); Model.localScale = new Vector3(MeshScale / PropReskin.NonZero(val2.x), MeshScale / PropReskin.NonZero(val2.y), MeshScale / PropReskin.NonZero(val2.z)); Model.position = Pivot() - val * (Anchor() * MeshScale); } } private void FixedUpdate() { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Root == (Object)null || (Object)(object)Model == (Object)null || !Shape.IsValid || !ModConfig.EnableCustomCards.Value) { return; } float fixedDeltaTime = Time.fixedDeltaTime; if (fixedDeltaTime <= 1E-06f) { return; } float num = AngleAt(Clock()); float num2 = (_haveFixedAngle ? _fixedAngle : num); _fixedAngle = num; _haveFixedAngle = true; float num3 = 180f / Mathf.Max(ModConfig.SwoopSeconds.Value, 0.01f); float num4 = Mathf.Min((num - num2) / fixedDeltaTime, num3); if (num4 <= 0.0001f || (ModConfig.SwatOnlyWhileRacing.Value && !IsRacing())) { return; } _measureTimer += fixedDeltaTime; if (_measureTimer >= 0.25f) { _measureTimer = 0f; _carWorldLength = CarMeasure.ReferenceLength(out var _); } IReadOnlyList players = GameManager.Players; if (players == null) { return; } Vector3 pivot = Pivot(); Vector3 spin = SwingAxis() * (num4 * ((float)Math.PI / 180f)); float num5 = Shape.PadReach * Mathf.Clamp(ModConfig.SwatterReach.Value, 0.05f, 1f) * MeshScale; float num6 = num3 * ((float)Math.PI / 180f) * num5; if (num6 <= 1E-06f) { return; } for (int i = 0; i < players.Count; i++) { PlayerData val = players[i]; if (!((Object)(object)val == (Object)null) && (val.isDead == null || !val.isDead.Value)) { SphereCarController controller = val.controller; Transform val2 = (((Object)(object)controller != (Object)null) ? controller.car : null); if (!((Object)(object)val2 == (Object)null)) { TrySwat(controller, val2, pivot, spin, num6, fixedDeltaTime); } } } } private void TrySwat(SphereCarController car, Transform body, Vector3 pivot, Vector3 spin, float reference, float dt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Expected O, but got Unknown Vector3 position = body.position; Vector3 val = Model.InverseTransformPoint(position); Bounds pad = Shape.Pad; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Mathf.Clamp(val.x, ((Bounds)(ref pad)).min.x, ((Bounds)(ref pad)).max.x), Mathf.Clamp(val.y, ((Bounds)(ref pad)).min.y, ((Bounds)(ref pad)).max.y), Mathf.Clamp(val.z, ((Bounds)(ref pad)).min.z, ((Bounds)(ref pad)).max.z)); Vector3 val3 = Model.TransformPoint(val2); Vector3 val4 = position - val3; float magnitude = ((Vector3)(ref val4)).magnitude; Vector3 val5; if (magnitude > 0.0001f) { val5 = val4 * (1f / magnitude); } else { Vector3 val6 = Model.rotation * Shape.FaceAxis; val5 = ((Vector3.Dot(val - ((Bounds)(ref pad)).center, Shape.FaceAxis) < 0f) ? (-val6) : val6); } float num = Vector3.Dot(Vector3.Cross(spin, val3 - pivot), val5); if (num <= 0.0001f) { return; } float num2 = car.SphereRadius + num * dt; if (magnitude > num2) { return; } float time = Time.time; if (_lastSwat.TryGetValue(car, out var value) && time - value < ModConfig.SwatCooldownSeconds.Value) { return; } _lastSwat[car] = time; float num3 = Mathf.Clamp(num / reference, 0f, 2f); float num4 = ModConfig.SwatPush.Value * _carWorldLength * num3; Shove(car, val5, num4); if (ModConfig.Verbose.Value || !_loggedFirstSwat) { _loggedFirstSwat = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(51, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("[swatter] swatted "); PlayerData player = car.player; ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(((player != null) ? player.DisplayName : null) ?? "someone"); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" at "); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(num4, "0.0"); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("/s "); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("(strength "); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(num3, "0.00"); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(magnitude, "0.00"); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" from the pad)"); } log.LogInfo(val7); } } private static void Shove(SphereCarController car, Vector3 direction, float speed) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)car == (Object)null || speed <= 0.0001f) { return; } PlayerNetworking val = car.player?.playerNetworking; if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).IsOwner) { return; } Rigidbody sphereRigidbody = car.sphereRigidbody; if (!((Object)(object)sphereRigidbody == (Object)null)) { Vector3 val2 = sphereRigidbody.velocity; float num = Vector3.Dot(val2, direction); if (num < 0f) { val2 -= direction * num; } val2 += direction * speed; val2 += new Vector3(0f, speed * ModConfig.SwatLift.Value, 0f); sphereRigidbody.velocity = val2; } } private static float AngleAt(float t) { float num = Mathf.Max(ModConfig.RestSeconds.Value, 0f); float num2 = Mathf.Max(ModConfig.SwoopSeconds.Value, 0.01f); float num3 = Mathf.Max(ModConfig.LiftSeconds.Value, 0.01f); float num4 = num + num2 + num3; float num5 = t - Mathf.Floor(t / num4) * num4; if (num5 < num) { return 0f; } num5 -= num; if (num5 < num2) { float num6 = num5 / num2; return 90f * num6 * num6; } num5 -= num2; float num7 = Mathf.Clamp01(num5 / num3); float num8 = num7 * num7 * (3f - 2f * num7); return 90f * (1f - num8); } private Quaternion SwingRotation(float angle) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Quaternion.AngleAxis(angle, SwingAxis()); Quaternion val2 = Quaternion.LookRotation(val * -Root.right, val * Root.forward); Quaternion val3 = Quaternion.LookRotation(Shape.ArmAxis, Shape.FaceAxis); return val2 * Quaternion.Inverse(val3); } private Vector3 SwingAxis() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Root.up; } private static float Clock() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.IsListening) { NetworkTime serverTime = singleton.ServerTime; return ((NetworkTime)(ref serverTime)).TimeAsFloat; } return Time.time; } private static bool IsRacing() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 GameManagerNetworkVariables val = GameManager.instance?.networkVariables; if ((Object)(object)val != (Object)null) { return (int)val.state.Value == 5; } return false; } } } namespace SlipSkid.MoreCards.Patches { [HarmonyPatch] internal static class BoinkPatches { [HarmonyPatch(typeof(SphereCarController), "OnPlayerCollisionEnter")] [HarmonyPostfix] private static void AfterPlayerCollision(SphereCarController __instance, SphereCarController other) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown try { BoinkCard.OnCarsCollided(__instance, other); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[boink] collision handling threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } } [HarmonyPatch] internal static class BouncyPatches { [HarmonyPatch(typeof(SphereCarController), "OnPlayerCollisionEnter")] [HarmonyPostfix] private static void AfterPlayerCollision(SphereCarController __instance, SphereCarController other) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown try { BouncyCard.OnCarsCollided(__instance, other); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[bouncy] collision handling threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } } [HarmonyPatch] internal static class CardPatches { [HarmonyPatch(typeof(ObstacleManager), "Awake")] [HarmonyPostfix] private static void AfterObstacleManagerAwake(ObstacleManager __instance) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if (!ModConfig.EnableCustomCards.Value || (Object)(object)__instance != (Object)(object)ObstacleManager.instance) { return; } try { CustomCards.Register(__instance); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomCards registration failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } [HarmonyPatch(typeof(Obstacle), "Init")] [HarmonyPostfix] private static void AfterObstacleInit(Obstacle __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown if (!ModConfig.EnableCustomCards.Value) { return; } CustomCard customCard = CustomCards.CardForObstacle(__instance); if (customCard == null || customCard.Decorate == null) { return; } try { customCard.Decorate(__instance); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[cards] decorating '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(customCard.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } [HarmonyPatch(typeof(Obstacle), "SetObstacleColors")] [HarmonyPostfix] private static void AfterSetObstacleColors(Obstacle __instance, Color32 primaryColor, Color32 secondaryColor) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.EnableCustomCards.Value) { return; } try { SwatterModel.OnObstacleColors(__instance, primaryColor, secondaryColor); if ((Object)(object)__instance != (Object)null && PlayerPaint.TryPickIdentity(primaryColor, secondaryColor, out var colour)) { PlayerPaint.Announce(((Object)__instance).GetInstanceID(), colour); BollardModel.Repaint(__instance, colour); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(30, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[cards] recolouring '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((__instance != null) ? ((Object)__instance).name : null); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } [HarmonyPatch(typeof(ObstacleSelectionElement), "Init")] [HarmonyPostfix] private static void AfterSelectionElementInit(ObstacleSelectionElement __instance, ObstacleDescription obstacleDescription) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown if (!ModConfig.EnableCustomCards.Value) { return; } bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; if (!CustomCards.TryGetCard(obstacleDescription, out var card)) { if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[cards] draft slot: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((obstacleDescription != null) ? ((Object)obstacleDescription).name : null); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (vanilla)"); } log.LogInfo(val); } return; } if ((Object)(object)__instance.nameLabel != (Object)null) { __instance.nameLabel.text = card.Name; } if ((Object)(object)__instance.descriptionLabel != (Object)null) { __instance.descriptionLabel.text = FormatBody(card); } ManualLogSource log2 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(45, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[cards] draft slot is showing custom card '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(card.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log2.LogInfo(val); } [HarmonyPatch(typeof(ObstacleManager), "GetRandomObstaclesDescriptions")] [HarmonyPostfix] private static void AfterRoll(ref ((int, ObstacleDescription)[], (int, ObstacleAffixDescription)[]) __result) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown if (!ModConfig.EnableCustomCards.Value || !ModConfig.ForceCustomCardInDraft.Value || CustomCards.All.Count == 0) { return; } (int, ObstacleDescription)[] item = __result.Item1; if (item == null || item.Length == 0) { return; } ObstacleManager instance = ObstacleManager.instance; if (instance?.allowedObstacleDescriptions == null) { return; } bool flag = default(bool); for (int i = 0; i < CustomCards.All.Count; i++) { CustomCard customCard = CustomCards.All[i]; if (i >= item.Length) { Plugin.Log.LogWarning((object)($"[cards] only {item.Length} draft slot(s) this roll, so '{customCard.Name}' was " + "not forced in. Raise the obstacle count in the game rules to test it.")); continue; } ObstacleDescription asset = customCard.Asset; int num = (((Object)(object)asset != (Object)null) ? Array.IndexOf(instance.allowedObstacleDescriptions, asset) : (-1)); if (num < 0) { Plugin.Log.LogWarning((object)("[cards] cannot force '" + customCard.Name + "' into the draft: it is not in the catalog (it was never registered, or something replaced allowedObstacleDescriptions after registration).")); continue; } item[i] = (num, asset); ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[cards] forced '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(customCard.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' into draft slot "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(i); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (catalog #"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } log.LogInfo(val); } } private static string FormatBody(CustomCard card) { if (card.DescriptionArg == null) { return card.Description; } try { return string.Format(card.Description, card.DescriptionArg()); } catch (FormatException) { return card.Description; } } } [HarmonyPatch(typeof(SphereCarController))] internal static class CarPatches { [HarmonyPostfix] [HarmonyPatch("UpdateGameRulesValues")] private static void AfterRulesApplied(SphereCarController __instance, CustomGameRules customGameRules) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.OverrideCarStats.Value) { return; } __instance.maxSpeed *= ModConfig.MaxSpeedMultiplier.Value; __instance.maxAirJumps += ModConfig.ExtraJumps.Value; if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(54, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[car] rules applied for "); PlayerData player = __instance.player; ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((player != null) ? player.DisplayName : null); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("maxSpeed "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(customGameRules.playerMaxSpeed); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(__instance.maxSpeed); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("airJumps "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(customGameRules.playerJumpCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(__instance.maxAirJumps); } log.LogInfo(val); } } [HarmonyPrefix] [HarmonyPatch("Simulate")] private static void BeforeSimulate(SphereCarController __instance, float delta) { } } [HarmonyPatch(typeof(LobbyMenu))] internal static class LobbyPatches { [HarmonyPostfix] [HarmonyPatch("UpdateSteamLobbyStatus")] private static void AfterLobbyStatusUpdate() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown if (ModConfig.Verbose.Value) { GameMode val = GameManager.instance?.currentGameMode; int num = GameManager.Players?.Count ?? 0; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(17, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[lobby] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val?.maxPlayerCount.ToString() ?? "?"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" players"); } log.LogInfo(val2); } } } [HarmonyPatch] internal static class ObstaclePatches { [HarmonyPatch(typeof(ObstacleManager), "GetRandomObstaclesDescriptions")] [HarmonyPostfix] private static void AfterRoll(int amount, bool modifierOnly, ref ((int, ObstacleDescription)[], (int, ObstacleAffixDescription)[]) __result) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.Verbose.Value) { return; } (int, ObstacleDescription)[] item = __result.Item1; if (item == null) { return; } (int, ObstacleDescription)[] array = item; bool flag = default(bool); for (int i = 0; i < array.Length; i++) { (int, ObstacleDescription) tuple = array[i]; int item2 = tuple.Item1; ObstacleDescription item3 = tuple.Item2; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[draft] #"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((item3 != null) ? ((Object)item3).name : null); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item3?.rarity); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } log.LogInfo(val); } } [HarmonyPatch(typeof(ObstacleManager), "InitLevel")] [HarmonyFinalizer] private static void ReportInitLevelFailure(Exception __exception) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown if (__exception != null) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ObstacleManager.InitLevel threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(__exception); } log.LogError(val); } } } [HarmonyPatch(typeof(GameManagerNetworkVariables))] internal static class RulesPatches { private const bool EnableRuleOverride = false; [HarmonyPrefix] [HarmonyPatch("SetRules")] private static void BeforeSetRules(GameManagerNetworkVariables __instance, ref CustomGameRules newValue) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if (((NetworkBehaviour)__instance).IsServer && ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[rules] SetRules pointsToWin="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(newValue.pointsToWin); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" maxSpeed="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(newValue.playerMaxSpeed); } log.LogInfo(val); } } } } namespace SlipSkid.MoreCards.Cards { internal static class BoinkCard { public static void Equip(PlayerData owner) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown Transform val = owner?.controller?.car; if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[boink] " + (((owner != null) ? owner.DisplayName : null) ?? "a player") + " drafted Boink! but has no car to mark right now, so nothing was enabled.")); return; } bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2; if ((Object)(object)((Component)val).GetComponent() != (Object)null) { ManualLogSource log = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[boink] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted((owner != null) ? owner.DisplayName : null); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" already boinks; nothing to do."); } log.LogInfo(val2); return; } ((Component)val).gameObject.AddComponent(); ManualLogSource log2 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(59, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[boink] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((owner != null) ? owner.DisplayName : null) ?? "a player"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" can now boink — landing on a car slows it "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ModConfig.BoinkSlowPercent.Value, "0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("% for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ModConfig.BoinkSlowSeconds.Value, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("s."); } log2.LogInfo(val2); } public static void OnCarsCollided(SphereCarController a, SphereCarController b) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.EnableCustomCards.Value || (Object)(object)a == (Object)null || (Object)(object)b == (Object)null || (Object)(object)a == (Object)(object)b) { return; } Transform car = a.car; Transform car2 = b.car; if ((Object)(object)car == (Object)null || (Object)(object)car2 == (Object)null) { return; } SphereCarController val = ((car.position.y >= car2.position.y) ? a : b); SphereCarController val2 = (((Object)(object)val == (Object)(object)a) ? b : a); if (!((Object)(object)((Component)val.car).GetComponent() == (Object)null)) { float num = val.car.position.y - val2.car.position.y; float num2 = ModConfig.BoinkMinHeight.Value * Mathf.Max(val2.SphereRadius, 0.01f); if (!(num < num2)) { PlayerNetworking val3 = val2.player?.playerNetworking; bool applySlow = (Object)(object)val3 != (Object)null && ((NetworkBehaviour)val3).IsOwner; BoinkedCar.Boink(val2, applySlow); } } } } internal static class BollardModel { private const string PostObjResource = "SlipSkid.MoreCards.BollardPost.obj"; private const string PostMtlResource = "SlipSkid.MoreCards.BollardPost.mtl"; private const string BaseObjResource = "SlipSkid.MoreCards.BollardBase.obj"; private const string BaseMtlResource = "SlipSkid.MoreCards.BollardBase.mtl"; private const string PostChildName = "BollardPost"; private static ObjModel _post; private static ObjModel _base; private static bool _loadFailed; private static bool Load() { //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) if (_post != null && _base != null) { return true; } if (_loadFailed) { return false; } try { _post = ObjModel.FromEmbeddedResource("SlipSkid.MoreCards.BollardPost.obj", "SlipSkid.MoreCards.BollardPost.mtl", "CustomBollardPost"); _base = ObjModel.FromEmbeddedResource("SlipSkid.MoreCards.BollardBase.obj", "SlipSkid.MoreCards.BollardBase.mtl", "CustomBollardBase"); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(100, 7, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[bollard] model loaded: post "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_post.Mesh.vertexCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" verts "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_post.Mesh.subMeshCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" submesh(es) size "); Bounds bounds = _post.Mesh.bounds; ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref bounds)).size); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("base "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_base.Mesh.vertexCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" verts size "); bounds = _base.Mesh.bounds; ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref bounds)).size); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Travel "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Travel(), "0.####"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", standing height "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(StandingHeight(), "0.####"); } log.LogInfo(val); return true; } catch (Exception ex) { _loadFailed = true; ManualLogSource log2 = Plugin.Log; bool flag2 = default(bool); BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(44, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[bollard] could not load the bundled model: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log2.LogError(val2); return false; } } private static float Travel() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = _post.Mesh.bounds; float y = ((Bounds)(ref bounds)).max.y; bounds = _base.Mesh.bounds; return y - ((Bounds)(ref bounds)).max.y; } private static float StandingHeight() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = _post.Mesh.bounds; float y = ((Bounds)(ref bounds)).max.y; bounds = _base.Mesh.bounds; return y - ((Bounds)(ref bounds)).min.y; } public static void Apply(Obstacle obstacle) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown if (!Load() || (Object)(object)obstacle == (Object)null) { return; } PropReskin.Neutralise(obstacle); MeshFilter[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { Plugin.Log.LogWarning((object)("[bollard] carrier '" + ((Object)obstacle).name + "' has no MeshFilter to replace; the card will place an unmodified carrier.")); return; } if (!PropReskin.TryGetWorldBounds(componentsInChildren, out var bounds)) { ((Bounds)(ref bounds))..ctor(((Component)obstacle).transform.position, Vector3.one); } MeshFilter val = PropReskin.TakeOverRenderers(componentsInChildren); MeshRenderer component = ((Component)val).GetComponent(); val.sharedMesh = _base.Mesh; Material template = (((Object)(object)component != (Object)null) ? ((Renderer)component).sharedMaterial : null); string ownerName; Color? tint = OwnerTint(obstacle, out ownerName); if ((Object)(object)component != (Object)null) { ((Renderer)component).materials = BuildMaterials(_base, template, "bollardbase", tint); } Transform transform = ((Component)obstacle).transform; float num = PlaceModel(((Component)val).transform, transform, bounds); Transform post = AttachPost(((Component)val).transform, template, tint); int num2 = FitCollision(obstacle, ((Component)val).transform, post, num); Bollard obj = ((Component)obstacle).gameObject.GetComponent() ?? ((Component)obstacle).gameObject.AddComponent(); obj.Post = post; obj.Travel = Travel(); obj.ColourKey = TintKey(tint); obj.Apply(); if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(101, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[bollard] re-skinned '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)obstacle).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' in "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ownerName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s colour: world scale "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num, "0.000"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", stands "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(StandingHeight() * num, "0.00"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" units tall, travels "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Travel() * num, "0.00"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" collider(s) fitted"); } log.LogInfo(val2); } } private static float PlaceModel(Transform model, Transform root, Bounds carrier) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) float num = TargetHeight() / Mathf.Max(StandingHeight(), 0.0001f); if (num <= 0.0001f || float.IsNaN(num) || float.IsInfinity(num)) { num = 1f; } model.rotation = root.rotation; Vector3 val = (((Object)(object)model.parent != (Object)null) ? model.parent.lossyScale : Vector3.one); model.localScale = new Vector3(num / PropReskin.NonZero(val.x), num / PropReskin.NonZero(val.y), num / PropReskin.NonZero(val.z)); Bounds bounds = _base.Mesh.bounds; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).center.z); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(((Bounds)(ref carrier)).center.x, ((Bounds)(ref carrier)).min.y, ((Bounds)(ref carrier)).center.z); model.position = val3 - model.rotation * (val2 * num); return num; } private static float TargetHeight() { float value = ModConfig.BollardHeight.Value; bool measured; float num = CarMeasure.ReferenceLength(out measured); float num2 = ((value > 0.0001f) ? value : (num * ModConfig.BollardScale.Value)); Plugin.Log.LogInfo((object)($"[bollard] bollard sized: {num2:0.00} units tall " + ((value > 0.0001f) ? "(BollardHeight, fixed)" : ($"(BollardScale {ModConfig.BollardScale.Value:0.###} x " + string.Format("{0} player car {1:0.00}). ", measured ? "measured" : "assumed", num) + "Set BollardScale in the [Bollard] section to change it.")))); return num2; } private static Color? OwnerTint(Obstacle obstacle, out string ownerName) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) PlayerData val = CustomCards.OwnerOf(obstacle); ownerName = (((Object)(object)val != (Object)null) ? (val.DisplayName ?? "a player") : "an unknown player"); if (PlayerPaint.TryAnnounced(((Object)obstacle).GetInstanceID(), out var colour)) { Plugin.Log.LogInfo((object)($"[bollard] painting {ownerName}'s bollard {Color32.op_Implicit(colour)} " + "(the colours the game gave the obstacle)")); return colour; } bool flag = default(bool); if (PlayerPaint.TryIdentityColour(val, out var colour2, out var source)) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(38, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[bollard] painting "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ownerName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s bollard "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Color32.op_Implicit(colour2)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (from "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(source); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } log.LogInfo(val2); return colour2; } ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(82, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[bollard] no usable colour for "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ownerName); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" on '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Object)obstacle).name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', so it stays steel. "); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Every source was empty: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(PlayerPaint.Describe(val)); } log2.LogWarning(val3); return null; } private static Material[] BuildMaterials(ObjModel model, Material template, string cacheKey, Color? tint) { return ObjMaterials.Build(model, template, cacheKey + TintKey(tint), null, untextured: true, opaque: true, doubleSided: false, tint); } private static string TintKey(Color? tint) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!tint.HasValue) { return "#steel"; } Color32 val = Color32.op_Implicit(tint.Value); return $"#{val.r:x2}{val.g:x2}{val.b:x2}"; } public static void Repaint(Obstacle obstacle, Color colour) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)obstacle == (Object)null || _post == null || _base == null) { return; } Bollard component = ((Component)obstacle).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component.Post == (Object)null) { return; } string text = TintKey(colour); if (!(text == component.ColourKey)) { Transform parent = component.Post.parent; MeshRenderer val = (((Object)(object)parent != (Object)null) ? ((Component)parent).GetComponent() : null); MeshRenderer component2 = ((Component)component.Post).GetComponent(); if ((Object)(object)val != (Object)null) { ((Renderer)val).materials = BuildMaterials(_base, ((Renderer)val).sharedMaterial, "bollardbase", colour); } if ((Object)(object)component2 != (Object)null) { ((Renderer)component2).materials = BuildMaterials(_post, ((Renderer)component2).sharedMaterial, "bollardpost", colour); } component.ColourKey = text; Plugin.Log.LogInfo((object)($"[bollard] repainted '{((Object)obstacle).name}' to {Color32.op_Implicit(colour)} — the game announced its " + "owner's colours after we dressed it.")); } } private static Transform AttachPost(Transform model, Material template, Color? tint) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) Transform val = null; for (int i = 0; i < model.childCount; i++) { Transform child = model.GetChild(i); if ((Object)(object)child != (Object)null && ((Object)child).name == "BollardPost") { val = child; break; } } if ((Object)(object)val == (Object)null) { val = new GameObject("BollardPost") { layer = ((Component)model).gameObject.layer }.transform; val.SetParent(model, false); } val.localPosition = Vector3.zero; val.localRotation = Quaternion.identity; val.localScale = Vector3.one; (((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent()).sharedMesh = _post.Mesh; MeshRenderer obj = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); ((Renderer)obj).materials = BuildMaterials(_post, template, "bollardpost", tint); ((Renderer)obj).enabled = true; return val; } private static int FitCollision(Obstacle obstacle, Transform model, Transform post, float scale) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) int num = 0; Bounds bounds = _post.Mesh.bounds; BoxCollider val = ((Component)post).GetComponent() ?? ((Component)post).gameObject.AddComponent(); val.center = ((Bounds)(ref bounds)).center; val.size = ((Bounds)(ref bounds)).size; num++; List list = new List(); List list2 = new List(); Collider[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !val2.isTrigger && val2.enabled && !((Object)(object)val2 == (Object)(object)val)) { BoxCollider val3 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null); if (val3 != null) { list.Add(val3); } else { list2.Add(val2); } } } if (list.Count == 0) { GameObject val4 = new GameObject("BollardBase") { layer = ((list2.Count > 0) ? ((Component)list2[0]).gameObject.layer : ((Component)model).gameObject.layer) }; val4.transform.SetParent(model, false); val4.transform.localPosition = Vector3.zero; val4.transform.localRotation = Quaternion.identity; val4.transform.localScale = Vector3.one; list.Add(val4.AddComponent()); } Bounds bounds2 = _base.Mesh.bounds; Vector3 val5 = model.TransformPoint(((Bounds)(ref bounds2)).center); Vector3 val6 = ((Bounds)(ref bounds2)).size * scale; foreach (BoxCollider item in list) { Transform transform = ((Component)item).transform; Vector3 lossyScale = transform.lossyScale; item.center = transform.InverseTransformPoint(val5); item.size = new Vector3(val6.x / PropReskin.NonZero(lossyScale.x), val6.y / PropReskin.NonZero(lossyScale.y), val6.z / PropReskin.NonZero(lossyScale.z)); num++; } foreach (Collider item2 in list2) { item2.enabled = false; } return num; } } internal static class BouncyCard { private const string RingObj = "SlipSkid.MoreCards.SwimRing.obj"; private const string RingMtl = "SlipSkid.MoreCards.SwimRing.mtl"; private static ObjModel _model; private static bool _loadFailed; private static ObjModel Model() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (_model != null || _loadFailed) { return _model; } bool flag = default(bool); try { _model = ObjModel.FromEmbeddedResource("SlipSkid.MoreCards.SwimRing.obj", "SlipSkid.MoreCards.SwimRing.mtl", "CustomSwimRing"); Bounds bounds = _model.Mesh.bounds; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(55, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[bouncy] ring model loaded: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_model.Mesh.vertexCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" verts, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_model.Mesh.subMeshCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" submesh(es), size "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref bounds)).size); } log.LogInfo(val); } catch (Exception ex) { _loadFailed = true; ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(48, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[bouncy] could not load the bundled ring model: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log2.LogError(val2); } return _model; } public static void Equip(PlayerData owner) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown ObjModel objModel = Model(); if (objModel == null) { return; } Transform val = CarMeasure.CarOf(owner); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[bouncy] " + (((owner != null) ? owner.DisplayName : null) ?? "a player") + " drafted Bouncy but has no car to put a ring on right now, so nothing was equipped.")); return; } if ((Object)(object)((Component)val).GetComponentInChildren(true) != (Object)null) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(47, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[bouncy] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted((owner != null) ? owner.DisplayName : null); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" already has a ring; leaving it alone."); } log.LogInfo(val2); return; } Material val3 = ObjMaterials.TemplateFrom(val); if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"[bouncy] no material on the car to clone a shader from; the ring may render untinted. This usually means the car had not finished spawning."); } GameObject val4 = new GameObject("ModSwimRing"); val4.transform.SetParent(val, false); val4.layer = ((Component)val).gameObject.layer; val4.AddComponent(); CarRing carRing = val4.AddComponent(); carRing.Car = val; carRing.Owner = owner; carRing.Controller = owner?.controller; carRing.Model = objModel; carRing.Mesh = BuildMesh(val4.transform, objModel, val3); Plugin.Log.LogInfo((object)("[bouncy] " + (((owner != null) ? owner.DisplayName : null) ?? "a player") + " is now wearing a swim ring — bumping a " + $"player throws them at {ModConfig.BouncePush.Value:0.##} car lengths/s. Tune it " + "under [Bouncy] in the config and press the ReloadConfigKey; a ring already worn re-reads its size and its push live.")); } private static Transform BuildMesh(Transform parent, ObjModel model, Material template) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("swimRingMesh"); val.transform.SetParent(parent, false); val.layer = ((Component)parent).gameObject.layer; val.AddComponent().sharedMesh = model.Mesh; MeshRenderer val2 = val.AddComponent(); Material[] array = ObjMaterials.Build(model, template, "swimring", null, untextured: true); if (array != null) { ((Renderer)val2).materials = array; } return val.transform; } public static void OnCarsCollided(SphereCarController a, SphereCarController b) { if (ModConfig.EnableCustomCards.Value && !((Object)(object)a == (Object)null) && !((Object)(object)b == (Object)null) && !((Object)(object)a == (Object)(object)b)) { CarRing carRing = RingOn(a); if ((Object)(object)carRing != (Object)null) { carRing.Bounce(b); } CarRing carRing2 = RingOn(b); if ((Object)(object)carRing2 != (Object)null) { carRing2.Bounce(a); } } } private static CarRing RingOn(SphereCarController controller) { Transform val = (((Object)(object)controller != (Object)null) ? controller.car : null); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponentInChildren(true); } } internal static class CarModel { private const string ObjResource = "SlipSkid.MoreCards.Car.obj"; private const string MtlResource = "SlipSkid.MoreCards.Car.mtl"; private static ObjModel _model; private static bool _loadFailed; private static ObjModel Model() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (_model != null || _loadFailed) { return _model; } bool flag = default(bool); try { _model = ObjModel.FromEmbeddedResource("SlipSkid.MoreCards.Car.obj", "SlipSkid.MoreCards.Car.mtl", "CustomCar"); Bounds bounds = _model.Mesh.bounds; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[car] model loaded: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_model.Mesh.vertexCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" verts, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_model.Mesh.subMeshCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" submesh(es), size "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref bounds)).size); } log.LogInfo(val); } catch (Exception ex) { _loadFailed = true; ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(40, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[car] could not load the bundled model: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log2.LogError(val2); } return _model; } public static void Apply(Obstacle obstacle) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) ObjModel objModel = Model(); if (objModel == null || (Object)(object)obstacle == (Object)null) { return; } PropReskin.Neutralise(obstacle); MeshFilter[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { Plugin.Log.LogWarning((object)("[car] carrier '" + ((Object)obstacle).name + "' has no MeshFilter to replace; the card will place an unmodified carrier.")); return; } if (!PropReskin.TryGetWorldBounds(componentsInChildren, out var bounds)) { ((Bounds)(ref bounds))..ctor(((Component)obstacle).transform.position, Vector3.one); } MeshFilter val = PropReskin.TakeOverRenderers(componentsInChildren); MeshRenderer component = ((Component)val).GetComponent(); val.sharedMesh = objModel.Mesh; if ((Object)(object)component != (Object)null) { ((Renderer)component).materials = ObjMaterials.Build(objModel, ((Renderer)component).sharedMaterial, "car"); } float num = PlaceModel(((Component)val).transform, ((Component)obstacle).transform, objModel.Mesh, bounds); int num2 = FitColliders(obstacle, ((Component)val).transform, objModel.Mesh, num); if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(65, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[car] re-skinned '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)obstacle).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': world scale "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num, "0.000"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("car size "); Bounds bounds2 = objModel.Mesh.bounds; ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Bounds)(ref bounds2)).size * num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" collider(s) fitted"); } log.LogInfo(val2); } } private static float PlaceModel(Transform model, Transform root, Mesh mesh, Bounds carrier) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = mesh.bounds; float num = Max3(((Bounds)(ref bounds)).size); if (num <= 0.0001f) { return 1f; } float num2 = TargetLength() / num; if (num2 <= 0.0001f || float.IsNaN(num2) || float.IsInfinity(num2)) { num2 = 1f; } model.rotation = root.rotation; Vector3 val = (((Object)(object)model.parent != (Object)null) ? model.parent.lossyScale : Vector3.one); model.localScale = new Vector3(num2 / PropReskin.NonZero(val.x), num2 / PropReskin.NonZero(val.y), num2 / PropReskin.NonZero(val.z)); bounds = mesh.bounds; float x = ((Bounds)(ref bounds)).center.x; bounds = mesh.bounds; float y = ((Bounds)(ref bounds)).min.y; bounds = mesh.bounds; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(x, y, ((Bounds)(ref bounds)).center.z); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(((Bounds)(ref carrier)).center.x, ((Bounds)(ref carrier)).min.y, ((Bounds)(ref carrier)).center.z); model.position = val3 - model.rotation * (val2 * num2); return num2; } private static float TargetLength() { float value = ModConfig.CarCardLength.Value; bool measured; float num = CarMeasure.ReferenceLength(out measured); float num2 = ((value > 0.0001f) ? value : (num * ModConfig.CarCardScale.Value)); Plugin.Log.LogInfo((object)($"[car] wreck sized: {num2:0.00} units long " + ((value > 0.0001f) ? "(CarCardLength, fixed)" : ($"(CarCardScale {ModConfig.CarCardScale.Value:0.###} x " + string.Format("{0} player car {1:0.00}). ", measured ? "measured" : "assumed", num) + "Set Cards.CarCardScale to change it.")))); return num2; } private static int FitColliders(Obstacle obstacle, Transform model, Mesh mesh, float scale) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Collider[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !val.isTrigger && val.enabled) { BoxCollider val2 = (BoxCollider)(object)((val is BoxCollider) ? val : null); if (val2 != null) { list.Add(val2); } } } if (list.Count == 0) { list.Add(((Component)model).gameObject.AddComponent()); } Bounds bounds = mesh.bounds; Vector3 val3 = model.TransformPoint(((Bounds)(ref bounds)).center); bounds = mesh.bounds; Vector3 val4 = ((Bounds)(ref bounds)).size * scale; foreach (BoxCollider item in list) { Transform transform = ((Component)item).transform; Vector3 lossyScale = transform.lossyScale; item.center = transform.InverseTransformPoint(val3); item.size = new Vector3(val4.x / PropReskin.NonZero(lossyScale.x), val4.y / PropReskin.NonZero(lossyScale.y), val4.z / PropReskin.NonZero(lossyScale.z)); } return list.Count; } private static float Max3(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return Mathf.Max(v.x, Mathf.Max(v.y, v.z)); } } internal enum CardRarity { Off = -1, Common, Uncommon, Rare, UltraRare, Legendary, Unique } internal enum CardKind { Modifier, Prop } internal sealed class CustomCard { public string Id { get; } public string Name { get; } public string Key { get; } public string Description { get; } public Func DescriptionArg { get; } public string Thumbnail { get; } public CardRarity Rarity { get; } public ConfigEntry RarityConfig { get; set; } public CardRarity EffectiveRarity { get { if (RarityConfig == null) { return Rarity; } return RarityConfig.Value; } } public CardKind Kind { get; } public Action> Apply { get; } public Action ApplyToOwner { get; } public Action Decorate { get; } public ObstacleDescription Asset { get; set; } private CustomCard(string id, string name, string key, string description, CardRarity rarity, CardKind kind, Action> apply, Action applyToOwner, Action decorate, Func descriptionArg, string thumbnail) { Id = id; Name = name; Key = key; Description = description; Rarity = rarity; Kind = kind; Apply = apply; ApplyToOwner = applyToOwner; Decorate = decorate; DescriptionArg = descriptionArg; Thumbnail = thumbnail; } public static CustomCard Modifier(string id, string name, string key, string description, CardRarity rarity, Action> apply, Func descriptionArg = null, string thumbnail = null) { return new CustomCard(id, name, key, description, rarity, CardKind.Modifier, apply ?? throw new ArgumentNullException("apply"), null, null, descriptionArg, thumbnail); } public static CustomCard OwnerModifier(string id, string name, string key, string description, CardRarity rarity, Action applyToOwner, Func descriptionArg = null, string thumbnail = null) { return new CustomCard(id, name, key, description, rarity, CardKind.Modifier, null, applyToOwner ?? throw new ArgumentNullException("applyToOwner"), null, descriptionArg, thumbnail); } public static CustomCard Prop(string id, string name, string key, string description, CardRarity rarity, Action decorate, Func descriptionArg = null, string thumbnail = null) { return new CustomCard(id, name, key, description, rarity, CardKind.Prop, null, null, decorate ?? throw new ArgumentNullException("decorate"), descriptionArg, thumbnail); } } internal static class CustomCards { private static readonly List _cards = new List { CustomCard.Modifier("b1a7c0de-0000-4000-8000-0000000f0001", "Overdrive", "Overdrive", "+{0}% top speed this round", CardRarity.Uncommon, ApplyOverdrive, () => ModConfig.SpeedCardBoostPercent.Value, "SlipSkid.MoreCards.Thumbnail.Overdrive.png"), CustomCard.Modifier("b1a7c0de-0000-4000-8000-0000000f0002", "Supersize", "Supersize", "+{0}% car size", CardRarity.Rare, ApplySupersize, () => ModConfig.SizeCardGrowthPercent.Value, "SlipSkid.MoreCards.Thumbnail.Supersize.png"), CustomCard.Prop("b1a7c0de-0000-4000-8000-0000000f0003", "Wreck", "Wreck", "Drop a car on the track", CardRarity.Off, CarModel.Apply, null, "SlipSkid.MoreCards.Thumbnail.Wreck.png"), CustomCard.OwnerModifier("b1a7c0de-0000-4000-8000-0000000f0004", "GUN!", "Gun", "A gun on your car. Fires {0}", CardRarity.Legendary, GunCard.Equip, () => GunCard.ShotSummary(), "SlipSkid.MoreCards.Thumbnail.Gun.png"), CustomCard.OwnerModifier("b1a7c0de-0000-4000-8000-0000000f0005", "Boink!", "Boink", "Land on a car to squash it and slow it {0}%", CardRarity.UltraRare, BoinkCard.Equip, () => ModConfig.BoinkSlowPercent.Value), CustomCard.OwnerModifier("b1a7c0de-0000-4000-8000-0000000f0006", "Bouncy", "Bouncy", "A swim ring on your car. Bump a player to fling them away", CardRarity.Legendary, BouncyCard.Equip, null, "SlipSkid.MoreCards.Thumbnail.Bouncy.png"), CustomCard.OwnerModifier("b1a7c0de-0000-4000-8000-0000000f0007", "Floaty", "Floaty", "-{0}% gravity. Jump higher and hang longer", CardRarity.Rare, FloatyCard.Equip, () => ModConfig.GravityReductionPercent.Value, "SlipSkid.MoreCards.Thumbnail.Floaty.png"), CustomCard.Prop("b1a7c0de-0000-4000-8000-0000000f0008", "Timber!", "Timber", "Drop a solid tree on the track", CardRarity.Off, TreeModel.Apply, null, "SlipSkid.MoreCards.Thumbnail.Tree.png"), CustomCard.Prop("b1a7c0de-0000-4000-8000-0000000f0009", "SWAT!", "Swat", "A flyswatter in your colour. Swats every {0}s and flings whoever it catches", CardRarity.Rare, SwatterModel.Apply, () => (ModConfig.RestSeconds.Value + ModConfig.SwoopSeconds.Value + ModConfig.LiftSeconds.Value).ToString("0.#"), "SlipSkid.MoreCards.Thumbnail.Swatter.png"), CustomCard.Prop("b1a7c0de-0000-4000-8000-0000000f000a", "Bollard", "Bollard", "A bollard that rises out of the road every {0}s", CardRarity.Uncommon, BollardModel.Apply, () => (ModConfig.DownSeconds.Value + ModConfig.UpSeconds.Value + 2f * ModConfig.RiseSeconds.Value).ToString("0.#"), "SlipSkid.MoreCards.Thumbnail.Bollard.png") }; private static bool _registered; private static readonly Dictionary _byDescription = new Dictionary(); private static Type _carrierType; public static IReadOnlyList All => _cards; public static string RegistrationSummary() { if (!ModConfig.EnableCustomCards.Value) { return "custom cards are disabled in config (Cards/EnableCustomCards)"; } if (!_registered) { return "custom cards NOT registered — the ObstacleManager.Awake postfix never ran or bailed out; check the log around plugin startup"; } ObstacleDescription[] array = ObstacleManager.instance?.allowedObstacleDescriptions; if (array == null) { return $"{_cards.Count} card(s) registered, but the obstacle catalog is unavailable"; } List list = new List(_cards.Count); foreach (CustomCard card in _cards) { int num = (((Object)(object)card.Asset != (Object)null) ? Array.IndexOf(array, card.Asset) : (-1)); list.Add((num >= 0) ? $"{card.Name}=#{num}" : (card.Name + "=MISSING (dropped from the catalog)")); } return $"{_cards.Count} card(s) registered in a {array.Length}-entry catalog: " + string.Join(", ", list.ToArray()); } public static void Register(ObstacleManager manager) { //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown if (_registered || (Object)(object)manager == (Object)null || manager.allowedObstacleDescriptions == null) { return; } ObstacleDescription val = FindModifierCarrier(manager.allowedObstacleDescriptions); ObstacleDescription val2 = FindPropCarrier(manager.allowedObstacleDescriptions); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"CustomCards: no existing modifier card to use as a carrier prefab; cannot add custom cards on this build."); return; } _carrierType = ((object)((Component)val.prefab).GetComponent()).GetType(); List list = new List(manager.allowedObstacleDescriptions); foreach (CustomCard card in _cards) { ObstacleDescription val3 = ((card.Kind == CardKind.Prop) ? val2 : val); if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)($"CustomCards: no {card.Kind} carrier available, so '{card.Name}' was not " + "registered.")); continue; } ObstacleDescription val4 = (card.Asset = BuildDescription(card, val3)); _byDescription[val4] = card; list.Add(val4); } manager.allowedObstacleDescriptions = list.ToArray(); ApplyDraftOdds(); MethodInfo methodInfo = AccessTools.Method(_carrierType, "ApplyModifier", (Type[])null, (Type[])null); if (methodInfo != null && Plugin.Harmony != null) { Plugin.Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(CustomCards), "CarrierApplyModifierPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } _registered = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(104, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("CustomCards: added "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(_cards.Count); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" card(s). "); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Modifier carrier '"); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(_carrierType.Name); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("', "); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("prop carrier '"); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "none"); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("'. "); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Catalog is now "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(manager.allowedObstacleDescriptions.Length); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" entries. "); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Draft odds: "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(DraftOddsSummary()); } log.LogInfo(val6); } public static bool TryGetCard(ObstacleDescription description, out CustomCard card) { return _byDescription.TryGetValue(description, out card); } public static void ApplyDraftOdds() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) foreach (CustomCard card in _cards) { ObstacleDescription asset = card.Asset; if (!((Object)(object)asset == (Object)null)) { CardRarity effectiveRarity = card.EffectiveRarity; if (effectiveRarity == CardRarity.Off) { asset.maxQuantity = 0; continue; } asset.maxQuantity = -1; asset.rarity = (ObstacleRarity)effectiveRarity; } } } public static string DraftOddsSummary() { List list = new List(_cards.Count); foreach (CustomCard card in _cards) { list.Add($"{card.Name}={card.EffectiveRarity}"); } return string.Join(", ", list.ToArray()); } public static CustomCard CardForObstacle(Obstacle obstacle) { PlayerData val = OwnerOf(obstacle); if ((Object)(object)val == (Object)null || val.selectedObstacleIndex == null) { return null; } int value = obstacle.playerInfosIndex.Value; int value2 = val.selectedObstacleIndex.Value; if (value2 < 0) { return null; } NetworkList val2 = GameManager.instance?.networkVariables?.obstaclesToSelectIndices; if (val2 == null || value2 >= val2.Count) { Plugin.Log.LogWarning((object)($"[cards] cannot resolve draft slot {value2} for player {value}: " + "the round's roll is " + ((val2 == null) ? "unavailable" : $"only {val2.Count} long") + ". The carrier's vanilla effect will run instead.")); return null; } int num = val2[value2]; ObstacleManager instance = ObstacleManager.instance; if (instance?.allowedObstacleDescriptions == null || num < 0 || num >= instance.allowedObstacleDescriptions.Length) { return null; } ObstacleDescription val3 = instance.allowedObstacleDescriptions[num]; if (!((Object)(object)val3 != (Object)null) || !_byDescription.TryGetValue(val3, out var value3)) { return null; } return value3; } public static PlayerData OwnerOf(Obstacle obstacle) { if ((Object)(object)obstacle == (Object)null || obstacle.playerInfosIndex == null) { return null; } return FindPlayerByIndex(obstacle.playerInfosIndex.Value); } private static bool CarrierApplyModifierPrefix(ObstacleGameModifier __instance) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown CustomCard customCard = CardForObstacle((Obstacle)(object)__instance); bool flag = default(bool); if (customCard == null) { if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(59, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[cards] placed '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((__instance != null) ? ((Object)__instance).name : null); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is not one of ours — vanilla effect runs."); } log.LogInfo(val); } return true; } try { if (customCard.ApplyToOwner != null) { customCard.ApplyToOwner(OwnerOf((Obstacle)(object)__instance)); } else { Action> apply = customCard.Apply; IReadOnlyList players = GameManager.Players; apply(players ?? Array.Empty()); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(34, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("CustomCards: effect for '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(customCard.Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log2.LogError(val2); } return false; } private static void ApplyOverdrive(IReadOnlyList players) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown float num = 1f + ModConfig.SpeedCardBoostPercent.Value / 100f; for (int i = 0; i < players.Count; i++) { SphereCarController val = players[i]?.controller; if (!((Object)(object)val == (Object)null)) { val.maxSpeed *= num; Traverse obj = Traverse.Create((object)val).Field("_maxSpeedDefaultValue"); obj.SetValue((object)(obj.GetValue() * num)); } } if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[card] Overdrive applied: top speed x"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num, "0.00"); } log.LogInfo(val2); } } private static void ApplySupersize(IReadOnlyList players) { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) float num = 1f + ModConfig.SizeCardGrowthPercent.Value / 100f; for (int i = 0; i < players.Count; i++) { SphereCarController val = players[i]?.controller; if ((Object)(object)val == (Object)null) { continue; } Vector3[] value = Traverse.Create((object)val).Field("_defaultChildrenLocalScale").GetValue(); if (value == null) { Plugin.Log.LogWarning((object)"[card] Supersize: could not read _defaultChildrenLocalScale; this car is unchanged. The field was probably renamed by a game update."); continue; } Transform transform = ((Component)val).transform; for (int j = 0; j < value.Length; j++) { ref Vector3 reference = ref value[j]; reference *= num; if (j < transform.childCount) { transform.GetChild(j).localScale = value[j]; } } val.floorRaycastDistance *= num; Traverse.Create((object)val).Property("SphereRadius", (object[])null).SetValue((object)(val.sphereCollider.radius * ((Component)val.sphereCollider).transform.lossyScale.x)); } if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[card] Supersize applied: car size x"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num, "0.00"); } log.LogInfo(val2); } } private static ObstacleDescription FindModifierCarrier(ObstacleDescription[] catalog) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 ObstacleDescription val = null; foreach (ObstacleDescription val2 in catalog) { if ((Object)(object)val2 == (Object)null || (int)val2.type != 4 || (Object)(object)val2.prefab == (Object)null) { continue; } ObstacleGameModifier component = ((Component)val2.prefab).GetComponent(); if (!((Object)(object)component == (Object)null)) { if (((object)component).GetType().Name.StartsWith("ObstacleGameModifierIncrease", StringComparison.Ordinal)) { return val2; } if (val == null) { val = val2; } } } return val; } private static ObstacleDescription FindPropCarrier(ObstacleDescription[] catalog) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) string text = ModConfig.PropCarrierName.Value?.Trim(); ObstacleDescription val = null; int num = int.MaxValue; List list = new List(); foreach (ObstacleDescription val2 in catalog) { if ((Object)(object)val2 == (Object)null || (int)val2.type != 0 || (Object)(object)val2.prefab == (Object)null || (Object)(object)((Component)val2.prefab).GetComponentInChildren(true) == (Object)null) { continue; } int num2 = InertnessScore(val2); list.Add($"{((Object)val2).name}(score {num2})"); if (!string.IsNullOrEmpty(text)) { if (string.Equals(((Object)val2).name, text, StringComparison.OrdinalIgnoreCase)) { val = val2; } } else if (num2 < num) { num = num2; val = val2; } } Plugin.Log.LogInfo((object)("[cards] prop carrier candidates (lower score = more inert): " + string.Join(", ", list.ToArray()))); if (!string.IsNullOrEmpty(text) && (Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[cards] PropCarrierName '" + text + "' matched no prop in the catalog; falling back to automatic selection.")); } if ((Object)(object)val == (Object)null && !string.IsNullOrEmpty(text)) { return FindPropCarrierAutomatically(catalog); } return val; } private static ObstacleDescription FindPropCarrierAutomatically(ObstacleDescription[] catalog) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) ObstacleDescription result = null; int num = int.MaxValue; foreach (ObstacleDescription val in catalog) { if (!((Object)(object)val == (Object)null) && (int)val.type == 0 && !((Object)(object)val.prefab == (Object)null) && !((Object)(object)((Component)val.prefab).GetComponentInChildren(true) == (Object)null)) { int num2 = InertnessScore(val); if (num2 < num) { num = num2; result = val; } } } return result; } private static int InertnessScore(ObstacleDescription d) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) int num = 0; MonoBehaviour[] componentsInChildren = ((Component)d.prefab).GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(val is Obstacle)) { string text = ((object)val).GetType().Namespace; if (text != null && text.StartsWith("Obstacles", StringComparison.Ordinal)) { num += 2; } } } num += ((Component)d.prefab).GetComponentsInChildren(true).Length; if ((int)d.bodyBodyType != 0) { num++; } return num; } private static ObstacleDescription BuildDescription(CustomCard card, ObstacleDescription carrier) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) ObstacleDescription val = ScriptableObject.CreateInstance(); FieldInfo[] fields = typeof(ObstacleDescription).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(val, fieldInfo.GetValue(carrier)); } ((Object)val).name = "CustomCard_" + card.Name; val.id = new SerializableGuid(new Guid(card.Id)); Texture2D val2 = CardArt.Load(card.Thumbnail); if ((Object)(object)val2 != (Object)null) { val.thumbnail = val2; val.isFullArt = false; val.overrideBackGroundMaterialTexture = null; val.overrideBackGroundMaterial = null; val.overrideBackGroundMaterialNormalMap = null; val.overrideThumbnailMaterial = null; val.overrideNameFontMaterial = null; val.overrideBackColor = false; val.overrideShineColor = false; val.thumbnailOffset = Vector3.zero; } val.type = (ObstacleType)((card.Kind != CardKind.Prop) ? 4 : 0); val.generationContexts = null; val.allowedAffixes = null; return val; } private static PlayerData FindPlayerByIndex(int playerIndex) { List players = GameManager.Players; if (players == null) { return null; } for (int i = 0; i < players.Count; i++) { PlayerData val = players[i]; if ((Object)(object)val != (Object)null && val.playerIndex != null && val.playerIndex.Value == playerIndex) { return val; } } return null; } } internal static class FloatyCard { public static void Equip(PlayerData owner) { SphereCarController val = owner?.controller; if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[floaty] " + (((owner != null) ? owner.DisplayName : null) ?? "a player") + " drafted Floaty but has no car to lighten right now, so nothing was applied.")); return; } CarFloat carFloat = ((Component)val).GetComponent(); if ((Object)(object)carFloat == (Object)null) { carFloat = ((Component)val).gameObject.AddComponent(); carFloat.Car = val; carFloat.Owner = owner; } carFloat.Picks++; Plugin.Log.LogInfo((object)(string.Format("[floaty] {0} took {1:0.##}% ", ((owner != null) ? owner.DisplayName : null) ?? "a player", ModConfig.GravityReductionPercent.Value) + $"off gravity (pick {carFloat.Picks}). Tune it under [Floaty] in the config and " + "press the ReloadConfigKey; every pick made so far is re-priced live.")); } } internal static class GunCard { internal sealed class Prepared { public ObjModel Model; public Quaternion BaseRotation; public float Extent; } private const string PistolObj = "SlipSkid.MoreCards.Pistol.obj"; private const string PistolMtl = "SlipSkid.MoreCards.Pistol.mtl"; private const string BulletObj = "SlipSkid.MoreCards.Bullet.obj"; private static Prepared _pistol; private static Prepared _bullet; private static bool _loadFailed; private static readonly Color BrassColor = new Color(0.85f, 0.65f, 0.25f); internal static Prepared PistolModel => _pistol; internal static Prepared BulletModel => _bullet; internal static string ShotSummary() { string arg = (ModConfig.BulletsKill.Value ? "killing" : "stunning"); return $"a {arg} shot every {ModConfig.GunFireInterval.Value:0.##}s"; } private static bool Load() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown if (_loadFailed) { return false; } if (_pistol != null && _bullet != null) { return true; } try { _pistol = Prepare(ObjModel.FromEmbeddedResource("SlipSkid.MoreCards.Pistol.obj", "SlipSkid.MoreCards.Pistol.mtl", "CustomPistol"), "pistol"); _bullet = Prepare(ObjModel.FromEmbeddedResource("SlipSkid.MoreCards.Bullet.obj", null, "CustomBullet"), "bullet"); return true; } catch (Exception ex) { _loadFailed = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[gun] could not load the bundled models: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); return false; } } private static Prepared Prepare(ObjModel model, string label) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = model.Mesh.bounds; Prepared prepared = new Prepared { Model = model, BaseRotation = ModelOrientation.LongestAxisForward(bounds), Extent = ModelOrientation.LongestExtent(bounds) }; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(67, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[gun] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(label); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" model loaded: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(model.Mesh.vertexCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" verts, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(model.Mesh.subMeshCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" submesh(es), size "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref bounds)).size); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("aiming axis "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(prepared.Extent, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" long"); } log.LogInfo(val); return prepared; } public static void Equip(PlayerData owner) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) if (!Load()) { return; } Transform val = CarMeasure.CarOf(owner); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[gun] " + (((owner != null) ? owner.DisplayName : null) ?? "a player") + " drafted GUN! but has no car to mount it on right now, so nothing was equipped.")); return; } if ((Object)(object)((Component)val).GetComponentInChildren(true) != (Object)null) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[gun] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted((owner != null) ? owner.DisplayName : null); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" already has a gun; leaving it alone."); } log.LogInfo(val2); return; } Material val3 = ObjMaterials.TemplateFrom(val); if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"[gun] no material on the car to clone a shader from; the gun may render untinted. This usually means the car had not finished spawning."); } GameObject val4 = new GameObject("ModGun"); val4.transform.SetParent(val, false); val4.layer = ((Component)val).gameObject.layer; val4.AddComponent(); Transform meshChild = BuildMeshChild(val4.transform, _pistol, ObjMaterials.Build(_pistol.Model, val3, "gun"), "gun"); CarGun carGun = val4.AddComponent(); carGun.Car = val; carGun.Owner = owner; carGun.MeshChild = meshChild; carGun.BulletMaterials = ObjMaterials.Build(_bullet.Model, val3, "bullet", BrassColor); Plugin.Log.LogInfo((object)("[gun] equipped " + (((owner != null) ? owner.DisplayName : null) ?? "a player") + " — firing every " + $"{ModConfig.GunFireInterval.Value:0.##}s. Tune it under [Gun] in the config " + "and press the ReloadConfigKey; a mounted gun re-reads its position live.")); } internal static Transform BuildMeshChild(Transform parent, Prepared prepared, Material[] materials, string name) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name + "Mesh"); val.transform.SetParent(parent, false); val.layer = ((Component)parent).gameObject.layer; val.AddComponent().sharedMesh = prepared.Model.Mesh; MeshRenderer val2 = val.AddComponent(); if (materials != null) { ((Renderer)val2).materials = materials; } val.transform.localRotation = prepared.BaseRotation; return val.transform; } internal static void FitMeshChild(Transform mesh, Prepared prepared, float length) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)mesh == (Object)null) && prepared != null && !(prepared.Extent <= 0.0001f)) { float num = length / prepared.Extent; mesh.localScale = new Vector3(num, num, num); Quaternion baseRotation = prepared.BaseRotation; Bounds bounds = prepared.Model.Mesh.bounds; mesh.localPosition = -(baseRotation * (((Bounds)(ref bounds)).center * num)); } } } internal static class SwatterModel { internal readonly struct SwatterShape { public readonly Bounds Pad; public readonly Vector3 Grip; public readonly Vector3 ArmAxis; public readonly Vector3 FaceAxis; public readonly float PadWidth; public readonly float HandleThickness; public readonly float PadReach; public bool IsValid { get { if (PadWidth > 1E-06f) { return PadReach > 1E-06f; } return false; } } public SwatterShape(Bounds pad, Vector3 grip, Vector3 armAxis, Vector3 faceAxis, float padWidth, float handleThickness, float padReach) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) Pad = pad; Grip = grip; ArmAxis = armAxis; FaceAxis = faceAxis; PadWidth = padWidth; HandleThickness = handleThickness; PadReach = padReach; } } private const string ObjResource = "SlipSkid.MoreCards.Flyswatter.obj"; private const string MtlResource = "SlipSkid.MoreCards.Flyswatter.mtl"; private const int Slices = 32; private const float PadWidthFraction = 0.5f; private const float HubInHandles = 3f; private const string SolidChildName = "SwatterSolid"; private const float PadColliderThickness = 0.35f; private static ObjModel _model; private static bool _loadFailed; private static SwatterShape _shape; private static ObjModel Model() { //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) if (_model != null || _loadFailed) { return _model; } bool flag = default(bool); try { _model = ObjModel.FromEmbeddedResource("SlipSkid.MoreCards.Flyswatter.obj", "SlipSkid.MoreCards.Flyswatter.mtl", "CustomFlyswatter"); _shape = Measure(_model.Mesh); Bounds bounds = _model.Mesh.bounds; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(75, 8, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[swatter] model loaded: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_model.Mesh.vertexCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" verts, size "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref bounds)).size); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Pad "); Bounds pad = _shape.Pad; ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref pad)).size); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at "); pad = _shape.Pad; ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref pad)).center); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", grip "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_shape.Grip); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("arm "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_shape.ArmAxis); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", face "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_shape.FaceAxis); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", reach "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_shape.PadReach, "0.###"); } log.LogInfo(val); if (!_shape.IsValid) { Plugin.Log.LogError((object)"[swatter] the model's pad could not be told from its handle, so there is nothing to swing. Is the mesh a single flat blob?"); _loadFailed = true; _model = null; } } catch (Exception ex) { _loadFailed = true; ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[swatter] could not load the bundled model: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log2.LogError(val2); } return _model; } public static void Apply(Obstacle obstacle) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Expected O, but got Unknown //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Expected O, but got Unknown //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) ObjModel objModel = Model(); if (objModel == null || (Object)(object)obstacle == (Object)null) { return; } PropReskin.Neutralise(obstacle); MeshFilter[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { Plugin.Log.LogWarning((object)("[swatter] carrier '" + ((Object)obstacle).name + "' has no MeshFilter to replace; the card will place an unmodified carrier.")); return; } if (!PropReskin.TryGetWorldBounds(componentsInChildren, out var bounds)) { ((Bounds)(ref bounds))..ctor(((Component)obstacle).transform.position, Vector3.one); } MeshFilter val = PropReskin.TakeOverRenderers(componentsInChildren); MeshRenderer component = ((Component)val).GetComponent(); val.sharedMesh = objModel.Mesh; string ownerName; Color val2 = OwnerColour(obstacle, out ownerName); bool flag = default(bool); if ((Object)(object)component != (Object)null) { if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[swatter] cloning "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ObjMaterials.Describe(((Renderer)component).sharedMaterial)); } log.LogInfo(val3); } ((Renderer)component).materials = ObjMaterials.Build(objModel, ((Renderer)component).sharedMaterial, "swatter" + ColourKey(val2), val2, untextured: true, opaque: true, doubleSided: true); } Transform transform = ((Component)obstacle).transform; Vector3 footprintLocal = transform.InverseTransformPoint(new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).center.z)); Swatter swatter = ((Component)obstacle).gameObject.GetComponent(); if ((Object)(object)swatter == (Object)null) { swatter = ((Component)obstacle).gameObject.AddComponent(); } swatter.Root = transform; swatter.Model = ((Component)val).transform; swatter.Shape = _shape; swatter.FootprintLocal = footprintLocal; swatter.ColourKey = ColourKey(val2); int num = FitSwingColliders(((Component)val).transform, CarrierLayer(obstacle, transform)); swatter.Resize(log: true); swatter.Pose(); if (ModConfig.Verbose.Value) { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(68, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[swatter] "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" swinging collider(s) on the pad and handle, plus the post"); } log2.LogInfo(val3); } if (ModConfig.Verbose.Value) { ManualLogSource log3 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(37, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[swatter] re-skinned '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Object)obstacle).name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' in "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ownerName); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'s colour "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Color32.op_Implicit(val2)); } log3.LogInfo(val3); } } public static void OnObstacleColors(Obstacle obstacle, Color32 primary, Color32 secondary) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)obstacle == (Object)null) { return; } Color colour; bool flag = PlayerPaint.TryPickIdentity(primary, secondary, out colour); if (flag) { PlayerPaint.Announce(((Object)obstacle).GetInstanceID(), colour); } if (ModConfig.Verbose.Value) { Plugin.Log.LogInfo((object)($"[swatter] the game painted '{((Object)obstacle).name}' primary {primary} secondary " + $"{secondary}" + (flag ? $" -> using {Color32.op_Implicit(colour)}" : " -> neither is set"))); } Swatter component = ((Component)obstacle).GetComponent(); if ((Object)(object)component == (Object)null || !flag) { return; } string text = ColourKey(colour); if (!(text == component.ColourKey)) { Transform model = component.Model; MeshRenderer val = (((Object)(object)model != (Object)null) ? ((Component)model).GetComponent() : null); if (!((Object)(object)val == (Object)null) && _model != null) { ((Renderer)val).materials = ObjMaterials.Build(_model, ((Renderer)val).sharedMaterial, "swatter" + text, colour, untextured: true, opaque: true, doubleSided: true); component.ColourKey = text; Plugin.Log.LogInfo((object)($"[swatter] repainted '{((Object)obstacle).name}' to {Color32.op_Implicit(colour)} — the game announced " + "its owner's colours after we dressed it.")); } } } private static Color OwnerColour(Obstacle obstacle, out string ownerName) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) PlayerData val = CustomCards.OwnerOf(obstacle); ownerName = (((Object)(object)val != (Object)null) ? (val.DisplayName ?? "a player") : "an unknown player"); if (PlayerPaint.TryAnnounced(((Object)obstacle).GetInstanceID(), out var colour)) { Plugin.Log.LogInfo((object)($"[swatter] painting {ownerName}'s swatter {Color32.op_Implicit(colour)} " + "(the colours the game gave the obstacle)")); return colour; } if (PlayerPaint.TryIdentityColour(val, out var colour2, out var source)) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(38, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[swatter] painting "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ownerName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s swatter "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Color32.op_Implicit(colour2)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (from "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(source); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } log.LogInfo(val2); return colour2; } Color result = Color.red; if (_model != null && _model.MaterialNames.Length != 0 && _model.MaterialColors.TryGetValue(_model.MaterialNames[0], out var value)) { result = value; } Plugin.Log.LogWarning((object)("[swatter] no usable colour for " + ownerName + " on '" + ((Object)obstacle).name + "', so it keeps the model's own red and whose swatter it is will not be obvious. Every source was empty: " + PlayerPaint.Describe(val))); return result; } private static string ColourKey(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Color32 val = Color32.op_Implicit(c); return $"#{val.r:x2}{val.g:x2}{val.b:x2}"; } internal static float WorldScale(bool log) { if (!_shape.IsValid) { return 1f; } float value = ModConfig.SwatterWidth.Value; bool measured; float num = CarMeasure.ReferenceLength(out measured); float num2 = ((value > 0.0001f) ? value : (num * ModConfig.SwatterScale.Value)); float num3 = num2 / _shape.PadWidth; if (num3 <= 0.0001f || float.IsNaN(num3) || float.IsInfinity(num3)) { num3 = 1f; } if (log) { Plugin.Log.LogInfo((object)($"[swatter] swatter sized: pad {num2:0.00} units across and " + $"{_shape.PadWidth * num3:0.00} tall, sweeping " + $"{_shape.PadReach * num3 * ModConfig.SwatterReach.Value:0.00} units out " + ((value > 0.0001f) ? "(SwatterWidth, fixed)" : ($"(SwatterScale {ModConfig.SwatterScale.Value:0.###} x " + string.Format("{0} player car {1:0.00}). ", measured ? "measured" : "assumed", num) + "Set SwatterScale, SwatterReach or SwatterWidth in the [Swatter] section to change it, then press ReloadConfigKey.")))); } return num3; } internal static void RefitPost(Swatter swatter, Vector3 pivotWorld, float postHeight, float scale) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)swatter == (Object)null) && !((Object)(object)swatter.Root == (Object)null)) { Obstacle component = ((Component)swatter.Root).GetComponent(); if (!((Object)(object)component == (Object)null)) { FitCollision(component, swatter.Root, pivotWorld, postHeight, scale); } } } private static int CarrierLayer(Obstacle obstacle, Transform root) { Collider[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if ((Object)(object)val != (Object)null && !val.isTrigger && val.enabled) { return ((Component)val).gameObject.layer; } } return ((Component)root).gameObject.layer; } private static int FitCollision(Obstacle obstacle, Transform root, Vector3 pivotWorld, float postHeight, float scale) { //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(_shape.HandleThickness * 3f * scale, 0.01f); float num2 = Mathf.Max(postHeight, num); List list = new List(); List list2 = new List(); Collider[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !val.isTrigger && val.enabled && !(((Object)((Component)val).gameObject).name == "SwatterSolid")) { BoxCollider val2 = (BoxCollider)(object)((val is BoxCollider) ? val : null); if (val2 != null) { list.Add(val2); } else { list2.Add(val); } } } if (list.Count == 0) { GameObject val3 = new GameObject("SwatterPost"); val3.layer = ((list2.Count > 0) ? ((Component)list2[0]).gameObject.layer : ((Component)root).gameObject.layer); val3.transform.SetParent(root, false); val3.transform.localPosition = root.InverseTransformPoint(pivotWorld); val3.transform.localRotation = Quaternion.identity; val3.transform.localScale = Vector3.one; list.Add(val3.AddComponent()); } Vector3 val4 = pivotWorld - root.up * (num2 * 0.5f); foreach (BoxCollider item in list) { Transform transform = ((Component)item).transform; Vector3 lossyScale = transform.lossyScale; item.center = transform.InverseTransformPoint(val4); item.size = new Vector3(num / PropReskin.NonZero(lossyScale.x), num2 / PropReskin.NonZero(lossyScale.y), num / PropReskin.NonZero(lossyScale.z)); } foreach (Collider item2 in list2) { item2.enabled = false; } return list.Count; } private static int FitSwingColliders(Transform model, int layer) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)model == (Object)null || !_shape.IsValid) { return 0; } Transform val = null; for (int i = 0; i < model.childCount; i++) { Transform child = model.GetChild(i); if ((Object)(object)child != (Object)null && ((Object)child).name == "SwatterSolid") { val = child; break; } } if ((Object)(object)val == (Object)null) { val = new GameObject("SwatterSolid") { layer = layer }.transform; val.SetParent(model, false); val.localPosition = Vector3.zero; val.localRotation = Quaternion.identity; val.localScale = Vector3.one; } int num = AxisIndex(_shape.FaceAxis); int num2 = AxisIndex(_shape.ArmAxis); int num3 = 3 - num - num2; BoxCollider[] components = ((Component)val).GetComponents(); BoxCollider obj = ((components.Length != 0) ? components[0] : ((Component)val).gameObject.AddComponent()); BoxCollider val2 = ((components.Length > 1) ? components[1] : ((Component)val).gameObject.AddComponent()); Bounds pad = _shape.Pad; Vector3 size = ((Bounds)(ref pad)).size; ((Vector3)(ref size))[num] = Mathf.Max(((Vector3)(ref size))[num], _shape.PadWidth * 0.35f); pad = _shape.Pad; obj.center = ((Bounds)(ref pad)).center; obj.size = size; Vector3 val3 = _shape.ArmAxis; float num4; if (!(((Vector3)(ref val3))[num2] < 0f)) { pad = _shape.Pad; val3 = ((Bounds)(ref pad)).min; num4 = ((Vector3)(ref val3))[num2]; } else { pad = _shape.Pad; val3 = ((Bounds)(ref pad)).max; num4 = ((Vector3)(ref val3))[num2]; } float num5 = num4; Vector3 grip = _shape.Grip; val3 = _shape.Grip; ((Vector3)(ref grip))[num2] = (((Vector3)(ref val3))[num2] + num5) * 0.5f; Vector3 zero = Vector3.zero; val3 = _shape.Grip; ((Vector3)(ref zero))[num2] = Mathf.Abs(((Vector3)(ref val3))[num2] - num5); ((Vector3)(ref zero))[num3] = _shape.HandleThickness; ((Vector3)(ref zero))[num] = _shape.HandleThickness; val2.center = grip; val2.size = zero; return 2; } private static int AxisIndex(Vector3 axis) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (Mathf.Abs(axis.x) > 0.5f) { return 0; } if (Mathf.Abs(axis.y) > 0.5f) { return 1; } return 2; } private static SwatterShape Measure(Mesh mesh) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = mesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; int num = 0; if (size.y > ((Vector3)(ref size))[num]) { num = 1; } if (size.z > ((Vector3)(ref size))[num]) { num = 2; } int num2 = 0; if (size.y < ((Vector3)(ref size))[num2]) { num2 = 1; } if (size.z < ((Vector3)(ref size))[num2]) { num2 = 2; } if (num2 == num) { num2 = (num + 1) % 3; } int num3 = 3 - num - num2; Vector3[] vertices = mesh.vertices; Vector3 val = ((Bounds)(ref bounds)).min; float num4 = ((Vector3)(ref val))[num]; float num5 = ((Vector3)(ref size))[num]; if (num5 <= 1E-06f || vertices.Length == 0) { return default(SwatterShape); } float num6 = num5 / 32f; float[] array = new float[32]; float[] array2 = new float[32]; for (int i = 0; i < 32; i++) { array[i] = float.PositiveInfinity; array2[i] = float.NegativeInfinity; } Vector3[] array3 = vertices; for (int j = 0; j < array3.Length; j++) { Vector3 val2 = array3[j]; int num7 = Mathf.Clamp((int)((((Vector3)(ref val2))[num] - num4) / num6), 0, 31); float num8 = ((Vector3)(ref val2))[num3]; if (num8 < array[num7]) { array[num7] = num8; } if (num8 > array2[num7]) { array2[num7] = num8; } } float num9 = 0f; for (int k = 0; k < 32; k++) { if (!float.IsInfinity(array[k])) { num9 = Mathf.Max(num9, array2[k] - array[k]); } } if (num9 <= 1E-06f) { return default(SwatterShape); } float num10 = num9 * 0.5f; int num11 = 0; int num12 = 0; for (int l = 0; l < 32; l++) { if (!float.IsInfinity(array[l]) && !(array2[l] - array[l] < num10)) { if (l < 16) { num11++; } else { num12++; } } } if (num11 == 0 && num12 == 0) { return default(SwatterShape); } bool flag = num11 >= num12; Bounds val3 = default(Bounds); bool flag2 = false; Bounds val4 = default(Bounds); bool flag3 = false; float num13; if (!flag) { val = ((Bounds)(ref bounds)).min; num13 = ((Vector3)(ref val))[num]; } else { val = ((Bounds)(ref bounds)).max; num13 = ((Vector3)(ref val))[num]; } float num14 = num13; array3 = vertices; for (int j = 0; j < array3.Length; j++) { Vector3 val5 = array3[j]; int num15 = Mathf.Clamp((int)((((Vector3)(ref val5))[num] - num4) / num6), 0, 31); bool num16 = !float.IsInfinity(array[num15]) && array2[num15] - array[num15] >= num10; bool flag4 = (flag ? (num15 < 16) : (num15 >= 16)); if (num16 && flag4) { if (!flag2) { ((Bounds)(ref val3))..ctor(val5, Vector3.zero); flag2 = true; } else { ((Bounds)(ref val3)).Encapsulate(val5); } } if (Mathf.Abs(((Vector3)(ref val5))[num] - num14) <= num6) { if (!flag3) { ((Bounds)(ref val4))..ctor(val5, Vector3.zero); flag3 = true; } else { ((Bounds)(ref val4)).Encapsulate(val5); } } } if (!flag2 || !flag3) { return default(SwatterShape); } Vector3 center = ((Bounds)(ref val4)).center; ((Vector3)(ref center))[num] = num14; Vector3 zero = Vector3.zero; ((Vector3)(ref zero))[num] = (flag ? (-1f) : 1f); Vector3 zero2 = Vector3.zero; ((Vector3)(ref zero2))[num2] = 1f; val = ((Bounds)(ref val3)).center; float padReach = Mathf.Abs(((Vector3)(ref val))[num] - num14); val = ((Bounds)(ref val4)).size; float num17 = ((Vector3)(ref val))[num3]; val = ((Bounds)(ref val4)).size; float num18 = Mathf.Max(num17, ((Vector3)(ref val))[num2]); if (num18 <= 1E-06f) { num18 = ((Vector3)(ref size))[num2]; } Bounds pad = val3; Vector3 grip = center; Vector3 armAxis = zero; Vector3 faceAxis = zero2; val = ((Bounds)(ref val3)).size; return new SwatterShape(pad, grip, armAxis, faceAxis, ((Vector3)(ref val))[num3], num18, padReach); } } internal static class TreeModel { private const string ObjResource = "SlipSkid.MoreCards.Tree.obj"; private const string MtlResource = "SlipSkid.MoreCards.Tree.mtl"; private const string BarkMaterial = "Bark"; private const string LeavesMaterial = "Leaves"; private const string CollisionChildName = "TreeCollision"; private const int TrunkSegments = 4; private const int MaxCanopySpheres = 8; private const int BarkBands = 24; private const float BranchFanArea = 2f; private static ObjModel _model; private static bool _loadFailed; private static ObjModel Model() { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (_model != null || _loadFailed) { return _model; } bool flag = default(bool); try { _model = ObjModel.FromEmbeddedResource("SlipSkid.MoreCards.Tree.obj", "SlipSkid.MoreCards.Tree.mtl", "CustomTree"); Bounds bounds = _model.Mesh.bounds; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[tree] model loaded: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_model.Mesh.vertexCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" verts, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_model.Mesh.subMeshCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" submesh(es) ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(string.Join(", ", _model.MaterialNames)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("size "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Bounds)(ref bounds)).size); } log.LogInfo(val); } catch (Exception ex) { _loadFailed = true; ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[tree] could not load the bundled model: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log2.LogError(val2); } return _model; } public static void Apply(Obstacle obstacle) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) ObjModel objModel = Model(); if (objModel == null || (Object)(object)obstacle == (Object)null) { return; } PropReskin.Neutralise(obstacle); MeshFilter[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { Plugin.Log.LogWarning((object)("[tree] carrier '" + ((Object)obstacle).name + "' has no MeshFilter to replace; the card will place an unmodified carrier.")); return; } if (!PropReskin.TryGetWorldBounds(componentsInChildren, out var bounds)) { ((Bounds)(ref bounds))..ctor(((Component)obstacle).transform.position, Vector3.one); } MeshFilter val = PropReskin.TakeOverRenderers(componentsInChildren); MeshRenderer component = ((Component)val).GetComponent(); val.sharedMesh = objModel.Mesh; if ((Object)(object)component != (Object)null) { ((Renderer)component).materials = ObjMaterials.Build(objModel, ((Renderer)component).sharedMaterial, "tree", null, untextured: true); } float num = PlaceModel(((Component)val).transform, ((Component)obstacle).transform, objModel.Mesh, bounds); int num2 = FitColliders(obstacle, ((Component)val).transform, objModel, num); if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(67, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[tree] re-skinned '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)obstacle).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': world scale "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num, "0.000"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("tree size "); Bounds bounds2 = objModel.Mesh.bounds; ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Bounds)(ref bounds2)).size * num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" collider(s) fitted"); } log.LogInfo(val2); } } private static float PlaceModel(Transform model, Transform root, Mesh mesh, Bounds carrier) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = mesh.bounds; float y = ((Bounds)(ref bounds)).size.y; if (y <= 0.0001f) { return 1f; } float num = TargetHeight() / y; if (num <= 0.0001f || float.IsNaN(num) || float.IsInfinity(num)) { num = 1f; } model.rotation = root.rotation; Vector3 val = (((Object)(object)model.parent != (Object)null) ? model.parent.lossyScale : Vector3.one); model.localScale = new Vector3(num / PropReskin.NonZero(val.x), num / PropReskin.NonZero(val.y), num / PropReskin.NonZero(val.z)); bounds = mesh.bounds; float x = ((Bounds)(ref bounds)).center.x; bounds = mesh.bounds; float y2 = ((Bounds)(ref bounds)).min.y; bounds = mesh.bounds; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(x, y2, ((Bounds)(ref bounds)).center.z); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(((Bounds)(ref carrier)).center.x, ((Bounds)(ref carrier)).min.y, ((Bounds)(ref carrier)).center.z); model.position = val3 - model.rotation * (val2 * num); return num; } private static float TargetHeight() { float value = ModConfig.TreeHeight.Value; bool measured; float num = CarMeasure.ReferenceLength(out measured); float num2 = ((value > 0.0001f) ? value : (num * ModConfig.TreeScale.Value)); Plugin.Log.LogInfo((object)($"[tree] tree sized: {num2:0.00} units tall " + ((value > 0.0001f) ? "(TreeHeight, fixed)" : ($"(TreeScale {ModConfig.TreeScale.Value:0.###} x " + string.Format("{0} player car {1:0.00}). ", measured ? "measured" : "assumed", num) + "Set Cards.TreeScale to change it.")))); return num2; } private static int FitColliders(Obstacle obstacle, Transform model, ObjModel obj, float scale) { //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Expected O, but got Unknown //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) Vector3[] vertices = obj.Mesh.vertices; List list = CanopyBlobs(obj, vertices); List list2 = TrunkColumn(obj, vertices, list); List list3 = new List(); List list4 = new List(); List list5 = new List(); Collider val = null; Collider[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || val2.isTrigger || !val2.enabled) { continue; } if ((Object)(object)val == (Object)null) { val = val2; } BoxCollider val3 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null); if (val3 != null) { list3.Add(val3); continue; } SphereCollider val4 = (SphereCollider)(object)((val2 is SphereCollider) ? val2 : null); if (val4 != null) { list4.Add(val4); } else { list5.Add(val2); } } Transform val5 = null; if (list3.Count < list2.Count || list4.Count < list.Count) { val5 = CollisionHost(model, val); } while (list3.Count < list2.Count) { list3.Add(((Component)val5).gameObject.AddComponent()); } while (list4.Count < list.Count) { list4.Add(((Component)val5).gameObject.AddComponent()); } int num = 0; for (int j = 0; j < list3.Count; j++) { FitBox(list3[j], model, list2[j % list2.Count]); num++; } if (list.Count == 0) { Plugin.Log.LogWarning((object)"[tree] no 'Leaves' submesh, so the canopy has no collider. Was the model re-converted without its material groups?"); foreach (SphereCollider item in list4) { list5.Add((Collider)(object)item); } } else { for (int k = 0; k < list4.Count; k++) { FitSphere(list4[k], model, list[k % list.Count], scale); num++; } } foreach (Collider item2 in list5) { item2.enabled = false; } if (ModConfig.Verbose.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(92, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[tree] collision: "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(list2.Count); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" trunk box(es) up to y "); Bounds val7 = list2[list2.Count - 1]; ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(((Bounds)(ref val7)).max.y, "0.0"); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" canopy sphere(s), "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(list5.Count); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" carrier shape(s) switched off"); } log.LogInfo(val6); } return num; } private static Transform CollisionHost(Transform model, Collider carrier) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < model.childCount; i++) { Transform child = model.GetChild(i); if ((Object)(object)child != (Object)null && ((Object)child).name == "TreeCollision") { return child; } } Transform transform = new GameObject("TreeCollision") { layer = (((Object)(object)carrier != (Object)null) ? ((Component)carrier).gameObject.layer : ((Component)model).gameObject.layer) }.transform; transform.SetParent(model, false); transform.localPosition = Vector3.zero; transform.localRotation = Quaternion.identity; transform.localScale = Vector3.one; return transform; } private static void FitBox(BoxCollider box, Transform model, Bounds meshSpace) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)box).transform; Vector3 min = ((Bounds)(ref meshSpace)).min; Vector3 max = ((Bounds)(ref meshSpace)).max; Bounds val = default(Bounds); Vector3 val2 = default(Vector3); for (int i = 0; i < 8; i++) { ((Vector3)(ref val2))..ctor(((i & 1) == 0) ? min.x : max.x, ((i & 2) == 0) ? min.y : max.y, ((i & 4) == 0) ? min.z : max.z); Vector3 val3 = transform.InverseTransformPoint(model.TransformPoint(val2)); if (i == 0) { ((Bounds)(ref val))..ctor(val3, Vector3.zero); } else { ((Bounds)(ref val)).Encapsulate(val3); } } box.center = ((Bounds)(ref val)).center; box.size = ((Bounds)(ref val)).size; } private static void FitSphere(SphereCollider sphere, Transform model, Bounds meshSpace, float scale) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)sphere).transform; Vector3 lossyScale = transform.lossyScale; float v = Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Max(Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z))); sphere.center = transform.InverseTransformPoint(model.TransformPoint(((Bounds)(ref meshSpace)).center)); sphere.radius = BlobRadius(meshSpace) * scale / PropReskin.NonZero(v); } private static float BlobRadius(Bounds blob) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Vector3 extents = ((Bounds)(ref blob)).extents; return (extents.x + extents.y + extents.z) / 3f; } private static List CanopyBlobs(ObjModel obj, Vector3[] vertices) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) List list = new List(); int num = Array.IndexOf(obj.MaterialNames, "Leaves"); if (num < 0 || num >= obj.Mesh.subMeshCount) { return list; } int[] triangles = obj.Mesh.GetTriangles(num); if (triangles.Length < 3) { return list; } Bounds bounds = obj.Mesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float grid = ((Vector3)(ref size)).magnitude * 0.0001f; Dictionary dictionary = new Dictionary(); Dictionary dictionary2 = new Dictionary(); List list2 = new List(); List list3 = new List(); int[] array = triangles; foreach (int num2 in array) { if (num2 >= 0 && num2 < vertices.Length && !dictionary.ContainsKey(num2)) { long key = GridKey(vertices[num2], grid); if (!dictionary2.TryGetValue(key, out var value)) { value = (dictionary2[key] = list2.Count); list2.Add(value); list3.Add(vertices[num2]); } dictionary[num2] = value; } } for (int j = 0; j + 2 < triangles.Length; j += 3) { if (dictionary.TryGetValue(triangles[j], out var value2) && dictionary.TryGetValue(triangles[j + 1], out var value3) && dictionary.TryGetValue(triangles[j + 2], out var value4)) { Union(list2, value2, value3); Union(list2, value3, value4); } } Dictionary dictionary3 = new Dictionary(); for (int k = 0; k < list2.Count; k++) { int key2 = Find(list2, k); if (dictionary3.TryGetValue(key2, out var value5)) { ((Bounds)(ref value5)).Encapsulate(list3[k]); dictionary3[key2] = value5; } else { dictionary3[key2] = new Bounds(list3[k], Vector3.zero); } } foreach (Bounds value6 in dictionary3.Values) { Bounds current = value6; size = ((Bounds)(ref current)).size; if (((Vector3)(ref size)).sqrMagnitude > 1E-06f) { list.Add(current); } } return MergeDownTo(list, 8); } private static List MergeDownTo(List blobs, int cap) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (blobs.Count <= cap) { return blobs; } blobs.Sort(delegate(Bounds a, Bounds b) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Vector3 extents2 = ((Bounds)(ref b)).extents; float sqrMagnitude2 = ((Vector3)(ref extents2)).sqrMagnitude; extents2 = ((Bounds)(ref a)).extents; return sqrMagnitude2.CompareTo(((Vector3)(ref extents2)).sqrMagnitude); }); List range = blobs.GetRange(0, cap); for (int num = cap; num < blobs.Count; num++) { int index = 0; float num2 = float.PositiveInfinity; for (int num3 = 0; num3 < range.Count; num3++) { Bounds val = range[num3]; ((Bounds)(ref val)).Encapsulate(blobs[num]); Vector3 extents = ((Bounds)(ref val)).extents; float sqrMagnitude = ((Vector3)(ref extents)).sqrMagnitude; Bounds val2 = range[num3]; extents = ((Bounds)(ref val2)).extents; float num4 = sqrMagnitude - ((Vector3)(ref extents)).sqrMagnitude; if (num4 < num2) { num2 = num4; index = num3; } } Bounds value = range[index]; ((Bounds)(ref value)).Encapsulate(blobs[num]); range[index] = value; } return range; } private static List TrunkColumn(ObjModel obj, Vector3[] vertices, List canopy) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List list2 = SubmeshVertices(obj, vertices, "Bark"); if (list2.Count == 0) { list.Add(obj.Mesh.bounds); return list; } float num = float.PositiveInfinity; float num2 = float.NegativeInfinity; foreach (Vector3 item in list2) { if (item.y < num) { num = item.y; } if (item.y > num2) { num2 = item.y; } } float num3 = Mathf.Min(num2, BoleCeiling(list2, num, num2, canopy)); for (int i = 0; i < 4; i++) { float num4 = Mathf.Lerp(num, num3, (float)i / 4f); float num5 = Mathf.Lerp(num, num3, (float)(i + 1) / 4f); if (BandBounds(list2, num4, num5, num, num3, out var bounds)) { list.Add(new Bounds(new Vector3(((Bounds)(ref bounds)).center.x, (num4 + num5) / 2f, ((Bounds)(ref bounds)).center.z), new Vector3(((Bounds)(ref bounds)).size.x, Mathf.Max(num5 - num4, 0.0001f), ((Bounds)(ref bounds)).size.z))); } } if (list.Count == 0) { list.Add(BandBounds(list2, num, num2, num, num2, out var bounds2) ? bounds2 : obj.Mesh.bounds); } return list; } private static float BoleCeiling(List bark, float bottom, float top, List canopy) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) float num = float.PositiveInfinity; foreach (Bounds item in canopy) { Bounds current = item; if (((Bounds)(ref current)).min.y < num) { num = ((Bounds)(ref current)).min.y; } } float num2 = (top - bottom) / 24f; if (num2 <= 0.0001f) { return top; } if (!BandBounds(bark, bottom, bottom + num2, bottom, top, out var bounds)) { return top; } float num3 = Mathf.Max(((Bounds)(ref bounds)).size.x * ((Bounds)(ref bounds)).size.z, 1E-06f); for (int i = 1; i < 24; i++) { float num4 = bottom + num2 * (float)i; if (BandBounds(bark, num4, num4 + num2, bottom, top, out var bounds2) && !(((Bounds)(ref bounds2)).size.x * ((Bounds)(ref bounds2)).size.z <= num3 * 2f)) { if (!float.IsPositiveInfinity(num)) { return Mathf.Max(num4, num); } return num4; } } return top; } private static bool BandBounds(List bark, float lo, float hi, float limitLo, float limitHi, out Bounds bounds) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) float num = float.NegativeInfinity; float num2 = float.PositiveInfinity; foreach (Vector3 item in bark) { if (item.y < lo && item.y >= limitLo && item.y > num) { num = item.y; } if (item.y > hi && item.y <= limitHi && item.y < num2) { num2 = item.y; } } bounds = default(Bounds); bool flag = false; foreach (Vector3 item2 in bark) { bool num3 = item2.y >= lo - 0.0001f && item2.y <= hi + 0.0001f; bool flag2 = Mathf.Abs(item2.y - num) <= 0.0001f || Mathf.Abs(item2.y - num2) <= 0.0001f; if (num3 || flag2) { if (!flag) { bounds = new Bounds(item2, Vector3.zero); flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(item2); } } } return flag; } private static List SubmeshVertices(ObjModel obj, Vector3[] vertices, string material) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) List list = new List(); int num = Array.IndexOf(obj.MaterialNames, material); if (num < 0 || num >= obj.Mesh.subMeshCount) { return list; } HashSet hashSet = new HashSet(); int[] triangles = obj.Mesh.GetTriangles(num); foreach (int num2 in triangles) { if (num2 >= 0 && num2 < vertices.Length && hashSet.Add(num2)) { list.Add(vertices[num2]); } } return list; } private static long GridKey(Vector3 v, float grid) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(grid, 1E-06f); long num2 = Mathf.RoundToInt(v.x / num) & 0x1FFFFF; long num3 = Mathf.RoundToInt(v.y / num) & 0x1FFFFF; long num4 = Mathf.RoundToInt(v.z / num) & 0x1FFFFF; return (num2 << 42) | (num3 << 21) | num4; } private static int Find(List parent, int i) { while (parent[i] != i) { parent[i] = parent[parent[i]]; i = parent[i]; } return i; } private static void Union(List parent, int a, int b) { int num = Find(parent, a); int num2 = Find(parent, b); if (num != num2) { parent[num2] = num; } } } }