PageRenderTime 1071ms CodeModel.GetById 38ms RepoModel.GetById 0ms app.codeStats 0ms

/Assets/Scripts/Map.cs

https://gitlab.com/ErikZappy/Fallen
C# | 554 lines | 422 code | 55 blank | 77 comment | 108 complexity | 96098b8bc2553bebedae99d48a998206 MD5 | raw file
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. public class Map : MonoBehaviour {
  5. // Dictionary<string, Land> map = new Dictionary<string, Land>();
  6. Dict<Land> map = new Dict<Land>();
  7. List<Land> landList = new List<Land>();
  8. List<int> intList = new List<int>();
  9. Dictionary<Land, int> f_Scores = new Dictionary<Land, int>();
  10. Dictionary<Land, int> g_Scores = new Dictionary<Land, int>();
  11. Dictionary<Land, Land> cameFrom = new Dictionary<Land, Land>();
  12. // Use this for initialization
  13. void Start () {
  14. setUpMap();
  15. // printContents();
  16. }
  17. // Update is called once per frame
  18. void Update (){
  19. }
  20. public void check(){
  21. Debug.Log("There is an instance of this thing on another thing");
  22. }
  23. // getters and seters
  24. // i set these 2 getters to void and returned nothing but i do not know
  25. // why. so i guess this is why commenting is incredibly important
  26. // these will not work since the key is an object where the values
  27. // are technically not the same
  28. public Land getLandAt(Vector2 iarry){
  29. return map.get((int)iarry.x, (int)iarry.y);
  30. }
  31. public Land getLandAt(int x, int y){
  32. // Vector2 arry = new Vector2();
  33. // arry.x = x;
  34. // arry.y = y;
  35. string arry = x + "," + y;
  36. return map.get(arry);
  37. }
  38. public Land getLandAt(string pos){
  39. return map.get(pos);
  40. }
  41. // helper methods
  42. public void printContents(){
  43. string mapString = map.ToString();
  44. Debug.Log(mapString);
  45. }
  46. private void setUpMap(){
  47. foreach(Transform ch in transform){
  48. Land land = ch.gameObject.GetComponent<Land>();
  49. if(land != null){
  50. string pos = land.x + "," + land.y;
  51. map.Add(pos, land);
  52. }
  53. else
  54. Debug.Log(ch.position);
  55. }
  56. }
  57. public Land[] getNeighborsOfLand(Land current){
  58. Land[] lArray = new Land[4];
  59. lArray[0] = map.get(current.x-1, current.y);
  60. lArray[1] = map.get(current.x+1, current.y);
  61. lArray[2] = map.get(current.x, current.y+1);
  62. lArray[3] = map.get (current.x, current.y-1);
  63. return lArray;
  64. }
  65. // this recursive will hightlight all possible areas that a unit can go to
  66. // well here it goes
  67. // i think this is the A* algorithm
  68. // i might put this in a different script or class
  69. // most likely in a unit class since i can just make each unit have
  70. // a link to the map class
  71. public void findMovableLands(List<Land> arlLand, Land land, int m){
  72. arlLand.Add(land);
  73. recGetUnitMovableV(arlLand, land, m);
  74. }
  75. public void findMovableLands(Unit u, Land l, int m){
  76. u.getMoveableList().Add(l);
  77. recGetUnitLandList(u, l, m, -1);
  78. }
  79. // for attacking
  80. public void recGetUnitMovableV(List<Land> arlLand, Land land, int m){
  81. if(land == null)
  82. return;
  83. int x = land.x;
  84. int y = land.y;
  85. if(!arlLand.Contains(land))
  86. arlLand.Add(land);
  87. if(m > 0){
  88. m--;
  89. // check left
  90. recGetUnitMovableV(arlLand, map.get(x-1, y), m);
  91. // check right
  92. recGetUnitMovableV(arlLand, map.get(x+1, y), m);
  93. // check up
  94. recGetUnitMovableV(arlLand, map.get(x, y+1), m);
  95. // check down
  96. recGetUnitMovableV(arlLand, map.get(x, y-1), m);
  97. }
  98. }
  99. // for moving
  100. public void recGetUnitLandList(Unit u, Land l,int m, int indexPrior){
  101. if(l == null)
  102. return;
  103. m = m+l.terrain;
  104. int x = l.x;
  105. int y = l.y;
  106. bool walk = true;
  107. if(null != l.getUnit()){
  108. Unit other = l.getUnit();
  109. walk = other.getTeam() == u.getTeam();
  110. }
  111. else
  112. walk = l.getWalkable();
  113. if(m>=0 && (walk || u.getMoveableList().Contains(l))){
  114. if(!u.getMoveableList().Contains(l))
  115. u.getMoveableList().Add(l);
  116. if(indexPrior < u.getMoveableList().IndexOf(l)){
  117. m--;
  118. // check left
  119. recGetUnitLandList(u, map.get(x-1, y), m, u.getMoveableList().IndexOf(l));
  120. // check right
  121. recGetUnitLandList(u, map.get(x+1, y), m, u.getMoveableList().IndexOf(l));
  122. // check up
  123. recGetUnitLandList(u, map.get(x, y+1), m, u.getMoveableList().IndexOf(l));
  124. // check down
  125. recGetUnitLandList(u, map.get(x, y-1), m, u.getMoveableList().IndexOf(l));
  126. }
  127. }
  128. }
  129. // always clear the int list before hand
  130. public void recGetUnitLandList(Unit u, int m){
  131. List<Land> newList = new List<Land>();
  132. List<int> newIntList = new List<int>();
  133. bool areAllZero = true;
  134. foreach(Land current in landList){
  135. int thing = landList.IndexOf(current);
  136. int move = intList[thing];
  137. if(move > 0){
  138. areAllZero = false;
  139. Land[] lArray = new Land[4];
  140. lArray[0] = map.get(current.x-1, current.y);
  141. lArray[1] = map.get(current.x+1, current.y);
  142. lArray[2] = map.get(current.x, current.y+1);
  143. lArray[3] = map.get (current.x, current.y-1);
  144. for(int i =0; i<lArray.Length; i++){
  145. Land l = lArray[i];
  146. Debug.Log(l);
  147. if(l==null){
  148. Debug.Log(current);
  149. }
  150. else if(!u.getMoveableList().Contains(l) && !newList.Contains(l) && move-1+l.terrain >= 0 && l.walkable){
  151. u.getMoveableList().Add(l);
  152. newList.Add(l);
  153. newIntList.Add(move-1+l.terrain);
  154. }
  155. }
  156. }
  157. }
  158. // if all the outside ints are zero end the recursion
  159. if(areAllZero){
  160. return;
  161. }
  162. landList = newList;
  163. intList = newIntList;
  164. recGetUnitLandList(u, m);
  165. }
  166. // assume first l has been added already to the int list and landlist
  167. // best one
  168. public void getMoveRange(Unit u, Land current, int move){
  169. Land[] lArray = new Land[4];
  170. try{
  171. lArray[0] = map.get(current.x-1, current.y);
  172. lArray[1] = map.get(current.x+1, current.y);
  173. lArray[2] = map.get(current.x, current.y+1);
  174. lArray[3] = map.get (current.x, current.y-1);
  175. }
  176. catch{
  177. return;
  178. }
  179. for(int i =0; i<lArray.Length; i++){
  180. Land l = lArray[i];
  181. int newMove = 0;
  182. Unit uOnLand = null;
  183. bool goNext = true;
  184. if(l!=null){
  185. newMove = move-l.terrain-1;
  186. if(l.occupiedEh){
  187. uOnLand = l.getUnit();
  188. if(uOnLand.team != u.getTeam()){
  189. goNext = false;
  190. }
  191. }
  192. }
  193. if(l==null){
  194. }
  195. //ADD
  196. else if(!u.getMoveableList().Contains(l) && newMove >= 0 && (l.walkable||goNext)){
  197. u.getMoveableList().Add(l);
  198. intList.Add(move-1-l.terrain);
  199. getMoveRange(u, l, newMove);
  200. }
  201. //CHECK
  202. else if(u.getMoveableList().Contains(l) && (l.walkable||goNext)){
  203. int index = u.getMoveableList().IndexOf(l);
  204. int oldMove = intList[index];
  205. if(newMove > oldMove){
  206. intList[index] = newMove;
  207. getMoveRange(u, l, newMove);
  208. }
  209. }
  210. }
  211. }
  212. private void getFullAttackRange(Unit u, Land current, int move, List<Land> thing, List<Land> closeOccupiedLands){
  213. Land[] lArray = new Land[4];
  214. lArray[0] = map.get(current.x-1, current.y);
  215. lArray[1] = map.get(current.x+1, current.y);
  216. lArray[2] = map.get(current.x, current.y+1);
  217. lArray[3] = map.get (current.x, current.y-1);
  218. for(int i =0; i<lArray.Length; i++){
  219. Land l = lArray[i];
  220. int newMove = 0;
  221. if(l!=null)
  222. newMove = move-l.terrain-1;
  223. if(l==null){
  224. }
  225. //ADD
  226. else if(!thing.Contains(l) && newMove >= 0 && (l.walkable || (!l.walkable && l.occupiedEh))){
  227. thing.Add(l);
  228. intList.Add(move-1-l.terrain);
  229. if(l.occupiedEh){
  230. if(l.getUnit().team != u.team){
  231. closeOccupiedLands.Add(l);
  232. }
  233. else
  234. getFullAttackRange(u, l, newMove, thing, closeOccupiedLands);
  235. }
  236. else
  237. getFullAttackRange(u, l, newMove, thing, closeOccupiedLands);
  238. }
  239. //CHECK
  240. else if(thing.Contains(l) && (l.walkable || (!l.walkable && l.occupiedEh))){
  241. int index = thing.IndexOf(l);
  242. int oldMove = intList[index];
  243. if(newMove > oldMove){
  244. intList[index] = newMove;
  245. getFullAttackRange(u, l, newMove, thing, closeOccupiedLands);
  246. }
  247. }
  248. }
  249. }
  250. public Unit getUnitInRange(Unit u){
  251. List<Land> listTracker = new List<Land>();
  252. List<Land> actualList = new List<Land>();
  253. listTracker.Add(u.getLandInhabiting());
  254. landList.Clear();
  255. intList.Clear();
  256. landList.Add(u.getLandInhabiting());
  257. intList.Add(u.move);
  258. getFullAttackRange(u, u.getLandInhabiting(), u.move, listTracker, actualList);
  259. Unit target = null;
  260. int mdist = 100;
  261. foreach(Land l in actualList){
  262. int newDist = mDist(u.getLandInhabiting(), l);
  263. if(newDist < mdist){
  264. if(l.getUnit().getTeam() != u.getTeam()){
  265. target = l.getUnit();
  266. }
  267. }
  268. }
  269. return target;
  270. }
  271. public void getMoveList(Unit unit){
  272. int move = unit.getMove();
  273. unit.getMoveableList().Add(unit.getLandInhabiting());
  274. landList.Clear();
  275. intList.Clear();
  276. landList.Add(unit.getLandInhabiting());
  277. intList.Add(unit.move);
  278. getMoveRange(unit, unit.getLandInhabiting(), unit.move);
  279. }
  280. public Land landClostestToTarget(Unit u, Unit target, Land current, int m, List<Land> newLand){
  281. Land landTarget = target.getLandInhabiting();
  282. if(m<=0){
  283. newLand.Add(current);
  284. return current;
  285. }
  286. Land[] landArray = new Land[4];
  287. landArray[0] = map.get(current.x-1, current.y);
  288. landArray[1] = map.get(current.x+1, current.y);
  289. landArray[2] = map.get(current.x, current.y+1);
  290. landArray[3] = map.get (current.x, current.y-1);
  291. for(int i=0; i<landArray.Length; i++){
  292. Land l = landArray[i];
  293. int newM = m-1+l.terrain;
  294. float dist = distance(l, landTarget);
  295. float curr = distance(current, landTarget);
  296. if(!l.walkable && l.occupiedEh){
  297. Unit unitOnLand = l.getUnit();
  298. if(unitOnLand == target){
  299. newLand.Add(l);
  300. return current;
  301. }
  302. }
  303. else if(l.terrain < 0 && dist < curr){
  304. newLand.Add(l);
  305. }
  306. if(!(newM <= -1) && l.walkable && dist < curr){
  307. newLand.Add(l);
  308. return landClostestToTarget(u, target, l, newM, newLand);
  309. }
  310. }
  311. return null;
  312. }
  313. // public Land landClostestToTarget(Unit u, Unit target, Land current, int m){
  314. // Land landTarget = target.getLandInhabiting();
  315. // bool done = false;
  316. // Land nextLand = current;
  317. // // done is m == 0 or if distance is == 1
  318. // do{
  319. // float currDist = distance(current, landTarget);
  320. // Land[] landArray = new Land[4];
  321. // landArray[0] = map.get(nextLand.x-1, nextLand.y);
  322. // landArray[1] = map.get(nextLand.x+1, nextLand.y);
  323. // landArray[2] = map.get(nextLand.x, nextLand.y+1);
  324. // landArray[3] = map.get (nextLand.x, nextLand.y-1);
  325. //
  326. // for(int i = 0; i<landArray.Length; i++){
  327. // Land l = landArray[i];
  328. // if(Mathf.Approximately(distance(l, landTarget), 0)){
  329. // done = true;
  330. // }
  331. // else if(distance(l, landTarget) < currDist
  332. // && l.walkable){
  333. // nextLand = l;
  334. // }
  335. // }
  336. // if(!done)
  337. // m = m-1+nextLand.terrain;
  338. // if(m == 0)
  339. // done = true;
  340. //
  341. // }while(!done);
  342. // return nextLand;
  343. // }
  344. private float distance(Land l1, Land l2){
  345. return distance2D(l1.transform.position, l2.transform.position);
  346. }
  347. private float distance2D(Vector3 vec1, Vector3 vec2){
  348. float x1 = vec1.x;
  349. float z1 = vec1.z;
  350. float x2 = vec2.x;
  351. float z2 = vec2.z;
  352. float deltaX = x1 - x2;
  353. float deltaZ = z1 - z2;
  354. float beforeSquare = deltaX * deltaX + deltaZ * deltaZ;
  355. float dist = Mathf.Sqrt(beforeSquare);
  356. return dist;
  357. }
  358. public List<Land> getNextMove(Unit u, Land target){
  359. Land first = u.getLandInhabiting();
  360. return aStarPathFinder(first, target, u);
  361. }
  362. private List<Land> aStarPathFinder(Land start, Land end, Unit u){
  363. f_Scores.Clear();
  364. g_Scores.Clear();
  365. cameFrom.Clear();
  366. List<Land> openList = new List<Land>();
  367. List<Land> closeList = new List<Land>();
  368. openList.Add(start);
  369. Land current = start;
  370. g_Scores.Add(start, 0);
  371. while(openList.Count > 0){
  372. // removing lowest rank
  373. current = getLowestFScore(end, openList);
  374. // checking if the g score is equal to the units move
  375. // or if current is the goal
  376. if(g_Scores[current] >= u.getMove() || current == end){
  377. if(current.occupiedEh){
  378. if(current.getUnit() != u){
  379. openList.Remove(current);
  380. closeList.Add(current);
  381. current = cameFrom[current];
  382. }
  383. else{
  384. end = current;
  385. break;
  386. }
  387. }
  388. else{
  389. if(g_Scores[current] == u.getMove())
  390. end = current;
  391. else if(g_Scores[current] > u.getMove()){
  392. end = cameFrom[current];
  393. }
  394. else
  395. end = current;
  396. break;
  397. }
  398. }
  399. else if(g_Scores[current] < u.getMove() && mDist(end, current) == 1 && end.occupiedEh){
  400. end = current;
  401. break;
  402. }
  403. // removing current from open
  404. openList.Remove(current);
  405. // add ing it to close
  406. closeList.Add(current);
  407. // for neighbors of current
  408. Land[] landArray = new Land[4];
  409. landArray[0] = map.get(current.x-1, current.y);
  410. landArray[1] = map.get(current.x+1, current.y);
  411. landArray[2] = map.get(current.x, current.y+1);
  412. landArray[3] = map.get (current.x, current.y-1);
  413. for(int i=0; i<landArray.Length; i++){
  414. Land l = landArray[i];
  415. bool goForward = true;
  416. if(l == null){
  417. goForward = false;
  418. }
  419. else if(l.occupiedEh){
  420. Unit unit = l.getUnit();
  421. if(unit.team != u.team)
  422. goForward = false;
  423. // if(!l.walkable){
  424. // goForward = false;
  425. // }
  426. }
  427. if(goForward){
  428. int cost = g_Scores[current] + l.terrain + 1;
  429. if(openList.Contains(l)){
  430. if(cost < g_Scores[l]){
  431. g_Scores[l] = cost;
  432. }
  433. }
  434. else if(closeList.Contains(l)){
  435. if(cost < g_Scores[l] + l.terrain+1){
  436. closeList.Remove(l);
  437. openList.Add(l);
  438. g_Scores[l] = cost;
  439. cameFrom[l] = current;
  440. }
  441. }
  442. else if(!openList.Contains(l)){
  443. openList.Add(l);
  444. g_Scores.Add(l, cost);
  445. cameFrom.Add(l, current);
  446. }
  447. }
  448. }
  449. }
  450. List<Land> thing = new List<Land>();
  451. try{
  452. thing = getPath(start, end);
  453. }
  454. catch{
  455. Debug.Log("something went wrong in getPath()");
  456. }
  457. return thing;
  458. }
  459. private List<Land> getPath(Land start, Land end){
  460. List<Land> newList = new List<Land>();
  461. Land l = end;
  462. if(start == end){
  463. newList.Add(end);
  464. return newList;
  465. }
  466. while(l != start){
  467. newList.Add(l);
  468. l = cameFrom[l];
  469. }
  470. newList.Reverse();
  471. return newList;
  472. }
  473. private int mDist(Land start, Land end){
  474. int sX = start.x;
  475. int sY = start.y;
  476. int eX = end.x;
  477. int eY = end.y;
  478. int deltaX = Mathf.Abs(sX - eX);
  479. int deltaY = Mathf.Abs(sY - eY);
  480. return deltaX + deltaY;
  481. }
  482. private Land getLowestFScore(Land end, List<Land> list){
  483. List<Land> lowest = new List<Land>();
  484. int numLow = 100;
  485. foreach(Land l in list){
  486. int fScore = mDist(l, end) + g_Scores[l];
  487. if(fScore < numLow){
  488. lowest.Add(l);
  489. numLow = fScore;
  490. }
  491. }
  492. if(lowest.Count == 1){
  493. return lowest[0];
  494. }
  495. else{
  496. return lowest[lowest.Count-1];
  497. }
  498. }
  499. }