Quote:
Originally Posted by Immortal_BLG
I think this is because RunPlayerMove receives view angles instead of move angles, which should be oriented same as red line (upwards)...
To traverse ladder:
1) pEdict->v.movetype == MOVETYPE_FLY
2) bot move angles which receives to RunPlayerMove should direct at top of ladder
3) bot forwardSpeed != 0.0
So from this point I think that you have missed something from this...
Sorry for bad english...
|
Hi Immortal_BLG, thanks for jumping in.
I believe I have met these requirements, however I'll detail the code I'm using to see if you can spot the mistake (don't worry, it's not much code).
My BotThink function looks like this:
Code:
void BotThink(bot_t *pBot)
{
edict_t *pEdict = pBot->pEdict;
pEdict->v.flags |= FL_THIRDPARTYBOT;
pEdict->v.button = 0;
if (pBot->name[0] == 0) // name filled in yet?
strcpy(pBot->name, STRING(pBot->pEdict->v.netname));
if (pBot->not_started) {
BotStartGame(pBot);
}
// If the bot does not have a path size
if (pBot->pathSize == 0) {
// Pick a random point on the navmesh as a destination
GetRandomPoint(pBot->targetDest);
// Create the path
FindPathToPoint(pBot, pBot->targetDest, pBot->currentPath, &pBot->pathSize);
// Point 0 is usually right at the bot's current position, so jump ahead
pBot->currentPathPoint = 1;
}
else {
// Determines the bot's forward and side speed
NextMove(pBot);
}
// Updates the bot's view frustum, updates the list of currently visible players and makes the bot look at their current waypoint
UpdateView(pBot);
// Adjust msec to command time interval
byte adjustedmsec = ThrottledMsec(pBot);
// save the command time
pBot->f_previous_command_time = gpGlobals->time;
// This is the ONLY call to pfnRunPlayerMove
g_engfuncs.pfnRunPlayerMove(pEdict, pEdict->v.v_angle, pBot->y_move_speed,
pBot->x_move_speed, 0, pEdict->v.button, 0, adjustedmsec);
}
The NextMove function is pretty big as it does a lot of checking of the path and whether the bot is stuck or not, but its ONLY function is to populate pBot->y_move_speed and pBot->x_move_speed. It basically takes the direction the bot needs to move in, uses VecToAngles to work out the orientation in relation to the bot's current rotation and then has an if statement that says "if the bot needs to move diagonally-right then set y_move_speed to maxspeed and x_move_speed to maxspeed", or "if the bot needs to move backwards then set y_move_speed to -maxspeed and x_move_speed to 0" and so on.
The UpdateView function does a bunch of stuff related to the bot's vision, and also makes the bot look its current waypoint:
Code:
void UpdateView(bot_t* pBot) {
int visibleCount = 0;
// Updates the view frustum based on the bot's position and v_angle
UpdateViewFrustrum(pBot);
memset(pBot->visiblePlayers, 0, sizeof(float) * 32);
// nextDest is the waypoint the bot is currently moving to
Vector lookDest = pBot->nextDest.location;
// Make the bot rotate instantly to look at lookDest
LookAt(pBot, lookDest);
// Update list of currently visible players
for (int i = 0; i < 32; i++) {
if (clients[i] != NULL) {
if (CheckPlayerVisiblity(pBot, clients[i])) {
pBot->visiblePlayers[visibleCount++] = clients[i];
}
}
}
// Call BotSeePlayer for every visible player each frame. Currently does nothing
for (int i = 0; i < visibleCount; i++) {
BotSeePlayer(pBot, pBot->visiblePlayers[i]);
}
}
and finally the LookAt code is listed here:
Code:
void LookAt(bot_t* pBot, Vector target) {
edict_t *pEdict = pBot->pEdict;
Vector viewPos = pBot->pEdict->v.origin + pBot->pEdict->v.view_ofs;
Vector dir = target - viewPos;
Vector bot_angles = UTIL_VecToAngles(dir) -pEdict->v.punchangle;
pEdict->v.idealpitch = bot_angles.x;
pEdict->v.ideal_yaw = bot_angles.y;
ClampAngle(pEdict->v.idealpitch);
ClampAngle(pEdict->v.ideal_yaw);
pEdict->v.v_angle.x = pEdict->v.idealpitch;
pEdict->v.v_angle.y = pEdict->v.ideal_yaw;
pEdict->v.angles.x = pEdict->v.v_angle.x * (1.f / 3.f);
pEdict->v.angles.y = pEdict->v.v_angle.y;
pEdict->v.angles.z = pEdict->v.v_angle.z = 0;
}
So every frame, the bot determines which direction it is heading in (i.e. whether it is moving forwards/backwards and strafing left/right) and updates the v_angle and angles to face its current waypoint.
If I view the bot in first person mode as spectator, I can see its looking at the top of the ladder, and I have traces to confirm it is definitely MOVETYPE_FLY, and that it is currently trying to move forwards (the yellow line in the earlier screenshot indicates that y_movement_speed is maxspeed and x_movement_speed is 0 basically).
Not sure what I'm missing here.