mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-26 06:27:45 +00:00
addItem is way less retarded now, stacks are automagically filled first
This commit is contained in:
parent
3396645e3c
commit
1b7d11bb43
11 changed files with 83 additions and 65 deletions
|
@ -2314,6 +2314,7 @@ Core::Data::Item::Item( uint32_t row_id, Core::Data::ExdDataGenerated* exdData )
|
|||
isUnique = exdData->getField< bool >( row, 20 );
|
||||
isUntradable = exdData->getField< bool >( row, 21 );
|
||||
isIndisposable = exdData->getField< bool >( row, 22 );
|
||||
isEquippable = exdData->getField< bool >( row, 23 );
|
||||
priceMid = exdData->getField< uint32_t >( row, 24 );
|
||||
priceLow = exdData->getField< uint32_t >( row, 25 );
|
||||
canBeHq = exdData->getField< bool >( row, 26 );
|
||||
|
|
|
@ -2406,6 +2406,7 @@ struct Item
|
|||
bool isUnique;
|
||||
bool isUntradable;
|
||||
bool isIndisposable;
|
||||
bool isEquippable;
|
||||
uint32_t priceMid;
|
||||
uint32_t priceLow;
|
||||
bool canBeHq;
|
||||
|
|
|
@ -42,7 +42,7 @@ private:
|
|||
default: itemId = 4426; break;
|
||||
}
|
||||
|
||||
auto item = player.addItem( Common::InventoryType::ArmoryRing, -1, itemId, 1, false, true );
|
||||
auto item = player.addItem( itemId, 1, false, true );
|
||||
|
||||
if( item )
|
||||
player.equipItem( Common::EquipSlot::Ring2, item, true );
|
||||
|
|
|
@ -57,7 +57,7 @@ private:
|
|||
default: itemId = 4426; break;
|
||||
}
|
||||
|
||||
auto item = player.addItem( Common::InventoryType::ArmoryRing, -1, itemId, 1, false, true );
|
||||
auto item = player.addItem( itemId, 1, false, true );
|
||||
|
||||
if( item )
|
||||
player.equipItem( Common::EquipSlot::Ring2, item, true );
|
||||
|
|
|
@ -43,7 +43,7 @@ private:
|
|||
default: itemId = 4426; break;
|
||||
}
|
||||
|
||||
auto item = player.addItem( Common::InventoryType::ArmoryRing, -1, itemId, 1, false, true );
|
||||
auto item = player.addItem( itemId, 1, false, true );
|
||||
|
||||
if( item )
|
||||
player.equipItem( Common::EquipSlot::Ring2, item, true );
|
||||
|
|
|
@ -155,7 +155,7 @@ namespace Core {
|
|||
return m_gmInvis;
|
||||
}
|
||||
|
||||
bool setGmInvis( bool invis )
|
||||
void setGmInvis( bool invis )
|
||||
{
|
||||
m_gmInvis = invis;
|
||||
}
|
||||
|
|
|
@ -222,10 +222,6 @@ public:
|
|||
|
||||
// Inventory / Item / Currency
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*! add an item to the first free slot in one of the 4 main containers */
|
||||
bool tryAddItem( uint16_t catalogId, uint32_t quantity );
|
||||
/*! add an item to a given container */
|
||||
// bool addItem( uint16_t containerId, uint16_t catalogId, uint32_t quantity );
|
||||
/*! equip an item to a specified slot */
|
||||
void equipItem( Common::EquipSlot equipSlotId, ItemPtr pItem, bool sendModel );
|
||||
/*! remove an item from an equipment slot */
|
||||
|
@ -612,7 +608,7 @@ public:
|
|||
bool loadInventory();
|
||||
InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId );
|
||||
InvSlotPair getFreeBagSlot();
|
||||
Core::ItemPtr addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity = 1, bool isHq = false, bool slient = false );
|
||||
Core::ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool slient = false );
|
||||
void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||
void swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||
void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId );
|
||||
|
|
|
@ -320,17 +320,6 @@ void Core::Entity::Player::removeCrystal( Common::CrystalType type, uint32_t amo
|
|||
queuePacket( invUpdate );
|
||||
}
|
||||
|
||||
bool Core::Entity::Player::tryAddItem( uint16_t catalogId, uint32_t quantity )
|
||||
{
|
||||
|
||||
for( uint16_t i = 0; i < 4; i++ )
|
||||
{
|
||||
if( addItem( i, -1, catalogId, quantity ) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Core::Entity::Player::sendInventory()
|
||||
{
|
||||
InventoryMap::iterator it;
|
||||
|
@ -495,7 +484,7 @@ bool Core::Entity::Player::isObtainable( uint32_t catalogId, uint8_t quantity )
|
|||
}
|
||||
|
||||
|
||||
Core::ItemPtr Core::Entity::Player::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity, bool isHq, bool silent )
|
||||
Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quantity, bool isHq, bool silent )
|
||||
{
|
||||
auto pDb = g_fw.get< Db::DbWorkerPool< Db::CharaDbConnection > >();
|
||||
auto pExdData = g_fw.get< Data::ExdDataGenerated >();
|
||||
|
@ -507,57 +496,87 @@ Core::ItemPtr Core::Entity::Player::addItem( uint16_t inventoryId, int8_t slotId
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
int8_t rSlotId = -1;
|
||||
if( itemInfo->isEquippable )
|
||||
quantity = 1;
|
||||
|
||||
//if( itemInfo->stack_size > 1 )
|
||||
//{
|
||||
// auto itemList = this->getSlotsOfItemsInInventory( catalogId );
|
||||
// // TODO: this is a stacked item so we need to see if the item is already in inventory and
|
||||
// // check how much free space we have on existing stacks before looking for empty slots.
|
||||
//}
|
||||
//else
|
||||
// used for item obtain notification
|
||||
uint32_t originalQuantity = quantity;
|
||||
|
||||
// todo: for now we're just going to add any items to main inv
|
||||
|
||||
std::pair< uint8_t, uint8_t > freeBagSlot;
|
||||
bool foundFreeSlot = false;
|
||||
|
||||
for( auto bag : { Bag0, Bag1, Bag2, Bag3 } )
|
||||
{
|
||||
auto freeSlot = getFreeBagSlot();
|
||||
inventoryId = freeSlot.first;
|
||||
rSlotId = freeSlot.second;
|
||||
auto storage = m_storageMap[bag];
|
||||
|
||||
if( rSlotId == -1 )
|
||||
return nullptr;
|
||||
for( uint8_t slot = 0; slot < storage->getMaxSize(); slot++ )
|
||||
{
|
||||
auto item = storage->getItem( slot );
|
||||
|
||||
// add any items that are stackable
|
||||
if( item && !itemInfo->isEquippable && item->getId() == catalogId )
|
||||
{
|
||||
uint32_t count = item->getStackSize();
|
||||
uint32_t maxStack = item->getMaxStackSize();
|
||||
|
||||
// if slot is full, skip it
|
||||
if( count >= maxStack )
|
||||
continue;
|
||||
|
||||
// update stack
|
||||
uint32_t newStackSize = count + quantity;
|
||||
uint32_t overflow = 0;
|
||||
|
||||
if( newStackSize > maxStack )
|
||||
{
|
||||
overflow = newStackSize - item->getMaxStackSize();
|
||||
newStackSize = maxStack;
|
||||
}
|
||||
|
||||
item->setStackSize( newStackSize );
|
||||
|
||||
auto slotUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(), slot, bag, *item );
|
||||
queuePacket( slotUpdate );
|
||||
|
||||
quantity = overflow;
|
||||
|
||||
// return existing stack if we have no overflow - items fit into a preexisting stack
|
||||
if( quantity == 0 )
|
||||
return item;
|
||||
}
|
||||
else if( !item && !foundFreeSlot )
|
||||
{
|
||||
freeBagSlot = { bag, slot };
|
||||
foundFreeSlot = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto item = createItem( catalogId, quantity );
|
||||
// couldn't find a free slot and we still have some quantity of items left, shits fucked
|
||||
if( !foundFreeSlot )
|
||||
return nullptr;
|
||||
|
||||
auto item = createItem( catalogId, quantity );
|
||||
item->setHq( isHq );
|
||||
|
||||
if( rSlotId != -1 )
|
||||
auto storage = m_storageMap[freeBagSlot.first];
|
||||
storage->setItem( freeBagSlot.second, item );
|
||||
|
||||
writeInventory( static_cast< InventoryType >( freeBagSlot.first ) );
|
||||
|
||||
if( !silent )
|
||||
{
|
||||
auto invUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(), freeBagSlot.second, freeBagSlot.first, *item );
|
||||
queuePacket( invUpdate );
|
||||
|
||||
auto storage = m_storageMap[inventoryId];
|
||||
storage->setItem( rSlotId, item );
|
||||
|
||||
pDb->execute( "UPDATE " + storage->getTableName() + " SET container_" +
|
||||
std::to_string( rSlotId ) + " = " + std::to_string( item->getUId() ) +
|
||||
" WHERE storageId = " + std::to_string( inventoryId ) +
|
||||
" AND CharacterId = " + std::to_string( getId() ) );
|
||||
|
||||
if( !silent )
|
||||
{
|
||||
auto invUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(),
|
||||
rSlotId,
|
||||
inventoryId,
|
||||
*item );
|
||||
|
||||
queuePacket( invUpdate );
|
||||
|
||||
queuePacket( boost::make_shared< ActorControlPacket143 >( getId(), ItemObtainIcon,
|
||||
catalogId, item->getStackSize() ) );
|
||||
}
|
||||
|
||||
|
||||
queuePacket( boost::make_shared< ActorControlPacket143 >( getId(), ItemObtainIcon, catalogId, originalQuantity ) );
|
||||
}
|
||||
|
||||
return item;
|
||||
|
||||
}
|
||||
|
||||
void Core::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot )
|
||||
|
@ -641,7 +660,7 @@ void Core::Entity::Player::splitItem( uint16_t fromInventoryId, uint8_t fromSlot
|
|||
// todo: correct invalid move? again, not sure what retail does here
|
||||
return;
|
||||
|
||||
auto newItem = addItem( toInventoryId, toSlot, fromItem->getId(), itemCount, fromItem->isHq(), true );
|
||||
auto newItem = addItem( fromItem->getId(), itemCount, fromItem->isHq(), true );
|
||||
if( !newItem )
|
||||
return;
|
||||
|
||||
|
|
|
@ -1059,14 +1059,14 @@ bool Core::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t optional
|
|||
{
|
||||
for( uint32_t i = 0; i < questInfo->itemReward0.size(); i++ )
|
||||
{
|
||||
addItem( -1, questInfo->itemReward0.at( i ), questInfo->itemCountReward0.at( i ) );
|
||||
addItem( questInfo->itemCountReward0.at( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( optionalItemCount > 0 )
|
||||
{
|
||||
auto itemId = questInfo->itemReward1.at( optionalChoice );
|
||||
addItem( -1, itemId, questInfo->itemCountReward1.at( optionalChoice ) );
|
||||
addItem( questInfo->itemCountReward1.at( optionalChoice ) );
|
||||
}
|
||||
|
||||
if( gilReward > 0 )
|
||||
|
|
|
@ -62,9 +62,10 @@ uint16_t Core::Items::Util::getArmoryToEquipSlot( uint8_t slotId )
|
|||
|
||||
case Common::Wrist:
|
||||
return Common::ArmoryWrist;
|
||||
}
|
||||
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -323,7 +323,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::FFXIVARR_PACKET_R
|
|||
return;
|
||||
}
|
||||
|
||||
if( !targetPlayer->addItem( -1, param1, quantity ) )
|
||||
if( !targetPlayer->addItem( param1, quantity ) )
|
||||
player.sendUrgent( "Item " + std::to_string( param1 ) + " could not be added to inventory." );
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue