Files
Leviathan/Client/Game/game/GameSystem/SSkillSlot.cpp
T
2026-06-01 12:46:52 +02:00

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;
}