1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-01 16:37:45 +00:00

Merge pull request #422 from XeAri/housing

Housing fixes
This commit is contained in:
Mordred 2018-11-10 22:26:25 +01:00 committed by GitHub
commit 9c4d965ff6
12 changed files with 231 additions and 24 deletions

View file

@ -751,6 +751,13 @@ namespace Core::Common
YardSign YardSign
}; };
enum HouseTagSlot
{
MainTag,
SubTag1,
SubTag2
};
//Structs //Structs
struct LandStruct struct LandStruct
{ {

View file

@ -24,6 +24,9 @@ public:
auto pTerritory = player.getCurrentZone(); auto pTerritory = player.getCurrentZone();
auto pHousing = std::dynamic_pointer_cast< HousingZone >( pTerritory ); auto pHousing = std::dynamic_pointer_cast< HousingZone >( pTerritory );
pHousing->playerPurchseLand( player, activeLand.plot, result.param2 );
} }
}; };

View file

@ -15,6 +15,9 @@
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include "Zone/ZonePosition.h" #include "Zone/ZonePosition.h"
#include "Zone//HousingMgr.h"
#include "Zone/Land.h"
#include "Network/GameConnection.h" #include "Network/GameConnection.h"
#include "Network/PacketWrappers/ActorControlPacket142.h" #include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h" #include "Network/PacketWrappers/ActorControlPacket143.h"
@ -1574,6 +1577,12 @@ void Core::Entity::Player::sendZonePackets()
sendItemLevel(); sendItemLevel();
} }
auto pHousingMgr = g_fw.get< HousingMgr >();
if( Core::LandPtr pLand = pHousingMgr->getLandByOwnerId( getId() ) )
{
setLandPermissions( LandPermissionSlot::Private, 0x0B, pLand->getLandId(), pLand->getWardNum(), pLand->getZoneId() );
}
sendLandPermissions(); sendLandPermissions();
auto initZonePacket = makeZonePacket< FFXIVIpcInitZone >( getId() ); auto initZonePacket = makeZonePacket< FFXIVIpcInitZone >( getId() );
@ -1752,11 +1761,12 @@ bool Core::Entity::Player::isOnEnterEventDone() const
return m_onEnterEventDone; return m_onEnterEventDone;
} }
void Core::Entity::Player::setLandPermissions( uint8_t permissionSet, uint32_t permissionMask, int16_t landSetId, int16_t wardNum, int16_t zoneId ) void Core::Entity::Player::setLandPermissions( uint8_t permissionSet, uint32_t permissionMask, int16_t landId, int16_t wardNum, int16_t zoneId )
{ {
m_landPermission[permissionSet].landId = landSetId; m_landPermission[permissionSet].landId = landId;
m_landPermission[permissionSet].permissionMask = permissionMask; m_landPermission[permissionSet].permissionMask = permissionMask;
m_landPermission[permissionSet].wardNum = wardNum; m_landPermission[permissionSet].wardNum = wardNum;
m_landPermission[permissionSet].zoneId = zoneId;
m_landPermission[permissionSet].worldId = 67; m_landPermission[permissionSet].worldId = 67;
m_landPermission[permissionSet].unkown1 = 0; m_landPermission[permissionSet].unkown1 = 0;
} }

View file

@ -763,7 +763,7 @@ namespace Core::Entity
// Housing Handling // Housing Handling
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
void setLandPermissions( uint8_t permissionSet, uint32_t permissionMask, int16_t landSetId, int16_t wardNum, int16_t zoneId ); void setLandPermissions( uint8_t permissionSet, uint32_t permissionMask, int16_t landId, int16_t wardNum, int16_t zoneId );
void sendLandPermissions(); void sendLandPermissions();

View file

