mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-03 02:13:51 +00:00
Complete revision of SE_SkillProc, SE_LimitToSkill,
SE_SkillProcSuccess (now implemented correctly) to function more accurately and efficiently, AA supported. This may need to be updated in the future, if more live spells readily become avialable to test with.
This commit is contained in:
parent
3a4e72e3e7
commit
0e438942e4
@ -7,6 +7,7 @@ Sympathetic foci on items with proc rate mod will now benefit from that modifier
|
||||
Sympathetic foci can now be placed on AA's (This should always be slot1 in the AA)
|
||||
Kayen: Implemented SE_IllusionPersistence- Allows illusions to last until you die or the illusion is forcibly removed.
|
||||
Kayen: Added rule 'PreNerftBardAEDot' for SE_BardAEDot to allow it to once again do damage to moving targets. (Set to true)
|
||||
Kayen: Completely revised SE_SkillProc, SE_LimitToSkill, SE_SkillProcSuccess to overall just work better and more accurately, AA support.
|
||||
|
||||
Required SQL: utils/sql/git/required/2014_07_04_AA_Update.sql
|
||||
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
#define MAX_SPELL_TRIGGER 12 // One for each slot(only 6 for AA since AA use 2)
|
||||
#define MAX_RESISTABLE_EFFECTS 12 // Number of effects that are typcially checked agianst resists.
|
||||
#define MaxLimitInclude 16 //Number(x 0.5) of focus Limiters that have inclusive checks used when calcing focus effects
|
||||
#define MAX_SKILL_PROCS 4 //Number of spells to check skill procs from. (This is arbitrary) [Single spell can have multiple proc checks]
|
||||
|
||||
|
||||
const int Z_AGGRO=10;
|
||||
|
||||
@ -576,7 +578,7 @@ typedef enum {
|
||||
//#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
|
||||
#define SE_SkillProc 427 // implemented - chance to proc when using a skill(ie taunt)
|
||||
#define SE_LimitToSkill 428 // implemented - limits what skills will effect a skill proc
|
||||
#define SE_SkillProc2 429 // implemented - chance to proc when using a skill (most have hit limits)
|
||||
#define SE_SkillProcSuccess 429 // implemented - chance to proc when tje skill in use successfully fires.
|
||||
//#define SE_PostEffect 430 // *not implemented - Fear of the Dark(27641) - Alters vision
|
||||
//#define SE_PostEffectData 431 // *not implemented - Fear of the Dark(27641) - Alters vision
|
||||
//#define SE_ExpandMaxActiveTrophyBen 432 // not used
|
||||
|
||||
274
zone/attack.cpp
274
zone/attack.cpp
@ -1359,8 +1359,11 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
|
||||
MeleeLifeTap(damage);
|
||||
|
||||
if (damage > 0)
|
||||
if (damage > 0){
|
||||
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
|
||||
if (HasSkillProcSuccess() && other && other->GetHP() > 0)
|
||||
TrySkillProc(other, skillinuse, 0, true, Hand);
|
||||
}
|
||||
|
||||
//break invis when you attack
|
||||
if(invisible) {
|
||||
@ -2018,9 +2021,12 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
if (!GetTarget())
|
||||
return true; //We killed them
|
||||
|
||||
if(!bRiposte && other->GetHP() > 0 ) {
|
||||
if(!bRiposte && other && other->GetHP() > 0) {
|
||||
TryWeaponProc(nullptr, weapon, other, Hand); //no weapon
|
||||
TrySpellProc(nullptr, weapon, other, Hand);
|
||||
|
||||
if (damage > 0 && HasSkillProcSuccess())
|
||||
TrySkillProc(other, skillinuse, 0, true, Hand);
|
||||
}
|
||||
|
||||
TriggerDefensiveProcs(nullptr, other, Hand, damage);
|
||||
@ -3426,9 +3432,20 @@ bool Mob::HasDefensiveProcs() const
|
||||
|
||||
bool Mob::HasSkillProcs() const
|
||||
{
|
||||
for (int i = 0; i < MAX_PROCS; i++)
|
||||
if (SkillProcs[i].spellID != SPELL_UNKNOWN)
|
||||
|
||||
for(int i = 0; i < MAX_SKILL_PROCS; i++){
|
||||
if (spellbonuses.SkillProc[i] || itembonuses.SkillProc[i] || aabonuses.SkillProc[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mob::HasSkillProcSuccess() const
|
||||
{
|
||||
for(int i = 0; i < MAX_SKILL_PROCS; i++){
|
||||
if (spellbonuses.SkillProcSuccess[i] || itembonuses.SkillProcSuccess[i] || aabonuses.SkillProcSuccess[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3911,22 +3928,7 @@ float Mob::GetProcChances(float ProcBonus, uint16 weapon_speed, uint16 hand)
|
||||
int mydex = GetDEX();
|
||||
float ProcChance = 0.0f;
|
||||
|
||||
switch (hand) {
|
||||
case 13:
|
||||
weapon_speed = attack_timer.GetDuration();
|
||||
break;
|
||||
case 14:
|
||||
weapon_speed = attack_dw_timer.GetDuration();
|
||||
break;
|
||||
case 11:
|
||||
weapon_speed = ranged_timer.GetDuration();
|
||||
break;
|
||||
}
|
||||
|
||||
//calculate the weapon speed in ms, so we can use the rule to compare against.
|
||||
// fast as a client can swing, so should be the floor of the proc chance
|
||||
if (weapon_speed < RuleI(Combat, MinHastedDelay))
|
||||
weapon_speed = RuleI(Combat, MinHastedDelay);
|
||||
weapon_speed = GetWeaponSpeedbyHand(hand);
|
||||
|
||||
if (RuleB(Combat, AdjustProcPerMinute)) {
|
||||
ProcChance = (static_cast<float>(weapon_speed) *
|
||||
@ -3948,25 +3950,10 @@ float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 w
|
||||
ProcBonus = 0;
|
||||
ProcChance = 0;
|
||||
|
||||
switch(hand){
|
||||
case 13:
|
||||
weapon_speed = attack_timer.GetDuration();
|
||||
break;
|
||||
case 14:
|
||||
weapon_speed = attack_dw_timer.GetDuration();
|
||||
break;
|
||||
case 11:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
weapon_speed = GetWeaponSpeedbyHand(hand);
|
||||
|
||||
//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
|
||||
weapon_speed = RuleI(Combat, MinHastedDelay);
|
||||
|
||||
ProcChance = ((float)weapon_speed * RuleR(Combat, AvgDefProcsPerMinute) / 60000.0f); // compensate for weapon_speed being in ms
|
||||
ProcBonus += float(myagi) * RuleR(Combat, DefProcPerMinAgiContrib) / 100.0f;
|
||||
ProcChance = (static_cast<float>(weapon_speed) * RuleR(Combat, AvgDefProcsPerMinute) / 60000.0f); // compensate for weapon_speed being in ms
|
||||
ProcBonus += static_cast<float>(myagi) * RuleR(Combat, DefProcPerMinAgiContrib) / 100.0f;
|
||||
ProcChance = ProcChance + (ProcChance * ProcBonus);
|
||||
|
||||
mlog(COMBAT__PROCS, "Defensive Proc chance %.2f (%.2f from bonuses)", ProcChance, ProcBonus);
|
||||
@ -3981,13 +3968,9 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand, int dam
|
||||
return;
|
||||
}
|
||||
|
||||
bool bSkillProc = HasSkillProcs();
|
||||
bool bDefensiveProc = HasDefensiveProcs();
|
||||
|
||||
if (!bDefensiveProc && !bSkillProc)
|
||||
return;
|
||||
|
||||
if (!bDefensiveProc && (bSkillProc && damage >= 0))
|
||||
if (!bDefensiveProc)
|
||||
return;
|
||||
|
||||
float ProcChance, ProcBonus;
|
||||
@ -4001,29 +3984,14 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand, int dam
|
||||
if (bDefensiveProc){
|
||||
for (int i = 0; i < MAX_PROCS; i++) {
|
||||
if (DefensiveProcs[i].spellID != SPELL_UNKNOWN) {
|
||||
int chance = ProcChance * (DefensiveProcs[i].chance);
|
||||
if ((MakeRandomInt(0, 100) < chance)) {
|
||||
float chance = ProcChance * (static_cast<float>(DefensiveProcs[i].chance)/100.0f);
|
||||
if ((MakeRandomInt(0, 1) <= chance)) {
|
||||
ExecWeaponProc(nullptr, DefensiveProcs[i].spellID, on);
|
||||
CheckNumHitsRemaining(NUMHIT_DefensiveSpellProcs,0,DefensiveProcs[i].base_spellID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bSkillProc && damage < 0){
|
||||
|
||||
if (damage == -1)
|
||||
TrySkillProc(on, SkillBlock, ProcChance);
|
||||
|
||||
if (damage == -2)
|
||||
TrySkillProc(on, SkillParry, ProcChance);
|
||||
|
||||
if (damage == -3)
|
||||
TrySkillProc(on, SkillRiposte, ProcChance);
|
||||
|
||||
if (damage == -4)
|
||||
TrySkillProc(on, SkillDodge, ProcChance);
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
|
||||
@ -4032,7 +4000,7 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TryWeaponProc for evaluation!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!IsAttackAllowed(on)) {
|
||||
mlog(COMBAT__PROCS, "Preventing procing off of unattackable things.");
|
||||
return;
|
||||
@ -4059,6 +4027,7 @@ 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)
|
||||
{
|
||||
|
||||
if (!weapon)
|
||||
return;
|
||||
uint16 skillinuse = 28;
|
||||
@ -4135,8 +4104,6 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on
|
||||
}
|
||||
}
|
||||
// TODO: Powersource procs
|
||||
if (HasSkillProcs())
|
||||
TrySkillProc(on, skillinuse, ProcChance);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -4217,6 +4184,14 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
|
||||
}
|
||||
}
|
||||
|
||||
if (HasSkillProcs() && hand != 11){ //We check ranged skill procs within the attack functions.
|
||||
uint16 skillinuse = 28;
|
||||
if (weapon)
|
||||
skillinuse = GetSkillByItemType(weapon->ItemType);
|
||||
|
||||
TrySkillProc(on, skillinuse, 0, false, hand);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4560,7 +4535,7 @@ uint16 Mob::GetDamageTable(SkillUseTypes skillinuse)
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::TrySkillProc(Mob *on, uint16 skill, float chance)
|
||||
void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, uint16 hand, bool IsDefensive)
|
||||
{
|
||||
|
||||
if (!on) {
|
||||
@ -4569,17 +4544,174 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, float chance)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_PROCS; i++) {
|
||||
if (SkillProcs[i].spellID != SPELL_UNKNOWN){
|
||||
if (PassLimitToSkill(SkillProcs[i].base_spellID,skill)){
|
||||
int ProcChance = chance * (float)SkillProcs[i].chance;
|
||||
if ((MakeRandomInt(0, 100) < ProcChance)) {
|
||||
ExecWeaponProc(nullptr, SkillProcs[i].spellID, on);
|
||||
CheckNumHitsRemaining(NUMHIT_OffensiveSpellProcs,0, SkillProcs[i].base_spellID);
|
||||
if (!spellbonuses.LimitToSkill[skill] && !itembonuses.LimitToSkill[skill] && !aabonuses.LimitToSkill[skill])
|
||||
return;
|
||||
|
||||
/*Allow one proc from each (Spell/Item/AA)
|
||||
Kayen: Due to limited avialability of effects on live it is too difficult
|
||||
to confirm how they stack at this time, will adjust formula when more data is avialablle to test.*/
|
||||
bool CanProc = true;
|
||||
|
||||
uint16 base_spell_id = 0;
|
||||
uint16 proc_spell_id = 0;
|
||||
float ProcMod = 0;
|
||||
float chance = 0;
|
||||
|
||||
if (IsDefensive)
|
||||
chance = on->GetSkillProcChances(ReuseTime, hand);
|
||||
else
|
||||
chance = GetSkillProcChances(ReuseTime, hand);
|
||||
|
||||
if (spellbonuses.LimitToSkill[skill]){
|
||||
|
||||
for(int e = 0; e < MAX_SKILL_PROCS; e++){
|
||||
|
||||
if (CanProc &&
|
||||
(!Success && spellbonuses.SkillProc[e] && IsValidSpell(spellbonuses.SkillProc[e]))
|
||||
|| (Success && spellbonuses.SkillProcSuccess[e] && IsValidSpell(spellbonuses.SkillProcSuccess[e]))) {
|
||||
base_spell_id = spellbonuses.SkillProc[e];
|
||||
base_spell_id = 0;
|
||||
ProcMod = 0;
|
||||
|
||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||
|
||||
if (spells[base_spell_id].effectid[i] == SE_SkillProc) {
|
||||
proc_spell_id = spells[base_spell_id].base[i];
|
||||
ProcMod = static_cast<float>(spells[base_spell_id].base2[i]);
|
||||
}
|
||||
|
||||
else if (spells[base_spell_id].effectid[i] == SE_LimitToSkill && spells[base_spell_id].effectid[i] <= HIGHEST_SKILL) {
|
||||
|
||||
if (CanProc && spells[base_spell_id].base[i] == skill && IsValidSpell(proc_spell_id)) {
|
||||
float final_chance = chance * (ProcMod / 100.0f);
|
||||
if (MakeRandomFloat(0, 1) <= final_chance) {
|
||||
ExecWeaponProc(nullptr, proc_spell_id, on);
|
||||
CheckNumHitsRemaining(NUMHIT_OffensiveSpellProcs,0, base_spell_id);
|
||||
CanProc = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
proc_spell_id = 0;
|
||||
ProcMod = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itembonuses.LimitToSkill[skill]){
|
||||
CanProc = true;
|
||||
for(int e = 0; e < MAX_SKILL_PROCS; e++){
|
||||
|
||||
if (CanProc &&
|
||||
(!Success && itembonuses.SkillProc[e] && IsValidSpell(itembonuses.SkillProc[e]))
|
||||
|| (Success && itembonuses.SkillProcSuccess[e] && IsValidSpell(itembonuses.SkillProcSuccess[e]))) {
|
||||
base_spell_id = itembonuses.SkillProc[e];
|
||||
base_spell_id = 0;
|
||||
ProcMod = 0;
|
||||
|
||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||
|
||||
if (spells[base_spell_id].effectid[i] == SE_SkillProc) {
|
||||
proc_spell_id = spells[base_spell_id].base[i];
|
||||
ProcMod = static_cast<float>(spells[base_spell_id].base2[i]);
|
||||
}
|
||||
|
||||
else if (spells[base_spell_id].effectid[i] == SE_LimitToSkill && spells[base_spell_id].effectid[i] <= HIGHEST_SKILL) {
|
||||
|
||||
if (CanProc && spells[base_spell_id].base[i] == skill && IsValidSpell(proc_spell_id)) {
|
||||
float final_chance = chance * (ProcMod / 100.0f);
|
||||
if (MakeRandomFloat(0, 1) <= final_chance) {
|
||||
ExecWeaponProc(nullptr, proc_spell_id, on);
|
||||
CanProc = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
proc_spell_id = 0;
|
||||
ProcMod = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsClient() && aabonuses.LimitToSkill[skill]){
|
||||
|
||||
CanProc = true;
|
||||
uint32 effect = 0;
|
||||
int32 base1 = 0;
|
||||
int32 base2 = 0;
|
||||
uint32 slot = 0;
|
||||
|
||||
for(int e = 0; e < MAX_SKILL_PROCS; e++){
|
||||
|
||||
if (CanProc &&
|
||||
(!Success && aabonuses.SkillProc[e])
|
||||
|| (Success && aabonuses.SkillProcSuccess[e])){
|
||||
int aaid = aabonuses.SkillProc[e];
|
||||
base_spell_id = 0;
|
||||
ProcMod = 0;
|
||||
|
||||
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aaid);
|
||||
if(find_iter == aa_effects.end())
|
||||
break;
|
||||
|
||||
for (std::map<uint32, AA_Ability>::const_iterator iter = aa_effects[aaid].begin(); iter != aa_effects[aaid].end(); ++iter) {
|
||||
effect = iter->second.skill_id;
|
||||
base1 = iter->second.base1;
|
||||
base2 = iter->second.base2;
|
||||
slot = iter->second.slot;
|
||||
|
||||
if (effect == SE_SkillProc) {
|
||||
proc_spell_id = base1;
|
||||
ProcMod = static_cast<float>(base2);
|
||||
}
|
||||
|
||||
else if (effect == SE_LimitToSkill && effect <= HIGHEST_SKILL) {
|
||||
|
||||
if (CanProc && base1 == skill && IsValidSpell(proc_spell_id)) {
|
||||
float final_chance = chance * (ProcMod / 100.0f);
|
||||
|
||||
if (MakeRandomFloat(0, 1) <= final_chance) {
|
||||
ExecWeaponProc(nullptr, proc_spell_id, on);
|
||||
CanProc = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
proc_spell_id = 0;
|
||||
ProcMod = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float Mob::GetSkillProcChances(uint16 ReuseTime, uint16 hand) {
|
||||
|
||||
uint16 weapon_speed;
|
||||
float ProcChance = 0;
|
||||
|
||||
if (!ReuseTime && hand) {
|
||||
|
||||
weapon_speed = GetWeaponSpeedbyHand(hand);
|
||||
|
||||
ProcChance = static_cast<float>(weapon_speed) * (RuleR(Combat, AvgProcsPerMinute) / 60000.0f);
|
||||
|
||||
if (hand != 13)
|
||||
ProcChance /= 2;
|
||||
}
|
||||
|
||||
else
|
||||
ProcChance = static_cast<float>(ReuseTime) * (RuleR(Combat, AvgProcsPerMinute) / 60000.0f);
|
||||
|
||||
return ProcChance;
|
||||
}
|
||||
|
||||
bool Mob::TryRootFadeByDamage(int buffslot, Mob* attacker) {
|
||||
|
||||
@ -637,7 +637,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
||||
continue;
|
||||
|
||||
_log(AA__BONUSES, "Applying Effect %d from AA %u in slot %d (base1: %d, base2: %d) on %s", effect, aaid, slot, base1, base2, this->GetCleanName());
|
||||
|
||||
|
||||
uint8 focus = IsFocusEffect(0, 0, true,effect);
|
||||
if (focus)
|
||||
{
|
||||
@ -1333,6 +1333,41 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
||||
newbon->IllusionPersistence = true;
|
||||
break;
|
||||
|
||||
case SE_LimitToSkill:{
|
||||
if (base1 <= HIGHEST_SKILL)
|
||||
newbon->LimitToSkill[base1] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_SkillProc:{
|
||||
for(int e = 0; e < MAX_SKILL_PROCS; e++)
|
||||
{
|
||||
if(newbon->SkillProc[e] && newbon->SkillProc[e] == aaid)
|
||||
break; //Do not use the same aa id more than once.
|
||||
|
||||
else if(!newbon->SkillProc[e]){
|
||||
newbon->SkillProc[e] = aaid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_SkillProcSuccess:{
|
||||
|
||||
for(int e = 0; e < MAX_SKILL_PROCS; e++)
|
||||
{
|
||||
if(newbon->SkillProcSuccess[e] && newbon->SkillProcSuccess[e] == aaid)
|
||||
break; //Do not use the same spell id more than once.
|
||||
|
||||
else if(!newbon->SkillProcSuccess[e]){
|
||||
newbon->SkillProcSuccess[e] = aaid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2884,6 +2919,44 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
newbon->IllusionPersistence = true;
|
||||
break;
|
||||
|
||||
case SE_LimitToSkill:{
|
||||
if (effect_value <= HIGHEST_SKILL){
|
||||
newbon->LimitToSkill[effect_value] = true;
|
||||
Shout("BONUS Set Limit = %i", effect_value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_SkillProc:{
|
||||
|
||||
for(int e = 0; e < MAX_SKILL_PROCS; e++)
|
||||
{
|
||||
if(newbon->SkillProc[e] && newbon->SkillProc[e] == spell_id)
|
||||
break; //Do not use the same spell id more than once.
|
||||
|
||||
else if(!newbon->SkillProc[e]){
|
||||
newbon->SkillProc[e] = spell_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_SkillProcSuccess:{
|
||||
|
||||
for(int e = 0; e < MAX_SKILL_PROCS; e++)
|
||||
{
|
||||
if(newbon->SkillProcSuccess[e] && newbon->SkillProcSuccess[e] == spell_id)
|
||||
break; //Do not use the same spell id more than once.
|
||||
|
||||
else if(!newbon->SkillProcSuccess[e]){
|
||||
newbon->SkillProcSuccess[e] = spell_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
||||
if (IsAISpellEffect) {
|
||||
|
||||
|
||||
20
zone/bot.cpp
20
zone/bot.cpp
@ -3292,7 +3292,7 @@ bool Bot::CheckBotDoubleAttack(bool tripleAttack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod, int16 focus, bool CanRiposte)
|
||||
void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod, int16 focus, bool CanRiposte, int ReuseTime)
|
||||
{
|
||||
if (!CanDoSpecialAttack(other))
|
||||
return;
|
||||
@ -3396,10 +3396,11 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
||||
other->Stun(100);
|
||||
}
|
||||
|
||||
if (CanSkillProc && HasSkillProcs()){
|
||||
float chance = 10.0f*RuleR(Combat, AvgProcsPerMinute)/60000.0f;
|
||||
TrySkillProc(other, skillinuse, chance);
|
||||
}
|
||||
if (CanSkillProc && HasSkillProcs())
|
||||
TrySkillProc(other, skillinuse, ReuseTime);
|
||||
|
||||
if (CanSkillProc && (damage > 0) && HasSkillProcSuccess())
|
||||
TrySkillProc(other, skillinuse, ReuseTime, true);
|
||||
}
|
||||
|
||||
void Bot::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg) {
|
||||
@ -8102,10 +8103,11 @@ void Bot::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
||||
//who->Stun(100); Kayen: This effect does not stun on live, it only moves the NPC.
|
||||
}
|
||||
|
||||
if (HasSkillProcs()){
|
||||
float chance = (float)ReuseTime*RuleR(Combat, AvgProcsPerMinute)/60000.0f;
|
||||
TrySkillProc(who, skill, chance);
|
||||
}
|
||||
if (HasSkillProcs())
|
||||
TrySkillProc(who, skill, ReuseTime*1000);
|
||||
|
||||
if (max_damage > 0 && HasSkillProcSuccess())
|
||||
TrySkillProc(who, skill, ReuseTime*1000, true);
|
||||
|
||||
if(max_damage == -3 && !(who->GetHP() <= 0))
|
||||
DoRiposte(who);
|
||||
|
||||
@ -185,7 +185,7 @@ public:
|
||||
virtual void RogueAssassinate(Mob* other);
|
||||
virtual void DoClassAttacks(Mob *target, bool IsRiposte=false);
|
||||
virtual bool TryHeadShot(Mob* defender, SkillUseTypes skillInUse);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod=0, int16 focus=0, bool CanRiposte=false);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod=0, int16 focus=0, bool CanRiposte=false, int ReuseTime =0);
|
||||
virtual void ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg);
|
||||
bool CanDoSpecialAttack(Mob *other);
|
||||
virtual int32 CheckAggroAmount(uint16 spellid);
|
||||
|
||||
@ -9490,13 +9490,6 @@ void Client::CompleteConnect()
|
||||
AddRangedProc(GetProcID(buffs[j1].spellid, x1), 100+spells[buffs[j1].spellid].base2[x1],buffs[j1].spellid);
|
||||
break;
|
||||
}
|
||||
case SE_SkillProc2:
|
||||
case SE_SkillProc:
|
||||
{
|
||||
AddSkillProc(GetProcID(buffs[j1].spellid, x1), 100+spells[buffs[j1].spellid].base2[x1],buffs[j1].spellid);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,6 +375,9 @@ struct StatBonuses {
|
||||
bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others.
|
||||
int16 FactionModPct; // Modifies amount of faction gained.
|
||||
int16 MeleeVulnerability; // Weakness/mitigation to melee damage
|
||||
bool LimitToSkill[HIGHEST_SKILL+2]; // Determines if we need to search for a skill proc.
|
||||
uint16 SkillProc[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs.
|
||||
uint16 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success.
|
||||
|
||||
// AAs
|
||||
int8 Packrat; //weight reduction for items, 1 point = 10%
|
||||
|
||||
50
zone/mob.cpp
50
zone/mob.cpp
@ -3050,6 +3050,34 @@ void Mob::TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand, in
|
||||
return;
|
||||
|
||||
on->TryDefensiveProc(weapon, this, hand, damage);
|
||||
|
||||
//Defensive Skill Procs
|
||||
if (damage < 0 && damage >= -4) {
|
||||
uint16 skillinuse = 0;
|
||||
switch (damage) {
|
||||
case (-1):
|
||||
skillinuse = SkillBlock;
|
||||
break;
|
||||
|
||||
case (-2):
|
||||
skillinuse = SkillParry;
|
||||
break;
|
||||
|
||||
case (-3):
|
||||
skillinuse = SkillRiposte;
|
||||
break;
|
||||
|
||||
case (-4):
|
||||
skillinuse = SkillDodge;
|
||||
break;
|
||||
}
|
||||
|
||||
if (on->HasSkillProcs())
|
||||
on->TrySkillProc(this, skillinuse, 0, false, hand, true);
|
||||
|
||||
if (on->HasSkillProcSuccess())
|
||||
on->TrySkillProc(this, skillinuse, 0, true, hand, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::SetDeltas(float dx, float dy, float dz, float dh) {
|
||||
@ -4714,6 +4742,28 @@ bool Mob::PassLimitToSkill(uint16 spell_id, uint16 skill) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 Mob::GetWeaponSpeedbyHand(uint16 hand) {
|
||||
|
||||
uint16 weapon_speed = 0;
|
||||
switch (hand) {
|
||||
|
||||
case 13:
|
||||
weapon_speed = attack_timer.GetDuration();
|
||||
break;
|
||||
case 14:
|
||||
weapon_speed = attack_dw_timer.GetDuration();
|
||||
break;
|
||||
case 11:
|
||||
weapon_speed = ranged_timer.GetDuration();
|
||||
break;
|
||||
}
|
||||
|
||||
if (weapon_speed < RuleI(Combat, MinHastedDelay))
|
||||
weapon_speed = RuleI(Combat, MinHastedDelay);
|
||||
|
||||
return weapon_speed;
|
||||
}
|
||||
|
||||
int8 Mob::GetDecayEffectValue(uint16 spell_id, uint16 spelleffect) {
|
||||
|
||||
if (!IsValidSpell(spell_id))
|
||||
|
||||
13
zone/mob.h
13
zone/mob.h
@ -506,9 +506,8 @@ public:
|
||||
bool AddDefensiveProc(uint16 spell_id, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
|
||||
bool RemoveDefensiveProc(uint16 spell_id, bool bAll = false);
|
||||
bool HasDefensiveProcs() const;
|
||||
bool AddSkillProc(uint16 spell_id, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
|
||||
bool RemoveSkillProc(uint16 spell_id, bool bAll = false);
|
||||
bool HasSkillProcs() const;
|
||||
bool HasSkillProcSuccess() const;
|
||||
bool AddProcToWeapon(uint16 spell_id, bool bPerma = false, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
|
||||
bool RemoveProcFromWeapon(uint16 spell_id, bool bAll = false);
|
||||
bool HasProcs() const;
|
||||
@ -700,9 +699,9 @@ public:
|
||||
int32 ReduceAllDamage(int32 damage);
|
||||
|
||||
virtual void DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance=false, bool CanAvoid=true);
|
||||
virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const Item_Struct* item=nullptr, uint16 weapon_damage=0, int16 chance_mod=0,int16 focus=0);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod=0, int16 focus=0, bool CanRiposte=false);
|
||||
virtual void DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemInst* Ammo=nullptr, uint16 weapon_damage=0, int16 chance_mod=0, int16 focus=0);
|
||||
virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const Item_Struct* item=nullptr, uint16 weapon_damage=0, int16 chance_mod=0,int16 focus=0, int ReuseTime=0);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod=0, int16 focus=0, bool CanRiposte=false, int ReuseTime=0);
|
||||
virtual void DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemInst* Ammo=nullptr, uint16 weapon_damage=0, int16 chance_mod=0, int16 focus=0, int ReuseTime=0);
|
||||
bool CanDoSpecialAttack(Mob *other);
|
||||
bool Flurry(ExtraAttackOptions *opts);
|
||||
bool Rampage(ExtraAttackOptions *opts);
|
||||
@ -987,7 +986,7 @@ protected:
|
||||
bool focused;
|
||||
void CalcSpellBonuses(StatBonuses* newbon);
|
||||
virtual void CalcBonuses();
|
||||
void TrySkillProc(Mob *on, uint16 skill, float chance);
|
||||
void TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success = false, uint16 hand = 0, bool IsDefensive = false);
|
||||
bool PassLimitToSkill(uint16 spell_id, uint16 skill);
|
||||
bool PassLimitClass(uint32 Classes_, uint16 Class_);
|
||||
void TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand = 13, int damage=0);
|
||||
@ -999,6 +998,8 @@ protected:
|
||||
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed = 30, uint16 hand = 13);
|
||||
virtual float GetSpecialProcChances(uint16 hand);
|
||||
virtual float GetAssassinateProcChances(uint16 ReuseTime);
|
||||
virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0);
|
||||
uint16 GetWeaponSpeedbyHand(uint16 hand);
|
||||
int GetWeaponDamage(Mob *against, const Item_Struct *weapon_item);
|
||||
int GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate = nullptr);
|
||||
int GetKickDamage();
|
||||
|
||||
@ -171,11 +171,12 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
||||
//who->Stun(100); Kayen: This effect does not stun on live, it only moves the NPC.
|
||||
}
|
||||
|
||||
if (HasSkillProcs()){
|
||||
float chance = (float)ReuseTime*RuleR(Combat, AvgProcsPerMinute)/60000.0f;
|
||||
TrySkillProc(who, skill, chance);
|
||||
}
|
||||
|
||||
if (HasSkillProcs())
|
||||
TrySkillProc(who, skill, ReuseTime*1000);
|
||||
|
||||
if (max_damage > 0 && HasSkillProcSuccess())
|
||||
TrySkillProc(who, skill, ReuseTime*1000, true);
|
||||
|
||||
if(max_damage == -3 && !who->HasDied())
|
||||
DoRiposte(who);
|
||||
}
|
||||
@ -847,7 +848,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus)
|
||||
void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime)
|
||||
{
|
||||
if (!CanDoSpecialAttack(other))
|
||||
return;
|
||||
@ -967,20 +968,33 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item
|
||||
entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, FATAL_BOW_SHOT, GetName());
|
||||
|
||||
other->Damage(this, TotalDmg, SPELL_UNKNOWN, SkillArchery);
|
||||
|
||||
|
||||
if (TotalDmg > 0 && HasSkillProcSuccess() && GetTarget() && other && !other->HasDied()){
|
||||
if (ReuseTime)
|
||||
TrySkillProc(other, SkillArchery, ReuseTime);
|
||||
else
|
||||
TrySkillProc(other, SkillArchery, 0, true, 11);
|
||||
}
|
||||
}
|
||||
|
||||
//try proc on hits and misses
|
||||
if((RangeWeapon != nullptr) && GetTarget() && other && (other->GetHP() > -10))
|
||||
if((RangeWeapon != nullptr) && GetTarget() && other && !other->HasDied())
|
||||
{
|
||||
TryWeaponProc(RangeWeapon, other, 11);
|
||||
}
|
||||
|
||||
//Arrow procs because why not?
|
||||
if((Ammo != NULL) && GetTarget() && other && (other->GetHP() > -10))
|
||||
if((Ammo != NULL) && GetTarget() && other && !other->HasDied())
|
||||
{
|
||||
TryWeaponProc(Ammo, other, 11);
|
||||
}
|
||||
|
||||
if (HasSkillProcs() && GetTarget() && other && !other->HasDied()){
|
||||
if (ReuseTime)
|
||||
TrySkillProc(other, SkillArchery, ReuseTime);
|
||||
else
|
||||
TrySkillProc(other, SkillArchery, 0, false, 11);
|
||||
}
|
||||
}
|
||||
|
||||
void NPC::RangedAttack(Mob* other)
|
||||
@ -1253,7 +1267,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod,int16 focus)
|
||||
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime)
|
||||
{
|
||||
if (!CanDoSpecialAttack(other))
|
||||
return;
|
||||
@ -1309,10 +1323,25 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
TotalDmg = -5;
|
||||
|
||||
other->Damage(this, TotalDmg, SPELL_UNKNOWN, SkillThrowing);
|
||||
|
||||
if (TotalDmg > 0 && HasSkillProcSuccess() && GetTarget() && other && !other->HasDied()){
|
||||
if (ReuseTime)
|
||||
TrySkillProc(other, SkillThrowing, ReuseTime);
|
||||
else
|
||||
TrySkillProc(other, SkillThrowing, 0, true, 11);
|
||||
}
|
||||
}
|
||||
|
||||
if((RangeWeapon != nullptr) && GetTarget() && other && (other->GetHP() > -10))
|
||||
TryWeaponProc(RangeWeapon, other, 11);
|
||||
|
||||
if (HasSkillProcs() && GetTarget() && other && !other->HasDied()){
|
||||
if (ReuseTime)
|
||||
TrySkillProc(other, SkillThrowing, ReuseTime);
|
||||
else
|
||||
TrySkillProc(other, SkillThrowing, 0, false, 11);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Mob::SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skillInUse) {
|
||||
@ -1891,6 +1920,7 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) {
|
||||
Mob *hate_top = who->GetHateMost();
|
||||
|
||||
float level_difference = GetLevel() - who->GetLevel();
|
||||
bool Success = false;
|
||||
|
||||
//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)){
|
||||
@ -1903,7 +1933,7 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) {
|
||||
|
||||
int32 newhate = 0;
|
||||
float tauntchance = 50.0f;
|
||||
|
||||
|
||||
if(always_succeed)
|
||||
tauntchance = 101.0f;
|
||||
|
||||
@ -1940,6 +1970,7 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) {
|
||||
if (hate_top && hate_top != this){
|
||||
newhate = (who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1;
|
||||
who->CastToNPC()->AddToHateList(this, newhate);
|
||||
Success = true;
|
||||
}
|
||||
else
|
||||
who->CastToNPC()->AddToHateList(this,12);
|
||||
@ -1955,10 +1986,12 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) {
|
||||
else
|
||||
Message_StringID(MT_SpellFailure,FAILED_TAUNT);
|
||||
|
||||
if (HasSkillProcs()){
|
||||
float chance = (float)TauntReuseTime*RuleR(Combat, AvgProcsPerMinute)/60000.0f;
|
||||
TrySkillProc(who, SkillTaunt, chance);
|
||||
}
|
||||
if (HasSkillProcs())
|
||||
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000);
|
||||
|
||||
|
||||
if (Success && HasSkillProcSuccess())
|
||||
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000, true);
|
||||
}
|
||||
|
||||
|
||||
@ -2045,20 +2078,7 @@ float Mob::GetSpecialProcChances(uint16 hand)
|
||||
float ProcChance = 0.0f;
|
||||
float ProcBonus = 0.0f;
|
||||
|
||||
switch (hand) {
|
||||
case 13:
|
||||
weapon_speed = attack_timer.GetDuration();
|
||||
break;
|
||||
case 14:
|
||||
weapon_speed = attack_dw_timer.GetDuration();
|
||||
break;
|
||||
case 11:
|
||||
weapon_speed = ranged_timer.GetDuration();
|
||||
break;
|
||||
}
|
||||
|
||||
if (weapon_speed < RuleI(Combat, MinHastedDelay))
|
||||
weapon_speed = RuleI(Combat, MinHastedDelay);
|
||||
weapon_speed = GetWeaponSpeedbyHand(hand);
|
||||
|
||||
if (RuleB(Combat, AdjustSpecialProcPerMinute)) {
|
||||
ProcChance = (static_cast<float>(weapon_speed) *
|
||||
@ -2138,7 +2158,7 @@ float Mob::GetAssassinateProcChances(uint16 ReuseTime)
|
||||
return ProcChance;
|
||||
}
|
||||
|
||||
void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod, int16 focus, bool CanRiposte)
|
||||
void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod, int16 focus, bool CanRiposte, int ReuseTime)
|
||||
{
|
||||
if (!CanDoSpecialAttack(other))
|
||||
return;
|
||||
@ -2244,10 +2264,11 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
||||
SpellFinished(904, other, 10, 0, -1, spells[904].ResistDiff);
|
||||
}
|
||||
|
||||
if (CanSkillProc && HasSkillProcs()){
|
||||
float chance = 10.0f*RuleR(Combat, AvgProcsPerMinute)/60000.0f;
|
||||
TrySkillProc(other, skillinuse, chance);
|
||||
}
|
||||
if (CanSkillProc && HasSkillProcs())
|
||||
TrySkillProc(other, skillinuse, ReuseTime);
|
||||
|
||||
if (CanSkillProc && (damage > 0) && HasSkillProcSuccess())
|
||||
TrySkillProc(other, skillinuse, ReuseTime, true);
|
||||
}
|
||||
|
||||
bool Mob::CanDoSpecialAttack(Mob *other)
|
||||
|
||||
@ -1773,20 +1773,6 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_SkillProc2:
|
||||
case SE_SkillProc:
|
||||
{
|
||||
uint16 procid = GetProcID(spell_id, i);
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
snprintf(effect_desc, _EDLEN, "Weapon Proc: %s (id %d)", spells[effect_value].name, procid);
|
||||
#endif
|
||||
if(spells[spell_id].base2[i] == 0)
|
||||
AddSkillProc(procid, 100, spell_id);
|
||||
else
|
||||
AddSkillProc(procid, spells[spell_id].base2[i]+100, spell_id);
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_NegateAttacks:
|
||||
{
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
@ -2257,6 +2243,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
*Max is lower value then Weapon base, possibly min hit vs Weapon Damage range ie. MakeRandInt(max,base)
|
||||
*/
|
||||
int16 focus = 0;
|
||||
int ReuseTime = spells[spell_id].recast_time + spells[spell_id].recovery_time;
|
||||
|
||||
if(caster->IsClient())
|
||||
focus = caster->CastToClient()->GetFocusEffect(focusFcBaseEffects, spell_id);
|
||||
@ -2264,15 +2251,15 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
switch(spells[spell_id].skill)
|
||||
{
|
||||
case SkillThrowing:
|
||||
caster->DoThrowingAttackDmg(this, nullptr, nullptr, spells[spell_id].base[i],spells[spell_id].base2[i], focus);
|
||||
caster->DoThrowingAttackDmg(this, nullptr, nullptr, spells[spell_id].base[i],spells[spell_id].base2[i], focus, ReuseTime);
|
||||
break;
|
||||
|
||||
case SkillArchery:
|
||||
caster->DoArcheryAttackDmg(this, nullptr, nullptr, spells[spell_id].base[i],spells[spell_id].base2[i],focus);
|
||||
caster->DoArcheryAttackDmg(this, nullptr, nullptr, spells[spell_id].base[i],spells[spell_id].base2[i],focus,ReuseTime);
|
||||
break;
|
||||
|
||||
default:
|
||||
caster->DoMeleeSkillAttackDmg(this, spells[spell_id].base[i], spells[spell_id].skill, spells[spell_id].base2[i], focus);
|
||||
caster->DoMeleeSkillAttackDmg(this, spells[spell_id].base[i], spells[spell_id].skill, spells[spell_id].base2[i], focus, ReuseTime);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -2970,6 +2957,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
case SE_FactionModPct:
|
||||
case SE_LimitSpellClass:
|
||||
case SE_Sanctuary:
|
||||
case SE_PetMeleeMitigation:
|
||||
case SE_SkillProc:
|
||||
case SE_SkillProcSuccess:
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -3683,14 +3673,6 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_SkillProc2:
|
||||
case SE_SkillProc:
|
||||
{
|
||||
uint16 procid = GetProcID(buffs[slot].spellid, i);
|
||||
RemoveSkillProc(procid);
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_DefensiveProc:
|
||||
{
|
||||
uint16 procid = GetProcID(buffs[slot].spellid, i);
|
||||
|
||||
@ -5103,37 +5103,6 @@ bool Mob::RemoveDefensiveProc(uint16 spell_id, bool bAll)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mob::AddSkillProc(uint16 spell_id, uint16 iChance, uint16 base_spell_id)
|
||||
{
|
||||
if(spell_id == SPELL_UNKNOWN)
|
||||
return(false);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < MAX_PROCS; i++) {
|
||||
if (SkillProcs[i].spellID == SPELL_UNKNOWN) {
|
||||
SkillProcs[i].spellID = spell_id;
|
||||
SkillProcs[i].chance = iChance;
|
||||
SkillProcs[i].base_spellID = base_spell_id;
|
||||
mlog(SPELLS__PROCS, "Added spell-granted skill proc spell %d with chance %d to slot %d", spell_id, iChance, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mob::RemoveSkillProc(uint16 spell_id, bool bAll)
|
||||
{
|
||||
for (int i = 0; i < MAX_PROCS; i++) {
|
||||
if (bAll || SkillProcs[i].spellID == spell_id) {
|
||||
SkillProcs[i].spellID = SPELL_UNKNOWN;
|
||||
SkillProcs[i].chance = 0;
|
||||
SkillProcs[i].base_spellID = SPELL_UNKNOWN;
|
||||
mlog(SPELLS__PROCS, "Removed Skill proc %d from slot %d", spell_id, i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mob::AddRangedProc(uint16 spell_id, uint16 iChance, uint16 base_spell_id)
|
||||
{
|
||||
if(spell_id == SPELL_UNKNOWN)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user