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 ValheimMannequins v0.3.0
plugins/ValheimMannequins/ValheimMannequins.dll
Decompiled a week agousing 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 BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("ValheimMannequins")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.0.0")] [assembly: AssemblyInformationalVersion("0.3.0")] [assembly: AssemblyProduct("ValheimMannequins")] [assembly: AssemblyTitle("ValheimMannequins")] [assembly: AssemblyVersion("0.3.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ValheimMannequins { internal static class EyeTextures { private const int X0 = 112; private const int X1 = 128; private const int Y0 = 16; private const int Y1 = 28; private static readonly Dictionary<int, Texture2D> Cache = new Dictionary<int, Texture2D>(); public static Texture Get(int eye, int model, Texture source) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) int key = model * 100 + eye; if (Cache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return (Texture)(object)value; } Texture2D val = Build(source, Mannequin.EyeTones[eye].Color); if ((Object)(object)val == (Object)null) { return source; } Cache[key] = val; return (Texture)(object)val; } private static Texture2D Build(Texture source, Color target) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0192: 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_019e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } int width = source.width; int height = source.height; RenderTexture temporary = RenderTexture.GetTemporary(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)0); RenderTexture active = RenderTexture.active; Color32[] pixels; try { Graphics.Blit(source, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(width, height, (TextureFormat)4, false); val.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0); pixels = val.GetPixels32(); Object.Destroy((Object)val); } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } float num = (float)width / 256f; float num2 = (float)height / 256f; int num3 = Mathf.FloorToInt(112f * num); int num4 = Mathf.CeilToInt(128f * num); int num5 = Mathf.FloorToInt(16f * num2); int num6 = Mathf.CeilToInt(28f * num2); Color32 val2 = Color32.op_Implicit(target); for (int i = num5; i < num6; i++) { int num7 = height - 1 - i; for (int j = num3; j < num4; j++) { Color32 val3 = pixels[num7 * width + j]; if (val3.b > val3.r + 10) { float num8 = Mathf.Clamp01((float)(val3.b - val3.r) / 142f); float num9 = (float)(int)val3.b / 255f; pixels[num7 * width + j] = new Color32((byte)Mathf.Lerp((float)(int)val3.r, (float)(int)val2.r * num9, num8), (byte)Mathf.Lerp((float)(int)val3.g, (float)(int)val2.g * num9, num8), (byte)Mathf.Lerp((float)(int)val3.b, (float)(int)val2.b * num9, num8), val3.a); } } } Texture2D val4 = new Texture2D(width, height, (TextureFormat)4, true); val4.SetPixels32(pixels); ((Texture)val4).wrapMode = source.wrapMode; ((Texture)val4).filterMode = source.filterMode; ((Texture)val4).anisoLevel = source.anisoLevel; val4.Apply(true, true); ((Object)val4).name = "PM_Eyes"; return val4; } } public class Mannequin : MonoBehaviour, Hoverable, Interactable, TextReceiver { public sealed class SlotDef { public string Label; public ItemType[] Types; public int VisualKey; public int VariantKey; public int QualityKey; } public struct Tone { public string Name; public Color Color; public Tone(string n, Color c) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Name = n; Color = c; } } public const int MaxNameLength = 40; private static readonly int[] NameKeys; private const string RpcSetName = "PM_SetName"; private const string RpcLabel = "PM_Label"; private string _shown = ""; private Nameplate _plate; public const int PoseCount = 15; public const int MaxSets = 8; private const int SwapSlots = 7; private const ItemType OneH = (ItemType)3; private const ItemType TwoH = (ItemType)14; private const ItemType Bow = (ItemType)4; private const ItemType Tool = (ItemType)19; private const ItemType Torch = (ItemType)15; private const ItemType Shield = (ItemType)5; public static readonly SlotDef[] Slots; private const int SlotStride = 16; private static readonly int PoseKey; private static readonly int ActiveSetKey; private static readonly int[,] ItemKeys; private static readonly int[,] BlobKeys; private const string RpcSetPose = "PM_SetPose"; private static readonly FieldInfo RightItemField; private static readonly FieldInfo LeftItemField; private static readonly FieldInfo HiddenRightItemField; private static readonly FieldInfo HiddenLeftItemField; private ZNetView _nview; private Animator _anim; private VisEquipment _vis; private int _appliedModel = -1; private int _appliedEye = -1; private int _pose = -1; private int _renameSet; public static readonly Tone[] SkinTones; public static readonly Tone[] HairTones; private static readonly int SkinIdxKey; private static readonly int HairIdxKey; public static readonly Tone[] EyeTones; private static readonly int EyeKey; internal static readonly Dictionary<VisEquipment, Mannequin> ByVis; private static List<string> _hairs; private static List<string> _beards; private const int BackFirst = 7; private const int BackCount = 2; private static readonly int[,] CarryKeys; public int Pose => _pose; public ZDO Zdo { get { if (!((Object)(object)_nview != (Object)null)) { return null; } return _nview.GetZDO(); } } public string Label => GetSetName(ActiveSet); public int EyeIndex { get { if (Zdo != null) { return Mathf.Clamp(Zdo.GetInt(EyeKey, 0), 0, EyeTones.Length - 1); } return 0; } } private static List<string> Hairs { get { if (_hairs == null || _hairs.Count <= 0) { return _hairs = StyleNames("Hair"); } return _hairs; } } private static List<string> Beards { get { if (_beards == null || _beards.Count <= 0) { return _beards = StyleNames("Beard"); } return _beards; } } public string HairName { get { if (StyleIndex(ZDOVars.s_hairItem, Hairs) != 0) { return Pretty(Hairs[StyleIndex(ZDOVars.s_hairItem, Hairs) - 1], "Hair"); } return "None"; } } public string BeardName { get { if (StyleIndex(ZDOVars.s_beardItem, Beards) != 0) { return Pretty(Beards[StyleIndex(ZDOVars.s_beardItem, Beards) - 1], "Beard"); } return "None"; } } public int SkinIndex { get { if (Zdo != null) { return Mathf.Clamp(Zdo.GetInt(SkinIdxKey, 0), 0, SkinTones.Length - 1); } return 0; } } public int HairToneIndex { get { if (Zdo != null) { return Mathf.Clamp(Zdo.GetInt(HairIdxKey, 0), 0, HairTones.Length - 1); } return 0; } } public bool IsFemale { get { if (Zdo != null) { return Zdo.GetInt(ZDOVars.s_modelIndex, 0) == 1; } return false; } } public int SetCount => Mathf.Clamp(Plugin.SetCount.Value, 1, 8); public int ActiveSet { get { ZDO zdo = Zdo; if (zdo != null) { return Mathf.Clamp(zdo.GetInt(ActiveSetKey, 0), 0, SetCount - 1); } return 0; } } private static ItemType[] T(params ItemType[] t) { return t; } private static SlotDef Def(string label, ItemType[] types, int visual, int variant = 0, int quality = 0) { return new SlotDef { Label = label, Types = types, VisualKey = visual, VariantKey = variant, QualityKey = quality }; } static Mannequin() { //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Unknown result type (might be due to invalid IL or missing references) //IL_0548: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) NameKeys = new int[8]; SlotDef[] obj = new SlotDef[9] { Def("Helmet", T((ItemType)6), ZDOVars.s_helmetItem), Def("Chest", T((ItemType)7), ZDOVars.s_chestItem), Def("Legs", T((ItemType)11), ZDOVars.s_legItem), Def("Cape", T((ItemType)17), ZDOVars.s_shoulderItem, ZDOVars.s_shoulderItemVariant, ZDOVars.s_shoulderItemQuality), Def("Utility", T((ItemType)18), ZDOVars.s_utilityItem), null, null, null, null }; ItemType[] array = new ItemType[5]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); obj[5] = Def("Right hand", T((ItemType[])(object)array), ZDOVars.s_rightItem, 0, ZDOVars.s_rightItemQuality); ItemType[] array2 = new ItemType[6]; RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); obj[6] = Def("Left hand", T((ItemType[])(object)array2), ZDOVars.s_leftItem, ZDOVars.s_leftItemVariant, ZDOVars.s_leftItemQuality); ItemType[] array3 = new ItemType[5]; RuntimeHelpers.InitializeArray(array3, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); obj[7] = Def("Back (weapon)", T((ItemType[])(object)array3), ZDOVars.s_leftBackItem, ZDOVars.s_leftBackItemVariant, ZDOVars.s_leftBackItemQuality); obj[8] = Def("Back (shield)", T((ItemType)5), ZDOVars.s_rightBackItem, 0, ZDOVars.s_rightBackItemQuality); Slots = obj; PoseKey = StringExtensionMethods.GetStableHashCode("PM_pose"); ActiveSetKey = StringExtensionMethods.GetStableHashCode("PM_set"); ItemKeys = new int[8, Slots.Length]; BlobKeys = new int[8, Slots.Length]; RightItemField = AccessTools.Field(typeof(Humanoid), "m_rightItem"); LeftItemField = AccessTools.Field(typeof(Humanoid), "m_leftItem"); HiddenRightItemField = AccessTools.Field(typeof(Humanoid), "m_hiddenRightItem"); HiddenLeftItemField = AccessTools.Field(typeof(Humanoid), "m_hiddenLeftItem"); SkinTones = new Tone[7] { new Tone("Default", Color.white), new Tone("Fair", new Color(1f, 0.93f, 0.86f)), new Tone("Light", new Color(0.9f, 0.78f, 0.68f)), new Tone("Medium", new Color(0.76f, 0.6f, 0.48f)), new Tone("Tan", new Color(0.62f, 0.46f, 0.34f)), new Tone("Dark", new Color(0.45f, 0.31f, 0.22f)), new Tone("Ashen", new Color(0.78f, 0.84f, 0.9f)) }; HairTones = new Tone[9] { new Tone("Default", Color.white), new Tone("Black", new Color(0.12f, 0.1f, 0.09f)), new Tone("Dark brown", new Color(0.3f, 0.18f, 0.1f)), new Tone("Brown", new Color(0.45f, 0.28f, 0.15f)), new Tone("Auburn", new Color(0.55f, 0.25f, 0.12f)), new Tone("Red", new Color(0.7f, 0.25f, 0.1f)), new Tone("Blonde", new Color(0.85f, 0.7f, 0.35f)), new Tone("Platinum", new Color(0.95f, 0.9f, 0.8f)), new Tone("Grey", new Color(0.6f, 0.6f, 0.6f)) }; SkinIdxKey = StringExtensionMethods.GetStableHashCode("PM_skinTone"); HairIdxKey = StringExtensionMethods.GetStableHashCode("PM_hairTone"); EyeTones = new Tone[9] { new Tone("Default", new Color(0.44f, 0.73f, 1f)), new Tone("Deep blue", new Color(0.12f, 0.32f, 0.85f)), new Tone("Green", new Color(0.3f, 0.78f, 0.35f)), new Tone("Hazel", new Color(0.6f, 0.48f, 0.18f)), new Tone("Brown", new Color(0.42f, 0.25f, 0.12f)), new Tone("Grey", new Color(0.62f, 0.66f, 0.7f)), new Tone("Amber", new Color(0.95f, 0.65f, 0.1f)), new Tone("Red", new Color(0.9f, 0.12f, 0.12f)), new Tone("Violet", new Color(0.6f, 0.28f, 0.88f)) }; EyeKey = StringExtensionMethods.GetStableHashCode("PM_eyes"); ByVis = new Dictionary<VisEquipment, Mannequin>(); CarryKeys = BuildCarryKeys(); for (int i = 0; i < 8; i++) { NameKeys[i] = StringExtensionMethods.GetStableHashCode((i == 0) ? "PM_name" : ("PM_name" + i)); } for (int j = 0; j < 8; j++) { for (int k = 0; k < Slots.Length; k++) { ItemKeys[j, k] = StringExtensionMethods.GetStableHashCode((j == 0) ? ("PM_item" + k) : ("PM_item" + j + "_" + k)); BlobKeys[j, k] = StringExtensionMethods.GetStableHashCode(j * 16 + k + "_itemData"); } } } private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); _anim = ((Component)this).GetComponentInChildren<Animator>(true); _vis = ((Component)this).GetComponent<VisEquipment>(); ZDO zdo = Zdo; if (zdo != null) { if ((Object)(object)_vis != (Object)null) { ByVis[_vis] = this; } _nview.Register<int>("PM_SetPose", (Action<long, int>)RPC_SetPose); _nview.Register<int, string>("PM_SetName", (Action<long, int, string>)RPC_SetName); _nview.Register<string>("PM_Label", (Action<long, string>)RPC_Label); ShowLabel(Label); WearNTear component = ((Component)this).GetComponent<WearNTear>(); if ((Object)(object)component != (Object)null) { component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(OnDestroyed)); } ApplyPose(zdo.GetInt(PoseKey, Plugin.DefaultPose.Value)); } else { ApplyPose(Plugin.DefaultPose.Value); } } private void OnDestroyed() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (!_nview.IsOwner()) { return; } for (int i = 0; i < 8; i++) { for (int j = 0; j < Slots.Length; j++) { if (Zdo.GetInt(ItemKeys[i, j], 0) != 0) { ItemData val = LoadItem(i, j); if (val == null) { Logger.LogWarning((object)$"ValheimMannequins: could not return item in set {i + 1} slot '{Slots[j].Label}' (prefab no longer exists)."); continue; } Vector3 val2 = ((Component)this).transform.position + Vector3.up * 0.8f + Random.insideUnitSphere * 0.3f; ItemDrop.DropItem(val, 0, val2, Quaternion.identity); ClearSlot(i, j); } } } } private void ApplyPose(int pose) { pose = Mathf.Clamp(pose, 0, 14); if (pose != _pose && !((Object)(object)_anim == (Object)null)) { _pose = pose; ((Behaviour)_anim).enabled = true; _anim.speed = 1f; _anim.SetInteger("Pose", pose); for (int i = 0; i < 30; i++) { _anim.Update(0.05f); } ((Behaviour)_anim).enabled = false; } } private void RPC_SetPose(long sender, int pose) { ApplyPose(pose); if (_nview.IsOwner()) { _nview.GetZDO().Set(PoseKey, _pose, false); } } public void RequestPoseStep(int delta) { if (HasAccess(flash: true)) { _nview.InvokeRPC(ZNetView.Everybody, "PM_SetPose", new object[1] { ((_pose + delta) % 15 + 15) % 15 }); } } private static string CleanName(string text) { text = (text ?? "").Replace("<", "").Replace(">", "").Trim(); if (text.Length <= 40) { return text; } return text.Substring(0, 40); } public string GetSetName(int set) { if (Zdo != null) { return Zdo.GetString(NameKeys[set], ""); } return ""; } private void ShowLabel(string name) { name = CleanName(name); _shown = name; if ((Object)(object)_plate == (Object)null) { if (name.Length == 0) { return; } _plate = Nameplate.Create(((Component)this).transform); } _plate.SetText(name); } private void BroadcastLabel() { _nview.InvokeRPC(ZNetView.Everybody, "PM_Label", new object[1] { Label }); } private void RPC_Label(long sender, string name) { ShowLabel(name); } private void RPC_SetName(long sender, int set, string name) { if (_nview.IsOwner() && set >= 0 && set < 8) { name = CleanName(name); _nview.GetZDO().Set(NameKeys[set], name); if (set == ActiveSet) { BroadcastLabel(); } } } public void RequestRename() { if (HasAccess(flash: true) && !((Object)(object)TextInput.instance == (Object)null)) { _renameSet = ActiveSet; TextInput.instance.RequestText((TextReceiver)(object)this, $"Name of set {_renameSet + 1} (empty = none)", 40); } } public string GetText() { return GetSetName(_renameSet); } public void SetText(string text) { if (HasAccess(flash: true)) { _nview.InvokeRPC(ZNetView.Everybody, "PM_SetName", new object[2] { _renameSet, CleanName(text) }); } } public void StepEyes(int delta) { if (HasAccess(flash: true) && TakeOwnership()) { Zdo.Set(EyeKey, ((EyeIndex + delta) % EyeTones.Length + EyeTones.Length) % EyeTones.Length, false); } } private void OnDestroy() { if ((Object)(object)_vis != (Object)null) { ByVis.Remove(_vis); } } internal void OnBodyUpdated() { ZDO zdo = Zdo; if (zdo != null && !((Object)(object)_vis == (Object)null) && !((Object)(object)_vis.m_bodyModel == (Object)null)) { int num = Mathf.Clamp(zdo.GetInt(ZDOVars.s_modelIndex, 0), 0, _vis.m_models.Length - 1); int eyeIndex = EyeIndex; if (num != _appliedModel || eyeIndex != _appliedEye) { _appliedModel = num; _appliedEye = eyeIndex; Texture texture = _vis.m_models[num].m_baseMaterial.GetTexture("_MainTex"); Texture val = ((eyeIndex == 0) ? texture : EyeTextures.Get(eyeIndex, num, texture)); ((Renderer)_vis.m_bodyModel).materials[0].SetTexture("_MainTex", val); } } } private static List<string> StyleNames(string prefix) { List<string> list = new List<string>(); if ((Object)(object)ObjectDB.instance == (Object)null) { return list; } foreach (ItemDrop allItem in ObjectDB.instance.GetAllItems((ItemType)10, prefix)) { if (!((Object)((Component)allItem).gameObject).name.EndsWith("None")) { list.Add(((Object)((Component)allItem).gameObject).name); } } list.Sort((string a, string b) => (a.Length == b.Length) ? string.CompareOrdinal(a, b) : a.Length.CompareTo(b.Length)); return list; } private static string Pretty(string prefabName, string prefix) { if (!prefabName.StartsWith(prefix)) { return prefabName; } return "Style " + prefabName.Substring(prefix.Length); } private int StyleIndex(int zdoKey, List<string> list) { int hash = ((Zdo != null) ? Zdo.GetInt(zdoKey, 0) : 0); if (hash == 0) { return 0; } int num = list.FindIndex((string n) => StringExtensionMethods.GetStableHashCode(n) == hash); if (num >= 0) { return num + 1; } return 0; } private void StepStyle(int zdoKey, List<string> list, int delta) { if (HasAccess(flash: true) && TakeOwnership()) { int num = list.Count + 1; int num2 = ((StyleIndex(zdoKey, list) + delta) % num + num) % num; Zdo.Set(zdoKey, (num2 != 0) ? StringExtensionMethods.GetStableHashCode(list[num2 - 1]) : 0, false); } } public void StepHair(int delta) { StepStyle(ZDOVars.s_hairItem, Hairs, delta); } public void StepBeard(int delta) { StepStyle(ZDOVars.s_beardItem, Beards, delta); } private void StepTone(int idxKey, int colorKey, Tone[] tones, int current, int delta) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (HasAccess(flash: true) && TakeOwnership()) { int num = ((current + delta) % tones.Length + tones.Length) % tones.Length; Color color = tones[num].Color; Zdo.Set(idxKey, num, false); Zdo.Set(colorKey, new Vector3(color.r, color.g, color.b)); } } public void StepSkin(int delta) { StepTone(SkinIdxKey, ZDOVars.s_skinColor, SkinTones, SkinIndex, delta); } public void StepHairTone(int delta) { StepTone(HairIdxKey, ZDOVars.s_hairColor, HairTones, HairToneIndex, delta); } public void ToggleBody() { if (HasAccess(flash: true) && TakeOwnership()) { Zdo.Set(ZDOVars.s_modelIndex, (!IsFemale) ? 1 : 0, false); } } public bool HasAccess(bool flash) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { return PrivateArea.CheckAccess(((Component)this).transform.position, 0f, flash, false); } return false; } private bool TakeOwnership() { if (!_nview.IsValid()) { return false; } if (!_nview.IsOwner()) { _nview.ClaimOwnership(); } return _nview.IsOwner(); } public bool IsEmpty(int slot) { return IsEmpty(ActiveSet, slot); } public bool IsEmpty(int set, int slot) { if (Zdo != null) { return Zdo.GetInt(ItemKeys[set, slot], 0) == 0; } return true; } public ItemData LoadItem(int slot) { return LoadItem(ActiveSet, slot); } public ItemData LoadItem(int set, int slot) { ZDO zdo = Zdo; if (zdo == null) { return null; } int num = zdo.GetInt(ItemKeys[set, slot], 0); if (num == 0) { return null; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(num) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null) { return null; } ItemData obj = val2.m_itemData.Clone(); obj.m_dropPrefab = val; ItemDrop.LoadFromZDO(obj, zdo, set * 16 + slot); obj.m_stack = 1; obj.m_equipped = false; return obj; } public void SelectSet(int set) { if (set >= 0 && set < SetCount && HasAccess(flash: true) && TakeOwnership()) { Zdo.Set(ActiveSetKey, set, false); RewriteVisuals(); BroadcastLabel(); } } public void StepSet(int delta) { int setCount = SetCount; SelectSet(((ActiveSet + delta) % setCount + setCount) % setCount); } private void RewriteVisuals() { ZDO zdo = Zdo; int activeSet = ActiveSet; for (int i = 0; i < Slots.Length; i++) { SlotDef slotDef = Slots[i]; ItemData val = ((zdo.GetInt(ItemKeys[activeSet, i], 0) != 0) ? LoadItem(activeSet, i) : null); zdo.Set(slotDef.VisualKey, (val != null) ? StringExtensionMethods.GetStableHashCode(((Object)val.m_dropPrefab).name) : 0, false); if (slotDef.VariantKey != 0) { zdo.Set(slotDef.VariantKey, val?.m_variant ?? 0, false); } if (slotDef.QualityKey != 0) { zdo.Set(slotDef.QualityKey, val?.m_quality ?? 0, false); } } } private void WriteSlot(int set, int slot, ItemData item) { ZDO zdo = Zdo; SlotDef slotDef = Slots[slot]; ItemData val = item.Clone(); val.m_stack = 1; val.m_equipped = false; int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)val.m_dropPrefab).name); zdo.Set(ItemKeys[set, slot], stableHashCode, false); ItemDrop.SaveToZDO(val, zdo, set * 16 + slot); if (set == ActiveSet) { zdo.Set(slotDef.VisualKey, stableHashCode, false); if (slotDef.VariantKey != 0) { zdo.Set(slotDef.VariantKey, val.m_variant, false); } if (slotDef.QualityKey != 0) { zdo.Set(slotDef.QualityKey, val.m_quality, false); } } } private void ClearSlot(int set, int slot) { ZDO zdo = Zdo; SlotDef slotDef = Slots[slot]; zdo.Set(ItemKeys[set, slot], 0, false); zdo.Set(BlobKeys[set, slot], new byte[0]); if (set == ActiveSet) { zdo.Set(slotDef.VisualKey, 0, false); if (slotDef.VariantKey != 0) { zdo.Set(slotDef.VariantKey, 0, false); } if (slotDef.QualityKey != 0) { zdo.Set(slotDef.QualityKey, 0, false); } } } public bool CanAttach(int slot, ItemData item) { //IL_0021: 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_002e: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null || (Object)(object)item.m_dropPrefab == (Object)null) { return false; } ItemType val = (((int)item.m_shared.m_attachOverride != 0) ? item.m_shared.m_attachOverride : item.m_shared.m_itemType); if (Array.IndexOf(Slots[slot].Types, val) < 0) { return false; } if ((int)val == 7 || (int)val == 11) { return true; } Transform transform = item.m_dropPrefab.transform; for (int i = 0; i < transform.childCount; i++) { string name = ((Object)((Component)transform.GetChild(i)).gameObject).name; if (name == "attach" || name == "attach_skin") { return true; } } return false; } public bool TryEquip(int slot, Player player, ItemData item) { if ((Object)(object)player == (Object)null || item == null || !HasAccess(flash: true)) { return false; } if (!CanAttach(slot, item)) { ((Character)player).Message((MessageType)2, "That item does not fit this slot.", 0, (Sprite)null, false); return false; } if (!TakeOwnership()) { return false; } int activeSet = ActiveSet; if (!IsEmpty(activeSet, slot)) { ((Character)player).Message((MessageType)2, "That slot is already occupied.", 0, (Sprite)null, false); return false; } Inventory inventory = ((Humanoid)player).GetInventory(); if (!inventory.ContainsItem(item)) { return false; } bool flag = ((Humanoid)player).IsItemEquiped(item); try { WriteSlot(activeSet, slot, item); if (flag) { ((Humanoid)player).UnequipItem(item, true); } if (!inventory.RemoveOneItem(item)) { ClearSlot(activeSet, slot); return false; } } catch (Exception ex) { Logger.LogError((object)("ValheimMannequins: equip failed, rolling back: " + ex)); ClearSlot(activeSet, slot); return false; } return true; } public bool TryTake(int slot, Player player) { if ((Object)(object)player == (Object)null || !HasAccess(flash: true)) { return false; } if (!TakeOwnership()) { return false; } int activeSet = ActiveSet; if (IsEmpty(activeSet, slot)) { return false; } ItemData val = LoadItem(activeSet, slot); if (val == null) { ((Character)player).Message((MessageType)2, "This item can no longer be loaded (missing mod?).", 0, (Sprite)null, false); return false; } Inventory inventory = ((Humanoid)player).GetInventory(); if (!inventory.CanAddItem(val, -1)) { ((Character)player).Message((MessageType)2, "$msg_inventoryfull", 0, (Sprite)null, false); return false; } if (!inventory.AddItem(val)) { return false; } ClearSlot(activeSet, slot); return true; } private static void CurrentGearSlots(Player player, ItemData[] worn) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Invalid comparison between Unknown and I4 //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Invalid comparison between Unknown and I4 //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Invalid comparison between Unknown and I4 //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Invalid comparison between Unknown and I4 //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Invalid comparison between Unknown and I4 //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Invalid comparison between Unknown and I4 object? obj = RightItemField?.GetValue(player) ?? HiddenRightItemField?.GetValue(player); ItemData val = (ItemData)((obj is ItemData) ? obj : null); object? obj2 = LeftItemField?.GetValue(player) ?? HiddenLeftItemField?.GetValue(player); ItemData val2 = (ItemData)((obj2 is ItemData) ? obj2 : null); foreach (ItemData equippedItem in ((Humanoid)player).GetInventory().GetEquippedItems()) { ItemType itemType = equippedItem.m_shared.m_itemType; int num; if ((int)itemType <= 7) { if ((int)itemType != 6) { if ((int)itemType != 7) { goto IL_00c5; } num = 1; } else { num = 0; } } else if ((int)itemType != 11) { if ((int)itemType != 17) { if ((int)itemType != 18) { goto IL_00c5; } num = 4; } else { num = 3; } } else { num = 2; } goto IL_0119; IL_00c5: ItemType itemType2 = equippedItem.m_shared.m_itemType; num = (((int)itemType2 != 5 && Array.IndexOf(Slots[5].Types, itemType2) < 0) ? (-1) : ((equippedItem == val) ? 5 : ((equippedItem == val2) ? 6 : (((int)itemType2 == 5) ? 6 : ((worn[5] == null) ? 5 : 6))))); goto IL_0119; IL_0119: if (num >= 0 && worn[num] == null) { worn[num] = equippedItem; } } } private static int[,] BuildCarryKeys() { int[,] array = new int[8, 2]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 2; j++) { array[i, j] = StringExtensionMethods.GetStableHashCode("PM_carry" + i + "_" + j); } } return array; } private static int CarryIndex(int set, int back) { return 200 + set * 2 + back; } private ItemData LoadCarry(int set, int back) { ZDO zdo = Zdo; int num = zdo.GetInt(CarryKeys[set, back], 0); if (num == 0) { return null; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(num) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null) { return null; } ItemData obj = val2.m_itemData.Clone(); obj.m_dropPrefab = val; ItemDrop.LoadFromZDO(obj, zdo, CarryIndex(set, back)); return obj; } private void WriteCarry(int set, int back, ItemData item) { ItemData val = CleanCopy(item); Zdo.Set(CarryKeys[set, back], StringExtensionMethods.GetStableHashCode(((Object)val.m_dropPrefab).name), false); ItemDrop.SaveToZDO(val, Zdo, CarryIndex(set, back)); } private void ClearCarry(int set, int back) { Zdo.Set(CarryKeys[set, back], 0, false); Zdo.Set(StringExtensionMethods.GetStableHashCode(CarryIndex(set, back) + "_itemData"), new byte[0]); } private static ItemData FindCarried(Inventory inventory, ItemData desc, ICollection<ItemData> exclude) { if (desc == null) { return null; } string name = ((Object)desc.m_dropPrefab).name; ItemData result = null; float num = float.MaxValue; foreach (ItemData allItem in inventory.GetAllItems()) { if (!exclude.Contains(allItem) && !((Object)(object)allItem.m_dropPrefab == (Object)null) && !(((Object)allItem.m_dropPrefab).name != name) && allItem.m_quality == desc.m_quality && allItem.m_variant == desc.m_variant && allItem.m_crafterID == desc.m_crafterID) { float num2 = Mathf.Abs(allItem.m_durability - desc.m_durability); if (num2 < num) { result = allItem; num = num2; } } } return result; } private static ItemData CleanCopy(ItemData item) { ItemData obj = item.Clone(); obj.m_stack = 1; obj.m_equipped = false; return obj; } public bool SwapWithPlayer(Player player, int set) { if ((Object)(object)player == (Object)null) { return false; } if (set < 0 || set >= SetCount) { ((Character)player).Message((MessageType)2, $"This mannequin has {SetCount} gear set(s).", 0, (Sprite)null, false); return false; } if (!HasAccess(flash: true) || !TakeOwnership()) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); ItemData[] array = (ItemData[])(object)new ItemData[7]; ItemData[] array2 = (ItemData[])(object)new ItemData[7]; CurrentGearSlots(player, array); for (int i = 0; i < 7; i++) { if (!IsEmpty(set, i)) { array2[i] = LoadItem(set, i); if (array2[i] == null) { ((Character)player).Message((MessageType)2, "Gear set contains an item that cannot be loaded (missing mod?).", 0, (Sprite)null, false); return false; } } } ItemData[] array3 = (ItemData[])(object)new ItemData[2]; ItemData[] array4 = (ItemData[])(object)new ItemData[2]; List<ItemData> list = new List<ItemData>(array); for (int j = 0; j < 2; j++) { if (!IsEmpty(set, 7 + j)) { array3[j] = LoadItem(set, 7 + j); if (array3[j] == null) { ((Character)player).Message((MessageType)2, "Gear set contains an item that cannot be loaded (missing mod?).", 0, (Sprite)null, false); return false; } } array4[j] = FindCarried(inventory, LoadCarry(set, j), list); if (array4[j] != null) { list.Add(array4[j]); } } int num = 0; int num2 = 0; for (int k = 0; k < 7; k++) { if (array2[k] != null) { num++; } if (array[k] != null) { num2++; } } for (int l = 0; l < 2; l++) { if (array3[l] != null) { num++; } if (array4[l] != null) { num2++; } } bool flag = false; for (int m = 0; m < 2; m++) { flag |= Zdo.GetInt(CarryKeys[set, m], 0) != 0; } if (num == 0 && num2 == 0 && !flag) { ((Character)player).Message((MessageType)2, "Nothing to swap.", 0, (Sprite)null, false); return false; } if (inventory.GetEmptySlots() + num2 < num) { ((Character)player).Message((MessageType)2, "$msg_inventoryfull", 0, (Sprite)null, false); return false; } List<ItemData> list2 = new List<ItemData>(); List<ItemData> list3 = new List<ItemData>(); ItemData[] array5 = (ItemData[])(object)new ItemData[7]; ItemData[] array6 = (ItemData[])(object)new ItemData[2]; try { for (int n = 0; n < 7; n++) { if (array[n] != null) { array5[n] = CleanCopy(array[n]); ((Humanoid)player).UnequipItem(array[n], false); if (!inventory.RemoveItem(array[n])) { throw new Exception("could not remove worn item " + array[n].m_shared.m_name); } list2.Add(array[n]); } } for (int num3 = 0; num3 < 2; num3++) { if (array4[num3] != null) { array6[num3] = CleanCopy(array4[num3]); ((Humanoid)player).UnequipItem(array4[num3], false); if (!inventory.RemoveItem(array4[num3])) { throw new Exception("could not take back remembered item " + array4[num3].m_shared.m_name); } list2.Add(array4[num3]); } } for (int num4 = 0; num4 < 7; num4++) { if (array2[num4] != null) { if (!inventory.AddItem(array2[num4])) { throw new Exception("could not add set item " + array2[num4].m_shared.m_name); } list3.Add(array2[num4]); } } for (int num5 = 0; num5 < 2; num5++) { if (array3[num5] != null) { if (!inventory.AddItem(array3[num5])) { throw new Exception("could not add back item " + array3[num5].m_shared.m_name); } list3.Add(array3[num5]); } } } catch (Exception ex) { Logger.LogError((object)("ValheimMannequins: gear swap failed, rolling back: " + ex.Message)); foreach (ItemData item in list3) { inventory.RemoveItem(item); } foreach (ItemData item2 in list2) { if (!inventory.ContainsItem(item2)) { inventory.AddItem(item2); } } ((Character)player).Message((MessageType)2, "Gear swap failed.", 0, (Sprite)null, false); return false; } Zdo.Set(ActiveSetKey, set, false); for (int num6 = 0; num6 < 7; num6++) { if (array5[num6] != null) { WriteSlot(set, num6, array5[num6]); } else { ClearSlot(set, num6); } } for (int num7 = 0; num7 < 2; num7++) { if (array6[num7] != null) { WriteSlot(set, 7 + num7, array6[num7]); } else { ClearSlot(set, 7 + num7); } if (array3[num7] != null) { WriteCarry(set, num7, array3[num7]); } else { ClearCarry(set, num7); } } RewriteVisuals(); BroadcastLabel(); for (int num8 = 0; num8 < 7; num8++) { if (array2[num8] != null) { ((Humanoid)player).EquipItem(array2[num8], true); } } return true; } public string GetHoverName() { if (_shown.Length <= 0) { return "Mannequin"; } return _shown; } public float GetHoverOffset() { return 0f; } public string GetHoverText() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize("Mannequin\n$piece_noaccess"); } string arg = Plugin.ModifierLabel(); return Localization.instance.Localize($"{GetHoverName()} (set {ActiveSet + 1}/{SetCount})\n[<color=yellow><b>$KEY_Use</b></color>] Manage\n" + "[<color=yellow><b>$KEY_HotbarUse</b></color>] Equip hotbar item\n" + $"[<color=yellow><b>{arg}+1-{SetCount}</b></color>] Swap gear set with mine"); } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold) { return false; } if (!HasAccess(flash: true)) { return true; } MannequinPanel.Show(this); return true; } public bool UseItem(Humanoid user, ItemData item) { Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || item == null) { return false; } if (!HasAccess(flash: true)) { return true; } bool flag = false; for (int i = 0; i < Slots.Length; i++) { if (CanAttach(i, item)) { flag = true; if (IsEmpty(i)) { TryEquip(i, val, item); return true; } } } if (flag) { ((Character)val).Message((MessageType)2, "All matching slots are occupied.", 0, (Sprite)null, false); } return flag; } } [HarmonyPatch(typeof(Player), "UseHotbarItem")] internal static class HotbarSwapPatch { private static bool Prefix(Player __instance, int index) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Plugin.ModifierHeld()) { return true; } GameObject hoverObject = ((Humanoid)__instance).GetHoverObject(); Mannequin mannequin = (((Object)(object)hoverObject != (Object)null) ? hoverObject.GetComponentInParent<Mannequin>() : null); if ((Object)(object)mannequin == (Object)null) { return true; } mannequin.SwapWithPlayer(__instance, index - 1); return false; } } internal static class MannequinScroll { public static Mannequin Hovered() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).InPlaceMode() || ((Character)localPlayer).IsDead()) { return null; } if (InventoryGui.IsVisible() || Menu.IsVisible() || TextInput.IsVisible() || Console.IsVisible() || MannequinPanel.IsOpen || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())) { return null; } GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject(); if (!((Object)(object)hoverObject != (Object)null)) { return null; } return hoverObject.GetComponentInParent<Mannequin>(); } } [HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")] internal static class ScrollZoomPatch { private static void Postfix(ref float __result) { if (__result != 0f && Plugin.ScrollSwitchesSet.Value && (Object)(object)MannequinScroll.Hovered() != (Object)null) { __result = 0f; } } } [HarmonyPatch(typeof(VisEquipment), "UpdateBaseModel")] internal static class EyeTexturePatch { private static void Postfix(VisEquipment __instance) { if (Mannequin.ByVis.Count != 0 && Mannequin.ByVis.TryGetValue(__instance, out var value)) { value.OnBodyUpdated(); } } } internal static class MannequinIcon { private static string FilePath => Path.Combine(Paths.ConfigPath, "ValheimMannequins_icon.png"); public static void Apply(GameObject prefab) { //IL_0071: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown Piece component = prefab.GetComponent<Piece>(); if ((Object)(object)component == (Object)null || GUIManager.IsHeadless()) { return; } if (File.Exists(FilePath)) { Sprite val = AssetUtils.LoadSpriteFromFile(FilePath); if ((Object)(object)val != (Object)null) { component.m_icon = val; return; } Logger.LogWarning((object)("ValheimMannequins: could not load " + FilePath + ", rendering a new icon.")); } GameObject val2 = null; ZNetView.m_forceDisableInit = true; try { val2 = Object.Instantiate<GameObject>(prefab, new Vector3(0f, -5000f, 0f), Quaternion.identity); } finally { ZNetView.m_forceDisableInit = false; } try { RenderRequest val3 = new RenderRequest(val2) { Width = 256, Height = 256, Rotation = Quaternion.Euler(0f, 25f, 0f), DistanceMultiplier = 1.05f, UseCache = false }; Sprite val4 = RenderManager.Instance.Render(val3); if ((Object)(object)val4 == (Object)null) { Logger.LogWarning((object)"ValheimMannequins: icon render returned nothing, keeping the placeholder."); return; } component.m_icon = val4; File.WriteAllBytes(FilePath, ImageConversion.EncodeToPNG(val4.texture)); Logger.LogInfo((object)("ValheimMannequins: icon rendered and saved to " + FilePath)); } catch (Exception ex) { Logger.LogWarning((object)("ValheimMannequins: icon render failed, keeping the placeholder: " + ex.Message)); } finally { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } } } } internal class MannequinPanel : MonoBehaviour { private static MannequinPanel _instance; private Mannequin _target; private GameObject _root; private RectTransform _leftRows; private RectTransform _content; private Text _rightHeader; private Text _poseLabel; private Text _title; private Text _lookLabel; private bool _lookMode; private GameObject _scrollGo; private readonly List<GameObject> _dynamic = new List<GameObject>(); private int _selected; private uint _lastRevision; private float _nextPoll; private const float MaxDistance = 6f; public static bool IsOpen { get { if ((Object)(object)_instance != (Object)null && (Object)(object)_instance._root != (Object)null) { return _instance._root.activeSelf; } return false; } } public static void Show(Mannequin target) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown if (GUIManager.Instance != null && !((Object)(object)GUIManager.CustomGUIFront == (Object)null)) { if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("PM_Panel"); val.transform.SetParent(GUIManager.CustomGUIFront.transform, false); _instance = val.AddComponent<MannequinPanel>(); _instance.Build(val.transform); } _instance.Open(target); } } private void Build(Transform parent) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00f9: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Expected O, but got Unknown //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Expected O, but got Unknown //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Expected O, but got Unknown //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Expected O, but got Unknown //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Expected O, but got Unknown //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Expected O, but got Unknown GUIManager instance = GUIManager.Instance; _root = instance.CreateWoodpanel(parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 780f, 620f, true); Transform transform = _root.transform; _title = Label(transform, "Mannequin", new Vector2(0f, 285f), 28, 600f, 40f).GetComponent<Text>(); Label(transform, "Tip: aim at it and press an item's hotbar key", new Vector2(-190f, 203f), 15, 360f, 24f); GameObject val = new GameObject("Rows", new Type[1] { typeof(RectTransform) }); _leftRows = val.GetComponent<RectTransform>(); ((Transform)_leftRows).SetParent(transform, false); RectTransform leftRows = _leftRows; RectTransform leftRows2 = _leftRows; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); leftRows2.anchorMax = val2; leftRows.anchorMin = val2; _leftRows.anchoredPosition = Vector2.zero; _leftRows.sizeDelta = Vector2.zero; _rightHeader = Label(transform, "", new Vector2(190f, 203f), 15, 340f, 24f).GetComponent<Text>(); GameObject val3 = instance.CreateScrollView(transform, false, true, 8f, 4f, instance.ValheimScrollbarHandleColorBlock, new Color(0f, 0f, 0f, 0.35f), 340f, 380f); RectTransform component = val3.GetComponent<RectTransform>(); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); component.anchorMax = val2; component.anchorMin = val2; component.anchoredPosition = new Vector2(190f, 0f); _scrollGo = val3; ScrollRect componentInChildren = val3.GetComponentInChildren<ScrollRect>(true); _content = componentInChildren.content; VerticalLayoutGroup obj = ((Component)_content).gameObject.GetComponent<VerticalLayoutGroup>() ?? ((Component)_content).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj).spacing = 4f; ((LayoutGroup)obj).padding = new RectOffset(4, 12, 4, 4); (((Component)_content).gameObject.GetComponent<ContentSizeFitter>() ?? ((Component)_content).gameObject.AddComponent<ContentSizeFitter>()).verticalFit = (FitMode)2; Button(transform, "<", new Vector2(-340f, -265f), 40f, 34f, (UnityAction)delegate { _target?.RequestPoseStep(-1); }); _poseLabel = Label(transform, "", new Vector2(-265f, -265f), 16, 110f, 30f).GetComponent<Text>(); Button(transform, ">", new Vector2(-190f, -265f), 40f, 34f, (UnityAction)delegate { _target?.RequestPoseStep(1); }); GameObject val4 = Button(transform, "Look", new Vector2(-70f, -265f), 150f, 34f, (UnityAction)delegate { _lookMode = !_lookMode; Refresh(); }); _lookLabel = val4.GetComponentInChildren<Text>(); Button(transform, "Rename", new Vector2(110f, -265f), 150f, 34f, new UnityAction(Rename)); Button(transform, "Close", new Vector2(290f, -265f), 140f, 34f, new UnityAction(Close)); _root.SetActive(false); } private static GameObject Label(Transform parent, string text, Vector2 pos, int size, float w, float h) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0036: Unknown result type (might be due to invalid IL or missing references) GUIManager instance = GUIManager.Instance; return instance.CreateText(text, parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), pos, instance.AveriaSerifBold, size, instance.ValheimBeige, true, Color.black, w, h, false); } private static GameObject Button(Transform parent, string text, Vector2 pos, float w, float h, UnityAction onClick) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GUIManager.Instance.CreateButton(text, parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), pos, w, h); ((UnityEvent)obj.GetComponent<Button>().onClick).AddListener(onClick); return obj; } private void Open(Mannequin target) { //IL_0020: 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) _target = target; _selected = 0; _lookMode = false; _root.transform.localScale = Vector3.one * Plugin.PanelScale.Value; _root.SetActive(true); GUIManager.BlockInput(true); Refresh(); } private void Rename() { Mannequin target = _target; if (!((Object)(object)target == (Object)null)) { Close(); target.RequestRename(); } } private void Close() { if ((Object)(object)_root != (Object)null && _root.activeSelf) { _root.SetActive(false); GUIManager.BlockInput(false); } _target = null; } private void OnDisable() { if ((Object)(object)_root != (Object)null && _root.activeSelf) { GUIManager.BlockInput(false); } } private void Update() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null || !_root.activeSelf) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)_target == (Object)null || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || Input.GetKeyDown((KeyCode)27) || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_target).transform.position) > 6f) { Close(); } else if (!(Time.unscaledTime < _nextPoll)) { _nextPoll = Time.unscaledTime + 0.4f; ZDO zdo = _target.Zdo; if (zdo == null) { Close(); } else if (zdo.DataRevision != _lastRevision) { Refresh(); } } } private void Clear() { foreach (GameObject item in _dynamic) { if (Object.op_Implicit((Object)(object)item)) { Object.Destroy((Object)(object)item); } } _dynamic.Clear(); } private void Refresh() { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Expected O, but got Unknown //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Expected O, but got Unknown //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Expected O, but got Unknown //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_05f0: Expected O, but got Unknown if ((Object)(object)_target == (Object)null || _target.Zdo == null) { return; } _lastRevision = _target.Zdo.DataRevision; Clear(); GUIManager instance = GUIManager.Instance; int setCount = _target.SetCount; int activeSet = _target.ActiveSet; for (int i = 0; i < setCount; i++) { int set = i; float num = Mathf.Min(140f, 700f / (float)setCount - 6f); float num2 = ((float)i - (float)(setCount - 1) / 2f) * (num + 6f); string setName = _target.GetSetName(set); string text = ((setName.Length == 0) ? ("Set " + (set + 1)) : ((setName.Length > 11) ? (setName.Substring(0, 10) + "…") : setName)); GameObject val = Button((Transform)(object)_leftRows, (set == activeSet) ? ("> " + text + " <") : text, new Vector2(num2, 247f), num, 32f, (UnityAction)delegate { _target.SelectSet(set); _selected = 0; Refresh(); }); val.GetComponentInChildren<Text>().fontSize = 15; _dynamic.Add(val); } for (int num3 = 0; num3 < Mannequin.Slots.Length; num3++) { int slot = num3; ItemData val2 = _target.LoadItem(num3); bool flag = !_target.IsEmpty(num3); string text2 = ((val2 != null) ? Localization.instance.Localize(val2.m_shared.m_name) : (flag ? "(unavailable item)" : "- empty -")); string text3 = ((slot == _selected) ? "> " : "") + Mannequin.Slots[num3].Label + ": " + text2; float num4 = 165f - (float)num3 * 42f; GameObject val3 = Button((Transform)(object)_leftRows, text3, new Vector2(-215f, num4), 270f, 36f, (UnityAction)delegate { _selected = slot; Refresh(); }); val3.GetComponentInChildren<Text>().fontSize = 15; _dynamic.Add(val3); if (flag) { GameObject val4 = Button((Transform)(object)_leftRows, "Take", new Vector2(-30f, num4), 70f, 36f, (UnityAction)delegate { _target.TryTake(slot, Player.m_localPlayer); Refresh(); }); val4.GetComponentInChildren<Text>().fontSize = 15; _dynamic.Add(val4); } } _scrollGo.SetActive(!_lookMode); if (_lookMode) { BuildLook(); } else { _rightHeader.text = "Your items for: " + Mannequin.Slots[_selected].Label; foreach (Transform item in (Transform)_content) { Object.Destroy((Object)(object)((Component)item).gameObject); } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && _target.IsEmpty(_selected)) { foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems()) { if (_target.CanAttach(_selected, allItem)) { ItemData captured = allItem; GameObject val5 = new GameObject("Row", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); val5.transform.SetParent((Transform)(object)_content, false); HorizontalLayoutGroup component = val5.GetComponent<HorizontalLayoutGroup>(); bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = childControlWidth; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component).spacing = 6f; val5.GetComponent<LayoutElement>().minHeight = 36f; GameObject val6 = new GameObject("Icon", new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val6.transform.SetParent(val5.transform, false); val6.GetComponent<Image>().sprite = allItem.GetIcon(); LayoutElement component2 = val6.GetComponent<LayoutElement>(); float minWidth = (component2.preferredWidth = 34f); component2.minWidth = minWidth; minWidth = (component2.preferredHeight = 34f); component2.minHeight = minWidth; string text4 = Localization.instance.Localize(allItem.m_shared.m_name) + ((allItem.m_quality > 1) ? $" (Q{allItem.m_quality})" : "") + (((Humanoid)localPlayer).IsItemEquiped(allItem) ? " [worn]" : ""); GameObject obj = instance.CreateButton(text4, val5.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 0f, 0f); LayoutElement obj2 = obj.AddComponent<LayoutElement>(); obj2.flexibleWidth = 1f; obj2.minHeight = 34f; obj2.preferredHeight = 34f; obj.GetComponentInChildren<Text>().fontSize = 14; ((UnityEvent)obj.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { _target.TryEquip(_selected, Player.m_localPlayer, captured); Refresh(); }); } } } else if (!_target.IsEmpty(_selected)) { AddNote("This slot is occupied. Take the item first."); } } _title.text = ((_target.Label.Length > 0) ? ("Mannequin - " + _target.Label) : "Mannequin"); _poseLabel.text = $"Pose {_target.Pose + 1}/{15}"; _lookLabel.text = (_lookMode ? "Back to items" : "Look"); } private void BuildLook() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) _rightHeader.text = "Appearance"; Mannequin m = _target; LookRow("Body", m.IsFemale ? "Female" : "Male", null, 150f, delegate { m.ToggleBody(); }); LookRow("Hair style", m.HairName, null, 85f, delegate(int d) { m.StepHair(d); }); LookRow("Hair colour", Mannequin.HairTones[m.HairToneIndex].Name, Mannequin.HairTones[m.HairToneIndex].Color, 20f, delegate(int d) { m.StepHairTone(d); }); LookRow("Beard", m.BeardName, null, -45f, delegate(int d) { m.StepBeard(d); }); LookRow("Skin tone", Mannequin.SkinTones[m.SkinIndex].Name, Mannequin.SkinTones[m.SkinIndex].Color, -110f, delegate(int d) { m.StepSkin(d); }); LookRow("Eye colour", Mannequin.EyeTones[m.EyeIndex].Name, Mannequin.EyeTones[m.EyeIndex].Color, -175f, delegate(int d) { m.StepEyes(d); }); } private void LookRow(string title, string value, Color? swatch, float y, Action<int> step) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_009b: 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) //IL_00bb: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) _dynamic.Add(Label((Transform)(object)_leftRows, title, new Vector2(190f, y + 24f), 15, 300f, 24f)); GameObject item = Button((Transform)(object)_leftRows, "<", new Vector2(45f, y - 8f), 44f, 34f, (UnityAction)delegate { step(-1); Refresh(); }); GameObject item2 = Button((Transform)(object)_leftRows, ">", new Vector2(335f, y - 8f), 44f, 34f, (UnityAction)delegate { step(1); Refresh(); }); _dynamic.Add(item); _dynamic.Add(item2); _dynamic.Add(Label((Transform)(object)_leftRows, value, new Vector2(swatch.HasValue ? 168f : 190f, y - 8f), 17, 150f, 30f)); if (swatch.HasValue) { GameObject val = new GameObject("Swatch", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)_leftRows, false); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); component.anchorMax = val2; component.anchorMin = val2; component.anchoredPosition = new Vector2(278f, y - 8f); component.sizeDelta = new Vector2(26f, 26f); ((Graphic)val.GetComponent<Image>()).color = swatch.Value; _dynamic.Add(val); } } private void AddNote(string msg) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0046: Unknown result type (might be due to invalid IL or missing references) GUIManager.Instance.CreateText(msg, (Transform)(object)_content, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, GUIManager.Instance.AveriaSerifBold, 15, GUIManager.Instance.ValheimBeige, false, Color.black, 300f, 30f, false).AddComponent<LayoutElement>().minHeight = 30f; } } internal static class MannequinPrefab { public const string PrefabName = "PM_Mannequin"; public static GameObject Build() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = PrefabManager.Instance.GetPrefab("ArmorStand_Male"); Animator val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponentInChildren<Animator>(true) : null); if ((Object)(object)val == (Object)null || (Object)(object)val.runtimeAnimatorController == (Object)null) { Logger.LogError((object)"ValheimMannequins: ArmorStand_Male animator not found, cannot build the mannequin."); return null; } GameObject val2 = PrefabManager.Instance.CreateClonedPrefab("PM_Mannequin", "Player"); if ((Object)(object)val2 == (Object)null) { Logger.LogError((object)"ValheimMannequins: failed to clone the Player prefab."); return null; } VisEquipment component = val2.GetComponent<VisEquipment>(); component.m_playerComponent = null; component.m_nViewOverride = null; component.m_isPlayer = true; component.m_isArmorStand = false; Transform val3 = val2.transform.Find("Visual"); Remove<CharacterAnimEvent>(((Component)val3).gameObject); Remove<PlayerController>(val2); Remove<FootStep>(val2); Remove<Talker>(val2); Remove<Skills>(val2); Remove<ZSyncAnimation>(val2); Remove<ZSyncTransform>(val2); Remove<Player>(val2); Remove<Rigidbody>(val2); Remove<CapsuleCollider>(val2); foreach (ParticleSystem item in val2.GetComponentsInChildren<ParticleSystem>(true).ToList()) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } Transform val4 = val3.Find("DevEffects"); if ((Object)(object)val4 != (Object)null) { Object.DestroyImmediate((Object)(object)((Component)val4).gameObject); } Animator component2 = ((Component)val3).GetComponent<Animator>(); component2.runtimeAnimatorController = val.runtimeAnimatorController; component2.cullingMode = (AnimatorCullingMode)0; ZNetView component3 = val2.GetComponent<ZNetView>(); component3.m_persistent = true; component3.m_distant = false; GameObject val5 = new GameObject("Hitbox"); val5.transform.SetParent(val2.transform, false); val5.layer = LayerMask.NameToLayer("piece"); CapsuleCollider obj = val5.AddComponent<CapsuleCollider>(); obj.center = new Vector3(0f, 0.9f, 0f); obj.height = 1.8f; obj.radius = 0.35f; Piece val6 = val2.AddComponent<Piece>(); CopyPublicFields((Component)(object)prefab.GetComponent<Piece>(), (Component)(object)val6, prefab.transform); val6.m_name = "Mannequin"; val6.m_description = "A player-shaped display figure."; WearNTear val7 = val2.AddComponent<WearNTear>(); CopyPublicFields((Component)(object)prefab.GetComponent<WearNTear>(), (Component)(object)val7, prefab.transform); val7.m_supports = false; val7.m_autoCreateFragments = false; val7.m_new = (val7.m_worn = (val7.m_broken = (val7.m_wet = null))); val2.AddComponent<Mannequin>(); val2.layer = LayerMask.NameToLayer("piece"); return val2; } private static void Remove<T>(GameObject root) where T : Component { for (int i = 0; i < 3; i++) { T[] componentsInChildren = root.GetComponentsInChildren<T>(true); if (componentsInChildren.Length == 0) { return; } T[] array = componentsInChildren; foreach (T val in array) { try { Object.DestroyImmediate((Object)(object)val); } catch (Exception ex) { Logger.LogDebug((object)("ValheimMannequins: could not remove " + typeof(T).Name + " yet: " + ex.Message)); } } } if (root.GetComponentsInChildren<T>(true).Length != 0) { Logger.LogWarning((object)("ValheimMannequins: " + typeof(T).Name + " could not be removed from the mannequin prefab.")); } } private static void CopyPublicFields(Component src, Component dst, Transform srcRoot) { FieldInfo[] fields = ((object)src).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (typeof(Delegate).IsAssignableFrom(fieldInfo.FieldType)) { continue; } object obj = fieldInfo.GetValue(src); Component val = (Component)((obj is Component) ? obj : null); if (val != null && (Object)(object)val != (Object)null && (Object)(object)val.transform.root == (Object)(object)srcRoot) { obj = null; } else { GameObject val2 = (GameObject)((obj is GameObject) ? obj : null); if (val2 != null && (Object)(object)val2 != (Object)null && (Object)(object)val2.transform.root == (Object)(object)srcRoot) { obj = null; } else if (obj is IList && fieldInfo.FieldType.IsArray && obj is Object[]) { obj = Array.CreateInstance(fieldInfo.FieldType.GetElementType(), 0); } else if (obj is IList && !fieldInfo.FieldType.IsArray && fieldInfo.FieldType.IsGenericType && typeof(Component).IsAssignableFrom(fieldInfo.FieldType.GetGenericArguments()[0])) { obj = Activator.CreateInstance(fieldInfo.FieldType); } } fieldInfo.SetValue(dst, obj); } } } internal class Nameplate : MonoBehaviour { private const float HeadHeight = 2.1f; private GameObject _container; private TextMeshProUGUI _text; private bool _hasText; private string _wanted = ""; public static Nameplate Create(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("NameplateAnchor"); val.transform.SetParent(parent, false); val.transform.localPosition = new Vector3(0f, 2.1f, 0f); Nameplate nameplate = val.AddComponent<Nameplate>(); ((Behaviour)nameplate).enabled = false; return nameplate; } private bool EnsureWidget() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00bc: 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) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_container != (Object)null) { return true; } EnemyHud instance = EnemyHud.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_baseHudPlayer == (Object)null || (Object)(object)instance.m_hudRoot == (Object)null) { return false; } Transform val = instance.m_baseHudPlayer.transform.Find("Name"); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"ValheimMannequins: vanilla player name widget not found; no nameplate."); return false; } _container = new GameObject("PM_Nameplate", new Type[1] { typeof(RectTransform) }); RectTransform component = _container.GetComponent<RectTransform>(); ((Transform)component).SetParent(instance.m_hudRoot.transform, false); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); component.anchorMax = val2; component.anchorMin = val2; component.sizeDelta = Vector2.zero; GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, (Transform)(object)component, false); val3.SetActive(true); RectTransform component2 = val3.GetComponent<RectTransform>(); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); component2.anchorMax = val2; component2.anchorMin = val2; component2.pivot = new Vector2(0.5f, 0.5f); component2.anchoredPosition = Vector2.zero; _text = val3.GetComponent<TextMeshProUGUI>(); ((TMP_Text)_text).richText = false; _container.SetActive(false); return true; } public void SetText(string text) { _wanted = text ?? ""; _hasText = _wanted.Length > 0; if (_hasText) { if (EnsureWidget()) { ((TMP_Text)_text).text = _wanted; } } else if ((Object)(object)_container != (Object)null) { _container.SetActive(false); } ((Behaviour)this).enabled = _hasText; } private void LateUpdate() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_container == (Object)null) { if (!EnsureWidget()) { return; } ((TMP_Text)_text).text = _wanted; } Camera mainCamera = Utils.GetMainCamera(); if ((Object)(object)mainCamera == (Object)null) { return; } float value = Plugin.NameDistance.Value; Vector3 val = ((Component)mainCamera).transform.position - ((Component)this).transform.position; if (((Vector3)(ref val)).sqrMagnitude > value * value) { Hide(); return; } Vector3 val2 = Utils.WorldToScreenPointScaled(mainCamera, ((Component)this).transform.position); if (val2.z <= 0f) { Hide(); return; } if (!_container.activeSelf) { _container.SetActive(true); } _container.transform.position = val2; } private void Hide() { if (_container.activeSelf) { _container.SetActive(false); } } private void OnDestroy() { if ((Object)(object)_container != (Object)null) { Object.Destroy((Object)(object)_container); } } } [BepInPlugin("morda.ValheimMannequins", "Valheim Mannequins", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string ModGuid = "morda.ValheimMannequins"; public const string ModName = "Valheim Mannequins"; public const string ModVersion = "0.3.0"; internal static ConfigEntry<string> Recipe; internal static ConfigEntry<int> DefaultPose; internal static ConfigEntry<int> SetCount; internal static ConfigEntry<KeyCode> SwapModifier; internal static ConfigEntry<float> PanelScale; internal static ConfigEntry<float> NameDistance; internal static ConfigEntry<bool> ScrollSwitchesSet; private float _nextScroll; private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) Recipe = ((BaseUnityPlugin)this).Config.Bind<string>("Recipe", "Materials", "Wood:20,Iron:1", new ConfigDescription("Build cost as Item:Amount pairs separated by commas (prefab names, e.g. Wood:20,Iron:1). Read at game start.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { IsAdminOnly = true } })); DefaultPose = ((BaseUnityPlugin)this).Config.Bind<int>("Mannequin", "DefaultPose", 0, new ConfigDescription("Pose index (0-14) a newly placed mannequin starts with.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 14), Array.Empty<object>())); SetCount = ((BaseUnityPlugin)this).Config.Bind<int>("Gear sets", "SetCount", 5, new ConfigDescription("Number of gear sets per mannequin (1-8). Lowering it never deletes stored items; hidden sets are returned when the mannequin is removed.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>())); SwapModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Gear sets", "SwapModifier", (KeyCode)308, "Hold this key + a number key while aiming at a mannequin to swap your worn gear with that gear set. (Left/right Alt, Ctrl and Shift are treated as the same key.) Change it if another mod already uses Alt+number."); PanelScale = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "PanelScale", 1.6f, new ConfigDescription("Size of the mannequin window.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.8f, 3f), Array.Empty<object>())); NameDistance = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "NameDistance", 30f, new ConfigDescription("Distance in meters up to which a mannequin's name is shown.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 100f), Array.Empty<object>())); ScrollSwitchesSet = ((BaseUnityPlugin)this).Config.Bind<bool>("Gear sets", "ScrollSwitchesSet", true, "Scrolling the mouse wheel while aiming at a mannequin switches its displayed gear set (the camera does not zoom while doing so)."); new Harmony("morda.ValheimMannequins").PatchAll(); PrefabManager.OnVanillaPrefabsAvailable += RegisterMannequin; } private void Update() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) float y = Input.mouseScrollDelta.y; if (y != 0f && ScrollSwitchesSet.Value && !(Time.unscaledTime < _nextScroll)) { Mannequin mannequin = MannequinScroll.Hovered(); if (!((Object)(object)mannequin == (Object)null)) { _nextScroll = Time.unscaledTime + 0.15f; mannequin.StepSet((y > 0f) ? 1 : (-1)); } } } internal static bool ModifierHeld() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) KeyCode value = SwapModifier.Value; if ((int)value != 0) { switch (value - 303) { case 4: case 5: if (!Input.GetKey((KeyCode)308)) { return Input.GetKey((KeyCode)307); } return true; case 2: case 3: if (!Input.GetKey((KeyCode)306)) { return Input.GetKey((KeyCode)305); } return true; case 0: case 1: if (!Input.GetKey((KeyCode)304)) { return Input.GetKey((KeyCode)303); } return true; default: return Input.GetKey(SwapModifier.Value); } } return false; } internal static string ModifierLabel() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_002f: Expected I4, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) KeyCode value = SwapModifier.Value; switch (value - 303) { case 4: case 5: return "Alt"; case 2: case 3: return "Ctrl"; case 0: case 1: return "Shift"; default: return ((object)SwapModifier.Value/*cast due to .constrained prefix*/).ToString(); } } private static void RegisterMannequin() { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= RegisterMannequin; GameObject val = MannequinPrefab.Build(); if ((Object)(object)val == (Object)null) { return; } GameObject prefab = PrefabManager.Instance.GetPrefab("ArmorStand_Male"); List<RequirementConfig> list = new List<RequirementConfig>(); string[] array = Recipe.Value.Split(new char[1] { ',' }); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }); if (array2.Length == 2 && int.TryParse(array2[1].Trim(), out var result) && result > 0 && !string.IsNullOrWhiteSpace(array2[0])) { list.Add(new RequirementConfig(array2[0].Trim(), result, 0, true)); } else { Logger.LogWarning((object)("Valheim Mannequins: ignoring malformed recipe entry '" + text + "'")); } } PieceConfig val2 = new PieceConfig { Name = "Mannequin", Description = "A player-shaped display figure.", PieceTable = "Hammer", Category = "Furniture", Requirements = list.ToArray(), Icon = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Piece>().m_icon : null) }; PieceManager.Instance.AddPiece(new CustomPiece(val, false, val2)); MannequinIcon.Apply(val); Logger.LogInfo((object)"Valheim Mannequins: mannequin piece registered."); } } internal sealed class ConfigurationManagerAttributes { public bool? IsAdminOnly; } }