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.
 
 
 
 
 

221 wiersze
5.0 KiB

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