From fb308eaa01f4555d3433b21beed01980ab891c6d Mon Sep 17 00:00:00 2001 From: Uleat Date: Sat, 3 Sep 2016 17:08:48 -0400 Subject: [PATCH] Rule-based update to 'Bind Wound' behavior --- changelog.txt | 4 + common/ruletypes.h | 2 + .../2016_09_03_old_bind_wound_rule.sql | 1 + zone/client.cpp | 148 ++++++++++++------ 4 files changed, 111 insertions(+), 44 deletions(-) create mode 100644 utils/sql/git/optional/2016_09_03_old_bind_wound_rule.sql diff --git a/changelog.txt b/changelog.txt index 2aa32e8ac..b2d7c7b05 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,9 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 09/03/2016 == +Uleat: Changed 'Bind Wound' behavior to match the best references that I could find for post-2004 era. + Note: If you wish to retain the old method, source in the optional '2016_09_03_old_bind_wound_rule.sql' script file. + == 08/27/2016 == Kinglykrab: Added optional IP-based account exemptions. - To use this system simply set World:EnableIPExemptions to true and create an entry in the ip_exemptions table. diff --git a/common/ruletypes.h b/common/ruletypes.h index f1898a559..7837834f9 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -145,6 +145,8 @@ RULE_BOOL(Character, UseStackablePickPocketing, true) // Allows stackable pickpo RULE_BOOL(Character, EnableAvoidanceCap, false) RULE_INT(Character, AvoidanceCap, 750) // 750 Is a pretty good value, seen people dodge all attacks beyond 1,000 Avoidance RULE_BOOL(Character, AllowMQTarget, false) // Disables putting players in the 'hackers' list for targeting beyond the clip plane or attempting to target something untargetable +RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound behavior + RULE_CATEGORY_END() RULE_CATEGORY(Mercs) diff --git a/utils/sql/git/optional/2016_09_03_old_bind_wound_rule.sql b/utils/sql/git/optional/2016_09_03_old_bind_wound_rule.sql new file mode 100644 index 000000000..87791d59b --- /dev/null +++ b/utils/sql/git/optional/2016_09_03_old_bind_wound_rule.sql @@ -0,0 +1 @@ +INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Character:UseOldBindWound', 'true', 'Uses the original bind wound behavior'); diff --git a/zone/client.cpp b/zone/client.cpp index 59998bfdb..3a7b60eb5 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2655,60 +2655,120 @@ bool Client::BindWound(Mob *bindmob, bool start, bool fail) bind_out->type = 0; CheckIncreaseSkill(EQEmu::skills::SkillBindWound, nullptr, 5); - int maxHPBonus = spellbonuses.MaxBindWound + itembonuses.MaxBindWound + - aabonuses.MaxBindWound; + if (RuleB(Character, UseOldBindWound)) { + int maxHPBonus = spellbonuses.MaxBindWound + itembonuses.MaxBindWound + + aabonuses.MaxBindWound; - int max_percent = 50 + 10 * maxHPBonus; + int max_percent = 50 + maxHPBonus; - if (GetClass() == MONK && GetSkill(EQEmu::skills::SkillBindWound) > 200) { - max_percent = 70 + 10 * maxHPBonus; - } - - max_percent = mod_bindwound_percent(max_percent, bindmob); - - 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(EQEmu::skills::SkillBindWound) > 200) { - bindhps += GetSkill(EQEmu::skills::SkillBindWound) * 4 / 10; - } - else if (GetSkill(EQEmu::skills::SkillBindWound) >= 10) { - bindhps += GetSkill(EQEmu::skills::SkillBindWound) / 4; + if (GetClass() == MONK && GetSkill(EQEmu::skills::SkillBindWound) > 200) { + max_percent = 70 + maxHPBonus; } - // Implementation of aaMithanielsBinding is a guess (the multiplier) - int bindBonus = spellbonuses.BindWound + itembonuses.BindWound + + max_percent = mod_bindwound_percent(max_percent, bindmob); + + 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(EQEmu::skills::SkillBindWound) > 200) { + bindhps += GetSkill(EQEmu::skills::SkillBindWound) * 4 / 10; + } + else if (GetSkill(EQEmu::skills::SkillBindWound) >= 10) { + bindhps += GetSkill(EQEmu::skills::SkillBindWound) / 4; + } + + // Implementation of aaMithanielsBinding is a guess (the multiplier) + int bindBonus = spellbonuses.BindWound + itembonuses.BindWound + aabonuses.BindWound; - bindhps += bindhps * bindBonus / 100; + bindhps += bindhps * bindBonus / 100; - bindhps = mod_bindwound_hp(bindhps, bindmob); + bindhps = mod_bindwound_hp(bindhps, bindmob); - // 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; + // 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 != this && bindmob->IsClient()) - bindmob->CastToClient()->Message( - 15, - "You cannot have your wounds bound above %d%% hitpoints.", - max_percent); - // Too many hp message goes here. + 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 != this && bindmob->IsClient()) + bindmob->CastToClient()->Message( + 15, + "You cannot have your wounds bound above %d%% hitpoints.", + max_percent); + // Too many hp message goes here. + } } - } else { + else { + int percent_base = 50; + if (GetRawSkill(EQEmu::skills::SkillBindWound) > 200) { + if ((GetClass() == MONK) || (GetClass() == BEASTLORD)) + percent_base = 70; + else if ((GetLevel() > 50) && ((GetClass() == WARRIOR) || (GetClass() == ROGUE) || (GetClass() == CLERIC))) + percent_base = 70; + } + + int percent_bonus = 0; + if (percent_base >= 70) + percent_bonus = spellbonuses.MaxBindWound + itembonuses.MaxBindWound + aabonuses.MaxBindWound; + + int max_percent = percent_base + percent_bonus; + if (max_percent < 0) + max_percent = 0; + if (max_percent > 100) + max_percent = 100; + + max_percent = mod_bindwound_percent(max_percent, bindmob); + + int max_hp = (bindmob->GetMaxHP() * max_percent) / 100; + if (max_hp > bindmob->GetMaxHP()) + max_hp = bindmob->GetMaxHP(); + + if (bindmob->GetHP() < bindmob->GetMaxHP() && bindmob->GetHP() < max_hp) { + int bindhps = 3; // base bind hp + if (percent_base >= 70) + bindhps = (GetSkill(EQEmu::skills::SkillBindWound) * 4) / 10; // 8:5 skill-to-hp ratio + else if (GetSkill(EQEmu::skills::SkillBindWound) >= 12) + bindhps = GetSkill(EQEmu::skills::SkillBindWound) / 4; // 4:1 skill-to-hp ratio + + int bonus_hp_percent = 0; + if (percent_base >= 70) + bonus_hp_percent = spellbonuses.BindWound + itembonuses.BindWound + aabonuses.BindWound; + + bindhps += (bindhps * bonus_hp_percent) / 100; + + if (bindhps < 3) + bindhps = 3; + + bindhps = mod_bindwound_hp(bindhps, bindmob); + + bindhps += bindmob->GetHP(); + if (bindhps > max_hp) + bindhps = max_hp; + + bindmob->SetHP(bindhps); + bindmob->SendHPUpdate(); + } + else { + Message(15, "You cannot bind wounds above %d%% hitpoints", max_percent); + if (bindmob != this && bindmob->IsClient()) + bindmob->CastToClient()->Message(15, "You cannot have your wounds bound above %d%% hitpoints", max_percent); + } + } + } + else { // Send client bind failed if (bindmob != this) bind_out->type = 6; // They moved