1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-02 08:57:44 +00:00

Merge branch 'housing' of https://github.com/SapphireMordred/Sapphire into housing

This commit is contained in:
mordred 2018-11-25 16:46:02 +01:00
commit 974e3a5356
28 changed files with 1873 additions and 673 deletions

View file

@ -2,7 +2,7 @@
#include "bparse.h" #include "bparse.h"
#include "stream.h" #include "stream.h"
#include <fstream>
#include "Exh.h" #include "Exh.h"
using xiv::utils::bparse::extract; using xiv::utils::bparse::extract;
@ -58,7 +58,7 @@ namespace xiv
for ( auto &file_ptr : _files ) for ( auto &file_ptr : _files )
{ {
// Get a stream // Get a stream
std::vector< char > dataCpy = file_ptr->get_data_sections().front(); std::vector< char > dataCpy = file_ptr->get_data_sections().front();
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) ); std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
// Extract the header and skip to the record indices // Extract the header and skip to the record indices
@ -101,12 +101,17 @@ namespace xiv
iss.seekg( cacheEntryIt->second.offset + 6 ); iss.seekg( cacheEntryIt->second.offset + 6 );
uint8_t subRows = *reinterpret_cast< uint8_t* >( &dataCpy[ cacheEntryIt->second.offset + 5 ] ); uint8_t subRows = *reinterpret_cast< uint8_t* >( &dataCpy[ cacheEntryIt->second.offset + 5 ] );
if( subRow >= subRows )
throw std::runtime_error( "Out of bounds sub-row!" );
int offset = cacheEntryIt->second.offset + 6 + ( subRow * _exh->get_header().data_offset + 2 * ( subRow + 1 ) );
for( auto& member_entry : _exh->get_exh_members() ) for( auto& member_entry : _exh->get_exh_members() )
{ {
// Seek to the position of the member to extract. // Seek to the position of the member to extract.
// 6 is because we have uint32_t/uint16_t at the start of each record // 6 is because we have uint32_t/uint16_t at the start of each record
iss.seekg( cacheEntryIt->second.offset + 6 + member_entry.offset ); iss.seekg( offset + member_entry.offset );
// Switch depending on the type to extract // Switch depending on the type to extract
switch( member_entry.type ) switch( member_entry.type )
@ -115,9 +120,10 @@ namespace xiv
// Extract the offset to the actual string // Extract the offset to the actual string
// Seek to it then extract the actual string // Seek to it then extract the actual string
{ {
auto string_offset = extract<uint32_t>( iss, "string_offset", false ); throw std::runtime_error( "String not implemented for variant 2!" );
iss.seekg( cacheEntryIt->second.offset + 6 + _exh->get_header().data_offset + string_offset ); //auto string_offset = extract<uint32_t>( iss, "string_offset", false );
fields.emplace_back( utils::bparse::extract_cstring( iss, "string" ) ); //iss.seekg( cacheEntryIt->second.offset + 6 + _exh->get_header().data_offset + string_offset );
//fields.emplace_back( utils::bparse::extract_cstring( iss, "string" ) );
} }
break; break;
@ -129,9 +135,18 @@ namespace xiv
fields.emplace_back( extract<int8_t>( iss, "int8_t" ) ); fields.emplace_back( extract<int8_t>( iss, "int8_t" ) );
break; break;
case DataType::uint8:
fields.emplace_back( extract<uint8_t>( iss, "uint8_t" ) );
break;
case DataType::int16: case DataType::int16:
fields.emplace_back( extract<int16_t>( iss, "int16_t", false ) ); fields.emplace_back( extract<int16_t>( iss, "int16_t", false ) );
break; break;
case DataType::uint16:
fields.emplace_back( extract<uint16_t>( iss, "uint16_t", false ) );
break;
case DataType::int32: case DataType::int32:
fields.emplace_back( extract<int32_t>( iss, "int32_t", false ) ); fields.emplace_back( extract<int32_t>( iss, "int32_t", false ) );
break; break;
@ -184,7 +199,7 @@ namespace xiv
fields.reserve( member_count ); fields.reserve( member_count );
iss.seekg( cacheEntryIt->second.offset + 6 ); iss.seekg( cacheEntryIt->second.offset + 6 );
uint8_t subRows = *reinterpret_cast< uint8_t* >( &dataCpy[ cacheEntryIt->second.offset + 5 ] ); uint8_t subRows = *reinterpret_cast< uint8_t* >( &dataCpy[ cacheEntryIt->second.offset + 5 ] );
for( auto& member_entry : _exh->get_exh_members() ) for( auto& member_entry : _exh->get_exh_members() )
{ {

View file

@ -31,9 +31,9 @@ namespace xiv
uint16_t field_count; uint16_t field_count;
uint16_t exd_count; uint16_t exd_count;
uint16_t language_count; uint16_t language_count;
uint16_t unknown1; uint16_t unknown1;
uint8_t u2; uint8_t u2;
uint8_t variant; uint8_t variant;
}; };
struct ExhMember struct ExhMember

View file

@ -805,8 +805,8 @@ namespace Core::Common
none, none,
forSale, forSale,
sold, sold,
privateHouse,
fcHouse, fcHouse,
privateHouse
}; };
enum HouseIconAdd : uint8_t enum HouseIconAdd : uint8_t

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -290,6 +290,8 @@ enum ActorControlType : uint16_t
AchievementList = 0x3E9, AchievementList = 0x3E9,
RequestHousingBuildPreset = 0x44C, RequestHousingBuildPreset = 0x44C,
RequestEstateHallRemoval = 0x44F,
RequestBuildPreset = 0x450, // no idea what this is, it gets sent with BuildPresetHandler and has the plot id in param1
RequestLandSignFree = 0x451, RequestLandSignFree = 0x451,
RequestLandSignOwned = 0x452, RequestLandSignOwned = 0x452,
RequestWardLandInfo = 0x453, RequestWardLandInfo = 0x453,

