feat: Add color role item effect with role swapping and implement item consumption toggle.

This commit is contained in:
syntaxbullet
2025-12-23 21:12:36 +01:00
parent 67d6298793
commit a3099b80c5
5 changed files with 37 additions and 3 deletions

View File

@@ -44,6 +44,7 @@ const getEffectTypeOptions = () => [
{ label: "Reply Message", value: "REPLY_MESSAGE", description: "Bot replies with a message" },
{ label: "XP Boost", value: "XP_BOOST", description: "Temporarily boosts XP gain" },
{ label: "Temp Role", value: "TEMP_ROLE", description: "Gives a temporary role" },
{ label: "Color Role", value: "COLOR_ROLE", description: "Equips a permanent color role (swaps)" },
];
// --- Render ---
@@ -72,6 +73,7 @@ export const renderWizard = (userId: string, isDraft = true) => {
{ name: "General", value: `**Type:** ${draft.type}\n**Rarity:** ${draft.rarity}\n**Desc:** ${draft.description}`, inline: true },
{ name: "Economy", value: `**Price:** ${draft.price ? `${draft.price} 🪙` : "Not for sale"}`, inline: true },
{ name: "Visuals", value: `**Icon:** ${draft.iconUrl ? "✅ Set" : "❌"}\n**Image:** ${draft.imageUrl ? "✅ Set" : "❌"}`, inline: true },
{ name: "Usage", value: `**Consume:** ${draft.usageData.consume ? "✅ Yes" : "❌ No"}`, inline: true },
);
// Effects Display
@@ -97,6 +99,7 @@ export const renderWizard = (userId: string, isDraft = true) => {
const row2 = new ActionRowBuilder<MessageActionRowComponentBuilder>()
.addComponents(
new ButtonBuilder().setCustomId("createitem_addeffect_start").setLabel("Add Effect").setStyle(ButtonStyle.Primary).setEmoji("✨"),
new ButtonBuilder().setCustomId("createitem_toggle_consume").setLabel(`Consume: ${draft.usageData.consume ? "ON" : "OFF"}`).setStyle(ButtonStyle.Secondary).setEmoji("🔄"),
new ButtonBuilder().setCustomId("createitem_save").setLabel("Save Item").setStyle(ButtonStyle.Success).setEmoji("💾"),
new ButtonBuilder().setCustomId("createitem_cancel").setLabel("Cancel").setStyle(ButtonStyle.Danger).setEmoji("✖️")
);
@@ -241,12 +244,25 @@ export const handleItemWizardInteraction = async (interaction: Interaction) => {
new ActionRowBuilder<TextInputBuilder>().addComponents(new TextInputBuilder().setCustomId("role_id").setLabel("Role ID").setStyle(TextInputStyle.Short).setRequired(true)),
new ActionRowBuilder<TextInputBuilder>().addComponents(new TextInputBuilder().setCustomId("duration").setLabel("Duration (Seconds)").setStyle(TextInputStyle.Short).setRequired(true).setValue("3600"))
);
} else if (effectType === "COLOR_ROLE") {
modal.addComponents(
new ActionRowBuilder<TextInputBuilder>().addComponents(new TextInputBuilder().setCustomId("role_id").setLabel("Role ID").setStyle(TextInputStyle.Short).setRequired(true))
);
}
await interaction.showModal(modal);
return;
}
// Toggle Consume
if (interaction.customId === "createitem_toggle_consume") {
if (!interaction.isButton()) return;
draft.usageData.consume = !draft.usageData.consume;
const payload = renderWizard(userId);
await interaction.update(payload);
return;
}
// 6. Handle Modal Submits
if (interaction.isModalSubmit()) {
if (interaction.customId === "createitem_modal_details") {
@@ -284,6 +300,10 @@ export const handleItemWizardInteraction = async (interaction: Interaction) => {
const duration = parseInt(interaction.fields.getTextInputValue("duration"));
if (roleId && !isNaN(duration)) effect = { type: "TEMP_ROLE", roleId: roleId, durationSeconds: duration };
}
else if (type === "COLOR_ROLE") {
const roleId = interaction.fields.getTextInputValue("role_id");
if (roleId) effect = { type: "COLOR_ROLE", roleId: roleId };
}
if (effect) {
draft.usageData.effects.push(effect);

View File

@@ -209,6 +209,9 @@ export const inventoryService = {
// Actual role assignment happens in the Command layer
results.push(`Temporary Role granted for ${Math.floor(roleDuration / 60)}m`);
break;
case 'COLOR_ROLE':
results.push("Color Role Equipped");
break;
}
}