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

📄 ancientonetentacle.cpp

📁 Blood 2全套源码
💻 CPP
字号:
// ----------------------------------------------------------------------- //
//
// MODULE  : AncientOneTentacle.cpp
//
// PURPOSE : Soul Drudge - Definition
//
// CREATED : 11/20/97
//
// ----------------------------------------------------------------------- //

#include <stdio.h>
#include "AncientOneTentacle.h"
#include "cpp_server_de.h"

BEGIN_CLASS(AncientOneTentacle)
	ADD_BASEAI_AGGREGATE()
	ADD_STRINGPROP(AIState, "IDLE")     \
END_CLASS_DEFAULT(AncientOneTentacle, AI_Mgr, NULL, NULL)

//static data member initialization
DBOOL		AncientOneTentacle::m_bLoadAnims = DTRUE;
CAnim_Sound	AncientOneTentacle::m_Anim_Sound;

#define TENTACLE_SCALE 2.5f

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

AncientOneTentacle::AncientOneTentacle() : AI_Mgr()
{
	m_fHearingDist	= 0.0f;
	m_fSensingDist	= 1000.0f;
	m_fSmellingDist	= 0.0f;
	m_fSeeingDist	= 2000.0f;

	m_fWalkSpeed	= 0.0f;
	m_fRunSpeed		= 0.0f;
	m_fRollSpeed	= 0.0f;

	m_fAIMass		= AI_DEFAULT_MASS;

	m_nAIStrength	= 5;

	_mbscpy((unsigned char*)m_szAIWeapon[0], (const unsigned char*)"ANCIENTONE_TENTACLE" );

	m_nState = STATE_Idle; 
	m_nLastState = STATE_Idle; 
	m_dwFlags = 0;

	m_bCabal = DFALSE;
	m_bMoveToGround = DTRUE;

	VEC_SET(m_vScale,TENTACLE_SCALE,TENTACLE_SCALE,TENTACLE_SCALE);

	// [blg]
	m_fAIHitPoints   = 200;
	m_fAIRandomHP    = 0;
	m_fAIArmorPoints = 0;

	m_fLastIdle = 0;
	m_fScaleBy = 1.0f;
	m_bHiding = DFALSE;

	_mbscpy((unsigned char*)m_szAIState, (const unsigned char*)"IDLE");

	m_damage.SetApplyDamagePhysics(DFALSE);
}


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

DDWORD AncientOneTentacle::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 = AI_Mgr::EngineMessageFn(messageID, pData, fData);

			PostPropRead((ObjectCreateStruct*)pData);

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

		case MID_SAVEOBJECT:
			Save((HMESSAGEWRITE)pData, (DDWORD)fData);
			break;

		case MID_LOADOBJECT:
			Load((HMESSAGEREAD)pData, (DDWORD)fData);
			break;

		default : break;
	}


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

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

void AncientOneTentacle::PostPropRead(ObjectCreateStruct *pStruct)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !pStruct) return;

	int iRand = pServerDE->IntRandom(1,4);

	sprintf(pStruct->m_Filename, "models\\enemies\\ancientone_t%d.abc", iRand);
	sprintf(pStruct->m_SkinName, "skins\\enemies\\ancientone.dtx");
}


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

