Jump to content

Fix Item Refinement Crash with Same Material


Recommended Posts

  • Honorable Member

When item materials are removed from the refinment process the source item that is beeing refined also get's removed since it's apart of the required item list and this is what causes the game core to crash after any instance like warping.

In order to fix this, we can check the source item beeing refined by position, simply by creating a new argument for the function RemoveSpecifyItem with the source item's cell position.

char_item.cpp

Spoiler

/// 1.
// Search @ DoRefineWithScroll
	for (int i = 0; i < prt->material_count; ++i)
	{
		if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
		{
			if (test_server)
			{
				ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
			}

			ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù."));
			return false;
		}
	}

	for (int i = 0; i < prt->material_count; ++i)
		RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);

// Replace with:
	for (int i = 0; i < prt->material_count; ++i)
	{
		DWORD material_count;

		if (prt->materials[i].vnum == item->GetVnum())
			material_count = prt->materials[i].count + 1;
		else
			material_count = prt->materials[i].count;

		if (CountSpecifyItem(prt->materials[i].vnum) < material_count)
		{
			if (test_server)
			{
				ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
			}

			ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù."));
			return false;
		}
	}

	for (int i = 0; i < prt->material_count; ++i)
		RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count, item->GetCell());

/// 2.
// Search @ DoRefine
		for (int i = 0; i < prt->material_count; ++i)
		{
			if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
			{
				if (test_server)
				{
					ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
				}

				ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù."));
				return false;
			}
		}

		for (int i = 0; i < prt->material_count; ++i)
			RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);

// Replace with
		for (int i = 0; i < prt->material_count; ++i)
		{
			DWORD material_count;

			if (prt->materials[i].vnum == item->GetVnum())
				material_count = prt->materials[i].count + 1;
			else
				material_count = prt->materials[i].count;

			if (CountSpecifyItem(prt->materials[i].vnum) < material_count)
			{
				if (test_server)
				{
					ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
				}

				ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù."));
				return false;
			}
		}

		for (int i = 0; i < prt->material_count; ++i)
			RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count, item->GetCell());

 

char.h

Spoiler

/// 1.
// Search
		void			RemoveSpecifyItem(DWORD vnum, DWORD count = 1);
// Replace with
		void			RemoveSpecifyItem(DWORD vnum, DWORD count = 1, DWORD sourcePos = -1);

 

Preview of fix: https://metin2.download/picture/S6ACMRa2ZApJHEV6slZx8KU4OJO7E8B2/.gifv

Edited by Metin2 Dev
Core X - External 2 Internal
  • Love 6
Link to comment
Share on other sites

Your tutorial is incompleted. (char_item part for RemoveSpecifyItem)

// char_item.cpp
// Search:
int CHARACTER::CountSpecifyItem(DWORD vnum) const
{
    int    count = 0;
    LPITEM item;

    for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
    {
// Replace with:
int CHARACTER::CountSpecifyItem(DWORD vnum, int iExceptionCell) const
{
    int    count = 0;
    LPITEM item;

    for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
    {
        if(i == iExceptionCell)
            continue;
            
            
// char_item.cpp
// Search:
void CHARACTER::RemoveSpecifyItem(DWORD vnum, DWORD count)
{
    if (0 == count)
        return;

    for (UINT i = 0; i < INVENTORY_MAX_NUM; ++i)
    {
// Replace with:
void CHARACTER::RemoveSpecifyItem(DWORD vnum, DWORD count, int iExceptionCell)
{
    if (0 == count)
        return;

    for (UINT i = 0; i < INVENTORY_MAX_NUM; ++i)
    {
        if(i == iExceptionCell)
            continue;
            
            
// char_item.cpp
// Search: 2x
            if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
// Replace with:
            if (CountSpecifyItem(prt->materials[i].vnum, item->GetCell()) < prt->materials[i].count)
            
            
// char_item.cpp
// Search: 2x
            RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);
// Replace with:
            RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count, item->GetCell());
            
            
// char.h
// Search:
        int                CountSpecifyItem(DWORD vnum) const;
        void            RemoveSpecifyItem(DWORD vnum, DWORD count = 1);
// Replace with:
        int                CountSpecifyItem(DWORD vnum, int iExceptionCell = -1) const;
        void            RemoveSpecifyItem(DWORD vnum, DWORD count = 1, int iExceptionCell = -1);

 

  • Love 3
Link to comment
Share on other sites

  • Honorable Member
Spoiler
7 hours ago, .Elijah said:

Your tutorial is incompleted. (char_item part for RemoveSpecifyItem)



// char_item.cpp
// Search:
int CHARACTER::CountSpecifyItem(DWORD vnum) const
{
    int    count = 0;
    LPITEM item;

    for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
    {
// Replace with:
int CHARACTER::CountSpecifyItem(DWORD vnum, int iExceptionCell) const
{
    int    count = 0;
    LPITEM item;

    for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
    {
        if(i == iExceptionCell)
            continue;
            
            
// char_item.cpp
// Search:
void CHARACTER::RemoveSpecifyItem(DWORD vnum, DWORD count)
{
    if (0 == count)
        return;

    for (UINT i = 0; i < INVENTORY_MAX_NUM; ++i)
    {
// Replace with:
void CHARACTER::RemoveSpecifyItem(DWORD vnum, DWORD count, int iExceptionCell)
{
    if (0 == count)
        return;

    for (UINT i = 0; i < INVENTORY_MAX_NUM; ++i)
    {
        if(i == iExceptionCell)
            continue;
            
            
// char_item.cpp
// Search: 2x
            if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
// Replace with:
            if (CountSpecifyItem(prt->materials[i].vnum, item->GetCell()) < prt->materials[i].count)
            
            
// char_item.cpp
// Search: 2x
            RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);
// Replace with:
            RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count, item->GetCell());
            
            
// char.h
// Search:
        int                CountSpecifyItem(DWORD vnum) const;
        void            RemoveSpecifyItem(DWORD vnum, DWORD count = 1);
// Replace with:
        int                CountSpecifyItem(DWORD vnum, int iExceptionCell = -1) const;
        void            RemoveSpecifyItem(DWORD vnum, DWORD count = 1, int iExceptionCell = -1);

 

It works the same but your way is cleaner, i just didn't feel the necessity of adding a new argument to the CountSpecificItem function, instead i differently added another way of counting the items. Anyway, thanks for making it more cleaner.

  • Love 2
Link to comment
Share on other sites

vor 2 Stunden schrieb Owsap:
  Inhalt unsichtbar machen

It works the same but your way is cleaner, i just didn't feel the necessity of adding a new argument to the CountSpecificItem function, instead i differently added another way of counting the items. Anyway, thanks for making it more cleaner.

Thank you ! 

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.