diff --git a/src/server/game/Housing/Housing.cpp b/src/server/game/Housing/Housing.cpp index 7b6a4629c..f60000d89 100644 --- a/src/server/game/Housing/Housing.cpp +++ b/src/server/game/Housing/Housing.cpp @@ -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(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()); + } +} diff --git a/src/server/game/Housing/Housing.h b/src/server/game/Housing/Housing.h index 2637c0859..04c6c5100 100644 --- a/src/server/game/Housing/Housing.h +++ b/src/server/game/Housing/Housing.h @@ -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; diff --git a/src/server/game/Housing/HousingMgr.cpp b/src/server/game/Housing/HousingMgr.cpp index ed5954a52..6107c1c52 100644 --- a/src/server/game/Housing/HousingMgr.cpp +++ b/src/server/game/Housing/HousingMgr.cpp @@ -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); diff --git a/src/server/game/Housing/HousingMgr.h b/src/server/game/Housing/HousingMgr.h index 819b402ea..52ab23c95 100644 --- a/src/server/game/Housing/HousingMgr.h +++ b/src/server/game/Housing/HousingMgr.h @@ -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;