From 2c426b5059afa37292b2e61f391b89712542ed31 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 23 Dec 2018 19:13:30 +1100 Subject: [PATCH] housing inventories work, parts are loaded from db now plus a shitload of cleanup and refactoring --- bin/sql/schema/schema.sql | 12 +- src/common/Common.h | 4 +- src/common/Database/ZoneDbConnection.cpp | 13 +- src/world/Manager/HousingMgr.cpp | 149 +++++++++++++++++++---- src/world/Manager/HousingMgr.h | 35 +++++- src/world/Manager/InventoryMgr.cpp | 67 ++++++++++ src/world/Manager/InventoryMgr.h | 49 ++++++++ src/world/Territory/House.cpp | 4 +- src/world/Territory/House.h | 4 +- src/world/Territory/HousingZone.cpp | 2 +- src/world/Territory/Land.cpp | 84 +------------ src/world/Territory/Land.h | 3 + 12 files changed, 303 insertions(+), 123 deletions(-) diff --git a/bin/sql/schema/schema.sql b/bin/sql/schema/schema.sql index 0b3cfba4..fba65de1 100644 --- a/bin/sql/schema/schema.sql +++ b/bin/sql/schema/schema.sql @@ -527,13 +527,15 @@ CREATE TABLE `landset` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE `houseiteminventory` ( - `LandIdent` BIGINT(20) UNSIGNED NOT NULL, - `ContainerId` INT(10) UNSIGNED NOT NULL, - `ItemId` INT(20) NOT NULL, - `SlotId` INT(10) UNSIGNED NOT NULL, - INDEX `landIdent` (`landIdent`) + `LandIdent` BIGINT(20) UNSIGNED NOT NULL, + `ContainerId` INT(10) UNSIGNED NOT NULL, + `SlotId` INT(10) UNSIGNED NOT NULL, + `ItemId` INT(20) NOT NULL, + PRIMARY KEY (`LandIdent`, `ContainerId`, `SlotId`), + INDEX `landIdent` (`LandIdent`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; + CREATE TABLE `spawngroup` ( `id` int(10) NOT NULL AUTO_INCREMENT, `territoryTypeId` int(5) NOT NULL, diff --git a/src/common/Common.h b/src/common/Common.h index 96e46fc8..b44c67c3 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -248,7 +248,7 @@ namespace Sapphire::Common // housing exterior containers HousingOutdoorPlacedItems = 25001, - HousingOutdoorAppearance = 25000, + HousingExteriorAppearance = 25000, HousingOutdoorStoreroom = 27000, @@ -769,7 +769,7 @@ namespace Sapphire::Common MountSkill = 0xD, }; - enum HousePartSlot + enum HouseExteriorSlot { ExteriorRoof, ExteriorWall, diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index a19f32d9..e1d66758 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -172,7 +172,7 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() /// ITEM GLOBAL prepareStatement( CHARA_ITEMGLOBAL_INS, - "INSERT INTO charaglobalitem ( CharacterId, ItemId, catalogId, UPDATE_DATE ) VALUES ( ?, ?, ?, NOW() );", + "INSERT INTO charaglobalitem ( CharacterId, ItemId, catalogId, stack, UPDATE_DATE ) VALUES ( ?, ?, ?, ?, NOW() );", CONNECTION_BOTH ); /// BNPC TEMPLATES @@ -222,6 +222,17 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() "ON land.HouseId = house.HouseId;", CONNECTION_SYNC ); + prepareStatement( LAND_INV_UP, + "INSERT INTO houseiteminventory ( LandIdent, ContainerId, SlotId, ItemId ) " + "VALUES ( ?, ?, ?, ? ) " + "ON DUPLICATE KEY UPDATE ItemId = ?;", + CONNECTION_BOTH ); + + prepareStatement( LAND_INV_DEL, + "DELETE FROM houseiteminventory " + "WHERE LandIdent = ? AND ContainerId = ? AND SlotId = ?;", + CONNECTION_BOTH ); + /*prepareStatement( LAND_INS, "INSERT INTO land ( LandSetId ) VALUES ( ? );", CONNECTION_BOTH ); diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 683d5eb2..7680128e 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -91,13 +91,13 @@ bool Sapphire::World::Manager::HousingMgr::loadEstateInventories() while( res->next() ) { //uint64_t uId, uint32_t catalogId, uint64_t model1, uint64_t model2, bool isHq - uint64_t ident = res->getUInt64( "LandIdent" ); - uint16_t containerId = res->getUInt16( "ContainerId" ); - uint64_t itemId = res->getUInt64( "ItemId" ); - uint16_t slot = res->getUInt16( "SlotId" ); - uint32_t catalogId = res->getUInt( "catalogId" ); - uint8_t stain = res->getUInt8( "stain" ); - uint64_t characterId = res->getUInt64( "CharacterId" ); + auto ident = res->getUInt64( "LandIdent" ); + auto containerId = res->getUInt16( "ContainerId" ); + auto itemId = res->getUInt64( "ItemId" ); + auto slot = res->getUInt16( "SlotId" ); + auto catalogId = res->getUInt( "catalogId" ); + auto stain = res->getUInt8( "stain" ); + auto characterId = res->getUInt64( "CharacterId" ); auto item = make_Item( itemId, catalogId, 0, 0, 0 ); item->setStain( stain ); @@ -162,6 +162,17 @@ void Sapphire::World::Manager::HousingMgr::loadLandCache() } } +uint64_t Sapphire::World::Manager::HousingMgr::getNextHouseId() +{ + auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); + auto pQR = pDb->query( "SELECT MAX( HouseId ) FROM house" ); + + if( !pQR->next() ) + return 0; + + return pQR->getUInt64( 1 ) + 1; +} + uint32_t Sapphire::World::Manager::HousingMgr::toLandSetId( uint16_t territoryTypeId, uint8_t wardId ) const { return ( static_cast< uint32_t >( territoryTypeId ) << 16 ) | wardId; @@ -430,6 +441,86 @@ void Sapphire::World::Manager::HousingMgr::sendEstateGreeting( Entity::Player& p player.queuePacket( greetingPacket ); } +bool Sapphire::World::Manager::HousingMgr::initHouseModels( Entity::Player& player, LandPtr land, uint32_t presetCatalogId ) +{ + auto house = land->getHouse(); + assert( house ); + + auto itemMax = land->getInventoryItemMax(); + + // type, maxSize, tableName, isMultiStorage + auto intContainer = make_ItemContainer( InventoryType::HousingInteriorAppearance, itemMax.second, "houseiteminventory", true ); + auto extContainer = make_ItemContainer( InventoryType::HousingExteriorAppearance, itemMax.first, "houseiteminventory", true ); + + // add containers to inv collection + auto& houseInventory = getEstateInventory( house->getLandIdent() ); + houseInventory[ InventoryType::HousingInteriorAppearance ] = intContainer; + houseInventory[ InventoryType::HousingExteriorAppearance ] = extContainer; + + auto exdData = g_fw.get< Sapphire::Data::ExdDataGenerated >(); + auto preset = exdData->get< Sapphire::Data::HousingPreset >( getItemAdditionalData( presetCatalogId ) ); + if( !preset ) + return false; + + // high iq shit + auto invMap = std::map< uint16_t, std::map< uint32_t, int32_t > > + { + // external + { + InventoryType::HousingExteriorAppearance, + { + { HouseExteriorSlot::ExteriorRoof, preset->exteriorRoof }, + { HouseExteriorSlot::ExteriorWall, preset->exteriorWall }, + { HouseExteriorSlot::ExteriorWindow, preset->exteriorWindow }, + { HouseExteriorSlot::ExteriorDoor, preset->exteriorDoor } + } + }, + + // internal + { + InventoryType::HousingInteriorAppearance, + { + // lobby/middle floor + { HousingInteriorSlot::InteriorWall, preset->interiorWall }, + { HousingInteriorSlot::InteriorFloor, preset->interiorFlooring }, + { HousingInteriorSlot::InteriorLight, preset->interiorLighting }, + + // attic + { HousingInteriorSlot::InteriorWall_Attic, preset->otherFloorWall }, + { HousingInteriorSlot::InteriorFloor_Attic, preset->otherFloorFlooring }, + { HousingInteriorSlot::InteriorLight_Attic, preset->otherFloorLighting }, + + // basement + { HousingInteriorSlot::InteriorWall_Basement, preset->basementWall }, + { HousingInteriorSlot::InteriorFloor_Basement, preset->basementFlooring }, + { HousingInteriorSlot::InteriorLight_Basement, preset->basementLighting }, + } + } + }; + + auto invMgr = g_fw.get< InventoryMgr >(); + + // create and link items + for( auto& destContainer : invMap ) + { + auto container = houseInventory[ destContainer.first ]; + + for( auto& item : destContainer.second ) + { + auto pItem = invMgr->createItem( player, item.second ); + + container->setItem( item.first, pItem ); + } + + invMgr->saveHousingContainer( land->getLandIdent(), container ); + } + + // lift off + updateHouseModels( house ); + + return true; +} + void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetItem ) { auto hZone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); @@ -447,7 +538,15 @@ void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& pl // todo: check if permit is in inventory and remove one - if( !pLand->setPreset( presetItem ) ) + // create house + auto ident = pLand->getLandIdent(); + auto house = make_House( getNextHouseId(), pLand->getLandSetId(), ident, + "Estate #" + std::to_string( ident.landId + 1 ), "" ); + + pLand->setHouse( house ); + + // create inventory items + if( !initHouseModels( player, pLand, presetItem ) ) return; pLand->setState( HouseState::privateHouse ); @@ -465,7 +564,7 @@ void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& pl player.eventStart( player.getId(), 0x000B0095, Event::EventHandler::EventType::Housing, 1, 1 ); player.playScene( 0x000B0095, 0, SET_BASE | HIDE_HOTBAR , 0, 1, plotNum, nullptr ); - player.setLandFlags( LandFlagsSlot::Private, EstateBuilt, pLand->getLandIdent() ); + player.setLandFlags( LandFlagsSlot::Private, EstateBuilt, ident ); player.sendLandFlagsSlot( LandFlagsSlot::Private ); hZone->registerHouseEntranceEObj( plotNum ); @@ -647,11 +746,7 @@ Sapphire::World::Manager::HousingMgr::LandIdentToInventoryContainerMap& Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap& Sapphire::World::Manager::HousingMgr::getEstateInventory( uint64_t ident ) { - auto map = m_estateInventories.find( ident ); - - assert( map != m_estateInventories.end() ); - - return map->second; + return m_estateInventories[ ident ]; } Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap& @@ -662,26 +757,19 @@ Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap& return getEstateInventory( u64ident ); } -void Sapphire::World::Manager::HousingMgr::updateHouseModelsFromDb( Sapphire::HousePtr house ) +void Sapphire::World::Manager::HousingMgr::updateHouseModels( Sapphire::HousePtr house ) { assert( house ); - auto getItemData = []( uint32_t itemId ) - { - auto pExdData = g_fw.get< Data::ExdDataGenerated >(); - auto info = pExdData->get< Sapphire::Data::Item >( itemId ); - return info->additionalData; - }; + auto& containers = getEstateInventory( house->getLandIdent() ); - auto containers = getEstateInventory( house->getLandIdent() ); - - auto extContainer = containers.find( static_cast< uint16_t >( InventoryType::HousingOutdoorAppearance ) ); + auto extContainer = containers.find( static_cast< uint16_t >( InventoryType::HousingExteriorAppearance ) ); if( extContainer != containers.end() ) { for( auto& item : extContainer->second->getItemMap() ) { - house->setExteriorModel( static_cast< Common::HousePartSlot >( item.first ), - getItemData( item.second->getId() ), item.second->getStain() ); + house->setExteriorModel( static_cast< Common::HouseExteriorSlot >( item.first ), + getItemAdditionalData( item.second->getId() ), item.second->getStain() ); } } else @@ -695,7 +783,7 @@ void Sapphire::World::Manager::HousingMgr::updateHouseModelsFromDb( Sapphire::Ho for( auto& item : intContainer->second->getItemMap() ) { house->setInteriorModel( static_cast< Common::HousingInteriorSlot >( item.first ), - getItemData( item.second->getId() ) ); + getItemAdditionalData( item.second->getId() ) ); } } else @@ -703,3 +791,10 @@ void Sapphire::World::Manager::HousingMgr::updateHouseModelsFromDb( Sapphire::Ho g_fw.get< Logger >()->error( "Plot " + std::to_string( house->getLandIdent().landId ) + " has an invalid inventory configuration for indoor appearance." ); } } + +uint32_t Sapphire::World::Manager::HousingMgr::getItemAdditionalData( uint32_t catalogId ) +{ + auto pExdData = g_fw.get< Data::ExdDataGenerated >(); + auto info = pExdData->get< Sapphire::Data::Item >( catalogId ); + return info->additionalData; +} \ No newline at end of file diff --git a/src/world/Manager/HousingMgr.h b/src/world/Manager/HousingMgr.h index 73884044..4cd07a57 100644 --- a/src/world/Manager/HousingMgr.h +++ b/src/world/Manager/HousingMgr.h @@ -18,6 +18,10 @@ namespace Sapphire::World::Manager public: + /*! + * @brief Structure that is generated and filled on world launch. Used to store housing data during init + * so we don't need to query them individually. + */ struct LandCacheEntry { // land table @@ -97,7 +101,7 @@ namespace Sapphire::World::Manager * * @param house The house to update the models for */ - void updateHouseModelsFromDb( HousePtr house ); + void updateHouseModels( HousePtr house ); /*! * @brief Sends the house inventory for the specified type to a player. @@ -131,10 +135,39 @@ namespace Sapphire::World::Manager * @return A map containing container ids to ItemContainerPtr */ ContainerIdToContainerMap& getEstateInventory( Common::LandIdent ident ); + + /** + * @brief Sets up inventories and spawns the base items for the house appearance + * @param land The house to update + */ + bool initHouseModels( Entity::Player& player, LandPtr land, uint32_t presetCatalogId ); + + private: + /*! + * @brief Gets the next available house id + * @return The next available house id + */ + uint64_t getNextHouseId(); + + /*! + * @brief Loads all the land entries from the database and caches them to speed up housing territory init + */ void loadLandCache(); + + /*! + * @brief Loads all the inventories for every estate on the world and sets up their containers + * @return True if it was successful + */ bool loadEstateInventories(); + /*! + * @brief Gets the additionalData field from item.exd for an item + * @param catalogId The item id to lookup in item.exd + * @return The additionalData field from item.exd + */ + uint32_t getItemAdditionalData( uint32_t catalogId ); + LandSetLandCacheMap m_landCache; LandIdentToInventoryContainerMap m_estateInventories; diff --git a/src/world/Manager/InventoryMgr.cpp b/src/world/Manager/InventoryMgr.cpp index 6529d617..c813a571 100644 --- a/src/world/Manager/InventoryMgr.cpp +++ b/src/world/Manager/InventoryMgr.cpp @@ -4,9 +4,17 @@ #include "Actor/Player.h" #include "Inventory/ItemContainer.h" #include "Inventory/Item.h" +#include "Inventory/ItemUtil.h" #include #include +#include +#include + +#include "Framework.h" + +extern Sapphire::Framework g_fw; + using namespace Sapphire::Network::Packets; void Sapphire::World::Manager::InventoryMgr::sendInventoryContainer( Sapphire::Entity::Player& player, @@ -55,4 +63,63 @@ void Sapphire::World::Manager::InventoryMgr::sendInventoryContainer( Sapphire::E containerInfoPacket->data().containerId = container->getId(); player.queuePacket( containerInfoPacket ); +} + +Sapphire::ItemPtr Sapphire::World::Manager::InventoryMgr::createItem( Entity::Player& player, + uint32_t catalogId, uint32_t quantity ) +{ + auto pExdData = g_fw.get< Data::ExdDataGenerated >(); + auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); + auto itemInfo = pExdData->get< Sapphire::Data::Item >( catalogId ); + + if( !itemInfo ) + return nullptr; + + auto item = make_Item( Items::Util::getNextUId(), catalogId, + itemInfo->modelMain, itemInfo->modelSub ); + + item->setStackSize( std::max< uint32_t >( 1, quantity ) ); + + auto stmt = pDb->getPreparedStatement( Db::CHARA_ITEMGLOBAL_INS ); + + stmt->setUInt( 1, player.getId() ); + stmt->setUInt( 2, item->getUId() ); + stmt->setUInt( 3, item->getId() ); + stmt->setUInt( 4, item->getStackSize() ); + + pDb->execute( stmt ); + + return item; +} + +void Sapphire::World::Manager::InventoryMgr::saveHousingContainer( Common::LandIdent ident, + Sapphire::ItemContainerPtr container ) +{ + auto u64ident = *reinterpret_cast< uint64_t* >( &ident ); + + for( auto& item : container->getItemMap() ) + { + saveHousingContainerItem( u64ident, container->getId(), item.first, item.second->getUId() ); + } +} + +void Sapphire::World::Manager::InventoryMgr::saveHousingContainerItem( uint64_t ident, + uint16_t containerId, uint16_t slotId, + uint64_t itemId ) +{ + auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); + + auto stmt = pDb->getPreparedStatement( Db::LAND_INV_UP ); + // LandIdent, ContainerId, SlotId, ItemId, ItemId + + stmt->setUInt64( 1, ident ); + stmt->setUInt( 2, containerId ); + stmt->setUInt( 3, slotId ); + stmt->setUInt64( 4, itemId ); + + // see query, we have to pass itemid in twice + // the second time is for the ON DUPLICATE KEY UPDATE condition + stmt->setUInt64( 5, itemId ); + + pDb->execute( stmt ); } \ No newline at end of file diff --git a/src/world/Manager/InventoryMgr.h b/src/world/Manager/InventoryMgr.h index 26fae576..c22c5342 100644 --- a/src/world/Manager/InventoryMgr.h +++ b/src/world/Manager/InventoryMgr.h @@ -9,7 +9,56 @@ namespace Sapphire::World::Manager class InventoryMgr { public: + /*! + * @brief Sends an item container to a player + * + * This does no checks on the container itself. You can send another players inventory to a different + * player if you so wish - not that you should + * + * Automagically manages inventory packet sequencing. + * + * @param player The player to send the container to + * @param container The container to send to the player + */ void sendInventoryContainer( Sapphire::Entity::Player& player, Sapphire::ItemContainerPtr container ); + + /*! + * @brief Creates an item, saves it to the global item table and returns a ptr to the created item + * @param player The player that will 'own' the item + * @param catalogId The ID for the item, see item.exd + * @param quantity how much item to make + * @return An ItemPtr to the newly created item + */ + Sapphire::ItemPtr createItem( Entity::Player& player, uint32_t catalogId, uint32_t quantity = 1 ); + + /*! + * @brief Commits a housing containers contents to the db + * @param ident The identity of the owner of the container + * @param container The container to save to the db + */ + void saveHousingContainer( Common::LandIdent ident, Sapphire::ItemContainerPtr container ); + + /*! + * @brief Update an item in the db + * @param item The item to commit to the db + */ + void updateItem( Sapphire::ItemPtr item ); + + private: + /*! + * @brief Saves an individual item to the db. + * + * This will create a new row in the event the slot doesn't exist in the db, otherwise this + * will overwrite the itemid in the existing row. + * + * @param ident + * @param containerId + * @param slotId + * @param itemId + */ + void saveHousingContainerItem( uint64_t ident, + uint16_t containerId, uint16_t slotId, + uint64_t itemId ); }; } diff --git a/src/world/Territory/House.cpp b/src/world/Territory/House.cpp index 09802a5f..34718ff7 100644 --- a/src/world/Territory/House.cpp +++ b/src/world/Territory/House.cpp @@ -87,12 +87,12 @@ void Sapphire::House::setHouseName( const std::string& name ) updateHouseDb(); } -void Sapphire::House::setExteriorModel( Sapphire::Common::HousePartSlot slot, uint32_t modelId, uint16_t stain ) +void Sapphire::House::setExteriorModel( Sapphire::Common::HouseExteriorSlot slot, uint32_t modelId, uint16_t stain ) { m_exteriorModelCache[ slot ] = std::make_pair( modelId, stain ); } -Sapphire::House::HousePart Sapphire::House::getExteriorModel( Sapphire::Common::HousePartSlot slot ) +Sapphire::House::HousePart Sapphire::House::getExteriorModel( Sapphire::Common::HouseExteriorSlot slot ) { return m_exteriorModelCache[ slot ]; } diff --git a/src/world/Territory/House.h b/src/world/Territory/House.h index ce73088b..d0a0e5a3 100644 --- a/src/world/Territory/House.h +++ b/src/world/Territory/House.h @@ -31,8 +31,8 @@ namespace Sapphire void setHouseGreeting( const std::string& greeting ); //functions - void setExteriorModel( Common::HousePartSlot slot, uint32_t modelId, uint16_t stain ); - HousePart getExteriorModel( Common::HousePartSlot slot ); + void setExteriorModel( Common::HouseExteriorSlot slot, uint32_t modelId, uint16_t stain ); + HousePart getExteriorModel( Common::HouseExteriorSlot slot ); void setInteriorModel( Common::HousingInteriorSlot slot, uint32_t modelId ); uint32_t getInteriorModel( Common::HousingInteriorSlot slot ); diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index 9e9d6e51..075059e2 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -85,7 +85,7 @@ bool Sapphire::HousingZone::init() { auto house = make_House( entry.m_houseId, m_landSetId, land->getLandIdent(), entry.m_estateName, entry.m_estateComment ); - housingMgr->updateHouseModelsFromDb( house ); + housingMgr->updateHouseModels( house ); land->setHouse( house ); } diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index 9aed4973..3e0abc1b 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -88,25 +88,6 @@ void Sapphire::Land::init( Common::LandType type, uint8_t size, uint8_t state, u default: break; } - - // init item containers -// auto setupContainer = [ this ]( InventoryType type, uint16_t maxSize ) -// { -// m_landInventoryMap[ type ] = make_ItemContainer( type, maxSize, "houseiteminventory", true, true ); -// }; -// -// setupContainer( InventoryType::HousingOutdoorAppearance, 8 ); -// setupContainer( InventoryType::HousingOutdoorPlacedItems, m_maxPlacedExternalItems ); -// setupContainer( InventoryType::HousingOutdoorStoreroom, m_maxPlacedExternalItems ); -// -// setupContainer( InventoryType::HousingInteriorAppearance, 9 ); -// -// // nb: so we're going to store these internally in one container because SE is fucked in the head -// // but when an inventory is requested, we will split them into groups of 50 -// setupContainer( InventoryType::HousingInteriorPlacedItems1, m_maxPlacedInternalItems ); -// setupContainer( InventoryType::HousingInteriorStoreroom1, m_maxPlacedInternalItems ); -// -// loadItemContainerContents(); } uint32_t Sapphire::Land::convertItemIdToHousingItemId( uint32_t itemId ) @@ -281,68 +262,7 @@ void Sapphire::Land::update( uint32_t currTime ) } } -uint32_t Sapphire::Land::getNextHouseId() +Sapphire::Land::InvMaxItemsPair Sapphire::Land::getInventoryItemMax() const { - auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); - auto pQR = pDb->query( "SELECT MAX( HouseId ) FROM house" ); - - if( !pQR->next() ) - return 0; - - return pQR->getUInt( 1 ) + 1; -} - -bool Sapphire::Land::setPreset( uint32_t itemId ) -{ - auto housingItemId = convertItemIdToHousingItemId( itemId ); - - auto exdData = g_fw.get< Sapphire::Data::ExdDataGenerated >(); - if( !exdData ) - return false; - - auto housingPreset = exdData->get< Sapphire::Data::HousingPreset >( housingItemId ); - if( !housingPreset ) - return false; - - if( !getHouse() ) - { - // todo: i guess we'd create a house here? - auto newId = getNextHouseId(); - - m_pHouse = make_House( newId, getLandSetId(), getLandIdent(), "Estate #" + std::to_string( m_landIdent.landId + 1 ), "" ); - } - - -// getHouse()->setHouseModel( Common::HousePartSlot::ExteriorRoof, -// convertItemIdToHousingItemId( housingPreset->exteriorRoof ) ); -// getHouse()->setHouseModel( Common::HousePartSlot::ExteriorWall, -// convertItemIdToHousingItemId( housingPreset->exteriorWall ) ); -// getHouse()->setHouseModel( Common::HousePartSlot::ExteriorWindow, -// convertItemIdToHousingItemId( housingPreset->exteriorWindow ) ); -// getHouse()->setHouseModel( Common::HousePartSlot::ExteriorDoor, -// convertItemIdToHousingItemId( housingPreset->exteriorDoor ) ); -// -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorWall, -// convertItemIdToHousingItemId( housingPreset->interiorWall ) ); -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorFloor, -// convertItemIdToHousingItemId( housingPreset->interiorFlooring ) ); -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorLight, -// convertItemIdToHousingItemId( housingPreset->interiorLighting ) ); -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorWall_Attic, -// convertItemIdToHousingItemId( housingPreset->otherFloorWall ) ); -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorFloor_Attic, -// convertItemIdToHousingItemId( housingPreset->otherFloorFlooring ) ); -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorLight_Attic, -// convertItemIdToHousingItemId( housingPreset->otherFloorLighting ) ); -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorWall_Basement, -// convertItemIdToHousingItemId( housingPreset->basementWall ) ); -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorFloor_Basement, -// convertItemIdToHousingItemId( housingPreset->basementFlooring ) ); -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorLight_Basement, -// convertItemIdToHousingItemId( housingPreset->basementLighting ) ); -// getHouse()->setHouseInteriorModel( Common::HousingInteriorSlot::InteriorLight_Mansion, -// convertItemIdToHousingItemId( housingPreset->mansionLighting ) ); - - - return true; + return std::make_pair( m_maxPlacedExternalItems, m_maxPlacedInternalItems ); } \ No newline at end of file diff --git a/src/world/Territory/Land.h b/src/world/Territory/Land.h index 19977e77..e80ff593 100644 --- a/src/world/Territory/Land.h +++ b/src/world/Territory/Land.h @@ -20,6 +20,7 @@ namespace Sapphire void init( Common::LandType type, uint8_t size, uint8_t state, uint32_t currentPrice, uint64_t ownerId, uint64_t houseId ); using LandInventoryMap = std::unordered_map< uint16_t, ItemContainerPtr >; + using InvMaxItemsPair = std::pair< uint16_t, uint16_t >; //Primary state void setSize( uint8_t size ); @@ -61,6 +62,8 @@ namespace Sapphire void setLandTag( uint8_t slot, uint8_t tag ); uint8_t getLandTag( uint8_t slot ); + InvMaxItemsPair getInventoryItemMax() const; + private: uint32_t convertItemIdToHousingItemId( uint32_t itemId ); uint32_t getNextHouseId();