diff --git a/utils/sql/git/required/2014_02_26_virulentvenomAA.sql b/utils/sql/git/required/2014_02_26_virulentvenomAA.sql new file mode 100644 index 000000000..6fa6cec9e --- /dev/null +++ b/utils/sql/git/required/2014_02_26_virulentvenomAA.sql @@ -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'); + + diff --git a/zone/attack.cpp b/zone/attack.cpp index 5e7b21a93..78ab250cd 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -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); diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 743c5d250..7cde92ae4 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -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: diff --git a/zone/bot.cpp b/zone/bot.cpp index a7ff02f1b..3cac34024 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -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); diff --git a/zone/bot.h b/zone/bot.h index 309931acd..8cf439c57 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -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); diff --git a/zone/common.h b/zone/common.h index 39f766794..89ef7e573 100644 --- a/zone/common.h +++ b/zone/common.h @@ -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) diff --git a/zone/effects.cpp b/zone/effects.cpp index 785dd882c..3c11b41d5 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -81,6 +81,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){ @@ -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) { diff --git a/zone/mob.h b/zone/mob.h index f636b5ea7..47e87412f 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -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);