diff --git a/src/battle.ts b/src/battle.ts new file mode 100644 index 0000000..eb1c087 --- /dev/null +++ b/src/battle.ts @@ -0,0 +1,109 @@ +import { Message, TextChannel } from "discord.js"; +import { Character, CHARACTERS, PotencyStatus } from "./characters"; +import { Player } from "./models/player"; +import { Unit } from "./models/unit"; + +interface StatusEffects { + poison: number + regeneration: number + burn: number + confusion: number +} + +interface PotencyEffects { + resistanceChange: PotencyStatus[] + accuracyChange: PotencyStatus[] + speedChange: PotencyStatus[] +} + +class BattleUnit { + constructor (unit: Unit) { + this.unit = unit; + this.defaultHealth = unit.health; + this.health = unit.health; + this.speed = unit.speed; + this.character = CHARACTERS.get(unit.character_id)!; + } + + unit: Unit + defaultHealth: number + health: number + speed: number + character: Character + statusEffects: StatusEffects = { + poison: 0, + regeneration: 0, + burn: 0, + confusion: 0 + } + potencyEffects: PotencyEffects = { + resistanceChange: [], + accuracyChange: [], + speedChange: [] + } + active = true +} + +export class Battle { + constructor (channel: TextChannel, player1: Player, player2: Player, team1: [Unit, Unit, Unit], team2: [Unit, Unit, Unit]) { + this.channel = channel; + this.player1 = player1; + this.player2 = player2; + this.team1 = team1.map(unit => {return new BattleUnit(unit)}) as [BattleUnit, BattleUnit, BattleUnit]; + this.team2 = team2.map(unit => {return new BattleUnit(unit)}) as [BattleUnit, BattleUnit, BattleUnit]; + this.units = this.team1.concat(this.team2) as [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit]; + } + + simulateRound () { + this.tickStatuses(this.units); + this.checkAlive(this.units); + } + + tickStatuses (units: BattleUnit[]) { + for (const unit of units) { + if (!unit.active) continue; + + if (unit.statusEffects.poison > 0) { + unit.statusEffects.poison-- + const change = Math.floor(unit.defaultHealth/12); + unit.health -= change; + this.appendLog(`${unit.character.nameShort} took ${change} poison damage!`); + } + this.log += '\n'; + if (unit.statusEffects.regeneration > 0) { + unit.statusEffects.regeneration-- + const change = Math.floor(unit.defaultHealth/10) + unit.health += change; + this.appendLog(`${unit.character.nameShort} regenerated ${change} health!`); + } + this.log += '\n'; + if (unit.statusEffects.burn > 0) { + unit.statusEffects.burn-- + unit.health -= 5; + this.appendLog(`${unit.character.nameShort} took 5 burn damage!`); + } + } + } + + checkAlive (units: BattleUnit[]) { + for (const unit of units) { + if (unit.health <= 0) unit.active = false; + } + } + + appendLog (str: string) { + if (this.log) this.log += '\n'; + this.log += str; + return this.log; + } + + message?: Message + log = "" + + channel: TextChannel + player1: Player + player2: Player + team1: [BattleUnit, BattleUnit, BattleUnit] + team2: [BattleUnit, BattleUnit, BattleUnit] + units: [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit] +} \ No newline at end of file diff --git a/src/characters.ts b/src/characters.ts index fe3afbf..4e12425 100644 --- a/src/characters.ts +++ b/src/characters.ts @@ -1,21 +1,48 @@ import charactersJSON from './characters.json' import { Collection } from 'discord.js' -export enum Type { - Something +enum Target { + Self = "self", + Team = "team", + OneOpponent = "oneOpponent", + AllOpponents = "allOpponents", + TrueRandomOpponent = "trueRandomOpponent" } -interface Character { - id: number; - name: string; - nameShort: string; - type: Type; - img: string; - stat1: number; - stat2: number; - stat3: number; - stat4: number; - stat5: number; +export interface PotencyStatus { + duration: number + potency: number +} + +interface Effect { + target: Target + accuracy?: number + damage?: number + heal?: number + poison?: number + regeneration?: number + burn?: number + confusion?: number + resistanceChange?: PotencyStatus + accuracyChange?: PotencyStatus + speedChange?: PotencyStatus + function?: string +} + +interface Skill { + name: string + accuracy?: number + effects: Effect[] +} + +export interface Character { + id: number + name: string + nameShort: string + img: string + health: number + speed: number + skills: [Skill, Skill, Skill] } export const CHARACTERS: Collection = new Collection(charactersJSON.map((element, index) => {return [index, element]})); \ No newline at end of file diff --git a/src/database.ts b/src/database.ts index 01ded09..f833bee 100644 --- a/src/database.ts +++ b/src/database.ts @@ -59,19 +59,10 @@ Unit.init({ character_id: { type: DataTypes.INTEGER }, - stat1: { + health: { type: DataTypes.INTEGER }, - stat2: { - type: DataTypes.INTEGER - }, - stat3: { - type: DataTypes.INTEGER - }, - stat4: { - type: DataTypes.INTEGER - }, - stat5: { + speed: { type: DataTypes.INTEGER } }, diff --git a/src/models/unit.ts b/src/models/unit.ts index b759da6..fff994b 100644 --- a/src/models/unit.ts +++ b/src/models/unit.ts @@ -3,9 +3,6 @@ import { CreationOptional, InferAttributes, InferCreationAttributes, Model } fro export class Unit extends Model, InferCreationAttributes> { declare user_id: string declare character_id: number - declare stat1: number - declare stat2: number - declare stat3: number - declare stat4: number - declare stat5: number + declare health: number + declare speed: number } \ No newline at end of file diff --git a/src/slash/roll.ts b/src/slash/roll.ts index 98ac8b1..691e6fb 100644 --- a/src/slash/roll.ts +++ b/src/slash/roll.ts @@ -26,11 +26,8 @@ export class RollCommand implements SlashCommand { await Unit.create({ user_id: int.user.id, character_id: character.id, - stat1: character.stat1, - stat2: character.stat2, - stat3: character.stat3, - stat4: character.stat4, - stat5: character.stat5 + health: character.health, + speed: character.speed }); return int.reply({