diff options
author | chai <215380520@qq.com> | 2023-10-27 11:05:14 +0800 |
---|---|---|
committer | chai <215380520@qq.com> | 2023-10-27 11:05:14 +0800 |
commit | 766cdff5ffa72b65d7f106658d1603f47739b2ba (patch) | |
tree | 34d7799a94dfa9be182825577583c0fa6dc935f7 /GameCode/HealthHandler.cs |
+ init
Diffstat (limited to 'GameCode/HealthHandler.cs')
-rw-r--r-- | GameCode/HealthHandler.cs | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/GameCode/HealthHandler.cs b/GameCode/HealthHandler.cs new file mode 100644 index 0000000..bbc739f --- /dev/null +++ b/GameCode/HealthHandler.cs @@ -0,0 +1,362 @@ +using System; +using System.Collections; +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class HealthHandler : Damagable +{ + [Header("Sounds")] + public SoundEvent soundDie; + + public SoundEvent soundHeal; + + public SoundEvent soundDamagePassive; + + public SoundEvent soundDamageLifeSteal; + + public SoundEvent soundBounce; + + [Header("Settings")] + public SpriteRenderer hpSprite; + + public GameObject deathEffect; + + public float regeneration; + + private CharacterData data; + + private CodeAnimation anim; + + private Player player; + + private CharacterStatModifiers stats; + + public ParticleSystem healPart; + + private DamageOverTime dot; + + private Vector3 startHealthSpriteScale; + + public float flyingFor; + + private float lastDamaged; + + public Action delayedReviveAction; + + public Action reviveAction; + + [HideInInspector] + public bool DestroyOnDeath; + + public bool isRespawning; + + public GameObject deathEffectPhoenix; + + private void Awake() + { + dot = GetComponent<DamageOverTime>(); + data = GetComponent<CharacterData>(); + anim = GetComponentInChildren<CodeAnimation>(); + player = GetComponent<Player>(); + stats = GetComponent<CharacterStatModifiers>(); + } + + private void Start() + { + startHealthSpriteScale = hpSprite.transform.localScale; + } + + private void Update() + { + flyingFor -= TimeHandler.deltaTime; + if (regeneration > 0f) + { + Heal(regeneration * TimeHandler.deltaTime); + } + } + + public void Heal(float healAmount) + { + if (healAmount != 0f && data.health != data.maxHealth) + { + SoundManager.Instance.Play(soundHeal, base.transform); + data.health += healAmount; + data.health = Mathf.Clamp(data.health, float.NegativeInfinity, data.maxHealth); + healPart.Emit((int)Mathf.Clamp(healAmount * 0.2f, 1f, 10f)); + } + } + + public void CallTakeForce(Vector2 force, ForceMode2D forceMode = ForceMode2D.Impulse, bool forceIgnoreMass = false, bool ignoreBlock = false, float setFlying = 0f) + { + if (data.isPlaying && (!data.block.IsBlocking() || ignoreBlock)) + { + data.view.RPC("RPCA_SendTakeForce", RpcTarget.All, force, (int)forceMode, forceIgnoreMass, true, setFlying); + } + } + + [PunRPC] + public void RPCA_SendTakeForce(Vector2 force, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false, float setFlying = 0f) + { + TakeForce(force, (ForceMode2D)forceMode, forceIgnoreMass, ignoreBlock, setFlying); + data.GetComponent<SyncPlayerMovement>().SetDontSyncFor((float)PhotonNetwork.GetPing() * 0.001f + 0.2f); + } + + [PunRPC] + public void RPCA_SendForceOverTime(Vector2 force, float time, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false) + { + StartCoroutine(IForceOverTime(force, time, forceMode, forceIgnoreMass, ignoreBlock)); + } + + private IEnumerator IForceOverTime(Vector2 force, float time, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false) + { + for (float i = 0f; i < time; i += TimeHandler.deltaTime) + { + TakeForce(force, (ForceMode2D)forceMode, forceIgnoreMass, ignoreBlock); + data.GetComponent<SyncPlayerMovement>().SetDontSyncFor((float)PhotonNetwork.GetPing() * 0.001f + 0.2f); + yield return new WaitForFixedUpdate(); + } + } + + [PunRPC] + public void RPCA_SendForceTowardsPointOverTime(float force, float drag, float clampDistancce, Vector2 point, float time, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false) + { + StartCoroutine(IForceTowardsPointOverTime(force, drag, clampDistancce, point, time, forceMode, forceIgnoreMass, ignoreBlock)); + } + + private IEnumerator IForceTowardsPointOverTime(float force, float drag, float clampDistancce, Vector2 point, float time, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false) + { + for (float i = 0f; i < time; i += TimeHandler.fixedDeltaTime) + { + Vector2 vector = point - (Vector2)base.transform.position; + vector = Vector2.ClampMagnitude(vector, clampDistancce); + Vector2 vector2 = data.playerVel.velocity * (0f - drag) * TimeHandler.fixedDeltaTime; + TakeForce(force * vector + vector2 * drag * TimeHandler.timeScale, (ForceMode2D)forceMode, forceIgnoreMass, ignoreBlock); + data.GetComponent<SyncPlayerMovement>().SetDontSyncFor((float)PhotonNetwork.GetPing() * 0.001f + 0.2f); + yield return new WaitForFixedUpdate(); + } + } + + public void TakeForce(Vector2 force, ForceMode2D forceMode = ForceMode2D.Impulse, bool forceIgnoreMass = false, bool ignoreBlock = false, float setFlying = 0f) + { + if (!data.isPlaying || !data.playerVel.simulated) + { + return; + } + bool flag = data.block.IsBlocking(); + if (flag && !ignoreBlock) + { + return; + } + if (!flag) + { + if (setFlying > flyingFor && setFlying > 0.25f) + { + flyingFor = setFlying; + SoundManager.Instance.Play(soundBounce, base.transform); + } + } + if (forceIgnoreMass) + { + force *= data.playerVel.mass / 100f; + } + data.playerVel.AddForce(force, forceMode); + if (force.y > 0f) + { + if (!forceIgnoreMass) + { + force.y /= data.playerVel.mass / 100f; + } + if (forceMode == ForceMode2D.Force) + { + force *= 0.003f; + } + data.sinceGrounded -= force.y * 0.003f; + } + data.sinceGrounded = Mathf.Clamp(data.sinceGrounded, -0.5f, 100f); + } + + public override void CallTakeDamage(Vector2 damage, Vector2 position, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true) + { + if (!(damage == Vector2.zero) && !data.block.IsBlocking()) + { + data.view.RPC("RPCA_SendTakeDamage", RpcTarget.All, damage, position, lethal, (damagingPlayer != null) ? damagingPlayer.playerID : (-1)); + } + } + + [PunRPC] + public void RPCA_SendTakeDamage(Vector2 damage, Vector2 position, bool lethal = true, int playerID = -1) + { + if (!(damage == Vector2.zero)) + { + Player playerWithID = PlayerManager.instance.GetPlayerWithID(playerID); + GameObject damagingWeapon = null; + if ((bool)playerWithID) + { + damagingWeapon = playerWithID.data.weaponHandler.gun.gameObject; + } + TakeDamage(damage, position, damagingWeapon, playerWithID, lethal, ignoreBlock: true); + } + } + + public override void TakeDamage(Vector2 damage, Vector2 position, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) + { + if (!(damage == Vector2.zero)) + { + TakeDamage(damage, position, Color.white * 0.85f, damagingWeapon, damagingPlayer, lethal, ignoreBlock); + } + } + + public override void TakeDamage(Vector2 damage, Vector2 position, Color dmgColor, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) + { + if (!(damage == Vector2.zero) && data.isPlaying && data.playerVel.simulated && !data.dead && (!data.block.IsBlocking() || ignoreBlock)) + { + if (dmgColor == Color.black) + { + dmgColor = Color.white * 0.85f; + } + if (stats.secondsToTakeDamageOver == 0f) + { + DoDamage(damage, position, dmgColor, damagingWeapon, damagingPlayer, healthRemoval: false, lethal, ignoreBlock); + } + else + { + TakeDamageOverTime(damage, position, stats.secondsToTakeDamageOver, 0.25f, dmgColor, damagingWeapon, damagingPlayer, lethal); + } + } + } + + public void DoDamage(Vector2 damage, Vector2 position, Color blinkColor, GameObject damagingWeapon = null, Player damagingPlayer = null, bool healthRemoval = false, bool lethal = true, bool ignoreBlock = false) + { + if (damage == Vector2.zero || !data.isPlaying || data.dead || (data.block.IsBlocking() && !ignoreBlock) || isRespawning) + { + return; + } + if ((bool)damagingPlayer) + { + damagingPlayer.GetComponent<CharacterStatModifiers>().DealtDamage(damage, damagingPlayer != null && damagingPlayer.transform.root == base.transform, data.player); + } + StopAllCoroutines(); + DisplayDamage(blinkColor); + data.lastSourceOfDamage = damagingPlayer; + data.health -= damage.magnitude; + stats.WasDealtDamage(damage, damagingPlayer != null && damagingPlayer.transform.root == base.transform); + if (!lethal) + { + data.health = Mathf.Clamp(data.health, 1f, data.maxHealth); + } + if (data.health < 0f && !data.dead) + { + if (data.stats.remainingRespawns > 0) + { + data.view.RPC("RPCA_Die_Phoenix", RpcTarget.All, damage); + } + else + { + data.view.RPC("RPCA_Die", RpcTarget.All, damage); + } + } + if (lastDamaged + 0.15f < Time.time && damagingPlayer != null && damagingPlayer.data.stats.lifeSteal != 0f) + { + SoundManager.Instance.Play(soundDamageLifeSteal, base.transform); + } + lastDamaged = Time.time; + } + + public void TakeDamageOverTime(Vector2 damage, Vector2 position, float time, float interval, Color color, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true) + { + dot.TakeDamageOverTime(damage, position, time, interval, color, soundDamagePassive, damagingWeapon, damagingPlayer, lethal); + } + + private void DisplayDamage(Color blinkColor) + { + GetComponentInChildren<PlayerSkinHandler>().BlinkColor(blinkColor); + } + + private IEnumerator DelayReviveAction() + { + yield return new WaitForSecondsRealtime(2f); + delayedReviveAction?.Invoke(); + } + + public void Revive(bool isFullRevive = true) + { + reviveAction?.Invoke(); + if (base.gameObject.activeInHierarchy) + { + StartCoroutine(DelayReviveAction()); + } + flyingFor = 0f; + if (isFullRevive) + { + data.stats.remainingRespawns = data.stats.respawns; + } + data.healthHandler.isRespawning = false; + data.health = data.maxHealth; + data.playerVel.velocity = Vector2.zero; + data.playerVel.angularVelocity = 0f; + data.stunTime = 0f; + data.block.ResetCD(soundPlay: false); + data.weaponHandler.gun.GetComponentInChildren<GunAmmo>().ReloadAmmo(playSound: false); + data.GetComponent<PlayerCollision>().IgnoreWallForFrames(5); + base.gameObject.SetActive(value: true); + if ((bool)deathEffect && data.dead) + { + anim.PlayIn(); + } + data.dead = false; + hpSprite.color = PlayerSkinBank.GetPlayerSkinColors(player.playerID).color; + data.stunHandler.StopStun(); + data.silenceHandler.StopSilence(); + GetComponent<CharacterStatModifiers>().slow = 0f; + GetComponent<CharacterStatModifiers>().slowSlow = 0f; + GetComponent<CharacterStatModifiers>().fastSlow = 0f; + GetComponent<WeaponHandler>().isOverHeated = false; + GetComponent<Block>().sinceBlock = float.PositiveInfinity; + dot.StopAllCoroutines(); + } + + [PunRPC] + private void RPCA_Die(Vector2 deathDirection) + { + if (data.isPlaying && !data.dead) + { + SoundManager.Instance.Play(soundDie, base.transform); + data.dead = true; + if (!DestroyOnDeath) + { + base.gameObject.SetActive(value: false); + GamefeelManager.GameFeel(deathDirection.normalized * 3f); + UnityEngine.Object.Instantiate(deathEffect, base.transform.position, base.transform.rotation).GetComponent<DeathEffect>().PlayDeath(PlayerSkinBank.GetPlayerSkinColors(player.playerID).color, data.playerVel, deathDirection); + dot.StopAllCoroutines(); + data.stunHandler.StopStun(); + data.silenceHandler.StopSilence(); + PlayerManager.instance.PlayerDied(player); + } + else + { + UnityEngine.Object.Destroy(base.transform.root.gameObject); + } + } + } + + [PunRPC] + private void RPCA_Die_Phoenix(Vector2 deathDirection) + { + if (data.isPlaying && !data.dead) + { + data.stats.remainingRespawns--; + isRespawning = true; + SoundManager.Instance.Play(soundDie, base.transform); + if (!DestroyOnDeath) + { + base.gameObject.SetActive(value: false); + GamefeelManager.GameFeel(deathDirection.normalized * 3f); + UnityEngine.Object.Instantiate(deathEffectPhoenix, base.transform.position, base.transform.rotation).GetComponent<DeathEffect>().PlayDeath(PlayerSkinBank.GetPlayerSkinColors(player.playerID).color, data.playerVel, deathDirection, player.playerID); + dot.StopAllCoroutines(); + data.stunHandler.StopStun(); + data.silenceHandler.StopSilence(); + } + } + } +} |