Author: conkerjo
(2009/07/05 18:01) Over 2 years ago
Behavior Refactoring
6
using Brains.Framework.Behaviors.PathFinding;
7
using Microsoft.Xna.Framework;
8
using Brains.Framework.Map;
9
using Brains.Framework.Utility;
10
namespace Brains.Framework.Behaviors
11
{
12
public class GoToBehavior :BehaviorBase,IActionBehavior
13
public class GoToBehavior :CompositeBehavior,IActionBehavior
14
protected BehaviorBase findPath = new FindPathBehavior();
15
protected CompositeBehavior findPath = new FindPathBehavior();
protected BehaviorBase followPath = new FollowPathBehavior();
16
protected CompositeBehavior followPath = new FollowPathBehavior();
GridCell _startNode;
17
GridCell _endNode;
18
Journey currentJourney;
19
...
75
SubJournies.Clear();
76
GridCell start = StartNode;
77
GridCell end = EndNode;
78
if (StartNode.Parent != EndNode.Parent)
79
80
List<int> grididschecked = new List<int>();
81
if (start.Parent != end.Parent)
82
if (end.Parent.Position.X > start.Parent.Position.X) //Right
83
GridCell currentStartCell;
84
GridCell currentEndCell;
85
86
Grid startGrid = StartNode.Parent;
87
Grid endGrid = EndNode.Parent;
88
int startId = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(startGrid);
89
int endId = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(endGrid);
90
91
92
List<Grid> gridsBetween = GetGridsBetween(StartNode, EndNode);
93
94
int ii = 0;
95
foreach (var item in gridsBetween)
96
end = start.Parent.GetCell(start.Parent.Cols - 1, end.Y);
97
GridCell startJourney = StartNode;
SubJournies.Add(new Journey(start, end));
98
GridCell endJourney = null;
99
start = EndNode.Parent.GetCell(0, end.Y);
100
int index = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(item);
end = EndNode;
101
int y = (index - (index % Owner.ParentWorld.Map.ClusterGrid.Cols)) / Owner.ParentWorld.Map.ClusterGrid.Cols;
102
int x = index % Owner.ParentWorld.Map.ClusterGrid.Cols;
103
Console.WriteLine(x + " : " + y);
104
if (item == startGrid)
105
106
Grid next = gridsBetween[ii + 1];
107
108
Grid nextPlusOne = gridsBetween[ii + 2];
109
foreach (var path in next.PredeterminedPaths)
110
111
int tmpindex = index;
112
int tmpindex1 =
113
Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(nextPlusOne);
114
if (path.FromGrid == tmpindex &&
115
path.ToGrid == tmpindex1)
116
117
int _newX = path.Nodes[0].X;
118
int _newY = path.Nodes[0].X;
119
if (path.Nodes[0].X == 0)
120
_newX = startGrid.Cols - 1;
121
if (path.Nodes[0].X == startGrid.Cols - 1)
122
_newX = 0;
123
if (path.Nodes[0].Y == 0)
124
_newY = startGrid.Rows - 1;
125
if (path.Nodes[0].Y == startGrid.Rows - 1)
126
_newY = 0;
127
Journey j = new Journey(StartNode,
128
startGrid.GetCell(_newX, _newY));
129
}
130
131
132
//Journey j=new Journey(StartNode,
133
//startGrid.GetCell(
134
135
else
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
Journey j = new Journey(item.GetCell(_newX, _newY),
158
item.GetCell(
159
path.Nodes[path.Nodes.Count - 1].X,
160
path.Nodes[path.Nodes.Count - 1].Y));
161
162
163
164
165
166
167
ii++;
168
else if (end.Parent.Position.X < start.Parent.Position.X) //Left
169
currentStartCell = StartNode;
170
171
bool finished = false;
172
Grid current = startGrid;
173
int currentId = startId;
174
175
Grid closest = null;
176
Cluster cluster = Owner.ParentWorld.Map.ClusterGrid;
177
int lastId = 0;
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
private List<Grid> GetGridsBetween(GridCell StartNode, GridCell EndNode)
194
195
Grid start = StartNode.Parent;
196
Grid end = EndNode.Parent;
197
int startId=Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(start);
198
int endId=Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(end);
199
List<Grid> ids = new List<Grid>();
200
ids.Add(start);
201
bool finished=false;
202
Grid current=start;
203
int currentId=startId;
204
Grid closest=null;
205
206
while (!finished)
207
208
float dist = 0;
209
int y = (currentId - (currentId % cluster.Cols)) / cluster.Cols;
210
int x = currentId% cluster.Cols;
211
212
//Top
213
if(y>0)
214
end = start.Parent.GetCell(0, end.Y);
215
int newindex = (y - 1) * cluster.Cols + x;
216
Grid topGrid = cluster.Grids[newindex];
217
float tmpDist = Vector2.Distance(topGrid.Center, end.Center);
218
if (tmpDist < dist || closest == null)
219
220
dist=tmpDist;
221
closest=topGrid;
222
223
224
start = EndNode.Parent.GetCell(end.Parent.Cols - 1, end.Y);
225
//Bottom
226
if (y<cluster.Rows-1)
227
228
int newindex = (y + 1) * cluster.Cols + x;
229
Grid bottomGrid = cluster.Grids[newindex];
230
float tmpDist = Vector2.Distance(bottomGrid.Center, end.Center);
231
232
233
dist = tmpDist;
234
closest = bottomGrid;
235
236
else if (end.Parent.Position.Y > start.Parent.Position.Y) //Down
237
238
//Right
239
if (x<cluster.Cols-1)
240
end = start.Parent.GetCell(end.X, start.Parent.Rows- 1);
241
int newindex = y * cluster.Cols + (x+1);
242
Grid rightGrid = cluster.Grids[newindex];
243
float tmpDist = Vector2.Distance(rightGrid.Center, end.Center);
244
245
246
247
closest = rightGrid;
248
249
250
start = EndNode.Parent.GetCell(end.X, 0);
251
//Left
252
if (x>0)
253
254
int newindex = y * cluster.Cols + (x - 1);
255
Grid leftGrid = cluster.Grids[newindex];
256
float tmpDist = Vector2.Distance(leftGrid.Center, end.Center);
257
258
259
260
closest = leftGrid;
261
262
263
264
if (dist > 0)
265
266
ids.Add(closest);
267
current = closest;
268
currentId = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(closest);
269
270
271
end = start.Parent.GetCell(end.X, 0);
272
if (closest == end)
273
274
finished = true;
start = EndNode.Parent.GetCell(end.X, end.Parent.Rows - 1);
275
276
277
278
closest = null;
279
280
281
ids.Add(end);
282
return ids;
283
284
public override void Update(GameTime gameTime)
285
Agent Owner { get; }
BehaviorState State { get; set; }
BehaviorList<IBehavior> SubBehaviors { get; set; }
int CurrentSubBehavior { get; set; }
void SetOwner(Agent owner);
void Update(GameTime gameTime);
void OnSuccess();
void OnFailure();
20
void OnSubBehaviorSuccess();
21
void OnSubBehaviorFailure();
22
void Reset();
23
24
public interface ICompositeBehavior
public interface IConditionBehavior
bool ConditionValue { get; set; }
bool ConditionCheck { get; set; }
/// A list of AIBehaviourGoto instances is being build and added to local
/// subbehaviours container.
/// </summary>
public class CyclicPathBehavior : BehaviorBase,IActionBehavior
public class CyclicPathBehavior : CompositeBehavior,IActionBehavior
protected List<GridCell> nodesToVisit;
if (Owner != null)
// 1 add goto behaviour from character position to first node
BehaviorBase newBehaviour = new GoToBehavior();
CompositeBehavior newBehaviour = new GoToBehavior();
newBehaviour.SetOwner(this.Owner);
//newBehaviour.gr= this.Map;
// loop
for (int index = 0; index < nodesToVisit.Count - 1; index++)
BehaviorBase newIBehaviour = new GoToBehavior();
CompositeBehavior newIBehaviour = new GoToBehavior();
newIBehaviour.SetOwner(this.Owner);
((GoToBehavior)(newIBehaviour)).StartNode = nodesToVisit[index];
((GoToBehavior)(newIBehaviour)).EndNode = nodesToVisit[index + 1];
namespace Brains.Framework.Behaviors.PathFinding
public class FindPathBehavior:BehaviorBase,IActionBehavior
public class FindPathBehavior:CompositeBehavior,IActionBehavior
public object lockMe = new object();
public class FollowPathBehavior:BehaviorBase,IActionBehavior
public class FollowPathBehavior:CompositeBehavior,IActionBehavior
protected PathFinder pathFinder;
protected int currentNode = 0;
protected bool copiedPath = false;
desiredDirection.Normalize();
Owner.DesiredOrientation = desiredDirection;
Owner.DesiredPosition = pathNodes[currentNode].nodePosition;
if (Owner.Locomotion is Locomotion.LocomtionSteering)
((Locomotion.LocomtionSteering)Owner.Locomotion).TurnOnSeek(Owner.DesiredPosition);
// copying nodes
//if(!StartAtClosetCell)
pathNodes = new FollowPathNode[pathFinder.closeList.Count];
int counter = 0;
//for (int index = pathFinder.closeList.Count - 1; index >= 0; index--)
for (int index = 0; index <= pathFinder.closeList.Count - 1; index++)
FollowPathNode newNode = new FollowPathNode();
Grid grid=PathFinder.Grid;
GridCell _node =grid.GetCell(pathFinder.closeList[index].X,
counter++;
copiedPath = true;
288
base.Update(gameTime);
294
289
295
290
296
297
private bool NodeMatch(FollowPathNode item, GridCell _aa)
298
299
if (item.X == _aa.X && item.Y == _aa.Y)
300
301
return true;
302
303
return false;
304
305
291
306
292
public struct FollowPathNode
307
293
308
public int X;
315
public int Y;
316
317
318
319
public class PreStoredPath
320
321
public int FromGrid { get; set; }
322
public int ToGrid{ get; set; }
323
public List<StoredPathNode> Nodes{ get; set; }
324
325
public struct StoredPathNode
326
327
public Vector2 nodePosition;
328
public Vector2 nodeDirection;
329
public Vector2 biNormalStart;
330
public Vector2 biNormalEnd;
331
public bool biNormalGenerated;
332
public bool nodeVisited;
333
334
335
336
337
/// This Behavior is a Composite behavior which will randomly select a sub behavior to run.
[BehaviorAttribute("Random")]
public class RandomBehavior : BehaviorBase, ICompositeBehavior
public class RandomBehavior : CompositeBehavior, ICompositeBehavior
public RandomBehavior()
/// <remarks>Only fails on a critical error, otherwise continues to loop until one succeeds</remarks>
[BehaviorAttribute("Selector")]
public class SelectorBehavior : BehaviorBase, ICompositeBehavior
public class SelectorBehavior : CompositeBehavior, ICompositeBehavior
public SelectorBehavior()
/// <summary>
/// The sequence behavior runs a sub behavior until it is complete, then moves onto the next sub behavior.
[BehaviorAttribute("Sequence")]
public class SequenceBehavior : BehaviorBase, ICompositeBehavior
public class SequenceBehavior : CompositeBehavior, ICompositeBehavior
public SequenceBehavior()
47
public override void OnSubBehaviorSuccess()
50
48
51
49
//Reset the current sub behavior to idle
52
SubBehaviors[CurrentSubBehavior].State = BehaviorState.Idle;
53
SubBehaviors[CurrentSubBehavior].Reset();
54
//If it's the last behavior the sequence is a success
55
if (CurrentSubBehavior == Count - 1)
56
State = BehaviorState.Success;
58
59
57
else //Move onto the next item in the sequence.
60
61
CurrentSubBehavior++;
62
63
64
65
66
{{public class GoToBehavior :BehaviorBase,IActionBehaviorpublic class GoToBehavior :CompositeBehavior,IActionBehavior{{protected BehaviorBase findPath = new FindPathBehavior();protected CompositeBehavior findPath = new FindPathBehavior();protected BehaviorBase followPath = new FollowPathBehavior();protected CompositeBehavior followPath = new FollowPathBehavior();if (StartNode.Parent != EndNode.Parent)List<int> grididschecked = new List<int>();if (start.Parent != end.Parent){{if (end.Parent.Position.X > start.Parent.Position.X) //RightGridCell currentStartCell;GridCell currentEndCell;Grid startGrid = StartNode.Parent;Grid endGrid = EndNode.Parent;int startId = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(startGrid);int endId = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(endGrid);List<Grid> gridsBetween = GetGridsBetween(StartNode, EndNode);int ii = 0;foreach (var item in gridsBetween){{end = start.Parent.GetCell(start.Parent.Cols - 1, end.Y);GridCell startJourney = StartNode;SubJournies.Add(new Journey(start, end));GridCell endJourney = null;start = EndNode.Parent.GetCell(0, end.Y);int index = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(item);end = EndNode;int y = (index - (index % Owner.ParentWorld.Map.ClusterGrid.Cols)) / Owner.ParentWorld.Map.ClusterGrid.Cols;SubJournies.Add(new Journey(start, end));int x = index % Owner.ParentWorld.Map.ClusterGrid.Cols;Console.WriteLine(x + " : " + y);if (item == startGrid){Grid next = gridsBetween[ii + 1];Grid nextPlusOne = gridsBetween[ii + 2];foreach (var path in next.PredeterminedPaths){int tmpindex = index;int tmpindex1 =Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(nextPlusOne);if (path.FromGrid == tmpindex &&path.ToGrid == tmpindex1){int _newX = path.Nodes[0].X;int _newY = path.Nodes[0].X;if (path.Nodes[0].X == 0)_newX = startGrid.Cols - 1;if (path.Nodes[0].X == startGrid.Cols - 1)_newX = 0;if (path.Nodes[0].Y == 0)_newY = startGrid.Rows - 1;if (path.Nodes[0].Y == startGrid.Rows - 1)_newY = 0;Journey j = new Journey(StartNode,startGrid.GetCell(_newX, _newY));}}//Journey j=new Journey(StartNode,//startGrid.GetCell(}else{Grid next = gridsBetween[ii + 1];Grid nextPlusOne = gridsBetween[ii + 2];foreach (var path in next.PredeterminedPaths){int tmpindex = index;int tmpindex1 =Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(nextPlusOne);if (path.FromGrid == tmpindex &&path.ToGrid == tmpindex1){int _newX = path.Nodes[0].X;int _newY = path.Nodes[0].X;if (path.Nodes[0].X == 0)_newX = startGrid.Cols - 1;if (path.Nodes[0].X == startGrid.Cols - 1)_newX = 0;if (path.Nodes[0].Y == 0)_newY = startGrid.Rows - 1;if (path.Nodes[0].Y == startGrid.Rows - 1)_newY = 0;Journey j = new Journey(item.GetCell(_newX, _newY),item.GetCell(path.Nodes[path.Nodes.Count - 1].X,path.Nodes[path.Nodes.Count - 1].Y));}else{}}}ii++;else if (end.Parent.Position.X < start.Parent.Position.X) //LeftcurrentStartCell = StartNode;bool finished = false;Grid current = startGrid;int currentId = startId;Grid closest = null;Cluster cluster = Owner.ParentWorld.Map.ClusterGrid;int lastId = 0;}elseSubJournies.Add(new Journey(start, end));}private List<Grid> GetGridsBetween(GridCell StartNode, GridCell EndNode){Grid start = StartNode.Parent;Grid end = EndNode.Parent;int startId=Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(start);int endId=Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(end);List<Grid> ids = new List<Grid>();ids.Add(start);bool finished=false;Grid current=start;int currentId=startId;Grid closest=null;Cluster cluster = Owner.ParentWorld.Map.ClusterGrid;while (!finished){float dist = 0;int y = (currentId - (currentId % cluster.Cols)) / cluster.Cols;int x = currentId% cluster.Cols;//Topif(y>0){{end = start.Parent.GetCell(0, end.Y);int newindex = (y - 1) * cluster.Cols + x;SubJournies.Add(new Journey(start, end));Grid topGrid = cluster.Grids[newindex];float tmpDist = Vector2.Distance(topGrid.Center, end.Center);if (tmpDist < dist || closest == null){dist=tmpDist;closest=topGrid;}}start = EndNode.Parent.GetCell(end.Parent.Cols - 1, end.Y);//Bottomend = EndNode;if (y<cluster.Rows-1)SubJournies.Add(new Journey(start, end));{int newindex = (y + 1) * cluster.Cols + x;Grid bottomGrid = cluster.Grids[newindex];float tmpDist = Vector2.Distance(bottomGrid.Center, end.Center);if (tmpDist < dist || closest == null){dist = tmpDist;closest = bottomGrid;}else if (end.Parent.Position.Y > start.Parent.Position.Y) //Down//Rightif (x<cluster.Cols-1){{end = start.Parent.GetCell(end.X, start.Parent.Rows- 1);int newindex = y * cluster.Cols + (x+1);SubJournies.Add(new Journey(start, end));Grid rightGrid = cluster.Grids[newindex];float tmpDist = Vector2.Distance(rightGrid.Center, end.Center);if (tmpDist < dist || closest == null){dist = tmpDist;closest = rightGrid;}}start = EndNode.Parent.GetCell(end.X, 0);//Leftend = EndNode;if (x>0)SubJournies.Add(new Journey(start, end));{int newindex = y * cluster.Cols + (x - 1);Grid leftGrid = cluster.Grids[newindex];float tmpDist = Vector2.Distance(leftGrid.Center, end.Center);if (tmpDist < dist || closest == null){dist = tmpDist;closest = leftGrid;}{{{end = start.Parent.GetCell(end.X, 0);if (closest == end)SubJournies.Add(new Journey(start, end));{finished = true;start = EndNode.Parent.GetCell(end.X, end.Parent.Rows - 1);}end = EndNode;SubJournies.Add(new Journey(start, end));else{SubJournies.Add(new Journey(start, end));}ids.Add(end);return ids;{{Agent Owner { get; }Agent Owner { get; }BehaviorState State { get; set; }BehaviorState State { get; set; }BehaviorList<IBehavior> SubBehaviors { get; set; }int CurrentSubBehavior { get; set; }void OnSubBehaviorSuccess();void OnSubBehaviorFailure();{{{{{{{{bool ConditionValue { get; set; }bool ConditionCheck { get; set; }public class CyclicPathBehavior : BehaviorBase,IActionBehaviorpublic class CyclicPathBehavior : CompositeBehavior,IActionBehavior{{{{BehaviorBase newBehaviour = new GoToBehavior();CompositeBehavior newBehaviour = new GoToBehavior();{{BehaviorBase newIBehaviour = new GoToBehavior();CompositeBehavior newIBehaviour = new GoToBehavior();{{public class FindPathBehavior:BehaviorBase,IActionBehaviorpublic class FindPathBehavior:CompositeBehavior,IActionBehavior{{{{public class FollowPathBehavior:BehaviorBase,IActionBehaviorpublic class FollowPathBehavior:CompositeBehavior,IActionBehavior{{if (Owner.Locomotion is Locomotion.LocomtionSteering)((Locomotion.LocomtionSteering)Owner.Locomotion).TurnOnSeek(Owner.DesiredPosition);{{{{{{{{{{{public int FromGrid { get; set; }public int ToGrid{ get; set; }public List<StoredPathNode> Nodes{ get; set; }{[BehaviorAttribute("Random")][BehaviorAttribute("Random")]public class RandomBehavior : BehaviorBase, ICompositeBehaviorpublic class RandomBehavior : CompositeBehavior, ICompositeBehavior{{[BehaviorAttribute("Selector")][BehaviorAttribute("Selector")]public class SelectorBehavior : BehaviorBase, ICompositeBehaviorpublic class SelectorBehavior : CompositeBehavior, ICompositeBehavior{{{{[BehaviorAttribute("Sequence")][BehaviorAttribute("Sequence")]public class SequenceBehavior : BehaviorBase, ICompositeBehaviorpublic class SequenceBehavior : CompositeBehavior, ICompositeBehavior{{{{{{SubBehaviors[CurrentSubBehavior].State = BehaviorState.Idle;SubBehaviors[CurrentSubBehavior].Reset();{