View file

@ -1,6 +1,9 @@
#include <ScriptObject.h> #include <ScriptObject.h>
#include <Actor/Player.h> #include <Actor/Player.h>
#include <Framework.h>
#include <Manager/ShopMgr.h>
using namespace Core; using namespace Core;
class GilShop : class GilShop :
@ -16,11 +19,11 @@ public:
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override 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: private:
static void shopInteractionCallback( Entity::Player& player, const Event::SceneResult& result ) void shopInteractionCallback( Entity::Player& player, const Event::SceneResult& result )
{ {
// item purchase // item purchase
if( result.param1 == 768 ) if( result.param1 == 768 )
@ -28,17 +31,19 @@ private:
// buy // buy
if( result.param2 == 1 ) 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 ) // can't sell if the vendor is yourself (eg, housing permit shop)
else if( result.param2 == 2 && result.actorId != player.getId() )
{ {
} }
player.sendDebug( "got tradeQuantity: " + std::to_string( result.param4 ) ); player.playGilShop( result.eventId, SCENE_FLAGS, std::bind( &GilShop::shopInteractionCallback, this, std::placeholders::_1, std::placeholders::_2 ) );
player.playGilShop( result.eventId, SCENE_FLAGS, shopInteractionCallback );
return; return;
} }
@ -46,8 +51,8 @@ private:
player.playScene( result.eventId, 255, SCENE_FLAGS ); 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 ) );
} }
}; };

View file

@ -61,7 +61,8 @@ public:
if( !warp ) if( !warp )
return; return;
player.eventStart( actorId, warp->defaultTalk1, Event::EventHandler::Nest, 0, 0, std::bind( &WarpTaxi::inner2, this, std::placeholders::_1, std::placeholders::_2 ) ); player.eventStart( actorId, warp->conditionSuccessEvent, Event::EventHandler::Nest, 0, 0,
player.playScene( warp->defaultTalk1, 0, HIDE_HOTBAR, 0, 0, 7, nullptr ); std::bind( &WarpTaxi::inner2, this, std::placeholders::_1, std::placeholders::_2 ) );
player.playScene( warp->conditionSuccessEvent, 0, HIDE_HOTBAR, 0, 0, 7, nullptr );
} }
}; };

