munch
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

300 строки
8.3 KiB

  1. let currentRoom = null;
  2. let currentDialog = null;
  3. let dirButtons = [];
  4. let actionButtons = [];
  5. let mode = "explore";
  6. let actions = [];
  7. let time = 9*60*60;
  8. let newline = " ";
  9. let player = new Player();
  10. function round(number, digits) {
  11. return Math.round(number * Math.pow(10,digits)) / Math.pow(10,digits);
  12. }
  13. function updateExploreCompass() {
  14. for (let i = 0; i < dirButtons.length; i++) {
  15. let button = dirButtons[i];
  16. if (currentRoom.exits[i] == null) {
  17. button.disabled = true;
  18. button.classList.remove("active-compass-button");
  19. button.classList.add("inactive-button");
  20. button.innerHTML = "";
  21. } else {
  22. button.disabled = false;
  23. button.classList.remove("inactive-button");
  24. button.classList.add("active-compass-button");
  25. button.innerHTML = currentRoom.exits[i].name;
  26. }
  27. }
  28. }
  29. function updateExploreActions() {
  30. for (let i = 0; i < actionButtons.length; i++) {
  31. if (i < actions.length) {
  32. actionButtons[i].disabled = false;
  33. actionButtons[i].innerHTML = actions[i].name;
  34. actionButtons[i].classList.remove("inactive-button");
  35. actionButtons[i].classList.add("active-button");
  36. }
  37. else {
  38. actionButtons[i].disabled = true;
  39. actionButtons[i].innerHTML = "";
  40. actionButtons[i].classList.remove("active-button");
  41. actionButtons[i].classList.add("inactive-button");
  42. }
  43. }
  44. }
  45. function updateExplore() {
  46. updateExploreCompass();
  47. updateExploreActions();
  48. }
  49. function updateCombat() {
  50. let list = document.getElementById("combat");
  51. while(list.firstChild) {
  52. list.removeChild(list.firstChild);
  53. }
  54. for (let i = 0; i < player.attacks.length; i++) {
  55. let li = document.createElement("li");
  56. let button = document.createElement("button");
  57. button.classList.add("combat-button");
  58. button.innerHTML = player.attacks[i].name;
  59. button.addEventListener("click", function() { attackClicked(i); } );
  60. button.addEventListener("mouseover", function() { attackHovered(i); } );
  61. li.appendChild(button);
  62. list.appendChild(li);
  63. }
  64. }
  65. function updateDialog() {
  66. let list = document.getElementById("dialog");
  67. while(list.firstChild) {
  68. list.removeChild(list.firstChild);
  69. }
  70. for (let i = 0; i < currentDialog.choices.length; i++) {
  71. let li = document.createElement("li");
  72. let button = document.createElement("button");
  73. button.classList.add("dialog-button");
  74. button.innerHTML = currentDialog.choices[i].text;
  75. button.addEventListener("click", function() { dialogClicked(i); });
  76. li.appendChild(button);
  77. list.appendChild(li);
  78. }
  79. }
  80. function updateDisplay() {
  81. switch(mode) {
  82. case "explore":
  83. document.getElementById("selector-explore").style.display = "flex";
  84. document.getElementById("selector-combat").style.display = "none";
  85. document.getElementById("selector-dialog").style.display = "none";
  86. updateExplore();
  87. break;
  88. case "combat":
  89. document.getElementById("selector-explore").style.display = "none";
  90. document.getElementById("selector-combat").style.display = "flex";
  91. document.getElementById("selector-dialog").style.display = "none";
  92. updateCombat();
  93. break;
  94. case "dialog":
  95. document.getElementById("selector-explore").style.display = "none";
  96. document.getElementById("selector-combat").style.display = "none";
  97. document.getElementById("selector-dialog").style.display = "flex";
  98. updateDialog();
  99. break;
  100. }
  101. document.getElementById("time").innerHTML = "Time: " + renderTime(time);
  102. document.getElementById("stat-name").innerHTML = "Name: " + player.name;
  103. document.getElementById("stat-health").innerHTML = "Health: " + player.health + "/" + player.maxHealth;
  104. document.getElementById("stat-fullness").innerHTML = "Fullness: " + round(player.fullness(),0);
  105. }
  106. function advanceTime(amount) {
  107. time = (time + amount) % 86400;
  108. update(player.stomach.digest(amount));
  109. }
  110. function renderTime(time) {
  111. let suffix = (time < 43200) ? "AM" : "PM";
  112. let hour = Math.floor((time % 43200) / 3600);
  113. if (hour == 0)
  114. hour = 12;
  115. let minute = Math.floor(time / 60) % 60;
  116. if (minute < 9)
  117. minute = "0" + minute;
  118. return hour + ":" + minute + " " + suffix;
  119. }
  120. function move(direction) {
  121. let target = currentRoom.exits[direction];
  122. if (target == null) {
  123. alert("Tried to move to an empty room!");
  124. return;
  125. }
  126. moveTo(target,currentRoom.exitDescs[direction]);
  127. }
  128. function moveTo(room,desc="You go places lol") {
  129. actions = [];
  130. currentRoom = room;
  131. advanceTime(30);
  132. currentRoom.objects.forEach(function (object) {
  133. object.actions.forEach(function (action) {
  134. actions.push(action);
  135. });
  136. });
  137. update([desc,newline]);
  138. currentRoom.visit();
  139. }
  140. window.addEventListener('load', function(event) {
  141. loadActions();
  142. loadCompass();
  143. loadDialog();
  144. currentRoom = createWorld();
  145. moveTo(currentRoom);
  146. updateDisplay();
  147. });
  148. function update(lines=[]) {
  149. let log = document.getElementById("log");
  150. for (let i=0; i<lines.length; i++) {
  151. let div = document.createElement("div");
  152. div.innerHTML = lines[i];
  153. log.appendChild(div);
  154. }
  155. log.scrollTop = log.scrollHeight;
  156. updateDisplay();
  157. }
  158. function changeMode(mode) {
  159. this.mode = mode;
  160. let body = document.querySelector("body");
  161. body.className = "";
  162. switch(mode) {
  163. case "explore":
  164. case "dialog":
  165. body.classList.add("explore");
  166. break;
  167. case "combat":
  168. body.classList.add("combat");
  169. break;
  170. case "eaten":
  171. body.classList.add("eaten");
  172. break;
  173. }
  174. }
  175. function startCombat(opponent) {
  176. mode = "combat";
  177. currentFoe = opponent;
  178. update(["Oh shit it's a " + opponent.description()]);
  179. }
  180. function attackClicked(index) {
  181. update([player.attacks[index].attack(currentFoe)]);
  182. if (currentFoe.health <= 0) {
  183. update(["The " + currentFoe.description() + " falls to the ground!"]);
  184. startDialog(new FallenFoe(currentFoe));
  185. } else {
  186. let attack = pick(currentFoe.attacks);
  187. update([attack.attackPlayer(player)]);
  188. if (player.health <= 0) {
  189. update(["You fall to the ground..."]);
  190. changeMode("eaten");
  191. }
  192. }
  193. }
  194. function attackHovered(index) {
  195. document.getElementById("combat-desc").innerHTML = player.attacks[index].desc;
  196. }
  197. function startDialog(dialog) {
  198. mode = "dialog";
  199. currentDialog = dialog;
  200. update([currentDialog.text]);
  201. currentDialog.visit();
  202. updateDisplay();
  203. }
  204. function dialogClicked(index) {
  205. currentDialog = currentDialog.choices[index].node;
  206. update([currentDialog.text]);
  207. currentDialog.visit();
  208. if (currentDialog.choices.length == 0) {
  209. mode = "explore";
  210. updateDisplay();
  211. }
  212. }
  213. function loadDialog() {
  214. dialogButtons = Array.from( document.querySelectorAll(".dialog-button"));
  215. for (let i = 0; i < dialogButtons.length; i++) {
  216. dialogButtons[i].addEventListener("click", function() { dialogClicked(i); });
  217. }
  218. }
  219. function actionClicked(index) {
  220. actions[index].action();
  221. }
  222. function loadActions() {
  223. actionButtons = Array.from( document.querySelectorAll(".action-button"));
  224. for (let i = 0; i < actionButtons.length; i++) {
  225. actionButtons[i].addEventListener("click", function() { actionClicked(i); });
  226. }
  227. }
  228. function loadCompass() {
  229. dirButtons[NORTH_WEST] = document.getElementById("compass-north-west");
  230. dirButtons[NORTH_WEST].addEventListener("click", function() {
  231. move(NORTH_WEST);
  232. });
  233. dirButtons[NORTH] = document.getElementById("compass-north");
  234. dirButtons[NORTH].addEventListener("click", function() {
  235. move(NORTH);
  236. });
  237. dirButtons[NORTH_EAST] = document.getElementById("compass-north-east");
  238. dirButtons[NORTH_EAST].addEventListener("click", function() {
  239. move(NORTH_EAST);
  240. });
  241. dirButtons[WEST] = document.getElementById("compass-west");
  242. dirButtons[WEST].addEventListener("click", function() {
  243. move(WEST);
  244. });
  245. dirButtons[EAST] = document.getElementById("compass-east");
  246. dirButtons[EAST].addEventListener("click", function() {
  247. move(EAST);
  248. });
  249. dirButtons[SOUTH_WEST] = document.getElementById("compass-south-west");
  250. dirButtons[SOUTH_WEST].addEventListener("click", function() {
  251. move(SOUTH_WEST);
  252. });
  253. dirButtons[SOUTH] = document.getElementById("compass-south");
  254. dirButtons[SOUTH].addEventListener("click", function() {
  255. move(SOUTH);
  256. });
  257. dirButtons[SOUTH_EAST] = document.getElementById("compass-south-east");
  258. dirButtons[SOUTH_EAST].addEventListener("click", function() {
  259. move(SOUTH_EAST);
  260. });
  261. }