8 mesaje
  • Mesaje: 6
  • Reacții: 1
  • Mesaje utile: 1
  • Medalii

    *Problemă/Întrebare:
    Hi, How can I disable animation for mounts when the horse level is under 11? (Attack system like horse)

    I already make the server side change, so when is under 11 level -> no damage. But the animation still running.
    Rezolvat de winkiller » 21 Sep 2025, 01:23

    🔥 Hai pe Discord! - Chat activ și support direct

    Te așteptăm și pe serverul de Discord - aici ne-am strâns toată comunitatea de Metin2 din România.

    Alătură-te acum!
    1300+ de membri activi!
    Robot Discord
    Roboțelu'
    Anunț
    Robot Robot
  • Mesaje: 122
  • Reacții: 0
  • Mesaje utile: 0
  • Status: Sunt doar un Bot :)
  • Regat: Shinsoo
  • Contact:

    Medalii

    Avatar utilizator
    Robot
    Robot

    Mesaj de Uriel »

    Salut, winkiller!

    Îți recomand câteva link-uri utile care te pot ajuta să rezolvi problema mai rapid:

    - Alte probleme rezolvate
    - Fixuri Metin2
    - Tutoriale
    - Cum resetez parola MySQL
    - Compilare sursă Metin2
    - Lista FreeBSD pentru compilare


    Și dacă vrei ajutor direct, te așteptăm pe serverul nostru de Discord — chat activ, suport live și o comunitate faină gata să te ajute! Pentru a intra pe serverul de Discord: Click aici
  • Mesaje: 25
  • Reacții: 21
  • Mesaje utile: 5
  • Status: Pierd vremea ^.^
  • Regat: Jinno
  • Medalii

    Mesaj de Dintisor »

    You’ve already blocked damage below level 11, but the horse attack animation is still playing, and you want to completely disable it.

    In Metin2, this isn’t only about damage – the input that triggers the attack motion/animation must also be controlled. You have a few options:

    🔹 1. In the client source (the cleanest method)

    The horse attack is linked to horse.cpp (or horse_riding.cpp) + GameCharacter.cpp.

    When the player presses the horse attack key, the client sends the command to start the attack motion.

    You can add a simple check: if horse level < 11 → don’t send the animation command.

    Example (simplified pseudo-code):

    if (pHorse->GetLevel() < 11)
    return; // block the animation


    This way, the animation never starts.

    🔹 2. In the server source

    You already blocked damage on the server.
    If you also want to block the animation server-side, you could send back a motion cancel packet when the horse is under level 11. The downside: the animation will start and then stop abruptly, which doesn’t look very good.

    🔹 3. Quick workaround (hacky method)

    In horse_skill_proto or skill_proto, you can set the horse attack animation to empty for levels below 11 (so there’s no motion). But this complicates your DB and makes it harder to manage level differences.

    ✅ Best recommendation: put the condition directly in the client (in the file that processes the horse attack input). This way, the animation won’t even start.
    Administrator Administrator
  • Mesaje: 3449
  • Reacții: 48420
  • Mesaje utile: 29
  • Status: Pe aici.. 🤠
  • Server: Saga2 - Soon
  • Regat: Jinno
  • [ID Discord]
  • Contact:
    Avatar utilizator
    Administrator
    Administrator

    Mesaj de [HF]White »

    You mean skills?

    Look in char_horse.cpp for:
    Code:
    bool CHARACTER::CanUseHorseSkill()
    { 
    	return (IsRiding() && GetHorseGrade() == 3); 
    }
    And edit it as you like.
    Te asteptam si pe serverul de Discord :p - aici ne-am strans toata comunitatea de Metin2 din Romania.
    Link: https://discord.gg/jWxeDSf7HP

    Suntem peste 1700 membri! - Avem chat activ zilnic, support, cereri, resurse. :D :ymcowboy:




    See full signature
  • Mesaje: 6
  • Reacții: 1
  • Mesaje utile: 1
  • Medalii

    malý zub scrie: You’ve already blocked damage below level 11, but the horse attack animation is still playing, and you want to completely disable it.

    In Metin2, this isn’t only about damage – the input that triggers the attack motion/animation must also be controlled. You have a few options:

    🔹 1. In the client source (the cleanest method)

    The horse attack is linked to horse.cpp (or horse_riding.cpp) + GameCharacter.cpp.

    When the player presses the horse attack key, the client sends the command to start the attack motion.

    You can add a simple check: if horse level < 11 → don’t send the animation command.

    Example (simplified pseudo-code):

    if (pHorse->GetLevel() < 11)
    return; // block the animation


    This way, the animation never starts.

    🔹 2. In the server source

    You already blocked damage on the server.
    If you also want to block the animation server-side, you could send back a motion cancel packet when the horse is under level 11. The downside: the animation will start and then stop abruptly, which doesn’t look very good.

    🔹 3. Quick workaround (hacky method)

    In horse_skill_proto or skill_proto, you can set the horse attack animation to empty for levels below 11 (so there’s no motion). But this complicates your DB and makes it harder to manage level differences.

    ✅ Best recommendation: put the condition directly in the client (in the file that processes the horse attack input). This way, the animation won’t even start.
    On the server side I already do it. But the animation doesnt look good as you say. I want to disable it on the client side, but in InstanceBase.cpp there is no HorseLevel... There is only getlevel but the value is base on mob Vnum... Start like this:

    UINT CInstanceBase::SHORSE::GetLevel()
    {
    if (m_pkActor)
    {

    DWORD mount = m_pkActor->GetRace();
    switch (mount)
    {
    case 20101:
    case 20102:
    case 20103:
    return 1;
    case 20104:
    case 20105:
    case 20106:
    return 2;
    case 20107:
    case 20108:


    So now I am trying to send new packet with horse level.
  • Mesaje: 6
  • Reacții: 1
  • Mesaje utile: 1
  • Medalii

    [HF]White scrie: You mean skills?

    Look in char_horse.cpp for:
    Code:
    bool CHARACTER::CanUseHorseSkill()
    { 
    	return (IsRiding() && GetHorseGrade() == 3); 
    }
    And edit it as you like.
    I meen only animation on mount when attacking with horse level under 11.
    Administrator Administrator
  • Mesaje: 3449
  • Reacții: 48420
  • Mesaje utile: 29
  • Status: Pe aici.. 🤠
  • Server: Saga2 - Soon
  • Regat: Jinno
  • [ID Discord]
  • Contact:
    Avatar utilizator
    Administrator
    Administrator

    Mesaj de [HF]White »

    winkiller scrie:
    [HF]White scrie: You mean skills?

    Look in char_horse.cpp for:
    Code:
    bool CHARACTER::CanUseHorseSkill()
    { 
    	return (IsRiding() && GetHorseGrade() == 3); 
    }
    And edit it as you like.
    I meen only animation on mount when attacking with horse level under 11.
    Do this but in reverse:
    ataca-toate-mount-urile-t1076.html

    This is default UINT CInstanceBase::SHORSE::GetLevel():
    Code:
    UINT CInstanceBase::SHORSE::GetLevel()
    {
    	if (m_pkActor)
    	{
    		DWORD mount = m_pkActor->GetRace();
    		switch (mount)
    		{
    			case 20101:
    			case 20102:
    			case 20103:
    				return 1;
    			case 20104:
    			case 20105:
    			case 20106:
    				return 2;
    			case 20107:
    			case 20108:
    			case 20109:
    			case 20110:
    			case 20111:
    			case 20112: 
    			case 20113: 
    			case 20114:
    			case 20115:
    			case 20116:
    			case 20117:
    			case 20118:
    			case 20120:
    			case 20121:
    			case 20122:
    			case 20123:
    			case 20124:
    			case 20125:
    			case 20233: 
    			case 20234:
    			case 20235:
    			case 20236:
    			case 20237:
    			case 20238:
    			case 20239:
    			case 20240:
    			case 20241:
    			case 20242:
    			case 20243:
    			case 20244:
    			case 20245:
    			case 20246:
    			case 20247:
    			case 20248:
    			case 20249:
    				return 3;
    			case 20119:
    			case 20219:
    			case 20220:
    			case 20221:
    			case 20222:
    				return 2;
    		}
    
    
    		{
    			if ((20205 <= mount &&  20208 >= mount) ||
    				(20214 == mount) || (20217 == mount)	
    				)
    				return 2;
    
    
    			if ((20209 <= mount &&  20212 >= mount) || 
    				(20215 == mount) || (20218 == mount) ||	
    				(20220 == mount)
    				)
    				return 3;
    		}
    	}
    	return 0;
    }
    
    
    Te asteptam si pe serverul de Discord :p - aici ne-am strans toata comunitatea de Metin2 din Romania.
    Link: https://discord.gg/jWxeDSf7HP

    Suntem peste 1700 membri! - Avem chat activ zilnic, support, cereri, resurse. :D :ymcowboy:




    See full signature
  • Mesaje: 6
  • Reacții: 1
  • Mesaje utile: 1
  • Medalii

    That's not work because getLevel return only level on specific mount vnum. But I figure it by myself. I am sending new packet to client with horse level.
    I will upload how I did it.:

    Server side:
    Packet.h:
    Search:
    Code:
    HEADER_GC_AUTH_SUCCESS_OPENID	= 154,
    Add:
    Code:
    HEADER_GC_HORSE_LEVEL			= 160,


    Search:
    Code:
    #pragma pack()
    Add over:
    Code:
    typedef struct SPacketHorseLevel
    {
        BYTE header;
        BYTE level;
    } TPacketHorseLevel;
    packet_info.cpp:


    Search:
    Code:
    Set(HEADER_CG_STATE_CHECKER, sizeof(BYTE), "ServerStateCheck", false);
    Add under:
    Code:
    Set(HEADER_GC_HORSE_LEVEL, sizeof(TPacketHorseLevel), "HorseLevel", false);


    char.cpp:
    Search:
    Code:
    void CHARACTER::MountVnum(DWORD vnum) {..}
    Add under:
    Code:
    void CHARACTER::SendHorseLevel()
    {
        if (!GetDesc())
            return;
    
        TPacketHorseLevel p;
        p.header = HEADER_GC_HORSE_LEVEL;
        p.level  = GetHorseLevel(); // existující metoda, co vrací horse level
    
        GetDesc()->Packet(&p, sizeof(p));
    }


    char_horse.cpp
    Modify this function like this:
    Code:
    void CHARACTER::SetHorseLevel(int iLevel)
    {
    	CHorseRider::SetHorseLevel(iLevel);
    	SetSkillLevel(SKILL_HORSE, GetHorseLevel());
    	SendHorseLevel();
    }


    input_login.cpp:
    At the end of this function:
    Code:
    void CInputLogin::Entergame(LPDESC d, const char * data)
    add before }:
    Code:
    ch->SendHorseLevel();


    Client-side:
    Packet.h:
    Search:
    Code:
    HEADER_GC_AUTH_SUCCESS_OPENID	= 154,
    Add:
    Code:
    HEADER_GC_HORSE_LEVEL			= 160,


    Search:
    Code:
    #pragma pack()
    Add over:
    Code:
    typedef struct SPacketHorseLevel
    {
        BYTE header;
        BYTE level;
    } TPacketHorseLevel;


    PythonNetworkStreamPhaseGame.cpp:
    Search:
    Code:
    default:
    	ret = RecvDefaultPacket(header);
    	break;
    }
    Add before:
    Code:
    case HEADER_GC_HORSE_LEVEL:
    	ret = RecvHorseLevel();
    	break;


    Add this on the end:
    Code:
    bool CPythonNetworkStream::RecvHorseLevel()
    {
    	TPacketHorseLevel kPacket;
    
    	if (!Recv(sizeof(kPacket), &kPacket))
    		return false;
    
    	CPythonPlayer::Instance().SetHorseLevel(kPacket.level);
    
    	return true;
    }


    PythonNetworkStream.h:
    Add:
    Code:
    bool RecvHorseLevel();
    PythonPlayer.h:
    add in public:
    Code:
    void SetHorseLevel(int level) { m_iHorseLevel = level; }
    int  GetHorseLevel() const { return m_iHorseLevel; }


    PythonPlayer.cpp:
    In this funcs:
    Code:
    void CPythonPlayer::Clear()
    and
    Code:
    CPythonPlayer::CPythonPlayer(void)
    add:
    m_iHorseLevel = 0;

    instancebase.cpp:
    And modify start the function GetLevel like this:
    Code:
    UINT CInstanceBase::SHORSE::GetLevel()
    {
    	if (m_pkActor)
    	{
    		 int horseLevel = CPythonPlayer::Instance().GetHorseLevel();
            if (horseLevel >= 11 && horseLevel < 20)
                return 2;
            else if (horseLevel >= 21)
                return 3;

    🔥 Hai pe Discord! - Chat activ și support direct

    Te așteptăm și pe serverul de Discord - aici ne-am strâns toată comunitatea de Metin2 din România.

    Alătură-te acum!
    1300+ de membri activi!
    Robot Discord
    Roboțelu'
    Anunț
    Închis

    Înapoi la “Probleme rezolvate”

    Informații

    Utilizatori ce navighează pe acest forum: Niciun utilizator înregistrat și 1 vizitator

    Discord ID copiat: