100 lines
2.0 KiB
TypeScript
100 lines
2.0 KiB
TypeScript
import { Embed, MessageCreateOptions, MessagePayload, MessagePayloadOption } from "discord.js"
|
|
|
|
|
|
|
|
export interface MessageSink {
|
|
SendMessage(v:MessageCreateOptions):Promise<void>
|
|
}
|
|
|
|
export const ConsoleMessageSink: MessageSink = {
|
|
async SendMessage(v) {
|
|
console.log(v)
|
|
},
|
|
}
|
|
|
|
export interface RandomSource {
|
|
Range(start:number, stop:number):number
|
|
}
|
|
|
|
export const DefaultRandom:RandomSource = {
|
|
Range(start, stop) {
|
|
const ans = (stop - start) * Math.random() + start
|
|
return ans
|
|
}
|
|
}
|
|
|
|
export interface ActionFactory {
|
|
next(game: Game): Action
|
|
}
|
|
|
|
// an action is in charge of the entire state transition
|
|
export interface Action {
|
|
Before?(game:Game):MessageCreateOptions[]
|
|
Play?(game:Game):MessageCreateOptions[]
|
|
After?(game:Game):MessageCreateOptions[]
|
|
}
|
|
|
|
export const PlayActions = async (game:Game, actions:Action[]) => {
|
|
for(let i = 0; i < actions.length; i++) {
|
|
const a = actions[i];
|
|
[a.Before,a.Play,a.After].forEach(async (x)=>{
|
|
if(x){
|
|
const msgs = x(game)
|
|
msgs.forEach(async (msg)=>{
|
|
await game.sink.SendMessage(msg).catch(console.log)
|
|
})
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// track game state
|
|
export class Game {
|
|
// players in the game
|
|
players: {[index: string]:Player}
|
|
rng: RandomSource
|
|
sink:MessageSink
|
|
|
|
constructor() {
|
|
this.players = {}
|
|
this.rng = DefaultRandom
|
|
this.sink = ConsoleMessageSink
|
|
}
|
|
}
|
|
|
|
// player class tracks a players stats through out the game
|
|
export class Player {
|
|
// display name of character
|
|
name: string
|
|
// if health reaches 0 ur dead
|
|
health: number
|
|
|
|
// chance you are selected for combat
|
|
visibility: number
|
|
|
|
// chance you will win your next combat
|
|
power: number
|
|
|
|
constructor(name:string) {
|
|
this.health = 100
|
|
this.visibility = 50
|
|
this.power = 50
|
|
this.name = name
|
|
}
|
|
|
|
// bool is whether or not player is dead after damage
|
|
damage(v:number):boolean{
|
|
this.health = this.health - v
|
|
if(this.health <= 0) {
|
|
this.health = 0
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
alive() {
|
|
return this.health > 0
|
|
}
|
|
}
|
|
|