Exemple #1
0
        public override GameAction Think(Character controlledChar, bool preThink, IRandom rand)
        {
            if (controlledChar.CantWalk)
            {
                return(null);
            }

            List <Character> seenCharacters = new List <Character>();
            bool             seeLeader      = false;

            foreach (Character testChar in controlledChar.MemberTeam.IterateByRank())
            {
                if (testChar == controlledChar)
                {
                    if (preThink)//follow only leaders in pre-thinking
                    {
                        break;
                    }
                    else//settle for other partners in action
                    {
                        if (seeLeader)
                        {
                            continue;
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
                else if (controlledChar.IsInSightBounds(testChar.CharLoc))
                {
                    seenCharacters.Add(testChar);
                    seeLeader = true;
                }
            }

            //gravitate to the CLOSEST ally.
            //iterate in increasing character indices
            GameAction result = null;

            foreach (Character targetChar in seenCharacters)
            {
                //get the direction to that character
                //use A* to get this first direction?  check only walls?
                List <Loc>[] paths = GetPaths(controlledChar, new Loc[1] {
                    targetChar.CharLoc
                }, true, false);
                List <Loc> path      = paths[0];
                Dir8       dirToChar = DirExt.GetDir(controlledChar.CharLoc, targetChar.CharLoc);
                if (path.Count > 1)
                {
                    dirToChar = DirExt.GetDir(path[path.Count - 1], path[path.Count - 2]);
                }

                //is it possible to move in that direction?
                //if so, use it
                result = tryDir(controlledChar, targetChar, dirToChar, !preThink);
                if (result != null)
                {
                    return(result);
                }
                if (dirToChar.IsDiagonal())
                {
                    Loc  diff = controlledChar.CharLoc - targetChar.CharLoc;
                    DirH horiz;
                    DirV vert;
                    dirToChar.Separate(out horiz, out vert);
                    //start with the one that covers the most distance
                    if (Math.Abs(diff.X) < Math.Abs(diff.Y))
                    {
                        result = tryDir(controlledChar, targetChar, vert.ToDir8(), !preThink);
                        if (result != null)
                        {
                            return(result);
                        }
                        result = tryDir(controlledChar, targetChar, horiz.ToDir8(), !preThink);
                        if (result != null)
                        {
                            return(result);
                        }
                    }
                    else
                    {
                        result = tryDir(controlledChar, targetChar, horiz.ToDir8(), !preThink);
                        if (result != null)
                        {
                            return(result);
                        }
                        result = tryDir(controlledChar, targetChar, vert.ToDir8(), !preThink);
                        if (result != null)
                        {
                            return(result);
                        }
                    }
                }
                else
                {
                    result = tryDir(controlledChar, targetChar, DirExt.AddAngles(dirToChar, Dir8.DownLeft), !preThink);
                    if (result != null)
                    {
                        return(result);
                    }
                    result = tryDir(controlledChar, targetChar, DirExt.AddAngles(dirToChar, Dir8.DownRight), !preThink);
                    if (result != null)
                    {
                        return(result);
                    }
                }
            }

            //if a path can't be found to anyone, return false
            return(null);
        }