示例#1
0
void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
	EoBItem *itm = &_items[_characters[charIndex].inventory[slot]];
	if (itm->type == 48 || itm->type == 62) {
		if (itm->value == 5)
			return;
		int charges = itm->flags & 0x3F;
		if (--charges)
			--itm->flags;
		else
			deleteInventoryItem(charIndex, slot);
	} else if (itm->type == 26 || itm->type == 34 || itm->type == 35) {
		deleteInventoryItem(charIndex, slot);
	}
}
void CGAddMouseToInventoryHandler::execute(CGAddMouseToInventory* pPacket , Player* pPlayer)
	throw(ProtocolException, Error)
{
	__BEGIN_TRY __BEGIN_DEBUG_EX

#ifdef __GAME_SERVER__

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

	try {
		GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);
		Assert(pGamePlayer != NULL);

		Creature* pCreature = pGamePlayer->getCreature();
		Assert(pCreature != NULL);
		Assert(pCreature->isPC());

		PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature);
		Assert(pPC != NULL);

		Zone* pZone = pPC->getZone();
		Assert(pZone != NULL);

		Inventory* pInventory = pPC->getInventory();
		Assert(pInventory != NULL);

		Item* pItem   = pPC->getExtraInventorySlot()->getItem();
		bool  Success = false;

		if (pItem == NULL) {
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}
        int invenID = 0;
