-
Posts
228 -
Joined
-
Last visited
-
Days Won
15 -
Feedback
0%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by HITRON
-
-
For me is not working hm?
-
47 minutes ago, Mali61 said:
you can use lower instead of replace
moneyString.lower()
I followed his example with the replace bellow just to be understandable. Yes you can.
-
25 minutes ago, WeedHex said:
Resellers have no hands bro ahaha
btw you're right, nowadays share things scares me and I also think of all those who voted negative.
What the fuck?
Is a simple Gui actually 30 lines of code maximum, nothing hard, no need libs or smth else to PROTECT it from resellers.
-
52 minutes ago, xP3NG3Rx said:
I wrote it deliberately like this way to avoid the quest.
Btw, is there any function to the warehouse keeper on private servers still?
Also faster if you can open it anywhere you are, you don't need to get to the npc to do the exchange tho.
Then, could be better with a Icon next to the Yang / Cheque taskbar when you click to open the Quest from there and then the Gui, i think the Informations still useless, and the Window could be smaller, so the buttons Yang / Won to be bigger and have Icon like that Yang Icon -> Cheque Icon that means Exchange Yang -> Won and <->, and also the editline to be centered under like that:
You could just add the Informations in the Quest before the select Yes / No for open the Gui.
If the editline and the tick btn is centered you could also make the window smaller, and the buttons bigger to looks like that ->
with 2 Tabs without the Information Tab.
Just a idea, but i think is fine anyway.
-
Better:
USE_MONEY_K_FORMAT = True if USE_MONEY_K_FORMAT: def FormatMoneyToK(string): moneyString = str(string) moneyString = moneyString.replace("K","k") money = 0 if len(moneyString) > 1 and 'k' in moneyString: money = int(moneyString.replace('k', '000')) return money
- 1
-
Is little bad i think, this could be much more easier but is good idea for a Gui that you can exchange Yang -> Won and <->.
The Information is not really need you can just do it with Quest and when you press Yes to open the Gui from the Warehouse Keeper.
-
2 hours ago, Syreldar said:
Make it complete, then.
switch (type) { case DAMAGE_TYPE_POISON: case DAMAGE_TYPE_BLEEDING: case DAMAGE_TYPE_FIRE: return; } ChangeVictimByAggro(info.iAggro, pAttacker);
switch (type) { case DAMAGE_TYPE_POISON: #ifdef ENABLE_WOLFMAN_CHARACTER case DAMAGE_TYPE_BLEEDING: #endif case DAMAGE_TYPE_FIRE: return; default: break; } ChangeVictimByAggro(info.iAggro, pAttacker);
- 1
-
-
Would be nice if you could also provide informations about the fixes, and why is better like this way.
Example the virtual void with void [...] override; is the same virtual void is for overidding, could be also virtual void [...] override;
++i increments the value, then returns it.
i++ returns the value, and then increments it.
Also when the function is float a simple 0 do the work if the value is zero.
return 0.0f;
return 0;
NULL = 0 (can return integers)
nullptr (is keyword that represents a null pointer value, not integers)
Thanks.
- 2
-
44 minutes ago, OtherChoice said:
The aggro taken is from a damage map iterator hence the only players found by the function are player attacking the monster, moreover you can just create a different method for selecting your next target just the way you select the nearest. The already existing functions checks for invisibility affect when selecting target and they have no knowledge about a potential change of the affect, that's why when you enter invisibility you need to check sectree to tell who and who's not attacking you and inform them about your new state.
example code for GetHighestDpsVictim(LPCHARACTER pkChr) { if (NULL == pkChr) pkChr = this; float fMinDist = 99999.0f; float fMaxDamage = 0.0f; LPCHARACTER pkVictim = NULL; TDamageMap::iterator it = m_map_kDamage.begin(); // 일단 주위에 없는 사람을 걸러 낸다. while (it != m_map_kDamage.end()) { const VID & c_VID = it->first; float fDamage = it->second.iTotalDamage; ++it; LPCHARACTER pAttacker = CHARACTER_MANAGER::instance().Find(c_VID); if (!pAttacker) continue; if (pAttacker->IsAffectFlag(AFF_EUNHYUNG) || pAttacker->IsAffectFlag(AFF_INVISIBILITY) || pAttacker->IsAffectFlag(AFF_REVIVE_INVISIBLE)) continue; float fDist = DISTANCE_APPROX(pAttacker->GetX() - pkChr->GetX(), pAttacker->GetY() - pkChr->GetY()); if (fDist < fMinDist && !pAttacker->IsDead() && fDamage > fMaxDamage) { pkVictim = pAttacker; fMaxDamage = fDamage; } } return pkVictim; }
Base to your idea to find next victim, then yes, otherwise doesn't matter to check if anybody else is invisible cause Monsters can't attack invisible targets at the first place it happens only when you attack and hiding after, but you logic is good in your case.
@Syreldar I tested it and seems that is passing the arg correctly (ifdef).
-
27 minutes ago, OtherChoice said:
Right now I'm not able to test it but I think this is what you were looking for:
in char.h add
friend struct RemoveInvisibleVictim;
then in char_skill.cpp add this struct
struct RemoveInvisibleVictim{ RemoveInvisibleVictim(LPCHARACTER pkOldVictim) { m_pkOldVictim = pkOldVictim; } void operator () (LPENTITY ent) { if (ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER pkChr = (LPCHARACTER) ent; if (pkChr && pkChr->IsMonster()) { LPCHARACTER pkVictim = pkChr->GetVictim(); if (pkVictim && pkVictim == m_pkOldVictim) { LPCHARACTER new_victim = pkChr->GetNearestVictim(pkChr); pkChr->SetVictim(new_victim); } } } } LPCHARACTER m_pkOldVictim; }
then in function (char_skill.cpp) int CHARACTER::ComputeSkill(DWORD dwVnum, LPCHARACTER pkVictim, BYTE bSkillLevel) add
if (dwVnum == SKILL_EUNHYUNG && GetSectree()) { RemoveInvisibleVictim f(this); GetSectree()->ForEachAround(f); }
For any problem please reply providing as much informations as possible.The function already exists in Source, i just improve it a little bit for Ninja's, Your function is not really necessary, also i think is wrong when the Monster losing their aggro to find the nearest victim cause if you are in a group and attacking Boss, if the Ninja has the aggro and after using the Eunhyung Skill, is gonna take a aggro from the nearest player, and maybe the random one couldn't tank the boss, so after when Boss losing their aggro is not Regen back his HP for some seconds as i saw, so someone else could take the aggro before that and continue basic to my idea func.
-
Hey,
In different Games always Ninja's have the ability to hide example in Wow when Rogue hide the Monsters losing their aggro, but in Metin2 when you hide with the Skill Eunhyung the Monster still have aggro on you, this seems little wrong, Hided and Monster still can reach you? Maybe because you can use Poison / Bleeding / Fire that make this little bit difficult, but i think i come up with a solution. I think the only part that missing is when you clean the Target from the Monster to move again back but is not really necessary.
* I Added also for GMs in /in command the function.
In the Tutorial bellow, you can find the Function ForgetMyAttacker with my improvements.
Spoilerin service.h or CommonDefines.h: add:
#define __EUNHYUNG_FORGET_MY_ATTACKER__
char.h
// Search for:
void ForgetMyAttacker();
// Replace with:
#ifdef __EUNHYUNG_FORGET_MY_ATTACKER__ void ForgetMyAttacker(bool bIsEunhyung = false); #else void ForgetMyAttacker(); #endif
char_battle.cpp
// Search for:
struct FuncForgetMyAttacker { [...] }
// Replace with:
struct FuncForgetMyAttacker{ LPCHARACTER m_ch; #ifdef __EUNHYUNG_FORGET_MY_ATTACKER__ bool m_bIsEunhyung; FuncForgetMyAttacker(LPCHARACTER ch, bool bIsEunhyung) { m_ch = ch, m_bIsEunhyung = bIsEunhyung; } #else FuncForgetMyAttacker(LPCHARACTER ch) { m_ch = ch; } #endif void operator()(LPENTITY ent) { if (ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = (LPCHARACTER) ent; if (ch->IsPC()) return; if (ch->m_kVIDVictim == m_ch->GetVID()) { #ifdef __EUNHYUNG_FORGET_MY_ATTACKER__ if (m_bIsEunhyung) { if (ch->IsAffectFlag(AFF_POISON)) ch->RemovePoison(); #ifdef ENABLE_WOLFMAN_CHARACTER if (ch->IsAffectFlag(AFF_BLEEDING)) ch->RemoveBleeding(); #endif if (ch->IsAffectFlag(AFF_FIRE)) ch->RemoveFire(); } #endif ch->SetVictim(NULL); } } } };
// Search for:
void CHARACTER::ForgetMyAttacker() { [...] }
// Replace with:
#ifdef __EUNHYUNG_FORGET_MY_ATTACKER__ void CHARACTER::ForgetMyAttacker(bool bIsEunhyung) #else void CHARACTER::ForgetMyAttacker() #endif { LPSECTREE pSec = GetSectree(); if (pSec) { #ifdef __EUNHYUNG_FORGET_MY_ATTACKER__ FuncForgetMyAttacker f(this, bIsEunhyung); #else FuncForgetMyAttacker f(this); #endif pSec->ForEachAround(f); } #ifdef __EUNHYUNG_FORGET_MY_ATTACKER__ if (!bIsEunhyung) ReviveInvisible(5); #else ReviveInvisible(5); #endif }
char_skill.cpp
// Search for:
bool CHARACTER::UseSkill(DWORD dwVnum, LPCHARACTER pkVictim, bool bUseGrandMaster){ [...] }
// Paste the code in the function:
#ifdef __EUNHYUNG_FORGET_MY_ATTACKER__ if (dwVnum == SKILL_EUNHYUNG) ForgetMyAttacker(true); #endif// Result:
// Don't replace your code with this, hope you have brain.bool CHARACTER::UseSkill(DWORD dwVnum, LPCHARACTER pkVictim, bool bUseGrandMaster) { [...] // Rest of the code. #ifdef __EUNHYUNG_FORGET_MY_ATTACKER__ if (dwVnum == SKILL_EUNHYUNG) ForgetMyAttacker(true); #endif m_dwLastSkillTime = get_dword_time(); m_dwLastSkillVnum = dwVnum; return true; }
cmd_gm.cpp// Seach for:
ACMD(do_invisibility) { [...] }
// Replace with:
ACMD(do_invisibility) { if (ch->IsAffectFlag(AFF_INVISIBILITY)) ch->RemoveAffect(AFFECT_INVISIBILITY); else { ch->AddAffect(AFFECT_INVISIBILITY, POINT_NONE, 0, AFF_INVISIBILITY, INFINITE_AFFECT_DURATION, 0, true); #ifdef __EUNHYUNG_FORGET_MY_ATTACKER__ ch->ForgetMyAttacker(true); #endif } }
- 1
- 1
- 1
- 1
- 22
-
All good.
- 1
-
I forgot to add something in the .rar / updated.
-
Hey,
I will share a function (Set Atlas Scale) that you can set your own scale in your Atlas Window.
As you can see in the Preview the Atlas is bigger than the default. You need to have good quality of Map Image, I think you can use World Editor for this.
Preview:
Spoiler- 46
- 1
- 1
- 1
- 1
- 12
- 1
- 55
-
Hey,
I want to share a fix about the SKILL_MUYEONG, Official fixed this before some months ago, but nobody care in such details so we still have the same issue in our servers.
Spoilerchar_skill.cpp
// Search for:
int CHARACTER::ComputeSkill(DWORD dwVnum, LPCHARACTER pkVictim, BYTE bSkillLevel) { [...] }
// Inside: CHARACTER::ComputeSkill - Search for:
if (bCanUseHorseSkill && pkSk->dwType != SKILL_TYPE_HORSE) return BATTLE_NONE;
// Replace with:
#ifdef __SKILL_MUYEONG_DAMAGE_WHILE_RIDING__ if (bCanUseHorseSkill && pkSk->dwType != SKILL_TYPE_HORSE && pkSk->dwVnum != SKILL_MUYEONG) #else if (bCanUseHorseSkill && pkSk->dwType != SKILL_TYPE_HORSE) #endif return BATTLE_NONE;
service.h or CommonDefines.h
// Define:
#define __SKILL_MUYEONG_DAMAGE_WHILE_RIDING__
The SKILL_MUYEONG is still attacking while you riding but doesn't make any damage.
Preview with Fixed SKILL_MUYEONG while you riding:
https://metin2.download/picture/r3F9504x09DVmF8K988YXgTtGTP6KMUj/.gif
- 9
- 1
- 45
-
Thank you!
Would be nice if we could do Translate.lua too. Maybe is possible to do it with the old Translate.lua (The public one) to replace the Texts base to their number some of them so we can get a result in each language.
- 1
-
Thank you!
-
Post your ProtoReader.cpp - Line: 206.
-
On 1/3/2020 at 12:51 PM, ezonyo123 said:
I've tried with the original horse, the one that you get from the stable... But same result... if my moving speed is higher than 170 and I have equipped weapon costume, sash, costume the player stutter...
So this is happening only when you reach 170 Move Speed? i don't get the part with the equipment can you be more specific?
-
This is very old, but you can search for the latest root from Official is somewhere here posted.
- 1
-
Welcome buddy!
-
7 hours ago, Metin2Place said:
If I do this it won't appear even with my mouse over.
I figured it out.
In PythonTextTail.cpp in void CPythonTextTail::ShowAllTextTail() replace
if (pTextTail->fDistanceFromPlayer < 3500.0f)
with
if (pTextTail->fDistanceFromPlayer < 3500.0f && CPythonCharacterManager::Instance().GetInstancePtr(pTextTail->dwVirtualID)->GetRace() != 30000)
I didn't notice the part with the mouse, but now that you figured it out, good. You may can close now your topic.
- 1
-
Maybe like that:
File: PythonTextTail.cpp
Find:
At : CPythonTextTail::ShowCharacterTextTail Search for: if (pInstance->IsGuildWall()) return; Add bellow: if (pInstance->GetRace() == 30000) return;
Not tested.
- 1
Is safe to use mainline anymore?
in Community Support - Questions & Answers
Posted
Maybe is much more safer than the public Sources with bugged Systems, you have just to fix the normal bug / exploits in mainline if is there any.