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