View file

@ -1580,7 +1580,7 @@ void Core::Entity::Player::sendZonePackets()
auto pHousingMgr = g_fw.get< HousingMgr >(); auto pHousingMgr = g_fw.get< HousingMgr >();
if( Core::LandPtr pLand = pHousingMgr->getLandByOwnerId( getId() ) ) if( Core::LandPtr pLand = pHousingMgr->getLandByOwnerId( getId() ) )
{ {
setLandPermissions( LandPermissionSlot::Private, 0x00, pLand->getLandId(), pLand->getWardNum(), pLand->getZoneId() ); setLandPermissions( LandPermissionSlot::Private, 0x00, pLand->getLandId(), pLand->getWardNum(), pLand->getTerritoryTypeId() );
} }
sendLandPermissions(); sendLandPermissions();

View file

@ -8,6 +8,7 @@ namespace Core::Event
struct SceneResult struct SceneResult
{ {
uint64_t actorId;
uint32_t eventId; uint32_t eventId;
uint16_t param1; uint16_t param1;
uint16_t param2; uint16_t param2;

View file

@ -0,0 +1,34 @@
#include "ShopMgr.h"
#include <Framework.h>
#include <Exd/ExdDataGenerated.h>
#include <Actor/Player.h>
#include <Common.h>
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;
}

View file

@ -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 );
};
}

View file

@ -321,6 +321,10 @@ void Core::Network::GameConnection::processOutQueue()
pRP.addPacket( pPacket ); pRP.addPacket( pPacket );
totalSize += pPacket->getSize(); totalSize += pPacket->getSize();
// todo: figure out a good max set size and make it configurable
if( totalSize > 15000 )
break;
} }
if( totalSize > 0 ) if( totalSize > 0 )

View file

@ -77,7 +77,7 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::FFXIVARR_PACK
if( !cfCondition ) if( !cfCondition )
return; return;
auto instance = pTeriMgr->createInstanceContent( cfCondition->instanceContent ); auto instance = pTeriMgr->createInstanceContent( cfCondition->content );
if( !instance ) if( !instance )
return; return;

View file

@ -221,6 +221,7 @@ void Core::Network::GameConnection::eventHandlerReturn( const Packets::FFXIVARR_
if( eventCallback ) if( eventCallback )
{ {
Event::SceneResult result; Event::SceneResult result;
result.actorId = pEvent->getActorId();
result.eventId = eventId; result.eventId = eventId;
result.param1 = param1; result.param1 = param1;
result.param2 = param2; result.param2 = param2;
@ -273,7 +274,9 @@ void Core::Network::GameConnection::eventHandlerShop( const Packets::FFXIVARR_PA
" (0x" + Util::intToHexString( static_cast< uint64_t >( eventId & 0xFFFFFFF ), 8 ) + ")" ); " (0x" + Util::intToHexString( static_cast< uint64_t >( eventId & 0xFFFFFFF ), 8 ) + ")" );
player.sendDebug( "Calling: " + objName + "." + eventName ); 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 );
} }

View file

@ -673,40 +673,6 @@ void Core::Network::GameConnection::buildPresetHandler( const Core::Network::Pac
{ {
const auto packet = ZoneChannelPacket< Client::FFXIVIpcBuildPresetHandler >( inPacket ); const auto packet = ZoneChannelPacket< Client::FFXIVIpcBuildPresetHandler >( inPacket );
auto zone = player.getCurrentZone(); auto pHousingMgr = g_fw.get< HousingMgr >();
auto plotNum = packet.data().plotNum; pHousingMgr->buildPresetEstate( player, packet.data().plotNum, packet.data().itemId );
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 );*/
} }

View file

