using System.Collections.Generic; using Rewired; using UnityEngine; using UnityEngine.Events; public class ManualAttack : MonoBehaviour { public float spawnAttackHeight; public List targetPriorities = new List(); public Weapon weapon; public float cooldownTime = 1f; public Transform transformForAttackDirection; public Transform attackMarkerPosition; public Transform preferredTargetMarkerPosition; public bool autoAttack = true; public ParticleSystem particlesOnAttack; public bool playOneShotOnAttack; public ThronefallAudioManager.AudioOneShot oneshotOnAttack; protected float cooldown; protected float inputBuffer = -1f; protected bool isAttacking; protected Hp hpPlayer; private Player input; protected TaggedObject myTaggedObj; private DayNightCycle dayNightCycle; private PlayerUpgradeManager upgradeManager; private Vector3 lastTargetPos; [HideInInspector] public UnityEvent onAttack = new UnityEvent(); protected AudioSet audioSet; private AudioSet.ClipArray caStillOnCooldown; private AudioSet.ClipArray caCooldownOver; protected ThronefallAudioManager audioManager; private bool timedActivationPerfectly; protected TaggedObject preferredTarget; protected TaggedObject target; private float perfectTimingDeniedFor; public float AttackDamageMultiplyer => upgradeManager.playerDamageMultiplyer; public Vector3 LastTargetPos => lastTargetPos; public float CooldownPercentage => Mathf.Clamp01(cooldown / cooldownTime); public virtual void Start() { upgradeManager = PlayerUpgradeManager.instance; hpPlayer = GetComponentInParent(); input = ReInput.players.GetPlayer(0); myTaggedObj = GetComponentInParent(); dayNightCycle = DayNightCycle.Instance; audioSet = ThronefallAudioManager.Instance.audioContent; audioManager = ThronefallAudioManager.Instance; caStillOnCooldown = audioSet.PlayerCantUseActiveAbility; caCooldownOver = audioSet.ActiveAbilityCooldownReadyToUse; } public virtual void Update() { if (autoAttack && hpPlayer.HpValue > 0f) { Tick(); } } public void Tick() { float num = cooldown; cooldown -= Time.deltaTime; if (upgradeManager.assassinsTraining && timedActivationPerfectly) { cooldown -= Time.deltaTime * UpgradeAssassinsTraining.instance.additionalCooldownSpeed; } if (num > 0f && cooldown <= 0f && !autoAttack && DayNightCycle.Instance.CurrentTimestate == DayNightCycle.Timestate.Night) { audioManager.PlaySoundAsOneShot(caCooldownOver, 1f, 1f, audioSet.mixGroupFX, 5); } isAttacking = false; HandleAttackUpdate(); inputBuffer -= Time.deltaTime; perfectTimingDeniedFor -= Time.deltaTime; if ((bool)attackMarkerPosition) { if (autoAttack || cooldown <= 0f) { target = FindAttackTarget(_choosePreferredTargetIfPossible: true); if (target == null) { attackMarkerPosition.gameObject.SetActive(value: false); } else { if (autoAttack) { inputBuffer = 0.2f; isAttacking = true; } attackMarkerPosition.gameObject.SetActive(value: true); attackMarkerPosition.position = target.transform.position; } } else { attackMarkerPosition.gameObject.SetActive(value: false); } } if (input.GetButtonDown("Lock Target")) { TaggedObject taggedObject = FindAttackTarget(); if (preferredTarget == null) { preferredTarget = taggedObject; if ((bool)taggedObject && upgradeManager.godlyCurse && (bool)preferredTargetMarkerPosition) { taggedObject.GetComponent().ScaleHp(1f / upgradeManager.godlyCurseDamageMultiplyer); } } else { if (upgradeManager.godlyCurse && (bool)preferredTargetMarkerPosition) { taggedObject.GetComponent().ScaleHp(upgradeManager.godlyCurseDamageMultiplyer); } preferredTarget = null; } } if ((bool)preferredTargetMarkerPosition) { if ((bool)preferredTarget) { preferredTargetMarkerPosition.gameObject.SetActive(value: true); preferredTargetMarkerPosition.position = preferredTarget.transform.position; } else { preferredTargetMarkerPosition.gameObject.SetActive(value: false); } } } public void TryToAttack() { if (dayNightCycle.CurrentTimestate == DayNightCycle.Timestate.Day && !autoAttack) { return; } if (upgradeManager.assassinsTraining && perfectTimingDeniedFor <= 0f) { timedActivationPerfectly = Mathf.Abs(cooldown) < UpgradeAssassinsTraining.instance.activationWindow; if (!timedActivationPerfectly) { perfectTimingDeniedFor = 2f; } } inputBuffer = 0.2f; isAttacking = true; } public void HandleAttackUpdate() { if (!(inputBuffer >= 0f)) { return; } if (cooldown > 0f) { if (!autoAttack && cooldown > inputBuffer) { audioManager.PlaySoundAsOneShot(caStillOnCooldown, 1f, Random.Range(1.8f, 2.2f), audioSet.mixGroupFX, 5); inputBuffer = -1f; } } else { inputBuffer = -1f; isAttacking = true; cooldown = cooldownTime; Attack(); } } public virtual void Attack() { if ((bool)particlesOnAttack) { particlesOnAttack.Play(); } if (playOneShotOnAttack) { ThronefallAudioManager.Oneshot(oneshotOnAttack); } TaggedObject taggedObject = FindAttackTarget(_choosePreferredTargetIfPossible: true); Hp hp = null; if ((bool)taggedObject) { hp = taggedObject.Hp; lastTargetPos = taggedObject.transform.position; weapon.Attack(base.transform.position + spawnAttackHeight * Vector3.up, hp, transformForAttackDirection.forward, myTaggedObj, AttackDamageMultiplyer); onAttack.Invoke(); } } protected TaggedObject FindAttackTarget(bool _choosePreferredTargetIfPossible = false) { if (_choosePreferredTargetIfPossible && (bool)preferredTarget && TagManager.instance.MeasureDistanceToTaggedObject(preferredTarget, base.transform.position) <= targetPriorities[0].range) { return preferredTarget; } for (int i = 0; i < targetPriorities.Count; i++) { TaggedObject taggedObject = targetPriorities[i].FindClosestTaggedObject(base.transform.position); if (taggedObject != null) { return taggedObject; } } return null; } }