diff --git a/server/common/length.h b/server/common/length.h index fba03e3..f4cafc3 100755 --- a/server/common/length.h +++ b/server/common/length.h @@ -12,7 +12,9 @@ enum EMisc ACCOUNT_STATUS_MAX_LEN = 8, CHARACTER_NAME_MAX_LEN = 24, SHOP_SIGN_MAX_LEN = 32, - INVENTORY_MAX_NUM = 90, + INVENTORY_PAGE_SIZE = 45, // 5 x 9 + INVENTORY_PAGE_COUNT = 5, // MT: 40250 ships 2 pages (90 cells) + INVENTORY_MAX_NUM = INVENTORY_PAGE_SIZE * INVENTORY_PAGE_COUNT, ABILITY_MAX_NUM = 50, EMPIRE_MAX_NUM = 4, BANWORD_MAX_LEN = 24, @@ -87,15 +89,15 @@ enum EMisc **** 현재까지 할당 된 아이템 영역 정리 (DB상 Item Position) **** +------------------------------------------------------+ 0 | 캐릭터 기본 인벤토리 (45칸 * 2페이지) 90칸 | - +------------------------------------------------------+ 90 = INVENTORY_MAX_NUM(90) + +------------------------------------------------------+ 225 = INVENTORY_MAX_NUM(225) MT: 5 pages; 40250 had 90 and every cell below moved by +135 | 캐릭터 장비 창 (착용중인 아이템) 32칸 | - +------------------------------------------------------+ 122 = INVENTORY_MAX_NUM(90) + WEAR_MAX_NUM(32) + +------------------------------------------------------+ 257 = INVENTORY_MAX_NUM(225) + WEAR_MAX_NUM(32) | 용혼석 장비 창 (착용중인 용혼석) 12칸 | - +------------------------------------------------------+ 134 = 122 + DS_SLOT_MAX(6) * DRAGON_SOUL_DECK_MAX_NUM(2) + +------------------------------------------------------+ 269 = 257 + DS_SLOT_MAX(6) * DRAGON_SOUL_DECK_MAX_NUM(2) | 용혼석 장비 창 예약 (아직 미사용) 18칸 | - +------------------------------------------------------+ 152 = 134 + DS_SLOT_MAX(6) * DRAGON_SOUL_DECK_RESERVED_MAX_NUM(3) + +------------------------------------------------------+ 287 = 269 + DS_SLOT_MAX(6) * DRAGON_SOUL_DECK_RESERVED_MAX_NUM(3) | 벨트 인벤토리 (벨트 착용시에만 벨트 레벨에 따라 활성)| - +------------------------------------------------------+ 168 = 152 + BELT_INVENTORY_SLOT_COUNT(16) = INVENTORY_AND_EQUIP_CELL_MAX + +------------------------------------------------------+ 303 = 287 + BELT_INVENTORY_SLOT_COUNT(16) = INVENTORY_AND_EQUIP_CELL_MAX | 미사용 | +------------------------------------------------------+ ?? */ diff --git a/server/common/tables.h b/server/common/tables.h index 6f7adac..8767f3d 100755 --- a/server/common/tables.h +++ b/server/common/tables.h @@ -403,7 +403,7 @@ typedef struct SPlayerItem typedef struct SQuickslot { BYTE type; - BYTE pos; + WORD pos; // MT: BYTE in 40250; belt cells are >= 256 with 5 inventory pages } TQuickslot; typedef struct SPlayerSkill diff --git a/server/game/src/char.h b/server/game/src/char.h index 6eca64e..a6cba74 100755 --- a/server/game/src/char.h +++ b/server/game/src/char.h @@ -395,7 +395,7 @@ typedef struct character_point_instant WORD parts[PART_MAX_NUM]; LPITEM pItems[INVENTORY_AND_EQUIP_SLOT_MAX]; - BYTE bItemGrid[INVENTORY_AND_EQUIP_SLOT_MAX]; + WORD bItemGrid[INVENTORY_AND_EQUIP_SLOT_MAX]; // MT: BYTE in 40250; holds cell + 1, and cells reach 302 // 용혼석 인벤토리. LPITEM pDSItems[DRAGON_SOUL_INVENTORY_MAX_NUM]; @@ -877,12 +877,12 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider // Quickslot 관련 public: - void SyncQuickslot(BYTE bType, BYTE bOldPos, BYTE bNewPos); + void SyncQuickslot(BYTE bType, WORD bOldPos, WORD bNewPos); bool GetQuickslot(BYTE pos, TQuickslot ** ppSlot); bool SetQuickslot(BYTE pos, TQuickslot & rSlot); bool DelQuickslot(BYTE pos); bool SwapQuickslot(BYTE a, BYTE b); - void ChainQuickslotItem(LPITEM pItem, BYTE bType, BYTE bOldPos); + void ChainQuickslotItem(LPITEM pItem, BYTE bType, WORD bOldPos); protected: TQuickslot m_quickslot[QUICKSLOT_MAX_NUM]; @@ -1120,7 +1120,7 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider // 착용중인 item을 벗을 수 있는 지 확인하고, 불가능 하다면 캐릭터에게 이유를 알려주는 함수 bool CanUnequipNow(const LPITEM item, const TItemPos& srcCell = NPOS, const TItemPos& destCell = NPOS); - bool SwapItem(BYTE bCell, BYTE bDestCell); + bool SwapItem(WORD bCell, WORD bDestCell); LPITEM AutoGiveItem(DWORD dwItemVnum, BYTE bCount=1, int iRarePct = -1, bool bMsg = true); void AutoGiveItem(LPITEM item, bool longOwnerShip = false); diff --git a/server/game/src/char_item.cpp b/server/game/src/char_item.cpp index 0c2403f..a77696c 100755 --- a/server/game/src/char_item.cpp +++ b/server/game/src/char_item.cpp @@ -523,7 +523,7 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) c { case INVENTORY: { - BYTE bCell = Cell.cell; + WORD bCell = Cell.cell; // bItemCell은 0이 false임을 나타내기 위해 + 1 해서 처리한다. // 따라서 iExceptionCell에 1을 더해 비교한다. @@ -562,16 +562,16 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) c return true; int j = 1; - BYTE bPage = bCell / (INVENTORY_MAX_NUM / 2); + int bPage = bCell / INVENTORY_PAGE_SIZE; do { - BYTE p = bCell + (5 * j); + int p = bCell + (5 * j); if (p >= INVENTORY_MAX_NUM) return false; - if (p / (INVENTORY_MAX_NUM / 2) != bPage) + if (p / INVENTORY_PAGE_SIZE != bPage) return false; if (m_pointsInstant.bItemGrid[p]) @@ -592,16 +592,16 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) c else { int j = 1; - BYTE bPage = bCell / (INVENTORY_MAX_NUM / 2); + int bPage = bCell / INVENTORY_PAGE_SIZE; do { - BYTE p = bCell + (5 * j); + int p = bCell + (5 * j); if (p >= INVENTORY_MAX_NUM) return false; - if (p / (INVENTORY_MAX_NUM / 2) != bPage) + if (p / INVENTORY_PAGE_SIZE != bPage) return false; if (m_pointsInstant.bItemGrid[p]) @@ -924,7 +924,7 @@ bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem); LogManager::instance().ItemLog(this, pkNewItem, "REFINE SUCCESS", pkNewItem->GetName()); - BYTE bCell = item->GetCell(); + WORD bCell = item->GetCell(); // DETAIL_REFINE_LOG NotifyRefineSuccess(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER"); @@ -1197,7 +1197,7 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem); LogManager::instance().ItemLog(this, pkNewItem, "REFINE SUCCESS", pkNewItem->GetName()); - BYTE bCell = item->GetCell(); + WORD bCell = item->GetCell(); NotifyRefineSuccess(this, item, szRefineType); DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost); @@ -1226,7 +1226,7 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem); LogManager::instance().ItemLog(this, pkNewItem, "REFINE FAIL", pkNewItem->GetName()); - BYTE bCell = item->GetCell(); + WORD bCell = item->GetCell(); DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost); NotifyRefineFail(this, item, szRefineType, -1); @@ -5982,7 +5982,7 @@ bool CHARACTER::PickupItem(DWORD dwVID) return false; } -bool CHARACTER::SwapItem(BYTE bCell, BYTE bDestCell) +bool CHARACTER::SwapItem(WORD bCell, WORD bDestCell) { if (!CanHandleItem()) return false; @@ -6034,7 +6034,7 @@ bool CHARACTER::SwapItem(BYTE bCell, BYTE bDestCell) if (TItemPos(EQUIPMENT, item2->GetCell()).IsEquipPosition()) { BYTE bEquipCell = item2->GetCell() - INVENTORY_MAX_NUM; - BYTE bInvenCell = item1->GetCell(); + WORD bInvenCell = item1->GetCell(); // 착용중인 아이템을 벗을 수 있고, 착용 예정 아이템이 착용 가능한 상태여야만 진행 if (false == CanUnequipNow(item2) || false == CanEquipNow(item1)) @@ -6052,8 +6052,8 @@ bool CHARACTER::SwapItem(BYTE bCell, BYTE bDestCell) } else { - BYTE bCell1 = item1->GetCell(); - BYTE bCell2 = item2->GetCell(); + WORD bCell1 = item1->GetCell(); + WORD bCell2 = item2->GetCell(); item1->RemoveFromCharacter(); item2->RemoveFromCharacter(); @@ -6182,7 +6182,7 @@ bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) } else { - BYTE bOldCell = item->GetCell(); + WORD bOldCell = item->GetCell(); if (item->EquipTo(this, iWearCell)) { diff --git a/server/game/src/char_quickslot.cpp b/server/game/src/char_quickslot.cpp index 884cd3b..4894fbb 100755 --- a/server/game/src/char_quickslot.cpp +++ b/server/game/src/char_quickslot.cpp @@ -9,7 +9,7 @@ ///////////////////////////////////////////////////////////////////////////// // QUICKSLOT HANDLING ///////////////////////////////////////////////////////////////////////////// -void CHARACTER::SyncQuickslot(BYTE bType, BYTE bOldPos, BYTE bNewPos) // bNewPos == 255 면 DELETE +void CHARACTER::SyncQuickslot(BYTE bType, WORD bOldPos, WORD bNewPos) // bNewPos == 255 면 DELETE { if (bOldPos == bNewPos) return; @@ -135,7 +135,7 @@ bool CHARACTER::SwapQuickslot(BYTE a, BYTE b) return true; } -void CHARACTER::ChainQuickslotItem(LPITEM pItem, BYTE bType, BYTE bOldPos) +void CHARACTER::ChainQuickslotItem(LPITEM pItem, BYTE bType, WORD bOldPos) { if (pItem->IsDragonSoul()) return; diff --git a/server/game/src/exchange.cpp b/server/game/src/exchange.cpp index a59452d..c3229f0 100755 --- a/server/game/src/exchange.cpp +++ b/server/game/src/exchange.cpp @@ -299,30 +299,27 @@ bool CExchange::Check(int * piItemCount) bool CExchange::CheckSpace() { - static CGrid s_grid1(5, INVENTORY_MAX_NUM/5 / 2); // inven page 1 - static CGrid s_grid2(5, INVENTORY_MAX_NUM/5 / 2); // inven page 2 + // MT: one grid per inventory page (40250 had s_grid1/s_grid2 for its 2 pages) + static CGrid * s_grids[INVENTORY_PAGE_COUNT]; - s_grid1.Clear(); - s_grid2.Clear(); + for (int page = 0; page < INVENTORY_PAGE_COUNT; ++page) + { + if (!s_grids[page]) + s_grids[page] = new CGrid(5, INVENTORY_PAGE_SIZE / 5); + s_grids[page]->Clear(); + } LPCHARACTER victim = GetCompany()->GetOwner(); LPITEM item; int i; - for (i = 0; i < INVENTORY_MAX_NUM / 2; ++i) - { - if (!(item = victim->GetInventoryItem(i))) - continue; - - s_grid1.Put(i, 1, item->GetSize()); - } - for (i = INVENTORY_MAX_NUM / 2; i < INVENTORY_MAX_NUM; ++i) + for (i = 0; i < INVENTORY_MAX_NUM; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; - s_grid2.Put(i - INVENTORY_MAX_NUM / 2, 1, item->GetSize()); + s_grids[i / INVENTORY_PAGE_SIZE]->Put(i % INVENTORY_PAGE_SIZE, 1, item->GetSize()); } // 아... 뭔가 개병신 같지만... 용혼석 인벤을 노멀 인벤 보고 따라 만든 내 잘못이다 ㅠㅠ @@ -387,25 +384,21 @@ bool CExchange::CheckSpace() } else { - int iPos = s_grid1.FindBlank(1, item->GetSize()); + bool bPut = false; - if (iPos >= 0) + for (int page = 0; page < INVENTORY_PAGE_COUNT && !bPut; ++page) { - s_grid1.Put(iPos, 1, item->GetSize()); - } - else - { - iPos = s_grid2.FindBlank(1, item->GetSize()); + int iPos = s_grids[page]->FindBlank(1, item->GetSize()); if (iPos >= 0) { - s_grid2.Put(iPos, 1, item->GetSize()); - } - else - { - return false; + s_grids[page]->Put(iPos, 1, item->GetSize()); + bPut = true; } } + + if (!bPut) + return false; } } diff --git a/server/game/src/fishing.cpp b/server/game/src/fishing.cpp index b240401..20b2a21 100755 --- a/server/game/src/fishing.cpp +++ b/server/game/src/fishing.cpp @@ -877,7 +877,7 @@ int RealRefineRod(LPCHARACTER ch, LPITEM item) if (pkNewItem) { - BYTE bCell = rod->GetCell(); + WORD bCell = rod->GetCell(); // 낚시대 개량 성공 ITEM_MANAGER::instance().RemoveItem(rod, "REMOVE (REFINE FISH_ROD)"); pkNewItem->AddToCharacter(ch, TItemPos (INVENTORY, bCell)); @@ -895,7 +895,7 @@ int RealRefineRod(LPCHARACTER ch, LPITEM item) LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(rod->GetValue(4), 1); if (pkNewItem) { - BYTE bCell = rod->GetCell(); + WORD bCell = rod->GetCell(); // 낚시대 개량에 성공 ITEM_MANAGER::instance().RemoveItem(rod, "REMOVE (REFINE FISH_ROD)"); pkNewItem->AddToCharacter(ch, TItemPos(INVENTORY, bCell)); diff --git a/server/game/src/mining.cpp b/server/game/src/mining.cpp index f1ea8a6..b6dd7b8 100755 --- a/server/game/src/mining.cpp +++ b/server/game/src/mining.cpp @@ -253,7 +253,7 @@ namespace mining LPITEM pkNewPick = ITEM_MANAGER::instance().CreateItem(rkOldPick.GetRefinedVnum(), 1); if (pkNewPick) { - BYTE bCell = rkOldPick.GetCell(); + WORD bCell = rkOldPick.GetCell(); rkItemMgr.RemoveItem(item, "REMOVE (REFINE PICK)"); pkNewPick->AddToCharacter(ch, TItemPos(INVENTORY, bCell)); LogManager::instance().ItemLog(ch, pkNewPick, "REFINE PICK SUCCESS", pkNewPick->GetName()); @@ -270,7 +270,7 @@ namespace mining if (pkNewPick) { - BYTE bCell = rkOldPick.GetCell(); + WORD bCell = rkOldPick.GetCell(); rkItemMgr.RemoveItem(item, "REMOVE (REFINE PICK)"); pkNewPick->AddToCharacter(ch, TItemPos(INVENTORY, bCell)); rkLogMgr.ItemLog(ch, pkNewPick, "REFINE PICK FAIL", pkNewPick->GetName()); diff --git a/server/game/src/questlua_item.cpp b/server/game/src/questlua_item.cpp index befc676..23200e8 100755 --- a/server/game/src/questlua_item.cpp +++ b/server/game/src/questlua_item.cpp @@ -436,7 +436,7 @@ namespace quest ITEM_MANAGER::CopyAllAttrTo(pItem, pkNewItem); LogManager::instance().ItemLog(pChar, pkNewItem, "COPY SUCCESS", pkNewItem->GetName()); - BYTE bCell = pItem->GetCell(); + WORD bCell = pItem->GetCell(); ITEM_MANAGER::instance().RemoveItem(pItem, "REMOVE (COPY SUCCESS)");