ソースを参照

Add a ToBe class for that annoying verb; put Cafat back in

master
Fen Dweller 5年前
コミット
5183efdd96
14個のファイルの変更127行の追加66行の削除
  1. +3
    -2
      src/App.vue
  2. +2
    -1
      src/components/ContainerView.vue
  3. +2
    -1
      src/components/Statblock.vue
  4. +0
    -0
      src/game/POV.ts
  5. +2
    -5
      src/game/combat/actions.ts
  6. +6
    -6
      src/game/combat/effects.ts
  7. +5
    -3
      src/game/creatures/cafat.ts
  8. +4
    -6
      src/game/creatures/kenzie.ts
  9. +2
    -2
      src/game/creatures/player.ts
  10. +2
    -2
      src/game/creatures/withers.ts
  11. +2
    -2
      src/game/creatures/wolf.ts
  12. +1
    -3
      src/game/entity.ts
  13. +88
    -24
      src/game/language.ts
  14. +8
    -9
      src/game/vore.ts

+ 3
- 2
src/App.vue ファイルの表示

@@ -11,7 +11,7 @@ import Combat from './components/Combat.vue'
import Header from './components/Header.vue'
import * as Creatures from '@/game/creatures'
import * as Items from '@/game/items'
import { Creature, POV } from '@/game/entity'
import { Creature } from '@/game/entity'
import { ProperNoun, TheyPronouns, FemalePronouns, MalePronouns, ImproperNoun } from '@/game/language'

