exclude buildings from collecting

This commit is contained in:
Kolby Nottingham 2024-03-06 14:25:15 -08:00
parent 74751a9bf2
commit 4d00cd1ccf
6 changed files with 64 additions and 33 deletions

View file

@ -359,11 +359,13 @@ export async function collectBlock(bot, blockType, num=1, exclude=null) {
let blocktypes = [blockType];
if (blockType.endsWith('ore'))
blocktypes.push('deepslate_'+blockType);
if (blockType === 'dirt')
blocktypes.push('grass_block');
let collected = 0;
for (let i=0; i<num; i++) {
const blocks = world.getNearestBlocks(bot, blocktypes, 64);
let blocks = world.getNearestBlocks(bot, blocktypes, 64);
if (exclude) {
for (let position of exclude) {
blocks = blocks.filter(

View file

@ -76,7 +76,7 @@ export function getNearestBlocks(bot, block_types, distance=16, count=null) {
for (let block of getNearbyBlocks(bot, distance, count)) {
if (block_types.includes(block.name)) {
blocks.push(block);
if (blocks.length >= count)
if (count !== null && blocks.length >= count)
break;
}
}

View file

@ -17,6 +17,13 @@ export class BuildGoal {
if (orientation === 3) return [sizez-z-1, x];
}
async wrapSkill(func) {
if (!this.agent.isIdle())
return false;
let res = await this.agent.coder.execute(func);
return !res.interrupted;
}
async executeNext(goal, position=null, orientation=null) {
let sizex = goal.blocks[0][0].length;
let sizez = goal.blocks[0].length;
@ -47,32 +54,28 @@ export class BuildGoal {
let current_block = this.agent.bot.blockAt(world_pos);
let res = null;
if (!blockSatisfied(block_name, current_block)) {
if (current_block !== null && !blockSatisfied(block_name, current_block)) {
acted = true;
if (!this.agent.isIdle())
return {missing: missing, acted: acted, position: position, orientation: orientation};
res = await this.agent.coder.execute(async () => {
await skills.breakBlockAt(this.agent.bot, world_pos.x, world_pos.y, world_pos.z);
});
if (res.interrupted)
return {missing: missing, acted: acted, position: position, orientation: orientation};
let block_typed = getTypeOfGeneric(this.agent.bot, block_name);
if (inventory[block_typed] > 0) {
if (!this.agent.isIdle())
return {missing: missing, acted: acted, position: position, orientation: orientation};
await this.agent.coder.execute(async () => {
await skills.placeBlock(this.agent.bot, block_typed, world_pos.x, world_pos.y, world_pos.z);
if (current_block.name !== 'air') {
res = await this.wrapSkill(async () => {
await skills.breakBlockAt(this.agent.bot, world_pos.x, world_pos.y, world_pos.z);
});
if (res.interrupted)
return {missing: missing, acted: acted, position: position, orientation: orientation};
if (!res) return {missing: missing, acted: acted, position: position, orientation: orientation};
}
} else {
if (missing[block_typed] === undefined)
missing[block_typed] = 0;
missing[block_typed]++;
if (block_name !== 'air') {
let block_typed = getTypeOfGeneric(this.agent.bot, block_name);
if (inventory[block_typed] > 0) {
res = await this.wrapSkill(async () => {
await skills.placeBlock(this.agent.bot, block_typed, world_pos.x, world_pos.y, world_pos.z);
});
if (!res) return {missing: missing, acted: acted, position: position, orientation: orientation};
} else {
if (missing[block_typed] === undefined)
missing[block_typed] = 0;
missing[block_typed]++;
}
}
}
}

View file

@ -10,11 +10,30 @@ export class NPCContoller {
this.agent = agent;
this.data = NPCData.fromObject(agent.prompter.prompts.npc);
this.temp_goals = [];
this.item_goal = new ItemGoal(agent);
this.item_goal = new ItemGoal(agent, this.data);
this.build_goal = new BuildGoal(agent);
this.constructions = {};
}
getBuiltPositions() {
let positions = [];
for (let name in this.data.built) {
let position = this.data.built[name].position;
let offset = this.constructions[name].offset;
let sizex = this.constructions[name].blocks[0][0].length;
let sizez = this.constructions[name].blocks[0].length;
let sizey = this.constructions[name].blocks.length;
for (let y = offset; y < sizey+offset; y++) {
for (let z = 0; z < sizez; z++) {
for (let x = 0; x < sizex; x++) {
positions.push({x: position.x + x, y: position.y + y, z: position.z + z});
}
}
}
}
return positions;
}
init() {
if (this.data === null) return;
@ -80,5 +99,8 @@ export class NPCContoller {
if (res.acted) break;
}
}
if (this.agent.isIdle())
this.agent.bot.emit('idle');
}
}

View file

@ -152,7 +152,7 @@ class ItemNode {
let inventory = world.getInventoryCounts(this.manager.agent.bot);
let init_quantity = inventory[this.name] || 0;
if (this.type === 'block') {
await skills.collectBlock(this.manager.agent.bot, this.source, quantity);
await skills.collectBlock(this.manager.agent.bot, this.source, quantity, this.manager.agent.npc.getBuiltPositions());
} else if (this.type === 'smelt') {
let to_smelt_name = this.recipe[0].node.name;
let to_smelt_quantity = Math.min(quantity, inventory[to_smelt_name] || 1);
@ -210,10 +210,13 @@ class ItemWrapper {
}
}
let block_source = mc.getItemBlockSource(this.name);
if (block_source) {
let tool = mc.getBlockTool(block_source);
this.add_method(new ItemNode(this.manager, this, this.name).setCollectable(block_source, tool));
let block_sources = mc.getItemBlockSources(this.name);
if (block_sources.length > 0 && this.name !== 'torch') { // Do not collect placed torches
for (let block_source of block_sources) {
if (block_source === 'grass_block') continue; // Dirt nodes will collect grass blocks
let tool = mc.getBlockTool(block_source);
this.add_method(new ItemNode(this.manager, this, this.name).setCollectable(block_source, tool));
}
}
let smeltingIngredient = mc.getItemSmeltingIngredient(this.name);

View file

@ -171,14 +171,15 @@ export function getItemSmeltingIngredient(itemName) {
}[itemName];
}
export function getItemBlockSource(itemName) {
export function getItemBlockSources(itemName) {
let itemId = getItemId(itemName);
let sources = [];
for (let block of getAllBlocks()) {
if (block.drops.includes(itemId)) {
return block.name;
sources.push(block.name);
}
}
return null;
return sources;
}
export function getItemAnimalSource(itemName) {