#include "cg_local.h"
//#include "../game/bg_public.h"
#include "wolfcam_local.h"

extern qboolean debuggingweapon;
extern vec3_t  ejectBrassCasingOrigin;

qboolean CG_GetPartFramesFromWeap( centity_t *cent, refEntity_t *part, refEntity_t *parent, int partid, weaponInfo_t *wi );
void CG_RunWeapLerpFrame( clientInfo_t *ci, weaponInfo_t *wi, lerpFrame_t *lf, int newAnimation, float speedScale );
void CG_FlamethrowerFlame( centity_t *cent, vec3_t origin );

#if 1
static void Wolfcam_StartWeaponAnim (int anim)
{
    clientInfo_t *ci;
    centity_t *cent;
    entityState_t *es;

    ci = &cgs.clientinfo[wolfcam_ent];
    cent = &cg_entities[ci->clientNum];
    es = &cent->currentState;

    if (es->eFlags & EF_DEAD)
        return;

    if (wolfcam_weapAnimTimer > 0)  //FIXME wolfcam this is never set
        return;
    
    if (es->weapon == WP_NONE)
        return;

    wolfcam_weapAnim = ( (wolfcam_weapAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT) | anim;
    //Com_Printf ("Wolfcam_StartWeaponAnim()\n");
}

static void Wolfcam_ContinueWeaponAnim (int anim)
{
    clientInfo_t *ci;
    centity_t *cent;
    entityState_t *es;

    ci = &cgs.clientinfo[wolfcam_ent];
    cent = &cg_entities[ci->clientNum];
    es = &cent->currentState;

    if (es->weapon == WP_NONE)
        return;

    if ((wolfcam_weapAnim & ~ANIM_TOGGLEBIT) == anim) {
        return;
    }
    //Com_Printf ("2\n");
    if (wolfcam_weapAnimTimer > 0) {
        return;
    }

    Wolfcam_StartWeaponAnim (anim);
    //Com_Printf ("Wolfcam_ContinueWeaponAnim()\n");
}
#endif

static int Wolfcam_IdleAnimForWeapon ( int weapon ) {
    switch( weapon ) {
    case WP_GPG40:
    case WP_M7:
    case WP_SATCHEL_DET:
    case WP_MORTAR_SET:
    case WP_MEDIC_ADRENALINE:
    case WP_MOBILE_MG42_SET:
        return WEAP_IDLE2;

    default:
        return WEAP_IDLE1;
    }
}

#if 1
static int Wolfcam_AltSwitchFromForWeapon ( int weapon ) {
    //CG_Printf ("^3Wolfcam_AltSwitchFromForWeapon\n");
    switch( weapon ) {
        //              case WP_MEDIC_SYRINGE:
        //                      return WEAP_DROP;
    default:
        return WEAP_ALTSWITCHFROM;
    }
}
#endif

static int Wolfcam_AltSwitchToForWeapon ( int weapon ) {
    //CG_Printf ("^jsldkfjlsdkfj\n");
    switch( weapon ) {
    case WP_GPG40:
    case WP_M7:
    case WP_MORTAR:
    case WP_MOBILE_MG42:
        return WEAP_ALTSWITCHFROM;
        //              case WP_MEDIC_SYRINGE:
        //                      return WEAP_RAISE;

    default:
        return WEAP_ALTSWITCHTO;
    }
}

static int Wolfcam_AttackAnimForWeapon ( int weapon ) {
    if (BG_IsAkimboWeapon(weapon)) {
        if (wolfcam_event_akimboFire)
            return WEAP_ATTACK1;
        else
            return WEAP_ATTACK2;
    }

    switch( weapon ) {
    case WP_GPG40:
    case WP_M7:
    case WP_SATCHEL_DET:
    case WP_MEDIC_ADRENALINE:
    case WP_MOBILE_MG42_SET:
        return WEAP_ATTACK2;
    
    default:
        return WEAP_ATTACK1;
    }
}

#if 0
static int Wolfcam_LastAttackAnimForWeapon ( int weapon ) {
    switch( weapon ) {
    case WP_GPG40:
    case WP_M7:
    case WP_MOBILE_MG42_SET:
        return WEAP_ATTACK2;
    case WP_MORTAR_SET:
        return WEAP_ATTACK1;

    default:
        return WEAP_ATTACK_LASTSHOT;
    }
}
#endif

static int Wolfcam_ReloadAnimForWeapon ( int weapon ) {
    switch( weapon ) {
    case WP_GPG40:
    case WP_M7:
        return WEAP_RELOAD2;
    case WP_MOBILE_MG42_SET:
        return WEAP_RELOAD3;
    default:
        if( cgs.clientinfo[wolfcam_ent].skill[SK_LIGHT_WEAPONS] >= 2 && BG_isLightWeaponSupportingFastReload( weapon )  )
            return WEAP_RELOAD2;    // faster reload
        else
            return WEAP_RELOAD1;
    }
}

#if 1
static int Wolfcam_RaiseAnimForWeapon ( int weapon ) {
    switch( weapon ) {
    case WP_GPG40:
    case WP_M7:
        return WEAP_RELOAD3;
    case WP_MOBILE_MG42_SET:
        return WEAP_DROP2;
    case WP_SATCHEL_DET:
        return WEAP_RELOAD2;

    default:
        return WEAP_RAISE;
    }
}

static int Wolfcam_DropAnimForWeapon ( int weapon ) {
    switch( weapon ) {
    case WP_GPG40:
    case WP_M7:
        return WEAP_DROP2;
    case WP_SATCHEL_DET:
        return WEAP_RELOAD1;

    default:
        return WEAP_DROP;
    }
}
#endif

//FIXME wolfcam switch time
//FIXME firing time
// reload ok?
//FIXME  alt switching
static int Wolfcam_GetWeaponAnim (void)
{
    clientInfo_t *ci;
    centity_t *cent;
    entityState_t *es;
    int eflags;
    int rtime;
    int anim;
    int newweapon;
    int oldweapon;

    ci = &cgs.clientinfo[wolfcam_ent];
    cent = &cg_entities[ci->clientNum];
    es = &cent->currentState;
    eflags = es->eFlags;

    newweapon = es->weapon;
    oldweapon = wolfcam_event_oldWeapon;

    //FIXME wolfcam first check for switch, then reload, then fire
    //    if (weapAlts[es->weapon])

#if 0   // wolfcam fuck it, can't get newweapon yet
    if (cg.time - wolfcam_event_weaponSwitchTime < 1000) {

        if (oldweapon == WP_LUGER  &&  newweapon == WP_SILENCER)
            return Wolfcam_AltSwitchToForWeapon(newweapon);
        if (oldweapon == WP_COLT  &&  newweapon == WP_SILENCED_COLT)
            return Wolfcam_AltSwitchToForWeapon(newweapon);

        if (oldweapon == WP_SILENCER  &&  newweapon == WP_LUGER) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }
        if (oldweapon == WP_SILENCED_COLT  &&  newweapon == WP_COLT) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }
        // hack, event delayed
        if (oldweapon == WP_SILENCED_COLT  &&  newweapon == oldweapon) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }
        if (oldweapon == WP_SILENCER  &&  newweapon == oldweapon) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }


        if (oldweapon == WP_AKIMBO_LUGER  &&  newweapon == WP_AKIMBO_SILENCEDLUGER)
            return Wolfcam_AltSwitchToForWeapon(newweapon);
        if (oldweapon == WP_AKIMBO_COLT  &&  newweapon == WP_AKIMBO_SILENCEDCOLT)
            return Wolfcam_AltSwitchToForWeapon(newweapon);

        if (oldweapon == WP_AKIMBO_SILENCEDLUGER  &&  newweapon == WP_AKIMBO_LUGER) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }
        if (oldweapon == WP_AKIMBO_SILENCEDCOLT  &&  newweapon == WP_AKIMBO_COLT) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }
        // hack, event delayed
        //FIXME wolfcam buggy, what if switching to machine gun, knife, etc.
        if (oldweapon == WP_AKIMBO_SILENCEDCOLT  &&  newweapon == oldweapon) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }
        if (oldweapon == WP_AKIMBO_SILENCEDLUGER  &&  newweapon == oldweapon) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }
        
        //if (cg.time - wolfcam_weaponSwitchTime < 50  &&  wolfcam_oldweapon == WP_FG42  &&  newweapon == WP_FG42SCOPE)
        //    return Wolfcam_AltSwitchToForWeapon(newweapon);

    }
#endif

#if 0  //FIXME wolfcam hmm
    if (cg.time - wolfcam_event_weaponSwitchTime < 50) {
        CG_Printf ("^3oldweapon:%d  newweapon:%d\n", oldweapon, newweapon);
        if (oldweapon == WP_FG42  &&  newweapon == WP_FG42SCOPE) {
            return Wolfcam_AltSwitchToForWeapon(newweapon);
        }
        if (oldweapon == WP_FG42SCOPE  &&  newweapon == WP_FG42) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }
        if (oldweapon == WP_FG42SCOPE  &&  newweapon == oldweapon) {
            return Wolfcam_AltSwitchFromForWeapon(newweapon);
        }
    }
#endif

    //FIXME wolfcam  alt weapons :(
    if (cg.time - wolfcam_event_weaponSwitchTime < 250)
        return Wolfcam_DropAnimForWeapon(oldweapon);
    else if (cg.time - wolfcam_event_weaponSwitchTime < 500)
        return Wolfcam_RaiseAnimForWeapon(newweapon);

#if 0
    if (cg.time - wolfcam_weaponSwitchTime < 250) {  //FIXME wolfcam 200, 400, 1000?  check proper times, also check if es->weapon is actually changed before or after the proper switch
        return Wolfcam_DropAnimForWeapon(wolfcam_oldweapon);
    } else if (cg.time - wolfcam_weaponSwitchTime < 500) {
        return Wolfcam_RaiseAnimForWeapon(es->weapon);
    } else if (cg.time - wolfcam_weaponSwitchTime < 1000) {  // silenced sidearms have longest switch time
        int newweapon = es->weapon;

        if (wolfcam_oldweapon == WP_LUGER  &&  newweapon == WP_SILENCER)
            return Wolfcam_AltSwitchToForWeapon(newweapon);
        if (wolfcam_oldweapon == WP_COLT  &&  newweapon == WP_SILENCED_COLT)
            return Wolfcam_AltSwitchToForWeapon(newweapon);

        if (cg.time - wolfcam_weaponSwitchTime < 50  &&  wolfcam_oldweapon == WP_FG42  &&  newweapon == WP_FG42SCOPE)
            return Wolfcam_AltSwitchToForWeapon(newweapon);
    }
#endif

    rtime = GetAmmoTableData(es->weapon)->reloadTime;
    if (ci->skill[SK_LIGHT_WEAPONS] >= 2 && BG_isLightWeaponSupportingFastReload(es->weapon)) {
        rtime *= 0.65f;
    }
    if (cg.time - wolfcam_event_reloadTime < rtime) {
        return Wolfcam_ReloadAnimForWeapon(es->weapon);
    }

    // delayed weapon anims
    //FIXME grenade anim after weapon fire
    switch (es->weapon) {  //FIXME packs
    case WP_PANZERFAUST:
        if (cg.time - wolfcam_event_fireWeaponTime < 2000)  //FIXME wolfcam check panzer time bg_pmove.c
            return Wolfcam_AttackAnimForWeapon(es->weapon);
        else
            return Wolfcam_IdleAnimForWeapon(es->weapon);
        break;
    case WP_GRENADE_LAUNCHER:
    case WP_GRENADE_PINEAPPLE:
        //FIXME wolfcam find numbers wolfcam_event_fireWeaponTime
        if (eflags & EF_FIRING  ||  cg.time - wolfcam_event_fireWeaponTime < 2000)  //FIXME wolfcam check bg_pmove.c
            return Wolfcam_AttackAnimForWeapon(es->weapon);
        break;
    default:
        break;
    }


#if 0
    if (eflags & EF_FIRING) {  //FIXME wolfcam firing times
        anim = Wolfcam_AttackAnimForWeapon(es->weapon);
        return anim;
    }
#endif

    if (cg.time - wolfcam_event_fireWeaponTime < 200)  //FIXME wolfcam
        return Wolfcam_AttackAnimForWeapon(es->weapon);

    return Wolfcam_IdleAnimForWeapon(es->weapon);
}

static void Wolfcam_WeaponAnimation (weaponInfo_t *weapon, int *weapOld, int *weap, float *weapBackLerp) 
{
	clientInfo_t *ci = &cgs.clientinfo[wolfcam_ent];
	centity_t *cent = &cg_entities[ci->clientNum];

    //Com_Printf ("Wolfcam_WeaponAnimation()\n");

	if ( cg_noPlayerAnims.integer ) {
		*weapOld = *weap = 0;
		return;
	}

#if 0
    wolfcam_weapAnim = ANIM_TOGGLEBIT;
    if (cent->currentState.eFlags & EF_FIRING) {
        wolfcam_weapAnim = ((wolfcam_weapAnim & ANIM_TOGGLEBIT) ^ ANIM_TOGGLEBIT) | WEAP_ATTACK1;  //WEAP_ATTACK1;
    } else {
        wolfcam_weapAnim = ((wolfcam_weapAnim & ANIM_TOGGLEBIT) ^ ANIM_TOGGLEBIT) | WEAP_IDLE2;
    }
#endif

    if (wolfcam_weapAnimTimer > 0) {
        wolfcam_weapAnim = wolfcam_weapAnimPrev;
        CG_Printf ("^ewaiting for animation\n");
    } else {
        wolfcam_weapAnim = ANIM_TOGGLEBIT;
        wolfcam_weapAnim = ((wolfcam_weapAnim & ANIM_TOGGLEBIT) ^ ANIM_TOGGLEBIT) | Wolfcam_GetWeaponAnim();
    }

    wolfcam_weapAnimPrev = wolfcam_weapAnim;

	//CG_RunWeapLerpFrame( ci, weapon, &cent->pe.weap, wolfcam_weapAnim, 1 );
	CG_RunWeapLerpFrame( ci, weapon, &cent->pe.weap, wolfcam_weapAnim, 1 );

	*weapOld		= cent->pe.weap.oldFrame;
	*weap			= cent->pe.weap.frame;
	*weapBackLerp	= cent->pe.weap.backlerp;

	if ( cg_debugAnim.integer == 3) {
		CG_Printf( "oldframe: %d   frame: %d   backlerp: %f\n", cent->pe.weap.oldFrame, cent->pe.weap.frame, cent->pe.weap.backlerp);
	}
}


