| @@ -84,7 +84,7 @@ export const StatDescs: {[key in Stat]: string} = { | |||
| export enum VoreStat { | |||
| Mass = "Mass", | |||
| Bulk = "Bulk", | |||
| PreyCount = "Prey Count" | |||
| Prey = "Prey" | |||
| } | |||
| export type VoreStats = {[key in VoreStat]: number} | |||
| @@ -92,13 +92,13 @@ export type VoreStats = {[key in VoreStat]: number} | |||
| export const VoreStatIcons: {[key in VoreStat]: string} = { | |||
| [VoreStat.Mass]: "fas fa-weight", | |||
| [VoreStat.Bulk]: "fas fa-weight-hanging", | |||
| [VoreStat.PreyCount]: "fas fa-utensils" | |||
| [VoreStat.Prey]: "fas fa-utensils" | |||
| } | |||
| export const VoreStatDescs: {[key in VoreStat]: string} = { | |||
| [VoreStat.Mass]: "How much you weigh", | |||
| [VoreStat.Bulk]: "Your weight, plus the weight of your prey", | |||
| [VoreStat.PreyCount]: "How many creatures you've got inside of you" | |||
| [VoreStat.Prey]: "How many creatures you've got inside of you" | |||
| } | |||
| export interface CombatTest { | |||
| @@ -584,6 +584,13 @@ export class Effective { | |||
| modStat (creature: Creature, stat: Stat, current: number): number { | |||
| return current | |||
| } | |||
| /** | |||
| * Provides actions | |||
| */ | |||
| actions (user: Creature): Array<Action> { | |||
| return [] | |||
| } | |||
| } | |||
| /** | |||
| * A displayable status effect | |||
| @@ -1,7 +1,11 @@ | |||
| import { Effective, Damage, DamageType } from '../combat' | |||
| import { Effective, Damage, DamageType, CompositionAction, StatDamageFormula, Action, Stat, Vigor, VoreStat } from '../combat' | |||
| import { TextLike } from '../language' | |||
| import { Creature } from '../creature' | |||
| import { TestCategory } from './tests' | |||
| import { EnemyCondition, PairCondition, TogetherCondition } from './conditions' | |||
| import { DamageConsequence, LogConsequence } from './consequences' | |||
| import { LogLine } from '../interface' | |||
| import * as Words from '../words' | |||
| export abstract class Perk extends Effective { | |||
| constructor (public name: TextLike, public desc: TextLike) { | |||
| @@ -48,7 +52,7 @@ export class RavenousPerk extends Perk { | |||
| } | |||
| modTestOffense (user: Creature, target: Creature, kind: TestCategory): number { | |||
| if (user.voreStats["Prey Count"] === 0 && kind === TestCategory.Vore) { | |||
| if (user.voreStats.Prey === 0 && kind === TestCategory.Vore) { | |||
| return 10 | |||
| } else { | |||
| return 0 | |||
| @@ -72,3 +76,38 @@ export class DeliciousPerk extends Perk { | |||
| } | |||
| } | |||
| } | |||
| export class FlauntPerk extends Perk { | |||
| constructor () { | |||
| super( | |||
| "Flaunt", | |||
| "Can show off your prey to intimidate enemies" | |||
| ) | |||
| } | |||
| actions (user: Creature): Array<Action> { | |||
| return [new CompositionAction( | |||
| "Flaunt", | |||
| "Show off your prey", | |||
| { | |||
| conditions: [ | |||
| new PairCondition(), | |||
| new EnemyCondition(), | |||
| new TogetherCondition() | |||
| ], | |||
| consequences: [ | |||
| new LogConsequence( | |||
| (user, target) => new LogLine(`${user.name.capital} ${user.name.conjugate(Words.Flaunt)} ${user.pronouns.possessive} prey.`) | |||
| ), | |||
| new DamageConsequence( | |||
| new StatDamageFormula( | |||
| [ | |||
| { fraction: 50, type: DamageType.Dominance, target: Vigor.Resolve, stat: VoreStat.Prey } | |||
| ] | |||
| ) | |||
| ) | |||
| ] | |||
| } | |||
| )] | |||
| } | |||
| } | |||
| @@ -105,12 +105,12 @@ export class Creature extends Entity { | |||
| const adjusted = mass / modifier | |||
| self.baseMass = adjusted | |||
| }, | |||
| get [VoreStat.PreyCount] () { | |||
| get [VoreStat.Prey] () { | |||
| return self.containers.reduce( | |||
| (total: number, container: VoreContainer) => { | |||
| return total + container.contents.concat(container.digested).reduce( | |||
| (total: number, prey: Creature) => { | |||
| return total + 1 + prey.voreStats[VoreStat.PreyCount] | |||
| return total + 1 + prey.voreStats[VoreStat.Prey] | |||
| }, | |||
| 0 | |||
| ) | |||
| @@ -264,7 +264,8 @@ export class Creature extends Entity { | |||
| target.otherActions, | |||
| this.otherContainers.flatMap(container => container.actions), | |||
| Object.values(this.equipment).filter(item => item !== undefined).flatMap(item => (item as Equipment).actions), | |||
| this.items.filter(item => item.kind === ItemKind.Consumable && !item.consumed).flatMap(item => item.actions) | |||
| this.items.filter(item => item.kind === ItemKind.Consumable && !item.consumed).flatMap(item => item.actions), | |||
| this.perks.flatMap(perk => perk.actions(this)) | |||
| ) | |||
| if (this.containedIn !== null) { | |||
| @@ -7,7 +7,8 @@ import { TogetherCondition } from '../combat/conditions' | |||
| import { DamageConsequence } from '../combat/consequences' | |||
| import { OpposedStatTest, TestCategory } from '../combat/tests' | |||
| import { LogLine } from '../interface' | |||
| import { RavenousPerk, BellyBulwakPerk } from '../combat/perks' | |||
| import { RavenousPerk, BellyBulwakPerk, FlauntPerk } from '../combat/perks' | |||
| import { Flaunt } from '../words' | |||
| export class Player extends Creature { | |||
| constructor () { | |||
| @@ -55,6 +56,7 @@ export class Player extends Creature { | |||
| this.perks.push(new RavenousPerk()) | |||
| this.perks.push(new BellyBulwakPerk()) | |||
| this.perks.push(new FlauntPerk()) | |||
| this.actions.push( | |||
| new CompositionAction( | |||
| @@ -86,3 +86,8 @@ export const Succumb = new RandomWord([ | |||
| new Verb("succumb"), | |||
| new Verb("surrender") | |||
| ]) | |||
| export const Flaunt = new RandomWord([ | |||
| new Verb("flaunt"), | |||
| new Verb("show off", "shows off", "showing off", "shown off") | |||
| ]) | |||