| @@ -4,6 +4,7 @@ import { LogEntry, LogLines, FAElem, LogLine, FormatEntry, FormatOpt, PropElem, | |||||
| import { Resistances } from './entity' | import { Resistances } from './entity' | ||||
| import { World } from './world' | import { World } from './world' | ||||
| import { TestCategory } from './combat/tests' | import { TestCategory } from './combat/tests' | ||||
| import { VoreContainer } from './vore' | |||||
| export enum DamageType { | export enum DamageType { | ||||
| Pierce = "Pierce", | Pierce = "Pierce", | ||||
| @@ -569,6 +570,13 @@ export class Effective { | |||||
| modTestDefense (defender: Creature, attacker: Creature, kind: TestCategory): number { | modTestDefense (defender: Creature, attacker: Creature, kind: TestCategory): number { | ||||
| return 0 | return 0 | ||||
| } | } | ||||
| /** | |||||
| * Affects digestion damage | |||||
| */ | |||||
| modDigestionDamage (predator: Creature, prey: Creature, container: VoreContainer, damage: Damage): Damage { | |||||
| return damage | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| * A displayable status effect | * A displayable status effect | ||||
| @@ -2,6 +2,8 @@ import { StatusEffect, Damage, DamageType, Action, Condition, Vigor } from '../c | |||||
| import { DynText, LiveText, ToBe, Verb } from '../language' | import { DynText, LiveText, ToBe, Verb } from '../language' | ||||
| import { Creature } from "../creature" | import { Creature } from "../creature" | ||||
| import { LogLine, LogEntry, LogLines, FAElem, nilLog } from '../interface' | import { LogLine, LogEntry, LogLines, FAElem, nilLog } from '../interface' | ||||
| import { VoreContainer } from '../vore' | |||||
| import * as Words from '../words' | |||||
| export class InstantKillEffect extends StatusEffect { | export class InstantKillEffect extends StatusEffect { | ||||
| constructor () { | constructor () { | ||||
| @@ -173,3 +175,22 @@ export class SizeEffect extends StatusEffect { | |||||
| return scale * this.change | return scale * this.change | ||||
| } | } | ||||
| } | } | ||||
| export class DigestionPowerEffect extends StatusEffect { | |||||
| constructor (private factor: number) { | |||||
| super('Acid-fueled', 'This creature is digesting faster than nomral', 'fas fa-flask') | |||||
| } | |||||
| onApply (creature: Creature): LogLine { | |||||
| const voreContainer: VoreContainer|undefined = creature.containers.find(c => c.digest !== null) | |||||
| if (voreContainer !== undefined) { | |||||
| return new LogLine(`${creature.name.capital.possessive}'s ${voreContainer.name} ${Words.Churns} and ${voreContainer.sound}`) | |||||
| } else { | |||||
| return new LogLine(`${creature.name.capital} can't digest people...`) | |||||
| } | |||||
| } | |||||
| modDigestionDamage (predator: Creature, prey: Creature, container: VoreContainer, damage: Damage): Damage { | |||||
| return damage.scale(this.factor) | |||||
| } | |||||
| } | |||||
| @@ -2,8 +2,8 @@ import { TextLike, LiveText, DynText, Word, ImproperNoun, Verb, Noun } from './l | |||||
| import { Actionable, Action, DamageFormula, ConstantDamageFormula, Damage, DamageType, Vigor, StatDamageFormula, Stat, Effective, CompositionAction, Condition, CompositeDamageFormula } from './combat' | import { Actionable, Action, DamageFormula, ConstantDamageFormula, Damage, DamageType, Vigor, StatDamageFormula, Stat, Effective, CompositionAction, Condition, CompositeDamageFormula } from './combat' | ||||
| import { AttackAction } from './combat/actions' | import { AttackAction } from './combat/actions' | ||||
| import { Resistances } from './entity' | import { Resistances } from './entity' | ||||
| import { DamageTypeResistanceEffect } from './combat/effects' | |||||
| import { DamageConsequence, LogConsequence, HealingConsequence } from './combat/consequences' | |||||
| import { DamageTypeResistanceEffect, DigestionPowerEffect } from './combat/effects' | |||||
| import { DamageConsequence, LogConsequence, HealingConsequence, StatusConsequence } from './combat/consequences' | |||||
| import { SoloCondition } from './combat/conditions' | import { SoloCondition } from './combat/conditions' | ||||
| import { LogLine, LogEntry } from './interface' | import { LogLine, LogEntry } from './interface' | ||||
| import { Creature } from './creature' | import { Creature } from './creature' | ||||
| @@ -230,3 +230,29 @@ export class HealthPotion extends Consumable { | |||||
| ) | ) | ||||
| } | } | ||||
| } | } | ||||
| export class AcidPotion extends Consumable { | |||||
| constructor () { | |||||
| super( | |||||
| new ImproperNoun("Acid Potion"), | |||||
| "Boosts your digestive power and causes a burst of damage to your prey", | |||||
| new CompositionAction( | |||||
| "Drink Potion", | |||||
| "Speed up your digestion", | |||||
| { | |||||
| conditions: [ | |||||
| new SoloCondition() | |||||
| ], | |||||
| consequences: [ | |||||
| new LogConsequence( | |||||
| (user, target) => new LogLine(`${user.name.capital} ${user.name.conjugate(new Verb('drink'))} an acid potion.`) | |||||
| ), | |||||
| new StatusConsequence( | |||||
| (user, target) => new DigestionPowerEffect(2) | |||||
| ) | |||||
| ] | |||||
| } | |||||
| ) | |||||
| ) | |||||
| } | |||||
| } | |||||
| @@ -244,6 +244,18 @@ export const Town = (): Place => { | |||||
| ) | ) | ||||
| ) | ) | ||||
| home.choices.push( | |||||
| new Choice( | |||||
| "Grab potions", | |||||
| "Grab some potions", | |||||
| (world, executor) => { | |||||
| executor.items.push(new Items.HealthPotion()) | |||||
| executor.items.push(new Items.AcidPotion()) | |||||
| return new LogLine("You grab some potions") | |||||
| } | |||||
| ) | |||||
| ) | |||||
| westAve.choices.push( | westAve.choices.push( | ||||
| new Choice( | new Choice( | ||||
| "Eat someone", | "Eat someone", | ||||
| @@ -160,6 +160,7 @@ export interface VoreContainer extends Container { | |||||
| tick: (dt: number) => LogEntry; | tick: (dt: number) => LogEntry; | ||||
| digest: (preys: Creature[]) => LogEntry; | digest: (preys: Creature[]) => LogEntry; | ||||
| absorb: (preys: Creature[]) => LogEntry; | absorb: (preys: Creature[]) => LogEntry; | ||||
| sound: Word; | |||||
| fluidName: Word; | fluidName: Word; | ||||
| fluidColor: string; | fluidColor: string; | ||||
| @@ -176,6 +177,8 @@ export abstract class NormalVoreContainer extends NormalContainer implements Vor | |||||
| digested: Array<Creature> = [] | digested: Array<Creature> = [] | ||||
| absorbed: Array<Creature> = [] | absorbed: Array<Creature> = [] | ||||
| sound = new Verb("slosh") | |||||
| abstract fluidName: Word | abstract fluidName: Word | ||||
| constructor (name: Noun, owner: Creature, voreTypes: Set<VoreType>, capacity: number, private damage: DamageFormula) { | constructor (name: Noun, owner: Creature, voreTypes: Set<VoreType>, capacity: number, private damage: DamageFormula) { | ||||
| @@ -223,9 +226,10 @@ export abstract class NormalVoreContainer extends NormalContainer implements Vor | |||||
| this.contents.forEach(prey => { | this.contents.forEach(prey => { | ||||
| const scaled = this.damage.calc(this.owner, prey).scale(dt / 60) | const scaled = this.damage.calc(this.owner, prey).scale(dt / 60) | ||||
| tickedEntryList.push(this.tickLine(this.owner, prey, { damage: scaled })) | |||||
| const modified = this.owner.effects.reduce((damage, effect) => effect.modDigestionDamage(this.owner, prey, this, damage), scaled) | |||||
| tickedEntryList.push(this.tickLine(this.owner, prey, { damage: modified })) | |||||
| damageResults.push(prey.takeDamage(scaled)) | |||||
| damageResults.push(prey.takeDamage(modified)) | |||||
| if (prey.vigors[Vigor.Health] <= 0) { | if (prey.vigors[Vigor.Health] <= 0) { | ||||
| prey.destroyed = true | prey.destroyed = true | ||||