Example #1
0
qboolean AI_ValidateNoEnemyGroupMember( AIGroupInfo_t *group, gentity_t *member )
{
	if ( !group )
	{
		return qfalse;
	}
	vec3_t center;
	if ( group->commander )
	{
		VectorCopy( group->commander->currentOrigin, center );
	}
	else
	{//hmm, just pick the first member
		if ( group->member[0].number < 0 || group->member[0].number >= ENTITYNUM_WORLD )
		{
			return qfalse;
		}
		VectorCopy( g_entities[group->member[0].number].currentOrigin, center );
	}
	//FIXME: maybe it should be based on the center of the mass of the group, not the commander?
	if ( DistanceSquared( center, member->currentOrigin ) > 147456/*384*384*/ )
	{
		return qfalse;
	}
	if ( !gi.inPVS( member->currentOrigin, center ) )
	{//not within PVS of the group enemy
		return qfalse;
	}
	return qtrue;
}
Example #2
0
/*
=================
S_Base_HearingThroughEntity

Also see S_AL_HearingThroughEntity
=================
*/
static qboolean S_Base_HearingThroughEntity( int entityNum, const vec3_t origin )
{
	float	distanceSq;
	vec3_t	sorigin;

	if (origin)
		VectorCopy(origin, sorigin);
	else
		VectorCopy(loopSounds[entityNum].origin, sorigin);

	if( listener_number == entityNum )
	{
		// This is an outrageous hack to detect
		// whether or not the player is rendering in third person or not. We can't
		// ask the renderer because the renderer has no notion of entities and we
		// can't ask cgame since that would involve changing the API and hence mod
		// compatibility. I don't think there is any way around this, but I'll leave
		// the FIXME just in case anyone has a bright idea.
		distanceSq = DistanceSquared(
				sorigin,
				listener_origin );

		if( distanceSq > THIRD_PERSON_THRESHOLD_SQ )
			return qfalse; //we're the player, but third person
		else
			return qtrue;  //we're the player
	}
	else
		return qfalse; //not the player
}
Example #3
0
float CVector3::LengthSquared()
{
	float result;
	Vector3 thisV3 = { X, Y, Z };
	DistanceSquared(thisV3, zero, result);
	return result;
}
Example #4
0
/*
===========
Team_GetLocation

Report a location for the player. Uses placed nearby target_location entities
============
*/
gentity_t *Team_GetLocation( gentity_t *ent )
{
	gentity_t *eloc, *best;
	float     bestlen, len;

	best = NULL;
	bestlen = 3.0f * 8192.0f * 8192.0f;

	for ( eloc = level.locationHead; eloc; eloc = eloc->nextPathSegment )
	{
		len = DistanceSquared( ent->r.currentOrigin, eloc->r.currentOrigin );

		if ( len > bestlen )
		{
			continue;
		}

		if ( !trap_InPVS( ent->r.currentOrigin, eloc->r.currentOrigin ) )
		{
			continue;
		}

		bestlen = len;
		best = eloc;
	}

	return best;
}
Example #5
0
void Rancor_Smash( void )
{
	int			radiusEntNums[128];
	int			numEnts;
	const float	radius = 128;
	const float	halfRadSquared = ((radius/2)*(radius/2));
	const float	radiusSquared = (radius*radius);
	float		distSq;
	int			i;
	vec3_t		boltOrg;

	AddSoundEvent( NPC, NPC->r.currentOrigin, 512, AEL_DANGER, qfalse );//, qtrue );

	numEnts = NPC_GetEntsNearBolt( radiusEntNums, radius, NPC->client->renderInfo.handLBolt, boltOrg );

	for ( i = 0; i < numEnts; i++ )
	{
		gentity_t *radiusEnt = &g_entities[radiusEntNums[i]];
		if ( !radiusEnt->inuse )
		{
			continue;
		}
		
		if ( radiusEnt == NPC )
		{//Skip the rancor ent
			continue;
		}
		
		if ( radiusEnt->client == NULL )
		{//must be a client
			continue;
		}

		if ( (radiusEnt->client->ps.eFlags2&EF2_HELD_BY_MONSTER) )
		{//can't be one being held
			continue;
		}
		
		distSq = DistanceSquared( radiusEnt->r.currentOrigin, boltOrg );
		if ( distSq <= radiusSquared )
		{
			G_Sound( radiusEnt, CHAN_AUTO, G_SoundIndex( "sound/chars/rancor/swipehit.wav" ) );
			if ( distSq < halfRadSquared )
			{//close enough to do damage, too
				G_Damage( radiusEnt, NPC, NPC, vec3_origin, radiusEnt->r.currentOrigin, Q_irand( 10, 25 ), DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK, MOD_MELEE );
			}
			if ( radiusEnt->health > 0 
				&& radiusEnt->client
				&& radiusEnt->client->NPC_class != CLASS_RANCOR
				&& radiusEnt->client->NPC_class != CLASS_ATST )
			{
				if ( distSq < halfRadSquared 
					|| radiusEnt->client->ps.groundEntityNum != ENTITYNUM_NONE )
				{//within range of my fist or withing ground-shaking range and not in the air
					G_Knockdown( radiusEnt );//, NPC, vec3_origin, 100, qtrue );
				}
			}
		}
	}
}
Example #6
0
qboolean NAVNEW_ResolveEntityCollision( gentity_t *self, gentity_t *blocker, vec3_t movedir, vec3_t pathDir, qboolean setBlockedInfo )
{
	vec3_t	blocked_dir;
	float blocked_dist;

	//Doors are ignored
	if ( Q_stricmp( blocker->classname, "func_door" ) == 0 )
	{
		vec3_t center;
		CalcTeamDoorCenter ( blocker, center );
		if ( DistanceSquared( self->r.currentOrigin, center ) > MIN_DOOR_BLOCK_DIST_SQR )
			return qtrue;
	}

	VectorSubtract( blocker->r.currentOrigin, self->r.currentOrigin, blocked_dir );
	blocked_dist = VectorNormalize( blocked_dir );

	//First, attempt to walk around the blocker or shove him out of the way
	if ( NAVNEW_Bypass( self, blocker, blocked_dir, blocked_dist, movedir, setBlockedInfo ) )
		return qtrue;

	//Can't get around him... see if I'm blocking him too... if so, I need to just keep moving?
	if ( NAVNEW_CheckDoubleBlock( self, blocker, blocked_dir ) )
		return qtrue;

	if ( setBlockedInfo )
	{
		//Complain about it if we can
		NPC_SetBlocked( self, blocker );
	}

	return qfalse;
}
Example #7
0
SVector2 EvadeBehavior::Update(float deltaTime)
{
	SVector2 returnForce = SVector2(0.0f, 0.0f);

	if (mPreviousDestination != SVector2(-1.0f, -1.0f))
	{
		SVector2 targetVelocity = (mpAgent->GetDestination() - mPreviousDestination)/deltaTime;
		float maxSpeed = mpAgent->GetMaxSpeed();

		float distFromTarget = Length(mpAgent->GetDestination() - mpAgent->GetPosition());
		float expectedTime = distFromTarget/maxSpeed;
		mTargetDestination = mpAgent->GetDestination() + targetVelocity * expectedTime;


		// FLEE
		const float panicDistanceSq = maxSpeed * maxSpeed;
		if (DistanceSquared(mpAgent->GetPosition(), mpAgent->GetDestination()) > panicDistanceSq)
		{
			return SVector2( 0, 0);
		}

		SVector2 positionToDestination = mpAgent->GetPosition() - mTargetDestination;
		SVector2 desiredVelocity = Normalize(positionToDestination) * mpAgent->GetMaxSpeed();

		returnForce = desiredVelocity - mpAgent->GetVelocity();
	}

	mPreviousDestination = mpAgent->GetDestination();

	return returnForce;
}
Example #8
0
/*
-------------------------
NPC_CheckSightEvents
-------------------------
*/
static int G_CheckSightEvents( gentity_t *self, int hFOV, int vFOV, float maxSeeDist, int ignoreAlert, qboolean mustHaveOwner, int minAlertLevel )
{
	int	bestEvent = -1;
	int bestAlert = -1;
	int	bestTime = -1;
	float	dist, radius;

	maxSeeDist *= maxSeeDist;
	for ( int i = 0; i < level.numAlertEvents; i++ )
	{
		//are we purposely ignoring this alert?
		if ( i == ignoreAlert )
			continue;
		//We're only concerned about sounds
		if ( level.alertEvents[i].type != AET_SIGHT )
			continue;
		//must be at least this noticable
		if ( level.alertEvents[i].level < minAlertLevel )
			continue;
		//must have an owner?
		if ( mustHaveOwner && !level.alertEvents[i].owner )
			continue;

		//Must be within range
		dist = DistanceSquared( level.alertEvents[i].position, self->currentOrigin );

		//can't see it
		if ( dist > maxSeeDist )
			continue;

		radius = level.alertEvents[i].radius * level.alertEvents[i].radius;
		if ( dist > radius )
			continue;

		//Must be visible
		if ( InFOV( level.alertEvents[i].position, self, hFOV, vFOV ) == qfalse )
			continue;

		if ( G_ClearLOS( self, level.alertEvents[i].position ) == qfalse )
			continue;

		//FIXME: possibly have the light level at this point affect the 
		//			visibility/alert level of this event?  Would also
		//			need to take into account how bright the event
		//			itself is.  A lightsaber would stand out more
		//			in the dark... maybe pass in a light level that
		//			is added to the actual light level at this position?

		//See if this one takes precedence over the previous one
		if ( level.alertEvents[i].level >= bestAlert //higher alert level
			|| (level.alertEvents[i].level==bestAlert&&level.alertEvents[i].timestamp >= bestTime) )//same alert level, but this one is newer
		{//NOTE: equal is better because it's later in the array
			bestEvent = i;
			bestAlert = level.alertEvents[i].level;
			bestTime = level.alertEvents[i].timestamp;
		}
	}

	return bestEvent;
}
Example #9
0
void Rancor_Bite( void )
{
	int			radiusEntNums[128];
	int			numEnts;
	const float	radius = 100;
	const float	radiusSquared = (radius*radius);
	int			i;
	vec3_t		boltOrg;

	numEnts = NPC_GetEntsNearBolt( radiusEntNums, radius, NPC->client->renderInfo.crotchBolt, boltOrg );//was gutBolt?

	for ( i = 0; i < numEnts; i++ )
	{
		gentity_t *radiusEnt = &g_entities[radiusEntNums[i]];
		if ( !radiusEnt->inuse )
		{
			continue;
		}
		
		if ( radiusEnt == NPC )
		{//Skip the rancor ent
			continue;
		}
		
		if ( radiusEnt->client == NULL )
		{//must be a client
			continue;
		}

		if ( (radiusEnt->client->ps.eFlags2&EF2_HELD_BY_MONSTER) )
		{//can't be one already being held
			continue;
		}
		
		if ( DistanceSquared( radiusEnt->r.currentOrigin, boltOrg ) <= radiusSquared )
		{
			G_Damage( radiusEnt, NPC, NPC, vec3_origin, radiusEnt->r.currentOrigin, Q_irand( 15, 30 ), DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK, MOD_MELEE );
			if ( radiusEnt->health <= 0 && radiusEnt->client )
			{//killed them, chance of dismembering
				if ( !Q_irand( 0, 1 ) )
				{//bite something off
					int hitLoc = Q_irand( G2_MODELPART_HEAD, G2_MODELPART_RLEG );
					if ( hitLoc == G2_MODELPART_HEAD )
					{
						NPC_SetAnim( radiusEnt, SETANIM_BOTH, BOTH_DEATH17, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
					}
					else if ( hitLoc == G2_MODELPART_WAIST )
					{
						NPC_SetAnim( radiusEnt, SETANIM_BOTH, BOTH_DEATHBACKWARD2, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
					}
					//radiusEnt->client->dismembered = qfalse;
					//FIXME: the limb should just disappear, cuz I ate it
					G_Dismember( radiusEnt, NPC, radiusEnt->r.currentOrigin, hitLoc, 90, 0, radiusEnt->client->ps.torsoAnim, qtrue);
					//G_DoDismemberment( radiusEnt, radiusEnt->r.currentOrigin, MOD_SABER, 1000, hitLoc, qtrue );
				}
			}
			G_Sound( radiusEnt, CHAN_AUTO, G_SoundIndex( "sound/chars/rancor/chomp.wav" ) );
		}
	}
}
Example #10
0
/*
** SetFarClip
*/
static void SetFarClip( void )
{
	float	farthestCornerDistance = 0;
	int		i;

	// if not rendering the world (icons, menus, etc)
	// set a 2k far clip plane
	if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
		tr.viewParms.zFar = 2048;
		return;
	}

	//
	// set far clipping planes dynamically
	//
	for ( i = 0; i < 8; i++ )
	{
		vec3_t v;
		float distance;

		if ( i & 1 )
		{
			v[0] = tr.viewParms.visBounds[0][0];
		}
		else
		{
			v[0] = tr.viewParms.visBounds[1][0];
		}

		if ( i & 2 )
		{
			v[1] = tr.viewParms.visBounds[0][1];
		}
		else
		{
			v[1] = tr.viewParms.visBounds[1][1];
		}

		if ( i & 4 )
		{
			v[2] = tr.viewParms.visBounds[0][2];
		}
		else
		{
			v[2] = tr.viewParms.visBounds[1][2];
		}

		distance = DistanceSquared(tr.viewParms.or.origin, v);

		if ( distance > farthestCornerDistance )
		{
			farthestCornerDistance = distance;
		}
	}
	// Bring in the zFar to the distanceCull distance
	// The sky renders at zFar so need to move it out a little
	// ...and make sure there is a minimum zfar to prevent problems
	tr.viewParms.zFar = Com_Clamp(2048.0f, tr.distanceCull * (1.732), sqrtf( farthestCornerDistance ));
}
Example #11
0
Spectrum PointLight::Sample_L(const pbrt::Point &p, float pEpsilon,
         const LightSample &ls, float time, Vector *wi, float *pdf,
         VisibilityTester *visibility) const {
    *wi = Normalize(lightPos - p);
    *pdf = 1.f;
    visibility->SetSegment(p, pEpsilon, lightPos, 0., time);
    return Intensity / DistanceSquared(lightPos, p);
}
Example #12
0
LightInfo ProjectionLight::Sample_L(const Point &p, float pEpsilon,
    const LightSample &ls, float time) const {
    auto wi = Normalize(lightPos - p);
    VisibilityTester visibility;
    visibility.SetSegment(p, pEpsilon, lightPos, 0., time);
    auto L = Intensity * Projection(-wi) / DistanceSquared(lightPos, p);
    return LightInfo{L,wi,1.f,visibility};
}
Example #13
0
/*
================
G_SelectSpawnBuildable

find the nearest buildable of the right type that is
spawned/healthy/unblocked etc.
================
*/
static gentity_t *G_SelectSpawnBuildable( vec3_t preference, buildable_t buildable )
{
	gentity_t *search = nullptr;
	gentity_t *spot = nullptr;

	while ( ( search = G_IterateEntitiesOfClass( search, BG_Buildable( buildable )->entityName ) ) != nullptr )
	{
		if ( !search->spawned )
		{
			continue;
		}

		if ( G_Dead( search ) )
		{
			continue;
		}

		if ( search->s.groundEntityNum == ENTITYNUM_NONE )
		{
			continue;
		}

		if ( search->clientSpawnTime > 0 )
		{
			continue;
		}

		Entity* blocker = nullptr;
		Vec3    spawnPoint;

		search->entity->CheckSpawnPoint(blocker, spawnPoint);

		if (blocker)
		{
			continue;
		}

		if ( !spot || DistanceSquared( preference, search->s.origin ) <
		     DistanceSquared( preference, spot->s.origin ) )
		{
			spot = search;
		}
	}

	return spot;
}
Example #14
0
Spectrum GonioPhotometricLight::Sample_L(const Point &P, float u1, float u2,
		Vector *wo, float *pdf,
		VisibilityTester *visibility) const {
	*wo = Normalize(lightPos - P);
	*pdf = 1.f;
	visibility->SetSegment(P, lightPos);
	return Intensity * Scale(-*wo) / DistanceSquared(lightPos, P);
}
Example #15
0
Spectrum SpotLight::Sample_Li(const Interaction &ref, const Point2f &u,
                              Vector3f *wi, Float *pdf,
                              VisibilityTester *vis) const {
    *wi = Normalize(pLight - ref.p);
    *pdf = 1.f;
    *vis = VisibilityTester(ref, Interaction(pLight, ref.time, medium));
    return intensity * Falloff(-*wi) / DistanceSquared(pLight, ref.p);
}
Example #16
0
void Bot::CheckAlertSpots(const StaticVector<edict_t *, MAX_CLIENTS> &visibleTargets)
{
    float scores[MAX_ALERT_SPOTS];

    // First compute scores (good for instruction cache)
    for (unsigned i = 0; i < alertSpots.size(); ++i)
    {
        float score = 0.0f;
        const auto &alertSpot = alertSpots[i];
        const float squareRadius = alertSpot.radius * alertSpot.radius;
        const float invRadius = 1.0f / alertSpot.radius;
        for (const edict_t *ent: visibleTargets)
        {
            float squareDistance = DistanceSquared(ent->s.origin, alertSpot.origin.Data());
            if (squareDistance > squareRadius)
                continue;
            float distance = Q_RSqrt(squareDistance + 0.001f);
            score += 1.0f - distance * invRadius;
            // Put likely case first
            if (!(ent->s.effects & EF_CARRIER))
                score *= alertSpot.regularEnemyInfluenceScale;
            else
                score *= alertSpot.carrierEnemyInfluenceScale;
        }
        // Clamp score by a max value
        clamp_high(score, 3.0f);
        // Convert score to [0, 1] range
        score /= 3.0f;
        // Get a square root of score (values closer to 0 gets scaled more than ones closer to 1)
        score = 1.0f / Q_RSqrt(score + 0.001f);
        // Sanitize
        clamp(score, 0.0f, 1.0f);
        scores[i] = score;
    }

    // Then call callbacks
    const unsigned levelTime = level.time;
    for (unsigned i = 0; i < alertSpots.size(); ++i)
    {
        auto &alertSpot = alertSpots[i];
        unsigned nonReportedFor = levelTime - alertSpot.lastReportedAt;
        if (nonReportedFor >= 1000)
            alertSpot.lastReportedScore = 0.0f;

        // Since scores are sanitized, they are in range [0.0f, 1.0f], and abs(scoreDelta) is in range [-1.0f, 1.0f];
        float scoreDelta = scores[i] - alertSpot.lastReportedScore;
        if (scoreDelta >= 0)
        {
            if (nonReportedFor >= 1000 - scoreDelta * 500)
                alertSpot.Alert(this, scores[i]);
        }
        else
        {
            if (nonReportedFor >= 500 - scoreDelta * 500)
                alertSpot.Alert(this, scores[i]);
        }
    }
}
Example #17
0
Interaction Sphere::Sample(const Interaction &ref, const Point2f &u) const {
    // Compute coordinate system for sphere sampling
    Point3f pCenter = (*ObjectToWorld)(Point3f(0, 0, 0));
    Vector3f wc = Normalize(pCenter - ref.p);
    Vector3f wcX, wcY;
    CoordinateSystem(wc, &wcX, &wcY);

    // Sample uniformly on sphere if $\pt{}$ is inside it
    Point3f pOrigin =
        OffsetRayOrigin(ref.p, ref.pError, ref.n, pCenter - ref.p);
    if (DistanceSquared(pOrigin, pCenter) <= radius * radius) return Sample(u);

    // Sample sphere uniformly inside subtended cone

    // Compute $\theta$ and $\phi$ values for sample in cone
    Float sinThetaMax2 = radius * radius / DistanceSquared(ref.p, pCenter);
    Float cosThetaMax = std::sqrt(std::max((Float)0, 1 - sinThetaMax2));
    Float cosTheta = (1 - u[0]) + u[0] * cosThetaMax;
    Float sinTheta = std::sqrt(1 - cosTheta * cosTheta);
    Float phi = u[1] * 2 * Pi;

    // Compute angle $\alpha$ from center of sphere to sampled point on surface
    Float dc = Distance(ref.p, pCenter);
    Float ds = dc * cosTheta -
               std::sqrt(std::max(
                   (Float)0, radius * radius - dc * dc * sinTheta * sinTheta));
    Float cosAlpha = (dc * dc + radius * radius - ds * ds) / (2 * dc * radius);
    Float sinAlpha = std::sqrt(std::max((Float)0, 1 - cosAlpha * cosAlpha));

    // Compute surface normal and sampled point on sphere
    Vector3f nObj =
        SphericalDirection(sinAlpha, cosAlpha, phi, -wcX, -wcY, -wc);
    Point3f pObj = radius * Point3f(nObj.x, nObj.y, nObj.z);

    // Return _Interaction_ for sampled point on sphere
    Interaction it;

    // Reproject _pObj_ to sphere surface and compute _pObjError_
    pObj *= radius / Distance(pObj, Point3f(0, 0, 0));
    Vector3f pObjError = gamma(5) * Abs((Vector3f)pObj);
    it.p = (*ObjectToWorld)(pObj, pObjError, &it.pError);
    it.n = (*ObjectToWorld)(Normal3f(nObj));
    if (reverseOrientation) it.n *= -1.f;
    return it;
}
Example #18
0
static float AStarHeuristic(void *fromNode, void *toNode, void *context)
{
    // Simple Euclidean
    Vec2i *v1 = fromNode;
    Vec2i *v2 = toNode;
    UNUSED(context);
    return (float)sqrt(DistanceSquared(
                           Vec2iCenterOfTile(*v1), Vec2iCenterOfTile(*v2)));
}
Example #19
0
// GonioPhotometricLight Method Definitions
Spectrum GonioPhotometricLight::Sample_L(const Interaction &ref,
                                         const Point2f &sample, Vector3f *wi,
                                         Float *pdf,
                                         VisibilityTester *vis) const {
    *wi = Normalize(pLight - ref.p);
    *pdf = 1.f;
    *vis = VisibilityTester(ref, Interaction(pLight, ref.time, medium));
    return intensity * Scale(-*wi) / DistanceSquared(pLight, ref.p);
}
Example #20
0
/*
================
G_SelectSpawnBuildable

find the nearest buildable of the right type that is
spawned/healthy/unblocked etc.
================
*/
static gentity_t *G_SelectSpawnBuildable( vec3_t preference, buildable_t buildable )
{
	gentity_t *search, *spot;

	search = spot = NULL;

	while ( ( search = G_Find( search, FOFS( classname ),
	                           BG_Buildable( buildable )->entityName ) ) != NULL )
	{
		if ( !search->spawned )
		{
			continue;
		}

		if ( search->health <= 0 )
		{
			continue;
		}

		if ( search->s.groundEntityNum == ENTITYNUM_NONE )
		{
			continue;
		}

		if ( search->clientSpawnTime > 0 )
		{
			continue;
		}

		if ( G_CheckSpawnPoint( search->s.number, search->s.origin,
		                        search->s.origin2, buildable, NULL ) != NULL )
		{
			continue;
		}

		if ( !spot || DistanceSquared( preference, search->s.origin ) <
		     DistanceSquared( preference, spot->s.origin ) )
		{
			spot = search;
		}
	}

	return spot;
}
Example #21
0
// not 100% sure how this one should work and PVP affects ...
void Aura::ProcessOnAllFriendlies(Mob *owner)
{
	auto &mob_list = entity_list.GetMobList(); // read only reference so we can do it all inline
	std::set<int> delayed_remove;
	bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter

	for (auto &e : mob_list) {
		auto mob = e.second;
		if (mob->IsClient() || mob->IsPetOwnerClient() || mob->IsMerc()) {
			auto it = casted_on.find(mob->GetID());

			if (it != casted_on.end()) { // we are already on the list, let's check for removal
				if (DistanceSquared(GetPosition(), mob->GetPosition()) > distance)
					delayed_remove.insert(mob->GetID());
			} else { // not on list, lets check if we're in range
				if (DistanceSquared(GetPosition(), mob->GetPosition()) <= distance) {
					casted_on.insert(mob->GetID());
					if (is_buff)
						SpellFinished(spell_id, mob);
				}
			}
		}
	}

	for (auto &e : delayed_remove) {
		auto mob = entity_list.GetMob(e);
		if (mob != nullptr && is_buff) // some auras cast instant spells so no need to remove
			mob->BuffFadeBySpellIDAndCaster(spell_id, GetID());
		casted_on.erase(e);
	}

	// so if we have a cast timer and our set isn't empty and timer is disabled we need to enable it
	if (cast_timer.GetDuration() > 0 && !cast_timer.Enabled() && !casted_on.empty())
		cast_timer.Start();

	if (!cast_timer.Enabled() || !cast_timer.Check())
		return;

	for (auto &e : casted_on) {
		auto mob = entity_list.GetMob(e);
		if (mob != nullptr)
			SpellFinished(spell_id, mob);
	}
}
Example #22
0
Spectrum ProjectionLight::Sample_Li(const Interaction &ref, const Point2f &u,
                                    Vector3f *wi, Float *pdf,
                                    VisibilityTester *vis) const {
    ProfilePhase _(Prof::LightSample);
    *wi = Normalize(pLight - ref.p);
    *pdf = 1;
    *vis =
        VisibilityTester(ref, Interaction(pLight, ref.time, mediumInterface));
    return I * Projection(-*wi) / DistanceSquared(pLight, ref.p);
}
Example #23
0
/*
-------------------------
NPC_CheckSoundEvents
-------------------------
*/
static int G_CheckSoundEvents( gentity_t *self, float maxHearDist, int ignoreAlert, qboolean mustHaveOwner, int minAlertLevel )
{
	int	bestEvent = -1;
	int bestAlert = -1;
	int	bestTime = -1;
	int i;
	float dist, radius;

	maxHearDist *= maxHearDist;

	for ( i = 0; i < level.numAlertEvents; i++ )
	{
		//are we purposely ignoring this alert?
		if ( i == ignoreAlert )
			continue;
		//We're only concerned about sounds
		if ( level.alertEvents[i].type != AET_SOUND )
			continue;
		//must be at least this noticable
		if ( level.alertEvents[i].level < minAlertLevel )
			continue;
		//must have an owner?
		if ( mustHaveOwner && !level.alertEvents[i].owner )
			continue;
		//Must be within range
		dist = DistanceSquared( level.alertEvents[i].position, self->r.currentOrigin );

		//can't hear it
		if ( dist > maxHearDist )
			continue;

		radius = level.alertEvents[i].radius * level.alertEvents[i].radius;
		if ( dist > radius )
			continue;

		if ( level.alertEvents[i].addLight )
		{//a quiet sound, must have LOS to hear it
			if ( G_ClearLOS5( self, level.alertEvents[i].position ) == qfalse )
			{//no LOS, didn't hear it
				continue;
			}
		}

		//See if this one takes precedence over the previous one
		if ( level.alertEvents[i].level >= bestAlert //higher alert level
			|| (level.alertEvents[i].level==bestAlert&&level.alertEvents[i].timestamp >= bestTime) )//same alert level, but this one is newer
		{//NOTE: equal is better because it's later in the array
			bestEvent = i;
			bestAlert = level.alertEvents[i].level;
			bestTime = level.alertEvents[i].timestamp;
		}
	}

	return bestEvent;
}
Example #24
0
            // Return the closest pathgrid point index from the specified position
            // coordinates.  NOTE: Does not check if there is a sensible way to get there
            // (e.g. a cliff in front).
            //
            // NOTE: pos is expected to be in local coordinates, as is grid->mPoints
            //
            static int GetClosestPoint(const ESM::Pathgrid* grid, const osg::Vec3f& pos)
            {
                assert(grid && !grid->mPoints.empty());

                float distanceBetween = DistanceSquared(grid->mPoints[0], pos);
                int closestIndex = 0;

                // TODO: if this full scan causes performance problems mapping pathgrid
                //       points to a quadtree may help
                for(unsigned int counter = 1; counter < grid->mPoints.size(); counter++)
                {
                    float potentialDistBetween = DistanceSquared(grid->mPoints[counter], pos);
                    if(potentialDistBetween < distanceBetween)
                    {
                        distanceBetween = potentialDistBetween;
                        closestIndex = counter;
                    }
                }

                return closestIndex;
            }
Example #25
0
/*
==============
IsHeadShotWeapon
==============
*/
qboolean IsHeadShotWeapon( int mod, gentity_t *targ, gentity_t *attacker ) {
	// distance rejection
	if ( DistanceSquared( targ->r.currentOrigin, attacker->r.currentOrigin )  >  ( g_headshotMaxDist.integer * g_headshotMaxDist.integer ) ) {
		return qfalse;
	}

	if ( attacker->aiCharacter ) {
		// ai's are always allowed headshots from these weapons
		if ( mod == MOD_SNIPERRIFLE ||
			 mod == MOD_SNOOPERSCOPE ) {
			return qtrue;
		}

		if ( g_gameskill.integer != GSKILL_MAX ) {
			// ai's allowed headshots in skill==GSKILL_MAX
			return qfalse;
		}
	}

	switch ( targ->aiCharacter ) {
		// get out quick for ai's that don't take headshots
	case AICHAR_ZOMBIE:
	case AICHAR_WARZOMBIE:
	case AICHAR_HELGA:      // boss1 (beast)
	case AICHAR_LOPER:
	case AICHAR_VENOM:      //----(SA)	added
		return qfalse;
	default:
		break;
	}

	switch ( mod ) {
		// players are allowed headshots from these weapons
	case MOD_LUGER:
	case MOD_COLT:
	case MOD_AKIMBO:
	case MOD_MP40:
	case MOD_THOMPSON:
	case MOD_STEN:
	case MOD_BAR:
	case MOD_FG42:
	case MOD_MAUSER:
	case MOD_GARAND:
	case MOD_SILENCER:
	case MOD_FG42SCOPE:
	case MOD_SNOOPERSCOPE:
	case MOD_SNIPERRIFLE:
		return qtrue;
	}

	return qfalse;
}
Example #26
0
void EntityList::DescribeAggro(Client *towho, NPC *from_who, float d, bool verbose) {
	float d2 = d*d;

	towho->Message(0, "Describing aggro for %s", from_who->GetName());

	bool engaged = from_who->IsEngaged();
	if(engaged) {
		Mob *top = from_who->GetHateTop();
		towho->Message(0, ".. I am currently fighting with %s", top == nullptr?"(nullptr)":top->GetName());
	}
	bool check_npcs = from_who->WillAggroNPCs();

	if(verbose) {
		char namebuf[256];

		int my_primary = from_who->GetPrimaryFaction();
		Mob *own = from_who->GetOwner();
		if(own != nullptr)
			my_primary = own->GetPrimaryFaction();

		if(my_primary == 0) {
			strcpy(namebuf, "(No faction)");
		} else if(my_primary < 0) {
			strcpy(namebuf, "(Special faction)");
		} else {
			if(!database.GetFactionName(my_primary, namebuf, sizeof(namebuf)))
				strcpy(namebuf, "(Unknown)");
		}
		towho->Message(0, ".. I am on faction %s (%d)\n", namebuf, my_primary);
	}

	for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
		Mob *mob = it->second;
		if (mob->IsClient())	//also ensures that mob != around
			continue;

		if (DistanceSquared(mob->GetPosition(), from_who->GetPosition()) > d2)
			continue;

		if (engaged) {
			uint32 amm = from_who->GetHateAmount(mob);
			if (amm == 0)
				towho->Message(0, "... %s is not on my hate list.", mob->GetName());
			else
				towho->Message(0, "... %s is on my hate list with value %lu", mob->GetName(), (unsigned long)amm);
		} else if (!check_npcs && mob->IsNPC()) {
				towho->Message(0, "... %s is an NPC and my npc_aggro is disabled.", mob->GetName());
		} else {
			from_who->DescribeAggro(towho, mob, verbose);
		}
	}
}
real64 MaxSquaredDistancePointToRect (const dng_point_real64 &point,
									  const dng_rect_real64 &rect)
	{
	
	real64 distSqr = DistanceSquared (point, 
									  rect.TL ());

	distSqr = Max_real64 (distSqr,
						  DistanceSquared (point, 
										   rect.BL ()));

	distSqr = Max_real64 (distSqr,
						  DistanceSquared (point, 
										   rect.BR ()));

	distSqr = Max_real64 (distSqr,
						  DistanceSquared (point, 
										   rect.TR ()));

	return distSqr;
	
	}
