1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-26 14:37:44 +00:00

Merge pull request #447 from NotAdam/housing

More housing and gilshop fix
This commit is contained in:
Mordred 2018-12-04 19:31:09 +01:00 committed by GitHub
commit b0f265bd9f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 118 additions and 41 deletions

View file

@ -0,0 +1,9 @@
CREATE TABLE `houseiteminventory` (
`landIdent` BIGINT(20) UNSIGNED NOT NULL,
`containerId` INT(10) UNSIGNED NOT NULL,
`itemId` INT(20) NOT NULL,
INDEX `landIdent` (`landIdent`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;

View file

@ -221,7 +221,11 @@ namespace Sapphire::Common
FreeCompanyBag2 = 20002,
FreeCompanyGil = 22000,
FreeCompanyCrystal = 22001,
HousingOutdoorItems = 25001
HousingExternalAppearance = 25000,
HousingOutdoorItemStoreroom = 25001,
HousingInternalAppearance = 25002,
HousingIndoorItemStoreroom = 25003,
};
enum ContainerType : uint16_t
@ -823,9 +827,9 @@ namespace Sapphire::Common
enum HouseSize : uint8_t
{
small,
medium,
big
Cottage,
House,
Mansion
};
enum HouseState : uint8_t
@ -861,7 +865,7 @@ namespace Sapphire::Common
{
IsEstateOwned = 1,
IsPublicEstate = 2,
HasEstateMessage = 4,
HasEstateGreeting = 4,
EstateFlagUnknown = 8,
IsFreeCompanyEstate = 16,
};

View file

@ -244,6 +244,9 @@ void Sapphire::World::Manager::HousingMgr::sendWardLandInfo( Entity::Player& pla
wardInfoPacket->data().landIdent.wardNum = wardId;
wardInfoPacket->data().landIdent.territoryTypeId = territoryTypeId;
// todo: properly get worldId
wardInfoPacket->data().landIdent.worldId = 67;
for( int i = 0; i < 60; i++ )
{
auto land = hZone->getLand( i );
@ -258,20 +261,26 @@ void Sapphire::World::Manager::HousingMgr::sendWardLandInfo( Entity::Player& pla
if( land->getState() == Common::HouseState::forSale )
continue;
if( auto house = land->getHouse() )
{
if( !house->getHouseGreeting().empty() )
entry.infoFlags |= WardlandFlags::HasEstateGreeting;
}
switch( land->getLandType() )
{
case LandType::FreeCompany:
entry.infoFlags = Common::WardlandFlags::IsEstateOwned | Common::WardlandFlags::IsFreeCompanyEstate;
entry.infoFlags |= Common::WardlandFlags::IsEstateOwned | Common::WardlandFlags::IsFreeCompanyEstate;
// todo: send FC name
break;
case LandType::Private:
entry.infoFlags = Common::WardlandFlags::IsEstateOwned;
entry.infoFlags |= Common::WardlandFlags::IsEstateOwned;
auto owner = land->getPlayerOwner();
std::string playerName = g_fw.get< Sapphire::ServerMgr >()->getPlayerNameFromDb( owner );
auto playerName = g_fw.get< Sapphire::ServerMgr >()->getPlayerNameFromDb( owner );
memcpy( &entry.estateOwnerName, playerName.c_str(), playerName.size() );
break;
@ -284,6 +293,32 @@ void Sapphire::World::Manager::HousingMgr::sendWardLandInfo( Entity::Player& pla
player.queuePacket( wardInfoPacket );
}
void Sapphire::World::Manager::HousingMgr::sendEstateGreeting( Entity::Player& player, const Common::LandIdent ident )
{
auto landSetId = toLandSetId( ident.territoryTypeId, ident.wardNum );
auto hZone = getHousingZoneByLandSetId( landSetId );
if( !hZone )
return;
auto land = hZone->getLand( ident.landId );
if( !land )
return;
auto house = land->getHouse();
if( !house )
return;
auto greetingPacket = makeZonePacket< FFXIVIpcHousingEstateGreeting >( player.getId() );
greetingPacket->data().landIdent = ident;
auto greeting = house->getHouseGreeting();
memcpy( &greetingPacket->data().message, greeting.c_str(), greeting.size() );
player.queuePacket( greetingPacket );
}
void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetItem )
{
auto hZone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() );

View file

@ -43,6 +43,8 @@ namespace Sapphire::World::Manager
void requestEstateEditGuestAccess( Entity::Player& player, uint16_t territoryTypeId, uint16_t worldId, uint8_t wardId, uint8_t plotId );
void sendEstateGreeting( Entity::Player& player, const Common::LandIdent ident );
};
}

View file

@ -22,13 +22,15 @@ bool Sapphire::World::Manager::ShopMgr::purchaseGilShopItem( Entity::Player& pla
if( !item )
return false;
if( player.getCurrency( Common::CurrencyType::Gil ) < item->priceMid )
auto price = item->priceMid * quantity;
if( player.getCurrency( Common::CurrencyType::Gil ) < price )
return false;
if( !player.addItem( gilShopItem->item, quantity ) )
return false;
player.removeCurrency( Common::CurrencyType::Gil, item->priceMid );
player.removeCurrency( Common::CurrencyType::Gil, price );
return true;
}

View file

@ -427,6 +427,28 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
break;
}
case ClientTriggerType::RequestEstateGreeting:
{
uint16_t territoryTypeId = param11 & 0xFFFF;
uint16_t worldId = param11 >> 16;
uint8_t ward = ( param12 >> 16 ) & 0xFF;
uint8_t plot = ( param12 & 0xFF );
auto housingMgr = g_fw.get< HousingMgr >();
if( !housingMgr )
break;
Common::LandIdent ident;
ident.territoryTypeId = territoryTypeId;
ident.worldId = worldId;
ident.wardNum = ward;
ident.landId = plot;
housingMgr->sendEstateGreeting( player, ident );
break;
}
default:
{

View file

@ -45,7 +45,7 @@ Sapphire::Land::Land( uint16_t territoryTypeId, uint8_t wardNum, uint8_t landId,
{
memset( &m_tag, 0x00, 3 );
load();
init();
}
Sapphire::Land::~Land()
@ -53,7 +53,7 @@ Sapphire::Land::~Land()
}
void Sapphire::Land::load()
void Sapphire::Land::init()
{
auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >();
auto res = pDb->query( "SELECT * FROM land WHERE LandSetId = " + std::to_string( m_landSetId ) + " "
@ -98,7 +98,34 @@ void Sapphire::Land::load()
m_mapMarkerPosition.z = info->z;
}
init();
switch( m_size )
{
case HouseSize::Cottage:
m_maxPlacedExternalItems = 20;
m_maxPlacedInternalItems = 200;
break;
case HouseSize::House:
m_maxPlacedExternalItems = 30;
m_maxPlacedInternalItems = 300;
break;
case HouseSize::Mansion:
m_maxPlacedExternalItems = 40;
m_maxPlacedInternalItems = 400;
break;
default:
break;
}
// init item containers
auto setupContainer = [ this ]( InventoryType type, uint8_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 );
}
uint32_t Sapphire::Land::convertItemIdToHousingItemId( uint32_t itemId )
@ -223,11 +250,6 @@ uint32_t Sapphire::Land::getPlayerOwner()
return m_ownerPlayerId;
}
uint32_t Sapphire::Land::getMaxItems()
{
return m_maxItems;
}
uint32_t Sapphire::Land::getDevaluationTime()
{
return m_nextDrop - static_cast< uint32_t >( Util::getTimeSeconds() );
@ -248,25 +270,6 @@ uint8_t Sapphire::Land::getLandTag( uint8_t slot )
return m_tag[ slot ];
}
void Sapphire::Land::init()
{
switch( m_size )
{
case HouseSize::small:
m_maxItems = 20;
break;
case HouseSize::medium:
m_maxItems = 30;
break;
case HouseSize::big:
m_maxItems = 40;
break;
default:
break;
}
}
void Sapphire::Land::updateLandDb()
{
uint32_t houseId = 0;

View file

@ -18,7 +18,7 @@ namespace Sapphire
Land( uint16_t zoneId, uint8_t wardNum, uint8_t landId, uint32_t landSetId, Sapphire::Data::HousingLandSetPtr info );
virtual ~Land();
void load();
using LandInventoryMap = std::unordered_map< uint32_t, ItemContainerPtr >;
//Primary state
void setSize( uint8_t size );
@ -53,7 +53,6 @@ namespace Sapphire
void updateLandDb();
void update( uint32_t currTime );
uint32_t getMaxItems();
uint32_t getCurrentPrice() const;
uint32_t getMaxPrice() const;
uint32_t getDevaluationTime();
@ -87,8 +86,9 @@ namespace Sapphire
Sapphire::HousePtr m_pHouse;
//item storage
Sapphire::ItemContainerPtr ItemsOutdoorContainer;
uint32_t m_maxItems;
LandInventoryMap m_landInventoryMap;
uint32_t m_maxPlacedExternalItems;
uint32_t m_maxPlacedInternalItems;
//price
uint32_t m_initPrice;