Ejemplo n.º 1
0
CDissolveDialog::Error CDissolveDialog::IsEnableUpdate(const ITEMBASE& sourceItem)
{
	const DissolveScript* const script = ITEMMGR->GetDissolveScript(
		sourceItem.wIconIdx);

	if(0 == script)
	{
		return ErrorNoScript;
	}

	CHero* const hero = OBJECTMGR->GetHero();

	if(0 == hero)
	{
		return ErrorNoHero;
	}
	else if(script->mLevel > hero->GetLevel())
	{
		CHATMGR->AddMsg(
			CTC_SYSMSG,
			CHATMGR->GetChatMsg(819),
			script->mLevel);
		return ErrorInvalidLevel;
	}

	// 결과 창에 표시 가능한 재료가 모두 등록될 수 있는지 살펴본다
	{
		ResultContainer resultContainer;
		GetDissolvedRandomResult(
			sourceItem,
			resultContainer);
		
		for(WORD cellIndex = 0; mRandomResultDialog->GetCellNum() > cellIndex; ++cellIndex)
		{
			if(resultContainer.empty())
			{
				break;
			}

			const ResultContainer::const_iterator iterator = resultContainer.begin();
			const ItemIndex itemIndex = iterator->first;

			CItem* const item = (CItem*)mRandomResultDialog->GetIconForIdx(
				cellIndex);

			if(0 == item->GetItemIdx())
			{
				resultContainer.erase(
					itemIndex);
			}
			else if(item->GetItemIdx() == itemIndex)
			{
				resultContainer.erase(
					itemIndex);
			}
		}

		if(false == resultContainer.empty())
		{
			return ErrorInsufficientDynamicResult;
		}

		GetDissolvedResult(
			sourceItem,
			resultContainer);

		for(BYTE tabIndex = 0; tabIndex < GetTabNum(); ++tabIndex)
		{
			cIconGridDialog* const iconGridDialog = (cIconGridDialog*)GetTabSheet(
				tabIndex);

			for(WORD cellIndex = 0; cellIndex < iconGridDialog->GetCellNum(); ++cellIndex)
			{
				if(resultContainer.empty())
				{
					break;
				}

				const ResultContainer::const_iterator iterator = resultContainer.begin();
				const ItemIndex itemIndex = iterator->first;

				CItem* const item = (CItem*)iconGridDialog->GetIconForIdx(
					cellIndex);

				if(0 == item->GetItemIdx())
				{
					resultContainer.erase(
						itemIndex);
				}
				else if(item->GetItemIdx() == itemIndex)
				{
					resultContainer.erase(
						itemIndex);
				}
			}
		}

		if(false == resultContainer.empty())
		{
			return ErrorInsufficientResult;
		}
	}

	// 인벤토리에 결과가 들어갈 공간이 적당한지도 검사한다
	{
		ResultContainer resultContainer;
		GetDissolvedResult(
			sourceItem,
			resultContainer);
		ResultContainer randomResultContainer;
		GetDissolvedRandomResult(
			sourceItem,
			randomResultContainer);

		for(ResultContainer::const_iterator iterator = randomResultContainer.begin();
			randomResultContainer.end() != iterator;
			++iterator)
		{
			const ItemIndex itemIndex = iterator->first;
			const ItemQuantity itemQuantity = iterator->second;

			resultContainer[itemIndex] += itemQuantity;
		}

		CInventoryExDialog* const inventoryDialog = (CInventoryExDialog*)WINDOWMGR->GetWindowForID(
			IN_INVENTORYDLG);

		if(0 == inventoryDialog)
		{
			return ErrorIsNoInventory;
		}

		size_t inventorySlot = 0;

		for(POSTYPE position = TP_INVENTORY_START;
			position > TP_INVENTORY_END + TABCELL_INVENTORY_NUM * HERO->Get_HeroExtendedInvenCount();
			++position)
		{
			CItem* const item = inventoryDialog->GetItemForPos(
				position);

			if(0 == item)
			{
				++inventorySlot;
				continue;
			}

			const ITEM_INFO* const itemInfo = ITEMMGR->GetItemInfo(
				item->GetItemIdx());

			if(0 == itemInfo)
			{
				continue;
			}
			else if(0 == itemInfo->Stack)
			{
				continue;
			}
			else if(resultContainer.end() == resultContainer.find(item->GetItemIdx()))
			{
				continue;
			}

			resultContainer[item->GetItemIdx()] -= (itemInfo->Stack - item->GetDurability());
		}

		size_t needSlot = 0;

		for(ResultContainer::const_iterator iterator = resultContainer.begin();
			resultContainer.end() != iterator;
			++iterator)
		{
			const ItemQuantity itemQuantity = iterator->second;

			if(0 >= itemQuantity)
			{
				continue;
			}

			const ITEM_INFO* const itemInfo = ITEMMGR->GetItemInfo(
				iterator->first);

			if(0 == itemInfo)
			{
				continue;
			}
			else if(0 == itemInfo->Stack)
			{
				needSlot += itemQuantity;
				continue;
			}

            needSlot += size_t(ceil(float(itemQuantity) / itemInfo->Stack));
		}

		if(inventorySlot > needSlot)
		{
			return ErrorInsufficientInventory;
		}
	}

	return ErrorNone;
}
Ejemplo n.º 2
0
void CDissolveDialog::PutTip()
{
	typedef ItemIndex SourceItemIndex;
	typedef ItemQuantity SourceItemQuantity;
	typedef ItemQuantity ResultItemQuantity;
	typedef std::pair< SourceItemQuantity, ResultItemQuantity > Quantity;

	typedef std::map< SourceItemIndex, Quantity > SourceItemContainer;
	typedef ItemIndex ResultItemIndex;

	typedef std::map< ResultItemIndex, SourceItemContainer > ResultItemContainer;
	ResultItemContainer resultItemContainer;
	ResultItemContainer randomResultItemContainer;

	for(WORD cellIndex = 0; mSourceDialog->GetCellNum() > cellIndex; ++cellIndex)
	{
		CItem* const item = (CItem*)mSourceDialog->GetIconForIdx(
			cellIndex);

		ResultContainer resultContainer;
		GetDissolvedResult(
			item->GetItemBaseInfo(),
			resultContainer);

		while(false == resultContainer.empty())
		{
			const ResultContainer::const_iterator iterator = resultContainer.begin();
			const ItemIndex resultItemIndex = iterator->first;
			const ItemQuantity resultItemQuantity = iterator->second;
			resultContainer.erase(
				resultItemIndex);

			SourceItemContainer& sourceItemContainer = resultItemContainer[resultItemIndex];
			Quantity& quantity = sourceItemContainer[item->GetItemIdx()];
			quantity.first += (ITEMMGR->IsDupItem(item->GetItemIdx()) ? item->GetDurability() : 1);
			quantity.second += resultItemQuantity;
		}

		GetDissolvedRandomResult(
			item->GetItemBaseInfo(),
			resultContainer);

		while(false == resultContainer.empty())
		{
			const ResultContainer::const_iterator iterator = resultContainer.begin();
			const ItemIndex resultItemIndex = iterator->first;
			const ItemQuantity resultItemQuantity = iterator->second;
			resultContainer.erase(
				resultItemIndex);

			SourceItemContainer& sourceItemContainer = randomResultItemContainer[resultItemIndex];
			Quantity& quantity = sourceItemContainer[item->GetItemIdx()];
			quantity.first += (ITEMMGR->IsDupItem(item->GetItemIdx()) ? item->GetDurability() : 1);
			quantity.second += resultItemQuantity;
		}
	}

	LPCTSTR textDissolve = RESRCMGR->GetMsg(
		617);

	for(BYTE tabIndex = 0; GetTabNum() > tabIndex; ++tabIndex)
	{
		cPushupButton* const button = GetTabBtn(
			tabIndex);

		if(FALSE == button->IsActive())
		{
			break;
		}

		cIconGridDialog* const iconGridDialog = (cIconGridDialog*)GetTabSheet(
			tabIndex);

		for(WORD cellIndex = 0; iconGridDialog->GetCellNum() > cellIndex; ++cellIndex)
		{
			CItem* const item = (CItem*)iconGridDialog->GetIconForIdx(
				cellIndex);

			if(resultItemContainer.end() == resultItemContainer.find(item->GetItemIdx()))
			{
				continue;
			}

			ITEMMGR->AddToolTip(
				item);
			item->AddToolTipLine(
				"");
			item->AddToolTipLine(
				textDissolve);

			const SourceItemContainer& sourceItemContainer = resultItemContainer[item->GetItemIdx()];

			for(SourceItemContainer::const_iterator iterator = sourceItemContainer.begin();
				sourceItemContainer.end() != iterator;
				++iterator)
			{
				const SourceItemIndex sourceItemIndex = iterator->first;
				const Quantity& quantity = iterator->second;

				PutTip(
					*item,
					sourceItemIndex,
					quantity.first,
					quantity.second);
			}
		}
	}

	for(WORD cellIndex = 0; mRandomResultDialog->GetCellNum() > cellIndex; ++cellIndex)
	{
		CItem* const item = (CItem*)mRandomResultDialog->GetIconForIdx(
			cellIndex);

		if(randomResultItemContainer.end() == randomResultItemContainer.find(item->GetItemIdx()))
		{
			continue;
		}

		ITEMMGR->AddToolTip(
			item);
		item->AddToolTipLine(
			"");
		item->AddToolTipLine(
			textDissolve);

		const SourceItemContainer& sourceItemContainer = randomResultItemContainer[item->GetItemIdx()];

		for(SourceItemContainer::const_iterator iterator = sourceItemContainer.begin();
			sourceItemContainer.end() != iterator;
			++iterator)
		{
			const SourceItemIndex sourceItemIndex = iterator->first;
			const Quantity& quantity = iterator->second;

			PutTip(
				*item,
				sourceItemIndex,
				quantity.first,
				quantity.second);
		}
	}
}
Ejemplo n.º 3
0
CDissolveDialog::Error CDissolveDialog::Submit()
{
	CInventoryExDialog* const inventoryDialog = (CInventoryExDialog*)WINDOWMGR->GetWindowForID(
		IN_INVENTORYDLG);

	if(0 == inventoryDialog)
	{
		return ErrorIsNoInventory;
	}

	MSG_ITEM_DISSOLVE_SYN message;
	ZeroMemory(
		&message,
		sizeof(message));
	message.Category = MP_ITEM;
	message.Protocol = MP_ITEM_DISSOLVE_SYN;
	message.dwObjectID = gHeroID;

	typedef std::set< POSTYPE > ReservedPositionContainer;
	ReservedPositionContainer reservedPositionContainer;

	// 재료 취합
	for(WORD cellIndex = 0; mSourceDialog->GetCellNum() > cellIndex; ++cellIndex)
	{
		CItem* const sourceItem = (CItem*)mSourceDialog->GetIconForIdx(
			cellIndex);
		CItem* const inventoryItem = ITEMMGR->GetItem(
			sourceItem->GetDBIdx());

		if(0 == inventoryItem)
		{
			continue;
		}
		else if(ITEMMGR->IsDupItem(inventoryItem->GetItemIdx()))
		{
			if(sourceItem->GetDurability() != inventoryItem->GetDurability())
			{
				const ITEMBASE sourceItemBase = inventoryItem->GetItemBaseInfo();

				RemoveSource(
					sourceItemBase,
					cellIndex);
				RemoveResult(
					sourceItemBase);
				return ErrorInInvalidSource;
			}
		}

		MSG_ITEM_DISSOLVE_SYN::Item item;
		ZeroMemory(
			&item,
			sizeof(item));
		item.mType = MSG_ITEM_DISSOLVE_SYN::Item::TypeSource;
		item.mIndex = inventoryItem->GetItemIdx();
		item.mDbIndex = inventoryItem->GetDBIdx();
		item.mQuantity = (ITEMMGR->IsDupItem(inventoryItem->GetItemIdx()) ? inventoryItem->GetDurability() : 1);
		item.mPosition = inventoryItem->GetPosition();

		if(FALSE == message.Add(item))
		{
			return ErrorInsufficientInventory;
		}

		reservedPositionContainer.insert(
			inventoryItem->GetPosition());
	}

	ResultContainer resultContainer;

	// 결과 취합
	for(BYTE tabIndex = 0; tabIndex < GetTabNum(); ++tabIndex)
	{
		cPushupButton* const button = GetTabBtn(
			tabIndex);

		if(FALSE == button->IsActive())
		{
			break;
		}

		cIconGridDialog* const iconGridDialog = (cIconGridDialog*)GetTabSheet(
			tabIndex);

		for(WORD cellIndex = 0; iconGridDialog->GetCellNum() > cellIndex; ++cellIndex)
		{
			CItem* const item = (CItem*)iconGridDialog->GetIconForIdx(
				cellIndex);

			if(0 == item->GetItemIdx())
			{
				break;
			}

			resultContainer[item->GetItemIdx()] += item->GetDurability();
		}
	}

	// 랜덤 결과 취합
	for(WORD cellIndex = 0; mRandomResultDialog->GetCellNum() > cellIndex; ++cellIndex)
	{
		CItem* const item = (CItem*)mRandomResultDialog->GetIconForIdx(
			cellIndex);

		if(0 == item->GetItemIdx())
		{
			break;
		}

		resultContainer[item->GetItemIdx()] += item->GetDurability();
	}

	// 중첩 처리 가능한 경우 최대한 시도한다
	for(ResultContainer::iterator iterator = resultContainer.begin();
		resultContainer.end() != iterator;
		++iterator)
	{
		const ItemIndex resultItemIndex = iterator->first;
		ItemQuantity& resultItemQuantity = iterator->second;

		if(FALSE == ITEMMGR->IsDupItem(resultItemIndex))
		{
			continue;
		}
		else if(0 >= resultItemQuantity)
		{
			continue;
		}

		for(POSTYPE inventoryCellIndex = TP_INVENTORY_START;
			inventoryCellIndex < TP_INVENTORY_END + TABCELL_INVENTORY_NUM * HERO->Get_HeroExtendedInvenCount();
			++inventoryCellIndex)
		{
			if(0 >= resultItemQuantity)
			{
				break;
			}
			else if(reservedPositionContainer.end() != reservedPositionContainer.find(inventoryCellIndex))
			{
				continue;
			}

			CItem* const item = inventoryDialog->GetItemForPos(
				inventoryCellIndex);
			const ITEM_INFO* const itemInfo = ITEMMGR->GetItemInfo(
				item ? item->GetItemIdx() : 0);

			if(0 == itemInfo)
			{
				continue;
			}
			else if(itemInfo->ItemIdx != resultItemIndex)
			{
				continue;
			}
			else if(itemInfo->Stack <= item->GetDurability())
			{
				continue;
			}
			else if(itemInfo->wSeal != item->GetItemBaseInfo().nSealed)
			{
				continue;
			}

			MSG_ITEM_DISSOLVE_SYN::Item resultItem;
			ZeroMemory(
				&resultItem,
				sizeof(resultItem));
			resultItem.mType = MSG_ITEM_DISSOLVE_SYN::Item::TypeResult;
			resultItem.mPosition = item->GetPosition();
			resultItem.mIndex = item->GetItemIdx();
			resultItem.mDbIndex = item->GetDBIdx();
			resultItem.mQuantity = min(
				itemInfo->Stack - item->GetDurability(),
				DURTYPE(resultItemQuantity));

			if(FALSE == message.Add(resultItem))
			{
				return ErrorInsufficientInventory;
			}

			resultItemQuantity -= resultItem.mQuantity;
		}
	}

	// 결과를 인벤토리 빈 칸에 채워나간다
	for(POSTYPE inventoryCellIndex = TP_INVENTORY_START;
		inventoryCellIndex < TP_INVENTORY_END + TABCELL_INVENTORY_NUM * HERO->Get_HeroExtendedInvenCount();)
	{
		if(resultContainer.empty())
		{
			break;
		}

		const ResultContainer::iterator resultIterator = resultContainer.begin();
		const ItemIndex resultItemIndex = resultIterator->first;
		ItemQuantity& resultItemQuantity = resultIterator->second;

		if(0 >= resultItemQuantity)
		{
			resultContainer.erase(
				resultIterator);
			continue;
		}

		CItem* const item = inventoryDialog->GetItemForPos(
			inventoryCellIndex);

		if(0 < item)
		{
			// 재료가 위치한 슬롯은 사용 가능하므로 검사한다
			if(reservedPositionContainer.end() == reservedPositionContainer.find(item->GetPosition()))
			{
				++inventoryCellIndex;
				continue;
			}
		}

		const ITEM_INFO* const itemInfo = ITEMMGR->GetItemInfo(
			resultItemIndex);

		if(0 == itemInfo)
		{
			++inventoryCellIndex;
			continue;
		}

		MSG_ITEM_DISSOLVE_SYN::Item resultItem;
		ZeroMemory(
			&resultItem,
			sizeof(resultItem));
		resultItem.mType = MSG_ITEM_DISSOLVE_SYN::Item::TypeResult;
		resultItem.mPosition = inventoryCellIndex;
		resultItem.mIndex = resultItemIndex;
		resultItem.mQuantity = min(
			itemInfo->Stack ? itemInfo->Stack : 1,
			resultItemQuantity);

		if(FALSE == message.Add(resultItem))
		{
			return ErrorInsufficientInventory;
		}

        resultItemQuantity -= resultItem.mQuantity;
		++inventoryCellIndex;
	}

	NETWORK->Send(
		&message,
		message.GetSize());
	return ErrorNone;
}
Ejemplo n.º 4
0
void CDissolveDialog::AddResult(const ITEMBASE& sourceItem)
{
	ResultContainer resultContainer;
	GetDissolvedResult(
		sourceItem,
		resultContainer);

	for(BYTE tabIndex = 0; tabIndex < GetTabNum(); ++tabIndex)
	{
		cIconGridDialog* const iconGridDialog = (cIconGridDialog*)GetTabSheet(
			tabIndex);

		for(WORD cellIndex = 0; iconGridDialog->GetCellNum() > cellIndex; ++cellIndex)
		{
			CItem* const item = (CItem*)iconGridDialog->GetIconForIdx(
				cellIndex);
			const ResultContainer::const_iterator iterator = resultContainer.find(
				item->GetItemIdx());

			if(resultContainer.end() != iterator)
			{
				const ItemIndex itemIndex = iterator->first;
				const ItemQuantity itemQuantity = iterator->second;

				item->SetDurability(
					item->GetDurability() + itemQuantity);

				resultContainer.erase(
					itemIndex);
			}
			else if(0 == item->GetItemIdx())
			{
				if(resultContainer.empty())
				{
					break;
				}

				const ResultContainer::const_iterator iterator = resultContainer.begin();
				const ItemIndex itemIndex = iterator->first;
				const ItemQuantity itemQuantity = iterator->second;

				cImage image;
				ITEMBASE itemBase;
				ZeroMemory(
					&itemBase,
					sizeof(itemBase));
				itemBase.wIconIdx = itemIndex;
				itemBase.Durability = itemQuantity;
				item->SetItemBaseInfo(
					itemBase);
				item->SetBasicImage(
					ITEMMGR->GetIconImage(itemBase.wIconIdx, &image));
				
				resultContainer.erase(
					itemIndex);
			}

			cPushupButton* const button = GetTabBtn(
				tabIndex);
			button->SetActive(
				TRUE);
		}
	}

	GetDissolvedRandomResult(
		sourceItem,
		resultContainer);

	for(WORD cellIndex = 0; mRandomResultDialog->GetCellNum() > cellIndex; ++cellIndex)
	{
		CItem* const item = (CItem*)mRandomResultDialog->GetIconForIdx(
			cellIndex);
		const ResultContainer::const_iterator iterator = resultContainer.find(
			item->GetItemIdx());

		if(resultContainer.end() != iterator)
		{
			const ItemIndex itemIndex = iterator->first;
			const ItemQuantity itemQuantity = iterator->second;

			item->SetDurability(
				item->GetDurability() + itemQuantity);
			
			resultContainer.erase(
				itemIndex);
		}
		else if(0 == item->GetItemIdx())
		{
			if(resultContainer.empty())
			{
				break;
			}

			const ResultContainer::const_iterator iterator = resultContainer.begin();
			const ItemIndex itemIndex = iterator->first;
			const ItemQuantity itemQuantity = iterator->second;

			cImage image;
			ITEMBASE itemBase;
			ZeroMemory(
				&itemBase,
				sizeof(itemBase));
			itemBase.wIconIdx = itemIndex;
			itemBase.Durability = itemQuantity;
			item->SetItemBaseInfo(
				itemBase);
			item->SetBasicImage(
				ITEMMGR->GetIconImage(itemBase.wIconIdx, &image));
			
			resultContainer.erase(
				itemIndex);
		}
	}

	PutTip();
}