init
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user