Jump to content

Recommended Posts

  • Developer

Hi loves

USE_TUNING and USE_DETACHMENT are part of the same case and are divided by if/else (Probably for the item removed in 2013 by Italian wiki):
https://en-wiki.metin2.gameforge.com/index.php/Tincture_of_Heaven

At first glance, when I read it, I didn't understand shit about it, so I decided to improve it and publish it; it's an unpretentious post, so enjoy it.

This is the hidden content, please

Edited by Mitachi
  • Metin2 Dev 93
  • kekw 1
  • Good 12
  • Love 22

Villains are not born, they are made.
Join

Link to comment
https://metin2.dev/topic/30424-refactoring-detachmetin/
Share on other sites

dunno why, for me neither detachment nor tuning will work after splitting it up. And yeah, its not that much of changing code but it literally doesnt work anymore. Even with debug outputs, none of the 2 functions gets triggered after splitting it up. Any idea?

 

 

					case USE_TUNING:
						{
							LPITEM item2 = nullptr;

							if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
								return false;

							if (item2->IsExchanging() || item2->IsEquipped());
								return false;

#ifdef __STONE_REFINE_FIX__
							if (item->GetVnum() >= 28330 && item->GetVnum() <= 28643) // fix
							{
								ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Du kannst Steine nur bei Seon-Pyeong verbessern."));
								return false;
							}
#endif
#ifdef __RITUAL_STONE__
							if (item->GetValue(0) == RITUALS_SCROLL)
							{
								if (item2->GetLevelLimit() < item->GetValue(1))
								{
									ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Du kannst nur Items über Lv. 80 verbessern."));
									return false;
								}
								else
									RefineItem(item, item2);
							}
#endif
							else
							{
								RefineItem(item, item2);
							}
						}
						break;
					// DETACH_METIN_REFACTORING //trennung von USE_DETACHMENT und USE_TUNING in 2 funktionen
					case USE_DETACHMENT:
						{
							LPITEM item2 = nullptr;
							if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
								return false;

							if (item2->IsExchanging() || item2->IsEquipped());
								return false;
							
							ChatPacket(CHAT_TYPE_INFO, "test 3");
								
#ifdef ENABLE_SOULBIND_SYSTEM	
							if (item2->IsBind() || item2->IsUntilBind())
							{
								ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Du kannst keine Steine aus seelengebundenen Items entfernen."));
								return false;
							}
#endif
#ifdef __SASH_SYSTEM__
							if (item->GetValue(0) == SASH_CLEAN_ATTR_VALUE0)
							{
								if (!CleanSashAttr(item, item2))
									return false;
								
								return true;
							}
#endif
							DetachMetin(item, item2);
						}
						break;
					// END_OF_DETACH_METIN_REFACTORING
                              
                              
   ------------------------------
                              
bool CHARACTER::RefineItem(LPITEM pkItem, LPITEM pkTarget)
{
	if (!CanHandleItem())
		return false;

#ifdef ENABLE_AURA_SYSTEM
	if (pkTarget->GetType() == ITEM_COSTUME && pkTarget->GetSubType() == COSTUME_AURA) 
	{
		ChatPacket(CHAT_TYPE_INFO, LC_TEXT("AURA_ITEM_CANNOT_BE_REFINED_THIS_WAY"));
		return false;
	}
#endif
	ChatPacket(CHAT_TYPE_INFO, "test 5");

#ifdef ENABLE_REFINE_FAILSTACK
	int failstacks = DBManager::Instance().GetFailStacks(this);
#endif
	// MUSIN_SCROLL
	if (pkItem->GetValue(0) == MUSIN_SCROLL)
#ifdef ENABLE_REFINE_FAILSTACK
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_MUSIN, pkItem->GetCell(), failstacks, failstacks / 100);
#else
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_MUSIN, pkItem->GetCell());
#endif
	// END_OF_MUSIN_SCROLL
#ifdef ENABLE_CAN_USE_SCROLL_FOR_501_REFINESET
	else if (pkItem->GetValue(0) == CHUKBOK_SCROLL)
#ifdef ENABLE_REFINE_FAILSTACK
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_SCROLL, pkItem->GetCell(), failstacks, failstacks / 100);
#else
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_SCROLL, pkItem->GetCell());
#endif
#endif
	else if (pkItem->GetValue(0) == HYUNIRON_CHN)
