using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx.Logging;
using GameNetcodeStuff;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EggPawn")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("EggPawn Monster for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EggPawn")]
[assembly: AssemblyTitle("EggPawn")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace EggPawnMod
{
public class EggPawnAI : EnemyAI
{
[Header("Movement Settings")]
public float moveSpeed = 4f;
public float pursuitTime = 5f;
public float minIdleTime = 2f;
public float maxIdleTime = 5f;
[Header("Health Settings")]
public int maxHealth = 3;
private bool isDying;
[Header("Detection Settings")]
public float detectionRadius = 15f;
public LayerMask detectionMask;
[Header("Animation Settings")]
public string idleAnimationTrigger = "Idle";
public string moveAnimationTrigger = "Moving";
public string detectAnimationTrigger = "Alert";
public string deathAnimationTrigger = "Death";
[Header("Audio Settings")]
public AudioClip detectionSound;
public AudioClip[] movementSounds;
public float movementSoundInterval = 0.5f;
public AudioClip deathSound;
public AudioClip explosionSound;
[Header("Death Settings")]
public GameObject explosionEffectPrefab;
public EnemyType[] possibleSpawns;
public Item[] possibleScrap;
private Vector3 targetLocation;
private bool isPursuing;
private float pursuitTimer;
private float idleTimer;
private float timeSinceLastStep;
private bool hasInitialDestination;
private bool isIdle = true;
private float timeSinceHittingPlayer;
private bool hasDetectedPlayer;
private PlayerControllerB lastDetectedPlayer;
private ManualLogSource logger;
public override void Start()
{
((EnemyAI)this).Start();
logger = Logger.CreateLogSource("EggPawnMod");
logger.LogInfo((object)"EggPawn initialized");
base.enemyHP = maxHealth;
if ((Object)(object)base.creatureSFX == (Object)null)
{
base.creatureSFX = ((Component)this).gameObject.AddComponent<AudioSource>();
base.creatureSFX.spatialBlend = 1f;
base.creatureSFX.maxDistance = 15f;
base.creatureSFX.rolloffMode = (AudioRolloffMode)1;
}
base.agent.speed = moveSpeed;
base.agent.stoppingDistance = 0.5f;
base.agent.angularSpeed = 120f;
idleTimer = Random.Range(minIdleTime, maxIdleTime);
if (((NetworkBehaviour)this).IsServer)
{
((MonoBehaviour)this).StartCoroutine(SetInitialDestination());
}
}
private IEnumerator SetInitialDestination()
{
yield return (object)new WaitForSeconds(1f);
SetNewRandomDestination();
hasInitialDestination = true;
logger.LogInfo((object)"Initial destination set");
}
public override void Update()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
((EnemyAI)this).Update();
if (!((NetworkBehaviour)this).IsServer || base.isEnemyDead || !hasInitialDestination)
{
return;
}
timeSinceHittingPlayer += Time.deltaTime;
PlayerControllerB val = ScanForPlayers();
if ((Object)(object)val != (Object)null && !isPursuing)
{
StartPursuit(((Component)val).transform.position);
}
if (isPursuing)
{
HandlePursuit();
}
else
{
HandleIdle();
}
Vector3 velocity = base.agent.velocity;
if (((Vector3)(ref velocity)).magnitude > 0.1f)
{
timeSinceLastStep += Time.deltaTime;
if (timeSinceLastStep >= movementSoundInterval)
{
PlayMovementSoundServerRpc();
timeSinceLastStep = 0f;
}
}
UpdateAnimationState();
}
private PlayerControllerB ScanForPlayers()
{
//IL_003e: 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_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: 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_008e: 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)
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
if ((Object)(object)val == (Object)null || val.isPlayerDead || !((Behaviour)val).isActiveAndEnabled)
{
continue;
}
float num = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position);
if (num <= detectionRadius)
{
Vector3 val2 = ((Component)val).transform.position - ((Component)this).transform.position;
Vector3 normalized = ((Vector3)(ref val2)).normalized;
if (!Physics.Raycast(((Component)this).transform.position, normalized, num, LayerMask.op_Implicit(detectionMask)))
{
logger.LogInfo((object)("Detected player: " + val.playerUsername));
return val;
}
}
}
return null;
}
public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
{
((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID);
logger.LogInfo((object)$"EggPawn hit for {force} damage. Current HP: {base.enemyHP}");
if (isDying)
{
return;
}
base.enemyHP -= force;
if (base.enemyHP <= 0 && !base.isEnemyDead)
{
logger.LogInfo((object)"EggPawn health depleted, triggering death");
if (((NetworkBehaviour)this).IsServer)
{
((EnemyAI)this).KillEnemyOnOwnerClient(false);
}
else
{
KillEnemyServerRpc();
}
}
else
{
PlayHitEffectsServerRpc();
}
}
private void HandlePursuit()
{
pursuitTimer -= Time.deltaTime;
if (pursuitTimer <= 0f || (base.agent.remainingDistance <= base.agent.stoppingDistance && !base.agent.pathPending))
{
EndPursuit();
}
}
private void HandleIdle()
{
if (!(base.agent.remainingDistance <= base.agent.stoppingDistance) || base.agent.pathPending)
{
return;
}
if (!isIdle)
{
isIdle = true;
idleTimer = Random.Range(minIdleTime, maxIdleTime);
return;
}
idleTimer -= Time.deltaTime;
if (idleTimer <= 0f)
{
SetNewRandomDestination();
}
}
private void StartPursuit(Vector3 playerPosition)
{
//IL_000b: 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_0043: Unknown result type (might be due to invalid IL or missing references)
logger.LogInfo((object)$"Starting pursuit to position: {playerPosition}");
targetLocation = playerPosition;
pursuitTimer = pursuitTime;
isPursuing = true;
isIdle = false;
base.agent.SetDestination(targetLocation);
base.creatureAnimator.SetTrigger(detectAnimationTrigger);
if ((Object)(object)detectionSound != (Object)null)
{
base.creatureSFX.PlayOneShot(detectionSound);
WalkieTalkie.TransmitOneShotAudio(base.creatureSFX, detectionSound, 1f);
}
PlayDetectionEffectsServerRpc();
}
private void EndPursuit()
{
logger.LogInfo((object)"Ending pursuit");
isPursuing = false;
hasDetectedPlayer = false;
lastDetectedPlayer = null;
pursuitTimer = 0f;
SetNewRandomDestination();
}
private void UpdateAnimationState()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Vector3 velocity = base.agent.velocity;
bool flag = ((Vector3)(ref velocity)).magnitude > 0.1f;
base.creatureAnimator.SetBool(moveAnimationTrigger, flag);
if (!flag && !isPursuing)
{
base.creatureAnimator.SetTrigger(idleAnimationTrigger);
}
}
private void SetNewRandomDestination()
{
//IL_000a: 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_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
if (((NetworkBehaviour)this).IsServer)
{
Vector3 randomNavMeshPoint = GetRandomNavMeshPoint();
base.agent.SetDestination(randomNavMeshPoint);
isIdle = false;
logger.LogInfo((object)$"Set new random destination: {randomNavMeshPoint}");
}
}
private Vector3 GetRandomNavMeshPoint()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = Random.insideUnitSphere * 20f + ((Component)this).transform.position;
Vector3 position = ((Component)this).transform.position;
NavMeshHit val2 = default(NavMeshHit);
if (NavMesh.SamplePosition(val, ref val2, 20f, -1))
{
position = ((NavMeshHit)(ref val2)).position;
}
return position;
}
public override void OnCollideWithPlayer(Collider other)
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
if (!((NetworkBehaviour)this).IsServer || base.isEnemyDead || timeSinceHittingPlayer < 0.5f)
{
return;
}
PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false);
if (!((Object)(object)val == (Object)null) && !val.isPlayerDead)
{
timeSinceHittingPlayer = 0f;
if ((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController)
{
val.DamagePlayer(35, true, true, (CauseOfDeath)1, 0, false, default(Vector3));
}
HitPlayerServerRpc(((NetworkBehaviour)val).NetworkObjectId);
}
}
public override void KillEnemy(bool destroy = false)
{
if (!base.isEnemyDead && !isDying)
{
logger.LogInfo((object)"EggPawn killed");
isDying = true;
base.isEnemyDead = true;
((MonoBehaviour)this).StopAllCoroutines();
if (base.agent.isOnNavMesh)
{
base.agent.isStopped = true;
}
base.creatureAnimator.SetTrigger(deathAnimationTrigger);
((MonoBehaviour)this).StartCoroutine(DeathSequence());
}
}
private IEnumerator DeathSequence()
{
PlayDeathEffectsServerRpc();
yield return (object)new WaitForSeconds(1f);
if (((NetworkBehaviour)this).IsServer)
{
if (Random.value < 0.5f && possibleSpawns.Length != 0)
{
EnemyType val = possibleSpawns[Random.Range(0, possibleSpawns.Length)];
RoundManager.Instance.SpawnEnemyGameObject(((Component)this).transform.position, 0f, -1, val);
}
else if (possibleScrap.Length != 0)
{
Object.Instantiate<GameObject>(possibleScrap[Random.Range(0, possibleScrap.Length)].spawnPrefab, ((Component)this).transform.position + Vector3.up * 0.5f, Quaternion.identity).GetComponent<NetworkObject>().Spawn(false);
}
}
yield return (object)new WaitForSeconds(0.5f);
if ((Object)(object)explosionEffectPrefab != (Object)null)
{
Object.Instantiate<GameObject>(explosionEffectPrefab, ((Component)this).transform.position, Quaternion.identity);
}
if (((NetworkBehaviour)this).IsServer)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
[ServerRpc]
private void PlayDetectionEffectsServerRpc()
{
PlayDetectionEffectsClientRpc();
}
[ClientRpc]
private void PlayDetectionEffectsClientRpc()
{
if (!((NetworkBehaviour)this).IsOwner && (Object)(object)detectionSound != (Object)null)
{
base.creatureSFX.PlayOneShot(detectionSound);
}
}
[ServerRpc]
private void PlayMovementSoundServerRpc()
{
PlayMovementSoundClientRpc();
}
[ClientRpc]
private void PlayMovementSoundClientRpc()
{
if (movementSounds != null && movementSounds.Length != 0)
{
base.creatureSFX.PlayOneShot(movementSounds[Random.Range(0, movementSounds.Length)]);
}
}
[ServerRpc(RequireOwnership = false)]
private void KillEnemyServerRpc()
{
if (!base.isEnemyDead)
{
((EnemyAI)this).KillEnemy(false);
}
}
[ServerRpc]
private void PlayHitEffectsServerRpc()
{
PlayHitEffectsClientRpc();
}
[ClientRpc]
private void PlayHitEffectsClientRpc()
{
if ((Object)(object)base.creatureAnimator != (Object)null)
{
base.creatureAnimator.SetTrigger("Hit");
}
_ = (Object)(object)base.creatureSFX != (Object)null;
}
[ServerRpc]
private void PlayDeathEffectsServerRpc()
{
PlayDeathEffectsClientRpc();
}
[ClientRpc]
private void PlayDeathEffectsClientRpc()
{
//IL_0058: 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)
if ((Object)(object)deathSound != (Object)null)
{
base.creatureSFX.PlayOneShot(deathSound);
}
if ((Object)(object)explosionSound != (Object)null)
{
base.creatureSFX.PlayOneShot(explosionSound);
}
if ((Object)(object)explosionEffectPrefab != (Object)null)
{
Object.Instantiate<GameObject>(explosionEffectPrefab, ((Component)this).transform.position, Quaternion.identity);
}
}
[ServerRpc]
private void HitPlayerServerRpc(ulong playerObjectId)
{
HitPlayerClientRpc(playerObjectId);
}
[ClientRpc]
private void HitPlayerClientRpc(ulong playerObjectId)
{
PlayerControllerB val = default(PlayerControllerB);
if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(playerObjectId, out var value) && ((Component)value).TryGetComponent<PlayerControllerB>(ref val) && (Object)(object)val.playerBodyAnimator != (Object)null)
{
val.playerBodyAnimator.SetTrigger("Hit");
}
}
}
}