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.
 
 
 
 
 

151 lines
3.2 KiB

  1. import { Stat, Vigor } from './combat'
  2. export interface LogEntry {
  3. render: () => HTMLElement[];
  4. }
  5. export class LogLines implements LogEntry {
  6. lines: string[]
  7. constructor (...lines: string[]) {
  8. this.lines = lines
  9. }
  10. render (): HTMLElement[] {
  11. return this.lines.map(line => {
  12. const div = document.createElement("div")
  13. div.innerText = line
  14. return div
  15. })
  16. }
  17. }
  18. export enum FormatOpt {
  19. Damage = "log-damage",
  20. DamageInst = "damage-instance"
  21. }
  22. export class FormatEntry implements LogEntry {
  23. constructor (private entry: LogEntry, private opt: FormatOpt) {
  24. }
  25. render (): HTMLElement[] {
  26. const span = document.createElement("span")
  27. this.entry.render().forEach(elem => {
  28. span.appendChild(elem)
  29. })
  30. span.classList.add(this.opt)
  31. return [span]
  32. }
  33. }
  34. export class FormatText implements LogEntry {
  35. constructor (private opt: FormatOpt, private line: string) {
  36. }
  37. render (): HTMLElement[] {
  38. const span = document.createElement("span")
  39. span.innerText = this.line
  40. span.classList.add(this.opt)
  41. return [span]
  42. }
  43. }
  44. export class LogLine implements LogEntry {
  45. private parts: Array<string|LogEntry>
  46. constructor (...parts: Array<string|LogEntry>) {
  47. this.parts = parts
  48. }
  49. render (): HTMLElement[] {
  50. const div = document.createElement("span")
  51. this.parts.forEach(part => {
  52. if (typeof part === "string") {
  53. const partSpan = document.createElement("span")
  54. partSpan.innerText = part
  55. div.appendChild(partSpan)
  56. } else {
  57. (part as LogEntry).render().forEach(logPart => {
  58. div.appendChild(logPart)
  59. })
  60. }
  61. })
  62. return [div]
  63. }
  64. }
  65. export class FAElem implements LogEntry {
  66. constructor (private name: string) {
  67. }
  68. render (): HTMLElement[] {
  69. const i = document.createElement("i")
  70. this.name.split(" ").map(cls => i.classList.add(cls))
  71. return [i]
  72. }
  73. }
  74. export class PropElem implements LogEntry {
  75. constructor (private value: number, private prop: Stat | Vigor) {
  76. }
  77. render (): HTMLElement[] {
  78. let cls: string
  79. switch (this.prop) {
  80. case Vigor.Health: cls = "fas fa-heart"; break
  81. case Vigor.Stamina: cls = "fas fa-bolt"; break
  82. case Vigor.Resolve: cls = "fas fa-brain"; break
  83. case Stat.Toughness: cls = "fas fa-heartbeat"; break
  84. case Stat.Power: cls = "fas fa-fist-raised"; break
  85. case Stat.Speed: cls = "fas fa-weather"; break
  86. case Stat.Willpower: cls = "fas fa-book"; break
  87. case Stat.Charm: cls = "fas fa-comments"; break
  88. }
  89. const span = document.createElement("span")
  90. span.classList.add("stat-entry")
  91. span.textContent = this.value.toString()
  92. new FAElem(cls).render().forEach(elem => {
  93. span.appendChild(elem)
  94. })
  95. span.dataset.tooltip = this.prop
  96. span.dataset["tooltip-full"] = this.prop
  97. return [span]
  98. }
  99. }
  100. export class ImgElem implements LogEntry {
  101. constructor (private url: string) {
  102. }
  103. render (): HTMLElement[] {
  104. const img = document.createElement("img")
  105. img.src = this.url
  106. return [img]
  107. }
  108. }
  109. export class CompositeLog implements LogEntry {
  110. entries: LogEntry[]
  111. constructor (...entries: LogEntry[]) {
  112. this.entries = entries
  113. }
  114. render (): HTMLElement[] {
  115. return this.entries.flatMap(e => e.render())
  116. }
  117. }