//o---------------------------------------------------------------------------o //| Function : void buyItem(CSocket *mSock) //| Date : Unknown //| Programmer : UOX3 DevTeam //o---------------------------------------------------------------------------o //| Purpose : Called when player buys an item from a vendor //o---------------------------------------------------------------------------o bool CPIBuyItem::Handle(void) { UI16 i; UI32 playergoldtotal, goldtotal = 0; bool soldout = false, clear = false; CChar *mChar = tSock->CurrcharObj(); CItem *p = mChar->GetPackItem(); if (!ValidateObject(p)) return true; ITEMLIST bitems; std::vector<UI08> layer; std::vector<UI16> amount; // vector for storing all objects that actually end up in user backpack std::vector< CItem * > boughtItems; CChar *npc = calcCharObjFromSer(tSock->GetDWord(3)); UI16 itemtotal = static_cast<UI16>((tSock->GetWord(1) - 8) / 7); if (itemtotal > 511) return true; boughtItems.reserve(itemtotal); bitems.resize(itemtotal); amount.resize(itemtotal); layer.resize(itemtotal); int baseOffset = 0; for (i = 0; i < itemtotal; ++i) { baseOffset = 7 * i; layer[i] = tSock->GetByte(8 + baseOffset); bitems[i] = calcItemObjFromSer(tSock->GetDWord(9 + baseOffset)); amount[i] = tSock->GetWord(13 + baseOffset); goldtotal += (amount[i] * (bitems[i]->GetBuyValue())); } bool useBank = (goldtotal >= static_cast<UI32>(cwmWorldState->ServerData()->BuyThreshold())); if (useBank) playergoldtotal = GetBankCount(mChar, 0x0EED); else playergoldtotal = GetItemAmount(mChar, 0x0EED); if (playergoldtotal >= goldtotal || mChar->IsGM()) { for (i = 0; i < itemtotal; ++i) { if (bitems[i]->GetAmount() < amount[i]) soldout = true; // Check if onBuyFromVendor JS event is present for each item being purchased // If true, and a return false has been returned from the script, halt the purchase UI16 targTrig = bitems[i]->GetScriptTrigger(); cScript *toExecute = JSMapping->GetScript(targTrig); if (toExecute != NULL) if (toExecute->OnBuyFromVendor(tSock, npc, bitems[i])) { bitems.clear(); //needed??? return true; } } if (soldout) { npc->TextMessage(tSock, 1336, TALK, false); clear = true; } else { if (mChar->IsGM()) npc->TextMessage(NULL, 1337, TALK, false, mChar->GetName().c_str()); else { if (goldtotal == 1) npc->TextMessage(NULL, 1338, TALK, false, mChar->GetName().c_str(), goldtotal); else npc->TextMessage(NULL, 1339, TALK, false, mChar->GetName().c_str(), goldtotal); Effects->goldSound(tSock, goldtotal); } clear = true; if (!mChar->IsGM()) if (useBank) DeleteBankItem(mChar, goldtotal, 0x0EED); else DeleteItemAmount(mChar, goldtotal, 0x0EED); CItem *biTemp; CItem *iMade = NULL; UI16 j; for (i = 0; i < itemtotal; ++i) { biTemp = bitems[i]; iMade = NULL; if (biTemp->GetAmount() > amount[i]) { if (biTemp->isPileable()) { iMade = Items->DupeItem(tSock, biTemp, amount[i]); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } else { for (j = 0; j < amount[i]; ++j) { iMade = Items->DupeItem(tSock, biTemp, 1); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } } biTemp->IncAmount(-amount[i], true); biTemp->SetRestock(biTemp->GetRestock() + amount[i]); } else { switch(layer[i]) { case 0x1A: // Sell Container if (biTemp->isPileable()) { iMade = Items->DupeItem(tSock, biTemp, amount[i]); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } else { for (j = 0; j < amount[i]; ++j) { iMade = Items->DupeItem(tSock, biTemp, 1); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } } biTemp->IncAmount(-amount[i], true); biTemp->SetRestock(biTemp->GetRestock() + amount[i]); break; case 0x1B: // Bought Container if (biTemp->isPileable()) { biTemp->SetCont(p); boughtItems.push_back(biTemp); } else { for (j = 0; j < amount[i]-1; ++j) { iMade = Items->DupeItem(tSock, biTemp, 1); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } biTemp->SetCont(p); biTemp->SetAmount(1); boughtItems.push_back(biTemp); } break; default: Console.Error(" Fallout of switch statement without default. vendor.cpp, buyItem()"); break; } } } for (i = 0; i < boughtItems.size(); ++i) { if (boughtItems[i]) { cScript *toGrab = JSMapping->GetScript(boughtItems[i]->GetScriptTrigger()); if (toGrab != NULL) toGrab->OnBoughtFromVendor(tSock, npc, boughtItems[i]); } } } } else npc->TextMessage(NULL, 1340, TALK, false); if (clear) { CPBuyItem clrSend; clrSend.Serial(tSock->GetDWord(3)); tSock->Send(&clrSend); } return true; }
void CItem::Spawn_GenerateItem( CResourceDef * pDef ) { // Count how many items are here already. // This could be in a container. RESOURCE_ID_BASE rid = pDef->GetResourceID(); ITEMID_TYPE id = (ITEMID_TYPE) rid.GetResIndex(); int iDistMax = m_itSpawnItem.m_DistMax; int iAmountPile = m_itSpawnItem.m_pile; int iCount = 0; CItemContainer * pCont = dynamic_cast <CItemContainer *>( GetParent()); if ( pCont != NULL ) { iCount = pCont->ContentCount( rid ); } else { // If is equipped this will produce the item where you are standing. CPointMap pt = GetTopLevelObj()->GetTopPoint(); CWorldSearch AreaItems( pt, iDistMax ); while (true) { CItem * pItem = AreaItems.GetItem(); if ( pItem == NULL ) break; if ( pItem->IsType(IT_SPAWN_ITEM)) continue; if ( pItem->IsAttr( ATTR_INVIS )) continue; if ( pItem->GetID() != id ) continue; // if ( pItem->m_uidLink != GetUID()) continue; iCount += pItem->GetAmount(); } } if ( iCount >= GetAmount()) return; CItem * pItem = CreateTemplate( id ); if ( pItem == NULL ) return; pItem->SetAttr( m_Attr & ( ATTR_OWNED | ATTR_MOVE_ALWAYS )); if ( iAmountPile > 1 ) { CItemBase * pItemDef = pItem->Item_GetDef(); ASSERT(pItemDef); if ( pItemDef->IsStackableType()) { if ( iAmountPile == 0 || iAmountPile > GetAmount()) iAmountPile = GetAmount(); pItem->SetAmount( Calc_GetRandVal(iAmountPile) + 1 ); } } // pItem->m_uidLink = GetUID(); // This might be dangerous ? pItem->SetDecayTime( g_Cfg.m_iDecay_Item ); // It will decay eventually to be replaced later. pItem->MoveNearObj( this, iDistMax ); }
//o---------------------------------------------------------------------------o //| Function : void sellItem(CSocket *mSock) //| Date : Unknown //| Programmer : UOX3 DevTeam //o---------------------------------------------------------------------------o //| Purpose : Player sells an item to the vendor //o---------------------------------------------------------------------------o bool CPISellItem::Handle(void) { if (tSock->GetByte(8) != 0) { CChar *mChar = tSock->CurrcharObj(); CChar *n = calcCharObjFromSer(tSock->GetDWord(3)); if (!ValidateObject(n) || !ValidateObject(mChar)) return true; CItem *buyPack = n->GetItemAtLayer(IL_BUYCONTAINER); CItem *boughtPack = n->GetItemAtLayer(IL_BOUGHTCONTAINER); CItem *sellPack = n->GetItemAtLayer(IL_SELLCONTAINER); if (!ValidateObject(buyPack) || !ValidateObject(sellPack) || !ValidateObject(boughtPack)) return true; CItem *j = NULL, *k = NULL, *l = NULL; UI16 amt = 0, maxsell = 0; UI08 i = 0; UI32 totgold = 0, value = 0; for (i = 0; i < tSock->GetByte(8); ++i) { j = calcItemObjFromSer(tSock->GetDWord(9 + (6*i))); amt = tSock->GetWord(13 + (6*i)); maxsell += amt; } if (maxsell > cwmWorldState->ServerData()->SellMaxItemsStatus()) { n->TextMessage(NULL, 1342, TALK, false, mChar->GetName().c_str(), cwmWorldState->ServerData()->SellMaxItemsStatus()); return true; } for (i = 0; i < tSock->GetByte(8); ++i) { j = calcItemObjFromSer(tSock->GetDWord(9 + (6*i))); amt = tSock->GetWord(13 + (6*i)); if (ValidateObject(j)) { if (j->GetAmount() < amt || FindItemOwner(j) != mChar) { n->TextMessage(NULL, 1343, TALK, false); return true; } // Check if onSellToVendor JS event is present for each item being sold // If true, and a value of "false" has been returned from the script, halt the sale UI16 targTrig = j->GetScriptTrigger(); cScript *toExecute = JSMapping->GetScript(targTrig); if (toExecute != NULL) if (toExecute->OnSellToVendor(tSock, n, j)) return true; CItem *join = NULL; CDataList<CItem *> *pCont = boughtPack->GetContainsList(); for (k = pCont->First(); !pCont->Finished(); k = pCont->Next()) if (ValidateObject(k)) if (k->GetID() == j->GetID() && j->GetType() == k->GetType()) join = k; pCont = buyPack->GetContainsList(); for (k = pCont->First(); !pCont->Finished(); k = pCont->Next()) if (ValidateObject(k)) if (k->GetID() == j->GetID() && j->GetType() == k->GetType()) value = calcValue(j, k->GetSellValue()); // If an object already exist in the boughtPack that this one can be joined to... if (ValidateObject(join)) { join->IncAmount(amt); join->SetRestock(join->GetRestock() - amt); l = join; totgold += (amt * value); if (j->GetAmount() == amt) j->Delete(); else j->IncAmount(-amt); } else { //Otherwise, move this item to the vendor's boughtPack totgold += (amt * value); if (j->GetAmount() != amt) { l = Items->DupeItem(tSock, j, amt); j->SetAmount(j->GetAmount() - amt); } else l = j; if (ValidateObject(l)) l->SetCont(boughtPack); } if (l) { cScript *toGrab = JSMapping->GetScript(l->GetScriptTrigger()); if (toGrab != NULL) toGrab->OnSoldToVendor(tSock, n, l); } } } Effects->goldSound(tSock, totgold); while (totgold > MAX_STACK) { Items->CreateScriptItem(tSock, mChar, "0x0EED", MAX_STACK, OT_ITEM, true); totgold -= MAX_STACK; } if (totgold > 0) Items->CreateScriptItem(tSock, mChar, "0x0EED", totgold, OT_ITEM, true); } CPBuyItem clrSend; clrSend.Serial(tSock->GetDWord(3)); tSock->Send(&clrSend); return true; }