a munch adventure
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 

277 rindas
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. createStatDisplays(room.data.stats, "area");
  109. if (!state.player.rooms[room.id]) {
  110. state.player.rooms[room.id] = {};
  111. }
  112. const areaName = document.querySelector("#area-name");
  113. const areaDesc = document.querySelector("#area-desc");
  114. areaName.textContent = room.name;
  115. areaDesc.textContent = room.desc;
  116. Object.entries(dirs).forEach(([dir, name]) => {
  117. const button = document.querySelector("#move-" + dir);
  118. button.classList.add("disabled");
  119. button.setAttribute("disabled", "true");
  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, state))) {
  129. return;
  130. }
  131. }
  132. button.textContent = dest.name;
  133. // if any condition fails, don't enable/add a listener
  134. if (exit.conditions) {
  135. if (!exit.conditions.every(cond => cond(room,state))) {
  136. return;
  137. }
  138. }
  139. button.classList.remove("disabled");
  140. button.removeAttribute("disabled");
  141. if (moveListeners[dir]) {
  142. button.removeEventListener("click", moveListeners[dir]);
  143. moveListeners[dir] = undefined;
  144. }
  145. moveFunc = () => {
  146. moveToRoom(room, exit, exit.target, state);
  147. };
  148. button.addEventListener("click", moveFunc);
  149. moveListeners[dir] = moveFunc;
  150. button.addEventListener("mouseenter", () => {
  151. showActionDescription(exit.desc);
  152. });
  153. button.addEventListener("mouseleave", () => {
  154. removeActionDescription();
  155. });
  156. });
  157. }
  158. const actionHolder = document.querySelector("#actions");
  159. const existingButtons = Array.from(document.querySelectorAll("#actions > button"));
  160. const keptButtons = [];
  161. if (room.actions) {
  162. for (index in room.actions) {
  163. const action = room.actions[index];
  164. let button;
  165. if (actionButtons[index]) {
  166. button = actionButtons[index];
  167. }
  168. else {
  169. button = document.createElement("button");
  170. button.classList.add("action-button");
  171. actionButtons[index] = button;
  172. button.textContent = action.name;
  173. button.addEventListener("click", () => {
  174. action.execute(room, state);
  175. refresh();
  176. });
  177. button.addEventListener("mouseenter", () => {
  178. showActionDescription(action.desc);
  179. });
  180. button.addEventListener("mouseleave", () => {
  181. removeActionDescription();
  182. });
  183. }
  184. if (action.show) {
  185. if (!action.show.every(cond => cond(room, state))) {
  186. continue;
  187. }
  188. }
  189. keptButtons.push(actionButtons[index]);
  190. if (action.conditions) {
  191. if (!action.conditions.every(cond => cond(room, state))) {
  192. button.classList.add("disabled");
  193. button.setAttribute("disabled", "true");
  194. }
  195. }
  196. }
  197. const removed = existingButtons.filter(button => {
  198. return !keptButtons.includes(button);
  199. });
  200. removed.forEach(button => actionHolder.removeChild(button));
  201. const added = actionButtons.filter(button => {
  202. return keptButtons.includes(button) && !existingButtons.includes(button);
  203. });
  204. added.forEach(button => actionHolder.appendChild(button));
  205. }
  206. }