⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playerobj.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		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 + -