You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
9.1 KiB
C#
222 lines
9.1 KiB
C#
using MalbersAnimations.Controller;
|
|
using MalbersAnimations.Controller.Reactions;
|
|
using MalbersAnimations.Events;
|
|
using MalbersAnimations.Scriptables;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace MalbersAnimations
|
|
{
|
|
[DisallowMultipleComponent]
|
|
/// <summary> Damager Receiver</summary>
|
|
[AddComponentMenu("Malbers/Damage/MDamageable")]
|
|
[HelpURL("https://malbersanimations.gitbook.io/animal-controller/secondary-components/mdamageable")]
|
|
public class MDamageable : MonoBehaviour, IMDamage
|
|
{
|
|
[Tooltip("Animal Reaction to apply when the damage is done")]
|
|
public Component character;
|
|
|
|
[Tooltip("Animal Reaction to apply when the damage is done")]
|
|
public MReaction reaction;
|
|
|
|
[Tooltip("Stats component to apply the Damage")]
|
|
public Stats stats;
|
|
|
|
[Tooltip("Multiplier for the Stat modifier Value")]
|
|
public FloatReference multiplier = new FloatReference(1);
|
|
|
|
public MDamageable Root;
|
|
public damagerEvents events;
|
|
|
|
public Vector3 HitDirection { get; set; }
|
|
public GameObject Damager { get; set; }
|
|
public GameObject Damagee => gameObject;
|
|
|
|
public DamageData LastDamage;
|
|
|
|
private void Start()
|
|
{
|
|
if (character == null) character = stats.GetComponent(reaction.ReactionType());
|
|
}
|
|
|
|
public virtual void ReceiveDamage(Vector3 Direction, GameObject Damager, StatModifier modifier, bool isCritical, bool react, MReaction customReaction, bool pureDamage)
|
|
{
|
|
if (!enabled) return; //This makes the Animal Immortal.
|
|
|
|
SetDamageable(Direction, Damager);
|
|
Root?.SetDamageable(Direction, Damager); //Send the Direction and Damager to the Root
|
|
|
|
if (isCritical)
|
|
{
|
|
events.OnCriticalDamage.Invoke();
|
|
Root?.events.OnCriticalDamage.Invoke();
|
|
}
|
|
|
|
if (!pureDamage) modifier.Value *= multiplier; //Apply to the Stat modifier a new Modification
|
|
|
|
events.OnReceivingDamage.Invoke(modifier.Value);
|
|
Root?.events.OnReceivingDamage.Invoke(modifier.Value);
|
|
|
|
LastDamage = new DamageData(Damager, modifier);
|
|
if (Root) Root.LastDamage = LastDamage;
|
|
|
|
modifier.ModifyStat(stats.Stat_Get(modifier.ID));
|
|
|
|
if (customReaction) customReaction.React(character); //Custom reaction
|
|
else if (react && reaction)
|
|
{
|
|
reaction.React(character); //Lets React
|
|
}
|
|
}
|
|
|
|
/// <summary> Receive Damage from external sources simplified </summary>
|
|
/// <param name="stat"> What stat will be modified</param>
|
|
/// <param name="amount"> value to substact to the stat</param>
|
|
public virtual void ReceiveDamage(StatID stat, float amount)
|
|
{
|
|
var modifier = new StatModifier(){ ID = stat, modify = StatOption.SubstractValue, Value = amount};
|
|
ReceiveDamage(Vector3.forward, null, modifier, false, true, null, false);
|
|
}
|
|
|
|
|
|
|
|
/// <summary> Receive Damage from external sources simplified </summary>
|
|
/// <param name="stat"> What stat will be modified</param>
|
|
/// <param name="amount"> value to substact to the stat</param>
|
|
public virtual void ReceiveDamage(StatID stat, float amount, StatOption modifyStat = StatOption.SubstractValue)
|
|
{
|
|
var modifier = new StatModifier() { ID = stat, modify = modifyStat, Value = amount };
|
|
ReceiveDamage(Vector3.forward, null, modifier, false, true, null, false);
|
|
}
|
|
|
|
|
|
|
|
/// <summary> Receive Damage from external sources simplified </summary>
|
|
/// <param name="Direction">Where the Damage is coming from</param>
|
|
/// <param name="Damager">Who is doing the Damage</param>
|
|
/// <param name="modifier">What Stat will be modified</param>
|
|
/// <param name="modifyStat">Type of modification applied to the stat</param>
|
|
/// <param name="isCritical">is the Damage Critical?</param>
|
|
/// <param name="react">Does Apply the Default Reaction?</param>
|
|
/// <param name="pureDamage">if is pure Damage, do not apply the default multiplier</param>
|
|
/// <param name="stat"> What stat will be modified</param>
|
|
/// <param name="amount"> value to substact to the stat</param>
|
|
public virtual void ReceiveDamage(Vector3 Direction, GameObject Damager, StatID stat, float amount, StatOption modifyStat = StatOption.SubstractValue,
|
|
bool isCritical = false, bool react = true, MReaction customReaction = null, bool pureDamage = false)
|
|
{
|
|
var modifier = new StatModifier() { ID = stat, modify = modifyStat, Value = amount };
|
|
ReceiveDamage(Direction, Damager, modifier, isCritical, react, customReaction, pureDamage);
|
|
}
|
|
|
|
|
|
/// <summary> Receive Damage from external sources simplified </summary>
|
|
/// <param name="Direction">Where the Damage is coming from</param>
|
|
/// <param name="Damager">Who is doing the Damage</param>
|
|
/// <param name="modifier">What Stat will be modified</param>
|
|
/// <param name="isCritical">is the Damage Critical?</param>
|
|
/// <param name="react">Does Apply the Default Reaction?</param>
|
|
/// <param name="pureDamage">if is pure Damage, do not apply the default multiplier</param>
|
|
/// <param name="stat"> What stat will be modified</param>
|
|
/// <param name="amount"> value to substact to the stat</param>
|
|
public virtual void ReceiveDamage(Vector3 Direction, GameObject Damager, StatID stat,
|
|
float amount, bool isCritical = false, bool react = true, MReaction customReaction = null, bool pureDamage = false)
|
|
{
|
|
var modifier = new StatModifier() { ID = stat, modify = StatOption.SubstractValue, Value = amount };
|
|
ReceiveDamage(Direction, Damager, modifier, isCritical, react, customReaction, pureDamage);
|
|
}
|
|
|
|
internal void SetDamageable(Vector3 Direction, GameObject Damager)
|
|
{
|
|
HitDirection = Direction;
|
|
this.Damager = Damager;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class damagerEvents
|
|
{
|
|
// public UnityEvent BeforeReceivingDamage = new UnityEvent();
|
|
public FloatEvent OnReceivingDamage = new FloatEvent();
|
|
// public UnityEvent AfterReceivingDamage = new UnityEvent();
|
|
public UnityEvent OnCriticalDamage = new UnityEvent();
|
|
}
|
|
|
|
public struct DamageData
|
|
{
|
|
/// <summary> Who made the Damage ? </summary>
|
|
public GameObject Damager;
|
|
/// <summary> Final Stat Modifier ? </summary>
|
|
public StatModifier stat;
|
|
/// <summary> Final value who modified the Stat</summary>
|
|
public float Damage => stat.modify != StatOption.None ? stat.Value.Value : 0f;
|
|
|
|
public DamageData(GameObject damager, StatModifier stat)
|
|
{
|
|
Damager = damager;
|
|
this.stat = new StatModifier(stat);
|
|
}
|
|
}
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
private void Reset()
|
|
{
|
|
reaction = MTools.GetInstance<ModeReaction>("Damaged");
|
|
stats = this.FindComponent<Stats>();
|
|
Root = transform.root.GetComponent<MDamageable>(); //Check if there's a Damageable on the Root
|
|
if (Root == this) Root = null;
|
|
|
|
if (stats == null)
|
|
{
|
|
stats = gameObject.AddComponent<Stats>();
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
[CustomEditor(typeof(MDamageable))]
|
|
public class MDamageableEditor : Editor
|
|
{
|
|
SerializedProperty reaction, stats, multiplier, events, Root;
|
|
MDamageable M;
|
|
|
|
|
|
private void OnEnable()
|
|
{
|
|
M = (MDamageable)target;
|
|
|
|
reaction = serializedObject.FindProperty("reaction");
|
|
stats = serializedObject.FindProperty("stats");
|
|
multiplier = serializedObject.FindProperty("multiplier");
|
|
events = serializedObject.FindProperty("events");
|
|
Root = serializedObject.FindProperty("Root");
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
serializedObject.Update();
|
|
MalbersEditor.DrawDescription("Allows the Animal React and Receive damage from external sources");
|
|
EditorGUILayout.BeginVertical(MalbersEditor.StyleGray);
|
|
|
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
|
if (M.transform.parent != null)
|
|
EditorGUILayout.PropertyField(Root);
|
|
EditorGUILayout.PropertyField(reaction);
|
|
EditorGUILayout.PropertyField(stats);
|
|
EditorGUILayout.PropertyField(multiplier);
|
|
EditorGUILayout.EndVertical();
|
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
|
EditorGUI.indentLevel++;
|
|
EditorGUILayout.PropertyField(events,true);
|
|
EditorGUI.indentLevel--;
|
|
EditorGUILayout.EndVertical();
|
|
EditorGUILayout.EndVertical();
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
}
|
|
#endif
|
|
} |