Ejemplo n.º 1
0
void Inventory::handleDragAndDrop() {
	if (!m_hasDraggingStarted) return;
	InventorySlot* selectedSlot = getSelectedSlot();
	if (!(g_inputController->isMousePressedLeft())) {
		if (selectedSlot != nullptr) {
			selectedSlot->activate();
			handleLevelDrop();
			handleMapDrop();
		}
		delete m_currentClone;
		m_currentClone = nullptr;
		m_hasDraggingStarted = false;
		m_isDragging = false;
		return;
	}
	sf::Vector2f mousePos = g_inputController->getDefaultViewMousePosition();
	if (!m_isDragging) {
		if (DRAG_DISTANCE < std::sqrt(
			(mousePos.x - m_startMousePosition.x) * (mousePos.x - m_startMousePosition.x) +
			(mousePos.y - m_startMousePosition.y) * (mousePos.y - m_startMousePosition.y))) {
			m_isDragging = true;
			delete m_currentClone;
			m_currentClone = new SlotClone(selectedSlot);
			m_currentClone->setPosition(mousePos - sf::Vector2f(InventorySlot::SIZE / 2.f, InventorySlot::SIZE / 2.f));
			selectedSlot->deactivate();
			handleLevelDrag();
			handleMapDrag();
		}
	}
	else {
		m_currentClone->setPosition(mousePos - sf::Vector2f(InventorySlot::SIZE / 2.f, InventorySlot::SIZE / 2.f));
	}
}
Ejemplo n.º 2
0
void Inventory::handleLevelDrag() {
	if (m_levelInterface == nullptr) return;
	InventorySlot* selectedSlot = getSelectedSlot();
	if (selectedSlot != nullptr && selectedSlot->getItemType() == ItemType::Consumable) {
		m_levelInterface->highlightQuickslots(true);
	}
}
Ejemplo n.º 3
0
int TradeShopHandler::helper_trade_shop_sell(SimulatorThread *sim,
		CharacterServerData *pld, SimulatorQuery *query,
		CreatureInstance *creatureInstance,
		const char *itemHex) {
	//Return the query response when selling stuff to an NPC shop.
	unsigned int CCSID = strtol(itemHex, NULL, 16);
	InventorySlot *item = pld->charPtr->inventory.GetItemPtrByCCSID(CCSID);
	if (item == NULL)
		return PrepExt_QueryResponseError(sim->SendBuf, query->ID,
				"Item not found in inventory.");

	ItemDef *itemPtr = item->ResolveItemPtr();
	if (itemPtr == NULL)
		return PrepExt_QueryResponseError(sim->SendBuf, query->ID,
				"Item does not exist in server database.");

	int wpos = 0;
	wpos += PrepExt_QueryResponseString(&sim->SendBuf[wpos], query->ID, "OK");

	int cost = itemPtr->mValue;
	cost *= item->GetStackCount();
	wpos += pld->charPtr->inventory.AddBuyBack(item, &sim->SendBuf[wpos]);
	wpos += RemoveItemUpdate(&sim->SendBuf[wpos], sim->Aux3, item);
	pld->charPtr->inventory.RemItem(CCSID);
	pld->charPtr->pendingChanges++;
	creatureInstance->AdjustCopper(cost);

	return wpos;
}
Ejemplo n.º 4
0
void Inventory::handleMapDrag() {
	if (m_mapInterface == nullptr) return;
	InventorySlot* selectedSlot = getSelectedSlot();
	if (selectedSlot != nullptr && !m_isEquipmentSlotDragged) {
		m_equipment->highlightEquipmentSlot(selectedSlot->getItemType(), true);
	}
}
Ejemplo n.º 5
0
void Inventory::handleLevelDrop() {
	if (m_levelInterface == nullptr || m_currentClone == nullptr) return;
	InventorySlot* selectedSlot = getSelectedSlot();
	if (selectedSlot != nullptr && selectedSlot->getItemType() == ItemType::Consumable) {
		m_levelInterface->notifyConsumableDrop(m_currentClone);
		m_levelInterface->highlightQuickslots(false);
	}
}
Ejemplo n.º 6
0
void Inventory::deselectCurrentSlot() {
	InventorySlot* slot = getSelectedSlot();
	m_selectedSlotId.first = "";
	m_selectedSlotId.second = ItemType::VOID;
	m_descriptionWindow->hide();
	if (slot != nullptr) {
		slot->deselect();
	}
}
Ejemplo n.º 7
0
int TradeShopHandler::helper_trade_shop_buyback(SimulatorThread *sim,
		CharacterServerData *pld, SimulatorQuery *query,
		CreatureInstance *creatureInstance,unsigned int CCSID) {
	InventorySlot *buybackItem = pld->charPtr->inventory.GetItemPtrByCCSID(
			CCSID);
	if (buybackItem == NULL)
		return PrepExt_QueryResponseError(sim->SendBuf, query->ID,
				"Item not found in buyback list.");

	int freeslot = pld->charPtr->inventory.GetFreeSlot(INV_CONTAINER);
	if (freeslot == -1)
		return PrepExt_QueryResponseError(sim->SendBuf, query->ID,
				"No free inventory space.");

	ItemDef *itemPtr = buybackItem->ResolveItemPtr();
	if (itemPtr == NULL)
		return PrepExt_QueryResponseError(sim->SendBuf, query->ID,
				"Item does not exist in database.");

	int cost = itemPtr->mValue * buybackItem->GetStackCount();
	if (creatureInstance->css.copper < cost)
		return PrepExt_QueryResponseError(sim->SendBuf, query->ID, "Not enough coin.");

	InventorySlot newItem;
	newItem.CopyFrom(*buybackItem, false);
	newItem.CCSID = pld->charPtr->inventory.GetCCSID(INV_CONTAINER, freeslot);

	int r = pld->charPtr->inventory.AddItem(INV_CONTAINER, newItem);
	if (r == -1)
		return PrepExt_QueryResponseError(sim->SendBuf, query->ID,
				"Failed to create item.");
	pld->charPtr->pendingChanges++;

	int wpos = 0;
	wpos = RemoveItemUpdate(sim->SendBuf, sim->Aux3, buybackItem);
	wpos += AddItemUpdate(&sim->SendBuf[wpos], sim->Aux3, &newItem);
	wpos += PrepExt_QueryResponseString(&sim->SendBuf[wpos], query->ID, "OK");
	pld->charPtr->inventory.RemItem(buybackItem->CCSID);
	pld->charPtr->pendingChanges++;
	creatureInstance->AdjustCopper(-cost);
	return wpos;
}
Ejemplo n.º 8
0
void Inventory::selectSlot(const std::string& selectedSlotId, ItemType type) {
	if (selectedSlotId.empty()) {
		deselectCurrentSlot();
		return;
	}
	m_hasDraggingStarted = true;
	m_isEquipmentSlotDragged = type != ItemType::VOID;
	m_startMousePosition = g_inputController->getDefaultViewMousePosition();

	if (selectedSlotId.compare(m_selectedSlotId.first) == 0) return;
	
	deselectCurrentSlot();
	m_selectedSlotId.first = selectedSlotId;
	m_selectedSlotId.second = type;
	InventorySlot* selectedSlot = getSelectedSlot();
	hideDocument();
	if (selectedSlot != nullptr) {
		selectedSlot->select();
		showDescription(selectedSlot->getItem());
	}
}
Ejemplo n.º 9
0
int TradeItemsHandler::protected_helper_query_trade_items(SimulatorThread *sim,
		CharacterServerData *pld, SimulatorQuery *query,
		CreatureInstance *creatureInstance) {
	int selfID = creatureInstance->CreatureID;
	int tradeID = creatureInstance->activeLootID;

	ActiveInstance *actInst = creatureInstance->actInst;
	TradeTransaction *tradeData = actInst->tradesys.GetExistingTransaction(
			tradeID);
	if (tradeData == NULL)
		return QueryErrorMsg::TRADENOTFOUND;

	TradePlayerData *pData = tradeData->GetPlayerData(selfID);
	if (pData == NULL)
		return actInst->tradesys.CancelTransaction(selfID, tradeID, sim->SendBuf);

	if (pData->otherPlayerData->tradeWindowOpen == false)
		return QueryErrorMsg::TRADENOTOPENED;

	InventorySlot item;
	pData->itemList.clear();
	for (unsigned int a = 0; a < query->argCount; a++) {
		unsigned long CCSID = strtol(query->args[a].c_str(), NULL, 16);
		InventorySlot *itemPtr = pld->charPtr->inventory.GetItemPtrByCCSID(
				CCSID);
		if (itemPtr == NULL)
			return QueryErrorMsg::INVALIDITEM;

		item.CopyFrom(*itemPtr, false);
		item.CCSID = CCSID;
		pData->itemList.push_back(item);
	}

	CreatureInstance *cInst = pData->otherPlayerData->cInst;
	int wpos = PrepExt_TradeItemOffer(sim->SendBuf, sim->Aux3, selfID, pData->itemList);

	SendToOneSimulator(sim->SendBuf, wpos, cInst->simulatorPtr);
	return PrepExt_QueryResponseString(sim->SendBuf, query->ID, "OK");
}
Ejemplo n.º 10
0
void Inventory::update(const sf::Time& frameTime) {
	if (!m_isVisible) return;

	// check whether an item was selected
	for (auto& it : *(m_typeMap.at(m_currentTab))) {
		it.second.update(frameTime);
		if (it.second.isClicked()) {
			selectSlot(it.second.getItemID(), ItemType::VOID);
			return;
		}
		if (it.second.isRightClicked()) {
			handleLevelRightClick(&it.second);
			handleMapRightClick(&it.second);
			break;
		}
	}

	for (auto& it : m_tabs) {
		it.first.update(frameTime);
		if (it.first.isClicked() && m_currentTab != it.second) {
			selectTab(it.second);
			return;
		}
	}

	// update equipment part
	m_equipment->update(frameTime);
	InventorySlot* eqSlot = m_equipment->getSelectedSlot();
	if (eqSlot != nullptr) {
		selectSlot(eqSlot->getItemID(), eqSlot->getItemType());
	}

	handleDragAndDrop();

	if (m_equipment->requiresReload()) {
		reload();
	}
}
void CGAddMouseToQuickSlotHandler::execute (CGAddMouseToQuickSlot* pPacket , Player* pPlayer)
	throw(ProtocolException, Error)
{
	__BEGIN_TRY __BEGIN_DEBUG_EX

#ifdef __GAME_SERVER__

	Assert(pPacket != NULL);
	Assert(pPlayer != NULL);

	GamePlayer*    pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);
	Creature*      pCreature   = pGamePlayer->getCreature();
	bool           Success     = false;

	if (pCreature->isSlayer())
	{
		Slayer*        pSlayer    = dynamic_cast<Slayer*>(pCreature);
		InventorySlot* pExtraSlot = pSlayer->getExtraInventorySlot();
		Item*          pItem      = pExtraSlot->getItem();

		if (pItem == NULL)
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		ObjectID_t      ItemObjectID = pItem->getObjectID();
		SlotID_t        SlotID       = pPacket->getSlotID();
		Item::ItemClass IClass       = pItem->getItemClass();

		// 아이템의 ObjectID가 일치하는지 체크한다.
		if (ItemObjectID != pPacket->getObjectID()) 
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		// 벨트를 입고 있지 않다면 벨트에다 아이템을 더할 수가 없다.
		if (!pSlayer->isWear(Slayer::WEAR_BELT))
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		// 포션도 아니고, 탄창도 아니라면 더할 수가 없지.
		if (IClass != Item::ITEM_CLASS_POTION && IClass != Item::ITEM_CLASS_MAGAZINE && IClass != Item::ITEM_CLASS_EVENT_ETC && IClass != Item::ITEM_CLASS_KEY)
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}
		if (IClass == Item::ITEM_CLASS_EVENT_ETC && pItem->getItemType() < 14 )
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		Item*      pBelt          = pSlayer->getWearItem(Slayer::WEAR_BELT);
		Inventory* pBeltInventory = ((Belt*)pBelt)->getInventory();

		if (pBeltInventory->canAdding(SlotID, 0,  pItem)) 
		{
			// 현재 벨트에 있는 Item을 받아온다.
			Item* pPrevItem = pBeltInventory->getItem(SlotID, 0);

			// 지정한 자리에 아이템이 있다면...
			if (pPrevItem != NULL)
			{
				// 아이템이 완전히 같은 아이템이라면...
				if (isStackable(pItem) && isSameItem(pItem, pPrevItem))
				{
					int MaxStack = ItemMaxStack[pItem->getItemClass()];

					if (pItem->getNum() + pPrevItem->getNum() > MaxStack) 
					{
						ItemNum_t CurrentNum = pPrevItem->getNum();
						ItemNum_t AddNum     = pItem->getNum();
						ItemNum_t NewNum	 = AddNum + CurrentNum - MaxStack;

						pPrevItem->setNum(MaxStack);
						pItem->setNum(NewNum);
						pBeltInventory->increaseNum(MaxStack - CurrentNum);
						pBeltInventory->increaseWeight(pItem->getWeight()* (MaxStack - CurrentNum));
						//pPrevItem->save(pSlayer->getName(), STORAGE_BELT, pBelt->getItemID(), SlotID, 0);
						// item저장 최적화. by sigi. 2002.5.13
						char pField[80];
						sprintf(pField, "Num=%d, Storage=%d, StorageID=%lu, X=%d", MaxStack, STORAGE_BELT, pBelt->getItemID(), SlotID);
						pPrevItem->tinysave(pField);

						//pItem->save(pSlayer->getName(), STORAGE_EXTRASLOT, 0, 0, 0);
						// item저장 최적화. by sigi. 2002.5.13
						sprintf(pField, "Num=%d, Storage=%d", NewNum, STORAGE_EXTRASLOT);
						pItem->tinysave(pField);


						Success = true;
					} 
					else // 숫자가 9개를 넘지 않을 때.
					{
						pSlayer->deleteItemFromExtraInventorySlot();
						pPrevItem->setNum(pPrevItem->getNum() + pItem->getNum());
						pBeltInventory->increaseNum(pItem->getNum());
						pBeltInventory->increaseWeight(pItem->getWeight()* pItem->getNum());
						//pPrevItem->save(pSlayer->getName(), STORAGE_BELT , pBelt->getItemID(), SlotID, 0);
						// item저장 최적화. by sigi. 2002.5.13
						char pField[80];
						sprintf(pField, "Num=%d, Storage=%d, StorageID=%lu, X=%d", pPrevItem->getNum(), STORAGE_BELT, pBelt->getItemID(), SlotID);
						pPrevItem->tinysave(pField);

						pItem->destroy();
						SAFE_DELETE(pItem);
						Success = true;
					}
				} 
				else // 클래스랑 타입이 같지 않을때
				{
					// 마우스에 달려있는 아이템과 벨트에 있는 아이템을 제거한다.
					pSlayer->deleteItemFromExtraInventorySlot();
					pBeltInventory->deleteItem(pPrevItem->getObjectID());

					// 둘의 위치를 바꿔 준다.
					pSlayer->addItemToExtraInventorySlot(pPrevItem);
					pBeltInventory->addItem(SlotID , 0 , pItem);

					// DB에다가 저장을 한다.
					//pPrevItem->save(pSlayer->getName(), STORAGE_EXTRASLOT, 0, 0, 0);
					// item저장 최적화. by sigi. 2002.5.13
					char pField[80];
					sprintf(pField, "Storage=%d", STORAGE_EXTRASLOT);
					pPrevItem->tinysave(pField);

					//pItem->save(pSlayer->getName(), STORAGE_BELT , pBelt->getItemID(), SlotID, 0);
					// item저장 최적화. by sigi. 2002.5.13
					sprintf(pField, "Storage=%d, StorageID=%lu, X=%d", STORAGE_BELT, pBelt->getItemID(), SlotID);
					pItem->tinysave(pField);


					Success = true;
				}
			} 
			else // 슬랏에 아무런 기존의 아이템이 없을때.
			{
				// Inventory에 특정 아이템을 넣는다.
				pBeltInventory->addItem(SlotID, 0 , pItem);

				// 넣기에 성공하면 마우스에 달려있는 아이템을 없앤다.
				pSlayer->deleteItemFromExtraInventorySlot();
				//pItem->save(pSlayer->getName(), STORAGE_BELT, pBelt->getItemID(), SlotID, 0);
				// item저장 최적화. by sigi. 2002.5.13
				char pField[80];
				sprintf(pField, "Storage=%d, StorageID=%lu, X=%d", STORAGE_BELT, pBelt->getItemID(), SlotID);
				pItem->tinysave(pField);

				Success = true;
			}
		} // end of if (pBeltInventory->canAdding(SlotID, 0,  pItem)) 
	} // if (pCreature->isSlayer())
	else if (pCreature->isOusters())
	{
		Ousters*        pOusters  = dynamic_cast<Ousters*>(pCreature);
		InventorySlot* pExtraSlot = pOusters->getExtraInventorySlot();
		Item*          pItem      = pExtraSlot->getItem();

		if (pItem == NULL)
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		ObjectID_t      ItemObjectID = pItem->getObjectID();
		SlotID_t        SlotID       = pPacket->getSlotID();
		Item::ItemClass IClass       = pItem->getItemClass();

		// 아이템의 ObjectID가 일치하는지 체크한다.
		if (ItemObjectID != pPacket->getObjectID()) 
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		Ousters::WearPart part = (SlotID > 2 ? Ousters::WEAR_ARMSBAND2 : Ousters::WEAR_ARMSBAND1);
		if (SlotID > 2 ) SlotID -= 3;

		// 해당 암스밴드가 없다
		if (!pOusters->isWear(part)) 
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		// 푸파도 아니고, 콤포스메이도 아니라면 더할 수가 없지.
		if (IClass != Item::ITEM_CLASS_PUPA && IClass != Item::ITEM_CLASS_COMPOS_MEI && IClass != Item::ITEM_CLASS_EVENT_ETC )
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		if (IClass == Item::ITEM_CLASS_EVENT_ETC && pItem->getItemType() < 14 )
		{
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		Item*      pArmsband          = pOusters->getWearItem(part);
		Inventory* pArmsbandInventory = ((OustersArmsband*)pArmsband)->getInventory();

		if (pArmsbandInventory->canAdding(SlotID, 0,  pItem)) 
		{
			// 현재 벨트에 있는 Item을 받아온다.
			Item* pPrevItem = pArmsbandInventory->getItem(SlotID, 0);

			// 지정한 자리에 아이템이 있다면...
			if (pPrevItem != NULL)
			{
				// 아이템이 완전히 같은 아이템이라면...
				if (isSameItem(pItem, pPrevItem))
				{
					int MaxStack = ItemMaxStack[pItem->getItemClass()];

					if (pItem->getNum() + pPrevItem->getNum() > MaxStack) 
					{
						ItemNum_t CurrentNum = pPrevItem->getNum();
						ItemNum_t AddNum     = pItem->getNum();
						ItemNum_t NewNum	 = AddNum + CurrentNum - MaxStack;

						pPrevItem->setNum(MaxStack);
						pItem->setNum(NewNum);
						pArmsbandInventory->increaseNum(MaxStack - CurrentNum);
						pArmsbandInventory->increaseWeight(pItem->getWeight()* (MaxStack - CurrentNum));
						//pPrevItem->save(pOusters->getName(), STORAGE_BELT, pArmsband->getItemID(), SlotID, 0);
						// item저장 최적화. by sigi. 2002.5.13
						char pField[80];
						sprintf(pField, "Num=%d, Storage=%d, StorageID=%lu, X=%d", MaxStack, STORAGE_BELT, pArmsband->getItemID(), SlotID);
						pPrevItem->tinysave(pField);

						//pItem->save(pOusters->getName(), STORAGE_EXTRASLOT, 0, 0, 0);
						// item저장 최적화. by sigi. 2002.5.13
						sprintf(pField, "Num=%d, Storage=%d", NewNum, STORAGE_EXTRASLOT);
						pItem->tinysave(pField);


						Success = true;
					} 
					else // 숫자가 9개를 넘지 않을 때.
					{
						pOusters->deleteItemFromExtraInventorySlot();
						pPrevItem->setNum(pPrevItem->getNum() + pItem->getNum());
						pArmsbandInventory->increaseNum(pItem->getNum());
						pArmsbandInventory->increaseWeight(pItem->getWeight()* pItem->getNum());
						//pPrevItem->save(pOusters->getName(), STORAGE_BELT , pArmsband->getItemID(), SlotID, 0);
						// item저장 최적화. by sigi. 2002.5.13
						char pField[80];
						sprintf(pField, "Num=%d, Storage=%d, StorageID=%lu, X=%d", pPrevItem->getNum(), STORAGE_BELT, pArmsband->getItemID(), SlotID);
						pPrevItem->tinysave(pField);

						pItem->destroy();
						SAFE_DELETE(pItem);
						Success = true;
					}
				} 
				else // 클래스랑 타입이 같지 않을때
				{
					// 마우스에 달려있는 아이템과 벨트에 있는 아이템을 제거한다.
					pOusters->deleteItemFromExtraInventorySlot();
					pArmsbandInventory->deleteItem(pPrevItem->getObjectID());

					// 둘의 위치를 바꿔 준다.
					pOusters->addItemToExtraInventorySlot(pPrevItem);
					pArmsbandInventory->addItem(SlotID , 0 , pItem);

					// DB에다가 저장을 한다.
					//pPrevItem->save(pOusters->getName(), STORAGE_EXTRASLOT, 0, 0, 0);
					// item저장 최적화. by sigi. 2002.5.13
					char pField[80];
					sprintf(pField, "Storage=%d", STORAGE_EXTRASLOT);
					pPrevItem->tinysave(pField);

					//pItem->save(pOusters->getName(), STORAGE_BELT , pArmsband->getItemID(), SlotID, 0);
					// item저장 최적화. by sigi. 2002.5.13
					sprintf(pField, "Storage=%d, StorageID=%lu, X=%d", STORAGE_BELT, pArmsband->getItemID(), SlotID);
					pItem->tinysave(pField);


					Success = true;
				}
			} 
			else // 슬랏에 아무런 기존의 아이템이 없을때.
			{
				// Inventory에 특정 아이템을 넣는다.
				pArmsbandInventory->addItem(SlotID, 0 , pItem);

				// 넣기에 성공하면 마우스에 달려있는 아이템을 없앤다.
				pOusters->deleteItemFromExtraInventorySlot();
				//pItem->save(pOusters->getName(), STORAGE_BELT, pArmsband->getItemID(), SlotID, 0);
				// item저장 최적화. by sigi. 2002.5.13
				char pField[80];
				sprintf(pField, "Storage=%d, StorageID=%lu, X=%d", STORAGE_BELT, pArmsband->getItemID(), SlotID);
				pItem->tinysave(pField);

				Success = true;
			}
		} // end of if (pArmsbandInventory->canAdding(SlotID, 0,  pItem)) 
	} // if (pCreature->isOusters())

	// QuickSlot에 넣는 것을 실패 하였을때 실패 패킷을 날린다.
	if (!Success) 
	{
		GCCannotAdd _GCCannotAdd;
		_GCCannotAdd.setObjectID(pPacket->getObjectID());
		pPlayer->sendPacket(&_GCCannotAdd);
	}

#endif	// __GAME_SERVER__

    __END_DEBUG_EX __END_CATCH

}
Ejemplo n.º 12
0
int TradeAcceptHandler::protected_helper_query_trade_accept(SimulatorThread *sim,
		CharacterServerData *pld, SimulatorQuery *query,
		CreatureInstance *creatureInstance) {
	int selfID = creatureInstance->CreatureID;
	int tradeID = creatureInstance->activeLootID;
	ActiveInstance *actInst = creatureInstance->actInst;
	TradeTransaction *tradeData = actInst->tradesys.GetExistingTransaction(
			tradeID);
	if (tradeData == NULL)
		return QueryErrorMsg::TRADENOTFOUND;

	TradePlayerData *pData = tradeData->GetPlayerData(selfID);
	if (pData == NULL)
		return actInst->tradesys.CancelTransaction(selfID, tradeID, sim->SendBuf);

	CreatureInstance *cInst = pData->otherPlayerData->cInst;

	pData->SetAccepted(true);

	int wpos = 0;
	wpos += PutByte(&sim->SendBuf[wpos], 51);     //_handleTradeMsg
	wpos += PutShort(&sim->SendBuf[wpos], 0);    //Placeholder for size
	wpos += PutInteger(&sim->SendBuf[wpos], creatureInstance->CreatureID);   //traderID
	wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::OFFER_ACCEPTED); //eventType
	PutShort(&sim->SendBuf[1], wpos - 3);       //Set message size
	SendToOneSimulator(sim->SendBuf, wpos, cInst->simulatorPtr);
	//actInst->LSendToOneSimulator(SendBuf, wpos, cInst->SimulatorIndex);

	CreatureInstance *origin = tradeData->player[0].cInst;
	CreatureInstance *target = tradeData->player[1].cInst;
	if (origin == NULL || target == NULL)
		return QueryErrorMsg::INVALIDOBJ;

	if (tradeData->MutualAccept() == true) {
		//Process the trade.
		int wpos = 0;

		//When counting slots, get the currently free slots.
		//Then add the number of items that would be traded (given away).
		//This allows a currently full inventory to potentially receive items
		//after the transaction is processed.

		int oslots = origin->charPtr->inventory.CountFreeSlots(INV_CONTAINER);
		oslots += tradeData->player[0].itemList.size();

		int tslots = target->charPtr->inventory.CountFreeSlots(INV_CONTAINER);
		tslots += tradeData->player[1].itemList.size();

		if (oslots < (int) tradeData->player[1].itemList.size()) {
			//Origin player does not have enough space to receive items.
			wpos = 0;
			wpos += PutByte(&sim->SendBuf[wpos], 51);    //_handleTradeMsg
			wpos += PutShort(&sim->SendBuf[wpos], 0);    //Placeholder for size
			wpos += PutInteger(&sim->SendBuf[wpos], origin->CreatureID);   //traderID
			wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType
			wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::INSUFFICIENT_SPACE); //eventType
			PutShort(&sim->SendBuf[1], wpos - 3);       //Set message size
			SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr);
			SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr);
			//origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex);
			//target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex);
			g_Logs.simulator->debug("[%v] Origin lacks space", sim->InternalID);
			goto exit;
		}
		if (tslots < (int) tradeData->player[0].itemList.size()) {
			//Target player does not have enough space to receive items.
			wpos = 0;
			wpos += PutByte(&sim->SendBuf[wpos], 51);    //_handleTradeMsg
			wpos += PutShort(&sim->SendBuf[wpos], 0);    //Placeholder for size
			wpos += PutInteger(&sim->SendBuf[wpos], target->CreatureID);   //traderID
			wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType
			wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::INSUFFICIENT_SPACE); //eventType
			PutShort(&sim->SendBuf[1], wpos - 3);       //Set message size
			SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr);
			SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr);
			//origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex);
			//target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex);
			g_Logs.simulator->debug("[%v] Target lacks space", sim->InternalID);
			goto exit;
		}

		//Check that each player has the required currencies.
		if (tradeData->player[0].coin > origin->css.copper) {
			wpos = 0;
			wpos += PutByte(&sim->SendBuf[wpos], 51);    //_handleTradeMsg
			wpos += PutShort(&sim->SendBuf[wpos], 0);    //Placeholder for size
			wpos += PutInteger(&sim->SendBuf[wpos], origin->CreatureID);   //traderID
			wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType
			wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::INSUFFICIENT_FUNDS); //eventType
			PutShort(&sim->SendBuf[1], wpos - 3);       //Set message size
			SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr);
			SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr);
			//origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex);
			//target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex);
			g_Logs.simulator->debug("[%v] Origin lacks copper", sim->InternalID);
			goto exit;
		}
		if (tradeData->player[1].coin > target->css.copper) {
			wpos = 0;
			wpos += PutByte(&sim->SendBuf[wpos], 51);    //_handleTradeMsg
			wpos += PutShort(&sim->SendBuf[wpos], 0);    //Placeholder for size
			wpos += PutInteger(&sim->SendBuf[wpos], target->CreatureID);   //traderID
			wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType
			wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::INSUFFICIENT_FUNDS); //eventType
			PutShort(&sim->SendBuf[1], wpos - 3);       //Set message size
			SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr);
			SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr);
			//origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex);
			//target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex);
			g_Logs.simulator->debug("[%v] Target lacks copper", sim->InternalID);
			goto exit;
		}

		//Ready to trade.
		g_Logs.simulator->debug("[%v] Trade requirements passed", sim->InternalID);

		//Adjust and send coin transfer to both players.
		origin->css.copper -= tradeData->player[0].coin;
		target->css.copper -= tradeData->player[1].coin;

		origin->css.copper += tradeData->player[1].coin;
		target->css.copper += tradeData->player[0].coin;

		static const short statSend = STAT::COPPER;
		wpos = PrepExt_SendSpecificStats(sim->SendBuf, origin, &statSend, 1);
		SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr);
		//origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex);

		wpos = PrepExt_SendSpecificStats(sim->SendBuf, target, &statSend, 1);
		SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr);
		//origin->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex);

		//Adjust and send items for first player.

		//Remove items from first player.
		wpos = 0;
		CharacterData *p1 = origin->charPtr;
		CharacterData *p2 = target->charPtr;
		g_Logs.simulator->debug("[%v] Trade betweeen [%v] and [%v]",
				sim->InternalID, p1->cdef.css.display_name, p2->cdef.css.display_name);
		for (size_t a = 0; a < tradeData->player[0].itemList.size(); a++) {
			unsigned long CCSID = tradeData->player[0].itemList[a].CCSID;
			InventorySlot *item = p1->inventory.GetItemPtrByCCSID(CCSID);
			if (item == NULL) {
				g_Logs.simulator->error(
						"[%v] Failed to remove item from first player.", sim->InternalID);
			} else {
				wpos += p1->inventory.RemoveItemUpdate(&sim->SendBuf[wpos], sim->Aux3,
						item);
				p1->inventory.RemItem(CCSID);
				p1->pendingChanges++;
			}
		}
		SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr);
		//origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex);
		g_Logs.simulator->debug("[%v] Removed %v items from first player.", sim->InternalID,
				tradeData->player[0].itemList.size());

		//Remove items from second player.
		wpos = 0;
		for (size_t a = 0; a < tradeData->player[1].itemList.size(); a++) {
			unsigned long CCSID = tradeData->player[1].itemList[a].CCSID;
			InventorySlot *item = p2->inventory.GetItemPtrByCCSID(CCSID);
			if (item == NULL) {
				g_Logs.simulator->error(
						"[%v] Failed to remove item from first player.", sim->InternalID);
			} else {
				wpos += p2->inventory.RemoveItemUpdate(&sim->SendBuf[wpos], sim->Aux3,
						item);
				p2->inventory.RemItem(CCSID);
				p2->pendingChanges++;
			}
		}
		SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr);
		//target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex);
		g_Logs.simulator->debug("[%v] Removed %v items from second player.", sim->InternalID,
				tradeData->player[1].itemList.size());

		//Give items to first player
		wpos = 0;
		for (size_t a = 0; a < tradeData->player[1].itemList.size(); a++) {
			int itemID = tradeData->player[1].itemList[a].IID;
			int count = tradeData->player[1].itemList[a].count + 1;
			InventorySlot *item = p1->inventory.AddItem_Ex(INV_CONTAINER,
					itemID, count);
			if (item == NULL)
				g_Logs.simulator->error("[%v] Failed to add item to first player.", sim->InternalID);
			else {
				p1->pendingChanges++;
				g_Logs.event->info("[TRADE] From %v to %v (%v)",
						tradeData->player[1].cInst->css.display_name,
						tradeData->player[0].cInst->css.display_name,
						item->IID);
				item->CopyWithoutCount(tradeData->player[1].itemList[a], false);
				sim->ActivateActionAbilities(item);
				wpos += AddItemUpdate(&sim->SendBuf[wpos], sim->Aux3, item);
			}
		}
		SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr);
		//origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex);
		g_Logs.simulator->debug("[%v] Gave %v items to first player.", sim->InternalID,
				tradeData->player[1].itemList.size());

		//Give items to second player
		wpos = 0;
		for (size_t a = 0; a < tradeData->player[0].itemList.size(); a++) {
			int itemID = tradeData->player[0].itemList[a].IID;
			int count = tradeData->player[0].itemList[a].count + 1;
			InventorySlot *item = p2->inventory.AddItem_Ex(INV_CONTAINER,
					itemID, count);
			if (item == NULL)
				g_Logs.simulator->error("[%v] Failed to add item to second player.", sim->InternalID);
			else {
				p2->pendingChanges++;
				g_Logs.event->info("[TRADE] From %v to %v (%v)",
						tradeData->player[0].cInst->css.display_name,
						tradeData->player[1].cInst->css.display_name,
						item->IID);
				item->CopyWithoutCount(tradeData->player[0].itemList[a], false);
				sim->ActivateActionAbilities(item);
				wpos += AddItemUpdate(&sim->SendBuf[wpos], sim->Aux3, item);
			}
		}
		SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr);
		//target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex);
		g_Logs.simulator->debug("[%v] Gave %v items to second player.", sim->InternalID,
				tradeData->player[0].itemList.size());

		//Send trade completion message.
		wpos = 0;
		wpos += PutByte(&sim->SendBuf[wpos], 51);    //_handleTradeMsg
		wpos += PutShort(&sim->SendBuf[wpos], 0);    //Placeholder for size
		wpos += PutInteger(&sim->SendBuf[wpos], origin->CreatureID);     //traderID
		wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType
		wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::COMPLETE);     //eventType
		PutShort(&sim->SendBuf[1], wpos - 3);       //Set message size

		SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr);
		//origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex);

		PutInteger(&sim->SendBuf[3], target->CreatureID);     //traderID
		SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr);
		//target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex);

		//Clear trade IDs.
		origin->activeLootID = 0;
		target->activeLootID = 0;

		g_Logs.simulator->debug("[%v] Trade complete", sim->InternalID);
		actInst->tradesys.RemoveTransaction(tradeID);
	}

	//Yes, I'm using goto.
	//Yes, I know this whole thing is badly programmed.
	//Deal with it.

	exit: return PrepExt_QueryResponseString(sim->SendBuf, query->ID, "OK");
}