Paththrough Navigation: Difference between revisions

From MyGamingTalk
m (1 revision imported)
(OnExit)
Line 15: Line 15:
  global Map =
  global Map =
  {
  {
Navigation =
Navigation =
{
{
strafe_r_point =
strafe_r_point =
{
{
navigate = function(_this)
navigate = function(_this)
{
{
_this.AddAimRequest(Priority.High, "facing", Vec3(0.7, 0, 0.8));
_this.AddAimRequest(Priority.High, "facing", Vec3(0.7, 0, 0.8));
_this.Bot.HoldButton(BTN.STRAFE_R, 2);
_this.Bot.HoldButton(BTN.STRAFE_R, 2);
sleep(2);
sleep(2);
},
},
},
},
},
},
  };</syntaxhighlight>
  };</syntaxhighlight>


In the above example, the navigate function tells the bot that when it reaches a waypoint whose paththrough property is set to <nowiki>Navigation_PT:strafe_r_point,</nowiki> it should hold the strafe right button for two seconds. Note that the hold button time and the sleep time should be the same value.  
In the above example, the navigate function tells the bot that when it reaches a waypoint whose paththrough property is set to <nowiki>Navigation_PT:strafe_r_point,</nowiki> it should hold the strafe right button for two seconds.  


If you use HoldButton with buttons FORWARD, BACKWARD, STRAFE_L or STRAFE_R, you must also call AddAimRequest, otherwise bot would aim at enemies and direction would be unpredictable.
If you use HoldButton with buttons FORWARD, BACKWARD, STRAFE_L or STRAFE_R, you must also call AddAimRequest, otherwise bot would aim at enemies and direction would be unpredictable.
Line 40: Line 40:
Although this is the simplest paththrough type, it is also the most powerful in terms of capabilities. The navigate function receives the entire [[ScriptGoal|script goal]] object as _this parameter. This basically exposes the new goal scripting system to map scripters; providing means for the map scripter to define more complex bot behaviors or "mini goals" when a bot gets to a specific waypoint.  
Although this is the simplest paththrough type, it is also the most powerful in terms of capabilities. The navigate function receives the entire [[ScriptGoal|script goal]] object as _this parameter. This basically exposes the new goal scripting system to map scripters; providing means for the map scripter to define more complex bot behaviors or "mini goals" when a bot gets to a specific waypoint.  


'''If paththrough function does not call Goto or GotoAsync, bot follows the path to his current goal.''' If navigate function calls Goto, bot goes to that position and then stops there and waits. Bot will find new path to current goal after your navigate function exits.
'''If navigate function does not call Goto or GotoAsync, bot follows the path to his current goal.''' If navigate function calls Goto, bot goes to that position and then stops there and waits. Bot will find new path to current goal after your navigate function exits.


Paththrough navigation in Omni-Bot 0.71, 0.8 and 0.81 could be interrupted if high level goal changed. This caused bots to stuck or fall to death. This changed in 0.82 and paththrough navigation is interrupted only by death. It's recommended that every while loop checks for time out so that navigate function won't suspend bot forever.
Paththrough navigation in Omni-Bot 0.71, 0.8 and 0.81 could be interrupted if high level goal changed. This caused bots to stuck or fall to death. This changed in 0.82 and paththrough navigation is interrupted only by death. It's recommended that every while loop checks for time out so that navigate function won't suspend bot forever.
Line 56: Line 56:
grenadegrate =
grenadegrate =
{
{
EvalFunc = function() // if this function returns false, navigation will not run
EvalFunc = function() // if EvalFunc returns false, navigation and OnExit will not run
{
{
// do nothing if the grate is already destroyed
// do nothing if the grate is already destroyed
Line 68: Line 68:
&& Map.Grate_Bot_Count == 0 && _this.Bot.HasWeapon( WEAPON.AXIS_GRENADE ))
&& Map.Grate_Bot_Count == 0 && _this.Bot.HasWeapon( WEAPON.AXIS_GRENADE ))
{
{
Map.Grate_Bot_Count += 1;
_this.Grate_Bot = true; //_this is local, each bot has his own variable
Map.Grate_Bot_Count += 1; //Map is global and shared by all bots
 
// look at the grate, you can use command /bot mypos to get facing vector
// look at the grate, you can use command /bot mypos to get facing vector
_this.AddAimRequest(Priority.High, "facing", Vec3(-0.758, 0.614, -0.221));
_this.AddAimRequest(Priority.High, "facing", Vec3(-0.758, 0.614, -0.221));
Line 76: Line 78:
// throw grenade
// throw grenade
_this.Bot.HoldButton(BTN.ATTACK1, 0.5);
_this.Bot.HoldButton(BTN.ATTACK1, 0.5);
sleep(3);
sleep(1);
// switch to primary weapon
// switch to primary weapon
_this.ReleaseAimRequest();
_this.ReleaseAimRequest();
_this.ReleaseWeaponRequest();
_this.ReleaseWeaponRequest();
//wait until the grenade explodes
//wait until the grenade explodes
sleep(3);
sleep(4);
Map.Grate_Bot_Count -= 1;
}
}
else
else
Line 88: Line 89:
// wait and hope that somebody else will destroy the grate
// wait and hope that somebody else will destroy the grate
sleep(6);
sleep(6);
}
},
OnExit = function() // OnExit is called after navigate finished or the bot has been killed
{
//if this is the bot who threw a grenade, decrease count
if (_this.Grate_Bot)
{
_this.Grate_Bot = null;
Map.Grate_Bot_Count -= 1;
}
}
},
},

