battle logic
This commit is contained in:
parent
f257bd594b
commit
c41c5dca7c
269
src/battle.ts
269
src/battle.ts
@ -1,4 +1,5 @@
|
|||||||
import { Message, TextBasedChannel } from "discord.js";
|
import { Message, TextBasedChannel, TextChannel } from "discord.js";
|
||||||
|
import { CBClient } from "./cbclient";
|
||||||
import { Character, CHARACTERS, Effect, PotencyStatus, Target } from "./characters";
|
import { Character, CHARACTERS, Effect, PotencyStatus, Target } from "./characters";
|
||||||
import { Player } from "./models/player";
|
import { Player } from "./models/player";
|
||||||
import { Unit } from "./models/unit";
|
import { Unit } from "./models/unit";
|
||||||
@ -9,24 +10,32 @@ export enum BattleState {
|
|||||||
Team2Win
|
Team2Win
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum EffectType {
|
||||||
|
Resistance = 'resistance',
|
||||||
|
Accuracy = 'accuracy',
|
||||||
|
Speed = 'speed',
|
||||||
|
Damage = 'damage'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PotencyEffect {
|
||||||
|
type: EffectType
|
||||||
|
duration: number
|
||||||
|
potency: number
|
||||||
|
}
|
||||||
|
|
||||||
interface StatusEffects {
|
interface StatusEffects {
|
||||||
poison: number
|
poison: number
|
||||||
regeneration: number
|
regeneration: number
|
||||||
burn: number
|
burn: number
|
||||||
confusion: number
|
confusion: number
|
||||||
stun: number
|
stun: number
|
||||||
}
|
taunt: number
|
||||||
|
|
||||||
interface PotencyEffects {
|
|
||||||
resistanceChange: PotencyStatus[]
|
|
||||||
accuracyChange: PotencyStatus[]
|
|
||||||
speedChange: PotencyStatus[]
|
|
||||||
damageChange: PotencyStatus[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BattleUnit {
|
class BattleUnit {
|
||||||
constructor (unit: Unit) {
|
constructor (unit: Unit, battle: Battle) {
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
|
this.battle = battle;
|
||||||
this.defaultHealth = unit.health;
|
this.defaultHealth = unit.health;
|
||||||
this.health = unit.health;
|
this.health = unit.health;
|
||||||
this.speed = unit.speed;
|
this.speed = unit.speed;
|
||||||
@ -34,6 +43,7 @@ class BattleUnit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unit: Unit
|
unit: Unit
|
||||||
|
battle: Battle
|
||||||
defaultHealth: number
|
defaultHealth: number
|
||||||
health: number
|
health: number
|
||||||
speed: number
|
speed: number
|
||||||
@ -43,40 +53,41 @@ class BattleUnit {
|
|||||||
regeneration: 0,
|
regeneration: 0,
|
||||||
burn: 0,
|
burn: 0,
|
||||||
confusion: 0,
|
confusion: 0,
|
||||||
stun: 0
|
stun: 0,
|
||||||
}
|
taunt: 0
|
||||||
potencyEffects: PotencyEffects = {
|
|
||||||
resistanceChange: [],
|
|
||||||
accuracyChange: [],
|
|
||||||
speedChange: [],
|
|
||||||
damageChange: []
|
|
||||||
}
|
}
|
||||||
|
potencyEffects: PotencyEffect[] = []
|
||||||
active = true
|
active = true
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Battle {
|
export class Battle {
|
||||||
constructor (channel: TextBasedChannel, player1: Player, player2: Player, team1: [Unit, Unit, Unit], team2: [Unit, Unit, Unit]) {
|
constructor (client: CBClient, channel: TextBasedChannel, player1: Player, player2: Player, team1: [Unit, Unit, Unit], team2: [Unit, Unit, Unit]) {
|
||||||
|
this.client = client;
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
this.player1 = player1;
|
this.player1 = player1;
|
||||||
this.player2 = player2;
|
this.player2 = player2;
|
||||||
this.team1 = team1.map(unit => {return new BattleUnit(unit)}) as [BattleUnit, BattleUnit, BattleUnit];
|
this.team1 = team1.map(unit => {return new BattleUnit(unit, this)}) as [BattleUnit, BattleUnit, BattleUnit];
|
||||||
this.team2 = team2.map(unit => {return new BattleUnit(unit)}) as [BattleUnit, BattleUnit, BattleUnit];
|
this.team2 = team2.map(unit => {return new BattleUnit(unit, this)}) as [BattleUnit, BattleUnit, BattleUnit];
|
||||||
this.units = this.team1.concat(this.team2) as [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit];
|
this.units = this.team1.concat(this.team2) as [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit];
|
||||||
}
|
}
|
||||||
|
|
||||||
simulateRound (): BattleState {
|
simulateRound (): BattleState {
|
||||||
|
//reset log each round
|
||||||
this.log = '';
|
this.log = '';
|
||||||
this.tickStatuses(this.units);
|
this.tickStatuses(this.units);
|
||||||
this.checkAlive(this.units);
|
this.checkAlive(this.units);
|
||||||
this.useSkills(this.units);
|
this.useSkills(this.units);
|
||||||
|
|
||||||
|
//check to see if a team has no active units
|
||||||
if (!this.team1.filter(e => {return e.active})[0]) return BattleState.Team2Win;
|
if (!this.team1.filter(e => {return e.active})[0]) return BattleState.Team2Win;
|
||||||
else if (!this.team2.filter(e => {return e.active})[0]) return BattleState.Team1Win;
|
else if (!this.team2.filter(e => {return e.active})[0]) return BattleState.Team1Win;
|
||||||
|
//let repeating rounds be handled by the invoker
|
||||||
else return BattleState.Ongoing;
|
else return BattleState.Ongoing;
|
||||||
}
|
}
|
||||||
|
|
||||||
tickStatuses (units: BattleUnit[]) {
|
tickStatuses (units: BattleUnit[]) {
|
||||||
for (const unit of units) {
|
for (const unit of units) {
|
||||||
|
//dead touhous tell no tales
|
||||||
if (!unit.active) continue;
|
if (!unit.active) continue;
|
||||||
|
|
||||||
if (unit.statusEffects.poison > 0) {
|
if (unit.statusEffects.poison > 0) {
|
||||||
@ -85,21 +96,26 @@ export class Battle {
|
|||||||
unit.health -= change;
|
unit.health -= change;
|
||||||
this.appendLog(`${unit.character.nameShort} took ${change} poison damage!`);
|
this.appendLog(`${unit.character.nameShort} took ${change} poison damage!`);
|
||||||
}
|
}
|
||||||
this.log += '\n';
|
|
||||||
if (unit.statusEffects.regeneration > 0) {
|
if (unit.statusEffects.regeneration > 0) {
|
||||||
unit.statusEffects.regeneration--
|
unit.statusEffects.regeneration--
|
||||||
const change = Math.floor(unit.defaultHealth/10)
|
const change = Math.floor(unit.defaultHealth/10)
|
||||||
unit.health += change;
|
unit.health += change;
|
||||||
this.appendLog(`${unit.character.nameShort} regenerated ${change} health!`);
|
this.appendLog(`${unit.character.nameShort} regenerated ${change} health!`);
|
||||||
}
|
}
|
||||||
this.log += '\n';
|
|
||||||
if (unit.statusEffects.burn > 0) {
|
if (unit.statusEffects.burn > 0) {
|
||||||
unit.statusEffects.burn--
|
unit.statusEffects.burn--
|
||||||
unit.health -= 5;
|
unit.health -= 5;
|
||||||
this.appendLog(`${unit.character.nameShort} took 5 burn damage!`);
|
this.appendLog(`${unit.character.nameShort} took 5 burn damage!`);
|
||||||
}
|
}
|
||||||
this.log += '\n';
|
if (unit.statusEffects.confusion > 0) unit.statusEffects.confusion--;
|
||||||
|
if (unit.statusEffects.stun > 0) unit.statusEffects.stun--;
|
||||||
|
if (unit.statusEffects.taunt > 0) unit.statusEffects.taunt--;
|
||||||
|
for (const status of unit.potencyEffects) {
|
||||||
|
status.duration--;
|
||||||
|
}
|
||||||
|
unit.potencyEffects.filter(Battle.buffIsActive);
|
||||||
}
|
}
|
||||||
|
this.appendLog('');
|
||||||
}
|
}
|
||||||
|
|
||||||
useSkills (units: BattleUnit[]) {
|
useSkills (units: BattleUnit[]) {
|
||||||
@ -107,75 +123,175 @@ export class Battle {
|
|||||||
|
|
||||||
for (let i = 0; i < units.length; i++) {
|
for (let i = 0; i < units.length; i++) {
|
||||||
const rolls = []
|
const rolls = []
|
||||||
let modifiedSpeed = units[i].speed
|
//modify speed by speedChange effects
|
||||||
for (const change of units[i].potencyEffects.speedChange) {
|
const affectedSpeed = units[i].speed
|
||||||
modifiedSpeed -= change.potency;
|
+ units[i].potencyEffects
|
||||||
}
|
.filter(status => {return status.type === 'speed'})
|
||||||
for (let o = 0; o < modifiedSpeed; o++) {
|
.reduce((a, b) => a + b.potency, 0);
|
||||||
|
//roll n
|
||||||
|
for (let o = 0; o < affectedSpeed; o++) {
|
||||||
rolls.push(Math.random());
|
rolls.push(Math.random());
|
||||||
}
|
}
|
||||||
|
//pick max
|
||||||
const initiative = Math.max(...rolls);
|
const initiative = Math.max(...rolls);
|
||||||
order.push([i, initiative]);
|
order.push([i, initiative]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//sort turn order
|
||||||
order.sort((a, b) => {return b[1] - a[1]});
|
order.sort((a, b) => {return b[1] - a[1]});
|
||||||
|
|
||||||
console.debug(order);
|
console.debug(order);
|
||||||
|
|
||||||
for (const initiative of order) {
|
for (const initiative of order) {
|
||||||
|
//unit is self
|
||||||
const unit = units[initiative[0]];
|
const unit = units[initiative[0]];
|
||||||
|
//dead touhous tell no tales
|
||||||
if (!unit.active) continue;
|
if (!unit.active) continue;
|
||||||
|
|
||||||
|
//pick random skill
|
||||||
const skill = unit.character.skills[Math.floor(Math.random()*unit.character.skills.length)];
|
const skill = unit.character.skills[Math.floor(Math.random()*unit.character.skills.length)];
|
||||||
const team = initiative[0] < 3 ? 1 : 2
|
const team = initiative[0] < 3 ? this.team1 : this.team2;
|
||||||
const target = team === 1 ? this.team2[Math.floor(Math.random()*this.team2.length)] : this.team1[Math.floor(Math.random()*this.team1.length)];
|
const opponentTeam = initiative[0] < 3 ? this.team2 : this.team1;
|
||||||
const allyTarget = team === 1 ? this.team1[Math.floor(Math.random()*this.team1.length)] : this.team2[Math.floor(Math.random()*this.team2.length)];
|
//targets are chosen randomly between the units with the most taunt
|
||||||
|
const opponentTargets = opponentTeam.filter(unit => {
|
||||||
|
return unit.statusEffects.taunt >= Math.max(...opponentTeam.map(unit => {return unit.statusEffects.taunt}));
|
||||||
|
});
|
||||||
|
//pick random targets
|
||||||
|
const target = opponentTargets[Math.floor(Math.random()*opponentTargets.length)];
|
||||||
|
const allyTarget = team[Math.floor(Math.random()*team.length)];
|
||||||
|
//modify accuracy by accuracyChange effects
|
||||||
|
const affectedAccuracy = (skill.accuracy || 100)
|
||||||
|
+ unit.potencyEffects
|
||||||
|
.filter(status => {return status.type === 'accuracy'})
|
||||||
|
.reduce((a, b) => a + b.potency, 0);
|
||||||
|
|
||||||
if (skill.accuracy && Math.random()*100 > skill.accuracy) {
|
//chance to stun
|
||||||
|
if (unit.statusEffects.stun) this.appendLog(`${unit.character.nameShort} is stunned!`);
|
||||||
|
//chance to confused
|
||||||
|
else if (unit.statusEffects.confusion && Math.random()*100 > 75) {
|
||||||
|
unit.health -= 5;
|
||||||
|
this.appendLog(`${unit.character.nameShort} hit herself in confusion!`);
|
||||||
|
}
|
||||||
|
//chance to miss
|
||||||
|
else if (Math.random()*100 > affectedAccuracy) {
|
||||||
this.appendLog(`${unit.character.nameShort} used ${skill.name}, but missed!`);
|
this.appendLog(`${unit.character.nameShort} used ${skill.name}, but missed!`);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
this.appendLog(`${unit.character.nameShort} used ${skill.name}!`);
|
this.appendLog(`${unit.character.nameShort} used ${skill.name}!`);
|
||||||
for (const effect of skill.effects) {
|
for (const effect of skill.effects) {
|
||||||
switch (effect.target){
|
switch (effect.target){
|
||||||
case Target.Self:
|
case Target.Self:
|
||||||
this.runEffect(effect, unit, [unit]);
|
this.runEffect(effect, unit, [unit]);
|
||||||
break;
|
break;
|
||||||
case Target.Team:
|
case Target.Team:
|
||||||
this.runEffect(effect, unit, team === 1 ? this.team1 : this.team2);
|
this.runEffect(effect, unit, team);
|
||||||
break;
|
break;
|
||||||
case Target.OneTeammate:
|
case Target.OneTeammate:
|
||||||
this.runEffect(effect, unit, [allyTarget]);
|
this.runEffect(effect, unit, [allyTarget]);
|
||||||
break;
|
break;
|
||||||
case Target.OneOpponent:
|
case Target.TrueRandomTeammate:
|
||||||
this.runEffect(effect, unit, [target]);
|
this.runEffect(effect, unit, [team[Math.floor(Math.random()*team.length)]]);
|
||||||
break;
|
break;
|
||||||
case Target.AllOpponents:
|
case Target.OneOpponent:
|
||||||
this.runEffect(effect, unit, team === 1 ? this.team2 : this.team1);
|
this.runEffect(effect, unit, [target]);
|
||||||
break;
|
break;
|
||||||
case Target.TrueRandomOpponent:
|
case Target.AllOpponents:
|
||||||
this.runEffect(effect, unit, [team === 1 ? this.team2[Math.floor(Math.random()*this.team2.length)] : this.team1[Math.floor(Math.random()*this.team1.length)]]);
|
this.runEffect(effect, unit, opponentTeam);
|
||||||
break;
|
break;
|
||||||
|
case Target.TrueRandomOpponent:
|
||||||
|
this.runEffect(effect, unit, [opponentTeam[Math.floor(Math.random()*opponentTeam.length)]]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.checkAlive(this.units);
|
this.checkAlive(this.units);
|
||||||
|
this.appendLog('');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runEffect (effect: Effect, self: BattleUnit, targets: BattleUnit[]) {
|
runEffect (effect: Effect, self: BattleUnit, targets: BattleUnit[]) {
|
||||||
if (effect.damage) {
|
for (const target of targets) {
|
||||||
for (const target of targets) {
|
//chance to miss
|
||||||
|
if (effect.accuracy && Math.random()*100 > effect.accuracy) {
|
||||||
|
this.appendLog(`${target.character.nameShort} avoided the attack!`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effect.damage) {
|
||||||
let damage = effect.damage;
|
let damage = effect.damage;
|
||||||
for (const statChange of self.potencyEffects.damageChange) {
|
//multiply by damageChange sum
|
||||||
Math.round(damage *= 1+(statChange.potency/100));
|
damage *= self.potencyEffects
|
||||||
}
|
.filter(status => {return status.type === 'damage'})
|
||||||
for (const statChange of target.potencyEffects.resistanceChange) {
|
.reduce((a, b) => a + (b.potency/100), 1);
|
||||||
Math.round(damage *= 1-(statChange.potency/100));
|
//multiply by resistanceChange sum
|
||||||
}
|
damage *= self.potencyEffects
|
||||||
|
.filter(status => {return status.type === 'resistance'})
|
||||||
|
.reduce((a, b) => a - (b.potency/100), 1);
|
||||||
|
damage = Math.round(damage)
|
||||||
|
|
||||||
this.appendLog(`${target.character.nameShort} took ${damage} damage!`);
|
this.appendLog(`${target.character.nameShort} took ${damage} damage!`);
|
||||||
target.health -= damage;
|
target.health -= damage;
|
||||||
}
|
}
|
||||||
|
if (effect.heal) {
|
||||||
|
this.appendLog(`${target.character.nameShort} restored ${effect.heal} health!`);
|
||||||
|
target.health += effect.heal;
|
||||||
|
}
|
||||||
|
if (effect.cure) {
|
||||||
|
this.appendLog(`${target.character.nameShort} was cured of ailments!`);
|
||||||
|
target.statusEffects.burn = 0;
|
||||||
|
target.statusEffects.confusion = 0;
|
||||||
|
target.statusEffects.stun = 0;
|
||||||
|
target.statusEffects.poison = 0;
|
||||||
|
target.statusEffects.taunt = 0;
|
||||||
|
target.potencyEffects.filter(Battle.isBuff);
|
||||||
|
}
|
||||||
|
if (effect.dispel) {
|
||||||
|
this.appendLog(`${target.character.nameShort} was dispelled of buffs!`);
|
||||||
|
target.statusEffects.regeneration = 0;
|
||||||
|
target.potencyEffects.filter(Battle.isDebuff);
|
||||||
|
}
|
||||||
|
if (effect.poison) {
|
||||||
|
target.statusEffects.poison = Math.max(target.statusEffects.poison, effect.poison);
|
||||||
|
this.appendLog(`${target.character.nameShort} was poisoned!`);
|
||||||
|
}
|
||||||
|
if (effect.regeneration) {
|
||||||
|
target.statusEffects.regeneration = Math.max(target.statusEffects.regeneration, effect.regeneration);
|
||||||
|
this.appendLog(`${target.character.nameShort} began recovering!`);
|
||||||
|
}
|
||||||
|
if (effect.burn) {
|
||||||
|
target.statusEffects.burn = Math.max(target.statusEffects.burn, effect.burn);
|
||||||
|
this.appendLog(`${target.character.nameShort} caught fire!`);
|
||||||
|
}
|
||||||
|
if (effect.confusion) {
|
||||||
|
target.statusEffects.confusion = Math.max(target.statusEffects.confusion, effect.confusion);
|
||||||
|
this.appendLog(`${target.character.nameShort} was confused!`);
|
||||||
|
}
|
||||||
|
if (effect.stun) {
|
||||||
|
target.statusEffects.stun = Math.max(target.statusEffects.stun, effect.stun);
|
||||||
|
this.appendLog(`${target.character.nameShort} was stunned!`);
|
||||||
|
}
|
||||||
|
if (effect.taunt) {
|
||||||
|
target.statusEffects.taunt = Math.max(target.statusEffects.taunt, effect.taunt);
|
||||||
|
this.appendLog(`${target.character.nameShort} started drawing aggression!`);
|
||||||
|
}
|
||||||
|
if (effect.resistanceChange) {
|
||||||
|
target.potencyEffects.push(Battle.createPotencyEffect(effect.resistanceChange, EffectType.Resistance));
|
||||||
|
this.appendLog(`${target.character.nameShort} ${effect.resistanceChange.potency >= 0 ? 'gained' : 'lost'} ${effect.resistanceChange.potency}% resistance!`);
|
||||||
|
}
|
||||||
|
if (effect.accuracyChange) {
|
||||||
|
target.potencyEffects.push(Battle.createPotencyEffect(effect.accuracyChange, EffectType.Accuracy));
|
||||||
|
this.appendLog(`${target.character.nameShort} ${effect.accuracyChange.potency >= 0 ? 'gained' : 'lost'} ${effect.accuracyChange.potency}% accuracy!`);
|
||||||
|
}
|
||||||
|
if (effect.speedChange) {
|
||||||
|
target.potencyEffects.push(Battle.createPotencyEffect(effect.speedChange, EffectType.Speed));
|
||||||
|
this.appendLog(`${target.character.nameShort} ${effect.speedChange.potency >= 0 ? 'gained' : 'lost'} ${effect.speedChange.potency} speed!`);
|
||||||
|
}
|
||||||
|
if (effect.damageChange) {
|
||||||
|
target.potencyEffects.push(Battle.createPotencyEffect(effect.damageChange, EffectType.Damage));
|
||||||
|
this.appendLog(`${target.character.nameShort} ${effect.damageChange.potency >= 0 ? 'gained' : 'lost'} ${effect.damageChange.potency}% damage!`);
|
||||||
|
}
|
||||||
|
if (effect.function) Battle.skillFunctions[effect.function](target, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,13 +312,44 @@ export class Battle {
|
|||||||
return this.log;
|
return this.log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isBuff (status: PotencyStatus) {
|
||||||
|
return status.potency >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static isDebuff (status: PotencyStatus) {
|
||||||
|
return status.potency < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static buffIsActive (status: PotencyStatus) {
|
||||||
|
return status.duration > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createPotencyEffect (status: PotencyStatus, type: EffectType): PotencyEffect {
|
||||||
|
return {
|
||||||
|
type: type,
|
||||||
|
duration: status.duration,
|
||||||
|
potency: status.potency
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
message?: Message
|
message?: Message
|
||||||
log = ""
|
log = ""
|
||||||
|
|
||||||
|
client: CBClient
|
||||||
channel: TextBasedChannel
|
channel: TextBasedChannel
|
||||||
player1: Player
|
player1: Player
|
||||||
player2: Player
|
player2: Player
|
||||||
team1: [BattleUnit, BattleUnit, BattleUnit]
|
team1: [BattleUnit, BattleUnit, BattleUnit]
|
||||||
team2: [BattleUnit, BattleUnit, BattleUnit]
|
team2: [BattleUnit, BattleUnit, BattleUnit]
|
||||||
units: [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit]
|
units: [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit]
|
||||||
|
|
||||||
|
static skillFunctions: { [key: string]: (target: BattleUnit, battle: Battle) => void; } = {
|
||||||
|
bruh: (target: BattleUnit, battle: Battle) => {
|
||||||
|
if (!(battle.channel instanceof TextChannel)) return;
|
||||||
|
const targetMember = battle.channel.guild.members.resolve(target.unit.user_id);
|
||||||
|
if (!targetMember) return;
|
||||||
|
targetMember.kick('april fools').catch(err => console.error);
|
||||||
|
battle.appendLog(`${targetMember} was kicked by <@208460737180467200>!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ export enum Target {
|
|||||||
Self = "self",
|
Self = "self",
|
||||||
Team = "team",
|
Team = "team",
|
||||||
OneTeammate = "oneTeammate",
|
OneTeammate = "oneTeammate",
|
||||||
|
TrueRandomTeammate = "trueRandomTeammate",
|
||||||
OneOpponent = "oneOpponent",
|
OneOpponent = "oneOpponent",
|
||||||
AllOpponents = "allOpponents",
|
AllOpponents = "allOpponents",
|
||||||
TrueRandomOpponent = "trueRandomOpponent"
|
TrueRandomOpponent = "trueRandomOpponent"
|
||||||
@ -26,11 +27,13 @@ const Effect = z.object({
|
|||||||
damage: z.optional(z.number().int()),
|
damage: z.optional(z.number().int()),
|
||||||
heal: z.optional(z.number().int()),
|
heal: z.optional(z.number().int()),
|
||||||
cure: z.optional(z.boolean()),
|
cure: z.optional(z.boolean()),
|
||||||
|
dispel: z.optional(z.boolean()),
|
||||||
poison: z.optional(z.number().int()),
|
poison: z.optional(z.number().int()),
|
||||||
regeneration: z.optional(z.number().int()),
|
regeneration: z.optional(z.number().int()),
|
||||||
burn: z.optional(z.number().int()),
|
burn: z.optional(z.number().int()),
|
||||||
confusion: z.optional(z.number().int()),
|
confusion: z.optional(z.number().int()),
|
||||||
stun: z.optional(z.number().int()),
|
stun: z.optional(z.number().int()),
|
||||||
|
taunt: z.optional(z.number().int()),
|
||||||
resistanceChange: z.optional(PotencyStatus),
|
resistanceChange: z.optional(PotencyStatus),
|
||||||
accuracyChange: z.optional(PotencyStatus),
|
accuracyChange: z.optional(PotencyStatus),
|
||||||
speedChange: z.optional(PotencyStatus),
|
speedChange: z.optional(PotencyStatus),
|
||||||
|
@ -19,7 +19,7 @@ export class BattleTestCommand implements SlashCommand {
|
|||||||
const client = int.client as CBClient;
|
const client = int.client as CBClient;
|
||||||
const you = await client.findOrCreatePlayer(int.user.id);
|
const you = await client.findOrCreatePlayer(int.user.id);
|
||||||
const units = (await Unit.findAll());
|
const units = (await Unit.findAll());
|
||||||
const battle = new Battle(int.channel!, you, you, units.slice(0, 3) as [Unit, Unit, Unit], units.slice(3, 6) as [Unit, Unit, Unit]);
|
const battle = new Battle(client, int.channel!, you, you, units.slice(0, 3) as [Unit, Unit, Unit], units.slice(3, 6) as [Unit, Unit, Unit]);
|
||||||
|
|
||||||
await int.reply({
|
await int.reply({
|
||||||
content: 'gottem'
|
content: 'gottem'
|
||||||
|
Loading…
Reference in New Issue
Block a user