/* Commenting the SubInventory stuff, since it's not supported by the client we use
		SubInventory* pInventoryItem = NULL;
		int invenID = 0;

		if (pPacket->getInventoryItemObjectID() != 0 )
		{
//			cout << "서브 인벤토리에 넣기 : " << pPacket->getInventoryItemObjectID() << endl;
			CoordInven_t X, Y;
			pInventoryItem = dynamic_cast<SubInventory*>(pInventory->findItemOID(pPacket->getInventoryItemObjectID(), X, Y ));

			TradeManager* pTradeManager = pZone->getTradeManager();
			Assert(pTradeManager != NULL);

			if (pInventoryItem == NULL || pItem->getItemClass() == Item::ITEM_CLASS_SUB_INVENTORY || pTradeManager->hasTradeInfo(pPC->getName()) )
			{
//				cout << "근데 서브 인벤토리가 없다." <<endl;
				GCCannotAdd _GCCannotAdd;
				_GCCannotAdd.setObjectID(pPacket->getObjectID());
				pPlayer->sendPacket(&_GCCannotAdd);
				return;
			}

			pInventory = pInventoryItem->getInventory();
			invenID = pInventoryItem->getItemID();
		}
*/
		//Item::ItemClass itemClass = pItem->getItemClass();
		//ItemType_t	itemType	 = pItem->getItemType();
		ObjectID_t  itemObjectID = pItem->getObjectID();
		CoordInven_t InvenX      = pPacket->getInvenX();
		CoordInven_t InvenY      = pPacket->getInvenY();

		if (InvenX >= pInventory->getWidth() || InvenY >= pInventory->getHeight() || itemObjectID != pPacket->getObjectID() ||
			!pInventory->canAdding(InvenX, InvenY, pItem)) {
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
			return;
		}

		TPOINT pt;
		pt.x = 99;
		pt.y = 99;

		// 넣을려는 Inventory Slot의 Item을 받아온다.
		Item* pPrevItem = pInventory->searchItem(InvenX, InvenY , pItem, pt);

		// 그 장소에 아이템이 있다면
		if (pPrevItem != NULL) {
			bool bisSame = true;
			// 아이템 클래스가 같을때 숫자를 올려 주고 마우스에 있는 것은 없앤다.
			if (canStack(pItem, pPrevItem)) {
				int MaxStack = ItemMaxStack[pItem->getItemClass()];

				VolumeWidth_t  ItemWidth  = pItem->getVolumeWidth();
				VolumeHeight_t ItemHeight = pItem->getVolumeHeight();
				VolumeWidth_t  InvenWidth = pInventory->getWidth();
				VolumeWidth_t  InvenHeight= pInventory->getHeight();


				if ((InvenX + ItemWidth <= InvenWidth) && (InvenY + ItemHeight <= InvenHeight)) {
					for (int x = InvenX; x < (InvenX + ItemWidth); x++) {
						for (int y = InvenY; y < (InvenY + ItemHeight); y++) {
							if (pInventory->hasItem(x, y)) {
								if(pInventory->getItem(x,y) != pPrevItem ) {
									bisSame = false;
									break;
								}
							} else {
								bisSame = false;
								break;
							}
						}
					}
				}

				// 들어갈 아이템과 들어있는 아이템의 좌표가 꼭 일치 한다면?
				if(bisSame) {
					// 숫자가 9개를 넘으면 9개 될때까지만 Add 하고 나머지는 마우스에 달아둔다.
					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);
						pInventory->increaseNum(MaxStack - CurrentNum);
						pInventory->increaseWeight(pItem->getWeight()* (MaxStack - CurrentNum));
						//pPrevItem->save(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY);
						// item저장 최적화. by sigi. 2002.5.13
						char pField[80];
						sprintf(pField, "Num=%d, Storage=%d, StorageID=%d, X=%d, Y=%d", MaxStack, STORAGE_INVENTORY, invenID, InvenX, InvenY);
						pPrevItem->tinysave(pField);

						//pItem->save(pPC->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 {
						pPC->deleteItemFromExtraInventorySlot();
						pPrevItem->setNum(pPrevItem->getNum() + pItem->getNum());
						pInventory->increaseNum(pItem->getNum());
						pInventory->increaseWeight(pItem->getWeight()* pItem->getNum());
						//pPrevItem->save(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY);
						// item저장 최적화. by sigi. 2002.5.13
						char pField[80];
						sprintf(pField, "Num=%d, Storage=%d, StorageID=%u, X=%d, Y=%d", pPrevItem->getNum(), STORAGE_INVENTORY, invenID, InvenX, InvenY);
						pPrevItem->tinysave(pField);

						pItem->destroy();
						SAFE_DELETE(pItem);
						Success = true;
					}

					if (g_pVariableManager->getVariable(NETMARBLE_CARD_EVENT) != 0 && pPrevItem->getItemClass() == Item::ITEM_CLASS_MOON_CARD && pPrevItem->getItemType() == 2 && pPrevItem->getNum() == 99) {
						GCNoticeEvent gcNE;
						gcNE.setCode(NOTICE_EVENT_NETMARBLE_CARD_FULL);
						pGamePlayer->sendPacket(&gcNE);
						//cout << "gcNE sent" << endl;
					}

					if (pPrevItem->getItemClass() == Item::ITEM_CLASS_LUCKY_BAG
						&& pPrevItem->getItemType() == 3
						&& pPrevItem->getNum() == 50 ) {
						GCDeleteInventoryItem gcDI;
						gcDI.setObjectID(pPrevItem->getObjectID());
						pGamePlayer->sendPacket(&gcDI);

						pInventory->deleteItem(pPrevItem->getObjectID());
						pPrevItem->destroy();
						SAFE_DELETE(pPrevItem);
						
						Item* pNewItem = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_EVENT_ITEM, 28, list<OptionType_t>());
						pZone->registerObject(pNewItem);

						if (!pInventory->addItem(pt.x, pt.y, pNewItem) )
							return;

						pNewItem->create(pPC->getName(), STORAGE_INVENTORY, 0, pt.x, pt.y);

						if (pNewItem != NULL ) {
							GCCreateItem gcCI;
							makeGCCreateItem(&gcCI, pNewItem, pt.x, pt.y);
							pGamePlayer->sendPacket(&gcCI);
						}
					}

				} else {

					pInventory->deleteItem(pPrevItem->getObjectID());

					pPC->deleteItemFromExtraInventorySlot();

					pPC->addItemToExtraInventorySlot(pPrevItem);

					pInventory->addItem(InvenX , InvenY , pItem);

					//pPrevItem->save(pPC->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(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY);
					// item저장 최적화. by sigi. 2002.5.13
					sprintf(pField, "Storage=%d, StorageID=%u, X=%d, Y=%d", STORAGE_INVENTORY, invenID, InvenX, InvenY);
					pItem->tinysave(pField);


					Success = true;
				}
			} 
			else {// 아이템 클래스가 다르거나, 쌓이는 아이템이 아니라면.
				pInventory->deleteItem(pPrevItem->getObjectID());

				pPC->deleteItemFromExtraInventorySlot();

				pPC->addItemToExtraInventorySlot(pPrevItem);

				pInventory->addItem(InvenX , InvenY , pItem);

				//pPrevItem->save(pPC->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(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY);
				// item저장 최적화. by sigi. 2002.5.13
				sprintf(pField, "Storage=%d, StorageID=%u, X=%d, Y=%d", STORAGE_INVENTORY, invenID, InvenX, InvenY);
				pItem->tinysave(pField);


				Success = true;
			}
		} else { // 그 장소에 아이템이 없다면.
			//cout << "prevItem is NULL" << endl;

			// Inventory에 특정 아이템을 넣는다.
			pInventory->addItem(InvenX , InvenY , pItem);

			// 넣기에 성공하면 마우스에 달려있는 아이템을 없앤다.
			pPC->deleteItemFromExtraInventorySlot();

			//pItem->save(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY);
			// item저장 최적화. by sigi. 2002.5.13
			char pField[80];
			sprintf(pField, "Storage=%d, StorageID=%u, X=%d, Y=%d", STORAGE_INVENTORY, invenID, InvenX, InvenY);
			pItem->tinysave(pField);


			Success = true;
		}

		if (Success) {
			TradeManager* pTradeManager = pZone->getTradeManager();
			TradeInfo* pInfo = pTradeManager->getTradeInfo(pCreature->getName());
			if (pInfo != NULL && pInfo->getStatus() == TRADE_FINISH) {
				GCTradeVerify gcTradeVerify;
				gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_MOUSE_TO_INVENTORY_OK);
				pPlayer->sendPacket(&gcTradeVerify);
			}

			// 트리 조각일 경우
			if (pItem != NULL && pItem->getItemClass() == Item::ITEM_CLASS_EVENT_TREE) {
				ItemType_t itemtype = pItem->getItemType();

				// 크리스마스 트리 조각이면
				if (itemtype <= 11) {
					// 크리스마스 트리 조각이 맞춰지는지 본다.
					TPOINT pt = checkEventPuzzle(pPC, InvenX, InvenY, 0);
					if (pt.x != -1 && pt.y != -1 )
					{
						// 맞춰진 트리 조각을 지운다.
						deleteInventoryItem(pInventory, pt.x, pt.y, pt.x + 2, pt.y + 3);

						// 트리를 생성한다.
						list<OptionType_t> optionType;
						Item* pTreeItem = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_EVENT_TREE, 12, optionType);
						pZone->getObjectRegistry().registerObject(pTreeItem);
						pInventory->addItem(pt.x, pt.y, pTreeItem);
						pTreeItem->create(pPC->getName(), STORAGE_INVENTORY, invenID, pt.x, pt.y);

						// 클라이언트에 트리가 만들어졌다는 걸 알린다.
						GCCreateItem gcCreateItem;
						makeGCCreateItem(&gcCreateItem, pTreeItem, pt.x, pt.y);
						pGamePlayer->sendPacket(&gcCreateItem);
					}
				}
				// 크리스마스 트리 조각이면
				else if (itemtype > 12 && itemtype <= 24) {
					// 크리스마스 트리 조각이 맞춰지는지 본다.
					TPOINT pt = checkEventPuzzle(pPC, InvenX, InvenY, 13);
					if (pt.x != -1 && pt.y != -1) {
						// 맞춰진 트리 조각을 지운다.
						deleteInventoryItem(pInventory, pt.x, pt.y, pt.x + 2, pt.y + 3);

						// 트리를 생성한다.
						list<OptionType_t> optionType;
						Item* pTreeItem = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_EVENT_TREE, 25, optionType);
						pTreeItem->setQuestItem();
						pZone->getObjectRegistry().registerObject(pTreeItem);
						pInventory->addItem(pt.x, pt.y, pTreeItem);
						pTreeItem->create(pPC->getName(), STORAGE_INVENTORY, invenID, pt.x, pt.y);

						// 클라이언트에 트리가 만들어졌다는 걸 알린다.
						GCCreateItem gcCreateItem;
						makeGCCreateItem(&gcCreateItem, pTreeItem, pt.x, pt.y);
						pGamePlayer->sendPacket(&gcCreateItem);
					}
				}
				// 크리스마스 트리 조각이면
				else if (itemtype > 28 && itemtype <= 40) {
					// 크리스마스 트리 조각이 맞춰지는지 본다.
					TPOINT pt = checkEventPuzzle(pPC, InvenX, InvenY, 29);
					if (pt.x != -1 && pt.y != -1) {
						// 맞춰진 트리 조각을 지운다.
						deleteInventoryItem(pInventory, pt.x, pt.y, pt.x + 2, pt.y + 3);

						// 트리를 생성한다.
						list<OptionType_t> optionType;
						Item* pTreeItem = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_EVENT_TREE, 41, optionType);
						pTreeItem->setQuestItem();
						pZone->getObjectRegistry().registerObject(pTreeItem);
						pInventory->addItem(pt.x, pt.y, pTreeItem);
						pTreeItem->create(pPC->getName(), STORAGE_INVENTORY, invenID, pt.x, pt.y);

						// 클라이언트에 트리가 만들어졌다는 걸 알린다.
						GCCreateItem gcCreateItem;
						makeGCCreateItem(&gcCreateItem, pTreeItem, pt.x, pt.y);
						pGamePlayer->sendPacket(&gcCreateItem);
					}
				}
			}
		} else {
			//cout << "cannot add" << endl;
			GCCannotAdd _GCCannotAdd;
			_GCCannotAdd.setObjectID(pPacket->getObjectID());
			pPlayer->sendPacket(&_GCCannotAdd);
		}
	} catch (Throwable & t) {}