DBOOL AncientOneTentacle::InitialUpdate(DVector *pMovement)
{
	m_pServerDE = BaseClass::GetServerDE();
	if (!m_pServerDE) return DFALSE;

	m_hObject = m_pServerDE->ObjectToHandle(this);
	if (!m_hObject) return DFALSE;

    if(m_bLoadAnims)
	{
	    m_Anim_Sound.SetAnimationIndexes(m_hObject);
		m_Anim_Sound.GenerateHitSpheres(m_hObject);
	    m_Anim_Sound.SetSoundRoot("sounds\\enemies\\AncientOneTentacle");	
		m_bLoadAnims = DFALSE;
	}

	AI_Mgr::InitStatics(&m_Anim_Sound);

	return DTRUE;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AncientOneTentacle::MC_Fire_Stand
// DESCRIPTION	: Run the fire_stand animation
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AncientOneTentacle::MC_Fire_Stand()
{
    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_FIRE_STAND)
    {
		DBOOL bRet = DFALSE;

		CWeapon *pW = m_InventoryMgr.GetCurrentWeapon();		
		if (pW)
		{
			m_fAttackLoadTime = pW->GetReloadTime();
		}

        bRet = SetAnimation( m_pAnim_Sound->m_nAnim_FIRE_STAND[TYPE_MELEE]);

		m_pServerDE->SetModelLooping(m_hObject, DFALSE);

		m_bAnimating = DTRUE; 
		m_nCurMetacmd = MC_FIRE_STAND;
    }
    else
    {   
		if(m_pServerDE->GetModelPlaybackState(m_hObject) & MS_PLAYDONE)
		{
			m_bAnimating = DFALSE;
			Metacmd++;
		}
    }      
	
    return;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AncientOneTentacle::ComputeState
// DESCRIPTION	: Compute actual substate
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AncientOneTentacle::ComputeState(int nStimType)
{
	int nStim = nStimType;

	if(nStimType == -1)
		nStim = ComputeStimuli();

	if(!nStim)
	{
		switch(m_nState)
		{
			case STATE_Idle:				SetNewState(STATE_Idle);				break;
			case STATE_SearchVisualTarget:	SetNewState(STATE_Idle);				break;
			default:						SetNewState(STATE_SearchVisualTarget);	break;
		}
	}
	else
	{
		DFLOAT fTemp = VEC_DIST(m_MoveObj.GetPos(),m_vTargetPos);

		if (fTemp <= 500.0f)
		{
			SetNewState(STATE_AttackClose);
		}
		else
		{
			SetNewState(STATE_Idle);
		}
	}

	return;
}

DDWORD AncientOneTentacle::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
	// We can't be damaged by the Ancient One
	if (messageID == MID_DAMAGE)
	{
		HCLASS hAncientOne = m_pServerDE->GetClass("AncientOne");
		HCLASS hClass = m_pServerDE->GetObjectClass(hSender);

		if (!m_pServerDE->IsKindOf(hClass,hAncientOne))
		{
			return AI_Mgr::ObjectMessageFn(hSender, messageID, hRead);			
		}
		else
		{
			return 0;
		}
	} else
	{
		return AI_Mgr::ObjectMessageFn(hSender, messageID, hRead);
	}
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AncientOneTentacle::AI_STATE_AttackFar
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AncientOneTentacle::AI_STATE_AttackClose()
{
	//SCHLEGZ 4/22/98 4:51:21 PM: sanity check
	if(m_hTarget == DNULL && m_nCurMetacmd != MC_FIRE_STAND)
	{
		SetNewState(STATE_SearchVisualTarget);
		return;
	}

	switch(Metacmd)
	{
		case 1:		MC_ScaleUp();		break;
		case 2:		MC_FaceTarget();	break;
		case 3:		m_fStimuli[SIGHT] = VEC_DIST(m_MoveObj.GetPos(),m_vTargetPos);
			
					if(m_fStimuli[SIGHT] <= 500.0f || m_nCurMetacmd == MC_FIRE_STAND)
						MC_Fire_Stand();
					else
						SetNewState(STATE_Idle);
					
					break;
		case 4:		ComputeState();									break;
		default:	ComputeState();									break;
	}

	return;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: AncientOneTentacle::AI_STATE_Idle
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void AncientOneTentacle::AI_STATE_Idle()
{
	int nStimType = ComputeStimuli();

	if(nStimType)
	{
		ComputeState(nStimType);
		return;
	}

	switch(Metacmd)
	{
		case 1:		MC_Idle();			break;
		case 2:		ComputeState();		break;
	}

	return;
}

void AncientOneTentacle::AI_STATE_Special1()
{
	switch(Metacmd)
	{
		case 1:
			MC_ScaleUp();
			break;

		case 2:
			m_bHiding = DFALSE;
			SetNewState(STATE_Idle);
			break;
	}
}

void AncientOneTentacle::MC_FadeIn()
{
    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_FADEIN)
    {        
		m_bAnimating = DTRUE; 
		m_nCurMetacmd = MC_FADEIN;

		DDWORD dwFlags = m_pServerDE->GetObjectFlags(m_hObject);
		dwFlags = dwFlags | FLAG_SOLID;
		m_pServerDE->SetObjectFlags(m_hObject,dwFlags);
    }
    else
	{
		DVector vColor;
		DFLOAT fAlpha = 0.0f;

		m_pServerDE->GetObjectColor(m_hObject,&vColor.x, &vColor.y, &vColor.z, &fAlpha);

		fAlpha += 1.0/64;
		if(fAlpha >= 1.0f)
			fAlpha = 1.0f;

		m_pServerDE->SetObjectColor(m_hObject,vColor.x,vColor.y,vColor.z, fAlpha);

		if(fAlpha >= 1.0f)
		{
			m_bAnimating = DFALSE;
			Metacmd++;
			return;
		}
    }      
	
    return;	
}


void AncientOneTentacle::AI_STATE_Special2()
{
	switch(Metacmd)
	{
		case 1:
			MC_ScaleDown();
			break;

		case 2:
			SetNewState(STATE_Special3);
			break;
	}
}

void AncientOneTentacle::AI_STATE_Special4()
{
	switch(Metacmd)
	{
		case 1:
			MC_ScaleDown();
			break;

		case 2:
			m_bHiding = DTRUE;
			SetNewState(STATE_Idle);
			break;
	}
}


void AncientOneTentacle::MC_FadeOut()
{
    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_FADEOUT)
    {        
		DDWORD dwFlags = m_pServerDE->GetObjectFlags(m_hObject);
		dwFlags &= ~FLAG_SOLID;
		m_pServerDE->SetObjectFlags(m_hObject,dwFlags);

		m_bAnimating = DTRUE; 
		m_nCurMetacmd = MC_FADEOUT;
    }
    else
	{
		DVector vColor;
		DFLOAT fAlpha = 1.0f;

		m_pServerDE->GetObjectColor(m_hObject,&vColor.x, &vColor.y, &vColor.z, &fAlpha);

		fAlpha -= 1.0/64;
		if(fAlpha <= 0.0f)
			fAlpha = 0.0f;

		m_pServerDE->SetObjectColor(m_hObject,vColor.x,vColor.y,vColor.z, fAlpha);

		if(fAlpha <= 0.0f)
		{
			m_bAnimating = DFALSE;
			Metacmd++;
			return;
		}
    }      
	
    return;	
}