Example #28
0
int DistanceToGoalSquared( gentity_t *self )
{
	vec3_t targetPos;
	vec3_t selfPos;
	//safety check for morons who use this incorrectly
	if ( !( self->botMind ) )
	{
		return -1;
	}
	BotGetTargetPos( self->botMind->goal, targetPos );
	VectorCopy( self->s.origin, selfPos );
	return DistanceSquared( selfPos, targetPos );
}
Example #29
0
// solar: causes caster to hit every mob within dist range of center with
// a bard pulse of spell_id.
// NPC spells will only affect other NPCs with compatible faction
void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
{
    Mob *curmob;

    float dist = caster->GetAOERange(spell_id);
    float dist2 = dist * dist;

    bool bad = IsDetrimentalSpell(spell_id);
    bool isnpc = caster->IsNPC();

    for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
        curmob = it->second;
        if (curmob == center)	//do not affect center
            continue;
        if (curmob == caster && !affect_caster)	//watch for caster too
            continue;
        if (DistanceSquared(center->GetPosition(), curmob->GetPosition()) > dist2)	//make sure they are in range
            continue;
        if (isnpc && curmob->IsNPC()) {	//check npc->npc casting
            FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
            if (bad) {
                //affect mobs that are on our hate list, or
                //which have bad faction with us
                if (!(caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
                    continue;
            } else {
                //only affect mobs we would assist.
                if (!(f <= FACTION_AMIABLE))
                    continue;
            }
        }
        //finally, make sure they are within range
        if (bad) {
            if (!center->CheckLosFN(curmob))
                continue;
        } else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
            // See notes in AESpell() above for more info.
            if (caster->IsAttackAllowed(curmob, true))
                continue;
            if (caster->CheckAggro(curmob))
                continue;

            AddHealAggro(curmob, caster, caster->CheckHealAggroAmount(spell_id, curmob));
        }

        //if we get here... cast the spell.
        curmob->BardPulse(spell_id, caster);
    }
    if (caster->IsClient())
        caster->CastToClient()->CheckSongSkillIncrease(spell_id);
}
Example #30
0
float Shape::Pdf(const Point &p, const Vector &wi) const {
    // Intersect sample ray with area light geometry
    DifferentialGeometry dgLight;
    Ray ray(p, wi, 1e-3f);
    ray.depth = -1; // temporary hack to ignore alpha mask
    float thit, rayEpsilon;
    if (!Intersect(ray, &thit, &rayEpsilon, &dgLight)) return 0.;

    // Convert light sample weight to solid angle measure
    float pdf = DistanceSquared(p, ray(thit)) /
                (AbsDot(dgLight.nn, -wi) * Area());
    if (isinf(pdf)) pdf = 0.f;
    return pdf;
}