cookie clicker but bigger
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.
 
 
 
 

347 lines
8.0 KiB

  1. "use strict";
  2. let belongings = {};
  3. let ownedUpgrades = {};
  4. let remainingUpgrades = [];
  5. let resources = {};
  6. let updateRate = 60;
  7. function calculateProductivity() {
  8. let productivity = 0;
  9. for (const [key, value] of Object.entries(belongings)) {
  10. productivity += productivityOf(key);
  11. }
  12. return productivity;
  13. }
  14. // here's where upgrades will go :3
  15. function productivityOf(type) {
  16. let baseProd = buildings[type].prod;
  17. for (const [key, value] of Object.entries(upgrades)) {
  18. if (!ownedUpgrades[key]) {
  19. continue;
  20. }
  21. if (value.effect.type == "prod-2x") {
  22. if (value.effect.target == key) {
  23. baseProd *= 2;
  24. }
  25. }
  26. }
  27. return baseProd * belongings[type].count;
  28. }
  29. function costOfBuilding(type) {
  30. let baseCost = buildings[type].cost
  31. let countCost = baseCost * Math.pow(1.15, belongings[type].count);
  32. return Math.round(countCost);
  33. }
  34. function buyBuilding(type) {
  35. let cost = costOfBuilding(type);
  36. if (resources.food >= cost) {
  37. belongings[type].count += 1;
  38. resources.food -= cost;
  39. }
  40. }
  41. // update stuff
  42. function updateResources() {
  43. addResources();
  44. displayResources();
  45. displayBuildings();
  46. displayUpgrades();
  47. setTimeout(updateResources, 1000/updateRate);
  48. }
  49. function addResources() {
  50. resources.food += calculateProductivity() * 1 / updateRate;
  51. }
  52. function displayResources() {
  53. document.getElementById("resource-food").innerText = "Food: " + render(resources.food);
  54. document.getElementById("productivity").innerText = (Math.round(calculateProductivity() * 10) / 10) + " food/sec";
  55. }
  56. function displayBuildings() {
  57. for (const [key, value] of Object.entries(belongings)) {
  58. let button = document.querySelector("#building-" + key);
  59. document.querySelector("#building-" + key + " > .building-button-name").innerText = value.count + " " + (value.count == 1 ? buildings[key].name : buildings[key].plural);
  60. document.querySelector("#building-" + key + " > .building-button-cost").innerText = costOfBuilding(key) + " food";
  61. if (costOfBuilding(key) > resources.food) {
  62. button.classList.add("building-button-disabled");
  63. } else {
  64. button.classList.remove("building-button-disabled");
  65. }
  66. }
  67. }
  68. function canAfford(cost) {
  69. for (const [resource, amount] of Object.entries(cost)) {
  70. if (resources[resource] < amount) {
  71. return false;
  72. }
  73. }
  74. return true;
  75. }
  76. function spend(cost) {
  77. for (const [resource, amount] of Object.entries(cost)) {
  78. resources[resource] -= amount;
  79. }
  80. }
  81. function displayUpgrades() {
  82. for (let id of remainingUpgrades) {
  83. let button = document.querySelector("#upgrade-" + id);
  84. if (ownedUpgrades[id]) {
  85. button.style.display = "none";
  86. continue;
  87. }
  88. if (upgradeAvailable(id)) {
  89. button.classList.remove("upgrade-button-inactive");
  90. } else {
  91. button.classList.add("upgrade-button-inactive");
  92. }
  93. }
  94. // now we throw out stuff
  95. for (let i = remainingUpgrades.length-1; i >= 0; i--) {
  96. if (ownedUpgrades[remainingUpgrades[i]]) {
  97. remainingUpgrades.splice(i, 1);
  98. }
  99. }
  100. }
  101. function buyUpgrade(id) {
  102. if (ownedUpgrades[id]) {
  103. return;
  104. }
  105. let upgrade = upgrades[id];
  106. if (!canAfford(upgrade.cost)) {
  107. return;
  108. }
  109. spend(upgrade.cost);
  110. ownedUpgrades[id] = true;
  111. }
  112. function eatMicro() {
  113. resources.food += 1;
  114. }
  115. // setup stuff lol
  116. // we'll initialize the dict of buildings we can own
  117. function setup() {
  118. initializeData();
  119. createButtons();
  120. createDisplays();
  121. registerListeners();
  122. }
  123. function initializeData() {
  124. for (const [key, value] of Object.entries(buildings)) {
  125. belongings[key] = {};
  126. belongings[key].count = 0;
  127. }
  128. for (const [key, value] of Object.entries(upgrades)) {
  129. ownedUpgrades[key] = false;
  130. }
  131. }
  132. function registerListeners() {
  133. document.querySelectorAll(".building-button").forEach(function(button) {
  134. let id = button.id.replace("building-", "");
  135. button.addEventListener("click", function() { buyBuilding(id); });
  136. });
  137. document.querySelector("#tasty-micro").addEventListener("click", eatMicro);
  138. }
  139. function createButtons() {
  140. createBuildings();
  141. createUpgrades();
  142. }
  143. function createBuildings() {
  144. let container = document.querySelector("#buildings-area");
  145. for (const [key, value] of Object.entries(buildings)) {
  146. let button = document.createElement("div");
  147. button.classList.add("building-button");
  148. button.id = "building-" + key;
  149. let buttonName = document.createElement("div");
  150. buttonName.classList.add("building-button-name");
  151. let buttonCost = document.createElement("div");
  152. buttonCost.classList.add("building-button-cost");
  153. button.appendChild(buttonName);
  154. button.appendChild(buttonCost);
  155. container.appendChild(button);
  156. }
  157. }
  158. function upgradeAvailable(id) {
  159. if (ownedUpgrades[id]) {
  160. return false;
  161. }
  162. if (!canAfford(upgrades[id].cost)) {
  163. return false;
  164. }
  165. for (const [type, reqs] of Object.entries(upgrades[id].prereqs)) {
  166. if (type == "buildings") {
  167. for (const [building, amount] of Object.entries(upgrades[id].prereqs[type])) {
  168. if (belongings[building].count < amount) {
  169. return false;
  170. }
  171. }
  172. }
  173. }
  174. return true;
  175. }
  176. function createUpgrades() {
  177. let container = document.querySelector("#upgrades-list");
  178. for (const [key, value] of Object.entries(upgrades)) {
  179. remainingUpgrades.push(key);
  180. let button = document.createElement("div");
  181. button.classList.add("upgrade-button");
  182. button.id = "upgrade-" + key;
  183. let buttonName = document.createElement("div");
  184. buttonName.classList.add("upgrade-button-name");
  185. buttonName.innerText = value.name;
  186. button.appendChild(buttonName);
  187. button.addEventListener("mousemove", function(e) { upgradeTooltip(key, e); });
  188. button.addEventListener("mouseleave", function() { upgradeTooltipRemove(); });
  189. button.addEventListener("click", function() { buyUpgrade(key); });
  190. container.appendChild(button);
  191. }
  192. }
  193. function createDisplays() {
  194. let resourceList = document.querySelector("#resource-list");
  195. for (const [key, value] of Object.entries(resourceTypes)) {
  196. resources[key] = 0;
  197. let line = document.createElement("div");
  198. line.id = "resource-" + key;
  199. resourceList.appendChild(line);
  200. }
  201. }
  202. function renderCost(cost) {
  203. let list = [];
  204. for (const [key, value] of Object.entries(cost)) {
  205. list.push(value + " " + resourceTypes[key].name);
  206. }
  207. let divs = [];
  208. for (let line of list) {
  209. let div = document.createElement("div");
  210. div.innerText = line;
  211. divs.push(div);
  212. }
  213. return divs;
  214. }
  215. function renderPrereqs(prereqs) {
  216. let list = [];
  217. for (const [key, value] of Object.entries(prereqs)) {
  218. if (key == "buildings") {
  219. for (const [building, amount] of Object.entries(prereqs.buildings)) {
  220. list.push(buildings[building].name + " x" + amount);
  221. }
  222. }
  223. }
  224. let divs = [];
  225. for (let line of list) {
  226. let div = document.createElement("div");
  227. div.innerText = line;
  228. divs.push(div);
  229. }
  230. return divs;
  231. }
  232. function upgradeTooltip(id, event) {
  233. let tooltip = document.querySelector("#upgrade-tooltip");
  234. tooltip.style.setProperty("display", "block");
  235. let tooltipDesc = document.querySelector("#upgrade-tooltip-desc");
  236. tooltipDesc.innerText = upgrades[id].desc;
  237. let tooltipEffect = document.querySelector("#upgrade-tooltip-effect");
  238. tooltipEffect.innerText = upgrade_types[upgrades[id].effect.type].desc(buildings[upgrades[id].effect.target].name);
  239. let tooltipCost = document.querySelector("#upgrade-tooltip-cost");
  240. replaceChildren(tooltipCost, renderCost(upgrades[id].cost));
  241. let tooltipPrereqs = document.querySelector("#upgrade-tooltip-prereqs");
  242. replaceChildren(tooltipPrereqs, renderPrereqs(upgrades[id].prereqs));
  243. let yOffset = tooltip.parentElement.getBoundingClientRect().y;
  244. let yTrans = Math.round(event.clientY - yOffset);
  245. tooltip.style.setProperty("transform", "translate(-220px, " + yTrans + "px)");
  246. }
  247. function upgradeTooltipRemove() {
  248. let tooltip = document.querySelector("#upgrade-tooltip");
  249. tooltip.style.setProperty("display", "none");
  250. }
  251. window.onload = function() {
  252. setup();
  253. setTimeout(updateResources, 1000/updateRate);
  254. }