Create a new task in AI sequence

Wrote new code? Fixed a bug? Want to discuss technical stuff? Feel free to post it here.

Moderator: Moderators

ryanblonna3
Human
Human
Posts: 30
Joined: 29 Jul 2010, 11:53
Noob?: No

Create a new task in AI sequence

#1 Post by ryanblonna3 »

Hi geniuses :-), how would one add a task to the AI sequence (i.e. @ai_seq and @ai_seq_args) that allows the AI to interrupt? For example, I want to create a task called "pause", so I would add it to the queue, and the queue would look something like this:

0: pause <---- my task
1: storageAuto

but the AI would still be able to interrupt it if a monster attacked. For example, the above would then look like this:

0: skill_use
1: attack
2: pause <---- my interrupted task
3: storageAuto

The purpose of this is to be able to "pause" a running "route" sequence, but still be able to attack, use skills, pick up items, etc. I'm using some experimental code to do this in a subroutine within the macro plugin, but nobody has answered any of my questions in Macros part of the forums.

I'm stumped on this. Please help.
Technology
Super Moderators
Super Moderators
Posts: 801
Joined: 06 May 2008, 12:47
Noob?: No

Re: Create a new task in AI sequence

#2 Post by Technology »

You could use the Wait task.
One ST0 to rule them all? One PE viewer to find them!
One ST_kRO to bring them all and in the darkness bind them...

Mount Doom awaits us, fellowship of OpenKore!
ryanblonna3
Human
Human
Posts: 30
Joined: 29 Jul 2010, 11:53
Noob?: No

Re: Create a new task in AI sequence

#3 Post by ryanblonna3 »

Hmmm...yeah I was just looking at that task. But how would you use it? Do you mean something like

Code: Select all

my $waitTask = new Task::Wait(
         seconds => 3,
         inGame => 1
);

AI::queue('pause', $waitTask);
?

I tried it out, but OK does not do anything after the task is queued. It should be able to sit, attack, etc. Maybe I should use the name 'route' instead of 'pause'?

Thanks for the help :-)

EDIT: Here's some code I tried that would not let the AI take over when it is called:

Code: Select all

macro AIPause {
[
	call AIResume
	
	Pause()
]
}

sub Pause {
	use Task::Wait;
	
	my $i = AI::findAction('route');
	
	if(defined $i) {
		my $task = new Task::Wait('name' => 'pause', 'priority' => Task::LOW_PRIORITY, 'seconds' => 1800, 'inGame' => 1);
		
		$task->{'attackOnRoute'} = 2;
		$task->{'noSitAuto'} = 0;
		
		splice(@::ai_seq, $i, 0, 'pause');
		splice(@::ai_seq_args, $i, 0, $task);
		
		message T('debug\n');
	}
}

macro AIResume {
[
	do eval AI::clear('pause')
]
}
The macro AIPause will be called from an automacro that will dictate when the bot will stop walking (i.e. only the 'route' sequence will not work).

I guess I'm supposed to call $task->interrupt and $task->resume somewhere, but I can't figure it out yet. Help! :-(
Technology
Super Moderators
Super Moderators
Posts: 801
Joined: 06 May 2008, 12:47
Noob?: No

Re: Create a new task in AI sequence

#4 Post by Technology »

Well, you put the task in the AI queue, but you don't actually add it to the task manager.

Code: Select all

$taskManager->add(new Task::Wait('name' => 'pause', 'priority' => Task::LOW_PRIORITY, 'seconds' => 1800, 'inGame' => 1));
Also, make sure you use kore svn, since the Task::Wait had a bug that i fixed after 2.0.7
One ST0 to rule them all? One PE viewer to find them!
One ST_kRO to bring them all and in the darkness bind them...

Mount Doom awaits us, fellowship of OpenKore!
ryanblonna3
Human
Human
Posts: 30
Joined: 29 Jul 2010, 11:53
Noob?: No

Re: Create a new task in AI sequence

#5 Post by ryanblonna3 »

Wow, wouldn't have been able to figure that out without your help, thanks :-). Yup, I'm using the latest SVN version. It should automagically update itself via TortoiseSVN, no?

But...

Code: Select all

macro AIPause {
[
	call AIResume
	
	Pause()
]
}

macro AIResume {
[
	do eval AI::clear('pause')
]
}

sub Pause {
   use Task::Wait;
   
   my $i = AI::findAction('route');
   
   if(defined $i) {
      my $task = new Task::Wait('name' => 'pause', 'priority' => Task::LOW_PRIORITY, 'seconds' => 1800, 'inGame' => 1);
          
      splice(@::ai_seq, $i, 0, 'pause');
      splice(@::ai_seq_args, $i, 0, $task);
      
      $::taskManager->add($task);
   }
   
   return;
}
Ok, so I added the task to the task manager, but it still won't do a sitAuto sequence. Maybe OK thinks it's not idle? If so, how do I make OK consider it as idle? I tried code similar to the cmdStand sub:

Code: Select all

sub cmdStand {
	if (!$net || $net->getState() != Network::IN_GAME) {
		error TF("You must be logged in the game to use this command (%s)\n", shift);
		return;
	}
	delete $ai_v{sitAuto_forcedBySitCommand};
	$ai_v{sitAuto_forceStop} = 1;
	require Task::SitStand;
	my $task = new Task::ErrorReport(
		task => new Task::SitStand(
			mode => 'stand',
			priority => Task::USER_PRIORITY
		)
	);
	$taskManager->add($task);
}
I changed parts of the sub to use my 'pause' task instead. But OK would just continue with its route sequence (it would just keep walking, instead of staying in one place). Note that I did not clear the 'route' sequence, because I want it to resume when I remove the 'pause' task.

Thanks again for the time and replies :-)
ryanblonna3
Human
Human
Posts: 30
Joined: 29 Jul 2010, 11:53
Noob?: No

