Browse Source

Finish enforcing member order

master
Fen Dweller 5 years ago
parent
commit
fa2b1ee388
6 changed files with 140 additions and 141 deletions
  1. +18
    -18
      src/components/Statblock.vue
  2. +27
    -28
      src/game/combat.ts
  3. +16
    -16
      src/game/combat/conditions.ts
  4. +8
    -8
      src/game/creatures/kenzie.ts
  5. +59
    -59
      src/game/creatures/withers.ts
  6. +12
    -12
      src/game/language.ts

+ 18
- 18
src/components/Statblock.vue View File

@@ -110,6 +110,9 @@ export default class Statblock extends Vue {
@Prop() @Prop()
initiative!: number initiative!: number


firstperson: POV = POV.First
thirdperson: POV = POV.Third

private vigorIcons = VigorIcons private vigorIcons = VigorIcons
private statIcons = StatIcons private statIcons = StatIcons
private voreStatIcons = VoreStatIcons private voreStatIcons = VoreStatIcons
@@ -118,24 +121,6 @@ export default class Statblock extends Vue {
private voreStatDescs = VoreStatDescs private voreStatDescs = VoreStatDescs
private vigor = Vigor private vigor = Vigor


firstperson: POV = POV.First
thirdperson: POV = POV.Third

mounted () {
const statEntries = Array.from(this.$el.querySelectorAll(".stat-entry"))
const name = Array.from(this.$el.querySelectorAll(".name"))
const tippyInstances = statEntries.concat(name).map(elem => {
const tooltip = elem.querySelector(".tooltip-template") as HTMLElement

return tippy(elem, {
content: tooltip
})
})
createSingleton(tippyInstances, { delay: 500 })

this.statusChanged([])
}

@Watch('subject.status') @Watch('subject.status')
private statusChanged (a: Array<VisibleStatus>) { private statusChanged (a: Array<VisibleStatus>) {
this.$nextTick(() => { this.$nextTick(() => {
@@ -151,6 +136,21 @@ export default class Statblock extends Vue {
}) })
}) })
} }

mounted () {
const statEntries = Array.from(this.$el.querySelectorAll(".stat-entry"))
const name = Array.from(this.$el.querySelectorAll(".name"))
const tippyInstances = statEntries.concat(name).map(elem => {
const tooltip = elem.querySelector(".tooltip-template") as HTMLElement

return tippy(elem, {
content: tooltip
})
})
createSingleton(tippyInstances, { delay: 500 })

this.statusChanged([])
}
} }
</script> </script>




+ 27
- 28
src/game/combat.ts View File

