2025-04-01 22:33:37 -07:00
import { readFileSync , writeFileSync , existsSync } from 'fs' ;
2025-04-21 12:20:06 -05:00
import { executeCommand } from '../commands/index.js' ;
import { getPosition } from '../library/world.js' ;
import { ConstructionTaskValidator , Blueprint } from './construction_tasks.js' ;
import { CookingTaskInitiator } from './cooking_tasks.js' ;
2024-12-10 15:39:57 -08:00
2025-04-01 22:33:37 -07:00
const PROGRESS _FILE = './hells_kitchen_progress.json' ;
const hellsKitchenProgressManager = {
readProgress : function ( ) {
try {
if ( existsSync ( PROGRESS _FILE ) ) {
const data = readFileSync ( PROGRESS _FILE , 'utf8' ) ;
return JSON . parse ( data ) ;
}
} catch ( err ) {
console . error ( 'Error reading progress file:' , err ) ;
}
return { taskId : null , agent0Complete : false , agent1Complete : false } ;
} ,
writeProgress : function ( progress ) {
try {
writeFileSync ( PROGRESS _FILE , JSON . stringify ( progress ) , 'utf8' ) ;
} catch ( err ) {
console . error ( 'Error writing progress file:' , err ) ;
}
} ,
resetTask : function ( taskId ) {
const progress = { taskId , agent0Complete : false , agent1Complete : false } ;
this . writeProgress ( progress ) ;
return progress ;
} ,
updateAgentProgress : function ( taskId , agentId , isComplete ) {
const progress = this . readProgress ( ) ;
// If it's a different task, reset first
if ( progress . taskId !== taskId ) {
progress . taskId = taskId ;
progress . agent0Complete = false ;
progress . agent1Complete = false ;
}
// Update the specific agent's status
if ( agentId === 0 ) progress . agent0Complete = isComplete ;
if ( agentId === 1 ) progress . agent1Complete = isComplete ;
this . writeProgress ( progress ) ;
return progress ;
} ,
isTaskComplete : function ( taskId ) {
const progress = this . readProgress ( ) ;
if ( progress . taskId !== taskId ) return false ;
return progress . agent0Complete && progress . agent1Complete ;
}
} ;
2024-12-29 10:56:20 -06:00
//todo: modify validator code to return an object with valid and score -> do more testing hahah
//todo: figure out how to log these things to the same place as bots/histories
2025-03-03 17:06:24 -08:00
// export class CraftTaskValidator {
// constructor(data, agent) {
// this.target = data.target;
// this.number_of_target = data.number_of_target;
// this.agent = agent;
2025-02-23 02:50:11 -08:00
/ * *
* Validates the presence of required items in an agent ' s inventory
* @ param { Object } data - Task data containing target and quantity information
* @ param { Object } agent - Agent object with bot inventory
* @ returns { Object } Validation result with success status and missing items
* /
function checkItemPresence ( data , agent ) {
2025-04-01 22:33:37 -07:00
try {
// Special handling for hells_kitchen tasks
if ( data . task _id && data . task _id . endsWith ( 'hells_kitchen' ) && Array . isArray ( data . target ) && data . target . length === 2 ) {
// Get agent ID and target for this agent
const agentId = agent . count _id ;
if ( agentId === 0 || agentId === 1 ) {
// Use only the corresponding element from the target list
const targetForThisAgent = data . target [ agentId ] ;
const modifiedData = {
... data ,
target : targetForThisAgent
} ;
// Check if this agent has their required item
const agentResult = checkItemForSingleAgent ( modifiedData , agent ) ;
// Update the file-based progress tracker
const progress = hellsKitchenProgressManager . updateAgentProgress (
data . task _id ,
agentId ,
agentResult . success
) ;
// // Log the current state
// console.log(`Agent ${agentId} has item: ${agentResult.success}`);
// console.log(`Task state: Agent0=${progress.agent0Complete}, Agent1=${progress.agent1Complete}`);
// Return combined result - success only if both agents have their items
return {
success : progress . agent0Complete && progress . agent1Complete ,
missingItems : agentResult . missingItems ,
agentComplete : agentResult . success // Individual agent status for debugging
} ;
}
}
// Non-hells_kitchen tasks use the standard check
return checkItemForSingleAgent ( data , agent ) ;
} catch ( error ) {
console . error ( 'Error checking item presence:' , error ) ;
return {
success : false ,
missingItems : [ ] ,
error : error . message
} ;
}
}
/ * *
* Helper function to check a single agent ' s inventory
* Extracted from the original checkItemPresence logic
* /
function checkItemForSingleAgent ( data , agent ) {
2025-02-23 02:50:11 -08:00
function isTargetDictionaryWithQuantities ( target ) {
return typeof target === 'object' &&
! Array . isArray ( target ) &&
target !== null &&
Object . values ( target ) . every ( value => typeof value === 'number' ) ;
2024-12-10 15:39:57 -08:00
}
2025-04-01 22:33:37 -07:00
2025-02-23 02:50:11 -08:00
function normalizeTargets ( target ) {
if ( typeof target === 'string' ) {
return { [ target ] : 1 } ;
} else if ( Array . isArray ( target ) ) {
return target . reduce ( ( acc , item ) => {
acc [ item ] = 1 ;
return acc ;
} , { } ) ;
} else if ( typeof target === 'object' && target !== null ) {
return target ;
}
throw new Error ( 'Invalid target format' ) ;
}
2025-04-01 22:33:37 -07:00
2025-02-23 02:50:11 -08:00
function normalizeQuantities ( targets , quantities ) {
if ( quantities === undefined ) {
return Object . keys ( targets ) . reduce ( ( acc , key ) => {
acc [ key ] = 1 ;
return acc ;
} , { } ) ;
} else if ( typeof quantities === 'number' ) {
return Object . keys ( targets ) . reduce ( ( acc , key ) => {
acc [ key ] = quantities ;
return acc ;
} , { } ) ;
} else if ( typeof quantities === 'object' && quantities !== null ) {
return quantities ;
}
throw new Error ( 'Invalid number_of_target format' ) ;
2024-12-10 15:39:57 -08:00
}
2025-04-01 22:33:37 -07:00
// First normalize targets to always have a consistent format
const targets = normalizeTargets ( data . target ) ;
// Determine the required quantities
const requiredQuantities = isTargetDictionaryWithQuantities ( data . target )
? data . target
: normalizeQuantities ( targets , data . number _of _target ) ;
2024-12-10 15:39:57 -08:00
2025-04-01 22:33:37 -07:00
// Count items in inventory
const inventoryCount = { } ;
agent . bot . inventory . slots . forEach ( ( slot ) => {
if ( slot ) {
const itemName = slot . name . toLowerCase ( ) ;
inventoryCount [ itemName ] = ( inventoryCount [ itemName ] || 0 ) + slot . count ;
2024-12-10 15:39:57 -08:00
}
2025-04-01 22:33:37 -07:00
} ) ;
2025-02-23 02:50:11 -08:00
2025-04-01 22:33:37 -07:00
// Check if all required items are present in sufficient quantities
const missingItems = [ ] ;
let allTargetsMet = true ;
2025-02-23 02:50:11 -08:00
2025-04-01 22:33:37 -07:00
for ( const [ item , requiredCount ] of Object . entries ( requiredQuantities ) ) {
const itemName = item . toLowerCase ( ) ;
const currentCount = inventoryCount [ itemName ] || 0 ;
if ( currentCount < requiredCount ) {
allTargetsMet = false ;
missingItems . push ( {
item : itemName ,
required : requiredCount ,
current : currentCount ,
missing : requiredCount - currentCount
} ) ;
}
2024-12-10 15:39:57 -08:00
}
2025-04-01 22:33:37 -07:00
return {
success : allTargetsMet ,
missingItems : missingItems
} ;
2024-12-10 15:39:57 -08:00
}
2025-04-01 22:33:37 -07:00
2025-03-03 17:06:24 -08:00
class CookingCraftingTaskValidator {
constructor ( data , agent ) {
this . data = data ;
this . agent = agent ;
}
2025-03-20 12:56:29 -07:00
validate ( ) {
const result = checkItemPresence ( this . data , this . agent ) ;
let score = 0 ;
if ( result . success ) {
score = 1 ;
2025-03-05 10:10:24 -08:00
}
2025-03-20 12:56:29 -07:00
return {
"valid" : result . success ,
"score" : score ,
} ;
2024-12-10 15:39:57 -08:00
}
}
export class Task {
2025-06-10 17:52:30 -05:00
constructor ( agent , task _data , taskStartTime = null ) {
2024-12-10 15:39:57 -08:00
this . agent = agent ;
this . data = null ;
2025-03-16 20:31:30 -07:00
if ( taskStartTime !== null )
this . taskStartTime = taskStartTime ;
else
this . taskStartTime = Date . now ( ) ;
2024-12-10 15:39:57 -08:00
this . validator = null ;
2025-01-07 19:29:50 -08:00
this . reset _function = null ;
2024-12-10 15:39:57 -08:00
this . blocked _actions = [ ] ;
2025-06-10 17:52:30 -05:00
this . task _data = task _data ;
if ( task _data ) {
console . log ( 'Starting task' , task _data . task _id ) ;
console . log ( "Task start time set to" , this . taskStartTime ) ;
if ( task _data . task _id . endsWith ( 'hells_kitchen' ) ) {
2025-04-21 12:20:06 -05:00
// Reset hells_kitchen progress when a new task starts
2025-06-10 17:52:30 -05:00
hellsKitchenProgressManager . resetTask ( task _data . task _id ) ;
2025-04-21 12:20:06 -05:00
console . log ( 'Reset Hells Kitchen progress for new task' ) ;
}
2025-06-10 17:52:30 -05:00
this . data = task _data ;
2024-12-23 11:34:56 -06:00
this . task _type = this . data . type ;
if ( this . task _type === 'construction' && this . data . blueprint ) {
this . blueprint = new Blueprint ( this . data . blueprint ) ;
2024-12-26 18:12:11 -06:00
this . goal = this . data . goal + ' \n' + this . blueprint . explain ( ) + " \n" + "make sure to place the lower levels of the blueprint first" ;
this . conversation = this . data . conversation + ' \n' + this . blueprint . explain ( ) ;
2024-12-23 11:34:56 -06:00
} else {
this . goal = this . data . goal ;
2024-12-26 18:12:11 -06:00
this . conversation = this . data . conversation ;
2024-12-23 11:34:56 -06:00
}
2024-12-10 15:39:57 -08:00
this . taskTimeout = this . data . timeout || 300 ;
2025-02-23 02:50:11 -08:00
// Set validator based on task_type
2025-02-27 21:00:41 -08:00
2025-05-23 11:49:51 -07:00
// do goal initialization here
// let agentGoal = this.getAgentGoal();
// if (agentGoal) {
// agentGoal += "You have to collaborate with other agents/bots, namely " + this.available_agents.filter(n => n !== this.name).join(', ') + " to complete the task as soon as possible by dividing the work among yourselves.";
// console.log(`Setting goal for agent ${this.agent.count_id}: ${agentGoal}`);
// await executeCommand(this.agent, `!goal("${agentGoal}")`);
// }
2024-12-26 18:12:11 -06:00
if ( this . task _type === 'construction' ) {
this . validator = new ConstructionTaskValidator ( this . data , this . agent ) ;
2025-03-03 17:06:24 -08:00
} else if ( this . task _type === 'cooking' || this . task _type === 'techtree' ) {
this . validator = new CookingCraftingTaskValidator ( this . data , this . agent ) ;
2025-03-04 11:10:42 -08:00
2025-02-23 02:50:11 -08:00
} else {
this . validator = null ;
2024-12-26 18:12:11 -06:00
}
2025-02-23 02:59:46 -08:00
2025-02-20 21:45:29 -08:00
if ( this . data . blocked _actions ) {
this . blocked _actions = this . data . blocked _actions [ this . agent . count _id . toString ( ) ] || [ ] ;
} else {
this . blocked _actions = [ ] ;
}
2025-01-09 15:15:25 -06:00
this . restrict _to _inventory = ! ! this . data . restrict _to _inventory ;
2024-12-10 15:39:57 -08:00
if ( this . data . goal )
this . blocked _actions . push ( '!endGoal' ) ;
2024-12-26 18:12:11 -06:00
if ( this . conversation )
2024-12-10 15:39:57 -08:00
this . blocked _actions . push ( '!endConversation' ) ;
}
2025-04-21 12:20:06 -05:00
else {
console . log ( 'No task.' ) ;
}
2025-03-03 11:53:57 -08:00
2025-02-23 02:50:11 -08:00
this . name = this . agent . name ;
2025-06-10 17:52:30 -05:00
this . available _agents = [ ]
}
updateAvailableAgents ( agents ) {
this . available _agents = agents
2024-12-10 15:39:57 -08:00
}
2025-04-01 22:33:37 -07:00
// Add this method if you want to manually reset the hells_kitchen progress
resetHellsKitchenProgress ( ) {
if ( this . task _id && this . task _id . endsWith ( 'hells_kitchen' ) ) {
hellsKitchenProgressManager . resetTask ( this . task _id ) ;
console . log ( 'Hells Kitchen progress reset manually' ) ;
}
}
2025-02-23 03:21:59 -08:00
getAgentGoal ( ) {
if ( ! this . data || ! this . data . goal ) {
return null ;
}
2025-02-25 22:47:43 -08:00
let add _string = '' ;
if ( this . task _type === 'cooking' ) {
2025-03-25 11:05:56 -07:00
2025-05-05 17:11:48 -07:00
if ( this . data . agent _count > 2 ) {
if ( this . name . toLowerCase ( ) . startsWith ( 'andy' ) ) {
add _string = '\nIn the end, all the food items should be given to you by other bots. Make sure to talk to all the agents using startConversation command to coordinate the task instead of talking to just one agent. You can even end current conversation with any agent using endConversation command and then talk to a new agent using startConversation command.' ;
2025-03-25 11:05:56 -07:00
}
else {
2025-05-05 17:11:48 -07:00
add _string = '\nIn the end, all the food items should be given to one single bot whose name starts with andy or Andy. Make sure to talk to all the agents using startConversation command to coordinate the task instead of talking to just one agent. You can even end current conversation with any agent using endConversation command and then talk to a new agent using startConversation command.' ;
}
}
else {
if ( this . data . task _id && this . data . task _id . endsWith ( 'hells_kitchen' ) ) {
add _string = '' ;
2025-03-25 11:05:56 -07:00
}
else {
2025-05-05 17:11:48 -07:00
add _string = '\nIn the end, all the food items should be given to one single bot.' ;
2025-04-01 22:33:37 -07:00
}
2025-05-05 17:11:48 -07:00
}
2025-02-25 22:47:43 -08:00
}
2025-04-07 20:36:05 -07:00
if ( this . task _type === 'techtree' ) {
if ( this . data . agent _count > 2 ) {
add _string = '\nMake sure to share resources among all agents and to talk to all the agents using startConversation command to coordinate the task instead of talking to just one agent. You can even end current conversation with any agent using endConversation command and then talk to a new agent using startConversation command.'
}
}
2025-02-23 03:21:59 -08:00
// If goal is a string, all agents share the same goal
if ( typeof this . data . goal === 'string' ) {
2025-02-25 22:47:43 -08:00
return this . data . goal + add _string ;
2025-02-23 03:21:59 -08:00
}
// If goal is an object, get the goal for this agent's count_id
if ( typeof this . data . goal === 'object' && this . data . goal !== null ) {
const agentId = this . agent . count _id . toString ( ) ;
2025-02-25 22:47:43 -08:00
return ( this . data . goal [ agentId ] || '' ) + add _string ;
2025-02-23 03:21:59 -08:00
}
return null ;
2024-12-10 15:39:57 -08:00
}
isDone ( ) {
2025-03-03 17:06:24 -08:00
let res = null ;
if ( this . validator )
2025-03-20 12:56:29 -07:00
res = this . validator . validate ( ) ;
2025-03-03 17:06:24 -08:00
if ( res && res . valid ) {
2025-03-20 12:56:29 -07:00
// Find all the agents and clear their inventories
for ( let agent of this . available _agents ) {
this . agent . bot . chat ( ` /clear ${ agent } ` ) ;
}
2025-05-05 14:19:14 -07:00
// this.agent.bot.chat(`/clear @a`);
2025-03-03 17:06:24 -08:00
return { "message" : 'Task successful' , "score" : res . score } ;
}
2025-02-28 16:59:56 -08:00
let other _names = this . available _agents . filter ( n => n !== this . name ) ;
const elapsedTime = ( Date . now ( ) - this . taskStartTime ) / 1000 ;
2025-02-28 18:31:19 -08:00
if ( elapsedTime >= 30 && this . available _agents . length !== this . data . agent _count ) {
2025-02-28 16:59:56 -08:00
console . log ( 'No other agents found. Task unsuccessful.' ) ;
2025-03-03 17:06:24 -08:00
return { "message" : 'No other agents found' , "score" : 0 } ;
2025-02-28 16:59:56 -08:00
}
2025-02-23 02:50:11 -08:00
2024-12-10 15:39:57 -08:00
if ( this . taskTimeout ) {
if ( elapsedTime >= this . taskTimeout ) {
console . log ( 'Task timeout reached. Task unsuccessful.' ) ;
2025-03-03 17:06:24 -08:00
if ( res ) {
return { "message" : 'Task timeout reached' , "score" : res . score } ;
} else {
return { "message" : 'Task timeout reached' , "score" : 0 } ;
}
2024-12-10 15:39:57 -08:00
}
}
return false ;
}
2025-05-23 11:49:51 -07:00
async setAgentGoal ( ) {
let agentGoal = this . getAgentGoal ( ) ;
if ( agentGoal && this . data . agent _count + this . data . human _count > 1 ) {
agentGoal += "You have to collaborate with other agents/bots, namely " + this . available _agents . filter ( n => n !== this . name ) . join ( ', ' ) + " to complete the task as soon as possible by dividing the work among yourselves." ;
console . log ( ` Setting goal for agent ${ this . agent . count _id } : ${ agentGoal } ` ) ;
}
await executeCommand ( this . agent , ` !goal(" ${ agentGoal } ") ` ) ;
}
2024-12-10 15:39:57 -08:00
async initBotTask ( ) {
2025-02-23 02:50:11 -08:00
await this . agent . bot . chat ( ` /clear ${ this . name } ` ) ;
console . log ( ` Cleared ${ this . name } 's inventory. ` ) ;
2025-01-07 19:29:50 -08:00
2024-12-10 15:39:57 -08:00
//wait for a bit so inventory is cleared
await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
2025-03-02 12:53:09 -08:00
2024-12-10 15:39:57 -08:00
if ( this . data === null )
return ;
2025-02-23 02:53:45 -08:00
if ( this . task _type === 'cooking' ) {
2025-05-01 15:08:07 -07:00
this . initiator = new CookingTaskInitiator ( this . data , this . agent . bot ) ;
2025-02-23 02:50:11 -08:00
} else {
this . initiator = null ;
2024-12-10 15:39:57 -08:00
}
2025-02-12 15:39:57 -08:00
2025-02-23 02:50:11 -08:00
//wait for a bit so bots are teleported
await new Promise ( ( resolve ) => setTimeout ( resolve , 3000 ) ) ;
2025-05-05 15:00:58 -07:00
if ( this . agent . count _id === 0 && this . data . human _count > 0 ) {
console . log ( 'Clearing human player inventories' ) ;
for ( let i = 0 ; i < this . data . human _count ; i ++ ) {
const username = this . data . usernames [ i ] ;
await this . agent . bot . chat ( ` /clear ${ username } ` ) ;
}
await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
}
2025-02-23 02:50:11 -08:00
if ( this . data . initial _inventory ) {
2024-12-10 15:39:57 -08:00
console . log ( "Setting inventory..." ) ;
2025-02-23 02:50:11 -08:00
let initialInventory = { } ;
2025-04-25 19:16:00 -07:00
initialInventory = this . data . initial _inventory [ this . agent . count _id . toString ( ) ] || { } ;
console . log ( "Initial inventory for agent" , this . agent . count _id , ":" , initialInventory ) ;
2025-05-05 15:00:58 -07:00
console . log ( "" )
2025-04-25 19:16:00 -07:00
if ( this . data . human _count > 0 && this . agent . count _id === 0 ) {
// this.num_humans = num_keys - this.data.num_agents;
if ( this . data . human _count !== this . data . usernames . length ) {
console . log ( ` Number of human players ${ this . human _count } does not match the number of usernames provided. ${ this . data . usernames . length } ` ) ;
throw new Error ( ` Number of human players ${ this . human _count } does not match the number of usernames provided. ${ this . data . usernames . length } ` ) ;
return ;
}
2025-05-03 15:00:48 -07:00
2025-04-25 19:16:00 -07:00
const starting _idx = this . data . agent _count ;
for ( let i = 0 ; i < this . data . human _count ; i ++ ) {
const username = this . data . usernames [ i ] ;
const inventory = this . data . initial _inventory [ starting _idx + i ] ;
console . log ( Object . keys ( inventory ) ) ;
for ( let key of Object . keys ( inventory ) ) {
const itemName = key . toLowerCase ( ) ;
const quantity = inventory [ key ] ;
console . log ( ` Give ${ username } ${ quantity } ${ itemName } ` ) ;
await this . agent . bot . chat ( ` /give ${ username } ${ itemName } ${ quantity } ` ) ;
}
}
2025-02-23 02:50:11 -08:00
}
2025-03-04 11:54:09 -08:00
console . log ( this . data . initial _inventory ) ;
2025-02-23 02:50:11 -08:00
// Assign inventory items
for ( let key of Object . keys ( initialInventory ) ) {
const itemName = key . toLowerCase ( ) ;
const quantity = initialInventory [ key ] ;
await this . agent . bot . chat ( ` /give ${ this . name } ${ itemName } ${ quantity } ` ) ;
console . log ( ` Gave ${ this . name } ${ quantity } ${ itemName } ` ) ;
}
// Wait briefly for inventory commands to complete
2024-12-10 15:39:57 -08:00
await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
}
2025-02-23 02:50:11 -08:00
2025-05-01 15:08:07 -07:00
if ( this . initiator && this . agent . count _id === 0 ) {
2025-02-23 02:50:11 -08:00
await this . initiator . init ( ) ;
}
2025-03-21 02:18:07 -07:00
await this . teleportBots ( ) ;
2025-02-23 02:50:11 -08:00
if ( this . data . agent _count && this . data . agent _count > 1 ) {
// TODO wait for other bots to join
await new Promise ( ( resolve ) => setTimeout ( resolve , 10000 ) ) ;
if ( this . available _agents . length < this . data . agent _count ) {
console . log ( ` Missing ${ this . data . agent _count - this . available _agents . length } bot(s). ` ) ;
this . agent . killAll ( ) ;
}
}
2025-06-01 18:43:28 -05:00
await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
2025-02-28 18:31:19 -08:00
if ( this . data . conversation && this . agent . count _id === 0 ) {
let other _name = this . available _agents . filter ( n => n !== this . name ) [ 0 ] ;
let waitCount = 0 ;
while ( other _name === undefined && waitCount < 20 ) {
other _name = this . available _agents . filter ( n => n !== this . name ) [ 0 ] ;
await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
waitCount ++ ;
}
2025-04-29 14:26:37 -07:00
if ( other _name === undefined && this . data . agent _count > 1 ) {
2025-02-28 18:31:19 -08:00
console . log ( 'No other agents found. Task unsuccessful.' ) ;
this . agent . killAll ( ) ;
}
await executeCommand ( this . agent , ` !startConversation(" ${ other _name } ", " ${ this . data . conversation } ") ` ) ;
}
2025-06-01 18:43:28 -05:00
await this . setAgentGoal ( ) ;
2025-02-23 02:50:11 -08:00
}
2024-12-10 15:39:57 -08:00
2025-02-23 02:50:11 -08:00
async teleportBots ( ) {
2025-03-05 10:10:24 -08:00
console . log ( '\n\nTeleporting bots' ) ;
2024-12-10 15:39:57 -08:00
function getRandomOffset ( range ) {
return Math . floor ( Math . random ( ) * ( range * 2 + 1 ) ) - range ;
}
2025-02-23 02:50:11 -08:00
2024-12-10 15:39:57 -08:00
let human _player _name = null ;
2025-02-23 02:50:11 -08:00
let bot = this . agent . bot ;
2025-03-03 11:53:57 -08:00
2024-12-10 15:39:57 -08:00
// Finding if there is a human player on the server
for ( const playerName in bot . players ) {
const player = bot . players [ playerName ] ;
2025-02-23 02:50:11 -08:00
if ( ! this . available _agents . some ( ( n ) => n === playerName ) ) {
2024-12-10 15:39:57 -08:00
console . log ( 'Found human player:' , player . username ) ;
human _player _name = player . username
break ;
}
2024-12-12 12:33:00 -08:00
}
2025-05-09 15:22:27 -07:00
// go the human if there is one and not required for the task
if ( human _player _name && this . data . human _count === 0 ) {
2025-02-23 02:50:11 -08:00
console . log ( ` Teleporting ${ this . name } to human ${ human _player _name } ` )
bot . chat ( ` /tp ${ this . name } ${ human _player _name } ` )
2024-12-10 15:39:57 -08:00
}
2025-03-21 02:18:07 -07:00
else {
console . log ( ` Teleporting ${ this . name } to ${ this . available _agents [ 0 ] } ` )
bot . chat ( ` /tp ${ this . name } ${ this . available _agents [ 0 ] } ` ) ;
}
2024-12-10 15:39:57 -08:00
await new Promise ( ( resolve ) => setTimeout ( resolve , 200 ) ) ;
2025-02-23 02:50:11 -08:00
2024-12-10 15:39:57 -08:00
// 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
2025-03-03 11:53:57 -08:00
2024-12-10 15:39:57 -08:00
/ *
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 ,
* /
2025-02-19 18:25:59 -08:00
2025-02-23 02:50:11 -08:00
2024-12-10 15:39:57 -08:00
if ( this . data . type !== 'construction' ) {
const pos = getPosition ( bot ) ;
const xOffset = getRandomOffset ( 5 ) ;
const zOffset = getRandomOffset ( 5 ) ;
2025-02-23 02:50:11 -08:00
bot . chat ( ` /tp ${ this . name } ${ Math . floor ( pos . x + xOffset ) } ${ pos . y + 3 } ${ Math . floor ( pos . z + zOffset ) } ` ) ;
2024-12-10 15:39:57 -08:00
await new Promise ( ( resolve ) => setTimeout ( resolve , 200 ) ) ;
}
2024-12-12 18:53:24 -08:00
2024-12-10 15:39:57 -08:00
if ( this . data . agent _count && this . data . agent _count > 1 ) {
2024-12-12 18:53:24 -08:00
// TODO wait for other bots to join
2024-12-10 15:39:57 -08:00
await new Promise ( ( resolve ) => setTimeout ( resolve , 10000 ) ) ;
2025-03-03 17:06:24 -08:00
if ( this . available _agents . length < this . data . agent _count ) {
console . log ( ` Missing ${ this . data . agent _count - this . available _agents . length } bot(s). ` ) ;
2024-12-13 10:42:41 -06:00
this . agent . killAll ( ) ;
2024-12-10 15:39:57 -08:00
}
}
2024-12-12 18:53:24 -08:00
2025-02-19 18:25:59 -08:00
if ( this . data . type === 'construction' ) {
//Ensures construction is cleaned out first. -> relies on cheats which are turned off?
if ( this . blueprint ) {
2025-04-08 20:57:19 -07:00
console . log ( 'Cleaning out construction blueprint' ) ;
2025-02-19 18:25:59 -08:00
const result = this . blueprint . autoDelete ( ) ;
const commands = result . commands ;
const nearbyPosition = result . nearbyPosition ;
2025-03-10 23:08:35 -07:00
console . log ( "nearby position" , nearbyPosition ) ;
2025-05-09 15:22:27 -07:00
const first _coord = this . data . blueprint . levels [ 0 ] . coordinates ;
bot . chat ( ` /tp @a ${ first _coord [ 0 ] } ${ first _coord [ 1 ] } ${ first _coord [ 2 ] } ` ) ;
if ( this . agent . agent _id === 0 && this . data . human _count > 0 ) {
for ( let i = 0 ; i < this . data . human _count ; i ++ ) {
const username = this . data . usernames [ i ] ;
await bot . chat ( ` /tp ${ username } ${ nearbyPosition . x } ${ nearbyPosition . y } ${ nearbyPosition . z } ` ) ;
}
}
2025-02-19 18:25:59 -08:00
for ( const command of commands ) {
bot . chat ( command ) ;
}
}
else {
console . log ( 'no construction blueprint?' )
}
}
2025-01-26 11:26:11 -08:00
}
2025-02-23 02:50:11 -08:00
}