mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Feature] New SPAs pass 1 (#1454)
* Implemented SPA Duration Pct Implemented new spell effects SE_Duration_HP_Pct 524 SE_Duration_Mana_Pct 525 SE_Duration_Endurance_Pct 526 Consumes 'base1' % of your maximum health/mana/endurance every 6 seconds. 'max' is maximum amount that can be consumed per tic. Additional Functionality Can be used as a heal/gain % by setting the base1 value to a positive. * Implemented SPA Instant Mana/End pct Fixes for SPA 524-526 Implemented SE_Instant_Mana_Pct 522 SE_Instant_Endurance_Pct 523 Extracts 'base1' percent of your maximum mana/endurance, or 'max', whichever is lower. * Implemented: SPA 521 EndAbsorbPctDmg Implemented SE_Endurance_Absorb_Pct_Damage 521 Absorb Damage using Endurance: base1 % (base2 End per 1 HP) Note: Both base1 and base2 need to be divided by 100 for actually value * Implemented SE_HealthTransfer 509 Implemented SE_Health_Transfer 509 'life burn' Consume base2 % of Hit Points to Damage for base % of Hit Points Can be used for heal Act of Valor * Implemented SPA 515,516,518,496 Implemented SE_AC_Avoidance_Max_Percent 515 SE_AC_Mitigation_Max_Percent 516 SE_Attack_Accuracy_Max_Percent 518 Above are stackable defense and offensive mods SE_Critical_Melee_Damage_Mod_Max 496 - This is a non stackable melee critical modifier * Implemented SPA 503 , 505 SE_Melee_Damage_Position_Mod 503 define SE_Damage_Taken_Position_Mod 505 SPA 503 increase/decreases melee damage by percent base1 based on your position base2 0=back 1=front SPA 504 increase/decreases melee damage taken by percent base1 based on your position base2 0=back 1=front * Implemented 467,468 Implemented SE_DS_Mitigation_Amount 467 SE_DS_Mitigation_Percentage 468 Reduce incoming DS by amt or percentage. base1 is value, if a reduction is desired it should be set to negative for both. * Fixes Formula fixes * Update spdat.h Added spa descriptions. * Fixes for PR removed debug shouts fixed description issue
This commit is contained in:
parent
a8e12c82a7
commit
8a2a1b152e
@ -62,6 +62,8 @@
|
||||
#define SPELL_SHAPECHANGE60 1924
|
||||
#define SPELL_COMMAND_OF_DRUZZIL 3355
|
||||
#define SPELL_SHAPECHANGE70 6503
|
||||
#define SPELL_MANA_BURN 2751
|
||||
#define SPELL_LIFE_BURN 2755
|
||||
// these have known hardcoded behavior but we don't do anything yet, move them above this comment when fixed
|
||||
#define SPELL_THE_DAINS_JUSTICE 1476
|
||||
#define SPELL_MODULATION 1502
|
||||
@ -152,7 +154,7 @@
|
||||
#define SPELL_RESURRECTION_SICKNESS 756
|
||||
#define SPELL_RESURRECTION_SICKNESS2 5249
|
||||
#define SPELL_REVIVAL_SICKNESS 13087
|
||||
#define SPELL_MANA_BURN 2751
|
||||
|
||||
|
||||
|
||||
#define EFFECT_COUNT 12
|
||||
@ -807,13 +809,13 @@ typedef enum {
|
||||
#define SE_PC_Pet_Rampage 464 // implemented - Base1 % chance to do rampage for base2 % of damage each melee round
|
||||
//#define SE_PC_Pet_AE_Rampage 465 // Would assume as above but need to confirm.
|
||||
#define SE_PC_Pet_Flurry_Chance 466 // implemented - Base1 % chance to do flurry from double attack hit.
|
||||
//#define SE_DS_Mitigation_Amount 467 //
|
||||
//#define SE_DS_Mitigation_Percentage 468 //
|
||||
#define SE_DS_Mitigation_Amount 467 // implemented - Modify incoming damage shield damage by a flat amount
|
||||
#define SE_DS_Mitigation_Percentage 468 // implemented - Modify incoming damage shield damage by percentage
|
||||
//#define SE_Chance_Best_in_Spell_Grp 469 //
|
||||
//#define SE_Trigger_Best_in_Spell Grp 470 //
|
||||
//#define SE_Double_Melee_Round 471 //
|
||||
//#define SE_Buy_AA_Rank 472 //
|
||||
//#define SE_Double_Backstab_Front 473 //
|
||||
#define SE_Double_Backstab_Front 473 // implemented - Chance to double backstab from front
|
||||
//#define SE_Pet_Crit_Melee_Damage_Pct_Owner 474 //
|
||||
//#define SE_Trigger_Spell_Non_Item 475 //
|
||||
//#define SE_Weapon_Stance 476 //
|
||||
@ -836,37 +838,37 @@ typedef enum {
|
||||
//#define SE_Ff_Endurance_Max 493 //
|
||||
//#define SE_Pet_Add_Atk 494 //
|
||||
//#define SE_Ff_DurationMax 495 //
|
||||
//#define SE_Critical_Melee_Damage_Mod_Max 496 //
|
||||
#define SE_Critical_Melee_Damage_Mod_Max 496 // implemented - increase or decrease by percent critical damage (not stackable)
|
||||
//#define SE_Ff_FocusCastProcNoBypass 497 //
|
||||
//#define SE_AddExtraAttackPct_1h_Primary 498 //
|
||||
//#define SE_AddExtraAttackPct_1h_Secondary 499 //
|
||||
//#define SE_Fc_CastTimeMod2 500 //
|
||||
//#define SE_Fc_CastTimeAmt 501 //
|
||||
//#define SE_Fearstun 502 //
|
||||
//#define SE_Melee_Damage_Position_Mod 503 //
|
||||
#define SE_Melee_Damage_Position_Mod 503 // implemented - modify melee damage by pct if done from Front or Behind
|
||||
//#define SE_Melee_Damage_Position_Amt 504 //
|
||||
//#define SE_Damage_Taken_Position_Mod 505 //
|
||||
#define SE_Damage_Taken_Position_Mod 505 // implemented - mitigate melee damage by pct if dmg taken from Front or Behind
|
||||
//#define SE_Damage_Taken_Position_Amt 506 //
|
||||
//#define SE_Fc_Amplify_Mod 507 //
|
||||
//#define SE_Fc_Amplify_Amt 508 //
|
||||
//#define SE_Health_Transfer 509 //
|
||||
#define SE_Health_Transfer 509 // implemented - exchange health for damage or healing on a target. ie Lifeburn/Act of Valor
|
||||
//#define SE_Fc_ResistIncoming 510 //
|
||||
//#define SE_Ff_FocusTimerMin 511 //
|
||||
//#define SE_Proc_Timer_Modifier 512 //
|
||||
//#define SE_Mana_Max_Percent 513 //
|
||||
//#define SE_Endurance_Max_Percent 514 //
|
||||
//#define SE_AC_Avoidance_Max_Percent 515 //
|
||||
//#define SE_AC_Mitigation_Max_Percent 516 //
|
||||
//#define SE_Attack_Offense_Max_Percent 517 //
|
||||
//#define SE_Attack_Accuracy_Max_Percent 518 //
|
||||
#define SE_AC_Avoidance_Max_Percent 515 // implemented - stackable avoidance modifier
|
||||
#define SE_AC_Mitigation_Max_Percent 516 // implemented - stackable defense modifier
|
||||
//#define SE_Attack_Offense_Max_Percent 517 //
|
||||
#define SE_Attack_Accuracy_Max_Percent 518 // implemented - stackable accurary modifer
|
||||
//#define SE_Luck_Amount 519 //
|
||||
//#define SE_Luck_Percent 520 //
|
||||
//#define SE_Endurance_Absorb_Pct_Damage 521 //
|
||||
//#define SE_Instant_Mana_Pct 522 //
|
||||
//#define SE_Instant_Endurance_Pct 523 //
|
||||
//#define SE_Duration_HP_Pct 524 //
|
||||
//#define SE_Duration_Mana_Pct 525 //
|
||||
//#define SE_Duration_Endurance_Pct 526 //
|
||||
#define SE_Endurance_Absorb_Pct_Damage 521 // implemented - Reduces % of Damage using Endurance, drains endurance at a ratio (ie. 0.05 Endurance per Hit Point)
|
||||
#define SE_Instant_Mana_Pct 522 // implemented - Increase/Decrease mana by percent of max mana
|
||||
#define SE_Instant_Endurance_Pct 523 // implemented - Increase/Decrease mana by percent of max endurance
|
||||
#define SE_Duration_HP_Pct 524 // implemented - Decrease Current Hit Points by % of Total Hit Points per Tick, up to a MAX per tick
|
||||
#define SE_Duration_Mana_Pct 525 // implemented - Decrease Current Mana by % of Total Mana per Tick, up to a MAX per tick
|
||||
#define SE_Duration_Endurance_Pct 526 // implemented - Decrease Current Endurance by % of Total Hit Points per Tick, up to a MAX per tick
|
||||
|
||||
|
||||
// LAST
|
||||
|
||||
@ -188,6 +188,11 @@ int Mob::GetTotalToHit(EQ::skills::SkillType skill, int chance_mod)
|
||||
if (skill != EQ::skills::SkillArchery && skill != EQ::skills::SkillThrowing)
|
||||
accuracy += itembonuses.HitChance;
|
||||
|
||||
//518 Increase ATK accuracy by percentage, stackable
|
||||
auto atkhit_bonus = itembonuses.Attack_Accuracy_Max_Percent + aabonuses.Attack_Accuracy_Max_Percent + spellbonuses.Attack_Accuracy_Max_Percent;
|
||||
if (atkhit_bonus)
|
||||
accuracy += round(static_cast<double>(accuracy) * static_cast<double>(atkhit_bonus) * 0.0001);
|
||||
|
||||
// 216 Melee Accuracy Amt aka SE_Accuracy -- flat bonus
|
||||
accuracy += itembonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
aabonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
@ -233,6 +238,11 @@ int Mob::compute_defense()
|
||||
if (IsClient())
|
||||
defense += CastToClient()->GetHeroicAGI() / 10;
|
||||
|
||||
//516 SE_AC_Mitigation_Max_Percent
|
||||
auto ac_bonus = itembonuses.AC_Mitigation_Max_Percent + aabonuses.AC_Mitigation_Max_Percent + spellbonuses.AC_Mitigation_Max_Percent;
|
||||
if (ac_bonus)
|
||||
defense += round(static_cast<double>(defense) * static_cast<double>(ac_bonus) * 0.0001);
|
||||
|
||||
defense += itembonuses.AvoidMeleeChance; // item mod2
|
||||
if (IsNPC())
|
||||
defense += CastToNPC()->GetAvoidanceRating();
|
||||
@ -255,7 +265,12 @@ int Mob::GetTotalDefense()
|
||||
auto evasion_bonus = spellbonuses.AvoidMeleeChanceEffect; // we check this first since it has a special case
|
||||
if (evasion_bonus >= 10000)
|
||||
return -1;
|
||||
//
|
||||
|
||||
// 515 SE_AC_Avoidance_Max_Percent
|
||||
auto ac_aviodance_bonus = itembonuses.AC_Avoidance_Max_Percent + aabonuses.AC_Avoidance_Max_Percent + spellbonuses.AC_Avoidance_Max_Percent;
|
||||
if (ac_aviodance_bonus)
|
||||
avoidance += round(static_cast<double>(avoidance) * static_cast<double>(ac_aviodance_bonus) * 0.0001);
|
||||
|
||||
// 172 Evasion aka SE_AvoidMeleeChance
|
||||
evasion_bonus += itembonuses.AvoidMeleeChanceEffect + aabonuses.AvoidMeleeChanceEffect; // item bonus here isn't mod2 avoidance
|
||||
|
||||
@ -2887,6 +2902,10 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
|
||||
|
||||
DS += aabonuses.DamageShield; //Live AA - coat of thistles. (negative value)
|
||||
DS -= itembonuses.DamageShield; //+Damage Shield should only work when you already have a DS spell
|
||||
DS -= attacker->aabonuses.DS_Mitigation_Amount + attacker->itembonuses.DS_Mitigation_Amount + attacker->spellbonuses.DS_Mitigation_Amount; //Negative value to reduce
|
||||
//Do not allow flat amount reductions to reduce past 0.
|
||||
if (DS >= 0)
|
||||
return;
|
||||
|
||||
//Spell data for damage shield mitigation shows a negative value for spells for clients and positive
|
||||
//value for spells that effect pets. Unclear as to why. For now will convert all positive to be consistent.
|
||||
@ -2896,7 +2915,12 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
|
||||
attacker->aabonuses.DSMitigationOffHand;
|
||||
DS -= DS*mitigation / 100;
|
||||
}
|
||||
DS -= DS * attacker->itembonuses.DSMitigation / 100;
|
||||
|
||||
int ds_mitigation = attacker->itembonuses.DSMitigation;
|
||||
// Subtract mitigations because DS_Mitigation_Percentage is a negative value when reducing total, thus final value will be positive
|
||||
ds_mitigation -= attacker->aabonuses.DS_Mitigation_Percentage + attacker->itembonuses.DS_Mitigation_Percentage + attacker->spellbonuses.DS_Mitigation_Percentage; //Negative value to reduce
|
||||
|
||||
DS -= DS * ds_mitigation / 100;
|
||||
}
|
||||
attacker->Damage(this, -DS, spellid, EQ::skills::SkillAbjuration/*hackish*/, false);
|
||||
//we can assume there is a spell now
|
||||
@ -3323,8 +3347,8 @@ int32 Mob::ReduceAllDamage(int32 damage)
|
||||
if (damage <= 0)
|
||||
return damage;
|
||||
|
||||
if (spellbonuses.ManaAbsorbPercentDamage[0]) {
|
||||
int32 mana_reduced = damage * spellbonuses.ManaAbsorbPercentDamage[0] / 100;
|
||||
if (spellbonuses.ManaAbsorbPercentDamage) {
|
||||
int32 mana_reduced = damage * spellbonuses.ManaAbsorbPercentDamage / 100;
|
||||
if (GetMana() >= mana_reduced) {
|
||||
damage -= mana_reduced;
|
||||
SetMana(GetMana() - mana_reduced);
|
||||
@ -3332,6 +3356,19 @@ int32 Mob::ReduceAllDamage(int32 damage)
|
||||
}
|
||||
}
|
||||
|
||||
if (spellbonuses.EnduranceAbsorbPercentDamage[0]) {
|
||||
int32 damage_reduced = damage * spellbonuses.EnduranceAbsorbPercentDamage[0] / 10000; //If hit for 1000, at 10% then lower damage by 100;
|
||||
int32 endurance_drain = damage_reduced * spellbonuses.EnduranceAbsorbPercentDamage[1] / 10000; //Reduce endurance by 0.05% per HP loss
|
||||
if (endurance_drain < 1)
|
||||
endurance_drain = 1;
|
||||
|
||||
if (IsClient() && CastToClient()->GetEndurance() >= endurance_drain) {
|
||||
damage -= damage_reduced;
|
||||
CastToClient()->SetEndurance(CastToClient()->GetEndurance() - endurance_drain);
|
||||
TryTriggerOnValueAmount(false, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
CheckNumHitsRemaining(NumHit::IncomingDamage);
|
||||
|
||||
return(damage);
|
||||
@ -4628,6 +4665,7 @@ void Mob::ApplyMeleeDamageMods(uint16 skill, int &damage, Mob *defender, ExtraAt
|
||||
int dmgbonusmod = 0;
|
||||
|
||||
dmgbonusmod += GetMeleeDamageMod_SE(skill);
|
||||
dmgbonusmod += GetMeleeDmgPositionMod(defender);
|
||||
if (opts)
|
||||
dmgbonusmod += opts->melee_damage_bonus_flat;
|
||||
|
||||
@ -5241,7 +5279,9 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
||||
if (spec_mod > 0)
|
||||
hit.damage_done = (hit.damage_done * spec_mod) / 100;
|
||||
|
||||
hit.damage_done += (hit.damage_done * defender->GetSkillDmgTaken(hit.skill, opts) / 100) + (defender->GetFcDamageAmtIncoming(this, 0, true, hit.skill));
|
||||
int pct_damage_reduction = defender->GetSkillDmgTaken(hit.skill, opts) + defender->GetPositionalDmgTaken(this);
|
||||
|
||||
hit.damage_done += (hit.damage_done * pct_damage_reduction / 100) + (defender->GetFcDamageAmtIncoming(this, 0, true, hit.skill));
|
||||
|
||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||
}
|
||||
|
||||
218
zone/bonuses.cpp
218
zone/bonuses.cpp
@ -978,6 +978,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
case SE_FrontalBackstabChance:
|
||||
newbon->FrontalBackstabChance += base1;
|
||||
break;
|
||||
case SE_Double_Backstab_Front:
|
||||
newbon->Double_Backstab_Front += base1;
|
||||
break;
|
||||
case SE_BlockBehind:
|
||||
newbon->BlockBehind += base1;
|
||||
break;
|
||||
@ -1102,6 +1105,19 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Critical_Melee_Damage_Mod_Max:
|
||||
{
|
||||
// Bad data or unsupported new skill
|
||||
if (base2 > EQ::skills::HIGHEST_SKILL)
|
||||
break;
|
||||
int skill = base2 == ALL_SKILLS ? EQ::skills::HIGHEST_SKILL + 1 : base2;
|
||||
if (base1 < 0 && newbon->CritDmgModNoStack[skill] > base1)
|
||||
newbon->CritDmgModNoStack[skill] = base1;
|
||||
else if (base1 > 0 && newbon->CritDmgModNoStack[skill] < base1)
|
||||
newbon->CritDmgModNoStack[skill] = base1;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_CriticalSpellChance: {
|
||||
newbon->CriticalSpellChance += base1;
|
||||
|
||||
@ -1487,6 +1503,50 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
}
|
||||
break;
|
||||
|
||||
case SE_Attack_Accuracy_Max_Percent:
|
||||
newbon->Attack_Accuracy_Max_Percent += base1;
|
||||
break;
|
||||
|
||||
case SE_AC_Mitigation_Max_Percent:
|
||||
newbon->AC_Mitigation_Max_Percent += base1;
|
||||
break;
|
||||
|
||||
case SE_AC_Avoidance_Max_Percent:
|
||||
newbon->AC_Avoidance_Max_Percent += base1;
|
||||
break;
|
||||
|
||||
case SE_Damage_Taken_Position_Mod:
|
||||
{
|
||||
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||
if (base2 < 0 || base2 > 2)
|
||||
break;
|
||||
else if (base1 < 0 && newbon->Damage_Taken_Position_Mod[base2] > base1)
|
||||
newbon->Damage_Taken_Position_Mod[base2] = base1;
|
||||
else if (base1 > 0 && newbon->Damage_Taken_Position_Mod[base2] < base1)
|
||||
newbon->Damage_Taken_Position_Mod[base2] = base1;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Melee_Damage_Position_Mod:
|
||||
{
|
||||
if (base2 < 0 || base2 > 2)
|
||||
break;
|
||||
else if (base1 < 0 && newbon->Melee_Damage_Position_Mod[base2] > base1)
|
||||
newbon->Melee_Damage_Position_Mod[base2] = base1;
|
||||
else if (base1 > 0 && newbon->Melee_Damage_Position_Mod[base2] < base1)
|
||||
newbon->Melee_Damage_Position_Mod[base2] = base1;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_DS_Mitigation_Amount:
|
||||
newbon->DS_Mitigation_Amount += base1;
|
||||
break;
|
||||
|
||||
case SE_DS_Mitigation_Percentage:
|
||||
newbon->DS_Mitigation_Percentage += base1;
|
||||
break;
|
||||
|
||||
|
||||
// to do
|
||||
case SE_PetDiscipline:
|
||||
break;
|
||||
@ -2485,6 +2545,20 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Critical_Melee_Damage_Mod_Max:
|
||||
{
|
||||
// Bad data or unsupported new skill
|
||||
if (base2 > EQ::skills::HIGHEST_SKILL)
|
||||
break;
|
||||
int skill = base2 == ALL_SKILLS ? EQ::skills::HIGHEST_SKILL + 1 : base2;
|
||||
if (effect_value < 0 && new_bonus->CritDmgModNoStack[skill] > effect_value)
|
||||
new_bonus->CritDmgModNoStack[skill] = effect_value;
|
||||
else if (effect_value > 0 && new_bonus->CritDmgModNoStack[skill] < effect_value) {
|
||||
new_bonus->CritDmgModNoStack[skill] = effect_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_ReduceSkillTimer:
|
||||
{
|
||||
if(new_bonus->SkillReuseTime[base2] < effect_value)
|
||||
@ -2690,9 +2764,17 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
|
||||
case SE_ManaAbsorbPercentDamage:
|
||||
{
|
||||
if (new_bonus->ManaAbsorbPercentDamage[0] < effect_value){
|
||||
new_bonus->ManaAbsorbPercentDamage[0] = effect_value;
|
||||
new_bonus->ManaAbsorbPercentDamage[1] = buffslot;
|
||||
if (new_bonus->ManaAbsorbPercentDamage < effect_value){
|
||||
new_bonus->ManaAbsorbPercentDamage = effect_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Endurance_Absorb_Pct_Damage:
|
||||
{
|
||||
if (new_bonus->EnduranceAbsorbPercentDamage[0] < effect_value) {
|
||||
new_bonus->EnduranceAbsorbPercentDamage[0] = effect_value;
|
||||
new_bonus->EnduranceAbsorbPercentDamage[1] = base2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2762,6 +2844,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
new_bonus->FrontalBackstabChance += effect_value;
|
||||
break;
|
||||
|
||||
case SE_Double_Backstab_Front:
|
||||
new_bonus->Double_Backstab_Front += effect_value;
|
||||
break;
|
||||
|
||||
case SE_ConsumeProjectile:
|
||||
new_bonus->ConsumeProjectile += effect_value;
|
||||
break;
|
||||
@ -3250,6 +3336,57 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
if (new_bonus->trap_slots < effect_value)
|
||||
new_bonus->trap_slots = effect_value;
|
||||
break;
|
||||
|
||||
case SE_Attack_Accuracy_Max_Percent:
|
||||
new_bonus->Attack_Accuracy_Max_Percent += effect_value;
|
||||
break;
|
||||
|
||||
|
||||
case SE_AC_Mitigation_Max_Percent:
|
||||
new_bonus->AC_Mitigation_Max_Percent += effect_value;
|
||||
break;
|
||||
|
||||
case SE_AC_Avoidance_Max_Percent:
|
||||
new_bonus->AC_Avoidance_Max_Percent += effect_value;
|
||||
break;
|
||||
|
||||
case SE_Damage_Taken_Position_Mod:
|
||||
{
|
||||
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||
if (base2 < 0 || base2 > 2)
|
||||
break;
|
||||
if (AdditiveWornBonus)
|
||||
new_bonus->Damage_Taken_Position_Mod[base2] += effect_value;
|
||||
else if (effect_value < 0 && new_bonus->Damage_Taken_Position_Mod[base2] > effect_value)
|
||||
new_bonus->Damage_Taken_Position_Mod[base2] = effect_value;
|
||||
else if (effect_value > 0 && new_bonus->Damage_Taken_Position_Mod[base2] < effect_value)
|
||||
new_bonus->Damage_Taken_Position_Mod[base2] = effect_value;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Melee_Damage_Position_Mod:
|
||||
{
|
||||
//Increase damage by percent from behind base2 = 0, from front base2 = 1
|
||||
if (base2 < 0 || base2 > 2)
|
||||
break;
|
||||
if (AdditiveWornBonus)
|
||||
new_bonus->Melee_Damage_Position_Mod[base2] += effect_value;
|
||||
else if (effect_value < 0 && new_bonus->Melee_Damage_Position_Mod[base2] > effect_value)
|
||||
new_bonus->Melee_Damage_Position_Mod[base2] = effect_value;
|
||||
else if (effect_value > 0 && new_bonus->Melee_Damage_Position_Mod[base2] < effect_value)
|
||||
new_bonus->Melee_Damage_Position_Mod[base2] = effect_value;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_DS_Mitigation_Amount:
|
||||
new_bonus->DS_Mitigation_Amount += effect_value;
|
||||
break;
|
||||
|
||||
case SE_DS_Mitigation_Percentage:
|
||||
new_bonus->DS_Mitigation_Percentage += effect_value;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
||||
if (IsAISpellEffect) {
|
||||
@ -4258,6 +4395,17 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Critical_Melee_Damage_Mod_Max:
|
||||
{
|
||||
for (int e = 0; e < EQ::skills::HIGHEST_SKILL + 1; e++)
|
||||
{
|
||||
spellbonuses.CritDmgModNoStack[e] = effect_value;
|
||||
aabonuses.CritDmgModNoStack[e] = effect_value;
|
||||
itembonuses.CritDmgModNoStack[e] = effect_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_SkillDamageAmount:
|
||||
{
|
||||
for (int e = 0; e < EQ::skills::HIGHEST_SKILL + 1; e++)
|
||||
@ -4353,8 +4501,12 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
break;
|
||||
|
||||
case SE_ManaAbsorbPercentDamage:
|
||||
spellbonuses.ManaAbsorbPercentDamage[0] = effect_value;
|
||||
spellbonuses.ManaAbsorbPercentDamage[1] = -1;
|
||||
spellbonuses.ManaAbsorbPercentDamage = effect_value;
|
||||
break;
|
||||
|
||||
case SE_Endurance_Absorb_Pct_Damage:
|
||||
spellbonuses.EnduranceAbsorbPercentDamage[0] = effect_value;
|
||||
spellbonuses.EnduranceAbsorbPercentDamage[1] = effect_value;
|
||||
break;
|
||||
|
||||
case SE_ShieldBlock:
|
||||
@ -4428,6 +4580,12 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
itembonuses.FrontalBackstabChance = effect_value;
|
||||
break;
|
||||
|
||||
case SE_Double_Backstab_Front:
|
||||
spellbonuses.Double_Backstab_Front = effect_value;
|
||||
aabonuses.Double_Backstab_Front = effect_value;
|
||||
itembonuses.Double_Backstab_Front = effect_value;
|
||||
break;
|
||||
|
||||
case SE_ConsumeProjectile:
|
||||
spellbonuses.ConsumeProjectile = effect_value;
|
||||
aabonuses.ConsumeProjectile = effect_value;
|
||||
@ -4770,6 +4928,56 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
aabonuses.IllusionPersistence = false;
|
||||
break;
|
||||
|
||||
case SE_Attack_Accuracy_Max_Percent:
|
||||
spellbonuses.Attack_Accuracy_Max_Percent = effect_value;
|
||||
itembonuses.Attack_Accuracy_Max_Percent = effect_value;
|
||||
aabonuses.Attack_Accuracy_Max_Percent = effect_value;
|
||||
break;
|
||||
|
||||
|
||||
case SE_AC_Mitigation_Max_Percent:
|
||||
spellbonuses.AC_Mitigation_Max_Percent = effect_value;
|
||||
itembonuses.AC_Mitigation_Max_Percent = effect_value;
|
||||
aabonuses.AC_Mitigation_Max_Percent = effect_value;
|
||||
break;
|
||||
|
||||
case SE_AC_Avoidance_Max_Percent:
|
||||
spellbonuses.AC_Avoidance_Max_Percent = effect_value;
|
||||
itembonuses.AC_Avoidance_Max_Percent = effect_value;
|
||||
aabonuses.AC_Avoidance_Max_Percent = effect_value;
|
||||
break;
|
||||
|
||||
case SE_Melee_Damage_Position_Mod:
|
||||
spellbonuses.Melee_Damage_Position_Mod[0] = effect_value;
|
||||
aabonuses.Melee_Damage_Position_Mod[0] = effect_value;
|
||||
itembonuses.Melee_Damage_Position_Mod[0] = effect_value;
|
||||
spellbonuses.Melee_Damage_Position_Mod[1] = effect_value;
|
||||
aabonuses.Melee_Damage_Position_Mod[1] = effect_value;
|
||||
itembonuses.Melee_Damage_Position_Mod[1] = effect_value;
|
||||
break;
|
||||
|
||||
case SE_Damage_Taken_Position_Mod:
|
||||
spellbonuses.Damage_Taken_Position_Mod[0] = effect_value;
|
||||
aabonuses.Damage_Taken_Position_Mod[0] = effect_value;
|
||||
itembonuses.Damage_Taken_Position_Mod[0] = effect_value;
|
||||
spellbonuses.Damage_Taken_Position_Mod[1] = effect_value;
|
||||
aabonuses.Damage_Taken_Position_Mod[1] = effect_value;
|
||||
itembonuses.Damage_Taken_Position_Mod[1] = effect_value;
|
||||
break;
|
||||
|
||||
|
||||
case SE_DS_Mitigation_Amount:
|
||||
spellbonuses.DS_Mitigation_Amount = effect_value;
|
||||
itembonuses.DS_Mitigation_Amount = effect_value;
|
||||
aabonuses.DS_Mitigation_Amount = effect_value;
|
||||
break;
|
||||
|
||||
case SE_DS_Mitigation_Percentage:
|
||||
spellbonuses.DS_Mitigation_Percentage = effect_value;
|
||||
itembonuses.DS_Mitigation_Percentage = effect_value;
|
||||
aabonuses.DS_Mitigation_Percentage = effect_value;
|
||||
break;
|
||||
|
||||
case SE_SkillProcSuccess:{
|
||||
for(int e = 0; e < MAX_SKILL_PROCS; e++)
|
||||
{
|
||||
|
||||
@ -461,6 +461,7 @@ struct StatBonuses {
|
||||
uint32 SpellOnKill[MAX_SPELL_TRIGGER*3]; // Chance to proc after killing a mob
|
||||
uint32 SpellOnDeath[MAX_SPELL_TRIGGER*2]; // Chance to have effect cast when you die
|
||||
int32 CritDmgMod[EQ::skills::HIGHEST_SKILL + 2]; // All Skills + -1
|
||||
int32 CritDmgModNoStack[EQ::skills::HIGHEST_SKILL + 2];// Critical melee damage modifier by percent, does not stack.
|
||||
int32 SkillReuseTime[EQ::skills::HIGHEST_SKILL + 1]; // Reduces skill timers
|
||||
int32 SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 2]; // All Skills + -1
|
||||
int32 TwoHandBluntBlock; // chance to block when wielding two hand blunt weapon
|
||||
@ -494,7 +495,8 @@ struct StatBonuses {
|
||||
uint32 MitigateDotRune[4]; // 0 = Mitigation value 1 = Buff Slot 2 = Max mitigation per tick 3 = Rune Amt
|
||||
bool TriggerMeleeThreshold; // Has Melee Threshhold
|
||||
bool TriggerSpellThreshold; // Has Spell Threshhold
|
||||
uint32 ManaAbsorbPercentDamage[2]; // 0 = Mitigation value 1 = Buff Slot
|
||||
uint32 ManaAbsorbPercentDamage; // 0 = Mitigation value
|
||||
int32 EnduranceAbsorbPercentDamage[2]; // 0 = Mitigation value 1 = Percent Endurance drain per HP lost
|
||||
int32 ShieldBlock; // Chance to Shield Block
|
||||
int32 BlockBehind; // Chance to Block Behind (with our without shield)
|
||||
bool CriticalRegenDecay; // increase critical regen chance, decays based on spell level cast
|
||||
@ -523,6 +525,14 @@ struct StatBonuses {
|
||||
uint32 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success.
|
||||
uint32 PC_Pet_Rampage[2]; // 0= % chance to rampage, 1=damage modifier
|
||||
uint32 PC_Pet_Flurry; // Percent chance flurry from double attack
|
||||
int32 Attack_Accuracy_Max_Percent; // Increase ATK accuracy by percent.
|
||||
int32 AC_Mitigation_Max_Percent; // Increase AC mitigation by percent
|
||||
int32 AC_Avoidance_Max_Percent; // Increase AC avoidance by percent
|
||||
int32 Damage_Taken_Position_Mod[2]; // base = percent melee damage reduction base2 0=back 1=front. [0]Back[1]Front
|
||||
int32 Melee_Damage_Position_Mod[2]; // base = percent melee damage increase base2 0=back 1=front. [0]Back[1]Front
|
||||
int32 Double_Backstab_Front; // base = percent chance to double back stab front
|
||||
int32 DS_Mitigation_Amount; // base = flat amt DS mitigation. Negative value to reduce
|
||||
int32 DS_Mitigation_Percentage; // base = percent amt of DS mitigation. Negative value to reduce
|
||||
|
||||
// AAs
|
||||
int8 Packrat; //weight reduction for items, 1 point = 10%
|
||||
|
||||
@ -1162,7 +1162,7 @@ uint32 Lua_StatBonuses::GetMitigateDotRune(int idx) const {
|
||||
|
||||
uint32 Lua_StatBonuses::GetManaAbsorbPercentDamage(int idx) const {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->ManaAbsorbPercentDamage[idx];
|
||||
return self->ManaAbsorbPercentDamage;
|
||||
}
|
||||
|
||||
int32 Lua_StatBonuses::GetImprovedTaunt(int idx) const {
|
||||
|
||||
89
zone/mob.cpp
89
zone/mob.cpp
@ -3711,6 +3711,32 @@ void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id)
|
||||
}
|
||||
}
|
||||
|
||||
//Used for effects that should occur after the completion of the spell
|
||||
void Mob::TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id)
|
||||
{
|
||||
if (!IsValidSpell(spell_id))
|
||||
return;
|
||||
|
||||
/*Apply damage from Lifeburn type effects on caster at end of spell cast.
|
||||
This allows for the AE spells to function without repeatedly killing caster
|
||||
Damage or heal portion can be found as regular single use spell effect
|
||||
*/
|
||||
if (IsEffectInSpell(spell_id, SE_Health_Transfer)){
|
||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||
|
||||
if (spells[spell_id].effectid[i] == SE_Health_Transfer) {
|
||||
int new_hp = GetMaxHP();
|
||||
new_hp -= GetMaxHP() * spells[spell_id].base[i] / 1000;
|
||||
|
||||
if (new_hp > 0)
|
||||
SetHP(new_hp);
|
||||
else
|
||||
Kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
|
||||
{
|
||||
if (!IsValidSpell(spell_id))
|
||||
@ -3771,7 +3797,7 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
|
||||
return value;
|
||||
}
|
||||
|
||||
int16 Mob::GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackOptions *opts)
|
||||
int32 Mob::GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackOptions *opts)
|
||||
{
|
||||
int skilldmg_mod = 0;
|
||||
|
||||
@ -3790,6 +3816,33 @@ int16 Mob::GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackO
|
||||
return skilldmg_mod;
|
||||
}
|
||||
|
||||
int32 Mob::GetPositionalDmgTaken(Mob *attacker)
|
||||
{
|
||||
if (!attacker)
|
||||
return 0;
|
||||
|
||||
int front_arc = 0;
|
||||
int back_arc = 0;
|
||||
int total_mod = 0;
|
||||
|
||||
back_arc += itembonuses.Damage_Taken_Position_Mod[0] + aabonuses.Damage_Taken_Position_Mod[0] + spellbonuses.Damage_Taken_Position_Mod[0];
|
||||
front_arc += itembonuses.Damage_Taken_Position_Mod[1] + aabonuses.Damage_Taken_Position_Mod[1] + spellbonuses.Damage_Taken_Position_Mod[1];
|
||||
|
||||
if (back_arc || front_arc) { //Do they have this bonus?
|
||||
if (attacker->BehindMob(this, attacker->GetX(), attacker->GetY()))//Check if attacker is striking from behind
|
||||
total_mod = back_arc; //If so, apply the back arc modifier only
|
||||
else
|
||||
total_mod = front_arc;//If not, apply the front arc modifer only
|
||||
}
|
||||
|
||||
total_mod = round(static_cast<double>(total_mod) * 0.1);
|
||||
|
||||
if (total_mod < -100)
|
||||
total_mod = -100;
|
||||
|
||||
return total_mod;
|
||||
}
|
||||
|
||||
int16 Mob::GetHealRate(uint16 spell_id, Mob* caster) {
|
||||
|
||||
int16 heal_rate = 0;
|
||||
@ -4598,10 +4651,13 @@ int16 Mob::GetCritDmgMod(uint16 skill)
|
||||
{
|
||||
int critDmg_mod = 0;
|
||||
|
||||
// All skill dmg mod + Skill specific
|
||||
// All skill dmg mod + Skill specific [SPA 330 and 496]
|
||||
critDmg_mod += itembonuses.CritDmgMod[EQ::skills::HIGHEST_SKILL + 1] + spellbonuses.CritDmgMod[EQ::skills::HIGHEST_SKILL + 1] + aabonuses.CritDmgMod[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
itembonuses.CritDmgMod[skill] + spellbonuses.CritDmgMod[skill] + aabonuses.CritDmgMod[skill];
|
||||
|
||||
critDmg_mod += itembonuses.CritDmgModNoStack[EQ::skills::HIGHEST_SKILL + 1] + spellbonuses.CritDmgModNoStack[EQ::skills::HIGHEST_SKILL + 1] + aabonuses.CritDmgModNoStack[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
itembonuses.CritDmgModNoStack[skill] + spellbonuses.CritDmgModNoStack[skill] + aabonuses.CritDmgModNoStack[skill];
|
||||
|
||||
return critDmg_mod;
|
||||
}
|
||||
|
||||
@ -4692,6 +4748,35 @@ int16 Mob::GetCrippBlowChance()
|
||||
return crip_chance;
|
||||
}
|
||||
|
||||
|
||||
int16 Mob::GetMeleeDmgPositionMod(Mob* defender)
|
||||
{
|
||||
if (!defender)
|
||||
return 0;
|
||||
|
||||
int front_arc = 0;
|
||||
int back_arc = 0;
|
||||
int total_mod = 0;
|
||||
|
||||
back_arc += itembonuses.Melee_Damage_Position_Mod[0] + aabonuses.Melee_Damage_Position_Mod[0] + spellbonuses.Melee_Damage_Position_Mod[0];
|
||||
front_arc += itembonuses.Melee_Damage_Position_Mod[1] + aabonuses.Melee_Damage_Position_Mod[1] + spellbonuses.Melee_Damage_Position_Mod[1];
|
||||
|
||||
if (back_arc || front_arc) { //Do they have this bonus?
|
||||
if (BehindMob(defender, GetX(), GetY()))//Check if attacker is striking from behind
|
||||
total_mod = back_arc; //If so, apply the back arc modifier only
|
||||
else
|
||||
total_mod = front_arc;//If not, apply the front arc modifer only
|
||||
}
|
||||
|
||||
total_mod = round(static_cast<double>(total_mod) * 0.1);
|
||||
|
||||
if (total_mod < -100)
|
||||
total_mod = -100;
|
||||
|
||||
return total_mod;
|
||||
|
||||
}
|
||||
|
||||
int16 Mob::GetSkillReuseTime(uint16 skill)
|
||||
{
|
||||
int skill_reduction = this->itembonuses.SkillReuseTime[skill] + this->spellbonuses.SkillReuseTime[skill] + this->aabonuses.SkillReuseTime[skill];
|
||||
|
||||
@ -353,6 +353,7 @@ public:
|
||||
void CalcDestFromHeading(float heading, float distance, float MaxZDiff, float StartX, float StartY, float &dX, float &dY, float &dZ);
|
||||
void BeamDirectional(uint16 spell_id, int16 resist_adjust);
|
||||
void ConeDirectional(uint16 spell_id, int16 resist_adjust);
|
||||
void TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id);
|
||||
|
||||
//Buff
|
||||
void BuffProcess();
|
||||
@ -802,7 +803,8 @@ public:
|
||||
int32 GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining);
|
||||
int32 GetFcDamageAmtIncoming(Mob *caster, uint32 spell_id, bool use_skill = false, uint16 skill=0);
|
||||
int32 GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spell_id);
|
||||
int16 GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackOptions *opts = nullptr);
|
||||
int32 GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackOptions *opts = nullptr);
|
||||
int32 GetPositionalDmgTaken(Mob *attacker);
|
||||
void DoKnockback(Mob *caster, uint32 pushback, uint32 pushup);
|
||||
int16 CalcResistChanceBonus();
|
||||
int16 CalcFearResistChance();
|
||||
@ -816,6 +818,7 @@ public:
|
||||
int16 GetMeleeDamageMod_SE(uint16 skill);
|
||||
int16 GetMeleeMinDamageMod_SE(uint16 skill);
|
||||
int16 GetCrippBlowChance();
|
||||
int16 GetMeleeDmgPositionMod(Mob* defender);
|
||||
int16 GetSkillReuseTime(uint16 skill);
|
||||
int GetCriticalChanceBonus(uint16 skill);
|
||||
int16 GetSkillDmgAmt(uint16 skill);
|
||||
|
||||
@ -585,6 +585,10 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) {
|
||||
if(IsClient())
|
||||
CastToClient()->CheckIncreaseSkill(EQ::skills::SkillBackstab, other, 10);
|
||||
m_specialattacks = eSpecialAttacks::None;
|
||||
|
||||
int double_bs_front = aabonuses.Double_Backstab_Front + itembonuses.Double_Backstab_Front + spellbonuses.Double_Backstab_Front;
|
||||
if (double_bs_front && other->GetHP() > 0 && zone->random.Roll(double_bs_front))
|
||||
RogueBackstab(other, false, ReuseTime);
|
||||
}
|
||||
else { //We do a single regular attack if we attack from the front without chaotic stab
|
||||
Attack(other, EQ::invslot::slotPrimary);
|
||||
|
||||
@ -275,11 +275,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
#endif
|
||||
|
||||
int32 dmg = effect_value;
|
||||
if (spell_id == 2751 && caster) //Manaburn
|
||||
if (spell_id == SPELL_MANA_BURN && caster) //Manaburn
|
||||
{
|
||||
dmg = caster->GetMana()*-3;
|
||||
caster->SetMana(0);
|
||||
} else if (spell_id == 2755 && caster) //Lifeburn
|
||||
} else if (spell_id == SPELL_LIFE_BURN && caster) //Lifeburn
|
||||
{
|
||||
dmg = caster->GetHP(); // just your current HP
|
||||
caster->SetHP(dmg / 4); // 2003 patch notes say ~ 1/4 HP. Should this be 1/4 your current HP or do 3/4 max HP dmg? Can it kill you?
|
||||
@ -303,6 +303,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case SE_PercentalHeal:
|
||||
{
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
@ -2828,6 +2829,52 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case SE_Instant_Mana_Pct: {
|
||||
effect_value = spells[spell_id].base[i];
|
||||
int32 amt = abs(GetMaxMana() * effect_value / 10000);
|
||||
if (spells[spell_id].max[i] && amt > spells[spell_id].max[i])
|
||||
amt = spells[spell_id].max[i];
|
||||
|
||||
if (effect_value < 0) {
|
||||
SetMana(GetMana() - amt);
|
||||
}
|
||||
else {
|
||||
SetMana(GetMana() + amt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Instant_Endurance_Pct: {
|
||||
effect_value = spells[spell_id].base[i];
|
||||
if (IsClient()) {
|
||||
int32 amt = abs(CastToClient()->GetMaxEndurance() * effect_value / 10000);
|
||||
if (spells[spell_id].max[i] && amt > spells[spell_id].max[i])
|
||||
amt = spells[spell_id].max[i];
|
||||
|
||||
if (effect_value < 0) {
|
||||
CastToClient()->SetEndurance(CastToClient()->GetEndurance() - amt);
|
||||
}
|
||||
else {
|
||||
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + amt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*Calc for base1 is found in TryOnSpellFinished() due to needing to account for AOE functionality
|
||||
since effect can potentially kill caster*/
|
||||
case SE_Health_Transfer: {
|
||||
effect_value = spells[spell_id].base2[i];
|
||||
int32 amt = abs(caster->GetMaxHP() * effect_value / 1000);
|
||||
|
||||
if (effect_value < 0)
|
||||
Damage(caster, amt, spell_id, spell.skill, false, buffslot, false);
|
||||
else
|
||||
HealDamage(amt, caster);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case SE_PersistentEffect:
|
||||
MakeAura(spell_id);
|
||||
break;
|
||||
@ -3071,6 +3118,19 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
case SE_SkillProc:
|
||||
case SE_SkillProcSuccess:
|
||||
case SE_SpellResistReduction:
|
||||
case SE_Duration_HP_Pct:
|
||||
case SE_Duration_Mana_Pct:
|
||||
case SE_Duration_Endurance_Pct:
|
||||
case SE_Endurance_Absorb_Pct_Damage:
|
||||
case SE_AC_Mitigation_Max_Percent:
|
||||
case SE_AC_Avoidance_Max_Percent:
|
||||
case SE_Attack_Accuracy_Max_Percent:
|
||||
case SE_Critical_Melee_Damage_Mod_Max:
|
||||
case SE_Melee_Damage_Position_Mod:
|
||||
case SE_Damage_Taken_Position_Mod:
|
||||
case SE_DS_Mitigation_Amount:
|
||||
case SE_DS_Mitigation_Percentage:
|
||||
case SE_Double_Backstab_Front:
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -3777,6 +3837,55 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Duration_HP_Pct: {
|
||||
effect_value = spells[buff.spellid].base[i];
|
||||
int32 amt = abs(GetMaxHP() * effect_value / 100);
|
||||
if (spells[buff.spellid].max[i] && amt > spells[buff.spellid].max[i])
|
||||
amt = spells[buff.spellid].max[i];
|
||||
|
||||
if (effect_value < 0) {
|
||||
Damage(this, amt, 0, EQ::skills::SkillEvocation, false);
|
||||
}
|
||||
else {
|
||||
HealDamage(amt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Duration_Mana_Pct: {
|
||||
effect_value = spells[buff.spellid].base[i];
|
||||
int32 amt = abs(GetMaxMana() * effect_value / 100);
|
||||
if (spells[buff.spellid].max[i] && amt > spells[buff.spellid].max[i])
|
||||
amt = spells[buff.spellid].max[i];
|
||||
|
||||
if (effect_value < 0) {
|
||||
|
||||
SetMana(GetMana() - amt);
|
||||
}
|
||||
else {
|
||||
SetMana(GetMana() + amt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Duration_Endurance_Pct: {
|
||||
effect_value = spells[buff.spellid].base[i];
|
||||
|
||||
if (IsClient()) {
|
||||
int32 amt = abs(CastToClient()->GetMaxEndurance() * effect_value / 100);
|
||||
if (spells[buff.spellid].max[i] && amt > spells[buff.spellid].max[i])
|
||||
amt = spells[buff.spellid].max[i];
|
||||
|
||||
if (effect_value < 0) {
|
||||
CastToClient()->SetEndurance(CastToClient()->GetEndurance() - amt);
|
||||
}
|
||||
else {
|
||||
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + amt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
// do we need to do anyting here?
|
||||
}
|
||||
|
||||
@ -1393,6 +1393,8 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
|
||||
TrySympatheticProc(target, spell_id);
|
||||
}
|
||||
|
||||
TryOnSpellFinished(this, target, spell_id);
|
||||
|
||||
TryTwincast(this, target, spell_id);
|
||||
|
||||
TryTriggerOnCast(spell_id, 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user