// Bot_Input.cpp // #include "precompiled.h" #pragma hdrstop #include "../Game_local.h" #include "../../../engine/framework/UsercmdGen.h" /* ============== rvmBot::BotInputToUserCommand ============== */ void rvmBot::BotInputToUserCommand(bot_input_t* bi, usercmd_t* ucmd, int time) { idVec3 forward, right; if( bi == NULL || ucmd == NULL ) { return; } if (bi->actionflags & ACTION_DELAYEDJUMP) { bi->actionflags |= ACTION_JUMP; bi->actionflags &= ~ACTION_DELAYEDJUMP; } if (bi->actionflags & ACTION_RESPAWN) { ucmd->buttons |= BUTTON_ATTACK; } if (bi->actionflags & ACTION_ATTACK) { ucmd->buttons |= BUTTON_ATTACK; } if (bi->actionflags & ACTION_WALK) { ucmd->buttons |= BUTTON_RUN; } ucmd->impulse = 0; if (bi->lastWeaponNum != bi->weapon) { ucmd->impulse = bi->weapon; bi->lastWeaponNum = bi->weapon; } idAngles botViewAngles = viewAngles; // Slow smoothing made bots fire while their usercmd view was still several // frames behind the computed aim, which is very noticeable when looking down // stairs. Turn briskly in general and snap on the frames where the bot is // actually firing. const float turnScale = ( bi->actionflags & ACTION_ATTACK ) ? 1.0f : 0.35f; for (int i = 0; i < 3; i++) { const float move = idMath::AngleDelta( bi->viewangles[i], botViewAngles[i] ); botViewAngles[i] += move * turnScale; } //set the view angles //NOTE: the ucmd->angles are the angles WITHOUT the delta angles ucmd->angles[0] = ANGLE2SHORT(botViewAngles[0] - deltaViewAngles[0]); ucmd->angles[1] = ANGLE2SHORT(botViewAngles[1] - deltaViewAngles[1]); ucmd->angles[2] = ANGLE2SHORT(botViewAngles[2] - deltaViewAngles[2]); // Movement commands are relative to the view angles that are actually put into // this usercmd, not the unsmoothed desired angles. Also keep movement on the // horizontal plane so looking up/down at an enemy does not change speed. idAngles moveAngles = botViewAngles; moveAngles[PITCH] = 0.0f; moveAngles[ROLL] = 0.0f; moveAngles.ToVectors(&forward, &right, NULL); idVec3 moveDir = bi->dir; moveDir[2] = 0.0f; if( moveDir.LengthSqr() > Square( 0.001f ) ) { moveDir.Normalize(); } else { moveDir = idVec3( 0.0f, 0.0f, 0.0f ); } float scaledSpeed = bi->speed; if( scaledSpeed < 0.0f ) { scaledSpeed = 0.0f; } else if( scaledSpeed > 400.0f ) { scaledSpeed = 400.0f; } scaledSpeed = scaledSpeed * 127.0f / 400.0f; ucmd->forwardmove = idMath::ClampChar( DotProduct(forward, moveDir) * scaledSpeed ); ucmd->rightmove = idMath::ClampChar( DotProduct(right, moveDir) * scaledSpeed ); //normal keyboard movement if (bi->actionflags & ACTION_MOVEFORWARD) { ucmd->forwardmove = idMath::ClampChar( ucmd->forwardmove + 127 ); } if (bi->actionflags & ACTION_MOVEBACK) { ucmd->forwardmove = idMath::ClampChar( ucmd->forwardmove - 127 ); } if (bi->actionflags & ACTION_MOVELEFT) { ucmd->rightmove = idMath::ClampChar( ucmd->rightmove - 127 ); } if (bi->actionflags & ACTION_MOVERIGHT) { ucmd->rightmove = idMath::ClampChar( ucmd->rightmove + 127 ); } if( bi->respawn ) { ucmd->buttons |= BUTTON_ATTACK; } } /* ================ rvmBot::ResetUcmd ================ */ void rvmBot::Bot_ResetUcmd( usercmd_t& ucmd ) { ucmd.forwardmove = 0; ucmd.rightmove = 0; //ucmd.upmove = 0; ucmd.impulse = 0; //ucmd.flags = 0; memset( &ucmd.buttons, 0, sizeof( ucmd.buttons ) ); } /* ======================== rvmBot::BotInputFrame ======================== */ void rvmBot::BotInputFrame( void ) { usercmd_t botcmd = { }; //(usercmd_t&)cmdMgr.GetUserCmdForPlayer(entityNumber); // gameLocal.usercmds[entityNumber]; Bot_ResetUcmd( botcmd ); BotInputToUserCommand( &bs.botinput, &botcmd, gameLocal.time ); networkSystem->ServerSetBotUserCommand(entityNumber, gameLocal.framenum, botcmd); }