Jump to content

metin2-factory

Inactive Member
  • Posts

    174
  • Joined

  • Last visited

  • Days Won

    13
  • Feedback

    0%

Posts posted by metin2-factory

  1. I haven't been active on this forum since last year but i'v heard from a friend what has happened. 

    I'm surprised metin2 is still alive to this day.. for the mmorpg's fan among us it has been obvious that mmorpg's is a dying genre.

    You barely see any new mmo's coming out and even those that do most of them are p2w crap. 

    This actually could be the reason people still play old games such as WoW or metin2, because the lack of new mmorpgs.

    Anyway, now i'm sure this game will die for sure. the main reason it actually lived to this day is the innovation & creative thinking private servers has brought to keep

    this game alive. I'v even seen systems from popular new games such as battle royal, MOBA etc. these innovations is what keep players in this game because even tho

    the graphics are old, gameplay is medicore and animations are eh but the content is what really matters. And let's be honest here, what innovation did gameforge bring

    except of cash grab p2w systems? On the other hand, you can find plenty of extremely interesting innovative systems on these large pservers. 

    Even on my own server(dead since 2 years) i have developed very unique dungeon competition timer ranking systems that no one until today have developed.

    Today it's the era of open source and sharing, companies who fail to adhere that will eventually die. why did microsoft published all of their recent products fully open source?

    microsoft was considered one of the biggest fan of closed source until few years ago. today, it doesn't catch.

    So, unless gameforge will publicly support pservers(or alternatively make this game open source) this game will for sure die.

    For those who relying their income on pserver, get a real job or open a real business.

    Peace

    • Love 1
  2. 4 minutes ago, Koray said:

    I can bet nobody cares this thread and content, they will still continue to take it for "protection". Look at to him repulation and remember comments on his sale thread, and finally remember that the account is still not banned despite all the cancer content. In this community there are a lot of braindead peoples.

    The real reason is because there isn't any management in this forum ,either that or a really bad one because even tho i come here every few days i see nothing has changed.

    i said it last year already that the forum is dying, i guess the management is too lazy to find new moderators

  3. 14 hours ago, tierrilopes said:

    It doesn't block brute-force, it makes the brute-force atempts useless because the password storage method is different.

    Yet, they can unpack your client, view the salt (I'm considering it is the same for all accounts) and adapt their brute-force.

    You should make an unique salt for each account, and use to make a hash (new versions of sha are nice).

    You can do like you said also, but it shouldn't be your first line of defense, blocking ip + hwid for 30min after 5wrong logins atempts in the last 5minutes for example.

    You can also implement 2-step auth on your server, check Google authenticator.

    2-step auth is a great idea as well, but entering a 2nd password with every entrance can hurt the user experience so i'm not sure about that(i'm not a UX expert xD).

    blocking ip + hwid is too much(why the rest of the family has to suffer if one is being a jackass?). blocking hwid can be bypassed aswell if i'm not mistaken? i know

    that mac address can be spoofed for sure.

    i'd go with the unique salt per account, or, make a very intuitive and user friendly 2-step auth system.

    GL :)

  4. 1 hour ago, emanuel said:

    Its about client side bro, i wanna know if its possibile to stop brute force on login client side 

    https://en.wikipedia.org/wiki/Salt_(cryptography)

    Reading/googling before commenting can do wonders mate :)

     

    Basically, having a hash generator in client & server side with symmetric encryption methods can significantly minimize the chance of successful bruteforce.

    For example, in client you'll have the salt encrypt method, it will convert the login data into a one way hash.

    and server will check if the hashed data equivalent to the database data.

    server side check, example:

    if (clientLoginHashedData is not equal encrypt(databaseLoginData)

    {

    return false;

    }

     

    If you're interested i can code for you such a system(not free).

    Good luck.

  5. yep.. i used to contribute here quite often but i'v stopped since few months. since i saw the amount of people leeching and not sharing anything with others 

    i have decided to stop. also few people just keep criticizing others work without even understanding how it works just cause they were bored.

     

    Right now im working full time as developer(c#) in finance company but i still develop games as hobby and im working on a generic game management system(metin2 included)

    that ill be selling in a month or two to public.

     

    metin2 is no longer alive as it used to be and that's a fact. one of the biggest reasons for metin2dev to die is because of lack of management(in my opinion).

    • Love 3
  6. The best tutorial you will find is by exploring the metin2 client source code yourself.

    My advice would be start from the main function in userinterface.cpp then dive in and see where it leads you. 

    metin2 UI is coded in python that is embedded in c++. so on run time the python code is being converted into c++. 

    so your best bet is to either be strong in c++ or python(preferably both).

    You can code the client directly in c++ without python although that'd be harder for beginners since python is way easier than c++ for beginners.

    nodeJS is a server side language, won't help you here.

  7. @Syerldar I totally agree with you regarding the importance of code being readable, maintainable and etc. 

    Yet, i do feel an urge to be a little pedant on such performance issues. because personally when developing systems you should always taking scalability factor into account.

    Right now it indeed has no impact but what if you had to iterate over 1000 or 1.000.000 or even 100.000.000 objects? metin2 is a real time action game

    and you always should aim for players to have the best performance possible.

    This case ofcours isn't included because we're iterating over a list of party members but i wrote it just as an example of why it is important to know how stuff works

    under the hood.

    and @Yiv i agree with what you said but again in my opinion using prefix incerement would always be preferable over postfix. because you always should expect for the worse.

    If you're using an old/crappy compiler it is not certain it will do the required optimizations. and, the best case scenerio for postfix incrementor would be to even out with prefix performance.

     

    There is a reason why the developers used prefix incerement for iterators and were very persistent and consistent about it in their entire code base.

  8. @Distraught the reason it ran faster is most likely due to this part of his code:

    if (GetNearMemberCount() <= iCount)
    	{
    		for (; it != m_memberMap.end(); it++)
    		{
    			if (it->second.pCharacter && it->second.pCharacter->CountSpecifyItem(itemVnum))
    				it->second.pCharacter->RemoveSpecifyItem(itemVnum);
    		}
    		
    		return true;
    	}

    he didn't assign a starting object to iterate over in this part of the code. and therefore it doesn't execute the loop part of the code. and as consequence you get supposedly a better performance.

    this for loop condition will always fail.. take a look.

    • Love 1
  9. 11 minutes ago, Tasho said:

    Who say that? Who buyed all stuff from lennt and ken and now is 'programmer' ?

    Don't let me to make public conversations between you and others people from some time ago with proofs,  just stop to look 'smart', you are not in a position to give me 'advices'.

    Just stop with that, i really don't care about you and m2 shit, you took it too seriously that, stop to make off-topic.

    Well, unlike you and most of the other "Devs" here i actually have a degree in computer science and working in a real world programming job, i develop metin2 systems for fun.

    so unless you're a certified developer or have a real world programming experience you have no right to judge other code. especially because you barely understand how it works

    under the hood.

    Lennet was one of a few devs here that actually deserve credit because he understood how stuff works unlike you.

  10. Quote
    
    bool CParty::CheckItem(int itemVnum)
    {
    	int iCount = 0;
    	itertype(m_memberMap) it = m_memberMap.begin();
    
    	for (; it != m_memberMap.end(); it++)
    	{
    		if (it->second.pCharacter && it->second.pCharacter->CountSpecifyItem(itemVnum))
    			iCount++;
    	}
    
    	if (GetNearMemberCount() <= iCount)
    	{
    		for (; it != m_memberMap.end(); it++)
    		{
    			if (it->second.pCharacter && it->second.pCharacter->CountSpecifyItem(itemVnum))
    				it->second.pCharacter->RemoveSpecifyItem(itemVnum);
    		}
    		
    		return true;
    	}
    
    	return false;
    }

    @Tasho

    His code style is perfectly fine.your addition actually made it for the worse.

     it is actually recommended to use ++it instead of it++ for 2 reasons

    first, iterator is a container class and when you use a postfix ++ the compiler use the overloaded operator ++ method

    look at the code example below:

    Foo& Foo::operator++()   // called for ++i
    {
        this->data += 1;
        return *this;
    }
    
    Foo Foo::operator++(int ignored_dummy_value)   // called for i++
    {
        Foo tmp(*this);   // variable "tmp" cannot be optimized away by the compiler
        ++(*this);
        return tmp;
    }

     

    you can clearly see why prefix++ is better for perfomance for class objects.

    the postfix++ actually creates a temp object which obviously result in less performance.

    and second: in most of the code you'll see the iterators style is with prefix ++ operator. so it would be better to use it to match the original source style.

     

    and for next time, please, unless you have a deep knowledge of c++ and design patterns, do not call others "bad style" because right now his code performance is better than yours.

    • Love 1
  11. Thank you for showing me that, appreciate it.

    There are a few things i don't like with the official way of doing it, you may agree with me or not it's subjective to each own.

    First, they have hard-coded the element values. this means that it is very hard to maintain the code, you must be very cautions with every change you make(i made it with indexing instead so its easier to maintain).

    Second, Element values defined both in client and server..again, very hard to maintain because if you change something in client you need to remember to change also in server and that can lead to bugs.

    Third, adding new part, that means you need to add a DWORD field for the character packet( that is updated very often) DWORD weight 4 bytes for very often updates isnt really worth it.

    There are more reasons but i dont think its important to mention them here.

    I personally think it doesn't really matter much tbh. 

  12. 2 hours ago, JeeX said:

    Are there any updates yet?

    Its a rly nice system, but can't use with these problems...
    Still have no Image after Tooltip Update...

    def OnElementImageOverIn(self):
    			if not self.elementImageToolTip:
    				self.elementImageToolTip = uiToolTip.ToolTip()
    			self.elementImageToolTip.ClearToolTip()
    			self.elementImageToolTip.AppendTextLine(ELEMENT_IMAGE_DIC[self.elementId] + " element")
    			self.elementImageToolTip.SetToolTipPosition(self.GetLeft() - 40, self.GetTop() + 70)
    			self.elementImageToolTip.Show()
    
    		def OnElementImageOverOut(self):
    			if self.elementImageToolTip:
    				self.elementImageToolTip.Hide()

    Make sure the tabs there are correct, otherwise you will have problems.

    This system has been tested on different servers and it works fine so you need to figure where the issue is at your end.

  13. Small update #2

    If you have installed my official like new elemental bonuses. follow the small guide below to view element icon of a target that wears

    the new rings, like in official.

    CxLhHukNSNe0fnTg7Ks24w.png

     

    open char.cpp,look for: 

    #ifdef ELEMENT_TARGET

    replace the entire content of the #ifdef, until the #endif with the following:

    #ifdef ELEMENT_TARGET
    	p.bElement = 0;
    	BYTE elementBase = 0;
    	DWORD raceFlag;
    	if (m_pkChrTarget)
    	{
    		if (m_pkChrTarget->IsMonster() && (raceFlag = m_pkChrTarget->GetMobTable().dwRaceFlag) >= RACE_FLAG_ATT_ELEC)
    		{
    			for (int i = RACE_FLAG_ATT_ELEC; i > 1; i /= 2)
    			{
    				elementBase++;
    			}
    			DWORD curElementBase = elementBase;
    			const int ELEMENT_BASE_FLAG = pow(2, elementBase);
    			for (int i = RACE_FLAG_ATT_ELEC; i <= RACE_FLAG_ATT_DARK; i *= 2)
    			{
    				curElementBase++;
    				int diff = raceFlag - i;
    				if (abs(diff) < ELEMENT_BASE_FLAG)
    					break;
    			}
    			p.bElement = curElementBase - elementBase;
    		}
    		else if (m_pkChrTarget->IsPC())
    		{
    			LPITEM pItem = m_pkChrTarget->GetWear(WEAR_RING1);
    			if (pItem)
    			{
    				const int BASE_ELEMENT = APPLY_ATTBONUS_ELEC;
    				for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
    				{
    					if (pItem->GetNewAttributeType(i) >= APPLY_ATTBONUS_ELEC && pItem->GetSocket(i) <= APPLY_ATTBONUS_DARK)
    					{
    						p.bElement = pItem->GetNewAttributeType(i) - BASE_ELEMENT + 1;
    						break;
    					}
    				}
    			}
    		}
    	}
    
    #endif

     

    Compile server and that's it. now, when you select a target that wear a ring with elemental bonuses, an element icon will appear next to the target.

    • Love 1
  14. Hi,

    I have worked on official like new elemental bonuses(strong against elec,fire,ice,wind,earth,dark), follow the guide below to add it to your server.

    Please like this topic if you find it useful! :) 

    (C) Metin2 Guild wars - (If you're looking for a custom made metin2 systems in c++/python send me a pm).

    Screenshots:

    O9Eu1CUDTauik5kDQ-mzZQ.png

    JyjQEjSBTDeKcfzlxEjrsw.png

     

    Let's begin!

    Server side:

    open service.h,add at the bottom:

    #define ELEMENT_NEW_BONUSES

    open length.h, look for:

    	MAX_APPLY_NUM,
    };

    add above:

    #ifdef ELEMENT_NEW_BONUSES
    	APPLY_ATTBONUS_ELEC,
    	APPLY_ATTBONUS_FIRE,
    	APPLY_ATTBONUS_ICE,
    	APPLY_ATTBONUS_WIND,
    	APPLY_ATTBONUS_EARTH,
    	APPLY_ATTBONUS_DARK,
    #endif


    in the same file replace enumERaceFlags with:

    enum ERaceFlags
    {
    RACE_FLAG_ANIMAL = (1 << 0),
    RACE_FLAG_UNDEAD = (1 << 1),
    RACE_FLAG_DEVIL = (1 << 2),
    RACE_FLAG_HUMAN = (1 << 3),
    RACE_FLAG_ORC = (1 << 4),
    RACE_FLAG_MILGYO = (1 << 5),
    RACE_FLAG_INSECT = (1 << 6),
    RACE_FLAG_FIRE = (1 << 7),
    RACE_FLAG_ICE = (1 << 8),
    RACE_FLAG_DESERT = (1 << 9),
    RACE_FLAG_TREE = (1 << 10),
    RACE_FLAG_ELEC = (1 << 11),
    RACE_FLAG_WIND = (1 << 12),
    RACE_FLAG_EARTH = (1 << 13),
    RACE_FLAG_DARK = (1 << 14),
    RACE_FLAG_ATT_ELEC = (1 << 15),
    RACE_FLAG_ATT_FIRE = (1 << 16),
    RACE_FLAG_ATT_ICE = (1 << 17),
    RACE_FLAG_ATT_WIND = (1 << 18),
    RACE_FLAG_ATT_EARTH = (1 << 19),
    RACE_FLAG_ATT_DARK = (1 << 20),
    };
     

    open battle.cpp, look for:

    else if (pkVictim->IsRaceFlag(RACE_FLAG_ICE))
    			iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ICE)) / 100;

    add below:

    #ifdef ELEMENT_NEW_BONUSES
    		else if (pkVictim->IsRaceFlag(RACE_FLAG_ELEC))
    			iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ELEC)) / 100;
    		else if (pkVictim->IsRaceFlag(RACE_FLAG_WIND))
    			iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_WIND)) / 100;
    		else if (pkVictim->IsRaceFlag(RACE_FLAG_EARTH))
    			iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_EARTH)) / 100;
    		else if (pkVictim->IsRaceFlag(RACE_FLAG_DARK))
    			iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_DARK)) / 100;
    #endif

    open char.cpp, look for: 

    case POINT_NORMAL_HIT_DEFEND_BONUS:

    add below:

    #ifdef ELEMENT_NEW_BONUSES
    		case POINT_ATTBONUS_ELEC:
    		case POINT_ATTBONUS_FIRE:
    		case POINT_ATTBONUS_ICE:
    		case POINT_ATTBONUS_WIND:
    		case POINT_ATTBONUS_EARTH:
    		case POINT_ATTBONUS_DARK:
    #endif

    in char.cpp, look for:

    PointChange(aApplyInfo[bApplyType].bPointType, iVal);

    add above:

    #ifdef ELEMENT_NEW_BONUSES
    		case APPLY_ATTBONUS_ELEC:
    		case APPLY_ATTBONUS_FIRE:
    		case APPLY_ATTBONUS_ICE:
    		case APPLY_ATTBONUS_WIND:
    		case APPLY_ATTBONUS_EARTH:
    		case APPLY_ATTBONUS_DARK:
    #endif

    in char.h, look for:

    };
    
    enum EPKModes

    add above:

    #ifdef ELEMENT_NEW_BONUSES
    	POINT_ATTBONUS_ELEC,
    	POINT_ATTBONUS_WIND,
    	POINT_ATTBONUS_EARTH,
    	POINT_ATTBONUS_DARK,
    #endif

    in constants.cpp, look for:

    };
    
    const int aiItemMagicAttributePercentHigh[ITEM_ATTRIBUTE_MAX_LEVEL] = {30, 40, 20, 8, 2};

    add above:

    #ifdef ELEMENT_NEW_BONUSES
    	{ POINT_ATTBONUS_ELEC,},
    	{ POINT_ATTBONUS_FIRE, },
    	{ POINT_ATTBONUS_ICE, },
    	{ POINT_ATTBONUS_WIND, },
    	{ POINT_ATTBONUS_EARTH, },
    	{ POINT_ATTBONUS_DARK, },
    #endif

    now go into db source.

    open ProtoReader.cpp, look for:

    	string arApplyType[] = { "APPLY_NONE", "APPLY_MAX_HP", "APPLY_MAX_SP", "APPLY_CON", "APPLY_INT", "APPLY_STR", "APPLY_DEX", "APPLY_ATT_SPEED", "APPLY_MOV_SPEED", "APPLY_CAST_SPEED", "APPLY_HP_REGEN", "APPLY_SP_REGEN", "APPLY_POISON_PCT", "APPLY_STUN_PCT", "APPLY_SLOW_PCT", "APPLY_CRITICAL_PCT", "APPLY_PENETRATE_PCT", "APPLY_ATTBONUS_HUMAN", "APPLY_ATTBONUS_ANIMAL", "APPLY_ATTBONUS_ORC", "APPLY_ATTBONUS_MILGYO", "APPLY_ATTBONUS_UNDEAD", "APPLY_ATTBONUS_DEVIL", "APPLY_STEAL_HP", "APPLY_STEAL_SP", "APPLY_MANA_BURN_PCT", "APPLY_DAMAGE_SP_RECOVER", "APPLY_BLOCK", "APPLY_DODGE", "APPLY_RESIST_SWORD", "APPLY_RESIST_TWOHAND", "APPLY_RESIST_DAGGER", "APPLY_RESIST_BELL", "APPLY_RESIST_FAN", "APPLY_RESIST_BOW","APPLY_RESIST_FIRE", "APPLY_RESIST_ELEC", "APPLY_RESIST_MAGIC", "APPLY_RESIST_WIND", "APPLY_REFLECT_MELEE", "APPLY_REFLECT_CURSE", "APPLY_POISON_REDUCE", "APPLY_KILL_SP_RECOVER", "APPLY_EXP_DOUBLE_BONUS", "APPLY_GOLD_DOUBLE_BONUS", "APPLY_ITEM_DROP_BONUS", "APPLY_POTION_BONUS", "APPLY_KILL_HP_RECOVER", "APPLY_IMMUNE_STUN", "APPLY_IMMUNE_SLOW", "APPLY_IMMUNE_FALL", "APPLY_SKILL", "APPLY_BOW_DISTANCE", "APPLY_ATT_GRADE_BONUS", "APPLY_DEF_GRADE_BONUS", "APPLY_MAGIC_ATT_GRADE", "APPLY_MAGIC_DEF_GRADE", "APPLY_CURSE_PCT", "APPLY_MAX_STAMINA", "APPLY_ATTBONUS_WARRIOR", "APPLY_ATTBONUS_ASSASSIN", "APPLY_ATTBONUS_SURA", "APPLY_ATTBONUS_SHAMAN", "APPLY_ATTBONUS_MONSTER", "APPLY_MALL_ATTBONUS", "APPLY_MALL_DEFBONUS", "APPLY_MALL_EXPBONUS", "APPLY_MALL_ITEMBONUS", "APPLY_MALL_GOLDBONUS", "APPLY_MAX_HP_PCT", "APPLY_MAX_SP_PCT", "APPLY_SKILL_DAMAGE_BONUS","APPLY_NORMAL_HIT_DAMAGE_BONUS", "APPLY_SKILL_DEFEND_BONUS", "APPLY_NORMAL_HIT_DEFEND_BONUS", "APPLY_PC_BANG_EXP_BONUS", "APPLY_PC_BANG_DROP_BONUS", "APPLY_EXTRACT_HP_PCT", "APPLY_RESIST_WARRIOR", "APPLY_RESIST_ASSASSIN", "APPLY_RESIST_SURA", "APPLY_RESIST_SHAMAN", "APPLY_ENERGY", "APPLY_DEF_GRADE", "APPLY_COSTUME_ATTR_BONUS", "APPLY_MAGIC_ATTBONUS_PER", "APPLY_MELEE_MAGIC_ATTBONUS_PER", "APPLY_RESIST_ICE", "APPLY_RESIST_EARTH", "APPLY_RESIST_DARK", "APPLY_ANTI_CRITICAL_PCT", "APPLY_ANTI_PENETRATE_PCT", "APPLY_ATTBONUS_WOLF", "APPLY_RESIST_WOLF", "APPLY_RESIST_CLAW", "APPLY_ANTI_RESIST_MAGIC", "APPLY_ATTBONUS_ELECT", "APPLY_ATTBONUS_FIRE", "APPLY_ATTBONUS_ICE", "APPLY_ATTBONUS_WIND", "APPLY_ATTBONUS_EARTH", "APPLY_ATTBONUS_DARK" };

    replace with:

    #ifdef ELEMENT_NEW_BONUSES
    	string arApplyType[] = { "APPLY_NONE", "APPLY_MAX_HP", "APPLY_MAX_SP", "APPLY_CON", "APPLY_INT", "APPLY_STR", "APPLY_DEX", "APPLY_ATT_SPEED", "APPLY_MOV_SPEED", "APPLY_CAST_SPEED", "APPLY_HP_REGEN", "APPLY_SP_REGEN", "APPLY_POISON_PCT", "APPLY_STUN_PCT", "APPLY_SLOW_PCT", "APPLY_CRITICAL_PCT", "APPLY_PENETRATE_PCT", "APPLY_ATTBONUS_HUMAN", "APPLY_ATTBONUS_ANIMAL", "APPLY_ATTBONUS_ORC", "APPLY_ATTBONUS_MILGYO", "APPLY_ATTBONUS_UNDEAD", "APPLY_ATTBONUS_DEVIL", "APPLY_STEAL_HP", "APPLY_STEAL_SP", "APPLY_MANA_BURN_PCT", "APPLY_DAMAGE_SP_RECOVER", "APPLY_BLOCK", "APPLY_DODGE", "APPLY_RESIST_SWORD", "APPLY_RESIST_TWOHAND", "APPLY_RESIST_DAGGER", "APPLY_RESIST_BELL", "APPLY_RESIST_FAN", "APPLY_RESIST_BOW","APPLY_RESIST_FIRE", "APPLY_RESIST_ELEC", "APPLY_RESIST_MAGIC", "APPLY_RESIST_WIND", "APPLY_REFLECT_MELEE", "APPLY_REFLECT_CURSE", "APPLY_POISON_REDUCE", "APPLY_KILL_SP_RECOVER", "APPLY_EXP_DOUBLE_BONUS", "APPLY_GOLD_DOUBLE_BONUS", "APPLY_ITEM_DROP_BONUS", "APPLY_POTION_BONUS", "APPLY_KILL_HP_RECOVER", "APPLY_IMMUNE_STUN", "APPLY_IMMUNE_SLOW", "APPLY_IMMUNE_FALL", "APPLY_SKILL", "APPLY_BOW_DISTANCE", "APPLY_ATT_GRADE_BONUS", "APPLY_DEF_GRADE_BONUS", "APPLY_MAGIC_ATT_GRADE", "APPLY_MAGIC_DEF_GRADE", "APPLY_CURSE_PCT", "APPLY_MAX_STAMINA", "APPLY_ATTBONUS_WARRIOR", "APPLY_ATTBONUS_ASSASSIN", "APPLY_ATTBONUS_SURA", "APPLY_ATTBONUS_SHAMAN", "APPLY_ATTBONUS_MONSTER", "APPLY_MALL_ATTBONUS", "APPLY_MALL_DEFBONUS", "APPLY_MALL_EXPBONUS", "APPLY_MALL_ITEMBONUS", "APPLY_MALL_GOLDBONUS", "APPLY_MAX_HP_PCT", "APPLY_MAX_SP_PCT", "APPLY_SKILL_DAMAGE_BONUS","APPLY_NORMAL_HIT_DAMAGE_BONUS", "APPLY_SKILL_DEFEND_BONUS", "APPLY_NORMAL_HIT_DEFEND_BONUS", "APPLY_PC_BANG_EXP_BONUS", "APPLY_PC_BANG_DROP_BONUS", "APPLY_EXTRACT_HP_PCT", "APPLY_RESIST_WARRIOR", "APPLY_RESIST_ASSASSIN", "APPLY_RESIST_SURA", "APPLY_RESIST_SHAMAN", "APPLY_ENERGY", "APPLY_DEF_GRADE", "APPLY_COSTUME_ATTR_BONUS", "APPLY_MAGIC_ATTBONUS_PER", "APPLY_MELEE_MAGIC_ATTBONUS_PER", "APPLY_RESIST_ICE", "APPLY_RESIST_EARTH", "APPLY_RESIST_DARK", "APPLY_ANTI_CRITICAL_PCT", "APPLY_ANTI_PENETRATE_PCT", "APPLY_ATTBONUS_WOLF", "APPLY_RESIST_WOLF", "APPLY_RESIST_CLAW", "APPLY_ANTI_RESIST_MAGIC", "APPLY_ATTBONUS_ELECT", "APPLY_ATTBONUS_FIRE", "APPLY_ATTBONUS_ICE", "APPLY_ATTBONUS_WIND", "APPLY_ATTBONUS_EARTH", "APPLY_ATTBONUS_DARK" };
    #else
    	string arApplyType[] = { "APPLY_NONE", "APPLY_MAX_HP", "APPLY_MAX_SP", "APPLY_CON", "APPLY_INT", "APPLY_STR", "APPLY_DEX", "APPLY_ATT_SPEED", "APPLY_MOV_SPEED", "APPLY_CAST_SPEED", "APPLY_HP_REGEN", "APPLY_SP_REGEN", "APPLY_POISON_PCT", "APPLY_STUN_PCT", "APPLY_SLOW_PCT", "APPLY_CRITICAL_PCT", "APPLY_PENETRATE_PCT", "APPLY_ATTBONUS_HUMAN", "APPLY_ATTBONUS_ANIMAL", "APPLY_ATTBONUS_ORC", "APPLY_ATTBONUS_MILGYO", "APPLY_ATTBONUS_UNDEAD", "APPLY_ATTBONUS_DEVIL", "APPLY_STEAL_HP", "APPLY_STEAL_SP", "APPLY_MANA_BURN_PCT", "APPLY_DAMAGE_SP_RECOVER", "APPLY_BLOCK", "APPLY_DODGE", "APPLY_RESIST_SWORD", "APPLY_RESIST_TWOHAND", "APPLY_RESIST_DAGGER", "APPLY_RESIST_BELL", "APPLY_RESIST_FAN", "APPLY_RESIST_BOW", "APPLY_RESIST_FIRE", "APPLY_RESIST_ELEC", "APPLY_RESIST_MAGIC", "APPLY_RESIST_WIND", "APPLY_REFLECT_MELEE", "APPLY_REFLECT_CURSE", "APPLY_POISON_REDUCE", "APPLY_KILL_SP_RECOVER", "APPLY_EXP_DOUBLE_BONUS", "APPLY_GOLD_DOUBLE_BONUS", "APPLY_ITEM_DROP_BONUS", "APPLY_POTION_BONUS", "APPLY_KILL_HP_RECOVER", "APPLY_IMMUNE_STUN", "APPLY_IMMUNE_SLOW", "APPLY_IMMUNE_FALL", "APPLY_SKILL", "APPLY_BOW_DISTANCE", "APPLY_ATT_GRADE_BONUS", "APPLY_DEF_GRADE_BONUS", "APPLY_MAGIC_ATT_GRADE", "APPLY_MAGIC_DEF_GRADE", "APPLY_CURSE_PCT", "APPLY_MAX_STAMINA", "APPLY_ATTBONUS_WARRIOR", "APPLY_ATTBONUS_ASSASSIN", "APPLY_ATTBONUS_SURA", "APPLY_ATTBONUS_SHAMAN", "APPLY_ATTBONUS_MONSTER", "APPLY_MALL_ATTBONUS", "APPLY_MALL_DEFBONUS", "APPLY_MALL_EXPBONUS", "APPLY_MALL_ITEMBONUS", "APPLY_MALL_GOLDBONUS", "APPLY_MAX_HP_PCT", "APPLY_MAX_SP_PCT", "APPLY_SKILL_DAMAGE_BONUS", "APPLY_NORMAL_HIT_DAMAGE_BONUS", "APPLY_SKILL_DEFEND_BONUS", "APPLY_NORMAL_HIT_DEFEND_BONUS", "APPLY_PC_BANG_EXP_BONUS", "APPLY_PC_BANG_DROP_BONUS", "APPLY_EXTRACT_HP_PCT", "APPLY_RESIST_WARRIOR", "APPLY_RESIST_ASSASSIN", "APPLY_RESIST_SURA", "APPLY_RESIST_SHAMAN", "APPLY_ENERGY", "APPLY_DEF_GRADE", "APPLY_COSTUME_ATTR_BONUS", "APPLY_MAGIC_ATTBONUS_PER", "APPLY_MELEE_MAGIC_ATTBONUS_PER", "APPLY_RESIST_ICE", "APPLY_RESIST_EARTH", "APPLY_RESIST_DARK", "APPLY_ANTI_CRITICAL_PCT", "APPLY_ANTI_PENETRATE_PCT", "APPLY_ATTBONUS_WOLF", "APPLY_RESIST_WOLF", "APPLY_RESIST_CLAW", "APPLY_ANTI_RESIST_MAGIC", };
    #endif

    Compile.

    Client side:

    open locale_inc.h, add at the bottom:

    #define ELEMENT_NEW_BONUSES

    open PythonItemModule.cpp, look for:

    #ifdef ENABLE_NEW_EQUIPMENT_SYSTEM

    add above:

    #ifdef ELEMENT_NEW_BONUSES
    	PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_ELEC", CItemData::APPLY_ATTBONUS_ELEC);
    	PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_FIRE", CItemData::APPLY_ATTBONUS_FIRE);
    	PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_ICE", CItemData::APPLY_ATTBONUS_ICE);
    	PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_WIND", CItemData::APPLY_ATTBONUS_WIND);
    	PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_EARTH", CItemData::APPLY_ATTBONUS_EARTH);
    	PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_DARK", CItemData::APPLY_ATTBONUS_DARK);
    
    #endif

    open Packet.h,look for: 

    POINT_MIN_WEP = 200,

    add above:

    #ifdef ELEMENT_NEW_BONUSES
    		POINT_ATTBONUS_ELEC,
    		POINT_ATTBONUS_WIND,
    		POINT_ATTBONUS_EARTH,
    		POINT_ATTBONUS_DARK,
    #endif

     

    open itemData.h, look for:

    MAX_APPLY_NUM,
    		};
    
    		enum EImmuneFlags

    add above:

    #ifdef ELEMENT_NEW_BONUSES
    			APPLY_ATTBONUS_ELEC,
    			APPLY_ATTBONUS_FIRE,
    			APPLY_ATTBONUS_ICE,
    			APPLY_ATTBONUS_WIND,
    			APPLY_ATTBONUS_EARTH,
    			APPLY_ATTBONUS_DARK,
    #endif

    go to root pack.

    open uiToolTip.py

    look for:

    }
    	
    
    	ATTRIBUTE_NEED_WIDTH = {

    add above:

    		item.APPLY_ATTBONUS_ELEC : localeInfo.TOOLTIP_APPLY_ATTBONUS_ELEC,
    		item.APPLY_ATTBONUS_FIRE : localeInfo.TOOLTIP_APPLY_ATTBONUS_FIRE,
    		item.APPLY_ATTBONUS_ICE : localeInfo.TOOLTIP_APPLY_ATTBONUS_ICE,
    		item.APPLY_ATTBONUS_WIND : localeInfo.TOOLTIP_APPLY_ATTBONUS_WIND,
    		item.APPLY_ATTBONUS_EARTH : localeInfo.TOOLTIP_APPLY_ATTBONUS_EARTH,
    		item.APPLY_ATTBONUS_DARK : localeInfo.TOOLTIP_APPLY_ATTBONUS_DARK,

    go to dump_proto folder, open ItemCSVReader.cpp,look for:

    #include "ItemCSVReader.h"

    add below:

    #define ELEMENT_NEW_BONUSES

    search for:

    	string arApplyType[] = {"APPLY_NONE", "APPLY_MAX_HP", "APPLY_MAX_SP", "APPLY_CON", "APPLY_INT", "APPLY_STR", "APPLY_DEX", "APPLY_ATT_SPEED", "APPLY_MOV_SPEED", "APPLY_CAST_SPEED", "APPLY_HP_REGEN", "APPLY_SP_REGEN", "APPLY_POISON_PCT", "APPLY_STUN_PCT", "APPLY_SLOW_PCT", "APPLY_CRITICAL_PCT", "APPLY_PENETRATE_PCT", "APPLY_ATTBONUS_HUMAN", "APPLY_ATTBONUS_ANIMAL", "APPLY_ATTBONUS_ORC", "APPLY_ATTBONUS_MILGYO", "APPLY_ATTBONUS_UNDEAD", "APPLY_ATTBONUS_DEVIL", "APPLY_STEAL_HP", "APPLY_STEAL_SP", "APPLY_MANA_BURN_PCT", "APPLY_DAMAGE_SP_RECOVER", "APPLY_BLOCK", "APPLY_DODGE", "APPLY_RESIST_SWORD", "APPLY_RESIST_TWOHAND", "APPLY_RESIST_DAGGER", "APPLY_RESIST_BELL", "APPLY_RESIST_FAN", "APPLY_RESIST_BOW","APPLY_RESIST_FIRE", "APPLY_RESIST_ELEC", "APPLY_RESIST_MAGIC", "APPLY_RESIST_WIND", "APPLY_REFLECT_MELEE", "APPLY_REFLECT_CURSE", "APPLY_POISON_REDUCE", "APPLY_KILL_SP_RECOVER", "APPLY_EXP_DOUBLE_BONUS", "APPLY_GOLD_DOUBLE_BONUS", "APPLY_ITEM_DROP_BONUS", "APPLY_POTION_BONUS", "APPLY_KILL_HP_RECOVER", "APPLY_IMMUNE_STUN", "APPLY_IMMUNE_SLOW", "APPLY_IMMUNE_FALL", "APPLY_SKILL", "APPLY_BOW_DISTANCE", "APPLY_ATT_GRADE_BONUS", "APPLY_DEF_GRADE_BONUS", "APPLY_MAGIC_ATT_GRADE", "APPLY_MAGIC_DEF_GRADE", "APPLY_CURSE_PCT", "APPLY_MAX_STAMINA", "APPLY_ATTBONUS_WARRIOR", "APPLY_ATTBONUS_ASSASSIN", "APPLY_ATTBONUS_SURA", "APPLY_ATTBONUS_SHAMAN", "APPLY_ATTBONUS_MONSTER", "APPLY_MALL_ATTBONUS", "APPLY_MALL_DEFBONUS", "APPLY_MALL_EXPBONUS", "APPLY_MALL_ITEMBONUS", "APPLY_MALL_GOLDBONUS", "APPLY_MAX_HP_PCT", "APPLY_MAX_SP_PCT", "APPLY_SKILL_DAMAGE_BONUS","APPLY_NORMAL_HIT_DAMAGE_BONUS", "APPLY_SKILL_DEFEND_BONUS", "APPLY_NORMAL_HIT_DEFEND_BONUS", "APPLY_PC_BANG_EXP_BONUS", "APPLY_PC_BANG_DROP_BONUS", "APPLY_EXTRACT_HP_PCT", "APPLY_RESIST_WARRIOR", "APPLY_RESIST_ASSASSIN", "APPLY_RESIST_SURA", "APPLY_RESIST_SHAMAN", "APPLY_ENERGY",	"APPLY_DEF_GRADE", "APPLY_COSTUME_ATTR_BONUS", "APPLY_MAGIC_ATTBONUS_PER", "APPLY_MELEE_MAGIC_ATTBONUS_PER", "APPLY_RESIST_ICE", "APPLY_RESIST_EARTH", "APPLY_RESIST_DARK", "APPLY_ANTI_CRITICAL_PCT", "APPLY_ANTI_PENETRATE_PCT", "APPLY_ATTBONUS_WOLF", "APPLY_RESIST_WOLF", "APPLY_RESIST_CLAW","APPLY_ANTI_RESIST_MAGIC","APPLY_ATTBONUS_ELECT","APPLY_ATTBONUS_FIRE","APPLY_ATTBONUS_ICE","APPLY_ATTBONUS_WIND","APPLY_ATTBONUS_EARTH","APPLY_ATTBONUS_DARK"};

    replace with:

    #ifdef ELEMENT_NEW_BONUSES
    	string arApplyType[] = {"APPLY_NONE", "APPLY_MAX_HP", "APPLY_MAX_SP", "APPLY_CON", "APPLY_INT", "APPLY_STR", "APPLY_DEX", "APPLY_ATT_SPEED", "APPLY_MOV_SPEED", "APPLY_CAST_SPEED", "APPLY_HP_REGEN", "APPLY_SP_REGEN", "APPLY_POISON_PCT", "APPLY_STUN_PCT", "APPLY_SLOW_PCT", "APPLY_CRITICAL_PCT", "APPLY_PENETRATE_PCT", "APPLY_ATTBONUS_HUMAN", "APPLY_ATTBONUS_ANIMAL", "APPLY_ATTBONUS_ORC", "APPLY_ATTBONUS_MILGYO", "APPLY_ATTBONUS_UNDEAD", "APPLY_ATTBONUS_DEVIL", "APPLY_STEAL_HP", "APPLY_STEAL_SP", "APPLY_MANA_BURN_PCT", "APPLY_DAMAGE_SP_RECOVER", "APPLY_BLOCK", "APPLY_DODGE", "APPLY_RESIST_SWORD", "APPLY_RESIST_TWOHAND", "APPLY_RESIST_DAGGER", "APPLY_RESIST_BELL", "APPLY_RESIST_FAN", "APPLY_RESIST_BOW","APPLY_RESIST_FIRE", "APPLY_RESIST_ELEC", "APPLY_RESIST_MAGIC", "APPLY_RESIST_WIND", "APPLY_REFLECT_MELEE", "APPLY_REFLECT_CURSE", "APPLY_POISON_REDUCE", "APPLY_KILL_SP_RECOVER", "APPLY_EXP_DOUBLE_BONUS", "APPLY_GOLD_DOUBLE_BONUS", "APPLY_ITEM_DROP_BONUS", "APPLY_POTION_BONUS", "APPLY_KILL_HP_RECOVER", "APPLY_IMMUNE_STUN", "APPLY_IMMUNE_SLOW", "APPLY_IMMUNE_FALL", "APPLY_SKILL", "APPLY_BOW_DISTANCE", "APPLY_ATT_GRADE_BONUS", "APPLY_DEF_GRADE_BONUS", "APPLY_MAGIC_ATT_GRADE", "APPLY_MAGIC_DEF_GRADE", "APPLY_CURSE_PCT", "APPLY_MAX_STAMINA", "APPLY_ATTBONUS_WARRIOR", "APPLY_ATTBONUS_ASSASSIN", "APPLY_ATTBONUS_SURA", "APPLY_ATTBONUS_SHAMAN", "APPLY_ATTBONUS_MONSTER", "APPLY_MALL_ATTBONUS", "APPLY_MALL_DEFBONUS", "APPLY_MALL_EXPBONUS", "APPLY_MALL_ITEMBONUS", "APPLY_MALL_GOLDBONUS", "APPLY_MAX_HP_PCT", "APPLY_MAX_SP_PCT", "APPLY_SKILL_DAMAGE_BONUS","APPLY_NORMAL_HIT_DAMAGE_BONUS", "APPLY_SKILL_DEFEND_BONUS", "APPLY_NORMAL_HIT_DEFEND_BONUS", "APPLY_PC_BANG_EXP_BONUS", "APPLY_PC_BANG_DROP_BONUS", "APPLY_EXTRACT_HP_PCT", "APPLY_RESIST_WARRIOR", "APPLY_RESIST_ASSASSIN", "APPLY_RESIST_SURA", "APPLY_RESIST_SHAMAN", "APPLY_ENERGY",	"APPLY_DEF_GRADE", "APPLY_COSTUME_ATTR_BONUS", "APPLY_MAGIC_ATTBONUS_PER", "APPLY_MELEE_MAGIC_ATTBONUS_PER", "APPLY_RESIST_ICE", "APPLY_RESIST_EARTH", "APPLY_RESIST_DARK", "APPLY_ANTI_CRITICAL_PCT", "APPLY_ANTI_PENETRATE_PCT", "APPLY_ATTBONUS_WOLF", "APPLY_RESIST_WOLF", "APPLY_RESIST_CLAW","APPLY_ANTI_RESIST_MAGIC","APPLY_ATTBONUS_ELECT","APPLY_ATTBONUS_FIRE","APPLY_ATTBONUS_ICE","APPLY_ATTBONUS_WIND","APPLY_ATTBONUS_EARTH","APPLY_ATTBONUS_DARK"};
    #else
    	string arApplyType[] = { "APPLY_NONE", "APPLY_MAX_HP", "APPLY_MAX_SP", "APPLY_CON", "APPLY_INT", "APPLY_STR", "APPLY_DEX", "APPLY_ATT_SPEED", "APPLY_MOV_SPEED", "APPLY_CAST_SPEED", "APPLY_HP_REGEN", "APPLY_SP_REGEN", "APPLY_POISON_PCT", "APPLY_STUN_PCT", "APPLY_SLOW_PCT", "APPLY_CRITICAL_PCT", "APPLY_PENETRATE_PCT", "APPLY_ATTBONUS_HUMAN", "APPLY_ATTBONUS_ANIMAL", "APPLY_ATTBONUS_ORC", "APPLY_ATTBONUS_MILGYO", "APPLY_ATTBONUS_UNDEAD", "APPLY_ATTBONUS_DEVIL", "APPLY_STEAL_HP", "APPLY_STEAL_SP", "APPLY_MANA_BURN_PCT", "APPLY_DAMAGE_SP_RECOVER", "APPLY_BLOCK", "APPLY_DODGE", "APPLY_RESIST_SWORD", "APPLY_RESIST_TWOHAND", "APPLY_RESIST_DAGGER", "APPLY_RESIST_BELL", "APPLY_RESIST_FAN", "APPLY_RESIST_BOW", "APPLY_RESIST_FIRE", "APPLY_RESIST_ELEC", "APPLY_RESIST_MAGIC", "APPLY_RESIST_WIND", "APPLY_REFLECT_MELEE", "APPLY_REFLECT_CURSE", "APPLY_POISON_REDUCE", "APPLY_KILL_SP_RECOVER", "APPLY_EXP_DOUBLE_BONUS", "APPLY_GOLD_DOUBLE_BONUS", "APPLY_ITEM_DROP_BONUS", "APPLY_POTION_BONUS", "APPLY_KILL_HP_RECOVER", "APPLY_IMMUNE_STUN", "APPLY_IMMUNE_SLOW", "APPLY_IMMUNE_FALL", "APPLY_SKILL", "APPLY_BOW_DISTANCE", "APPLY_ATT_GRADE_BONUS", "APPLY_DEF_GRADE_BONUS", "APPLY_MAGIC_ATT_GRADE", "APPLY_MAGIC_DEF_GRADE", "APPLY_CURSE_PCT", "APPLY_MAX_STAMINA", "APPLY_ATTBONUS_WARRIOR", "APPLY_ATTBONUS_ASSASSIN", "APPLY_ATTBONUS_SURA", "APPLY_ATTBONUS_SHAMAN", "APPLY_ATTBONUS_MONSTER", "APPLY_MALL_ATTBONUS", "APPLY_MALL_DEFBONUS", "APPLY_MALL_EXPBONUS", "APPLY_MALL_ITEMBONUS", "APPLY_MALL_GOLDBONUS", "APPLY_MAX_HP_PCT", "APPLY_MAX_SP_PCT", "APPLY_SKILL_DAMAGE_BONUS", "APPLY_NORMAL_HIT_DAMAGE_BONUS", "APPLY_SKILL_DEFEND_BONUS", "APPLY_NORMAL_HIT_DEFEND_BONUS", "APPLY_PC_BANG_EXP_BONUS", "APPLY_PC_BANG_DROP_BONUS", "APPLY_EXTRACT_HP_PCT", "APPLY_RESIST_WARRIOR", "APPLY_RESIST_ASSASSIN", "APPLY_RESIST_SURA", "APPLY_RESIST_SHAMAN", "APPLY_ENERGY", "APPLY_DEF_GRADE", "APPLY_COSTUME_ATTR_BONUS", "APPLY_MAGIC_ATTBONUS_PER", "APPLY_MELEE_MAGIC_ATTBONUS_PER", "APPLY_RESIST_ICE", "APPLY_RESIST_EARTH", "APPLY_RESIST_DARK", "APPLY_ANTI_CRITICAL_PCT", "APPLY_ANTI_PENETRATE_PCT", "APPLY_ATTBONUS_WOLF", "APPLY_RESIST_WOLF", "APPLY_RESIST_CLAW", "APPLY_ANTI_RESIST_MAGIC", };
    #endif

    inside locale folder, open locale_game.txt, add in the end:

    TOOLTIP_APPLY_ATTBONUS_ELEC	Strong against Lightning +%d%%	SA
    TOOLTIP_APPLY_ATTBONUS_FIRE	Strong against Fire +%d%%	SA
    TOOLTIP_APPLY_ATTBONUS_ICE	Strong against Ice +%d%%	SA
    TOOLTIP_APPLY_ATTBONUS_WIND	Strong against Wind +%d%%	SA
    TOOLTIP_APPLY_ATTBONUS_EARTH	Strong against Earth +%d%%	SA
    TOOLTIP_APPLY_ATTBONUS_DARK	Strong against Dark +%d%%	SA

     

    Compile and that's it!

    to use it in item_proto.txt you can use:

    APPLY_ATTBONUS_ELEC,

    APPLY_ATTBONUS_FIRE,

    APPLY_ATTBONUS_ICE,

    APPLY_ATTBONUS_WIND,

    APPLY_ATTBONUS_EARTH,

    APPLY_ATTBONUS_DARK

     

    Enjoy!

    • Sad 1
    • Scream 1
    • Love 7
×
×
  • 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.