CUSTOM RECIPES 🎉🎉🎉🎉
This commit is contained in:
parent
f2c1d0efa9
commit
07e6e162ff
|
@ -6,6 +6,7 @@ exports.up = function(knex) {
|
||||||
return knex.schema
|
return knex.schema
|
||||||
.createTable('customCraftingRecipes', (table) => {
|
.createTable('customCraftingRecipes', (table) => {
|
||||||
table.increments('id');
|
table.increments('id');
|
||||||
|
table.string('guild');
|
||||||
table.string('station');
|
table.string('station');
|
||||||
})
|
})
|
||||||
.createTable('customCraftingRecipeItems', (table) => {
|
.createTable('customCraftingRecipeItems', (table) => {
|
||||||
|
@ -23,5 +24,5 @@ exports.up = function(knex) {
|
||||||
exports.down = function(knex) {
|
exports.down = function(knex) {
|
||||||
return knex.schema
|
return knex.schema
|
||||||
.dropTable('customCraftingRecipes')
|
.dropTable('customCraftingRecipes')
|
||||||
.dropTable('customCraftingRecipes');
|
.dropTable('customCraftingRecipeItems');
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { AutocompleteInteraction, GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
|
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 { getStation, canUseStation, craftingStations, verb, CraftingStation } from '../lib/rpg/craftingStations';
|
||||||
import { formatItem, getItemQuantity, formatItems, getMaxStack, giveItem, formatItemsArray } from '../lib/rpg/items';
|
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';
|
import { Command } from '../types/index';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -34,7 +34,7 @@ export default {
|
||||||
|
|
||||||
await interaction.deferReply({ephemeral: true});
|
await interaction.deferReply({ephemeral: true});
|
||||||
|
|
||||||
const recipe = getRecipe(recipeID);
|
const recipe = await getRecipe(recipeID);
|
||||||
if (!recipe) return interaction.followUp('Recipe does not exist!');
|
if (!recipe) return interaction.followUp('Recipe does not exist!');
|
||||||
|
|
||||||
const station = getStation(recipe.station)!;
|
const station = getStation(recipe.station)!;
|
||||||
|
@ -118,15 +118,29 @@ export default {
|
||||||
|
|
||||||
return interaction.respond(found);
|
return interaction.respond(found);
|
||||||
} else if (focused.name === 'recipe') {
|
} else if (focused.name === 'recipe') {
|
||||||
const found = defaultRecipes
|
const station = interaction.options.getString('station');
|
||||||
.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()
|
|
||||||
}));
|
|
||||||
|
|
||||||
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;
|
} satisfies Command;
|
|
@ -44,7 +44,7 @@ export default {
|
||||||
if (!interaction.member) return;
|
if (!interaction.member) return;
|
||||||
|
|
||||||
if (id.startsWith('recipe-create-')) {
|
if (id.startsWith('recipe-create-')) {
|
||||||
//const guildID = id.split('-')[2];
|
const guildID = id.split('-')[2];
|
||||||
|
|
||||||
if (interaction.isMessageComponent()) {
|
if (interaction.isMessageComponent()) {
|
||||||
const modal = new ModalBuilder()
|
const modal = new ModalBuilder()
|
||||||
|
@ -164,6 +164,7 @@ export default {
|
||||||
|
|
||||||
const [customRecipe] = await db<CustomCraftingRecipe>('customCraftingRecipes')
|
const [customRecipe] = await db<CustomCraftingRecipe>('customCraftingRecipes')
|
||||||
.insert({
|
.insert({
|
||||||
|
guild: guildID,
|
||||||
station: recipe.station
|
station: recipe.station
|
||||||
})
|
})
|
||||||
.returning('id');
|
.returning('id');
|
||||||
|
|
|
@ -71,6 +71,7 @@ export interface CraftingStationCooldown {
|
||||||
}
|
}
|
||||||
export interface CustomCraftingRecipe {
|
export interface CustomCraftingRecipe {
|
||||||
id: number,
|
id: number,
|
||||||
|
guild: string,
|
||||||
station: string
|
station: string
|
||||||
}
|
}
|
||||||
export interface CustomCraftingRecipeItem {
|
export interface CustomCraftingRecipeItem {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
import { CustomCraftingRecipe, CustomCraftingRecipeItem, db } from '../db';
|
||||||
import { getStation } from './craftingStations';
|
import { getStation } from './craftingStations';
|
||||||
import { DefaultItems, Items, formatItemsArray, getDefaultItem } from './items';
|
import { DefaultItems, Items, formatItemsArray, getDefaultItem, getItem } from './items';
|
||||||
|
|
||||||
export interface DefaultRecipe {
|
export interface DefaultRecipe {
|
||||||
id: number,
|
id: number,
|
||||||
|
@ -8,7 +9,15 @@ export interface DefaultRecipe {
|
||||||
requirements: Items[],
|
requirements: Items[],
|
||||||
outputs: 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[] = [
|
export const defaultRecipes: DefaultRecipe[] = [
|
||||||
{
|
{
|
||||||
|
@ -147,14 +156,45 @@ export const defaultRecipes: DefaultRecipe[] = [
|
||||||
export function getDefaultRecipe(id: number): DefaultRecipe | undefined {
|
export function getDefaultRecipe(id: number): DefaultRecipe | undefined {
|
||||||
return defaultRecipes.find(recipe => recipe.id === id);
|
return defaultRecipes.find(recipe => recipe.id === id);
|
||||||
}
|
}
|
||||||
export function getRecipe(id: number): Recipe | undefined {
|
export async function getCustomRecipe(id: number): Promise<ResolvedCustomRecipe | undefined> {
|
||||||
return getDefaultRecipe(id); // currently just a stub
|
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) =>
|
const defaultFormatRecipe = (inputs: Items[], requirements: Items[], outputs: Items[], disableBold = false) =>
|
||||||
`${formatItemsArray(inputs, disableBold)}${requirements.length === 0 ? '' : ` w/ ${formatItemsArray(requirements, disableBold)}`} => ${formatItemsArray(outputs, disableBold)}`;
|
`${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);
|
const station = getStation(recipe.station);
|
||||||
return (station?.formatRecipe || defaultFormatRecipe)(recipe.inputs, recipe.requirements, recipe.outputs, disableBold);
|
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')),
|
||||||
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue