142 lines
4.7 KiB
C#
142 lines
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Sirenix.OdinInspector;
|
|
using Sirenix.Utilities;
|
|
using UnityEngine;
|
|
using VOID.Generic.Dict;
|
|
using VOID.Generic.Objects.Abstract.Events;
|
|
using VOID.Generic.Triggers;
|
|
|
|
namespace VOID.Generic.Objects.Abstract
|
|
{
|
|
[SelectionBase]
|
|
[DisallowMultipleComponent]
|
|
[RequireComponent(typeof(Rigidbody))]
|
|
public abstract class AbstractObject : MonoBehaviour
|
|
{
|
|
[Title("=== BasicObject properties ===")]
|
|
public AbstractObjectData basicData;
|
|
public AbstractObjectEvents basicEvents;
|
|
public AbstractObjectStatusManager statusManager;
|
|
public AbstractObjectState basicState;
|
|
|
|
protected void OnValidate()
|
|
{
|
|
gameObject.GetComponent<Rigidbody>().hideFlags = HideFlags.NotEditable;
|
|
|
|
// Init RigidBody
|
|
var rb = GetComponent<Rigidbody>();
|
|
rb.mass = 0;
|
|
rb.linearDamping = 0;
|
|
rb.angularDamping = 0;
|
|
rb.automaticCenterOfMass = true;
|
|
rb.automaticInertiaTensor = true;
|
|
rb.useGravity = false;
|
|
rb.isKinematic = true;
|
|
rb.interpolation = RigidbodyInterpolation.None;
|
|
rb.constraints = RigidbodyConstraints.FreezeAll;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
GetObjectComponents().ForEach(component => component.SetParent(this));
|
|
GetObjectComponents().ForEach(component => component.DoSelfInitialize());
|
|
GetObjectComponents().ForEach(component => component.DoEventInitialize());
|
|
GetObjectComponents().ForEach(component => component.DoInitialize());
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
// Finally when this object is fully initialized then we can
|
|
basicEvents.onSpawn.Invoke();
|
|
}
|
|
|
|
protected void FixedUpdate()
|
|
{
|
|
basicEvents.onFixedUpdate.Invoke();
|
|
}
|
|
|
|
protected virtual List<ObjectComponent> GetObjectComponents()
|
|
{
|
|
return new List<ObjectComponent>
|
|
{
|
|
basicData,
|
|
basicEvents,
|
|
statusManager,
|
|
basicState
|
|
};
|
|
}
|
|
|
|
[Button]
|
|
public void TakeDamage(DamageEvent damageEvent)
|
|
{
|
|
if (basicState.isDead) return;
|
|
if (!basicData.canBeDestroyed) return;
|
|
|
|
basicEvents.onDamagedBefore.Invoke(damageEvent);
|
|
if (damageEvent.attacker) damageEvent.attacker.unitEvents.onDamageBefore.Invoke(damageEvent);
|
|
|
|
if (damageEvent.prevented) return;
|
|
|
|
var damage = damageEvent.amount;
|
|
var resistance = 1 - basicData.resistances.Get(damageEvent.damageType);
|
|
|
|
basicData.UseResource(BasicResourceType.Health, damage * resistance, true);
|
|
|
|
basicEvents.onDamagedAfter.Invoke(damageEvent);
|
|
if (damageEvent.attacker) damageEvent.attacker.unitEvents.onDamageAfter.Invoke(damageEvent);
|
|
|
|
if (basicData.currentResources.health <= 0f) Death();
|
|
}
|
|
|
|
[Button]
|
|
public void Death()
|
|
{
|
|
if (basicState.isDead) return;
|
|
if (!basicData.canBeDestroyed) return;
|
|
|
|
var deathEvent = new DeathEvent { obj = this };
|
|
|
|
basicEvents.onDeathBefore.Invoke(deathEvent);
|
|
if (deathEvent.prevented) return;
|
|
basicEvents.onDeathAfter.Invoke(deathEvent);
|
|
|
|
basicData.currentResources.health = 0f;
|
|
}
|
|
|
|
[Button]
|
|
public void Revive()
|
|
{
|
|
if (basicState.isDead == false) return;
|
|
|
|
basicData.SetResourcePercentage(BasicResourceType.Health, 0.3f);
|
|
basicEvents.onRevive.Invoke(new ReviveEvent { obj = this });
|
|
}
|
|
|
|
[Button]
|
|
public void Remove()
|
|
{
|
|
var removeEvent = new RemoveEvent { obj = this };
|
|
|
|
basicEvents.onRemove.Invoke(removeEvent);
|
|
|
|
Destroy(gameObject);
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other)
|
|
{
|
|
other.GetComponentsInParent<IDynamicTrigger>().ForEach(triggerArea => {
|
|
if (basicState.isDead == false) triggerArea.OnObjectEnter(this);
|
|
basicEvents.onTriggerEnter.Invoke(new TriggerEvent { obj = this, triggerArea = triggerArea });
|
|
});
|
|
}
|
|
|
|
private void OnTriggerExit(Collider other)
|
|
{
|
|
other.GetComponentsInParent<IDynamicTrigger>().ForEach(triggerArea => {
|
|
if (basicState.isDead == false) triggerArea.OnObjectExit(this);
|
|
basicEvents.onTriggerExit.Invoke(new TriggerEvent { obj = this, triggerArea = triggerArea });
|
|
});
|
|
}
|
|
}
|
|
} |