using System;
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 GameNetcodeStuff;
using HarmonyLib;
using LC_API.BundleAPI;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AvatarCreatures")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Custom avatars in Lethal Company.")]
[assembly: AssemblyFileVersion("0.0.6.0")]
[assembly: AssemblyInformationalVersion("0.0.6+2db75090404c8dd6b712954e21f2bdb9fcfa09ca")]
[assembly: AssemblyProduct("AvatarCreatures")]
[assembly: AssemblyTitle("AvatarCreatures")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.6.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 AvatarCreatures
{
public class AvatarCreature
{
public class CreatureController : MonoBehaviour
{
private bool isLocalPlayer = false;
private GameObject currentAvatar = null;
private Transform spineBoneForRotation = null;
private Transform chestBone = null;
private Camera thirdPersonCamera = null;
private MonoBehaviour thirdPersonComponent = null;
private ulong LOCAL_STEAM_ID = 0uL;
private bool oldValue = false;
private void Start()
{
//IL_024d: Unknown result type (might be due to invalid IL or missing references)
//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
//IL_0670: Unknown result type (might be due to invalid IL or missing references)
//IL_0677: Expected O, but got Unknown
//IL_069d: Unknown result type (might be due to invalid IL or missing references)
//IL_06ad: Unknown result type (might be due to invalid IL or missing references)
//IL_06b4: Expected O, but got Unknown
//IL_06da: Unknown result type (might be due to invalid IL or missing references)
//IL_06ea: Unknown result type (might be due to invalid IL or missing references)
//IL_06f1: Expected O, but got Unknown
//IL_0717: Unknown result type (might be due to invalid IL or missing references)
//IL_0727: Unknown result type (might be due to invalid IL or missing references)
//IL_072e: Expected O, but got Unknown
//IL_0754: Unknown result type (might be due to invalid IL or missing references)
//IL_049e: Unknown result type (might be due to invalid IL or missing references)
PlayerControllerB component = ((Component)this).gameObject.GetComponent<PlayerControllerB>();
ulong playerSteamId = component.playerSteamId;
if (((NetworkBehaviour)component).IsLocalPlayer)
{
isLocalPlayer = true;
}
Debug.Log((object)"Checking for third person mod...");
GameObject val = GameObject.Find("3rdPerson");
if ((Object)(object)val != (Object)null)
{
thirdPersonComponent = val.GetComponents<MonoBehaviour>().ElementAt(2);
}
bool flag = (Object)(object)thirdPersonComponent != (Object)null;
Debug.Log((object)("Third person mod is: " + (flag ? "Enabled" : "Not Found")));
Debug.Log((object)$"Loading model for player '{playerSteamId}'...");
string path = Path.Combine(Paths.GameRootPath, "Avatars");
string text = Path.Combine(path, playerSteamId.ToString());
string text2 = text + ".assetbundle";
AssetBundle val2 = AssetBundle.LoadFromFile(text2);
if ((Object)(object)val2 == (Object)null)
{
Debug.LogWarning((object)("Failed to load asset bundle '" + text2 + "' - does not exist, falling back to custom default"));
text2 = Path.Combine(path, "default.assetbundle");
val2 = AssetBundle.LoadFromFile(text2);
if ((Object)(object)val2 == (Object)null)
{
Debug.LogWarning((object)("Failed to load default asset bundle '" + text2 + "' - does not exist, falling back to game default"));
return;
}
}
Transform val3 = ((Component)this).gameObject.transform.Find("ScavengerModel").Find("metarig");
spineBoneForRotation = val3.Find("spine").Find("spine.001").Find("spine.002")
.Find("spine.003");
if ((Object)(object)spineBoneForRotation == (Object)null)
{
throw new Exception("ScavengerModel is missing a spine bone");
}
HideDefaultCreature();
GameObject val4 = val2.LoadAsset<GameObject>("model.fbx");
if ((Object)(object)val4 == (Object)null)
{
throw new Exception("Model fbx not found inside bundle");
}
RuntimeAnimatorController loadedAsset = BundleLoader.GetLoadedAsset<RuntimeAnimatorController>("assets/crittercontrol.controller");
if ((Object)(object)loadedAsset == (Object)null)
{
loadedAsset = BundleLoader.GetLoadedAsset<RuntimeAnimatorController>("assets/assets/crittercontrol.controller");
if ((Object)(object)loadedAsset == (Object)null)
{
throw new Exception("Could not find controller in bundle");
}
}
Debug.Log((object)"Creating avatar");
GameObject val5 = Object.Instantiate<GameObject>(val4);
val5.transform.localScale = new Vector3(1f, 1f, 1f);
Debug.Log((object)"Parenting avatar");
Transform parent = val3.Find("spine").Find("spine.001");
val5.transform.SetParent(parent);
val5.transform.localPosition = new Vector3(0f, 0f, 0f);
val5.transform.localEulerAngles = Vector3.zero;
Debug.Log((object)"Updating material");
SkinnedMeshRenderer thisPlayerModel = ((Component)this).gameObject.GetComponent<PlayerControllerB>().thisPlayerModel;
Shader shader = ((Renderer)thisPlayerModel).material.shader;
Renderer[] componentsInChildren = val5.GetComponentsInChildren<Renderer>();
Renderer[] array = componentsInChildren;
foreach (Renderer val6 in array)
{
string name = ((Object)((Component)val6).gameObject).name;
Debug.Log((object)$"Updating {val6.materials.Length} materials for renderer '{name}'");
int num = 0;
Material[] materials = val6.materials;
foreach (Material val7 in materials)
{
Debug.Log((object)$"Applying textures to material #{num} - '{((Object)val7).name}'");
val7.shader = shader;
val7.EnableKeyword("_EMISSION");
val7.EnableKeyword("_SPECGLOSSMAP");
val7.EnableKeyword("_NORMALMAP");
string text3 = $"{name}_{num}_Albedo.png";
Texture val8 = val2.LoadAsset<Texture>(text3);
Texture val9 = val2.LoadAsset<Texture>($"{name}_{num}_Smoothness.png");
Texture val10 = val2.LoadAsset<Texture>($"{name}_{num}_Emission.png");
Texture val11 = val2.LoadAsset<Texture>($"{name}_{num}_Normal.png");
if ((Object)(object)val8 == (Object)null)
{
throw new Exception("Could not find asset '" + text3 + "' in asset bundle");
}
val7.SetTexture("_BaseColorMap", val8);
val7.SetTexture("_SpecularColorMap", val9);
val7.SetFloat("_Smoothness", 0.3f);
val7.SetTexture("_EmissiveColorMap", val10);
val7.SetTexture("_BumpMap", val11);
if ((Object)(object)val10 != (Object)null)
{
val7.SetColor("_EmissiveColor", Color.white);
}
HDMaterial.ValidateMaterial(val7);
num++;
}
}
Animator componentInChildren = val5.GetComponentInChildren<Animator>();
Debug.Log((object)"Storing chest bone");
chestBone = componentInChildren.GetBoneTransform((HumanBodyBones)8);
if ((Object)(object)chestBone == (Object)null)
{
chestBone = componentInChildren.GetBoneTransform((HumanBodyBones)7);
if ((Object)(object)chestBone == (Object)null)
{
throw new Exception("Avatar is missing a chest or spine bone");
}
}
Debug.Log((object)"Inserting controller");
componentInChildren.runtimeAnimatorController = loadedAsset;
Debug.Log((object)"Setting up IK");
IKController iKController = val5.AddComponent<IKController>();
Transform val12 = val3.Find("spine").Find("thigh.L");
Transform val13 = val3.Find("spine").Find("thigh.R");
Transform val14 = val12.Find("shin.L");
Transform val15 = val13.Find("shin.R");
Transform val16 = val14.Find("foot.L");
Transform val17 = val15.Find("foot.R");
Transform val18 = val3.Find("spine").Find("spine.001").Find("spine.002")
.Find("spine.003");
Transform val19 = val18.Find("shoulder.L");
Transform val20 = val18.Find("shoulder.R");
Transform val21 = val19.Find("arm.L_upper");
Transform val22 = val20.Find("arm.R_upper");
Transform val23 = val21.Find("arm.L_lower");
Transform val24 = val22.Find("arm.R_lower");
Transform val25 = val23.Find("hand.L");
Transform val26 = val24.Find("hand.R");
GameObject val27 = new GameObject("IK Offset");
val27.transform.SetParent(val16, false);
val27.transform.localPosition = new Vector3(0f, -0.1f, 0f);
GameObject val28 = new GameObject("IK Offset");
val28.transform.SetParent(val17, false);
val28.transform.localPosition = new Vector3(0f, -0.1f, 0f);
GameObject val29 = new GameObject("IK Offset");
val29.transform.SetParent(val25, false);
val29.transform.localPosition = new Vector3(0.05f, 0f, 0f);
GameObject val30 = new GameObject("IK Offset");
val30.transform.SetParent(val26, false);
val30.transform.localPosition = new Vector3(-0.05f, 0f, 0f);
iKController.leftLegTarget = val27.transform;
iKController.rightLegTarget = val28.transform;
iKController.leftHandTarget = val29.transform;
iKController.rightHandTarget = val30.transform;
iKController.ikActive = true;
Debug.Log((object)"IK set up");
val2.Unload(false);
Debug.Log((object)"Avatar has been loaded");
currentAvatar = val5;
}
private void LateUpdate()
{
//IL_004b: 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)
if ((Object)(object)currentAvatar != (Object)null && (Object)(object)chestBone != (Object)null && (Object)(object)spineBoneForRotation != (Object)null)
{
currentAvatar.transform.localPosition = new Vector3(0f, -0.15f, 0f);
chestBone.localEulerAngles = spineBoneForRotation.localEulerAngles;
}
}
private void HideDefaultCreature()
{
((Component)this).gameObject.GetComponentInChildren<LODGroup>().enabled = false;
SkinnedMeshRenderer[] componentsInChildren = ((Component)this).gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
SkinnedMeshRenderer[] array = componentsInChildren;
foreach (SkinnedMeshRenderer val in array)
{
((Renderer)val).enabled = false;
}
}
}
}
public class IKController : MonoBehaviour
{
protected Animator animator;
public bool ikActive = false;
public Transform leftLegTarget = null;
public Transform rightLegTarget = null;
public Transform leftHandTarget = null;
public Transform rightHandTarget = null;
private void Start()
{
animator = ((Component)this).GetComponent<Animator>();
}
private void OnAnimatorIK()
{
//IL_0052: 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_00a6: 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_00fc: 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_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)animator))
{
return;
}
if (ikActive)
{
if ((Object)(object)leftLegTarget != (Object)null)
{
animator.SetIKPositionWeight((AvatarIKGoal)0, 1f);
animator.SetIKPosition((AvatarIKGoal)0, leftLegTarget.position);
animator.SetIKRotation((AvatarIKGoal)0, leftLegTarget.rotation);
}
if ((Object)(object)rightLegTarget != (Object)null)
{
animator.SetIKPositionWeight((AvatarIKGoal)1, 1f);
animator.SetIKPosition((AvatarIKGoal)1, rightLegTarget.position);
animator.SetIKRotation((AvatarIKGoal)1, rightLegTarget.rotation);
}
if ((Object)(object)leftHandTarget != (Object)null)
{
animator.SetIKPositionWeight((AvatarIKGoal)2, 1f);
animator.SetIKPosition((AvatarIKGoal)2, leftHandTarget.position);
animator.SetIKRotation((AvatarIKGoal)2, leftHandTarget.rotation);
}
if ((Object)(object)rightHandTarget != (Object)null)
{
animator.SetIKPositionWeight((AvatarIKGoal)3, 1f);
animator.SetIKPosition((AvatarIKGoal)3, rightHandTarget.position);
animator.SetIKRotation((AvatarIKGoal)3, rightHandTarget.rotation);
}
}
else
{
animator.SetIKPositionWeight((AvatarIKGoal)0, 0f);
animator.SetIKRotationWeight((AvatarIKGoal)0, 0f);
animator.SetIKPositionWeight((AvatarIKGoal)1, 0f);
animator.SetIKRotationWeight((AvatarIKGoal)1, 0f);
animator.SetIKPositionWeight((AvatarIKGoal)2, 0f);
animator.SetIKRotationWeight((AvatarIKGoal)2, 0f);
animator.SetIKPositionWeight((AvatarIKGoal)3, 0f);
animator.SetIKRotationWeight((AvatarIKGoal)3, 0f);
}
}
}
[BepInPlugin("AvatarCreatures", "AvatarCreatures", "0.0.6")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public static Harmony _harmony;
public static ConfigEntry<bool> configAlwaysRenderLocalPlayerModel;
private void Awake()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
configAlwaysRenderLocalPlayerModel = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AlwaysRenderLocalPlayerModel", false, "If to always render the local player model. Useful for testing with 3rd person mods.");
_harmony = new Harmony("AvatarCreatures");
_harmony.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"AvatarCreatures loaded");
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "AvatarCreatures";
public const string PLUGIN_NAME = "AvatarCreatures";
public const string PLUGIN_VERSION = "0.0.6";
}
}
namespace AvatarCreatures.Patches
{
[HarmonyPatch]
internal class PlayerObjects
{
public static void InitModels()
{
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
PlayerControllerB[] array = Object.FindObjectsOfType<PlayerControllerB>();
bool value = Plugin.configAlwaysRenderLocalPlayerModel.Value;
Debug.Log((object)("Always render local player model: " + (value ? "Yes" : "No")));
PlayerControllerB[] array2 = array;
foreach (PlayerControllerB val in array2)
{
if (((Object)(object)val == (Object)(object)localPlayerController || val.playerSteamId == 0L) && !value)
{
Debug.Log((object)$"Ignoring local player (steam ID {val.playerSteamId})");
continue;
}
AvatarCreature.CreatureController[] componentsInChildren = ((Component)val).gameObject.GetComponentsInChildren<AvatarCreature.CreatureController>();
if (componentsInChildren.Length != 0)
{
Debug.Log((object)$"Steam ID {val.playerSteamId} already has creature, skipping");
continue;
}
Debug.Log((object)$"Adding creature to steam ID {val.playerSteamId}...");
((Component)val).gameObject.AddComponent<AvatarCreature.CreatureController>();
}
}
[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
[HarmonyPostfix]
public static void InitModel(ref PlayerControllerB __instance)
{
InitModels();
}
[HarmonyPatch(typeof(PlayerControllerB), "DisablePlayerModel")]
[HarmonyPostfix]
public static void DisablePlayerModel(ref PlayerControllerB __instance, GameObject playerObject)
{
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
if ((Object)(object)playerObject == (Object)(object)localPlayerController)
{
return;
}
playerObject.gameObject.GetComponentInChildren<LODGroup>().enabled = false;
SkinnedMeshRenderer[] componentsInChildren = playerObject.gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
SkinnedMeshRenderer[] array = componentsInChildren;
foreach (SkinnedMeshRenderer val in array)
{
if (!(((Object)val).name == "Body"))
{
((Renderer)val).enabled = false;
}
}
}
}
[HarmonyPatch(typeof(UnlockableSuit))]
internal class UnlockableSuitPatch
{
[HarmonyPatch("SwitchSuitForPlayer")]
[HarmonyPrefix]
private static void SwitchSuitForPlayerPatch(PlayerControllerB player, int suitID, bool playAudio = true)
{
}
}
}