init
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Schema;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
using VOID.Generic.Util;
|
||||
|
||||
namespace VOID.Generic.AI.Schema.Actions
|
||||
{
|
||||
[Description("Gets unit by selected filters and save it as blackboard variable")]
|
||||
[Category(SchemaCategory.CombatThisUnit)]
|
||||
public class GetUnit : Action
|
||||
{
|
||||
private enum UnitType
|
||||
{
|
||||
Any,
|
||||
Enemy,
|
||||
Neutral,
|
||||
Friendly
|
||||
}
|
||||
|
||||
private enum SearchType
|
||||
{
|
||||
ClosestByDistance,
|
||||
FarthestByDistance,
|
||||
Random,
|
||||
LeastHp,
|
||||
MostHp,
|
||||
ClosestByPath,
|
||||
FarthestByPath
|
||||
}
|
||||
|
||||
[SerializeField] private UnitType _findUnitBy;
|
||||
[SerializeField] private SearchType _searchBy;
|
||||
[SerializeField, Space(15)] private BlackboardEntrySelector<UnitObject> _saveTo;
|
||||
|
||||
public override NodeStatus Tick(object nodeMemory, SchemaAgent agent)
|
||||
{
|
||||
var thisUnit = ((UnitObjectSchemaAgent)agent).unit;
|
||||
if (!thisUnit.basicState.turnManager) return NodeStatus.Failure;
|
||||
|
||||
// Get all participants in combat except current unit
|
||||
var allUnits = thisUnit.basicState.turnManager.allUnitsInQueue.Where(otherUnit => otherUnit != thisUnit)
|
||||
.ToList();
|
||||
|
||||
// Filter by UnitType
|
||||
if (_findUnitBy is UnitType.Enemy) allUnits = GetEnemy(thisUnit, allUnits);
|
||||
if (_findUnitBy is UnitType.Neutral) allUnits = GetNeutral(thisUnit, allUnits);
|
||||
if (_findUnitBy is UnitType.Friendly) allUnits = GetFriendly(thisUnit, allUnits);
|
||||
|
||||
// Filter by SearchType
|
||||
if (_searchBy is SearchType.ClosestByDistance) _saveTo.value = GetClosestByDistance(thisUnit, allUnits);
|
||||
if (_searchBy is SearchType.FarthestByDistance) _saveTo.value = GetFarthestByDistance(thisUnit, allUnits);
|
||||
if (_searchBy is SearchType.Random) _saveTo.value = RandomUtil.RandomElement(allUnits);
|
||||
if (_searchBy is SearchType.LeastHp) _saveTo.value = GetByLeastHp(allUnits);
|
||||
if (_searchBy is SearchType.MostHp) _saveTo.value = GetByMostHp(allUnits);
|
||||
if (_searchBy is SearchType.ClosestByPath) _saveTo.value = GetClosestByPath(thisUnit, allUnits);
|
||||
if (_searchBy is SearchType.FarthestByPath) _saveTo.value = GetFarthestByPath(thisUnit, allUnits);
|
||||
|
||||
// Could not find anything
|
||||
if (!_saveTo.value) return NodeStatus.Failure;
|
||||
|
||||
return NodeStatus.Success;
|
||||
}
|
||||
|
||||
private List<UnitObject> GetEnemy(UnitObject thisUnit, List<UnitObject> units)
|
||||
{
|
||||
return units.Where(otherUnit => thisUnit.unitAttitude.GetAttitudeWith(otherUnit) < AttitudeType.Neutral)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private List<UnitObject> GetNeutral(UnitObject thisUnit, List<UnitObject> units)
|
||||
{
|
||||
return units.Where(otherUnit => thisUnit.unitAttitude.GetAttitudeWith(otherUnit) == AttitudeType.Neutral)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private List<UnitObject> GetFriendly(UnitObject thisUnit, List<UnitObject> units)
|
||||
{
|
||||
return units.Where(otherUnit => thisUnit.unitAttitude.GetAttitudeWith(otherUnit) > AttitudeType.Neutral)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private UnitObject GetClosestByDistance(UnitObject thisUnit, List<UnitObject> units)
|
||||
{
|
||||
var closestDistance = float.MaxValue;
|
||||
var closestUnit = (UnitObject)null;
|
||||
units.ForEach(otherUnit =>
|
||||
{
|
||||
var distance = RangeUtil.GetDistance(thisUnit, otherUnit);
|
||||
if (distance >= closestDistance) return;
|
||||
closestDistance = distance;
|
||||
closestUnit = otherUnit;
|
||||
});
|
||||
return closestUnit;
|
||||
}
|
||||
|
||||
private UnitObject GetFarthestByDistance(UnitObject thisUnit, List<UnitObject> units)
|
||||
{
|
||||
var farthestDistance = float.MinValue;
|
||||
var farthestUnit = (UnitObject)null;
|
||||
units.ForEach(otherUnit =>
|
||||
{
|
||||
var distance = RangeUtil.GetDistance(thisUnit, otherUnit);
|
||||
if (distance <= farthestDistance) return;
|
||||
farthestDistance = distance;
|
||||
farthestUnit = otherUnit;
|
||||
});
|
||||
return farthestUnit;
|
||||
}
|
||||
|
||||
private UnitObject GetClosestByPath(UnitObject thisUnit, List<UnitObject> units)
|
||||
{
|
||||
var closestPathLength = float.MaxValue;
|
||||
var closestUnit = (UnitObject)null;
|
||||
units.ForEach(otherUnit =>
|
||||
{
|
||||
thisUnit.unitNavAgent.CalculatePathTo(otherUnit.transform.position);
|
||||
var path = thisUnit.unitNavAgent.GetPath();
|
||||
var pathLength = NavMeshPathUtil.GetPathLength(path);
|
||||
if (path.status is not NavMeshPathStatus.PathInvalid)
|
||||
pathLength += Vector3.Distance(path.corners.Last(), otherUnit.transform.position);
|
||||
if (pathLength >= closestPathLength) return;
|
||||
closestPathLength = pathLength;
|
||||
closestUnit = otherUnit;
|
||||
});
|
||||
return closestUnit;
|
||||
}
|
||||
|
||||
private UnitObject GetFarthestByPath(UnitObject thisUnit, List<UnitObject> units)
|
||||
{
|
||||
var farthestPathLength = float.MinValue;
|
||||
var farthestUnit = (UnitObject)null;
|
||||
units.ForEach(otherUnit =>
|
||||
{
|
||||
thisUnit.unitNavAgent.CalculatePathTo(otherUnit.transform.position);
|
||||
var path = thisUnit.unitNavAgent.GetPath();
|
||||
var pathLength = NavMeshPathUtil.GetPathLength(path);
|
||||
if (path.status is not NavMeshPathStatus.PathInvalid)
|
||||
pathLength += Vector3.Distance(path.corners.Last(), otherUnit.transform.position);
|
||||
if (pathLength <= farthestPathLength) return;
|
||||
farthestPathLength = pathLength;
|
||||
farthestUnit = otherUnit;
|
||||
});
|
||||
return farthestUnit;
|
||||
}
|
||||
|
||||
private UnitObject GetByLeastHp(List<UnitObject> units)
|
||||
{
|
||||
var leastHp = float.MinValue;
|
||||
var leastHpUnit = (UnitObject)null;
|
||||
units.ForEach(otherUnit =>
|
||||
{
|
||||
var hp = otherUnit.basicData.currentResources.health;
|
||||
if (hp >= leastHp) return;
|
||||
leastHp = hp;
|
||||
leastHpUnit = otherUnit;
|
||||
});
|
||||
return leastHpUnit;
|
||||
}
|
||||
|
||||
private UnitObject GetByMostHp(List<UnitObject> units)
|
||||
{
|
||||
var mostHp = float.MaxValue;
|
||||
var mostHpUnit = (UnitObject)null;
|
||||
units.ForEach(otherUnit =>
|
||||
{
|
||||
var hp = otherUnit.basicData.currentResources.health;
|
||||
if (hp <= mostHp) return;
|
||||
mostHp = hp;
|
||||
mostHpUnit = otherUnit;
|
||||
});
|
||||
return mostHpUnit;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user