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(); }