@ -20,6 +20,7 @@ namespace Core {
TYPE_FORWARD( Cell ); TYPE_FORWARD( Cell );
TYPE_FORWARD( Zone ); TYPE_FORWARD( Zone );
TYPE_FORWARD( HousingZone ); TYPE_FORWARD( HousingZone );
TYPE_FORWARD( HousingMgr );
TYPE_FORWARD( InstanceContent ); TYPE_FORWARD( InstanceContent );
TYPE_FORWARD( Item ); TYPE_FORWARD( Item );
TYPE_FORWARD( ItemContainer ); TYPE_FORWARD( ItemContainer );

View file

@ -0,0 +1,70 @@
#include "HousingMgr.h"
#include "HousingMgr.h"
#include <Logging/Logger.h>
#include <Database/DatabaseDef.h>
#include <Exd/ExdDataGenerated.h>
#include <unordered_map>
#include "Actor/Player.h"
#include "Zone.h"
#include "HousingZone.h"
#include "HousingMgr.h"
#include "Land.h"
#include "Framework.h"
extern Core::Framework g_fw;
Core::HousingMgr::HousingMgr() :
m_lastLandId( 0 )
{
}
Core::HousingMgr::~HousingMgr()
{
}
bool Core::HousingMgr::init()
{
return true;
}
uint16_t Core::HousingMgr::getNexLandId()
{
return ++m_lastLandId;
}
void Core::HousingMgr::insertHousingZone( Core::Data::HousingZonePtr hZone )
{
uint16_t id = getNexLandId();
m_housingZonePtrMap[id] = hZone;
}
Core::Data::HousingZonePtr Core::HousingMgr::getHousingZone( uint16_t id )
{
auto it = m_housingZonePtrMap.find( id );
if( it == m_housingZonePtrMap.end() )
return nullptr;
return it->second;
}
Core::LandPtr Core::HousingMgr::getLandByOwnerId( uint32_t id )
{
for( const auto& hZoneIt : m_housingZonePtrMap )
{
auto pHousingZone = hZoneIt.second;
for( uint8_t landId = 0;landId < 60;landId++ )
{
if( pHousingZone->getLand( landId )->getPlayerOwner() == id )
{
return pHousingZone->getLand( landId );
}
}
}
return nullptr;
}

View file

@ -0,0 +1,38 @@
#ifndef SAPPHIRE_HOUSINGMGR_H
#define SAPPHIRE_HOUSINGMGR_H
#include "Forwards.h"
#include "HousingZone.h"
#include <set>
#include <unordered_map>
namespace Core
{
namespace Data
{
using HousingZonePtr = std::shared_ptr< HousingZone >;
}
class HousingMgr
{
public:
HousingMgr();
virtual ~HousingMgr();
bool init();
uint16_t getNexLandId();
void insertHousingZone( Core::Data::HousingZonePtr hZone );
Core::Data::HousingZonePtr getHousingZone( uint16_t id );
Core::LandPtr getLandByOwnerId( uint32_t id );
private:
using HousingZonePtrMap = std::unordered_map< uint16_t, Core::Data::HousingZonePtr >;
uint16_t m_lastLandId;
HousingZonePtrMap m_housingZonePtrMap;
};
}
#endif // SAPPHIRE_HOUSINGMGR_H

View file

@ -13,6 +13,7 @@
#include "Forwards.h" #include "Forwards.h"
#include "HousingZone.h" #include "HousingZone.h"
#include "HousingMgr.h"
#include "Framework.h" #include "Framework.h"
extern Core::Framework g_fw; extern Core::Framework g_fw;
@ -61,10 +62,12 @@ bool Core::HousingZone::init()
for( landId = 0; landId < 60; landId++ ) for( landId = 0; landId < 60; landId++ )
{ {
auto pObject = make_Land( m_territoryTypeId, getWardNum(), landId, m_landSetId, info ); auto pObject = make_Land( m_territoryTypeId, getWardNum(), landId, m_landSetId, info );
pObject->setHouseSize( 1 );
m_landPtrMap[ landId ] = pObject; m_landPtrMap[ landId ] = pObject;
} }
auto pHousingMgr = g_fw.get< HousingMgr >();
pHousingMgr->insertHousingZone( (HousingZonePtr)this );
return true; return true;
} }
@ -100,13 +103,14 @@ void Core::HousingZone::onPlayerZoneIn( Entity::Player& player )
} }
auto landSetMap = makeZonePacket< FFXIVIpcLandSetMap >( player.getId() ); auto landSetMap = makeZonePacket< FFXIVIpcLandSetMap >( player.getId() );
landSetMap->data().subdivision = isPlayerSubInstance( player ) == false ? 1 : 2; landSetMap->data().subdivision = isPlayerSubInstance( player ) == false ? 2 : 1;
uint8_t startIndex = isPlayerSubInstance( player ) == false ? 0 : 30; uint8_t startIndex = isPlayerSubInstance( player ) == false ? 0 : 30;
for( uint8_t i = startIndex, count = 0; i < ( startIndex + 30 ); i++, count++ ) for( uint8_t i = startIndex, count = 0; i < ( startIndex + 30 ); i++, count++ )
{ {
landSetMap->data().landInfo[ count ].status = 1; landSetMap->data().landInfo[ count ].status = 1;
//memcpy( , &getLand( i )->getLand(), sizeof( Common::LandStruct ) ); //memcpy( , &getLand( i )->getLand(), sizeof( Common::LandStruct ) );
} }
player.queuePacket( landSetMap ); player.queuePacket( landSetMap );
} }
@ -150,6 +154,31 @@ bool Core::HousingZone::isPlayerSubInstance( Entity::Player& player )
return player.getPos().x < -15000.0f; //ToDo: get correct pos return player.getPos().x < -15000.0f; //ToDo: get correct pos
} }
void Core::HousingZone::playerPurchseLand( Entity::Player & player, uint8_t plot, uint8_t state )
{
uint32_t plotPrice = getLand( plot )->getCurrentPrice();
if( plotPrice <= player.getCurrency( CurrencyType::Gil ) )
{
auto pHousing = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() );
if( state == 1 ) //TODO: add Free company purchase
player.sendDebug( "Free company house purchase aren't supported at this time." );
if( state == 2 ) //Private Purchase
{
getLand( plot )->setPlayerOwner( player.getId() );
getLand( plot )->setState( HouseState::sold );
player.removeCurrency( CurrencyType::Gil, plotPrice );
player.setLandPermissions( LandPermissionSlot::Private, 0x0B, plot, pHousing->getWardNum(), pHousing->getTerritoryTypeId() );
player.sendLandPermissions();
getLand( plot )->UpdateLandDb();
sendLandUpdate( plot );
}
}
//else
//TOD: add error msg - insufficient gil
}
void Core::HousingZone::onUpdate( uint32_t currTime ) void Core::HousingZone::onUpdate( uint32_t currTime )
{ {
for( uint8_t i = 0; i < 60; i++ ) for( uint8_t i = 0; i < 60; i++ )

View file

@ -26,6 +26,8 @@ namespace Core
void sendLandUpdate( uint8_t landId ); void sendLandUpdate( uint8_t landId );
bool isPlayerSubInstance( Entity::Player& player ); bool isPlayerSubInstance( Entity::Player& player );
void playerPurchseLand( Entity::Player& player, uint8_t plot, uint8_t state );
/* returns current ward number for this zone */ /* returns current ward number for this zone */
uint8_t getWardNum() const; uint8_t getWardNum() const;

View file

@ -32,11 +32,13 @@ Core::Land::Land( uint16_t zoneId, uint8_t wardNum, uint8_t landId, uint32_t lan
m_landId( landId ), m_landId( landId ),
m_currentPrice( 0 ), m_currentPrice( 0 ),
m_minPrice( 0 ), m_minPrice( 0 ),
m_nextDrop( 0 ), m_nextDrop( Util::getTimeSeconds() + 21600 ),
m_ownerPlayerId( 0 ),
m_landSetId( landSetId ), m_landSetId( landSetId ),
m_landInfo( info ) m_landInfo( info )
{ {
memset( &m_land, 0x00, sizeof( LandStruct ) ); memset( &m_land, 0x00, sizeof( LandStruct ) );
memset( &m_tag, 0x00, 3 );
load(); load();
} }
@ -47,11 +49,9 @@ Core::Land::~Land()
void Core::Land::load() void Core::Land::load()
{ {
m_land.houseState = HouseState::forSale;
auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >();
auto res = pDb->query( "SELECT * FROM land WHERE landsetid = " + std::to_string( m_landSetId ) + " " auto res = pDb->query( "SELECT * FROM land WHERE LandSetId = " + std::to_string( m_landSetId ) + " "
"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, size, status, landprice ) " pDb->directExecute( "INSERT INTO land ( landsetid, landid, size, status, landprice ) "
@ -65,9 +65,11 @@ void Core::Land::load()
} }
else else
{ {
m_land.houseSize = res->getUInt( "size" ); m_land.houseSize = res->getUInt( "Size" );
m_land.houseState = res->getUInt( "status" ); m_land.houseState = res->getUInt( "Status" );
m_currentPrice = res->getUInt( "LandPrice" );; m_currentPrice = res->getUInt( "LandPrice" );
m_ownerPlayerId = res->getUInt( "OwnerId" );
m_minPrice = m_landInfo->minPrices[ m_landId ];
} }
init(); init();
// setPreset( 262145 ); // setPreset( 262145 );
@ -170,6 +172,26 @@ uint8_t Core::Land::getSharing()
return m_land.iconAddIcon; return m_land.iconAddIcon;
} }
uint32_t Core::Land::getLandSetId()
{
return m_landSetId;
}
uint8_t Core::Land::getWardNum()
{
return m_wardNum;
}
uint8_t Core::Land::getLandId()
{
return m_landId;
}
uint16_t Core::Land::getZoneId()
{
return m_zoneId;
}
//Free Comapny //Free Comapny
void Core::Land::setFreeCompany( uint32_t id, uint32_t icon, uint32_t color ) void Core::Land::setFreeCompany( uint32_t id, uint32_t icon, uint32_t color )
{ {
@ -241,6 +263,16 @@ uint32_t Core::Land::getDevaluationTime()
return m_nextDrop - Util::getTimeSeconds(); return m_nextDrop - Util::getTimeSeconds();
} }
void Core::Land::setLandTag( uint8_t slot, uint8_t tag )
{
m_tag[ slot ] = tag;
}
uint8_t Core::Land::getLandTag( uint8_t slot )
{
return m_tag[ slot ];
}
void Core::Land::init() void Core::Land::init()
{ {
@ -260,15 +292,16 @@ void Core::Land::init()
} }
} }
void Core::Land::UpdateDatabase() void Core::Land::UpdateLandDb()
{ {
/*auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >();
std::string exec = "UPDATE land SET landset='" + pDb->directExecute( "UPDATE land SET status = " + std::to_string( m_land.houseState )
std::string( reinterpret_cast< const char* >( &m_land ) ) + "', nextDrop=" + + ", LandPrice = " + std::to_string( getCurrentPrice() )
std::to_string( m_nextDrop ) + ", currentPrice=" + + ", UpdateTime = " + std::to_string( getDevaluationTime() )
std::to_string( m_currentPrice ) + + ", OwnerId = " + std::to_string( getPlayerOwner() )
" WHERE Id =" + std::to_string( m_landKey ); + ", HouseId = " + std::to_string( 0 ) //TODO: add house id
pDb->execute( exec );*/ + " WHERE LandSetId = " + std::to_string( m_landSetId )
+ " AND LandId = " + std::to_string( m_landId ) + ";" );
} }
void Core::Land::Update( uint32_t currTime ) void Core::Land::Update( uint32_t currTime )
@ -279,7 +312,7 @@ void Core::Land::Update( uint32_t currTime )
{ {
m_nextDrop = currTime + 21600; m_nextDrop = currTime + 21600;
m_currentPrice = ( m_currentPrice / 100 ) * 99.58; m_currentPrice = ( m_currentPrice / 100 ) * 99.58;
UpdateLandDb();
} }
UpdateDatabase();
} }
} }

