mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-28 07:07:45 +00:00
commit
e81ddd4a50
17 changed files with 267 additions and 73 deletions
|
@ -791,7 +791,7 @@ namespace Sapphire::Common
|
|||
ExteriorFence
|
||||
};
|
||||
|
||||
enum HousingInteriorSlot
|
||||
enum HouseInteriorSlot
|
||||
{
|
||||
InteriorWall,
|
||||
InteriorFloor,
|
||||
|
|
|
@ -58,6 +58,11 @@ namespace Sapphire
|
|||
spdlog::get( "logger" )->error( text );
|
||||
}
|
||||
|
||||
void Logger::warn( const std::string& text )
|
||||
{
|
||||
spdlog::get( "logger" )->warn( text );
|
||||
}
|
||||
|
||||
void Logger::info( const std::string& text )
|
||||
{
|
||||
spdlog::get( "logger" )->info( text );
|
||||
|
@ -73,4 +78,9 @@ namespace Sapphire
|
|||
spdlog::get( "logger" )->critical( text );
|
||||
}
|
||||
|
||||
void Logger::trace( const std::string& text )
|
||||
{
|
||||
spdlog::get( "logger" )->trace( text );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,12 +20,16 @@ namespace Sapphire
|
|||
|
||||
static void error( const std::string& text );
|
||||
|
||||
static void warn( const std::string& text );
|
||||
|
||||
static void info( const std::string& text );
|
||||
|
||||
static void debug( const std::string& text );
|
||||
|
||||
static void fatal( const std::string& text );
|
||||
|
||||
static void trace( const std::string& text );
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ struct FFXIVIpcReqPlaceHousingItem :
|
|||
/* 000C */ Common::FFXIVARR_POSITION3 position;
|
||||
/* 0018 */ float rotation;
|
||||
|
||||
/* 001C */ uint32_t unknown3; // always 1?
|
||||
/* 001C */ uint32_t shouldPlaceItem; // 1 if placing an item, 0 if placing in store
|
||||
/* 0020 */ uint32_t unknown4[2]; // always 0 it looks like
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "Actor/EventObject.h"
|
||||
#include "Territory/HousingZone.h"
|
||||
#include "Manager/TerritoryMgr.h"
|
||||
#include "Territory/Land.h"
|
||||
#include "Framework.h"
|
||||
|
||||
using namespace Sapphire;
|
||||
|
@ -19,8 +20,6 @@ public:
|
|||
|
||||
void onTalk( uint32_t eventId, Entity::Player& player, Entity::EventObject& eobj ) override
|
||||
{
|
||||
player.sendDebug( "Found plot entrance for plot: " + std::to_string( eobj.getHousingLink() >> 8 ) );
|
||||
|
||||
player.playScene( eventId, 0, 0, [this, eobj]( Entity::Player& player, const Event::SceneResult& result )
|
||||
{
|
||||
// param2 == 1 when player wants to enter house
|
||||
|
@ -42,15 +41,45 @@ public:
|
|||
ident.worldId = 67;
|
||||
|
||||
auto internalZone = terriMgr->findOrCreateHousingInterior( ident );
|
||||
if( internalZone )
|
||||
if( !internalZone )
|
||||
{
|
||||
player.sendDebug( "created zone with guid: " + std::to_string( internalZone->getGuId() ) + "\nname: " + internalZone->getName() );
|
||||
// an error occurred during event movement
|
||||
// lol
|
||||
player.sendLogMessage( 1311 );
|
||||
player.eventFinish( result.eventId, 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
player.eventFinish( result.eventId, 1 );
|
||||
|
||||
player.setPos( { 0.f, 0.f, 0.f } );
|
||||
player.setInstance( internalZone );
|
||||
Common::FFXIVARR_POSITION3 pos {};
|
||||
|
||||
auto land = zone->getLand( eobj.getHousingLink() >> 8 );
|
||||
if( !land )
|
||||
return;
|
||||
|
||||
switch( land->getSize() )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
pos = { 0.1321167f, 0.f, 2.746273f };
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
pos = { 1.337722f, 0.f, 3.995964f };
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
pos = { 0.07214607f, 0.f, 8.217761f };
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
player.setInstance( internalZone, pos );
|
||||
} );
|
||||
}
|
||||
};
|
|
@ -459,6 +459,33 @@ bool Sapphire::Entity::Player::setInstance( ZonePtr instance )
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Player::setInstance( ZonePtr instance, Common::FFXIVARR_POSITION3 pos )
|
||||
{
|
||||
if( !instance )
|
||||
return false;
|
||||
|
||||
m_onEnterEventDone = false;
|
||||
|
||||
auto pTeriMgr = m_pFw->get< TerritoryMgr >();
|
||||
auto currentZone = getCurrentZone();
|
||||
|
||||
m_prevPos = m_pos;
|
||||
m_prevRot = m_rot;
|
||||
m_prevTerritoryTypeId = currentZone->getTerritoryTypeId();
|
||||
m_prevTerritoryId = getTerritoryId();
|
||||
|
||||
if( pTeriMgr->movePlayer( instance, getAsPlayer() ) )
|
||||
{
|
||||
m_pos = pos;
|
||||
|
||||
sendZonePackets();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Player::exitInstance()
|
||||
{
|
||||
auto pTeriMgr = m_pFw->get< TerritoryMgr >();
|
||||
|
|
|
@ -482,6 +482,9 @@ namespace Sapphire::Entity
|
|||
/*! sets the players instance & initiates zoning process */
|
||||
bool setInstance( ZonePtr instance );
|
||||
|
||||
/*! sets the players instance & initiates zoning process */
|
||||
bool setInstance( Sapphire::ZonePtr instance, Sapphire::Common::FFXIVARR_POSITION3 pos );
|
||||
|
||||
/*! returns the player to their position before zoning into an instance */
|
||||
bool exitInstance();
|
||||
|
||||
|
@ -916,7 +919,7 @@ namespace Sapphire::Entity
|
|||
|
||||
uint32_t getNextInventorySequence();
|
||||
|
||||
void send();
|
||||
bool findFirstItemWithId( uint32_t catalogId, Inventory::InventoryContainerPair& location );
|
||||
|
||||
uint8_t getFreeSlotsInBags();
|
||||
|
||||
|
|
|
@ -932,4 +932,25 @@ void Sapphire::Entity::Player::insertInventoryItem( Sapphire::Common::InventoryT
|
|||
auto slotUpdate = std::make_shared< UpdateInventorySlotPacket >( getId(), slot, type, *item );
|
||||
queuePacket( slotUpdate );
|
||||
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Player::findFirstItemWithId( uint32_t catalogId,
|
||||
Inventory::InventoryContainerPair& location )
|
||||
{
|
||||
for( auto bagId : { Bag0, Bag1, Bag2, Bag3 } )
|
||||
{
|
||||
auto& container = m_storageMap[ bagId ];
|
||||
|
||||
for( const auto& item : container->getItemMap() )
|
||||
{
|
||||
if( item.second->getId() != catalogId )
|
||||
continue;
|
||||
|
||||
location = std::make_pair( bagId, item.first );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -416,11 +416,10 @@ bool Sapphire::World::Manager::HousingMgr::relinquishLand( Entity::Player& playe
|
|||
|
||||
auto pLand = pHousing->getLand( plot );
|
||||
auto plotMaxPrice = pLand->getCurrentPrice();
|
||||
auto landOwnerId = pLand->getOwnerId();
|
||||
|
||||
// can't relinquish when you are not the owner
|
||||
// TODO: actually use permissions here for FC houses
|
||||
if( landOwnerId != player.getId() )
|
||||
if( !hasPermission( player, *pLand, 0 ) )
|
||||
{
|
||||
auto msgPkt = makeActorControl143( player.getId(), ActorControl::LogMsg, 3304, 0 );
|
||||
player.queuePacket( msgPkt );
|
||||
|
@ -564,6 +563,18 @@ bool Sapphire::World::Manager::HousingMgr::initHouseModels( Entity::Player& play
|
|||
if( !preset )
|
||||
return false;
|
||||
|
||||
// remove preset item
|
||||
Inventory::InventoryContainerPair foundItem;
|
||||
if( !player.findFirstItemWithId( presetCatalogId, foundItem ) )
|
||||
return false;
|
||||
|
||||
auto item = player.dropInventoryItem( foundItem.first, foundItem.second );
|
||||
if( !item )
|
||||
return false;
|
||||
|
||||
// move preset item into ext appearance container
|
||||
houseInventory[ InventoryType::HousingExteriorAppearance ]->setItem( HouseExteriorSlot::HousePermit, item );
|
||||
|
||||
// high iq shit
|
||||
auto invMap = std::map< uint16_t, std::map< uint32_t, int32_t > >
|
||||
{
|
||||
|
@ -583,19 +594,19 @@ bool Sapphire::World::Manager::HousingMgr::initHouseModels( Entity::Player& play
|
|||
InventoryType::HousingInteriorAppearance,
|
||||
{
|
||||
// lobby/middle floor
|
||||
{ HousingInteriorSlot::InteriorWall, preset->interiorWall },
|
||||
{ HousingInteriorSlot::InteriorFloor, preset->interiorFlooring },
|
||||
{ HousingInteriorSlot::InteriorLight, preset->interiorLighting },
|
||||
{ HouseInteriorSlot::InteriorWall, preset->interiorWall },
|
||||
{ HouseInteriorSlot::InteriorFloor, preset->interiorFlooring },
|
||||
{ HouseInteriorSlot::InteriorLight, preset->interiorLighting },
|
||||
|
||||
// attic
|
||||
{ HousingInteriorSlot::InteriorWall_Attic, preset->otherFloorWall },
|
||||
{ HousingInteriorSlot::InteriorFloor_Attic, preset->otherFloorFlooring },
|
||||
{ HousingInteriorSlot::InteriorLight_Attic, preset->otherFloorLighting },
|
||||
{ HouseInteriorSlot::InteriorWall_Attic, preset->otherFloorWall },
|
||||
{ HouseInteriorSlot::InteriorFloor_Attic, preset->otherFloorFlooring },
|
||||
{ HouseInteriorSlot::InteriorLight_Attic, preset->otherFloorLighting },
|
||||
|
||||
// basement
|
||||
{ HousingInteriorSlot::InteriorWall_Basement, preset->basementWall },
|
||||
{ HousingInteriorSlot::InteriorFloor_Basement, preset->basementFlooring },
|
||||
{ HousingInteriorSlot::InteriorLight_Basement, preset->basementLighting },
|
||||
{ HouseInteriorSlot::InteriorWall_Basement, preset->basementWall },
|
||||
{ HouseInteriorSlot::InteriorFloor_Basement, preset->basementFlooring },
|
||||
{ HouseInteriorSlot::InteriorLight_Basement, preset->basementLighting },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -641,7 +652,7 @@ void Sapphire::World::Manager::HousingMgr::createHouse( Sapphire::HousePtr house
|
|||
pDb->execute( stmt );
|
||||
}
|
||||
|
||||
void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetItem )
|
||||
void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetCatalogId )
|
||||
{
|
||||
auto hZone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() );
|
||||
|
||||
|
@ -652,12 +663,9 @@ void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& pl
|
|||
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->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *pLand, 0 ) )
|
||||
return;
|
||||
|
||||
// todo: check if permit is in inventory and remove one
|
||||
|
||||
// create house
|
||||
auto ident = pLand->getLandIdent();
|
||||
auto house = make_House( getNextHouseId(), pLand->getLandSetId(), ident,
|
||||
|
@ -666,8 +674,11 @@ void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& pl
|
|||
pLand->setHouse( house );
|
||||
|
||||
// create inventory items
|
||||
if( !initHouseModels( player, pLand, presetItem ) )
|
||||
if( !initHouseModels( player, pLand, presetCatalogId ) )
|
||||
{
|
||||
pLand->setHouse( nullptr );
|
||||
return;
|
||||
}
|
||||
|
||||
createHouse( house );
|
||||
|
||||
|
@ -750,8 +761,7 @@ void Sapphire::World::Manager::HousingMgr::updateEstateGreeting( Entity::Player&
|
|||
if( !land )
|
||||
return;
|
||||
|
||||
// todo: implement proper permissions checks
|
||||
if( land->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return;
|
||||
|
||||
auto house = land->getHouse();
|
||||
|
@ -776,8 +786,7 @@ void Sapphire::World::Manager::HousingMgr::requestEstateEditGuestAccess( Entity:
|
|||
if( !land )
|
||||
return;
|
||||
|
||||
// todo: add proper permission check
|
||||
if( land->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return;
|
||||
|
||||
auto packet = makeZonePacket< Server::FFXIVIpcHousingShowEstateGuestAccess >( player.getId() );
|
||||
|
@ -841,8 +850,7 @@ void Sapphire::World::Manager::HousingMgr::sendEstateInventory( Entity::Player&
|
|||
if( !targetLand )
|
||||
return;
|
||||
|
||||
// todo: add proper permissions checks
|
||||
if( targetLand->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *targetLand, 0 ) )
|
||||
return;
|
||||
|
||||
auto& containers = getEstateInventory( targetLand->getLandIdent() );
|
||||
|
@ -913,7 +921,7 @@ void Sapphire::World::Manager::HousingMgr::updateHouseModels( Sapphire::HousePtr
|
|||
{
|
||||
for( auto& item : intContainer->second->getItemMap() )
|
||||
{
|
||||
house->setInteriorModel( static_cast< Common::HousingInteriorSlot >( item.first ),
|
||||
house->setInteriorModel( static_cast< Common::HouseInteriorSlot >( item.first ),
|
||||
getItemAdditionalData( item.second->getId() ) );
|
||||
}
|
||||
}
|
||||
|
@ -980,12 +988,11 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity
|
|||
if( !land )
|
||||
return;
|
||||
|
||||
// todo: add proper permissions checks
|
||||
if( land->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return;
|
||||
|
||||
// todo: check item position and make sure it's not outside the plot
|
||||
// retail uses a radius based check
|
||||
// anecdotal evidence on reddit seems to imply retail uses a radius based check
|
||||
|
||||
// unlink item
|
||||
Inventory::HousingItemPtr item;
|
||||
|
@ -996,6 +1003,8 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity
|
|||
containerId == InventoryType::Bag3 )
|
||||
{
|
||||
auto tmpItem = player.dropInventoryItem( static_cast< Common::InventoryType >( containerId ), slotId );
|
||||
if( !tmpItem )
|
||||
return;
|
||||
|
||||
item = Inventory::make_HousingItem( tmpItem->getUId(), tmpItem->getId(), framework() );
|
||||
|
||||
|
@ -1029,6 +1038,76 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity
|
|||
player.sendUrgent( "An internal error occurred when placing the item." );
|
||||
}
|
||||
|
||||
void Sapphire::World::Manager::HousingMgr::reqPlaceItemInStore( Sapphire::Entity::Player& player, uint16_t landId,
|
||||
uint16_t containerId, uint16_t slotId )
|
||||
{
|
||||
LandPtr land;
|
||||
bool isOutside = false;
|
||||
|
||||
if( auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ) )
|
||||
{
|
||||
land = zone->getLand( landId );
|
||||
isOutside = true;
|
||||
}
|
||||
else if( auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ) )
|
||||
{
|
||||
// todo: this whole process is retarded and needs to be fixed
|
||||
// perhaps maintain a list of estates by ident inside housingmgr?
|
||||
auto ident = zone->getLandIdent();
|
||||
auto landSet = toLandSetId( ident.territoryTypeId, ident.wardNum );
|
||||
|
||||
land = getHousingZoneByLandSetId( landSet )->getLand( ident.landId );
|
||||
}
|
||||
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return;
|
||||
|
||||
auto invMgr = framework()->get< InventoryMgr >();
|
||||
auto ident = land->getLandIdent();
|
||||
auto& containers = getEstateInventory( ident );
|
||||
|
||||
if( isOutside )
|
||||
{
|
||||
auto& container = containers[ InventoryType::HousingExteriorStoreroom ];
|
||||
|
||||
auto freeSlot = container->getFreeSlot();
|
||||
if( freeSlot == -1 )
|
||||
return;
|
||||
|
||||
auto item = player.dropInventoryItem( static_cast< Common::InventoryType >( containerId ), slotId );
|
||||
if( !item )
|
||||
return;
|
||||
|
||||
container->setItem( freeSlot, item );
|
||||
invMgr->sendInventoryContainer( player, container );
|
||||
invMgr->saveHousingContainer( ident, container );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( auto houseContainer : m_internalStoreroomContainers )
|
||||
{
|
||||
auto needle = containers.find( houseContainer );
|
||||
if( needle == containers.end() )
|
||||
continue;
|
||||
|
||||
auto container = needle->second;
|
||||
auto freeSlot = container->getFreeSlot();
|
||||
if( freeSlot == -1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto item = player.dropInventoryItem( static_cast< Common::InventoryType >( containerId ), slotId );
|
||||
if( !item )
|
||||
return;
|
||||
|
||||
container->setItem( freeSlot, item );
|
||||
invMgr->sendInventoryContainer( player, container );
|
||||
invMgr->saveHousingContainer( ident, container );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Sapphire::World::Manager::HousingMgr::placeExternalItem( Entity::Player& player,
|
||||
Inventory::HousingItemPtr item,
|
||||
Common::LandIdent ident )
|
||||
|
@ -1094,9 +1173,6 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl
|
|||
// have a free slot
|
||||
container->setItem( freeSlot, item );
|
||||
|
||||
// todo: see comment above in placeExternalItem where the same func is called
|
||||
invMgr->saveItem( player, item );
|
||||
|
||||
// resend container
|
||||
invMgr->sendInventoryContainer( player, container );
|
||||
invMgr->saveHousingContainer( ident, container );
|
||||
|
@ -1163,8 +1239,7 @@ void Sapphire::World::Manager::HousingMgr::reqMoveHousingItem( Entity::Player& p
|
|||
if( !land )
|
||||
return;
|
||||
|
||||
// todo: proper perms checks
|
||||
if( land->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return;
|
||||
|
||||
// todo: what happens when either of these fail? how does the server let the client know that the moment failed
|
||||
|
@ -1237,8 +1312,7 @@ bool Sapphire::World::Manager::HousingMgr::moveExternalItem( Entity::Player& pla
|
|||
{
|
||||
auto land = terri.getLand( ident.landId );
|
||||
|
||||
// todo: add proper perms check
|
||||
if( land->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return false;
|
||||
|
||||
auto& containers = getEstateInventory( ident );
|
||||
|
@ -1285,8 +1359,7 @@ void Sapphire::World::Manager::HousingMgr::reqRemoveHousingItem( Sapphire::Entit
|
|||
if( !land )
|
||||
return;
|
||||
|
||||
// todo: proper perms checks
|
||||
if( land->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return;
|
||||
|
||||
removeInternalItem( player, *terri, containerId, slot, sendToStoreroom );
|
||||
|
@ -1297,7 +1370,7 @@ void Sapphire::World::Manager::HousingMgr::reqRemoveHousingItem( Sapphire::Entit
|
|||
if( !land )
|
||||
return;
|
||||
|
||||
if( land->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return;
|
||||
|
||||
auto containerType = static_cast< Common::InventoryType >( containerId );
|
||||
|
@ -1406,11 +1479,13 @@ bool Sapphire::World::Manager::HousingMgr::removeExternalItem( Entity::Player& p
|
|||
if( !item )
|
||||
return false;
|
||||
|
||||
bool shouldDespawnItem = containerType != InventoryType::HousingExteriorStoreroom;
|
||||
|
||||
auto invMgr = framework()->get< InventoryMgr >();
|
||||
|
||||
if( sendToStoreroom )
|
||||
{
|
||||
auto& storeroomContainer = containers[ InventoryType::HousingExteriorStoreroom ];
|
||||
auto& storeroomContainer = containers[ containerType ];
|
||||
auto freeSlot = storeroomContainer->getFreeSlot();
|
||||
|
||||
if( freeSlot == -1 )
|
||||
|
@ -1418,8 +1493,8 @@ bool Sapphire::World::Manager::HousingMgr::removeExternalItem( Entity::Player& p
|
|||
|
||||
sourceContainer->removeItem( slotId );
|
||||
invMgr->sendInventoryContainer( player, sourceContainer );
|
||||
invMgr->removeHousingItemPosition( *item );
|
||||
invMgr->removeItemFromHousingContainer( land.getLandIdent(), sourceContainer->getId(), slotId );
|
||||
invMgr->removeHousingItemPosition( *item );
|
||||
|
||||
storeroomContainer->setItem( freeSlot, item );
|
||||
invMgr->sendInventoryContainer( player, storeroomContainer );
|
||||
|
@ -1441,7 +1516,8 @@ bool Sapphire::World::Manager::HousingMgr::removeExternalItem( Entity::Player& p
|
|||
player.insertInventoryItem( containerPair.first, containerPair.second, item );
|
||||
}
|
||||
|
||||
terri.despawnYardObject( land.getLandIdent().landId, slotId );
|
||||
if( shouldDespawnItem )
|
||||
terri.despawnYardObject( land.getLandIdent().landId, slotId );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1482,8 +1558,7 @@ void Sapphire::World::Manager::HousingMgr::reqEstateExteriorRemodel( Sapphire::E
|
|||
if( !land )
|
||||
return;
|
||||
|
||||
// todo: proper perms checks
|
||||
if( land->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return;
|
||||
|
||||
auto& inv = getEstateInventory( land->getLandIdent() );
|
||||
|
@ -1513,8 +1588,7 @@ void Sapphire::World::Manager::HousingMgr::reqEstateInteriorRemodel( Sapphire::E
|
|||
if( !land )
|
||||
return;
|
||||
|
||||
// todo: proper perms checks
|
||||
if( land->getOwnerId() != player.getId() )
|
||||
if( !hasPermission( player, *land, 0 ) )
|
||||
return;
|
||||
|
||||
auto& inv = getEstateInventory( land->getLandIdent() );
|
||||
|
@ -1528,4 +1602,16 @@ void Sapphire::World::Manager::HousingMgr::reqEstateInteriorRemodel( Sapphire::E
|
|||
|
||||
auto pkt = Server::makeActorControl143( player.getId(), Network::ActorControl::ShowEstateInternalAppearanceUI );
|
||||
player.queuePacket( pkt );
|
||||
}
|
||||
|
||||
bool Sapphire::World::Manager::HousingMgr::hasPermission( Sapphire::Entity::Player& player, Sapphire::Land& land,
|
||||
uint32_t permission )
|
||||
{
|
||||
// todo: proper perms checks pls
|
||||
if( land.getOwnerId() == player.getId() )
|
||||
return true;
|
||||
|
||||
// todo: check perms here
|
||||
|
||||
return false;
|
||||
}
|
|
@ -91,7 +91,7 @@ namespace Sapphire::World::Manager
|
|||
|
||||
bool relinquishLand( Entity::Player& player, uint8_t plot );
|
||||
|
||||
void buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetItem );
|
||||
void buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetCatalogId );
|
||||
|
||||
void requestEstateRename( Entity::Player& player, const Common::LandIdent ident );
|
||||
|
||||
|
@ -159,6 +159,8 @@ namespace Sapphire::World::Manager
|
|||
void reqPlaceHousingItem( Entity::Player& player, uint16_t landId, uint16_t containerId, uint16_t slotId,
|
||||
Common::FFXIVARR_POSITION3 pos, float rotation );
|
||||
|
||||
void reqPlaceItemInStore( Entity::Player& player, uint16_t landId, uint16_t containerId, uint16_t slotId );
|
||||
|
||||
/*!
|
||||
* @brief Returns the equivalent YardObject for a HousingItem
|
||||
* @param item The item to convert into a YardObject
|
||||
|
@ -179,6 +181,8 @@ namespace Sapphire::World::Manager
|
|||
|
||||
void reqEstateInteriorRemodel( Entity::Player& player );
|
||||
|
||||
bool hasPermission( Entity::Player& player, Land& land, uint32_t permission );
|
||||
|
||||
private:
|
||||
|
||||
ItemContainerPtr getFreeEstateInventorySlot( Common::LandIdent ident,
|
||||
|
|
|
@ -287,7 +287,7 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createInstanceContent(
|
|||
pTeri->name, pInstanceContent->name, instanceContentId, framework() );
|
||||
pZone->init();
|
||||
|
||||
m_instanceContentToInstanceMap[ instanceContentId ][ pZone->getGuId() ] = pZone;
|
||||
m_instanceContentIdToInstanceMap[ instanceContentId ][ pZone->getGuId() ] = pZone;
|
||||
m_instanceIdToZonePtrMap[ pZone->getGuId() ] = pZone;
|
||||
m_instanceZoneSet.insert( pZone );
|
||||
|
||||
|
@ -381,7 +381,7 @@ bool Sapphire::World::Manager::TerritoryMgr::removeTerritoryInstance( uint32_t i
|
|||
if( isInstanceContentTerritory( pZone->getTerritoryTypeId() ) )
|
||||
{
|
||||
auto instance = std::dynamic_pointer_cast< InstanceContent >( pZone );
|
||||
m_instanceContentToInstanceMap[ instance->getInstanceContentId() ].erase( pZone->getGuId() );
|
||||
m_instanceContentIdToInstanceMap[ instance->getInstanceContentId() ].erase( pZone->getGuId() );
|
||||
}
|
||||
else
|
||||
m_territoryTypeIdToInstanceGuidMap[ pZone->getTerritoryTypeId() ].erase( pZone->getGuId() );
|
||||
|
@ -486,8 +486,8 @@ void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint32_t
|
|||
Sapphire::World::Manager::TerritoryMgr::InstanceIdList Sapphire::World::Manager::TerritoryMgr::getInstanceContentIdList( uint16_t instanceContentId ) const
|
||||
{
|
||||
std::vector< uint32_t > idList;
|
||||
auto zoneMap = m_instanceContentToInstanceMap.find( instanceContentId );
|
||||
if( zoneMap == m_instanceContentToInstanceMap.end() )
|
||||
auto zoneMap = m_instanceContentIdToInstanceMap.find( instanceContentId );
|
||||
if( zoneMap == m_instanceContentIdToInstanceMap.end() )
|
||||
return idList;
|
||||
|
||||
for( auto& entry : zoneMap->second )
|
||||
|
|
|
@ -176,7 +176,7 @@ namespace Sapphire::World::Manager
|
|||
LandSetIdToZonePtrMap m_landSetIdToZonePtrMap;
|
||||
|
||||
/*! map holding actual instances of InstanceContent */
|
||||
InstanceContentIdToInstanceMap m_instanceContentToInstanceMap;
|
||||
InstanceContentIdToInstanceMap m_instanceContentIdToInstanceMap;
|
||||
|
||||
/*! flat map for easier lookup of instances by guid */
|
||||
InstanceIdToZonePtrMap m_instanceIdToZonePtrMap;
|
||||
|
|
|
@ -731,8 +731,14 @@ void Sapphire::Network::GameConnection::reqPlaceHousingItem( FrameworkPtr pFw,
|
|||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcReqPlaceHousingItem >( inPacket );
|
||||
const auto& data = packet.data();
|
||||
|
||||
housingMgr->reqPlaceHousingItem( player, data.landId, data.sourceInvContainerId, data.sourceInvSlotId,
|
||||
data.position, data.rotation );
|
||||
if( data.shouldPlaceItem == 1 )
|
||||
{
|
||||
housingMgr->reqPlaceHousingItem( player, data.landId, data.sourceInvContainerId, data.sourceInvSlotId,
|
||||
data.position, data.rotation );
|
||||
}
|
||||
else
|
||||
housingMgr->reqPlaceItemInStore( player, data.landId, data.sourceInvContainerId, data.sourceInvSlotId );
|
||||
|
||||
}
|
||||
|
||||
void Sapphire::Network::GameConnection::reqMoveHousingItem( FrameworkPtr pFw,
|
||||
|
|
|
@ -19,7 +19,10 @@ Sapphire::House::House( uint32_t houseId, uint32_t landSetId, Common::LandIdent
|
|||
m_estateName( estateName ),
|
||||
m_estateComment( estateComment ),
|
||||
m_pFw( pFw )
|
||||
{}
|
||||
{
|
||||
m_interiorModelCache.fill( 0 );
|
||||
m_exteriorModelCache.fill( std::make_pair( 0, 0 ) );
|
||||
}
|
||||
|
||||
Sapphire::House::~House() = default;
|
||||
|
||||
|
@ -57,7 +60,7 @@ uint32_t Sapphire::House::getId() const
|
|||
return m_houseId;
|
||||
}
|
||||
|
||||
Sapphire::House::HouseModelsArray const& Sapphire::House::getHouseModels() const
|
||||
Sapphire::House::ExteriorModelsArray const& Sapphire::House::getHouseModels() const
|
||||
{
|
||||
return m_exteriorModelCache;
|
||||
}
|
||||
|
@ -96,12 +99,12 @@ Sapphire::House::HousePart Sapphire::House::getExteriorModel( Sapphire::Common::
|
|||
return m_exteriorModelCache[ slot ];
|
||||
}
|
||||
|
||||
void Sapphire::House::setInteriorModel( Sapphire::Common::HousingInteriorSlot slot, uint32_t modelId )
|
||||
void Sapphire::House::setInteriorModel( Sapphire::Common::HouseInteriorSlot slot, uint32_t modelId )
|
||||
{
|
||||
m_interiorModelCache[ slot ] = modelId;
|
||||
}
|
||||
|
||||
uint32_t Sapphire::House::getInteriorModel( Sapphire::Common::HousingInteriorSlot slot )
|
||||
uint32_t Sapphire::House::getInteriorModel( Sapphire::Common::HouseInteriorSlot slot )
|
||||
{
|
||||
return m_interiorModelCache[ slot ];
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <Common.h>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <array>
|
||||
|
||||
namespace Sapphire
|
||||
{
|
||||
|
@ -17,7 +18,8 @@ namespace Sapphire
|
|||
virtual ~House();
|
||||
|
||||
using HousePart = std::pair< uint32_t, uint16_t >;
|
||||
using HouseModelsArray = std::array< HousePart, 8 >;
|
||||
using ExteriorModelsArray = std::array< HousePart, 8 >;
|
||||
using InteriorModelsArray = std::array< uint32_t, 10 >;
|
||||
|
||||
//gerneral
|
||||
uint32_t getLandSetId() const;
|
||||
|
@ -34,10 +36,10 @@ namespace Sapphire
|
|||
void setExteriorModel( Common::HouseExteriorSlot slot, uint32_t modelId, uint16_t stain );
|
||||
HousePart getExteriorModel( Common::HouseExteriorSlot slot );
|
||||
|
||||
void setInteriorModel( Common::HousingInteriorSlot slot, uint32_t modelId );
|
||||
uint32_t getInteriorModel( Common::HousingInteriorSlot slot );
|
||||
void setInteriorModel( Common::HouseInteriorSlot slot, uint32_t modelId );
|
||||
uint32_t getInteriorModel( Common::HouseInteriorSlot slot );
|
||||
|
||||
HouseModelsArray const& getHouseModels() const;
|
||||
ExteriorModelsArray const& getHouseModels() const;
|
||||
|
||||
void updateHouseDb();
|
||||
|
||||
|
@ -52,8 +54,8 @@ namespace Sapphire
|
|||
uint64_t m_buildTime;
|
||||
bool m_hasAetheryte;
|
||||
|
||||
HouseModelsArray m_exteriorModelCache;
|
||||
uint32_t m_interiorModelCache[10];
|
||||
ExteriorModelsArray m_exteriorModelCache;
|
||||
InteriorModelsArray m_interiorModelCache;
|
||||
|
||||
std::string m_estateComment;
|
||||
std::string m_estateName;
|
||||
|
|
|
@ -71,7 +71,7 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZone
|
|||
for( auto i = 0; i < 10; i++ )
|
||||
{
|
||||
indoorInitPacket->data().indoorItems[ i ] = pHouse->getInteriorModel(
|
||||
static_cast< Common::HousingInteriorSlot >( i ) );
|
||||
static_cast< Common::HouseInteriorSlot >( i ) );
|
||||
}
|
||||
|
||||
player.queuePacket( indoorInitPacket );
|
||||
|
|
|
@ -714,7 +714,6 @@ void Sapphire::Zone::registerEObj( Entity::EventObjectPtr object )
|
|||
if( !object )
|
||||
return;
|
||||
|
||||
object->setId( getNextEObjId() );
|
||||
pushActor( object );
|
||||
|
||||
m_eventObjects[ object->getId() ] = object;
|
||||
|
|
Loading…
Add table
Reference in a new issue