Browse Source

Delete some old, unused test types

master
Fen Dweller 5 years ago
parent
commit
1ff2e8068c
5 changed files with 29 additions and 336 deletions
  1. +22
    -13
      src/game/combat/actions.ts
  2. +0
    -276
      src/game/combat/tests.ts
  3. +2
    -40
      src/game/creatures/player.ts
  4. +4
    -5
      src/game/creatures/shingo.ts
  5. +1
    -2
      src/game/creatures/withers.ts

+ 22
- 13
src/game/combat/actions.ts View File

@@ -1,9 +1,9 @@
import { StatTest, StatVigorTest, StatVigorSizeTest, OpposedStatTest, TestCategory, CompositionTest, OpposedStatScorer } from './tests'
import { TestCategory, CompositionTest, OpposedStatScorer } from './tests'
import { DynText, LiveText, TextLike, Verb, PairLine, PairLineArgs } from '../language'
import { Entity } from '../entity'
import { Creature } from "../creature"
import { Damage, DamageFormula, Stat, Vigor, Action, Condition, CombatTest, CompositionAction } from '../combat'
import { LogLine, LogLines, LogEntry, nilLog, Newline } from '../interface'
import { Damage, DamageFormula, Vigor, Action, Condition, CombatTest, CompositionAction } from '../combat'
import { LogLine, LogLines, LogEntry } from '../interface'
import { VoreContainer, Container } from '../vore'
import { CapableCondition, UserDrainedVigorCondition, TogetherCondition, EnemyCondition, SoloCondition, PairCondition, ContainsCondition, ContainedByCondition, HasRoomCondition } from './conditions'
import { ConsumeConsequence } from './consequences'
@@ -108,13 +108,18 @@ export class DevourAction extends CompositionAction {
new LiveText(container, x => `Try to ${x.consumeVerb} your foe`),
{
conditions: [new CapableCondition(), new TogetherCondition(), new HasRoomCondition(container)],
tests: [new OpposedStatTest(
{ Power: 1, Charm: 1, Mass: 0.05 },
{ Toughness: 1, Willpower: 1, Bulk: 0.05 },
(user, target) => new LogLine(`${user.name.capital} ${user.name.conjugate(new Verb('fail'))} to ${container.consumeVerb} ${target.name.objective}.`),
TestCategory.Vore,
-5
)],
tests: [
new CompositionTest(
[
new OpposedStatScorer(
{ Power: 1, Charm: 1, Mass: 0.05 },
{ Toughness: 1, Willpower: 1, Bulk: 0.05 }
)
],
(user, target) => new LogLine(`${user.name.capital} ${user.name.conjugate(new Verb('fail'))} to ${container.consumeVerb} ${target.name.objective}.`),
TestCategory.Vore,
-5
)],
consequences: [
new ConsumeConsequence(container)
]
@@ -191,9 +196,13 @@ export class StruggleAction extends Action {
'Try to escape from your foe',
[new CapableCondition(), new PairCondition(), new ContainedByCondition(container)],
[
new OpposedStatTest(
{ Power: 1, Agility: 1, Bulk: 0.05 },
{ Toughness: 1, Reflexes: 1, Mass: 0.05 },
new CompositionTest(
[
new OpposedStatScorer(
{ Power: 1, Agility: 1, Bulk: 0.05 },
{ Toughness: 1, Reflexes: 1, Mass: 0.05 }
)
],
(user, target) => new LogLine(`${user.name.capital} ${user.name.conjugate(new Verb('fail'))} to escape from ${target.name.possessive} ${container.name}.`),
TestCategory.Vore,
-5


+ 0
- 276
src/game/combat/tests.ts View File

@@ -1,7 +1,6 @@
import { CombatTest, Stat, Vigor, Stats, StatToVigor, VoreStats, VoreStat } from '../combat'
import { Creature } from "../creature"
import { LogEntry, LogLines, PropElem, LogLine, nilLog } from '../interface'
import { Verb } from '../language'

function logistic (x0: number, L: number, k: number): (x: number) => number {
return (x: number) => {
@@ -146,283 +145,8 @@ export class CompositionTest extends RandomTest {
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 targetMod = target.effects.reduce((score, effect) => score + effect.modTestDefense(target, user, this.category), 0)

return this.f(userScore - targetScore + this.bias)
}
}

export class OpposedStatTest extends RandomTest {
private f: (x: number) => number
private k = 0.1

// how much a stat can be reduced by its corresponding vigor being low
private maxStatVigorPenalty = 0.5

// how much the total score can be reduced by each vigor being low
private maxTotalVigorPenalty = 0.1

constructor (
public readonly userStats: Partial<Stats & VoreStats>,
public readonly targetStats: Partial<Stats & VoreStats>,
fail: (user: Creature, target: Creature) => LogEntry,
public category: TestCategory,
private bias = 0
) {
super(fail)
this.f = logistic(0, 1, this.k)
}

odds (user: Creature, target: Creature): number {
const userScore = this.getScoreOffense(user, target, this.userStats)
const targetScore = this.getScoreDefense(target, user, this.targetStats)

return this.f(userScore - targetScore + this.bias)
}

explain (user: Creature, target: Creature): LogEntry {
return new LogLines(
new LogLine(
`Pits `,
...Object.entries(this.userStats).map(([stat, frac]) => {
if (frac !== undefined) {
return new LogLine(`${(frac * 100).toFixed(0)}% of `, new PropElem(stat as Stat), `, `)
} else {
return nilLog
}
}),
` against `,
...Object.entries(this.targetStats).map(([stat, frac]) => {
if (frac !== undefined) {
return new LogLine(`${(frac * 100).toFixed(0)}% of `, new PropElem(stat as Stat), `, `)
} else {
return nilLog
}
})
),
new LogLine(
`${user.name.capital}: ${this.getScoreOffense(user, target, this.userStats)} // ${this.getScoreDefense(target, user, this.targetStats)} :${target.name.capital}`
),
new LogLine(
`${user.name.capital} ${user.name.conjugate(new Verb("have", "has"))} a ${(this.odds(user, target) * 100).toFixed(0)}% chance of winning this test.`
)
)
}

private getScoreDefense (defender: Creature, attacker: Creature, parts: Partial<Stats>): number {
return this.getScore(defender, parts) + defender.effects.reduce((total, effect) => total + effect.modTestDefense(defender, attacker, this.category), 0)
}

private getScoreOffense (attacker: Creature, defender: Creature, parts: Partial<Stats>): number {
return this.getScore(attacker, parts) + attacker.effects.reduce((total, effect) => total + effect.modTestOffense(attacker, defender, this.category), 0)
}

private getScore (actor: Creature, parts: Partial<Stats>): number {
const total = Object.entries(parts).reduce((total: number, [stat, frac]) => {
if (stat in Stat) {
let value = actor.stats[stat as Stat] * (frac === undefined ? 0 : frac)

const vigor = StatToVigor[stat as Stat]
value = value * (1 - this.maxStatVigorPenalty) + value * this.maxStatVigorPenalty * actor.vigors[vigor] / actor.maxVigors[vigor]

return total + value
} else if (stat in VoreStat) {
const value = actor.voreStats[stat as VoreStat] * (frac === undefined ? 0 : frac)

return total + value
} else {
return total
}
}, 0)

const modifiedTotal = Object.keys(Vigor).reduce(
(total, vigor) => {
return total * (1 - this.maxStatVigorPenalty) + total * this.maxStatVigorPenalty * actor.vigors[vigor as Vigor] / actor.maxVigors[vigor as Vigor]
},
total
)

return modifiedTotal
}
}

export class StatVigorSizeTest extends RandomTest {
private f: (x: number) => number
private k = 0.1

constructor (public readonly stat: Stat, private bias = 0, fail: (user: Creature, target: Creature) => LogEntry) {
super(fail)
this.f = logistic(0, 1, this.k)
}

odds (user: Creature, target: Creature): number {
let userPercent = 1
let targetPercent = 1

Object.keys(Vigor).forEach(key => {
userPercent *= user.vigors[key as Vigor] / Math.max(1, user.maxVigors[key as Vigor])
targetPercent *= target.vigors[key as Vigor] / Math.max(1, target.maxVigors[key as Vigor])

userPercent = Math.max(0, userPercent)
targetPercent = Math.max(0, targetPercent)
})

if (userPercent === 0) {
targetPercent *= 4
}

if (targetPercent === 0) {
userPercent *= 4
}

const sizeOffset = Math.log2(user.voreStats.Mass / target.voreStats.Mass)

return this.f(this.bias + sizeOffset * 5 + user.stats[this.stat] * userPercent - target.stats[this.stat] * targetPercent)
}

explain (user: Creature, target: Creature): LogEntry {
let result: LogEntry

let userPercent = 1
let targetPercent = 1

Object.keys(Vigor).forEach(key => {
userPercent *= user.vigors[key as Vigor] / user.maxVigors[key as Vigor]
targetPercent *= target.vigors[key as Vigor] / target.maxVigors[key as Vigor]

userPercent = Math.max(0, userPercent)
targetPercent = Math.max(0, targetPercent)
})

if (userPercent === 0) {
targetPercent *= 4
}

if (targetPercent === 0) {
userPercent *= 4
}

const sizeOffset = Math.log2(user.voreStats.Mass / target.voreStats.Mass)

const userMod = user.stats[this.stat] * userPercent
const targetMod = target.stats[this.stat] * targetPercent
const delta = userMod - targetMod + sizeOffset * 5

if (delta === 0) {
result = new LogLine('You and the target have the same effective', new PropElem(this.stat), '.')
} else if (delta < 0) {
result = new LogLine('You effectively have ', new PropElem(this.stat, -delta), ' less than your foe.')
} else {
result = new LogLine('You effectively have ', new PropElem(this.stat, delta), ' more than you foe.')
}

result = new LogLine(result, 'Your odds of success are ' + (100 * this.odds(user, target)).toFixed(1) + '%')

return result
}
}

export class StatVigorTest extends RandomTest {
private f: (x: number) => number
private k = 0.1

constructor (public readonly stat: Stat, private bias = 0, fail: (user: Creature, target: Creature) => LogEntry) {
super(fail)
this.f = logistic(0, 1, this.k)
}

odds (user: Creature, target: Creature): number {
let userPercent = 1
let targetPercent = 1

Object.keys(Vigor).forEach(key => {
userPercent *= user.vigors[key as Vigor] / Math.max(1, user.maxVigors[key as Vigor])
targetPercent *= target.vigors[key as Vigor] / Math.max(1, target.maxVigors[key as Vigor])

userPercent = Math.max(0, userPercent)
targetPercent = Math.max(0, targetPercent)
})

if (userPercent === 0) {
targetPercent *= 4
}

if (targetPercent === 0) {
userPercent *= 4
}

return this.f(this.bias + user.stats[this.stat] * userPercent - target.stats[this.stat] * targetPercent)
}

explain (user: Creature, target: Creature): LogEntry {
let result: LogEntry

let userPercent = 1
let targetPercent = 1

Object.keys(Vigor).forEach(key => {
userPercent *= user.vigors[key as Vigor] / user.maxVigors[key as Vigor]
targetPercent *= target.vigors[key as Vigor] / target.maxVigors[key as Vigor]

userPercent = Math.max(0, userPercent)
targetPercent = Math.max(0, targetPercent)
})

if (userPercent === 0) {
targetPercent *= 4
}

if (targetPercent === 0) {
userPercent *= 4
}
const userMod = user.stats[this.stat] * userPercent
const targetMod = target.stats[this.stat] * targetPercent
const delta = userMod - targetMod

if (delta === 0) {
result = new LogLine('You and the target have the same effective', new PropElem(this.stat), '.')
} else if (delta < 0) {
result = new LogLine('You effectively have ', new PropElem(this.stat, -delta), ' less than your foe.')
} else {
result = new LogLine('You effectively have ', new PropElem(this.stat, delta), ' more than you foe.')
}

result = new LogLine(result, 'Your odds of success are ' + (100 * this.odds(user, target)).toFixed(1) + '%')

return result
}
}

export class StatTest extends RandomTest {
private f: (x: number) => number
private k = 0.1

constructor (public readonly stat: Stat, private bias = 0, fail: (user: Creature, target: Creature) => LogEntry) {
super(fail)
this.f = logistic(0, 1, this.k)
}

odds (user: Creature, target: Creature): number {
return this.f(this.bias + user.stats[this.stat] - target.stats[this.stat])
}

explain (user: Creature, target: Creature): LogEntry {
const delta: number = user.stats[this.stat] - target.stats[this.stat]
let result: LogEntry

if (delta === 0) {
result = new LogLine('You and the target have the same ', new PropElem(this.stat), '.')
} else if (delta < 0) {
result = new LogLine('You have ', new PropElem(this.stat, -delta), ' less than your foe.')
} else {
result = new LogLine('You have ', new PropElem(this.stat, delta), ' more than you foe.')
}

result = new LogLine(result, 'Your odds of success are ' + (100 * this.odds(user, target)).toFixed(1) + '%')

return result
}
}

export class ChanceTest extends RandomTest {


+ 2
- 40
src/game/creatures/player.ts View File

@@ -1,14 +1,9 @@
import { Creature } from "../creature"
import { ProperNoun, TheyPronouns, ImproperNoun, POV } from '../language'
import { Damage, DamageType, Vigor, ConstantDamageFormula, CompositionAction, UniformRandomDamageFormula, StatDamageFormula, Stat } from '../combat'
import { Stomach, Bowels, VoreType, anyVore, Bladder, Cock, Balls, Breasts, InnerBladder, Slit, Womb, biconnectContainers } from '../vore'
import { Damage, DamageType, Vigor, ConstantDamageFormula } from '../combat'
import { Stomach, Bowels, anyVore, Cock, Balls, Breasts, InnerBladder, Slit, Womb, biconnectContainers } from '../vore'
import { AttackAction } from '../combat/actions'
import { TogetherCondition } from '../combat/conditions'
import { DamageConsequence } from '../combat/consequences'
import { OpposedStatTest, TestCategory } from '../combat/tests'
import { LogLine } from '../interface'
import { RavenousPerk, BellyBulwakPerk, FlauntPerk } from '../combat/perks'
import { Flaunt } from '../words'

export class Player extends Creature {
constructor () {
@@ -57,38 +52,5 @@ 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(
"Bite",
"Munch",
{
conditions: [
new TogetherCondition()
],
consequences: [
new DamageConsequence(
new StatDamageFormula([
{ fraction: 2, stat: Stat.Power, target: Vigor.Health, type: DamageType.Crush },
{ fraction: 2, stat: Stat.Power, target: Vigor.Stamina, type: DamageType.Crush }
])
)
],
tests: [
new OpposedStatTest(
{
Power: 1
},
{
Agility: 1
},
(user, target) => new LogLine(`No munch.`),
TestCategory.Attack,
0
)
]
}
)
)
}
}

+ 4
- 5
src/game/creatures/shingo.ts View File

@@ -1,11 +1,10 @@
import { Creature } from "../creature"
import { Damage, DamageType, ConstantDamageFormula, Vigor, Side, StatDamageFormula, Stat, Action, DamageFormula, Condition, FractionDamageFormula } from '../combat'
import { ImproperNoun, ProperNoun, FemalePronouns, MalePronouns, Verb, PairLineArgs, PairLine, TextLike } from '../language'
import { VoreType, Stomach, Bowels, NormalContainer, InnerContainer, VoreContainer, Container } from '../vore'
import { Damage, DamageType, ConstantDamageFormula, Vigor, Side, StatDamageFormula, Stat, DamageFormula, Condition, FractionDamageFormula } from '../combat'
import { ImproperNoun, ProperNoun, MalePronouns, Verb, PairLineArgs, TextLike } from '../language'
import { VoreType, Stomach, NormalContainer, Container } from '../vore'
import { AttackAction, TransferAction, FeedAction, StruggleAction, DamageAction } from '../combat/actions'
import { LogLine, LogEntry, LogLines } from '../interface'
import { LogLine, LogEntry } from '../interface'
import { ContainsCondition, CapableCondition, EnemyCondition, TargetDrainedVigorCondition } from '../combat/conditions'
import { StatTest } from '../combat/tests'

export class TrappedAction extends DamageAction {
constructor (name: TextLike, desc: TextLike, protected verb: Verb, protected damage: DamageFormula, container: Container, conditions: Condition[] = []) {


+ 1
- 2
src/game/creatures/withers.ts View File

@@ -1,5 +1,5 @@
import { Creature } from "../creature"
import { Damage, DamageType, ConstantDamageFormula, Vigor, Side, GroupAction, CombatTest, Stat, DamageFormula, UniformRandomDamageFormula, Action, DamageInstance, StatDamageFormula, VoreStat } from '../combat'
import { Damage, DamageType, ConstantDamageFormula, Vigor, Side, GroupAction, Stat, DamageFormula, UniformRandomDamageFormula, Action, DamageInstance, StatDamageFormula, VoreStat } from '../combat'
import { ImproperNoun, ProperNoun, FemalePronouns, RandomWord, Adjective, Verb, PairLine } from '../language'
import { LogLine, LogLines, LogEntry, Newline } from '../interface'
import { VoreType, Stomach, VoreContainer, NormalContainer, Container } from '../vore'
@@ -7,7 +7,6 @@ import { AttackAction, FeedAction, TransferAction } from '../combat/actions'
import { TogetherCondition, ContainsCondition, EnemyCondition, AllyCondition, PairCondition, CapableCondition } from '../combat/conditions'
import { InstantKillEffect, DamageTypeResistanceEffect } from '../combat/effects'
import * as Words from '../words'
import { StatVigorTest } from '../combat/tests'

class LevelDrain extends Action {
constructor (private container: Container) {


Loading…
Cancel
Save