1076 lines
29 KiB
C++
1076 lines
29 KiB
C++
#include "stdafx.h"
|
|
#include "SGame.h"
|
|
#include "SSkillSlot.h"
|
|
#include "SSkillDB.h"
|
|
//#include "SGameMessageUI.h"
|
|
#include "SDebug_Util.h"
|
|
|
|
#define CREATURE_CONTROL_SKILL 1801
|
|
|
|
SSkillSlot::SSkillSlot()
|
|
: m_hTarget ( 0 )
|
|
, m_hSkillCard ( 0 )
|
|
, m_bCasting ( false )
|
|
, m_bFire ( false )
|
|
, m_dwBeginTime ( 0 )
|
|
, m_nUseLevel ( 0 )
|
|
, m_nAddedLevel ( 0 )
|
|
{
|
|
memset( &m_SkillData, 0, sizeof( m_SkillData ) );
|
|
ReInit();
|
|
}
|
|
|
|
SSkillSlot::~SSkillSlot()
|
|
{
|
|
|
|
}
|
|
|
|
void SSkillSlot::ReInit()
|
|
{
|
|
m_dwCoolTime = 0;
|
|
m_dwStartTime = 0;
|
|
m_bUse = FALSE;
|
|
}
|
|
|
|
void SSkillSlot::SetUse( BOOL bUse )
|
|
{
|
|
m_bUse = bUse;
|
|
m_dwStartTime = 0;
|
|
|
|
if( m_bUse )
|
|
m_dwCoolTime = GetCoolingTime();
|
|
}
|
|
|
|
void SSkillSlot::SetSkill( SMSG_SKILL_LIST::SkillInfo & skill_data )
|
|
{
|
|
m_SkillData = skill_data;
|
|
m_nUseLevel = skill_data.current_skill_level;
|
|
}
|
|
|
|
void SSkillSlot::SetSkill( SMSG_SKILL_LIST::SkillInfo & skill_data, AR_TIME coolTime )
|
|
{
|
|
m_SkillData = skill_data;
|
|
m_nUseLevel = skill_data.current_skill_level;
|
|
m_SkillData.total_cool_time = coolTime;
|
|
}
|
|
|
|
const DWORD SSkillSlot::GetCoolingTime()
|
|
{
|
|
return static_cast< DWORD >( m_SkillData.total_cool_time * 10 );
|
|
}
|
|
|
|
void SSkillSlot::Process( DWORD dwTime )
|
|
{
|
|
/* if( !m_bUse ) return;
|
|
|
|
if( m_dwStartTime == 0 )
|
|
{
|
|
m_dwStartTime = dwTime;
|
|
return;
|
|
}
|
|
|
|
if( ( dwTime - m_dwStartTime ) >= m_dwCoolTime )
|
|
{
|
|
// _oprint( "쿨링 끝 : %d\n", m_SkillData.skill_id );
|
|
SetUse( FALSE );
|
|
}
|
|
|
|
// 남은 시간 계산 : // 인터페이스에서 사용
|
|
if( m_bFire )
|
|
{
|
|
DWORD dwCurTime = dwTime - m_dwBeginTime;
|
|
if( dwCurTime >= GetCoolingTime() )
|
|
{
|
|
SetFire(false);
|
|
// 인터페이스에 알려준다
|
|
ProcMsgAtStatic( &SIMSG_UI_SKILL_TIME_UPDATE( m_hTarget, m_SkillData.skill_id ) );
|
|
}
|
|
}*/
|
|
}
|
|
|
|
void SSkillSlot::setBeginTime(DWORD dwTime, AR_TIME totalCoolTime, AR_TIME remainCoolTime)
|
|
{
|
|
SetBeginTime( dwTime-((totalCoolTime-remainCoolTime)*10) );
|
|
}
|
|
|
|
SAddedSkillInfo::SAddedSkillInfo()
|
|
: m_hTarget ( 0 )
|
|
{
|
|
memset( &m_SkillData, 0, sizeof( m_SkillData ) );
|
|
}
|
|
|
|
SAddedSkillInfo::~SAddedSkillInfo()
|
|
{
|
|
|
|
}
|
|
|
|
void SAddedSkillInfo::SetAddedSkill( SMSG_ADDED_SKILL_LIST::AddedSkillInfo & skill_data )
|
|
{
|
|
m_SkillData = skill_data;
|
|
}
|
|
|
|
int SAddedSkillInfo::GetLevel(int SkillId, AR_HANDLE hTarget)
|
|
{
|
|
if( m_hTarget == hTarget)
|
|
{
|
|
if ( m_SkillData.restricted_to_type == true )
|
|
{
|
|
SkillBaseEx* s_data = GetSkillDB().GetSkillData( SkillId );
|
|
|
|
/// 2011.03.15 예외 처리- prodongi
|
|
if (!s_data)
|
|
return 0;
|
|
|
|
// AziaMafia Skill ++
|
|
//if (s_data->skill_lvup_limit)
|
|
//return 0;
|
|
|
|
int skill_type = 0;
|
|
|
|
// 스킬 타입 정의
|
|
if( s_data->IsHarmful() ) skill_type += StateInfo::FLAG_HARMFUL;
|
|
else skill_type += StateInfo::FLAG_HELPFUL;
|
|
if( s_data->IsPassive() ) skill_type += StateInfo::FLAG_PASSIVE;
|
|
else skill_type += StateInfo::FLAG_ACTIVE;
|
|
if( s_data->IsPhysicalSkill() ) skill_type += StateInfo::FLAG_PHYSICAL;
|
|
else skill_type += StateInfo::FLAG_MAGICAL;
|
|
|
|
if( m_SkillData.skill_id & skill_type )
|
|
{
|
|
// AziaMafia Skill ++
|
|
if (s_data->skill_lvup_limit) return 0;
|
|
|
|
return m_SkillData.added_skill_level;
|
|
}
|
|
}
|
|
else if ( SkillId == m_SkillData.skill_id)
|
|
{
|
|
return m_SkillData.added_skill_level;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//SSkillSlotMgr
|
|
// MJ 2005/04/01
|
|
// 플레이어의 스킬 매니저
|
|
//
|
|
|
|
SSkillSlotMgr::SSkillSlotMgr()
|
|
: SGameUIMgr() // 2011.03.29 - servantes
|
|
{
|
|
Init();
|
|
}
|
|
|
|
SSkillSlotMgr::~SSkillSlotMgr()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void SSkillSlotMgr::ResetInfo()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void SSkillSlotMgr::Init()
|
|
{
|
|
m_nCurUseSkill = -1;
|
|
m_dwTime = 0;
|
|
tLastTimeUsed = 0;
|
|
}
|
|
|
|
void SSkillSlotMgr::Destroy()
|
|
{
|
|
SKILL_VECTOR::iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SAFE_DELETE( (*it) );
|
|
it = m_vecSkillSlotList.erase( it );
|
|
}
|
|
|
|
m_dwTime = 0;
|
|
|
|
m_nCurUseSkill = -1;
|
|
m_nCoolingSkill.clear();
|
|
}
|
|
|
|
void SSkillSlotMgr::ResetSkill()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void SSkillSlotMgr::ResetAddedSkill()
|
|
{
|
|
ADDED_SKILL_VECTOR::iterator it = m_vecAddedSkillList.begin();
|
|
while( it != m_vecAddedSkillList.end() )
|
|
{
|
|
SAFE_DELETE( (*it) );
|
|
it = m_vecAddedSkillList.erase( it );
|
|
}
|
|
}
|
|
|
|
void SSkillSlotMgr::Process( DWORD dwTime )
|
|
{
|
|
m_dwTime = dwTime;
|
|
|
|
//쿨 타임 검사
|
|
|
|
SKILL_VECTOR::iterator iter = m_vecSkillSlotList.begin();
|
|
for( ; iter != m_vecSkillSlotList.end(); ++iter )
|
|
{
|
|
SSkillSlot* pSlot = (*iter);
|
|
|
|
if( pSlot->IsUse() == false ) continue;
|
|
|
|
if( pSlot->m_dwStartTime == 0 )
|
|
{
|
|
pSlot->m_dwStartTime = dwTime;
|
|
continue;
|
|
}
|
|
|
|
if( ( dwTime - pSlot->m_dwStartTime ) >= pSlot->m_dwCoolTime )
|
|
{
|
|
pSlot->SetUse( FALSE );
|
|
}
|
|
|
|
// 남은 시간 계산 : // 인터페이스에서 사용
|
|
if( pSlot->m_bFire )
|
|
{
|
|
DWORD dwCurTime = dwTime - pSlot->m_dwBeginTime;
|
|
if( dwCurTime >= pSlot->GetCoolingTime() )
|
|
{
|
|
pSlot->SetFire(false);
|
|
|
|
pSlot->SetRemainTime(0);
|
|
// 인터페이스에 알려준다
|
|
ProcMsgAtStatic( &SIMSG_UI_SKILL_TIME_UPDATE( pSlot->m_hTarget, pSlot->m_SkillData.skill_id ) );
|
|
}
|
|
}
|
|
|
|
/// 2011.04.18 쿨타임을 초기화 하는 스킬을 사용 했을 때, 쿨타임이 초기화된 스킬을 실제적으로 use = false로
|
|
/// 설정하기 위한 부분(해당 조건들이 맞는지 확실히 모르겠음,,)- prodongi
|
|
if (!pSlot->m_bFire && pSlot->IsUse() && 0 == pSlot->m_SkillData.remain_cool_time)
|
|
{
|
|
pSlot->SetUse( FALSE );
|
|
}
|
|
|
|
if( !pSlot->IsUse() )
|
|
{
|
|
//종료 되었으면, Cooling List에서 제거
|
|
DelCooling( pSlot->GetSkillID(), pSlot->GetTarget() );
|
|
}
|
|
}
|
|
}
|
|
|
|
void SSkillSlotMgr::AddAddedSkill(SMSG_ADDED_SKILL_LIST::AddedSkillInfo & skill_data, AR_HANDLE hTarget)
|
|
{
|
|
SAddedSkillInfo * pInfo = new SAddedSkillInfo;
|
|
pInfo->SetAddedSkill( skill_data );
|
|
pInfo->SetTarget( hTarget );
|
|
|
|
m_vecAddedSkillList.push_back( pInfo );
|
|
}
|
|
|
|
void SSkillSlotMgr::AddSkill( DWORD dwTime, SMSG_SKILL_LIST::SkillInfo & skill_data, AR_HANDLE hTarget, int modificationType )
|
|
{
|
|
// _oprint( "Skill List - Code : %d, Cnt : %d\n", skill_data.skill_id, m_vecSkillSlotList.size() );
|
|
|
|
unsigned int nSkillSlotSize = m_vecSkillSlotList.size();
|
|
for( unsigned int i(0); nSkillSlotSize>i; ++i )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetSkillID() == skill_data.skill_id )
|
|
{
|
|
/// 2012.01.31 걸려있는 다른 스킬의 쿨타임 감소 효과가 사라질 때,
|
|
/// 이 스킬의 전체 쿨타임 값이 쿨타임 감소 효과가 사라진 값으로 서버에서 받고 있다.
|
|
/// 쿨타임 감소 효과가 사라지더라도, 한번 적용된 전체 쿨타임 시간은 변하지 말아야 되는데, 서버에서는 이전 전체 쿨타임 시간을
|
|
/// 알 수 없기 때문에 클라이언트에서 스킬이 업데이트 될 때에는 이전 전체 쿨타임 시간을 세팅해 준다.
|
|
/// (발동 할 때는 감소된 쿨타임 시간이 적용되어 있기 때문에 서버에서 받은 값을 쓴다.) - prodongi
|
|
AR_TIME total_cool_time = skill_data.total_cool_time;
|
|
if (SMSG_SKILL_LIST::UPDATE == modificationType)
|
|
{
|
|
if (skill_data.total_cool_time != skill_data.remain_cool_time)
|
|
total_cool_time = m_vecSkillSlotList[i]->GetCoolingTime()/10;
|
|
}
|
|
|
|
m_vecSkillSlotList[i]->SetSkill(skill_data, total_cool_time);
|
|
m_vecSkillSlotList[i]->SetCasting( false );
|
|
//이미 1렙이라도 올린 스킬을 사용하여 쿨타임 중인데 스킬을 올릴 경우도 있기 때문에 필히 쿨타임중인지 쎄팅해줘야 한다.
|
|
m_vecSkillSlotList[i]->SetFire( (skill_data.remain_cool_time > 0) ? true : false );
|
|
/// 2011.03.16 - prodongi
|
|
if (m_vecSkillSlotList[i]->IsFire())
|
|
{
|
|
/// 2012.02.28 SetBeginTime -> setBeginTime으로 변경 - prodongi
|
|
m_vecSkillSlotList[i]->setBeginTime(dwTime, total_cool_time, skill_data.remain_cool_time);
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
SSkillSlot * pSlot = new SSkillSlot;
|
|
pSlot->SetSkill( skill_data ); // 1/100, -> 1/1000 변환
|
|
pSlot->SetCasting( false );
|
|
pSlot->SetFire( false );
|
|
pSlot->SetTarget( hTarget );
|
|
pSlot->SetAddedLevel( 0 );
|
|
//이미 쿨링 중인 스킬은 쿨링리스트에 추가 한다.
|
|
if( skill_data.remain_cool_time > 0 )
|
|
{
|
|
pSlot->SetUse(TRUE); //순서 있음
|
|
/// 2012.02.28 SetBeginTime -> setBeginTime으로 변경 - prodongi
|
|
pSlot->setBeginTime(dwTime, skill_data.total_cool_time, skill_data.remain_cool_time);
|
|
pSlot->SetFire( true );
|
|
m_nCoolingSkill.push_back( skill_data.skill_id );
|
|
// _oprint( "이미 쿨링 중인 스킬이 있을까마는..\n" );
|
|
}
|
|
|
|
m_vecSkillSlotList.push_back( pSlot );
|
|
}
|
|
void SSkillSlotMgr::DelSkill( int nSkillCode, AR_HANDLE hTarget )
|
|
{
|
|
unsigned int nSkillSlotSize = m_vecSkillSlotList.size();
|
|
for( unsigned int i(0); nSkillSlotSize>i; i++ )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetSkillID() == nSkillCode && m_vecSkillSlotList[i]->GetTarget() == hTarget )
|
|
{
|
|
m_vecSkillSlotList[i]->ReInit();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//서버에 스킬을 요청하기 전에, 타겟이 없거나, 기타 다른 이유에 의해서 사용 할 수 없을때, 초기화 하는 것임.
|
|
void SSkillSlotMgr::SetCurSkill( int nSkill_ID )
|
|
{
|
|
// _oprint( "SetCurSkill : Request - %d, Current - %d\n", nSkill_ID, m_nCurUseSkill );
|
|
m_nCurUseSkill = -1;
|
|
}
|
|
|
|
BOOL SSkillSlotMgr::UseSkill( int nSkillCode, int nLevel )
|
|
{
|
|
_oprint( "UseSkill : %d %d - Current Use Skill :%d \n", nSkillCode, nLevel, m_nCurUseSkill );
|
|
|
|
//스킬을 사용 중임..
|
|
if( m_nCurUseSkill != -1 )
|
|
return FALSE;
|
|
|
|
//이미 사용 중인 스킬인지 검사
|
|
if( m_nCurUseSkill == nSkillCode )
|
|
return FALSE;
|
|
|
|
//쿨링 중인 스킬인지 검사
|
|
unsigned int nCoolingSkillSize = m_nCoolingSkill.size();
|
|
for( unsigned int i(0); nCoolingSkillSize>i; i++ )
|
|
{
|
|
if( m_nCoolingSkill[i] == nSkillCode )
|
|
return FALSE;
|
|
}
|
|
|
|
unsigned int nSkillSlotSize = m_vecSkillSlotList.size();
|
|
for( unsigned int i(0); nSkillSlotSize>i; i++ )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetSkillID() == nSkillCode )
|
|
{
|
|
//사용 할 수 있는 레벨인지 검사
|
|
if( nLevel > m_vecSkillSlotList[i]->GetSkill().base_skill_level + m_vecSkillSlotList[i]->GetAddedLevel())
|
|
return FALSE;
|
|
|
|
//사용하고 있는 스킬에 등록
|
|
m_nCurUseSkill = nSkillCode;
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//등록된 쿨링 리스트 삭제
|
|
void SSkillSlotMgr::DelCooling( int nSkill_ID, AR_HANDLE hTarget )
|
|
{
|
|
unsigned int nCoolingSkillSize = m_nCoolingSkill.size();
|
|
for( unsigned int a(0); nCoolingSkillSize>a; a++ )
|
|
{ //쿨링 리스트 제거
|
|
if( m_nCoolingSkill[a] == nSkill_ID )
|
|
{ //_oprint( "쿨링 리스트 삭제 : %d\n", nSkill_ID );
|
|
m_nCoolingSkill.erase( m_nCoolingSkill.begin()+a );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Cooling 등록
|
|
void SSkillSlotMgr::AddCooling( int nSkill_ID, AR_HANDLE hTarget )
|
|
{
|
|
// _oprint( "현재 스킬 : %d, 쿨링 추가 스킬 : %d\n", m_nCurUseSkill, nSkill_ID );
|
|
if( m_nCurUseSkill == nSkill_ID )
|
|
m_nCurUseSkill = -1;
|
|
|
|
unsigned int nCoolingSkillSize = m_nCoolingSkill.size();
|
|
for( unsigned int i(0); nCoolingSkillSize>i; i++ )
|
|
{
|
|
if( m_nCoolingSkill[i] == nSkill_ID )
|
|
{
|
|
_oprint( "쿨링 중인게 어떻게 들어 왔을까!!!\n" );
|
|
return;
|
|
}
|
|
}
|
|
|
|
unsigned int nSkillSlotSize = m_vecSkillSlotList.size();
|
|
for( unsigned int i(0); nSkillSlotSize>i; i++ )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetSkillID() == nSkill_ID )
|
|
{
|
|
m_vecSkillSlotList[i]->SetUse( TRUE );
|
|
break;
|
|
}
|
|
}
|
|
m_nCoolingSkill.push_back( nSkill_ID );
|
|
}
|
|
//쿨타임 그룹 얻는 함수 / 동일한 쿨타임 그룹의 스킬을 리스트에 담아서 준다
|
|
void SSkillSlotMgr::GetIdenticalCoolTimeGroup( int nSkill_ID, std::vector<int>& vecSkillList ) const
|
|
{
|
|
SkillBaseEx* pSkillData = GetSkillDB().GetSkillData( nSkill_ID );
|
|
if( !pSkillData ) return;
|
|
|
|
int nCoolTimeGroup = pSkillData->GetCoolTimeGroup();
|
|
if( !nCoolTimeGroup )
|
|
{
|
|
vecSkillList.push_back( nSkill_ID );
|
|
return;
|
|
}
|
|
|
|
unsigned int nSkillSlotSize = m_vecSkillSlotList.size();
|
|
for( unsigned int i(0); nSkillSlotSize>i; i++ )
|
|
{
|
|
SMSG_SKILL_LIST::SkillInfo SkillInfo = m_vecSkillSlotList[i]->GetSkill();
|
|
|
|
SkillBaseEx* pSkillData2 = GetSkillDB().GetSkillData( SkillInfo.skill_id );
|
|
if( !pSkillData2 ) continue;
|
|
|
|
int nSkillID( pSkillData2->GetID() );
|
|
if( pSkillData2->GetCoolTimeGroup() == nCoolTimeGroup )
|
|
vecSkillList.push_back( nSkillID );
|
|
}
|
|
}
|
|
|
|
const bool SSkillSlotMgr::IsExistSkill( int nSkillID, AR_HANDLE hTarget ) const
|
|
{
|
|
|
|
if (nSkillID==6101 || nSkillID==6102)
|
|
{
|
|
// 장착 부스트 아이템과 스킬이 일치하는지 검사
|
|
return true;
|
|
}
|
|
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID && ( hTarget == NULL || (hTarget && pSkillSlot->GetTarget() == hTarget) ) )
|
|
return true;
|
|
|
|
it++;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const bool SSkillSlotMgr::IsExistSkillLevel( int nSkillID, int nSkillLevel, AR_HANDLE hTarget ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID && ( hTarget == NULL || (hTarget && pSkillSlot->GetTarget() == hTarget) ) )
|
|
{
|
|
if (pSkillSlot->GetCurLevel() >= nSkillLevel)
|
|
return true;
|
|
}
|
|
|
|
it++;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 조건
|
|
const bool SSkillSlotMgr::IsEnableCreatureSkill() const
|
|
{
|
|
return IsExistSkill( CREATURE_CONTROL_SKILL );
|
|
}
|
|
const bool SSkillSlotMgr::IsCastingSkill( int nSkillID, AR_HANDLE hTarget ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID && ( hTarget == NULL || (hTarget && pSkillSlot->GetTarget() == hTarget) ) )
|
|
return pSkillSlot->IsCasting();
|
|
|
|
it++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
const bool SSkillSlotMgr::IsFireSkill( int nSkillID, AR_HANDLE hTarget ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID && ( hTarget == NULL || (hTarget && pSkillSlot->GetTarget() == hTarget) ) )
|
|
return pSkillSlot->IsFire();
|
|
|
|
it++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool SSkillSlotMgr::SetCastingCancelSkill( int nSkillID, AR_HANDLE hTarget )
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
for(; it != m_vecSkillSlotList.end(); it++ )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID && pSkillSlot->GetTarget() == hTarget )
|
|
{
|
|
pSkillSlot->SetCasting( false );
|
|
pSkillSlot->SetUse( false );
|
|
DelCooling( nSkillID );
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Set
|
|
bool SSkillSlotMgr::SetCastingSkill( int nSkillID, bool bCasting, AR_HANDLE hTarget )
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID && pSkillSlot->GetTarget() == hTarget )
|
|
{
|
|
pSkillSlot->SetCasting(bCasting);
|
|
return true;
|
|
}
|
|
|
|
it++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
bool SSkillSlotMgr::SetFireSkill( int nSkillID, bool bFire, AR_HANDLE hTarget )
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID && pSkillSlot->GetTarget() == hTarget )
|
|
{
|
|
pSkillSlot->SetCasting(false);
|
|
// REDMINE : 24123
|
|
// 스킬의 남은 시간이 패킷에 담겨오는데 같은 쿨타입 그룹의 스킬들도 쿨타임이 같이 적용되야 함
|
|
// 그래서 쿨타임 그룹이 같은 스킬은 모두 쿨타임 적용 계산한다
|
|
// 인벤토리 매니저에서 쿨타임 그룹 전체, 대여 아이템 등을 모두 Process에서 시간 계산함
|
|
pSkillSlot->SetFire(true);
|
|
|
|
AR_TIME total_cool_time = pSkillSlot->GetCoolingTime()/10;
|
|
if( pSkillSlot->GetRemainTime() == 0 )
|
|
pSkillSlot->setBeginTime(m_dwTime, total_cool_time, total_cool_time);
|
|
else
|
|
pSkillSlot->setBeginTime(m_dwTime, total_cool_time, pSkillSlot->GetRemainTime());
|
|
|
|
return true;
|
|
}
|
|
|
|
it++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
void SSkillSlotMgr::SetSkillCard( int nSkillID, AR_HANDLE hItem )
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
|
|
if( pSkillSlot->GetSkillID() == nSkillID )
|
|
{
|
|
(*it)->SetSkillCard( hItem );
|
|
break;
|
|
}
|
|
it++;
|
|
}
|
|
}
|
|
// Get
|
|
const int SSkillSlotMgr::GetBaseSkillLevel( int nSkillID, AR_HANDLE hTarget ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID && ( hTarget == NULL || (hTarget && pSkillSlot->GetTarget() == hTarget) ) )
|
|
return pSkillSlot->GetSkill().base_skill_level;
|
|
|
|
it++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const int SSkillSlotMgr::GetCurrentSkillLevel( int nSkillID, AR_HANDLE hTarget ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID && ( hTarget == NULL || (hTarget && pSkillSlot->GetTarget() == hTarget) ) )
|
|
return pSkillSlot->GetSkill().current_skill_level;
|
|
|
|
it++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
const int SSkillSlotMgr::GetUseSkillLevel( int nSkillID ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID ) return pSkillSlot->GetUseLevel();
|
|
|
|
it++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const int SSkillSlotMgr::GetUseSkillLevel( int nSkillID, AR_HANDLE hTarget ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
|
|
if( pSkillSlot->GetSkillID() == nSkillID &&
|
|
( hTarget == NULL || (hTarget && pSkillSlot->GetTarget() == hTarget) ) )
|
|
return pSkillSlot->GetUseLevel();
|
|
|
|
it++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const DWORD SSkillSlotMgr::GetSkillMaxTime( int nSkillID, AR_HANDLE hTarget ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
|
|
if( pSkillSlot->GetSkillID() == nSkillID && ( hTarget == NULL || (hTarget && pSkillSlot->GetTarget() == hTarget) ) )
|
|
return pSkillSlot->GetCoolingTime();
|
|
|
|
it++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
const DWORD SSkillSlotMgr::GetSkillCurTime( int nSkillID, AR_HANDLE hTarget ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
|
|
if( pSkillSlot->GetSkillID() == nSkillID && ( hTarget == NULL || (hTarget && pSkillSlot->GetTarget() == hTarget) ) )
|
|
return m_dwTime-pSkillSlot->GetBeginTime();
|
|
|
|
it++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
const AR_HANDLE SSkillSlotMgr::GetSkillCard( int nSkillID ) const
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
|
|
if( pSkillSlot->GetSkillID() == nSkillID )
|
|
return pSkillSlot->GetSkillCard();
|
|
|
|
it++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
SSkillSlot* SSkillSlotMgr::GetSkillSlot( int nSkillID )
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
|
|
if( pSkillSlot->GetSkillID() == nSkillID )
|
|
return (*it);
|
|
|
|
it++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
BOOL SSkillSlotMgr::CheckCoolTime( int nSkillID )
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
for( ; it != m_vecSkillSlotList.end(); ++it )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
if( pSkillSlot->GetSkillID() == nSkillID )
|
|
return pSkillSlot->IsUse();
|
|
}
|
|
|
|
assert( 0 && "SSkillSlotMgr::CheckCoolTime 문제있다~~~" );
|
|
return FALSE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 소환수 스킬 메니저
|
|
SCreatureSkillSlotMgr::SCreatureSkillSlotMgr()
|
|
: SSkillSlotMgr() // 2011.03.29 - servantes
|
|
{
|
|
Init();
|
|
}
|
|
|
|
SCreatureSkillSlotMgr::~SCreatureSkillSlotMgr()
|
|
{
|
|
Destroy();
|
|
InitQuickSlot();
|
|
}
|
|
|
|
void SCreatureSkillSlotMgr::ResetInfo()
|
|
{
|
|
m_vecQuickSlotList.clear();
|
|
|
|
SSkillSlotMgr::ResetInfo();
|
|
}
|
|
|
|
void SCreatureSkillSlotMgr::InitQuickSlot()
|
|
{
|
|
if( m_vecQuickSlotList.empty() ) return;
|
|
|
|
m_vecQuickSlotList.clear();
|
|
}
|
|
|
|
void SCreatureSkillSlotMgr::ResetCreatureSkill( AR_HANDLE hTarget )
|
|
{
|
|
{
|
|
//큇슬롯 삭제
|
|
std::vector<QUICK_SKILL>::iterator it = m_vecQuickSlotList.begin();
|
|
while( it != m_vecQuickSlotList.end() )
|
|
{
|
|
QUICK_SKILL skill = (*it);
|
|
if( skill.m_hCreature == hTarget )
|
|
{
|
|
it = m_vecQuickSlotList.erase(it);
|
|
}
|
|
else it++;
|
|
}
|
|
}
|
|
|
|
{
|
|
//스킬 리스트 삭제
|
|
SKILL_VECTOR::iterator it = m_vecSkillSlotList.begin();
|
|
while( it != m_vecSkillSlotList.end() )
|
|
{
|
|
if( (*it)->GetTarget() == hTarget )
|
|
{
|
|
SAFE_DELETE( (*it) );
|
|
it = m_vecSkillSlotList.erase( it );
|
|
}
|
|
else it++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCreatureSkillSlotMgr::AddSkill( DWORD dwTime, SMSG_SKILL_LIST::SkillInfo & skill_data, AR_HANDLE hTarget, int modificationType )
|
|
{
|
|
unsigned int nSkillSlotSize = m_vecSkillSlotList.size();
|
|
for( unsigned int i = 0; nSkillSlotSize>i; i++ )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetTarget() == hTarget && m_vecSkillSlotList[i]->GetSkillID() == skill_data.skill_id )
|
|
{
|
|
m_vecSkillSlotList[i]->SetSkill(skill_data);
|
|
m_vecSkillSlotList[i]->SetCasting( false );
|
|
m_vecSkillSlotList[i]->SetFire( false );
|
|
return;
|
|
}
|
|
}
|
|
|
|
SSkillSlot * pSlot = new SSkillSlot;
|
|
pSlot->SetSkill( skill_data ); // 1/100, -> 1/1000 변환
|
|
pSlot->SetCasting( false );
|
|
pSlot->SetFire( false );
|
|
pSlot->SetTarget( hTarget );
|
|
|
|
//이미 쿨링 중인 스킬은 쿨링리스트에 추가 한다.
|
|
if( skill_data.remain_cool_time > 0 )
|
|
{
|
|
//m_nCoolingSkill.push_back( skill_data.skill_id );
|
|
pSlot->SetUse(TRUE); //순서 있음
|
|
/// 2012.02.28 SetBeginTime -> setBeginTime으로 수정 - prodongi
|
|
pSlot->setBeginTime(dwTime, skill_data.total_cool_time, skill_data.remain_cool_time);
|
|
pSlot->SetFire( true );
|
|
}
|
|
|
|
m_vecSkillSlotList.push_back( pSlot );
|
|
}
|
|
BOOL SCreatureSkillSlotMgr::UseSkill( int nSkillCode, int nLevel )
|
|
{
|
|
return true;
|
|
}
|
|
void SCreatureSkillSlotMgr::SetCurSkill( int nSkill_ID )
|
|
{
|
|
}
|
|
void SCreatureSkillSlotMgr::AddCooling( int nSkill_ID, AR_HANDLE hTarget )
|
|
{
|
|
/*if( m_nCurUseSkill == nSkill_ID )
|
|
m_nCurUseSkill = -1;
|
|
|
|
for( unsigned int i(0); m_nCoolingSkill.size()>i; i++ )
|
|
{
|
|
if( m_nCoolingSkill[i] == nSkill_ID )
|
|
{
|
|
_oprint( "쿨링 중인게 어떻게 들어 왔을까!!!\n" );
|
|
return;
|
|
}
|
|
}*/
|
|
|
|
unsigned int nSkillSlotSize = m_vecSkillSlotList.size();
|
|
for( unsigned int i(0); nSkillSlotSize>i; i++ )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetSkillID() == nSkill_ID && m_vecSkillSlotList[i]->GetTarget() == hTarget )
|
|
{
|
|
m_vecSkillSlotList[i]->SetUse( TRUE );
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_nCoolingSkill.push_back( nSkill_ID );
|
|
}
|
|
void SCreatureSkillSlotMgr::DelCooling( int nSkil_ID, AR_HANDLE hTarget )
|
|
{
|
|
}
|
|
|
|
void SCreatureSkillSlotMgr::AddQuickSlot( AR_HANDLE hCreature, int nSkillID, int nLevel, int nState, int nQuickSlotNum, int nDragIndex/*-1*/ )
|
|
{
|
|
QUICK_SKILL* pEquipSkill(NULL); QUICK_SKILL* pDragSkill(NULL);
|
|
std::vector<QUICK_SKILL>::iterator DragIt = m_vecQuickSlotList.end();
|
|
std::vector<QUICK_SKILL>::iterator it = m_vecQuickSlotList.begin();
|
|
while( it != m_vecQuickSlotList.end() )
|
|
{
|
|
QUICK_SKILL skill = (*it);
|
|
if( skill.m_hCreature == hCreature && skill.m_nQuickSlotNum == nQuickSlotNum )
|
|
pEquipSkill = &(*it);
|
|
else if( skill.m_hCreature == hCreature && nDragIndex != -1 && skill.m_nQuickSlotNum == nDragIndex )
|
|
{
|
|
DragIt = it;
|
|
pDragSkill = &(*it);
|
|
}
|
|
|
|
if( pEquipSkill && pDragSkill )
|
|
{
|
|
int nTempIndex(-1);
|
|
nTempIndex = pEquipSkill->m_nQuickSlotNum;
|
|
pEquipSkill->m_nQuickSlotNum = pDragSkill->m_nQuickSlotNum;
|
|
pDragSkill->m_nQuickSlotNum = nTempIndex;
|
|
|
|
if( pDragSkill->m_nStateQuickSlot == QUICK_SKILL::STATE_TOGGLE_ON && pEquipSkill->m_nStateQuickSlot == QUICK_SKILL::STATE_TOGGLE_ON )
|
|
{
|
|
return;
|
|
}
|
|
else if( pDragSkill->m_nStateQuickSlot == QUICK_SKILL::STATE_TOGGLE_ON )
|
|
{
|
|
pEquipSkill->m_nStateQuickSlot = QUICK_SKILL::STATE_TOGGLE_OFF;
|
|
}
|
|
else if( pEquipSkill->m_nStateQuickSlot == QUICK_SKILL::STATE_TOGGLE_ON )
|
|
{
|
|
pDragSkill->m_nStateQuickSlot = QUICK_SKILL::STATE_TOGGLE_OFF;
|
|
}
|
|
else if( pEquipSkill->m_nStateQuickSlot == QUICK_SKILL::STATE_TOGGLE_ON_BY_USER )
|
|
{
|
|
pDragSkill->m_nStateQuickSlot = QUICK_SKILL::STATE_TOGGLE_OFF;
|
|
}
|
|
else if( pDragSkill->m_nStateQuickSlot == QUICK_SKILL::STATE_TOGGLE_ON_BY_USER )
|
|
{
|
|
pEquipSkill->m_nStateQuickSlot = QUICK_SKILL::STATE_TOGGLE_OFF;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
it++;
|
|
}
|
|
|
|
//드래그한 스킬이 있고 슬롯에 넣은 스킬이 있을때는 위 while()에서 이미 swap을 하였다....
|
|
//swap을 하고서 return;이 되지 않았는데 드래그한 스킬이 있다면 드래그한 곳에 넣을 스킬이 없으니 삭제하자...
|
|
if( pDragSkill && DragIt != m_vecQuickSlotList.end() )
|
|
{
|
|
m_vecQuickSlotList.erase(DragIt);
|
|
}
|
|
|
|
//위 while()에서 swap을 하지 않았는데 슬롯창에 장착할 스킬이 있으니 이미 스킬이 있었따면 덮어 쓰고 없는 곳이라면 push한다.
|
|
if( pEquipSkill )
|
|
{
|
|
pEquipSkill->m_nSkillID = nSkillID;
|
|
pEquipSkill->m_nUseLevel = nLevel;
|
|
pEquipSkill->m_nStateQuickSlot = (QUICK_SKILL::STATE_QUICK_SLOT)nState;
|
|
}
|
|
else
|
|
{
|
|
QUICK_SKILL skill( nSkillID, nLevel, nQuickSlotNum, hCreature, nState );
|
|
m_vecQuickSlotList.push_back(skill);
|
|
}
|
|
|
|
|
|
// if( !ChangeQuickSlot( hCreature, nQuickSlotNum, nDragIndex ) ) //이미 있어서 인덱스 change 했음
|
|
// {
|
|
// QUICK_SKILL skill( nSkillID, nLevel, nQuickSlotNum, hCreature );
|
|
// m_vecQuickSlotList.push_back(skill);
|
|
// if( nDragIndex != -1 ) //ChangeQuickSlot에서 false이니 빈공간에 드랍된 것이라서 기존 것을 삭제
|
|
// DelQuickSlot(hCreature, nDragIndex);
|
|
// }
|
|
}
|
|
bool SCreatureSkillSlotMgr::ChangeQuickSlot( AR_HANDLE hCreature, int nQuickSlotNum, int nDragIndex )
|
|
{
|
|
if( nDragIndex == -1 ) return false;
|
|
|
|
QUICK_SKILL* pQuick1(NULL); QUICK_SKILL* pQuick2(NULL);
|
|
std::vector<QUICK_SKILL>::iterator it = m_vecQuickSlotList.begin();
|
|
while( it != m_vecQuickSlotList.end() )
|
|
{
|
|
QUICK_SKILL skill = (*it);
|
|
if( skill.m_hCreature == hCreature && skill.m_nQuickSlotNum == nQuickSlotNum )
|
|
pQuick1 = &(*it);
|
|
else if( skill.m_hCreature == hCreature && skill.m_nQuickSlotNum == nDragIndex )
|
|
pQuick2 = &(*it);
|
|
if( pQuick1 && pQuick2 )
|
|
{
|
|
int nTempIndex(-1);
|
|
nTempIndex = pQuick1->m_nQuickSlotNum;
|
|
pQuick1->m_nQuickSlotNum = pQuick2->m_nQuickSlotNum;
|
|
pQuick2->m_nQuickSlotNum = nTempIndex;
|
|
return true;
|
|
}
|
|
|
|
it++;
|
|
}
|
|
return false;
|
|
}
|
|
void SCreatureSkillSlotMgr::DelQuickSlot( AR_HANDLE hCreature, int nQuickSlotNum )
|
|
{
|
|
QUICK_SKILL* pSlot = FindQuickSlot( hCreature, nQuickSlotNum );
|
|
if( pSlot == NULL ) return;
|
|
|
|
std::vector<QUICK_SKILL>::iterator it = m_vecQuickSlotList.begin();
|
|
while( it != m_vecQuickSlotList.end() )
|
|
{
|
|
QUICK_SKILL skill = (*it);
|
|
if( skill.m_hCreature == hCreature && skill.m_nQuickSlotNum == nQuickSlotNum )
|
|
{
|
|
m_vecQuickSlotList.erase(it);
|
|
return;
|
|
}
|
|
it++;
|
|
}
|
|
}
|
|
QUICK_SKILL* SCreatureSkillSlotMgr::FindQuickSlot( AR_HANDLE hCreature, int nQuickSlotNum )
|
|
{
|
|
std::vector<QUICK_SKILL>::iterator it = m_vecQuickSlotList.begin();
|
|
while( it != m_vecQuickSlotList.end() )
|
|
{
|
|
QUICK_SKILL skill = (*it);
|
|
if( skill.m_hCreature == hCreature && skill.m_nQuickSlotNum == nQuickSlotNum )
|
|
return &(*it);
|
|
it++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
void SCreatureSkillSlotMgr::GetQuickslotID( AR_HANDLE hCreature, int nSkillID, std::vector<int>& rIdList )
|
|
{
|
|
std::vector<QUICK_SKILL>::iterator it = m_vecQuickSlotList.begin();
|
|
while( it != m_vecQuickSlotList.end() )
|
|
{
|
|
QUICK_SKILL skill = (*it);
|
|
if( skill.m_hCreature == hCreature && skill.m_nSkillID == nSkillID )
|
|
rIdList.push_back( skill.m_nQuickSlotNum );
|
|
it++;
|
|
}
|
|
}
|
|
const bool SCreatureSkillSlotMgr::IsExistSkill( int nSkillID, AR_HANDLE hTarget ) const
|
|
{
|
|
for( unsigned int i(0); m_vecSkillSlotList.size()>i; i++ )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetSkillID() == nSkillID && m_vecSkillSlotList[i]->GetTarget() == hTarget )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
const bool SCreatureSkillSlotMgr::AbleLearnSkill( int nSkillID, int nLv, AR_HANDLE hTarget ) const
|
|
{
|
|
unsigned int nSkillSlotSize = m_vecSkillSlotList.size();
|
|
for( unsigned int i(0); nSkillSlotSize>i; i++ )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetSkillID() == nSkillID && m_vecSkillSlotList[i]->GetTarget() == hTarget )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetBaseLevel() >= nLv )
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
BOOL SCreatureSkillSlotMgr::IsUseSkill( AR_HANDLE hCreature, int nSkillID )
|
|
{
|
|
//m_pGame->AddChatMessage("BOOL SCreatureSkillSlotMgr::IsUseSkill( AR_HANDLE hCreature, int nSkillID )");
|
|
unsigned int nSkillSlotSize = m_vecSkillSlotList.size();
|
|
for( unsigned int i(0); nSkillSlotSize>i; i++ )
|
|
{
|
|
if( m_vecSkillSlotList[i]->GetSkillID() == nSkillID && m_vecSkillSlotList[i]->GetTarget() == hCreature )
|
|
return m_vecSkillSlotList[i]->IsUse();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL SCreatureSkillSlotMgr::CheckCoolTime( int nSkillID, AR_HANDLE hCaster )
|
|
{
|
|
SKILL_VECTOR::const_iterator it = m_vecSkillSlotList.begin();
|
|
for( ; it != m_vecSkillSlotList.end(); ++it )
|
|
{
|
|
SSkillSlot* pSkillSlot = (*it);
|
|
// 현재 사용한 스킬ID와 스킬스전 핸들 검사 kappamind, 2010.01.28
|
|
if( pSkillSlot->GetSkillID() == nSkillID && pSkillSlot->GetTarget() == hCaster )
|
|
{
|
|
return pSkillSlot->IsUse();
|
|
}
|
|
}
|
|
|
|
assert( 0 && "SSkillSlotMgr::CheckCoolTime 문제있다~~~" );
|
|
return FALSE;
|
|
} |