BotLib/Nodes: Add support for variable link radius. If you need to fill

your old waypoint data... try 'sv way radiushack'. Sorry!
This commit is contained in:
Marco Cawthorne 2021-01-02 11:17:14 +01:00
parent 829757d415
commit 58be8e2170
6 changed files with 154 additions and 89 deletions

View file

@ -129,6 +129,7 @@ bot::CheckRoute(void)
{
float flDist;
vector evenpos;
float rad;
if (!m_iNodes) {
return;
@ -137,14 +138,16 @@ bot::CheckRoute(void)
/* level out position/node stuff */
if (m_iCurNode < 0) {
evenpos = m_vecLastNode - origin;
rad = 64;
} else {
evenpos = m_pRoute[m_iCurNode].m_vecDest - origin;
rad = m_pRoute[m_iCurNode].m_flRadius;
}
evenpos[2] *= 0.25f;
//evenpos[2] *= 0.25f;
flDist = floor(vlen(evenpos));
if (flDist < 32) {
if (flDist < rad) {
dprint(sprintf("^2CBaseMonster::^3CheckRoute^7: " \
"%s reached node\n", this.targetname));
m_iCurNode--;
@ -318,7 +321,7 @@ bot::RunAI(void)
/* we are far away, inch closer */
aimpos = m_eTarget.origin;
} else {
if (m_iCurNode == BOTROUTE_DESTINATION)
if (m_iCurNode <= BOTROUTE_DESTINATION)
aimpos = m_vecLastNode;
else
aimpos = m_pRoute[m_iCurNode].m_vecDest;

View file

@ -102,12 +102,14 @@ static void
Way_LinkWaypoints(waypoint_t *wp, waypoint_t *w2)
{
int w2n = w2 - g_pWaypoints;
/* don't bother if we're already linked */
for (int i = 0i; i < wp->iNeighbours; i++) {
if (wp->neighbour[i].node == w2n) {
return;
}
}
int idx = wp->iNeighbours++;
wp->neighbour = memrealloc(wp->neighbour, sizeof(*wp->neighbour), idx, wp->iNeighbours);
local struct wpneighbour_s *n = wp->neighbour+idx;
@ -265,7 +267,8 @@ Way_Waypoint_LinkJump(void)
if (way1 != way2) {
for (int b = 0i; b < g_pWaypoints[way1].iNeighbours; b++) {
if (g_pWaypoints[way1].neighbour[b].node == way2) {
g_pWaypoints[way1].neighbour[b].iFlags = LF_JUMP;
g_pWaypoints[way1].neighbour[b].iFlags |= LF_JUMP;
env_message_single(self, "Jump-linked the two points!\n");
}
}
} else {
@ -291,7 +294,8 @@ Way_Waypoint_LinkCrouch(void)
if (way1 != way2) {
for (int b = 0i; b < g_pWaypoints[way1].iNeighbours; b++) {
if (g_pWaypoints[way1].neighbour[b].node == way2) {
g_pWaypoints[way1].neighbour[b].iFlags = LF_CROUCH;
g_pWaypoints[way1].neighbour[b].iFlags |= LF_CROUCH;
env_message_single(self, "Crouch-linked the two points!\n");
}
}
} else {
@ -309,7 +313,7 @@ Way_Waypoint_LinkWalk(void)
if (waylink_status == 0) {
way1 = Way_FindClosestWaypoint(self.origin);
waylink_status = 1;
centerprint(self, "Selected first waypoint!\n");
env_message_single(self, "Selected first waypoint!\n");
} else if (waylink_status == 1) {
way2 = Way_FindClosestWaypoint(self.origin);
waylink_status = 0;
@ -317,11 +321,12 @@ Way_Waypoint_LinkWalk(void)
if (way1 != way2) {
for (int b = 0i; b < g_pWaypoints[way1].iNeighbours; b++) {
if (g_pWaypoints[way1].neighbour[b].node == way2) {
g_pWaypoints[way1].neighbour[b].iFlags = LF_WALK;
g_pWaypoints[way1].neighbour[b].iFlags |= LF_WALK;
env_message_single(self, "Walk-linked the two points!\n");
}
}
} else {
centerprint(self, "Failed to link, the two points are the same!\n");
env_message_single(self, "Failed to link, the two points are the same!\n");
}
}
}
@ -377,9 +382,11 @@ Way_DrawDebugInfo(void)
for (int i = 0i; i < g_iWaypoints; i++) {
waypoint_t *w = g_pWaypoints + i;
vector org = w->vecOrigin;
for (float j = 0; j < (2 * M_PI); j += (2 * M_PI) / 4) {
R_PolygonVertex(org + [sin(j), cos(j)]*w->flRadius, '1 1', '0 0.25 0', 1);
for(int j = 0; j < 16; j++) {
float theta = 2.0f * M_PI * j / 16;
R_PolygonVertex(org + [sin(theta), cos(theta)]*w->flRadius, '1 1', '0 0.25 0', 1);
}
R_EndPolygon();
}
@ -434,16 +441,16 @@ Way_ConnectOne(void)
if (waylink_status == 0) {
way1 = Way_FindClosestWaypoint(self.origin);
waylink_status = 1;
centerprint(self, "Selected first waypoint!\n");
env_message_single(self, "Selected first waypoint!\n");
} else if (waylink_status == 1) {
way2 = Way_FindClosestWaypoint(self.origin);
waylink_status = 0;
if (way1 != way2) {
Way_LinkWaypoints(&g_pWaypoints[way1], &g_pWaypoints[way2]);
centerprint(self, "Linked first waypoint with second waypoint!\n");
env_message_single(self, "Linked first waypoint with second waypoint!\n");
} else {
centerprint(self, "Failed to link, the two points are the same!\n");
env_message_single(self, "Failed to link, the two points are the same!\n");
}
}
}
@ -457,7 +464,7 @@ Way_ConnectTwo(void)
if (waylink_status == 0) {
way1 = Way_FindClosestWaypoint(self.origin);
waylink_status = 1;
centerprint(self, "Selected first waypoint!\n");
env_message_single(self, "Selected first waypoint!\n");
} else if (waylink_status == 1) {
way2 = Way_FindClosestWaypoint(self.origin);
waylink_status = 0;
@ -465,13 +472,21 @@ Way_ConnectTwo(void)
if (way1 != way2) {
Way_LinkWaypoints(&g_pWaypoints[way1], &g_pWaypoints[way2]);
Way_LinkWaypoints(&g_pWaypoints[way2], &g_pWaypoints[way1]);
centerprint(self, "Linked first waypoint with second waypoint!\n");
env_message_single(self, "Linked first waypoint with second waypoint!\n");
} else {
centerprint(self, "Failed to link, the two points are the same!\n");
env_message_single(self, "Failed to link, the two points are the same!\n");
}
}
}
void
Way_RadiusDefaults(void)
{
for (int i = 0i; i < g_iWaypoints; i++) {
g_pWaypoints[i].flRadius = 48;
}
}
void
Way_ConnectAuto(void)
{
@ -487,101 +502,60 @@ Way_Purge(void)
void
Way_Cmd(void)
{
if (!self) {
return;
}
switch (argv(1)) {
case "goto":
if ( !self ) {
return;
}
Way_GoToPoint( self );
break;
case "autolink":
if (!self) {
return;
}
Way_ConnectAuto();
break;
case "connect1":
if (!self) {
return;
}
Way_ConnectOne();
break;
case "connect2":
if (!self) {
return;
}
Way_ConnectTwo();
break;
case "add":
if ( !self ) {
return;
}
Way_Waypoint_Create( self, 1 );
break;
case "addchain":
if ( !self ) {
return;
}
Way_Waypoint_Create( self, 0 );
break;
case "addsingle":
if ( !self ) {
return;
}
Way_Waypoint_Create( self, -3 );
break;
case "addltn":
if ( !self ) {
return;
}
Way_Waypoint_Create( self, -1 );
break;
case "addntl":
if ( !self ) {
return;
}
Way_Waypoint_Create( self, -2 );
break;
case "addspawns":
if ( !self ) {
return;
}
Way_Waypoint_CreateSpawns();
break;
case "delete":
if ( !self ) {
return;
}
Way_Waypoint_Delete( Way_FindClosestWaypoint( self.origin ) );
break;
case "purge":
if ( !self ) {
return;
}
Way_Purge();
break;
case "radius":
if ( !self ) {
return;
}
Way_Waypoint_SetRadius( Way_FindClosestWaypoint( self.origin ), stof( argv( 2 ) ) );
break;
case "radiushack":
Way_RadiusDefaults();
break;
case "linkjump":
if ( !self ) {
return;
}
Way_Waypoint_LinkJump();
break;
case "linkcrouch":
if ( !self ) {
return;
}
Way_Waypoint_LinkCrouch();
break;
case "linkwalk":
if ( !self ) {
return;
}
Way_Waypoint_LinkWalk();
break;
case "save":

View file

@ -274,6 +274,7 @@ HUD_Draw(void)
{
g_hud_color = autocvar_con_color * (1 / 255);
Textmenu_Draw();
Obituary_Draw();
Damage_Draw();
HUD_DrawHealth();
@ -285,4 +286,5 @@ void
HUD_DrawSpectator(void)
{
// FIXME
Textmenu_Draw();
}

View file

@ -22,26 +22,43 @@ Way_Init(void)
titles_t way_menu;
way_menu.m_strName = "WAY_MENU";
way_menu.m_strMessage = "1.\tAdd...\n" \
"2.\tLink...\n" \
"2.\tLink/Unlink...\n" \
"3.\tRemove...\n" \
"4.\tLink Flags...\n" \
"5.\tAuto-Link Settings...\n" \
"5.\tRadius Settings...\n" \
"6.\tAuto-Link Settings...\n" \
"7.\tSave/Load...\n" \
"\n" \
"\n" \
"7.\tSave File\n" \
"8.\tLoad File\n" \
"9.\tExit\n";
way_menu.m_flPosX = 0;
way_menu.m_flPosY = -1;
Titles_AddEntry(way_menu);
}
/* add waypoint menu */
{
titles_t way_file;
way_file.m_strName = "WAY_FILE";
way_file.m_strMessage = "1.\tSave current file (data/mapname.way)\n" \
"\n" \
"\n" \
"4.\tLoad file (data/mapname.way)\n" \
"\n" \
"\n" \
"\n" \
"\n" \
"\n" \
"9.\tBack\n";
way_file.m_flPosX = 0;
way_file.m_flPosY = -1;
Titles_AddEntry(way_file);
}
/* add waypoint menu */
{
titles_t way_add;
way_add.m_strName = "WAY_ADD";
way_add.m_strMessage = "1.\tAdd ^1Autolink^7 Waypoint\n" \
way_add.m_strMessage = "1.\tAdd ^1Single^7 Waypoint\n" \
"2.\tAdd ^1Chain^7 Waypoint^7 (last-to-new)\n" \
"3.\tAdd ^1Single^7 Waypoint\n" \
"3.\tAdd ^1Autolink^7 Waypoint\n" \
"4.\tAdd ^1Spawnpoint^7 Waypoints\n" \
"\n" \
"\n" \
@ -59,12 +76,13 @@ Way_Init(void)
way_link.m_strName = "WAY_LINK";
way_link.m_strMessage = "1.\tLink 2-way (2 steps)\n" \
"2.\tLink 1-way (2 steps)\n" \
"\n" \
"\n" \
"\n" \
"\n" \
"\n" \
"3.\tAutolink closest\n" \
"\n" \
"\n" \
"\n" \
"\n" \
"\n" \
"9.\tBack\n";
way_link.m_flPosX = 0;
way_link.m_flPosY = -1;
@ -80,7 +98,7 @@ Way_Init(void)
"\n" \
"\n" \
"\n" \
"7.\tRemove ALL\n" \
"7.\t^1DANGER^7: Remove ^1ALL\n" \
"\n" \
"9.\tBack\n";
way_remove.m_flPosX = 0;
@ -105,6 +123,23 @@ Way_Init(void)
Titles_AddEntry(way_flags);
}
/* add waypoint menu */
{
titles_t way_radius;
way_radius.m_strName = "WAY_RADIUS";
way_radius.m_strMessage = "1.\tSet closest way-radius (0)\n" \
"2.\tSet closest way-radius (8)\n" \
"3.\tSet closest way-radius (16)\n" \
"4.\tSet closest way-radius (32)\n" \
"5.\tSet closest way-radius (48)\n" \
"6.\tSet closest way-radius (64)\n" \
"7.\tSet closest way-radius (128)\n" \
"\n" \
"9.\tBack\n";
way_radius.m_flPosX = 0;
way_radius.m_flPosY = -1;
Titles_AddEntry(way_radius);
}
/* add waypoint menu */
{
titles_t way_text;
way_text.m_strName = "WAY_AUTOLINK";
@ -140,15 +175,13 @@ WAY_MENU(int n)
Textmenu_Call("WAY_FLAGS");
break;
case 5:
Textmenu_Call("WAY_RADIUS");
break;
case 6:
Textmenu_Call("WAY_AUTOLINK");
break;
case 7:
localcmd(sprintf("sv way save %s.way\n", mapname));
Textmenu_Call("");
break;
case 8:
localcmd(sprintf("sv way load %s.way\n", mapname));
Textmenu_Call("");
Textmenu_Call("WAY_FILE");
break;
case 9:
Textmenu_Call("");
@ -156,18 +189,37 @@ WAY_MENU(int n)
}
}
void
WAY_FILE(int n)
{
switch (n) {
case 1:
localcmd(sprintf("sv way save %s.way\n", mapname));
Textmenu_Call("WAY_MENU");
break;
case 4:
localcmd(sprintf("sv way load %s.way\n", mapname));
Textmenu_Call("WAY_MENU");
break;
case 9:
Textmenu_Call("WAY_MENU");
break;
}
}
void
WAY_ADD(int n)
{
switch (n) {
case 1:
localcmd("sv way add\n");
localcmd("sv way addsingle\n");
break;
case 2:
localcmd("sv way addchain\n");
break;
case 3:
localcmd("sv way addsingle\n");
localcmd("sv way add\n");
break;
case 4:
localcmd("sv way addspawns\n");
@ -188,7 +240,7 @@ WAY_LINK(int n)
case 2:
localcmd("sv way connect1\n");
break;
case 3:
case 7:
localcmd("sv way autolink\n");
break;
case 9:
@ -225,6 +277,7 @@ WAY_REMOVE(int n)
break;
case 7:
localcmd("sv way purge\n");
Textmenu_Call("WAY_MENU");
break;
case 9:
Textmenu_Call("WAY_MENU");
@ -243,10 +296,10 @@ WAY_AUTOLINK(int n)
localcmd("nav_linksize 32\n");
break;
case 3:
localcmd("nav_linksize 64\n");
localcmd("nav_linksize 48\n");
break;
case 4:
localcmd("nav_linksize 128\n");
localcmd("nav_linksize 64\n");
break;
case 5:
localcmd("nav_linksize 512\n");
@ -262,3 +315,34 @@ WAY_AUTOLINK(int n)
break;
}
}
void
WAY_RADIUS(int n)
{
switch (n) {
case 1:
localcmd("sv way radius 0\n");
break;
case 2:
localcmd("sv way radius 8\n");
break;
case 3:
localcmd("sv way radius 16\n");
break;
case 4:
localcmd("sv way radius 32\n");
break;
case 5:
localcmd("sv way radius 48\n");
break;
case 6:
localcmd("sv way radius 64\n");
break;
case 7:
localcmd("sv way radius 128\n");
break;
case 9:
Textmenu_Call("WAY_MENU");
break;
}
}

View file

@ -20,6 +20,7 @@ typedef struct
{
vector m_vecDest;
int m_iFlags;
float m_flRadius;
} nodeslist_t;
/* monster flags, these are defined by the level designers */

View file

@ -172,6 +172,7 @@ Nodes_Init(void)
n->origin = a.origin;
n->nb = __NULL__;
n->nb_count = 0;
n->radius = 32;
Node_AutoLink(n);
}