Changeset 22

User picture

Author: conkerjo

(2009/07/05 18:01) Over 2 years ago

Behavior Refactoring

Affected files

Added src/BRAINSFramework/Behaviors/CompositeBehavior.cs

Show contents

Added src/BRAINSFramework/Behaviors/ConditionBehavior.cs

Show contents

Added src/BRAINSFramework/Behaviors/DecoratorBehavior.cs

Show contents

Updated src/BRAINSFramework/Behaviors/GoToBehavior.cs Download diff

2122
6
using Brains.Framework.Behaviors.PathFinding;
6
using Brains.Framework.Behaviors.PathFinding;
7
using Microsoft.Xna.Framework;
7
using Microsoft.Xna.Framework;
8
using Brains.Framework.Map;
8
using Brains.Framework.Map;
9
using Brains.Framework.Utility;
9
10
10
namespace Brains.Framework.Behaviors
11
namespace Brains.Framework.Behaviors
11
{
12
{
12
    public class GoToBehavior :BehaviorBase,IActionBehavior
13
    public class GoToBehavior :CompositeBehavior,IActionBehavior
13
    {
14
    {
14
        protected BehaviorBase findPath = new FindPathBehavior();
15
        protected CompositeBehavior findPath = new FindPathBehavior();
15
        protected BehaviorBase followPath = new FollowPathBehavior();
16
        protected CompositeBehavior followPath = new FollowPathBehavior();
16
        GridCell _startNode;
17
        GridCell _startNode;
17
        GridCell _endNode;
18
        GridCell _endNode;
18
        Journey currentJourney;
19
        Journey currentJourney;
...
...
75
            SubJournies.Clear();
76
            SubJournies.Clear();
76
            GridCell start = StartNode;
77
            GridCell start = StartNode;
77
            GridCell end = EndNode;
78
            GridCell end = EndNode;
78
            if (StartNode.Parent != EndNode.Parent)
79
            
80
            List<int> grididschecked = new List<int>();
81
            if (start.Parent != end.Parent)
79
            {
82
            {
80
                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)
81
                {
96
                {
82
                    end = start.Parent.GetCell(start.Parent.Cols - 1, end.Y);
97
                    GridCell startJourney = StartNode;
83
                    SubJournies.Add(new Journey(start, end));
98
                    GridCell endJourney = null;
84
99
85
                    start = EndNode.Parent.GetCell(0, end.Y);
100
                    int index = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(item);
86
                    end = EndNode;
101
                    int y = (index - (index % Owner.ParentWorld.Map.ClusterGrid.Cols)) / Owner.ParentWorld.Map.ClusterGrid.Cols;
87
                    SubJournies.Add(new Journey(start, end));
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
                        Grid next = gridsBetween[ii + 1];
138
                        Grid nextPlusOne = gridsBetween[ii + 2];
139
                        foreach (var path in next.PredeterminedPaths)
140
                        {
141
                            int tmpindex = index;
142
                            int tmpindex1 =
143
                                Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(nextPlusOne);
144
                            if (path.FromGrid == tmpindex &&
145
                                path.ToGrid == tmpindex1)
146
                            {
147
                                int _newX = path.Nodes[0].X;
148
                                int _newY = path.Nodes[0].X;
149
                                if (path.Nodes[0].X == 0)
150
                                    _newX = startGrid.Cols - 1;
151
                                if (path.Nodes[0].X == startGrid.Cols - 1)
152
                                    _newX = 0;
153
                                if (path.Nodes[0].Y == 0)
154
                                    _newY = startGrid.Rows - 1;
155
                                if (path.Nodes[0].Y == startGrid.Rows - 1)
156
                                    _newY = 0;
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
                            else
163
                            {
164
                            }
165
                        }
166
                    }
167
                    ii++;
88
                }
168
                }
89
                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
            else
184
                SubJournies.Add(new Journey(start, end));
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
            Cluster cluster = Owner.ParentWorld.Map.ClusterGrid;
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)
90
                {
214
                {
91
                    end = start.Parent.GetCell(0, end.Y);
215
                    int newindex = (y - 1) * cluster.Cols + x;
92
                    SubJournies.Add(new Journey(start, end));
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
                }
93
224
94
                    start = EndNode.Parent.GetCell(end.Parent.Cols - 1, end.Y);
225
                //Bottom
95
                    end = EndNode;
226
                if (y<cluster.Rows-1)
96
                    SubJournies.Add(new Journey(start, end));
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
                    if (tmpDist < dist || closest == null)
232
                    {
233
                        dist = tmpDist;
234
                        closest = bottomGrid;
235
                    }
97
                }
236
                }
98
                else if (end.Parent.Position.Y > start.Parent.Position.Y) //Down
237
238
                //Right
239
                if (x<cluster.Cols-1)
99
                {
240
                {
100
                    end = start.Parent.GetCell(end.X, start.Parent.Rows- 1);
241
                    int newindex = y * cluster.Cols + (x+1);
101
                    SubJournies.Add(new Journey(start, end));
242
                    Grid rightGrid = cluster.Grids[newindex];
243
                    float tmpDist = Vector2.Distance(rightGrid.Center, end.Center);
244
                    if (tmpDist < dist || closest == null)
245
                    {
246
                        dist = tmpDist;
247
                        closest = rightGrid;
248
                    }
249
                }
102
250
103
                    start = EndNode.Parent.GetCell(end.X, 0);
251
                //Left
104
                    end = EndNode;
252
                if (x>0)
105
                    SubJournies.Add(new Journey(start, end));
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
                    if (tmpDist < dist || closest == null)
258
                    {
259
                        dist = tmpDist;
260
                        closest = leftGrid;
261
                    }
106
                }
262
                }
263
264
                if (dist > 0)
265
                {
266
                    ids.Add(closest);
267
                    current = closest;
268
                    currentId = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(closest);
269
                }
107
                else
270
                else
108
                {
271
                {
109
                    end = start.Parent.GetCell(end.X, 0);
272
                    if (closest == end)
110
                    SubJournies.Add(new Journey(start, end));
273
                    {
111
274
                        finished = true;
112
                    start = EndNode.Parent.GetCell(end.X, end.Parent.Rows - 1);
275
                    }
113
                    end = EndNode;
114
                    SubJournies.Add(new Journey(start, end));
115
                }
276
                }
277
                
278
                closest = null;
116
            }
279
            }
