Feast 2.0!
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 

185 строки
4.6 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. flex: 1 0;
  112. flex-basis: 100pt;
  113. margin: 0pt 4pt 0pt;
  114. user-select: none;
  115. }
  116. .stat-line {
  117. width: 100%;
  118. display: flex;
  119. justify-content: space-around;
  120. flex-wrap: wrap;
  121. }
  122. .stat-entry {
  123. position: relative;
  124. font-size: 10pt;
  125. padding-top: 4pt;
  126. padding-bottom: 4pt;
  127. display: flex;
  128. flex-direction: column;
  129. justify-content: space-evenly;
  130. user-select: none;
  131. }
  132. .stat-entry i {
  133. transform: translate(0, -40%) scale(1.6);
  134. }
  135. .stat-entry.low {
  136. color: yellow;
  137. }
  138. .stat-entry.crit {
  139. color: red;
  140. }
  141. .stat-entry.buff {
  142. color: green;
  143. }
  144. .statblock[data-active] {
  145. background: #444;
  146. border-radius: 4px;
  147. }
  148. .statblock[data-active] .stats,
  149. .statblock[data-active] .vore-stats {
  150. display: flex;
  151. }
  152. </style>
  153. <style>
  154. .left-stats .stat-entry::after {
  155. transform: translate(calc(0% + 16pt), -100%);
  156. }
  157. .left-stats .stat-entry::before {
  158. transform: translate(calc(0% + 16pt), calc(-100% + 18pt + 16pt));
  159. }
  160. .right-stats .stat-entry::after {
  161. transform: translate(calc(-100% + 16pt), -100%);
  162. }
  163. .right-stats .stat-entry::before {
  164. transform: translate(calc(-100% + 16pt), calc(-100% + 18pt + 16pt));
  165. }
  166. </style>