a munch adventure
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 

198 рядки
4.3 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. function initWorld(story, state) {
  14. state.world = story["world"];
  15. initRoomState(state);
  16. }
  17. function initRoomState(state) {
  18. state.player.rooms = {};
  19. Object.entries(state.world).forEach(([key, val]) => {
  20. state.player.rooms[key] = {};
  21. });
  22. }
  23. function showActionDescription(desc) {
  24. const descHolder = document.querySelector("#desc");
  25. descHolder.textContent = desc;
  26. }
  27. function removeActionDescription() {
  28. const descHolder = document.querySelector("#desc");
  29. descHolder.textContent = "";
  30. }
  31. function moveToRoom(src, exit, dest, state) {
  32. const from = state.world[state.player.location];
  33. const room = state.world[dest];
  34. if (exit.hooks) {
  35. for (let hook of exit.hooks) {
  36. if (!hook(room, exit, state)) {
  37. return;
  38. }
  39. }
  40. }
  41. if (room.hooks) {
  42. for (let hook of room.hooks) {
  43. if (!hook(room, state)) {
  44. return;
  45. }
  46. }
  47. }
  48. if (from && from.exit)
  49. from.exit(state.world[dest], state);
  50. if (room.move)
  51. room.move(state.world[dest], state);
  52. if (room.enter)
  53. room.enter(state.world[dest], state);
  54. state.player.location = dest;
  55. refresh();
  56. }
  57. function goToRoom(dest, state) {
  58. const from = state.world[state.player.location];
  59. const room = state.world[dest];
  60. if (room.hooks) {
  61. for (let hook of room.hooks) {
  62. if (!hook(room, state)) {
  63. return;
  64. }
  65. }
  66. }
  67. if (from && from.exit)
  68. from.exit(state.world[dest], state);
  69. if (room.enter)
  70. room.enter(state.world[dest], state);
  71. state.player.location = dest;
  72. refresh();
  73. }
  74. function updateRoom(state) {
  75. const name = state.player.location;
  76. const room = state.world[name];
  77. if (!state.player.rooms[room.id]) {
  78. state.player.rooms[room.id] = {};
  79. }
  80. const areaName = document.querySelector("#area-name");
  81. const areaDesc = document.querySelector("#area-desc");
  82. areaName.textContent = room.name;
  83. areaDesc.textContent = room.desc;
  84. const moveHolder = document.querySelector("#move-holder");
  85. moveHolder.innerHTML = "";
  86. Object.entries(dirs).forEach(([dir, name]) => {
  87. const button = document.createElement("button");
  88. button.classList.add("move-button")
  89. button.id = "move-" + dir;
  90. button.classList.add("disabled");
  91. button.setAttribute("disabled", "true");
  92. button.textContent = dirs[dir];
  93. moveHolder.appendChild(button);
  94. });
  95. if (room.exits) {
  96. Object.entries(room.exits).forEach(([dir, exit]) => {
  97. const button = document.querySelector("#move-" + dir);
  98. const dest = state.world[exit.target];
  99. // don't even show an exit if this fails!
  100. if (exit.show) {
  101. if (!exit.show.every(cond => cond(room, state))) {
  102. return;
  103. }
  104. }
  105. button.textContent = dest.name;
  106. // if any condition fails, don't enable/add a listener
  107. if (exit.conditions) {
  108. if (!exit.conditions.every(cond => cond(room,state))) {
  109. return;
  110. }
  111. }
  112. button.classList.remove("disabled");
  113. button.removeAttribute("disabled");
  114. button.addEventListener("click", () => {
  115. // todo: log
  116. moveToRoom(room, exit, exit.target, state);
  117. })
  118. });
  119. }
  120. const actionHolder = document.querySelector("#actions");
  121. actionHolder.innerHTML = "";
  122. if (room.actions) {
  123. room.actions.forEach(action => {
  124. const button = document.createElement("button");
  125. button.classList.add("action-button");
  126. if (action.show) {
  127. if (!action.show.every(cond => cond(room, state))) {
  128. return;
  129. }
  130. }
  131. button.textContent = action.name;
  132. actionHolder.appendChild(button);
  133. if (action.conditions) {
  134. if (!action.conditions.every(cond => cond(room, state))) {
  135. button.classList.add("disabled");
  136. button.setAttribute("disabled", "true");
  137. return;
  138. }
  139. }
  140. button.addEventListener("click", () => {
  141. action.execute(room, state);
  142. refresh();
  143. });
  144. button.addEventListener("mouseenter", () => {
  145. showActionDescription(action.desc);
  146. });
  147. button.addEventListener("mouseleave", () => {
  148. removeActionDescription();
  149. });
  150. });
  151. }
  152. }