📄 ai_mgr.cpp
字号:
// Don't let y be a factor...
vTargetPos.y = vPos.y;
MC_FacePos(vTargetPos);
DFLOAT fSpeed = m_fWalkSpeed;
if (m_eScriptMovement == SM_RUN)
{
fSpeed = m_fRunSpeed;
}
DFLOAT fDistLeft = VEC_DIST(vTargetPos, vPos);
DFLOAT fDistPredict = m_pServerDE->GetFrameTime() * fSpeed;
if (fDistLeft <= fDistPredict * 2.0f)
{
// Move to the position for completeness
if(!m_nTrapped)
m_pServerDE->MoveObject(m_hObject, &vTargetPos);
// Check for Target and messages from this pathpoint...
if (pCurKey->m_hstrActionMessage)
{
// If there is a target, use that. If not, send to myself.
if (pCurKey->m_hstrActionTarget)
{
SendTriggerMsgToObjects(this,
pCurKey->m_hstrActionTarget,
pCurKey->m_hstrActionMessage);
}
else
{
HMESSAGEWRITE hMessage;
hMessage = m_pServerDE->StartMessageToObject(this, m_hObject, MID_TRIGGER);
m_pServerDE->WriteToMessageHString(hMessage, pCurKey->m_hstrActionMessage);
m_pServerDE->EndMessage(hMessage);
}
}
// Remove it from the pathpoint list
m_AIPathList.Remove(0);
}
else
{
DBOOL bOkToMove = DTRUE;
if (m_dwScriptFlags & AI_SCRFLG_OPPORTFIRE)
{
bOkToMove = !Script_Fire_Stand();
}
if (bOkToMove)
{
if (m_eScriptMovement == SM_RUN)
{
Script_Run();
}
else
{
Script_Walk();
}
}
}
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetMoveToObjectCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::SetMoveToObjectCmd()
{
char *pTargetName = m_curScriptCmd.args;
ObjectList* pList = m_pServerDE->FindNamedObjects(pTargetName);
if (!pList) return;
ObjectLink* pLink = pList->m_pFirstLink;
if (pLink)
{
SetNewTarget(pLink->m_hObject);
}
else
{
m_bUpdateScriptCmd = DTRUE;
}
m_pServerDE->RelinquishList(pList);
Metacmd = 1;
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::UpdateMoveToObjectCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::UpdateMoveToObjectCmd()
{
// Face where we are going...
if (!m_hTarget)
{
m_bUpdateScriptCmd = DTRUE;
return;
}
DVector vTargetPos;
m_pServerDE->GetObjectPos(m_hTarget, &vTargetPos);
DVector vPos;
VEC_COPY(vPos, m_MoveObj.GetPos());
// Don't let y be a factor...
vTargetPos.y = vPos.y;
switch(Metacmd)
{
case 1:
{
m_MoveObj.CalculatePath(vTargetPos);
Metacmd++;
}
break;
case 2:
{
MC_FacePos(*m_MoveObj.GetNextPathPoint());
}
break;
case 3:
{
DFLOAT fSpeed = m_fWalkSpeed;
if (m_eScriptMovement == SM_RUN)
{
fSpeed = m_fRunSpeed;
}
DFLOAT fDistLeft = VEC_DIST(*m_MoveObj.GetNextPathPoint(), vPos);
DFLOAT fDistPredict = m_pServerDE->GetFrameTime() * fSpeed;
if (fDistLeft <= fDistPredict * 2.0f)
{
if (!m_MoveObj.MoveToNextPathPoint())
{
Metacmd++;
}
else
{
Metacmd = 2;
}
}
else
{
if (m_eScriptMovement == SM_RUN)
{
if (m_dwScriptFlags & AI_SCRFLG_OPPORTFIRE)
{
Script_Fire_Run();
}
else
{
Script_Run();
}
}
else
{
if (m_dwScriptFlags & AI_SCRFLG_OPPORTFIRE)
{
Script_Fire_Walk();
}
else
{
Script_Walk();
}
}
Metacmd = 2;
}
}
break;
case 4:
{
// Move to the position for completeness
if(!m_nTrapped)
m_pServerDE->MoveObject(m_hObject, &vTargetPos);
m_bUpdateScriptCmd = DTRUE;
}
break;
}
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetPlaysoundCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::SetPlaysoundCmd()
{
char* pSoundName = m_curScriptCmd.args;
if (pSoundName)
{
PlaySoundFromObject( m_hObject, pSoundName, 5000.0f, SOUNDPRIORITY_MISC_HIGH, DFALSE, DFALSE, DFALSE );
}
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetSetStateCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::SetSetStateCmd()
{
SetNewState(StateStrToInt(m_curScriptCmd.args));
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetTargetCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::SetTargetCmd()
{
SetTarget(m_curScriptCmd.args);
SetNewState(STATE_AttackFar);
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetWaitCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::SetWaitCmd()
{
m_fScriptWaitEnd = m_pServerDE->GetTime() + atoi(m_curScriptCmd.args);
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::UpdateWaitCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::UpdateWaitCmd()
{
if (m_pServerDE->GetTime() >= m_fScriptWaitEnd)
{
m_bUpdateScriptCmd = DTRUE;
}
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetPlayAnimationCmd
// DESCRIPTION :
// RETURN TYPE : void
// PARAMS : DBOOL bLooping - Animation should be played looping.
// ----------------------------------------------------------------------- //
void AI_Mgr::SetPlayAnimationCmd(DBOOL bLooping)
{
DDWORD dwIndex = m_pServerDE->GetAnimIndex(m_hObject, m_curScriptCmd.args);
m_pServerDE->SetModelLooping(m_hObject, bLooping);
// m_pServerDE->SetModelAnimation(m_hObject, dwIndex);
SetAnimation(dwIndex);
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::UpdatePlayAnimationCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::UpdatePlayAnimationCmd()
{
DDWORD dwState = m_pServerDE->GetModelPlaybackState(m_hObject);
if ((dwState & MS_PLAYDONE))
{
m_bUpdateScriptCmd = DTRUE;
}
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::FacePos
// DESCRIPTION :
// RETURN TYPE : void
// PARAMS : DVector vTargetPos
// ----------------------------------------------------------------------- //
void AI_Mgr::FacePos(DVector vTargetPos)
{
DVector vDir, vPos;
// GJK 7/29/98 - Made this puppy much simpler. More importantly, it works now.
m_pServerDE->GetObjectPos(m_hObject, &vPos);
vTargetPos.y = vPos.y; // Don't look up/down.
VEC_SUB(vDir, vTargetPos, vPos);
VEC_NORM(vDir);
DRotation rRot;
m_pServerDE->AlignRotation(&rRot, &vDir, NULL);
m_pServerDE->SetObjectRotation(m_hObject, &rRot);
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::HandleDamage
// DESCRIPTION : Handle MID_DAMAGE messages
// RETURN TYPE : void
// PARAMS : HOBJECT hSender
// PARAMS : DDWORD messageID
// PARAMS : HMESSAGEREAD hRead
// ----------------------------------------------------------------------- //
DBOOL AI_Mgr::HandleDamage()
{
if(m_nState == STATE_Dying || m_bRemoveMe)
return DTRUE;
//should we limp?
int nNodeHit = m_damage.GetNodeHit();
//didn't hit so return
if(nNodeHit == -1)
return DTRUE;
int nType = m_damage.GetLastDamageType();
DFLOAT fDamage = m_damage.GetLastDamageAmount();
DVector vDir;
m_damage.GetLastDamageDirection(&vDir);
if(m_dwFlags & FLAG_LIMP && m_nInjuredLeg == 0 &&
(nNodeHit == NODE_LLEG || nNodeHit == NODE_RLEG))
{
if(m_damage.GetHitPoints() < (m_damage.GetMaxHitPoints() * 0.5f))
{
m_nInjuredLeg = nNodeHit;
}
}
//SCHLEGZ 3/10/98 12:44:32 AM: check for limb loss
if (m_damage.GetHitPoints() <= 0.0f)
{
if(m_bCabal)
m_InventoryMgr.DropCurrentWeapon(); //SCHLEGZ 4/26/98 10:14:32 PM: i'm dead; no need for weapon
//see what we are standing on
CollisionInfo collisionInfo;
m_pServerDE->GetStandingOn(m_hObject, &collisionInfo);
if(collisionInfo.m_hObject && (collisionInfo.m_hObject != m_pServerDE->GetWorldObject()))
{
DDWORD dwFlags = m_pServerDE->GetObjectFlags(collisionInfo.m_hObject);
if(!(dwFlags & FLAG_SOLID))
{
m_dwFlags |= FLAG_ALWAYSGIB;
}
}
//do we need to start the barbecue?
if(nType == DAMAGE_TYPE_FIRE && !(m_dwFlags & FLAG_ALWAYSGIB))
{
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
ocStruct.m_ObjectType = OT_NORMAL;
ocStruct.m_NextUpdate = 0.01f;
m_pServerDE->GetModelNodeTransform(m_hObject, "torso",&ocStruct.m_Pos,&ocStruct.m_Rotation);
ocStruct.m_Flags = FLAG_FORCECLIENTUPDATE;
HCLASS hClass = m_pServerDE->GetClass("BaseClass");
BaseClass* pObj = m_pServerDE->CreateObject(hClass, &ocStruct);
if(pObj)
{
m_hFireSource = pObj->m_hObject;
}
}
else if((nType == DAMAGE_TYPE_EXPLODE || m_dwFlags & FLAG_ALWAYSGIB) && !(m_dwFlags & FLAG_NEVERGIB))
{
CreateGibs(vDir, ((int)m_damage.GetMass())>>5, nType, fDamage);
m_bRemoveMe = DTRUE;
if (IsRandomChance(7) && (m_damage.GetWhoKilledMeLast() == g_pPlayerObj->m_hObject))
{
g_pPlayerObj->PlayVoiceGroupEventOnClient(VME_BIGGIB, DTRUE); // [blg]
}
}
else if((m_damage.GetLastDamagePercent() >= 0.90f) && !(m_dwFlags & FLAG_NEVERGIB))
{
CreateGibs(vDir, ((int)m_damage.GetMass())>>5, nType, fDamage);
m_bRemoveMe = DTRUE;
if (IsRandomChance(7) && (m_damage.GetWhoKilledMeLast() == g_pPlayerObj->m_hObject))
{
g_pPlayerObj->PlayVoiceGroupEventOnClient(VME_BIGGIB, DTRUE); // [blg]
}
}
/* else if(nNodeHit > 0 && m_damage.GetLastDamagePercent() >= 0.25f) // 10% of the time, blow off the head. 25% for other limbs
{
if(AIShared.HideLimb(m_hObject,nNodeHit) && (m_dwFlags & FLAG_LIMBLOSS))
{
AIShared.CreateLimb(m_hObject, nNodeHit, vDir);
}
}
*/
if (IsRandomChance(6) && (m_damage.GetWhoKilledMeLast() == g_pPlayerObj->m_hObject))
{
g_pPlayerObj->PlayVoiceGroupEventOnClient(VME_KILL, DTRUE); // [blg]
}
}
if (m_nState == STATE_Script)
{
if(!(m_dwScriptFlags & AI_SCRFLG_INT))
return DTRUE;
}
if(m_dwFlags & FLAG_ALWAYSRECOIL)
SetNewState(STATE_Recoil);
else if(fDamage >= m_damage.GetHitPoints() * 0.25f && m_nState != STATE_Teleport && m_nState != STATE_Dodge)
SetNewState(STATE_Recoil);
else if(m_nState != STATE_AttackClose && m_nState != STATE_AttackFar)
ComputeState();
return DTRUE;
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetNewState
// DESCRIPTION : Set new state and reset metacmd
// RETURN TYPE : void
// PARAMS : int nState
// ----------------------------------------------------------------------- //
void AI_Mgr::SetNewState(int nState)
{
float fTime;
if(m_nState != STATE_WalkAroundObj && m_nState != STATE_RunAroundObj
&& m_nState != STATE_JumpOverObj && m_nState != STATE_CrawlUnderObj
&& m_nState != STATE_SearchVisualTarget && m_nState != STATE_SearchSmellTarget)
{
if(m_nLastState != m_nState)
m_nLastState = m_nState;
}
fTime = g_pServerDE->GetTime( );
// Don't switch to the idle state too fast
if( nState == STATE_Idle && m_bHasTargeted )
{
if( fTime > m_fWaitForIdleTime )
m_nState = nState;
else
m_nState = STATE_SearchVisualTarget;
}
else
{
m_nState = nState;
m_fWaitForIdleTime = fTime + WAITFORIDLETIME;
}
Metacmd = 1;
m_nCurMetacmd = 999;
m_bAnimating = DFALSE;
StopVelocity();
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -