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.
 
 
 
 
 

184 wiersze
4.5 KiB

  1. <template>
  2. <div class="statblock">
  3. <h2 v-if="subject.perspective === firstperson">You</h2>
  4. <h2 v-if="subject.perspective !== firstperson">{{subject.name.all.capital}}</h2>
  5. <div class="stat-line vigors">
  6. <div :class="vigorClass(subject.vigors[vigor], subject.maxVigors[vigor])" v-for="vigor in Object.keys(subject.vigors)" v-bind:key="vigor">
  7. <i :class="vigorIcons[vigor]" />
  8. <div>{{subject.vigors[vigor]}}</div>
  9. <div class="tooltip-template">
  10. <div class="tooltip-title">{{ vigor }}</div>
  11. <div class="tooltip-body">{{ vigorDescs[vigor] }}</div>
  12. </div>
  13. </div>
  14. </div>
  15. <div class="stat-line stats">
  16. <div :class="statClass(subject.stats[stat], subject.baseStats[stat])" v-for="stat in Object.keys(subject.stats)" v-bind:key="stat">
  17. <i :class="statIcons[stat]" />
  18. <div>{{subject.stats[stat]}}</div>
  19. <div class="tooltip-template">
  20. <div class="tooltip-title">{{ stat }}</div>
  21. <div class="tooltip-body">{{ statDescs[stat] }}</div>
  22. </div>
  23. </div>
  24. </div>
  25. <div class="stat-line vore-stats">
  26. <div class="stat-entry" v-for="stat in Object.keys(subject.voreStats)" v-bind:key="stat">
  27. <i :class="voreStatIcons[stat]" />
  28. <div>{{subject.voreStats[stat]}}</div>
  29. <div class="tooltip-template">
  30. <div class="tooltip-title">{{ stat }}</div>
  31. <div class="tooltip-body">{{ voreStatDescs[stat] }}</div>
  32. </div>
  33. </div>
  34. </div>
  35. <div>Status: {{subject.status}}</div>
  36. <button @click="subject.perspective = firstperson">First-person</button>
  37. </div>
  38. </template>
  39. <script lang="ts">
  40. import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator'
  41. import { Creature, POV } from '@/game/entity'
  42. import { Stats, Stat, StatIcons, StatDescs, Vigor, VigorIcons, VigorDescs, VoreStatDescs, VoreStatIcons } from '@/game/combat'
  43. import ContainerView from './ContainerView.vue'
  44. import tippy, { createSingleton } from 'tippy.js'
  45. import 'tippy.js/dist/tippy.css'
  46. @Component({
  47. components: {
  48. ContainerView
  49. },
  50. methods: {
  51. vigorClass (value: number, max: number) {
  52. if (value * 5 <= max) {
  53. return 'stat-entry crit'
  54. } else if (value * 3 <= max) {
  55. return 'stat-entry low'
  56. } else {
  57. return 'stat-entry'
  58. }
  59. },
  60. statClass (value: number, normal: number) {
  61. if (value < normal) {
  62. return 'stat-entry crit'
  63. } else if (value > normal) {
  64. return 'stat-entry buff'
  65. } else {
  66. return 'stat-entry'
  67. }
  68. }
  69. }
  70. })
  71. export default class Statblock extends Vue {
  72. @Prop({ type: Creature, required: true })
  73. subject!: Creature
  74. private vigorIcons = VigorIcons
  75. private statIcons = StatIcons
  76. private voreStatIcons = VoreStatIcons
  77. private vigorDescs = VigorDescs
  78. private statDescs = StatDescs
  79. private voreStatDescs = VoreStatDescs
  80. private vigor = Vigor
  81. firstperson: POV = POV.First
  82. mounted () {
  83. const tippyInstances = Array.from(this.$el.querySelectorAll(".stat-entry")).map(elem => {
  84. const tooltip = elem.querySelector(".tooltip-template") as HTMLElement
  85. return tippy(elem, {
  86. content: tooltip
  87. })
  88. })
  89. createSingleton(tippyInstances, { delay: 500 })
  90. }
  91. }
  92. </script>
  93. <!-- Add "scoped" attribute to limit CSS to this component only -->
  94. <style scoped>
  95. h2 {
  96. margin-bottom: 8pt;
  97. font-size: 200%;
  98. }
  99. ul {
  100. list-style-type: none;
  101. padding: 0;
  102. }
  103. li {
  104. display: inline-block;
  105. margin: 0 10px;
  106. }
  107. a {
  108. color: #42b983;
  109. }
  110. .statblock {
  111. margin: 16px;
  112. user-select: none;
  113. }
  114. .stat-line {
  115. width: 100%;
  116. display: flex;
  117. justify-content: space-around;
  118. flex-wrap: wrap;
  119. }
  120. .stats,
  121. .vore-stats {
  122. display: none;
  123. }
  124. .stat-entry {
  125. position: relative;
  126. font-size: 16pt;
  127. padding-top: 4pt;
  128. padding-bottom: 4pt;
  129. display: flex;
  130. flex-direction: column;
  131. justify-content: space-evenly;
  132. user-select: none;
  133. }
  134. .stat-entry.low {
  135. color: yellow;
  136. }
  137. .stat-entry.crit {
  138. color: red;
  139. }
  140. .stat-entry.buff {
  141. color: green;
  142. }
  143. .statblock[data-active] {
  144. background: #444;
  145. border-radius: 4px;
  146. }
  147. .statblock[data-active] .stats,
  148. .statblock[data-active] .vore-stats {
  149. display: flex;
  150. }
  151. </style>
  152. <style>
  153. .left-stats .stat-entry::after {
  154. transform: translate(calc(0% + 16pt), -100%);
  155. }
  156. .left-stats .stat-entry::before {
  157. transform: translate(calc(0% + 16pt), calc(-100% + 18pt + 16pt));
  158. }
  159. .right-stats .stat-entry::after {
  160. transform: translate(calc(-100% + 16pt), -100%);
  161. }
  162. .right-stats .stat-entry::before {
  163. transform: translate(calc(-100% + 16pt), calc(-100% + 18pt + 16pt));
  164. }
  165. </style>