DragonNest/Server/DNGameServer/MAAiScript.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

1992 lines
53 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAFx.h"
#include "MAAiScript.h"
#include "DnMonsterActor.h"
#include "DnWorld.h"
#include "DnWeapon.h"
#include "lua_tinker.h"
#include "DnSkill.h"
#include "DnBlow.h"
#include "MAAiChecker.h"
#include "MAAiCommand.h"
#include "DNAggroSystem.h"
#include "DNMonsterAggroSystem.h"
#include "MAAiProcessor.h"
#include "DnPartsMonsterActor.h"
#if defined(PRE_ADD_64990)
#include "DNGameRoom.h"
#endif // PRE_ADD_64990
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
AiScriptLoader g_AiScriptLoader;
AiScriptLoader::AiScriptLoader()
{
}
AiScriptLoader::~AiScriptLoader()
{
for( std::map<std::string, ScriptData>::iterator itor=m_ScriptMap.begin() ; itor!=m_ScriptMap.end() ; ++itor )
{
for( UINT i=0 ; i<(*itor).second.m_AITable.size() ; ++i )
{
for( UINT j=0 ; j<(*itor).second.m_AITable[i].VecActionTable.size() ; ++j )
{
SAFE_DELETE( (*itor).second.m_AITable[i].VecActionTable[j].pMAAiCheckerManager );
}
}
#if defined(PRE_ADD_64990)
for (int nIndex = 0; nIndex < 2; ++nIndex)
{
for( DWORD i=0; i<(*itor).second.m_SkillTable[nIndex].size(); i++ )
{
SAFE_DELETE( (*itor).second.m_SkillTable[nIndex][i].pMAAiCheckerManager );
}
}
#else
for( DWORD i=0; i<(*itor).second.m_SkillTable.size(); i++ )
{
SAFE_DELETE( (*itor).second.m_SkillTable[i].pMAAiCheckerManager );
}
#endif // PRE_ADD_64990
for( UINT i=0 ; i<(*itor).second.m_AISkillProcessorTable.size() ; ++i )
{
SAFE_DELETE( (*itor).second.m_AISkillProcessorTable[i].pMAAiProcessorManager );
}
for( UINT i=0; i<(*itor).second.m_NonDownMeleeDamageActionTable.size(); ++i )
{
SAFE_DELETE( (*itor).second.m_NonDownMeleeDamageActionTable[i].pMAAiCheckerManager );
}
for( UINT i=0; i<(*itor).second.m_NonDownRangeDamageActionTable.size(); ++i )
{
SAFE_DELETE( (*itor).second.m_NonDownRangeDamageActionTable[i].pMAAiCheckerManager );
}
for( UINT i=0; i<(*itor).second.m_MeleeDefenseActionTable.size(); ++i )
{
SAFE_DELETE( (*itor).second.m_MeleeDefenseActionTable[i].pMAAiCheckerManager );
}
for( UINT i=0; i<(*itor).second.m_RangeDefenseActionTable.size(); ++i )
{
SAFE_DELETE( (*itor).second.m_RangeDefenseActionTable[i].pMAAiCheckerManager );
}
for( UINT i=0; i<(*itor).second.m_BeHitSkillActionTable.size(); ++i )
{
SAFE_DELETE( (*itor).second.m_BeHitSkillActionTable[i].pMAAiCheckerManager );
}
for( UINT i=0; i<(*itor).second.m_AssaultActionTable.size(); ++i )
{
SAFE_DELETE( (*itor).second.m_AssaultActionTable[i].pMAAiCheckerManager );
}
}
}
bool AiScriptLoader::AllLoadScript()
{
m_ScriptMap.clear();
std::vector<CFileNameString> FileList;
CEtResourceMng::GetInstance().FindFileListAll_IgnoreExistFile( "MonsterAI", "*.lua", FileList );
//CEtResourceMng::GetInstance().FindFileListAll_IgnoreExistFile( "MonsterAI", "MultiTarget_Test.lua", FileList );
for ( int i = 0 ; i < (int)FileList.size() ; i++ )
{
bool bResult = LoadScript(FileList[i].c_str());
if ( !bResult )
{
std::string szLog = FormatA("Ai File Load Failed : %s\r\n", FileList[i].c_str());
std::wstring wszLog;
ToWideString(szLog, wszLog);
g_Log.Log(LogType::_FILELOG, L"%s", wszLog.c_str());
return false;
}
}
return true;
}
bool AiScriptLoader::GetScript(const char* szFileName, OUT ScriptData& data)
{
std::string szTemp = szFileName;
ToLowerA( szTemp );
std::map<std::string, ScriptData>::iterator it = m_ScriptMap.find( szTemp );
if ( it == m_ScriptMap.end() )
return false;
data = it->second;
return true;
}
bool AiScriptLoader::LoadActionTable(lua_tinker::table& t, int nIdx, OUT ActionTable& at)
{
ActionTableCommon::eType Type = ActionTableCommon::Max;
const char* szActionName = t.get<const char*>("action_name");
if ( szActionName )
Type = ActionTableCommon::Action;
else
{
const char* szSkilIndex = t.get<const char*>("lua_skill_index");
if( szSkilIndex )
Type = ActionTableCommon::Skill;
}
if( Type == ActionTableCommon::Max )
return false;
std::string sz;
if( szActionName )
sz = szActionName;
int nRate = t.get<int>("rate");
int nLoop = t.get<int>("loop");
int nCoolTime = t.get<int>("cooltime");
int nCancelLook = t.get<int>("cancellook");
float fApproach = t.get<float>("approach");
int nMinAttackMissRadian = t.get<int>("min_missradian");
int nMaxAttackMissRadian = t.get<int>("max_missradian");
float fRandomTarget = t.get<float>("randomtarget");
#ifdef PRE_ADD_MONSTER_NORMAL_ACTION_PRIORITY
int nPriority = t.get<int>("priority");
#endif
#if defined (PRE_MOD_AIMULTITARGET)
int nMultipleTarget = 0;
int nSummonerTarget = 0;
#else
bool bMultipleTarget = false;
#endif
int iMultipleMaxCount = 0;
bool bIsExecptCannonPlayer = false;
bool bAnyMultipleTarget = false;
const char* pAnyMultipleTarget = t.get<const char*>("anymultipletarget");
if( pAnyMultipleTarget )
bAnyMultipleTarget = true;
const char* pTemp = t.get<const char*>( bAnyMultipleTarget ? "anymultipletarget" : "multipletarget" );
if( pTemp )
{
std::string strString( pTemp );
std::vector<std::string> vSplit;
boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") );
#if defined (PRE_MOD_AIMULTITARGET)
nMultipleTarget = boost::lexical_cast<int>(vSplit[0]);
if( vSplit.size() > 1 )
{
iMultipleMaxCount = boost::lexical_cast<int>(vSplit[1]);
}
if( vSplit.size() > 2 )
{
if( stricmp( vSplit[2].c_str(), "exceptcannon" ) == 0 )
bIsExecptCannonPlayer = true;
}
if( vSplit.size() > 3 )
nSummonerTarget = boost::lexical_cast<int>(vSplit[3]);
#else
bMultipleTarget = boost::lexical_cast<int>(vSplit[0]) ? true : false;
if( vSplit.size() == 2 )
{
iMultipleMaxCount = boost::lexical_cast<int>(vSplit[1]);
}
else if( vSplit.size() == 3 )
{
if( stricmp( vSplit[2].c_str(), "exceptcannon" ) == 0 )
bIsExecptCannonPlayer = true;
}
#endif
}
if ( fApproach < 1.0f)
fApproach = 100.0f;
const char* szCondition = t.get<const char*>("target_condition");
at.Type = Type;
at.szActionName = sz;
at.nIdx = (int)nIdx;
at.nRate = nRate;
at.nLoop = nLoop;
at.nCoolTime = nCoolTime;
at.nCancelLook = nCancelLook;
at.fApproach = fApproach;
at.nMinAttackMissRadian = nMinAttackMissRadian;
at.nMaxAttackMissRadian = nMaxAttackMissRadian;
at.fRandomTarget = fRandomTarget;
#if defined (PRE_MOD_AIMULTITARGET)
at.nMultipleTarget = nMultipleTarget;
at.nSummonerTarget = nSummonerTarget;
#else
at.bMultipleTarget = bMultipleTarget;
#endif
at.iMaxMultipleTargetCount = iMultipleMaxCount;
at.bIsAnyMultipleTarget = bAnyMultipleTarget;
at.bIsExceptCannonPlayer = bIsExecptCannonPlayer;
#ifdef PRE_ADD_MONSTER_NORMAL_ACTION_PRIORITY
at.nActionPriority = nPriority;
#endif
#if defined( PRE_FIX_68096 )
if( t.get<const char*>("globalcooltime") )
{
at.iGlobalCoolTimeIndex[0] = t.get<int>("globalcooltime")-1;
_ASSERT( at.iGlobalCoolTimeIndex[0] >= 0 );
}
for( int i=1 ; i<ActionTableCommon::eCommon::MaxGlobalCoolTime ; ++i )
{
char szBuf[MAX_PATH];
sprintf( szBuf, "globalcooltime%d", i+1 );
at.iGlobalCoolTimeIndex[i] = t.get<int>(szBuf)-1;
if(at.iGlobalCoolTimeIndex[i] == -1)
break;
}
#else
if( t.get<const char*>("globalcooltime") )
{
at.iGlobalCoolTimeIndex = t.get<int>("globalcooltime")-1;
_ASSERT( at.iGlobalCoolTimeIndex >= 0 );
}
#endif
if( Type == ActionTableCommon::Skill )
{
at.nLuaSkillIndex = t.get<int>("lua_skill_index");
at.nBeHitSkillIndex = t.get<int>("skill_index");
}
// LoadChecker
at.pMAAiCheckerManager = new CMAAiActionCheckerManager;
if( !at.pMAAiCheckerManager->bLoadChecker( t ) )
return false;
if ( szCondition )
at.szTargetCondition = szCondition;
return true;
}
bool AiScriptLoader::LoadTable( lua_State* pLua, const char* pTableName, std::vector<ActionTable>& vActionTable )
{
vActionTable.clear();
lua_tinker::table luaTable = lua_tinker::get<lua_tinker::table>( pLua, pTableName );
lua_tinker::table t = luaTable.get<lua_tinker::table>(1);
if( t.get<const char*>("action_name") || t.get<const char*>("lua_skill_index") )
{
for( int j=1 ; j<=luaTable.getSize() ; ++j )
{
lua_tinker::table LocalT = luaTable.get<lua_tinker::table>(j);
ActionTable at;
if( !LoadActionTable( LocalT, (int)vActionTable.size(), at ) )
return false;
vActionTable.push_back(at);
}
}
return true;
}
bool AiScriptLoader::LoadSkillProcessor( lua_State* pLua, std::vector<AISkillProcessor>& vSkillProcessor )
{
vSkillProcessor.clear();
lua_tinker::table luaTable = lua_tinker::get<lua_tinker::table>( pLua, "g_Lua_SkillProcessor" );
lua_tinker::table t = luaTable.get<lua_tinker::table>(1);
if( t.get<const char*>("skill_index") )
{
for( int i=1 ; i<=luaTable.getSize() ; ++i )
{
lua_tinker::table LocalT = luaTable.get<lua_tinker::table>(i);
AISkillProcessor at;
at.nSkillIndex = LocalT.get<int>("skill_index");
at.pMAAiProcessorManager = new CMAAiProcessorManager();
if( !at.pMAAiProcessorManager->bLoad( LocalT ) )
return false;
vSkillProcessor.push_back(at);
}
}
return true;
}
#if defined( PRE_ADD_LOTUSGOLEM )
bool AiScriptLoader::LoadPartsProcessor( lua_State* pLua, ScriptData& data )
{
// OnlyParts
data.m_iOnlyPartsDamage = lua_tinker::get<int>(pLua, "g_Lua_OnlyPartsDamage");
// Parts
std::vector<AIPartsProcessor>& vPartsProcessor = data.m_AIPartsProcessor;
vPartsProcessor.clear();
lua_tinker::table luaTable = lua_tinker::get<lua_tinker::table>( pLua, "g_Lua_PartsProcessor" );
lua_tinker::table t = luaTable.get<lua_tinker::table>(1);
if( t.get<const char*>("hp") )
{
for( int i=1 ; i<=luaTable.getSize() ; ++i )
{
lua_tinker::table LocalT = luaTable.get<lua_tinker::table>(i);
AIPartsProcessor at;
// hp
{
const char* pszHP = LocalT.get<const char*>("hp");
if( pszHP == NULL )
{
_ASSERT(0);
return false;
}
std::string strString( pszHP );
std::vector<std::string> vSplit;
std::vector<int> vTableID;
boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") );
for( UINT i=0 ; i<vSplit.size() ; ++i )
vTableID.push_back( atoi(vSplit[i].c_str()) );
if( vTableID.size() != 2 )
{
_ASSERT(0);
return false;
}
at.iMinHP = vTableID[0];
at.iMaxHP = vTableID[1];
}
// checkskill
{
at.iCheckSkillIndex = 0;
const char* pszCheckSkillIndex = LocalT.get<const char*>("checkskill");
if( pszCheckSkillIndex )
at.iCheckSkillIndex = atoi( pszCheckSkillIndex );
}
// checkblow
{
at.iCheckBlowIndex = 0;
const char* pszCheckBlowIndex = LocalT.get<const char*>("checkblow");
if( pszCheckBlowIndex )
at.iCheckBlowIndex = atoi( pszCheckBlowIndex );
}
// checkaction
{
const char* pszCheckAction = LocalT.get<const char*>("checkaction");
if( pszCheckAction )
at.strCheckActionName = pszCheckAction;
}
// ignore
{
const char* pszIgnore = LocalT.get<const char*>("ignore");
if( pszIgnore )
{
std::string strString( pszIgnore );
std::vector<std::string> vSplit;
std::vector<int> vTableID;
boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") );
for( UINT i=0 ; i<vSplit.size() ; ++i )
vTableID.push_back( atoi(vSplit[i].c_str()) );
at.vIgnorePartsIndex = vTableID;
}
}
// nodamage
{
const char* pszNoDamage = LocalT.get<const char*>("nodamage");
if( pszNoDamage )
{
std::string strString( pszNoDamage );
std::vector<std::string> vSplit;
std::vector<int> vTableID;
boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") );
for( UINT i=0 ; i<vSplit.size() ; ++i )
vTableID.push_back( atoi(vSplit[i].c_str()) );
at.vNoDamagePartsIndex = vTableID;
}
}
// active
{
const char* pszActive = LocalT.get<const char*>("active");
if( pszActive )
{
std::string strString( pszActive );
std::vector<std::string> vSplit;
std::vector<int> vTableID;
boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") );
for( UINT i=0 ; i<vSplit.size() ; ++i )
vTableID.push_back( atoi(vSplit[i].c_str()) );
at.vActivePartsIndex = vTableID;
}
}
vPartsProcessor.push_back(at);
}
}
return true;
}
#endif // #if defined( PRE_ADD_LOTUSGOLEM )
bool AiScriptLoader::LoadAggroRange( lua_State* pLua, std::vector<AIAggroRange>& vAggroRange )
{
vAggroRange.clear();
lua_tinker::table luaTable = lua_tinker::get<lua_tinker::table>( pLua, "g_Lua_ThreatRange" );
lua_tinker::table t = luaTable.get<lua_tinker::table>(1);
if( t.get<const char*>("selfhppercent") )
{
for( int i=1 ; i<=luaTable.getSize() ; ++i )
{
lua_tinker::table LocalT = luaTable.get<lua_tinker::table>(i);
AIAggroRange at;
at.iSelfHPPercent = LocalT.get<int>("selfhppercent");
at.iThreatRange = LocalT.get<int>("ThreatRange");
at.iCognizanceGentleRange = LocalT.get<int>("CognizanceGentleRange");
at.iCognizanceThreatRange = LocalT.get<int>("CognizanceThreatRange");
vAggroRange.push_back(at);
}
}
return true;
}
bool AiScriptLoader::LoadGlobalCoolTime( lua_State* pLua, std::vector<AIGlobalCoolTime>& vGlobalCoolTime )
{
vGlobalCoolTime.clear();
for( int i=1 ; i<INT_MAX ; ++i )
{
char szBuf[MAX_PATH];
sprintf( szBuf, "g_Lua_GlobalCoolTime%d", i );
int iCoolTime = lua_tinker::get<int>( pLua, szBuf );
if( iCoolTime <= 0 )
break;
AIGlobalCoolTime at;
at.dwCoolTime = static_cast<DWORD>(iCoolTime);
vGlobalCoolTime.push_back( at );
}
return true;
}
bool AiScriptLoader::LoadSetPartsRebirthTable( lua_State* pLua, ScriptData& data )
{
data.m_vSetPartsRebirthTable.clear();
std::string strTableName = boost::io::str( boost::format( "g_Lua_RebirthParts" ) );
lua_tinker::table luaTable = lua_tinker::get<lua_tinker::table>( pLua, strTableName.c_str() );
if( !luaTable.m_obj->m_pointer )
return true;
for( int i=1 ; i<=luaTable.getSize() ; ++i )
{
AI_SETPARTSREBIRTH_TABLE PartsTable;
lua_tinker::table t = luaTable.get<lua_tinker::table>(i);
// PartsTableID
std::string strString( t.get<const char*>("tableID") );
std::vector<std::string> vSplit;
boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") );
for( UINT j=0 ; j<vSplit.size() ; ++j )
PartsTable.vPartsTableID.push_back( boost::lexical_cast<UINT>(vSplit[j]) );
// Tick
PartsTable.uiRebirthTick = t.get<int>("tick");
data.m_vSetPartsRebirthTable.push_back( PartsTable );
}
return true;
}
bool AiScriptLoader::LoadScript(const char* szFilename)
{
std::map<std::string, ScriptData>::iterator it = m_ScriptMap.find(std::string(szFilename));
if ( it != m_ScriptMap.end() )
return false;
ScriptData data;
std::string szFullName;
szFullName = CEtResourceMng::GetInstance().GetFullName( szFilename ).c_str();
char szTemp[256] = { 0, };
_GetFullFileName( szTemp, _countof(szTemp), szFilename );
_strlwr_s( szTemp );
data.m_szSettingFile = szTemp;
lua_State* pLua = lua_open();
luaL_openlibs(pLua);
if ( lua_tinker::dofile(pLua, szFullName.c_str()) != 0 )
{
OutputDebug("Cannot open file : %s\n" , szFullName.c_str());
lua_close(pLua);
return true;
}
data.m_nNearTableCnt = lua_tinker::get<int>(pLua, "g_Lua_NearTableCount");
data.m_nPatrolBaseTime = lua_tinker::get<int>(pLua, "g_Lua_PatrolBaseTime");
data.m_nPatrolRandTime = lua_tinker::get<int>(pLua, "g_Lua_PatrolRandTime");
data.m_fApproachValue = lua_tinker::get<float>(pLua, "g_Lua_ApproachValue");
data.m_nAssaultTime = lua_tinker::get<int>(pLua, "g_Lua_AssaultTime");
data.m_Type = ScriptData::None;
if( lua_tinker::get<int>(pLua, "g_Lua_NoAggroOwnerFollow") > 0 )
data.m_Type |= ScriptData::NoAggroOwnerFollow;
#ifdef PRE_ADD_AI_NOAGGRO_STAND
bool bIsNoAggroStand = (lua_tinker::get<int>(pLua, "g_Lua_NoAggroStand") > 0);
if (bIsNoAggroStand)
data.m_Type |= ScriptData::NoAggroStand;
#endif
if ( data.m_nAssaultTime < 100 )
data.m_nAssaultTime = 3000;
if ( data.m_fApproachValue < 10.0f )
data.m_fApproachValue = 100.0f;
data.m_AITable.clear();
data.m_CustomActionMap.clear();
// SET<45><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ȱ <20><><EFBFBD>̺<EFBFBD>
if( !LoadSetPartsRebirthTable( pLua, data ) )
return false;
// MeleeDefenseTable
if( !LoadTable( pLua, "g_Lua_MeleeDefense", data.m_MeleeDefenseActionTable ) )
return false;
// RangeDefenseTable
if( !LoadTable( pLua, "g_Lua_RangeDefense", data.m_RangeDefenseActionTable ) )
return false;
// NonDownMeleeDamageTable
if( !LoadTable( pLua, "g_Lua_NonDownMeleeDamage", data.m_NonDownMeleeDamageActionTable ) )
return false;
// NonDownRangeDamageTable
if( !LoadTable( pLua, "g_Lua_NonDownRangeDamage", data.m_NonDownRangeDamageActionTable ) )
return false;
// BeHitSkillTable
if( !LoadTable( pLua, "g_Lua_BeHitSkill", data.m_BeHitSkillActionTable ) )
return false;
// AssultTable
if( !LoadTable( pLua, "g_Lua_Assault", data.m_AssaultActionTable ) )
return false;
if( !LoadSkillProcessor( pLua, data.m_AISkillProcessorTable ) )
return false;
#if defined( PRE_ADD_LOTUSGOLEM )
if( !LoadPartsProcessor( pLua, data ) )
return false;
#endif // #if defined( PRE_ADD_LOTUSGOLEM )
if( !LoadAggroRange( pLua, data.m_AIAggroRange ) )
return false;
if( !LoadGlobalCoolTime( pLua, data.m_AIGlobalCoolTime ) )
return false;
// <20><>ų <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20>ִٸ<D6B4>.
#if defined(PRE_ADD_64990)
vector<string> tableNames;
MonsterSkillAI::CheckSkillTable(pLua, tableNames);
string PvESkillTableName;
string PvPSkillTableName;
if (tableNames[2].empty() == false)
PvPSkillTableName = tableNames[2];
else
{
//<2F><><EFBFBD><EFBFBD> "g_Lua_Skill"<22><> <20>ְ<EFBFBD>, PvE<76><45> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (tableNames[0].empty() == false && tableNames[1].empty() == true)
PvPSkillTableName = tableNames[0];
}
if (tableNames[1].empty() == false)
PvESkillTableName = tableNames[1];
else
{
if (tableNames[0].empty() == false)
PvESkillTableName = tableNames[0];
}
if( !MonsterSkillAI::LoadSkillTable(pLua, data.m_SkillTable[0], PvESkillTableName) )
return false;
if( !MonsterSkillAI::LoadSkillTable(pLua, data.m_SkillTable[1], PvPSkillTableName) )
return false;
#else
if( !MonsterSkillAI::LoadSkillTable(pLua, data.m_SkillTable) )
return false;
#endif // PRE_ADD_64990
for ( int i = 0 ; i < data.m_nNearTableCnt ; i++ )
{
AI_TABLE table;
char buff[512] = {0,};
ZeroMemory(buff, sizeof(char)*512);
sprintf_s(buff, "g_Lua_NearValue%d", i+1 );
table.fNearValue = (float)lua_tinker::get<float>(pLua, buff);
table.fNearValueSq = table.fNearValue * table.fNearValue;
ZeroMemory(buff, sizeof(char)*512);
sprintf_s(buff, "g_Lua_Near%d", i+1 );
lua_tinker::table neartable = lua_tinker::get<lua_tinker::table>(pLua, buff);
if( !neartable.m_obj->m_pointer )
return false;
table.nRateSum = 0;
for ( int j = 1 ; j <= neartable.getSize() ; j++ )
{
lua_tinker::table t = neartable.get<lua_tinker::table>(j);
ActionTable at;
at.nDistanceState = i;
if( !LoadActionTable(t, (int)table.VecActionTable.size(), at) )
return false;
table.VecActionTable.push_back(at);
table.nRateSum += at.nRate;
}
data.m_AITable.push_back(table);
}
lua_tinker::table custom_table = lua_tinker::get<lua_tinker::table>(pLua, "g_Lua_CustomAction");
// fuck.. -_-
bool bHave = false;
lua_tinker::table t = custom_table.get<lua_tinker::table>("CustomAction1");
lua_tinker::table t2 = t.get<lua_tinker::table>(1);
const char* szCustomActionName = t2.get<const char*>(1);
if ( szCustomActionName == NULL ) bHave = false;
else bHave = true;
if ( bHave )
{
char buff[512] = {0,} ;
for ( int i = 1 ; i <= custom_table.getSize() ; i++ )
{
CustomActionTable custom;
ZeroMemory(buff, sizeof(char)*512);
sprintf_s(buff, "CustomAction%d", i );
custom.szCustomActionName = buff;
lua_tinker::table custom_action = custom_table.get<lua_tinker::table>(buff);
for ( int j = 1 ; j <= custom_action.getSize() ; j++ )
{
lua_tinker::table action_info = custom_action.get<lua_tinker::table>(j);
CustomAction info;
info.szActionName = action_info.get<const char*>(1);
if( stricmp( info.szActionName.c_str(), "useskill" ) == 0 )
{
info.nLuaSkillIndex = action_info.get<int>( "lua_skill_index" );
}
else
{
info.nLoop = action_info.get<int>(2);
}
custom.m_ActionList.push_back(info);
}
data.m_CustomActionMap.insert(make_pair(custom.szCustomActionName, custom));
}
}
lua_tinker::table customAttackTable = lua_tinker::get<lua_tinker::table>(pLua, "g_Lua_CustomAttack");
//-----------------------------------------------------------------------------------------------
{
lua_tinker::table state_table = lua_tinker::get<lua_tinker::table>(pLua, "g_Lua_State");
bHave = false;
lua_tinker::table LocalT = state_table.get<lua_tinker::table>("State1");
const char* szStateName = LocalT.get<const char*>(1);
if ( szStateName == NULL ) { bHave = false; }
else { bHave = true; }
if ( bHave )
{
char buff[512] = {0,};
for ( int i = 1 ; i <= state_table.getSize() ; i++ )
{
ZeroMemory(buff, sizeof(char)*512);
sprintf_s(buff, "State%d", i );
StateCondition condition;
lua_tinker::table __state = state_table.get<lua_tinker::table>(buff);
for ( int j = 1 ; j <= __state.getSize() ; j++ )
{
OrOperator oper;
const char* _szState = __state.get<const char*>(j);
std::string szState = _szState;
std::vector<std::string> orOper;
TokenizeA(szState, orOper, "|");
for ( int k = 0 ; k < (int)orOper.size() ; k++ )
{
StateOperation stateOper;
stateOper.nState = CDnActorState::None;
stateOper.bNOT = false;
stateOper.szString = orOper[k];
std::string::size_type npos = stateOper.szString.find("!");
if ( npos < stateOper.szString.size() )
{
stateOper.bNOT = true;
}
std::string szLocalTemp = orOper[k];
RemoveStringA(szLocalTemp, std::string("!"));
stateOper.nState = CDnActorState::String2ActorStateEnum(szLocalTemp.c_str());
oper.OrOperatorArray.push_back(stateOper);
}
condition.AndOperatorArray.push_back(oper) ;
}
data.m_StateContidionMap.insert(make_pair(buff, condition));
}
}
}
//---------------------------------------------------------------------------
m_ScriptMap.insert(make_pair(data.m_szSettingFile, data));
lua_close(pLua);
return true;
}
//---------------------------------------------------------------------------------------------------------
MAAiScript::MAAiScript( DnActorHandle hActor, MAAiReceiver *pReceiver )
: MAAiBase( hActor, pReceiver )
{
m_Data.m_nNearTableCnt = 0;
m_Data.m_nPatrolBaseTime = 5000;
m_Data.m_nPatrolRandTime = 3000;
m_Data.m_fApproachValue = 100.0f;
m_Data.m_nCurrentCustomActionPlayIndex = -1;
m_Data.m_nAssaultTime = 5000;
m_Data.m_Type = ScriptData::eTypeBit::None;
m_nState = AT_Normal;
m_nSeletedAssaultActionIndex = -1;
m_bValidAI = false;
m_pDestinationOBB = NULL;
m_uiMoveFrontRate = 100; // Default MOVE_FRONT
m_dwDestinationOBB = 0;
m_ChangeStateTime = 0;
m_pAICommand = new MAAiCommand;
}
MAAiScript::~MAAiScript()
{
SAFE_DELETE( m_pAICommand );
}
void MAAiScript::Process( LOCAL_TIME LocalTime, float fDelta )
{
MAAiBase::Process( LocalTime, fDelta );
m_SkillAI.Process(LocalTime, fDelta);
std::string szAction = m_hActor->GetCurrentAction();
if ( szAction == "" )
m_hActor->CmdAction( "Stand", 0, -1.f );
OnAI("", LocalTime);
#if defined( PRE_ADD_LOTUSGOLEM )
_ProcessParts();
#endif // #if defined( PRE_ADD_LOTUSGOLEM )
}
void MAAiScript::OnChangeAction(const char* szPrevAction)
{
if( bIsAILook() && !m_strAILookAction.empty() )
{
if( strcmp( m_strAILookAction.c_str(), szPrevAction ) == 0 )
{
ResetAILook();
m_strAILookAction.clear();
}
else
{
return;
}
}
if( bIsAILook() && !m_hActor->IsProcessSkill() )
ResetAILook();
#if defined( PRE_FIX_MOVEBACK )
if(m_hActor && m_hActor->IsMonsterActor() && m_pMonsterActor )
m_pMonsterActor->SetNearMoveBack();
#endif
// <20>׼<EFBFBD><D7BC><EFBFBD> <20>ٲ<EFBFBD><D9B2><EFBFBD> <20>߻<EFBFBD>ü Ÿ<><C5B8> <20><><EFBFBD><EFBFBD> <20>ñ׳η<D7B3> <20><><EFBFBD>õǾ<C3B5><C7BE>ִ<EFBFBD> <20><><EFBFBD>͸<EFBFBD> <20>ʱ<EFBFBD>ȭ.
m_hReservedProjectileTarget = CDnActor::Identity();
}
void MAAiScript::OnFinishAction(const char* szPrevAction, LOCAL_TIME time)
{
if( bIsAILook() && !m_strAILookAction.empty() )
{
if( strcmp( m_strAILookAction.c_str(), szPrevAction ) == 0 )
{
ResetAILook();
m_strAILookAction.clear();
}
}
// <20>׼<EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MultipleTarget <20>ʱ<EFBFBD>ȭ~
#if defined (PRE_MOD_AIMULTITARGET)
if( m_cMultipleTarget.GetMultipleTarget() > 0 && m_cMultipleTarget.GetType() == CMAAiMultipleTarget::Skill )
#else
if( m_cMultipleTarget.bIsMultipleTarget() && m_cMultipleTarget.GetType() == CMAAiMultipleTarget::Skill )
#endif
{
if( m_hActor->IsProcessSkill() == false )
m_cMultipleTarget.Reset();
}
else
{
m_cMultipleTarget.Reset();
}
#if defined( PRE_FIX_MOVEBACK )
if(m_hActor && m_hActor->IsMonsterActor() && m_pMonsterActor )
m_pMonsterActor->SetPrevMoveBack( false );
#endif
OnAI(szPrevAction, time);
}
void MAAiScript::OnDie()
{
}
void MAAiScript::OnInitNaviDestination( SOBB* pOBB, UINT uiMoveFrontRate )
{
m_pDestinationOBB = pOBB;
m_uiMoveFrontRate = uiMoveFrontRate;
}
#ifndef _FINAL_BUILD
void MAAiScript::OnTestNaviAI( LOCAL_TIME time )
{
if ( IsDelay(AIDelayType::Patrol) )
return;
if ( m_hTarget )
{
EtVector3* pvPos = m_hActor->GetPosition();
float fLength = 0.0f;
if( m_hTarget )
{
fLength = EtVec3Length( &( *pvPos - *m_hTarget->GetPosition() ) );
}
// <20>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
if ( fLength <= 50.0f && m_hActor->IsMovable() /*&& !m_hActor->IsHit() && !m_hActor->IsAttack() && !m_hActor->IsDown()*/ )
{
std::string szAction;
int nBack = _rand(m_hActor->GetRoom())%2;
switch( nBack )
{
case 0: szAction = "Move_Back"; break;
case 1: szAction = "Walk_Back"; break;
}
m_hActor->CmdAction( szAction.c_str(), 0, g_fBendFrame );
return;
}
if ( m_hActor->IsStay() && m_hActor->IsMovable() )
{
m_hActor->CmdMoveNavi( m_hTarget, 50.0f, "Move_Front", -1, g_fBendFrame );
//m_hActor->CmdMove( m_hTarget, 50.0f, "Move_Front", -1, g_fBendFrame );
return;
}
}
SetDelay( AIDelayType::Patrol, 10000);
}
void MAAiScript::OnTestAttackAI( LOCAL_TIME time )
{
static int nTestCount = 0;
if ( IsDelay( AIDelayType::Patrol ) )
return;
if( m_hTarget )
{
int state = 0;
if( m_hActor->IsStay() && m_hActor->IsMovable() )
{
int nIndex = SelectAction(m_Data.m_AITable[state].VecActionTable, time);
if( nIndex < 0 )
return;
int nLoop = m_Data.m_AITable[state].VecActionTable[nIndex].nLoop;
if( nLoop > 0 ) nLoop = _rand(m_hActor->GetRoom())%nLoop;
std::string szAction = m_Data.m_AITable[state].VecActionTable[nIndex].szActionName;
if( strstr( szAction.c_str(), "Attack" ) )
{
m_vAILook = EtVec3toVec2( *m_hTarget->GetPosition() - *m_hActor->GetPosition() );
int nAdd = (_rand(m_hActor->GetRoom())%10)+0;
if( nTestCount++%2 )
nAdd *= -1;
m_bIsAILook = true;
m_vAILook.x = m_vAILook.x * cos( D3DXToRadian(nAdd)) - m_vAILook.y * sin( D3DXToRadian(nAdd) );
m_vAILook.y = m_vAILook.x * sin( D3DXToRadian(nAdd)) + m_vAILook.y * cos( D3DXToRadian(nAdd) );
EtVec2Normalize( &m_vAILook, &m_vAILook );
m_hActor->CmdAction( szAction.c_str(), nLoop, g_fBendFrame );
SetDelay( AIDelayType::Patrol, 5000 );
//g_Log.LogA( "<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>=%d\r\n", nAdd );
return;
}
}
}
}
#endif // #ifndef _FINAL_BUILD
void MAAiScript::OnAI(const char* szPrevAction, LOCAL_TIME time)
{
if( !m_bValidAI || m_hActor->IsDie() )
return;
EtVector3* pvPos = m_hActor->GetPosition();
FindTarget();
#ifndef _FINAL_BUILD
//return OnTestNaviAI( time );
//return OnTestAttackAI( time );
#endif
if ( m_pMonsterActor )
{
if ( m_pMonsterActor->OnPreAiProcess(szPrevAction, time) )
return;
}
int state = 0;
float fLength = 0.0f;
if( m_hTarget )
{
state = GetTargetDistanceState( m_hTarget );
#ifdef PRE_FIX_PARTSMONSTER_AI_TARGETTING
fLength = EtVec3Length( &( *pvPos - m_hTarget->FindAutoTargetPos() ) );
#else
fLength = EtVec3Length( &( *pvPos - *m_hTarget->GetPosition() ) );
#endif
}
if ( m_nState == AT_CustomAction )
{
if ( m_hActor->IsStay() && m_hActor->IsMovable() )
{
// if( m_hActor->GetLookTarget() != m_hTarget ) m_hActor->CmdLook(m_hTarget);
OnCustomAction(state, fLength, time);
}
return;
}
else if( m_nState == AT_Assault )
{
if( m_hActor->IsMove() )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD> AssaultTime <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if( time - m_ChangeStateTime >= m_Data.m_nAssaultTime )
{
m_hActor->CmdStop( "Stand" );
//g_Log.LogA( "AssaultTime <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD> <20>̵<EFBFBD> <20><><EFBFBD><EFBFBD>!!!\r\n" );
}
}
}
if( m_hTarget )
{
// Ÿ<><C5B8><EFBFBD><EFBFBD> <20>׾<EFBFBD><D7BE>ų<EFBFBD> <20>ʹ<EFBFBD> <20>ָ<EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ϰ<EFBFBD> <20><>ȸ<EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20><><EFBFBD><EFBFBD>.
if( m_hTarget->IsDie() || (m_pMonsterActor && fLength > m_pMonsterActor->GetCognizanceThreatRange()) )
{
SetTarget( CDnActor::Identity() );
// m_hActor->CmdLook(m_hTarget);
SetDelay( AIDelayType::Patrol, 0 );
return;
}
else
{
if ( state < 0 )
{
// g_Log.Log(_WARNING, L"<22><><EFBFBD>׷<EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>̰<EFBFBD> <20>ȸ¾<C8B8>..\n"); // <20><><EFBFBD><EFBFBD> <20>ּ<EFBFBD>ó<EFBFBD><C3B3><EFBFBD>մϴ<D5B4>
SetTarget( CDnActor::Identity() );
// m_hActor->CmdLook(m_hTarget);
SetDelay( AIDelayType::Patrol, 0 );
return;
}
}
// <20>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
if ( !(m_hActor->IsNaviMode()) && fLength <= 50.0f && m_hActor->IsMovable() )
{
const char *szCurAction = m_hActor->GetCurrentAction();
if( strcmp( szCurAction, "Move_Back" ) == NULL || strcmp( szCurAction, "Walk_Back" ) == NULL )
return;
std::string szAction;
int nBack = _rand(m_hActor->GetRoom())%2;
switch( nBack )
{
case 0: szAction = "Move_Back"; break;
case 1: szAction = "Walk_Back"; break;
}
if( m_hActor->IsExistAction( szAction.c_str() ) )
{
#if defined( PRE_FIX_MOVEBACK )
if ( m_hActor && m_hActor->IsMonsterActor() && m_pMonsterActor )
m_pMonsterActor->SetPrevMoveBack( true );
#endif
m_hActor->CmdAction( szAction.c_str(), 0, g_fBendFrame );
return;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( strstr( m_hActor->GetCurrentAction(), "Defense" ) )
{
m_nState = AT_Defense;
return;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ծ<EFBFBD><D4BE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20>ִٸ<D6B4>
if ( m_hActor->IsHit() && m_hActor->IsStiff() )
{
if ( m_Data.m_NonDownMeleeDamageActionTable.empty() == false || m_Data.m_NonDownRangeDamageActionTable.empty() == false )
{
m_nState = AT_Damage;
return;
}
}
bool bResult = m_hActor->IsProcessSkill();
if ( bResult == false )
{
for( UINT i=0 ; i<m_Data.m_AISkillProcessorTable.size() ; ++i )
{
const AISkillProcessor& at = m_Data.m_AISkillProcessorTable.at(i);
at.pMAAiProcessorManager->End();
}
}
else
{
for( UINT i=0 ; i<m_Data.m_AISkillProcessorTable.size() ; ++i )
{
const AISkillProcessor& at = m_Data.m_AISkillProcessorTable.at(i);
if( at.nSkillIndex == m_hActor->GetProcessSkill()->GetClassID() )
{
at.pMAAiProcessorManager->Process( m_hActor );
}
}
}
if ( m_hActor->IsStay() && m_hActor->IsMovable() )
{
// if( m_hActor->GetLookTarget() != m_hTarget )
// m_hActor->CmdLook(m_hTarget);
// <20><><EFBFBD>Ⱑ AI <20>б<EFBFBD><D0B1><EFBFBD>
OnDistanceState(state, fLength, time);
}
}
// Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><EEBDBD>
else
{
if( m_bEnableAggroProcess && m_pMonsterActor->GetAggroSystem() )
{
if( !static_cast<CDNMonsterAggroSystem*>(m_pMonsterActor->GetAggroSystem())->bIsInit() )
return;
}
#ifdef PRE_ADD_AI_NOAGGRO_STAND
if (m_Data.m_Type & ScriptData::eTypeBit::NoAggroStand)
{
if (m_hActor && m_hActor->IsMonsterActor())
{
if (m_hActor->IsMove())
m_hActor->CmdStop("Stand");
return;
}
}
#endif
if( m_pReceiver->GetAIState() == MAAiReceiver::Disable ) return;
if( _bDestinationProcess() )
return;
if ( IsDelay(AIDelayType::Patrol) )
return;
// NonTargetAI
bool bPatrol = false;
if( m_pMonsterActor )
bPatrol = m_pMonsterActor->OnAINonTarget();
if( bPatrol )
{
if ( m_Data.m_nPatrolBaseTime < 1 || m_Data.m_nPatrolRandTime < 1)
SetDelay( AIDelayType::Patrol, 5000 + _rand(m_hActor->GetRoom())%3000 );
else
SetDelay( AIDelayType::Patrol, m_Data.m_nPatrolBaseTime + _rand(m_hActor->GetRoom())%m_Data.m_nPatrolRandTime );
}
}
}
int MAAiScript::GetTargetDistanceState( DnActorHandle hTarget )
{
if( !hTarget )
return -1;
EtVector3 *pvPos = m_hActor->GetPosition();
#ifdef PRE_FIX_PARTSMONSTER_AI_TARGETTING
float fLengthSq = EtVec3LengthSq( &( *pvPos - hTarget->FindAutoTargetPos() ) );
#else
float fLengthSq = EtVec3LengthSq( &( *pvPos - *hTarget->GetPosition() ) );
#endif
#if defined( PRE_ADD_ACADEMIC )
if( m_hActor->IsMonsterActor() )
{
CDnMonsterActor* pMonster = static_cast<CDnMonsterActor*>(m_hActor.GetPointer());
if( pMonster->GetSummonerPlayerActor() )
{
fLengthSq -= pow((m_hActor->GetUnitSize()+hTarget->GetUnitSize())*1.f,2);
if( fLengthSq < 0.f )
fLengthSq = 0.f;
}
}
#endif // #if defined( PRE_ADD_ACADEMIC )
int nSize = (int)m_Data.m_AITable.size();
if ( nSize < 2 )
return -1;
if ( fLengthSq >= 0.0f && fLengthSq < m_Data.m_AITable[0].fNearValueSq )
return 0;
for ( int i = 0 ; i < nSize-1 ; i++ )
{
if ( fLengthSq >= m_Data.m_AITable[i].fNearValueSq && fLengthSq < m_Data.m_AITable[i+1].fNearValueSq )
return i+1;
}
return nSize - 1;
}
void MAAiScript::OnDistanceState(int state, float fLength, LOCAL_TIME time)
{
// Target <20>ʱ<EFBFBD>ȭ
m_cMultipleTarget.Reset();
switch(m_nState)
{
case AT_Normal: OnNormal(state, fLength, time); break;
case AT_Assault: OnAssault(state, fLength, time); break;
case AT_CustomAction: OnCustomAction(state, fLength, time); break;
case AT_Defense: OnDefense(state, fLength, time); break;
case AT_Damage: OnDamage(state, fLength, time); break;
case AT_UseSkill: OnUseSkill(state, fLength, time); break;
}
}
void MAAiScript::_CmdActionTable( const ActionTable* pTable, float fLength, int iLoop, ActionType State/*=AT_Normal*/ )
{
if( pTable->Type == ActionTableCommon::eType::Skill )
{
bool bResult = m_SkillAI.UseSkill( pTable->nLuaSkillIndex );
if ( bResult )
{
m_nState = AT_UseSkill;
return;
}
}
else
{
std::string szAction = pTable->szActionName;
_CmdAction(szAction.c_str(), fLength, iLoop);
}
m_nState = State;
}
void MAAiScript::_CmdFinishProcessSkill( LOCAL_TIME time )
{
DnSkillHandle hSkill = m_hActor->GetProcessSkill();
if( !hSkill )
return;
int nSkillID = hSkill->GetClassID();
m_hActor->ResetProcessSkill();
// <20><>Ŷ
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
Stream.Write( &nSkillID, sizeof(int) );
m_hActor->Send( eActor::SC_FINISH_PROCESSSKILL, &Stream );
}
void MAAiScript::OnAssault(int state, float fLength, LOCAL_TIME time)
{
int nIndex = m_nSeletedAssaultActionIndex;
if ( m_Data.m_AssaultActionTable.empty() || nIndex < 0 || nIndex >= (int)m_Data.m_AssaultActionTable.size() )
{
m_nState = AT_Normal;
return;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20>߿<EFBFBD> <20>ϳ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׼<EFBFBD><D7BC><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
int nLoop = m_Data.m_AssaultActionTable[nIndex].nLoop;
if( nLoop > 0 ) nLoop = _rand(m_hActor->GetRoom())%nLoop;
_CmdActionTable( &m_Data.m_AssaultActionTable[nIndex], fLength, nLoop );
}
int MAAiScript::SelectAction_Random(std::vector<ActionTable*>& AtArray, LOCAL_TIME time)
{
if ( AtArray.empty() )
return -1;
int nRateSum = 0;
int nCount = static_cast<int>(AtArray.size());
for( int i=0 ; i<nCount ; ++i )
nRateSum += AtArray[i]->nRate;
if( nRateSum == 0 )
return -1;
int nRand = _rand(m_hActor->GetRoom())%nRateSum;
int nSum = AtArray[0]->nRate;
int nIndex = (nCount-1);
for( int i=1 ; i<nCount ; ++i )
{
if( nRand < nSum )
{
nIndex = i-1;
break;
}
nSum += AtArray[i]->nRate;
}
#ifdef PRE_ADD_MONSTER_NORMAL_ACTION_PRIORITY
int nPriorityValue = 0;
for( int i=0 ; i<nCount ; ++i )
{
if( AtArray[i]->nActionPriority > nPriorityValue )
{
nPriorityValue = AtArray[i]->nActionPriority;
nIndex = i;
}
}
#endif
AtArray[nIndex]->nLastTime = time;
return AtArray[nIndex]->nIdx;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׼<EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1 <20><><EFBFBD>ϵȴ<CFB5>.
int MAAiScript::SelectAction(std::vector<ActionTable>& AtArray, LOCAL_TIME time)
{
std::vector<ActionTable*> UsableAT;
UsableAT.reserve( AtArray.size() );
for( UINT i=0 ; i<AtArray.size() ; ++i )
{
if( !m_hActor->IsLimitAction( AtArray[i].szActionName.c_str() ) && _bIsTargetActorChecker( AtArray[i] ) && IsPassedCoolTime(AtArray[i], time) && IsCheckedTargetCondition(AtArray[i], this->GetTarget()) && _bIsActorChecker( AtArray[i] ) )
{
UsableAT.push_back( &(AtArray[i]) );
}
}
return SelectAction_Random( UsableAT, time );
}
bool MAAiScript::_bIsActorChecker( const ActionTable& AT )
{
return AT.pMAAiCheckerManager->bIsActorChecker( m_hActor );
}
bool MAAiScript::_bIsTargetActorChecker( const ActionTable& AT )
{
return AT.pMAAiCheckerManager->bIsTargetActorChecker( m_hActor, m_hTarget );
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> return true <20>׿<EFBFBD> return false;
bool MAAiScript::_bDestinationProcess()
{
SOBB ChangeObb;
UINT uiMoveFrontRate = m_uiMoveFrontRate;
SOBB* pObb = m_pDestinationOBB;
#if defined( PRE_ADD_ACADEMIC )
if( m_Data.m_Type&ScriptData::eTypeBit::NoAggroOwnerFollow )
{
if( m_hActor->IsMonsterActor() )
{
CDnMonsterActor* pMonster = static_cast<CDnMonsterActor*>(m_hActor.GetPointer());
DnActorHandle hSummonerPlayerActor = pMonster->GetSummonerPlayerActor();
if( hSummonerPlayerActor )
{
ChangeObb.Center = *hSummonerPlayerActor->GetPosition();
ChangeObb.Axis[0] = EtVector3( 1.f, 0.f, 0.f );
ChangeObb.Axis[1] = EtVector3( 0.f, 1.f, 0.f );
ChangeObb.Axis[2] = EtVector3( 0.f, 0.f, 1.f );
ChangeObb.Extent[0] = ChangeObb.Extent[1] = ChangeObb.Extent[2] = 100.f;
// SummonerPlayer <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD>
pObb = &ChangeObb;
uiMoveFrontRate = 100;
DWORD dwCurTime = timeGetTime();
if( dwCurTime-m_dwDestinationOBB < 1000 )
return true;
m_dwDestinationOBB = dwCurTime;
}
}
}
#endif // #if defined( PRE_ADD_ACADEMIC )
if( pObb )
{
if( pObb->IsInside( *m_hActor->GetPosition() ) )
{
if( m_hActor->IsMove() )
m_hActor->CmdStop( "Stand" );
return true;
}
if( !m_hActor->IsMove() && m_hActor->IsMovable() )
{
UINT uiRandVal = _rand( m_hActor->GetRoom() )%100;
m_hActor->CmdMoveNavi( pObb->Center, 50.0f, (uiMoveFrontRate<=uiRandVal) ? "Walk_Front" : "Move_Front", -1, g_fBendFrame );
}
return true;
}
return false;
}
bool MAAiScript::IsPassedCoolTime(ActionTable& at, LOCAL_TIME time)
{
if( at.nLastTime == 0 || at.nLastTime + at.nCoolTime <= time )
return true;
return false;
}
bool MAAiScript::IsCheckedTargetCondition(ActionTable& at, DnActorHandle hTarget)
{
if ( at.szTargetCondition.empty() )
return true;
std::map<std::string, StateCondition>::iterator it = m_Data.m_StateContidionMap.find(at.szTargetCondition);
if ( it == m_Data.m_StateContidionMap.end() )
return true;
if ( !GetTarget() )
return false;
return (*it).second.Check( GetTarget() );
}
// m_hTarget <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD>(state)<29><> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void MAAiScript::GetTargetDistance( const int state, DNVector(DnActorHandle)& vTarget, bool bExceptAggroTarget/*=true*/ )
{
CDNAggroSystem* pAggroSystem = m_pMonsterActor->GetAggroSystem();
_ASSERT( pAggroSystem );
pAggroSystem->Convert( vTarget );
for( DNVector(DnActorHandle)::iterator itor=vTarget.begin() ; itor!=vTarget.end() ; )
{
DnActorHandle hTarget = (*itor);
if( !hTarget || (bExceptAggroTarget && hTarget == m_hTarget) || hTarget->IsDie() || GetTargetDistanceState( hTarget ) != state )
{
itor = vTarget.erase( itor );
continue;
}
++itor;
}
}
// m_hTarget <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD>(Min~Max)<29><> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void MAAiScript::GetTargetDistance( const int iMin, const int iMax, DNVector(DnActorHandle)& vTarget, bool bExceptAggroTarget/*=true*/ )
{
CDNAggroSystem* pAggroSystem = m_pMonsterActor->GetAggroSystem();
_ASSERT( pAggroSystem );
pAggroSystem->Convert( vTarget );
for( DNVector(DnActorHandle)::iterator itor=vTarget.begin() ; itor!=vTarget.end() ; )
{
DnActorHandle hTarget = (*itor);
if( !hTarget || (bExceptAggroTarget && hTarget == m_hTarget) || hTarget->IsDie() || !bIsTargetDistance( m_hActor, hTarget, iMin, iMax ) )
{
itor = vTarget.erase( itor );
continue;
}
++itor;
}
}
bool MAAiScript::bIsTargetDistance( DnActorHandle hActor, DnActorHandle hTarget, const int iMin, const int iMax )
{
if( !hActor || !hTarget )
return false;
bool bFindPosition = true;
float fLengthSq = EtVec3LengthSq( &( *hActor->GetPosition() - *hTarget->GetPosition() ) );
if( fLengthSq < iMin*iMin || fLengthSq > iMax*iMax )
bFindPosition = false;
#if defined( PRE_ADD_ACADEMIC )
if( hActor->IsMonsterActor() )
{
CDnMonsterActor* pMonster = static_cast<CDnMonsterActor*>(hActor.GetPointer());
// PartsMonster <20><> Collision <20><><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
if( pMonster->GetSummonerPlayerActor() && hTarget->IsPartsMonsterActor() )
{
if( hTarget->GetObjectHandle()->FindCollisionPrimitiveCenterInRange( (*hActor->GetPosition()), static_cast<float>(iMin), static_cast<float>(iMax) ) == true )
bFindPosition = true;
}
}
#endif // #if defined( PRE_ADD_ACADEMIC )
return bFindPosition;
}
// AIState <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> <20><><EFBFBD><EFBFBD>
void MAAiScript::_SelectRandomTarget( const int state, const float fRandomTarget )
{
if( fRandomTarget == 0.f )
return;
DNVector(DnActorHandle) vTarget;
GetTargetDistance( state, vTarget );
if( vTarget.empty() )
return;
DnActorHandle hPrevTarget = m_hTarget;
size_t uiRand = _rand(m_hActor->GetRoom())%vTarget.size();
ChangeTarget( vTarget[uiRand] );
if( fRandomTarget > 0.f )
{
CDNAggroSystem* pAggroSystem = m_hActor->GetAggroSystem();
CDNAggroSystem::AggroStruct* pPrevStruct = pAggroSystem->GetAggroStruct( hPrevTarget );
if( pPrevStruct )
{
CDNAggroSystem::AggroStruct* pStruct = pAggroSystem->GetAggroStruct( vTarget[uiRand] );
if( pStruct )
{
pStruct->iAggro = static_cast<int>(pPrevStruct->iAggro * fRandomTarget);
}
}
}
}
#if defined( PRE_ADD_LOTUSGOLEM )
void MAAiScript::_ProcessParts()
{
if( m_Data.m_AIPartsProcessor.empty() )
return;
if( m_hActor->IsPartsMonsterActor() == false )
{
_ASSERT(0);
return;
}
static_cast<CDnPartsMonsterActor*>(m_hActor.GetPointer())->ProcessPartsAI( m_Data.m_AIPartsProcessor );
}
#endif // #if defined( PRE_ADD_LOTUSGOLEM )
void MAAiScript::OnNormal(int state, float fLength, LOCAL_TIME time)
{
if( m_Data.m_AITable.empty() || state < 0 || state >= static_cast<int>(m_Data.m_AITable.size()) )
return;
// <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ <20>غ<EFBFBD><D8BA><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴٸ<CFB4> <20><>ų <20><><EFBFBD><EFBFBD> <20><><EFBFBD>·<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ع<EFBFBD><D8B9><EFBFBD><EFBFBD><EFBFBD>.
bool bResult = m_SkillAI.UseSkill();
if ( bResult )
{
m_nState = AT_UseSkill;
return;
}
int nIndex = SelectAction(m_Data.m_AITable[state].VecActionTable, time);
if( nIndex < 0 )
return;
_SelectRandomTarget( state, m_Data.m_AITable[state].VecActionTable[nIndex].fRandomTarget );
int nLoop = m_Data.m_AITable[state].VecActionTable[nIndex].nLoop;
if( nLoop > 0 ) nLoop = _rand(m_hActor->GetRoom())%nLoop;
std::string szAction = m_Data.m_AITable[state].VecActionTable[nIndex].szActionName;
m_Data.m_nMinAttackMissRadian = m_Data.m_AITable[state].VecActionTable[nIndex].nMinAttackMissRadian;
m_Data.m_nMaxAttackMissRadian = m_Data.m_AITable[state].VecActionTable[nIndex].nMaxAttackMissRadian;
if ( szAction == "Assault" )
{
if ( m_Data.m_AssaultActionTable.empty() )
return;
nIndex = SelectAction(m_Data.m_AssaultActionTable, time);
if( nIndex < 0 )
return;
m_nState = AT_Assault;
m_ChangeStateTime = time;
m_nSeletedAssaultActionIndex = nIndex;
float fApproach = m_Data.m_AssaultActionTable[m_nSeletedAssaultActionIndex].fApproach;
// <20>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD><CFB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD>ŭ<EFBFBD><C5AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
m_hActor->CmdMove( m_hTarget, fApproach, "Move_Front", -1, g_fBendFrame );
//g_Log.LogA( "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>!!!\r\n" );
return;
}
if ( szAction.find("CustomAction") < szAction.size() )
{
// Ŀ<><C4BF><EFBFBD><EFBFBD> <20>׼<EFBFBD><D7BC≯<EFBFBD>
if ( _FindCustomAction(szAction.c_str(), m_Data.m_CurrentCustomActionTable ) )
{
// OutputDebug("Ŀ<><C4BF><EFBFBD>Ҿ׼<D2BE> : %s\n", szAction.c_str());
m_Data.m_nCurrentCustomActionPlayIndex = 0;
m_nState = AT_CustomAction;
return;
}
}
// MultipleŸ<65><C5B8> <20>׼<EFBFBD> <20><><EFBFBD><EFBFBD>
m_cMultipleTarget.SetMultipleTargetAction( &m_Data.m_AITable[state].VecActionTable[nIndex] );
_CmdAction(szAction.c_str(), fLength, nLoop);
#if defined( PRE_FIX_68096 )
for( int i=0;i<ActionTableCommon::eCommon::MaxGlobalCoolTime;i++ )
{
int iGlobalCoolTimeIndex = m_Data.m_AITable[state].VecActionTable[nIndex].iGlobalCoolTimeIndex[i];
DWORD dwTime = timeGetTime();
if( iGlobalCoolTimeIndex >= 0 )
{
if( iGlobalCoolTimeIndex < static_cast<int>(GetScriptData().m_AIGlobalCoolTime.size()) )
m_GlobalCoolTime.AddCoolTime( iGlobalCoolTimeIndex, dwTime+(GetScriptData().m_AIGlobalCoolTime[iGlobalCoolTimeIndex].dwCoolTime ) );
else
_ASSERT(0);
}
}
#else
int iGlobalCoolTimeIndex = m_Data.m_AITable[state].VecActionTable[nIndex].iGlobalCoolTimeIndex;
DWORD dwTime = timeGetTime();
if( iGlobalCoolTimeIndex >= 0 )
{
if( iGlobalCoolTimeIndex < static_cast<int>(GetScriptData().m_AIGlobalCoolTime.size()) )
m_GlobalCoolTime.AddCoolTime( iGlobalCoolTimeIndex, dwTime+(GetScriptData().m_AIGlobalCoolTime[iGlobalCoolTimeIndex].dwCoolTime ) );
else
_ASSERT(0);
}
#endif
}
void MAAiScript::_CmdAction(const char* szAction, float fLength, int nLoop)
{
// if( m_hActor->GetLookTarget() != m_hTarget ) m_hActor->CmdLook( m_hTarget );
if( strstr( szAction, "Front" ) )
{
if ( !m_hTarget )
return;
float fAttackDist = m_hTarget->GetUnitSize() + m_hActor->GetUnitSize() + ( ( m_hActor->GetWeapon() ) ? m_hActor->GetWeapon()->GetWeaponLength() : 0.f );
if( fLength <= fAttackDist )
return;
//m_hActor->CmdLook( m_hTarget, false );
m_hActor->CmdMove( m_hTarget, m_Data.m_fApproachValue, szAction, nLoop, g_fBendFrame);
}
else if( strstr( szAction, "Attack" ) )
{
// MissAttack
if( m_hTarget && m_Data.m_nMaxAttackMissRadian > 0 )
{
m_vAILook = EtVec3toVec2( *m_hTarget->GetPosition() - *m_hActor->GetPosition() );
// Miss <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
int nRadian = (_rand(m_hActor->GetRoom())%(m_Data.m_nMaxAttackMissRadian-m_Data.m_nMinAttackMissRadian+1))+m_Data.m_nMinAttackMissRadian;
if( _rand(m_hActor->GetRoom())%2 )
nRadian *= -1;
// AILook <20><><EFBFBD><EFBFBD>
m_bIsAILook = true;
m_vAILook.x = m_vAILook.x * cos( D3DXToRadian(nRadian)) - m_vAILook.y * sin( D3DXToRadian(nRadian) );
m_vAILook.y = m_vAILook.x * sin( D3DXToRadian(nRadian)) + m_vAILook.y * cos( D3DXToRadian(nRadian) );
EtVec2Normalize( &m_vAILook, &m_vAILook );
m_strAILookAction = szAction;
//g_Log.LogA( "MissAttack : %s Radian=%d\r\n", szAction, nRadian );
}
m_hActor->CmdAction( szAction, nLoop, g_fBendFrame );
}
else
{
// if( m_hActor->GetLookTarget() != m_hTarget )
// m_hActor->CmdLook( m_hTarget );
m_hActor->CmdAction(szAction, nLoop , g_fBendFrame);
}
}
void MAAiScript::OnCustomAction(int state, float fLength, LOCAL_TIME time)
{
if ( m_Data.m_nCurrentCustomActionPlayIndex == -1 )
return;
// Ŀ<><C4BF><EFBFBD><EFBFBD> <20>׼<EFBFBD><D7BC><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><20><><EFBFBD>·<EFBFBD> <20>ٲ<EFBFBD><D9B2>ش<EFBFBD>.
if ( m_Data.m_nCurrentCustomActionPlayIndex >= (int)m_Data.m_CurrentCustomActionTable.m_ActionList.size() )
{
m_nState = AT_Normal;
m_Data.m_nCurrentCustomActionPlayIndex = -1;
return;
}
std::string szCurAction = m_Data.m_CurrentCustomActionTable.m_ActionList[m_Data.m_nCurrentCustomActionPlayIndex].szActionName;
int nCount = m_Data.m_CurrentCustomActionTable.m_ActionList[m_Data.m_nCurrentCustomActionPlayIndex].nLoop;
//m_hActor->CmdAction(szCurAction.c_str(), nCount);
if( stricmp( szCurAction.c_str(), "useskill") == 0 )
{
m_SkillAI.UseSkill( m_Data.m_CurrentCustomActionTable.m_ActionList[m_Data.m_nCurrentCustomActionPlayIndex].nLuaSkillIndex );
}
else
{
_CmdAction(szCurAction.c_str(), fLength, nCount);
}
m_Data.m_nCurrentCustomActionPlayIndex++;
/*
for ( int i = 0 ; i < (int)m_Data.m_CurrentCustomActionTable.m_ActionList.size() ; i++ )
{
OutputDebug("CustomAction : %s, %d<><64> ", m_Data.m_CurrentCustomActionTable.m_ActionList[i].szActionName.c_str(),
m_Data.m_CurrentCustomActionTable.m_ActionList[i].nLoop );
}
OutputDebug("\n");
OutputDebug("Play OnCustomAction : %s[%d] \n", szCurAction.c_str(), nCount);
*/
}
void MAAiScript::OnDefense(int state, float fLength, LOCAL_TIME time)
{
if ( m_Data.m_MeleeDefenseActionTable.empty() && m_Data.m_RangeDefenseActionTable.empty() )
{
m_nState = AT_Normal;
return;
}
CDnDamageBase::SHitParam* pHitParam = m_hActor->GetHitParam();
if( !pHitParam )
{
m_nState = AT_Normal;
return;
}
std::vector<ActionTable>* pDefenseTable = NULL;
if ( pHitParam->DistanceType == CDnDamageBase::DistanceTypeEnum::Range )
pDefenseTable = &(m_Data.m_RangeDefenseActionTable);
else
pDefenseTable = &(m_Data.m_MeleeDefenseActionTable);
if( pDefenseTable->empty() )
{
m_nState = AT_Normal;
return;
}
std::vector<ActionTable>& DefenseTable = *pDefenseTable;
int nIndex = SelectAction(DefenseTable, time);
if( nIndex < 0 )
{
m_nState = AT_Normal;
return;
}
int nLoop = DefenseTable[nIndex].nLoop;
if( nLoop > 0 ) nLoop = _rand(m_hActor->GetRoom())%nLoop;
_CmdActionTable( &DefenseTable[nIndex], fLength, nLoop );
}
void MAAiScript::OnDamage(int state, float fLength, LOCAL_TIME time)
{
if ( m_Data.m_NonDownMeleeDamageActionTable.empty() && m_Data.m_NonDownRangeDamageActionTable.empty() )
{
m_nState = AT_Normal;
return;
}
CDnDamageBase::SHitParam* pHitParam = m_hActor->GetHitParam();
if( !pHitParam )
{
m_nState = AT_Normal;
return;
}
std::vector<ActionTable>* pDefenseTable = NULL;
if ( pHitParam->DistanceType == CDnDamageBase::DistanceTypeEnum::Range )
pDefenseTable = &(m_Data.m_NonDownRangeDamageActionTable);
else
pDefenseTable = &(m_Data.m_NonDownMeleeDamageActionTable);
if ( pDefenseTable->empty() )
{
m_nState = AT_Normal;
return;
}
std::vector<ActionTable>& DefenseTable = *pDefenseTable;
int nIndex = SelectAction(DefenseTable, time);
if( nIndex < 0 )
{
m_nState = AT_Normal;
return;
}
int nLoop = DefenseTable[nIndex].nLoop;
if( nLoop > 0 ) nLoop = _rand(m_hActor->GetRoom())%nLoop;
_CmdActionTable( &DefenseTable[nIndex], fLength, nLoop );
}
void MAAiScript::OnHitFinish( LOCAL_TIME LocalTime, HitStruct *pStruct )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Hit <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><> AI <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> BeHitSkill <20>ۿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƴϸ<C6B4> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
if( !m_hActor->IsProcessSkill() )
return;
std::vector<ActionTable>* pBeHitSkillTable = &m_Data.m_BeHitSkillActionTable;
if( pBeHitSkillTable->empty() )
return;
std::vector<ActionTable> SelectTable;
for( UINT i=0 ; i<pBeHitSkillTable->size() ; ++i )
{
const ActionTable& t = pBeHitSkillTable->at(i);
if( t.nBeHitSkillIndex == m_hActor->GetProcessSkill()->GetClassID() )
SelectTable.push_back( t );
}
if( SelectTable.empty() )
return;
int nIndex = SelectAction( SelectTable, LocalTime );
if( nIndex < 0 )
return;
#if defined( PRE_FIX_HITFINISH )
for( UINT i=0 ; i<SelectTable.size() ; ++i )
{
if( nIndex == SelectTable[i].nIdx )
{
nIndex = i;
break;
}
}
if( nIndex >= SelectTable.size() )
return;
#endif
if( SelectTable[nIndex].Type == ActionTableCommon::eType::Skill )
m_hActor->OnFinishAction( m_hActor->GetCurrentAction(), LocalTime );
_CmdFinishProcessSkill( LocalTime );
_CmdActionTable( &SelectTable[nIndex], 0.f, 0, AT_UseSkill );
}
void MAAiScript::OnUseSkill(int state, float fLength, LOCAL_TIME time)
{
bool bResult = m_hActor->IsProcessSkill();
if ( bResult == false )
{
for( UINT i=0 ; i<m_Data.m_AISkillProcessorTable.size() ; ++i )
{
const AISkillProcessor& at = m_Data.m_AISkillProcessorTable.at(i);
at.pMAAiProcessorManager->End();
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٷ<EFBFBD> <20>̾ <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
if( m_SkillAI.GetNextLuaSkillIndex() >= 0 )
{
m_SkillAI.UseSkill( m_SkillAI.GetNextLuaSkillIndex() );
return;
}
m_nState = AT_Normal;
}
else
{
for( UINT i=0 ; i<m_Data.m_AISkillProcessorTable.size() ; ++i )
{
const AISkillProcessor& at = m_Data.m_AISkillProcessorTable.at(i);
if( at.nSkillIndex == m_hActor->GetProcessSkill()->GetClassID() )
{
at.pMAAiProcessorManager->Process( m_hActor );
}
}
}
}
void MAAiScript::OnBeginNaviMode( const char* szPrevAction, const bool bPrevIsMove )
{
DnActorHandle hTarget = GetTarget();
if( !m_hActor->IsNaviMode() && hTarget && bPrevIsMove && (strstr( szPrevAction, "Front" )||strstr( szPrevAction, "Back")) )
{
const char* pszActionName = "Walk_Front";
if( m_hActor->IsExistAction( pszActionName) )
{
m_hActor->CmdMoveNavi( hTarget, 50.0f, pszActionName, -1, g_fBendFrame );
}
else
{
_ASSERT(0);
}
}
}
void MAAiScript::AICmdMsgProc( const UINT uiMsg, void* pParam )
{
if( !m_pAICommand )
{
_DANGER_POINT();
return;
}
m_pAICommand->MsgProc( this, uiMsg, pParam );
}
bool MAAiScript::_FindCustomAction(const char* szCustomActionName, OUT CustomActionTable& table)
{
std::map<std::string, CustomActionTable>::iterator it = m_Data.m_CustomActionMap.find(std::string(szCustomActionName));
if ( it == m_Data.m_CustomActionMap.end() )
return false;
table = it->second;
return true;
}
bool MAAiScript::LoadScript(const char* szFilename)
{
m_bValidAI = g_AiScriptLoader.GetScript(szFilename, m_Data);
if ( !m_bValidAI )
return false;
#if defined(PRE_ADD_64990)
int nType = 0;
CDNGameRoom *pRoom = m_hActor->GetGameRoom();
if( pRoom && pRoom->bIsPvPRoom() )
nType = 1;
m_SkillAI.Initialize(&(m_Data.m_SkillTable[nType]), m_hActor);
#else
m_SkillAI.Initialize(&(m_Data.m_SkillTable), m_hActor);
#endif // PRE_ADD_64990
return m_bValidAI;
}
void MAAiScript::ReloadAllScript()
{
g_AiScriptLoader.AllLoadScript();
}
// STE_ProjectileTargetPosition <20>ñ׳<C3B1> ȣ<><C8A3> <20>Ǿ<EFBFBD><C7BE><EFBFBD> <20><> ȣ<><C8A3>
void MAAiScript::_OnSetProjectileTarget()
{
m_cMultipleTarget.CalcTarget( m_hActor, this );
}