void TryUse( gentity_t *ent ) { gentity_t *target; trace_t trace; vec3_t src, dest, vf; if ( ent->s.number == 0 && ent->client->NPC_class == CLASS_ATST ) {//a player trying to get out of his ATST GEntity_UseFunc( ent->activator, ent, ent ); return; } //FIXME: this does not match where the new accurate crosshair aims... //cg.refdef.vieworg, basically VectorCopy( ent->client->renderInfo.eyePoint, src ); AngleVectors( ent->client->ps.viewangles, vf, NULL, NULL );//ent->client->renderInfo.eyeAngles was cg.refdef.viewangles, basically //extend to find end of use trace VectorMA( src, USE_DISTANCE, vf, dest ); //Trace ahead to find a valid target gi.trace( &trace, src, vec3_origin, vec3_origin, dest, ent->s.number, MASK_OPAQUE|CONTENTS_SOLID|CONTENTS_BODY|CONTENTS_ITEM|CONTENTS_CORPSE, G2_NOCOLLIDE, 0 ); if ( trace.fraction == 1.0f || trace.entityNum < 1 ) { //TODO: Play a failure sound /* if ( ent->s.number == 0 ) {//if nothing else, try the force telepathy power ForceTelepathy( ent ); } */ return; } target = &g_entities[trace.entityNum]; //Check for a use command if ( ValidUseTarget( target ) ) { NPC_SetAnim( ent, SETANIM_TORSO, BOTH_BUTTON_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); /* if ( !VectorLengthSquared( ent->client->ps.velocity ) && !PM_CrouchAnim( ent->client->ps.legsAnim ) ) { NPC_SetAnim( ent, SETANIM_LEGS, BOTH_BUTTON_HOLD, SETANIM_FLAG_NORMAL|SETANIM_FLAG_HOLD ); } */ //ent->client->ps.weaponTime = ent->client->ps.torsoAnimTimer; GEntity_UseFunc( target, ent, ent ); return; } else if ( target->client && target->client->ps.pm_type < PM_DEAD && target->NPC!=NULL && target->client->playerTeam && (target->client->playerTeam == ent->client->playerTeam || target->client->playerTeam == TEAM_NEUTRAL) && !(target->NPC->scriptFlags&SCF_NO_RESPONSE) ) { NPC_UseResponse ( target, ent, qfalse ); return; } /* if ( ent->s.number == 0 ) {//if nothing else, try the force telepathy power ForceTelepathy( ent ); } */ }
qboolean CanUseInfrontOf(gentity_t *ent) { gentity_t *target; trace_t trace; vec3_t src, dest, vf; if ( ent->s.number && ent->client->NPC_class == CLASS_ATST ) {//a player trying to get out of his ATST // GEntity_UseFunc( ent->activator, ent, ent ); return qfalse; } if (ent->client->ps.viewEntity != ent->s.number) { ent = &g_entities[ent->client->ps.viewEntity]; if ( !Q_stricmp( "misc_camera", ent->classname ) ) { // we are in a camera gentity_t *next = 0; if ( ent->target2 != NULL ) { next = G_Find( NULL, FOFS(targetname), ent->target2 ); } if ( next ) {//found another one if ( !Q_stricmp( "misc_camera", next->classname ) ) {//make sure it's another camera return qtrue; } } else //if ( ent->health > 0 ) {//I was the last (only?) one, clear out the viewentity return qfalse; } } } if ( !ent->client ) { return qfalse; } //FIXME: this does not match where the new accurate crosshair aims... //cg.refdef.vieworg, basically VectorCopy( ent->client->renderInfo.eyePoint, src ); AngleVectors( ent->client->ps.viewangles, vf, NULL, NULL ); //extend to find end of use trace VectorMA( src, USE_DISTANCE, vf, dest ); //Trace ahead to find a valid target gi.trace( &trace, src, vec3_origin, vec3_origin, dest, ent->s.number, MASK_OPAQUE|CONTENTS_SOLID|CONTENTS_TERRAIN|CONTENTS_BODY|CONTENTS_ITEM|CONTENTS_CORPSE , G2_NOCOLLIDE, 10); if ( trace.fraction == 1.0f || trace.entityNum >= ENTITYNUM_WORLD ) { return (CanUseInfrontOfPartOfLevel(ent)); } target = &g_entities[trace.entityNum]; if ( target && target->client && target->client->NPC_class == CLASS_VEHICLE ) { // Attempt to board this vehicle. return qtrue; } //Check for a use command if (ValidUseTarget( target )) { if ( target->s.eType == ET_ITEM ) {//item, see if we could actually pick it up if ( (target->spawnflags&128/*ITMSF_USEPICKUP*/) ) {//player has to be touching me and hit use to pick it up, so don't allow this if ( !G_BoundsOverlap( target->absmin, target->absmax, ent->absmin, ent->absmax ) ) {//not touching return qfalse; } } if ( !BG_CanItemBeGrabbed( &target->s, &ent->client->ps ) ) {//nope, so don't indicate that we can use it return qfalse; } } else if ( target->e_UseFunc == useF_misc_atst_use ) {//drivable AT-ST from JK2 if ( ent->client->ps.groundEntityNum != target->s.number ) {//must be standing on it to use it return qfalse; } } else if ( target->NPC!=NULL && target->health<=0 ) { return qfalse; } else if ( target->e_UseFunc == useF_eweb_use ) { if ( !eweb_can_be_used( target, ent, ent ) ) { return qfalse; } } return qtrue; } if ( target->client && target->client->ps.pm_type < PM_DEAD && target->NPC!=NULL && target->client->playerTeam && (target->client->playerTeam == ent->client->playerTeam || target->client->playerTeam == TEAM_NEUTRAL) && !(target->NPC->scriptFlags&SCF_NO_RESPONSE) && G_ValidActivateBehavior (target, BSET_USE)) { return qtrue; } if (CanUseInfrontOfPartOfLevel(ent)) { return qtrue; } return qfalse; }