EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Server Code Submissions (https://www.eqemulator.org/forums/forumdisplay.php?f=669)
-   -   Break bind wound while sitting (https://www.eqemulator.org/forums/showthread.php?t=34541)

game 12-01-2011 01:05 AM

Break bind wound while sitting
 
Fixed by That of The Sleeper dev team
Enjoy


Code:

bool Client::BindWound(Mob* bindmob, bool start, bool fail){
    EQApplicationPacket* outapp = 0;
    if(!fail) {
        outapp = new EQApplicationPacket(OP_Bind_Wound, sizeof(BindWound_Struct));
        BindWound_Struct* bind_out = (BindWound_Struct*) outapp->pBuffer;
        // Start bind
        if(!bindwound_timer.Enabled()) {
            //make sure we actually have a bandage... and consume it.
            sint16 bslot = m_inv.HasItemByUse(ItemTypeBandage, 1, invWhereWorn|invWherePersonal);
            if(bslot == SLOT_INVALID) {
                bind_out->type = 3;
                QueuePacket(outapp);
                bind_out->type = 7;    //this is the wrong message, dont know the right one.
                QueuePacket(outapp);
                return(true);
            }
            DeleteItemInInventory(bslot, 1, true);    //do we need client update?

            // start complete timer
            bindwound_timer.Start(10000);
            bindwound_target = bindmob;

            // Send client unlock
            bind_out->type = 3;
            QueuePacket(outapp);
            bind_out->type = 0;
            // Client Unlocked
            if(!bindmob)
            {
                // send "bindmob dead" to client
                bind_out->type = 4;
                QueuePacket(outapp);
                bind_out->type = 0;
                bindwound_timer.Disable();
                bindwound_target = 0;
     
             
            }
            else {
                // send bindmob "stand still"
                if(!bindmob->IsAIControlled() && bindmob != this ) {
                    bind_out->type = 2; // ?
                    //bind_out->type = 3; // ?
                    bind_out->to = GetID(); // ?
                    bindmob->CastToClient()->QueuePacket(outapp);
                    bind_out->type = 0;
                    bind_out->to = 0;
                }
                else if (bindmob->IsAIControlled() && bindmob != this ){
                    ; // Tell IPC to stand still?
                }
                else {
                    ; // Binding self
                }
            }
        } else {
        // finish bind
            // disable complete timer
            bindwound_timer.Disable();
            bindwound_target = 0;
            if(!bindmob){
                    // send "bindmob gone" to client
                    bind_out->type = 5; // not in zone
                    QueuePacket(outapp);
                    bind_out->type = 0;
            }

            else {
                if (!GetFeigned() && (bindmob->DistNoRoot(*this) <= 400)) {
                    // send bindmob bind done
                    if(!bindmob->IsAIControlled() && bindmob != this ) {

                    }
                    else if(bindmob->IsAIControlled() && bindmob != this ) {
                    // Tell IPC to resume??
                    }
                    else {
                    // Binding self
                    }
                    // Send client bind done

                    //this is taken care of on start of bind, not finish now, and is improved
                    //DeleteItemInInventory(m_inv.HasItem(13009, 1), 1, true);

                    bind_out->type = 1; // Done
                    QueuePacket(outapp);
                    bind_out->type = 0;
                    CheckIncreaseSkill(BIND_WOUND, NULL, 5);

                    int max_percent = 50 + 10 * GetAA(aaFirstAid);

                    if(GetClass() == MONK && GetSkill(BIND_WOUND) > 200) {
                        max_percent = 70 + 10 * GetAA(aaFirstAid);
                    }

                    int max_hp = bindmob->GetMaxHP()*max_percent/100;

                    // send bindmob new hp's
                    if (bindmob->GetHP() < bindmob->GetMaxHP() && bindmob->GetHP() <= (max_hp)-1){
                        // 0.120 per skill point, 0.60 per skill level, minimum 3 max 30
                        int bindhps = 3;


                        if (GetSkill(BIND_WOUND) > 200) {
                            bindhps += GetSkill(BIND_WOUND)*4/10;
                        } else if (GetSkill(BIND_WOUND) >= 10) {
                            bindhps += GetSkill(BIND_WOUND)/4;
                        }

                        //Implementation of aaMithanielsBinding is a guess (the multiplier)
                        switch (GetAA(aaBandageWound))
                        {
                            case 1:
                                bindhps = bindhps * (110 + 20*GetAA(aaMithanielsBinding)) / 100;
                                break;
                            case 2:
                                bindhps = bindhps * (125 + 20*GetAA(aaMithanielsBinding)) / 100;
                                break;
                            case 3:
                                bindhps = bindhps * (150 + 20*GetAA(aaMithanielsBinding)) / 100;
                                break;
                        }

                        //if the bind takes them above the max bindable
                        //cap it at that value. Dont know if live does it this way
                        //but it makes sense to me.
                        int chp = bindmob->GetHP() + bindhps;
                        if(chp > max_hp)
                            chp = max_hp;

                        bindmob->SetHP(chp);
                        bindmob->SendHPUpdate();
                    }
                    else
                    {
                        //I dont have the real, live
                        Message(15, "You cannot bind wounds above %d%% hitpoints.", max_percent);
                        if(bindmob->IsClient())
                            bindmob->CastToClient()->Message(15, "You cannot have your wounds bound above %d%% hitpoints.", max_percent);
                        // Too many hp message goes here.
                    }
                }
                else {
                    // Send client bind failed
                    if(bindmob != this)
                        bind_out->type = 6; // They moved
                    else
                        bind_out->type = 7; // Bandager moved

                    QueuePacket(outapp);
                    bind_out->type = 0;
                }
            }
        }
    }
 
    else if (bindwound_timer.Enabled()) {
        // You moved
        outapp = new EQApplicationPacket(OP_Bind_Wound, sizeof(BindWound_Struct));
        BindWound_Struct* bind_out = (BindWound_Struct*) outapp->pBuffer;
        bindwound_timer.Disable();
        bindwound_target = 0;
        bind_out->type = 7;
        QueuePacket(outapp);
        bind_out->type = 3;
        QueuePacket(outapp);
    }
    //Break bind wound while sitting
    if (bindwound_timer.Enabled() && IsSitting() == 1)
    {
        if(bindmob->IsClient());
        {
                        Message(15, "You can not bind wounds in that position.");
                        bindwound_timer.Disable();
                        bindwound_target = 0;
                       
        }
    }
                 
    else
                            //(bindwound_timer.Enabled() && IsSitting() != 1)
    {
        safe_delete(outapp);
        return true;
        Stand();
    }
                   
    safe_delete(outapp);
    return true;

 
}


trevius 12-01-2011 04:08 AM

Thanks for the submission, but would you mind posting a diff so we can easily see what it is that you changed exactly?

Here is some information from one of the sticky posts which is good for anyone posting submissions:
http://www.eqemulator.org/forums/showthread.php?t=26351

game 12-01-2011 10:31 AM

Here is the change itself:

Code:

//Break bind wound while sitting
    if (bindwound_timer.Enabled() && IsSitting() == 1)
    {
        if(bindmob->IsClient());
        {
                        Message(15, "You can not bind wounds in that position.");
                        bindwound_timer.Disable();
                        bindwound_target = 0;
                       
        }
    }
                 
    else
                            //(bindwound_timer.Enabled() && IsSitting() != 1)
    {
        safe_delete(outapp);
        return true;
        Stand();
    }

I have marked where the the change is added with hashes

Code:

bool Client::BindWound(Mob* bindmob, bool start, bool fail){
    EQApplicationPacket* outapp = 0;
    if(!fail) {
        outapp = new EQApplicationPacket(OP_Bind_Wound, sizeof(BindWound_Struct));
        BindWound_Struct* bind_out = (BindWound_Struct*) outapp->pBuffer;
        // Start bind
        if(!bindwound_timer.Enabled()) {
            //make sure we actually have a bandage... and consume it.
            sint16 bslot = m_inv.HasItemByUse(ItemTypeBandage, 1, invWhereWorn|invWherePersonal);
            if(bslot == SLOT_INVALID) {
                bind_out->type = 3;
                QueuePacket(outapp);
                bind_out->type = 7;    //this is the wrong message, dont know the right one.
                QueuePacket(outapp);
                return(true);
            }
            DeleteItemInInventory(bslot, 1, true);    //do we need client update?

            // start complete timer
            bindwound_timer.Start(10000);
            bindwound_target = bindmob;

            // Send client unlock
            bind_out->type = 3;
            QueuePacket(outapp);
            bind_out->type = 0;
            // Client Unlocked
            if(!bindmob)
            {
                // send "bindmob dead" to client
                bind_out->type = 4;
                QueuePacket(outapp);
                bind_out->type = 0;
                bindwound_timer.Disable();
                bindwound_target = 0;
     
             
            }
            else {
                // send bindmob "stand still"
                if(!bindmob->IsAIControlled() && bindmob != this ) {
                    bind_out->type = 2; // ?
                    //bind_out->type = 3; // ?
                    bind_out->to = GetID(); // ?
                    bindmob->CastToClient()->QueuePacket(outapp);
                    bind_out->type = 0;
                    bind_out->to = 0;
                }
                else if (bindmob->IsAIControlled() && bindmob != this ){
                    ; // Tell IPC to stand still?
                }
                else {
                    ; // Binding self
                }
            }
        } else {
        // finish bind
            // disable complete timer
            bindwound_timer.Disable();
            bindwound_target = 0;
            if(!bindmob){
                    // send "bindmob gone" to client
                    bind_out->type = 5; // not in zone
                    QueuePacket(outapp);
                    bind_out->type = 0;
            }

            else {
                if (!GetFeigned() && (bindmob->DistNoRoot(*this) <= 400)) {
                    // send bindmob bind done
                    if(!bindmob->IsAIControlled() && bindmob != this ) {

                    }
                    else if(bindmob->IsAIControlled() && bindmob != this ) {
                    // Tell IPC to resume??
                    }
                    else {
                    // Binding self
                    }
                    // Send client bind done

                    //this is taken care of on start of bind, not finish now, and is improved
                    //DeleteItemInInventory(m_inv.HasItem(13009, 1), 1, true);

                    bind_out->type = 1; // Done
                    QueuePacket(outapp);
                    bind_out->type = 0;
                    CheckIncreaseSkill(BIND_WOUND, NULL, 5);

                    int max_percent = 50 + 10 * GetAA(aaFirstAid);

                    if(GetClass() == MONK && GetSkill(BIND_WOUND) > 200) {
                        max_percent = 70 + 10 * GetAA(aaFirstAid);
                    }

                    int max_hp = bindmob->GetMaxHP()*max_percent/100;

                    // send bindmob new hp's
                    if (bindmob->GetHP() < bindmob->GetMaxHP() && bindmob->GetHP() <= (max_hp)-1){
                        // 0.120 per skill point, 0.60 per skill level, minimum 3 max 30
                        int bindhps = 3;


                        if (GetSkill(BIND_WOUND) > 200) {
                            bindhps += GetSkill(BIND_WOUND)*4/10;
                        } else if (GetSkill(BIND_WOUND) >= 10) {
                            bindhps += GetSkill(BIND_WOUND)/4;
                        }

                        //Implementation of aaMithanielsBinding is a guess (the multiplier)
                        switch (GetAA(aaBandageWound))
                        {
                            case 1:
                                bindhps = bindhps * (110 + 20*GetAA(aaMithanielsBinding)) / 100;
                                break;
                            case 2:
                                bindhps = bindhps * (125 + 20*GetAA(aaMithanielsBinding)) / 100;
                                break;
                            case 3:
                                bindhps = bindhps * (150 + 20*GetAA(aaMithanielsBinding)) / 100;
                                break;
                        }

                        //if the bind takes them above the max bindable
                        //cap it at that value. Dont know if live does it this way
                        //but it makes sense to me.
                        int chp = bindmob->GetHP() + bindhps;
                        if(chp > max_hp)
                            chp = max_hp;

                        bindmob->SetHP(chp);
                        bindmob->SendHPUpdate();
                    }
                    else
                    {
                        //I dont have the real, live
                        Message(15, "You cannot bind wounds above %d%% hitpoints.", max_percent);
                        if(bindmob->IsClient())
                            bindmob->CastToClient()->Message(15, "You cannot have your wounds bound above %d%% hitpoints.", max_percent);
                        // Too many hp message goes here.
                    }
                }
                else {
                    // Send client bind failed
                    if(bindmob != this)
                        bind_out->type = 6; // They moved
                    else
                        bind_out->type = 7; // Bandager moved

                    QueuePacket(outapp);
                    bind_out->type = 0;
                }
            }
        }
    }
 
    else if (bindwound_timer.Enabled()) {
        // You moved
        outapp = new EQApplicationPacket(OP_Bind_Wound, sizeof(BindWound_Struct));
        BindWound_Struct* bind_out = (BindWound_Struct*) outapp->pBuffer;
        bindwound_timer.Disable();
        bindwound_target = 0;
        bind_out->type = 7;
        QueuePacket(outapp);
        bind_out->type = 3;
        QueuePacket(outapp);
    }
############################################
############################################
#    //Break bind wound while sitting
#    if (bindwound_timer.Enabled() && IsSitting() == 1)
#    {
#        if(bindmob->IsClient());
#        {
#                      Message(15, "You can not bind wounds in that position.");
#                        bindwound_timer.Disable();
#                        bindwound_target = 0;
#                       
#        }
#    }
#                 
#    else
#                            //(bindwound_timer.Enabled() && IsSitting() != 1)
#    {
#        safe_delete(outapp);
#        return true;
#        Stand();
#    }
#############################################
#############################################                 
    safe_delete(outapp);
    return true;

 
}


trevius 12-02-2011 06:55 AM

Thanks for pointing out the changes that were made. That logic does not look correct to me, though.

For one thing, you have a return and then Stand():

Code:

    else
                            //(bindwound_timer.Enabled() && IsSitting() != 1)
    {
        safe_delete(outapp);
        return true;
        Stand();
    }

Also, the commented out line there could also be:
Code:

                            //(!bindwound_timer.Enabled() && IsSitting() == 1)
Another thing is that it should probably be moved to just after this:

Code:

    if(!fail) {
        outapp = new EQApplicationPacket(OP_Bind_Wound, sizeof(BindWound_Struct));
        BindWound_Struct* bind_out = (BindWound_Struct*) outapp->pBuffer;
        // Start bind
        if(!bindwound_timer.Enabled()) {

That way the check is made before consuming a bandage. Though that depends on if the client consumes the bandage on your screen even if you are sitting and click it.

Since I am pretty sure you have to be standing to use bind wound, you could probably just do this check so you make sure they aren't feigned or whatever as well:

Code:

if (GetAppearance() != eaStanding)
{
Message(15, "You can not bind wounds in that position.");
bindwound_target = 0;
safe_delete(outapp);
return false;
}

So, the whole function would look something like this, though this is untested:
Code:

bool Client::BindWound(Mob* bindmob, bool start, bool fail){
        EQApplicationPacket* outapp = 0;
        if(!fail) {
                outapp = new EQApplicationPacket(OP_Bind_Wound, sizeof(BindWound_Struct));
                BindWound_Struct* bind_out = (BindWound_Struct*) outapp->pBuffer;
                // Start bind
                if(!bindwound_timer.Enabled()) {
                        // Verify they are standing when they attempt to Bind Wounds
                        if (GetAppearance() != eaStanding)
                        {
                                Message(15, "You can not bind wounds in that position.");
                                bindwound_target = 0;
                                safe_delete(outapp);
                                return false;
                        }

                        //make sure we actually have a bandage... and consume it.
                        sint16 bslot = m_inv.HasItemByUse(ItemTypeBandage, 1, invWhereWorn|invWherePersonal);
                        if(bslot == SLOT_INVALID) {
                                bind_out->type = 3;
                                QueuePacket(outapp);
                                bind_out->type = 7;        //this is the wrong message, dont know the right one.
                                QueuePacket(outapp);
                                return(true);
                        }
                        DeleteItemInInventory(bslot, 1, true);        //do we need client update?

                        // start complete timer
                        bindwound_timer.Start(10000);
                        bindwound_target = bindmob;

                        // Send client unlock
                        bind_out->type = 3;
                        QueuePacket(outapp);
                        bind_out->type = 0;
                        // Client Unlocked
                        if(!bindmob)
                        {
                                // send "bindmob dead" to client
                                bind_out->type = 4;
                                QueuePacket(outapp);
                                bind_out->type = 0;
                                bindwound_timer.Disable();
                                bindwound_target = 0;
         
                         
                        }
                        else {
                                // send bindmob "stand still"
                                if(!bindmob->IsAIControlled() && bindmob != this ) {
                                        bind_out->type = 2; // ?
                                        //bind_out->type = 3; // ?
                                        bind_out->to = GetID(); // ?
                                        bindmob->CastToClient()->QueuePacket(outapp);
                                        bind_out->type = 0;
                                        bind_out->to = 0;
                                }
                                else if (bindmob->IsAIControlled() && bindmob != this ){
                                        ; // Tell IPC to stand still?
                                }
                                else {
                                        ; // Binding self
                                }
                        }
                } else {
                // finish bind
                        // disable complete timer
                        bindwound_timer.Disable();
                        bindwound_target = 0;
                        if(!bindmob){
                                        // send "bindmob gone" to client
                                        bind_out->type = 5; // not in zone
                                        QueuePacket(outapp);
                                        bind_out->type = 0;
                        }

                        else {
                                if (!GetFeigned() && (bindmob->DistNoRoot(*this) <= 400)) {
                                        // send bindmob bind done
                                        if(!bindmob->IsAIControlled() && bindmob != this ) {

                                        }
                                        else if(bindmob->IsAIControlled() && bindmob != this ) {
                                        // Tell IPC to resume??
                                        }
                                        else {
                                        // Binding self
                                        }
                                        // Send client bind done

                                        //this is taken care of on start of bind, not finish now, and is improved
                                        //DeleteItemInInventory(m_inv.HasItem(13009, 1), 1, true);

                                        bind_out->type = 1; // Done
                                        QueuePacket(outapp);
                                        bind_out->type = 0;
                                        CheckIncreaseSkill(BIND_WOUND, NULL, 5);

                                        int max_percent = 50 + 10 * GetAA(aaFirstAid);

                                        if(GetClass() == MONK && GetSkill(BIND_WOUND) > 200) {
                                                max_percent = 70 + 10 * GetAA(aaFirstAid);
                                        }

                                        int max_hp = bindmob->GetMaxHP()*max_percent/100;

                                        // send bindmob new hp's
                                        if (bindmob->GetHP() < bindmob->GetMaxHP() && bindmob->GetHP() <= (max_hp)-1){
                                                // 0.120 per skill point, 0.60 per skill level, minimum 3 max 30
                                                int bindhps = 3;


                                                if (GetSkill(BIND_WOUND) > 200) {
                                                        bindhps += GetSkill(BIND_WOUND)*4/10;
                                                } else if (GetSkill(BIND_WOUND) >= 10) {
                                                        bindhps += GetSkill(BIND_WOUND)/4;
                                                }

                                                //Implementation of aaMithanielsBinding is a guess (the multiplier)
                                                switch (GetAA(aaBandageWound))
                                                {
                                                        case 1:
                                                                bindhps = bindhps * (110 + 20*GetAA(aaMithanielsBinding)) / 100;
                                                                break;
                                                        case 2:
                                                                bindhps = bindhps * (125 + 20*GetAA(aaMithanielsBinding)) / 100;
                                                                break;
                                                        case 3:
                                                                bindhps = bindhps * (150 + 20*GetAA(aaMithanielsBinding)) / 100;
                                                                break;
                                                }

                                                //if the bind takes them above the max bindable
                                                //cap it at that value. Dont know if live does it this way
                                                //but it makes sense to me.
                                                int chp = bindmob->GetHP() + bindhps;
                                                if(chp > max_hp)
                                                        chp = max_hp;

                                                bindmob->SetHP(chp);
                                                bindmob->SendHPUpdate();
                                        }
                                        else
                                        {
                                                //I dont have the real, live
                                                Message(15, "You cannot bind wounds above %d%% hitpoints.", max_percent);
                                                if(bindmob->IsClient())
                                                        bindmob->CastToClient()->Message(15, "You cannot have your wounds bound above %d%% hitpoints.", max_percent);
                                                // Too many hp message goes here.
                                        }
                                }
                                else {
                                        // Send client bind failed
                                        if(bindmob != this)
                                                bind_out->type = 6; // They moved
                                        else
                                                bind_out->type = 7; // Bandager moved

                                        QueuePacket(outapp);
                                        bind_out->type = 0;
                                }
                        }
                }
        }
        else if (bindwound_timer.Enabled()) {
                // You moved
                outapp = new EQApplicationPacket(OP_Bind_Wound, sizeof(BindWound_Struct));
                BindWound_Struct* bind_out = (BindWound_Struct*) outapp->pBuffer;
                bindwound_timer.Disable();
                bindwound_target = 0;
                bind_out->type = 7;
                QueuePacket(outapp);
                bind_out->type = 3;
                QueuePacket(outapp);
        }                         

        safe_delete(outapp);
        return true;

}


game 12-02-2011 05:09 PM

I will give this a test later this weekend and let you know :)

game 12-05-2011 11:13 AM

Havent had the chance to test it yet but it will be done and results dropped off here.

game 12-10-2011 02:21 PM

Tested, no bueno, it breaks your ability to sit after attempting to bind wound while sitting.

game 12-16-2011 04:10 PM

Original submitted fix still works quite well, only issue is it eats a bandage when they try to do it sitting - either way we feel they deserve to lose it for trying to get OP health regen :)


All times are GMT -4. The time now is 03:13 PM.

Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.