Also adds more variety for some words.master
| @@ -310,3 +310,39 @@ export class TransferAction extends Action { | |||
| return new LogLine(`Push ${target.baseName} from your ${this.from.name} to your ${this.to.name}`) | |||
| } | |||
| } | |||
| export class WillingTransferAction extends Action { | |||
| giveIn: Verb = new Verb('give in', 'gives in', 'gave in', 'giving in') | |||
| allow: Verb = new Verb('allow') | |||
| verb: Verb = new Verb('send') | |||
| constructor (protected from: Container, protected to: Container, name = 'Transfer') { | |||
| super( | |||
| name, | |||
| `${from.name.all.capital} to ${to.name.all}`, | |||
| [new CapableCondition(), new PairCondition()] | |||
| ) | |||
| } | |||
| line: PairLineArgs<Creature, { from: Container; to: Container }> = (user, target, args) => new LogLine( | |||
| `${user.name.capital} ${user.name.conjugate(this.giveIn)} and ${user.name.conjugate(this.allow)} ${target.name.objective} to send ${user.name.objective} from ${target.pronouns.possessive} ${args.from.name} to ${target.pronouns.possessive} ${args.to.name}` | |||
| ) | |||
| allowed (user: Creature, target: Creature) { | |||
| if (user.containedIn === this.from && this.from.contents.includes(user)) { | |||
| return super.allowed(user, target) | |||
| } else { | |||
| return false | |||
| } | |||
| } | |||
| execute (user: Creature, target: Creature): LogEntry { | |||
| this.from.release(user) | |||
| this.to.consume(user) | |||
| return this.line(user, target, { from: this.from, to: this.to }) | |||
| } | |||
| describe (user: Creature, target: Creature): LogEntry { | |||
| return new LogLine(`Allow ${target.baseName} to pull ${user.pronouns.subjective} ${this.to.consumePreposition} ${target.pronouns.possessive} ${this.to.name}`) | |||
| } | |||
| } | |||
| @@ -10,5 +10,6 @@ import { Goldeneye } from './creatures/goldeneye' | |||
| import { Kuro } from './creatures/kuro' | |||
| import { Geta } from './creatures/geta' | |||
| import { Werewolf } from './creatures/werewolf' | |||
| import { Taluthus } from './creatures/taluthus' | |||
| export { Wolf, DireWolf, Player, Cafat, Human, Withers, Kenzie, Dragon, Shingo, Goldeneye, Kuro, Geta, Werewolf } | |||
| export { Wolf, DireWolf, Player, Cafat, Human, Withers, Kenzie, Dragon, Shingo, Goldeneye, Kuro, Geta, Werewolf, Taluthus } | |||
| @@ -0,0 +1,100 @@ | |||
| import { Creature } from "../creature" | |||
| import { DamageType, Vigor, Side, StatDamageFormula, Stat } from '../combat' | |||
| import { MalePronouns, ProperNoun, Verb } from '../language' | |||
| import { Stomach, Bowels, Cock, Balls, anyVore, biconnectContainers, Tail } from '../vore' | |||
| import { AttackAction, TransferAction, FeedAction, WillingTransferAction } from '../combat/actions' | |||
| import { VoreAI } from '../ai' | |||
| export class Taluthus extends Creature { | |||
| constructor () { | |||
| super( | |||
| new ProperNoun('Taluthus'), | |||
| new ProperNoun('Taluthus'), | |||
| MalePronouns, | |||
| { Toughness: 40, Power: 50, Reflexes: 40, Agility: 30, Willpower: 50, Charm: 60 }, | |||
| new Set(), | |||
| anyVore, | |||
| 100 | |||
| ) | |||
| this.actions.push( | |||
| new AttackAction( | |||
| new StatDamageFormula([ | |||
| { fraction: 1, stat: Stat.Power, target: Vigor.Health, type: DamageType.Pierce }, | |||
| { fraction: 0.5, stat: Stat.Power, target: Vigor.Health, type: DamageType.Crush } | |||
| ]), | |||
| new Verb("bite") | |||
| ) | |||
| ) | |||
| this.ai = new VoreAI() | |||
| this.side = Side.Monsters | |||
| const stomach = new Stomach( | |||
| this, | |||
| 1, | |||
| new StatDamageFormula([ | |||
| { fraction: 1, stat: Stat.Toughness, target: Vigor.Health, type: DamageType.Acid }, | |||
| { fraction: 1, stat: Stat.Power, target: Vigor.Health, type: DamageType.Crush }, | |||
| { fraction: 0.5, stat: Stat.Toughness, target: Vigor.Stamina, type: DamageType.Acid }, | |||
| { fraction: 0.5, stat: Stat.Power, target: Vigor.Stamina, type: DamageType.Crush }, | |||
| { fraction: 0.5, stat: Stat.Toughness, target: Vigor.Resolve, type: DamageType.Acid }, | |||
| { fraction: 0.5, stat: Stat.Power, target: Vigor.Resolve, type: DamageType.Crush } | |||
| ]) | |||
| ) | |||
| this.containers.push(stomach) | |||
| const tail = new Tail( | |||
| this, | |||
| 1.5, | |||
| new StatDamageFormula([ | |||
| { fraction: 0.05, stat: Stat.Toughness, target: Vigor.Health, type: DamageType.Acid }, | |||
| { fraction: 0.1, stat: Stat.Power, target: Vigor.Health, type: DamageType.Crush }, | |||
| { fraction: 0.5, stat: Stat.Toughness, target: Vigor.Stamina, type: DamageType.Acid }, | |||
| { fraction: 1, stat: Stat.Power, target: Vigor.Stamina, type: DamageType.Crush }, | |||
| { fraction: 0.5, stat: Stat.Toughness, target: Vigor.Resolve, type: DamageType.Acid }, | |||
| { fraction: 1, stat: Stat.Power, target: Vigor.Resolve, type: DamageType.Crush } | |||
| ]) | |||
| ) | |||
| this.containers.push(tail) | |||
| this.actions.push(new TransferAction(tail, stomach)) | |||
| this.otherActions.push(new WillingTransferAction(tail, stomach)) | |||
| this.otherActions.push(new FeedAction(stomach)) | |||
| const cock = new Cock( | |||
| this, | |||
| 1.5, | |||
| new StatDamageFormula([ | |||
| { fraction: 1, stat: Stat.Charm, target: Vigor.Health, type: DamageType.Acid }, | |||
| { fraction: 1, stat: Stat.Power, target: Vigor.Health, type: DamageType.Crush }, | |||
| { fraction: 0.5, stat: Stat.Charm, target: Vigor.Stamina, type: DamageType.Acid }, | |||
| { fraction: 0.5, stat: Stat.Power, target: Vigor.Stamina, type: DamageType.Crush }, | |||
| { fraction: 1, stat: Stat.Charm, target: Vigor.Resolve, type: DamageType.Acid }, | |||
| { fraction: 1, stat: Stat.Power, target: Vigor.Resolve, type: DamageType.Crush } | |||
| ]) | |||
| ) | |||
| const balls = new Balls( | |||
| this, | |||
| 1.5, | |||
| new StatDamageFormula([ | |||
| { fraction: 1, stat: Stat.Toughness, target: Vigor.Health, type: DamageType.Acid }, | |||
| { fraction: 1, stat: Stat.Power, target: Vigor.Health, type: DamageType.Crush }, | |||
| { fraction: 1, stat: Stat.Toughness, target: Vigor.Stamina, type: DamageType.Acid }, | |||
| { fraction: 1, stat: Stat.Power, target: Vigor.Stamina, type: DamageType.Crush }, | |||
| { fraction: 1.5, stat: Stat.Toughness, target: Vigor.Resolve, type: DamageType.Acid }, | |||
| { fraction: 1.5, stat: Stat.Power, target: Vigor.Resolve, type: DamageType.Crush } | |||
| ]), | |||
| cock | |||
| ) | |||
| // this.containers.push(balls) | |||
| // this.containers.push(cock) | |||
| biconnectContainers(cock, balls) | |||
| } | |||
| } | |||
| @@ -192,6 +192,24 @@ export const Town = (): Place => { | |||
| ) | |||
| ) | |||
| woods.choices.push( | |||
| new Choice( | |||
| "Fight Taluthus", | |||
| "yolo", | |||
| (world, executor) => { | |||
| world.encounter = new Encounter( | |||
| { | |||
| name: "You punched Taluthus", | |||
| intro: () => new LogLine(`You punched Tal.`) | |||
| }, | |||
| [executor, new Creatures.Taluthus()] | |||
| ) | |||
| return new LogLine(`FIGHT TIME`) | |||
| } | |||
| ) | |||
| ) | |||
| const bossEncounters = [ | |||
| new Encounter( | |||
| { name: "Withers & Kenzie", intro: () => nilLog }, | |||
| @@ -11,7 +11,8 @@ export enum VoreType { | |||
| Cock = "Cock Vore", | |||
| Unbirth = "Unbirthing", | |||
| Breast = "Breast Vore", | |||
| Bladder = "Bladder vore" | |||
| Bladder = "Bladder Vore", | |||
| Tail = "Tail Vore" | |||
| } | |||
| export const anyVore = new Set([ | |||
| @@ -20,7 +21,8 @@ export const anyVore = new Set([ | |||
| VoreType.Cock, | |||
| VoreType.Unbirth, | |||
| VoreType.Breast, | |||
| VoreType.Bladder | |||
| VoreType.Bladder, | |||
| VoreType.Tail | |||
| ]) | |||
| export interface Container extends Actionable { | |||
| @@ -40,8 +42,11 @@ export interface Container extends Actionable { | |||
| struggle: (prey: Creature) => LogEntry; | |||
| consumeVerb: Verb; | |||
| consumePreposition: Preposition; | |||
| releaseVerb: Verb; | |||
| releasePreposition: Preposition; | |||
| struggleVerb: Verb; | |||
| strugglePreposition: Preposition; | |||
| consumeLine (user: Creature, target: Creature): LogEntry; | |||
| @@ -209,8 +214,8 @@ export abstract class NormalVoreContainer extends NormalContainer implements Vor | |||
| tickLine (user: Creature, target: Creature, args: { damage: Damage }): LogEntry { | |||
| return new RandomEntry( | |||
| new LogLine(`${user.name.capital} ${user.name.conjugate(Words.Churns)} ${target.name.objective} ${this.strugglePreposition} ${user.pronouns.possessive} ${this.name} for `, args.damage.renderShort(), `.`), | |||
| new LogLine(`${user.name.capital.possessive} ${this.name} ${this.name.conjugate(Words.Churns)}, stewing ${target.name.objective} for `, args.damage.renderShort(), `.`), | |||
| new LogLine(`${target.name.capital} ${target.name.conjugate(new Verb("thrash", "thrashes"))} ${this.strugglePreposition} ${user.name.possessive} ${Words.Slick} ${this.name} as it churns ${target.pronouns.objective} for `, args.damage.renderShort(), `.`) | |||
| new LogLine(`${user.name.capital.possessive} ${this.name} ${this.name.conjugate(Words.Churns)}, ${Words.Churns.present} ${target.name.objective} for `, args.damage.renderShort(), `.`), | |||
| new LogLine(`${target.name.capital} ${target.name.conjugate(new Verb("thrash", "thrashes"))} ${this.strugglePreposition} ${user.name.possessive} ${Words.Slick} ${this.name} as it ${Words.Churns.singular} ${target.pronouns.objective} for `, args.damage.renderShort(), `.`) | |||
| ) | |||
| } | |||
| @@ -379,6 +384,20 @@ export class Bowels extends NormalVoreContainer { | |||
| } | |||
| } | |||
| export class Tail extends NormalVoreContainer { | |||
| fluidName = new Noun("chyme") | |||
| constructor (owner: Creature, capacity: number, damage: DamageFormula) { | |||
| super(new ImproperNoun('tail', 'tails').all, owner, new Set([VoreType.Tail]), capacity, damage) | |||
| } | |||
| tickLine (user: Creature, target: Creature, args: { damage: Damage }) { | |||
| return new RandomEntry( | |||
| new LogLine(`${user.name.capital} ${user.name.conjugate(Words.Clench)} ${target.name.objective} in ${user.pronouns.possessive} ${this.name} for `, args.damage.renderShort(), `.`) | |||
| ) | |||
| } | |||
| } | |||
| export class Cock extends NormalVoreContainer { | |||
| fluidName = new Noun("cum") | |||
| @@ -15,7 +15,8 @@ export const Slick = new RandomWord([ | |||
| new Adjective('slick'), | |||
| new Adjective('slippery'), | |||
| new Adjective('slimy'), | |||
| new Adjective('glistening') | |||
| new Adjective('glistening'), | |||
| new Adjective('wet') | |||
| ]) | |||
| export const Swallow = new RandomWord([ | |||
| @@ -28,30 +29,42 @@ export const Churns = new RandomWord([ | |||
| new Verb("churn"), | |||
| new Verb("sizzle", "sizzles", "sizzling", "sizzled"), | |||
| new Verb("simmer"), | |||
| new Verb("stew") | |||
| new Verb("stew"), | |||
| new Verb("gurgle", "gurgles", "gurgling", "gurgled") | |||
| ]) | |||
| export const Dark = new RandomWord([ | |||
| new Adjective("dark"), | |||
| new Adjective("lightless"), | |||
| new Adjective("pitch-black") | |||
| new Adjective("pitch-black"), | |||
| new Adjective("black"), | |||
| new Adjective("tenebrous"), | |||
| new Adjective("unlit"), | |||
| new Adjective("dark-as-night") | |||
| ]) | |||
| export const Digest = new RandomWord([ | |||
| new Verb("digest"), | |||
| new Verb("melt down", "melts down", "melting down", "melted down"), | |||
| new Verb("dissolve", "dissolves", "dissolving", "dissolved") | |||
| new Verb("dissolve", "dissolves", "dissolving", "dissolved"), | |||
| new Verb("mulch", "mulches", "mulching", "mulched"), | |||
| new Verb("break down", "breaks down", "breaking down", "broken down") | |||
| ]) | |||
| export const Absorb = new RandomWord([ | |||
| new Verb("absorb"), | |||
| new Verb("soak up", "soaks up", "soaking up", "soaked up") | |||
| new Verb("soak up", "soaks up", "soaking up", "soaked up"), | |||
| new Verb("erase", "erases", "erasing", "erased") | |||
| ]) | |||
| export const Struggle = new RandomWord([ | |||
| new Verb("squirm"), | |||
| new Verb("struggle", "struggles", "struggling", "struggled"), | |||
| new Verb("thrash", "thrashes") | |||
| new Verb("thrash", "thrashes"), | |||
| new Verb("writhe", "writhes", "writhing", "writhed"), | |||
| new Verb("flounder"), | |||
| new Verb("wriggle", "wriggles", "wriggling", "wriggled"), | |||
| new Verb("flail") | |||
| ]) | |||
| export const Bulge = new RandomWord([ | |||
| @@ -69,6 +82,14 @@ export const Brutally = new RandomWord([ | |||
| new Adjective('mercilessly') | |||
| ]) | |||
| export const Fatal = new RandomWord([ | |||
| new Adjective("deadly"), | |||
| new Adjective("fatal"), | |||
| new Adjective("brutal"), | |||
| new Adjective("unsurvivable"), | |||
| new Adjective("death-sentence of a") | |||
| ]) | |||
| export const Force = new RandomWord([ | |||
| new Verb("force", "forces", "forcing", "forced"), | |||
| new Verb("cram", "crams", "cramming", "crammed"), | |||
| @@ -79,12 +100,15 @@ export const Clench = new RandomWord([ | |||
| new Verb("clench", "clenches", "clenching", "clenched"), | |||
| new Verb("smother", "smothers", "smothering", "smothered"), | |||
| new Verb("squeeze", "squeezes", "squeezing", "squeezed"), | |||
| new Verb("bear down on", "bears down on", "bearing down on", "bore down on") | |||
| new Verb("bear down on", "bears down on", "bearing down on", "bore down on"), | |||
| new Verb("crush on", "crushes on", "crushing on", "crushed on") | |||
| ]) | |||
| export const Succumb = new RandomWord([ | |||
| new Verb("succumb"), | |||
| new Verb("surrender") | |||
| new Verb("surrender"), | |||
| new Verb("give in to", "gives in to", "giving in to", "gave in to"), | |||
| new Verb("yield") | |||
| ]) | |||
| export const Flaunt = new RandomWord([ | |||