| @@ -1,8 +1,8 @@ | |||
| import { Creature, POV } from '../entity' | |||
| import { Damage, DamageType, ConstantDamageFormula, Vigor, Side, GroupAction } from '../combat' | |||
| import { ImproperNoun, POVPair, ProperNoun, FemalePronouns, RandomWord, Adjective } from '../language' | |||
| import { ImproperNoun, POVPair, ProperNoun, FemalePronouns, RandomWord, Adjective, POVPairArgs } from '../language' | |||
| import { LogLine, LogLines, LogEntry } from '../interface' | |||
| import { VoreType, Stomach, Container } from '../vore' | |||
| import { VoreType, Stomach, Container, Vore } from '../vore' | |||
| import { AttackAction, FeedAction } from '../combat/actions' | |||
| import { TogetherCondition } from '../combat/conditions' | |||
| import { InstantKill } from '../combat/effects' | |||
| @@ -68,7 +68,7 @@ class DevourAllAction extends GroupAction { | |||
| executeGroup (user: Creature, targets: Array<Creature>): LogEntry { | |||
| return new LogLines(...targets.map(target => this.execute(user, target)).concat( | |||
| [new LogLine(`${Words.SwallowSound.allCaps}! All ${targets.length} of them pour down ${user.name}'s ${Words.Slick} gullet; they're just ${user.kind.all} chow now`)] | |||
| [new LogLine(`${Words.SwallowSound.allCaps}! All ${targets.length} of them pour down ${user.name}'s ${Words.Slick} gullet as ${user.pronouns.possessive} ${Words.Swallows.singular}; they're just ${user.kind.all} chow now`)] | |||
| )) | |||
| } | |||
| @@ -100,11 +100,23 @@ export class Withers extends Creature { | |||
| this.side = Side.Monsters | |||
| const stomach = new Stomach(this, 50, new Damage( | |||
| { amount: 30, type: DamageType.Acid, target: Vigor.Health }, | |||
| { amount: 20, type: DamageType.Crush, target: Vigor.Stamina }, | |||
| { amount: 20, type: DamageType.Dominance, target: Vigor.Resolve } | |||
| { amount: 300, type: DamageType.Acid, target: Vigor.Health }, | |||
| { amount: 200, type: DamageType.Crush, target: Vigor.Stamina }, | |||
| { amount: 200, type: DamageType.Dominance, target: Vigor.Resolve } | |||
| )) | |||
| stomach.tickLines = new POVPairArgs<Vore, Vore, { damage: Damage }>([ | |||
| [[POV.First, POV.Third], (user, target, args) => new LogLine(`Your stomach ${Words.Churns.singular} ${target.name} for `, args.damage.renderShort())], | |||
| [[POV.Third, POV.First], (user, target, args) => new LogLine(`${user.name.capital}'s stomach ${Words.Churns.singular} you for `, args.damage.renderShort())], | |||
| [[POV.Third, POV.Third], (user, target, args) => new LogLine(`${user.name.capital} ${Words.Churns.singular} ${target.name} for `, args.damage.renderShort())] | |||
| ]) | |||
| stomach.digestLines = new POVPair<Vore, Vore>([ | |||
| [[POV.First, POV.Third], (user, target) => new LogLine(`Your stomach ${Words.Digests.singular} ${target.name}`)], | |||
| [[POV.Third, POV.First], (user, target) => new LogLine(`${user.name.capital}'s stomach ${Words.Digests.singular} you`)], | |||
| [[POV.Third, POV.Third], (user, target) => new LogLine(`${target.name.capital}'s squirms fade as the ${target.kind.all} is ${Words.Digests.past} by the ${user.kind}'s ${stomach.name}.`)] | |||
| ]) | |||
| this.containers.push(stomach) | |||
| this.otherActions.push(new FeedAction(stomach)) | |||
| @@ -60,6 +60,14 @@ enum VowelSound { | |||
| NonVowel | |||
| } | |||
| enum VerbKind { | |||
| Root, | |||
| Singular, | |||
| Present, | |||
| Past, | |||
| PastParticiple | |||
| } | |||
| export interface Pluralizable { | |||
| isPlural: boolean; | |||
| } | |||
| @@ -69,7 +77,8 @@ interface WordOptions { | |||
| capital: boolean; | |||
| allCaps: boolean; | |||
| proper: boolean; | |||
| kind: NounKind; | |||
| nounKind: NounKind; | |||
| verbKind: VerbKind; | |||
| vowel: VowelSound; | |||
| count: boolean; | |||
| } | |||
| @@ -78,7 +87,8 @@ const emptyConfig: WordOptions = { | |||
| allCaps: false, | |||
| capital: false, | |||
| count: false, | |||
| kind: NounKind.Specific, | |||
| nounKind: NounKind.Specific, | |||
| verbKind: VerbKind.Root, | |||
| plural: false, | |||
| proper: false, | |||
| vowel: VowelSound.Default | |||
| @@ -151,19 +161,19 @@ export abstract class Word { | |||
| get specific (): this { | |||
| const opts: WordOptions = Object.assign({}, this.opt) | |||
| opts.kind = NounKind.Specific | |||
| opts.nounKind = NounKind.Specific | |||
| return this.configure(opts) as this | |||
| } | |||
| get nonspecific (): this { | |||
| const opts: WordOptions = Object.assign({}, this.opt) | |||
| opts.kind = NounKind.Nonspecific | |||
| opts.nounKind = NounKind.Nonspecific | |||
| return this.configure(opts) as this | |||
| } | |||
| get all (): this { | |||
| const opts: WordOptions = Object.assign({}, this.opt) | |||
| opts.kind = NounKind.All | |||
| opts.nounKind = NounKind.All | |||
| return this.configure(opts) as this | |||
| } | |||
| @@ -172,6 +182,36 @@ export abstract class Word { | |||
| opts.count = false | |||
| return this.configure(opts) as this | |||
| } | |||
| get root (): this { | |||
| const opts: WordOptions = Object.assign({}, this.opt) | |||
| opts.verbKind = VerbKind.Root | |||
| return this.configure(opts) as this | |||
| } | |||
| get singular (): this { | |||
| const opts: WordOptions = Object.assign({}, this.opt) | |||
| opts.verbKind = VerbKind.Singular | |||
| return this.configure(opts) as this | |||
| } | |||
| get present (): this { | |||
| const opts: WordOptions = Object.assign({}, this.opt) | |||
| opts.verbKind = VerbKind.Present | |||
| return this.configure(opts) as this | |||
| } | |||
| get past (): this { | |||
| const opts: WordOptions = Object.assign({}, this.opt) | |||
| opts.verbKind = VerbKind.Past | |||
| return this.configure(opts) as this | |||
| } | |||
| get pastParticiple (): this { | |||
| const opts: WordOptions = Object.assign({}, this.opt) | |||
| opts.verbKind = VerbKind.PastParticiple | |||
| return this.configure(opts) as this | |||
| } | |||
| } | |||
| export class RandomWord extends Word { | |||
| @@ -220,7 +260,7 @@ export class Noun extends Word { | |||
| } | |||
| if (!this.options.proper) { | |||
| if (this.options.kind === NounKind.Nonspecific && this.options.count) { | |||
| if (this.options.nounKind === NounKind.Nonspecific && this.options.count) { | |||
| if (this.options.plural) { | |||
| result = 'some ' + result | |||
| } else { | |||
| @@ -236,7 +276,7 @@ export class Noun extends Word { | |||
| result = 'a ' + result | |||
| } | |||
| } | |||
| } else if (this.options.kind === NounKind.Specific) { | |||
| } else if (this.options.nounKind === NounKind.Specific) { | |||
| result = 'the ' + result | |||
| } | |||
| } | |||
| @@ -253,13 +293,13 @@ export class Noun extends Word { | |||
| export class ImproperNoun extends Noun { | |||
| constructor (singularNoun: string, pluralNoun: string = singularNoun) { | |||
| super(singularNoun, pluralNoun, { plural: false, allCaps: false, capital: false, proper: false, kind: NounKind.Specific, vowel: VowelSound.Default, count: true }) | |||
| super(singularNoun, pluralNoun, { plural: false, allCaps: false, capital: false, proper: false, nounKind: NounKind.Specific, verbKind: VerbKind.Root, vowel: VowelSound.Default, count: true }) | |||
| } | |||
| } | |||
| export class ProperNoun extends Noun { | |||
| constructor (singularNoun: string) { | |||
| super(singularNoun, null, { plural: false, allCaps: false, capital: false, proper: true, kind: NounKind.Specific, vowel: VowelSound.Default, count: true }) | |||
| super(singularNoun, null, { plural: false, allCaps: false, capital: false, proper: true, nounKind: NounKind.Specific, verbKind: VerbKind.Root, vowel: VowelSound.Default, count: true }) | |||
| } | |||
| } | |||
| @@ -272,11 +312,49 @@ export class Adjective extends Word { | |||
| return new Adjective(this.adjective, opts) | |||
| } | |||
| // TODO caps et al. | |||
| toString (): string { | |||
| return this.adjective | |||
| } | |||
| } | |||
| export class Verb extends Word { | |||
| configure (opts: WordOptions): Word { | |||
| return new Verb( | |||
| this._root, | |||
| this._singular, | |||
| this._present, | |||
| this._past, | |||
| this._pastParticiple, | |||
| opts | |||
| ) | |||
| } | |||
| toString (): string { | |||
| let choice: string | |||
| switch (this.opt.verbKind) { | |||
| case VerbKind.Root: choice = this._root; break | |||
| case VerbKind.Singular: choice = this._singular; break | |||
| case VerbKind.Present: choice = this._present; break | |||
| case VerbKind.Past: choice = this._past; break | |||
| case VerbKind.PastParticiple: choice = this._pastParticiple; break | |||
| } | |||
| if (this.opt.allCaps) { | |||
| choice = choice.toUpperCase() | |||
| } else if (this.opt.capital) { | |||
| choice = choice.slice(0, 1).toUpperCase() + choice.slice(1) | |||
| } | |||
| return choice | |||
| } | |||
| constructor (private _root: string, private _singular: string = _root + "s", private _present: string = _root + "ing", private _past: string = _root + "ed", private _pastParticiple: string = _past, public opt: WordOptions = emptyConfig) { | |||
| super(opt) | |||
| } | |||
| } | |||
| interface PronounDict { | |||
| subjective: string; | |||
| objective: string; | |||
| @@ -201,19 +201,19 @@ export class Stomach extends NormalContainer { | |||
| super(new ImproperNoun('stomach', 'stomachs').all, owner, new Set([VoreType.Oral]), capacity, damage) | |||
| } | |||
| consumeLines = new POVPair([ | |||
| consumeLines = new POVPair<Vore, Vore>([ | |||
| [[POV.First, POV.Third], (user, target) => new LogLine(`You devour ${target.name}`)], | |||
| [[POV.Third, POV.First], (user, target) => new LogLine(`${user.name.capital} munches you`)], | |||
| [[POV.Third, POV.Third], (user, target) => new LogLine(`${user.name.capital} munches ${target.name}`)] | |||
| ]) | |||
| releaseLines = new POVPair([ | |||
| releaseLines = new POVPair<Vore, Vore>([ | |||
| [[POV.First, POV.Third], (user, target) => new LogLine(`You hork up ${target.name}`)], | |||
| [[POV.Third, POV.First], (user, target) => new LogLine(`${user.name.capital} horks you up`)], | |||
| [[POV.Third, POV.Third], (user, target) => new LogLine(`${user.name.capital} horks up ${target.name}`)] | |||
| ]) | |||
| struggleLines = new POVPair([ | |||
| struggleLines = new POVPair<Vore, Vore>([ | |||
| [[POV.First, POV.Third], (user, target) => new LogLine(`You claw your way out of ${target.name}`)], | |||
| [[POV.Third, POV.First], (user, target) => new LogLine(`${user.name.capital} forces ${user.pronouns.possessive} way up your throat!`)], | |||
| [[POV.Third, POV.Third], (user, target) => new LogLine(`${user.name.capital} escapes from the gut of ${target.name}`)] | |||
| @@ -225,19 +225,19 @@ export class Stomach extends NormalContainer { | |||
| [[POV.Third, POV.Third], (user, target, args) => new LogLine(`${user.name.capital} churns ${target.name} for `, args.damage.renderShort())] | |||
| ]) | |||
| digestLines = new POVPair([ | |||
| digestLines = new POVPair<Vore, Vore>([ | |||
| [[POV.First, POV.Third], (user, target) => new LogLine(`Your stomach overwhelms ${target.name}`)], | |||
| [[POV.Third, POV.First], (user, target) => new LogLine(`${user.name.capital}'s stomach finishes you off`)], | |||
| [[POV.Third, POV.Third], (user, target) => new LogLine(`${target.name.capital}'s squirms fade, overwhelmed by the stomach of ${user.name}`)] | |||
| ]) | |||
| absorbLines = new POVPair([ | |||
| absorbLines = new POVPair<Vore, Vore>([ | |||
| [[POV.First, POV.Third], (user, target) => new LogLine(`Your guts completely absorb ${target.name}`)], | |||
| [[POV.Third, POV.First], (user, target) => new LogLine(`${user.name.capital}'s guts soak you up like water in a sponge`)], | |||
| [[POV.Third, POV.Third], (user, target) => new LogLine(`${user.name.capital} finishes absorbing the remains of ${target.name}`)] | |||
| ]) | |||
| disposeLines = new POVPair([ | |||
| disposeLines = new POVPair<Vore, Vore>([ | |||
| [[POV.First, POV.Third], (user, target) => new LogLine(`Your guts completely absorb ${target.name}`)], | |||
| [[POV.Third, POV.First], (user, target) => new LogLine(`${user.name.capital}'s guts soak you up like water in a sponge`)], | |||
| [[POV.Third, POV.Third], (user, target) => new LogLine(`${user.name.capital} finishes absorbing the remains of ${target.name}`)] | |||
| @@ -1,4 +1,4 @@ | |||
| import { RandomWord, ImproperNoun, Adjective } from './language' | |||
| import { RandomWord, ImproperNoun, Adjective, Verb } from './language' | |||
| export const SwallowSound = new RandomWord([ | |||
| new ImproperNoun('gulp'), | |||
| @@ -12,3 +12,21 @@ export const Slick = new RandomWord([ | |||
| new Adjective('slimy'), | |||
| new Adjective('glistening') | |||
| ]) | |||
| export const Swallows = new RandomWord([ | |||
| new Verb("swallow"), | |||
| new Verb("gulp") | |||
| ]) | |||
| export const Churns = new RandomWord([ | |||
| new Verb("churn"), | |||
| new Verb("sizzle", "sizzles", "sizzling", "sizzled"), | |||
| new Verb("simmer"), | |||
| new Verb("stew") | |||
| ]) | |||
| export const Digests = new RandomWord([ | |||
| new Verb("digest"), | |||
| new Verb("melt"), | |||
| new Verb("dissolve", "dissolves", "dissolving", "dissolved") | |||
| ]) | |||