Decompiled source of zPaulinsWeaponArsenal v1.0.1
BepInEx\plugins\HowToFish.WeaponArsenal\HowToFish.ModKit.dll
Decompiled 2 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx.Logging; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("HowToFish.ModKit")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+5554268e42ae4803814c23b41e24d3c196693022")] [assembly: AssemblyProduct("HowToFish.ModKit")] [assembly: AssemblyTitle("How to Fish - Mod Kit runtime")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HowToFish.ModKit { public static class BundleLoader { private static readonly Dictionary<string, AssetBundle> Loaded = new Dictionary<string, AssetBundle>(StringComparer.OrdinalIgnoreCase); public static ManualLogSource Log { get; set; } public static string PluginDirectoryOf(object plugin) { return Path.GetDirectoryName(plugin.GetType().Assembly.Location); } public static AssetBundle Load(object plugin, string bundleFileName) { return LoadFrom(Path.Combine(PluginDirectoryOf(plugin), bundleFileName)); } public static AssetBundle LoadFrom(string fullPath) { string fullPath2 = Path.GetFullPath(fullPath); if (Loaded.TryGetValue(fullPath2, out var value) && (Object)(object)value != (Object)null) { return value; } if (!File.Exists(fullPath2)) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("Asset bundle not found: " + fullPath2)); } return null; } AssetBundle val = AssetBundle.LoadFromFile(fullPath2); if ((Object)(object)val == (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogError((object)("Failed to load asset bundle: " + fullPath2 + ". It was most likely built with a different Unity version than 6000.4.x.")); } return null; } Loaded[fullPath2] = val; ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)$"Loaded bundle {Path.GetFileName(fullPath2)} ({val.GetAllAssetNames().Length} assets)"); } return val; } public static T Asset<T>(AssetBundle bundle, string name) where T : Object { if ((Object)(object)bundle == (Object)null) { return default(T); } T val = bundle.LoadAsset<T>(name); if ((Object)(object)val == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("Asset '" + name + "' of type " + typeof(T).Name + " not found in bundle. Available: " + string.Join(", ", bundle.GetAllAssetNames()))); } return default(T); } object obj = val; GameObject val2 = (GameObject)((obj is GameObject) ? obj : null); if (val2 != null) { ShaderFix.Apply(val2); } else { object obj2 = val; Material val3 = (Material)((obj2 is Material) ? obj2 : null); if (val3 != null) { ShaderFix.Apply(val3); } } return val; } public static GameObject Prefab(AssetBundle bundle, string name) { return BundleLoader.Asset<GameObject>(bundle, name); } public static void UnloadAll(bool unloadLoadedObjects = false) { foreach (AssetBundle value in Loaded.Values) { if ((Object)(object)value != (Object)null) { value.Unload(unloadLoadedObjects); } } Loaded.Clear(); } } public static class ShaderFix { private static readonly Dictionary<string, Shader> Cache = new Dictionary<string, Shader>(); public static bool Enabled = true; public static void Apply(GameObject root) { if (!Enabled || (Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material[] sharedMaterials = val.sharedMaterials; foreach (Material material in sharedMaterials) { Apply(material); } } } public static void Apply(Material material) { if (!Enabled || (Object)(object)material == (Object)null || (Object)(object)material.shader == (Object)null) { return; } string name = ((Object)material.shader).name; if (!Cache.TryGetValue(name, out var value)) { value = Shader.Find(name); Cache[name] = value; } if ((Object)(object)value == (Object)null) { ManualLogSource log = BundleLoader.Log; if (log != null) { log.LogWarning((object)("Shader '" + name + "' is not present in the game build; material '" + ((Object)material).name + "' will render incorrectly. Author it with a URP shader the game already uses (Universal Render Pipeline/Lit).")); } } else { int renderQueue = material.renderQueue; material.shader = value; material.renderQueue = renderQueue; } } } }
BepInEx\plugins\HowToFish.WeaponArsenal\HowToFish.WeaponArsenal.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FishNet; using FishNet.Managing; using FishNet.Managing.Object; using FishNet.Object; using HarmonyLib; using HowToFish.ModKit; using HowToFish.WeaponArsenal.Arsenal; using HowToFish.WeaponArsenal.Assets; using HowToFish.WeaponArsenal.Patches; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [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("HowToFish.WeaponArsenal")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+6cb5338874bba59a68beef237a2c7fbf6e227e13")] [assembly: AssemblyProduct("HowToFish.WeaponArsenal")] [assembly: AssemblyTitle("HowToFish.WeaponArsenal")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HowToFish.WeaponArsenal { internal sealed class ModConfig { public readonly ConfigEntry<bool> Enabled; public readonly ConfigEntry<bool> VerboseLogging; public readonly ConfigEntry<ushort> PrefabCollectionId; public readonly ConfigEntry<string> ShopIslandName; public readonly ConfigEntry<int> ShopIslandIndex; public readonly ConfigEntry<float> ShopFallbackSpacing; public readonly ConfigEntry<bool> LiveTuning; public readonly ConfigEntry<string> SourceWeaponsFolder; public ModConfig(ConfigFile f) { Enabled = f.Bind<bool>("01 - General", "Enabled", true, "Master switch. When off no custom weapons are built or registered, and the game behaves exactly as it does without the mod installed."); VerboseLogging = f.Bind<bool>("01 - General", "VerboseLogging", false, "Log every base weapon prefab found and every stat applied. Worth turning on once while authoring a new weapon def, and off again afterwards."); PrefabCollectionId = f.Bind<ushort>("02 - Multiplayer", "PrefabCollectionId", (ushort)4100, "FishNet spawnable-prefab collection the mod's weapons are registered into. The mod deliberately uses its own collection rather than appending to the game's, so vanilla prefab indices never shift.\n\nEvery player in a lobby must run the same mod version with the same weapons folder: a networked prefab is identified by its index within the collection, so a different arsenal on another client resolves to a different weapon. Compare the fingerprint from /wa status between players to confirm they match."); ShopIslandName = f.Bind<string>("03 - Shop", "ShopIslandName", "", "Island scene name, or any part of it, that sells the mod's weapons. Takes precedence over ShopIslandIndex when it matches. Run /wa islands in game to see the real scene names - the last island by index is not the volcano."); ShopIslandIndex = f.Bind<int>("03 - Shop", "ShopIslandIndex", -1, "Island index that sells the mod's weapons, used when ShopIslandName is empty or does not match. -1 means the last playable island, skipping DevIsland, which sits at the highest index but is not part of the game."); ShopFallbackSpacing = f.Bind<float>("03 - Shop", "ShopFallbackSpacing", 1f, "Metres between stands, used only when the island has a single weapon stand to measure against. With two or more the spacing is taken from the real gap between them, so the new stands line up with the existing rack."); SourceWeaponsFolder = f.Bind<string>("04 - Development", "SourceWeaponsFolder", "", "Repository weapons folder, if you develop this mod from source. '/wa fit save' normally writes only to the deployed plugin folder, where the next build overwrites it from the repo copy - silently losing tuned values. Set this and save writes to both. Leave empty if you only installed the mod."); LiveTuning = f.Bind<bool>("04 - Development", "LiveTuning", true, "Enable the /wa fit commands, which rebake a weapon's mesh alignment in game without a rebuild. This is how the scale, position and rotation numbers in a weapon def are meant to be found - by eye, on screen, rather than by guessing and recompiling."); } } [BepInPlugin("com.zpaulin.howtofish.weaponarsenal", "zPaulin's Weapon Arsenal", "1.0.1")] [BepInProcess("How to Fish.exe")] public sealed class Plugin : BaseUnityPlugin { private Harmony _harmony; private GameObject _host; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ModConfig Cfg { get; private set; } internal static WeaponRegistry Registry { get; private set; } internal static ArsenalRuntime Runtime { get; private set; } internal static string WeaponsFolder { get; private set; } private void Awake() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0089: 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_009b: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Cfg = new ModConfig(((BaseUnityPlugin)this).Config); WeaponsFolder = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "weapons"); Registry = new WeaponRegistry(); Registry.Load(WeaponsFolder); _harmony = new Harmony("com.zpaulin.howtofish.weaponarsenal"); _harmony.PatchAll(typeof(Plugin).Assembly); _host = new GameObject("HowToFish.WeaponArsenal.Runtime") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)(object)_host); Runtime = _host.AddComponent<ArsenalRuntime>(); try { string location = typeof(Plugin).Assembly.Location; Log.LogInfo((object)("BUILD STAMP: " + File.GetLastWriteTime(location).ToString("yyyy-MM-dd HH:mm:ss") + " from " + location)); } catch (Exception ex) { Log.LogWarning((object)("could not stamp build: " + ex.Message)); } Log.LogInfo((object)("zPaulin's Weapon Arsenal v1.0.1 loaded - " + Registry.Defs.Count + " weapon def(s), fingerprint " + Registry.Fingerprint)); } private void OnDestroy() { if ((Object)(object)_host != (Object)null) { Object.Destroy((Object)(object)_host); } if (_harmony != null) { _harmony.UnpatchSelf(); } } } public static class PluginInfo { public const string Guid = "com.zpaulin.howtofish.weaponarsenal"; public const string Name = "zPaulin's Weapon Arsenal"; public const string Version = "1.0.1"; public const string CommandRoot = "wa"; } internal static class Refl { private static readonly Dictionary<string, FieldInfo> FieldCache = new Dictionary<string, FieldInfo>(); private static readonly HashSet<string> Warned = new HashSet<string>(); public static FieldInfo Field(Type type, string name) { string text = type.FullName + "." + name; if (FieldCache.TryGetValue(text, out var value)) { return value; } value = AccessTools.Field(type, name); FieldCache[text] = value; if (value == null && Warned.Add(text)) { Plugin.Log.LogWarning((object)("Field not found: " + text + " - the game may have changed. That value will be left alone.")); } return value; } public static bool Set<T>(object target, string name, T? value) where T : struct { if (!value.HasValue || target == null) { return false; } return SetRaw(target, name, value.Value); } public static bool SetRaw(object target, string name, object value) { if (target == null) { return false; } FieldInfo fieldInfo = Field(target.GetType(), name); if (fieldInfo == null) { return false; } try { fieldInfo.SetValue(target, value); return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to set " + target.GetType().Name + "." + name + ": " + ex.Message)); return false; } } public static object Get(object target, string name) { if (target == null) { return null; } FieldInfo fieldInfo = Field(target.GetType(), name); if (fieldInfo == null) { return null; } try { return fieldInfo.GetValue(target); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to read " + target.GetType().Name + "." + name + ": " + ex.Message)); return null; } } public static T GetAs<T>(object target, string name) where T : class { return Get(target, name) as T; } public static bool SetProperty(object target, string name, object value) { if (target == null) { return false; } PropertyInfo propertyInfo = AccessTools.Property(target.GetType(), name); if (propertyInfo == null || !propertyInfo.CanWrite) { string text = target.GetType().FullName + "::" + name; if (Warned.Add(text)) { Plugin.Log.LogWarning((object)("Property not writable: " + text)); } return false; } try { propertyInfo.SetValue(target, value, null); return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to set property " + target.GetType().Name + "." + name + ": " + ex.Message)); return false; } } } } namespace HowToFish.WeaponArsenal.Patches { [HarmonyPatch(typeof(Attachments), "InitAttachments")] internal static class AttachmentsInitPatch { [HarmonyPostfix] private static void Postfix(Attachments __instance) { if (Plugin.Cfg == null || !Plugin.Cfg.Enabled.Value) { return; } ArsenalWeapon componentInParent = ((Component)__instance).GetComponentInParent<ArsenalWeapon>(true); if ((Object)(object)componentInParent == (Object)null) { return; } WeaponDef def = componentInParent.Def; if (def == null || def.Attachments == null || !(Refl.Get(__instance, "_attachmentCosts") is Dictionary<AttachmentInfo, int> dictionary)) { return; } int num = 0; AttachmentsDef attachments = def.Attachments; if (!attachments.Sights) { num += RemoveList<Sight>(dictionary, Refl.Get(__instance, "_sights") as IEnumerable<Sight>, 1); } if (!attachments.Barrels) { num += RemoveList<BarrelAttachment>(dictionary, Refl.Get(__instance, "_barrelAttachments") as IEnumerable<BarrelAttachment>, 1); } if (!attachments.Laser) { object obj = Refl.Get(__instance, "_laserSight"); LaserSight val = (LaserSight)((obj is LaserSight) ? obj : null); if ((Object)(object)val != (Object)null && (Object)(object)((Attachment)val).Info != (Object)null && dictionary.Remove(((Attachment)val).Info)) { num++; } } if (!attachments.ExtendedMag) { object obj2 = Refl.Get(__instance, "_extendedMagInfo"); AttachmentInfo val2 = (AttachmentInfo)((obj2 is AttachmentInfo) ? obj2 : null); if ((Object)(object)val2 != (Object)null && dictionary.Remove(val2)) { num++; } } if (num > 0 && Plugin.Cfg.VerboseLogging.Value) { Plugin.Log.LogInfo((object)("Blocked " + num + " attachment(s) on " + def.Id + ".")); } } private static int RemoveList<T>(Dictionary<AttachmentInfo, int> costs, IEnumerable<T> items, int skip) where T : Attachment { if (items == null) { return 0; } int num = 0; int num2 = 0; foreach (T item in items) { if (num2++ >= skip && !((Object)(object)item == (Object)null) && !((Object)(object)((Attachment)item).Info == (Object)null) && costs.Remove(((Attachment)item).Info)) { num++; } } return num; } } [HarmonyPatch(typeof(AudioManager), "Start")] internal static class AudioManagerStartPatch { [HarmonyPostfix] private static void Postfix() { SoundLibrary.ReapplyAll(); } } [HarmonyPatch(typeof(DazedCommands), "IsServerCommand")] internal static class CommandPatches { [HarmonyPrefix] private static bool Prefix(string __0, ref bool __result) { if (string.IsNullOrEmpty(__0)) { return true; } string text = __0.Trim(); if (text.StartsWith("/")) { text = text.Substring(1); } string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { return true; } if (!string.Equals(array[0], "wa", StringComparison.OrdinalIgnoreCase)) { return true; } Plugin.Log.LogInfo((object)("command: " + text)); try { Dispatch(array); } catch (Exception ex) { Say("error: " + ex.Message); Plugin.Log.LogError((object)("Command '" + __0 + "' threw: " + ex)); } __result = true; return false; } private static void Dispatch(string[] parts) { string text = ((parts.Length > 1) ? parts[1].ToLowerInvariant() : "status"); switch (text) { case "status": Status(); break; case "list": List(); break; case "bases": Bases(); break; case "give": Give(parts); break; case "inspect": Inspect(parts); break; case "shop": Shop(); break; case "islands": Islands(); break; case "prop": Prop(parts); break; case "bones": Bones(parts); break; case "part": Part(parts); break; case "anchors": Anchors(parts); break; case "ik": Ik(parts); break; case "pose": Pose(parts); break; case "grip": Grip(parts); break; case "slide": Slide(parts); break; case "paths": Paths(parts); break; case "charge": Charge(parts); break; case "forge": Forge(parts); break; case "ads": Ads(parts); break; case "auto": Auto(parts); break; case "reload": Reload(); break; case "fit": Fit(parts); break; case "help": Help(); break; default: Say("unknown subcommand '" + text + "'."); Help(); break; } } private static void Status() { WeaponRegistry registry = Plugin.Registry; Say("zPaulin's Weapon Arsenal v1.0.1" + (Plugin.Cfg.Enabled.Value ? "" : " [DISABLED]")); Say("defs: " + registry.Defs.Count + " | fingerprint: " + registry.Fingerprint); Say("prefabs: " + ModPrefabRegistry.Status()); Say(BaseWeaponIndex.Ready ? ("bases: " + BaseWeaponIndex.WeaponNames.Count + " indexed") : "bases: not indexed yet"); if (registry.LoadErrors.Count > 0) { Say(registry.LoadErrors.Count + " def(s) rejected:"); foreach (string loadError in registry.LoadErrors) { Say(" " + loadError); } } Say("compare the fingerprint with other players - it must match to play together."); } private static void List() { ArsenalRuntime runtime = Plugin.Runtime; if (Plugin.Registry.Defs.Count == 0) { Say("no weapon defs loaded."); return; } foreach (WeaponDef def in Plugin.Registry.Defs) { BuiltWeapon builtWeapon = (((Object)(object)runtime == (Object)null) ? null : runtime.Find(def.Id)); Say(((builtWeapon != null) ? "[ok] " : "[--] ") + def.Describe() + ((builtWeapon != null) ? (" | scale " + def.Model.Scale.ToString("F3", CultureInfo.InvariantCulture)) : "")); } } private static void Bases() { if (!BaseWeaponIndex.Ready) { Say("base weapon index not built yet - load into a game first."); return; } Say(BaseWeaponIndex.Summary()); Say("use one of these names as \"basePrefab\" in a weapon def."); } private static void Inspect(string[] parts) { if (parts.Length < 3) { Say("usage: /wa inspect <basePrefabName|weaponId>"); Bases(); return; } string text = JoinRest(parts, 2); BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(text)); if (builtWeapon != null) { string text2 = PrefabInspector.Dump(builtWeapon.Prefab, (Item)(object)builtWeapon.Weapon, "built:" + text); Say("dumped built '" + text + "' to the BepInEx log - " + text2); return; } NetworkObject val = BaseWeaponIndex.Find(text); if ((Object)(object)val == (Object)null) { Say("no base prefab or built weapon called '" + text + "'."); Bases(); } else { Item componentInChildren = ((Component)val).GetComponentInChildren<Item>(true); string text3 = PrefabInspector.Dump(((Component)val).gameObject, componentInChildren, "base:" + text); Say("dumped base '" + text + "' to the BepInEx log - " + text3); } } private static void Auto(string[] parts) { if (parts.Length < 3) { Say("usage: /wa auto <id> [align|hands] - solves both and saves when given neither"); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } string text = ((parts.Length > 3) ? parts[3].ToLowerInvariant() : null); bool alignModel = text == null || text == "align"; bool snapHands = text == null || text == "hands"; Say(AutoSolver.Solve(builtWeapon, alignModel, snapHands)); if (text == null) { Save(builtWeapon.Def); Say("solved and saved. respawn the weapon if it is already in your hands."); } else { Say("looks right? /wa fit " + builtWeapon.Def.Id + " save"); } } private static void Ads(string[] parts) { //IL_0097: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0289: 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_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0213: 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_021d: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: 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_01e4: 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_01ed: 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_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) if (parts.Length < 3) { Say("usage: /wa ads <id> nudge up|down|left|right|forward|back <n> | set <x> <y> <z> | show | reset | save"); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } string text = ((parts.Length > 3) ? parts[3].ToLowerInvariant() : "show"); switch (text) { case "save": Save(builtWeapon.Def); return; case "show": Say(builtWeapon.Def.Id + " ads " + Vec3(WeaponBuilder.CurrentAds(builtWeapon)) + ((builtWeapon.Def.Ads == null) ? " (the base weapon's own)" : " (from the def)")); return; case "reset": builtWeapon.Def.Ads = null; Say("def override cleared - respawn the weapon to get the base value back."); return; } Vector3 val = WeaponBuilder.CurrentAds(builtWeapon); Vector3 value; if (text == "set") { if (!TryParseVector(parts, 4, out value)) { Say("usage: /wa ads " + builtWeapon.Def.Id + " set <x> <y> <z>"); return; } } else { if (!(text == "nudge")) { Say("unknown ads option '" + text + "'."); return; } if (parts.Length < 6 || !TryParse(parts[5], out var value2)) { Say("usage: /wa ads " + builtWeapon.Def.Id + " nudge up|down|left|right|forward|back <n>"); return; } Vector3 val2; switch (parts[4].ToLowerInvariant()) { case "right": val2 = Vector3.right; break; case "left": val2 = Vector3.left; break; case "up": val2 = Vector3.up; break; case "down": val2 = Vector3.down; break; case "forward": val2 = Vector3.forward; break; case "back": val2 = Vector3.back; break; default: Say("direction must be up, down, left, right, forward or back."); return; } value = val + val2 * value2; } builtWeapon.Def.Ads = new float[3] { value.x, value.y, value.z }; WeaponBuilder.ApplyAds(builtWeapon); Say("ads " + Vec3(val) + " -> " + Vec3(value) + ". aim to check; /wa ads " + builtWeapon.Def.Id + " save"); } private static void Forge(string[] parts) { if (parts.Length < 3) { Say("usage: /wa forge <id> [charge] | restore"); Say(" plain rebuilds the clip exactly as recorded - use it to check the rebuild itself."); Say(" 'charge' additionally rewrites the racking segment. 'restore' puts the game's clip back."); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } string text = ((parts.Length > 3) ? parts[3].ToLowerInvariant() : ""); if (text == "restore") { Say(ClipForge.Restore() ? "the weapon's own clip is back." : "nothing to restore - the clip in use is already the game's."); return; } ClipForge.ApplyCharge = text == "charge"; if (ClipForge.ApplyCharge && (builtWeapon.Def.Ik == null || builtWeapon.Def.Ik.ChargeLeft == null)) { Say("measure the handle first: /wa charge " + builtWeapon.Def.Id + ", then a full reload."); return; } HandDriver handDriver = null; HandDriver[] array = Resources.FindObjectsOfTypeAll<HandDriver>(); foreach (HandDriver handDriver2 in array) { if (!((Object)(object)handDriver2 == (Object)null)) { ArsenalWeapon componentInChildren = ((Component)handDriver2).GetComponentInChildren<ArsenalWeapon>(true); if (!((Object)(object)componentInChildren == (Object)null) && string.Equals(componentInChildren.WeaponId, builtWeapon.Def.Id, StringComparison.OrdinalIgnoreCase) && ((Component)handDriver2).gameObject.activeInHierarchy) { handDriver = handDriver2; break; } } } if ((Object)(object)handDriver == (Object)null || (Object)(object)handDriver.Anim == (Object)null) { Say("hold the weapon first - the clip is rebuilt from the one that is in your hands."); return; } ClipForge.Begin(builtWeapon, handDriver.Anim, ((Component)handDriver).transform); Say("do a FULL reload now - recording" + (ClipForge.ApplyCharge ? " and rewriting the charge." : " a faithful copy.")); } private static void Charge(string[] parts) { if (parts.Length < 3) { Say("usage: /wa charge <id> [show|clear] - measure where this model's charging"); Say("handle is and steer the hand onto it during the racking frames of the reload."); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } string text = ((parts.Length > 3) ? parts[3].ToLowerInvariant() : "learn"); IkDef ik = builtWeapon.Def.Ik; if (text == "show") { if (ik == null || ik.ChargeLeft == null) { Say("no charge offset measured."); return; } Say("charge " + Vec(ik.ChargeLeft) + " over " + Num(ik.ChargeFrom) + "-" + Num(ik.ChargePeak) + "-" + Num(ik.ChargeTo) + " of '" + ik.ChargeClip + "' | grip returns at " + Num(ik.GripReturnAt)); } else if (text == "clear") { if (ik != null) { ik.ChargeLeft = null; } WeaponBuilder.SyncIkOnLiveInstances(builtWeapon); Say("charge offset cleared; the clip racks wherever the base weapon does."); } else { HandDriver.LearningCharge = true; Say("hold the weapon and do a FULL reload now - watching where it racks."); } } private static void Paths(string[] parts) { if (parts.Length < 3) { Say("usage: /wa paths <id>"); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); } else { Say(AnimationLibrary.DumpPaths(builtWeapon)); } } private static void Slide(string[] parts) { //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: 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) if (parts.Length < 3) { Say("usage: /wa slide <id> learn|keep|clear|travel <v>|time <v>|show|save"); Say(" learn watches the next reload and copies the rack it performs."); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } if (builtWeapon.Def.Slide == null) { builtWeapon.Def.Slide = new SlideDef(); } SlideDef slide = builtWeapon.Def.Slide; string text = ((parts.Length > 3) ? parts[3].ToLowerInvariant() : "show"); switch (text) { case "save": Save(builtWeapon.Def); return; case "show": Say(builtWeapon.Def.Id + ": travel " + Num(slide.Travel) + " | time " + Num(slide.Time) + ((slide.Offset == null) ? "" : (" | offset " + Vec(slide.Offset)))); return; case "learn": SlideDriver.Learning = true; Say("watching the next reload - reload now, then /wa slide " + builtWeapon.Def.Id + " keep"); return; case "keep": { SlideDriver slideDriver = FindDriver(builtWeapon); if ((Object)(object)slideDriver == (Object)null || !slideDriver.Captured(out var travel, out var duration)) { Say("nothing measured yet - run /wa slide " + builtWeapon.Def.Id + " learn and reload."); return; } slide.Offset = new float[3] { travel.x, travel.y, travel.z }; slide.Time = duration; WeaponBuilder.ApplySlide(builtWeapon); WeaponBuilder.SyncLiveInstances(builtWeapon); Say("kept " + Vec(slide.Offset) + " over " + Num(slide.Time) + "s. fire to compare; /wa slide " + builtWeapon.Def.Id + " save"); return; } case "clear": slide.Offset = null; WeaponBuilder.ApplySlide(builtWeapon); WeaponBuilder.SyncLiveInstances(builtWeapon); Say("measured offset cleared; back to the fire-point direction."); return; } if (parts.Length < 5 || !TryParse(parts[4], out var value)) { Say("usage: /wa slide " + builtWeapon.Def.Id + " " + text + " <value>"); return; } switch (text) { case "travel": slide.Travel = value; break; case "offsetx": slide.Offset = Store(slide.Offset, 0, value); break; case "offsety": slide.Offset = Store(slide.Offset, 1, value); break; case "offsetz": slide.Offset = Store(slide.Offset, 2, value); break; case "time": slide.Time = Mathf.Max(0.01f, value); break; default: Say("unknown slide option '" + text + "'."); return; } WeaponBuilder.ApplySlide(builtWeapon); WeaponBuilder.SyncLiveInstances(builtWeapon); Say(builtWeapon.Def.Id + ": travel " + Num(slide.Travel) + " | time " + Num(slide.Time) + ". fire once to see it; /wa slide " + builtWeapon.Def.Id + " save"); } private static SlideDriver FindDriver(BuiltWeapon built) { SlideDriver[] array = Resources.FindObjectsOfTypeAll<SlideDriver>(); foreach (SlideDriver slideDriver in array) { if (!((Object)(object)slideDriver == (Object)null)) { ArsenalWeapon componentInChildren = ((Component)slideDriver).GetComponentInChildren<ArsenalWeapon>(true); if ((Object)(object)componentInChildren != (Object)null && string.Equals(componentInChildren.WeaponId, built.Def.Id, StringComparison.OrdinalIgnoreCase)) { return slideDriver; } } } return null; } private static float[] Store(float[] existing, int index, float value) { float[] obj = ((existing != null && existing.Length >= 3) ? existing : new float[3]); obj[index] = value; return obj; } private static void Grip(string[] parts) { if (parts.Length < 3) { Say("usage: /wa grip <id> [left|right] [save]"); Say("wraps the fingers onto the weapon's real surface, measured from the live skeleton."); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } bool flag = true; bool flag2 = false; for (int i = 3; i < parts.Length; i++) { switch (parts[i].ToLowerInvariant()) { case "right": flag = false; break; case "left": flag = true; break; case "save": flag2 = true; break; } } Say(GripSolver.Solve(builtWeapon, flag, apply: true, out var pose)); if (pose.Count != 0) { WeaponBuilder.SyncLiveInstances(builtWeapon); if (flag2) { Save(builtWeapon.Def); } else { Say("looks right? /wa grip " + builtWeapon.Def.Id + (flag ? "" : " right") + " save"); } } } private static void Pose(string[] parts) { //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) if (parts.Length < 4) { Say("usage: /wa pose <id> <boneName> <x> <y> <z> | show | bones [filter] | clear | save"); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } string text = parts[3]; switch (text.ToLowerInvariant()) { case "save": Save(builtWeapon.Def); return; case "clear": builtWeapon.Def.Pose = null; WeaponBuilder.ApplyPose(builtWeapon); Say("pose cleared; the base hand pose is back. respawn the weapon to be sure."); return; case "show": if (builtWeapon.Def.Pose == null || builtWeapon.Def.Pose.Count == 0) { Say("no pose overrides."); return; } { foreach (KeyValuePair<string, float[]> item in builtWeapon.Def.Pose) { Say(" " + item.Key + " " + Vec(item.Value)); } return; } case "bones": { string text2 = ((parts.Length > 4) ? parts[4].ToLowerInvariant() : null); List<string> list = WeaponBuilder.BoneNames(builtWeapon); int num = 0; foreach (string item2 in list) { if (text2 == null || item2.ToLowerInvariant().IndexOf(text2) >= 0) { Say(" " + item2); if (++num >= 20) { Say(" ... " + list.Count + " total; pass a filter to narrow."); break; } } } if (num == 0) { Say("no bone matched. " + list.Count + " bones total."); } return; } } if (!TryParseVector(parts, 4, out var value)) { Say("usage: /wa pose " + builtWeapon.Def.Id + " " + text + " <x> <y> <z>"); Say("current: " + Vec3(WeaponBuilder.CurrentLocalEuler(builtWeapon, text))); return; } if (builtWeapon.Def.Pose == null) { builtWeapon.Def.Pose = new Dictionary<string, float[]>(); } builtWeapon.Def.Pose[text] = new float[3] { value.x, value.y, value.z }; WeaponBuilder.ApplyPose(builtWeapon); Say(text + " -> " + Vec3(value) + ". looks right? /wa pose " + builtWeapon.Def.Id + " save"); } private static void Ik(string[] parts) { //IL_00f1: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) if (parts.Length < 4) { Say("usage: /wa ik <id> left|right <x> <y> <z> (or 'show', or 'save')"); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } string text = parts[3].ToLowerInvariant(); int num; switch (text) { case "save": Save(builtWeapon.Def); return; case "show": { bool[] array = new bool[2] { true, false }; foreach (bool flag in array) { Transform val = WeaponBuilder.FindIkTarget(builtWeapon, flag); if ((Object)(object)val == (Object)null) { Say((flag ? "l_IK " : "r_IK ") + "(missing)"); continue; } string[] obj = new string[5] { flag ? "l_IK " : "r_IK ", "pos ", Vec3(val.localPosition), " | rot ", null }; Quaternion localRotation = val.localRotation; obj[4] = Vec3(((Quaternion)(ref localRotation)).eulerAngles); Say(string.Concat(obj)); } return; } case "chargenudge": ChargeNudge(builtWeapon, parts); return; case "chargewindow": case "gripreturn": ChargeWindow(builtWeapon, text, parts); return; default: num = ((text == "reloadleftrot") ? 1 : 0); break; case "leftrot": case "rightrot": num = 1; break; } int num2; switch (text) { default: num2 = ((text == "chargeleft") ? 1 : 0); break; case "left": case "right": case "reloadleft": num2 = 1; break; } bool flag2 = (byte)num2 != 0; if (num == 0 && !flag2) { Say("usage: /wa ik <id> left|right|leftrot|rightrot|reloadleft|reloadleftrot <x> <y> <z>"); Say(" reloadleft steers the hand during the reload clip only - it is a delta on top"); Say(" of the animation, so 0 0 0 means 'play it exactly as the developers made it'."); return; } if (!TryParseVector(parts, 4, out var value)) { Say("usage: /wa ik " + builtWeapon.Def.Id + " " + text + " <x> <y> <z>"); return; } if (builtWeapon.Def.Ik == null) { builtWeapon.Def.Ik = new IkDef(); } float[] array2 = new float[3] { value.x, value.y, value.z }; switch (text) { case "left": builtWeapon.Def.Ik.Left = array2; break; case "right": builtWeapon.Def.Ik.Right = array2; break; case "leftrot": builtWeapon.Def.Ik.LeftRotation = array2; break; case "reloadleft": builtWeapon.Def.Ik.ReloadLeft = array2; break; case "reloadleftrot": builtWeapon.Def.Ik.ReloadLeftRotation = array2; break; case "chargeleft": builtWeapon.Def.Ik.ChargeLeft = array2; break; default: builtWeapon.Def.Ik.RightRotation = array2; break; } WeaponBuilder.ApplyIk(builtWeapon); WeaponBuilder.SyncIkOnLiveInstances(builtWeapon); Say(text + " -> " + Vec3(value) + ". looks right? /wa ik " + builtWeapon.Def.Id + " save"); } private static void ChargeWindow(BuiltWeapon built, string op, string[] parts) { if (built.Def.Ik == null) { built.Def.Ik = new IkDef(); } IkDef ik = built.Def.Ik; if (op == "gripreturn") { if (parts.Length < 5 || !TryParse(parts[4], out var value)) { Say("usage: /wa ik " + built.Def.Id + " gripreturn <0..1> (now " + Num(ik.GripReturnAt) + ")"); return; } ik.GripReturnAt = Mathf.Clamp01(value); } else { if (parts.Length < 7 || !TryParse(parts[4], out var value2) || !TryParse(parts[5], out var value3) || !TryParse(parts[6], out var value4)) { Say("usage: /wa ik " + built.Def.Id + " chargewindow <from> <peak> <to>"); Say(" now " + Num(ik.ChargeFrom) + " " + Num(ik.ChargePeak) + " " + Num(ik.ChargeTo)); return; } ik.ChargeFrom = Mathf.Clamp01(value2); ik.ChargePeak = Mathf.Clamp01(value3); ik.ChargeTo = Mathf.Clamp01(value4); } WeaponBuilder.SyncIkOnLiveInstances(built); Say("window " + Num(ik.ChargeFrom) + "-" + Num(ik.ChargePeak) + "-" + Num(ik.ChargeTo) + " | grip returns at " + Num(ik.GripReturnAt) + ". reload to check; /wa ik " + built.Def.Id + " save"); } private static void ChargeNudge(BuiltWeapon built, string[] parts) { //IL_00ec: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_015d: 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_00fb: 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_0105: 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_019e: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: 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_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: 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_0123: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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_023e: Unknown result type (might be due to invalid IL or missing references) if (parts.Length < 6 || !TryParse(parts[5], out var value)) { Say("usage: /wa ik " + built.Def.Id + " chargenudge left|right|up|down|forward|back <amount>"); return; } Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.CamObject == (Object)null) { Say("no local player to take directions from."); return; } Transform val = WeaponBuilder.FindIkTarget(built, left: true); if ((Object)(object)val == (Object)null || (Object)(object)val.parent == (Object)null) { Say("no l_IK on this weapon."); return; } Transform camObject = localPlayer.CamObject; Vector3 val2; switch (parts[4].ToLowerInvariant()) { case "right": val2 = camObject.right; break; case "left": val2 = -camObject.right; break; case "up": val2 = camObject.up; break; case "down": val2 = -camObject.up; break; case "forward": val2 = camObject.forward; break; case "back": val2 = -camObject.forward; break; default: Say("direction must be left, right, up, down, forward or back."); return; } Vector3 val3 = val.parent.InverseTransformDirection(val2); Vector3 val4 = ((Vector3)(ref val3)).normalized * value; if (built.Def.Ik == null) { built.Def.Ik = new IkDef(); } IkDef ik = built.Def.Ik; Vector3 val5 = (Vector3)((ik.ChargeLeft != null && ik.ChargeLeft.Length >= 3) ? new Vector3(ik.ChargeLeft[0], ik.ChargeLeft[1], ik.ChargeLeft[2]) : Vector3.zero); Vector3 val6 = val5 + val4; ik.ChargeLeft = new float[3] { val6.x, val6.y, val6.z }; WeaponBuilder.SyncIkOnLiveInstances(built); bool flag = ClipForge.HasRecording && ClipForge.ApplyCharge && ClipForge.Rebake(); Say("charge " + Vec3(val5) + " -> " + Vec3(val6) + " (" + parts[4] + " " + Num(value) + ")"); Say(flag ? ("clip re-baked - reload to see it; /wa ik " + built.Def.Id + " save") : ("reload to check; /wa ik " + built.Def.Id + " save")); } private static void Anchors(string[] parts) { //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_01e7: 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_0229: 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_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) if (parts.Length < 3) { Say("usage: /wa anchors <id>"); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } if (builtWeapon.Targets.Count == 0) { Say("weapon has no model target."); return; } ModelSwapTarget modelSwapTarget = builtWeapon.Targets[0]; Transform val = (((Object)(object)modelSwapTarget.Skinned != (Object)null && (Object)(object)modelSwapTarget.Skinned.rootBone != (Object)null) ? modelSwapTarget.Skinned.rootBone : builtWeapon.Prefab.transform); Plugin.Log.LogInfo((object)("=== anchors: " + builtWeapon.Def.Id + " (space = '" + ((Object)val).name + "') ===")); Transform[] componentsInChildren = builtWeapon.Prefab.GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { string name = ((Object)val2).name; if (name.EndsWith("_IK") || name == "Gun" || name == "Mag" || name == "Slide") { Plugin.Log.LogInfo((object)(" " + name + " at " + Vec3(val.InverseTransformPoint(val2.position)))); } } string[] array = new string[3] { "_firePoint", "_adsPos", "_aimPos" }; foreach (string text in array) { object obj = Refl.Get(builtWeapon.Weapon, text); Transform val3 = (Transform)((obj is Transform) ? obj : null); if (!((Object)(object)val3 == (Object)null)) { Plugin.Log.LogInfo((object)(" " + text + " at " + Vec3(val.InverseTransformPoint(val3.position)))); } } Mesh fittedMesh = modelSwapTarget.FittedMesh; if ((Object)(object)fittedMesh != (Object)null) { ManualLogSource log = Plugin.Log; Bounds bounds = fittedMesh.bounds; string text2 = Vec3(((Bounds)(ref bounds)).center); bounds = fittedMesh.bounds; log.LogInfo((object)(" fitted mesh centre " + text2 + ", size " + Vec3(((Bounds)(ref bounds)).size))); } Say("dumped anchors for '" + builtWeapon.Def.Id + "' to the BepInEx log."); } private static string Vec3(Vector3 v) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; return "(" + v.x.ToString("F2", invariantCulture) + ", " + v.y.ToString("F2", invariantCulture) + ", " + v.z.ToString("F2", invariantCulture) + ")"; } private static string JoinRest(string[] parts, int start) { return string.Join(" ", parts, start, parts.Length - start).Trim().Trim(new char[1] { '"' }); } private static void Part(string[] parts) { //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) if (parts.Length < 4) { Say("usage: /wa part <id> <index|next|all>"); return; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(parts[2])); if (builtWeapon == null) { Say("no built weapon '" + parts[2] + "'."); return; } int num = 0; int[] array = ((builtWeapon.Model == null) ? null : builtWeapon.Model.GroupIds); if (array != null) { int[] array2 = array; foreach (int num2 in array2) { if (num2 + 1 > num) { num = num2 + 1; } } } if (num == 0) { Say("model has no part information."); return; } string text = parts[3].ToLowerInvariant(); if (text == "all") { builtWeapon.IsolatePart = -1; } else if (text == "next") { builtWeapon.IsolatePart = (builtWeapon.IsolatePart + 1) % num; } else { if (!int.TryParse(text, out var result) || result < 0 || result >= num) { Say("index must be 0.." + (num - 1) + ", 'next' or 'all'."); return; } builtWeapon.IsolatePart = result; } WeaponBuilder.Refit(builtWeapon); WeaponBuilder.SyncLiveInstances(builtWeapon); if (builtWeapon.IsolatePart < 0) { Say("showing the whole model again (" + num + " parts)"); return; } Say("showing ONLY part " + builtWeapon.IsolatePart + " of " + (num - 1) + " - is this the magazine?"); if (builtWeapon.Targets.Count > 0 && (Object)(object)builtWeapon.Targets[0].FittedMesh != (Object)null) { Bounds bounds = builtWeapon.Targets[0].FittedMesh.bounds; int num3 = builtWeapon.Targets[0].FittedMesh.triangles.Length / 3; string text2 = "part " + builtWeapon.IsolatePart + ": " + num3 + " tris, centre " + Vec3(((Bounds)(ref bounds)).center) + ", size " + Vec3(((Bounds)(ref bounds)).size); Say(text2); Plugin.Log.LogInfo((object)text2); } } private static void Bones(string[] parts) { float value = 6f; if (parts.Length > 2) { TryParse(parts[2], out value); } value = Mathf.Clamp(value, 1f, 30f); Say(BoneRecorder.Start(value)); } private static void Prop(string[] parts) { //IL_05b6: Unknown result type (might be due to invalid IL or missing references) //IL_05c0: Unknown result type (might be due to invalid IL or missing references) //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Unknown result type (might be due to invalid IL or missing references) //IL_05fc: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_0647: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_038e: 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_064c: Unknown result type (might be due to invalid IL or missing references) //IL_064e: Unknown result type (might be due to invalid IL or missing references) //IL_0650: Unknown result type (might be due to invalid IL or missing references) //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Unknown result type (might be due to invalid IL or missing references) //IL_0662: Unknown result type (might be due to invalid IL or missing references) //IL_066c: Unknown result type (might be due to invalid IL or missing references) //IL_0676: Unknown result type (might be due to invalid IL or missing references) //IL_0640: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) if (parts.Length < 3 || string.Equals(parts[2], "list", StringComparison.OrdinalIgnoreCase)) { if (PropPlacer.All.Count == 0) { Say("no props defined - add weapons/props.json"); return; } foreach (PropDef item in PropPlacer.All) { GameObject val = PropPlacer.LiveObject(item.Id); Say(item.Id + (item.Enabled ? "" : " [disabled]") + " scale " + item.Scale + (((Object)(object)val != (Object)null) ? " [placed]" : " [not here]")); } Say("/wa prop <id> pos|rot <x> <y> <z> | height <m> | scale <v> | nudge <dx> <dy> <dz> | here | show | save"); return; } string text = parts[2]; PropDef propDef = PropPlacer.Find(text); if (propDef == null) { Say("no prop '" + text + "' - /wa prop list"); return; } string text2 = ((parts.Length > 3) ? parts[3].ToLowerInvariant() : "show"); switch (text2) { case "show": Say(propDef.Id + " pos " + VecText(propDef.Position) + " rot " + VecText(propDef.Rotation) + (propDef.TargetHeight.HasValue ? (" height " + propDef.TargetHeight.Value + " m") : (" scale " + propDef.Scale))); break; case "reload": PropPlacer.Load(); Say(PropPlacer.PlaceNow()); break; case "save": Say(PropPlacer.Save()); break; case "here": { Player localPlayer = Player.LocalPlayer; Camera val3 = (((Object)(object)localPlayer != (Object)null) ? localPlayer.CurCam : null); if ((Object)(object)val3 == (Object)null) { Say("no local player camera - load into a game first"); break; } Transform transform = ((Component)val3).transform; Vector3 val4 = transform.position + transform.forward * 2.5f; RaycastHit val5 = default(RaycastHit); if (Physics.Raycast(val4 + Vector3.up * 3f, Vector3.down, ref val5, 30f)) { val4.y = ((RaycastHit)(ref val5)).point.y; } propDef.Position = new float[3] { val4.x, val4.y, val4.z }; Vector3 val6 = transform.position - val4; val6.y = 0f; if (((Vector3)(ref val6)).sqrMagnitude > 0.0001f) { float[] array = new float[3]; Quaternion val7 = Quaternion.LookRotation(val6, Vector3.up); array[1] = ((Quaternion)(ref val7)).eulerAngles.y; propDef.Rotation = array; } Say("moved " + propDef.Id + " to " + VecText(propDef.Position) + " rot " + VecText(propDef.Rotation)); Say(PropPlacer.PlaceNow()); Say("/wa prop " + propDef.Id + " save to keep it"); break; } case "scale": { if (parts.Length < 5 || !TryParse(parts[4], out var value2)) { Say("/wa prop " + propDef.Id + " scale <v> (or: height <metres>)"); break; } propDef.TargetHeight = null; propDef.Scale = value2; Say(PropPlacer.PlaceNow()); break; } case "height": { if (parts.Length < 5 || !TryParse(parts[4], out var value3)) { Say("/wa prop " + propDef.Id + " height <metres>"); break; } propDef.TargetHeight = value3; Say(propDef.Id + " target height " + value3 + " m"); Say(PropPlacer.PlaceNow()); break; } case "nudge": case "pos": case "rot": { if (!TryParseVector(parts, 4, out var value)) { Say("/wa prop " + propDef.Id + " " + text2 + " <x> <y> <z>"); break; } if (text2 == "pos") { propDef.Position = new float[3] { value.x, value.y, value.z }; } else if (text2 == "rot") { propDef.Rotation = new float[3] { value.x, value.y, value.z }; } else { Vector3 val2 = (Vector3)((propDef.Position == null || propDef.Position.Length < 3) ? Vector3.zero : new Vector3(propDef.Position[0], propDef.Position[1], propDef.Position[2])); val2 += value; propDef.Position = new float[3] { val2.x, val2.y, val2.z }; } Say(propDef.Id + " pos " + VecText(propDef.Position) + " rot " + VecText(propDef.Rotation)); Say(PropPlacer.PlaceNow()); break; } default: Say("/wa prop <id> pos|rot <x> <y> <z> | height <m> | scale <v> | nudge <dx> <dy> <dz> | here | show | save | reload"); break; } } private static string VecText(float[] v) { if (v != null && v.Length >= 3) { return "(" + v[0].ToString("0.##") + ", " + v[1].ToString("0.##") + ", " + v[2].ToString("0.##") + ")"; } return "(0, 0, 0)"; } private static void Islands() { if (IslandCatalog.Total <= 0) { Say("island list not available - load into a game first."); return; } Say("islands (> = current):"); foreach (string item in IslandCatalog.Describe()) { Say(item); Plugin.Log.LogInfo((object)("island " + item)); } int islandIndex = IslandCatalog.Resolve(Plugin.Cfg.ShopIslandName.Value, Plugin.Cfg.ShopIslandIndex.Value); Say("shop island is " + islandIndex + " (" + (IslandCatalog.SceneName(islandIndex) ?? "?") + ")"); Say("set ShopIslandName in the config to pick by scene name."); } private static void Shop() { OnlineIslandManager instance = OnlineIslandManager.Instance; if ((Object)(object)instance == (Object)null) { Say("OnlineIslandManager not ready - load into a game first."); return; } if (!InstanceFinder.IsServerStarted) { Say("only the host can change islands."); return; } int total = IslandCatalog.Total; int num = IslandCatalog.Resolve(Plugin.Cfg.ShopIslandName.Value, Plugin.Cfg.ShopIslandIndex.Value); if (num < 0 || num >= total) { Say("island " + num + " is out of range (0.." + (total - 1) + ")."); } else if (IslandCatalog.Current() == num) { Say(ShopPlacer.PlaceNow()); } else { instance.UnlockIsland((byte)num); OnlineIslandManager.TpToSpecificIsland((byte)num); Say("unlocking and travelling to island " + num + " (" + (IslandCatalog.SceneName(num) ?? "?") + ")."); Say("stands are placed when the island finishes loading - check the gun rack."); } } private static void Give(string[] parts) { if (parts.Length < 3) { Say("usage: /wa give <id>"); List(); return; } string text = parts[2]; BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(text)); string error; if (builtWeapon == null) { Say("no built weapon with id '" + text + "'. Try /wa list."); } else if (WeaponSpawner.TrySpawn(builtWeapon, out error)) { Say("spawned " + (builtWeapon.Def.DisplayName ?? text) + " in front of you."); Say("align it with /wa fit " + text + " scale|pos|rot, then /wa fit " + text + " save"); } else { Say("could not spawn: " + error); } } private static void Reload() { if ((Object)(object)Plugin.Runtime == (Object)null) { Say("runtime not ready."); return; } Plugin.Runtime.Rebuild(); Say("reloading weapon defs from " + Plugin.WeaponsFolder); } private static void Fit(string[] parts) { //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Unknown result type (might be due to invalid IL or missing references) //IL_04fb: Unknown result type (might be due to invalid IL or missing references) //IL_0505: Unknown result type (might be due to invalid IL or missing references) //IL_050f: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: 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_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Cfg.LiveTuning.Value) { Say("live tuning is disabled in the config."); return; } if (parts.Length < 3) { Say("usage: /wa fit <id> auto|flip|roll|reverse|scale|pos|rot|show|save [values]"); return; } string text = parts[2]; BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(text)); if (builtWeapon == null) { Say("no built weapon with id '" + text + "'. Try /wa list."); return; } string text2 = ((parts.Length > 3) ? parts[3].ToLowerInvariant() : "show"); ModelDef model = builtWeapon.Def.Model; switch (text2) { case "show": Say(text + ": scale " + Num(model.Scale) + " | pos " + Vec(model.Position) + " | rot " + Vec(model.Rotation) + " | fitToBase " + model.FitToBase); return; case "scale": { if (parts.Length < 5 || !TryParse(parts[4], out var value4)) { Say("usage: /wa fit " + text + " scale <value>"); return; } model.Scale = value4; break; } case "pos": { if (!TryParseVector(parts, 4, out var value3)) { Say("usage: /wa fit " + text + " pos <x> <y> <z>"); return; } model.Position = new float[3] { value3.x, value3.y, value3.z }; break; } case "rot": { if (!TryParseVector(parts, 4, out var value2)) { Say("usage: /wa fit " + text + " rot <x> <y> <z>"); return; } model.Rotation = new float[3] { value2.x, value2.y, value2.z }; break; } case "auto": { Vector3 val3 = WeaponBuilder.SuggestRotation(builtWeapon); model.Rotation = new float[3] { val3.x, val3.y, val3.z }; Say("aligned the model's long axis to the base weapon's."); Say("roll around the barrel is not derivable from bounds - nudge it by hand if needed."); break; } case "flip": { Vector3 val4 = WeaponBuilder.RotateAboutBarrel(builtWeapon, 180f); model.Rotation = new float[3] { val4.x, val4.y, val4.z }; Say("flipped 180 around the barrel."); break; } case "roll": { if (parts.Length < 5 || !TryParse(parts[4], out var value5)) { Say("usage: /wa fit " + text + " roll <degrees>"); return; } Vector3 val5 = WeaponBuilder.RotateAboutBarrel(builtWeapon, value5); model.Rotation = new float[3] { val5.x, val5.y, val5.z }; break; } case "nudge": { if (!TryParseVector(parts, 4, out var value)) { Say("usage: /wa fit " + text + " nudge <dx> <dy> <dz>"); return; } Vector3 val = (Vector3)((model.Position != null && model.Position.Length >= 3) ? new Vector3(model.Position[0], model.Position[1], model.Position[2]) : Vector3.zero) + value; model.Position = new float[3] { val.x, val.y, val.z }; break; } case "reverse": { Vector3 val2 = WeaponBuilder.RotateAboutPerpendicular(builtWeapon, 180f); model.Rotation = new float[3] { val2.x, val2.y, val2.z }; Say("turned the model end for end."); break; } case "material": { string text3 = ((parts.Length > 4) ? parts[4].ToLowerInvariant() : null); if (text3 != "vanilla" && text3 != "model" && text3 != "colors") { Say("usage: /wa fit " + text + " material vanilla|model|colors"); Say("current: " + model.Material); } else if (WeaponBuilder.SwitchMaterial(builtWeapon, text3, Plugin.Registry.WeaponsFolder)) { Say("material set to '" + text3 + "'. See the log for the shader used."); } else { Say("could not switch material; check the log."); } return; } case "save": Save(builtWeapon.Def); return; default: Say("unknown fit operation '" + text2 + "'."); return; } WeaponBuilder.Refit(builtWeapon); WeaponBuilder.SyncLiveInstances(builtWeapon); Say(text + ": scale " + Num(model.Scale) + " | pos " + Vec(model.Position) + " | rot " + Vec(model.Rotation)); Say("looks right? /wa fit " + text + " save"); } private static void Save(WeaponDef def) { //IL_0029: 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_0036: Expected O, but got Unknown if (string.IsNullOrEmpty(def.SourcePath)) { Say("no source file recorded for '" + def.Id + "'."); return; } try { JsonSerializerSettings val = new JsonSerializerSettings { NullValueHandling = (NullValueHandling)1 }; string contents = JsonConvert.SerializeObject((object)def, (Formatting)1, val); File.WriteAllText(def.SourcePath, contents); string text = MirrorPath(def); if (text != null) { File.WriteAllText(text, contents); Say("saved " + Path.GetFileName(def.SourcePath) + " (and mirrored to the repo)"); Plugin.Log.LogInfo((object)("Mirrored tuned def to " + text)); } else { Say("saved " + Path.GetFileName(def.SourcePath)); Say("WARNING: not mirrored - the next plugin build will overwrite this."); Plugin.Log.LogWarning((object)"Tuned def was NOT mirrored. Set SourceWeaponsFolder in the config to this mod's repository weapons folder, or every rebuild discards what you tune in game."); } Plugin.Log.LogInfo((object)("Wrote tuned def to " + def.SourcePath + " | scale " + Num(def.Model.Scale) + " | pos " + Vec(def.Model.Position) + " | rot " + Vec(def.Model.Rotation) + " | pose " + ((def.Pose != null) ? def.Pose.Count : 0) + " bone(s)")); } catch (Exception ex) { Say("save failed: " + ex.Message); } } private static string MirrorPath(WeaponDef def) { string value = Plugin.Cfg.SourceWeaponsFolder.Value; if (string.IsNullOrEmpty(value) || !Directory.Exists(value)) { return null; } string text = Path.Combine(value, Path.GetFileName(def.SourcePath)); if (!(Path.GetFullPath(text) == Path.GetFullPath(def.SourcePath))) { return text; } return null; } private static void Help() { Say("/wa status - version, def count, fingerprint, registration state"); Say("/wa list - weapon defs and whether they built"); Say("/wa bases - vanilla weapon prefabs available as basePrefab"); Say("/wa give <id> - spawn a custom weapon in front of you (host only)"); Say("/wa inspect <name> - dump a prefab's renderer hierarchy to the BepInEx log"); Say("/wa shop - unlock and travel to the shop island (host only)"); Say("/wa islands - list island indices and their scene names"); Say("/wa prop [id] ... - place and move scenery props; list|pos|rot|scale|nudge|here|show|save"); Say("/wa bones [seconds] - record what the weapon's own animation moves, hand IK targets included"); Say(" (the mod's hand override is suspended while it runs - reload while it does)"); Say("/wa anchors <id> - log hand IK targets, fire point and ADS pose in mesh space"); Say("/wa ik <id> left|right|leftrot|rightrot <x> <y> <z> - hand pos/rot; show|save"); Say("/wa ik <id> reloadleft <x> <y> <z> - steer the hand during the reload clip only"); Say("/wa auto <id> - solve alignment AND hand placement, then save"); Say("/wa pose <id> <bone> <x> <y> <z> - rotate any bone (finger curl); bones|show|clear|save"); Say("/wa grip <id> [left|right] [save] - wrap the fingers onto the model, solved from geometry"); Say("/wa slide <id> learn -> reload -> keep - copy the rack from the reload clip"); Say("/wa slide <id> travel <v>|time <v> - charging handle throw and speed; show|clear|save"); Say("/wa charge <id> - MEASURE the charging handle offset from a full reload; show|clear"); Say("/wa forge <id> [charge]|restore - rebuild ReloadLast as a real clip; restore undoes it"); Say("/wa ads <id> nudge up|down|left|right|forward|back <n> - line the iron sights up; show|save"); Say("/wa ik <id> chargenudge left|right|up|down|forward|back <n> - nudge it as you see it"); Say("/wa ik <id> chargewindow <from> <peak> <to> | gripreturn <t> - when the racking happens"); Say("/wa ik <id> chargeleft <x> <y> <z> - the same offset by hand, if the measurement misses"); Say(" during the racking frames of the reload only"); Say("/wa paths <id> - transform paths an authored AnimationClip must bind to"); Say("/wa fit <id> nudge <dx> <dy> <dz> - move the model by a small delta"); Say("/wa part <id> next - show one model part at a time to identify it"); Say("/wa fit <id> show - current alignment numbers"); Say("/wa fit <id> auto - guess a rotation from the base weapon's proportions"); Say("/wa fit <id> flip - 180 around the barrel, for an upside-down model"); Say("/wa fit <id> roll <d> - any angle around the barrel"); Say("/wa fit <id> reverse - end for end, when the barrel points backwards"); Say("/wa fit <id> scale <v>"); Say("/wa fit <id> pos <x> <y> <z>"); Say("/wa fit <id> rot <x> <y> <z>"); Say("/wa fit <id> save - write the tuned numbers back to the def"); Say("/wa reload - reload defs from disk and rebuild"); } private static bool TryParse(string text, out float value) { return float.TryParse((text ?? "").Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out value); } private static bool TryParseVector(string[] parts, int start, out Vector3 value) { //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_0047: 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) value = Vector3.zero; if (parts.Length < start + 3) { return false; } if (!TryParse(parts[start], out var value2)) { return false; } if (!TryParse(parts[start + 1], out var value3)) { return false; } if (!TryParse(parts[start + 2], out var value4)) { return false; } value = new Vector3(value2, value3, value4); return true; } private static string Num(float value) { return value.ToString("F3", CultureInfo.InvariantCulture); } private static string Vec(float[] values) { if (values == null || values.Length < 3) { return "0 0 0"; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(Num(values[0])).Append(' ').Append(Num(values[1])) .Append(' ') .Append(Num(values[2])); return stringBuilder.ToString(); } private static void Say(string message) { try { ChatManager.ChatMessage("[WA] " + message); } catch { Plugin.Log.LogInfo((object)("[WA] " + message)); } } } [HarmonyPatch(typeof(InventorySlot), "SetItem")] internal static class InventorySlotSetItemPatch { private sealed class SlotState { public Material[] Original; public Material[] Wrote; } private static readonly Dictionary<InventorySlot, SlotState> States = new Dictionary<InventorySlot, SlotState>(); private static bool _logged; [HarmonyPostfix] private static void Postfix(InventorySlot __instance, Item item) { if (Plugin.Cfg == null || !Plugin.Cfg.Enabled.Value || (Object)(object)__instance == (Object)null) { return; } object obj = Refl.Get(__instance, "_renderer"); Renderer val = (Renderer)((obj is Renderer) ? obj : null); if ((Object)(object)val == (Object)null) { return; } Material[] array = MaterialsFor(item); if (array == null) { Revert(__instance, val); return; } if (!States.TryGetValue(__instance, out var value)) { value = new SlotState(); States[__instance] = value; } if (!Same(val.sharedMaterials, value.Wrote)) { value.Original = val.sharedMaterials; } val.sharedMaterials = array; value.Wrote = array; LogOnce(__instance, val, array); } private static bool Same(Material[] a, Material[] b) { if (a == null || b == null) { return a == b; } if (a.Length != b.Length) { return false; } for (int i = 0; i < a.Length; i++) { if ((Object)(object)a[i] != (Object)(object)b[i]) { return false; } } return true; } private static void LogOnce(InventorySlot slot, Renderer renderer, Material[] applied) { if (!_logged && Plugin.Cfg != null && Plugin.Cfg.VerboseLogging.Value) { _logged = true; object obj = Refl.Get(slot, "_filter"); MeshFilter val = (MeshFilter)((obj is MeshFilter) ? obj : null); Mesh val2 = (((Object)(object)val != (Object)null) ? val.sharedMesh : null); Plugin.Log.LogInfo((object)("Hotbar slot: mesh '" + (((Object)(object)val2 == (Object)null) ? "<none>" : ((Object)val2).name) + "' submeshes=" + ((!((Object)(object)val2 == (Object)null)) ? val2.subMeshCount : 0) + ", applied " + applied.Length + " material(s).")); } } private static Material[] MaterialsFor(Item item) { if ((Object)(object)item == (Object)null) { return null; } ArsenalWeapon componentInParent = ((Component)item).GetComponentInParent<ArsenalWeapon>(true); if ((Object)(object)componentInParent == (Object)null) { return null; } BuiltWeapon builtWeapon = (((Object)(object)Plugin.Runtime == (Object)null) ? null : Plugin.Runtime.Find(componentInParent.WeaponId)); if (builtWeapon == null) { return null; } for (int i = 0; i < builtWeapon.Targets.Count; i++) { ModelSwapTarget modelSwapTarget = builtWeapon.Targets[i]; if (modelSwapTarget != null && !((Object)(object)modelSwapTarget.Renderer == (Object)null)) { Material[] sharedMaterials = modelSwapTarget.Renderer.sharedMaterials; if (sharedMaterials != null && sharedMaterials.Length != 0 && (Object)(object)sharedMaterials[0] != (Object)null) { return sharedMaterials; } } } return null; } private static void Revert(InventorySlot slot, Renderer renderer) { if (States.TryGetValue(slot, out var value)) { if (value.Wrote != null && Same(renderer.sharedMaterials, value.Wrote) && value.Original != null) { renderer.sharedMaterials = value.Original; } States.Remove(slot); } } public static void ClearCache() { States.Clear(); } } [HarmonyPatch(typeof(Item), "GetName")] internal static class ItemGetNamePatch { [HarmonyPostfix] private static void Postfix(Item __instance, ref string __result) { if (Plugin.Cfg == null || !Plugin.Cfg.Enabled.Value) { return; } ArsenalWeapon componentInParent = ((Component)__instance).GetComponentInParent<ArsenalWeapon>(true); if (!((Object)(object)componentInParent == (Object)null)) { WeaponDef def = componentInParent.Def; if (def != null && !string.IsNullOrEmpty(def.DisplayName)) { __result = def.DisplayName; } } } } [HarmonyPatch(typeof(Weapon), "Awake")] internal static class WeaponAwakePatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(Weapon __instance) { if (Plugin.Cfg == null || !Plugin.Cfg.Enabled.Value) { return; } ArsenalWeapon componentInParent = ((Component)__instance).GetComponentInParent<ArsenalWeapon>(true); if ((Object)(object)componentInParent == (Object)null || componentInParent.RuntimeStatsApplied) { return; } WeaponDef def = componentInParent.Def; if (def != null) { WeaponBuilder.ApplyRuntimeStats(__instance, def); componentInParent.RuntimeStatsApplied = true; if (Plugin.Cfg.VerboseLogging.Value) { Plugin.Log.LogInfo((object)("Applied runtime stats to " + def.Id + " instance.")); } } } } } namespace HowToFish.WeaponArsenal.Assets { internal static class BundleSource { public static AssetBundle Resolve(string weaponsFolder, string bundleFile) { if (string.IsNullOrEmpty(bundleFile)) { return null; } BundleLoader.Log = Plugin.Log; return BundleLoader.LoadFrom(Path.Combine(weaponsFolder, bundleFile)); } private static void StripRig(Mesh mesh) { if ((mesh.bindposes != null && mesh.bindposes.Length != 0) || (mesh.boneWeights != null && mesh.boneWeights.Length != 0)) { Plugin.Log.LogInfo((object)("Dropped the imported rig from '" + ((Object)mesh).name + "' (" + mesh.bindposes.Length + " bindposes); the game's own rig is bound instead.")); mesh.boneWeights = (BoneWeight[])(object)new BoneWeight[0]; mesh.bindposes = (Matrix4x4[])(object)new Matrix4x4[0]; } } private static void ApplyAxisFix(Mesh mesh) { //IL_0032: 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_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) Vector3[] vertices = mesh.vertices; for (int i = 0; i < vertices.Length; i++) { vertices[i] = new Vector3(0f - vertices[i].x, vertices[i].z, vertices[i].y); } mesh.vertices = vertices; Vector3[] normals = mesh.normals; if (normals != null && normals.Length == vertices.Length) { for (int j = 0; j < normals.Length; j++) { normals[j] = new Vector3(0f - normals[j].x, normals[j].z, normals[j].y); } mesh.normals = normals; } mesh.RecalculateBounds(); mesh.RecalculateTangents(); } public static LoadedModel LoadModel(AssetBundle bundle, string assetName, bool wantTextures, bool axisFix) { //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_00e5: 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_0105: 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_010e: 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) Object obj = bundle.LoadAsset<Object>(assetName); if (obj == (Object)null) { throw new Exception("Asset '" + assetName + "' not found in bundle. Available: " + string.Join(", ", bundle.GetAllAssetNames())); } ReadSource(obj, out var mesh, out var materials); if ((Object)(object)mesh == (Object)null) { throw new Exception("Asset '" + assetName + "' carries no mesh."); } Mesh val = Object.Instantiate<Mesh>(mesh); ((Object)val).name = "WA_" + assetName; ((Object)val).hideFlags = (HideFlags)52; StripRig(val); if (axisFix) { ApplyAxisFix(val); } ManualLogSource log = Plugin.Log; string[] obj2 = new string[10] { "Bundle mesh '", assetName, "' axisFix=", axisFix.ToString(), " submeshes=", val.subMeshCount.ToString(), " bounds center=", null, null, null }; Bounds bounds = val.bounds; Vector3 val2 = ((Bounds)(ref bounds)).center; obj2[7] = ((Vector3)(ref val2)).ToString("F3"); obj2[8] = " size="; bounds = val.bounds; val2 = ((Bounds)(ref bounds)).size; obj2[9] = ((Vector3)(ref val2)).ToString("F3"); log.LogInfo((object)string.Concat(obj2)); LoadedModel loadedModel = new LoadedModel { Mesh = val, SourceFile = assetName, GroupIds = GroupIdsFromSubmeshes(val), SubmeshColors = SubmeshColors(materials, val.subMeshCount) }; if (wantTextures && materials != null && materials.Length != 0 && (Object)(object)materials[0] != (Object)null) { ShaderFix.Apply(materials[0]); loadedModel.Albedo = (Texture2D)(((object)Texture(materials[0], "_BaseMap", "baseColorTexture")) ?? ((object)/*isinst with value type is only supported in some contexts*/)); loadedModel.Normal = Texture(materials[0], "_BumpMap", "normalTexture"); } return loadedModel; } public static AudioClip LoadClip(AssetBundle bundle, string assetName) { AudioClip obj = bundle.LoadAsset<AudioClip>(assetName); if ((Object)(object)obj == (Object)null) { Plugin.Log.LogWarning((object)("AudioClip '" + assetName + "' not found in bundle. Available: " + string.Join(", ", bundle.GetAllAssetNames()))); } return obj; } private static Texture2D Texture(Material material, params string[] properties) { foreach (string text in properties) { if (material.HasProperty(text)) { Texture texture = material.GetTexture(text); Texture2D val = (Texture2D)(object)((texture is Texture2D) ? texture : null); if ((Object)(object)val != (Object)null) { return val; } } } return null; } private static bool TryColor(Material material, out Color color) { //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_0033: 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) string[] array = new string[3] { "_BaseColor", "baseColorFactor", "_Color" }; foreach (string text in array) { if (material.HasProperty(text)) { color = material.GetColor(text); return true; } } color = Color.white; return false; } private static void ReadSource(Object source, out Mesh mesh, out Material[] materials) { mesh = (Mesh)(object)((source is Mesh) ? source : null); materials = null; if ((Object)(object)mesh != (Object)null) { return; } GameObject val = (GameObject)(object)((source is GameObject) ? source : null); if ((Object)(object)val == (Object)null) { return; } SkinnedMeshRenderer componentInChildren = val.GetComponentInChildren<SkinnedMeshRenderer>(true); if ((Object)(object)componentInChildren != (Object)null) { mesh = componentInChildren.sharedMesh; materials = ((Renderer)componentInChildren).sharedMaterials; return; } MeshFilter componentInChildren2 = val.GetComponentInChildren<MeshFilter>(true); if (!((Object)(object)componentInChildren2 == (Object)null)) { mesh = componentInChildren2.sharedMesh; MeshRenderer component = ((Component)componentInChildren2).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { materials = ((Renderer)component).sharedMaterials; } } } private static int[] GroupIdsFromSubmeshes(Mesh mesh) { if (mesh.subMeshCount <= 1) { return null; } int[] array = new int[mesh.vertexCount]; for (int i = 0; i < mesh.subMeshCount; i++) { int[] triangles = mesh.GetTriangles(i); foreach (int num in triangles) { if (num >= 0 && num < array.Length) { array[num] = i; } } } return array; } private static Color[] SubmeshColors(Material[] materials, int subMeshCount) { //IL_001c: 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_0048: 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) if (materials == null || materials.Length == 0 || subMeshCount <= 0) { return null; } Color[] array = (Color[])(object)new Color[subMeshCount]; bool flag = false; for (int i = 0; i < subMeshCount; i++) { array[i] = Color.white; Material val = ((i < materials.Length) ? materials[i] : null); if (!((Object)(object)val == (Object)null) && TryColor(val, out var color)) { array[i] = color; flag = true; } } if (!flag) { return null; } return array; } } internal sealed class GltfAssetExtras { [JsonProperty("title")] public string Title; [JsonProperty("author")] public string Author; [JsonProperty("license")] public string License; [JsonProperty("source")] public string Source; } internal sealed class GltfAsset { [JsonProperty("version")] public string Version; [JsonProperty("generator")] public string Generator; [JsonProperty("extras")] public GltfAssetExtras Extras; } internal sealed class GltfScene { [JsonProperty("name")] public string Name; [JsonProperty("nodes")] public int[] Nodes; } internal sealed class GltfNode { [JsonProperty("name")] public string Name; [JsonProperty("mesh")] public int? Mesh; [JsonProperty("skin")] public int? Skin; [JsonProperty("children")] public int[] Children; [JsonProperty("matrix")] public float[] Matrix; [JsonProperty("translation")] public float[] Translation; [JsonProperty("rotation")] public float[] Rotation; [JsonProperty("scale")] public float[] Scale; } internal sealed class GltfPrimitive { [JsonProperty("attributes")] public Dictionary<string, int> Attributes; [JsonProperty("indices")] public int? Indices; [JsonProperty("material")] public int? Material; [JsonProperty("mode")] public int? Mode; } internal sealed class GltfMesh { [JsonProperty("name")] public string Name; [JsonProperty("primitives")] public List<GltfPrimitive> Primitives; } internal sealed class GltfAccessor { [JsonProperty("bufferView")] public int? BufferView; [JsonProperty("byteOffset")] public int ByteOffset; [JsonProperty("componentType")] public int ComponentType; [JsonProperty("count")] public int Count; [JsonProperty("type")] public string Type; [JsonProperty("normalized")] public bool Normalized; [JsonProperty("sparse")] public object Sparse; } internal sealed class GltfBufferView { [JsonProperty("buffer")] public int Buffer; [JsonProperty("byteOffset")] public int ByteOffset; [JsonProperty("byteLength")] public int ByteLength; [JsonProperty("byteStride")] public int? ByteStride; } internal sealed class GltfBuffer { [JsonProperty("byteLength")] public int ByteLength; [JsonProperty("uri")] public string Uri; } internal sealed class GltfTextureRef { [JsonProperty("index")] public int Index; [JsonProperty("texCoord")] public int TexCoord; } internal sealed class GltfPbrMetallicRoughness { [JsonProperty("baseColorTexture")] public GltfTextureRef BaseColorTexture; [JsonProperty("baseColorFactor")] public float[] BaseColorFactor; } internal sealed class GltfSpecularGlossiness { [JsonProperty("diffuseTexture")] public GltfTextureRef DiffuseTexture; [JsonProperty("diffuseFactor")] public float[] DiffuseFactor; } internal sealed class GltfMaterialExtensions { [JsonProperty("KHR_materials_pbrSpecularGlossiness")] public GltfSpecularGlossiness SpecularGlossiness; } internal sealed class GltfMaterial { [JsonProperty("name")] public string Name; [JsonProperty("pbrMetallicRoughness")] public GltfPbrMetallicRoughness Pbr; [JsonProperty("normalTexture")] public GltfTextureRef NormalTexture; [JsonProperty("extensions")] public GltfMaterialExtensions Extensions; public int? AlbedoTextureIndex { get { if (Pbr != null && Pbr.BaseColorTexture != null) { return Pbr.BaseColorTexture.Index; } GltfSpecularGlossiness gltfSpecularGlossiness = ((Extensions == null) ? null : Extensions.SpecularGlossiness); if (gltfSpecularGlossiness != null && gltfSpecularGlossiness.DiffuseTexture != null) { return gltfSpecularGlossiness.DiffuseTexture.Index; } return null; } } } internal sealed class GltfTexture { [JsonProperty("source")] public int? Source; [JsonProperty("sampler")] public int? Sampler; } internal sealed class GltfImage { [JsonProperty("bufferView")] public int? BufferView; [JsonProperty("mimeType")] public string MimeType; [JsonProperty("uri")] public string Uri; [JsonProperty("name")] public string Name; } internal sealed class GltfRoot { [JsonProperty("asset")] public GltfAsset Asset; [JsonProperty("scene")] public int? Scene; [JsonProperty("scenes")] public List<GltfScene> Scenes; [JsonProperty("nodes")] public List<GltfNode> Nodes; [JsonProperty("meshes")] public List<GltfMesh> Meshes; [JsonProperty("accessors")] public List<GltfAccessor> Accessors; [JsonProperty("bufferViews")] public List<GltfBufferView> BufferViews; [JsonProperty("buffers")] public List<GltfBuffer> Buffers; [JsonProperty("materials")] public List<GltfMaterial> Materials; [JsonProperty("textures")] public List<GltfTexture> Textures; [JsonProperty("images")] public List<GltfImage> Images; [JsonProperty("extensionsRequired")] public string[] ExtensionsRequired; } internal sealed class GlbFile { private const uint MagicGltf = 1179937895u; private const uint ChunkJson = 1313821514u; private const uint ChunkBin = 5130562u; public GltfRoot Root { get; private set; } public byte[] Bin { get; private set; } public string SourcePath { get; private set; } public static GlbFile Load(string path) { byte[] array = File.ReadAllBytes(path); if (array.Length < 12) { throw new InvalidDataException(Path.GetFileName(path) + " is too small to be a .glb."); } if (BitConverter.ToUInt32(array, 0) != 1179937895) { throw new InvalidDataException(Path.GetFileName(path) + " is not a binary .glb (bad magic). Convert to GLB - .gltf, .fbx and .obj are not read by this loader."); } uint num = BitConverter.ToUInt32(array, 4); if (num != 2) { throw new InvalidDataException(Path.GetFileName(path) + " is glTF version " + num + "; only 2 is supported."); } long num2 = BitConverter.ToUInt32(array, 8); if (num2 > array.Length) { num2 = array.Length; } string text = null; byte[] array2 = null; int num3 = 12; while (num3 + 8 <= num2) { int num4 = BitConverter.ToInt32(array, num3); uint num5 = BitConverter.ToUInt32(array, num3 + 4); int num6 = num3 + 8; if (num4 < 0 || (long)num6 + (long)num4 > array.Length) { break; } switch (num5) { case 1313821514u: text = Encoding.UTF8.GetString(array, num6, num4); break; case 5130562u: array2 = new byte[num4]; Buffer.BlockCopy(array, num6, array2, 0, num4); break; } num3 = num6 + num4; } if (text == null) { throw new InvalidDataException(Path.GetFileName(path) + " has no JSON chunk."); } GltfRoot gltfRoot = JsonConvert.DeserializeObject<GltfRoot>(text); if (gltfRoot == null || gltfRoot.Meshes == null || gltfRoot.Meshes.Count == 0) { throw new InvalidDataException(Path.GetFileName(path) + " contains no meshes."); } return new GlbFile { Root = gltfRoot, Bin = (array2 ?? new byte[0]), SourcePath = path }; } public string CreditLine() { GltfAssetExtras gltfAssetExtras = ((Root == null || Root.Asset == null) ? null : Root.Asset.Extras); if (gltfAssetExtras == null) { return null; } StringBuilder stringBuilder = new StringBuilder(); if (!string.IsNullOrEmpty(gltfAssetExtras.Title)) { stringBuilder.Append(gltfAssetExtras.Title); } if (!string.IsNullOrEmpty(gltfAssetExtras.Author)) { stringBuilder.Append((stringBuilder.Length > 0) ? " by " : "").Append(gltfAssetExtras.Author); } if (!string.IsNullOrEmpty(gltfAssetExtras.License)) { stringBuilder.Append(" [").Append(gltfAssetExtras.License).Append("]"); } if (!string.IsNullOrEmpty(gltfAssetExtras.Source)) { stringBuilder.Append(" ").Append(gltfAssetExtras.Source); } if (stringBuilder.Length <= 0) { return null; } return stringBuilder.ToString(); } public byte[] ReadBufferView(int index) { GltfBufferView gltfBufferView = Root.BufferViews[index]; byte[] array = new byte[gltfBufferView.ByteLength]; Buffer.BlockCopy(Bin, gltfBufferView.ByteOffset, array, 0, gltfBufferView.ByteLength); return array; } } internal static class GlbMeshBuilder { private const int ModeTriangles = 4; private static bool WarnedAboutSkin; private static MethodInfo _loadImage; private static bool _loadImageResolved; public static Mesh Build(GlbFile glb, string meshName, out int[] groupIds) { int[] submeshMaterials; return Build(glb, meshName, out groupIds, out submeshMaterials); } public static Mesh Build(GlbFile glb, string meshName, out int[] groupIds, out int[] submeshMaterials) { //IL_0048: 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_00ab: Expected O, but got Unknown GltfRoot root = glb.Root; WarnedAboutSkin = false; List<Vector3> list = new List<Vector3>(); List<int> list2 = new List<int>(); int groupCounter = 0; List<Vector3> list3 = new List<Vector3>(); List<Vector2> list4 = new List<Vector2>(); Dictionary<int, List<int>> dictionary = new Dictionary<int, List<int>>(); foreach (int item in RootNodes(root)) { Walk(glb, item, Matrix4x4.identity, list, list3, list4, dictionary, list2, ref groupCounter); } if (list.Count == 0) { throw new InvalidDataException(Path.GetFileName(glb.SourcePath) + " produced no geometry."); } groupIds = list2.ToArray(); Mesh val = new Mesh { name = meshName }; val.indexFormat = (IndexFormat)(list.Count > 65000); val.SetVertices(list); if (list3.Count == list.Count) { val.SetNormals(list3); } if (list4.Count == list.Count) { val.SetUVs(0, list4); } List<int> list5 = new List<int>(dictionary.Keys); list5.Sort(); val.subMeshCount = list5.Count; for (int i = 0; i < list5.Count; i++) { val.SetTriangles(dictionary[list5[i]], i, false); } submeshMaterials = list5.ToArray(); if (list3.Count != list.Count) { val.RecalculateNormals(); } val.RecalculateBounds(); val.RecalculateTangents(); return val; } private static IEnumerable<int> RootNodes(GltfRoot root) { int valueOrDefault = root.Scene.GetValueOrDefault(); if (root.Scenes != null && valueOrDefault >= 0 && valueOrDefault < root.Scenes.Count) { int[] nodes = root.Scenes[valueOrDefault].Nodes; if (nodes != null) { return nodes; } } List<int> list = new List<int>(); if (root.Nodes != null) { for (int i = 0; i < root.Nodes.Count; i++) { list.Add(i); } } return list; } private static void Walk(GlbFile glb, int nodeIndex, Matrix4x4 parent, List<Vector3> positions, List<Vector3> normals, List<Vector2> uvs, Dictionary<int, List<int>> perMaterial, List<int> groups, ref int groupCounter) { //IL_002f: 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_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_0059: 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: 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_0094: Unknown result type (might be due to invalid IL or missing references) GltfRoot root = glb.Root; if (root.Nodes == null || nodeIndex < 0 || nodeIndex >= root.Nodes.Count) { return; } GltfNode gltfNode = root.Nodes[nodeIndex]; Matrix4x4 val = parent * LocalMatrix(gltfNode); if (gltfNode.Mesh.HasValue) { Matrix4x4 world = (gltfNode.Skin.HasValue ? Matrix4x4.identity : val); if (gltfNode.Skin.HasValue && !WarnedAboutSkin) { WarnedAboutSkin = true; Plugin.Log.LogInfo((object)"Model is skinned; node transforms are ignored for its geometry, as glTF requires. Vertices are taken in bind-pose space."); } AppendMesh(glb, gltfNode.Mesh.Value, world, positions, normals, uvs, perMaterial, groups, ref groupCounter); } if (gltfNode.Children != null) { int[] children = gltfNode.Children; foreach (int nodeIndex2 in children) { Walk(glb, nodeIndex2, val, positions, normals, uvs, perMaterial, groups, ref groupCounter); } } } private static Matrix4x4 LocalMatrix(GltfNode node) { //IL_00f2: 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_0045: 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_00a2: 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_00dd: 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_0129: 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_0150: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) if (node.Matrix != null && node.Matrix.Length == 16) { Matrix4x4 result = default(Matrix4x4); ((Matrix4x4)(ref result)).SetColumn(0, new Vector4(node.Matrix[0], node.Matrix[1], node.Matrix[2], node.Matrix[3])); ((Matrix4x4)(ref result)).SetColumn(1, new Vector4(node.Matrix[4], node.Matrix[5], node.Matrix[6], node.Matrix[7])); ((Matrix4x4)(ref result)).SetColumn(2, new Vector4(node.Matrix[8], node.Matrix[9], node.Matrix[10], node.Matrix[11])); ((Matrix4x4)(ref result)).SetColumn(3, new Vector4(node.Matrix[12], node.Matrix[13], node.Matrix[14], node.Matrix[15])); return result; } ? val = ((node.Translation != null && node.Translation.Length == 3) ? new Vector3(node.Translation[0], node.Translation[1], node.Translation[2]) : Vector3.zero); Quaternion val2 = (Quaternion)((node.Rotation != null && node.Rotation.Length == 4) ? new Quaternion(node.Rotation[0], node.Rotation[1], node.Rotation[2], node.Rotation[3]) : Quaternion.identity); Vector3 val3 = (Vector3)((node.Scale != null && node.Scale.Length == 3) ? new Vector3(node.Scale[0], node.Scale[1],