#ifdef ENABLE_REFINE_FAILSTACK
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_HYUNIRON, pkItem->GetCell(), failstacks, failstacks / 100);
#else
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_HYUNIRON, pkItem->GetCell());
#endif
	else if (pkItem->GetValue(0) == BDRAGON_SCROLL)
	{
		if (pkTarget->GetRefineSet() != 702) return false;
#ifdef ENABLE_REFINE_FAILSTACK
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_BDRAGON, pkItem->GetCell(), failstacks, failstacks / 100);
#else
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_BDRAGON, pkItem->GetCell());
#endif
	}
#ifdef __RITUAL_STONE__
	else if (pkItem->GetValue(0) == RITUALS_SCROLL)
	{
		if(pkTarget->GetLevelLimit() <= pkItem->GetValue(1)) return false;
#ifdef ENABLE_REFINE_FAILSTACK
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_RITUALS_SCROLL, pkItem->GetCell(), failstacks, failstacks / 100);
#else
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_RITUALS_SCROLL, pkItem->GetCell());
#endif
	}
#endif
	else
	{
		if (pkTarget->GetRefineSet() == 501) return false;
#ifdef ENABLE_REFINE_FAILSTACK
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_SCROLL, pkItem->GetCell(), failstacks, failstacks / 100);
#else
		RefineInformation(pkTarget->GetCell(), REFINE_TYPE_SCROLL, pkItem->GetCell());
#endif
	}
	return false;
}

bool CHARACTER::DetachMetin(LPITEM pkItem, LPITEM pkTarget)
{
	//if (!(pkItem || pkTarget))
	//	return false; //deactivated just for testing
	ChatPacket(CHAT_TYPE_INFO, "test 123");
	LogManager::instance().ItemLog(this, pkTarget, "USE_DETACHMENT", pkTarget->GetName());

	bool bHasMetinStone = false;

#ifdef ENABLE_EXTENDED_SOCKETS
	for (int i = 0; i < ITEM_STONES_MAX_NUM; i++)
#else
	for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
#endif
	{
		long socket = pkTarget->GetSocket(i);
		if (socket > 2 && (DWORD)socket != ITEM_BROKEN_METIN_VNUM)
		{
			bHasMetinStone = true;
			break;
		}
	}
	
	if (bHasMetinStone)
	{
#ifdef ENABLE_EXTENDED_SOCKETS
		for (int i = 0; i < ITEM_STONES_MAX_NUM; i++)
#else
		for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
#endif
		{
			long socket = pkTarget->GetSocket(i);
			if (socket > 2 && (DWORD)socket != ITEM_BROKEN_METIN_VNUM)
			{
				ChatPacket(CHAT_TYPE_INFO, "test 2");
				AutoGiveItem(socket);
#ifdef ENABLE_BROKEN_METIN_ITEM
				pkTarget->SetSocket(i, ITEM_BROKEN_METIN_VNUM);
#endif
				pkTarget->SetSocket(i, 1);
			}
		}
		
		pkItem->SetCount(pkItem->GetCount() - 1);
		ChatPacket(CHAT_TYPE_INFO, "successfull 1");
		return true;
	}
	else
	{
		ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Es gibt keinen Stein zum Herausnehmen. "));
		return false;
	}
}                         

refine window wont open up again, stone detachment opens the yes/no dialog window but doesnt do anything after pressing yes. No crash, no syserr

 

dunno why i cant just fkn edit my comment and need to double post (thanks metin2dev) but you fked up your tut with wrong ;'s

 

					case USE_TUNING:
						{
							LPITEM item2 = nullptr;
							if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
								return false;

							if (item2->IsExchanging() || item2->IsEquipped()); <--- ???
								return false;

							RefineItem(item, item2);
						}
						break;

					// DETACH_METIN_REFACTORING
					case USE_DETACHMENT:
						{
							LPITEM item2 = nullptr;
							if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
								return false;

							if (item2->IsExchanging() || item2->IsEquipped()); <---- ???
								return false;

							DetachMetin(item, item2);
						}
						break;
					// END_OF_DETACH_METIN_REFACTORING

wont work this way

Edited by Mafuyu
  • Good 1
Link to comment
https://metin2.dev/topic/30424-refactoring-detachmetin/#findComment-155596
Share on other sites

  • 2 years later...

Sorry i'm late ; but just saw this post.
And... No don't use it.

I've got you're idea : but if you do it like this, you give players a way to generate items. I explain :

	for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
	{
		long socket = pkTarget->GetSocket(i);
		if (socket > 2 && socket != ITEM_BROKEN_METIN_VNUM)
		{
			bHasMetinStone = true;
			break;
		}
	}

