mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-04-09 11:41:32 +00:00
jabot: remove botroam functionality
Trust A* heuristic to search path
This commit is contained in:
parent
8aea22e6c6
commit
0d8cba6711
13 changed files with 12 additions and 256 deletions
|
@ -57,8 +57,6 @@ original clients (Vanilla Quake II) commands are still in place.
|
|||
|
||||
* **sv savenodes**: Save nodes file
|
||||
|
||||
* **sv addbotroam**: Drop a bot roam node
|
||||
|
||||
* **sv addbot <team> <name> <skin>**: Spawn a bot (consult ACEbot readme,
|
||||
it's just the same thing)
|
||||
|
||||
|
|
|
@ -437,19 +437,6 @@ AI_PathMap(void)
|
|||
}
|
||||
|
||||
|
||||
//==========================================
|
||||
// AI_ClientPathMap
|
||||
// Clients try to create new nodes while walking the map
|
||||
//==========================================
|
||||
void AITools_AddBotRoamNode(void)
|
||||
{
|
||||
if( nav.loaded )
|
||||
return;
|
||||
|
||||
AI_AddNode( player.ent->s.origin, NODEFLAGS_BOTROAM );
|
||||
}
|
||||
|
||||
|
||||
//==========================================
|
||||
// AI_ClientPathMap
|
||||
// Clients try to create new nodes while walking the map
|
||||
|
@ -478,9 +465,6 @@ void AITools_EraseNodes( void )
|
|||
nav.num_ents = 0;
|
||||
memset( nav.ents, 0, sizeof(nav_ents_t) * MAX_EDICTS );
|
||||
|
||||
nav.num_broams = 0;
|
||||
memset( nav.broams, 0, sizeof(nav_broam_t) * MAX_BOT_ROAMS );
|
||||
|
||||
nav.num_items = 0;
|
||||
memset( nav.items, 0, sizeof(nav_item_t) * MAX_EDICTS );
|
||||
|
||||
|
@ -498,9 +482,6 @@ void AITools_InitEditnodes( void )
|
|||
nav.num_ents = 0;
|
||||
memset( nav.ents, 0, sizeof(nav_ents_t) * MAX_EDICTS );
|
||||
|
||||
nav.num_broams = 0;
|
||||
memset( nav.broams, 0, sizeof(nav_broam_t) * MAX_BOT_ROAMS );
|
||||
|
||||
nav.num_items = 0;
|
||||
memset( nav.items, 0, sizeof(nav_item_t) * MAX_EDICTS );
|
||||
nav.loaded = false;
|
||||
|
|
|
@ -278,29 +278,3 @@ float AI_ItemWeight(edict_t *self, edict_t *it)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================
|
||||
//QUAKED item_botroam
|
||||
//==========================================
|
||||
void SP_item_botroam (edict_t *ent)
|
||||
{
|
||||
float weight;
|
||||
|
||||
//try to convert Q3 weights (doh)
|
||||
if(st.weight)
|
||||
{
|
||||
weight = st.weight;
|
||||
|
||||
// item_botroam weights should go between 0 and 100.
|
||||
// to convert odd weights to this format:
|
||||
if (weight >= 1000)
|
||||
weight = 100;
|
||||
else if (weight >= 100) //include 100, cause some q3 mappers use 100, 200, 300... etc
|
||||
weight *= 0.1;
|
||||
}
|
||||
else
|
||||
weight = 30; //default value
|
||||
|
||||
ent->count = (int)weight;
|
||||
}
|
||||
|
|
|
@ -155,8 +155,6 @@ int AI_GravityBoxToLink(int n1, int n2);
|
|||
//----------------------------------------------------------
|
||||
qboolean AI_CanPick_Ammo (edict_t *ent, gitem_t *item);
|
||||
qboolean AI_CanUseArmor (gitem_t *item, edict_t *other);
|
||||
void AI_BotRoamFinishTimeouts(edict_t *self);
|
||||
|
||||
|
||||
//bot_classes
|
||||
//----------------------------------------------------------
|
||||
|
|
|
@ -150,71 +150,9 @@ void AI_ResetNavigation(edict_t *ent)
|
|||
ent->ai->next_node = INVALID;
|
||||
|
||||
VectorSet( ent->ai->move_vector, 0, 0, 0 );
|
||||
|
||||
//reset bot_roams timeouts
|
||||
for( i=0; i<nav.num_broams; i++)
|
||||
ent->ai->status.broam_timeouts[i] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================
|
||||
// AI_BotRoamForLRGoal
|
||||
//
|
||||
// Try assigning a bot roam node as LR Goal
|
||||
//==========================================
|
||||
qboolean AI_BotRoamForLRGoal(edict_t *self, int current_node)
|
||||
{
|
||||
int i;
|
||||
float cost;
|
||||
float weight, best_weight = 0.0;
|
||||
int goal_node = INVALID;
|
||||
// int best_broam = INVALID;
|
||||
float dist;
|
||||
|
||||
if (!nav.num_broams)
|
||||
return false;
|
||||
|
||||
for( i=0; i<nav.num_broams; i++)
|
||||
{
|
||||
if( self->ai->status.broam_timeouts[i] > level.time)
|
||||
continue;
|
||||
|
||||
//limit cost finding by distance
|
||||
dist = AI_Distance( self->s.origin, nodes[nav.broams[i].node].origin );
|
||||
if( dist > 10000 )
|
||||
continue;
|
||||
|
||||
//find cost
|
||||
cost = AI_FindCost(current_node, nav.broams[i].node, self->ai->pers.moveTypesMask);
|
||||
if(cost == INVALID || cost < 3) // ignore invalid and very short hops
|
||||
continue;
|
||||
|
||||
cost *= random(); // Allow random variations for broams
|
||||
weight = nav.broams[i].weight / cost; // Check against cost of getting there
|
||||
|
||||
if(weight > best_weight)
|
||||
{
|
||||
best_weight = weight;
|
||||
goal_node = nav.broams[i].node;
|
||||
// best_broam = i;
|
||||
}
|
||||
}
|
||||
|
||||
if(best_weight == 0.0 || goal_node == INVALID)
|
||||
return false;
|
||||
|
||||
//set up the goal
|
||||
self->ai->state = BOT_STATE_MOVE;
|
||||
self->ai->tries = 0; // Reset the count of how many times we tried this goal
|
||||
|
||||
// if(AIDevel.debugChased && bot_showlrgoal->value)
|
||||
// gi.cprintf(AIDevel.chaseguy, PRINT_HIGH, "%s: selected a bot roam of weight %f at node %d for LR goal.\n",self->ai->pers.netname, nav.broams[best_broam].weight, goal_node);
|
||||
|
||||
AI_SetGoal(self,goal_node);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================
|
||||
// AI_PickLongRangeGoal
|
||||
//
|
||||
|
@ -332,15 +270,11 @@ void AI_PickLongRangeGoal(edict_t *self)
|
|||
// If do not find a goal, go wandering....
|
||||
if(best_weight == 0.0 || goal_node == INVALID)
|
||||
{
|
||||
//BOT_ROAMS
|
||||
if (!AI_BotRoamForLRGoal(self, current_node))
|
||||
{
|
||||
self->ai->goal_node = INVALID;
|
||||
self->ai->state = BOT_STATE_WANDER;
|
||||
self->ai->wander_timeout = level.time + 1.0;
|
||||
// if(AIDevel.debugChased && bot_showlrgoal->value)
|
||||
// gi.cprintf(AIDevel.chaseguy, PRINT_HIGH, "%s: did not find a LR goal, wandering.\n",self->ai->pers.netname);
|
||||
}
|
||||
self->ai->goal_node = INVALID;
|
||||
self->ai->state = BOT_STATE_WANDER;
|
||||
self->ai->wander_timeout = level.time + 1.0;
|
||||
// if(AIDevel.debugChased && bot_showlrgoal->value)
|
||||
// gi.cprintf(AIDevel.chaseguy, PRINT_HIGH, "%s: did not find a LR goal, wandering.\n",self->ai->pers.netname);
|
||||
return; // no path?
|
||||
}
|
||||
|
||||
|
|
|
@ -185,22 +185,6 @@ qboolean AI_FollowPath( edict_t *self )
|
|||
//if(AIDevel.debugChased && bot_showlrgoal->value)
|
||||
// gi.cprintf(AIDevel.chaseguy, PRINT_HIGH, "%s: GOAL REACHED!\n", self->ai->pers.netname);
|
||||
|
||||
//if botroam, setup a timeout for it
|
||||
if( nodes[self->ai->goal_node].flags & NODEFLAGS_BOTROAM )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<nav.num_broams; i++) { //find the broam
|
||||
if( nav.broams[i].node != self->ai->goal_node )
|
||||
continue;
|
||||
|
||||
//if(AIDevel.debugChased && bot_showlrgoal->integer)
|
||||
// gi.cprintf(AIDevel.chaseguy, PRINT_HIGH, "%s: BotRoam Time Out set up for node %i\n", self->ai->pers.netname, nav.broams[i].node);
|
||||
//Com_Printf( "%s: BotRoam Time Out set up for node %i\n", self->ai->pers.netname, nav.broams[i].node);
|
||||
self->ai->status.broam_timeouts[i] = level.time + 15.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Pick a new goal
|
||||
AI_PickLongRangeGoal(self);
|
||||
}
|
||||
|
|
|
@ -486,41 +486,6 @@ int AI_AddNode_Teleporter( edict_t *ent )
|
|||
}
|
||||
|
||||
|
||||
//==========================================
|
||||
// AI_AddNode_BotRoam
|
||||
// add nodes from bot roam entities
|
||||
//==========================================
|
||||
int AI_AddNode_BotRoam( edict_t *ent )
|
||||
{
|
||||
if( nav.num_nodes + 1 > MAX_NODES )
|
||||
return INVALID;
|
||||
|
||||
nodes[nav.num_nodes].flags = (NODEFLAGS_BOTROAM);//bot roams are not NODEFLAGS_NOWORLD
|
||||
|
||||
// Set location
|
||||
VectorCopy( ent->s.origin, nodes[nav.num_nodes].origin );
|
||||
if ( ent->spawnflags & 1 ) // floating items
|
||||
nodes[nav.num_nodes].flags |= NODEFLAGS_FLOAT;
|
||||
else
|
||||
if( !AI_DropNodeOriginToFloor( nodes[nav.num_nodes].origin, NULL ) )
|
||||
return INVALID;//spawned inside solid
|
||||
|
||||
nodes[nav.num_nodes].flags |= AI_FlagsForNode( nodes[nav.num_nodes].origin, NULL );
|
||||
|
||||
//count into bot_roams table
|
||||
nav.broams[nav.num_broams].node = nav.num_nodes;
|
||||
|
||||
if( ent->count )
|
||||
nav.broams[nav.num_broams].weight = ent->count * 0.01;//count is a int with a value in between 0 and 100
|
||||
else
|
||||
nav.broams[nav.num_broams].weight = 0.3;
|
||||
|
||||
nav.num_broams++;
|
||||
nav.num_nodes++;
|
||||
return nav.num_nodes-1; // return the node added
|
||||
}
|
||||
|
||||
|
||||
//==========================================
|
||||
// AI_AddNode_ItemNode
|
||||
// Used to add nodes from items
|
||||
|
@ -587,62 +552,6 @@ void AI_CreateNodesForEntities ( void )
|
|||
}
|
||||
}
|
||||
|
||||
// bot roams
|
||||
nav.num_broams = 0;
|
||||
memset( nav.broams, 0, sizeof(nav_broam_t) * MAX_BOT_ROAMS );
|
||||
|
||||
//visit world nodes first, and put in list what we find in there
|
||||
for( node=0; node < nav.num_nodes; node++ )
|
||||
{
|
||||
if( nodes[node].flags & NODEFLAGS_BOTROAM && nav.num_broams < MAX_BOT_ROAMS)
|
||||
{
|
||||
nav.broams[nav.num_broams].node = node;
|
||||
nav.broams[nav.num_broams].weight = 0.3;
|
||||
nav.num_broams++;
|
||||
}
|
||||
}
|
||||
|
||||
//now add bot roams from entities
|
||||
// for(ent = game.edicts; ent < &game.edicts[game.numentities]; ent++)
|
||||
for( ent = g_edicts; ent < &g_edicts[game.maxentities]; ent++ )
|
||||
{
|
||||
if( !ent->classname )
|
||||
continue;
|
||||
|
||||
if( !strcmp( ent->classname,"item_botroam" ) )
|
||||
{
|
||||
//if we have a available node close enough to the item, use it instead of dropping a new node
|
||||
node = AI_FindClosestReachableNode( ent->s.origin, NULL, 48, NODE_ALL );
|
||||
if( node != -1 &&
|
||||
!(nodes[node].flags & NODEFLAGS_SERVERLINK) &&
|
||||
!(nodes[node].flags & NODEFLAGS_LADDER) )
|
||||
{
|
||||
float heightdiff = 0;
|
||||
heightdiff = ent->s.origin[2] - nodes[node].origin[2];
|
||||
if( heightdiff < 0 ) heightdiff = -heightdiff;
|
||||
|
||||
if( heightdiff < AI_STEPSIZE && nav.num_broams < MAX_BOT_ROAMS ) //near enough
|
||||
{
|
||||
nodes[node].flags |= NODEFLAGS_BOTROAM;
|
||||
//add node to botroam list
|
||||
if( ent->count )
|
||||
nav.broams[nav.num_broams].weight = ent->count * 0.01;//count is a int with a value in between 0 and 100
|
||||
else
|
||||
nav.broams[nav.num_broams].weight = 0.3; //jalfixme: add cmd to weight (dropped by console cmd, self is player)
|
||||
|
||||
nav.broams[nav.num_broams].node = node;
|
||||
nav.num_broams++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//drop a new node
|
||||
if( nav.num_broams < MAX_BOT_ROAMS ){
|
||||
AI_AddNode_BotRoam( ent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// game items (I want all them on top of the nodes array)
|
||||
nav.num_items = 0;
|
||||
memset( nav.items, 0, sizeof(nav_item_t) * MAX_EDICTS );
|
||||
|
|
|
@ -54,13 +54,6 @@ typedef struct nav_ents_s
|
|||
|
||||
} nav_ents_t;
|
||||
|
||||
typedef struct nav_botroam_s
|
||||
{
|
||||
int node;
|
||||
float weight;
|
||||
|
||||
} nav_broam_t;
|
||||
|
||||
typedef struct nav_path_s
|
||||
{
|
||||
int next; //next node
|
||||
|
@ -82,10 +75,6 @@ typedef struct
|
|||
|
||||
int num_ents;
|
||||
nav_ents_t ents[MAX_EDICTS]; //plats, etc
|
||||
|
||||
int num_broams;
|
||||
nav_broam_t broams[MAX_BOT_ROAMS]; //list of nodes wich are botroams
|
||||
|
||||
} ai_navigation_t;
|
||||
|
||||
extern ai_navigation_t nav;
|
||||
|
|
|
@ -53,16 +53,14 @@
|
|||
#define NODEFLAGS_LADDER 0x00000002
|
||||
#define NODEFLAGS_SERVERLINK 0x00000004 //plats, doors, teles. Only server can link 2 nodes with this flag
|
||||
#define NODEFLAGS_FLOAT 0x00000008 //don't drop node to floor ( air & water )
|
||||
//#define NODEFLAGS_ITEM 0x00000010 //jal remove me
|
||||
#define NODEFLAGS_BOTROAM 0x00000020
|
||||
#define NODEFLAGS_JUMPPAD 0x00000040 // jalfixme: add NODEFLAGS_REACHATTOUCH
|
||||
#define NODEFLAGS_JUMPPAD_LAND 0x00000080
|
||||
#define NODEFLAGS_PLATFORM 0x00000100
|
||||
#define NODEFLAGS_TELEPORTER_IN 0x00000200 // jalfixme: add NODEFLAGS_REACHATTOUCH
|
||||
#define NODEFLAGS_TELEPORTER_OUT 0x00000400
|
||||
#define NODEFLAGS_REACHATTOUCH 0x00000800
|
||||
#define NODEFLAGS_JUMPPAD 0x00000010 // jalfixme: add NODEFLAGS_REACHATTOUCH
|
||||
#define NODEFLAGS_JUMPPAD_LAND 0x00000020
|
||||
#define NODEFLAGS_PLATFORM 0x00000040
|
||||
#define NODEFLAGS_TELEPORTER_IN 0x00000080 // jalfixme: add NODEFLAGS_REACHATTOUCH
|
||||
#define NODEFLAGS_TELEPORTER_OUT 0x00000100
|
||||
#define NODEFLAGS_REACHATTOUCH 0x00000200
|
||||
|
||||
#define NODE_ALL 0x00001000
|
||||
#define NODE_ALL 0x00000400
|
||||
|
||||
// links types (movetypes required to run node links)
|
||||
#define LINK_MOVE 0x00000001
|
||||
|
|
|
@ -370,10 +370,6 @@ ServerCommand(void)
|
|||
{
|
||||
AITools_SaveNodes();
|
||||
}
|
||||
else if (!Q_stricmp (cmd, "addbotroam"))
|
||||
{
|
||||
AITools_AddBotRoamNode();
|
||||
}
|
||||
else if(Q_stricmp(cmd, "removebot") == 0)
|
||||
{
|
||||
BOT_RemoveBot(gi.argv(2));
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
// declaration of botedict for the game
|
||||
//----------------------------------------------------------
|
||||
#define MAX_BOT_ROAMS 128
|
||||
/* jalToDo: needs dynamic alloc (big terrain maps) */
|
||||
#define MAX_NODES 2048
|
||||
|
||||
|
@ -49,7 +48,6 @@ typedef struct
|
|||
|
||||
float inventoryWeights[MAX_ITEMS];
|
||||
float playersWeights[MAX_EDICTS];
|
||||
float broam_timeouts[MAX_BOT_ROAMS]; //revisit bot roams
|
||||
} ai_status_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -120,7 +118,6 @@ void AITools_Frame(void);
|
|||
void AITools_DropNodes(edict_t *ent);
|
||||
|
||||
/* ai_dropnodes.c */
|
||||
void AITools_AddBotRoamNode(void);
|
||||
void AITools_SaveNodes(void);
|
||||
void AITools_InitEditnodes(void);
|
||||
void AITools_InitMakenodes(void);
|
||||
|
|
|
@ -66,7 +66,6 @@ extern void SP_info_player_deathmatch(edict_t * self);
|
|||
extern void SP_info_player_intermission ( edict_t * ent ) ;
|
||||
extern void SP_info_player_start(edict_t * self);
|
||||
extern void SP_info_teleport_destination(edict_t * self);
|
||||
extern void SP_item_botroam(edict_t * self);
|
||||
extern void SP_item_foodcube(edict_t * self);
|
||||
extern void SP_item_health(edict_t * self);
|
||||
extern void SP_item_health_large(edict_t * self);
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
{"info_player_team1", SP_info_player_team1},
|
||||
{"info_player_team2", SP_info_player_team2},
|
||||
{"info_teleport_destination", SP_info_teleport_destination},
|
||||
{"item_botroam", SP_item_botroam},
|
||||
{"item_health", SP_item_health},
|
||||
{"item_health_large", SP_item_health_large},
|
||||
{"item_health_mega", SP_item_health_mega},
|
||||
|
|
Loading…
Reference in a new issue