2021-12-05 17:54:36 +00:00
# include "VendorComponent.h"
2023-06-23 06:10:06 +00:00
# include "BitStream.h"
2021-12-05 17:54:36 +00:00
2022-04-26 10:41:16 +00:00
# include "Game.h"
# include "dServer.h"
2021-12-05 17:54:36 +00:00
2023-03-17 14:36:21 +00:00
# include "CDComponentsRegistryTable.h"
# include "CDVendorComponentTable.h"
# include "CDLootMatrixTable.h"
# include "CDLootTableTable.h"
2023-06-23 05:56:25 +00:00
# include "CDItemComponentTable.h"
2023-03-17 14:36:21 +00:00
2022-04-26 10:41:16 +00:00
VendorComponent : : VendorComponent ( Entity * parent ) : Component ( parent ) {
2023-06-23 05:56:25 +00:00
m_HasStandardCostItems = false ;
m_HasMultiCostItems = false ;
2023-06-26 07:15:25 +00:00
}
void VendorComponent : : Startup ( ) {
2022-04-26 10:41:16 +00:00
SetupConstants ( ) ;
RefreshInventory ( true ) ;
2021-12-05 17:54:36 +00:00
}
void VendorComponent : : Serialize ( RakNet : : BitStream * outBitStream , bool bIsInitialUpdate , unsigned int & flags ) {
2023-06-23 05:56:25 +00:00
outBitStream - > Write ( bIsInitialUpdate | | m_DirtyVendor ) ;
if ( bIsInitialUpdate | | m_DirtyVendor ) {
outBitStream - > Write ( m_HasStandardCostItems ) ;
outBitStream - > Write ( m_HasMultiCostItems ) ;
}
2021-12-05 17:54:36 +00:00
}
void VendorComponent : : OnUse ( Entity * originator ) {
2023-06-09 09:46:01 +00:00
GameMessages : : SendVendorOpenWindow ( m_ParentEntity , originator - > GetSystemAddress ( ) ) ;
GameMessages : : SendVendorStatusUpdate ( m_ParentEntity , originator - > GetSystemAddress ( ) ) ;
2021-12-05 17:54:36 +00:00
}
2022-04-26 10:41:16 +00:00
void VendorComponent : : RefreshInventory ( bool isCreation ) {
2023-06-23 05:56:25 +00:00
SetHasStandardCostItems ( false ) ;
SetHasMultiCostItems ( false ) ;
2023-06-26 07:15:25 +00:00
// Custom code for Max vanity NPC
2023-06-09 09:46:01 +00:00
if ( m_ParentEntity - > GetLOT ( ) = = 9749 & & Game : : server - > GetZoneID ( ) = = 1201 ) {
2022-04-26 10:41:16 +00:00
if ( ! isCreation ) return ;
2023-06-23 05:56:25 +00:00
SetHasStandardCostItems ( true ) ;
2023-06-26 07:15:25 +00:00
m_Inventory . push_back ( SoldItem ( 11909 , 0 ) ) ; // Top hat w frog
m_Inventory . push_back ( SoldItem ( 7785 , 0 ) ) ; // Flash bulb
m_Inventory . push_back ( SoldItem ( 12764 , 0 ) ) ; // Big fountain soda
m_Inventory . push_back ( SoldItem ( 12241 , 0 ) ) ; // Hot cocoa (from fb)
2022-04-26 10:41:16 +00:00
return ;
}
m_Inventory . clear ( ) ;
2023-03-17 14:36:21 +00:00
auto * lootMatrixTable = CDClientManager : : Instance ( ) . GetTable < CDLootMatrixTable > ( ) ;
2023-06-26 07:15:25 +00:00
const auto lootMatrices = lootMatrixTable - > Query ( [ = ] ( CDLootMatrix entry ) { return ( entry . LootMatrixIndex = = m_LootMatrixID ) ; } ) ;
2022-04-26 10:41:16 +00:00
if ( lootMatrices . empty ( ) ) return ;
// Done with lootMatrix table
2023-03-17 14:36:21 +00:00
auto * lootTableTable = CDClientManager : : Instance ( ) . GetTable < CDLootTableTable > ( ) ;
2023-06-23 05:56:25 +00:00
auto * itemComponentTable = CDClientManager : : Instance ( ) . GetTable < CDItemComponentTable > ( ) ;
auto * compRegistryTable = CDClientManager : : Instance ( ) . GetTable < CDComponentsRegistryTable > ( ) ;
2022-04-26 10:41:16 +00:00
for ( const auto & lootMatrix : lootMatrices ) {
int lootTableID = lootMatrix . LootTableIndex ;
2023-06-26 07:15:25 +00:00
auto vendorItems = lootTableTable - > Query ( [ = ] ( CDLootTable entry ) { return ( entry . LootTableIndex = = lootTableID ) ; } ) ;
2022-04-26 10:41:16 +00:00
if ( lootMatrix . maxToDrop = = 0 | | lootMatrix . minToDrop = = 0 ) {
2023-06-26 07:15:25 +00:00
for ( const auto & item : vendorItems ) {
if ( ! m_HasStandardCostItems | | ! m_HasMultiCostItems ) {
2023-06-23 05:56:25 +00:00
auto itemComponentID = compRegistryTable - > GetByIDAndType ( item . itemid , eReplicaComponentType : : ITEM ) ;
auto itemComponent = itemComponentTable - > GetItemComponentByID ( itemComponentID ) ;
if ( ! m_HasStandardCostItems & & itemComponent . baseValue ! = - 1 ) SetHasStandardCostItems ( true ) ;
if ( ! m_HasMultiCostItems & & ! itemComponent . currencyCosts . empty ( ) ) SetHasMultiCostItems ( true ) ;
}
2023-06-26 07:15:25 +00:00
m_Inventory . push_back ( SoldItem ( item . itemid , item . sortPriority ) ) ;
2022-04-26 10:41:16 +00:00
}
} else {
auto randomCount = GeneralUtils : : GenerateRandomNumber < int32_t > ( lootMatrix . minToDrop , lootMatrix . maxToDrop ) ;
for ( size_t i = 0 ; i < randomCount ; i + + ) {
if ( vendorItems . empty ( ) ) break ;
auto randomItemIndex = GeneralUtils : : GenerateRandomNumber < int32_t > ( 0 , vendorItems . size ( ) - 1 ) ;
2023-06-26 07:15:25 +00:00
const auto & randomItem = vendorItems . at ( randomItemIndex ) ;
2022-04-26 10:41:16 +00:00
vendorItems . erase ( vendorItems . begin ( ) + randomItemIndex ) ;
2023-06-26 07:15:25 +00:00
if ( ! m_HasStandardCostItems | | ! m_HasMultiCostItems ) {
auto itemComponentID = compRegistryTable - > GetByIDAndType ( randomItem . itemid , eReplicaComponentType : : ITEM , - 1 ) ;
if ( itemComponentID = = - 1 ) {
Game : : logger - > Log ( " VendorComponent " , " Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item! " , itemComponentID , m_ParentEntity - > GetLOT ( ) ) ;
continue ;
}
2023-06-23 05:56:25 +00:00
auto itemComponent = itemComponentTable - > GetItemComponentByID ( itemComponentID ) ;
if ( ! m_HasStandardCostItems & & itemComponent . baseValue ! = - 1 ) SetHasStandardCostItems ( true ) ;
if ( ! m_HasMultiCostItems & & ! itemComponent . currencyCosts . empty ( ) ) SetHasMultiCostItems ( true ) ;
}
2023-06-26 07:15:25 +00:00
m_Inventory . push_back ( SoldItem ( randomItem . itemid , randomItem . sortPriority ) ) ;
2022-04-26 10:41:16 +00:00
}
}
}
2023-06-26 07:15:25 +00:00
// Because I (Max) want a vendor to sell these cameras
2023-06-09 09:46:01 +00:00
if ( m_ParentEntity - > GetLOT ( ) = = 13569 ) {
2022-04-26 10:41:16 +00:00
auto randomCamera = GeneralUtils : : GenerateRandomNumber < int32_t > ( 0 , 2 ) ;
2023-06-26 07:15:25 +00:00
LOT camera = 0 ;
DluAssert ( randomCamera > = 0 & & randomCamera < = 2 ) ;
2022-04-26 10:41:16 +00:00
switch ( randomCamera ) {
case 0 :
2023-06-26 07:15:25 +00:00
camera = 16253 ; // Grungagroid
2022-04-26 10:41:16 +00:00
break ;
case 1 :
2023-06-26 07:15:25 +00:00
camera = 16254 ; // Hipstabrick
2022-04-26 10:41:16 +00:00
break ;
case 2 :
2023-06-26 07:15:25 +00:00
camera = 16204 ; // Megabrixel snapshot
2022-04-26 10:41:16 +00:00
break ;
}
2023-06-26 07:15:25 +00:00
m_Inventory . push_back ( SoldItem ( camera , 0 ) ) ; //Megabrixel snapshot
2022-04-26 10:41:16 +00:00
}
// Callback timer to refresh this inventory.
2023-06-09 09:46:01 +00:00
m_ParentEntity - > AddCallbackTimer ( m_RefreshTimeSeconds , [ this ] ( ) {
2022-04-26 10:41:16 +00:00
RefreshInventory ( ) ;
2023-06-26 07:15:25 +00:00
} ) ;
2023-06-23 05:56:25 +00:00
EntityManager : : Instance ( ) - > SerializeEntity ( m_ParentEntity ) ;
2023-06-09 09:46:01 +00:00
GameMessages : : SendVendorStatusUpdate ( m_ParentEntity , UNASSIGNED_SYSTEM_ADDRESS ) ;
2021-12-05 17:54:36 +00:00
}
2022-04-26 10:41:16 +00:00
void VendorComponent : : SetupConstants ( ) {
2023-03-17 14:36:21 +00:00
auto * compRegistryTable = CDClientManager : : Instance ( ) . GetTable < CDComponentsRegistryTable > ( ) ;
2023-06-09 09:46:01 +00:00
int componentID = compRegistryTable - > GetByIDAndType ( m_ParentEntity - > GetLOT ( ) , eReplicaComponentType : : VENDOR ) ;
2022-04-26 10:41:16 +00:00
2023-03-17 14:36:21 +00:00
auto * vendorComponentTable = CDClientManager : : Instance ( ) . GetTable < CDVendorComponentTable > ( ) ;
2022-04-26 10:41:16 +00:00
std : : vector < CDVendorComponent > vendorComps = vendorComponentTable - > Query ( [ = ] ( CDVendorComponent entry ) { return ( entry . id = = componentID ) ; } ) ;
if ( vendorComps . empty ( ) ) return ;
2023-06-26 07:15:25 +00:00
auto vendorData = vendorComps . at ( 0 ) ;
m_BuyScalar = vendorData . buyScalar ;
m_SellScalar = vendorData . sellScalar ;
m_RefreshTimeSeconds = vendorData . refreshTimeSeconds ;
m_LootMatrixID = vendorData . LootMatrixIndex ;
2022-04-26 10:41:16 +00:00
}
2023-06-03 07:40:46 +00:00
2023-06-23 05:56:25 +00:00