static void Wolfcam_CalculateWeaponPosition (vec3_t origin, vec3_t angles) 
{
	float	scale;
	//int		delta;
	float	fracsin;
    clientInfo_t *ci;
    centity_t *cent;
    entityState_t *es;

    ci = &cgs.clientinfo[wolfcam_ent];
    cent = &cg_entities[ci->clientNum];
    es = &cent->currentState;

	VectorCopy( cg.refdef_current->vieworg, origin );
	VectorCopy( cg.refdefViewAngles, angles );

	if( es->eFlags & EF_MOUNTEDTANK ) {
		angles[PITCH] = cg.refdefViewAngles[PITCH] / 1.2;
	}

    /*
	if( !cg.renderingThirdPerson &&
		( cg.predictedPlayerState.weapon == WP_MORTAR_SET || cg.predictedPlayerState.weapon == WP_MOBILE_MG42_SET )&&
		cg.predictedPlayerState.weaponstate != WEAPON_RAISING ) { */  //FIXME wolfcam
    if (!(es->eFlags & EF_DEAD)  &&
        ( es->weapon == WP_MORTAR_SET  ||  es->weapon == WP_MOBILE_MG42_SET)  &&
        ci->weaponState != WEAPON_RAISING) {  //FIXME wolfcam is ci->weaponState ok?
		angles[PITCH] = cg.pmext.mountedWeaponAngles[PITCH];  //FIXME wolfcam mountedWeaponAngles?
        //Com_Printf ("FIXME wolfcam\n");
	}

	if( es->eFlags & EF_PRONE_MOVING ) {
		int pronemovingtime = cg.time - wolfcam_proneMovingTime;
		if( pronemovingtime > 0 ) {	// div by 0
			float factor = pronemovingtime > 200 ? 1.f : 1.f / (200.f / (float)pronemovingtime);
			VectorMA( origin, factor * -20, cg.refdef_current->viewaxis[0], origin );
			VectorMA( origin, factor * 3, cg.refdef_current->viewaxis[1], origin );
		}
	} else {
		int pronenomovingtime = cg.time - -cg.proneMovingTime;

		if( pronenomovingtime < 200 ) {
			float factor = pronenomovingtime == 0 ? 1.f : 1.f - (1.f / (200.f / (float)pronenomovingtime));
			VectorMA( origin, factor * -20, cg.refdef_current->viewaxis[0], origin );
			VectorMA( origin, factor * 3, cg.refdef_current->viewaxis[1], origin );
		}
	}

	// adjust 'lean' into weapon
#if 0  //FIXME wolfcam 'lean' possible?
	if(cg.predictedPlayerState.leanf != 0) {
		vec3_t	right, up;
		float myfrac = 1.0f;

		switch(cg.predictedPlayerState.weapon) {
			case WP_FLAMETHROWER:
			case WP_KAR98:
			case WP_CARBINE:
			case WP_GPG40:
			case WP_M7:
			case WP_K43:
				myfrac = 2.0f;
				break;
			case WP_GARAND:
				myfrac = 3.0f;
				break;
		}

		// reverse the roll on the weapon so it stays relatively level
		angles[ROLL] -= cg.predictedPlayerState.leanf/(myfrac * 2.0f);
		AngleVectors(angles, NULL, right, up);
		VectorMA(origin, angles[ROLL], right, origin);

		// pitch the gun down a bit to show that firing is not allowed when leaning
		angles[PITCH] += (abs(cg.predictedPlayerState.leanf)/2.0f);

		// this gives you some impression that the weapon stays in relatively the same
		// position while you lean, so you appear to 'peek' over the weapon
		AngleVectors(cg.refdefViewAngles, NULL, right, NULL);
		VectorMA(origin, -cg.predictedPlayerState.leanf/4.0f, right, origin);
	}
#endif

	// on odd legs, invert some angles
#if 1  //FIXME wolfcam bobbing
	if ( wolfcam_bobcycle & 1 ) {
		scale = -wolfcam_xyspeed;
	} else {
		scale = wolfcam_xyspeed;
	}

	// gun angles from bobbing
    if (es->groundEntityNum != ENTITYNUM_NONE) {
        angles[ROLL]	+= scale		* wolfcam_bobfracsin * 0.005;
        angles[YAW]		+= scale		* wolfcam_bobfracsin * 0.01;
        angles[PITCH]	+= wolfcam_xyspeed	* wolfcam_bobfracsin * 0.005;
    }
#endif

	// drop the weapon when landing
#if 0  //FIXME wolfcam
	delta = cg.time - cg.landTime;
	if ( delta < LAND_DEFLECT_TIME ) {
		origin[2] += cg.landChange*0.25 * delta / LAND_DEFLECT_TIME;
	} else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) {
		origin[2] += cg.landChange*0.25 * 
			(LAND_DEFLECT_TIME + LAND_RETURN_TIME - delta) / LAND_RETURN_TIME;
	}
#endif

#if 0
	// drop the weapon when stair climbing
	delta = cg.time - cg.stepTime;
	if ( delta < STEP_TIME/2 ) {
		origin[2] -= cg.stepChange*0.25 * delta / (STEP_TIME/2);
	} else if ( delta < STEP_TIME ) {
		origin[2] -= cg.stepChange*0.25 * (STEP_TIME - delta) / (STEP_TIME/2);
	}
#endif

	// idle drift
	if( (!(es->eFlags & EF_MOUNTEDTANK)) && (es->weapon != WP_MORTAR_SET) && (es->weapon != WP_MOBILE_MG42_SET) ) {
	//----(SA) adjustment for MAX KAUFMAN
	//	scale = cg.xyspeed + 40;
		scale = 80;
	//----(SA)	end
		fracsin = sin( cg.time * 0.001 );
		angles[ROLL] += scale * fracsin * 0.01;
		angles[YAW] += scale * fracsin * 0.01;
		angles[PITCH] += scale * fracsin * 0.01;
	}

	// RF, subtract the kickAngles
	//VectorMA( angles, -1.0, cg.kickAngles, angles );  //FIXME wolfcam
}


static void Wolfcam_AddWeaponWithPowerups (refEntity_t *gun)
{
    trap_R_AddRefEntityToScene (gun);
}