117
            else
118
            {
119
                SubJournies.Add(new Journey(start, end));
120
            }
121
280
122
            
281
            ids.Add(end);
282
            return ids;
123
        }
283
        }
124
284
125
        public override void Update(GameTime gameTime)
285
        public override void Update(GameTime gameTime)

Updated src/BRAINSFramework/Behaviors/IBehavior.cs Download diff

2122
11
    {
11
    {
12
        Agent Owner { get; }
12
        Agent Owner { get; }
13
        BehaviorState State { get; set; }
13
        BehaviorState State { get; set; }
14
        BehaviorList<IBehavior> SubBehaviors { get; set; }
14
        
15
        int CurrentSubBehavior { get; set; }
16
        void SetOwner(Agent owner);
15
        void SetOwner(Agent owner);
17
        void Update(GameTime gameTime);
16
        void Update(GameTime gameTime);
18
        void OnSuccess();
17
        void OnSuccess();
19
        void OnFailure();
18
        void OnFailure();
20
        void OnSubBehaviorSuccess();
21
        void OnSubBehaviorFailure();
22
        void Reset();
19
        void Reset();
23
    }
20
    }
21
    
24
}
22
}

Updated src/BRAINSFramework/Behaviors/ICompositeBehavior.cs Download diff

2122
8
{
8
{
9
    public interface ICompositeBehavior
9
    public interface ICompositeBehavior
10
    {
10
    {
11
11
    }
12
    }
12
}
13
}

Updated src/BRAINSFramework/Behaviors/IConditionBehavior.cs Download diff

2122
9
{
9
{
10
    public interface IConditionBehavior
10
    public interface IConditionBehavior
11
    {
11
    {
12
        bool ConditionValue { get; set; }
12
        bool ConditionCheck { get; set; }
13
    }
13
    }
14
}
14
}

Added src/BRAINSFramework/Behaviors/ISubBehaviorHolder.cs

Show contents

Added src/BRAINSFramework/Behaviors/ParallelBehavior.cs

Show contents

Updated src/BRAINSFramework/Behaviors/PathFinding/CyclicPathBehavior.cs Download diff

2122
17
    /// A list of AIBehaviourGoto instances is being build and added to local 
17
    /// A list of AIBehaviourGoto instances is being build and added to local 
18
    /// subbehaviours container.
18
    /// subbehaviours container.
19
    /// </summary>
19
    /// </summary>
20
    public class CyclicPathBehavior : BehaviorBase,IActionBehavior
