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 VanillaNPC v1.1.0
plugins/VanillaNPC.dll
Decompiled 9 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.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FjordFolk.Bandits; using FjordFolk.Beggar; using FjordFolk.Fisher; using FjordFolk.Guards; using FjordFolk.Recruiters; using FjordFolk.Tavern; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("VanillaNPC")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("VanillaNPC")] [assembly: AssemblyTitle("VanillaNPC")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FjordFolk { internal static class Loc { private const string Prefix = "fjordfolk_"; private static readonly string[] Languages = new string[2] { "English", "Russian" }; public static void Register() { string[] languages = Languages; for (int i = 0; i < languages.Length; i++) { string text = languages[i]; string text2 = "FjordFolk.Localization." + text + ".txt"; using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text2); if (stream == null) { FjordFolkPlugin.Log.LogError((object)("embedded " + text2 + " not found")); continue; } using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); Dictionary<string, string> dictionary = Parse(streamReader.ReadToEnd()); LocalizationManager.Instance.GetLocalization().AddTranslation(ref text, dictionary); } } public static string Token(string key) { return "$fjordfolk_" + key; } public static string T(string key) { if (Localization.instance == null) { return key; } return Localization.instance.Localize(Token(key)); } public static string T(string key, params object[] args) { return string.Format(T(key), args); } private static Dictionary<string, string> Parse(string text) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); string[] array = text.Split('\n'); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim().TrimStart('\ufeff'); if (text2.Length != 0 && !text2.StartsWith("#")) { int num = text2.IndexOf('='); if (num > 0) { string text3 = text2.Substring(0, num).Trim(); string value = text2.Substring(num + 1).Trim().Replace("\\n", "\n"); dictionary["fjordfolk_" + text3] = value; } } } return dictionary; } } public class NpcActor : MonoBehaviour, Hoverable, Interactable { public int m_presetId; [NonSerialized] public bool m_portrait; [NonSerialized] public string m_poseOverride; private static readonly int s_appearanceVersion = StringExtensionMethods.GetStableHashCode("fjordfolk_appearance_v1"); private ZNetView m_nview; private VisEquipment m_vis; private FisherWorkplace m_work; private BeggarBehaviour m_beggar; private RecruiterCamp m_camp; private CraftingStation m_station; private Innkeeper m_inn; private Drunkard m_drunk; private NpcPreset m_preset; private NpcEmotes m_emotes; private void Awake() { FjordFolkPlugin.Guard("NpcActor.Awake", delegate { m_nview = ((Component)this).GetComponent<ZNetView>(); m_vis = ((Component)this).GetComponent<VisEquipment>(); m_work = ((Component)this).GetComponent<FisherWorkplace>(); m_beggar = ((Component)this).GetComponent<BeggarBehaviour>(); m_camp = ((Component)this).GetComponent<RecruiterCamp>(); m_station = ((Component)this).GetComponent<CraftingStation>(); m_inn = ((Component)this).GetComponent<Innkeeper>(); m_drunk = ((Component)this).GetComponent<Drunkard>(); m_preset = NpcPresets.Get(m_presetId); if ((Object)(object)m_vis == (Object)null || m_preset == null) { FjordFolkPlugin.Log.LogWarning((object)$"{((Object)this).name}: missing VisEquipment or preset {m_presetId}"); } else { ZDO val = (((Object)(object)m_nview != (Object)null) ? m_nview.GetZDO() : null); if (val == null) { DressGhost(m_preset); } else if (m_nview.IsOwner() && !val.GetBool(s_appearanceVersion, false)) { WriteAppearance(val, m_preset); val.Set(s_appearanceVersion, true); } } }); } private void Start() { FjordFolkPlugin.Guard("NpcActor.Start", delegate { Animator componentInChildren = ((Component)this).GetComponentInChildren<Animator>(); if (!((Object)(object)componentInChildren == (Object)null) && m_preset != null) { m_emotes = new NpcEmotes(componentInChildren); m_emotes.SkipWakeup(); if (!m_portrait) { ApplyPose(); } } }); } private void WriteAppearance(ZDO zdo, NpcPreset p) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) zdo.Set(ZDOVars.s_modelIndex, p.Model, false); zdo.Set(ZDOVars.s_skinColor, p.SkinColor); zdo.Set(ZDOVars.s_hairColor, p.HairColor); zdo.Set(ZDOVars.s_hairItem, ItemHash(HairName(p)), false); zdo.Set(ZDOVars.s_beardItem, ItemHash(BeardName(p)), false); zdo.Set(ZDOVars.s_chestItem, ItemHash(p.Chest), false); zdo.Set(ZDOVars.s_legItem, ItemHash(p.Legs), false); zdo.Set(ZDOVars.s_helmetItem, ItemHash(p.Helmet), false); zdo.Set(ZDOVars.s_shoulderItem, ItemHash(p.Shoulder), false); zdo.Set(ZDOVars.s_rightItem, ItemHash(p.RightItem), false); zdo.Set(ZDOVars.s_leftItem, ItemHash(p.LeftItem), false); } private void DressGhost(NpcPreset p) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_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) m_vis.m_modelIndex = p.Model; m_vis.m_skinColor = p.SkinColor; m_vis.m_hairColor = p.HairColor; m_vis.m_hairItem = ItemHash(HairName(p)); m_vis.m_beardItem = ItemHash(BeardName(p)); m_vis.m_chestItem = ItemHash(p.Chest); m_vis.m_legItem = ItemHash(p.Legs); m_vis.m_helmetItem = ItemHash(p.Helmet); m_vis.m_shoulderItem = ItemHash(p.Shoulder); m_vis.m_rightItem = ItemHash(p.RightItem); m_vis.m_leftItem = ItemHash(p.LeftItem); } private static string HairName(NpcPreset p) { return Customization("Hair", p.HairIndex); } private static string BeardName(NpcPreset p) { return Customization("Beard", p.BeardIndex); } internal static string Customization(string prefix, int index) { if (index <= 0 || (Object)(object)ObjectDB.instance == (Object)null) { return ""; } List<string> list = (from i in ObjectDB.instance.GetAllItems((ItemType)10, prefix) where (Object)(object)i != (Object)null && !((Object)i).name.EndsWith("None") select ((Object)i).name into n orderby n.Length, n select n).ToList(); if (list.Count != 0) { return list[Mathf.Clamp(index, 1, list.Count) - 1]; } return ""; } private int ItemHash(string itemName) { if (string.IsNullOrEmpty(itemName)) { return 0; } if ((Object)(object)ObjectDB.instance != (Object)null && (Object)(object)ObjectDB.instance.GetItemPrefab(itemName) == (Object)null) { FjordFolkPlugin.Log.LogWarning((object)(((Object)this).name + ": item '" + itemName + "' does not exist, slot left empty")); return 0; } return StringExtensionMethods.GetStableHashCode(itemName); } private void ApplyPose() { if (m_emotes != null && m_preset != null) { ((MonoBehaviour)this).CancelInvoke("ApplyPose"); string text = ((!string.IsNullOrEmpty(m_poseOverride)) ? m_poseOverride : m_preset.Pose); if (string.IsNullOrEmpty(text)) { m_emotes.StopAll(); } else if (m_emotes.Play(text) == "missing") { FjordFolkPlugin.Log.LogWarning((object)(((Object)this).name + ": pose '" + text + "' not in animator")); } } } public void PlayGestureLocal(string emote, float returnAfter = 3.5f) { if (m_emotes != null && !string.IsNullOrEmpty(emote)) { ((MonoBehaviour)this).CancelInvoke("ApplyPose"); m_emotes.Play(emote); if (returnAfter > 0f) { ((MonoBehaviour)this).Invoke("ApplyPose", returnAfter); } } } public void ReturnToPose() { ApplyPose(); } public string GetHoverName() { if (m_preset == null) { return ""; } return m_preset.Name; } public string GetHoverText() { if (m_preset == null) { return ""; } if ((Object)(object)m_work != (Object)null && m_work.IsLive) { return m_work.HoverText(m_preset.Name); } if ((Object)(object)m_beggar != (Object)null && m_beggar.IsLive) { return m_beggar.HoverText(m_preset.Name); } if ((Object)(object)m_camp != (Object)null && (Object)(object)m_nview != (Object)null && m_nview.IsValid()) { return m_camp.HoverText(m_preset.Name); } if ((Object)(object)m_inn != (Object)null && (Object)(object)m_nview != (Object)null && m_nview.IsValid()) { return m_inn.HoverText(m_preset.Name); } if ((Object)(object)m_drunk != (Object)null && (Object)(object)m_nview != (Object)null && m_nview.IsValid()) { return m_drunk.HoverText(m_preset.Name); } return m_preset.Name; } public float GetHoverOffset() { return 0f; } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold || m_preset == null) { return false; } FjordFolkPlugin.Guard("NpcActor.Interact", delegate { if ((Object)(object)m_work != (Object)null) { if (m_work.IsLive && !FisherPanel.JustClosed) { FisherPanel.Open(m_work); } } else if ((Object)(object)m_beggar != (Object)null) { m_beggar.GiveCoin(user); } else if ((Object)(object)m_inn != (Object)null) { m_inn.OpenShop(user); } else if ((Object)(object)m_drunk != (Object)null) { m_drunk.Interact(user); } else if ((Object)(object)m_station != (Object)null) { m_station.Interact(user, false, alt); } }); return true; } public bool UseItem(Humanoid user, ItemData item) { if ((Object)(object)m_beggar == (Object)null || !m_beggar.IsLive || !BeggarBehaviour.IsCoin(item)) { return false; } FjordFolkPlugin.Guard("NpcActor.UseItem", delegate { m_beggar.GiveCoin(user); }); return true; } public void Say(string text) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Chat.instance.SetNpcText(((Component)this).gameObject, Vector3.up * 2.1f, 25f, 6f, "", text, false); } } internal sealed class NpcDialogue { private const string EmbeddedPrefix = "FjordFolk.Dialogue."; private static readonly string[] FallbackLanguages = new string[2] { "English", "Russian" }; private static readonly Dictionary<string, NpcDialogue> s_cache = new Dictionary<string, NpcDialogue>(); private static readonly Random s_random = new Random(); private readonly Dictionary<string, List<string>> m_sections; private readonly Dictionary<string, Queue<string>> m_bags = new Dictionary<string, Queue<string>>(); private readonly Dictionary<string, string> m_lastPicked = new Dictionary<string, string>(); public string Source { get; } private NpcDialogue(Dictionary<string, List<string>> sections, string source) { m_sections = sections; Source = source; } public static NpcDialogue For(string dialogueId) { string text = ((Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "English"); string key = dialogueId + "|" + text; if (s_cache.TryGetValue(key, out var value)) { return value; } NpcDialogue npcDialogue = Load(dialogueId, text); s_cache[key] = npcDialogue; FjordFolkPlugin.Log.LogDebug((object)("dialogue '" + dialogueId + "' for " + text + ": " + npcDialogue.Source + ", " + $"{npcDialogue.m_sections.Count} sections, {Total(npcDialogue.m_sections)} lines")); return npcDialogue; } public bool Has(string section) { if (m_sections.TryGetValue(section, out var value)) { return value.Count > 0; } return false; } public string Pick(string section) { if (!Has(section)) { return null; } if (!m_bags.TryGetValue(section, out var value) || value.Count == 0) { value = Refill(section); m_bags[section] = value; } string text = value.Dequeue(); m_lastPicked[section] = text; return text; } private Queue<string> Refill(string section) { List<string> list = new List<string>(m_sections[section]); for (int num = list.Count - 1; num > 0; num--) { int num2 = s_random.Next(num + 1); List<string> list2 = list; int index = num; List<string> list3 = list; int index2 = num2; string value = list[num2]; string value2 = list[num]; list2[index] = value; list3[index2] = value2; } if (list.Count > 1 && m_lastPicked.TryGetValue(section, out var value3) && list[0] == value3) { List<string> list3 = list; List<string> list2 = list; int index2 = list.Count - 1; string value2 = list[list.Count - 1]; string value = list[0]; list3[0] = value2; list2[index2] = value; } return new Queue<string>(list); } private static NpcDialogue Load(string dialogueId, string language) { List<string> list = new List<string> { language }; string[] fallbackLanguages = FallbackLanguages; foreach (string item in fallbackLanguages) { if (!list.Contains(item)) { list.Add(item); } } foreach (string item2 in list) { string text = dialogueId + "." + item2 + ".txt"; string text2 = Path.Combine(Paths.ConfigPath, "VanillaNPC", "dialogue", text); if (File.Exists(text2)) { return new NpcDialogue(Parse(File.ReadAllText(text2, Encoding.UTF8)), "override " + text2); } using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FjordFolk.Dialogue." + text); if (stream == null) { continue; } using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); string source = ((item2 == language) ? ("embedded " + text) : ("embedded " + text + " (no " + language + " translation)")); return new NpcDialogue(Parse(streamReader.ReadToEnd()), source); } FjordFolkPlugin.Log.LogWarning((object)("no dialogue file for '" + dialogueId + "' in any language")); return new NpcDialogue(new Dictionary<string, List<string>>(), "none"); } private static Dictionary<string, List<string>> Parse(string text) { Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase); List<string> value = null; string[] array = text.Split('\n'); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim().TrimStart('\ufeff'); if (text2.Length == 0 || text2.StartsWith("#")) { continue; } if (text2.StartsWith("[") && text2.EndsWith("]")) { string key = text2.Substring(1, text2.Length - 2).Trim(); if (!dictionary.TryGetValue(key, out value)) { value = (dictionary[key] = new List<string>()); } } else { value?.Add(text2); } } return dictionary; } private static int Total(Dictionary<string, List<string>> sections) { int num = 0; foreach (List<string> value in sections.Values) { num += value.Count; } return num; } } internal sealed class NpcEmotes { private static bool s_parametersLogged; private readonly Animator m_animator; private readonly Dictionary<string, AnimatorControllerParameter> m_params = new Dictionary<string, AnimatorControllerParameter>(); private string m_activeLoop; public NpcEmotes(Animator animator) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) m_animator = animator; AnimatorControllerParameter[] parameters = animator.parameters; foreach (AnimatorControllerParameter val in parameters) { m_params[val.name.ToLowerInvariant()] = val; } if (!s_parametersLogged) { s_parametersLogged = true; List<string> list = new List<string>(); parameters = animator.parameters; foreach (AnimatorControllerParameter val2 in parameters) { list.Add($"{val2.name}:{val2.type}"); } FjordFolkPlugin.Log.LogDebug((object)string.Format("animator parameters ({0}): {1}", list.Count, string.Join(", ", list))); } } public void SkipWakeup() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 if (m_params.TryGetValue("wakeup", out var value) && (int)value.type == 4) { m_animator.SetBool(value.name, false); } } public string Play(string emote) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Invalid comparison between Unknown and I4 //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Invalid comparison between Unknown and I4 string key = (emote.StartsWith("attach_", StringComparison.OrdinalIgnoreCase) ? emote.ToLowerInvariant() : ("emote_" + emote.ToLowerInvariant())); if (!m_params.TryGetValue(key, out var value)) { return "missing"; } StopLoop(); if (m_params.TryGetValue("emote_stop", out var value2)) { m_animator.ResetTrigger(value2.name); } AnimatorControllerParameterType type = value.type; if ((int)type != 4) { if ((int)type == 9) { m_animator.SetTrigger(value.name); return "once"; } return "missing"; } m_animator.SetBool(value.name, true); m_activeLoop = value.name; return "loop"; } public void StopAll() { StopLoop(); if (m_params.TryGetValue("emote_stop", out var value)) { m_animator.SetTrigger(value.name); } } private void StopLoop() { if (!string.IsNullOrEmpty(m_activeLoop)) { m_animator.SetBool(m_activeLoop, false); m_activeLoop = null; if (m_params.TryGetValue("emote_stop", out var value)) { m_animator.SetTrigger(value.name); } } } } public class NpcGreeter : MonoBehaviour { public string m_dialogueId = ""; public float m_greetRange = 5f; public float m_byeRange = 9f; public string m_gesture = "wave"; public bool m_holdGesture; private const float CheckInterval = 0.25f; private const float QuickReturnWindow = 120f; private const float PestWindow = 150f; private const int PestVisits = 2; private const float ShortVisit = 6f; private ZNetView m_nview; private NpcActor m_actor; private bool m_near; private float m_nearSince; private float m_leftAt = -9999f; private readonly List<float> m_visits = new List<float>(); private float m_nextCheck; private string m_pending; private float m_pendingAt; private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); m_actor = ((Component)this).GetComponent<NpcActor>(); } private void Update() { if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid() || string.IsNullOrEmpty(m_dialogueId)) { return; } if (m_pending != null && Time.time >= m_pendingAt) { string action = m_pending; m_pending = null; FjordFolkPlugin.Guard("NpcGreeter." + action, delegate { Perform(action); }); } if (!(Time.time < m_nextCheck)) { m_nextCheck = Time.time + 0.25f; FjordFolkPlugin.Guard("NpcGreeter.Update", CheckPlayer); } } private void CheckPlayer() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { return; } float num = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position); if (!m_near && num < m_greetRange) { m_near = true; m_nearSince = Time.time; Schedule("greet", Random.Range(0.35f, 1.1f)); } else if (m_near && num > m_byeRange) { m_near = false; if (m_pending == "greet") { m_pending = null; return; } m_leftAt = Time.time; Schedule("bye", Random.Range(0.2f, 0.7f)); } } private void Schedule(string action, float delay) { m_pending = action; m_pendingAt = Time.time + delay; } private void Perform(string action) { NpcDialogue dialogue = NpcDialogue.For(m_dialogueId); if (action == "greet") { Greet(dialogue); } else { Goodbye(dialogue); } } private void Greet(NpcDialogue dialogue) { m_visits.RemoveAll((float t) => Time.time - t > 150f); int count = m_visits.Count; m_visits.Add(Time.time); string text = ((count >= 2) ? "greet_pest" : ((!(Time.time - m_leftAt < 120f)) ? (Lore(dialogue) ?? Situational("greet", "greet_first", dialogue)) : "greet_again")); bool flag = text == "greet_pest"; bool num = flag || m_holdGesture || Random.value < 0.85f; bool flag2 = !string.IsNullOrEmpty(m_gesture) && (m_holdGesture || (!flag && Random.value < 0.8f)); if (flag2) { m_actor?.PlayGestureLocal(m_gesture, m_holdGesture ? 0f : 3.5f); } string text2 = (num ? (dialogue.Pick(text) ?? dialogue.Pick("greet_first")) : null); if (text2 != null) { m_actor?.Say(text2); } Report("greet", text, flag2, text2); } private void Goodbye(NpcDialogue dialogue) { if (m_holdGesture) { m_actor?.ReturnToPose(); } string section = ((Time.time - m_nearSince < 6f && Random.value < 0.7f) ? "bye_short" : Situational("bye", "bye", dialogue)); string text = ((Random.value < 0.7f) ? (dialogue.Pick(section) ?? dialogue.Pick("bye")) : null); if (text != null) { m_actor?.Say(text); } Report("bye", section, gestured: false, text); } private static string Lore(NpcDialogue dialogue) { if (dialogue.Has("greet_brother") && BeggarLore.MetRecently && Random.value < 0.5f) { return "greet_brother"; } if (dialogue.Has("greet_hired") && Random.value < 0.35f && FisherRules.FishermanExists()) { return "greet_hired"; } return null; } private static string Situational(string prefix, string plain, NpcDialogue dialogue) { EnvMan instance = EnvMan.instance; if ((Object)(object)instance == (Object)null) { return plain; } float dayFraction = instance.GetDayFraction(); return Try("rain", EnvMan.IsWet(), 0.45f) ?? Try("night", EnvMan.IsNight(), 0.4f) ?? Try("morning", dayFraction > 0.22f && dayFraction < 0.38f, 0.35f) ?? Try("evening", dayFraction > 0.62f && dayFraction < 0.76f, 0.35f) ?? plain; string Try(string suffix, bool when, float chance) { string text = prefix + "_" + suffix; if (!when || !dialogue.Has(text) || !(Random.value < chance)) { return null; } return text; } } private void Report(string action, string section, bool gestured, string line) { string text = ((line == null) ? "(silent)" : ("\"" + line + "\"")); FjordFolkPlugin.Log.LogDebug((object)(m_dialogueId + " " + action + ": [" + section + "]" + (gestured ? (" +" + m_gesture) : "") + " " + text)); } } internal sealed class NpcIcons : MonoBehaviour { private static readonly List<string> s_prefabs = new List<string>(); private static bool s_started; internal static bool Staging { get; private set; } public static void Add(string prefabName) { if (!s_prefabs.Contains(prefabName)) { s_prefabs.Add(prefabName); } } private void Update() { if (!s_started && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)ObjectDB.instance == (Object)null)) { s_started = true; ((MonoBehaviour)this).StartCoroutine(RenderAll()); } } private IEnumerator RenderAll() { yield return (object)new WaitForSeconds(3f); int rendered = 0; foreach (string s_prefab in s_prefabs) { GameObject prefab = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(s_prefab) : null); Piece piece = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Piece>() : null); if ((Object)(object)piece == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { continue; } GameObject stage = null; Staging = true; FjordFolkPlugin.Guard("NpcIcons.Stage", delegate { stage = Stage(prefab); }); Staging = false; if ((Object)(object)stage == (Object)null) { continue; } yield return (object)new WaitForSeconds(1.5f); Staging = true; FjordFolkPlugin.Guard("NpcIcons.Render", delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) Sprite val = RenderManager.Instance.Render(new RenderRequest(stage) { Width = 128, Height = 128, Rotation = Quaternion.Euler(8f, -30f, 0f), UseCache = false }); if (!((Object)(object)val == (Object)null)) { Rect rect = val.rect; if (!(((Rect)(ref rect)).width <= 1f)) { piece.m_icon = val; int num = rendered; rendered = num + 1; } } }); Staging = false; Object.Destroy((Object)(object)stage); } FjordFolkPlugin.Log.LogDebug((object)$"NPC icons rendered: {rendered} of {s_prefabs.Count}"); } private static GameObject Stage(GameObject prefab) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0031: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)Player.m_localPlayer).transform.position + new Vector3(0f, 600f, 0f); ZNetView.m_forceDisableInit = true; GameObject val2; try { val2 = Object.Instantiate<GameObject>(prefab, val, Quaternion.identity); } finally { ZNetView.m_forceDisableInit = false; } NpcActor component = val2.GetComponent<NpcActor>(); if ((Object)(object)component != (Object)null) { component.m_portrait = true; } Collider[] componentsInChildren = val2.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } Animator[] componentsInChildren2 = val2.GetComponentsInChildren<Animator>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].cullingMode = (AnimatorCullingMode)0; } return val2; } } internal static class NpcPieces { private static readonly HashSet<string> KeepTypes = new HashSet<string> { "Transform", "ZNetView", "VisEquipment", "Animator", "SkinnedMeshRenderer", "MeshRenderer", "MeshFilter", "LODGroup", "CapsuleCollider", "SphereCollider", "BoxCollider", "MeshCollider", "MagicaCloth", "MagicaCapsuleCollider", "MagicaSphereCollider", "MagicaPlaneCollider" }; public static void RegisterAll() { GameObject prefab = PrefabManager.Instance.GetPrefab("Player"); if ((Object)(object)prefab == (Object)null) { FjordFolkPlugin.Log.LogError((object)"vanilla 'Player' prefab not found, nothing registered"); return; } FisherPieces.Register(prefab); BeggarPieces.Register(prefab); GuardPieces.Register(prefab); RecruiterPieces.Register(prefab); TavernPieces.Register(prefab); BanditPieces.Register(prefab); } internal static GameObject BuildNpc(GameObject player, string prefabName, int presetId) { GameObject val = PrefabManager.Instance.CreateClonedPrefab(prefabName, player); Strip(val); ZNetView component = val.GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null) { FjordFolkPlugin.Log.LogError((object)(prefabName + ": ZNetView lost during strip")); return null; } component.m_persistent = true; val.AddComponent<NpcActor>().m_presetId = presetId; NpcPreset npcPreset = NpcPresets.Get(presetId); if (npcPreset != null && !string.IsNullOrEmpty(npcPreset.DialogueId)) { NpcGreeter npcGreeter = val.AddComponent<NpcGreeter>(); npcGreeter.m_dialogueId = npcPreset.DialogueId; npcGreeter.m_gesture = npcPreset.Greet; npcGreeter.m_holdGesture = npcPreset.HoldGreet; } if ((Object)(object)val.GetComponent<Piece>() == (Object)null) { val.AddComponent<Piece>(); } return val; } internal static void AddToHammer(GameObject prefab, string nameToken, string descriptionToken, string iconItem, RequirementConfig[] requirements) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown if (!((Object)(object)prefab == (Object)null)) { PieceConfig val = new PieceConfig { Name = nameToken, Description = descriptionToken, PieceTable = "Hammer", Category = "Misc", Icon = IconOf(iconItem), Requirements = requirements }; PieceManager.Instance.AddPiece(new CustomPiece(prefab, false, val)); NpcIcons.Add(((Object)prefab).name); FjordFolkPlugin.Log.LogDebug((object)("registered " + ((Object)prefab).name)); } } private static void Strip(GameObject prefab) { for (int i = 0; i < 10; i++) { List<Component> list = (from c in prefab.GetComponentsInChildren<Component>(true) where (Object)(object)c != (Object)null && !KeepTypes.Contains(((object)c).GetType().Name) orderby (!(c is MonoBehaviour)) ? 1 : 0 select c).ToList(); if (list.Count == 0) { break; } foreach (Component item in list) { Object.DestroyImmediate((Object)(object)item); } int num = prefab.GetComponentsInChildren<Component>(true).Count((Component c) => (Object)(object)c != (Object)null && !KeepTypes.Contains(((object)c).GetType().Name)); if (num == list.Count) { FjordFolkPlugin.Log.LogWarning((object)$"{((Object)prefab).name}: {num} components could not be removed"); break; } } int num2 = LayerMask.NameToLayer("piece"); Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (val.isTrigger) { Object.DestroyImmediate((Object)(object)val); } else if (num2 >= 0) { ((Component)val).gameObject.layer = num2; } } } internal static Sprite IconOf(string itemName) { GameObject prefab = PrefabManager.Instance.GetPrefab(itemName); Sprite[] array = ((!((Object)(object)prefab != (Object)null)) ? null : prefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_icons); if (array == null || array.Length == 0) { return null; } return array[0]; } } internal sealed class NpcPreset { public int Id; public string NameKey; public int Model; public Vector3 SkinColor; public Vector3 HairColor; public int HairIndex; public int BeardIndex; public string Chest = ""; public string Legs = ""; public string Helmet = ""; public string Shoulder = ""; public string RightItem = ""; public string LeftItem = ""; public string Pose = ""; public string Greet = ""; public bool HoldGreet; public string DialogueId = ""; public string Name => Loc.T(NameKey); } internal static class NpcPresets { public const int FishermanId = 1; public const int BeggarId = 2; public const int RecruiterId = 3; public const int RecruiterGuardLeftId = 4; public const int RecruiterGuardRightId = 5; public const int InnkeeperId = 6; public const int DrunkardId = 7; public const int RegularBodvarId = 8; public const int RegularHjaltiId = 9; private static readonly NpcPreset[] All = new NpcPreset[9] { new NpcPreset { Id = 1, NameKey = "knut_name", Model = 0, SkinColor = new Vector3(0.85f, 0.72f, 0.6f), HairColor = new Vector3(0.62f, 0.28f, 0.12f), HairIndex = 9, BeardIndex = 2, Chest = "ArmorRagsChest", Legs = "ArmorRagsLegs", Helmet = "HelmetFishingHat", RightItem = "FishingRod", Pose = "sit", Greet = "wave", DialogueId = "fisher" }, new NpcPreset { Id = 2, NameKey = "ulv_name", Model = 0, SkinColor = new Vector3(0.85f, 0.72f, 0.6f), HairColor = new Vector3(0.45f, 0.34f, 0.22f), HairIndex = 8, BeardIndex = 10, Chest = "ArmorRagsChest", Legs = "ArmorRagsLegs", Helmet = "HelmetSweatBand", Pose = "sit", Greet = "cower", HoldGreet = true, DialogueId = "beggar" }, new NpcPreset { Id = 3, NameKey = "hrodgeir_name", Model = 0, SkinColor = new Vector3(0.85f, 0.72f, 0.6f), HairColor = new Vector3(0.62f, 0.28f, 0.12f), HairIndex = 7, BeardIndex = 12, Chest = "ArmorTunic6", Legs = "ArmorLeatherLegs", Shoulder = "CapeLox", Helmet = "HelmetHat1", Greet = "comehere", DialogueId = "recruiter" }, new NpcPreset { Id = 4, NameKey = "recruiter_guard_name", Model = 0, SkinColor = new Vector3(0.85f, 0.72f, 0.6f), HairColor = new Vector3(0.45f, 0.34f, 0.22f), HairIndex = 9, BeardIndex = 8, Chest = "ArmorBronzeChest", Legs = "ArmorBronzeLegs", Shoulder = "CapeLinen", Helmet = "HelmetBronze", RightItem = "SpearBronze", LeftItem = "ShieldBronzeBuckler" }, new NpcPreset { Id = 5, NameKey = "recruiter_guard_name", Model = 0, SkinColor = new Vector3(0.85f, 0.72f, 0.6f), HairColor = new Vector3(0.45f, 0.34f, 0.22f), HairIndex = 9, BeardIndex = 8, Chest = "ArmorBronzeChest", Legs = "ArmorBronzeLegs", Shoulder = "CapeLinen", Helmet = "HelmetBronze", RightItem = "SpearBronze", LeftItem = "ShieldBronzeBuckler" }, new NpcPreset { Id = 6, NameKey = "innkeeper_name", Model = 0, SkinColor = new Vector3(0.85f, 0.72f, 0.6f), HairColor = new Vector3(0.62f, 0.28f, 0.12f), HairIndex = 6, BeardIndex = 12, Chest = "ArmorDeepNorthMediumChest", Legs = "ArmorDeepNorthMediumlegs", RightItem = "Tankard", Greet = "toast", DialogueId = "innkeeper" }, new NpcPreset { Id = 7, NameKey = "drunkard_name", Model = 0, SkinColor = new Vector3(0.85f, 0.72f, 0.6f), HairColor = new Vector3(0.45f, 0.34f, 0.22f), HairIndex = 11, BeardIndex = 5, Chest = "ArmorTunic3", Legs = "ArmorRagsLegs", Helmet = "HelmetMidsummerCrown", RightItem = "Tankard_dvergr", Greet = "laugh", DialogueId = "drunkard" }, new NpcPreset { Id = 8, NameKey = "regular_bodvar_name", Model = 0, SkinColor = new Vector3(0.85f, 0.72f, 0.6f), HairColor = new Vector3(0.2f, 0.14f, 0.1f), HairIndex = 3, BeardIndex = 8, Chest = "ArmorTunic5", Legs = "ArmorTrollLeatherLegs", Shoulder = "CapeLinen", Helmet = "HelmetHat8", RightItem = "Tankard", Greet = "toast" }, new NpcPreset { Id = 9, NameKey = "regular_hjalti_name", Model = 0, SkinColor = new Vector3(0.85f, 0.72f, 0.6f), HairColor = new Vector3(0.45f, 0.34f, 0.22f), HairIndex = 6, BeardIndex = 6, Chest = "ArmorTunic8", Legs = "ArmorLeatherLegs", Shoulder = "CapeFeather", Helmet = "HelmetHat2", RightItem = "Tankard", Greet = "toast" } }; public static NpcPreset Get(int id) { NpcPreset[] all = All; foreach (NpcPreset npcPreset in all) { if (npcPreset.Id == id) { return npcPreset; } } return null; } } internal static class PieceKit { public static readonly HashSet<string> Scenery = new HashSet<string> { "Transform", "MeshRenderer", "MeshFilter", "SkinnedMeshRenderer", "Cloth", "LODGroup", "BoxCollider", "CapsuleCollider", "SphereCollider", "MeshCollider" }; public static readonly HashSet<string> Decor = new HashSet<string>(Scenery) { "Light", "LightFlicker", "LightLod", "ParticleSystem", "ParticleSystemRenderer" }; public static void ShowUndamaged(GameObject go) { WearNTear[] componentsInChildren = go.GetComponentsInChildren<WearNTear>(true); foreach (WearNTear val in componentsInChildren) { if ((Object)(object)val.m_worn != (Object)null && (Object)(object)val.m_worn != (Object)(object)val.m_new) { val.m_worn.SetActive(false); } if ((Object)(object)val.m_broken != (Object)null && (Object)(object)val.m_broken != (Object)(object)val.m_new) { val.m_broken.SetActive(false); } if ((Object)(object)val.m_new != (Object)null) { val.m_new.SetActive(true); } } } public static void StripTo(GameObject go, HashSet<string> keep) { for (int i = 0; i < 10; i++) { List<Component> list = (from c in go.GetComponentsInChildren<Component>(true) where (Object)(object)c != (Object)null && !keep.Contains(((object)c).GetType().Name) orderby (!(c is MonoBehaviour)) ? 1 : 0 select c).ToList(); if (list.Count == 0) { break; } foreach (Component item in list) { Object.DestroyImmediate((Object)(object)item); } } } public static void KeepSolidColliders(GameObject go, int layer = -1) { Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (val.isTrigger) { Object.DestroyImmediate((Object)(object)val); } else if (layer >= 0) { ((Component)val).gameObject.layer = layer; } } } public static void RemoveColliders(GameObject go) { Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } } public static Bounds ActiveBounds(Transform root, Transform space) { //IL_0002: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = default(Bounds); bool any = false; Matrix4x4 worldToLocalMatrix = space.worldToLocalMatrix; MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if (IsSwitchedOn(((Component)val).transform, root) && (Object)(object)((Component)val).GetComponent<Renderer>() != (Object)null) { Encapsulate(ref bounds, ref any, val.sharedMesh, worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix); } } SkinnedMeshRenderer[] componentsInChildren2 = ((Component)root).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val2 in componentsInChildren2) { if (IsSwitchedOn(((Component)val2).transform, root)) { Encapsulate(ref bounds, ref any, val2.sharedMesh, worldToLocalMatrix * ((Component)val2).transform.localToWorldMatrix); } } return bounds; } public static Bounds ColliderBounds(Transform root, Transform space) { //IL_0002: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_012a: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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) Bounds bounds = default(Bounds); bool any = false; Matrix4x4 worldToLocalMatrix = space.worldToLocalMatrix; Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (val.isTrigger || !IsSwitchedOn(((Component)val).transform, root)) { continue; } Matrix4x4 matrix = worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix; Collider val2 = val; BoxCollider val3 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null); if (val3 == null) { MeshCollider val4 = (MeshCollider)(object)((val2 is MeshCollider) ? val2 : null); if (val4 == null) { SphereCollider val5 = (SphereCollider)(object)((val2 is SphereCollider) ? val2 : null); if (val5 == null) { CapsuleCollider val6 = (CapsuleCollider)(object)((val2 is CapsuleCollider) ? val2 : null); if (val6 != null) { Vector3 val7 = Vector3.one * val6.radius * 2f; ((Vector3)(ref val7))[val6.direction] = Mathf.Max(val6.height, val6.radius * 2f); EncapsulateBox(ref bounds, ref any, new Bounds(val6.center, val7), matrix); } } else { EncapsulateBox(ref bounds, ref any, new Bounds(val5.center, Vector3.one * val5.radius * 2f), matrix); } } else if ((Object)(object)val4.sharedMesh != (Object)null) { EncapsulateBox(ref bounds, ref any, val4.sharedMesh.bounds, matrix); } } else { EncapsulateBox(ref bounds, ref any, new Bounds(val3.center, val3.size), matrix); } } return bounds; } private static bool IsSwitchedOn(Transform t, Transform root) { Transform val = t; while ((Object)(object)val != (Object)null) { if (!((Component)val).gameObject.activeSelf) { return false; } if ((Object)(object)val == (Object)(object)root) { return true; } val = val.parent; } return true; } private static void Encapsulate(ref Bounds bounds, ref bool any, Mesh mesh, Matrix4x4 matrix) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mesh != (Object)null) { EncapsulateBox(ref bounds, ref any, mesh.bounds, matrix); } } private static void EncapsulateBox(ref Bounds bounds, ref bool any, Bounds b, Matrix4x4 matrix) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 8; i++) { Vector3 val = ((Matrix4x4)(ref matrix)).MultiplyPoint3x4(new Vector3(((i & 1) == 0) ? ((Bounds)(ref b)).min.x : ((Bounds)(ref b)).max.x, ((i & 2) == 0) ? ((Bounds)(ref b)).min.y : ((Bounds)(ref b)).max.y, ((i & 4) == 0) ? ((Bounds)(ref b)).min.z : ((Bounds)(ref b)).max.z)); if (!any) { bounds = new Bounds(val, Vector3.zero); any = true; } else { ((Bounds)(ref bounds)).Encapsulate(val); } } } public static string Describe(GameObject go) { return string.Join(", ", from c in go.GetComponentsInChildren<Component>(true) where (Object)(object)c != (Object)null && !(c is Transform) group c by ((object)c).GetType().Name into g orderby g.Key select (g.Count() <= 1) ? g.Key : $"{g.Key} x{g.Count()}"); } public static List<RequirementConfig> CostOf(string pieceName) { GameObject prefab = PrefabManager.Instance.GetPrefab(pieceName); return ((prefab != null) ? prefab.GetComponent<Piece>() : null)?.m_resources?.Where((Requirement r) => (Object)(object)r?.m_resItem != (Object)null && r.m_amount > 0).Select((Func<Requirement, RequirementConfig>)((Requirement r) => new RequirementConfig(((Object)r.m_resItem).name, r.m_amount, 0, true))).ToList() ?? new List<RequirementConfig>(); } public static string BaseName(string name) { int num = name.IndexOf(" (", StringComparison.Ordinal); if (num > 0) { name = name.Substring(0, num); } return name.Replace("(Clone)", "").Trim(); } public static string Fmt(Bounds b) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) return $"center ({((Bounds)(ref b)).center.x:0.00}, {((Bounds)(ref b)).center.y:0.00}, {((Bounds)(ref b)).center.z:0.00}) size ({((Bounds)(ref b)).size.x:0.00}, {((Bounds)(ref b)).size.y:0.00}, {((Bounds)(ref b)).size.z:0.00})"; } } [BepInPlugin("fedorovdgap.vanillanpc", "VanillaNPC", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("fedorovdgap.fjordfolk")] [BepInProcess("valheim.exe")] public class FjordFolkPlugin : BaseUnityPlugin { public const string PluginId = "fedorovdgap.vanillanpc"; public const string PluginName = "VanillaNPC"; public const string PluginVersion = "1.1.0"; public const string FormerPluginId = "fedorovdgap.fjordfolk"; public const string ConfigFolder = "VanillaNPC"; internal static ManualLogSource Log; private static readonly HashSet<string> s_failedOnce = new HashSet<string>(); private void Awake() { Log = ((BaseUnityPlugin)this).Logger; FisherConfig.Bind(((BaseUnityPlugin)this).Config); BeggarConfig.Bind(((BaseUnityPlugin)this).Config); GuardConfig.Bind(((BaseUnityPlugin)this).Config); Guard("Loc.Register", Loc.Register); Guard("Harmony", delegate { //IL_0005: Unknown result type (might be due to invalid IL or missing references) new Harmony("fedorovdgap.vanillanpc").PatchAll(typeof(FjordFolkPlugin).Assembly); }); ((Component)this).gameObject.AddComponent<BeggarSpawner>(); ((Component)this).gameObject.AddComponent<GuardFollowService>(); ((Component)this).gameObject.AddComponent<BanditReminders>(); ((Component)this).gameObject.AddComponent<NpcIcons>(); PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; } private void OnVanillaPrefabsAvailable() { PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; Guard("RegisterAll", NpcPieces.RegisterAll); } internal static void Guard(string where, Action action) { try { action(); } catch (Exception arg) { if (s_failedOnce.Add(where)) { Log.LogError((object)$"{where} failed (repeats are not logged): {arg}"); } } } } internal static class VanillaUi { public sealed class Window { public RectTransform Root; public float Width; public TMP_Text Title; public Image Icon; public TMP_Text LevelText; public UITooltip LevelTooltip; public readonly List<Button> Tabs = new List<Button>(); public Rect ContentArea; public GameObject List; public RectTransform ListRoot; public float ListSpacing; public GameObject Details; public Image DetailsIcon; public TMP_Text DetailsName; public TMP_Text DetailsText; public TMP_Text DetailsFooter; public readonly List<Tile> Requirements = new List<Tile>(); public TMP_Text RequirementLevel; public UITooltip RequirementLevelTooltip; public Button ActionButton; } public sealed class ListEntry { public GameObject Root; public Image Icon; public TMP_Text Name; public TMP_Text Badge; public GameObject Selected; public Button Button; } public enum TextStyle { Header, Body, Big } public sealed class Slot { public RectTransform Rect; public Image Icon; public TMP_Text Amount; public GameObject Selected; public Button Button; public UITooltip Tooltip; public void Show(Sprite icon, int amount, bool dim) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Icon != (Object)null) { Icon.sprite = icon; ((Behaviour)Icon).enabled = (Object)(object)icon != (Object)null; ((Graphic)Icon).color = (Color)(dim ? new Color(1f, 1f, 1f, 0.45f) : Color.white); } if ((Object)(object)Amount != (Object)null) { Amount.text = ((amount > 0) ? amount.ToString() : ""); ((Component)Amount).gameObject.SetActive(amount > 0); } } } public sealed class Tile { public GameObject Root; public Image Icon; public TMP_Text Name; public TMP_Text Amount; public UITooltip Tooltip; } private static readonly HashSet<string> Behaviours = new HashSet<string> { "SkillsDialog", "UIGroupHandler", "UIGamePad", "Localize", "UIInputHandler", "UIDragHandler", "InventoryElement", "ScrollRectEnsureVisible", "EventTrigger" }; private static readonly HashSet<string> Layouts = new HashSet<string> { "ContentSizeFitter", "LayoutElement", "VerticalLayoutGroup", "HorizontalLayoutGroup", "GridLayoutGroup" }; public static readonly Color Red = new Color(1f, 0.25f, 0.25f); private static GameObject s_holder; public static Vector2 ButtonSize => SizeOf((RectTransform)((Component)InventoryGui.instance.m_takeAllButton).transform, new Vector2(133f, 40f)); public static float SlotNaturalSize => SizeOf((RectTransform)InventoryGui.instance.m_playerGrid.m_elementPrefab.transform, new Vector2(64f, 64f)).x; public static float SlotSpacing => Mathf.Max(SlotNaturalSize, InventoryGui.instance.m_playerGrid.m_elementSpace); public static string MissingPart() { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { return "InventoryGui"; } if ((Object)(object)instance.m_crafting == (Object)null || (Object)(object)instance.m_craftingStationName == (Object)null) { return "crafting panel"; } if ((Object)(object)instance.m_tabCraft == (Object)null || (Object)(object)instance.m_tabUpgrade == (Object)null) { return "tabs"; } if ((Object)(object)instance.m_recipeListRoot == (Object)null || (Object)(object)instance.m_recipeElementPrefab == (Object)null) { return "recipe list"; } if ((Object)(object)instance.m_recipeName == (Object)null || (Object)(object)instance.m_recipeDecription == (Object)null || (Object)(object)instance.m_itemCraftType == (Object)null) { return "description"; } if (instance.m_recipeRequirementList == null || instance.m_recipeRequirementList.Length == 0) { return "requirements"; } if ((Object)(object)instance.m_craftButton == (Object)null || (Object)(object)instance.m_takeAllButton == (Object)null) { return "buttons"; } if ((Object)(object)instance.m_playerGrid == (Object)null || (Object)(object)instance.m_playerGrid.m_elementPrefab == (Object)null) { return "inventory slot"; } return null; } public static Transform GuiRoot() { Canvas val = (((Object)(object)InventoryGui.instance != (Object)null) ? ((Component)InventoryGui.instance).GetComponentInParent<Canvas>(true) : null); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val.rootCanvas).transform; } public static Window CreateWindow(Transform parent, string title, IList<string> tabs, Action<int> onTab) { //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_04da: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Expected O, but got Unknown //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_06c6: Unknown result type (might be due to invalid IL or missing references) //IL_06d0: Expected O, but got Unknown //IL_07e1: Unknown result type (might be due to invalid IL or missing references) //IL_07e8: Unknown result type (might be due to invalid IL or missing references) //IL_07fb: Unknown result type (might be due to invalid IL or missing references) //IL_0807: Unknown result type (might be due to invalid IL or missing references) //IL_080f: Unknown result type (might be due to invalid IL or missing references) //IL_081b: Unknown result type (might be due to invalid IL or missing references) //IL_08d5: Unknown result type (might be due to invalid IL or missing references) //IL_08e1: Unknown result type (might be due to invalid IL or missing references) //IL_08ed: Unknown result type (might be due to invalid IL or missing references) //IL_08f2: Unknown result type (might be due to invalid IL or missing references) //IL_0861: Unknown result type (might be due to invalid IL or missing references) //IL_086b: Expected O, but got Unknown //IL_0866: Unknown result type (might be due to invalid IL or missing references) //IL_086b: Unknown result type (might be due to invalid IL or missing references) //IL_087b: Unknown result type (might be due to invalid IL or missing references) //IL_0885: Expected O, but got Unknown //IL_0880: Unknown result type (might be due to invalid IL or missing references) //IL_0885: Unknown result type (might be due to invalid IL or missing references) //IL_08bd: Unknown result type (might be due to invalid IL or missing references) //IL_08c2: Unknown result type (might be due to invalid IL or missing references) //IL_0730: Unknown result type (might be due to invalid IL or missing references) //IL_073a: Expected O, but got Unknown //IL_0749: Unknown result type (might be due to invalid IL or missing references) //IL_0753: Expected O, but got Unknown InventoryGui instance = InventoryGui.instance; RectTransform source = instance.m_crafting; var anon = new { Title = PathOf((Component)(object)instance.m_craftingStationName), Icon = PathOf((Component)(object)instance.m_craftingStationIcon), Level = PathOf((Component)(object)instance.m_craftingStationLevelRoot), LevelText = PathOf((Component)(object)instance.m_craftingStationLevel), Tabs = new string[2] { PathOf((Component)(object)instance.m_tabCraft), PathOf((Component)(object)instance.m_tabUpgrade) }, List = TopOf((Component)(object)instance.m_recipeListRoot), ListRoot = PathOf((Component)(object)instance.m_recipeListRoot), Details = TopOf((Component)(object)instance.m_recipeName), DetailsIcon = PathOf((Component)(object)instance.m_recipeIcon), DetailsName = PathOf((Component)(object)instance.m_recipeName), DetailsText = PathOf((Component)(object)instance.m_recipeDecription), DetailsFooter = PathOf((Component)(object)instance.m_itemCraftType), Requirements = instance.m_recipeRequirementList.Select((GameObject r) => (!((Object)(object)r != (Object)null)) ? null : PathFrom((Transform)(object)source, r.transform)).ToArray(), RequirementLevel = PathOf((Component)(object)instance.m_minStationLevelText), RequirementLevelIcon = PathOf((Component)(object)instance.m_minStationLevelIcon), Action = PathOf((Component)(object)instance.m_craftButton), Hidden = new string[4] { PathOf((Component)(object)instance.m_variantButton), PathOf((Component)(object)instance.m_qualityPanel), PathOf((Component)(object)instance.m_craftProgressPanel), PathOf((Component)(object)instance.m_upgradeItemName)?.Split('/').Take(2).Aggregate((string a, string b) => a + "/" + b) }, Removed = new string[2] { TopOf((Component)(object)instance.m_repairButton), TopOf((Component)(object)instance.m_repairPanel) } }; Rect rect = source.rect; Vector2 size = ((Rect)(ref rect)).size; GameObject val = CloneInactive(((Component)source).gameObject); ((Object)val).name = "fjordfolk_window"; HashSet<string> hashSet = new HashSet<string>(from p in new string[5] { anon.Title, anon.Icon, anon.Level, anon.List, anon.Details }.Concat(anon.Tabs) where !string.IsNullOrEmpty(p) select p.Split('/')[0]); foreach (Transform item in ((IEnumerable)val.transform).Cast<Transform>().ToList()) { Image component = ((Component)item).GetComponent<Image>(); Sprite val2 = ((component != null) ? component.sprite : null); bool num = (Object)(object)val2 != (Object)null && ((Object)val2).name.Contains("repair"); bool flag = !((Component)item).gameObject.activeSelf && !hashSet.Contains(((Object)item).name); if (num || flag || anon.Removed.Contains(((Object)item).name)) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } } foreach (string item2 in new string[14] { anon.Title, anon.Icon, anon.Level, anon.LevelText, anon.List, anon.ListRoot, anon.Details, anon.DetailsIcon, anon.DetailsName, anon.DetailsText, anon.DetailsFooter, anon.RequirementLevel, anon.RequirementLevelIcon, anon.Action }.Concat(anon.Tabs).Concat(anon.Requirements)) { SwitchOn(val, item2); } foreach (string item3 in anon.Hidden.Where((string p) => !string.IsNullOrEmpty(p))) { Transform obj = val.transform.Find(item3); if (obj != null) { ((Component)obj).gameObject.SetActive(false); } } RectTransform val3 = Find<RectTransform>(val, anon.ListRoot); if ((Object)(object)val3 != (Object)null) { foreach (Transform item4 in ((IEnumerable)val3).Cast<Transform>().ToList()) { Object.DestroyImmediate((Object)(object)((Component)item4).gameObject); } } Strip(val); Window obj2 = new Window { Root = (RectTransform)val.transform, Width = size.x, Title = Find<TMP_Text>(val, anon.Title), Icon = Find<Image>(val, anon.Icon), LevelText = Find<TMP_Text>(val, anon.LevelText), LevelTooltip = Find<UITooltip>(val, anon.Level) }; Transform obj3 = val.transform.Find(anon.List ?? ""); obj2.List = ((obj3 != null) ? ((Component)obj3).gameObject : null); obj2.ListRoot = val3; obj2.ListSpacing = ((instance.m_recipeListSpace > 1f) ? instance.m_recipeListSpace : 32f); Transform obj4 = val.transform.Find(anon.Details ?? ""); obj2.Details = ((obj4 != null) ? ((Component)obj4).gameObject : null); obj2.DetailsIcon = Find<Image>(val, anon.DetailsIcon); obj2.DetailsName = Find<TMP_Text>(val, anon.DetailsName); obj2.DetailsText = Find<TMP_Text>(val, anon.DetailsText); obj2.DetailsFooter = Find<TMP_Text>(val, anon.DetailsFooter); obj2.RequirementLevel = Find<TMP_Text>(val, anon.RequirementLevel); obj2.RequirementLevelTooltip = Find<UITooltip>(val, anon.RequirementLevelIcon); obj2.ActionButton = Find<Button>(val, anon.Action); Window window = obj2; string[] requirements = anon.Requirements; foreach (string path in requirements) { RectTransform val4 = Find<RectTransform>(val, path); if ((Object)(object)val4 != (Object)null) { window.Requirements.Add(TileOf(((Component)val4).gameObject)); } } if ((Object)(object)window.Title != (Object)null) { window.Title.text = title; } if ((Object)(object)window.ActionButton != (Object)null) { window.ActionButton.onClick = new ButtonClickedEvent(); } for (int num3 = 0; num3 < anon.Tabs.Length; num3++) { Button val5 = Find<Button>(val, anon.Tabs[num3]); if ((Object)(object)val5 == (Object)null) { continue; } if (tabs == null || num3 >= tabs.Count) { ((Component)val5).gameObject.SetActive(false); continue; } int index = num3; val5.onClick = new ButtonClickedEvent(); ((UnityEvent)val5.onClick).AddListener((UnityAction)delegate { FjordFolkPlugin.Guard("VanillaUi.Tab", delegate { onTab(index); }); }); Transform obj5 = ((Component)val5).transform.Find("Text"); TMP_Text val6 = ((obj5 != null) ? ((Component)obj5).GetComponent<TMP_Text>() : null) ?? ((Component)val5).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)val6 != (Object)null) { val6.text = tabs[num3]; } window.Tabs.Add(val5); } RectTransform root = window.Root; ((Transform)root).SetParent(parent, false); Vector2 val7 = default(Vector2); ((Vector2)(ref val7))..ctor(0.5f, 0.5f); root.anchorMax = val7; root.anchorMin = val7; root.pivot = new Vector2(0.5f, 0.5f); root.sizeDelta = size; root.anchoredPosition = Vector2.zero; ((Transform)root).localScale = Vector3.one; val.SetActive(true); Canvas.ForceUpdateCanvases(); if ((Object)(object)window.List != (Object)null && (Object)(object)window.Details != (Object)null) { Rect val8 = FromTopLeft(root, (RectTransform)window.List.transform); Rect val9 = FromTopLeft(root, (RectTransform)window.Details.transform); window.ContentArea = Rect.MinMaxRect(((Rect)(ref val8)).xMin, Mathf.Min(((Rect)(ref val8)).yMin, ((Rect)(ref val9)).yMin), ((Rect)(ref val9)).xMax, Mathf.Max(((Rect)(ref val8)).yMax, ((Rect)(ref val9)).yMax)); } else { window.ContentArea = new Rect(10f, 101f, size.x - 20f, size.y - 105f); } return window; string PathOf(Component c) { if (!((Object)(object)c != (Object)null)) { return null; } return PathFrom((Transform)(object)source, c.transform); } string TopOf(Component c) { string text = PathOf(c); if (text == null) { return null; } return text.Split('/')[0]; } } public static ListEntry AddListEntry(Window window, int index, Action onClick) { //IL_0142: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown GameObject val = CloneInactive(InventoryGui.instance.m_recipeElementPrefab); ((Object)val).name = "fjordfolk_listentry"; ListEntry obj = new ListEntry { Root = val }; Transform obj2 = val.transform.Find("icon"); obj.Icon = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null); Transform obj3 = val.transform.Find("name"); obj.Name = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null); Transform obj4 = val.transform.Find("QualityLevel"); obj.Badge = ((obj4 != null) ? ((Component)obj4).GetComponent<TMP_Text>() : null); Transform obj5 = val.transform.Find("selected"); obj.Selected = ((obj5 != null) ? ((Component)obj5).gameObject : null); obj.Button = val.GetComponent<Button>(); ListEntry listEntry = obj; Transform obj6 = val.transform.Find("Durability"); if (obj6 != null) { ((Component)obj6).gameObject.SetActive(false); } GameObject selected = listEntry.Selected; if (selected != null) { selected.SetActive(false); } Strip(val); if ((Object)(object)listEntry.Button != (Object)null) { listEntry.Button.onClick = new ButtonClickedEvent(); ((UnityEvent)listEntry.Button.onClick).AddListener((UnityAction)delegate { FjordFolkPlugin.Guard("VanillaUi.ListEntry", onClick.Invoke); }); } RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)window.ListRoot, false); val2.anchoredPosition = new Vector2(0f, (float)(-index) * window.ListSpacing); val.SetActive(true); float num = (float)(index + 1) * window.ListSpacing; Rect rect = window.ListRoot.rect; if (((Rect)(ref rect)).height < num) { window.ListRoot.SetSizeWithCurrentAnchors((Axis)1, num); } return listEntry; } public static Image Panel(Transform parent, float x, float y, float width, float height) { //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_00b4: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown Image component = ((Component)InventoryGui.instance.m_recipeName.transform.parent).GetComponent<Image>(); GameObject val = new GameObject("fjordfolk_panel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); Image component2 = val.GetComponent<Image>(); if ((Object)(object)component != (Object)null) { component2.sprite = component.sprite; component2.type = component.type; ((Graphic)component2).color = ((Graphic)component).color; ((Graphic)component2).material = ((Graphic)component).material; component2.pixelsPerUnitMultiplier = component.pixelsPerUnitMultiplier; } else { ((Graphic)component2).color = new Color(0f, 0f, 0f, 0.56f); } ((Graphic)component2).raycastTarget = false; Place((RectTransform)val.transform, parent, x, y, new Vector2(width, height)); return component2; } public static TMP_Text Text(Transform parent, TextStyle style, string text, float x, float y, float width, float height, TextAlignmentOptions alignment = (TextAlignmentOptions)513, float size = 0f) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected O, but got Unknown InventoryGui instance = InventoryGui.instance; GameObject val = CloneInactive(((Component)(style switch { TextStyle.Big => instance.m_recipeName, TextStyle.Header => instance.m_itemCraftType, _ => instance.m_recipeDecription, })).gameObject); ((Object)val).name = "fjordfolk_text"; foreach (Transform item in ((IEnumerable)val.transform).Cast<Transform>().ToList()) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } Strip(val); StripLayouts(val, includeChildren: true); TMP_Text component = val.GetComponent<TMP_Text>(); component.text = text; component.alignment = alignment; component.textWrappingMode = (TextWrappingModes)1; component.overflowMode = (TextOverflowModes)0; component.enableAutoSizing = false; component.richText = true; ((Graphic)component).raycastTarget = false; component.fontSize = ((size > 0f) ? size : (style switch { TextStyle.Big => 30f, TextStyle.Header => 20f, _ => 17f, })); Place((RectTransform)val.transform, parent, x, y, new Vector2(width, height)); val.SetActive(true); return component; } public static Button Button(Transform parent, string label, float x, float y, float width, float height, Action onClick) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown GameObject val = CloneInactive(((Component)InventoryGui.instance.m_takeAllButton).gameObject); ((Object)val).name = "fjordfolk_button"; Strip(val); StripLayouts(val, includeChildren: true); Button component = val.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { FjordFolkPlugin.Guard("VanillaUi.Button " + label, onClick.Invoke); }); ((Selectable)component).interactable = true; Transform obj = val.transform.Find("Text"); TMP_Text val2 = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null) ?? val.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)val2 != (Object)null) { val2.text = label; val2.textWrappingMode = (TextWrappingModes)0; } Place((RectTransform)val.transform, parent, x, y, new Vector2(width, height)); val.SetActive(true); return component; } public static void SetButtonLabel(Button button, string label) { object obj; if (!((Object)(object)button != (Object)null)) { obj = null; } else { Transform obj2 = ((Component)button).transform.Find("Text"); obj = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null) ?? ((Component)button).GetComponentInChildren<TMP_Text>(true); } TMP_Text val = (TMP_Text)obj; if ((Object)(object)val != (Object)null) { val.text = label; } } public static UITooltip TooltipOf(Component c) { if (!((Object)(object)c != (Object)null)) { return null; } return c.GetComponentInChildren<UITooltip>(true); } public static void SetTooltip(UITooltip tooltip, string topic, string text) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tooltip != (Object)null) { tooltip.Set(topic, text, (RectTransform)null, Vector2.zero); } } public static Slot InventorySlot(Transform parent, float x, float y, float size, Action onClick) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_01dc: 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_01f5: 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_01a4: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown GameObject val = CloneInactive(InventoryGui.instance.m_playerGrid.m_elementPrefab); ((Object)val).name = "fjordfolk_slot"; InventoryElement component = val.GetComponent<InventoryElement>(); Slot slot = new Slot { Rect = (RectTransform)val.transform, Icon = (((Object)(object)component != (Object)null) ? component.m_icon : null), Amount = (((Object)(object)component != (Object)null) ? component.m_amount : null), Selected = (((Object)(object)component != (Object)null) ? component.m_selected : null), Button = (((Object)(object)component != (Object)null && (Object)(object)component.m_button != (Object)null) ? component.m_button : val.GetComponent<Button>()), Tooltip = val.GetComponentInChildren<UITooltip>(true) }; if ((Object)(object)component != (Object)null) { Component[] array = (Component[])(object)new Component[7] { (Component)component.m_quality, (Component)component.m_equiped, (Component)component.m_queued, (Component)component.m_noteleport, (Component)component.m_food, (Component)component.m_durability, (Component)component.m_dropFocus }; foreach (Component val2 in array) { if ((Object)(object)val2 != (Object)null) { val2.gameObject.SetActive(false); } } } Transform obj = val.transform.Find("binding"); if (obj != null) { ((Component)obj).gameObject.SetActive(false); } GameObject selected = slot.Selected; if (selected != null) { selected.SetActive(false); } Strip(val); if ((Object)(object)slot.Button != (Object)null) { slot.Button.onClick = new ButtonClickedEvent(); if (onClick != null) { ((UnityEvent)slot.Button.onClick).AddListener((UnityAction)delegate { FjordFolkPlugin.Guard("VanillaUi.Slot", onClick.Invoke); }); } } float slotNaturalSize = SlotNaturalSize; Place(slot.Rect, parent, x, y, new Vector2(slotNaturalSize, slotNaturalSize)); ((Transform)slot.Rect).localScale = Vector3.one * (size / slotNaturalSize); val.SetActive(true); return slot; } private static Tile TileOf(GameObject go) { Tile obj = new Tile { Root = go }; Transform obj2 = go.transform.Find("res_icon"); obj.Icon = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null); Transform obj3 = go.transform.Find("res_name"); obj.Name = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null); Transform obj4 = go.transform.Find("res_amount"); obj.Amount = ((obj4 != null) ? ((Component)obj4).GetComponent<TMP_Text>() : null); obj.Tooltip = go.GetComponent<UITooltip>(); return obj; } public static void ShowRequirement(Tile tile, Sprite icon, string name, int have, int need, string tooltip) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) Component[] array = (Component[])(object)new Component[3] { (Component)tile.Icon, (Component)tile.Name, (Component)tile.Amount }; foreach (Component obj in array) { if (obj != null) { obj.gameObject.SetActive(true); } } if ((Object)(object)tile.Icon != (Object)null) { tile.Icon.sprite = icon; ((Graphic)tile.Icon).color = Color.white; } if ((Object)(object)tile.Name != (Object)null) { tile.Name.text = name; } if ((Object)(object)tile.Amount != (Object)null) { tile.Amount.text = $"{have}/{need}"; ((Graphic)tile.Amount).color = ((have >= need) ? Color.white : Red); } SetTooltip(tile.Tooltip, name, tooltip); } public static void HideRequirement(Tile tile) { Component[] array = (Component[])(object)new Component[3] { (Component)tile.Icon, (Component)tile.Name, (Component)tile.Amount }; foreach (Component obj in array) { if (obj != null) { obj.gameObject.SetActive(false); } } SetTooltip(tile.Tooltip, "", ""); } private static GameObject CloneInactive(GameObject source) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)s_holder == (Object)null) { s_holder = new GameObject("fjordfolk_ui_holder"); s_holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)s_holder); } GameObject obj = Object.Instantiate<GameObject>(source, s_holder.transform, false); obj.SetActive(true); return obj; } private static void Strip(GameObject go) { UIGamePad[] componentsInChildren = go.GetComponentsInChildren<UIGamePad>(true); foreach (UIGamePad val in componentsInChildren) { if ((Object)(object)val.m_hint != (Object)null) { Object.DestroyImmediate((Object)(object)val.m_hint); } } foreach (GameObject item in (from b in go.GetComponentsInChildren<MonoBehaviour>(true) where (Object)(object)b != (Object)null && ((object)b).GetType().Name == "UIInputHint" select ((Component)b).gameObject).Distinct().ToList()) { if ((Object)(object)item != (Object)null) { Object.DestroyImmediate((Object)(object)item); } } MonoBehaviour[] componentsInChildren2 = go.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null && Behaviours.Contains(((object)val2).GetType().Name)) { Object.DestroyImmediate((Object)(object)val2); } } } private static void StripLayouts(GameObject go, bool includeChildren) { Component[] array = (includeChildren ? go.GetComponentsInChildren<Component>(true) : go.GetComponents<Component>()); foreach (Component val in array) { if ((Object)(object)val != (Object)null && Layouts.Contains(((object)val).GetType().Name)) { Object.DestroyImmediate((Object)(object)val); } } } public static void Place(RectTransform rect, Transform parent, float x, float y, Vector2 size) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) ((Transform)rect).SetParent(parent, false); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rect.anchorMax = val; rect.anchorMin = val; rect.pivot = new Vector2(0f, 1f); rect.sizeDelta = size; rect.anchoredPosition = new Vector2(x, 0f - y); ((Transform)rect).localScale = Vector3.one; } public static RectTransform Group(Transform parent, string name, float x, float y, float width, float height) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0036: Expected O, but got Unknown RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }).transform; Place(val, parent, x, y, new Vector2(width, height)); return val; } private static Rect FromTopLeft(RectTransform root, RectTransform child) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[4]; child.GetWorldCorners(array); Rect rect = root.rect; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(float.MaxValue, float.MaxValue); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(float.MinValue, float.MinValue); Vector3[] array2 = array; Vector2 val5 = default(Vector2); foreach (Vector3 val3 in array2) { Vector3 val4 = ((Transform)root).InverseTransformPoint(val3); ((Vector2)(ref val5))..ctor(val4.x - ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMax - val4.y); val = Vector2.Min(val, val5); val2 = Vector2.Max(val2, val5); } return Rect.MinMaxRect(val.x, val.y, val2.x, val2.y); } private static void SwitchOn(GameObject root, string path) { if (string.IsNullOrEmpty(path)) { return; } Transform val = root.transform.Find(path); Transform val2 = val; while ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)root.transform) { ((Component)val2).gameObject.SetActive(true); val2 = val2.parent; } if (!((Object)(object)val == (Object)null)) { Graphic[] components = ((Component)val).GetComponents<Graphic>(); for (int i = 0; i < components.Length; i++) { ((Behaviour)components[i]).enabled = true; } } } private static T Find<T>(GameObject root, string path) where T : Component { if (string.IsNullOrEmpty(path)) { return default(T); } Transform val = root.transform.Find(path); if (!((Object)(object)val != (Object)null)) { return default(T); } return ((Component)val).GetComponent<T>(); } private static Vector2 SizeOf(RectTransform rect, Vector2 fallback) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_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_001a: 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_0035: 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_0027: 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_0047: 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_0050: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rect == (Object)null) { return fallback; } Rect rect2 = rect.rect; Vector2 val = ((Rect)(ref rect2)).size; if (val.x <= 1f || val.y <= 1f) { val = ((rect.anchorMin == rect.anchorMax) ? rect.sizeDelta : fallback); } return new Vector2((val.x > 1f) ? val.x : fallback.x, (val.y > 1f) ? val.y : fallback.y); } private static string PathFrom(Transform root, Transform target) { if ((Object)(object)target == (Object)null) { return null; } List<string> list = new List<string>(); Transform val = target; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace FjordFolk.Tavern { public class Drunkard : MonoBehaviour { public const string DialogueId = "drunkard"; public const int Coins = 400; private static readonly (string Boss, string Mead)[] Progress = new(string, string)[8] { ("", "MeadHealthMinor"), ("defeated_eikthyr", "MeadHealthMinor"), ("defeated_gdking", "MeadHealthMedium"), ("defeated_bonemass", "MeadHealthMedium"), ("defeated_dragon", "MeadHealthMajor"), ("defeated_goblinking", "MeadHealthMajor"), ("defeated_queen", "MeadHealthLingering"), ("defeated_fader", "MeadHealthLingering") }; private NpcActor m_actor; private void Awake() { m_actor = ((Component)this).GetComponent<NpcActor>(); } internal static string WantedMead() { ZoneSystem instance = ZoneSystem.instance; string result = Progress[0].Mead; (string, string)[] progress = Progress; for (int i = 0; i < progress.Length; i++) { var (text, text2) = progress[i]; if (string.IsNullOrEmpty(text) || ((Object)(object)instance != (Object)null && instance.GetGlobalKey(text))) { result = text2; } } return result; } private static string MeadName(string prefab) { object obj; if (!((Object)(object)ObjectDB.instance != (Object)null)) { obj = null; } else { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); obj = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); } ItemDrop val = (ItemDrop)obj; if (!((Object)(object)val != (Object)null)) { return prefab; } return val.m_itemData.m_shared.m_name; } internal string HoverText(string name) { string text = name + "\n<color=#c8c8c8>" + Loc.T("drunkard_role") + "</color>\n[<color=yellow><b>$KEY_Use</b></color>] " + Loc.T("drunkard_offer", MeadName(WantedMead()), 400); return Localization.instance.Localize(text); } internal void Interact(Humanoid user) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0199: 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_0137: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)((user is Player) ? user : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return; } bool anyInWorld; TraderLocations.Kind kind; Vector3? val2 = TraderLocations.NearestUnfound(((Component)val).transform.position, out kind, out anyInWorld); if (!val2.HasValue && !TraderLocations.ClientOnly) { Say(anyInWorld ? "all_known" : "no_traders"); return; } Inventory inventory = ((Humanoid)val).GetInventory(); string text = WantedMead(); string text2 = MeadName(text); if (inventory.CountItems(text2, -1, true) < 1 || inventory.CountItems(MeadName("Coins"), -1, true) < 400) { Say("want"); ((Character)val).Message((MessageType)2, Localization.instance.Localize(Loc.T("msg_drunkard_want", text2, 400)), 0, (Sprite)null, false); return; } inventory.RemoveItem(text2, 1, -1, true); inventory.RemoveItem(MeadName("Coins"), 400, -1, true); m_actor?.PlayGestureLocal("toast"); if (!val2.HasValue) { kind = TraderLocations.FirstKindForClient(); if (kind != null) { Game.instance.DiscoverClosestLocation(kind.LocationName, ((Component)val).transform.position, Loc.T(kind.NameKey), 3, true, false); Say("tell_" + kind.Key); } FjordFolkPlugin.Log.LogDebug((object)$"drunkard paid ({text} + {400}), asked the server for {kind?.LocationName}"); } else { Minimap.instance.DiscoverLocation(val2.Value, (PinType)3, Loc.T(kind.NameKey), true); Say("tell_" + kind.Key); FjordFolkPlugin.Log.LogDebug((object)$"drunkard paid ({text} + {400}), marked {kind.Key} at {val2.Value}"); } } private void Say(string section) { string text = NpcDialogue.For("drunkard").Pick(section); if (text != null) { m_actor?.Say(text); } } } internal static class TraderLocations { internal sealed class Kind { public string Key; public string NameKey; public Regex Pattern; public string LocationName; public List<string> Names = new List<string>(); } private static readonly Kind[] Kinds = new Kind[4] { new Kind { Key = "haldor", NameKey = "trader_haldor", Pattern = new Regex("^Vendor_BlackForest$", RegexOptions.IgnoreCase) }, new Kind { Key = "hildir", NameKey = "trader_hildir", Pattern = new Regex("^Hildir_camp$", RegexOptions.IgnoreCase) }, new Kind { Key = "bogwitch", NameKey = "trader_bogwitch", Pattern = new Regex("^BogWitch_Camp$", RegexOptions.IgnoreCase) }, new Kind { Key = "forge", NameKey = "trader_forge", Pattern = new Regex("^(?!dev).*potential", RegexOptions.IgnoreCase) } }; private static ZoneSystem s_resolvedFor; public static bool ClientOnly { get { if (!((Object)(object)ZoneSystem.instance == (Object)null)) { return ZoneSystem.instance.m_locationInstances.Count == 0; } return true; } } private static void Resolve() { if ((Object)(object)s_resolvedFor == (Object)(object)ZoneSystem.instance || (Object)(object)ZoneSystem.instance == (Object)null) { return; } s_resolvedFor = ZoneSystem.instance; List<string> source = (from l in ZoneSystem.instance.m_locations where l != null && !string.IsNullOrEmpty(l.m_prefabName) select l.m_prefabName).Distinct().ToList(); Kind[] kinds = Kinds; foreach (Kind kind in kinds) { kind.Names = source.Where((string n) => kind.Pattern.IsMatch(n)).ToList(); kind.LocationName = kind.Names.FirstOrDefault(); } FjordFolkPlugin.Log.LogDebug((object)("trader locations: " + string.Join("; ", Kinds.Select((Kind k) => k.Key + " = " + ((k.Names.Count > 0) ? string.Join(", ", k.Names) : "none"))))); FjordFolkPlugin.Log.LogDebug((object)("locations that might be traders: " + string.Join(", ", source.Where((string n) => Regex.IsMatch(n, "vendor|trader|hildir|witch|forge|potential|idol|merchant", RegexOptions.IgnoreCase))))); } public static Vector3? NearestUnfound(Vector3 from, out Kind kind, out bool anyInWorld) { //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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00c4: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) Resolve(); kind = null; anyInWorld = false; if ((Object)(object)ZoneSystem.instance == (Object)null || (Object)(object)Minimap.instance == (Object)null) { return null; } Vector3? result = null; float num = float.MaxValue; foreach (LocationInstance value in ZoneSystem.instance.m_locationInstances.Values) { string name = value.m_location?.m_prefabName; Kind kind2 = ((name != null) ? Kinds.FirstOrDefault((Kind k) => k.Names.Contains(name)) : null); if (kind2 == null) { continue; } anyInWorld = true; Vector3 position = value.m_position; if (!Minimap.instance.IsExplored(position) && !HasPinNear(position)) { float num2 = Vector3.Distance(from, position); if (num2 < num) { num = num2; result = position; kind = kind2; } } } return result; } public static Kind FirstKindForClient() { Resolve(); return Kinds.FirstOrDefault((Kind k) => k.LocationName != null && !Minimap.instance.m_pins.Any((PinData p) => p.m_name == Loc.T(k.NameKey))); } private static bool HasPinNear(Vector3 position) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Minimap.instance.m_pins.Any(delegate(PinData p) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (p != null && (int)p.m_type != 4) { Vector3 val = p.m_pos - position; return ((Vector3)(ref val)).sqrMagnitude < 3600f; } return false; }); } } public class Innkeeper : MonoBehaviour { public const string DialogueId = "innkeeper"; private const float StandRange = 5f; private const float SitRange = 8f; private const float SitDelay = 2f; private ZNetView m_nview; private NpcActor m_actor; private NpcSeat m_seat; private Trader m_trader; private float m_nextCheck; private float m_sitAt = -1f; internal Trader Trader => m_trader; private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); m_actor = ((Component)this).GetComponent<NpcActor>(); m_seat = ((Component)this).GetComponent<NpcSeat>(); m_trader = ((Component)this).GetComponent<Trader>(); } private void Update() { if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid() || (Object)(object)m_seat == (Object)null || Time.time < m_nextCheck) { return; } m_nextCheck = Time.time + 0.25f; FjordFolkPlugin.Guard("Innkeeper.Update", delegate { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; float num = (((Object)(object)localPlayer != (Object)null) ? Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) : float.MaxValue); bool flag = (Object)(object)StoreGui.instance != (Object)null