Jump to content

GF LoadAtlasMarkInfo


Recommended Posts

  • Honorable Member

Yo!

 

Yesterday I have noticed that webzen changed the CPythonMiniMap::__LoadAtlasMarkInfo function whiches basically load all the positions of the npcs, warp portals onto the atlaswindow.
I don't know they stopped sending the HEADER_GC_NPC_POSITION packet on every single login or not, but it seems with this code and the files from the official locale all the maps have the complete npc position info. My opinion about this that it's not needed to send this packet after every single login/warp.

 

So I reversed this small modification, which is a bit different then the old one.

This is how the old position info looks like:

#TokenIndex	Type	PosX	PosY	ToolTipText
0	WARP	140900	13900	"ąÚ¶óÇö"

And this is the new one:

#TokenIndex	PosX	PosY	NPCVnum
0	44100	3300	20081

 

Here is the modified function:

Spoiler


void CPythonMiniMap::__LoadAtlasMarkInfo()
{
	ClearAtlasMarkInfo();
	ClearGuildArea();

	CPythonBackground& rkBG=CPythonBackground::Instance();
	if (!rkBG.IsMapOutdoor())
		return;

	CMapOutdoor& rkMap=rkBG.GetMapOutdoorRef();

	// LOCALE
	char szAtlasMarkInfoFileName[64+1];
	_snprintf(szAtlasMarkInfoFileName, sizeof(szAtlasMarkInfoFileName), "%s/map/%s_point.txt", LocaleService_GetLocalePath(), rkMap.GetName().c_str());
	// END_OF_LOCALE

	CTokenVectorMap stTokenVectorMap;
	if (!LoadMultipleTextData(szAtlasMarkInfoFileName, stTokenVectorMap))
	{
		Tracef(" CPythonMiniMap::__LoadAtlasMarkInfo File Load %s ERROR\n", szAtlasMarkInfoFileName);
		return;
	}

#ifndef ENABLE_GF_ATLAS_MARK_INFO
	const std::string strType[TYPE_COUNT] = { "OPC", "OPCPVP", "OPCPVPSELF", "NPC", "MONSTER", "WARP", "WAYPOINT" };
#endif

	for (DWORD i = 0; i < stTokenVectorMap.size(); ++i)
	{
		char szMarkInfoName[32+1];
		_snprintf(szMarkInfoName, sizeof(szMarkInfoName), "%lu", i);

		if (stTokenVectorMap.end() == stTokenVectorMap.find(szMarkInfoName))
			continue;

		const CTokenVector & rVector = stTokenVectorMap[szMarkInfoName];

#ifdef ENABLE_GF_ATLAS_MARK_INFO
		const std::string& c_rstrPositionX = rVector[0].c_str();
		const std::string& c_rstrPositionY = rVector[1].c_str();
		const std::string& c_rstrVnum = rVector[2].c_str();
		const DWORD c_dwVnum = atoi(c_rstrVnum.c_str());

		const CPythonNonPlayer::TMobTable* c_pMobTable = CPythonNonPlayer::Instance().GetTable(c_dwVnum);
		if (c_pMobTable)
		{
			TAtlasMarkInfo aAtlasMarkInfo;
			aAtlasMarkInfo.m_fX = atof(c_rstrPositionX.c_str());
			aAtlasMarkInfo.m_fY = atof(c_rstrPositionY.c_str());
			aAtlasMarkInfo.m_strText = c_pMobTable->szLocaleName;
			if (c_pMobTable->bType == CActorInstance::TYPE_NPC)
				aAtlasMarkInfo.m_byType = TYPE_NPC;
			else if (c_pMobTable->bType == CActorInstance::TYPE_WARP)
			{
				aAtlasMarkInfo.m_byType = TYPE_WARP;
				int iPos = aAtlasMarkInfo.m_strText.find(" ");
				if (iPos >= 0)
					aAtlasMarkInfo.m_strText[iPos] = 0;

			}
			else if (c_pMobTable->bType == CActorInstance::TYPE_STONE && c_dwVnum >= 20702 && c_dwVnum <= 20706)
				aAtlasMarkInfo.m_byType = TYPE_NPC;

			aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f;
			aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f;

			switch (aAtlasMarkInfo.m_byType)
			{
			case TYPE_NPC:
				m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo);
				break;
			case TYPE_WARP:
				m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo);
				break;
			}
		}
#else
		const std::string & c_rstrType = rVector[0].c_str();
		const std::string & c_rstrPositionX = rVector[1].c_str();
		const std::string & c_rstrPositionY = rVector[2].c_str();
		const std::string & c_rstrText = rVector[3].c_str();

		TAtlasMarkInfo aAtlasMarkInfo;
		//memset(&aAtlasMarkInfo, 0, sizeof(aAtlasMarkInfo));

		for ( int i = 0; i < TYPE_COUNT; ++i)
		{
			if (0 == c_rstrType.compare(strType[i]))
				aAtlasMarkInfo.m_byType = (BYTE)i;
		}
		aAtlasMarkInfo.m_fX = atof(c_rstrPositionX.c_str());
		aAtlasMarkInfo.m_fY = atof(c_rstrPositionY.c_str());
		aAtlasMarkInfo.m_strText = c_rstrText;

		aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f;
		aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f;

		switch(aAtlasMarkInfo.m_byType)
		{
			case TYPE_NPC:
				m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo);
				break;
			case TYPE_WARP:
				m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo);
				break;
		}
#endif
	}
}

Don't forget to include the PythonNonPlayer.h, if you don't have it.

 

Some facts what good to know about this:

  • This code does nothing until the RecvNPCList runs down, because when the packet arrives into the client, it clears the loaded vectors what was loaded from the txt files.
  • Just in that case do remove the packet, if you know what you are doing, and 101% sure about it...
  • Without the packet the server will not take care about your atlaswindow anymore, so you have to take care about it by yourself, if you place a new NPC/Warp portal on a map, you have to add it into the text file of the map at clientside. (Easy to write a script which iterates all over the map folder and collect these entries.)
  • I don't provide guide/help how to remove the HEADER_GC_NPC_POSITION packet, it's very basic..
  • Metin2 Dev 1
  • Love 15
Link to comment
Share on other sites

  • Honorable Member

I think this was a move they made for their multi language system since the packet sends the name from the server directly to the binary without any translation, with this method they can get the locale name based on the vnum, just my guess and the best way to handle it.

  • Metin2 Dev 1
  • Love 1
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.