#include "StdAfx.h" #include "Handler_AG_ITEM.h" #include #include "Player.h" #include "./Status/StatusManager.h" #include "ItemManager.h" #include "GameServerEx.h" //-------------------------------------------------------------------------------------------------- // changes, f100819.1L const nsPacket::PacketHandlerInfo Handler_AG_ITEM::GetPacketHandlerNodes() { #define HANDLER_NODE_INFO(c, p, phase) { MAKEWORD(c, p), phase, Handler_AG_ITEM::On##p } #define HANDLER_NODE_INFO_EOR() { 0, static_cast(0), NULL } static const nsPacket::PacketHandlerNode handlers_static_[] = { HANDLER_NODE_INFO(AG_ITEM, AG_ITEM_PORTAL_ACK, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ITEM, AG_ITEM_UNLOCK_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ITEM, AG_ITEM_DECREASE_UNLOCK_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ITEM, AG_ITEM_USE_DECREE_ITEM_SYN, PHASE_SERVICE), #ifdef _NA_20101011_HEIM_LOTTO_CASH_TICKET HANDLER_NODE_INFO(AG_ITEM, AG_ITEM_USE_HEIM_LOTTO_TICKET_ACK, PHASE_SERVICE), #endif HANDLER_NODE_INFO_EOR() // end of records }; // BOOST_STATIC_ASSERT(_countof(handlers_static_) >= 1); nsPacket::PacketHandlerInfo return_value = { handlers_static_, _countof(handlers_static_) - 1 }; // return return_value; }; //-------------------------------------------------------------------------------------------------- Handler_AG_ITEM_IMPL( AG_ITEM_PORTAL_ACK ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ITEM_PORTAL_ACK *pRecvMsg = (MSG_AG_ITEM_PORTAL_ACK*)pMsg; Player *pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( pRecvMsg->m_dwKey ); if( !pPlayer ) return; //{__NA001164_20081024_CHAR_WAY_POINT_ITEM //¿þÀÌÆ÷ÀÎÆ® ¸®½ºÆ®¸¦ ÅëÇÑ À̵¿ ÈÄó¸®. ItemManager* pItemManager = pPlayer->GetItemManager(); if( !pItemManager ) return; ASSERT(pRecvMsg->m_ItemCode); if (pRecvMsg->m_ItemCode == 0) return; SCSlotContainer * pContainer = (SCSlotContainer *)pItemManager->GetItemSlotContainer( SI_INVENTORY ); SCItemSlot & rItemSlot = (SCItemSlot &)pContainer->GetSlot( pRecvMsg->m_PortalPos ); POSTYPE item_position = INVALID_POSTYPE_VALUE; if (rItemSlot.GetItemCode() == pRecvMsg->m_ItemCode) { item_position = pRecvMsg->m_PortalPos; } else { const SCSlotContainer::SLOT_LINEAR_LIST& slot_list = pContainer->GetSlotList(); uint count = slot_list.size(); for (uint i = 0 ; i < count ; ++i) { SCItemSlot& temp_slot = (SCItemSlot&)pContainer->GetSlot(i); if (pRecvMsg->m_ItemCode == temp_slot.GetItemCode()) { item_position = temp_slot.GetPos(); break; } } } if (item_position == INVALID_POSTYPE_VALUE) return; SCItemSlot& item_slot = (SCItemSlot&)pContainer->GetSlot(item_position); if (item_slot.IsWayPointItem()) return; if (item_slot.GetItemInfo()->m_wType != eITEMTYPE_PORTAL) return; // º¹¼öÀÇ µ¹ ¾ÆÀÌÅÛÀ» »èÁ¦ÇÑ´Ù. RC::eITEM_RESULT rcResult = pPlayer->GetItemManager()->Delete( SI_INVENTORY, pRecvMsg->m_PortalPos, 1, ITEM_DELETE_ITEM_PORTAL ); if( rcResult != RC::RC_ITEM_SUCCESS ) { SUNLOG( eCRITICAL_LOG, "[AG_ITEM_PORTAL_ACK] Cannot Delete PortalItem! ErrorCode[%d]", rcResult ); return; } } Handler_AG_ITEM_IMPL( AG_ITEM_UNLOCK_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ITEM_UNLOCK_CMD *pRecvMsg = (MSG_AG_ITEM_UNLOCK_CMD*)pMsg; Player *pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( pRecvMsg->m_dwKey ); if( !pPlayer ) return; ItemManager* pItemManager = pPlayer->GetItemManager(); if( !pItemManager ) return; SCSlotContainer * pContainer = (SCSlotContainer *)pItemManager->GetItemSlotContainer( pRecvMsg->m_ItemIndex ); if( !pItemManager->ValidState() ) return; //if( !pItemManager->ValidPos( pRecvMsg->m_ItemIndex, pRecvMsg->m_ItemPos ) ) // return; SCItemSlot & rItemSlot = (SCItemSlot &)pContainer->GetSlot( pRecvMsg->m_ItemPos ); if( !rItemSlot.GetItemInfo() ) return; rItemSlot.SetLock(FALSE); // (f100528.2L) prevent a locked state after an instance dungeon moving transaction failed // if a item operation is fails, a post action is failed, too. // referenced by f100514.3L switch (pRecvMsg->post_action_) { case pRecvMsg->eAction_MoveFailed: { StatusManager* status_manager = pPlayer->GetStatusManager(); status_manager->ChangeInterState(eCHAR_STATE_ZONE_TRANSACTION, false); }; break; } } Handler_AG_ITEM_IMPL( AG_ITEM_DECREASE_UNLOCK_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ITEM_DECREASE_UNLOCK_CMD *pRecvMsg = (MSG_AG_ITEM_DECREASE_UNLOCK_CMD*)pMsg; Player *pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( pRecvMsg->m_dwKey ); if( !pPlayer ) return; ItemManager* pItemManager = pPlayer->GetItemManager(); if( !pItemManager ) return; SCSlotContainer * pContainer = (SCSlotContainer *)pItemManager->GetItemSlotContainer( pRecvMsg->m_ItemIndex ); SCItemSlot & rItemSlot = (SCItemSlot &)pContainer->GetSlot( pRecvMsg->m_ItemPos ); if( !rItemSlot.GetItemInfo() ) return; rItemSlot.SetLock(FALSE); if( !pItemManager->ValidState() ) return; if( !pItemManager->ValidPos( pRecvMsg->m_ItemIndex, pRecvMsg->m_ItemPos ) ) return; GAMELOG->LogItem( ITEM_USE, pPlayer, &rItemSlot ); pItemManager->Lose( pContainer, pRecvMsg->m_ItemPos, 1); WORD wCoolTimeType = rItemSlot.GetItemInfo()->m_wCoolTimeType; pPlayer->ResetUseItem( wCoolTimeType ); } Handler_AG_ITEM_IMPL( AG_ITEM_USE_DECREE_ITEM_SYN ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ITEM_USE_DECREE_ITEM_SYN* pRecvMsg = (MSG_AG_ITEM_USE_DECREE_ITEM_SYN *)pMsg; Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(pRecvMsg->m_dwKey); if(!pPlayer) return; if(!pPlayer->GetField() ) return; ItemManager* pItemManager = pPlayer->GetItemManager(); if(!pItemManager) return; SCSlotContainer* pContainer = (SCSlotContainer *)pItemManager->GetItemSlotContainer(SI_INVENTORY); if(!pContainer) return; for(int pos = 0; pos < MAX_INVENTORY_SLOT_NUM; pos++) { if( pContainer->IsEmpty(pos) ) continue; SCItemSlot &rItemSlot = (SCItemSlot &)pContainer->GetSlot(pos); if( rItemSlot.GetSerial() != 0 ) { const BASE_ITEMINFO* const pInfo = rItemSlot.GetItemInfo(); if(!pInfo) break; if(pInfo->m_wType == eITEMTYPE_CHAT_SHOUT_CONSUME) { if(!pItemManager->ValidState()) return; if(!pItemManager->ValidPos(SI_INVENTORY, pos)) return; //__CN_1299_WASTE_ITEM_LEVEL_LIMITE_CHECK RC::eITEM_RESULT rcResult = pPlayer->CanUseItem( rItemSlot.GetItemInfo() ); if( rcResult != RC::RC_ITEM_SUCCESS ) { MSG_AG_ITEM_USE_DECREE_ITEM_NAK msgNAK; msgNAK.m_dwKey = pPlayer->GetUserGuid(); msgNAK.m_byErrorCode = rcResult; g_pGameServer->SendToServer(AGENT_SERVER, &msgNAK, sizeof(msgNAK)); return; } pItemManager->Lose(pContainer, pos, 1); MSG_CG_ITEM_USE_ACK ackMsg; ackMsg.m_atIndex = static_cast(SI_INVENTORY); ackMsg.m_atPos = pos; pPlayer->SendPacket( &ackMsg, sizeof( ackMsg ) ); MSG_AG_ITEM_USE_DECREE_ITEM_ACK msgACK; msgACK.m_dwKey = pPlayer->GetUserGuid(); g_pGameServer->SendToServer(AGENT_SERVER, &msgACK, sizeof(msgACK)); return; } } continue; } //¿©±â±îÁö ¿À¸é ÇØ´ç ¾ÆÀÌÅÛÀÌ ¾ø´Â°Å´Ù. MSG_AG_ITEM_USE_DECREE_ITEM_NAK msgNAK; msgNAK.m_dwKey = pPlayer->GetUserGuid(); msgNAK.m_byErrorCode = RC::RC_ITEM_NOT_EXIST; g_pGameServer->SendToServer(AGENT_SERVER, &msgNAK, sizeof(msgNAK)); } #ifdef _NA_20101011_HEIM_LOTTO_CASH_TICKET // ÇÏÀÓÇà¿î ij½Ã ÀÀ¸ð±Ç »ç¿ë ÀÀ´ä Handler_AG_ITEM_IMPL( AG_ITEM_USE_HEIM_LOTTO_TICKET_ACK ) { __TOUCHED((pServerSession, pMsg, wSize)); const MSG_AG_ITEM_USE_HEIM_LOTTO_TICKET_ACK* msg = \ static_cast(pMsg); Player* player = PlayerManager::Instance()->FindPlayerByCharKey(msg->char_guid); if (player == NULL || player->GetField() == NULL) { return; } if (msg->result_code != RC::RC_ITEM_SUCCESS) { MSG_CG_ITEM_USE_NAK nak; nak.m_ErrorCode = (BYTE)msg->result_code; player->SendPacket(&nak, (WORD)sizeof(nak)); // ½ÇÆÐÀÇ °æ¿ì¿¡µµ À¯È¿ÇÑ ¾ÆÀÌÅÛÀÇ unlockÀ» À§ÇØ ÀÏ´Ü ÁøÇà } ItemManager* item_manager = player->GetItemManager(); if (item_manager == NULL) { return; } SCSlotContainer* container = (SCSlotContainer*)item_manager->GetItemSlotContainer(msg->index); if (container == NULL) { return; } SCItemSlot& item_slot = (SCItemSlot&)container->GetSlot(msg->pos); if (item_slot.GetSerial() == 0) { return; } const BASE_ITEMINFO* item_info = item_slot.GetItemInfo(); if (item_info == NULL) { return; } item_slot.SetLock(FALSE); // ½ÇÆÐÀÇ °æ¿ì¿¡´Â ¿©±â¼­ ¸®ÅÏ if (msg->result_code != RC::RC_ITEM_SUCCESS) { return; } // ¼º°øÀÇ °æ¿ì¿¡´Â ¸ÕÀú ¾ÆÀÌÅÛ »ç¿ë ·Î±×ºÎÅÍ ³²±ä´Ù GAMELOG->LogItem(ITEM_USE, player, &item_slot); // ¼Ò¸ð¼º ¾ÆÀÌÅÛ »èÁ¦ if (item_info->m_wType == eITEMTYPE_HEIM_LOTTO_TICKET) { if(item_slot.GetNum() <= 1) { container->DeleteSlot(msg->pos, NULL); } else { container->UpdateSlot(msg->pos, -1); } } player->ResetUseItem(item_info->m_wCoolTimeType); MSG_CG_ITEM_USE_ACK ack; ack.m_atIndex = msg->index; ack.m_atPos = msg->pos; player->SendPacket(&ack, (WORD)sizeof(ack)); } #endif // _NA_20101011_HEIM_LOTTO_CASH_TICKET