Feast 2.0!
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 

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