📄 viewweapon.cpp
字号:
DFLOAT fReloadTime;
if (m_bLastFireAlt)
fReloadTime = m_fAltReloadTime;
else
fReloadTime = m_fReloadTime;
fReloadTime *= 1; // m_pInventoryMgr->GetFireRateMultiplier();
// See if we should play an idle animation
if((m_pClientDE->GetTime() - m_fIdleStartTime) > m_fIdleDelay)
{
m_pClientDE->SetModelLooping(m_hObject, DFALSE);
PlayAnimation(m_nIdleAnim);
m_eState = WS_IDLE;
}
// Make sure enough time has gone by to allow firing
if(((fTime - m_fLastShotTime) > fReloadTime))
{
if (bFiring && (CheckAmmo(DFALSE) >= m_nAmmoUse))
{
m_fLastShotTime = fTime;
m_eState = WS_START_FIRING;
if (!PlayAnimation(m_nStartFireAnim))
{
m_pClientDE->SetModelLooping(m_hObject, m_bLoopAnim);
PlayAnimation(m_nFireAnim);
m_eState = WS_FIRING;
}
}
else if (bAltFiring && !IsAltFireZoom() && (CheckAmmo(DTRUE) >= m_nAltAmmoUse))
{
m_fLastShotTime = fTime;
m_eState = WS_START_ALT_FIRING;
if (!PlayAnimation(m_nStartAltFireAnim))
{
m_pClientDE->SetModelLooping(m_hObject, m_bAltLoopAnim);
PlayAnimation(m_nAltFireAnim);
m_eState = WS_ALT_FIRING;
}
}
}
}
break;
case WS_DRAW:
{
if(!PlayAnimation(m_nDrawAnim))
{
PlayAnimation(m_nRestAnim);
m_eState = WS_REST;
m_pClientDE->SetModelLooping(m_hObject, m_bLoopStatic);
m_fIdleStartTime = fTime;
}
}
break;
case WS_HOLSTER:
{
if(!PlayAnimation(m_nHolsterAnim))
{
m_eState = WS_HOLSTERED;
m_pClientDE->SetModelLooping(m_hObject, DFALSE);
}
}
break;
case WS_START_ALT_FIRING:
case WS_START_FIRING:
{
bAltFire = (m_eState == WS_START_ALT_FIRING);
if (!PlayAnimation(bAltFire ? m_nStartAltFireAnim : m_nStartFireAnim))
{
if (bAltFire ? m_bAltLoopAnim : m_bLoopAnim)
m_pClientDE->SetModelLooping(m_hObject, DTRUE);
else
m_pClientDE->SetModelLooping(m_hObject, DFALSE);
PlayAnimation(bAltFire ? m_nAltFireAnim : m_nFireAnim);
m_eState = bAltFire ? WS_ALT_FIRING : WS_FIRING;
}
m_fIdleStartTime = fTime;
}
break;
case WS_ALT_FIRING:
case WS_FIRING:
{
bAltFire = (m_eState == WS_ALT_FIRING);
DBOOL bLoopAnim;
DDWORD nFireAnim;
DBOOL bNowFiring;
DFLOAT fReloadTime;
DDWORD nAmmoUse;
DFLOAT fAmmo;
WeaponState eNextState;
if (bAltFire)
{
bLoopAnim = m_bAltLoopAnim;
nFireAnim = m_nAltFireAnim;
bNowFiring = bAltFiring;
fReloadTime = m_fAltReloadTime;
eNextState = WS_STOP_ALT_FIRING;
nAmmoUse = m_nAltAmmoUse;
fAmmo = CheckAmmo(DTRUE);
}
else
{
bLoopAnim = m_bLoopAnim;
nFireAnim = m_nFireAnim;
bNowFiring = bFiring;
fReloadTime = m_fReloadTime;
eNextState = WS_STOP_FIRING;
nAmmoUse = m_nAmmoUse;
fAmmo = CheckAmmo(DFALSE);
}
// No fire anim, so fire right away
if (nFireAnim == INVALID_ANI && !bLoopAnim)
{
if(fAmmo >= nAmmoUse)
Fire();
m_eState = eNextState;
}
// Else looping anim, so fire based on rate of fire
else if (bLoopAnim)
{
if (!bNowFiring || (fAmmo < nAmmoUse))
{
m_eState = eNextState;
m_pClientDE->SetModelLooping(m_hObject, DFALSE);
}
}
else if (m_bSemiAuto && !bAltFire)
{
// Stopped firing
if (!m_bLastFiring && bNowFiring && (fAmmo >= nAmmoUse))
{
m_pClientDE->ResetModelAnimation(m_hObject);
}
else if (!PlayAnimation(bAltFire ? m_nAltFireAnim : m_nFireAnim))
{
m_eState = eNextState;
}
}
// Else just wait for the animation to stop
else if (!PlayAnimation(bAltFire ? m_nAltFireAnim : m_nFireAnim))
{
m_eState = eNextState;
}
// check if there is a fire rate multiplier
/// TODO: This may need to be copied from the server? GK
// else if (m_pInventoryMgr->GetFireRateMultiplier() < 1.0f)
// {
// if (!m_bLastFiring && bNowFiring && (fTime - m_fLastShotTime) > fReloadTime * m_pInventoryMgr->GetFireRateMultiplier())
// m_pClientDE->ResetModelAnimation(m_hObject);
// }
m_fIdleStartTime = fTime;
}
break;
case WS_STOP_ALT_FIRING:
case WS_STOP_FIRING:
{
bAltFire = (m_eState == WS_STOP_ALT_FIRING);
if (!PlayAnimation(bAltFire ? m_nStopAltFireAnim : m_nStopFireAnim))
{
PlayAnimation(m_nRestAnim);
m_eState = WS_REST;
m_pClientDE->SetModelLooping(m_hObject, m_bLoopStatic);
}
m_fIdleStartTime = fTime;
}
break;
default : break;
}
m_bLastFiring = bFiring | bAltFiring;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CViewWeapon::CancelFiringState
//
// PURPOSE: Cancel the current weapon state and reset
//
// ----------------------------------------------------------------------- //
void CViewWeapon::CancelFiringState()
{
if (!m_pClientDE) return;
m_pClientDE->ResetModelAnimation(m_hObject);
PlayAnimation(m_nRestAnim);
m_pClientDE->ResetModelAnimation(m_hObject);
m_eState = WS_REST;
SendSoundMsg(DNULL, 0x02);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CViewWeapon::SetupViewModel
//
// PURPOSE: Sets the model filenames and animations.
//
// ----------------------------------------------------------------------- //
void CViewWeapon::SetupViewModel()
{
if (!m_pClientDE) return;
CBloodClientShell *pShell = (CBloodClientShell*)m_pClientDE->GetClientShell();
HLOCALOBJ hPlayerObj = m_pClientDE->GetClientObject();
// Choose the right or lefthanded model
char *pModelFilename;
if(m_bLeftHand) pModelFilename = m_pLeftViewModelFilename;
else pModelFilename = m_pViewModelFilename;
if(pModelFilename && m_pViewModelSkinname)
{
char firstChar = 0;
char start[] = "C_";
char *change = DNULL;
ObjectCreateStruct createStruct;
INIT_OBJECTCREATESTRUCT(createStruct);
// Get the character to use for the skin
#ifdef _ADDON
DBOOL bEnemyChar = DFALSE;
if (pShell->GetCharacter() >= CHARACTER_M_CULTIST)
{
bEnemyChar = DTRUE;
}
#endif
switch(pShell->GetCharacter())
{
case CHARACTER_CALEB: firstChar = 'C'; break;
case CHARACTER_OPHELIA: firstChar = 'O'; break;
case CHARACTER_ISHMAEL: firstChar = 'I'; break;
case CHARACTER_GABREILLA: firstChar = 'G'; break;
#ifdef _ADDON
case CHARACTER_M_CULTIST: firstChar = 'C'; break;
case CHARACTER_F_CULTIST: firstChar = 'O'; break;
case CHARACTER_SOULDRUDGE: firstChar = 'C'; break;
case CHARACTER_PROPHET: firstChar = 'I'; break;
#endif
}
// Copy over the filenames so we preserver the originals
strcpy(createStruct.m_Filename, pModelFilename);
strcpy(createStruct.m_SkinName, m_pViewModelSkinname);
strupr(createStruct.m_Filename); // [blg]
strupr(createStruct.m_SkinName);
createStruct.m_Flags = FLAG_MODELGOURAUDSHADE | FLAG_REALLYCLOSE | FLAG_VISIBLE | m_nFlags;
// Change the weapon skin to the correct character
change = strstr(createStruct.m_SkinName, start);
if (change) change[0] = firstChar;
// Change the knife model to the correct character
if(m_nType == WEAP_MELEE)
{
change = strstr(createStruct.m_Filename, start);
if (change) change[0] = firstChar;
}
// Change to the generic orb skin if necessary
#ifdef _ADDON
if (m_nType == WEAP_ORB && bEnemyChar)
{
strcpy(createStruct.m_SkinName, "skins_ao\\weapons_ao\\generic_orb_pv_t.dtx");
}
#endif
// Set the remaining info
change = DNULL;
createStruct.m_ObjectType = OT_MODEL;
m_pClientDE->GetObjectPos(hPlayerObj, &createStruct.m_Pos);
// Delete the object to avoid duplicates
/* if(m_hObject)
{
m_pClientDE->DeleteObject(m_hObject);
m_hObject = DNULL;
}
*/
m_hObject = m_pClientDE->CreateObject(&createStruct);
if(m_nFlags & FLAG_ENVIRONMENTMAP)
m_pClientDE->SetObjectColor(m_hObject, 1.0f, 1.0f, 1.0f, m_fChromeValue);
else
m_pClientDE->SetObjectColor(m_hObject, 0.0f, 0.0f, 0.0f, 1.0f);
m_pClientDE->SetObjectClientFlags(m_hObject, CF_NOTIFYMODELKEYS);
// Set the new model filenames
// m_pClientDE->SetObjectFilenames(m_hObject, model, skin);
m_pClientDE->SetModelLooping(m_hObject, DFALSE);
m_pClientDE->SetModelAnimation(m_hObject, -1);
// Tell it that this weapon this is it's parent for now.
m_nRestAnim = m_pClientDE->GetAnimIndex(m_hObject, "static_model");
m_nIdleAnim = m_pClientDE->GetAnimIndex(m_hObject, "idle");
m_nDrawAnim = m_pClientDE->GetAnimIndex(m_hObject, "draw");
m_nDrawDuelAnim = m_pClientDE->GetAnimIndex(m_hObject, "dh_draw");
m_nHolsterAnim = m_pClientDE->GetAnimIndex(m_hObject, "holster");
m_nHolsterDuelAnim = m_pClientDE->GetAnimIndex(m_hObject, "dh_holster");
m_nStartFireAnim = m_pClientDE->GetAnimIndex(m_hObject, "start_fire");
m_nFireAnim = m_pClientDE->GetAnimIndex(m_hObject, "fire");
m_nStopFireAnim = m_pClientDE->GetAnimIndex(m_hObject, "end_fire");
m_nStartAltFireAnim = m_pClientDE->GetAnimIndex(m_hObject, "start_alt_fire");
m_nAltFireAnim = m_pClientDE->GetAnimIndex(m_hObject, "alt_fire");
m_nStopAltFireAnim = m_pClientDE->GetAnimIndex(m_hObject, "end_alt_fire");
if (m_nIdleAnim == INVALID_ANI)
m_nIdleAnim = m_nRestAnim;
if (m_nAltFireAnim == INVALID_ANI)
{
m_nStartAltFireAnim = m_nStartFireAnim;
m_nAltFireAnim = m_nFireAnim;
m_nStopAltFireAnim = m_nStopFireAnim;
}
PlayAnimation(m_nDrawAnim);
m_fIdleDelay = GetRandom(m_fMinIdleDelay, m_fMaxIdleDelay);
m_fIdleStartTime = m_pClientDE->GetTime();
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CViewWeapon::PlayAnimation()
//
// PURPOSE: Set model to new animation
//
// ----------------------------------------------------------------------- //
DBOOL CViewWeapon::PlayAnimation(DDWORD dwNewAni)
{
if (!m_pClientDE || dwNewAni == INVALID_ANI) return DFALSE;
DDWORD dwAni = m_pClientDE->GetModelAnimation(m_hObject);
DDWORD dwState = m_pClientDE->GetModelPlaybackState(m_hObject);
if (dwAni == dwNewAni && (dwState & MS_PLAYDONE))
{
return DFALSE;
}
else if (dwAni != dwNewAni)
{
m_pClientDE->SetModelAnimation(m_hObject, dwNewAni);
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CViewWeapon::OnModelKey()
//
// PURPOSE: Handle animation command
//
// ----------------------------------------------------------------------- //
void CViewWeapon::OnModelKey(HLOCALOBJ hObj, ArgList* pArgList)
{
char* pKey;
int count = pArgList->argc;
CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
for(int i = 0; i < count; i++)
{
pKey = pArgList->argv[i];
if(!pKey) break;
if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_FIRE) == 0)
{
Fire();
}
else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_SOUND) == 0)
{
char* pSound = pArgList->argv[++i];
char pDir[100];
if(pSound)
{
_mbscpy((unsigned char*)pDir, (const unsigned char*)"Sounds\\Weapons\\");
_mbscat((unsigned char*)pDir, (const unsigned char*)pSound);
SendSoundMsg(pDir, 0x00);
// PlaySoundFromObject(m_hObject, pDir, 1000, SOUNDPRIORITY_PLAYER_HIGH,
// DFALSE, DFALSE, DFALSE, 100 );
}
}
else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_SOUNDLOOP) == 0)
{
char* pSound = pArgList->argv[++i];
char pDir[100];
if(pSound && !m_hLoopSound)
{
_mbscpy((unsigned char*)pDir, (const unsigned char*)"Sounds\\Weapons\\");
_mbscat((unsigned char*)pDir, (const unsigned char*)pSound);
SendSoundMsg(pDir, 0x01);
// m_hLoopSound = PlaySoundFromObject(m_hObject, pDir, 1000, SOUNDPRIORITY_PLAYER_HIGH, DTRUE, DTRUE);
}
}
else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_SOUNDSTOP) == 0)
{
SendSoundMsg(DNULL, 0x02);
// if(m_hLoopSound)
// m_pClientDE->KillSound(m_hLoopSound);
// m_hLoopSound = DNULL;
}
else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_HIDE) == 0)
{
char* pNode = pArgList->argv[++i];
DBOOL nodeStat;
m_pClientDE->GetModelNodeHideStatus(m_hObject, pNode, &nodeStat);
if(!nodeStat)
m_pClientDE->SetModelNodeHideStatus(m_hObject, pNode, DTRUE);
}
else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_SHOW) == 0)
{
char* pNode = pArgList->argv[++i];
DBOOL nodeStat;
m_pClientDE->GetModelNodeHideStatus(m_hObject, pNode, &nodeStat);
if(nodeStat)
m_pClientDE->SetModelNodeHideStatus(m_hObject, pNode, DFALSE);
}
}
/*
else if (stricmp(pKey, WEAPON_KEY_SOUND) == 0)
{
if (pArgList->argc > 1)
{
char* pSound = pArgList->argv[1];
if (pSound)
{
char buf[100];
sprintf(buf,"Sounds\\Weapons\\%s.wav", pSound);
PlaySoundLocal(buf, SOUNDPRIORITY_PLAYER_HIGH, DFALSE, DFALSE, 100, DTRUE );
// Send message to Server so that other client's can hear this sound...
HSTRING hSound = m_pClientDE->CreateString(buf);
HMESSAGEWRITE hWrite = m_pClientDE->StartMessage(CMSG_WEAPON_SOUND);
m_pClientDE->WriteToMessageByte(hWrite, WEAPON_SOUND_KEY);
m_pClientDE->WriteToMessageByte(hWrite, m_nWeaponId);
m_pClientDE->WriteToMessageVector(hWrite, &m_vFlashPos);
m_pClientDE->WriteToMessageHString(hWrite, hSound);
m_pClientDE->EndMessage2(hWrite, MESSAGE_NAGGLEFAST|MESSAGE_GUARANTEED);
m_pClientDE->FreeString(hSound);
}
}
}
*/
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CViewWeapon::SendSoundMsg
//
// PURPOSE: Send fire message to server
//
// ----------------------------------------------------------------------- //
void CViewWeapon::SendSoundMsg(char *szSound, DBYTE byFlags)
{
if (!m_pClientDE) return;
HSTRING sSound = m_pClientDE->CreateString(szSound);
// Send Sound message to server...
HMESSAGEWRITE hWrite = m_pClientDE->StartMessage(CMSG_WEAPON_SOUND);
m_pClientDE->WriteToMessageByte(hWrite, byFlags);
if(byFlags != 0x02)
m_pClientDE->WriteToMessageHString(hWrite, sSound);
m_pClientDE->EndMessage2(hWrite, MESSAGE_NAGGLEFAST|MESSAGE_GUARANTEED);
if(sSound) m_pClientDE->FreeString(sSound);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -