Jump to content

Owsap

Honorable Member
  • Posts

    265
  • Joined

  • Last visited

  • Days Won

    29
  • Feedback

    91%

Posts posted by Owsap

  1. M2 Download Center

    This is the hidden content, please
    ( Internal )

    This is the hidden content, please
    ( GitHub )

    Hello, came by to share something simple yet helpful for players, someone requested me this feature that allows you to input money with k format on the pick money dialog window, this will enable you to input “1kk” instead of “1000000”


    Hope it comes in handy for who is planning to use it.

    Spoiler

    gL0Mp4H.gif

     

    • Metin2 Dev 124
    • kekw 1
    • Eyes 1
    • Dislove 1
    • Not Good 1
    • Cry 1
    • Confused 3
    • Lmao 1
    • Good 27
    • Love 4
    • Love 72
  2. A possible way to fix this issue is to change the scale of sash when the character is dead, at first I think all characters will be in the same position while laying down so adjusting the z position to -30 should do the trick and would be less weird. 

     

    dk7XG3j.gif

     

    @ InstanceBase.cpp
    /// 1.
    // Search @ void CInstanceBase::SetAcce
    		m_GraphicThingInstance.SetScalePosition(fPositionX, fPositionY, fPositionZ);
    
    // Add above
    		if (IsDead())
    			fPositionZ -= 30;
    
    @ char_battle.cpp
    /// 1.
    // Search @ void CHARACTER::Dead
    		GetDesc()->SetPhase(PHASE_DEAD);
    
    // Add below
    		LPITEM pkAcce = GetWear(WEAR_COSTUME_ACCE);
    		if (pkAcce && pkAcce->IsEquipped())
    			this->UpdatePacket();

     

    • Love 3
  3. M2 Download Center

    This is the hidden content, please
    ( Internal )

    This is the hidden content, please
    ( GitHub )

    Hello community, this is my first tool shared on the forum, hope it helps a lot as it helped me.

    I know @Mali61 has already shared the tool on the forum but mine is open source so you can change what ever you want.
    The code is not the best but it does what it's supposed to, good uses.

     

    Spoiler

    080137Balsdw.gif


    Credits: @WLsj24 for setting up the base locale_string.txt for translations.

     

     

    • Metin2 Dev 115
    • Eyes 2
    • Dislove 4
    • Think 2
    • Confused 2
    • Lmao 1
    • Good 35
    • Love 5
    • Love 69
  4. You can get a VPS SSD for as low as 2.5€, just search the web and you don't have to worry about anything else. A home laptop is not meant to be a home server but to answer your question you can use Microsoft Loopback Adapter of even Hamachi to setup a public connection and together allowing these connections in your Firewall, note that port forwarding is necessary on your router aswell, after all this is configured just use your public IP address to access your server and client.

  5. @ interfaceModule.py
    ''' 1. '''
    # Search
    		self.wndCharacter = uiCharacter.CharacterWindow()
    
    # Add below
    		self.wndCharacter.BindInterface(self)
    
    
    @ uiCharacter.py
    ''' 1. '''
    # Search @ def __init__(self):
    		ui.ScriptWindow.__init__(self)
    
    # Add below
    		self.interface = None
    
    ''' 2. '''
    # Search
    	def Show(self):
    		self.__LoadWindow()
    
    # Add above
    	def BindInterface(self, interface):
    		from _weakref import proxy
    		self.interface = proxy(interface)
    
    ''' 3. '''
    # Search
    	def Show(self):
    		self.__LoadWindow()
    
    # Add below
    		if self.interface:
    			self.interface.HideAllQuestButton()
    
    ''' 4. '''
    # Search
    	def Close(self):
    		if 0 != self.toolTipSkill:
    			self.toolTipSkill.Hide()
    
    # Add below
    		if self.interface:
    			self.interface.HideAllQuestButton()

    Not sure if this is what you really want but it will hide quest scrolls when opening the character window and show them again once closed.

    m8gTyc2.gif

    • Love 1
  6. On 9/26/2019 at 8:46 PM, Tatsumaru said:

    I recently made a switchbot interface. It came out quite interesting, so i can boast:

    giphy.gif

    giphy.gif

    giphy.gif

    giphy.gif

    Cool, I really liked that design, the gears give a very nice touch to it! Keep up the good work!

    • Love 1
  7. On 9/8/2019 at 3:00 PM, Zeph said:

    You added quest or something to open shop in npc?

     

    On 9/8/2019 at 2:34 PM, displayjokes said:

    Can you show me this function: bool CShopManager::Initialize(TShopTable * table, int size)

    From your shop_manager.cpp in game>src please?


    You must add the value 1 to OnClick column of your shop NPC in mob_proto.
    Example:

    PQg3Xaz.png

    • Love 1
  8. First of all I know this is kind useless but for the sake of enabling and disabling the flash effect in buttons I decided to use the standard flash function because I didn't know an easier way.

     

    Spoiler

    EterPythonLib/PythonWindow.cpp

    
    
    /// 1.
    // Search
    	void CButton::Flash()
    	{
    		m_isFlash = true;
    	}
    
    // Add below
    	void CButton::EnableFlash()
    	{
    		m_isFlash = true;
    		if (!m_overVisual.IsEmpty())
    			SetCurrentVisual(&m_overVisual);
    	}
    
    	void CButton::DisableFlash()
    	{
    		m_isFlash = false;
    		if (!m_upVisual.IsEmpty())
    			SetCurrentVisual(&m_upVisual);
    	}
    
    
    /// 2.
    // Search function
    	void CButton::OnRender()
    
    // Replace with
    	void CButton::OnRender()
    	{
    		if (!IsShow())
    			return;
    
    		if (m_pcurVisual)
    		{
    			if (m_isFlash)
    			{
    				if (!IsIn() && !IsPressed())
    				{
    					if (!m_overVisual.IsEmpty())
    						SetCurrentVisual(&m_overVisual);
    
    					if (int(timeGetTime() / 500) % 2)
    						return;
    				}
    			}
    
    			m_pcurVisual->Render();
    		}
    
    		PyCallClassMemberFunc(m_poHandler, "OnRender", BuildEmptyTuple());
    	}

    EterPythonLib/PythonWindow.h

    
    
    /// 1.
    // Search
    			void Flash();
    
    // Add below
    			void EnableFlash();
    			void DisableFlash();

    EterPythonLib/PythonWindowManagerModule.cpp

    
    
    /// 1.
    // Search
    PyObject * wndButtonFlash(PyObject * poSelf, PyObject * poArgs)
    {
    	UI::CWindow * pWindow;
    	if (!PyTuple_GetWindow(poArgs, 0, &pWindow))
    		return Py_BuildException();
    
    	((UI::CButton*)pWindow)->Flash();
    
    	return Py_BuildNone();
    }
    
    // Add below
    PyObject* wndButtonEnableFlash(PyObject* poSelf, PyObject* poArgs)
    {
    	UI::CWindow * pWindow;
    	if (!PyTuple_GetWindow(poArgs, 0, &pWindow))
    		return Py_BuildException();
    
    	((UI::CButton*)pWindow)->EnableFlash();
    
    	return Py_BuildNone();
    }
    
    PyObject* wndButtonDisableFlash(PyObject* poSelf, PyObject* poArgs)
    {
    	UI::CWindow * pWindow;
    	if (!PyTuple_GetWindow(poArgs, 0, &pWindow))
    		return Py_BuildException();
    
    	((UI::CButton*)pWindow)->DisableFlash();
    
    	return Py_BuildNone();
    }
    
    /// 2.
    // Search
    		{ "Flash",						wndButtonFlash,						METH_VARARGS },
    
    // Add below
    		{ "EnableFlash",				wndButtonEnableFlash,				METH_VARARGS },
    		{ "DisableFlash",				wndButtonDisableFlash,				METH_VARARGS },

    ROOT/ui.py

    
    
    ''' 1. '''
    # Search
    	def Flash(self):
    		wndMgr.Flash(self.hWnd)
    
    # Add below
    	def EnableFlash(self):
    		wndMgr.EnableFlash(self.hWnd)
    
    	def DisableFlash(self):
    		wndMgr.DisableFlash(self.hWnd)

     

    As for an example, here is a demonstration of the flash effect.

     

    255226CU52L7z-1-.gif

    • Metin2 Dev 1
    • Good 2
    • Love 7
  9. Spoiler
    7 hours ago, .Elijah said:

    Your tutorial is incompleted. (char_item part for RemoveSpecifyItem)

    
    
    // char_item.cpp
    // Search:
    int CHARACTER::CountSpecifyItem(DWORD vnum) const
    {
        int    count = 0;
        LPITEM item;
    
        for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
        {
    // Replace with:
    int CHARACTER::CountSpecifyItem(DWORD vnum, int iExceptionCell) const
    {
        int    count = 0;
        LPITEM item;
    
        for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
        {
            if(i == iExceptionCell)
                continue;
                
                
    // char_item.cpp
    // Search:
    void CHARACTER::RemoveSpecifyItem(DWORD vnum, DWORD count)
    {
        if (0 == count)
            return;
    
        for (UINT i = 0; i < INVENTORY_MAX_NUM; ++i)
        {
    // Replace with:
    void CHARACTER::RemoveSpecifyItem(DWORD vnum, DWORD count, int iExceptionCell)
    {
        if (0 == count)
            return;
    
        for (UINT i = 0; i < INVENTORY_MAX_NUM; ++i)
        {
            if(i == iExceptionCell)
                continue;
                
                
    // char_item.cpp
    // Search: 2x
                if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
    // Replace with:
                if (CountSpecifyItem(prt->materials[i].vnum, item->GetCell()) < prt->materials[i].count)
                
                
    // char_item.cpp
    // Search: 2x
                RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);
    // Replace with:
                RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count, item->GetCell());
                
                
    // char.h
    // Search:
            int                CountSpecifyItem(DWORD vnum) const;
            void            RemoveSpecifyItem(DWORD vnum, DWORD count = 1);
    // Replace with:
            int                CountSpecifyItem(DWORD vnum, int iExceptionCell = -1) const;
            void            RemoveSpecifyItem(DWORD vnum, DWORD count = 1, int iExceptionCell = -1);

     

    It works the same but your way is cleaner, i just didn't feel the necessity of adding a new argument to the CountSpecificItem function, instead i differently added another way of counting the items. Anyway, thanks for making it more cleaner.

    • Love 2
  10. When item materials are removed from the refinment process the source item that is beeing refined also get's removed since it's apart of the required item list and this is what causes the game core to crash after any instance like warping.

    In order to fix this, we can check the source item beeing refined by position, simply by creating a new argument for the function RemoveSpecifyItem with the source item's cell position.

    char_item.cpp

    Spoiler
    
    /// 1.
    // Search @ DoRefineWithScroll
    	for (int i = 0; i < prt->material_count; ++i)
    	{
    		if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
    		{
    			if (test_server)
    			{
    				ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
    			}
    
    			ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù."));
    			return false;
    		}
    	}
    
    	for (int i = 0; i < prt->material_count; ++i)
    		RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);
    
    // Replace with:
    	for (int i = 0; i < prt->material_count; ++i)
    	{
    		DWORD material_count;
    
    		if (prt->materials[i].vnum == item->GetVnum())
    			material_count = prt->materials[i].count + 1;
    		else
    			material_count = prt->materials[i].count;
    
    		if (CountSpecifyItem(prt->materials[i].vnum) < material_count)
    		{
    			if (test_server)
    			{
    				ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
    			}
    
    			ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù."));
    			return false;
    		}
    	}
    
    	for (int i = 0; i < prt->material_count; ++i)
    		RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count, item->GetCell());
    
    /// 2.
    // Search @ DoRefine
    		for (int i = 0; i < prt->material_count; ++i)
    		{
    			if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
    			{
    				if (test_server)
    				{
    					ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
    				}
    
    				ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù."));
    				return false;
    			}
    		}
    
    		for (int i = 0; i < prt->material_count; ++i)
    			RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);
    
    // Replace with
    		for (int i = 0; i < prt->material_count; ++i)
    		{
    			DWORD material_count;
    
    			if (prt->materials[i].vnum == item->GetVnum())
    				material_count = prt->materials[i].count + 1;
    			else
    				material_count = prt->materials[i].count;
    
    			if (CountSpecifyItem(prt->materials[i].vnum) < material_count)
    			{
    				if (test_server)
    				{
    					ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
    				}
    
    				ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°³·®À» Çϱâ À§ÇÑ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù."));
    				return false;
    			}
    		}
    
    		for (int i = 0; i < prt->material_count; ++i)
    			RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count, item->GetCell());

     

    char.h

    Spoiler
    
    /// 1.
    // Search
    		void			RemoveSpecifyItem(DWORD vnum, DWORD count = 1);
    // Replace with
    		void			RemoveSpecifyItem(DWORD vnum, DWORD count = 1, DWORD sourcePos = -1);

     

    Preview of fix: https://metin2.download/picture/S6ACMRa2ZApJHEV6slZx8KU4OJO7E8B2/.gifv

    • Love 6
×
×
  • 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.