📄 ai_mgr.cpp
字号:
}
CBaseCharacter::OnStringKey(pArgList);
return;
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::HandleTrigger
// DESCRIPTION : Handle MID_TRIGGER messages
// RETURN TYPE : DBOOL
// PARAMS : HOBJECT hSender
// PARAMS : HMESSAGEREAD hRead
// ----------------------------------------------------------------------- //
DBOOL AI_Mgr::HandleTrigger( HOBJECT hSender, HMESSAGEREAD hRead )
{
if (!m_hObject ) return DFALSE;
HSTRING hMsg = m_pServerDE->ReadFromMessageHString(hRead);
// char *pCommand = _strupr(m_pServerDE->GetStringData(hMsg));
char *pCommand = m_pServerDE->GetStringData(hMsg);
int nArgs;
char tokenSpace[64*20];
char *pTokens[64];
char *pCommandPos;
// got a plain trigger message, relay it..
if (_mbsicmp((const unsigned char*)TRIGGER, (const unsigned char*)pCommand) == 0 && m_hstrTriggerRelayTarget)
{
SendTriggerMsgToObjects(this, m_hstrTriggerRelayTarget, hMsg);
g_pServerDE->FreeString( hMsg );
return DTRUE;
}
DBOOL bContinue = DTRUE;
while (bContinue)
{
bContinue = m_pServerDE->Parse(pCommand, &pCommandPos, tokenSpace, pTokens, &nArgs);
// Okay, see if we can handle the message...
if(_mbsicmp((const unsigned char*)TRIGGER_SOUND, (const unsigned char*)pTokens[0]) == 0 && nArgs > 1)
{
if(hSender != m_hObject)
{
if(m_nState == STATE_Script && !(m_dwScriptFlags & AI_SCRFLG_INT))
{
m_pServerDE->FreeString( hMsg );
return DTRUE;
}
int nId = atoi(pTokens[1]);
switch(nId)
{
case SOUND_GUNFIRE:
{
if(m_nState == STATE_Idle)
{
DVector vPos;
m_pServerDE->GetObjectPos(hSender, &vPos);
if(VEC_DIST(vPos, m_MoveObj.GetPos()) <= m_fHearingDist)
{
HCLASS hTest = m_pServerDE->GetClass("CPlayerObj");
if(m_pServerDE->IsKindOf(hTest, m_pServerDE->GetObjectClass(hSender)))
{
VEC_COPY(m_vTargetPos, vPos);
SetNewState(STATE_SearchVisualTarget);
}
/* else
{
AI_Mgr* pAI = (AI_Mgr*)m_pServerDE->HandleToObject(hSender);
m_hTrackObject = pAI->GetTarget();
if(VEC_DIST(vPos, m_MoveObj.GetPos()) > (m_fHearingDist * 0.1)
&& m_dwFlags & FLAG_CANASSIST)
{
VEC_COPY(m_vTrackObjPos, vPos);
SetNewState(STATE_AssistAlly);
}
else
{
m_hTarget = m_hTrackObject;
m_pServerDE->GetObjectPos(m_hTarget, &m_vTargetPos);
MC_FaceTarget();
}
}
*/ }
}
break;
}
case SOUND_PLAYERSOUND:
{
if(m_nState == STATE_Idle)
{
DVector vPos;
m_pServerDE->GetObjectPos(hSender, &vPos);
if(VEC_DIST(vPos, m_MoveObj.GetPos()) <= m_fHearingDist)
{
if(VEC_DIST(vPos, m_MoveObj.GetPos()) < m_fHearingDist/2)
{
VEC_COPY(m_vTargetPos, vPos);
SetNewState(STATE_SearchVisualTarget);
}
else
{
MC_FacePos(vPos);
SetNewState(STATE_Idle);
}
}
}
break;
}
case SOUND_GUNIMPACT:
{
if(m_dwFlags & FLAG_DODGE)
{
if(m_nState != STATE_Dodge && m_nLastState != STATE_Dodge
&& m_nLastState != STATE_Passive)
{
m_vTrackObjPos.x = (DFLOAT)atof(pTokens[2]);
m_vTrackObjPos.y = (DFLOAT)atof(pTokens[3]);
m_vTrackObjPos.z = (DFLOAT)atof(pTokens[4]);
SetNewState(STATE_Dodge);
}
}
break;
}
}
}
}
else if (_mbsicmp((const unsigned char*)TRIGGER_PLAY_SOUND, (const unsigned char*)pTokens[0]) == 0 && nArgs > 1)
{
// Get sound name from message...
char* pSoundName = pTokens[1];
if (pSoundName)
{
// See if sound radius was in message..
DFLOAT fRadius = 5000;
if (nArgs > 2 && pTokens[2])
{
fRadius = (DFLOAT) atoi(pTokens[2]);
}
fRadius = fRadius > 0.0f ? fRadius : 1000.0f;
PlaySoundFromObject( m_hObject, pSoundName, fRadius, SOUNDPRIORITY_MISC_HIGH, DFALSE, DFALSE, DFALSE );
m_pServerDE->FreeString( hMsg );
return DTRUE;
}
}
else if (_mbsicmp((const unsigned char*)TRIGGER_SET_STATE, (const unsigned char*)pTokens[0]) == 0 && nArgs > 1)
{
// Get state name from message...
char* pStateName = pTokens[1];
if (pStateName)
{
SetNewState(StateStrToInt(pStateName));
m_pServerDE->FreeString( hMsg );
return DTRUE;
}
}
else if (_mbsicmp((const unsigned char*)TRIGGER_TARGET_OBJECT, (const unsigned char*)pTokens[0]) == 0 && nArgs > 1)
{
// Get target name from message...
char* pName = pTokens[1];
if (pName)
{
SetTarget(pName);
SetNewState(STATE_AttackFar);
m_pServerDE->FreeString( hMsg );
return DTRUE;
}
}
else if (_mbsicmp((const unsigned char*)TRIGGER_PLAY_ANIMATION, (const unsigned char*)pTokens[0]) == 0 && nArgs > 1)
{
// Get ani name from message...
char* pName = pTokens[1];
if (pName)
{
PlayAnimation(pName);
m_pServerDE->FreeString( hMsg );
return DTRUE;
}
}
else if (_mbsicmp((const unsigned char*)TRIGGER_SCRIPT, (const unsigned char*)pTokens[0]) == 0)
{
// Get script type from message...
m_dwScriptFlags &= ~AI_SCRFLG_INT; // Not interruptable
if (nArgs > 1)
{
char* pType = pTokens[1];
if (pType)
{
if (_mbsicmp((const unsigned char*)TRIGGER_STYPE_INTERRUPTABLE, (const unsigned char*)pType) == 0)
{
m_dwScriptFlags |= AI_SCRFLG_INT;
}
else // Assume the flags were specified as a number
{
m_dwScriptFlags = atoi(pType);
}
}
}
m_scriptCmdList.RemoveAll();
// char* pCommand = pScriptBody;
// process the Next Command
pCommand = pCommandPos;
int nArgs;
while (m_pServerDE->Parse(pCommand, &pCommandPos, tokenSpace, pTokens, &nArgs))
{
if (nArgs != 2)
{
m_pServerDE->FreeString( hMsg );
return DFALSE;
}
AISCRIPTCMD* pCmd = new AISCRIPTCMD;
if (!pCmd)
{
m_pServerDE->FreeString( hMsg );
return DFALSE;
}
pCmd->command = StringToAIScriptCmdType(pTokens[0]);
char* pArgs = pTokens[1];
if (pArgs) _mbsncpy((unsigned char*)pCmd->args, (const unsigned char*)pArgs, MAX_AI_ARGS_LENGTH);
m_scriptCmdList.Add(pCmd);
pCommand = pCommandPos;
}
// Set the State to Script
SetNewState(STATE_Script);
m_bUpdateScriptCmd = DTRUE;
m_nScriptCmdIndex = 0;
// Force a Update
AI_Update();
} // else if
pCommand = pCommandPos;
} // While commands
m_pServerDE->FreeString( hMsg );
return DFALSE;
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::PlayAnimation
// DESCRIPTION :
// RETURN TYPE : void
// PARAMS : char* pAniName
// ----------------------------------------------------------------------- //
void AI_Mgr::PlayAnimation(char* pAniName)
{
DDWORD dwAniIndex = m_pServerDE->GetAnimIndex(m_hObject, pAniName);
m_pServerDE->SetModelLooping(m_hObject, DFALSE);
// m_pServerDE->SetModelAnimation(m_hObject, dwAniIndex);
SetAnimation(dwAniIndex);
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetTarget
// DESCRIPTION :
// RETURN TYPE : void
// PARAMS : char* pTargetName
// ----------------------------------------------------------------------- //
void AI_Mgr::SetTarget(char* pTargetName)
{
ObjectList* pList = m_pServerDE->FindNamedObjects(pTargetName);
if (!pList) return;
ObjectLink* pLink = pList->m_pFirstLink;
if (pLink)
{
SetNewTarget(pLink->m_hObject);
m_pServerDE->GetObjectPos(m_hTarget, &m_vTargetPos);
MC_FaceTarget();
Metacmd--;
}
m_pServerDE->RelinquishList(pList);
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetNewTarget
// DESCRIPTION :
// RETURN TYPE : void
// PARAMS : HOBJECT hNewTarget
// ----------------------------------------------------------------------- //
void AI_Mgr::SetNewTarget(HOBJECT hNewTarget)
{
if (m_hTarget != hNewTarget)
{
if (m_hTarget)
{
m_pServerDE->BreakInterObjectLink(m_hObject, m_hTarget);
}
m_hTarget = hNewTarget;
if (m_hTarget)
{
m_pServerDE->CreateInterObjectLink(m_hObject, m_hTarget);
}
}
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::UpdateScriptCommand
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::UpdateScriptCommand()
{
m_bUpdateScriptCmd = DFALSE;
m_curScriptCmd.command = AI_SCMD_DONE;
int nNumItems = m_scriptCmdList.GetNumItems();
if (nNumItems > 0)
{
m_curScriptCmd = *(m_scriptCmdList[m_nScriptCmdIndex]);
// Determine what the next script cmd index should be...
if (m_dwScriptFlags & AI_SCRFLG_LOOP)
{
m_nScriptCmdIndex = (m_nScriptCmdIndex + 1 < nNumItems) ? m_nScriptCmdIndex + 1 : 0;
}
else // Non-looping, remove current script command...
{
m_nScriptCmdIndex = 0;
m_scriptCmdList.Remove(0);
}
switch(m_curScriptCmd.command)
{
case AI_SCMD_SETMOVEMENT:
SetSetMovementCmd();
break;
case AI_SCMD_FOLLOWPATH:
SetFollowPathCmd();
break;
case AI_SCMD_PLAYSOUND:
SetPlaysoundCmd();
break;
case AI_SCMD_SETSTATE:
SetSetStateCmd();
break;
case AI_SCMD_TARGET:
SetTargetCmd();
break;
case AI_SCMD_WAIT:
SetWaitCmd();
break;
case AI_SCMD_PLAYANIMATION:
SetPlayAnimationCmd(DFALSE);
break;
case AI_SCMD_PLAYANIMATION_LOOPING:
SetPlayAnimationCmd(DTRUE);
break;
case AI_SCMD_MOVETOOBJECT:
SetMoveToObjectCmd();
break;
case AI_SCMD_DONE:
default:
m_dwScriptFlags = 0;
ComputeState();
break;
}
}
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetSetMovementCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::SetSetMovementCmd()
{
if (_mbsicmp((const unsigned char*)m_curScriptCmd.args, (const unsigned char*)SCRIPT_MOVEMENT_WALK) == 0)
{
m_eScriptMovement = SM_WALK;
}
else if (_mbsicmp((const unsigned char*)m_curScriptCmd.args, (const unsigned char*)SCRIPT_MOVEMENT_RUN) == 0)
{
m_eScriptMovement = SM_RUN;
}
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::SetFollowPathCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::SetFollowPathCmd()
{
m_AIPathList.RemoveAll();
if (!g_pBloodServerShell) return;
PathMgr* pPathMgr = g_pBloodServerShell->GetPathMgr();
if (!pPathMgr) return;
pPathMgr->GetPath(m_curScriptCmd.args, &m_AIPathList);
Metacmd = 1;
}
// ----------------------------------------------------------------------- //
// ROUTINE : AI_Mgr::UpdateFollowPathCmd
// DESCRIPTION :
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
void AI_Mgr::UpdateFollowPathCmd()
{
if (m_AIPathList.IsEmpty())
{
m_bUpdateScriptCmd = DTRUE;
return;
}
PathListData* pCurKey = m_AIPathList[0];
if (!pCurKey)
{
m_bUpdateScriptCmd = DTRUE;
return;
}
DVector vTargetPos;
VEC_COPY(vTargetPos, pCurKey->m_vPos);
DVector vPos;
VEC_COPY(vPos, m_MoveObj.GetPos());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -