Esempio n. 1
0
qboolean G_CheckPounceAttack( gentity_t *self )
{
	trace_t   tr;
	gentity_t *traceEnt;
	int       damage, timeMax, pounceRange, payload;

	if ( self->client->pmext.pouncePayload <= 0 )
	{
		return qfalse;
	}

	// In case the goon lands on his target, he gets one shot after landing
	payload = self->client->pmext.pouncePayload;

	if ( !( self->client->ps.pm_flags & PMF_CHARGE ) )
	{
		self->client->pmext.pouncePayload = 0;
	}

	// Calculate muzzle point
	AngleVectors( self->client->ps.viewangles, forward, right, up );
	G_CalcMuzzlePoint( self, forward, right, up, muzzle );

	// Trace from muzzle to see what we hit
	pounceRange = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_RANGE :
	              LEVEL3_POUNCE_UPG_RANGE;
	G_WideTrace( &tr, self, pounceRange, LEVEL3_POUNCE_WIDTH,
	             LEVEL3_POUNCE_WIDTH, &traceEnt );

	if ( traceEnt == NULL )
	{
		return qfalse;
	}

	// Send blood impact
	if ( traceEnt->takedamage )
	{
		SendMeleeHitEvent( self, traceEnt, &tr );
	}

	if ( !traceEnt->takedamage )
	{
		return qfalse;
	}

	// Deal damage
	timeMax = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_TIME :
	          LEVEL3_POUNCE_TIME_UPG;
	damage = payload * LEVEL3_POUNCE_DMG / timeMax;
	self->client->pmext.pouncePayload = 0;
	G_Damage( traceEnt, self, self, forward, tr.endpos, damage,
	          DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE );

	return qtrue;
}
Esempio n. 2
0
void G_ChargeAttack( gentity_t *self, gentity_t *victim )
{
	int    damage;
	int    i;
	vec3_t forward;

	if ( !self->client || self->client->ps.stats[ STAT_MISC ] <= 0 ||
	     !( self->client->ps.stats[ STAT_STATE ] & SS_CHARGING ) ||
	     self->client->ps.weaponTime )
	{
		return;
	}

	VectorSubtract( victim->s.origin, self->s.origin, forward );
	VectorNormalize( forward );

	if ( !victim->takedamage )
	{
		return;
	}

	// For buildables, track the last MAX_TRAMPLE_BUILDABLES_TRACKED buildables
	//  hit, and do not do damage if the current buildable is in that list
	//  in order to prevent dancing over stuff to kill it very quickly
	if ( !victim->client )
	{
		for ( i = 0; i < MAX_TRAMPLE_BUILDABLES_TRACKED; i++ )
		{
			if ( self->client->trampleBuildablesHit[ i ] == victim - g_entities )
			{
				return;
			}
		}

		self->client->trampleBuildablesHit[
		  self->client->trampleBuildablesHitPos++ % MAX_TRAMPLE_BUILDABLES_TRACKED ] =
		    victim - g_entities;
	}

	SendMeleeHitEvent( self, victim, NULL );

	damage = LEVEL4_TRAMPLE_DMG * self->client->ps.stats[ STAT_MISC ] /
	         LEVEL4_TRAMPLE_DURATION;

	G_Damage( victim, self, self, forward, victim->s.origin, damage,
	          DAMAGE_NO_LOCDAMAGE, MOD_LEVEL4_TRAMPLE );

	self->client->ps.weaponTime += LEVEL4_TRAMPLE_REPEAT;
}
Esempio n. 3
0
static gentity_t *FireMelee( gentity_t *self, float range, float width, float height,
                             int damage, meansOfDeath_t mod )
{
	trace_t   tr;
	gentity_t *traceEnt;

	G_WideTrace( &tr, self, range, width, height, &traceEnt );

	if ( traceEnt != NULL && traceEnt->takedamage )
	{
		SendMeleeHitEvent( self, traceEnt, &tr );

		G_Damage( traceEnt, self, self, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, mod );
	}

	return traceEnt;
}
Esempio n. 4
0
qboolean G_CheckVenomAttack( gentity_t *self )
{
	trace_t   tr;
	gentity_t *traceEnt;
	int       damage = LEVEL0_BITE_DMG;

	if ( self->client->ps.weaponTime )
	{
		return qfalse;
	}

	// Calculate muzzle point
	AngleVectors( self->client->ps.viewangles, forward, right, up );
	G_CalcMuzzlePoint( self, forward, right, up, muzzle );

	G_WideTrace( &tr, self, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt );

	if ( !traceEnt || !traceEnt->takedamage || traceEnt->health <= 0 ||
	     G_OnSameTeam( self, traceEnt ) )
	{
		return qfalse;
	}

	// only allow bites to work against turrets or buildables in construction
	if ( traceEnt->s.eType == ET_BUILDABLE && traceEnt->spawned )
	{
		switch ( traceEnt->s.modelindex )
		{
			case BA_H_MGTURRET:
			case BA_H_TESLAGEN:
				break;

			default:
				return qfalse;
		}
	}

	SendMeleeHitEvent( self, traceEnt, &tr );

	G_Damage( traceEnt, self, self, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK,
	          MOD_LEVEL0_BITE );

	self->client->ps.weaponTime += LEVEL0_BITE_REPEAT;

	return qtrue;
}
Esempio n. 5
0
bool G_CheckPounceAttack( gentity_t *self )
{
	trace_t   tr;
	gentity_t *traceEnt;
	int       damage, timeMax, pounceRange, payload;

	if ( self->client->pmext.pouncePayload <= 0 )
	{
		return false;
	}

	// In case the goon lands on his target, he gets one shot after landing
	payload = self->client->pmext.pouncePayload;

	if ( !( self->client->ps.pm_flags & PMF_CHARGE ) )
	{
		self->client->pmext.pouncePayload = 0;
	}

	// Calculate muzzle point
	AngleVectors( self->client->ps.viewangles, forward, right, up );
	G_CalcMuzzlePoint( self, forward, right, up, muzzle );

	// Trace from muzzle to see what we hit
	pounceRange = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_RANGE :
	              LEVEL3_POUNCE_UPG_RANGE;
	G_WideTrace( &tr, self, pounceRange, LEVEL3_POUNCE_WIDTH,
	             LEVEL3_POUNCE_WIDTH, &traceEnt );

	if ( !G_Alive( traceEnt ) )
	{
		return false;
	}

	timeMax = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_TIME : LEVEL3_POUNCE_TIME_UPG;
	damage  = payload * LEVEL3_POUNCE_DMG / timeMax;

	self->client->pmext.pouncePayload = 0;

	traceEnt->entity->Damage((float)damage, self, Vec3::Load(tr.endpos), Vec3::Load(forward),
	                         DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE);

	SendMeleeHitEvent( self, traceEnt, &tr );

	return true;
}
Esempio n. 6
0
static gentity_t *FireMelee( gentity_t *self, float range, float width, float height,
                             int damage, meansOfDeath_t mod )
{
	trace_t   tr;
	gentity_t *traceEnt;

	G_WideTrace( &tr, self, range, width, height, &traceEnt );

	if ( !G_Alive( traceEnt ) )
	{
		return nullptr;
	}

	traceEnt->entity->Damage((float)damage, self, Vec3::Load(tr.endpos),
		                     Vec3::Load(forward), 0, (meansOfDeath_t)mod);

	SendMeleeHitEvent( self, traceEnt, &tr );

	return traceEnt;
}
Esempio n. 7
0
bool G_CheckVenomAttack( gentity_t *self )
{
	trace_t   tr;
	gentity_t *traceEnt;
	int       damage = LEVEL0_BITE_DMG;

	if ( self->client->ps.weaponTime )
	{
		return false;
	}

	// Calculate muzzle point
	AngleVectors( self->client->ps.viewangles, forward, right, up );
	G_CalcMuzzlePoint( self, forward, right, up, muzzle );

	G_WideTrace( &tr, self, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt );

	if ( !traceEnt || !traceEnt->takedamage || traceEnt->health <= 0 ||
	     G_OnSameTeam( self, traceEnt ) )
	{
		return false;
	}

	// only allow bites to work against buildables in construction
	if ( traceEnt->s.eType == ET_BUILDABLE && traceEnt->spawned )
	{
		return false;
	}

	SendMeleeHitEvent( self, traceEnt, &tr );

	G_Damage( traceEnt, self, self, forward, tr.endpos, damage, 0, MOD_LEVEL0_BITE );

	self->client->ps.weaponTime += LEVEL0_BITE_REPEAT;

	return true;
}
Esempio n. 8
0
bool G_CheckVenomAttack( gentity_t *self )
{
	trace_t   tr;
	gentity_t *traceEnt;

	if ( self->client->ps.weaponTime )
	{
		return false;
	}

	// Calculate muzzle point
	AngleVectors( self->client->ps.viewangles, forward, right, up );
	G_CalcMuzzlePoint( self, forward, right, up, muzzle );

	G_WideTrace( &tr, self, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt );

	if ( !G_Alive( traceEnt ) || G_OnSameTeam( self, traceEnt ) )
	{
		return false;
	}

	// only allow bites to work against buildables in construction
	if ( traceEnt->s.eType == ET_BUILDABLE && traceEnt->spawned )
	{
		return false;
	}

	traceEnt->entity->Damage((float)LEVEL0_BITE_DMG, self, Vec3::Load(tr.endpos),
	                         Vec3::Load(forward), 0, (meansOfDeath_t)MOD_LEVEL0_BITE);

	SendMeleeHitEvent( self, traceEnt, &tr );

	self->client->ps.weaponTime += LEVEL0_BITE_REPEAT;

	return true;
}