This commit is contained in:
2026-07-09 21:33:33 +02:00
commit 84a2a365f3
2364 changed files with 950134 additions and 0 deletions
@@ -0,0 +1,84 @@
using System;
using System.Linq;
using Schema;
using Sirenix.Utilities;
using UnityEngine;
using VOID.Generic.Dict.Ability;
using VOID.Generic.Util;
using VOID.ScriptableObjects.Abilities;
using Action = Schema.Action;
namespace VOID.Generic.AI.Schema.Actions
{
[Description("Gets ability by selected filters from this unit and save it as blackboard variable")]
[Category(SchemaCategory.ThisUnit)]
public class GetAbility : Action
{
private enum SearchType
{
First,
Random,
LeastExpensive,
MostExpensive,
GreatestRange
}
private enum AbilityPurposeType
{
Any,
All
}
[SerializeField] private bool includeBasicAttack;
[SerializeField] private BlackboardEntrySelector<float> atLeastRange;
[SerializeField] private AbilityPurposeType abilityPurposeType;
[SerializeField] private AbilityPurposeFlag abilityPurpose;
[SerializeField] private SearchType searchBy;
[SerializeField, WriteOnly, Space(15)] private BlackboardEntrySelector<BasicAbility> saveTo;
public override NodeStatus Tick(object nodeMemory, SchemaAgent agent)
{
var thisUnit = ((UnitObjectSchemaAgent)agent).unit;
var allAbilities = thisUnit.unitAbilityBook.abilities.ToList();
// Unit dont have any abilities
if (allAbilities.IsNullOrEmpty()) return NodeStatus.Failure;
if (includeBasicAttack) allAbilities.Add(thisUnit.unitAbilityBook.attackAbility);
// Filter by range required
allAbilities = allAbilities.Where(ability => ability.range >= atLeastRange.value).ToList();
// Filter by wanted purpose
allAbilities = allAbilities.Where(ability =>
{
switch (abilityPurposeType)
{
case AbilityPurposeType.All when (ability.abilityPurpose & abilityPurpose) == abilityPurpose:
case AbilityPurposeType.Any when (ability.abilityPurpose & abilityPurpose) != AbilityPurposeFlag.None:
return true;
default:
return false;
}
}).ToList();
// Getting final ability and saving it
saveTo.value = searchBy switch
{
SearchType.First => allAbilities.FirstOrDefault(),
SearchType.Random => RandomUtil.RandomElement(allAbilities),
SearchType.LeastExpensive => allAbilities.Aggregate(allAbilities.First(),
(a1, a2) => a2.actionPointCost > a1.actionPointCost ? a1 : a2),
SearchType.MostExpensive => allAbilities.Aggregate(allAbilities.First(),
(a1, a2) => a2.actionPointCost <= a1.actionPointCost ? a1 : a2),
SearchType.GreatestRange => allAbilities.Aggregate(allAbilities.First(),
(a1, a2) => a2.range <= a1.range ? a1 : a2),
_ => throw new ArgumentOutOfRangeException()
};
if (!saveTo.value) return NodeStatus.Failure;
return NodeStatus.Success;
}
}
}