BotLib: Add support for the AIM linkflag, to control when a bot is forced
to look ahead to the current waypoint node.
This commit is contained in:
parent
4bb854f16b
commit
6a48c18171
10 changed files with 83 additions and 38 deletions
|
@ -273,7 +273,7 @@ bot::RunAI(void)
|
|||
if (m_iCurNode == BOTROUTE_DESTINATION)
|
||||
aimpos = m_vecLastNode;
|
||||
else {
|
||||
if (m_iCurNode > 0)
|
||||
if (m_iCurNode > 0 && !(m_pRoute[m_iCurNode].m_iFlags & LF_AIM))
|
||||
aimpos = m_pRoute[m_iCurNode - 1].m_vecDest;
|
||||
else
|
||||
aimpos = m_pRoute[m_iCurNode].m_vecDest;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
enum
|
||||
{
|
||||
BOTINFO_NONE,
|
||||
BOTINFO_HEALTH,
|
||||
BOTINFO_ARMOR,
|
||||
BOTINFO_SPAWNPOINT,
|
||||
|
|
|
@ -21,16 +21,16 @@
|
|||
* The route must be followed in reverse order (ie: the first node that must be reached
|
||||
* is at index numnodes-1). If no route is available then the callback will be called with no nodes.
|
||||
*/
|
||||
|
||||
int Route_RoundDistance( float flDist )
|
||||
int
|
||||
Route_RoundDistance(float flDist)
|
||||
{
|
||||
float r = fabs( flDist ) % 2;
|
||||
if ( r == 0 ) {
|
||||
float r = fabs(flDist) % 2;
|
||||
if (r == 0) {
|
||||
return flDist;
|
||||
}
|
||||
|
||||
if ( flDist < 0 ) {
|
||||
return -( fabs( flDist ) - r );
|
||||
if (flDist < 0) {
|
||||
return -(fabs(flDist) - r);
|
||||
} else {
|
||||
return flDist + 2 - r;
|
||||
}
|
||||
|
@ -42,10 +42,11 @@ int Route_RoundDistance( float flDist )
|
|||
Spawn_SelectRandom
|
||||
================
|
||||
*/
|
||||
entity Route_SelectRandom ( string sEntname )
|
||||
entity
|
||||
Route_SelectRandom(string sEntname)
|
||||
{
|
||||
static entity eLastSpot;
|
||||
eLastSpot = find( eLastSpot, classname, sEntname );
|
||||
eLastSpot = find(eLastSpot, classname, sEntname);
|
||||
return eLastSpot;
|
||||
}
|
||||
|
||||
|
@ -54,14 +55,16 @@ entity Route_SelectRandom ( string sEntname )
|
|||
Route_SelectRandomSpot
|
||||
================
|
||||
*/
|
||||
entity Route_SelectRandomSpot(void)
|
||||
entity
|
||||
Route_SelectRandomSpot(void)
|
||||
{
|
||||
static entity eLastSpot;
|
||||
eLastSpot = findfloat( eLastSpot, ::botinfo, BOTINFO_SPAWNPOINT );
|
||||
eLastSpot = findfloat(eLastSpot, ::botinfo, BOTINFO_SPAWNPOINT);
|
||||
return eLastSpot;
|
||||
}
|
||||
|
||||
void Bot_RouteCB( entity ent, vector dest, int numnodes, nodeslist_t *nodelist )
|
||||
void
|
||||
Bot_RouteCB(entity ent, vector dest, int numnodes, nodeslist_t *nodelist)
|
||||
{
|
||||
bot b = (bot)ent;
|
||||
b.m_iNodes = numnodes;
|
||||
|
@ -69,31 +72,32 @@ void Bot_RouteCB( entity ent, vector dest, int numnodes, nodeslist_t *nodelist )
|
|||
b.m_pRoute = nodelist;
|
||||
b.m_vecLastNode = dest;
|
||||
|
||||
//dprint( "Bot: Route calculated.\n" );
|
||||
//dprint( sprintf( "Bot: # of nodes: %i\n", bot.m_iNodes ) );
|
||||
//dprint( sprintf( "Bot: # current node: %i\n", bot.m_iCurNode ) );
|
||||
//dprint( sprintf( "Bot: # endpos: %v\n", dest ) );
|
||||
//dprint("Bot: Route calculated.\n");
|
||||
//dprint(sprintf("Bot: # of nodes: %i\n", bot.m_iNodes) );
|
||||
//dprint(sprintf("Bot: # current node: %i\n", bot.m_iCurNode) );
|
||||
//dprint(sprintf("Bot: # endpos: %v\n", dest));
|
||||
}
|
||||
|
||||
vector Route_SelectDestination( bot target )
|
||||
vector
|
||||
Route_SelectDestination(bot target)
|
||||
{
|
||||
entity dest = world;
|
||||
|
||||
// Need health!
|
||||
if ( target.health < 50 ) {
|
||||
if (target.health < 50) {
|
||||
entity temp;
|
||||
int bestrange = COST_INFINITE;
|
||||
int range;
|
||||
for ( temp = world; ( temp = findfloat( temp, ::botinfo, BOTINFO_HEALTH ) ); ) {
|
||||
range = vlen( temp.origin - target.origin );
|
||||
if ( ( range < bestrange ) && ( temp.solid == SOLID_TRIGGER ) ) {
|
||||
for (temp = world; (temp = findfloat(temp, ::botinfo, BOTINFO_HEALTH));) {
|
||||
range = vlen(temp.origin - target.origin);
|
||||
if ((range < bestrange) && (temp.solid == SOLID_TRIGGER)) {
|
||||
bestrange = range;
|
||||
dest = temp;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dest ) {
|
||||
//dprint( "Route: Going for health!" );
|
||||
if (dest) {
|
||||
//dprint("Route: Going for health!");
|
||||
return dest.origin + '0 0 32';
|
||||
}
|
||||
}
|
||||
|
@ -102,14 +106,3 @@ vector Route_SelectDestination( bot target )
|
|||
target.m_eDestination = dest;
|
||||
return dest.origin;
|
||||
}
|
||||
|
||||
int Route_CanCrouch(bot target, vector endpos)
|
||||
{
|
||||
traceline(target.origin + [0,0,-18], endpos, FALSE, target);
|
||||
|
||||
if ( trace_fraction != 1.0f ) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,5 +16,4 @@
|
|||
|
||||
int Route_RoundDistance( float flDist );
|
||||
vector Route_SelectDestination( bot target );
|
||||
int Route_CanCrouch(bot target, vector endpos);
|
||||
void Bot_RouteCB( entity ent, vector dest, int numnodes, nodeslist_t *nodelist );
|
||||
|
|
|
@ -265,6 +265,31 @@ Way_FlagWalk(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Way_FlagAim(void)
|
||||
{
|
||||
if (g_waylink_status == 0) {
|
||||
g_way1 = Way_FindClosestNode(self.origin);
|
||||
g_waylink_status = 1;
|
||||
env_message_single(self, "^2Selected first waypoint!\n");
|
||||
} else if (g_waylink_status == 1) {
|
||||
g_way2 = Way_FindClosestNode(self.origin);
|
||||
g_waylink_status = 0;
|
||||
|
||||
if (g_way1 != g_way2) {
|
||||
for (int b = 0i; b < g_pWaypoints[g_way1].m_numNeighbours; b++) {
|
||||
if (g_pWaypoints[g_way1].m_pNeighbour[b].m_iNode == g_way2) {
|
||||
g_pWaypoints[g_way1].m_pNeighbour[b].m_iFlags |= LF_AIM;
|
||||
env_message_single(self, "^2Walk-linked the two points!\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
env_message_single(self, "^1Failed to link, the two points are the same!\n");
|
||||
}
|
||||
g_way1 = g_way2 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Way_HelperSpawns()
|
||||
{
|
||||
|
@ -461,6 +486,9 @@ Way_Cmd(void)
|
|||
case "linkwalk":
|
||||
Way_FlagWalk();
|
||||
break;
|
||||
case "linkaim":
|
||||
Way_FlagAim();
|
||||
break;
|
||||
case "move":
|
||||
vector p;
|
||||
int n = Way_FindClosestNode(self.origin);
|
||||
|
@ -551,6 +579,12 @@ Way_DrawDebugInfo(void)
|
|||
R_EndPolygon();
|
||||
}
|
||||
|
||||
if (fl & LF_AIM) {
|
||||
R_PolygonVertex(org + [0,0,4], [0,1], [0.25,0.25,1], 1);
|
||||
R_PolygonVertex(w2->m_vecOrigin + [0,0,4], [1,1], [0,0,0], 1);
|
||||
R_EndPolygon();
|
||||
}
|
||||
|
||||
R_PolygonVertex(org, [0,1], [1,0,1], 1);
|
||||
R_PolygonVertex(w2->m_vecOrigin, [1,1], [0,1,0], 1);
|
||||
R_EndPolygon();
|
||||
|
|
|
@ -21,5 +21,6 @@
|
|||
#define LF_CROUCH 0x00000004i
|
||||
#define LF_TELEPORT 0x00000008i
|
||||
#define LF_WALK 0x00000010i
|
||||
#define LF_AIM 0x00000020i
|
||||
#define LF_USER 0x7fffff00i
|
||||
#define LF_DESTINATION 0x80000000i
|
||||
|
|
|
@ -279,6 +279,9 @@ WAY_FLAGS(int n)
|
|||
case 3:
|
||||
localcmd("sv way linkwalk\n");
|
||||
break;
|
||||
case 4:
|
||||
localcmd("sv way linkaim\n");
|
||||
break;
|
||||
case 9:
|
||||
Textmenu_Call("WAY_MENU");
|
||||
break;
|
||||
|
|
|
@ -26,6 +26,7 @@ void info_player_start(void)
|
|||
if (autocvar_fcs_swapteams == TRUE) {
|
||||
self.classname = "info_player_deathmatch";
|
||||
}
|
||||
self.botinfo = BOTINFO_SPAWNPOINT;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -40,6 +41,7 @@ void info_player_deathmatch(void)
|
|||
if (autocvar_fcs_swapteams == TRUE) {
|
||||
self.classname = "info_player_start";
|
||||
}
|
||||
self.botinfo = BOTINFO_SPAWNPOINT;
|
||||
}
|
||||
|
||||
/* Counter-Strike: Source compat */
|
||||
|
|
|
@ -174,11 +174,16 @@ times the amount of players in a given game.
|
|||
*/
|
||||
void PlayerPreThink(void)
|
||||
{
|
||||
if (self.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BOT_INCLUDED
|
||||
if (clienttype(self) == CLIENTTYPE_BOT) {
|
||||
((bot)self).PreFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
g_grMode.PlayerPreFrame((base_player)self);
|
||||
}
|
||||
|
||||
|
@ -193,6 +198,10 @@ times the amount of players in a given game.
|
|||
*/
|
||||
void PlayerPostThink(void)
|
||||
{
|
||||
if (self.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BOT_INCLUDED
|
||||
if (clienttype(self) == CLIENTTYPE_BOT) {
|
||||
((bot)self).PostFrame();
|
||||
|
@ -247,9 +256,12 @@ with the input_X globals being set to the appropriate data.
|
|||
*/
|
||||
void SV_RunClientCommand(void)
|
||||
{
|
||||
if (self.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BOT_INCLUDED
|
||||
/* wait a few seconds, as we may not have been spawned yet */
|
||||
if (time > 5.0)
|
||||
if (clienttype(self) == CLIENTTYPE_BOT) {
|
||||
((bot)self).RunAI();
|
||||
}
|
||||
|
|
4
tfc.fmf
4
tfc.fmf
|
@ -3,6 +3,7 @@ GAME tfc
|
|||
NAME "Team Fortress"
|
||||
BASEGAME platform
|
||||
BASEGAME logos
|
||||
BASEGAME valve
|
||||
BASEGAME tfc
|
||||
|
||||
// custom game menu variables
|
||||
|
@ -24,9 +25,8 @@ BASEGAME tfc
|
|||
-set gameinfo_url_dl "http://www.frag-net.com/mods/tfc.fmf"
|
||||
-set gameinfo_menutrack ""
|
||||
|
||||
DOWNLOADSURL http://www.frag-net.com/dl/tfc_packages
|
||||
DOWNLOADSURL http://www.frag-net.com/dl/valve_packages
|
||||
UPDATEURL http://www.frag-net.com/mods/tfc.fmf
|
||||
INSTALL "tfc_essential;valve_essential;free_essential"
|
||||
|
||||
// you don't really want to change these
|
||||
RTCBROKER master.frag-net.com:27950
|
||||
|
|
Loading…
Reference in a new issue