mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-26 06:27:45 +00:00
Merge pull request #447 from NotAdam/housing
More housing and gilshop fix
This commit is contained in:
commit
338032b700
8 changed files with 118 additions and 41 deletions
9
sql/houseiteminventory.sql
Normal file
9
sql/houseiteminventory.sql
Normal 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
|
||||
;
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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 );
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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:
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue