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

📄 zealotai.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

		//SCHLEGZ 4/22/98 3:27:12 PM: if we can't stand up, crawl out from underneath
		if(!bRet)
		{
			SetNewState(STATE_CrawlUnderObj);
			return;
		}

        m_pServerDE->SetModelLooping(m_hObject, DFALSE);

		//create the spellcasting effect
		ObjectCreateStruct ocStruct;
		INIT_OBJECTCREATESTRUCT(ocStruct);

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

		m_bStartStaffEffect = DTRUE;
        
		m_bAnimating = DTRUE; 
		m_nCurMetacmd = MC_FIRE_STAND;
    }
    else
	{
		if(m_bStartStaffEffect)
		{
			DVector		offset;
			VEC_SET(offset, 0.0f, 0.0f, 0.0f);

			HMESSAGEWRITE hMessage = m_pServerDE->StartInstantSpecialEffectMessage(&offset);
			m_pServerDE->WriteToMessageByte(hMessage, SFX_OBJECTFX_ID);
			m_pServerDE->WriteToMessageObject(hMessage, m_hStaffEffect);
			m_pServerDE->WriteToMessageVector(hMessage, &offset);
			m_pServerDE->WriteToMessageFloat(hMessage, 2.0f);
			m_pServerDE->WriteToMessageDWord(hMessage, OBJFX_SCALENUMPARTICLES);

			if(m_bDivine)
				m_pServerDE->WriteToMessageDWord(hMessage, OBJFX_FIRETRAIL_1);
			else
				m_pServerDE->WriteToMessageDWord(hMessage, OBJFX_FIRETRAIL_2);

			m_pServerDE->WriteToMessageDWord(hMessage, 0);
			m_pServerDE->EndMessage(hMessage);

			DRotation rRot;
			ROT_INIT(rRot);
			m_pServerDE->CreateAttachment(m_hObject, m_hStaffEffect, "r_hand_extra2", &offset, &rRot, &m_hAttach);

			m_bStartStaffEffect = DFALSE;
		}

		if(m_pServerDE->GetModelPlaybackState(m_hObject) & MS_PLAYDONE)		
		{
			m_pServerDE->RemoveAttachment(m_hAttach);
			m_pServerDE->RemoveObject(m_hStaffEffect);

			m_hAttach = DNULL;
			m_hStaffEffect = DNULL;

			m_bAnimating = DFALSE;
			Metacmd++;
			return;
		}
    }      
	
    return;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: ZealotAI::MC_Dead
// DESCRIPTION	: Run death animation based on node hit
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void ZealotAI::MC_Dead()
{
    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_DEAD)
    {		
		DVector vVel, vColor;
		DFLOAT fAlpha = 0.0f;

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

        SetAnimation(m_pAnim_Sound->m_nAnim_DEATH[0]);

		VEC_MULSCALAR(vVel, m_MoveObj.GetUpVector(), 30.0f);

		//turn off gravity
		DDWORD dwFlags = m_pServerDE->GetObjectFlags(m_hObject);
		dwFlags &= ~FLAG_GRAVITY;
		m_pServerDE->SetObjectFlags(m_hObject, dwFlags);

		Move(vVel, MATH_EPSILON);

		m_pServerDE->SetModelLooping(m_hObject, DFALSE);

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

			char* szSound = "sounds\\enemies\\zealot\\magic.wav";
			PlaySoundFromObject(m_hObject, szSound, 2000.0f, SOUNDPRIORITY_MISC_MEDIUM, 
								DFALSE, DTRUE, DTRUE);

			DDWORD nType = 0;
			
			if(!m_bDivine)
				nType = EXP_SHOCKBALL;
			else
				nType = EXP_DIVINE_SHOCKBALL;

			DVector vPos, vNormal;

			VEC_COPY(vPos, m_MoveObj.GetPos());
			VEC_COPY(vNormal, m_MoveObj.GetUpVector());

			//********************************************************************
			// Create the explosion type
			HMESSAGEWRITE hMessage = m_pServerDE->StartInstantSpecialEffectMessage(&vPos);
			m_pServerDE->WriteToMessageByte(hMessage, SFX_EXPLOSIONFX_ID);

			m_pServerDE->WriteToMessageVector(hMessage, &vPos);
			m_pServerDE->WriteToMessageVector(hMessage, &vNormal);
			m_pServerDE->WriteToMessageDWord(hMessage, nType);

			m_pServerDE->EndMessage(hMessage);

			DFLOAT fDamage = (DFLOAT)m_pServerDE->IntRandom(25,50);
			DamageObjectsInRadius(m_hObject, this, m_MoveObj.GetPos(), LIFELEECH_PUSH_RADIUS,
								  fDamage, DAMAGE_TYPE_EXPLODE);

			if(m_hStaffEffect)
			{
				m_pServerDE->RemoveAttachment(m_hAttach);
				m_pServerDE->RemoveObject(m_hStaffEffect);

				m_hAttach = DNULL;
				m_hStaffEffect = DNULL;
			}

			RemoveMe();
		}
	}

	return;
}

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

void ZealotAI::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;
			case STATE_SearchSmellTarget:	SetNewState(STATE_Idle);			break;
			case STATE_Escape_RunAway:		SetNewState(STATE_Idle);			break;
			case STATE_Escape_Hide:			SetNewState(STATE_Idle);			break;
			default:						SetNewState(STATE_SearchVisualTarget);	break;
		}
	}
	else
	{
		if((m_fStimuli[HEALTH] < 0.5f) && (m_nState != STATE_Escape_Hide))
		{
			SetNewState(STATE_Escape_Hide);
			return;
		}

		if(m_fStimuli[SENSE] >= 0.85f)
			SetNewState(STATE_AttackClose);
		else
			SetNewState(STATE_AttackFar);
	}

	return;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: ZealotAI::AI_STATE_AttackClose
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void ZealotAI::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;
	}

	m_fStimuli[SENSE] = VEC_DIST(m_MoveObj.GetPos(),m_vTargetPos);

	switch(Metacmd)
	{
		case 1:		MC_FaceTarget();	break;	
		case 2:		if(m_fStimuli[SENSE] <= (m_fSensingDist * 0.10) && m_nCurMetacmd != MC_FIRE_STAND)
					{
						SetNewState(STATE_Teleport);
					}
					else
						Metacmd++;

					break;
		case 3:		MC_FaceTarget();
					Metacmd--;

					if(m_fStimuli[SENSE] >= (m_fSensingDist * 0.15) && m_nCurMetacmd != MC_FIRE_STAND)
						ComputeState();
					else
					{
						if(m_bFloat || m_nCurMetacmd == MC_FLOAT)
							MC_Float(DFALSE);
						else
							MC_Fire_Stand();
					}

					break;
		case 4:		ComputeState();		break;
	}

	return;
}

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

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

	m_fStimuli[SENSE] = VEC_DIST(m_MoveObj.GetPos(),m_vTargetPos);

	switch(Metacmd)
	{
		case 1:		MC_FaceTarget();	break;	
		case 2:		if(m_fStimuli[SENSE] > (m_fSensingDist * 0.75))
					{
						if(m_bFloat)
							MC_Run();
						else
							MC_Float(DTRUE);
					}
					else
						Metacmd++;

					break;
		case 3:		MC_FaceTarget();
					Metacmd--;

					if(m_fStimuli[SENSE] <= (m_fSensingDist * 0.75) || m_nCurMetacmd == MC_FIRE_STAND)
					{
						if(m_bFloat || m_nCurMetacmd == MC_FLOAT)
							MC_Float(DFALSE);
						else
							MC_Fire_Stand();
					}
					else
						Metacmd++;

					break;
		case 4:		ComputeState();		break;
	}

	return;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: ZealotAI::AI_STATE_Escape_Hide
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void ZealotAI::AI_STATE_Escape_Hide()
{
	switch(Metacmd)
	{
		case 1:		MC_Heal();			break;	
		case 2:		ComputeState();		break;
	}

	return;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: ZealotAI::AI_STATE_Teleport
// DESCRIPTION	: 
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void ZealotAI::AI_STATE_Teleport()
{
	switch(Metacmd)
	{
		case 1:		MC_FadeOut();		break;
		case 2:
		{
					char szSound[256];
					sprintf(szSound, "%s%d.wav", SOUND_LAUGH, m_pServerDE->IntRandom(1,3));
					m_pAnim_Sound->PlaySound(m_hObject, szSound, 2000.0f, 100);					

					Metacmd++;			break;
		}
		case 3:
		{
					IntersectQuery IQuery;
					IntersectInfo IInfo;

					IQuery.m_Flags	  = INTERSECT_OBJECTS;
					IQuery.m_FilterFn = DNULL;

					DVector vDir;
					VEC_SET(vDir, m_pServerDE->Random(-1.0f,1.0f), 0.0f, m_pServerDE->Random(-1.0f,1.0f));

					VEC_COPY(IQuery.m_From, m_MoveObj.GetPos());
					VEC_ADDSCALED(IQuery.m_To, IQuery.m_From, vDir, m_fSensingDist);

					if(m_pServerDE->IntersectSegment(&IQuery, &IInfo))
					{
						VEC_ADDSCALED(IInfo.m_Point, IInfo.m_Point, vDir, -100.0f);
						m_pServerDE->MoveObject(m_hObject, &IInfo.m_Point);
					}
					else
					{
						VEC_ADDSCALED(IInfo.m_Point, IQuery.m_To, vDir, -100.0f);
						m_pServerDE->MoveObject(m_hObject, &IQuery.m_To);
					}

					Metacmd++;
					break;
		}
		case 4:		
		{	
					DVector vColor;
					DFLOAT	fAlpha = 1.0f;

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

					DDWORD dwFlags = m_pServerDE->GetObjectFlags(m_hObject);
					dwFlags |= FLAG_SOLID;
					m_pServerDE->SetObjectFlags(m_hObject, dwFlags);

					Metacmd++;
					break;
		}
		case 5:		MC_FaceTarget();	break;
		case 6:		ComputeState();		break;
	}

	return;
}

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

	DBYTE val;

	val = m_bFloat | (m_bStartStaffEffect * 0x02) | (m_bDivine * 0x04);
	pServerDE->WriteToMessageByte(hWrite,val);
	pServerDE->WriteToMessageFloat(hWrite, m_fMaxHeight);
//	pServerDE->WriteToMessageObject(hWrite, m_hStaffEffect);
}

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

	DBYTE val;

	val = m_pServerDE->ReadFromMessageByte(hRead);
	m_bFloat = val & 0x01;
	m_bStartStaffEffect = ((val & 0x02) != 0);
	m_bDivine = ((val & 0x04) != 0);

	m_fMaxHeight = pServerDE->ReadFromMessageFloat(hRead);
