CUSTOM RECIPES 🎉🎉🎉🎉

This commit is contained in:
Jill 2023-11-18 15:24:56 +03:00
parent f2c1d0efa9
commit 07e6e162ff
Signed by: oat
GPG Key ID: 33489AA58A955108
5 changed files with 75 additions and 18 deletions

View File

@ -6,6 +6,7 @@ exports.up = function(knex) {
return knex.schema
.createTable('customCraftingRecipes', (table) => {
table.increments('id');
table.string('guild');
table.string('station');
})
.createTable('customCraftingRecipeItems', (table) => {
@ -23,5 +24,5 @@ exports.up = function(knex) {
exports.down = function(knex) {
return knex.schema
.dropTable('customCraftingRecipes')
.dropTable('customCraftingRecipes');
.dropTable('customCraftingRecipeItems');
};

View File

@ -1,8 +1,8 @@
import { AutocompleteInteraction, GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
import { CraftingStationCooldown, db } from '../lib/db';
import { CraftingStationCooldown, CustomCraftingRecipe, db } from '../lib/db';
import { getStation, canUseStation, craftingStations, verb, CraftingStation } from '../lib/rpg/craftingStations';
import { formatItem, getItemQuantity, formatItems, getMaxStack, giveItem, formatItemsArray } from '../lib/rpg/items';
import { getRecipe, defaultRecipes, formatRecipe } from '../lib/rpg/recipes';
import { getRecipe, defaultRecipes, formatRecipe, resolveCustomRecipe } from '../lib/rpg/recipes';
import { Command } from '../types/index';
export default {
@ -34,7 +34,7 @@ export default {
await interaction.deferReply({ephemeral: true});
const recipe = getRecipe(recipeID);
const recipe = await getRecipe(recipeID);
if (!recipe) return interaction.followUp('Recipe does not exist!');
const station = getStation(recipe.station)!;
@ -118,15 +118,29 @@ export default {
return interaction.respond(found);
} else if (focused.name === 'recipe') {
const found = defaultRecipes
.filter(recipe => recipe.station === interaction.options.getString('station'))
.filter(recipe => recipe.outputs.filter(n => n.item.name.toLowerCase().includes(focused.value.toLowerCase())).length > 0)
.map(recipe => ({
name: formatRecipe(recipe, true),
value: recipe.id.toString()
}));
const station = interaction.options.getString('station');
return interaction.respond(found);
const foundDefaultRecipes = defaultRecipes
.filter(recipe => recipe.station === station)
.filter(recipe => recipe.outputs.filter(n => n.item.name.toLowerCase().includes(focused.value.toLowerCase())).length > 0);
const customRecipes = await db<CustomCraftingRecipe>('customCraftingRecipes')
.where('station', station);
const resolvedCustomRecipes = await Promise.all(customRecipes.map(resolveCustomRecipe));
const foundCustomRecipes = resolvedCustomRecipes
.filter(recipe => recipe.outputs.filter(n => n.item.name.toLowerCase().includes(focused.value.toLowerCase())).length > 0);
const recipes = [...foundDefaultRecipes, ...foundCustomRecipes];
return interaction.respond(
recipes
.map(recipe => ({
name: formatRecipe(recipe, true),
value: recipe.id.toString()
}))
);
}
}
} satisfies Command;

View File

@ -44,7 +44,7 @@ export default {
if (!interaction.member) return;
if (id.startsWith('recipe-create-')) {
//const guildID = id.split('-')[2];
const guildID = id.split('-')[2];
if (interaction.isMessageComponent()) {
const modal = new ModalBuilder()
@ -164,6 +164,7 @@ export default {
const [customRecipe] = await db<CustomCraftingRecipe>('customCraftingRecipes')
.insert({
guild: guildID,
station: recipe.station
})
.returning('id');

View File

@ -71,6 +71,7 @@ export interface CraftingStationCooldown {
}
export interface CustomCraftingRecipe {
id: number,
guild: string,
station: string
}
export interface CustomCraftingRecipeItem {

View File

@ -1,5 +1,6 @@
import { CustomCraftingRecipe, CustomCraftingRecipeItem, db } from '../db';
import { getStation } from './craftingStations';
import { DefaultItems, Items, formatItemsArray, getDefaultItem } from './items';
import { DefaultItems, Items, formatItemsArray, getDefaultItem, getItem } from './items';
export interface DefaultRecipe {
id: number,
@ -8,7 +9,15 @@ export interface DefaultRecipe {
requirements: Items[],
outputs: Items[]
}
export type Recipe = DefaultRecipe
export interface ResolvedCustomRecipe {
id: number,
guild: string,
station: string,
inputs: Items[],
requirements: Items[],
outputs: Items[]
}
export type Recipe = DefaultRecipe | ResolvedCustomRecipe
export const defaultRecipes: DefaultRecipe[] = [
{
@ -147,14 +156,45 @@ export const defaultRecipes: DefaultRecipe[] = [
export function getDefaultRecipe(id: number): DefaultRecipe | undefined {
return defaultRecipes.find(recipe => recipe.id === id);
}
export function getRecipe(id: number): Recipe | undefined {
return getDefaultRecipe(id); // currently just a stub
export async function getCustomRecipe(id: number): Promise<ResolvedCustomRecipe | undefined> {
const recipe = await db<CustomCraftingRecipe>('customCraftingRecipes')
.where('id', id)
.first();
if (!recipe) return;
return await resolveCustomRecipe(recipe);
}
export async function getRecipe(id: number): Promise<Recipe | undefined> {
if (id >= 0) {
return await getCustomRecipe(id);
} else {
return getDefaultRecipe(id);
}
}
const defaultFormatRecipe = (inputs: Items[], requirements: Items[], outputs: Items[], disableBold = false) =>
`${formatItemsArray(inputs, disableBold)}${requirements.length === 0 ? '' : ` w/ ${formatItemsArray(requirements, disableBold)}`} => ${formatItemsArray(outputs, disableBold)}`;
export function formatRecipe(recipe: DefaultRecipe, disableBold = false) {
export function formatRecipe(recipe: Recipe, disableBold = false) {
const station = getStation(recipe.station);
return (station?.formatRecipe || defaultFormatRecipe)(recipe.inputs, recipe.requirements, recipe.outputs, disableBold);
}
function resolveItems(items: CustomCraftingRecipeItem[]) {
return Promise.all(items.map(async i => ({item: (await getItem(i.item))!, quantity: i.quantity})));
}
export async function resolveCustomRecipe(recipe: CustomCraftingRecipe): Promise<ResolvedCustomRecipe> {
const items = await db<CustomCraftingRecipeItem>('customCraftingRecipeItems')
.where('id', recipe.id);
return {
id: recipe.id,
guild: recipe.guild,
station: recipe.station,
inputs: await resolveItems(items.filter(i => i.type === 'input')),
requirements: await resolveItems(items.filter(i => i.type === 'requirement')),
outputs: await resolveItems(items.filter(i => i.type === 'output')),
};
}