@ -3,6 +3,7 @@
#include <Logging/Logger.h> #include <Logging/Logger.h>
#include <Exd/ExdDataGenerated.h> #include <Exd/ExdDataGenerated.h>
#include <Database/DatabaseDef.h>
#include "House.h" #include "House.h"
@ -20,6 +21,18 @@ Core::House::House( uint32_t houseId, uint32_t landSetId, uint8_t landId, uint8_
{ {
memset( &m_houseParts, 0x00, sizeof( m_houseParts ) ); memset( &m_houseParts, 0x00, sizeof( m_houseParts ) );
memset( &m_commentMsg, 0x00, sizeof( m_commentMsg ) ); memset( &m_commentMsg, 0x00, sizeof( m_commentMsg ) );
auto pDB = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >();
auto res = pDB->query("SELECT * FROM house WHERE HouseId = " + std::to_string( houseId ) );
if( !res->next() )
{
pDB->directExecute("INSERT INTO house ( LandSetId, HouseId ) VALUES ( " + std::to_string( m_landSetId ) + ", " + std::to_string( m_houseId ) + " )" );
}
else
{
// todo
}
} }
Core::House::~House() Core::House::~House()
@ -70,4 +83,4 @@ void Core::House::setHousePartColor( Common::HousePartSlot slot, uint32_t id )
uint32_t Core::House::getHousePart( Common::HousePartSlot slot ) const uint32_t Core::House::getHousePart( Common::HousePartSlot slot ) const
{ {
return m_houseParts[ slot ]; return m_houseParts[ slot ];
} }

View file

@ -98,7 +98,7 @@ void Core::HousingMgr::sendLandSignOwned( Entity::Player& player, uint8_t wardId
memcpy( &landInfoSignPacket->data().ownerName, playerName.c_str(), playerName.size() ); memcpy( &landInfoSignPacket->data().ownerName, playerName.c_str(), playerName.size() );
landInfoSignPacket->data().wardNum = land->getWardNum(); landInfoSignPacket->data().wardNum = land->getWardNum();
landInfoSignPacket->data().worldId = 67; landInfoSignPacket->data().worldId = 67;
landInfoSignPacket->data().zoneId = land->getZoneId(); landInfoSignPacket->data().zoneId = land->getTerritoryTypeId();
player.queuePacket( landInfoSignPacket ); player.queuePacket( landInfoSignPacket );
} }
@ -273,3 +273,32 @@ void Core::HousingMgr::sendWardLandInfo( Entity::Player& player, uint8_t wardId,
player.queuePacket( wardInfoPacket ); 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
if( !pLand->setPreset( presetItem ) )
return;
pLand->setState( HouseState::privateHouse );
pLand->setLandType( LandType::Private );
pLand->updateLandDb();
hZone->sendLandUpdate( plotNum );
auto pSuccessBuildingPacket = makeActorControl142( player.getId(), ActorControl::BuildPresetResponse, plotNum );
player.queuePacket( pSuccessBuildingPacket );
}

View file

@ -34,6 +34,8 @@ namespace Core
bool relinquishLand( Entity::Player& player, uint8_t plot ); bool relinquishLand( Entity::Player& player, uint8_t plot );
void buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetItem );
private: private:
}; };

View file

