NoNameBoyyy 5 Posted September 11, 2023 Share Posted September 11, 2023 You can change how many TargetSkins and SourceSkins to be read on a single model, on hair or on costume models. With this, if you have a models with multiple textures which have alpha channel on each of them, they will all be read, instead of only one. Example: Group ShapeData240 { SpecialPath "d:/ymir work/example/" ShapeIndex 37500 Model "assassin_m.gr2" SourceSkin "texture_m.dds" TargetSkin "texture_m.dds" SourceSkin2 "texture_2.dds" TargetSkin2 "texture_2.dds" SourceSkin3 "texture_3.dds" TargetSkin3 "texture_3.dds" SourceSkin4 "texture_4.dds" TargetSkin4 "texture_4.dds" SourceSkin5 "texture_5.dds" TargetSkin5 "texture_5.dds" SourceSkin6 "texture_6.dds" TargetSkin6 "texture_6.dds" ... } etc. the same for hair Code - Pastebin : https://pastebin.com/Nu1AJ7z4 - Look for #ifdef ENABLE_SKIN_EXTENDED Spoiler #include "StdAfx.h" #include "../eterLib/ResourceManager.h" #include "RaceData.h" #include "RaceMotionData.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////// #define ENABLE_SKIN_EXTENDED BOOL CRaceData::LoadRaceData(const char * c_szFileName) { CTextFileLoader TextFileLoader; if (!TextFileLoader.Load(c_szFileName)) return FALSE; TextFileLoader.SetTop(); TextFileLoader.GetTokenString("basemodelfilename", &m_strBaseModelFileName); TextFileLoader.GetTokenString("treefilename", &m_strTreeFileName); TextFileLoader.GetTokenString("attributefilename", &m_strAttributeFileName); TextFileLoader.GetTokenString("smokebonename", &m_strSmokeBoneName); TextFileLoader.GetTokenString("motionlistfilename", &m_strMotionListFileName); if (!m_strTreeFileName.empty()) { CFileNameHelper::StringPath(m_strTreeFileName); } CTokenVector* pSmokeTokenVector; if (TextFileLoader.GetTokenVector("smokefilename", &pSmokeTokenVector)) { if (pSmokeTokenVector->size()%2!=0) { TraceError("SmokeFileName ArgCount[%d]%2==0", pSmokeTokenVector->size()); return FALSE; } UINT uLineCount=pSmokeTokenVector->size()/2; for (UINT uLine=0; uLine<uLineCount; ++uLine) { int eSmoke=atoi(pSmokeTokenVector->at(uLine*2+0).c_str()); if (eSmoke<0 || eSmoke>=SMOKE_NUM) { TraceError("SmokeFileName SmokeNum[%d] OUT OF RANGE", eSmoke); return FALSE; } const std::string& c_rstrEffectFileName = pSmokeTokenVector->at(uLine*2+1); DWORD& rdwCRCEft=m_adwSmokeEffectID[eSmoke]; if (!CEffectManager::Instance().RegisterEffect2(c_rstrEffectFileName.c_str(), &rdwCRCEft)) { TraceError("CRaceData::RegisterEffect2(%s) ERROR", c_rstrEffectFileName.c_str()); rdwCRCEft=0; return false; } } } if (TextFileLoader.SetChildNode("shapedata")) { std::string strPathName; DWORD dwShapeDataCount = 0; if (TextFileLoader.GetTokenString("pathname", &strPathName) && TextFileLoader.GetTokenDoubleWord("shapedatacount", &dwShapeDataCount)) { for (DWORD i = 0; i < dwShapeDataCount; ++i) { if (!TextFileLoader.SetChildNode("shapedata", i)) { continue; } ///////////////////////// TextFileLoader.GetTokenString("specialpath", &strPathName); ///////////////////////// DWORD dwShapeIndex; if (!TextFileLoader.GetTokenDoubleWord("shapeindex", &dwShapeIndex)) { continue; } // LOCAL_PATH_SUPPORT std::string strModel; if (TextFileLoader.GetTokenString("model", &strModel)) { SetShapeModel(dwShapeIndex, (strPathName + strModel).c_str()); } else { if (!TextFileLoader.GetTokenString("local_model", &strModel)) continue; SetShapeModel(dwShapeIndex, strModel.c_str()); } // END_OF_LOCAL_PATH_SUPPORT std::string strSourceSkin; std::string strTargetSkin; #ifdef ENABLE_SKIN_EXTENDED constexpr auto minSkinExtension = 2; constexpr auto maxSkinExtension = 9; static char __szSourceSkin[10+6+2+1]; static char __szTargetSkin[10+6+2+1]; #endif // LOCAL_PATH_SUPPORT if (TextFileLoader.GetTokenString("local_sourceskin", &strSourceSkin) && TextFileLoader.GetTokenString("local_targetskin", &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, strSourceSkin.c_str(), strTargetSkin.c_str()); } #ifdef ENABLE_SKIN_EXTENDED for (auto j=minSkinExtension; j<=maxSkinExtension; j++) { _snprintf(__szSourceSkin, sizeof(__szSourceSkin), "local_sourceskin%d", j); _snprintf(__szTargetSkin, sizeof(__szTargetSkin), "local_targetskin%d", j); if (TextFileLoader.GetTokenString(__szSourceSkin, &strSourceSkin) && TextFileLoader.GetTokenString(__szTargetSkin, &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, __szSourceSkin, __szTargetSkin); } } #endif // END_OF_LOCAL_PATH_SUPPORT if (TextFileLoader.GetTokenString("sourceskin", &strSourceSkin) && TextFileLoader.GetTokenString("targetskin", &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } #ifdef ENABLE_SKIN_EXTENDED for (auto j=minSkinExtension; j<=maxSkinExtension; j++) { _snprintf(__szSourceSkin, sizeof(__szSourceSkin), "sourceskin%d", j); _snprintf(__szTargetSkin, sizeof(__szTargetSkin), "targetskin%d", j); if (TextFileLoader.GetTokenString(__szSourceSkin, &strSourceSkin) && TextFileLoader.GetTokenString(__szTargetSkin, &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } } #else if (TextFileLoader.GetTokenString("sourceskin2", &strSourceSkin) && TextFileLoader.GetTokenString("targetskin2", &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } #endif TextFileLoader.SetParentNode(); } } TextFileLoader.SetParentNode(); } if (TextFileLoader.SetChildNode("hairdata")) { std::string strPathName; DWORD dwHairDataCount = 0; if (TextFileLoader.GetTokenString("pathname", &strPathName) && TextFileLoader.GetTokenDoubleWord("hairdatacount", &dwHairDataCount)) { for (DWORD i = 0; i < dwHairDataCount; ++i) { if (!TextFileLoader.SetChildNode("hairdata", i)) { continue; } ///////////////////////// TextFileLoader.GetTokenString("specialpath", &strPathName); ///////////////////////// DWORD dwShapeIndex; if (!TextFileLoader.GetTokenDoubleWord("hairindex", &dwShapeIndex)) { continue; } std::string strModel; std::string strSourceSkin; std::string strTargetSkin; #ifdef ENABLE_SKIN_EXTENDED constexpr auto minSkinExtension = 2; constexpr auto maxSkinExtension = 9; static char __szSourceSkin[10 + 6 + 2 + 1]; static char __szTargetSkin[10 + 6 + 2 + 1]; #endif if (TextFileLoader.GetTokenString("model", &strModel) && TextFileLoader.GetTokenString("sourceskin", &strSourceSkin) && TextFileLoader.GetTokenString("targetskin", &strTargetSkin)) { SetHairSkin(dwShapeIndex, 0, (strPathName + strModel).c_str(), (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } #ifdef ENABLE_SKIN_EXTENDED for (auto j = minSkinExtension; j <= maxSkinExtension; j++) { _snprintf(__szSourceSkin, sizeof(__szSourceSkin), "sourceskin%d", j); _snprintf(__szTargetSkin, sizeof(__szTargetSkin), "targetskin%d", j); if (TextFileLoader.GetTokenString("model", &strModel) && TextFileLoader.GetTokenString(__szSourceSkin, &strSourceSkin) && TextFileLoader.GetTokenString(__szTargetSkin, & strTargetSkin)) { SetHairSkin(dwShapeIndex, 0, (strPathName + strModel).c_str(), (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } } if (TextFileLoader.GetTokenString("local_model", &strModel) && TextFileLoader.GetTokenString("local_sourceskin", &strSourceSkin) && TextFileLoader.GetTokenString("local_targetskin", &strTargetSkin)) { SetHairSkin(dwShapeIndex, 0, strModel.c_str(), strSourceSkin.c_str(), strTargetSkin.c_str()); } #endif TextFileLoader.SetParentNode(); } } TextFileLoader.SetParentNode(); } if (TextFileLoader.SetChildNode("attachingdata")) { if (!NRaceData::LoadAttachingData(TextFileLoader, &m_AttachingDataVector)) return FALSE; TextFileLoader.SetParentNode(); } return TRUE; } or separate code: UserInterface/Locale_inc.h Spoiler add: #define ENABLE_SKIN_EXTENDED //extended TargetSkin and SourceSkin in class.msm Gamelib/RaceDataFile.cpp For costumes: Spoiler search in if (TextFileLoader.SetChildNode("shapedata")): std::string strSourceSkin; std::string strTargetSkin; add after #ifdef ENABLE_SKIN_EXTENDED constexpr auto minSkinExtension = 2; constexpr auto maxSkinExtension = 9; //add the number of how many targetskin and sourceskins to be read as maximum value. static char __szSourceSkin[10+6+2+1]; static char __szTargetSkin[10+6+2+1]; #endif search: AppendShapeSkin(dwShapeIndex, 0, strSourceSkin.c_str(), strTargetSkin.c_str()); } add: #ifdef ENABLE_SKIN_EXTENDED for (auto j=minSkinExtension; j<=maxSkinExtension; j++) { _snprintf(__szSourceSkin, sizeof(__szSourceSkin), "local_sourceskin%d", j); _snprintf(__szTargetSkin, sizeof(__szTargetSkin), "local_targetskin%d", j); if (TextFileLoader.GetTokenString(__szSourceSkin, &strSourceSkin) && TextFileLoader.GetTokenString(__szTargetSkin, &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, __szSourceSkin, __szTargetSkin); } } #endif search: if (TextFileLoader.GetTokenString("sourceskin2", &strSourceSkin) && TextFileLoader.GetTokenString("targetskin2", &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } replace: #ifdef ENABLE_SKIN_EXTENDED for (auto j=minSkinExtension; j<=maxSkinExtension; j++) { _snprintf(__szSourceSkin, sizeof(__szSourceSkin), "sourceskin%d", j); _snprintf(__szTargetSkin, sizeof(__szTargetSkin), "targetskin%d", j); if (TextFileLoader.GetTokenString(__szSourceSkin, &strSourceSkin) && TextFileLoader.GetTokenString(__szTargetSkin, &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } } #else if (TextFileLoader.GetTokenString("sourceskin2", &strSourceSkin) && TextFileLoader.GetTokenString("targetskin2", &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } #endif For hair: Spoiler Search in if (TextFileLoader.SetChildNode("hairdata")) std::string strModel; std::string strSourceSkin; std::string strTargetSkin; add after: #ifdef ENABLE_SKIN_EXTENDED constexpr auto minSkinExtension = 2; constexpr auto maxSkinExtension = 9; //add the number of how many targetskin and sourceskins to be read as maximum value. static char __szSourceSkin[10 + 6 + 2 + 1]; static char __szTargetSkin[10 + 6 + 2 + 1]; #endif search: SetHairSkin(dwShapeIndex, 0, (strPathName + strModel).c_str(), (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } add after: #ifdef ENABLE_SKIN_EXTENDED for (auto j = minSkinExtension; j <= maxSkinExtension; j++) { _snprintf(__szSourceSkin, sizeof(__szSourceSkin), "sourceskin%d", j); _snprintf(__szTargetSkin, sizeof(__szTargetSkin), "targetskin%d", j); if (TextFileLoader.GetTokenString("model", &strModel) && TextFileLoader.GetTokenString(__szSourceSkin, &strSourceSkin) && TextFileLoader.GetTokenString(__szTargetSkin, & strTargetSkin)) { SetHairSkin(dwShapeIndex, 0, (strPathName + strModel).c_str(), (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } } if (TextFileLoader.GetTokenString("local_model", &strModel) && TextFileLoader.GetTokenString("local_sourceskin", &strSourceSkin) && TextFileLoader.GetTokenString("local_targetskin", &strTargetSkin)) { SetHairSkin(dwShapeIndex, 0, strModel.c_str(), strSourceSkin.c_str(), strTargetSkin.c_str()); } #endif 3 2 Link to comment Share on other sites More sharing options...
Active Member [A]Demonul 131 Posted September 13, 2023 Active Member Share Posted September 13, 2023 Perfect working with 10 textures on hair. Thank you Link to comment Share on other sites More sharing options...
Powell 8 Posted September 14, 2023 Share Posted September 14, 2023 std::string strPathName; int maxSkinCount = 500; // You can change how many TargetSkins and SourceSkins wants to be here. for (int i = 1; i <= maxSkinCount; ++i) { std::string sourceToken = "sourceskin" + std::to_string(i); std::string targetToken = "targetskin" + std::to_string(i); std::string strSourceSkin; std::string strTargetSkin; if (TextFileLoader.GetTokenString(sourceToken.c_str(), &strSourceSkin) && TextFileLoader.GetTokenString(targetToken.c_str(), &strTargetSkin)) { AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); } } I think, many if and else copy paste blocks waste of time. This for loop good waypoint at this moment maybe i dont know. Link to comment Share on other sites More sharing options...
Recommended Posts