📄 zealotai.cpp
字号:
//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 + -