void Wolfcam_AddPlayerWeapon (refEntity_t *parent, centity_t *cent) 
{

	refEntity_t	gun;
	refEntity_t	barrel;
	refEntity_t	flash;
	vec3_t		angles;
	weapon_t	weaponNum;
	weaponInfo_t	*weapon;
	centity_t	*nonPredictedCent;
	qboolean	firing;	// Ridah
	qboolean	akimboFire = qfalse;

//	qboolean	playerScaled;
	qboolean	drawpart;
	int			i;
	qboolean	isPlayer;

	bg_playerclass_t* classInfo;
    clientInfo_t *ci;

    ci = &cgs.clientinfo[wolfcam_ent];

	classInfo = BG_GetPlayerClassInfo(cgs.clientinfo[cent->currentState.clientNum].team, cgs.clientinfo[cent->currentState.clientNum].cls);

	// (SA) might as well have this check consistant throughout the routine
	//isPlayer = (qboolean)(cent->currentState.clientNum == cg.snap->ps.clientNum);
    isPlayer = qtrue;

	weaponNum = cent->currentState.weapon;

	if(cg.cameraMode) {
		return;
	}

	// don't draw any weapons when the binocs are up
	if( cent->currentState.eFlags & EF_ZOOMING ) {
		return;
	}

	// don't draw weapon stuff when looking through a scope
	if( weaponNum == WP_FG42SCOPE || weaponNum == WP_GARAND_SCOPE || weaponNum == WP_K43_SCOPE ) {
		//if( isPlayer && !cg.renderingThirdPerson ) {  //FIXME wolfcam thirdperson
		//	return;
		//}
	}

	if( weaponNum == WP_GRENADE_PINEAPPLE || weaponNum == WP_GRENADE_LAUNCHER ) {
		//if( ps && !ps->ammoclip[ weaponNum ] ) {  //FIXME wolfcam how to get ammo count?
		//	return;
		//}
	}

	// no weapon when on mg_42
	if( cent->currentState.eFlags & EF_MOUNTEDTANK ) {	
		//if( isPlayer && !cg.renderingThirdPerson ) {  //FIXME wolfcam thirdperson
		//	return;
		//}

		if( cg.time - cent->muzzleFlashTime < MUZZLE_FLASH_TIME ) {
			memset (&flash, 0, sizeof (flash));
			flash.renderfx = RF_LIGHTING_ORIGIN;
			flash.hModel = cgs.media.mg42muzzleflash;
			
			VectorCopy( cg_entities[cg_entities[ cent->currentState.number ].tagParent].mountedMG42Flash.origin, flash.origin );
			AxisCopy( cg_entities[cg_entities[ cent->currentState.number ].tagParent].mountedMG42Flash.axis, flash.axis );
			
			trap_R_AddRefEntityToScene( &flash );
			
			// ydnar: add dynamic light
			trap_R_AddLightToScene( flash.origin, 320, 1.25 + (rand() & 31) / 128, 1.0, 0.6, 0.23, 0, 0 );
		}
		return;
	}

	if( cent->currentState.eFlags & EF_MG42_ACTIVE || cent->currentState.eFlags & EF_AAGUN_ACTIVE ) {
		// Arnout: MG42 Muzzle Flash
		if ( cg.time - cent->muzzleFlashTime < MUZZLE_FLASH_TIME ) {
			CG_MG42EFX( cent );
		}
		return;
	}

	//if( (!ps || cg.renderingThirdPerson) && cent->currentState.eFlags & EF_PRONE_MOVING ) {
	//	return;
	//}

	weapon = &cg_weapons[weaponNum];

#if 0
	if( BG_IsAkimboWeapon( weaponNum ) ) {
		if( isPlayer ) {
            //FIXME wolfcam keep track of cycle
			akimboFire = BG_AkimboFireSequence( weaponNum, cg.predictedPlayerState.ammoclip[BG_FindClipForWeapon(weaponNum)], cg.predictedPlayerState.ammoclip[BG_FindClipForWeapon(BG_AkimboSidearm(weaponNum))] );
		} else if (0) {   //( ps ) {  // wolfcam
			//akimboFire = BG_AkimboFireSequence( weaponNum, ps->ammoclip[BG_FindClipForWeapon(weaponNum)], ps->ammoclip[BG_FindClipForWeapon(BG_AkimboSidearm(weaponNum))] );
		}
		// Gordon: FIXME: alternate for other clients, store flip-flop on cent or smuffin
	}
#endif
    if (BG_IsAkimboWeapon(weaponNum))
        akimboFire = wolfcam_event_akimboFire;

	// add the weapon
	memset( &gun, 0, sizeof( gun ) );
	VectorCopy( parent->lightingOrigin, gun.lightingOrigin );
	gun.shadowPlane = parent->shadowPlane;
	gun.renderfx = parent->renderfx;
	
	if (1) {  // if( ps ) {  // wolfcam ps
		//team_t team = ps->persistant[PERS_TEAM];
        team_t team = cgs.clientinfo[cent->currentState.clientNum].team;

		if( ( weaponNum != WP_SATCHEL ) && ( cent->currentState.powerups & (1 << PW_OPS_DISGUISED) ) ) {
			team = team == TEAM_AXIS ? TEAM_ALLIES : TEAM_AXIS;
		}

		gun.hModel = weapon->weaponModel[W_FP_MODEL].model;
		if( ( team == TEAM_AXIS ) &&
			weapon->weaponModel[W_FP_MODEL].skin[TEAM_AXIS] )
			gun.customSkin = weapon->weaponModel[W_FP_MODEL].skin[TEAM_AXIS];
		else if( ( team == TEAM_ALLIES ) &&
				 weapon->weaponModel[W_FP_MODEL].skin[TEAM_ALLIES] )
			gun.customSkin = weapon->weaponModel[W_FP_MODEL].skin[TEAM_ALLIES];
		else
			gun.customSkin = weapon->weaponModel[W_FP_MODEL].skin[0];	// if not loaded it's 0 so doesn't do any harm
	} else {
#if 0  // wolfcam
		team_t team = cgs.clientinfo[cent->currentState.clientNum].team;

		if( ( weaponNum != WP_SATCHEL ) && cent->currentState.powerups & (1 << PW_OPS_DISGUISED) ) {
			team = team == TEAM_AXIS ? TEAM_ALLIES : TEAM_AXIS;
		}

		gun.hModel = weapon->weaponModel[W_TP_MODEL].model;
		if( ( team == TEAM_AXIS ) &&
			weapon->weaponModel[W_TP_MODEL].skin[TEAM_AXIS] )
			gun.customSkin = weapon->weaponModel[W_FP_MODEL].skin[TEAM_AXIS];
		else if( ( team == TEAM_ALLIES ) &&
				 weapon->weaponModel[W_TP_MODEL].skin[TEAM_ALLIES] )
			gun.customSkin = weapon->weaponModel[W_TP_MODEL].skin[TEAM_ALLIES];
		else
			gun.customSkin = weapon->weaponModel[W_TP_MODEL].skin[0];	// if not loaded it's 0 so doesn't do any harm
#endif
	}

	if (!gun.hModel) {
		if(debuggingweapon) CG_Printf("returning due to: !gun.hModel\n");
		return;
	}

#if 0  //FIXME wolfcam check for ladder
	if(!ps && cg.snap->ps.pm_flags & PMF_LADDER && isPlayer)		//----(SA) player on ladder
	{
		if(debuggingweapon) CG_Printf("returning due to: !ps && cg.snap->ps.pm_flags & PMF_LADDER\n");
		return;
	}
#endif

#if 0  // wolfcam
	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->lerpOrigin, vec3_origin, weapon->firingSound, 255, 0 );
			cent->pe.lightningFiring = qtrue;
		} else if ( weapon->readySound ) {
			trap_S_AddLoopingSound( cent->lerpOrigin, vec3_origin, weapon->readySound, 255, 0 );
		}
	}
#endif

	// Ridah
	firing = ((cent->currentState.eFlags & EF_FIRING) != 0);

	//if( ps && !cg.renderingThirdPerson && cg.predictedPlayerState.weapon == WP_MORTAR_SET && cg.predictedPlayerState.weaponstate != WEAPON_RAISING ) {  //FIXME wolfcam thirdperson
    if (cent->currentState.weapon == WP_MORTAR_SET  &&  ci->weaponState != WEAPON_RAISING) {
		vec3_t angles;

		angles[YAW] = angles[ROLL] = 0.f;
		//angles[PITCH] = -.4f * AngleNormalize180( cg.pmext.mountedWeaponAngles[PITCH] - ps->viewangles[PITCH] );  //FIXME wolfcam mountedWeaponAngles ?

		AnglesToAxis( angles, gun.axis );

		CG_PositionRotatedEntityOnTag( &gun, parent, "tag_weapon" );
    } else if (0) {  //( (!ps || cg.renderingThirdPerson) && (weaponNum == WP_MORTAR_SET || weaponNum == WP_MORTAR ) ) {  //FIXME wolfcam thirdperson also !ps so skip
        //CG_PositionEntityOnTag( &gun, parent, "tag_weapon2", 0, NULL);
		} else {
			CG_PositionEntityOnTag( &gun, parent, "tag_weapon", 0, NULL);
		}


/*	playerScaled = (qboolean)(cgs.clientinfo[ cent->currentState.clientNum ].playermodelScale[0] != 0);
	if(!ps && playerScaled) {	// don't "un-scale" weap up in 1st person
		for(i=0;i<3;i++) {	// scale weapon back up so it doesn't pick up the adjusted scale of the character models.
							// this will affect any parts attached to the gun as well (barrel/bolt/flash/brass/etc.)
			VectorScale( gun.axis[i], 1.0/(cgs.clientinfo[ cent->currentState.clientNum ].playermodelScale[i]), gun.axis[i]);
		}

	}*/

	if(1) {  // (ps) {  // wolfcam
		drawpart = CG_GetPartFramesFromWeap(cent, &gun, parent, W_MAX_PARTS, weapon);	// W_MAX_PARTS specifies this as the primary view model
	} else {
		drawpart = qtrue;
	}

	if( drawpart ) {
		if( weaponNum == WP_AMMO ) {
			if (1) {  // ( ps ) {  // wolfcam
				if( cgs.clientinfo[ cent->currentState.clientNum ].skill[ SK_SIGNALS ] >= 1 ) {
					gun.customShader = weapon->modModels[0];
				}
			} else {
				if( cgs.clientinfo[ cent->currentState.clientNum ].skill[ SK_SIGNALS ] >= 1 ) {
					gun.customShader = weapon->modModels[0];
				}
			}
		}
		if (0) {  //  ( !ps ) {  // wolfcam
			if( weaponNum == WP_MEDIC_SYRINGE ) {
				if( cgs.clientinfo[ cent->currentState.clientNum ].skill[ SK_FIRST_AID ] >= 3 ) {
					gun.customShader = weapon->modModels[ 0 ];
				}
			}
		}
		//CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups, ps, cent );
        Wolfcam_AddWeaponWithPowerups (&gun);
	}

