Site hosted by Angelfire.com: Build your free website today!
Adding glow and flash to railgun

I lu of trying to expain how it is done i am just going post the code and you can read the notes in it.


Major notes in red others in green.

/*
=============
CG_AddPlayerWeapon

Used for both the view weapon (ps is valid) and the world modelother character models (ps is NULL)
The main player will have this called for BOTH cases, so effects like light and
sound should only be done on the world model case.
=============
*/
void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent ) {
	refEntity_t	gun;
	refEntity_t	barrel;
	refEntity_t	flash;
	vec3_t		angles;
	weapon_t	weaponNum;
	weaponInfo_t	*weapon;
	centity_t	*nonPredictedCent;
// q3app (moved *ci up here)
        clientInfo_t    *ci;
        float           temp_fl;

        ci = &cgs.clientinfo[ cent->currentState.clientNum ];
// --
	weaponNum = cent->currentState.weapon;

	CG_RegisterWeapon( weaponNum );
	weapon = &cg_weapons[weaponNum];

	// add the weapon
	memset( &gun, 0, sizeof( gun ) );
	VectorCopy( parent->lightingOrigin, gun.lightingOrigin );
	gun.shadowPlane = parent->shadowPlane;
	gun.renderfx = parent->renderfx;

	// set custom shading for railgun refire rate
	if ( ps ) {
		if ( cg.predictedPlayerState.weapon == WP_RAILGUN 
			&& cg.predictedPlayerState.weaponstate == WEAPON_FIRING ) {
// q3app (won't need f anymore)
//                        float   f;
//                        f = (float)cg.predictedPlayerState.weaponTime / 1500;

// q3app (railgun shader now glows with effects color and goes white when charged)

                        gun.shaderRGBA[0] = 255 * ci->color[0];
                        gun.shaderRGBA[1] = 255 * ci->color[1];
                        gun.shaderRGBA[2] = 255 * ci->color[2];
                        gun.shaderRGBA[3] = 255;
// --
		} else {
                        gun.shaderRGBA[0] = 255;
                        gun.shaderRGBA[1] = 255;
                        gun.shaderRGBA[2] = 255;
			gun.shaderRGBA[3] = 255;
		}
	}

	gun.hModel = weapon->weaponModel;
	if (!gun.hModel) {
		return;
	}

	if ( !ps ) {
		// add weapon ready sound
		cent->pe.lightningFiring = qfalse;
		if ( ( cent->currentState.eFlags & EF_FIRING ) && weapon->firingSound ) {
			// lightning gun and guantlet make a different sound when fire is held down
			trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, weapon->firingSound );
			cent->pe.lightningFiring = qtrue;
		} else if ( weapon->readySound ) {
			trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, weapon->readySound );
		}
// q3app (railgun color)
                if ( cent->currentState.weapon == WP_RAILGUN ) {
                        if ( cent->muzzleFlashTime + 1500 > cg.time ) {
                                gun.shaderRGBA[0] = 255 * ci->color[0];
                                gun.shaderRGBA[1] = 255 * ci->color[1];
                                gun.shaderRGBA[2] = 255 * ci->color[2];
                                gun.shaderRGBA[3] = 255;
                        } else {
                                gun.shaderRGBA[0] = 255;
                                gun.shaderRGBA[1] = 255;
                                gun.shaderRGBA[2] = 255;
                                gun.shaderRGBA[3] = 255;
                        }
                }
// --
	}

	CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon");

	CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups );

	// add the spinning barrel
	if ( weaponNum == WP_MACHINEGUN || weaponNum == WP_GAUNTLET || weaponNum == WP_BFG ) {
		memset( &barrel, 0, sizeof( barrel ) );
		VectorCopy( parent->lightingOrigin, barrel.lightingOrigin );
		barrel.shadowPlane = parent->shadowPlane;
		barrel.renderfx = parent->renderfx;

		barrel.hModel = weapon->barrelModel;
		angles[YAW] = 0;
		angles[PITCH] = 0;
		angles[ROLL] = CG_MachinegunSpinAngle( cent );
		AnglesToAxis( angles, barrel.axis );

		CG_PositionRotatedEntityOnTag( &barrel, &gun, weapon->weaponModel, "tag_barrel" );

		CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups );
	}

	// make sure we aren't looking at cg.predictedPlayerEntity for LG
	nonPredictedCent = &cg_entities[cent->currentState.clientNum];

	// if the index of the nonPredictedCent is not the same as the clientNum
	// then this is a fake player (like on teh single player podiums), so
	// go ahead and use the cent
	if( ( nonPredictedCent - cg_entities ) != cent->currentState.clientNum ) {
		nonPredictedCent = cent;
	}

	// add the flash
	if ( ( weaponNum == WP_LIGHTNING || weaponNum == WP_GAUNTLET || weaponNum == WP_GRAPPLING_HOOK )
		&& ( nonPredictedCent->currentState.eFlags & EF_FIRING ) ) 
	{
		// continuous flash
	} else {
		// impulse flash
		if ( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME && !cent->pe.railgunFlash ) {
			return;
		}
	}

	memset( &flash, 0, sizeof( flash ) );
	VectorCopy( parent->lightingOrigin, flash.lightingOrigin );
	flash.shadowPlane = parent->shadowPlane;
	flash.renderfx = parent->renderfx;

	flash.hModel = weapon->flashModel;
	if (!flash.hModel) {
		return;
	}
	angles[YAW] = 0;
	angles[PITCH] = 0;
	angles[ROLL] = crandom() * 10;
	AnglesToAxis( angles, flash.axis );

	// colorize the railgun blast
	if ( weaponNum == WP_RAILGUN ) {
// q3app (*ci moved up to start of function because it's used earlier)
//                clientInfo_t    *ci;

		flash.shaderRGBA[0] = 255 * ci->color[0];
		flash.shaderRGBA[1] = 255 * ci->color[1];
		flash.shaderRGBA[2] = 255 * ci->color[2];
	}

// q3app (flash size)
        temp_fl = cgv.cg_gun.flash;
        if ( temp_fl > 2 ) {
                temp_fl = 2;   
        }
        VectorScale(flash.axis[0], temp_fl, flash.axis[0]);
        VectorScale(flash.axis[1], temp_fl, flash.axis[1]);
        VectorScale(flash.axis[2], temp_fl, flash.axis[2]);

	CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash");
        if ( temp_fl > 0 ) { // no drawing of flash if flash size == 0
                trap_R_AddRefEntityToScene( &flash );
        }
	if ( ps || cg.renderingThirdPerson ||
		cent->currentState.number != cg.predictedPlayerState.clientNum ) {
		// add lightning bolt
                CG_LightningBolt( nonPredictedCent, flash.origin );

		// add rail trail
                CG_SpawnRailTrail( cent, flash.origin );

		// make a dlight for the flash
		if ( weapon->flashDlightColor[0] || weapon->flashDlightColor[1] || weapon->flashDlightColor[2] ) {
			trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), weapon->flashDlightColor[0],
				weapon->flashDlightColor[1], weapon->flashDlightColor[2] );
		}
	}
}


Credit for the edited code go to Dan 'Neurobasher' Gomes and it can be found in the Quake 3 Arena ++ source.
The site should still be up at http://www.planetquake.com/q3app/
I will allso put a copy of the source in the source archive.

Well enjoy

--powerr