qboolean G_RadiusDamage( vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int mod ) { float points, dist; gentity_t *ent; int entityList[ MAX_GENTITIES ]; int numListedEntities; vec3_t mins, maxs; vec3_t v; vec3_t dir; int i, e; qboolean hitClient = qfalse; if ( radius < 1 ) { radius = 1; } for ( i = 0; i < 3; i++ ) { mins[ i ] = origin[ i ] - radius; maxs[ i ] = origin[ i ] + radius; } numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); for ( e = 0; e < numListedEntities; e++ ) { ent = &g_entities[ entityList[ e ] ]; if ( ent == ignore ) { continue; } if ( !ent->takedamage ) { continue; } // find the distance from the edge of the bounding box for ( i = 0; i < 3; i++ ) { if ( origin[ i ] < ent->r.absmin[ i ] ) { v[ i ] = ent->r.absmin[ i ] - origin[ i ]; } else if ( origin[ i ] > ent->r.absmax[ i ] ) { v[ i ] = origin[ i ] - ent->r.absmax[ i ]; } else { v[ i ] = 0; } } dist = VectorLength( v ); if ( dist >= radius ) { continue; } points = damage * ( 1.0 - dist / radius ); if ( G_CanDamage( ent, origin ) ) { VectorSubtract( ent->r.currentOrigin, origin, dir ); // push the center of mass higher than the origin so players // get knocked into the air more dir[ 2 ] += 24; VectorNormalize( dir ); hitClient = qtrue; G_Damage( ent, NULL, attacker, dir, origin, ( int ) points, DAMAGE_RADIUS | DAMAGE_NO_LOCDAMAGE, mod ); } } return hitClient; }
bool G_SelectiveRadiusDamage( vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int mod, int ignoreTeam ) { float points, dist; gentity_t *ent; int entityList[ MAX_GENTITIES ]; int numListedEntities; vec3_t mins, maxs; vec3_t v; int i, e; bool hitClient = false; if ( radius < 1 ) { radius = 1; } for ( i = 0; i < 3; i++ ) { mins[ i ] = origin[ i ] - radius; maxs[ i ] = origin[ i ] + radius; } numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); for ( e = 0; e < numListedEntities; e++ ) { ent = &g_entities[ entityList[ e ] ]; if ( ent == ignore ) { continue; } if ( !ent->takedamage ) { continue; } if ( ent->flags & FL_NOTARGET ) { continue; } // find the distance from the edge of the bounding box for ( i = 0; i < 3; i++ ) { if ( origin[ i ] < ent->r.absmin[ i ] ) { v[ i ] = ent->r.absmin[ i ] - origin[ i ]; } else if ( origin[ i ] > ent->r.absmax[ i ] ) { v[ i ] = origin[ i ] - ent->r.absmax[ i ]; } else { v[ i ] = 0; } } dist = VectorLength( v ); if ( dist >= radius ) { continue; } points = damage * ( 1.0 - dist / radius ); if ( G_CanDamage( ent, origin ) && ent->client && ent->client->pers.team != ignoreTeam ) { hitClient = true; G_Damage( ent, nullptr, attacker, nullptr, origin, ( int ) points, DAMAGE_RADIUS | DAMAGE_NO_LOCDAMAGE, mod ); } } return hitClient; }
qboolean G_SelectiveRadiusDamage( vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int mod, int ignoreTeam ) { float points, dist; gentity_t *ent; int entityList[ MAX_GENTITIES ]; int numListedEntities; vec3_t mins, maxs; vec3_t v; int i, e; qboolean hitClient = qfalse; if ( radius < 1 ) { radius = 1; } for ( i = 0; i < 3; i++ ) { mins[ i ] = origin[ i ] - radius; maxs[ i ] = origin[ i ] + radius; } numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); for ( e = 0; e < numListedEntities; e++ ) { ent = &g_entities[ entityList[ e ] ]; if ( ent == ignore ) { continue; } if ( !ent->takedamage ) { continue; } if ( ent->flags & FL_NOTARGET ) { continue; } // find the distance from the edge of the bounding box for ( i = 0; i < 3; i++ ) { if ( origin[ i ] < ent->r.absmin[ i ] ) { v[ i ] = ent->r.absmin[ i ] - origin[ i ]; } else if ( origin[ i ] > ent->r.absmax[ i ] ) { v[ i ] = origin[ i ] - ent->r.absmax[ i ]; } else { v[ i ] = 0; } } dist = VectorLength( v ); if ( dist >= radius ) { continue; } points = damage * ( 1.0 - dist / radius ); if ( G_CanDamage( ent, origin ) && ent->client && ent->client->pers.team != ignoreTeam ) { hitClient = qtrue; // don't do knockback, since an attack that spares one team is most likely // not based on kinetic energy G_Damage( ent, NULL, attacker, NULL, origin, ( int ) points, DAMAGE_RADIUS | DAMAGE_NO_LOCDAMAGE | DAMAGE_NO_KNOCKBACK, mod ); } } return hitClient; }
bool G_RadiusDamage( vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int dflags, int mod, team_t testHit ) { float points, dist; gentity_t *ent; int entityList[ MAX_GENTITIES ]; int numListedEntities; vec3_t mins, maxs; vec3_t v; vec3_t dir; int i, e; bool hitSomething = false; if ( radius < 1 ) { radius = 1; } for ( i = 0; i < 3; i++ ) { mins[ i ] = origin[ i ] - radius; maxs[ i ] = origin[ i ] + radius; } numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); for ( e = 0; e < numListedEntities; e++ ) { ent = &g_entities[ entityList[ e ] ]; if ( ent == ignore ) { continue; } // find the distance from the edge of the bounding box for ( i = 0; i < 3; i++ ) { if ( origin[ i ] < ent->r.absmin[ i ] ) { v[ i ] = ent->r.absmin[ i ] - origin[ i ]; } else if ( origin[ i ] > ent->r.absmax[ i ] ) { v[ i ] = origin[ i ] - ent->r.absmax[ i ]; } else { v[ i ] = 0; } } dist = VectorLength( v ); if ( dist >= radius ) { continue; } points = damage * ( 1.0 - dist / radius ); if ( G_CanDamage( ent, origin ) ) { if ( testHit == TEAM_NONE ) { VectorSubtract( ent->r.currentOrigin, origin, dir ); // push the center of mass higher than the origin so players // get knocked into the air more dir[ 2 ] += 24; VectorNormalize( dir ); hitSomething = ent->entity->Damage(points, attacker, Vec3::Load(origin), Vec3::Load(dir), (DAMAGE_NO_LOCDAMAGE | dflags), (meansOfDeath_t)mod); } else if ( G_Team( ent ) == testHit && G_Alive( ent ) ) { return true; } } } return hitSomething; }