From 2d2c3eaae84e390d53c766f5bc1341330c0d0a76 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 30 Jul 2020 15:19:20 -0400 Subject: [PATCH] Start working on Shingo --- src/App.vue | 1 + src/game/creatures.ts | 3 +- src/game/creatures/shingo.ts | 137 +++++++++++++++++++++++++++++++++++ src/game/vore.ts | 20 ++++- 4 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 src/game/creatures/shingo.ts diff --git a/src/App.vue b/src/App.vue index 3760c9a..b7e26e4 100644 --- a/src/App.vue +++ b/src/App.vue @@ -42,6 +42,7 @@ export default class App extends Vue { this.$data.encounters.push(new Encounter({ name: 'Boss Fight' }, this.makeParty().concat([new Creatures.Withers(), new Creatures.Kenzie()]))) this.$data.encounters.push(new Encounter({ name: 'Cafat' }, this.makeParty().concat([new Creatures.Cafat(), new Creatures.Wolf()]))) this.$data.encounters.push(new Encounter({ name: 'Dragon' }, this.makeParty().concat([new Creatures.Dragon()]))) + this.$data.encounters.push(new Encounter({ name: 'Large Wah' }, this.makeParty().concat([new Creatures.Shingo()]))) this.$data.encounter = this.$data.encounters[0] } diff --git a/src/game/creatures.ts b/src/game/creatures.ts index 6061b21..e744393 100644 --- a/src/game/creatures.ts +++ b/src/game/creatures.ts @@ -5,4 +5,5 @@ import { Human } from './creatures/human' import { Withers } from './creatures/withers' import { Kenzie } from './creatures/kenzie' import { Dragon } from './creatures/dragon' -export { Wolf, Player, Cafat, Human, Withers, Kenzie, Dragon } +import { Shingo } from './creatures/shingo' +export { Wolf, Player, Cafat, Human, Withers, Kenzie, Dragon, Shingo } diff --git a/src/game/creatures/shingo.ts b/src/game/creatures/shingo.ts new file mode 100644 index 0000000..6db92bc --- /dev/null +++ b/src/game/creatures/shingo.ts @@ -0,0 +1,137 @@ +import { Creature } from "../creature" +import { Damage, DamageType, ConstantDamageFormula, Vigor, Side, StatDamageFormula, Stat, Action, DamageFormula } from '../combat' +import { ImproperNoun, ProperNoun, FemalePronouns, MalePronouns, Verb, PairLineArgs, PairLine } from '../language' +import { VoreType, Stomach, Bowels, NormalContainer, InnerContainer, VoreContainer, Container } from '../vore' +import { AttackAction, TransferAction, FeedAction, StruggleAction } from '../combat/actions' +import { LogLine, LogEntry, LogLines } from '../interface' +import { ContainsCondition, CapableCondition, EnemyCondition } from '../combat/conditions' +import { StatTest } from '../combat/tests' + +class Hand extends NormalContainer { + consumeVerb: Verb = new Verb('grab', 'grabs', 'grabbing', 'grabbed') + releaseVerb: Verb = new Verb('release', 'releases', 'releasing', 'released') + struggleVerb: Verb = new Verb('squirm', 'squirms', 'squirming', 'squirmed') + + constructor (owner: Creature) { + super(new ImproperNoun('hand', 'hands'), owner, new Set(), 100) + } +} + +export class ChewAction extends Action { + protected test: StatTest + + constructor (protected damage: DamageFormula, protected verb: Verb = new Verb('smack'), container: Container) { + super( + verb.root.capital, + 'Chew your victim', + [new CapableCondition(), new ContainsCondition(container), new EnemyCondition()] + ) + this.test = new StatTest(Stat.Power) + } + + execute (user: Creature, target: Creature): LogEntry { + const effectResults = target.effects.map(effect => effect.preAttack(target, user)) + + if (effectResults.some(result => result.prevented)) { + return new LogLines(...effectResults.map(result => result.log)) + } + if (this.test.test(user, target)) { + const damage = this.damage.calc(user, target) + const targetResult = target.takeDamage(damage) + const ownResult = this.successLine(user, target, { damage: damage }) + return new LogLines(ownResult, targetResult) + } else { + return this.failLine(user, target) + } + } + + describe (user: Creature, target: Creature): LogEntry { + return new LogLine(`Attack ${target.name}. `, this.damage.describe(user, target), '. ', this.test.explain(user, target)) + } + + protected successLine: PairLineArgs = (user, target, args) => new LogLine( + `${user.name.capital} ${user.name.conjugate(this.verb)} ${target.name.objective} for `, + target.effectiveDamage(args.damage).renderShort() + ) + + protected failLine: PairLine = (user, target) => new LogLine( + `${user.name.capital} ${user.name.conjugate(new Verb('miss', 'misses'))} ${target.name.objective}` + ) +} + +class Maw extends NormalContainer { + consumeVerb: Verb = new Verb('grab', 'grabs', 'grabbing', 'grabbed') + releaseVerb: Verb = new Verb('release', 'releases', 'releasing', 'released') + struggleVerb: Verb = new Verb('squirm', 'squirms', 'squirming', 'squirmed') + + constructor (owner: Creature) { + super(new ImproperNoun('maw', 'maws'), owner, new Set([VoreType.Oral]), 100) + + this.actions = [] + this.actions.push(new StruggleAction(this)) + this.actions.push(new ChewAction( + new ConstantDamageFormula( + new Damage( + { amount: 200, target: Vigor.Health, type: DamageType.Crush } + ) + ), + new Verb('chew'), + this + )) + } +} + +export class Shingo extends Creature { + constructor () { + super( + new ProperNoun('Shingo'), + new ImproperNoun('red panda', 'red pandas'), + MalePronouns, + { Toughness: 40, Power: 50, Speed: 30, Willpower: 30, Charm: 60 }, + new Set(), + new Set([VoreType.Oral]), + 3000 + ) + + this.actions.push( + new AttackAction( + new StatDamageFormula( + [ + { fraction: 0.5, stat: Stat.Power, target: Vigor.Health, type: DamageType.Crush } + ] + ) + ) + ) + + this.side = Side.Monsters + + const stomach = new Stomach(this, 50, new Damage( + { amount: 200, type: DamageType.Acid, target: Vigor.Health }, + { amount: 100, type: DamageType.Crush, target: Vigor.Stamina }, + { amount: 100, type: DamageType.Dominance, target: Vigor.Resolve } + )) + + this.containers.push(stomach) + + this.otherActions.push(new FeedAction(stomach)) + + const hand = new Hand(this) + const maw = new Maw(this) + this.otherContainers.push(hand) + this.otherContainers.push(maw) + + const stuff = new TransferAction(hand, maw) + stuff.verb = new Verb('stuff') + stuff.line = (user, target, args) => new LogLine( + `${user.name.capital} ${user.name.conjugate(stuff.verb)} ${target.name.objective} into ${user.pronouns.possessive} ${args.to.name}!` + ) + this.actions.push(stuff) + + const gulp = new TransferAction(maw, stomach) + gulp.verb = new Verb('gulp') + gulp.line = (user, target, args) => new LogLine( + `${user.name.capital} ${user.name.conjugate(gulp.verb)} ${target.name.objective} down ${user.pronouns.possessive} tight, inescapable gullet, sending ${target.pronouns.objective} down to ${user.pronouns.possessive} ${args.to.name}` + ) + this.actions.push(gulp) + } +} diff --git a/src/game/vore.ts b/src/game/vore.ts index 9bbf86a..391565a 100644 --- a/src/game/vore.ts +++ b/src/game/vore.ts @@ -194,6 +194,22 @@ export abstract class NormalContainer implements Container { } } +export abstract class InnerContainer extends NormalContainer { + constructor (name: Noun, owner: Vore, voreTypes: Set, capacity: number, private escape: VoreContainer) { + super(name, owner, voreTypes, capacity) + + this.actions = [] + + this.actions.push(new StruggleAction(this)) + } + + release (prey: Vore): LogEntry { + prey.containedIn = this.escape + this.contents = this.contents.filter(victim => victim !== prey) + return this.releaseLine(this.owner, prey, { container: this }) + } +} + export interface VoreContainer extends Container { digested: Array; tick: (dt: number) => LogEntry; @@ -260,7 +276,7 @@ export abstract class NormalVoreContainer extends NormalContainer implements Vor } } -abstract class InnerContainer extends NormalVoreContainer { +abstract class InnerVoreContainer extends NormalVoreContainer { constructor (name: Noun, owner: Vore, voreTypes: Set, capacity: number, damage: Damage, private escape: VoreContainer) { super(name, owner, voreTypes, capacity, damage) @@ -302,7 +318,7 @@ export class Stomach extends NormalVoreContainer { } } -export class InnerStomach extends InnerContainer { +export class InnerStomach extends InnerVoreContainer { consumeVerb = new Verb('swallow') releaseVerb = new Verb('hork') constructor (owner: Vore, capacity: number, damage: Damage, escape: VoreContainer) {