+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Content;\r
+using Microsoft.Xna.Framework.Graphics;\r
+\r
+namespace CarFire\r
+{\r
+ public enum AiState\r
+ {\r
+ Standing,\r
+ Pacing,\r
+ Chasing,\r
+ Dazed,\r
+ Fighting,\r
+ Retreating\r
+ }\r
+\r
+\r
+ public class SaberMonster : IMonster\r
+ {\r
+ public SaberMonster(char identifier, Point position, Dictionary<string, string> info, Game game)\r
+ {\r
+ mId = identifier;\r
+ mMotion = new MovementManager(position);\r
+ mGame = game;\r
+\r
+ string speedString;\r
+ if (info.TryGetValue("speed", out speedString))\r
+ {\r
+ int? speed = Parse.Integer(speedString);\r
+ if (speed != null) mMotion.Speed = speed.Value;\r
+ }\r
+\r
+ // Get the "idle path" coordinates loaded from the map.\r
+ string idlePath;\r
+ if (info.TryGetValue("path", out idlePath))\r
+ {\r
+ string[] idlePathPoints = Parse.List(idlePath);\r
+ foreach (string pathPoint in idlePathPoints)\r
+ {\r
+ Point? point = Parse.Coordinates(pathPoint);\r
+ if (point != null) mIdlePath.Add(point.Value);\r
+ }\r
+ }\r
+\r
+ StartPacing();\r
+ }\r
+\r
+\r
+ public void StartPacing()\r
+ {\r
+ mState = AiState.Pacing;\r
+\r
+ if (mIdlePath.Count == 0) return;\r
+\r
+ // Determine the best (closest) waypoint to start at.\r
+ mIdlePathIndex = 0;\r
+ int closest = int.MaxValue;\r
+ for (int i = 0; i < mIdlePath.Count; i++)\r
+ {\r
+ int distance = PathFinder.GetManhattanDistance(Coordinates, mIdlePath[i]);\r
+ if (distance < closest)\r
+ {\r
+ mIdlePathIndex = i;\r
+ closest = distance;\r
+ }\r
+ }\r
+\r
+ PathFinder pathFinder = new PathFinder(mGame.Grid);\r
+ mPath = new List<Point>(32);\r
+ mPath.Add(Coordinates);\r
+ mPath.AddRange(pathFinder.GetPath(mMotion.Coordinates, mIdlePath[mIdlePathIndex]));\r
+ mPath.Add(mIdlePath[mIdlePathIndex]);\r
+ mPathIndex = 0;\r
+ }\r
+\r
+ Direction GetDirectionToNextCell()\r
+ {\r
+ if (mPathIndex >= mPath.Count)\r
+ {\r
+ mIdlePathIndex++;\r
+ PathFinder pathFinder = new PathFinder(mGame.Grid);\r
+ mPath = new List<Point>(32);\r
+ mPath.Add(Coordinates);\r
+ mPath.AddRange(pathFinder.GetPath(mMotion.Coordinates, mIdlePath[mIdlePathIndex % mIdlePath.Count]));\r
+ mPath.Add(mIdlePath[mIdlePathIndex % mIdlePath.Count]);\r
+ mPathIndex = 0;\r
+ }\r
+\r
+ if (mPath[mPathIndex % mPath.Count] == mMotion.Coordinates)\r
+ {\r
+ mPathIndex++;\r
+ mPathDirection = MovementManager.GetDirection(mMotion.Coordinates, mPath[mPathIndex % mPath.Count]);\r
+ }\r
+\r
+ return mPathDirection;\r
+ }\r
+\r
+\r
+ #region IMonster Members\r
+\r
+ public bool visible\r
+ {\r
+ get { throw new NotImplementedException(); }\r
+ }\r
+\r
+ #endregion\r
+\r
+\r
+ #region ICharacter Members\r
+\r
+ public void LoadContent(ContentManager contentManager)\r
+ {\r
+ mTexture = contentManager.Load<Texture2D>("menuItem");\r
+ }\r
+\r
+ public void Update(TimeSpan timeSpan)\r
+ {\r
+ if (mState == AiState.Pacing)\r
+ {\r
+ mMotion.Update(timeSpan, GetDirectionToNextCell());\r
+ }\r
+ }\r
+\r
+ public void Draw(SpriteBatch spriteBatch)\r
+ {\r
+ Rectangle position = mGame.State.Map.GetRectangleFromCoordinates(mMotion.Position);\r
+ spriteBatch.Draw(mTexture, position, Color.White);\r
+ }\r
+\r
+ public int Health\r
+ {\r
+ get { throw new NotImplementedException(); }\r
+ }\r
+\r
+ public void causeDamageTo(int amount)\r
+ {\r
+ throw new NotImplementedException();\r
+ }\r
+\r
+ public Vector2 Position { get { return mMotion.Position; } }\r
+\r
+ public Point Coordinates { get { return mMotion.Coordinates; } }\r
+\r
+ #endregion\r
+\r
+\r
+ #region Private Variables\r
+\r
+ Game mGame;\r
+\r
+ char mId;\r
+ MovementManager mMotion;\r
+\r
+ List<Point> mIdlePath = new List<Point>();\r
+ int mIdlePathIndex;\r
+\r
+ List<Point> mPath;\r
+ int mPathIndex;\r
+ Direction mPathDirection;\r
+\r
+ AiState mState;\r
+\r
+ Texture2D mTexture;\r
+\r
+ #endregion\r
+ }\r
+}\r