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.
 
 
 
 
 

273 lines
5.6 KiB

  1. <template>
  2. <div class="combat-layout">
  3. <div class="left-selector">
  4. <button @click="left = combatant" v-for="(combatant, index) in combatants.filter(c => c !== right && c !== left)" :key="'left' + index">
  5. {{ combatant.name }}
  6. </button>
  7. </div>
  8. <div class="right-selector">
  9. <button @click="right = combatant" v-for="(combatant, index) in combatants.filter(c => c !== left && c !== right)" :key="'right' + index">
  10. {{ combatant.name }}
  11. </button>
  12. </div>
  13. <Statblock class="left-stats" :subject="left" />
  14. <Statblock class="right-stats" :subject="right" />
  15. <div id="log">
  16. </div>
  17. <div class="left-actions">
  18. <h2>Your moves</h2>
  19. <div class="vert-display">
  20. <ActionButton @executed="executedLeft" v-for="action in left.validActions(right)" :key="'left' + action.name" :action="action" :user="left" :target="right" />
  21. <ActionButton @executed="executedLeft" v-for="action in left.validActions(left)" :key="'left' + action.name" :action="action" :user="left" :target="right" />
  22. </div>
  23. <div>{{actionDescription}}</div>
  24. </div>
  25. <div class="right-actions">
  26. <h2>Enemy moves</h2>
  27. <div class="vert-display">
  28. <ActionButton @executed="executedRight" v-for="action in right.validActions(left)" :key="'right' + action.name" :action="action" :user="right" :target="left" />
  29. <ActionButton @executed="executedRight" v-for="action in right.validActions(right)" :key="'right' + action.name" :action="action" :user="right" :target="left" />
  30. </div>
  31. </div>
  32. </div>
  33. </template>
  34. <script lang="ts">
  35. import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator'
  36. import { Creature, POV } from '@/game/entity'
  37. import { LogEntry } from '@/game/interface'
  38. import Statblock from './Statblock.vue'
  39. import ActionButton from './ActionButton.vue'
  40. @Component(
  41. {
  42. components: { Statblock, ActionButton }
  43. }
  44. )
  45. export default class Combat extends Vue {
  46. @Prop({ type: Creature, required: true })
  47. left!: Creature
  48. @Prop({ type: Creature, required: true })
  49. right!: Creature
  50. @Prop()
  51. combatants!: Array<Creature>
  52. actionDescription = ''
  53. constructor () {
  54. super()
  55. }
  56. @Emit("executedLeft")
  57. executedLeft (entry: LogEntry) {
  58. const log = document.querySelector("#log")
  59. if (log !== null) {
  60. const holder = document.createElement("div")
  61. entry.render().forEach(element => {
  62. holder.appendChild(element)
  63. })
  64. holder.classList.add("left-move")
  65. log.appendChild(holder)
  66. log.scrollTo({ top: 10000000000, left: 0 })
  67. }
  68. }
  69. @Emit("executedRight")
  70. executedRight (entry: LogEntry) {
  71. const log = document.querySelector("#log")
  72. if (log !== null) {
  73. const holder = document.createElement("div")
  74. entry.render().forEach(element => {
  75. holder.appendChild(element)
  76. })
  77. holder.classList.add("right-move")
  78. log.appendChild(holder)
  79. log.scrollTo({ top: 10000000000, left: 0 })
  80. }
  81. }
  82. }
  83. </script>
  84. <!-- Add "scoped" attribute to limit CSS to this component only -->
  85. <style scoped>
  86. .combat-layout {
  87. display: grid;
  88. grid-template-rows: 10% 20% [main-row-start] 1fr 1fr [main-row-end] 20%;
  89. grid-template-columns: minmax(80pt, 20%) [main-col-start] 1fr [main-col-end] minmax(80pt, 20%);
  90. width: 100%;
  91. height: 100%;
  92. flex: 10;
  93. }
  94. .left-stats {
  95. grid-area: 2 / 1 / 3 / 2
  96. }
  97. .right-stats {
  98. grid-area: 2 / 3 / 3 / 4;
  99. }
  100. #log {
  101. grid-area: main-row-start / main-col-start / main-row-end / main-col-end;
  102. overflow-y: auto;
  103. font-size: 16pt;
  104. width: 100%;
  105. max-height: 100%;
  106. align-self: end;
  107. }
  108. .left-selector {
  109. grid-area: 1 / 1 / 2 / 2;
  110. }
  111. .right-selector {
  112. grid-area: 1 / 3 / 2 / 4;
  113. }
  114. .left-actions {
  115. grid-area: 4 / 1 / 5 / 2;
  116. }
  117. .right-actions {
  118. grid-area: 4 / 3 / 5 / 4;
  119. }
  120. h3 {
  121. margin: 40px 0 0;
  122. }
  123. ul {
  124. list-style-type: none;
  125. padding: 0;
  126. }
  127. li {
  128. display: inline-block;
  129. margin: 0 10px;
  130. }
  131. a {
  132. color: #42b983;
  133. }
  134. .horiz-display {
  135. display: flex;
  136. justify-content: center;
  137. }
  138. .vert-display {
  139. display: flex;
  140. flex-direction: column;
  141. align-items: center;
  142. flex-wrap: wrap;
  143. }
  144. </style>
  145. <style>
  146. .log-damage {
  147. font-weight: bold;
  148. }
  149. .damage-instance {
  150. white-space: nowrap;
  151. }
  152. #log > div {
  153. color: #888;
  154. padding-top: 4pt;
  155. padding-bottom: 4pt;
  156. }
  157. div.left-move,
  158. div.right-move {
  159. color: #888;
  160. }
  161. div.left-move {
  162. text-align: start;
  163. margin-right: 25%;
  164. margin-left: 5%;
  165. }
  166. div.right-move {
  167. text-align: end;
  168. margin-left: 25%;
  169. margin-right: 5%;
  170. }
  171. #log img {
  172. width: 75%;
  173. }
  174. #log > div.left-move:nth-last-child(7) {
  175. padding-top: 8pt;
  176. color: #988;
  177. }
  178. #log > div.left-move:nth-last-child(6) {
  179. padding-top: 12pt;
  180. color: #a88;
  181. }
  182. #log > div.left-move:nth-last-child(5) {
  183. padding-top: 16pt;
  184. color: #b88;
  185. }
  186. #log > div.left-move:nth-last-child(4) {
  187. padding-top: 20pt;
  188. color: #c88;
  189. }
  190. #log > div.left-move:nth-last-child(3) {
  191. padding-top: 24pt;
  192. color: #d88;
  193. }
  194. #log > div.left-move:nth-last-child(2) {
  195. padding-top: 28pt;
  196. color: #e88;
  197. }
  198. #log > div.left-move:nth-last-child(1) {
  199. padding-top: 32pt;
  200. color: #f88;
  201. }
  202. #log > div.right-move:nth-last-child(7) {
  203. padding-top: 8pt;
  204. color: #988;
  205. }
  206. #log > div.right-move:nth-last-child(6) {
  207. padding-top: 12pt;
  208. color: #a88;
  209. }
  210. #log > div.right-move:nth-last-child(5) {
  211. padding-top: 16pt;
  212. color: #b88;
  213. }
  214. #log > div.right-move:nth-last-child(4) {
  215. padding-top: 20pt;
  216. color: #c88;
  217. }
  218. #log > div.right-move:nth-last-child(3) {
  219. padding-top: 24pt;
  220. color: #d88;
  221. }
  222. #log > div.right-move:nth-last-child(2) {
  223. padding-top: 28pt;
  224. color: #e88;
  225. }
  226. #log > div.right-move:nth-last-child(1) {
  227. padding-top: 32pt;
  228. color: #f88;
  229. }
  230. </style>