mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 17:43:52 +00:00
refactor: extract loadWeaponM2() to deduplicate weapon model loading
Extract shared M2+skin loading logic into Application::loadWeaponM2(), replacing duplicate 15-line blocks in loadEquippedWeapons() and tryAttachCreatureVirtualWeapons(). Future weapon loading changes only need to update one place.
This commit is contained in:
parent
43caf7b5e6
commit
56f8f5c592
2 changed files with 24 additions and 45 deletions
|
|
@ -73,6 +73,7 @@ public:
|
||||||
|
|
||||||
// Weapon loading (called at spawn and on equipment change)
|
// Weapon loading (called at spawn and on equipment change)
|
||||||
void loadEquippedWeapons();
|
void loadEquippedWeapons();
|
||||||
|
bool loadWeaponM2(const std::string& m2Path, pipeline::M2Model& outModel);
|
||||||
|
|
||||||
// Logout to login screen
|
// Logout to login screen
|
||||||
void logoutToLogin();
|
void logoutToLogin();
|
||||||
|
|
|
||||||
|
|
@ -4016,6 +4016,21 @@ void Application::spawnPlayerCharacter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Application::loadWeaponM2(const std::string& m2Path, pipeline::M2Model& outModel) {
|
||||||
|
auto m2Data = assetManager->readFile(m2Path);
|
||||||
|
if (m2Data.empty()) return false;
|
||||||
|
outModel = pipeline::M2Loader::load(m2Data);
|
||||||
|
// Load skin (WotLK+ M2 format): strip .m2, append 00.skin
|
||||||
|
std::string skinPath = m2Path;
|
||||||
|
size_t dotPos = skinPath.rfind('.');
|
||||||
|
if (dotPos != std::string::npos) skinPath = skinPath.substr(0, dotPos);
|
||||||
|
skinPath += "00.skin";
|
||||||
|
auto skinData = assetManager->readFile(skinPath);
|
||||||
|
if (!skinData.empty() && outModel.version >= 264)
|
||||||
|
pipeline::M2Loader::loadSkin(skinData, outModel);
|
||||||
|
return outModel.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
void Application::loadEquippedWeapons() {
|
void Application::loadEquippedWeapons() {
|
||||||
if (!renderer || !renderer->getCharacterRenderer() || !assetManager || !assetManager->isInitialized())
|
if (!renderer || !renderer->getCharacterRenderer() || !assetManager || !assetManager->isInitialized())
|
||||||
return;
|
return;
|
||||||
|
|
@ -4090,39 +4105,15 @@ void Application::loadEquippedWeapons() {
|
||||||
|
|
||||||
// Try Weapon directory first, then Shield
|
// Try Weapon directory first, then Shield
|
||||||
std::string m2Path = "Item\\ObjectComponents\\Weapon\\" + modelFile;
|
std::string m2Path = "Item\\ObjectComponents\\Weapon\\" + modelFile;
|
||||||
auto m2Data = assetManager->readFile(m2Path);
|
pipeline::M2Model weaponModel;
|
||||||
if (m2Data.empty()) {
|
if (!loadWeaponM2(m2Path, weaponModel)) {
|
||||||
m2Path = "Item\\ObjectComponents\\Shield\\" + modelFile;
|
m2Path = "Item\\ObjectComponents\\Shield\\" + modelFile;
|
||||||
m2Data = assetManager->readFile(m2Path);
|
if (!loadWeaponM2(m2Path, weaponModel)) {
|
||||||
}
|
LOG_WARNING("loadEquippedWeapons: failed to load ", modelFile);
|
||||||
if (m2Data.empty()) {
|
charRenderer->detachWeapon(charInstanceId, ws.attachmentId);
|
||||||
LOG_WARNING("loadEquippedWeapons: failed to read ", modelFile);
|
continue;
|
||||||
charRenderer->detachWeapon(charInstanceId, ws.attachmentId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto weaponModel = pipeline::M2Loader::load(m2Data);
|
|
||||||
|
|
||||||
// Load skin file
|
|
||||||
std::string skinFile = modelFile;
|
|
||||||
{
|
|
||||||
size_t dotPos = skinFile.rfind('.');
|
|
||||||
if (dotPos != std::string::npos) {
|
|
||||||
skinFile = skinFile.substr(0, dotPos) + "00.skin";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try same directory as m2
|
|
||||||
std::string skinDir = m2Path.substr(0, m2Path.rfind('\\') + 1);
|
|
||||||
auto skinData = assetManager->readFile(skinDir + skinFile);
|
|
||||||
if (!skinData.empty() && weaponModel.version >= 264) {
|
|
||||||
pipeline::M2Loader::loadSkin(skinData, weaponModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!weaponModel.isValid()) {
|
|
||||||
LOG_WARNING("loadEquippedWeapons: invalid weapon model from ", m2Path);
|
|
||||||
charRenderer->detachWeapon(charInstanceId, ws.attachmentId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build texture path
|
// Build texture path
|
||||||
std::string texturePath;
|
std::string texturePath;
|
||||||
|
|
@ -4228,22 +4219,9 @@ bool Application::tryAttachCreatureVirtualWeapons(uint64_t guid, uint32_t instan
|
||||||
modelFile += ".m2";
|
modelFile += ".m2";
|
||||||
|
|
||||||
// Main-hand NPC weapon path: only use actual weapon models.
|
// Main-hand NPC weapon path: only use actual weapon models.
|
||||||
// This avoids shields/placeholder hilts being attached incorrectly.
|
|
||||||
std::string m2Path = "Item\\ObjectComponents\\Weapon\\" + modelFile;
|
std::string m2Path = "Item\\ObjectComponents\\Weapon\\" + modelFile;
|
||||||
auto m2Data = assetManager->readFile(m2Path);
|
pipeline::M2Model weaponModel;
|
||||||
if (m2Data.empty()) return false;
|
if (!loadWeaponM2(m2Path, weaponModel)) return false;
|
||||||
|
|
||||||
auto weaponModel = pipeline::M2Loader::load(m2Data);
|
|
||||||
std::string skinFile = modelFile;
|
|
||||||
size_t skinDot = skinFile.rfind('.');
|
|
||||||
if (skinDot != std::string::npos) skinFile = skinFile.substr(0, skinDot);
|
|
||||||
skinFile += "00.skin";
|
|
||||||
std::string skinDir = m2Path.substr(0, m2Path.rfind('\\') + 1);
|
|
||||||
auto skinData = assetManager->readFile(skinDir + skinFile);
|
|
||||||
if (!skinData.empty() && weaponModel.version >= 264) {
|
|
||||||
pipeline::M2Loader::loadSkin(skinData, weaponModel);
|
|
||||||
}
|
|
||||||
if (!weaponModel.isValid()) return false;
|
|
||||||
|
|
||||||
std::string texturePath;
|
std::string texturePath;
|
||||||
if (!textureName.empty()) {
|
if (!textureName.empty()) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue