From fd9bf92a25fdb9c32bd22ce8fb6018fa1d3a9de2 Mon Sep 17 00:00:00 2001 From: Mordred Date: Thu, 1 Nov 2018 00:18:19 +0100 Subject: [PATCH] Initial housing work by Vox --- src/common/Common.h | 44 ++- src/common/Database/ZoneDbConnection.cpp | 22 ++ src/common/Database/ZoneDbConnection.h | 5 + src/common/Network/PacketDef/Ipcs.h | 13 +- .../Network/PacketDef/Zone/ServerZoneDef.h | 111 ++++-- src/servers/sapphire_zone/ForwardsZone.h | 3 +- .../sapphire_zone/Zone/HousingZone.cpp | 97 +++-- src/servers/sapphire_zone/Zone/HousingZone.h | 46 ++- src/servers/sapphire_zone/Zone/Landset.cpp | 346 ++++++++++++++++++ src/servers/sapphire_zone/Zone/Landset.h | 116 ++++++ 10 files changed, 713 insertions(+), 90 deletions(-) create mode 100644 src/servers/sapphire_zone/Zone/Landset.cpp create mode 100644 src/servers/sapphire_zone/Zone/Landset.h diff --git a/src/common/Common.h b/src/common/Common.h index f729f5ba..e796d3c3 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -214,7 +214,8 @@ namespace Core::Common FreeCompanyBag1 = 20001, FreeCompanyBag2 = 20002, FreeCompanyGil = 22000, - FreeCompanyCrystal = 22001 + FreeCompanyCrystal = 22001, + HousingOutdoorItems = 25001 }; enum ContainerType : uint16_t @@ -731,6 +732,47 @@ namespace Core::Common MountSkill = 0xD, }; +//Structs +struct LandsetStruct +{ + uint8_t houseSize; //0 + uint8_t houseState; // 2 + uint8_t iconColor; // 4 + uint8_t iconAddIcon; // 6 + uint32_t fcId; //8 + uint32_t fcIcon;// 12 + uint32_t fcIconColor; // 16 + uint16_t exteriorRoof; //20 + uint16_t exteriorWall; //22 + uint16_t exteriorWindow; //24 + uint16_t exteriorDoor;// 26 + uint16_t otherFloorWall; // 28 + uint16_t otherFloorFlooring; //30 + uint16_t basementWall; // 32 + uint16_t gardenSign; // 34 + uint8_t color[8]; // 36 + //44 +}; + +struct HousePermissionSet +{ + uint16_t landSetId; //00 + uint16_t wardNum; //02 + uint16_t zoneId; //04 + uint16_t worldId; //06 + uint32_t permissionMask; //08 + uint32_t unkown1; //12 +}; + +struct YardObject +{ + uint32_t itemId; + uint16_t itemRotation; + uint16_t pos_x; + uint16_t pos_y; + uint16_t pos_z; +}; + using PlayerStateFlagList = std::vector< PlayerStateFlag >; } diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index 6f9e873b..b8992014 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -190,4 +190,26 @@ void Core::Db::ZoneDbConnection::doPrepareStatements() prepareStatement( CHARA_ITEMGLOBAL_DELETE, "UPDATE charaglobalitem SET IS_DELETE = 1 WHERE ItemId = ?;", CONNECTION_BOTH ); + + prepareStatement( LAND_INS, + "INSERT INTO land ( LandSetId ) VALUES ( ? );", + CONNECTION_BOTH ); + + prepareStatement( LAND_SEL, + "SELECT LandSetId, Size, houseState, iconColor, iconAddIcon, fcId, fcIcon, fcIconColor, exteriorRoof, " + "exteriorWall, exteriorWindow, exteriorDoor, otherFloorWall, otherFloorFlooring, basementWall, " + "gardenSign, colorSlot_0, colorSlot_1, colorSlot_2, colorSlot_3, colorSlot_4, colorSlot_5, " + "colorSlot_6, colorSlot_7, ownerPlayerId, nextDrop, dropCount, currentPrice " + "FROM land WHERE LandSetId = ?;", + CONNECTION_BOTH ); + + prepareStatement( LAND_UP, + "UPDATE land SET Size = ?, houseState = ?, iconColor = ?, iconAddIcon = ?, fcId = ?, " + "fcIcon = ?, fcIconColor = ?, exteriorRoof = ?, exteriorWall = ?, exteriorWindow = ?, " + "exteriorDoor = ?, otherFloorWall = ?, otherFloorFlooring = ?, basementWall = ?, gardenSign = ?, " + "colorSlot_0 = ?, colorSlot_1 = ?, colorSlot_2 = ?, colorSlot_3 = ?, colorSlot_4 = ?, " + "colorSlot_5 = ?, colorSlot_6 = ?, colorSlot_7 = ?, ownerPlayerId = ?, nextDrop = ?, " + "dropCount = ?, currentPrice = ?" + " WHERE LandSetId = ?;", + CONNECTION_BOTH ); } diff --git a/src/common/Database/ZoneDbConnection.h b/src/common/Database/ZoneDbConnection.h index b89e27e9..0a106cd3 100644 --- a/src/common/Database/ZoneDbConnection.h +++ b/src/common/Database/ZoneDbConnection.h @@ -78,6 +78,11 @@ namespace Core::Db ZONE_SEL_BNPCTEMPLATES, + LAND_INS, + LAND_SEL, + LAND_UP, + + MAX_STATEMENTS }; diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index c4c7a36d..cf2eb60b 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -188,9 +188,14 @@ enum ServerZoneIpcType : EquipDisplayFlags = 0x020C, // updated 4.4 - WardInfo = 0x0220, // updated 4.4 - WardHousingPermission = 0x0229, // updated 4.4 - WardYardInfo = 0x022C, // updated 4.4 + LandsetInitialize = 0x0220, // updated 4.4 + YardObjectSpawn = 0x0222, // updated 4.4 + LandsetPriceUpdate = 0x0225, // updated 4.3 + LandsetPermission = 0x0229, // updated 4.4 + LandsetYardInitialize = 0x022C, // updated 4.4 + YardObjectMove = 0x0230, // updated 4.4 + LandsetExtending = 0x0251, // updated 4.4 + LandsetUpdate = 0x0221, // updated 4.4 SharedEstateSettingsResponse = 0x023C, // updated 4.4 @@ -200,8 +205,6 @@ enum ServerZoneIpcType : PrepareZoning = 0x028F, // updated 4.4 ActorGauge = 0x0292, // updated 4.3 - - // Unknown IPC types that still need to be sent // TODO: figure all these out properly IPCTYPE_UNK_320 = 0x0249, // updated 4.4 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index c42be004..ba075261 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1578,8 +1578,53 @@ struct FFXIVIpcPerformNote : uint8_t data[32]; }; -struct FFXIVIpcWardInfo : - FFXIVIpcBasePacket< WardInfo > +//IPCs +struct FFXIVIpcLandsetPermission : + FFXIVIpcBasePacket +{ + Common::HousePermissionSet freeCompanyHouse; // 00 + uint64_t unkown1; + Common::HousePermissionSet privateHouse; // 24 + uint64_t unkown2; + Common::HousePermissionSet apartment; // 48 + uint64_t unkown3; + Common::HousePermissionSet sharedHouse[2]; //72 + uint64_t unkown4; + Common::HousePermissionSet unkownHouse; + uint64_t unkown5; +}; + +struct FFXIVIpcLandsetUpdate : + FFXIVIpcBasePacket< LandsetUpdate > +{ + uint16_t landSetId; + uint16_t unknow0; + uint16_t unknow1; + uint16_t unknow2; + Common::LandsetStruct landset; +}; + +struct FFXIVIpcLandsetPriceUpdate : + FFXIVIpcBasePacket< LandsetPriceUpdate > +{ + uint32_t price; + uint32_t timeLeft; +}; + +struct FFXIVIpcLandsetExtend : + FFXIVIpcBasePacket< LandsetExtending > +{ + struct + { + uint8_t houseSize; + uint8_t houseState; + uint8_t iconColor; + uint8_t iconIconAdd; + } landset[30]; +}; + +struct FFXIVIpcLandsetInitialize : + FFXIVIpcBasePacket< LandsetInitialize > { uint16_t unknown0; uint16_t wardNum; // set 1 for "Mist, Ward 2" @@ -1593,44 +1638,46 @@ struct FFXIVIpcWardInfo : uint8_t unknown6; uint8_t unknown7; uint8_t unknown8; - struct - { - uint8_t houseSize; //1 = small, 2 = middle, 3 = big; 1 - uint8_t houseState; //1 = for sell, 2 = sold, 3 = hasOwner, 0x0A = House sharing; 2 - uint8_t iconColor; //HouseState has to be 3; 1 = Private, 2 = FC House; 4 - uint8_t iconAddIcon; //Heart Icon = 2; 6 - uint32_t unknown9; //can be 0 (default) maybe fcId; 8 - uint32_t fcIcon; //can be 0 (default); 12 - uint32_t fcIconColor; //can be 0 (default); 16 - uint16_t houseRoofId; //18 - uint16_t houseFacadeId;//20 - uint16_t houseWindowId;//22 - uint16_t houseDoorId;//24 - uint8_t gardenData[4];//28 - uint16_t gardenSignId; //For fcIcon; 30 - uint16_t gardenFenceId; //32 - uint8_t color[8]; //40 - } landSet[30]; + Common::LandsetStruct landset[30]; }; -struct FFXIVIpcWardYardInfo : - FFXIVIpcBasePacket< WardYardInfo > +struct FFXIVIpcYardObjectSpawn : + FFXIVIpcBasePacket +{ + uint8_t landSetId; + uint8_t objectArray; + uint16_t unknown1; + uint32_t itemId; + uint16_t itemRotation; + uint16_t pos_x; + uint16_t pos_y; + uint16_t pos_z; +}; + +struct FFXIVIpcYardObjectMove : + FFXIVIpcBasePacket +{ + uint16_t itemRotation; + uint8_t objectArray; + uint8_t landSetId; + uint16_t pos_x; + uint16_t pos_y; + uint16_t pos_z; + uint16_t unknown1; + uint16_t unknown2; + uint16_t unknown3; +}; + +struct FFXIVIpcLandsetYardInitialize : + FFXIVIpcBasePacket< LandsetYardInitialize > { - /* consistency check? */ uint32_t unknown1; //always 0xFFFFFFFF uint32_t unknown2; //always 0xFFFFFFFF uint8_t unknown3; //always 0xFF - /* --- */ uint8_t packetNum; uint16_t packetTotal; - struct - { - uint32_t itemId; - uint16_t itemRotation; - uint16_t pos_x; - uint16_t pos_y; - uint16_t pos_z; - } object[100]; + Common::YardObject object[100]; + uint32_t unknown4; //unused }; /** diff --git a/src/servers/sapphire_zone/ForwardsZone.h b/src/servers/sapphire_zone/ForwardsZone.h index 2ab1ede2..eb5e909a 100644 --- a/src/servers/sapphire_zone/ForwardsZone.h +++ b/src/servers/sapphire_zone/ForwardsZone.h @@ -24,7 +24,8 @@ TYPE_FORWARD( InstanceContent ); TYPE_FORWARD( Item ); TYPE_FORWARD( ItemContainer ); TYPE_FORWARD( Session ); -TYPE_FORWARD( ZonePosition ) +TYPE_FORWARD( ZonePosition ); +TYPE_FORWARD( Landset ) namespace StatusEffect { TYPE_FORWARD( StatusEffect ); diff --git a/src/servers/sapphire_zone/Zone/HousingZone.cpp b/src/servers/sapphire_zone/Zone/HousingZone.cpp index 8b0871b4..ba551399 100644 --- a/src/servers/sapphire_zone/Zone/HousingZone.cpp +++ b/src/servers/sapphire_zone/Zone/HousingZone.cpp @@ -2,11 +2,14 @@ #include #include #include +#include #include #include #include "Actor/Player.h" +#include "Actor/Actor.h" +#include "Landset.h" #include "Forwards.h" #include "HousingZone.h" @@ -24,18 +27,20 @@ Core::HousingZone::HousingZone( uint8_t wardNum, const std::string& internalName, const std::string& contentName ) : Zone( territoryId, guId, internalName, contentName ), - m_wardNum( wardNum ) + m_wardNum( wardNum ), + m_zoneId( territoryId ) { } bool Core::HousingZone::init() { - uint32_t landSetId; - - for( landSetId = 0; landSetId < 60; landSetId++ ) + uint32_t landsetId; + for( landsetId = 0; landsetId < 60; landsetId++ ) { - //TODO: load house information here + auto pObject = make_Landset( m_territoryId, getWardNum(), landsetId ); + pObject->setHouseSize( 1 ); + m_landsetPtrMap[ landsetId ] = pObject; } return true; @@ -46,50 +51,78 @@ Core::HousingZone::~HousingZone() } -void Core::HousingZone::onPlayerZoneIn( Entity::Player& player ) +void Core::HousingZone::onPlayerZoneIn(Entity::Player& player) { auto pLog = g_fw.get< Logger >(); - pLog->debug( "HousingZone::onPlayerZoneIn: Zone#" + std::to_string( getGuId() ) + "|" + - +", Entity#" + std::to_string( player.getId() ) ); + pLog->debug( "HousingZone::onPlayerZoneIn: Zone#" + std::to_string(getGuId()) + "|" + ", Entity#" + std::to_string( player.getId() ) ); - uint32_t landSetId; uint32_t yardPacketNum; uint32_t yardPacketTotal = 8; - auto wardInfoPacket = makeZonePacket< FFXIVIpcWardInfo >( player.getId() ); - - wardInfoPacket->data().wardNum = m_wardNum; - wardInfoPacket->data().zoneId = player.getZoneId(); - //TODO: get current WorldId - wardInfoPacket->data().worldId = 67; - //TODO: handle Subdivision - wardInfoPacket->data().subInstance = 1; - - for( landSetId = 0; landSetId < 30; landSetId++ ) - { - wardInfoPacket->data().landSet[ landSetId ].houseSize = 1; - wardInfoPacket->data().landSet[ landSetId ].houseState = 1; - } - - player.queuePacket( wardInfoPacket ); + sendMap( player ); for( yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ ) { - auto wardYardInfoPacket = makeZonePacket< FFXIVIpcWardYardInfo >( player.getId() ); - wardYardInfoPacket->data().unknown1 = 0xFFFFFFFF; - wardYardInfoPacket->data().unknown2 = 0xFFFFFFFF; - wardYardInfoPacket->data().unknown3 = 0xFF; - wardYardInfoPacket->data().packetNum = yardPacketNum; - wardYardInfoPacket->data().packetTotal = yardPacketTotal; + auto landsetYardInitializePacket = makeZonePacket< FFXIVIpcLandsetYardInitialize >(player.getId()); + landsetYardInitializePacket->data().unknown1 = 0xFFFFFFFF; + landsetYardInitializePacket->data().unknown2 = 0xFFFFFFFF; + landsetYardInitializePacket->data().unknown3 = 0xFF; + landsetYardInitializePacket->data().packetNum = yardPacketNum; + landsetYardInitializePacket->data().packetTotal = yardPacketTotal; //TODO: Add Objects here - player.queuePacket( wardYardInfoPacket ); + player.queuePacket(landsetYardInitializePacket); } } +void Core::HousingZone::sendMap( Entity::Player& player ) +{ + auto landsetInitializePacket = makeZonePacket< FFXIVIpcLandsetInitialize >( player.getId() ); + + landsetInitializePacket->data().wardNum = m_wardNum; + landsetInitializePacket->data().zoneId = m_territoryId; + //TODO: get current WorldId + landsetInitializePacket->data().worldId = 67; + landsetInitializePacket->data().subInstance = isPlayerSubInstance( player ) == false ? 1 : 2; + + uint8_t startIndex = isPlayerSubInstance( player ) == false ? 0 : 30; + uint8_t count = 0; + for( uint8_t i = startIndex; i < ( startIndex + 30 ); i++ ) + { + memcpy( &landsetInitializePacket->data().landset[ count ], + &getLandset( i )->getLandset(), sizeof( Common::LandsetStruct ) ); + count++; + } + + player.queuePacket( landsetInitializePacket ); +} + +bool Core::HousingZone::isPlayerSubInstance( Entity::Player& player ) +{ + return player.getPos().x < -15000.0f; //ToDo: get correct pos +} + +void Core::HousingZone::onUpdate( uint32_t currTime ) +{ + for( uint8_t i = 0; i < 60; i++ ) + { + getLandset( i )->Update( currTime ); + } +} + uint8_t Core::HousingZone::getWardNum() const { return m_wardNum; } + +Core::LandsetPtr Core::HousingZone::getLandset( uint8_t id ) +{ + auto it = m_landsetPtrMap.find( id ); + if( it == m_landsetPtrMap.end() ) + return nullptr; + + return it->second; +} \ No newline at end of file diff --git a/src/servers/sapphire_zone/Zone/HousingZone.h b/src/servers/sapphire_zone/Zone/HousingZone.h index 43d979e3..340a08f1 100644 --- a/src/servers/sapphire_zone/Zone/HousingZone.h +++ b/src/servers/sapphire_zone/Zone/HousingZone.h @@ -4,30 +4,38 @@ #include "Zone.h" #include "Forwards.h" -namespace Core { -class HousingZone : - public Zone +namespace Core { -public: - HousingZone( uint8_t wardNum, - uint16_t territoryId, - uint32_t guId, - const std::string& internalName, - const std::string& contentName ); + class HousingZone : public Zone + { + public: + HousingZone( uint8_t wardNum, + uint16_t territoryId, + uint32_t guId, + const std::string& internalName, + const std::string& contentName ); - virtual ~HousingZone(); + virtual ~HousingZone(); - bool init() override; + bool init() override; - void onPlayerZoneIn( Entity::Player& player ) override; + void onPlayerZoneIn( Entity::Player& player ) override; + void onUpdate( uint32_t currTime ) override; - /* returns current ward number for this zone */ - uint8_t getWardNum() const; + void sendMap( Entity::Player& player ); + bool isPlayerSubInstance( Entity::Player& player ); - const uint32_t m_wardMaxNum = 18; -private: - uint8_t m_wardNum; -}; + /* returns current ward number for this zone */ + uint8_t getWardNum() const; + Core::LandsetPtr getLandset( uint8_t id ); + + const uint32_t m_wardMaxNum = 18; + private: + using LandsetPtrMap = std::unordered_map< uint8_t, Core::LandsetPtr >; + LandsetPtrMap m_landsetPtrMap; + uint8_t m_wardNum; + uint32_t m_zoneId; + }; } -#endif //SAPPHIRE_HOUSINGZONE_H +#endif //SAPPHIRE_HOUSINGZONE_H \ No newline at end of file diff --git a/src/servers/sapphire_zone/Zone/Landset.cpp b/src/servers/sapphire_zone/Zone/Landset.cpp new file mode 100644 index 00000000..75adfc6b --- /dev/null +++ b/src/servers/sapphire_zone/Zone/Landset.cpp @@ -0,0 +1,346 @@ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "Actor/Player.h" +#include "Inventory/ItemContainer.h" +#include "Inventory/Item.h" + +#include "Forwards.h" +#include "Landset.h" +#include "Framework.h" + +extern Core::Framework g_fw; + +using namespace Core::Common; + +Core::Landset::Landset( uint16_t zoneId, uint8_t wardNum, uint8_t landsetId ) : + m_zoneId( zoneId ), + m_wardNum( wardNum ), + m_landsetId( landsetId ), + m_currentPrice( 0 ), + m_nextDrop( 0 ) +{ + m_landsetKey = ( m_zoneId << 16 ) | ( m_wardNum << 8 ) | m_landsetId; + memset( &m_landset, 0x00, sizeof( LandsetStruct ) ); + load(); +} + +Core::Landset::~Landset() +{ + +} + +void Core::Landset::load() +{ + auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); + auto res = pDb->query( "SELECT * FROM landset WHERE Id = " + std::to_string( m_landsetKey ) ); + if( !res->next() ) + { + setHouseSize( HouseSizeType::smallHouse );//ToDo: get house site from ExD (Landset first 60 rows) + m_currentPrice = m_initPrice; + m_landset.color[ 7 ] = 0xFF; + m_ownerPlayerId = 0; + m_nextDrop = 0; + setState( HouseStateType::forSell ); + auto stmt = pDb->getPreparedStatement( Db::ZoneDbStatements::LAND_INS ); + stmt->setUInt( 1, m_landsetKey ); + pDb->directExecute( stmt ); + Init(); + } + else + { + Init(); + if( getState() == HouseStateType::privateHouse || getState() == HouseStateType::sold ) + { + m_ownerPlayerId = res->getUInt( "ownerPlayerId" ); + } + else if( getState() == HouseStateType::forSell ) + { + m_currentPrice = res->getUInt( "currentPrice" ); + m_nextDrop = res->getUInt( "nextDrop" ); + m_ownerPlayerId = 0; + } + } + ItemsOutdoorContainer = make_ItemContainer( InventoryType::HousingOutdoorItems, + m_maxItems, + "housingoutdooritems", true ); +} + +uint32_t Core::Landset::convertItemIdToHousingItemId( uint32_t itemId ) +{ + auto pExdData = g_fw.get< Data::ExdDataGenerated >(); + auto info = pExdData->get< Core::Data::Item >( itemId ); + return info->additionalData; +} + +void Core::Landset::setPreset( uint32_t id ) +{ + auto pExdData = g_fw.get< Data::ExdDataGenerated >(); + auto info = pExdData->get< Core::Data::HousingPreset >( convertItemIdToHousingItemId( id ) ); + setRoof( info->exteriorRoof ); + setWall( info->exteriorWall ); + setWindow( info->exteriorWindow ); + setBasementWall( info->basementWall ); + setFloorFlooring( info->otherFloorFlooring ); + setFloorWall( info->otherFloorWall ); +} + +//Primary State +void Core::Landset::setHouseSize( uint8_t size ) +{ + m_landset.houseSize = size; +} + +void Core::Landset::setState( uint8_t state ) +{ + m_landset.houseState = state; +} + +void Core::Landset::setOwnership( uint8_t state ) +{ + m_landset.iconColor = state; +} + +void Core::Landset::setSharing( uint8_t state ) +{ + m_landset.iconAddIcon = state; +} + +uint8_t Core::Landset::getHouseSize() +{ + return m_landset.houseSize; +} + +uint8_t Core::Landset::getState() +{ + return m_landset.houseState; +} + +uint8_t Core::Landset::getOwnership() +{ + return m_landset.iconColor; +} + +uint8_t Core::Landset::getSharing() +{ + return m_landset.iconAddIcon; +} + +//Free Comapny +void Core::Landset::setFreeCompany( uint32_t id, uint32_t icon, uint32_t color ) +{ + m_landset.fcId = id; + m_landset.fcIcon = icon; + m_landset.fcIconColor = color; //RGBA +} + +uint32_t Core::Landset::getFcId() +{ + return m_landset.fcIcon; +} + +uint32_t Core::Landset::getFcIcon() +{ + return m_landset.fcIcon; +} + +uint32_t Core::Landset::getFcColor() +{ + return m_landset.fcIconColor; +} + +//House Data +void Core::Landset::setRoof( uint16_t id ) +{ + m_landset.exteriorRoof = convertItemIdToHousingItemId( id ); +} + +void Core::Landset::setFacade( uint16_t id ) +{ + m_landset.exteriorWall = convertItemIdToHousingItemId( id ); +} + +void Core::Landset::setWindow( uint16_t id ) +{ + m_landset.exteriorWindow = convertItemIdToHousingItemId( id ); +} + +void Core::Landset::setDoor( uint16_t id ) +{ + m_landset.exteriorDoor = convertItemIdToHousingItemId( id ); +} + +void Core::Landset::setFloorWall( uint16_t id ) +{ + m_landset.otherFloorWall = convertItemIdToHousingItemId( id ); +} + +void Core::Landset::setFloorFlooring( uint16_t id ) +{ + m_landset.otherFloorFlooring = convertItemIdToHousingItemId( id ); +} + +void Core::Landset::setWall( uint16_t id ) +{ + m_landset.exteriorWall = convertItemIdToHousingItemId( id ); +} + +void Core::Landset::setSign( uint16_t id ) +{ + m_landset.gardenSign = convertItemIdToHousingItemId( id ); +} + +void Core::Landset::setBasementWall( uint16_t id ) +{ + m_landset.basementWall = convertItemIdToHousingItemId( id ); +} + +uint16_t Core::Landset::getRoof() +{ + return m_landset.exteriorRoof; +} + +uint16_t Core::Landset::getFacade() +{ + return m_landset.exteriorWall; +} + +uint16_t Core::Landset::getWindow() +{ + return m_landset.exteriorWindow; +} + +uint16_t Core::Landset::getDoor() +{ + return m_landset.exteriorDoor; +} + +uint16_t Core::Landset::getSign() +{ + return m_landset.gardenSign; +} + +uint16_t Core::Landset::getWall() +{ + return m_landset.basementWall; +} + +uint16_t Core::Landset::getFloorWall() +{ + return m_landset.otherFloorFlooring; +} + +uint16_t Core::Landset::getFloorFlooring() +{ + return m_landset.otherFloorFlooring; +} + +uint16_t Core::Landset::getBasememtWall() +{ + return m_landset.basementWall; +} + +//Color +void Core::Landset::setColor( uint8_t slot, uint8_t color ) +{ + m_landset.color[ slot ] = color; +} + +uint8_t Core::Landset::getColor( uint8_t slot ) +{ + return m_landset.color[ slot ]; +} + +//Player +void Core::Landset::setPlayerOwner( uint32_t id ) +{ + m_ownerPlayerId = id; +} + +uint32_t Core::Landset::getPlayerOwner() +{ + return m_ownerPlayerId; +} + +uint32_t Core::Landset::getLandsetKey() +{ + return m_landsetKey; +} + +LandsetStruct Core::Landset::getLandset() +{ + return m_landset; +} + +uint32_t Core::Landset::getMaxItems() +{ + return m_maxItems; +} + +void Core::Landset::Init() +{ + + + switch( getHouseSize() ) + { + case HouseSizeType::smallHouse: + m_initPrice = 3750000; + m_maxItems = 20; + break; + case HouseSizeType::mediumHouse: + m_initPrice = 20000000; + m_maxItems = 30; + break; + case HouseSizeType::bigHouse: + m_initPrice = 50000000; + m_maxItems = 40; + break; + default: + break; + } +} + +void Core::Landset::UpdateDatabase() +{ + auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); + std::string exec = "UPDATE land SET landset='" + + std::string( reinterpret_cast< const char* >( &m_landset ) ) + "', nextDrop=" + + std::to_string( m_nextDrop ) + ", currentPrice=" + + std::to_string( m_currentPrice ) + + " WHERE Id =" + std::to_string( m_landsetKey ); + pDb->execute( exec ); +} + +void Core::Landset::Update( uint32_t currTime ) +{ + if( m_currentPrice == 0 && getState() == HouseStateType::forSell ) + { + m_currentPrice = m_initPrice; + m_nextDrop = 0; + UpdateDatabase(); + } + if( m_nextDrop < currTime && getState() == HouseStateType::forSell ) + { + m_currentPrice = ( m_currentPrice / 100 ) * 90; + m_nextDrop = currTime + 86400; + UpdateDatabase(); + } + onUpdate(); +} + +void Core::Landset::onUpdate() +{ + +} \ No newline at end of file diff --git a/src/servers/sapphire_zone/Zone/Landset.h b/src/servers/sapphire_zone/Zone/Landset.h new file mode 100644 index 00000000..b895ba0d --- /dev/null +++ b/src/servers/sapphire_zone/Zone/Landset.h @@ -0,0 +1,116 @@ +#ifndef LANDSET_H_ +#define LANDSET_H_ +#include +#include "ForwardsZone.h" + +namespace Core +{ + class Landset + { + public: + enum HouseSizeType : uint8_t + { + //noneHouse, + smallHouse, + mediumHouse, + bigHouse + }; + + enum HouseStateType : uint8_t + { + none, + forSell, + sold, + fcHouse, + privateHouse + }; + + enum HouseIconAdd : uint8_t + { + heart = 0x06 + }; + + Landset( uint16_t zoneId, uint8_t wardNum, uint8_t landsetId ); + virtual ~Landset(); + + void load(); + + //Primary state + void setHouseSize( uint8_t size ); + void setState( uint8_t state ); + void setOwnership( uint8_t state ); + void setSharing( uint8_t state ); + + //Gerneral + uint8_t getHouseSize(); + uint8_t getState(); + uint8_t getOwnership(); + uint8_t getSharing(); + + //Free Comapny + void setFreeCompany( uint32_t id, uint32_t icon, uint32_t color ); + uint32_t getFcId(); + uint32_t getFcIcon(); + uint32_t getFcColor(); + + //House data + void setRoof( uint16_t itemId ); + void setFacade( uint16_t itemId ); + void setWindow( uint16_t itemId ); + void setDoor( uint16_t itemId ); + void setFloorWall( uint16_t itemId ); + void setFloorFlooring( uint16_t itemId ); + void setWall( uint16_t itemId ); + void setSign( uint16_t itemId ); + void setBasementWall( uint16_t itemId ); + + uint16_t getRoof(); + uint16_t getFacade(); + uint16_t getWindow(); + uint16_t getDoor(); + uint16_t getFloorWall(); + uint16_t getFloorFlooring(); + uint16_t getWall(); + uint16_t getSign(); + uint16_t getBasememtWall(); + + //Color + void setColor( uint8_t slot, uint8_t color ); + uint8_t getColor( uint8_t slot ); + //Player + void setPlayerOwner( uint32_t id ); + uint32_t getPlayerOwner(); + //Housing Functions + void setPreset( uint32_t itemId ); + void UpdateDatabase(); + void Update( uint32_t currTime ); + void onUpdate(); + uint32_t getLandsetKey(); + + Common::LandsetStruct getLandset(); + uint32_t getMaxItems(); + + private: + uint32_t convertItemIdToHousingItemId( uint32_t itemId ); + void Init(); + + uint32_t m_landsetKey; + uint8_t m_wardNum; + uint8_t m_landsetId; + uint16_t m_zoneId; + Common::LandsetStruct m_landset; + uint32_t m_ownerPlayerId; + + + //item storage + Core::ItemContainerPtr ItemsOutdoorContainer; + uint32_t m_maxItems; + + //price + uint32_t m_initPrice; + uint32_t m_nextDrop; + uint32_t m_currentPrice; + }; + +} +#endif \ No newline at end of file