📄 playerobj.cpp
字号:
pServerDE->FreeString(m_hstrPlayerName);
if (m_hCurSound)
pServerDE->KillSound(m_hCurSound);
if (m_hWeapSound)
pServerDE->KillSound(m_hWeapSound);
if (m_hstrWhoKilledMeLast)
pServerDE->FreeString(m_hstrWhoKilledMeLast);
if (m_hstrWhoIKilledLast)
pServerDE->FreeString(m_hstrWhoIKilledLast);
if (m_hPowerupStartSound)
pServerDE->KillSound(m_hPowerupStartSound);
if (m_hPowerupEndSound)
pServerDE->KillSound(m_hPowerupEndSound);
if (m_hPowerupLoopSound)
pServerDE->KillSound(m_hPowerupLoopSound);
if( m_hClientSaveData )
{
pServerDE->EndHMessageRead( m_hClientSaveData );
}
if( m_CabalLink.m_pData && AI_Mgr::m_dwNumCabal > 0 )
{
dl_Remove( &m_CabalLink );
AI_Mgr::m_dwNumCabal--;
}
if( m_MonsterLink.m_pData && AI_Mgr::m_dwNumMonster > 0 )
{
dl_Remove( &m_MonsterLink );
AI_Mgr::m_dwNumMonster--;
}
// Delete the attached objects list
pCur = m_AttachedObjectsList.m_Head.m_pNext;
while( pCur != &m_AttachedObjectsList.m_Head )
{
pNext = pCur->m_pNext;
delete pCur;
pCur = pNext;
}
// Dump the bomb list.
if( m_pBombList )
{
ObjectLink* pLink = m_pBombList->m_pFirstLink;
while( pLink )
{
g_pServerDE->RemoveObject( pLink->m_hObject );
pLink = pLink->m_pNext;
}
pServerDE->RelinquishList( m_pBombList );
m_pBombList = DNULL;
}
m_hPlrPosVar = DNULL;
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::PostPropRead()
//
// PURPOSE: Called after properties are set, do initialization stuff here.
//
// --------------------------------------------------------------------------- //
void CPlayerObj::PostPropRead(ObjectCreateStruct *pStruct)
{
_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)"Models\\Characters\\Caleb.abc");
_mbscpy((unsigned char*)pStruct->m_SkinName, (const unsigned char*)"Skins\\Characters\\Caleb1.dtx");
_mbscpy((unsigned char*)pStruct->m_Name, (const unsigned char*)"player");
pStruct->m_ObjectType = OT_MODEL;
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::InitialUpdate()
//
// PURPOSE: The first update, set various player object properties.
//
// --------------------------------------------------------------------------- //
DBOOL CPlayerObj::InitialUpdate(int nData)
{
// NOTE: m_hClient is DNULL when we get here!!!
// Dev code to help us find the "ghost player" bug...
m_hPlrPosVar = g_pServerDE->GetGameConVar("playerpos");
if (!m_hPlrPosVar)
{
g_pServerDE->SetGameConVar("playerpos", "0");
m_hPlrPosVar = g_pServerDE->GetGameConVar("playerpos");
}
// Do the initial update...
CServerDE* pServerDE = GetServerDE();
pServerDE->SetNetFlags(m_hObject, NETFLAG_POSUNGUARANTEED|NETFLAG_ROTUNGUARANTEED|NETFLAG_ANIMUNGUARANTEED);
m_InventoryMgr.Init(m_hObject, m_hClient); // note: m_hClient is NULL, but it both get updated later
m_damage.Init(m_hObject, &m_InventoryMgr, &m_Anim_Sound);
// Set the team ID...
UpdateTeamID();
//for the internal AI enemy lists
dl_Insert( &AI_Mgr::m_MonsterHead, &m_MonsterLink );
m_MonsterLink.m_pData = ( void * )this;
AI_Mgr::m_dwNumMonster++;
dl_Insert( &AI_Mgr::m_CabalHead, &m_CabalLink );
m_CabalLink.m_pData = ( void * )this;
AI_Mgr::m_dwNumCabal++;
m_bFirstUpdate = DTRUE;
m_fMoveVel = 0;
m_fLadderVel = 0;
m_fJumpVel = 0;
m_fLeashLen = 0;
m_fMoveMultiplier = 0;
m_fBaseMoveAccel = 0;
m_fJumpMultiplier = 0;
m_bDoorPush = DFALSE;
VEC_INIT( m_vDoorPush );
m_fTeleportTime = 0;
m_LeashLenTrack.Init(pServerDE, "LeashLen", DNULL, DEFAULT_LEASHLEN);
// Only init stuff needed when restoring a savegame.
if (nData == INITIALUPDATE_SAVEGAME)
{
return DTRUE;
}
// Give max ammo for now
/* for (int i=AMMO_BULLET; i <= AMMO_MAXAMMOTYPES; i++)
{
m_InventoryMgr.AddAmmo(i, (DFLOAT)1000);
}*/
m_InventoryMgr.AddAmmo(AMMO_BULLET, 50);
// Change weapon
m_bSpectatorMode = DFALSE;
SendMessageToClient(SMSG_SPECTATORMODE);
m_bZoomView = DFALSE;
pServerDE->SetNextUpdate(m_hObject, (DFLOAT).001);
m_bLastJumpCommand = DFALSE;
m_bLastCrouchCommand = DFALSE;
m_bForcedCrouch = DFALSE;
m_bFalling = DFALSE;
m_bServerFalling = DFALSE;
m_damage.SetHitPoints(100.0f);
m_damage.SetArmorPoints(0.0f);
m_damage.SetMaxHitPoints(100.0f);
m_damage.SetMaxMegaHitPoints(100.0f);
m_damage.SetMaxArmorPoints(100.0f);
m_damage.SetMaxNecroArmorPoints(100.0f);
m_nLastHitPoints = 0;
m_nLastDamage = 0;
m_nLastAmmo = 0;
m_nLastArmor = 0;
m_nLastFocus = 0;
m_damage.SetMass(PA_DEFAULT_MASS);
pServerDE->SetBlockingPriority(m_hObject, BLOCKPRIORITY_PLAYER);
// Override the friction
pServerDE->SetFrictionCoefficient(m_hObject, 0.0f);
// pServerDE->SetFrictionCoefficient(m_hObject, 15.0f);
// Set the Smell Time
m_fSmellTime = pServerDE->GetTime();
m_fSmellDelay = 0.5f; // Delay between smell drops
DVector vPos;
pServerDE->GetObjectPos(m_hObject, &vPos);
ObjectCreateStruct theStruct;
INIT_OBJECTCREATESTRUCT(theStruct);
DRotation rRot;
ROT_INIT(rRot);
ROT_COPY(theStruct.m_Rotation, rRot);
VEC_COPY(theStruct.m_Pos, vPos);
pServerDE->CreateObject(pServerDE->GetClass("SmellHint"), &theStruct);
// Send the initial health, armor and ammo values to the client
// [blg] Andy says we don't need this...m_hClient is NULL at this point anyway
// [blg] SendMessageToClient(SMSG_HEALTH);
// pServerDE->SetForceIgnoreLimit(m_hObject, 250.0f);
m_Frags = 0;
m_MeleeKills = 0;
m_CurGun = WEAP_NONE;
m_CurGunSlot = 0;
m_bMovementBlocked = DFALSE;
// Wait until we get PLAYERATTRIBUTES from client for first respawn.
// Set initial dims
DVector dims;
VEC_SET(dims, 12, gCharacterValues[m_nCharacter].fHeightStanding/2, 12)
pServerDE->SetObjectDims(m_hObject, &dims);
m_hstrTrigger = pServerDE->CreateString("TRIGGER");
// All done...
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::UpdateTeamID
//
// PURPOSE: Updates the team ID value that this player is on
//
// ----------------------------------------------------------------------- //
void CPlayerObj::UpdateTeamID()
{
CTeam* pTeam = g_pBloodServerShell->GetTeamMgr()->GetTeamFromPlayerID(g_pServerDE->GetClientID(GetClient()));
if (pTeam)
{
m_dwTeamID = pTeam->GetID();
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::UpdateControlFlags
//
// PURPOSE: Set the movement/firing flags
//
// ----------------------------------------------------------------------- //
void CPlayerObj::UpdateControlFlags()
{
// Clear control flags...
m_dwControlFlags = 0;
if(m_bDead) return;
// Make sure it's ok for us to move...
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !m_hClient || m_bDemoPlayback || m_bMovementBlocked) return;
if (m_bInSlowDeath) return; // [blg] 01/13/99
// Determine what commands are currently on...
if (pServerDE->IsCommandOn(m_hClient, COMMAND_RUN) || m_byFlags & CDATA_RUNLOCK)
{
m_dwControlFlags |= CTRLFLAG_RUN;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_JUMP))
{
m_dwControlFlags |= CTRLFLAG_JUMP;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_DUCK))
{
m_dwControlFlags |= CTRLFLAG_CROUCH;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_FORWARD))
{
m_dwControlFlags |= CTRLFLAG_FORWARD;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_BACKWARD))
{
m_dwControlFlags |= CTRLFLAG_BACKWARD;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_LEFT))
{
m_dwControlFlags |= CTRLFLAG_LEFT;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_RIGHT))
{
m_dwControlFlags |= CTRLFLAG_RIGHT;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_STRAFE))
{
m_dwControlFlags |= CTRLFLAG_STRAFE;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_STRAFERIGHT))
{
m_dwControlFlags |= CTRLFLAG_STRAFERIGHT;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_STRAFELEFT))
{
m_dwControlFlags |= CTRLFLAG_STRAFELEFT;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_FIRE))
{
m_dwControlFlags |= CTRLFLAG_FIRE;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_ALTFIRE))
{
m_dwControlFlags |= CTRLFLAG_ALTFIRE;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_GRAB))
{
m_dwControlFlags |= CTRLFLAG_GRAB;
}
if (pServerDE->IsCommandOn(m_hClient, COMMAND_TAUNT))
{
m_dwControlFlags |= CTRLFLAG_TAUNT;
}
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CPlayerObj::HandleMovement()
//
// PURPOSE: Checks for movement commands and updates acceleration, etc.
//
// --------------------------------------------------------------------------- //
DBOOL CPlayerObj::HandleMovement()
{
CServerDE* pServerDE = GetServerDE();
DVector vMyVel;
DVector vAccel;
DVector vUp;
DVector vRight;
DVector vForward;
DVector vMyPos;
DFLOAT fMaxMoveAccel;
DFLOAT fMaxMoveVel;
DFLOAT fMoveAccel = 0.0;
DFLOAT fJumpSpeed = DEFAULT_JUMPVEL;
DFLOAT fStrafeAccel = 0;
DBOOL bNothingHappened = DTRUE;
DBOOL bHeadInLiquid = IsLiquid(m_eContainerCode);
DBOOL bInLiquid = bHeadInLiquid || m_bBodyInLiquid;
DBOOL bFreeMovement = bHeadInLiquid || m_bBodyOnLadder || m_bSpectatorMode;
DBOOL bLateralMovement = DFALSE;
int nIndex = (m_nAttribSpeed + m_nBindingSpeed - 1);
nIndex = DCLAMP(nIndex, 0, 6);
fMaxMoveVel = gMoveVel[nIndex];
fMaxMoveAccel = fMaxMoveVel * gDragCoeff[nIndex];
// Zero acceleration to start with
VEC_INIT(vAccel);
// Get my position
pServerDE->GetObjectPos(m_hObject, &vMyPos);
// See if standing on anything
// DBOOL bIsStandingOn = DFALSE;
// m_eLastSurface = SURFTYPE_UNKNOWN;
CollisionInfo collisionInfo;
pServerDE->GetStandingOn(m_hObject, &collisionInfo);
// DBOOL bIsStandingOn = (collisionInfo.m_hObject != DNULL);
// Don't want to be moved if standing on a base character
if(m_bOnGround)
{
DDWORD dwFlags = pServerDE->GetObjectFlags(m_hObject);
if(IsBaseCharacter(collisionInfo.m_hObject))
dwFlags |= FLAG_DONTFOLLOWSTANDING;
else
dwFlags &= ~FLAG_DONTFOLLOWSTANDING;
pServerDE->SetObjectFlags(m_hObject, dwFlags);
// Get the last surface type (for footsteps, etc)
// m_eLastSurface = ::GetSurfaceType(collisionInfo.m_hObject, collisionInfo.m_hPoly);
// Damage object we fell on...
if (m_bFalling)
{
DVector vTmp;
VEC_INIT(vTmp);
DamageObject(m_hObject, this, collisionInfo.m_hObject, 1.0f, vTmp, vTmp, DAMAGE_TYPE_NORMAL);
}
// Set higher blocking priority when on the ground so we can push stuff
pServerDE->SetBlockingPriority(m_hObject, BLOCKPRIORITY_PLAYER);
}
else
pServerDE->SetBlockingPriority(m_hObject, BLOCKPRIORITY_PLAYER_AIRBORNE);
// Get current velocity
pServerDE->GetVelocity(m_hObject, &vMyVel);
DFLOAT fMyVelMag = VEC_MAG(vMyVel);
// Disable footsteps if moving too slowly
m_bDisableFootsteps = (fMyVelMag < 50) ? DTRUE : DFALSE;
// BEGIN 10/6/98 Kevin additions ////////////////////////////////////
m_fSwimVel = (m_dwControlFlags & CTRLFLAG_RUN) ? DEFAULT_SWIM_VEL : DEFAULT_SWIM_VEL/2.0f;
m_fLadderVel = (m_dwControlFlags & CTRLFLAG_RUN) ? DEFAULT_LADDER_VEL : DEFAULT_LADDER_VEL/2.0f;
if (!m_bBodyInLiquid) m_bSwimmingJump = DFALSE;
// Limit velocity when in certain containers...
if (m_bBodyOnLadder)
{
if (fMyVelMag > m_fLadderVel)
{
VEC_NORM(vMyVel);
VEC_MULSCALAR(vMyVel, vMyVel, m_fLadderVel);
}
}
else if (m_bBodyInLiquid)
{
if (fMyVelMag > m_fSwimVel)
{
VEC_NORM(vMyVel);
VEC_MULSCALAR(vMyVel, vMyVel, m_fSwimVel);
if (m_bSwimmingJump) // Keep setting jump speed until I jump out
vMyVel.y = fJumpSpeed * 0.75f;
}
}
// END 10/6/98 Kevin additions ////////////////////////////////////
// See if running
if (!m_damage.IsDead())
{
// get the object's vectors
pServerDE->GetRotationVectors(&m_rRotation, &vUp, &vRight, &vForward);
if (m_bSpectatorMode)
{
DVector vel;
VEC_INIT(vel);
// pServerDE->SetVelocity(m_hObject, &vel);
fMaxMoveAccel = 1.0f;
fMaxMoveVel = 500.0f;
}
else if (!bFreeMovement && !bInLiquid)
{
// Only want x and z components for movement
vRight.y = 0;
VEC_NORM(vRight)
vForward.y = 0;
VEC_NORM(vForward)
}
if (m_dwControlFlags & CTRLFLAG_RUN)
{
fMaxMoveAccel *= 1.5;
fMaxMoveVel *= 1.5;
}
if (((m_dwControlFlags & CTRLFLAG_CROUCH) || m_bForcedCrouch) && !bFreeMovement)
{
fMaxMoveAccel /= 2;
fMaxMoveVel /= 2;
bNothingHappened = DFALSE;
}
// Set acceleration based on player controls
// Move forward/backwards
if ((m_dwControlFlags & CTRLFLAG_FORWARD) && (!m_bMovementBlocked || m_eContainerCode == CC_CRANECONTROL))
{
fMoveAccel += fMaxMoveAccel;
bNothingHappened = DFALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -