From 5607afee06b671c2b9b3e39978015dbd9d4cc01e Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 24 Nov 2018 15:17:18 +1100 Subject: [PATCH] buying from gilshops now works --- src/common/Common.h | 2 +- src/common/Exd/ExdDataGenerated.h | 2 +- src/common/Network/CommonActorControl.h | 1 + src/servers/Scripts/common/GilShop.cpp | 22 +++++++---- src/servers/sapphire_zone/Manager/ShopMgr.cpp | 34 +++++++++++++++++ src/servers/sapphire_zone/Manager/ShopMgr.h | 10 +++++ .../Network/Handlers/EventHandlers.cpp | 4 +- .../Network/Handlers/PacketHandlers.cpp | 38 +------------------ src/servers/sapphire_zone/Zone/HousingMgr.cpp | 27 +++++++++++++ src/servers/sapphire_zone/Zone/HousingMgr.h | 2 + src/servers/sapphire_zone/Zone/Land.cpp | 16 +++++++- src/servers/sapphire_zone/Zone/Land.h | 4 +- src/servers/sapphire_zone/mainGameServer.cpp | 3 ++ 13 files changed, 114 insertions(+), 51 deletions(-) create mode 100644 src/servers/sapphire_zone/Manager/ShopMgr.cpp create mode 100644 src/servers/sapphire_zone/Manager/ShopMgr.h diff --git a/src/common/Common.h b/src/common/Common.h index 543cf72d..fe8eb6bc 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -805,8 +805,8 @@ namespace Core::Common none, forSale, sold, + privateHouse, fcHouse, - privateHouse }; enum HouseIconAdd : uint8_t diff --git a/src/common/Exd/ExdDataGenerated.h b/src/common/Exd/ExdDataGenerated.h index 6eda3351..af2974ef 100644 --- a/src/common/Exd/ExdDataGenerated.h +++ b/src/common/Exd/ExdDataGenerated.h @@ -6127,7 +6127,7 @@ struct ZoneSharedGroup } catch( std::runtime_error error ) { - std::cout << error.what(); + // std::cout << error.what(); return nullptr; } return nullptr; diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index e028e136..72ff77f3 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -290,6 +290,7 @@ enum ActorControlType : uint16_t AchievementList = 0x3E9, RequestHousingBuildPreset = 0x44C, + RequestBuildPreset = 0x450, // no idea what this is, it gets sent with BuildPresetHandler and has the plot id in param1 RequestLandSignFree = 0x451, RequestLandSignOwned = 0x452, RequestWardLandInfo = 0x453, diff --git a/src/servers/Scripts/common/GilShop.cpp b/src/servers/Scripts/common/GilShop.cpp index e6c988ea..6554ca72 100644 --- a/src/servers/Scripts/common/GilShop.cpp +++ b/src/servers/Scripts/common/GilShop.cpp @@ -1,6 +1,9 @@ #include #include +#include +#include + using namespace Core; class GilShop : @@ -16,11 +19,11 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { - player.playScene( eventId, 0, SCENE_FLAGS, 0, 2, shopCallback ); + player.playScene( eventId, 0, SCENE_FLAGS, 0, 2, std::bind( &GilShop::shopCallback, this, std::placeholders::_1, std::placeholders::_2 ) ); } private: - static void shopInteractionCallback( Entity::Player& player, const Event::SceneResult& result ) + void shopInteractionCallback( Entity::Player& player, const Event::SceneResult& result ) { // item purchase if( result.param1 == 768 ) @@ -28,17 +31,20 @@ private: // buy if( result.param2 == 1 ) { + auto shopMgr = getFramework()->get< Sapphire::World::Manager::ShopMgr >(); + shopMgr->purchaseGilShopItem( player, result.eventId, result.param3, result.param4 ); } - // sell + // sell else if( result.param2 == 2 ) { - + // so apparently shops will always show a sell window + // BUT won't always let you sell stuff (eg, housing permit menu) + // there doesn't seem to be anything in gilshop exd for that, so maybe it's some shitty server hack? } - player.sendDebug( "got tradeQuantity: " + std::to_string( result.param4 ) ); - player.playGilShop( result.eventId, SCENE_FLAGS, shopInteractionCallback ); + player.playGilShop( result.eventId, SCENE_FLAGS, std::bind( &GilShop::shopInteractionCallback, this, std::placeholders::_1, std::placeholders::_2 ) ); return; } @@ -46,8 +52,8 @@ private: player.playScene( result.eventId, 255, SCENE_FLAGS ); } - static void shopCallback( Entity::Player& player, const Event::SceneResult& result ) + void shopCallback( Entity::Player& player, const Event::SceneResult& result ) { - player.playGilShop( result.eventId, SCENE_FLAGS, shopInteractionCallback ); + player.playGilShop( result.eventId, SCENE_FLAGS, std::bind( &GilShop::shopInteractionCallback, this, std::placeholders::_1, std::placeholders::_2 ) ); } }; \ No newline at end of file diff --git a/src/servers/sapphire_zone/Manager/ShopMgr.cpp b/src/servers/sapphire_zone/Manager/ShopMgr.cpp new file mode 100644 index 00000000..78173a1f --- /dev/null +++ b/src/servers/sapphire_zone/Manager/ShopMgr.cpp @@ -0,0 +1,34 @@ +#include "ShopMgr.h" + +#include +#include +#include +#include + +extern Core::Framework g_fw; +using namespace Core; + +bool Sapphire::World::Manager::ShopMgr::purchaseGilShopItem( Entity::Player& player, uint32_t shopId, uint16_t itemId, uint32_t quantity ) +{ + auto exdData = g_fw.get< Data::ExdDataGenerated >(); + if( !exdData ) + return false; + + auto gilShopItem = exdData->get< Data::GilShopItem >( shopId, itemId ); + if( !gilShopItem ) + return false; + + auto item = exdData->get< Data::Item >( gilShopItem->item ); + if( !item ) + return false; + + if( player.getCurrency( Common::CurrencyType::Gil ) < item->priceMid ) + return false; + + if( !player.addItem( gilShopItem->item, quantity ) ) + return false; + + player.removeCurrency( Common::CurrencyType::Gil, item->priceMid ); + + return true; +} \ No newline at end of file diff --git a/src/servers/sapphire_zone/Manager/ShopMgr.h b/src/servers/sapphire_zone/Manager/ShopMgr.h new file mode 100644 index 00000000..8ec5de4d --- /dev/null +++ b/src/servers/sapphire_zone/Manager/ShopMgr.h @@ -0,0 +1,10 @@ +#include "ForwardsZone.h" + +namespace Sapphire::World::Manager +{ + class ShopMgr + { + public: + bool purchaseGilShopItem( Core::Entity::Player& player, uint32_t shopId, uint16_t itemId, uint32_t quantity ); + }; +} \ No newline at end of file diff --git a/src/servers/sapphire_zone/Network/Handlers/EventHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/EventHandlers.cpp index d6d77bb2..becbcdc5 100644 --- a/src/servers/sapphire_zone/Network/Handlers/EventHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/EventHandlers.cpp @@ -273,7 +273,9 @@ void Core::Network::GameConnection::eventHandlerShop( const Packets::FFXIVARR_PA " (0x" + Util::intToHexString( static_cast< uint64_t >( eventId & 0xFFFFFFF ), 8 ) + ")" ); player.sendDebug( "Calling: " + objName + "." + eventName ); - player.eventStart( 0, eventId, Event::EventHandler::UI, 0, packet.data().param ); + player.eventStart( player.getId(), eventId, Event::EventHandler::UI, 0, packet.data().param ); + + pScriptMgr->onTalk( player, player.getId(), eventId ); } diff --git a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp index c7604ba8..821b9b3d 100644 --- a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp @@ -673,40 +673,6 @@ void Core::Network::GameConnection::buildPresetHandler( const Core::Network::Pac { const auto packet = ZoneChannelPacket< Client::FFXIVIpcBuildPresetHandler >( inPacket ); - auto zone = player.getCurrentZone(); - auto plotNum = packet.data().plotNum; - auto preset = packet.data().itemId; - std::string landString = std::string( packet.data().stateString ); - auto hZone = std::dynamic_pointer_cast< HousingZone >( zone ); - - if( !hZone ) - return; - - auto pLand = hZone->getLand( plotNum ); - /* - if (!pLand) - player.sendDebug( "Something went wrong..." ); - - if( stateString.find( "Private" ) ) - { - pLand->setPreset( preset ); - pLand->setState( HouseState::privateHouse ); - pLand->UpdateLandDb(); - hZone->sendLandUpdate( plotNum ); - } - else if( stateString.find("Free") ) - { - pLand->setPreset( preset ); - pLand->setState( HouseState::fcHouse ); - pLand->UpdateLandDb(); - hZone->sendLandUpdate( plotNum ); - } - else - { - player.sendDebug( "You tried to build a preset on not supported land." ); - } - - auto pSuccessBuildingPacket = makeActorControl142( player.getId(), BuildPresetResponse, plotNum ); - - player.queuePacket( pSuccessBuildingPacket );*/ + auto pHousingMgr = g_fw.get< HousingMgr >(); + pHousingMgr->buildPresetEstate( player, packet.data().plotNum, packet.data().itemId ); } diff --git a/src/servers/sapphire_zone/Zone/HousingMgr.cpp b/src/servers/sapphire_zone/Zone/HousingMgr.cpp index c9d50ca0..8b52c753 100644 --- a/src/servers/sapphire_zone/Zone/HousingMgr.cpp +++ b/src/servers/sapphire_zone/Zone/HousingMgr.cpp @@ -273,3 +273,30 @@ void Core::HousingMgr::sendWardLandInfo( Entity::Player& player, uint8_t wardId, player.queuePacket( wardInfoPacket ); } +void Core::HousingMgr::buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetItem ) +{ + auto hZone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); + + if( !hZone ) + return; + + auto pLand = hZone->getLand( plotNum ); + if( !pLand ) + return; + + // todo: when doing FC houses, look up the type from the original purchase and check perms from FC and set state accordingly + if( pLand->getPlayerOwner() != player.getId() ) + return; + + // todo: check if permit is in inventory and remove one + + pLand->setPreset( presetItem ); + pLand->setState( HouseState::privateHouse ); + pLand->setLandType( LandType::Private ); + pLand->updateLandDb(); + hZone->sendLandUpdate( plotNum ); + + auto pSuccessBuildingPacket = makeActorControl142( player.getId(), ActorControl::BuildPresetResponse, plotNum ); + + player.queuePacket( pSuccessBuildingPacket ); +} diff --git a/src/servers/sapphire_zone/Zone/HousingMgr.h b/src/servers/sapphire_zone/Zone/HousingMgr.h index bc5d94d8..cacaa9c1 100644 --- a/src/servers/sapphire_zone/Zone/HousingMgr.h +++ b/src/servers/sapphire_zone/Zone/HousingMgr.h @@ -34,6 +34,8 @@ namespace Core bool relinquishLand( Entity::Player& player, uint8_t plot ); + void buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetItem ); + private: }; diff --git a/src/servers/sapphire_zone/Zone/Land.cpp b/src/servers/sapphire_zone/Zone/Land.cpp index c39701af..8488c139 100644 --- a/src/servers/sapphire_zone/Zone/Land.cpp +++ b/src/servers/sapphire_zone/Zone/Land.cpp @@ -79,7 +79,7 @@ void Core::Land::load() init(); } -uint16_t Core::Land::convertItemIdToHousingItemId( uint16_t itemId ) +uint32_t Core::Land::convertItemIdToHousingItemId( uint32_t itemId ) { auto pExdData = g_fw.get< Data::ExdDataGenerated >(); auto info = pExdData->get< Core::Data::Item >( itemId ); @@ -246,7 +246,7 @@ void Core::Land::updateLandDb() pDb->directExecute( "UPDATE land SET status = " + std::to_string( m_state ) + ", LandPrice = " + std::to_string( getCurrentPrice() ) + ", UpdateTime = " + std::to_string( getDevaluationTime() ) - + ", OwnerId = " + std::to_string( getPlayerOwner() ) + + ", OwnerId = " + std::to_string( getPlayerOwner() ) + ", HouseId = " + std::to_string( 0 ) //TODO: add house id + ", Type = " + std::to_string( static_cast< uint32_t >( m_type ) ) //TODO: add house id + " WHERE LandSetId = " + std::to_string( m_landSetId ) @@ -265,3 +265,15 @@ void Core::Land::update( uint32_t currTime ) } } } + +bool Core::Land::setPreset( uint32_t itemId ) +{ + auto housingItemId = convertItemIdToHousingItemId( itemId ); + + auto exdData = g_fw.get< Core::Data::ExdDataGenerated >(); + if( !exdData ) + return false; + + auto housingPreset = exdData->get< Core::Data::HousingPreset >( housingItemId ); + +} diff --git a/src/servers/sapphire_zone/Zone/Land.h b/src/servers/sapphire_zone/Zone/Land.h index 173a00a7..243ca62c 100644 --- a/src/servers/sapphire_zone/Zone/Land.h +++ b/src/servers/sapphire_zone/Zone/Land.h @@ -48,7 +48,7 @@ namespace Core uint32_t getPlayerOwner(); //Housing Functions void setCurrentPrice( uint32_t currentPrice ); - void setPreset( uint32_t itemId ); + bool setPreset( uint32_t itemId ); void updateLandDb(); void update( uint32_t currTime ); @@ -62,7 +62,7 @@ namespace Core uint8_t getLandTag( uint8_t slot ); private: - uint16_t convertItemIdToHousingItemId( uint16_t itemId ); + uint32_t convertItemIdToHousingItemId( uint32_t itemId ); void init(); uint8_t m_wardNum; diff --git a/src/servers/sapphire_zone/mainGameServer.cpp b/src/servers/sapphire_zone/mainGameServer.cpp index 489857b0..e6acc87d 100644 --- a/src/servers/sapphire_zone/mainGameServer.cpp +++ b/src/servers/sapphire_zone/mainGameServer.cpp @@ -12,6 +12,7 @@ #include "Zone/HousingMgr.h" #include "DebugCommand/DebugCommandHandler.h" #include "Manager/PlayerMgr.h" +#include "Manager/ShopMgr.h" #include @@ -32,6 +33,7 @@ bool setupFramework() auto pDebugCom = std::make_shared< DebugCommandHandler >(); auto pConfig = std::make_shared< ConfigMgr >(); auto pPlayerMgr = std::make_shared< Sapphire::World::Manager::PlayerMgr >(); + auto pShopMgr = std::make_shared< Sapphire::World::Manager::ShopMgr >(); pLogger->setLogPath( "log/SapphireZone" ); pLogger->init(); @@ -47,6 +49,7 @@ bool setupFramework() g_fw.set< DebugCommandHandler >( pDebugCom ); g_fw.set< ConfigMgr >( pConfig ); g_fw.set< Sapphire::World::Manager::PlayerMgr >( pPlayerMgr ); + g_fw.set< Sapphire::World::Manager::ShopMgr >( pShopMgr ); // actuall catch errors here... return true;