Re: Create a new task in AI sequence

#6 Post by ryanblonna3 »

Ah, I just noticed that a task can be interrupted via $task->interrupt, and resumed via $task->resume. This might work! But right now I'm getting a "Task 'Route' (class Task::Route) has status INTERRUPTED, but should be RUNNING" message. Is there any work around?

Code: Select all

macro AIPause {
[
	do eval my $_i = AI::findAction('route'); if(defined $_i && AI::args($_i)->getStatus() == Task::RUNNING){ AI::args($_i)->interrupt(); }
]
}

macro AIResume {
[
	do eval my $_i = AI::findAction('route'); if(defined $_i && AI::args($_i)->getStatus() == Task::INTERRUPTED){ AI::args($_i)->resume(); }
]
}
And here's errors.txt (tell me if the post is too long :-) ):

Code: Select all

OpenKore version what-will-become-2.1
@ai_seq = route
Network state = 5
Network handler = Network::XKore
SVN revision: 7429
Loaded plugins:
  plugins/arrowCraft.pl (arrowCraft)
  plugins/breakTime.pl (breakTime)
  plugins/chatDomains.pl (chatDomains)
  plugins/geographer.pl (geographer)
  plugins/macro.pl (macro)
  plugins/macroinclude.pl (macroinclude)
  plugins/monsterDB.pl (monsterDB)

Error message:
Task 'Route' (class Task::Route) has status INTERRUPTED, but should be RUNNING. Object details:
$VAR1 = bless( {
                 'attackID' => undef,
                 'time_start' => '1285654028.71441',
                 'LOSSubRoute' => undef,
                 'stage' => 'Walk the Route Solution',
                 'T_priority' => 500,
                 'dest' => {
                             'map' => 'iz_dun04',
                             'pos' => {
                                        'y' => 134,
                                        'x' => 115
                                      }
                           },
                 'avoidWalls' => 1,
                 'ST_autostop' => 1,
                 'ST_subtask' => bless( {
                                          'giveup' => {
                                                        'time' => '1285654029.52629',
                                                        'timeout' => '1.5'
                                                      },
                                          'T_priority' => 500,
                                          'ST_autofail' => 1,
                                          'start_time' => '1285654029.52629',
                                          'x' => 115,
                                          'ST_autostop' => 1,
                                          'ST_manageMutexes' => undef,
                                          'T_name' => 'Move',
                                          'retry' => {
                                                       'time' => '1285654030.03364',
                                                       'timeout' => '0.5'
                                                     },
                                          'y' => 134,
                                          'interruptionTime' => '1285654030.36972',
                                          'T_status' => 2,
                                          'T_onStop' => bless( [], 'CallbackList' ),
                                          'T_onMutexesChanged' => bless( [], 'CallbackList' ),
                                          'mapChangedHook' => bless( [
                                                                       \'Network::Receive::map_changed',
                                                                       3
                                                                     ], 'Plugins::HookHandle' ),
                                          'T_mutexes' => [
                                                           'movement'
                                                         ]
                                        }, 'Task::Move' ),
                 'ST_manageMutexes' => undef,
                 'time_step' => '1285654028.71482',
                 'T_name' => 'Route',
                 'old_y' => 126,
                 'T_onStop' => bless( [], 'CallbackList' ),
                 'T_mutexes' => [
                                  'movement'
                                ],
                 'noSitAuto' => undef,
                 'ST_autofail' => 0,
                 'mapChanged' => undef,
                 'maxTime' => '75',
                 'new_y' => 134,
                 'index' => 15,
                 'new_x' => 115,
                 'old_x' => 108,
                 'interruptionTime' => '1285654030.36973',
                 'T_status' => 2,
                 'T_onMutexesChanged' => bless( [], 'CallbackList' ),
                 'attackOnRoute' => 2,
                 'mapChangedHook' => bless( [
                                              $VAR1->{'ST_subtask'}{'mapChangedHook'}[0],
                                              2
                                            ], 'Plugins::HookHandle' )
               }, 'Task::Route' );

