Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Huskarl v1.11.1
plugins/Huskarl/Huskarl.dll
Decompiled a day 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.ComponentModel; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using ModCommon; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; using Valheim.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("HuskarlDev")] [assembly: InternalsVisibleTo("HuskarlDev.Scripts")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("Huskarl")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.11.1.0")] [assembly: AssemblyInformationalVersion("1.11.1")] [assembly: AssemblyProduct("Huskarl")] [assembly: AssemblyTitle("Huskarl")] [assembly: AssemblyMetadata("AI_Assisted_Creation", "Code, documentation and translations written with generative AI assistance")] [assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic (Claude, via Claude Code)")] [assembly: AssemblyVersion("1.11.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 ModCommon { internal static class Lang { private const string Fallback = "English"; private const string SettingsSource = "Russian"; private static readonly Dictionary<string, Dictionary<string, string>> s_tables = new Dictionary<string, Dictionary<string, string>>(); private static readonly MethodInfo s_addWord = AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null); private static string s_current; public static string Current => s_current ?? Saved(); private static string Saved() { try { string text = PlatformPrefs.GetString("language", ""); return string.IsNullOrEmpty(text) ? "English" : text; } catch { return "English"; } } private static Dictionary<string, string> Table(string language) { if (s_tables.TryGetValue(language, out var value)) { return value; } value = new Dictionary<string, string>(); Read(value, "common." + language + ".txt"); Read(value, "lang." + language + ".txt"); return s_tables[language] = value; } private static void Read(Dictionary<string, string> table, string resource) { using Stream stream = typeof(Lang).Assembly.GetManifestResourceStream(resource); if (stream == null) { return; } using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); string text; while ((text = streamReader.ReadLine()) != null) { text = text.Trim(); if (text.Length != 0 && text[0] != '#') { int num = text.IndexOf('='); if (num > 0) { table[text.Substring(0, num).Trim()] = text.Substring(num + 1).Trim().Replace("\\n", "\n"); } } } } private static string Find(string language, string key) { if (!Table(language).TryGetValue(key, out var value)) { return null; } return value; } public static string Text(string key) { return Find(Current, key) ?? Find("English", key) ?? key; } public static string Setting(string key, string russian) { string current = Current; if (current == "Russian") { return russian; } return Find(current, key) ?? Find("English", key) ?? russian; } internal static void AddTokens(Localization loc, string language) { s_current = language; Dictionary<string, string> dictionary = Table(language); foreach (KeyValuePair<string, string> item in Table("English")) { if (item.Key[0] == '$') { string value; string text = (dictionary.TryGetValue(item.Key, out value) ? value : item.Value); s_addWord.Invoke(loc, new object[2] { item.Key.Substring(1), text }); } } } public static void AddTokens() { Localization instance = Localization.instance; if (instance != null) { AddTokens(instance, instance.GetSelectedLanguage()); } } } [HarmonyPatch(typeof(Localization), "SetupLanguage")] internal static class Lang_SetupLanguage { private static void Postfix(Localization __instance, string language) { Lang.AddTokens(__instance, language); } } internal sealed class MenuInfo { internal string SectionKey; internal string KeyPrefix; internal string RussianName; internal string RussianSection; internal string RussianDescription; public string Name => Lang.Setting(KeyPrefix + ".name", RussianName); public string Section => Lang.Setting("cfg.section." + SectionKey, RussianSection); public string Description => ConfigSync.Describe(KeyPrefix, RussianDescription, HostControlled, NeedsRelog, NeedsRestart); public string ModName => ConfigSync.ModText("name", "MenuName"); public string ModDescription => ConfigSync.ModText("description", "MenuDescription"); public int Order { get; set; } public bool HostControlled { get; set; } public bool NeedsRelog { get; set; } public bool NeedsRestart { get; set; } public Func<bool> LockedByHost { get; set; } } internal static class ConfigSync { private static BaseUnityPlugin s_plugin; private static ManualLogSource s_log; private static ConfigFile s_cfg; private static string s_version; private static string s_rpcRequest; private static string s_rpcData; private static int s_order; private static bool s_sendQueued; private static readonly List<ConfigEntryBase> s_hostEntries = new List<ConfigEntryBase>(); private static readonly Dictionary<string, string> s_sectionNames = new Dictionary<string, string>(); private static readonly Dictionary<ConfigEntryBase, string> s_local = new Dictionary<ConfigEntryBase, string>(); private static readonly HashSet<long> s_peers = new HashSet<long>(); private static readonly Dictionary<Type, FieldInfo> s_valueFields = new Dictionary<Type, FieldInfo>(); private static List<KeyValuePair<ConfigEntryBase, object>> s_setAside; public static bool HostValuesActive { get; private set; } public static event Action<string> Received; public static void Init(BaseUnityPlugin plugin, string version) { s_plugin = plugin; s_log = Logger.CreateLogSource(plugin.Info.Metadata.Name + " sync"); s_cfg = plugin.Config; s_version = version; string gUID = plugin.Info.Metadata.GUID; s_rpcRequest = gUID + ".ConfigRequest"; s_rpcData = gUID + ".ConfigData"; s_cfg.SettingChanged += OnSettingChanged; } public static void Section(string key, string name) { s_sectionNames[key] = name; } public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string name, string description, bool host, AcceptableValueBase acceptable = null, bool relog = false, bool restart = false) { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown string value; MenuInfo menuInfo = new MenuInfo { SectionKey = section, KeyPrefix = "cfg." + section + "." + key, RussianName = name, RussianSection = (s_sectionNames.TryGetValue(section, out value) ? value : section), RussianDescription = description, Order = s_order++, HostControlled = host, NeedsRelog = relog, NeedsRestart = restart, LockedByHost = (host ? ((Func<bool>)(() => HostValuesActive)) : ((Func<bool>)(() => false))) }; ConfigEntry<T> val = s_cfg.Bind<T>(section, key, defaultValue, new ConfigDescription(menuInfo.Description, acceptable, new object[1] { menuInfo })); if (host) { s_hostEntries.Add((ConfigEntryBase)(object)val); } return val; } internal static string Describe(string keyPrefix, string russian, bool host, bool relog, bool restart) { string text = Lang.Setting(keyPrefix + ".desc", russian); if (host) { text = text + "\n" + Lang.Text("common.host"); } if (restart) { text = text + "\n" + Lang.Text("common.restart"); } else if (relog) { text = text + "\n" + Lang.Text("common.relog"); } return text; } internal static string ModText(string key, string constant) { FieldInfo field = ((object)s_plugin).GetType().GetField(constant, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); return Lang.Setting("menu." + key, (field?.GetValue(null) as string) ?? s_plugin.Info.Metadata.Name); } internal static void RegisterRpcs() { if (s_cfg != null && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<string>(s_rpcRequest, (Action<long, string>)RPC_Request); ZRoutedRpc.instance.Register<ZPackage>(s_rpcData, (Action<long, ZPackage>)RPC_Data); } } internal static void RequestFromHost() { if (s_cfg != null && s_hostEntries.Count != 0 && Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer()) { ZRoutedRpc.instance.InvokeRoutedRPC(s_rpcRequest, new object[1] { s_version }); } } private static void RPC_Request(long sender, string clientVersion) { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { if (clientVersion != s_version) { s_log.LogWarning((object)$"Client {sender} runs version {clientVersion}, this host runs {s_version}"); } s_peers.Add(sender); ZRoutedRpc.instance.InvokeRoutedRPC(sender, s_rpcData, new object[1] { Pack() }); } } private static ZPackage Pack() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(s_version); val.Write(s_hostEntries.Count); foreach (ConfigEntryBase s_hostEntry in s_hostEntries) { val.Write(s_hostEntry.Definition.Section + "/" + s_hostEntry.Definition.Key); val.Write(s_hostEntry.GetSerializedValue()); } return val; } private static void RPC_Data(long sender, ZPackage p) { if (!Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.IsServer()) { return; } string text = p.ReadString(); Dictionary<string, ConfigEntryBase> dictionary = new Dictionary<string, ConfigEntryBase>(); foreach (ConfigEntryBase s_hostEntry in s_hostEntries) { dictionary[s_hostEntry.Definition.Section + "/" + s_hostEntry.Definition.Key] = s_hostEntry; } bool saveOnConfigSet = s_cfg.SaveOnConfigSet; s_cfg.SaveOnConfigSet = false; HostValuesActive = true; try { int num = p.ReadInt(); for (int i = 0; i < num; i++) { string text2 = p.ReadString(); string text3 = p.ReadString(); if (!dictionary.TryGetValue(text2, out var value)) { continue; } if (!s_local.ContainsKey(value)) { s_local[value] = value.GetSerializedValue(); } if (!(value.GetSerializedValue() == text3)) { try { value.SetSerializedValue(text3); } catch (Exception ex) { s_log.LogWarning((object)("Host value '" + text3 + "' for " + text2 + " rejected: " + ex.Message)); } } } } finally { s_cfg.SaveOnConfigSet = saveOnConfigSet; } s_log.LogInfo((object)("Using the host's settings (host runs version " + text + ")")); try { ConfigSync.Received?.Invoke(text); } catch (Exception ex2) { s_log.LogError((object)ex2); } } internal static void RestoreLocal() { s_peers.Clear(); if (!HostValuesActive) { return; } HostValuesActive = false; bool saveOnConfigSet = s_cfg.SaveOnConfigSet; s_cfg.SaveOnConfigSet = false; try { foreach (KeyValuePair<ConfigEntryBase, string> item in s_local) { if (item.Key.GetSerializedValue() != item.Value) { item.Key.SetSerializedValue(item.Value); } } } finally { s_cfg.SaveOnConfigSet = saveOnConfigSet; } s_local.Clear(); } private static void OnSettingChanged(object sender, SettingChangedEventArgs e) { if (!s_sendQueued && s_peers.Count != 0 && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer() && s_hostEntries.Contains(e.ChangedSetting)) { s_sendQueued = true; ((MonoBehaviour)s_plugin).StartCoroutine(SendSoon()); } } private static IEnumerator SendSoon() { yield return (object)new WaitForSecondsRealtime(0.3f); s_sendQueued = false; if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer() || ZRoutedRpc.instance == null) { yield break; } s_peers.RemoveWhere((long uid) => ZNet.instance.GetPeer(uid) == null); foreach (long s_peer in s_peers) { ZRoutedRpc.instance.InvokeRoutedRPC(s_peer, s_rpcData, new object[1] { Pack() }); } } private static void SetRaw(ConfigEntryBase e, object value) { Type type = ((object)e).GetType(); if (!s_valueFields.TryGetValue(type, out var value2)) { value2 = (s_valueFields[type] = type.GetField("_typedValue", BindingFlags.Instance | BindingFlags.NonPublic)); } value2.SetValue(e, value); } internal static void SwapToLocal(ConfigFile file) { if (file != s_cfg || s_local.Count == 0 || s_setAside != null) { return; } s_setAside = new List<KeyValuePair<ConfigEntryBase, object>>(); foreach (KeyValuePair<ConfigEntryBase, string> item in s_local) { s_setAside.Add(new KeyValuePair<ConfigEntryBase, object>(item.Key, item.Key.BoxedValue)); SetRaw(item.Key, TomlTypeConverter.ConvertToValue(item.Value, item.Key.SettingType)); } } internal static void SwapBack(ConfigFile file) { if (file != s_cfg || s_setAside == null) { return; } foreach (KeyValuePair<ConfigEntryBase, object> item in s_setAside) { SetRaw(item.Key, item.Value); } s_setAside = null; } } [HarmonyPatch(typeof(Game), "Start")] internal static class ConfigSync_GameStart { private static void Postfix() { ConfigSync.RegisterRpcs(); } } [HarmonyPatch(typeof(Game), "Shutdown")] internal static class ConfigSync_GameShutdown { private static void Postfix() { ConfigSync.RestoreLocal(); } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class ConfigSync_PlayerSpawned { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { ConfigSync.RequestFromHost(); } } } [HarmonyPatch(typeof(ConfigFile), "Save")] internal static class ConfigSync_Save { private static void Prefix(ConfigFile __instance) { ConfigSync.SwapToLocal(__instance); } private static Exception Finalizer(ConfigFile __instance, Exception __exception) { ConfigSync.SwapBack(__instance); return __exception; } } } namespace Huskarl { internal static class Ballistics { public static Vector3 Aim(Vector3 from, Character target, float speed, float gravity) { //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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) Vector3 velocity = target.GetVelocity(); velocity.y = 0f; Vector3 val = target.GetCenterPoint(); for (int i = 0; i < 2; i++) { float num = Vector3.Distance(from, val) / speed; val = target.GetCenterPoint() + velocity * num; } Vector3 val2 = val - from; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(val2.x, 0f, val2.z); float magnitude = ((Vector3)(ref val3)).magnitude; if (gravity <= 0.01f || magnitude < 0.5f) { return ((Vector3)(ref val2)).normalized; } float y = val2.y; float num2 = speed * speed; float num3 = num2 * num2 - gravity * (gravity * magnitude * magnitude + 2f * y * num2); float num4 = ((num3 < 0f) ? ((float)Math.PI / 4f) : Mathf.Atan((num2 - Mathf.Sqrt(num3)) / (gravity * magnitude))); return val3 / magnitude * Mathf.Cos(num4) + Vector3.up * Mathf.Sin(num4); } } internal static class Cannons { internal class Gun { public Ship Ship; public Component Interact; public Component Root; public string Name; public Transform Tr; public Transform Muzzle; public Ships.Seat Post; public float NextShot; public bool Active { get { if (Object.op_Implicit((Object)(object)Tr) && Object.op_Implicit((Object)(object)Muzzle) && Object.op_Implicit((Object)(object)Root)) { return ((Component)Tr).gameObject.activeInHierarchy; } return false; } } } internal struct Load { public ItemData Item; public int Profile; public float Speed; public float Pitch; public float Gravity; } private static bool s_init; private static Type s_interactType; private static FieldInfo s_interactRoot; private static FieldInfo s_interactName; private static MethodInfo s_findMuzzle; private static MethodInfo s_direction; private static MethodInfo s_limits; private static MethodInfo s_requestFire; private static MethodInfo s_ensureAmmo; private static FieldInfo s_profiles; private static FieldInfo s_cooldown; private static FieldInfo s_profAmmo; private static FieldInfo s_profProjectile; private static FieldInfo s_profSpeed; private static FieldInfo s_profPitch; private static PropertyInfo s_aimActive; private static readonly Dictionary<Ship, List<Gun>> s_guns = new Dictionary<Ship, List<Gun>>(); private static readonly Dictionary<string, float> s_gravity = new Dictionary<string, float>(); private static readonly string[] AmmoOrder = new string[5] { "CannonballBlackmetal_DO", "CannonballIron_DO", "CannonballGrausten_DO", "CannonballStone_DO", "CannonballBomb_DO" }; private static readonly List<Gun> Empty = new List<Gun>(); private static int s_deckMask; internal static bool Available { get { if (!s_init) { Init(); } return s_interactType != null; } } private static void Init() { s_init = true; try { Type type = AccessTools.TypeByName("Artisan_Mastery.CannonFireInteract"); Type type2 = AccessTools.TypeByName("Artisan_Mastery.CannonFireRoot"); Type type3 = AccessTools.TypeByName("Artisan_Mastery.AmmoProfile"); Type type4 = AccessTools.TypeByName("Artisan_Mastery.CannonAimController"); if (!(type == null) && !(type2 == null) && !(type3 == null)) { s_interactRoot = AccessTools.Field(type, "Root"); s_interactName = AccessTools.Field(type, "CannonName"); s_findMuzzle = AccessTools.Method(type2, "FindMuzzle", new Type[1] { typeof(Transform) }, (Type[])null); s_direction = AccessTools.Method(type2, "ComputeWorldDirection", new Type[4] { typeof(Transform), typeof(string), typeof(float), typeof(float) }, (Type[])null); s_limits = AccessTools.Method(type2, "GetAimLimits", (Type[])null, (Type[])null); s_requestFire = AccessTools.Method(type2, "RequestFire", new Type[5] { typeof(string), typeof(int), typeof(long), typeof(float), typeof(float) }, (Type[])null); s_ensureAmmo = AccessTools.Method(type2, "EnsureDefaultAmmoProfiles", (Type[])null, (Type[])null); s_profiles = AccessTools.Field(type2, "AmmoProfiles"); s_cooldown = AccessTools.Field(type2, "CooldownSeconds"); s_profAmmo = AccessTools.Field(type3, "AmmoItemPrefabName"); s_profProjectile = AccessTools.Field(type3, "ProjectilePrefabName"); s_profSpeed = AccessTools.Field(type3, "Speed"); s_profPitch = AccessTools.Field(type3, "PitchDegrees"); s_aimActive = ((type4 != null) ? AccessTools.Property(type4, "ActiveInteract") : null); if (s_interactRoot == null || s_interactName == null || s_findMuzzle == null || s_direction == null || s_limits == null || s_requestFire == null || s_profiles == null || s_profAmmo == null || s_profProjectile == null || s_profSpeed == null || s_profPitch == null) { Plugin.Log.LogWarning((object)"Artisan Mastery cannons found, but not the way Huskarl knows them: huskarls will not man them"); return; } s_interactType = type; Plugin.Log.LogInfo((object)"Artisan Mastery found: huskarls man ship cannons"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Artisan Mastery cannons: " + ex.Message)); s_interactType = null; } } internal static List<Gun> Of(Ship ship) { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (!Available || !Object.op_Implicit((Object)(object)ship)) { return Empty; } if (s_guns.TryGetValue(ship, out var value)) { return value; } if (s_guns.Count > 16) { Prune(); } value = new List<Gun>(); Rigidbody component = ((Component)ship).GetComponent<Rigidbody>(); Component[] componentsInChildren = ((Component)ship).GetComponentsInChildren(s_interactType, true); foreach (Component val in componentsInChildren) { try { Gun gun = new Gun { Ship = ship, Interact = val, Root = (Component)/*isinst with value type is only supported in some contexts*/, Name = (s_interactName.GetValue(val) as string), Tr = val.transform }; if (Object.op_Implicit((Object)(object)gun.Root) && !string.IsNullOrEmpty(gun.Name)) { ref Transform muzzle = ref gun.Muzzle; object? obj = s_findMuzzle.Invoke(gun.Root, new object[1] { gun.Tr }); muzzle = (Transform)((obj is Transform) ? obj : null); if (Object.op_Implicit((Object)(object)gun.Muzzle)) { Vector3 val2 = PostFor(gun); gun.Post = new Ships.Seat { Ship = ship, Point = Ships.LocalPoint(ship, ((Component)ship).transform.InverseTransformPoint(val2), "huskarl_gunpost"), Body = component, Stand = true, Gun = gun }; value.Add(gun); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Cannon skipped: " + ex.Message)); } } s_guns[ship] = value; if (value.Count > 0) { Plugin.Log.LogInfo((object)$"{Utils.GetPrefabName(((Component)ship).gameObject)}: {value.Count} cannons for huskarl gunners"); } return value; } private static void Prune() { List<Ship> list = new List<Ship>(); foreach (Ship key in s_guns.Keys) { if (!Object.op_Implicit((Object)(object)key)) { list.Add(key); } } foreach (Ship item in list) { s_guns.Remove(item); } } private static Vector3 PostFor(Gun g) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: 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_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) if (s_deckMask == 0) { s_deckMask = LayerMask.GetMask(new string[4] { "Default", "static_solid", "piece", "vehicle" }); } Vector3 val = Direction(g, 0f, 0f); val.y = 0f; val = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : ((Component)g.Ship).transform.right); float y = g.Tr.position.y; float[] array = new float[3] { 1.3f, 1f, 1.6f }; foreach (float num in array) { RaycastHit[] array2 = Physics.RaycastAll(g.Tr.position - val * num + Vector3.up * 1.2f, Vector3.down, 3f, s_deckMask, (QueryTriggerInteraction)1); for (int j = 0; j < array2.Length; j++) { RaycastHit val2 = array2[j]; if (!((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Ship>() != (Object)(object)g.Ship) && !(((RaycastHit)(ref val2)).normal.y < 0.8f) && !(((RaycastHit)(ref val2)).point.y > g.Tr.position.y + 0.6f)) { return ((RaycastHit)(ref val2)).point + Vector3.up * 0.05f; } } } Vector3 result = g.Tr.position - val * 1.3f; result.y = y; return result; } private static Vector3 Direction(Gun g, float pitch, float yaw) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) return (Vector3)s_direction.Invoke(g.Root, new object[4] { g.Tr, g.Name, pitch, yaw }); } internal static bool FindLoad(Gun g, Inventory bag, out Load load) { load = default(Load); if (bag == null || !Object.op_Implicit((Object)(object)g.Root)) { return false; } s_ensureAmmo?.Invoke(g.Root, null); if (!(s_profiles.GetValue(g.Root) is IList list)) { return false; } string[] ammoOrder = AmmoOrder; foreach (string text in ammoOrder) { for (int j = 0; j < list.Count; j++) { object obj = list[j]; if (obj != null && !((string)s_profAmmo.GetValue(obj) != text)) { ItemData val = ItemByPrefab(bag, text); if (val == null) { break; } load = new Load { Item = val, Profile = j, Speed = Mathf.Max(0.1f, (float)s_profSpeed.GetValue(obj)), Pitch = (float)s_profPitch.GetValue(obj), Gravity = GravityOf((string)s_profProjectile.GetValue(obj)) }; return true; } } } return false; } internal static bool HasAmmo(Inventory bag) { if (bag == null) { return false; } string[] ammoOrder = AmmoOrder; foreach (string prefab in ammoOrder) { if (ItemByPrefab(bag, prefab) != null) { return true; } } return false; } private static ItemData ItemByPrefab(Inventory bag, string prefab) { foreach (ItemData allItem in bag.GetAllItems()) { if (Object.op_Implicit((Object)(object)allItem.m_dropPrefab) && ((Object)allItem.m_dropPrefab).name == prefab) { return allItem; } } return null; } private static float GravityOf(string projectile) { if (string.IsNullOrEmpty(projectile)) { return 0f; } if (s_gravity.TryGetValue(projectile, out var value)) { return value; } GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab(projectile) : null); Projectile val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponentInChildren<Projectile>(true) : null); value = (Object.op_Implicit((Object)(object)val2) ? val2.m_gravity : 0f); s_gravity[projectile] = value; return value; } internal static bool Aim(Gun g, Character target, Load load, out float yaw, out float pitch) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) yaw = (pitch = 0f); if (!g.Active || !Object.op_Implicit((Object)(object)target)) { return false; } Vector3 val = Ballistics.Aim(g.Muzzle.position, target, load.Speed, load.Gravity); Vector3 val2 = Direction(g, 0f, 0f); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(val.x, 0f, val.z); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(val2.x, 0f, val2.z); if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f || ((Vector3)(ref val4)).sqrMagnitude < 0.0001f) { return false; } yaw = Vector3.SignedAngle(val4, val3, Vector3.up); float num = Mathf.Asin(Mathf.Clamp(((Vector3)(ref val)).normalized.y, -1f, 1f)) * 57.29578f; float num2 = Mathf.Asin(Mathf.Clamp(((Vector3)(ref val2)).normalized.y, -1f, 1f)) * 57.29578f; pitch = num - num2 - load.Pitch; object[] array = new object[5] { g.Name, 0f, 0f, 0f, 0f }; s_limits.Invoke(g.Root, array); float num3 = (float)array[1]; float num4 = (float)array[2]; float num5 = (float)array[3]; float num6 = (float)array[4]; if (yaw >= num3 && yaw <= num4 && pitch >= num5) { return pitch <= num6; } return false; } internal static bool Fire(Gun g, Load load, float yaw, float pitch) { if (!g.Active || Time.time < g.NextShot) { return false; } float num = ((s_cooldown != null) ? ((float)s_cooldown.GetValue(g.Root)) : 3f); g.NextShot = Time.time + Mathf.Max(0.5f, num) + 0.1f; s_requestFire.Invoke(g.Root, new object[5] { g.Name, load.Profile, 0L, yaw, pitch }); return true; } internal static float Cooldown(Gun g) { if (!(s_cooldown != null) || !Object.op_Implicit((Object)(object)g.Root)) { return 3f; } return (float)s_cooldown.GetValue(g.Root); } internal static bool PlayerAt(Gun g) { //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (s_aimActive != null && (Object)s_aimActive.GetValue(null) == (Object)(object)g.Interact) { return true; } Vector3 position = g.Tr.position; foreach (Player allPlayer in Player.GetAllPlayers()) { if (Object.op_Implicit((Object)(object)allPlayer) && Vector3.Distance(((Component)allPlayer).transform.position, position) < 1.5f) { return true; } } return false; } } internal static class Cfg { private static ConfigEntry<int> s_maxHelpers; private static ConfigEntry<bool> s_allowImmortality; private static ConfigEntry<bool> s_ownerOnly; private static ConfigEntry<string> s_reviveCost; private static ConfigEntry<string> s_hornRecipe; private static ConfigEntry<string> s_hornStation; private static ConfigEntry<float> s_maxHealth; private static ConfigEntry<float> s_regenSeconds; private static ConfigEntry<float> s_damageMultiplier; private static ConfigEntry<float> s_armorMultiplier; private static ConfigEntry<int> s_bagWidth; private static ConfigEntry<int> s_bagHeight; private static ConfigEntry<float> s_workRadius; private static ConfigEntry<float> s_teleportDistance; private static ConfigEntry<KeyCode> s_wheelModifier; private static ConfigEntry<KeyCode> s_wheelKey; private static ConfigEntry<bool> s_gameStyleWheel; private static ConfigEntry<float> s_squadRadius; private static ConfigEntry<string> s_gatherPrefabs; private static ConfigEntry<string> s_huntPrefabs; private static ConfigEntry<string> s_oreKeywords; private static ConfigEntry<bool> s_useRanged; private static ConfigEntry<float> s_rangedSkill; private static ConfigEntry<float> s_meleeDistance; private static ConfigEntry<bool> s_mapHelpers; private static ConfigEntry<bool> s_mapGraves; private static ConfigEntry<bool> s_mapOthers; private static ConfigEntry<float> s_clearRadius; private static ConfigEntry<float> s_lootRadius; private static ConfigEntry<string> s_lootIgnore; private static ConfigEntry<bool> s_lootContainers; private static ConfigEntry<bool> s_openDoors; private static ConfigEntry<bool> s_chatter; private static ConfigEntry<bool> s_lively; private static ConfigEntry<bool> s_passThrough; private static ConfigEntry<bool> s_boardShips; private static ConfigEntry<float> s_boardDistance; private static ConfigEntry<float> s_shipCatchUp; private static ConfigEntry<bool> s_useCannons; private static ConfigEntry<float> s_cannonRange; private static ConfigEntry<FormationShape> s_formationShape; private static ConfigEntry<float> s_formationSpacing; public static int MaxHelpers => s_maxHelpers.Value; public static bool AllowImmortality => s_allowImmortality.Value; public static bool OwnerOnly => s_ownerOnly.Value; public static string ReviveCost => s_reviveCost.Value; public static string HornRecipe => s_hornRecipe.Value; public static string HornStation => s_hornStation.Value; public static float MaxHealth => s_maxHealth.Value; public static float RegenSeconds => Math.Max(10f, s_regenSeconds.Value); public static float DamageMultiplier => s_damageMultiplier.Value; public static float ArmorMultiplier => s_armorMultiplier.Value; public static int BagWidth => Math.Max(1, Math.Min(8, s_bagWidth.Value)); public static int BagHeight => Math.Max(1, Math.Min(16, s_bagHeight.Value)); public static float WorkRadius => s_workRadius.Value; public static float TeleportDistance => s_teleportDistance.Value; public static KeyCode WheelModifier => s_wheelModifier.Value; public static KeyCode WheelKey => s_wheelKey.Value; public static bool GameStyleWheel => s_gameStyleWheel.Value; public static float SquadRadius => s_squadRadius.Value; public static string GatherPrefabs => s_gatherPrefabs.Value; public static string HuntPrefabs => s_huntPrefabs.Value; public static string OreKeywords => s_oreKeywords.Value; public static bool UseRanged => s_useRanged.Value; public static float RangedSkill => s_rangedSkill.Value; public static float MeleeDistance => s_meleeDistance.Value; public static bool MapShowHelpers => s_mapHelpers.Value; public static bool MapShowGraves => s_mapGraves.Value; public static bool MapShowOthers => s_mapOthers.Value; public static float ClearRadius => s_clearRadius.Value; public static float LootRadius => s_lootRadius.Value; public static string LootIgnore => s_lootIgnore.Value; public static bool LootContainers => s_lootContainers.Value; public static bool OpenDoors => s_openDoors.Value; public static bool Lively => s_lively.Value; public static bool Chatter => s_chatter.Value; public static bool PassThrough => s_passThrough.Value; public static bool BoardShips => s_boardShips.Value; public static float BoardDistance => s_boardDistance.Value; public static float ShipCatchUp => s_shipCatchUp.Value; public static bool UseCannons => s_useCannons.Value; public static float CannonRange => s_cannonRange.Value; public static FormationShape FormationShape => s_formationShape.Value; public static float FormationSpacing => Math.Max(1.5f, Math.Min(8f, s_formationSpacing.Value)); public static event Action Changed; private static AcceptableValueRange<float> Range(float min, float max) { return new AcceptableValueRange<float>(min, max); } private static AcceptableValueRange<int> Range(int min, int max) { return new AcceptableValueRange<int>(min, max); } public static void Bind(ConfigFile f) { ConfigSync.Section("Helpers", "Помощники"); ConfigSync.Section("Combat", "Бой"); ConfigSync.Section("Work", "Работа"); ConfigSync.Section("Death", "Смерть"); ConfigSync.Section("Horn", "Рог"); ConfigSync.Section("Controls", "Управление"); ConfigSync.Section("Map", "Карта"); ConfigSync.Section("Dungeon", "Подземелья"); ConfigSync.Section("Life", "Живость"); ConfigSync.Section("Ships", "Корабли"); ConfigSync.Section("Formation", "Строй"); s_maxHelpers = ConfigSync.Bind("Helpers", "MaxHelpersPerPlayer", 5, "Помощников на игрока", "Сколько помощников (живых или в могиле) может быть у одного игрока. Рог на пределе не призывает нового, а зовёт ваших помощников к вам.", host: true, (AcceptableValueBase)(object)Range(0, 20)); s_ownerOnly = ConfigSync.Bind("Helpers", "OwnerOnlyCommands", defaultValue: false, "Приказы только от хозяина", "Если включено, отдавать приказы и открывать рюкзак помощника может только тот, кто его призвал. Иначе — любой игрок.", host: true); s_maxHealth = ConfigSync.Bind("Helpers", "MaxHealth", 300f, "Здоровье", "Здоровье помощника.", host: true, (AcceptableValueBase)(object)Range(50f, 3000f)); s_regenSeconds = ConfigSync.Bind("Helpers", "RegenSeconds", 300f, "Восстановление здоровья, с", "За сколько секунд здоровье восстанавливается с нуля до полного.", host: true, (AcceptableValueBase)(object)Range(10f, 3600f)); s_damageMultiplier = ConfigSync.Bind("Helpers", "DamageMultiplier", 1f, "Множитель урона", "Множитель урона, который помощник наносит оружием и инструментами.", host: true, (AcceptableValueBase)(object)Range(0.1f, 5f)); s_armorMultiplier = ConfigSync.Bind("Helpers", "ArmorMultiplier", 1f, "Множитель брони", "Множитель брони, которую помощник получает от надетой экипировки.", host: true, (AcceptableValueBase)(object)Range(0.1f, 5f)); s_bagWidth = ConfigSync.Bind("Helpers", "BagWidth", 8, "Ширина рюкзака", "Столбцов в рюкзаке помощника. У всех игроков и на сервере должно быть одинаковое значение.", host: false, (AcceptableValueBase)(object)Range(1, 8), relog: false, restart: true); s_bagHeight = ConfigSync.Bind("Helpers", "BagHeight", 6, "Высота рюкзака", "Рядов в рюкзаке помощника. У всех игроков и на сервере должно быть одинаковое значение.", host: false, (AcceptableValueBase)(object)Range(1, 16), relog: false, restart: true); s_useRanged = ConfigSync.Bind("Combat", "UseRanged", defaultValue: true, "Стрелять из лука и ружья", "Помощники стреляют из луков, арбалетов и ружей из рюкзака, если у них есть боеприпасы.", host: true); s_rangedSkill = ConfigSync.Bind("Combat", "RangedSkill", 50f, "Навык стрельбы", "Навык луков и арбалетов у помощника, 0–100: точность, скорость натяжения и перезарядки.", host: true, (AcceptableValueBase)(object)Range(0f, 100f)); s_meleeDistance = ConfigSync.Bind("Combat", "MeleeDistance", 4f, "Ближний бой с, м", "Стрелок, у которого есть и оружие ближнего боя, переключается на него, когда враг подходит ближе этого расстояния. Ружья с дробью вблизи используются всё равно.", host: true, (AcceptableValueBase)(object)Range(0f, 15f)); s_workRadius = ConfigSync.Bind("Work", "WorkRadius", 30f, "Радиус работы, м", "Как далеко от места приказа помощник ищет деревья, руду, ягоды и дичь.", host: true, (AcceptableValueBase)(object)Range(5f, 100f)); s_teleportDistance = ConfigSync.Bind("Work", "FollowTeleportDistance", 50f, "Подтягивать отставших с, м", "Помощник, который отстал от ведущего на это расстояние, переносится к нему.", host: true, (AcceptableValueBase)(object)Range(10f, 200f)); s_gatherPrefabs = ConfigSync.Bind("Work", "GatherPrefabs", "RaspberryBush,BlueberryBush,CloudberryBush,LingonberryBush,VineAsh,Pickable_Mushroom,Pickable_Mushroom_yellow,Pickable_Mushroom_blue,Pickable_Mushroom_JotunPuffs,Pickable_Mushroom_Magecap,Pickable_SmokePuff,Pickable_Fiddlehead", "Что собирать", "Префабы, которые помощники собирают по приказу «Собирать», через запятую.", host: true); s_huntPrefabs = ConfigSync.Bind("Work", "HuntPrefabs", "Deer,Hare,Boar,Neck,Lox,Moose,Seal", "На кого охотиться", "Существа, на которых помощники охотятся по приказу «Охота». В других режимах их не трогают, если те не нападают.", host: true); s_oreKeywords = ConfigSync.Bind("Work", "OreKeywords", "Ore,Scrap", "Что считать рудой", "Камень считается рудой, если в названии его добычи есть одно из этих слов.", host: true); s_allowImmortality = ConfigSync.Bind("Death", "AllowImmortality", defaultValue: true, "Разрешить бессмертие", "Игроки могут сделать помощника бессмертным в меню приказов.", host: true); s_reviveCost = ConfigSync.Bind("Death", "ReviveCost", "SurtlingCore:3", "Цена воскрешения", "Предметы для воскрешения помощника у могилы, например «SurtlingCore:3,Coins:50». Пусто — бесплатно.", host: true); s_hornRecipe = ConfigSync.Bind("Horn", "Recipe", "TrophyDeer:1,LeatherScraps:6,Wood:10", "Рецепт рога", "Предметы для крафта рога помощника.", host: true); s_hornStation = ConfigSync.Bind("Horn", "CraftingStation", "piece_workbench", "Станция для рога", "Префаб станции, на которой крафтится рог. Пусто — крафт с рук.", host: true); s_wheelModifier = ConfigSync.Bind<KeyCode>("Controls", "WheelModifier", (KeyCode)304, "Клавиша колеса приказов", "Удерживайте эту клавишу и крутите колесо мыши, чтобы открыть колесо приказов отряду. Пока она зажата, колесо мыши не меняет приближение камеры. None — выключено.", host: false); s_wheelKey = ConfigSync.Bind<KeyCode>("Controls", "WheelKey", (KeyCode)0, "Отдельная клавиша колеса", "Необязательная клавиша, которая открывает колесо приказов сама по себе.", host: false); s_gameStyleWheel = ConfigSync.Bind("Controls", "GameStyleWheel", defaultValue: true, "Колесо в стиле игры", "Колесо приказов рисуется радиальным меню самой игры, как эмоции: иконки, анимация, выбор мышью или стиком, ПКМ — назад. Выключите, чтобы вернуть простое колесо мода (например, если другой мод меняет радиальное меню игры).", host: false); s_squadRadius = ConfigSync.Bind("Controls", "SquadRadius", 40f, "Радиус отряда, м", "Приказы с колеса получают ваши помощники в этом радиусе.", host: false, (AcceptableValueBase)(object)Range(5f, 150f)); s_mapHelpers = ConfigSync.Bind("Map", "ShowHelpers", defaultValue: true, "Хускарлы на карте", "Ваши хускарлы отмечены на миникарте и большой карте значком рога с именем, метка движется вместе с ними — даже если хускарл остался далеко.", host: false); s_mapGraves = ConfigSync.Bind("Map", "ShowGraves", defaultValue: true, "Могилы на карте", "Могила погибшего хускарла отмечена на карте черепом с его именем, пока его не воскресят. Если выключить, при гибели ставится обычная метка смерти.", host: false); s_mapOthers = ConfigSync.Bind("Map", "ShowOthers", defaultValue: false, "Чужие хускарлы на карте", "Показывать на карте и хускарлов (и их могилы) других игроков, с именем хозяина в скобках.", host: false); s_clearRadius = ConfigSync.Bind("Dungeon", "ClearRadius", 25f, "Радиус зачистки, м", "По приказу «Зачистка» хускарлы убивают врагов (и разбивают кучи костей, из которых лезут скелеты) в этом радиусе от места приказа, потом возвращаются к вам. Враг за стеной, до которого идти дальше полутора радиусов, не считается.", host: true, (AcceptableValueBase)(object)Range(5f, 80f)); s_lootRadius = ConfigSync.Bind("Dungeon", "LootRadius", 25f, "Радиус разграбления, м", "По приказу «Разграбление» хускарлы обыскивают сундуки, подбирают ценности и предметы с пола в этом радиусе от места приказа, потом возвращаются к вам.", host: true, (AcceptableValueBase)(object)Range(5f, 80f)); s_lootIgnore = ConfigSync.Bind("Dungeon", "LootIgnore", "Stone,Wood,Flint,Resin,Grausten", "Что не брать", "Предметы, которые хускарлы не берут при разграблении, через запятую (имена префабов).", host: true); s_lootContainers = ConfigSync.Bind("Dungeon", "LootContainers", defaultValue: true, "Обыскивать сундуки", "При разграблении хускарлы забирают вещи из сундуков подземелий и других ничейных сундуков. Сундуки, построенные игроками, они не трогают никогда.", host: true); s_openDoors = ConfigSync.Bind("Dungeon", "OpenDoors", defaultValue: true, "Открывать двери", "Хускарлы сами открывают двери на пути и закрывают за собой, если за ними никто не идёт. Запертые двери (нужен ключ) не открывают.", host: true); s_lively = ConfigSync.Bind("Life", "Lively", defaultValue: true, "Живое поведение", "Хускарлы смотрят на вас, когда вы рядом, иногда разминаются и машут рукой, ночью садятся греться у костра, садятся рядом, когда вы сидите. Действует на хускарлов, которыми управляет ваша игра.", host: false); s_chatter = ConfigSync.Bind("Life", "Chatter", defaultValue: true, "Реплики", "Хускарлы иногда говорят что-нибудь к месту: ранен, дождь, ночь, вы вернулись, повержен сильный враг. Выключите, чтобы видеть только ответы на приказы.", host: false); s_passThrough = ConfigSync.Bind("Life", "PassThrough", defaultValue: true, "Проходить сквозь хускарлов", "Если вы упёрлись в хускарла (например, в узком проходе пещеры) и он не успел уступить, через полсекунды вы проходите сквозь него.", host: false); s_boardShips = ConfigSync.Bind("Ships", "BoardShips", defaultValue: true, "Садиться на корабль", "Хускарлы в режиме «За мной» запрыгивают к вам на корабль: на скамьи, а где их нет — на палубу, сидя или стоя. Плывут на своих местах, стреляют с места по серпентам и сходят на берег вслед за вами. Место, где сидит хускарл, можно занять: E по хускарлу — он встанет и уступит.", host: true); s_boardDistance = ConfigSync.Bind("Ships", "BoardDistance", 8f, "Запрыгивают на борт с, м", "С какого расстояния до борта хускарл запрыгивает на корабль. Дальше он бежит или плывёт к кораблю.", host: true, (AcceptableValueBase)(object)Range(2f, 12f)); s_shipCatchUp = ConfigSync.Bind("Ships", "ShipCatchUpSeconds", 8f, "Подтягивать на борт через, с", "Хускарл, не успевший на корабль (вы отплыли без него), через столько секунд оказывается на свободном месте на борту. 0 — не подтягивать: он поплывёт следом, а если отстанет, будет ждать.", host: true, (AcceptableValueBase)(object)Range(0f, 60f)); s_useCannons = ConfigSync.Bind("Ships", "UseCannons", defaultValue: true, "Стрелять из пушек", "На корабле с пушками (галеон из мода Artisan Mastery) хускарлы с ядрами в мешке встают к свободной пушке, которая достаёт до врага, наводят её и стреляют. Ядра берут из своего мешка. Без мода Artisan Mastery ничего не делает.", host: true); s_cannonRange = ConfigSync.Bind("Ships", "CannonRange", 70f, "Дальность стрельбы из пушек, м", "Враги дальше этого от корабля пушкари не обстреливают.", host: true, (AcceptableValueBase)(object)Range(20f, 150f)); s_formationShape = ConfigSync.Bind("Formation", "Shape", FormationShape.Free, "Строй", "Как ваши хускарлы идут за вами в режиме «За мной»: дугой позади, клином, колонной по вашим следам, кольцом вокруг вас или свободно (без строя, просто рядом, как раньше, но не ближе заданного расстояния). Строй поворачивается по направлению вашего движения, а не камеры. Где место в строю занято деревом, стеной или водой, хускарл идёт по вашим следам. Меняется и на колесе приказов: «Строй». Действует на хускарлов, которые идут за вами, и по приказу «Идите туда».", host: false); s_formationSpacing = ConfigSync.Bind("Formation", "Spacing", 3f, "Расстояние в строю, м", "Сколько метров между соседями в строю и от вас до ближайших хускарлов. В свободном строю — как близко они подходят к вам и друг к другу. Меняется и на колесе приказов: «Строй» → «Расстояние».", host: false, (AcceptableValueBase)(object)Range(1.5f, 8f)); f.SettingChanged += delegate { RaiseChanged(); }; } public static void SetFormationShape(FormationShape shape) { s_formationShape.Value = shape; } public static void SetFormationSpacing(float spacing) { s_formationSpacing.Value = spacing; } private static void RaiseChanged() { try { Cfg.Changed?.Invoke(); } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } public static List<KeyValuePair<string, int>> ParseItems(string s) { List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(); if (string.IsNullOrWhiteSpace(s)) { return list; } string[] array = s.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Trim().Split(new char[1] { ':' }); if (array2[0].Length != 0) { int result = 1; if (array2.Length > 1) { int.TryParse(array2[1].Trim(), out result); } list.Add(new KeyValuePair<string, int>(array2[0].Trim(), Math.Max(1, result))); } } return list; } public static HashSet<string> ParseSet(string s) { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); if (string.IsNullOrWhiteSpace(s)) { return hashSet; } string[] array = s.Split(new char[1] { ',' }); foreach (string text in array) { if (text.Trim().Length > 0) { hashSet.Add(text.Trim()); } } return hashSet; } } internal static class CommandMenu { private static float s_openedAt; private static int s_openFrame; private static readonly Stack<string> s_path = new Stack<string>(); private static List<OrderNode> s_nodes = new List<OrderNode>(); private static string s_title = ""; private static string s_subtitle = ""; private static int s_hover = -2; private static readonly List<Rect> s_rows = new List<Rect>(); private static bool s_rowsSub; private const int BackRow = -1; public static HuskarlNpc Target { get; private set; } public static bool IsOpen => Object.op_Implicit((Object)(object)Target); public static void Open(HuskarlNpc npc) { CommandWheel.Close(); Target = npc; s_openedAt = Time.time; s_openFrame = Time.frameCount; s_path.Clear(); s_rows.Clear(); s_hover = -2; Rebuild(); } public static void Close() { if (Object.op_Implicit((Object)(object)Target)) { InputGuard.Arm(); } Target = null; s_path.Clear(); s_rows.Clear(); } private static void Back() { if (s_path.Count > 0) { s_path.Pop(); } else { Close(); } } private static void Rebuild() { HuskarlNpc target = Target; List<OrderNode> list = Orders.Build(new List<HuskarlNpc> { target }, null, "", null, single: true); string text = target.GetHelperName(); List<string> list2 = new List<string>(s_path); list2.Reverse(); int num = 0; foreach (string step in list2) { OrderNode orderNode = list.Find((OrderNode n) => n.Label == step && n.Children != null); if (orderNode == null) { break; } list = orderNode.Children; text = orderNode.Label; num++; } while (s_path.Count > num) { s_path.Pop(); } s_nodes = list; s_title = text; s_subtitle = ((s_path.Count > 0) ? target.GetHelperName() : $"{Mathf.CeilToInt(((Character)target).GetHealth())} / {Mathf.CeilToInt(((Character)target).GetMaxHealth())}"); } public static void Update() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (!IsOpen) { return; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)Target) || ((Character)Target).IsDead() || !Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)Target).transform.position) > 8f || InventoryGui.IsVisible() || Menu.IsVisible() || TextInput.IsVisible() || Minimap.IsOpen()) { Close(); return; } Rebuild(); bool flag = s_path.Count > 0; s_hover = -2; if (s_rowsSub == flag) { Vector2 val = InputGuard.Pointer(); for (int i = 0; i < s_rows.Count; i++) { Rect val2 = s_rows[i]; if (((Rect)(ref val2)).Contains(val)) { s_hover = (flag ? (i - 1) : i); } } } if (Time.frameCount == s_openFrame || Time.time - s_openedAt < 0.15f) { return; } if (InputGuard.KeyDown((KeyCode)27) || ZInput.GetButtonDown("Use") || ZInput.GetButtonDown("JoyButtonB")) { Close(); return; } if (InputGuard.KeyDown((KeyCode)8) || ZInput.GetMouseButtonDown(1)) { Back(); return; } OrderNode orderNode = null; int num = InputGuard.DigitDown(); if (num >= 0 && num < s_nodes.Count) { orderNode = s_nodes[num]; } if (ZInput.GetMouseButtonDown(0)) { if (s_hover == -1 && flag) { Back(); return; } if (s_hover >= 0 && s_hover < s_nodes.Count) { orderNode = s_nodes[s_hover]; } } if (orderNode == null || !orderNode.Enabled) { return; } if (orderNode.Children != null) { s_path.Push(orderNode.Label); return; } orderNode.Run?.Invoke(); if (IsOpen && !IsToggle(orderNode)) { Close(); } } public static void OnGUI() { //IL_002e: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) if (IsOpen && s_nodes != null) { UiStyle.Init(); List<OrderNode> list = s_nodes; bool flag = s_path.Count > 0; float scale = UiStyle.Scale; Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(scale, scale, 1f)); float num = (float)Screen.width / scale; float num2 = (float)Screen.height / scale; int num3 = list.Count + (flag ? 1 : 0); float num4 = 70f + (float)num3 * 43f + 4f + 40f + 12f; Rect val = default(Rect); ((Rect)(ref val))..ctor(num * 0.5f + 140f, (num2 - num4) * 0.5f, 420f, num4); if (((Rect)(ref val)).xMax > num - 10f) { ((Rect)(ref val)).x = num - 420f - 10f; } GUI.DrawTexture(new Rect(((Rect)(ref val)).x - 2f, ((Rect)(ref val)).y - 2f, ((Rect)(ref val)).width + 4f, ((Rect)(ref val)).height + 4f), (Texture)(object)UiStyle.Border); GUI.Box(val, GUIContent.none, UiStyle.Window); float num5 = ((Rect)(ref val)).y + 14f; GUI.Label(new Rect(((Rect)(ref val)).x + 18f, num5, 384f, 30f), s_title, UiStyle.Title); num5 += 30f; GUI.Label(new Rect(((Rect)(ref val)).x + 18f, num5, 384f, 18f), s_subtitle, UiStyle.Hint); num5 += 26f; s_rows.Clear(); s_rowsSub = flag; if (flag) { Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 18f, num5, 384f, 38f); GUI.Label(val2, "← " + Localization.instance.Localize("$huskarl_back"), (s_hover == -1) ? UiStyle.Hover : UiStyle.Button); s_rows.Add(Unscale(val2, scale)); num5 += 43f; } Rect val3 = default(Rect); for (int i = 0; i < list.Count; i++) { OrderNode orderNode = list[i]; ((Rect)(ref val3))..ctor(((Rect)(ref val)).x + 18f, num5, 384f, 38f); string text = string.Format("{0}. {1}{2}", i + 1, orderNode.Label, (orderNode.Children != null) ? " ›" : ""); GUIStyle val4 = ((!orderNode.Enabled) ? UiStyle.Disabled : (orderNode.Active ? UiStyle.Active : ((s_hover == i) ? UiStyle.Hover : UiStyle.Button))); GUI.Label(val3, text, val4); s_rows.Add(Unscale(val3, scale)); num5 += 43f; } num5 += 4f; GUI.Label(new Rect(((Rect)(ref val)).x + 18f, num5, 384f, 40f), Localization.instance.Localize("$huskarl_menu_hint"), UiStyle.Hint); GUI.matrix = matrix; } } private static Rect Unscale(Rect r, float scale) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) return new Rect(((Rect)(ref r)).x * scale, ((Rect)(ref r)).y * scale, ((Rect)(ref r)).width * scale, ((Rect)(ref r)).height * scale); } private static bool IsToggle(OrderNode n) { string text = Localization.instance.Localize("$huskarl_cmd_passive_on"); string text2 = Localization.instance.Localize("$huskarl_cmd_passive_off"); string text3 = Localization.instance.Localize("$huskarl_cmd_immortal_on"); string text4 = Localization.instance.Localize("$huskarl_cmd_immortal_off"); if (!(n.Label == text) && !(n.Label == text2) && !(n.Label == text3)) { return n.Label == text4; } return true; } } internal static class UiStyle { public static GUIStyle Window; public static GUIStyle Title; public static GUIStyle Button; public static GUIStyle Hover; public static GUIStyle Active; public static GUIStyle Disabled; public static GUIStyle Hint; public static GUIStyle Center; public static GUIStyle Sector; public static GUIStyle SectorActive; public static GUIStyle SectorDisabled; public static Texture2D Border; public static Texture2D Disc; private static Texture2D s_bg; private static Texture2D s_btn; private static Texture2D s_btnHover; private static Texture2D s_btnActive; private static Font s_font; public static float Scale => Mathf.Max(0.75f, (float)Screen.height / 1080f); private static Texture2D Tex(Color c) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1) { hideFlags = (HideFlags)61 }; val.SetPixel(0, 0, c); val.Apply(); return val; } private static Texture2D MakeDisc(int size, Color inner, Color edge) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false) { hideFlags = (HideFlags)61 }; float num = (float)size * 0.5f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(num, num)) / num; Color val2 = ((num2 > 1f) ? Color.clear : ((num2 > 0.97f) ? edge : Color.Lerp(inner, new Color(inner.r, inner.g, inner.b, inner.a * 0.55f), num2))); if (num2 > 0.985f && num2 <= 1f) { val2.a *= (1f - num2) / 0.015f; } val.SetPixel(j, i, val2); } } val.Apply(); return val; } public static void Init() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_0161: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Expected O, but got Unknown //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0214: 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_0238: Expected O, but got Unknown //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Expected O, but got Unknown //IL_0268: 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_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Expected O, but got Unknown //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Expected O, but got Unknown //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Expected O, but got Unknown //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0354: 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_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0383: 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_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: 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_03d6: Expected O, but got Unknown //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Expected O, but got Unknown //IL_03fb: Expected O, but got Unknown //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Expected O, but got Unknown //IL_0420: Expected O, but got Unknown //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Expected O, but got Unknown //IL_0445: Expected O, but got Unknown if (Window != null && Object.op_Implicit((Object)(object)s_bg)) { return; } Font[] array = Resources.FindObjectsOfTypeAll<Font>(); foreach (Font val in array) { if (((Object)val).name == "AveriaSerifLibre-Bold") { s_font = val; } } s_bg = Tex(new Color(0.11f, 0.085f, 0.06f, 0.94f)); Border = Tex(new Color(0.78f, 0.6f, 0.3f, 1f)); s_btn = Tex(new Color(0.22f, 0.17f, 0.12f, 0.95f)); s_btnHover = Tex(new Color(0.36f, 0.27f, 0.17f, 1f)); s_btnActive = Tex(new Color(0.52f, 0.37f, 0.16f, 1f)); Disc = MakeDisc(512, new Color(0.08f, 0.06f, 0.04f, 0.85f), new Color(0.78f, 0.6f, 0.3f, 0.9f)); GUIStyle val2 = new GUIStyle(); val2.normal.background = s_bg; val2.padding = new RectOffset(18, 18, 14, 16); Window = val2; GUIStyle val3 = new GUIStyle { font = s_font, fontSize = 26, alignment = (TextAnchor)4 }; val3.normal.textColor = new Color(1f, 0.86f, 0.55f); Title = val3; GUIStyle val4 = new GUIStyle { font = s_font, fontSize = 15, alignment = (TextAnchor)4, wordWrap = true }; val4.normal.textColor = new Color(0.75f, 0.7f, 0.62f); Hint = val4; GUIStyle val5 = new GUIStyle { font = s_font, fontSize = 22, alignment = (TextAnchor)4, wordWrap = true }; val5.normal.textColor = new Color(0.98f, 0.93f, 0.82f); Center = val5; GUIStyle val6 = new GUIStyle { font = s_font, fontSize = 19, alignment = (TextAnchor)3, padding = new RectOffset(14, 10, 6, 6) }; val6.normal.background = s_btn; val6.normal.textColor = new Color(0.95f, 0.9f, 0.8f); val6.hover.background = s_btnHover; val6.hover.textColor = Color.white; val6.active.background = s_btnActive; val6.active.textColor = Color.white; Button = val6; GUIStyle val7 = new GUIStyle(Button); val7.normal.background = s_btnHover; val7.normal.textColor = Color.white; Hover = val7; GUIStyle val8 = new GUIStyle(Button); val8.normal.background = s_btnActive; val8.normal.textColor = Color.white; Active = val8; GUIStyle val9 = new GUIStyle(Button); val9.normal.background = s_btn; val9.normal.textColor = new Color(0.62f, 0.57f, 0.5f); val9.hover.background = s_btn; val9.hover.textColor = new Color(0.62f, 0.57f, 0.5f); val9.active.background = s_btn; val9.active.textColor = new Color(0.62f, 0.57f, 0.5f); Disabled = val9; Sector = new GUIStyle(Button) { alignment = (TextAnchor)4, padding = new RectOffset(8, 8, 6, 6) }; SectorActive = new GUIStyle(Active) { alignment = (TextAnchor)4, padding = new RectOffset(8, 8, 6, 6) }; SectorDisabled = new GUIStyle(Disabled) { alignment = (TextAnchor)4, padding = new RectOffset(8, 8, 6, 6) }; } } internal static class CommandWheel { internal static bool s_rawScroll; private const float GotoRange = 120f; private static List<HuskarlNpc> s_squad; private static GameObject s_target; private static string s_targetName = ""; private static Vector3? s_ground; private static readonly Stack<string> s_path = new Stack<string>(); private static int s_selected; private static Vector2 s_lastMouse; private static float s_openedAt; private static int s_openFrame; private static int s_targetMask; private static int s_groundMask; private static List<OrderNode> s_nodes = new List<OrderNode>(); private static string s_title = ""; public static bool IsOpen { get; private set; } private static bool ModifierHeld() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 KeyCode wheelModifier = Cfg.WheelModifier; if ((int)wheelModifier == 0) { return false; } if (ZInput.GetKey(wheelModifier, false)) { return true; } if ((int)wheelModifier == 304) { return ZInput.GetKey((KeyCode)303, false); } if ((int)wheelModifier == 306) { return ZInput.GetKey((KeyCode)305, false); } if ((int)wheelModifier == 308) { return ZInput.GetKey((KeyCode)307, false); } return false; } private static bool CanOpenNow() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).InPlaceMode() || ((Character)localPlayer).InCutscene()) { return false; } if (CommandMenu.IsOpen || InventoryGui.IsVisible() || Menu.IsVisible() || TextInput.IsVisible() || Minimap.IsOpen() || Console.IsVisible() || (Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus()) || Hud.InRadial() || Hud.IsPieceSelectionVisible()) { return false; } return !StoreGui.IsVisible(); } public static bool EatScroll() { if (s_rawScroll) { return false; } if (!IsOpen && !GameWheel.IsOpen) { if (ModifierHeld()) { return CanOpenNow(); } return false; } return true; } private static float RawScroll() { s_rawScroll = true; try { return ZInput.GetMouseScrollWheel(); } finally { s_rawScroll = false; } } public static void Update() { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if (IsOpen) { Player localPlayer = Player.m_localPlayer; s_squad?.RemoveAll((HuskarlNpc n) => !Object.op_Implicit((Object)(object)n) || ((Character)n).IsDead()); if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || s_squad == null || s_squad.Count == 0 || InventoryGui.IsVisible() || Menu.IsVisible() || TextInput.IsVisible() || Minimap.IsOpen()) { Close(); } else { HandleInput(); } } else if (GameWheel.IsOpen) { if ((int)Cfg.WheelKey != 0 && ZInput.GetKeyDown(Cfg.WheelKey, false)) { GameWheel.Close(); } } else if (CanOpenNow()) { bool flag = false; if (ModifierHeld()) { flag = RawScroll() != 0f; } if ((int)Cfg.WheelKey != 0 && ZInput.GetKeyDown(Cfg.WheelKey, false)) { flag = true; } if (flag) { Open(); } } } public static void Open() { Open(classic: false); } private static void Open(bool classic) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; s_squad = Orders.Squad(localPlayer, Cfg.SquadRadius); if (s_squad.Count == 0) { ((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("$huskarl_no_squad"), 0, (Sprite)null, false); return; } s_target = PickTarget(s_squad[0], out s_targetName); s_ground = (Object.op_Implicit((Object)(object)s_target) ? ((Vector3?)null) : PickGround()); s_path.Clear(); s_selected = 0; s_lastMouse = new Vector2(-1f, -1f); s_openedAt = Time.time; s_openFrame = Time.frameCount; if (!classic && Cfg.GameStyleWheel && GameWheel.Available()) { string title; List<OrderNode> nodes = CurrentNodes(out title); s_squad = null; s_target = null; s_ground = null; if (!GameWheel.Open(title, nodes)) { Plugin.Log.LogWarning((object)"The game's radial menu did not open, using the classic wheel"); Open(classic: true); } } else { IsOpen = true; s_nodes = CurrentNodes(out s_title); } } public static void Close() { if (IsOpen) { InputGuard.Arm(); } IsOpen = false; s_squad = null; s_target = null; s_ground = null; s_path.Clear(); } private static GameObject PickTarget(HuskarlNpc lead, out string name) { //IL_009c: 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_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) name = ""; if (!Object.op_Implicit((Object)(object)GameCamera.instance)) { return null; } if (s_targetMask == 0) { s_targetMask = LayerMask.GetMask(new string[12] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox", "character_noenv", "vehicle" }); } Transform transform = ((Component)GameCamera.instance).transform; RaycastHit[] array = Physics.RaycastAll(transform.position, transform.forward, 60f, s_targetMask, (QueryTriggerInteraction)2); Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); Player localPlayer = Player.m_localPlayer; RaycastHit[] array2 = array; for (int num = 0; num < array2.Length; num++) { RaycastHit val = array2[num]; Collider collider = ((RaycastHit)(ref val)).collider; GameObject val2 = (Object.op_Implicit((Object)(object)collider.attachedRigidbody) ? ((Component)collider.attachedRigidbody).gameObject : ((Component)collider).gameObject); if (Object.op_Implicit((Object)(object)localPlayer) && val2.transform.IsChildOf(((Component)localPlayer).transform)) { continue; } Character componentInParent = val2.GetComponentInParent<Character>(); if (Object.op_Implicit((Object)(object)componentInParent)) { if (!(componentInParent is HuskarlNpc) && !componentInParent.IsPlayer()) { if (componentInParent.IsDead() || !BaseAI.IsEnemy((Character)(object)lead, componentInParent)) { return null; } name = componentInParent.GetHoverName(); return ((Component)componentInParent).gameObject; } continue; } Pickable componentInParent2 = ((Component)collider).GetComponentInParent<Pickable>(); if (Object.op_Implicit((Object)(object)componentInParent2)) { if (!componentInParent2.CanBePicked()) { return null; } name = Localization.instance.Localize(componentInParent2.GetHoverName()); return ((Component)componentInParent2).gameObject; } if (!collider.isTrigger) { GameObject val3 = Projectile.FindHitObject(collider); if (!Object.op_Implicit((Object)(object)val3) || !Targets.RoleFor(val3, out var role)) { break; } Hoverable component = val3.GetComponent<Hoverable>(); string text = ((component != null) ? Localization.instance.Localize(component.GetHoverName()) : ""); name = ((text.Length > 0) ? text : Localization.instance.Localize((role == Role.Axe) ? "$huskarl_target_tree" : "$huskarl_target_rock")); return val3; } } return NearCrosshairCreature(lead, transform, out name); } private static Vector3? PickGround() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)GameCamera.instance)) { return null; } if (s_groundMask == 0) { s_groundMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" }); } Transform transform = ((Component)GameCamera.instance).transform; RaycastHit[] array = Physics.RaycastAll(transform.position, transform.forward, 120f, s_groundMask, (QueryTriggerInteraction)1); Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); Player localPlayer = Player.m_localPlayer; RaycastHit[] array2 = array; float num2 = default(float); for (int num = 0; num < array2.Length; num++) { RaycastHit val = array2[num]; if ((!Object.op_Implicit((Object)(object)localPlayer) || !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)localPlayer).transform)) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Character>())) { Vector3 val2 = ((RaycastHit)(ref val)).point; if (((RaycastHit)(ref val)).normal.y < 0.5f) { Vector3 val3 = val2; Vector3 val4 = VectorExtensions.Horizontal(transform.forward); val2 = val3 - ((Vector3)(ref val4)).normalized * 1f; } if (Object.op_Implicit((Object)(object)ZoneSystem.instance) && ZoneSystem.instance.GetSolidHeight(val2 + Vector3.up * 1.5f, ref num2, 1000) && num2 < val2.y + 3f) { val2.y = num2; } if (Object.op_Implicit((Object)(object)ZoneSystem.instance) && val2.y < ZoneSystem.instance.m_waterLevel - 0.6f && ((Component)((RaycastHit)(ref val)).collider).gameObject.layer == LayerMask.NameToLayer("terrain")) { return null; } return val2; } } return null; } private static GameObject NearCrosshairCreature(HuskarlNpc lead, Transform cam, out string name) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) name = ""; Character val = null; float num = 4f; foreach (Character allCharacter in Character.GetAllCharacters()) { if (!Object.op_Implicit((Object)(object)allCharacter) || allCharacter.IsDead() || allCharacter.IsPlayer() || allCharacter is HuskarlNpc || !BaseAI.IsEnemy((Character)(object)lead, allCharacter)) { continue; } Vector3 val2 = allCharacter.GetCenterPoint() - cam.position; if (!(((Vector3)(ref val2)).magnitude > 60f)) { float num2 = Vector3.Angle(cam.forward, val2); if (num2 < num) { val = allCharacter; num = num2; } } } if (!Object.op_Implicit((Object)(object)val)) { return null; } name = val.GetHoverName(); return ((Component)val).gameObject; } private static List<OrderNode> CurrentNodes(out string title) { List<OrderNode> list = Orders.Build(s_squad, s_target, s_targetName, s_ground, single: false); title = ((s_squad.Count == 1) ? s_squad[0].GetHelperName() : Localization.instance.Localize("$huskarl_squad", new string[1] { s_squad.Count.ToString() })); List<string> list2 = new List<string>(s_path); list2.Reverse(); foreach (string step in list2) { OrderNode orderNode = list.Find((OrderNode n) => n.Label == step && n.Children != null); if (orderNode == null) { break; } list = orderNode.Children; title = orderNode.Label; } return list; } private static void Activate(OrderNode n) { if (n != null && n.Enabled) { if (n.Children != null) { s_path.Push(n.Label); s_selected = 0; } else { n.Run?.Invoke(); Close(); } } } private static void Back() { if (s_path.Count > 0) { s_path.Pop(); s_selected = 0; } else { Close(); } } private static void HandleInput() { //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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) s_nodes = CurrentNodes(out s_title); int count = s_nodes.Count; if (count == 0) { return; } s_selected = Mathf.Clamp(s_selected, 0, count - 1); Vector2 val = InputGuard.Pointer(); if (s_lastMouse.x >= 0f) { Vector2 val2 = val - s_lastMouse; if (((Vector2)(ref val2)).sqrMagnitude > 4f) { Vector2 val3 = val - new Vector2((float)Screen.width * 0.5f, (float)Screen.height * 0.5f); if (((Vector2)(ref val3)).magnitude > 70f * UiStyle.Scale) { float num = Mathf.Atan2(val3.x, 0f - val3.y) * 57.29578f; if (num < 0f) { num += 360f; } s_selected = Mathf.RoundToInt(num / (360f / (float)count)) % count; } } } s_lastMouse = val; if (Time.frameCount == s_openFrame) { return; } float num2 = RawScroll(); if (num2 != 0f) { s_selected = (s_selected + ((num2 < 0f) ? 1 : (count - 1))) % count; } if (InputGuard.KeyDown((KeyCode)27) || ZInput.GetButtonDown("JoyButtonB")) { Close(); } else { if (Time.time - s_openedAt < 0.1f) { return; } if (InputGuard.KeyDown((KeyCode)8) || ZInput.GetMouseButtonDown(1)) { Back(); return; } if (ZInput.GetMouseButtonDown(0) || InputGuard.KeyDown((KeyCode)13) || InputGuard.KeyDown((KeyCode)271) || InputGuard.KeyDown((KeyCode)32)) { Activate(s_nodes[s_selected]); return; } int num3 = InputGuard.DigitDown(); if (num3 >= 0 && num3 < count) { Activate(s_nodes[num3]); } } } public static void OnGUI() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0181: 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_0263: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) if (!IsOpen || s_squad == null || s_squad.Count == 0 || s_nodes == null) { return; } UiStyle.Init(); List<OrderNode> list = s_nodes; bool flag = s_path.Count > 0; int count = list.Count; if (count == 0) { return; } int num = Mathf.Clamp(s_selected, 0, count - 1); float scale = UiStyle.Scale; Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(scale, scale, 1f)); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor((float)Screen.width / scale * 0.5f, (float)Screen.height / scale * 0.5f); float num2 = ((count > 8) ? 240f : 220f); float num3 = ((count > 8) ? 345f : 290f); float num4 = num2 * 2f + 260f; float num5 = num3 * 2f + 260f; GUI.DrawTexture(new Rect(val.x - num5 * 0.5f, val.y - num4 * 0.5f, num5, num4), (Texture)(object)UiStyle.Disc); Vector2 val2 = default(Vector2); Rect val3 = default(Rect); for (int i = 0; i < count; i++) { OrderNode orderNode = list[i]; float num6 = (float)i * (float)Math.PI * 2f / (float)count; ((Vector2)(ref val2))..ctor(val.x + Mathf.Sin(num6) * num3, val.y - Mathf.Cos(num6) * num2); ((Rect)(ref val3))..ctor(val2.x - 115f, val2.y - 22f, 230f, 44f);