|
- import { Stat, Vigor, StatDescs, VigorDescs, StatIcons, VigorIcons, VoreStat, VoreStatIcons, VoreStatDescs } from './combat'
- import tippy from 'tippy.js'
-
- /**
- * A LogEntry is something that can produce zero or more HTMLElements
- */
- export interface LogEntry {
- render: () => HTMLElement[];
- }
-
- /**
- * Takes zero or more strings or [[LogEntry]] objects
- *
- * Produces a list of divs containing each string/object
- */
- export class LogLines implements LogEntry {
- private parts: Array<string|LogEntry>
-
- constructor (...parts: Array<string|LogEntry>) {
- this.parts = parts
- }
-
- render (): HTMLElement[] {
- const div = document.createElement("div")
-
- this.parts.forEach(part => {
- if (typeof part === "string") {
- const partDiv = document.createElement("div")
- partDiv.innerText = part
- div.appendChild(partDiv)
- } else {
- (part as LogEntry).render().forEach(logPart => {
- const partDiv = document.createElement("div")
- partDiv.appendChild(logPart)
- div.appendChild(partDiv)
- })
- }
- })
-
- return [div]
- }
- }
-
- export enum FormatOpt {
- Damage = "log-damage",
- DamageInst = "damage-instance"
- }
-
- /**
- * Wraps its LogEntry up in a span with the specified class
- */
- export class FormatEntry implements LogEntry {
- constructor (private entry: LogEntry, private opt: FormatOpt) {
-
- }
-
- render (): HTMLElement[] {
- const span = document.createElement("span")
-
- this.entry.render().forEach(elem => {
- span.appendChild(elem)
- })
-
- span.classList.add(this.opt)
-
- return [span]
- }
- }
-
- /**
- * Wraps a string up in a span with the specified class
- *
- * This will probably be folded into FormatEntry soon
- */
- export class FormatText implements LogEntry {
- constructor (private opt: FormatOpt, private line: string) {
-
- }
-
- render (): HTMLElement[] {
- const span = document.createElement("span")
- span.innerText = this.line
- span.classList.add(this.opt)
- return [span]
- }
- }
-
- /**
- * Like [[LogLines]], but with spans instead of divs
- */
- export class LogLine implements LogEntry {
- private parts: Array<string|LogEntry>
-
- constructor (...parts: Array<string|LogEntry>) {
- this.parts = parts
- }
-
- render (): HTMLElement[] {
- const div = document.createElement("span")
-
- this.parts.forEach(part => {
- if (typeof part === "string") {
- const partSpan = document.createElement("span")
- partSpan.innerText = part
- div.appendChild(partSpan)
- } else {
- (part as LogEntry).render().forEach(logPart => {
- div.appendChild(logPart)
- })
- }
- })
-
- return [div]
- }
- }
-
- export class Newline implements LogEntry {
- render (): HTMLElement[] {
- return [document.createElement("br")]
- }
- }
-
- /**
- * Produces a FontAwesome icon
- */
- export class FAElem implements LogEntry {
- constructor (private name: string) {
-
- }
-
- render (): HTMLElement[] {
- const i = document.createElement("i")
- this.name.split(" ").map(cls => i.classList.add(cls))
- return [i]
- }
- }
-
- /**
- * Produces a representation of a creature's property, such as health or power
- *
- * Can be just the icon, or include a number as well
- *
- * A tooltip is attached to the symbol
- */
- export class PropElem implements LogEntry {
- constructor (private prop: Stat | Vigor | VoreStat, private value: number|null = null) {
-
- }
-
- render (): HTMLElement[] {
- let cls: string
-
- if (this.prop in Stat) {
- cls = StatIcons[this.prop as Stat]
- } else if (this.prop in Vigor) {
- cls = VigorIcons[this.prop as Vigor]
- } else if (this.prop in Vigor) {
- cls = VoreStatIcons[this.prop as VoreStat]
- } else {
- // this shouldn't be possible, given the typing...
- cls = "fas fa-exclamation-triangle"
- }
-
- const span = document.createElement("span")
- span.classList.add("stat-entry")
-
- const tooltipTemplate = document.createElement("div")
- const tooltipTitle = document.createElement("div")
- tooltipTitle.classList.add("tooltip-title")
- const tooltipBody = document.createElement("div")
- tooltipBody.classList.add("tooltip-body")
-
- tooltipTemplate.appendChild(tooltipTitle)
- tooltipTemplate.appendChild(tooltipBody)
-
- tooltipTitle.textContent = this.prop
-
- if (this.prop in Stat) {
- tooltipBody.textContent = StatDescs[this.prop as Stat]
- } else if (this.prop in Vigor) {
- tooltipBody.textContent = VigorDescs[this.prop as Vigor]
- } else if (this.prop in VoreStat) {
- tooltipBody.textContent = VoreStatDescs[this.prop as VoreStat]
- }
-
- if (this.value !== null) {
- const numText = Math.round(this.value).toFixed(0) === this.value.toFixed(0) ? this.value.toFixed(0) : this.value.toFixed(1)
- span.textContent = numText + ' '
- }
-
- const icon = new FAElem(cls).render()[0]
-
- span.appendChild(icon)
-
- tippy(icon, {
- content: tooltipTemplate
- })
- return [span]
- }
- }
-
- /**
- * Produces an <img>
- */
- export class ImgElem implements LogEntry {
- constructor (private url: string) {
-
- }
-
- render (): HTMLElement[] {
- const div = document.createElement("div")
- const img = document.createElement("img")
- img.src = this.url
- div.appendChild(img)
- return [div]
- }
- }
-
- /**
- * Directly concatenates zero or more [[LogEntry]] objects, without wrapping them in anything
- */
- export class CompositeLog implements LogEntry {
- entries: LogEntry[]
-
- constructor (...entries: LogEntry[]) {
- this.entries = entries
- }
-
- render (): HTMLElement[] {
- return this.entries.flatMap(e => e.render())
- }
- }
|