Revision as of 13:46, 12 June 2023

Paththrough Main Page Paththrough Navigation


Navigation

Navigation is the simplest paththrough type. It requires two things:

(1) Navigation table inside the Map table in the map script that could look like this:

 global Map =
 {
	Navigation =
	{
		strafe_r_point =
		{
			navigate = function(_this)
			{
				_this.AddAimRequest(Priority.High, "facing", Vec3(0.7, 0, 0.8));
				_this.Bot.HoldButton(BTN.STRAFE_R, 2);
				sleep(2);
			},
		},
	},
 };

In the above example, the navigate function tells the bot that when it reaches a waypoint whose paththrough property is set to Navigation_PT:strafe_r_point, it should hold the strafe right button for two seconds.

If you use HoldButton with buttons FORWARD, BACKWARD, STRAFE_L or STRAFE_R, you must also call AddAimRequest, otherwise bot would aim at enemies and direction would be unpredictable.

(2) The second thing that's necessary to set up paththrough navigation: go to the waypoint where you want the bots to strafe (or whatever) and add the property:

/bot waypoint_setproperty paththrough Navigation_PT:strafe_r_point

Using the Script Goal Object

Although this is the simplest paththrough type, it is also the most powerful in terms of capabilities. The navigate function receives the entire script goal object as _this parameter. This basically exposes the new goal scripting system to map scripters; providing means for the map scripter to define more complex bot behaviors or "mini goals" when a bot gets to a specific waypoint.

If navigate function does not call Goto or GotoAsync, bot follows the path to his current goal. If navigate function calls Goto, bot goes to that position and then stops there and waits. Bot will find new path to current goal after your navigate function exits.

Paththrough navigation in Omni-Bot 0.71, 0.8 and 0.81 could be interrupted if high level goal changed. This caused bots to stuck or fall to death. This changed in 0.82 and paththrough navigation is interrupted only by death. It's recommended that every while loop checks for time out so that navigate function won't suspend bot forever.

As an example, this following setup would instruct a bot that reaches the paththrough waypoint to go throw a grenade at some target:

global Map =
{
	Grate_Bot_Count = 0,
	Grate_Destroyed = false,

	Navigation =
	{
		grenadegrate =
		{
			EvalFunc = function()  // if EvalFunc returns false, navigation and OnExit will not run
			{
				// do nothing if the grate is already destroyed
				return !Map.Grate_Destroyed;
			},
			navigate = function(_this)
			{
				// you can use command /bot mypos or /bot spp to get coordinates
				if ( _this.Goto(Vec3(1608, 3830, 24)) == EVENT.PATH_SUCCESS
					// only one bot will throw grenade
					&& Map.Grate_Bot_Count == 0 && _this.Bot.HasWeapon( WEAPON.AXIS_GRENADE ))
				{
					_this.Grate_Bot = true; //_this is local, each bot has his own variable
					Map.Grate_Bot_Count += 1; //Map is global and shared by all bots

					// look at the grate, you can use command /bot mypos to get facing vector
					_this.AddAimRequest(Priority.High, "facing", Vec3(-0.758, 0.614, -0.221));
					// switch to grenade (this navigation is only for Axis team !)
					_this.AddWeaponRequest(Priority.High, WEAPON.AXIS_GRENADE );
					_this.BlockForWeaponChange( WEAPON.AXIS_GRENADE );
					// throw grenade
					_this.Bot.HoldButton(BTN.ATTACK1, 0.5);
					sleep(1);
					// switch to primary weapon
					_this.ReleaseAimRequest();
					_this.ReleaseWeaponRequest();
					//wait until the grenade explodes
					sleep(4);
				}
				else
				{
					// wait and hope that somebody else will destroy the grate
					sleep(6);
				}
			},
			OnExit = function() // OnExit is called after navigate finished or the bot has been killed
			{
				//if this is the bot who threw a grenade, decrease count
				if (_this.Grate_Bot)
				{
					_this.Grate_Bot = null;
					Map.Grate_Bot_Count -= 1;
				}
			},
		},
	},
	
	Grate_Trigger = function(trigger)
	{
		Map.Grate_Destroyed = true;
	},
};

In this case the waypoint property would be set as:

/bot waypoint_setproperty paththrough Navigation_PT:grenadegrate

While this application of the navigation paththrough goal offers complete flexibility, great care should be taken when scripting such things. Any implementation should be thoroughly tested.