l2-unlegits/l2ooghelper/L2ClientAI.cpp
2012-02-01 05:25:08 +00:00

198 lines
4.2 KiB
C++

#include "stdafx.h"
#include "Logger.h"
#include "L2ClientAI.h"
AI_INTENTION::AI_INTENTION()
{
m_type = INT_TYPE_NONE;
m_npcdlg_string[0] = 0;
}
AI_INTENTION::AI_INTENTION( const AI_INTENTION& other )
{
m_npcdlg_string[0] = 0;
operator=( other );
}
const AI_INTENTION& AI_INTENTION::operator=( const AI_INTENTION& other )
{
if( this == &other ) return (*this);
m_type = other.m_type;
m_x = other.m_x; m_y = other.m_y; m_z = other.m_z;
m_target_oid = other.m_target_oid;
wcsncpy( m_npcdlg_string, other.m_npcdlg_string, sizeof(m_npcdlg_string)/2 );
return (*this);
}
void AI_INTENTION::set_GOTO( int x, int y, int z )
{
m_type = INT_TYPE_GOTO;
m_x = x; m_y = y; m_z = z;
}
void AI_INTENTION::set_ATTACK( unsigned int target_oid )
{
m_type = INT_TYPE_ATTACK;
m_target_oid = target_oid;
}
void AI_INTENTION::set_NPC_TALK( unsigned int npc_oid, const wchar_t *dlg_str )
{
m_type = INT_TYPE_NPC_TALK;
m_target_oid = npc_oid;
wcsncpy( m_npcdlg_string, dlg_str, 255 ); m_npcdlg_string[255] = 0;
}
AiIntentionQueue::AiIntentionQueue()
{
m_q.clear();
}
AiIntentionQueue::~AiIntentionQueue()
{
m_q.clear();
}
void AiIntentionQueue::pushIntention( AI_INTENTION i )
{
m_q.push_back( i );
}
AI_INTENTION AiIntentionQueue::getIntention()
{
AI_INTENTION i = *m_q.begin();
m_q.pop_front();
return i;
}
bool AiIntentionQueue::hasIntentions() const
{
return m_q.size() > 0;
}
L2ClientAI::L2ClientAI( IL2Client *pinterfaceL2Client )
{
m_cl = pinterfaceL2Client;
m_last_think_time = GetTickCount() - THINK_DELAY - THINK_DELAY;
m_last_follow_time = m_last_think_time;
m_follow_enabled = false;
m_follow_oid = 0;
}
L2ClientAI::~L2ClientAI()
{
}
void L2ClientAI::think()
{
unsigned int t_now = (unsigned int)GetTickCount();
if( t_now - m_last_think_time < THINK_DELAY ) return;
m_last_think_time = t_now;
// check for follow
follow();
// check for intentions
if( !m_int_queue.hasIntentions() )
{
//log_error( LOG_USERAI, "L2ClientAI:think: no intentions" );
return;
}
AI_INTENTION i = m_int_queue.getIntention();
switch( i.getType() )
{
case INT_TYPE_NONE: break;
case INT_TYPE_GOTO: onIntentionGoto( i ); break;
case INT_TYPE_ATTACK: onIntentionAttack( i ); break;
case INT_TYPE_NPC_TALK: onIntentionNpcTalk( i ); break;
}
}
void L2ClientAI::setFollow( bool enable, unsigned int oid )
{
m_follow_enabled = enable;
m_follow_oid = oid;
}
void L2ClientAI::pushIntentionGoto( int x, int y, int z )
{
AI_INTENTION i;
i.set_GOTO( x, y, z );
m_int_queue.pushIntention( i );
}
void L2ClientAI::pushIntentionAttack( unsigned int target_oid )
{
AI_INTENTION i;
i.set_ATTACK( target_oid );
m_int_queue.pushIntention( i );
}
void L2ClientAI::pushIntentionNpcTalk( unsigned int npc_oid, const wchar_t *dlg_str )
{
AI_INTENTION i;
i.set_NPC_TALK( npc_oid, dlg_str );
m_int_queue.pushIntention( i );
}
void L2ClientAI::follow()
{
if( m_follow_enabled == false ) return;
UserInfo *user = m_cl->get_UserInfo();
CharArray *chars = m_cl->get_WorldChars();
int char_idx = chars->FindCharByObjectID( m_follow_oid );
if( char_idx >= 0 )
{
L2Player *target = chars->chars_array[char_idx];
// compare coordinates
int dx = target->x - user->x;
int dy = target->y - user->y;
int dz = target->z - user->z;
if( abs(dx) > 50 || abs(dy) > 50 || abs(dz) > 50 )
{
unsigned int t_now = (unsigned int)GetTickCount();
if( t_now - m_last_follow_time >= 1000 )
{
m_last_follow_time = t_now;
m_cl->game_MoveBackwardToLocation( target->x, target->y, target->z );
log_error( LOG_USERAI, "L2ClientAI:follow: following [%S] to (%d,%d,%d)\n", target->charName, target->x, target->y, target->z );
}
}
}
else // target not found in world
{
setFollow( false, 0 );
log_error( LOG_USERAI, "L2ClientAI:follow: target not found, cancel follow\n" );
}
}
void L2ClientAI::onIntentionGoto( AI_INTENTION& wish )
{
(void)wish;
}
void L2ClientAI::onIntentionAttack( AI_INTENTION& wish )
{
(void)wish;
}
void L2ClientAI::onIntentionNpcTalk( AI_INTENTION& wish )
{
(void)wish;
}