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.
 
 
 
 
 

307 wiersze
6.4 KiB

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