diff --git a/src/components/Statblock.vue b/src/components/Statblock.vue index e14c165..44a2995 100644 --- a/src/components/Statblock.vue +++ b/src/components/Statblock.vue @@ -127,6 +127,8 @@ export default class Statblock extends Vue { }) }) createSingleton(tippyInstances, { delay: 500 }) + + this.statusChanged([]) } @Watch('subject.status') diff --git a/src/game/combat.ts b/src/game/combat.ts index bf68424..71272a7 100644 --- a/src/game/combat.ts +++ b/src/game/combat.ts @@ -373,4 +373,11 @@ export abstract class StatusEffect implements VisibleStatus { preDamage (creature: Creature, damage: Damage): Damage { return damage } + + preAttack (creature: Creature, attacker: Creature): { prevented: boolean; log: LogEntry } { + return { + prevented: false, + log: nilLog + } + } } diff --git a/src/game/combat/actions.ts b/src/game/combat/actions.ts index 1fb1b73..f342a63 100644 --- a/src/game/combat/actions.ts +++ b/src/game/combat/actions.ts @@ -28,6 +28,11 @@ export class AttackAction extends Action { } 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) diff --git a/src/game/combat/effects.ts b/src/game/combat/effects.ts index 3a2a957..a7991c4 100644 --- a/src/game/combat/effects.ts +++ b/src/game/combat/effects.ts @@ -1,7 +1,7 @@ -import { StatusEffect, Damage, DamageType } from '../combat' +import { StatusEffect, Damage, DamageType, Action } from '../combat' import { DynText, LiveText, ToBe, Verb } from '../language' import { Creature } from '../entity' -import { LogLine, LogEntry, LogLines, FAElem } from '../interface' +import { LogLine, LogEntry, LogLines, FAElem, nilLog } from '../interface' export class InstantKillEffect extends StatusEffect { constructor () { @@ -74,3 +74,24 @@ export class ShieldEffect extends StatusEffect { return damage.scale(this.amount) } } + +export class PredatorCounterEffect extends StatusEffect { + constructor (private devour: Action, private chance: number) { + super('Predatory Counter', 'Eat them back', 'fas fa-redo') + this.desc = new DynText(new LiveText(this, x => (x.chance * 100).toFixed(0)), '% chance to devour your attackers') + } + + preAttack (creature: Creature, attacker: Creature) { + if (this.devour.allowed(creature, attacker) && Math.random() < this.chance) { + return { + prevented: true, + log: new LogLines( + `${creature.name.capital} ${creature.name.conjugate(new Verb('surprise'))} ${attacker.name.objective} and ${creature.name.conjugate(new Verb('try', 'tries'))} to devour ${attacker.pronouns.objective}!`, + this.devour.execute(creature, attacker) + ) + } + } else { + return { prevented: false, log: nilLog } + } + } +} diff --git a/src/game/creatures/kenzie.ts b/src/game/creatures/kenzie.ts index 0e8f095..adde107 100644 --- a/src/game/creatures/kenzie.ts +++ b/src/game/creatures/kenzie.ts @@ -2,10 +2,10 @@ import { Creature } from '../entity' import { ProperNoun, ImproperNoun, FemalePronouns, Verb } from '../language' import { VoreType, Stomach } from '../vore' import { Side, Damage, DamageType, Vigor, StatDamageFormula, Stat, VoreStat, DamageFormula } from '../combat' -import { AttackAction } from '../combat/actions' +import { AttackAction, DevourAction } from '../combat/actions' import { LogEntry, LogLines } from '../interface' import { StatTest } from '../combat/tests' -import { StunEffect } from '../combat/effects' +import { StunEffect, PredatorCounterEffect } from '../combat/effects' class StompAttack extends AttackAction { execute (user: Creature, target: Creature): LogEntry { @@ -52,6 +52,8 @@ export class Kenzie extends Creature { { amount: 100, type: DamageType.Dominance, target: Vigor.Resolve } )) + this.applyEffect(new PredatorCounterEffect(new DevourAction(stomach), 0.4)) + this.containers.push(stomach) this.actions.push( diff --git a/src/game/creatures/withers.ts b/src/game/creatures/withers.ts index ee24bc0..a19a709 100644 --- a/src/game/creatures/withers.ts +++ b/src/game/creatures/withers.ts @@ -3,9 +3,9 @@ import { Damage, DamageType, ConstantDamageFormula, Vigor, Side, GroupAction, Co import { ImproperNoun, ProperNoun, FemalePronouns, RandomWord, Adjective, Verb, POV, PairLine } from '../language' import { LogLine, LogLines, LogEntry, Newline } from '../interface' import { VoreType, Stomach, VoreContainer, Vore, NormalContainer, Container, InnerStomach } from '../vore' -import { AttackAction, FeedAction, TransferAction, EatenAction } from '../combat/actions' +import { AttackAction, FeedAction, TransferAction, EatenAction, DevourAction } from '../combat/actions' import { TogetherCondition, ContainsCondition, EnemyCondition, AllyCondition, PairCondition, CapableCondition } from '../combat/conditions' -import { InstantKillEffect, ShieldEffect } from '../combat/effects' +import { InstantKillEffect, ShieldEffect, PredatorCounterEffect } from '../combat/effects' import * as Words from '../words' import { StatVigorTest } from '../combat/tests'