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; 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 = new Map() perspective: POV = POV.Third containers: Array = [] actions: Array = []; otherActions: Array = []; 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, public predPrefs: Set, 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 { 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() } }