Premium Syreldar 1890 Posted January 31, 2018 Premium Share Posted January 31, 2018 (edited) Hello, pretty sure anyone of you knows about the Dispel and Heal Lag problem that has been around since always. This little modification will fix both these problems completely. (Thanks @Horinna for helping with the in-game tests) Problem: The RemoveAffect function calls ComputePoints() (Complete rearrange of all the player stats and equip parts, one of the heaviest checks). The correct function to use is RefreshAffect() which does its job pretty fine! But that's not the only problem: Based on the current code, that function would get called every single time an affect gets removed or added, while it should only get called once, at the end of the process. Solution: We could make new functions for those 2 special flags (REMOVE_BAD_AFFECT and REMOVE_GOOD_AFFECT), but in order to keep things simple for you guys, i'll simply "dynamicize" the RemoveAffect function. 1: navigate inside char_affect.cpp: Spoiler find: bool CHARACTER::RemoveAffect(CAffect * pkAff) substitute with: bool CHARACTER::RemoveAffect(CAffect * pkAff, bool single) inside it find: if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType) ComputePoints(); else UpdatePacket(); substitute it with: if (single) { if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType) ComputePoints(); else UpdatePacket(); } else UpdatePacket(); then, find: bool CHARACTER::RemoveAffect(DWORD dwType) inside of it, find: while ((pkAff = FindAffect(dwType))) { RemoveAffect(pkAff); flag = true; } and substitute it with: while ((pkAff = FindAffect(dwType))) { RemoveAffect(pkAff, false); flag = true; } 1 1 2 2 2 2: navigate inside char.h: Spoiler find: bool RemoveAffect(CAffect * pkAff); substitute with: bool RemoveAffect(CAffect * pkAff, bool single = true); This way, we applied a simple boolean value arg to the RemoveAffect function, which will get set to true by default. By setting it to false like this RemoveAffect(affectLUL, false); we are basically saying the game to not Rearrange the points when affectLUL gets removed. now we will use a cycle to do that for every affect like usual, and we will rearrange of the points just once, at the end of the process, like it should be. Done! Comparison: Spoiler Before: https://metin2.download/picture/zO4Qtg5uHwp827fLMUFiLo15XF9N89pC/.gif After: https://metin2.download/picture/3lC1Ccin1FUmj0P11u4dDF21t326y4vh/.gifv Edited May 20, 2023 by Syreldar Core X - External 2 Internal 8 5 30 "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
Premium Speachless 765 Posted January 31, 2018 Premium Share Posted January 31, 2018 Or you can create a new ClearAffect with new definitions of which affect it should clear on target. Link to comment Share on other sites More sharing options...
Premium Syreldar 1890 Posted January 31, 2018 Author Premium Share Posted January 31, 2018 On 1/31/2018 at 11:22 PM, Dobrescu Sebastian said: Or you can create a new ClearAffect with new definitions of which affect it should clear on target. That's not the issue as i said in the topic. You can create a new function which does the same thing as RemoveAffect but without the computepoints check which is the lag factor, but that's the same thing as i did, I kept things simple. "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
Horinna 4 Posted January 31, 2018 Share Posted January 31, 2018 It was a pleasure to test all these things. These kind of bugs are the worst metin2-bugs. Link to comment Share on other sites More sharing options...
Premium Speachless 765 Posted February 1, 2018 Premium Share Posted February 1, 2018 #define IS_FIX_POISON_RISIPA_AFFECT(type) ((type) == AFFECT_MOV_SPEED || (type) == AFFECT_ATT_SPEED || (type) == AFFECT_STR || (type) == AFFECT_DEX || (type) == AFFECT_INT || (type) == AFFECT_CON || (type) == AFFECT_CHINA_FIREWORK || (type) == SKILL_JEONGWI || (type) == SKILL_GEOMKYUNG || (type) == SKILL_CHUNKEON || (type) == SKILL_EUNHYUNG || (type) == SKILL_GYEONGGONG || (type) == SKILL_GWIGEOM || (type) == SKILL_TERROR || (type) == SKILL_JUMAGAP || (type) == SKILL_MANASHILED || (type) == SKILL_HOSIN || (type) == SKILL_REFLECT || (type) == SKILL_KWAESOK || (type) == SKILL_JEUNGRYEOK || (type) == SKILL_GICHEON || (type) == SKILL_JEOKRANG || (type) == SKILL_CHEONGRANG) void CHARACTER::ClearAffect_New(bool bSave) { TAffectFlag afOld = m_afAffectFlag; WORD wMovSpd = GetPoint(POINT_MOV_SPEED); WORD wAttSpd = GetPoint(POINT_ATT_SPEED); itertype(m_list_pkAffect) it = m_list_pkAffect.begin(); while (it != m_list_pkAffect.end()) { CAffect * pkAff = *it; if (bSave) { if (!IS_FIX_POISON_RISIPA_AFFECT(pkAff->dwType)) { ++it; continue; } if (IsPC()) { SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn); } } ComputeAffect(pkAff, false); it = m_list_pkAffect.erase(it); CAffect::Release(pkAff); } if (afOld != m_afAffectFlag || wMovSpd != GetPoint(POINT_MOV_SPEED) || wAttSpd != GetPoint(POINT_ATT_SPEED)) UpdatePacket(); CheckMaximumPoints(); if (m_list_pkAffect.empty()) event_cancel(&m_pkAffectEvent); } That's how i solved a long time ago. Everyone is free to use what he wants. In chat skill at sura skill you use if (IS_SET(m_pkSk->dwFlag, SKILL_FLAG_REMOVE_GOOD_AFFECT)) { ..... if (number(1, 100) <= iAmount2) { pkChrVictim->ClearAffect_New(true); pkChrVictim->AddAffect(m_pkSk->dwVnum, POINT_NONE, 0, AFF_PABEOP, iDur2, 0, true); } } 1 Link to comment Share on other sites More sharing options...
Premium Syreldar 1890 Posted February 1, 2018 Author Premium Share Posted February 1, 2018 29 minutes ago, Dobrescu Sebastian said: Well not much of a difference i guess, i just modified RemoveAffect() in order to behave similiarly. But yea! 1 "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
Socialized 42 Posted February 12, 2018 Share Posted February 12, 2018 I wouldn't suggest anyone using the ops solution, as it isn't working as intended. The issue that you don't take into account is, that e.g. a warrior can use "Sword Aura" or use a dew, ... and the shaman can then use heal onto him (which will trigger RefreshAffect() and thus Compute and apply the points for the already existing affect again!) You should recompute all the players points or refactor the whole affect system (because it is actual garbage) to actually solve this bug. tl;dr: Replace RefreshAffect() through ComputePoints() 1 Link to comment Share on other sites More sharing options...
M.Sorin 284 Posted February 12, 2018 Share Posted February 12, 2018 ^ Tested and the bug iz real. Should refactor the whole affect , because ymir waz fucking lazy to do it right. Link to comment Share on other sites More sharing options...
Premium Syreldar 1890 Posted February 12, 2018 Author Premium Share Posted February 12, 2018 27 minutes ago, Socialized said: I wouldn't suggest anyone using the ops solution, as it isn't working as intended. The issue that you don't take into account is, that e.g. a warrior can use "Sword Aura" or use a dew, ... and the shaman can then use heal onto him (which will trigger RefreshAffect() and thus Compute and apply the points for the already existing affect again!) You should recompute all the players points or refactor the whole affect system (because it is actual garbage) to actually solve this bug. tl;dr: Replace RefreshAffect() through ComputePoints() Thanks for the contribution, done. 10 minutes ago, M.Sorin said: ^ Tested and the bug iz real. Should refactor the whole affect , because ymir waz fucking lazy to do it right. Not really, the issue is they are recomputing points every time an affect gets removed while they should only do it once at the end of the process, as I said. The mistake I made was to simply test the normal case, and not the shaman one. Didn't think that refreshaffect would just readd the affect, that's why the bug was occurring. I fixed it. "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
M.Sorin 284 Posted February 12, 2018 Share Posted February 12, 2018 Yea , i know. But still , ymir was to lazzy to fix some simple things. Not only the affect. Link to comment Share on other sites More sharing options...
Premium Syreldar 1890 Posted February 12, 2018 Author Premium Share Posted February 12, 2018 Just now, M.Sorin said: Yea , i know. But still , ymir was to lazzy to fix some simple things. Not only the affect. Dunno wether or not this is fixed on official servers yet, but yeah. We have to fix a ton of things ourselves. But isn't this what really makes the difference between servers and developers? 1 "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
M.Sorin 284 Posted February 12, 2018 Share Posted February 12, 2018 Right on point, if you are a good developer , you have a good server. But let`s leave this discuss only for affect things xD. Link to comment Share on other sites More sharing options...
Premium Syreldar 1890 Posted February 12, 2018 Author Premium Share Posted February 12, 2018 Well, this forum is kinda dead, i like to talk about things once in a while, regardless of the main topic. 2 "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
Socialized 42 Posted February 13, 2018 Share Posted February 13, 2018 vor 19 Stunden schrieb Syreldar: Well, this forum is kinda dead, i like to talk about things once in a while, regardless of the main topic. I agree with that. Did people move to a different forum or is there a skype group open? Link to comment Share on other sites More sharing options...
Premium Syreldar 1890 Posted February 13, 2018 Author Premium Share Posted February 13, 2018 5 minutes ago, Socialized said: I agree with that. Did people move to a different forum or is there a skype group open? Nah, I believe people just moved on to better things in life, metin2 is full of leechers, no actual respect for developers. 3 "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
metin2-factory 1018 Posted February 13, 2018 Share Posted February 13, 2018 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). 3 Link to comment Share on other sites More sharing options...
Салом 20 Posted February 13, 2018 Share Posted February 13, 2018 (edited) Edited August 24, 2022 by Metin2 Dev Core X - External 2 Internal Link to comment Share on other sites More sharing options...
Premium Dr3Ame3r 33 Posted February 16, 2018 Premium Share Posted February 16, 2018 As i have tested this, i can encounter some type of "errors". If someone uses dispell on me, it doesn't remove my berserk, if he does it the second time, it does remove the berserk, it happens to strong body too, sura's enchanted blade and enchanted armor. Link to comment Share on other sites More sharing options...
Premium Speachless 765 Posted February 16, 2018 Premium Share Posted February 16, 2018 1 hour ago, Dr3Ame3r said: As i have tested this, i can encounter some type of "errors". If someone uses dispell on me, it doesn't remove my berserk, if he does it the second time, it does remove the berserk, it happens to strong body too, sura's enchanted blade and enchanted armor. Try my fix. Link to comment Share on other sites More sharing options...
Premium Syreldar 1890 Posted February 16, 2018 Author Premium Share Posted February 16, 2018 2 hours ago, Dr3Ame3r said: As i have tested this, i can encounter some type of "errors". If someone uses dispell on me, it doesn't remove my berserk, if he does it the second time, it does remove the berserk, it happens to strong body too, sura's enchanted blade and enchanted armor. You did something wrong, it works fine for everybody here. "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
Premium Dr3Ame3r 33 Posted February 16, 2018 Premium Share Posted February 16, 2018 (edited) Acum 1 oră, Syreldar a spus: You did something wrong, it works fine for everybody here. Nope, didn't do anything wrong, it just does not work after the removal effect, i've already told you, it happens only on those spells. I don't think that i am crazy, and the bug replicates like this: https://metin2.download/picture/U9S16K5Bk3SfFsU2nO3pwbvhZ0261T2Z/.gif Edited August 27, 2022 by Metin2 Dev Core X - External 2 Internal 1 1 Link to comment Share on other sites More sharing options...
Premium Syreldar 1890 Posted February 16, 2018 Author Premium Share Posted February 16, 2018 8 minutes ago, Dr3Ame3r said: Nope, didn't do anything wrong, it just does not work after the removal effect, i've already told you, it happens only on those spells. Can you try to add RefreshAffect() before UpdatePacket() on removegoodaffect()? "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
Premium Dr3Ame3r 33 Posted February 16, 2018 Premium Share Posted February 16, 2018 (edited) Acum 6 minute, Syreldar a spus: Can you try to add RefreshAffect() before UpdatePacket() on removegoodaffect()? https://metin2.download/picture/MBWfO9gBj1CxqgsYDZaQMVZnjZV9dXri/.gif Edited August 27, 2022 by Metin2 Dev Core X - External 2 Internal 1 Link to comment Share on other sites More sharing options...
miguelmig 13 Posted February 18, 2018 Share Posted February 18, 2018 On 2/12/2018 at 9:21 PM, Socialized said: I wouldn't suggest anyone using the ops solution, as it isn't working as intended. The issue that you don't take into account is, that e.g. a warrior can use "Sword Aura" or use a dew, ... and the shaman can then use heal onto him (which will trigger RefreshAffect() and thus Compute and apply the points for the already existing affect again!) You should recompute all the players points or refactor the whole affect system (because it is actual garbage) to actually solve this bug. tl;dr: Replace RefreshAffect() through ComputePoints() You don't have to refactor the whole affect system, you can "fix" it with a fix similar to OP's one, just not exactly the same. EDIT: I tried reproducing that bug on my source, but neither the "Sword Aura" nor the "Heal" invokes ComputePoints() Link to comment Share on other sites More sharing options...
Tallywa 35 Posted February 19, 2018 Share Posted February 19, 2018 my error compile char_affect.cpp:771: error: scalar object 'GoodAffects' requires one element in initializer char_affect.cpp: In member function 'void CHARACTER::RemoveGoodAffect()': char_affect.cpp:775: error: a function-definition is not allowed here before ':' token char_affect.cpp:781: error: could not convert 'CHARACTER::RefreshAffect()' to 'bool' char_affect.cpp:782: error: expected `)' before ';' token compile input.cpp char_affect.cpp: At global scope: char_affect.cpp:740: warning: 'GoodAffects' defined but not used Link to comment Share on other sites More sharing options...
Recommended Posts