SE_Taunt is a flat chance not a bonus to taunt chance

This commit is contained in:
Michael Cook (mackal) 2017-03-20 19:45:26 -04:00
parent 9510e8fbe1
commit 0ac70c5459
3 changed files with 56 additions and 53 deletions

View File

@ -843,7 +843,7 @@ public:
void StartEnrage(); void StartEnrage();
void ProcessEnrage(); void ProcessEnrage();
bool IsEnraged(); bool IsEnraged();
void Taunt(NPC* who, bool always_succeed, float chance_bonus=0, bool FromSpell=false, int32 bonus_hate=0); void Taunt(NPC *who, bool always_succeed, int chance_bonus = 0, bool FromSpell = false, int32 bonus_hate = 0);
virtual void AI_Init(); virtual void AI_Init();
virtual void AI_Start(uint32 iMoveDelay = 0); virtual void AI_Start(uint32 iMoveDelay = 0);

View File

@ -1868,18 +1868,18 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
} }
} }
void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus, bool FromSpell, int32 bonus_hate) { void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool FromSpell, int32 bonus_hate)
{
if (who == nullptr) if (who == nullptr)
return; return;
if(DivineAura()) if (DivineAura())
return; return;
if(!FromSpell && !CombatRange(who)) if (!FromSpell && !CombatRange(who))
return; return;
if(!always_succeed && IsClient()) if (!always_succeed && IsClient())
CastToClient()->CheckIncreaseSkill(EQEmu::skills::SkillTaunt, who, 10); CastToClient()->CheckIncreaseSkill(EQEmu::skills::SkillTaunt, who, 10);
Mob *hate_top = who->GetHateMost(); Mob *hate_top = who->GetHateMost();
@ -1887,69 +1887,73 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus, bool FromSpel
int level_difference = GetLevel() - who->GetLevel(); int level_difference = GetLevel() - who->GetLevel();
bool Success = false; bool Success = false;
//Support for how taunt worked pre 2000 on LIVE - Can not taunt NPC over your level. // Support for how taunt worked pre 2000 on LIVE - Can not taunt NPC over your level.
if ((RuleB(Combat,TauntOverLevel) == false) && (level_difference < 0) || who->GetSpecialAbility(IMMUNE_TAUNT)){ if ((RuleB(Combat, TauntOverLevel) == false) && (level_difference < 0) ||
Message_StringID(MT_SpellFailure,FAILED_TAUNT); who->GetSpecialAbility(IMMUNE_TAUNT)) {
Message_StringID(MT_SpellFailure, FAILED_TAUNT);
return; return;
} }
//All values used based on live parses after taunt was updated in 2006. // All values used based on live parses after taunt was updated in 2006.
if ((hate_top && hate_top->GetHPRatio() >= 20) || hate_top == nullptr) { if ((hate_top && hate_top->GetHPRatio() >= 20) || hate_top == nullptr || chance_bonus) {
// SE_Taunt this is flat chance
if (chance_bonus) {
Success = zone->random.Roll(chance_bonus);
} else {
int32 newhate = 0;
float tauntchance = 50.0f;
int32 newhate = 0; if (always_succeed)
float tauntchance = 50.0f; tauntchance = 101.0f;
if(always_succeed)
tauntchance = 101.0f;
else {
if (level_difference < 0){
tauntchance += static_cast<float>(level_difference)*3.0f;
if (tauntchance < 20)
tauntchance = 20.0f;
}
else { else {
tauntchance += static_cast<float>(level_difference)*5.0f;
if (tauntchance > 65) if (level_difference < 0) {
tauntchance = 65.0f; tauntchance += static_cast<float>(level_difference) * 3.0f;
if (tauntchance < 20)
tauntchance = 20.0f;
}
else {
tauntchance += static_cast<float>(level_difference) * 5.0f;
if (tauntchance > 65)
tauntchance = 65.0f;
}
} }
// TauntSkillFalloff rate is not based on any real data. Default of 33% gives a reasonable
// result.
if (IsClient() && !always_succeed)
tauntchance -= (RuleR(Combat, TauntSkillFalloff) *
(CastToClient()->MaxSkill(EQEmu::skills::SkillTaunt) -
GetSkill(EQEmu::skills::SkillTaunt)));
if (tauntchance < 1)
tauntchance = 1.0f;
tauntchance /= 100.0f;
Success = tauntchance > zone->random.Real(0, 1);
} }
//TauntSkillFalloff rate is not based on any real data. Default of 33% gives a reasonable result. if (Success) {
if (IsClient() && !always_succeed) if (hate_top && hate_top != this) {
tauntchance -= (RuleR(Combat, TauntSkillFalloff) * (CastToClient()->MaxSkill(EQEmu::skills::SkillTaunt) - GetSkill(EQEmu::skills::SkillTaunt)));
//From SE_Taunt (Does a taunt with a chance modifier)
if (chance_bonus)
tauntchance += tauntchance*chance_bonus/100.0f;
if (tauntchance < 1)
tauntchance = 1.0f;
tauntchance /= 100.0f;
if (tauntchance > zone->random.Real(0, 1)) {
if (hate_top && hate_top != this){
newhate = (who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1 + bonus_hate; newhate = (who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1 + bonus_hate;
who->CastToNPC()->AddToHateList(this, newhate); who->CastToNPC()->AddToHateList(this, newhate);
Success = true; Success = true;
} else {
who->CastToNPC()->AddToHateList(this, 12);
} }
else
who->CastToNPC()->AddToHateList(this,12);
if (who->CanTalk()) if (who->CanTalk())
who->Say_StringID(SUCCESSFUL_TAUNT,GetCleanName()); who->Say_StringID(SUCCESSFUL_TAUNT, GetCleanName());
} } else {
else{ Message_StringID(MT_SpellFailure, FAILED_TAUNT);
Message_StringID(MT_SpellFailure,FAILED_TAUNT);
} }
} else {
Message_StringID(MT_SpellFailure, FAILED_TAUNT);
} }
else
Message_StringID(MT_SpellFailure,FAILED_TAUNT);
if (HasSkillProcs()) if (HasSkillProcs())
TrySkillProc(who, EQEmu::skills::SkillTaunt, TauntReuseTime * 1000); TrySkillProc(who, EQEmu::skills::SkillTaunt, TauntReuseTime * 1000);
@ -1957,7 +1961,6 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus, bool FromSpel
TrySkillProc(who, EQEmu::skills::SkillTaunt, TauntReuseTime * 1000, true); TrySkillProc(who, EQEmu::skills::SkillTaunt, TauntReuseTime * 1000, true);
} }
void Mob::InstillDoubt(Mob *who) { void Mob::InstillDoubt(Mob *who) {
//make sure we can use this skill //make sure we can use this skill
/*int skill = GetSkill(INTIMIDATION);*/ //unused /*int skill = GetSkill(INTIMIDATION);*/ //unused

View File

@ -2676,7 +2676,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
case SE_Taunt: case SE_Taunt:
{ {
if (caster && IsNPC()){ if (caster && IsNPC()){
caster->Taunt(this->CastToNPC(), false, static_cast<float>(spell.base[i]), true, spell.base2[i]); caster->Taunt(this->CastToNPC(), false, spell.base[i], true, spell.base2[i]);
} }
break; break;
} }