コード例 #1
0
ファイル: g_weapon.c プロジェクト: Kaperstone/warsow
/*
* W_Touch_Plasma
*/
static void W_Touch_Plasma( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags )
{
	int hitType;
	vec3_t dir;

	if( surfFlags & SURF_NOIMPACT )
	{
		G_FreeEdict( ent );
		return;
	}

	hitType = G_Projectile_HitStyle( ent, other );
	if( hitType == PROJECTILE_TOUCH_NOT )
		return;

	if( other->takedamage )
	{
		VectorNormalize2( ent->velocity, dir );

		if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) // use hybrid direction from splash and projectile
		{
			G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta );
		}
		else
		{
			VectorNormalize2( ent->velocity, dir );
		}

		G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, ent->projectileInfo.maxDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, DAMAGE_KNOCKBACK_SOFT, ent->style );
	}

	W_Plasma_Explosion( ent, other, plane, surfFlags );
}
コード例 #2
0
ファイル: g_weapon.cpp プロジェクト: Picmip/qfusion
/*
* W_Touch_Rocket
*/
static void W_Touch_Rocket( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags ) {
	int mod_splash;
	vec3_t dir;
	int hitType;

	if( surfFlags & SURF_NOIMPACT ) {
		G_FreeEdict( ent );
		return;
	}

	hitType = G_Projectile_HitStyle( ent, other );
	if( hitType == PROJECTILE_TOUCH_NOT ) {
		return;
	}

	if( other->takedamage ) {
		int directHitDamage = ent->projectileInfo.maxDamage;

		VectorNormalize2( ent->velocity, dir );

		if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) { // use hybrid direction from splash and projectile

			G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta );
		} else {
			VectorNormalize2( ent->velocity, dir );

			if( hitType == PROJECTILE_TOUCH_DIRECTAIRHIT ) {
				directHitDamage += DIRECTAIRTHIT_DAMAGE_BONUS;
			} else if( hitType == PROJECTILE_TOUCH_DIRECTHIT ) {
				directHitDamage += DIRECTHIT_DAMAGE_BONUS;
			}
		}

		G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, directHitDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, 0, ent->style );
	}

	if( ent->s.effects & EF_STRONG_WEAPON ) {
		mod_splash = MOD_ROCKET_SPLASH_S;
	} else {
		mod_splash = MOD_ROCKET_SPLASH_W;
	}

	G_RadiusDamage( ent, ent->r.owner, plane, other, mod_splash );

	// spawn the explosion
	if( !( surfFlags & SURF_NOIMPACT ) ) {
		edict_t *event;
		vec3_t explosion_origin;

		VectorMA( ent->s.origin, -0.02, ent->velocity, explosion_origin );
		event = G_SpawnEvent( EV_ROCKET_EXPLOSION, DirToByte( plane ? plane->normal : NULL ), explosion_origin );
		event->s.firemode = ( ent->s.effects & EF_STRONG_WEAPON ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;
		event->s.weapon = ( ( ent->projectileInfo.radius * 1 / 8 ) > 255 ) ? 255 : ( ent->projectileInfo.radius * 1 / 8 );
	}

	// free the rocket at next frame
	G_FreeEdict( ent );
}
コード例 #3
0
ファイル: g_weapon.cpp プロジェクト: ShaitanShootout/BM
/*
* W_Touch_Grenade
*/
static void W_Touch_Grenade( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags )
{
	int hitType;
	vec3_t dir;

	if( surfFlags & SURF_NOIMPACT )
	{
		G_FreeEdict( ent );
		return;
	}

	hitType = G_Projectile_HitStyle( ent, other );
	if( hitType == PROJECTILE_TOUCH_NOT )
		return;

	// don't explode on doors and plats that take damage
	if( !other->takedamage || ISBRUSHMODEL( other->s.modelindex ) )
	{
		G_AddEvent( ent, EV_GRENADE_BOUNCE, ( ent->s.effects & EF_STRONG_WEAPON ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK, true );
		return;
	}

	if( other->takedamage )
	{
		int directHitDamage = ent->projectileInfo.maxDamage;

		VectorNormalize2( ent->velocity, dir );

		if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) // use hybrid direction from splash and projectile
		{
			G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta );
		}
		else
		{
			VectorNormalize2( ent->velocity, dir );

			// no direct hit bonuses for grenades
			/*
			if( hitType == PROJECTILE_TOUCH_DIRECTAIRHIT )
				directHitDamage += DIRECTAIRTHIT_DAMAGE_BONUS;
			else if( hitType == PROJECTILE_TOUCH_DIRECTHIT )
				directHitDamage += DIRECTHIT_DAMAGE_BONUS;
			*/
		}

		G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, directHitDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, 0, ent->style );
	}

	ent->enemy = other;
	W_Grenade_ExplodeDir( ent, plane ? plane->normal : NULL );
}
コード例 #4
0
ファイル: g_weapon.c プロジェクト: Kaperstone/warsow
/*
* W_Touch_GunbladeBlast
*/
static void W_Touch_GunbladeBlast( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags )
{
	vec3_t dir;
	int hitType;

	if( surfFlags & SURF_NOIMPACT )
	{
		G_FreeEdict( ent );
		return;
	}

	hitType = G_Projectile_HitStyle( ent, other );
	if( hitType == PROJECTILE_TOUCH_NOT )
		return;

	if( other->takedamage )
	{
		VectorNormalize2( ent->velocity, dir );

		if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) // use hybrid direction from splash and projectile
		{
			G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta );
		}
		else
		{
			VectorNormalize2( ent->velocity, dir );
		}

		G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, ent->projectileInfo.maxDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, 0, ent->style );
	}

	G_RadiusDamage( ent, ent->r.owner, plane, other, MOD_GUNBLADE_S );

	// add explosion event
	if( ( !other->takedamage || ISBRUSHMODEL( other->s.modelindex ) ) )
	{
		edict_t *event;

		event = G_SpawnEvent( EV_GUNBLADEBLAST_IMPACT, DirToByte( plane ? plane->normal : NULL ), ent->s.origin );
		event->s.weapon = ( ( ent->projectileInfo.radius * 1/8 ) > 127 ) ? 127 : ( ent->projectileInfo.radius * 1/8 );
		event->s.skinnum = ( ( ent->projectileInfo.maxKnockback * 1/8 ) > 255 ) ? 255 : ( ent->projectileInfo.maxKnockback * 1/8 );
	}

	// free at next frame
	G_FreeEdict( ent );
}
コード例 #5
0
ファイル: g_weapon.c プロジェクト: Kaperstone/warsow
/*
* W_Touch_Projectile - Generic projectile touch func. Only for replacement in tests
*/
static void W_Touch_Projectile( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags )
{
	vec3_t dir, normal;
	int hitType;

	if( surfFlags & SURF_NOIMPACT )
	{
		G_FreeEdict( ent );
		return;
	}

	hitType = G_Projectile_HitStyle( ent, other );
	if( hitType == PROJECTILE_TOUCH_NOT )
		return;

	if( other->takedamage )
	{
		VectorNormalize2( ent->velocity, dir );

		if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) // use hybrid direction from splash and projectile
		{
			G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta );
		}
		else
		{
			VectorNormalize2( ent->velocity, dir );
		}

		G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, ent->projectileInfo.maxDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, 0, ent->style );
	}

	G_RadiusDamage( ent, ent->r.owner, plane, other, MOD_EXPLOSIVE );

	if( !plane->normal )
		VectorSet( normal, 0, 0, 1 );
	else
		VectorCopy( plane->normal, normal );
	
	G_Gametype_ScoreEvent( NULL, "projectilehit", va( "%i %i %f %f %f", ent->s.number, surfFlags, normal[0], normal[1], normal[2] ) );
}
コード例 #6
0
ファイル: g_combat.c プロジェクト: Kaperstone/warsow
/*
* G_RadiusDamage
*/
void G_RadiusDamage( edict_t *inflictor, edict_t *attacker, cplane_t *plane, edict_t *ignore, int mod )
{
	edict_t *ent = NULL;
	float dmgFrac, kickFrac, damage, knockback, stun;
	vec3_t pushDir;
	int timeDelta;

	float maxdamage, mindamage, maxknockback, minknockback, maxstun, minstun, radius;

	assert( inflictor );

	maxdamage = inflictor->projectileInfo.maxDamage;
	mindamage = inflictor->projectileInfo.minDamage;
	maxknockback = inflictor->projectileInfo.maxKnockback;
	minknockback = inflictor->projectileInfo.minKnockback;
	maxstun = inflictor->projectileInfo.stun;
	minstun = 1;
	radius = inflictor->projectileInfo.radius;

	if( radius <= 1.0f || ( maxdamage <= 0.0f && maxknockback <= 0.0f ) )
		return;

	clamp_high( mindamage, maxdamage );
	clamp_high( minknockback, maxknockback );
	clamp_high( minstun, maxstun );

	while( ( ent = GClip_FindBoxInRadius4D( ent, inflictor->s.origin, radius, inflictor->timeDelta ) ) != NULL )
	{
		if( ent == ignore || !ent->takedamage )
			continue;

		if( ent == attacker && ent->r.client )
			timeDelta = 0;
		else
			timeDelta = inflictor->timeDelta;

		G_SplashFrac4D( ENTNUM( ent ), inflictor->s.origin, radius, pushDir, &kickFrac, &dmgFrac, timeDelta );

		damage = max( 0, mindamage + ( ( maxdamage - mindamage ) * dmgFrac ) );
		stun = max( 0, minstun + ( ( maxstun - minstun ) * dmgFrac ) );
		knockback = max( 0, minknockback + ( ( maxknockback - minknockback ) * kickFrac ) );

		// weapon jumps hack : when knockback on self, use strong weapon definition
		if( ent == attacker && ent->r.client )
		{
			gs_weapon_definition_t *weapondef = NULL;
			if( inflictor->s.type == ET_ROCKET )
				weapondef = GS_GetWeaponDef( WEAP_ROCKETLAUNCHER );
			else if( inflictor->s.type == ET_GRENADE )
				weapondef = GS_GetWeaponDef( WEAP_GRENADELAUNCHER );
			else if( inflictor->s.type == ET_PLASMA )
				weapondef = GS_GetWeaponDef( WEAP_PLASMAGUN );
			else if( inflictor->s.type == ET_BLASTER )
				weapondef = GS_GetWeaponDef( WEAP_GUNBLADE );

			if( weapondef )
			{
				G_SplashFrac4D( ENTNUM( ent ), inflictor->s.origin, radius, pushDir, &kickFrac, NULL, 0 );

				minknockback = weapondef->firedef.minknockback;
				maxknockback = weapondef->firedef.knockback;
				clamp_high( minknockback, maxknockback );
				knockback = ( minknockback + ( (float)( maxknockback - minknockback ) * kickFrac ) ) * g_self_knockback->value;
				damage *= weapondef->firedef.selfdamage;
			}
		}

		if( knockback < 1.0f )
			knockback = 0.0f;

		if( stun < 1.0f )
			stun = 0.0f;

		if( damage <= 0.0f && knockback <= 0.0f && stun <= 0.0f )
			continue;

		if( G_CanSplashDamage( ent, inflictor, plane ) )
			G_Damage( ent, inflictor, attacker, pushDir, inflictor->velocity, inflictor->s.origin, damage, knockback, stun, DAMAGE_RADIUS, mod );
	}
}