-
Posts
265 -
Joined
-
Last visited
-
Days Won
29 -
Feedback
91%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by Owsap
-
-
Personally, I found the title of this topic being a little confusing just because the fact that Metin2 has a stupid resistance gauge which is also called “Stamina”, BUT what we also know from Metin2 and other RPG’s that use special magical abilities is that they are usually measured in MP "Magic Points", "Mana Points" and even “Stamina Points” and here is the confusion from the title. Which Stamina? Resistance or Mana?
Here is a little reference in Magic (game terminology) - Wikipedia : https://en.wikipedia.org/wiki/Magic_(game_terminology)EXP = ("Experience") HP = ("Health Points") SP = ("Stamina Points") MP = ("Magic Points") MP = ("Mana Points") Both in game terminology are the same designation. ST = (Simply, "Stamina")
And again, personally, I would suggest, if the author agrees along as the administration team, altering the topic name from “Stamina” to “Mana” or something similar that’s not simply just “Stamina”.
Regardless, thanks for sharing.- 1
- 4
- 1
-
1 minute ago, Cunoo said:
No, client works fibe.. I'm kicked to login before black screen.. So I never got black screen but insta kick to login..
I find it hard to believe that 1 line of code causes that. It must be something else and certainly it's another topic.
- 1
-
@Cunoowhat do you mean with kick? Does the client crash or does the character get disconnected back the the login phase? If the client is crashing, have you tried to debug it?
-
54 minutes ago, VegasForPresident said:
WTF WHAT'S NEXT?? XD
Imagine he drops ENABLE_KEYCHANGE_SYSTEM from gfroot 2k18 too, BANGER then
He is already giving us a clue of what's coming next, just pay attention to the details and you will notice it.
- 1
- 1
- 1
-
Give this guy an award for sharing what I would call “premium systems” with logical and modern coding while he could be selling it for wasting his time and knowledge of the Metin2 sources, instead he does it for free and adores sharing his work with the community. He has over 70 repositories related to Metin2 systems on his GitHub and you can clearly see from the first repositories to the last that he is evolving his skills from each system he develops. I hope you also apply these skills in the real-world programing if you aren’t already. It’s very rare to see developers that are actually talented and have a lot of experience in the Metin2 sources / environment to actually share their knowledge for free. Big thumbs up to you @Mali and to all the other developers that contribute to the private server community because without them we wouldn’t have half of what we have today.
- 3
- 1
- 3
- 2
- 14
-
28 minutes ago, Karbust said:
First of all, thank you for this release.
Since I use a hostname instead of an IP, this didn't work for me, this are the changes I made to make it work (also works with IP).
CAccountConnector& rkAccountConnector = CAccountConnector::Instance(); struct hostent* remoteHost; if ((remoteHost = gethostbyname(rkAccountConnector.GetServerAddr())) == NULL) { #if defined(_DEBUG_RTT) TraceError("Unknown Hostname.\n\n"); #endif return; // Unkown Hostname } char* pDmsIP = inet_ntoa(*(struct in_addr*)(remoteHost->h_addr_list[0])); ipaddr = inet_addr(pDmsIP);
Thanks for contributing, I will update the repository soon.
-
36 minutes ago, rares2017 said:
I solved that,but hide option does not work for chat log.
The chat log is a set of tabs separated by the type of chat, in my opinion it doesn't make sense to hide the text in the log window.
How are you going to see a log if it's hidden? -
SpoilerOn 9/9/2021 at 8:08 AM, Fluff99s said:
After adding this system into my server, i get the following error in syserrȘ
0909 10:58:15148 :: GRANNY: r:/granny/rt/granny_file_info.cpp(145): File has run-time type tag of 0x8000000f, which doesn't match this version of Granny (0x80000010). Automatic conversion will be attempted. 0909 10:58:18436 :: Traceback (most recent call last): 0909 10:58:18436 :: File "networkModule.py", line 239, in SetGamePhase 0909 10:58:18437 :: File "game.py", line 109, in __init__ 0909 10:58:18437 :: File "interfaceModule.py", line 306, in MakeInterface 0909 10:58:18437 :: File "interfaceModule.py", line 100, in __MakeMessengerWindow 0909 10:58:18437 :: File "uiMessenger.py", line 397, in __init__ 0909 10:58:18438 :: File "uiMessenger.py", line 540, in __AddGroup 0909 10:58:18438 :: File "uiMessenger.py", line 318, in __init__ 0909 10:58:18438 :: AttributeError 0909 10:58:18438 :: : 0909 10:58:18438 :: 'module' object has no attribute 'MESSENGER_FRIEND' 0909 10:58:18438 ::
What can I do about it? do you know where is the problem from? I have in locale_game the MESSENGER_FRIEND and the "TAB" is ok, in locale_info i don't have one.
EDIT: here is the solve for this error :
Enter in your uimessenger.py and replace locale. to localeInfo. and it should work fine.
Sorry, but this has nothing to do with the system or the modified files.
SpoilerOn 9/9/2021 at 9:17 AM, Fluff99s said:This error is happening with other lib files from my client downloaded from internet, with my originals lib files from client i have another error wich is it:
0909 12:16:08738 :: networkModule.py(line:200) SetSelectCharacterPhase system.py(line:130) __pack_import system.py(line:110) _process_result introSelect.py(line:27) <module> system.py(line:130) __pack_import system.py(line:110) _process_result interfaceModule.py(line:11) <module> system.py(line:130) __pack_import system.py(line:110) _process_result uiChat.py(line:17) <module> system.py(line:137) __pack_import C:\Users\Marian\Desktop\Client\lib\pickle.py(line:33) <module> - import re system.py(line:137) __pack_import C:\Users\Marian\Desktop\Client\lib\re.py(line:27) <module> - from sre import * system.py(line:137) __pack_import C:\Users\Marian\Desktop\Client\lib\sre.py(line:97) <module> - import sre_compile system.py(line:137) __pack_import C:\Users\Marian\Desktop\Client\lib\sre_compile.py(line:17) <module> - assert _sre.MAGIC == MAGIC, "SRE module mismatch" networkModule.SetSelectCharacterPhase - <type 'exceptions.AssertionError'>:SRE module mismatch 0909 12:16:08738 :: ============================================================================================================ 0909 12:16:08738 :: Abort!!!!
L.E: to get pass this, search on google for ne lib python27 and change it in your client folder lib, as an experience, keep the originals for later.
I have added some
(check the repository) it could help you solve your problem.
@rares2017Spoiler3 hours ago, rares2017 said:It doesn't say how much experience I get when I kill a monster.
Search the exp string in your source and change CHAT_TYPE_INFO with CHAT_TYPE_EXP_INFO
@ MrPicksSpoiler1 hour ago, MrPicks said:Thank your for release, it works good but there's one bug in python.
Which bug?
Background of Chat Window doesn't hide anymore
https://metin2.download/picture/1nvjxFelzjKd39zs8vA1JrtqdxKp9I60/.gif
sysrr
0910 22:39:49128 :: File "uiChat.py", line 1257, in OnRender
0910 22:39:49128 :: File "uiChat.py", line 1196, in Refresh
0910 22:39:49128 :: File "uiChat.py", line 1223, in RefreshBoardViewState
0910 22:39:49129 :: AttributeError
0910 22:39:49129 :: :
0910 22:39:49129 :: 'int' object has no attribute 'GetGlobalPosition'
0910 22:39:49129 ::https://metin2.download/picture/VmLtFb2xO0cZ6AS4LP84o0iIs8PlIUfb/.png
https://metin2.download/picture/228xtk9g6dtV58wfNF6uwzqv50OX5XsE/.png
When it happens?
1. Open Chat and write something
2. let the chat window open and warp with warpring to XY
3. now the background of the new chat is buggy / doesn't hide
The GetGlobalPosition function has always been there even on older roots, possibly you added something wrong but show us your uiChat.py so we can take a look at it.
- 30
- 1
- 2
- 8
- 2
- 14
-
13 hours ago, Dex said:
Would you like to put also the function for creating new chats through the + sign like official to have different chatwindows for each ?
I only planned to release a Mini Version, that's why I didn't add that feature
but who knows maybe sooner or later I can extend it or until thenyou can find it already done from someone else. -
Reports
SpoilerOn 8/31/2021 at 8:17 PM, Shaggyxdd said:copy_reg.py?
0831 22:22:32364 :: Traceback (most recent call last):
0831 22:22:32364 :: File "networkModule.py", line 233, in SetGamePhase
0831 22:22:32365 :: File "game.py", line 121, in __init__
0831 22:22:32365 :: File "interfaceModule.py", line 379, in MakeInterface
0831 22:22:32365 :: File "interfaceModule.py", line 138, in __MakeChatWindow
0831 22:22:32365 :: File "uiChat.py", line 952, in __init__
0831 22:22:32365 :: File "uiChat.py", line 173, in __init__
0831 22:22:32365 :: File "uiChat.py", line 208, in __LoadWindow
0831 22:22:32366 :: File "uiChat.py", line 258, in __LoadChattingOptionFile
0831 22:22:32366 :: File "Lib\copy_reg.py", line 70, in _reduce_ex
0831 22:22:32367 :: TypeError
0831 22:22:32367 :: :
0831 22:22:32367 :: can't pickle file objects
0831 22:22:32367 ::23 hours ago, livetime97 said:Thx For Release I Have a Problem Pls Help me
0905 18:30:12071 :: Traceback (most recent call last):
0905 18:30:12071 :: File "networkModule.py", line 247, in SetGamePhase
0905 18:30:12071 :: File "game.py", line 89, in __init__
0905 18:30:12071 :: File "interfaceModule.py", line 317, in MakeInterface
0905 18:30:12072 :: File "interfaceModule.py", line 123, in __MakeChatWindow
0905 18:30:12072 :: File "uiChat.py", line 968, in __init__
0905 18:30:12072 :: File "uiChat.py", line 164, in __init__
0905 18:30:12072 :: File "uiChat.py", line 199, in __LoadWindow
0905 18:30:12072 :: File "uiChat.py", line 249, in __LoadChattingOptionFile
0905 18:30:12072 :: File "Lib\copy_reg.py", line 70, in _reduce_ex
0905 18:30:12073 :: TypeError
0905 18:30:12073 :: :
0905 18:30:12073 :: can't pickle file objects
0905 18:30:12073 ::22 hours ago, Shaggyxdd said:uichat, replace:
def __LoadChattingOptionFile(self):
load = False
try:
fileName = self.__GetChattingFile()
file = open(fileName)
try:
load = True
self.tmpCheckBoxSettingDict = cPickle.load(file)
except (ValueError, EOFError, cPickle.PicklingError, cPickle.UnpicklingError): pass
except IOError: passfor key in xrange(1, len(OPTION_CHECKBOX_MODE) + 1):
if not load:
# Default, always enable and add to dict.
value = True
self.tmpCheckBoxSettingDict[key] = True
else:
value = self.tmpCheckBoxSettingDict[key]
self.checkBoxSlotDict[key].SetCheck(value)if not load:
self.__SaveDefault()Sorry for the delay regarding the reported issue with the pickle module.
I have reviewed the tutorial and noticed a dump line intended for debugging while opening the chat setting window. Removing that line will solve the unpickling issue. There were also some faults in the tutorial that have been corrected and some files that have been added which were missing.
The MEGA link and repository have been updated.
- 1
- 1
-
15 minutes ago, Shaggyxdd said:
Function SetTextAddPos?
''' 1. @ root/ui.py ''' # Search @ class Button def SetText(self, text, height = 4): # Add above def SetTextAddPos(self, text, x_add = 0, y_add = 0, height = 4): if not self.ButtonText: textLine = TextLine() textLine.SetParent(self) textLine.SetPosition(self.GetWidth() / 2 + x_add, self.GetHeight() / 2 + y_add) textLine.SetVerticalAlignCenter() textLine.SetHorizontalAlignCenter() textLine.Show() self.ButtonText = textLine self.ButtonText.SetText(text)
Repository updated, check the updated links and if there is anything missing please let me know.
- 1
-
On 8/30/2021 at 1:13 PM, Shaggyxdd said:
chattingoption.dds
Repository updated, check the updated links.
- 1
- 1
-
Other Mirrors
( GitHub ) ( MEGA )
A Mini Version of the official chatting window renewal.All settings are saved in UserData/chatting/<character_name> using the cPickle module in C, a powerful algorithm for serializing and de-serializing a Python object structure, also used by Webzen.
- 279
- 3
- 6
- 4
- 3
- 3
- 2
- 3
- 4
- 1
- 3
- 96
- 16
- 169
-
M2 Download Center
( GitHub )
( MEGA )
( Internal )I came across this new insert event by quests which I had to use while I was developing the 6th & 7th Attribute System so I decided to share this little feature and it could be useful in some situations.
- 112
- 2
- 2
- 1
- 1
- 1
- 30
- 5
- 45
-
12 hours ago, UdvAtt108 said:
There is a nice memory leak, that spammed in every 5 seconds and makes high memory usage few hours later...
Please, be carefull when you use memory allocations...
Easy to fix it, lets correct it.
Glad someone had to point that out, obviously, every allocation must be freed after using it but I wasn’t sure if IcmpSendEcho2 function cleared it for me, but honestly, I forgot about it.
Since you had good eyes in pointing that out, you also forgot to mention to close the IcmpFile HANDLE.7 hours ago, Jimmermania said:I have this sysser:
0724 13:48:16827 :: UISCRIPT_LOAD_ERROR: can only concatenate tuple (not "list") to tuple [filename UIScript/MiniMap.py] 0724 13:48:16829 :: uiMiniMap.py(line:341) __LoadWindow ui.py(line:3740) GetChild MiniMap.LoadWindow.Bind - <type 'exceptions.KeyError'>:'RTTTextLine'
The file in the tutorial "UIScript/MiniMap.py" already contains the correct structure to attach more children in the window. If you didn't use the file you can do this (2 options);
Spoiler''' 1. @ UIScript/MiniMap.py ''' # Search all "children" : ( ... ), # Replace with "children" : [ ... ],
Or you can just add;
Spoiler''' 1. @ UIScript/MiniMap.py ''' # Search ## ServerInfo { "name" : "ServerInfo", "type" : "text", "text_horizontal_align" : "center", "outline" : 1, "x" : 70, "y" : 140, "text" : "", }, # Add below ## RTT Statistics { "name" : "RTTTextLine", "type" : "text", "x" : 0, "y" : 160, "horizontal_align" : "center", "text_horizontal_align" : "center", "text" : "", "outline" : 1, }, { "name" : "PacketLossTextLine", "type" : "text", "x" : 0, "y" : 160 + 15, "horizontal_align" : "center", "text_horizontal_align" : "center", "text" : "", "outline" : 1, },
Links & Repository Updated.- 2
- 1
-
M2 Download Center
( GitHub )
( MEGA )
( Internal )Hey M2Dev, here is a little statistics overview of the Round Trip Time (RTT) Ping and Packet Loss.
Usefully for some, useless for others, so I decided to share it.
Preview
The image is an example...
The results where not captured accurately because they kept updating while I tried to take screenshots.
You will not get any PING on localhost.If you find any problems let me know.
- 134
- 2
- 2
- 1
- 4
- 1
- 1
- 28
- 3
- 74
-
''' @ uiToolTip.py ''' # Function "SetTooltipPosition" allows you to do this. # You can use the position of your mouse using wndMgr. # Example: (mouseX, mouseY) = wndMgr.GetMousePosition() # Don't forget to import wndMgr toolTip.SetTooltipPosition(mouseX - x, mouseY - y) # Or you can set the position manually. toolTip.SetTooltipPosition(x, y)
-
If you are rendering the frames while the client is minimized, then maybe try to disable it.
/// 1. @ Source/Client/UserInterface/PythonApplication.cpp // Search if (m_isMinimizedWnd) { canRender = true; } // Replace with if (m_isMinimizedWnd) { canRender = false; }
Also, update your DirectX: https://www.microsoft.com/en-us/download/details.aspx?id=35
StateManager files without the macros.
If you say it runs well on Debug build then use the macros set for it on Release and Distribute builds.
- 32
- 1
- 1
- 2
- 10
-
1 hour ago, wubservice said:
UPDATE:
I get this sysser:
Entergame: !GetMovablePosition (name Python 57600x0 map 111 changed to 70400x12800)
Entergame: !GetMovablePosition (name Python 32000x0 map 110 changed to 44800x12800)First of all, double check if the coordinates and the map index are correct in the server files.
Server/share/locale/map/index103 metin2_map_t1 105 metin2_map_t2 110 metin2_map_t3 111 metin2_map_t4
Server/share/locale/map/metin2_map_t1/Setting.txt
SpoilerScriptType MapSetting CellScale 200 HeightScale 0.500000 ViewRadius 128 MapSize 3 3 BasePosition 0 25600 TextureSet metin2_map_t1.txt Environment map_b_fielddungeon2.msenv
Server/share/locale/map/metin2_map_t2/Setting.txt
SpoilerScriptType MapSetting CellScale 200 HeightScale 0.500000 ViewRadius 128 MapSize 1 1 BasePosition 6400 0 TextureSet textureset\metin2_map_t2.txt Environment t2.msenv
Server/share/locale/map/metin2_map_t3/Setting.txt
SpoilerScriptType MapSetting CellScale 200 HeightScale 0.500000 ViewRadius 128 MapSize 1 1 BasePosition 32000 0 TextureSet textureset\metin2_map_t3.txt Environment t2.msenv
Server/share/locale/map/metin2_map_t4/Setting.txt
SpoilerScriptType MapSetting CellScale 200 HeightScale 0.500000 ViewRadius 128 MapSize 1 1 BasePosition 57600 0 TextureSet textureset\metin2_map_t4.txt Environment moonlight04.msenv
all the files mentioned above and the additional server_attr file for each map.
Server/Game99/CONFIGMAP_INDEX: 103 105 110 111
In your client files, you should also check if the atlasinfo.txt contains the correct coordinates for each map as in your server files.
Client/locale/atlasinfo.txt
Client/root/atlasinfo.txtmetin2_map_t1 0 25600 3 3 metin2_map_t2 6400 0 1 1 metin2_map_t3 32000 0 1 1 metin2_map_t4 57600 0 1 1
You should also double check if you have another map on top of the guild map's coordinates, sometimes this is a common issue when warping to a map or simply using the GM go command.
Here is what I mean,
Each block represents a map, as you can see T1, T2, T3 and T4 are separate from each other and no other map is on top of them.
Now, in this case you can clearly see another map is on top of map T1 which will mess the coordinates of the map.
the tool "M2Koordinator - By KingSora!1" used in the demonstration above.
There is also a possibility that the map index is not correct in your source, this should be a rare case but it should also be verified.
Source/Server/game/war_map.h
Make sure you are using the correct map index.enum EWarMapIndex { WAR_MAP_INDEX_NORMAL = 110, WAR_MAP_INDEX_FLAG = 111, };
Quote1- I do not get the mission to enter, I must teleport to appear, yes, the quest exists and has the correct name "guild_join_war.quest" something like that.
Instead of using makequestbutton in the guild_war_join.quest you can use send_letter.
Here is an example:Spoilerquest guild_war_join begin state start begin when letter with (pc.get_map_index() != 71 and pc.get_map_index() != 104 and pc.get_map_index() != 72 and pc.get_map_index() != 73 and pc.get_map_index() != 208) and pc.get_map_index() <= 200 begin local e = guild.get_any_war() if e != 0 and pc.get_war_map() == 0 then setskin(NOWINDOW) send_letter(gameforge.locale.guild.war_join_request) --makequestbutton(gameforge.locale.guild.war_join_request) end end when button with (pc.get_map_index() != 71 and pc.get_map_index() != 104 and pc.get_map_index() != 72 and pc.get_map_index() != 73 and pc.get_map_index() != 208) and pc.get_map_index() <= 200 begin local e = guild.get_any_war() if e == 0 then say(gameforge.locale.guild.war_over) else say(string.format(gameforge.guild_war_join._10_say, guild.name(e))) local s = select(gameforge.locale.guild.yes, gameforge.locale.guild.no) if s == 1 then guild.war_enter(e) else setskin(NOWINDOW) send_letter(gameforge.locale.guild.war_join_request) --makequestbutton(gameforge.locale.guild.war_join_request) end end end end end
- 9
- 1
- 3
- 1
-
As @TMP4said, Dump Proto does not dump some values to the protos as it isn't needed by the client.
Although your tutorial orientation is correct @TMP4, you have to consider that BYTE is unsigned and it will not dump the correct value of the AddonType since, usually, it holds the value -1 or 0.
So, @ ahmet199, I have made a complete tutorial on how you can add it correctly to your Dump Proto tool and call it from your client.
Dump Proto source.
Spoiler/// 1. @ Srcs/Tools/Dump Proto/ItemCSVReader.h // Add #define DUMP_ITEM_ADDON_TYPE_VALUES /// 2. @ Srcs/Tools/Dump Proto/dump_proto.cpp // Search @ TClientItemTable BYTE bGainSocketPct; // Add below #if defined(DUMP_ITEM_ADDON_TYPE_VALUES) char cAddonType; #endif /// 3. @ Srcs/Tools/Dump Proto/dump_proto.cpp // Search @ bool Set_Proto_Item_Table col++; // AddonType // Replace with #if defined(DUMP_ITEM_ADDON_TYPE_VALUES) itemTable->cAddonType = atoi(csvTable.AsStringByIndex(col++)); #else col++; // AddonType #endif /// 4. @ Srcs/Tools/Dump Proto/dump_proto.cpp // Search @ bool BuildItemTable item_table->bGainSocketPct = tempTable->bGainSocketPct; // Add below #if defined(DUMP_ITEM_ADDON_TYPE_VALUES) item_table->cAddonType = tempTable->cAddonType; #endif
Client source.
Spoiler/// 1. @ Srcs/Client/GameLib/ItemData.h // Search @ TItemTable BYTE bGainSocketPct; // Add below char cAddonType; /// 2. @ Srcs/Client/GameLib/ItemData.h // Search int GetSocketCount() const; // Add below char GetAddonType() const; /// 3. Srcs/Client/GameLib/ItemData.cpp // Search DWORD CItemData::GetIconNumber() const // Add above char CItemData::GetAddonType() const { return m_ItemTable.cAddonType; }
Finally, here is how you can get that value from the item module.
Client source.
Spoiler/// 1. @ Srcs/Client/UserInterface/PythonItemModule.cpp // Search PyObject* itemGetIconInstance(PyObject* poSelf, PyObject* poArgs) // Add above PyObject* itemGetAddonType(PyObject* poSelf, PyObject* poArgs) { CItemData* pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); if (!pItemData) return Py_BuildException("no selected item data"); return Py_BuildValue("i", pItemData->GetAddonType()); } /// 2. @ Srcs/Client/UserInterface/PythonItemModule.cpp // Search { "GetIconInstance", itemGetIconInstance, METH_VARARGS }, // Add above { "GetAddonType", itemGetAddonType, METH_VARARGS },
Root example.
Spoiler''' 1. @ Client/Root/uiToolTip.py ''' # Search def __AppendLimitInformation(self): appendSpace = False # Add below self.AppendTextLine("AddonType %d" % (item.GetAddonType()), self.CONDITION_COLOR)
- 1
- 2
-
function notice_all_yellow(text) notice_all("|cFFFFFF00|H|h" .. text) end
- 1
-
18 hours ago, tarata12 said:
Hello,
Where can I find those letters in the black circle? I already looked for root, locale, binary source and I can't find it, if someone can help me I would appreciate it very much.
IMAGE:
You can find the version number in the client's source at UserInterface/Locale_inc.h
Good luck with that version...Spoiler- 1
- 1
- 2
-
There isn't any other proper way to fix this unless you calculate the sash from the matrix of the bone. You can check the author of the topic below that provides the best fix for this.
If you don't want to calculate the position for every animation (which isn't worth it) while you're on a specific mount, dead or any other animation, it's worth checking out the topic.
1. Scaling method.
-
Thanks for sharing, as always!
You could also check the position realtime while the player is in range so it updates faster.
/// 1. @ UserInterface/PythonMiniMap.cpp // Search @ void CPythonMiniMap::RenderAtlas const auto& PartyInfo = it->second; __GlobalPositionToAtlasPosition(PartyInfo->lX - m_dwAtlasBaseX, PartyInfo->lY - m_dwAtlasBaseY, &PartyInfo->fScreenX, &PartyInfo->fScreenY); // Replace with long xPos = PartyInfo->lX; long yPos = PartyInfo->lY; CInstanceBase* pkInst = CPythonCharacterManager::Instance().GetInstancePtrByName(pPartyMemberInfo->strName.c_str()); if (pkInst) { TPixelPosition kInstPos; pkInst->NEW_GetPixelPosition(&kInstPos); xPos = kInstPos.x + m_dwAtlasBaseX; yPos = kInstPos.y + m_dwAtlasBaseY; } __GlobalPositionToAtlasPosition(xPos - m_dwAtlasBaseX, yPos - m_dwAtlasBaseY, &PartyInfo->fScreenX, &PartyInfo->fScreenY);
- 2
- 3
- 2
- 7
Official Keyboard Settings System
in Features & Metin2 Systems
Posted · Edited by Owsap
Added left alt show name and quick page toggle.
M2 Download Center
As the title indicates, the system allows you to change the default keyboard keys.
Click here to check the tutorial for adding new keys & functions.
Click here for tab targeting key support.