LethalCompany/Lethal Company/ExportedProject/Assets/Scripts/Assembly-CSharp/DeadBodyInfo.cs
2023-12-22 18:30:10 -05:00

468 lines
12 KiB
C#

using GameNetcodeStuff;
using UnityEngine;
public class DeadBodyInfo : MonoBehaviour
{
public int playerObjectId;
public PlayerControllerB playerScript;
public Rigidbody[] bodyParts;
[Space(3f)]
public Rigidbody attachedLimb;
public Transform attachedTo;
[Space(2f)]
public Rigidbody secondaryAttachedLimb;
public Transform secondaryAttachedTo;
[Space(5f)]
public int timesOutOfBounds;
public Vector3 spawnPosition;
[Space(3f)]
private Vector3 forceDirection;
public float maxVelocity;
public float speedMultiplier;
public bool matchPositionExactly = true;
public bool wasMatchingPosition;
private Rigidbody previousAttachedLimb;
[Space(3f)]
public bool bodyBleedingHeavily = true;
private Vector3 previousBodyPosition;
private int bloodAmount;
private int maxBloodAmount = 30;
public GameObject[] bodyBloodDecals;
[Space(3f)]
private bool bodyMovedThisFrame;
private float syncBodyPositionTimer;
private bool serverSyncedPositionWithClients;
public bool seenByLocalPlayer;
public AudioSource bodyAudio;
private float velocityLastFrame;
public Transform radarDot;
private float timeSinceLastCollisionSFX;
public bool parentedToShip;
public bool detachedHead;
public Transform detachedHeadObject;
public Vector3 detachedHeadVelocity;
public ParticleSystem bloodSplashParticle;
public ParticleSystem beamUpParticle;
public AudioSource playAudioOnDeath;
public CauseOfDeath causeOfDeath;
private float resetBodyPartsTimer;
public GrabbableObject grabBodyObject;
private bool bodySetToKinematic;
public bool lerpBeforeMatchingPosition;
private float moveToExactPositionTimer;
public bool canBeGrabbedBackByPlayers;
public bool isInShip;
private void FloatBodyToWaterSurface()
{
for (int i = 0; i < bodyParts.Length; i++)
{
float num = playerScript.underwaterCollider.transform.position.y + playerScript.underwaterCollider.bounds.extents.y - bodyParts[i].transform.position.y;
bodyParts[i].AddForce(-Physics.gravity * num * 5f, ForceMode.Force);
bodyParts[i].drag = 2.5f;
bodyParts[i].useGravity = false;
}
}
private void StopFloatingBody()
{
playerScript.underwaterCollider = null;
for (int i = 0; i < bodyParts.Length; i++)
{
bodyParts[i].drag = 0f;
bodyParts[i].useGravity = true;
}
}
private void FixedUpdate()
{
if (!wasMatchingPosition && causeOfDeath == CauseOfDeath.Drowning && playerScript != null && playerScript.underwaterCollider != null && !isInShip)
{
FloatBodyToWaterSurface();
}
}
private void OnDestroy()
{
if (grabBodyObject != null)
{
grabBodyObject.grabbable = false;
}
}
private void Start()
{
spawnPosition = base.transform.position;
previousBodyPosition = Vector3.zero;
if (StartOfRound.Instance != null)
{
playerScript = StartOfRound.Instance.allPlayerScripts[playerObjectId];
base.gameObject.GetComponentInChildren<SkinnedMeshRenderer>().sharedMaterial = StartOfRound.Instance.unlockablesList.unlockables[playerScript.currentSuitID].suitMaterial;
for (int i = 0; i < playerScript.bodyParts.Length; i++)
{
bodyParts[i].position = playerScript.bodyParts[i].position;
}
}
if (detachedHead)
{
if (RoundManager.Instance != null && RoundManager.Instance.mapPropsContainer != null)
{
detachedHeadObject.SetParent(RoundManager.Instance.mapPropsContainer.transform);
}
detachedHeadObject.GetComponent<Rigidbody>().AddForce(detachedHeadVelocity * 350f, ForceMode.Impulse);
}
if (bloodSplashParticle != null)
{
ParticleSystem.MainModule main = bloodSplashParticle.main;
main.customSimulationSpace = RoundManager.Instance.mapPropsContainer.transform;
}
if ((bool)playAudioOnDeath)
{
playAudioOnDeath.Play();
WalkieTalkie.TransmitOneShotAudio(playAudioOnDeath, playAudioOnDeath.clip);
}
}
private void Update()
{
isInShip = parentedToShip || (grabBodyObject != null && grabBodyObject.isHeld && grabBodyObject.playerHeldBy != null && grabBodyObject.playerHeldBy.isInElevator);
if (attachedLimb != null && attachedTo != null && matchPositionExactly)
{
syncBodyPositionTimer = 5f;
ResetBodyPositionIfTooFarFromAttachment();
resetBodyPartsTimer += Time.deltaTime;
if (resetBodyPartsTimer >= 0.25f)
{
resetBodyPartsTimer = 0f;
EnableCollisionOnBodyParts();
}
}
if (GameNetworkManager.Instance == null || GameNetworkManager.Instance.localPlayerController == null)
{
return;
}
DetectIfSeenByLocalPlayer();
DetectBodyMovedDistanceThreshold();
if (bodyMovedThisFrame)
{
syncBodyPositionTimer = 5f;
Debug.Log("Body moved this frame");
if (bodyBleedingHeavily && bloodAmount < maxBloodAmount)
{
bloodAmount++;
playerScript.DropBlood(Vector3.down);
Debug.Log("Dropping blood");
}
}
if (attachedLimb != null && attachedTo != null)
{
syncBodyPositionTimer = 5f;
}
else if (GameNetworkManager.Instance.localPlayerController.IsOwnedByServer && !serverSyncedPositionWithClients)
{
if (syncBodyPositionTimer >= 0f)
{
syncBodyPositionTimer -= Time.deltaTime;
}
else
{
if (Physics.CheckSphere(base.transform.position, 30f, StartOfRound.Instance.playersMask))
{
for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
{
if (StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled && !Physics.Linecast(StartOfRound.Instance.allPlayerScripts[i].gameplayCamera.transform.position, base.transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
{
syncBodyPositionTimer = 0.3f;
return;
}
}
}
serverSyncedPositionWithClients = true;
playerScript.SyncBodyPositionWithClients();
}
}
if (timeSinceLastCollisionSFX <= 0.5f)
{
timeSinceLastCollisionSFX += Time.deltaTime;
return;
}
timeSinceLastCollisionSFX = 0f;
velocityLastFrame = bodyParts[5].velocity.sqrMagnitude;
}
public void DetectIfSeenByLocalPlayer()
{
if (seenByLocalPlayer)
{
return;
}
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
Rigidbody rigidbody = null;
float num = Vector3.Distance(localPlayerController.gameplayCamera.transform.position, base.transform.position);
for (int i = 0; i < bodyParts.Length; i++)
{
if (bodyParts[i] == rigidbody)
{
continue;
}
rigidbody = bodyParts[i];
if (localPlayerController.HasLineOfSightToPosition(bodyParts[i].transform.position, 30f / (num / 5f)))
{
if (num < 10f)
{
GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.9f);
}
else
{
GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.55f);
}
seenByLocalPlayer = true;
break;
}
}
}
private void LateUpdate()
{
radarDot.eulerAngles = new Vector3(0f, radarDot.eulerAngles.y, 0f);
if (attachedLimb == null || attachedTo == null || attachedTo.parent == base.transform)
{
if (grabBodyObject != null)
{
grabBodyObject.grabbable = true;
}
moveToExactPositionTimer = 0f;
if (wasMatchingPosition)
{
wasMatchingPosition = false;
if (StartOfRound.Instance.shipBounds.bounds.Contains(base.transform.position))
{
base.transform.SetParent(StartOfRound.Instance.elevatorTransform);
parentedToShip = true;
StopFloatingBody();
}
previousAttachedLimb.ResetCenterOfMass();
previousAttachedLimb.ResetInertiaTensor();
previousAttachedLimb.freezeRotation = false;
previousAttachedLimb.isKinematic = false;
EnableCollisionOnBodyParts();
}
return;
}
if (grabBodyObject != null)
{
grabBodyObject.grabbable = canBeGrabbedBackByPlayers;
}
if (parentedToShip)
{
parentedToShip = false;
base.transform.SetParent(null, worldPositionStays: true);
}
if (matchPositionExactly)
{
if (!lerpBeforeMatchingPosition || !(moveToExactPositionTimer < 0.3f))
{
if (!wasMatchingPosition)
{
wasMatchingPosition = true;
Vector3 vector = base.transform.position - attachedLimb.position;
base.transform.GetComponent<Rigidbody>().position = attachedTo.position + vector;
previousAttachedLimb = attachedLimb;
attachedLimb.freezeRotation = true;
attachedLimb.isKinematic = true;
attachedLimb.transform.position = attachedTo.position;
attachedLimb.transform.rotation = attachedTo.rotation;
for (int i = 0; i < bodyParts.Length; i++)
{
bodyParts[i].angularDrag = 1f;
bodyParts[i].maxAngularVelocity = 2f;
bodyParts[i].maxDepenetrationVelocity = 0.3f;
bodyParts[i].velocity = Vector3.zero;
bodyParts[i].angularVelocity = Vector3.zero;
bodyParts[i].WakeUp();
}
}
else
{
attachedLimb.position = attachedTo.position;
attachedLimb.rotation = attachedTo.rotation;
attachedLimb.centerOfMass = Vector3.zero;
attachedLimb.inertiaTensorRotation = Quaternion.identity;
}
return;
}
moveToExactPositionTimer += Time.deltaTime;
speedMultiplier = 25f;
}
forceDirection = Vector3.Normalize(attachedTo.position - attachedLimb.position);
attachedLimb.AddForce(forceDirection * speedMultiplier * Mathf.Clamp(Vector3.Distance(attachedTo.position, attachedLimb.position), 0.2f, 2.5f), ForceMode.VelocityChange);
if (attachedLimb.velocity.sqrMagnitude > maxVelocity)
{
attachedLimb.velocity = attachedLimb.velocity.normalized * maxVelocity;
}
if (!(secondaryAttachedLimb == null) && !(secondaryAttachedTo == null))
{
forceDirection = Vector3.Normalize(secondaryAttachedTo.position - secondaryAttachedLimb.position);
secondaryAttachedLimb.AddForce(forceDirection * speedMultiplier * Mathf.Clamp(Vector3.Distance(secondaryAttachedTo.position, secondaryAttachedLimb.position), 0.2f, 2.5f), ForceMode.VelocityChange);
if (secondaryAttachedLimb.velocity.sqrMagnitude > maxVelocity)
{
secondaryAttachedLimb.velocity = secondaryAttachedLimb.velocity.normalized * maxVelocity;
}
}
}
private void DetectBodyMovedDistanceThreshold()
{
bodyMovedThisFrame = false;
if (isInShip)
{
if (Vector3.Distance(previousBodyPosition, base.transform.localPosition) > 1f)
{
previousBodyPosition = base.transform.localPosition;
bodyMovedThisFrame = true;
}
}
else if (Vector3.Distance(previousBodyPosition, base.transform.position) > 1f)
{
previousBodyPosition = base.transform.position;
bodyMovedThisFrame = true;
}
}
private void ResetBodyPositionIfTooFarFromAttachment()
{
for (int i = 0; i < bodyParts.Length; i++)
{
if (Vector3.Distance(bodyParts[i].position, attachedTo.position) > 4f)
{
resetBodyPartsTimer = 0f;
bodyParts[i].GetComponent<Collider>().enabled = false;
}
}
}
private void EnableCollisionOnBodyParts()
{
for (int i = 0; i < bodyParts.Length; i++)
{
bodyParts[i].GetComponent<Collider>().enabled = true;
}
}
public void MakeCorpseBloody()
{
for (int i = 0; i < bodyBloodDecals.Length; i++)
{
bodyBloodDecals[i].SetActive(value: true);
}
}
public void SetBodyPartsKinematic(bool setKinematic = true)
{
if (setKinematic)
{
bodySetToKinematic = true;
for (int i = 0; i < bodyParts.Length; i++)
{
bodyParts[i].velocity = Vector3.zero;
bodyParts[i].isKinematic = true;
}
return;
}
for (int j = 0; j < bodyParts.Length; j++)
{
bodyParts[j].velocity = Vector3.zero;
if (!(bodyParts[j] == attachedLimb) || !matchPositionExactly)
{
bodyParts[j].isKinematic = false;
}
}
}
public void ResetRagdollPosition()
{
if (attachedLimb != null && attachedTo != null)
{
base.transform.position = attachedTo.position + Vector3.up * 2f;
}
else
{
base.transform.position = spawnPosition;
}
for (int i = 0; i < bodyParts.Length; i++)
{
bodyParts[i].velocity = Vector3.zero;
bodyParts[i].GetComponent<Collider>().enabled = false;
}
}
public void SetRagdollPositionSafely(Vector3 newPosition, bool disableSpecialEffects = false)
{
base.transform.position = newPosition + Vector3.up * 2.5f;
if (disableSpecialEffects)
{
StopFloatingBody();
}
for (int i = 0; i < bodyParts.Length; i++)
{
bodyParts[i].velocity = Vector3.zero;
}
timeSinceLastCollisionSFX = -1f;
}
public void AddForceToBodyPart(int bodyPartIndex, Vector3 force)
{
bodyParts[bodyPartIndex].AddForce(force, ForceMode.Impulse);
}
public void ChangeMesh(Mesh changeMesh, Material changeMaterial = null)
{
base.gameObject.GetComponentInChildren<SkinnedMeshRenderer>().sharedMesh = changeMesh;
if (changeMaterial != null)
{
base.gameObject.GetComponentInChildren<SkinnedMeshRenderer>().sharedMaterial = changeMaterial;
}
}
}