Stack trace:
Task 'Route' (class Task::Route) has status INTERRUPTED, but should be RUNNING. Object details:
$VAR1 = bless( {
                 'attackID' => undef,
                 'time_start' => '1285654028.71441',
                 'LOSSubRoute' => undef,
                 'stage' => 'Walk the Route Solution',
                 'T_priority' => 500,
                 'dest' => {
                             'map' => 'iz_dun04',
                             'pos' => {
                                        'y' => 134,
                                        'x' => 115
                                      }
                           },
                 'avoidWalls' => 1,
                 'ST_autostop' => 1,
                 'ST_subtask' => bless( {
                                          'giveup' => {
                                                        'time' => '1285654029.52629',
                                                        'timeout' => '1.5'
                                                      },
                                          'T_priority' => 500,
                                          'ST_autofail' => 1,
                                          'start_time' => '1285654029.52629',
                                          'x' => 115,
                                          'ST_autostop' => 1,
                                          'ST_manageMutexes' => undef,
                                          'T_name' => 'Move',
                                          'retry' => {
                                                       'time' => '1285654030.03364',
                                                       'timeout' => '0.5'
                                                     },
                                          'y' => 134,
                                          'interruptionTime' => '1285654030.36972',
                                          'T_status' => 2,
                                          'T_onStop' => bless( [], 'CallbackList' ),
                                          'T_onMutexesChanged' => bless( [], 'CallbackList' ),
                                          'mapChangedHook' => bless( [
                                                                       \'Network::Receive::map_changed',
                                                                       3
                                                                     ], 'Plugins::HookHandle' ),
                                          'T_mutexes' => [
                                                           'movement'
                                                         ]
                                        }, 'Task::Move' ),
                 'ST_manageMutexes' => undef,
                 'time_step' => '1285654028.71482',
                 'T_name' => 'Route',
                 'old_y' => 126,
                 'T_onStop' => bless( [], 'CallbackList' ),
                 'T_mutexes' => [
                                  'movement'
                                ],
                 'noSitAuto' => undef,
                 'ST_autofail' => 0,
                 'mapChanged' => undef,
                 'maxTime' => '75',
                 'new_y' => 134,
                 'index' => 15,
                 'new_x' => 115,
                 'old_x' => 108,
                 'interruptionTime' => '1285654030.36973',
                 'T_status' => 2,
                 'T_onMutexesChanged' => bless( [], 'CallbackList' ),
                 'attackOnRoute' => 2,
                 'mapChangedHook' => bless( [
                                              $VAR1->{'ST_subtask'}{'mapChangedHook'}[0],
                                              2
                                            ], 'Plugins::HookHandle' )
               }, 'Task::Route' );
 at src/AI/CoreLogic.pm line 739
	AI::CoreLogic::processTask('route', 'onError', 'CODE(0x3ea17c4)') called at src/AI/CoreLogic.pm line 88
	AI::CoreLogic::iterate() called at src/functions.pl line 749
	main::mainLoop_initialized() called at src/functions.pl line 69
	main::mainLoop() called at src/Interface.pm line 75
	Interface::mainLoop('Interface::Console::Win32=HASH(0x3ff383c)') called at openkore.pl line 97
	main::__start() called at start.pl line 125
Thanks...
ryanblonna3
Human
Human
Posts: 30
Joined: 29 Jul 2010, 11:53
Noob?: No

Re: Create a new task in AI sequence

#7 Post by ryanblonna3 »

Ok, that last attempt did not work. Now I'm using the Function task. Here's my new code:

Code: Select all

macro AIPause {
[
	do eval use Task::Function; $_routePause = 1; $::taskManager->add(new Task::Function('name' => 'pause', 'priority' => Task::USER_PRIORITY, 'function' => sub{if($_debugMsg){Log::message T("var = $_routePause\n"); $_debugMsg = 0} $_[0]->setDone() if !$_routePause}))
	#do eval AI::clear('route')
]
}

macro AIResume {
[
	do eval $_debugMsg = 1; $_routePause = 0
]
}
The task executes, but then again, it does not stop the route task. How does the UseSkill task accomplish this?

Thanks :-)
EternalHarvest
Developers
Developers
Posts: 1798
Joined: 05 Dec 2008, 05:42
Noob?: Yes

Re: Create a new task in AI sequence

#8 Post by EternalHarvest »

Aren't tasks in $taskManager independent from AI queue?
ryanblonna3 wrote:

Code: Select all

my $waitTask = new Task::Wait(
         seconds => 3,
         inGame => 1
);

AI::queue('pause', $waitTask);
?

I tried it out, but OK does not do anything after the task is queued.
For tasks in AI queue to work (they don't need to be in $taskManager) you need to call CoreLogic::processTask('pause') (where 'pause' is first argument from AI::queue) in CoreLogic::iterate or in any its hook ('AI_pre' for example).
ryanblonna3
Human
Human
Posts: 30
Joined: 29 Jul 2010, 11:53
Noob?: No

Re: Create a new task in AI sequence

#9 Post by ryanblonna3 »

Oh. Now I get it...these are two completely different ways of operating the AI, and you guys are planning to shift to the task manager instead of using the AI queue. Now I have two ways to do things :-). Thanks for clearing that up. Cheers!