#include "stdafx.h" #include #include #include #include #include #include #include #include #include #include #include #include "Character.h" unsigned long CCharacter::RepairItem(const unsigned long dwNPCID, Item::ItemPos itemPos, unsigned short& wError) { CCreature* lpCreature = CCreatureManager::GetInstance().GetCreature(dwNPCID); if (NULL == lpCreature) { ERRLOG2(g_Log, "CID:%10u ¼ö¸®ÇØÁÙ Å©¸®Ãİ¡ Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù. ¼ö¸® ½ÇÆÐ. CID:%10u", m_dwCID, dwNPCID); wError = PktRpI::FAIL_NOT_CREATURE; return 0; } if (Creature::CT_NPC == Creature::GetCreatureType(dwNPCID)) { int nZone = CServerSetup::GetInstance().GetServerZone(); if (GetMapIndex() != 0) { VirtualArea::CVirtualArea* lpVirtualArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(GetMapIndex()); if (NULL != lpVirtualArea) { nZone = static_cast(lpVirtualArea->GetVirtualZone()); } } CNPC* lpNPC = reinterpret_cast(lpCreature); if (lpNPC->GetZone() != nZone) { ERRLOG3(g_Log, "CID:%10u NPCÀÇ Á¸ ¹øÈ£°¡ ´Ù¸¨´Ï´Ù. Server Zone : %d, NPC Zone : %d", m_dwCID, nZone, lpNPC->GetZone()); wError = PktRpI::FAIL_NOT_NPCZONE; return 0; } } Item::CItem* lpItem = GetItem(itemPos); if (NULL == lpItem) { ERRLOG3(g_Log, "CID:%10u ¾ÆÀÌÅÛÀÌ %d Pos, %d Index¿¡ ¾ø½À´Ï´Ù", m_dwCID, itemPos.m_cPos, itemPos.m_cIndex); wError = PktRpI::FAIL_NOT_POSITEM; return 0; } if (true == lpItem->IsSet(Item::DetailData::STACKABLE)) { ERRLOG1(g_Log, "CID:%10u ½ºÅà ¾ÆÀÌÅÛÀ̾ ¼ö¸®ÇÒ ¼ö ¾ø½À´Ï´Ù", m_dwCID); wError = PktRpI::FAIL_NOT_STACKABLE; return 0; } if (false == lpItem->IsSet(Item::DetailData::EQUIP)) { ERRLOG1(g_Log, "CID:%10u Àåºñ ¾ÆÀÌÅÛÀÌ ¾Æ´Ï¾î¼­ ¼ö¸®ÇÒ ¼ö ¾ø½À´Ï´Ù", m_dwCID); wError = PktRpI::FAIL_NOT_EQUIP; return 0; } if (lpItem->GetNumOrDurability() >= lpItem->GetMaxNumOrDurability()) { // ERRLOG4(g_Log, "CID:%10u Àåºñ°¡ ÀÌ¹Ì ÃÖ´ë ³»±¸µµ¿¡ µµ´ÞÇØ¼­, ¼ö¸®ÇÒ ¼ö ¾ø½À´Ï´Ù." // " Á¾·ùID:%d, ÇöÀç ³»±¸µµ:%d, ÃÖ´ë ³»±¸µµ:%d", m_dwCID, lpItem->GetPrototypeID(), // lpItem->GetNumOrDurability(), lpItem->GetMaxNumOrDurability()); wError = PktRpI::FAIL_FULL_DRUA; return 0; } Item::CEquipment* lpEquipment = Item::CEquipment::DowncastToEquipment(lpItem); unsigned long dwGold = lpCreature->RepairItem(lpEquipment, m_DBData.m_Info.Gold); if (0 != dwGold) { CalculateStatusData(false); } else { wError = PktRpAI::FAIL_NOT_REPAIR; } return dwGold; } unsigned long CCharacter::RepairAllItem(const unsigned long dwNPCID, unsigned short& wError) { CCreature* lpCreature = CCreatureManager::GetInstance().GetCreature(dwNPCID); if (NULL == lpCreature) { ERRLOG2(g_Log, "CID:%10u ¼ö¸®ÇØÁÙ Å©¸®Ãİ¡ Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù. ¼ö¸® ½ÇÆÐ. CID:%10u", m_dwCID, dwNPCID); wError = PktRpAI::FAIL_NOT_CREATURE; return 0; } if (Creature::CT_NPC == Creature::GetCreatureType(dwNPCID)) { int nZone = CServerSetup::GetInstance().GetServerZone(); if (GetMapIndex() != 0) { VirtualArea::CVirtualArea* lpVirtualArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(GetMapIndex()); if (NULL != lpVirtualArea) { nZone = static_cast(lpVirtualArea->GetVirtualZone()); } } CNPC* lpNPC = reinterpret_cast(lpCreature); if (lpNPC->GetZone() != nZone) { ERRLOG3(g_Log, "CID:%10u NPCÀÇ Á¸ ¹øÈ£°¡ ´Ù¸¨´Ï´Ù. Server Zone : %d, NPC Zone : %d", m_dwCID, nZone, lpNPC->GetZone()); wError = PktRpAI::FAIL_NOT_NPCZONE; return 0; } } unsigned long dwRepairGold = 0; Item::ItemPos itemPos; itemPos.m_cPos = TakeType::TS_EQUIP; // 1´Ü°è °Ë»ç for (unsigned char cIndex = 0; cIndex < Item::EquipmentPos::MAX_EQUPMENT_POS; ++cIndex) { if (GetRace() == CClass::AKHAN && (Item::EquipmentPos::SHIRT == cIndex || Item::EquipmentPos::TUNIC == cIndex || Item::EquipmentPos::SHIELD_HAND2 == cIndex || Item::EquipmentPos::WEAPON_HAND2 < cIndex)) { continue; } itemPos.m_cIndex = cIndex; Item::CItem* lpItem = GetItem(itemPos); if (NULL == lpItem) { continue; } if (true == lpItem->IsSet(Item::DetailData::STACKABLE)) { // È­»ì/º¼Æ®ÀÇ °æ¿ì ¼ö¸® ºÒ°¡ continue; } if (false == lpItem->IsSet(Item::DetailData::EQUIP)) { ERRLOG3(g_Log, "CID:%10u ¼ö¸®ÇÏ´Â ¾ÆÀÌÅÛÀÌ Àåºñ ¾ÆÀÌÅÛÀÌ ¾Æ´Õ´Ï´Ù. (%d Pos, %d Index)", m_dwCID, itemPos.m_cPos, itemPos.m_cIndex); continue; } if (lpItem->GetNumOrDurability() >= lpItem->GetMaxNumOrDurability()) { // Ç®³»±¸ÀÇ Àåºñ´Â ½ºÅµ continue; } // °ñµå¸¦ °è»êÇÑ´Ù. Item::CEquipment* lpEquipment = Item::CEquipment::DowncastToEquipment(lpItem); if(lpEquipment) dwRepairGold += lpEquipment->GetRepairPrice(); } // µ·ÀÌ ½ÇÁ¦º¸´Ù ¸¹À̵é¸é ¿¡·¯¸¦ ¸®ÅÏÇÑ´Ù. if (dwRepairGold > GetGold()) { wError = PktRpAI::NOT_ENOUGH_GOLD; return 0; } dwRepairGold = 0; // 2´Ü°è ½ÇÁ¦ ¼ö¸® for (unsigned char cIndex = 0; cIndex < Item::EquipmentPos::MAX_EQUPMENT_POS; ++cIndex) { if (GetRace() == CClass::AKHAN && (Item::EquipmentPos::SHIRT == cIndex || Item::EquipmentPos::TUNIC == cIndex || Item::EquipmentPos::SHIELD_HAND2 == cIndex || Item::EquipmentPos::WEAPON_HAND2 < cIndex)) { continue; } itemPos.m_cIndex = cIndex; Item::CItem* lpItem = GetItem(itemPos); if (NULL == lpItem) { continue; } if (true == lpItem->IsSet(Item::DetailData::STACKABLE)) { // È­»ì/º¼Æ®ÀÇ °æ¿ì ¼ö¸® ºÒ°¡ continue; } if (false == lpItem->IsSet(Item::DetailData::EQUIP)) { ERRLOG3(g_Log, "CID:%10u ¼ö¸®ÇÏ´Â ¾ÆÀÌÅÛÀÌ Àåºñ ¾ÆÀÌÅÛÀÌ ¾Æ´Õ´Ï´Ù. (%d Pos, %d Index)", m_dwCID, itemPos.m_cPos, itemPos.m_cIndex); continue; } if (lpItem->GetNumOrDurability() >= lpItem->GetMaxNumOrDurability()) { // Ç®³»±¸ÀÇ Àåºñ´Â ½ºÅµ continue; } Item::CEquipment* lpEquipment = Item::CEquipment::DowncastToEquipment(lpItem); if(lpEquipment) dwRepairGold += lpCreature->RepairItem(lpEquipment, m_DBData.m_Info.Gold); } if (0 != dwRepairGold) { CalculateStatusData(false); } else { wError = PktRpAI::FAIL_NOT_REPAIR; } return dwRepairGold; } Item::CItem* CCharacter::SellToCharacter(CCharacter *lpCustomer, unsigned short wKindItem, TakeType takeType, Item::CItem* lpRequestItem, unsigned long &dwPrice, unsigned short wCouponID, unsigned short &usError) { Item::CItem* lpItem = m_Stall.GetItem(takeType.m_srcPos); if (NULL == lpItem) { return NULL; } unsigned long dwCustomerCID = lpCustomer->GetCID(); unsigned long dwCurrentGold = lpCustomer->GetGold(); dwPrice = lpItem->GetBuyPrice() * takeType.m_cNum; if (dwPrice > dwCurrentGold) { ERRLOG2(g_Log, "³ëÁ¡»ó ¿À·ù : µ·ÀÌ ºÎÁ·ÇÕ´Ï´Ù. °¡°Ý:%d, ¼ÒÁö±Ý:%d", dwPrice, dwCurrentGold); GAMELOG::LogTradeItem(*this, dwCustomerCID, dwPrice, lpItem, takeType.m_srcPos, PktTr::TRC_SELL, PktTr::FAIL_ITEM_BUY); return NULL; } // °¡Áú¼ö ÀÖ´Â ÃÖ´ë ¼ÒÁö±Ý Ãʰú if (GetGold() > ULONG_MAX - dwPrice) { ERRLOG2(g_Log, "³ëÁ¡»ó ¿À·ù : °Å·¡ÈÄ Gold°¡ ÃÖ´ë ¼ÒÁö±ÝÀ» ÃʰúÇÕ´Ï´Ù. °¡°Ý:%d, ¼ÒÁö±Ý:%d", dwPrice, GetGold()); GAMELOG::LogTradeItem(*this, dwCustomerCID, dwPrice, lpItem, takeType.m_srcPos, PktTr::TRC_SELL, PktTr::FAIL_GOLD_OVERFLOW); return NULL; } if (false == lpCustomer->GetInventory().TestItem(takeType.m_dstPos, lpItem->GetPrototypeID(), takeType.m_cNum)) { Item::CItemContainer* lpItemContainer = lpCustomer->GetItemContainer(takeType.m_dstPos.m_cPos); if (NULL != lpItemContainer) { lpItemContainer->DumpItemInfo(); } else { ERRLOG1(g_Log, "CID:%10u ¾ÆÀÌÅÛ ´ýÇÁ¸¦ Ãâ·ÂÇÒ ¼ö ¾ø½À´Ï´Ù.", dwCustomerCID); } ERRLOG4(g_Log, "CID:%10u ¾ÆÀÌÅÛ Á¾·ù:%d¸¦ (%2d:%2d)¿¡ ¾ÆÀÌÅÛ ³Ö±â ½ÇÆÐ.", dwCustomerCID, lpItem->GetPrototypeID(), takeType.m_dstPos.m_cPos, takeType.m_dstPos.m_cIndex); return NULL; } bool bStackable = lpItem->IsSet(Item::DetailData::STACKABLE); unsigned char cNumOrDurability = lpItem->GetNumOrDurability(); Item::ItemPos ItemPos = lpItem->GetPos(); // ½ºÅà °¡´ÉÇÑ ¾ÆÀÌÅÛÀÎ °æ¿ì, °³¼öÁ¦ÇÑ È®ÀÎ. if (!(bStackable && (cNumOrDurability < takeType.m_cNum))) { // ½ºÅÃÀÌ ºÒ°¡´ÉÇϰųª, ÀüºÎ ÆÄ´Â °æ¿ì¿¡´Â ¾ÆÀÌÅÛ Á¦°Å. if (!bStackable || (bStackable && (takeType.m_cNum == lpItem->GetNumOrDurability()))) { if (false == m_Stall.RemoveItem(takeType.m_srcPos)) { ERRLOG3(g_Log, "CID:%10u ¾ÆÀÌÅÛÀ» (%2d, %4x)À§Ä¡·ÎºÎÅÍ Áö¿ì´Â µ¥ ½ÇÆÐÇß½À´Ï´Ù.", m_dwCID, takeType.m_srcPos.m_cPos, takeType.m_srcPos.m_cIndex); GAMELOG::LogTradeItem(*this, dwCustomerCID, dwPrice, lpItem, takeType.m_srcPos, PktTr::TRC_SELL, PktTr::FAIL_ITEM_BUY); return NULL; } else { RemoveItem(ItemPos); m_Stall.SendRemoveItem(takeType, PktStRI::SC_CANCEL, lpCustomer->GetCharacterName()); } } else { lpItem->SetNumOrDurability(cNumOrDurability - takeType.m_cNum); m_Stall.SendRemoveItem(takeType, PktStRI::SC_CANCEL, lpCustomer->GetCharacterName()); unsigned short usProtoTypeID = lpItem->GetPrototypeID(); lpItem = Item::CItemFactory::GetInstance().CreateItem(usProtoTypeID); if (NULL == lpItem) { ERRLOG1(g_Log, "³ëÁ¡»ó ¿À·ù : ¾ÆÀÌÅÛ »ý¼º ½ÇÆÐ. ProtoTypeID : %d", usProtoTypeID); GAMELOG::LogTradeItem(*this, dwCustomerCID, dwPrice, lpItem, takeType.m_srcPos, PktTr::TRC_SELL, PktTr::FAIL_ITEM_BUY); return NULL; } lpItem->SetNumOrDurability(takeType.m_cNum); } AddGold(dwPrice, false); if (NULL != m_lpGameClientDispatch) { GameClientSendPacket::SendCharTradeItem(m_lpGameClientDispatch->GetSendStream(), this, lpCustomer->GetCID(), Item::ItemPos(), NULL, ItemPos, takeType.m_cNum, 0); } } else { ERRLOG4(g_Log, "³ëÁ¡»ó ¿À·ù : (%2d, %4x)ÀÇ ¾ÆÀÌÅÛ °³¼ö : %d°³ ÆÈ·Á´Â ¾ÆÀÌÅÛ °³¼ö : %d°³", takeType.m_srcPos.m_cPos, takeType.m_srcPos.m_cIndex, cNumOrDurability, takeType.m_cNum); GAMELOG::LogTradeItem(*this, dwCustomerCID, dwPrice, lpItem, takeType.m_srcPos, PktTr::TRC_SELL, PktTr::FAIL_ITEM_BUY); return NULL; } GAMELOG::LogTradeItem(*this, dwCustomerCID, dwPrice, lpItem, takeType.m_srcPos, PktTr::TRC_SELL, PktTr::NO_SERVER_ERR); return lpItem; }