Hugo
9 months ago
#1
An (In Depth) Introduction to Better NPCs : yourlstcomrade/ai_unit_control/news/an-in-depth-introduction-to-better-npcs-c6325a12




using Sandbox;
using System;
public sealed class AiBrain : Component
{
[Property] public Dictionary<string, AiAction> actions = new Dictionary<string, AiAction>();
[Property] public List<IPriority> priorities = new List<IPriority>();
public bool? GetDecision(string action, List<object> context)
{
AiAction _action = actions[action];
if ( _action != null )
{
float approval = 0;
foreach ( IPriority priority in priorities )
{
foreach ( object _context in context )
{
int approv = priority.GetApproval( _context ).AsInt();
if ( approv < _action.minRequiredApproval ) return false;
if ( approv > _action.maxRequiredApproval ) return true;
approval += approv;
}
}
if ( priorities.Count * context.Count > 0 )
approval /= priorities.Count * context.Count;
if ( approval > _action.requiredApproval ) return true;
return false;
}
return null;
}
public abstract class AiAction
{
// required median approval (equal or above) to get the decision to approve
public float requiredApproval = 1;
// Anything below this will cause the decision to immediately dissaprove
public int minRequiredApproval = -1;
// Anything above this will cause the decision to immediately approve
public int maxRequiredApproval = 2;
}
public enum PriorityApproval
{
StronglyDisapprove = -2,
Disapprove = -1,
Impartial = 0,
Approve = 1,
StronglyApprove = 2,
}
public class IPriority : Object
{
public virtual PriorityApproval GetApproval( object context )
{
//if(context != null && typeof( AiContext ).IsAssignableFrom( context.GetType() )) return PriorityApproval.Approve;
return PriorityApproval.Impartial;
}
public IPriority()
{
}
}
}
public struct SoldierData
{
public Rank rank;
public HumanData.Ethnicity ethnicity;
public HumanData.Name name;
public HumanData.Gender gender;
public bool isAlive = true;
public bool spawned { get { return soldierInstance.IsValid(); } }
//private bool isSpawned = false;
public AiSoldier soldierInstance { get { return _soldierInstance; } set { _soldierInstance = value; } }
private AiSoldier _soldierInstance;
public SoldierData( HumanData.Name name, Rank rank, HumanData.Gender gender, HumanData.Ethnicity ethnicity, AiSoldier soldierInstance = null )
{
this.name = name;
this.rank = rank;
this.gender = gender;
this.ethnicity = ethnicity;
if ( soldierInstance != null )
{
this._soldierInstance = soldierInstance;
//isSpawned = true;
}
}
}