Jump to content

Has anyone reversed the GF [Official] Update 19.6 - Weapon Elemental System ?


Go to solution Solved by Metin2 Dev,

Recommended Posts

  • Active+ Member

Metin2 Board: Update 19.6 – Under the Spell of the Dragon King

The reason I'm interested if anyone reversed this system is because I want to know how exactly the GF [Official] **Refined Element** system works and if any variables like character level / rank / map location or any other can influence the percentage of element power assigned to a weapon on each upgrade (+1 / +2 / +3).

image-4.png?ex=6733d27e&is=673280fe&hm=a

Edited by Metin2 Dev International
Core X - External 2 Internal

Life rips

__________________________

  • Replies 4
  • Created
  • Last Reply

Top Posters In This Topic

  • Bot

I reversed it a long time ago and I also played with it on official servers.
- The element can be added on weapons +7 or bigger.
- The element can be max +3
- For each plus you get a random value of element power between 1 and 8
- For each plus you get a random value of attack between 2 and 12

I got power of element value 8 multiple times on official so I don't think they have a special algorithm for the random.

english_banner.gif

  • Active+ Member

@ Abel(Tiger) Thanks for the response, do you happen to have the source code for the system ? I'd like to take a look, I'm only interested in the part where the 2 things quoted below are determined - not the whole system (as I understand that might be sold).

Quote

- For each plus you get a random value of element power between 1 and 8
- For each plus you get a random value of attack between 2 and 12

If this 👆 is true and there are no other factors then I guess I got my answer. 

Life rips

__________________________

  • Bot
  • Solution

Here you go: 
 

