| @@ -72,7 +72,8 @@ export default class App extends Vue { | |||
| const withers = new Creatures.Withers() | |||
| const kenzie = new Creatures.Kenzie() | |||
| const cafat = new Creatures.Cafat() | |||
| this.combatants = [fighter, withers, wizard, rogue, cleric, kenzie, cafat] | |||
| const wolf = new Creatures.Wolf() | |||
| this.combatants = [fighter, withers, wizard, rogue, cleric, kenzie, cafat, wolf] | |||
| } | |||
| } | |||
| </script> | |||
| @@ -42,7 +42,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 { LogEntry } from '@/game/interface' | |||
| import Statblock from './Statblock.vue' | |||
| import ActionButton from './ActionButton.vue' | |||
| @@ -1,4 +1,4 @@ | |||
| import { Creature, POV } from '../entity' | |||
| import { Creature } from '../entity' | |||
| import { LogEntry, LogLine, FAElem } from '../interface' | |||
| import { Effect } from '../combat' | |||
| import { SoloLine, ToBe } from '../language' | |||
| @@ -1,26 +1,17 @@ | |||
| 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 { ProperNoun, TheyPronouns, ImproperNoun, POVPair, FemalePronouns, Verb, POV, PairLineArgs, PairLine } from '../language' | |||
| import { VoreType, Stomach, InnerStomach, VoreContainer } from '../vore' | |||
| import { LogLine, LogLines, LogEntry, FAElem, CompositeLog, ImgElem } from '../interface' | |||
| import { AttackAction, EatenAction, TransferAction, FeedAction } from '../combat/actions' | |||
| import { InstantKill } from '../combat/effects' | |||
| import * as Words from '../words' | |||
| class BellyCrushAction extends AttackAction { | |||
| successLines = new POVPairArgs<Entity, Entity, { damage: Damage }>([ | |||
| [[POV.Second, POV.Third], (user, target, args) => new CompositeLog(new LogLine( | |||
| `You crush on ${target.name} with your belly for `, | |||
| successLine: PairLineArgs<Creature, { damage: Damage }> = (user, target, args) => new LogLines(new LogLine( | |||
| `${user.name.capital} ${user.name.conjugate(new Verb('crush', 'crushes'))} on ${target.name.objective} with ${user.pronouns.possessive} belly for `, | |||
| args.damage.renderShort() | |||
| ), new ImgElem('./media/cafat/images/belly-crush.webp'))], | |||
| [[POV.Third, POV.Second], (user, target, args) => new CompositeLog(new LogLine( | |||
| `${user.name.capital} crushes on you with ${user.pronouns.possessive} belly for `, | |||
| args.damage.renderShort() | |||
| ), new ImgElem('./media/cafat/images/belly-crush.webp'))], | |||
| [[POV.Third, POV.Third], (user, target, args) => new CompositeLog(new LogLine( | |||
| `${user.name.capital} crushes on ${target.name} with ${user.pronouns.possessive} belly for `, | |||
| args.damage.renderShort() | |||
| ), new ImgElem('./media/cafat/images/belly-crush.webp'))] | |||
| ]) | |||
| ), new ImgElem('./media/cafat/images/belly-crush.webp')) | |||
| constructor (_damage: Damage) { | |||
| super({ | |||
| @@ -38,20 +29,13 @@ class BellyCrushAction extends AttackAction { | |||
| } | |||
| class BelchAction extends AttackAction { | |||
| successLines = new POVPairArgs<Entity, Entity, { damage: Damage }>([ | |||
| [[POV.Second, POV.Third], (user, target, args) => new CompositeLog(new LogLine( | |||
| `You belch on ${target.name} for `, | |||
| args.damage.renderShort() | |||
| ), new ImgElem('./media/cafat/images/belch.webp'))], | |||
| [[POV.Third, POV.Second], (user, target, args) => new CompositeLog(new LogLine( | |||
| `${user.name.capital} belches on you for `, | |||
| successLine: PairLineArgs<Creature, { damage: Damage }> = (user, target, args) => new LogLines( | |||
| new LogLine( | |||
| `${user.name.capital} ${user.name.conjugate} on ${target.name.objective} for `, | |||
| args.damage.renderShort() | |||
| ), new ImgElem('./media/cafat/images/belch.webp'))], | |||
| [[POV.Third, POV.Third], (user, target, args) => new CompositeLog(new LogLine( | |||
| `${user.name.capital} belches on ${target.name} for `, | |||
| args.damage.renderShort() | |||
| ), new ImgElem('./media/cafat/images/belch.webp'))] | |||
| ]) | |||
| ), | |||
| new ImgElem('./media/cafat/images/belch.webp') | |||
| ) | |||
| constructor (damage: Damage) { | |||
| super(new ConstantDamageFormula(damage)) | |||
| @@ -61,19 +45,18 @@ class BelchAction extends AttackAction { | |||
| } | |||
| class CrushAction extends EatenAction { | |||
| lines: POVPair<Entity, Entity> = new POVPair([ | |||
| [[POV.Second, POV.Third], (user, target) => new LogLine(`You crush ${target.name} `)], | |||
| [[POV.Third, POV.Second], (user) => new CompositeLog(new LogLine(`${user.name.capital} crushes you; ${user.pronouns.subjective} ${user.pronouns.isPlural ? 'belch' : 'belches'} as ${user.pronouns.possessive} gut lets out a fatal CRUNCH `), new ImgElem('./media/cafat/images/crunch.webp'))], | |||
| [[POV.Third, POV.Third], (user, target) => new LogLine(`${user.name.capital} crushes ${target.name}; ${user.pronouns.subjective} ${user.pronouns.isPlural ? 'belch' : 'belches'} as ${user.pronouns.possessive} gut lets out a fatal CRUNCH `, new ImgElem('./media/cafat/images/crunch.webp'))] | |||
| ]) | |||
| constructor (container: VoreContainer) { | |||
| super(container, "Crush", "Crush 'em!") | |||
| line: PairLineArgs<Creature, { container: VoreContainer }> = (user, target, args) => new LogLine( | |||
| `${user.name.capital.possessive} ${args.container.name} ${Words.Brutally} ${user.name.conjugate(new Verb('crush', 'crushes'))} ${target.name.objective}; ${user.pronouns.subjective} ${user.pronouns.conjugate(new Verb('belch', 'belches'))} as ${user.pronouns.possessive} gut lets out a fatal CRUNCH `, | |||
| new ImgElem('./media/cafat/images/crunch.webp') | |||
| ) | |||
| constructor (private _container: VoreContainer) { | |||
| super(_container, "Crush", "Crush 'em!") | |||
| this.desc = "Crush somebody in your gut" | |||
| } | |||
| execute (user: Creature, target: Creature): LogEntry { | |||
| return new LogLines(this.lines.run(user, target), new InstantKill().apply(target)) | |||
| return new LogLines(this.line(user, target, { container: this._container }), new InstantKill().apply(target)) | |||
| } | |||
| describe (user: Creature, target: Creature): LogEntry { | |||
| @@ -1,6 +1,6 @@ | |||
| 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, POV } from '../language' | |||
| import { ImproperNoun, POVPair, 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' | |||
| @@ -1,52 +1,23 @@ | |||
| import { Creature, Entity } from '../entity' | |||
| import { Stat, Damage, DamageType, ConstantDamageFormula, Vigor } from '../combat' | |||
| import { MalePronouns, ImproperNoun, POVPair, POVPairArgs, POV } from '../language' | |||
| import { LogLine, LogLines } from '../interface' | |||
| import { Creature } from '../entity' | |||
| import { Damage, DamageType, ConstantDamageFormula, Vigor, Side } from '../combat' | |||
| import { MalePronouns, ImproperNoun } from '../language' | |||
| import { VoreType, Stomach, Bowels } from '../vore' | |||
| import { StatTest } from '../combat/tests' | |||
| import { AttackAction, TransferAction, FeedAction } from '../combat/actions' | |||
| class BiteAction extends AttackAction { | |||
| constructor () { | |||
| super(new ConstantDamageFormula(new Damage({ amount: 10, type: DamageType.Slash, target: Vigor.Health }))) | |||
| this.name = "Bite" | |||
| } | |||
| } | |||
| class HypnoAction extends AttackAction { | |||
| protected successLines: POVPairArgs<Entity, Entity, { damage: Damage }> = new POVPairArgs([ | |||
| [[POV.Second, POV.Third], (user, target, args) => new LogLine( | |||
| `You hypnotize ${target.name} for `, | |||
| args.damage.renderShort() | |||
| )], | |||
| [[POV.Third, POV.Second], (user, target, args) => new LogLine( | |||
| `${user.name.capital} hypnotizes you for `, | |||
| args.damage.renderShort() | |||
| )], | |||
| [[POV.Third, POV.Third], (user, target, args) => new LogLine( | |||
| `${user.name.capital} hypnotizes ${target.name} for `, | |||
| args.damage.renderShort() | |||
| )] | |||
| ]) | |||
| protected failLines: POVPair<Entity, Entity> = new POVPair([ | |||
| [[POV.Second, POV.Third], (user, target) => new LogLine(`You try to hypnotize ${target.name}, but you miss`)], | |||
| [[POV.Third, POV.Second], (user, target) => new LogLine(`${user.name.capital} misses you`)], | |||
| [[POV.Third, POV.Third], (user, target) => new LogLine(`${target.name} misses ${target.name}`)] | |||
| ]) | |||
| constructor () { | |||
| super(new ConstantDamageFormula(new Damage({ amount: 30, type: DamageType.Dominance, target: Vigor.Resolve }))) | |||
| this.test = new StatTest(Stat.Willpower) | |||
| this.name = "Hypnotize" | |||
| } | |||
| } | |||
| export class Wolf extends Creature { | |||
| constructor () { | |||
| super(new ImproperNoun('wolf', 'wolves'), new ImproperNoun('wolf', 'wolves'), MalePronouns, { Toughness: 20, Power: 20, Speed: 20, Willpower: 20, Charm: 20 }, new Set([VoreType.Oral, VoreType.Anal]), new Set([VoreType.Oral, VoreType.Anal]), 25) | |||
| this.actions.push(new BiteAction()) | |||
| this.actions.push(new HypnoAction()) | |||
| this.actions.push( | |||
| new AttackAction( | |||
| new ConstantDamageFormula( | |||
| new Damage( | |||
| { amount: 20, type: DamageType.Pierce, target: Vigor.Health } | |||
| ) | |||
| ) | |||
| ) | |||
| ) | |||
| this.side = Side.Monsters | |||
| const stomach = new Stomach(this, 50, new Damage( | |||
| { amount: 20, type: DamageType.Acid, target: Vigor.Health }, | |||
| @@ -24,37 +24,6 @@ export class POVPair<K extends Entity, V extends Entity> { | |||
| } | |||
| } | |||
| export class POVPairArgs<K extends Entity, V extends Entity, U> { | |||
| run (user: K, target: V, args: U): LogEntry { | |||
| const choice = this.options.find(element => element[0][0] === user.perspective && element[0][1] === target.perspective) | |||
| if (choice === undefined) { | |||
| return new LogLine("Fen didn't write any text for this...") | |||
| } else { | |||
| return choice[1](user, target, args) | |||
| } | |||
| } | |||
| constructor (private options: Array<[[POV, POV], (user: K, target: V, args: U) => LogEntry]>) { | |||
| } | |||
| } | |||
| export class POVSolo<K extends Entity> { | |||
| run (user: K): LogEntry { | |||
| const choice = this.options.find(element => element[0][0] === user.perspective) | |||
| if (choice === undefined) { | |||
| return new LogLine("Fen didn't write any text for this...") | |||
| } else { | |||
| return choice[1](user) | |||
| } | |||
| } | |||
| constructor (private options: Array<[[POV], (user: K) => LogEntry]>) { | |||
| } | |||
| } | |||
| enum NounKind { | |||
| Specific, | |||
| Nonspecific, | |||
| @@ -477,6 +446,14 @@ export class Pronoun implements Pluralizable { | |||
| return this.caps(this.pronouns.reflexive) | |||
| } | |||
| conjugate (verb: Word): Word { | |||
| if (this.isPlural) { | |||
| return verb.root | |||
| } else { | |||
| return verb.singular | |||
| } | |||
| } | |||
| private caps (input: string): string { | |||
| if (this.capitalize) { | |||
| return input.slice(0, 1).toUpperCase() + input.slice(1) | |||
| @@ -42,3 +42,12 @@ export const Bulge = new RandomWord([ | |||
| new ImproperNoun("outline", "outlines"), | |||
| new ImproperNoun("imprint", "imprints") | |||
| ]) | |||
| export const Brutally = new RandomWord([ | |||
| new Adjective('brutally'), | |||
| new Adjective('viciously'), | |||
| new Adjective('callously'), | |||
| new Adjective('savagely'), | |||
| new Adjective('ruthlessly'), | |||
| new Adjective('mercilessly') | |||
| ]) | |||