329 lines
6.2 KiB
JavaScript
329 lines
6.2 KiB
JavaScript
const {
|
|
SlashCommandBuilder,
|
|
ModalBuilder,
|
|
TextInputBuilder,
|
|
TextInputStyle,
|
|
ActionRowBuilder,
|
|
MessageFlags
|
|
} = require("discord.js");
|
|
|
|
const { ObjectId } = require("mongodb");
|
|
const { mClient } = require("../..");
|
|
|
|
|
|
const DATABASE = "neo-db";
|
|
const DUTY_COLLECTION = "items_duties";
|
|
|
|
|
|
const RAID_TYPES = [
|
|
"Trial",
|
|
"Raid",
|
|
"AllianceRaid"
|
|
];
|
|
|
|
|
|
const RAID_DIFFICULTIES = [
|
|
"Extreme",
|
|
"Unreal",
|
|
"Savage",
|
|
"Ultimate",
|
|
"Chaotic"
|
|
];
|
|
|
|
|
|
module.exports = {
|
|
data: new SlashCommandBuilder()
|
|
.setName("raid")
|
|
.setDescription("Raid planning commands.")
|
|
|
|
.addSubcommand(subcommand =>
|
|
subcommand
|
|
.setName("plan")
|
|
.setDescription("Create a new raid event.")
|
|
|
|
.addStringOption(option =>
|
|
option
|
|
.setName("duty")
|
|
.setDescription(
|
|
"Select the duty you want to run."
|
|
)
|
|
.setRequired(true)
|
|
.setAutocomplete(true)
|
|
)
|
|
),
|
|
|
|
|
|
async execute(interaction) {
|
|
switch (
|
|
interaction.options.getSubcommand()
|
|
) {
|
|
case "plan":
|
|
return planRaid(interaction);
|
|
}
|
|
},
|
|
|
|
|
|
async autocomplete(interaction) {
|
|
return autocompleteDuty(interaction);
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
* AUTOCOMPLETE
|
|
*/
|
|
|
|
async function autocompleteDuty(interaction) {
|
|
const focused =
|
|
interaction.options.getFocused();
|
|
|
|
const collection = mClient
|
|
.db(DATABASE)
|
|
.collection(DUTY_COLLECTION);
|
|
|
|
|
|
const query = {
|
|
Type: {
|
|
$in: RAID_TYPES
|
|
},
|
|
|
|
Difficulty: {
|
|
$in: RAID_DIFFICULTIES
|
|
}
|
|
};
|
|
|
|
|
|
if (focused) {
|
|
query.Name = {
|
|
$regex: escapeRegex(focused),
|
|
$options: "i"
|
|
};
|
|
}
|
|
|
|
|
|
const duties = await collection
|
|
.find(query)
|
|
.sort({
|
|
Name: 1
|
|
})
|
|
.limit(25)
|
|
.toArray();
|
|
|
|
|
|
return interaction.respond(
|
|
duties.map(duty => ({
|
|
name: buildAutocompleteName(duty),
|
|
value: duty._id.toString()
|
|
}))
|
|
);
|
|
}
|
|
|
|
|
|
/*
|
|
* /raid plan
|
|
*/
|
|
|
|
async function planRaid(interaction) {
|
|
if (!interaction.guild) {
|
|
return interaction.reply({
|
|
content:
|
|
"Raid planning can only be used inside a server.",
|
|
flags:
|
|
MessageFlags.Ephemeral
|
|
});
|
|
}
|
|
|
|
|
|
const dutyId =
|
|
interaction.options.getString(
|
|
"duty",
|
|
true
|
|
);
|
|
|
|
|
|
if (!ObjectId.isValid(dutyId)) {
|
|
return interaction.reply({
|
|
content:
|
|
"Please select a duty from the autocomplete results.",
|
|
flags:
|
|
MessageFlags.Ephemeral
|
|
});
|
|
}
|
|
|
|
|
|
const collection = mClient
|
|
.db(DATABASE)
|
|
.collection(DUTY_COLLECTION);
|
|
|
|
|
|
const duty =
|
|
await collection.findOne({
|
|
_id:
|
|
new ObjectId(dutyId),
|
|
|
|
Type: {
|
|
$in: RAID_TYPES
|
|
},
|
|
|
|
Difficulty: {
|
|
$in: RAID_DIFFICULTIES
|
|
}
|
|
});
|
|
|
|
|
|
if (!duty) {
|
|
return interaction.reply({
|
|
content:
|
|
"That duty could not be found or is not eligible for raid planning.",
|
|
flags:
|
|
MessageFlags.Ephemeral
|
|
});
|
|
}
|
|
|
|
|
|
const modal =
|
|
buildRaidModal(duty);
|
|
|
|
|
|
return interaction.showModal(
|
|
modal
|
|
);
|
|
}
|
|
|
|
|
|
/*
|
|
* MODAL
|
|
*/
|
|
|
|
function buildRaidModal(duty) {
|
|
const modal =
|
|
new ModalBuilder()
|
|
.setCustomId(
|
|
`raidPlan:${duty._id}`
|
|
)
|
|
.setTitle(
|
|
"Shaiwase Raid Planner"
|
|
);
|
|
|
|
|
|
const nameInput =
|
|
new TextInputBuilder()
|
|
.setCustomId("raid-name")
|
|
.setLabel("Name")
|
|
.setPlaceholder(
|
|
"Friday Savage Prog"
|
|
)
|
|
.setStyle(
|
|
TextInputStyle.Short
|
|
)
|
|
.setMinLength(1)
|
|
.setMaxLength(100)
|
|
.setRequired(true);
|
|
|
|
|
|
const descriptionInput =
|
|
new TextInputBuilder()
|
|
.setCustomId(
|
|
"raid-description"
|
|
)
|
|
.setLabel("Description")
|
|
.setPlaceholder(
|
|
"What are we doing? Any requirements?"
|
|
)
|
|
.setStyle(
|
|
TextInputStyle.Paragraph
|
|
)
|
|
.setMaxLength(1000)
|
|
.setRequired(true);
|
|
|
|
|
|
const dateInput =
|
|
new TextInputBuilder()
|
|
.setCustomId("raid-date")
|
|
.setLabel("Date")
|
|
.setPlaceholder(
|
|
"DD-MM-YYYY"
|
|
)
|
|
.setStyle(
|
|
TextInputStyle.Short
|
|
)
|
|
.setMinLength(10)
|
|
.setMaxLength(10)
|
|
.setRequired(true);
|
|
|
|
|
|
const timeInput =
|
|
new TextInputBuilder()
|
|
.setCustomId("raid-time")
|
|
.setLabel(
|
|
"Start - End (24h clock)"
|
|
)
|
|
.setPlaceholder(
|
|
"20:00 - 23:00"
|
|
)
|
|
.setStyle(
|
|
TextInputStyle.Short
|
|
)
|
|
.setRequired(true);
|
|
|
|
|
|
modal.addComponents(
|
|
|
|
new ActionRowBuilder()
|
|
.addComponents(
|
|
nameInput
|
|
),
|
|
|
|
new ActionRowBuilder()
|
|
.addComponents(
|
|
descriptionInput
|
|
),
|
|
|
|
new ActionRowBuilder()
|
|
.addComponents(
|
|
dateInput
|
|
),
|
|
|
|
new ActionRowBuilder()
|
|
.addComponents(
|
|
timeInput
|
|
)
|
|
);
|
|
|
|
|
|
return modal;
|
|
}
|
|
|
|
|
|
/*
|
|
* HELPERS
|
|
*/
|
|
|
|
function buildAutocompleteName(duty) {
|
|
const label =
|
|
`${duty.Name} — ${formatDutyType(duty.Type)} / ${duty.Difficulty}`;
|
|
|
|
return label.slice(
|
|
0,
|
|
100
|
|
);
|
|
}
|
|
|
|
|
|
function formatDutyType(type) {
|
|
switch (type) {
|
|
case "AllianceRaid":
|
|
return "Alliance Raid";
|
|
|
|
default:
|
|
return type;
|
|
}
|
|
}
|
|
|
|
|
|
function escapeRegex(value) {
|
|
return value.replace(
|
|
/[.*+?^${}()|[\]\\]/g,
|
|
"\\$&"
|
|
);
|
|
} |