| @@ -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}`) | 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 { Kuro } from './creatures/kuro' | ||||
| import { Geta } from './creatures/geta' | import { Geta } from './creatures/geta' | ||||
| import { Werewolf } from './creatures/werewolf' | 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 = [ | const bossEncounters = [ | ||||
| new Encounter( | new Encounter( | ||||
| { name: "Withers & Kenzie", intro: () => nilLog }, | { name: "Withers & Kenzie", intro: () => nilLog }, | ||||
| @@ -11,7 +11,8 @@ export enum VoreType { | |||||
| Cock = "Cock Vore", | Cock = "Cock Vore", | ||||
| Unbirth = "Unbirthing", | Unbirth = "Unbirthing", | ||||
| Breast = "Breast Vore", | Breast = "Breast Vore", | ||||
| Bladder = "Bladder vore" | |||||
| Bladder = "Bladder Vore", | |||||
| Tail = "Tail Vore" | |||||
| } | } | ||||
| export const anyVore = new Set([ | export const anyVore = new Set([ | ||||
| @@ -20,7 +21,8 @@ export const anyVore = new Set([ | |||||
| VoreType.Cock, | VoreType.Cock, | ||||
| VoreType.Unbirth, | VoreType.Unbirth, | ||||
| VoreType.Breast, | VoreType.Breast, | ||||
| VoreType.Bladder | |||||
| VoreType.Bladder, | |||||
| VoreType.Tail | |||||
| ]) | ]) | ||||
| export interface Container extends Actionable { | export interface Container extends Actionable { | ||||
| @@ -40,8 +42,11 @@ export interface Container extends Actionable { | |||||
| struggle: (prey: Creature) => LogEntry; | struggle: (prey: Creature) => LogEntry; | ||||
| consumeVerb: Verb; | consumeVerb: Verb; | ||||
| consumePreposition: Preposition; | |||||
| releaseVerb: Verb; | releaseVerb: Verb; | ||||
| releasePreposition: Preposition; | |||||
| struggleVerb: Verb; | struggleVerb: Verb; | ||||
| strugglePreposition: Preposition; | |||||
| consumeLine (user: Creature, target: Creature): LogEntry; | 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 { | tickLine (user: Creature, target: Creature, args: { damage: Damage }): LogEntry { | ||||
| return new RandomEntry( | 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} ${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 { | export class Cock extends NormalVoreContainer { | ||||
| fluidName = new Noun("cum") | fluidName = new Noun("cum") | ||||
| @@ -15,7 +15,8 @@ export const Slick = new RandomWord([ | |||||
| new Adjective('slick'), | new Adjective('slick'), | ||||
| new Adjective('slippery'), | new Adjective('slippery'), | ||||
| new Adjective('slimy'), | new Adjective('slimy'), | ||||
| new Adjective('glistening') | |||||
| new Adjective('glistening'), | |||||
| new Adjective('wet') | |||||
| ]) | ]) | ||||
| export const Swallow = new RandomWord([ | export const Swallow = new RandomWord([ | ||||
| @@ -28,30 +29,42 @@ export const Churns = new RandomWord([ | |||||
| new Verb("churn"), | new Verb("churn"), | ||||
| new Verb("sizzle", "sizzles", "sizzling", "sizzled"), | new Verb("sizzle", "sizzles", "sizzling", "sizzled"), | ||||
| new Verb("simmer"), | new Verb("simmer"), | ||||
| new Verb("stew") | |||||
| new Verb("stew"), | |||||
| new Verb("gurgle", "gurgles", "gurgling", "gurgled") | |||||
| ]) | ]) | ||||
| export const Dark = new RandomWord([ | export const Dark = new RandomWord([ | ||||
| new Adjective("dark"), | new Adjective("dark"), | ||||
| new Adjective("lightless"), | 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([ | export const Digest = new RandomWord([ | ||||
| new Verb("digest"), | new Verb("digest"), | ||||
| new Verb("melt down", "melts down", "melting down", "melted down"), | 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([ | export const Absorb = new RandomWord([ | ||||
| new Verb("absorb"), | 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([ | export const Struggle = new RandomWord([ | ||||
| new Verb("squirm"), | new Verb("squirm"), | ||||
| new Verb("struggle", "struggles", "struggling", "struggled"), | 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([ | export const Bulge = new RandomWord([ | ||||
| @@ -69,6 +82,14 @@ export const Brutally = new RandomWord([ | |||||
| new Adjective('mercilessly') | 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([ | export const Force = new RandomWord([ | ||||
| new Verb("force", "forces", "forcing", "forced"), | new Verb("force", "forces", "forcing", "forced"), | ||||
| new Verb("cram", "crams", "cramming", "crammed"), | new Verb("cram", "crams", "cramming", "crammed"), | ||||
| @@ -79,12 +100,15 @@ export const Clench = new RandomWord([ | |||||
| new Verb("clench", "clenches", "clenching", "clenched"), | new Verb("clench", "clenches", "clenching", "clenched"), | ||||
| new Verb("smother", "smothers", "smothering", "smothered"), | new Verb("smother", "smothers", "smothering", "smothered"), | ||||
| new Verb("squeeze", "squeezes", "squeezing", "squeezed"), | 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([ | export const Succumb = new RandomWord([ | ||||
| new Verb("succumb"), | 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([ | export const Flaunt = new RandomWord([ | ||||