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

📄 ai_shared.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// ----------------------------------------------------------------------- //
//
// MODULE  : AI_Shared.cpp
//
// PURPOSE : AI shared functions 
//
// CREATED : 
//
// ----------------------------------------------------------------------- //

#include <stdio.h>
#include "cpp_server_de.h"
//#include "Destructable.h"
#include "BaseCharacter.h"
#include "generic_msg_de.h"
#include "AI_Shared.h"
#include "ObjectUtilities.h"
#include "SoundTypes.h"

#include "PathPoint.h"
#include "gib.h"
#include <mbstring.h>

#define MAX_DISTANCE	100000.0f

void BPrint(char*);



// *************************************************************************
// *************************************************************************
// *************************************************************************
//
// Shared Functions
// All these functions are generic... they could be used by any game system
//
// *************************************************************************
// *************************************************************************
// *************************************************************************



// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::AI_Shared()
//
//	PURPOSE:	Constructor - Initialize
//
// ----------------------------------------------------------------------- //
AI_Shared::AI_Shared()
{
    m_bTurnR = DFALSE;
    m_bTurnL = DFALSE;
}




// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::GetEyeLevel()
//
//	PURPOSE:	Compute our 'eye level'
//
// ----------------------------------------------------------------------- //
DVector AI_Shared::GetEyeLevel(HOBJECT m_hObject)
{
	DVector vPos, vDims;
	VEC_INIT(vPos);

	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject) return vPos;

	pServerDE->GetObjectDims(m_hObject, &vDims);
	pServerDE->GetObjectPos(m_hObject, &vPos);

	vPos.y += vDims.y / 2.0f;
//	vPos.y -= m_fEyeLevelOffset;
	vPos.y -= 1;
	
	return vPos;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::DistToWorld()
//
//	PURPOSE:	How far away is the closes object
//
// ----------------------------------------------------------------------- //
DFLOAT AI_Shared::DistToWorld(HOBJECT m_hObject, DVector vDir)
{
	DVector vPos = GetEyeLevel(m_hObject);

	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject) return MAX_DISTANCE;

	IntersectQuery IQuery;
	IntersectInfo IInfo;

	VEC_COPY(IQuery.m_From, vPos);
	VEC_COPY(IQuery.m_Direction, vDir);
	IQuery.m_Flags	  = INTERSECT_OBJECTS;
	IQuery.m_FilterFn = DNULL;

	if (pServerDE->CastRay(&IQuery, &IInfo))
	{
		return VEC_DIST(vPos, IInfo.m_Point);
	}

	return MAX_DISTANCE;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::TurnToClear()
//
//	PURPOSE:	To to clearest direction for traveling
//
// ----------------------------------------------------------------------- //

DBOOL AI_Shared::TurnToClear(HOBJECT hObject)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !hObject) return DFALSE;

	DRotation rRot;
	DVector m_vUp, m_vRight, m_vForward, vPos;

	pServerDE->GetObjectRotation(hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);
	pServerDE->GetObjectPos(hObject,&vPos);

	IntersectQuery IQuery;
	IntersectInfo IInfo;

	IQuery.m_Flags	  = INTERSECT_OBJECTS;
	IQuery.m_FilterFn = DNULL;
	VEC_COPY(IQuery.m_From, vPos);

	//FORWARD
	VEC_COPY(IQuery.m_Direction, m_vForward);

	pServerDE->CastRay(&IQuery, &IInfo);
	DFLOAT fForward = VEC_DIST(vPos, IInfo.m_Point);

	//RIGHT
	VEC_COPY(IQuery.m_Direction, m_vRight);

	pServerDE->CastRay(&IQuery, &IInfo);
	DFLOAT fRight = VEC_DIST(vPos, IInfo.m_Point);

	//LEFT
	VEC_MULSCALAR(m_vRight,m_vRight,-1);
	VEC_COPY(IQuery.m_Direction, m_vRight);

	pServerDE->CastRay(&IQuery, &IInfo);
	DFLOAT fLeft = VEC_DIST(vPos, IInfo.m_Point);

	//Check which way we need to go
	if(fForward > fRight && fForward > fLeft)
		return DFALSE;
	else if(fRight > fForward && fRight > fLeft)
	{
	    pServerDE->EulerRotateY(&rRot, MATH_PI/10 * -1);
		pServerDE->SetObjectRotation(hObject, &rRot);	
	}
	else if(fLeft > fForward && fLeft > fRight)
	{
	    pServerDE->EulerRotateY(&rRot, MATH_PI/10);
		pServerDE->SetObjectRotation(hObject, &rRot);	
	}

	return DTRUE;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::IsLedge()
