| @@ -84,7 +84,7 @@ export const StatDescs: {[key in Stat]: string} = { | |||||
| export enum VoreStat { | export enum VoreStat { | ||||
| Mass = "Mass", | Mass = "Mass", | ||||
| Bulk = "Bulk", | Bulk = "Bulk", | ||||
| PreyCount = "Prey Count" | |||||
| Prey = "Prey" | |||||
| } | } | ||||
| export type VoreStats = {[key in VoreStat]: number} | 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} = { | export const VoreStatIcons: {[key in VoreStat]: string} = { | ||||
| [VoreStat.Mass]: "fas fa-weight", | [VoreStat.Mass]: "fas fa-weight", | ||||
| [VoreStat.Bulk]: "fas fa-weight-hanging", | [VoreStat.Bulk]: "fas fa-weight-hanging", | ||||
| [VoreStat.PreyCount]: "fas fa-utensils" | |||||
| [VoreStat.Prey]: "fas fa-utensils" | |||||
| } | } | ||||
| export const VoreStatDescs: {[key in VoreStat]: string} = { | export const VoreStatDescs: {[key in VoreStat]: string} = { | ||||
| [VoreStat.Mass]: "How much you weigh", | [VoreStat.Mass]: "How much you weigh", | ||||
| [VoreStat.Bulk]: "Your weight, plus the weight of your prey", | [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 { | export interface CombatTest { | ||||
| @@ -584,6 +584,13 @@ export class Effective { | |||||
| modStat (creature: Creature, stat: Stat, current: number): number { | modStat (creature: Creature, stat: Stat, current: number): number { | ||||
| return current | return current | ||||
| } | } | ||||
| /** | |||||
| * Provides actions | |||||
| */ | |||||
| actions (user: Creature): Array<Action> { | |||||
| return [] | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| * A displayable status effect | * 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 { TextLike } from '../language' | ||||
| import { Creature } from '../creature' | import { Creature } from '../creature' | ||||
| import { TestCategory } from './tests' | 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 { | export abstract class Perk extends Effective { | ||||
| constructor (public name: TextLike, public desc: TextLike) { | constructor (public name: TextLike, public desc: TextLike) { | ||||
| @@ -48,7 +52,7 @@ export class RavenousPerk extends Perk { | |||||
| } | } | ||||
| modTestOffense (user: Creature, target: Creature, kind: TestCategory): number { | 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 | return 10 | ||||
| } else { | } else { | ||||
| return 0 | 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 | const adjusted = mass / modifier | ||||
| self.baseMass = adjusted | self.baseMass = adjusted | ||||
| }, | }, | ||||
| get [VoreStat.PreyCount] () { | |||||
| get [VoreStat.Prey] () { | |||||
| return self.containers.reduce( | return self.containers.reduce( | ||||
| (total: number, container: VoreContainer) => { | (total: number, container: VoreContainer) => { | ||||
| return total + container.contents.concat(container.digested).reduce( | return total + container.contents.concat(container.digested).reduce( | ||||
| (total: number, prey: Creature) => { | (total: number, prey: Creature) => { | ||||
| return total + 1 + prey.voreStats[VoreStat.PreyCount] | |||||
| return total + 1 + prey.voreStats[VoreStat.Prey] | |||||
| }, | }, | ||||
| 0 | 0 | ||||
| ) | ) | ||||
| @@ -264,7 +264,8 @@ export class Creature extends Entity { | |||||
| target.otherActions, | target.otherActions, | ||||
| this.otherContainers.flatMap(container => container.actions), | this.otherContainers.flatMap(container => container.actions), | ||||
| Object.values(this.equipment).filter(item => item !== undefined).flatMap(item => (item as Equipment).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) { | if (this.containedIn !== null) { | ||||
| @@ -7,7 +7,8 @@ import { TogetherCondition } from '../combat/conditions' | |||||
| import { DamageConsequence } from '../combat/consequences' | import { DamageConsequence } from '../combat/consequences' | ||||
| import { OpposedStatTest, TestCategory } from '../combat/tests' | import { OpposedStatTest, TestCategory } from '../combat/tests' | ||||
| import { LogLine } from '../interface' | 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 { | export class Player extends Creature { | ||||
| constructor () { | constructor () { | ||||
| @@ -55,6 +56,7 @@ export class Player extends Creature { | |||||
| this.perks.push(new RavenousPerk()) | this.perks.push(new RavenousPerk()) | ||||
| this.perks.push(new BellyBulwakPerk()) | this.perks.push(new BellyBulwakPerk()) | ||||
| this.perks.push(new FlauntPerk()) | |||||
| this.actions.push( | this.actions.push( | ||||
| new CompositionAction( | new CompositionAction( | ||||
| @@ -86,3 +86,8 @@ export const Succumb = new RandomWord([ | |||||
| new Verb("succumb"), | new Verb("succumb"), | ||||
| new Verb("surrender") | new Verb("surrender") | ||||
| ]) | ]) | ||||
| export const Flaunt = new RandomWord([ | |||||
| new Verb("flaunt"), | |||||
| new Verb("show off", "shows off", "showing off", "shown off") | |||||
| ]) | |||||