#include "stdafx.h" #include "ItemStorage.h" #include "ItemSlot.h" #include "ui/UIItemSystem.h" #include "ui/UISystem.h" #include "ItemManager.h" ////////////////////////////////////////////////////////////////////////// CSYItemBagSlotContainer::CSYItemBagSlotContainer() { m_bIsBag = true; m_pBag = NULL; } CSYItemBagSlotContainer::~CSYItemBagSlotContainer() { m_pBag = NULL; } SYItemBag* CSYItemBagSlotContainer::GetSYItemBagFromContainer() // 如果为空,表示该位置不存在一个背包。 { if (m_pBag) { return m_pBag; } return NULL; } void CSYItemBagSlotContainer::CopyBagData() { if (m_pBag) { m_pBag->CopyToStorage(); } //跟新包裹里的道具到Container。。并且映射到UI。 } void CSYItemBagSlotContainer::SetSYItemBag(SYItemBag* pBag) //先需要释放资源。设定背包,根据背包的格子数重新分配Slot. { if (pBag) { Init(pBag->GetSlotCount(),0); m_pBag = pBag; }else { Release(); m_pBag = NULL; Init(0,0); } } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// CStorage::CStorage(StorageType pType) { m_Type = pType; m_pDefContainer = NULL; for (int i=0 ; i < 8 ; i++) { m_pDefBagSlot[i] = NULL; } m_pkSortMsg.clear() ; OnCreate(); } CStorage::~CStorage() { m_pkSortMsg.clear(); OnDestroy(); } CItemSlotContainer* CStorage::GetDefItemContainer() { if (m_pDefContainer) { return m_pDefContainer; } return NULL; } CSlot* CStorage::GetSlot(BYTE cPos) { if (GetServerPos(cPos) != -1 && GetServerBag(cPos) != -1) { return GetSlot(GetServerBag(cPos),GetServerPos(cPos)); } return NULL; } CSlot* CStorage::GetSlotByEntry(ui32 pEntry) { for (int i=0; i < m_pDefContainer->GetMaxSlotNum(); i++) { CSlot* pSlot = m_pDefContainer->GetSlot(i); if (pSlot && pSlot->GetCode() == pEntry) { return pSlot; } } for (int i= 0 ;i< 8 ;i++) { if (m_pDefBagSlot[i]) { for (int j = 0; j < m_pDefBagSlot[i]->GetMaxSlotNum(); j++ ) { CSlot* pSlot = m_pDefBagSlot[i]->GetSlot(j); if (pSlot && pSlot->GetCode() == pEntry) { return pSlot; } } } } return NULL; } CSlot* CStorage::GetSlotByGuid(ui64 guid) { for (int i=0; i < m_pDefContainer->GetMaxSlotNum(); i++) { CItemSlot* pSlot = (CItemSlot*)m_pDefContainer->GetSlot(i); if (pSlot && pSlot->GetGUID() == guid) { return pSlot; } } for (int i= 0 ;i< 8 ;i++) { if (m_pDefBagSlot[i]) { for (int j = 0; j < m_pDefBagSlot[i]->GetMaxSlotNum(); j++ ) { CItemSlot* pSlot = (CItemSlot*)m_pDefBagSlot[i]->GetSlot(j); if (pSlot && pSlot->GetGUID() == guid) { return pSlot; } } } } return NULL; } CSlot* CStorage::GetSlot(ui8 bag ,BYTE AtPos) //根据UI的位置来查询相关信息. { if (bag == INVENTORY_SLOT_NOT_SET) { if (m_Type == EBAG) { return m_pDefContainer->GetSlot(AtPos - INVENTORY_SLOT_ITEM_START); } if (m_Type == EBANK) { return m_pDefContainer->GetSlot(AtPos - BANK_SLOT_ITEM_START); } }else { if (m_Type == EBAG) { if (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END) { assert(m_pDefBagSlot[bag - INVENTORY_SLOT_BAG_START]); return m_pDefBagSlot[bag - INVENTORY_SLOT_BAG_START]->GetSlot(AtPos); } } if (m_Type == EBANK) { if (bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END) { assert(m_pDefBagSlot[bag - BANK_SLOT_BAG_START]); return m_pDefBagSlot[bag - BANK_SLOT_BAG_START]->GetSlot(AtPos); } } } return NULL; } void CStorage::ReleaseAllLock() { for (UINT i = 0; i < GetNumMaxSlotCount(); i++) { CItemSlot* pSlot = (CItemSlot*)GetSlot(i); if (pSlot) { pSlot->SetLock(FALSE); } } } bool CStorage::HasLockSolt() { for (UINT i = 0; i < GetNumMaxSlotCount(); i++) { CItemSlot* pSlot = (CItemSlot*)GetSlot(i); if (pSlot->IsLocked()) { return true; } } return false ; } CItemSlotContainer* CStorage::GetContainerByIndex(ui8 bag) { if (bag == INVENTORY_SLOT_NOT_SET) { return m_pDefContainer; }else { for (int i=0; i<8; i++) { if (m_pDefBagSlot[i] && m_pDefBagSlot[i]->GetSYItemBagFromContainer()) { if (bag == m_pDefBagSlot[i]->GetSYItemBagFromContainer()->GetBagSlot()) { return m_pDefBagSlot[i]; } } } } return NULL; } CItemSlotContainer* CStorage::GetContainerByPos(BYTE cPos) //根据UI的信息来获取CItemSlotContainer { if (m_pDefContainer) { UINT MaxPos = m_pDefContainer->GetMaxSlotNum(); if (cPos < MaxPos) { return m_pDefContainer; }else { for (int i = 0; i < 8; i++) { if (m_pDefBagSlot[i] && m_pDefBagSlot[i]->GetSYItemBagFromContainer()) { int Pos = m_pDefBagSlot[i]->GetMaxSlotNum(); if (cPos < (MaxPos + Pos)) { return m_pDefBagSlot[i]; } MaxPos += Pos; } } } } return NULL; } UINT CStorage::GetItemCnt(ui32 entryid) // 获取一种道具的总数量. { int Count = 0; Count += m_pDefContainer->GetItemCnt(entryid); for (int i = 0; i < 8; i++) { if (m_pDefBagSlot[i] && m_pDefBagSlot[i]->GetSYItemBagFromContainer()) { Count += m_pDefBagSlot[i]->GetItemCnt(entryid); } } return Count; } UINT CStorage::GetNumMaxSlotCount() { int Count = 0; Count += m_pDefContainer->GetMaxSlotNum(); for (int i=0; i<8; i++) { if (m_pDefBagSlot[i] && m_pDefBagSlot[i]->GetSYItemBagFromContainer()) { Count += m_pDefBagSlot[i]->GetMaxSlotNum(); } } return Count; } struct SortMsg { ui32 From ; ui32 To ; ui32 Count ; }; struct SortStruct { SortStruct() { entry = 0; MaxCount = 0; Count = 0; ItemStorage = NULL ; } bool operator==(SortStruct&B) { if (entry == B.entry && Count == B.Count) { return true ; } return false ; } bool operator!=( SortStruct&B) { if (entry != B.entry || Count != B.Count) { return true ; } return false ; } SortStruct(CItemSlot* pkSlot, CStorage* Storage) { if (pkSlot->GetGUID()) { entry = pkSlot->GetCode(); MaxCount = pkSlot->GetItemProperty()->MaxCount ; Count = pkSlot->GetNum(); }else { entry = 0; MaxCount = 0; Count = 0; } ItemStorage = Storage ; } //对pkSSA 和pkSSB 进行堆叠操作,并且创建详细 static bool Pile(SortStruct& pkSSA,SortStruct& pkSSB,ui8 pkssAPos, ui8 pkssBPos) { if (pkSSA.entry == pkSSB.entry && pkSSA.entry) { if ((pkSSA.Count < pkSSA.MaxCount) && (pkSSB.Count < pkSSB.MaxCount)) { if (pkSSA.Count + pkSSB.Count > pkSSA.MaxCount) { ui32 need = pkSSA.MaxCount - pkSSA.Count; pkSSB.Count -= need; pkSSA.Count = pkSSA.MaxCount ; CreateMoveMsg(pkssBPos, pkssAPos, need, pkSSA.ItemStorage); return true; }else { pkSSA.Count += pkSSB.Count ; pkSSB.entry = 0; pkSSB.Count = 0; pkSSB.MaxCount = 0; CreateMoveMsg(pkssBPos, pkssAPos, pkSSB.Count, pkSSA.ItemStorage); return true ; } } } return false ; } //排序函数 static bool Sort(SortStruct& pkSSA,SortStruct& pkSSB) { if (pkSSA.ItemStorage != pkSSB.ItemStorage) { return true ; } // 两者都不为空时候. 比较两者大小 if (pkSSA.entry > pkSSB.entry) { return true ; }else if (pkSSA.entry == pkSSB.entry) { if (pkSSA.Count > pkSSB.Count) { return true ; } return false; }else { // return false; } } //和pkSS交换信息 int Move(SortStruct& pkSS, ui32 fpos, ui32 tpos, ui32 need) { ui32 NeedMoveCount = need ; CreateMoveMsg(fpos, tpos, need, pkSS.ItemStorage); SortStruct Tem ; Tem.entry = pkSS.entry; Tem.Count = pkSS.Count; Tem.MaxCount = pkSS.MaxCount; Tem.ItemStorage = pkSS.ItemStorage; pkSS.entry = entry; pkSS.Count = Count; pkSS.MaxCount = MaxCount; pkSS.ItemStorage = ItemStorage; entry = Tem.entry; Count = Tem.Count; MaxCount = Tem.MaxCount; ItemStorage = Tem.ItemStorage; return need ; } //创建移动的消息 static bool CreateMoveMsg(ui32 From, ui32 To, ui32 Count, const CStorage* Storage) { if (Storage) { SortMsg TemMsg ; TemMsg.From = From; TemMsg.To = To; TemMsg.Count = Count ; ((CStorage*)Storage)->PushBackSortMsg(TemMsg); return true; } return false ; } ui32 entry ; ui32 MaxCount ; //最大堆叠数量 ui32 Count; //当前堆叠数量 const CStorage* ItemStorage ; }; void CStorage::PushBackSortMsg(SortMsg& sortMsg) { m_pkSortMsg.push_back(sortMsg); } int CStorage::SortBag() { m_pkSortMsg.clear(); //消息队列 vector v_SortSt ; v_SortSt.clear(); for (int i=0; i < m_pDefContainer->GetMaxSlotNum(); i++) { CItemSlot* pSlot = (CItemSlot*)m_pDefContainer->GetSlot(i); SortStruct pkSt(pSlot,this) ; v_SortSt.push_back(pkSt); } for (int i= 0 ;i< 8 ;i++) { if (m_pDefBagSlot[i]) { for (int j = 0; j < m_pDefBagSlot[i]->GetMaxSlotNum(); j++ ) { CItemSlot* pSlot = (CItemSlot*)m_pDefBagSlot[i]->GetSlot(j); SortStruct pkSt(pSlot,this) ; v_SortSt.push_back(pkSt); } } } //先查找背包可以堆叠的。因为这个消息是不可避免的。 for (size_t it = 0; it < v_SortSt.size(); it++) { for (size_t jt = 0; jt < v_SortSt.size(); jt++) { if (jt != it) { //自己不能和自己进行堆叠操作 SortStruct::Pile(v_SortSt[it], v_SortSt[jt], it, jt); } } } //临时存储排序前的信息 vector v_SortSTTem ; v_SortSTTem.clear(); v_SortSTTem = v_SortSt ; //排序. std::sort(v_SortSt.begin(), v_SortSt.end(), SortStruct::Sort); //排序好后,比较v_SortSTTem 和v_SortSt for (size_t ui = 0; ui < v_SortSt.size(); ui++) { SortStruct* pSort = &v_SortSt[ui]; if (!pSort->entry) { continue ; } if (*pSort != v_SortSTTem[ui]) { bool bfind = false ; for (size_t uj = ui; uj < v_SortSTTem.size() ; uj++) { if (*pSort == v_SortSTTem[uj]) { bfind = true; v_SortSTTem[ui].Move( v_SortSTTem[uj], uj, ui, v_SortSTTem[uj].Count ); break; } if (!bfind) { //ULOG("BUG!@1@!2123131"); } } } } ULOG("%d", m_pkSortMsg.size()); // for (size_t m = 0; m < m_pkSortMsg.size(); m++) { ui8 from = 0; SortMsg* pkSortMsg = &m_pkSortMsg[m]; if (m_Type == EBAG){ from = UItemSystem::ICT_BAG ; } if (m_Type == EBANK){ from = UItemSystem::ICT_BANK ; } ItemMgr->ItemMoveReq(from,from, pkSortMsg->From, pkSortMsg->To,pkSortMsg->Count); } bool isBank = false ; if (m_Type == EBANK){ isBank = true ; } SYState()->UI->GetUItemSystem()->SetNeateningBag(false, isBank); return m_pkSortMsg.size() ; } void CStorage::CopyBagDataToContainer() { for (int i=0; i<8; i++) { if (m_pDefBagSlot[i] && m_pDefBagSlot[i]->GetSYItemBagFromContainer()) { m_pDefBagSlot[i]->CopyBagData(); } } } //设置包裹栏背包对于的SYItemBag. 在对UI进行相关的格子的操作后在进行数据拷贝。 void CStorage::SetSYItemBagContainer(SYItemBag* pBag) { ui8 index = pBag->GetBagSlot(); if (m_Type == EBAG) { assert(m_pDefBagSlot[index - INVENTORY_SLOT_BAG_START]); m_pDefBagSlot[index - INVENTORY_SLOT_BAG_START]->SetSYItemBag(pBag); } if (m_Type == EBANK) { assert(m_pDefBagSlot[index - BANK_SLOT_BAG_START]); m_pDefBagSlot[index - BANK_SLOT_BAG_START]->SetSYItemBag(pBag); } } //清空包裹栏背包 void CStorage::SetBagContainerNull(ui8 bag) { if (m_Type == EBAG) { assert(m_pDefBagSlot[bag - INVENTORY_SLOT_BAG_START]); m_pDefBagSlot[bag - INVENTORY_SLOT_BAG_START]->SetSYItemBag(NULL); } if (m_Type == EBANK) { assert(m_pDefBagSlot[bag - BANK_SLOT_BAG_START]); m_pDefBagSlot[bag - BANK_SLOT_BAG_START]->SetSYItemBag(NULL); } } void CStorage::OnCreate() { m_pDefContainer = new CItemSlotContainer ; if (m_Type == EBAG) { m_pDefContainer->Init((INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START),0); }else if(m_Type == EBANK) { m_pDefContainer->Init((BANK_SLOT_ITEM_END - BANK_SLOT_ITEM_START),0); } //只申请了内存,并没有初始化SLOT; for( int i=0 ; i < 8; i++) { m_pDefBagSlot[i] = new CSYItemBagSlotContainer; m_pDefBagSlot[i]->Init(0,0); } } void CStorage::OnDestroy() { if (m_pDefContainer) { delete m_pDefContainer; m_pDefContainer = NULL; } for( int i=0 ; i < 8; i++) { if (m_pDefBagSlot[i]) { delete m_pDefBagSlot[i]; m_pDefBagSlot[i] = NULL; } } } INT CStorage::GetServerPos(int cPos) { int MaxPos = m_pDefContainer->GetMaxSlotNum(); if (cPos < MaxPos) { if (m_Type == EBAG) { return cPos + INVENTORY_SLOT_ITEM_START ; }else if (m_Type == EBANK) { return cPos + BANK_SLOT_ITEM_START ; } }else { for (int i =0; i<8; i++) { if (m_pDefBagSlot[i] && m_pDefBagSlot[i]->GetSYItemBagFromContainer()) { int pdos = m_pDefBagSlot[i]->GetMaxSlotNum(); if (cPos < (MaxPos + pdos)) { return cPos - MaxPos; } MaxPos += pdos; } } } return -1; } INT CStorage::GetServerBag(int cPos) { int MaxPos = m_pDefContainer->GetMaxSlotNum(); if (MaxPos > cPos) { return INVENTORY_SLOT_NOT_SET; }else { for (int i =0; i< 8; i++) { if (m_pDefBagSlot[i] && m_pDefBagSlot[i]->GetSYItemBagFromContainer()) { if (cPos < (MaxPos + m_pDefBagSlot[i]->GetMaxSlotNum())) { return m_pDefBagSlot[i]->GetSYItemBagFromContainer()->GetBagSlot(); } MaxPos += m_pDefBagSlot[i]->GetMaxSlotNum(); } } } return -1; } UINT CStorage::GetUIPos(ui8 bag, BYTE AtPos) { UINT uPos = 0; uPos = m_pDefContainer->GetMaxSlotNum(); int maxBag = 0; if (bag == INVENTORY_SLOT_NOT_SET) { if (m_Type == EBAG) { return AtPos - INVENTORY_SLOT_ITEM_START ; } if (m_Type == EBANK) { return AtPos - BANK_SLOT_ITEM_START; } }else { if (m_Type == EBAG) { maxBag = bag - INVENTORY_SLOT_BAG_START ; } if (m_Type == EBANK) { maxBag = bag - BANK_SLOT_BAG_START; } } for (int i = 0; i < maxBag; i++) { if (m_pDefBagSlot[i] && m_pDefBagSlot[i]->GetSYItemBagFromContainer()) { uPos += m_pDefBagSlot[i]->GetMaxSlotNum(); } } uPos += AtPos ; return uPos ; } UINT CStorage::GetUIPos(ui64 guid) { UINT pPos = 0; for (int i=0; i < m_pDefContainer->GetMaxSlotNum(); i++) { CItemSlot* pSlot = (CItemSlot*)m_pDefContainer->GetSlot(i); if (pSlot && pSlot->GetGUID() == guid) { if (m_Type == EBAG) { return GetUIPos(INVENTORY_SLOT_NOT_SET, i + INVENTORY_SLOT_ITEM_START); }else { return GetUIPos(INVENTORY_SLOT_NOT_SET, i + BANK_SLOT_ITEM_START); } } } for (int i= 0 ;i< 8 ;i++) { if (m_pDefBagSlot[i]) { for (int j = 0; j < m_pDefBagSlot[i]->GetMaxSlotNum(); j++ ) { CItemSlot* pSlot = (CItemSlot*)m_pDefBagSlot[i]->GetSlot(j); if (pSlot && pSlot->GetGUID() == guid) { if (m_Type == EBAG) { return GetUIPos( i + INVENTORY_SLOT_BAG_START,j); }else { return GetUIPos( i + BANK_SLOT_BAG_START, j); } } } } } return 0xff; }