a munch adventure
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

291 satır
6.2 KiB

  1. dirs = {
  2. "up-left": "Northwest",
  3. "up": "North",
  4. "up-right": "Northeast",
  5. "left": "West",
  6. "right": "East",
  7. "down-left": "Southwest",
  8. "down": "South",
  9. "down-right": "Southeast",
  10. "ascend": "Up",
  11. "descend": "Down"
  12. }
  13. moveListeners = {
  14. }
  15. actionButtons = [
  16. ]
  17. function initWorld(story) {
  18. state.world = story["world"];
  19. initRoomState(state);
  20. }
  21. function initRoomState() {
  22. state.player.rooms = {};
  23. Object.entries(state.world).forEach(([key, val]) => {
  24. state.player.rooms[key] = {};
  25. });
  26. }
  27. function resetControls() {
  28. const moveHolder = document.querySelector("#move-holder");
  29. moveHolder.innerHTML = "";
  30. Object.entries(dirs).forEach(([dir, name]) => {
  31. const button = document.createElement("button");
  32. button.classList.add("move-button")
  33. button.id = "move-" + dir;
  34. button.classList.add("missing");
  35. disableButton(button);
  36. button.textContent = dirs[dir];
  37. moveHolder.appendChild(button);
  38. moveListeners[dir] = undefined;
  39. });
  40. const actionHolder = document.querySelector("#actions");
  41. actionHolder.innerHTML = "";
  42. actionButtons = [];
  43. const actions = state.world[state.player.location].actions;
  44. if (actions) {
  45. actions.forEach(action => {
  46. actionButtons.push(undefined);
  47. });
  48. }
  49. }
  50. function showActionDescription(desc) {
  51. const descHolder = document.querySelector("#desc");
  52. descHolder.textContent = desc;
  53. }
  54. function removeActionDescription() {
  55. const descHolder = document.querySelector("#desc");
  56. descHolder.textContent = "";
  57. }
  58. function moveToRoom(src, exit, dest) {
  59. const from = state.world[state.player.location];
  60. const room = state.world[dest];
  61. if (exit.hooks) {
  62. for (let hook of exit.hooks) {
  63. if (!hook(room, exit)) {
  64. return;
  65. }
  66. }
  67. }
  68. if (room.hooks) {
  69. for (let hook of room.hooks) {
  70. if (!hook(room)) {
  71. return;
  72. }
  73. }
  74. }
  75. if (exit.move)
  76. exit.move(from);
  77. if (from && from.exit)
  78. from.exit(from);
  79. if (room.move)
  80. room.move(room);
  81. if (room.enter)
  82. room.enter(room);
  83. state.player.location = dest;
  84. resetControls(state);
  85. createStatDisplays(room.data.stats, "area");
  86. refresh();
  87. }
  88. function goToRoom(dest) {
  89. const from = state.world[state.player.location];
  90. const room = state.world[dest];
  91. if (room.hooks) {
  92. for (let hook of room.hooks) {
  93. if (!hook(room)) {
  94. return;
  95. }
  96. }
  97. }
  98. if (from && from.exit)
  99. from.exit(from);
  100. if (room.enter)
  101. room.enter(state.world[dest]);
  102. state.player.location = dest;
  103. resetControls(state);
  104. createStatDisplays(room.data.stats, "area");
  105. refresh();
  106. }
  107. function updateRoom() {
  108. const name = state.player.location;
  109. const room = state.world[name];
  110. if (!state.player.rooms[room.id]) {
  111. state.player.rooms[room.id] = {};
  112. }
  113. const areaName = document.querySelector("#area-name");
  114. const areaDesc = document.querySelector("#area-desc");
  115. areaName.textContent = room.name;
  116. areaDesc.textContent = room.desc;
  117. Object.entries(dirs).forEach(([dir, name]) => {
  118. const button = document.querySelector("#move-" + dir);
  119. disableButton(button);
  120. button.textContent = dirs[dir];
  121. });
  122. if (room.exits) {
  123. Object.entries(room.exits).forEach(([dir, exit]) => {
  124. const button = document.querySelector("#move-" + dir);
  125. const dest = state.world[exit.target];
  126. // don't even show an exit if this fails!
  127. if (exit.show) {
  128. if (!exit.show.every(cond => cond(room))) {
  129. return;
  130. }
  131. }
  132. button.classList.remove("missing");
  133. disableButton(button);
  134. button.textContent = dest.name;
  135. button.addEventListener("mouseenter", () => {
  136. showActionDescription(exit.desc);
  137. });
  138. button.addEventListener("mouseleave", () => {
  139. removeActionDescription();
  140. });
  141. // if any condition fails, don't turn it on and allow clicks
  142. if (exit.conditions) {
  143. if (!exit.conditions.every(cond => cond(room,state))) {
  144. return;
  145. }
  146. }
  147. enableButton(button);
  148. if (moveListeners[dir]) {
  149. button.removeEventListener("click", moveListeners[dir]);
  150. moveListeners[dir] = undefined;
  151. }
  152. moveFunc = () => {
  153. moveToRoom(room, exit, exit.target);
  154. };
  155. button.addEventListener("click", moveFunc);
  156. moveListeners[dir] = moveFunc;
  157. });
  158. }
  159. const actionHolder = document.querySelector("#actions");
  160. const existingButtons = Array.from(document.querySelectorAll("#actions > button"));
  161. const keptButtons = [];
  162. if (room.actions) {
  163. for (index in room.actions) {
  164. const action = room.actions[index];
  165. let button;
  166. if (actionButtons[index]) {
  167. button = actionButtons[index];
  168. }
  169. else {
  170. button = document.createElement("button");
  171. button.classList.add("action-button");
  172. actionButtons[index] = button;
  173. button.textContent = action.name;
  174. button.addEventListener("click", () => {
  175. if (!button.classList.contains("disabled")) {
  176. action.execute(room);
  177. refresh();
  178. }
  179. });
  180. button.addEventListener("mouseenter", () => {
  181. showActionDescription(action.desc);
  182. });
  183. button.addEventListener("mouseleave", () => {
  184. removeActionDescription();
  185. });
  186. }
  187. if (action.show) {
  188. if (!action.show.every(cond => cond(room))) {
  189. continue;
  190. }
  191. }
  192. keptButtons.push(actionButtons[index]);
  193. if (action.conditions) {
  194. if (!action.conditions.every(cond => cond(room))) {
  195. disableButton(button);
  196. } else {
  197. enableButton(button);
  198. }
  199. }
  200. }
  201. const removed = existingButtons.filter(button => {
  202. return !keptButtons.includes(button);
  203. });
  204. removed.forEach(button => actionHolder.removeChild(button));
  205. const added = actionButtons.filter(button => {
  206. return keptButtons.includes(button) && !existingButtons.includes(button);
  207. });
  208. added.forEach(button => actionHolder.appendChild(button));
  209. }
  210. }
  211. function disableButton(button) {
  212. button.setAttribute("tabindex", "-1");
  213. button.classList.add("disabled");
  214. }
  215. function enableButton(button) {
  216. button.removeAttribute("tabindex");
  217. button.classList.remove("disabled");
  218. }