Beispiel #1
0
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
}