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

📄 ai_shared.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
//	ROUTINE:	AI_Shared::ListenForEnemy()
//
//	PURPOSE:	Look for sound objects... (will be created by Player shooting, open doors)
//              sound object will remove itself after a few secs...
//
//              Message from sound...
//
// ----------------------------------------------------------------------- //
//HOBJECTL AI_Shared::ListenForEnemy(HOBJECT m_hObject, DFLOAT fRange)
//{
//// Sound Messages... SOUND_NOTIFY???
//    return DFALSE;
//}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::SenseForEnemy()
//
//	PURPOSE:	Look for Player objects (radius)
//
// ----------------------------------------------------------------------- //
HOBJECT AI_Shared::SenseForEnemy(HOBJECT m_hObject, DFLOAT fRange)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject ) return DFALSE;
    
	HCLASS hPlayerTest = pServerDE->GetClass("CPlayerObj");

    HOBJECT hFoundObj = FindObjectInRadius(m_hObject, hPlayerTest, fRange, DFALSE, "", DTRUE);
    
    if (hFoundObj != DNULL)
    {
        CBaseCharacter* pB = (CBaseCharacter*)pServerDE->HandleToObject(hFoundObj);
        if( pB->IsDead() == DFALSE )
        {
    	    return hFoundObj;
        }            
    }
    
    return DNULL;
}



// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::SmellForEnemy()
//
//	PURPOSE:	Look for Player objects (radius)
//
// ----------------------------------------------------------------------- //
HOBJECT AI_Shared::SmellForEnemy(HOBJECT m_hObject, DFLOAT fRange)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject ) return DFALSE;

	HCLASS hPlayerTest = pServerDE->GetClass("CPlayerObj");

    HOBJECT hFoundObj = FindObjectInRadius(m_hObject, hPlayerTest, fRange, DTRUE, "", DTRUE);
    
    if (hFoundObj != DNULL)
    {
        CBaseCharacter* pB = (CBaseCharacter*)pServerDE->HandleToObject(hFoundObj);
        if( pB->IsDead() == DFALSE )
        {
    	    return hFoundObj;
        }            
    }
    
    return DNULL;
}



// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::LookForEnemy()
//
//	PURPOSE:	Look for Player objects (radius)
//
// ----------------------------------------------------------------------- //
HOBJECT AI_Shared::LookForEnemy(HOBJECT m_hObject, DFLOAT fRange)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject ) return DFALSE;

    // 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);

	HCLASS hPlayerTest = pServerDE->GetClass("CPlayerObj");
    HOBJECT hFoundObj = FindObjectInRadius(m_hObject, hPlayerTest, fRange, DTRUE, "", DTRUE);
    
    if (hFoundObj != DNULL)
    {
    	DVector vOurPos, vTheirPos;

		pServerDE->GetObjectPos(m_hObject, &vOurPos);
		pServerDE->GetObjectPos(hFoundObj, &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
            CBaseCharacter* pB = (CBaseCharacter*)pServerDE->HandleToObject(hFoundObj);
            if( pB->IsDead() == DFALSE )
            {
    	        return hFoundObj;
            }            

            // Already checked for range in the FindNearObjectInRadius...
			//if (VEC_MAG(vDir) < fRange) return DTRUE;
		}
	}

	return DNULL;
}			






// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_Shared::FindNearObjectInRadius()
//
//  RETURN:     return the Ideal Object we are looking for, DNULL of nothing found
//
//	PURPOSE:	Look for nearest object within radius (visible or Not)
//
// ----------------------------------------------------------------------- //
HOBJECT AI_Shared::FindObjectInRadius(HOBJECT m_hObject, HCLASS hObjectTest, DFLOAT fRange, DBOOL bCheckVisible, char* sObjName, DBOOL bNear)
{

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

    DFLOAT fObjDist, fSaveDist = 0;
    DFLOAT fObjTime, fSaveTime = 0;

    HOBJECT hIdealObj = DNULL;
    DBOOL bVisible = DFALSE;
    
    // Get AI's current Position
	DVector vPos;
//	pServerDE->GetObjectPos(m_hObject, &vPos);
	DRotation rRot;
	pServerDE->GetModelNodeTransform(m_hObject,szNodes[NODE_NECK-1],&vPos,&rRot);

    // Create a List of objects within the Radius
	ObjectList* pTargets = pServerDE->FindObjectsTouchingSphere(&vPos, fRange);
	if (!pTargets || pTargets->m_nInList <= 0) return DNULL;

    // Found all the Objects
	ObjectLink *pLink = pTargets->m_pFirstLink;
	while(pLink && pLink->m_hObject)
	{
		HCLASS hType = pServerDE->GetObjectClass(pLink->m_hObject);

        char sTestObjectName[128];
        
        if (_mbstrlen(sObjName) == 0)
        {
            _mbscpy((unsigned char*)sTestObjectName, (const unsigned char*)pServerDE->GetObjectName(pLink->m_hObject));
        }
        else
        {
            _mbscpy((unsigned char*)sTestObjectName, (const unsigned char*)sObjName);
        }        
        
        // Did we find one?
		if( (pServerDE->IsKindOf(hType, hObjectTest)) && 
            (_mbsncmp((const unsigned char*)pServerDE->GetObjectName(pLink->m_hObject), (const unsigned char*)sTestObjectName, _mbstrlen(sTestObjectName)) == 0 ) )
		{
            // Check for nearest Object!
        	DVector vTheirPos;
    		pServerDE->GetObjectPos(pLink->m_hObject, &vTheirPos);

            bVisible = DFALSE;
            
            if (bCheckVisible)
            {
            
                // Cast a ray for each sholder (left and right side of dims)
                
            	IntersectQuery IQuery;
            	IntersectInfo IInfo;

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

            	if (pServerDE->IntersectSegment(&IQuery, &IInfo))
            	{
            		// BUGBUG: If the object is partially occluded it might fail this test!
            		if (IInfo.m_hObject == pLink->m_hObject)
        	    	{
                        bVisible = DTRUE;        
            		}
            	}
                else
                {
                    // Line of sight to the object is clear...
                    bVisible = DTRUE;
                }
            
                // If only looking for Visible objects and We found one NOT visible Break to next one.
                if (bVisible == DFALSE)
                {
                    break;
                }
                
            }
            
            
    		fObjDist = VEC_DIST(vPos, vTheirPos);

            // Smell Path Points
            if ( _mbsncmp((const unsigned char*)pServerDE->GetObjectName(pLink->m_hObject), (const unsigned char*)"SMELL", _mbstrlen("SMELL") ) == 0 ) 
            {
                PathPoint *pSmell = (PathPoint*)pServerDE->HandleToObject(pLink->m_hObject);
                fObjTime = pSmell->m_fStartTime;

                if (fSaveTime == 0)
                {
                    fSaveTime = fObjTime;
                    hIdealObj = pLink->m_hObject;
                }
                else
                {
                    if (fObjTime > fSaveTime)
                    {
                        fSaveTime = fObjTime;
                        hIdealObj = pLink->m_hObject;
                    }
                }
            
            }
            else
            {
            
                // NON Smell Objects
                if (fSaveDist == 0)
                {
                    fSaveDist = fObjDist;
                    hIdealObj = pLink->m_hObject;
                }
                else
                {
                    // check to see if we are the nearest or NOT
                    if (bNear)
                    {
                        if (fObjDist < fSaveDist)
                        {
                            fSaveDist = fObjDist;
                            hIdealObj = pLink->m_hObject;
                        }
                    }
                    else
                    {
                    // check for far
                        if (fObjDist > fSaveDist)
                        {
                            fSaveDist = fObjDist;
                            hIdealObj = pLink->m_hObject;
                        }
                    
                    }    
                }
                
            }        
            
            
		}

        // Next object
		pLink = pLink->m_pNext;
	}

    // clean up	
	pServerDE->RelinquishList(pTargets);

    // return the closest object found (DNULL of nothing found)
    return hIdealObj;

}




