LethalCompany/Lethal Company/ExportedProject/Assets/Scripts/Assembly-CSharp/DoublewingAI.cs
2023-12-22 19:30:32 -05:00

583 lines
16 KiB
C#

using System;
using System.Collections;
using GameNetcodeStuff;
using Unity.Netcode;
using UnityEngine;
public class DoublewingAI : EnemyAI
{
public Animator bodyAnimator;
private int behaviourStateLastFrame = -1;
public AudioSource flappingAudio;
public AudioClip[] birdScreechSFX;
public AudioClip birdHitGroundSFX;
public AISearchRoutine roamGlide;
private bool alertingBird;
private float glideTime = 10f;
private float currentGlideTime;
private RaycastHit hit;
private bool flyingToOtherBirdLanding;
private float avoidingPlayer;
public Transform Body;
private Vector3 previousPosition;
private float flyLayerWeight;
[Space(5f)]
public float maxSpeed;
[Space(5f)]
public float speedElevationMultiplier;
private float randomYRot;
private int velocityAverageCount;
private float averageVelocity;
private float lerpedElevation;
private float timeSinceEnteringFlight;
private float randomHeightOffset;
private bool birdStunned;
private bool oddInterval;
private int birdNoisiness = 5;
private float timeSinceSquawking;
private float velocityInterval;
public Rigidbody birdRigidbody;
private int timesSyncingPosition;
public override void Start()
{
base.Start();
creatureAnimator.SetInteger("idleType", UnityEngine.Random.Range(0, 2));
creatureAnimator.SetFloat("speedMultiplier", UnityEngine.Random.Range(0.73f, 1.3f));
bodyAnimator.SetFloat("speedMultiplier", UnityEngine.Random.Range(0.8f, 1.2f));
randomHeightOffset = (float)new System.Random(StartOfRound.Instance.randomMapSeed / (int)(base.NetworkObjectId + 1)).NextDouble();
}
public override void DaytimeEnemyLeave()
{
base.DaytimeEnemyLeave();
if (stunNormalizedTimer < 0f && !isEnemyDead)
{
bodyAnimator.SetBool("flying", value: true);
creatureAnimator.SetBool("gliding", value: true);
bodyAnimator.SetTrigger("Leave");
}
StartCoroutine(flyAwayThenDespawn());
}
private IEnumerator flyAwayThenDespawn()
{
yield return new WaitForSeconds(7f);
if (base.IsOwner)
{
KillEnemyOnOwnerClient(overrideDestroy: true);
}
}
public override void DetectNoise(Vector3 noisePosition, float noiseLoudness, int timesPlayedInOneSpot = 0, int noiseID = 0)
{
base.DetectNoise(noisePosition, noiseLoudness, timesPlayedInOneSpot, noiseID);
if (noiseID != 911 && !isEnemyDead && !(stunNormalizedTimer > 0f))
{
float num = Vector3.Distance(noisePosition, base.transform.position + Vector3.up * 0.5f);
if (Physics.Linecast(base.transform.position, noisePosition, 256))
{
noiseLoudness /= 2f;
}
float num2 = 0.01f;
if (!(noiseLoudness / num <= num2) && currentBehaviourStateIndex == 0 && !alertingBird)
{
alertingBird = true;
AlertBirdServerRpc();
}
}
}
public void StunBird()
{
if (birdStunned)
{
return;
}
birdStunned = true;
agent.speed = 0f;
DoublewingAI[] array = UnityEngine.Object.FindObjectsByType<DoublewingAI>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
for (int i = 0; i < array.Length; i++)
{
if (!(array[i] == this) && Vector3.Distance(array[i].transform.position, base.transform.position) < 8f)
{
array[i].AlertBirdByOther();
}
}
flappingAudio.Stop();
creatureAnimator.SetBool("stunned", value: true);
bodyAnimator.SetBool("stunned", value: true);
}
public void UnstunBird()
{
if (birdStunned)
{
birdStunned = false;
creatureAnimator.SetBool("stunned", value: false);
bodyAnimator.SetBool("stunned", value: false);
if (currentBehaviourStateIndex == 0)
{
SwitchToBehaviourStateOnLocalClient(1);
}
}
}
public override void DoAIInterval()
{
base.DoAIInterval();
if (daytimeEnemyLeaving || isEnemyDead || StartOfRound.Instance.allPlayersDead || stunNormalizedTimer > 0f)
{
return;
}
switch (currentBehaviourStateIndex)
{
case 0:
oddInterval = !oddInterval;
if (oddInterval && !alertingBird && (bool)CheckLineOfSightForPlayer(80f, 8, 4))
{
alertingBird = true;
AlertBirdServerRpc();
}
break;
case 1:
{
behaviourStateLastFrame = 1;
creatureAnimator.SetBool("gliding", value: true);
bodyAnimator.SetBool("flying", value: true);
agent.speed = Mathf.Clamp(agent.speed + AIIntervalTime * 4f, 5f, 19f);
if (!flyingToOtherBirdLanding && avoidingPlayer <= 0f && !roamGlide.inProgress)
{
StartSearch(base.transform.position, roamGlide);
}
if (avoidingPlayer > 0f)
{
avoidingPlayer -= AIIntervalTime;
if (Vector3.Distance(base.transform.position, destination) < 3f)
{
avoidingPlayer = 0f;
}
break;
}
PlayerControllerB playerControllerB = CheckLineOfSightForPlayer(80f, 10, 8);
if (oddInterval && (bool)playerControllerB)
{
Transform transform = ChooseFarthestNodeFromPosition(playerControllerB.transform.position, avoidLineOfSight: false, UnityEngine.Random.Range(0, allAINodes.Length / 2));
if (SetDestinationToPosition(transform.position))
{
avoidingPlayer = UnityEngine.Random.Range(10, 20);
StopSearch(roamGlide);
}
}
currentGlideTime += AIIntervalTime;
if (!(currentGlideTime > glideTime))
{
break;
}
currentGlideTime = 0f;
if (flyingToOtherBirdLanding)
{
if (!SetDestinationToPosition(destination, checkForPath: true))
{
flyingToOtherBirdLanding = false;
glideTime = 5f;
break;
}
if (Vector3.Distance(base.transform.position, destination) < 3f)
{
if (!TryLanding())
{
flyingToOtherBirdLanding = false;
glideTime = 5f;
}
else
{
SwitchToBehaviourState(0);
}
break;
}
}
for (int i = 0; i < RoundManager.Instance.SpawnedEnemies.Count; i++)
{
if (RoundManager.Instance.SpawnedEnemies[i].enemyType == enemyType && RoundManager.Instance.SpawnedEnemies[i].currentBehaviourStateIndex == 0 && Vector3.Distance(base.transform.position, RoundManager.Instance.SpawnedEnemies[i].transform.position) < 100f)
{
Vector3 randomNavMeshPositionInRadius = RoundManager.Instance.GetRandomNavMeshPositionInRadius(RoundManager.Instance.SpawnedEnemies[i].transform.position);
if (SetDestinationToPosition(randomNavMeshPositionInRadius, checkForPath: true))
{
StopSearch(roamGlide);
flyingToOtherBirdLanding = true;
glideTime = 2f;
}
break;
}
}
if (!flyingToOtherBirdLanding)
{
if (TryLanding())
{
SwitchToBehaviourState(0);
}
else
{
glideTime = 10f;
}
}
break;
}
}
}
public bool TryLanding()
{
if (Physics.Raycast(new Vector3(base.transform.position.x, eye.position.y, base.transform.position.z), Vector3.down, out hit, 60f, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
{
if (Physics.CheckSphere(hit.point, 16f, StartOfRound.Instance.playersMask, QueryTriggerInteraction.Ignore))
{
return false;
}
if (Vector3.Distance(hit.point, base.transform.position) > 1f)
{
if (SetDestinationToPosition(hit.point, checkForPath: true))
{
agent.Warp(destination);
return true;
}
return false;
}
return true;
}
return false;
}
[ServerRpc(RequireOwnership = false)]
public void AlertBirdServerRpc()
{
NetworkManager networkManager = base.NetworkManager;
if ((object)networkManager != null && networkManager.IsListening)
{
if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost))
{
ServerRpcParams serverRpcParams = default(ServerRpcParams);
FastBufferWriter bufferWriter = __beginSendServerRpc(838150599u, serverRpcParams, RpcDelivery.Reliable);
__endSendServerRpc(ref bufferWriter, 838150599u, serverRpcParams, RpcDelivery.Reliable);
}
if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost))
{
AlertBirdClientRpc();
}
}
}
[ClientRpc]
public void AlertBirdClientRpc()
{
NetworkManager networkManager = base.NetworkManager;
if ((object)networkManager != null && networkManager.IsListening)
{
if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
{
ClientRpcParams clientRpcParams = default(ClientRpcParams);
FastBufferWriter bufferWriter = __beginSendClientRpc(3264241129u, clientRpcParams, RpcDelivery.Reliable);
__endSendClientRpc(ref bufferWriter, 3264241129u, clientRpcParams, RpcDelivery.Reliable);
}
if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost))
{
AlertBird();
}
}
}
public void AlertBird()
{
DoublewingAI[] array = UnityEngine.Object.FindObjectsByType<DoublewingAI>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
for (int i = 0; i < array.Length; i++)
{
if (!(array[i] == this) && Vector3.Distance(array[i].transform.position, base.transform.position) < 8f)
{
array[i].AlertBirdByOther();
}
}
SwitchToBehaviourStateOnLocalClient(1);
alertingBird = false;
}
public void AlertBirdByOther()
{
if (!daytimeEnemyLeaving)
{
if (base.IsServer)
{
SwitchToBehaviourState(1);
}
else
{
SwitchToBehaviourStateOnLocalClient(1);
}
}
}
public override void Update()
{
base.Update();
if (isEnemyDead || StartOfRound.Instance.allPlayersDead)
{
return;
}
SetFlyDirection();
if (daytimeEnemyLeaving)
{
return;
}
timeSinceSquawking += Time.deltaTime;
if (stunNormalizedTimer > 0f)
{
StunBird();
}
else
{
UnstunBird();
}
switch (currentBehaviourStateIndex)
{
case 0:
if (behaviourStateLastFrame != 0)
{
behaviourStateLastFrame = 0;
randomYRot = UnityEngine.Random.Range(0f, 360f);
agent.speed = 0f;
creatureAnimator.SetBool("gliding", value: false);
bodyAnimator.SetBool("flying", value: false);
flyingToOtherBirdLanding = false;
timeSinceEnteringFlight = 0f;
}
flyLayerWeight = Mathf.Max(0f, flyLayerWeight - Time.deltaTime * 0.28f);
timeSinceEnteringFlight += Time.deltaTime;
break;
case 1:
if (behaviourStateLastFrame != 1)
{
behaviourStateLastFrame = 1;
timeSinceEnteringFlight = 0f;
creatureAnimator.SetBool("gliding", value: true);
bodyAnimator.SetBool("flying", value: true);
int num = RoundManager.PlayRandomClip(creatureSFX, enemyType.audioClips);
WalkieTalkie.TransmitOneShotAudio(creatureSFX, enemyType.audioClips[num], 0.7f);
RoundManager.Instance.PlayAudibleNoise(base.transform.position, 12f, 0.6f, 0, noiseIsInsideClosedShip: false, 911);
glideTime = UnityEngine.Random.Range(8f, 20f);
}
timeSinceEnteringFlight += Time.deltaTime;
flyLayerWeight = Mathf.Min(1f, flyLayerWeight + Time.deltaTime * 0.33f);
break;
}
}
private void BirdScreech()
{
RoundManager.PlayRandomClip(creatureVoice, birdScreechSFX);
WalkieTalkie.TransmitOneShotAudio(creatureVoice, birdScreechSFX[UnityEngine.Random.Range(0, birdScreechSFX.Length)]);
RoundManager.Instance.PlayAudibleNoise(base.transform.position, 12f, 0.6f, 0, noiseIsInsideClosedShip: false, 911);
}
public void SetFlyDirection()
{
if (birdStunned)
{
Vector3 localEulerAngles = Body.localEulerAngles;
localEulerAngles.x = 0f;
localEulerAngles.z = 0f;
Body.localEulerAngles = localEulerAngles;
return;
}
bool flag = false;
flag = averageVelocity * speedElevationMultiplier < 12f;
float num = (Body.position - previousPosition).magnitude / Time.deltaTime;
if (daytimeEnemyLeaving)
{
Body.rotation = Quaternion.Lerp(Body.rotation, Quaternion.LookRotation(Body.position - previousPosition, Vector3.up), 5f * Time.deltaTime);
}
else if (currentBehaviourStateIndex == 0 || timeSinceEnteringFlight < 1f)
{
flag = false;
Body.rotation = Quaternion.Lerp(Body.rotation, Quaternion.Euler(new Vector3(0f, randomYRot, 0f)), 10f * Time.deltaTime);
}
else if (averageVelocity * speedElevationMultiplier > 0f)
{
Body.rotation = Quaternion.Lerp(Body.rotation, Quaternion.LookRotation(Body.position - previousPosition, Vector3.up), 5f * Time.deltaTime);
}
if (velocityInterval <= 0f)
{
velocityInterval = 0.1f;
velocityAverageCount++;
if (velocityAverageCount > 5)
{
averageVelocity += (num - averageVelocity) / 6f;
}
else
{
averageVelocity += num;
if (velocityAverageCount == 5)
{
averageVelocity /= velocityAverageCount;
}
}
}
else
{
velocityInterval -= Time.deltaTime;
}
creatureAnimator.SetBool("flapping", flag);
if (flag)
{
if (flappingAudio.volume <= 0.99f)
{
flappingAudio.volume = Mathf.Min(flappingAudio.volume + Time.deltaTime, 1f);
}
if (!flappingAudio.isPlaying)
{
flappingAudio.Play();
}
}
else if (flappingAudio.volume >= 0.05f)
{
flappingAudio.volume = Mathf.Max(flappingAudio.volume - Time.deltaTime, 0f);
}
else
{
flappingAudio.Stop();
}
lerpedElevation = Mathf.Lerp(lerpedElevation, averageVelocity * speedElevationMultiplier / maxSpeed, Time.deltaTime * 0.5f);
bodyAnimator.SetFloat("elevation", Mathf.Clamp(lerpedElevation * randomHeightOffset, 0.02f, 0.98f));
previousPosition = Body.position;
}
public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false)
{
base.HitEnemy(force, playerWhoHit, playHitSFX);
if (base.IsOwner)
{
KillEnemyOnOwnerClient();
}
}
public override void KillEnemy(bool destroy = false)
{
base.KillEnemy(destroy);
bodyAnimator.SetBool("stunned", value: true);
creatureAnimator.SetBool("dead", value: true);
}
public override void AnimationEventA()
{
base.AnimationEventA();
if (base.IsServer && timeSinceSquawking > 0.7f && UnityEngine.Random.Range(0, 100) < birdNoisiness)
{
timeSinceSquawking = 0f;
BirdScreechClientRpc();
}
}
[ClientRpc(Delivery = RpcDelivery.Unreliable)]
public void BirdScreechClientRpc()
{
NetworkManager networkManager = base.NetworkManager;
if ((object)networkManager != null && networkManager.IsListening)
{
if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
{
ClientRpcParams clientRpcParams = default(ClientRpcParams);
FastBufferWriter bufferWriter = __beginSendClientRpc(2325720037u, clientRpcParams, RpcDelivery.Unreliable);
__endSendClientRpc(ref bufferWriter, 2325720037u, clientRpcParams, RpcDelivery.Unreliable);
}
if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost))
{
BirdScreech();
}
}
}
public override void AnimationEventB()
{
base.AnimationEventB();
creatureSFX.PlayOneShot(birdHitGroundSFX);
}
protected override void __initializeVariables()
{
base.__initializeVariables();
}
[RuntimeInitializeOnLoadMethod]
internal static void InitializeRPCS_DoublewingAI()
{
NetworkManager.__rpc_func_table.Add(838150599u, __rpc_handler_838150599);
NetworkManager.__rpc_func_table.Add(3264241129u, __rpc_handler_3264241129);
NetworkManager.__rpc_func_table.Add(2325720037u, __rpc_handler_2325720037);
}
private static void __rpc_handler_838150599(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
{
NetworkManager networkManager = target.NetworkManager;
if ((object)networkManager != null && networkManager.IsListening)
{
target.__rpc_exec_stage = __RpcExecStage.Server;
((DoublewingAI)target).AlertBirdServerRpc();
target.__rpc_exec_stage = __RpcExecStage.None;
}
}
private static void __rpc_handler_3264241129(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
{
NetworkManager networkManager = target.NetworkManager;
if ((object)networkManager != null && networkManager.IsListening)
{
target.__rpc_exec_stage = __RpcExecStage.Client;
((DoublewingAI)target).AlertBirdClientRpc();
target.__rpc_exec_stage = __RpcExecStage.None;
}
}
private static void __rpc_handler_2325720037(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
{
NetworkManager networkManager = target.NetworkManager;
if ((object)networkManager != null && networkManager.IsListening)
{
target.__rpc_exec_stage = __RpcExecStage.Client;
((DoublewingAI)target).BirdScreechClientRpc();
target.__rpc_exec_stage = __RpcExecStage.None;
}
}
protected internal override string __getTypeName()
{
return "DoublewingAI";
}
}