Feast 2.0!
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.
 
 
 
 
 

233 lignes
5.2 KiB

  1. <template>
  2. <div class="explore-layout">
  3. <div class="explore-log">
  4. <div class="explore-log-filler"></div>
  5. </div>
  6. <div class="explore-worldinfo">
  7. <button @click="$emit('profile')">Show profile</button>
  8. <p class="worldinfo-date">{{ world.time.format("MMMM Do Y") }}</p>
  9. <p class="worldinfo-date">{{ world.time.format("hh:mm:ss a") }}</p>
  10. </div>
  11. <Statblock :subject="world.player" :initiative="0" />
  12. <div class="explore-containers">
  13. <ContainerView :container="container" v-for="(container, index) in world.player.containers" :key="'explore-container-' + index" />
  14. </div>
  15. <div class="explore-info">
  16. <h2 class="location-name">{{ location.name.capital }}</h2>
  17. <p class="location-desc">{{ location.desc }}</p>
  18. </div>
  19. <div class="explore-nav">
  20. <NavButton @click.native="writeLog(location.connections[direction].travel(world, world.player))" v-for="direction in Object.keys(location.connections)" :key="direction" :style="navBtnCss(direction)" :location="location" :direction="direction" />
  21. </div>
  22. <div class="explore-choices">
  23. <ChoiceButton @click.native="writeLog(choice.execute(world, world.player))" v-for="(choice, index) in location.choices.filter(choice => choice.visible(world))" :key="'choice' + index" :choice="choice" :world="world" />
  24. </div>
  25. </div>
  26. </template>
  27. <script lang="ts">
  28. import { Component, Prop, Vue } from 'vue-property-decorator'
  29. import { Direction, World, Place } from '@/game/world'
  30. import NavButton from './NavButton.vue'
  31. import ChoiceButton from './ChoiceButton.vue'
  32. import Statblock from './Statblock.vue'
  33. import ContainerView from './ContainerView.vue'
  34. import { LogEntry } from '@/game/interface'
  35. @Component({
  36. components: {
  37. NavButton, ChoiceButton, Statblock, ContainerView
  38. },
  39. data () {
  40. return {
  41. directions: Direction
  42. }
  43. }
  44. })
  45. export default class Explore extends Vue {
  46. get location () {
  47. return this.world.player.location
  48. }
  49. set location (loc: Place) {
  50. this.world.player.location = loc
  51. }
  52. @Prop({ type: World })
  53. world!: World
  54. navBtnCss (dir: Direction) {
  55. return {
  56. '--nav-direction': dir
  57. }
  58. }
  59. writeLog (entry: LogEntry) {
  60. const log = this.$el.querySelector(".explore-log")
  61. if (log !== null) {
  62. const rendered = entry.render()
  63. if (rendered.length > 0) {
  64. const holder = document.createElement("div")
  65. holder.classList.add("explore-log-entry")
  66. entry.render().forEach(element => {
  67. holder.appendChild(element)
  68. })
  69. holder.classList.add("explore-entry")
  70. const hline = document.createElement("div")
  71. hline.classList.add("explore-log-separator")
  72. log.appendChild(hline)
  73. log.appendChild(holder)
  74. log.scrollTo({ top: log.scrollHeight, left: 0, behavior: "smooth" })
  75. }
  76. }
  77. }
  78. }
  79. </script>
  80. <style scoped>
  81. .explore-layout {
  82. flex: 10;
  83. position: relative;
  84. display: grid;
  85. grid-template-areas: "info log log statblock"
  86. "info log log containers"
  87. "worldinfo log log containers"
  88. "nav nav choices containers ";
  89. grid-template-rows: fit-content(50%) 1fr 1fr 1fr;
  90. grid-template-columns: 1fr 1fr 1fr 1fr;
  91. width: 100%;
  92. height: 100%;
  93. max-width: 1500px;
  94. margin: auto;
  95. overflow: hidden;
  96. }
  97. .explore-containers {
  98. grid-area: containers;
  99. display: flex;
  100. flex-direction: row;
  101. flex-wrap: wrap;
  102. overflow-x: hidden;
  103. justify-content: flex-end;
  104. }
  105. .explore-containers > .vore-container {
  106. flex-basis: 25%;
  107. }
  108. .explore-log {
  109. grid-area: log;
  110. background: #222;
  111. overflow-y: scroll;
  112. padding: 8pt;
  113. }
  114. .explore-log-filler {
  115. height: 100%;
  116. }
  117. .explore-worldinfo {
  118. grid-area: worldinfo;
  119. background: #111;
  120. padding: 8px;
  121. }
  122. .worldinfo-date,
  123. .worldinfo-time {
  124. font-size: 1.25rem;
  125. }
  126. .explore-info {
  127. grid-area: info;
  128. background: #333;
  129. display: flex;
  130. flex-direction: column;
  131. flex-wrap: none;
  132. justify-content: start;
  133. align-items: center;
  134. padding: 8px;
  135. }
  136. .location-name {
  137. font-size: 2rem;
  138. margin: 8pt;
  139. }
  140. .location-desc {
  141. font-size: 1.5rem;
  142. color: #ccc;
  143. }
  144. .explore-nav {
  145. padding: 8px;
  146. position: relative;
  147. grid-area: nav;
  148. background: #444;
  149. display: grid;
  150. justify-content: center;
  151. align-content: center;
  152. grid-template-areas: "Northwest North Northeast"
  153. "West Center East "
  154. "Southwest South Southeast";
  155. grid-template-rows: 1fr 1fr 1fr;
  156. grid-template-columns: 1fr 1fr 1fr;
  157. width: calc(100% - 16px);
  158. height: calc(100% - 16px);
  159. justify-self: end;
  160. }
  161. .explore-choices {
  162. padding: 8px;
  163. grid-area: choices;
  164. background: #555;
  165. display: flex;
  166. flex-direction: column;
  167. overflow-y: scroll;
  168. }
  169. </style>
  170. <style>
  171. .explore-log-entry {
  172. animation: explore-entry-fade 1s;
  173. }
  174. @keyframes explore-entry-fade {
  175. from {
  176. opacity: 0;
  177. }
  178. to {
  179. opacity: 1
  180. }
  181. }
  182. .explore-log-separator {
  183. animation: explore-log-keyframes 0.5s;
  184. height: 4px;
  185. margin: 16pt auto 16pt;
  186. background: linear-gradient(90deg, transparent, #444 10%, #444 90%, transparent 100%);
  187. }
  188. @keyframes explore-log-keyframes {
  189. from {
  190. width: 0%;
  191. }
  192. to {
  193. width: 100%;
  194. }
  195. }
  196. .explore-log > div:last-child {
  197. margin-bottom: 8pt;
  198. }
  199. </style>