@Component({
@@ -71,7 +71,8 @@ export default class App extends Vue {

const withers = new Creatures.Withers()
const kenzie = new Creatures.Kenzie()
this.combatants = [fighter, withers, wizard, rogue, cleric, kenzie]
const cafat = new Creatures.Cafat()
this.combatants = [fighter, withers, wizard, rogue, cleric, kenzie, cafat]
}
}
</script>


+ 2
- 1
src/components/ContainerView.vue ファイルの表示

@@ -8,7 +8,8 @@

<script lang="ts">
import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator'
import { Creature, POV } from '@/game/entity'
import { Creature } from '@/game/entity'
import { POV } from '@/game/language'
import { Stats, Stat } from '@/game/combat'
import { Container } from '@/game/vore'



+ 2
- 1
src/components/Statblock.vue ファイルの表示

@@ -54,7 +54,8 @@

<script lang="ts">
import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator'
import { Creature, POV } from '@/game/entity'
import { Creature } from '@/game/entity'
import { POV } from '@/game/language'
import { Stats, Stat, StatIcons, StatDescs, Vigor, VigorIcons, VigorDescs, VoreStatDescs, VoreStatIcons } from '@/game/combat'
import ContainerView from './ContainerView.vue'
import tippy, { createSingleton } from 'tippy.js'


+ 0
- 0
src/game/POV.ts ファイルの表示


+ 2
- 5
src/game/combat/actions.ts ファイルの表示

@@ -1,6 +1,6 @@
import { StatTest, StatVigorTest } from './tests'
import { POVPairArgs, POVPair, DynText, LiveText, TextLike, Verb, PairLine, PairLineArgs } from '../language'
import { Entity, POV, Creature } from '../entity'
import { DynText, LiveText, TextLike, Verb, PairLine, PairLineArgs } from '../language'
import { Entity, Creature } from '../entity'
import { Damage, DamageFormula, Stat, Vigor, Action } from '../combat'
import { LogLine, LogLines, LogEntry, CompositeLog } from '../interface'
import { VoreContainer, Container } from '../vore'
@@ -85,8 +85,6 @@ export class DevourAction extends Action {
}

export class FeedAction extends Action {
private test: StatTest

protected successLine: PairLine<Entity> = (user, target) => new LogLine(
`${user.name.capital} ${user.name.conjugate(new Verb('feed'))} ${user.pronouns.reflexive} to ${target.name}. `
)
@@ -114,7 +112,6 @@ export class FeedAction extends Action {
[new UserDrainedVigorCondition(Vigor.Resolve), new TogetherCondition()]
)
this.name += ` (${container.name})`
this.test = new StatTest(Stat.Power)
}

execute (user: Creature, target: Creature): LogEntry {


+ 6
- 6
src/game/combat/effects.ts ファイルの表示

@@ -1,18 +1,18 @@
import { Creature, POV } from '../entity'
import { LogEntry, LogLine, FAElem } from '../interface'
import { Effect } from '../combat'
import { POVSolo } from '../language'
import { SoloLine, ToBe } from '../language'

export class InstantKill implements Effect {
lines = new POVSolo<Creature>([
[[POV.Second], (target: Creature) => new LogLine(`You're killed instantly! `, new FAElem('fas fa-skull'))],
[[POV.Third], (target: Creature) => new LogLine(`${target.name.capital} is killed instantly! `, new FAElem('fas fa-skull'))]
])
line: SoloLine<Creature> = (victim) => new LogLine(
`${victim.name.capital} ${victim.name.conjugate(new ToBe())} killed instantly!`,
new FAElem('fas fa-skull')
)

name = "Instant Kill"
desc = "Instantly kills its victim"
apply (target: Creature): LogEntry {
target.vigors.Health = Math.min(0, target.vigors.Health)
return this.lines.run(target)
return this.line(target)
}
}

+ 5
- 3
src/game/creatures/cafat.ts ファイルの表示

@@ -1,6 +1,6 @@
import { Creature, POV, Entity } from '../entity'
import { Stat, Damage, DamageType, Vigor, ConstantDamageFormula } from '../combat'
import { ProperNoun, TheyPronouns, ImproperNoun, POVPair, FemalePronouns, POVPairArgs, Verb } from '../language'
import { Creature, Entity } from '../entity'
import { Stat, Damage, DamageType, Vigor, ConstantDamageFormula, Side } from '../combat'
import { ProperNoun, TheyPronouns, ImproperNoun, POVPair, FemalePronouns, POVPairArgs, Verb, POV } from '../language'
import { VoreType, Stomach, InnerStomach, VoreContainer, NormalContainer, Vore } from '../vore'
import { LogLine, LogLines, LogEntry, FAElem, CompositeLog, ImgElem } from '../interface'
import { AttackAction, EatenAction, TransferAction, FeedAction } from '../combat/actions'
@@ -91,6 +91,8 @@ export class Cafat extends Creature {
[Stat.Charm]: 20
}, new Set([VoreType.Oral, VoreType.Anal]), new Set([VoreType.Oral, VoreType.Anal]), 150)

this.side = Side.Monsters

const stomach = new Stomach(this, 100, new Damage(
{ amount: 20, type: DamageType.Acid, target: Vigor.Health },
{ amount: 10, type: DamageType.Crush, target: Vigor.Stamina },


+ 4
- 6
src/game/creatures/kenzie.ts ファイルの表示

@@ -1,10 +1,8 @@
import { Creature, POV } from '../entity'
import { Creature } from '../entity'
import { ProperNoun, ImproperNoun, FemalePronouns, Verb } from '../language'
import { VoreType, Stomach, Vore } from '../vore'
import { Side, Damage, DamageType, Vigor, UniformRandomDamageFormula, ConstantDamageFormula, StatDamageFormula, Stat, VoreStat } from '../combat'
import { LogLine } from '../interface'
import { FeedAction, TransferAction, AttackAction } from '../combat/actions'
import * as Words from '../words'
import { VoreType, Stomach } from '../vore'
import { Side, Damage, DamageType, Vigor, StatDamageFormula, Stat, VoreStat } from '../combat'
import { AttackAction } from '../combat/actions'

export class Kenzie extends Creature {
title = "Large Lycanroc"


+ 2
- 2
src/game/creatures/player.ts ファイルの表示

@@ -1,5 +1,5 @@
import { Creature, POV } from '../entity'
import { ProperNoun, TheyPronouns, ImproperNoun } from '../language'
import { Creature } from '../entity'
import { ProperNoun, TheyPronouns, ImproperNoun, POV } from '../language'
import { Stat, Damage, DamageType, Vigor, ConstantDamageFormula } from '../combat'
import { Stomach, Bowels, VoreType } from '../vore'
import { AttackAction } from '../combat/actions'


+ 2
- 2
src/game/creatures/withers.ts ファイルの表示

@@ -1,6 +1,6 @@
import { Creature, POV } from '../entity'
import { Creature } from '../entity'
import { Damage, DamageType, ConstantDamageFormula, Vigor, Side, GroupAction, CombatTest, Stat, DamageFormula, UniformRandomDamageFormula, Action, DamageInstance, StatDamageFormula, VoreStat } from '../combat'
import { ImproperNoun, POVPair, POVPairArgs, ProperNoun, FemalePronouns, RandomWord, Adjective, Verb } from '../language'
import { ImproperNoun, POVPair, POVPairArgs, ProperNoun, FemalePronouns, RandomWord, Adjective, Verb, POV } from '../language'
import { LogLine, LogLines, LogEntry, Newline } from '../interface'
import { VoreType, Stomach, VoreContainer, Vore, NormalContainer, Container } from '../vore'
import { AttackAction, FeedAction, TransferAction, EatenAction } from '../combat/actions'


+ 2
- 2
src/game/creatures/wolf.ts ファイルの表示

@@ -1,6 +1,6 @@
import { Creature, POV, Entity } from '../entity'
import { Creature, Entity } from '../entity'
import { Stat, Damage, DamageType, ConstantDamageFormula, Vigor } from '../combat'
import { MalePronouns, ImproperNoun, POVPair, POVPairArgs } from '../language'
import { MalePronouns, ImproperNoun, POVPair, POVPairArgs, POV } from '../language'
import { LogLine, LogLines } from '../interface'
import { VoreType, Stomach, Bowels } from '../vore'
import { StatTest } from '../combat/tests'


+ 1
- 3
src/game/entity.ts ファイルの表示

@@ -1,11 +1,9 @@
import { DamageType, Damage, Combatant, Stats, Action, Vigor, VoreStats, VoreStat, Stat, Side, GroupAction, Vigors } from './combat'
import { Noun, Pronoun, Adjective, ImproperNoun, TextLike } from './language'
import { Noun, Pronoun, TextLike, POV } from './language'
import { LogEntry, LogLine } from './interface'
import { Vore, VoreContainer, VoreType, Container } from './vore'
import { Item } from './items'

export enum POV {First, Second, Third}

export interface Entity {
name: Noun;
pronouns: Pronoun;


+ 88
- 24
src/game/language.ts ファイルの表示

@@ -1,6 +1,8 @@
import { Entity, POV } from './entity'
import { Entity } from './entity'
import { LogEntry, LogLine } from './interface'

export enum POV {First, Second, Third}

export type SoloLine<T> = (user: T) => LogEntry
export type SoloLineArgs<T, V> = (user: T, args: V) => LogEntry
export type PairLine<T> = (user: T, target: T) => LogEntry
@@ -88,6 +90,7 @@ interface WordOptions {
count: boolean;
possessive: boolean;
objective: boolean;
perspective: POV;
}

const emptyConfig: WordOptions = {
@@ -100,7 +103,8 @@ const emptyConfig: WordOptions = {
proper: false,
vowel: VowelSound.Default,
possessive: false,
objective: false
objective: false,
perspective: POV.Third
}

export type TextLike = { toString: () => string }
@@ -233,6 +237,24 @@ export abstract class Word {
opts.objective = true
return this.configure(opts) as this
}

get pov1 (): this {
const opts: WordOptions = Object.assign({}, this.opt)
opts.perspective = POV.First
return this.configure(opts) as this
}

get pov2 (): this {
const opts: WordOptions = Object.assign({}, this.opt)
opts.perspective = POV.Second
return this.configure(opts) as this
}

get pov3 (): this {
const opts: WordOptions = Object.assign({}, this.opt)
opts.perspective = POV.Third
return this.configure(opts) as this
}
}

export class RandomWord extends Word {
@@ -329,13 +351,13 @@ export class Noun extends Word {

export class ImproperNoun extends Noun {
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, objective: false })
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, objective: false, perspective: POV.Third })
}
}

export class ProperNoun extends Noun {
constructor (singularNoun: string) {
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, objective: false })
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, objective: false, perspective: POV.Third })
}
}

