unsigned int AI_CurrentLinkType( edict_t *self ) { if( !AI_PlinkExists( self->ai.current_node, self->ai.next_node ) ) return LINK_INVALID; return AI_PlinkMoveType( self->ai.current_node, self->ai.next_node ); }
void BOT_DMclass_SpecialMove( edict_t *self, vec3_t lookdir, vec3_t pathdir, usercmd_t *ucmd ) { bool wallJump = false; bool dash = true; bool bunnyhop = true; trace_t trace; vec3_t end; int n1, n2, nextMoveType; self->ai->is_bunnyhop = false; if( self->ai->path.numNodes < MIN_BUNNY_NODES ) return; // verify that the 2nd node is in front of us for dashing n1 = self->ai->path.nodes[self->ai->path.numNodes]; n2 = self->ai->path.nodes[self->ai->path.numNodes-1]; if( !AI_infront2D( lookdir, self->s.origin, nodes[n2].origin, 0.5 ) ) bunnyhop = false; // do not dash if the next link will be a fall, jump or // any other kind of special link nextMoveType = AI_PlinkMoveType( n1, n2 ); if( nextMoveType & (LINK_LADDER|LINK_PLATFORM|LINK_ROCKETJUMP|LINK_FALL|LINK_JUMP|LINK_CROUCH) ) dash = false; if( nextMoveType &(LINK_LADDER|LINK_PLATFORM|LINK_FALL|LINK_CROUCH) ) bunnyhop = false; #if 0 if( VectorLengthFast( self->velocity ) < AI_JUMP_SPEED ) { if( dash && self->groundentity ) // attempt dash { if( DotProduct( lookdir, pathdir ) > 0.9 ) { // do not dash unless both next nodes are visible if( AI_ReachabilityVisible( self, nodes[n1].origin ) && AI_ReachabilityVisible( self, nodes[n2].origin ) ) { ucmd->buttons |= BUTTON_SPECIAL; ucmd->sidemove = 0; ucmd->forwardmove = 1; self->ai->is_bunnyhop = true; } } } } else #endif if( bunnyhop && ( (nextMoveType &LINK_JUMP) || level.gametype.spawnableItemsMask == 0 ) ) { if( self->groundentity ) ucmd->upmove = 1; #if 0 // fake strafe-jumping acceleration if( VectorLengthFast( self->velocity ) < 700 && DotProduct( lookdir, pathdir ) > 0.6 ) VectorMA( self->velocity, 0.1f, lookdir, self->velocity ); #endif self->ai->is_bunnyhop = true; } if( wallJump ) { if( self->ai->move_vector[2] > 25 && DotProduct( self->velocity, pathdir ) < -0.2 ) { VectorMA( self->s.origin, 0.02, self->velocity, end ); G_Trace( &trace, self->s.origin, self->r.mins, self->r.maxs, end, self, MASK_AISOLID ); if( trace.fraction != 1.0f ) ucmd->buttons |= BUTTON_SPECIAL; } } // if pushing in the opposite direction of the path, reduce the push if( DotProduct( lookdir, pathdir ) < -0.33f ) ucmd->forwardmove = 0; }
//========================================== // M_default_Move // movement following paths code //========================================== //void M_default_Move( edict_t *self, usercmd_t *ucmd ) //{ // BOT_DMclass_Move( self, ucmd ); //} void M_default_Move(edict_t *self, usercmd_t *ucmd) { int current_node_flags = 0; int next_node_flags = 0; int current_link_type = 0; // int i; current_node_flags = nodes[self->ai->current_node].flags; next_node_flags = nodes[self->ai->next_node].flags; if( AI_PlinkExists( self->ai->current_node, self->ai->next_node )) { current_link_type = AI_PlinkMoveType( self->ai->current_node, self->ai->next_node ); //Com_Printf("%s\n", AI_LinkString( current_link_type )); } // Falling off ledge if(!self->groundentity && !self->is_step && !self->is_swim ) { AI_ChangeAngle(self); if (current_link_type == LINK_JUMPPAD ) { ucmd->forwardmove = 100; } else if( current_link_type == LINK_JUMP ) { self->velocity[0] = self->ai->move_vector[0] * 280; self->velocity[1] = self->ai->move_vector[1] * 280; } else { self->velocity[0] = self->ai->move_vector[0] * 160; self->velocity[1] = self->ai->move_vector[1] * 160; } return; } // swimming if( self->is_swim ) { // We need to be pointed up/down AI_ChangeAngle(self); //if( !(trap_PointContents(nodes[self->ai->next_node].origin) & MASK_WATER) ) // Exit water if( !(gi.pointcontents(nodes[self->ai->next_node].origin) & MASK_WATER) ) // Exit water ucmd->upmove = 400; ucmd->forwardmove = 300; return; } // Check to see if stuck, and if so try to free us if(VectorCompare(self->s.old_origin, self->s.origin)) { // Keep a random factor just in case.... if( random() > 0.1 && AI_SpecialMove(self, ucmd) ) //jumps, crouches, turns... return; self->s.angles[YAW] += random() * 180 - 90; AI_ChangeAngle(self); ucmd->forwardmove = 400; return; } AI_ChangeAngle(self); // Otherwise move as fast as we can... ucmd->forwardmove = 400; }