Spoiler
bool CHARACTER::DoRefineElement(BYTE bArg)
{
	if (!CanHandleItem(true))
	{
		ClearRefineElement();
		return false;
	}
	
	// Save the values local and clear them 
	// in case someone click multiple times
	// or a return false ocurs and the values need to be cleaned
	short sRefineElementSrcCell = m_sRefineElementSrcCell;
	short sRefineElementDstCell = m_sRefineElementDstCell;
	char  cRefineElementType = m_cRefineElementType;
	ClearRefineElement();
	
	if(sRefineElementSrcCell < 0 || sRefineElementDstCell < 0 || cRefineElementType < 0)
		return false;

	LPITEM srcItem = GetInventoryItem(sRefineElementSrcCell);
	LPITEM dstItem = GetInventoryItem(sRefineElementDstCell);

	if(!srcItem || !dstItem)
		return false;
	
	if(dstItem->IsExchanging() || dstItem->IsEquipped())
		return false;
	
	if(srcItem->GetType() != ITEM_USE)
		return false;
	
	if(dstItem->GetType() != ITEM_WEAPON)
		return false;
	
	if(dstItem->GetRefineLevel() < ELEMENT_MIN_REFINE_LEVEL)
		return false;
	
	if(srcItem->GetSubType() == USE_ELEMENT_UPGRADE)
	{
		if(cRefineElementType != REFINE_ELEMENT_TYPE_UPGRADE)
			return false;
		
		if(srcItem->GetValue(0) <= REFINE_ELEMENT_CATEGORY_NONE || srcItem->GetValue(0) >= REFINE_ELEMENT_CATEGORY_MAX)
			return false;
		
		if(dstItem->GetRefineElementPlus() == REFINE_ELEMENT_MAX)
			return false;
		
		if(dstItem->GetRefineElementType() > 0 && dstItem->GetRefineElementType() != srcItem->GetValue(0))
			return false;
	}
	else if(srcItem->GetSubType() == USE_ELEMENT_DOWNGRADE)
	{
		if(cRefineElementType != REFINE_ELEMENT_TYPE_DOWNGRADE)
			return false;
	}
	else if(srcItem->GetSubType() == USE_ELEMENT_CHANGE)
	{
		if(cRefineElementType != REFINE_ELEMENT_TYPE_CHANGE)
			return false;
		
		if(bArg <= REFINE_ELEMENT_CATEGORY_NONE || bArg >= REFINE_ELEMENT_CATEGORY_MAX)
			return false;
	}
	else // It's not a good subtype
		return false;

	long long llRefineCost = 10000000; // Default value in case some shit happen
	int iSuccessProb = 0;
	switch(cRefineElementType)
	{
		case REFINE_ELEMENT_TYPE_UPGRADE:
			llRefineCost = REFINE_ELEMENT_UPGRADE_YANG;
			iSuccessProb = REFINE_ELEMENT_UPGRADE_PROBABILITY;
			break;
			
		case REFINE_ELEMENT_TYPE_DOWNGRADE:
			llRefineCost = REFINE_ELEMENT_DOWNGRADE_YANG;
			iSuccessProb = REFINE_ELEMENT_DOWNGRADE_PROBABILITY;
			break;
			
		case REFINE_ELEMENT_TYPE_CHANGE:
			llRefineCost = REFINE_ELEMENT_CHANGE_YANG;
			iSuccessProb = REFINE_ELEMENT_DOWNGRADE_PROBABILITY;
			break;
			
		default:
			llRefineCost = 10000000;
			break;
	}

	if (GetGold() < llRefineCost)
		return false;
	
	// Save and delete after
	BYTE bElementType = srcItem->GetValue(0);
	srcItem->SetCount(srcItem->GetCount() - 1);
	
#ifdef ENABLE_REMOVE_LIMIT_GOLD
	ChangeGold(-llRefineCost);
#else
	PointChange(POINT_GOLD, -llRefineCost);
#endif
	
	int iRandomProb = number(1, 100);
	if(iRandomProb <= iSuccessProb)
	{
		// Succes
		// For upgrade / change
		BYTE bRefineElementType = dstItem->GetRefineElementType();
		BYTE bRefineElementPlus = dstItem->GetRefineElementPlus();
		BYTE bRefineElementBonusValue = dstItem->GetRefineElementBonusValue();
		BYTE bRefineElementAttackValue = dstItem->GetRefineElementAttackValue();
		
		// For downgrade
		BYTE bRefineElementLastIncBonus = dstItem->GetRefineElementLastIncBonus();
		BYTE bRefineElementLastIncAttack = dstItem->GetRefineElementLastIncAttack();
		
		if(cRefineElementType == REFINE_ELEMENT_TYPE_UPGRADE)
		{
			bRefineElementType = bElementType;
			bRefineElementPlus++;
			
			BYTE bIncreaseValue = number(REFINE_ELEMENT_RANDOM_VALUE_MIN, REFINE_ELEMENT_RANDOM_VALUE_MAX);
			bRefineElementBonusValue += bIncreaseValue;
			bRefineElementLastIncBonus = bIncreaseValue;
			
			BYTE bIncreaseAttackValue = number(REFINE_ELEMENT_RANDOM_BONUS_VALUE_MIN, REFINE_ELEMENT_RANDOM_BONUS_VALUE_MAX);
			bRefineElementAttackValue += bIncreaseAttackValue;
			bRefineElementLastIncAttack = bIncreaseAttackValue;
			
			char szRefineElement[10 + 1];
			snprintf(szRefineElement, sizeof(szRefineElement), "%d%d%02d%02d%d%02d", 
				bRefineElementType, bRefineElementPlus, 
				bRefineElementBonusValue, bRefineElementAttackValue, 
				bRefineElementLastIncBonus, bRefineElementLastIncAttack
			);
			
			DWORD dwRefineElement = atoi(szRefineElement);
			dstItem->SetRefineElement(dwRefineElement);
			
			SendRefineElementPacket(sRefineElementSrcCell, sRefineElementDstCell, REFINE_ELEMENT_TYPE_UPGRADE_SUCCES);
		}
		else if(cRefineElementType == REFINE_ELEMENT_TYPE_DOWNGRADE)
		{
			if(bRefineElementPlus == 1)
			{
				dstItem->SetRefineElement(0);
				SendRefineElementPacket(sRefineElementSrcCell, sRefineElementDstCell, REFINE_ELEMENT_TYPE_DOWNGRADE_SUCCES);
			}
			else
			{
				bRefineElementPlus--;
				bRefineElementBonusValue -= bRefineElementLastIncBonus;
				bRefineElementAttackValue -= bRefineElementLastIncAttack;
				bRefineElementLastIncBonus = MINMAX(0, bRefineElementLastIncBonus, bRefineElementBonusValue - 1);
				bRefineElementLastIncAttack = MINMAX(0, bRefineElementLastIncAttack, bRefineElementAttackValue - 1);
				
				char szRefineElement[10 + 1];
				snprintf(szRefineElement, sizeof(szRefineElement), "%d%d%02d%02d%d%02d", 
					bRefineElementType, bRefineElementPlus, 
					bRefineElementBonusValue, bRefineElementAttackValue, 
					bRefineElementLastIncBonus, bRefineElementLastIncAttack
				);
				
				DWORD dwRefineElement = atoi(szRefineElement);
				dstItem->SetRefineElement(dwRefineElement);
				
				SendRefineElementPacket(sRefineElementSrcCell, sRefineElementDstCell, REFINE_ELEMENT_TYPE_DOWNGRADE_SUCCES);
			}
		}
		else if(cRefineElementType == REFINE_ELEMENT_TYPE_CHANGE)
		{
			bRefineElementType = bArg;
				
			char szRefineElement[10 + 1];
			snprintf(szRefineElement, sizeof(szRefineElement), "%d%d%02d%02d%d%02d", 
				bRefineElementType, bRefineElementPlus, 
				bRefineElementBonusValue, bRefineElementAttackValue, 
				bRefineElementLastIncBonus, bRefineElementLastIncAttack
			);
			
			DWORD dwRefineElement = atoi(szRefineElement);
			dstItem->SetRefineElement(dwRefineElement);
			
			SendRefineElementPacket(sRefineElementSrcCell, sRefineElementDstCell, REFINE_ELEMENT_TYPE_CHANGE_SUCCES);
		}
	}
	else
	{
		// Fail
		// No change actually, 
		// but send a notification in client
		SendRefineElementPacket(sRefineElementSrcCell, sRefineElementDstCell, REFINE_ELEMENT_TYPE_UPGRADE_FAIL);
	}

	return true;
}

 

 

  • Love 1

english_banner.gif

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.