@ -10,6 +10,7 @@
#include "Actor/Player.h" #include "Actor/Player.h"
#include "Actor/Actor.h" #include "Actor/Actor.h"
#include "Land.h" #include "Land.h"
#include "House.h"
#include "Forwards.h" #include "Forwards.h"
#include "HousingZone.h" #include "HousingZone.h"
@ -149,12 +150,24 @@ void Core::HousingZone::sendLandUpdate( uint8_t landId )
landUpdatePacket->data().landId = landId; landUpdatePacket->data().landId = landId;
landUpdatePacket->data().land.plotSize = pLand->getSize(); landUpdatePacket->data().land.plotSize = pLand->getSize();
landUpdatePacket->data().land.houseState = pLand->getState(); landUpdatePacket->data().land.houseState = pLand->getState();
landUpdatePacket->data().land.type = static_cast< uint8_t >( pLand->getLandType() ); landUpdatePacket->data().land.type = 0;
landUpdatePacket->data().land.iconAddIcon = pLand->getSharing(); landUpdatePacket->data().land.iconAddIcon = pLand->getSharing();
landUpdatePacket->data().land.fcId = pLand->getFcId(); landUpdatePacket->data().land.fcId = pLand->getFcId();
landUpdatePacket->data().land.fcIcon = pLand->getFcIcon(); landUpdatePacket->data().land.fcIcon = pLand->getFcIcon();
landUpdatePacket->data().land.fcIconColor = pLand->getFcColor(); landUpdatePacket->data().land.fcIconColor = pLand->getFcColor();
if( auto house = pLand->getHouse() )
{
// todo: this is retarded, need a getter to the internal array
for( int i = 0; i < 8; i++ )
{
auto slot = static_cast< Common::HousePartSlot >( i );
auto part = pLand->getHouse()->getHousePart( slot );
landUpdatePacket->data().land.housePart[ slot ] = part;
}
}
pPlayer->queuePacket( landUpdatePacket ); pPlayer->queuePacket( landUpdatePacket );
} }
} }

View file

