diff --git a/.travis.yml b/.travis.yml index 3df10328..8ca1bc43 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,7 @@ matrix: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-6.0 packages: - - clang-6.0 - g++-7 env: - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" @@ -29,8 +27,7 @@ cache: # Setup build matrix and dependencies before_install: - eval "${MATRIX_EVAL}" - - gem install --no-ri --no-rdoc mtime_cache - - sudo add-apt-repository -y ppa:rexut/recoil + - gem install mtime_cache --no-document - sudo apt-get update - sudo apt-get install -y libmysqlclient-dev diff --git a/README.md b/README.md index 1d441c47..582f4ebf 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

[![Discord Server](https://img.shields.io/badge/discord-Sapphire-7289DA.svg)](https://discord.gg/xxcdCER) -[![Linux Build Status](https://api.travis-ci.org/SapphireServer/Sapphire.svg?branch=master)](https://travis-ci.org/SapphireMordred/Sapphire) +[![Linux Build Status](https://api.travis-ci.org/SapphireServer/Sapphire.svg?branch=master)](https://travis-ci.org/SapphireServer/Sapphire) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/lil7lxa3ty165emm?svg=true)](https://ci.appveyor.com/project/SapphireMordred/Sapphire) diff --git a/bin/sql/schema/schema.sql b/bin/sql/schema/schema.sql index b87b2a9b..185d0225 100644 --- a/bin/sql/schema/schema.sql +++ b/bin/sql/schema/schema.sql @@ -530,9 +530,10 @@ 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, + `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`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/src/common/Common.h b/src/common/Common.h index 14de2012..96e46fc8 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -222,10 +222,36 @@ namespace Sapphire::Common FreeCompanyGil = 22000, FreeCompanyCrystal = 22001, - HousingExternalAppearance = 25000, - HousingOutdoorItemStoreroom = 25001, - HousingInternalAppearance = 25002, - HousingIndoorItemStoreroom = 25003, + // housing interior containers + HousingInteriorAppearance = 25002, + + // 50 in each container max, 300 slots max + HousingInteriorPlacedItems1 = 25003, + HousingInteriorPlacedItems2 = 25004, + HousingInteriorPlacedItems3 = 25005, + HousingInteriorPlacedItems4 = 25006, + HousingInteriorPlacedItems5 = 25007, + HousingInteriorPlacedItems6 = 25008, + + // 50 max per container, 400 slots max + // slot limit increased 'temporarily' for relocation for all estates + // see: https://na.finalfantasyxiv.com/lodestone/topics/detail/d781e0d538428aef93b8bed4b50dd62c3c50fc74 + HousingInteriorStoreroom1 = 27001, + HousingInteriorStoreroom2 = 27002, + HousingInteriorStoreroom3 = 27003, + HousingInteriorStoreroom4 = 27004, + HousingInteriorStoreroom5 = 27005, + HousingInteriorStoreroom6 = 27006, + HousingInteriorStoreroom7 = 27007, + HousingInteriorStoreroom8 = 27008, + + + // housing exterior containers + HousingOutdoorPlacedItems = 25001, + HousingOutdoorAppearance = 25000, + HousingOutdoorStoreroom = 27000, + + }; enum ContainerType : uint16_t diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index 1f55a52b..0f0eda35 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -304,6 +304,7 @@ enum ActorControlType : uint16_t AchievementCritReq = 0x3E8, AchievementList = 0x3E9, + SetEstateLightingLevel = 0x40B, // param1 = light level 0 - 5 maps to UI val 5-0 RequestHousingBuildPreset = 0x44C, RequestEstateHallRemoval = 0x44F, RequestBuildPreset = 0x450, // no idea what this is, it gets sent with BuildPresetHandler and has the plot id in param1 diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 8532e21a..34ea3204 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -910,6 +910,8 @@ namespace Sapphire::Entity bool isObtainable( uint32_t catalogId, uint8_t quantity ); + uint32_t getNextInventorySequence(); + void send(); uint8_t getFreeSlotsInBags(); @@ -939,6 +941,8 @@ namespace Sapphire::Entity bool m_onEnterEventDone; + uint32_t m_inventorySequence; + private: using InventoryMap = std::map< uint16_t, Sapphire::ItemContainerPtr >; diff --git a/src/world/Actor/PlayerInventory.cpp b/src/world/Actor/PlayerInventory.cpp index 365bd622..67545381 100644 --- a/src/world/Actor/PlayerInventory.cpp +++ b/src/world/Actor/PlayerInventory.cpp @@ -357,14 +357,11 @@ void Sapphire::Entity::Player::removeCrystal( Common::CrystalType type, uint32_t void Sapphire::Entity::Player::sendInventory() { - InventoryMap::iterator it; - auto pInvMgr = g_fw.get< World::Manager::InventoryMgr >(); - uint32_t count = 0; - for( it = m_storageMap.begin(); it != m_storageMap.end(); ++it, ++count ) + for( auto it = m_storageMap.begin(); it != m_storageMap.end(); ++it ) { - pInvMgr->sendInventoryContainer( *this, it->second, count ); + pInvMgr->sendInventoryContainer( *this, it->second ); } } @@ -867,3 +864,8 @@ bool Sapphire::Entity::Player::collectHandInItems( std::vector< uint32_t > itemI return true; } + +uint32_t Sapphire::Entity::Player::getNextInventorySequence() +{ + return m_inventorySequence++; +} diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 2a999e95..539bd634 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -24,6 +24,7 @@ #include "Framework.h" #include "ServerMgr.h" #include "Territory/House.h" +#include "InventoryMgr.h" using namespace Sapphire::Common; using namespace Sapphire::Network; @@ -508,5 +509,10 @@ void Sapphire::World::Manager::HousingMgr::sendHousingInventory( Entity::Player& if( targetLand->getOwnerId() != player.getId() ) return; - player.sendDebug( "got inventory for plot: " + targetLand->getHouse()->getHouseName() ); + auto container = targetLand->getItemContainer( inventoryType ); + if( !container ) + return; + + auto invMgr = g_fw.get< Manager::InventoryMgr >(); + invMgr->sendInventoryContainer( player, container ); } \ No newline at end of file diff --git a/src/world/Manager/InventoryMgr.cpp b/src/world/Manager/InventoryMgr.cpp index 8ce40ffe..6529d617 100644 --- a/src/world/Manager/InventoryMgr.cpp +++ b/src/world/Manager/InventoryMgr.cpp @@ -10,9 +10,9 @@ using namespace Sapphire::Network::Packets; void Sapphire::World::Manager::InventoryMgr::sendInventoryContainer( Sapphire::Entity::Player& player, - Sapphire::ItemContainerPtr container, - uint32_t sequence ) + Sapphire::ItemContainerPtr container ) { + auto sequence = player.getNextInventorySequence(); auto pMap = container->getItemMap(); for( auto itM = pMap.begin(); itM != pMap.end(); ++itM ) diff --git a/src/world/Manager/InventoryMgr.h b/src/world/Manager/InventoryMgr.h index 55869850..26fae576 100644 --- a/src/world/Manager/InventoryMgr.h +++ b/src/world/Manager/InventoryMgr.h @@ -9,8 +9,7 @@ namespace Sapphire::World::Manager class InventoryMgr { public: - void sendInventoryContainer( Sapphire::Entity::Player& player, Sapphire::ItemContainerPtr container, - uint32_t sequence = 0 ); + void sendInventoryContainer( Sapphire::Entity::Player& player, Sapphire::ItemContainerPtr container ); }; } diff --git a/src/world/Network/Handlers/ClientTriggerHandler.cpp b/src/world/Network/Handlers/ClientTriggerHandler.cpp index 40add015..de7528c2 100644 --- a/src/world/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/world/Network/Handlers/ClientTriggerHandler.cpp @@ -423,16 +423,18 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX } case ClientTriggerType::RequestLandInventory: { - if( param2 != 1 ) - return; - uint8_t plot = ( param12 & 0xFF ); + auto housingMgr = g_fw.get< HousingMgr >(); if( !housingMgr ) break; - housingMgr->sendHousingInventory( player, Common::InventoryType::HousingOutdoorItemStoreroom, plot ); + uint16_t inventoryType = Common::InventoryType::HousingOutdoorPlacedItems; + if( param2 == 1 ) + inventoryType = Common::InventoryType::HousingOutdoorStoreroom; + + housingMgr->sendHousingInventory( player, inventoryType, plot ); break; } @@ -446,7 +448,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX if( !housingMgr ) break; - housingMgr->sendHousingInventory( player, Common::InventoryType::HousingIndoorItemStoreroom, 255 ); + // housingMgr->sendHousingInventory( player, Common::InventoryType::HousingInd, 255 ); break; } diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index ee815597..20035793 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -117,15 +117,21 @@ void Sapphire::Land::init() } // init item containers - auto setupContainer = [ this ]( InventoryType type, uint8_t maxSize ) + auto setupContainer = [ this ]( InventoryType type, uint16_t maxSize ) { m_landInventoryMap[ type ] = make_ItemContainer( type, maxSize, "houseiteminventory", true, true ); }; - setupContainer( InventoryType::HousingExternalAppearance, 8 ); - setupContainer( InventoryType::HousingInternalAppearance, 8 ); - setupContainer( InventoryType::HousingOutdoorItemStoreroom, m_maxPlacedExternalItems ); - setupContainer( InventoryType::HousingIndoorItemStoreroom, m_maxPlacedInternalItems ); + setupContainer( InventoryType::HousingOutdoorAppearance, 8 ); + setupContainer( InventoryType::HousingOutdoorPlacedItems, m_maxPlacedExternalItems ); + setupContainer( InventoryType::HousingOutdoorStoreroom, m_maxPlacedExternalItems ); + + setupContainer( InventoryType::HousingInteriorAppearance, 9 ); +} + +void Sapphire::Land::loadItemContainerContents() +{ + } uint32_t Sapphire::Land::convertItemIdToHousingItemId( uint32_t itemId ) diff --git a/src/world/Territory/Land.h b/src/world/Territory/Land.h index 5aadbb94..a7b73192 100644 --- a/src/world/Territory/Land.h +++ b/src/world/Territory/Land.h @@ -62,6 +62,7 @@ namespace Sapphire uint8_t getLandTag( uint8_t slot ); ItemContainerPtr getItemContainer( uint16_t inventoryType ) const; + void loadItemContainerContents(); private: uint32_t convertItemIdToHousingItemId( uint32_t itemId );