Jump to content
metin2dev

Search the Community

Showing results for tags 'how to'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Community
    • Announcements
    • Feedback
  • Metin2
    • General
    • Questions and Answers
    • Guides & HowTo
    • Design
    • Private Servers
    • Services
    • Videos
  • Releases
    • General
    • Tools
    • Programming / Scripts
    • Quests
    • Binaries & Clients/Serverfiles
    • 3D Models
    • 2D Graphics
    • Operating Systems
  • Safe Zone
    • Offtopic
    • Games Talk
    • Music/Videos/Art

Categories

There are no results to display.

There are no results to display.


Found 16 results

  1. [C++]Expand maximum level

    Hi there Devs, I have published a tutorial yesterday on a Hungarian forum, and I decided to share it here, too. So... I chose int type for the level variables (originally its unsigned char) because: its more than enough maximum level 2147483647the damage done by the characters (and much more thing) is calculated via they levels, and the type of this variables is intThis is why I recommend to use int type game/src char.cpp Search this: void CHARACTER::SetLevel(BYTE level)Then replace to this: void CHARACTER::SetLevel(int level)char.h Search this: void SetLevel(BYTE level);Then replace to this: void SetLevel(int level);Then search: BYTE level; (its under this: typedef struct character_point) And replace to this: int level;party.cpp Search this one: void CParty::P2PSetMemberLevel(DWORD pid, BYTE level)Then replace to this: void CParty::P2PSetMemberLevel(DWORD pid, int level)Then replace this: BYTE CParty::GetMemberMaxLevel() { BYTE bMax = 0;To this: int CParty::GetMemberMaxLevel() { int bMax = 0;Find this one: BYTE CParty::GetMemberMinLevel() { BYTE bMin = PLAYER_MAX_LEVEL_CONST;And replace to this: int CParty::GetMemberMinLevel() { int bMin = PLAYER_MAX_LEVEL_CONST;And then this: void CParty::RequestSetMemberLevel(DWORD pid, BYTE level)To this: void CParty::RequestSetMemberLevel(DWORD pid, int level)party.h Search this: BYTE bLevel; (its under typedef struct SMember)And replace to this: int bLevel;Then this ones: BYTE GetMemberMaxLevel(); BYTE GetMemberMinLevel();To this: int GetMemberMaxLevel(); int GetMemberMinLevel();And these: void RequestSetMemberLevel(DWORD pid, BYTE level); void P2PSetMemberLevel(DWORD pid, BYTE level);To: void RequestSetMemberLevel(DWORD pid, int level); void P2PSetMemberLevel(DWORD pid, int level);char_battle.cpp Find: struct FPartyTotaler { int total;And replace to: struct FPartyTotaler { long total;And this: struct FPartyDistributor { int total; LPCHARACTER c; int x, y; DWORD _iExp; int m_iMode; int m_iMemberCount; FPartyDistributor(LPCHARACTER center, int member_count, int total, DWORD iExp, int iMode) To this: struct FPartyDistributor { long total; LPCHARACTER c; int x, y; DWORD _iExp; int m_iMode; int m_iMemberCount; FPartyDistributor(LPCHARACTER center, int member_count, long total, DWORD iExp, int iMode) config.h Find this: extern BYTE PK_PROTECT_LEVEL;And replace to this: extern int PK_PROTECT_LEVEL;locale_service.cpp Change: BYTE PK_PROTECT_LEVELTo this: int PK_PROTECT_LEVELconstants.cpp Well, here you should decide how much is the maximum level you want. You should fill these tables with as much records, as the maximum level. (e.g if you want to have maximum level 300, you need to put 300 records to these tables) const DWORD exp_table_euckr[PLAYER_EXP_TABLE_MAX + 1] const DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1] const DWORD exp_table_newcibn[PLAYER_EXP_TABLE_MAX + 1 ] const DWORD party_exp_distribute_table[PLAYER_MAX_LEVEL_CONST + 1] const int aiExpLossPercents[PLAYER_EXP_TABLE_MAX + 1]log.h Edit this: void LoginLog(bool isLogin, DWORD dwAccountID, DWORD dwPID, BYTE bLevel, BYTE bJob, DWORD dwPlayTime);To this: void LoginLog(bool isLogin, DWORD dwAccountID, DWORD dwPID, int bLevel, BYTE bJob, DWORD dwPlayTime);log.cpp Replace this: void LogManager::LoginLog(bool isLogin, DWORD dwAccountID, DWORD dwPID, BYTE bLevel, BYTE bJob, DWORD dwPlayTime)To this: void LogManager::LoginLog(bool isLogin, DWORD dwAccountID, DWORD dwPID, int bLevel, BYTE bJob, DWORD dwPlayTime)guild.h Replace this: typedef struct SGuildMemberPacketData { DWORD pid; BYTE grade; BYTE is_general; BYTE job; BYTE level; DWORD offer; BYTE name_flag; char name[CHARACTER_NAME_MAX_LEN+1]; } TGuildMemberPacketData;To this: typedef struct SGuildMemberPacketData { DWORD pid; BYTE byGrade; BYTE byIsGeneral; BYTE byJob; int byLevel; DWORD dwOffer; BYTE byNameFlag; } TGuildMemberPacketData;Then this: void ChangeMemberData(DWORD pid, DWORD offer, BYTE level, BYTE grade);To this: void ChangeMemberData(DWORD pid, DWORD offer, int level, BYTE grade);Then SGuildMember(DWORD pid, BYTE grade, BYTE is_general, BYTE job, BYTE level, DWORD offer_exp, char* name);To this: SGuildMember(DWORD pid, BYTE grade, BYTE is_general, BYTE job, int level, DWORD offer_exp, char* name);And this: DWORD pid; // player Ĺ×ŔĚşíŔÇ id; primary key BYTE grade; // ±ćµĺ»óŔÇ ÇĂ·ąŔĚľîŔÇ °č±Ţ 1 to 15 (1ŔĚ ÂŻ) BYTE is_general; BYTE job; BYTE level; DWORD offer_exp; // °řÇĺÇŃ °ćÇčġ BYTE _dummy;To this: DWORD pid; // player Ĺ×ŔĚşíŔÇ id; primary key BYTE grade; // ±ćµĺ»óŔÇ ÇĂ·ąŔĚľîŔÇ °č±Ţ 1 to 15 (1ŔĚ ÂŻ) BYTE is_general; BYTE job; int level; DWORD offer_exp; // °řÇĺÇŃ °ćÇčġ BYTE _dummy; And then this: void LevelChange(DWORD pid, BYTE level);To this: void LevelChange(DWORD pid, int level);guild.cpp Find this: BYTE level = (BYTE)strtoul(row[4], (char**) NULL, 10);Replace to this: int level = (int)strtoul(row[4], (char**) NULL, 10); Then this: sys_log(0, "GUILD: AddMember PID %u, grade %u, job %u, level %u, offer %u, name %s ptr %p",To this: sys_log(0, "GUILD: AddMember PID %u, grade %u, job %u, level %d, offer %u, name %s ptr %p",Then replace the whole function: void CGuild::ChangeMemberData(DWORD pid, DWORD offer, BYTE level, BYTE grade)To this: void CGuild::ChangeMemberData(DWORD pid, DWORD offer, int level, BYTE grade) { TGuildMemberContainer::iterator cit = m_member.find(pid); if (cit == m_member.end()) return; cit->second.offer_exp = offer; cit->second.level = level; cit->second.grade = grade; cit->second._dummy = 0; TPacketGCGuild pack; TGuildMemberPacketData mbData; pack.header = HEADER_GC_GUILD; pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size = sizeof(TPacketGCGuild); pack.size += sizeof(TGuildMemberPacketData); for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it) { LPDESC d = (*it)->GetDesc(); if (d) { TEMP_BUFFER buf; buf.write(&pack, sizeof(pack)); mbData.byNameFlag = 0; mbData.byGrade = cit->second.grade; mbData.byIsGeneral = cit->second.is_general; mbData.byJob = cit->second.job; mbData.byLevel = cit->second.level; mbData.dwOffer = cit->second.offer_exp; mbData.pid = cit->second.pid; buf.write(&mbData, sizeof(TGuildMemberPacketData)); d->Packet(buf.read_peek(), buf.size()); } } }And replace this function too: void CGuild::LevelChange(DWORD pid, BYTE level)To this: void CGuild::LevelChange(DWORD pid, int level) { TGuildMemberContainer::iterator cit = m_member.find(pid); if (cit == m_member.end()) return; cit->second.level = level; TPacketGuildChangeMemberData gd_guild; gd_guild.guild_id = GetID(); gd_guild.pid = pid; gd_guild.offer = cit->second.offer_exp; gd_guild.grade = cit->second.grade; gd_guild.level = level; db_clientdesc->DBPacket(HEADER_GD_GUILD_CHANGE_MEMBER_DATA, 0, &gd_guild, sizeof(gd_guild)); TPacketGCGuild pack; TGuildMemberPacketData mbData; pack.header = HEADER_GC_GUILD; pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size = sizeof(TPacketGCGuild); pack.size += sizeof(TGuildMemberPacketData); cit->second._dummy = 0; for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it) { LPDESC d = (*it)->GetDesc(); if (d) { TEMP_BUFFER buf; buf.write(&pack, sizeof(pack)); mbData.byNameFlag = 0; mbData.byGrade = cit->second.grade; mbData.byIsGeneral = cit->second.is_general; mbData.byJob = cit->second.job; mbData.byLevel = cit->second.level; mbData.dwOffer = cit->second.offer_exp; mbData.pid = cit->second.pid; buf.write(&mbData, sizeof(TGuildMemberPacketData)); d->Packet(buf.read_peek(), buf.size()); } } }Then this function: bool CGuild::OfferExp(LPCHARACTER ch, int amount)To this: bool CGuild::OfferExp(LPCHARACTER ch, int amount) { TGuildMemberContainer::iterator cit = m_member.find(ch->GetPlayerID()); if (cit == m_member.end()) return false; if (m_data.exp+amount < m_data.exp) return false; if (amount < 0) return false; if (ch->GetExp() < (DWORD) amount) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ćµĺ> Á¦°řÇĎ°íŔÚ ÇĎ´Â °ćÇčġ°ˇ ł˛Ŕş °ćÇčġş¸´Ů ¸ą˝Ŕ´Ď´Ů.")); return false; } if (ch->GetExp() - (DWORD) amount > ch->GetExp()) { sys_err("Wrong guild offer amount %d by %s[%u]", amount, ch->GetName(), ch->GetPlayerID()); return false; } ch->PointChange(POINT_EXP, -amount); TPacketGuildExpUpdate guild_exp; guild_exp.guild_id = GetID(); guild_exp.amount = amount / 100; db_clientdesc->DBPacket(HEADER_GD_GUILD_EXP_UPDATE, 0, &guild_exp, sizeof(guild_exp)); GuildPointChange(POINT_EXP, amount / 100, true); cit->second.offer_exp += amount / 100; cit->second._dummy = 0; TPacketGCGuild pack; TGuildMemberPacketData mbData; pack.header = HEADER_GC_GUILD; pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size = sizeof(TPacketGCGuild); pack.size += sizeof(TGuildMemberPacketData); for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it) { LPDESC d = (*it)->GetDesc(); if (d) { TEMP_BUFFER buf; buf.write(&pack, sizeof(pack)); mbData.byNameFlag = 0; mbData.byGrade = cit->second.grade; mbData.byIsGeneral = cit->second.is_general; mbData.byJob = cit->second.job; mbData.byLevel = cit->second.level; mbData.dwOffer = cit->second.offer_exp; mbData.pid = cit->second.pid; buf.write(&mbData, sizeof(TGuildMemberPacketData)); d->Packet(buf.read_peek(), buf.size()); } } SaveMember(ch->GetPlayerID()); TPacketGuildChangeMemberData gd_guild; gd_guild.guild_id = GetID(); gd_guild.pid = ch->GetPlayerID(); gd_guild.offer = cit->second.offer_exp; gd_guild.level = ch->GetLevel(); gd_guild.grade = cit->second.grade; db_clientdesc->DBPacket(HEADER_GD_GUILD_CHANGE_MEMBER_DATA, 0, &gd_guild, sizeof(gd_guild)); return true; }And this function: void CGuild::SendListPacket(LPCHARACTER ch)To this: void CGuild::SendListPacket(LPCHARACTER ch) { /* List Packet Header Count (byte) [ ... name_flag 1 - Ŕ̸§Ŕ» ş¸ł»´ŔłÄ ľČş¸ł»´ŔłÄ name CHARACTER_NAME_MAX_LEN+1 ] * Count */ LPDESC d; if (!(d=ch->GetDesc())) return; TPacketGCGuild pack; pack.header = HEADER_GC_GUILD; pack.size = sizeof(TPacketGCGuild); pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size += sizeof(TGuildMemberPacketData) * m_member.size(); pack.size += (CHARACTER_NAME_MAX_LEN + 1) * m_member.size(); TEMP_BUFFER buf; TGuildMemberPacketData mbData; buf.write(&pack,sizeof(pack)); char c[CHARACTER_NAME_MAX_LEN+1]; for (TGuildMemberContainer::iterator it = m_member.begin(); it != m_member.end(); ++it) { it->second._dummy = 1; mbData.byNameFlag = 1; mbData.byGrade = it->second.grade; mbData.byIsGeneral = it->second.is_general; mbData.byJob = it->second.job; mbData.byLevel = it->second.level; mbData.dwOffer = it->second.offer_exp; mbData.pid = it->second.pid; buf.write(&mbData, sizeof(TGuildMemberPacketData)); strlcpy(c, it->second.name.c_str(), MIN(sizeof(c), it->second.name.length() + 1)); buf.write(c, CHARACTER_NAME_MAX_LEN+1 ); if ( test_server ) sys_log(0 ,"name %s job %d ", it->second.name.c_str(), it->second.job ); } d->Packet(buf.read_peek(), buf.size()); for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it) { SendLoginPacket(ch, *it); } for (TGuildMemberP2POnlineContainer::iterator it = m_memberP2POnline.begin(); it != m_memberP2POnline.end(); ++it) { SendLoginPacket(ch, *it); } }Then this function: void CGuild::SendListOneToAll(DWORD pid)To this: void CGuild::SendListOneToAll(DWORD pid) { TPacketGCGuild pack; pack.header = HEADER_GC_GUILD; pack.size = sizeof(TPacketGCGuild); pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size += sizeof(TGuildMemberPacketData); TGuildMemberPacketData mbData; char c[CHARACTER_NAME_MAX_LEN+1]; memset(c, 0, sizeof(c)); TGuildMemberContainer::iterator cit = m_member.find(pid); if (cit == m_member.end()) return; for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it!= m_memberOnline.end(); ++it) { LPDESC d = (*it)->GetDesc(); if (!d) continue; TEMP_BUFFER buf; buf.write(&pack, sizeof(pack)); cit->second._dummy = 1; mbData.byNameFlag = 1; mbData.byGrade = cit->second.grade; mbData.byIsGeneral = cit->second.is_general; mbData.byJob = cit->second.job; mbData.byLevel = cit->second.level; mbData.dwOffer = cit->second.offer_exp; mbData.pid = cit->second.pid; //buf.write(&(cit->second), sizeof(DWORD) * 3 +1); buf.write(&mbData, sizeof(TGuildMemberPacketData)); buf.write(cit->second.name.c_str(), cit->second.name.length()); buf.write(c, CHARACTER_NAME_MAX_LEN + 1 - cit->second.name.length()); d->Packet(buf.read_peek(), buf.size()); } }Then find this: SGuildMember::SGuildMember(DWORD pid, BYTE grade, BYTE is_general, BYTE job, BYTE level, DWORD offer_exp, char* name)And replace to this: SGuildMember::SGuildMember(DWORD pid, BYTE grade, BYTE is_general, BYTE job, int level, DWORD offer_exp, char* name)common tables.h Find this: BYTE byLevel;Replace to this: int byLevel;Then this: BYTE level;To this: int level;And this: BYTE level;To this: int level;Then this: BYTE bLevel;(under typedef struct SPacketPartySetMemberLevel) To this: int bLevel;And then this: BYTE bLevel;(under typedef struct SPacketDGGuildMember) To this: int bLevel;lenght.h Then here set the maximum level: PLAYER_EXP_TABLE_MAX = 120, PLAYER_MAX_LEVEL_CONST = 120,db/src ClientManager.h Find this: struct TPartyInfo { BYTE bRole; BYTE bLevel;Replace to this: struct TPartyInfo { BYTE bRole; int bLevel;ClientManager.cpp Search this: pkPeer->Encode(&it_member->second.bLevel, sizeof(BYTE));(its in the void CClientManager::SendPartyOnSetup(CPeer* pkPeer) function) and replace with this: pkPeer->Encode(&it_member->second.bLevel, sizeof(int));ClientManagerPlayer.cpp Find this: "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d"Then replace to this: "PLAYER_DELETE FAILED LEVEL %d >= DELETE LIMIT %d"And find this: "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d"You will find it 2 times, replace both to this: "PLAYER_DELETE FAILED LEVEL %d >= DELETE LIMIT %d"client packet.h Find this: BYTE byLevel;Then replace to this: int byLevel;And this: BYTE byLevel;To this: int byLevel;PythonGuild.h Find this: BYTE byLevel;And replace to this: int byLevel;And finally, edit the level colum in the player table in the player database. Set its type from tinyint to smallint (or int, it depends how high is the maximum level) and expand its size to 3 (or higher). And then, here you are I also made a video while I made this, if you have free 42 minute, maybe worth to watch it (if you do, you are my guest for a beer (or something liquid :D)) https://www.youtube.com/embed/NTN5mwEeEv8 If you have question(s)/problem(s)/remark(s), feel free to post it here, or send me a PM. Have a nice day, ~masodikbela
  2. Hello devs Today I would like to present you a new solution that can make you feel more safe with your GMs. This is my first release and it's very simple to do, I'm just posting it here for the newbies and those who don't know how to start searching and other shit like that WHAT IS THIS SYSTEM? This system is a number of preventions for GameMaster characters about certain interractions with normal players in the game. The functions you are about to see are blocking GMs from: Trading items with normal players (and the opposite) Invite normal players to parties (and the opposite) Invite normal players to guilds (and the opposite) Adding normal players as friend contacts (I would say and the opposite but it already exists by default ) Drop items to the ground Build their own private shops with the Bundle item Buy items from a private shop Block a GM from buffing normal players Using the commands /set, /a and /setskillother to normal players WHO IS THIS SYSTEM FOR? I believe we can all agree that trust in partnership is a rare thing these days. This system is released from me for the Admins out there that cannot trust their GMs (and many times their self) so much. Imagine having a server and your GM just gives away items for free to everyone. Bad huh? I thought so... So with this system you are sure that your GMs will do their job properly and won't violate any game rules behind your backs. Your server has rules (as all games out there) and if you wanted people to have some items for free you can easily put those items for sale into the town vendors. People who do this kind of things behind your backs are not authorized by you to do it but I believe that it happened (if not happening yet) to the best of you guys, that's why I'm releasing it. It's time to set some things right in your servers, GMs exist to answer questions and not helping players cheat without any authorization from the administrators, so without further ado, let's get started. SORRY AGAIN, ONE MORE THING I BELIEVE THIS QUESTION IS IN THE MIND OF A DEVELOPER WHO READS THIS GUIDE: MIND RAPIST, WHY DO YOU USE THE IsGM() BOOLEAN TO CHECK IF A PLAYER IS A GM AND NOT USE THE TRADITIONAL CHECK GetGMLevel() > GM_PLAYER? In this tutorial, we will be using the bool IsGM() instead of the usual check because some of the guys who see this may have added @Alina's GM Elevation system. In that case, GetGMLevel() won't work before the character elevates, so our GMs will be able to bypass the check and just create a perfect item, relog and give it away before they elevate. We don't want that don't we? So who ever wants to use GetGMLevel() > GM_PLAYER instead of IsGM() there is no difference you can do that guys, except if you did the elevation system, then you need to use my function in order to work. So let's get the party started. PARTY INVITATION BLOCK In char.cpp search for the function "void CHARACTER::PartyInvite(LPCHARACTER pchInvitee)" and under add this: Done with party block, let's continue BUNDLE USAGE BLOCK FOR CREATING PRIVATE SHOPS In char_item.cpp search for the function "bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell)" and under add this: Done, let's continue ITEM DROP BLOCK Still in char_item.cpp search for the function "bool CHARACTER::DropItem(TItemPos Cell, BYTE bCount)" and under add this: Done with that one, you can close char_item.cpp. Let's move on BUFF BLOCK In char_skill.cpp find this: and paste this under it: Done with that, next! /SET COMMAND BLOCK FOR PLAYERS In cmd_gm.cpp search for the function "ACMD(do_set)" and under add this: Done, but do not close, we have more commands to block! /A COMMAND BLOCK FOR PLAYERS Still in cmd_gm.cpp, search for the function "ACMD(do_advance)" and under add this: Do not close that file yet, one more command left to block /SETSKILLOTHER COMMAND BLOCK FOR PLAYERS Still in this file, search for the function "ACMD(do_setskillother)" and under add this: Done with the commands, you may close cmd_gm.cpp and move on EXCHANGE BLOCK In exchange.cpp search for the function "bool CHARACTER::ExchangeStart(LPCHARACTER victim)" and under (if you have sash system in your source, the top line may be "if ( IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen() || IsAcceOpen() )") add this: Done with the exchange, moving on! GUILD INVITATION BLOCK In guild.cpp search for the function "void CGuild::Invite( LPCHARACTER pchInviter, LPCHARACTER pchInvitee )" and under add this: Here goes the guild invitation, let's move forward FRIEND LIST BLOCK In input_main.cpp search for the function "int CInputMain::Messenger(LPCHARACTER ch, const char* c_pData, size_t uiBytes)" and find this line: change it like this: Still in the same function, find this line in "case MESSENGER_SUBHEADER_CG_ADD_BY_NAME:": and add this: Friends are done. Let's move on to the last one! BUYING ITEMS FROM PRIVATE SHOPS BLOCK In shop_manager.cpp search for the function "void CShopManager::Buy(LPCHARACTER ch, BYTE pos)" and under add this: Done It's not something hard to do, I just gathered everything in one place, you can now sleep at night knowing that your GMs cannot fraud you. I would like to give special thanks to @VegaS who wrote the blocks for buffs, party and guild invitation, thanks so much buddy Note: These will block any interraction between a GM and a normal player, but a GM will be able to interract with another GM (example trade GM with GM). And before someone asks yes I thought about a safebox block for GMs but there is no need for that since you can login to his account and create 3 players, then logout and delete them directly from their database, leaving 3 warriors with Level 0 that cannot login to the game. Let the poor GMs have their safebox it's the only thing left to them after that I think xD So I hope I helped some folks here the tutorial is done Kind regards ~ Mind Rapist
  3. [HOW TO]ADD NEW ALIGNMENTS

    Hi all.Today i work and tested how to add new alignments Now i finish it and create instructions for you. Now how do it: 1. edit game source open char_battle.cpp and find: int iAlignIndex; and edit for example: if (GetRealAlignment() == 300000) iAlignIndex = 0; else if (GetRealAlignment() >= 200000) iAlignIndex = 1; else if (GetRealAlignment() >= 120000) iAlignIndex = 2; else if (GetRealAlignment() >= 80000) iAlignIndex = 3; else if (GetRealAlignment() >= 40000) iAlignIndex = 4; else if (GetRealAlignment() >= 10000) iAlignIndex = 5; else if (GetRealAlignment() >= 0) iAlignIndex = 6; else if (GetRealAlignment() > -40000) iAlignIndex = 7; else if (GetRealAlignment() > -80000) iAlignIndex = 8; else if (GetRealAlignment() > -120000) iAlignIndex = 9; else if (GetRealAlignment() > -200000) iAlignIndex = 10; else if (GetRealAlignment() > -250000) iAlignIndex = 11; else iAlignIndex = 12; now find FPartyAlignmentCompute f(-20000, pkKiller->GetX(), pkKiller->GetY()); pkKiller->GetParty()->ForEachOnlineMember(f); if (f.m_iCount == 0) pkKiller->UpdateAlignment(-20000); else { sys_log(0, "ALIGNMENT PARTY count %d amount %d", f.m_iCount, f.m_iAmount); f.m_iStep = 1; pkKiller->GetParty()->ForEachOnlineMember(f); } } else pkKiller->UpdateAlignment(-20000); and replace with this: FPartyAlignmentCompute f(-30000, pkKiller->GetX(), pkKiller->GetY()); pkKiller->GetParty()->ForEachOnlineMember(f); if (f.m_iCount == 0) pkKiller->UpdateAlignment(-30000); else { sys_log(0, "ALIGNMENT PARTY count %d amount %d", f.m_iCount, f.m_iAmount); f.m_iStep = 1; pkKiller->GetParty()->ForEachOnlineMember(f); } } else pkKiller->UpdateAlignment(-30000); now find m_iRealAlignment = MINMAX(-200000, m_iRealAlignment + iAmount, 200000); and replace with this: m_iRealAlignment = MINMAX(-300000, m_iRealAlignment + iAmount, 300000); now you can compile game! 2. edit binary: open InstanceBase.h and find: TITLE_NUM = 9, TITLE_NONE = 4, and replace this: TITLE_NUM = 13, TITLE_NUM = 6, Now you can save and close InstanceBase.h. Now open InstanceBase.cpp and find: UINT CInstanceBase::GetAlignmentGrade() and edit for example this: UINT CInstanceBase::GetAlignmentGrade() { if (m_sAlignment == 30000) return 0; else if (m_sAlignment >= 20000) return 1; else if (m_sAlignment >= 12000) return 2; else if (m_sAlignment >= 8000) return 3; else if (m_sAlignment >= 4000) return 4; else if (m_sAlignment >= 1000) return 5; else if (m_sAlignment >= 0) return 6; else if (m_sAlignment > -4000) return 7; else if (m_sAlignment > -8000) return 8; else if (m_sAlignment > -12000) return 9; else if (m_sAlignment > -20000) return 10; else if (m_sAlignment > -25000) return 11; return 12; } now find int CInstanceBase::GetAlignmentType() and edit for example this: int CInstanceBase::GetAlignmentType() { switch (GetAlignmentGrade()) { case 0: case 1: case 2: case 3: case 4: case 5: { return ALIGNMENT_TYPE_WHITE; break; } case 7: case 8: case 9: case 10: case 11: case 12: { return ALIGNMENT_TYPE_DARK; break; } case 6: { return ALIGNMENT_TYPE_NORMAL; break; } } } now you can save and close InstanceBase.cpp and Build binari. 3. edit client Extract root files and open locale.py now find this: TITLE_NAME_LIST = ( PVP_LEVEL0, PVP_LEVEL1, PVP_LEVEL2, PVP_LEVEL3, PVP_LEVEL4, PVP_LEVEL5, PVP_LEVEL6, PVP_LEVEL7, PVP_LEVEL8, ) and replace with this: TITLE_NAME_LIST = ( PVP_LEVEL0, PVP_LEVEL1, PVP_LEVEL2, PVP_LEVEL3, PVP_LEVEL4, PVP_LEVEL5, PVP_LEVEL6, PVP_LEVEL7, PVP_LEVEL8, PVP_LEVEL9, PVP_LEVEL10, PVP_LEVEL11, PVP_LEVEL12, ) now you can save locale.py and open introloading.py find this: TITLE_COLOR_DICT and edit this: TITLE_COLOR_DICT = ( colorInfo.TITLE_RGB_GOOD_6, colorInfo.TITLE_RGB_GOOD_5, colorInfo.TITLE_RGB_GOOD_4, colorInfo.TITLE_RGB_GOOD_3, colorInfo.TITLE_RGB_GOOD_2, colorInfo.TITLE_RGB_GOOD_1, colorInfo.TITLE_RGB_NORMAL, colorInfo.TITLE_RGB_EVIL_1, colorInfo.TITLE_RGB_EVIL_2, colorInfo.TITLE_RGB_EVIL_3, colorInfo.TITLE_RGB_EVIL_4, colorInfo.TITLE_RGB_EVIL_5, colorInfo.TITLE_RGB_EVIL_6, ) now you can save introloading.py and open uicharacter.py find this: COLOR_DICT and edit this: COLOR_DICT = { 0 : colorInfo.TITLE_RGB_GOOD_6, 1 : colorInfo.TITLE_RGB_GOOD_5, 2 : colorInfo.TITLE_RGB_GOOD_4, 3 : colorInfo.TITLE_RGB_GOOD_3, 4 : colorInfo.TITLE_RGB_GOOD_2, 5 : colorInfo.TITLE_RGB_GOOD_1, 6 : colorInfo.TITLE_RGB_NORMAL, 7 : colorInfo.TITLE_RGB_EVIL_1, 8 : colorInfo.TITLE_RGB_EVIL_2, 9 : colorInfo.TITLE_RGB_EVIL_3, 10 : colorInfo.TITLE_RGB_EVIL_4, 11 : colorInfo.TITLE_RGB_EVIL_5, 12 : colorInfo.TITLE_RGB_EVIL_6, } now you can save uicharacter.py and open colorinfo.py and add this: TITLE_RGB_GOOD_6 = (255, 215, 0) TITLE_RGB_GOOD_5 = ( 0, 159, 0) TITLE_RGB_EVIL_5 = (127, 32, 0) TITLE_RGB_EVIL_6 = ( 48, 0, 0) save and you can compile root. now you extract locale and open locale_game.txt find: PVP_LEVEL0 and edit PVP levels for example this: PVP_LEVEL0 King PVP_LEVEL1 Machr PVP_LEVEL2 Rytířský PVP_LEVEL3 Vznešený PVP_LEVEL4 Dobrý PVP_LEVEL5 Přátelský PVP_LEVEL6 Neutrální PVP_LEVEL7 Agresivní PVP_LEVEL8 Úskočný PVP_LEVEL9 Zlomyslný PVP_LEVEL10 Krutý PVP_LEVEL11 Chudák PVP_LEVEL12 Ubožák save and compile locale. This is all. GOOD LUCK! PS: sorry for my bad english.
  4. SpeedTree Modeling

    Hello there, I have just started using SpeedTree 3 so I can create my own trees, but something is not working, in WE trees are 15x smaller and textures aren't applied. That is why I need some tips -Which SpeedTree version should I use? I heard 3 is fully compatible, but I don't like using it, it is weird o.O -How to export it to be fully functional in Metin2? -Why are textures not applied on trees when I look at it in WorldEditor? I would really appreciate your help!
  5. Hello devs it's been a while... Today I have a very strange question: how can I send a request from the gameserver (FreeBSD) to an external server (Windows)? I want to create an XML file that contains the status of the channels (Auth, DB, Ch1,2,3,4,5,6, World server (game99)) and I want my gameserver to send a request that changes the values in the XML on the other server every time a channel is launched or shut down. I know it can be done with the shell files I just don't know how to do it. I appreciate any help
  6. Hey devs I want to change a specific skill's bMethod from SKILL_UP_BY_POINT to SKILL_UP_BY_BOOK before Master can anyone help me to do that? Thanks in advance
  7. Hello devs can anyone show me how to add a new button to the Dragon Soul inventory window? I have my images I want to add something like the Item Shop button of the inventory page but this time I want to make a toogle button (stays at "down" state after click, until clicked again to restore to normal state). I want this button to communicate with the game and changes a quest state. This is the quest What this does is enabling/disabling the Dragon Soul drops from mobs and it comes as a letter and that's very annoying so I want to turn it into a button but I've just started to learning python and I don't even know how to position it. I appreciate any help guys. Thanks in advance
  8. Costume weapon attributes

    Hello guys I have a problem I don't know how to get costume weapon items to have bonus. I searched any potential function in the source but no luck so can somebody help me please? Thanks in advance
  9. Hello devs, I found this tut the other day and I did it. It is actually an effect for non-tradable items when the exchange window is open. When this window is open this system basicly covers the non-tradable item's slot with a white color and makes it unusable for this action. I want to do the same for non-sellable items (vendors and myshop) and non-storagable items. I tried this in my uitooltip (ignore the exchange function this one works ) but I'm getting this syserr Are there any tuts or tips that can help? Thanks in advance
  10. Searching for complete NEW Sash items

    Hello guys I'm searching for the new sash items (effects, icons, txt records and id vnums) and if possible a way to implement them into my binary and packs. I'm using msm but 2 days ago I saw a post somewhere that can help one sash item to apply to every class's body height from the binary. I appreciate any help
  11. I have an idea about Hp bar i need to know How i get Last damage taken from python it was like self.lastdamage = 0 how i can fill this var any idea ?
  12. 6th Skill of Warrior/Ninja

    Hello guys so I tried to implement the 6th skill of the Warrior and the Ninja I have added the nessecary stuff in: - Skilldesc.txt - Skilltable.txt - Skill_power.txt - MySql table - Playersettingmodule.py - Locale.lua - Translate.lua - Questlib.lua Does anyone have instructions for anywhere else I need to install?
  13. Hello guys I just "activated" ring slots and ITEM_RING in my server and everything goes on smoothly except one thing: when my "ring" items had "UNIQUE" type their remaining time was visible. Once I turned them into rings the remaining time was gone. My REAL_TIME and it's value in item_proto is correct. So are there any suggestions to this problem?
  14. 6/7 Bonus Database lv.5

    Hello guys I just noticed a problem that many of you may have with 6/7 attributes and may have ever noticed of it. When I change the 6/7 attributes it changes the bonuses but they come always on their 5th level from the table player.item_attr_rare (ex. if Max HP has lv1 = 200, lv2 = 250, lv3 = 350, lv4 = 400 and lv5 = 500 it fetches only 500). I really need your help on this guys please if anybody has a tip that can help share it below thanks Also if you can help me with this topic I'd appreciate thanks again https://metin2dev.org/board/index.php?/topic/9457-new-resist-flag-for-mob_proto/
  15. How to extract mob_proto?

    Hi, i have a question. How to extract newest mob_proto? Thank you for answers
×