#if 0  // wolfcam  !ps	
	if( (!ps || cg.renderingThirdPerson) &&
		(weaponNum == WP_AKIMBO_COLT || weaponNum == WP_AKIMBO_SILENCEDCOLT || weaponNum == WP_AKIMBO_LUGER || weaponNum == WP_AKIMBO_SILENCEDLUGER) ) {
		// add to other hand as well
		CG_PositionEntityOnTag( &gun, parent, "tag_weapon2", 0, NULL);
		//CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups, ps, cent );
        Wolfcam_AddWeaponWithPowerups (&gun);
	}
#endif

	// ydnar: test hack
	//%	if( weaponNum == WP_KNIFE )
	//%		trap_R_AddLightToScene( gun.origin, 512, 1.5, 1.0, 1.0, 1.0, 0, 0 );

	if( isPlayer ) {
		refEntity_t	brass;

		if( BG_IsAkimboWeapon( weaponNum ) && akimboFire ) {
			CG_PositionRotatedEntityOnTag( &brass, parent, "tag_brass2" );
		} else {
			CG_PositionRotatedEntityOnTag( &brass, parent, "tag_brass" );
		}
		VectorCopy (brass.origin, ejectBrassCasingOrigin);
	}

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

	// add barrels
	// attach generic weapon parts to the first person weapon.
	// if a barrel should be attached for third person, add it in the (!ps) section below
	angles[YAW] = angles[PITCH] = 0;

	if (1) {  // ( ps ) {   // wolfcam ps == true
		qboolean spunpart;

		for( i = W_PART_1; i < W_MAX_PARTS; i++ ) {
			if( weaponNum == WP_MORTAR_SET && ( i == W_PART_4 || i == W_PART_5 ) ) {
				//if( ps && !cg.renderingThirdPerson && cg.predictedPlayerState.weaponstate != WEAPON_RAISING ) {  //FIXME wolfcam thirdperson
                if (ci->weaponState != WEAPON_RAISING) {
					continue;
				}
			}

			spunpart = qfalse;
			barrel.hModel = weapon->partModels[W_FP_MODEL][i].model;

			if( weaponNum == WP_MORTAR_SET ) {
				if( i == W_PART_3 ) {
                    //					if( ps && !cg.renderingThirdPerson && cg.predictedPlayerState.weaponstate != WEAPON_RAISING ) {  //FIXME wolfcam thirdperson
                    if (ci->weaponState != WEAPON_RAISING) {
						angles[PITCH] = angles[YAW] = 0.f;
						//angles[ROLL] = .8f * AngleNormalize180( cg.pmext.mountedWeaponAngles[YAW] - ps->viewangles[YAW] );  //FIXME wolfcam mountedWeaponAngles ?
						spunpart = qtrue;
					}
				} else if( i == W_PART_1 || i == W_PART_2 ) {
                    //					if( ps && !cg.renderingThirdPerson && cg.predictedPlayerState.weaponstate != WEAPON_RAISING ) {  //FIXME wolfcam thirdperson
                    if (ci->weaponState != WEAPON_RAISING) {
						angles[YAW] = angles[ROLL] = 0.f;
                        //						angles[PITCH] = -.4f * AngleNormalize180( cg.pmext.mountedWeaponAngles[PITCH] - ps->viewangles[PITCH] );  //FIXME wolfcam mountedWeaponAngles??
						spunpart = qtrue;
					}
				}
			} else if( weaponNum == WP_MOBILE_MG42_SET ) {

			}

			if( spunpart ) {
				AnglesToAxis( angles, barrel.axis );
			}

			if( barrel.hModel ) {
				if( spunpart ) {
					CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->partModels[W_FP_MODEL][i].tagName );
				} else {
					CG_PositionEntityOnTag( &barrel, parent, weapon->partModels[W_FP_MODEL][i].tagName, 0, NULL );
				}

				drawpart = CG_GetPartFramesFromWeap( cent, &barrel, parent, i, weapon );
					
				if( weaponNum == WP_MORTAR_SET && (i == W_PART_1 || i == W_PART_2) ) {
                    //					if( ps && !cg.renderingThirdPerson && cg.predictedPlayerState.weaponstate != WEAPON_RAISING ) {  //FIXME wolfcam thirdperson
                    if (ci->weaponState != WEAPON_RAISING) {  //FIXME wolfcam ci->weaponState no
						VectorMA( barrel.origin, .5f * angles[PITCH], cg.refdef_current->viewaxis[0], barrel.origin );
					}
				}

				if( drawpart ) {
					if( ( ci->team == TEAM_AXIS ||
						( ci->team == TEAM_ALLIES && cent->currentState.powerups & (1 << PW_OPS_DISGUISED) ) ) &&
						weapon->partModels[W_FP_MODEL][i].skin[TEAM_AXIS] )
						barrel.customSkin = weapon->partModels[W_FP_MODEL][i].skin[TEAM_AXIS];
					else if( ( ci->team == TEAM_ALLIES ||
							 ( ci->team == TEAM_AXIS && cent->currentState.powerups & (1 << PW_OPS_DISGUISED) ) ) &&
							 weapon->partModels[W_FP_MODEL][i].skin[TEAM_ALLIES] )
						barrel.customSkin = weapon->partModels[W_FP_MODEL][i].skin[TEAM_ALLIES];
					else
						barrel.customSkin = weapon->partModels[W_FP_MODEL][i].skin[0];	// if not loaded it's 0 so doesn't do any harm

					if( weaponNum == WP_MEDIC_SYRINGE && i == W_PART_1 ) {
						if( cgs.clientinfo[ wolfcam_ent ].skill[ SK_FIRST_AID ] >= 3 ) {
							barrel.customShader = weapon->modModels[ 0 ];
						}
					}

					//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
                    Wolfcam_AddWeaponWithPowerups (&barrel);

					if( weaponNum == WP_SATCHEL_DET && i == W_PART_1 ) {
						float rangeSquared;
						qboolean inRange;
						refEntity_t satchelDetPart;

						if( cg.satchelCharge ) {
							//rangeSquared = DistanceSquared( cg.satchelCharge->lerpOrigin, cg.predictedPlayerEntity.lerpOrigin );
                            rangeSquared = DistanceSquared( cg.satchelCharge->lerpOrigin, cent->lerpOrigin );
						} else {
							rangeSquared = Square(2001.f);
						}

						if( rangeSquared <= Square(2000) ) {
							inRange = qtrue;
						} else {
							inRange = qfalse;
						}

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

						satchelDetPart.hModel = weapon->modModels[0];
						CG_PositionEntityOnTag( &satchelDetPart, &barrel, "tag_rlight", 0, NULL);
						satchelDetPart.customShader = inRange ? weapon->modModels[2] : weapon->modModels[3];
						//CG_AddWeaponWithPowerups( &satchelDetPart, cent->currentState.powerups, ps, cent );
                        Wolfcam_AddWeaponWithPowerups (&satchelDetPart);

						CG_PositionEntityOnTag( &satchelDetPart, &barrel, "tag_glight", 0, NULL);
						satchelDetPart.customShader = inRange ? weapon->modModels[5] : weapon->modModels[4];
						//CG_AddWeaponWithPowerups( &satchelDetPart, cent->currentState.powerups, ps, cent );
                        Wolfcam_AddWeaponWithPowerups (&satchelDetPart);

						satchelDetPart.hModel = weapon->modModels[1];
						angles[PITCH] = angles[ROLL] = 0.f;
						if( inRange ) {
 							angles[YAW] = -30.f + ( 60.f * ( rangeSquared / Square(2000) ) );
						} else {
							angles[YAW] = 30.f;
						}
						AnglesToAxis( angles, satchelDetPart.axis );
						CG_PositionRotatedEntityOnTag( &satchelDetPart, &barrel, "tag_needle" );
						satchelDetPart.customShader = weapon->modModels[2];
						//CG_AddWeaponWithPowerups( &satchelDetPart, cent->currentState.powerups, ps, cent );
                        Wolfcam_AddWeaponWithPowerups (&satchelDetPart);
					} else if( weaponNum == WP_MORTAR_SET && i == W_PART_3 ) {
						//if( ps && !cg.renderingThirdPerson && cg.predictedPlayerState.weaponstate != WEAPON_RAISING ) {  //FIXME wolfcam thirdperson
                        if (ci->weaponState != WEAPON_RAISING) {  //FIXME wolfcam ci->weaponState no
							refEntity_t bipodLeg;

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

							bipodLeg.hModel = weapon->partModels[W_FP_MODEL][3].model;
							CG_PositionEntityOnTag( &bipodLeg, &barrel, "tag_barrel4", 0, NULL);
							//CG_AddWeaponWithPowerups( &bipodLeg, cent->currentState.powerups, ps, cent );
                            Wolfcam_AddWeaponWithPowerups (&bipodLeg);

							bipodLeg.hModel = weapon->partModels[W_FP_MODEL][4].model;
							CG_PositionEntityOnTag( &bipodLeg, &barrel, "tag_barrel5", 0, NULL);
							//CG_AddWeaponWithPowerups( &bipodLeg, cent->currentState.powerups, ps, cent );
                            Wolfcam_AddWeaponWithPowerups (&bipodLeg);
						}
					}
				}
			}
		}
	}

	// add the scope model to the rifle if you've got it
	//if( isPlayer && !cg.renderingThirdPerson ) {		// (SA) for now just do it on the first person weapons  //FIXME wolfcam thirdperson
    if (1) {
		if ( weaponNum == WP_CARBINE || weaponNum == WP_KAR98 || weaponNum == WP_GPG40 || weaponNum == WP_M7 ) {
			//if(	(cg.snap->ps.ammo[BG_FindAmmoForWeapon(WP_GPG40)] || cg.snap->ps.ammo[BG_FindAmmoForWeapon(WP_M7)] || cg.snap->ps.ammoclip[BG_FindAmmoForWeapon(WP_GPG40)] || cg.snap->ps.ammoclip[BG_FindAmmoForWeapon(WP_M7)]) ) {  //FIXME wolfcam  ammo count
            if (1) {
				//int anim = cg.snap->ps.weapAnim & ~ANIM_TOGGLEBIT;
                int anim = wolfcam_weapAnim & ~ANIM_TOGGLEBIT;
				if( anim == PM_AltSwitchFromForWeapon( weaponNum ) || anim == PM_AltSwitchToForWeapon( weaponNum ) || anim == PM_IdleAnimForWeapon( weaponNum ) ) {  //FIXME wolfcam PM_IdleAnimForWeapon
					barrel.hModel = weapon->modModels[0];
					if( barrel.hModel ) {
						CG_PositionEntityOnTag( &barrel, parent, "tag_scope", 0, NULL);
						//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
                        Wolfcam_AddWeaponWithPowerups (&barrel);
					}
				}
			}
		} else if( weaponNum == WP_GARAND ) {
			barrel.hModel = weapon->modModels[0];
			if(barrel.hModel) {
				CG_PositionEntityOnTag( &barrel, &gun, "tag_scope2", 0, NULL);
				//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
                Wolfcam_AddWeaponWithPowerups (&barrel);
			}

			barrel.hModel = weapon->modModels[1];
//			if(barrel.hModel) {
				CG_PositionEntityOnTag( &barrel, &gun, "tag_flash", 0, NULL);
				//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
                Wolfcam_AddWeaponWithPowerups (&barrel);
//			}
		} else if( weaponNum == WP_K43 ) {
			barrel.hModel = weapon->modModels[0];
			if(barrel.hModel) {
				CG_PositionEntityOnTag( &barrel, &gun, "tag_scope", 0, NULL);
				//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
                Wolfcam_AddWeaponWithPowerups (&barrel);
			}

			barrel.hModel = weapon->modModels[1];
//			if(barrel.hModel) {
				CG_PositionEntityOnTag( &barrel, &gun, "tag_flash", 0, NULL);
				//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
                Wolfcam_AddWeaponWithPowerups (&barrel);
//			}
		}
	}

	// 3rd person attachements
