Jump to content

Reading more than one SourceSkin and TargetSkin on Hair & Costumes


Recommended Posts

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
  • Metin2 Dev 3
  • Love 2
Link to comment
Share on other sites

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

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.