bool WeaponHasAttachments(entity_state_t *pplayer) { studiohdr_t *modelheader = NULL; model_t *pweaponmodel; if (!pplayer) return false; pweaponmodel = IEngineStudio.GetModelByIndex(pplayer->weaponmodel); modelheader = (studiohdr_t *)IEngineStudio.Mod_Extradata(pweaponmodel); return (modelheader->numattachments != 0); }
int V_FindViewModelByWeaponModel(int weaponindex) { static char * modelmap[][2] = { { "models/p_crossbow.mdl", "models/v_crossbow.mdl" }, { "models/p_crowbar.mdl", "models/v_crowbar.mdl" }, { "models/p_egon.mdl", "models/v_egon.mdl" }, { "models/p_gauss.mdl", "models/v_gauss.mdl" }, { "models/p_9mmhandgun.mdl", "models/v_9mmhandgun.mdl" }, { "models/p_grenade.mdl", "models/v_grenade.mdl" }, { "models/p_hgun.mdl", "models/v_hgun.mdl" }, { "models/p_9mmAR.mdl", "models/v_9mmAR.mdl" }, { "models/p_357.mdl", "models/v_357.mdl" }, { "models/p_rpg.mdl", "models/v_rpg.mdl" }, { "models/p_shotgun.mdl", "models/v_shotgun.mdl" }, { "models/p_squeak.mdl", "models/v_squeak.mdl" }, { "models/p_tripmine.mdl", "models/v_tripmine.mdl" }, { "models/p_satchel_radio.mdl", "models/v_satchel_radio.mdl"}, // Fograin92: This will be changed in future { "models/p_satchel.mdl", "models/v_satchel.mdl" }, { NULL, NULL } }; struct model_s * weaponModel = IEngineStudio.GetModelByIndex( weaponindex ); if ( weaponModel ) { int len = strlen( weaponModel->name ); int i = 0; while ( modelmap[i] != NULL ) { if ( !strnicmp( weaponModel->name, modelmap[i][0], len ) ) { return gEngfuncs.pEventAPI->EV_FindModelIndex( modelmap[i][1] ); } i++; } return 0; } else return 0; }
int V_FindViewModelByWeaponModel(int weaponindex) { static char * modelmap[][2] = { #ifdef THREEWAVE // { "models/p_grapple.mdl", "models/v_grapple.mdl" }, #endif { "models/p_crowbar.mdl", "models/v_crowbar.mdl" }, { "models/p_shot.mdl", "models/v_shot.mdl" }, { "models/p_shot2.mdl", "models/v_shot2.mdl" }, { "models/p_nail.mdl", "models/v_nail.mdl" }, { "models/p_nail2.mdl", "models/v_nail2.mdl" }, { "models/p_rock.mdl", "models/v_rock.mdl" }, { "models/p_rock2.mdl", "models/v_rock2.mdl" }, { "models/p_light.mdl", "models/v_light.mdl" }, { NULL, NULL } }; struct model_s * weaponModel = IEngineStudio.GetModelByIndex( weaponindex ); if ( weaponModel ) { int len = strlen( weaponModel->name ); int i = 0; while ( *modelmap[i] != NULL ) { if ( !strnicmp( weaponModel->name, modelmap[i][0], len ) ) { return gEngfuncs.pEventAPI->EV_FindModelIndex( modelmap[i][1] ); } i++; } return 0; } else return 0; }
int V_FindViewModelByWeaponModel( int iWeaponIndex ) { model_t *pWeaponModel = IEngineStudio.GetModelByIndex( iWeaponIndex ); if ( pWeaponModel && pWeaponModel->name ) { static char szViewModelName[MAX_MODEL_NAME]; strncpy( szViewModelName, pWeaponModel->name, sizeof( szViewModelName ) ); char *szSub = strstr( szViewModelName, "/p_" ); if( szSub ) { // szSub pointer is a part of szViewModelName szSub[1] = 'v'; return gEngfuncs.pEventAPI->EV_FindModelIndex(szViewModelName); } return 0; } else return 0; }
int V_FindViewModelByWeaponModel(int weaponindex) { static char * modelmap[][2] = { { "models/p_knife.mdl", "models/v_knife.mdl" }, { "models/p_sabre.mdl", "models/v_sabre.mdl" }, { "models/p_tomahawk.mdl", "models/v_tomahawk.mdl" }, { "models/p_brownbess.mdl", "models/v_brownbess.mdl" }, { "models/p_pennsylvania.mdl", "models/v_pennsylvania.mdl" }, { "models/p_charleville.mdl", "models/v_charleville.mdl" }, { "models/p_revolutionnaire.mdl","models/v_revolutionnaire.mdl" }, { "models/p_pistol_british.mdl","models/v_pistol_british.mdl" }, { "models/p_pistol_american.mdl","models/v_pistol_american.mdl" }, { NULL, NULL } }; struct model_s * weaponModel = IEngineStudio.GetModelByIndex( weaponindex ); if ( weaponModel ) { int len = strlen( weaponModel->name ); int i = 0; while ( modelmap[i] != NULL ) { if ( !strnicmp( weaponModel->name, modelmap[i][0], len ) ) { return gEngfuncs.pEventAPI->EV_FindModelIndex( modelmap[i][1] ); } i++; } return 0; } else return 0; }
int CGameStudioModelRenderer::_StudioDrawPlayer(int flags, entity_state_t *pplayer) { m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); IEngineStudio.GetTimes(&m_nFrameCount, &m_clTime, &m_clOldTime); IEngineStudio.GetViewInfo(m_vRenderOrigin, m_vUp, m_vRight, m_vNormal); IEngineStudio.GetAliasScale(&m_fSoftwareXScale, &m_fSoftwareYScale); m_nPlayerIndex = pplayer->number - 1; if (m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients()) return 0; m_pRenderModel = IEngineStudio.SetupPlayerModel(m_nPlayerIndex); if (m_pRenderModel == NULL) return 0; m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(m_pRenderModel); IEngineStudio.StudioSetHeader(m_pStudioHeader); IEngineStudio.SetRenderModel(m_pRenderModel); if (m_pCurrentEntity->curstate.sequence >= m_pStudioHeader->numseq) m_pCurrentEntity->curstate.sequence = 0; if (pplayer->sequence >= m_pStudioHeader->numseq) pplayer->sequence = 0; if (m_pCurrentEntity->curstate.gaitsequence >= m_pStudioHeader->numseq) m_pCurrentEntity->curstate.gaitsequence = 0; if (pplayer->gaitsequence >= m_pStudioHeader->numseq) pplayer->gaitsequence = 0; if (pplayer->gaitsequence) { vec3_t orig_angles; m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); VectorCopy(m_pCurrentEntity->angles, orig_angles); StudioProcessGait(pplayer); m_pPlayerInfo->gaitsequence = pplayer->gaitsequence; m_pPlayerInfo = NULL; StudioSetUpTransform(0); VectorCopy(orig_angles, m_pCurrentEntity->angles); } else { m_pCurrentEntity->curstate.controller[0] = 127; m_pCurrentEntity->curstate.controller[1] = 127; m_pCurrentEntity->curstate.controller[2] = 127; m_pCurrentEntity->curstate.controller[3] = 127; m_pCurrentEntity->latched.prevcontroller[0] = m_pCurrentEntity->curstate.controller[0]; m_pCurrentEntity->latched.prevcontroller[1] = m_pCurrentEntity->curstate.controller[1]; m_pCurrentEntity->latched.prevcontroller[2] = m_pCurrentEntity->curstate.controller[2]; m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); CalculatePitchBlend(pplayer); CalculateYawBlend(pplayer); m_pPlayerInfo->gaitsequence = 0; StudioSetUpTransform(0); } if (flags & STUDIO_RENDER) { (*m_pModelsDrawn)++; (*m_pStudioModelCount)++; if (m_pStudioHeader->numbodyparts == 0) return 1; } m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); StudioSetupBones(); StudioSaveBones(); m_pPlayerInfo->renderframe = m_nFrameCount; m_pPlayerInfo = NULL; if (flags & STUDIO_EVENTS && (!(flags & STUDIO_RENDER) || !pplayer->weaponmodel || !WeaponHasAttachments(pplayer))) { StudioCalcAttachments(); IEngineStudio.StudioClientEvents(); if (m_pCurrentEntity->index > 0) { cl_entity_t *ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index); memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * 4); } } if (flags & STUDIO_RENDER) { alight_t lighting; vec3_t dir; lighting.plightvec = dir; IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting); IEngineStudio.StudioEntityLight(&lighting); IEngineStudio.StudioSetupLighting(&lighting); m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); m_nTopColor = m_pPlayerInfo->topcolor; if (m_nTopColor < 0) m_nTopColor = 0; if (m_nTopColor > 360) m_nTopColor = 360; m_nBottomColor = m_pPlayerInfo->bottomcolor; if (m_nBottomColor < 0) m_nBottomColor = 0; if (m_nBottomColor > 360) m_nBottomColor = 360; IEngineStudio.StudioSetRemapColors(m_nTopColor, m_nBottomColor); StudioRenderModel(dir); m_pPlayerInfo = NULL; if (pplayer->weaponmodel) { studiohdr_t *saveheader = m_pStudioHeader; cl_entity_t saveent = *m_pCurrentEntity; model_t *pweaponmodel = IEngineStudio.GetModelByIndex(pplayer->weaponmodel); m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(pweaponmodel); IEngineStudio.StudioSetHeader(m_pStudioHeader); StudioMergeBones(pweaponmodel); IEngineStudio.StudioSetupLighting(&lighting); StudioRenderModel(dir); StudioCalcAttachments(); if (m_pCurrentEntity->index > 0) memcpy(saveent.attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * m_pStudioHeader->numattachments); *m_pCurrentEntity = saveent; m_pStudioHeader = saveheader; IEngineStudio.StudioSetHeader(m_pStudioHeader); if (flags & STUDIO_EVENTS) IEngineStudio.StudioClientEvents(); } } if( cl_shadows->value != 0.0f ) { StudioDrawShadow(m_pCurrentEntity->origin, 20.0f); } return 1; }
/* ================== V_CalcSpectatorRefdef ================== */ void V_CalcSpectatorRefdef ( struct ref_params_s * pparams ) { static vec3_t velocity ( 0.0f, 0.0f, 0.0f); static int lastWeaponModelIndex = 0; static int lastViewModelIndex = 0; cl_entity_t * ent = gEngfuncs.GetEntityByIndex( g_iUser2 ); pparams->onlyClientDraw = false; // refresh position VectorCopy ( pparams->simorg, v_sim_org ); // get old values VectorCopy ( pparams->cl_viewangles, v_cl_angles ); VectorCopy ( pparams->viewangles, v_angles ); VectorCopy ( pparams->vieworg, v_origin ); if ( ( g_iUser1 == OBS_IN_EYE || gHUD.m_Spectator.m_pip->value == INSET_IN_EYE ) && ent ) { // calculate player velocity float timeDiff = ent->curstate.msg_time - ent->prevstate.msg_time; if ( timeDiff > 0 ) { vec3_t distance; VectorSubtract(ent->prevstate.origin, ent->curstate.origin, distance); VectorScale(distance, 1/timeDiff, distance ); velocity[0] = velocity[0]*0.9f + distance[0]*0.1f; velocity[1] = velocity[1]*0.9f + distance[1]*0.1f; velocity[2] = velocity[2]*0.9f + distance[2]*0.1f; VectorCopy(velocity, pparams->simvel); } // predict missing client data and set weapon model ( in HLTV mode or inset in eye mode ) #ifdef _TFC if ( gEngfuncs.IsSpectateOnly() || gHUD.m_Spectator.m_pip->value == INSET_IN_EYE ) #else if ( gEngfuncs.IsSpectateOnly() ) #endif { V_GetInEyePos( g_iUser2, pparams->simorg, pparams->cl_viewangles ); pparams->health = 1; cl_entity_t * gunModel = gEngfuncs.GetViewModel(); if ( lastWeaponModelIndex != ent->curstate.weaponmodel ) { // weapon model changed lastWeaponModelIndex = ent->curstate.weaponmodel; lastViewModelIndex = V_FindViewModelByWeaponModel( lastWeaponModelIndex ); if ( lastViewModelIndex ) { gEngfuncs.pfnWeaponAnim(0,0); // reset weapon animation } else { // model not found gunModel->model = NULL; // disable weapon model lastWeaponModelIndex = lastViewModelIndex = 0; } } if ( lastViewModelIndex ) { gunModel->model = IEngineStudio.GetModelByIndex( lastViewModelIndex ); gunModel->curstate.modelindex = lastViewModelIndex; gunModel->curstate.frame = 0; gunModel->curstate.colormap = 0; gunModel->index = g_iUser2; } else { gunModel->model = NULL; // disable weaopn model } } else { // only get viewangles from entity VectorCopy ( ent->angles, pparams->cl_viewangles ); pparams->cl_viewangles[PITCH]*=-3.0f; // see CL_ProcessEntityUpdate() } } v_frametime = pparams->frametime; if ( pparams->nextView == 0 ) { // first renderer cycle, full screen switch ( g_iUser1 ) { case OBS_CHASE_LOCKED: V_GetChasePos( g_iUser2, NULL, v_origin, v_angles ); break; case OBS_CHASE_FREE: V_GetChasePos( g_iUser2, v_cl_angles, v_origin, v_angles ); break; case OBS_ROAMING : VectorCopy (v_cl_angles, v_angles); VectorCopy (v_sim_org, v_origin); // override values if director is active gHUD.m_Spectator.GetDirectorCamera(v_origin, v_angles); break; case OBS_IN_EYE : V_CalcNormalRefdef ( pparams ); break; case OBS_MAP_FREE : pparams->onlyClientDraw = true; V_GetMapFreePosition( v_cl_angles, v_origin, v_angles ); break; case OBS_MAP_CHASE : pparams->onlyClientDraw = true; V_GetMapChasePosition( g_iUser2, v_cl_angles, v_origin, v_angles ); break; } if ( gHUD.m_Spectator.m_pip->value ) pparams->nextView = 1; // force a second renderer view gHUD.m_Spectator.m_iDrawCycle = 0; } else { // second renderer cycle, inset window // set inset parameters pparams->viewport[0] = XRES(gHUD.m_Spectator.m_OverviewData.insetWindowX); // change viewport to inset window pparams->viewport[1] = YRES(gHUD.m_Spectator.m_OverviewData.insetWindowY); pparams->viewport[2] = XRES(gHUD.m_Spectator.m_OverviewData.insetWindowWidth); pparams->viewport[3] = YRES(gHUD.m_Spectator.m_OverviewData.insetWindowHeight); pparams->nextView = 0; // on further view // override some settings in certain modes switch ( (int)gHUD.m_Spectator.m_pip->value ) { case INSET_CHASE_FREE : V_GetChasePos( g_iUser2, v_cl_angles, v_origin, v_angles ); break; case INSET_IN_EYE : V_CalcNormalRefdef ( pparams ); break; case INSET_MAP_FREE : pparams->onlyClientDraw = true; V_GetMapFreePosition( v_cl_angles, v_origin, v_angles ); break; case INSET_MAP_CHASE : pparams->onlyClientDraw = true; if ( g_iUser1 == OBS_ROAMING ) V_GetMapChasePosition( 0, v_cl_angles, v_origin, v_angles ); else V_GetMapChasePosition( g_iUser2, v_cl_angles, v_origin, v_angles ); break; } gHUD.m_Spectator.m_iDrawCycle = 1; } // write back new values into pparams VectorCopy ( v_cl_angles, pparams->cl_viewangles ); VectorCopy ( v_angles, pparams->viewangles ) VectorCopy ( v_origin, pparams->vieworg ); }
int V_FindViewModelByWeaponModel(int weaponindex) { static char * modelmap[][2] = { # ifdef _TFC // TFC models override HL models { "models/p_mini.mdl", "models/v_tfac.mdl" }, { "models/p_sniper.mdl", "models/v_tfc_sniper.mdl" }, { "models/p_umbrella.mdl", "models/v_umbrella.mdl" }, { "models/p_crowbar.mdl", "models/v_tfc_crowbar.mdl" }, { "models/p_spanner.mdl", "models/v_tfc_spanner.mdl" }, { "models/p_knife.mdl", "models/v_tfc_knife.mdl" }, { "models/p_medkit.mdl", "models/v_tfc_medkit.mdl" }, { "models/p_egon.mdl", "models/v_flame.mdl" }, { "models/p_glauncher.mdl", "models/v_tfgl.mdl" }, { "models/p_rpg.mdl", "models/v_tfc_rpg.mdl" }, { "models/p_nailgun.mdl", "models/v_tfc_nailgun.mdl" }, { "models/p_snailgun.mdl", "models/v_tfc_supernailgun.mdl" }, { "models/p_9mmhandgun.mdl", "models/v_tfc_railgun.mdl" }, { "models/p_srpg.mdl", "models/v_tfc_rpg.mdl" }, { "models/p_smallshotgun.mdl", "models/v_tfc_12gauge.mdl" }, { "models/p_shotgun.mdl", "models/v_tfc_shotgun.mdl" }, { "models/p_spygun.mdl", "models/v_tfc_pistol.mdl" }, #endif { "models/p_crossbow.mdl", "models/v_crossbow.mdl" }, { "models/p_crowbar.mdl", "models/v_crowbar.mdl" }, { "models/p_egon.mdl", "models/v_egon.mdl" }, { "models/p_gauss.mdl", "models/v_gauss.mdl" }, { "models/p_9mmhandgun.mdl", "models/v_9mmhandgun.mdl" }, { "models/p_grenade.mdl", "models/v_grenade.mdl" }, { "models/p_hgun.mdl", "models/v_hgun.mdl" }, { "models/p_9mmAR.mdl", "models/v_9mmAR.mdl" }, { "models/p_357.mdl", "models/v_357.mdl" }, { "models/p_rpg.mdl", "models/v_rpg.mdl" }, { "models/p_shotgun.mdl", "models/v_shotgun.mdl" }, { "models/p_squeak.mdl", "models/v_squeak.mdl" }, { "models/p_tripmine.mdl", "models/v_tripmine.mdl" }, { "models/p_satchel_radio.mdl", "models/v_satchel_radio.mdl"}, { "models/p_satchel.mdl", "models/v_satchel.mdl" }, { NULL, NULL } }; struct model_s * weaponModel = IEngineStudio.GetModelByIndex( weaponindex ); if ( weaponModel ) { int len = strlen( weaponModel->name ); int i = 0; while ( modelmap[i] != NULL ) { if ( !_strnicmp( weaponModel->name, modelmap[i][0], len ) ) { return gEngfuncs.pEventAPI->EV_FindModelIndex( modelmap[i][1] ); } i++; } return 0; } else return 0; }
/* ==================== _StudioDrawPlayer ==================== */ int CGameStudioModelRenderer::_StudioDrawPlayer(int flags, entity_state_t *pplayer) { alight_t lighting; vec3_t dir; m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); IEngineStudio.GetTimes(&m_nFrameCount, &m_clTime, &m_clOldTime); IEngineStudio.GetViewInfo(m_vRenderOrigin, m_vUp, m_vRight, m_vNormal); IEngineStudio.GetAliasScale(&m_fSoftwareXScale, &m_fSoftwareYScale); m_nPlayerIndex = pplayer->number - 1; if(m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients()) return 0; m_pRenderModel = IEngineStudio.SetupPlayerModel(m_nPlayerIndex); if(m_pRenderModel == NULL) return 0; m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(m_pRenderModel); IEngineStudio.StudioSetHeader(m_pStudioHeader); IEngineStudio.SetRenderModel(m_pRenderModel); if(pplayer->gaitsequence) { vec3_t orig_angles; m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); VectorCopy(m_pCurrentEntity->angles, orig_angles); StudioProcessGait(pplayer); m_pPlayerInfo->gaitsequence = pplayer->gaitsequence; m_pPlayerInfo = NULL; StudioSetUpTransform(0); VectorCopy(orig_angles, m_pCurrentEntity->angles); } else { m_pCurrentEntity->curstate.controller[0] = 127; m_pCurrentEntity->curstate.controller[1] = 127; m_pCurrentEntity->curstate.controller[2] = 127; m_pCurrentEntity->curstate.controller[3] = 127; m_pCurrentEntity->latched.prevcontroller[0] = m_pCurrentEntity->curstate.controller[0]; m_pCurrentEntity->latched.prevcontroller[1] = m_pCurrentEntity->curstate.controller[1]; m_pCurrentEntity->latched.prevcontroller[2] = m_pCurrentEntity->curstate.controller[2]; m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); m_pPlayerInfo->gaitsequence = 0; StudioSetUpTransform(0); } if(flags & STUDIO_RENDER) { // see if the bounding box lets us trivially reject, also sets if(!IEngineStudio.StudioCheckBBox()) return 0; (*m_pModelsDrawn)++; (*m_pStudioModelCount)++; // render data cache cookie if(m_pStudioHeader->numbodyparts == 0) return 1; } m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); StudioSetupBones(); StudioSaveBones(); m_pPlayerInfo->renderframe = m_nFrameCount; m_pPlayerInfo = NULL; if(flags & STUDIO_EVENTS) { StudioCalcAttachments(); IEngineStudio.StudioClientEvents(); // copy attachments into global entity array if(m_pCurrentEntity->index > 0) { cl_entity_t *ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index); memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * 4); } } if(flags & STUDIO_RENDER) { /* if (m_pCvarHiModels->value && m_pRenderModel != m_pCurrentEntity->model ) { // show highest resolution multiplayer model m_pCurrentEntity->curstate.body = 255; } if (!(m_pCvarDeveloper->value == 0 && gEngfuncs.GetMaxClients() == 1 ) && ( m_pRenderModel == m_pCurrentEntity->model ) ) { m_pCurrentEntity->curstate.body = 1; // force helmet } */ lighting.plightvec = dir; IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting); IEngineStudio.StudioEntityLight(&lighting); // model and frame independant IEngineStudio.StudioSetupLighting(&lighting); m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); // get remap colors m_nTopColor = m_pPlayerInfo->topcolor; if(m_nTopColor < 0) m_nTopColor = 0; if(m_nTopColor > 360) m_nTopColor = 360; m_nBottomColor = m_pPlayerInfo->bottomcolor; if(m_nBottomColor < 0) m_nBottomColor = 0; if(m_nBottomColor > 360) m_nBottomColor = 360; IEngineStudio.StudioSetRemapColors(m_nTopColor, m_nBottomColor); StudioRenderModel(); m_pPlayerInfo = NULL; if(pplayer->weaponmodel) { cl_entity_t saveent = *m_pCurrentEntity; model_t *pweaponmodel = IEngineStudio.GetModelByIndex(pplayer->weaponmodel); m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(pweaponmodel); IEngineStudio.StudioSetHeader(m_pStudioHeader); StudioMergeBones(pweaponmodel); IEngineStudio.StudioSetupLighting(&lighting); StudioRenderModel(); StudioCalcAttachments(); *m_pCurrentEntity = saveent; } } return 1; }
int V_FindViewModelByWeaponModel(int weaponindex) { //TODO: this shouldn't be hardcoded. - Solokiller static const char* const modelmap[][2] = { # ifdef _TFC // TFC models override HL models { "models/p_mini.mdl", "models/v_tfac.mdl" }, { "models/p_sniper.mdl", "models/v_tfc_sniper.mdl" }, { "models/p_umbrella.mdl", "models/v_umbrella.mdl" }, { "models/p_crowbar.mdl", "models/v_tfc_crowbar.mdl" }, { "models/p_spanner.mdl", "models/v_tfc_spanner.mdl" }, { "models/p_knife.mdl", "models/v_tfc_knife.mdl" }, { "models/p_medkit.mdl", "models/v_tfc_medkit.mdl" }, { "models/p_egon.mdl", "models/v_flame.mdl" }, { "models/p_glauncher.mdl", "models/v_tfgl.mdl" }, { "models/p_rpg.mdl", "models/v_tfc_rpg.mdl" }, { "models/p_nailgun.mdl", "models/v_tfc_nailgun.mdl" }, { "models/p_snailgun.mdl", "models/v_tfc_supernailgun.mdl" }, { "models/p_9mmhandgun.mdl", "models/v_tfc_railgun.mdl" }, { "models/p_srpg.mdl", "models/v_tfc_rpg.mdl" }, { "models/p_smallshotgun.mdl", "models/v_tfc_12gauge.mdl" }, { "models/p_shotgun.mdl", "models/v_tfc_shotgun.mdl" }, { "models/p_spygun.mdl", "models/v_tfc_pistol.mdl" }, #endif { "models/p_crossbow.mdl", "models/v_crossbow.mdl" }, { "models/p_crowbar.mdl", "models/v_crowbar.mdl" }, { "models/p_egon.mdl", "models/v_egon.mdl" }, { "models/p_gauss.mdl", "models/v_gauss.mdl" }, { "models/p_9mmhandgun.mdl", "models/v_9mmhandgun.mdl" }, { "models/p_grenade.mdl", "models/v_grenade.mdl" }, { "models/p_hgun.mdl", "models/v_hgun.mdl" }, { "models/p_9mmAR.mdl", "models/v_9mmAR.mdl" }, { "models/p_357.mdl", "models/v_357.mdl" }, { "models/p_rpg.mdl", "models/v_rpg.mdl" }, { "models/p_shotgun.mdl", "models/v_shotgun.mdl" }, { "models/p_squeak.mdl", "models/v_squeak.mdl" }, { "models/p_tripmine.mdl", "models/v_tripmine.mdl" }, { "models/p_satchel_radio.mdl", "models/v_satchel_radio.mdl"}, { "models/p_satchel.mdl", "models/v_satchel.mdl" }, #if USE_OPFOR { "models/p_pipe_wrench.mdl", "models/v_pipe_wrench.mdl" }, { "models/p_m40a1.mdl", "models/v_m40a1.mdl" }, #endif { nullptr, nullptr } }; model_t * weaponModel = IEngineStudio.GetModelByIndex( weaponindex ); if ( weaponModel ) { int len = strlen( weaponModel->name ); int i = 0; while ( modelmap[i] != NULL ) { if ( !strnicmp( weaponModel->name, modelmap[i][0], len ) ) { return gEngfuncs.pEventAPI->EV_FindModelIndex( modelmap[i][1] ); } i++; } return 0; } else return 0; }
/* ================== V_CalcSpectatorRefdef ================== */ void V_CalcSpectatorRefdef ( struct ref_params_s * pparams ) { vec3_t angles; static viewinterp_t ViewInterp; static float bob = 0.0f; static vec3_t velocity ( 0.0f, 0.0f, 0.0f); static int lastWeaponModelIndex = 0; static int lastViewModelIndex = 0; cl_entity_t * ent = gEngfuncs.GetEntityByIndex( g_iUser2 ); cl_entity_t * gunModel = gEngfuncs.GetViewModel(); static float lasttime; static float lastang[3]; static float lastorg[3]; vec3_t delta; pparams->onlyClientDraw = false; // refresh position VectorCopy ( pparams->simorg, v_sim_org ); // get old values VectorCopy ( pparams->cl_viewangles, v_cl_angles ); VectorCopy ( pparams->viewangles, v_angles ); VectorCopy ( pparams->vieworg, v_origin ); v_frametime = pparams->frametime; if ( pparams->nextView == 0 ) { // first renderer cycle, full screen switch ( g_iUser1 ) { case OBS_CHASE_LOCKED: V_GetChasePos( g_iUser2, NULL, v_origin, v_angles ); break; case OBS_CHASE_FREE: V_GetChasePos( g_iUser2, v_cl_angles, v_origin, v_angles ); break; case OBS_ROAMING : VectorCopy (v_cl_angles, v_angles); VectorCopy (v_sim_org, v_origin); break; case OBS_IN_EYE : V_GetInEyePos( g_iUser2, v_origin, v_angles ); break; case OBS_MAP_FREE : pparams->onlyClientDraw = true; V_GetMapFreePosition( v_cl_angles, v_origin, v_angles ); break; case OBS_MAP_CHASE : pparams->onlyClientDraw = true; V_GetMapChasePosition( g_iUser2, v_cl_angles, v_origin, v_angles ); break; } if ( gHUD.m_Spectator.m_pip->value ) pparams->nextView = 1; // force a second renderer view gHUD.m_Spectator.m_iDrawCycle = 0; } else { // second renderer cycle, inset window // set inset parameters pparams->viewport[0] = XRES(gHUD.m_Spectator.m_OverviewData.insetWindowX); // change viewport to inset window pparams->viewport[1] = YRES(gHUD.m_Spectator.m_OverviewData.insetWindowY); pparams->viewport[2] = XRES(gHUD.m_Spectator.m_OverviewData.insetWindowWidth); pparams->viewport[3] = YRES(gHUD.m_Spectator.m_OverviewData.insetWindowHeight); pparams->nextView = 0; // on further view pparams->onlyClientDraw = false; // override some settings in certain modes switch ( (int)gHUD.m_Spectator.m_pip->value ) { case INSET_CHASE_FREE : V_GetChasePos( g_iUser2, v_cl_angles, v_origin, v_angles ); break; case INSET_IN_EYE : V_GetInEyePos( g_iUser2, v_origin, v_angles ); break; case INSET_MAP_FREE : pparams->onlyClientDraw = true; V_GetMapFreePosition( v_cl_angles, v_origin, v_angles ); break; case INSET_MAP_CHASE : pparams->onlyClientDraw = true; if ( g_iUser1 == OBS_ROAMING ) V_GetMapChasePosition( 0, v_cl_angles, v_origin, v_angles ); else V_GetMapChasePosition( g_iUser2, v_cl_angles, v_origin, v_angles ); break; } gHUD.m_Spectator.m_iDrawCycle = 1; } // do the smoothing only once per frame, not in roaming or map mode if ( (gHUD.m_Spectator.m_iDrawCycle == 0) && (g_iUser1 == OBS_IN_EYE) ) { // smooth angles VectorSubtract( v_angles, lastang, delta ); if ( Length( delta ) != 0.0f ) { VectorCopy( v_angles, ViewInterp.Angles[ ViewInterp.CurrentAngle & ORIGIN_MASK ] ); ViewInterp.AngleTime[ ViewInterp.CurrentAngle & ORIGIN_MASK ] = pparams->time; ViewInterp.CurrentAngle++; VectorCopy( v_angles, lastang ); } if ( cl_vsmoothing && cl_vsmoothing->value ) { int foundidx; int i; float t; t = pparams->time - cl_vsmoothing->value; for ( i = 1; i < ORIGIN_MASK; i++ ) { foundidx = ViewInterp.CurrentAngle - 1 - i; if ( ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ] <= t ) break; } if ( i < ORIGIN_MASK && ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ] != 0.0 ) { // Interpolate double dt; float da; vec3_t v1,v2; AngleVectors( ViewInterp.Angles[ foundidx & ORIGIN_MASK ], v1, NULL, NULL ); AngleVectors( ViewInterp.Angles[ (foundidx + 1) & ORIGIN_MASK ], v2, NULL, NULL ); da = AngleBetweenVectors( v1, v2 ); dt = ViewInterp.AngleTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ]; if ( dt > 0.0 && ( da < 22.5f) ) { double frac; frac = ( t - ViewInterp.AngleTime[ foundidx & ORIGIN_MASK] ) / dt; frac = min( 1.0, frac ); // interpolate angles InterpolateAngles( ViewInterp.Angles[ foundidx & ORIGIN_MASK ], ViewInterp.Angles[ (foundidx + 1) & ORIGIN_MASK ], v_angles, frac ); } } } // smooth origin VectorSubtract( v_origin, lastorg, delta ); if ( Length( delta ) != 0.0 ) { VectorCopy( v_origin, ViewInterp.Origins[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] ); ViewInterp.OriginTime[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] = pparams->time; ViewInterp.CurrentOrigin++; VectorCopy( v_origin, lastorg ); } // don't smooth in roaming (already smoothd), if ( cl_vsmoothing && cl_vsmoothing->value ) { int foundidx; int i; float t; t = pparams->time - cl_vsmoothing->value; for ( i = 1; i < ORIGIN_MASK; i++ ) { foundidx = ViewInterp.CurrentOrigin - 1 - i; if ( ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] <= t ) break; } if ( i < ORIGIN_MASK && ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] != 0.0 ) { // Interpolate vec3_t delta; double frac; double dt; vec3_t neworg; dt = ViewInterp.OriginTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ]; if ( dt > 0.0 ) { frac = ( t - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK] ) / dt; frac = min( 1.0, frac ); VectorSubtract( ViewInterp.Origins[ ( foundidx + 1 ) & ORIGIN_MASK ], ViewInterp.Origins[ foundidx & ORIGIN_MASK ], delta ); VectorMA( ViewInterp.Origins[ foundidx & ORIGIN_MASK ], frac, delta, neworg ); // Dont interpolate large changes if ( Length( delta ) < 64 ) { VectorCopy( neworg, v_origin ); } } } } } // Hack in weapon model: if ( (g_iUser1 == OBS_IN_EYE || gHUD.m_Spectator.m_pip->value == INSET_IN_EYE) && ent && g_iUser2 ) { // get position for weapon model VectorCopy( v_origin, gunModel->origin); VectorCopy( v_angles, gunModel->angles); // add idle tremble gunModel->angles[PITCH]*=-1; // calculate player velocity float timeDiff = ent->curstate.msg_time - ent->prevstate.msg_time; if ( timeDiff > 0 ) { vec3_t distance; VectorSubtract(ent->prevstate.origin, ent->curstate.origin, distance); VectorScale(distance, 1/timeDiff, distance ); velocity[0] = velocity[0]*0.66f + distance[0]*0.33f; velocity[1] = velocity[1]*0.66f + distance[1]*0.33f; velocity[2] = velocity[2]*0.66f + distance[2]*0.33f; VectorCopy(velocity, pparams->simvel); pparams->onground = 1; bob = V_CalcBob( pparams ); } vec3_t forward; AngleVectors(v_angles, forward, NULL, NULL ); for ( int i = 0; i < 3; i++ ) { gunModel->origin[ i ] += bob * 0.4 * forward[ i ]; } // throw in a little tilt. gunModel->angles[YAW] -= bob * 0.5; gunModel->angles[ROLL] -= bob * 1; gunModel->angles[PITCH] -= bob * 0.3; VectorCopy( gunModel->angles, gunModel->curstate.angles ); VectorCopy( gunModel->angles, gunModel->latched.prevangles ); if ( lastWeaponModelIndex != ent->curstate.weaponmodel ) { // weapon model changed lastWeaponModelIndex = ent->curstate.weaponmodel; lastViewModelIndex = V_FindViewModelByWeaponModel( lastWeaponModelIndex ); if ( lastViewModelIndex ) { gEngfuncs.pfnWeaponAnim(0,0); // reset weapon animation } else { // model not found gunModel->model = NULL; // disable weaopn model lastWeaponModelIndex = lastViewModelIndex = 0; } } if ( lastViewModelIndex ) { gunModel->model = IEngineStudio.GetModelByIndex( lastViewModelIndex ); gunModel->curstate.modelindex = lastViewModelIndex; gunModel->curstate.frame = 0; gunModel->curstate.colormap = 0; gunModel->index = g_iUser2; } else { gunModel->model = NULL; // disable weaopn model } } else { gunModel->model = NULL; // disable weaopn model lastWeaponModelIndex = lastViewModelIndex = 0; } lasttime = pparams->time; // write back new values into pparams VectorCopy ( v_angles, pparams->viewangles ) VectorCopy ( v_origin, pparams->vieworg ); }