📄 playerobj.cpp
字号:
bLateralMovement = DTRUE;
}
if ((m_dwControlFlags & CTRLFLAG_BACKWARD) && (!m_bMovementBlocked || m_eContainerCode == CC_CRANECONTROL))
{
fMoveAccel += -fMaxMoveAccel;
bNothingHappened = DFALSE;
bLateralMovement = DTRUE;
}
if (!(m_byFlags & CDATA_MOUSEAIMING) && !m_bMovementBlocked)
{
fMoveAccel += -(m_fMouseAxis1) * fMaxMoveAccel;
m_dwControlFlags |= CTRLFLAG_FORWARD;
bLateralMovement = DTRUE;
}
if (fMoveAccel > fMaxMoveAccel)
fMoveAccel = fMaxMoveAccel;
else if (fMoveAccel < -fMaxMoveAccel)
fMoveAccel = -fMaxMoveAccel;
VEC_MULSCALAR(vForward, vForward, fMoveAccel)
VEC_ADD(vAccel, vAccel, vForward)
// Strafe.. Check for strafe modifier first
if (m_dwControlFlags & CTRLFLAG_STRAFE)
{
if (m_dwControlFlags & CTRLFLAG_LEFT)
fStrafeAccel += -fMaxMoveAccel;
if (m_dwControlFlags & CTRLFLAG_RIGHT)
fStrafeAccel += fMaxMoveAccel;
fStrafeAccel += (m_fMouseAxis0) * fMaxMoveAccel;
bNothingHappened = DFALSE;
bLateralMovement = DTRUE;
}
// Check individual strafe commands
if (m_dwControlFlags & CTRLFLAG_STRAFELEFT)
{
fStrafeAccel += -fMaxMoveAccel;
bNothingHappened = DFALSE;
bLateralMovement = DTRUE;
}
if (m_dwControlFlags & CTRLFLAG_STRAFERIGHT)
{
fStrafeAccel += fMaxMoveAccel;
bNothingHappened = DFALSE;
bLateralMovement = DTRUE;
}
if (fStrafeAccel > fMaxMoveAccel)
fStrafeAccel = fMaxMoveAccel;
else if (fStrafeAccel < -fMaxMoveAccel)
fStrafeAccel = -fMaxMoveAccel;
VEC_MULSCALAR(vRight, vRight, fStrafeAccel)
VEC_ADD(vAccel, vAccel, vRight)
// tone down run-strafing, but not too much.
DFLOAT fAccelMag = VEC_MAG(vAccel);
DFLOAT fMaxRunStrafeAccel = (DFLOAT)sqrt((fMaxMoveAccel * fMaxMoveAccel) * 2);
if (fAccelMag > fMaxRunStrafeAccel)
{
VEC_MULSCALAR(vAccel, vAccel, (fMaxRunStrafeAccel/fAccelMag));
}
DBOOL bSteep = DFALSE;
if (!m_bSpectatorMode && !m_bMovementBlocked)
{
// Make sure the slope isn't too steep to climb or jump up (prevent jump-skip)
if (m_bOnGround && !bFreeMovement)
{
// If standing on something, tilt the acceleration so it's aligned with
// the surface.
DVector &v = collisionInfo.m_Plane.m_Normal;
if ((v.z + v.x) > v.y) // Check for slope > 45 degrees
{
vAccel.y -= 4000.0f; // Just to make sure I slide down
bSteep = DTRUE;
}
else
{
TiltVectorToPlane(&vAccel, &collisionInfo.m_Plane.m_Normal);
}
}
// See if we just broke the surface of water...
if ((IsLiquid(m_eLastContainerCode) && !bHeadInLiquid) && !m_bOnGround && !m_bBodyOnLadder)
{
m_bSwimmingOnSurface = DTRUE;
}
else if (bHeadInLiquid) // See if we went back under...
{
m_bSwimmingOnSurface = DFALSE;
m_bCanSwimJump = DTRUE;
}
// See if we landed (after falling)...
if (!bFreeMovement && m_bFalling && m_bOnGround)
{
// See if we should play a landing sound
if ((m_fMaxFallPos - m_fMinFallPos) > 56.0f && !m_bPowerupActivated[PU_INCORPOREAL])
{
char szSound[MAX_CS_FILENAME_LEN+1];
if (GetLandingSound(szSound))
{
PlayPlayerSound(szSound, 200.0f, 70, DFALSE, SOUNDPRIORITYMOD_LOW);
}
}
m_startFall = -1.0;
}
else if (bFreeMovement)
{
m_startFall = -1.0;
}
// now update m_bServerFalling
CollisionInfo ci;
g_pServerDE->GetStandingOn(m_hObject, &ci);
m_bServerFalling = !ci.m_hObject;
// now update m_bFalling
m_bFalling = m_bOnGround ? DFALSE : DTRUE;
if (m_bFalling)
{
if (m_startFall < 0)
{
m_startFall = pServerDE->GetTime();
m_fMinFallPos = m_fMaxFallPos = vMyPos.y;
}
else
{
if (vMyPos.y > m_fMaxFallPos)
m_fMaxFallPos = vMyPos.y;
if (vMyPos.y < m_fMinFallPos)
m_fMinFallPos = vMyPos.y;
}
}
// Jumping
if (m_dwControlFlags & CTRLFLAG_JUMP)
{
// If we are in a container that supports free movement, see if we are
// moving up or down...
if (bFreeMovement)
{
vAccel.y += fMaxMoveAccel;
// m_bLastJumpCommand = DFALSE;
bNothingHappened = DFALSE;
}
else if (!m_bLastJumpCommand)
{
// BEGIN 10/5/98 Kevin additions ////////////////////////////////////
// Handling jumping out of water...
if (m_bBodyInLiquid && !bHeadInLiquid)
{
if (m_bCanSwimJump)
{
m_bSwimmingJump = DTRUE;
m_bCanSwimJump = DFALSE;
}
// If our head is out of the liquid and we're standing on the
// ground, let us jump out of the water...
else if (m_bOnGround)
{
m_bSwimmingJump = DTRUE;
}
if (m_bSwimmingJump)
{
m_bSwimmingOnSurface = DFALSE;
bNothingHappened = DFALSE;
vMyVel.y += fJumpSpeed * 0.75f;
m_bLastJumpCommand = DTRUE;
m_bOnGround = DFALSE;
bFreeMovement = DFALSE;
}
}
else if (m_bOnGround && !bSteep)
{
if (m_bForcedCrouch)
vMyVel.y += fJumpSpeed * 0.75f;
else
vMyVel.y += fJumpSpeed;
m_bLastJumpCommand = DTRUE;
bNothingHappened = DFALSE;
// bIsStandingOn = DFALSE;
}
}
}
else
m_bLastJumpCommand = DFALSE;
// Crouching
if (m_dwControlFlags & CTRLFLAG_CROUCH)
{
if ((bInLiquid || bFreeMovement) && !m_bOnGround)
{
vAccel.y -= fMaxMoveAccel;
}
else
{
m_bLastCrouchCommand = DTRUE;
if (!m_bForcedCrouch)
m_PStateChangeFlags |= PSTATE_CROUCH;
m_bForcedCrouch = DTRUE;
}
bNothingHappened = DFALSE;
}
else // Stand up again
{
m_bLastCrouchCommand = DFALSE;
}
}
}
// Calculate drag for in-air movement, we want air movement consistent
// with ground movement. gDragCoeff needs to be the same as the object's
// friction coefficient.
DVector vAirVel;
VEC_COPY(vAirVel, vMyVel);
// Apply drag to y when going down, but not going up.
if (vAirVel.y >= 0.0f)
vAirVel.y = 0.0f;
else
{
vAirVel.y = DCLAMP(vAirVel.y/2.0f, -25.0f, 0.0f);
}
DFLOAT fVel = VEC_MAGSQR(vAirVel);
if (!bFreeMovement && !m_bOnGround && fVel > 0.01f)
{
DFLOAT fDragAccel = gDragCoeff[nIndex];
VEC_MULSCALAR(vAirVel, vAirVel, -fDragAccel);
VEC_ADD(vAccel, vAccel, vAirVel);
}
if (!m_bSpectatorMode)
{
// ADDED BY ANDY 9-20-98
if(m_bSlowMode)
{
VEC_MULSCALAR(vMyVel, vMyVel, 0.5f);
if(pServerDE->GetTime() > m_fSlowTime)
m_bSlowMode = DFALSE;
}
// Cap horizontal velcity at max to make sure.
DFLOAT fYVel = vMyVel.y;
vMyVel.y = 0.0f;
DFLOAT fMag = VEC_MAG(vMyVel);
fMaxMoveVel = (DFLOAT)sqrt(fMaxMoveVel * fMaxMoveVel * 2);
if (fMag > fMaxMoveVel)
{
fMag = fMaxMoveVel / fMag;
VEC_MULSCALAR(vMyVel, vMyVel, fMag);
}
vMyVel.y = fYVel;
// pServerDE->SetVelocity(m_hObject, &vMyVel);
}
else // m_bSpectatorMode
{
if (bLateralMovement)
{
VEC_NORM(vAccel);
VEC_MULSCALAR(vAccel, vAccel, fMaxMoveVel);
}
else
{
VEC_INIT(vAccel);
}
// pServerDE->SetVelocity(m_hObject, &vAccel);
}
if (m_bLastJumpCommand && vMyVel.y > 0 && vAccel.y > 0)
vAccel.y = 0;
// pServerDE->SetAcceleration(m_hObject, &vAccel);
//
// pServerDE->GetVelocity(m_hObject, &m_vLastVel);
// Reset these value
m_bBodyInLiquid = DFALSE;
m_bBodyOnLadder = DFALSE;
// pServerDE->BPrint("Vel: %.2f, %.2f, %.2f", vMyVel.x, vMyVel.y, vMyVel.z);
// pServerDE->BPrint("Accel: %.2f, %.2f, %.2f", vAccel.x, vAccel.y, vAccel.z);
return bNothingHappened;
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::ResetPlayerInventory()
//
// PURPOSE:
//
// --------------------------------------------------------------------------- //
void CPlayerObj::ResetPlayerInventory()
{
m_InventoryMgr.Term();
m_InventoryMgr.ObtainWeapon(WEAP_MELEE, 0);
m_InventoryMgr.ObtainWeapon(WEAP_BERETTA, 0);
for (int i = AMMO_BULLET; i <= AMMO_MAXAMMOTYPES; i++)
m_InventoryMgr.SetAmmoCount(i, 0.0f);
m_InventoryMgr.SetAmmoCount(AMMO_BULLET, DEFAULT_BULLETS);
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::Slow()
//
// PURPOSE: Checks for firing commands and updates the weapon object
//
// --------------------------------------------------------------------------- //
void CPlayerObj::Slow(DFLOAT time)
{
CServerDE* pServerDE = GetServerDE();
if(!pServerDE) return;
if(time > 0.0f)
{
m_bSlowMode = DTRUE;
m_fSlowTime = pServerDE->GetTime() + time;
}
else
m_bSlowMode = DFALSE;
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::AddRemoteBomb()
//
// PURPOSE: Add a remote bomb to the list
//
// --------------------------------------------------------------------------- //
void CPlayerObj::AddRemoteBomb(CProjectile* pBomb)
{
CServerDE* pServerDE = GetServerDE();
if(!pServerDE) return;
if (!m_pBombList)
m_pBombList = pServerDE->CreateObjectList();
HOBJECT hBombObject = pServerDE->ObjectToHandle((LPBASECLASS)pBomb);
if( hBombObject )
{
ObjectLink* ol = pServerDE->AddObjectToList(m_pBombList, hBombObject);
ol->m_hObject = hBombObject;
g_pServerDE->CreateInterObjectLink( m_hObject, hBombObject );
}
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::AddRemoteBomb()
//
// PURPOSE: Add a remote bomb to the list
//
// --------------------------------------------------------------------------- //
void CPlayerObj::RemoveRemoteBomb(CProjectile* pBomb)
{
CServerDE* pServerDE = GetServerDE();
if(!pServerDE) return;
if(m_pBombList)
{
HOBJECT hBombObject = pServerDE->ObjectToHandle((LPBASECLASS)pBomb);
if( hBombObject )
{
pServerDE->RemoveObjectFromList(m_pBombList, hBombObject);
g_pServerDE->BreakInterObjectLink( m_hObject, hBombObject );
}
}
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::SetOrbObject()
//
// PURPOSE:
//
// --------------------------------------------------------------------------- //
void CPlayerObj::SetOrbObject(HOBJECT hObj)
{
CServerDE* pServerDE = GetServerDE();
if(!pServerDE) return;
m_hOrbObj = hObj;
if(hObj)
pServerDE->CreateInterObjectLink(m_hObject, m_hOrbObj);
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::HandleFiring()
//
// PURPOSE: Checks for firing commands and updates the weapon object
//
// --------------------------------------------------------------------------- //
DBOOL CPlayerObj::HandleFiring()
{
DBOOL bNothingHappened = DTRUE;
CServerDE* pServerDE = GetServerDE();
/*
DRotation rotGun;
DVector vRGunPos, vLGunPos, vMyPos;
pServerDE->GetObjectPos(m_hObject, &vMyPos);
VEC_ADD(vRGunPos, vMyPos, m_vGunMuzzlePos);
VEC_ADD(vLGunPos, vMyPos, m_vlGunMuzzlePos);
ROT_COPY(rotGun, m_rRotation);
if (!m_damage.IsDead() && !m_bSpectatorMode)
{
DBOOL bFiring = DFALSE;
DBOOL bAltFiring = DFALSE;
if (!m_bMovementBlocked)
{
bFiring = (m_dwControlFlags & CTRLFLAG_FIRE) != 0;
bAltFiring = (!bFiring && (m_dwControlFlags & CTRLFLAG_ALTFIRE));
}
if (bFiring || bAltFiring)
{
// Binoculars prevents firing.
if (IsItemActive(INV_BINOCULARS))
{
bFiring = bAltFiring = DFALSE;
}
// Firing kills the incorporeal powerup
if (m_bPowerupActivated[PU_INCORPOREAL])
m_fIncorporealTime = 0.0f;
bNothingHappened = DFALSE;
}
m_InventoryMgr.UpdateCurrentWeaponFiring(&vRGunPos, &vLGunPos, &rotGun, bFiring, bAltFiring);
}
else if (m_damage.IsDead())
{
m_InventoryMgr.UpdateCurrentWeaponFiring(&vRGunPos, &vLGunPos, &rotGun, DFALSE, DFALSE);
}
*/
return bNothingHappened;
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::UpdateAnim()
//
// PURPOSE: Updates the player animation based on the current movement.
//
// --------------------------------------------------------------------------- //
void CPlayerObj::UpdateAnim()
{
// Update the PMOVE state..
if (!m_bDead)
{
if (m_bInSlowDeath)
{
DoHumiliationAnim();
}
else if ((m_dwControlFlags & CTRLFLAG_FIRE) || (m_dwControlFlags & CTRLFLAG_ALTFIRE))
{
if (m_dwControlFlags & CTRLFLAG_JUMP && !m_bForcedCrouch)
{
DoFireJumpAnim();
}
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)
DoFireCrawlAnim();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -