void eweb_use( gentity_t *self, gentity_t *other, gentity_t *activator ) { if ( !eweb_can_be_used( self, other, activator ) ) { return; } int oldWeapon = activator->s.weapon; if ( oldWeapon == WP_SABER ) { self->alt_fire = activator->client->ps.SaberActive(); } // swap the users weapon with the emplaced gun and add the ammo the gun has to the player activator->client->ps.weapon = self->s.weapon; Add_Ammo( activator, WP_EMPLACED_GUN, self->count ); activator->client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_EMPLACED_GUN ); // Allow us to point from one to the other activator->owner = self; // kind of dumb, but when we are locked to the weapon, we are owned by it. self->activator = activator; G_RemoveWeaponModels( activator ); extern void ChangeWeapon( gentity_t *ent, int newWeapon ); if ( activator->NPC ) { ChangeWeapon( activator, WP_EMPLACED_GUN ); } else if ( activator->s.number == 0 ) { // we don't want for it to draw the weapon select stuff cg.weaponSelect = WP_EMPLACED_GUN; CG_CenterPrint( "@SP_INGAME_EXIT_VIEW", SCREEN_HEIGHT * 0.95 ); } VectorCopy( activator->currentOrigin, self->pos4 );//keep this around so we know when to make them play the strafe anim // the gun will track which weapon we used to have self->s.weapon = oldWeapon; // Lock the player activator->client->ps.eFlags |= EF_LOCKED_TO_WEAPON; activator->owner = self; // kind of dumb, but when we are locked to the weapon, we are owned by it. self->activator = activator; self->delay = level.time; // can't disconnect from the thing for half a second // Let the gun be considered an enemy //Ugh, so much AI code seems to assume enemies are clients, maybe this shouldn't be on, but it's too late in the game to change it now without knowing what side-effects this will have self->svFlags |= SVF_NONNPC_ENEMY; self->noDamageTeam = activator->client->playerTeam; //FIXME: should really wait a bit after spawn and get this just once? self->waypoint = NAV::GetNearestNode(self); #ifdef _DEBUG if ( self->waypoint == -1 ) { gi.Printf( S_COLOR_RED"ERROR: no waypoint for emplaced_gun %s at %s\n", self->targetname, vtos(self->currentOrigin) ); } #endif G_Sound( self, G_SoundIndex( "sound/weapons/eweb/eweb_mount.mp3" )); if ( !(self->spawnflags&EMPLACED_PLAYERUSE) || activator->s.number == 0 ) {//player-only usescript or any usescript // Run use script G_ActivateBehavior( self, BSET_USE ); } }
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; }