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

📄 defenseglobeai.cpp

📁 Blood 2全套源码
💻 CPP
字号:
// ----------------------------------------------------------------------- //
//
// MODULE  : DefenseGlobeAI.cpp
//
// PURPOSE : DefenseGlobe AI
//
// CREATED : 12/01/97   
//
// ----------------------------------------------------------------------- //

// 9.4.4 Defense Globe

// This small device is activates a few seconds after dropped.  
// It sits stationary on turrets and rotates around, looking for targets.  
// Once it finds a target it unleashes its Pulse Cannon at them.  It only carries 50
// rounds, but will stay active until it is destroyed or all those rounds are gone. 
// Once it is out of ammo it harmlessly self-destructs.

// has Hit points.
// Will attack everything around it, even the player that droped it!

// 01/05/98 UPDATE

// 1.1.1 Defense Globe

// This small device is activates a few seconds after dropped.  It sits stationary on turrets
// and rotates around, looking for targets.  Once it finds a target it unleashes its Pulse Cannon
// at them.  It only carries 50 rounds, but will stay active until it is destroyed or all those
// rounds are gone.  Once it is out of ammo it harmlessly self-destructs.  In single player, once
// this item is dropped it is lost, as it will target the player as well.  In multi-player when
// the weapon runs out of ammo or is destroyed it will return to the player's inventory.  This item
// has 50 health, and can be destroyed.


#include "DefenseGlobeAI.h"
#include "cpp_server_de.h"


//BEGIN_CLASS(CPlayerObj)
//END_CLASS_DEFAULT(CPlayerObj, CBaseCharacter, NULL, NULL)

BEGIN_CLASS(DefenseGlobeAI)
	ADD_BASEAI_AGGREGATE()                  \
    ADD_REALPROP(SightDistance, 400.0f)     \
    ADD_REALPROP(SenseDistance, 250.0f)     \
    ADD_REALPROP(SmellDistance, 0.0f)       \
    ADD_REALPROP(ListenDistance, 0.0f)      \
    ADD_REALPROP(Mass, 17.0f)               \
    ADD_REALPROP(HitPoints, 100.0f)         \
    ADD_REALPROP(RandomHitPoints, 50.0f)    \
    ADD_REALPROP(ArmorPoints, 0.0f)         \
	ADD_STRINGPROP(AIState, "IDLE")       \
	ADD_STRINGPROP(AIBrain, "STRONG")       \
	ADD_STRINGPROP(AIWeapon, "PULSE")       \
END_CLASS_DEFAULT(DefenseGlobeAI, CBaseCharacter, NULL, NULL)
//END_CLASS_DEFAULT_FLAGS(DefenseGlobeAI, CBaseCharacter, NULL, NULL, CF_HIDDEN)



// ----------------------------------------------------------------------- //
//
//	ROUTINE:	
//
//	PURPOSE:	Constructor
//
// ----------------------------------------------------------------------- //

DefenseGlobeAI::DefenseGlobeAI() : CBaseCharacter(OT_MODEL)
{
	AddAggregate(&m_ai);

	_mbscpy((unsigned char*)m_szAIState, (const unsigned char*)"");
  	_mbscpy((unsigned char*)m_szAIBrain, (const unsigned char*)"");
  	_mbscpy((unsigned char*)m_szAIWeapon[0], (const unsigned char*)"");
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	EngineMessageFn
//
//	PURPOSE:	Handle engine messages
//
// ----------------------------------------------------------------------- //

DDWORD DefenseGlobeAI::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
	switch(messageID)
	{
		case MID_PRECREATE:
		{
			// Need to call base class to have the object name read in before
			// we call PostPropRead()

			DDWORD dwRet = B2BaseClass::EngineMessageFn(messageID, pData, fData);

			if (fData == 1.0)
				AIReadProp((ObjectCreateStruct*)pData);  // inside BaseCharacter

			PostPropRead((ObjectCreateStruct*)pData);

			return dwRet;
		}
		break;
        
		case MID_INITIALUPDATE:
		{
			InitialUpdate((DVector *)pData);
			break;
		}

		default : break;
	}


	return CBaseCharacter::EngineMessageFn(messageID, pData, fData);
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	PostPropRead()
//
//	PURPOSE:	Update properties
//
// ----------------------------------------------------------------------- //

void DefenseGlobeAI::PostPropRead(ObjectCreateStruct *pStruct)
{
	if (!pStruct) return;

	char* pFilename = "Models\\Enemies\\def_top.abc";
	char* pSkin = "Skins\\Enemies\\def_top.dtx";
	_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)pFilename);
	_mbscpy((unsigned char*)pStruct->m_SkinName, (const unsigned char*)pSkin);

