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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Scripting;
using ValheimPlayerModels.Loaders;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: IgnoresAccessChecksTo("assembly_googleanalytics")]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_lux")]
[assembly: IgnoresAccessChecksTo("assembly_postprocessing")]
[assembly: IgnoresAccessChecksTo("assembly_simplemeshcombine")]
[assembly: IgnoresAccessChecksTo("assembly_steamworks")]
[assembly: IgnoresAccessChecksTo("assembly_sunshafts")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("ValheimPlayerModels")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Use custom player models in Valheim !")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Valheim Player Models")]
[assembly: AssemblyTitle("ValheimPlayerModels")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Ikeiwa/ValheimPlayerModels")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 ValheimPlayerModels
{
internal sealed class ConfigurationManagerAttributes
{
public bool? ShowRangeAsPercent;
public Action<ConfigEntryBase> CustomDrawer;
public bool? Browsable;
public string Category;
public object DefaultValue;
public bool? HideDefaultButton;
public bool? HideSettingName;
public string Description;
public string DispName;
public int? Order;
public bool? ReadOnly;
public bool? IsAdvanced;
public Func<object, string> ObjToStr;
public Func<string, object> StrToObj;
}
public class CustomRagdoll : MonoBehaviour
{
private Ragdoll ragdoll;
private Animator ragdollAnimator;
private Animator avatarAnimator;
private bool hidden = false;
public void Setup(Animator ogAnimator, Animator avatarAnimator)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: 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_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: 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_01b6: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)avatarAnimator))
{
Object.Destroy((Object)(object)this);
}
((Component)avatarAnimator).transform.SetParent(((Component)this).transform);
((Component)avatarAnimator).transform.localPosition = Vector3.zero;
((Component)avatarAnimator).transform.localRotation = Quaternion.identity;
ragdoll = ((Component)this).GetComponent<Ragdoll>();
this.avatarAnimator = avatarAnimator;
ragdollAnimator = ((Component)((Component)ragdoll).gameObject.transform.GetChild(0)).gameObject.AddComponent<Animator>();
ragdollAnimator.avatar = ogAnimator.avatar;
avatarAnimator.GetBoneTransform((HumanBodyBones)0).position = ragdollAnimator.GetBoneTransform((HumanBodyBones)0).position;
for (int i = 0; i < 55; i++)
{
Transform boneTransform = ragdollAnimator.GetBoneTransform((HumanBodyBones)i);
Transform boneTransform2 = avatarAnimator.GetBoneTransform((HumanBodyBones)i);
if (Object.op_Implicit((Object)(object)boneTransform) && Object.op_Implicit((Object)(object)boneTransform2))
{
RotationConstraint val = ((Component)boneTransform2).gameObject.AddComponent<RotationConstraint>();
ConstraintSource val2 = default(ConstraintSource);
((ConstraintSource)(ref val2)).sourceTransform = boneTransform;
((ConstraintSource)(ref val2)).weight = 1f;
val.AddSource(val2);
Quaternion val3 = Quaternion.identity * Quaternion.Inverse(boneTransform.rotation);
Quaternion val4 = Quaternion.identity * Quaternion.Inverse(boneTransform2.rotation);
Quaternion val5 = val3 * Quaternion.Inverse(val4);
val.rotationOffset = ((Quaternion)(ref val5)).eulerAngles;
val.locked = true;
val.constraintActive = true;
if (i == 0)
{
PositionConstraint val6 = ((Component)boneTransform2).gameObject.AddComponent<PositionConstraint>();
val2 = default(ConstraintSource);
((ConstraintSource)(ref val2)).sourceTransform = boneTransform;
((ConstraintSource)(ref val2)).weight = 1f;
val6.AddSource(val2);
val6.translationOffset = boneTransform2.position - boneTransform.position;
val6.locked = true;
val6.constraintActive = true;
}
}
}
}
private void LateUpdate()
{
if (!hidden)
{
Renderer[] componentsInChildren = ((Component)((Component)ragdollAnimator).transform).GetComponentsInChildren<Renderer>();
foreach (Renderer val in componentsInChildren)
{
val.enabled = false;
}
hidden = true;
}
}
}
public static class HarmonyUtils
{
public static Tout GetField<Tin, Tout>(this Tin self, string fieldName)
{
return AccessTools.FieldRefAccess<Tin, Tout>(fieldName).Invoke(self);
}
}
[DefaultExecutionOrder(2147483646)]
public class PlayerModel : MonoBehaviour
{
public class AttachTransform
{
public Transform ogAttach;
public Transform pmAttach;
public Vector3 ogPosition;
public Quaternion ogRotation;
public Vector3 ogScale;
}
public static PlayerModel localModel;
public string selectedAvatar = "";
private VisEquipment visEquipment;
private GameObject ogVisual;
private int selectedHash = Animator.StringToHash("SelectedCustomAvatar");
private bool playerModelVisible = true;
private Animator ogAnimator;
private List<AttachTransform> ogAttachments;
private HumanPoseHandler ogPose;
private HumanPoseHandler pmPose;
private HumanPose pose = default(HumanPose);
private float footOffset;
private bool dead = false;
private bool requestHide;
public bool enableTracking = true;
public Player player { get; private set; }
public ZNetView zNetView { get; private set; }
public AvatarInstance avatar { get; private set; }
public bool playerModelLoaded { get; private set; }
private void Awake()
{
player = ((Component)this).GetComponent<Player>();
visEquipment = ((Component)this).GetComponent<VisEquipment>();
zNetView = ((Component)this).GetComponent<ZNetView>();
ogVisual = ((Component)((Character)player).m_animator).gameObject;
ogAnimator = ((Character)player).m_animator;
ogAnimator.keepAnimatorControllerStateOnDisable = true;
ogAnimator.cullingMode = (AnimatorCullingMode)0;
((MonoBehaviour)this).StartCoroutine(LoadAvatar());
}
private void OnDestroy()
{
if ((Object)(object)localModel == (Object)(object)this)
{
Plugin.showActionMenu = false;
Plugin.showAvatarMenu = false;
Plugin.ResetCursor();
}
RemoveAvatar();
((MonoBehaviour)this).StopAllCoroutines();
}
private void Update()
{
}
private void FixedUpdate()
{
if (!((Object)(object)Game.instance != (Object)null) || !playerModelLoaded || !playerModelVisible || dead || !zNetView.IsValid() || zNetView.IsOwner())
{
return;
}
ZDO zDO = zNetView.GetZDO();
foreach (KeyValuePair<int, AvatarInstance.AvatarParameter> parameter in avatar.Parameters)
{
switch (parameter.Value.type)
{
case AvatarInstance.ParameterType.Bool:
{
bool @bool = zDO.GetBool(438569 + parameter.Key, false);
avatar.Animator.SetBool(parameter.Key, @bool);
break;
}
case AvatarInstance.ParameterType.Int:
{
int @int = zDO.GetInt(438569 + parameter.Key, 0);
avatar.Animator.SetInteger(parameter.Key, @int);
break;
}
case AvatarInstance.ParameterType.Float:
{
float @float = zDO.GetFloat(438569 + parameter.Key, 0f);
avatar.Animator.SetFloat(parameter.Key, @float);
break;
}
default:
throw new ArgumentOutOfRangeException();
}
}
string @string = zDO.GetString(selectedHash, (string)null);
if (@string != null && @string != selectedAvatar)
{
selectedAvatar = @string;
ReloadAvatar();
}
}
private void LateUpdate()
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: 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)
if (!playerModelLoaded || !playerModelVisible || dead)
{
return;
}
if (enableTracking)
{
avatar.Transform.localPosition = Vector3.zero;
ogPose.GetHumanPose(ref pose);
pmPose.SetHumanPose(ref pose);
Transform boneTransform = ogAnimator.GetBoneTransform((HumanBodyBones)0);
if (Object.op_Implicit((Object)(object)boneTransform))
{
avatar.Hips.position = new Vector3(avatar.Hips.position.x, boneTransform.position.y, avatar.Hips.position.z);
float num = Mathf.Min(new float[3]
{
avatar.LeftFoot.position.y - avatar.Transform.position.y,
avatar.RightFoot.position.y - avatar.Transform.position.y,
0f
});
avatar.Hips.Translate(0f, 0f - num + footOffset, 0f, (Space)0);
}
}
foreach (AttachTransform ogAttachment in ogAttachments)
{
if ((Object)(object)ogAttachment.pmAttach != (Object)null)
{
ogAttachment.ogAttach.position = ogAttachment.pmAttach.position;
ogAttachment.ogAttach.rotation = ogAttachment.pmAttach.rotation;
ogAttachment.ogAttach.localScale = Vector3.Scale(ogAttachment.ogScale, ogAttachment.pmAttach.localScale);
}
}
if (requestHide)
{
ToggleEquipments();
}
if (((Character)player).IsDead() && !dead)
{
dead = true;
if (!PluginConfig.enableCustomRagdoll.Value)
{
Hide();
}
}
}
private IEnumerator LoadAvatar()
{
yield return (object)new WaitForSecondsRealtime(0.5f);
Plugin.RefreshBundlePaths();
if ((Object)(object)player == (Object)(object)Player.m_localPlayer || (Object)(object)Game.instance == (Object)null)
{
selectedAvatar = PluginConfig.selectedAvatar.Value;
localModel = this;
}
if ((Object)(object)zNetView != (Object)null && zNetView.IsValid() && !zNetView.IsOwner() && (Object)(object)Game.instance != (Object)null)
{
int tries = 0;
string syncedAvatar = null;
while (syncedAvatar == null && tries < 100)
{
syncedAvatar = zNetView.GetZDO().GetString(selectedHash, (string)null);
tries++;
yield return (object)new WaitForSecondsRealtime(0.05f);
}
if (syncedAvatar != null)
{
selectedAvatar = syncedAvatar;
}
}
if (string.IsNullOrEmpty(selectedAvatar))
{
if ((Object)(object)Game.instance != (Object)null)
{
selectedAvatar = player.GetPlayerName();
if (selectedAvatar == "" || selectedAvatar == "...")
{
selectedAvatar = Game.instance.GetPlayerProfile().GetName();
}
}
else
{
int index = FejdStartup.instance.GetField<FejdStartup, int>("m_profileIndex");
List<PlayerProfile> profiles = FejdStartup.instance.GetField<FejdStartup, List<PlayerProfile>>("m_profiles");
if (index >= 0 && index < profiles.Count)
{
selectedAvatar = profiles[index].GetName();
}
}
selectedAvatar = selectedAvatar.ToLower();
string playerId = "";
if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer() && (int)ZNet.GetConnectionStatus() == 2)
{
int tries2 = 0;
do
{
List<PlayerInfo> playerList = ZNet.instance.GetPlayerList();
int playerIndex = playerList.FindIndex((PlayerInfo p) => ((ZDOID)(ref p.m_characterID)).UserID == ((ZDOID)(ref zNetView.m_zdo.m_uid)).UserID);
if (playerIndex != -1)
{
playerId = playerList[playerIndex].m_host;
tries2++;
}
else
{
tries2++;
yield return null;
}
}
while (string.IsNullOrEmpty(playerId) && tries2 < 100);
if (!string.IsNullOrEmpty(playerId) && Plugin.playerModelBundlePaths.ContainsKey(playerId))
{
selectedAvatar = playerId;
}
}
}
if ((Object)(object)zNetView != (Object)null && zNetView.IsValid() && zNetView.IsOwner() && (Object)(object)Game.instance != (Object)null)
{
zNetView.GetZDO().Set(selectedHash, selectedAvatar);
}
Plugin.Log.LogMessage((object)("Loading " + selectedAvatar + " avatar"));
if (!Plugin.playerModelBundlePaths.ContainsKey(selectedAvatar))
{
Plugin.Log.LogError((object)("Bundle list doesn't contain bundle for : " + selectedAvatar));
Object.Destroy((Object)(object)this);
yield break;
}
AvatarLoaderBase loader;
if (Plugin.playerModelBundleCache.ContainsKey(selectedAvatar))
{
while (Plugin.playerModelBundleCache[selectedAvatar] == null)
{
yield return null;
}
loader = Plugin.playerModelBundleCache[selectedAvatar];
}
else
{
if (!Plugin.playerModelBundleCache.ContainsKey(selectedAvatar))
{
Plugin.playerModelBundleCache.Add(selectedAvatar, null);
}
string avatarFile = Plugin.playerModelBundlePaths[selectedAvatar];
string text = Path.GetExtension(avatarFile).ToLower();
string text2 = text;
string text3 = text2;
if (!(text3 == ".valavtr"))
{
if (!(text3 == ".vrm"))
{
Object.Destroy((Object)(object)this);
yield break;
}
loader = new VrmLoader();
}
else
{
loader = new ValavtrLoader();
}
yield return ((MonoBehaviour)this).StartCoroutine(loader.LoadFile(avatarFile));
if (!loader.LoadedSuccessfully)
{
Plugin.playerModelBundleCache.Remove(selectedAvatar);
Object.Destroy((Object)(object)this);
}
Plugin.playerModelBundleCache[selectedAvatar] = loader;
}
avatar = loader.LoadAvatar(this);
if (avatar == null)
{
Object.Destroy((Object)(object)this);
}
ApplyAvatar();
playerModelLoaded = true;
}
private void SetAttachParent(Transform attach, Transform newAttach)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
ogAttachments.Add(new AttachTransform
{
ogAttach = attach,
pmAttach = newAttach,
ogPosition = attach.localPosition,
ogRotation = attach.localRotation,
ogScale = attach.localScale
});
}
private void ApplyAvatar()
{
//IL_0024: 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_00b1: Expected O, but got Unknown
//IL_00f5: 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_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Expected O, but got Unknown
avatar.Animator.applyRootMotion = true;
avatar.Animator.updateMode = ogAnimator.updateMode;
avatar.Animator.feetPivotActive = ogAnimator.feetPivotActive;
avatar.Animator.layersAffectMassCenter = ogAnimator.layersAffectMassCenter;
avatar.Animator.stabilizeFeet = ogAnimator.stabilizeFeet;
if (ogPose == null)
{
ogPose = new HumanPoseHandler(ogAnimator.avatar, ((Component)ogAnimator).transform);
}
if (pmPose == null)
{
pmPose = new HumanPoseHandler(avatar.Animator.avatar, ((Component)avatar.Animator).transform);
}
footOffset = (avatar.LeftFoot.position.y - avatar.Transform.position.y + (avatar.RightFoot.position.y - avatar.Transform.position.y)) / 2f;
ogAttachments = new List<AttachTransform>();
SetAttachParent(visEquipment.m_backAtgeir, avatar.AvatarDescriptor.backAtgeir);
SetAttachParent(visEquipment.m_backBow, avatar.AvatarDescriptor.backBow);
SetAttachParent(visEquipment.m_backMelee, avatar.AvatarDescriptor.backMelee);
SetAttachParent(visEquipment.m_backShield, avatar.AvatarDescriptor.backShield);
SetAttachParent(visEquipment.m_backTool, avatar.AvatarDescriptor.backTool);
SetAttachParent(visEquipment.m_backTwohandedMelee, avatar.AvatarDescriptor.backTwohandedMelee);
SetAttachParent(visEquipment.m_helmet, avatar.AvatarDescriptor.helmet);
SetAttachParent(visEquipment.m_leftHand, avatar.AvatarDescriptor.leftHand);
SetAttachParent(visEquipment.m_rightHand, avatar.AvatarDescriptor.rightHand);
ToggleAvatar();
}
public void ToggleAvatar(bool visible = true)
{
playerModelVisible = visible;
Animator animator = avatar.Animator;
if (animator != null)
{
((Component)animator).gameObject.SetActive(visible);
}
SkinnedMeshRenderer[] componentsInChildren = ogVisual.GetComponentsInChildren<SkinnedMeshRenderer>();
foreach (SkinnedMeshRenderer val in componentsInChildren)
{
((Renderer)val).forceRenderingOff = visible;
val.updateWhenOffscreen = true;
}
ToggleEquipments(!visible);
}
public void Hide()
{
((Component)avatar.Animator).gameObject.SetActive(false);
}
public void Show()
{
if (Object.op_Implicit((Object)(object)avatar.Animator))
{
((Component)avatar.Animator).gameObject.SetActive(true);
}
}
public void ToggleEquipments(bool visible = false)
{
//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
//IL_02db: Unknown result type (might be due to invalid IL or missing references)
if (!playerModelLoaded)
{
requestHide = true;
}
else
{
if (!Object.op_Implicit((Object)(object)visEquipment))
{
return;
}
GameObject beardItemInstance = visEquipment.m_beardItemInstance;
if (beardItemInstance != null)
{
beardItemInstance.SetActive(visible);
}
GameObject hairItemInstance = visEquipment.m_hairItemInstance;
if (hairItemInstance != null)
{
hairItemInstance.SetActive(visible);
}
GameObject helmetItemInstance = visEquipment.m_helmetItemInstance;
if (helmetItemInstance != null)
{
helmetItemInstance.SetActive(visible || avatar.AvatarDescriptor.showHelmet);
}
if (visEquipment.m_shoulderItemInstances != null)
{
foreach (GameObject shoulderItemInstance in visEquipment.m_shoulderItemInstances)
{
if (visEquipment.m_shoulderItem.ToLower().Contains("cape"))
{
if (shoulderItemInstance != null)
{
shoulderItemInstance.SetActive(visible || avatar.AvatarDescriptor.showCape);
}
SkinnedMeshRenderer[] componentsInChildren = shoulderItemInstance.GetComponentsInChildren<SkinnedMeshRenderer>();
foreach (SkinnedMeshRenderer val in componentsInChildren)
{
((Renderer)val).forceRenderingOff = false;
val.updateWhenOffscreen = true;
}
}
else if (shoulderItemInstance != null)
{
shoulderItemInstance.SetActive(visible);
}
}
}
if (visEquipment.m_legItemInstances != null)
{
foreach (GameObject legItemInstance in visEquipment.m_legItemInstances)
{
if (legItemInstance != null)
{
legItemInstance.SetActive(visible);
}
}
}
if (visEquipment.m_chestItemInstances != null)
{
foreach (GameObject chestItemInstance in visEquipment.m_chestItemInstances)
{
if (chestItemInstance != null)
{
chestItemInstance.SetActive(visible);
}
}
}
if (visEquipment.m_utilityItemInstances != null)
{
foreach (GameObject utilityItemInstance in visEquipment.m_utilityItemInstances)
{
if (utilityItemInstance != null)
{
utilityItemInstance.SetActive(visible);
}
}
}
if (visible)
{
foreach (AttachTransform ogAttachment in ogAttachments)
{
ogAttachment.ogAttach.localPosition = ogAttachment.ogPosition;
ogAttachment.ogAttach.localRotation = ogAttachment.ogRotation;
ogAttachment.ogAttach.localScale = ogAttachment.ogScale;
}
SkinnedMeshRenderer[] componentsInChildren2 = ogVisual.GetComponentsInChildren<SkinnedMeshRenderer>();
foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
{
((Renderer)val2).forceRenderingOff = false;
val2.updateWhenOffscreen = true;
}
}
requestHide = false;
}
}
public void SetupRagdoll(Ragdoll ragdoll)
{
((Component)ragdoll).gameObject.AddComponent<CustomRagdoll>().Setup(ogAnimator, avatar.Animator);
}
public void RemoveAvatar(bool forced = false)
{
if ((!PluginConfig.enableCustomRagdoll.Value || forced) && avatar != null)
{
Object.Destroy((Object)(object)avatar.AvatarObject);
}
avatar = null;
if (ogPose != null)
{
ogPose.Dispose();
ogPose = null;
}
if (pmPose != null)
{
pmPose.Dispose();
pmPose = null;
}
playerModelLoaded = false;
}
public void ReloadAvatar()
{
if (playerModelLoaded)
{
ToggleAvatar(visible: false);
RemoveAvatar(forced: true);
((MonoBehaviour)this).StartCoroutine(LoadAvatar());
}
}
}
[HarmonyPatch(typeof(Player), "Awake")]
internal static class Patch_Player_Awake
{
[HarmonyPostfix]
private static void Postfix(Player __instance)
{
if (PluginConfig.enablePlayerModels.Value)
{
((Component)__instance).gameObject.AddComponent<PlayerModel>();
}
}
}
[HarmonyPatch(typeof(VisEquipment), "UpdateLodgroup")]
internal static class Patch_VisEquipment_UpdateLodgroup
{
[HarmonyPostfix]
private static void Postfix(VisEquipment __instance)
{
if (PluginConfig.enablePlayerModels.Value)
{
((Component)__instance).GetComponent<PlayerModel>()?.ToggleEquipments();
}
}
}
[HarmonyPatch(typeof(Ragdoll), "Start")]
internal static class Patch_Ragdoll_Start
{
[HarmonyPostfix]
private static void Postfix(Ragdoll __instance)
{
if (PluginConfig.enableCustomRagdoll.Value && ((Object)((Component)__instance).gameObject).name.StartsWith("Player") && Object.op_Implicit((Object)(object)ZNet.instance))
{
PlayerModel[] source = Object.FindObjectsOfType<PlayerModel>();
PlayerModel playerModel = source.FirstOrDefault(delegate(PlayerModel p)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
ZDOID zDOID = ((Character)p.player).GetZDOID();
return ((ZDOID)(ref zDOID)).UserID == ((ZDOID)(ref __instance.m_nview.m_zdo.m_uid)).UserID;
});
if (Object.op_Implicit((Object)(object)playerModel))
{
playerModel.SetupRagdoll(__instance);
}
}
}
}
[HarmonyPatch(typeof(Terminal), "TryRunCommand")]
internal static class Patch_Terminal_TryRunCommand
{
[HarmonyPostfix]
private static void Postfix(Terminal __instance, string text, bool silentFail = false, bool skipAllowedCheck = false)
{
string text2 = text.ToLower();
string[] array = text2.Split(new char[1] { ' ' });
if (text2.StartsWith("anim") && array.Length == 3 && Object.op_Implicit((Object)(object)PlayerModel.localModel) && (!bool.TryParse(array[2], out var result) || !PlayerModel.localModel.avatar.SetBool(array[1], result)) && (!int.TryParse(array[2], out var result2) || !PlayerModel.localModel.avatar.SetInt(array[1], result2)) && float.TryParse(array[2], out var result3))
{
PlayerModel.localModel.avatar.SetFloat(array[1], result3);
}
}
}
[HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")]
internal static class Patch_GameCamera_UpdateMouseCapture
{
[HarmonyPrefix]
private static bool Prefix(GameCamera __instance)
{
if (PluginConfig.enablePlayerModels.Value && (Plugin.showActionMenu || Plugin.showAvatarMenu))
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Player), "SetMouseLook")]
internal static class Patch_Player_SetMouseLook
{
[HarmonyPrefix]
private static bool Prefix(Player __instance)
{
if (PluginConfig.enablePlayerModels.Value && (Plugin.showActionMenu || Plugin.showAvatarMenu))
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Character), "SetVisible")]
internal static class Patch_Character_SetVisible
{
[HarmonyPostfix]
private static void Postfix(Character __instance, bool visible)
{
//IL_00bc: 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)
if (!__instance.IsPlayer())
{
return;
}
PlayerModel playerModel;
if (!Plugin.playerModelCharacters.ContainsKey(__instance))
{
playerModel = ((Component)__instance.GetVisual().transform.parent).GetComponent<PlayerModel>();
Plugin.playerModelCharacters.Add(__instance, playerModel);
}
else
{
playerModel = Plugin.playerModelCharacters[__instance];
}
if (!Object.op_Implicit((Object)(object)playerModel) || playerModel.avatar == null)
{
return;
}
LODGroup lodGroup = playerModel.avatar.lodGroup;
if (Object.op_Implicit((Object)(object)lodGroup))
{
if (visible)
{
lodGroup.localReferencePoint = __instance.m_originalLocalRef;
}
else
{
lodGroup.localReferencePoint = new Vector3(999999f, 999999f, 999999f);
}
}
}
}
[BepInPlugin("ValheimPlayerModels", "Valheim Player Models", "1.0.1")]
[BepInProcess("valheim.exe")]
public class Plugin : BaseUnityPlugin
{
public static ManualLogSource Log;
public static Dictionary<string, AvatarLoaderBase> playerModelBundleCache = new Dictionary<string, AvatarLoaderBase>();
public static Dictionary<Character, PlayerModel> playerModelCharacters = new Dictionary<Character, PlayerModel>();
public static bool showActionMenu;
public static bool showAvatarMenu;
private Rect ActionWindowRect;
private Rect AvatarWindowRect;
private static CursorLockMode oldCursorLockState = (CursorLockMode)2;
private static bool oldCursorVisible = false;
public const int ActionWindowId = -48;
public const int AvatarWindowId = -49;
private Vector2 actionMenuWindowScrollPos;
private Vector2 avatarMenuWindowScrollPos;
private int hasChangedParam = 0;
public static string playerModelsPath => Path.Combine(Environment.CurrentDirectory, "PlayerModels");
public static Dictionary<string, string> playerModelBundlePaths { get; private set; }
private void Awake()
{
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
GarbageCollector.incrementalTimeSliceNanoseconds = 5000000uL;
PluginConfig.InitConfig(((BaseUnityPlugin)this).Config);
((BaseUnityPlugin)this).Config.SettingChanged += ConfigOnSettingChanged;
if (!Directory.Exists(playerModelsPath))
{
Directory.CreateDirectory(playerModelsPath);
}
RefreshBundlePaths(silent: false);
Harmony val = new Harmony("ValheimPlayerModels.patch");
val.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin ValheimPlayerModels is loaded!");
}
private void Update()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: 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)
KeyboardShortcut value = PluginConfig.reloadKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown() && PluginConfig.enablePlayerModels.Value)
{
PlayerModel[] array = Object.FindObjectsOfType<PlayerModel>();
bool flag = true;
PlayerModel[] array2 = array;
foreach (PlayerModel playerModel in array2)
{
if (!playerModel.playerModelLoaded)
{
flag = false;
break;
}
}
if (!flag)
{
return;
}
PlayerModel[] array3 = array;
foreach (PlayerModel playerModel2 in array3)
{
playerModel2.ToggleAvatar(visible: false);
Object.Destroy((Object)(object)playerModel2);
}
foreach (AvatarLoaderBase value2 in playerModelBundleCache.Values)
{
value2?.Unload();
}
playerModelBundleCache.Clear();
RefreshBundlePaths();
Player[] array4 = Object.FindObjectsOfType<Player>();
Player[] array5 = array4;
foreach (Player val in array5)
{
((Component)val).gameObject.AddComponent<PlayerModel>();
}
}
value = PluginConfig.actionMenuKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown() && !showAvatarMenu && (Object)(object)PlayerModel.localModel != (Object)null && (Object)(object)Game.instance != (Object)null)
{
showActionMenu = !showActionMenu;
if (showActionMenu)
{
SetUnlockCursor();
GUI.FocusWindow(-48);
}
else
{
ResetCursor();
}
}
value = PluginConfig.avatarMenuKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown() && !showActionMenu)
{
showAvatarMenu = !showAvatarMenu;
if (showAvatarMenu)
{
SetUnlockCursor();
GUI.FocusWindow(-49);
}
else
{
ResetCursor();
}
}
if (showActionMenu && hasChangedParam > 0)
{
hasChangedParam--;
}
}
private void ConfigOnSettingChanged(object sender, SettingChangedEventArgs e)
{
if (e.ChangedSetting.Definition.Key == "EnablePlayerModels")
{
PlayerModel[] array = Object.FindObjectsOfType<PlayerModel>();
if ((bool)e.ChangedSetting.BoxedValue)
{
PlayerModel[] array2 = array;
foreach (PlayerModel playerModel in array2)
{
playerModel.ToggleAvatar();
}
Player[] array3 = Object.FindObjectsOfType<Player>();
Player[] array4 = array3;
foreach (Player val in array4)
{
if ((Object)(object)((Component)val).GetComponent<PlayerModel>() == (Object)null)
{
((Component)val).gameObject.AddComponent<PlayerModel>();
}
}
}
else
{
PlayerModel[] array5 = array;
foreach (PlayerModel playerModel2 in array5)
{
playerModel2.ToggleAvatar(visible: false);
}
}
}
else if (e.ChangedSetting.Definition.Key == "SelectedAvatar")
{
PlayerModel playerModel3 = null;
playerModel3 = ((!((Object)(object)Player.m_localPlayer != (Object)null)) ? Object.FindObjectOfType<PlayerModel>() : ((Component)Player.m_localPlayer).gameObject.GetComponent<PlayerModel>());
if ((Object)(object)playerModel3 != (Object)null && playerModel3.playerModelLoaded)
{
playerModel3.ReloadAvatar();
}
}
}
public static void RefreshBundlePaths(bool silent = true)
{
playerModelBundlePaths = new Dictionary<string, string>();
string[] array = (from s in Directory.GetFiles(playerModelsPath, "*.*", SearchOption.AllDirectories)
where s.EndsWith(".valavtr") || s.EndsWith(".vrm")
select s).ToArray();
string[] array2 = array;
foreach (string text in array2)
{
string text2 = Path.GetFileNameWithoutExtension(text).ToLower();
if (!silent)
{
Log.LogMessage((object)("Found avatar : " + text2));
}
if (!playerModelBundlePaths.ContainsKey(text2))
{
playerModelBundlePaths.Add(text2, text);
}
}
}
public static void SetUnlockCursor()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
if ((int)Cursor.lockState != 0)
{
oldCursorLockState = Cursor.lockState;
oldCursorVisible = Cursor.visible;
Cursor.lockState = (CursorLockMode)0;
Cursor.visible = true;
}
}
public static void ResetCursor()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
Cursor.lockState = oldCursorLockState;
Cursor.visible = oldCursorVisible;
}
private void OnGUI()
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: 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_00ad: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Expected O, but got Unknown
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
//IL_0204: Expected O, but got Unknown
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
if (showActionMenu && (Object)(object)PlayerModel.localModel != (Object)null)
{
ActionWindowRect = new Rect((float)Screen.width, (float)Screen.height, 250f, 400f);
ref Rect actionWindowRect = ref ActionWindowRect;
((Rect)(ref actionWindowRect)).x = ((Rect)(ref actionWindowRect)).x - ((Rect)(ref ActionWindowRect)).width;
ref Rect actionWindowRect2 = ref ActionWindowRect;
((Rect)(ref actionWindowRect2)).y = ((Rect)(ref actionWindowRect2)).y - ((Rect)(ref ActionWindowRect)).height;
if ((GUI.Button(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), string.Empty, GUIStyle.none) && !((Rect)(ref ActionWindowRect)).Contains(Input.mousePosition)) || Input.GetKeyDown((KeyCode)27))
{
showActionMenu = false;
ResetCursor();
}
GUI.enabled = PlayerModel.localModel.playerModelLoaded;
GUI.Box(ActionWindowRect, GUIContent.none);
GUILayout.Window(-48, ActionWindowRect, new WindowFunction(ActionMenuWindow), "Action Menu", Array.Empty<GUILayoutOption>());
Input.ResetInputAxes();
}
if (showAvatarMenu)
{
AvatarWindowRect = new Rect(20f, 100f, 250f, 400f);
if ((GUI.Button(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), string.Empty, GUIStyle.none) && !((Rect)(ref AvatarWindowRect)).Contains(Input.mousePosition)) || Input.GetKeyDown((KeyCode)27))
{
showAvatarMenu = false;
ResetCursor();
}
if (Object.op_Implicit((Object)(object)PlayerModel.localModel))
{
GUI.enabled = PlayerModel.localModel.playerModelLoaded;
}
else
{
GUI.enabled = true;
}
GUI.Box(AvatarWindowRect, GUIContent.none);
GUILayout.Window(-49, AvatarWindowRect, new WindowFunction(AvatarMenuWindow), "Avatar Menu", Array.Empty<GUILayoutOption>());
Input.ResetInputAxes();
}
}
private void ActionMenuWindow(int id)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
AvatarInstance avatar = PlayerModel.localModel.avatar;
actionMenuWindowScrollPos = GUILayout.BeginScrollView(actionMenuWindowScrollPos, false, true, Array.Empty<GUILayoutOption>());
float y = actionMenuWindowScrollPos.y;
float height = ((Rect)(ref ActionWindowRect)).height;
GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
float num = 21f;
float num2 = 0f;
for (int i = 0; i < avatar.MenuControls.Count; i++)
{
int num3 = Animator.StringToHash(avatar.MenuControls[i].parameter);
if (string.IsNullOrEmpty(avatar.MenuControls[i].name) || string.IsNullOrEmpty(avatar.MenuControls[i].parameter) || !avatar.Parameters.ContainsKey(num3))
{
continue;
}
if (num == 0f || (num2 + num >= y && num2 <= y + height))
{
try
{
GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
GUILayout.Label(avatar.MenuControls[i].name, Array.Empty<GUILayoutOption>());
float parameterValue = avatar.GetParameterValue(num3);
switch (avatar.MenuControls[i].type)
{
case ControlType.Button:
if (GUILayout.Button("Press", Array.Empty<GUILayoutOption>()))
{
if (parameterValue == 0f)
{
avatar.SetParameterValue(num3, avatar.MenuControls[i].value);
hasChangedParam = 5;
}
}
else if (parameterValue != 0f && hasChangedParam <= 0)
{
avatar.SetParameterValue(num3, 0f);
}
break;
case ControlType.Toggle:
{
bool flag = parameterValue != 0f;
bool flag2 = GUILayout.Toggle(flag, string.Empty, Array.Empty<GUILayoutOption>());
if (flag2 != flag)
{
avatar.SetParameterValue(num3, flag2 ? avatar.MenuControls[i].value : 0f);
}
break;
}
case ControlType.Slider:
{
float num4 = GUILayout.HorizontalSlider(parameterValue, 0f, 1f, Array.Empty<GUILayoutOption>());
if (Mathf.Abs(num4 - parameterValue) > 0.01f)
{
avatar.SetParameterValue(num3, num4);
}
break;
}
default:
throw new ArgumentOutOfRangeException();
}
GUILayout.EndHorizontal();
}
catch (ArgumentException)
{
}
}
else
{
try
{
GUILayout.Space(num);
}
catch (ArgumentException)
{
}
}
num2 += num;
}
GUILayout.Space(70f);
GUILayout.EndVertical();
GUILayout.EndScrollView();
}
private void AvatarMenuWindow(int id)
{
//IL_0003: 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_0014: Unknown result type (might be due to invalid IL or missing references)
avatarMenuWindowScrollPos = GUILayout.BeginScrollView(avatarMenuWindowScrollPos, false, true, Array.Empty<GUILayoutOption>());
float y = avatarMenuWindowScrollPos.y;
float height = ((Rect)(ref AvatarWindowRect)).height;
GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
float num = 21f;
float num2 = num;
GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
GUILayout.Label("Automatic", Array.Empty<GUILayoutOption>());
if (PluginConfig.selectedAvatar.Value == "")
{
GUI.enabled = false;
}
if (GUILayout.Button("Select", Array.Empty<GUILayoutOption>()))
{
((ConfigEntryBase)PluginConfig.selectedAvatar).BoxedValue = "";
}
GUI.enabled = true;
GUILayout.EndHorizontal();
foreach (string key in playerModelBundlePaths.Keys)
{
if (num == 0f || (num2 + num >= y && num2 <= y + height))
{
try
{
GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
GUILayout.Label(key, Array.Empty<GUILayoutOption>());
if (PlayerModel.localModel.selectedAvatar == key)
{
GUI.enabled = false;
}
if (GUILayout.Button("Select", Array.Empty<GUILayoutOption>()))
{
((ConfigEntryBase)PluginConfig.selectedAvatar).BoxedValue = key;
}
GUI.enabled = true;
GUILayout.EndHorizontal();
}
catch (ArgumentException)
{
}
}
else
{
try
{
GUILayout.Space(num);
}
catch (ArgumentException)
{
}
}
num2 += num;
}
GUILayout.EndVertical();
GUILayout.EndScrollView();
}
}
public static class PluginConfig
{
public const string PLUGIN_GUID = "ValheimPlayerModels";
public const string PLUGIN_NAME = "Valheim Player Models";
public const string PLUGIN_VERSION = "1.0.1";
public static ConfigFile config;
public static ConfigEntry<bool> enablePlayerModels;
public static ConfigEntry<bool> enableCustomRagdoll;
public static ConfigEntry<string> serverUrl;
public static ConfigEntry<string> selectedAvatar;
public static ConfigEntry<KeyboardShortcut> reloadKey;
public static ConfigEntry<KeyboardShortcut> actionMenuKey;
public static ConfigEntry<KeyboardShortcut> avatarMenuKey;
public static void InitConfig(ConfigFile _config)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: 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
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Expected O, but got Unknown
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Expected O, but got Unknown
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Expected O, but got Unknown
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Expected O, but got Unknown
config = _config;
enablePlayerModels = config.Bind<bool>("General", "EnablePlayerModels", true, new ConfigDescription("Toggle the use of custom player models.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 1
}
}));
enableCustomRagdoll = config.Bind<bool>("General", "EnableCustomRagdoll", true, new ConfigDescription("Toggle the use of custom player models for ragdolls.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 2
}
}));
selectedAvatar = config.Bind<string>("General", "SelectedAvatar", "", new ConfigDescription("Selected avatar name, leave empty for automatic", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Browsable = false
}
}));
reloadKey = config.Bind<KeyboardShortcut>("General", "ReloadKey", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), new ConfigDescription("The key to reload the player models.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 3
}
}));
actionMenuKey = config.Bind<KeyboardShortcut>("General", "ActionMenuKey", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), new ConfigDescription("The key to open the action menu.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 4
}
}));
avatarMenuKey = config.Bind<KeyboardShortcut>("General", "AvatarMenuKey", new KeyboardShortcut((KeyCode)279, Array.Empty<KeyCode>()), new ConfigDescription("The key to open the avatar selection menu.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 4
}
}));
serverUrl = config.Bind<string>("General", "ServerURL", "", new ConfigDescription("Player Models Server URL, keep empty for local player models only.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 6
}
}));
}
}
[DefaultExecutionOrder(int.MaxValue)]
public sealed class SpringBone : MonoBehaviour
{
public enum SpringBoneUpdateType
{
LateUpdate,
FixedUpdate
}
private class SpringBoneLogic
{
private Transform m_transform;
private Vector3 m_boneAxis;
private Vector3 m_currentTail;
private readonly float m_length;
private Vector3 m_prevTail;
public Transform Head => m_transform;
public Vector3 Tail
{
get
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
Matrix4x4 localToWorldMatrix = m_transform.localToWorldMatrix;
return ((Matrix4x4)(ref localToWorldMatrix)).MultiplyPoint(m_boneAxis * m_length);
}
}
private Quaternion LocalRotation { get; }
private Quaternion ParentRotation => ((Object)(object)m_transform.parent != (Object)null) ? m_transform.parent.rotation : Quaternion.identity;
public SpringBoneLogic(Transform center, Transform transform, Vector3 localChildPosition)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: 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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: 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_0055: Unknown result type (might be due to invalid IL or missing references)
m_transform = transform;
Vector3 val = m_transform.TransformPoint(localChildPosition);
m_currentTail = (((Object)(object)center != (Object)null) ? center.InverseTransformPoint(val) : val);
m_prevTail = m_currentTail;
LocalRotation = transform.localRotation;
m_boneAxis = ((Vector3)(ref localChildPosition)).normalized;
m_length = ((Vector3)(ref localChildPosition)).magnitude;
}
public void Update(Transform center, float stiffnessForce, float dragForce, Vector3 external)
{
//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_000b: 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_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: 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_005d: 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_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: 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_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: 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_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)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: 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_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = (((Object)(object)center != (Object)null) ? center.TransformPoint(m_currentTail) : m_currentTail);
Vector3 val2 = (((Object)(object)center != (Object)null) ? center.TransformPoint(m_prevTail) : m_prevTail);
Vector3 val3 = val + (val - val2) * (1f - dragForce) + ParentRotation * LocalRotation * m_boneAxis * stiffnessForce + external;
Vector3 position = m_transform.position;
Vector3 val4 = val3 - position;
val3 = position + ((Vector3)(ref val4)).normalized * m_length;
m_prevTail = (((Object)(object)center != (Object)null) ? center.InverseTransformPoint(val) : val);
m_currentTail = (((Object)(object)center != (Object)null) ? center.InverseTransformPoint(val3) : val3);
m_transform.rotation = ApplyRotation(val3);
}
protected virtual Quaternion ApplyRotation(Vector3 nextTail)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
Quaternion val = ParentRotation * LocalRotation;
return Quaternion.FromToRotation(val * m_boneAxis, nextTail - m_transform.position) * val;
}
public void DrawGizmo(Transform center, Color color)
{
//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_000b: 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_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0049: 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_0057: 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)
Vector3 val = (((Object)(object)center != (Object)null) ? center.TransformPoint(m_currentTail) : m_currentTail);
Vector3 val2 = (((Object)(object)center != (Object)null) ? center.TransformPoint(m_prevTail) : m_prevTail);
Gizmos.color = Color.gray;
Gizmos.DrawLine(val, val2);
Gizmos.color = color;
Gizmos.DrawLine(val, m_transform.position);
}
}
[SerializeField]
public string m_comment;
[SerializeField]
[Header("Gizmo")]
private bool m_drawGizmo = false;
[SerializeField]
private Color m_gizmoColor = Color.yellow;
[SerializeField]
[Range(0f, 4f)]
[Header("Settings")]
public float m_stiffnessForce = 1f;
[SerializeField]
[Range(0f, 2f)]
public float m_gravityPower;
[SerializeField]
public Vector3 m_gravityDir = new Vector3(0f, -1f, 0f);
[SerializeField]
[Range(0f, 1f)]
public float m_dragForce = 0.4f;
[SerializeField]
public Transform m_center;
[SerializeField]
public List<Transform> RootBones = new List<Transform>();
private Dictionary<Transform, Quaternion> m_initialLocalRotationMap;
[SerializeField]
public SpringBoneUpdateType m_updateType = SpringBoneUpdateType.LateUpdate;
private List<SpringBoneLogic> m_verlet = new List<SpringBoneLogic>();
private void Awake()
{
Setup();
}
[ContextMenu("Reset bones")]
public void Setup(bool force = false)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
if (RootBones == null)
{
return;
}
if (force || m_initialLocalRotationMap == null)
{
m_initialLocalRotationMap = new Dictionary<Transform, Quaternion>();
}
else
{
foreach (KeyValuePair<Transform, Quaternion> item in m_initialLocalRotationMap)
{
item.Key.localRotation = item.Value;
}
m_initialLocalRotationMap.Clear();
}
m_verlet.Clear();
foreach (Transform rootBone in RootBones)
{
if ((Object)(object)rootBone != (Object)null)
{
Transform[] componentsInChildren = ((Component)((Component)rootBone).transform).GetComponentsInChildren<Transform>(true);
foreach (Transform val in componentsInChildren)
{
m_initialLocalRotationMap[val] = val.localRotation;
}
SetupRecursive(m_center, rootBone);
}
}
}
private float GetUniformedLossyScale(Transform transform)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
return Mathf.Max(Mathf.Max(transform.lossyScale.x, transform.lossyScale.y), transform.lossyScale.z);
}
private static IEnumerable<Transform> GetChildren(Transform parent)
{
int i = 0;
while (i < parent.childCount)
{
yield return parent.GetChild(i);
int num = i + 1;
i = num;
}
}
private void SetupRecursive(Transform center, Transform parent)
{
//IL_0003: 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_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_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: 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_003e: 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_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_0061: 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_006a: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: 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: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Expected O, but got Unknown
Vector3 val = default(Vector3);
Vector3 val2 = default(Vector3);
if (parent.childCount == 0)
{
Vector3 val3 = parent.position - parent.parent.position;
Vector3 val4 = parent.position + ((Vector3)(ref val3)).normalized * 0.07f * GetUniformedLossyScale(parent);
Matrix4x4 worldToLocalMatrix = parent.worldToLocalMatrix;
val = ((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint(val4);
val2 = parent.lossyScale;
}
else
{
Transform val5 = GetChildren(parent).First();
val = val5.localPosition;
val2 = val5.lossyScale;
}
m_verlet.Add(new SpringBoneLogic(center, parent, new Vector3(val.x * val2.x, val.y * val2.y, val.z * val2.z)));
foreach (Transform item in parent)
{
Transform parent2 = item;
SetupRecursive(center, parent2);
}
}
private void LateUpdate()
{
if (m_updateType == SpringBoneUpdateType.LateUpdate)
{
UpdateProcess(Time.deltaTime);
}
}
private void FixedUpdate()
{
if (m_updateType == SpringBoneUpdateType.FixedUpdate)
{
UpdateProcess(Time.fixedDeltaTime);
}
}
private void UpdateProcess(float deltaTime)
{
//IL_0041: 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_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (m_verlet == null || m_verlet.Count == 0)
{
if (RootBones == null)
{
return;
}
Setup();
}
float stiffnessForce = m_stiffnessForce * deltaTime;
Vector3 external = m_gravityDir * (m_gravityPower * deltaTime);
foreach (SpringBoneLogic item in m_verlet)
{
item.Update(m_center, stiffnessForce, m_dragForce, external);
}
}
private void OnDrawGizmos()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (!m_drawGizmo)
{
return;
}
foreach (SpringBoneLogic item in m_verlet)
{
item.DrawGizmo(m_center, m_gizmoColor);
}
}
}
public class ValheimToggleTracking : StateMachineBehaviour
{
public bool enableTracking = true;
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
PlayerModel component = ((Component)((Component)animator).transform.parent).GetComponent<PlayerModel>();
if (Object.op_Implicit((Object)(object)component))
{
component.enableTracking = enableTracking;
}
}
}
public static class Utils
{
public static void Resize<T>(this List<T> list, int sz, T c)
{
int count = list.Count;
if (sz < count)
{
list.RemoveRange(sz, count - sz);
}
else if (sz > count)
{
if (sz > list.Capacity)
{
list.Capacity = sz;
}
list.AddRange(Enumerable.Repeat(c, sz - count));
}
}
public static void Resize<T>(this List<T> list, int sz) where T : new()
{
list.Resize(sz, new T());
}
}
public enum ControlType
{
Button,
Toggle,
Slider
}
public class ValheimAvatarDescriptor : MonoBehaviour
{
public string avatarName = "player";
public Transform leftHand;
public Transform rightHand;
public Transform helmet;
public Transform backShield;
public Transform backMelee;
public Transform backTwohandedMelee;
public Transform backBow;
public Transform backTool;
public Transform backAtgeir;
public bool showHelmet;
public bool showCape;
public List<string> boolParameters;
public List<bool> boolParametersDefault;
public List<string> intParameters;
public List<int> intParametersDefault;
public List<string> floatParameters;
public List<float> floatParametersDefault;
public string[] controlName;
public ControlType[] controlTypes;
public string[] controlParameterNames;
public float[] controlValues;
private void Awake()
{
Validate();
}
public void Validate()
{
for (int i = 0; i < boolParameters.Count; i++)
{
if (!boolParameters[i].StartsWith("param_"))
{
boolParameters[i] = "param_" + boolParameters[i];
}
}
for (int j = 0; j < intParameters.Count; j++)
{
if (!intParameters[j].StartsWith("param_"))
{
intParameters[j] = "param_" + intParameters[j];
}
}
for (int k = 0; k < floatParameters.Count; k++)
{
if (!floatParameters[k].StartsWith("param_"))
{
floatParameters[k] = "param_" + floatParameters[k];
}
}
if (boolParametersDefault.Count != boolParameters.Count)
{
boolParametersDefault.Resize(boolParameters.Count);
}
if (intParametersDefault.Count != intParameters.Count)
{
intParametersDefault.Resize(intParameters.Count);
}
if (floatParametersDefault.Count != floatParameters.Count)
{
floatParametersDefault.Resize(floatParameters.Count);
}
if (controlTypes.Length != controlName.Length)
{
Array.Resize(ref controlTypes, controlName.Length);
}
if (controlParameterNames.Length != controlName.Length)
{
Array.Resize(ref controlParameterNames, controlName.Length);
}
if (controlValues.Length != controlName.Length)
{
Array.Resize(ref controlValues, controlName.Length);
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "ValheimPlayerModels";
public const string PLUGIN_NAME = "Valheim Player Models";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace ValheimPlayerModels.Loaders
{
public class AvatarInstance
{
public enum ParameterType
{
Bool,
Int,
Float
}
public class AvatarParameter
{
public ParameterType type;
public bool boolValue;
public int intValue;
public float floatValue;
}
public class MenuControl
{
public string name;
public ControlType type;
public string parameter;
public float value;
}
private PlayerModel Owner;
public GameObject AvatarObject;
public Transform Transform;
public Transform LeftFoot;
public Transform RightFoot;
public Transform Hips;
public Animator Animator;
public LODGroup lodGroup;
public ValheimAvatarDescriptor AvatarDescriptor;
public Dictionary<int, AvatarParameter> Parameters;
public List<MenuControl> MenuControls;
public AvatarInstance(PlayerModel owner)
{
Owner = owner;
}
public void SetParameterValue(string name, float value)
{
int hash = Animator.StringToHash(name);
SetParameterValue(hash, value);
}
public void SetParameterValue(int hash, float value)
{
if (Parameters.ContainsKey(hash))
{
switch (Parameters[hash].type)
{
case ParameterType.Bool:
SetBool(hash, value != 0f);
break;
case ParameterType.Int:
SetInt(hash, (int)value);
break;
case ParameterType.Float:
SetFloat(hash, value);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
public float GetParameterValue(string name)
{
int hash = Animator.StringToHash(name);
return GetParameterValue(hash);
}
public float GetParameterValue(int hash)
{
if (!Parameters.ContainsKey(hash))
{
return 0f;
}
return Parameters[hash].type switch
{
ParameterType.Bool => Parameters[hash].boolValue ? 1 : 0,
ParameterType.Int => Parameters[hash].intValue,
ParameterType.Float => Parameters[hash].floatValue,
_ => throw new ArgumentOutOfRangeException(),
};
}
public bool SetBool(string name, bool value)
{
int hash = Animator.StringToHash(name);
return SetBool(hash, value);
}
public bool SetBool(int hash, bool value)
{
if (!Parameters.ContainsKey(hash))
{
return false;
}
Parameters[hash].boolValue = value;
Animator.SetBool(hash, value);
if (Owner.zNetView.GetZDO() != null && Owner.zNetView.IsOwner())
{
Owner.zNetView.GetZDO().Set(438569 + hash, value);
}
return true;
}
public bool SetInt(string name, int value)
{
int hash = Animator.StringToHash(name);
return SetInt(hash, value);
}
public bool SetInt(int hash, int value)
{
if (!Parameters.ContainsKey(hash))
{
return false;
}
Parameters[hash].intValue = value;
Animator.SetInteger(hash, value);
if (Owner.zNetView.GetZDO() != null && Owner.zNetView.IsOwner())
{
Owner.zNetView.GetZDO().Set(438569 + hash, value, false);
}
return true;
}
public bool SetFloat(string name, float value)
{
int hash = Animator.StringToHash(name);
return SetFloat(hash, value);
}
public bool SetFloat(int hash, float value)
{
if (!Parameters.ContainsKey(hash))
{
return false;
}
Parameters[hash].floatValue = value;
Animator.SetFloat(hash, value);
if (Owner.zNetView.GetZDO() != null && Owner.zNetView.IsOwner())
{
Owner.zNetView.GetZDO().Set(438569 + hash, value);
}
return true;
}
}
public abstract class AvatarLoaderBase
{
public bool LoadedSuccessfully { get; protected set; }
public abstract IEnumerator LoadFile(string file);
public abstract AvatarInstance LoadAvatar(PlayerModel playerModel);
public abstract void Unload();
}
public class ValavtrLoader : AvatarLoaderBase
{
private AssetBundle avatarBundle;
public override IEnumerator LoadFile(string file)
{
AssetBundleCreateRequest bundleRequest = AssetBundle.LoadFromFileAsync(file);
yield return bundleRequest;
avatarBundle = bundleRequest.assetBundle;
if (!Object.op_Implicit((Object)(object)avatarBundle))
{
Plugin.Log.LogError((object)("Avatar Bundle " + file + " couldn't load!"));
base.LoadedSuccessfully = false;
}
else
{
base.LoadedSuccessfully = true;
}
}
public override AvatarInstance LoadAvatar(PlayerModel playerModel)
{
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
AvatarInstance avatarInstance = new AvatarInstance(playerModel);
GameObject val = avatarBundle.LoadAsset<GameObject>("_avatar");
if (!Object.op_Implicit((Object)(object)val))
{
Plugin.Log.LogError((object)"Couldn't find avatar prefab");
return null;
}
avatarInstance.AvatarObject = Object.Instantiate<GameObject>(val);
avatarInstance.AvatarDescriptor = avatarInstance.AvatarObject.GetComponent<ValheimAvatarDescriptor>();
avatarInstance.Animator = avatarInstance.AvatarObject.GetComponent<Animator>();
avatarInstance.Transform = avatarInstance.AvatarObject.transform;
avatarInstance.Transform.SetParent(((Component)playerModel).transform, false);
avatarInstance.LeftFoot = avatarInstance.Animator.GetBoneTransform((HumanBodyBones)5);
avatarInstance.RightFoot = avatarInstance.Animator.GetBoneTransform((HumanBodyBones)6);
avatarInstance.Hips = avatarInstance.Animator.GetBoneTransform((HumanBodyBones)0);
avatarInstance.lodGroup = avatarInstance.AvatarObject.AddComponent<LODGroup>();
Renderer[] componentsInChildren = (Renderer[])(object)avatarInstance.AvatarObject.GetComponentsInChildren<SkinnedMeshRenderer>();
LOD val2 = default(LOD);
((LOD)(ref val2))..ctor(0.1f, componentsInChildren);
avatarInstance.lodGroup.SetLODs((LOD[])(object)new LOD[1] { val2 });
avatarInstance.lodGroup.RecalculateBounds();
LODGroup component = ((Character)playerModel.player).GetVisual().GetComponent<LODGroup>();
avatarInstance.lodGroup.fadeMode = component.fadeMode;
avatarInstance.lodGroup.animateCrossFading = component.animateCrossFading;
Renderer[] componentsInChildren2 = avatarInstance.AvatarObject.GetComponentsInChildren<Renderer>();
Renderer[] array = componentsInChildren2;
foreach (Renderer val3 in array)
{
Material[] sharedMaterials = val3.sharedMaterials;
foreach (Material val4 in sharedMaterials)
{
if (Object.op_Implicit((Object)(object)val4) && ((Object)val4.shader).name == "Valheim/Standard")
{
val4.shader = Shader.Find("Custom/Player");
Texture2D val5 = (Texture2D)(val4.HasProperty("_MainTex") ? /*isinst with value type is only supported in some contexts*/: null);
Texture val6 = (val4.HasProperty("_BumpMap") ? val4.GetTexture("_BumpMap") : null);
val4.SetTexture("_MainTex", (Texture)(object)val5);
val4.SetTexture("_SkinBumpMap", val6);
val4.SetTexture("_ChestTex", (Texture)(object)val5);
val4.SetTexture("_ChestBumpMap", val6);
val4.SetTexture("_LegsTex", (Texture)(object)val5);
val4.SetTexture("_LegsBumpMap", val6);
}
}
}
avatarInstance.AvatarDescriptor.Validate();
avatarInstance.Parameters = new Dictionary<int, AvatarInstance.AvatarParameter>();
if (avatarInstance.AvatarDescriptor.boolParameters != null)
{
for (int k = 0; k < avatarInstance.AvatarDescriptor.boolParameters.Count; k++)
{
int num = Animator.StringToHash(avatarInstance.AvatarDescriptor.boolParameters[k]);
if (!avatarInstance.Parameters.ContainsKey(num))
{
avatarInstance.Parameters.Add(num, new AvatarInstance.AvatarParameter
{
type = AvatarInstance.ParameterType.Bool,
boolValue = avatarInstance.AvatarDescriptor.boolParametersDefault[k]
});
avatarInstance.Animator.SetBool(num, avatarInstance.AvatarDescriptor.boolParametersDefault[k]);
}
}
}
if (avatarInstance.AvatarDescriptor.intParameters != null)
{
for (int l = 0; l < avatarInstance.AvatarDescriptor.intParameters.Count; l++)
{
int num2 = Animator.StringToHash(avatarInstance.AvatarDescriptor.intParameters[l]);
if (!avatarInstance.Parameters.ContainsKey(num2))
{
avatarInstance.Parameters.Add(num2, new AvatarInstance.AvatarParameter
{
type = AvatarInstance.ParameterType.Int,
intValue = avatarInstance.AvatarDescriptor.intParametersDefault[l]
});
avatarInstance.Animator.SetInteger(num2, avatarInstance.AvatarDescriptor.intParametersDefault[l]);
}
}
}
if (avatarInstance.AvatarDescriptor.floatParameters != null)
{
for (int m = 0; m < avatarInstance.AvatarDescriptor.floatParameters.Count; m++)
{
int num3 = Animator.StringToHash(avatarInstance.AvatarDescriptor.floatParameters[m]);
if (!avatarInstance.Parameters.ContainsKey(num3))
{
avatarInstance.Parameters.Add(num3, new AvatarInstance.AvatarParameter
{
type = AvatarInstance.ParameterType.Float,
floatValue = avatarInstance.AvatarDescriptor.floatParametersDefault[m]
});
avatarInstance.Animator.SetFloat(num3, avatarInstance.AvatarDescriptor.floatParametersDefault[m]);
}
}
}
avatarInstance.MenuControls = new List<AvatarInstance.MenuControl>();
if (avatarInstance.AvatarDescriptor.controlName != null)
{
for (int n = 0; n < avatarInstance.AvatarDescriptor.controlName.Length; n++)
{
avatarInstance.MenuControls.Add(new AvatarInstance.MenuControl
{
name = avatarInstance.AvatarDescriptor.controlName[n],
type = avatarInstance.AvatarDescriptor.controlTypes[n],
parameter = avatarInstance.AvatarDescriptor.controlParameterNames[n],
value = avatarInstance.AvatarDescriptor.controlValues[n]
});
}
}
return avatarInstance;
}
public override void Unload()
{
if (Object.op_Implicit((Object)(object)avatarBundle))
{
avatarBundle.Unload(true);
}
}
}
public class VrmLoader : AvatarLoaderBase
{
public override IEnumerator LoadFile(string file)
{
base.LoadedSuccessfully = false;
yield break;
}
public override AvatarInstance LoadAvatar(PlayerModel playerModel)
{
return null;
}
public override void Unload()
{
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}