void AncientOneTentacle::AI_STATE_Special3()
{
	switch(Metacmd)
	{
		case 1:
			if ((m_pServerDE->GetTime() - m_fTimeOfDeath) >= DEATH_DURATION)
				Metacmd++;
			break;

		case 2:
			SetNewState(STATE_Special1);
			break;
	}
}

void AncientOneTentacle::MC_ScaleDown()
{
    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_SCALEDOWN)
    {        
		DDWORD dwFlags = m_pServerDE->GetObjectFlags(m_hObject);
		dwFlags &= ~FLAG_SOLID;
		dwFlags = dwFlags | FLAG_GRAVITY;
		m_pServerDE->SetObjectFlags(m_hObject,dwFlags);

		m_fScaleBy = TENTACLE_SCALE;

		SetAnimation(m_pAnim_Sound->m_nAnim_IDLE[0]);
		m_pServerDE->SetModelLooping(m_hObject, DTRUE);
		m_bAnimating = DTRUE; 
		m_nCurMetacmd = MC_SCALEDOWN;
    }
    else
	{
		DVector vScale;
		DVector vDims;
		DVector vScaleBy;

		m_fScaleBy -= TENTACLE_SCALE/20.0f;

		if (m_fScaleBy <= 0.01f) m_fScaleBy = 0.01f;

		m_pServerDE->GetObjectScale(m_hObject,&vScale);
		m_pServerDE->GetModelAnimUserDims(m_hObject, &vDims, 0);

		VEC_SET(vScaleBy,m_fScaleBy,m_fScaleBy,m_fScaleBy);
		VEC_COPY(vScale,vScaleBy);
		VEC_MUL(vDims,vDims,vScale);

		m_pServerDE->ScaleObject(m_hObject,&vScale);
		m_pServerDE->SetObjectDims(m_hObject,&vDims);

		VEC_COPY(m_vScale,vScale);

		MoveObjectToGround(m_hObject);

		if(m_fScaleBy <= 0.01f)
		{
			Metacmd++;
			return;
		}
    }      
	
    return;	
}

