bool ActiveTrade::bothCanTrade() { if (!canTrade(getSender(), getReceiverTrade())) { return false; } if (!canTrade(getReceiver(), getSenderTrade())) { return false; } return true; }
void CGTradeAddItemHandler::executeOusters (CGTradeAddItem* pPacket , Player* pPlayer) throw(ProtocolException , Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ // 상위 함수에서 에러를 검사했기 때문에, // 여기서는 포인터가 널인지를 검사하지 않는다. ObjectID_t TargetOID = pPacket->getTargetObjectID(); ObjectID_t ItemOID = pPacket->getItemObjectID(); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Creature* pPC = pGamePlayer->getCreature(); Zone* pZone = pPC->getZone(); PlayerCreature* pTargetPC = dynamic_cast<PlayerCreature*>(pZone->getCreature(TargetOID)); // NoSuch제거. by sigi. 2002.5.2 if (pTargetPC==NULL) return; Ousters* pSender = dynamic_cast<Ousters*>(pPC); TradeManager* pTradeManager = pZone->getTradeManager(); Assert(pTradeManager != NULL); // 교환 대상에 추가할 아이템의 포인터를 얻어낸다. CoordInven_t X, Y; Inventory* pInventory = pSender->getInventory(); Item* pItem = pInventory->findItemOID(ItemOID, X, Y); // 추가할 아이템이 없다면 당연히 더 이상 처리가 불가능 // Relic은 교환할 수 없다. if (pItem == NULL || !canTrade(pItem ) || pSender->getStore()->hasItem(pItem) || (pItem->getItemClass() == Item::ITEM_CLASS_SUB_INVENTORY && hasItemWithItemClass(pTargetPC, Item::ITEM_CLASS_SUB_INVENTORY ) ) ) { pTradeManager->cancelTrade(pPC); executeError(pPacket, pPlayer, GC_TRADE_ERROR_CODE_ADD_ITEM); return; } // //#ifdef __XMAS_EVENT_CODE__ // 녹색 선물 상자인 경우에는, 상대방에게 적색 선물 상자가 없는지 검사한 후, // 인증 패킷을 보내줘야 한다. if (pItem->getItemClass() == Item::ITEM_CLASS_EVENT_GIFT_BOX) { PlayerCreature* pReceiver = dynamic_cast<PlayerCreature*>(pTargetPC); Item* pExtraSlotItem = pReceiver->getExtraInventorySlotItem(); if (pItem->getItemType() == 0) { Inventory* pTargetInventory = pReceiver->getInventory(); if (pTargetInventory->hasRedGiftBox()) { // 적색 선물 상자를 가지고 있다면 더할 수 없다. 리턴시킨다. GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_ADD_ITEM_FAIL); pPlayer->sendPacket(&gcTradeVerify); return; } else if (pExtraSlotItem != NULL) { if (pExtraSlotItem->getItemClass() == Item::ITEM_CLASS_EVENT_GIFT_BOX && pExtraSlotItem->getItemType() == 1) { GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_ADD_ITEM_FAIL); pPlayer->sendPacket(&gcTradeVerify); return; } } else { // 적색 선물 상자를 가지고 있지 않다면, 걍 넘어간다. GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_ADD_ITEM_OK); pPlayer->sendPacket(&gcTradeVerify); } } else if (pItem->getItemType() == 1) { // 적색 선물 상자는 교환 품목이 될 수 없다. GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_ADD_ITEM_FAIL); pPlayer->sendPacket(&gcTradeVerify); return; } } //#endif // TradeInfo* pInfo1 = pTradeManager->getTradeInfo(pSender->getName()); TradeInfo* pInfo2 = pTradeManager->getTradeInfo(pTargetPC->getName()); list<Item*> tradeList1 = pInfo1->getItemList(); if (pItem->getItemClass() == Item::ITEM_CLASS_EVENT_GIFT_BOX && pItem->getItemType() > 1 && pItem->getItemType() < 6) { for (list<Item*>::iterator itr = tradeList1.begin(); itr != tradeList1.end(); itr++) { Item* pTradeItem = (*itr); if (pTradeItem->getItemClass() == Item::ITEM_CLASS_EVENT_GIFT_BOX && pTradeItem->getItemType() > 1 && pTradeItem->getItemType() < 6) { GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_ADD_ITEM_FAIL); pPlayer->sendPacket(&gcTradeVerify); return; } } GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_ADD_ITEM_OK); pPlayer->sendPacket(&gcTradeVerify); } else if (pItem->getItemClass() == Item::ITEM_CLASS_EVENT_GIFT_BOX && pItem->getItemType() >= 6) { GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_ADD_ITEM_OK); pPlayer->sendPacket(&gcTradeVerify); } // TradeManager에 교환 대상으로서 아이템을 더한다. //Assert(pInfo1->addItem(pItem)); pInfo1->addItem(pItem); // 현재 OK를 누른 상태라면, 클라이언트에게 인증 패킷을 보내줘야 한다. if (pInfo1->getStatus() == TRADE_FINISH) { //cout << "CGTradeRemoveItem [" << pSender->getName() << "]의 상태가 TRADE_FINISH이므로, 인증 패킷을 보내준다." << endl; // 인증 패킷을 날려준다. GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_ADD_ITEM_WHEN_ACCEPT); pPlayer->sendPacket(&gcTradeVerify); } else { //cout << "CGTradeRemoveItem [" << pSender->getName() << "]의 상태가 TRADE_FINISH가 아니므로, 인증 패킷 날리지 않는다." << endl; } // 아이템을 더하거나 뺄 경우, 상태가 TRADE_FINISH라면 // TRADE_TRADING으로 바꿔줘야 한다. pInfo1->setStatus(TRADE_TRADING); pInfo2->setStatus(TRADE_TRADING); // 상대방에게 날려줄 아이템 정보를 구성한다. GCTradeAddItem gcTradeAddItem; makeGCTradeAddItemPacket(&gcTradeAddItem, pSender->getObjectID(), pItem, X, Y); // 상대방에게 교환할 아이템 정보를 날려준다. Player* pTargetPlayer = pTargetPC->getPlayer(); pTargetPlayer->sendPacket(&gcTradeAddItem); #endif __END_DEBUG_EX __END_CATCH }
void CGDisplayItemHandler::execute (CGDisplayItem* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ //#ifndef __TEST_SERVER__ // return; //#endif Assert(pPacket != NULL); Assert(pPlayer != NULL); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature()); Assert(pPC != NULL); Inventory* pInventory = pPC->getInventory(); Assert(pInventory != NULL); Store* pStore = pPC->getStore(); Assert(pStore != NULL); GCSystemMessage errorMsg; GCNoticeEvent errorNotice; if (pPacket->getIndex() > MAX_ITEM_NUM ) { filelog("Store.log", "[%s:%s] (%u) 잘못된 인덱스입니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pPacket->getIndex()); return; } if (pPacket->getX() >= pInventory->getWidth() || pPacket->getY() >= pInventory->getHeight() ) { filelog("Store.log", "[%s:%s] (%u,%u) 인벤토리 좌표를 잘못 보내줬습니다..", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pPacket->getX(), pPacket->getY()); return; } Item* pItem = pInventory->getItem(pPacket->getX(), pPacket->getY()); if (pItem == NULL || pItem->getObjectID() != pPacket->getItemObjectID() ) { filelog("Store.log", "[%s:%s] (%u, %u) : %u 아이템 좌표가 잘못되었거나 오브젝트 아이디가 잘못되었습니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pPacket->getX(), pPacket->getY(), pPacket->getItemObjectID()); return; } if (pPC->getZone()->getTradeManager()->getTradeInfo(pPC->getName() ) != NULL ) { filelog("Store.log", "[%s:%s] : 거래중에는 물건을 올려놓을 수 없습니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str()); return; } if (pStore->hasItem(pItem ) ) { filelog("Store.log", "[%s:%s] (%u, %u) 이미 아이템이 상점에 있습니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pItem->getObjectID(), pPacket->getIndex()); // errorMsg.setMessage("이미 진열된 아이템입니다."); errorNotice.setCode(NOTICE_EVENT_ALREADY_DISPLAYED); pGamePlayer->sendPacket(&errorNotice); return; } if (pItem->isTimeLimitItem() || !canSell(pItem ) || !canTrade(pItem ) || !canTradeInventoryItem(pItem ) ) { filelog("Store.log", "[%s:%s] (%s) 팔 수 없는 아이템입니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pItem->toString().c_str()); // errorMsg.setMessage("판매할 수 없는 아이템입니다."); errorNotice.setCode(NOTICE_EVENT_CANNOT_SELL); pGamePlayer->sendPacket(&errorNotice); return; } BYTE result = pStore->setStoreItem(pPacket->getIndex(), pItem, pPacket->getPrice()); if ( result != 0 ) { filelog("Store.log", "[%s:%s] (%u) 아이템을 놓을 수 없습니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), result); return; } GCMyStoreInfo gcInfo; gcInfo.setStoreInfo(&(pStore->getStoreInfo())); pGamePlayer->sendPacket(&gcInfo); if (pStore->isOpen() ) { GCAddStoreItem gcAdd; gcAdd.setOwnerObjectID(pPC->getObjectID()); gcAdd.setIndex(pPacket->getIndex()); pStore->getStoreItem(pPacket->getIndex() ).makeStoreItemInfo(gcAdd.getItem()); pPC->getZone()->broadcastPacket(pPC->getX(), pPC->getY(), &gcAdd, pPC); } #endif // __GAME_SERVER__ __END_DEBUG_EX __END_CATCH }