@@ -391,6 +413,38 @@ export class Verb extends Word {
}
}

// this one is obnoxious
export class ToBe extends Word {
configure (opts: WordOptions): Word {
return new ToBe(opts)
}

toString (): string {
let choice

if (this.opts.plural) {
choice = 'are'
}
switch (this.opts.perspective) {
case POV.First: choice = 'am'; break
case POV.Second: choice = 'are'; break
case POV.Third: choice = 'is'; 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 (protected opts: WordOptions = emptyConfig) {
super(opts)
}
}

interface PronounDict {
subjective: string;
objective: string;
@@ -432,26 +486,6 @@ 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
this.options.plural = true
}

configure (opts: WordOptions): Word {
return new PronounAsNoun(this.pronouns, opts)
}

toString (): string {
if (this.options.objective) {
return new Noun(this.pronouns.objective, this.pronouns.objective, this.pronouns.possessive, this.options).toString()
} else {
return super.toString()
}
}
}

export const MalePronouns = new Pronoun({
subjective: 'he',
objective: 'him',
@@ -500,3 +534,33 @@ export const FirstPersonPronouns = new Pronoun({
possessive: 'my',
reflexive: 'myself'
})

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
this.options.plural = true
}

configure (opts: WordOptions): Word {
return new PronounAsNoun(this.pronouns, opts)
}

toString (): string {
if (this.options.objective) {
return new Noun(this.pronouns.objective, this.pronouns.objective, this.pronouns.possessive, this.options).toString()
} else {
return super.toString()
}
}

conjugate (verb: Word): Word {
if (this.pronouns === FirstPersonPronouns) {
return super.conjugate(verb.pov1)
} else if (this.pronouns === SecondPersonPronouns) {
return super.conjugate(verb.pov2)
} else {
return super.conjugate(verb.pov3)
}
}
}

+ 8
- 9
src/game/vore.ts ファイルの表示

@@ -1,7 +1,7 @@
import { Mortal, POV } from './entity'
import { Mortal } from './entity'
import { Damage, DamageType, Stats, Actionable, Action, Vigor, VoreStats } from './combat'
import { LogLines, LogEntry, LogLine } from './interface'
import { Noun, Pronoun, ImproperNoun, POVSolo, TextLike, Verb, SecondPersonPronouns, PronounAsNoun, FirstPersonPronouns, PairLineArgs } from './language'
import { Noun, Pronoun, ImproperNoun, TextLike, Verb, SecondPersonPronouns, PronounAsNoun, FirstPersonPronouns, PairLineArgs, SoloLine, POV } from './language'
import { DigestAction, DevourAction, ReleaseAction, StruggleAction } from './combat/actions'
import * as Words from './words'

@@ -56,10 +56,9 @@ export abstract class Vore implements Mortal {
abstract containers: Array<VoreContainer>;
abstract otherContainers: Array<Container>;
destroy (): LogEntry {
const lines = new POVSolo<Vore>([
[[POV.Second], () => new LogLine('You die!')],
[[POV.Third], (target: Vore) => new LogLine(`${target.name.capital} dies!`)]
])
const line: SoloLine<Vore> = (victim) => new LogLine(
`${victim.name.capital} ${victim.name.conjugate(new Verb('die'))}`
)

const released: Array<Vore> = this.containers.flatMap(container => {
return container.contents.map(prey => {
@@ -79,17 +78,17 @@ export abstract class Vore implements Mortal {
if (released.length > 0) {
if (this.containedIn === null) {
return new LogLines(
lines.run(this),
line(this),
new LogLine(names + ` spill out!`)
)
} else {
return new LogLines(
lines.run(this),
line(this),
new LogLine(names + ` spill out into ${this.containedIn.owner.name}'s ${this.containedIn.name}!`)
)
}
} else {
return lines.run(this)
return line(this)
}
}
}


読み込み中…
キャンセル
保存