SanAndreasUnity/Assets/Scripts/Behaviours/Ped/Ped_Damage.cs

187 lines
5 KiB
C#
Raw Normal View History

2020-05-31 17:07:22 +00:00
using System.Collections.Generic;
using UnityEngine;
using SanAndreasUnity.Utilities;
using SanAndreasUnity.Net;
2020-05-31 17:07:22 +00:00
namespace SanAndreasUnity.Behaviours
{
2021-09-06 22:28:37 +00:00
public static class PedDamageInfoExtensions
{
public static Ped GetAttackerPed(this DamageInfo damageInfo)
{
return damageInfo.attacker as Ped;
}
}
public partial class Ped {
2020-05-31 17:07:22 +00:00
public Damageable Damageable { get; private set; }
public float Health { get { return this.Damageable.Health; } set { this.Damageable.Health = value; } }
[SerializeField] private float m_maxHealth = 100f;
public float MaxHealth { get { return m_maxHealth; } set { m_maxHealth = value; } }
public Bar HealthBar { get; private set; }
2021-01-04 00:28:58 +00:00
/// <summary>
/// Damage info that killed the ped.
/// </summary>
public DamageInfo KillingDamageInfo { get; set; }
public float LastTimeWhenDamaged { get; private set; }
public float TimeSinceDamaged => Time.time - this.LastTimeWhenDamaged;
private bool m_alreadyKilled = false;
2021-02-19 01:55:09 +00:00
public class DamageResult
{
public float DamageAmount { get; }
public DamageResult()
{
}
public DamageResult(float damageAmount)
{
DamageAmount = damageAmount;
}
}
public static event System.Action<Ped, DamageInfo, DamageResult> onDamaged = delegate {};
2020-05-31 17:07:22 +00:00
void AwakeForDamage ()
{
this.Damageable = this.GetComponentOrThrow<Damageable> ();
}
void StartForDamage ()
{
this.CreateHealthBar ();
}
void CreateHealthBar ()
{
this.HealthBar = Object.Instantiate (GameManager.Instance.barPrefab, this.transform).GetComponentOrThrow<Bar> ();
// this.HealthBar.SetBorderWidth (0.1f);
2020-04-22 21:26:55 +00:00
this.HealthBar.BackgroundColor = PedManager.Instance.healthBackgroundColor;
this.HealthBar.FillColor = PedManager.Instance.healthColor;
2020-05-31 17:07:22 +00:00
this.HealthBar.BorderColor = Color.black;
this.UpdateHealthBar ();
}
void UpdateDamageStuff ()
{
this.UpdateHealthBar ();
}
void UpdateHealthBar ()
{
bool shouldBeVisible = this.TimeSinceDamaged < PedManager.Instance.healthBarVisibleTimeAfterDamage && !this.IsControlledByLocalPlayer;
2020-05-31 17:07:22 +00:00
this.HealthBar.gameObject.SetActive (shouldBeVisible);
if (shouldBeVisible)
{
this.HealthBar.BarSize = new Vector3 (PedManager.Instance.healthBarWorldWidth, PedManager.Instance.healthBarWorldHeight, 1.0f);
this.HealthBar.SetFillPerc (this.Health / this.MaxHealth);
this.HealthBar.transform.position = this.GetPosForHealthBar ();
this.HealthBar.MaxHeightOnScreen = PedManager.Instance.healthBarMaxScreenHeight;
}
}
public void DrawHealthBar ()
{
Vector3 pos = this.GetPosForHealthBar ();
Rect rect = GUIUtils.GetRectForBarAsBillboard (pos, PedManager.Instance.healthBarWorldWidth,
PedManager.Instance.healthBarWorldHeight, Camera.main);
// limit height
rect.height = Mathf.Min (rect.height, PedManager.Instance.healthBarMaxScreenHeight);
float borderWidth = Mathf.Min( 2f, rect.height / 4f );
2020-04-22 21:26:55 +00:00
GUIUtils.DrawBar( rect, this.Health / this.MaxHealth, PedManager.Instance.healthColor, PedManager.Instance.healthBackgroundColor, borderWidth );
2020-05-31 17:07:22 +00:00
}
private Vector3 GetPosForHealthBar ()
{
if (null == this.PlayerModel.Head)
return this.transform.position;
Vector3 pos = this.PlayerModel.Head.position;
pos += this.transform.up * PedManager.Instance.healthBarVerticalOffset;
return pos;
}
public void OnDamaged()
{
if (!NetStatus.IsServer)
return;
if (this.Health <= 0)
return;
this.LastTimeWhenDamaged = Time.time;
2021-02-19 01:55:09 +00:00
var damageInfo = this.Damageable.LastDamageInfo;
var damageResult = this.CurrentState.OnDamaged(damageInfo);
2021-02-19 01:55:09 +00:00
F.InvokeEventExceptionSafe(onDamaged, this, damageInfo, damageResult);
}
public void SendDamagedEventToClients(DamageInfo damageInfo, float damageAmount)
{
2021-09-06 22:28:37 +00:00
Ped attackingPed = damageInfo.GetAttackerPed();
PedSync.SendDamagedEvent(this.gameObject, attackingPed != null ? attackingPed.gameObject : null, damageAmount);
}
public void OnReceivedDamageEventFromServer(float damageAmount, Ped attackingPed)
{
2021-11-20 18:08:02 +00:00
this.LastTimeWhenDamaged = Time.time;
if (attackingPed != null && attackingPed.IsControlledByLocalPlayer && attackingPed != this)
{
this.DisplayInflictedDamageMessage(damageAmount);
}
}
public void DisplayInflictedDamageMessage(float damageAmount)
{
2020-06-06 16:09:26 +00:00
var msg = OnScreenMessageManager.Instance.CreateMessage();
msg.velocity = Random.insideUnitCircle.normalized * PedManager.Instance.inflictedDamageMessageVelocityInScreenPerc;
msg.TextColor = PedManager.Instance.inflictedDamageMessageColor;
msg.timeLeft = PedManager.Instance.inflictedDamageMessageLifetime;
msg.Text = Mathf.RoundToInt(damageAmount).ToString();
}
2020-05-31 17:07:22 +00:00
public void Kill()
{
F.RunExceptionSafe(this.KillInternal);
}
void KillInternal()
{
if (m_alreadyKilled)
return;
m_alreadyKilled = true;
2021-02-06 20:11:14 +00:00
this.CurrentState.KillPed();
}
2020-05-31 17:07:22 +00:00
}
}