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:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user