#if 0  // wolfcam don't need third person 
	else {
		if( weaponNum == WP_M7 || weaponNum == WP_GPG40/* || weaponNum == WP_CARBINE || weaponNum == WP_KAR98*/ ) {
			// the holder
			barrel.hModel = weapon->modModels[1];
			CG_PositionEntityOnTag( &barrel, &gun, "tag_flash", 0, NULL);
			//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
            Wolfcam_AddWeaponWithPowerups (&barrel);

			// the grenade - have to always enabled it, no means of telling if another person has a grenade loaded or not atm :/
			//if( cg.snap->ps.weaponstate != WEAPON_FIRING && cg.snap->ps.weaponstate != WEAPON_RELOADING ) {
			if( weaponNum == WP_M7 /*|| weaponNum == WP_CARBINE*/ ) {
				barrel.hModel = weapon->missileModel;
				CG_PositionEntityOnTag( &barrel, &barrel, "tag_prj", 0, NULL);
				//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
                Wolfcam_AddWeaponWithPowerups (&barrel);
			}
		} else if( weaponNum == WP_GARAND || weaponNum == WP_GARAND_SCOPE || weaponNum == WP_K43 || weaponNum == WP_K43_SCOPE ) {
			// the holder
			barrel.hModel = weapon->modModels[2];
			CG_PositionEntityOnTag( &barrel, &gun, "tag_scope", 0, NULL);
			//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
            Wolfcam_AddWeaponWithPowerups (&barrel);
		} else if( weaponNum == WP_MOBILE_MG42 ) {
			barrel.hModel = weapon->modModels[0];
			barrel.frame = 1;
			CG_PositionEntityOnTag( &barrel, &gun, "tag_bipod", 0, NULL);
			//CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
            Wolfcam_AddWeaponWithPowerups (&barrel);
		} else if( weaponNum == WP_MOBILE_MG42_SET ) {
			barrel.hModel = weapon->modModels[0];
			barrel.frame = 0;
			CG_PositionEntityOnTag( &barrel, &gun, "tag_bipod", 0, NULL);
			CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups, ps, cent );
            Wolfcam_AddWeaponWithPowerups (&barrel);
		}
	}
#endif

    //FIXME wolfcam  don't understand this
#if 1  // wolfcam
	// 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 the single player podiums), so
	// go ahead and use the cent
	if( ( nonPredictedCent - cg_entities ) != cent->currentState.clientNum ) {
		nonPredictedCent = cent;
	}
    nonPredictedCent = cent;
