Jump to content

HITRON

Inactive Member
  • Posts

    228
  • Joined

  • Last visited

  • Days Won

    15
  • Feedback

    0%

Posts posted by HITRON

  1. 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.

  2. 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:

    mxhEPJr.png

     

    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 ->

    DdA6H6p.png

    with 2 Tabs without the Information Tab.

     

    Just a idea, but i think is fine anyway.

  3. 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.

  4. 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);

     

    • Love 1
  5. 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.

    • Love 2
  6. 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).

  7. 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.

  8. 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.

     

    Spoiler

    in 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
        }
    }

     

     

    • Dislove 1
    • Confused 1
    • Lmao 1
    • Good 1
    • Love 22
  9. M2 Download Center

    This is the hidden content, please
    ( Internal )

    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

    190951FExw5gW.png

     

    • Metin2 Dev 46
    • kekw 1
    • Sad 1
    • Scream 1
    • Lmao 1
    • Good 12
    • Love 1
    • Love 55
  10. 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.

     

     

    Spoiler

    char_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

    • Metin2 Dev 9
    • Good 1
    • Love 45
  11. 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?

  12. 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.

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