From d91ca8fb59c08b107e8ac64da40556de163cd3f0 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Tue, 18 Aug 2020 13:37:17 -0400 Subject: [PATCH] Switch vore containers to use methods, not properties, for lines; add some variety --- src/game/interface.ts | 17 ++++++++++ src/game/maps/town.ts | 2 +- src/game/vore.ts | 78 ++++++++++++++++++++++++------------------- src/game/words.ts | 6 ++++ 4 files changed, 68 insertions(+), 35 deletions(-) diff --git a/src/game/interface.ts b/src/game/interface.ts index f14808d..c9cf89e 100644 --- a/src/game/interface.ts +++ b/src/game/interface.ts @@ -129,6 +129,23 @@ export class LogLine implements LogEntry { } } +export class RandomEntry implements LogEntry { + private options: Array + + constructor (...options: Array) { + this.options = options + } + + render (): HTMLElement[] { + if (this.options.length === 0) { + return nilLog.render() + } else { + const choice = Math.floor(Math.random() * this.options.length) + return this.options[choice].render() + } + } +} + export class Newline implements LogEntry { render (): HTMLElement[] { return [document.createElement("br")] diff --git a/src/game/maps/town.ts b/src/game/maps/town.ts index a92538c..9f17ece 100644 --- a/src/game/maps/town.ts +++ b/src/game/maps/town.ts @@ -248,7 +248,7 @@ export const Town = (): Place => { "Eat someone", "Slurp", (world, executor) => { - const snack = new Creatures.Human(new ProperNoun(["Snack", "Treat", "Tasty", "Dinner", "Appetizer"][Math.floor(Math.random() * 5)]), TheyPronouns) + const snack = new Creatures.Human(new ProperNoun(["Snack", "Treat", "Tasty", "Dinner", "Appetizer"][Math.floor(Math.random() * 5)]), [MalePronouns, FemalePronouns, TheyPronouns][Math.floor(Math.random() * 3)]) snack.applyEffect(new SurrenderEffect()) const options = executor.validActions(snack).filter(action => action instanceof DevourAction) return options[Math.floor(options.length * Math.random())].execute(executor, snack) diff --git a/src/game/vore.ts b/src/game/vore.ts index 53c7afc..6bb8f26 100644 --- a/src/game/vore.ts +++ b/src/game/vore.ts @@ -1,6 +1,6 @@ import { Mortal } from './entity' import { Damage, DamageType, Stats, Actionable, Action, Vigor, VoreStats, VisibleStatus, VoreStat, DamageInstance, DamageFormula } from './combat' -import { LogLines, LogEntry, LogLine, nilLog } from './interface' +import { LogLines, LogEntry, LogLine, nilLog, RandomEntry } from './interface' import { Noun, Pronoun, ImproperNoun, TextLike, Verb, SecondPersonPronouns, PronounAsNoun, FirstPersonPronouns, PairLineArgs, SoloLine, POV, RandomWord } from './language' import { RubAction, DevourAction, ReleaseAction, StruggleAction, TransferAction } from './combat/actions' import * as Words from './words' @@ -40,7 +40,7 @@ export interface Container extends Actionable { releaseVerb: Verb; struggleVerb: Verb; - consumeLine: PairLineArgs; + consumeLine (user: Creature, target: Creature): LogEntry; } @@ -64,16 +64,16 @@ export abstract class NormalContainer implements Container { return this.capacityFactor * this.owner.voreStats.Mass } - consumeLine: PairLineArgs = (user, target, args) => { - return new LogLine(`${user.name.capital} ${user.name.conjugate(this.consumeVerb)} ${target.name.objective} in ${user.pronouns.possessive} ${args.container.name}.`) + consumeLine (user: Creature, target: Creature): LogEntry { + return new LogLine(`${user.name.capital} ${user.name.conjugate(this.consumeVerb)} ${target.name.objective} in ${user.pronouns.possessive} ${this.name}.`) } - releaseLine: PairLineArgs = (user, target, args) => { - return new LogLine(`${user.name.capital} ${user.name.conjugate(this.releaseVerb)} ${target.name.objective} up from ${user.pronouns.possessive} ${args.container.name}.`) + releaseLine (user: Creature, target: Creature): LogEntry { + return new LogLine(`${user.name.capital} ${user.name.conjugate(this.releaseVerb)} ${target.name.objective} up from ${user.pronouns.possessive} ${this.name}.`) } - struggleLine: PairLineArgs = (user, target, args) => { - return new LogLine(`${user.name.capital} ${user.name.conjugate(this.struggleVerb)} within ${target.name.possessive} ${args.container.name}.`) + struggleLine (user: Creature, target: Creature): LogEntry { + return new LogLine(`${user.name.capital} ${user.name.conjugate(this.struggleVerb)} within ${target.name.possessive} ${this.name}.`) } get fullness (): number { @@ -96,7 +96,7 @@ export abstract class NormalContainer implements Container { } this.contents.push(prey) prey.containedIn = this - return this.consumeLine(this.owner, prey, { container: this }) + return this.consumeLine(this.owner, prey) } release (prey: Creature): LogEntry { @@ -106,11 +106,11 @@ export abstract class NormalContainer implements Container { if (this.owner.containedIn !== null) { this.owner.containedIn.contents.push(prey) } - return this.releaseLine(this.owner, prey, { container: this }) + return this.releaseLine(this.owner, prey) } struggle (prey: Creature): LogEntry { - return this.struggleLine(prey, this.owner, { container: this }) + return this.struggleLine(prey, this.owner) } describe (): LogEntry { @@ -148,7 +148,7 @@ export abstract class InnerContainer extends NormalContainer { release (prey: Creature): LogEntry { prey.containedIn = this.escape this.contents = this.contents.filter(victim => victim !== prey) - return this.releaseLine(this.owner, prey, { container: this }) + return this.releaseLine(this.owner, prey) } } @@ -184,20 +184,27 @@ export abstract class NormalVoreContainer extends NormalContainer implements Vor return Array.from(this.contents.concat(this.digested, this.absorbed).values()).reduce((total: number, prey: Creature) => total + prey.voreStats.Bulk, 0) } - consumeLine: PairLineArgs = (user, target, args) => { - return new LogLine(`${user.name.capital} ${user.name.conjugate(this.consumeVerb)} ${target.name.objective}, forcing ${target.pronouns.objective} into ${user.pronouns.possessive} ${args.container.name}.`) + consumeLine (user: Creature, target: Creature) { + return new RandomEntry( + new LogLine(`${user.name.capital} ${user.name.conjugate(this.consumeVerb)} ${target.name.objective}, forcing ${target.pronouns.objective} into ${user.pronouns.possessive} ${this.name}.`), + new LogLine(`${user.name.capital} ${user.name.conjugate(new Verb("pounce"))} on ${target.name.objective} and ${user.name.conjugate(this.consumeVerb)} ${target.pronouns.objective}, ${Words.Force.present} ${target.pronouns.objective} into ${user.pronouns.possessive} ${this.name}.`) + ) } - tickLine: PairLineArgs = (user, target, args) => { - return new LogLine(`${user.name.capital} ${user.name.conjugate(Words.Churns)} ${target.name.objective} in ${user.pronouns.possessive} ${args.container.name} for `, args.damage.renderShort(), `.`) + tickLine (user: Creature, target: Creature, args: { damage: Damage }): LogEntry { + return new RandomEntry( + new LogLine(`${user.name.capital} ${user.name.conjugate(Words.Churns)} ${target.name.objective} in ${user.pronouns.possessive} ${this.name} for `, args.damage.renderShort(), `.`), + new LogLine(`${user.name.capital.possessive} ${this.name} ${Words.Churns}, stewing ${target.name.objective} for `, args.damage.renderShort(), `.`), + new LogLine(`${target.name.capital} ${target.name.conjugate(new Verb("thrash", "thrashes"))} in ${user.name.possessive} ${Words.Slick} ${this.name} as it churns ${target.pronouns.objective} for `, args.damage.renderShort(), `.`) + ) } - digestLine: PairLineArgs = (user, target, args) => { - return new LogLine(`${user.name.capital.possessive} ${args.container.name} ${args.container.name.conjugate(new Verb('finish', 'finishes'))} ${Words.Digests.present} ${target.name.objective} down, ${target.pronouns.possessive} ${Words.Struggles.singular} fading away.`) + digestLine (user: Creature, target: Creature): LogEntry { + return new LogLine(`${user.name.capital.possessive} ${this.name} ${this.name.conjugate(new Verb('finish', 'finishes'))} ${Words.Digests.present} ${target.name.objective} down, ${target.pronouns.possessive} ${Words.Struggles.singular} fading away.`) } - absorbLine: PairLineArgs = (user, target, args) => { - return new LogLine(`${user.name.capital.possessive} ${args.container.name} ${args.container.name.conjugate(new Verb('finish', 'finishes'))} ${Words.Absorbs.present} ${target.name.objective}, fully claiming ${target.pronouns.objective}.`) + absorbLine (user: Creature, target: Creature): LogEntry { + return new LogLine(`${user.name.capital.possessive} ${this.name} ${this.name.conjugate(new Verb('finish', 'finishes'))} ${Words.Absorbs.present} ${target.name.objective}, fully claiming ${target.pronouns.objective}.`) } tick (dt: number): LogEntry { @@ -210,7 +217,7 @@ export abstract class NormalVoreContainer extends NormalContainer implements Vor this.contents.forEach(prey => { const scaled = this.damage.calc(this.owner, prey).scale(dt / 60) - tickedEntryList.push(this.tickLine(this.owner, prey, { container: this, damage: scaled })) + tickedEntryList.push(this.tickLine(this.owner, prey, { damage: scaled })) damageResults.push(prey.takeDamage(scaled)) @@ -258,11 +265,11 @@ export abstract class NormalVoreContainer extends NormalContainer implements Vor } absorb (preys: Creature[]): LogEntry { - return new LogLines(...preys.map(prey => this.absorbLine(this.owner, prey, { container: this }))) + return new LogLines(...preys.map(prey => this.absorbLine(this.owner, prey))) } digest (preys: Creature[]): LogEntry { - return new LogLines(...preys.map(prey => this.digestLine(this.owner, prey, { container: this }))) + return new LogLines(...preys.map(prey => this.digestLine(this.owner, prey))) } onAbsorb (prey: Creature): LogEntry { @@ -288,7 +295,7 @@ export abstract class InnerVoreContainer extends NormalVoreContainer { prey.containedIn = this.escape this.contents = this.contents.filter(victim => victim !== prey) this.escape.consume(prey) - return this.releaseLine(this.owner, prey, { container: this }) + return this.releaseLine(this.owner, prey) } } @@ -330,13 +337,16 @@ export class Bowels extends NormalVoreContainer { super(new ImproperNoun('bowel', 'bowels').plural.all, owner, new Set([VoreType.Anal]), capacity, damage) } - tickLine: PairLineArgs = (user, target, args) => { - return new LogLine(`${user.name.capital} ${user.name.conjugate( - new RandomWord([ - new Verb('crush', 'crushes'), - new Verb('clench', 'clenches') - ]) - )} ${target.name.objective} in ${user.pronouns.possessive} ${args.container.name} for `, args.damage.renderShort(), `.`) + tickLine (user: Creature, target: Creature, args: { damage: Damage }) { + return new RandomEntry( + new LogLine(`${user.name.capital} ${user.name.conjugate( + new RandomWord([ + new Verb('crush', 'crushes'), + new Verb('clench', 'clenches') + ]) + )} ${target.name.objective} in ${user.pronouns.possessive} ${this.name} for `, args.damage.renderShort(), `.`), + super.tickLine(user, target, args) + ) } } @@ -353,13 +363,13 @@ export class Cock extends NormalVoreContainer { ) } - tickLine: PairLineArgs = (user, target, args) => { + tickLine (user: Creature, target: Creature, args: { damage: Damage }): LogEntry { return new LogLine(`${user.name.capital} ${user.name.conjugate( new RandomWord([ new Verb('crush', 'crushes'), new Verb('clench', 'clenches') ]) - )} ${target.name.objective} in ${user.pronouns.possessive} ${args.container.name}.`) + )} ${target.name.objective} in ${user.pronouns.possessive} ${this.name}.`) } } @@ -411,7 +421,7 @@ export function biconnectContainers (outer: VoreContainer, inner: VoreContainer) outer.onDigest = (prey: Creature) => { outer.digested = outer.digested.filter(victim => victim !== prey) inner.digested.push(prey) - return inner.consumeLine(inner.owner, prey, { container: inner }) + return inner.consumeLine(inner.owner, prey) } outer.actions.push( diff --git a/src/game/words.ts b/src/game/words.ts index ec0d7ee..f290577 100644 --- a/src/game/words.ts +++ b/src/game/words.ts @@ -68,3 +68,9 @@ export const Brutally = new RandomWord([ new Adjective('ruthlessly'), new Adjective('mercilessly') ]) + +export const Force = new RandomWord([ + new Verb("force", "forces", "forcing", "forced"), + new Verb("cram", "crams", "cramming", "crammed"), + new Verb("stuff", "stuffs", "stuffing", "stuffed") +])