using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using FistVR; using HarmonyLib; using OtherLoader; using Packer.LootCompanion; using UnityEngine; using UnityEngine.AI; using UnityEngine.UI; [assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] public class DigitalClock : MonoBehaviour { private Text textClock; private void Awake() { textClock = ((Component)this).GetComponent(); } private void Update() { DateTime now = DateTime.Now; string text = LeadingZero(now.Hour); string text2 = LeadingZero(now.Minute); string text3 = LeadingZero(now.Second); textClock.text = text + ":" + text2 + ":" + text3; } private string LeadingZero(int n) { return n.ToString().PadLeft(2, '0'); } } public class RandomPhoneRing : MonoBehaviour { [Header("Phone Behavior")] public AudioSource audioSource; public List ringClips; public List speechClips; public AudioClip phoneTone; public float minRingInterval = 5f; public float maxRingInterval = 15f; public float ringDuration = 10f; public float speechStartDelay = 2f; public float ringCooldown = 20f; [Header("Blinking Light")] public GameObject lightObject; public float lightBlinkInterval = 0.5f; private bool isRinging = false; private bool isHeld = false; private bool isCooldown = false; private Coroutine ringCoroutine; private Coroutine blinkCoroutine; private void Start() { StartRandomRinging(); } private void Update() { FVRPhysicalObject component = ((Component)this).GetComponent(); if (!((Object)(object)component != (Object)null)) { return; } bool flag = ((FVRInteractiveObject)component).IsHeld; if (flag != isHeld) { isHeld = flag; if (isHeld) { HandlePickup(); } else { HandlePutDown(); } } } private void HandlePickup() { if (isRinging) { StopRinging(); ((MonoBehaviour)this).StartCoroutine(PlaySpeechAfterDelay(speechStartDelay)); } else if (!isRinging && (Object)(object)phoneTone != (Object)null) { PlayPhoneTone(); } } private void HandlePutDown() { StopAudio(); if (!isCooldown) { ((MonoBehaviour)this).StartCoroutine(CooldownBeforeNextRing()); } } private void StartRandomRinging() { if (ringCoroutine == null) { ringCoroutine = ((MonoBehaviour)this).StartCoroutine(RandomRingRoutine()); } } private void StopRinging() { if (audioSource.isPlaying && isRinging) { audioSource.Stop(); } if (blinkCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(blinkCoroutine); blinkCoroutine = null; } if ((Object)(object)lightObject != (Object)null) { lightObject.SetActive(false); } isRinging = false; } private IEnumerator RandomRingRoutine() { while (true) { float interval = Random.Range(minRingInterval, maxRingInterval); yield return (object)new WaitForSeconds(interval); if (!isHeld && !isCooldown && ringClips.Count > 0) { isRinging = true; audioSource.clip = ringClips[Random.Range(0, ringClips.Count)]; audioSource.loop = true; audioSource.Play(); if (blinkCoroutine == null) { blinkCoroutine = ((MonoBehaviour)this).StartCoroutine(BlinkLightRoutine()); } yield return (object)new WaitForSeconds(ringDuration); if (isRinging) { StopRinging(); } if (!isHeld) { ((MonoBehaviour)this).StartCoroutine(CooldownBeforeNextRing()); } } } } private IEnumerator BlinkLightRoutine() { while (true) { if ((Object)(object)lightObject != (Object)null) { lightObject.SetActive(!lightObject.activeSelf); } yield return (object)new WaitForSeconds(lightBlinkInterval); } } private IEnumerator PlaySpeechAfterDelay(float delay) { yield return (object)new WaitForSeconds(delay); if (isHeld && speechClips.Count > 0) { audioSource.loop = false; audioSource.clip = speechClips[Random.Range(0, speechClips.Count)]; audioSource.Play(); } ((MonoBehaviour)this).StartCoroutine(CooldownBeforeNextRing()); } private void PlayPhoneTone() { if ((Object)(object)phoneTone != (Object)null && !audioSource.isPlaying) { audioSource.loop = true; audioSource.clip = phoneTone; audioSource.Play(); } } private void StopAudio() { if (audioSource.isPlaying) { audioSource.Stop(); } } private IEnumerator CooldownBeforeNextRing() { isCooldown = true; yield return (object)new WaitForSeconds(ringCooldown); isCooldown = false; StartRandomRinging(); } } public class PlateRackToggle : SteelPopTarget { public List hingeJointsToToggle; public override void Start() { ((SteelPopTarget)this).Start(); bool useSpring = base.SpringSwitchJoint.useSpring; UpdateHingeJointsSpring(useSpring); } private void Update() { bool useSpring = base.SpringSwitchJoint.useSpring; UpdateHingeJointsSpring(useSpring); } private void UpdateHingeJointsSpring(bool springEnabled) { foreach (HingeJoint item in hingeJointsToToggle) { item.useSpring = springEnabled; } } } public class CombatCompanion : FVRInteractiveObject { public enum CompanionModeEnum { LootCompanion, CombatHelper } public enum AnimationTypeEnum { Rotation, Translation } public enum AxisEnum { X, Y, Z } [Header("Mode Configuration")] public CompanionModeEnum mode = CompanionModeEnum.LootCompanion; [Header("Interactive Geometry Config")] [Tooltip("The moving transform representing the physical switch or button")] public Transform ButtonGeo; [Tooltip("Choose whether the button rotates or slides/depresses")] public AnimationTypeEnum AnimationType = AnimationTypeEnum.Rotation; [Tooltip("The local axis along which the transformation occurs")] public AxisEnum TargetAxis = AxisEnum.Z; [Tooltip("Speed of the animation transition (use larger numbers for rotation)")] public float AnimationSpeed = 800f; [Tooltip("The value on the targeted axis when the state is OFF (Degrees for Rotation, Local Units for Translation)")] public float OffValue = 0f; [Tooltip("The value on the targeted axis when the state is ON (Degrees for Rotation, Local Units for Translation)")] public float OnValue = 90f; [Header("Toggle Audio Events")] public AudioEvent AudEvent_ToggleOn; public AudioEvent AudEvent_ToggleOff; [Header("Combat Sensory Range")] [Tooltip("Maximum range to detect and target enemies")] public float maxCombatRange = 40f; [Tooltip("Field of View angle for enemy detection")] public float maxCombatFOV = 120f; [Tooltip("Layer mask used for line of sight occlusion checks")] public LayerMask visualOcclusionMask; [Header("Tactical Combat Movement")] [Tooltip("The distance the companion tries to maintain from the enemy. It will stop moving closer once inside this range.")] public float combatStandoffDistance = 5f; [Tooltip("How fast the companion physically rotates its body to face the enemy")] public float bodyRotationSpeed = 8f; [Header("Combat Animations")] [Tooltip("Custom combat idle animation. Falls back to standard Idle if empty.")] public string animCombatIdle = "CombatIdle"; [Tooltip("Custom combat wait animation. Falls back to standard Wait if empty.")] public string animCombatWait = "CombatWait"; [Tooltip("Custom combat run animation. Falls back to standard Run if empty.")] public string animCombatRun = "CombatRun"; [Header("Aggression Scaling")] [Range(0f, 1f)] public float currentThreat = 0f; [Tooltip("Slowest shoot delay (in seconds) when calm")] public float maxShootDelay = 2f; [Tooltip("Fastest shoot delay (in seconds) under heavy threat")] public float minShootDelay = 0.15f; [Header("Developer Debugging")] [Tooltip("Check this to output state changes, targeting changes, and firing logs to your BepInEx console")] public bool enableDebugLogs = false; [Tooltip("Draws a visual sight cone and targeting laser in the Unity Editor scene view")] public bool drawDebugGizmos = true; private LootCompanion lootComp; private NavMeshAgent agent; private AIEntity selfAIEntity; private AIEntity targetEntity; private float nextShootTime = 0f; private float suppressionThreatSpike = 0f; private Vector3 m_defaultLocalPos; private Vector3 m_defaultLocalRot; private float m_curValue; private float m_tarValue; private bool m_isOn; public override void Awake() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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) ((FVRInteractiveObject)this).Awake(); if ((Object)(object)ButtonGeo != (Object)null) { m_defaultLocalPos = ButtonGeo.localPosition; m_defaultLocalRot = ButtonGeo.localEulerAngles; } m_curValue = OffValue; m_tarValue = OffValue; } public override void Start() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown ((FVRInteractiveObject)this).Start(); lootComp = ((Component)this).GetComponentInParent(); agent = ((Component)this).GetComponentInParent(); selfAIEntity = ((Component)this).GetComponentInParent(); if ((Object)(object)selfAIEntity != (Object)null) { selfAIEntity.AIReceiveSuppressionEvent += new AIReceiveSuppression(OnSuppressionReceived); } if (enableDebugLogs) { Debug.Log((object)("[CombatCompanion] Initialization completed on companion: " + ((Object)((Component)this).gameObject).name)); } } public override void OnDestroy() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown ((FVRInteractiveObject)this).OnDestroy(); if ((Object)(object)selfAIEntity != (Object)null) { selfAIEntity.AIReceiveSuppressionEvent -= new AIReceiveSuppression(OnSuppressionReceived); } } private void OnSuppressionReceived(Vector3 pos, Vector3 dir, int iffcode, float intensity, float range) { suppressionThreatSpike = Mathf.Clamp01(suppressionThreatSpike + intensity * 0.25f); if (enableDebugLogs) { Debug.Log((object)("[CombatCompanion] Suppression received! Intensity: " + intensity + ". Current Spike: " + suppressionThreatSpike)); } } public override void SimpleInteraction(FVRViveHand hand) { ((FVRInteractiveObject)this).SimpleInteraction(hand); ToggleButtonState(); } private void ToggleButtonState() { if (m_isOn) { SetStateOff(); } else { SetStateOn(); } } private void SetStateOn() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!m_isOn) { m_isOn = true; m_tarValue = OnValue; mode = CompanionModeEnum.CombatHelper; if (enableDebugLogs) { Debug.Log((object)"[CombatCompanion] State changed to: COMBAT HELPER"); } if (AudEvent_ToggleOn != null) { SM.PlayCoreSound((FVRPooledAudioType)10, AudEvent_ToggleOn, ((Component)this).transform.position); } } } private void SetStateOff() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (m_isOn) { m_isOn = false; m_tarValue = OffValue; mode = CompanionModeEnum.LootCompanion; if (enableDebugLogs) { Debug.Log((object)"[CombatCompanion] State changed to: LOOT COMPANION"); } if (AudEvent_ToggleOff != null) { SM.PlayCoreSound((FVRPooledAudioType)10, AudEvent_ToggleOff, ((Component)this).transform.position); } } } public override void FVRUpdate() { //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) ((FVRInteractiveObject)this).FVRUpdate(); if ((Object)(object)ButtonGeo != (Object)null && Mathf.Abs(m_tarValue - m_curValue) > 0.001f) { m_curValue = Mathf.MoveTowards(m_curValue, m_tarValue, Time.deltaTime * AnimationSpeed); if (AnimationType == AnimationTypeEnum.Rotation) { float num = ((TargetAxis != AxisEnum.X) ? m_defaultLocalRot.x : m_curValue); float num2 = ((TargetAxis != AxisEnum.Y) ? m_defaultLocalRot.y : m_curValue); float num3 = ((TargetAxis != AxisEnum.Z) ? m_defaultLocalRot.z : m_curValue); ButtonGeo.localEulerAngles = new Vector3(num, num2, num3); } else { float num4 = ((TargetAxis != AxisEnum.X) ? m_defaultLocalPos.x : m_curValue); float num5 = ((TargetAxis != AxisEnum.Y) ? m_defaultLocalPos.y : m_curValue); float num6 = ((TargetAxis != AxisEnum.Z) ? m_defaultLocalPos.z : m_curValue); ButtonGeo.localPosition = new Vector3(num4, num5, num6); } } if ((Object)(object)lootComp == (Object)null) { return; } if (mode == CompanionModeEnum.LootCompanion) { if (!((Behaviour)lootComp).enabled) { ((Behaviour)lootComp).enabled = true; } return; } if (((Behaviour)lootComp).enabled) { ((Behaviour)lootComp).enabled = false; } UpdateThreat(); HandleCombatMovement(); HandleCombatShooting(); } private void LateUpdate() { if (mode == CompanionModeEnum.CombatHelper && (Object)(object)targetEntity != (Object)null) { FVRFireArm firstAvailableWeapon = GetFirstAvailableWeapon(); if ((Object)(object)firstAvailableWeapon != (Object)null) { AimWeaponAtTarget(firstAvailableWeapon); } } } private void UpdateThreat() { if (suppressionThreatSpike > 0f) { suppressionThreatSpike -= Time.deltaTime * 0.15f; } float num = 0f; AIEntity[] array = Object.FindObjectsOfType(); if (array != null) { int num2 = 0; int num3 = (((Object)(object)selfAIEntity != (Object)null) ? selfAIEntity.IFFCode : 0); foreach (AIEntity val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)selfAIEntity && !val.IsPassiveEntity && val.IFFCode != num3 && IsInSight(val)) { num2++; } } num = Mathf.Clamp01((float)num2 * 0.15f); } float num4 = Mathf.Clamp01(num + suppressionThreatSpike); currentThreat = Mathf.Lerp(currentThreat, num4, Time.deltaTime * 1.5f); } private void HandleCombatShooting() { FVRFireArm firstAvailableWeapon = GetFirstAvailableWeapon(); if ((Object)(object)firstAvailableWeapon == (Object)null) { return; } if ((Object)(object)targetEntity == (Object)null || !IsInSight(targetEntity)) { FindCombatTarget(); } if ((Object)(object)targetEntity != (Object)null && Time.time >= nextShootTime && WeaponHasAmmoInChamber(firstAvailableWeapon)) { InjectTriggerPull(firstAvailableWeapon); if (enableDebugLogs) { Debug.Log((object)("[CombatCompanion] Trigger injected on weapon: " + ((Object)((Component)firstAvailableWeapon).gameObject).name + ". Active target: " + ((Object)((Component)targetEntity).gameObject).name)); } float num = Mathf.Lerp(maxShootDelay, minShootDelay, currentThreat); nextShootTime = Time.time + num; } } private FVRFireArm GetFirstAvailableWeapon() { if ((Object)(object)lootComp == (Object)null) { return null; } if ((Object)(object)lootComp.mouthSlot != (Object)null && (Object)(object)lootComp.mouthSlot.HeldObject != (Object)null) { FVRInteractiveObject heldObject = lootComp.mouthSlot.HeldObject; FVRFireArm val = (FVRFireArm)(object)((heldObject is FVRFireArm) ? heldObject : null); if ((Object)(object)val != (Object)null) { return val; } } if (lootComp.backpack != null) { for (int i = 0; i < lootComp.backpack.Length; i++) { FVRQuickBeltSlot val2 = lootComp.backpack[i]; if ((Object)(object)val2 != (Object)null && (Object)(object)val2.HeldObject != (Object)null) { FVRInteractiveObject heldObject2 = val2.HeldObject; FVRFireArm val3 = (FVRFireArm)(object)((heldObject2 is FVRFireArm) ? heldObject2 : null); if ((Object)(object)val3 != (Object)null) { return val3; } } } } return null; } private FVRQuickBeltSlot GetSlotOfWeapon(FVRFireArm weapon) { if ((Object)(object)weapon == (Object)null || (Object)(object)lootComp == (Object)null) { return null; } if ((Object)(object)lootComp.mouthSlot != (Object)null && (Object)(object)lootComp.mouthSlot.HeldObject == (Object)(object)weapon) { return lootComp.mouthSlot; } if (lootComp.backpack != null) { for (int i = 0; i < lootComp.backpack.Length; i++) { if ((Object)(object)lootComp.backpack[i] != (Object)null && (Object)(object)lootComp.backpack[i].HeldObject == (Object)(object)weapon) { return lootComp.backpack[i]; } } } return null; } private void FindCombatTarget() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) AIEntity[] array = Object.FindObjectsOfType(); if (array == null) { return; } AIEntity val = null; float num = maxCombatRange; int num2 = (((Object)(object)selfAIEntity != (Object)null) ? selfAIEntity.IFFCode : 0); foreach (AIEntity val2 in array) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)selfAIEntity) && !val2.IsPassiveEntity && val2.IFFCode != num2) { float num3 = Vector3.Distance(((Component)this).transform.position, val2.GetPos()); if (num3 < num && IsInSight(val2)) { num = num3; val = val2; } } } if ((Object)(object)val != (Object)(object)targetEntity) { targetEntity = val; if (enableDebugLogs && (Object)(object)targetEntity != (Object)null) { Debug.Log((object)("[CombatCompanion] Acquired new combat target: " + ((Object)((Component)targetEntity).gameObject).name)); } } } private bool IsInSight(AIEntity target) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_0092: 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) if ((Object)(object)target == (Object)null) { return false; } Vector3 val = target.GetPos() - ((Component)this).transform.position; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude > maxCombatRange) { return false; } float num = Vector3.Angle(((Component)this).transform.forward, val); if (num > maxCombatFOV * 0.5f) { return false; } RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(((Component)this).transform.position + Vector3.up * 0.5f, ((Vector3)(ref val)).normalized, ref val2, magnitude, LayerMask.op_Implicit(visualOcclusionMask)) && (Object)(object)((RaycastHit)(ref val2)).transform != (Object)(object)((Component)target).transform && !((RaycastHit)(ref val2)).transform.IsChildOf(((Component)target).transform)) { return false; } return true; } private void RotateBodyTowards(Vector3 targetPos) { //IL_0001: 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_001f: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0055: Unknown result type (might be due to invalid IL or missing references) Vector3 val = targetPos - ((Component)this).transform.position; val.y = 0f; if (val != Vector3.zero) { Quaternion val2 = Quaternion.LookRotation(val); ((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, val2, Time.deltaTime * bodyRotationSpeed); } } private void AimWeaponAtTarget(FVRFireArm weapon) { //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_0063: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00a5: 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_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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)targetEntity == (Object)null) { return; } FVRQuickBeltSlot slotOfWeapon = GetSlotOfWeapon(weapon); if (!((Object)(object)slotOfWeapon == (Object)null)) { Vector3 pos = targetEntity.GetPos(); Vector3 val = ((!((Object)(object)weapon.MuzzlePos != (Object)null)) ? ((Component)slotOfWeapon).transform.position : weapon.MuzzlePos.position); Vector3 val2 = pos - val; if (val2 != Vector3.zero) { float num = Mathf.Lerp(0.5f, 4f, currentThreat); Vector3 val3 = Random.insideUnitSphere * num; Quaternion val4 = Quaternion.LookRotation(val2) * Quaternion.Euler(val3); ((Component)slotOfWeapon).transform.rotation = Quaternion.Slerp(((Component)slotOfWeapon).transform.rotation, val4, Time.deltaTime * 10f); ((Component)weapon).transform.rotation = ((Component)slotOfWeapon).transform.rotation; } } } private bool WeaponHasAmmoInChamber(FVRFireArm firearm) { if ((Object)(object)firearm == (Object)null) { return false; } PropertyInfo property = ((object)firearm).GetType().GetProperty("Chamber", BindingFlags.Instance | BindingFlags.Public); if ((object)property != null) { object value = property.GetValue(firearm, null); if (value != null) { PropertyInfo property2 = value.GetType().GetProperty("IsFull", BindingFlags.Instance | BindingFlags.Public); PropertyInfo property3 = value.GetType().GetProperty("IsSpent", BindingFlags.Instance | BindingFlags.Public); if ((object)property2 != null && (object)property3 != null) { bool flag = (bool)property2.GetValue(value, null); bool flag2 = (bool)property3.GetValue(value, null); return flag && !flag2; } } } return true; } private void InjectTriggerPull(FVRFireArm firearm) { if (!((Object)(object)firearm == (Object)null)) { Type type = ((object)firearm).GetType(); MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public); if (!TryInvokeNamedMethod(firearm, methods, "DropHammer") && !TryInvokeNamedMethod(firearm, methods, "PullTrigger") && !TryInvokeNamedMethod(firearm, methods, "Fire")) { } } } private bool TryInvokeNamedMethod(FVRFireArm firearm, MethodInfo[] methods, string name) { foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name == name)) { continue; } try { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 0) { methodInfo.Invoke(firearm, null); return true; } if (parameters.Length == 1 && (object)parameters[0].ParameterType == typeof(bool)) { methodInfo.Invoke(firearm, new object[1] { true }); return true; } } catch (Exception ex) { if (enableDebugLogs) { Debug.LogWarning((object)("[CombatCompanion] Safe invoke failed for " + name + ": " + ex.Message)); } } } return false; } private void HandleCombatMovement() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)agent == (Object)null) { return; } Transform transform = ((Component)GM.CurrentPlayerBody).transform; Vector3 val = transform.position + transform.forward; float num = Vector3.Distance(((Component)this).transform.position, val); if (num >= lootComp.playerDistanceMax) { NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(val, ref val2, 50f, -1)) { agent.Warp(((NavMeshHit)(ref val2)).position); } } else if ((Object)(object)targetEntity != (Object)null) { Vector3 pos = targetEntity.GetPos(); float num2 = Vector3.Distance(((Component)this).transform.position, pos); if (num2 > combatStandoffDistance) { if (!((Behaviour)agent).enabled) { ((Behaviour)agent).enabled = true; } agent.SetDestination(pos); PlayCompanionAnimation(GetTargetAnimState(lootComp.animRun, animCombatRun)); } else { if (((Behaviour)agent).enabled && agent.hasPath) { agent.ResetPath(); } PlayCompanionAnimation(GetTargetAnimState(lootComp.animWait, animCombatWait)); } RotateBodyTowards(pos); } else if (num >= lootComp.playerDistanceMin) { if (!((Behaviour)agent).enabled) { ((Behaviour)agent).enabled = true; } agent.SetDestination(val); PlayCompanionAnimation(GetTargetAnimState(lootComp.animRun, animCombatRun)); } else { PlayCompanionAnimation(GetTargetAnimState(lootComp.animIdle, animCombatIdle)); } } private string GetTargetAnimState(string defaultAnim, string combatAnim) { if (mode == CompanionModeEnum.CombatHelper && !string.IsNullOrEmpty(combatAnim)) { return combatAnim; } return defaultAnim; } private void PlayCompanionAnimation(string animName) { if ((Object)(object)lootComp != (Object)null && (Object)(object)lootComp.animator != (Object)null && !string.IsNullOrEmpty(animName)) { lootComp.animator.Play(animName); } } private void OnDrawGizmos() { //IL_0011: 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_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_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_0052: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_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) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) if (drawDebugGizmos) { Gizmos.color = Color.yellow; Vector3 val = ((Component)this).transform.position + Vector3.up * 0.5f; Vector3 val2 = Quaternion.Euler(0f, (0f - maxCombatFOV) * 0.5f, 0f) * ((Component)this).transform.forward * maxCombatRange; Vector3 val3 = Quaternion.Euler(0f, maxCombatFOV * 0.5f, 0f) * ((Component)this).transform.forward * maxCombatRange; Gizmos.DrawLine(val, val + val2); Gizmos.DrawLine(val, val + val3); Gizmos.DrawLine(val + val2, val + val3); if (Application.isPlaying && (Object)(object)targetEntity != (Object)null) { Gizmos.color = ((!IsInSight(targetEntity)) ? Color.red : Color.green); Gizmos.DrawLine(val, targetEntity.GetPos()); Gizmos.DrawWireSphere(targetEntity.GetPos(), 0.5f); } } } } namespace Volks.KerfusCompanion; [BepInPlugin("Volks.KerfusCompanion", "KerfusCompanion", "1.0.0")] [BepInProcess("h3vr.exe")] [Description("Built with MeatKit")] [BepInDependency("h3vr.otherloader", "1.3.0")] public class KerfusCompanionPlugin : BaseUnityPlugin { private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); internal static ManualLogSource Logger; private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; LoadAssets(); } private void LoadAssets() { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Volks.KerfusCompanion"); OtherLoader.RegisterDirectLoad(BasePath, "Volks.KerfusCompanion", "", "", "kerfuscompanion", ""); } } public class Semtex : PinnedGrenade { [Header("Semtex Values")] public bool isSticky; public LayerMask stickyMask; [Header("Semtex Extras (Leave Empty If Not Needed)")] [Tooltip("If not null, will play audio clip placed inside of source. Used for a stick sound if you want.")] public AudioSource StickSource; public override void OnCollisionEnter(Collision collision) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (collision.gameObject.layer == LayerMask.op_Implicit(stickyMask) && !((FVRInteractiveObject)this).IsHeld) { ((Component)this).transform.parent = collision.transform; ((Component)this).GetComponent().isKinematic = true; if ((Object)(object)StickSource != (Object)null) { StickSource.Play(); } } ((PinnedGrenade)this).OnCollisionEnter(collision); } } public class Semtex_Updated : PinnedGrenade { [Header("Semtex Values")] public bool isSticky; public LayerMask stickyMask; [Header("Semtex Extras (Leave Empty If Not Needed)")] [Tooltip("If not null, will play audio clip placed inside of source. Used for a stick sound if you want.")] public AudioSource StickSource; private float timeBeforeEnableStick = 0.1f; private bool canStick = false; private Transform fakeParent; private Vector3 pos; private Vector3 fw; private Vector3 up; public override void FVRUpdate() { if (base.m_isLeverReleased && !canStick) { timeBeforeEnableStick -= Time.deltaTime; if (timeBeforeEnableStick <= 0f) { canStick = true; } } ((PinnedGrenade)this).FVRUpdate(); } private void FixedUpdate() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)fakeParent != (Object)null) { Vector3 position = ((Component)fakeParent).transform.TransformPoint(pos); Vector3 val = ((Component)fakeParent).transform.TransformDirection(fw); Vector3 val2 = ((Component)fakeParent).transform.TransformDirection(up); Quaternion rotation = Quaternion.LookRotation(val, val2); ((Component)this).transform.position = position; ((Component)this).transform.rotation = rotation; } } public override void OnCollisionEnter(Collision collision) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) ((PinnedGrenade)this).OnCollisionEnter(collision); if (!((FVRInteractiveObject)this).IsHeld && canStick && (Object)(object)fakeParent == (Object)null) { fakeParent = collision.gameObject.transform; ((Component)this).transform.position = ((ContactPoint)(ref collision.contacts[0])).point; ((Component)this).transform.rotation = Quaternion.LookRotation(((ContactPoint)(ref collision.contacts[0])).normal); pos = ((Component)fakeParent).transform.InverseTransformPoint(((Component)this).transform.position); fw = ((Component)fakeParent).transform.InverseTransformDirection(((Component)this).transform.forward); up = ((Component)fakeParent).transform.InverseTransformDirection(((Component)this).transform.up); ((Component)this).GetComponent().isKinematic = true; if ((Object)(object)StickSource != (Object)null) { StickSource.Play(); } } } public override void BeginInteraction(FVRViveHand hand) { ((PinnedGrenade)this).BeginInteraction(hand); fakeParent = null; } }