|
@@ -197,24 +197,38 @@ void InventoryInteraction::pushItems( int count, ItemFilter *zFilter )
|
|
|
}
|
|
|
|
|
|
|
|
|
-Inventory::Inventory( const Framework::Vec3<float> location )
|
|
|
+Inventory::Inventory( const Framework::Vec3<float> location, bool hasInventory )
|
|
|
: ReferenceCounter(),
|
|
|
location( location )
|
|
|
{
|
|
|
- pullSlotsOrder = new Framework::RCArray<ItemSlot>();
|
|
|
- pushSlotsOrder = new Framework::RCArray<ItemSlot>();
|
|
|
- itemCache = new Framework::HashMap<int, Framework::Array<ItemSlot *> *>( ITEM_CACHE_SIZE, std::_Identity<int>() );
|
|
|
+ if( hasInventory )
|
|
|
+ {
|
|
|
+ pullSlotsOrder = new Framework::RCArray<ItemSlot>();
|
|
|
+ pushSlotsOrder = new Framework::RCArray<ItemSlot>();
|
|
|
+ itemCache = new Framework::HashMap<int, Framework::Array<ItemSlot *> *>( ITEM_CACHE_SIZE, std::_Identity<int>() );
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pullSlotsOrder = 0;
|
|
|
+ pushSlotsOrder = 0;
|
|
|
+ itemCache = 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
Inventory::~Inventory()
|
|
|
{
|
|
|
- pullSlotsOrder->release();
|
|
|
- pushSlotsOrder->release();
|
|
|
- itemCache->release();
|
|
|
+ if( pullSlotsOrder )
|
|
|
+ pullSlotsOrder->release();
|
|
|
+ if( pushSlotsOrder )
|
|
|
+ pushSlotsOrder->release();
|
|
|
+ if( itemCache )
|
|
|
+ itemCache->release();
|
|
|
}
|
|
|
|
|
|
void Inventory::updateCache( ItemSlot *zSlot, int beforeKey )
|
|
|
{
|
|
|
+ if( !itemCache )
|
|
|
+ return;
|
|
|
int key = zSlot->zStack()->zItem()->zItemType()->getId();
|
|
|
if( key == beforeKey )
|
|
|
return;
|
|
@@ -261,12 +275,12 @@ void Inventory::addSlot( ItemSlot *slot )
|
|
|
|
|
|
bool Inventory::allowPullStack( ItemSlot *zSlot, Direction dir )
|
|
|
{
|
|
|
- return true;
|
|
|
+ return pullSlotsOrder;
|
|
|
}
|
|
|
|
|
|
bool Inventory::allowPushStack( ItemSlot *zSlot, Direction dir, const Item *zItem, int &count )
|
|
|
{
|
|
|
- return true;
|
|
|
+ return pushSlotsOrder;
|
|
|
}
|
|
|
|
|
|
void Inventory::afterPullStack( ItemSlot *zSlot, Direction dir, const Item *zItem, int count )
|
|
@@ -277,131 +291,140 @@ void Inventory::afterPushStack( ItemSlot *zSlot, Direction dir, const Item *zIte
|
|
|
|
|
|
void Inventory::loadInventory( Framework::StreamReader *zReader )
|
|
|
{
|
|
|
- for( auto iterator = pushSlotsOrder->getIterator(); iterator; iterator++ )
|
|
|
+ if( itemCache )
|
|
|
{
|
|
|
- int size = 0;
|
|
|
- zReader->lese( (char *)&size, 4 );
|
|
|
- if( size != 0 )
|
|
|
+ for( auto iterator = pushSlotsOrder->getIterator(); iterator; iterator++ )
|
|
|
{
|
|
|
- int id = 0;
|
|
|
- zReader->lese( (char *)&id, 4 );
|
|
|
- Item *item = StaticRegistry<ItemType>::INSTANCE.zElement( id )->loadItem( zReader );
|
|
|
- iterator->addItems( new ItemStack( item, size ), NO_DIRECTION );
|
|
|
+ int size = 0;
|
|
|
+ zReader->lese( (char *)&size, 4 );
|
|
|
+ if( size != 0 )
|
|
|
+ {
|
|
|
+ int id = 0;
|
|
|
+ zReader->lese( (char *)&id, 4 );
|
|
|
+ Item *item = StaticRegistry<ItemType>::INSTANCE.zElement( id )->loadItem( zReader );
|
|
|
+ iterator->addItems( new ItemStack( item, size ), NO_DIRECTION );
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void Inventory::saveInventory( Framework::StreamWriter *zWriter )
|
|
|
{
|
|
|
- for( auto iterator = pushSlotsOrder->getIterator(); iterator; iterator++ )
|
|
|
+ if( itemCache )
|
|
|
{
|
|
|
- const ItemStack *stack = iterator->zStack();
|
|
|
- int value = 0;
|
|
|
- if( !stack || !stack->zItem() )
|
|
|
+ for( auto iterator = pushSlotsOrder->getIterator(); iterator; iterator++ )
|
|
|
{
|
|
|
- zWriter->schreibe( (char *)&value, 4 );
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- value = stack->getSize();
|
|
|
- zWriter->schreibe( (char *)&value, 4 );
|
|
|
- value = stack->zItem()->zItemType()->getId();
|
|
|
- zWriter->schreibe( (char *)&value, 4 );
|
|
|
- stack->zItem()->zItemType()->saveItem( stack->zItem(), zWriter );
|
|
|
+ const ItemStack *stack = iterator->zStack();
|
|
|
+ int value = 0;
|
|
|
+ if( !stack || !stack->zItem() )
|
|
|
+ {
|
|
|
+ zWriter->schreibe( (char *)&value, 4 );
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ value = stack->getSize();
|
|
|
+ zWriter->schreibe( (char *)&value, 4 );
|
|
|
+ value = stack->zItem()->zItemType()->getId();
|
|
|
+ zWriter->schreibe( (char *)&value, 4 );
|
|
|
+ stack->zItem()->zItemType()->saveItem( stack->zItem(), zWriter );
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void Inventory::localTransaction( Array< ItemSlot * > *zSourceSlots, Array< ItemSlot * > *zTargetSlots, ItemFilter *zFilter, int count )
|
|
|
{
|
|
|
- cs.Enter();
|
|
|
- auto sourceSlot = zSourceSlots->getIterator();
|
|
|
- for( auto targetSlot = zTargetSlots->getIterator(); targetSlot; )
|
|
|
+ if( itemCache )
|
|
|
{
|
|
|
- int amount = count;
|
|
|
- if( !targetSlot->isFull() )
|
|
|
+ cs.Enter();
|
|
|
+ auto sourceSlot = zSourceSlots->getIterator();
|
|
|
+ for( auto targetSlot = zTargetSlots->getIterator(); targetSlot; )
|
|
|
{
|
|
|
- if( targetSlot->zStack() )
|
|
|
+ int amount = count;
|
|
|
+ if( !targetSlot->isFull() )
|
|
|
{
|
|
|
- Array<ItemSlot *> *zSurceListe = itemCache->safeGet( targetSlot->zStack()->zItem()->zItemType()->getId(), 0 );
|
|
|
- if( zSurceListe )
|
|
|
+ if( targetSlot->zStack() )
|
|
|
{
|
|
|
- Array<int> toDelete;
|
|
|
- int index = 0;
|
|
|
- for( auto sourceSlot = zSurceListe->getIterator(); sourceSlot; sourceSlot++, index++ )
|
|
|
+ Array<ItemSlot *> *zSurceListe = itemCache->safeGet( targetSlot->zStack()->zItem()->zItemType()->getId(), 0 );
|
|
|
+ if( zSurceListe )
|
|
|
{
|
|
|
- if( zSourceSlots->getWertIndex( sourceSlot ) < 0 )
|
|
|
- continue;
|
|
|
- if( zFilter && !zFilter->matchItem( sourceSlot->zStack()->zItem() ) )
|
|
|
- continue;
|
|
|
- int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), NO_DIRECTION ), count );
|
|
|
- if( number > 0 )
|
|
|
+ Array<int> toDelete;
|
|
|
+ int index = 0;
|
|
|
+ for( auto sourceSlot = zSurceListe->getIterator(); sourceSlot; sourceSlot++, index++ )
|
|
|
{
|
|
|
- ItemStack *stack = sourceSlot->takeItemsOut( number, NO_DIRECTION );
|
|
|
- if( stack )
|
|
|
+ if( zSourceSlots->getWertIndex( sourceSlot ) < 0 )
|
|
|
+ continue;
|
|
|
+ if( zFilter && !zFilter->matchItem( sourceSlot->zStack()->zItem() ) )
|
|
|
+ continue;
|
|
|
+ int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), NO_DIRECTION ), count );
|
|
|
+ if( number > 0 )
|
|
|
{
|
|
|
- if( !sourceSlot->zStack() )
|
|
|
- toDelete.add( index, 0 );
|
|
|
- targetSlot->addItems( stack, NO_DIRECTION );
|
|
|
- if( stack->getSize() )
|
|
|
+ ItemStack *stack = sourceSlot->takeItemsOut( number, NO_DIRECTION );
|
|
|
+ if( stack )
|
|
|
{
|
|
|
- cs.Leave();
|
|
|
- throw stack;
|
|
|
+ if( !sourceSlot->zStack() )
|
|
|
+ toDelete.add( index, 0 );
|
|
|
+ targetSlot->addItems( stack, NO_DIRECTION );
|
|
|
+ if( stack->getSize() )
|
|
|
+ {
|
|
|
+ cs.Leave();
|
|
|
+ throw stack;
|
|
|
+ }
|
|
|
+ stack->release();
|
|
|
+ count -= number;
|
|
|
+ if( count == 0 )
|
|
|
+ break;
|
|
|
}
|
|
|
- stack->release();
|
|
|
- count -= number;
|
|
|
- if( count == 0 )
|
|
|
- break;
|
|
|
}
|
|
|
}
|
|
|
+ for( auto indexToDelete = toDelete.getIterator(); indexToDelete; indexToDelete++ )
|
|
|
+ zSurceListe->remove( indexToDelete );
|
|
|
+ if( count == 0 )
|
|
|
+ {
|
|
|
+ cs.Leave();
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
- for( auto indexToDelete = toDelete.getIterator(); indexToDelete; indexToDelete++ )
|
|
|
- zSurceListe->remove( indexToDelete );
|
|
|
- if( count == 0 )
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ while( sourceSlot && (!sourceSlot->zStack() || (zFilter && !zFilter->matchItem( sourceSlot->zStack()->zItem() ))) )
|
|
|
+ sourceSlot++;
|
|
|
+ if( !sourceSlot )
|
|
|
{
|
|
|
cs.Leave();
|
|
|
return;
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- while( sourceSlot && (!sourceSlot->zStack() || (zFilter && !zFilter->matchItem( sourceSlot->zStack()->zItem() ))) )
|
|
|
- sourceSlot++;
|
|
|
- if( !sourceSlot )
|
|
|
- {
|
|
|
- cs.Leave();
|
|
|
- return;
|
|
|
- }
|
|
|
- int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), NO_DIRECTION ), count );
|
|
|
- if( number > 0 )
|
|
|
- {
|
|
|
- ItemStack *stack = sourceSlot->takeItemsOut( number, NO_DIRECTION );
|
|
|
- if( stack )
|
|
|
+ int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), NO_DIRECTION ), count );
|
|
|
+ if( number > 0 )
|
|
|
{
|
|
|
- updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
|
|
|
- targetSlot->addItems( stack, NO_DIRECTION );
|
|
|
- updateCache( targetSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
|
|
|
- if( stack->getSize() )
|
|
|
- {
|
|
|
- cs.Leave();
|
|
|
- throw stack;
|
|
|
- }
|
|
|
- stack->release();
|
|
|
- count -= number;
|
|
|
- if( count == 0 )
|
|
|
+ ItemStack *stack = sourceSlot->takeItemsOut( number, NO_DIRECTION );
|
|
|
+ if( stack )
|
|
|
{
|
|
|
- cs.Leave();
|
|
|
- return;
|
|
|
+ updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
|
|
|
+ targetSlot->addItems( stack, NO_DIRECTION );
|
|
|
+ updateCache( targetSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
|
|
|
+ if( stack->getSize() )
|
|
|
+ {
|
|
|
+ cs.Leave();
|
|
|
+ throw stack;
|
|
|
+ }
|
|
|
+ stack->release();
|
|
|
+ count -= number;
|
|
|
+ if( count == 0 )
|
|
|
+ {
|
|
|
+ cs.Leave();
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ if( amount == count || targetSlot->isFull() )
|
|
|
+ targetSlot++;
|
|
|
}
|
|
|
- if( amount == count || targetSlot->isFull() )
|
|
|
- targetSlot++;
|
|
|
+ cs.Leave();
|
|
|
}
|
|
|
- cs.Leave();
|
|
|
}
|
|
|
|
|
|
InventoryInteraction Inventory::interactWith( Inventory *zInventory, Direction dir )
|