@@ -167,14 +167,14 @@ export interface DamageFormula {
* Simply returns the damage it was given. * Simply returns the damage it was given.
*/ */
export class ConstantDamageFormula implements DamageFormula { export class ConstantDamageFormula implements DamageFormula {
calc (user: Creature, target: Creature): Damage {
return this.damage
}

constructor (private damage: Damage) { constructor (private damage: Damage) {


} }


calc (user: Creature, target: Creature): Damage {
return this.damage
}

describe (user: Creature, target: Creature): LogEntry { describe (user: Creature, target: Creature): LogEntry {
return this.explain(user) return this.explain(user)
} }
@@ -188,14 +188,14 @@ export class ConstantDamageFormula implements DamageFormula {
* Randomly scales the damage it was given with a factor of (1-x) to (1+x) * Randomly scales the damage it was given with a factor of (1-x) to (1+x)
*/ */
export class UniformRandomDamageFormula implements DamageFormula { export class UniformRandomDamageFormula implements DamageFormula {
calc (user: Creature, target: Creature): Damage {
return this.damage.scale(Math.random() * this.variance * 2 - this.variance + 1)
}

constructor (private damage: Damage, private variance: number) { constructor (private damage: Damage, private variance: number) {


} }


calc (user: Creature, target: Creature): Damage {
return this.damage.scale(Math.random() * this.variance * 2 - this.variance + 1)
}

describe (user: Creature, target: Creature): LogEntry { describe (user: Creature, target: Creature): LogEntry {
return this.explain(user) return this.explain(user)
} }
@@ -206,6 +206,10 @@ export class UniformRandomDamageFormula implements DamageFormula {
} }


export class StatDamageFormula implements DamageFormula { export class StatDamageFormula implements DamageFormula {
constructor (private factors: Array<{ stat: Stat|VoreStat; fraction: number; type: DamageType; target: Vigor|Stat }>) {

}

calc (user: Creature, target: Creature): Damage { calc (user: Creature, target: Creature): Damage {
const instances: Array<DamageInstance> = this.factors.map(factor => { const instances: Array<DamageInstance> = this.factors.map(factor => {
if (factor.stat in Stat) { if (factor.stat in Stat) {
@@ -252,10 +256,6 @@ export class StatDamageFormula implements DamageFormula {
)).joinGeneral(new LogLine(`, `), new LogLine(` and `)) )).joinGeneral(new LogLine(`, `), new LogLine(` and `))
) )
} }

constructor (private factors: Array<{ stat: Stat|VoreStat; fraction: number; type: DamageType; target: Vigor|Stat }>) {

}
} }


export enum Side { export enum Side {
@@ -276,21 +276,20 @@ export interface Combatant {
* An Action is anything that can be done by a [[Creature]] to a [[Creature]]. * An Action is anything that can be done by a [[Creature]] to a [[Creature]].
*/ */
export abstract class Action { export abstract class Action {
allowed (user: Creature, target: Creature): boolean {
return this.conditions.every(cond => cond.allowed(user, target))
}

abstract execute (user: Creature, target: Creature): LogEntry

abstract describe (user: Creature, target: Creature): LogEntry

constructor (public name: TextLike, public desc: TextLike, private conditions: Array<Condition> = []) { constructor (public name: TextLike, public desc: TextLike, private conditions: Array<Condition> = []) {


} }


allowed (user: Creature, target: Creature): boolean {
return this.conditions.every(cond => cond.allowed(user, target))
}

toString (): string { toString (): string {
return this.name.toString() return this.name.toString()
} }

abstract execute (user: Creature, target: Creature): LogEntry
abstract describe (user: Creature, target: Creature): LogEntry
} }


/** /**
@@ -305,6 +304,10 @@ export interface Actionable {
} }


export abstract class GroupAction extends Action { export abstract class GroupAction extends Action {
constructor (name: TextLike, desc: TextLike, conditions: Array<Condition>) {
super(name, desc, conditions)
}

allowedGroup (user: Creature, targets: Array<Creature>): Array<Creature> { allowedGroup (user: Creature, targets: Array<Creature>): Array<Creature> {
return targets.filter(target => this.allowed(user, target)) return targets.filter(target => this.allowed(user, target))
} }
@@ -314,10 +317,6 @@ export abstract class GroupAction extends Action {
} }


abstract describeGroup (user: Creature, targets: Array<Creature>): LogEntry abstract describeGroup (user: Creature, targets: Array<Creature>): LogEntry

constructor (name: TextLike, desc: TextLike, conditions: Array<Condition>) {
super(name, desc, conditions)
}
} }


/** /**
@@ -364,12 +363,12 @@ export interface VisibleStatus {
* a status indicating that it is dead, but entities cannot be "given" the dead effect * a status indicating that it is dead, but entities cannot be "given" the dead effect
*/ */
export class ImplicitStatus implements VisibleStatus { export class ImplicitStatus implements VisibleStatus {
topLeft = ''
bottomRight = ''

constructor (public name: TextLike, public desc: TextLike, public icon: string) { constructor (public name: TextLike, public desc: TextLike, public icon: string) {


} }

topLeft = ''
bottomRight = ''
} }


/** /**
@@ -388,7 +387,7 @@ export abstract class StatusEffect extends Effective implements VisibleStatus {
* An Encounter describes a fight: who is in it and whose turn it is * An Encounter describes a fight: who is in it and whose turn it is
*/ */
export class Encounter { export class Encounter {
private initiatives: Map<Creature, number>
initiatives: Map<Creature, number>
currentMove: Creature currentMove: Creature
turnTime = 100 turnTime = 100




+ 16
- 16
src/game/combat/conditions.ts View File

@@ -3,13 +3,13 @@ import { Creature } from "../entity"
import { Container } from '../vore' import { Container } from '../vore'


export class InverseCondition implements Condition { export class InverseCondition implements Condition {
allowed (user: Creature, target: Creature): boolean {
return !this.condition.allowed(user, target)
}

constructor (private condition: Condition) { constructor (private condition: Condition) {


} }

allowed (user: Creature, target: Creature): boolean {
return !this.condition.allowed(user, target)
}
} }


export class CapableCondition implements Condition { export class CapableCondition implements Condition {
@@ -19,23 +19,23 @@ export class CapableCondition implements Condition {
} }


export class UserDrainedVigorCondition implements Condition { export class UserDrainedVigorCondition implements Condition {
constructor (private vigor: Vigor) {

}

allowed (user: Creature, target: Creature): boolean { allowed (user: Creature, target: Creature): boolean {
return user.vigors[this.vigor] <= 0 return user.vigors[this.vigor] <= 0
} }
}


export class TargetDrainedVigorCondition implements Condition {
constructor (private vigor: Vigor) { constructor (private vigor: Vigor) {


} }
}


export class TargetDrainedVigorCondition implements Condition {
allowed (user: Creature, target: Creature): boolean { allowed (user: Creature, target: Creature): boolean {
return target.vigors[this.vigor] <= 0 return target.vigors[this.vigor] <= 0
} }

constructor (private vigor: Vigor) {

}
} }


export class SoloCondition implements Condition { export class SoloCondition implements Condition {
@@ -57,23 +57,23 @@ export class TogetherCondition implements Condition {
} }


export class ContainedByCondition implements Condition { export class ContainedByCondition implements Condition {
constructor (private container: Container) {

}

allowed (user: Creature, target: Creature): boolean { allowed (user: Creature, target: Creature): boolean {
return user.containedIn === this.container && this.container.owner === target return user.containedIn === this.container && this.container.owner === target
} }
}


export class ContainsCondition implements Condition {
constructor (private container: Container) { constructor (private container: Container) {


} }
}


export class ContainsCondition implements Condition {
allowed (user: Creature, target: Creature): boolean { allowed (user: Creature, target: Creature): boolean {
return target.containedIn === this.container return target.containedIn === this.container
} }

constructor (private container: Container) {

}
} }


export class AllyCondition implements Condition { export class AllyCondition implements Condition {


+ 8
- 8
src/game/creatures/kenzie.ts View File

@@ -8,6 +8,14 @@ import { StatTest } from '../combat/tests'
import { StunEffect, PredatorCounterEffect } from '../combat/effects' import { StunEffect, PredatorCounterEffect } from '../combat/effects'


class StompAttack extends AttackAction { class StompAttack extends AttackAction {
constructor (protected damage: DamageFormula, protected verb: Verb = new Verb('smack')) {
super(
damage,
verb
)
this.test = new StatTest(Stat.Power)
}

execute (user: Creature, target: Creature): LogEntry { execute (user: Creature, target: Creature): LogEntry {
if (this.test.test(user, target)) { if (this.test.test(user, target)) {
const damage = this.damage.calc(user, target) const damage = this.damage.calc(user, target)
@@ -20,14 +28,6 @@ class StompAttack extends AttackAction {
return this.failLine(user, target) return this.failLine(user, target)
} }
} }

constructor (protected damage: DamageFormula, protected verb: Verb = new Verb('smack')) {
super(
damage,
verb
)
this.test = new StatTest(Stat.Power)
}
} }
export class Kenzie extends Creature { export class Kenzie extends Creature {
title = "Large Lycanroc" title = "Large Lycanroc"


+ 59
- 59
src/game/creatures/withers.ts View File

@@ -10,6 +10,17 @@ import * as Words from '../words'
import { StatVigorTest } from '../combat/tests' import { StatVigorTest } from '../combat/tests'


class LevelDrain extends Action { class LevelDrain extends Action {
constructor (private container: Container) {
super(
'Level Drain',
'Drain energy from your prey',
[
new ContainsCondition(container),
new CapableCondition()
]
)
}

execute (user: Creature, target: Creature): LogEntry { execute (user: Creature, target: Creature): LogEntry {
const damage: Damage = new Damage(...Object.keys(Stat).map(stat => { const damage: Damage = new Damage(...Object.keys(Stat).map(stat => {
return { return {
@@ -40,19 +51,20 @@ class LevelDrain extends Action {
describe (user: Creature, target: Creature): LogEntry { describe (user: Creature, target: Creature): LogEntry {
return new LogLine(`Drain energy from ${target.name}`) return new LogLine(`Drain energy from ${target.name}`)
} }

constructor (private container: Container) {
}
class HypnotizeAction extends Action {
constructor () {
super( super(
'Level Drain',
'Drain energy from your prey',
`Hypnotize`,
`Change their mind!`,
[ [
new ContainsCondition(container),
new TogetherCondition(),
new EnemyCondition(),
new CapableCondition() new CapableCondition()
] ]
) )
} }
}
class HypnotizeAction extends Action {

line: PairLine<Creature> = (user, target) => new LogLine( line: PairLine<Creature> = (user, target) => new LogLine(
`${user.name.capital.possessive} hypnotic gaze enthralls ${target.name}, putting ${target.pronouns.objective} under ${user.pronouns.possessive} control!` `${user.name.capital.possessive} hypnotic gaze enthralls ${target.name}, putting ${target.pronouns.objective} under ${user.pronouns.possessive} control!`
) )
@@ -65,18 +77,6 @@ class HypnotizeAction extends Action {
describe (user: Creature, target: Creature): LogEntry { describe (user: Creature, target: Creature): LogEntry {
return new LogLine(`Force your target to fight by your side`) return new LogLine(`Force your target to fight by your side`)
} }

constructor () {
super(
`Hypnotize`,
`Change their mind!`,
[
new TogetherCondition(),
new EnemyCondition(),
new CapableCondition()
]
)
}
} }
class MawContainer extends NormalContainer { class MawContainer extends NormalContainer {
consumeVerb = new Verb('grab', 'grabs', 'grabbing', 'grabbed') consumeVerb = new Verb('grab', 'grabs', 'grabbing', 'grabbed')
@@ -93,27 +93,27 @@ class MawContainer extends NormalContainer {
} }


class FlexToesAction extends GroupAction { class FlexToesAction extends GroupAction {
line = (user: Creature, target: Creature, args: { damage: Damage }) => new LogLine(`${user.name.capital.possessive} toes crush ${target.name.objective} for `, args.damage.renderShort(), ` damage!`)

describeGroup (user: Creature, targets: Creature[]): LogEntry {
return new LogLine(`Flex your toes. `, this.damage.explain(user))
}

execute (user: Creature, target: Creature): LogEntry {
const damage = this.damage.calc(user, target)
return new LogLines(target.takeDamage(damage), this.line(user, target, { damage: damage }))
}

describe (user: Creature, target: Creature): LogEntry {
return new LogLine(`Flex your toes! `, this.damage.describe(user, target))
}

constructor (private damage: DamageFormula, container: Container) { constructor (private damage: DamageFormula, container: Container) {
super('Flex Toes', 'Flex your toes!', [ super('Flex Toes', 'Flex your toes!', [
new ContainsCondition(container), new ContainsCondition(container),
new PairCondition() new PairCondition()
]) ])
} }

line = (user: Creature, target: Creature, args: { damage: Damage }) => new LogLine(`${user.name.capital.possessive} toes crush ${target.name.objective} for `, args.damage.renderShort(), ` damage!`)

describeGroup (user: Creature, targets: Creature[]): LogEntry {
return new LogLine(`Flex your toes. `, this.damage.explain(user))
}

execute (user: Creature, target: Creature): LogEntry {
const damage = this.damage.calc(user, target)
return new LogLines(target.takeDamage(damage), this.line(user, target, { damage: damage }))
}

describe (user: Creature, target: Creature): LogEntry {
return new LogLine(`Flex your toes! `, this.damage.describe(user, target))
}
} }


class BootContainer extends NormalContainer { class BootContainer extends NormalContainer {
@@ -159,6 +159,12 @@ class BiteAction extends AttackAction {
} }


class ChewAction extends GroupAction { class ChewAction extends GroupAction {
constructor (private damage: DamageFormula, container: Container, private killAction: Action) {
super('Chew', 'Give them the big chew', [
new ContainsCondition(container)
])
}

line = (user: Creature, target: Creature, args: { damage: Damage }) => new LogLine(`${user.name.capital} chews on ${target.name.objective} for `, args.damage.renderShort(), `!`) line = (user: Creature, target: Creature, args: { damage: Damage }) => new LogLine(`${user.name.capital} chews on ${target.name.objective} for `, args.damage.renderShort(), `!`)


describeGroup (user: Creature, targets: Creature[]): LogEntry { describeGroup (user: Creature, targets: Creature[]): LogEntry {
@@ -185,15 +191,17 @@ class ChewAction extends GroupAction {
describe (user: Creature, target: Creature): LogEntry { describe (user: Creature, target: Creature): LogEntry {
return new LogLine('Do the crunch') return new LogLine('Do the crunch')
} }
}


constructor (private damage: DamageFormula, container: Container, private killAction: Action) {
super('Chew', 'Give them the big chew', [
new ContainsCondition(container)
class StompAction extends GroupAction {
constructor () {
super('Stomp', 'STOMP!', [
new TogetherCondition(),
new EnemyCondition(),
new CapableCondition()
]) ])
} }
}


class StompAction extends GroupAction {
line: PairLine<Creature> = (user, target) => new LogLine( line: PairLine<Creature> = (user, target) => new LogLine(
`${user.name.capital} ${user.name.conjugate(new Verb('flatten'))} ${target.name.objective} under ${user.pronouns.possessive} ${huge} foot!` `${user.name.capital} ${user.name.conjugate(new Verb('flatten'))} ${target.name.objective} under ${user.pronouns.possessive} ${huge} foot!`
) )
@@ -209,17 +217,17 @@ class StompAction extends GroupAction {
describeGroup (user: Creature, targets: Array<Creature>): LogEntry { describeGroup (user: Creature, targets: Array<Creature>): LogEntry {
return new LogLine('Stomp all ', targets.length.toString(), ' of \'em!') return new LogLine('Stomp all ', targets.length.toString(), ' of \'em!')
} }
}


class StompAllyAction extends Action {
constructor () { constructor () {
super('Stomp', 'STOMP!', [
super('Stomp Ally', '-1 ally, +1 buff', [
new TogetherCondition(), new TogetherCondition(),
new EnemyCondition(),
new AllyCondition(),
new CapableCondition() new CapableCondition()
]) ])
} }
}


class StompAllyAction extends Action {
line: PairLine<Creature> = (user, target) => new LogLine( line: PairLine<Creature> = (user, target) => new LogLine(
`${user.name.capital} ${user.name.conjugate(new Verb('flatten'))} ${target.name.objective} under ${user.pronouns.possessive} ${huge} boot!` `${user.name.capital} ${user.name.conjugate(new Verb('flatten'))} ${target.name.objective} under ${user.pronouns.possessive} ${huge} boot!`
) )
@@ -251,17 +259,20 @@ class StompAllyAction extends Action {
describe (user: Creature, target: Creature): LogEntry { describe (user: Creature, target: Creature): LogEntry {
return new LogLine('Crush an ally to absorb their power') return new LogLine('Crush an ally to absorb their power')
} }
}


constructor () {
super('Stomp Ally', '-1 ally, +1 buff', [
class DevourAllAction extends GroupAction {
private test: CombatTest

constructor (private container: VoreContainer) {
super('Devour All', 'GULP!', [
new TogetherCondition(), new TogetherCondition(),
new AllyCondition(),
new EnemyCondition(),
new CapableCondition() new CapableCondition()
]) ])
this.test = new StatVigorTest(Stat.Power)
} }
}


class DevourAllAction extends GroupAction {
line = (user: Creature, target: Creature) => new LogLine(`${user.name.capital} ${user.name.conjugate(new Verb('scoop'))} ${target.name} up!`) line = (user: Creature, target: Creature) => new LogLine(`${user.name.capital} ${user.name.conjugate(new Verb('scoop'))} ${target.name} up!`)


groupLine = (user: Creature, args: { count: number }) => new LogLine(`${Words.SwallowSound.allCaps}! All ${args.count} of ${user.pronouns.possessive} prey pour down ${user.name.possessive} ${Words.Slick} gullet as ${user.pronouns.subjective} ${user.name.conjugate(Words.Swallows)}; they're just ${user.kind.all} chow now`) groupLine = (user: Creature, args: { count: number }) => new LogLine(`${Words.SwallowSound.allCaps}! All ${args.count} of ${user.pronouns.possessive} prey pour down ${user.name.possessive} ${Words.Slick} gullet as ${user.pronouns.subjective} ${user.name.conjugate(Words.Swallows)}; they're just ${user.kind.all} chow now`)
@@ -287,17 +298,6 @@ class DevourAllAction extends GroupAction {
describeGroup (user: Creature, targets: Array<Creature>): LogEntry { describeGroup (user: Creature, targets: Array<Creature>): LogEntry {
return new LogLine('Eat all ', targets.length.toString(), ' of \'em!') return new LogLine('Eat all ', targets.length.toString(), ' of \'em!')
} }

private test: CombatTest

constructor (private container: VoreContainer) {
super('Devour All', 'GULP!', [
new TogetherCondition(),
new EnemyCondition(),
new CapableCondition()
])
this.test = new StatVigorTest(Stat.Power)
}
} }


export class Withers extends Creature { export class Withers extends Creature {


+ 12
- 12
src/game/language.ts View File

@@ -64,13 +64,13 @@ export type TextLike = { toString: () => string }


// updates as needed // updates as needed
export class LiveText<T> { export class LiveText<T> {
toString (): string {
return this.run(this.contents).toString()
}

constructor (private contents: T, private run: (thing: T) => TextLike) { constructor (private contents: T, private run: (thing: T) => TextLike) {


} }

toString (): string {
return this.run(this.contents).toString()
}
} }


export class DynText { export class DynText {
@@ -330,6 +330,10 @@ export class Adjective extends Word {
} }


export class Verb extends Word { export class Verb extends Word {
constructor (private _root: string, private _singular: string = _root + "s", private _present: string = _root + "ing", private _past: string = _root + "ed", private _pastParticiple: string = _past, public opt: WordOptions = emptyConfig) {
super(opt)
}

configure (opts: WordOptions): Word { configure (opts: WordOptions): Word {
return new Verb( return new Verb(
this._root, this._root,
@@ -360,14 +364,14 @@ export class Verb extends Word {


return choice return choice
} }

constructor (private _root: string, private _singular: string = _root + "s", private _present: string = _root + "ing", private _past: string = _root + "ed", private _pastParticiple: string = _past, public opt: WordOptions = emptyConfig) {
super(opt)
}
} }


// this one is obnoxious // this one is obnoxious
export class ToBe extends Word { export class ToBe extends Word {
constructor (protected opts: WordOptions = emptyConfig) {
super(opts)
}

configure (opts: WordOptions): Word { configure (opts: WordOptions): Word {
return new ToBe(opts) return new ToBe(opts)
} }
@@ -392,10 +396,6 @@ export class ToBe extends Word {


return choice return choice
} }

constructor (protected opts: WordOptions = emptyConfig) {
super(opts)
}
} }


interface PronounDict { interface PronounDict {


Loading…
Cancel
Save