//
//	PURPOSE:	Check a ledge in front of you
//
// ----------------------------------------------------------------------- //
DBOOL AI_Shared::IsLedge(HOBJECT m_hObject, DFLOAT m_fDist)
{
	DVector vPos, vTemp, vDir, vDims;

	VEC_INIT(vPos);
	VEC_INIT(vDir);
	VEC_INIT(vTemp);
    
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject) return DFALSE;

	DRotation rRot;
    DVector m_vUp, m_vRight, m_vForward;
    
    VEC_INIT(m_vUp);
	VEC_INIT(m_vRight);
	VEC_INIT(m_vForward);

	pServerDE->GetObjectRotation(m_hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);    

//  m_fDist = 50;
    DFLOAT m_fStepHeight = 25;
    
	pServerDE->GetObjectDims(m_hObject, &vDims);
	pServerDE->GetObjectPos(m_hObject, &vPos);

	VEC_MULSCALAR(vTemp, m_vForward, m_fDist);
	VEC_ADD(vPos, vPos, vTemp);
    
    // vPos is a point in front of you.
    // vDir is a point in front of you, but down
	VEC_COPY(vDir, vPos);
	vDir.y = (vDir.y - vDims.y) - m_fStepHeight;

	IntersectQuery IQuery;
	IntersectInfo IInfo;

	VEC_COPY(IQuery.m_From, vPos);
	VEC_COPY(IQuery.m_To, vDir);
    
	IQuery.m_Flags	  = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	IQuery.m_FilterFn = NULL;
	IQuery.m_pUserData = NULL;	

	if (pServerDE->IntersectSegment(&IQuery, &IInfo))
	{
    	return DFALSE;
	}
    
  	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::DistToWorldForward()
//
//	PURPOSE:	How far away is the closes object straight ahead
//
// ----------------------------------------------------------------------- //
DFLOAT AI_Shared::DistToWorldForward(HOBJECT m_hObject)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject) return DFALSE;

	DRotation rRot;
    DVector m_vUp, m_vRight, m_vForward;
    
    VEC_INIT(m_vUp);
	VEC_INIT(m_vRight);
	VEC_INIT(m_vForward);

	pServerDE->GetObjectRotation(m_hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);

	return DistToWorld(m_hObject, m_vForward);
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AI_Shared::DistToWorldBackward
// DESCRIPTION	: 
// RETURN TYPE	: DFLOAT 
// PARAMS		: HOBJECT m_hObject
// ----------------------------------------------------------------------- //

DFLOAT AI_Shared::DistToWorldBackward(HOBJECT m_hObject)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject) return DFALSE;

	DRotation rRot;
    DVector m_vUp, m_vRight, m_vForward;
    
	VEC_INIT(m_vUp);
	VEC_INIT(m_vRight);
	VEC_INIT(m_vForward);

	pServerDE->GetObjectRotation(m_hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);

	DVector vDir;
	VEC_COPY(vDir, m_vForward);
	VEC_MULSCALAR(vDir, vDir, -1.0f); // point left
	
	return DistToWorld(m_hObject, vDir);
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::DistToWorldRight()
//
//	PURPOSE:	How far away is the closest object to our right
//
// ----------------------------------------------------------------------- //
DFLOAT AI_Shared::DistToWorldRight(HOBJECT m_hObject)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject) return DFALSE;

	DRotation rRot;
    DVector m_vUp, m_vRight, m_vForward;
    
	VEC_INIT(m_vUp);
	VEC_INIT(m_vRight);
	VEC_INIT(m_vForward);

	pServerDE->GetObjectRotation(m_hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);
    
	return DistToWorld(m_hObject, m_vRight);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::DistToWorldLeft()
