-
Notifications
You must be signed in to change notification settings - Fork 9
/
GameAI.cs
70 lines (61 loc) · 2.23 KB
/
GameAI.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using System;
using System.ComponentModel;
using static Activ.GOAP.Util;
using S = Activ.GOAP.PlanningState;
namespace Activ.GOAP{ // See also Runtime/Unity/GameAI.cs)
public abstract partial class GameAI<T>
: SolverOwner, INotifyPropertyChanged where T : class {
public event PropertyChangedEventHandler PropertyChanged;
//
public float cooldown;
public bool verbose;
public Solver<T> solver;
public SolverParams config = new SolverParams();
public Handlers policies = new Handlers();
public ActionHandler handler = new ActionMap();
//
int index = 0;
Goal<T>[] goals;
public SolverStats stats => solver;
public Goal<T> goal => goals[index];
public S status => solver.status;
public abstract Goal<T>[] Goals();
public abstract T Model();
virtual public void Idle(){ }
virtual public bool IsActing() => false;
public virtual void Update(){
solver = solver ?? new Solver<T>();
if(policies.Block(status) || IsActing()) return;
var s = status;
var next = (solver.status != S.Running) ? StartSolving()
: solver.Iterate(config.frameBudget);
if(next != null) handler.Effect(next.Head(), this);
policies.OnResult(status, ObjectName(this));
if(s != status) NotifyPropertyChanged(nameof(status));
}
Node<T> StartSolving(){
if(handler is ActionMap m) m.verbose = verbose;
var model = Model(); if(model == null) return null;
var goal = NextGoal();
config.Reset(solver);
return solver.Next(model, goal, config.frameBudget);
}
Goal<T> NextGoal(){
goals = Goals();
switch(status){
case S.Done: index = 0; break;
case S.Running: throw new System.Exception("Invalid");
default:
index = (index + 1);
if(index >= goals.Length){
index = 0;
#if UNITY_2018_1_OR_NEWER
Cooldown();
#endif
} break;
}
return goals[index];
}
void NotifyPropertyChanged(String p) => PropertyChanged?
.Invoke(this, new PropertyChangedEventArgs(p));
}}