|
@@ -5,523 +5,535 @@
|
|
|
|
|
|
using namespace Framework;
|
|
|
|
|
|
-InventoryInteraction::InventoryInteraction( Inventory* current, Inventory* other, Direction dir )
|
|
|
- : current( current ),
|
|
|
- other( other ),
|
|
|
- dir( dir )
|
|
|
+InventoryInteraction::InventoryInteraction(Inventory* current, Inventory* other, Direction dir)
|
|
|
+ : current(current),
|
|
|
+ other(other),
|
|
|
+ dir(dir)
|
|
|
{
|
|
|
- lock();
|
|
|
+ lock();
|
|
|
}
|
|
|
|
|
|
-InventoryInteraction::InventoryInteraction( const InventoryInteraction& interaction )
|
|
|
- : InventoryInteraction( interaction.current, interaction.other, interaction.dir )
|
|
|
+InventoryInteraction::InventoryInteraction(const InventoryInteraction& interaction)
|
|
|
+ : InventoryInteraction(interaction.current, interaction.other, interaction.dir)
|
|
|
{}
|
|
|
|
|
|
InventoryInteraction::~InventoryInteraction()
|
|
|
{
|
|
|
- unlock();
|
|
|
+ unlock();
|
|
|
}
|
|
|
|
|
|
void InventoryInteraction::lock()
|
|
|
{
|
|
|
- if( !current || !other ) return;
|
|
|
- if( current->location.x < other->location.x )
|
|
|
- {
|
|
|
- current->cs.lock();
|
|
|
- other->cs.lock();
|
|
|
- return;
|
|
|
- }
|
|
|
- else if( current->location.x == other->location.x )
|
|
|
- {
|
|
|
- if( current->location.y < other->location.y )
|
|
|
- {
|
|
|
- current->cs.lock();
|
|
|
- other->cs.lock();
|
|
|
- return;
|
|
|
- }
|
|
|
- else if( current->location.y == other->location.y )
|
|
|
- {
|
|
|
- if( current->location.z < other->location.z )
|
|
|
- {
|
|
|
- current->cs.lock();
|
|
|
- other->cs.lock();
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- other->cs.lock();
|
|
|
- current->cs.lock();
|
|
|
+ if (!current || !other) return;
|
|
|
+ if (current->location.x < other->location.x)
|
|
|
+ {
|
|
|
+ current->cs.lock();
|
|
|
+ other->cs.lock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if (current->location.x == other->location.x)
|
|
|
+ {
|
|
|
+ if (current->location.y < other->location.y)
|
|
|
+ {
|
|
|
+ current->cs.lock();
|
|
|
+ other->cs.lock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if (current->location.y == other->location.y)
|
|
|
+ {
|
|
|
+ if (current->location.z < other->location.z)
|
|
|
+ {
|
|
|
+ current->cs.lock();
|
|
|
+ other->cs.lock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ other->cs.lock();
|
|
|
+ current->cs.lock();
|
|
|
}
|
|
|
|
|
|
void InventoryInteraction::unlock()
|
|
|
{
|
|
|
- if( !current || !other ) return;
|
|
|
- if( current->location.x < other->location.x )
|
|
|
- {
|
|
|
- current->cs.unlock();
|
|
|
- other->cs.unlock();
|
|
|
- return;
|
|
|
- }
|
|
|
- else if( current->location.x == other->location.x )
|
|
|
- {
|
|
|
- if( current->location.y < other->location.y )
|
|
|
- {
|
|
|
- current->cs.unlock();
|
|
|
- other->cs.unlock();
|
|
|
- return;
|
|
|
- }
|
|
|
- else if( current->location.y == other->location.y )
|
|
|
- {
|
|
|
- if( current->location.z < other->location.z )
|
|
|
- {
|
|
|
- current->cs.unlock();
|
|
|
- other->cs.unlock();
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- other->cs.unlock();
|
|
|
- current->cs.unlock();
|
|
|
+ if (!current || !other) return;
|
|
|
+ if (current->location.x < other->location.x)
|
|
|
+ {
|
|
|
+ current->cs.unlock();
|
|
|
+ other->cs.unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if (current->location.x == other->location.x)
|
|
|
+ {
|
|
|
+ if (current->location.y < other->location.y)
|
|
|
+ {
|
|
|
+ current->cs.unlock();
|
|
|
+ other->cs.unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if (current->location.y == other->location.y)
|
|
|
+ {
|
|
|
+ if (current->location.z < other->location.z)
|
|
|
+ {
|
|
|
+ current->cs.unlock();
|
|
|
+ other->cs.unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ other->cs.unlock();
|
|
|
+ current->cs.unlock();
|
|
|
}
|
|
|
|
|
|
-void InventoryInteraction::transaction( Inventory* zSource, Inventory* zTarget, ItemFilter* zFilter, Direction sourceView, Direction targetView, int count )
|
|
|
+void InventoryInteraction::transaction(Inventory* zSource, Inventory* zTarget, ItemFilter* zFilter, Direction sourceView, Direction targetView, int count)
|
|
|
{
|
|
|
- // TODO: rewrite this such that for each source slot all target slots are looped trough
|
|
|
- auto sourceSlot = zSource->pullSlotsOrder->begin();
|
|
|
- for( auto targetSlot = zTarget->pushSlotsOrder->begin(); targetSlot; )
|
|
|
- {
|
|
|
- int amount = count;
|
|
|
- if( !targetSlot->isFull() )
|
|
|
- {
|
|
|
- if( targetSlot->zStack() )
|
|
|
- {
|
|
|
- Array<ItemSlot*>* zSurceListe = zSource->itemCache->safeGet( targetSlot->zStack()->zItem()->zItemType()->getId(), 0 );
|
|
|
- if( zSurceListe )
|
|
|
- {
|
|
|
- Array<int> toDelete;
|
|
|
- int index = 0;
|
|
|
- for( auto sourceSlot = zSurceListe->begin(); sourceSlot; sourceSlot++, index++ )
|
|
|
- {
|
|
|
- if( zFilter && !zFilter->matchItem( sourceSlot->zStack()->zItem() ) )
|
|
|
- continue;
|
|
|
- int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), sourceView ), count );
|
|
|
- int tmp = number;
|
|
|
- if( number > 0 && zSource->allowPullStack( sourceSlot, sourceView ) && zTarget->allowPushStack( targetSlot, targetView, sourceSlot->zStack()->zItem(), tmp ) )
|
|
|
- {
|
|
|
- number = MIN( number, tmp );
|
|
|
- ItemStack* stack = sourceSlot->takeItemsOut( number, dir );
|
|
|
- if( stack )
|
|
|
- {
|
|
|
- if( !sourceSlot->zStack() )
|
|
|
- toDelete.add( index, 0 );
|
|
|
- targetSlot->addItems( stack, dir );
|
|
|
- zSource->updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
|
|
|
- zSource->afterPullStack( sourceSlot, sourceView, targetSlot->zStack()->zItem(), number );
|
|
|
- zTarget->afterPushStack( targetSlot, targetView, targetSlot->zStack()->zItem(), number );
|
|
|
- if( stack->getSize() )
|
|
|
- throw stack;
|
|
|
- stack->release();
|
|
|
- count -= number;
|
|
|
- if( count == 0 )
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- for( auto indexToDelete = toDelete.begin(); indexToDelete; indexToDelete++ )
|
|
|
- zSurceListe->remove( indexToDelete );
|
|
|
- if( count == 0 )
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- while( sourceSlot && (!sourceSlot->zStack() || (zFilter && !zFilter->matchItem( sourceSlot->zStack()->zItem() ))) )
|
|
|
- sourceSlot++;
|
|
|
- if( !sourceSlot )
|
|
|
- return;
|
|
|
- int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), sourceView ), count );
|
|
|
- int tmp = number;
|
|
|
- if( number > 0 && zSource->allowPullStack( sourceSlot, sourceView ) && zTarget->allowPushStack( targetSlot, targetView, sourceSlot->zStack()->zItem(), tmp ) )
|
|
|
- {
|
|
|
- number = MIN( number, tmp );
|
|
|
- if( number > 0 )
|
|
|
- {
|
|
|
- ItemStack* stack = sourceSlot->takeItemsOut( number, dir );
|
|
|
- if( stack )
|
|
|
- {
|
|
|
- targetSlot->addItems( stack, dir );
|
|
|
- zSource->updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
|
|
|
- zTarget->updateCache( targetSlot, -1 );
|
|
|
- zSource->afterPullStack( sourceSlot, sourceView, targetSlot->zStack()->zItem(), number );
|
|
|
- zTarget->afterPushStack( targetSlot, targetView, targetSlot->zStack()->zItem(), number );
|
|
|
- if( stack->getSize() )
|
|
|
- throw stack;
|
|
|
- stack->release();
|
|
|
- count -= number;
|
|
|
- if( count == 0 )
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if( amount == count || targetSlot->isFull() )
|
|
|
- targetSlot++;
|
|
|
- }
|
|
|
+ // TODO: rewrite this such that for each source slot all target slots are looped trough
|
|
|
+ auto sourceSlot = zSource->pullSlotsOrder->begin();
|
|
|
+ for (auto targetSlot = zTarget->pushSlotsOrder->begin(); targetSlot; )
|
|
|
+ {
|
|
|
+ int amount = count;
|
|
|
+ if (!targetSlot->isFull())
|
|
|
+ {
|
|
|
+ if (targetSlot->zStack())
|
|
|
+ {
|
|
|
+ Array<ItemSlot*>* zSurceListe = zSource->itemCache->safeGet(targetSlot->zStack()->zItem()->zItemType()->getId(), 0);
|
|
|
+ if (zSurceListe)
|
|
|
+ {
|
|
|
+ Array<int> toDelete;
|
|
|
+ int index = 0;
|
|
|
+ for (auto sourceSlot = zSurceListe->begin(); sourceSlot; sourceSlot++, index++)
|
|
|
+ {
|
|
|
+ if (zFilter && !zFilter->matchItem(sourceSlot->zStack()->zItem()))
|
|
|
+ continue;
|
|
|
+ int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), sourceView), count);
|
|
|
+ int tmp = number;
|
|
|
+ if (number > 0 && zSource->allowPullStack(sourceSlot, sourceView) && zTarget->allowPushStack(targetSlot, targetView, sourceSlot->zStack()->zItem(), tmp))
|
|
|
+ {
|
|
|
+ number = MIN(number, tmp);
|
|
|
+ ItemStack* stack = sourceSlot->takeItemsOut(number, dir);
|
|
|
+ if (stack)
|
|
|
+ {
|
|
|
+ if (!sourceSlot->zStack())
|
|
|
+ toDelete.add(index, 0);
|
|
|
+ targetSlot->addItems(stack, dir);
|
|
|
+ zSource->updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
+ zSource->afterPullStack(sourceSlot, sourceView, targetSlot->zStack()->zItem(), number);
|
|
|
+ zTarget->afterPushStack(targetSlot, targetView, targetSlot->zStack()->zItem(), number);
|
|
|
+ if (stack->getSize())
|
|
|
+ throw stack;
|
|
|
+ stack->release();
|
|
|
+ count -= number;
|
|
|
+ if (count == 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (auto indexToDelete = toDelete.begin(); indexToDelete; indexToDelete++)
|
|
|
+ zSurceListe->remove(indexToDelete);
|
|
|
+ if (count == 0)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ while (sourceSlot && (!sourceSlot->zStack() || (zFilter && !zFilter->matchItem(sourceSlot->zStack()->zItem()))))
|
|
|
+ sourceSlot++;
|
|
|
+ if (!sourceSlot)
|
|
|
+ return;
|
|
|
+ int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), sourceView), count);
|
|
|
+ int tmp = number;
|
|
|
+ if (number > 0 && zSource->allowPullStack(sourceSlot, sourceView) && zTarget->allowPushStack(targetSlot, targetView, sourceSlot->zStack()->zItem(), tmp))
|
|
|
+ {
|
|
|
+ number = MIN(number, tmp);
|
|
|
+ if (number > 0)
|
|
|
+ {
|
|
|
+ ItemStack* stack = sourceSlot->takeItemsOut(number, dir);
|
|
|
+ if (stack)
|
|
|
+ {
|
|
|
+ targetSlot->addItems(stack, dir);
|
|
|
+ zSource->updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
+ zTarget->updateCache(targetSlot, -1);
|
|
|
+ zSource->afterPullStack(sourceSlot, sourceView, targetSlot->zStack()->zItem(), number);
|
|
|
+ zTarget->afterPushStack(targetSlot, targetView, targetSlot->zStack()->zItem(), number);
|
|
|
+ if (stack->getSize())
|
|
|
+ throw stack;
|
|
|
+ stack->release();
|
|
|
+ count -= number;
|
|
|
+ if (count == 0)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (amount == count || targetSlot->isFull())
|
|
|
+ targetSlot++;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
-InventoryInteraction& InventoryInteraction::operator=( const InventoryInteraction& data )
|
|
|
+InventoryInteraction& InventoryInteraction::operator=(const InventoryInteraction& data)
|
|
|
{
|
|
|
- if( &data == this ) return *this;
|
|
|
- unlock();
|
|
|
- current = data.current;
|
|
|
- other = data.other;
|
|
|
- dir = data.dir;
|
|
|
- lock();
|
|
|
- return *this;
|
|
|
+ if (&data == this) return *this;
|
|
|
+ unlock();
|
|
|
+ current = data.current;
|
|
|
+ other = data.other;
|
|
|
+ dir = data.dir;
|
|
|
+ lock();
|
|
|
+ return *this;
|
|
|
}
|
|
|
|
|
|
void InventoryInteraction::endInteraction()
|
|
|
{
|
|
|
- unlock();
|
|
|
- current = 0;
|
|
|
- other = 0;
|
|
|
+ unlock();
|
|
|
+ current = 0;
|
|
|
+ other = 0;
|
|
|
}
|
|
|
|
|
|
-void InventoryInteraction::pullItems( int count, ItemFilter* zFilter )
|
|
|
+void InventoryInteraction::pullItems(int count, ItemFilter* zFilter)
|
|
|
{
|
|
|
- if( !current || !other ) return;
|
|
|
- transaction( other, current, zFilter, getOppositeDirection( dir ), dir, count );
|
|
|
+ if (!current || !other) return;
|
|
|
+ transaction(other, current, zFilter, getOppositeDirection(dir), dir, count);
|
|
|
}
|
|
|
|
|
|
-void InventoryInteraction::pushItems( int count, ItemFilter* zFilter )
|
|
|
+void InventoryInteraction::pushItems(int count, ItemFilter* zFilter)
|
|
|
{
|
|
|
- if( !current || !other ) return;
|
|
|
- transaction( current, other, zFilter, dir, getOppositeDirection( dir ), count );
|
|
|
+ if (!current || !other) return;
|
|
|
+ transaction(current, other, zFilter, dir, getOppositeDirection(dir), count);
|
|
|
}
|
|
|
|
|
|
|
|
|
-Inventory::Inventory( const Framework::Vec3<float> location, bool hasInventory )
|
|
|
- : ReferenceCounter(),
|
|
|
- location( location )
|
|
|
+Inventory::Inventory(const Framework::Vec3<float> location, bool hasInventory)
|
|
|
+ : ReferenceCounter(),
|
|
|
+ nextSlotId(1),
|
|
|
+ location(location)
|
|
|
{
|
|
|
- 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;
|
|
|
- }
|
|
|
+ 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()
|
|
|
{
|
|
|
- if( pullSlotsOrder )
|
|
|
- pullSlotsOrder->release();
|
|
|
- if( pushSlotsOrder )
|
|
|
- pushSlotsOrder->release();
|
|
|
- if( itemCache )
|
|
|
- itemCache->release();
|
|
|
+ if (pullSlotsOrder)
|
|
|
+ pullSlotsOrder->release();
|
|
|
+ if (pushSlotsOrder)
|
|
|
+ pushSlotsOrder->release();
|
|
|
+ if (itemCache)
|
|
|
+ itemCache->release();
|
|
|
}
|
|
|
|
|
|
-void Inventory::updateCache( ItemSlot* zSlot, int beforeKey )
|
|
|
+void Inventory::updateCache(ItemSlot* zSlot, int beforeKey)
|
|
|
{
|
|
|
- if( !itemCache )
|
|
|
- return;
|
|
|
- int key = zSlot->zStack() ? zSlot->zStack()->zItem()->zItemType()->getId() : -1;
|
|
|
- if( key == beforeKey )
|
|
|
- return;
|
|
|
- if( beforeKey >= 0 )
|
|
|
- {
|
|
|
- auto tmp = itemCache->safeGet( key, 0 );
|
|
|
- if( tmp )
|
|
|
- tmp->removeValue( zSlot );
|
|
|
- }
|
|
|
- if( zSlot->zStack() )
|
|
|
- {
|
|
|
- auto tmp = itemCache->safeGet( key, 0 );
|
|
|
- if( !tmp )
|
|
|
- {
|
|
|
- tmp = new Array<ItemSlot*>();
|
|
|
- itemCache->put( key, tmp );
|
|
|
- }
|
|
|
- tmp->add( zSlot, 0 );
|
|
|
- }
|
|
|
+ if (!itemCache)
|
|
|
+ return;
|
|
|
+ int key = zSlot->zStack() ? zSlot->zStack()->zItem()->zItemType()->getId() : -1;
|
|
|
+ if (key == beforeKey)
|
|
|
+ return;
|
|
|
+ if (beforeKey >= 0)
|
|
|
+ {
|
|
|
+ auto tmp = itemCache->safeGet(key, 0);
|
|
|
+ if (tmp)
|
|
|
+ tmp->removeValue(zSlot);
|
|
|
+ }
|
|
|
+ if (zSlot->zStack())
|
|
|
+ {
|
|
|
+ auto tmp = itemCache->safeGet(key, 0);
|
|
|
+ if (!tmp)
|
|
|
+ {
|
|
|
+ tmp = new Array<ItemSlot*>();
|
|
|
+ itemCache->put(key, tmp);
|
|
|
+ }
|
|
|
+ tmp->add(zSlot, 0);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-void Inventory::addSlot( ItemSlot* slot )
|
|
|
+void Inventory::addSlot(ItemSlot* slot)
|
|
|
{
|
|
|
- cs.lock();
|
|
|
- int pullPrio = slot->getPullPriority();
|
|
|
- int pushPrio = slot->getPushPriority();
|
|
|
- int index = 0;
|
|
|
- for( auto stack : *pullSlotsOrder )
|
|
|
- {
|
|
|
- if( stack->getPullPriority() > pullPrio )
|
|
|
- break;
|
|
|
- index++;
|
|
|
- }
|
|
|
- pullSlotsOrder->add( dynamic_cast<ItemSlot*>(slot->getThis()), index );
|
|
|
- index = 0;
|
|
|
- for( auto stack : *pushSlotsOrder )
|
|
|
- {
|
|
|
- if( stack->getPushPriority() > pushPrio )
|
|
|
- break;
|
|
|
- index++;
|
|
|
- }
|
|
|
- pushSlotsOrder->add( slot, index );
|
|
|
- updateCache( slot, -1 );
|
|
|
- cs.unlock();
|
|
|
+ cs.lock();
|
|
|
+ ((ItemSlotIDSetter*)slot)->setId(nextSlotId++);
|
|
|
+ int pullPrio = slot->getPullPriority();
|
|
|
+ int pushPrio = slot->getPushPriority();
|
|
|
+ int index = 0;
|
|
|
+ for (auto stack : *pullSlotsOrder)
|
|
|
+ {
|
|
|
+ if (stack->getPullPriority() > pullPrio)
|
|
|
+ break;
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+ pullSlotsOrder->add(dynamic_cast<ItemSlot*>(slot->getThis()), index);
|
|
|
+ index = 0;
|
|
|
+ for (auto stack : *pushSlotsOrder)
|
|
|
+ {
|
|
|
+ if (stack->getPushPriority() > pushPrio)
|
|
|
+ break;
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+ pushSlotsOrder->add(slot, index);
|
|
|
+ updateCache(slot, -1);
|
|
|
+ cs.unlock();
|
|
|
}
|
|
|
|
|
|
-bool Inventory::allowPullStack( ItemSlot* zSlot, Direction dir ) const
|
|
|
+bool Inventory::allowPullStack(ItemSlot* zSlot, Direction dir) const
|
|
|
{
|
|
|
- return pullSlotsOrder;
|
|
|
+ return pullSlotsOrder;
|
|
|
}
|
|
|
|
|
|
-bool Inventory::allowPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int& count ) const
|
|
|
+bool Inventory::allowPushStack(ItemSlot* zSlot, Direction dir, const Item* zItem, int& count) const
|
|
|
{
|
|
|
- return pushSlotsOrder;
|
|
|
+ return pushSlotsOrder;
|
|
|
}
|
|
|
|
|
|
-void Inventory::afterPullStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count )
|
|
|
+void Inventory::afterPullStack(ItemSlot* zSlot, Direction dir, const Item* zItem, int count)
|
|
|
{}
|
|
|
|
|
|
-void Inventory::afterPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count )
|
|
|
+void Inventory::afterPushStack(ItemSlot* zSlot, Direction dir, const Item* zItem, int count)
|
|
|
{}
|
|
|
|
|
|
-void Inventory::loadInventory( Framework::StreamReader* zReader )
|
|
|
+void Inventory::loadInventory(Framework::StreamReader* zReader)
|
|
|
{
|
|
|
- if( itemCache )
|
|
|
- {
|
|
|
- for( auto stack : *pushSlotsOrder )
|
|
|
- {
|
|
|
- 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 );
|
|
|
- stack->addItems( new ItemStack( item, size ), NO_DIRECTION );
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ if (itemCache)
|
|
|
+ {
|
|
|
+ for (auto stack : *pushSlotsOrder)
|
|
|
+ {
|
|
|
+ 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);
|
|
|
+ stack->addItems(new ItemStack(item, size), NO_DIRECTION);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-void Inventory::saveInventory( Framework::StreamWriter* zWriter )
|
|
|
+void Inventory::saveInventory(Framework::StreamWriter* zWriter)
|
|
|
{
|
|
|
- if( itemCache )
|
|
|
- {
|
|
|
- for( auto slot : *pushSlotsOrder )
|
|
|
- {
|
|
|
- const ItemStack* stack = slot->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 );
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ if (itemCache)
|
|
|
+ {
|
|
|
+ for (auto slot : *pushSlotsOrder)
|
|
|
+ {
|
|
|
+ const ItemStack* stack = slot->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, Direction outDir, Direction inDir )
|
|
|
+void Inventory::localTransaction(Array< ItemSlot* >* zSourceSlots, Array< ItemSlot* >* zTargetSlots, ItemFilter* zFilter, int count, Direction outDir, Direction inDir)
|
|
|
{
|
|
|
- if( itemCache )
|
|
|
- {
|
|
|
- cs.lock();
|
|
|
- auto sourceSlot = zSourceSlots ? zSourceSlots->begin() : pullSlotsOrder->begin();
|
|
|
- for( auto targetSlot = zTargetSlots->begin(); targetSlot; )
|
|
|
- {
|
|
|
- int amount = count;
|
|
|
- if( !targetSlot->isFull() )
|
|
|
- {
|
|
|
- if( targetSlot->zStack() )
|
|
|
- {
|
|
|
- Array<ItemSlot*>* zSurceListe = itemCache->safeGet( targetSlot->zStack()->zItem()->zItemType()->getId(), 0 );
|
|
|
- if( zSurceListe )
|
|
|
- {
|
|
|
- Array<int> toDelete;
|
|
|
- int index = 0;
|
|
|
- for( auto sourceSlot = zSurceListe->begin(); sourceSlot; sourceSlot++, index++ )
|
|
|
- {
|
|
|
- if( zSourceSlots && zSourceSlots->getWertIndex( sourceSlot ) < 0 )
|
|
|
- continue;
|
|
|
- if( zFilter && !zFilter->matchItem( sourceSlot->zStack()->zItem() ) )
|
|
|
- continue;
|
|
|
- int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), inDir ), count );
|
|
|
- if( number > 0 )
|
|
|
- {
|
|
|
- ItemStack* stack = sourceSlot->takeItemsOut( number, outDir );
|
|
|
- if( stack )
|
|
|
- {
|
|
|
- if( !sourceSlot->zStack() )
|
|
|
- toDelete.add( index, 0 );
|
|
|
- targetSlot->addItems( stack, inDir );
|
|
|
- updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
|
|
|
- if( stack->getSize() )
|
|
|
- {
|
|
|
- cs.unlock();
|
|
|
- throw stack;
|
|
|
- }
|
|
|
- stack->release();
|
|
|
- count -= number;
|
|
|
- if( count == 0 )
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- for( auto indexToDelete = toDelete.begin(); indexToDelete; indexToDelete++ )
|
|
|
- zSurceListe->remove( indexToDelete );
|
|
|
- if( count == 0 )
|
|
|
- {
|
|
|
- cs.unlock();
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- while( sourceSlot && (!sourceSlot->zStack() || (zFilter && !zFilter->matchItem( sourceSlot->zStack()->zItem() ))) )
|
|
|
- sourceSlot++;
|
|
|
- if( !sourceSlot )
|
|
|
- {
|
|
|
- cs.unlock();
|
|
|
- return;
|
|
|
- }
|
|
|
- int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), inDir ), count );
|
|
|
- if( number > 0 )
|
|
|
- {
|
|
|
- ItemStack* stack = sourceSlot->takeItemsOut( number, outDir );
|
|
|
- if( stack )
|
|
|
- {
|
|
|
- targetSlot->addItems( stack, inDir );
|
|
|
- updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
|
|
|
- updateCache( targetSlot, -1 );
|
|
|
- if( stack->getSize() )
|
|
|
- {
|
|
|
- cs.unlock();
|
|
|
- throw stack;
|
|
|
- }
|
|
|
- stack->release();
|
|
|
- count -= number;
|
|
|
- if( count == 0 )
|
|
|
- {
|
|
|
- cs.unlock();
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if( amount == count || targetSlot->isFull() )
|
|
|
- targetSlot++;
|
|
|
- }
|
|
|
- cs.unlock();
|
|
|
- }
|
|
|
+ if (itemCache)
|
|
|
+ {
|
|
|
+ cs.lock();
|
|
|
+ auto sourceSlot = zSourceSlots ? zSourceSlots->begin() : pullSlotsOrder->begin();
|
|
|
+ for (auto targetSlot = zTargetSlots->begin(); targetSlot; )
|
|
|
+ {
|
|
|
+ int amount = count;
|
|
|
+ if (!targetSlot->isFull())
|
|
|
+ {
|
|
|
+ if (targetSlot->zStack())
|
|
|
+ {
|
|
|
+ Array<ItemSlot*>* zSurceListe = itemCache->safeGet(targetSlot->zStack()->zItem()->zItemType()->getId(), 0);
|
|
|
+ if (zSurceListe)
|
|
|
+ {
|
|
|
+ Array<int> toDelete;
|
|
|
+ int index = 0;
|
|
|
+ for (auto sourceSlot = zSurceListe->begin(); sourceSlot; sourceSlot++, index++)
|
|
|
+ {
|
|
|
+ if (zSourceSlots && zSourceSlots->getWertIndex(sourceSlot) < 0)
|
|
|
+ continue;
|
|
|
+ if (zFilter && !zFilter->matchItem(sourceSlot->zStack()->zItem()))
|
|
|
+ continue;
|
|
|
+ int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), inDir), count);
|
|
|
+ if (number > 0)
|
|
|
+ {
|
|
|
+ ItemStack* stack = sourceSlot->takeItemsOut(number, outDir);
|
|
|
+ if (stack)
|
|
|
+ {
|
|
|
+ if (!sourceSlot->zStack())
|
|
|
+ toDelete.add(index, 0);
|
|
|
+ targetSlot->addItems(stack, inDir);
|
|
|
+ updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
+ if (stack->getSize())
|
|
|
+ {
|
|
|
+ cs.unlock();
|
|
|
+ throw stack;
|
|
|
+ }
|
|
|
+ stack->release();
|
|
|
+ count -= number;
|
|
|
+ if (count == 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (auto indexToDelete = toDelete.begin(); indexToDelete; indexToDelete++)
|
|
|
+ zSurceListe->remove(indexToDelete);
|
|
|
+ if (count == 0)
|
|
|
+ {
|
|
|
+ cs.unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ while (sourceSlot && (!sourceSlot->zStack() || (zFilter && !zFilter->matchItem(sourceSlot->zStack()->zItem()))))
|
|
|
+ sourceSlot++;
|
|
|
+ if (!sourceSlot)
|
|
|
+ {
|
|
|
+ cs.unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), inDir), count);
|
|
|
+ if (number > 0)
|
|
|
+ {
|
|
|
+ ItemStack* stack = sourceSlot->takeItemsOut(number, outDir);
|
|
|
+ if (stack)
|
|
|
+ {
|
|
|
+ targetSlot->addItems(stack, inDir);
|
|
|
+ updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
+ updateCache(targetSlot, -1);
|
|
|
+ if (stack->getSize())
|
|
|
+ {
|
|
|
+ cs.unlock();
|
|
|
+ throw stack;
|
|
|
+ }
|
|
|
+ stack->release();
|
|
|
+ count -= number;
|
|
|
+ if (count == 0)
|
|
|
+ {
|
|
|
+ cs.unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (amount == count || targetSlot->isFull())
|
|
|
+ targetSlot++;
|
|
|
+ }
|
|
|
+ cs.unlock();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-void Inventory::addItems( ItemStack* items, Direction dir )
|
|
|
+void Inventory::addItems(ItemStack* items, Direction dir)
|
|
|
{
|
|
|
- if( itemCache && items && items->getSize() > 0 )
|
|
|
- {
|
|
|
- cs.lock();
|
|
|
- for( auto targetSlot = pushSlotsOrder->begin(); targetSlot; targetSlot++ )
|
|
|
- {
|
|
|
- if( !targetSlot->isFull() )
|
|
|
- {
|
|
|
- if( targetSlot->zStack() )
|
|
|
- {
|
|
|
- int number = MIN( targetSlot->numberOfAddableItems( items, dir ), items->getSize() );
|
|
|
- int tmp = number;
|
|
|
- if( number > 0 && allowPushStack( targetSlot, dir, items->zItem(), tmp ) )
|
|
|
- {
|
|
|
- number = MIN( number, tmp );
|
|
|
- ItemStack* stack = items->split( number );
|
|
|
- if( stack )
|
|
|
- {
|
|
|
- targetSlot->addItems( stack, dir );
|
|
|
- afterPushStack( targetSlot, dir, targetSlot->zStack()->zItem(), number );
|
|
|
- if( stack->getSize() )
|
|
|
- throw stack;
|
|
|
- stack->release();
|
|
|
- if( !items->getSize() )
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- int number = MIN( targetSlot->numberOfAddableItems( items, dir ), items->getSize() );
|
|
|
- int tmp = number;
|
|
|
- if( number > 0 && allowPushStack( targetSlot, dir, items->zItem(), tmp ) )
|
|
|
- {
|
|
|
- number = MIN( number, tmp );
|
|
|
- ItemStack* stack = items->split( number );
|
|
|
- if( stack )
|
|
|
- {
|
|
|
- targetSlot->addItems( stack, dir );
|
|
|
- updateCache( targetSlot, -1 );
|
|
|
- afterPushStack( targetSlot, dir, targetSlot->zStack()->zItem(), number );
|
|
|
- if( stack->getSize() )
|
|
|
- throw stack;
|
|
|
- stack->release();
|
|
|
- if( !items->getSize() )
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- cs.unlock();
|
|
|
- }
|
|
|
+ if (itemCache && items && items->getSize() > 0)
|
|
|
+ {
|
|
|
+ cs.lock();
|
|
|
+ for (auto targetSlot = pushSlotsOrder->begin(); targetSlot; targetSlot++)
|
|
|
+ {
|
|
|
+ if (!targetSlot->isFull())
|
|
|
+ {
|
|
|
+ if (targetSlot->zStack())
|
|
|
+ {
|
|
|
+ int number = MIN(targetSlot->numberOfAddableItems(items, dir), items->getSize());
|
|
|
+ int tmp = number;
|
|
|
+ if (number > 0 && allowPushStack(targetSlot, dir, items->zItem(), tmp))
|
|
|
+ {
|
|
|
+ number = MIN(number, tmp);
|
|
|
+ ItemStack* stack = items->split(number);
|
|
|
+ if (stack)
|
|
|
+ {
|
|
|
+ targetSlot->addItems(stack, dir);
|
|
|
+ afterPushStack(targetSlot, dir, targetSlot->zStack()->zItem(), number);
|
|
|
+ if (stack->getSize())
|
|
|
+ throw stack;
|
|
|
+ stack->release();
|
|
|
+ if (!items->getSize())
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ int number = MIN(targetSlot->numberOfAddableItems(items, dir), items->getSize());
|
|
|
+ int tmp = number;
|
|
|
+ if (number > 0 && allowPushStack(targetSlot, dir, items->zItem(), tmp))
|
|
|
+ {
|
|
|
+ number = MIN(number, tmp);
|
|
|
+ ItemStack* stack = items->split(number);
|
|
|
+ if (stack)
|
|
|
+ {
|
|
|
+ targetSlot->addItems(stack, dir);
|
|
|
+ updateCache(targetSlot, -1);
|
|
|
+ afterPushStack(targetSlot, dir, targetSlot->zStack()->zItem(), number);
|
|
|
+ if (stack->getSize())
|
|
|
+ throw stack;
|
|
|
+ stack->release();
|
|
|
+ if (!items->getSize())
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ cs.unlock();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-ItemStack* Inventory::takeItemsOut( ItemSlot* zSlot, int count, Direction dir )
|
|
|
+ItemStack* Inventory::takeItemsOut(ItemSlot* zSlot, int count, Direction dir)
|
|
|
{
|
|
|
- if( allowPullStack( zSlot, dir ) )
|
|
|
- {
|
|
|
- ItemStack* stack = zSlot->takeItemsOut( count, dir );
|
|
|
- if( stack )
|
|
|
- updateCache( zSlot, stack->zItem()->zItemType()->getId() );
|
|
|
- return stack;
|
|
|
- }
|
|
|
- return 0;
|
|
|
+ if (allowPullStack(zSlot, dir))
|
|
|
+ {
|
|
|
+ ItemStack* stack = zSlot->takeItemsOut(count, dir);
|
|
|
+ if (stack)
|
|
|
+ updateCache(zSlot, stack->zItem()->zItemType()->getId());
|
|
|
+ return stack;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-InventoryInteraction Inventory::interactWith( Inventory* zInventory, Direction dir )
|
|
|
+InventoryInteraction Inventory::interactWith(Inventory* zInventory, Direction dir)
|
|
|
{
|
|
|
- return InventoryInteraction( this, zInventory, dir );
|
|
|
+ return InventoryInteraction(this, zInventory, dir);
|
|
|
}
|
|
|
|
|
|
-void Inventory::unsaveAddItem( ItemStack* zStack, Direction dir )
|
|
|
+void Inventory::unsaveAddItem(ItemStack* zStack, Direction dir)
|
|
|
{
|
|
|
- addItems( zStack, dir );
|
|
|
+ addItems(zStack, dir);
|
|
|
}
|
|
|
|
|
|
-int Inventory::numberOfAddableItems( const ItemStack* zStack, Direction dir ) const
|
|
|
+int Inventory::numberOfAddableItems(const ItemStack* zStack, Direction dir) const
|
|
|
{
|
|
|
- int count = 0;
|
|
|
- for( auto targetSlot = pushSlotsOrder->begin(); targetSlot; targetSlot++ )
|
|
|
- {
|
|
|
- int maxCount = targetSlot->numberOfAddableItems( zStack, dir );
|
|
|
- int allowed = maxCount;
|
|
|
- if( allowPushStack( targetSlot, dir, zStack->zItem(), allowed ) )
|
|
|
- count += MIN( maxCount, allowed );
|
|
|
- }
|
|
|
- return count;
|
|
|
+ int count = 0;
|
|
|
+ for (auto targetSlot = pushSlotsOrder->begin(); targetSlot; targetSlot++)
|
|
|
+ {
|
|
|
+ int maxCount = targetSlot->numberOfAddableItems(zStack, dir);
|
|
|
+ int allowed = maxCount;
|
|
|
+ if (allowPushStack(targetSlot, dir, zStack->zItem(), allowed))
|
|
|
+ count += MIN(maxCount, allowed);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+Framework::Iterator<ItemSlot*> Inventory::begin()
|
|
|
+{
|
|
|
+ return pullSlotsOrder->begin();
|
|
|
+}
|
|
|
+
|
|
|
+Framework::Iterator<ItemSlot*> Inventory::end()
|
|
|
+{
|
|
|
+ return pullSlotsOrder->end();
|
|
|
}
|