|
- import { Entity, Mortal, POV } from './entity'
- import { Damage, Actionable, Action, DevourAction, DigestAction, ReleaseAction, StruggleAction } from './combat'
- import { LogLines, LogEntry, CompositeLog } from './interface'
- import { POVSolo, POVPair, POVPairArgs } from './language'
-
- export enum VoreType {
- Oral = "Oral Vore",
- Anal = "Anal Vore",
- Cock = "Cock Vore",
- Unbirth = "Unbirthing"
- }
-
- export interface Prey extends Mortal {
- preyPrefs: Set<VoreType>;
- bulk: number;
- containedIn: Container | null;
- }
-
- export interface Pred extends Entity {
- predPrefs: Set<VoreType>;
- containers: Array<Container>;
- }
-
- export interface Container extends Actionable {
- name: string;
- owner: Pred;
- voreTypes: Set<VoreType>;
- contents: Array<Prey>;
- capacity: number;
- fullness: number;
- canTake: (prey: Prey) => boolean;
- consume: (prey: Prey) => LogEntry;
- release: (prey: Prey) => LogEntry;
- struggle: (prey: Prey) => LogEntry;
- tick: (dt: number) => LogEntry;
- describe: () => LogEntry;
- digest: (prey: Prey) => LogEntry;
- absorb: (prey: Prey) => LogEntry;
- dispose: (preys: Prey[]) => LogEntry;
- actions: Array<Action>;
- }
-
- abstract class NormalContainer implements Container {
- contents: Array<Prey>
-
- abstract consumeLines: POVPair<Pred, Prey>
- abstract releaseLines: POVPair<Pred, Prey>
- abstract struggleLines: POVPair<Prey, Pred>
- abstract tickLines: POVSolo<Pred>
- abstract digestLines: POVPair<Pred, Prey>
- abstract absorbLines: POVPair<Pred, Prey>
- abstract disposeLines: POVPair<Pred, Prey>
-
- get fullness (): number {
- return Array.from(this.contents.values()).reduce((total: number, prey: Prey) => total + prey.bulk, 0)
- }
-
- canTake (prey: Prey): boolean {
- const fits = this.capacity - this.fullness >= prey.bulk
-
- const permitted = Array.from(this.voreTypes).every(voreType => {
- return prey.preyPrefs.has(voreType)
- })
-
- return fits && permitted
- }
-
- consume (prey: Prey): LogEntry {
- this.contents.push(prey)
- prey.containedIn = this
- return this.consumeLines.run(this.owner, prey)
- }
-
- release (prey: Prey): LogEntry {
- prey.containedIn = null
- this.contents = this.contents.filter(victim => victim !== prey)
- return this.releaseLines.run(this.owner, prey)
- }
-
- struggle (prey: Prey): LogEntry {
- return this.struggleLines.run(prey, this.owner)
- }
-
- tick (dt: number): LogEntry {
- const digested: Array<Prey> = []
- const absorbed: Array<Prey> = []
-
- this.contents.forEach(prey => {
- const start = prey.health
- prey.takeDamage(this.damage.scale(dt / 3600))
- const end = prey.health
- if (start > 0 && end <= 0) {
- digested.push(prey)
- } else if (start > -100 && end <= -100) {
- absorbed.push(prey)
- }
- })
-
- const digestedEntries = new CompositeLog(...digested.map(prey => this.digest(prey)))
- const absorbedEntries = new CompositeLog(...digested.map(prey => this.absorb(prey)))
-
- this.contents = this.contents.filter(prey => {
- return prey.health > -100
- })
-
- return new CompositeLog(this.tickLines.run(this.owner), digestedEntries, absorbedEntries)
- }
-
- describe (): LogEntry {
- const lines: Array<string> = []
-
- this.contents.forEach(prey => {
- lines.push(prey.toString())
- })
-
- return new LogLines(...lines)
- }
-
- digest (prey: Prey): LogEntry {
- return this.digestLines.run(this.owner, prey)
- }
-
- absorb (prey: Prey): LogEntry {
- return this.absorbLines.run(this.owner, prey)
- }
-
- dispose (preys: Prey[]): LogEntry {
- return new CompositeLog(...preys.map(prey => this.disposeLines.run(this.owner, prey)))
- }
-
- actions: Array<Action>
-
- constructor (public name: string, public owner: Pred, public voreTypes: Set<VoreType>, public capacity: number, private damage: Damage) {
- this.contents = []
-
- this.actions = []
-
- this.actions.push(new DevourAction(this))
- this.actions.push(new DigestAction(this))
- this.actions.push(new ReleaseAction(this))
- this.actions.push(new StruggleAction(this))
- }
- }
-
- export class Stomach extends NormalContainer {
- constructor (owner: Pred, capacity: number, damage: Damage) {
- super('Stomach', owner, new Set([VoreType.Oral]), capacity, damage)
- }
-
- consumeLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`You devour ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} munches you`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} munches ${target.name.capital}`)]
- ])
-
- releaseLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`You hork up ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} horks you up`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} horks up ${target.name.capital}`)]
- ])
-
- struggleLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`You claw your way out of ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} forces ${user.pronouns.possessive} way up your throat!`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} escapes from the gut of ${target.name}`)]
- ])
-
- tickLines = new POVSolo([
- [[POV.First], (user) => new LogLines(`Your stomach gurgles and churns`)],
- [[POV.Third], (user) => new LogLines(`${user.name.capital}'s gut snarls and gurgles`)]
- ])
-
- digestLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`Your stomach overwhelms ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s stomach finishes you off`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name.capital}'s squirms fade, overwhelmed by the stomach of ${user.name}`)]
- ])
-
- absorbLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`Your guts completely absorb ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s guts soak you up like water in a sponge`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} finishes absorbing the remains of ${target.name}`)]
- ])
-
- disposeLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`Your guts completely absorb ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s guts soak you up like water in a sponge`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} finishes absorbing the remains of ${target.name}`)]
- ])
- }
-
- export class Bowels extends NormalContainer {
- constructor (owner: Pred, capacity: number, damage: Damage) {
- super('Bowels', owner, new Set([VoreType.Anal]), capacity, damage)
- }
-
- consumeLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`You devour ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} munches you`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} munches ${target.name.capital}`)]
- ])
-
- releaseLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`You hork up ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} horks you up`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} horks up ${target.name.capital}`)]
- ])
-
- struggleLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`You claw your way out of ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} forces ${user.pronouns.possessive} way up your throat!`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} escapes from the gut of ${target.name}`)]
- ])
-
- tickLines = new POVSolo([
- [[POV.First], (user) => new LogLines(`Your stomach gurgles and churns!`)],
- [[POV.Third], (user) => new LogLines(`${user.name.capital}'s gut snarls and gurgles`)]
- ])
-
- digestLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`Your stomach overwhelms ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s stomach finishes you off`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name.capital}'s squirms fade, overwhelmed by the stomach of ${user.name}`)]
- ])
-
- absorbLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`Your guts completely absorb ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s guts soak you up like water in a sponge`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} finishes absorbing the remains of ${target.name}`)]
- ])
-
- disposeLines = new POVPair([
- [[POV.First, POV.Third], (user, target) => new LogLines(`Your guts completely absorb ${target.name}`)],
- [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s guts soak you up like water in a sponge`)],
- [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} finishes absorbing the remains of ${target.name}`)]
- ])
- }
|