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.
 
 
 
 

275 lignes
6.0 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. refresh();
  86. }
  87. function goToRoom(dest, state) {
  88. const from = state.world[state.player.location];
  89. const room = state.world[dest];
  90. if (room.hooks) {
  91. for (let hook of room.hooks) {
  92. if (!hook(room, state)) {
  93. return;
  94. }
  95. }
  96. }
  97. if (from && from.exit)
  98. from.exit(from, state);
  99. if (room.enter)
  100. room.enter(state.world[dest], state);
  101. state.player.location = dest;
  102. resetControls(state);
  103. refresh();
  104. }
  105. function updateRoom(state) {
  106. const name = state.player.location;
  107. const room = state.world[name];
  108. if (!state.player.rooms[room.id]) {
  109. state.player.rooms[room.id] = {};
  110. }
  111. const areaName = document.querySelector("#area-name");
  112. const areaDesc = document.querySelector("#area-desc");
  113. areaName.textContent = room.name;
  114. areaDesc.textContent = room.desc;
  115. Object.entries(dirs).forEach(([dir, name]) => {
  116. const button = document.querySelector("#move-" + dir);
  117. button.classList.add("disabled");
  118. button.setAttribute("disabled", "true");
  119. button.textContent = dirs[dir];
  120. });
  121. if (room.exits) {
  122. Object.entries(room.exits).forEach(([dir, exit]) => {
  123. const button = document.querySelector("#move-" + dir);
  124. const dest = state.world[exit.target];
  125. // don't even show an exit if this fails!
  126. if (exit.show) {
  127. if (!exit.show.every(cond => cond(room, state))) {
  128. return;
  129. }
  130. }
  131. button.textContent = dest.name;
  132. // if any condition fails, don't enable/add a listener
  133. if (exit.conditions) {
  134. if (!exit.conditions.every(cond => cond(room,state))) {
  135. return;
  136. }
  137. }
  138. button.classList.remove("disabled");
  139. button.removeAttribute("disabled");
  140. if (moveListeners[dir]) {
  141. button.removeEventListener("click", moveListeners[dir]);
  142. moveListeners[dir] = undefined;
  143. }
  144. moveFunc = () => {
  145. moveToRoom(room, exit, exit.target, state);
  146. };
  147. button.addEventListener("click", moveFunc);
  148. moveListeners[dir] = moveFunc;
  149. button.addEventListener("mouseenter", () => {
  150. showActionDescription(exit.desc);
  151. });
  152. button.addEventListener("mouseleave", () => {
  153. removeActionDescription();
  154. });
  155. });
  156. }
  157. const actionHolder = document.querySelector("#actions");
  158. const existingButtons = Array.from(document.querySelectorAll("#actions > button"));
  159. const keptButtons = [];
  160. if (room.actions) {
  161. for (index in room.actions) {
  162. const action = room.actions[index];
  163. let button;
  164. if (actionButtons[index]) {
  165. button = actionButtons[index];
  166. }
  167. else {
  168. button = document.createElement("button");
  169. button.classList.add("action-button");
  170. actionButtons[index] = button;
  171. button.textContent = action.name;
  172. button.addEventListener("click", () => {
  173. action.execute(room, state);
  174. refresh();
  175. });
  176. button.addEventListener("mouseenter", () => {
  177. showActionDescription(action.desc);
  178. });
  179. button.addEventListener("mouseleave", () => {
  180. removeActionDescription();
  181. });
  182. }
  183. if (action.show) {
  184. if (!action.show.every(cond => cond(room, state))) {
  185. continue;
  186. }
  187. }
  188. keptButtons.push(actionButtons[index]);
  189. if (action.conditions) {
  190. if (!action.conditions.every(cond => cond(room, state))) {
  191. button.classList.add("disabled");
  192. button.setAttribute("disabled", "true");
  193. }
  194. }
  195. }
  196. const removed = existingButtons.filter(button => {
  197. return !keptButtons.includes(button);
  198. });
  199. removed.forEach(button => actionHolder.removeChild(button));
  200. const added = actionButtons.filter(button => {
  201. return keptButtons.includes(button) && !existingButtons.includes(button);
  202. });
  203. added.forEach(button => actionHolder.appendChild(button));
  204. }
  205. }