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); }