void Wolfcam_AddPlayerWeapon (const refEntity_t *parent, centity_t *cent, int team) { refEntity_t gun; refEntity_t barrel; refEntity_t flash; vec3_t angles; weapon_t weaponNum; const weaponInfo_t *weapon; centity_t *nonPredictedCent; // int col clientInfo_t *ci; float flashSize; float dlight[3]; float f; qboolean revertColors = qfalse; vec3_t origColor1; vec3_t origColor2; if (!cent->inCurrentSnapshot) { // this can happen with /follow which can stay in victim position // (frag hover) return; } ci = &cgs.clientinfo[ cent->currentState.clientNum ]; weaponNum = cent->currentState.weapon; if (weaponNum <= WP_NONE || weaponNum >= WP_NUM_WEAPONS) { return; } 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 (0) { //( ps ) { } else { if (weaponNum == WP_RAILGUN) { qboolean teamRail; qboolean enemyRail; if (cg_railUseOwnColors.integer && CG_IsUs(ci)) { VectorCopy(ci->color1, origColor1); VectorCopy(ci->color2, origColor2); VectorCopy(cg.color1, ci->color1); VectorCopy(cg.color2, ci->color2); revertColors = qtrue; } teamRail = CG_IsTeammate(ci); enemyRail = CG_IsEnemy(ci); if (cgs.gametype < GT_TEAM) { if (!CG_IsUs(ci)) { if (*cg_enemyRailItemColor.string) { SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_enemyRailItemColor); gun.shaderRGBA[3] = 255; } else { gun.shaderRGBA[0] = 255 * ci->color1[0]; gun.shaderRGBA[1] = 255 * ci->color1[1]; gun.shaderRGBA[2] = 255 * ci->color1[2]; gun.shaderRGBA[3] = 255; } } else { gun.shaderRGBA[0] = 255 * ci->color1[0]; gun.shaderRGBA[1] = 255 * ci->color1[1]; gun.shaderRGBA[2] = 255 * ci->color1[2]; gun.shaderRGBA[3] = 255; } } else { // team game if (!CG_IsUs(ci) && teamRail) { if (cg_teamRailItemColorTeam.integer) { if (ci->team == TEAM_RED) { SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_weaponRedTeamColor); } else { SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_weaponBlueTeamColor); } gun.shaderRGBA[3] = 255; } else if (*cg_teamRailItemColor.string) { SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_teamRailItemColor); gun.shaderRGBA[3] = 255; } else { gun.shaderRGBA[0] = 255 * ci->color1[0]; gun.shaderRGBA[1] = 255 * ci->color1[1]; gun.shaderRGBA[2] = 255 * ci->color1[2]; gun.shaderRGBA[3] = 255; } } else if (!CG_IsUs(ci) && enemyRail) { if (cg_enemyRailItemColorTeam.integer) { if (ci->team == TEAM_RED) { SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_weaponRedTeamColor); } else { SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_weaponBlueTeamColor); } gun.shaderRGBA[3] = 255; } else if (*cg_enemyRailItemColor.string) { SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_enemyRailItemColor); gun.shaderRGBA[3] = 255; } else { gun.shaderRGBA[0] = 255 * ci->color1[0]; gun.shaderRGBA[1] = 255 * ci->color1[1]; gun.shaderRGBA[2] = 255 * ci->color1[2]; gun.shaderRGBA[3] = 255; } } else { // us gun.shaderRGBA[0] = 255 * ci->color1[0]; gun.shaderRGBA[1] = 255 * ci->color1[1]; gun.shaderRGBA[2] = 255 * ci->color1[2]; gun.shaderRGBA[3] = 255; } } // end weapon == WP_RAILGUN //cent->pe.muzzleFlashTime //Com_Printf("yes....\n"); //f = cg.time - (cent->pe.muzzleFlashTime + 1500); f = cg.time - (cent->pe.muzzleFlashTime + 1460); // hack //Com_Printf("f %f\n", f); if (f < 0) { f = 1.0 - (f / -1500); gun.shaderRGBA[0] *= 0.314 * f; gun.shaderRGBA[1] *= 0.314 * f; gun.shaderRGBA[2] *= 0.314 * f; } } } gun.hModel = weapon->weaponModel; if (!gun.hModel) { //Com_Printf("no gun model '%s'\n", weapNamesCasual[weaponNum]); //FIXME grapple returns here //FIXME fx //CG_PositionEntityOnTag(&gun, parent, parent->hModel, "tag_weapon"); //CG_CheckFxWeaponFlash(cent, weaponNum, gun.origin); //return; } CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon"); CG_ScaleModel(&gun, cg_gunSize.value); // custom weapon shaders { vmCvar_t *firstPersonShaders[MAX_WEAPONS] = { NULL, &cg_firstPersonShaderWeaponGauntlet, &cg_firstPersonShaderWeaponMachineGun, &cg_firstPersonShaderWeaponShotgun, &cg_firstPersonShaderWeaponGrenadeLauncher, &cg_firstPersonShaderWeaponRocketLauncher, &cg_firstPersonShaderWeaponLightningGun, &cg_firstPersonShaderWeaponRailGun, &cg_firstPersonShaderWeaponPlasmaGun, &cg_firstPersonShaderWeaponBFG, &cg_firstPersonShaderWeaponGrapplingHook, &cg_firstPersonShaderWeaponNailGun, &cg_firstPersonShaderWeaponProximityLauncher, &cg_firstPersonShaderWeaponChainGun, &cg_firstPersonShaderWeaponHeavyMachineGun }; if (firstPersonShaders[weaponNum] && *(firstPersonShaders[weaponNum]->string)) { gun.customShader = trap_R_RegisterShader(firstPersonShaders[weaponNum]->string); } } if (gun.hModel) { if (cg_drawGun.integer > 2) { gun.customShader = cgs.media.ghostWeaponShader; gun.shaderRGBA[0] = 255; gun.shaderRGBA[1] = 255; gun.shaderRGBA[2] = 255; gun.shaderRGBA[3] = 255; } CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups ); } // add the spinning barrel if ( weapon->barrelModel ) { 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_ScaleModel(&barrel, cg_gunSize.value); if (cg_drawGun.integer > 2) { barrel.customShader = cgs.media.ghostWeaponShader; barrel.shaderRGBA[0] = 255; barrel.shaderRGBA[1] = 255; barrel.shaderRGBA[2] = 255; barrel.shaderRGBA[3] = 255; } CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups ); } // make sure we aren't looking at cg.predictedPlayerEntity for LG nonPredictedCent = &cg_entities[cent->currentState.clientNum]; #if 0 // 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; //Com_Printf("fake player %d -> %d\n", nonPredictedCent - cg_entities, cent->currentState.clientNum); } #endif // add the flash //if ( ( weaponNum == WP_LIGHTNING || weaponNum == WP_GAUNTLET || weaponNum == WP_GRAPPLING_HOOK ) && (cent->currentState.eFlags & EF_FIRING)) { if ( ( weaponNum == WP_LIGHTNING || weaponNum == WP_GAUNTLET || weaponNum == WP_GRAPPLING_HOOK ) && (nonPredictedCent->currentState.eFlags & EF_FIRING)) { // && ( nonPredictedCent->currentState.eFlags & EF_FIRING ) ) { // continuous flash } else { //int ftime; if (weaponNum == WP_LIGHTNING && cent->currentState.eFlags & EF_FIRING) { //Com_Printf("%f wtf ps %p\n", cg.ftime, ps); } // impulse flash //if ( cg.time - cent->pe.muzzleFlashTime > MUZZLE_FLASH_TIME && !cent->pe.railgunFlash ) { if ( cg.time - nonPredictedCent->pe.muzzleFlashTime > MUZZLE_FLASH_TIME && !nonPredictedCent->pe.railgunFlash ) { //Com_Printf("returning for %d (%d)\n", cent - cg_entities, cent->currentState.number); //goto bolt; // not called, in case code changes if (revertColors) { VectorCopy(origColor1, ci->color1); VectorCopy(origColor2, ci->color2); } return; } } memset( &flash, 0, sizeof( flash ) ); VectorCopy( parent->lightingOrigin, flash.lightingOrigin ); flash.shadowPlane = parent->shadowPlane; flash.renderfx = parent->renderfx; flash.hModel = weapon->flashModel; /* if (weaponNum == WP_HEAVY_MACHINEGUN) { flash.hModel = cg_weapons[WP_MACHINEGUN].flashModel; } */ if (!flash.hModel) { //Com_Printf("no flash model '%s'\n", weapNamesCasual[weaponNum]); //FIXME fx //return; } angles[YAW] = 0; angles[PITCH] = 0; angles[ROLL] = crandom() * 10; AnglesToAxis( angles, flash.axis ); // colorize the railgun blast if ( weaponNum == WP_RAILGUN ) { //clientInfo_t *ci; //ci = &cgs.clientinfo[ cent->currentState.clientNum ]; if (cg_railUseOwnColors.integer && CG_IsUs(ci)) { flash.shaderRGBA[0] = 255 * cg.color1[0]; flash.shaderRGBA[1] = 255 * cg.color1[1]; flash.shaderRGBA[2] = 255 * cg.color1[2]; } else { flash.shaderRGBA[0] = 255 * ci->color1[0]; flash.shaderRGBA[1] = 255 * ci->color1[1]; flash.shaderRGBA[2] = 255 * ci->color1[2]; } } if (0) { //(weapon->hasFlashScript) { //CG_RunQ3mmeFlashScript(weapon, dlight, flash.shaderRGBA, &flashSize); //VectorCopy(flash.origin, ScriptVars.origin); //CG_RunQ3mmeScript((char *)weapon->flashScript); //return; } else { dlight[0] = weapon->flashDlightColor[0]; dlight[1] = weapon->flashDlightColor[1]; dlight[2] = weapon->flashDlightColor[2]; /* flash.shaderRGBA[0] = 255; flash.shaderRGBA[1] = 255; flash.shaderRGBA[2] = 255; flash.shaderRGBA[3] = 0; */ flashSize = 300 + (rand()&31); } CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash"); //Com_Printf("ps:%d %p\n", ps != NULL, cent); if (0) { //(cent == &cg.predictedPlayerEntity && !cg.renderingThirdPerson && !ps) { // don't run flash script twice for first person view } else if (EffectScripts.weapons[weaponNum].hasFlashScript) { //CG_RunQ3mmeFlashScript(weapon, dlight, flash.shaderRGBA, &flashSize); //memset(&ScriptVars, 0, sizeof(ScriptVars)); //CG_Printf("addplayerweapon() flash script cent %d\n", cent - cg_entities); CG_ResetScriptVars(); CG_CopyPlayerDataToScriptData(cent); VectorCopy(flash.origin, ScriptVars.origin); VectorCopy(flash.origin, ScriptVars.parentOrigin); VectorCopy(cent->lastFlashIntervalPosition, ScriptVars.lastIntervalPosition); ScriptVars.lastIntervalTime = cent->lastFlashIntervalTime; VectorCopy(cent->lastFlashDistancePosition, ScriptVars.lastDistancePosition); ScriptVars.lastDistanceTime = cent->lastFlashDistanceTime; CG_RunQ3mmeScript((char *)EffectScripts.weapons[weaponNum].flashScript, NULL); VectorCopy(ScriptVars.lastIntervalPosition, cent->lastFlashIntervalPosition); cent->lastFlashIntervalTime = ScriptVars.lastIntervalTime; VectorCopy(ScriptVars.lastDistancePosition, cent->lastFlashDistancePosition); cent->lastFlashDistanceTime = ScriptVars.lastDistanceTime; //return; } if (!cg_muzzleFlash.integer) { // pass } else { if (flash.hModel) { CG_AddRefEntity(&flash); } } // bolt: if (1) { // add lightning bolt if (1) { CG_LightningBolt( nonPredictedCent, flash.origin ); //Com_Printf("adding bolt\n"); // add rail trail CG_SpawnRailTrail( cent, flash.origin ); //if ((dlight[0] || dlight[1] || dlight[2]) && !weapon->hasFlashScript) { if ((dlight[0] || dlight[1] || dlight[2]) && !EffectScripts.weapons[weaponNum].hasFlashScript) { trap_R_AddLightToScene(flash.origin, flashSize, dlight[0], dlight[1], dlight[2]); } } } else { //Com_Printf("%f no...\n", cg.ftime); } if (revertColors) { VectorCopy(origColor1, ci->color1); VectorCopy(origColor2, ci->color2); } }
// 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, int team, vector3 *newAngles, qboolean thirdPerson ) { refEntity_t gun, barrel, flash; vector3 angles; weapon_t weaponNum; weaponInfo_t *weapon; centity_t *nonPredictedCent; if ( !thirdPerson && cg_fakeGun.integer ) { weaponNum = (weapon_t)cg_fakeGun.integer; } else { weaponNum = (weapon_t)cent->currentState.weapon; } if ( weaponNum == WP_EMPLACED_GUN ) return; // spectator mode, don't draw it... if ( cg.predictedPlayerState.pm_type == PM_SPECTATOR && cent->currentState.number == cg.predictedPlayerState.clientNum ) { return; } CG_RegisterWeapon( weaponNum ); weapon = &cg_weapons[weaponNum]; memset( &gun, 0, sizeof(gun) ); // only do this if we are in first person, since world weapons are now handled on the server by Ghoul2 if ( !thirdPerson ) { // add the weapon VectorCopy( &parent->lightingOrigin, &gun.lightingOrigin ); gun.shadowPlane = parent->shadowPlane; gun.renderfx = parent->renderfx; // this player, in first person view if ( ps ) gun.hModel = weapon->viewModel; else gun.hModel = weapon->weaponModel; if ( !gun.hModel ) return; if ( !ps ) { // add weapon ready sound if ( (cent->currentState.eFlags & EF_FIRING) && weapon->firingSound ) { trap->S_AddLoopingSound( cent->currentState.number, ¢->lerpOrigin, &vec3_origin, weapon->firingSound ); } else if ( weapon->readySound ) { trap->S_AddLoopingSound( cent->currentState.number, ¢->lerpOrigin, &vec3_origin, weapon->readySound ); } } CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon" ); if ( !CG_IsMindTricked( cent->currentState.trickedEntIndex, cg.snap->ps.clientNum ) ) { // don't draw the weapon if the player is invisible CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups ); } if ( weaponNum == WP_STUN_BATON ) { int i; for ( i = 0; i < 3; i++ ) { memset( &barrel, 0, sizeof(barrel) ); VectorCopy( &parent->lightingOrigin, &barrel.lightingOrigin ); barrel.shadowPlane = parent->shadowPlane; barrel.renderfx = parent->renderfx; if ( i == 0 ) { barrel.hModel = trap->R_RegisterModel( "models/weapons2/stun_baton/baton_barrel.md3" ); } else if ( i == 1 ) { barrel.hModel = trap->R_RegisterModel( "models/weapons2/stun_baton/baton_barrel2.md3" ); } else { barrel.hModel = trap->R_RegisterModel( "models/weapons2/stun_baton/baton_barrel3.md3" ); } angles.yaw = 0; angles.pitch = 0; angles.roll = 0; AnglesToAxis( &angles, barrel.axis ); if ( i == 0 ) { CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel" ); } else if ( i == 1 ) { CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel2" ); } else { CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel3" ); } CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups ); } } else { // add the spinning barrel if ( weapon->barrelModel ) { 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 = 0; AnglesToAxis( &angles, barrel.axis ); CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel" ); CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups ); } } } memset( &flash, 0, sizeof(flash) ); CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash" ); VectorCopy( &flash.origin, &cg.lastFPFlashPoint ); // Do special charge bits // Make the guns do their charging visual in True View. if ( (ps || cg.renderingThirdPerson || cg.predictedPlayerState.clientNum != cent->currentState.number || cg_trueGuns.integer) && ((cent->currentState.modelindex2 == WEAPON_CHARGING_ALT && weaponNum == WP_BRYAR_PISTOL) || (cent->currentState.modelindex2 == WEAPON_CHARGING_ALT && weaponNum == WP_BRYAR_OLD) || (weaponNum == WP_BOWCASTER && cent->currentState.modelindex2 == WEAPON_CHARGING) || (weaponNum == WP_DEMP2 && cent->currentState.modelindex2 == WEAPON_CHARGING_ALT)) ) { int shader = 0; float val = 0.0f; float scale = 1.0f; addspriteArgStruct_t fxSArgs; vector3 flashorigin, flashdir; if ( !thirdPerson ) { VectorCopy( &flash.origin, &flashorigin ); VectorCopy( &flash.axis[0], &flashdir ); } else { mdxaBone_t boltMatrix; // it's quite possible that we may have have no weapon model and be in a valid state, so return here if this is the case if ( !trap->G2API_HasGhoul2ModelOnIndex( &(cent->ghoul2), 1 ) ) return; // Couldn't find bolt point. if ( !trap->G2API_GetBoltMatrix( cent->ghoul2, 1, 0, &boltMatrix, newAngles, ¢->lerpOrigin, cg.time, cgs.gameModels, ¢->modelScale ) ) { return; } BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, &flashorigin ); BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_X, &flashdir ); } if ( weaponNum == WP_BRYAR_PISTOL || weaponNum == WP_BRYAR_OLD ) { // Hardcoded max charge time of 1 second val = (cg.time - cent->currentState.constantLight) * 0.001f; shader = media.gfx.world.bryarFrontFlash; } else if ( weaponNum == WP_BOWCASTER ) { // Hardcoded max charge time of 1 second val = (cg.time - cent->currentState.constantLight) * 0.001f; shader = media.gfx.world.greenFrontFlash; } else if ( weaponNum == WP_DEMP2 ) { val = (cg.time - cent->currentState.constantLight) * 0.001f; shader = media.gfx.world.lightningFlash; scale = 1.75f; } if ( val < 0.0f ) val = 0.0f; else if ( val > 1.0f ) { val = 1.0f; if ( ps && cent->currentState.number == ps->clientNum ) CGCam_Shake( 0.2f, 100 ); } else if ( ps && cent->currentState.number == ps->clientNum ) CGCam_Shake( val * val * 0.6f, 100 ); val += random() * 0.5f; VectorCopy( &flashorigin, &fxSArgs.origin ); VectorClear( &fxSArgs.vel ); VectorClear( &fxSArgs.accel ); fxSArgs.scale = 3.0f*val*scale; fxSArgs.dscale = 0.0f; fxSArgs.sAlpha = 0.7f; fxSArgs.eAlpha = 0.7f; fxSArgs.rotation = random() * 360; fxSArgs.bounce = 0.0f; fxSArgs.life = 1.0f; fxSArgs.shader = shader; fxSArgs.flags = 0x08000000; trap->FX_AddSprite( &fxSArgs ); } // 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; // add the flash if ( weaponNum != WP_DEMP2 || (nonPredictedCent->currentState.eFlags & EF_FIRING) ) { // impulse flash if ( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME ) return; } if ( ps || cg.renderingThirdPerson || cg_trueGuns.integer || cent->currentState.number != cg.predictedPlayerState.clientNum ) { // Make sure we don't do the thirdperson model effects for the local player if we're in first person vector3 flashorigin, flashdir; refEntity_t tpflash; memset( &tpflash, 0, sizeof(tpflash) ); if ( !thirdPerson ) { CG_PositionEntityOnTag( &tpflash, &gun, gun.hModel, "tag_flash" ); VectorCopy( &tpflash.origin, &flashorigin ); VectorCopy( &tpflash.axis[0], &flashdir ); } else { mdxaBone_t boltMatrix; // it's quite possible that we may have have no weapon model and be in a valid state, so return here if this is the case if ( !trap->G2API_HasGhoul2ModelOnIndex( &(cent->ghoul2), 1 ) ) return; // Couldn't find bolt point. if ( !trap->G2API_GetBoltMatrix( cent->ghoul2, 1, 0, &boltMatrix, newAngles, ¢->lerpOrigin, cg.time, cgs.gameModels, ¢->modelScale ) ) return; BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, &flashorigin ); BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_X, &flashdir ); } if ( cg.time - cent->muzzleFlashTime <= MUZZLE_FLASH_TIME + 10 ) { // Handle muzzle flashes if ( cent->currentState.eFlags & EF_ALT_FIRING ) { // Check the alt firing first. if ( weapon->altMuzzleEffect ) { if ( !thirdPerson ) trap->FX_PlayEntityEffectID( weapon->altMuzzleEffect, &flashorigin, tpflash.axis, -1, -1, -1, -1 ); else trap->FX_PlayEffectID( weapon->altMuzzleEffect, &flashorigin, &flashdir, -1, -1, qfalse ); } } else { // Regular firing if ( weapon->muzzleEffect ) { if ( !thirdPerson ) trap->FX_PlayEntityEffectID( weapon->muzzleEffect, &flashorigin, tpflash.axis, -1, -1, -1, -1 ); else trap->FX_PlayEffectID( weapon->muzzleEffect, &flashorigin, &flashdir, -1, -1, qfalse ); } } } if ( weapon->flashDlightColor.r || weapon->flashDlightColor.g || weapon->flashDlightColor.b ) { trap->R_AddLightToScene( &flashorigin, 300 + (rand() & 31), weapon->flashDlightColor.r, weapon->flashDlightColor.g, weapon->flashDlightColor.b ); } } }
void JKG_DrawWeaponHolsters( centity_t *cent, refEntity_t legs, float shadowPlane ) { if (cent->currentState.weapon > 0 // UQ1: Issues with weapon 0??? && !(cent->currentState.number == cg.predictedPlayerState.clientNum && !cg.renderingThirdPerson) && cent->currentState.number == cg.clientNum // UQ1: Enemy ones??? Best data transfer method??? && (cent && cent->ghoul2 && cent->currentState.eType != ET_NPC)) { int HOLSTER_POINT = 0; int NUM_HOLSTERS = 5; // UQ1: Extra 2 look stupid... int i = 0; cgItemData_t *LIGHT_ITEMS_LIST[5]; cgItemData_t *HEAVY_ITEMS_LIST[5]; int NUM_LIGHT_ITEMS = 0; int NUM_HEAVY_ITEMS = 0; #ifdef _DEBUG //CG_Printf("Adding holster items...\n"); #endif //_DEBUG for (i = 0; i < 3; i++) LIGHT_ITEMS_LIST[i] = NULL; for (i = 0; i < 2; i++) HEAVY_ITEMS_LIST[i] = NULL; // Create Light Items List... for (i = 0; i < MAX_ACI_SLOTS; i++) { unsigned int weap, var; // FIXME: How to get enemy player ACI list???? // Events? Even the data for just 4 holsters would be crazy... if (cg.playerACI[i] < 0) continue; if (cg.playerInventory[cg.playerACI[i]].id->weapon == cg.predictedPlayerState.weapon) continue; if (cg.playerInventory[cg.playerACI[i]].equipped) continue; if (!cg.playerInventory[cg.playerACI[i]].id) continue; weap = cg.playerInventory[cg.playerACI[i]].id->weapon; var = cg.playerInventory[cg.playerACI[i]].id->variation; // How did this get through equipped above??? if (weap == cent->currentState.weapon) continue; // Quick and dirty choice of where to put guns based on weight... if (cg.playerInventory[cg.playerACI[i]].id->weight > 1) continue; // Too heavy for waist... // FIXME: Sort by new WEAPON_TYPE value... LIGHT_ITEMS_LIST[NUM_LIGHT_ITEMS] = cg.playerInventory[cg.playerACI[i]].id; NUM_LIGHT_ITEMS++; if (NUM_LIGHT_ITEMS >= 3) break; // Full... } // Create Heavy Items List... for (i = 0; i < MAX_ACI_SLOTS; i++) { unsigned int weap, var; // FIXME: How to get enemy player ACI list???? // Events? Even the data for just 4 holsters would be crazy... if (cg.playerACI[i] < 0) continue; if (cg.playerInventory[cg.playerACI[i]].equipped) continue; if (!cg.playerInventory[cg.playerACI[i]].id) continue; weap = cg.playerInventory[cg.playerACI[i]].id->weapon; var = cg.playerInventory[cg.playerACI[i]].id->variation; // How did this get through equipped above??? if (weap == cent->currentState.weapon) continue; // Quick and dirty choice of where to put guns based on weight... if (cg.playerInventory[cg.playerACI[i]].id->weight <= 1) continue; // Too light for back... // FIXME: Sort by new WEAPON_TYPE value... HEAVY_ITEMS_LIST[NUM_HEAVY_ITEMS] = cg.playerInventory[cg.playerACI[i]].id; NUM_HEAVY_ITEMS++; if (NUM_HEAVY_ITEMS >= 2) break; // Full... } for(HOLSTER_POINT = 0; HOLSTER_POINT < NUM_HOLSTERS; HOLSTER_POINT++) { void *weaponGhoul2 = NULL; refEntity_t holsterRefEnt; int WEAPON_NUM = 0; weaponInfo_t *weapon = NULL; if (HOLSTER_POINT == 0 && NUM_LIGHT_ITEMS < 1) continue; // No more light items to draw... if (HOLSTER_POINT == 1 && NUM_LIGHT_ITEMS < 2) continue; // No more light items to draw... //if (HOLSTER_POINT == 2 && NUM_LIGHT_ITEMS < 3) continue; // No more light items to draw... if (HOLSTER_POINT == 2) continue; // Disabled... if (HOLSTER_POINT == 3 && NUM_HEAVY_ITEMS < 1) continue; // No more heavy items to draw... if (HOLSTER_POINT == 4 && NUM_HEAVY_ITEMS < 2) continue; // No more heavy items to draw... if (HOLSTER_POINT < 3) { if (LIGHT_ITEMS_LIST[HOLSTER_POINT]) { // Light Items (waist)... WEAPON_NUM = LIGHT_ITEMS_LIST[HOLSTER_POINT]->weapon; if (WEAPON_NUM <= 0) continue; weapon = CG_WeaponInfo (WEAPON_NUM, LIGHT_ITEMS_LIST[HOLSTER_POINT]->variation); } else { continue; } } else { if (HEAVY_ITEMS_LIST[HOLSTER_POINT-3]) { // Heavy Items (back)... WEAPON_NUM = HEAVY_ITEMS_LIST[HOLSTER_POINT-3]->weapon; if (WEAPON_NUM <= 0) continue; weapon = CG_WeaponInfo (WEAPON_NUM, HEAVY_ITEMS_LIST[HOLSTER_POINT-3]->variation); } else { continue; } } if (!weapon) continue; memset( &holsterRefEnt, 0, sizeof( holsterRefEnt ) ); weaponGhoul2 = weapon->g2WorldModel; if (trap_G2_HaveWeGhoul2Models(weaponGhoul2)) { char bone_name[MAX_QPATH]; vec3_t holsterAngles, end, fwd, rt, originalOrigin; // UQ1: Which bone are we using? if (HOLSTER_POINT == 0) Q_strncpyz( bone_name , "pelvis", sizeof( bone_name ) ); if (HOLSTER_POINT == 1) Q_strncpyz( bone_name , "pelvis", sizeof( bone_name ) ); if (HOLSTER_POINT == 2) Q_strncpyz( bone_name , "thoracic", sizeof( bone_name ) ); if (HOLSTER_POINT == 3) Q_strncpyz( bone_name , "thoracic", sizeof( bone_name ) ); if (HOLSTER_POINT == 4) Q_strncpyz( bone_name , "thoracic", sizeof( bone_name ) ); //if (HOLSTER_POINT == 4) Q_strncpyz( bone_name , "ltibia", sizeof( bone_name ) ); // UQ1: These look really dumb.... //if (HOLSTER_POINT == 5) Q_strncpyz( bone_name , "rtibia", sizeof( bone_name ) ); // UQ1: These look really dumb.... // UQ1: Set exact org/angles for this bone... if (!CG_SnapRefEntToBone(cent, &holsterRefEnt, bone_name)) { #ifdef _DEBUG CG_Printf("Holster point %i NOT drawn (snap to bone issue)...\n", HOLSTER_POINT); assert(0); #endif // continue; } VectorCopy( legs.modelScale, holsterRefEnt.modelScale); holsterRefEnt.radius = legs.radius; VectorCopy(holsterRefEnt.origin, originalOrigin); VectorCopy(cent->lerpAngles, holsterAngles); holsterAngles[PITCH] = 0; holsterAngles[ROLL] = 0; AngleVectors( holsterAngles, fwd, rt, NULL ); // UQ1: Now modify the org/angles... switch (HOLSTER_POINT) { case 0: // "pelvis" left VectorMA( originalOrigin, -2, fwd, end ); VectorMA( end, -6, rt, end ); VectorCopy(end, holsterRefEnt.origin); holsterRefEnt.origin[2] += 8; // because the bones suck for placement... //AxisToAngles(holsterRefEnt.axis, holsterAngles); holsterAngles[PITCH] += 90; //holsterAngles[YAW] -= 90; holsterAngles[ROLL] += 90; holsterAngles[PITCH] += 30; holsterAngles[YAW] -= 50; holsterAngles[ROLL] -= 50; break; case 1: // "pelvis" right VectorMA( originalOrigin, -2, fwd, end ); VectorMA( end, 6, rt, end ); VectorCopy(end, holsterRefEnt.origin); holsterRefEnt.origin[2] += 8; // because the bones suck for placement... //AxisToAngles(holsterRefEnt.axis, holsterAngles); holsterAngles[PITCH] += 90; holsterAngles[YAW] += 180; holsterAngles[ROLL] += 90; holsterAngles[PITCH] -= 30; holsterAngles[YAW] += 50; holsterAngles[ROLL] += 50; break; case 2: // "thoracic" left - used for center pistol - where on the back is this meant to fit??? VectorMA( originalOrigin, -4, fwd, end ); VectorMA( end, -2, rt, end ); VectorCopy(end, holsterRefEnt.origin); holsterRefEnt.origin[2] += 8; // because the bones suck for placement... //AxisToAngles(holsterRefEnt.axis, holsterAngles); holsterAngles[PITCH] += 90; //holsterAngles[YAW] -= 90; holsterAngles[ROLL] += 90; holsterAngles[PITCH] += 10;//d_poff.value; holsterAngles[YAW] += 0;//d_yoff.value; holsterAngles[ROLL] += 0;//d_roff.value; break; case 3: // "thoracic" left VectorMA( originalOrigin, -4, fwd, end ); VectorMA( end, -6, rt, end ); VectorCopy(end, holsterRefEnt.origin); holsterRefEnt.origin[2] += 6; // because the bones suck for placement... //AxisToAngles(holsterRefEnt.axis, holsterAngles); holsterAngles[PITCH] += 90; //holsterAngles[YAW] -= 90; holsterAngles[ROLL] += 90; holsterAngles[PITCH] += 10 + 25; holsterAngles[YAW] += 50 + 15; holsterAngles[ROLL] += 50; break; case 4: // "thoracic" right VectorMA( originalOrigin, -4, fwd, end ); VectorMA( end, 6, rt, end ); VectorCopy(end, holsterRefEnt.origin); holsterRefEnt.origin[2] += 6; // because the bones suck for placement... //AxisToAngles(holsterRefEnt.axis, holsterAngles); holsterAngles[PITCH] += 90; holsterAngles[YAW] += 180; holsterAngles[ROLL] += 90; holsterAngles[PITCH] -= 10 + 25; holsterAngles[YAW] -= 50 + 15; holsterAngles[ROLL] -= 50; break; /*case 5: // UQ1: These look really dumb.... // "ltibia" VectorMA( originalOrigin, -4, fwd, end ); VectorMA( end, -4, rt, end ); VectorCopy(end, holsterRefEnt.origin); holsterRefEnt.origin[2] += 8; // because the bones suck for placement... holsterAngles[PITCH] += 90; //holsterAngles[YAW] -= 90; holsterAngles[ROLL] += 90; holsterAngles[PITCH] -= d_poff.value; holsterAngles[YAW] -= d_yoff.value; holsterAngles[ROLL] -= d_roff.value; break; case 6: // UQ1: These look really dumb.... // "rtibia" VectorMA( originalOrigin, -4, fwd, end ); VectorMA( end, 4, rt, end ); VectorCopy(end, holsterRefEnt.origin); holsterRefEnt.origin[2] += 8; // because the bones suck for placement... holsterAngles[PITCH] += 90; holsterAngles[YAW] += 180; holsterAngles[ROLL] += 90; holsterAngles[PITCH] += d_poff.value; holsterAngles[YAW] += d_yoff.value; holsterAngles[ROLL] += d_roff.value; break;*/ default: continue; // should never see this... break; } holsterRefEnt.reType = RT_MODEL; holsterRefEnt.hModel = 0; holsterRefEnt.ghoul2 = weaponGhoul2; AnglesToAxis(holsterAngles, holsterRefEnt.axis); holsterRefEnt.shadowPlane = shadowPlane; CG_AddWeaponWithPowerups( &holsterRefEnt, cent->currentState.powerups ); #ifdef _DEBUG //CG_Printf("Holster point %i drawn at %f %f %f (P.ORG %f %f %f)...\n", HOLSTER_POINT, holsterRefEnt.origin[0], holsterRefEnt.origin[1], holsterRefEnt.origin[2], cent->lerpOrigin[0], cent->lerpOrigin[1], cent->lerpOrigin[2]); #endif //_DEBUG } #ifdef _DEBUG else { //CG_Printf("Holster point %i NOT drawn...\n", HOLSTER_POINT); //assert(0); } #endif //_DEBUG } } }