| @@ -218,7 +218,7 @@ export class ConstantDamageFormula implements DamageFormula { | |||||
| } | } | ||||
| explain (user: Creature): LogEntry { | explain (user: Creature): LogEntry { | ||||
| return new LogLine('Deal ', this.damage.renderShort(), '.') | |||||
| return new LogLine('Deal ', this.damage.renderShort()) | |||||
| } | } | ||||
| } | } | ||||
| @@ -390,10 +390,9 @@ export abstract class Action { | |||||
| } | } | ||||
| } | } | ||||
| describe (user: Creature, target: Creature): LogEntry { | |||||
| describe (user: Creature, target: Creature, verbose = true): LogEntry { | |||||
| return new LogLines( | return new LogLines( | ||||
| ...this.conditions.map(condition => condition.explain(user, target)), | |||||
| new Newline(), | |||||
| ...(verbose ? this.conditions.map(condition => condition.explain(user, target)).concat([new Newline()]) : []), | |||||
| new LogLine( | new LogLine( | ||||
| `Success chance: ${(this.odds(user, target) * 100).toFixed(0)}%` | `Success chance: ${(this.odds(user, target) * 100).toFixed(0)}%` | ||||
| ), | ), | ||||
| @@ -3,7 +3,7 @@ import { DynText, LiveText, TextLike, Verb, PairLine, PairLineArgs } from '../la | |||||
| import { Entity } from '../entity' | import { Entity } from '../entity' | ||||
| import { Creature } from "../creature" | import { Creature } from "../creature" | ||||
| import { Damage, DamageFormula, Stat, Vigor, Action, Condition, CombatTest, CompositionAction } from '../combat' | import { Damage, DamageFormula, Stat, Vigor, Action, Condition, CombatTest, CompositionAction } from '../combat' | ||||
| import { LogLine, LogLines, LogEntry, nilLog } from '../interface' | |||||
| import { LogLine, LogLines, LogEntry, nilLog, Newline } from '../interface' | |||||
| import { VoreContainer, Container } from '../vore' | import { VoreContainer, Container } from '../vore' | ||||
| import { CapableCondition, UserDrainedVigorCondition, TogetherCondition, EnemyCondition, SoloCondition, PairCondition, ContainsCondition, ContainedByCondition, HasRoomCondition } from './conditions' | import { CapableCondition, UserDrainedVigorCondition, TogetherCondition, EnemyCondition, SoloCondition, PairCondition, ContainsCondition, ContainedByCondition, HasRoomCondition } from './conditions' | ||||
| import { ConsumeConsequence } from './consequences' | import { ConsumeConsequence } from './consequences' | ||||
| @@ -89,7 +89,7 @@ export class AttackAction extends DamageAction { | |||||
| } | } | ||||
| describe (user: Creature, target: Creature): LogEntry { | describe (user: Creature, target: Creature): LogEntry { | ||||
| return new LogLine(`Attack ${target.baseName}. `, this.damage.describe(user, target), '. ', super.describe(user, target)) | |||||
| return new LogLine(`Attack ${target.baseName}. `, this.damage.describe(user, target), super.describe(user, target)) | |||||
| } | } | ||||
| successLine: PairLineArgs<Creature, { damage: Damage }> = (user, target, args) => new LogLine( | successLine: PairLineArgs<Creature, { damage: Damage }> = (user, target, args) => new LogLine( | ||||
| @@ -10,11 +10,13 @@ function logistic (x0: number, L: number, k: number): (x: number) => number { | |||||
| } | } | ||||
| /** | /** | ||||
| * A [[Scorer]] produces a score for a creature in a certain situation | |||||
| * A [[Scorer]] produces a score for a creature in a certain situation. | |||||
| * | |||||
| * It takes the current score and returns a new one. | |||||
| */ | */ | ||||
| export interface Scorer { | export interface Scorer { | ||||
| userScore (attacker: Creature): number; | |||||
| targetScore (defender: Creature): number; | |||||
| userScore (attacker: Creature, score: number): number; | |||||
| targetScore (defender: Creature, score: number): number; | |||||
| explain(user: Creature, target: Creature): LogEntry; | explain(user: Creature, target: Creature): LogEntry; | ||||
| } | } | ||||
| @@ -52,12 +54,12 @@ export class OpposedStatScorer implements Scorer { | |||||
| ) | ) | ||||
| } | } | ||||
| userScore (attacker: Creature): number { | |||||
| return this.computeScore(attacker, this.userStats) | |||||
| userScore (attacker: Creature, score: number): number { | |||||
| return score + this.computeScore(attacker, this.userStats) | |||||
| } | } | ||||
| targetScore (defender: Creature): number { | |||||
| return this.computeScore(defender, this.targetStats) | |||||
| targetScore (defender: Creature, score: number): number { | |||||
| return score + this.computeScore(defender, this.targetStats) | |||||
| } | } | ||||
| private computeScore (subject: Creature, parts: Partial<Stats & VoreStats>): number { | private computeScore (subject: Creature, parts: Partial<Stats & VoreStats>): number { | ||||
| @@ -141,8 +143,8 @@ export class CompositionTest extends RandomTest { | |||||
| } | } | ||||
| odds (user: Creature, target: Creature): number { | odds (user: Creature, target: Creature): number { | ||||
| const userScore = this.scorers.reduce((score, scorer) => score + scorer.userScore(user), 0) | |||||
| const targetScore = this.scorers.reduce((score, scorer) => score + scorer.targetScore(target), 0) | |||||
| const userScore = this.scorers.reduce((score, scorer) => scorer.userScore(user, score), 0) | |||||
| const targetScore = this.scorers.reduce((score, scorer) => scorer.targetScore(target, score), 0) | |||||
| const userMod = user.effects.reduce((score, effect) => score + effect.modTestOffense(user, target, this.category), 0) | const userMod = user.effects.reduce((score, effect) => score + effect.modTestOffense(user, target, this.category), 0) | ||||
| const targetMod = target.effects.reduce((score, effect) => score + effect.modTestDefense(target, user, this.category), 0) | const targetMod = target.effects.reduce((score, effect) => score + effect.modTestDefense(target, user, this.category), 0) | ||||