a munch adventure
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

279 lignes
6.1 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, state) {
  18. state.world = story["world"];
  19. initRoomState(state);
  20. }
  21. function initRoomState(state) {
  22. state.player.rooms = {};
  23. Object.entries(state.world).forEach(([key, val]) => {
  24. state.player.rooms[key] = {};
  25. });
  26. }
  27. function resetControls(state) {
  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("disabled");
  35. button.setAttribute("disabled", "true");
  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, state) {
  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, state)) {
  64. return;
  65. }
  66. }
  67. }
  68. if (room.hooks) {
  69. for (let hook of room.hooks) {
  70. if (!hook(room, state)) {
  71. return;
  72. }
  73. }
  74. }
  75. if (exit.move)
  76. exit.move(from, state);
  77. if (from && from.exit)
  78. from.exit(from, state);
  79. if (room.move)
  80. room.move(room, state);
  81. if (room.enter)
  82. room.enter(room, state);
  83. state.player.location = dest;
  84. resetControls(state);
  85. createStatDisplays(room.data.stats, "area");
  86. refresh();
  87. }
  88. function goToRoom(dest, state) {
  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, state)) {
  94. return;
  95. }
  96. }
  97. }
  98. if (from && from.exit)
  99. from.exit(from, state);
  100. if (room.enter)
  101. room.enter(state.world[dest], state);
  102. state.player.location = dest;
  103. resetControls(state);
  104. createStatDisplays(room.data.stats, "area");
  105. refresh();
  106. }
  107. function updateRoom(state) {
  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. button.classList.add("disabled");
  120. button.setAttribute("disabled", "true");
  121. button.textContent = dirs[dir];
  122. });
  123. if (room.exits) {
  124. Object.entries(room.exits).forEach(([dir, exit]) => {
  125. const button = document.querySelector("#move-" + dir);
  126. const dest = state.world[exit.target];
  127. // don't even show an exit if this fails!
  128. if (exit.show) {
  129. if (!exit.show.every(cond => cond(room, state))) {
  130. return;
  131. }
  132. }
  133. button.textContent = dest.name;
  134. // if any condition fails, don't enable/add a listener
  135. if (exit.conditions) {
  136. if (!exit.conditions.every(cond => cond(room,state))) {
  137. return;
  138. }
  139. }
  140. button.classList.remove("disabled");
  141. button.removeAttribute("disabled");
  142. if (moveListeners[dir]) {
  143. button.removeEventListener("click", moveListeners[dir]);
  144. moveListeners[dir] = undefined;
  145. }
  146. moveFunc = () => {
  147. moveToRoom(room, exit, exit.target, state);
  148. };
  149. button.addEventListener("click", moveFunc);
  150. moveListeners[dir] = moveFunc;
  151. button.addEventListener("mouseenter", () => {
  152. showActionDescription(exit.desc);
  153. });
  154. button.addEventListener("mouseleave", () => {
  155. removeActionDescription();
  156. });
  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. action.execute(room, state);
  176. refresh();
  177. });
  178. button.addEventListener("mouseenter", () => {
  179. showActionDescription(action.desc);
  180. });
  181. button.addEventListener("mouseleave", () => {
  182. removeActionDescription();
  183. });
  184. }
  185. if (action.show) {
  186. if (!action.show.every(cond => cond(room, state))) {
  187. continue;
  188. }
  189. }
  190. keptButtons.push(actionButtons[index]);
  191. if (action.conditions) {
  192. if (!action.conditions.every(cond => cond(room, state))) {
  193. button.classList.add("disabled");
  194. button.setAttribute("disabled", "true");
  195. }
  196. }
  197. }
  198. const removed = existingButtons.filter(button => {
  199. return !keptButtons.includes(button);
  200. });
  201. removed.forEach(button => actionHolder.removeChild(button));
  202. const added = actionButtons.filter(button => {
  203. return keptButtons.includes(button) && !existingButtons.includes(button);
  204. });
  205. added.forEach(button => actionHolder.appendChild(button));
  206. }
  207. }