/* =================== CG_AddLocalEntities =================== */ void CG_AddLocalEntities( void ) { localEntity_t *le, *next; // walk the list backwards, so any new local entities generated // (trails, marks, etc) will be present this frame le = cg_activeLocalEntities.prev; for ( ; le != &cg_activeLocalEntities ; le = next ) { // grab next now, so if the local entity is freed we // still have it next = le->prev; if ( cg.time >= le->endTime ) { CG_FreeLocalEntity( le ); continue; } switch ( le->leType ) { default: trap->Error( ERR_DROP, "Bad leType: %i", le->leType ); break; case LE_MARK: break; case LE_SPRITE_EXPLOSION: CG_AddSpriteExplosion( le ); break; case LE_EXPLOSION: CG_AddExplosion( le ); break; case LE_FADE_SCALE_MODEL: CG_AddFadeScaleModel( le ); break; case LE_FRAGMENT: // gibs and brass CG_AddFragment( le ); break; case LE_PUFF: CG_AddPuff( le ); break; case LE_MOVE_SCALE_FADE: // water bubbles CG_AddMoveScaleFade( le ); break; case LE_FADE_RGB: // teleporters, railtrails CG_AddFadeRGB( le ); break; case LE_FALL_SCALE_FADE: // gib blood trails CG_AddFallScaleFade( le ); break; case LE_SCALE_FADE: // rocket trails CG_AddScaleFade( le ); break; case LE_SCOREPLUM: CG_AddScorePlum( le ); break; case LE_OLINE: CG_AddOLine( le ); break; case LE_SHOWREFENTITY: CG_AddRefEntity( le ); break; case LE_LINE: // oriented lines for FX CG_AddLine( le ); break; } } }
/* =================== CG_AddLocalEntities =================== */ void CG_AddLocalEntities( void ) { localEntity_t *le, *next; qboolean forceOnlyMirror; // walk the list backwards, so any new local entities generated // (trails, marks, etc) will be present this frame le = cg_activeLocalEntities.prev; for ( ; le != &cg_activeLocalEntities ; le = next ) { // grab next now, so if the local entity is freed we // still have it next = le->prev; if ( cg.time >= le->endTime ) { CG_FreeLocalEntity( le ); continue; } // Check if local entity should be rendered by this local client. if (le->localClients && !(le->localClients & (1<<cg.cur_localClientNum))) { continue; } forceOnlyMirror = (!(le->refEntity.renderfx & RF_ONLY_MIRROR) && !cg.cur_lc->renderingThirdPerson && cg.snap->pss[cg.cur_localClientNum].clientNum == le->firstPersonEntity); if ( forceOnlyMirror ) { le->refEntity.renderfx |= RF_ONLY_MIRROR; } switch ( le->leType ) { default: CG_Error( "Bad leType: %i", le->leType ); break; case LE_MARK: break; case LE_SPRITE_EXPLOSION: CG_AddSpriteExplosion( le ); break; case LE_EXPLOSION: CG_AddExplosion( le ); break; case LE_FRAGMENT: // gibs and brass CG_AddFragment( le ); break; case LE_MOVE_SCALE_FADE: // water bubbles CG_AddMoveScaleFade( le ); break; case LE_FADE_RGB: // teleporters, railtrails CG_AddFadeRGB( le ); break; case LE_FALL_SCALE_FADE: // gib blood trails CG_AddFallScaleFade( le ); break; case LE_SCALE_FADE: // rocket trails CG_AddScaleFade( le ); break; case LE_SCOREPLUM: CG_AddScorePlum( le ); break; #ifdef MISSIONPACK case LE_KAMIKAZE: CG_AddKamikaze( le ); break; case LE_INVULIMPACT: CG_AddInvulnerabilityImpact( le ); break; case LE_INVULJUICED: CG_AddInvulnerabilityJuiced( le ); break; case LE_SHOWREFENTITY: CG_AddRefEntity( le ); break; #endif } if ( forceOnlyMirror ) { le->refEntity.renderfx &= ~RF_ONLY_MIRROR; } } }
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); } }
/* =================== CG_AddLocalEntities =================== */ void CG_AddLocalEntities( void ) { localEntity_t *le, *next; // walk the list backwards, so any new local entities generated // (trails, marks, etc) will be present this frame le = cg_activeLocalEntities.prev; for ( ; le != &cg_activeLocalEntities ; le = next ) { // grab next now, so if the local entity is freed we // still have it next = le->prev; if ( cg.time >= le->endTime ) { CG_FreeLocalEntity( le ); continue; } switch ( le->leType ) { default: CG_Error( "Bad leType: %i", le->leType ); break; case LE_MARK: break; case LE_SPRITE_EXPLOSION: CG_AddSpriteExplosion( le ); break; case LE_EXPLOSION: CG_AddExplosion( le ); break; case LE_FRAGMENT: // gibs and brass CG_AddFragment( le ); break; case LE_MOVE_SCALE_FADE: // water bubbles CG_AddMoveScaleFade( le ); break; case LE_FADE_RGB: // teleporters, railtrails CG_AddFadeRGB( le ); break; case LE_FALL_SCALE_FADE: // gib blood trails CG_AddFallScaleFade( le ); break; case LE_SCALE_FADE: // rocket trails CG_AddScaleFade( le ); break; case LE_SCOREPLUM: CG_AddScorePlum( le ); break; #ifdef MISSIONPACK case LE_KAMIKAZE: CG_AddKamikaze( le ); break; case LE_INVULIMPACT: CG_AddInvulnerabilityImpact( le ); break; case LE_INVULJUICED: CG_AddInvulnerabilityJuiced( le ); break; case LE_SHOWREFENTITY: CG_AddRefEntity( le ); break; #endif } } }
/* ======================================================================================================================================= CG_AddLocalEntities ======================================================================================================================================= */ void CG_AddLocalEntities(void) { localEntity_t *le, *next; int oldPhysicsTime; // have local entities interact with movers (submodels) at their render position oldPhysicsTime = cg.physicsTime; cg.physicsTime = cg.time; // walk the list backwards, so any new local entities generated (trails, marks, etc.) will be present this frame le = cg_activeLocalEntities.prev; for (; le != &cg_activeLocalEntities; le = next) { // grab next now, so if the local entity is freed we still have it next = le->prev; if (cg.time >= le->endTime) { CG_FreeLocalEntity(le); continue; } switch (le->leType) { default: CG_Error("Bad leType: %i", le->leType); break; case LE_SPRITE_EXPLOSION: CG_AddSpriteExplosion(le); break; case LE_EXPLOSION: CG_AddExplosion(le); break; case LE_KAMIKAZE: CG_AddKamikaze(le); break; case LE_MARK: break; case LE_FRAGMENT: // gibs and brass CG_AddFragment(le); break; case LE_SCALE_FADE: // rocket trails CG_AddScaleFade(le); break; case LE_FADE_RGB: // teleporters, railtrails CG_AddFadeRGB(le); break; case LE_FALL_SCALE_FADE: // gib blood trails CG_AddFallScaleFade(le); break; case LE_MOVE_SCALE_FADE: // water bubbles CG_AddMoveScaleFade(le); break; case LE_BUBBLE: CG_BubbleThink(le); break; case LE_SCOREPLUM: CG_AddScorePlum(le); break; case LE_SHOWREFENTITY: CG_AddRefEntity(le); break; } } cg.physicsTime = oldPhysicsTime; }