using System; using Sirenix.OdinInspector; using UnityEngine; using VOID.Generic.Dict; using VOID.Generic.Objects.Abstract.Data; using VOID.Generic.Objects.Abstract.Events; using VOID.Generic.Objects.Item; using Resources = VOID.Generic.Objects.Abstract.Data.Resources; namespace VOID.Generic.Objects.Abstract { /// /// Contain and manages all generic data needed and used by or its children. /// [Serializable] public class AbstractObjectData : ObjectComponent { #region Initialize protected override void SelfInitialize() { // Init resources values foreach (BasicResourceType resourceType in Enum.GetValues(typeof(BasicResourceType))) maxResources.Set(resourceType, baseMaxResources.Get(resourceType)); // Init resistances values foreach (DamageType damageType in Enum.GetValues(typeof(DamageType))) resistances.Set(damageType, baseResistances.Get(damageType)); } protected override void Initialize() { // Instantiate stats baseMaxResources = baseMaxResources with {}; maxResources = maxResources with {}; currentResources = currentResources with {}; baseResistances = baseResistances with {}; resistances = resistances with {}; } #endregion [Title("Possible actions")] [LabelText("TODO: canBeSelected")] public bool canBeSelected = true; public bool canBeDestroyed = true; [LabelText("TODO: canBeInspected")] public bool canBeInspected = true; [Title("Display in UI")] public string name; public string finalName => parent switch { ItemObject item => item.itemData.finalName, _ => name }; public Texture2D image; [TextArea] public string description; [Title("Size")] [MinValue(1f)] public float height = 1f; [MinValue(.25f)] public float radius = 0.25f; [Title("Basic Resources")] public Resources baseMaxResources; [ReadOnly] public Resources maxResources; [ReadOnly] public Resources currentResources; [Title("Basic Resistances")] public Resistances baseResistances; [ReadOnly] public Resistances resistances; /// /// Uses given resource by given amount.
/// That means positive values decreases and negative values increases that resource. ///
/// Resource to use /// Amount to change /// If TRUE then we can use this resource even if we don't have enough of it /// Returns TRUE if done successfully. public bool UseResource(BasicResourceType resourceType, float change, bool force = false) { var oldValue = currentResources.Get(resourceType); var maxValue = maxResources.Get(resourceType); // Attempt to use more than available if (oldValue - change < 0f) { // If not forced - not enough resource if (!force) return false; // Else - use only remaining resource change += oldValue - change; } // Attempt to go over limit if (oldValue - change > maxValue) { change = oldValue - maxValue; } currentResources.Set(resourceType, oldValue - change); parent.basicEvents.onCurrentResourceChange.Invoke(new BasicResourceChangeEvent { obj = parent, type = resourceType, oldValue = oldValue, newValue = oldValue - change, changedValue = change, }); return true; } /// /// Sets given resource to given value.
/// It uses so whole process will be executed as change from starting value to given value. ///
/// Resource type to set /// Value to set /// Return TRUE if done successfully. public bool SetResource(BasicResourceType resourceType, float value) { var max = maxResources.Get(resourceType); var oldValue = Mathf.Clamp(currentResources.Get(resourceType), 0f, max); var change = oldValue - value; return UseResource(resourceType, change, true); } /// /// Sets given resource to percentage of its max value.
/// It uses so whole process will be executed as change from starting value to given value. ///
/// Resource type to set /// float as percent, value needs to be between 0 and 1 /// Return TRUE if done successfully. public bool SetResourcePercentage(BasicResourceType resourceType, float percentage) { percentage = Mathf.Clamp01(percentage); var max = maxResources.Get(resourceType); var value = percentage * max; var oldValue = currentResources.Get(resourceType); var change = oldValue - value; return UseResource(resourceType, change, true); } } }