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