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

📄 ai_mgr.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	// Don't let y be a factor...
	vTargetPos.y = vPos.y;

	MC_FacePos(vTargetPos);

	DFLOAT fSpeed = m_fWalkSpeed;
	if (m_eScriptMovement == SM_RUN)
	{
		fSpeed = m_fRunSpeed;
	}

	DFLOAT fDistLeft = VEC_DIST(vTargetPos, vPos);
	DFLOAT fDistPredict = m_pServerDE->GetFrameTime() * fSpeed;

	if (fDistLeft <= fDistPredict * 2.0f)
	{
		// Move to the position for completeness
		if(!m_nTrapped)
			m_pServerDE->MoveObject(m_hObject, &vTargetPos);

		// Check for Target and messages from this pathpoint...
		if (pCurKey->m_hstrActionMessage)
		{
			// If there is a target, use that.  If not, send to myself.
			if (pCurKey->m_hstrActionTarget)
			{
				SendTriggerMsgToObjects(this, 
										pCurKey->m_hstrActionTarget, 
										pCurKey->m_hstrActionMessage);
			}
			else
			{
				HMESSAGEWRITE hMessage;

				hMessage = m_pServerDE->StartMessageToObject(this, m_hObject, MID_TRIGGER);
				m_pServerDE->WriteToMessageHString(hMessage, pCurKey->m_hstrActionMessage);
				m_pServerDE->EndMessage(hMessage);
			}
		}

		// Remove it from the pathpoint list
		m_AIPathList.Remove(0);
	}
	else
	{
		DBOOL bOkToMove = DTRUE;
		if (m_dwScriptFlags & AI_SCRFLG_OPPORTFIRE)
		{
			bOkToMove = !Script_Fire_Stand();
		}

		if (bOkToMove)
		{
			if (m_eScriptMovement == SM_RUN)
			{
				Script_Run();
			}
			else
			{
				Script_Walk();
			}
		}
	}

}


// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::SetMoveToObjectCmd
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AI_Mgr::SetMoveToObjectCmd()
{
	char *pTargetName = m_curScriptCmd.args;
	ObjectList*	pList = m_pServerDE->FindNamedObjects(pTargetName);
	if (!pList) return;

	ObjectLink* pLink = pList->m_pFirstLink;
	if (pLink)
	{
		SetNewTarget(pLink->m_hObject);
	}
	else
	{
		m_bUpdateScriptCmd = DTRUE;
	}

	m_pServerDE->RelinquishList(pList);

	Metacmd = 1;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::UpdateMoveToObjectCmd
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AI_Mgr::UpdateMoveToObjectCmd()
{
	// Face where we are going...

	if (!m_hTarget)
	{
		m_bUpdateScriptCmd = DTRUE;
		return;
	}

	DVector vTargetPos;
	m_pServerDE->GetObjectPos(m_hTarget, &vTargetPos);
    
 	DVector vPos;
	VEC_COPY(vPos, m_MoveObj.GetPos());

	// Don't let y be a factor...
	vTargetPos.y = vPos.y;

   switch(Metacmd)
    {
		case 1:
		{
			m_MoveObj.CalculatePath(vTargetPos);
			Metacmd++;									
		}
		break;
		
		case 2:		
		{
			MC_FacePos(*m_MoveObj.GetNextPathPoint());
		}
		break;

		case 3:		
		{
			DFLOAT fSpeed = m_fWalkSpeed;
			if (m_eScriptMovement == SM_RUN)
			{
				fSpeed = m_fRunSpeed;
			}

			DFLOAT fDistLeft = VEC_DIST(*m_MoveObj.GetNextPathPoint(), vPos);
			DFLOAT fDistPredict = m_pServerDE->GetFrameTime() * fSpeed;

			if (fDistLeft <= fDistPredict * 2.0f)
			{
				if (!m_MoveObj.MoveToNextPathPoint())
				{
					Metacmd++;
				}
				else
				{
					Metacmd = 2;
				}
			}
			else
			{
				if (m_eScriptMovement == SM_RUN)
				{
					if (m_dwScriptFlags & AI_SCRFLG_OPPORTFIRE)
					{
						Script_Fire_Run();
					}
					else
					{
						Script_Run();
					}
				}
				else
				{
					if (m_dwScriptFlags & AI_SCRFLG_OPPORTFIRE)
					{
						Script_Fire_Walk();
					}
					else
					{
						Script_Walk();
					}
				}

				Metacmd = 2;
			}
		}
		break;
						
		case 4:		
		{
			// Move to the position for completeness
			if(!m_nTrapped)
				m_pServerDE->MoveObject(m_hObject, &vTargetPos);
			m_bUpdateScriptCmd = DTRUE;
		}
		break;
	}
}


// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::SetPlaysoundCmd
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AI_Mgr::SetPlaysoundCmd()
{
	char* pSoundName = m_curScriptCmd.args;
	if (pSoundName) 
    {
        PlaySoundFromObject( m_hObject, pSoundName, 5000.0f, SOUNDPRIORITY_MISC_HIGH, DFALSE, DFALSE, DFALSE );
    }                          
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::SetSetStateCmd
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AI_Mgr::SetSetStateCmd()
{
    SetNewState(StateStrToInt(m_curScriptCmd.args));
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::SetTargetCmd
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AI_Mgr::SetTargetCmd()
{
	SetTarget(m_curScriptCmd.args);
	SetNewState(STATE_AttackFar);
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::SetWaitCmd
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AI_Mgr::SetWaitCmd()
{
	m_fScriptWaitEnd = m_pServerDE->GetTime() + atoi(m_curScriptCmd.args);
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::UpdateWaitCmd
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AI_Mgr::UpdateWaitCmd()
{
	if (m_pServerDE->GetTime() >= m_fScriptWaitEnd)
	{
		m_bUpdateScriptCmd = DTRUE;
	}
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::SetPlayAnimationCmd
// DESCRIPTION	: 
// RETURN TYPE	: void 
// PARAMS		: DBOOL bLooping - Animation should be played looping.
// ----------------------------------------------------------------------- //

void AI_Mgr::SetPlayAnimationCmd(DBOOL bLooping)
{
	DDWORD dwIndex = m_pServerDE->GetAnimIndex(m_hObject, m_curScriptCmd.args);
	m_pServerDE->SetModelLooping(m_hObject, bLooping);
//	m_pServerDE->SetModelAnimation(m_hObject, dwIndex);
	SetAnimation(dwIndex);
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::UpdatePlayAnimationCmd
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AI_Mgr::UpdatePlayAnimationCmd()
{
	DDWORD dwState = m_pServerDE->GetModelPlaybackState(m_hObject);

	if ((dwState & MS_PLAYDONE))
	{
		m_bUpdateScriptCmd = DTRUE;
	}
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::FacePos
// DESCRIPTION	: 
// RETURN TYPE	: void 
// PARAMS		: DVector vTargetPos
// ----------------------------------------------------------------------- //

void AI_Mgr::FacePos(DVector vTargetPos)
{
	DVector vDir, vPos;

	// GJK 7/29/98 - Made this puppy much simpler.  More importantly, it works now.

	m_pServerDE->GetObjectPos(m_hObject, &vPos);
	vTargetPos.y = vPos.y; // Don't look up/down.

	VEC_SUB(vDir, vTargetPos, vPos);
	VEC_NORM(vDir);

	DRotation rRot;
	m_pServerDE->AlignRotation(&rRot, &vDir, NULL);
	m_pServerDE->SetObjectRotation(m_hObject, &rRot);
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::HandleDamage
// DESCRIPTION	: Handle MID_DAMAGE messages
// RETURN TYPE	: void 
// PARAMS		: HOBJECT hSender
// PARAMS		: DDWORD messageID
// PARAMS		: HMESSAGEREAD hRead
// ----------------------------------------------------------------------- //

DBOOL AI_Mgr::HandleDamage()
{
	if(m_nState == STATE_Dying || m_bRemoveMe)
		return DTRUE;

	//should we limp?
	int nNodeHit = m_damage.GetNodeHit();

	//didn't hit so return
	if(nNodeHit == -1)
		return DTRUE;

	int nType = m_damage.GetLastDamageType();
	DFLOAT fDamage = m_damage.GetLastDamageAmount();

	DVector vDir;
	m_damage.GetLastDamageDirection(&vDir);

	if(m_dwFlags & FLAG_LIMP && m_nInjuredLeg == 0 && 
	   (nNodeHit == NODE_LLEG || nNodeHit == NODE_RLEG))
	{
		if(m_damage.GetHitPoints() < (m_damage.GetMaxHitPoints() * 0.5f))
		{
			m_nInjuredLeg = nNodeHit;
		}
	}

	//SCHLEGZ 3/10/98 12:44:32 AM: check for limb loss
	if (m_damage.GetHitPoints() <= 0.0f) 
	{
		if(m_bCabal)
			m_InventoryMgr.DropCurrentWeapon();		//SCHLEGZ 4/26/98 10:14:32 PM: i'm dead; no need for weapon

		//see what we are standing on
		CollisionInfo collisionInfo;
		m_pServerDE->GetStandingOn(m_hObject, &collisionInfo);

		if(collisionInfo.m_hObject && (collisionInfo.m_hObject != m_pServerDE->GetWorldObject()))
		{
			DDWORD dwFlags = m_pServerDE->GetObjectFlags(collisionInfo.m_hObject);

			if(!(dwFlags & FLAG_SOLID))
			{
				m_dwFlags |= FLAG_ALWAYSGIB;		
			}
		}

		//do we need to start the barbecue?
		if(nType == DAMAGE_TYPE_FIRE && !(m_dwFlags & FLAG_ALWAYSGIB))
		{
			ObjectCreateStruct ocStruct;
			INIT_OBJECTCREATESTRUCT(ocStruct);

			ocStruct.m_ObjectType = OT_NORMAL;
			ocStruct.m_NextUpdate = 0.01f;
			m_pServerDE->GetModelNodeTransform(m_hObject, "torso",&ocStruct.m_Pos,&ocStruct.m_Rotation);
			ocStruct.m_Flags = FLAG_FORCECLIENTUPDATE;
			
			HCLASS hClass = m_pServerDE->GetClass("BaseClass");
			BaseClass* pObj = m_pServerDE->CreateObject(hClass, &ocStruct);

			if(pObj)
			{
				m_hFireSource = pObj->m_hObject;
			}
		}
		else if((nType == DAMAGE_TYPE_EXPLODE || m_dwFlags & FLAG_ALWAYSGIB) && !(m_dwFlags & FLAG_NEVERGIB))
		{
			CreateGibs(vDir, ((int)m_damage.GetMass())>>5, nType, fDamage);

			m_bRemoveMe = DTRUE;

			if (IsRandomChance(7) && (m_damage.GetWhoKilledMeLast() == g_pPlayerObj->m_hObject))
			{
				g_pPlayerObj->PlayVoiceGroupEventOnClient(VME_BIGGIB, DTRUE);	// [blg]
			}
		}
		else if((m_damage.GetLastDamagePercent() >= 0.90f) && !(m_dwFlags & FLAG_NEVERGIB))
		{
			CreateGibs(vDir, ((int)m_damage.GetMass())>>5, nType, fDamage);

			m_bRemoveMe = DTRUE;

			if (IsRandomChance(7) && (m_damage.GetWhoKilledMeLast() == g_pPlayerObj->m_hObject))
			{
				g_pPlayerObj->PlayVoiceGroupEventOnClient(VME_BIGGIB, DTRUE);	// [blg]
			}
		}
/*		else if(nNodeHit > 0 && m_damage.GetLastDamagePercent() >= 0.25f)	// 10% of the time, blow off the head.  25% for other limbs
		{
			if(AIShared.HideLimb(m_hObject,nNodeHit) && (m_dwFlags & FLAG_LIMBLOSS))
			{
				AIShared.CreateLimb(m_hObject, nNodeHit, vDir);
			}

		}
*/
		if (IsRandomChance(6) && (m_damage.GetWhoKilledMeLast() == g_pPlayerObj->m_hObject))
		{
			g_pPlayerObj->PlayVoiceGroupEventOnClient(VME_KILL, DTRUE);	// [blg]
		}
	}

	if (m_nState == STATE_Script)
	{
		if(!(m_dwScriptFlags & AI_SCRFLG_INT))
			return DTRUE;
	}

	if(m_dwFlags & FLAG_ALWAYSRECOIL)
		SetNewState(STATE_Recoil);
	else if(fDamage >= m_damage.GetHitPoints() * 0.25f && m_nState != STATE_Teleport && m_nState != STATE_Dodge)	
		SetNewState(STATE_Recoil);
	else if(m_nState != STATE_AttackClose && m_nState != STATE_AttackFar)
		ComputeState();

	return DTRUE;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Mgr::SetNewState
// DESCRIPTION	: Set new state and reset metacmd 
// RETURN TYPE	: void 
// PARAMS		: int nState
// ----------------------------------------------------------------------- //

void AI_Mgr::SetNewState(int nState)
{
	float fTime;

	if(m_nState != STATE_WalkAroundObj && m_nState != STATE_RunAroundObj
	   && m_nState != STATE_JumpOverObj && m_nState != STATE_CrawlUnderObj
	   && m_nState != STATE_SearchVisualTarget && m_nState != STATE_SearchSmellTarget)
	{
		if(m_nLastState != m_nState)
			m_nLastState = m_nState; 
	}

	fTime = g_pServerDE->GetTime( );

	// Don't switch to the idle state too fast
	if( nState == STATE_Idle && m_bHasTargeted )
	{
		if( fTime > m_fWaitForIdleTime )
			m_nState = nState;
		else
			m_nState = STATE_SearchVisualTarget;
	}
	else
	{
		m_nState = nState;
		m_fWaitForIdleTime = fTime + WAITFORIDLETIME;
	}
	Metacmd = 1; 
	m_nCurMetacmd = 999;
	m_bAnimating = DFALSE;

	StopVelocity();

	return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -