a munch adventure
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

281 Zeilen
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, 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("missing");
  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.classList.remove("missing");
  134. button.classList.add("disabled");
  135. button.textContent = dest.name;
  136. // if any condition fails, don't enable/add a listener
  137. if (exit.conditions) {
  138. if (!exit.conditions.every(cond => cond(room,state))) {
  139. return;
  140. }
  141. }
  142. button.classList.remove("disabled");
  143. button.removeAttribute("disabled");
  144. if (moveListeners[dir]) {
  145. button.removeEventListener("click", moveListeners[dir]);
  146. moveListeners[dir] = undefined;
  147. }
  148. moveFunc = () => {
  149. moveToRoom(room, exit, exit.target, state);
  150. };
  151. button.addEventListener("click", moveFunc);
  152. moveListeners[dir] = moveFunc;
  153. button.addEventListener("mouseenter", () => {
  154. showActionDescription(exit.desc);
  155. });
  156. button.addEventListener("mouseleave", () => {
  157. removeActionDescription();
  158. });
  159. });
  160. }
  161. const actionHolder = document.querySelector("#actions");
  162. const existingButtons = Array.from(document.querySelectorAll("#actions > button"));
  163. const keptButtons = [];
  164. if (room.actions) {
  165. for (index in room.actions) {
  166. const action = room.actions[index];
  167. let button;
  168. if (actionButtons[index]) {
  169. button = actionButtons[index];
  170. }
  171. else {
  172. button = document.createElement("button");
  173. button.classList.add("action-button");
  174. actionButtons[index] = button;
  175. button.textContent = action.name;
  176. button.addEventListener("click", () => {
  177. action.execute(room, state);
  178. refresh();
  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, state))) {
  189. continue;
  190. }
  191. }
  192. keptButtons.push(actionButtons[index]);
  193. if (action.conditions) {
  194. if (!action.conditions.every(cond => cond(room, state))) {
  195. button.classList.add("disabled");
  196. button.setAttribute("disabled", "true");
  197. }
  198. }
  199. }
  200. const removed = existingButtons.filter(button => {
  201. return !keptButtons.includes(button);
  202. });
  203. removed.forEach(button => actionHolder.removeChild(button));
  204. const added = actionButtons.filter(button => {
  205. return keptButtons.includes(button) && !existingButtons.includes(button);
  206. });
  207. added.forEach(button => actionHolder.appendChild(button));
  208. }
  209. }