@ -20,14 +20,15 @@
#include "Forwards.h" #include "Forwards.h"
#include "Land.h" #include "Land.h"
#include "Framework.h" #include "Framework.h"
#include "House.h"
extern Core::Framework g_fw; extern Core::Framework g_fw;
using namespace Core::Common; using namespace Core::Common;
Core::Land::Land( uint16_t zoneId, uint8_t wardNum, uint8_t landId, uint32_t landSetId, Core::Land::Land( uint16_t territoryTypeId, uint8_t wardNum, uint8_t landId, uint32_t landSetId,
Core::Data::HousingLandSetPtr info ) : Core::Data::HousingLandSetPtr info ) :
m_zoneId( zoneId ), m_territoryTypeId( territoryTypeId ),
m_wardNum( wardNum ), m_wardNum( wardNum ),
m_landId( landId ), m_landId( landId ),
m_currentPrice( 0 ), m_currentPrice( 0 ),
@ -36,7 +37,11 @@ Core::Land::Land( uint16_t zoneId, uint8_t wardNum, uint8_t landId, uint32_t lan
m_ownerPlayerId( 0 ), m_ownerPlayerId( 0 ),
m_landSetId( landSetId ), m_landSetId( landSetId ),
m_landInfo( info ), m_landInfo( info ),
m_type( Common::LandType::Private ) m_type( Common::LandType::none ),
m_fcIcon( 0 ),
m_fcIconColor( 0 ),
m_fcId( 0 ),
m_iconAddIcon( 0 )
{ {
memset( &m_tag, 0x00, 3 ); memset( &m_tag, 0x00, 3 );
@ -55,15 +60,15 @@ void Core::Land::load()
"AND LandId = " + std::to_string( m_landId ) ); "AND LandId = " + std::to_string( m_landId ) );
if( !res->next() ) if( !res->next() )
{ {
pDb->directExecute( "INSERT INTO land ( landsetid, landid, type, size, status, landprice ) " pDb->directExecute( "INSERT INTO land ( landsetid, landid, type, size, status, landprice, UpdateTime, OwnerId, HouseId ) "
"VALUES ( " + std::to_string( m_landSetId ) + "," + std::to_string( m_landId ) + "," "VALUES ( " + std::to_string( m_landSetId ) + "," + std::to_string( m_landId ) + ","
+ std::to_string( static_cast< uint8_t >( m_type ) ) + "," + std::to_string( static_cast< uint8_t >( m_type ) ) + ","
+ std::to_string( m_landInfo->sizes[ m_landId ] ) + "," + std::to_string( m_landInfo->plotSize[ m_landId ] ) + ","
+ " 1, " + std::to_string( m_landInfo->prices[ m_landId ] ) + " );" ); + " 1, " + std::to_string( m_landInfo->initialPrice[ m_landId ] ) + ", 0, 0, 0 );" );
m_currentPrice = m_landInfo->prices[ m_landId ]; m_currentPrice = m_landInfo->initialPrice[ m_landId ];
m_minPrice = m_landInfo->minPrices[ m_landId ]; m_minPrice = m_landInfo->minPrice[ m_landId ];
m_size = m_landInfo->sizes[ m_landId ]; m_size = m_landInfo->plotSize[ m_landId ];
m_state = HouseState::forSale; m_state = HouseState::forSale;
} }
else else
@ -73,13 +78,13 @@ void Core::Land::load()
m_state = res->getUInt( "Status" ); m_state = res->getUInt( "Status" );
m_currentPrice = res->getUInt( "LandPrice" ); m_currentPrice = res->getUInt( "LandPrice" );
m_ownerPlayerId = res->getUInt( "OwnerId" ); m_ownerPlayerId = res->getUInt( "OwnerId" );
m_minPrice = m_landInfo->minPrices[ m_landId ]; m_minPrice = m_landInfo->minPrice[ m_landId ];
m_maxPrice = m_landInfo->prices[ m_landId ]; m_maxPrice = m_landInfo->initialPrice[ m_landId ];
} }
init(); 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 pExdData = g_fw.get< Data::ExdDataGenerated >();
auto info = pExdData->get< Core::Data::Item >( itemId ); auto info = pExdData->get< Core::Data::Item >( itemId );
@ -147,9 +152,9 @@ uint8_t Core::Land::getLandId() const
return m_landId; return m_landId;
} }
uint16_t Core::Land::getZoneId() const uint16_t Core::Land::getTerritoryTypeId() const
{ {
return m_zoneId; return m_territoryTypeId;
} }
Core::HousePtr Core::Land::getHouse() const Core::HousePtr Core::Land::getHouse() const
@ -242,12 +247,17 @@ void Core::Land::init()
void Core::Land::updateLandDb() void Core::Land::updateLandDb()
{ {
uint32_t houseId = 0;
if( getHouse() )
houseId = getHouse()->getHouseId();
auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >();
pDb->directExecute( "UPDATE land SET status = " + std::to_string( m_state ) pDb->directExecute( "UPDATE land SET status = " + std::to_string( m_state )
+ ", LandPrice = " + std::to_string( getCurrentPrice() ) + ", LandPrice = " + std::to_string( getCurrentPrice() )
+ ", UpdateTime = " + std::to_string( getDevaluationTime() ) + ", UpdateTime = " + std::to_string( getDevaluationTime() )
+ ", OwnerId = " + std::to_string( getPlayerOwner() ) + ", OwnerId = " + std::to_string( getPlayerOwner() )
+ ", HouseId = " + std::to_string( 0 ) //TODO: add house id + ", HouseId = " + std::to_string( houseId )
+ ", Type = " + std::to_string( static_cast< uint32_t >( m_type ) ) //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 ) + " WHERE LandSetId = " + std::to_string( m_landSetId )
+ " AND LandId = " + std::to_string( m_landId ) + ";" ); + " AND LandId = " + std::to_string( m_landId ) + ";" );
@ -265,3 +275,41 @@ void Core::Land::update( uint32_t currTime )
} }
} }
} }
uint32_t Core::Land::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->getUInt( 1 ) + 1;
}
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 );
if( !housingPreset )
return false;
if( !getHouse() )
{
// todo: i guess we'd create a house here?
auto newId = getNextHouseId();
m_pHouse = make_House( newId, getLandSetId(), getLandId(), getWardNum(), getTerritoryTypeId() );
}
getHouse()->setHousePart( Common::HousePartSlot::ExteriorRoof, housingPreset->exteriorRoof );
getHouse()->setHousePart( Common::HousePartSlot::ExteriorWall, housingPreset->exteriorWall );
getHouse()->setHousePart( Common::HousePartSlot::ExteriorWindow, housingPreset->exteriorWindow );
getHouse()->setHousePart( Common::HousePartSlot::ExteriorDoor, housingPreset->exteriorDoor );
return true;
}