//	pStruct->m_Flags = FLAG_VISIBLE | FLAG_SOLID | FLAG_GRAVITY | FLAG_STAIRSTEP | FLAG_SHADOW;	
	pStruct->m_Flags = FLAG_VISIBLE | FLAG_GRAVITY | FLAG_STAIRSTEP | FLAG_SHADOW;	


}




// ----------------------------------------------------------------------- //
//
//	ROUTINE:	InitialUpdate()
//
//	PURPOSE:	Handle initial update
//
// ----------------------------------------------------------------------- //

DBOOL DefenseGlobeAI::InitialUpdate(DVector *pMovement)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return DFALSE;

// Create the Legs
    ObjectCreateStruct theStruct;
	INIT_OBJECTCREATESTRUCT(theStruct);
    
	DRotation rRot;
    ROT_INIT(rRot);
    
	DVector vPos;
    pServerDE->GetObjectPos(m_hObject, &vPos);
    
    ROT_COPY(theStruct.m_Rotation, rRot);
	VEC_COPY(theStruct.m_Pos, vPos);
    
	theStruct.m_NextUpdate = 0.1f;
	pServerDE->CreateObject(pServerDE->GetClass("DefenseGlobeLegs"), &theStruct);
    

    // set the friction for object    
	pServerDE->SetFrictionCoefficient(m_hObject, 18.0);

    // Init the objects
	m_InventoryMgr.Init(m_hObject);
	m_ai.Init(m_hObject, &m_damage, &m_InventoryMgr, &m_Anim_Sound, m_szAIState, m_szAIBrain, m_szAIWeapon[0]);

    m_ai.SetListenDistance(m_fAIListenDistance);
    m_ai.SetSightDistance( m_fAISightDistance);
    m_ai.SetSenseDistance( m_fAISenseDistance);
    m_ai.SetSmellDistance( m_fAISmellDistance);
    
    
	m_damage.SetHitPoints(m_fAIHitPoints);
	m_damage.SetMaxHitPoints(100.0f);

	m_damage.SetArmorPoints(m_fAIArmorPoints);
	m_damage.SetMaxArmorPoints(200.0f);
	m_damage.SetMass(m_fAIMass);

	m_ai.SetWalkSpeed(1.8f);
	m_ai.SetRunSpeed(4.0f);

    m_Anim_Sound.SetAnimationIndexes(m_hObject);
   
	m_ai.SetDeathAniLength(5.0f);

	// Set the dims...
	DVector vDims;
// will cause problems with this small...    
//	VEC_SET(vDims, 10, 12, 10);
//  10,12,10  never hits??
//  10,15,10  sometimes it hits...

	VEC_SET(vDims, 2, 2, 2);
	pServerDE->SetObjectDims(m_hObject, &vDims);

	return DTRUE;
}



// -----------------------------------------------------------------------------------
//
// AI_DefenseGlobe
//
// -----------------------------------------------------------------------------------

