Browse Source

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 years ago
parent
commit
ee1a089ef8
5 changed files with 90 additions and 35 deletions
  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 View File

@@ -6,14 +6,7 @@
<div class="statblock-shader statblock-shader-dead"></div>
<div class="statblock-shader statblock-shader-eaten"></div>
<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}}
<div class="tooltip-template">
<div class="tooltip-title">{{ subject.title }}</div>


+ 4
- 7
src/game/creatures/withers.ts View File

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

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 {
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 {


+ 4
- 2
src/game/entity.ts View File

@@ -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<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()
const containers = this.containers



+ 61
- 15
src/game/language.ts View File

@@ -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'
})

+ 20
- 3
src/game/vore.ts View File

@@ -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;


Loading…
Cancel
Save