Files
2026-01-31 22:34:20 -05:00

103 lines
3.1 KiB
JavaScript

'use strict';
const Vec3 = require('vec3');
const conf = require('../../conf');
class Organizer {
constructor() {
this.categories = conf.storage?.categories || {
minerals: ['diamond', 'netherite_ingot', 'gold_ingot', 'iron_ingot'],
food: ['bread', 'cooked_porkchop', 'steak'],
tools: ['diamond_sword', 'diamond_pickaxe', 'netherite_pickaxe'],
armor: ['diamond_chestplate', 'netherite_helmet'],
blocks: ['stone', 'dirt', 'cobblestone'],
redstone: ['redstone', 'repeater', 'piston'],
misc: []
};
}
categorizeItem(itemName) {
// Fast path: check each category
for (const [category, items] of Object.entries(this.categories)) {
if (items.includes(itemName)) {
return category;
}
}
return 'misc';
}
async findShulkerForItem(database, itemId, categoryName) {
// Find shulker with matching item that has space
const shulker = await database.findShulkerForItem(itemId, categoryName);
return shulker;
}
async findEmptyShulkerSlot(database, categoryName) {
// Find an empty shulker in the appropriate category and row (prefer row 4 for empty storage)
const chests = await database.getChests();
// Filter chests by category and row 4 (top row for empty/new shulkers)
const categoryChests = chests.filter(c =>
c.category === categoryName && c.row === 4
).sort((a, b) => a.column - b.column); // Left to right
for (const chest of categoryChests) {
const shulkers = await database.getShulkersByChest(chest.id);
// Find first shulker that's empty (slotCount = 0) or has space
for (const shulker of shulkers) {
if (!shulker.item_focus) {
// Empty shulker available
return {
chest_id: chest.id,
chestPosition: new Vec3(chest.pos_x, chest.pos_y, chest.pos_z),
chestSlot: shulker.slot,
shulker_id: shulker.id
};
}
}
}
// If no empty shulker, look for first available slot in row 4
// ... this would need to scan actual chest for empty slots
return null;
}
async sortItemIntoStorage(bot, database, item, categoryName) {
// Find existing shulker with same item and space
const existingShulker = await this.findShulkerForItem(database, item.id, categoryName);
if (existingShulker) {
// Space available, add to existing shulker
console.log(`Organizer: Found shulker ${existingShulker.id} for ${item.name}`);
return existingShulker;
} else {
// Need new shulker
console.log(`Organizer: Creating new shulker for ${item.name} (${categoryName})`);
const shulkerSlot = await this.findEmptyShulkerSlot(database, categoryName);
if (!shulkerSlot) {
console.log(`Organizer: No available shulker slot for ${item.name}`);
return null;
}
// Create/prepare new shulker
await database.upsertShulker(
shulkerSlot.chest_id,
shulkerSlot.chestSlot,
'shulker_box',
categoryName,
item.name // item_focus
);
console.log(`Organizer: Created shulker at chest ${shulkerSlot.chest_id}, slot ${shulkerSlot.chestSlot}`);
return {
chest_id: shulkerSlot.chest_id,
slot: shulkerSlot.chestSlot,
new: true
};
}
}
}
module.exports = Organizer;