📄 playerobj.cpp
字号:
else if (m_dwControlFlags & CTRLFLAG_STRAFELEFT)
DoStrafeLeftAnim();
else if (m_dwControlFlags & CTRLFLAG_STRAFERIGHT)
DoStrafeRightAnim();
else if (m_dwControlFlags & CTRLFLAG_RUN)
DoFireRunAnim();
else
DoFireWalkAnim();
}
else if (m_dwControlFlags & CTRLFLAG_CROUCH)
{
DoFireCrouchAnim();
}
else
{
DoFireStandAnim();
}
}
else
{
if (m_dwControlFlags & CTRLFLAG_JUMP && !m_bForcedCrouch)
{
DoJumpAnim();
}
else if (m_dwControlFlags & CTRLFLAG_FORWARD || m_dwControlFlags & CTRLFLAG_BACKWARD ||
m_dwControlFlags & CTRLFLAG_LEFT || m_dwControlFlags & CTRLFLAG_RIGHT ||
m_dwControlFlags & CTRLFLAG_STRAFELEFT || m_dwControlFlags & CTRLFLAG_STRAFERIGHT)
{
if (m_dwControlFlags & CTRLFLAG_CROUCH)
DoCrawlAnim();
else if (m_dwControlFlags & CTRLFLAG_STRAFELEFT)
DoStrafeLeftAnim();
else if (m_dwControlFlags & CTRLFLAG_STRAFERIGHT)
DoStrafeRightAnim();
else if (m_dwControlFlags & CTRLFLAG_RUN)
DoRunAnim();
else
DoWalkAnim();
}
else if (m_dwControlFlags & CTRLFLAG_CROUCH)
{
DoCrouchAnim();
}
else
{
IdleTime();
}
}
}
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::Update()
//
// PURPOSE: Handles the update for the player object.
//
// --------------------------------------------------------------------------- //
DBOOL CPlayerObj::Update(DVector *pMovement)
{
CServerDE* pServerDE = GetServerDE();
DBOOL bNothingHappened = DTRUE;
// Dev code to help us find the "ghost player" bug...
if (m_hPlrPosVar)
{
if( pServerDE->GetVarValueFloat( m_hPlrPosVar ) > 0.0f )
pServerDE->SetNetFlags( m_hObject, 0 );
else
pServerDE->SetNetFlags(m_hObject, NETFLAG_POSUNGUARANTEED|NETFLAG_ROTUNGUARANTEED|NETFLAG_ANIMUNGUARANTEED);
}
// Set our next update
pServerDE->SetNextUpdate(m_hObject, (DFLOAT).001);
// Sanity check
if (!m_hClient)
return DTRUE;
// Update timers
m_fSlowDeathSafeTimer -= g_pServerDE->GetFrameTime();
if (m_fSlowDeathSafeTimer < 0) m_fSlowDeathSafeTimer = 0;
m_fSlowDeathStayTimer -= g_pServerDE->GetFrameTime();
if (m_fSlowDeathStayTimer < 0) m_fSlowDeathStayTimer = 0;
// Check for first update
if (m_bFirstUpdate)
{
SetMoveVel(gMoveVel[m_nAttribSpeed-1]);
SetJumpVel(DEFAULT_JUMPVEL);
m_PStateChangeFlags = PSTATE_ALL;
UpdateClientPhysics(); // (to make sure they have their model around)
TeleportClientToServerPos();
// Initial update for some stats..
m_nStatsFlags = PLAYERSTATS_HEALTH | PLAYERSTATS_AMMO | PLAYERSTATS_ALTAMMO | PLAYERSTATS_ARMOR | PLAYERSTATS_FOCUS;
SendMessageToClient( SMSG_PLAYERSTATSUPDATE );
m_bFirstUpdate = DFALSE;
}
// Check for sound completion
if (m_hCurSound)
{
DBOOL bSoundDone = DFALSE;
if (pServerDE->IsSoundDone(m_hCurSound, &bSoundDone) == LT_OK && bSoundDone)
{
g_pServerDE->KillSound( m_hCurSound );
m_hCurSound = DNULL;
}
}
/*
// Check to see if the status bar display items have changed
DDWORD nItem;
// See if the health has changed, send to client
nItem = (DDWORD)m_damage.GetHitPoints();
if (m_nLastHitPoints != nItem)
{
// If we took damage, tell the client
if (m_nLastHitPoints > nItem)
{
m_nLastDamage = m_nLastHitPoints - nItem;
SendMessageToClient(SMSG_TOOKDAMAGE);
}
m_nLastHitPoints = nItem;
SendMessageToClient(SMSG_HEALTH);
}
// See if the ammo has changed, send to client
nItem = (DDWORD)m_InventoryMgr.GetCurrentWeaponAmmoCount();
if (m_nLastAmmo != nItem)
{
m_nLastAmmo = nItem;
SendMessageToClient(SMSG_AMMO);
}
// See if the armor has changed, send to client
nItem = (DDWORD)m_damage.GetArmorPoints();
if (m_nLastArmor != nItem)
{
m_nLastArmor = nItem;
SendMessageToClient(SMSG_ARMOR);
}
// See if the focus has changed, send to client
nItem = (DDWORD)m_InventoryMgr.GetAmmoCount(AMMO_FOCUS);
if (m_nLastFocus != nItem)
{
m_nLastFocus = nItem;
SendMessageToClient(SMSG_FOCUS);
}
*/
// Keep the client updated.
UpdateClientPhysics();
// Update air level...
UpdateAirLevel();
// Update the player stats to the client...
UpdateStats( );
// Update any powerup timers..
CheckPowerups();
// Update based on active inventory items or spells
CheckItemsAndSpells();
UpdateControlFlags();
// Check for player movement
if (!HandleMovement())
bNothingHappened = DFALSE;
// if (!HandleFiring())
// bNothingHappened = DFALSE;
if (m_dwControlFlags & CTRLFLAG_GRAB)
GrabObject();
if (m_dwControlFlags & CTRLFLAG_TAUNT)
DoTaunt();
UpdateAnim();
// 11/10/97 added auto smell maker...
if (!m_damage.IsDead() && !m_bSpectatorMode && m_hObject)
{
if ((pServerDE->GetTime() > m_fSmellTime + m_fSmellDelay) )
{
DVector vPos, vHintPos;
pServerDE->GetObjectPos(m_hObject, &vPos);
if(SmellHint::m_SmellHead.m_pPrev && SmellHint::m_SmellHead.m_pPrev->m_pData)
{
SmellHint* pPrevHint = (SmellHint*)SmellHint::m_SmellHead.m_pPrev->m_pData;
pServerDE->GetObjectPos(pPrevHint->m_hObject, &vHintPos);
if(VEC_DIST(vHintPos, vPos) >= 10.0f)
{
ObjectCreateStruct theStruct;
INIT_OBJECTCREATESTRUCT(theStruct);
DRotation rRot;
ROT_INIT(rRot);
ROT_COPY(theStruct.m_Rotation, rRot);
VEC_COPY(theStruct.m_Pos, vPos);
m_fSmellTime = pServerDE->GetTime();
pServerDE->CreateObject(pServerDE->GetClass("SmellHint"), &theStruct);
}
}
else
{
ObjectCreateStruct theStruct;
INIT_OBJECTCREATESTRUCT(theStruct);
DRotation rRot;
ROT_INIT(rRot);
ROT_COPY(theStruct.m_Rotation, rRot);
VEC_COPY(theStruct.m_Pos, vPos);
m_fSmellTime = pServerDE->GetTime();
pServerDE->CreateObject(pServerDE->GetClass("SmellHint"), &theStruct);
}
}
}
else if (m_damage.IsDead()) // I'm dead according to m_damage.
{
if (!m_bDead) // Just died handled here.
HandleDeath();
bNothingHappened = DFALSE;
}
// Get current gun ID for the client
CWeapon *w = m_InventoryMgr.GetCurrentWeapon();
DBOOL bChange = DFALSE;
if (!w && m_CurGun != WEAP_NONE)
{
m_CurGun = WEAP_NONE;
m_CurGunSlot = m_InventoryMgr.GetCurrentWeaponSlot();
bChange = DTRUE;
}
if (w && m_CurGun != w->GetType())
{
m_CurGun = w->GetType();
m_CurGunSlot = m_InventoryMgr.GetCurrentWeaponSlot();
bChange = DTRUE;
}
if (bChange)
{
// Toggle binoculars off if they are active
if (m_InventoryMgr.IsItemActive(INV_BINOCULARS))
m_InventoryMgr.SetActiveItem(INV_BINOCULARS);
SendMessageToClient(SMSG_CHANGEWEAPON);
}
if (m_bDead)
{
m_InventoryMgr.ShowHandModels(DFALSE);
int nRet = m_InventoryMgr.ChangeWeaponSlot(1);
if (nRet == CHWEAP_NOTAVAIL)
{
m_InventoryMgr.ChangeWeaponSlot(0);
}
}
// See if we should be cloaked, and set alpha if so.
/* if (IsItemActive(INV_CLOAKING) && !m_bInvisible)
{
pServerDE->SetObjectColor(m_hObject, 0.0f, 0.0f, 0.0f, ALPHA_CLOAKED);
}
if (bNothingHappened)
{
IdleTime();
}
else
{
m_startIdle = pServerDE->GetTime();
}
*/
// [blg] Check for idle time
if (bNothingHappened && (m_dwControlFlags == 0 || m_dwControlFlags == CTRLFLAG_RUN) && !m_bDead)
{
m_fIdleTime += pServerDE->GetFrameTime();
if (m_fIdleTime > MAX_IDLE_TIME)
{
ResetIdleTime();
PlayVoiceGroupEventOnClient(VME_IDLE, DTRUE);
}
}
else
{
ResetIdleTime();
}
// Set client view pos to the camera level
pServerDE->GetObjectPos(m_hObject, &m_vLastPos);
DVector vListenPos;
if (!g_hActiveCamera)
{
if (IsItemActive(INV_THEEYE))
{
CInvTheEye* pEye = (CInvTheEye*)m_InventoryMgr.GetItem(INV_THEEYE);
if (pEye)
{
DVector vListenPos;
HOBJECT hObj = pEye->GetEyeObject();
if (hObj)
{
pServerDE->GetObjectPos(hObj, &vListenPos);
pServerDE->SetClientViewPos(m_hClient, &vListenPos);
}
}
}
else if(m_hOrbObj)
{
DVector vListenPos;
pServerDE->GetObjectPos(m_hOrbObj, &vListenPos);
pServerDE->SetClientViewPos(m_hClient, &vListenPos);
}
else // not the eye
{
VEC_COPY(vListenPos, m_vLastPos);
vListenPos.y += m_fEyeLevel;
pServerDE->SetClientViewPos(m_hClient, &vListenPos);
if( pServerDE->GetTime( ) > m_fNextPingTime )
{
m_fNextPingTime = pServerDE->GetTime( ) + PINGPERIOD;
pServerDE->PingObjects(m_hObject);
}
}
}
else
{
pServerDE->GetObjectPos(g_hActiveCamera, &vListenPos);
pServerDE->SetClientViewPos(m_hClient, &vListenPos);
if( pServerDE->GetTime( ) > m_fNextPingTime )
{
m_fNextPingTime = pServerDE->GetTime( ) + PINGPERIOD;
pServerDE->PingObjects(g_hActiveCamera);
}
}
// If we're outside the world in a multiplayer game, we deserve to die...
if (g_pBloodServerShell->IsMultiplayerGame())
{
DVector vPos, vMin, vMax;
pServerDE->GetWorldBox(vMin, vMax);
pServerDE->GetObjectPos(m_hObject, &vPos);
if (vPos.x < vMin.x || vPos.y < vMin.y || vPos.z < vMin.z ||
vPos.x > vMax.x || vPos.y > vMax.y || vPos.z > vMax.z)
{
DVector vNull;
VEC_INIT(vNull);
DamageObject(m_hObject, (LPBASECLASS)this, m_hObject, 100.0f, vNull, vNull, DAMAGE_TYPE_DEATH);
}
}
// All done...
return DTRUE;
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::UpdateStats()
//
// PURPOSE: Updates player stats.
//
// --------------------------------------------------------------------------- //
void CPlayerObj::UpdateStats()
{
// Check to see if the status bar display items have changed
DDWORD nItem;
m_nStatsFlags = 0;
// See if the health has changed, send to client
nItem = (DDWORD)m_damage.GetHitPoints();
if (m_nLastHitPoints != nItem)
{
// If we took damage, tell the client
if (m_nLastHitPoints > nItem)
{
m_nLastDamage = m_nLastHitPoints - nItem;
m_nStatsFlags |= PLAYERSTATS_TOOKDAMAGE;
if (IsRandomChance(69 + m_nLastDamage))
{
if (m_damage.GetLastDamageType() == DAMAGE_TYPE_FIRE)
{
PlayVoiceGroupEventOnClient(VME_BURNING, DTRUE);
}
else
{
PlayVoiceGroupEventOnClient(VME_PAIN, DTRUE);
}
}
}
m_nLastHitPoints = nItem;
m_nStatsFlags |= PLAYERSTATS_HEALTH;
}
// See if the ammo has changed, send to client
nItem = (DDWORD)m_InventoryMgr.GetCurrentWeaponAmmoCount();
if (m_nLastAmmo != nItem)
{
m_nLastAmmo = nItem;
m_nStatsFlags |= PLAYERSTATS_AMMO;
}
// See if the ammo has changed, send to client
nItem = (DDWORD)m_InventoryMgr.GetCurrentWeaponAltFireAmmoCount();
if (m_nLastAltAmmo != nItem)
{
m_nLastAltAmmo = nItem;
m_nStatsFlags |= PLAYERSTATS_ALTAMMO;
}
// See if the armor has changed, send to client
nItem = (DDWORD)m_damage.GetArmorPoints();
if (m_nLastArmor != nItem)
{
m_nLastArmor = nItem;
m_nStatsFlags |= PLAYERSTATS_ARMOR;
}
// See if the focus has changed, send to client
nItem = (DDWORD)m_InventoryMgr.GetAmmoCount(AMMO_FOCUS);
if (m_nLastFocus != nItem)
{
m_nLastFocus = nItem;
m_nStatsFlags |= PLAYERSTATS_FOCUS;
}
// See if air level has changed...
if (m_fOldAirLevel != m_fAirLevel)
{
m_fOldAirLevel = m_fAirLevel;
m_nStatsFlags |= PLAYERSTATS_AIRLEVEL;
}
if( m_nStatsFlags )
SendMessageToClient( SMSG_PLAYERSTATSUPDATE );
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::ToggleSpectatorMode()
//
// PURPOSE: Toggles spectator mode on or off.
//
// --------------------------------------------------------------------------- //
void CPlayerObj::ToggleSpectatorMode()
{
CServerDE* pServerDE = GetServerDE();
m_bSpectatorMode = !m_bSpectatorMode;
SendMessageToClient(SMSG_SPECTATORMODE);
// Kludge to fix problem with sinking through floor...
if (m_bSpectatorMode)
{
DVector pos;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -