root/src/BRAINSFramework/Behaviors/GoToBehavior.cs

User picture

Author: conkerjo

Revision: 30 («Previous)


File Size: 12.5 KB

(July 05, 2009 18:01 UTC) Almost 3 years ago

Behavior Refactoring

 
Show/hide line numbers

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Brains.Framework.Behaviors.PathFinding;
using Microsoft.Xna.Framework;
using Brains.Framework.Map;
using Brains.Framework.Utility;

namespace Brains.Framework.Behaviors
{
    public class GoToBehavior :CompositeBehavior,IActionBehavior
    {
        protected CompositeBehavior findPath = new FindPathBehavior();
        protected CompositeBehavior followPath = new FollowPathBehavior();
        GridCell _startNode;
        GridCell _endNode;
        Journey currentJourney;
        protected float tolerance;

        // How far from the desiret path a character can deviate and still
        // be recognised as if following path exactly.
        public float Tolarance
        {
            get { return tolerance; }
            set
            {
                tolerance = value;
                // propagate new tolerance value to the follow path behaviour
                if (followPath != null)
                {
                    ((FollowPathBehavior)(followPath)).Tolerance = value;
                }
            }
        }

        public GridCell StartNode
        {
            get { return _startNode; }
            set
            {
                if (value != null)
                {
                    _startNode= value;
                }
            }
        }

        public GridCell EndNode
        {
            get { return _endNode; }
            set
            {
                if (value != null)
                {
                    _endNode = value;
                }
            }
        }

        public GoToBehavior():base()
        {
            SubBehaviors.Add(findPath);
            SubBehaviors.Add(followPath);
        }

        ~GoToBehavior()
        {
            findPath = null;
            followPath = null;
        }
        public override void Reset()
        {
            currentJourney = null;
            SubJournies.Clear();
            GridCell start = StartNode;
            GridCell end = EndNode;
            
            List<int> grididschecked = new List<int>();
            if (start.Parent != end.Parent)
            {
                GridCell 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)
                {
                    GridCell startJourney = StartNode;
                    GridCell endJourney = null;

                    int index = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(item);
                    int y = (index - (index % Owner.ParentWorld.Map.ClusterGrid.Cols)) / Owner.ParentWorld.Map.ClusterGrid.Cols;
                    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++;
                }
                currentStartCell = StartNode;

                bool finished = false;
                Grid current = startGrid;
                int currentId = startId;

                Grid closest = null;
                Cluster cluster = Owner.ParentWorld.Map.ClusterGrid;
                int lastId = 0;




            }
            else
                SubJournies.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;
                
                //Top
                if(y>0)
                {
                    int newindex = (y - 1) * cluster.Cols + x;
                    Grid topGrid = cluster.Grids[newindex];
                    float tmpDist = Vector2.Distance(topGrid.Center, end.Center);
                    if (tmpDist < dist || closest == null)
                    {
                        dist=tmpDist;
                        closest=topGrid;
                    }
                }

                //Bottom
                if (y<cluster.Rows-1)
                {
                    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;
                    }
                }

                //Right
                if (x<cluster.Cols-1)
                {
                    int newindex = y * cluster.Cols + (x+1);
                    Grid rightGrid = cluster.Grids[newindex];
                    float tmpDist = Vector2.Distance(rightGrid.Center, end.Center);
                    if (tmpDist < dist || closest == null)
                    {
                        dist = tmpDist;
                        closest = rightGrid;
                    }
                }

                //Left
                if (x>0)
                {
                    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;
                    }
                }

                if (dist > 0)
                {
                    ids.Add(closest);
                    current = closest;
                    currentId = Owner.ParentWorld.Map.ClusterGrid.Grids.IndexOf(closest);
                }
                else
                {
                    if (closest == end)
                    {
                        finished = true;
                    }
                }
                
                closest = null;
            }

            ids.Add(end);
            return ids;
        }

        public override void Update(GameTime gameTime)
        {
            if (currentJourney == null && SubJournies.Count == 0)
            {
                Reset();
            }
            if (currentJourney == null && SubJournies.Count > 0)
            {
                currentJourney = SubJournies[0];
                ((FindPathBehavior)findPath).StartNode = currentJourney.StartNode;
                ((FindPathBehavior)findPath).EndNode= currentJourney.EndNode;
                ((FindPathBehavior)findPath).initialized = false;
            }
            if (((FindPathBehavior)findPath).StartNode != null &&
                ((FindPathBehavior)findPath).EndNode != null)
            {
                base.Update(gameTime);
            }
        }
        public override void OnSubBehaviorSuccess()
        {
            if (CurrentSubBehavior== 0)
            {
                Owner.Locomotion.Stationary = false;
                ((FollowPathBehavior)(followPath)).PathFinder =
                    ((FindPathBehavior)(findPath)).PathFinder;
                SubBehaviors[CurrentSubBehavior].State = BehaviorState.Idle;
                CurrentSubBehavior++;
            }
            else if (CurrentSubBehavior == 1)
            {
                SubJournies.Remove(currentJourney);
                currentJourney = null;
                SubBehaviors[CurrentSubBehavior].State = BehaviorState.Idle;
                ((FollowPathBehavior)SubBehaviors[CurrentSubBehavior]).Reset();
                ((FollowPathBehavior)SubBehaviors[CurrentSubBehavior]).PathFinder.Reset();
                
                CurrentSubBehavior = 0;
                if (SubJournies.Count == 0)
                {
                    Owner.Locomotion.Stationary = true;
                    State = BehaviorState.Success;
                }
            }

            base.OnSubBehaviorSuccess();
        }
        public List<Journey> SubJournies = new List<Journey>();
    }
    public class Journey
    {
        public GridCell StartNode { get; set; }
        public GridCell EndNode{ get; set; }
        public Journey(GridCell start, GridCell end)
        {
            StartNode = start;
            EndNode = end;
        }
    }
}