mindcraft/src/utils/tasks.js
Kolby Nottingham 4e0611d29e cleanup
2024-12-09 16:30:44 -08:00

148 lines
5.2 KiB
JavaScript

import yaml from 'js-yaml'
import { readFileSync } from 'fs';
import {getPosition} from './library/world.js'
export function loadTask(taskId) {
try {
const taskType = taskId.split('_')[0];
const tasksFile = readFileSync(`tasks/${taskType}_tasks.yaml`, 'utf8');
const tasks = yaml.load(tasksFile);
const task = tasks[taskId];
if (!task) {
throw new Error(`Task ${taskId} not found`);
}
return task;
} catch (error) {
console.error('Error loading task:', error);
process.exit(1);
}
}
export async function initBotTask(bot, task, name) {
if (task) {
bot.chat(`/clear ${bot.username}`);
console.log(`Cleared ${bot.username}'s inventory.`);
}
//wait for a bit so inventory is cleared
await new Promise((resolve) => setTimeout(resolve, 500));
console.log(task && "agent_number" in task && task.agent_number > 1);
if (task && "agent_number" in task && task.agent_number > 1) {
var initial_inventory = task.initial_inventory[bot.username];
console.log("Initial inventory:", initial_inventory);
} else if (task) {
console.log("Initial inventory:", task.initial_inventory);
var initial_inventory = task.initial_inventory;
}
if (task && "initial_inventory" in task) {
console.log("Setting inventory...");
console.log("Inventory to set:", initial_inventory);
for (let key of Object.keys(initial_inventory)) {
console.log('Giving item:', key);
bot.chat(`/give ${bot.username} ${key} ${initial_inventory[key]}`);
};
//wait for a bit so inventory is set
await new Promise((resolve) => setTimeout(resolve, 500));
console.log("Done giving inventory items.");
}
// Function to generate random numbers
function getRandomOffset(range) {
return Math.floor(Math.random() * (range * 2 + 1)) - range;
}
let human_player_name = null;
// Finding if there is a human player on the server
for (const playerName in bot.players) {
const player = bot.players[playerName];
if (!isOtherAgent(player.username)) {
console.log('Found human player:', player.username);
human_player_name = player.username
break;
}
}
// If there are multiple human players, teleport to the first one
// teleport near a human player if found by default
if (task && "agent_number" in task) {
var agent_names = task.agent_names;
if (human_player_name) {
console.log(`Teleporting ${bot.username} to human ${human_player_name}`)
bot.chat(`/tp ${bot.username} ${human_player_name}`) // teleport on top of the human player
}
else {
bot.chat(`/tp ${bot.username} ${agent_names[0]}`) // teleport on top of the first agent
}
await new Promise((resolve) => setTimeout(resolve, 200));
}
else if (task) {
if (human_player_name) {
console.log(`Teleporting ${bot.username} to human ${human_player_name}`)
bot.chat(`/tp ${bot.username} ${human_player_name}`) // teleport on top of the human player
}
await new Promise((resolve) => setTimeout(resolve, 200));
}
// now all bots are teleport on top of each other (which kinda looks ugly)
// Thus, we need to teleport them to random distances to make it look better
/*
Note : We don't want randomness for construction task as the reference point matters a lot.
Another reason for no randomness for construction task is because, often times the user would fly in the air,
then set a random block to dirt and teleport the bot to stand on that block for starting the construction,
This was done by MaxRobinson in one of the youtube videos.
*/
if (task && task.type !== 'construction') {
const pos = getPosition(bot);
const xOffset = getRandomOffset(5);
const zOffset = getRandomOffset(5);
bot.chat(`/tp ${bot.username} ${Math.floor(pos.x + xOffset)} ${pos.y + 3} ${Math.floor(pos.z + zOffset)}`);
await new Promise((resolve) => setTimeout(resolve, 200));
}
}
export class TechTreeHarvestValidator {
constructor(task, bot) {
this.target = task.target;
this.number_of_target = task.number_of_target;
this.bot = bot;
}
validate() {
try{
console.log("validate");
let valid = false;
let total_targets = 0;
this.bot.inventory.slots.forEach((slot) => {
if (slot && slot.name.toLowerCase() === this.target) {
total_targets += slot.count;
}
if (slot && slot.name.toLowerCase() === this.target && slot.count >= this.number_of_target) {
valid = true;
console.log('Task is complete');
}
});
if (total_targets >= this.number_of_target) {
valid = true;
console.log('Task is complete');
}
return valid;
} catch (error) {
console.error('Error validating task:', error);
return false;
}
}
}