Feast 2.0!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

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