main.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. let params = new URLSearchParams(window.location.search);
  2. if (params.get("delete")) {
  3. if (confirm("Are you sure you want to clear all game data?")) {
  4. localStorage.clear();
  5. window.location = "./";
  6. }
  7. }
  8. var timeoutId;
  9. var previousState;
  10. var errorMessage;
  11. var states = [];
  12. var rooms = [];
  13. var selectedItems = [];
  14. var userData = {
  15. version: 1,
  16. position: "begin-pickup",
  17. fuel: 40,
  18. energy: 50,
  19. money: 0,
  20. debrisInSpace: [],
  21. inCargoHold: [],
  22. maxCargoCapacity: 20,
  23. energyRegenRate: 10,
  24. maxBattery: 100,
  25. energyRegenAmount: 1,
  26. ramscoop: 25,
  27. energyRegen: 10,
  28. enabled: [],
  29. id: 1,
  30. name: "FR-LNC-3R",
  31. sprite: "playerShip1_red.png",
  32. };
  33. var templateLoader;
  34. var messageQueue = [];
  35. document.addEventListener("DOMContentLoaded", event => {
  36. errorMessage = "";
  37. document.getElementById("delete-game").addEventListener("click", () => {
  38. if (confirm("Are you sure you want to delete your game? This cannot be undone.")) {
  39. localStorage.clear();
  40. window.location = "./";
  41. }
  42. });
  43. templateLoader = new TemplateLoader();
  44. load();
  45. setInterval(gameTick, 1000);
  46. var settingsButton = document.getElementsByClassName('dropdown-toggle')[0];
  47. settingsButton.addEventListener('click', event => {
  48. event.stopPropagation();
  49. let dropdownTarget = settingsButton.getAttribute("data-target");
  50. let dropdownContainer = document.getElementById(dropdownTarget);
  51. if(dropdownContainer.style.display == "block") {
  52. dropdownContainer.style.display = "none";
  53. } else {
  54. dropdownContainer.style.display = "block";
  55. dropdownContainer.style.top = settingsButton.offsetTop + settingsButton.clientHeight + 4 + "px";
  56. dropdownContainer.style.left = settingsButton.offsetRight + dropdownContainer.clientWidth + "px";
  57. }
  58. });
  59. window.addEventListener("click", event => {
  60. var settingsButton = document.getElementsByClassName('dropdown-toggle')[0];
  61. let dropdownTarget = settingsButton.getAttribute("data-target");
  62. let dropdownContainer = document.getElementById(dropdownTarget);
  63. dropdownContainer.style.display = "none";
  64. });
  65. });
  66. function updateError() {
  67. let errorElement = document.getElementById("error");
  68. if (errorMessage != "") {
  69. toastMessage(`<span class="error">${errorMessage}</span>`);
  70. }
  71. errorElement.innerHTML = errorMessage;
  72. }
  73. function toastMessage(message, style) {
  74. messageQueue.push({message: message, style: style});
  75. processToasts();
  76. }
  77. function processToasts() {
  78. let message = messageQueue.pop();
  79. if(!message) {
  80. return;
  81. }
  82. let messageElement = document.createElement('div');
  83. messageElement.innerHTML = message.message;
  84. messageElement.className = "toast";
  85. if(message.style) {
  86. messageElement.className += " " + message.style;
  87. }
  88. let messageLength = message.message.split(" ").length;
  89. let timeoutId = setTimeout(() => hideToast(messageElement), Math.max(5000, messageLength * 500));
  90. let closeButton = document.createElement('i');
  91. closeButton.className = "toast-close fas fa-times";
  92. closeButton.addEventListener("click", event => {
  93. hideToast(messageElement);
  94. clearTimeout(timeoutId);
  95. });
  96. messageElement.appendChild(closeButton);
  97. document.body.appendChild(messageElement);
  98. updateToastPosition();
  99. }
  100. function updateToastPosition() {
  101. let activeToasts = document.body.getElementsByClassName("toast");
  102. let lastTop = 30;
  103. for(let i = activeToasts.length - 1; i >= 0; i--) {
  104. let toastElement = activeToasts[i];
  105. toastElement.style.right = "5%";
  106. toastElement.style.bottom = lastTop + "px";
  107. let bounds = toastElement.getBoundingClientRect();
  108. lastTop += bounds.height + 16;
  109. }
  110. }
  111. function hideToast(messageElement) {
  112. document.body.removeChild(messageElement);
  113. updateToastPosition();
  114. }
  115. function updateEnergy() {
  116. let batteryClass = "fa-battery-full";
  117. if(userData.energy/ userData.maxBattery < 0.75) {
  118. batteryClass = "fa-battery-three-quarters";
  119. }
  120. if(userData.energy/ userData.maxBattery < 0.5) {
  121. batteryClass = "fa-battery-half";
  122. }
  123. if(userData.energy/ userData.maxBattery < 0.25) {
  124. batteryClass = "fa-battery-quarter";
  125. }
  126. if(userData.energy/ userData.maxBattery < 0.05) {
  127. batteryClass = "fa-battery-empty";
  128. }
  129. document.getElementById("energy").innerHTML = `<i class="fas ${batteryClass}"></i> <span>${userData.energy} / ${userData.maxBattery}</span>`;
  130. }
  131. function updateMoney() {
  132. document.getElementById("money").innerHTML = `<i class="fas fa-won-sign"></i> ${userData.money}`;
  133. }
  134. function updateFuel() {
  135. document.getElementById("fuel").innerHTML = `<i class="fas fa-gas-pump"></i> ${userData.fuel}`;
  136. }
  137. function groupByType(dataset) {
  138. let reducedDataset = dataset.reduce((accumulator, value) => {
  139. accumulator[value.type] = accumulator[value.type] || [];
  140. accumulator[value.type].push(value);
  141. return accumulator;
  142. }, {});
  143. return Object.values(reducedDataset);
  144. }
  145. function updateActivity(newActivityText) {
  146. document.getElementById("activity").innerHTML = newActivityText;
  147. }
  148. function delayLoop(callback = () => { }, duration = 3000, step = 10) {
  149. var delay = duration / step;
  150. timeoutId = setTimeout(() => {
  151. let progress = document.getElementById("progress");
  152. progress.value += (delay / duration) * 100;
  153. if (progress.value >= 100) {
  154. progress.value = 100;
  155. callback();
  156. } else {
  157. delayLoop(callback, duration, step);
  158. }
  159. }, delay);
  160. }
  161. function gameTick() {
  162. processToasts();
  163. userData.energyRegen--;
  164. if (userData.energyRegen < 0) {
  165. userData.energy = Math.min(userData.maxBattery, userData.energy + userData.energyRegenAmount);
  166. updateEnergy();
  167. userData.energyRegen = userData.energyRegenRate;
  168. save();
  169. }
  170. if (userData.energy > 0 && isFlagEnabled('ion-engine-enabled')) {
  171. userData.energy--;
  172. if (isFlagEnabled('ramjet-enabled')) {
  173. userData.ramscoop--;
  174. if (userData.ramscoop < 0) {
  175. userData.ramscoop = 25;
  176. userData.fuel++;
  177. updateFuel();
  178. save();
  179. }
  180. }
  181. updateEnergy();
  182. save();
  183. }
  184. }
  185. function pickRandomItem(probabilityTable) {
  186. let roll = Math.floor(100 * Math.random()) + 1;
  187. let totalProbability = 0;
  188. let selectedItem = probabilityTable[0];
  189. for (let i = 0; i < probabilityTable.length; i++) {
  190. let item = probabilityTable[i];
  191. totalProbability += item.probability;
  192. if (roll < totalProbability) {
  193. selectedItem = item;
  194. break;
  195. }
  196. };
  197. return selectedItem;
  198. }