Housing: Add racial house styles and starter fixture persistence

Map player race to house exterior WMO style on purchase:
Night Elf → Woodland (55), Blood Elf → Engraved (56),
other Alliance → Human (9), other Horde → Orc (87).

On house creation, persist starter fixtures (Base + Roof) to
character_housing_fixtures so spawning reads from DB rather than
relying on runtime default resolution. Door auto-resolves from
the hook system via GetDefaultFixtureForType.
This commit is contained in:
luis
2026-03-15 17:54:46 -03:00
parent 06a4b3f844
commit dd888b36db
4 changed files with 63 additions and 6 deletions
+43 -6
View File
@@ -555,12 +555,8 @@ HousingResult Housing::Create(ObjectGuid neighborhoodGuid, uint8 plotIndex)
_editorMode = HOUSING_EDITOR_MODE_NONE;
_exteriorLocked = false;
_houseSize = HOUSING_FIXTURE_SIZE_SMALL;
// Sniff-verified WmoDataIDs: 9=Alliance, 87=Horde
Neighborhood* neighborhood = sNeighborhoodMgr.GetNeighborhood(neighborhoodGuid);
if (neighborhood && neighborhood->GetFactionRestriction() == NEIGHBORHOOD_FACTION_HORDE)
_houseType = 87;
else
_houseType = 9;
// Racial house style: Night Elf ? 55, Blood Elf ? 56, other Alliance ? 9, other Horde ? 87
_houseType = HousingMgr::GetRacialWmoDataID(_owner->GetRace(), _owner->GetTeam());
_createTime = static_cast<uint32>(GameTime::GetGameTime());
_hasCustomPosition = false;
_housePosX = _housePosY = _housePosZ = _houseFacing = 0.0f;
@@ -612,6 +608,10 @@ HousingResult Housing::Create(ObjectGuid neighborhoodGuid, uint8 plotIndex)
_owner->GetName());
}
// Populate starter fixtures: Base + Roof for the racial WMO style.
// These are persisted to DB so spawning only reads what's stored.
PopulateStarterFixtures();
return HOUSING_RESULT_SUCCESS;
}
@@ -2338,3 +2338,40 @@ void Housing::PersistFixtureToDB(uint32 fixturePointId, uint32 optionId)
stmt->setUInt32(2, fixturePointId);
CharacterDatabase.Execute(stmt);
}
void Housing::PopulateStarterFixtures()
{
// Starter house = Base(9) + Roof(10) as root components.
// Door(11) auto-resolves from hook system via GetDefaultFixtureForType.
// Root components are stored as { FixturePointId = componentID, OptionId = 0 }.
static constexpr uint8 starterTypes[] = { HOUSING_FIXTURE_TYPE_BASE, HOUSING_FIXTURE_TYPE_ROOF };
uint64 ownerGuid = _owner->GetGUID().GetCounter();
for (uint8 fixtureType : starterTypes)
{
uint32 compID = sHousingMgr.GetDefaultFixtureForType(fixtureType, _houseType);
if (!compID)
{
TC_LOG_ERROR("housing", "Housing::PopulateStarterFixtures: No default component for type={} wmo={} ? skipping",
fixtureType, _houseType);
continue;
}
// Insert into in-memory map
Fixture& fixture = _fixtures[compID];
fixture.FixturePointId = compID;
fixture.OptionId = 0;
// Persist to DB
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_HOUSING_FIXTURES);
uint8 index = 0;
stmt->setUInt64(index++, ownerGuid);
stmt->setUInt32(index++, compID);
stmt->setUInt32(index++, 0); // OptionId = 0 (default)
CharacterDatabase.Execute(stmt);
TC_LOG_INFO("housing", "Housing::PopulateStarterFixtures: Added type={} compID={} wmo={} for player {}",
fixtureType, compID, _houseType, _owner->GetName());
}
}
+3
View File
@@ -242,6 +242,9 @@ private:
void PersistRoomToDB(ObjectGuid roomGuid, Room const& room);
void PersistFixtureToDB(uint32 fixturePointId, uint32 optionId);
// Populate starter fixtures (Base + Roof) on house creation
void PopulateStarterFixtures();
Player* _owner;
ObjectGuid _houseGuid;
ObjectGuid _neighborhoodGuid;
+13
View File
@@ -26,7 +26,9 @@
#include "Neighborhood.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "RaceMask.h"
#include "Random.h"
#include "SharedDefines.h"
#include "SocialMgr.h"
#include "StringFormat.h"
#include "Timer.h"
@@ -1404,6 +1406,17 @@ uint32 HousingMgr::GetDefaultFixtureForType(uint8 componentType, uint32 wmoDataI
return itr != _defaultFixtureByTypeWmo.end() ? itr->second : 0;
}
uint32 HousingMgr::GetRacialWmoDataID(uint8 race, uint32 teamId)
{
switch (race)
{
case RACE_NIGHTELF: return 55; // Woodland
case RACE_BLOODELF: return 56; // Engraved
default:
return (teamId == HORDE) ? 87 : 9; // Orc / Human
}
}
ExteriorComponentExitPointEntry const* HousingMgr::GetExitPoint(uint32 extCompID) const
{
auto itr = _exitPointByExtComp.find(extCompID);
+4
View File
@@ -340,6 +340,10 @@ public:
// returns the default fixture component ID (Flags & 0x1, ParentComponentID == 0).
uint32 GetDefaultFixtureForType(uint8 componentType, uint32 wmoDataID) const;
// Racial house style: maps player race to the appropriate HouseExteriorWmoDataID.
// Night Elf ? 55, Blood Elf ? 56, other Alliance ? 9 (Human), other Horde ? 87 (Orc).
static uint32 GetRacialWmoDataID(uint8 race, uint32 teamId);
// Find the first HouseRoom entry with visual components (not the base room 18)
uint32 GetDefaultVisualRoomEntry() const;