You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
6.8 KiB

  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using UnityEngine;
  4. using Networking.Server;
  5. public class blockSpawn : MonoBehaviour
  6. {
  7. [SerializeField]
  8. public Inventory.Data[] spawnLogicList;
  9. public List<ClientData> ConnectedClients;
  10. public ClientList clientDataList;
  11. public Block[] SpawnBlocks;
  12. public List<Vector3> spawnedLocations;
  13. int scoreDifference = 0;
  14. float average = 0;
  15. void Awake()
  16. {
  17. ConnectedClients = clientDataList.ConnectedClients;
  18. SpawnBlocks = FindObjectsOfType<Block>().Where(p => p.is_Walkable).ToArray();
  19. spawnedLocations = new List<Vector3>();
  20. }
  21. public void Spawn()
  22. {
  23. getPlayerScores();
  24. getPlayerLocations(ConnectedClients.ToArray(), 0.75f);
  25. //second spawning block only if needed
  26. /* if (scoreDifference > average)
  27. {
  28. List<ClientData> lessClients = new List<ClientData>(ConnectedClients);
  29. lessClients.RemoveAt(lessClients.Count - 1);
  30. getPlayerLocations(lessClients.ToArray(), 0.6f);
  31. }*/
  32. }
  33. private void getPlayerScores()
  34. {
  35. ConnectedClients.Sort((b, a) => a.SceneScore.CompareTo(b.SceneScore));
  36. int totalScores = 0;
  37. scoreDifference = ConnectedClients[0].SceneScore + ConnectedClients[ConnectedClients.Count-1].SceneScore;
  38. //Debug.Log("score difference " + scoreDifference);
  39. for(int i = 0; i < ConnectedClients.Count; i++)
  40. {
  41. totalScores += ConnectedClients[i].SceneScore;
  42. }
  43. average = totalScores / ConnectedClients.Count;
  44. //Debug.Log("score average " + average);
  45. }
  46. private bool checkDuplicatePosition(Vector3 spawnposition)
  47. {
  48. if (spawnedLocations.Count > 0)
  49. {
  50. for (int k = 0; k < spawnedLocations.Count; k++)
  51. {
  52. if (spawnedLocations[k].x == spawnposition.x && spawnedLocations[k].z == spawnposition.z)
  53. {
  54. return true;
  55. }
  56. }
  57. }
  58. return false;
  59. }
  60. private bool checkValid(Vector3 spawnposition)
  61. {
  62. for (int i = 0; i < SpawnBlocks.Length; i++)
  63. {
  64. if (SpawnBlocks[i].position.x == spawnposition.x && SpawnBlocks[i].position.z == spawnposition.z)
  65. {
  66. return true;
  67. }
  68. }
  69. return false;
  70. }
  71. private void spawnBlock(Vector3 spawnposition)
  72. {
  73. GameObject prefab = Resources.Load("Logic Block") as GameObject;
  74. GameObject block = Instantiate(prefab);
  75. int number = (int)Random.Range(1.0f, spawnLogicList.Length);
  76. block.GetComponent<LogicCollectable_Multiplayer>().Collectable.element = spawnLogicList[number].element;
  77. block.GetComponent<LogicCollectable_Multiplayer>().Collectable.Count = spawnLogicList[number].Count;
  78. block.transform.position = spawnposition;
  79. Debug.Log("Instantiated new logic block: " + spawnLogicList[number].element + " at position: " + block.transform.position);
  80. spawnedLocations.Add(spawnposition);
  81. }
  82. private void checkLocation(Vector3 spawnposition)
  83. {
  84. bool duplicate = false;
  85. if (duplicate == false)
  86. {
  87. bool valid = checkValid(spawnposition);
  88. if (valid == true)
  89. {
  90. spawnBlock(spawnposition);
  91. }
  92. else
  93. {
  94. Block clostest = Utility.minBy(SpawnBlocks, p => Vector3.Distance(p.transform.position, spawnposition));
  95. checkLocation(new Vector3(clostest.position.x, clostest.position.y + 1.5f, clostest.position.z));
  96. }
  97. }
  98. else
  99. {
  100. //this needs to be changed
  101. Block clostest = Utility.minBy(SpawnBlocks, p => Vector3.Distance(p.transform.position, spawnposition));
  102. checkLocation(new Vector3(clostest.position.x, clostest.position.y + 1.5f, clostest.position.z));
  103. }
  104. }
  105. private void getPlayerLocations(ClientData[] clients, float weightMultiplier)
  106. {
  107. float[] weightings = new float[clients.Length];
  108. if(clients.Length > 1)
  109. {
  110. Vector3 spawnposition = new Vector3(0, 0, 0);
  111. for (int i = 0; i < clients.Length; i++)
  112. {
  113. spawnposition += clients[i].playerCharacter.CurrentBlock.VisualPosition;
  114. //Debug.Log("currentBlock.VisualPosition " + clients[i].playerCharacter.CurrentBlock.VisualPosition);
  115. }
  116. spawnposition *= (1.0f / clients.Length);
  117. //Debug.Log("spawnposition " + spawnposition);
  118. Vector3[] direction = new Vector3[clients.Length];
  119. for (int i = 0; i < clients.Length; i++)
  120. {
  121. direction[i] = (spawnposition - clients[i].playerCharacter.CurrentBlock.VisualPosition);
  122. //Debug.Log("direction " + i + " " + direction[i]);
  123. }
  124. //weighting calculations
  125. float[] difAvg = new float[clients.Length];
  126. for (int i = 0; i < clients.Length; i++)
  127. {
  128. difAvg[i] = clients[i].SceneScore - average;
  129. }
  130. float[] ratio = new float[clients.Length];
  131. //Debug.Log("difAvg[0] " + difAvg[0]);
  132. if (difAvg[0] == 0)
  133. {
  134. for (int i = 0; i < clients.Length; i++)
  135. {
  136. weightings[i] = 0.5f * weightMultiplier;
  137. //Debug.Log("weightings " + i + " " + weightings[i]);
  138. }
  139. }
  140. else
  141. {
  142. for (int i = 0; i < clients.Length; i++)
  143. {
  144. ratio[i] = difAvg[i] / difAvg[0];
  145. ratio[i] /= 2.0f;
  146. ratio[i] += 0.5f;
  147. weightings[i] = ratio[i] * weightMultiplier;
  148. weightings[i] = Mathf.Clamp(weightings[i], 0, 1);
  149. //Debug.Log("weightings " + i + " " + weightings[i]);
  150. }
  151. }
  152. //multiply weightings by the direction
  153. //take average point and add directions
  154. for (int i = 0; i < clients.Length; i++)
  155. {
  156. spawnposition += (weightings[i] * direction[i]);
  157. //Debug.Log("(weightings[i] * direction[i] " + (weightings[i] * direction[i]));
  158. }
  159. spawnposition += Vector3.one * 0.5f;
  160. //Debug.Log("spawnposition " + spawnposition);
  161. //spawn first block
  162. checkLocation(spawnposition);
  163. }
  164. else
  165. {
  166. Vector2 playerOne = new Vector2(clients[0].playerCharacter.CurrentBlock.VisualPosition.x, clients[0].playerCharacter.CurrentBlock.VisualPosition.z);
  167. int xVal = (int)Random.Range(-3.0f, 3.0f) + (int)playerOne.x;
  168. int zVal = (int)Random.Range(-3.0f, 3.0f) + (int)playerOne.y;
  169. checkLocation(new Vector3(xVal, 1.0f, zVal));
  170. }
  171. }
  172. }