Jump to content

xP3NG3Rx

Honorable Member
  • Posts

    839
  • Joined

  • Days Won

    393
  • Feedback

    100%

Posts posted by xP3NG3Rx

  1. No, that is the multiline version of the bigboard for ox-quiz, he is looking for this:

    Spoiler
    
    if app.ENABLE_12ZI:
    	class MissionBoard(ui.Bar):
    		FONT_HEIGHT	= 15
    		LINE_HEIGHT	= FONT_HEIGHT + 5
    		STEP_HEIGHT	= LINE_HEIGHT + 5
    		LONG_TEXT_START_X	= 300
    		SCREEN_WIDTH	= wndMgr.GetScreenWidth()
    		
    		
    		def __init__(self):
    			ui.Bar.__init__(self)
    
    			self.AddFlag("not_pick")
    			self.missionText = None
    			self.missionFullText = None
    			self.curPos = 0
    			self.dstPos = -5
    			self.nextScrollTime = 0
    			self.flowMode = False
    			self.ScrollStartTime = 0.0
    
    			self.SetPosition(0, 100)
    			self.SetSize(self.SCREEN_WIDTH, 35)
    			self.SetColor(grp.GenerateColor(0.0, 0.0, 0.0, 0.5))
    			self.SetWindowHorizontalAlignCenter()
    
    			self.__CreateTextBar()
    			
    		def __del__(self):
    			ui.Bar.__del__(self)
    
    		def __CreateTextBar(self):
    
    			x, y = self.GetGlobalPosition()
    
    			self.textBar = BigTextBar(self.SCREEN_WIDTH*2, 300, self.FONT_HEIGHT)
    			self.textBar.SetParent(self)
    			self.textBar.SetPosition(6, 8)
    			self.textBar.SetTextColor(242, 231, 193)
    			self.textBar.SetClipRect(0, y, self.SCREEN_WIDTH, y+8+self.STEP_HEIGHT)
    			self.textBar.Show()
    
    		def CleanMission(self):
    			self.missionText = None
    			self.missionFullText = None
    			self.textBar.ClearBar()
    			self.Hide()
    
    		def __RefreshBoard(self):
    
    			self.textBar.ClearBar()
    
    			if self.missionFullText:
    				(text_width, text_height) = self.textBar.GetTextExtent(self.missionFullText)
    				
    				if text_width>self.SCREEN_WIDTH:
    					self.textBar.TextOut(0, (self.STEP_HEIGHT-8-text_height)/2, self.missionFullText)
    					self.flowMode = True
    				else:
    					self.textBar.TextOut((wndMgr.GetScreenWidth()-text_width)/2, (self.STEP_HEIGHT-8-text_height)/2, self.missionFullText)
    					self.flowMode = False
    
    		def SetMission(self, text):
    			self.__AppendText(text)
    			self.__RefreshBoard()
    
    			if self.flowMode:
    				self.dstPos = -text_width
    				self.curPos = self.LONG_TEXT_START_X
    				self.textBar.SetPosition(3 + self.curPos, 8)
    			else:
    				self.dstPos = 0
    				self.curPos = self.STEP_HEIGHT
    				self.textBar.SetPosition(3, 8 + self.curPos)
    			
    			if not self.IsShow():
    				self.Show()
    				
    		def SetSubMission(self, text):
    			self.missionFullText = self.missionText + text
    			
    			preflowMode = self.flowMode
    			
    			self.__RefreshBoard()
    			
    			if preflowMode != self.flowMode:
    				if self.flowMode:
    					self.dstPos = -text_width
    					self.curPos = self.LONG_TEXT_START_X
    					self.textBar.SetPosition(3 + self.curPos, 8)
    				else:
    					self.dstPos = 0
    					self.curPos = self.STEP_HEIGHT
    					self.textBar.SetPosition(3, 8 + self.curPos)
    
    		def __AppendText(self, text):
    			if text == "":
    				self.CleanMission()
    				return
    				
    			self.missionText = text
    			self.missionFullText = text
    			
    		def OnUpdate(self):
    			if self.missionFullText == None:
    				self.Hide()
    				return
    
    			if self.dstPos < self.curPos:
    				self.curPos -= 1
    				if self.flowMode:
    					self.textBar.SetPosition(3 + self.curPos, 8)
    				else:
    					self.textBar.SetPosition(3, 8 + self.curPos)
    			else:
    				if self.flowMode:
    					self.curPos = self.SCREEN_WIDTH

    This is the part of the game.py:

    
    	if app.ENABLE_12ZI:
    		def BINARY_SetMissionMessage(self, message):
    			self.interface.missionBoard.SetMission(message)
    			
    		def BINARY_SetSubMissionMessage(self, message):
    			self.interface.missionBoard.SetSubMission(message)
    			
    		def BINARY_CleanMissionMessage(self):
    			self.interface.missionBoard.CleanMission()

    And some declarations in the interfaceModule.py like the rest of the tipboards.
    The rest is c++.

     

  2. About the new mob_proto raceflags:
    There are three new raceflags. DECO[1 << 17], HIDE[1 << 18] and ATT_CZ[i <<19](? this isn't sure, only the new zodiac mobs have it).
    Deco: Means the actor is a decoration and doesn't shown on minimap.

    Spoiler

    415007c341.png

    7914ae6dcf.png

    d9657ceaaf.png

    386a7c7d61.png


    Hide: This is the decoration filter for the decorations into the Game options.

    Spoiler

    167d2b0498.png

    4544fb6e73.png

    d1ccef1334.png

    bed54dac80.png

    9e5b690f99.png


    Att_CZ: I didn't find any informations about the last flag in the binary, so maybe that has only serverside options.

    • Metin2 Dev 3
    • Confused 1
    • Good 2
    • Love 4
  3. They did it again... https://metin2.dev/uploads/custom-emoji/emoticons/default_biggrin.png Now the gameguard isn't runing.

    Here is the whole pack with item and mob protos, but the mob_proto isn't clear just dumped with false values, and ofc I don't recommend of use one of them either.
    (Exclude files: root, outdoor,
    outdoorempirebattle1) (

    This is the hidden content, please
    ) (
    This is the hidden content, please
    )

    • Metin2 Dev 25
    • Sad 2
    • Cry 1
    • Good 7
    • Love 30
  4. M2 Download Center

    This is the hidden content, please
    ( Internal )

    Hello.

     

    Today I'd like to share this little stuff what I reversed from the official binary a month ago.
    This will fix the positions of textails(name position changes by every update packet on the main character), and also the position of the emotions when you are on a mount :).
    I've made a little demonstration video where you can see a private server without the fix, my fixxed version and the official aswell.

     

    1. Client/bin/playersettingmodule.py

    Spoiler

    1. Add the following code above of the loadGameDataDict declaration:

    
    
    # SetRaceHeight
    def __LoadRaceHeight():
    	try:
    		lines = open("race_height.txt", "r").readlines()
    	except IOError:
    		return
    
    	for line in lines:
    		tokens = line[:-1].split("\t")
    		if len(tokens) == 0 or not tokens[0]:
    			continue
    
    		vnum = int(tokens[0])
    		height = float(tokens[1])
    
    		chrmgr.SetRaceHeight(vnum, height)

    2. Add the following line below of the dict or extend it however you want:

    
    
    loadGameDataDict.update({"RACE_HEIGHT": __LoadRaceHeight,})

    2.1 extension:

    
    
    	"RACE_HEIGHT" : __LoadRaceHeight,

     

    2. Client/bin/introLoading.py

    Spoiler

    1. Paste the following line below of the self.__LoadNPC() in the DEBUG_LoadData function:

    
    
    		self.__LoadRaceHeight()

    2. Add the following line below of the self.loadStepList definition in the LoadData function:

    
    
    		self.loadStepList+=[(98, ui.__mem_func__(self.__LoadRaceHeight)),]

    2.1 or extend it:

    
    
    			(98, ui.__mem_func__(self.__LoadRaceHeight)),

    3. Add the following function after the __LoadNPC function or anywhere you want:
     

    
    
    	def __LoadRaceHeight(self):
    		playerSettingModule.LoadGameData("RACE_HEIGHT")

     

    3. Place the race_height.txt from the official client into the yours and pack it in the root.
    4. Client/UserInterface/PythonCharacterManagerModule.cpp

    Spoiler

    1. Add the new function to the module:

    
    
    PyObject * chrmgrSetRaceHeight(PyObject* poSelf, PyObject* poArgs)
    {
    	int iRaceIndex;
    	if (!PyTuple_GetInteger(poArgs, 0, &iRaceIndex))
    		return Py_BadArgument();
    	float fRaceHeight = 0.0f;
    	if (!PyTuple_GetFloat(poArgs, 1, &fRaceHeight))
    		return Py_BadArgument();
    
    	CRaceManager::Instance().SetRaceHeight(iRaceIndex, fRaceHeight);
    	return Py_BuildNone();
    }

    And to the methodlist:

    
    
    		{ "SetRaceHeight",				chrmgrSetRaceHeight,					METH_VARARGS },

     

    5. Client/GameLib/RaceManager.h

    Spoiler

    1. Add these new functions as public:

    
    
    		void SetRaceHeight(int iVnum, float fHeight);
    		float GetRaceHeight(int iVnum);

    2. And define the new map which will stores the informations as protected:

    
    
    		std::map<int, float>				m_kMap_iRaceKey_fRaceAdditionalHeight;

     

    6. Client/GameLib/RaceManager.cpp

    Spoiler

    1. Add the new functions anywhere you want:

    
    
    void CRaceManager::SetRaceHeight(int iVnum, float fHeight)
    {
    	m_kMap_iRaceKey_fRaceAdditionalHeight.insert(std::map<int, float>::value_type(iVnum, fHeight));
    }
    
    float CRaceManager::GetRaceHeight(int iVnum)
    {
    	std::map<int, float>::iterator it = m_kMap_iRaceKey_fRaceAdditionalHeight.find(iVnum);
    	if (m_kMap_iRaceKey_fRaceAdditionalHeight.end() == it)
    		return 0.0f;
    
    	return it->second;
    }

     

    7. Client/UserInterface/InstanceBase.h

    Spoiler

    1. Paste the following definition of function below of the definition of GetDistance as public:

    
    
    		float					GetBaseHeight();

     

    8. Client/UserInterface/InstanceBase.cpp

    Spoiler

    0. Add to the includes:

    
    
    #include "../gamelib/RaceManager.h"

    1. Add the function anywhere you want:

    
    
    float CInstanceBase::GetBaseHeight()
    {
    	CActorInstance* pkHorse = m_kHorse.GetActorPtr();
    	if (!m_kHorse.IsMounting() || !pkHorse)
    		return 0.0f;
    
    	DWORD dwHorseVnum = m_kHorse.m_pkActor->GetRace();
    	if ((dwHorseVnum >= 20101 && dwHorseVnum <= 20109) ||
    		(dwHorseVnum == 20029 || dwHorseVnum == 20030))
    		return 100.0f;
    
    	float fRaceHeight = CRaceManager::instance().GetRaceHeight(dwHorseVnum);
    	if (fRaceHeight == 0.0f)
    		return 100.0f;
    	else
    		return fRaceHeight;
    }

     

    9. Client/UserInterface/InstanceBaseEffect.cpp

    Spoiler

    1. Replace the fTextTailHeight definition of variable in the AttachTextTail function with this:

    
    
    		float fTextTailHeight = GetBaseHeight() + 10.0f;

    2. Replace the following in the SetEmoticon function:

    
    
    		v3Pos.z += float(m_GraphicThingInstance.GetHeight());

    With this:

    
    
    		v3Pos.z += float(GetBaseHeight() + m_GraphicThingInstance.GetHeight());

    Twice!!! The are two times this line, replace both of them!
     

    10. Client/UserInterface/PythonTextTail.cpp

    Spoiler

    1. Replace the following code in the RegisterChatTail function:

    
    
    	TTextTail * pTextTail = RegisterTextTail(VirtualID,
    											 c_szChat,
    											 pCharacterInstance->GetGraphicThingInstancePtr(),
    											 pCharacterInstance->GetGraphicThingInstanceRef().GetHeight() + 10.0f,
    											 c_TextTail_Chat_Color);

    With this:
     

    
    
    	TTextTail * pTextTail = RegisterTextTail(VirtualID,
    											 c_szChat,
    											 pCharacterInstance->GetGraphicThingInstancePtr(),
    											 pCharacterInstance->GetGraphicThingInstanceRef().GetHeight() + pCharacterInstance->GetBaseHeight() + 10.0f,
    											 c_TextTail_Chat_Color);

     

    11. Client/GameLib/ActorInstance.cpp

    Spoiler

    0. Add the following to the includes:

    
    
    #include "RaceManager.h"

    1. Replace the whole GetHeight function with this:

    
    
    float CActorInstance::GetHeight()
    {
    	DWORD dwRace = GetRace();
    	float fRaceHeight = CRaceManager::instance().GetRaceHeight(dwRace);
    	if (fRaceHeight == 0.0f)
    	{
    		fRaceHeight = CGraphicThingInstance::GetHeight();
    		CRaceManager::instance().SetRaceHeight(dwRace, fRaceHeight);
    	}
    
    	return fRaceHeight;
    }

     

     

    I hope you like it, and if you find any problem just let me know in this topic.

    • Metin2 Dev 80
    • Dislove 1
    • Angry 1
    • Cry 1
    • Confused 3
    • Good 20
    • Love 4
    • Love 94
  5. Probably with this?

    		else if ("info" == TokenVector[1])
    		{
    			if (5 != TokenVector.size())
    			{
    				TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
    				return;
    			}
    
    			long long gold = atoll(TokenVector[2].c_str());
    			UINT itemVnum = atoi(TokenVector[3].c_str());
    			UINT count = atoi(TokenVector[4].c_str());
    			PyObject * poArgs = PyTuple_New(3);
    			PyTuple_SetItem(poArgs, 0, PyLong_FromLongLong(gold));
    			PyTuple_SetItem(poArgs, 1, PyInt_FromLong(itemVnum));
    			PyTuple_SetItem(poArgs, 2, PyInt_FromLong(count));
    			PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_UpdateInfo", poArgs);
    		}

     

    • Love 1
  6. Spoiler

     

    24 minutes ago, Syreldar said:

    Stone shards have a time, you can't stack shards with different remaining time.

    An idea just turned into my mind now about this. If the item is stackable, and it has realtime limit, the less time will remain on both items which are stacked.
    For example you have two items with realtime(same items, different socket time) 1x Item1 have 3 minutes, 1x Item2 have 5 minutes and if you are trying to stack them, a dialog will ask to make sure blabla yes no, and then the result will be 2x Item with 3 minutes. Ofc, it sucks, but something for something, no tho?

     

  7. Once I've met with this problem, the reason was a comma before the new weapon type, nothing else. It was missing from here:

    Quote

    string arIAFVSub1[] = {
        "WEAPON_SWORD",
        "WEAPON_DAGGER",
        "WEAPON_BOW",
        "WEAPON_TWO_HANDED",
        "WEAPON_BELL",
        "WEAPON_FAN",
        "WEAPON_ARROW",
        "WEAPON_MOUNT_SPEAR",
        "WEAPON_CLAW",
        "WEAPON_QUIVER",
        "WEAPON_BOUQUET"
    };

     

    The weapon type of the quiver has been overflowed and got 255 as value.
    You can check it with this code:
     

    			if app.ENABLE_QUIVER_SYSTEM:
    				import chat
    				chat.AppendChat(1, str((itemType, itemSubType)))
    				if itemSubType != item.WEAPON_QUIVER:
    					self.__AppendMetinSlotInfo(metinSlot)
    				else:
    					bHasRealtimeFlag = 0
    					for i in xrange(item.LIMIT_MAX_NUM):
    						(limitType, limitValue) = item.GetLimit(i)
    						if item.LIMIT_REAL_TIME == limitType:
    							bHasRealtimeFlag = 1
    
    					if bHasRealtimeFlag == 1:
    						self.AppendMallItemLastTime(metinSlot[0])
    			else:
    				self.__AppendMetinSlotInfo(metinSlot)

     

  8. #ui.py
    	def SetPercentageWithScale(self, curValue, maxValue):
    		wndMgr.SetRenderingRectWithScale(self.hWnd, 0.0, 0.0, -1.0 + float(curValue) / float(maxValue), 0.0)
    // EterPythonLib/PythonWindowManagerModule.cpp
    PyObject * wndImageSetRenderingRectWithScale(PyObject * poSelf, PyObject * poArgs)
    {
    	UI::CWindow * pWindow;
    	if (!PyTuple_GetWindow(poArgs, 0, &pWindow))
    		return Py_BuildException();
    	float fLeft;
    	if (!PyTuple_GetFloat(poArgs, 1, &fLeft))
    		return Py_BuildException();
    	float fTop;
    	if (!PyTuple_GetFloat(poArgs, 2, &fTop))
    		return Py_BuildException();
    	float fRight;
    	if (!PyTuple_GetFloat(poArgs, 3, &fRight))
    		return Py_BuildException();
    	float fBottom;
    	if (!PyTuple_GetFloat(poArgs, 4, &fBottom))
    		return Py_BuildException();
    
    	if (pWindow->IsType(UI::CExpandedImageBox::Type()))
    		((UI::CExpandedImageBox*)pWindow)->SetRenderingRectWithScale(fLeft, fTop, fRight, fBottom);
    	else if (pWindow->IsType(UI::CAniImageBox::Type()))
    		((UI::CAniImageBox*)pWindow)->SetRenderingRectWithScale(fLeft, fTop, fRight, fBottom);
    
    	return Py_BuildNone();
    }
    
    // Bottom of the file where is the functionlist:
    		{ "SetRenderingRectWithScale",	wndImageSetRenderingRectWithScale,	METH_VARARGS },
    // EterPythonLib/PythonWindow.h
    // class CExpandedImageBox --> Public function definition:
    			void SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom);
    
    // class CAniImageBox --> Public function definition:
    			void SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom);
    // EterPythonLib/PythonWindow.cpp
    // Add this near to the CExcpandedImageBox functions
    	void CExpandedImageBox::SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom)
    	{
    		if (!m_pImageInstance)
    			return;
    
    		((CGraphicExpandedImageInstance*)m_pImageInstance)->SetRenderingRectWithScale(fLeft, fTop, fRight, fBottom);
    	}
    
    // Add this near to the CAniImageBox functions
    	struct FSetRenderingRectWithScale
    	{
    		float fLeft, fTop, fRight, fBottom;
    		void operator () (CGraphicExpandedImageInstance * pInstance)
    		{
    			pInstance->SetRenderingRectWithScale(fLeft, fTop, fRight, fBottom);
    		}
    	};
    	void CAniImageBox::SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom)
    	{
    		FSetRenderingRectWithScale setRenderingRect;
    		setRenderingRect.fLeft = fLeft;
    		setRenderingRect.fTop = fTop;
    		setRenderingRect.fRight = fRight;
    		setRenderingRect.fBottom = fBottom;
    		for_each(m_ImageVector.begin(), m_ImageVector.end(), setRenderingRect);
    	}
    // EterLib/GrpExpandedImageInstance.h
    // class CGraphicExpandedImageInstance --> Public function definition:
    		void SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom);
    // EterLib/GrpExpandedImageInstance.cpp
    void CGraphicExpandedImageInstance::SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom)
    {
    	if (IsEmpty())
    		return;
    
    	float fWidth = float(GetWidth() * m_v2Scale.x);
    	float fHeight = float(GetHeight() * m_v2Scale.y);
    
    	m_RenderingRect.left = fWidth * fLeft;
    	m_RenderingRect.top = fHeight * fTop;
    	m_RenderingRect.right = fWidth * fRight;
    	m_RenderingRect.bottom = fHeight * fBottom;
    }

     

    A couple of minutes of RE :)

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