//	m_hStaffEffect = pServerDE->ReadFromMessageObject(hRead);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CacheFiles
//
//	PURPOSE:	Cache resources used by the object
//
// ----------------------------------------------------------------------- //

void ZealotAI::CacheFiles()
{
	// Sanity checks...

	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;

	if(!(pServerDE->GetServerFlags() & SS_CACHING))
	{
		return;
	}

	if (!m_hObject) return;


	// Get the model filenames...

	char sModel[256] = { "" };
	char sSkin[256]  = { "" };

	pServerDE->GetModelFilenames(m_hObject, sModel, 255, sSkin, 255);


	// Cache models...

	pServerDE->CacheFile(FT_MODEL, sModel);


	// Cache textures...

	pServerDE->CacheFile(FT_TEXTURE, sSkin);


	// Cache sounds...

	SetCacheDirectory("sounds\\enemies\\zealot");

	CacheSoundFileRange("death", 1, 3);
	CacheSoundFileRange("anger", 1, 3);
	CacheSoundFileRange("fear", 1, 3);
	CacheSoundFileRange("idle", 1, 3);
	CacheSoundFileRange("laugh", 1, 3);
	CacheSoundFileRange("pain", 1, 3);
	CacheSoundFileRange("spot", 1, 3);

	CacheSoundFile("shield");
	CacheSoundFile("magic");
}


⌨️ 快捷键说明

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