Actually, USE_PUT_INTO_ACCESSORY_SOCKET items also use socket (for the remaining time). So you will give items whose vnum corresponds to the remaining time of the refineries.

I haven't touched Metin for a long time, I don't know if there is an easy way to differentiate items, but from my point of view the code should be fixed with somethings like this (DetachMetin):

	// Check if item can hold stone
	auto const pkItemProto = ITEM_MANAGER::instance().GetTable(pkTarget->GetVnum());
	if (!pkItemProto || pkItemProto->bGainSocketPct == 0)
	{
		ChatPacket(CHAT_TYPE_INFO, LC_TEXT("There is no Stone available to take out."));
		return false;
	}

(On top of your function, just after checking pkItem and pkTarget)


Update: 
I just went to look at the mainlines... They use a flag (which my old queues no longer use... To adapt according to your case) : 
 

	else if (pkItem->GetSubType() == USE_DETACHMENT && IS_SET(pkTarget->GetFlag(), ITEM_FLAG_REFINEABLE))
	{
		LogManager::instance().ItemLog(this, pkTarget, "USE_DETACHMENT", pkTarget->GetName());

		bool bHasMetinStone = false;
		// ...

 

Edited by Takuma
Link to comment
https://metin2.dev/topic/30424-refactoring-detachmetin/#findComment-170492
Share on other sites

  • Honorable Member
17 minutes ago, Takuma said:

Sorry i'm late ; but just saw this post.
And... No don't use it.

I've got you're idea : but if you do it like this, you give players a way to generate items. I explain :

	for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
	{
		long socket = pkTarget->GetSocket(i);
		if (socket > 2 && socket != ITEM_BROKEN_METIN_VNUM)
		{
			bHasMetinStone = true;
			break;
		}
	}

Actually, USE_PUT_INTO_ACCESSORY_SOCKET items also use socket (for the remaining time). So you will give items whose vnum corresponds to the remaining time of the refineries.

I haven't touched Metin for a long time, I don't know if there is an easy way to differentiate items, but from my point of view the code should be fixed with somethings like this (DetachMetin):

	// Check if item can hold stone
	auto const pkItemProto = ITEM_MANAGER::instance().GetTable(pkTarget->GetVnum());
	if (!pkItemProto || pkItemProto->bGainSocketPct == 0)
	{
		ChatPacket(CHAT_TYPE_INFO, LC_TEXT("There is no Stone available to take out."));
		return false;
	}

(On top of your function, just after checking pkItem and pkTarget)

 

 

I understand what you're saying, but that bug is not related to his change.

QxLSd7rRQyK5GGDrWWeLCA.png?width=1659&he

 

The functionality simply needs a correction, such as adding a method similiar to this in the check in char_item.cpp to distinguish between items where the spirit stone scroll can work and those where it's not supposed to, such as ores inserted into items (hence producing the bug you're talking about).

bool CItem::IsRemovableSocket()
{
    if (m_pProto->bType == ITEM_ARMOR)
        return m_pProto->bSubType == ARMOR_BODY;

    if (m_pProto->bType == ITEM_WEAPON)
        return !(m_pProto->bSubType == WEAPON_ARROW
            || m_pProto->bSubType == WEAPON_MOUNT_SPEAR
#if defined(__QUIVER_SYSTEM__)
            || m_pProto->bSubType == WEAPON_QUIVER
#endif
            || m_pProto->bSubType == WEAPON_BOUQUET);

    return false;
}
// Search
    else if (pkItem->GetSubType() == USE_DETACHMENT && IS_SET(pkTarget->GetFlag(), ITEM_FLAG_REFINEABLE))

// Replace with
    else if (pkItem->GetSubType() == USE_DETACHMENT && IS_SET(pkTarget->GetFlag(), ITEM_FLAG_REFINEABLE) && pkTarget->IsRemovableSocket())

Feel free to also make the correction in ItemData.h/PythonPlayerModule.cpp clientside, obviously.

Edited by Metin2 Dev International
Core X - External 2 Internal
  • Love 2

 

"Nothing's free in this life.

Ignorant people have an obligation to make up for their ignorance by paying those who help them.

Either you got the brains or cash, if you lack both you're useless."

Syreldar

Link to comment
https://metin2.dev/topic/30424-refactoring-detachmetin/#findComment-170493
Share on other sites

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • 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.