PDA

View Full Version : Break bind wound while sitting


game
12-01-2011, 01:05 AM
Fixed by That of The Sleeper dev team
Enjoy


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:

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

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():

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

Also, the commented out line there could also be:
//(!bindwound_timer.Enabled() && IsSitting() == 1)

Another thing is that it should probably be moved to just after this:

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:

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