2105 lines
58 KiB
C++
2105 lines
58 KiB
C++
#include "stdafx.h"
|
|
#include "SInventoryMgr.h"
|
|
//#include <string>
|
|
//#include <vector>
|
|
|
|
#include "SGame.h"
|
|
#include "SChatType.h"
|
|
#include "SGameMessage.h"
|
|
//#include "SGameMessageUI.h"
|
|
#include "SkillBaseFile.h"
|
|
#include "SItemDB.h"
|
|
#include "SStringDB.h"
|
|
#include "SUIDefine.h"
|
|
#include "SGameInput.h"
|
|
#include "SSummonSlotMgr.h"
|
|
#include "SUISysMsgDefine.h"
|
|
#include "SDebug_Util.h"
|
|
#include <toolkit/XStringUtil.h>
|
|
#include "SUIUtil.h"
|
|
|
|
// AziaMafia ++
|
|
#include "SCommandSystem.h"
|
|
#include "SGameSystem.h"
|
|
extern SGameSystem* g_pCurrentGameSystem;
|
|
|
|
//IsInstanceUnstackable : 중복불가능한가? ( 비정적데이터를 이용하여 )
|
|
bool IsInstanceUnstackable( SInventorySlot* pSlot )
|
|
{
|
|
static SInventoryMgr* pInvenMgr = NULL;
|
|
if( pInvenMgr == NULL )
|
|
pInvenMgr = static_cast<SInventoryMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::INVENTORY_MGR ));
|
|
|
|
return pSlot->GetXFlag().IsOn( ItemInstance::ITEM_FLAG_SUMMON ) || ( pInvenMgr && pInvenMgr->IsEquipCard( pSlot->GetHandle() ) );
|
|
}
|
|
|
|
bool IsInstanceUnstackable( const XFlag<int>& rFlag )
|
|
{
|
|
return rFlag.IsOn( ItemInstance::ITEM_FLAG_SUMMON );
|
|
}
|
|
|
|
bool IsInstanceUnstackable( const int nFlag )
|
|
{
|
|
XFlag<int> xFlag;
|
|
xFlag.CopyFrom( &nFlag);
|
|
|
|
return IsInstanceUnstackable( xFlag );
|
|
}
|
|
|
|
const char* GetMaterialSound( int nMaterial )
|
|
{
|
|
switch( nMaterial )
|
|
{
|
|
case 0: return "ui_wear_skin01.wav"; break;//피부
|
|
case 1: return "ui_wear_leather01.wav"; break;//가죽
|
|
case 2: return "ui_wear_wood01.wav"; break;//나무
|
|
case 3: return "ui_wear_steel01.wav"; break;//금속
|
|
case 4: return "ui_wear_feather01.wav"; break;//깃털
|
|
case 5: return "ui_wear_stone01.wav"; break;//돌
|
|
case 6: return "ui_wear_bone01.wav"; break;//뼈
|
|
case 7: return "ui_wear_acc01.wav"; break;//악세서리
|
|
case 8: return "ui_wear_cube01.wav"; break;//큐브
|
|
case 9: return "ui_wear_paper01.wav"; break;//종이
|
|
case 10: return "ui_wear_shackle01.wav"; break;//쇠사슬
|
|
case 11: return "ui_wear_water01.wav"; break;//물
|
|
case 12: return "ui_wear_cloth01.wav"; break;//옷감류
|
|
case 13: return "ui_wear_powder01.wav"; break;//가루류
|
|
|
|
default : return "ui_icon_drag.wav";
|
|
// case 99: //기타
|
|
}
|
|
|
|
return "ui_icon_drag.wav";
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// shop slot
|
|
SShopSlot::SShopSlot()
|
|
{
|
|
m_nItemCode = 0;
|
|
m_nIconID = 0;
|
|
m_nPrice = money_t( 0 );
|
|
m_nHuntaHolicPoint = money_t( 0 ); // #2.1.2.11.1
|
|
|
|
m_hNpc = NULL;
|
|
}
|
|
SShopSlot::~SShopSlot()
|
|
{
|
|
}
|
|
void SShopSlot::SetItemCode( int nItemCode )
|
|
{
|
|
m_nItemCode = nItemCode;
|
|
|
|
m_nIconID = GetItemDB().GetIconID(nItemCode);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//Invetory Slot
|
|
SInventorySlot::SInventorySlot()
|
|
: m_bIsAppendedDecomposeWnd( false )
|
|
{
|
|
m_nGetItemCount = count_t( 0 );
|
|
m_bIsExistence = false;
|
|
|
|
m_nIconID = 0;
|
|
::memset( &m_ItemInfo, 0, sizeof(m_ItemInfo) );
|
|
|
|
m_nLastDurabilityCheckPercent = 0;
|
|
m_nLastDurabilityValue = 0;
|
|
|
|
m_bShowDecoration = true; // 꾸미기아이템 보임.
|
|
}
|
|
|
|
SInventorySlot::~SInventorySlot()
|
|
{
|
|
}
|
|
void SInventorySlot::SetItem( TS_ITEM_INFO* pItemInfo )
|
|
{
|
|
::memcpy( &m_ItemInfo, pItemInfo, sizeof(m_ItemInfo) );
|
|
}
|
|
|
|
// { [sonador][3.1.2] 경매장 구현
|
|
const unsigned int SInventorySlot::GetMaxEndurance( TS_ITEM_BASE_INFO* item )
|
|
{
|
|
const ItemBaseEx_info* pItemBaseInfo( GetItemDB().GetItemData( item->Code ) );
|
|
if( NULL == pItemBaseInfo )
|
|
return NULL;
|
|
|
|
if( NULL == item->socket )
|
|
return NULL;
|
|
|
|
int nJewelID( NULL );
|
|
unsigned int dwMaxEndurance( NULL );
|
|
const ItemBaseEx_info* pJewelInfo( NULL );
|
|
const int nJewelSlotCount( pItemBaseInfo->socket + item->random_option.GetAddJewelSocketCount() );
|
|
|
|
for( int i( 0 ); i < nJewelSlotCount; ++i )
|
|
{
|
|
nJewelID = item->socket[i];
|
|
if( nJewelID )
|
|
{
|
|
pJewelInfo = GetItemDB().GetItemData( nJewelID );
|
|
if( pJewelInfo )
|
|
dwMaxEndurance += pJewelInfo->nEndurance;
|
|
}
|
|
}
|
|
|
|
return dwMaxEndurance;
|
|
}
|
|
|
|
const int SInventorySlot::GetCrrEndurancePer( TS_ITEM_BASE_INFO* item, unsigned int& rEndurance )
|
|
{
|
|
const ItemBaseEx_info* pItemBaseInfo( GetItemDB( ).GetItemData( item->Code ) );
|
|
if( NULL == pItemBaseInfo )
|
|
return SInventorySlot::NONEITEM;
|
|
|
|
if( NULL == item->socket )
|
|
return SInventorySlot::SOKETNULL;
|
|
|
|
int nJewelID( 0 );
|
|
unsigned int dwMaxEndurance( GetMaxEndurance( item ) );
|
|
|
|
if( dwMaxEndurance )
|
|
{
|
|
unsigned int dwEndurance = ( item->endurance + 99999 ) / 100000;
|
|
dwMaxEndurance = dwMaxEndurance / 100000;
|
|
|
|
if( dwMaxEndurance == 0 )
|
|
rEndurance = 0;
|
|
else
|
|
rEndurance = dwEndurance * 100 / dwMaxEndurance;
|
|
|
|
if( rEndurance == 0 && dwEndurance != 0 )
|
|
rEndurance = 1;
|
|
|
|
return SInventorySlot::ENDURANCE_SUCCESS;
|
|
}
|
|
return SInventorySlot::NONESOKET;
|
|
}
|
|
|
|
|
|
const unsigned int SInventorySlot::GetMaxEndurance()
|
|
{
|
|
return GetMaxEndurance( &m_ItemInfo );
|
|
}
|
|
|
|
const int SInventorySlot::GetCrrEndurancePer( unsigned int& rEndurance )
|
|
{
|
|
return GetCrrEndurancePer( &m_ItemInfo, rEndurance );
|
|
}
|
|
|
|
// 2010.07.14 - prodongi
|
|
int SInventorySlot::getMaxEtherealDurability() const
|
|
{
|
|
float pEnhanceDurability[30] =
|
|
{
|
|
1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f,
|
|
2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 4.0f,
|
|
5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.f, 10.f, 10.f, 10.f, 10.f
|
|
};
|
|
|
|
ItemBaseEx_info const* itemBaseInfo = GetItemDB( ).GetItemData(m_ItemInfo.Code);
|
|
if (!itemBaseInfo)
|
|
return 0;
|
|
if (itemBaseInfo->nType == ItemBase::TYPE_ARMOR && GetEnhance() > 0 && GetEnhance() <= 29)
|
|
return itemBaseInfo->nEthereal_durability * pEnhanceDurability[ GetEnhance() - 1 ];
|
|
|
|
return itemBaseInfo->nEthereal_durability;
|
|
}
|
|
|
|
// 2010.07.14 - prodongi
|
|
bool SInventorySlot::isExhausted() const
|
|
{
|
|
if (isExhaustedSummonCard(m_ItemInfo.Code, GetEnhance(), GetEtherealDurability()))
|
|
return true;
|
|
return ((0 < getMaxEtherealDurability()) && (0 == GetEtherealDurability()));
|
|
}
|
|
|
|
|
|
bool SInventorySlot::IsAwakeningItem()
|
|
{
|
|
for ( int i = 0; i < ItemBase::MAX_AWAKENING_OPTION; i++ )
|
|
{
|
|
if ( m_ItemInfo.awakenoption.nData[i] != 0 )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void SInventorySlot::SetUpdateCount( count_t nNewCount, bool bDestroy /*= false*/ )
|
|
{
|
|
if( !bDestroy )
|
|
m_nGetItemCount = GetItemCount() > 0 ? (nNewCount - GetItemCount()) : nNewCount;
|
|
else
|
|
m_nGetItemCount = nNewCount;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 보석 장착 슬롯 개수 얻기
|
|
// 설명 : 기본 ItemResourceDB에 설정된 슬롯 개수 + 랜덤 옵션으로 생성 된 슬롯 개수
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
const int SInventorySlot::GetJewelSlotCount()
|
|
{
|
|
int nJewelSlotCount( NULL );
|
|
|
|
int nte = m_ItemInfo.Code;
|
|
|
|
const ItemBaseEx_info* pItemBaseInfo( GetItemDB().GetItemData( GetItemCode() ) );
|
|
if( NULL == pItemBaseInfo )
|
|
return nJewelSlotCount;
|
|
|
|
nJewelSlotCount += pItemBaseInfo->socket;
|
|
|
|
TS_ITEM_BASE_INFO::RANDOM_OPTION* const pRandomOption( GetRandomOption() );
|
|
|
|
if( NULL == pRandomOption )
|
|
return nJewelSlotCount;
|
|
|
|
nJewelSlotCount += pRandomOption->GetAddJewelSocketCount();
|
|
|
|
return nJewelSlotCount;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//Invetory
|
|
SInventoryMgr::SInventoryMgr()
|
|
: SGameUIMgr() // 2011.03.29 - servantes
|
|
, m_pUpdateItemInfo( NULL )
|
|
{
|
|
Clear();
|
|
|
|
m_pUpdateItemInfo = new SInventorySlot;
|
|
}
|
|
|
|
SInventoryMgr::~SInventoryMgr()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void SInventoryMgr::Clear()
|
|
{
|
|
ItemSet(SET_INDEX_01);
|
|
|
|
for( unsigned int a(0); ItemBase::MAX_ITEM_WEAR>a; a++ )
|
|
{
|
|
m_itemCode[a] = 0;
|
|
m_itemHandle[a] = 0;
|
|
}
|
|
|
|
m_dwTime = 0;
|
|
m_dwCheckLendingTime = 0;
|
|
m_nCheckCount = 0;
|
|
|
|
for( int i(0); TS_SC_ITEM_COOL_TIME::MAX_ITEM_COOLTIME_GROUP>i; i++ )
|
|
{
|
|
m_dwCur_time[i] = 0;
|
|
m_dwCool_time[i] = 0;
|
|
m_dwRemain_time[i] = 0;
|
|
}
|
|
|
|
m_hCashDragItem = 0;
|
|
|
|
for( int i(0); c_BeltSlotCnt>i; i++ )
|
|
handle_BeltSlot[i] = 0;
|
|
|
|
m_vLendingItem.clear();
|
|
|
|
SAFE_DELETE_VECTOR( m_vInventory );
|
|
SAFE_DELETE_VECTOR( m_vecShopList );
|
|
|
|
m_vCashItemList.clear();
|
|
m_vEquipCareList.clear();
|
|
|
|
SAFE_DELETE( m_pUpdateItemInfo );
|
|
|
|
m_rqItemState = RQ_ITEM_STATE::RQ_ITEM_STATE_NONE; // 아이템 요청 상태.
|
|
}
|
|
|
|
void SInventoryMgr::ResetInfo()
|
|
{
|
|
Clear();
|
|
|
|
if( m_pUpdateItemInfo == NULL )
|
|
m_pUpdateItemInfo = new SInventorySlot;
|
|
}
|
|
|
|
AR_HANDLE SInventoryMgr::GetItemHandle( int nIndex )
|
|
{
|
|
if( m_vInventory.empty() ) return NO_HANDLE;
|
|
if( (int)m_vInventory.size() <= nIndex ) return NO_HANDLE;
|
|
|
|
return m_vInventory[nIndex]->GetHandle();
|
|
}
|
|
|
|
AR_HANDLE SInventoryMgr::GetItemHandleForCode( int nItemCode )
|
|
{
|
|
int nSize = (int)m_vInventory.size();
|
|
for( int i(0); i<nSize; ++i )
|
|
{
|
|
if( m_vInventory[i]->GetItemCode() == nItemCode )
|
|
return m_vInventory[i]->GetHandle();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//Update Item Info
|
|
void SInventoryMgr::UpdateWear( struct SMSG_ITEM_WEAR* pMsg )
|
|
{
|
|
for( int i=0; ItemBase::MAX_ITEM_SPARE_WEAR>i; i++ )
|
|
{
|
|
m_itemCode[i] = pMsg->nItemCode[i];
|
|
}
|
|
}
|
|
|
|
void SInventoryMgr::UpdateWearInfo( struct SMSG_ITEM_WEAR_INFO* pMsg, bool bCreature )
|
|
{
|
|
AR_HANDLE handle = 0;
|
|
|
|
for( unsigned int i(0); m_vInventory.size()>i; i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == pMsg->item_handle )
|
|
{
|
|
//변경된 아이템의 위치 갱신
|
|
m_vInventory[i]->SetPosition( pMsg->wear_position );
|
|
m_vInventory[i]->SetWearHandle(NULL);
|
|
|
|
if( bCreature )
|
|
{
|
|
m_vInventory[i]->SetWearHandle(pMsg->target_handle);
|
|
break;
|
|
}
|
|
|
|
if( pMsg->wear_position != -1 )
|
|
{
|
|
//기존에 있던 넘의 핸들을 얻는다.
|
|
handle = m_itemHandle[pMsg->wear_position];
|
|
m_itemHandle[pMsg->wear_position] = pMsg->item_handle;
|
|
}
|
|
else
|
|
{
|
|
for( unsigned int a(0); ItemBase::MAX_ITEM_WEAR>a; a++ )
|
|
{
|
|
if( m_itemHandle[a] == pMsg->item_handle )
|
|
m_itemHandle[a] = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
//기존에 들어 있던것의 위치를 없앤다.
|
|
if( !handle ) return;
|
|
|
|
for( unsigned int i(0); m_vInventory.size()>i; i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == handle )
|
|
{
|
|
m_vInventory[i]->SetPosition( -1 );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Item Use
|
|
void SInventoryMgr::Rq_UseItem( int nRace, AR_HANDLE item_handle, AR_HANDLE target_handle, AR_HANDLE item_target_handle, const char* lpText/*=NULL*/ )
|
|
{
|
|
if( m_vInventory.empty() ) return;
|
|
|
|
for( unsigned int i(0); m_vInventory.size()>i; i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == item_handle )
|
|
{
|
|
const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( m_vInventory[i]->GetItemCode() );
|
|
//사용 가능 한가?
|
|
if( ItemBase::TYPE_USEABLE == pItemBase->nType )
|
|
{
|
|
short nCoolTimeGroup = GetItemDB().GetCoolTimeGroup( m_vInventory[i]->GetItemCode() );
|
|
if( GetItemMaxCoolTime( (nCoolTimeGroup-1) ) < GetItemCurCoolTime( (nCoolTimeGroup-1) ) )
|
|
{
|
|
if( nCoolTimeGroup == 1 || //레드 포션
|
|
nCoolTimeGroup == 2 || //오렌지 포션
|
|
nCoolTimeGroup == 3 || //블루 포션
|
|
nCoolTimeGroup == 4 || //신속의 포션
|
|
nCoolTimeGroup == 5 || //바람의 포션
|
|
nCoolTimeGroup == 6 ) //스펠 포션
|
|
{
|
|
//포션류만 소리 재생.
|
|
if( m_pGame ) m_pGame->StartSound( "ui_click_potion01.wav" );
|
|
}
|
|
}
|
|
|
|
/* TS_CS_USE_ITEM use_msg;
|
|
//타겟에 사용 할 수 있는가?
|
|
if( pItemBase->Flag.IsOn(ItemBase::FLAG_TARGET_USE) )
|
|
{
|
|
//타겟을 얻음, 타겟에게 사용
|
|
use_msg.item_handle = item_handle;
|
|
use_msg.target_handle = target_handle;
|
|
}
|
|
else
|
|
{
|
|
//자신한테만 사용한다.
|
|
use_msg.item_handle = item_handle;
|
|
use_msg.target_handle = 0;
|
|
}
|
|
|
|
SetUpdateItemInfo( m_vInventory[i] );
|
|
SendMsg( &use_msg );*/
|
|
|
|
if( pItemBase->CheckFlag(ItemBase::FLAG_TARGET_USE) )
|
|
{
|
|
//타겟을 얻음, 타겟에게 사용
|
|
AR_UNIT nRange = pItemBase->nThrowRange * GameRule::DEFAULT_UNIT_SIZE;
|
|
/* SInputUseItem inupt( target_handle, item_handle, nRange, pItemBase->fOptVar1[0] );
|
|
if( m_pGame ) m_pGame->AddGameInput( &inupt );*/
|
|
|
|
SIMSG_UI_ACT_USEITEM msg;
|
|
msg.m_hItemUseTargetHandle = item_target_handle;
|
|
msg.m_hTargetHandle = target_handle;
|
|
msg.m_hItemHandle = item_handle;
|
|
msg.m_fUseRange = nRange;
|
|
msg.m_nSkillID = pItemBase->dOptVar1[0];
|
|
msg.m_bNeedTarget = true;
|
|
|
|
if( lpText )
|
|
msg.m_strParameter = lpText;
|
|
|
|
ProcMsgAtStatic( &msg );
|
|
}
|
|
else
|
|
{
|
|
//자신한테만 사용한다.
|
|
/* SInputUseItem inupt( 0, item_handle, 0, 0 );
|
|
if( m_pGame ) m_pGame->AddGameInput( &inupt );*/
|
|
|
|
bool bIsPosition = false;
|
|
if( pItemBase->nType == ItemBase::TYPE_USEABLE &&
|
|
((int)pItemBase->dOptVar1[0]) == 0 )
|
|
{
|
|
bIsPosition = true;
|
|
}
|
|
|
|
// 2012. 8. 8 - marine 추가 성능 아이디가 1(hp), 2(mp)인 경우에는 이동을 유지하도록 수정
|
|
if( pItemBase->nType == ItemBase::TYPE_USEABLE &&
|
|
(((int)pItemBase->nOptType[0]) == 1 || ((int)pItemBase->nOptType[0]) == 2 ) )
|
|
{
|
|
bIsPosition = true;
|
|
}
|
|
|
|
SIMSG_UI_ACT_USEITEM msg;
|
|
msg.m_hItemUseTargetHandle = item_target_handle;
|
|
msg.m_hTargetHandle = 0;
|
|
msg.m_hItemHandle = item_handle;
|
|
msg.m_fUseRange = 0;
|
|
msg.m_nSkillID = 0;
|
|
msg.m_bIsPosition = bIsPosition;
|
|
if( lpText )
|
|
msg.m_strParameter = lpText;
|
|
|
|
ProcMsgAtStatic( &msg );
|
|
}
|
|
SetUpdateItemInfo( m_vInventory[i] );
|
|
}
|
|
else
|
|
{
|
|
bool bUseItem(false);
|
|
if( ItemBase::TYPE_USE == pItemBase->nType ) //장착시 사용인 아이템의 경우
|
|
{
|
|
/* for( int i(0); ItemBase::MAX_ITEM_WEAR>i; i++ )
|
|
{
|
|
if( m_itemHandle[i] == item_handle ) //장착되있다면
|
|
{
|
|
bUseItem = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ItemBase::GROUP_RIDING == pItemBase->nGroup ||
|
|
ItemBase::GROUP_CASH_ITEM == pItemBase->nGroup )
|
|
bUseItem = true;*/
|
|
|
|
|
|
// if( bUseItem )
|
|
{
|
|
SIMSG_UI_ACT_USEITEM msg; //사용
|
|
msg.m_hItemUseTargetHandle = item_target_handle;
|
|
msg.m_hTargetHandle = target_handle;
|
|
msg.m_hItemHandle = item_handle;
|
|
msg.m_fUseRange = 0;
|
|
msg.m_nSkillID = pItemBase->dOptVar1[0];
|
|
msg.m_bNeedTarget = false;
|
|
|
|
ProcMsgAtStatic( &msg );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( m_vInventory[i]->GetItem() == NULL )
|
|
{
|
|
assert( 0 && "Item Data Error!!!" );
|
|
continue;
|
|
}
|
|
|
|
//너무 빨리 장비를 장착하려고하지는 않는가? 2009.07.31 sfreer
|
|
{
|
|
static AR_TIME lastpuTime = 0;
|
|
|
|
AR_TIME time = GetSafeTickCount();
|
|
if (time < lastpuTime + 200) //200 tick 안에 wearInfo 들어 오면 무시
|
|
{
|
|
SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_PUT_ITEM_TOOFAST ) );
|
|
return;
|
|
}
|
|
lastpuTime = time;
|
|
}
|
|
|
|
//장착 레벨이 되는가?
|
|
int nItemCode = m_vInventory[i]->GetItemCode();
|
|
ItemBase::ItemWearType wearType = GetItemDB().GetWearType( m_vInventory[i]->GetItemCode() );
|
|
|
|
if( wearType == ItemBase::WEAR_CANTWEAR && nItemCode != 804000 )
|
|
{
|
|
//아무 것도 안 해...
|
|
return; //사용
|
|
}
|
|
else
|
|
{
|
|
int nPosition = GetItemDB().GetWearType( m_vInventory[i]->GetItemCode() );
|
|
BOOL bPut = FALSE;
|
|
unsigned int a = 0;
|
|
|
|
// 장착여부 검사. 장착되어 있다면 탈착. bintitle. 2010.11.15.
|
|
bPut = TRUE;
|
|
for( ; ItemBase::MAX_ITEM_WEAR>a; a++ )
|
|
{
|
|
if( m_itemHandle[a] == item_handle )
|
|
{
|
|
//탈착
|
|
bPut = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 장착되지 않았다면 양손 여부 검사. bintitle. 2010.11.15.
|
|
if( bPut )
|
|
{
|
|
//장착 할수 있는 종족 인가?
|
|
bool bRace = GetItemDB().IsWearablebyRace( nItemCode, nRace );
|
|
if( !bRace )
|
|
{
|
|
SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_PUT_ITEM_FAIL ) );
|
|
_oprint( "Cannot equip due to wrong race... ItemCode: %d, Race: %d\n", nItemCode,nRace );
|
|
return; //사용 불가
|
|
}
|
|
|
|
// From ZONE source; dual crossbows
|
|
if (pItemBase->nClass == ItemBase::CLASS_ONEHAND_SWORD ||
|
|
pItemBase->nClass == ItemBase::CLASS_DAGGER ||
|
|
pItemBase->nClass == ItemBase::CLASS_ONEHAND_AXE ||
|
|
<<<<<<< HEAD
|
|
pItemBase->nClass == ItemBase::CLASS_CROSSBOW) //Double Crossbow
|
|
{
|
|
CheckWeapon(pItemBase, item_handle, ItemBase::WEAR_WEAPON, ItemBase::WEAR_SHIELD, a, nPosition, bPut);
|
|
}
|
|
else if( pItemBase->nClass == ItemBase::CLASS_DECO_ONEHAND_SWORD ||
|
|
pItemBase->nClass == ItemBase::CLASS_DECO_DAGGER ||
|
|
pItemBase->nClass == ItemBase::CLASS_DECO_ONEHAND_AXE ||
|
|
pItemBase->nClass == ItemBase::CLASS_DECO_CROSSBOW) //Double Crossbow
|
|
=======
|
|
pItemBase->nClass == ItemBase::CLASS_CROSSBOW)
|
|
{
|
|
CheckWeapon(pItemBase, item_handle, ItemBase::WEAR_WEAPON, ItemBase::WEAR_SHIELD, a, nPosition, bPut);
|
|
}
|
|
else if (pItemBase->nClass == ItemBase::CLASS_DECO_ONEHAND_SWORD ||
|
|
pItemBase->nClass == ItemBase::CLASS_DECO_DAGGER ||
|
|
pItemBase->nClass == ItemBase::CLASS_DECO_ONEHAND_AXE ||
|
|
pItemBase->nClass == ItemBase::CLASS_DECO_CROSSBOW)
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
{
|
|
CheckWeapon(pItemBase, item_handle, ItemBase::WEAR_DECO_WEAPON, ItemBase::WEAR_DECO_SHIELD, a, nPosition, bPut);
|
|
}
|
|
|
|
//양손 장착 가능 무기인가 검사
|
|
//if( pItemBase->nClass == ItemBase::CLASS_ONEHAND_SWORD ||
|
|
// pItemBase->nClass == ItemBase::CLASS_DAGGER ||
|
|
// pItemBase->nClass == ItemBase::CLASS_ONEHAND_AXE ||
|
|
//
|
|
// // AziaMafia Double Crossbow
|
|
// pItemBase->nClass == ItemBase::CLASS_CROSSBOW)
|
|
//{
|
|
// CheckWeapon(pItemBase, item_handle, ItemBase::WEAR_WEAPON, ItemBase::WEAR_SHIELD, a, nPosition, bPut);
|
|
//}
|
|
//else if( pItemBase->nClass == ItemBase::CLASS_DECO_ONEHAND_SWORD ||
|
|
// pItemBase->nClass == ItemBase::CLASS_DECO_DAGGER ||
|
|
// pItemBase->nClass == ItemBase::CLASS_DECO_ONEHAND_AXE ||
|
|
//
|
|
// // AziaMafia Double Crossbow
|
|
// pItemBase->nClass == ItemBase::CLASS_DECO_CROSSBOW)
|
|
//{
|
|
// CheckWeapon(pItemBase, item_handle, ItemBase::WEAR_DECO_WEAPON, ItemBase::WEAR_DECO_SHIELD, a, nPosition, bPut);
|
|
//}
|
|
//else
|
|
//{
|
|
// //Loop 도는 것은 나중에 고치자~
|
|
// //이미 장착 되어 있나 판별
|
|
// bPut = TRUE;
|
|
// for( ; ItemBase::MAX_ITEM_WEAR>a; a++ )
|
|
// {
|
|
// if( m_itemHandle[a] == item_handle )
|
|
// {
|
|
// //탈착
|
|
// bPut = FALSE;
|
|
// break;
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
} // bintitle. 2010.11.15.
|
|
|
|
// ( target_handle == 0 가능 );
|
|
|
|
if( bPut )
|
|
{
|
|
|
|
{
|
|
//에테리얼 내구도 체크
|
|
SInventorySlot* pSlot = m_vInventory[i];
|
|
const ItemBaseEx_info * pItem = GetItemDB().GetItemData( pSlot->GetItemCode() );
|
|
|
|
if(pItem->nEthereal_durability > 0)
|
|
{
|
|
if( pSlot->GetEtherealDurability() == 0)
|
|
{
|
|
SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_PUT_BROKEN_ITEM ) );
|
|
_oprint( "Ethereal durability is 0. ItemCode: %d\n", nItemCode);
|
|
return; //사용 불가
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if( m_pGame )
|
|
{
|
|
m_pGame->StartSound( GetMaterialSound( GetItemDB().GetMaterial( m_vInventory[i]->GetItemCode() ) ) );
|
|
m_pGame->Rq_PutOnOffItem( target_handle, item_handle, nPosition);
|
|
}
|
|
|
|
//장착
|
|
/* TS_CS_PUTON_ITEM msg;
|
|
msg.item_handle = item_handle;
|
|
msg.target_handle = target_handle;
|
|
msg.position = nPosition;
|
|
assert( msg.position != 255 && "Data Error~ 장착 Position 이상~" );
|
|
SendMsg( &msg );*/
|
|
return; //사용
|
|
}
|
|
else//탈착 시키자
|
|
{
|
|
if( m_pGame ) m_pGame->Rq_PutOnOffItem( target_handle, 0, a );
|
|
|
|
/* TS_CS_PUTOFF_ITEM msg;
|
|
msg.position = a;//실제 장착위치//GetItemDB().GetWearType( m_vInventory[i]->GetItemCode() );
|
|
msg.target_handle = target_handle;
|
|
SendMsg( &msg );*/
|
|
return; //사용
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SInventoryMgr::CheckWeapon( const ItemBaseEx_info* pItemBase, int item_handle, ItemBase::ItemWearType MainWearType, ItemBase::ItemWearType SubWearType, unsigned int& a, int& nPosition, BOOL& bPut )
|
|
{
|
|
if( m_itemHandle[MainWearType] == 0)
|
|
{
|
|
a = MainWearType;
|
|
nPosition = MainWearType;
|
|
bPut = TRUE;
|
|
}
|
|
//Sub(Shield)슬롯이 비어있다면 이곳에 장착 하자
|
|
else if( m_itemHandle[SubWearType] == 0 )
|
|
{
|
|
//Main(Weapon)슬롯 무기와 같지 않아야 한다
|
|
if( m_itemHandle[MainWearType] != item_handle )
|
|
{
|
|
<<<<<<< HEAD
|
|
//Main(Weapon)슬롯이 한손검이나 데거 혹은 치장무기가 장착돼있어야 한다
|
|
ItemBase::ItemClass clss = GetItemDB().GetClassID( m_itemCode[MainWearType] );
|
|
if( clss == ItemBase::CLASS_ONEHAND_SWORD || clss == ItemBase::CLASS_DAGGER || clss == ItemBase::CLASS_ONEHAND_AXE ||
|
|
clss == ItemBase::CLASS_DECO_ONEHAND_SWORD || clss == ItemBase::CLASS_DECO_DAGGER ||
|
|
clss == ItemBase::CLASS_DECO_ONEHAND_AXE || clss == ItemBase::CLASS_CROSSBOW || clss == ItemBase::CLASS_DECO_CROSSBOW) //Double Crossbow
|
|
=======
|
|
// From ZONE source; dual crossbows
|
|
ItemBase::ItemClass clss = GetItemDB().GetClassID(m_itemCode[MainWearType]);
|
|
if (clss == ItemBase::CLASS_ONEHAND_SWORD || clss == ItemBase::CLASS_DAGGER || clss == ItemBase::CLASS_ONEHAND_AXE ||
|
|
clss == ItemBase::CLASS_DECO_ONEHAND_SWORD || clss == ItemBase::CLASS_DECO_DAGGER ||
|
|
clss == ItemBase::CLASS_DECO_ONEHAND_AXE || clss == ItemBase::CLASS_CROSSBOW || clss == ItemBase::CLASS_DECO_CROSSBOW)
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
{
|
|
if (clss == pItemBase->nClass)
|
|
nPosition = SubWearType;
|
|
}
|
|
//Main(Weapon)슬롯이 한손검이나 데거 혹은 치장무기가 장착돼있어야 한다
|
|
//ItemBase::ItemClass clss = GetItemDB().GetClassID( m_itemCode[MainWearType] );
|
|
//if( clss == ItemBase::CLASS_ONEHAND_SWORD || clss == ItemBase::CLASS_DAGGER || clss == ItemBase::CLASS_ONEHAND_AXE ||
|
|
// clss == ItemBase::CLASS_DECO_ONEHAND_SWORD || clss == ItemBase::CLASS_DECO_DAGGER
|
|
// || clss == ItemBase::CLASS_DECO_ONEHAND_AXE
|
|
|
|
// // AziaMafia Double Crossbow
|
|
// || clss == ItemBase::CLASS_CROSSBOW
|
|
// || clss == ItemBase::CLASS_DECO_CROSSBOW )
|
|
//{
|
|
// //장착될 아이템과 Main(Weapon)에 장착된 아이템이 같은 클래스여야 한다
|
|
// if( clss == pItemBase->nClass )
|
|
// nPosition = SubWearType;
|
|
//}
|
|
bPut = TRUE;
|
|
}
|
|
else a = MainWearType;
|
|
}
|
|
else //양손모두 장착돼 있다면
|
|
{
|
|
//Main(Weapon)슬롯과 같다면 탈착 시킨다
|
|
if( m_itemHandle[MainWearType] == item_handle )
|
|
a = MainWearType;
|
|
//Sub(Shield)슬롯과 같다면 탈착 시킨다
|
|
else if( m_itemHandle[SubWearType] == item_handle )
|
|
a = SubWearType;
|
|
else//새로운 아이템 이면
|
|
{
|
|
nPosition = MainWearType;
|
|
bPut = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SInventoryMgr::AddEquipCard( AR_HANDLE target_handle, AR_HANDLE hItem )
|
|
{
|
|
for( unsigned int i(0); m_vEquipCareList.size()>i; i++ )
|
|
{
|
|
if( m_vEquipCareList[i].item_handle == hItem )
|
|
return;
|
|
}
|
|
|
|
EQUIP_CARD equip_card;
|
|
equip_card.item_handle = hItem;
|
|
equip_card.target_handle = target_handle;
|
|
|
|
m_vEquipCareList.push_back( equip_card );
|
|
}
|
|
|
|
void SInventoryMgr::DelEquipCard( AR_HANDLE target_handle, AR_HANDLE hItem )
|
|
{
|
|
for( unsigned int i(0); m_vEquipCareList.size()>i; i++ )
|
|
{
|
|
if( m_vEquipCareList[i].item_handle == hItem )
|
|
{
|
|
m_vEquipCareList.erase( m_vEquipCareList.begin()+i );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool SInventoryMgr::IsEquipCard( AR_HANDLE hItem ) const /// 2010.12.29 const 추가
|
|
{
|
|
for( unsigned int i(0); m_vEquipCareList.size()>i; i++ )
|
|
{
|
|
if( m_vEquipCareList[i].item_handle == hItem )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void SInventoryMgr::SetBeltSlotCard( struct SMSG_BELT_SLOT_INFO* pMsg )
|
|
{
|
|
for( int i(0); c_BeltSlotCnt>i; i++ )
|
|
handle_BeltSlot[i] = pMsg->handle[i];
|
|
}
|
|
|
|
bool SInventoryMgr::IsBeltSlotCard( AR_HANDLE hItem ) const /// 2010.12.29 const 추가 - prodongi
|
|
{
|
|
for( int i(0); c_BeltSlotCnt>i; i++ )
|
|
{
|
|
if( handle_BeltSlot[i] == hItem )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
// 아이템의 장착여부 반환.
|
|
bool SInventoryMgr::IsEquip( AR_HANDLE handle )
|
|
{
|
|
for( int i=0; i<ItemBase::MAX_ITEM_WEAR; ++i )
|
|
{
|
|
if( m_itemHandle[ i ] == handle )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
int SInventoryMgr::GetBeltSlotIndex( AR_HANDLE hItem )
|
|
{
|
|
for( int i(0); c_BeltSlotCnt>i; i++ )
|
|
{
|
|
if( handle_BeltSlot[i] == hItem )
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int SInventoryMgr::GetEmptyBeltSlotIndex()
|
|
{
|
|
for( int i(0); c_BeltSlotCnt>i; i++ )
|
|
{
|
|
if( handle_BeltSlot[i] == 0 )
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
AR_HANDLE SInventoryMgr::GetBeltSlot( int nIndex )
|
|
{
|
|
if( nIndex >= 0 && nIndex < c_BeltSlotCnt )
|
|
return handle_BeltSlot[nIndex];
|
|
|
|
return 0;
|
|
}
|
|
|
|
// 2010.08.17 - prodongi
|
|
//void SInventoryMgr::Rq_BeltCardPut( bool bPutOn, AR_HANDLE hItem )
|
|
void SInventoryMgr::Rq_BeltCardPut( bool bPutOn, AR_HANDLE hItem, int putSlot )
|
|
{
|
|
if( bPutOn )
|
|
{
|
|
TS_CS_PUTON_CARD msg;
|
|
// 2010.08.17 - prodongi
|
|
//msg.position = GetEmptyBeltSlotIndex();
|
|
msg.position = putSlot;
|
|
msg.item_handle = hItem;
|
|
SendMsg( &msg );
|
|
}
|
|
else
|
|
{
|
|
// 탈착
|
|
TS_CS_PUTOFF_CARD msg;
|
|
msg.position = GetBeltSlotIndex( hItem );
|
|
SendMsg( &msg );
|
|
}
|
|
}
|
|
|
|
// creture item
|
|
void SInventoryMgr::Rq_CreatureUseItem( AR_HANDLE item_handle, AR_HANDLE target_handle )
|
|
{
|
|
if( m_vInventory.empty() ) return;
|
|
|
|
for( unsigned int i(0); m_vInventory.size()>i; i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == item_handle )
|
|
{
|
|
SInventorySlot* pItem = m_vInventory[i];
|
|
|
|
if( pItem->GetPosition() == ItemBase::WEAR_NONE )
|
|
{
|
|
//장착
|
|
TS_CS_PUTON_ITEM msg;
|
|
msg.item_handle = item_handle;
|
|
msg.target_handle = target_handle;
|
|
//msg.position = ItemBase::MAX_ITEM_WEAR; // 서버에서의 max 값을 날린다.. 크리처는 특정 장착 위치가 없다
|
|
// 서버에서의 max 값을 날린다.. 크리처는 특정 장착 위치가 없다.
|
|
// 2010.10.05. bintitle. 아바타에 SWAP 장비가 추가되어 MAX가 28 개로 늘었다. 하지만 크리쳐는 서버에서 MAX 24 만 인정하므로 24로 변경.
|
|
msg.position = ItemBase::MAX_ITEM_SPARE_WEAR;
|
|
assert( msg.position != 255 && "Data Error~ 장착 Position 이상~" );
|
|
SendMsg( &msg );
|
|
return; //사용
|
|
}
|
|
else
|
|
{
|
|
// 탈착
|
|
TS_CS_PUTOFF_ITEM msg;
|
|
msg.position = pItem->GetPosition()%1000;
|
|
msg.target_handle = target_handle;
|
|
SendMsg( &msg );
|
|
return; //사용
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SInventoryMgr::SetItemCoolTime( int nIndex, DWORD dwCoolTime )
|
|
{
|
|
if( nIndex >= 0 && nIndex < TS_SC_ITEM_COOL_TIME::MAX_ITEM_COOLTIME_GROUP )
|
|
{
|
|
if( m_dwRemain_time[nIndex] == 0 )
|
|
{
|
|
m_dwRemain_time[nIndex] = dwCoolTime;
|
|
m_dwCool_time[nIndex] = dwCoolTime;
|
|
m_dwCur_time[nIndex] = m_dwTime;
|
|
}
|
|
}
|
|
}
|
|
|
|
int SInventoryMgr::GetItemCurCoolTime( int nIndex )
|
|
{
|
|
if( nIndex >= 0 && nIndex < TS_SC_ITEM_COOL_TIME::MAX_ITEM_COOLTIME_GROUP )
|
|
return m_dwTime - m_dwCur_time[nIndex];
|
|
|
|
return 0;
|
|
}
|
|
|
|
int SInventoryMgr::GetItemMaxCoolTime( int nIndex )
|
|
{
|
|
if( nIndex >= 0 && nIndex < TS_SC_ITEM_COOL_TIME::MAX_ITEM_COOLTIME_GROUP )
|
|
return m_dwCool_time[nIndex];
|
|
|
|
return 0;
|
|
}
|
|
|
|
void SInventoryMgr::Process( DWORD time )
|
|
{
|
|
m_dwTime = time;
|
|
|
|
//아이템 그룹 쿨 타임 처리
|
|
for( int i(0); TS_SC_ITEM_COOL_TIME::MAX_ITEM_COOLTIME_GROUP>i; i++ )
|
|
{
|
|
if( (m_dwRemain_time[i] > 0) && (m_dwTime - m_dwCur_time[i]) >= (DWORD)m_dwRemain_time[i] )
|
|
{
|
|
m_dwRemain_time[i] = 0;
|
|
}
|
|
}
|
|
|
|
//대여 시간 처리
|
|
if( m_dwCheckLendingTime == 0 )
|
|
{
|
|
m_dwCheckLendingTime = m_dwTime;
|
|
}
|
|
else
|
|
{
|
|
if( (m_dwTime - m_dwCheckLendingTime) >= CHECK_LENDING_TIME )
|
|
{ //대여 아이템 갱신
|
|
m_dwCheckLendingTime = m_dwTime;
|
|
|
|
++m_nCheckCount;
|
|
|
|
for( unsigned int i(0); m_vLendingItem.size()>i; i++ )
|
|
{
|
|
SInventorySlot * pInvenSlot = m_vLendingItem[i];
|
|
|
|
if( pInvenSlot->GetItem()->remain_time > 0 )
|
|
--pInvenSlot->GetItem()->remain_time;
|
|
}
|
|
for ( unsigned int i(0); m_vInventory.size()>i; i++ )
|
|
{
|
|
if (( m_vInventory[i]->GetItem()->elemental_effect_type != 0 ) &&
|
|
( m_vInventory[i]->GetItem()->elemental_effect_remain_time > 0 ))
|
|
--m_vInventory[i]->GetItem()->elemental_effect_remain_time;
|
|
}
|
|
|
|
if( m_nCheckCount >= 60 )
|
|
{
|
|
m_nCheckCount = 0;
|
|
ProcMsgAtStatic( &(SIMSG_UI_STATE_UPDATE(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_INVENTORY)) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int SInventoryMgr::GetLendingItemTime( AR_HANDLE item_handle )
|
|
{
|
|
for( unsigned int i(0); m_vLendingItem.size()>i; i++ )
|
|
{
|
|
SInventorySlot * pInvenSlot = m_vLendingItem[i];
|
|
|
|
if( pInvenSlot->GetHandle() == item_handle )
|
|
{
|
|
return pInvenSlot->GetItem()->remain_time;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void SInventoryMgr::_addLendingItem( SInventorySlot* pItemSlot )
|
|
{
|
|
if( pItemSlot->GetItem()->remain_time > 0 )
|
|
{
|
|
m_vLendingItem.push_back( pItemSlot );
|
|
}
|
|
}
|
|
|
|
void SInventoryMgr::ClearCashItem()
|
|
{
|
|
m_vCashItemList.clear();
|
|
}
|
|
|
|
void SInventoryMgr::UpdateCashItem( TS_SC_COMMERCIAL_STORAGE_LIST::CommercialItemInfo* pCashItemInfo )
|
|
{
|
|
for( unsigned int i(0); m_vCashItemList.size()>i; i++ )
|
|
{
|
|
TS_SC_COMMERCIAL_STORAGE_LIST::CommercialItemInfo* pItemInfo = &m_vCashItemList[i];
|
|
|
|
if( pItemInfo->commercial_item_uid == pCashItemInfo->commercial_item_uid )
|
|
{ //기존것 갱신
|
|
pItemInfo->count = pCashItemInfo->count;
|
|
return;
|
|
}
|
|
}
|
|
|
|
//새로 추가
|
|
TS_SC_COMMERCIAL_STORAGE_LIST::CommercialItemInfo newItem;
|
|
|
|
newItem.commercial_item_uid = pCashItemInfo->commercial_item_uid;
|
|
newItem.code = pCashItemInfo->code;
|
|
newItem.count = pCashItemInfo->count;
|
|
|
|
m_vCashItemList.push_back( newItem );
|
|
}
|
|
|
|
//내구도 관련 메시지 체크 하여 출력하는 함수
|
|
void SInventoryMgr::CheckDurabilityMsg(SInventorySlot* pSlot)
|
|
{
|
|
/*if( pSlot->m_nLastDurabilityValue < pSlot->GetEtherealDurability())
|
|
pSlot->m_nLastDurabilityCheckPercent = 0;*/
|
|
|
|
const ItemBaseEx_info * pItem = GetItemDB().GetItemData( pSlot->GetItemCode() );
|
|
int CheckPercent = 0;
|
|
if(pItem && pSlot->m_nLastDurabilityValue > pSlot->GetEtherealDurability())
|
|
{
|
|
if(pSlot->getMaxEtherealDurability() > 0 && pItem->nClass != 451)
|
|
{
|
|
if( pSlot->GetEtherealDurability() == 0)
|
|
{
|
|
if(pSlot->m_nLastDurabilityCheckPercent == 0 || pSlot->m_nLastDurabilityCheckPercent != 1 )
|
|
CheckPercent = 1;
|
|
}
|
|
else if( pSlot->GetEtherealDurability() <= pSlot->getMaxEtherealDurability()*0.2 )
|
|
{
|
|
if(pSlot->m_nLastDurabilityCheckPercent == 0 || pSlot->m_nLastDurabilityCheckPercent != 20 )
|
|
CheckPercent = 20;
|
|
}
|
|
else if( pSlot->GetEtherealDurability() <= pSlot->getMaxEtherealDurability()*0.4 )
|
|
{
|
|
if(pSlot->m_nLastDurabilityCheckPercent == 0 || pSlot->m_nLastDurabilityCheckPercent != 40)
|
|
CheckPercent = 40;
|
|
}
|
|
else if( pSlot->GetEtherealDurability() <= pSlot->getMaxEtherealDurability()*0.6 )
|
|
{
|
|
if(pSlot->m_nLastDurabilityCheckPercent == 0 || pSlot->m_nLastDurabilityCheckPercent != 60)
|
|
CheckPercent = 60;
|
|
}
|
|
else if( pSlot->GetEtherealDurability() <= pSlot->getMaxEtherealDurability()*0.8 )
|
|
{
|
|
if(pSlot->m_nLastDurabilityCheckPercent == 0 || pSlot->m_nLastDurabilityCheckPercent != 80)
|
|
CheckPercent = 80;
|
|
}
|
|
|
|
|
|
if(CheckPercent > 0)
|
|
{
|
|
pSlot->m_nLastDurabilityCheckPercent = CheckPercent;
|
|
std::string basemsg;
|
|
if(CheckPercent==1)
|
|
basemsg = S(7907);
|
|
else if(CheckPercent==20)
|
|
basemsg = S(7906);
|
|
else
|
|
basemsg = S(7905);
|
|
|
|
XStringUtil::Replace( basemsg, "#@item_name@#", GetStringDB().GetString( pItem->nNameId ) );
|
|
//CStringUtil::StringFormat( "%s(%d%%)", basemsg.c_str(), basemsg );
|
|
m_pGame->AddChatMessage( basemsg.c_str() );
|
|
}
|
|
}
|
|
}
|
|
|
|
pSlot->m_nLastDurabilityValue = pSlot->GetEtherealDurability();
|
|
}
|
|
|
|
|
|
//Item 추가
|
|
int SInventoryMgr::AddItem( TS_ITEM_INFO * pItemInfo )
|
|
{
|
|
if( pItemInfo == NULL ) return 1;
|
|
|
|
//기존것 갱신
|
|
for( unsigned int i(0); m_vInventory.size()>i; i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == pItemInfo->handle )
|
|
{
|
|
/// 2010.12.08 아이템의 영혼력이 바꼈을 때, 오토 메세지 수정 - prodongi
|
|
if( m_vInventory[i]->GetEndurance() != 0 && pItemInfo->endurance == 0 )
|
|
SendGameInterfaceMsg( &SIMSG_UI_EMPTY_SOULPWER_MSG(pItemInfo->handle, true) );
|
|
else
|
|
SendGameInterfaceMsg( &SIMSG_UI_EMPTY_SOULPWER_MSG(pItemInfo->handle, false) );
|
|
|
|
m_vInventory[i]->SetUpdateCount( count_t( pItemInfo->count ) );
|
|
m_vInventory[i]->SetItem( pItemInfo );
|
|
|
|
CheckDurabilityMsg( m_vInventory[i] );
|
|
|
|
return (int)m_vInventory.size();
|
|
}
|
|
}
|
|
|
|
//새것 추가
|
|
SInventorySlot * pInvenSlot = new SInventorySlot;
|
|
pInvenSlot->SetUpdateCount( count_t( pItemInfo->count ) );
|
|
pInvenSlot->SetItem( pItemInfo ); //순서 있음
|
|
m_vInventory.push_back( pInvenSlot );
|
|
|
|
CheckDurabilityMsg( pInvenSlot );
|
|
|
|
|
|
//대여 시간이 있는 것들만 추가됨.
|
|
_addLendingItem( pInvenSlot );
|
|
|
|
if( pInvenSlot->IsEquipItem() && !pInvenSlot->IsStorageItem() && !pInvenSlot->IsSummonEquip() )
|
|
{
|
|
if( pItemInfo->wear_position < ItemBase::MAX_ITEM_WEAR &&
|
|
pItemInfo->wear_position > -1 )
|
|
{
|
|
m_itemCode[pItemInfo->wear_position] = pItemInfo->Code;
|
|
m_itemHandle[pItemInfo->wear_position] = pItemInfo->handle;
|
|
}
|
|
}
|
|
|
|
SetUpdateItemInfo( pInvenSlot );
|
|
|
|
/// 2010.12.08 영혼력이 0 이면 오토 메세지 출력 - prodongi
|
|
if (0 == pItemInfo->endurance)
|
|
{
|
|
unsigned int nEndurancePer;
|
|
int nResult = pInvenSlot->GetCrrEndurancePer(nEndurancePer);
|
|
if( nResult == SInventorySlot::ENDURANCE_SUCCESS )
|
|
{
|
|
if (0 == nEndurancePer && IsEndurance(nEndurancePer))
|
|
{
|
|
SendGameInterfaceMsg( &SIMSG_UI_EMPTY_SOULPWER_MSG(pItemInfo->handle, true) );
|
|
}
|
|
}
|
|
}
|
|
|
|
return (int)m_vInventory.size();
|
|
}
|
|
|
|
//Item 삭제
|
|
int SInventoryMgr::DropItem( AR_HANDLE item_handle )
|
|
{
|
|
if( m_vInventory.empty() ) return 0;
|
|
|
|
/*for( unsigned int i(0); m_vInventory.size()>i; i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == item_handle )
|
|
{
|
|
delete m_vInventory[i];
|
|
m_vInventory.erase( m_vInventory.begin()+i );
|
|
return 1;
|
|
}
|
|
}*/
|
|
|
|
std::vector<SInventorySlot*>::iterator it = m_vInventory.begin();
|
|
while( it != m_vInventory.end() )
|
|
{
|
|
SInventorySlot* pSlot = (*it);
|
|
if( pSlot && pSlot->GetHandle() == item_handle )
|
|
{
|
|
SetUpdateItemInfo( pSlot );
|
|
|
|
_delLendingItem( pSlot );
|
|
|
|
delete pSlot;
|
|
_onEraseItem( m_vInventory.erase(it) );
|
|
return 1;
|
|
}
|
|
it++;
|
|
}
|
|
|
|
SetUpdateItemInfo( NULL );
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
void SInventoryMgr::_delLendingItem( SInventorySlot* pItemSlot )
|
|
{
|
|
std::vector<SInventorySlot*>::iterator it = m_vLendingItem.begin();
|
|
while( it != m_vLendingItem.end() )
|
|
{
|
|
SInventorySlot* pSlot = (*it);
|
|
if( pSlot && pSlot->GetHandle() == pItemSlot->GetHandle() )
|
|
{
|
|
m_vLendingItem.erase(it);
|
|
return;
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
|
|
//Item 제거.
|
|
int SInventoryMgr::DestroyItem( AR_HANDLE item_handle )
|
|
{
|
|
// 아이템 파괴상태 일 경우 함수종료.
|
|
if( m_vInventory.empty() || m_rqItemState == RQ_ITEM_STATE::RQ_ITEM_STATE_ERASE )
|
|
return 0;
|
|
|
|
// 상태 초기화.
|
|
if( m_rqItemState == RQ_ITEM_STATE::RQ_ITEM_STATE_DROP )
|
|
m_rqItemState = RQ_ITEM_STATE::RQ_ITEM_STATE_NONE;
|
|
|
|
/*for( unsigned int i(0); m_vInventory.size()>i; i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == item_handle )
|
|
{
|
|
delete m_vInventory[i];
|
|
m_vInventory.erase( m_vInventory.begin()+i );
|
|
return 1;
|
|
}
|
|
}*/
|
|
std::vector<SInventorySlot*>::iterator it = m_vInventory.begin();
|
|
while( it != m_vInventory.end() )
|
|
{
|
|
SInventorySlot* pSlot = (*it);
|
|
if( pSlot && pSlot->GetHandle() == item_handle )
|
|
{
|
|
/// 2010.12.08 영혼력 충전 오토메세지 삭제 - prodongi
|
|
if (0 == pSlot->GetEndurance())
|
|
{
|
|
SendGameInterfaceMsg( &SIMSG_UI_EMPTY_SOULPWER_MSG(item_handle, false) );
|
|
}
|
|
|
|
//모두 다 버린다. 버릴 갯수 설정
|
|
pSlot->SetUpdateCount( pSlot->GetItemCount(), true );
|
|
|
|
SetUpdateItemInfo( pSlot );
|
|
|
|
_delLendingItem( pSlot );
|
|
|
|
delete pSlot;
|
|
_onEraseItem( m_vInventory.erase(it) );
|
|
return 1;
|
|
}
|
|
it++;
|
|
}
|
|
|
|
SetUpdateItemInfo( NULL );
|
|
|
|
return 0;
|
|
}
|
|
|
|
void SInventoryMgr::_onEraseItem( std::vector<SInventorySlot*>::iterator it )
|
|
{
|
|
for( ; it != m_vInventory.end() ; ++it )
|
|
{
|
|
((*it)->GetItem())->index--;
|
|
}
|
|
}
|
|
|
|
// 아이템파괴.
|
|
int SInventoryMgr::EraseItem( AR_HANDLE handle, __int64 count )
|
|
{
|
|
// 상태 초기화.
|
|
if( m_rqItemState == RQ_ITEM_STATE::RQ_ITEM_STATE_ERASE )
|
|
m_rqItemState = RQ_ITEM_STATE::RQ_ITEM_STATE_NONE;
|
|
|
|
// 0 이면 파괴 실패.
|
|
if( handle == 0 )
|
|
return 0;
|
|
|
|
SInventorySlot * pSlot;
|
|
int size = m_vInventory.size();
|
|
for( std::vector<SInventorySlot*>::iterator it=m_vInventory.begin(); it!=m_vInventory.end(); ++it )
|
|
{
|
|
pSlot = (*it);
|
|
if( pSlot && pSlot->GetHandle() == handle ) // GetItemCode() == itemCode )
|
|
{
|
|
SendDestroyMsg(count, pSlot->GetItemCode() );
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//SetUpdateItemInfo( NULL );
|
|
|
|
//// 0 이면 파괴 실패.
|
|
//if( itemCode == 0 )
|
|
// return 0;
|
|
|
|
//SInventorySlot * pSlot;
|
|
//int size = m_vInventory.size();
|
|
//for( std::vector<SInventorySlot*>::iterator it=m_vInventory.begin(); it!=m_vInventory.end(); ++it )
|
|
//{
|
|
// pSlot = (*it);
|
|
// if( pSlot && pSlot->GetItemCode() == itemCode )
|
|
// {
|
|
// if( pSlot->GetItemCount().getAmount() == 0 ) // 0개이하면 제거.
|
|
// {
|
|
// _delLendingItem( pSlot );
|
|
|
|
// delete pSlot;
|
|
// m_vInventory.erase( it );
|
|
// return 1;
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void SInventoryMgr::SendDestroyMsg(int count, int itemCode)
|
|
{
|
|
// 시스템메세지 출력.
|
|
SMSG_CHATTING msg;
|
|
msg.nChatType = CHAT_SYSTEM;
|
|
msg.szSender = "";
|
|
char strCount[10]={0,};
|
|
::itoa( count, strCount, 10 );
|
|
msg.strText = SStringDB::ParseString( 730, "#@item_name@#", GetStringDB( ).GetString( GetItemDB().GetTextID( itemCode ) ), "#@item_num@#", strCount );
|
|
//msg.strText = CStringUtil::StringFormat( "[%s - %d개] 파괴 되었습니다.", GetStringDB( ).GetString( GetItemDB().GetTextID( pSlot->GetItemCode() ) ), count );
|
|
this->m_pGame->ProcMsgAtStatic( &msg );
|
|
}
|
|
|
|
int SInventoryMgr::UpdateItemCount( AR_HANDLE item_handle, count_t nItemCount, bool fromDestory /* = false */ )
|
|
{
|
|
if( m_vInventory.empty() ) return 0;
|
|
|
|
SInventorySlot * pSlot;
|
|
for( unsigned int i(0); m_vInventory.size()>i; i++ )
|
|
{
|
|
pSlot = m_vInventory[i];
|
|
if( pSlot->GetHandle() == item_handle )
|
|
{
|
|
count_t beforeCount = pSlot->GetItemCount();
|
|
pSlot->SetUpdateCount( nItemCount );
|
|
pSlot->SetItemCount( nItemCount );
|
|
|
|
SetUpdateItemInfo( pSlot );
|
|
|
|
// 0개면 제거.
|
|
if( pSlot->GetItemCount().getAmount() < 1 )
|
|
{
|
|
std::vector<SInventorySlot*>::iterator it = find( m_vInventory.begin(), m_vInventory.end(), pSlot );
|
|
if( it != m_vInventory.end() )
|
|
{
|
|
// 2012. 7. 20 - marine 완전히 파괴된 경우이므로 이전에 업데이트 하기 전의 count를 쓴다.
|
|
// EraseItem()에서도 메세지를 넣지만 여기서 삭제되면 핸들이 사라지기때문에 삭제되기전에 메시지를 날린다.
|
|
if(fromDestory)
|
|
SendDestroyMsg( beforeCount.getAmount(), pSlot->GetItemCode() );
|
|
_delLendingItem( pSlot );
|
|
delete pSlot;
|
|
_onEraseItem( m_vInventory.erase(it) );
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
SetUpdateItemInfo( NULL );
|
|
|
|
return 0;
|
|
}
|
|
|
|
SInventorySlot* SInventoryMgr::GetItemInfo( AR_HANDLE hItem )
|
|
{
|
|
if( hItem == NULL ) return NULL;
|
|
if( m_vInventory.empty() ) return NULL;
|
|
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == hItem )
|
|
return m_vInventory[i];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
SInventorySlot* SInventoryMgr::GetItemInfo( int nWearPos )
|
|
{
|
|
if( nWearPos == -1 ) return NULL;
|
|
if( m_vInventory.empty() ) return NULL;
|
|
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->IsPlayerEquipItem(nWearPos) )
|
|
return m_vInventory[i];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
SInventorySlot* SInventoryMgr::GetItemInfo( ItemInstance::ItemUID itemUID )
|
|
{
|
|
if( m_vInventory.empty() ) return NULL;
|
|
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->GetUID() == itemUID )
|
|
return m_vInventory[i];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void SInventoryMgr::GetItemInfo( std::vector<SInventorySlot*>& rItemList, ItemBase::ItemCode code, int level, int enhance )
|
|
{
|
|
if( m_vInventory.empty() ) return;
|
|
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
bool bPush(true);
|
|
if( m_vInventory[i]->GetItemCode() == code )
|
|
{
|
|
if( level && m_vInventory[i]->GetLevel() != level )
|
|
bPush = false;
|
|
if( enhance && m_vInventory[i]->GetEnhance() != enhance )
|
|
bPush = false;
|
|
if( bPush ) rItemList.push_back(m_vInventory[i]);
|
|
}
|
|
}
|
|
}
|
|
SInventorySlot* SInventoryMgr::GetCodeItemInfo( ItemBase::ItemCode code )
|
|
{
|
|
if( m_vInventory.empty() ) return NULL;
|
|
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->GetItemCode() == code )
|
|
{
|
|
return m_vInventory[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
SInventorySlot* SInventoryMgr::GetComparableEquipItemInfo( SInventorySlot* pItem, bool second_equip )
|
|
{
|
|
if( pItem->IsEquipItem() == false )
|
|
{
|
|
return GetComparableEquipItemInfo( pItem->GetItemCode(), second_equip );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
SInventorySlot* SInventoryMgr::GetComparableEquipItemInfo( ItemBase::ItemCode code, bool second_equip )
|
|
{
|
|
SInventorySlot* pEquipItem = NULL;
|
|
int wear_pos = GetItemDB().GetWearType( code );
|
|
if( wear_pos >= 0 )
|
|
{
|
|
// 벨트 슬롯은 비교하지 않는다.(너무 많다.)
|
|
if( wear_pos == ItemBase::ItemWearType::WEAR_BELT_SLOT )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// 반지 혹은 무기
|
|
if( wear_pos == ItemBase::ItemWearType::WEAR_RING ||
|
|
wear_pos == ItemBase::ItemWearType::WEAR_WEAPON ||
|
|
wear_pos == ItemBase::ItemWearType::WEAR_TWOHAND )
|
|
{
|
|
if( second_equip )
|
|
{
|
|
if( wear_pos == ItemBase::ItemWearType::WEAR_RING )
|
|
{
|
|
// 두번째 반지
|
|
wear_pos = ItemBase::ItemWearType::WEAR_RING + 1;
|
|
}
|
|
else
|
|
{
|
|
// 이도류의 경우만. 방패는 제외한다.
|
|
wear_pos = ItemBase::ItemWearType::WEAR_SHIELD;
|
|
pEquipItem = GetItemInfo( wear_pos );
|
|
if( pEquipItem != NULL )
|
|
{
|
|
if( GetItemDB().GetWearType( pEquipItem->GetItemCode() ) == ItemBase::ItemWearType::WEAR_WEAPON )
|
|
{
|
|
return pEquipItem;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 반지가 아닌데 두번째 장비를 요구하면 리턴
|
|
if( second_equip )
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
pEquipItem = GetItemInfo( wear_pos );
|
|
if( pEquipItem == NULL )
|
|
{
|
|
// 무기라면(투핸드 원핸드 비교)
|
|
if( wear_pos == ItemBase::ItemWearType::WEAR_WEAPON )
|
|
{
|
|
pEquipItem = GetItemInfo( ItemBase::ItemWearType::WEAR_TWOHAND );
|
|
}
|
|
else if( wear_pos == ItemBase::ItemWearType::WEAR_TWOHAND )
|
|
{
|
|
pEquipItem = GetItemInfo( ItemBase::ItemWearType::WEAR_WEAPON );
|
|
}
|
|
}
|
|
}
|
|
|
|
return pEquipItem;
|
|
}
|
|
|
|
SInventorySlot* SInventoryMgr::GetItemInfoCreatureUID( int nUID )
|
|
{
|
|
if( m_vInventory.empty() ) return NULL;
|
|
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->GetItem()->socket[0] == nUID )
|
|
return m_vInventory[i];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool SInventoryMgr::GetInvenDataList2( int nCategory, std::vector< SInventorySlot*>& vecInvenList )
|
|
{
|
|
//gmpbigsun( 20130904 ) : nCategory에 따라 Type Value를 재설정하고 아이템DB값의 bitset포함여부로 판단한다.
|
|
|
|
vecInvenList.clear();
|
|
|
|
int nNewValue = 0;
|
|
|
|
switch( nCategory )
|
|
{
|
|
case UI_ITEM_ALL: nNewValue = UI_ITEM_NEW_ALL; break;
|
|
case UI_ITEM_EQUIP: nNewValue = UI_ITEM_NEW_1; break;
|
|
case UI_ITEM_USE: nNewValue = UI_ITEM_NEW_2; break;
|
|
case UI_ITEM_CARD: nNewValue = UI_ITEM_NEW_3; break;
|
|
case UI_ITEM_CREATURE: nNewValue = UI_ITEM_NEW_4; break;
|
|
case UI_ITEM_EXPEND: nNewValue = UI_ITEM_NEW_5; break;
|
|
case UI_ITEM_ETC: nNewValue = UI_ITEM_NEW_6; break;
|
|
case UI_ITEM_QUEST: nNewValue = UI_ITEM_NEW_7; break;
|
|
case UI_ITEM_CRU: nNewValue = UI_ITEM_NEW_8; break;
|
|
case UI_ITEM_COLLECTION: nNewValue = UI_ITEM_NEW_9; break;
|
|
case UI_ITEM_CARD2: nNewValue = UI_ITEM_NEW_10; break;
|
|
|
|
default:
|
|
nNewValue = 0;
|
|
break;
|
|
}
|
|
|
|
|
|
//TODO:
|
|
//nNewVlaue 와 DB의 bitset &(and)결과에 의해 결과 리스트를 뽑음.
|
|
|
|
int nMaxSize = static_cast<int>(m_vInventory.size());
|
|
for( int i = 0; i < nMaxSize; ++i )
|
|
{
|
|
SInventorySlot* pSlot = m_vInventory[i];
|
|
|
|
if( !pSlot )
|
|
continue; //oops
|
|
|
|
//창고아이템 pass
|
|
if( pSlot->IsStorageItem() )
|
|
continue;
|
|
|
|
const ItemBaseEx_info* pItem = GetItemDB().GetItemData( pSlot->GetItemCode() );
|
|
|
|
if( !pItem )
|
|
continue; //oops
|
|
|
|
if( nNewValue == UI_ITEM_ALL )
|
|
{
|
|
|
|
//AziaMafia All item inventaire
|
|
/*
|
|
if ( !( pItem->nCategory_Bitset & UI_ITEM_NEW_3 ) &&
|
|
!( pItem->nCategory_Bitset & UI_ITEM_NEW_4 ) )
|
|
{
|
|
vecInvenList.push_back( pSlot );
|
|
}
|
|
*/
|
|
|
|
//add item into all
|
|
if ((!(pItem->nCategory_Bitset & UI_ITEM_NEW_7) && !(pItem->nCategory_Bitset & UI_ITEM_NEW_4) &&
|
|
!(pItem->nCategory_Bitset & UI_ITEM_NEW_3)) || pSlot->GetItemCode() == 800001 //800001 Unit Card
|
|
|
|
)
|
|
{
|
|
vecInvenList.push_back(pSlot);
|
|
}
|
|
}
|
|
|
|
//Category Creature
|
|
else if (UI_ITEM_NEW_4 == nNewValue && (pSlot->GetXFlag().IsOn(ItemInstance::ITEM_FLAG_CARD)
|
|
|| pSlot->GetItemCode() == 800000 // Chalk of Restoration
|
|
|| pSlot->GetItemCode() == 710001 // Soul Catalyst<Creature enhancement item><ep7>
|
|
|| pSlot->GetItemCode() == 710004)) // Advanced Soul Catalyst<Creature enhancement item><ep7>
|
|
vecInvenList.push_back(pSlot);
|
|
|
|
// else if( UI_ITEM_NEW_7 == nNewValue && pItem->CheckFlag( ItemBase::ITEM_FLAG::FLAG_QUEST ) )
|
|
// vecInvenList.push_back( pSlot );
|
|
// else if( UI_ITEM_NEW_8 == nNewValue && pItem->CheckFlag( ItemBase::ITEM_FLAG::FLAG_CASHITEM ) )
|
|
// vecInvenList.push_back( pSlot );
|
|
|
|
else if (UI_ITEM_NEW_10 == nNewValue )
|
|
{
|
|
SGameAvatarEx* pOwner = g_pCurrentGameSystem->GetLocalPlayer();
|
|
|
|
if (pOwner && (ItemBase::GROUP_SKILLCARD == pItem->nGroup
|
|
|| pSlot->GetItemCode() == 700401 // Cube de Compétence
|
|
|| pSlot->GetItemCode() == 700402 // Ancien Cube de Compétence
|
|
))
|
|
if (isWearableSkillCardItem(pItem, g_pCurrentGameSystem->GetSkillSlotMgr() ) == true )
|
|
vecInvenList.push_back(pSlot);
|
|
}
|
|
|
|
else
|
|
{
|
|
if( pItem->nCategory_Bitset & nNewValue )
|
|
vecInvenList.push_back( pSlot );
|
|
}
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
/// 2010.11.24 - prodongi
|
|
void SInventoryMgr::GetInvenDataList( int nCategory, std::vector<SInventorySlot*>& vecInvenList, SCreatureSlotMgr const& creatureSlotMgr, bool bExceptEquipItem, bool bExceptDontBuyItem )
|
|
//void SInventoryMgr::GetInvenDataList( int nCategory, std::vector<SInventorySlot*>& vecInvenList, bool bExceptEquipItem, bool bExceptDontBuyItem )
|
|
{
|
|
vecInvenList.clear();
|
|
|
|
int nUseType = (-1);
|
|
switch( nCategory )
|
|
{
|
|
case UI_ITEM_ALL: nUseType = (-1); break;
|
|
case UI_ITEM_EQUIP: nUseType = ItemBase::TYPE_ARMOR; break;
|
|
case UI_ITEM_CARD: nUseType = ItemBase::TYPE_CARD; break;
|
|
case UI_ITEM_EXPEND: nUseType = ItemBase::TYPE_USEABLE; break;
|
|
case UI_ITEM_ETC: nUseType = ItemBase::TYPE_ETC; break;
|
|
case UI_ITEM_USE: nUseType = ItemBase::TYPE_USE; break;
|
|
case UI_ITEM_QUEST: nUseType = 9999; break; //퀘스트는 플래그
|
|
case UI_ITEM_CREATURE: nUseType = ItemBase::TYPE_CREATURE; break; //servantes 2010.11.24 크리처 버튼 안 눌러지는 버그 수정
|
|
case UI_ITEM_CRU: nUseType = -2; break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if(nUseType == ItemBase::TYPE_CREATURE) //크리처 //servantes 2010.11.24 크리처 버튼 안 눌러지는 버그 수정
|
|
{
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
SInventorySlot* pSlot = m_vInventory[i];
|
|
|
|
int nGruop = GetItemDB().GetGroup(pSlot->GetItemCode()); //그룹
|
|
bool bCARD = pSlot->GetXFlag().IsOn( ItemInstance::ITEM_FLAG_CARD ); //크리처 장비 카드 여부
|
|
|
|
if( nGruop == ItemBase::GROUP_SUMMONCARD || //크리처 카드
|
|
bCARD ) //크리처 장비 카드
|
|
{
|
|
/// 2010.12.29 - prodongi
|
|
//vecInvenList.push_back( pSlot );
|
|
const ItemBaseEx_info * item = GetItemDB().GetItemData( pSlot->GetItemCode() );
|
|
if (enableSellItem(bExceptEquipItem, bExceptDontBuyItem, pSlot, creatureSlotMgr, item))
|
|
{
|
|
vecInvenList.push_back( pSlot );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(nUseType == ItemBase::TYPE_CARD) //카드 //servantes 2010.11.24
|
|
{
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
SInventorySlot* pSlot = m_vInventory[i];
|
|
|
|
int nGruop = GetItemDB().GetGroup(pSlot->GetItemCode()); //그룹
|
|
|
|
if( nGruop == ItemBase::GROUP_SKILLCARD || //스킬 카드
|
|
nGruop == ItemBase::GROUP_ITEMCARD || //아이템 카드
|
|
nGruop == ItemBase::GROUP_SPELLCARD || //스펠 카드
|
|
nGruop == ItemBase::GROUP_SUMMONCARD ) //크리처 카드
|
|
{
|
|
/// 2010.12.29 - prodongi
|
|
//vecInvenList.push_back( pSlot );
|
|
const ItemBaseEx_info * item = GetItemDB().GetItemData( pSlot->GetItemCode() );
|
|
if (enableSellItem(bExceptEquipItem, bExceptDontBuyItem, pSlot, creatureSlotMgr, item))
|
|
{
|
|
vecInvenList.push_back( pSlot );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if( nUseType != 9999 )
|
|
{
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->IsStorageItem() ) continue;
|
|
|
|
|
|
const ItemBaseEx_info * pItem = GetItemDB().GetItemData( m_vInventory[i]->GetItemCode() );
|
|
|
|
bool bInsert = false;
|
|
if( pItem->nType == nUseType )
|
|
{
|
|
bInsert = true;
|
|
|
|
if( nUseType == ItemBase::TYPE_ARMOR )
|
|
{ //장비 얻을때, 카드화 아이템 제외
|
|
if( m_vInventory[i]->GetXFlag().IsOn( ItemInstance::ITEM_FLAG_CARD ) )
|
|
bInsert = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( nUseType == ItemBase::TYPE_CARD )
|
|
{ //카드 얻을때, 카드화 아이템 포함
|
|
if( m_vInventory[i]->GetXFlag().IsOn( ItemInstance::ITEM_FLAG_CARD ) )
|
|
bInsert = true;
|
|
}
|
|
else
|
|
{
|
|
// 실제적인 기타 ( 각 탭에 매칭되는 타입 이외의 아이템들 )
|
|
if( nUseType == -2 )
|
|
{
|
|
if( pItem->nType != ItemBase::TYPE_ARMOR && pItem->nType != ItemBase::TYPE_USEABLE && pItem->nType != ItemBase::TYPE_ETC
|
|
&& pItem->nType != ItemBase::TYPE_CREATURE && pItem->nType != ItemBase::TYPE_CARD )
|
|
bInsert = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if usetype == -1 : 모든 리스트, else : 특정 탭에 해당하는 아이템만, 퀘스트 아이템 제외, 상점 매각 불가 제외
|
|
|
|
//if (nUseType == -1 || bInsert && !pItem->CheckFlag(ItemBase::ITEM_FLAG::FLAG_QUEST))
|
|
if( nUseType == -1 || bInsert && !pItem->CheckFlag( ItemBase::ITEM_FLAG::FLAG_QUEST ) )
|
|
{
|
|
/// 2010.12.29 - prodongi
|
|
/*
|
|
// if except equipitem : 비장착된 아이템만 장착된 카드도 제외, else : 창고 아이템만 제외
|
|
if( (bExceptEquipItem && (!m_vInventory[i]->IsEquipItem() && !IsEquipCard(m_vInventory[i]->GetHandle())) ) ||
|
|
(!bExceptEquipItem && !m_vInventory[i]->IsStorageItem() ) )
|
|
{
|
|
if( bExceptDontBuyItem )
|
|
{ //상점, 매각 불가 아이템은 스킵
|
|
if( pItem->CheckFlag( ItemBase::ITEM_FLAG::FLAG_CANT_SELL ) )
|
|
continue;
|
|
}
|
|
|
|
/// 2010.11.15 - prodongi
|
|
if (bExceptEquipItem)
|
|
{
|
|
if (IsBeltSlotCard(m_vInventory[i]->GetHandle()))
|
|
continue;
|
|
/// 2010.11.24 편성된 크리처 카드 인지 검사 - prodongi
|
|
if (creatureSlotMgr.IsExistCreatureCard(m_vInventory[i]->GetHandle()))
|
|
continue;
|
|
}
|
|
|
|
vecInvenList.push_back( m_vInventory[i] );
|
|
}
|
|
*/
|
|
if (enableSellItem(bExceptEquipItem, bExceptDontBuyItem, m_vInventory[i], creatureSlotMgr, pItem))
|
|
{
|
|
vecInvenList.push_back( m_vInventory[i] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->IsStorageItem() ) continue;
|
|
|
|
const ItemBaseEx_info * pItem = GetItemDB().GetItemData( m_vInventory[i]->GetItemCode() );
|
|
|
|
if( pItem->CheckFlag( ItemBase::ITEM_FLAG::FLAG_QUEST ) )
|
|
{
|
|
if( (bExceptEquipItem && !m_vInventory[i]->IsEquipItem()) || (!bExceptEquipItem && !m_vInventory[i]->IsStorageItem() ) )
|
|
vecInvenList.push_back(m_vInventory[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// shop list
|
|
void SInventoryMgr::AddShopItem( SMSG_MARKET* pMsg )
|
|
{
|
|
SAFE_DELETE_VECTOR( m_vecShopList );
|
|
|
|
SMSG_MARKET::ItemInfo* pItemInfo = pMsg->pItemInfo;
|
|
for( int i = 0; i < pMsg->item_count; i++ )
|
|
{
|
|
SShopSlot* pSlot = new SShopSlot;
|
|
pSlot->SetNpcHandle( pMsg->npc_handle );
|
|
pSlot->SetItemCode( pItemInfo->code );
|
|
pSlot->SetPrice( money_t( pItemInfo->price ) );
|
|
pSlot->SetHuntaHolicPoint( money_t( pItemInfo->huntaholic_point ) ); // #2.1.2.11.1
|
|
|
|
pSlot->SetArenaPoint(money_t(pItemInfo->arena_point));
|
|
pSlot->SetRank( GetItemDB().GetItemRank( pItemInfo->code ) );
|
|
|
|
m_vecShopList.push_back(pSlot);
|
|
|
|
pItemInfo++;
|
|
}
|
|
}
|
|
void SInventoryMgr::GetShopDataList( int nCategory, std::vector<SShopSlot*>& vecShopList )
|
|
{
|
|
vecShopList.clear();
|
|
|
|
int nUseType = (-1);
|
|
switch( nCategory )
|
|
{
|
|
case UI_ITEM_ALL: nUseType = (-1); break;
|
|
case UI_ITEM_EQUIP: nUseType = ItemBase::TYPE_ARMOR; break;
|
|
case UI_ITEM_CARD: nUseType = ItemBase::TYPE_CARD; break;
|
|
case UI_ITEM_EXPEND: nUseType = ItemBase::TYPE_USEABLE; break;
|
|
case UI_ITEM_ETC: nUseType = ItemBase::TYPE_ETC; break;
|
|
case UI_ITEM_USE: nUseType = ItemBase::TYPE_USE; break;
|
|
case UI_ITEM_QUEST: nUseType = 9999; break; //퀘스트는 플래그로 처리
|
|
case UI_ITEM_CRU: nUseType = -2; break;
|
|
}
|
|
|
|
if( nUseType != 9999 )
|
|
{
|
|
std::vector<SShopSlot*>::iterator it = m_vecShopList.begin();
|
|
while( it != m_vecShopList.end() )
|
|
{
|
|
SShopSlot* pSlot = (*it);
|
|
const ItemBaseEx_info * pItem = GetItemDB().GetItemData( pSlot->GetItemCode() );
|
|
|
|
if( nUseType == -1 || GetItemDB().GetUseType(pSlot->GetItemCode()) == nUseType && !pItem->CheckFlag( ItemBase::ITEM_FLAG::FLAG_QUEST ) )
|
|
vecShopList.push_back(pSlot);
|
|
else
|
|
{
|
|
if( nUseType == -2 && GetItemDB().GetUseType( pSlot->GetItemCode() ) != nUseType && !pItem->CheckFlag( ItemBase::ITEM_FLAG::FLAG_QUEST ) )
|
|
vecShopList.push_back( pSlot );
|
|
}
|
|
it++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::vector<SShopSlot*>::iterator it = m_vecShopList.begin();
|
|
while( it != m_vecShopList.end() )
|
|
{
|
|
SShopSlot* pSlot = (*it);
|
|
|
|
const ItemBaseEx_info * pItem = GetItemDB().GetItemData( pSlot->GetItemCode() );
|
|
|
|
if( pItem->CheckFlag( ItemBase::ITEM_FLAG::FLAG_QUEST ) )
|
|
vecShopList.push_back(pSlot);
|
|
it++;
|
|
}
|
|
}
|
|
}
|
|
SShopSlot* SInventoryMgr::GetShopItem( int nItemCode )
|
|
{
|
|
std::vector<SShopSlot*>::iterator it = m_vecShopList.begin();
|
|
while( it != m_vecShopList.end() )
|
|
{
|
|
SShopSlot* pSlot = (*it);
|
|
if( pSlot->GetItemCode() == nItemCode )
|
|
return pSlot;
|
|
it++;
|
|
}
|
|
return NULL;
|
|
}
|
|
void SInventoryMgr::SetUpdateItemInfo( SInventorySlot* pSlot )
|
|
{
|
|
if( pSlot )
|
|
{
|
|
*m_pUpdateItemInfo = *pSlot;
|
|
m_pUpdateItemInfo->SetExistence( true );
|
|
}
|
|
else
|
|
{
|
|
m_pUpdateItemInfo->SetExistence( false );
|
|
}
|
|
}
|
|
|
|
SInventorySlot* SInventoryMgr::GetUpdateItemInfo( AR_HANDLE handle )
|
|
{
|
|
if( m_pUpdateItemInfo->GetHandle() == handle )
|
|
{
|
|
if( m_pUpdateItemInfo->IsExistence() )
|
|
return m_pUpdateItemInfo;
|
|
else
|
|
return NULL;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
bool SInventoryMgr::IsExistItem( int nItemCode )
|
|
{
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->GetItemCode() == nItemCode )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool SInventoryMgr::IsExistItem( AR_HANDLE hItem )
|
|
{
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == hItem )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool SInventoryMgr::IsExistItem( AR_HANDLE hItem, count_t nItemCount )
|
|
{
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->GetHandle() == hItem &&
|
|
m_vInventory[i]->GetItemCount() >= nItemCount )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool SInventoryMgr::IsExistInvenItem( int nItemCode )
|
|
{
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->GetItemCode() == nItemCode && !m_vInventory[i]->IsStorageItem() )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool SInventoryMgr::IsAwakeningItem(SInventorySlot* pSlot)
|
|
{
|
|
return pSlot->IsAwakeningItem();
|
|
}
|
|
|
|
|
|
AR_HANDLE SInventoryMgr::GetFirstFindItem( int nItemCode )
|
|
{
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->GetItemCode() == nItemCode )
|
|
return m_vInventory[i]->GetHandle();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
count_t SInventoryMgr::GetItemCount( int nItemCode )
|
|
{
|
|
int nSize = (int)m_vInventory.size();
|
|
for( int i = 0; i < nSize; ++i )
|
|
{
|
|
if( m_vInventory[i]->GetItemCode() == nItemCode )
|
|
return m_vInventory[i]->GetItemCount();
|
|
}
|
|
|
|
return count_t( 0 );
|
|
}
|
|
|
|
void SInventoryMgr::GetEquipItemList( std::vector<SInventorySlot*>& vecInvenList )
|
|
{
|
|
vecInvenList.clear();
|
|
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->IsEquipItem() && !m_vInventory[i]->IsStorageItem() && !m_vInventory[i]->IsSummonEquip() )
|
|
vecInvenList.push_back(m_vInventory[i]);
|
|
}
|
|
}
|
|
|
|
// 2010.07.22 - prodongi
|
|
void SInventoryMgr::getCreatureEquipItemList( std::vector<SInventorySlot*>& vecInvenList, AR_HANDLE creatureHandle )
|
|
{
|
|
vecInvenList.clear();
|
|
|
|
for( int i = 0; i < static_cast<int>(m_vInventory.size()); i++ )
|
|
{
|
|
if( m_vInventory[i]->IsEquipItem() && !m_vInventory[i]->IsStorageItem() && m_vInventory[i]->IsSummonEquip() )
|
|
{
|
|
if (m_vInventory[i]->GetWearHandle() == creatureHandle)
|
|
vecInvenList.push_back(m_vInventory[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SInventoryMgr::SortItemList()
|
|
{
|
|
struct TItemLess
|
|
{
|
|
//두인자가 같을 경우 무조건 false가 나오도록 해야한다. 흠 false가 바꾸는 것인데...
|
|
bool operator () ( SInventorySlot* a, SInventorySlot* b )
|
|
{
|
|
if( !a || !b ) return true;
|
|
|
|
TS_ITEM_INFO* pInfo_1 = a->GetItem();
|
|
TS_ITEM_INFO* pInfo_2 = b->GetItem();
|
|
if( !pInfo_1 || !pInfo_2 ) return true;
|
|
|
|
return pInfo_1->index < pInfo_2->index;
|
|
}
|
|
} pred;
|
|
|
|
std::sort( m_vInventory.begin(), m_vInventory.end(), pred );
|
|
}
|
|
|
|
/// 2010.12.29 - prodongi
|
|
bool SInventoryMgr::enableSellItem(bool exceptEquipItem, bool exceptDontBuyItem, SInventorySlot const* slot,
|
|
SCreatureSlotMgr const& creatureSlotMgr, ItemBaseEx_info const* item) const
|
|
{
|
|
// if except equipitem : 비장착된 아이템만 장착된 카드도 제외, else : 창고 아이템만 제외
|
|
if( (exceptEquipItem && (!slot->IsEquipItem() && !IsEquipCard(slot->GetHandle())) ) ||
|
|
(!exceptEquipItem && !slot->IsStorageItem() ) )
|
|
{
|
|
if( exceptDontBuyItem )
|
|
{ //상점, 매각 불가 아이템은 스킵
|
|
if( item && item->CheckFlag( ItemBase::ITEM_FLAG::FLAG_CANT_SELL ) )
|
|
return false;
|
|
}
|
|
|
|
/// 2010.11.15 - prodongi
|
|
if (exceptEquipItem)
|
|
{
|
|
if (IsBeltSlotCard(slot->GetHandle()))
|
|
return false;
|
|
/// 2010.11.24 편성된 크리처 카드 인지 검사 - prodongi
|
|
if (creatureSlotMgr.IsExistCreatureCard(slot->GetHandle()))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
} |