using System; using System.Collections.Generic; using System.Diagnostics; 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 Photon.Pun; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FellowDroid { internal static class Cfg { public static ConfigEntry Enabled; public static ConfigEntry CopyNameTag; public static ConfigEntry KeepDisguiseAfterTransform; public static ConfigEntry Scale; public static void Bind(ConfigFile c) { Enabled = c.Bind("General", "Enabled", true, "Master switch for the whole mod. Off means the droid stays exactly as Wesleys Enemies made it."); CopyNameTag = c.Bind("General", "CopyNameTag", true, "Show the stolen player name above the droid, exactly the way real player names show up. Turn it off if a fake name feels like too much."); KeepDisguiseAfterTransform = c.Bind("General", "KeepDisguiseAfterTransform", true, "Keep the stolen look after the droid turns into its second form. On by default: the copied outfit is not visible on that form anyway, but the copied colours are, and the creature staying the player's colour reads better than it snapping back to a stock one. Turn it off for a completely plain fight."); Scale = c.Bind("General", "Scale", 1f, "Size correction for the copied cosmetics. The droid rig matches the player rig, so 1.0 should be right; raise or lower it only if things sit visibly too big or too small."); } } internal class Disguise : MonoBehaviour { private static readonly List UsedThisLevel = new List(); private static object lastLevel; private static Transform holder; private const string DecorationFolder = "HeadDecorations"; private const string WorldFollower = "WorldDecorationFollower"; private static int albedoId; private static int emissionId; private static int fresnelId; private static bool shaderIdsReady; private readonly List spawned = new List(); private readonly List created = new List(); private readonly List tinted = new List(); private readonly List tintedWas = new List(); private readonly List hiddenParts = new List(); private Transform worldAnchor; private NameTag nameTag; private Component droid; private PhotonView view; private static readonly string[] BodyParts = new string[12] { "head_top", "head_bot", "body_top", "body_bot", "arm_l", "arm_r", "leg_l", "leg_r", "eye_l", "eye_r", "pupil_l", "pupil_r" }; internal static void OnDroidSpawn(Component lostDroid) { if ((Object)(object)lostDroid == (Object)null) { return; } Disguise disguise = lostDroid.GetComponent(); if ((Object)(object)disguise == (Object)null) { disguise = lostDroid.gameObject.AddComponent(); disguise.droid = lostDroid; disguise.view = lostDroid.GetComponent(); if ((Object)(object)disguise.view != (Object)null) { disguise.view.RefreshRpcMonoBehaviourCache(); } } disguise.TakeOff(); if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } EnsureLevel(); int num = ChooseVictim(); if (num < 0) { Plugin.Log.LogInfo((object)"Fellow Droid: некого копировать, дроид остался обычным."); return; } UsedThisLevel.Add(num); if (SemiFunc.IsMultiplayer() && (Object)(object)disguise.view != (Object)null) { disguise.view.RPC("FellowDroidWearRPC", (RpcTarget)0, new object[1] { num }); } else { disguise.WearRPC(num); } } internal static void OnDroidTransform(Component lostDroid) { if (!((Object)(object)lostDroid == (Object)null) && !Cfg.KeepDisguiseAfterTransform.Value) { Disguise component = lostDroid.GetComponent(); if ((Object)(object)component != (Object)null) { component.TakeOff(); } } } private void OnDestroy() { TakeOff(); } private static void EnsureLevel() { object instance = LevelGenerator.Instance; if (instance != lastLevel) { UsedThisLevel.Clear(); lastLevel = instance; } } private static int ChooseVictim() { GameDirector instance = GameDirector.instance; if ((Object)(object)instance == (Object)null || instance.PlayerList == null) { return -1; } List list = new List(); List list2 = new List(); foreach (PlayerAvatar player in instance.PlayerList) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player.photonView == (Object)null)) { int viewID = player.photonView.ViewID; list.Add(viewID); if (!player.isDisabled) { list2.Add(viewID); } } } return Victims.Pick(list2, list, UsedThisLevel, (int count) => Random.Range(0, count)); } private static PlayerAvatar FindPlayer(int viewId) { GameDirector instance = GameDirector.instance; if ((Object)(object)instance == (Object)null || instance.PlayerList == null) { return null; } foreach (PlayerAvatar player in instance.PlayerList) { if ((Object)(object)player != (Object)null && (Object)(object)player.photonView != (Object)null && player.photonView.ViewID == viewId) { return player; } } return null; } [PunRPC] private void FellowDroidWearRPC(int viewId) { WearRPC(viewId); } private void WearRPC(int viewId) { PlayerAvatar val = FindPlayer(viewId); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Fellow Droid: игрок " + viewId + " не найден, маскировки не будет.")); } else { Wear(val); } } private void Wear(PlayerAvatar victim) { TakeOff(); if ((Object)(object)victim.playerAvatarVisuals == (Object)null || (Object)(object)victim.playerCosmetics == (Object)null) { return; } if ((Object)(object)GameplayManager.instance != (Object)null && !GameplayManager.instance.cosmetics) { Plugin.Log.LogInfo((object)"Fellow Droid: в лобби выключена косметика, дроид остался обычным."); return; } Transform transform = ((Component)victim.playerAvatarVisuals).transform; Transform val = RigRoot(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Fellow Droid: у дроида не нашёлся узел [RIG], маскировки не будет."); return; } EnsureShaderIds(); HideSameParts(transform, val); List cosmeticEquipped = victim.playerCosmetics.cosmeticEquipped; if (cosmeticEquipped != null) { foreach (Cosmetic item in cosmeticEquipped) { if (!((Object)(object)item == (Object)null)) { if (!((Component)item).gameObject.activeInHierarchy) { Plugin.Log.LogInfo((object)("Fellow Droid: вещь \"" + ((Object)item).name + "\" на игроке выключена, пропускаем.")); } else { TryWear(((Component)item).transform, null, transform, val, victim); } } } } WearDecorations(transform, val, victim); Recolor(victim); WearNameTag(victim, transform, val); Plugin.Log.LogInfo((object)("Fellow Droid: дроид надел " + spawned.Count + " вещей игрока " + victim.playerName + ".")); } private void WearNameTag(PlayerAvatar victim, Transform sourceRoot, Transform targetRoot) { if (!Cfg.CopyNameTag.Value) { return; } Transform val = null; if ((Object)(object)victim.playerAvatarVisuals != (Object)null) { val = RigMirror.Mirror(sourceRoot, targetRoot, victim.playerAvatarVisuals.headLookAtTransform, created); } if ((Object)(object)val == (Object)null) { val = targetRoot; Transform[] componentsInChildren = ((Component)targetRoot).GetComponentsInChildren(true); foreach (Transform val2 in componentsInChildren) { if (((Object)val2).name == "code_head_top") { val = val2; break; } } } nameTag = NameTag.Create(victim.playerName, val, ((Component)this).GetComponentInParent()); if ((Object)(object)nameTag == (Object)null) { Plugin.Log.LogWarning((object)"Fellow Droid: подпись над головой создать не вышло."); } } private void HideSameParts(Transform sourceRoot, Transform targetRoot) { List list = new List(); List list2 = new List(); Renderer[] componentsInChildren = ((Component)sourceRoot).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { string text = BodyPart(((Object)val).name); if (text != null) { if (!list.Contains(text)) { list.Add(text); } if (val.enabled && ((Component)val).gameObject.activeInHierarchy && !list2.Contains(text)) { list2.Add(text); } } } componentsInChildren = ((Component)targetRoot).GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { string text2 = BodyPart(((Object)val2).name); if (text2 != null && val2.enabled && list.Contains(text2) && !list2.Contains(text2)) { val2.enabled = false; hiddenParts.Add(val2); } } } private static string BodyPart(string meshName) { if (meshName == null || !meshName.StartsWith("mesh_")) { return null; } string text = meshName.Substring("mesh_".Length); if (text.EndsWith("_sphere")) { text = text.Substring(0, text.Length - "_sphere".Length); } else if (text.EndsWith("_flat")) { text = text.Substring(0, text.Length - "_flat".Length); } string[] bodyParts = BodyParts; foreach (string text2 in bodyParts) { if (text == text2) { return text; } } return null; } private void WearDecorations(Transform sourceRoot, Transform targetRoot, PlayerAvatar victim) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown Transform[] componentsInChildren = ((Component)sourceRoot).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name != "HeadDecorations") { continue; } bool flag = InWorldSpace(val); foreach (Transform item in val) { Transform val2 = item; if (flag ? ((Component)val2).gameObject.activeSelf : ((Component)val2).gameObject.activeInHierarchy) { Transform parent = (flag ? WorldAnchorOn(targetRoot) : null); TryWear(val2, parent, sourceRoot, targetRoot, victim); } } } } private Transform WorldAnchorOn(Transform targetRoot) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0033: 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_0053: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)worldAnchor != (Object)null) { return worldAnchor; } GameObject val = new GameObject("FellowDroidWorldDecorations"); val.transform.SetParent(targetRoot, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; val.AddComponent().Root = targetRoot; created.Add(val); worldAnchor = val.transform; return worldAnchor; } private static bool InWorldSpace(Transform node) { Transform val = node; while ((Object)(object)val != (Object)null) { if (((Object)val).name == "WorldDecorationFollower") { return true; } val = val.parent; } return false; } private void TryWear(Transform source, Transform parent, Transform sourceRoot, Transform targetRoot, PlayerAvatar victim) { try { if ((Object)(object)parent == (Object)null) { parent = RigMirror.Mirror(sourceRoot, targetRoot, source.parent, created); if ((Object)(object)parent == (Object)null) { Plugin.Log.LogWarning((object)("Fellow Droid: вещи \"" + ((Object)source).name + "\" не нашлось места на дроиде (на игроке она висит на " + (((Object)(object)source.parent == (Object)null) ? "null" : ((Object)source.parent).name) + ").")); return; } } Attach(source, parent, sourceRoot, targetRoot, victim); } catch (Exception ex) { Plugin.Log.LogError((object)("Fellow Droid: вещь \"" + ((Object)source).name + "\" надеть не вышло: " + ex)); } } private Transform RigRoot() { EnemyParent componentInParent = ((Component)this).GetComponentInParent(); Transform[] componentsInChildren = ((Component)(((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).transform : ((Component)this).transform)).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == "[RIG]") { return val.parent; } } return null; } private void Attach(Transform source, Transform parent, Transform sourceRoot, Transform targetRoot, PlayerAvatar victim) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(((Component)source).gameObject, Holder()); ((Object)val).name = ((Object)source).name; Strip(val); RemapBones(val, sourceRoot, targetRoot); Tint(val, victim); val.transform.SetParent(parent, false); val.transform.localPosition = source.localPosition; val.transform.localRotation = source.localRotation; val.transform.localScale = source.localScale * Cfg.Scale.Value; SetLayer(val, DroidLayer()); MatchLighting(val); spawned.Add(val); } private int DroidLayer() { Renderer[] array = Patches.RenderersOf(droid); if (array != null) { Renderer[] array2 = array; foreach (Renderer val in array2) { if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject.layer; } } } return ((Component)this).gameObject.layer; } private void MatchLighting(GameObject clone) { //IL_006f: 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_0089: Unknown result type (might be due to invalid IL or missing references) Renderer val = null; Renderer[] array = Patches.RenderersOf(droid); Renderer[] array2; if (array != null) { array2 = array; foreach (Renderer val2 in array2) { if ((Object)(object)val2 != (Object)null) { val = val2; break; } } } array2 = clone.GetComponentsInChildren(true); foreach (Renderer val3 in array2) { val3.SetPropertyBlock((MaterialPropertyBlock)null); val3.probeAnchor = null; if (!((Object)(object)val == (Object)null)) { val3.renderingLayerMask = val.renderingLayerMask; val3.lightProbeUsage = val.lightProbeUsage; val3.reflectionProbeUsage = val.reflectionProbeUsage; val3.shadowCastingMode = val.shadowCastingMode; val3.receiveShadows = val.receiveShadows; } } } private static void SetLayer(GameObject go, int layer) { Transform[] componentsInChildren = go.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = layer; } } private static Transform Holder() { //IL_0012: 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_001e: 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_002c: Expected O, but got Unknown if ((Object)(object)holder == (Object)null) { GameObject val = new GameObject("FellowDroidHolder"); val.SetActive(false); ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)val); holder = val.transform; } return holder; } private static void Strip(GameObject clone) { Collider[] componentsInChildren = clone.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } MonoBehaviour[] componentsInChildren2 = clone.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren2) { if (!((Object)(object)val == (Object)null) && !(val is PlayerMaterial)) { Object.DestroyImmediate((Object)(object)val); } } } private void RemapBones(GameObject clone, Transform sourceRoot, Transform targetRoot) { SkinnedMeshRenderer[] componentsInChildren = clone.GetComponentsInChildren(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { Transform[] bones = val.bones; bool flag = false; for (int j = 0; j < bones.Length; j++) { Transform val2 = bones[j]; if (!((Object)(object)val2 == (Object)null) && !val2.IsChildOf(clone.transform)) { Transform val3 = RigMirror.Mirror(sourceRoot, targetRoot, val2, created); if ((Object)(object)val3 != (Object)null) { bones[j] = val3; flag = true; } } } if (flag) { val.bones = bones; } Transform rootBone = val.rootBone; if ((Object)(object)rootBone != (Object)null && !rootBone.IsChildOf(clone.transform)) { Transform val4 = RigMirror.Mirror(sourceRoot, targetRoot, rootBone, created); if ((Object)(object)val4 != (Object)null) { val.rootBone = val4; } } } } private static void Tint(GameObject clone, PlayerAvatar victim) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected I4, but got Unknown int[] colorsEquipped = victim.playerCosmetics.colorsEquipped; PlayerMaterial[] componentsInChildren = clone.GetComponentsInChildren(true); foreach (PlayerMaterial val in componentsInChildren) { if (!((Object)(object)((Component)val).GetComponent() == (Object)null)) { val.Setup(); int num = (int)val.cosmeticType; int index = ((colorsEquipped != null && num >= 0 && num < colorsEquipped.Length) ? colorsEquipped[num] : 0); val.ColorSet(albedoId, emissionId, fresnelId, SafeColor(index)); } } } private void Recolor(PlayerAvatar victim) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected I4, but got Unknown //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_0087: 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_00a1: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) Renderer[] array = Patches.RenderersOf(droid); if (array == null) { return; } int[] colorsEquipped = victim.playerCosmetics.colorsEquipped; Renderer[] array2 = array; foreach (Renderer val in array2) { if (!((Object)(object)val == (Object)null)) { int num = (int)SlotFor(((Object)val).name); int index = ((colorsEquipped != null && num >= 0 && num < colorsEquipped.Length) ? colorsEquipped[num] : 0); Color color = MetaManager.instance.colors[SafeColor(index)].color; Material material = val.material; Color color2 = material.GetColor(albedoId); tinted.Add(val); tintedWas.Add(color2); material.SetColor(albedoId, new Color(color.r, color.g, color.b, color2.a)); } } } private static CosmeticType SlotFor(string meshName) { return (CosmeticType)(BodyPart(meshName) switch { "head_top" => 5, "head_bot" => 6, "body_top" => 7, "body_bot" => 8, "arm_l" => 10, "arm_r" => 9, "leg_l" => 12, "leg_r" => 11, _ => 7, }); } private static int SafeColor(int index) { MetaManager instance = MetaManager.instance; if ((Object)(object)instance == (Object)null || instance.colors == null || instance.colors.Count == 0) { return 0; } if (index < 0 || index >= instance.colors.Count) { return 0; } return index; } private static void EnsureShaderIds() { if (!shaderIdsReady) { albedoId = Shader.PropertyToID("_AlbedoColor"); emissionId = Shader.PropertyToID("_EmissionColor"); fresnelId = Shader.PropertyToID("_FresnelColor"); shaderIdsReady = true; } } private void TakeOff() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) for (int num = spawned.Count - 1; num >= 0; num--) { if ((Object)(object)spawned[num] != (Object)null) { Object.Destroy((Object)(object)spawned[num]); } } spawned.Clear(); for (int num2 = created.Count - 1; num2 >= 0; num2--) { if ((Object)(object)created[num2] != (Object)null) { Object.Destroy((Object)(object)created[num2]); } } created.Clear(); for (int i = 0; i < tinted.Count; i++) { if ((Object)(object)tinted[i] != (Object)null) { tinted[i].material.SetColor(albedoId, tintedWas[i]); } } tinted.Clear(); tintedWas.Clear(); for (int j = 0; j < hiddenParts.Count; j++) { if ((Object)(object)hiddenParts[j] != (Object)null) { hiddenParts[j].enabled = true; } } hiddenParts.Clear(); worldAnchor = null; if ((Object)(object)nameTag != (Object)null) { Object.Destroy((Object)(object)((Component)nameTag).gameObject); } nameTag = null; } } internal class NameTag : MonoBehaviour { private const float ViewDistance = 15f; private const float ViewRadius = 0.25f; private const float ShowTime = 0.5f; private const float CheckEvery = 0.25f; private const float HeadOffset = 0.35f; private RectTransform rect; private TextMeshProUGUI text; private Transform head; private EnemyParent owner; private Vector3 followTarget; private float showTimer; private float checkTimer; internal static NameTag Create(string playerName, Transform head, EnemyParent owner) { //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_00be: Unknown result type (might be due to invalid IL or missing references) WorldSpaceUIParent instance = WorldSpaceUIParent.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerNamePrefab == (Object)null || (Object)(object)head == (Object)null) { return null; } GameObject val = Object.Instantiate(instance.playerNamePrefab, ((Component)instance).transform); WorldSpaceUIPlayerName component = val.GetComponent(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } NameTag nameTag = val.AddComponent(); nameTag.rect = val.GetComponent(); nameTag.text = val.GetComponentInChildren(true); nameTag.head = head; nameTag.owner = owner; nameTag.followTarget = head.position; if ((Object)(object)nameTag.text != (Object)null) { ((TMP_Text)nameTag.text).text = playerName; ((Graphic)nameTag.text).color = new Color(1f, 1f, 1f, 0f); } return nameTag; } private void LateUpdate() { //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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_0122: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //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_0148: 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)head == (Object)null || (Object)(object)rect == (Object)null || (Object)(object)text == (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } if (Allowed()) { checkTimer -= Time.deltaTime; if (checkTimer <= 0f) { checkTimer = 0.25f; if (LookedAt()) { showTimer = 0.5f; } } } else { showTimer = 0f; } bool flag = showTimer > 0f; Color val = default(Color); ((Color)(ref val))..ctor(1f, 1f, 1f, flag ? 0.5f : 0f); ((Graphic)text).color = Color.Lerp(((Graphic)text).color, val, Time.deltaTime * (flag ? 5f : 20f)); if (flag) { showTimer -= Time.deltaTime; } followTarget = Vector3.Lerp(followTarget, head.position, Time.deltaTime * 30f); Vector3 val2 = followTarget + Vector3.up * 0.35f; rect.anchoredPosition = Vector2.op_Implicit(SemiFunc.UIWorldToCanvasPosition(val2)); Camera main = Camera.main; if ((Object)(object)main != (Object)null) { ((TMP_Text)text).fontSize = 20f - Vector3.Distance(val2, ((Component)main).transform.position); } } private static bool Allowed() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if ((Object)(object)GameDirector.instance == (Object)null || (int)GameDirector.instance.currentState != 2) { return false; } if ((Object)(object)Map.Instance != (Object)null && Map.Instance.Active) { return false; } if ((Object)(object)GameplayManager.instance == (Object)null || !GameplayManager.instance.playerNames) { return false; } if ((Object)(object)SpectateCamera.instance != (Object)null) { return false; } return true; } private bool LookedAt() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0073: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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) Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return false; } Vector3 position = ((Component)main).transform.position; RaycastHit[] array = Physics.SphereCastAll(position, 0.25f, ((Component)main).transform.forward, 15f, -1, (QueryTriggerInteraction)2); RaycastHit val3 = default(RaycastHit); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent() != (Object)(object)owner)) { int num = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()) - LayerMask.GetMask(new string[1] { "Player" }); Vector3 val2 = position - ((RaycastHit)(ref val)).point; if (!Physics.Raycast(((RaycastHit)(ref val)).point, val2, ref val3, ((Vector3)(ref val2)).magnitude, num, (QueryTriggerInteraction)2)) { return true; } } } return false; } } internal static class Patches { private const string TypeName = "WesleysEnemies.AI.LostDroid"; private static FieldInfo renderersField; internal static bool TryPatch(Harmony harmony) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown Type type = AccessTools.TypeByName("WesleysEnemies.AI.LostDroid"); if (type == null) { return false; } MethodInfo methodInfo = AccessTools.Method(type, "PickRandomVariantRPC", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "TransformImpulseRPC", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { Plugin.Log.LogWarning((object)"Fellow Droid: в WesleysEnemies.AI.LostDroid не нашлись PickRandomVariantRPC или TransformImpulseRPC. Похоже, чужой мод обновился и переименовал их."); return false; } renderersField = AccessTools.Field(type, "renderers"); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Patches), "AfterPickVariant", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Patches), "AfterTransformImpulse", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); return true; } internal static Renderer[] RenderersOf(Component lostDroid) { if (renderersField == null || (Object)(object)lostDroid == (Object)null) { return null; } return renderersField.GetValue(lostDroid) as Renderer[]; } private static void AfterPickVariant(object __instance) { try { Disguise.OnDroidSpawn((Component)((__instance is Component) ? __instance : null)); } catch (Exception ex) { Plugin.Log.LogError((object)("Fellow Droid: не удалось надеть маскировку: " + ex)); } } private static void AfterTransformImpulse(object __instance) { try { Disguise.OnDroidTransform((Component)((__instance is Component) ? __instance : null)); } catch (Exception ex) { Plugin.Log.LogError((object)("Fellow Droid: не удалось снять маскировку: " + ex)); } } } [BepInPlugin("sweet.fellowdroid", "Fellow Droid", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "sweet.fellowdroid"; public const string Name = "Fellow Droid"; public const string Version = "1.0.1"; internal static ManualLogSource Log; private static Harmony harmony; private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Cfg.Bind(((BaseUnityPlugin)this).Config); if (!Cfg.Enabled.Value) { Log.LogInfo((object)"Fellow Droid disabled in config, patches not applied."); return; } harmony = new Harmony("sweet.fellowdroid"); if (!Patches.TryPatch(harmony)) { Log.LogWarning((object)"Fellow Droid: мод Wesleys Enemies не найден, делать нечего."); } else { Log.LogInfo((object)"Fellow Droid 1.0.1 loaded."); } } } internal static class RigMirror { internal static string Path(Transform root, Transform node) { if ((Object)(object)root == (Object)null || (Object)(object)node == (Object)null) { return null; } List list = new List(); Transform val = node; while ((Object)(object)val != (Object)(object)root) { if ((Object)(object)val == (Object)null) { return null; } list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list.ToArray()); } internal static Transform Mirror(Transform sourceRoot, Transform targetRoot, Transform sourceNode, List created) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)sourceRoot == (Object)null || (Object)(object)targetRoot == (Object)null || (Object)(object)sourceNode == (Object)null) { return null; } if ((Object)(object)sourceNode == (Object)(object)sourceRoot) { return targetRoot; } List list = new List(); Transform val = sourceNode; while ((Object)(object)val != (Object)(object)sourceRoot) { if ((Object)(object)val == (Object)null) { return null; } list.Add(val); val = val.parent; } list.Reverse(); Transform val2 = targetRoot; for (int i = 0; i < list.Count; i++) { Transform val3 = list[i]; Transform val4 = ChildAt(val2, ((Object)val3).name, Occurrence(val3)); if ((Object)(object)val4 == (Object)null && i + 1 < list.Count) { Transform val5 = list[i + 1]; if ((Object)(object)ChildAt(val2, ((Object)val5).name, Occurrence(val5)) != (Object)null) { continue; } } if ((Object)(object)val4 == (Object)null) { GameObject val6 = new GameObject(((Object)val3).name); val4 = val6.transform; val4.SetParent(val2, false); val4.localPosition = val3.localPosition; val4.localRotation = val3.localRotation; val4.localScale = val3.localScale; created?.Add(val6); } val2 = val4; } return val2; } private static int Occurrence(Transform node) { Transform parent = node.parent; if ((Object)(object)parent == (Object)null) { return 0; } int num = 0; for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if ((Object)(object)child == (Object)(object)node) { return num; } if (((Object)child).name == ((Object)node).name) { num++; } } return num; } private static Transform ChildAt(Transform parent, string name, int occurrence) { int num = 0; for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if (!(((Object)child).name != name)) { if (num == occurrence) { return child; } num++; } } return null; } } internal static class Victims { internal static int Pick(IList alive, IList all, ICollection used, Func roll) { List list = Free(alive, used); if (list.Count == 0) { list = Copy(alive); } if (list.Count == 0) { list = Free(all, used); } if (list.Count == 0) { list = Copy(all); } if (list.Count == 0) { return -1; } int num = roll(list.Count); if (num < 0) { num = 0; } if (num >= list.Count) { num = list.Count - 1; } return list[num]; } private static List Free(IList from, ICollection used) { List list = new List(); if (from == null) { return list; } foreach (int item in from) { if (used == null || !used.Contains(item)) { list.Add(item); } } return list; } private static List Copy(IList from) { if (from != null) { return new List(from); } return new List(); } } internal class WorldAnchor : MonoBehaviour { internal Transform Root; private void LateUpdate() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) if ((Object)(object)Root == (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } ((Component)this).transform.position = Root.position; ((Component)this).transform.rotation = Quaternion.Euler(0f, Root.eulerAngles.y, 0f); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }