static int ImpactSlowblob( gentity_t*, trace_t *trace, gentity_t *hitEnt ) { gentity_t *neighbor; int impactFlags = MIB_IMPACT; // put out fires on direct hit hitEnt->entity->Extinguish( ABUILDER_BLOB_FIRE_IMMUNITY ); // put out fires in range // TODO: Iterate over all ignitable entities only neighbor = nullptr; while ( ( neighbor = G_IterateEntitiesWithinRadius( neighbor, trace->endpos, ABUILDER_BLOB_FIRE_STOP_RANGE ) ) ) { if ( neighbor != hitEnt ) { neighbor->entity->Extinguish( ABUILDER_BLOB_FIRE_IMMUNITY ); } } if ( hitEnt->client && hitEnt->client->pers.team == TEAM_HUMANS ) { hitEnt->client->ps.stats[ STAT_STATE ] |= SS_SLOWLOCKED; hitEnt->client->lastSlowTime = level.time; } else if ( hitEnt->s.eType == ET_BUILDABLE && hitEnt->buildableTeam == TEAM_ALIENS ) { impactFlags &= ~MIF_NO_DAMAGE; } return impactFlags; }
/** * @brief Attempts to refill jetpack fuel from a close source. * @return true if fuel was refilled. */ bool G_FindFuel( gentity_t *self ) { gentity_t *neighbor = nullptr; bool foundSource = false; if ( !self || !self->client ) { return false; } // search for fuel source while ( ( neighbor = G_IterateEntitiesWithinRadius( neighbor, self->s.origin, ENTITY_BUY_RANGE ) ) ) { // only friendly, living and powered buildables provide fuel if ( neighbor->s.eType != ET_BUILDABLE || !G_OnSameTeam( self, neighbor ) || !neighbor->spawned || !neighbor->powered || G_Dead( neighbor ) ) { continue; } switch ( neighbor->s.modelindex ) { case BA_H_ARMOURY: foundSource = true; break; } } if ( foundSource ) { return G_RefillFuel( self, true ); } return false; }
/** * @brief Attempts to refill ammo from a close source. * @return Whether ammo was refilled. */ qboolean G_FindAmmo( gentity_t *self ) { gentity_t *neighbor = NULL; qboolean foundSource = qfalse; // don't search for a source if refilling isn't possible if ( !CanUseAmmoRefill( self ) ) { return qfalse; } // search for ammo source while ( ( neighbor = G_IterateEntitiesWithinRadius( neighbor, self->s.origin, ENTITY_BUY_RANGE ) ) ) { // only friendly, living and powered buildables provide ammo if ( neighbor->s.eType != ET_BUILDABLE || !G_OnSameTeam( self, neighbor ) || !neighbor->spawned || !neighbor->powered || neighbor->health <= 0 ) { continue; } switch ( neighbor->s.modelindex ) { case BA_H_ARMOURY: foundSource = qtrue; break; case BA_H_REACTOR: case BA_H_REPEATER: if ( BG_Weapon( self->client->ps.stats[ STAT_WEAPON ] )->usesEnergy ) { foundSource = qtrue; } break; } } if ( foundSource ) { return G_RefillAmmo( self, qtrue ); } return qfalse; }
bool GoalInRange( gentity_t *self, float r ) { gentity_t *ent = nullptr; if ( !BotTargetIsEntity( self->botMind->goal ) ) { return ( Distance( self->s.origin, self->botMind->nav.tpos ) < r ); } while ( ( ent = G_IterateEntitiesWithinRadius( ent, self->s.origin, r ) ) ) { if ( ent == self->botMind->goal.ent ) { return true; } } return false; }
static void FirebombMissileThink( gentity_t *self ) { gentity_t *neighbor, *m; int subMissileNum; vec3_t dir, upwards = { 0.0f, 0.0f, 1.0f }; // ignite alien buildables in range neighbor = NULL; while ( ( neighbor = G_IterateEntitiesWithinRadius( neighbor, self->s.origin, FIREBOMB_IGNITE_RANGE ) ) ) { if ( neighbor->s.eType == ET_BUILDABLE && neighbor->buildableTeam == TEAM_ALIENS && G_LineOfSight( self, neighbor ) ) { G_IgniteBuildable( neighbor, self->parent ); } } // set floor below on fire (assumes the firebomb lays on the floor!) G_SpawnFire( self->s.origin, upwards, self->parent ); // spam fire for ( subMissileNum = 0; subMissileNum < FIREBOMB_SUBMISSILE_COUNT; subMissileNum++ ) { dir[ 0 ] = ( rand() / ( float )RAND_MAX ) - 0.5f; dir[ 1 ] = ( rand() / ( float )RAND_MAX ) - 0.5f; dir[ 2 ] = ( rand() / ( float )RAND_MAX ) * 0.5f; VectorNormalize( dir ); // the submissile's parent is the attacker m = G_SpawnMissile( MIS_FIREBOMB_SUB, self->parent, self->s.origin, dir, NULL, G_FreeEntity, level.time + 10000 ); // randomize missile speed VectorScale( m->s.pos.trDelta, ( rand() / ( float )RAND_MAX ) + 0.5f, m->s.pos.trDelta ); } // explode G_ExplodeMissile( self ); }
static int ImpactFlamer( gentity_t *ent, trace_t *trace, gentity_t *hitEnt ) { gentity_t *neighbor = nullptr; // ignite on direct hit if ( random() < FLAMER_IGNITE_CHANCE ) { hitEnt->entity->Ignite( ent->parent ); } // ignite in radius while ( ( neighbor = G_IterateEntitiesWithinRadius( neighbor, trace->endpos, FLAMER_IGNITE_RADIUS ) ) ) { // we already handled other, since it might not always be in FLAMER_IGNITE_RADIUS due to BBOX sizes if ( neighbor == hitEnt ) { continue; } if ( random() < FLAMER_IGNITE_SPLCHANCE ) { neighbor->entity->Ignite( ent->parent ); } } // set the environment on fire if ( hitEnt->s.number == ENTITYNUM_WORLD ) { if ( random() < FLAMER_LEAVE_FIRE_CHANCE ) { G_SpawnFire( trace->endpos, trace->plane.normal, ent->parent ); } } return MIB_IMPACT; }