From ee1a089ef80ad40fff46546c4b0ecb22e8e3ba39 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 25 Jul 2020 11:46:45 -0400 Subject: [PATCH] Make entities provide names/pronouns based on perspective The name and pronouns properties now check the entity's perspective, returning specific ones for first person. This also includes a class for using a pronoun as a noun. --- src/components/Statblock.vue | 9 +---- src/game/creatures/withers.ts | 11 ++--- src/game/entity.ts | 6 ++- src/game/language.ts | 76 ++++++++++++++++++++++++++++------- src/game/vore.ts | 23 +++++++++-- 5 files changed, 90 insertions(+), 35 deletions(-) diff --git a/src/components/Statblock.vue b/src/components/Statblock.vue index a3d99c5..7334ef6 100644 --- a/src/components/Statblock.vue +++ b/src/components/Statblock.vue @@ -6,14 +6,7 @@
-

- You -
-
{{ subject.title }}
-
{{ subject.desc }}
-
-

-

+

{{subject.name.all.capital}}
{{ subject.title }}
diff --git a/src/game/creatures/withers.ts b/src/game/creatures/withers.ts index 39b04d8..57196b0 100644 --- a/src/game/creatures/withers.ts +++ b/src/game/creatures/withers.ts @@ -10,12 +10,6 @@ import * as Words from '../words' import { StatVigorTest } from '../combat/tests' class LevelDrain extends Action { - lines = new POVPairArgs([ - [[POV.First, POV.Third], (user, target, args) => new LogLine(`Your ${args.container.name} drains power from ${target.name}, siphoning `, args.damage.renderShort(), ` from ${target.pronouns.possessive} body!`)], - [[POV.Third, POV.First], (user, target, args) => new LogLine(`${user.name.capital}'s ${args.container.name} drains power from you, siphoning `, args.damage.renderShort(), ` from your body!`)], - [[POV.Third, POV.Third], (user, target, args) => new LogLine(`${user.name.capital}'s ${args.container.name} drains power from ${target.name}, siphoning `, args.damage.renderShort(), ` from ${target.pronouns.possessive} body!`)] - ]) - execute (user: Creature, target: Creature): LogEntry { const damage: Damage = new Damage(...Object.keys(Stat).map(stat => { return { @@ -35,7 +29,10 @@ class LevelDrain extends Action { user.takeDamage(heal) const targetResult = target.takeDamage(damage) - return new LogLines(this.lines.run(user, target, { damage: damage, container: this.container }), targetResult) + return new LogLines( + new LogLine(`${user.name.capital.possessive} ${this.container.name} drains power from ${target.name}, siphoning `, damage.renderShort(), ` from ${target.pronouns.possessive} body!`), + targetResult + ) } describe (user: Creature, target: Creature): LogEntry { diff --git a/src/game/entity.ts b/src/game/entity.ts index 64e9c2f..925ded0 100644 --- a/src/game/entity.ts +++ b/src/game/entity.ts @@ -8,9 +8,11 @@ export enum POV {First, Third} export interface Entity { name: Noun; + pronouns: Pronoun; + baseName: Noun; + basePronouns: Pronoun; title: TextLike; desc: TextLike; - pronouns: Pronoun; perspective: POV; } @@ -68,7 +70,7 @@ export class Creature extends Vore implements Combatant { containedIn: VoreContainer|null = null; - constructor (public name: Noun, public kind: Noun, public pronouns: Pronoun, public stats: Stats, public preyPrefs: Set, public predPrefs: Set, mass: number) { + constructor (public baseName: Noun, public kind: Noun, public basePronouns: Pronoun, public stats: Stats, public preyPrefs: Set, public predPrefs: Set, mass: number) { super() const containers = this.containers diff --git a/src/game/language.ts b/src/game/language.ts index a8886c2..2b51afe 100644 --- a/src/game/language.ts +++ b/src/game/language.ts @@ -89,14 +89,15 @@ export interface Pluralizable { } interface WordOptions { - plural: boolean; - capital: boolean; - allCaps: boolean; - proper: boolean; - nounKind: NounKind; - verbKind: VerbKind; - vowel: VowelSound; - count: boolean; + plural: boolean; + capital: boolean; + allCaps: boolean; + proper: boolean; + nounKind: NounKind; + verbKind: VerbKind; + vowel: VowelSound; + count: boolean; + possessive: boolean; } const emptyConfig: WordOptions = { @@ -107,7 +108,8 @@ const emptyConfig: WordOptions = { verbKind: VerbKind.Root, plural: false, proper: false, - vowel: VowelSound.Default + vowel: VowelSound.Default, + possessive: false } export type TextLike = { toString: () => string } @@ -228,6 +230,18 @@ export abstract class Word { opts.verbKind = VerbKind.PastParticiple return this.configure(opts) as this } + + get possessive (): this { + const opts: WordOptions = Object.assign({}, this.opt) + opts.possessive = true + return this.configure(opts) as this + } + + get nonpossessive (): this { + const opts: WordOptions = Object.assign({}, this.opt) + opts.possessive = false + return this.configure(opts) as this + } } export class RandomWord extends Word { @@ -254,18 +268,25 @@ export class RandomWord extends Word { } export class Noun extends Word { - constructor (private singularNoun: string, private pluralNoun: string|null = null, private options: WordOptions = emptyConfig) { + constructor (protected singularNoun: string, protected pluralNoun: string|null = null, protected possessiveNoun: string|null = null, protected options: WordOptions = emptyConfig) { super(options) } configure (opts: WordOptions): Word { - return new Noun(this.singularNoun, this.pluralNoun, opts) + return new Noun(this.singularNoun, this.pluralNoun, this.possessiveNoun, opts) } toString (): string { let result: string - if (this.options.plural) { + // TODO: plural possessive nouns? + if (this.options.possessive) { + if (this.possessiveNoun === null) { + result = this.singularNoun + "'s" + } else { + result = this.possessiveNoun + } + } else if (this.options.plural) { if (this.pluralNoun === null) { result = this.singularNoun } else { @@ -308,14 +329,14 @@ 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, nounKind: NounKind.Specific, verbKind: VerbKind.Root, vowel: VowelSound.Default, count: true }) + constructor (singularNoun: string, pluralNoun: string = singularNoun, possessiveNoun: string = singularNoun + "'s") { + super(singularNoun, pluralNoun, null, { plural: false, allCaps: false, capital: false, proper: false, nounKind: NounKind.Specific, verbKind: VerbKind.Root, vowel: VowelSound.Default, count: true, possessive: false }) } } export class ProperNoun extends Noun { constructor (singularNoun: string) { - super(singularNoun, null, { plural: false, allCaps: false, capital: false, proper: true, nounKind: NounKind.Specific, verbKind: VerbKind.Root, vowel: VowelSound.Default, count: true }) + super(singularNoun, null, null, { plural: false, allCaps: false, capital: false, proper: true, nounKind: NounKind.Specific, verbKind: VerbKind.Root, vowel: VowelSound.Default, count: true, possessive: false }) } } @@ -412,6 +433,17 @@ export class Pronoun implements Pluralizable { } } +export class PronounAsNoun extends Noun { + constructor (private pronouns: Pronoun, opt: WordOptions = emptyConfig) { + super(pronouns.subjective, pronouns.subjective, pronouns.possessive, opt) + this.options.nounKind = NounKind.All + } + + configure (opts: WordOptions): Word { + return new PronounAsNoun(this.pronouns, opts) + } +} + export const MalePronouns = new Pronoun({ subjective: 'he', objective: 'him', @@ -446,3 +478,17 @@ export const ObjectPronouns = new Pronoun({ possessive: 'its', reflexive: 'itself' }) + +export const SecondPersonPronouns = new Pronoun({ + subjective: 'you', + objective: 'you', + possessive: 'your', + reflexive: 'yourself' +}) + +export const FirstPersonPronouns = new Pronoun({ + subjective: 'I', + objective: 'me', + possessive: 'my', + reflexive: 'myself' +}) diff --git a/src/game/vore.ts b/src/game/vore.ts index d1a5531..a4376df 100644 --- a/src/game/vore.ts +++ b/src/game/vore.ts @@ -1,7 +1,7 @@ import { Entity, Mortal, POV, Creature } from './entity' import { Damage, DamageType, Stats, Actionable, Action, Vigor, VoreStats } from './combat' import { LogLines, LogEntry, CompositeLog, LogLine } from './interface' -import { Noun, Pronoun, POVPair, POVPairArgs, ImproperNoun, POVSolo, TextLike, Verb, Word } from './language' +import { Noun, Pronoun, POVPair, POVPairArgs, ImproperNoun, POVSolo, TextLike, Verb, SecondPersonPronouns, PronounAsNoun } from './language' import { DigestAction, DevourAction, ReleaseAction, StruggleAction } from './combat/actions' import * as Words from './words' @@ -13,12 +13,29 @@ export enum VoreType { } export abstract class Vore implements Mortal { - abstract name: Noun; + abstract baseName: Noun; + abstract basePronouns: Pronoun; abstract title: TextLike; abstract desc: TextLike; abstract kind: Noun; - abstract pronouns: Pronoun; abstract perspective: POV; + + get name (): Noun { + if (this.perspective === POV.First) { + return new PronounAsNoun(SecondPersonPronouns) + } else { + return this.baseName + } + } + + get pronouns (): Pronoun { + if (this.perspective === POV.First) { + return SecondPersonPronouns + } else { + return this.basePronouns + } + } + abstract vigors: {[key in Vigor]: number}; abstract maxVigors: {[key in Vigor]: number}; abstract disabled: boolean;