using System.Collections; using GameNetcodeStuff; using Unity.Netcode; using UnityEngine; public class ShotgunItem : GrabbableObject { public int gunCompatibleAmmoID = 1410; public bool isReloading; public int shellsLoaded; public Animator gunAnimator; public AudioSource gunAudio; public AudioSource gunShootAudio; public AudioSource gunBulletsRicochetAudio; private Coroutine gunCoroutine; public AudioClip[] gunShootSFX; public AudioClip gunReloadSFX; public AudioClip gunReloadFinishSFX; public AudioClip noAmmoSFX; public AudioClip gunSafetySFX; public AudioClip switchSafetyOnSFX; public AudioClip switchSafetyOffSFX; public bool safetyOn; private float misfireTimer = 30f; private bool hasHitGroundWithSafetyOff = true; private int ammoSlotToUse = -1; private bool localClientSendingShootGunRPC; private PlayerControllerB previousPlayerHeldBy; public ParticleSystem gunShootParticle; public Transform shotgunRayPoint; public MeshRenderer shotgunShellLeft; public MeshRenderer shotgunShellRight; public MeshRenderer shotgunShellInHand; public Transform shotgunShellInHandTransform; private RaycastHit[] enemyColliders; private EnemyAI heldByEnemy; public override void Start() { base.Start(); misfireTimer = 30f; hasHitGroundWithSafetyOff = true; } public override int GetItemDataToSave() { base.GetItemDataToSave(); return shellsLoaded; } public override void LoadItemSaveData(int saveData) { base.LoadItemSaveData(saveData); safetyOn = true; shellsLoaded = saveData; } public override void Update() { base.Update(); if (!base.IsOwner || shellsLoaded <= 0 || isReloading || heldByEnemy != null || isPocketed) { return; } if (hasHitGround && !safetyOn && !hasHitGroundWithSafetyOff && !isHeld) { if (Random.Range(0, 100) < 5) { ShootGunAndSync(heldByPlayer: false); } hasHitGroundWithSafetyOff = true; } else if (!safetyOn && misfireTimer <= 0f && !StartOfRound.Instance.inShipPhase) { if (Random.Range(0, 100) < 4) { ShootGunAndSync(isHeld); } if (Random.Range(0, 100) < 5) { misfireTimer = 2f; } else { misfireTimer = Random.Range(28f, 50f); } } else if (!safetyOn) { misfireTimer -= Time.deltaTime; } } public override void EquipItem() { base.EquipItem(); previousPlayerHeldBy = playerHeldBy; previousPlayerHeldBy.equippedUsableItemQE = true; hasHitGroundWithSafetyOff = false; } public override void GrabItemFromEnemy(EnemyAI enemy) { base.GrabItemFromEnemy(enemy); heldByEnemy = enemy; hasHitGroundWithSafetyOff = false; } public override void DiscardItemFromEnemy() { base.DiscardItemFromEnemy(); heldByEnemy = null; } public override void ItemActivate(bool used, bool buttonDown = true) { base.ItemActivate(used, buttonDown); if (!isReloading) { if (shellsLoaded == 0) { StartReloadGun(); } else if (safetyOn) { gunAudio.PlayOneShot(gunSafetySFX); } else if (base.IsOwner) { ShootGunAndSync(heldByPlayer: true); } } } public void ShootGunAndSync(bool heldByPlayer) { Vector3 shotgunPosition; Vector3 forward; if (!heldByPlayer) { shotgunPosition = shotgunRayPoint.position; forward = shotgunRayPoint.forward; } else { shotgunPosition = GameNetworkManager.Instance.localPlayerController.gameplayCamera.transform.position - GameNetworkManager.Instance.localPlayerController.gameplayCamera.transform.up * 0.45f; forward = GameNetworkManager.Instance.localPlayerController.gameplayCamera.transform.forward; } Debug.Log("Calling shoot gun...."); ShootGun(shotgunPosition, forward); Debug.Log("Calling shoot gun and sync"); localClientSendingShootGunRPC = true; ShootGunServerRpc(shotgunPosition, forward); } [ServerRpc(RequireOwnership = false)] public void ShootGunServerRpc(Vector3 shotgunPosition, Vector3 shotgunForward) { 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(1329927282u, serverRpcParams, RpcDelivery.Reliable); bufferWriter.WriteValueSafe(in shotgunPosition); bufferWriter.WriteValueSafe(in shotgunForward); __endSendServerRpc(ref bufferWriter, 1329927282u, serverRpcParams, RpcDelivery.Reliable); } if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost)) { ShootGunClientRpc(shotgunPosition, shotgunForward); } } } [ClientRpc] public void ShootGunClientRpc(Vector3 shotgunPosition, Vector3 shotgunForward) { NetworkManager networkManager = base.NetworkManager; if ((object)networkManager == null || !networkManager.IsListening) { return; } if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams clientRpcParams = default(ClientRpcParams); FastBufferWriter bufferWriter = __beginSendClientRpc(4176294522u, clientRpcParams, RpcDelivery.Reliable); bufferWriter.WriteValueSafe(in shotgunPosition); bufferWriter.WriteValueSafe(in shotgunForward); __endSendClientRpc(ref bufferWriter, 4176294522u, clientRpcParams, RpcDelivery.Reliable); } if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost)) { Debug.Log("Shoot gun client rpc received"); if (localClientSendingShootGunRPC) { localClientSendingShootGunRPC = false; Debug.Log("localClientSendingShootGunRPC was true"); } else { ShootGun(shotgunPosition, shotgunForward); } } } public void ShootGun(Vector3 shotgunPosition, Vector3 shotgunForward) { isReloading = false; bool flag = false; if (isHeld && playerHeldBy != null && playerHeldBy == GameNetworkManager.Instance.localPlayerController) { playerHeldBy.playerBodyAnimator.SetTrigger("ShootShotgun"); flag = true; } RoundManager.PlayRandomClip(gunShootAudio, gunShootSFX, randomize: true, 1f, 1840); WalkieTalkie.TransmitOneShotAudio(gunShootAudio, gunShootSFX[0]); gunShootParticle.Play(withChildren: true); shellsLoaded = Mathf.Clamp(shellsLoaded - 1, 0, 2); PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if (localPlayerController == null) { return; } float num = Vector3.Distance(localPlayerController.transform.position, shotgunRayPoint.transform.position); bool flag2 = false; int num2 = 0; float num3 = 0f; Vector3 vector = localPlayerController.playerCollider.ClosestPoint(shotgunPosition); if (!flag && !Physics.Linecast(shotgunPosition, vector, StartOfRound.Instance.collidersAndRoomMaskAndDefault, QueryTriggerInteraction.Ignore) && Vector3.Angle(shotgunForward, vector - shotgunPosition) < 30f) { flag2 = true; } if (num < 5f) { num3 = 0.8f; HUDManager.Instance.ShakeCamera(ScreenShakeType.Big); num2 = 100; } if (num < 15f) { num3 = 0.5f; HUDManager.Instance.ShakeCamera(ScreenShakeType.Big); num2 = 100; } else if (num < 23f) { HUDManager.Instance.ShakeCamera(ScreenShakeType.Small); num2 = 40; } else if (num < 30f) { num2 = 20; } if (num3 > 0f && SoundManager.Instance.timeSinceEarsStartedRinging > 16f) { StartCoroutine(delayedEarsRinging(num3)); } Ray ray = new Ray(shotgunPosition, shotgunForward); if (Physics.Raycast(ray, out var hitInfo, 30f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, QueryTriggerInteraction.Ignore)) { gunBulletsRicochetAudio.transform.position = ray.GetPoint(hitInfo.distance - 0.5f); gunBulletsRicochetAudio.Play(); } if (flag2) { Debug.Log($"Dealing {num2} damage to player"); localPlayerController.DamagePlayer(num2, hasDamageSFX: true, callRPC: true, CauseOfDeath.Gunshots, 0, fallDamage: false, shotgunRayPoint.forward * 30f); } if (enemyColliders == null) { enemyColliders = new RaycastHit[10]; } ray = new Ray(shotgunPosition - shotgunForward * 10f, shotgunForward); int num4 = Physics.SphereCastNonAlloc(ray, 5f, enemyColliders, 15f, 524288, QueryTriggerInteraction.Collide); Debug.Log($"Enemies hit: {num4}"); for (int i = 0; i < num4; i++) { Debug.Log("Raycasting enemy"); if (!enemyColliders[i].transform.GetComponent()) { break; } EnemyAI mainScript = enemyColliders[i].transform.GetComponent().mainScript; if (heldByEnemy != null && heldByEnemy == mainScript) { Debug.Log("Shotgun is held by enemy, skipping enemy raycast"); break; } if (enemyColliders[i].distance == 0f) { Debug.Log("Spherecast started inside enemy collider"); break; } IHittable component; if (Physics.Linecast(shotgunPosition, enemyColliders[i].point, out hitInfo, StartOfRound.Instance.collidersAndRoomMaskAndDefault, QueryTriggerInteraction.Ignore)) { Debug.DrawRay(hitInfo.point, Vector3.up, Color.red, 15f); Debug.DrawLine(shotgunPosition, enemyColliders[i].point, Color.cyan, 15f); Debug.Log("Raycast hit wall"); } else if (enemyColliders[i].transform.TryGetComponent(out component)) { float num5 = Vector3.Distance(shotgunPosition, enemyColliders[i].point); int num6 = ((num5 < 3.7f) ? 5 : ((!(num5 < 6f)) ? 2 : 3)); Debug.Log($"Hit enemy, hitDamage: {num6}"); component.Hit(num6, shotgunForward, playerHeldBy, playHitSFX: true); } else { Debug.Log("Could not get hittable script from collider, transform: " + enemyColliders[i].transform.name); Debug.Log("collider: " + enemyColliders[i].collider.name); } } } private IEnumerator delayedEarsRinging(float effectSeverity) { yield return new WaitForSeconds(0.6f); SoundManager.Instance.earsRingingTimer = effectSeverity; } public override void ItemInteractLeftRight(bool right) { base.ItemInteractLeftRight(right); if (playerHeldBy == null) { return; } Debug.Log($"r/l activate: {right}"); if (!right) { if (safetyOn) { safetyOn = false; gunAudio.PlayOneShot(switchSafetyOffSFX); WalkieTalkie.TransmitOneShotAudio(gunAudio, switchSafetyOffSFX); SetSafetyControlTip(); } else { safetyOn = true; gunAudio.PlayOneShot(switchSafetyOnSFX); WalkieTalkie.TransmitOneShotAudio(gunAudio, switchSafetyOnSFX); SetSafetyControlTip(); } playerHeldBy.playerBodyAnimator.SetTrigger("SwitchGunSafety"); } else if (!isReloading && shellsLoaded < 2) { StartReloadGun(); } } public override void SetControlTipsForItem() { string[] toolTips = itemProperties.toolTips; if (toolTips.Length <= 2) { Debug.LogError("Shotgun control tips array length is too short to set tips!"); return; } if (safetyOn) { toolTips[2] = "Turn safety off: [Q]"; } else { toolTips[2] = "Turn safety on: [Q]"; } HUDManager.Instance.ChangeControlTipMultiple(toolTips, holdingItem: true, itemProperties); } private void SetSafetyControlTip() { string changeTo = ((!safetyOn) ? "Turn safety on: [Q]" : "Turn safety off: [Q]"); if (base.IsOwner) { HUDManager.Instance.ChangeControlTip(3, changeTo); } } private void StartReloadGun() { if (ReloadedGun()) { if (base.IsOwner) { if (gunCoroutine != null) { StopCoroutine(gunCoroutine); } gunCoroutine = StartCoroutine(reloadGunAnimation()); } } else { gunAudio.PlayOneShot(noAmmoSFX); } } [ServerRpc] public void ReloadGunEffectsServerRpc(bool start = true) { NetworkManager networkManager = base.NetworkManager; if ((object)networkManager == null || !networkManager.IsListening) { return; } if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost)) { if (base.OwnerClientId != networkManager.LocalClientId) { if (networkManager.LogLevel <= LogLevel.Normal) { Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!"); } return; } ServerRpcParams serverRpcParams = default(ServerRpcParams); FastBufferWriter bufferWriter = __beginSendServerRpc(3349119596u, serverRpcParams, RpcDelivery.Reliable); bufferWriter.WriteValueSafe(in start, default(FastBufferWriter.ForPrimitives)); __endSendServerRpc(ref bufferWriter, 3349119596u, serverRpcParams, RpcDelivery.Reliable); } if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost)) { ReloadGunEffectsClientRpc(start); } } [ClientRpc] public void ReloadGunEffectsClientRpc(bool start = true) { NetworkManager networkManager = base.NetworkManager; if ((object)networkManager == null || !networkManager.IsListening) { return; } if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams clientRpcParams = default(ClientRpcParams); FastBufferWriter bufferWriter = __beginSendClientRpc(2673645315u, clientRpcParams, RpcDelivery.Reliable); bufferWriter.WriteValueSafe(in start, default(FastBufferWriter.ForPrimitives)); __endSendClientRpc(ref bufferWriter, 2673645315u, clientRpcParams, RpcDelivery.Reliable); } if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost) && !base.IsOwner) { if (start) { gunAudio.PlayOneShot(gunReloadSFX); WalkieTalkie.TransmitOneShotAudio(gunAudio, gunReloadSFX); gunAnimator.SetBool("Reloading", value: true); isReloading = true; } else { shellsLoaded = Mathf.Clamp(shellsLoaded + 1, 0, 2); gunAudio.PlayOneShot(gunReloadFinishSFX); gunAnimator.SetBool("Reloading", value: false); isReloading = false; } } } private IEnumerator reloadGunAnimation() { isReloading = true; if (shellsLoaded <= 0) { playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun", value: true); shotgunShellLeft.enabled = false; shotgunShellRight.enabled = false; } else { playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun2", value: true); shotgunShellRight.enabled = false; } yield return new WaitForSeconds(0.3f); gunAudio.PlayOneShot(gunReloadSFX); gunAnimator.SetBool("Reloading", value: true); ReloadGunEffectsServerRpc(); yield return new WaitForSeconds(0.95f); shotgunShellInHand.enabled = true; shotgunShellInHandTransform.SetParent(playerHeldBy.leftHandItemTarget); shotgunShellInHandTransform.localPosition = new Vector3(-0.0555f, 0.1469f, -0.0655f); shotgunShellInHandTransform.localEulerAngles = new Vector3(-1.956f, 143.856f, -16.427f); yield return new WaitForSeconds(0.95f); playerHeldBy.DestroyItemInSlotAndSync(ammoSlotToUse); ammoSlotToUse = -1; shellsLoaded = Mathf.Clamp(shellsLoaded + 1, 0, 2); shotgunShellLeft.enabled = true; if (shellsLoaded == 2) { shotgunShellRight.enabled = true; } shotgunShellInHand.enabled = false; shotgunShellInHandTransform.SetParent(base.transform); yield return new WaitForSeconds(0.45f); gunAudio.PlayOneShot(gunReloadFinishSFX); gunAnimator.SetBool("Reloading", value: false); playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun", value: false); playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun2", value: false); isReloading = false; ReloadGunEffectsServerRpc(start: false); } private bool ReloadedGun() { int num = FindAmmoInInventory(); if (num == -1) { Debug.Log("not reloading"); return false; } Debug.Log("reloading!"); ammoSlotToUse = num; return true; } private int FindAmmoInInventory() { for (int i = 0; i < playerHeldBy.ItemSlots.Length; i++) { if (!(playerHeldBy.ItemSlots[i] == null)) { GunAmmo gunAmmo = playerHeldBy.ItemSlots[i] as GunAmmo; Debug.Log($"Ammo null in slot #{i}?: {gunAmmo == null}"); if (gunAmmo != null) { Debug.Log($"Ammo in slot #{i} id: {gunAmmo.ammoType}"); } if (gunAmmo != null && gunAmmo.ammoType == gunCompatibleAmmoID) { return i; } } } return -1; } public override void PocketItem() { base.PocketItem(); StopUsingGun(); } public override void DiscardItem() { base.DiscardItem(); StopUsingGun(); } private void StopUsingGun() { previousPlayerHeldBy.equippedUsableItemQE = false; if (isReloading) { if (gunCoroutine != null) { StopCoroutine(gunCoroutine); } gunAnimator.SetBool("Reloading", value: false); gunAudio.Stop(); if (previousPlayerHeldBy != null) { previousPlayerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun", value: false); previousPlayerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun2", value: false); } shotgunShellInHand.enabled = false; shotgunShellInHandTransform.SetParent(base.transform); isReloading = false; } } protected override void __initializeVariables() { base.__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_ShotgunItem() { NetworkManager.__rpc_func_table.Add(1329927282u, __rpc_handler_1329927282); NetworkManager.__rpc_func_table.Add(4176294522u, __rpc_handler_4176294522); NetworkManager.__rpc_func_table.Add(3349119596u, __rpc_handler_3349119596); NetworkManager.__rpc_func_table.Add(2673645315u, __rpc_handler_2673645315); } private static void __rpc_handler_1329927282(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { NetworkManager networkManager = target.NetworkManager; if ((object)networkManager != null && networkManager.IsListening) { reader.ReadValueSafe(out Vector3 value); reader.ReadValueSafe(out Vector3 value2); target.__rpc_exec_stage = __RpcExecStage.Server; ((ShotgunItem)target).ShootGunServerRpc(value, value2); target.__rpc_exec_stage = __RpcExecStage.None; } } private static void __rpc_handler_4176294522(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { NetworkManager networkManager = target.NetworkManager; if ((object)networkManager != null && networkManager.IsListening) { reader.ReadValueSafe(out Vector3 value); reader.ReadValueSafe(out Vector3 value2); target.__rpc_exec_stage = __RpcExecStage.Client; ((ShotgunItem)target).ShootGunClientRpc(value, value2); target.__rpc_exec_stage = __RpcExecStage.None; } } private static void __rpc_handler_3349119596(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { NetworkManager networkManager = target.NetworkManager; if ((object)networkManager == null || !networkManager.IsListening) { return; } if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId) { if (networkManager.LogLevel <= LogLevel.Normal) { Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!"); } } else { reader.ReadValueSafe(out bool value, default(FastBufferWriter.ForPrimitives)); target.__rpc_exec_stage = __RpcExecStage.Server; ((ShotgunItem)target).ReloadGunEffectsServerRpc(value); target.__rpc_exec_stage = __RpcExecStage.None; } } private static void __rpc_handler_2673645315(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { NetworkManager networkManager = target.NetworkManager; if ((object)networkManager != null && networkManager.IsListening) { reader.ReadValueSafe(out bool value, default(FastBufferWriter.ForPrimitives)); target.__rpc_exec_stage = __RpcExecStage.Client; ((ShotgunItem)target).ReloadGunEffectsClientRpc(value); target.__rpc_exec_stage = __RpcExecStage.None; } } protected internal override string __getTypeName() { return "ShotgunItem"; } }