View file

@ -33,7 +33,7 @@ namespace Core
uint32_t getLandSetId() const; uint32_t getLandSetId() const;
uint8_t getWardNum() const; uint8_t getWardNum() const;
uint8_t getLandId() const; uint8_t getLandId() const;
uint16_t getZoneId() const; uint16_t getTerritoryTypeId() const;
Common::LandType getLandType() const; Common::LandType getLandType() const;
Core::HousePtr getHouse() const; Core::HousePtr getHouse() const;
@ -48,7 +48,7 @@ namespace Core
uint32_t getPlayerOwner(); uint32_t getPlayerOwner();
//Housing Functions //Housing Functions
void setCurrentPrice( uint32_t currentPrice ); void setCurrentPrice( uint32_t currentPrice );
void setPreset( uint32_t itemId ); bool setPreset( uint32_t itemId );
void updateLandDb(); void updateLandDb();
void update( uint32_t currTime ); void update( uint32_t currTime );
@ -62,13 +62,14 @@ namespace Core
uint8_t getLandTag( uint8_t slot ); uint8_t getLandTag( uint8_t slot );
private: private:
uint16_t convertItemIdToHousingItemId( uint16_t itemId ); uint32_t convertItemIdToHousingItemId( uint32_t itemId );
void init(); void init();
uint32_t getNextHouseId();
uint8_t m_wardNum; uint8_t m_wardNum;
uint8_t m_landId; uint8_t m_landId;
uint32_t m_landSetId; uint32_t m_landSetId;
uint16_t m_zoneId; uint16_t m_territoryTypeId;
uint8_t m_size; uint8_t m_size;
uint8_t m_state; uint8_t m_state;
Common::LandType m_type; Common::LandType m_type;

View file

