mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-15 04:11:30 +00:00
[Feature] Classic Taunt (Pre 2006) style of taunt (#3942)
* DRAFT - Classic Taunt (Pre 2006) style of taunt RULE: ClassicTauntSystem Completely seperate logic for each system. Could potentially be re-writte to be more inline but there are a good bit of minor differences. * Consolidate Logic Still needs in-game testing * Feedback Request * Updates per feedback
This commit is contained in:
parent
26693992b6
commit
14d4a2610f
@ -529,6 +529,8 @@ RULE_REAL(Combat, DefProcPerMinAgiContrib, 0.075, "How much agility contributes
|
||||
RULE_INT(Combat, NPCFlurryChance, 20, "Chance for NPC to flurry")
|
||||
RULE_BOOL(Combat, TauntOverLevel, 1, "Allows you to taunt NPC's over warriors level")
|
||||
RULE_INT(Combat, TauntOverAggro, 0, "+ amount over hate_top it will add before any bonus hate.")
|
||||
RULE_INT(Combat, TauntChanceBonus, 0, "Bonus to taunt chance")
|
||||
RULE_BOOL(Combat, ClassicTauntSystem, false, "Enable to use the pre 2006 taunt system.")
|
||||
RULE_REAL(Combat, TauntSkillFalloff, 0.33, "For every taunt skill point that's not maxed you lose this percentage chance to taunt")
|
||||
RULE_BOOL(Combat, EXPFromDmgShield, false, "Determine if damage from a damage shield counts for experience gain")
|
||||
RULE_INT(Combat, QuiverHasteCap, 1000, "Quiver haste cap 1000 on live for a while, currently 700 on live")
|
||||
|
||||
@ -2134,9 +2134,22 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
||||
}
|
||||
}
|
||||
|
||||
/* Classic Taunt Methodology
|
||||
* This is not how Sony did it. This is a guess that fits the very limited data available.
|
||||
* Low level players with maxed taunt for their level taunted about 50% on white cons.
|
||||
* A 65 ranger with 150 taunt skill (max) taunted about 50% on level 60 and under NPCs.
|
||||
* A 65 warrior with maxed taunt (230) was taunting around 50% on SSeru NPCs. */
|
||||
|
||||
/* Rashere in 2006: "your taunt skill was irrelevant if you were above level 60 and taunting
|
||||
* something that was also above level 60."
|
||||
* Also: "The chance to taunt an NPC higher level than yourself dropped off at double the rate
|
||||
* if you were above level 60 than if you were below level 60 making it very hard to taunt creature
|
||||
* higher level than yourself if you were above level 60."
|
||||
*
|
||||
* See http://www.elitegamerslounge.com/home/soearchive/viewtopic.php?t=81156 */
|
||||
void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool from_spell, int32 bonus_hate)
|
||||
{
|
||||
if (!who || DivineAura() || (!from_spell && !CombatRange(who))) {
|
||||
if (!who || DivineAura() || (!from_spell && !CombatRange(who)) || (IsNPC() && IsCharmed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2144,10 +2157,10 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool from_spell
|
||||
CastToClient()->CheckIncreaseSkill(EQ::skills::SkillTaunt, who, 10);
|
||||
}
|
||||
|
||||
Mob *hate_top = who->GetHateMost();
|
||||
|
||||
Mob *hate_top = who->GetHateMost();
|
||||
int level_difference = GetLevel() - who->GetLevel();
|
||||
bool success = false;
|
||||
bool success = false;
|
||||
int taunt_chance = 0;
|
||||
|
||||
// Support for how taunt worked pre 2000 on LIVE - Can not taunt NPC over your level.
|
||||
if (
|
||||
@ -2159,104 +2172,133 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool from_spell
|
||||
return;
|
||||
}
|
||||
|
||||
// All values used based on live parses after taunt was updated in 2006.
|
||||
if (
|
||||
(hate_top && hate_top->GetHPRatio() >= 20) ||
|
||||
!hate_top ||
|
||||
chance_bonus
|
||||
) {
|
||||
// SE_Taunt this is flat chance
|
||||
if (chance_bonus) {
|
||||
success = zone->random.Roll(chance_bonus);
|
||||
} else {
|
||||
float taunt_chance = 50.0f;
|
||||
|
||||
if (always_succeed) {
|
||||
taunt_chance = 101.0f;
|
||||
if (always_succeed) {
|
||||
taunt_chance = 100;
|
||||
}
|
||||
|
||||
// Modern Taunt
|
||||
if (!RuleB(Combat, ClassicTauntSystem)) {
|
||||
if (
|
||||
(hate_top && hate_top->GetHPRatio() >= 20) ||
|
||||
!hate_top ||
|
||||
chance_bonus
|
||||
) {
|
||||
if (chance_bonus) {
|
||||
taunt_chance = chance_bonus;
|
||||
} else {
|
||||
if (level_difference < 0) {
|
||||
taunt_chance += static_cast<float>(level_difference) * 3.0f;
|
||||
if (taunt_chance < 20) {
|
||||
taunt_chance = 20.0f;
|
||||
}
|
||||
} else {
|
||||
taunt_chance += static_cast<float>(level_difference) * 5.0f;
|
||||
if (taunt_chance > 65) {
|
||||
taunt_chance = 65.0f;
|
||||
}
|
||||
taunt_chance = 50;
|
||||
}
|
||||
} else {
|
||||
if (level_difference < 0) {
|
||||
taunt_chance += level_difference * 3;
|
||||
if (taunt_chance < 20) {
|
||||
taunt_chance = 20;
|
||||
}
|
||||
} else {
|
||||
taunt_chance += level_difference * 5;
|
||||
if (taunt_chance > 65) {
|
||||
taunt_chance = 65;
|
||||
}
|
||||
}
|
||||
|
||||
// TauntSkillFalloff rate is not based on any real data. Default of 33% gives a reasonable
|
||||
// result.
|
||||
if (IsClient() && !always_succeed) {
|
||||
taunt_chance -= (RuleR(Combat, TauntSkillFalloff) *
|
||||
(CastToClient()->MaxSkill(EQ::skills::SkillTaunt) -
|
||||
GetSkill(EQ::skills::SkillTaunt)));
|
||||
(CastToClient()->MaxSkill(EQ::skills::SkillTaunt) -
|
||||
GetSkill(EQ::skills::SkillTaunt)));
|
||||
}
|
||||
|
||||
if (taunt_chance < 1) {
|
||||
taunt_chance = 1.0f;
|
||||
taunt_chance = 1;
|
||||
}
|
||||
|
||||
taunt_chance /= 100.0f;
|
||||
success = taunt_chance > zone->random.Real(0, 1);
|
||||
|
||||
LogHate(
|
||||
"Taunter mob {} target npc {} taunt_chance [{}] success [{}] hate_top [{}]",
|
||||
GetMobDescription(),
|
||||
who->GetMobDescription(),
|
||||
taunt_chance,
|
||||
success ? "true" : "false",
|
||||
hate_top ? hate_top->GetMobDescription() : "not found"
|
||||
);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
if (hate_top && hate_top != this) {
|
||||
int64 new_hate = (
|
||||
(who->GetNPCHate(hate_top) - who->GetNPCHate(this)) +
|
||||
bonus_hate +
|
||||
RuleI(Combat, TauntOverAggro) +
|
||||
1
|
||||
);
|
||||
|
||||
LogHate(
|
||||
"Not Top Hate - Taunter [{}] Target [{}] Hated Top [{}] Hate Top Amt [{}] This Character Amt [{}] Bonus_Hate Amt [{}] TauntOverAggro Amt [{}] - Total [{}]",
|
||||
GetMobDescription(),
|
||||
who->GetMobDescription(),
|
||||
hate_top->GetMobDescription(),
|
||||
who->GetNPCHate(hate_top),
|
||||
who->GetNPCHate(this),
|
||||
bonus_hate,
|
||||
RuleI(Combat, TauntOverAggro),
|
||||
new_hate
|
||||
);
|
||||
|
||||
who->CastToNPC()->AddToHateList(this, new_hate);
|
||||
success = true;
|
||||
} else { // Classic Taunt
|
||||
if (GetLevel() >= 60 && level_difference < 0) {
|
||||
if (level_difference < -5) {
|
||||
taunt_chance = 0;
|
||||
} else if (level_difference == -5) {
|
||||
taunt_chance = 10;
|
||||
} else {
|
||||
who->CastToNPC()->AddToHateList(this, 12);
|
||||
}
|
||||
|
||||
if (who->CanTalk()) {
|
||||
who->SayString(SUCCESSFUL_TAUNT, GetCleanName());
|
||||
taunt_chance = 50 + level_difference * 10;
|
||||
}
|
||||
} else {
|
||||
MessageString(Chat::SpellFailure, FAILED_TAUNT);
|
||||
// this will make the skill difference between the tank classes actually affect success rates
|
||||
// but only for NPCs near the player's level. Mid to low blues will start to taunt at 50%
|
||||
// even with lower skill
|
||||
taunt_chance = 50 * GetSkill(EQ::skills::SkillTaunt) / (who->GetLevel() * 5 + 5);
|
||||
taunt_chance += level_difference * 5;
|
||||
|
||||
if (taunt_chance > 50) {
|
||||
taunt_chance = 50;
|
||||
} else if (taunt_chance < 10) {
|
||||
taunt_chance = 10;
|
||||
}
|
||||
}
|
||||
|
||||
// Taunt Chance Rule Bonus
|
||||
taunt_chance += RuleI(Combat, TauntChanceBonus);
|
||||
}
|
||||
|
||||
//success roll
|
||||
success = zone->random.Roll(taunt_chance);
|
||||
|
||||
// Log result
|
||||
LogHate(
|
||||
"Taunter mob [{}] target npc [{}] taunt_chance [{}] success [{}] hate_top [{}]",
|
||||
GetMobDescription(),
|
||||
who->GetMobDescription(),
|
||||
taunt_chance,
|
||||
success ? "true" : "false",
|
||||
hate_top ? hate_top->GetMobDescription() : "not found"
|
||||
);
|
||||
|
||||
// Actual Taunting
|
||||
if (success) {
|
||||
if (hate_top && hate_top != this) {
|
||||
int64 new_hate = (
|
||||
(who->GetNPCHate(hate_top) - who->GetNPCHate(this)) +
|
||||
bonus_hate +
|
||||
RuleI(Combat, TauntOverAggro) +
|
||||
1
|
||||
);
|
||||
|
||||
LogHate(
|
||||
"Not Top Hate - Taunter [{}] Target [{}] Hated Top [{}] Hate Top Amt [{}] This Character Amt [{}] Bonus_Hate Amt [{}] TauntOverAggro Amt [{}] - Total [{}]",
|
||||
GetMobDescription(),
|
||||
who->GetMobDescription(),
|
||||
hate_top->GetMobDescription(),
|
||||
who->GetNPCHate(hate_top),
|
||||
who->GetNPCHate(this),
|
||||
bonus_hate,
|
||||
RuleI(Combat, TauntOverAggro),
|
||||
new_hate
|
||||
);
|
||||
|
||||
who->CastToNPC()->AddToHateList(this, new_hate);
|
||||
} else {
|
||||
LogHate("Already Hate Top");
|
||||
who->CastToNPC()->AddToHateList(this, 12);
|
||||
}
|
||||
|
||||
if (who->CanTalk()) {
|
||||
who->SayString(SUCCESSFUL_TAUNT, GetCleanName());
|
||||
}
|
||||
|
||||
MessageString(Chat::Skills, TAUNT_SUCCESS, who->GetCleanName());
|
||||
} else {
|
||||
MessageString(Chat::SpellFailure, FAILED_TAUNT);
|
||||
MessageString(Chat::Skills, FAILED_TAUNT);
|
||||
}
|
||||
|
||||
TryCastOnSkillUse(who, EQ::skills::SkillTaunt);
|
||||
// Modern Abilities
|
||||
if (!RuleB(Combat, ClassicTauntSystem)) {
|
||||
TryCastOnSkillUse(who, EQ::skills::SkillTaunt);
|
||||
|
||||
if (HasSkillProcs()) {
|
||||
TrySkillProc(who, EQ::skills::SkillTaunt, TauntReuseTime * 1000);
|
||||
}
|
||||
if (HasSkillProcs()) {
|
||||
TrySkillProc(who, EQ::skills::SkillTaunt, TauntReuseTime * 1000);
|
||||
}
|
||||
|
||||
if (success && HasSkillProcSuccess()) {
|
||||
TrySkillProc(who, EQ::skills::SkillTaunt, TauntReuseTime * 1000, true);
|
||||
if (success && HasSkillProcSuccess()) {
|
||||
TrySkillProc(who, EQ::skills::SkillTaunt, TauntReuseTime * 1000, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -140,6 +140,7 @@
|
||||
#define SONG_NEEDS_BRASS 408 //You need to play a brass instrument for this song
|
||||
#define AA_GAIN_ABILITY 410 //You have gained the ability "%T1" at a cost of %2 ability %T3.
|
||||
#define AA_IMPROVE 411 //You have improved %T1 %2 at a cost of %3 ability %T4.
|
||||
#define TAUNT_SUCCESS 412 //You taunt %1 to ignore others and attack you!
|
||||
#define AA_REUSE_MSG 413 //You can use the ability %B1(1) again in %2 hour(s) %3 minute(s) %4 seconds.
|
||||
#define AA_REUSE_MSG2 414 //You can use the ability %B1(1) again in %2 minute(s) %3 seconds.
|
||||
#define YOU_HEALED 419 //%1 has healed you for %2 points of damage.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user