PageRenderTime 163ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/VisualStudioTemplates/Delta Engine/CreepyTowers/Levels/GameLevelExtensions.cs

#
C# | 308 lines | 282 code | 26 blank | 0 comment | 38 complexity | 43f7a546582779ef676f1cdedf3766ad MD5 | raw file
Possible License(s): Apache-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using CreepyTowers.Content;
  5. using CreepyTowers.Enemy.Creeps;
  6. using CreepyTowers.Stats;
  7. using CreepyTowers.Towers;
  8. using CreepyTowers.Triggers;
  9. using DeltaEngine.Content;
  10. using DeltaEngine.Core;
  11. using DeltaEngine.Datatypes;
  12. using DeltaEngine.Entities;
  13. using DeltaEngine.Extensions;
  14. using DeltaEngine.GameLogic;
  15. using DeltaEngine.Multimedia;
  16. using DeltaEngine.Rendering3D;
  17. namespace $safeprojectname$.Levels
  18. {
  19. public static class GameLevelExtensions
  20. {
  21. public static void ResetPlayerGoldAndLives()
  22. {
  23. var player = Player.Current;
  24. player.Gold = 4000;
  25. player.LivesLeft = 5;
  26. }
  27. public static Vector2D GetGridPosition(Vector2D point)
  28. {
  29. var result = Level.GetIntersectionWithFloor(point);
  30. if (result == null)
  31. throw new IntersectionNotFound(point);
  32. var position = (Vector3D)result;
  33. return Level.Current.GetMapCoordinates(position.GetVector2D());
  34. }
  35. private class IntersectionNotFound : Exception
  36. {
  37. public IntersectionNotFound(Vector2D position)
  38. : base(position.ToString()) {}
  39. }
  40. public static void AddCreepWaveToWaveGenerator(this GameLevel gameLevel, CreepWave wave)
  41. {
  42. gameLevel.WaveGenerator.waveList.Add(wave);
  43. gameLevel.WaveGenerator.UpdateTotalCreepCountForLevel();
  44. gameLevel.UpdateWave();
  45. }
  46. public static void SpawnCreepInGame(this GameLevel gameLevel, CreepType type)
  47. {
  48. var path = gameLevel.GetPathForCreep().ToList();
  49. var creep = gameLevel.CreateAndShowCreep(type, path[0], path[path.Count - 1]);
  50. foreach (var position in path)
  51. creep.Path.Add(new Vector2D(position.X, position.Y));
  52. }
  53. private static IEnumerable<Vector2D> GetPathForCreep(this GameLevel gameLevel)
  54. {
  55. var storedPaths = gameLevel.GetStoredPaths();
  56. if (storedPaths.Count == 1)
  57. return storedPaths[0].GetListOfCoordinates();
  58. int max = 0;
  59. int min = 0;
  60. for (int i = 1; i < storedPaths.Count; i++)
  61. if (storedPaths[i].FinalCost < storedPaths[min].FinalCost)
  62. min = i;
  63. else if (storedPaths[i].FinalCost > storedPaths[max].FinalCost)
  64. max = i;
  65. var valueMin = storedPaths[min].FinalCost / storedPaths[min].GetListOfCoordinates().Count;
  66. var valueMax = storedPaths[max].FinalCost / storedPaths[max].GetListOfCoordinates().Count;
  67. return Math.Abs(valueMax - valueMin) <= 50
  68. ? storedPaths[Randomizer.Current.Get(0, storedPaths.Count)].GetListOfCoordinates()
  69. : storedPaths[min].GetListOfCoordinates();
  70. }
  71. private static Creep CreateAndShowCreep(this GameLevel gameLevel, CreepType type,
  72. Vector2D spawnPoint, Vector2D finalTarget)
  73. {
  74. var creep = new Creep(type, spawnPoint) { FinalTarget = finalTarget };
  75. creep.RenderModel();
  76. creep.IsDead += () =>
  77. {
  78. gameLevel.EarnGold((int)creep.GetStatValue("Gold"));
  79. gameLevel.DeadCreepCount++;
  80. gameLevel.CheckChapterCompletion();
  81. };
  82. creep.ReachedExit += gameLevel.ReduceOneLife;
  83. return creep;
  84. }
  85. private static void CheckChapterCompletion(this GameLevel gameLevel)
  86. {
  87. if (!HasPlayerFailed())
  88. CheckForPlayerSuccess(gameLevel);
  89. }
  90. private static bool HasPlayerFailed()
  91. {
  92. if (Player.Current.LivesLeft > 0)
  93. return false;
  94. ChapterOver.ChaptedFailed();
  95. return true;
  96. }
  97. private static void CheckForPlayerSuccess(this GameLevel gameLevel)
  98. {
  99. if (gameLevel.DeadCreepCount + gameLevel.ExitReachedCreepCount <
  100. gameLevel.WaveGenerator.TotalCreepsInLevel)
  101. return;
  102. gameLevel.FinishChapter();
  103. }
  104. private static void ReduceOneLife(this GameLevel gameLevel)
  105. {
  106. Player.Current.LivesLeft--;
  107. gameLevel.ExitReachedCreepCount++;
  108. if (IsPlayerLifeLessThan20Percent())
  109. PlaySound(GameSounds.LowHealth);
  110. gameLevel.UpdateLife();
  111. gameLevel.CheckChapterCompletion();
  112. }
  113. private static bool IsPlayerLifeLessThan20Percent()
  114. {
  115. return Player.Current.LivesLeft <= 0.2 * Player.Current.MaxLives;
  116. }
  117. private static void PlaySound(GameSounds soundName)
  118. {
  119. var sound = ContentLoader.Load<Sound>(soundName.ToString());
  120. if (sound != null)
  121. sound.Play();
  122. }
  123. public static void SpawnTowerInGame(this GameLevel level, TowerType type,
  124. Vector2D gridPosition, float rotation = 0.0f)
  125. {
  126. var properties = ContentLoader.Load<TowerPropertiesXml>(Xml.TowerProperties.ToString());
  127. if (IsCreepInTile(gridPosition) || Player.Current.Gold < properties.Get(type).Cost)
  128. return;
  129. var index = level.GetIndexForMapData(gridPosition);
  130. if (level.MapData[index] != LevelTileType.Placeable)
  131. return;
  132. level.SetUnreacheableTile(gridPosition, type);
  133. if (!level.IsPossibleAddTower(gridPosition))
  134. return;
  135. var towerPosInWorldSpace = level.GetWorldCoordinates(gridPosition);
  136. var tower = new Tower(type, towerPosInWorldSpace, rotation);
  137. tower.RenderModel();
  138. level.EarnGold(-properties.Get(type).Cost);
  139. }
  140. private static bool IsCreepInTile(Vector2D position)
  141. {
  142. foreach (var creep in EntitiesRunner.Current.GetEntitiesOfType<Creep>())
  143. {
  144. var creepTile = creep.Position - Vector2D.Half;
  145. if ((creepTile.X - position.X).Abs() <= 1.0f && (creepTile.Y - position.Y).Abs() <= 1.0f &&
  146. creep.Path.Contains(position + Vector2D.Half))
  147. return true;
  148. }
  149. return false;
  150. }
  151. private static void SetUnreacheableTile(this GameLevel level, Vector2D position,
  152. TowerType type)
  153. {
  154. var pathfinding = level.GetPathFinding();
  155. var index = (int)(position.X + position.Y * level.Size.Width);
  156. level.MapData[index] = LevelTileType.Blocked;
  157. pathfinding.SetUnreachableAndUpdate(index);
  158. var towerProperties = ContentLoader.Load<TowerPropertiesXml>(Xml.TowerProperties.ToString());
  159. var buff = new BuffEffect(Player.Current.Avatar.GetType().Name + "RangeMultiplier");
  160. var range = towerProperties.Get(type).Range;
  161. range *= buff.Multiplier > 0.0f ? buff.Multiplier : 1.0f;
  162. pathfinding.UpdateWeightInAdjacentNodes(position, (int)range, 100);
  163. }
  164. private static bool IsPossibleAddTower(this GameLevel level, Vector2D gridPosition)
  165. {
  166. var index = level.GetIndexForMapData(gridPosition);
  167. if (level.UpdateExistingCreeps(gridPosition + Vector2D.Half) &&
  168. level.UpdatePathsIfPossible())
  169. return true;
  170. level.MapData[index] = LevelTileType.Placeable;
  171. level.GetPathFinding().SetReachableAndUpdate(index);
  172. return false;
  173. }
  174. private static bool UpdateExistingCreeps(this GameLevel gameLevel, Vector2D position)
  175. {
  176. foreach (var creep in EntitiesRunner.Current.GetEntitiesOfType<Creep>())
  177. {
  178. if (creep.Path.Count == 0 || !creep.Path.Contains(position))
  179. continue;
  180. if (!IsTherePossibleExitPath(gameLevel, creep))
  181. return false;
  182. }
  183. return true;
  184. }
  185. private static bool IsTherePossibleExitPath(this GameLevel gameLevel, Creep creep)
  186. {
  187. var isThereWay = false;
  188. for (int i = 0; i < gameLevel.GoalPoints.Count; i++)
  189. {
  190. var list =
  191. gameLevel.GetPath(creep.Position.GetVector2D(), gameLevel.GoalPoints[i]).
  192. GetListOfCoordinates();
  193. if (list.Count == 0)
  194. continue;
  195. creep.Path = list.Select(element => element + Vector2D.Half).ToList();
  196. creep.FinalTarget = creep.Path[creep.Path.Count - 1];
  197. isThereWay = true;
  198. break;
  199. }
  200. return isThereWay;
  201. }
  202. public static bool UpdatePathsIfPossible(this GameLevel gameLevel)
  203. {
  204. for (int i = 0; i < gameLevel.SpawnPoints.Count; i++)
  205. for (int j = 0; j < gameLevel.GoalPoints.Count; j++)
  206. {
  207. var list = gameLevel.GetPath(gameLevel.SpawnPoints[i], gameLevel.GoalPoints[j]);
  208. if (list.GetListOfCoordinates().Count == 0)
  209. return false;
  210. var storedPaths = gameLevel.GetStoredPaths();
  211. storedPaths[i * gameLevel.SpawnPoints.Count + j] = list;
  212. }
  213. gameLevel.UpdateTracers();
  214. return true;
  215. }
  216. public static void CleanLevel(this GameLevel level)
  217. {
  218. if (level == null)
  219. return;
  220. level.RemoveTowers();
  221. level.RemoveCreeps();
  222. level.GetStoredPaths().Clear();
  223. level.RemoveCurrentTracers();
  224. ResetPlayerGoldAndLives();
  225. level.DeadCreepCount = 0;
  226. level.ExitReachedCreepCount = 0;
  227. level.WaveGenerator.Dispose();
  228. level.IsCompleted = false;
  229. }
  230. public static void RemoveTowers(this GameLevel level)
  231. {
  232. foreach (var tower in EntitiesRunner.Current.GetEntitiesOfType<Tower>())
  233. {
  234. var towerMapPos = level.GetMapCoordinates(tower.Position.GetVector2D());
  235. var index = level.GetIndexForMapData(towerMapPos);
  236. if(index >= level.MapData.Length)
  237. return;
  238. level.MapData[index] = LevelTileType.Placeable;
  239. level.GetPathFinding().SetReachableAndUpdate(index);
  240. tower.Dispose();
  241. }
  242. }
  243. public static void RemoveCreeps(this GameLevel level)
  244. {
  245. var allCreeps = EntitiesRunner.Current.GetEntitiesOfType<Creep>();
  246. foreach (Creep creep in allCreeps)
  247. creep.Dispose();
  248. }
  249. public static void RemoveModel(this GameLevel level)
  250. {
  251. var models = EntitiesRunner.Current.GetEntitiesOfType<Model>();
  252. foreach (Model model in models)
  253. model.Dispose();
  254. }
  255. public static void SellTower(this GameLevel level, Vector2D position)
  256. {
  257. var list = EntitiesRunner.Current.GetEntitiesOfType<Tower>();
  258. foreach (var tower in list)
  259. {
  260. var towerTile = tower.Position - Vector2D.Half;
  261. if (towerTile != position)
  262. continue;
  263. PlaySound(GameSounds.TowerSell);
  264. level.EarnGold((int)(tower.GetStatValue("Cost") / 2));
  265. level.GetPathFinding().UpdateWeightInAdjacentNodes(position,
  266. (int)(tower.GetStatValue("Range")), -100);
  267. tower.Dispose();
  268. level.UpdateGridAndExistingCreeps(position);
  269. return;
  270. }
  271. }
  272. private static void UpdateGridAndExistingCreeps(this GameLevel level, Vector2D gridPosition)
  273. {
  274. var index = level.GetIndexForMapData(gridPosition);
  275. level.MapData[index] = LevelTileType.Placeable;
  276. level.GetPathFinding().SetReachableAndUpdate(index);
  277. foreach (var creep in EntitiesRunner.Current.GetEntitiesOfType<Creep>())
  278. level.IsTherePossibleExitPath(creep);
  279. level.UpdatePathsIfPossible();
  280. }
  281. }
  282. }