From ddb85d1d2f8efd9145c287bdb498123b5e7e3454 Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine\" Monoids" Date: Wed, 22 Nov 2023 11:40:37 +0300 Subject: [PATCH] behavior adding --- src/commands/item.ts | 101 ++++++++++++++++++++++++++++++++++++++- src/lib/rpg/behaviors.ts | 10 +++- 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/src/commands/item.ts b/src/commands/item.ts index af4968e..6b23c37 100644 --- a/src/commands/item.ts +++ b/src/commands/item.ts @@ -1,8 +1,9 @@ import { AutocompleteInteraction, CommandInteraction, SlashCommandBuilder } from 'discord.js'; -import { Counter, CustomCraftingRecipeItem, CustomItem, db } from '../lib/db'; -import { customItemAutocomplete, formatItem, formatItems, getItem, giveItem, itemAutocomplete } from '../lib/rpg/items'; +import { Counter, CustomCraftingRecipeItem, CustomItem, ItemBehavior, db } from '../lib/db'; +import { customItemAutocomplete, formatItem, formatItems, getCustomItem, getItem, giveItem, isDefaultItem, itemAutocomplete } from '../lib/rpg/items'; import { Command } from '../types/index'; import { formatRecipe, getCustomRecipe } from '../lib/rpg/recipes'; +import { behaviors, formatBehavior, getBehavior } from '../lib/rpg/behaviors'; //function extendOption(t: string) { // return {name: t, value: t}; @@ -149,6 +150,54 @@ export default { .setRequired(true) ) ) + .addSubcommandGroup(grp => + grp + .setName('behavior') + .setDescription('[ADMIN] Item behavior management') + .addSubcommand(cmd => + cmd + .setName('add') + .setDescription('[ADMIN] Give an item a behavior') + .addStringOption(opt => + opt + .setName('customitem') + .setDescription('The item') + .setAutocomplete(true) + .setRequired(true) + ) + .addStringOption(opt => + opt + .setName('behavior') + .setDescription('The behavior to add') + .setAutocomplete(true) + .setRequired(true) + ) + .addNumberOption(opt => + opt + .setName('value') + .setDescription('A value to assign the behavior, not always applicable') + ) + ) + .addSubcommand(cmd => + cmd + .setName('remove') + .setDescription('[ADMIN] Rid an item of a behavior') + .addStringOption(opt => + opt + .setName('customitem') + .setDescription('The item') + .setAutocomplete(true) + .setRequired(true) + ) + .addStringOption(opt => + opt + .setName('removebehavior') + .setDescription('The behavior to remove') + .setAutocomplete(true) + .setRequired(true) + ) + ) + ) .setDefaultMemberPermissions('0') .setDMPermission(false), @@ -174,6 +223,39 @@ export default { .returning('*'); await interaction.followUp(`${JSON.stringify(item[0])}`); + } else if (group === 'behavior') { + const itemID = parseInt(interaction.options.getString('customitem', true)); + const item = await getCustomItem(itemID); + if (!item) return await interaction.followUp('No such item exists!'); + if (item.guild !== interaction.guildId) return await interaction.followUp('This item is from a different server! Nice try though'); + + if (subcommand === 'add') { + const behaviorName = interaction.options.getString('behavior', true); + const value = interaction.options.getNumber('value'); + + const behavior = getBehavior(behaviorName); + if (!behavior) return await interaction.followUp(`No such behavior ${behaviorName}!`); + + const existingBehavior = await db('itemBehaviors') + .where('item', item.id) + .where('behavior', behavior.name) + .first(); + + if (existingBehavior) { + return await interaction.followUp(`${formatItem(item)} already has **${formatBehavior(behavior, existingBehavior.value)}**!`); + } + + await db('itemBehaviors') + .insert({ + item: item.id, + behavior: behavior.name, + value: value || undefined, + }); + + return await interaction.followUp(`${formatItem(item)} now has **${formatBehavior(behavior, value || undefined)}**`); + } else if (subcommand === 'remove') { + /////////////////// asngheasgyjdreajdneyonv + } } else { if (subcommand === 'give') { const user = interaction.options.getUser('who', true); @@ -183,6 +265,10 @@ export default { const item = await getItem(itemID); if (!item) return interaction.followUp('No such item exists!'); + if (!isDefaultItem(item)) { + if (item.guild !== interaction.guildId) return await interaction.followUp('This item is from a different server! Nice try though'); + } + const inv = await giveItem(user.id, item, quantity); await interaction.followUp(`${user.toString()} now has ${formatItems(item, inv.quantity)}.`); @@ -223,6 +309,17 @@ export default { return itemAutocomplete(interaction); } else if (focused.name === 'customitem') { return customItemAutocomplete(interaction); + } else if (focused.name === 'behavior') { + let foundBehaviors = behaviors.filter(b => b.name.toLowerCase().includes(focused.value.toLowerCase())); + const itemID = interaction.options.getString('customitem'); + if (itemID) { + const item = await getItem(parseInt(itemID)); + if (item) { + foundBehaviors = foundBehaviors.filter(b => b.itemType === item.type); + } + } + + await interaction.respond(foundBehaviors.map(b => ({name: `${b.itemType}:${b.name} - ${b.description}`, value: b.name}))); } } } satisfies Command; \ No newline at end of file diff --git a/src/lib/rpg/behaviors.ts b/src/lib/rpg/behaviors.ts index e9496c6..fd07ced 100644 --- a/src/lib/rpg/behaviors.ts +++ b/src/lib/rpg/behaviors.ts @@ -8,7 +8,7 @@ export interface Behavior { description: string, itemType: 'plain' | 'weapon' | 'consumable', // make it look fancy - format?: (value: number) => string, + format?: (value?: number) => string, // triggers upon use // for 'weapons', this is on attack // for 'consumable' and `plain`, this is on use @@ -19,6 +19,8 @@ export interface Behavior { onAttack?: (value: number, item: Item, user: string, target: string, damage: number) => Promise>, } +const defaultFormat = (behavior: Behavior, value?: number) => `${behavior.name}${value ? ' ' + value.toString() : ''}`; + export const behaviors: Behavior[] = [ { name: 'heal', @@ -75,4 +77,10 @@ export async function getBehaviors(item: Item) { return await db('itemBehaviors') .where('item', item.id); } +} +export function getBehavior(behavior: string) { + return behaviors.find(b => b.name === behavior); +} +export function formatBehavior(behavior: Behavior, value: number | undefined) { + return behavior.format ? behavior.format(value) : defaultFormat(behavior, value); } \ No newline at end of file