コード例 #1
0
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;
}
コード例 #2
0
/**
 * @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;
}
コード例 #3
0
ファイル: g_weapon.cpp プロジェクト: Xecantur/Unvanquished
/**
 * @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;
}
コード例 #4
0
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;
}
コード例 #5
0
ファイル: g_weapon.cpp プロジェクト: Xecantur/Unvanquished
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 );
}
コード例 #6
0
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;
}