i almost just lost a whole file i'm committing my changes
This commit is contained in:
parent
c86864a1ff
commit
b1035bfa6a
@ -1,6 +1,6 @@
|
||||
import { Message, TextBasedChannel, TextChannel } from "discord.js";
|
||||
import { Message, TextBasedChannel } from "discord.js";
|
||||
import { CBClient } from "./cbclient";
|
||||
import { Character, CHARACTERS, Effect, PotencyStatus, Target } from "./characters";
|
||||
import { CHARACTERS, Character, Effect, PotencyStatus, Target } from "./characters";
|
||||
import { Player } from "./models/player";
|
||||
import { Unit } from "./models/unit";
|
||||
|
||||
@ -33,16 +33,16 @@ interface StatusEffects {
|
||||
}
|
||||
|
||||
class BattleUnit {
|
||||
constructor (unit: Unit, battle: Battle) {
|
||||
constructor (unit: {user_id: string, character_id: number}, battle: Battle) {
|
||||
this.unit = unit;
|
||||
this.battle = battle;
|
||||
this.defaultHealth = unit.health;
|
||||
this.health = unit.health;
|
||||
this.speed = unit.speed;
|
||||
this.character = CHARACTERS.get(unit.character_id)!;
|
||||
this.defaultHealth = this.character.health;
|
||||
this.health = this.character.health;
|
||||
this.speed = this.character.speed;
|
||||
}
|
||||
|
||||
unit: Unit
|
||||
unit: {user_id: string, character_id: number}
|
||||
battle: Battle
|
||||
defaultHealth: number
|
||||
health: number
|
||||
@ -150,8 +150,9 @@ export class Battle {
|
||||
|
||||
//pick random skill
|
||||
const skill = unit.character.skills[Math.floor(Math.random()*unit.character.skills.length)];
|
||||
const team = initiative[0] < 3 ? this.team1 : this.team2;
|
||||
const opponentTeam = initiative[0] < 3 ? this.team2 : this.team1;
|
||||
const team = initiative[0] < 3 ? this.team1.filter(Battle.filterActive) : this.team2.filter(Battle.filterActive);
|
||||
const opponentTeam = initiative[0] < 3 ? this.team2.filter(Battle.filterActive) : this.team1.filter(Battle.filterActive);
|
||||
const activeUnits = this.units.filter(Battle.filterActive);
|
||||
//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}));
|
||||
@ -201,6 +202,9 @@ export class Battle {
|
||||
case Target.TrueRandomOpponent:
|
||||
this.runEffect(effect, unit, [opponentTeam[Math.floor(Math.random()*opponentTeam.length)]]);
|
||||
break;
|
||||
case Target.TrueRandom:
|
||||
this.runEffect(effect, unit, [activeUnits[Math.floor(Math.random()*activeUnits.length)]]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,6 +215,8 @@ export class Battle {
|
||||
}
|
||||
|
||||
runEffect (effect: Effect, self: BattleUnit, targets: BattleUnit[]) {
|
||||
if (!targets[0]) return;
|
||||
|
||||
for (const target of targets) {
|
||||
//chance to miss
|
||||
if (effect.accuracy && Math.random()*100 > effect.accuracy) {
|
||||
@ -277,19 +283,19 @@ export class Battle {
|
||||
}
|
||||
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!`);
|
||||
this.appendLog(`${target.character.nameShort} ${effect.resistanceChange.potency >= 0 ? 'gained' : 'lost'} ${Math.abs(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!`);
|
||||
this.appendLog(`${target.character.nameShort} ${effect.accuracyChange.potency >= 0 ? 'gained' : 'lost'} ${Math.abs(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!`);
|
||||
this.appendLog(`${target.character.nameShort} ${effect.speedChange.potency >= 0 ? 'gained' : 'lost'} ${Math.abs(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!`);
|
||||
this.appendLog(`${target.character.nameShort} ${effect.damageChange.potency >= 0 ? 'gained' : 'lost'} ${Math.abs(effect.damageChange.potency)}% damage!`);
|
||||
}
|
||||
if (effect.function) Battle.skillFunctions[effect.function](target, this);
|
||||
}
|
||||
@ -332,6 +338,10 @@ export class Battle {
|
||||
};
|
||||
}
|
||||
|
||||
static filterActive (unit: BattleUnit) {
|
||||
return unit.active;
|
||||
}
|
||||
|
||||
message?: Message
|
||||
log = ""
|
||||
|
||||
@ -345,7 +355,7 @@ export class Battle {
|
||||
|
||||
static skillFunctions: { [key: string]: (target: BattleUnit, battle: Battle) => void; } = {
|
||||
bruh: (target: BattleUnit, battle: Battle) => {
|
||||
if (!(battle.channel instanceof TextChannel)) return;
|
||||
if (battle.channel.isDMBased()) return;
|
||||
const targetMember = battle.channel.guild.members.resolve(target.unit.user_id);
|
||||
if (!targetMember) return;
|
||||
targetMember.kick('april fools').catch(err => console.error);
|
||||
|
112
src/cbclient.ts
112
src/cbclient.ts
@ -1,27 +1,125 @@
|
||||
import { Snowflake } from "discord.js";
|
||||
import { ClientOptions, Collection, Message, Snowflake } from "discord.js";
|
||||
import { CommandClient } from "./commandclient";
|
||||
import { Player } from "./models/player";
|
||||
import { Battle } from "./battle";
|
||||
import { Sequelize } from "sequelize";
|
||||
import { Unit } from "./models/unit";
|
||||
import { CHARACTERS } from "./characters";
|
||||
|
||||
export class Challenge {
|
||||
constructor (player1: Player, player2: Player, message: Message) {
|
||||
this.player1 = player1;
|
||||
this.player2 = player2;
|
||||
this.message = message
|
||||
this.id = player1.user_id + player2.user_id;
|
||||
}
|
||||
|
||||
player1: Player
|
||||
player2: Player
|
||||
message: Message
|
||||
id: string
|
||||
created = Date.now()
|
||||
}
|
||||
|
||||
export class ActiveBattle {
|
||||
constructor (battle: Battle, message: Message) {
|
||||
this.battle = battle;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
sendRound () {
|
||||
|
||||
}
|
||||
|
||||
static async create (battle: Battle) {
|
||||
const activeBattle = new ActiveBattle(battle, (await battle.channel.send('initial battle state')));
|
||||
return activeBattle;
|
||||
}
|
||||
|
||||
battle: Battle
|
||||
message: Message
|
||||
}
|
||||
|
||||
export class CBClient extends CommandClient {
|
||||
async createPlayer(user_id: Snowflake) {
|
||||
return await Player.create({
|
||||
constructor (options: ClientOptions, db: Sequelize) {
|
||||
super(options, db);
|
||||
|
||||
this.on('interactionCreate', async (int) => {
|
||||
if (!int.isButton() || !int.channel || int.channel.isDMBased()) return;
|
||||
|
||||
const defaultUnit = await Unit.findOne({ where: { id: 0 } }) as Unit;
|
||||
|
||||
const challenge = this.CHALLENGES.get(int.customId);
|
||||
if (!challenge || challenge.created+60_000 < Date.now()) {
|
||||
int.reply("That challenge has expired!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (int.user.id != challenge.player2.user_id) {
|
||||
int.reply("You can't accept someone else's challenge!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.ACTIVE_BATTLES.find(e => {
|
||||
return [challenge.player1.user_id, challenge.player2.user_id].includes(e.battle.player1.user_id)
|
||||
|| [challenge.player1.user_id, challenge.player2.user_id].includes(e.battle.player2.user_id);
|
||||
})) {
|
||||
int.reply("A participant is already in a battle!");
|
||||
return;
|
||||
}
|
||||
|
||||
await challenge.message.delete();
|
||||
this.CHALLENGES.delete(challenge.id);
|
||||
|
||||
const team1: [Unit, Unit, Unit] = [
|
||||
await Unit.findOne({ where: { id: challenge.player1.slot1 } }) || defaultUnit,
|
||||
await Unit.findOne({ where: { id: challenge.player1.slot2 } }) || defaultUnit,
|
||||
await Unit.findOne({ where: { id: challenge.player1.slot3 } }) || defaultUnit
|
||||
]
|
||||
const team2: [Unit, Unit, Unit] = [
|
||||
await Unit.findOne({ where: { id: challenge.player2.slot1 } }) || defaultUnit,
|
||||
await Unit.findOne({ where: { id: challenge.player2.slot2 } }) || defaultUnit,
|
||||
await Unit.findOne({ where: { id: challenge.player2.slot3 } }) || defaultUnit
|
||||
]
|
||||
const battle = new Battle(this, int.channel, challenge.player1, challenge.player2, team1, team2);
|
||||
const activeBattle = new ActiveBattle(battle,
|
||||
await int.channel.send({
|
||||
content: 'wooo'
|
||||
}
|
||||
));
|
||||
this.ACTIVE_BATTLES.push();
|
||||
});
|
||||
}
|
||||
|
||||
readonly CHALLENGES: Collection<string, Challenge> = new Collection()
|
||||
readonly ACTIVE_BATTLES: ActiveBattle[] = []
|
||||
|
||||
static async createPlayer(user_id: Snowflake) {
|
||||
return Player.create({
|
||||
user_id: user_id,
|
||||
start: Math.floor(Date.now()/1000)
|
||||
});
|
||||
}
|
||||
|
||||
async findOrCreatePlayer(user_id: Snowflake) {
|
||||
static async initializePlayer(user_id: Snowflake) {
|
||||
Unit.create({ user_id: user_id, character_id: CHARACTERS.randomKey()! });
|
||||
Unit.create({ user_id: user_id, character_id: CHARACTERS.randomKey()! });
|
||||
Unit.create({ user_id: user_id, character_id: CHARACTERS.randomKey()! });
|
||||
return CBClient.createPlayer(user_id);
|
||||
}
|
||||
|
||||
static async findOrCreatePlayer(user_id: Snowflake) {
|
||||
const player = await Player.findOne({
|
||||
where: {
|
||||
user_id: user_id
|
||||
}
|
||||
});
|
||||
|
||||
if (!player) return await this.createPlayer(user_id);
|
||||
if (!player) return await CBClient.initializePlayer(user_id);
|
||||
return player;
|
||||
}
|
||||
|
||||
async spendOnPlayer(player: Player, amount: number) {
|
||||
static async spendOnPlayer(player: Player, amount: number) {
|
||||
const currency = Date.now() - player.start - player.spent;
|
||||
|
||||
if (currency - amount < 0) return false;
|
||||
@ -29,7 +127,7 @@ export class CBClient extends CommandClient {
|
||||
return true;
|
||||
}
|
||||
|
||||
async grantMoneyToPlayer(player: Player, amount: number) {
|
||||
static async grantMoneyToPlayer(player: Player, amount: number) {
|
||||
await player.update("spent", player.spent-amount);
|
||||
return;
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ export enum Target {
|
||||
TrueRandomTeammate = "trueRandomTeammate",
|
||||
OneOpponent = "oneOpponent",
|
||||
AllOpponents = "allOpponents",
|
||||
TrueRandomOpponent = "trueRandomOpponent"
|
||||
TrueRandomOpponent = "trueRandomOpponent",
|
||||
TrueRandom = "trueRandom"
|
||||
}
|
||||
|
||||
const TargetEnum = z.nativeEnum(Target);
|
||||
@ -64,5 +65,5 @@ const CharacterJSON = z.array(Character);
|
||||
type CharacterJSON = z.infer<typeof CharacterJSON>;
|
||||
|
||||
export const CHARACTERS: Collection<number, Character> = (() => {
|
||||
return new Collection(CharacterJSON.parse(charactersJSON).map((element, index) => {return [index, element]}));
|
||||
return new Collection(CharacterJSON.parse(charactersJSON).map((element, index) => {return [element.id, element]}));
|
||||
})();
|
@ -1,13 +1,13 @@
|
||||
{
|
||||
"command": {
|
||||
"guildOnly": "that command doesn't work in DMs!",
|
||||
"ownerOnly": "you can't use that command if you don't own this bot...",
|
||||
"noPermission": "you aren't allowed to use that command!",
|
||||
"noArguments": "i can't do anything without the command arguments!",
|
||||
"missingArguments": "you're missing arguments!",
|
||||
"guildOnly": "That command doesn't work in DMs!",
|
||||
"ownerOnly": "You can't use that command if you don't own this bot!",
|
||||
"noPermission": "You aren't allowed to use that command!",
|
||||
"noArguments": "I can't do anything without the command arguments!",
|
||||
"missingArguments": "You're missing arguments!",
|
||||
"invalidArgument": "`{1}` is invalid!",
|
||||
"usagePrefix": "the proper usage would be: ",
|
||||
"onCooldown": "you need to wait {1} more seconds before reusing the `{2}` command!"
|
||||
"usagePrefix": "The proper usage would be: ",
|
||||
"onCooldown": "You need to wait {1} more seconds before reusing the `{2}` command!"
|
||||
},
|
||||
"error": "there was an error, shout at hexugory and hope he hears you!"
|
||||
"error": "There was an error, april fools???"
|
||||
}
|
@ -45,6 +45,25 @@ Player.init({
|
||||
spent: {
|
||||
type: DataTypes.BIGINT,
|
||||
defaultValue: 0
|
||||
},
|
||||
elo: {
|
||||
type: DataTypes.INTEGER,
|
||||
defaultValue: 400
|
||||
},
|
||||
slot1: {
|
||||
type: DataTypes.INTEGER,
|
||||
defaultValue: null,
|
||||
allowNull: true
|
||||
},
|
||||
slot2: {
|
||||
type: DataTypes.INTEGER,
|
||||
defaultValue: null,
|
||||
allowNull: true
|
||||
},
|
||||
slot3: {
|
||||
type: DataTypes.INTEGER,
|
||||
defaultValue: null,
|
||||
allowNull: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -53,17 +72,16 @@ Player.init({
|
||||
});
|
||||
|
||||
Unit.init({
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true
|
||||
},
|
||||
user_id: {
|
||||
type: DataTypes.TEXT
|
||||
},
|
||||
character_id: {
|
||||
type: DataTypes.INTEGER
|
||||
},
|
||||
health: {
|
||||
type: DataTypes.INTEGER
|
||||
},
|
||||
speed: {
|
||||
type: DataTypes.INTEGER
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -4,4 +4,8 @@ export class Player extends Model<InferAttributes<Player>, InferCreationAttribut
|
||||
declare readonly user_id: string
|
||||
declare start: number
|
||||
declare spent: CreationOptional<number>
|
||||
declare elo: CreationOptional<number>
|
||||
declare slot1: CreationOptional<number>
|
||||
declare slot2: CreationOptional<number>
|
||||
declare slot3: CreationOptional<number>
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
import { CreationOptional, InferAttributes, InferCreationAttributes, Model } from "sequelize";
|
||||
|
||||
export class Unit extends Model<InferAttributes<Unit>, InferCreationAttributes<Unit>> {
|
||||
declare id: CreationOptional<number>
|
||||
declare user_id: string
|
||||
declare character_id: number
|
||||
declare health: number
|
||||
declare speed: number
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
import { ApplicationCommandOptionData, ApplicationCommandOptionType, CommandInteraction } from "discord.js"
|
||||
import { ApplicationCommandOptionData, CommandInteraction } from "discord.js"
|
||||
import { Battle, BattleState } from "../battle"
|
||||
import { CBClient } from "../cbclient"
|
||||
import { CHARACTERS } from "../characters"
|
||||
import { Player } from "../models/player"
|
||||
import { Unit } from "../models/unit"
|
||||
import { createArgumentsObject, SlashCommand } from "./slash"
|
||||
import { SlashCommand } from "./slash"
|
||||
|
||||
export class BattleTestCommand implements SlashCommand {
|
||||
name = 'battletest'
|
||||
@ -17,7 +15,7 @@ export class BattleTestCommand implements SlashCommand {
|
||||
|
||||
async execute(int: CommandInteraction) {
|
||||
const client = int.client as CBClient;
|
||||
const you = await client.findOrCreatePlayer(int.user.id);
|
||||
const you = await CBClient.findOrCreatePlayer(int.user.id);
|
||||
const units = (await Unit.findAll());
|
||||
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]);
|
||||
|
||||
|
54
src/slash/challenge.ts
Normal file
54
src/slash/challenge.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { ActionRowBuilder, ApplicationCommandOptionData, ApplicationCommandOptionType, ButtonBuilder, ButtonStyle, CommandInteraction, GuildMember } from "discord.js"
|
||||
import { CBClient, Challenge } from "../cbclient"
|
||||
import { SlashCommand, createArgumentsObject } from "./slash"
|
||||
|
||||
interface ChallengeArguments {
|
||||
opponent: GuildMember
|
||||
}
|
||||
|
||||
export class ChallengeCommand implements SlashCommand {
|
||||
name = 'challenge'
|
||||
description = 'Challenge a player to a danmaku battle!'
|
||||
permission = []
|
||||
ownerOnly = false
|
||||
guildOnly = true
|
||||
guildID = "739645806100873328" //for testing
|
||||
args: ApplicationCommandOptionData[] = [
|
||||
{
|
||||
name: 'opponent',
|
||||
type: ApplicationCommandOptionType.User,
|
||||
description: "Who to challenge",
|
||||
required: true
|
||||
}
|
||||
]
|
||||
|
||||
async execute(int: CommandInteraction) {
|
||||
const args = createArgumentsObject<ChallengeArguments>(int.options.data);
|
||||
const client = int.client as CBClient;
|
||||
|
||||
const player1 = await CBClient.findOrCreatePlayer(int.user.id);
|
||||
const player2 = await CBClient.findOrCreatePlayer(args.opponent.id);
|
||||
|
||||
if (!player1.slot1 || !player1.slot2 || !player1.slot3) return int.reply({
|
||||
content: "You don't have a full team!",
|
||||
ephemeral: true
|
||||
});
|
||||
if (!player2.slot1 || !player2.slot2 || !player2.slot3) return int.reply({
|
||||
content: "Your opponent doesn't have a full team!",
|
||||
ephemeral: true
|
||||
});
|
||||
|
||||
const challenge = new Challenge(player1, player2, await int.reply({
|
||||
content: `${args.opponent}, you have been challenged!`,
|
||||
fetchReply: true,
|
||||
components: [new ActionRowBuilder<ButtonBuilder>()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId(player1.user_id+player2.user_id)
|
||||
.setLabel('Accept')
|
||||
.setStyle(ButtonStyle.Success)
|
||||
)]
|
||||
}));
|
||||
return client.CHALLENGES.set(challenge.id, challenge);
|
||||
}
|
||||
};
|
@ -1,12 +1,20 @@
|
||||
import { ChallengeCommand } from "./challenge";
|
||||
import { BattleTestCommand } from "./battletest";
|
||||
import { InitCommand } from "./init";
|
||||
import { RandomCaseCommand } from "./randomcase";
|
||||
import { RollCommand } from "./roll";
|
||||
import { SlashCommand } from "./slash";
|
||||
import { GrantCommand } from "./grant";
|
||||
import { EquipCommand } from "./equip";
|
||||
import { ListCommand } from "./list";
|
||||
|
||||
export const SlashCommandList: SlashCommand[] = [
|
||||
new RandomCaseCommand(),
|
||||
new InitCommand(),
|
||||
new RollCommand(),
|
||||
new BattleTestCommand()
|
||||
new BattleTestCommand(),
|
||||
new ChallengeCommand(),
|
||||
new GrantCommand(),
|
||||
new EquipCommand(),
|
||||
new ListCommand()
|
||||
];
|
69
src/slash/equip.ts
Normal file
69
src/slash/equip.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { ApplicationCommandOptionData, ApplicationCommandOptionType, CommandInteraction, User } from "discord.js"
|
||||
import { CBClient } from "../cbclient"
|
||||
import { CHARACTERS } from "../characters"
|
||||
import { Unit } from "../models/unit"
|
||||
import { createArgumentsObject, SlashCommand } from "./slash"
|
||||
|
||||
interface EquipArguments {
|
||||
slot: number
|
||||
unit: number
|
||||
}
|
||||
|
||||
export class EquipCommand implements SlashCommand {
|
||||
name = 'equip'
|
||||
description = 'Equip a unit'
|
||||
permission = []
|
||||
ownerOnly = false
|
||||
guildOnly = false
|
||||
guildID = "739645806100873328" //for testing
|
||||
args: ApplicationCommandOptionData[] = [
|
||||
{
|
||||
name: 'slot',
|
||||
type: ApplicationCommandOptionType.Integer,
|
||||
description: "The slot to equip to",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'unit',
|
||||
type: ApplicationCommandOptionType.Integer,
|
||||
description: "The unit ID to equip",
|
||||
required: true
|
||||
}
|
||||
]
|
||||
|
||||
async execute(int: CommandInteraction) {
|
||||
const args = createArgumentsObject<EquipArguments>(int.options.data);
|
||||
const client = int.client as CBClient;
|
||||
const player = await CBClient.findOrCreatePlayer(int.user.id);
|
||||
|
||||
if (!(await Unit.findOne( { where: { user_id: int.user.id, id: args.unit } } ))) return int.reply({
|
||||
content: `That isn't your unit!`
|
||||
});
|
||||
|
||||
if (player.slot1 === args.unit) player.set({slot1:undefined});
|
||||
if (player.slot2 === args.unit) player.set({slot2:undefined});
|
||||
if (player.slot3 === args.unit) player.set({slot3:undefined});
|
||||
|
||||
switch (args.slot) {
|
||||
case 1:
|
||||
player.set({slot1:args.unit});
|
||||
break;
|
||||
case 2:
|
||||
player.set({slot2:args.unit});
|
||||
break;
|
||||
case 3:
|
||||
player.set({slot3:args.unit});
|
||||
break;
|
||||
default:
|
||||
await player.save();
|
||||
return int.reply({
|
||||
content: `Invalid slot.`
|
||||
});
|
||||
}
|
||||
|
||||
await player.save();
|
||||
return int.reply({
|
||||
content: `Equipped to slot ${args.slot}.`
|
||||
});
|
||||
}
|
||||
};
|
51
src/slash/grant.ts
Normal file
51
src/slash/grant.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { ApplicationCommandOptionData, ApplicationCommandOptionType, CommandInteraction, User } from "discord.js"
|
||||
import { CBClient } from "../cbclient"
|
||||
import { CHARACTERS } from "../characters"
|
||||
import { Unit } from "../models/unit"
|
||||
import { createArgumentsObject, SlashCommand } from "./slash"
|
||||
|
||||
interface GrantArguments {
|
||||
user: User
|
||||
character: number
|
||||
}
|
||||
|
||||
export class GrantCommand implements SlashCommand {
|
||||
name = 'grant'
|
||||
description = 'Grant someone a character'
|
||||
permission = []
|
||||
ownerOnly = true
|
||||
guildOnly = false
|
||||
guildID = "739645806100873328" //for testing
|
||||
args: ApplicationCommandOptionData[] = [
|
||||
{
|
||||
name: 'user',
|
||||
type: ApplicationCommandOptionType.User,
|
||||
description: "Who to grant to",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'character',
|
||||
type: ApplicationCommandOptionType.Integer,
|
||||
description: "Character ID",
|
||||
required: true
|
||||
}
|
||||
]
|
||||
|
||||
async execute(int: CommandInteraction) {
|
||||
const args = createArgumentsObject<GrantArguments>(int.options.data);
|
||||
|
||||
const character = CHARACTERS.get(args.character);
|
||||
if (!character) return int.reply({
|
||||
content: `That's not a character`,
|
||||
ephemeral: true
|
||||
});
|
||||
await Unit.create({
|
||||
user_id: args.user.id,
|
||||
character_id: character.id
|
||||
});
|
||||
|
||||
return int.reply({
|
||||
content: `${args.user} got **${character.name}**!`
|
||||
});
|
||||
}
|
||||
};
|
@ -1,6 +1,7 @@
|
||||
import { ApplicationCommandOptionData, ApplicationCommandOptionType, CommandInteraction } from "discord.js"
|
||||
import { Player } from "../models/player"
|
||||
import { SlashCommand } from "./slash"
|
||||
import { CBClient } from "../cbclient"
|
||||
|
||||
export class InitCommand implements SlashCommand {
|
||||
name = 'init'
|
||||
@ -12,21 +13,7 @@ export class InitCommand implements SlashCommand {
|
||||
args: ApplicationCommandOptionData[] = []
|
||||
|
||||
async execute(int: CommandInteraction) {
|
||||
const player = await Player.findOne({
|
||||
where: {
|
||||
user_id: int.user.id
|
||||
}
|
||||
});
|
||||
|
||||
if (player) return int.reply({
|
||||
content: "You're already in the game.",
|
||||
ephemeral: true
|
||||
});
|
||||
|
||||
Player.create({
|
||||
user_id: int.user.id,
|
||||
start: Math.floor(Date.now()/1000)
|
||||
});
|
||||
await CBClient.findOrCreatePlayer(int.user.id);
|
||||
|
||||
return int.reply({
|
||||
content: "You've been added to the game.",
|
||||
|
57
src/slash/list.ts
Normal file
57
src/slash/list.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { ApplicationCommandOptionData, ApplicationCommandOptionType, CommandInteraction, EmbedBuilder, User } from "discord.js"
|
||||
import { CBClient } from "../cbclient"
|
||||
import { CHARACTERS } from "../characters"
|
||||
import { Unit } from "../models/unit"
|
||||
import { createArgumentsObject, SlashCommand } from "./slash"
|
||||
|
||||
interface ListArguments {
|
||||
page?: number
|
||||
}
|
||||
|
||||
export class ListCommand implements SlashCommand {
|
||||
name = 'list'
|
||||
description = 'List your units'
|
||||
permission = []
|
||||
ownerOnly = false
|
||||
guildOnly = false
|
||||
guildID = "739645806100873328" //for testing
|
||||
args: ApplicationCommandOptionData[] = [
|
||||
{
|
||||
name: 'page',
|
||||
type: ApplicationCommandOptionType.Integer,
|
||||
description: "The page to view",
|
||||
required: false
|
||||
}
|
||||
]
|
||||
|
||||
async execute(int: CommandInteraction) {
|
||||
const args = createArgumentsObject<ListArguments>(int.options.data);
|
||||
if (!args.page) args.page = 1;
|
||||
args.page = Math.max(args.page, 1);
|
||||
const player = await CBClient.findOrCreatePlayer(int.user.id);
|
||||
|
||||
const units = await Unit.findAll({ where: { user_id: int.user.id } });
|
||||
|
||||
let liststr = '';
|
||||
for (let i = (args.page-1)*10; i < Math.min(args.page*10, units.length); i++) {
|
||||
const character = CHARACTERS.get(units[i].character_id)!;
|
||||
liststr += `${units[i].id}: ${character.name}\n`;
|
||||
}
|
||||
|
||||
const slot1 = await Unit.findOne({ where: { id: player.slot1 } });
|
||||
const slot2 = await Unit.findOne({ where: { id: player.slot2 } });
|
||||
const slot3 = await Unit.findOne({ where: { id: player.slot3 } });
|
||||
const character1 = CHARACTERS.get(slot1?.character_id || -1);
|
||||
const character2 = CHARACTERS.get(slot2?.character_id || -1);
|
||||
const character3 = CHARACTERS.get(slot3?.character_id || -1);
|
||||
|
||||
return int.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle(`${int.user.username}'s Units`)
|
||||
.setDescription(liststr || 'Empty...')
|
||||
.addFields({ name: 'Equipped', value: `1: ${character1 ? character1.name + ` (${slot1?.id})` : 'Empty'}\n2: ${character2 ? character2.name + ` (${slot2?.id})` : 'Empty'}\n3: ${character3 ? character3.name + ` (${slot3?.id})` : 'Empty'}` })
|
||||
]
|
||||
});
|
||||
}
|
||||
};
|
@ -21,7 +21,7 @@ export class RandomCaseCommand implements SlashCommand {
|
||||
]
|
||||
|
||||
async execute(int: CommandInteraction) {
|
||||
const args = createArgumentsObject(int.options.data) as RandomCaseArguments;
|
||||
const args = createArgumentsObject<RandomCaseArguments>(int.options.data);
|
||||
|
||||
var strSplit = args.string.toLowerCase().split('');
|
||||
for(let [i, char] of strSplit.entries()){
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ApplicationCommandOptionData, ApplicationCommandOptionType, CommandInteraction } from "discord.js"
|
||||
import { ApplicationCommandOptionData, ApplicationCommandOptionType, CommandInteraction, EmbedBuilder } from "discord.js"
|
||||
import { CBClient } from "../cbclient"
|
||||
import { CHARACTERS } from "../characters"
|
||||
import { Unit } from "../models/unit"
|
||||
@ -14,10 +14,9 @@ export class RollCommand implements SlashCommand {
|
||||
args: ApplicationCommandOptionData[] = []
|
||||
|
||||
async execute(int: CommandInteraction) {
|
||||
const client = int.client as CBClient;
|
||||
const player = await client.findOrCreatePlayer(int.user.id);
|
||||
const player = await CBClient.findOrCreatePlayer(int.user.id);
|
||||
|
||||
if (!(await client.spendOnPlayer(player, 0))) return int.reply({
|
||||
if (!(await CBClient.spendOnPlayer(player, 3600_000))) return int.reply({
|
||||
content: "You don't have the money!",
|
||||
ephemeral: true
|
||||
});
|
||||
@ -25,13 +24,15 @@ export class RollCommand implements SlashCommand {
|
||||
const character = CHARACTERS.random()!;
|
||||
await Unit.create({
|
||||
user_id: int.user.id,
|
||||
character_id: character.id,
|
||||
health: character.health,
|
||||
speed: character.speed
|
||||
character_id: character.id
|
||||
});
|
||||
|
||||
return int.reply({
|
||||
content: `You got **${character.name}**!`
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle(`You got **${character.name}**!`)
|
||||
.setImage(character.img)
|
||||
]
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ApplicationCommandOptionData, AutocompleteInteraction, CommandInteraction, PermissionResolvable, CommandInteractionOption, CacheType } from "discord.js"
|
||||
import { ApplicationCommandOptionData, AutocompleteInteraction, CommandInteraction, PermissionResolvable, CommandInteractionOption, CacheType, ApplicationCommandOptionType } from "discord.js"
|
||||
|
||||
export interface SlashCommand {
|
||||
name: string
|
||||
@ -13,12 +13,18 @@ export interface SlashCommand {
|
||||
execute(int: CommandInteraction): Promise<any>
|
||||
}
|
||||
|
||||
export function createArgumentsObject(data: readonly CommandInteractionOption<CacheType>[]) {
|
||||
export function createArgumentsObject<T> (data: readonly CommandInteractionOption<CacheType>[]): T {
|
||||
var a: {
|
||||
[key: string]: any
|
||||
} = {};
|
||||
for (const arg of data) {
|
||||
a[arg.name] = arg.value;
|
||||
switch (arg.type) {
|
||||
case ApplicationCommandOptionType.User:
|
||||
a[arg.name] = arg.member || arg.user;
|
||||
break;
|
||||
default:
|
||||
a[arg.name] = arg.value;
|
||||
}
|
||||
}
|
||||
return a;
|
||||
return a as T;
|
||||
}
|
Loading…
Reference in New Issue
Block a user