#endif	// __GAME_SERVER__

    __END_DEBUG_EX __END_CATCH

}
示例#3
0
文件: magic_eob.cpp 项目: 33d/scummvm
void EoBCoreEngine::usePotion(int charIndex, int weaponSlot) {
	EoBCharacter *c = &_characters[charIndex];

	int val = deleteInventoryItem(charIndex, weaponSlot);
	snd_playSoundEffect(10);

	if (_flags.gameID == GI_EOB1)
		val--;

	switch (val) {
	case 0:
		sparkEffectDefensive(charIndex);
		c->strengthCur = 22;
		c->strengthExtCur = 0;
		setCharEventTimer(charIndex, 546 * rollDice(1, 4, 4), 7, 1);
		break;

	case 1:
		sparkEffectDefensive(charIndex);
		modifyCharacterHitpoints(charIndex, rollDice(2, 4, 2));
		break;

	case 2:
		sparkEffectDefensive(charIndex);
		modifyCharacterHitpoints(charIndex, rollDice(3, 8, 3));
		break;

	case 3:
		statusAttack(charIndex, 2, _potionStrings[0], 0, 1, 8, 1);
		c->effectFlags &= ~0x2000;
		if (c->flags & 2)
			return;
		break;

	case 4:
		sparkEffectDefensive(charIndex);
		c->food = 100;
		if (_currentControlMode)
			gui_drawCharPortraitWithStats(charIndex);
		break;

	case 5:
		sparkEffectDefensive(charIndex);
		c->effectFlags |= 0x10000;
		setCharEventTimer(charIndex, 546 * rollDice(1, 4, 4), 12, 1);
		snd_playSoundEffect(100);
		gui_drawCharPortraitWithStats(charIndex);
		break;

	case 6:
		sparkEffectDefensive(charIndex);
		c->effectFlags |= 0x40;
		gui_drawCharPortraitWithStats(charIndex);
		break;

	case 7:
		sparkEffectDefensive(charIndex);
		neutralizePoison(charIndex);
		break;

	default:
		break;
	}

	_txt->printMessage(_potionStrings[1], -1, c->name, _potionEffectStrings[val]);
}