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.
 
 
 
 
 

259 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(location.connections)" :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. "info log log containers"
  91. "worldinfo log log containers"
  92. "nav nav choices containers ";
  93. grid-template-rows: fit-content(50%) 1fr 1fr 1fr;
  94. grid-template-columns: 1fr 1fr 1fr 1fr;
  95. width: 100%;
  96. height: 100%;
  97. max-width: 1500px;
  98. margin: auto;
  99. overflow: hidden;
  100. }
  101. .explore-containers {
  102. grid-area: containers;
  103. display: flex;
  104. flex-direction: column;
  105. flex-wrap: wrap;
  106. overflow-x: hidden;
  107. }
  108. .explore-containers > .vore-container {
  109. flex-basis: 25%;
  110. max-height: 125px;
  111. }
  112. .explore-log {
  113. grid-area: log;
  114. background: #222;
  115. overflow-y: scroll;
  116. padding: 8pt;
  117. }
  118. .explore-log-filler {
  119. height: 100%;
  120. }
  121. .explore-worldinfo {
  122. grid-area: worldinfo;
  123. background: #111;
  124. padding: 8px;
  125. }
  126. .worldinfo-date,
  127. .worldinfo-time {
  128. font-size: 1.25rem;
  129. }
  130. .explore-statblock {
  131. grid-area: statblock;
  132. }
  133. .explore-info {
  134. grid-area: info;
  135. background: #333;
  136. display: flex;
  137. flex-direction: column;
  138. flex-wrap: none;
  139. justify-content: start;
  140. align-items: center;
  141. padding: 8px;
  142. }
  143. .location-name {
  144. font-size: 2rem;
  145. margin: 8pt;
  146. }
  147. .location-desc {
  148. font-size: 1.5rem;
  149. color: #ccc;
  150. }
  151. .explore-nav {
  152. padding: 8px;
  153. position: relative;
  154. grid-area: nav;
  155. background: #444;
  156. display: grid;
  157. justify-content: center;
  158. align-content: center;
  159. grid-template-areas: "Northwest North Northeast"
  160. "West Center East "
  161. "Southwest South Southeast";
  162. grid-template-rows: 1fr 1fr 1fr;
  163. grid-template-columns: 1fr 1fr 1fr;
  164. width: calc(100% - 16px);
  165. height: calc(100% - 16px);
  166. justify-self: end;
  167. }
  168. .explore-choices {
  169. padding: 8px;
  170. grid-area: choices;
  171. background: #555;
  172. display: flex;
  173. flex-direction: column;
  174. overflow-y: scroll;
  175. }
  176. .container-enter {
  177. opacity: 0;
  178. }
  179. .container-enter-active {
  180. transition: opacity 2s;
  181. }
  182. .container-move {
  183. transition: transform 1s;
  184. }
  185. .container-leave-active {
  186. transition: opacity 5s;
  187. opacity: 0;
  188. }
  189. </style>
  190. <style>
  191. .explore-log-entry {
  192. animation: explore-entry-fade 1s;
  193. }
  194. @keyframes explore-entry-fade {
  195. from {
  196. opacity: 0;
  197. }
  198. to {
  199. opacity: 1
  200. }
  201. }
  202. .explore-log-separator {
  203. animation: explore-log-keyframes 0.5s;
  204. height: 4px;
  205. margin: 16pt auto 16pt;
  206. background: linear-gradient(90deg, transparent, #444 10%, #444 90%, transparent 100%);
  207. }
  208. @keyframes explore-log-keyframes {
  209. from {
  210. width: 0%;
  211. }
  212. to {
  213. width: 100%;
  214. }
  215. }
  216. .explore-log > div:last-child {
  217. margin-bottom: 8pt;
  218. }
  219. </style>