/*
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_STATE_WaitForEnemy
//
//	PURPOSE:	Idle, wait for enemy
//
// ----------------------------------------------------------------------- //
void AI_DefenseGlobe::AI_STATE_WaitForEnemy()
{

//
// Set the SubState
//
    if (m_nSubState == SS_EMPTY)
    {
        LoopCheck++;
        switch(LoopCheck)
        {
            case 1: if(AI_CheckSeeEnemy()) m_nSubState = SS_SEE_ENEMY; break;        
            default: 
            {   LoopCheck = 0; 
                if(AI_CheckSenseEnemy()) m_nSubState = SS_SENSE_ENEMY; 
            } break;
        }
    }

    if (m_nSubState == SS_EMPTY)   m_nSubState = SS_DEFAULT;


//
// Execute the SubState Meta commands
//
    switch(m_nSubState)
    {
        
        case SS_SEE_ENEMY:
        case SS_SENSE_ENEMY:
        {
            switch(Metacmd)
            {
                case 1: MC_Facetarget();  break;
                case 2: NewState(STATE_AttackEnemy,0,0,0,0); break;
            }                
        } break;
        
        // Make the SS_DEFAULT the default
        default:
        {
            switch(Metacmd)
            {
                case 1: MC_Idle();  break;
                case 2: NewState(STATE_WaitForEnemy,0,0,0,0); break;
            }                
        } break;
    
    }
    
}




// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_STATE_AttackEnemy
//
//	PURPOSE:	Attack the Enemy
//
// ----------------------------------------------------------------------- //
void AI_DefenseGlobe::AI_STATE_AttackEnemy()
{

//
// Set the SubState
//
    if (m_nSubState == SS_EMPTY)
    {
        // Always check each one...    
        if ( AI_CheckIsThereNoTarget() )            m_nSubState = SS_NO_TARGET; 
        else if ( AI_CheckIsTargetOutofSite() )     m_nSubState = SS_TARGET_OUTOSITE;
        else if ( AI_CheckIsTargetDead() )          m_nSubState = SS_TARGET_DEAD;
        else if ( AI_CheckIsTargetNearToHit() )     m_nSubState = SS_TARGET_IS_NEAR_TO_HIT;
        
    }

    if (m_nSubState == SS_EMPTY)   m_nSubState = SS_DEFAULT;
            
            
//
// Execute the SubState Meta commands
//
    switch(m_nSubState)
    {
    
        case SS_NO_TARGET:
        {
            switch(Metacmd)
            {
                case 1: MC_Turnl();  break;
                case 2: MC_Turnr();  break;
                case 3: NewState(STATE_AttackEnemy,0,0,0,0); break;
            }                
        } break;
        
        
        case SS_TARGET_OUTOSITE:
        {
            switch(Metacmd)
            {
                case 1: MC_Facetarget();    break;
                case 2: NewState(STATE_AttackEnemy,0,0,0,0); break;
            }                
        } break;
        

        case SS_TARGET_DEAD:
        {
            switch(Metacmd)
            {
                case 1: MC_Facetarget();    break;
                case 2: NewState(STATE_WaitForEnemy,0,0,0,0); break;    // reset the SubState to 0 & Metacmd to 1
            }                
        } break;


        case SS_TARGET_IS_NEAR_TO_HIT:
        {
            switch(Metacmd)
            {
                case 1: MC_Facetarget();    break;
                case 2: MC_Dg_shot_target();   break;
                case 3: NewState(STATE_AttackEnemy,0,0,0,0); break;
            }                
        } break;

        // Make the SS_DEFAULT the default
        default:
        {
            switch(Metacmd)
            {
                case 1: MC_Turnr();  break;
                case 2: MC_Delay33();  break;
                case 3: MC_Facetarget();  break;
                case 4: MC_Turnr();  break;
                case 5: MC_Turnl();  break;
                case 6: NewState(STATE_AttackEnemy,0,0,0,0); break;
            }                
        } break;
        
    }
    
}





// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AI_STATE_Dying
//
//	PURPOSE:	Dying
//
// ----------------------------------------------------------------------- //
void AI_DefenseGlobe::AI_STATE_Dying()
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject ) return;
     
//
// Set the SubState
//
    if (m_nSubState == SS_EMPTY)
    {
        b_Animating = DFALSE; 
   	    m_Condition = DEAD;
        m_nSubState = SS_DIE_GIB;
    }

            
//
// Execute the SubState Meta commands
//
    switch(m_nSubState)
    {

        case SS_DIE_GIB:
        {
            switch(Metacmd)
            {
                case 1: MC_Deadgib();  break;
                case 2: NewState(STATE_Inactive,0,0,0,0); break;
            }                
        } break;

    }
         
}

*/

⌨️ 快捷键说明

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