Fuzzy item matching + periodic inventory check for auto-equip
- equipBestWeapon uses fuzzy substring matching on item names - equipBestArmor uses .includes() instead of .startsWith() for tiers - Both strip minecraft: prefix before comparing - Added periodic inventory check every 5 seconds (playerCollect doesn't fire on Bedrock) — detects new items and auto-equips - evaluateEquipment logs full inventory contents for debugging - All name comparisons are case-insensitive Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
aa0a937171
commit
9869181071
1 changed files with 43 additions and 8 deletions
|
|
@ -386,19 +386,36 @@ async function evaluateEquipment() {
|
||||||
if (Date.now() - lastEquipCheck < 3000) return;
|
if (Date.now() - lastEquipCheck < 3000) return;
|
||||||
lastEquipCheck = Date.now();
|
lastEquipCheck = Date.now();
|
||||||
|
|
||||||
|
// Log what we have
|
||||||
|
const allItems = bot.inventory.items();
|
||||||
|
if (allItems.length > 0) {
|
||||||
|
log('client', 'INFO', `Inventory: ${allItems.map(i => i.name).join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
const weaponResult = await equipBestWeapon();
|
const weaponResult = await equipBestWeapon();
|
||||||
if (weaponResult.equipped) {
|
if (weaponResult.equipped) {
|
||||||
log('client', 'INFO', `🛡 Auto-equipped weapon: ${weaponResult.item}`);
|
log('client', 'INFO', `Auto-equipped weapon: ${weaponResult.item}`);
|
||||||
sendEvent('equipment_changed', { type: 'weapon', item: weaponResult.item });
|
sendEvent('equipment_changed', { type: 'weapon', item: weaponResult.item });
|
||||||
}
|
}
|
||||||
|
|
||||||
const armorResult = await equipBestArmor();
|
const armorResult = await equipBestArmor();
|
||||||
if (armorResult.equipped) {
|
if (armorResult.equipped) {
|
||||||
log('client', 'INFO', `🛡 Auto-equipped armor: ${armorResult.items.join(', ')}`);
|
log('client', 'INFO', `Auto-equipped armor: ${armorResult.items.join(', ')}`);
|
||||||
sendEvent('equipment_changed', { type: 'armor', items: armorResult.items });
|
sendEvent('equipment_changed', { type: 'armor', items: armorResult.items });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also check inventory periodically (playerCollect may not fire on Bedrock)
|
||||||
|
setInterval(() => {
|
||||||
|
if (!spawned) return;
|
||||||
|
const items = bot.inventory.items();
|
||||||
|
const hash = items.map(i => `${i.name}:${i.count}`).sort().join(',');
|
||||||
|
if (hash !== lastInventoryHash && hash !== '') {
|
||||||
|
lastInventoryHash = hash;
|
||||||
|
evaluateEquipment();
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
// --- Player-friendly name → Bedrock item ID mapping ---
|
// --- Player-friendly name → Bedrock item ID mapping ---
|
||||||
const ITEM_ALIASES = {
|
const ITEM_ALIASES = {
|
||||||
// Plural → singular
|
// Plural → singular
|
||||||
|
|
@ -634,24 +651,41 @@ async function equipBestWeapon() {
|
||||||
let bestTier = -1;
|
let bestTier = -1;
|
||||||
|
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const name = item.name.replace('minecraft:', '');
|
// Fuzzy match: strip prefix, try exact and partial matching
|
||||||
const tier = WEAPON_TIERS[name] || 0;
|
const rawName = (item.name || '').replace('minecraft:', '').toLowerCase();
|
||||||
|
let tier = WEAPON_TIERS[rawName] || 0;
|
||||||
|
// Also try matching by substring (e.g. item.name contains "diamond_sword")
|
||||||
|
if (tier === 0) {
|
||||||
|
for (const [weaponName, weaponTier] of Object.entries(WEAPON_TIERS)) {
|
||||||
|
if (rawName.includes(weaponName) || weaponName.includes(rawName)) {
|
||||||
|
tier = weaponTier;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (tier > bestTier) {
|
if (tier > bestTier) {
|
||||||
bestTier = tier;
|
bestTier = tier;
|
||||||
bestItem = item;
|
bestItem = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestItem && bestItem !== bot.heldItem) {
|
if (bestItem) {
|
||||||
|
// Check if already holding this item
|
||||||
|
const heldName = bot.heldItem?.name?.replace('minecraft:', '').toLowerCase() || '';
|
||||||
|
const bestName = bestItem.name.replace('minecraft:', '').toLowerCase();
|
||||||
|
if (heldName === bestName) {
|
||||||
|
return { equipped: false, reason: 'already_equipped' };
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
await bot.equip(bestItem, 'hand');
|
await bot.equip(bestItem, 'hand');
|
||||||
log('client', 'INFO', `Equipped ${bestItem.name}`);
|
log('client', 'INFO', `Equipped ${bestItem.name}`);
|
||||||
return { equipped: true, item: bestItem.name };
|
return { equipped: true, item: bestItem.name };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
log('client', 'WARN', `Failed to equip ${bestItem.name}: ${e.message}`);
|
||||||
return { equipped: false, error: e.message };
|
return { equipped: false, error: e.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { equipped: false, reason: bestItem ? 'already_equipped' : 'no_weapons' };
|
return { equipped: false, reason: 'no_weapons' };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function equipBestTool(blockType) {
|
async function equipBestTool(blockType) {
|
||||||
|
|
@ -704,9 +738,9 @@ async function equipBestArmor() {
|
||||||
let bestTierIdx = 999;
|
let bestTierIdx = 999;
|
||||||
|
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const name = item.name.replace('minecraft:', '');
|
const name = (item.name || '').replace('minecraft:', '').toLowerCase();
|
||||||
if (!name.includes(armorPiece)) continue;
|
if (!name.includes(armorPiece)) continue;
|
||||||
const tierIdx = ARMOR_TIERS.findIndex(t => name.startsWith(t));
|
const tierIdx = ARMOR_TIERS.findIndex(t => name.includes(t));
|
||||||
if (tierIdx >= 0 && tierIdx < bestTierIdx) {
|
if (tierIdx >= 0 && tierIdx < bestTierIdx) {
|
||||||
bestTierIdx = tierIdx;
|
bestTierIdx = tierIdx;
|
||||||
bestItem = item;
|
bestItem = item;
|
||||||
|
|
@ -717,6 +751,7 @@ async function equipBestArmor() {
|
||||||
try {
|
try {
|
||||||
await bot.equip(bestItem, slot);
|
await bot.equip(bestItem, slot);
|
||||||
equipped.push(bestItem.name);
|
equipped.push(bestItem.name);
|
||||||
|
log('client', 'INFO', `Equipped armor: ${bestItem.name} → ${slot}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('client', 'WARN', `Failed to equip ${bestItem.name}: ${e.message}`);
|
log('client', 'WARN', `Failed to equip ${bestItem.name}: ${e.message}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue