#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& 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::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::iterator DragIt = m_vecQuickSlotList.end(); std::vector::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::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::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::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& rIdList ) { std::vector::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; }