20
    public class CyclicPathBehavior : CompositeBehavior,IActionBehavior
21
    {
21
    {
22
22
23
        protected List<GridCell> nodesToVisit;
23
        protected List<GridCell> nodesToVisit;
...
...
79
                if (Owner != null)
79
                if (Owner != null)
80
                {
80
                {
81
                    // 1 add goto behaviour from character position to first node
81
                    // 1 add goto behaviour from character position to first node
82
                    BehaviorBase newBehaviour = new GoToBehavior();
82
                    CompositeBehavior newBehaviour = new GoToBehavior();
83
                    newBehaviour.SetOwner(this.Owner);
83
                    newBehaviour.SetOwner(this.Owner);
84
                    //newBehaviour.gr= this.Map;
84
                    //newBehaviour.gr= this.Map;
85
85
86
                    // loop
86
                    // loop
87
                    for (int index = 0; index < nodesToVisit.Count - 1; index++)
87
                    for (int index = 0; index < nodesToVisit.Count - 1; index++)
88
                    {
88
                    {
89
                        BehaviorBase newIBehaviour = new GoToBehavior();
89
                        CompositeBehavior newIBehaviour = new GoToBehavior();
90
                        newIBehaviour.SetOwner(this.Owner);
90
                        newIBehaviour.SetOwner(this.Owner);
91
                        ((GoToBehavior)(newIBehaviour)).StartNode = nodesToVisit[index];
91
                        ((GoToBehavior)(newIBehaviour)).StartNode = nodesToVisit[index];
92
                        ((GoToBehavior)(newIBehaviour)).EndNode = nodesToVisit[index + 1];
92
                        ((GoToBehavior)(newIBehaviour)).EndNode = nodesToVisit[index + 1];

Updated src/BRAINSFramework/Behaviors/PathFinding/FindPathBehavior.cs Download diff

2122
9
9
10
namespace Brains.Framework.Behaviors.PathFinding
10
namespace Brains.Framework.Behaviors.PathFinding
11
{
11
{
12
    public class FindPathBehavior:BehaviorBase,IActionBehavior
12
    public class FindPathBehavior:CompositeBehavior,IActionBehavior
13
    {
13
    {
14
        public object lockMe = new object();
14
        public object lockMe = new object();
15
        
15
        

Updated src/BRAINSFramework/Behaviors/PathFinding/FollowPathBehavior.cs Download diff

2122
9
9
10
namespace Brains.Framework.Behaviors.PathFinding
10
namespace Brains.Framework.Behaviors.PathFinding
11
{
11
{
12
    public class FollowPathBehavior:BehaviorBase,IActionBehavior
12
    public class FollowPathBehavior:CompositeBehavior,IActionBehavior
13
    {
13
    {
14
        
14
        protected PathFinder pathFinder;
15
        protected PathFinder pathFinder;
15
        protected int currentNode = 0;
16
        protected int currentNode = 0;
16
        protected bool copiedPath = false;
17
        protected bool copiedPath = false;
...
...
173
                                desiredDirection.Normalize();
174
                                desiredDirection.Normalize();
174
                                Owner.DesiredOrientation = desiredDirection;
175
                                Owner.DesiredOrientation = desiredDirection;
175
                                Owner.DesiredPosition = pathNodes[currentNode].nodePosition;
176
                                Owner.DesiredPosition = pathNodes[currentNode].nodePosition;
176
177
                                if (Owner.Locomotion is Locomotion.LocomtionSteering)
178
                                    ((Locomotion.LocomtionSteering)Owner.Locomotion).TurnOnSeek(Owner.DesiredPosition);
177
                            }
179
                            }
178
                            else
180
                            else
179
                            {
181
                            {
...
...
247
                        }
249
                        }
248
                        else
250
                        else
249
                        {
251
                        {
252
250
                            // copying nodes
253
                            // copying nodes
254
                            //if(!StartAtClosetCell)  
251
                            pathNodes = new FollowPathNode[pathFinder.closeList.Count];
255
                            pathNodes = new FollowPathNode[pathFinder.closeList.Count];
252
                            int counter = 0;
256
                            int counter = 0;
253
                            //for (int index = pathFinder.closeList.Count - 1; index >= 0; index--)
257
                            //for (int index = pathFinder.closeList.Count - 1; index >= 0; index--)
254
                            for (int index = 0; index <= pathFinder.closeList.Count - 1; index++)
258
                            for (int index = 0; index <= pathFinder.closeList.Count - 1; index++)
255
                            {
259
                            {
260
                                
256
                                FollowPathNode newNode = new FollowPathNode();
261
                                FollowPathNode newNode = new FollowPathNode();
257
                                Grid grid=PathFinder.Grid;
262
                                Grid grid=PathFinder.Grid;
258
                                GridCell _node =grid.GetCell(pathFinder.closeList[index].X,
263
                                GridCell _node =grid.GetCell(pathFinder.closeList[index].X,
...
...
268
                                counter++;
273
                                counter++;
269
                            }
274
                            }
270
275
276
                            
271
                            copiedPath = true;
277
                            copiedPath = true;
272
278
273
                        }
279
                        }
...
...
288
            base.Update(gameTime);
294
            base.Update(gameTime);
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
    public struct FollowPathNode
293
    {
308
    {
...
...
300
        public int X;
315
        public int X;
301
        public int Y;
316
        public int Y;
302
    }
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
        public int X;
334
        public int Y;
335
        
336
    }
303
}
337
}

Updated src/BRAINSFramework/Behaviors/RandomBehavior.cs Download diff

2122
12
    /// This Behavior is a Composite behavior which will randomly select a sub behavior to run.
12
    /// This Behavior is a Composite behavior which will randomly select a sub behavior to run.
13
    /// </summary>
13
    /// </summary>
14
    [BehaviorAttribute("Random")]
14
    [BehaviorAttribute("Random")]
15
    public class RandomBehavior : BehaviorBase, ICompositeBehavior
15
    public class RandomBehavior : CompositeBehavior, ICompositeBehavior
16
    {
16
    {
17
17
18
        public RandomBehavior()
18
        public RandomBehavior()

Updated src/BRAINSFramework/Behaviors/SelectorBehavior.cs Download diff

2122
14
    /// </summary>
14
    /// </summary>
15
    /// <remarks>Only fails on a critical error, otherwise continues to loop until one succeeds</remarks>
15
    /// <remarks>Only fails on a critical error, otherwise continues to loop until one succeeds</remarks>
16
    [BehaviorAttribute("Selector")]
16
    [BehaviorAttribute("Selector")]
17
    public class SelectorBehavior : BehaviorBase, ICompositeBehavior
17
    public class SelectorBehavior : CompositeBehavior, ICompositeBehavior
18
    {
18
    {
19
19
20
        public SelectorBehavior()
20
        public SelectorBehavior()

Updated src/BRAINSFramework/Behaviors/SequenceBehavior.cs Download diff

2122
8
8
9
namespace Brains.Framework.Behaviors
9
namespace Brains.Framework.Behaviors
10
{
10
{
11
    /// <summary>
12
    /// The sequence behavior runs a sub behavior until it is complete, then moves onto the next sub behavior.
13
    /// </summary>
11
    [BehaviorAttribute("Sequence")]
14
    [BehaviorAttribute("Sequence")]
12
    public class SequenceBehavior : BehaviorBase, ICompositeBehavior
15
    public class SequenceBehavior : CompositeBehavior, ICompositeBehavior
13
    {
16
    {
14
      
17
      
15
        public SequenceBehavior()
18
        public SequenceBehavior()
16
        {
19
        {
17
20
            
18
        }
21
        }
19
        
22
        
20
        public override void Update(GameTime gameTime)
23
        public override void Update(GameTime gameTime)
...
...
47
        public override void OnSubBehaviorSuccess()
50
        public override void OnSubBehaviorSuccess()
48
        {
51
        {
49
            //Reset the current sub behavior to idle
52
            //Reset the current sub behavior to idle
50
            SubBehaviors[CurrentSubBehavior].State = BehaviorState.Idle;
53
            SubBehaviors[CurrentSubBehavior].Reset();
51
54
52
            //If it's the last behavior the sequence is a success
55
            //If it's the last behavior the sequence is a success
53
            if (CurrentSubBehavior == Count - 1)
56
            if (CurrentSubBehavior == Count - 1)
...
...
55
                State = BehaviorState.Success;
58
                State = BehaviorState.Success;
56
            }
59
            }
57
            else //Move onto the next item in the sequence.
60
            else //Move onto the next item in the sequence.
61
            {   
58
                CurrentSubBehavior++;
62
                CurrentSubBehavior++;
63
            }
59
64
60
        }
65
        }
61
    }
66
    }

Added src/BRAINSFramework/Behaviors/TaskBehavior.cs

Show contents