View file

@ -30,6 +30,10 @@ namespace Core
uint8_t getState(); uint8_t getState();
uint8_t getOwnership(); uint8_t getOwnership();
uint8_t getSharing(); uint8_t getSharing();
uint32_t getLandSetId();
uint8_t getWardNum();
uint8_t getLandId();
uint16_t getZoneId();
//Free Comapny //Free Comapny
void setFreeCompany( uint32_t id, uint32_t icon, uint32_t color ); void setFreeCompany( uint32_t id, uint32_t icon, uint32_t color );
@ -50,7 +54,7 @@ namespace Core
uint32_t getPlayerOwner(); uint32_t getPlayerOwner();
//Housing Functions //Housing Functions
void setPreset( uint32_t itemId ); void setPreset( uint32_t itemId );
void UpdateDatabase(); void UpdateLandDb();
void Update( uint32_t currTime ); void Update( uint32_t currTime );
const Common::LandStruct& getLand(); const Common::LandStruct& getLand();
@ -59,6 +63,10 @@ namespace Core
uint32_t getCurrentPrice() const; uint32_t getCurrentPrice() const;
uint32_t getDevaluationTime(); uint32_t getDevaluationTime();
//House tags
void setLandTag( uint8_t slot, uint8_t tag );
uint8_t getLandTag( uint8_t slot );
private: private:
uint16_t convertItemIdToHousingItemId( uint16_t itemId ); uint16_t convertItemIdToHousingItemId( uint16_t itemId );
void init(); void init();
@ -81,6 +89,9 @@ namespace Core
uint32_t m_nextDrop; uint32_t m_nextDrop;
uint32_t m_currentPrice; uint32_t m_currentPrice;
uint32_t m_minPrice; uint32_t m_minPrice;
//Tags
uint8_t m_tag[3];
}; };
} }

View file

@ -9,6 +9,7 @@
#include <Database/DbWorkerPool.h> #include <Database/DbWorkerPool.h>
#include "Linkshell/LinkshellMgr.h" #include "Linkshell/LinkshellMgr.h"
#include "Zone/TerritoryMgr.h" #include "Zone/TerritoryMgr.h"
#include "Zone/HousingMgr.h"
#include "DebugCommand/DebugCommandHandler.h" #include "DebugCommand/DebugCommandHandler.h"
#include <Config/ConfigMgr.h> #include <Config/ConfigMgr.h>
@ -25,6 +26,7 @@ bool setupFramework()
auto pScript = std::make_shared< Scripting::ScriptMgr >(); auto pScript = std::make_shared< Scripting::ScriptMgr >();
auto pDb = std::make_shared< Db::DbWorkerPool< Db::ZoneDbConnection > >(); auto pDb = std::make_shared< Db::DbWorkerPool< Db::ZoneDbConnection > >();
auto pLsMgr = std::make_shared< LinkshellMgr >(); auto pLsMgr = std::make_shared< LinkshellMgr >();
auto pHousingMgr = std::make_shared< HousingMgr >();
auto pTeriMgr = std::make_shared< TerritoryMgr >(); auto pTeriMgr = std::make_shared< TerritoryMgr >();
auto pDebugCom = std::make_shared< DebugCommandHandler >(); auto pDebugCom = std::make_shared< DebugCommandHandler >();
auto pConfig = std::make_shared< ConfigMgr >(); auto pConfig = std::make_shared< ConfigMgr >();
@ -38,6 +40,7 @@ bool setupFramework()
g_fw.set< Scripting::ScriptMgr >( pScript ); g_fw.set< Scripting::ScriptMgr >( pScript );
g_fw.set< Db::DbWorkerPool< Db::ZoneDbConnection > >( pDb ); g_fw.set< Db::DbWorkerPool< Db::ZoneDbConnection > >( pDb );
g_fw.set< LinkshellMgr >( pLsMgr ); g_fw.set< LinkshellMgr >( pLsMgr );
g_fw.set< HousingMgr >( pHousingMgr );
g_fw.set< TerritoryMgr >( pTeriMgr ); g_fw.set< TerritoryMgr >( pTeriMgr );
g_fw.set< DebugCommandHandler >( pDebugCom ); g_fw.set< DebugCommandHandler >( pDebugCom );
g_fw.set< ConfigMgr >( pConfig ); g_fw.set< ConfigMgr >( pConfig );