void AncientOneTentacle::MC_ScaleUp()
{
    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_SCALEUP)
    {        
		m_bAnimating = DTRUE; 
		m_nCurMetacmd = MC_SCALEUP;
    }
    else
	{
		DVector vScale;
		DVector vDims;
		DVector vScaleBy;

		m_fScaleBy += TENTACLE_SCALE/20.0f;

		if (m_fScaleBy >= TENTACLE_SCALE) m_fScaleBy = TENTACLE_SCALE;

		m_pServerDE->GetObjectScale(m_hObject,&vScale);
		m_pServerDE->GetModelAnimUserDims(m_hObject, &vDims, 0);

		VEC_SET(vScaleBy,m_fScaleBy,m_fScaleBy,m_fScaleBy);
		VEC_COPY(vScale,vScaleBy);
		VEC_MUL(vDims,vDims,vScale);

		m_pServerDE->ScaleObject(m_hObject,&vScale);
		m_pServerDE->SetObjectDims(m_hObject,&vDims);

		VEC_COPY(m_vScale,vScale);

		DVector vPos;
		m_pServerDE->GetObjectPos(m_hObject, &vPos);
		vPos.y += 200;
		m_pServerDE->SetObjectPos(m_hObject, &vPos);

		MoveObjectToGround(m_hObject);

		if(m_fScaleBy >= TENTACLE_SCALE)
		{
			DDWORD dwFlags = m_pServerDE->GetObjectFlags(m_hObject);
			dwFlags = dwFlags | FLAG_SOLID | FLAG_GRAVITY;
			m_pServerDE->SetObjectFlags(m_hObject,dwFlags);
			SetAnimation(m_pAnim_Sound->m_nAnim_IDLE[0]);
			m_pServerDE->SetModelLooping(m_hObject, DTRUE);

			m_bAnimating = DTRUE;
			Metacmd++;
			return;
		}
    }      
	
    return;	
}


void AncientOneTentacle::MC_Dead()
{
	m_fTimeOfDeath = m_pServerDE->GetTime();
	m_damage.SetHitPoints(200.0f);
	SetNewState(STATE_Special2);
}

void AncientOneTentacle::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	pServerDE->WriteToMessageFloat(hWrite, m_fTimeOfDeath);
	pServerDE->WriteToMessageFloat(hWrite, m_fLastIdle);
	pServerDE->WriteToMessageFloat(hWrite, m_fScaleBy);
	pServerDE->WriteToMessageByte(hWrite, (DBYTE)m_bHiding);
}

void AncientOneTentacle::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	m_fTimeOfDeath = pServerDE->ReadFromMessageFloat(hRead);
	m_fLastIdle = pServerDE->ReadFromMessageFloat(hRead);
	m_fScaleBy = pServerDE->ReadFromMessageFloat(hRead);
	m_bHiding = (DBOOL)(pServerDE->ReadFromMessageByte(hRead));
}


void AncientOneTentacle::MC_Idle()
{
    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_IDLE)
    {
		DBOOL bRet = DFALSE;

		bRet = SetAnimation(m_pAnim_Sound->m_nAnim_IDLE[0]);
		m_pServerDE->SetModelLooping(m_hObject, DTRUE);

        m_bAnimating = DTRUE; 
		m_nCurMetacmd = MC_IDLE;
//		if (!m_bHiding) m_fLastIdle = m_pServerDE->GetTime();
	}
	else
	{
		/*
		if (((m_fLastIdle + 30.0f) >= m_pServerDE->GetTime()) && !m_bHiding)
		{
			SetNewState(STATE_Special4);
		}
		*/

		if(m_pServerDE->GetModelPlaybackState(m_hObject) & MS_PLAYDONE)
        {
            m_bAnimating = DFALSE;
            Metacmd++;
            return;
        }
	}

	return;
}

⌨️ 快捷键说明

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