// ----------------------------------------------------------------------- //
//
//	ROUTINE:  AI_Shared::
//
//	PURPOSE:  
//
// ----------------------------------------------------------------------- //
DBOOL AI_Shared::CheckForProjectile(HOBJECT m_hObject)
{

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

    HOBJECT hFoundObj = DNULL;
    
    // Get AI's current Position
	DVector vPos;
	pServerDE->GetObjectPos(m_hObject, &vPos);

    // Create a List of objects within the Radius
	ObjectList* pTargets = pServerDE->FindObjectsTouchingSphere(&vPos, 250);
	if (!pTargets || pTargets->m_nInList <= 0) return DNULL;

    // Found all the Objects
	ObjectLink *pLink = pTargets->m_pFirstLink;
	while(pLink && pLink->m_hObject)
	{
		HCLASS hType = pServerDE->GetObjectClass(pLink->m_hObject);
        
		if(pServerDE->IsKindOf(hType, pServerDE->GetClass("CGrenade")))
		{
            hFoundObj = pLink->m_hObject;        
            break;
        }        
//        else if(pServerDE->IsKindOf(hType, pServerDE->GetClass("CMissileProjectile")))
//		{
//            hFoundObj = pLink->m_hObject;        
//            break;
//        }        
//        else if(pServerDE->IsKindOf(hType, pServerDE->GetClass("CPulseProjectile")))
//		{
//            hFoundObj = pLink->m_hObject;        
//            break;
//        }        
//        else if(pServerDE->IsKindOf(hType, pServerDE->GetClass("CEnergyProjectile")))
//		{
//            hFoundObj = pLink->m_hObject;        
//            break;
//        }        
//        else if(pServerDE->IsKindOf(hType, pServerDE->GetClass("CFlareProjectile")))
//		{
//            hFoundObj = pLink->m_hObject;        
//            break;
//        }        
//        else if(pServerDE->IsKindOf(hType, pServerDE->GetClass("CDeadlyDiscProj")))
//		{
//            hFoundObj = pLink->m_hObject;        
//            break;
//        }        
        
        
        // Next object
		pLink = pLink->m_pNext;
	}

    // clean up	
	pServerDE->RelinquishList(pTargets);


    if (hFoundObj)
    {
        return DTRUE;
    }

    return DFALSE;

}



// ----------------------------------------------------------------------- //
//
//	ROUTINE:  AI_Shared::
//
//	PURPOSE:  
//
// ----------------------------------------------------------------------- //
void AI_Shared::FacePosition(HOBJECT m_hObject, DVector vTargetPos)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject) return;

	DVector vDir, vPos;
    
    // Our current position	
	pServerDE->GetObjectPos(m_hObject, &vPos);

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

	DRotation rRot;
	ROT_INIT(rRot);
    
	pServerDE->GetObjectRotation(m_hObject, &rRot);

	// m_Angles.y = ATan2(vDir.x, vDir.z);
	DFLOAT fAmount = (DFLOAT) atan2(vDir.x, vDir.z);
    
	DVector vU, vR, vF;
	pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);

	DFLOAT fAmount2 = (DFLOAT) atan2(vF.x, vF.z);
    
	pServerDE->EulerRotateY(&rRot, fAmount2 - fAmount);
	pServerDE->SetObjectRotation(m_hObject, &rRot);
}





// ----------------------------------------------------------------------- //
//
//	ROUTINE:  AI_Shared::
//
//	PURPOSE:  
// Aim Up/down
//
// ----------------------------------------------------------------------- //
DFLOAT AI_Shared::PitchToObject(HOBJECT m_hObject, HOBJECT hPTarget)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject || !hPTarget) return 0;

⌨️ 快捷键说明

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