import { DamageType, Damage, Combatant, Stats, Action, Vigor } from './combat' import { Noun, Pronoun } from './language' import { Pred, Prey, 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}; resistances: Map; takeDamage: (damage: Damage) => void; stats: Stats; status: string; } export class Creature implements Mortal, Pred, Prey, Combatant { vigors = { [Vigor.Health]: 100, [Vigor.Stamina]: 100, [Vigor.Willpower]: 100 } maxVigors = { [Vigor.Health]: 100, [Vigor.Stamina]: 100, [Vigor.Willpower]: 100 } resistances: Map = new Map() perspective: POV = POV.Third containers: Array = [] actions: Array = []; private baseBulk: number; get bulk (): number { return this.baseBulk } containedIn: Container|null = null; constructor (public name: Noun, public pronouns: Pronoun, public stats: Stats, public preyPrefs: Set, public predPrefs: Set, bulk: number) { this.baseBulk = bulk } toString (): string { return this.name.toString() } takeDamage (damage: Damage): void { 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 } }) } get status (): string { if (this.vigors[Vigor.Health] < 0) { return "DEAD" } if (this.vigors[Vigor.Stamina] < 0) { return "Unconscious" } if (this.vigors[Vigor.Willpower] < 0) { return "Too horny" } if (this.containedIn !== null) { return "Devoured" } return "Normal" } validActions (target: Creature): Array { let choices = this.actions.concat(this.containers.flatMap(container => container.actions)) if (this.containedIn !== null) { choices = choices.concat(this.containedIn.actions) } return choices.filter(action => { return action.allowed(this, target) }) } }