@ -249,7 +249,7 @@ Core::ZonePtr Core::TerritoryMgr::createInstanceContent( uint32_t contentFinderC
auto pContentFinderCondition = pExdData->get< Core::Data::ContentFinderCondition >( contentFinderConditionId ); auto pContentFinderCondition = pExdData->get< Core::Data::ContentFinderCondition >( contentFinderConditionId );
if( !pContentFinderCondition ) if( !pContentFinderCondition )
return nullptr; return nullptr;
auto instanceContentId = pContentFinderCondition->instanceContent; auto instanceContentId = pContentFinderCondition->content;
auto pInstanceContent = pExdData->get< Core::Data::InstanceContent >( instanceContentId ); auto pInstanceContent = pExdData->get< Core::Data::InstanceContent >( instanceContentId );
if( !pInstanceContent ) if( !pInstanceContent )

View file

@ -12,6 +12,7 @@
#include "Zone/HousingMgr.h" #include "Zone/HousingMgr.h"
#include "DebugCommand/DebugCommandHandler.h" #include "DebugCommand/DebugCommandHandler.h"
#include "Manager/PlayerMgr.h" #include "Manager/PlayerMgr.h"
#include "Manager/ShopMgr.h"
#include <Config/ConfigMgr.h> #include <Config/ConfigMgr.h>
@ -32,6 +33,7 @@ bool setupFramework()
auto pDebugCom = std::make_shared< DebugCommandHandler >(); auto pDebugCom = std::make_shared< DebugCommandHandler >();
auto pConfig = std::make_shared< ConfigMgr >(); auto pConfig = std::make_shared< ConfigMgr >();
auto pPlayerMgr = std::make_shared< Sapphire::World::Manager::PlayerMgr >(); auto pPlayerMgr = std::make_shared< Sapphire::World::Manager::PlayerMgr >();
auto pShopMgr = std::make_shared< Sapphire::World::Manager::ShopMgr >();
pLogger->setLogPath( "log/SapphireZone" ); pLogger->setLogPath( "log/SapphireZone" );
pLogger->init(); pLogger->init();
@ -47,6 +49,7 @@ bool setupFramework()
g_fw.set< DebugCommandHandler >( pDebugCom ); g_fw.set< DebugCommandHandler >( pDebugCom );
g_fw.set< ConfigMgr >( pConfig ); g_fw.set< ConfigMgr >( pConfig );
g_fw.set< Sapphire::World::Manager::PlayerMgr >( pPlayerMgr ); g_fw.set< Sapphire::World::Manager::PlayerMgr >( pPlayerMgr );
g_fw.set< Sapphire::World::Manager::ShopMgr >( pShopMgr );
// actuall catch errors here... // actuall catch errors here...
return true; return true;

View file

@ -36,8 +36,8 @@ bool Core::Data::ExdDataGenerated::init( const std::string& path )
{ {
try try
{ {
m_data = boost::make_shared< xiv::dat::GameData >( path ); m_data = std::make_shared< xiv::dat::GameData >( path );
m_exd_data = boost::make_shared< xiv::exd::ExdData >( *m_data ); m_exd_data = std::make_shared< xiv::exd::ExdData >( *m_data );
SETUPDATACCESS SETUPDATACCESS
} }

View file

@ -11,7 +11,7 @@
#include <ExdCat.h> #include <ExdCat.h>
#include <Exd.h> #include <Exd.h>
#include <set> #include <set>
#include <boost/make_shared.hpp> #include <variant>
namespace Core { namespace Core {
namespace Data { namespace Data {
@ -35,13 +35,13 @@ STRUCTS
template< class T > template< class T >
T getField( std::vector< xiv::exd::Field >& fields, uint32_t index ) T getField( std::vector< xiv::exd::Field >& fields, uint32_t index )
{ {
return *boost::get< T >( &fields.at( index ) ); return std::get< T >( fields.at( index ) );
} }
void loadIdList( xiv::exd::Exd& data, std::set< uint32_t >& outIdList ); void loadIdList( xiv::exd::Exd& data, std::set< uint32_t >& outIdList );
boost::shared_ptr< xiv::dat::GameData > m_data; std::shared_ptr< xiv::dat::GameData > m_data;
boost::shared_ptr< xiv::exd::ExdData > m_exd_data; std::shared_ptr< xiv::exd::ExdData > m_exd_data;
DATACCESS DATACCESS

View file

@ -45,8 +45,8 @@ std::vector< std::string > cppKeyWords
"class" "class"
}; };
std::string datLocation( "/home/mordred/sqpack" ); //std::string datLocation( "/home/mordred/sqpack" );
//std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" ); std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
std::map< uint8_t, std::string > g_typeMap; std::map< uint8_t, std::string > g_typeMap;

View file

@ -21,8 +21,8 @@ Core::Logger g_log;
Core::Data::ExdDataGenerated g_exdData; Core::Data::ExdDataGenerated g_exdData;
const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" ); //const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
//const std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" ); const std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
int main() int main()
@ -38,15 +38,20 @@ int main()
} }
g_log.info( "getting id list " ); //g_log.info( "getting id list " );
auto idList = g_exdData.getTerritoryTypeIdList(); //auto idList = g_exdData.getGilShopIdList();
g_log.info( "getting id list done" ); //g_log.info( "getting id list done" );
for( auto id : idList ) //for( auto id : idList )
{ {
auto teri1 = g_exdData.get< Core::Data::TerritoryType >( id ); auto teri1 = g_exdData.get< Core::Data::GilShopItem >( 262440, 0 );
g_log.info( "0 -> " + std::to_string( teri1->item ) );
g_log.info( teri1->name ); auto teri2 = g_exdData.get< Core::Data::GilShopItem >( 262440, 1 );
g_log.info( "1 -> " + std::to_string( teri2->item ) );
auto teri3 = g_exdData.get< Core::Data::GilShopItem >( 262440, 2 );
g_log.info( "2 -> " + std::to_string( teri3->item ) );
} }
return 0; return 0;