//
//	PURPOSE:	How far away is the closest object to our left
//
// ----------------------------------------------------------------------- //
DFLOAT AI_Shared::DistToWorldLeft(HOBJECT m_hObject)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject) return DFALSE;

	DRotation rRot;
    DVector m_vUp, m_vRight, m_vForward;
    
	VEC_INIT(m_vUp);
	VEC_INIT(m_vRight);
	VEC_INIT(m_vForward);

	pServerDE->GetObjectRotation(m_hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);

	DVector vDir;
	VEC_COPY(vDir, m_vRight);
	VEC_MULSCALAR(vDir, vDir, -1.0f); // point left
	
	return DistToWorld(m_hObject, vDir);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::IsObjectVisible()
//
//	PURPOSE:	Is the test object visible
//
// ----------------------------------------------------------------------- //
DBOOL AI_Shared::IsObjectVisible(HOBJECT m_hObject, HOBJECT hTestObj)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject || !hTestObj) return DFALSE;

	DVector vOurPos, vTheirPos;
	DVector vPos = GetEyeLevel(m_hObject);

	pServerDE->GetObjectPos(m_hObject, &vOurPos);
	pServerDE->GetObjectPos(hTestObj, &vTheirPos);

	DVector vDir;
	VEC_SUB(vDir, vTheirPos, vOurPos);
	
	IntersectQuery IQuery;
	IntersectInfo IInfo;

	VEC_COPY(IQuery.m_From, vPos);
	VEC_COPY(IQuery.m_Direction, vDir);
	IQuery.m_Flags	  = INTERSECT_OBJECTS;
	IQuery.m_FilterFn = DNULL;

	if (pServerDE->CastRay(&IQuery, &IInfo))
	{
		// BUGBUG: If the object is partially occluded it might fail this test!
		if (IInfo.m_hObject == hTestObj)
		{
			return DTRUE;
		}
	}

	return DFALSE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::IsObjectVisibleToAI()
//
//	PURPOSE:	Is the test object visible to us (forward + FoV)?
//
// ----------------------------------------------------------------------- //
DBOOL AI_Shared::IsObjectVisibleToAI(HOBJECT m_hObject, HOBJECT hTestObj, DFLOAT m_fSeeingDist)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject || !hTestObj) return DFALSE;

	DVector vOurPos, vTheirPos;

    // Get the Rotation
	DRotation rRot;
    DVector m_vUp, m_vRight, m_vForward;
    
	VEC_INIT(m_vUp);
	VEC_INIT(m_vRight);
	VEC_INIT(m_vForward);

	pServerDE->GetObjectRotation(m_hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);


	if(IsObjectVisible(m_hObject, hTestObj))
	{
		pServerDE->GetObjectPos(m_hObject, &vOurPos);
		pServerDE->GetObjectPos(hTestObj, &vTheirPos);

		DVector vDir;
		VEC_SUB(vDir, vTheirPos, vOurPos);
	
		// Now test to see if AI is facing test object...

		DFLOAT fDp;
		fDp = (vDir.x * m_vForward.x) + (vDir.y * m_vForward.y) + (vDir.z * m_vForward.z);
		
		if (fDp > 0)
		{
			// AI is facing test object so it can 'see' it
			if (VEC_MAG(vDir) < m_fSeeingDist) return DTRUE;
		}
	}
		
	return DFALSE;
}			





// ----------------------------------------------------------------------- //

⌨️ 快捷键说明

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