mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-01 16:37:45 +00:00
Add LootMessage packet to fix old ItemObtainIcon.
This commit is contained in:
parent
37fbb35c0a
commit
cc95097fbe
7 changed files with 112 additions and 31 deletions
|
@ -1229,6 +1229,16 @@ namespace Sapphire::Common
|
|||
} whm;
|
||||
};
|
||||
|
||||
enum class LootMessageType : uint8_t
|
||||
{
|
||||
GetItem1 = 1, // p1: actorId, p4: itemId (HQ: itemId + 1,000,000 lol), p5: amount
|
||||
GetItem2 = 3, // p1: actorId, p2: itemId, p3: amount, seems like same thing as GetItem1 but different param position.
|
||||
FailedToGetLootNoFreeInventorySlot = 5, // p1: actorId
|
||||
LootRolled = 7, // p1: actorId, p2: itemId, p3: amount
|
||||
GetGil = 9, // p1: gil
|
||||
EmptyCoffer = 11, // seems like no param
|
||||
};
|
||||
|
||||
using PlayerStateFlagList = std::vector< PlayerStateFlag >;
|
||||
|
||||
}
|
||||
|
|
|
@ -376,8 +376,8 @@ namespace Sapphire::Network::Packets
|
|||
|
||||
PerformNoteHandler = 0x029B, // updated 4.3
|
||||
|
||||
|
||||
ShopMessage = 0x00C1, // updated 5.25
|
||||
LootMessage = 0x00B1, // updated 5.25
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -2018,6 +2018,19 @@ namespace Sapphire::Network::Packets::Server
|
|||
uint32_t unknown7;
|
||||
};
|
||||
|
||||
struct FFXIVIpcLootMessage : FFXIVIpcBasePacket< LootMessage >
|
||||
{
|
||||
Common::LootMessageType msgType;
|
||||
uint8_t padding[3];
|
||||
uint32_t param1;
|
||||
uint32_t param2;
|
||||
uint32_t param3;
|
||||
uint32_t param4;
|
||||
uint32_t param5;
|
||||
uint32_t param6;
|
||||
uint32_t param7;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /*_CORE_NETWORK_PACKETS_SERVER_IPC_H*/
|
||||
|
|
|
@ -360,7 +360,7 @@ namespace Sapphire::Entity
|
|||
uint32_t getModelForSlot( Common::GearModelSlot slot );
|
||||
|
||||
/*! add amount to the currency of type */
|
||||
void addCurrency( Common::CurrencyType type, uint32_t amount );
|
||||
void addCurrency( Common::CurrencyType type, uint32_t amount, bool sendLootMessage = false );
|
||||
|
||||
/*! remove amount from the currency of type */
|
||||
void removeCurrency( Common::CurrencyType type, uint32_t amount );
|
||||
|
@ -928,8 +928,8 @@ namespace Sapphire::Entity
|
|||
|
||||
InvSlotPair getFreeBagSlot();
|
||||
|
||||
ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool slient = false, bool canMerge = true );
|
||||
ItemPtr addItem( ItemPtr itemToAdd, bool slient = false, bool canMerge = true );
|
||||
ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool silent = false, bool canMerge = true, bool sendLootMessage = false );
|
||||
ItemPtr addItem( ItemPtr itemToAdd, bool silent = false, bool canMerge = true, bool sendLootMessage = false );
|
||||
|
||||
void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||
|
||||
|
@ -964,7 +964,7 @@ namespace Sapphire::Entity
|
|||
uint32_t getCrystal( Common::CrystalType type );
|
||||
|
||||
/*! add amount to the crystal of type */
|
||||
void addCrystal( Common::CrystalType type, uint32_t amount );
|
||||
void addCrystal( Common::CrystalType type, uint32_t amount, bool sendLootMessage = false );
|
||||
|
||||
/*! remove amount from the crystals of type */
|
||||
void removeCrystal( Common::CrystalType type, uint32_t amount );
|
||||
|
@ -980,7 +980,7 @@ namespace Sapphire::Entity
|
|||
void setActiveLand( uint8_t land, uint8_t ward );
|
||||
Common::ActiveLand getActiveLand() const;
|
||||
|
||||
Sapphire::ItemPtr dropInventoryItem( Common::InventoryType type, uint16_t slotId, bool slient = false );
|
||||
Sapphire::ItemPtr dropInventoryItem( Common::InventoryType type, uint16_t slotId, bool silent = false );
|
||||
|
||||
// Job UI
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -298,7 +298,7 @@ void Sapphire::Entity::Player::unequipSoulCrystal( ItemPtr pItem )
|
|||
}
|
||||
|
||||
// TODO: these next functions are so similar that they could likely be simplified
|
||||
void Sapphire::Entity::Player::addCurrency( CurrencyType type, uint32_t amount )
|
||||
void Sapphire::Entity::Player::addCurrency( CurrencyType type, uint32_t amount, bool sendLootMessage )
|
||||
{
|
||||
auto slot = static_cast< uint8_t >( static_cast< uint8_t >( type ) - 1 );
|
||||
auto currItem = m_storageMap[ Currency ]->getItem( slot );
|
||||
|
@ -321,6 +321,22 @@ void Sapphire::Entity::Player::addCurrency( CurrencyType type, uint32_t amount )
|
|||
Common::InventoryType::Currency,
|
||||
*currItem );
|
||||
queuePacket( invUpdate );
|
||||
|
||||
|
||||
if( sendLootMessage )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case CurrencyType::Gil:
|
||||
{
|
||||
auto lootMsg = makeZonePacket< FFXIVIpcLootMessage >( getId() );
|
||||
lootMsg->data().msgType = Common::LootMessageType::GetGil;
|
||||
lootMsg->data().param1 = amount;
|
||||
queuePacket( lootMsg );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::removeCurrency( Common::CurrencyType type, uint32_t amount )
|
||||
|
@ -346,7 +362,7 @@ void Sapphire::Entity::Player::removeCurrency( Common::CurrencyType type, uint32
|
|||
}
|
||||
|
||||
|
||||
void Sapphire::Entity::Player::addCrystal( Common::CrystalType type, uint32_t amount )
|
||||
void Sapphire::Entity::Player::addCrystal( Common::CrystalType type, uint32_t amount, bool sendLootMessage )
|
||||
{
|
||||
auto currItem = m_storageMap[ Crystal ]->getItem( static_cast< uint8_t >( type ) - 1 );
|
||||
|
||||
|
@ -371,7 +387,21 @@ void Sapphire::Entity::Player::addCrystal( Common::CrystalType type, uint32_t am
|
|||
Common::InventoryType::Crystal,
|
||||
*currItem );
|
||||
queuePacket( invUpdate );
|
||||
queuePacket( makeActorControlSelf( getId(), ItemObtainIcon, static_cast< uint8_t >( type ) + 1, amount ) );
|
||||
|
||||
if( sendLootMessage )
|
||||
{
|
||||
auto lootMsg = makeZonePacket< FFXIVIpcLootMessage >( getId() );
|
||||
lootMsg->data().msgType = Common::LootMessageType::GetItem2;
|
||||
lootMsg->data().param1 = getId();
|
||||
lootMsg->data().param2 = currItem->getId();
|
||||
lootMsg->data().param3 = amount;
|
||||
queuePacket( lootMsg );
|
||||
}
|
||||
|
||||
auto soundEffectPacket = makeZonePacket< FFXIVIpcInventoryActionAck >( getId() );
|
||||
soundEffectPacket->data().sequence = 0xFFFFFFFF;
|
||||
soundEffectPacket->data().type = 6;
|
||||
queuePacket( soundEffectPacket );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::removeCrystal( Common::CrystalType type, uint32_t amount )
|
||||
|
@ -524,7 +554,7 @@ bool Sapphire::Entity::Player::isObtainable( uint32_t catalogId, uint8_t quantit
|
|||
return true;
|
||||
}
|
||||
|
||||
Sapphire::ItemPtr Sapphire::Entity::Player::addItem( ItemPtr itemToAdd, bool silent, bool canMerge )
|
||||
Sapphire::ItemPtr Sapphire::Entity::Player::addItem( ItemPtr itemToAdd, bool silent, bool canMerge, bool sendLootMessage )
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
auto itemInfo = exdData.get< Sapphire::Data::Item >( itemToAdd->getId() );
|
||||
|
@ -591,13 +621,24 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( ItemPtr itemToAdd, bool sil
|
|||
item->setStackSize( newStackSize );
|
||||
writeItem( item );
|
||||
|
||||
auto slotUpdate = std::make_shared< UpdateInventorySlotPacket >( getId(), slot, bag, *item );
|
||||
queuePacket( slotUpdate );
|
||||
if( !silent )
|
||||
{
|
||||
auto slotUpdate = std::make_shared< UpdateInventorySlotPacket >( getId(), slot, bag, *item );
|
||||
queuePacket( slotUpdate );
|
||||
}
|
||||
|
||||
// return existing stack if we have no overflow - items fit into a preexisting stack
|
||||
if( itemToAdd->getStackSize() == 0 )
|
||||
{
|
||||
queuePacket( makeActorControlSelf( getId(), ItemObtainIcon, itemToAdd->getId(), originalQuantity ) );
|
||||
if( sendLootMessage )
|
||||
{
|
||||
auto lootMsg = makeZonePacket< FFXIVIpcLootMessage >( getId() );
|
||||
lootMsg->data().msgType = Common::LootMessageType::GetItem2;
|
||||
lootMsg->data().param1 = getId();
|
||||
lootMsg->data().param2 = itemToAdd->isHq() ? itemToAdd->getId() + 1000000 : itemToAdd->getId();
|
||||
lootMsg->data().param3 = originalQuantity;
|
||||
queuePacket( lootMsg );
|
||||
}
|
||||
|
||||
auto soundEffectPacket = makeZonePacket< FFXIVIpcInventoryActionAck >( getId() );
|
||||
soundEffectPacket->data().sequence = 0xFFFFFFFF;
|
||||
|
@ -629,24 +670,32 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( ItemPtr itemToAdd, bool sil
|
|||
{
|
||||
auto invUpdate = std::make_shared< UpdateInventorySlotPacket >( getId(), freeBagSlot.second, freeBagSlot.first, *itemToAdd );
|
||||
queuePacket( invUpdate );
|
||||
|
||||
queuePacket( makeActorControlSelf( getId(), ItemObtainIcon, itemToAdd->getId(), originalQuantity ) );
|
||||
|
||||
auto soundEffectPacket = makeZonePacket< FFXIVIpcInventoryActionAck >( getId() );
|
||||
soundEffectPacket->data().sequence = 0xFFFFFFFF;
|
||||
soundEffectPacket->data().type = 6;
|
||||
queuePacket( soundEffectPacket );
|
||||
}
|
||||
|
||||
if( sendLootMessage )
|
||||
{
|
||||
auto lootMsg = makeZonePacket< FFXIVIpcLootMessage >( getId() );
|
||||
lootMsg->data().msgType = Common::LootMessageType::GetItem2;
|
||||
lootMsg->data().param1 = getId();
|
||||
lootMsg->data().param2 = itemToAdd->isHq() ? itemToAdd->getId() + 1000000 : itemToAdd->getId();
|
||||
lootMsg->data().param3 = originalQuantity;
|
||||
queuePacket( lootMsg );
|
||||
}
|
||||
|
||||
auto soundEffectPacket = makeZonePacket< FFXIVIpcInventoryActionAck >( getId() );
|
||||
soundEffectPacket->data().sequence = 0xFFFFFFFF;
|
||||
soundEffectPacket->data().type = 6;
|
||||
queuePacket( soundEffectPacket );
|
||||
|
||||
return itemToAdd;
|
||||
}
|
||||
|
||||
|
||||
Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_t quantity, bool isHq, bool silent, bool canMerge )
|
||||
Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_t quantity, bool isHq, bool silent, bool canMerge, bool sendLootMessage )
|
||||
{
|
||||
auto item = createItem( catalogId, quantity );
|
||||
item->setHq( isHq );
|
||||
return addItem( item, silent, canMerge );
|
||||
return addItem( item, silent, canMerge, sendLootMessage );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -929,7 +978,7 @@ uint32_t Sapphire::Entity::Player::getNextInventorySequence()
|
|||
return m_inventorySequence++;
|
||||
}
|
||||
|
||||
Sapphire::ItemPtr Sapphire::Entity::Player::dropInventoryItem( Sapphire::Common::InventoryType type, uint16_t slotId, bool slient )
|
||||
Sapphire::ItemPtr Sapphire::Entity::Player::dropInventoryItem( Sapphire::Common::InventoryType type, uint16_t slotId, bool silent )
|
||||
{
|
||||
auto& container = m_storageMap[ type ];
|
||||
|
||||
|
@ -941,7 +990,7 @@ Sapphire::ItemPtr Sapphire::Entity::Player::dropInventoryItem( Sapphire::Common:
|
|||
container->removeItem( slotId, false );
|
||||
updateContainer( type, slotId, nullptr );
|
||||
|
||||
if( !slient )
|
||||
if( !silent )
|
||||
{
|
||||
auto invUpdate = std::make_shared< UpdateInventorySlotPacket >( getId(), slotId, static_cast< uint16_t >( type ) );
|
||||
queuePacket( invUpdate );
|
||||
|
|
|
@ -1065,7 +1065,7 @@ bool Sapphire::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t opti
|
|||
{
|
||||
for( uint32_t i = 0; i < rewardItemCount; i++ )
|
||||
{
|
||||
addItem( questInfo->itemReward0.at( i ), questInfo->itemCountReward0.at( i ) );
|
||||
addItem( questInfo->itemReward0.at( i ), questInfo->itemCountReward0.at( i ), false, false, true, true );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1076,14 +1076,14 @@ bool Sapphire::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t opti
|
|||
auto itemId = questInfo->itemReward1.at( i );
|
||||
if( itemId == optionalChoice )
|
||||
{
|
||||
addItem( itemId, questInfo->itemCountReward1.at( i ) );
|
||||
addItem( itemId, questInfo->itemCountReward1.at( i ), false, false, true, true );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( gilReward > 0 )
|
||||
addCurrency( CurrencyType::Gil, gilReward );
|
||||
addCurrency( CurrencyType::Gil, gilReward, true );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -345,14 +345,23 @@ void Sapphire::Network::GameConnection::gm1Handler( const Packets::FFXIVARR_PACK
|
|||
player.sendUrgent( "Syntaxerror." );
|
||||
return;
|
||||
}
|
||||
if( param1 <= 0x12 ) // crystal
|
||||
{
|
||||
targetPlayer->addCrystal( static_cast< Common::CrystalType >( param1 ), quantity, true );
|
||||
}
|
||||
else // item
|
||||
{
|
||||
// decode using the epic SE style HQ item id
|
||||
bool isHq = param1 > 1000000;
|
||||
|
||||
if( !targetPlayer->addItem( param1, quantity ) )
|
||||
player.sendUrgent( "Item #{0} could not be added to inventory.", param1 );
|
||||
break;
|
||||
if( !targetPlayer->addItem( isHq ? param1 - 1000000 : param1, quantity, isHq, false, true, true ) )
|
||||
player.sendUrgent( "Item #{0} could not be added to inventory.", isHq ? param1 - 1000000 : param1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
case GmCommand::Gil:
|
||||
{
|
||||
targetPlayer->addCurrency( CurrencyType::Gil, param1 );
|
||||
targetPlayer->addCurrency( CurrencyType::Gil, param1, true );
|
||||
player.sendNotice( "Added {0} Gil for {1}", param1, targetPlayer->getName() );
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue