using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 GameNetcodeStuff;
using Lembont.MantleEnemy.NetcodePatcher;
using LethalLib.Modules;
using MantleEnemy.Configuration;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
[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("Lembont.MantleEnemy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MantleEnemy")]
[assembly: AssemblyTitle("Lembont.MantleEnemy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
static <Module>()
{
}
}
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 MantleEnemy
{
internal class MantleEnemyAI : EnemyAI
{
private enum State
{
SearchingForPlayer,
MovingTowardsPlayer,
Patrolling,
Fleeing
}
public AudioSource audioSource;
public AudioClip mantle_footstep;
public AudioClip mantle_roar;
public AudioClip roam_sound;
public Transform turnCompass = null;
public float normalSpeed = 3f;
public float chaseSpeed = 5f;
public float chargeSpeed = 15f;
public float fleeSpeed = 7f;
public float stunDuration = 3f;
public float damageAmount = 10f;
public float maxHealth = 100f;
public float wanderRadius = 20f;
public float wanderTimer = 5f;
private Animator animator;
private bool isCharging = false;
private bool isStunned = false;
private bool isFleeing = false;
private float currentHealth;
private float stunEndTime;
private bool knockbackApplied = false;
private float knockbackCooldownTime = 1f;
private float lastKnockbackTime = float.NegativeInfinity;
private NavMeshAgent navMeshAgent;
private float timer;
private float footstepTimer = 0f;
private float footstepInterval = 0.5f;
private float healthThreshold = 20f;
private float lastStateChangeTime = 0f;
private float changeStateInterval = 5f;
public override void Start()
{
((EnemyAI)this).Start();
animator = ((Component)this).GetComponent<Animator>();
navMeshAgent = ((Component)this).GetComponent<NavMeshAgent>();
audioSource = ((Component)this).GetComponent<AudioSource>();
if ((Object)(object)audioSource == (Object)null)
{
Debug.LogWarning((object)"AudioSource is missing from the enemy prefab");
}
else
{
audioSource.spatialBlend = 1f;
audioSource.minDistance = 1f;
audioSource.maxDistance = 20f;
audioSource.rolloffMode = (AudioRolloffMode)0;
}
if ((Object)(object)mantle_footstep == (Object)null)
{
Debug.LogWarning((object)"mantle_footstep is not assigned in the inspector");
}
if ((Object)(object)mantle_roar == (Object)null)
{
Debug.LogWarning((object)"mantle_roar is not assigned in the inspector");
}
if ((Object)(object)roam_sound == (Object)null)
{
Debug.LogWarning((object)"roam_sound is not assigned in the inspector");
}
currentHealth = maxHealth;
base.currentBehaviourStateIndex = 2;
navMeshAgent.speed = normalSpeed;
timer = wanderTimer;
((MonoBehaviour)this).StartCoroutine(PlayRandomRoar());
}
public override void Update()
{
((EnemyAI)this).Update();
if (base.isEnemyDead)
{
return;
}
if (isStunned)
{
if (!(Time.time >= stunEndTime))
{
navMeshAgent.speed = 0f;
return;
}
isStunned = false;
((EnemyAI)this).SwitchToBehaviourClientRpc(0);
}
if (currentHealth < healthThreshold && !isFleeing)
{
isFleeing = true;
((EnemyAI)this).SwitchToBehaviourClientRpc(3);
}
int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
if (Time.time > lastStateChangeTime + changeStateInterval)
{
lastStateChangeTime = Time.time;
}
switch (currentBehaviourStateIndex)
{
case 1:
HandleMovingTowardsPlayer();
break;
case 2:
HandlePatrolling();
break;
case 3:
HandleFleeing();
break;
default:
navMeshAgent.speed = normalSpeed;
animator.SetBool("isWalking", false);
break;
}
if (knockbackApplied && currentBehaviourStateIndex != 1)
{
knockbackApplied = false;
}
}
private void HandleMovingTowardsPlayer()
{
navMeshAgent.speed = (isCharging ? chargeSpeed : chaseSpeed);
animator.SetBool("isCharging", isCharging);
animator.SetBool("isWalking", !isCharging);
animator.SetFloat("WalkSpeedMultiplier", isCharging ? 2f : 1f);
footstepTimer += Time.deltaTime;
if (footstepTimer >= footstepInterval / (isCharging ? 2f : 1f))
{
PlayMantleFootstep();
footstepTimer = 0f;
}
}
private void HandlePatrolling()
{
//IL_002f: 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_0047: Unknown result type (might be due to invalid IL or missing references)
timer += Time.deltaTime;
if (timer >= wanderTimer)
{
Vector3 destination = RandomNavSphere(((Component)this).transform.position, wanderRadius, -1);
navMeshAgent.SetDestination(destination);
timer = 0f;
}
if (!navMeshAgent.pathPending && navMeshAgent.remainingDistance < 0.5f)
{
timer = wanderTimer;
}
animator.SetBool("isWalking", true);
}
private void HandleFleeing()
{
//IL_0019: 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_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_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: 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_0059: Unknown result type (might be due to invalid IL or missing references)
navMeshAgent.speed = fleeSpeed;
Vector3 val = ((Component)this).transform.position - ((Component)base.targetPlayer).transform.position;
Vector3 normalized = ((Vector3)(ref val)).normalized;
Vector3 position = ((Component)this).transform.position + normalized * 10f;
SetDestinationToPosition(position);
animator.SetBool("isWalking", true);
}
public static Vector3 RandomNavSphere(Vector3 origin, float dist, int layermask)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: 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_000e: 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)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = Random.insideUnitSphere * dist;
val += origin;
NavMeshHit val2 = default(NavMeshHit);
NavMesh.SamplePosition(val, ref val2, dist, layermask);
return ((NavMeshHit)(ref val2)).position;
}
public void ApplyDamage(float damage)
{
currentHealth -= damage;
if (currentHealth <= 0f)
{
Die();
}
}
private void Die()
{
base.isEnemyDead = true;
navMeshAgent.isStopped = true;
animator.SetTrigger("Die");
}
private void OnTriggerEnter(Collider other)
{
//IL_00bc: 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_00d1: 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)
//IL_00da: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
if (!((Component)other).CompareTag("Player") || !(Time.time > lastKnockbackTime + knockbackCooldownTime))
{
return;
}
Debug.Log((object)"Player or Obstacle Hit by Enemy!");
isStunned = true;
stunEndTime = Time.time + stunDuration;
isCharging = false;
animator.SetBool("isCharging", false);
animator.SetTrigger("ChargeAtk");
PlayRoamSound();
navMeshAgent.speed = 0f;
if (((Component)other).CompareTag("Player"))
{
PlayerControllerB component = ((Component)other).GetComponent<PlayerControllerB>();
if ((Object)(object)component != (Object)null)
{
Vector3 val = ((Component)other).transform.position - ((Component)this).transform.position;
Vector3 normalized = ((Vector3)(ref val)).normalized;
((MonoBehaviour)this).StartCoroutine(ApplyKnockback(component, normalized));
int num = (int)damageAmount;
val = default(Vector3);
component.DamagePlayer(num, true, true, (CauseOfDeath)0, 0, false, val);
}
knockbackApplied = true;
lastKnockbackTime = Time.time;
}
((MonoBehaviour)this).StartCoroutine(TransitionToIdleAfterCharge());
}
private IEnumerator TransitionToIdleAfterCharge()
{
yield return (object)new WaitForSeconds(1f);
animator.SetBool("isWalking", false);
animator.SetBool("isCharging", false);
animator.ResetTrigger("ChargeAtk");
if (base.currentBehaviourStateIndex == 1)
{
isCharging = false;
base.currentBehaviourStateIndex = 2;
}
((MonoBehaviour)this).StartCoroutine(RestartSearchingForPlayer());
}
private IEnumerator RestartSearchingForPlayer()
{
yield return (object)new WaitForSeconds(stunDuration);
if (!base.isEnemyDead)
{
((EnemyAI)this).SwitchToBehaviourClientRpc(2);
}
}
private IEnumerator ApplyKnockback(PlayerControllerB playerController, Vector3 hitDirection)
{
//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)
((Behaviour)playerController).enabled = false;
float knockbackForce = Random.Range(5f, 20f);
float upwardsModifier = Random.Range(0.2f, 1f);
Vector3 val = new Vector3(hitDirection.x, upwardsModifier, hitDirection.z);
Vector3 force = ((Vector3)(ref val)).normalized * knockbackForce;
CharacterController controller = ((Component)playerController).GetComponent<CharacterController>();
if ((Object)(object)controller != (Object)null)
{
for (float timer = 0f; timer < 0.5f; timer += Time.deltaTime)
{
controller.Move(force * Time.deltaTime);
yield return null;
}
}
((Behaviour)playerController).enabled = true;
RaycastHit hit = default(RaycastHit);
if (Physics.Raycast(((Component)playerController).transform.position, ((Vector3)(ref force)).normalized, ref hit, 1f) && ((Component)((RaycastHit)(ref hit)).collider).gameObject.layer == LayerMask.NameToLayer("Default"))
{
controller.Move(Vector3.zero);
}
}
public override void DoAIInterval()
{
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: 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)
((EnemyAI)this).DoAIInterval();
if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
{
return;
}
switch (base.currentBehaviourStateIndex)
{
case 2:
navMeshAgent.speed = normalSpeed;
if (FoundClosestPlayerInRange(30f, 5f))
{
((EnemyAI)this).SwitchToBehaviourClientRpc(1);
}
break;
case 1:
if (!TargetClosestPlayerInAnyCase() || (Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) > 25f && !((EnemyAI)this).CheckLineOfSightForPosition(((Component)base.targetPlayer).transform.position, 45f, 60, -1f, (Transform)null)))
{
((EnemyAI)this).SwitchToBehaviourClientRpc(2);
}
else
{
MoveTowardsPlayer();
}
break;
}
}
private bool FoundClosestPlayerInRange(float range, float senseRange)
{
//IL_004e: 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)
((EnemyAI)this).TargetClosestPlayer(1.5f, true, 70f);
if ((Object)(object)base.targetPlayer == (Object)null)
{
((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f);
range = senseRange;
}
return (Object)(object)base.targetPlayer != (Object)null && Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < range;
}
private bool TargetClosestPlayerInAnyCase()
{
//IL_001e: 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)
base.mostOptimalDistance = 2000f;
base.targetPlayer = null;
for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++)
{
float num = Vector3.Distance(((Component)this).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
if (num < base.mostOptimalDistance)
{
base.mostOptimalDistance = num;
base.targetPlayer = StartOfRound.Instance.allPlayerScripts[i];
}
}
return (Object)(object)base.targetPlayer != (Object)null;
}
private void MoveTowardsPlayer()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)base.targetPlayer == (Object)null) && ((NetworkBehaviour)this).IsOwner)
{
SetDestinationToPosition(((Component)base.targetPlayer).transform.position, checkForPath: false);
isCharging = true;
animator.SetBool("isCharging", true);
animator.SetBool("isWalking", false);
}
}
private void SetDestinationToPosition(Vector3 position, bool checkForPath = true)
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected O, but got Unknown
//IL_0013: 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_0023: Invalid comparison between Unknown and I4
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
if (checkForPath)
{
NavMeshPath val = new NavMeshPath();
if (navMeshAgent.CalculatePath(position, val) && (int)val.status == 0)
{
navMeshAgent.SetDestination(position);
}
}
else
{
navMeshAgent.SetDestination(position);
}
}
public void PlayMantleFootstep()
{
if ((Object)(object)audioSource != (Object)null && (Object)(object)mantle_footstep != (Object)null)
{
audioSource.PlayOneShot(mantle_footstep);
}
else
{
Debug.LogWarning((object)"AudioSource or FootstepClip is not assigned");
}
}
public void PlayRoamSound()
{
if ((Object)(object)audioSource != (Object)null && (Object)(object)roam_sound != (Object)null)
{
audioSource.PlayOneShot(roam_sound);
}
else
{
Debug.LogWarning((object)"AudioSource or RoamClip is not assigned");
}
}
private IEnumerator PlayRandomRoar()
{
while (!base.isEnemyDead)
{
float waitTime = Random.Range(10f, 20f);
yield return (object)new WaitForSeconds(waitTime);
PlayMantleRoar();
}
}
public void PlayMantleRoar()
{
if ((Object)(object)audioSource != (Object)null && (Object)(object)mantle_roar != (Object)null)
{
audioSource.PlayOneShot(mantle_roar);
}
else
{
Debug.LogWarning((object)"AudioSource or RoarClip is not assigned");
}
}
protected override void __initializeVariables()
{
((EnemyAI)this).__initializeVariables();
}
protected internal override string __getTypeName()
{
return "MantleEnemyAI";
}
}
[BepInPlugin("Lembont.MantleEnemy", "MantleEnemy", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
public static AssetBundle? ModAssetss;
internal static PluginConfig BoundConfig { get; private set; }
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
InitializeNetworkBehaviours();
string path = "MantleAssets!";
ModAssetss = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), path));
if ((Object)(object)ModAssetss == (Object)null)
{
Logger.LogError((object)"Failed to load custom assets.");
return;
}
EnemyType val = ModAssetss.LoadAsset<EnemyType>("MantleEnemy");
TerminalNode val2 = ModAssetss.LoadAsset<TerminalNode>("MantleEnemyTN");
TerminalKeyword val3 = ModAssetss.LoadAsset<TerminalKeyword>("MantleEnemyTK");
NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab);
Enemies.RegisterEnemy(val, BoundConfig.SpawnWeight.Value, (LevelTypes)(-1), val2, val3);
Logger.LogInfo((object)"PLAY. PLAY BASEBALL WITH MANTLE. :3");
}
private static void InitializeNetworkBehaviours()
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
Type[] array = types;
foreach (Type type in array)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo[] array2 = methods;
foreach (MethodInfo methodInfo in array2)
{
object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
if (customAttributes.Length != 0)
{
methodInfo.Invoke(null, null);
}
}
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "Lembont.MantleEnemy";
public const string PLUGIN_NAME = "MantleEnemy";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace MantleEnemy.Configuration
{
public class PluginConfig
{
public ConfigEntry<int> SpawnWeight;
public PluginConfig(ConfigFile cfg)
{
SpawnWeight = cfg.Bind<int>("General", "Spawn weight", 60, "The spawn chance weight for ExampleEnemy, relative to other existing enemies.\nGoes up from 0, lower is more rare, 100 and up is very common.");
ClearUnusedEntries(cfg);
}
private void ClearUnusedEntries(ConfigFile cfg)
{
PropertyInfo property = ((object)cfg).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(cfg, null);
dictionary.Clear();
cfg.Save();
}
}
}
namespace Lembont.MantleEnemy.NetcodePatcher
{
[AttributeUsage(AttributeTargets.Module)]
internal class NetcodePatchedAssemblyAttribute : Attribute
{
}
}