Ejemplo n.º 1
0
BOOL CUser::RunEvent(EVENT_DATA *pEventData)
{
	EXEC* pExec = NULL;
	list<EXEC*>::iterator	Iter;

	for( Iter = pEventData->m_arExec.begin(); Iter != pEventData->m_arExec.end(); Iter++ ) 
	{
		pExec = (*Iter);
		if( !pExec ) break;

		switch(pExec->m_Exec){
			case EXEC_SAY:
				SendNpcSay( pExec );
				break;

			case	EXEC_SELECT_MSG:
				SelectMsg( pExec );
				break;

			case	EXEC_RUN_EVENT:
				{
					EVENT* pEvent = NULL;
					EVENT_DATA* pEventData = NULL;				

					pEvent = m_pMain->m_Event.GetData(m_pUserData->m_bZone);
					if(!pEvent)	break;

					pEventData = pEvent->m_arEvent.GetData(pExec->m_ExecInt[0]);
					if(!pEventData) break;

					if( !CheckEventLogic(pEventData) )	break;

					if( !RunEvent(pEventData) ){
						return FALSE;
					}
				}
				break;

			case	EXEC_GIVE_ITEM:
				if ( !GiveItem(pExec->m_ExecInt[0], pExec->m_ExecInt[1]) )
					return FALSE;
				break;

			case	EXEC_ROB_ITEM:
				if ( !RobItem(pExec->m_ExecInt[0], pExec->m_ExecInt[1]) )
					return FALSE;
				break;

			case	EXEC_GIVE_NOAH:
				GoldGain(pExec->m_ExecInt[0]);
				break;

			case	EXEC_SAVE_COM_EVENT:
				SaveComEvent(pExec->m_ExecInt[0]);
				break;

			case	EXEC_ROB_NOAH:
				GoldLose(pExec->m_ExecInt[0]);
				break;
//
			case	EXEC_RETURN:
				return FALSE;
				break;

/*
			case EXEC_SAY:		
				break;

			case EXEC_SELECT_MSG:
				SelectMsg( pExec );
				break;

			case EXEC_RUN_EVENT:
				{								
					EVENT* pEvent = NULL;
					pEvent = m_pMain->m_Quest.GetData(m_pUserData->m_bZone);
					if(!pEvent)	break;

					EVENT_DATA* pEventData = NULL;
					pEventData = pEvent->m_arEvent.GetData(pExec->m_ExecInt[0]);
					if(!pEventData) break;

					if( !CheckEventLogic(pEventData) )	break;

					if( !RunEvent(pEventData) ) {
						return FALSE;
					}
				}
				break;

			case EXEC_ROB_NOAH:
				break;

			case EXEC_GIVE_QUEST:
				break;

			case EXEC_QUEST_END:		
				break;

			case EXEC_QUEST_SAVE:
				break;

			case EXEC_RETURN:
				return FALSE;
/////// These events are for the test quest. ///////
			case EXEC_ROB_ITEM:
				if (!RobItem(pExec->m_ExecInt[0], pExec->m_ExecInt[1])) {
					return FALSE;	
				}
				break;

			case EXEC_GIVE_ITEM:
				if (!GiveItem(pExec->m_ExecInt[0], pExec->m_ExecInt[1])) {
					return FALSE;
				}
				break;
*/

			default:
				break;
		}
	}

	return TRUE;
}
void CUser::BuyingMerchantBuy(Packet & pkt)
{
    uint32 nPrice;
    uint16 sStackSize, sRemainingStackSize;
    uint8 bSellerSrcSlot, bMerchantListSlot;

    CUser *pMerchant = g_pMain->GetUserPtr(m_sMerchantsSocketID);
    if (pMerchant == nullptr)
        return;

    pkt >> bSellerSrcSlot >> bMerchantListSlot >> sStackSize;

    if (bSellerSrcSlot >= HAVE_MAX
            || bMerchantListSlot >= MAX_MERCH_ITEMS)
        return;

    _MERCH_DATA *pWantedItem = &pMerchant->m_arMerchantItems[bMerchantListSlot];
    _ITEM_DATA *pSellerItem = GetItem(SLOT_MAX + bSellerSrcSlot);

    // Make sure the merchant actually has that item in that slot
    // and that they want enough, and the selling user has enough
    if (pWantedItem->nNum != pSellerItem->nNum
            || pWantedItem->sCount < sStackSize
            || pSellerItem->sCount < sStackSize
            // For scrolls, this will ensure you can only sell a full stack of scrolls.
            // For everything else, this will ensure you cannot sell items that need repair.
            || pSellerItem->sDuration != pWantedItem->sDuration)
        return;

    // If it's not stackable, and we're specifying something other than 1
    // we really don't care to handle this request...
    _ITEM_TABLE *proto = g_pMain->GetItemPtr(pWantedItem->nNum);
    if (proto == nullptr
            || !proto->m_bCountable && sStackSize != 1)
        return;

    // Do they have enough coins?
    nPrice = pWantedItem->nPrice * sStackSize;
    if (!pMerchant->hasCoins(nPrice))
        return;

    // Now find the buyer a home for their item
    int8 bDstPos = pMerchant->FindSlotForItem(pWantedItem->nNum, sStackSize);
    if (bDstPos < 0)
        return;

    _ITEM_DATA *pMerchantItem = pMerchant->GetItem(bDstPos);

    // Take coins off the buying merchant
    if (!pMerchant->GoldLose(nPrice))
        return;

    // and give them all to me, me, me!
    GoldGain(nPrice);

    // Get the remaining stack size after purchase.
    sRemainingStackSize = pSellerItem->sCount - sStackSize;

    // Now we give the buying merchant their wares.
    pMerchantItem->nNum = pSellerItem->nNum;
    pMerchantItem->sDuration = pSellerItem->sDuration;
    pSellerItem->sCount -= sStackSize;
    pMerchantItem->sCount += sStackSize;

    // Update how many items the buyer still needs.
    pWantedItem->sCount -= sStackSize;

    // If the buyer needs no more, remove this item from the wanted list.
    if (pWantedItem->sCount == 0)
        memset(pWantedItem, 0, sizeof(_MERCH_DATA));

    // If the seller's all out, remove their item.
    if (pSellerItem->sCount == 0)
        memset(pSellerItem, 0, sizeof(_ITEM_DATA));

    // TO-DO : Proper checks for the removal of the items in the array, we're now assuming everything gets bought

    // Update players
    SendStackChange(pSellerItem->nNum, pSellerItem->sCount, pSellerItem->sDuration, bSellerSrcSlot);
    pMerchant->SendStackChange(pMerchantItem->nNum, pMerchantItem->sCount, pMerchantItem->sDuration, bDstPos - SLOT_MAX,
                               pMerchantItem->sCount == sStackSize); 	// if the buying merchant only has what they wanted, it's a new item.
    // (otherwise it was a stackable item that was merged into an existing slot)

    Packet result(WIZ_MERCHANT, uint8(MERCHANT_BUY_BOUGHT));
    result << bMerchantListSlot << uint16(0) << GetName();
    pMerchant->Send(&result);

    result.clear();
    result << uint8(MERCHANT_BUY_SOLD) << uint8(1) << bMerchantListSlot << pWantedItem->sCount << bSellerSrcSlot << pSellerItem->sCount;
    Send(&result);

    result.clear();
    result << uint8(MERCHANT_BUY_BUY) << uint8(1);
    Send(&result);

    if (bMerchantListSlot < 4 && pWantedItem->sCount == 0)
    {
        result.Initialize(WIZ_MERCHANT_INOUT);
        result << uint8(2) << m_sMerchantsSocketID << uint8(1) << uint8(0) << bMerchantListSlot;
        pMerchant->SendToRegion(&result);
    }

    int nItemsRemaining = 0;
    for (int i = 0; i < MAX_MERCH_ITEMS; i++)
    {
        if (pMerchant->m_arMerchantItems[i].nNum != 0)
            nItemsRemaining++;
    }

    if (nItemsRemaining == 0)
        pMerchant->BuyingMerchantClose();
}