#endif 

    //FIXME wolfcam  was flash already added?
	// add the flash
	memset( &flash, 0, sizeof( flash ) );
	VectorCopy( parent->lightingOrigin, flash.lightingOrigin );
	flash.shadowPlane = parent->shadowPlane;
	flash.renderfx = parent->renderfx;

	if(1)  // (ps)  wolfcam
		flash.hModel = weapon->flashModel[W_FP_MODEL];
	else
		flash.hModel = weapon->flashModel[W_TP_MODEL];

    //Com_Printf ("weapNum:%d  weapon:%p  flash.hModel:%d\n", weaponNum, weapon, flash.hModel);

	angles[YAW]		= 0;
	angles[PITCH]	= 0;
	angles[ROLL]	= crandom() * 10;
	AnglesToAxis( angles, flash.axis );

	if( /*isPlayer &&*/ BG_IsAkimboWeapon( weaponNum ) ) {
		//if( !ps || cg.renderingThirdPerson ) {  //FIXME wolfcam thirdperson, also !ps
        if (0) {
			if( !cent->akimboFire ) {
				CG_PositionRotatedEntityOnTag( &flash, parent, "tag_weapon");
				VectorMA( flash.origin, 10, flash.axis[0], flash.origin );
			} else {
				CG_PositionRotatedEntityOnTag( &flash, &gun, "tag_flash");
			}
		} else {
			if (akimboFire) {  //if( !cent->akimboFire ) {
				CG_PositionRotatedEntityOnTag( &flash, parent, "tag_flash2");

			} else {
				CG_PositionRotatedEntityOnTag( &flash, parent, "tag_flash");
			}
		}
	} else {
		CG_PositionRotatedEntityOnTag( &flash, &gun, "tag_flash");
	}

	// store this position for other cgame elements to access
	//cent->pe.gunRefEnt = gun;
	//cent->pe.gunRefEntFrame = cg.clientFrame;

	if ( ( weaponNum == WP_FLAMETHROWER ) && ( nonPredictedCent->currentState.eFlags & EF_FIRING) ) 
	{
		// continuous flash

	} else {

		// continuous smoke after firing
#define BARREL_SMOKE_TIME 1000

		//if ( ps || cg.renderingThirdPerson || !isPlayer ) {  // wolfcam ps
        if (1) {
			if( weaponNum == WP_STEN || weaponNum == WP_MOBILE_MG42 || weaponNum == WP_MOBILE_MG42_SET ) {
				// hot smoking gun
				if(cg.time - cent->overheatTime < 3000) {
					if(!(rand()%3)) {
						float alpha;
						alpha = 1.0f - ((float)(cg.time - cent->overheatTime)/3000.0f);
						alpha *= 0.25f;		// .25 max alpha
						CG_ParticleImpactSmokePuffExtended(cgs.media.smokeParticleShader, flash.origin, 1000, 8, 20, 30, alpha, 8.f);
					}
				}

			} else if( weaponNum == WP_PANZERFAUST ) {
				if (cg.time - cent->muzzleFlashTime < BARREL_SMOKE_TIME) {
					if(!(rand()%5)) {
						float alpha;
						alpha = 1.0f - ((float)(cg.time - cent->muzzleFlashTime)/(float)BARREL_SMOKE_TIME);	// what fraction of BARREL_SMOKE_TIME are we at
						alpha *= 0.25f;		// .25 max alpha
						CG_ParticleImpactSmokePuffExtended(cgs.media.smokeParticleShader, flash.origin, 1000, 8, 20, 30, alpha, 8.f);
					}
				}
			}
		}

		if( weaponNum == WP_MORTAR_SET ) {
			//if( ps && !cg.renderingThirdPerson && cg.time - cent->muzzleFlashTime < 800 ) {  //FIXME wolfcam thirdperson
            if (cg.time - cent->muzzleFlashTime < 800) {
				CG_ParticleImpactSmokePuffExtended( cgs.media.smokeParticleShader, flash.origin, 700, 16, 20, 30, .12f, 4.f );
			}
		}


        ///        if (ci->clientNum == cent->currentState.clientNum)
        //  Com_Printf ("blahsldkfjsldkfj\n");  // yes both here
        //Com_Printf ("^3cg.time - cent->muzzleFlashTime %d  %d\n", cg.time - cent->muzzleFlashTime, cent->muzzleFlashTime);

        // this is it, cent->muzzleFlashTime not being set for demo taker

        //FIXME wolfcam hack since cent->muzzleFlashTime doesn't seem to stay for demo taker
        if (cent->currentState.clientNum == cg.snap->ps.clientNum) {
            cent->muzzleFlashTime = wolfcam_event_fireWeaponTime;
            // testing  see if we get brass ejects for demo pov >-1
            //VectorCopy (cg.refdefViewAngles, cent->lerpAngles);
            //VectorCopy (cg.refdef.vieworg, cent->lerpOrigin);
        }
            

		// impulse flash
		if (cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME) {
			// Ridah, blue ignition flame if not firing flamer
			if ( weaponNum != WP_FLAMETHROWER ) {
                //Com_Printf ("oops:\n");
				return;
			}
		}

	}

    //Com_Printf ("here xxx\n");  // not here
	// weapons that don't need to go any further as they have no flash or light
	if(	weaponNum == WP_GRENADE_LAUNCHER || 
		weaponNum == WP_GRENADE_PINEAPPLE ||
		weaponNum == WP_KNIFE ||
		weaponNum == WP_DYNAMITE ||
		weaponNum == WP_GPG40 ||
		weaponNum == WP_M7 ||
		weaponNum == WP_LANDMINE ||
		weaponNum == WP_SATCHEL ||
		weaponNum == WP_SATCHEL_DET ||
		weaponNum == WP_TRIPMINE ||
		weaponNum == WP_SMOKE_BOMB ||
		weaponNum == WP_MEDIC_SYRINGE ||
		weaponNum == WP_MEDIC_ADRENALINE
		)
	{
		return;
	}

	// weaps with barrel smoke
	//if ( ps || cg.renderingThirdPerson || !isPlayer ) {  // wolfcam ps
    if (1) {
		if( weaponNum == WP_STEN ) {
			if ( cg.time - cent->muzzleFlashTime < 100 )
//				CG_ParticleImpactSmokePuff (cgs.media.smokeParticleShader, flash.origin);
				CG_ParticleImpactSmokePuffExtended(cgs.media.smokeParticleShader, flash.origin, 500, 8, 20, 30, 0.25f, 8.f);
		}
	}

    //Com_Printf ("flash.hModel:%d\n", flash.hModel);  //not here

	if( flash.hModel ) {
		if(weaponNum != WP_FLAMETHROWER ) {	//Ridah, hide the flash also for now
			// RF, changed this so the muzzle flash stays onscreen for long enough to be seen
			if ( cg.time - cent->muzzleFlashTime < MUZZLE_FLASH_TIME ) {
			//if (firing) {	// Ridah
				trap_R_AddRefEntityToScene( &flash );
                //Com_Printf ("flash added\n");
			}
            //Com_Printf ("cent->muzzleFlashTime: %d\n", cent->muzzleFlashTime);
		}
	}

	// Ridah, zombie fires from his head
	//if (CG_MonsterUsingWeapon( cent, AICHAR_ZOMBIE, WP_MONSTER_ATTACK1 )) {
	//	CG_PositionEntityOnTag( &flash, parent, parent->hModel, "tag_head", NULL);
	//}
	
	//if ( ps || cg.renderingThirdPerson || !isPlayer )  // wolfcam ps
    if (1)
	{
		// ydnar: no flamethrower flame on prone moving
		// ydnar: or dead players
		if( firing && !(cent->currentState.eFlags & (EF_PRONE_MOVING | EF_DEAD)) )
		{
			// Ridah, Flamethrower effect
			CG_FlamethrowerFlame( 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], 0 );
				trap_R_AddLightToScene( flash.origin, 320, 1.25 + (rand() & 31) / 128, weapon->flashDlightColor[0],
					weapon->flashDlightColor[1], weapon->flashDlightColor[2], 0, 0 );
			}
		} else {
			if ( weaponNum == WP_FLAMETHROWER ) {
				vec3_t angles;
				AxisToAngles( flash.axis, angles );
// JPW NERVE
				weaponNum = BG_FindAmmoForWeapon(WP_FLAMETHROWER);
				//if (ps) {  // wolfcam ps
                if (1) {
					//if (ps->ammoclip[weaponNum])  //FIXME wolfcam find ammo
                    if (1)
						CG_FireFlameChunks( cent, flash.origin, angles, 1.0, qfalse );
				}
				else {
					CG_FireFlameChunks( cent, flash.origin, angles, 1.0, qfalse );
				}
// jpw
			}
		}
	}
}


