Jump to content

Recommended Posts

  • Active+ Member

Not sure if there is another guide somewhere but here but I randomly stumbled upon this issue and I was like "someone else may needs this".

You may need to adjust it for your own codebase and C++ version!

The issue:

If an item inside a private shop runs out of time the core will crash.  The core downs when anything walks a private shop's item grid after a timed item expired inside it like any purchases from that shop, functions that search through its items grid, etc...

The fix:

Spoiler

game/shop.h:

// [Find]
		void	SetPCShop(LPCHARACTER ch);

// [Add after]
		bool	UnlinkItem(LPITEM pkItem);

game/shop.cpp:

// [Find]
void CShop::SetPCShop(LPCHARACTER ch)
{
	m_pkPC = ch;
}

// [Add after]
bool CShop::UnlinkItem(LPITEM pkItem)
{
	bool bFound = false;

	for (DWORD i = 0; i < m_itemVector.size(); ++i)
	{
		if (m_itemVector[i].pkItem != pkItem)
			continue;

		m_pGrid->Put(i, 0, pkItem->GetSize());
		memset((void*)&m_itemVector[i], 0, sizeof(SHOP_ITEM));
		BroadcastUpdateItem(i);
		bFound = true;
	}

	return bFound;
}

game/item_manager.cpp:

// [Find]
#include "char.h"

// [Add after]
#include "shop.h"

// [Find]
void ITEM_MANAGER::RemoveItem(LPITEM item, const char * c_pszReason)
{
	LPCHARACTER o;
  	...

// [Replace with]
void ITEM_MANAGER::RemoveItem(LPITEM item, const char * c_pszReason)
{
	// REAL_TIME_EXPIRE / UNIQUE_EXPIRE / TIMER_BASED_ON_WEAR_EXPIRE
	const bool bExpired = c_pszReason && strstr(c_pszReason, "EXPIRE");

	LPCHARACTER o;
  	...

// [Find]  (same function)
		else
		{
			o->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
			item->RemoveFromCharacter();
		}

// [Replace with]
		else
		{
			if (o->GetMyShop() && o->GetMyShop()->UnlinkItem(item) && bExpired)
                        {
                    		// Use this if not using client-side translations:
                    		// o->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s has run out of time and was removed from the Shop."), item->GetLocaleName());
				o->ChatPacket(CHAT_TYPE_INFO, "[LS;100045;[IN;%u]]", item->GetVnum());
                        }

			o->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
			item->RemoveFromCharacter();
		}

// [In ITEM_MANAGER::DestroyItem: Find]
	if (item->GetOwner())
	{
		if (CHARACTER_MANAGER::instance().Find(item->GetOwner()->GetPlayerID()) != NULL)
        ...

// [Replace with]
	if (item->GetOwner())
	{
		if (item->GetOwner()->GetMyShop())
			item->GetOwner()->GetMyShop()->UnlinkItem(item);

		if (CHARACTER_MANAGER::instance().Find(item->GetOwner()->GetPlayerID()) != NULL)
        ...

game/item.cpp

// [Find]
int CItem::GetRefineLevel()
{
	const char* name = GetName();
	const char* p = strrchr(name, '+');

// [Replace with]
int CItem::GetRefineLevel()
{
	const char* name = GetName();

	if (!name)
		return 0;

	const char* p = strrchr(name, '+');

Translations:

ae: انتهت صلاحية %s وتمت إزالته من المتجر.
br: %s expirou e foi removido da loja.
cz: Předmětu %s vypršela platnost a byl odstraněn z obchodu.
de: %s ist abgelaufen und wurde aus dem Laden entfernt.
dk: %s er udløbet og er blevet fjernet fra butikken.
en: %s has run out of time and was removed from the Shop.
es: %s ha caducado y se ha retirado de la tienda.
fr: %s a expiré et a été retiré du magasin.
gr: Το %s έληξε και αφαιρέθηκε από το κατάστημα.
hu: %s ideje lejárt, ezért eltávolításra került a boltból.
it: %s è scaduto ed è stato rimosso dal negozio.
nl: %s is verlopen en uit de shop verwijderd.
pl: Przedmiot %s stracił ważność i został usunięty ze sklepu.
pt: %s expirou e foi removido da loja.
ro: %s a expirat și a fost eliminat din magazin.
ru: Время действия предмета %s истекло, и он был удалён из лавки.
tr: %s süresi dolduğu için dükkandan kaldırıldı.

ℹ️ These strings were machine-translated from English. Feel free to provide better ones for the language(s) you speak.

 

Constructive feedback and improvements are always appreciated. I am by no means a professional developer and your codebase may have significant differences according to your edits. Please adjust accordingly.

This fix is for the classic private shops. If you wish to extend it for any of the Offline Shops that exist out there feel free to and if you wanna share your fixes in this thread you are most welcome to.

Hope this helps some of y'all 😄

  • Metin2 Dev 3
  • Love 1

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.