浏览代码

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.
master
Fen Dweller 5 年前
父节点
当前提交
ee1a089ef8
共有 5 个文件被更改,包括 90 次插入35 次删除
  1. +1
    -8
      src/components/Statblock.vue
  2. +4
    -7
      src/game/creatures/withers.ts
  3. +4
    -2
      src/game/entity.ts
  4. +61
    -15
      src/game/language.ts
  5. +20
    -3
      src/game/vore.ts

+ 1
- 8
src/components/Statblock.vue 查看文件

@@ -6,14 +6,7 @@
<div class="statblock-shader statblock-shader-dead"></div> <div class="statblock-shader statblock-shader-dead"></div>
<div class="statblock-shader statblock-shader-eaten"></div> <div class="statblock-shader statblock-shader-eaten"></div>
<div class="statblock-content"> <div class="statblock-content">
<h2 class="name" v-if="subject.perspective === firstperson">
You
<div class="tooltip-template">
<div class="tooltip-title">{{ subject.title }}</div>
<div class="tooltip-body">{{ subject.desc }}</div>
</div>
</h2>
<h2 class="name" v-if="subject.perspective !== firstperson">
<h2 class="name">
{{subject.name.all.capital}} {{subject.name.all.capital}}
<div class="tooltip-template"> <div class="tooltip-template">
<div class="tooltip-title">{{ subject.title }}</div> <div class="tooltip-title">{{ subject.title }}</div>


+ 4
- 7
src/game/creatures/withers.ts 查看文件

@@ -10,12 +10,6 @@ import * as Words from '../words'
import { StatVigorTest } from '../combat/tests' import { StatVigorTest } from '../combat/tests'


class LevelDrain extends Action { class LevelDrain extends Action {
lines = new POVPairArgs<Creature, Creature, { damage: Damage; container: Container }>([
[[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 { execute (user: Creature, target: Creature): LogEntry {
const damage: Damage = new Damage(...Object.keys(Stat).map(stat => { const damage: Damage = new Damage(...Object.keys(Stat).map(stat => {
return { return {
@@ -35,7 +29,10 @@ class LevelDrain extends Action {
user.takeDamage(heal) user.takeDamage(heal)
const targetResult = target.takeDamage(damage) 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 { describe (user: Creature, target: Creature): LogEntry {


+ 4
- 2
src/game/entity.ts 查看文件

@@ -8,9 +8,11 @@ export enum POV {First, Third}


export interface Entity { export interface Entity {
name: Noun; name: Noun;
pronouns: Pronoun;
baseName: Noun;
basePronouns: Pronoun;
title: TextLike; title: TextLike;
desc: TextLike; desc: TextLike;
pronouns: Pronoun;
perspective: POV; perspective: POV;
} }


@@ -68,7 +70,7 @@ export class Creature extends Vore implements Combatant {


containedIn: VoreContainer|null = null; containedIn: VoreContainer|null = null;


constructor (public name: Noun, public kind: Noun, public pronouns: Pronoun, public stats: Stats, public preyPrefs: Set<VoreType>, public predPrefs: Set<VoreType>, mass: number) {
constructor (public baseName: Noun, public kind: Noun, public basePronouns: Pronoun, public stats: Stats, public preyPrefs: Set<VoreType>, public predPrefs: Set<VoreType>, mass: number) {
super() super()
const containers = this.containers const containers = this.containers




+ 61
- 15
src/game/language.ts 查看文件

@@ -89,14 +89,15 @@ export interface Pluralizable {
} }


interface WordOptions { 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 = { const emptyConfig: WordOptions = {
@@ -107,7 +108,8 @@ const emptyConfig: WordOptions = {
verbKind: VerbKind.Root, verbKind: VerbKind.Root,
plural: false, plural: false,
proper: false, proper: false,
vowel: VowelSound.Default
vowel: VowelSound.Default,
possessive: false
} }


export type TextLike = { toString: () => string } export type TextLike = { toString: () => string }
@@ -228,6 +230,18 @@ export abstract class Word {
opts.verbKind = VerbKind.PastParticiple opts.verbKind = VerbKind.PastParticiple
return this.configure(opts) as this 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 { export class RandomWord extends Word {
@@ -254,18 +268,25 @@ export class RandomWord extends Word {
} }


export class Noun 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) super(options)
} }


configure (opts: WordOptions): Word { configure (opts: WordOptions): Word {
return new Noun(this.singularNoun, this.pluralNoun, opts)
return new Noun(this.singularNoun, this.pluralNoun, this.possessiveNoun, opts)
} }


toString (): string { toString (): string {
let result: 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) { if (this.pluralNoun === null) {
result = this.singularNoun result = this.singularNoun
} else { } else {
@@ -308,14 +329,14 @@ export class Noun extends Word {
} }


export class ImproperNoun extends Noun { 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 { export class ProperNoun extends Noun {
constructor (singularNoun: string) { 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({ export const MalePronouns = new Pronoun({
subjective: 'he', subjective: 'he',
objective: 'him', objective: 'him',
@@ -446,3 +478,17 @@ export const ObjectPronouns = new Pronoun({
possessive: 'its', possessive: 'its',
reflexive: 'itself' 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'
})

+ 20
- 3
src/game/vore.ts 查看文件

@@ -1,7 +1,7 @@
import { Entity, Mortal, POV, Creature } from './entity' import { Entity, Mortal, POV, Creature } from './entity'
import { Damage, DamageType, Stats, Actionable, Action, Vigor, VoreStats } from './combat' import { Damage, DamageType, Stats, Actionable, Action, Vigor, VoreStats } from './combat'
import { LogLines, LogEntry, CompositeLog, LogLine } from './interface' 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 { DigestAction, DevourAction, ReleaseAction, StruggleAction } from './combat/actions'
import * as Words from './words' import * as Words from './words'


@@ -13,12 +13,29 @@ export enum VoreType {
} }


export abstract class Vore implements Mortal { export abstract class Vore implements Mortal {
abstract name: Noun;
abstract baseName: Noun;
abstract basePronouns: Pronoun;
abstract title: TextLike; abstract title: TextLike;
abstract desc: TextLike; abstract desc: TextLike;
abstract kind: Noun; abstract kind: Noun;
abstract pronouns: Pronoun;
abstract perspective: POV; 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 vigors: {[key in Vigor]: number};
abstract maxVigors: {[key in Vigor]: number}; abstract maxVigors: {[key in Vigor]: number};
abstract disabled: boolean; abstract disabled: boolean;


正在加载...
取消
保存