Clean up and revision of proc chance bonuses

Combat Effects and WeaponProc bonuses will no longer affect melee spell procs
This commit is contained in:
KayenEQ 2014-02-26 05:16:37 -05:00
parent 8caac162b2
commit 205dd8a1e5
8 changed files with 54 additions and 50 deletions

View File

@ -0,0 +1,8 @@
-- Virulent Venom
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1, `base2`) VALUES ('888', '1', '250', '10', '0');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1, `base2`) VALUES ('889', '1', '250', '20', '0');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1, `base2`) VALUES ('890', '1', '250', '30', '0');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1, `base2`) VALUES ('891', '1', '250', '40', '0');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1, `base2`) VALUES ('892', '1', '250', '50', '0');

View File

@ -3888,14 +3888,14 @@ void Mob::HealDamage(uint32 amount, Mob* caster) {
//proc chance includes proc bonus
float Mob::GetProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed, uint16 hand) {
float Mob::GetProcChances(float &BaseProcChance, float &ProcBonus, float &ProcChance, uint16 weapon_speed, uint16 hand) {
int mydex = GetDEX();
float AABonus = 0;
ProcBonus = 0;
ProcChance = 0;
BaseProcChance = 0;
if (aabonuses.ProcChance)
AABonus = float(aabonuses.ProcChance) / 100.0f;
ProcBonus = float(aabonuses.ProcChanceSPA + spellbonuses.ProcChanceSPA + itembonuses.ProcChanceSPA); //Spell Effects
ProcBonus += float(itembonuses.ProcChance)/10.0f; //Combat Effects
switch(hand){
case 13:
@ -3915,18 +3915,18 @@ float Mob::GetProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_spe
if(weapon_speed < RuleI(Combat, MinHastedDelay)) // fast as a client can swing, so should be the floor of the proc chance
weapon_speed = RuleI(Combat, MinHastedDelay);
ProcBonus += (float(itembonuses.ProcChance + spellbonuses.ProcChance) / 1000.0f + AABonus);
if(RuleB(Combat, AdjustProcPerMinute) == true)
{
ProcChance = ((float)weapon_speed * RuleR(Combat, AvgProcsPerMinute) / 60000.0f); // compensate for weapon_speed being in ms
ProcBonus += float(mydex) * RuleR(Combat, ProcPerMinDexContrib) / 100.0f;
ProcChance = ProcChance + (ProcChance * ProcBonus);
BaseProcChance = ProcChance;
ProcBonus += float(mydex) * RuleR(Combat, ProcPerMinDexContrib);
ProcChance += ProcChance*ProcBonus/100.0f;
}
else
{
ProcChance = RuleR(Combat, BaseProcChance) + float(mydex) / RuleR(Combat, ProcDexDivideBy);
ProcChance = ProcChance + (ProcChance * ProcBonus);
BaseProcChance = ProcChance;
ProcChance += ProcChance*ProcBonus/100.0f;
}
mlog(COMBAT__PROCS, "Proc chance %.2f (%.2f from bonuses)", ProcChance, ProcBonus);
@ -3950,16 +3950,6 @@ float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 w
break;
}
/*
float PermaHaste;
if(GetHaste() > 0)
PermaHaste = 1 / (1 + (float)GetHaste()/100);
else if(GetHaste() < 0)
PermaHaste = 1 * (1 - (float)GetHaste()/100);
else
PermaHaste = 1.0f;
*/
//calculate the weapon speed in ms, so we can use the rule to compare against.
//weapon_speed = ((int)(weapon_speed*(100.0f+attack_speed)*PermaHaste));
if(weapon_speed < RuleI(Combat, MinHastedDelay)) // fast as a client can swing, so should be the floor of the proc chance
@ -4054,8 +4044,8 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
//we have to calculate these again, oh well
int ourlevel = GetLevel();
float ProcChance, ProcBonus;
GetProcChances(ProcBonus, ProcChance, weapon_g->GetItem()->Delay, hand);
float ProcChance, ProcBonus, BaseProcChance;
GetProcChances(BaseProcChance, ProcBonus, ProcChance, weapon_g->GetItem()->Delay, hand);
if(hand != 13)
{
ProcChance /= 2;
@ -4092,11 +4082,11 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct* weapon, Mob *on, uint16 hand) {
uint16 skillinuse = 28;
int ourlevel = GetLevel();
float ProcChance, ProcBonus;
float ProcChance, ProcBonus, BaseProcChance;
if(weapon!=nullptr)
GetProcChances(ProcBonus, ProcChance, weapon->Delay, hand);
GetProcChances(BaseProcChance, ProcBonus, ProcChance, weapon->Delay, hand);
else
GetProcChances(ProcBonus, ProcChance);
GetProcChances(BaseProcChance, ProcBonus, ProcChance);
if(hand != 13) //Is Archery intended to proc at 50% rate?
ProcChance /= 2;
@ -4153,7 +4143,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct* weapon, Mob *on
uint32 i;
for(i = 0; i < MAX_PROCS; i++) {
if (PermaProcs[i].spellID != SPELL_UNKNOWN) {
if(MakeRandomInt(0, 100) < PermaProcs[i].chance) {
if(MakeRandomInt(0, 100) < PermaProcs[i].chance) { //TODO: Unclear if these are treated like Spells or WeaponProcs
mlog(COMBAT__PROCS, "Permanent proc %d procing spell %d (%d percent chance)", i, PermaProcs[i].spellID, PermaProcs[i].chance);
ExecWeaponProc(nullptr, PermaProcs[i].spellID, on);
} else {
@ -4169,7 +4159,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct* weapon, Mob *on
}
else
{
int chance = ProcChance * (SpellProcs[i].chance);
int chance = BaseProcChance * (SpellProcs[i].chance);
chance += chance*SpellProcChance/100;
if(MakeRandomInt(0, 100) < chance) {
mlog(COMBAT__PROCS, "Spell proc %d procing spell %d (%d percent chance)", i, SpellProcs[i].spellID, chance);
@ -4181,7 +4171,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct* weapon, Mob *on
}
}
if (bRangedAttack) {
int chance = ProcChance * RangedProcs[i].chance;
int chance = BaseProcChance * RangedProcs[i].chance;
chance += chance*SpellProcChance/100;
if(MakeRandomInt(0, 100) < chance) {
mlog(COMBAT__PROCS, "Ranged proc %d procing spell %d", i, RangedProcs[i].spellID, RangedProcs[i].chance);

View File

@ -963,7 +963,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
newbon->GiveDoubleAttack += base1;
break;
case SE_ProcChance:
newbon->ProcChance += base1;
newbon->ProcChanceSPA += base1;
break;
case SE_RiposteChance:
newbon->RiposteChance += base1;
@ -1890,17 +1890,14 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_ProcChance:
{
//multiplier is to be compatible with item effects,watching for overflow too
effect_value = effect_value<3000? effect_value : 3000;
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
newbon->ProcChance += effect_value;
newbon->ProcChanceSPA += effect_value;
else if((effect_value < 0) && (newbon->DoubleAttackChance > effect_value))
newbon->ProcChance = effect_value;
else if((effect_value < 0) && (newbon->ProcChanceSPA > effect_value))
newbon->ProcChanceSPA = effect_value;
if(newbon->ProcChance < effect_value)
newbon->ProcChance = effect_value;
if(newbon->ProcChanceSPA < effect_value)
newbon->ProcChanceSPA = effect_value;
break;
}
@ -3323,9 +3320,9 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
break;
case SE_ProcChance:
spellbonuses.ProcChance = effect_value;
aabonuses.ProcChance = effect_value;
itembonuses.ProcChance = effect_value;
spellbonuses.ProcChanceSPA = effect_value;
aabonuses.ProcChanceSPA = effect_value;
itembonuses.ProcChanceSPA = effect_value;
break;
case SE_ExtraAttackChance:

View File

@ -7705,14 +7705,14 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
}
//proc chance includes proc bonus
float Bot::GetProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed, uint16 hand) {
float Bot::GetProcChances(float &BaseProcChance, float &ProcBonus, float &ProcChance, uint16 weapon_speed, uint16 hand) {
int mydex = GetDEX();
float AABonus = 0;
ProcBonus = 0;
ProcChance = 0;
BaseProcChance = 0;
if (aabonuses.ProcChance)
AABonus = float(aabonuses.ProcChance) / 100.0f;
ProcBonus = float(aabonuses.ProcChanceSPA + spellbonuses.ProcChanceSPA + itembonuses.ProcChanceSPA); //Spell Effects
ProcBonus += float(itembonuses.ProcChance)/10.0f; //Combat Effects
switch(hand){
case SLOT_PRIMARY:
@ -7732,18 +7732,18 @@ float Bot::GetProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_spe
if(weapon_speed < RuleI(Combat, MinHastedDelay)) // fast as a client can swing, so should be the floor of the proc chance
weapon_speed = RuleI(Combat, MinHastedDelay);
ProcBonus += (float(itembonuses.ProcChance + spellbonuses.ProcChance) / 1000.0f + AABonus);
if(RuleB(Combat, AdjustProcPerMinute) == true)
{
ProcChance = ((float)weapon_speed * RuleR(Combat, AvgProcsPerMinute) / 60000.0f); // compensate for weapon_speed being in ms
ProcBonus += float(mydex) * RuleR(Combat, ProcPerMinDexContrib) / 100.0f;
ProcChance = ProcChance + (ProcChance * ProcBonus);
ProcChance = BaseProcChance;
ProcBonus += float(mydex) * RuleR(Combat, ProcPerMinDexContrib);
ProcChance += ProcChance*ProcBonus / 100.0f;
}
else
{
ProcChance = RuleR(Combat, BaseProcChance) + float(mydex) / RuleR(Combat, ProcDexDivideBy);
ProcChance = ProcChance + (ProcChance * ProcBonus);
ProcChance = BaseProcChance;
ProcChance += ProcChance*ProcBonus / 100.0f;
}
mlog(COMBAT__PROCS, "Proc chance %.2f (%.2f from bonuses)", ProcChance, ProcBonus);

View File

@ -167,7 +167,7 @@ public:
uint16 BotGetSpells(int spellslot) { return AIspells[spellslot].spellid; }
uint16 BotGetSpellType(int spellslot) { return AIspells[spellslot].type; }
uint16 BotGetSpellPriority(int spellslot) { return AIspells[spellslot].priority; }
virtual float GetProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed, uint16 hand);
virtual float GetProcChances(float &BaseProcChance, float &ProcBonus, float &ProcChance, uint16 weapon_speed, uint16 hand);
virtual bool AvoidDamage(Mob* other, int32 &damage, bool CanRiposte);
virtual int GetMonkHandToHandDamage(void);
virtual bool TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse);

View File

@ -274,6 +274,7 @@ struct StatBonuses {
int16 DamageModifier[HIGHEST_SKILL+2]; //i
int16 MinDamageModifier[HIGHEST_SKILL+2]; //i
int16 ProcChance; // ProcChance/10 == % increase i = CombatEffects
int16 ProcChanceSPA; // ProcChance from spell effects
int16 ExtraAttackChance;
int16 DoTShielding;
int16 DivineSaveChance[2]; // Second Chance (base1 = chance, base2 = spell on trigger)

View File

@ -82,6 +82,8 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
int chance = RuleI(Spells, BaseCritChance);
chance += itembonuses.CriticalSpellChance + spellbonuses.CriticalSpellChance + aabonuses.CriticalSpellChance;
chance += itembonuses.FrenziedDevastation + spellbonuses.FrenziedDevastation + aabonuses.FrenziedDevastation;
if (chance > 0){
int32 ratio = RuleI(Spells, BaseCritRatio); //Critical modifier is applied from spell effects only. Keep at 100 for live like criticals.
@ -321,6 +323,12 @@ int32 Client::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
{
//FrenziedDevastation doubles mana cost of all DD spells
int16 FrenziedDevastation = itembonuses.FrenziedDevastation + spellbonuses.FrenziedDevastation + aabonuses.FrenziedDevastation;
if (FrenziedDevastation && IsPureNukeSpell(spell_id))
cost *= 2;
// Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell
if(this->itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
{

View File

@ -971,7 +971,7 @@ protected:
void TryWeaponProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = 13);
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = 13);
void ExecWeaponProc(const ItemInst* weapon, uint16 spell_id, Mob *on);
virtual float GetProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed = 30, uint16 hand = 13);
virtual float GetProcChances(float &BaseProcChance, float &ProcBonus, float &ProcChance, uint16 weapon_speed = 30, uint16 hand = 13);
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed = 30, uint16 hand = 13);
int GetWeaponDamage(Mob *against, const Item_Struct *weapon_item);
int GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate = nullptr);