void Bot_CL_KeyMove( ) { int forwardmove = 0, sidemove = 0, upmove = 0; int buttons = 0; buttons = ( ( self->s.v.button0 ) ? 1 : 0 ) + ( ( self->s.v.button2 ) ? 2 : 0 ); sidemove += self->maxstrafespeed * CL_KeyState( KEY_MOVERIGHT ); sidemove -= self->maxstrafespeed * CL_KeyState( KEY_MOVELEFT ); upmove += 200 * CL_KeyState( KEY_MOVEUP ); upmove -= 200 * CL_KeyState( KEY_MOVEDOWN ); forwardmove += self->maxfbspeed * CL_KeyState( KEY_MOVEFORWARD ); forwardmove -= self->maxfbspeed * CL_KeyState( KEY_MOVEBACK ); if ( self->s.v.v_angle[0] > 80 ) self->s.v.v_angle[0] = 80; else { if ( self->s.v.v_angle[0] < -70 ) self->s.v.v_angle[0] = -70; } //self->s.v.v_angle[2] = 0; self->s.v.v_angle[1] = anglemod( self->s.v.v_angle[1] ); trap_SetBotCMD( NUM_FOR_EDICT( self ), bot_frametime * 1000, PASSVEC3(self->s.v.v_angle), forwardmove, sidemove, upmove, buttons, self->s.v.impulse ); }
void BotSetCommand (gedict_t* self) { extern float last_frame_time; float msec_since_last = (last_frame_time - self->fb.last_cmd_sent) * 1000; int cmd_msec = (int)msec_since_last; int weapon_script_impulse = 0; int impulse = 0; qbool jumping; qbool firing; vec3_t direction; BotPerformRocketJump (self); if (cmd_msec) { self->fb.cmd_msec_lost += (msec_since_last - cmd_msec); if (self->fb.cmd_msec_lost >= 1) { self->fb.cmd_msec_lost -= 1; cmd_msec += 1; } } else if (self->fb.cmd_msec_last) { // Probably re-sending after blocked(), re-use old number cmd_msec = self->fb.cmd_msec_last; } else { cmd_msec = 12; } //G_sprint(self, PRINT_HIGH, "Movement length @ %f: %d\n", last_frame_time, cmd_msec); // dir_move_ is the direction we want to move in, but need to take inertia into effect // ... as rough guide (and save doubling physics calculations), scale command > VectorNormalize (self->fb.dir_move_); VectorScale (self->fb.dir_move_, sv_maxspeed, self->fb.last_cmd_direction); trap_makevectors (self->fb.desired_angle); // During intermission, always do nothing and leave humans to change level if (intermission_running) { self->fb.firing = self->fb.jumping = false; } else if (teamplay && deathmatch == 1 && !self->fb.firing) { // Weaponscripts if (self->s.v.weapon != IT_SHOTGUN && self->s.v.weapon != IT_AXE) { weapon_script_impulse = (self->s.v.ammo_shells ? 2 : 1); } } impulse = self->fb.botchose ? self->fb.next_impulse : self->fb.firing ? self->fb.desired_weapon_impulse : weapon_script_impulse; if (self->fb.firing && BotUsingCorrectWeapon (self)) { impulse = 0; // we already have the requested weapon } jumping = self->fb.jumping || self->fb.waterjumping; firing = self->fb.firing; self->fb.waterjumping = false; if (self->fb.dbg_countdown > 0) { jumping = firing = false; VectorClear (direction); --self->fb.dbg_countdown; } else { if (jumping && ((int)self->s.v.flags & FL_ONGROUND)) { BestJumpingDirection (self); } else { ApplyPhysics (self); } if (self->s.v.waterlevel <= 1) { vec3_t hor; VectorCopy (self->fb.dir_move_, hor); hor[2] = 0; VectorNormalize (hor); VectorScale (hor, 800, hor); direction[0] = DotProduct (g_globalvars.v_forward, hor); direction[1] = DotProduct (g_globalvars.v_right, hor); direction[2] = 0; } else { direction[0] = DotProduct (g_globalvars.v_forward, self->fb.dir_move_) * 800; direction[1] = DotProduct (g_globalvars.v_right, self->fb.dir_move_) * 800; direction[2] = DotProduct (g_globalvars.v_up, self->fb.dir_move_) * 800; } #ifdef DEBUG_MOVEMENT if (self->fb.debug_path) { G_bprint (PRINT_HIGH, " : final direction sent [%4.1f %4.1f %4.1f]\n", PASSVEC3 (self->fb.dir_move_)); } #endif } self->fb.desired_angle[2] = 0; if (ISDEAD (self)) { firing = false; jumping = BotRequestRespawn (self); VectorClear (direction); impulse = 0; } else if (self->fb.min_move_time > g_globalvars.time) { VectorClear (direction); } // Keep bots on spawns before match start if (match_in_progress != 2 && cvar(FB_CVAR_FREEZE_PREWAR)) { jumping = firing = false; VectorClear(direction); impulse = 0; } trap_SetBotCMD ( NUM_FOR_EDICT (self), cmd_msec, PASSVEC3(self->fb.desired_angle), PASSVEC3(direction), (firing ? 1 : 0) | (jumping ? 2 : 0), impulse ); self->fb.next_impulse = 0; self->fb.botchose = false; self->fb.last_cmd_sent = last_frame_time; self->fb.cmd_msec_last = cmd_msec; VectorClear (self->fb.obstruction_normal); if (self->s.v.button0 && !firing) { // Stopped firing, randomise next time self->fb.last_rndaim_time = 0; } self->fb.prev_look_object = self->fb.look_object; VectorCopy (self->s.v.velocity, self->fb.prev_velocity); }