/* ==================== G_KillBrushModel ==================== */ void G_KillBrushModel( gentity_t *ent, gentity_t *activator ) { gentity_t *e; vec3_t mins, maxs; trace_t tr; for( e = &g_entities[ 0 ]; e < &g_entities[ level.num_entities ]; ++e ) { if( !e->r.linked || !e->clipmask ) continue; VectorAdd( e->r.currentOrigin, e->r.mins, mins ); VectorAdd( e->r.currentOrigin, e->r.maxs, maxs ); if( !trap_EntityContact( mins, maxs, ent ) ) continue; trap_Trace( &tr, e->r.currentOrigin, e->r.mins, e->r.maxs, e->r.currentOrigin, e->s.number, e->clipmask, 0 ); if( tr.entityNum != ENTITYNUM_NONE ) { Entities::Kill(e, activator, MOD_CRUSH); } } }
/* ==================== G_KillBrushModel ==================== */ void G_KillBrushModel( gentity_t *ent, gentity_t *activator ) { gentity_t *e; vec3_t mins, maxs; trace_t tr; for( e = &g_entities[ 0 ]; e < &g_entities[ level.num_entities ]; ++e ) { if( !e->takedamage || !e->r.linked || !e->clipmask || ( e->client && e->client->noclip ) ) continue; VectorAdd( e->r.currentOrigin, e->r.mins, mins ); VectorAdd( e->r.currentOrigin, e->r.maxs, maxs ); if( !trap_EntityContact( mins, maxs, ent ) ) continue; trap_Trace( &tr, e->r.currentOrigin, e->r.mins, e->r.maxs, e->r.currentOrigin, e->s.number, e->clipmask ); if( tr.entityNum != ENTITYNUM_NONE ) G_Damage( e, ent, activator, NULL, NULL, 100000, DAMAGE_NO_PROTECTION, MOD_CRUSH ); } }
/* ============ G_TouchTriggers Find all trigger entities that ent's current position touches. Spectators will only interact with teleporters (and door triggers for spectators) ============ */ void G_TouchTriggers(gentity_t * ent) { int i, num; int touch[MAX_GENTITIES]; gentity_t *hit; trace_t trace; vec3_t mins, maxs; static vec3_t range = { 40, 40, 52 }; if (!ent->client) { return; } // dead clients don't activate triggers! if (ent->client->ps.stats[STAT_HEALTH] <= 0) { return; } VectorSubtract(ent->client->ps.origin, range, mins); VectorAdd(ent->client->ps.origin, range, maxs); num = trap_EntitiesInBox(mins, maxs, touch, MAX_GENTITIES); // can't use ent->absmin, because that has a one unit pad VectorAdd(ent->client->ps.origin, ent->r.mins, mins); VectorAdd(ent->client->ps.origin, ent->r.maxs, maxs); for (i = 0; i < num; i++) { //Blaze: Print out some debug info if (&g_entities[touch[i]] == NULL) G_Printf("Ln 0429\n"); hit = &g_entities[touch[i]]; if (!hit->touch && !ent->touch) { continue; } if (!(hit->r.contents & CONTENTS_TRIGGER)) { continue; } // ignore most entities if a spectator if (ent->client->sess.sessionTeam == TEAM_SPECTATOR) { if (hit->s.eType != ET_TELEPORT_TRIGGER) { //&& // this is ugly but adding a new ET_? type will // most likely cause network incompatibilities // NiceAss: changed Touch_DoorTrigger to Touch_DoorTriggerSpectator // hit->touch != Touch_DoorTriggerSpectator) { continue; } } // use seperate code for determining if an item is picked up // so you don't have to actually contact its bounding box if (hit->s.eType == ET_ITEM) { if (!BG_PlayerTouchesItem(&ent->client->ps, &hit->s, level.time)) { continue; } } else { if (!trap_EntityContact(mins, maxs, hit)) { continue; } } memset(&trace, 0, sizeof(trace)); if (hit->touch) { hit->touch(hit, ent, &trace); } if ((ent->r.svFlags & SVF_BOT) && (ent->touch)) { ent->touch(ent, hit, &trace); } } // if we didn't touch a jump pad this pmove frame if (ent->client->ps.jumppad_frame != ent->client->ps.pmove_framecount) { ent->client->ps.jumppad_frame = 0; ent->client->ps.jumppad_ent = 0; } if (ent->client->openDoor == 2) { ent->client->openDoor = qfalse; ent->client->openDoorTime = 0; } }
/* ============ G_TouchTriggers Find all trigger entities that ent's current position touches. Spectators will only interact with teleporters. ============ */ void G_TouchTriggers( gentity_t *ent ) { int i, num; int touch[MAX_GENTITIES]; gentity_t *hit; trace_t trace; vec3_t mins, maxs; static vec3_t range = { 40, 40, 52 }; if ( !ent->client ) { return; } // dead clients don't activate triggers! if ( ent->client->ps.stats[STAT_HEALTH] <= 0 ) { return; } VectorSubtract( ent->client->ps.origin, range, mins ); VectorAdd( ent->client->ps.origin, range, maxs ); num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); // can't use ent->absmin, because that has a one unit pad VectorAdd( ent->client->ps.origin, ent->r.mins, mins ); VectorAdd( ent->client->ps.origin, ent->r.maxs, maxs ); for ( i = 0 ; i < num ; i++ ) { hit = &g_entities[touch[i]]; if ( !hit->touch && !ent->touch ) { continue; } if ( !( hit->r.contents & CONTENTS_TRIGGER ) ) { continue; } // ignore most entities if a spectator if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) { if ( hit->s.eType != ET_TELEPORT_TRIGGER ) { continue; } } // use seperate code for determining if an item is picked up // so you don't have to actually contact its bounding box if ( hit->s.eType == ET_ITEM ) { if ( !BG_PlayerTouchesItem( &ent->client->ps, &hit->s, level.time ) ) { continue; } } else { // MrE: always use capsule for player //if ( !trap_EntityContactCapsule( mins, maxs, hit ) ) { if ( !trap_EntityContact( mins, maxs, hit ) ) { continue; } } memset( &trace, 0, sizeof( trace ) ); if ( hit->touch ) { hit->touch( hit, ent, &trace ); } if ( ( ent->r.svFlags & SVF_BOT ) && ( ent->touch ) ) { ent->touch( ent, hit, &trace ); } } }
/* ============ G_TouchTriggers Find all trigger entities that ent's current position touches. Spectators will only interact with teleporters. ============ */ void G_TouchTriggers( gentity_t *ent ) { int num; int touch[MAX_GENTITIES]; vec3_t mins; vec3_t maxs; static vec3_t range = { 20, 20, 40 }; if ( !ent->client ) { return; } // dead clients don't activate triggers! if ( G_IsClientDead ( ent->client ) ) { return; } VectorSubtract( ent->client->ps.origin, range, mins ); VectorAdd( ent->client->ps.origin, range, maxs ); num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); // can't use ent->r.absmin, because that has a one unit pad VectorAdd( ent->client->ps.origin, ent->r.mins, mins ); VectorAdd( ent->client->ps.origin, ent->r.maxs, maxs ); // Reset the players can use flag ent->client->ps.pm_flags &= ~(PMF_CAN_USE); ent->s.modelindex = 0; for ( int i=0 ; i<num ; i++ ) { gentity_t *hit = &g_entities[touch[i]]; // pmove would have to have detected siamese twins first if ( hit->client && hit != ent && !hit->client->siameseTwin && (ent->client->ps.pm_flags & PMF_SIAMESETWINS) ) { // See if this client has a twin if ( !G_IsClientSiameseTwin ( ent, hit ) ) { continue; } // About time these twins were separated!! ent->client->siameseTwin = hit; hit->client->siameseTwin = ent; } if ( !( hit->r.contents & CONTENTS_TRIGGER ) ) { continue; } if ( !hit->touch && !ent->touch ) { continue; } // ignore most entities if a spectator if ( G_IsClientSpectating ( ent->client ) ) { if ( hit->s.eType != ET_TELEPORT_TRIGGER && // this is ugly but adding a new ET_? type will // most likely cause network incompatibilities hit->touch != Touch_DoorTrigger) { continue; } } // use seperate code for determining if an item is picked up // so you don't have to actually contact its bounding box if ( hit->s.eType == ET_ITEM ) { if ( !BG_PlayerTouchesItem( &ent->client->ps, &hit->s, level.time ) ) { continue; } } else { if ( !trap_EntityContact( mins, maxs, hit ) ) { continue; } } trace_t trace; memset( &trace, 0, sizeof(trace) ); if ( hit->touch ) { hit->touch (hit, ent, &trace); } if ( ( ent->r.svFlags & SVF_BOT ) && ( ent->touch ) ) { ent->touch( ent, hit, &trace ); } } // Dont bother looking for twins again unless pmove says so ent->client->ps.pm_flags &= (~PMF_SIAMESETWINS); }
/* ============ G_MoverTouchTriggers Find all trigger entities that ent's current position touches. Spectators will only interact with teleporters. ============ */ void G_MoverTouchPushTriggers( gentity_t *ent, vec3_t oldOrg ) { int i, num; float step, stepSize, dist; int touch[MAX_GENTITIES]; gentity_t *hit; trace_t trace; vec3_t mins, maxs, dir, size, checkSpot; const vec3_t range = { 40, 40, 52 }; // non-moving movers don't hit triggers! if ( !VectorLengthSquared( ent->s.pos.trDelta ) ) { return; } VectorSubtract( ent->r.mins, ent->r.maxs, size ); stepSize = VectorLength( size ); if ( stepSize < 1 ) { stepSize = 1; } VectorSubtract( ent->r.currentOrigin, oldOrg, dir ); dist = VectorNormalize( dir ); for ( step = 0; step <= dist; step += stepSize ) { VectorMA( ent->r.currentOrigin, step, dir, checkSpot ); VectorSubtract( checkSpot, range, mins ); VectorAdd( checkSpot, range, maxs ); num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); // can't use ent->r.absmin, because that has a one unit pad VectorAdd( checkSpot, ent->r.mins, mins ); VectorAdd( checkSpot, ent->r.maxs, maxs ); for ( i=0 ; i<num ; i++ ) { hit = &g_entities[touch[i]]; if ( hit->s.eType != ET_PUSH_TRIGGER ) { continue; } if ( hit->touch == NULL ) { continue; } if ( !( hit->r.contents & CONTENTS_TRIGGER ) ) { continue; } if ( !trap_EntityContact( mins, maxs, hit ) ) { continue; } memset( &trace, 0, sizeof(trace) ); if ( hit->touch != NULL ) { hit->touch(hit, ent, &trace); } } } }
/* ============ G_TouchTriggers Find all trigger entities that ent's current position touches. Spectators will only interact with teleporters. ============ */ void G_TouchTriggers( gentity_t *ent ) { int i, num; int touch[MAX_GENTITIES]; gentity_t *hit; trace_t trace; vec3_t mins, maxs; vec3_t pmins, pmaxs; static vec3_t range = { 10, 10, 10 }; if( !ent->client ) return; // dead clients don't activate triggers! if( ent->client->ps.stats[ STAT_HEALTH ] <= 0 ) return; BG_FindBBoxForClass( ent->client->ps.stats[ STAT_PCLASS ], pmins, pmaxs, NULL, NULL, NULL ); VectorAdd( ent->client->ps.origin, pmins, mins ); VectorAdd( ent->client->ps.origin, pmaxs, maxs ); VectorSubtract( mins, range, mins ); VectorAdd( maxs, range, maxs ); num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); // can't use ent->absmin, because that has a one unit pad VectorAdd( ent->client->ps.origin, ent->r.mins, mins ); VectorAdd( ent->client->ps.origin, ent->r.maxs, maxs ); for( i = 0; i < num; i++ ) { hit = &g_entities[ touch[ i ] ]; if( !hit->touch && !ent->touch ) continue; if( !( hit->r.contents & CONTENTS_TRIGGER ) ) continue; // ignore most entities if a spectator if( ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) || ( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) || ( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) ) { if( hit->s.eType != ET_TELEPORT_TRIGGER && // this is ugly but adding a new ET_? type will // most likely cause network incompatibilities hit->touch != Touch_DoorTrigger ) { //check for manually triggered doors manualTriggerSpectator( hit, ent ); continue; } } if( !trap_EntityContact( mins, maxs, hit ) ) continue; memset( &trace, 0, sizeof( trace ) ); if( hit->touch ) hit->touch( hit, ent, &trace ); if( ( ent->r.svFlags & SVF_BOT ) && ( ent->touch ) ) ent->touch( ent, hit, &trace ); } // if we didn't touch a jump pad this pmove frame if( ent->client->ps.jumppad_frame != ent->client->ps.pmove_framecount ) { ent->client->ps.jumppad_frame = 0; ent->client->ps.jumppad_ent = 0; } }