From 8b0dc8add4998f190397d0f9369e8eb3fdcb4ffa Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sun, 12 Jul 2020 16:28:30 -0400 Subject: [PATCH] Work on vore mechanics; add Cafat --- .gitattributes | 1 + public/media/cafat/images/belch.webp | 3 + public/media/cafat/images/crunch.webp | 3 + public/media/cafat/images/lower-stomach.webp | 3 + public/media/cafat/images/stomach.webp | 3 + src/App.vue | 6 +- src/components/Combat.vue | 4 + src/components/Statblock.vue | 2 +- src/game/combat.ts | 44 +++++--- src/game/creatures.ts | 3 +- src/game/creatures/cafat.ts | 103 +++++++++++++++++++ src/game/feast.ts | 16 --- src/game/interface.ts | 12 +++ src/game/language.ts | 23 +++++ src/game/vore.ts | 79 ++++++++++++-- 15 files changed, 263 insertions(+), 42 deletions(-) create mode 100644 .gitattributes create mode 100644 public/media/cafat/images/belch.webp create mode 100644 public/media/cafat/images/crunch.webp create mode 100644 public/media/cafat/images/lower-stomach.webp create mode 100644 public/media/cafat/images/stomach.webp create mode 100644 src/game/creatures/cafat.ts delete mode 100644 src/game/feast.ts diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..0a3d8c2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.webp filter=lfs diff=lfs merge=lfs -text diff --git a/public/media/cafat/images/belch.webp b/public/media/cafat/images/belch.webp new file mode 100644 index 0000000..171619c --- /dev/null +++ b/public/media/cafat/images/belch.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f33bba6327c0a75e40d3e67a1c757421acde2d826ce3de05f397ab4c80fd039 +size 39712 diff --git a/public/media/cafat/images/crunch.webp b/public/media/cafat/images/crunch.webp new file mode 100644 index 0000000..3a40e45 --- /dev/null +++ b/public/media/cafat/images/crunch.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9af601f92ecf19fbef987599e4fbba7162be7fe24cc1fa809ca1d8dbb57091b8 +size 43650 diff --git a/public/media/cafat/images/lower-stomach.webp b/public/media/cafat/images/lower-stomach.webp new file mode 100644 index 0000000..207f179 --- /dev/null +++ b/public/media/cafat/images/lower-stomach.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e29868efd8a6fb854ab3a3c0381dcdd1f9677e7f446183e4f9b4360cc997bbca +size 26554 diff --git a/public/media/cafat/images/stomach.webp b/public/media/cafat/images/stomach.webp new file mode 100644 index 0000000..8ab036b --- /dev/null +++ b/public/media/cafat/images/stomach.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc9e319a2319b4ae676650a4cec84ceb5a70a76ebe92c222f6d0722aff9a6214 +size 29310 diff --git a/src/App.vue b/src/App.vue index c48d866..e1ef10b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -11,6 +11,7 @@ import Combat from './components/Combat.vue' import Header from './components/Header.vue' import * as Creatures from '@/game/creatures' import { Creature, POV } from '@/game/entity' +import { ProperNoun } from '@/game/language' @Component({ components: { @@ -22,8 +23,9 @@ export default class App extends Vue { enemy: Creature constructor () { super() - this.player = new Creatures.Player() - this.enemy = new Creatures.Wolf() + this.player = new Creatures.Wolf() + this.enemy = new Creatures.Cafat() + this.player.perspective = POV.First console.log(this.player) console.log(this.enemy) } diff --git a/src/components/Combat.vue b/src/components/Combat.vue index 29e7cfe..853f8f8 100644 --- a/src/components/Combat.vue +++ b/src/components/Combat.vue @@ -174,6 +174,10 @@ div.enemy-move { margin-right: 5%; } +#log img { + width: 75%; +} + #log > div.enemy-move:nth-last-child(7) { color: #988; } diff --git a/src/components/Statblock.vue b/src/components/Statblock.vue index 3b81ee4..f5bbb0e 100644 --- a/src/components/Statblock.vue +++ b/src/components/Statblock.vue @@ -8,7 +8,7 @@
: {{subject.stats[stat]}}
Status: {{subject.status}}
- + diff --git a/src/game/combat.ts b/src/game/combat.ts index d8c0bb9..f01979c 100644 --- a/src/game/combat.ts +++ b/src/game/combat.ts @@ -1,5 +1,5 @@ import { Creature, POV, Entity } from './entity' -import { POVPair, POVPairArgs } from './language' +import { POVPair, POVPairArgs, TextLike, DynText, LiveText } from './language' import { Container } from './vore' import { LogEntry, LogLines, CompositeLog, FAElem, LogLine, FormatEntry, FormatOpt } from './interface' @@ -213,12 +213,12 @@ export abstract class Action { abstract execute(user: Creature, target: Creature): LogEntry - constructor (public name: string, public desc: string, private conditions: Array = []) { + constructor (public name: TextLike, public desc: string, private conditions: Array = []) { } toString (): string { - return this.name + return this.name.toString() } } @@ -306,7 +306,7 @@ export class AttackAction extends TogetherAction { protected failLines: POVPair = new POVPair([ [[POV.First, POV.Third], (user, target) => new LogLines(`You try to smack ${target.name}, but you miss`)], [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} misses you`)], - [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name} misses ${target.name}`)] + [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} misses ${target.name}`)] ]) constructor (protected damage: Damage) { @@ -330,7 +330,7 @@ export class DevourAction extends TogetherAction { protected failLines: POVPair = new POVPair([ [[POV.First, POV.Third], (user, target) => new LogLines(`You fail to make a meal out of ${target.name}`)], [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} tries to devour you, but fails`)], - [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name} unsuccessfully tries to swallow ${target.name}`)] + [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} unsuccessfully tries to swallow ${target.name}`)] ]) allowed (user: Creature, target: Creature): boolean { @@ -346,8 +346,7 @@ export class DevourAction extends TogetherAction { } constructor (protected container: Container) { - super('Devour', 'Try to consume your foe', [new CapableCondition()]) - this.name += ` (${container.name})` + super(new DynText('Devour (', new LiveText(container, x => x.name.all), ')'), 'Try to consume your foe', [new CapableCondition()]) this.test = new StatVigorTest(Stat.STR) } @@ -366,7 +365,7 @@ export class FeedAction extends TogetherAction { protected failLines: POVPair = new POVPair([ [[POV.First, POV.Third], (user, target) => new LogLines(`You fail to feed yourself to ${target.name}`)], [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} tries to feed ${user.pronouns.possessive} to you, but fails`)], - [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name} unsuccessfully tries to feed ${user.pronouns.possessive} to ${target.name}`)] + [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} unsuccessfully tries to feed ${user.pronouns.possessive} to ${target.name}`)] ]) allowed (user: Creature, target: Creature): boolean { @@ -402,7 +401,7 @@ export class StruggleAction extends PairAction { protected failLines: POVPair = new POVPair([ [[POV.First, POV.Third], (user, target) => new LogLines(`You fail to escape from ${target.name}`)], [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} tries to escape from you, but fails`)], - [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name} unsuccessfully struggles within ${target.name}`)] + [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} unsuccessfully struggles within ${target.name}`)] ]) allowed (user: Creature, target: Creature) { @@ -414,7 +413,7 @@ export class StruggleAction extends PairAction { } constructor (public container: Container) { - super('Struggle', 'Try to escape your predator', [new CapableCondition()]) + super(new DynText('Struggle (', new LiveText(container, x => x.name.all), ')'), 'Try to escape from your foe', [new CapableCondition()]) this.test = new StatVigorTest(Stat.STR) } @@ -431,6 +430,21 @@ export class StruggleAction extends PairAction { } } +export abstract class EatenAction extends PairAction { + protected lines: POVPair = new POVPair([]) + + allowed (user: Creature, target: Creature) { + if (target.containedIn === this.container) { + return super.allowed(user, target) + } else { + return false + } + } + + constructor (public container: Container, name: TextLike, desc: string) { + super(new DynText(name, ' (', new LiveText(container, x => x.name.all), ')'), 'Do something to your prey!', [new CapableCondition()]) + } +} export class DigestAction extends SelfAction { protected lines: POVPair = new POVPair([]) @@ -443,8 +457,7 @@ export class DigestAction extends SelfAction { } constructor (protected container: Container) { - super('Digest', 'Digest all of your current prey', [new CapableCondition()]) - this.name += ` (${container.name})` + super(new DynText('Digest (', new LiveText(container, container => container.name.all), ')'), 'Digest your prey', [new CapableCondition()]) } execute (user: Creature, target: Creature): LogEntry { @@ -463,8 +476,7 @@ export class ReleaseAction extends PairAction { } constructor (protected container: Container) { - super('Release', 'Release one of your prey') - this.name += ` (${container.name})` + super(new DynText('Release (', new LiveText(container, x => x.name.all), ')'), 'Release one of your prey', [new CapableCondition()]) } execute (user: Creature, target: Creature): LogEntry { @@ -473,9 +485,9 @@ export class ReleaseAction extends PairAction { } export class TransferAction extends PairAction { - protected lines: POVPairArgs = new POVPairArgs([ + lines: POVPairArgs = new POVPairArgs([ [[POV.First, POV.Third], (user, target, args) => new LogLine(`You squeeze ${target.name} from your ${args.from.name} to your ${args.to.name}`)], - [[POV.Third, POV.First], (user, target, args) => new LogLine(`You're squeezed from ${user.name}'s ${args.from.name} to ${target.pronouns.possessive} ${args.to.name}`)], + [[POV.Third, POV.First], (user, target, args) => new LogLine(`You're squeezed from ${user.name}'s ${args.from.name} to ${user.pronouns.possessive} ${args.to.name}`)], [[POV.Third, POV.Third], (user, target, args) => new LogLine(`${user.name} squeezes ${target.name} from ${user.pronouns.possessive} ${args.from.name} to ${user.pronouns.possessive} ${args.to.name}`)] ]) diff --git a/src/game/creatures.ts b/src/game/creatures.ts index fd240f2..8694fb0 100644 --- a/src/game/creatures.ts +++ b/src/game/creatures.ts @@ -1,4 +1,5 @@ import { Wolf } from './creatures/wolf' import { Player } from './creatures/player' +import { Cafat } from './creatures/cafat' -export { Wolf, Player } +export { Wolf, Player, Cafat } diff --git a/src/game/creatures/cafat.ts b/src/game/creatures/cafat.ts new file mode 100644 index 0000000..dd33e19 --- /dev/null +++ b/src/game/creatures/cafat.ts @@ -0,0 +1,103 @@ +import { Creature, POV, Entity } from '../entity' +import { Stat, Damage, DamageType, TransferAction, Vigor, StatTest, FeedAction, DigestAction, EatenAction, AttackAction } from '../combat' +import { ProperNoun, TheyPronouns, ImproperNoun, POVPair, FemalePronouns, POVPairArgs } from '../language' +import { VoreType, Stomach, InnerStomach, Container } from '../vore' +import { LogLine, LogLines, LogEntry, FAElem, CompositeLog, ImgElem } from '../interface' + +class BelchAction extends AttackAction { + successLines = new POVPairArgs([ + [[POV.First, POV.Third], (user, target, args) => new CompositeLog(new LogLine( + `You belch on ${target.name} for `, + args.damage.renderShort() + ), new ImgElem('./media/cafat/images/belch.webp'))], + [[POV.Third, POV.First], (user, target, args) => new CompositeLog(new LogLine( + `${user.name.capital} belches on you for `, + args.damage.renderShort() + ), new ImgElem('./media/cafat/images/belch.webp'))], + [[POV.Third, POV.Third], (user, target, args) => new CompositeLog(new LogLine( + `${user.name.capital} belches on ${target.name} for `, + args.damage.renderShort() + ), new ImgElem('./media/cafat/images/belch.webp'))] + ]) + + constructor (damage: Damage) { + super(damage) + this.name = 'Belch' + } +} +class CrushAction extends EatenAction { + lines: POVPair = new POVPair([ + [[POV.First, POV.Third], (user, target) => new LogLine(`You crush ${target.name} `, new FAElem('fas fa-skull'))], + [[POV.Third, POV.First], (user, target) => new CompositeLog(new LogLine(`${user.name.capital} crushes you; ${user.pronouns.subjective} belches as ${user.pronouns.possessive} gut lets out a fatal CRUNCH `, new FAElem('fas fa-skull')), new ImgElem('./media/cafat/images/crunch.webp'))], + [[POV.Third, POV.Third], (user, target) => new LogLine(`${user.name.capital} crushes ${target.name}; ${user.pronouns.subjective} belches as ${user.pronouns.possessive} gut lets out a fatal CRUNCH `, new FAElem('fas fa-skull'))] + ]) + + private damage: Damage = new Damage( + { amount: 99, type: DamageType.Crush, target: Vigor.Health } + ) + + constructor (container: Container) { + super(container, "Crush", "Crush 'em!") + } + + execute (user: Creature, target: Creature): LogEntry { + target.takeDamage(this.damage) + return this.lines.run(user, target) + } +} + +export class Cafat extends Creature { + constructor () { + super(new ProperNoun('Cafat'), [TheyPronouns, FemalePronouns][Math.floor(Math.random() * 2)], { [Stat.STR]: 30, [Stat.DEX]: 15, [Stat.CON]: 25 }, new Set([VoreType.Oral, VoreType.Anal]), new Set([VoreType.Oral, VoreType.Anal]), 150) + + this.vigors.Health = 200 + this.maxVigors.Health = 200 + this.vigors.Stamina = 250 + this.maxVigors.Stamina = 250 + this.vigors.Willpower = 150 + this.maxVigors.Willpower = 150 + + const stomach = new Stomach(this, 100, new Damage( + { amount: 20, type: DamageType.Acid, target: Vigor.Health }, + { amount: 10, type: DamageType.Crush, target: Vigor.Stamina }, + { amount: 10, type: DamageType.Dominance, target: Vigor.Willpower } + )) + + stomach.name = new ImproperNoun("upper stomach", "upper stomachs").all + + this.containers.push(stomach) + + const lowerStomach = new InnerStomach(this, 100, new Damage( + { amount: 40, type: DamageType.Acid, target: Vigor.Health }, + { amount: 20, type: DamageType.Crush, target: Vigor.Stamina }, + { amount: 20, type: DamageType.Dominance, target: Vigor.Willpower } + ), stomach) + + lowerStomach.name = new ImproperNoun("lower stomach", "lower stomachs").all + + stomach.consumeLines = new POVPair([ + [[POV.First, POV.Third], (user, target) => new LogLines(`You devour ${target.name}`)], + [[POV.Third, POV.First], (user, target) => new CompositeLog(new LogLines(`${user.name.capital} devours you`), new ImgElem('./media/cafat/images/stomach.webp'))], + [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} munches ${target.name.capital}`)] + ]) + const crush = new CrushAction(lowerStomach) + + lowerStomach.actions.push(crush) + this.containers.push(lowerStomach) + + const transfer = new TransferAction(stomach, lowerStomach) + + transfer.lines = new POVPairArgs([ + [[POV.First, POV.Third], (user, target, args) => new LogLine(`You squeeze ${target.name} from your ${args.from.name} to your ${args.to.name}`)], + [[POV.Third, POV.First], (user, target, args) => new CompositeLog(new LogLine(`You're squeezed from ${user.name}'s ${args.from.name} to ${user.pronouns.possessive} ${args.to.name}`), new ImgElem('./media/cafat/images/lower-stomach.webp'))], + [[POV.Third, POV.Third], (user, target, args) => new LogLine(`${user.name} squeezes ${target.name} from ${user.pronouns.possessive} ${args.from.name} to ${user.pronouns.possessive} ${args.to.name}`)] + ]) + this.actions.push(transfer) + this.actions.push(new TransferAction(lowerStomach, stomach)) + + this.actions.push(new BelchAction(new Damage( + { amount: 100, target: Vigor.Willpower, type: DamageType.Acid } + ))) + this.otherActions.push(new FeedAction(stomach)) + } +} diff --git a/src/game/feast.ts b/src/game/feast.ts deleted file mode 100644 index 311a96e..0000000 --- a/src/game/feast.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Wolf } from './creatures/wolf' -import { POV } from './entity' -import { CompositeLog, LogLines, log } from './interface' - -const wolf = new Wolf() -const player = new Wolf() - -player.perspective = POV.First - -log(new CompositeLog(...player.validActions(wolf).map(action => new LogLines(action.toString())))) -log(new CompositeLog(...player.validActions(player).map(action => new LogLines(action.toString())))) - -log(player.actions[1].execute(player, wolf)) - -log(new CompositeLog(...player.validActions(wolf).map(action => new LogLines(action.toString())))) -log(new CompositeLog(...player.validActions(player).map(action => new LogLines(action.toString())))) diff --git a/src/game/interface.ts b/src/game/interface.ts index 7fcd349..6cbf663 100644 --- a/src/game/interface.ts +++ b/src/game/interface.ts @@ -92,6 +92,18 @@ export class FAElem implements LogEntry { } } +export class ImgElem implements LogEntry { + constructor (private url: string) { + + } + + render (): HTMLElement[] { + const img = document.createElement("img") + img.src = this.url + return [img] + } +} + export class CompositeLog implements LogEntry { entries: LogEntry[] diff --git a/src/game/language.ts b/src/game/language.ts index 35bbf39..af64d99 100644 --- a/src/game/language.ts +++ b/src/game/language.ts @@ -69,6 +69,29 @@ interface WordOptions { count: boolean; } +export type TextLike = { toString: () => string } + +// updates as needed +export class LiveText { + toString (): string { + return this.run(this.contents).toString() + } + + constructor (private contents: T, private run: (thing: T) => TextLike) { + + } +} + +export class DynText { + private parts: Array + constructor (...parts: TextLike[]) { + this.parts = parts + } + + toString (): string { + return (this.parts.map(part => part.toString())).join('') + } +} export class Noun { constructor (private singularNoun: string, private pluralNoun: string|null = null, private options: WordOptions = { plural: false, capital: false, proper: false, kind: NounKind.Specific, vowel: VowelSound.Default, count: true }) { diff --git a/src/game/vore.ts b/src/game/vore.ts index 7f64a19..39933e0 100644 --- a/src/game/vore.ts +++ b/src/game/vore.ts @@ -1,7 +1,7 @@ import { Entity, Mortal, POV } from './entity' import { Damage, Actionable, Action, DevourAction, FeedAction, DigestAction, ReleaseAction, StruggleAction, Vigor } from './combat' import { LogLines, LogEntry, CompositeLog, LogLine } from './interface' -import { POVSolo, POVPair, POVPairArgs } from './language' +import { Noun, POVPair, POVPairArgs, ImproperNoun } from './language' export enum VoreType { Oral = "Oral Vore", @@ -22,7 +22,7 @@ export interface Pred extends Entity { } export interface Container extends Actionable { - name: string; + name: Noun; owner: Pred; voreTypes: Set; contents: Array; @@ -136,11 +136,13 @@ abstract class NormalContainer implements Container { actions: Array - constructor (public name: string, public owner: Pred, public voreTypes: Set, public capacity: number, private damage: Damage) { + constructor (public name: Noun, public owner: Pred, public voreTypes: Set, public capacity: number, private damage: Damage) { this.contents = [] this.actions = [] + this.name = name + this.actions.push(new DevourAction(this)) this.actions.push(new DigestAction(this)) this.actions.push(new ReleaseAction(this)) @@ -148,9 +150,74 @@ abstract class NormalContainer implements Container { } } +abstract class InnerContainer extends NormalContainer { + release (prey: Prey): LogEntry { + prey.containedIn = this.escape + this.contents = this.contents.filter(victim => victim !== prey) + return this.releaseLines.run(this.owner, prey) + } + + constructor (name: Noun, owner: Pred, voreTypes: Set, capacity: number, damage: Damage, private escape: Container) { + super(name, owner, voreTypes, capacity, damage) + + this.actions = [] + + this.actions.push(new DigestAction(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) + super(new ImproperNoun('stomach', 'stomachs').all, 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}`)] + ]) + + 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}`)] + ]) + + 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 POVPairArgs([ + [[POV.First, POV.Third], (user, target, args) => new LogLine(`Your stomach gurgles ${target.name} for `, args.damage.renderShort())], + [[POV.Third, POV.First], (user, target, args) => new LogLine(`${user.name.capital}'s stomach churns you for `, args.damage.renderShort())], + [[POV.Third, POV.Third], (user, target, args) => new LogLine(`${user.name.capital} churns ${target.name} for `, args.damage.renderShort())] + ]) + + 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 InnerStomach extends InnerContainer { + constructor (owner: Pred, capacity: number, damage: Damage, escape: Container) { + super(new ImproperNoun('inner stomach', 'inner stomachs').all, owner, new Set([VoreType.Oral]), capacity, damage, escape) } consumeLines = new POVPair([ @@ -174,7 +241,7 @@ export class Stomach extends NormalContainer { tickLines = new POVPairArgs([ [[POV.First, POV.Third], (user, target, args) => new LogLine(`Your stomach gurgles ${target.name} for `, args.damage.renderShort())], [[POV.Third, POV.First], (user, target, args) => new LogLine(`${user.name.capital}'s stomach churns you for `, args.damage.renderShort())], - [[POV.Third, POV.Third], (user, target, args) => new LogLine(`${target.name.capital} churns ${user.name} for `, args.damage.renderShort())] + [[POV.Third, POV.Third], (user, target, args) => new LogLine(`${user.name.capital} churns ${target.name} for `, args.damage.renderShort())] ]) digestLines = new POVPair([ @@ -198,7 +265,7 @@ export class Stomach extends NormalContainer { export class Bowels extends NormalContainer { constructor (owner: Pred, capacity: number, damage: Damage) { - super('Bowels', owner, new Set([VoreType.Anal]), capacity, damage) + super(new ImproperNoun('bowel', 'bowels').plural, owner, new Set([VoreType.Anal]), capacity, damage) } consumeLines = new POVPair([