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 );
|
isUnique = exdData->getField< bool >( row, 20 );
|
||||||
isUntradable = exdData->getField< bool >( row, 21 );
|
isUntradable = exdData->getField< bool >( row, 21 );
|
||||||
isIndisposable = exdData->getField< bool >( row, 22 );
|
isIndisposable = exdData->getField< bool >( row, 22 );
|
||||||
|
isEquippable = exdData->getField< bool >( row, 23 );
|
||||||
priceMid = exdData->getField< uint32_t >( row, 24 );
|
priceMid = exdData->getField< uint32_t >( row, 24 );
|
||||||
priceLow = exdData->getField< uint32_t >( row, 25 );
|
priceLow = exdData->getField< uint32_t >( row, 25 );
|
||||||
canBeHq = exdData->getField< bool >( row, 26 );
|
canBeHq = exdData->getField< bool >( row, 26 );
|
||||||
|
|
|
@ -2406,6 +2406,7 @@ struct Item
|
||||||
bool isUnique;
|
bool isUnique;
|
||||||
bool isUntradable;
|
bool isUntradable;
|
||||||
bool isIndisposable;
|
bool isIndisposable;
|
||||||
|
bool isEquippable;
|
||||||
uint32_t priceMid;
|
uint32_t priceMid;
|
||||||
uint32_t priceLow;
|
uint32_t priceLow;
|
||||||
bool canBeHq;
|
bool canBeHq;
|
||||||
|
|
|
@ -42,7 +42,7 @@ private:
|
||||||
default: itemId = 4426; break;
|
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 )
|
if( item )
|
||||||
player.equipItem( Common::EquipSlot::Ring2, item, true );
|
player.equipItem( Common::EquipSlot::Ring2, item, true );
|
||||||
|
|
|
@ -57,7 +57,7 @@ private:
|
||||||
default: itemId = 4426; break;
|
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 )
|
if( item )
|
||||||
player.equipItem( Common::EquipSlot::Ring2, item, true );
|
player.equipItem( Common::EquipSlot::Ring2, item, true );
|
||||||
|
|
|
@ -43,7 +43,7 @@ private:
|
||||||
default: itemId = 4426; break;
|
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 )
|
if( item )
|
||||||
player.equipItem( Common::EquipSlot::Ring2, item, true );
|
player.equipItem( Common::EquipSlot::Ring2, item, true );
|
||||||
|
|
|
@ -155,7 +155,7 @@ namespace Core {
|
||||||
return m_gmInvis;
|
return m_gmInvis;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setGmInvis( bool invis )
|
void setGmInvis( bool invis )
|
||||||
{
|
{
|
||||||
m_gmInvis = invis;
|
m_gmInvis = invis;
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,10 +222,6 @@ public:
|
||||||
|
|
||||||
// Inventory / Item / Currency
|
// 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 */
|
/*! equip an item to a specified slot */
|
||||||
void equipItem( Common::EquipSlot equipSlotId, ItemPtr pItem, bool sendModel );
|
void equipItem( Common::EquipSlot equipSlotId, ItemPtr pItem, bool sendModel );
|
||||||
/*! remove an item from an equipment slot */
|
/*! remove an item from an equipment slot */
|
||||||
|
@ -612,7 +608,7 @@ public:
|
||||||
bool loadInventory();
|
bool loadInventory();
|
||||||
InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId );
|
InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId );
|
||||||
InvSlotPair getFreeBagSlot();
|
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 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 swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||||
void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId );
|
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 );
|
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()
|
void Core::Entity::Player::sendInventory()
|
||||||
{
|
{
|
||||||
InventoryMap::iterator it;
|
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 pDb = g_fw.get< Db::DbWorkerPool< Db::CharaDbConnection > >();
|
||||||
auto pExdData = g_fw.get< Data::ExdDataGenerated >();
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t rSlotId = -1;
|
if( itemInfo->isEquippable )
|
||||||
|
quantity = 1;
|
||||||
|
|
||||||
//if( itemInfo->stack_size > 1 )
|
// used for item obtain notification
|
||||||
//{
|
uint32_t originalQuantity = quantity;
|
||||||
// auto itemList = this->getSlotsOfItemsInInventory( catalogId );
|
|
||||||
// // TODO: this is a stacked item so we need to see if the item is already in inventory and
|
// todo: for now we're just going to add any items to main inv
|
||||||
// // check how much free space we have on existing stacks before looking for empty slots.
|
|
||||||
//}
|
std::pair< uint8_t, uint8_t > freeBagSlot;
|
||||||
//else
|
bool foundFreeSlot = false;
|
||||||
|
|
||||||
|
for( auto bag : { Bag0, Bag1, Bag2, Bag3 } )
|
||||||
{
|
{
|
||||||
auto freeSlot = getFreeBagSlot();
|
auto storage = m_storageMap[bag];
|
||||||
inventoryId = freeSlot.first;
|
|
||||||
rSlotId = freeSlot.second;
|
|
||||||
|
|
||||||
if( rSlotId == -1 )
|
for( uint8_t slot = 0; slot < storage->getMaxSize(); slot++ )
|
||||||
return nullptr;
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto item = createItem( catalogId, quantity );
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 );
|
item->setHq( isHq );
|
||||||
|
|
||||||
if( rSlotId != -1 )
|
auto storage = m_storageMap[freeBagSlot.first];
|
||||||
{
|
storage->setItem( freeBagSlot.second, item );
|
||||||
|
|
||||||
auto storage = m_storageMap[inventoryId];
|
writeInventory( static_cast< InventoryType >( freeBagSlot.first ) );
|
||||||
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 )
|
if( !silent )
|
||||||
{
|
{
|
||||||
auto invUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(),
|
auto invUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(), freeBagSlot.second, freeBagSlot.first, *item );
|
||||||
rSlotId,
|
|
||||||
inventoryId,
|
|
||||||
*item );
|
|
||||||
|
|
||||||
queuePacket( invUpdate );
|
queuePacket( invUpdate );
|
||||||
|
|
||||||
queuePacket( boost::make_shared< ActorControlPacket143 >( getId(), ItemObtainIcon,
|
queuePacket( boost::make_shared< ActorControlPacket143 >( getId(), ItemObtainIcon, catalogId, originalQuantity ) );
|
||||||
catalogId, item->getStackSize() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot )
|
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
|
// todo: correct invalid move? again, not sure what retail does here
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto newItem = addItem( toInventoryId, toSlot, fromItem->getId(), itemCount, fromItem->isHq(), true );
|
auto newItem = addItem( fromItem->getId(), itemCount, fromItem->isHq(), true );
|
||||||
if( !newItem )
|
if( !newItem )
|
||||||
return;
|
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++ )
|
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 )
|
if( optionalItemCount > 0 )
|
||||||
{
|
{
|
||||||
auto itemId = questInfo->itemReward1.at( optionalChoice );
|
auto itemId = questInfo->itemReward1.at( optionalChoice );
|
||||||
addItem( -1, itemId, questInfo->itemCountReward1.at( optionalChoice ) );
|
addItem( questInfo->itemCountReward1.at( optionalChoice ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( gilReward > 0 )
|
if( gilReward > 0 )
|
||||||
|
|
|
@ -62,10 +62,11 @@ uint16_t Core::Items::Util::getArmoryToEquipSlot( uint8_t slotId )
|
||||||
|
|
||||||
case Common::Wrist:
|
case Common::Wrist:
|
||||||
return Common::ArmoryWrist;
|
return Common::ArmoryWrist;
|
||||||
}
|
|
||||||
|
|
||||||
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::FFXIVARR_PACKET_R
|
||||||
return;
|
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." );
|
player.sendUrgent( "Item " + std::to_string( param1 ) + " could not be added to inventory." );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue