mirror of
https://github.com/UOX3DevTeam/UOX3
synced 2026-08-13 12:27:04 -04:00
Fixed an issue with onDyeTarget event where the dyetub and target object parameters were not set properly Fixed some incorrect casting animation-related variable assignments for AI_HEALER and AI_EVIL_HEALER Fixed an issue with pets not going wild from lack of loyalty to their owners when at zero loyalty Addressed issues with idle/fidget animation setup that could cause NPCs to blink out of existence Removed stray semicolon behind control statement related to triggering of OnFacetChange JS event Fixed an issue with Bless spell when cast from item Some minor code cleanup
621 lines
17 KiB
C++
621 lines
17 KiB
C++
#include "uox3.h"
|
|
#include "commands.h"
|
|
#include "cEffects.h"
|
|
#include "CPacketSend.h"
|
|
#include "classes.h"
|
|
#include "townregion.h"
|
|
#include "CJSMapping.h"
|
|
#include "cScript.h"
|
|
|
|
#include "cServerDefinitions.h"
|
|
|
|
#include "ObjectFactory.h"
|
|
#include <algorithm>
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
//| Function - CalcValue()
|
|
//o------------------------------------------------------------------------------------------------o
|
|
//| Purpose - Calculate the value of an item
|
|
//o------------------------------------------------------------------------------------------------o
|
|
UI32 CalcValue( CItem *i, UI32 value )
|
|
{
|
|
if( i->GetType() == IT_POTION )
|
|
{
|
|
UI32 mod = 10;
|
|
if( i->GetTempVar( CITV_MOREX ) > 500 )
|
|
{
|
|
++mod;
|
|
}
|
|
if( i->GetTempVar( CITV_MOREX ) > 900 )
|
|
{
|
|
++mod;
|
|
}
|
|
if( i->GetTempVar( CITV_MOREX ) > 1000 )
|
|
{
|
|
++mod;
|
|
}
|
|
if( i->GetTempVar( CITV_MOREZ ) > 1 )
|
|
{
|
|
mod += ( 3 * ( i->GetTempVar( CITV_MOREZ ) - 1 ));
|
|
}
|
|
value = ( value * mod ) / 10;
|
|
}
|
|
|
|
if( i->GetRank() > 0 && i->GetRank() < 10 && cwmWorldState->ServerData()->RankSystemStatus() )
|
|
{
|
|
value = static_cast<UI32>( i->GetRank() * value ) / 10;
|
|
}
|
|
if( value < 1 )
|
|
{
|
|
value = 1;
|
|
}
|
|
|
|
if( !i->GetRndValueRate() )
|
|
{
|
|
i->SetRndValueRate( 0 );
|
|
}
|
|
if( i->GetRndValueRate() != 0 && cwmWorldState->ServerData()->TradeSystemStatus() )
|
|
{
|
|
value += static_cast<UI32>( value * i->GetRndValueRate() ) / 1000;
|
|
}
|
|
if( value < 1 )
|
|
{
|
|
value = 1;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
//| Function - CalcGoodValue()
|
|
//o------------------------------------------------------------------------------------------------o
|
|
//| Purpose - Calculate the value of a good
|
|
//o------------------------------------------------------------------------------------------------o
|
|
UI32 CalcGoodValue( CTownRegion *tReg, CItem *i, UI32 value, bool isSelling )
|
|
{
|
|
if( tReg == nullptr )
|
|
return value;
|
|
|
|
SI16 good = i->GetGood();
|
|
SI32 regvalue = 0;
|
|
|
|
if( good <= -1 )
|
|
{
|
|
return value;
|
|
}
|
|
|
|
if( isSelling )
|
|
{
|
|
regvalue = tReg->GetGoodSell( static_cast<UI08>( i->GetGood() ));
|
|
}
|
|
else
|
|
{
|
|
regvalue = tReg->GetGoodBuy( static_cast<UI08>( i->GetGood() ));
|
|
}
|
|
|
|
UI32 x = static_cast<UI32>( value * abs( regvalue )) / 1000;
|
|
|
|
if( regvalue < 0 )
|
|
{
|
|
value -= x;
|
|
}
|
|
else
|
|
{
|
|
value += x;
|
|
}
|
|
|
|
if( value < 1 )
|
|
{
|
|
value = 1;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
bool ApplyItemSection( CItem *applyTo, CScriptSection *toApply, std::string sectionId );
|
|
//o------------------------------------------------------------------------------------------------o
|
|
//| Function - CPIBuyItem::Handle()
|
|
//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;
|
|
|
|
std::vector<CItem*> 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 );
|
|
SI32 baseOffset = 0;
|
|
for( i = 0; i < itemTotal; ++i )
|
|
{
|
|
baseOffset = 7 * i;
|
|
layer[i] = tSock->GetByte( 8 + static_cast<size_t>( baseOffset ));
|
|
bItems[i] = CalcItemObjFromSer( tSock->GetDWord( 9 + static_cast<size_t>( baseOffset )));
|
|
amount[i] = tSock->GetWord( 13 + static_cast<size_t>( 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 return false or 0 has been returned from the script, halt the purchase
|
|
std::vector<UI16> scriptTriggers = bItems[i]->GetScriptTriggers();
|
|
for( auto scriptTrig : scriptTriggers )
|
|
{
|
|
cScript *toExecute = JSMapping->GetScript( scriptTrig );
|
|
if( toExecute != nullptr )
|
|
{
|
|
if( toExecute->OnBuyFromVendor( tSock, npc, bItems[i] ) == 0 )
|
|
{
|
|
bItems.clear();
|
|
bItems.shrink_to_fit();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if( soldout )
|
|
{
|
|
npc->TextMessage( tSock, 1336, TALK, false ); // Alas, I no longer have all those goods in stock. Let me know if there is something else thou wouldst buy.
|
|
clear = true;
|
|
}
|
|
else
|
|
{
|
|
if( mChar->IsGM() )
|
|
{
|
|
npc->TextMessage( nullptr, 1337, TALK, 0, mChar->GetName().c_str() ); // Here you are, %s. Someone as special as thee will receive my wares for free of course.
|
|
}
|
|
else
|
|
{
|
|
if( goldTotal == 1 )
|
|
{
|
|
npc->TextMessage( nullptr, 1338, TALK, 0, mChar->GetName().c_str(), goldTotal ); // Here you are, %s. That will be %d gold coin. I thank thee for thy business.
|
|
}
|
|
else
|
|
{
|
|
npc->TextMessage( nullptr, 1339, TALK, 0, mChar->GetName().c_str(), goldTotal ); // Here you are, %s. That will be %d gold coins. I thank thee for thy business.
|
|
}
|
|
|
|
Effects->GoldSound( tSock, goldTotal );
|
|
}
|
|
|
|
clear = true;
|
|
if( !mChar->IsGM() )
|
|
{
|
|
if( useBank )
|
|
{
|
|
// Remove total amount of gold spent, from player's bankbox
|
|
DeleteBankItem( mChar, goldTotal, 0x0EED );
|
|
}
|
|
else
|
|
{
|
|
// Remove total amount of gold spent, from player's backpack
|
|
DeleteItemAmount( mChar, goldTotal, 0x0EED );
|
|
}
|
|
}
|
|
CItem *biTemp;
|
|
CItem *iMade = nullptr;
|
|
UI16 j;
|
|
for( i = 0; i < itemTotal; ++i )
|
|
{
|
|
biTemp = bItems[i];
|
|
iMade = nullptr;
|
|
if( biTemp->GetAmount() > amount[i] )
|
|
{
|
|
if( biTemp->IsPileable() )
|
|
{
|
|
iMade = Items->DupeItem( tSock, biTemp, amount[i] );
|
|
if( iMade != nullptr )
|
|
{
|
|
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 != nullptr )
|
|
{
|
|
CItem * biTempCont = static_cast<CItem *>( biTemp->GetCont() );
|
|
if( biTempCont->GetLayer() == 0x1A )
|
|
{
|
|
// Only do this for new items sold from vendor's sell container
|
|
SI16 iMadeHP = iMade->GetHP();
|
|
SI16 iMadeMaxHP = static_cast<SI16>( iMade->GetMaxHP() );
|
|
if( iMadeMaxHP > iMadeHP )
|
|
{
|
|
// Randomize the item's HP from HP to MaxHP
|
|
iMade->SetHP( static_cast<SI16>( RandomNum( iMadeHP, iMadeMaxHP )));
|
|
}
|
|
}
|
|
iMade->SetCont( p );
|
|
iMade->PlaceInPack();
|
|
boughtItems.push_back( iMade );
|
|
}
|
|
}
|
|
}
|
|
biTemp->IncAmount( -amount[i], true );
|
|
biTemp->SetRestock( biTemp->GetRestock() + amount[i] );
|
|
}
|
|
else
|
|
{
|
|
CItem * biTempCont = static_cast<CItem *>( biTemp->GetCont() );
|
|
switch( biTempCont->GetLayer() )
|
|
{
|
|
case 0x1A: // Sell Container
|
|
if( biTemp->IsPileable() )
|
|
{
|
|
iMade = Items->DupeItem( tSock, biTemp, amount[i] );
|
|
if( iMade != nullptr )
|
|
{
|
|
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 != nullptr )
|
|
{
|
|
SI16 iMadeHP = iMade->GetHP();
|
|
SI16 iMadeMaxHP = static_cast<SI16>( iMade->GetMaxHP() );
|
|
if( iMadeMaxHP > iMadeHP )
|
|
{
|
|
// Randomize the item's HP from HP to MaxHP
|
|
iMade->SetHP( static_cast<SI16>( RandomNum( iMadeHP, iMadeMaxHP )));
|
|
}
|
|
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 != nullptr )
|
|
{
|
|
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] )
|
|
{
|
|
std::vector<UI16> scriptTriggers = boughtItems[i]->GetScriptTriggers();
|
|
for( auto scriptTrig : scriptTriggers )
|
|
{
|
|
cScript *toExecute = JSMapping->GetScript( scriptTrig );
|
|
if( toExecute != nullptr )
|
|
{
|
|
// If script returns 1, prevent other scripts with event from running
|
|
if( toExecute->OnBoughtFromVendor( tSock, npc, boughtItems[i] ) == 1 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
npc->TextMessage( nullptr, 1340, TALK, false ); // Alas, thou dost not possess sufficient gold for this purchase!
|
|
}
|
|
|
|
if( clear )
|
|
{
|
|
CPBuyItem clrSend;
|
|
clrSend.Serial( tSock->GetDWord( 3 ));
|
|
tSock->Send( &clrSend );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
//| Function - CPISellItem::Handle()
|
|
//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 = nullptr, *k = nullptr, *l = nullptr;
|
|
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 * static_cast<size_t>( i ))));
|
|
amt = tSock->GetWord( 13 + ( 6 * static_cast<size_t>( i )));
|
|
maxsell += amt;
|
|
}
|
|
|
|
if( maxsell > cwmWorldState->ServerData()->SellMaxItemsStatus() )
|
|
{
|
|
n->TextMessage( nullptr, 1342, TALK, 0, mChar->GetName().c_str(), cwmWorldState->ServerData()->SellMaxItemsStatus() ); // Sorry %s, but I can only buy %i items at a time!
|
|
return true;
|
|
}
|
|
|
|
// Loop through each item being sold
|
|
for( i = 0; i < tSock->GetByte( 8 ); ++i )
|
|
{
|
|
j = CalcItemObjFromSer( tSock->GetDWord( 9 + ( 6 * static_cast<size_t>( i ))));
|
|
amt = tSock->GetWord( 13 + ( 6 * static_cast<size_t>( i )));
|
|
if( ValidateObject( j ))
|
|
{
|
|
if( j->GetAmount() < amt || FindItemOwner( j ) != mChar )
|
|
{
|
|
n->TextMessage( nullptr, 1343, TALK, false ); // Cheating scum! Leave now, before I call the guards!
|
|
return true;
|
|
}
|
|
|
|
// Check if onSellToVendor JS event is present for item being sold
|
|
// If present and a value of "false" or 0 was returned from the script, halt the sale
|
|
bool saleHalted = false;
|
|
std::vector<UI16> scriptTriggers = j->GetScriptTriggers();
|
|
for( auto scriptTrig : scriptTriggers )
|
|
{
|
|
cScript *toExecute = JSMapping->GetScript( scriptTrig );
|
|
if( toExecute != nullptr )
|
|
{
|
|
if( toExecute->OnSellToVendor( tSock, n, j ) == 0 )
|
|
{
|
|
// Halt sale!
|
|
saleHalted = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If sale was halted by onSellToVendor event, continue to next item
|
|
if( saleHalted )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
CItem *join = nullptr;
|
|
GenericList<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() )
|
|
{
|
|
if( j->GetId() != 0x14f0 || ( j->GetTempVar( CITV_MOREX ) == k->GetTempVar( CITV_MOREX )))
|
|
{
|
|
join = k;
|
|
break; // we found the item we're looking for already
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pCont = buyPack->GetContainsList();
|
|
for( k = pCont->First(); !pCont->Finished(); k = pCont->Next() )
|
|
{
|
|
if( ValidateObject( k ))
|
|
{
|
|
if( k->GetId() == j->GetId() && j->GetType() == k->GetType() )
|
|
{
|
|
if( j->GetId() != 0x14f0 || ( j->GetTempVar( CITV_MOREX ) == k->GetTempVar( CITV_MOREX )))
|
|
{
|
|
value = CalcValue( j, k->GetSellValue() );
|
|
break; // we found the value we're looking for already
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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 );
|
|
l->RemoveFromSight();
|
|
}
|
|
}
|
|
if( l )
|
|
{
|
|
std::vector<UI16> scriptTriggers = l->GetScriptTriggers();
|
|
for( auto scriptTrig : scriptTriggers )
|
|
{
|
|
cScript *toExecute = JSMapping->GetScript( scriptTrig );
|
|
if( toExecute != nullptr )
|
|
{
|
|
// If script returns true/1, prevent other scripts with event from running
|
|
if( toExecute->OnSoldToVendor( tSock, n, l ) == 1 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
//| Function - RestockNPC()
|
|
///o------------------------------------------------------------------------------------------------o
|
|
//| Purpose - Restock NPC Vendors
|
|
//o------------------------------------------------------------------------------------------------o
|
|
void RestockNPC( CChar& i, bool stockAll )
|
|
{
|
|
if( !i.IsShop() )
|
|
return; // if we aren't a shopkeeper, why bother?
|
|
|
|
CItem *ci = i.GetItemAtLayer( IL_SELLCONTAINER );
|
|
if( ValidateObject( ci ))
|
|
{
|
|
GenericList<CItem *> *ciCont = ci->GetContainsList();
|
|
for( CItem *c = ciCont->First(); !ciCont->Finished(); c = ciCont->Next() )
|
|
{
|
|
if( ValidateObject( c ))
|
|
{
|
|
if( stockAll )
|
|
{
|
|
c->IncAmount( c->GetRestock() );
|
|
c->SetRestock( 0 );
|
|
}
|
|
else if( c->GetRestock() )
|
|
{
|
|
UI16 stockAmt = std::min( c->GetRestock(), static_cast<UI16>(( c->GetRestock() / 2 ) + 1 ));
|
|
c->IncAmount( stockAmt );
|
|
c->SetRestock( c->GetRestock() - stockAmt );
|
|
}
|
|
if( cwmWorldState->ServerData()->TradeSystemStatus() )
|
|
{
|
|
CTownRegion *tReg = CalcRegionFromXY( i.GetX(), i.GetY(), i.WorldNumber(), i.GetInstanceId() );
|
|
Items->StoreItemRandomValue( c, tReg );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool RestockFunctor( CBaseObject *a, UI32 &b, void *extraData )
|
|
{
|
|
bool retVal = true;
|
|
CChar *c = static_cast<CChar *>( a );
|
|
if( ValidateObject( c ))
|
|
{
|
|
RestockNPC(( *c ), ( b == 1 ));
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
//o------------------------------------------------------------------------------------------------o
|
|
//| Function - Restock()
|
|
//| Date - 3/15/2003
|
|
//o------------------------------------------------------------------------------------------------o
|
|
//| Purpose - Restock all NPC Vendors
|
|
//o------------------------------------------------------------------------------------------------o
|
|
void Restock( bool stockAll )
|
|
{
|
|
UI32 b = ( stockAll ? 1 : 0 );
|
|
ObjectFactory::GetSingleton().IterateOver( OT_CHAR, b, nullptr, &RestockFunctor );
|
|
}
|