void Wolfcam_AddViewWeapon (void) 
{
	refEntity_t	hand;
	float		fovOffset;
	vec3_t		angles;
	vec3_t		gunoff;
	weaponInfo_t	*weapon;
    clientInfo_t *ci;
    centity_t *cent;
    entityState_t *es;

    ci = &cgs.clientinfo[wolfcam_ent];
    cent = &cg_entities[ci->clientNum];
    es = &cent->currentState;

    //Com_Printf ("Wolfcam_AddViewWeapon()\n");

    if (cg.predictedPlayerState.pm_type == PM_INTERMISSION)
        return;

	// no gun if in third person view
#if 0  //FIXME wolfcam
    if (wolfcam_thirdperson) 
        return;
#endif

    if (es->eFlags & EF_DEAD  ||  (!cent->currentValid  &&  cgs.clientinfo[wolfcam_ent].clientNum != cg.snap->ps.clientNum))
        return;

	if (cg.editingSpeakers)
		return;

	// allow the gun to be completely removed
	if( ( !cg_drawGun.integer ) ) {
		vec3_t		origin;

		//bani - #589
		if ( es->eFlags & EF_FIRING && !( es->eFlags & ( EF_MG42_ACTIVE | EF_MOUNTEDTANK ) ) ) {
			// special hack for flamethrower...
			VectorCopy( cg.refdef_current->vieworg, origin );

			VectorMA( origin, 18, cg.refdef_current->viewaxis[0], origin );
			VectorMA( origin, -7, cg.refdef_current->viewaxis[1], origin );
			VectorMA( origin, -4, cg.refdef_current->viewaxis[2], origin );

			// Ridah, Flamethrower effect
			//CG_FlamethrowerFlame( &cg.predictedPlayerEntity, origin );
            // wolfcam this goes on to use cg.snap but it seems ok so far
            CG_FlamethrowerFlame (cent, origin);
		}

		if( wolfcam_binocZoomTime ) {
			if( wolfcam_binocZoomTime < 0 ) {
				if( -wolfcam_binocZoomTime + 500 + 200 < cg.time ) {
					wolfcam_binocZoomTime = 0;
				}
			} else {
				if( wolfcam_binocZoomTime + 500 < cg.time ) {
					trap_SendConsoleCommand( "+zoom\n" );
					wolfcam_binocZoomTime = 0;
				} else {
				}
			}
		}
		return;
	}

	// don't draw if testing a gun model
	if ( cg.testGun ) {
		return;
	}

    
	if ( es->eFlags & EF_MG42_ACTIVE || es->eFlags & EF_AAGUN_ACTIVE ) {
		return;
	}

	// drop gun lower at higher fov
	if ( cg_fov.integer > 90 ) {
		fovOffset = -0.2 * ( cg_fov.integer - 90 );
	} else {
		fovOffset = 0;
	}

	// Gordon: mounted gun drawing
	if( es->eFlags & EF_MOUNTEDTANK ) {
		// FIXME: Arnout: HACK dummy model to just draw _something_
		refEntity_t		flash;

		memset( &hand, 0, sizeof( hand ) );
		Wolfcam_CalculateWeaponPosition( hand.origin, angles );
		AnglesToAxis( angles, hand.axis );
		hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT;

		if( cg_entities[cg_entities[cg_entities[ ci->clientNum ].tagParent].tankparent].currentState.density & 8 ) { // should we use a browning?
			hand.hModel = cgs.media.hMountedFPBrowning;
		} else {
			hand.hModel = cgs.media.hMountedFPMG42;
		}

		//gunoff[0] = cg_gun_x.value;
		//gunoff[1] = cg_gun_y.value;
		//gunoff[2] = cg_gun_z.value;

		gunoff[0] = 20;
		if ( cg.time - cent->muzzleFlashTime < MUZZLE_FLASH_TIME ) {
			gunoff[0] += random() * 2.f;
		}
		VectorMA( hand.origin, gunoff[0], cg.refdef_current->viewaxis[0], hand.origin );
		VectorMA( hand.origin, -10, cg.refdef_current->viewaxis[1], hand.origin );
		VectorMA( hand.origin, (-8+fovOffset), cg.refdef_current->viewaxis[2], hand.origin );

		Wolfcam_AddWeaponWithPowerups (&hand);

		if( cg.time - cent->overheatTime < 3000 ) {  //FIXME wolfcam is this overheatTime ok?
			if(!(rand()%3)) {
				float alpha;
				alpha = 1.0f - ((float)(cg.time - cent->overheatTime)/3000.0f);
				alpha *= 0.25f;		// .25 max alpha
				CG_ParticleImpactSmokePuffExtended( cgs.media.smokeParticleShader, wolfcam_tankflashorg, 1000, 8, 20, 30, alpha, 8.f);
			}
		}

		{
			memset (&flash, 0, sizeof (flash));
			flash.renderfx = (RF_LIGHTING_ORIGIN|RF_DEPTHHACK);
			flash.hModel = cgs.media.mg42muzzleflash;

			angles[YAW]		= 0;
			angles[PITCH]	= 0;
			angles[ROLL]	= crandom() * 10;
			AnglesToAxis( angles, flash.axis );

			CG_PositionRotatedEntityOnTag( &flash, &hand, "tag_flash");

            VectorMA( flash.origin, 22, flash.axis[0], flash.origin );

			VectorCopy( flash.origin, wolfcam_tankflashorg );

			if ( cg.time - cent->muzzleFlashTime < MUZZLE_FLASH_TIME ) { 
				trap_R_AddRefEntityToScene( &flash );
                //Com_Printf ("flash added\n");
			}
		}
		return;
	}

    //Com_Printf ("here...\n");

	if ( es->weapon > WP_NONE) {
		weapon = &cg_weapons[ es->weapon ];

		memset (&hand, 0, sizeof(hand));

		// set up gun position
		Wolfcam_CalculateWeaponPosition( hand.origin, angles );

		gunoff[0] = cg_gun_x.value;
		gunoff[1] = cg_gun_y.value;
		gunoff[2] = cg_gun_z.value;

//----(SA)	removed

		VectorMA( hand.origin, gunoff[0], cg.refdef_current->viewaxis[0], hand.origin );
		VectorMA( hand.origin, gunoff[1], cg.refdef_current->viewaxis[1], hand.origin );
		VectorMA( hand.origin, (gunoff[2]+fovOffset), cg.refdef_current->viewaxis[2], hand.origin );

		AnglesToAxis( angles, hand.axis );

		if ( cg_gun_frame.integer ) {
			hand.frame = hand.oldframe = cg_gun_frame.integer;
			hand.backlerp = 0;
		}
		else {	// get the animation state

			if( wolfcam_binocZoomTime ) {
				if( wolfcam_binocZoomTime < 0 ) {
					if( -wolfcam_binocZoomTime + 500 + 200 < cg.time ) {
						wolfcam_binocZoomTime = 0;
					} else {
						if( -wolfcam_binocZoomTime + 200 < cg.time ) {
							Wolfcam_ContinueWeaponAnim( WEAP_ALTSWITCHFROM );  //FIXME wolfcam weapAnimTimer
						} else {
							Wolfcam_ContinueWeaponAnim( WEAP_IDLE2 );
						}
					}
				} else {
					if( wolfcam_binocZoomTime + 500 < cg.time ) {
						trap_SendConsoleCommand( "+zoom\n" );
						wolfcam_binocZoomTime = 0;
						Wolfcam_ContinueWeaponAnim( WEAP_IDLE2 );
					} else {
						Wolfcam_ContinueWeaponAnim( WEAP_ALTSWITCHTO );
					}
				}
			}
			//CG_WeaponAnimation( ps, weapon, &hand.oldframe, &hand.frame, &hand.backlerp);	//----(SA)	changed  //FIXME wolfcam
            Wolfcam_WeaponAnimation (weapon, &hand.oldframe, &hand.frame, &hand.backlerp);
		}


		hand.hModel = weapon->handsModel;
		hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT;	//----(SA)	

		// add everything onto the hand
		//CG_AddPlayerWeapon( &hand, ps, &cg.predictedPlayerEntity);  //FIXME wolfcam
        Wolfcam_AddPlayerWeapon (&hand, cent);
		// Ridah

        //wolfcam_weapAnim = WEAP_ATTACK1;
        
	}
}
