84 lines
3.2 KiB
C#
84 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|
|
} |