/* * GS_Cmd_UseItem */ gsitem_t *GS_Cmd_UseItem( player_state_t *playerState, const char *string, int typeMask ) { gsitem_t *item = NULL; assert( playerState ); if( playerState->pmove.pm_type >= PM_SPECTATOR ) return NULL; if( !string || !string[0] ) return NULL; if( Q_isdigit( string ) ) { int tag = atoi( string ); item = GS_FindItemByTag( tag ); } else item = GS_FindItemByName( string ); if( !item ) return NULL; if( typeMask && !( item->type & typeMask ) ) return NULL; // we don't have this item in the inventory if( !playerState->inventory[item->tag] ) { if( gs.module == GS_MODULE_CGAME && !( item->type & IT_WEAPON ) ) module_Printf( "Item %s is not in inventory\n", item->name ); return NULL; } // see if we can use it if( !(item->flags & ITFLAG_USABLE) ) return NULL; if( item->type & IT_WEAPON ) { if( !( playerState->pmove.stats[PM_STAT_FEATURES] & PMFEAT_WEAPONSWITCH ) ) return NULL; if( item->tag == playerState->stats[STAT_PENDING_WEAPON] ) // it's already being loaded return NULL; // check for need of any kind of ammo/fuel/whatever if( item->ammo_tag != AMMO_NONE && item->weakammo_tag != AMMO_NONE ) { gs_weapon_definition_t *weapondef = GS_GetWeaponDef( item->tag ); if( weapondef ) { // do we have any of these ammos ? if( playerState->inventory[item->weakammo_tag] >= weapondef->firedef_weak.usage_count ) return item; if( playerState->inventory[item->ammo_tag] >= weapondef->firedef.usage_count ) return item; } return NULL; } return item; // one of the weapon modes doesn't require ammo to be fired } if( item->type & IT_AMMO ) return item; if( item->type & IT_HEALTH ) return item; if( item->type & IT_POWERUP ) return item; return NULL; }
/* * GS_SlideMove */ int GS_SlideMove( move_t *move ) { #define MAX_SLIDEMOVE_ATTEMPTS 8 int count; int blockedmask = 0; vec3_t lastValidOrigin, originalVelocity; // if the velocity is too small, just stop if( VectorLength( move->velocity ) < STOP_EPSILON ) { VectorClear( move->velocity ); move->remainingTime = 0; return 0; } VectorCopy( move->velocity, originalVelocity ); VectorCopy( move->origin, lastValidOrigin ); GS_ClearClippingPlanes( move ); move->numtouch = 0; for( count = 0; count < MAX_SLIDEMOVE_ATTEMPTS; count++ ) { // get the original velocity and clip it to all the planes we got in the list VectorCopy( originalVelocity, move->velocity ); GS_ClipVelocityToClippingPlanes( move ); blockedmask = GS_SlideMoveClipMove( move /*, stepping*/ ); #ifdef CHECK_TRAPPED { trace_t trace; module_Trace( &trace, move->origin, move->mins, move->maxs, move->origin, move->passent, move->contentmask, 0 ); if( trace.startsolid ) { blockedmask |= SLIDEMOVEFLAG_TRAPPED; } } #endif // can't continue if( blockedmask & SLIDEMOVEFLAG_TRAPPED ) { #ifdef CHECK_TRAPPED module_Printf( "GS_SlideMove SLIDEMOVEFLAG_TRAPPED\n" ); #endif move->remainingTime = 0.0f; VectorCopy( lastValidOrigin, move->origin ); return blockedmask; } VectorCopy( move->origin, lastValidOrigin ); // touched a plane, re-clip velocity and retry if( blockedmask & SLIDEMOVEFLAG_PLANE_TOUCHED ) { continue; } // if it didn't touch anything the move should be completed if( move->remainingTime > 0.0f ) { module_Printf( "slidemove finished with remaining time\n" ); move->remainingTime = 0.0f; } break; } // snap GS_SnapPosition( move->origin, move->mins, move->maxs, move->passent, move->contentmask ); GS_SnapVelocity( move->velocity ); return blockedmask; }