PageRenderTime 49ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/Classes/Object/Object.cs

http://github.com/Concliff/Maze
C# | 315 lines | 168 code | 40 blank | 107 comment | 26 complexity | 76ddb9d827ea0f17c485fbecd7a343eb MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Maze.Forms;
  6. namespace Maze.Classes
  7. {
  8. /// <summary>
  9. /// Specifies the type of object (or derived class) that an instance of the <see cref="Object"/> class represents.
  10. /// </summary>
  11. public enum ObjectTypes
  12. {
  13. /// <summary>
  14. /// Default type. An <see cref="Object"/> instance is possibly had bad initialization.
  15. /// </summary>
  16. Object,
  17. /// <summary>
  18. /// An <see cref="Object"/> instance is derived from <see cref="GridObject"/> class.
  19. /// </summary>
  20. GridObject,
  21. /// <summary>
  22. /// An <see cref="Object"/> instance is derived from <see cref="Unit"/> class (except Slug).
  23. /// </summary>
  24. Unit,
  25. /// <summary>
  26. /// An instance is <see cref="Slug"/> class instance.
  27. /// </summary>
  28. Slug,
  29. };
  30. /// <summary>
  31. /// Defines the determinate state in which an instance of the <see cref="Object"/> class can be.
  32. /// </summary>
  33. public enum ObjectStates
  34. {
  35. /// <summary>
  36. /// Set by default
  37. /// </summary>
  38. Default,
  39. /// <summary>
  40. /// An instance is no longer exist and wating for deletion from <see cref="ObjectContainer"/>.
  41. /// </summary>
  42. Removed,
  43. }
  44. /// <summary>
  45. /// Provides data for the <see cref="Object.PositionChanged"/> and <see cref="Object.LocationChanged"/> events.
  46. /// </summary>
  47. public class PositionEventArgs : EventArgs
  48. {
  49. /// <summary>
  50. /// Gets the previous <see cref="Object"/> position (before changing).
  51. /// </summary>
  52. public GPS PrevPosition { get; private set; }
  53. /// <summary>
  54. /// Gets the new <see cref="Object"/> position (after changing).
  55. /// </summary>
  56. public GPS NewPosition { get; private set; }
  57. /// <summary>
  58. /// Initializes a new instance of the PositionEventArgs class.
  59. /// </summary>
  60. /// <param name="prevPosition">The previous <see cref="Object"/> position.</param>
  61. /// <param name="newPosition">The new <see cref="Object"/> position.</param>
  62. public PositionEventArgs(GPS prevPosition, GPS newPosition)
  63. {
  64. PrevPosition = prevPosition;
  65. NewPosition = newPosition;
  66. }
  67. }
  68. /// <summary>
  69. /// Specifies the base class for every Object that can be placed on Map (i.e. has any <see cref="Object.Position"/> within any <see cref="Cell"/>)
  70. /// </summary>
  71. public abstract class Object
  72. {
  73. /// <summary>
  74. /// Represents an Object size information that is used to prevent collistions and intersections with walls.
  75. /// </summary>
  76. protected struct ModelSize
  77. {
  78. public int Width;
  79. public int Height;
  80. };
  81. /// <summary>
  82. /// Represents the method that will handle the <see cref="Object.PositionChanged"/> or <see cref="Object.LocationChanged"/> or <see cref="Unit.Relocated"/> event of an <see cref="Object"/>.
  83. /// </summary>
  84. /// <param name="sender">The source of the event.</param>
  85. /// <param name="e">A <see cref="PositionEventArgs"/> that contains the event data.</param>
  86. public delegate void PositionHandler(object sender, PositionEventArgs e);
  87. /// <summary>
  88. /// Occurs after object changed its Position.
  89. /// </summary>
  90. public event PositionHandler PositionChanged;
  91. /// <summary>
  92. /// Occurs after object changed its GPS location, i.e moved to other <see cref="Cell"/>
  93. /// </summary>
  94. public event PositionHandler LocationChanged;
  95. protected ObjectTypes pr_objectType;
  96. /// <summary>
  97. /// Gets or sets the object essense (based on derived class).
  98. /// </summary>
  99. public ObjectTypes ObjectType
  100. {
  101. get { return this.pr_objectType; }
  102. protected set { this.pr_objectType = value; }
  103. }
  104. protected ObjectStates pr_objectState;
  105. /// <summary>
  106. /// Get or sets the current state of an object.
  107. /// </summary>
  108. public ObjectStates ObjectState
  109. {
  110. get { return this.pr_objectState; }
  111. set { this.pr_objectState = value; }
  112. }
  113. private GPS pr_position;
  114. /// <summary>
  115. /// Gets or sets Object location on the Map.
  116. /// </summary>
  117. public GPS Position
  118. {
  119. get
  120. {
  121. return pr_position;
  122. }
  123. set
  124. {
  125. if (pr_position.Equals(value))
  126. return;
  127. GPS newPosition = value;
  128. bool locationChanged = false;
  129. // if coordinates are outside the cell
  130. // then change Location
  131. if (newPosition.X < 0)
  132. {
  133. newPosition.Location.X -= 1;
  134. newPosition.X += GlobalConstants.CELL_WIDTH;
  135. }
  136. else if (newPosition.X > GlobalConstants.CELL_WIDTH)
  137. {
  138. newPosition.Location.X += 1;
  139. newPosition.X -= GlobalConstants.CELL_WIDTH;
  140. }
  141. if (newPosition.Y < 0)
  142. {
  143. newPosition.Location.Y -= 1;
  144. newPosition.Y += GlobalConstants.CELL_HEIGHT;
  145. }
  146. else if (newPosition.Y > GlobalConstants.CELL_HEIGHT)
  147. {
  148. newPosition.Location.Y += 1;
  149. newPosition.Y -= GlobalConstants.CELL_HEIGHT;
  150. }
  151. // Object moved to other GPS
  152. if (newPosition.Location != pr_position.Location)
  153. {
  154. // HACK:
  155. // Do not enter the nonexistent block
  156. // Need revert after NormalizePosition rework
  157. Cell newCell = Map.Instance.GetCell(newPosition.Location);
  158. if (newCell.ID != -1)
  159. {
  160. currentCell = newCell;
  161. locationChanged = true;
  162. }
  163. else
  164. newPosition = pr_position;
  165. }
  166. // Fix Position, including object bounds and map border
  167. newPosition = NormalizePosition(newPosition);
  168. // Apply new Position
  169. GPS prevPosition = pr_position;
  170. pr_position = newPosition;
  171. // Call events
  172. if (locationChanged && LocationChanged != null)
  173. LocationChanged(this, new PositionEventArgs(prevPosition, pr_position));
  174. if (PositionChanged != null)
  175. PositionChanged(this, new PositionEventArgs(prevPosition, pr_position));
  176. }
  177. }
  178. /// <summary>
  179. /// Gets or sets an Object GUID value.
  180. /// </summary>
  181. public uint GUID { get; protected set; }
  182. /// <summary>
  183. /// The <see cref="Cell"/> object where this Object is belong (located).
  184. /// </summary>
  185. protected Cell currentCell;
  186. /// <summary>
  187. /// The object size information.
  188. /// </summary>
  189. protected ModelSize objectSize;
  190. /// <summary>
  191. /// Initializes a new instance of the Object class.
  192. /// </summary>
  193. public Object()
  194. {
  195. ObjectType = ObjectTypes.Object;
  196. ObjectState = ObjectStates.Default;
  197. // Initialize Position by default values
  198. // Seems not needed
  199. // All uninitialized values is auto-initialized by 0
  200. currentCell.Initialize();
  201. }
  202. /// <summary>
  203. /// <see cref="Object.Create"/> an object with the specified position.
  204. /// </summary>
  205. /// <param name="position">Object default position</param>
  206. public virtual void Create(GPS position)
  207. {
  208. Position = position;
  209. Create();
  210. }
  211. /// <summary>
  212. /// Initilize this instance with assigning the GUID value and placing into <see cref="ObjectContainer"/>.
  213. /// </summary>
  214. public virtual void Create()
  215. {
  216. // Do not create object twice
  217. if (GUID != 0)
  218. return;
  219. GUID = ObjectContainer.Instance.CreateObject(this);
  220. }
  221. // ObjectSearcher simplified
  222. protected List<Object> GetObjectsWithinRange(int rangeDistance)
  223. {
  224. return ObjectSearcher.GetObjectsWithinRange(this, rangeDistance);
  225. }
  226. protected List<GridObject> GetGridObjectsWithinRange(int rangeDistance)
  227. {
  228. return ObjectSearcher.GetGridObjectsWithinRange(this, rangeDistance);
  229. }
  230. protected List<Unit> GetUnitsWithinRange(int rangeDistance)
  231. {
  232. return ObjectSearcher.GetUnitsWithinRange(this, rangeDistance);
  233. }
  234. protected List<Unit> GetUnitsWithinRange(int rangeDistance, bool isVisibleOnly, bool isAliveOnly)
  235. {
  236. return ObjectSearcher.GetUnitsWithinRange(this, rangeDistance, isVisibleOnly, isAliveOnly);
  237. }
  238. /// <summary>
  239. /// Gets a linear distance to another Object.
  240. /// </summary>
  241. public double GetDistance(Object target)
  242. {
  243. return this.Position.GetDistance(target.Position);
  244. }
  245. /// <summary>
  246. /// Set Position.X and Position.Y considering object model size and current Cell
  247. /// </summary>
  248. protected GPS NormalizePosition(GPS position)
  249. {
  250. Cell cell = Map.Instance.GetCell(position.Location);
  251. int lowerXBound = GlobalConstants.CELL_BORDER_PX + objectSize.Width / 2;
  252. int upperXBound = GlobalConstants.CELL_WIDTH - lowerXBound;
  253. int lowerYBound = GlobalConstants.CELL_BORDER_PX + objectSize.Height / 2;
  254. int upperYBound = GlobalConstants.CELL_HEIGHT - lowerYBound;
  255. if (position.X < lowerXBound)
  256. if (!cell.CanMoveTo(Directions.Left))
  257. position.X = lowerXBound;
  258. if (position.X > upperXBound)
  259. if (!cell.CanMoveTo(Directions.Right))
  260. position.X = upperXBound;
  261. if (position.Y < lowerYBound)
  262. if (!cell.CanMoveTo(Directions.Up))
  263. position.Y = lowerYBound;
  264. if (position.Y > upperYBound)
  265. if (!cell.CanMoveTo(Directions.Down))
  266. position.Y = upperYBound;
  267. return position;
  268. }
  269. /// <summary>
  270. /// Update the object statement due to past time.
  271. /// </summary>
  272. /// <param name="timeP">Elapsed time value (in milliseconds).</param>
  273. public virtual void UpdateState(int timeP) { }
  274. }
  275. }