|  | import { DamageType, Damage, Combatant, Stats, Action, Vigor } from './combat'
import { Noun, Pronoun } from './language'
import { LogEntry, LogLine } from './interface'
import { Vore, Container, VoreType } from './vore'
export enum POV {First, Third}
export interface Entity {
    name: Noun;
    pronouns: Pronoun;
    perspective: POV;
}
export interface Mortal extends Entity {
  vigors: {[key in Vigor]: number};
  maxVigors: {[key in Vigor]: number};
  disabled: boolean;
  resistances: Map<DamageType, number>;
  takeDamage: (damage: Damage) => void;
  stats: Stats;
  status: string;
  destroy: () => LogEntry;
}
export class Creature extends Vore implements Combatant {
    vigors = {
      [Vigor.Health]: 100,
      [Vigor.Stamina]: 100,
      [Vigor.Willpower]: 100
    }
    maxVigors = {
      [Vigor.Health]: 100,
      [Vigor.Stamina]: 100,
      [Vigor.Willpower]: 100
    }
    get disabled (): boolean {
      return Object.values(this.vigors).some(val => val <= 0)
    }
    resistances: Map<DamageType, number> = new Map()
    perspective: POV = POV.Third
    containers: Array<Container> = []
    actions: Array<Action> = [];
    otherActions: Array<Action> = [];
    private baseBulk: number;
    get bulk (): number {
      return this.baseBulk + this.containers.reduce((total, conatiner) => { return total + conatiner.contents.reduce((total, prey) => total + prey.bulk, 0) }, 0)
    }
    containedIn: Container|null = null;
    constructor (public name: Noun, public pronouns: Pronoun, public stats: Stats, public preyPrefs: Set<VoreType>, public predPrefs: Set<VoreType>, bulk: number) {
      super()
      this.baseBulk = bulk
    }
    toString (): string {
      return this.name.toString()
    }
    takeDamage (damage: Damage): LogEntry {
      damage.damages.forEach(instance => {
        const resistance: number|undefined = this.resistances.get(instance.type)
        if (resistance !== undefined) {
          this.vigors[instance.target] -= instance.amount * resistance
        } else {
          this.vigors[instance.target] -= instance.amount
        }
      })
      if (this.vigors.Health <= -100) {
        return this.destroy()
      } else {
        return new LogLine()
      }
    }
    get status (): string {
      if (this.vigors[Vigor.Health] <= -100) {
        return "Dead"
      }
      if (this.vigors[Vigor.Stamina] <= -100) {
        return "Unconscious"
      }
      if (this.vigors[Vigor.Willpower] <= -100) {
        return "Broken"
      }
      if (this.vigors[Vigor.Health] <= 0) {
        return "Unconscious"
      }
      if (this.vigors[Vigor.Stamina] <= 0) {
        return "Exhausted"
      }
      if (this.vigors[Vigor.Willpower] <= 0) {
        return "Overpowered"
      }
      if (this.containedIn !== null) {
        return "Devoured"
      }
      return "Normal"
    }
    validActions (target: Creature): Array<Action> {
      let choices = this.actions.concat(this.containers.flatMap(container => container.actions)).concat(target.otherActions)
      if (this.containedIn !== null) {
        choices = choices.concat(this.containedIn.actions)
      }
      return choices.filter(action => {
        return action.allowed(this, target)
      })
    }
    destroy (): LogEntry {
      return super.destroy()
    }
}
 |