using System; using System.Collections.Generic; using Sirenix.OdinInspector; using UnityEngine; using VOID.Generic.Dict.Ability; using VOID.Generic.DynamicValue; using VOID.Generic.Objects.Unit; using VOID.Generic.Projectile; using VOID.Generic.Requirement; using VOID.Generic.Status.Effect; using VOID.ScriptableObjects.Animations; namespace VOID.ScriptableObjects.Abilities { [CreateAssetMenu(menuName = "GAME DATA/Zdolności/Ability")] public class BasicAbility : ScriptableObject { [Space(40)] [Title("Display UI")] [Required] public string displayName; [Required] public Texture2D displayIcon; [Required] public AbilityQuality quality; public DynamicText displayDescription; [Space(40)] [Title("Resource costs")] public DynamicFormula actionPointCost; public DynamicFormula movePointCost; [Space(40)] [Title("Requirements")] [SerializeReference] public List requirements = new(); [Space(40)] [Title("Casting")] [Required] public AbilityCastingType castingType; [ShowIf(nameof(ShowAimingType))] [Required] public AbilityAimingType aimingType; [ShowIf(nameof(ShowAimingCorrectionType))] [Required] public AbilityAimingCorrectionType aimingCorrectionType; [InfoBox("Amount of targets for projectiles")] [Required] [MinValue(0)] [ShowIf(nameof(ShowCastUsages))] public int castUsages = 1; [Space(40)] [Title("Range")] [ShowIf(nameof(ShowIsRange))] [Required] public bool isRanged; [ShowIf(nameof(ShowRange)), SerializeField] private DynamicFormula _range; public float range => ShowRange() ? _range : 0.25f; [Space(40)] [Title("Animation")] [ShowIf(nameof(ShowAbilityAnimationList))] [Required] public ActionAnimationList abilityAnimationList; [ShowIf(nameof(ShowAbilityLoopAnimationList))] [Required] public ActionLoopAnimationList abilityLoopAnimationList; [ShowIf(nameof(ShowCastingAnimationList))] public ActionLoopAnimationList castingAnimationList; [Space(40)] [Title("Effects")] public AbilityExecutionMoment applyOnCasterMoment; [SerializeReference] [ShowIf(nameof(ShowApplyOnCaster))] [TypeSelectorSettings(ShowCategories = true, ShowNoneItem = false)] public List applyOnCaster = new(); [SerializeReference] [ShowIf(nameof(ShowApplyOnTarget))] [TypeSelectorSettings(ShowCategories = true, ShowNoneItem = false)] public List applyOnTarget = new(); [Space(40)] [Title("Tagging")] public AbilityPurposeFlag abilityPurpose; [Space(40)] [Title("Projectile")] [InfoBox("IMPORTANT!\nSo far only first step of projectile is fully supported!")] [ShowIf(nameof(ShowProjectileSteps))] [RequiredListLength(1)] public ProjectileStep[] projectileSteps; [InfoBox("If no projectile selected then default empty one will be used!")] [ShowIf(nameof(ShowProjectile))] public ProjectileObject projectile; public void OnAddedToUnit(UnitObject unitObject) { displayDescription.AddSource(unitObject); actionPointCost.AddSource(unitObject); movePointCost.AddSource(unitObject); _range.AddSource(unitObject); } private void OnValidate() { // If properties are hiden then set them to default values if (!ShowAimingType()) aimingType = AbilityAimingType.Blank; if (!ShowAimingCorrectionType()) aimingCorrectionType = AbilityAimingCorrectionType.None; if (aimingType is AbilityAimingType.Blank) castUsages = 0; if (aimingType is AbilityAimingType.Self) castUsages = 1; if (!ShowIsRange()) isRanged = false; // if (!ShowRange()) range = 0.25f; if (!ShowCastingAnimationList()) castingAnimationList = null; if (!ShowAbilityAnimationList()) abilityAnimationList = null; if (!ShowAbilityLoopAnimationList()) abilityLoopAnimationList = null; if (!ShowApplyOnCaster()) applyOnCaster = new List(); if (!ShowApplyOnTarget()) applyOnTarget = new List(); if (!ShowProjectileSteps()) projectileSteps = Array.Empty(); if (!ShowProjectile()) projectile = null; } private bool ShowAimingType() => castingType is not AbilityCastingType.Instant and not AbilityCastingType.InstantCasting; private bool ShowAimingCorrectionType() => aimingType is AbilityAimingType.Target; private bool ShowCastUsages() => aimingType is not AbilityAimingType.Blank and not AbilityAimingType.Self; private bool ShowIsRange() => castUsages > 0; private bool ShowRange() => ShowIsRange() && isRanged; private bool ShowCastingAnimationList() => castingType is not AbilityCastingType.Instant and not AbilityCastingType.InstantCasting; private bool ShowAbilityAnimationList() => castingType is not AbilityCastingType.Instant and not AbilityCastingType.Channel; private bool ShowAbilityLoopAnimationList() => castingType is AbilityCastingType.Channel; private bool ShowApplyOnCaster() => applyOnCasterMoment is not AbilityExecutionMoment.None; private bool ShowApplyOnTarget() => castUsages > 0; private bool ShowProjectileSteps() => castUsages > 0; private bool ShowProjectile() => castUsages > 0; } }